├── test ├── index.ts ├── setupFilesAfterEnv.ts └── mocks │ ├── resizeObserver.mock.ts │ └── matchMedia.mock.ts ├── cypress ├── .gitignore ├── support │ └── e2e.ts ├── fixtures │ └── example.json ├── tsconfig.json └── e2e │ └── ui │ ├── textInput.cy.ts │ └── tab.cy.ts ├── exports ├── index.ts └── theme.ts ├── pnpm-workspace.yaml ├── .prettierignore ├── src ├── core │ ├── primitives │ │ ├── box │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ ├── props.tsx │ │ │ │ └── responsive.tsx │ │ ├── kbd │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── plain.tsx │ │ ├── badge │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── tones.tsx │ │ │ ├── styles.ts │ │ │ └── badge.test.tsx │ │ ├── code │ │ │ ├── index.ts │ │ │ ├── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── props.tsx │ │ │ └── refractor.tsx │ │ ├── flex │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── gap.tsx │ │ ├── grid │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ └── index.ts │ │ ├── label │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── plain.tsx │ │ ├── radio │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── plain.tsx │ │ ├── stack │ │ │ ├── index.ts │ │ │ ├── __workshop__ │ │ │ │ └── index.ts │ │ │ └── styles.ts │ │ ├── text │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ └── index.ts │ │ ├── button │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── mixedChildren.tsx │ │ │ │ ├── styled1.tsx │ │ │ │ ├── styled2.tsx │ │ │ │ ├── uploadButton.tsx │ │ │ │ └── sanityUploadButton.tsx │ │ ├── checkbox │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── readOnly.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── tones.tsx │ │ │ │ └── example.tsx │ │ ├── heading │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── __workshop__ │ │ │ │ └── index.ts │ │ ├── inline │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── plain.tsx │ │ │ └── styles.ts │ │ ├── select │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ ├── readOnly.tsx │ │ │ │ └── plain.tsx │ │ ├── spinner │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── Props.tsx │ │ ├── switch │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ ├── props.tsx │ │ │ │ └── example.tsx │ │ ├── textArea │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ └── index.ts │ │ ├── _selectable │ │ │ ├── index.ts │ │ │ └── selectable.tsx │ │ ├── textInput │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── readOnly.tsx │ │ │ │ ├── customValidity.tsx │ │ │ │ ├── typed.tsx │ │ │ │ └── clearButton.tsx │ │ ├── card │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── __workshop__ │ │ │ │ ├── styled.tsx │ │ │ │ ├── checkered.tsx │ │ │ │ ├── allTones.tsx │ │ │ │ ├── asComponent.tsx │ │ │ │ └── interactive.tsx │ │ ├── container │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── example.tsx │ │ │ └── styles.ts │ │ ├── popover │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── __workshop__ │ │ │ │ ├── OpenOnMountStory.tsx │ │ │ │ └── MarginsStory.tsx │ │ │ └── helpers.ts │ │ ├── tooltip │ │ │ ├── index.ts │ │ │ ├── tooltipDelayGroup │ │ │ │ ├── index.ts │ │ │ │ ├── types.ts │ │ │ │ ├── tooltipDelayGroupContext.tsx │ │ │ │ └── useTooltipDelayGroup.ts │ │ │ └── __workshop__ │ │ │ │ └── index.ts │ │ ├── avatar │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── __workshop__ │ │ │ │ ├── asButton.tsx │ │ │ │ ├── index.ts │ │ │ │ └── stack.tsx │ │ └── index.ts │ ├── utils │ │ ├── arrow │ │ │ └── index.ts │ │ ├── srOnly │ │ │ ├── index.ts │ │ │ └── srOnly.tsx │ │ ├── elementQuery │ │ │ ├── index.ts │ │ │ ├── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── customMedia.tsx │ │ │ └── helpers.ts │ │ ├── virtualList │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── windowScrolll.tsx │ │ │ │ ├── elementScroll.tsx │ │ │ │ └── index.ts │ │ ├── conditionalWrapper │ │ │ ├── index.ts │ │ │ └── conditionalWrapper.tsx │ │ ├── layer │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── layerContext.ts │ │ │ ├── __workshop__ │ │ │ │ ├── responsiveZOffset.tsx │ │ │ │ ├── _debug.tsx │ │ │ │ └── index.ts │ │ │ ├── useLayer.ts │ │ │ ├── getLayerContext.test.ts │ │ │ └── getLayerContext.ts │ │ ├── boundaryElement │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── boundaryElementContext.ts │ │ │ ├── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── plain.tsx │ │ │ ├── boundaryElementProvider.tsx │ │ │ └── useBoundaryElement.ts │ │ ├── portal │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── __workshop__ │ │ │ │ └── index.ts │ │ │ ├── portal.ts │ │ │ ├── usePortal.ts │ │ │ └── portalContext.ts │ │ ├── spanWithTextOverflow.tsx │ │ └── index.ts │ ├── components │ │ ├── hotkeys │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── plain.tsx │ │ │ │ └── index.ts │ │ ├── breadcrumbs │ │ │ ├── index.ts │ │ │ ├── __workshop__ │ │ │ │ └── index.ts │ │ │ └── breadcrumbs.styles.ts │ │ ├── skeleton │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ └── index.ts │ │ ├── autocomplete │ │ │ ├── index.ts │ │ │ ├── __workshop__ │ │ │ │ └── types.ts │ │ │ ├── constants.ts │ │ │ └── autocomplete.styles.tsx │ │ ├── tab │ │ │ ├── index.ts │ │ │ ├── __workshop__ │ │ │ │ └── index.ts │ │ │ └── tabPanel.tsx │ │ ├── tree │ │ │ ├── index.ts │ │ │ ├── treeContext.ts │ │ │ ├── useTree.ts │ │ │ ├── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── basic.perf.ts │ │ │ ├── types.ts │ │ │ └── treeGroup.tsx │ │ ├── toast │ │ │ ├── index.ts │ │ │ ├── toastState.ts │ │ │ ├── toastContext.ts │ │ │ ├── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── toast.tsx │ │ │ ├── types.ts │ │ │ └── useToast.ts │ │ ├── dialog │ │ │ ├── index.ts │ │ │ ├── useDialog.ts │ │ │ ├── __workshop__ │ │ │ │ ├── provider.tsx │ │ │ │ └── autoFocus.tsx │ │ │ ├── dialogContext.ts │ │ │ └── dialogProvider.tsx │ │ ├── menu │ │ │ ├── index.ts │ │ │ ├── menuDivider.ts │ │ │ ├── __workshop__ │ │ │ │ ├── nestedMenu.tsx │ │ │ │ ├── withoutArrow.tsx │ │ │ │ └── tones.tsx │ │ │ ├── menuContext.ts │ │ │ └── useMenu.ts │ │ └── index.ts │ ├── styles │ │ ├── card │ │ │ └── index.ts │ │ ├── box │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── border │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── margin │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── marginsStyle.test.ts │ │ │ └── marginStyle.ts │ │ ├── radius │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── radiusStyle.ts │ │ ├── shadow │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── padding │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── paddingStyle.test.ts │ │ │ └── paddingStyle.ts │ │ ├── input │ │ │ └── index.ts │ │ ├── flex │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── flexItemStyle.ts │ │ ├── grid │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── index.ts │ │ ├── types.ts │ │ ├── font │ │ │ ├── index.ts │ │ │ ├── textFontStyle.ts │ │ │ ├── codeFontStyle.ts │ │ │ ├── labelFontStyle.ts │ │ │ ├── headingFontStyle.ts │ │ │ ├── textAlignStyle.ts │ │ │ └── types.ts │ │ ├── internal.ts │ │ └── focusRing │ │ │ └── index.ts │ ├── hooks │ │ ├── useMediaIndex │ │ │ ├── index.ts │ │ │ └── __workshop__ │ │ │ │ ├── index.ts │ │ │ │ └── test.tsx │ │ ├── useElementRect │ │ │ ├── index.ts │ │ │ ├── __workshop__ │ │ │ │ └── index.ts │ │ │ └── useElementRect.ts │ │ ├── useIsomorphicEffect.ts │ │ ├── useCustomValidity.ts │ │ ├── useMounted.ts │ │ ├── index.ts │ │ ├── useElementSize.ts │ │ ├── useArrayProp.ts │ │ ├── useForwardedRef.ts │ │ ├── usePrefersDark.test.tsx │ │ ├── usePrefersReducedMotion.test.tsx │ │ ├── useGlobalKeyDown.ts │ │ └── useDelayedState.ts │ ├── types │ │ ├── radius.ts │ │ ├── dialog.ts │ │ ├── popover.ts │ │ ├── text.ts │ │ ├── card.ts │ │ ├── selectable.ts │ │ ├── badge.ts │ │ ├── avatar.ts │ │ ├── grid.ts │ │ ├── placement.ts │ │ ├── box.ts │ │ ├── index.ts │ │ ├── button.ts │ │ ├── gridItem.ts │ │ └── flex.ts │ ├── observers │ │ ├── index.ts │ │ └── resizeObserver.ts │ ├── helpers │ │ ├── index.ts │ │ ├── scroll.ts │ │ └── animation.ts │ ├── lib │ │ ├── isRecord.ts │ │ └── globalScope.ts │ ├── theme │ │ ├── index.ts │ │ ├── themeContext.ts │ │ ├── types.ts │ │ ├── useTheme.ts │ │ ├── useRootTheme.ts │ │ ├── __workshop__ │ │ │ ├── nestedProvider.tsx │ │ │ └── index.ts │ │ └── themeColorProvider.tsx │ └── index.ts └── theme │ ├── config │ ├── tokens │ │ ├── color │ │ │ └── index.ts │ │ ├── index.ts │ │ └── parseTokenValue.test.ts │ └── index.ts │ ├── build │ ├── _deprecated │ │ └── color │ │ │ ├── index.ts │ │ │ ├── button │ │ │ └── createButtonModes.ts │ │ │ └── spot │ │ │ └── createSpot.ts │ ├── colorToken │ │ ├── index.ts │ │ ├── types.ts │ │ ├── compileColorToken.ts │ │ └── colorToken.ts │ ├── index.ts │ ├── lib │ │ ├── color-fns │ │ │ ├── blend │ │ │ │ ├── index.ts │ │ │ │ ├── mix.ts │ │ │ │ ├── screen.ts │ │ │ │ └── multiply.ts │ │ │ ├── index.ts │ │ │ ├── rgba.ts │ │ │ └── types.ts │ │ ├── isRecord.ts │ │ └── utils.ts │ ├── mixThemeColor.test.ts │ ├── merge.ts │ └── theme.test.ts │ ├── system │ ├── v0 │ │ ├── index.ts │ │ ├── avatar.ts │ │ ├── color │ │ │ ├── index.ts │ │ │ ├── spot.ts │ │ │ ├── _system.ts │ │ │ ├── base.ts │ │ │ ├── card.ts │ │ │ ├── _generic.ts │ │ │ ├── muted.ts │ │ │ ├── solid.ts │ │ │ ├── input.ts │ │ │ └── selectable.ts │ │ └── input.ts │ ├── focusRing.ts │ ├── color │ │ ├── kbd.ts │ │ ├── shadow.ts │ │ ├── badge.ts │ │ ├── avatar.ts │ │ ├── index.ts │ │ ├── selectable.ts │ │ ├── button.ts │ │ ├── input.ts │ │ ├── syntax.ts │ │ ├── state.ts │ │ └── _helpers.ts │ ├── layer.ts │ ├── styles.ts │ ├── css.ts │ ├── index.ts │ ├── avatar.ts │ ├── shadow.ts │ ├── input.ts │ └── font.ts │ ├── index.ts │ ├── versioning │ ├── index.ts │ ├── is_v0.ts │ └── is_v2.ts │ └── defaults │ └── colorPalette.ts ├── .czrc ├── figma ├── src │ ├── theme.ts │ ├── index.html │ └── index.ts ├── tsconfig.dist.json ├── tsconfig.json ├── package.config.ts ├── manifest.json └── package.json ├── .husky └── commit-msg ├── .gitignore ├── cypress.config.ts ├── .npmrc ├── typings ├── styled-components.d.ts ├── workshop-env.d.ts └── dom.d.ts ├── stories ├── tokens │ └── Colors.mdx ├── tests │ ├── FocusRings.mdx │ └── Tones.mdx ├── primitives │ ├── components │ │ └── FieldWrapper.tsx │ ├── Spinner.stories.tsx │ ├── AvatarCounter.stories.tsx │ ├── Box.stories.tsx │ └── AvatarStack.stories.tsx ├── helpers │ ├── columnBuilder.tsx │ └── rowBuilder.tsx └── components │ ├── Breadcrumbs.stories.tsx │ └── Hotkeys.stories.tsx ├── .editorconfig ├── vercel.json ├── .storybook ├── manager.ts └── preview.tsx ├── workshop.runtime.ts ├── tsconfig.dist.json ├── package.config.ts ├── CONTRIBUTING.md ├── tsconfig.json ├── tsconfig.settings.json ├── README.md └── jest.config.js /test/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utils' 2 | -------------------------------------------------------------------------------- /cypress/.gitignore: -------------------------------------------------------------------------------- 1 | /screenshots 2 | /videos 3 | -------------------------------------------------------------------------------- /exports/index.ts: -------------------------------------------------------------------------------- 1 | export * from '../src/core' 2 | -------------------------------------------------------------------------------- /exports/theme.ts: -------------------------------------------------------------------------------- 1 | export * from '../src/theme' 2 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'figma' 3 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .workshop 2 | dist 3 | pnpm-lock.yaml 4 | -------------------------------------------------------------------------------- /src/core/primitives/box/index.ts: -------------------------------------------------------------------------------- 1 | export * from './box' 2 | -------------------------------------------------------------------------------- /src/core/primitives/kbd/index.ts: -------------------------------------------------------------------------------- 1 | export * from './kbd' 2 | -------------------------------------------------------------------------------- /src/core/utils/arrow/index.ts: -------------------------------------------------------------------------------- 1 | export * from './arrow' 2 | -------------------------------------------------------------------------------- /.czrc: -------------------------------------------------------------------------------- 1 | { 2 | "path": "cz-conventional-changelog" 3 | } 4 | -------------------------------------------------------------------------------- /cypress/support/e2e.ts: -------------------------------------------------------------------------------- 1 | import 'cypress-real-events/support' 2 | -------------------------------------------------------------------------------- /src/core/primitives/badge/index.ts: -------------------------------------------------------------------------------- 1 | export * from './badge' 2 | -------------------------------------------------------------------------------- /src/core/primitives/code/index.ts: -------------------------------------------------------------------------------- 1 | export * from './code' 2 | -------------------------------------------------------------------------------- /src/core/primitives/flex/index.ts: -------------------------------------------------------------------------------- 1 | export * from './flex' 2 | -------------------------------------------------------------------------------- /src/core/primitives/grid/index.ts: -------------------------------------------------------------------------------- 1 | export * from './grid' 2 | -------------------------------------------------------------------------------- /src/core/primitives/label/index.ts: -------------------------------------------------------------------------------- 1 | export * from './label' 2 | -------------------------------------------------------------------------------- /src/core/primitives/radio/index.ts: -------------------------------------------------------------------------------- 1 | export * from './radio' 2 | -------------------------------------------------------------------------------- /src/core/primitives/stack/index.ts: -------------------------------------------------------------------------------- 1 | export * from './stack' 2 | -------------------------------------------------------------------------------- /src/core/primitives/text/index.ts: -------------------------------------------------------------------------------- 1 | export * from './text' 2 | -------------------------------------------------------------------------------- /src/core/utils/srOnly/index.ts: -------------------------------------------------------------------------------- 1 | export * from './srOnly' 2 | -------------------------------------------------------------------------------- /src/core/components/hotkeys/index.ts: -------------------------------------------------------------------------------- 1 | export * from './hotkeys' 2 | -------------------------------------------------------------------------------- /src/core/primitives/button/index.ts: -------------------------------------------------------------------------------- 1 | export * from './button' 2 | -------------------------------------------------------------------------------- /src/core/primitives/checkbox/index.ts: -------------------------------------------------------------------------------- 1 | export * from './checkbox' 2 | -------------------------------------------------------------------------------- /src/core/primitives/heading/index.ts: -------------------------------------------------------------------------------- 1 | export * from './heading' 2 | -------------------------------------------------------------------------------- /src/core/primitives/inline/index.ts: -------------------------------------------------------------------------------- 1 | export * from './inline' 2 | -------------------------------------------------------------------------------- /src/core/primitives/select/index.ts: -------------------------------------------------------------------------------- 1 | export * from './select' 2 | -------------------------------------------------------------------------------- /src/core/primitives/spinner/index.ts: -------------------------------------------------------------------------------- 1 | export * from './spinner' 2 | -------------------------------------------------------------------------------- /src/core/primitives/switch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './switch' 2 | -------------------------------------------------------------------------------- /src/core/primitives/textArea/index.ts: -------------------------------------------------------------------------------- 1 | export * from './textArea' 2 | -------------------------------------------------------------------------------- /src/core/styles/card/index.ts: -------------------------------------------------------------------------------- 1 | export * from './_cardColorStyle' 2 | -------------------------------------------------------------------------------- /src/theme/config/tokens/color/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types' 2 | -------------------------------------------------------------------------------- /src/core/hooks/useMediaIndex/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useMediaIndex' 2 | -------------------------------------------------------------------------------- /src/core/primitives/_selectable/index.ts: -------------------------------------------------------------------------------- 1 | export * from './selectable' 2 | -------------------------------------------------------------------------------- /src/core/primitives/textInput/index.ts: -------------------------------------------------------------------------------- 1 | export * from './textInput' 2 | -------------------------------------------------------------------------------- /src/core/utils/elementQuery/index.ts: -------------------------------------------------------------------------------- 1 | export * from './elementQuery' 2 | -------------------------------------------------------------------------------- /src/core/utils/virtualList/index.ts: -------------------------------------------------------------------------------- 1 | export * from './virtualList' 2 | -------------------------------------------------------------------------------- /src/theme/build/_deprecated/color/index.ts: -------------------------------------------------------------------------------- 1 | export * from './factory' 2 | -------------------------------------------------------------------------------- /src/core/components/breadcrumbs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './breadcrumbs' 2 | -------------------------------------------------------------------------------- /src/core/hooks/useElementRect/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useElementRect' 2 | -------------------------------------------------------------------------------- /src/core/utils/conditionalWrapper/index.ts: -------------------------------------------------------------------------------- 1 | export * from './conditionalWrapper' 2 | -------------------------------------------------------------------------------- /src/core/primitives/card/index.ts: -------------------------------------------------------------------------------- 1 | export * from './card' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/styles/box/index.ts: -------------------------------------------------------------------------------- 1 | export * from './boxStyle' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/styles/border/index.ts: -------------------------------------------------------------------------------- 1 | export * from './borderStyle' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/styles/margin/index.ts: -------------------------------------------------------------------------------- 1 | export * from './marginStyle' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/styles/radius/index.ts: -------------------------------------------------------------------------------- 1 | export * from './radiusStyle' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/styles/shadow/index.ts: -------------------------------------------------------------------------------- 1 | export * from './shadowStyle' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/primitives/container/index.ts: -------------------------------------------------------------------------------- 1 | export * from './container' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/primitives/popover/index.ts: -------------------------------------------------------------------------------- 1 | export * from './popover' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/styles/padding/index.ts: -------------------------------------------------------------------------------- 1 | export * from './paddingStyle' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/types/radius.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export type Radius = number | 'full' 5 | -------------------------------------------------------------------------------- /src/theme/build/colorToken/index.ts: -------------------------------------------------------------------------------- 1 | export * from './colorToken' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/components/skeleton/index.ts: -------------------------------------------------------------------------------- 1 | export * from './skeleton' 2 | export * from './textSkeleton' 3 | -------------------------------------------------------------------------------- /test/setupFilesAfterEnv.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom' 2 | import 'jest-axe/extend-expect' 3 | -------------------------------------------------------------------------------- /src/core/components/autocomplete/index.ts: -------------------------------------------------------------------------------- 1 | export * from './autocomplete' 2 | export * from './types' 3 | -------------------------------------------------------------------------------- /src/core/observers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './elementSizeObserver' 2 | export * from './resizeObserver' 3 | -------------------------------------------------------------------------------- /src/core/primitives/tooltip/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tooltip' 2 | export * from './tooltipDelayGroup' 3 | -------------------------------------------------------------------------------- /figma/src/theme.ts: -------------------------------------------------------------------------------- 1 | import {buildTheme} from '@sanity/ui/theme' 2 | 3 | export const theme = buildTheme().v2! 4 | -------------------------------------------------------------------------------- /src/core/types/dialog.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export type DialogPosition = 'absolute' | 'fixed' 5 | -------------------------------------------------------------------------------- /src/theme/system/v0/index.ts: -------------------------------------------------------------------------------- 1 | export * from './avatar' 2 | export * from './color' 3 | export * from './input' 4 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | pnpm exec commitlint --edit $1 5 | -------------------------------------------------------------------------------- /src/core/styles/input/index.ts: -------------------------------------------------------------------------------- 1 | export * from './responsiveInputPaddingStyle' 2 | export * from './textInputStyle' 3 | -------------------------------------------------------------------------------- /src/core/components/tab/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tab' 2 | export * from './tabList' 3 | export * from './tabPanel' 4 | -------------------------------------------------------------------------------- /src/core/types/popover.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @beta 3 | */ 4 | export type PopoverMargins = [number, number, number, number] 5 | -------------------------------------------------------------------------------- /src/core/styles/flex/index.ts: -------------------------------------------------------------------------------- 1 | export * from './flexItemStyle' 2 | export * from './flexStyle' 3 | export * from './types' 4 | -------------------------------------------------------------------------------- /src/core/styles/grid/index.ts: -------------------------------------------------------------------------------- 1 | export * from './gridItemStyle' 2 | export * from './gridStyle' 3 | export * from './types' 4 | -------------------------------------------------------------------------------- /src/core/styles/index.ts: -------------------------------------------------------------------------------- 1 | export * from './helpers' 2 | export * from './types' 3 | 4 | // beta 5 | export * from './font' 6 | -------------------------------------------------------------------------------- /src/core/types/text.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export type TextAlign = 'left' | 'right' | 'center' | 'justify' | 'initial' 5 | -------------------------------------------------------------------------------- /src/theme/build/index.ts: -------------------------------------------------------------------------------- 1 | export * from './_deprecated/color' 2 | export * from './buildTheme' 3 | export * from './lib/color-fns' 4 | -------------------------------------------------------------------------------- /src/theme/build/lib/color-fns/blend/index.ts: -------------------------------------------------------------------------------- 1 | export * from './mix' 2 | export * from './multiply' 3 | export * from './screen' 4 | -------------------------------------------------------------------------------- /src/core/components/autocomplete/__workshop__/types.ts: -------------------------------------------------------------------------------- 1 | export interface ExampleOption { 2 | value: string 3 | title: string 4 | } 5 | -------------------------------------------------------------------------------- /src/theme/config/index.ts: -------------------------------------------------------------------------------- 1 | export * from './helpers' 2 | export * from './system' 3 | export * from './tokens' 4 | export * from './types' 5 | -------------------------------------------------------------------------------- /src/core/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './animation' 2 | export * from './element' 3 | export * from './focus' 4 | export * from './scroll' 5 | -------------------------------------------------------------------------------- /src/core/styles/shadow/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export interface ResponsiveShadowStyleProps { 5 | $shadow: number[] 6 | } 7 | -------------------------------------------------------------------------------- /src/theme/system/focusRing.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export interface ThemeFocusRing { 5 | offset: number 6 | width: number 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.tgz 2 | 3 | .DS_Store 4 | .env.local 5 | .workshop 6 | dist 7 | etc 8 | node_modules 9 | storybook-static 10 | .eslintcache 11 | -------------------------------------------------------------------------------- /src/core/components/tree/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tree' 2 | export * from './treeItem' 3 | export * from './types' 4 | export * from './useTree' 5 | -------------------------------------------------------------------------------- /src/core/primitives/inline/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export interface ResponsiveInlineSpaceStyleProps { 5 | $space: number[] 6 | } 7 | -------------------------------------------------------------------------------- /src/core/utils/layer/index.ts: -------------------------------------------------------------------------------- 1 | export * from './layer' 2 | export * from './layerProvider' 3 | export * from './types' 4 | export * from './useLayer' 5 | -------------------------------------------------------------------------------- /src/core/components/toast/index.ts: -------------------------------------------------------------------------------- 1 | export * from './toast' 2 | export * from './toastProvider' 3 | export * from './types' 4 | export * from './useToast' 5 | -------------------------------------------------------------------------------- /src/core/utils/boundaryElement/index.ts: -------------------------------------------------------------------------------- 1 | export * from './boundaryElementProvider' 2 | export * from './types' 3 | export * from './useBoundaryElement' 4 | -------------------------------------------------------------------------------- /src/core/utils/portal/index.ts: -------------------------------------------------------------------------------- 1 | export * from './portal' 2 | export * from './portalProvider' 3 | export * from './types' 4 | export * from './usePortal' 5 | -------------------------------------------------------------------------------- /src/theme/system/color/kbd.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export interface ThemeColorKBD { 5 | bg: string 6 | fg: string 7 | border: string 8 | } 9 | -------------------------------------------------------------------------------- /src/core/primitives/avatar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './avatar' 2 | export * from './avatarCounter' 3 | export * from './avatarStack' 4 | export * from './types' 5 | -------------------------------------------------------------------------------- /src/core/primitives/container/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export interface ResponsiveWidthStyleProps { 5 | $width: (number | 'auto')[] 6 | } 7 | -------------------------------------------------------------------------------- /src/core/primitives/heading/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export interface HeadingStyleProps { 5 | $accent: boolean 6 | $muted: boolean 7 | } 8 | -------------------------------------------------------------------------------- /src/theme/config/tokens/index.ts: -------------------------------------------------------------------------------- 1 | export * from './color' 2 | export * from './parseTokenKey' 3 | export * from './parseTokenValue' 4 | export * from './types' 5 | -------------------------------------------------------------------------------- /cypress.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'cypress' 2 | 3 | export default defineConfig({ 4 | e2e: { 5 | baseUrl: 'http://localhost:1337', 6 | }, 7 | }) 8 | -------------------------------------------------------------------------------- /src/core/styles/types.ts: -------------------------------------------------------------------------------- 1 | import {Theme} from '@sanity/ui/theme' 2 | 3 | /** 4 | * @internal 5 | */ 6 | export interface ThemeProps { 7 | theme: Theme 8 | } 9 | -------------------------------------------------------------------------------- /src/core/components/dialog/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dialog' 2 | export * from './dialogContext' 3 | export * from './dialogProvider' 4 | export * from './useDialog' 5 | -------------------------------------------------------------------------------- /src/core/components/toast/toastState.ts: -------------------------------------------------------------------------------- 1 | let toastId = 0 2 | 3 | /** @internal */ 4 | export function generateToastId(): string { 5 | return String(toastId++) 6 | } 7 | -------------------------------------------------------------------------------- /src/core/types/card.ts: -------------------------------------------------------------------------------- 1 | import {ThemeColorCardToneKey} from '@sanity/ui/theme' 2 | 3 | /** 4 | * @public 5 | */ 6 | export type CardTone = ThemeColorCardToneKey | 'inherit' 7 | -------------------------------------------------------------------------------- /src/theme/index.ts: -------------------------------------------------------------------------------- 1 | export * from './build' 2 | export * from './config' 3 | export * from './getScopedTheme' 4 | export * from './system' 5 | export * from './versioning' 6 | -------------------------------------------------------------------------------- /src/theme/versioning/index.ts: -------------------------------------------------------------------------------- 1 | export * from './getTheme_v2' 2 | export * from './is_v0' 3 | export * from './is_v2' 4 | export * from './v0_v2' 5 | export * from './v2_v0' 6 | -------------------------------------------------------------------------------- /src/core/primitives/badge/types.ts: -------------------------------------------------------------------------------- 1 | import {BadgeTone} from '../../types' 2 | 3 | /** 4 | * @internal 5 | */ 6 | export interface BadgeStyleProps { 7 | $tone: BadgeTone 8 | } 9 | -------------------------------------------------------------------------------- /src/core/types/selectable.ts: -------------------------------------------------------------------------------- 1 | import {ThemeColorStateToneKey} from '@sanity/ui/theme' 2 | 3 | /** 4 | * @public 5 | */ 6 | export type SelectableTone = ThemeColorStateToneKey 7 | -------------------------------------------------------------------------------- /src/core/utils/boundaryElement/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export interface BoundaryElementContextValue { 5 | version: 0.0 6 | element: HTMLElement | null 7 | } 8 | -------------------------------------------------------------------------------- /src/core/styles/radius/types.ts: -------------------------------------------------------------------------------- 1 | import {Radius} from '../../types' 2 | 3 | /** 4 | * @internal 5 | */ 6 | export interface ResponsiveRadiusStyleProps { 7 | $radius: Radius[] 8 | } 9 | -------------------------------------------------------------------------------- /src/theme/build/colorToken/types.ts: -------------------------------------------------------------------------------- 1 | import {ColorHueKey} from '@sanity/color' 2 | 3 | export interface ColorTokenContext { 4 | hue: ColorHueKey 5 | scheme: 'light' | 'dark' 6 | } 7 | -------------------------------------------------------------------------------- /src/theme/system/color/shadow.ts: -------------------------------------------------------------------------------- 1 | /** @public */ 2 | export interface ThemeColorShadow { 3 | outline: string 4 | umbra: string 5 | penumbra: string 6 | ambient: string 7 | } 8 | -------------------------------------------------------------------------------- /src/core/components/menu/index.ts: -------------------------------------------------------------------------------- 1 | export * from './menu' 2 | export * from './menuButton' 3 | export * from './menuDivider' 4 | export * from './menuGroup' 5 | export * from './menuItem' 6 | -------------------------------------------------------------------------------- /src/core/lib/isRecord.ts: -------------------------------------------------------------------------------- 1 | export function isRecord(value: unknown): value is Record { 2 | return Boolean(value && typeof value === 'object' && !Array.isArray(value)) 3 | } 4 | -------------------------------------------------------------------------------- /test/mocks/resizeObserver.mock.ts: -------------------------------------------------------------------------------- 1 | global.ResizeObserver = jest.fn().mockImplementation(() => ({ 2 | observe: jest.fn(), 3 | unobserve: jest.fn(), 4 | disconnect: jest.fn(), 5 | })) 6 | -------------------------------------------------------------------------------- /src/core/theme/index.ts: -------------------------------------------------------------------------------- 1 | export * from './themeColorProvider' 2 | export * from './themeProvider' 3 | export * from './types' 4 | export * from './useRootTheme' 5 | export * from './useTheme' 6 | -------------------------------------------------------------------------------- /src/theme/defaults/colorPalette.ts: -------------------------------------------------------------------------------- 1 | import {color} from '@sanity/color' 2 | 3 | import {ThemeColorPalette} from '../config' 4 | 5 | export const defaultColorPalette: ThemeColorPalette = color 6 | -------------------------------------------------------------------------------- /src/theme/system/layer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export interface ThemeLayer { 5 | dialog: {zOffset: number} 6 | popover: {zOffset: number} 7 | tooltip: {zOffset: number} 8 | } 9 | -------------------------------------------------------------------------------- /src/theme/build/lib/isRecord.ts: -------------------------------------------------------------------------------- 1 | export function isRecord(value: unknown): value is Record { 2 | return Boolean(value && typeof value === 'object' && !Array.isArray(value)) 3 | } 4 | -------------------------------------------------------------------------------- /cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } 6 | -------------------------------------------------------------------------------- /src/theme/build/lib/color-fns/index.ts: -------------------------------------------------------------------------------- 1 | export * from './blend' 2 | export * from './contrastRatio' 3 | export * from './convert' 4 | export * from './parse' 5 | export * from './rgba' 6 | export * from './types' 7 | -------------------------------------------------------------------------------- /src/core/primitives/tooltip/tooltipDelayGroup/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tooltipDelayGroupContext' 2 | export * from './tooltipDelayGroupProvider' 3 | export * from './types' 4 | export * from './useTooltipDelayGroup' 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies = false 2 | link-workspace-packages = deep 3 | # https://github.com/cypress-io/github-action/blob/43c624e40c65c7c3a255a901d0a0a0a2040b7140/examples/basic-pnpm/.npmrc#L2C1-L2C25 4 | side-effects-cache=false 5 | -------------------------------------------------------------------------------- /src/core/styles/font/index.ts: -------------------------------------------------------------------------------- 1 | export * from './codeFontStyle' 2 | export * from './headingFontStyle' 3 | export * from './labelFontStyle' 4 | export * from './textAlignStyle' 5 | export * from './textFontStyle' 6 | export * from './types' 7 | -------------------------------------------------------------------------------- /src/theme/versioning/is_v0.ts: -------------------------------------------------------------------------------- 1 | import {RootTheme, RootTheme_v2} from '../system' 2 | 3 | /** @internal */ 4 | export function is_v0(themeProp: RootTheme | RootTheme_v2): themeProp is RootTheme { 5 | return themeProp._version === 0 6 | } 7 | -------------------------------------------------------------------------------- /src/theme/versioning/is_v2.ts: -------------------------------------------------------------------------------- 1 | import {RootTheme, RootTheme_v2} from '../system' 2 | 3 | /** @internal */ 4 | export function is_v2(themeProp: RootTheme | RootTheme_v2): themeProp is RootTheme_v2 { 5 | return themeProp._version === 2 6 | } 7 | -------------------------------------------------------------------------------- /src/theme/system/styles.ts: -------------------------------------------------------------------------------- 1 | import {CSSObject} from './css' 2 | 3 | /** 4 | * @internal 5 | */ 6 | export interface ThemeStyles { 7 | button?: { 8 | root?: CSSObject 9 | } 10 | card?: { 11 | root?: CSSObject 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /typings/styled-components.d.ts: -------------------------------------------------------------------------------- 1 | import {type Theme} from '@sanity/ui/theme' 2 | 3 | declare module 'styled-components' { 4 | // eslint-disable-next-line @typescript-eslint/no-empty-object-type 5 | interface DefaultTheme extends Theme {} 6 | } 7 | -------------------------------------------------------------------------------- /cypress/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig", 3 | "compilerOptions": { 4 | "target": "es5", 5 | "lib": ["es5", "dom"], 6 | "types": ["cypress", "cypress-real-events", "node"] 7 | }, 8 | "include": ["./**/*.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /src/theme/system/v0/avatar.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | * @deprecated Use `ThemeAvatar_v2` from `@sanity/ui/theme` instead. 4 | */ 5 | export interface ThemeAvatar { 6 | sizes: { 7 | distance: number 8 | size: number 9 | }[] 10 | } 11 | -------------------------------------------------------------------------------- /stories/tokens/Colors.mdx: -------------------------------------------------------------------------------- 1 | import {Meta, Unstyled} from '@storybook/blocks' 2 | import {ColorPalette} from './ColorPalette' 3 | 4 | ## Sanity Colors 5 | 6 | Full `@sanity/color` palette 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/core/utils/layer/types.ts: -------------------------------------------------------------------------------- 1 | /** @public */ 2 | export interface LayerContextValue { 3 | version: 0.0 4 | isTopLayer: boolean 5 | level?: number 6 | registerChild: (childLevel?: number) => () => void 7 | size: number 8 | zIndex: number 9 | } 10 | -------------------------------------------------------------------------------- /typings/workshop-env.d.ts: -------------------------------------------------------------------------------- 1 | declare module '$packages' { 2 | export const packages: Record< 3 | string, 4 | | { 5 | name: string 6 | version: string 7 | description: string 8 | } 9 | | undefined 10 | > 11 | } 12 | -------------------------------------------------------------------------------- /src/core/primitives/popover/types.ts: -------------------------------------------------------------------------------- 1 | /** @beta */ 2 | export type PopoverUpdateCallback = () => void 3 | 4 | // eslint-disable-next-line no-warning-comments 5 | // todo: remove `auto` from PopoverWidth 6 | /** @public */ 7 | export type PopoverWidth = number | 'auto' 8 | -------------------------------------------------------------------------------- /src/core/styles/border/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export interface ResponsiveBorderStyleProps { 5 | $border: boolean[] 6 | $borderTop: boolean[] 7 | $borderRight: boolean[] 8 | $borderBottom: boolean[] 9 | $borderLeft: boolean[] 10 | } 11 | -------------------------------------------------------------------------------- /src/core/utils/portal/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export interface PortalContextValue { 5 | version: 0.0 6 | boundaryElement: HTMLElement | null 7 | element: HTMLElement | null 8 | elements?: Record 9 | } 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ; editorconfig.org 2 | root = true 3 | charset= utf8 4 | 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | indent_style = space 10 | indent_size = 2 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /src/core/primitives/card/types.ts: -------------------------------------------------------------------------------- 1 | import {ThemeColorToneKey} from '@sanity/ui/theme' 2 | 3 | /** 4 | * @internal 5 | */ 6 | export interface CardStyleProps { 7 | $checkered: boolean 8 | $focusRing: boolean 9 | $muted: boolean 10 | $tone: ThemeColorToneKey 11 | } 12 | -------------------------------------------------------------------------------- /src/theme/build/lib/color-fns/rgba.ts: -------------------------------------------------------------------------------- 1 | import {parseColor} from './parse' 2 | 3 | /** 4 | * @internal 5 | */ 6 | export function rgba(color: unknown, a: number): string { 7 | const rgb = parseColor(color) 8 | 9 | return `rgba(${rgb.r},${rgb.g},${rgb.b},${a})` 10 | } 11 | -------------------------------------------------------------------------------- /src/core/primitives/textInput/__workshop__/readOnly.tsx: -------------------------------------------------------------------------------- 1 | import {Flex, TextInput} from '@sanity/ui' 2 | 3 | export default function ReadOnlyStory() { 4 | return ( 5 | 6 | 7 | 8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /src/core/styles/margin/types.ts: -------------------------------------------------------------------------------- 1 | export interface ResponsiveMarginStyleProps { 2 | $margin?: number[] 3 | $marginX?: number[] 4 | $marginY?: number[] 5 | $marginTop?: number[] 6 | $marginRight?: number[] 7 | $marginBottom?: number[] 8 | $marginLeft?: number[] 9 | } 10 | -------------------------------------------------------------------------------- /src/core/hooks/useIsomorphicEffect.ts: -------------------------------------------------------------------------------- 1 | import {useEffect, useLayoutEffect} from 'react' 2 | 3 | /** 4 | * @beta 5 | * @deprecated use `useLayoutEffect` instead, or `useEffect` if possible 6 | */ 7 | export const useIsomorphicEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect 8 | -------------------------------------------------------------------------------- /src/core/types/badge.ts: -------------------------------------------------------------------------------- 1 | import {ThemeColorStateToneKey} from '@sanity/ui/theme' 2 | 3 | /** 4 | * @public 5 | * @deprecated No longer used 6 | */ 7 | export type BadgeMode = 'default' | 'outline' 8 | 9 | /** 10 | * @public 11 | */ 12 | export type BadgeTone = ThemeColorStateToneKey 13 | -------------------------------------------------------------------------------- /src/core/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './autocomplete' 2 | export * from './breadcrumbs' 3 | export * from './dialog' 4 | export * from './hotkeys' 5 | export * from './menu' 6 | export * from './skeleton' 7 | export * from './tab' 8 | export * from './toast' 9 | export * from './tree' 10 | -------------------------------------------------------------------------------- /src/core/utils/layer/layerContext.ts: -------------------------------------------------------------------------------- 1 | import {createGlobalScopedContext} from '../../lib/createGlobalScopedContext' 2 | import {LayerContextValue} from './types' 3 | 4 | export const LayerContext = createGlobalScopedContext( 5 | '@sanity/ui/context/layer', 6 | null, 7 | ) 8 | -------------------------------------------------------------------------------- /src/core/utils/spanWithTextOverflow.tsx: -------------------------------------------------------------------------------- 1 | import {styled} from 'styled-components' 2 | 3 | /** @internal */ 4 | export const SpanWithTextOverflow = styled.span` 5 | display: block; 6 | white-space: nowrap; 7 | text-overflow: ellipsis; 8 | overflow: hidden; 9 | overflow: clip; 10 | ` 11 | -------------------------------------------------------------------------------- /src/theme/system/css.ts: -------------------------------------------------------------------------------- 1 | import type {StyledObject} from 'styled-components' 2 | 3 | /** 4 | * Work around types that are missing in `styled-components@6` 5 | * https://github.com/styled-components/styled-components/issues/4062 6 | * @internal 7 | */ 8 | export type CSSObject = StyledObject 9 | -------------------------------------------------------------------------------- /src/core/components/hotkeys/__workshop__/plain.tsx: -------------------------------------------------------------------------------- 1 | import {Flex, Hotkeys} from '@sanity/ui' 2 | 3 | export default function PlainStory() { 4 | return ( 5 | 6 | 7 | 8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /src/core/components/toast/toastContext.ts: -------------------------------------------------------------------------------- 1 | import {createGlobalScopedContext} from '../../lib/createGlobalScopedContext' 2 | import {ToastContextValue} from './types' 3 | 4 | export const ToastContext = createGlobalScopedContext( 5 | '@sanity/ui/context/toast', 6 | null, 7 | ) 8 | -------------------------------------------------------------------------------- /src/core/types/avatar.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export type AvatarPosition = 'top' | 'bottom' | 'inside' 5 | 6 | /** 7 | * @public 8 | */ 9 | export type AvatarSize = 0 | 1 | 2 | 3 10 | 11 | /** 12 | * @public 13 | */ 14 | export type AvatarStatus = 'online' | 'editing' | 'inactive' 15 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "routes": [ 4 | { 5 | "handle": "filesystem" 6 | }, 7 | { 8 | "src": "/frame/(.*)", 9 | "dest": "/frame/index.html" 10 | }, 11 | { 12 | "src": "/(.*)", 13 | "dest": "/index.html" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /src/core/primitives/kbd/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/kbd', 6 | title: 'KBD', 7 | stories: [{name: 'plain', title: 'Plain', component: lazy(() => import('./plain'))}], 8 | }) 9 | -------------------------------------------------------------------------------- /stories/tests/FocusRings.mdx: -------------------------------------------------------------------------------- 1 | import {Meta, Unstyled} from '@storybook/blocks' 2 | import {FocusRings} from './FocusRings' 3 | 4 | ## Focusable elements 5 | 6 | A page containing all Sanity UI primitives and components that can receive focus. 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /stories/tests/Tones.mdx: -------------------------------------------------------------------------------- 1 | import {Meta, Unstyled} from '@storybook/blocks' 2 | import {Tones} from './Tones' 3 | 4 | ## Cards with tones 5 | 6 | A page containing cards with all components that are modified when the card tone changes. 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/core/styles/box/types.ts: -------------------------------------------------------------------------------- 1 | import {BoxDisplay, BoxHeight, BoxOverflow, BoxSizing} from '../../types' 2 | 3 | /** 4 | * @internal 5 | */ 6 | export interface ResponsiveBoxStyleProps { 7 | $display: BoxDisplay[] 8 | $height: BoxHeight[] 9 | $overflow: BoxOverflow[] 10 | $sizing: BoxSizing[] 11 | } 12 | -------------------------------------------------------------------------------- /src/core/index.ts: -------------------------------------------------------------------------------- 1 | export * from './_compat' 2 | export * from './components' 3 | export * from './helpers' 4 | export * from './hooks' 5 | export * from './observers' 6 | export * from './primitives' 7 | export * from './styles' 8 | export * from './theme' 9 | export * from './types' 10 | export * from './utils' 11 | -------------------------------------------------------------------------------- /src/core/primitives/inline/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/inline', 6 | title: 'Inline', 7 | stories: [{name: 'plain', title: 'Plain', component: lazy(() => import('./plain'))}], 8 | }) 9 | -------------------------------------------------------------------------------- /src/core/components/menu/menuDivider.ts: -------------------------------------------------------------------------------- 1 | import {styled} from 'styled-components' 2 | 3 | /** 4 | * @public 5 | */ 6 | export const MenuDivider = styled.hr` 7 | height: 1px; 8 | border: 0; 9 | background: var(--card-hairline-soft-color); 10 | margin: 0; 11 | ` 12 | MenuDivider.displayName = 'MenuDivider' 13 | -------------------------------------------------------------------------------- /src/core/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './arrow' 2 | export * from './boundaryElement' 3 | export * from './conditionalWrapper' 4 | export * from './elementQuery' 5 | export * from './errorBoundary' 6 | export * from './layer' 7 | export * from './portal' 8 | export * from './srOnly' 9 | export * from './virtualList' 10 | -------------------------------------------------------------------------------- /src/core/primitives/container/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/container', 6 | title: 'Container', 7 | stories: [{name: 'plain', title: 'Plain', component: lazy(() => import('./example'))}], 8 | }) 9 | -------------------------------------------------------------------------------- /src/core/styles/padding/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export interface ResponsivePaddingStyleProps { 5 | $padding?: number[] 6 | $paddingX?: number[] 7 | $paddingY?: number[] 8 | $paddingTop?: number[] 9 | $paddingRight?: number[] 10 | $paddingBottom?: number[] 11 | $paddingLeft?: number[] 12 | } 13 | -------------------------------------------------------------------------------- /src/core/theme/themeContext.ts: -------------------------------------------------------------------------------- 1 | import {createGlobalScopedContext} from '../lib/createGlobalScopedContext' 2 | import {ThemeContextValue} from './types' 3 | 4 | /** 5 | * @internal 6 | */ 7 | export const ThemeContext = createGlobalScopedContext( 8 | '@sanity/ui/context/theme', 9 | null, 10 | ) 11 | -------------------------------------------------------------------------------- /src/core/types/grid.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export type GridAutoRows = 'auto' | 'min' | 'max' | 'fr' 5 | 6 | /** 7 | * @public 8 | */ 9 | export type GridAutoCols = 'auto' | 'min' | 'max' | 'fr' 10 | 11 | /** 12 | * @public 13 | */ 14 | export type GridAutoFlow = 'row' | 'column' | 'row dense' | 'column dense' 15 | -------------------------------------------------------------------------------- /src/core/primitives/kbd/__workshop__/plain.tsx: -------------------------------------------------------------------------------- 1 | import {Flex, KBD} from '@sanity/ui' 2 | 3 | export default function PlainStory() { 4 | return ( 5 | 6 | Ctrl 7 | 8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /src/theme/system/index.ts: -------------------------------------------------------------------------------- 1 | export * from './avatar' 2 | export * from './color' 3 | export * from './css' 4 | export * from './focusRing' 5 | export * from './font' 6 | export * from './input' 7 | export * from './layer' 8 | export * from './shadow' 9 | export * from './styles' 10 | export * from './theme' 11 | export * from './v0' 12 | -------------------------------------------------------------------------------- /src/core/components/dialog/useDialog.ts: -------------------------------------------------------------------------------- 1 | import {useContext} from 'react' 2 | 3 | import {DialogContext, DialogContextValue} from './dialogContext' 4 | 5 | /** 6 | * This API might change. DO NOT USE IN PRODUCTION. 7 | * @beta 8 | */ 9 | export function useDialog(): DialogContextValue { 10 | return useContext(DialogContext) 11 | } 12 | -------------------------------------------------------------------------------- /src/core/components/tree/treeContext.ts: -------------------------------------------------------------------------------- 1 | import {createGlobalScopedContext} from '../../lib/createGlobalScopedContext' 2 | import {TreeContextValue} from './types' 3 | 4 | /** 5 | * @internal 6 | */ 7 | export const TreeContext = createGlobalScopedContext( 8 | '@sanity/ui/context/tree', 9 | null, 10 | ) 11 | -------------------------------------------------------------------------------- /src/core/primitives/grid/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/grid', 6 | title: 'Grid', 7 | stories: [ 8 | {name: 'responsive', title: 'Responsive', component: lazy(() => import('./responsive'))}, 9 | ], 10 | }) 11 | -------------------------------------------------------------------------------- /src/core/theme/types.ts: -------------------------------------------------------------------------------- 1 | import {RootTheme, ThemeColorCardToneKey, ThemeColorSchemeKey} from '@sanity/ui/theme' 2 | 3 | /** 4 | * @public 5 | */ 6 | export interface ThemeContextValue { 7 | /** @deprecated No longer used */ 8 | version: 0.0 9 | scheme: ThemeColorSchemeKey 10 | theme: RootTheme 11 | tone: ThemeColorCardToneKey 12 | } 13 | -------------------------------------------------------------------------------- /src/theme/system/v0/color/index.ts: -------------------------------------------------------------------------------- 1 | export * from './_generic' 2 | export * from './_system' 3 | export * from './base' 4 | export * from './button' 5 | export * from './card' 6 | export * from './color' 7 | export * from './input' 8 | export * from './muted' 9 | export * from './selectable' 10 | export * from './solid' 11 | export * from './spot' 12 | -------------------------------------------------------------------------------- /src/core/utils/boundaryElement/boundaryElementContext.ts: -------------------------------------------------------------------------------- 1 | import {createGlobalScopedContext} from '../../lib/createGlobalScopedContext' 2 | import {BoundaryElementContextValue} from './types' 3 | 4 | export const BoundaryElementContext = createGlobalScopedContext( 5 | '@sanity/ui/context/boundaryElement', 6 | null, 7 | ) 8 | -------------------------------------------------------------------------------- /src/core/types/placement.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Placement of floating UI elements. 3 | * 4 | * @public 5 | */ 6 | export type Placement = 7 | | 'top' 8 | | 'top-start' 9 | | 'top-end' 10 | | 'right' 11 | | 'right-start' 12 | | 'right-end' 13 | | 'bottom' 14 | | 'bottom-start' 15 | | 'bottom-end' 16 | | 'left' 17 | | 'left-start' 18 | | 'left-end' 19 | -------------------------------------------------------------------------------- /src/core/observers/resizeObserver.ts: -------------------------------------------------------------------------------- 1 | import {ResizeObserver as ResizeObserverPolyfill} from '@juggle/resize-observer' 2 | 3 | /** 4 | * @internal 5 | */ 6 | export const _ResizeObserver: typeof ResizeObserver = 7 | typeof document !== 'undefined' && typeof window !== 'undefined' && window.ResizeObserver 8 | ? window.ResizeObserver 9 | : ResizeObserverPolyfill 10 | -------------------------------------------------------------------------------- /src/core/styles/internal.ts: -------------------------------------------------------------------------------- 1 | // Not yet ready to be exposed 2 | export * from './border' 3 | export * from './box' 4 | export * from './flex' 5 | export * from './focusRing' 6 | export * from './font' 7 | export * from './grid' 8 | export * from './input' 9 | export * from './margin' 10 | export * from './padding' 11 | export * from './radius' 12 | export * from './shadow' 13 | -------------------------------------------------------------------------------- /src/theme/system/avatar.ts: -------------------------------------------------------------------------------- 1 | import {ThemeFocusRing} from './focusRing' 2 | 3 | /** 4 | * @public 5 | */ 6 | export interface ThemeAvatar_v2 { 7 | sizes: { 8 | /** Spacing between avatars in an component (px) */ 9 | distance: number 10 | /** Diameter of the avatar (px) */ 11 | size: number 12 | }[] 13 | focusRing: ThemeFocusRing 14 | } 15 | -------------------------------------------------------------------------------- /src/theme/system/color/badge.ts: -------------------------------------------------------------------------------- 1 | import {ThemeColorStateToneKey} from './_system' 2 | 3 | /** 4 | * @public 5 | */ 6 | export interface ThemeColorBadgeTone_v2 { 7 | bg: string 8 | fg: string 9 | dot: string 10 | icon: string 11 | } 12 | 13 | /** 14 | * @public 15 | */ 16 | export type ThemeColorBadge_v2 = Record 17 | -------------------------------------------------------------------------------- /src/theme/system/shadow.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export type ThemeBoxShadow = [ 5 | // offsetX, offsetY, blurRadius, spreadRadius 6 | number, 7 | number, 8 | number, 9 | number, 10 | ] 11 | 12 | /** 13 | * @public 14 | */ 15 | export interface ThemeShadow { 16 | umbra: ThemeBoxShadow 17 | penumbra: ThemeBoxShadow 18 | ambient: ThemeBoxShadow 19 | } 20 | -------------------------------------------------------------------------------- /src/core/components/tab/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'components/tab', 6 | title: 'Tab', 7 | stories: [ 8 | { 9 | name: 'example', 10 | title: 'Example', 11 | component: lazy(() => import('./example')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /src/core/primitives/stack/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/stack', 6 | title: 'Stack', 7 | stories: [ 8 | { 9 | name: 'plain', 10 | title: 'Plain', 11 | component: lazy(() => import('./plain')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /src/core/utils/portal/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'utils/portal', 6 | title: 'Portal', 7 | stories: [ 8 | { 9 | name: 'named', 10 | title: 'Named portals', 11 | component: lazy(() => import('./named')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /src/core/components/hotkeys/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'components/hotkeys', 6 | title: 'Hotkeys', 7 | stories: [ 8 | { 9 | name: 'plain', 10 | title: 'Plain', 11 | component: lazy(() => import('./plain')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /src/core/primitives/spinner/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/spinner', 6 | title: 'Spinner', 7 | stories: [ 8 | { 9 | name: 'props', 10 | title: 'Props', 11 | component: lazy(() => import('./Props')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /figma/tsconfig.dist.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.settings", 3 | "include": ["./src"], 4 | "exclude": ["./src/**/*.test.ts"], 5 | "compilerOptions": { 6 | "rootDir": ".", 7 | "outDir": "./dist", 8 | "target": "ES6", 9 | "lib": ["ES2020"], 10 | "typeRoots": ["./node_modules/@types", "./node_modules/@figma"], 11 | "resolveJsonModule": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/core/hooks/useMediaIndex/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'hooks/use-media-index', 6 | title: 'useMediaIndex', 7 | stories: [ 8 | { 9 | name: 'test', 10 | title: 'Test', 11 | component: lazy(() => import('./test')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /src/core/primitives/textArea/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/text-area', 6 | title: 'TextArea', 7 | stories: [ 8 | { 9 | name: 'plain', 10 | title: 'Plain', 11 | component: lazy(() => import('./plain')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /.storybook/manager.ts: -------------------------------------------------------------------------------- 1 | import {addons} from '@storybook/manager-api' 2 | import {themes} from '@storybook/theming' 3 | 4 | addons.setConfig({ 5 | theme: { 6 | ...themes.dark, 7 | brandTitle: 'Sanity UI', 8 | fontBase: 9 | 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Liberation Sans", Helvetica, Arial, system-ui, sans-serif', 10 | }, 11 | }) 12 | -------------------------------------------------------------------------------- /src/core/components/breadcrumbs/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'components/breadcrumbs', 6 | title: 'Breadcrumbs', 7 | stories: [ 8 | { 9 | name: 'example', 10 | title: 'Example', 11 | component: lazy(() => import('./example')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /src/core/hooks/useCustomValidity.ts: -------------------------------------------------------------------------------- 1 | import {useEffect} from 'react' 2 | 3 | /** 4 | * @beta 5 | */ 6 | export function useCustomValidity( 7 | ref: {current: null | {setCustomValidity: (validity: string) => void}}, 8 | customValidity: string | undefined, 9 | ): void { 10 | useEffect(() => { 11 | ref.current?.setCustomValidity(customValidity || '') 12 | }, [customValidity, ref]) 13 | } 14 | -------------------------------------------------------------------------------- /src/core/hooks/useElementRect/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'hooks/useElementRect', 6 | title: 'useElementRect', 7 | stories: [ 8 | { 9 | name: 'example', 10 | title: 'Example', 11 | component: lazy(() => import('./example')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /src/core/primitives/avatar/types.ts: -------------------------------------------------------------------------------- 1 | import {ThemeColorAvatarColorKey} from '@sanity/ui/theme' 2 | 3 | import {AvatarSize} from '../../types' 4 | 5 | /** 6 | * @internal 7 | */ 8 | export interface AvatarRootStyleProps { 9 | $color: ThemeColorAvatarColorKey 10 | } 11 | 12 | /** 13 | * @internal 14 | */ 15 | export interface ResponsiveAvatarSizeStyleProps { 16 | $size: AvatarSize[] 17 | } 18 | -------------------------------------------------------------------------------- /src/core/types/box.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export type BoxSizing = 'content' | 'border' 5 | 6 | /** 7 | * @public 8 | */ 9 | export type BoxDisplay = 'none' | 'block' | 'grid' | 'flex' | 'inline-block' 10 | 11 | /** 12 | * @public 13 | */ 14 | export type BoxHeight = 'stretch' | 'fill' 15 | 16 | /** 17 | * @public 18 | */ 19 | export type BoxOverflow = 'visible' | 'hidden' | 'auto' 20 | -------------------------------------------------------------------------------- /src/core/utils/boundaryElement/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'utils/boundaryElement', 6 | title: 'BoundaryElement', 7 | stories: [ 8 | { 9 | name: 'plain', 10 | title: 'Plain', 11 | component: lazy(() => import('./plain')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /src/theme/system/color/avatar.ts: -------------------------------------------------------------------------------- 1 | import {ThemeColorAvatarColorKey, ThemeColorBlendModeKey} from './_system' 2 | 3 | /** 4 | * @public 5 | */ 6 | export interface ThemeColorAvatarHue_v2 { 7 | _blend?: ThemeColorBlendModeKey 8 | bg: string 9 | fg: string 10 | } 11 | 12 | /** 13 | * @public 14 | */ 15 | export type ThemeColorAvatar_v2 = Record 16 | -------------------------------------------------------------------------------- /src/theme/system/v0/color/spot.ts: -------------------------------------------------------------------------------- 1 | import {ThemeColorAvatarColorKey} from '../../color/_system' 2 | 3 | /** 4 | * @public 5 | * @deprecated Use `ThemeColorAvatarColorKey` instead 6 | */ 7 | export type ThemeColorSpotKey = ThemeColorAvatarColorKey 8 | 9 | /** 10 | * @public 11 | * @deprecated Use `ThemeColorAvatar_v2` instead 12 | */ 13 | export type ThemeColorSpot = Record 14 | -------------------------------------------------------------------------------- /src/core/components/dialog/__workshop__/provider.tsx: -------------------------------------------------------------------------------- 1 | import {Dialog, DialogProvider} from '@sanity/ui' 2 | 3 | export default function ProviderStory() { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /src/core/primitives/flex/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/flex', 6 | title: 'Flex', 7 | stories: [ 8 | {name: 'plain', title: 'Plain', component: lazy(() => import('./example'))}, 9 | {name: 'gap', title: 'Gap', component: lazy(() => import('./gap'))}, 10 | ], 11 | }) 12 | -------------------------------------------------------------------------------- /src/core/primitives/tooltip/tooltipDelayGroup/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @beta 3 | */ 4 | export interface TooltipDelayGroupContextValue { 5 | setIsGroupActive: (nextState: React.SetStateAction, delay?: number | undefined) => void 6 | setOpenTooltipId: (nextId: string | null, delay?: number | undefined) => void 7 | openDelay: number 8 | closeDelay: number 9 | openTooltipId: string | null 10 | } 11 | -------------------------------------------------------------------------------- /src/core/utils/elementQuery/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'utils/elementQuery', 6 | title: 'ElementQuery', 7 | stories: [ 8 | { 9 | name: 'custom-media', 10 | title: 'Custom media', 11 | component: lazy(() => import('./customMedia')), 12 | }, 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /src/theme/system/color/index.ts: -------------------------------------------------------------------------------- 1 | export * from './_constants' 2 | export * from './_helpers' 3 | export * from './_system' 4 | export * from './avatar' 5 | export * from './badge' 6 | export * from './button' 7 | export * from './color' 8 | export * from './input' 9 | export * from './kbd' 10 | export * from './selectable' 11 | export * from './shadow' 12 | export * from './state' 13 | export * from './syntax' 14 | -------------------------------------------------------------------------------- /src/core/components/tree/useTree.ts: -------------------------------------------------------------------------------- 1 | import {useContext} from 'react' 2 | 3 | import {TreeContext} from './treeContext' 4 | import {TreeContextValue} from './types' 5 | 6 | /** 7 | * @beta 8 | */ 9 | export function useTree(): TreeContextValue { 10 | const tree = useContext(TreeContext) 11 | 12 | if (!tree) { 13 | throw new Error('Tree: missing context value') 14 | } 15 | 16 | return tree 17 | } 18 | -------------------------------------------------------------------------------- /src/theme/system/v0/color/_system.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | * @deprecated Use `ThemeColorCardToneKey` instead. 4 | */ 5 | export type ThemeColorName = 6 | | 'transparent' 7 | | 'default' 8 | | 'primary' 9 | | 'positive' 10 | | 'caution' 11 | | 'critical' 12 | 13 | /** 14 | * @public 15 | * @deprecated Use `ThemeColorCardToneKey` instead. 16 | */ 17 | export type ThemeColorToneKey = ThemeColorName 18 | -------------------------------------------------------------------------------- /src/core/theme/useTheme.ts: -------------------------------------------------------------------------------- 1 | import {getTheme_v2, Theme, Theme_v2} from '@sanity/ui/theme' 2 | import {useTheme as useStyledTheme} from 'styled-components' 3 | 4 | /** 5 | * @public 6 | */ 7 | export function useTheme(): Theme { 8 | return useStyledTheme() as Theme 9 | } 10 | 11 | /** 12 | * @public 13 | */ 14 | export function useTheme_v2(): Theme_v2 { 15 | return getTheme_v2(useStyledTheme() as Theme) 16 | } 17 | -------------------------------------------------------------------------------- /src/theme/system/color/selectable.ts: -------------------------------------------------------------------------------- 1 | import {ThemeColorStateKey, ThemeColorStateToneKey} from './_system' 2 | import {ThemeColorState_v2} from './state' 3 | 4 | /** 5 | * @public 6 | */ 7 | export type ThemeColorSelectableTone_v2 = Record 8 | 9 | /** 10 | * @public 11 | */ 12 | export type ThemeColorSelectable_v2 = Record 13 | -------------------------------------------------------------------------------- /figma/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.settings", 3 | "include": ["../exports", "../src", "../typings", "./src"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "rootDir": "..", 7 | "outDir": "./dist/types", 8 | "target": "ES6", 9 | "lib": ["ES2020"], 10 | "paths": { 11 | "@sanity/ui/*": ["../exports/*"], 12 | "@sanity/ui": ["../exports"] 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/core/helpers/scroll.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export function _isScrollable(el: Node): boolean { 5 | if (!(el instanceof Element)) return false 6 | 7 | const style = window.getComputedStyle(el) 8 | 9 | return ( 10 | style.overflowX.includes('auto') || 11 | style.overflowX.includes('scroll') || 12 | style.overflowY.includes('auto') || 13 | style.overflowY.includes('scroll') 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /src/core/primitives/radio/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/radio', 6 | title: 'Radio', 7 | stories: [ 8 | {name: 'plain', title: 'Plain', component: lazy(() => import('./plain'))}, 9 | {name: 'example', title: 'Example', component: lazy(() => import('./example'))}, 10 | ], 11 | }) 12 | -------------------------------------------------------------------------------- /src/core/primitives/switch/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/switch', 6 | title: 'Switch', 7 | stories: [ 8 | {name: 'props', title: 'Props', component: lazy(() => import('./props'))}, 9 | {name: 'example', title: 'Example', component: lazy(() => import('./example'))}, 10 | ], 11 | }) 12 | -------------------------------------------------------------------------------- /src/core/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './avatar' 2 | export * from './badge' 3 | export * from './box' 4 | export * from './button' 5 | export * from './card' 6 | export * from './dialog' 7 | export * from './flex' 8 | export * from './grid' 9 | export * from './gridItem' 10 | export * from './placement' 11 | export * from './popover' 12 | export * from './radius' 13 | export * from './selectable' 14 | export * from './text' 15 | -------------------------------------------------------------------------------- /src/core/hooks/useElementRect/useElementRect.ts: -------------------------------------------------------------------------------- 1 | import {useElementSize} from '../useElementSize' 2 | 3 | /** 4 | * Subscribe to the rect of a DOM element. 5 | * @beta 6 | * 7 | * @deprecated Use `useElementSize` instead 8 | */ 9 | export function useElementRect(element: HTMLElement | null): DOMRectReadOnly | null { 10 | const elementSize = useElementSize(element) 11 | 12 | return elementSize?._contentRect || null 13 | } 14 | -------------------------------------------------------------------------------- /src/core/primitives/select/__workshop__/index.ts: -------------------------------------------------------------------------------- 1 | import {defineScope} from '@sanity/ui-workshop' 2 | import {lazy} from 'react' 3 | 4 | export default defineScope({ 5 | name: 'primitives/select', 6 | title: 'Select', 7 | stories: [ 8 | {name: 'plain', title: 'Plain', component: lazy(() => import('./plain'))}, 9 | {name: 'read-only', title: 'Read-only', component: lazy(() => import('./readOnly'))}, 10 | ], 11 | }) 12 | -------------------------------------------------------------------------------- /src/core/primitives/tooltip/tooltipDelayGroup/tooltipDelayGroupContext.tsx: -------------------------------------------------------------------------------- 1 | import {createGlobalScopedContext} from '../../../lib/createGlobalScopedContext' 2 | import {TooltipDelayGroupContextValue} from './types' 3 | 4 | /** 5 | * @beta 6 | */ 7 | export const TooltipDelayGroupContext = 8 | createGlobalScopedContext( 9 | '@sanity/ui/context/tooltipDelayGroup', 10 | null, 11 | ) 12 | -------------------------------------------------------------------------------- /src/core/utils/layer/__workshop__/responsiveZOffset.tsx: -------------------------------------------------------------------------------- 1 | import {Card, Layer} from '@sanity/ui' 2 | 3 | import {LayerDebugInfo} from './_debug' 4 | 5 | export default function ResponsiveZOffsetStory() { 6 | return ( 7 | 8 | 9 | 10 | 11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /figma/package.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from '@sanity/pkg-utils' 2 | 3 | export default defineConfig({ 4 | babel: { 5 | plugins: ['@babel/plugin-transform-object-rest-spread'], 6 | }, 7 | dist: './dist', 8 | src: './src', 9 | tsconfig: './tsconfig.dist.json', 10 | strictOptions: { 11 | alwaysPackageJsonMain: 'off', 12 | alwaysPackageJsonFiles: 'off', 13 | noImplicitBrowsersList: 'off', 14 | }, 15 | }) 16 | -------------------------------------------------------------------------------- /src/theme/build/lib/color-fns/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export interface RGB { 5 | r: number 6 | g: number 7 | b: number 8 | a?: undefined 9 | } 10 | 11 | /** 12 | * @internal 13 | */ 14 | export interface RGBA { 15 | r: number 16 | g: number 17 | b: number 18 | a: number 19 | } 20 | 21 | /** 22 | * @internal 23 | */ 24 | export interface HSL { 25 | h: number 26 | s: number 27 | l: number 28 | } 29 | -------------------------------------------------------------------------------- /src/core/hooks/useMounted.ts: -------------------------------------------------------------------------------- 1 | import {useSyncExternalStore} from 'react' 2 | 3 | /** 4 | * Some components should only render after mounting to the DOM, and not be rendered at all during SSR renderToString or equivalent. 5 | * @public 6 | */ 7 | export function useMounted(): boolean { 8 | return useSyncExternalStore( 9 | subscribe, 10 | () => true, 11 | () => false, 12 | ) 13 | } 14 | 15 | const subscribe = () => () => {} 16 | -------------------------------------------------------------------------------- /src/core/primitives/popover/__workshop__/OpenOnMountStory.tsx: -------------------------------------------------------------------------------- 1 | import {Button, Card, Popover, Text} from '@sanity/ui' 2 | 3 | export default function OpenOnMountStory() { 4 | return ( 5 | 6 | popover content} open padding={3}> 7 | 10 | 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/core/styles/font/headingFontStyle.ts: -------------------------------------------------------------------------------- 1 | import {CSSObject} from '@sanity/ui/theme' 2 | 3 | import {ThemeProps} from '../types' 4 | import {responsiveFont} from './responsiveFont' 5 | import {ResponsiveFontStyleProps} from './types' 6 | 7 | /** 8 | * Get responsive CSS for the `heading` font style. 9 | * @internal 10 | */ 11 | export function responsiveHeadingFont(props: ResponsiveFontStyleProps & ThemeProps): CSSObject[] { 12 | return responsiveFont('heading', props) 13 | } 14 | -------------------------------------------------------------------------------- /src/theme/system/v0/input.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | * @deprecated Use `ThemeInput_v2` instead 4 | */ 5 | export interface ThemeInput { 6 | checkbox: { 7 | size: number 8 | } 9 | radio: { 10 | size: number 11 | markSize: number 12 | } 13 | switch: { 14 | width: number 15 | height: number 16 | padding: number 17 | transitionDurationMs: number 18 | transitionTimingFunction: string 19 | } 20 | border: { 21 | width: number 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/core/primitives/button/__workshop__/styled1.tsx: -------------------------------------------------------------------------------- 1 | import {Button, Flex} from '@sanity/ui' 2 | import {styled} from 'styled-components' 3 | 4 | const StyledButton1 = styled.a` 5 | &:hover { 6 | background-color: red; 7 | box-shadow: none; 8 | } 9 | ` 10 | 11 | export default function StyledButton1Story() { 12 | return ( 13 | 14 | 4 | 5 | 6 | 7 | 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.settings", 3 | "include": [ 4 | "./.storybook", 5 | "./exports", 6 | "./package.config.ts", 7 | "./scripts", 8 | "./src", 9 | "./stories", 10 | "./test", 11 | "./typings", 12 | "./workshop", 13 | "./workshop.config.ts", 14 | "./workshop.runtime.ts" 15 | ], 16 | "compilerOptions": { 17 | "rootDir": ".", 18 | "outDir": "./dist/types", 19 | "baseUrl": ".", 20 | "paths": { 21 | "@sanity/ui/*": ["./exports/*"], 22 | "@sanity/ui": ["./exports"] 23 | }, 24 | // Setting "jsx" to aynthing but "preserve" is usually incorrect, but at the moment Storybook needs it 25 | "jsx": "react-jsx" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/core/utils/boundaryElement/__workshop__/plain.tsx: -------------------------------------------------------------------------------- 1 | import {BoundaryElementProvider, Button, Card, Text, Tooltip} from '@sanity/ui' 2 | import {useState} from 'react' 3 | 4 | export default function PlainStory() { 5 | const [boundaryElement, setBoundaryElement] = useState(null) 6 | 7 | return ( 8 | 9 | 10 | Test aldsakm alkdmal dmalskdm alkdmlakds} 12 | placement="top" 13 | > 14 |