@sanity/ui 3.0.0-static.11 → 3.0.0-static.13

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 (251) hide show
  1. package/dist/_chunks-cjs/_visual-editing.js +1293 -1215
  2. package/dist/_chunks-cjs/_visual-editing.js.map +1 -1
  3. package/dist/_chunks-cjs/buildCommand.js +28 -10
  4. package/dist/_chunks-cjs/buildCommand.js.map +1 -1
  5. package/dist/_chunks-es/_visual-editing.mjs +1284 -1202
  6. package/dist/_chunks-es/_visual-editing.mjs.map +1 -1
  7. package/dist/_visual-editing.d.mts +528 -358
  8. package/dist/_visual-editing.d.ts +528 -358
  9. package/dist/cli.js +1 -1
  10. package/dist/css.d.mts +143 -73
  11. package/dist/css.d.ts +143 -73
  12. package/dist/css.js +329 -472
  13. package/dist/css.js.map +1 -1
  14. package/dist/css.mjs +330 -473
  15. package/dist/css.mjs.map +1 -1
  16. package/dist/index.d.mts +1362 -869
  17. package/dist/index.d.ts +1362 -869
  18. package/dist/index.js +383 -308
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.mjs +387 -312
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/sanity-palette.css +105 -1
  23. package/dist/sanity-palette.min.css +1 -0
  24. package/dist/sanity-theme.css +4571 -1
  25. package/dist/sanity-theme.min.css +1 -0
  26. package/dist/system.css +22053 -21946
  27. package/dist/system.min.css +1 -0
  28. package/dist/theme.d.mts +51 -106
  29. package/dist/theme.d.ts +51 -106
  30. package/dist/theme.js +9 -9
  31. package/dist/theme.js.map +1 -1
  32. package/dist/theme.mjs +9 -9
  33. package/dist/theme.mjs.map +1 -1
  34. package/package.json +10 -5
  35. package/src/cli/buildCommand.ts +46 -19
  36. package/src/css/_comp.ts +2 -2
  37. package/src/css/{compile/compileStyle.ts → _compileStyle.ts} +7 -7
  38. package/src/css/{system.style.ts → _system.style.ts} +3 -2
  39. package/src/css/aspects/display/display.ts +1 -0
  40. package/src/css/aspects/display/types.ts +2 -3
  41. package/src/css/aspects/flex/types.ts +4 -12
  42. package/src/css/aspects/flexItem/types.ts +1 -3
  43. package/src/css/aspects/font/types.ts +1 -3
  44. package/src/css/aspects/grid/grid.ts +1 -0
  45. package/src/css/aspects/grid/types.ts +5 -9
  46. package/src/css/aspects/gridItem/gridItem.ts +1 -1
  47. package/src/css/aspects/gridItem/types.ts +7 -18
  48. package/src/css/aspects/height/height.ts +3 -4
  49. package/src/css/aspects/inset/inset.ts +1 -0
  50. package/src/css/aspects/margin/margin.ts +1 -0
  51. package/src/css/aspects/margin/types.ts +1 -0
  52. package/src/css/aspects/maxWidth/maxWidth.ts +1 -0
  53. package/src/css/aspects/maxWidth/types.ts +1 -0
  54. package/src/css/aspects/minWidth/minWidth.ts +1 -0
  55. package/src/css/aspects/minWidth/types.ts +2 -0
  56. package/src/css/aspects/overflow/overflow.ts +1 -0
  57. package/src/css/aspects/padding/padding.ts +1 -0
  58. package/src/css/aspects/pointerEvents/pointerEvents.ts +1 -0
  59. package/src/css/aspects/position/position.ts +1 -0
  60. package/src/css/aspects/shadow/shadow.ts +1 -0
  61. package/src/css/aspects/textOverflow/textOverflow.ts +1 -0
  62. package/src/css/aspects/textOverflow/types.ts +1 -0
  63. package/src/css/aspects/width/types.ts +2 -0
  64. package/src/css/aspects/width/width.ts +1 -0
  65. package/src/css/{compile/compilePalette.ts → compilePalette.ts} +14 -10
  66. package/src/css/compileSystem.ts +7 -0
  67. package/src/css/{compile/compileTheme.ts → compileTheme.ts} +1 -0
  68. package/src/css/{compile/compileTheme_v3.ts → compileTheme_v3.ts} +123 -104
  69. package/src/css/components/breadcrumbs/breadcrumbs.ts +1 -0
  70. package/src/css/components/dialog/dialog.ts +7 -0
  71. package/src/css/components/menu/menu.ts +2 -0
  72. package/src/css/components/skeleton/skeleton.ts +4 -0
  73. package/src/css/components/skeleton/types.ts +4 -0
  74. package/src/css/components/toast/toast.ts +5 -0
  75. package/src/css/components/tree/tree.ts +1 -0
  76. package/src/css/composeClassNames.ts +4 -2
  77. package/src/css/constants.ts +2 -0
  78. package/src/css/index.ts +3 -3
  79. package/src/css/primitives/_arrow/_arrow.ts +3 -0
  80. package/src/css/primitives/_input/input.ts +2 -0
  81. package/src/css/primitives/_selectable/_selectable.style.ts +1 -2
  82. package/src/css/primitives/_selectable/selectable.ts +1 -2
  83. package/src/css/primitives/avatar/avatar.style.ts +5 -8
  84. package/src/css/primitives/avatar/avatar.ts +6 -0
  85. package/src/css/primitives/avatar/types.ts +1 -0
  86. package/src/css/primitives/box/types.ts +1 -3
  87. package/src/css/primitives/button/button.ts +4 -21
  88. package/src/css/primitives/button/index.ts +1 -0
  89. package/src/css/primitives/button/types.ts +18 -0
  90. package/src/css/primitives/card/card.style.ts +3 -6
  91. package/src/css/primitives/card/card.ts +2 -2
  92. package/src/css/primitives/card/types.ts +2 -2
  93. package/src/css/primitives/checkbox/checkbox.ts +2 -0
  94. package/src/css/primitives/container/container.ts +1 -0
  95. package/src/css/primitives/container/types.ts +1 -0
  96. package/src/css/primitives/kbd/kbd.ts +1 -0
  97. package/src/css/primitives/label/types.ts +7 -2
  98. package/src/css/primitives/popover/popover.ts +2 -0
  99. package/src/css/primitives/radio/radio.ts +1 -0
  100. package/src/css/primitives/select/select.ts +2 -0
  101. package/src/css/primitives/spinner/spinner.ts +2 -0
  102. package/src/css/primitives/switch/switch.ts +5 -0
  103. package/src/css/primitives/text/types.ts +4 -0
  104. package/src/css/primitives/textArea/textArea.ts +1 -0
  105. package/src/css/primitives/textInput/textInput.ts +1 -0
  106. package/src/css/primitives/tooltip/tooltip.ts +2 -0
  107. package/src/css/scopeClassName.ts +1 -0
  108. package/src/css/types.ts +9 -12
  109. package/src/css/util.ts +5 -0
  110. package/src/css/utils/srOnly/srOnly.ts +3 -1
  111. package/src/css/varNames.ts +131 -141
  112. package/src/css/vars.ts +1 -6
  113. package/src/theme/palette/constants.ts +2 -0
  114. package/src/theme/palette/types.ts +3 -0
  115. package/src/theme/types.ts +2 -6
  116. package/src/theme/v0/focusRing.ts +1 -3
  117. package/src/theme/v0/font.ts +6 -18
  118. package/src/theme/v0/layer.ts +1 -3
  119. package/src/theme/v0/shadow.ts +2 -6
  120. package/src/theme/v2/avatar.ts +1 -3
  121. package/src/theme/v2/color/_system.ts +1 -3
  122. package/src/theme/v2/color/avatar.ts +2 -6
  123. package/src/theme/v2/color/badge.ts +2 -6
  124. package/src/theme/v2/color/button.ts +3 -9
  125. package/src/theme/v2/color/color.ts +3 -9
  126. package/src/theme/v2/color/input.ts +3 -9
  127. package/src/theme/v2/color/kbd.ts +1 -3
  128. package/src/theme/v2/color/selectable.ts +2 -6
  129. package/src/theme/v2/color/state.ts +1 -3
  130. package/src/theme/v2/color/syntax.ts +1 -3
  131. package/src/theme/v2/input.ts +1 -3
  132. package/src/theme/v2/theme.ts +2 -6
  133. package/src/theme/v3/buildTheme_v3.ts +1 -0
  134. package/src/theme/v3/color/color.ts +6 -4
  135. package/src/theme/v3/color/renderColor.ts +4 -1
  136. package/src/theme/v3/defaultTokens.ts +1 -0
  137. package/src/theme/v3/resolveTokens.ts +9 -9
  138. package/src/ui/RootClassNames.tsx +3 -0
  139. package/src/ui/StyleTags.tsx +3 -1
  140. package/src/ui/_compat/theme/themeColorProvider.tsx +2 -6
  141. package/src/ui/_compat/theme/themeProvider.tsx +2 -6
  142. package/src/ui/_compat/theme/types.ts +1 -3
  143. package/src/ui/_compat/theme/useRootTheme.ts +1 -3
  144. package/src/ui/_compat/theme/useTheme.ts +2 -6
  145. package/src/ui/components/autocomplete/__workshop__/constrainedHeight.tsx +2 -2
  146. package/src/ui/components/autocomplete/autocomplete.tsx +86 -114
  147. package/src/ui/components/autocomplete/autocompleteOption.tsx +2 -0
  148. package/src/ui/components/autocomplete/types.ts +3 -8
  149. package/src/ui/components/breadcrumbs/breadcrumbs.tsx +27 -21
  150. package/src/ui/components/dialog/dialog.tsx +89 -291
  151. package/src/ui/components/dialog/dialogCard.tsx +183 -0
  152. package/src/ui/components/dialog/isTargetWithinScope.ts +14 -0
  153. package/src/ui/components/hotkeys/hotkeys.tsx +33 -15
  154. package/src/ui/components/menu/__workshop__/asComponent.tsx +6 -6
  155. package/src/ui/components/menu/menu.tsx +27 -33
  156. package/src/ui/components/menu/menuButton.tsx +10 -14
  157. package/src/ui/components/menu/menuDivider.tsx +25 -13
  158. package/src/ui/components/menu/menuGroup.tsx +34 -26
  159. package/src/ui/components/menu/menuItem.tsx +51 -40
  160. package/src/ui/components/skeleton/codeSkeleton.tsx +53 -0
  161. package/src/ui/components/skeleton/headingSkeleton.tsx +52 -0
  162. package/src/ui/components/skeleton/index.ts +3 -0
  163. package/src/ui/components/skeleton/labelSkeleton.tsx +51 -0
  164. package/src/ui/components/skeleton/skeleton.tsx +39 -16
  165. package/src/ui/components/skeleton/textSkeleton.tsx +31 -110
  166. package/src/ui/components/tab/tab.tsx +23 -19
  167. package/src/ui/components/tab/tabList.tsx +34 -33
  168. package/src/ui/components/tab/tabPanel.tsx +25 -19
  169. package/src/ui/components/toast/toast.tsx +21 -16
  170. package/src/ui/components/toast/toastLayer.tsx +28 -10
  171. package/src/ui/components/toast/toastProvider.tsx +2 -6
  172. package/src/ui/components/toast/types.ts +2 -6
  173. package/src/ui/components/toast/useToast.ts +1 -3
  174. package/src/ui/components/tree/tree.tsx +194 -187
  175. package/src/ui/components/tree/treeGroup.tsx +25 -5
  176. package/src/ui/components/tree/treeItem.tsx +35 -23
  177. package/src/ui/hooks/useClickOutside.ts +2 -6
  178. package/src/ui/hooks/useClickOutsideEvent.ts +3 -9
  179. package/src/ui/primitives/_selectable/selectable.tsx +33 -20
  180. package/src/ui/primitives/avatar/avatar.tsx +28 -31
  181. package/src/ui/primitives/avatar/avatarCounter.tsx +33 -25
  182. package/src/ui/primitives/avatar/avatarStack.tsx +31 -24
  183. package/src/ui/primitives/avatar/types.ts +2 -0
  184. package/src/ui/primitives/badge/__workshop__/props.tsx +1 -9
  185. package/src/ui/primitives/badge/__workshop__/tones.tsx +1 -6
  186. package/src/ui/primitives/badge/badge.tsx +33 -32
  187. package/src/ui/primitives/badge/types.ts +2 -1
  188. package/src/ui/primitives/box/box.tsx +59 -29
  189. package/src/ui/primitives/button/__workshop__/sanityUploadButton.tsx +3 -3
  190. package/src/ui/primitives/button/__workshop__/uploadButton.tsx +2 -1
  191. package/src/ui/primitives/button/button.test.tsx +1 -15
  192. package/src/ui/primitives/button/button.tsx +64 -70
  193. package/src/ui/primitives/card/__workshop__/asComponent.tsx +3 -3
  194. package/src/ui/primitives/card/card.tsx +22 -22
  195. package/src/ui/primitives/card/cardProvider.tsx +2 -0
  196. package/src/ui/primitives/checkbox/checkbox.tsx +26 -15
  197. package/src/ui/primitives/code/code.tsx +24 -22
  198. package/src/ui/primitives/container/container.tsx +26 -15
  199. package/src/ui/primitives/flex/flex.tsx +21 -19
  200. package/src/ui/primitives/grid/grid.tsx +21 -16
  201. package/src/ui/primitives/heading/heading.tsx +42 -19
  202. package/src/ui/primitives/inline/inline.tsx +26 -23
  203. package/src/ui/primitives/kbd/kbd.tsx +25 -23
  204. package/src/ui/primitives/label/label.tsx +41 -26
  205. package/src/ui/primitives/popover/popover.tsx +281 -277
  206. package/src/ui/primitives/popover/popoverCard.tsx +119 -118
  207. package/src/ui/primitives/radio/radio.tsx +30 -14
  208. package/src/ui/primitives/select/select.tsx +24 -16
  209. package/src/ui/primitives/spinner/animatedSpinnerIcon.tsx +4 -2
  210. package/src/ui/primitives/spinner/spinner.tsx +24 -12
  211. package/src/ui/primitives/stack/stack.tsx +27 -18
  212. package/src/ui/primitives/switch/switch.tsx +31 -14
  213. package/src/ui/primitives/text/text.tsx +42 -24
  214. package/src/ui/primitives/textArea/textArea.tsx +33 -18
  215. package/src/ui/primitives/textInput/textInput.tsx +28 -40
  216. package/src/ui/primitives/tooltip/constants.ts +1 -1
  217. package/src/ui/primitives/tooltip/tooltip.tsx +76 -59
  218. package/src/ui/primitives/tooltip/tooltipCard.tsx +89 -82
  219. package/src/ui/primitives/types.ts +1 -3
  220. package/src/ui/types/avatar.ts +3 -6
  221. package/src/ui/types/badge.ts +1 -3
  222. package/src/ui/types/button.ts +1 -3
  223. package/src/ui/types/card.ts +1 -3
  224. package/src/ui/types/dialog.ts +1 -3
  225. package/src/ui/types/props.ts +20 -10
  226. package/src/ui/utils/arrow/arrow.tsx +40 -14
  227. package/src/ui/utils/boundaryElement/boundaryElementProvider.tsx +2 -6
  228. package/src/ui/utils/boundaryElement/types.ts +1 -3
  229. package/src/ui/utils/boundaryElement/useBoundaryElement.ts +1 -3
  230. package/src/ui/utils/elementQuery/elementQuery.tsx +36 -14
  231. package/src/ui/utils/errorBoundary.tsx +2 -0
  232. package/src/ui/utils/index.ts +0 -1
  233. package/src/ui/utils/layer/layer.tsx +23 -93
  234. package/src/ui/utils/layer/layerCard.tsx +92 -0
  235. package/src/ui/utils/layer/layerProvider.tsx +2 -6
  236. package/src/ui/utils/layer/useLayer.ts +1 -3
  237. package/src/ui/utils/portal/portal.ts +2 -6
  238. package/src/ui/utils/portal/portalProvider.tsx +2 -6
  239. package/src/ui/utils/portal/types.ts +1 -3
  240. package/src/ui/utils/portal/usePortal.ts +1 -3
  241. package/src/ui/utils/srOnly/srOnly.tsx +25 -20
  242. package/src/ui/utils/virtualList/virtualList.tsx +36 -24
  243. package/src/css/compile/compileRule.ts +0 -97
  244. package/src/css/compile/compileRules.test.ts +0 -36
  245. package/src/css/compile/compileRules.ts +0 -43
  246. package/src/css/compile/compileSystem.ts +0 -7
  247. package/src/css/compile/types.ts +0 -6
  248. package/src/css/primitives/_selectable/_contants.ts +0 -11
  249. package/src/css/primitives/card/_constants.ts +0 -13
  250. package/src/ui/utils/conditionalWrapper/conditionalWrapper.tsx +0 -23
  251. package/src/ui/utils/conditionalWrapper/index.ts +0 -1
@@ -1,23 +1,50 @@
1
- import {
2
- box,
1
+ import type {
3
2
  BoxStyleProps,
4
- composeClassNames,
5
3
  GapStyleProps,
6
4
  InsetStyleProps,
7
5
  PositionStyleProps,
8
6
  } from '@sanity/ui/css'
9
- import {ForwardedRef, forwardRef} from 'react'
7
+ import {box, composeClassNames} from '@sanity/ui/css'
10
8
 
11
- import {Props} from '../../types'
9
+ import type {ComponentType, Props} from '../../types'
12
10
 
13
- /**
14
- * @public
15
- */
16
- export interface BoxProps
17
- extends BoxStyleProps,
18
- GapStyleProps,
19
- InsetStyleProps,
20
- PositionStyleProps {}
11
+ /** @public */
12
+ export const DEFAULT_BOX_ELEMENT = 'div'
13
+
14
+ /** @public */
15
+ export type BoxOwnProps = BoxStyleProps & GapStyleProps & InsetStyleProps & PositionStyleProps
16
+
17
+ /** @public */
18
+ export type BoxElementType =
19
+ | 'a'
20
+ | 'article'
21
+ | 'aside'
22
+ | 'blockquote'
23
+ | 'button'
24
+ | 'details'
25
+ | 'div'
26
+ | 'header'
27
+ | 'fieldset'
28
+ | 'figure'
29
+ | 'figcaption'
30
+ | 'footer'
31
+ | 'form'
32
+ | 'kbd'
33
+ | 'label'
34
+ | 'legend'
35
+ | 'li'
36
+ | 'main'
37
+ | 'nav'
38
+ | 'ol'
39
+ | 'pre'
40
+ | 'section'
41
+ | 'span'
42
+ | 'summary'
43
+ | 'ul'
44
+ | ComponentType
45
+
46
+ /** @public */
47
+ export type BoxProps<E extends BoxElementType = BoxElementType> = Props<BoxOwnProps, E>
21
48
 
22
49
  /**
23
50
  * The `Box` component is a basic layout wrapper component which provides utility properties
@@ -25,13 +52,10 @@ export interface BoxProps
25
52
  *
26
53
  * @public
27
54
  */
28
- export const Box = forwardRef(function Box(
29
- props: Props<BoxProps, 'div'>,
30
- ref: ForwardedRef<HTMLDivElement>,
31
- ) {
55
+ export function Box<E extends BoxElementType = typeof DEFAULT_BOX_ELEMENT>(props: BoxProps<E>) {
32
56
  const {
33
57
  align,
34
- as: As = 'div',
58
+ as: Element = DEFAULT_BOX_ELEMENT,
35
59
  autoCols,
36
60
  autoFlow,
37
61
  autoRows,
@@ -41,6 +65,7 @@ export const Box = forwardRef(function Box(
41
65
  borderBottom,
42
66
  borderLeft,
43
67
  className,
68
+ children,
44
69
  column,
45
70
  columnStart,
46
71
  columnEnd,
@@ -67,7 +92,11 @@ export const Box = forwardRef(function Box(
67
92
  marginLeft,
68
93
  maxWidth,
69
94
  minWidth = 0,
95
+ muted,
96
+ outline,
70
97
  overflow,
98
+ overflowX,
99
+ overflowY,
71
100
  padding = 0,
72
101
  paddingX,
73
102
  paddingY,
@@ -77,7 +106,6 @@ export const Box = forwardRef(function Box(
77
106
  paddingLeft,
78
107
  pointerEvents,
79
108
  position,
80
- muted,
81
109
  radius,
82
110
  row,
83
111
  rows,
@@ -86,13 +114,13 @@ export const Box = forwardRef(function Box(
86
114
  sizing = 'border',
87
115
  width,
88
116
  wrap,
89
- ...restProps
90
- } = props
117
+ ...rest
118
+ } = props as BoxProps<typeof DEFAULT_BOX_ELEMENT>
91
119
 
92
120
  return (
93
- <As
121
+ <Element
94
122
  data-ui="Box"
95
- {...restProps}
123
+ {...rest}
96
124
  className={composeClassNames(
97
125
  className,
98
126
  box({
@@ -122,7 +150,6 @@ export const Box = forwardRef(function Box(
122
150
  insetRight,
123
151
  insetTop,
124
152
  justify,
125
- overflow,
126
153
  margin,
127
154
  marginX,
128
155
  marginY,
@@ -133,6 +160,10 @@ export const Box = forwardRef(function Box(
133
160
  maxWidth,
134
161
  minWidth,
135
162
  muted,
163
+ outline,
164
+ overflow,
165
+ overflowX,
166
+ overflowY,
136
167
  padding,
137
168
  paddingX,
138
169
  paddingY,
@@ -152,11 +183,10 @@ export const Box = forwardRef(function Box(
152
183
  wrap,
153
184
  }),
154
185
  )}
155
- ref={ref}
156
186
  >
157
- {props.children}
158
- </As>
187
+ {children}
188
+ </Element>
159
189
  )
160
- })
190
+ }
161
191
 
162
- Box.displayName = 'ForwardRef(Box)'
192
+ Box.displayName = 'Box'
@@ -18,7 +18,7 @@ const SanityUploadButton = styled(Button).attrs({forwardedAs: 'label'})`
18
18
  width: stretch;
19
19
  }
20
20
 
21
- & span:nth-child(2) {
21
+ & > span:nth-child(2) {
22
22
  width: 0;
23
23
  flex: none;
24
24
  padding: 0;
@@ -27,8 +27,8 @@ const SanityUploadButton = styled(Button).attrs({forwardedAs: 'label'})`
27
27
 
28
28
  export default function SanityUploadButtonWorkaroundStory() {
29
29
  return (
30
- <Flex align="center" height="fill" htmlFor="file" justify="center">
31
- <SanityUploadButton icon={UploadIcon} tabIndex={0} text="Upload">
30
+ <Flex align="center" height="fill" justify="center">
31
+ <SanityUploadButton htmlFor="file" icon={UploadIcon} tabIndex={0} text="Upload">
32
32
  <input type="file" />
33
33
  </SanityUploadButton>
34
34
  </Flex>
@@ -11,9 +11,10 @@ export default function UploadButtonStory() {
11
11
  }, [])
12
12
 
13
13
  return (
14
- <Flex align="center" height="fill" htmlFor="file" justify="center">
14
+ <Flex align="center" height="fill" justify="center">
15
15
  <Button
16
16
  as="label"
17
+ htmlFor="file"
17
18
  onKeyDown={handleKeyDown}
18
19
  tabIndex={0}
19
20
  text={
@@ -5,7 +5,7 @@ import {screen} from '@testing-library/react'
5
5
  import {axe} from 'jest-axe'
6
6
 
7
7
  import {render} from '../../../../test'
8
- import {Button, ButtonProps} from './button'
8
+ import {Button} from './button'
9
9
 
10
10
  describe('atoms/button', () => {
11
11
  it('Axe: should have no violations', async () => {
@@ -27,18 +27,4 @@ describe('atoms/button', () => {
27
27
 
28
28
  expect(screen.getByText('Button text')).toBeInTheDocument()
29
29
  })
30
-
31
- it('should wrap button', () => {
32
- function WrappedButton({button: buttonProps}: {button: ButtonProps}) {
33
- return <Button {...buttonProps} />
34
- }
35
-
36
- const buttonProps: ButtonProps = {
37
- text: 'Button text',
38
- }
39
-
40
- render(<WrappedButton button={buttonProps} />)
41
-
42
- expect(screen.getByText('Button text')).toBeInTheDocument()
43
- })
44
30
  })
@@ -1,8 +1,5 @@
1
- import {
2
- button,
3
- buttonLoadingBox,
1
+ import type {
4
2
  ButtonStyleProps,
5
- composeClassNames,
6
3
  DisplayStyleProps,
7
4
  FlexStyleProps,
8
5
  GapStyleProps,
@@ -10,59 +7,63 @@ import {
10
7
  ResponsiveProp,
11
8
  Width,
12
9
  } from '@sanity/ui/css'
13
- import {FontTextSize, Space} from '@sanity/ui/theme'
14
- import {ElementType, ForwardedRef, forwardRef, isValidElement, ReactNode} from 'react'
10
+ import {button, buttonLoadingBox, composeClassNames} from '@sanity/ui/css'
11
+ import type {FontTextSize, Space} from '@sanity/ui/theme'
12
+ import {type ElementType as ReactElementType, isValidElement, type ReactNode} from 'react'
15
13
  import {isValidElementType} from 'react-is'
16
14
 
17
- import {ButtonMode, ButtonTextAlign, ButtonTone, Props} from '../../types'
15
+ import type {ButtonMode, ButtonTextAlign, ButtonTone, ComponentType, Props} from '../../types'
18
16
  import {Box} from '../box'
19
17
  import {Spinner} from '../spinner'
20
- import {Text, TextProps} from '../text'
18
+ import type {TextOwnProps} from '../text'
19
+ import {Text} from '../text'
21
20
 
22
- /**
23
- * @public
24
- */
25
- export interface ButtonProps
26
- extends ButtonStyleProps,
27
- DisplayStyleProps,
28
- FlexStyleProps,
29
- GapStyleProps,
30
- PaddingStyleProps {
31
- 'data-ui'?: string
32
- 'fontSize'?: ResponsiveProp<FontTextSize>
33
- 'href'?: string
34
- 'mode'?: ButtonMode
35
- 'icon'?: ElementType | ReactNode
36
- 'iconRight'?: ElementType | ReactNode
37
- /** @beta Do not use in production, as this might change.*/
38
- 'loading'?: boolean
39
- 'selected'?: boolean
40
- /** @deprecated Use `gap` instead. */
41
- 'space'?: ResponsiveProp<Space>
42
- 'textAlign'?: ButtonTextAlign
43
- 'muted'?: boolean
44
- 'target'?: string
45
- 'text'?: ReactNode
46
- 'textOverflow'?: TextProps['textOverflow']
47
- 'textWeight'?: TextProps['weight']
48
- 'tone'?: ButtonTone
49
- 'type'?: 'button' | 'reset' | 'submit'
50
- 'width'?: ResponsiveProp<Width>
51
- }
21
+ /** @public */
22
+ export const DEFAULT_BUTTON_ELEMENT = 'button'
23
+
24
+ /** @public */
25
+ export type ButtonOwnProps = ButtonStyleProps &
26
+ DisplayStyleProps &
27
+ GapStyleProps &
28
+ PaddingStyleProps & {
29
+ 'align'?: FlexStyleProps['align']
30
+ 'data-ui'?: string
31
+ 'disabled'?: boolean
32
+ 'fontSize'?: ResponsiveProp<FontTextSize>
33
+ 'mode'?: ButtonMode
34
+ 'icon'?: ReactElementType | ReactNode
35
+ 'iconRight'?: ReactElementType | ReactNode
36
+ 'justify'?: FlexStyleProps['justify']
37
+ /** @beta Do not use in production, as this might change.*/
38
+ 'loading'?: boolean
39
+ 'selected'?: boolean
40
+ /** @deprecated Use `gap` instead. */
41
+ 'space'?: ResponsiveProp<Space>
42
+ 'textAlign'?: ButtonTextAlign
43
+ 'muted'?: boolean
44
+ 'target'?: string
45
+ 'text'?: ReactNode
46
+ 'textOverflow'?: TextOwnProps['textOverflow']
47
+ 'textWeight'?: TextOwnProps['weight']
48
+ 'tone'?: ButtonTone
49
+ 'width'?: ResponsiveProp<Width>
50
+ }
51
+
52
+ /** @public */
53
+ export type ButtonElementType = 'a' | 'button' | 'label' | ComponentType
54
+
55
+ /** @public */
56
+ export type ButtonProps<E extends ButtonElementType = ButtonElementType> = Props<ButtonOwnProps, E>
52
57
 
53
- /**
54
- * @public
55
- */
56
- export const Button = forwardRef(function Button(
57
- props: Props<ButtonProps, 'button'>,
58
- ref: ForwardedRef<HTMLButtonElement>,
58
+ /** @public */
59
+ export function Button<E extends ButtonElementType = typeof DEFAULT_BUTTON_ELEMENT>(
60
+ props: ButtonProps<E>,
59
61
  ) {
60
62
  const {
61
- // align = 'center',
62
- as: As = 'button',
63
+ align = 'center',
64
+ as: Element = DEFAULT_BUTTON_ELEMENT,
63
65
  children,
64
66
  className,
65
- direction,
66
67
  disabled,
67
68
  display = 'inline-flex',
68
69
  flex,
@@ -70,7 +71,6 @@ export const Button = forwardRef(function Button(
70
71
  gap = props.space ?? props.padding ?? 3,
71
72
  gapX,
72
73
  gapY,
73
- href,
74
74
  icon: IconComponent,
75
75
  iconRight: IconRightComponent,
76
76
  justify = 'center',
@@ -94,20 +94,26 @@ export const Button = forwardRef(function Button(
94
94
  type = 'button',
95
95
  muted = false,
96
96
  width,
97
- // wrap,
98
- ...restProps
99
- } = props
97
+ ...rest
98
+ } = props as ButtonProps<typeof DEFAULT_BUTTON_ELEMENT>
99
+
100
+ let href: string | undefined = undefined
101
+
102
+ if ('href' in rest) {
103
+ href = typeof rest.href === 'string' ? rest.href : href
104
+ delete rest.href
105
+ }
100
106
 
101
107
  return (
102
- <As
108
+ <Element
103
109
  data-ui="Button"
104
- {...restProps}
110
+ {...rest}
105
111
  className={composeClassNames(className, button({display, flex, mode, radius, tone, width}))}
106
112
  data-disabled={loading || disabled ? '' : undefined}
107
113
  data-selected={selected ? '' : undefined}
108
114
  disabled={Boolean(loading || disabled)}
115
+ // @ts-expect-error - TODO: fix this
109
116
  href={disabled ? undefined : href}
110
- ref={ref}
111
117
  type={type}
112
118
  >
113
119
  {Boolean(loading) && (
@@ -126,9 +132,8 @@ export const Button = forwardRef(function Button(
126
132
 
127
133
  {(IconComponent || text || IconRightComponent) && (
128
134
  <Box
129
- // align={align}
135
+ align={align}
130
136
  as="span"
131
- direction={direction}
132
137
  display="flex"
133
138
  flex={1}
134
139
  gap={gap}
@@ -142,8 +147,6 @@ export const Button = forwardRef(function Button(
142
147
  paddingBottom={paddingBottom}
143
148
  paddingLeft={paddingLeft}
144
149
  paddingRight={paddingRight}
145
- // width="fill"
146
- // wrap={wrap}
147
150
  >
148
151
  {IconComponent && (
149
152
  <Text as="span" flex="none" muted size={fontSize}>
@@ -177,15 +180,8 @@ export const Button = forwardRef(function Button(
177
180
 
178
181
  {children && (
179
182
  <Box
180
- // align={align}
181
183
  as="span"
182
- // direction={direction}
183
- // display="flex"
184
184
  flex={1}
185
- // gap={gap}
186
- // gapX={gapX}
187
- // gapY={gapY}
188
- // justify={justify}
189
185
  padding={padding}
190
186
  paddingX={paddingX}
191
187
  paddingY={paddingY}
@@ -193,14 +189,12 @@ export const Button = forwardRef(function Button(
193
189
  paddingBottom={paddingBottom}
194
190
  paddingLeft={paddingLeft}
195
191
  paddingRight={paddingRight}
196
- // width="fill"
197
- // wrap={wrap}
198
192
  >
199
193
  {children}
200
194
  </Box>
201
195
  )}
202
- </As>
196
+ </Element>
203
197
  )
204
- })
198
+ }
205
199
 
206
- Button.displayName = 'ForwardRef(Button)'
200
+ Button.displayName = 'Button'
@@ -5,10 +5,10 @@ const CustomLink = forwardRef(function CustomLink(
5
5
  props: {req: string} & Omit<React.HTMLProps<HTMLAnchorElement>, 'as' | 'href'>,
6
6
  ref: React.ForwardedRef<HTMLAnchorElement>,
7
7
  ): React.JSX.Element {
8
- const {children, req, ...restProps} = props
8
+ const {children, req, ...rest} = props
9
9
 
10
10
  return (
11
- <a data-required={req} {...restProps} ref={ref}>
11
+ <a data-required={req} {...rest} ref={ref}>
12
12
  {children}
13
13
  </a>
14
14
  )
@@ -19,7 +19,7 @@ export default function AsComponentStory() {
19
19
 
20
20
  return (
21
21
  <Flex align="center" height="fill" justify="center">
22
- <Card as={CustomLink} data-as="a" {...props} padding={3}>
22
+ <Card as={CustomLink} data-as="a" {...props} padding={3} req="1">
23
23
  <Text size={1}>As component</Text>
24
24
  </Card>
25
25
  </Flex>
@@ -1,16 +1,16 @@
1
1
  import {card, CardStyleProps, composeClassNames} from '@sanity/ui/css'
2
- import {createElement, ForwardedRef, forwardRef} from 'react'
3
- import {isValidElementType} from 'react-is'
2
+ import {createElement} from 'react'
4
3
 
5
4
  import {Props} from '../../types'
6
- import {Box, BoxProps} from '../box'
5
+ import {Box, BoxElementType, BoxOwnProps} from '../box'
7
6
  import {CardProvider} from './cardProvider'
8
7
  import {useCard} from './useCard'
9
8
 
10
- /**
11
- * @public
12
- */
13
- export interface CardProps extends BoxProps, CardStyleProps {
9
+ /** @public */
10
+ export const DEFAULT_CARD_ELEMENT = 'div'
11
+
12
+ /** @public */
13
+ export interface CardOwnProps extends BoxOwnProps, CardStyleProps {
14
14
  /**
15
15
  * Do not use in production.
16
16
  * @beta
@@ -22,39 +22,39 @@ export interface CardProps extends BoxProps, CardStyleProps {
22
22
  */
23
23
  __unstable_focusRing?: boolean
24
24
  disabled?: boolean
25
- href?: string
26
25
  pressed?: boolean
27
26
  selected?: boolean
28
27
  target?: string
29
28
  }
30
29
 
30
+ /** @public */
31
+ export type CardElementType = BoxElementType
32
+
33
+ /** @public */
34
+ export type CardProps<E extends CardElementType = CardElementType> = Props<CardOwnProps, E>
35
+
31
36
  /**
32
37
  * The `Card` component acts much like a `Box`, but with a background and foreground color.
33
38
  * Components within a `Card` inherit its colors.
34
39
  *
35
40
  * @public
36
41
  */
37
- export const Card = forwardRef(function Card(
38
- props: Props<CardProps, 'div'>,
39
- ref: ForwardedRef<HTMLDivElement>,
40
- ) {
42
+ export function Card<E extends CardElementType = typeof DEFAULT_CARD_ELEMENT>(props: CardProps<E>) {
41
43
  const {
42
44
  __unstable_checkered: checkered = false,
43
45
  __unstable_focusRing: focusRing = false,
44
- as: asProp,
46
+ as = DEFAULT_CARD_ELEMENT,
45
47
  className,
48
+ disabled,
46
49
  pressed,
47
50
  radius = 0,
48
51
  scheme: schemeProp,
49
- // selectable,
50
52
  selected,
51
53
  shadow,
52
54
  style,
53
55
  tone: toneProp = 'default',
54
- ...restProps
55
- } = props
56
-
57
- const as = isValidElementType(asProp) ? asProp : 'div'
56
+ ...rest
57
+ } = props as CardProps<typeof DEFAULT_CARD_ELEMENT>
58
58
 
59
59
  const parent = useCard()
60
60
 
@@ -69,7 +69,7 @@ export const Card = forwardRef(function Card(
69
69
  let node = (
70
70
  <Box
71
71
  data-ui="Card"
72
- {...restProps}
72
+ {...rest}
73
73
  as={as}
74
74
  className={composeClassNames(
75
75
  className,
@@ -80,11 +80,11 @@ export const Card = forwardRef(function Card(
80
80
  }),
81
81
  )}
82
82
  data-checkered={checkered ? '' : undefined}
83
+ data-disabled={disabled ? '' : undefined}
83
84
  data-focus-ring={focusRing ? '' : undefined}
84
85
  data-pressed={pressed ? '' : undefined}
85
86
  data-selected={selected ? '' : undefined}
86
87
  radius={radius}
87
- ref={ref}
88
88
  style={style}
89
89
  />
90
90
  )
@@ -113,6 +113,6 @@ export const Card = forwardRef(function Card(
113
113
  }
114
114
 
115
115
  return node
116
- })
116
+ }
117
117
 
118
- Card.displayName = 'ForwardRef(Card)'
118
+ Card.displayName = 'Card'
@@ -17,3 +17,5 @@ export function CardProvider(props: {
17
17
 
18
18
  return <CardContext.Provider value={context}>{children}</CardContext.Provider>
19
19
  }
20
+
21
+ CardProvider.displayName = 'CardProvider'
@@ -1,37 +1,48 @@
1
1
  import {CheckmarkIcon, RemoveIcon} from '@sanity/icons'
2
2
  import {checkbox, checkboxInput, composeClassNames} from '@sanity/ui/css'
3
- import {ForwardedRef, forwardRef, useEffect, useImperativeHandle, useRef} from 'react'
3
+ import {useEffect, useImperativeHandle, useRef} from 'react'
4
4
 
5
5
  import {useCustomValidity} from '../../hooks'
6
- import {Props} from '../../types'
6
+ import {ComponentType, Props} from '../../types'
7
7
 
8
- /**
9
- * @public
10
- */
11
- export interface CheckboxProps {
8
+ /** @public */
9
+ export const DEFAULT_CHECKBOX_ELEMENT = 'input'
10
+
11
+ /** @public */
12
+ export type CheckboxOwnProps = {
12
13
  indeterminate?: boolean
13
14
  customValidity?: string
14
15
  }
15
16
 
17
+ /** @public */
18
+ export type CheckboxElementType = 'input' | ComponentType
19
+
20
+ /** @public */
21
+ export type CheckboxProps<E extends CheckboxElementType = CheckboxElementType> = Props<
22
+ CheckboxOwnProps,
23
+ E
24
+ >
25
+
16
26
  /**
17
27
  * Checkboxes allow the user to select one or more items from a set.
18
28
  *
19
29
  * @public
20
30
  */
21
- export const Checkbox = forwardRef(function Checkbox(
22
- props: Props<CheckboxProps, 'input'>,
23
- forwardedRef: ForwardedRef<HTMLInputElement>,
31
+ export function Checkbox<E extends CheckboxElementType = typeof DEFAULT_CHECKBOX_ELEMENT>(
32
+ props: CheckboxProps<E>,
24
33
  ) {
25
34
  const {
35
+ as: Element = DEFAULT_CHECKBOX_ELEMENT,
26
36
  checked,
27
37
  className,
28
38
  disabled,
29
39
  indeterminate,
30
40
  customValidity,
31
41
  readOnly,
42
+ ref: forwardedRef,
32
43
  style,
33
- ...restProps
34
- } = props
44
+ ...rest
45
+ } = props as CheckboxProps<typeof DEFAULT_CHECKBOX_ELEMENT>
35
46
 
36
47
  const ref = useRef<HTMLInputElement | null>(null)
37
48
 
@@ -51,8 +62,8 @@ export const Checkbox = forwardRef(function Checkbox(
51
62
 
52
63
  return (
53
64
  <span className={composeClassNames(className, checkbox())} data-ui="Checkbox" style={style}>
54
- <input
55
- {...restProps}
65
+ <Element
66
+ {...rest}
56
67
  checked={checked}
57
68
  className={composeClassNames(className, checkboxInput())}
58
69
  data-disabled={disabled ? '' : undefined}
@@ -69,6 +80,6 @@ export const Checkbox = forwardRef(function Checkbox(
69
80
  </span>
70
81
  </span>
71
82
  )
72
- })
83
+ }
73
84
 
74
- Checkbox.displayName = 'ForwardRef(Checkbox)'
85
+ Checkbox.displayName = 'Checkbox'