@sanity/ui 3.1.14 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/_chunks-cjs/_visual-editing.js +323 -292
  2. package/dist/_chunks-cjs/_visual-editing.js.map +1 -1
  3. package/dist/_chunks-es/_visual-editing.mjs +323 -292
  4. package/dist/_chunks-es/_visual-editing.mjs.map +1 -1
  5. package/dist/_visual-editing.d.mts +195 -76
  6. package/dist/_visual-editing.d.ts +195 -76
  7. package/dist/index.d.mts +308 -140
  8. package/dist/index.d.ts +308 -140
  9. package/dist/index.js +97 -93
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +97 -93
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/theme.d.mts +10 -4
  14. package/dist/theme.d.ts +10 -4
  15. package/package.json +1 -1
  16. package/src/core/components/autocomplete/autocomplete.tsx +1 -1
  17. package/src/core/components/autocomplete/types.ts +2 -2
  18. package/src/core/components/breadcrumbs/breadcrumbs.test.tsx +51 -0
  19. package/src/core/components/breadcrumbs/breadcrumbs.tsx +7 -3
  20. package/src/core/components/hotkeys/hotkeys.test.tsx +42 -0
  21. package/src/core/components/hotkeys/hotkeys.tsx +7 -3
  22. package/src/core/components/menu/__workshop__/asComponent.tsx +1 -1
  23. package/src/core/components/menu/menu.spacing.test.tsx +63 -0
  24. package/src/core/components/menu/menu.tsx +8 -2
  25. package/src/core/components/menu/menuDivider.ts +16 -5
  26. package/src/core/components/menu/menuGroup.spacing.test.tsx +63 -0
  27. package/src/core/components/menu/menuGroup.tsx +22 -8
  28. package/src/core/components/menu/menuItem.spacing.test.tsx +59 -0
  29. package/src/core/components/menu/menuItem.tsx +25 -8
  30. package/src/core/components/skeleton/skeleton.tsx +2 -2
  31. package/src/core/components/tab/tabList.test.tsx +48 -0
  32. package/src/core/components/tab/tabList.tsx +2 -2
  33. package/src/core/components/tab/tabPanel.tsx +2 -2
  34. package/src/core/components/toast/styles.ts +2 -2
  35. package/src/core/components/tree/__workshop__/basic.perf.ts +1 -1
  36. package/src/core/components/tree/__workshop__/tabFromElement.tsx +1 -1
  37. package/src/core/components/tree/tree.test.tsx +55 -0
  38. package/src/core/components/tree/tree.tsx +19 -10
  39. package/src/core/components/tree/treeGroup.tsx +3 -3
  40. package/src/core/components/tree/treeItem.test.tsx +65 -0
  41. package/src/core/components/tree/treeItem.tsx +11 -4
  42. package/src/core/components/tree/types.ts +4 -0
  43. package/src/core/primitives/avatar/avatar.tsx +19 -11
  44. package/src/core/primitives/badge/badge.tsx +20 -12
  45. package/src/core/primitives/box/__workshop__/asComponent.tsx +31 -0
  46. package/src/core/primitives/box/__workshop__/index.ts +5 -0
  47. package/src/core/primitives/box/box.test.tsx +142 -0
  48. package/src/core/primitives/box/box.tsx +41 -18
  49. package/src/core/primitives/button/__workshop__/disabled.tsx +2 -2
  50. package/src/core/primitives/button/__workshop__/sanityUploadButton.tsx +1 -1
  51. package/src/core/primitives/button/__workshop__/uploadButton.tsx +1 -1
  52. package/src/core/primitives/button/button.test.tsx +41 -3
  53. package/src/core/primitives/button/button.tsx +36 -12
  54. package/src/core/primitives/card/__workshop__/asComponent.tsx +1 -1
  55. package/src/core/primitives/card/card.tsx +24 -13
  56. package/src/core/primitives/code/code.tsx +16 -7
  57. package/src/core/primitives/container/container.tsx +23 -10
  58. package/src/core/primitives/flex/flex.tsx +21 -11
  59. package/src/core/primitives/grid/grid.test.tsx +80 -0
  60. package/src/core/primitives/grid/grid.tsx +39 -13
  61. package/src/core/primitives/heading/heading.tsx +19 -11
  62. package/src/core/primitives/inline/inline.test.tsx +51 -0
  63. package/src/core/primitives/inline/inline.tsx +28 -12
  64. package/src/core/primitives/kbd/kbd.tsx +19 -11
  65. package/src/core/primitives/label/label.tsx +19 -11
  66. package/src/core/primitives/popover/__workshop__/SidePanelStory.tsx +1 -1
  67. package/src/core/primitives/select/select.test.tsx +52 -0
  68. package/src/core/primitives/select/select.tsx +8 -2
  69. package/src/core/primitives/stack/stack.test.tsx +57 -0
  70. package/src/core/primitives/stack/stack.tsx +27 -13
  71. package/src/core/primitives/text/text.tsx +19 -11
  72. package/src/core/primitives/textInput/textInput.test.tsx +48 -0
  73. package/src/core/primitives/textInput/textInput.tsx +9 -4
  74. package/src/core/primitives/types.ts +33 -0
  75. package/src/core/types/component.ts +32 -0
  76. package/src/core/types/index.ts +1 -0
  77. package/src/core/utils/virtualList/virtualList.tsx +2 -2
  78. package/src/theme/system/css.ts +10 -4
@@ -2,42 +2,56 @@ import {forwardRef} from 'react'
2
2
  import {styled} from 'styled-components'
3
3
 
4
4
  import {_getArrayProp} from '../../styles'
5
- import {Box, BoxProps} from '../box'
5
+ import {ElementType, Props} from '../../types'
6
+ import {Box, BoxOwnProps} from '../box'
6
7
  import {responsiveStackSpaceStyle, ResponsiveStackSpaceStyleProps, stackBaseStyle} from './styles'
7
8
 
8
9
  /**
9
10
  * @public
10
11
  */
11
- export interface StackProps extends BoxProps {
12
- as?: React.ElementType | keyof React.JSX.IntrinsicElements
12
+ export interface StackOwnProps extends BoxOwnProps {
13
+ gap?: number | number[]
14
+ /**
15
+ * @deprecated Use `gap` instead. `space` will be removed in v4.
16
+ */
13
17
  space?: number | number[]
14
18
  }
15
19
 
20
+ /**
21
+ * @public
22
+ */
23
+ export type StackProps<E extends ElementType = 'div'> = Props<StackOwnProps, E>
24
+
16
25
  const StyledStack = styled(Box)<ResponsiveStackSpaceStyleProps>(
17
26
  stackBaseStyle,
18
27
  responsiveStackSpaceStyle,
19
28
  )
20
29
 
21
- /**
22
- * The `Stack` component is used to place elements on top of each other.
23
- *
24
- * @public
25
- */
26
- export const Stack = forwardRef(function Stack(
27
- props: StackProps & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'ref'>,
30
+ const StackComponent = forwardRef(function Stack(
31
+ props: StackOwnProps & {as?: ElementType} & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'ref'>,
28
32
  ref: React.ForwardedRef<HTMLDivElement>,
29
33
  ) {
30
- const {as, space, ...restProps} = props
34
+ const {as, gap, space: deprecated_space, ...restProps} = props
35
+ const spacing = gap === undefined ? deprecated_space : gap
31
36
 
32
37
  return (
33
38
  <StyledStack
34
39
  data-as={typeof as === 'string' ? as : undefined}
35
40
  data-ui="Stack"
36
41
  {...restProps}
37
- $space={_getArrayProp(space)}
42
+ $space={_getArrayProp(spacing)}
38
43
  forwardedAs={as}
39
44
  ref={ref}
40
45
  />
41
46
  )
42
47
  })
43
- Stack.displayName = 'ForwardRef(Stack)'
48
+ StackComponent.displayName = 'ForwardRef(Stack)'
49
+
50
+ /**
51
+ * The `Stack` component is used to place elements on top of each other.
52
+ *
53
+ * @public
54
+ */
55
+ export const Stack = StackComponent as unknown as <E extends ElementType = 'div'>(
56
+ props: StackProps<E>,
57
+ ) => React.JSX.Element
@@ -8,17 +8,16 @@ import {
8
8
  responsiveTextAlignStyle,
9
9
  responsiveTextFont,
10
10
  } from '../../styles/internal'
11
- import {TextAlign} from '../../types'
11
+ import {ElementType, Props, TextAlign} from '../../types'
12
12
  import {SpanWithTextOverflow} from '../../utils/spanWithTextOverflow'
13
13
  import {textBaseStyle} from './styles'
14
14
 
15
15
  /**
16
16
  * @public
17
17
  */
18
- export interface TextProps {
18
+ export interface TextOwnProps {
19
19
  accent?: boolean
20
20
  align?: TextAlign | TextAlign[]
21
- as?: React.ElementType | keyof React.JSX.IntrinsicElements
22
21
  /** When `true` the text color will be muted. */
23
22
  muted?: boolean
24
23
  size?: number | number[]
@@ -31,19 +30,19 @@ export interface TextProps {
31
30
  weight?: ThemeFontWeightKey
32
31
  }
33
32
 
33
+ /**
34
+ * @public
35
+ */
36
+ export type TextProps<E extends ElementType = 'div'> = Props<TextOwnProps, E>
37
+
34
38
  const StyledText = styled.div<ResponsiveFontStyleProps>(
35
39
  responsiveTextFont,
36
40
  responsiveTextAlignStyle,
37
41
  textBaseStyle,
38
42
  )
39
43
 
40
- /**
41
- * The `Text` component is an agile, themed typographic element.
42
- *
43
- * @public
44
- */
45
- export const Text = forwardRef(function Text(
46
- props: TextProps & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'size'>,
44
+ const TextComponent = forwardRef(function Text(
45
+ props: TextOwnProps & {as?: ElementType} & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'size'>,
47
46
  ref: React.ForwardedRef<HTMLDivElement>,
48
47
  ) {
49
48
  const {
@@ -78,4 +77,13 @@ export const Text = forwardRef(function Text(
78
77
  </StyledText>
79
78
  )
80
79
  })
81
- Text.displayName = 'ForwardRef(Text)'
80
+ TextComponent.displayName = 'ForwardRef(Text)'
81
+
82
+ /**
83
+ * The `Text` component is an agile, themed typographic element.
84
+ *
85
+ * @public
86
+ */
87
+ export const Text = TextComponent as unknown as <E extends ElementType = 'div'>(
88
+ props: TextProps<E>,
89
+ ) => React.JSX.Element
@@ -0,0 +1,48 @@
1
+ /** @jest-environment jsdom */
2
+
3
+ import {render} from '../../../../test'
4
+ import {responsiveInputPaddingStyle} from '../../styles/internal'
5
+ import {TextInput} from './textInput'
6
+
7
+ jest.mock('../../styles/internal', () => {
8
+ const actual = jest.requireActual('../../styles/internal')
9
+
10
+ return {
11
+ ...actual,
12
+ responsiveInputPaddingStyle: jest.fn(actual.responsiveInputPaddingStyle),
13
+ }
14
+ })
15
+
16
+ describe('primitives/textInput', () => {
17
+ const mockedResponsiveInputPaddingStyle = jest.mocked(responsiveInputPaddingStyle)
18
+
19
+ beforeEach(() => {
20
+ mockedResponsiveInputPaddingStyle.mockClear()
21
+ })
22
+
23
+ it('should support `space` and `gap` with the same behavior', () => {
24
+ render(<TextInput icon={() => null} space={2} />)
25
+
26
+ expect(mockedResponsiveInputPaddingStyle).toHaveBeenCalledWith(
27
+ expect.objectContaining({$space: [2]}),
28
+ )
29
+
30
+ mockedResponsiveInputPaddingStyle.mockClear()
31
+ render(<TextInput gap={2} icon={() => null} />)
32
+
33
+ expect(mockedResponsiveInputPaddingStyle).toHaveBeenCalledWith(
34
+ expect.objectContaining({$space: [2]}),
35
+ )
36
+ })
37
+
38
+ it('should prefer `gap` over `space` when both are provided', () => {
39
+ render(<TextInput gap={3} icon={() => null} space={1} />)
40
+
41
+ expect(mockedResponsiveInputPaddingStyle).toHaveBeenCalledWith(
42
+ expect.objectContaining({$space: [3]}),
43
+ )
44
+ expect(mockedResponsiveInputPaddingStyle).not.toHaveBeenCalledWith(
45
+ expect.objectContaining({$space: [1]}),
46
+ )
47
+ })
48
+ })
@@ -22,14 +22,14 @@ import {
22
22
  import {useRootTheme} from '../../theme'
23
23
  import {Radius} from '../../types'
24
24
  import {Box} from '../box'
25
- import {Button, ButtonProps} from '../button'
25
+ import {Button, ButtonOwnProps} from '../button'
26
26
  import {Card} from '../card'
27
27
  import {Text} from '../text'
28
28
 
29
29
  /**
30
30
  * @public
31
31
  */
32
- export type TextInputClearButtonProps = Omit<ButtonProps, 'as'> &
32
+ export type TextInputClearButtonProps = ButtonOwnProps &
33
33
  Omit<React.HTMLProps<HTMLButtonElement>, 'as' | 'onClick' | 'onMouseDown' | 'ref'>
34
34
 
35
35
  /**
@@ -74,7 +74,11 @@ export interface TextInputProps {
74
74
  padding?: number | number[]
75
75
  prefix?: React.ReactNode
76
76
  radius?: Radius | Radius[]
77
+ /**
78
+ * @deprecated Use `gap` instead. `space` will be removed in v4.
79
+ */
77
80
  space?: number | number[]
81
+ gap?: number | number[]
78
82
  suffix?: React.ReactNode
79
83
  type?: TextInputType
80
84
  weight?: ThemeFontWeightKey
@@ -162,6 +166,7 @@ export const TextInput = forwardRef(function TextInput(
162
166
  clearButton,
163
167
  disabled = false,
164
168
  fontSize: fontSizeProp = 2,
169
+ gap,
165
170
  icon: IconComponent,
166
171
  iconRight: IconRightComponent,
167
172
  onClear,
@@ -169,7 +174,7 @@ export const TextInput = forwardRef(function TextInput(
169
174
  prefix,
170
175
  radius: radiusProp = 2,
171
176
  readOnly,
172
- space: spaceProp = 3,
177
+ space: deprecated_space = 3,
173
178
  suffix,
174
179
  customValidity,
175
180
  type = 'text',
@@ -183,7 +188,7 @@ export const TextInput = forwardRef(function TextInput(
183
188
  const fontSize = _getArrayProp(fontSizeProp)
184
189
  const padding = _getArrayProp(paddingProp)
185
190
  const radius = _getArrayProp(radiusProp)
186
- const space = _getArrayProp(spaceProp)
191
+ const space = _getArrayProp(gap === undefined ? deprecated_space : gap)
187
192
 
188
193
  // Transient properties
189
194
  const $hasClearButton = Boolean(clearButton)
@@ -66,22 +66,55 @@ export interface ResponsiveGridProps {
66
66
  autoRows?: GridAutoRows | GridAutoRows[]
67
67
  autoCols?: GridAutoCols | GridAutoCols[]
68
68
  autoFlow?: GridAutoFlow | GridAutoFlow[]
69
+
70
+ /**
71
+ * @deprecated Use `gridTemplateColumns` instead. `columns` will be removed in v4.
72
+ */
69
73
  columns?: number | number[]
74
+ gridTemplateColumns?: number | number[]
70
75
  gap?: number | number[]
71
76
  gapX?: number | number[]
72
77
  gapY?: number | number[]
78
+ /**
79
+ * @deprecated Use `gridTemplateRows` instead. `rows` will be removed in v4.
80
+ */
73
81
  rows?: number | number[]
82
+ gridTemplateRows?: number | number[]
74
83
  }
75
84
 
76
85
  /**
77
86
  * @public
78
87
  */
79
88
  export interface ResponsiveGridItemProps {
89
+ gridColumn?: GridItemColumn | GridItemColumn[]
90
+ /**
91
+ * @deprecated Use `gridColumn` instead. `column` will be removed in v4.
92
+ */
80
93
  column?: GridItemColumn | GridItemColumn[]
94
+ gridColumnStart?: GridItemColumnStart | GridItemColumnStart[]
95
+ /**
96
+ * @deprecated Use `gridColumnStart` instead. `columnStart` will be removed in v4.
97
+ */
81
98
  columnStart?: GridItemColumnStart | GridItemColumnStart[]
99
+ gridColumnEnd?: GridItemColumnEnd | GridItemColumnEnd[]
100
+ /**
101
+ * @deprecated Use `gridColumnEnd` instead. `columnEnd` will be removed in v4.
102
+ */
82
103
  columnEnd?: GridItemColumnEnd | GridItemColumnEnd[]
104
+ gridRow?: GridItemRow | GridItemRow[]
105
+ /**
106
+ * @deprecated Use `gridRow` instead. `row` will be removed in v4.
107
+ */
83
108
  row?: GridItemRow | GridItemRow[]
109
+ gridRowStart?: GridItemRowStart | GridItemRowStart[]
110
+ /**
111
+ * @deprecated Use `gridRowStart` instead. `rowStart` will be removed in v4.
112
+ */
84
113
  rowStart?: GridItemRowStart | GridItemRowStart[]
114
+ gridRowEnd?: GridItemRowEnd | GridItemRowEnd[]
115
+ /**
116
+ * @deprecated Use `gridRowEnd` instead. `rowEnd` will be removed in v4.
117
+ */
85
118
  rowEnd?: GridItemRowEnd | GridItemRowEnd[]
86
119
  }
87
120
 
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Assign properties from `U` to `T`, excluding properties that already exist in `T`.
3
+ *
4
+ * @public
5
+ */
6
+ export type Assign<T extends object, U extends object> = Omit<T, keyof U> & U
7
+
8
+ /** @public */
9
+ export type EmptyProps = object
10
+
11
+ /** @public */
12
+ export type TagType = keyof React.JSX.IntrinsicElements
13
+
14
+ /** @public */
15
+ export type ComponentType<P = any> =
16
+ | React.FunctionComponent<P>
17
+ | React.ComponentClass<P>
18
+ | React.ExoticComponent<P>
19
+
20
+ /** @public */
21
+ export type ElementType<P = any> = TagType | ComponentType<P>
22
+
23
+ /**
24
+ * Resolves the props of a polymorphic component: the props of the element/component passed to `as`
25
+ * (defaulting to the component's own element), with the component's own props assigned on top.
26
+ *
27
+ * @public
28
+ */
29
+ export type Props<P extends EmptyProps, E extends ElementType<P>> = Assign<
30
+ E extends TagType ? React.JSX.IntrinsicElements[E] : React.ComponentProps<E>,
31
+ P & {as?: E}
32
+ >
@@ -3,6 +3,7 @@ export * from './badge'
3
3
  export * from './box'
4
4
  export * from './button'
5
5
  export * from './card'
6
+ export * from './component'
6
7
  export * from './dialog'
7
8
  export * from './flex'
8
9
  export * from './grid'
@@ -3,7 +3,7 @@ import {styled} from 'styled-components'
3
3
 
4
4
  import {_isScrollable} from '../../helpers'
5
5
  import {_ResizeObserver} from '../../observers'
6
- import {StackProps} from '../../primitives'
6
+ import {StackOwnProps} from '../../primitives'
7
7
  import {useTheme_v2} from '../../theme'
8
8
 
9
9
  /**
@@ -45,7 +45,7 @@ const ItemWrapper = styled.div`
45
45
  */
46
46
  export const VirtualList = forwardRef(function VirtualList(
47
47
  props: VirtualListProps &
48
- StackProps &
48
+ StackOwnProps &
49
49
  Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'children' | 'onChange' | 'ref'>,
50
50
  forwardedRef: React.ForwardedRef<HTMLDivElement>,
51
51
  ): React.JSX.Element {
@@ -1,8 +1,14 @@
1
- import type {StyledObject} from 'styled-components'
1
+ import type * as CSS from 'csstype'
2
2
 
3
3
  /**
4
- * Work around types that are missing in `styled-components@6`
5
- * https://github.com/styled-components/styled-components/issues/4062
4
+ * A CSS-in-JS style object: standard CSS properties plus an index signature that allows nested
5
+ * selectors, at-rules and custom properties.
6
+ *
7
+ * This is a self-owned definition (based on `csstype`) so the published `.d.ts` types stay fully
8
+ * controlled by us and do not reference any external CSS-in-JS library types.
9
+ *
6
10
  * @internal
7
11
  */
8
- export type CSSObject = StyledObject<any>
12
+ export interface CSSObject extends CSS.Properties<number | (string & {})> {
13
+ [key: string]: CSSObject | string | number | undefined
14
+ }