@sanity/ui 2.3.6 → 2.3.7-canary.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 (53) hide show
  1. package/dist/index.compiled.mjs +7488 -0
  2. package/dist/index.compiled.mjs.map +1 -0
  3. package/dist/index.d.mts +13 -1
  4. package/dist/index.d.ts +13 -1
  5. package/dist/index.esm.js +1047 -1072
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +1054 -1079
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +1047 -1072
  10. package/dist/index.mjs.map +1 -1
  11. package/package.json +31 -35
  12. package/src/core/components/autocomplete/autocomplete.tsx +31 -34
  13. package/src/core/components/breadcrumbs/breadcrumbs.tsx +3 -2
  14. package/src/core/components/dialog/dialog.tsx +23 -12
  15. package/src/core/components/hotkeys/hotkeys.tsx +3 -3
  16. package/src/core/components/menu/menu.tsx +5 -1
  17. package/src/core/components/menu/menuButton.tsx +17 -32
  18. package/src/core/components/menu/menuGroup.tsx +7 -5
  19. package/src/core/components/menu/menuItem.tsx +10 -6
  20. package/src/core/components/skeleton/skeleton.tsx +5 -11
  21. package/src/core/components/skeleton/textSkeleton.tsx +6 -7
  22. package/src/core/components/toast/toastProvider.tsx +26 -24
  23. package/src/core/components/tree/treeItem.styles.ts +21 -0
  24. package/src/core/components/tree/treeItem.tsx +31 -44
  25. package/src/core/hooks/useArrayProp.ts +11 -10
  26. package/src/core/primitives/avatar/avatar.tsx +11 -15
  27. package/src/core/primitives/avatar/avatarCounter.tsx +11 -17
  28. package/src/core/primitives/avatar/avatarStack.tsx +3 -7
  29. package/src/core/primitives/badge/badge.tsx +7 -4
  30. package/src/core/primitives/box/box.tsx +53 -27
  31. package/src/core/primitives/button/button.tsx +11 -12
  32. package/src/core/primitives/card/card.tsx +17 -9
  33. package/src/core/primitives/code/code.tsx +4 -3
  34. package/src/core/primitives/container/container.tsx +4 -11
  35. package/src/core/primitives/flex/flex.tsx +13 -7
  36. package/src/core/primitives/grid/grid.tsx +19 -10
  37. package/src/core/primitives/heading/heading.tsx +7 -4
  38. package/src/core/primitives/inline/inline.tsx +3 -2
  39. package/src/core/primitives/kbd/kbd.tsx +4 -3
  40. package/src/core/primitives/label/label.tsx +7 -4
  41. package/src/core/primitives/popover/popover.tsx +49 -49
  42. package/src/core/primitives/select/select.tsx +12 -6
  43. package/src/core/primitives/stack/stack.tsx +4 -3
  44. package/src/core/primitives/text/text.tsx +7 -4
  45. package/src/core/primitives/textArea/textArea.tsx +12 -6
  46. package/src/core/primitives/textInput/textInput.tsx +6 -5
  47. package/src/core/primitives/tooltip/tooltip.tsx +14 -7
  48. package/src/core/theme/themeProvider.tsx +4 -6
  49. package/src/core/utils/elementQuery/elementQuery.tsx +4 -3
  50. package/src/core/utils/layer/getLayerContext.test.ts +0 -4
  51. package/src/core/utils/layer/layer.test.tsx +0 -2
  52. package/src/core/utils/layer/layerProvider.tsx +35 -43
  53. package/src/core/utils/layer/types.ts +0 -1
@@ -45,8 +45,6 @@ const ToastContainer = styled.div`
45
45
  width: 100%;
46
46
  `
47
47
 
48
- let toastId = 0
49
-
50
48
  /**
51
49
  * @public
52
50
  */
@@ -57,27 +55,7 @@ export function ToastProvider(props: ToastProviderProps): React.ReactElement {
57
55
  const mounted = useMounted()
58
56
  const prefersReducedMotion = usePrefersReducedMotion()
59
57
  const variants = useMemo<Variants>(
60
- () => ({
61
- initial: {
62
- opacity: 0,
63
- [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: 0,
64
- y: 32,
65
- scale: 0.25,
66
- willChange: 'transform',
67
- },
68
- animate: {
69
- opacity: [0, 1, 1],
70
- [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: [0, 0, 1],
71
- y: 0,
72
- scale: 1,
73
- },
74
- exit: {
75
- opacity: [1, 1, 0],
76
- [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: [1, 0, 0],
77
- scale: 0.5,
78
- transition: prefersReducedMotion ? {duration: 0} : {duration: 0.2},
79
- },
80
- }),
58
+ () => getVariants(prefersReducedMotion),
81
59
  [prefersReducedMotion],
82
60
  )
83
61
 
@@ -86,7 +64,7 @@ export function ToastProvider(props: ToastProviderProps): React.ReactElement {
86
64
  // Wrap setState in startTransition to allow React to give input state updates higher priority
87
65
  const setState: typeof _setState = (state) => startTransition(() => _setState(state))
88
66
 
89
- const id = params.id || String(toastId++)
67
+ const id = params.id || crypto.randomUUID()
90
68
  const duration = params.duration || 5000
91
69
 
92
70
  const dismiss = () => {
@@ -188,3 +166,27 @@ export function ToastProvider(props: ToastProviderProps): React.ReactElement {
188
166
  </ToastContext.Provider>
189
167
  )
190
168
  }
169
+
170
+ function getVariants(prefersReducedMotion: boolean) {
171
+ return {
172
+ initial: {
173
+ opacity: 0,
174
+ [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: 0,
175
+ y: 32,
176
+ scale: 0.25,
177
+ willChange: 'transform',
178
+ },
179
+ animate: {
180
+ opacity: [0, 1, 1],
181
+ [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: [0, 0, 1],
182
+ y: 0,
183
+ scale: 1,
184
+ },
185
+ exit: {
186
+ opacity: [1, 1, 0],
187
+ [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: [1, 0, 0],
188
+ scale: 0.5,
189
+ transition: {duration: prefersReducedMotion ? 0 : 0.2},
190
+ },
191
+ }
192
+ }
@@ -0,0 +1,21 @@
1
+ import {memo} from 'react'
2
+ import {styled} from 'styled-components'
3
+ import {Box, Text} from '../../primitives'
4
+ import {
5
+ treeItemRootStyle,
6
+ treeItemRootColorStyle,
7
+ treeItemBoxStyle,
8
+ TreeItemBoxStyleProps,
9
+ } from './style'
10
+
11
+ export const Root = memo(styled.li(treeItemRootStyle, treeItemRootColorStyle))
12
+
13
+ export const TreeItemBox = styled(Box).attrs({forwardedAs: 'a'})<TreeItemBoxStyleProps>(
14
+ treeItemBoxStyle,
15
+ )
16
+
17
+ export const ToggleArrowText = styled(Text)`
18
+ & > svg {
19
+ transition: transform 100ms;
20
+ }
21
+ `
@@ -1,16 +1,10 @@
1
1
  import {ToggleArrowRightIcon} from '@sanity/icons'
2
2
  import {ThemeFontWeightKey} from '@sanity/ui/theme'
3
3
  import {memo, useCallback, useEffect, useId, useMemo, useRef} from 'react'
4
- import {styled} from 'styled-components'
5
4
  import {Box, BoxProps, Flex, Text} from '../../primitives'
6
- import {
7
- treeItemRootStyle,
8
- treeItemRootColorStyle,
9
- treeItemBoxStyle,
10
- TreeItemBoxStyleProps,
11
- } from './style'
12
5
  import {TreeContext} from './treeContext'
13
6
  import {TreeGroup} from './treeGroup'
7
+ import {Root, ToggleArrowText, TreeItemBox} from './treeItem.styles'
14
8
  import {useTree} from './useTree'
15
9
 
16
10
  /**
@@ -30,16 +24,6 @@ export interface TreeItemProps {
30
24
  weight?: ThemeFontWeightKey
31
25
  }
32
26
 
33
- const Root = memo(styled.li(treeItemRootStyle, treeItemRootColorStyle))
34
-
35
- const TreeItemBox = styled(Box).attrs({forwardedAs: 'a'})<TreeItemBoxStyleProps>(treeItemBoxStyle)
36
-
37
- const ToggleArrowText = styled(Text)`
38
- & > svg {
39
- transition: transform 100ms;
40
- }
41
- `
42
-
43
27
  /**
44
28
  * This API might change. DO NOT USE IN PRODUCTION.
45
29
  * @beta
@@ -70,7 +54,7 @@ export const TreeItem = memo(function TreeItem(
70
54
  const {path, registerItem, setExpanded, setFocusedElement} = tree
71
55
  const _id = useId()
72
56
  const id = idProp || _id
73
- const itemPath = useMemo(() => path.concat([id || '']), [id, path])
57
+ const itemPath = useMemo(() => [...path, id || ''], [id, path])
74
58
  const itemKey = itemPath.join('/')
75
59
  const itemState = tree.state[itemKey]
76
60
  const focused = tree.focusedElement === rootRef.current
@@ -83,7 +67,7 @@ export const TreeItem = memo(function TreeItem(
83
67
 
84
68
  const handleClick = useCallback(
85
69
  (event: React.MouseEvent<HTMLLIElement>) => {
86
- if (onClick) onClick(event)
70
+ onClick?.(event)
87
71
 
88
72
  const target = event.target
89
73
 
@@ -117,32 +101,35 @@ export const TreeItem = memo(function TreeItem(
117
101
  return registerItem(rootRef.current, itemPath.join('/'), expanded, selected)
118
102
  }, [expanded, itemPath, registerItem, selected])
119
103
 
120
- const content = (
121
- <Flex padding={padding}>
122
- <Box
123
- marginRight={space}
124
- style={{
125
- visibility: IconComponent || children ? 'visible' : 'hidden',
126
- pointerEvents: 'none',
127
- }}
128
- >
129
- {IconComponent && (
130
- <Text muted={muted} size={fontSize} weight={weight}>
131
- <IconComponent />
104
+ const content = useMemo(
105
+ () => (
106
+ <Flex padding={padding}>
107
+ <Box
108
+ marginRight={space}
109
+ style={{
110
+ visibility: IconComponent || children ? 'visible' : 'hidden',
111
+ pointerEvents: 'none',
112
+ }}
113
+ >
114
+ {IconComponent && (
115
+ <Text muted={muted} size={fontSize} weight={weight}>
116
+ <IconComponent />
117
+ </Text>
118
+ )}
119
+ {!IconComponent && (
120
+ <ToggleArrowText muted={muted} size={fontSize} weight={weight}>
121
+ <ToggleArrowRightIcon style={{transform: expanded ? 'rotate(90deg)' : undefined}} />
122
+ </ToggleArrowText>
123
+ )}
124
+ </Box>
125
+ <Box flex={1}>
126
+ <Text muted={muted} size={fontSize} textOverflow="ellipsis" weight={weight}>
127
+ {text}
132
128
  </Text>
133
- )}
134
- {!IconComponent && (
135
- <ToggleArrowText muted={muted} size={fontSize} weight={weight}>
136
- <ToggleArrowRightIcon style={{transform: expanded ? 'rotate(90deg)' : undefined}} />
137
- </ToggleArrowText>
138
- )}
139
- </Box>
140
- <Box flex={1}>
141
- <Text muted={muted} size={fontSize} textOverflow="ellipsis" weight={weight}>
142
- {text}
143
- </Text>
144
- </Box>
145
- </Flex>
129
+ </Box>
130
+ </Flex>
131
+ ),
132
+ [IconComponent, children, expanded, fontSize, muted, padding, space, text, weight],
146
133
  )
147
134
 
148
135
  if (href) {
@@ -7,19 +7,20 @@ export type ArrayPropPrimitive = string | number | boolean | undefined | null
7
7
  /**
8
8
  * This API might change. DO NOT USE IN PRODUCTION.
9
9
  * @beta
10
+ * @deprecated use `_getArrayProp` and `useMemo` directly instead
11
+ * @example
12
+ * ```diff
13
+ * -import {useArrayProp} from '@sanity/ui'
14
+ * +import {_getArrayProp} from '@sanity/ui'
15
+ * +import {useMemo} from 'react'
16
+ *
17
+ * -const width = useArrayProp(props.width)
18
+ * +const width = useMemo(() => _getArrayProp(props.width), [props.width])
19
+ * ```
10
20
  */
11
21
  export function useArrayProp<T extends ArrayPropPrimitive = ArrayPropPrimitive>(
12
22
  val: T | T[] | undefined,
13
23
  defaultVal?: T[],
14
24
  ): T[] {
15
- // JSON.stringify is fast, but it's not faster than useMemo's referencial equality check
16
- const __perf_hash__ = useMemo(() => JSON.stringify(val ?? defaultVal), [defaultVal, val])
17
-
18
- return useMemo(
19
- () => _getArrayProp(val, defaultVal),
20
-
21
- // Improve performance: Keep object identify for a given hash of the value
22
- // eslint-disable-next-line react-hooks/exhaustive-deps
23
- [__perf_hash__],
24
- )
25
+ return useMemo(() => _getArrayProp(val, defaultVal), [defaultVal, val])
25
26
  }
@@ -1,8 +1,8 @@
1
1
  import {ThemeColorAvatarColorKey} from '@sanity/ui/theme'
2
- import {forwardRef, useCallback, useEffect, useId, useMemo, useState} from 'react'
3
- import ReactIs from 'react-is'
2
+ import {forwardRef, useCallback, useEffect, useId, useState} from 'react'
3
+ import {isValidElementType} from 'react-is'
4
4
  import {styled} from 'styled-components'
5
- import {useArrayProp} from '../../hooks'
5
+ import {_getArrayProp} from '../../styles'
6
6
  import {useTheme_v2} from '../../theme'
7
7
  import {AvatarPosition, AvatarSize, AvatarStatus} from '../../types'
8
8
  import {Label} from '../label'
@@ -73,8 +73,8 @@ export const Avatar = forwardRef(function Avatar(
73
73
  ...restProps
74
74
  } = props
75
75
  const {avatar} = useTheme_v2()
76
- const as = ReactIs.isValidElementType(asProp) ? asProp : 'div'
77
- const size = useArrayProp(sizeProp)
76
+ const as = isValidElementType(asProp) ? asProp : 'div'
77
+ const size = _getArrayProp(sizeProp)
78
78
 
79
79
  // @todo: remove this
80
80
  const avatarSize = avatar.sizes[size[0]] || avatar.sizes[0]
@@ -111,17 +111,13 @@ export const Avatar = forwardRef(function Avatar(
111
111
  }
112
112
  }, [onImageLoadError])
113
113
 
114
- const initialsSize = useMemo(
115
- () =>
116
- size.map((s) => {
117
- if (s === 1) return 1
118
- if (s === 2) return 3
119
- if (s === 3) return 5
114
+ const initialsSize = size.map((s) => {
115
+ if (s === 1) return 1
116
+ if (s === 2) return 3
117
+ if (s === 3) return 5
120
118
 
121
- return 0
122
- }),
123
- [size],
124
- )
119
+ return 0
120
+ })
125
121
 
126
122
  return (
127
123
  <Root
@@ -1,9 +1,8 @@
1
1
  import {getTheme_v2} from '@sanity/ui/theme'
2
- import {forwardRef, useMemo} from 'react'
2
+ import {forwardRef} from 'react'
3
3
  import {styled, css} from 'styled-components'
4
4
  import {EMPTY_RECORD} from '../../constants'
5
- import {useArrayProp} from '../../hooks'
6
- import {rem, _responsive, ThemeProps} from '../../styles'
5
+ import {rem, _responsive, ThemeProps, _getArrayProp} from '../../styles'
7
6
  import {AvatarSize} from '../../types'
8
7
  import {Label} from '../label'
9
8
 
@@ -67,23 +66,18 @@ export const AvatarCounter = forwardRef(function AvatarCounter(
67
66
  props: AvatarCounterProps,
68
67
  ref: React.Ref<HTMLDivElement>,
69
68
  ) {
70
- const {count, size: sizeProp = 1} = props
71
- const size = useArrayProp(sizeProp)
69
+ const {count, size} = props
70
+ const $size = _getArrayProp(size ?? 1)
71
+ const fontSize = $size.map((s) => {
72
+ if (s === 1) return 1
73
+ if (s === 2) return 3
74
+ if (s === 3) return 5
72
75
 
73
- const fontSize = useMemo(
74
- () =>
75
- size.map((s) => {
76
- if (s === 1) return 1
77
- if (s === 2) return 3
78
- if (s === 3) return 5
79
-
80
- return 0
81
- }),
82
- [size],
83
- )
76
+ return 0
77
+ })
84
78
 
85
79
  return (
86
- <Root $size={size} data-ui="AvatarCounter" ref={ref}>
80
+ <Root $size={$size} data-ui="AvatarCounter" ref={ref}>
87
81
  <Label as="span" size={fontSize} weight="medium">
88
82
  {count}
89
83
  </Label>
@@ -2,8 +2,7 @@ import {getTheme_v2} from '@sanity/ui/theme'
2
2
  import {Children, cloneElement, forwardRef, isValidElement, useMemo} from 'react'
3
3
  import {styled, css} from 'styled-components'
4
4
  import {EMPTY_RECORD} from '../../constants'
5
- import {useArrayProp} from '../../hooks'
6
- import {rem, _responsive, ThemeProps} from '../../styles'
5
+ import {rem, _responsive, ThemeProps, _getArrayProp} from '../../styles'
7
6
  import {AvatarSize} from '../../types'
8
7
  import {AvatarCounter} from './avatarCounter'
9
8
 
@@ -65,12 +64,9 @@ export const AvatarStack = forwardRef(function AvatarStack(
65
64
  size: sizeProp = 1,
66
65
  ...restProps
67
66
  } = props
68
- const children = useMemo<React.ReactElement[]>(
69
- () => Children.toArray(childrenProp).filter(isValidElement),
70
- [childrenProp],
71
- )
67
+ const children: React.ReactElement[] = Children.toArray(childrenProp).filter(isValidElement)
72
68
  const maxLength = Math.max(maxLengthProp, 0)
73
- const size = useArrayProp(sizeProp)
69
+ const size = useMemo(() => _getArrayProp(sizeProp), [sizeProp])
74
70
 
75
71
  const len = children.length
76
72
  const visibleCount = maxLength - 1
@@ -1,6 +1,6 @@
1
- import {forwardRef} from 'react'
1
+ import {forwardRef, useMemo} from 'react'
2
2
  import {styled} from 'styled-components'
3
- import {useArrayProp} from '../../hooks'
3
+ import {_getArrayProp} from '../../styles'
4
4
  import {responsiveRadiusStyle, ResponsiveRadiusStyleProps} from '../../styles/internal'
5
5
  import {BadgeMode, BadgeTone} from '../../types'
6
6
  import {Box, BoxProps} from '../box'
@@ -45,13 +45,16 @@ export const Badge = forwardRef(function Badge(
45
45
  ...restProps
46
46
  } = props
47
47
 
48
+ const $radius = useMemo(() => _getArrayProp(radius), [radius])
49
+ const $padding = useMemo(() => _getArrayProp(padding), [padding])
50
+
48
51
  return (
49
52
  <Root
50
53
  data-ui="Badge"
51
54
  {...restProps}
52
55
  $tone={tone}
53
- $radius={useArrayProp(radius)}
54
- padding={useArrayProp(padding)}
56
+ $radius={$radius}
57
+ padding={$padding}
55
58
  ref={ref}
56
59
  >
57
60
  <Text size={fontSize}>{children}</Text>
@@ -1,6 +1,6 @@
1
- import {forwardRef} from 'react'
1
+ import {forwardRef, useMemo} from 'react'
2
2
  import {styled} from 'styled-components'
3
- import {useArrayProp} from '../../hooks'
3
+ import {_getArrayProp} from '../../styles'
4
4
  import {
5
5
  boxStyle,
6
6
  flexItemStyle,
@@ -90,36 +90,62 @@ export const Box = forwardRef(function Box(
90
90
  ...restProps
91
91
  } = props
92
92
 
93
+ const $column = useMemo(() => _getArrayProp(column), [column])
94
+ const $columnStart = useMemo(() => _getArrayProp(columnStart), [columnStart])
95
+ const $columnEnd = useMemo(() => _getArrayProp(columnEnd), [columnEnd])
96
+ const $display = useMemo(() => _getArrayProp(display), [display])
97
+ const $flex = useMemo(() => _getArrayProp(flex), [flex])
98
+ const $height = useMemo(() => _getArrayProp(height), [height])
99
+ const $margin = useMemo(() => _getArrayProp(margin), [margin])
100
+ const $marginX = useMemo(() => _getArrayProp(marginX), [marginX])
101
+ const $marginY = useMemo(() => _getArrayProp(marginY), [marginY])
102
+ const $marginTop = useMemo(() => _getArrayProp(marginTop), [marginTop])
103
+ const $marginRight = useMemo(() => _getArrayProp(marginRight), [marginRight])
104
+ const $marginBottom = useMemo(() => _getArrayProp(marginBottom), [marginBottom])
105
+ const $marginLeft = useMemo(() => _getArrayProp(marginLeft), [marginLeft])
106
+ const $overflow = useMemo(() => _getArrayProp(overflow), [overflow])
107
+ const $padding = useMemo(() => _getArrayProp(padding), [padding])
108
+ const $paddingX = useMemo(() => _getArrayProp(paddingX), [paddingX])
109
+ const $paddingY = useMemo(() => _getArrayProp(paddingY), [paddingY])
110
+ const $paddingTop = useMemo(() => _getArrayProp(paddingTop), [paddingTop])
111
+ const $paddingRight = useMemo(() => _getArrayProp(paddingRight), [paddingRight])
112
+ const $paddingBottom = useMemo(() => _getArrayProp(paddingBottom), [paddingBottom])
113
+ const $paddingLeft = useMemo(() => _getArrayProp(paddingLeft), [paddingLeft])
114
+ const $row = useMemo(() => _getArrayProp(row), [row])
115
+ const $rowStart = useMemo(() => _getArrayProp(rowStart), [rowStart])
116
+ const $rowEnd = useMemo(() => _getArrayProp(rowEnd), [rowEnd])
117
+ const $sizing = useMemo(() => _getArrayProp(sizing), [sizing])
118
+
93
119
  return (
94
120
  <Root
95
121
  data-as={typeof asProp === 'string' ? asProp : undefined}
96
122
  data-ui="Box"
97
123
  {...restProps}
98
- $column={useArrayProp(column)}
99
- $columnStart={useArrayProp(columnStart)}
100
- $columnEnd={useArrayProp(columnEnd)}
101
- $display={useArrayProp(display)}
102
- $flex={useArrayProp(flex)}
103
- $height={useArrayProp(height)}
104
- $margin={useArrayProp(margin)}
105
- $marginX={useArrayProp(marginX)}
106
- $marginY={useArrayProp(marginY)}
107
- $marginTop={useArrayProp(marginTop)}
108
- $marginRight={useArrayProp(marginRight)}
109
- $marginBottom={useArrayProp(marginBottom)}
110
- $marginLeft={useArrayProp(marginLeft)}
111
- $overflow={useArrayProp(overflow)}
112
- $padding={useArrayProp(padding)}
113
- $paddingX={useArrayProp(paddingX)}
114
- $paddingY={useArrayProp(paddingY)}
115
- $paddingTop={useArrayProp(paddingTop)}
116
- $paddingRight={useArrayProp(paddingRight)}
117
- $paddingBottom={useArrayProp(paddingBottom)}
118
- $paddingLeft={useArrayProp(paddingLeft)}
119
- $row={useArrayProp(row)}
120
- $rowStart={useArrayProp(rowStart)}
121
- $rowEnd={useArrayProp(rowEnd)}
122
- $sizing={useArrayProp(sizing)}
124
+ $column={$column}
125
+ $columnStart={$columnStart}
126
+ $columnEnd={$columnEnd}
127
+ $display={$display}
128
+ $flex={$flex}
129
+ $height={$height}
130
+ $margin={$margin}
131
+ $marginX={$marginX}
132
+ $marginY={$marginY}
133
+ $marginTop={$marginTop}
134
+ $marginRight={$marginRight}
135
+ $marginBottom={$marginBottom}
136
+ $marginLeft={$marginLeft}
137
+ $overflow={$overflow}
138
+ $padding={$padding}
139
+ $paddingX={$paddingX}
140
+ $paddingY={$paddingY}
141
+ $paddingTop={$paddingTop}
142
+ $paddingRight={$paddingRight}
143
+ $paddingBottom={$paddingBottom}
144
+ $paddingLeft={$paddingLeft}
145
+ $row={$row}
146
+ $rowStart={$rowStart}
147
+ $rowEnd={$rowEnd}
148
+ $sizing={$sizing}
123
149
  as={asProp}
124
150
  ref={ref}
125
151
  >
@@ -1,8 +1,7 @@
1
1
  import {forwardRef, isValidElement, useMemo} from 'react'
2
2
  import {isValidElementType} from 'react-is'
3
3
  import {styled} from 'styled-components'
4
- import {useArrayProp} from '../../hooks'
5
- import {ThemeProps} from '../../styles'
4
+ import {ThemeProps, _getArrayProp} from '../../styles'
6
5
  import {responsiveRadiusStyle, ResponsiveRadiusStyleProps} from '../../styles/internal'
7
6
  import {useTheme_v2} from '../../theme'
8
7
  import {ButtonMode, ButtonTextAlign, ButtonTone, ButtonWidth, FlexJustify} from '../../types'
@@ -93,16 +92,16 @@ export const Button = forwardRef(function Button(
93
92
  } = props
94
93
  const {button} = useTheme_v2()
95
94
 
96
- const justify = useArrayProp(justifyProp)
97
- const padding = useArrayProp(paddingProp)
98
- const paddingX = useArrayProp(paddingXProp)
99
- const paddingY = useArrayProp(paddingYProp)
100
- const paddingTop = useArrayProp(paddingTopProp)
101
- const paddingBottom = useArrayProp(paddingBottomProp)
102
- const paddingLeft = useArrayProp(paddingLeftProp)
103
- const paddingRight = useArrayProp(paddingRightProp)
104
- const radius = useArrayProp(radiusProp)
105
- const space = useArrayProp(spaceProp)
95
+ const justify = useMemo(() => _getArrayProp(justifyProp), [justifyProp])
96
+ const padding = useMemo(() => _getArrayProp(paddingProp), [paddingProp])
97
+ const paddingX = useMemo(() => _getArrayProp(paddingXProp), [paddingXProp])
98
+ const paddingY = useMemo(() => _getArrayProp(paddingYProp), [paddingYProp])
99
+ const paddingTop = useMemo(() => _getArrayProp(paddingTopProp), [paddingTopProp])
100
+ const paddingBottom = useMemo(() => _getArrayProp(paddingBottomProp), [paddingBottomProp])
101
+ const paddingLeft = useMemo(() => _getArrayProp(paddingLeftProp), [paddingLeftProp])
102
+ const paddingRight = useMemo(() => _getArrayProp(paddingRightProp), [paddingRightProp])
103
+ const radius = useMemo(() => _getArrayProp(radiusProp), [radiusProp])
104
+ const space = useMemo(() => _getArrayProp(spaceProp), [spaceProp])
106
105
 
107
106
  const boxProps = useMemo(
108
107
  () => ({
@@ -1,8 +1,8 @@
1
1
  import {ThemeColorSchemeKey} from '@sanity/ui/theme'
2
- import {forwardRef} from 'react'
2
+ import {forwardRef, useMemo} from 'react'
3
3
  import {isValidElementType} from 'react-is'
4
4
  import {styled} from 'styled-components'
5
- import {useArrayProp} from '../../hooks'
5
+ import {_getArrayProp} from '../../styles'
6
6
  import {
7
7
  responsiveBorderStyle,
8
8
  ResponsiveBorderStyleProps,
@@ -82,6 +82,14 @@ export const Card = forwardRef(function Card(
82
82
  const rootTheme = useRootTheme()
83
83
  const tone = toneProp === 'inherit' ? rootTheme.tone : toneProp
84
84
 
85
+ const $border = useMemo(() => _getArrayProp(border), [border])
86
+ const $borderTop = useMemo(() => _getArrayProp(borderTop), [borderTop])
87
+ const $borderRight = useMemo(() => _getArrayProp(borderRight), [borderRight])
88
+ const $borderBottom = useMemo(() => _getArrayProp(borderBottom), [borderBottom])
89
+ const $borderLeft = useMemo(() => _getArrayProp(borderLeft), [borderLeft])
90
+ const $radius = useMemo(() => _getArrayProp(radius), [radius])
91
+ const $shadow = useMemo(() => _getArrayProp(shadow), [shadow])
92
+
85
93
  // todo: Consider adding the wrapper approach for nested cards in which the tones are not changing, avoid unnecessary ThemeColorProvider
86
94
  return (
87
95
  <ThemeColorProvider scheme={scheme} tone={tone}>
@@ -91,16 +99,16 @@ export const Card = forwardRef(function Card(
91
99
  data-ui="Card"
92
100
  data-tone={tone}
93
101
  {...restProps}
94
- $border={useArrayProp(border)}
95
- $borderTop={useArrayProp(borderTop)}
96
- $borderRight={useArrayProp(borderRight)}
97
- $borderBottom={useArrayProp(borderBottom)}
98
- $borderLeft={useArrayProp(borderLeft)}
102
+ $border={$border}
103
+ $borderTop={$borderTop}
104
+ $borderRight={$borderRight}
105
+ $borderBottom={$borderBottom}
106
+ $borderLeft={$borderLeft}
107
+ $radius={$radius}
108
+ $shadow={$shadow}
99
109
  $checkered={checkered}
100
110
  $focusRing={focusRing}
101
111
  $muted={muted}
102
- $radius={useArrayProp(radius)}
103
- $shadow={useArrayProp(shadow)}
104
112
  $tone={tone}
105
113
  data-checkered={checkered ? '' : undefined}
106
114
  data-pressed={pressed ? '' : undefined}
@@ -1,8 +1,8 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import {forwardRef} from 'react'
2
+ import {forwardRef, useMemo} from 'react'
3
3
  import Refractor from 'react-refractor'
4
4
  import {styled} from 'styled-components'
5
- import {useArrayProp} from '../../hooks'
5
+ import {_getArrayProp} from '../../styles'
6
6
  import {responsiveCodeFontStyle, ResponsiveFontStyleProps} from '../../styles/internal'
7
7
  import {codeBaseStyle} from './styles'
8
8
 
@@ -29,9 +29,10 @@ export const Code = forwardRef(function Code(
29
29
  const {children, language: languageProp, size = 2, weight, ...restProps} = props
30
30
  const language = typeof languageProp === 'string' ? languageProp : undefined
31
31
  const registered = language ? Refractor.hasLanguage(language as any) : false
32
+ const $size = useMemo(() => _getArrayProp(size), [size])
32
33
 
33
34
  return (
34
- <Root data-ui="Code" {...restProps} $size={useArrayProp(size)} $weight={weight} ref={ref}>
35
+ <Root data-ui="Code" {...restProps} $size={$size} $weight={weight} ref={ref}>
35
36
  {!(language && registered) && <code>{children}</code>}
36
37
  {language && registered && <Refractor inline language={language} value={String(children)} />}
37
38
  </Root>
@@ -1,6 +1,6 @@
1
- import {forwardRef} from 'react'
1
+ import {forwardRef, useMemo} from 'react'
2
2
  import {styled} from 'styled-components'
3
- import {useArrayProp} from '../../hooks'
3
+ import {_getArrayProp} from '../../styles'
4
4
  import {Box, BoxProps} from '../box'
5
5
  import {ResponsiveWidthProps} from '../types'
6
6
  import {containerBaseStyle, responsiveContainerWidthStyle} from './styles'
@@ -26,14 +26,7 @@ export const Container = forwardRef(function Container(
26
26
  ref: React.ForwardedRef<HTMLDivElement>,
27
27
  ) {
28
28
  const {as, width = 2, ...restProps} = props
29
+ const $width = useMemo(() => _getArrayProp(width), [width])
29
30
 
30
- return (
31
- <Root
32
- data-ui="Container"
33
- {...restProps}
34
- $width={useArrayProp(width)}
35
- forwardedAs={as}
36
- ref={ref}
37
- />
38
- )
31
+ return <Root data-ui="Container" {...restProps} $width={$width} forwardedAs={as} ref={ref} />
39
32
  })
@@ -1,6 +1,6 @@
1
- import {forwardRef} from 'react'
1
+ import {forwardRef, useMemo} from 'react'
2
2
  import {styled} from 'styled-components'
3
- import {useArrayProp} from '../../hooks'
3
+ import {_getArrayProp} from '../../styles'
4
4
  import {
5
5
  flexItemStyle,
6
6
  FlexItemStyleProps,
@@ -36,15 +36,21 @@ export const Flex = forwardRef(function Flex(
36
36
  ) {
37
37
  const {align, as, direction = 'row', gap, justify, wrap, ...restProps} = props
38
38
 
39
+ const $align = useMemo(() => _getArrayProp(align), [align])
40
+ const $direction = useMemo(() => _getArrayProp(direction), [direction])
41
+ const $gap = useMemo(() => _getArrayProp(gap), [gap])
42
+ const $justify = useMemo(() => _getArrayProp(justify), [justify])
43
+ const $wrap = useMemo(() => _getArrayProp(wrap), [wrap])
44
+
39
45
  return (
40
46
  <Root
41
47
  data-ui="Flex"
42
48
  {...restProps}
43
- $align={useArrayProp(align)}
44
- $direction={useArrayProp(direction)}
45
- $gap={useArrayProp(gap)}
46
- $justify={useArrayProp(justify)}
47
- $wrap={useArrayProp(wrap)}
49
+ $align={$align}
50
+ $direction={$direction}
51
+ $gap={$gap}
52
+ $justify={$justify}
53
+ $wrap={$wrap}
48
54
  forwardedAs={as}
49
55
  ref={ref}
50
56
  />