@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.
- package/dist/index.compiled.mjs +7488 -0
- package/dist/index.compiled.mjs.map +1 -0
- package/dist/index.d.mts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.esm.js +1047 -1072
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1054 -1079
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1047 -1072
- package/dist/index.mjs.map +1 -1
- package/package.json +31 -35
- package/src/core/components/autocomplete/autocomplete.tsx +31 -34
- package/src/core/components/breadcrumbs/breadcrumbs.tsx +3 -2
- package/src/core/components/dialog/dialog.tsx +23 -12
- package/src/core/components/hotkeys/hotkeys.tsx +3 -3
- package/src/core/components/menu/menu.tsx +5 -1
- package/src/core/components/menu/menuButton.tsx +17 -32
- package/src/core/components/menu/menuGroup.tsx +7 -5
- package/src/core/components/menu/menuItem.tsx +10 -6
- package/src/core/components/skeleton/skeleton.tsx +5 -11
- package/src/core/components/skeleton/textSkeleton.tsx +6 -7
- package/src/core/components/toast/toastProvider.tsx +26 -24
- package/src/core/components/tree/treeItem.styles.ts +21 -0
- package/src/core/components/tree/treeItem.tsx +31 -44
- package/src/core/hooks/useArrayProp.ts +11 -10
- package/src/core/primitives/avatar/avatar.tsx +11 -15
- package/src/core/primitives/avatar/avatarCounter.tsx +11 -17
- package/src/core/primitives/avatar/avatarStack.tsx +3 -7
- package/src/core/primitives/badge/badge.tsx +7 -4
- package/src/core/primitives/box/box.tsx +53 -27
- package/src/core/primitives/button/button.tsx +11 -12
- package/src/core/primitives/card/card.tsx +17 -9
- package/src/core/primitives/code/code.tsx +4 -3
- package/src/core/primitives/container/container.tsx +4 -11
- package/src/core/primitives/flex/flex.tsx +13 -7
- package/src/core/primitives/grid/grid.tsx +19 -10
- package/src/core/primitives/heading/heading.tsx +7 -4
- package/src/core/primitives/inline/inline.tsx +3 -2
- package/src/core/primitives/kbd/kbd.tsx +4 -3
- package/src/core/primitives/label/label.tsx +7 -4
- package/src/core/primitives/popover/popover.tsx +49 -49
- package/src/core/primitives/select/select.tsx +12 -6
- package/src/core/primitives/stack/stack.tsx +4 -3
- package/src/core/primitives/text/text.tsx +7 -4
- package/src/core/primitives/textArea/textArea.tsx +12 -6
- package/src/core/primitives/textInput/textInput.tsx +6 -5
- package/src/core/primitives/tooltip/tooltip.tsx +14 -7
- package/src/core/theme/themeProvider.tsx +4 -6
- package/src/core/utils/elementQuery/elementQuery.tsx +4 -3
- package/src/core/utils/layer/getLayerContext.test.ts +0 -4
- package/src/core/utils/layer/layer.test.tsx +0 -2
- package/src/core/utils/layer/layerProvider.tsx +35 -43
- package/src/core/utils/layer/types.ts +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/ui",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.7-canary.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"sanity",
|
|
6
6
|
"ui",
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
"exports": {
|
|
24
24
|
".": {
|
|
25
25
|
"source": "./exports/index.ts",
|
|
26
|
+
"react-compiler": {
|
|
27
|
+
"source": "./exports/index.ts",
|
|
28
|
+
"default": "./dist/index.compiled.mjs"
|
|
29
|
+
},
|
|
26
30
|
"import": "./dist/index.mjs",
|
|
27
31
|
"require": "./dist/index.js",
|
|
28
32
|
"default": "./dist/index.js"
|
|
@@ -51,32 +55,6 @@
|
|
|
51
55
|
"src",
|
|
52
56
|
"theme.js"
|
|
53
57
|
],
|
|
54
|
-
"scripts": {
|
|
55
|
-
"build": "run-s clean pkg:build pkg:check figma:pkg:build",
|
|
56
|
-
"clean": "rimraf .workshop dist",
|
|
57
|
-
"commit": "cz",
|
|
58
|
-
"cypress:dev": "run-p dev cypress:open",
|
|
59
|
-
"cypress:open": "cypress open",
|
|
60
|
-
"cypress:run": "cypress run",
|
|
61
|
-
"dev": "run-p storybook:dev workshop:dev",
|
|
62
|
-
"figma:pkg:build": "cd figma && pnpm build",
|
|
63
|
-
"format": "prettier --write --cache --ignore-unknown .",
|
|
64
|
-
"lint": "eslint . --ext .cjs,.js,.jsx,.mjs,.ts,.tsx",
|
|
65
|
-
"pkg:build": "pkg build --strict",
|
|
66
|
-
"pkg:check": "pkg --strict",
|
|
67
|
-
"prepare": "husky install",
|
|
68
|
-
"prepublishOnly": "pnpm build",
|
|
69
|
-
"release": "semantic-release",
|
|
70
|
-
"storybook:build": "storybook build",
|
|
71
|
-
"storybook:dev": "storybook dev -p 6006",
|
|
72
|
-
"test": "jest",
|
|
73
|
-
"test:browser": "start-server-and-test 'run-s workshop:build workshop:start' http://localhost:1337 'run-s cypress:run'",
|
|
74
|
-
"ts:check": "tsc",
|
|
75
|
-
"watch": "pkg watch --strict",
|
|
76
|
-
"workshop:build": "workshop build",
|
|
77
|
-
"workshop:dev": "workshop dev",
|
|
78
|
-
"workshop:start": "http-server -a localhost -c-0 -p 1337 -s -P http://localhost:1337/index.html? dist"
|
|
79
|
-
},
|
|
80
58
|
"commitlint": {
|
|
81
59
|
"extends": [
|
|
82
60
|
"@commitlint/config-conventional"
|
|
@@ -106,7 +84,7 @@
|
|
|
106
84
|
"dependencies": {
|
|
107
85
|
"@floating-ui/react-dom": "^2.1.0",
|
|
108
86
|
"@sanity/color": "^3.0.6",
|
|
109
|
-
"@sanity/icons": "
|
|
87
|
+
"@sanity/icons": "3.2.1-canary.0",
|
|
110
88
|
"csstype": "^3.1.3",
|
|
111
89
|
"framer-motion": "11.0.8",
|
|
112
90
|
"react-refractor": "^2.2.0"
|
|
@@ -119,7 +97,7 @@
|
|
|
119
97
|
"@commitlint/cli": "^19.3.0",
|
|
120
98
|
"@commitlint/config-conventional": "^19.2.2",
|
|
121
99
|
"@juggle/resize-observer": "^3.4.0",
|
|
122
|
-
"@sanity/pkg-utils": "
|
|
100
|
+
"@sanity/pkg-utils": "6.9.4-canary.1",
|
|
123
101
|
"@sanity/semantic-release-preset": "^4.1.8",
|
|
124
102
|
"@sanity/ui-workshop": "^2.0.15",
|
|
125
103
|
"@storybook/addon-a11y": "^8.0.8",
|
|
@@ -193,7 +171,6 @@
|
|
|
193
171
|
"react-is": "^18",
|
|
194
172
|
"styled-components": "^5.2 || ^6"
|
|
195
173
|
},
|
|
196
|
-
"packageManager": "pnpm@9.2.0",
|
|
197
174
|
"engines": {
|
|
198
175
|
"node": ">=14.0.0"
|
|
199
176
|
},
|
|
@@ -203,9 +180,28 @@
|
|
|
203
180
|
"esm.sh": {
|
|
204
181
|
"bundle": false
|
|
205
182
|
},
|
|
206
|
-
"
|
|
207
|
-
"
|
|
208
|
-
|
|
209
|
-
|
|
183
|
+
"scripts": {
|
|
184
|
+
"build": "run-s clean pkg:build pkg:check figma:pkg:build",
|
|
185
|
+
"clean": "rimraf .workshop dist",
|
|
186
|
+
"commit": "cz",
|
|
187
|
+
"cypress:dev": "run-p dev cypress:open",
|
|
188
|
+
"cypress:open": "cypress open",
|
|
189
|
+
"cypress:run": "cypress run",
|
|
190
|
+
"dev": "run-p storybook:dev workshop:dev",
|
|
191
|
+
"figma:pkg:build": "cd figma && pnpm build",
|
|
192
|
+
"format": "prettier --write --cache --ignore-unknown .",
|
|
193
|
+
"lint": "eslint . --ext .cjs,.js,.jsx,.mjs,.ts,.tsx",
|
|
194
|
+
"pkg:build": "pkg build --strict",
|
|
195
|
+
"pkg:check": "pkg --strict",
|
|
196
|
+
"release": "semantic-release",
|
|
197
|
+
"storybook:build": "storybook build",
|
|
198
|
+
"storybook:dev": "storybook dev -p 6006",
|
|
199
|
+
"test": "jest",
|
|
200
|
+
"test:browser": "start-server-and-test 'run-s workshop:build workshop:start' http://localhost:1337 'run-s cypress:run'",
|
|
201
|
+
"ts:check": "tsc",
|
|
202
|
+
"watch": "pkg watch --strict",
|
|
203
|
+
"workshop:build": "workshop build",
|
|
204
|
+
"workshop:dev": "workshop dev",
|
|
205
|
+
"workshop:start": "http-server -a localhost -c-0 -p 1337 -s -P http://localhost:1337/index.html? dist"
|
|
210
206
|
}
|
|
211
|
-
}
|
|
207
|
+
}
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
} from 'react'
|
|
21
21
|
import {EMPTY_ARRAY, EMPTY_RECORD} from '../../constants'
|
|
22
22
|
import {_hasFocus, _raf, focusFirstDescendant} from '../../helpers'
|
|
23
|
-
import {useArrayProp} from '../../hooks'
|
|
24
23
|
import {
|
|
25
24
|
Box,
|
|
26
25
|
BoxProps,
|
|
@@ -32,6 +31,7 @@ import {
|
|
|
32
31
|
Text,
|
|
33
32
|
TextInput,
|
|
34
33
|
} from '../../primitives'
|
|
34
|
+
import {_getArrayProp} from '../../styles'
|
|
35
35
|
import {Radius} from '../../types'
|
|
36
36
|
import {AnimatedSpinnerIcon, ListBox, Root} from './autocomplete.styles'
|
|
37
37
|
import {AutocompleteOption} from './autocompleteOption'
|
|
@@ -200,7 +200,7 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
|
|
|
200
200
|
|
|
201
201
|
const listBoxId = `${id}-listbox`
|
|
202
202
|
const options = Array.isArray(optionsProp) ? optionsProp : EMPTY_ARRAY
|
|
203
|
-
const padding =
|
|
203
|
+
const padding = _getArrayProp(paddingProp)
|
|
204
204
|
const currentOption = useMemo(
|
|
205
205
|
() => (value !== null ? options.find((o) => o.value === value) : undefined),
|
|
206
206
|
[options, value],
|
|
@@ -213,44 +213,41 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
|
|
|
213
213
|
const activeItemId = activeValue ? `${id}-option-${activeValue}` : undefined
|
|
214
214
|
const expanded = (query !== null && loading) || (focused && query !== null)
|
|
215
215
|
|
|
216
|
-
const handleRootBlur =
|
|
217
|
-
(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
216
|
+
const handleRootBlur = (event: FocusEvent<HTMLInputElement>) => {
|
|
217
|
+
setTimeout(() => {
|
|
218
|
+
// NOTE: This is a workaround for a bug that may happen in Chrome (clicking the scrollbar
|
|
219
|
+
// closes the results in certain situations):
|
|
220
|
+
// - Do not handle blur if the mouse is within the popover
|
|
221
|
+
if (popoverMouseWithinRef.current) {
|
|
222
|
+
return
|
|
223
|
+
}
|
|
225
224
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
225
|
+
const elements: HTMLElement[] = (relatedElements || []).concat(
|
|
226
|
+
rootElementRef.current ? [rootElementRef.current] : [],
|
|
227
|
+
resultsPopoverElementRef.current ? [resultsPopoverElementRef.current] : [],
|
|
228
|
+
)
|
|
230
229
|
|
|
231
|
-
|
|
230
|
+
let focusInside = false
|
|
232
231
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
232
|
+
if (document.activeElement) {
|
|
233
|
+
for (const e of elements) {
|
|
234
|
+
if (e === document.activeElement || e.contains(document.activeElement)) {
|
|
235
|
+
focusInside = true
|
|
236
|
+
break
|
|
239
237
|
}
|
|
240
238
|
}
|
|
239
|
+
}
|
|
241
240
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
[onBlur, onQueryChange, relatedElements],
|
|
251
|
-
)
|
|
241
|
+
if (focusInside === false) {
|
|
242
|
+
dispatch({type: 'root/blur'})
|
|
243
|
+
popoverMouseWithinRef.current = false
|
|
244
|
+
if (onQueryChange) onQueryChange(null)
|
|
245
|
+
if (onBlur) onBlur(event)
|
|
246
|
+
}
|
|
247
|
+
}, 0)
|
|
248
|
+
}
|
|
252
249
|
|
|
253
|
-
const handleRootFocus =
|
|
250
|
+
const handleRootFocus = (event: FocusEvent<HTMLDivElement>) => {
|
|
254
251
|
const listBoxElement = listBoxElementRef.current
|
|
255
252
|
const focusedElement = event.target instanceof HTMLElement ? event.target : null
|
|
256
253
|
const listFocused = listBoxElement?.contains(focusedElement) || false
|
|
@@ -260,7 +257,7 @@ const InnerAutocomplete = forwardRef(function InnerAutocomplete<
|
|
|
260
257
|
|
|
261
258
|
dispatch({type: 'root/setListFocused', listFocused})
|
|
262
259
|
}
|
|
263
|
-
}
|
|
260
|
+
}
|
|
264
261
|
|
|
265
262
|
const handleOptionSelect = useCallback(
|
|
266
263
|
(v: string) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {Children, forwardRef, Fragment, isValidElement, useCallback, useMemo, useState} from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import {useClickOutside} from '../../hooks'
|
|
3
3
|
import {Box, Popover, Stack, Text} from '../../primitives'
|
|
4
|
+
import {_getArrayProp} from '../../styles'
|
|
4
5
|
import {ExpandButton, Root} from './breadcrumbs.styles'
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -20,7 +21,7 @@ export const Breadcrumbs = forwardRef(function Breadcrumbs(
|
|
|
20
21
|
ref: React.ForwardedRef<HTMLOListElement>,
|
|
21
22
|
) {
|
|
22
23
|
const {children, maxLength, separator, space: spaceRaw = 2, ...restProps} = props
|
|
23
|
-
const space =
|
|
24
|
+
const space = useMemo(() => _getArrayProp(spaceRaw), [spaceRaw])
|
|
24
25
|
const [open, setOpen] = useState(false)
|
|
25
26
|
const [expandElement, setExpandElement] = useState<HTMLButtonElement | null>(null)
|
|
26
27
|
const [popoverElement, setPopoverElement] = useState<HTMLDivElement | null>(null)
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import {CloseIcon} from '@sanity/icons'
|
|
2
2
|
import {ThemeColorSchemeKey} from '@sanity/ui/theme'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
forwardRef,
|
|
5
|
+
useCallback,
|
|
6
|
+
useEffect,
|
|
7
|
+
useImperativeHandle,
|
|
8
|
+
useMemo,
|
|
9
|
+
useRef,
|
|
10
|
+
useState,
|
|
11
|
+
} from 'react'
|
|
4
12
|
import {styled} from 'styled-components'
|
|
5
13
|
import {
|
|
6
14
|
containsOrEqualsElement,
|
|
@@ -8,9 +16,10 @@ import {
|
|
|
8
16
|
focusLastDescendant,
|
|
9
17
|
isHTMLElement,
|
|
10
18
|
} from '../../helpers'
|
|
11
|
-
import {
|
|
19
|
+
import {useClickOutside, useGlobalKeyDown, usePrefersReducedMotion} from '../../hooks'
|
|
12
20
|
import {Box, Button, Card, Container, Flex, Text} from '../../primitives'
|
|
13
21
|
import {ResponsivePaddingProps, ResponsiveWidthProps} from '../../primitives/types'
|
|
22
|
+
import {_getArrayProp} from '../../styles'
|
|
14
23
|
import {responsivePaddingStyle, ResponsivePaddingStyleProps} from '../../styles/internal'
|
|
15
24
|
import {useTheme_v2} from '../../theme'
|
|
16
25
|
import {DialogPosition, Radius} from '../../types'
|
|
@@ -166,9 +175,9 @@ const DialogCard = forwardRef(function DialogCard(
|
|
|
166
175
|
const portal = usePortal()
|
|
167
176
|
const portalElement = portalProp ? portal.elements?.[portalProp] || null : portal.element
|
|
168
177
|
const boundaryElement = useBoundaryElement().element
|
|
169
|
-
const radius =
|
|
170
|
-
const shadow =
|
|
171
|
-
const width =
|
|
178
|
+
const radius = useMemo(() => _getArrayProp(radiusProp), [radiusProp])
|
|
179
|
+
const shadow = useMemo(() => _getArrayProp(shadowProp), [shadowProp])
|
|
180
|
+
const width = useMemo(() => _getArrayProp(widthProp), [widthProp])
|
|
172
181
|
const ref = useRef<HTMLDivElement | null>(null)
|
|
173
182
|
const [rootElement, setRootElement] = useState<HTMLDivElement | null>(null)
|
|
174
183
|
const contentRef = useRef<HTMLDivElement | null>(null)
|
|
@@ -307,23 +316,25 @@ export const Dialog = forwardRef(function Dialog(
|
|
|
307
316
|
onFocus,
|
|
308
317
|
padding: paddingProp = 3,
|
|
309
318
|
portal: portalProp,
|
|
310
|
-
position:
|
|
319
|
+
position: _position,
|
|
311
320
|
scheme,
|
|
312
321
|
width: widthProp = 0,
|
|
313
|
-
zOffset:
|
|
322
|
+
zOffset: _zOffset,
|
|
314
323
|
animate: _animate = false,
|
|
315
324
|
...restProps
|
|
316
325
|
} = props
|
|
326
|
+
const positionProp = _position ?? (dialog.position || 'fixed')
|
|
327
|
+
const zOffsetProp = _zOffset ?? (dialog.zOffset || layer.dialog.zOffset)
|
|
317
328
|
const prefersReducedMotion = usePrefersReducedMotion()
|
|
318
329
|
const animate = prefersReducedMotion ? false : _animate
|
|
319
330
|
const portal = usePortal()
|
|
320
331
|
const portalElement = portalProp ? portal.elements?.[portalProp] || null : portal.element
|
|
321
332
|
const boundaryElement = useBoundaryElement().element
|
|
322
|
-
const cardRadius =
|
|
323
|
-
const padding =
|
|
324
|
-
const position =
|
|
325
|
-
const width =
|
|
326
|
-
const zOffset =
|
|
333
|
+
const cardRadius = useMemo(() => _getArrayProp(cardRadiusProp), [cardRadiusProp])
|
|
334
|
+
const padding = useMemo(() => _getArrayProp(paddingProp), [paddingProp])
|
|
335
|
+
const position = useMemo(() => _getArrayProp(positionProp), [positionProp])
|
|
336
|
+
const width = useMemo(() => _getArrayProp(widthProp), [widthProp])
|
|
337
|
+
const zOffset = useMemo(() => _getArrayProp(zOffsetProp), [zOffsetProp])
|
|
327
338
|
const preDivRef = useRef<HTMLDivElement | null>(null)
|
|
328
339
|
const postDivRef = useRef<HTMLDivElement | null>(null)
|
|
329
340
|
const cardRef = useRef<HTMLDivElement | null>(null)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {forwardRef} from 'react'
|
|
1
|
+
import {forwardRef, useMemo} from 'react'
|
|
2
2
|
import {styled} from 'styled-components'
|
|
3
|
-
import {useArrayProp} from '../../hooks'
|
|
4
3
|
import {Inline, KBD} from '../../primitives'
|
|
4
|
+
import {_getArrayProp} from '../../styles'
|
|
5
5
|
import {Radius} from '../../types'
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -40,7 +40,7 @@ export const Hotkeys = forwardRef(function Hotkeys(
|
|
|
40
40
|
ref: React.Ref<HTMLElement>,
|
|
41
41
|
) {
|
|
42
42
|
const {fontSize, keys, padding, radius, space: spaceProp = 0.5, ...restProps} = props
|
|
43
|
-
const space =
|
|
43
|
+
const space = useMemo(() => _getArrayProp(spaceProp), [spaceProp])
|
|
44
44
|
|
|
45
45
|
if (!keys || keys.length === 0) {
|
|
46
46
|
return <></>
|
|
@@ -11,6 +11,7 @@ import {useMenuController} from './useMenuController'
|
|
|
11
11
|
* @public
|
|
12
12
|
*/
|
|
13
13
|
export interface MenuProps extends ResponsivePaddingProps {
|
|
14
|
+
'aria-labelledby'?: string
|
|
14
15
|
/**
|
|
15
16
|
* @deprecated Use `shouldFocus="first"` instead.
|
|
16
17
|
*/
|
|
@@ -20,6 +21,7 @@ export interface MenuProps extends ResponsivePaddingProps {
|
|
|
20
21
|
*/
|
|
21
22
|
focusLast?: boolean
|
|
22
23
|
onClickOutside?: (event: MouseEvent) => void
|
|
24
|
+
onBlurCapture?: (event: React.FocusEvent<HTMLButtonElement>) => void
|
|
23
25
|
onEscape?: () => void
|
|
24
26
|
onItemClick?: () => void
|
|
25
27
|
onItemSelect?: (index: number) => void
|
|
@@ -57,10 +59,12 @@ export const Menu = forwardRef(function Menu(
|
|
|
57
59
|
originElement,
|
|
58
60
|
padding = 1,
|
|
59
61
|
registerElement,
|
|
60
|
-
shouldFocus
|
|
62
|
+
shouldFocus: _shouldFocus,
|
|
61
63
|
space = 1,
|
|
62
64
|
...restProps
|
|
63
65
|
} = props
|
|
66
|
+
const shouldFocus =
|
|
67
|
+
_shouldFocus ?? ((props.focusFirst && 'first') || (props.focusLast && 'last') || null)
|
|
64
68
|
|
|
65
69
|
const ref = useRef<HTMLDivElement | null>(null)
|
|
66
70
|
|
|
@@ -203,8 +203,9 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
203
203
|
}
|
|
204
204
|
}, [])
|
|
205
205
|
|
|
206
|
-
const
|
|
207
|
-
|
|
206
|
+
const menu =
|
|
207
|
+
menuProp &&
|
|
208
|
+
cloneElement<MenuProps>(menuProp, {
|
|
208
209
|
'aria-labelledby': id,
|
|
209
210
|
onBlurCapture: handleBlur,
|
|
210
211
|
onClickOutside: handleMenuClickOutside,
|
|
@@ -213,22 +214,8 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
213
214
|
originElement: buttonElement,
|
|
214
215
|
registerElement,
|
|
215
216
|
shouldFocus,
|
|
216
|
-
})
|
|
217
|
-
[
|
|
218
|
-
buttonElement,
|
|
219
|
-
handleMenuClickOutside,
|
|
220
|
-
handleMenuEscape,
|
|
221
|
-
handleItemClick,
|
|
222
|
-
id,
|
|
223
|
-
handleBlur,
|
|
224
|
-
registerElement,
|
|
225
|
-
shouldFocus,
|
|
226
|
-
],
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
const menu = menuProp && cloneElement(menuProp, menuProps)
|
|
217
|
+
})
|
|
230
218
|
|
|
231
|
-
const ref = useRef<HTMLButtonElement | null>(null)
|
|
232
219
|
const button = useMemo(
|
|
233
220
|
() =>
|
|
234
221
|
buttonProp &&
|
|
@@ -240,7 +227,7 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
240
227
|
onMouseDown: handleMouseDown,
|
|
241
228
|
'aria-haspopup': true,
|
|
242
229
|
'aria-expanded': open,
|
|
243
|
-
ref:
|
|
230
|
+
ref: setButtonElement,
|
|
244
231
|
selected: buttonProp.props.selected ?? open,
|
|
245
232
|
}),
|
|
246
233
|
[buttonProp, handleButtonClick, handleButtonKeyDown, handleMouseDown, id, open],
|
|
@@ -249,19 +236,10 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
249
236
|
// Forward button ref to parent
|
|
250
237
|
useImperativeHandle<HTMLButtonElement | null, HTMLButtonElement | null>(
|
|
251
238
|
forwardedRef,
|
|
252
|
-
() =>
|
|
239
|
+
() => buttonElement,
|
|
240
|
+
[buttonElement],
|
|
253
241
|
)
|
|
254
242
|
|
|
255
|
-
// If there's a button then we need to set the reference element to the cloned button ref
|
|
256
|
-
// and if button changes we make sure to update or remove the reference element.
|
|
257
|
-
useEffect(() => {
|
|
258
|
-
if (!button) return undefined
|
|
259
|
-
|
|
260
|
-
setButtonElement(ref.current)
|
|
261
|
-
|
|
262
|
-
return () => setButtonElement(null)
|
|
263
|
-
}, [button])
|
|
264
|
-
|
|
265
243
|
const popoverProps: MenuButtonProps['popover'] = useMemo(
|
|
266
244
|
() => ({
|
|
267
245
|
boundaryElement: deprecated_boundaryElement,
|
|
@@ -285,8 +263,15 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
285
263
|
)
|
|
286
264
|
|
|
287
265
|
return (
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
266
|
+
<>
|
|
267
|
+
<Popover
|
|
268
|
+
data-ui="MenuButton__popover"
|
|
269
|
+
referenceElement={buttonElement}
|
|
270
|
+
{...popoverProps}
|
|
271
|
+
content={menu}
|
|
272
|
+
open={open}
|
|
273
|
+
/>
|
|
274
|
+
{button}
|
|
275
|
+
</>
|
|
291
276
|
)
|
|
292
277
|
})
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {ChevronRightIcon} from '@sanity/icons'
|
|
2
|
-
import {isValidElement, useCallback, useEffect, useRef, useState} from 'react'
|
|
2
|
+
import {isValidElement, useCallback, useEffect, useMemo, useRef, useState} from 'react'
|
|
3
3
|
import {isValidElementType} from 'react-is'
|
|
4
|
-
import {useArrayProp} from '../../hooks'
|
|
5
4
|
import {Box, Flex, Popover, PopoverProps, Text} from '../../primitives'
|
|
6
5
|
import {Selectable} from '../../primitives/_selectable'
|
|
6
|
+
import {_getArrayProp} from '../../styles'
|
|
7
7
|
import {useRootTheme} from '../../theme'
|
|
8
8
|
import {Radius, SelectableTone} from '../../types'
|
|
9
9
|
import {Menu} from './menu'
|
|
@@ -39,7 +39,7 @@ export function MenuGroup(
|
|
|
39
39
|
onClick,
|
|
40
40
|
padding = 3,
|
|
41
41
|
popover,
|
|
42
|
-
radius = 2,
|
|
42
|
+
radius: radiusProp = 2,
|
|
43
43
|
space = 3,
|
|
44
44
|
text,
|
|
45
45
|
tone = 'default',
|
|
@@ -53,14 +53,16 @@ export function MenuGroup(
|
|
|
53
53
|
onClickOutside,
|
|
54
54
|
onEscape,
|
|
55
55
|
onItemClick,
|
|
56
|
-
onItemMouseEnter
|
|
56
|
+
onItemMouseEnter: _onItemMouseEnter,
|
|
57
57
|
registerElement,
|
|
58
58
|
} = menu
|
|
59
|
+
const onItemMouseEnter = _onItemMouseEnter ?? menu.onMouseEnter
|
|
59
60
|
const [rootElement, setRootElement] = useState<HTMLButtonElement | HTMLDivElement | null>(null)
|
|
60
61
|
const [open, setOpen] = useState(false)
|
|
61
62
|
const shouldFocusRef = useRef<'first' | 'last' | null>(null)
|
|
62
63
|
const active = Boolean(activeElement) && activeElement === rootElement
|
|
63
64
|
const [withinMenu, setWithinMenu] = useState(false)
|
|
65
|
+
const radius = useMemo(() => _getArrayProp(radiusProp), [radiusProp])
|
|
64
66
|
|
|
65
67
|
const handleMouseEnter = useCallback(
|
|
66
68
|
(event: React.MouseEvent<HTMLElement>) => {
|
|
@@ -166,7 +168,7 @@ export function MenuGroup(
|
|
|
166
168
|
aria-pressed={as === 'button' ? withinMenu : undefined}
|
|
167
169
|
data-pressed={as !== 'button' ? withinMenu : undefined}
|
|
168
170
|
data-selected={!withinMenu && active ? '' : undefined}
|
|
169
|
-
$radius={
|
|
171
|
+
$radius={radius}
|
|
170
172
|
$tone={tone}
|
|
171
173
|
$scheme={scheme}
|
|
172
174
|
onClick={handleClick}
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
useState,
|
|
10
10
|
} from 'react'
|
|
11
11
|
import {isValidElementType} from 'react-is'
|
|
12
|
-
import {useArrayProp} from '../../hooks'
|
|
13
12
|
import {Box, Flex, Text} from '../../primitives'
|
|
14
13
|
import {Selectable} from '../../primitives/_selectable'
|
|
15
14
|
import {ResponsivePaddingProps, ResponsiveRadiusProps} from '../../primitives/types'
|
|
15
|
+
import {_getArrayProp} from '../../styles'
|
|
16
16
|
import {useRootTheme} from '../../theme'
|
|
17
17
|
import {SelectableTone} from '../../types/selectable'
|
|
18
18
|
import {Hotkeys} from '../hotkeys'
|
|
@@ -72,9 +72,11 @@ export const MenuItem = forwardRef(function MenuItem(
|
|
|
72
72
|
activeElement,
|
|
73
73
|
mount,
|
|
74
74
|
onItemClick,
|
|
75
|
-
onItemMouseEnter
|
|
76
|
-
onItemMouseLeave
|
|
75
|
+
onItemMouseEnter: _onItemMouseEnter,
|
|
76
|
+
onItemMouseLeave: _onItemMouseLeave,
|
|
77
77
|
} = menu
|
|
78
|
+
const onItemMouseEnter = _onItemMouseEnter ?? menu.onMouseEnter
|
|
79
|
+
const onItemMouseLeave = _onItemMouseLeave ?? menu.onMouseLeave
|
|
78
80
|
const [rootElement, setRootElement] = useState<HTMLDivElement | null>(null)
|
|
79
81
|
const active = Boolean(activeElement) && activeElement === rootElement
|
|
80
82
|
const ref = useRef<HTMLDivElement | null>(null)
|
|
@@ -105,7 +107,9 @@ export const MenuItem = forwardRef(function MenuItem(
|
|
|
105
107
|
[padding, paddingX, paddingY, paddingTop, paddingRight, paddingBottom, paddingLeft],
|
|
106
108
|
)
|
|
107
109
|
|
|
108
|
-
const hotkeysFontSize =
|
|
110
|
+
const hotkeysFontSize = useMemo(() => _getArrayProp(fontSize).map((s) => s - 1), [fontSize])
|
|
111
|
+
const $radius = useMemo(() => _getArrayProp(radius), [radius])
|
|
112
|
+
const $padding = useMemo(() => _getArrayProp(0), [])
|
|
109
113
|
|
|
110
114
|
const setRef = useCallback((el: HTMLDivElement | null) => {
|
|
111
115
|
ref.current = el
|
|
@@ -121,8 +125,8 @@ export const MenuItem = forwardRef(function MenuItem(
|
|
|
121
125
|
data-selected={active ? '' : undefined}
|
|
122
126
|
data-disabled={disabled ? '' : undefined}
|
|
123
127
|
forwardedAs={as}
|
|
124
|
-
$radius={
|
|
125
|
-
$padding={
|
|
128
|
+
$radius={$radius}
|
|
129
|
+
$padding={$padding}
|
|
126
130
|
$tone={disabled ? 'default' : tone}
|
|
127
131
|
$scheme={scheme}
|
|
128
132
|
disabled={disabled}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {forwardRef, useEffect, useState} from 'react'
|
|
1
|
+
import {forwardRef, useEffect, useMemo, useState} from 'react'
|
|
2
2
|
import {styled} from 'styled-components'
|
|
3
|
-
import {useArrayProp} from '../../hooks'
|
|
4
3
|
import {Box} from '../../primitives'
|
|
5
4
|
import {BoxProps, ResponsiveRadiusProps} from '../../primitives'
|
|
5
|
+
import {_getArrayProp} from '../../styles'
|
|
6
6
|
import {responsiveRadiusStyle, ResponsiveRadiusStyleProps} from '../../styles/internal'
|
|
7
7
|
import {skeletonStyle} from './styles'
|
|
8
8
|
|
|
@@ -45,13 +45,7 @@ export const Skeleton = forwardRef(function Skeleton(
|
|
|
45
45
|
}
|
|
46
46
|
}, [delay])
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
$animated={animated}
|
|
52
|
-
$radius={useArrayProp(radius)}
|
|
53
|
-
$visible={visible}
|
|
54
|
-
ref={ref}
|
|
55
|
-
/>
|
|
56
|
-
)
|
|
48
|
+
const $radius = useMemo(() => _getArrayProp(radius), [radius])
|
|
49
|
+
|
|
50
|
+
return <Root {...restProps} $animated={animated} $radius={$radius} $visible={visible} ref={ref} />
|
|
57
51
|
})
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {ThemeFontKey, getTheme_v2} from '@sanity/ui/theme'
|
|
2
|
-
import {forwardRef} from 'react'
|
|
2
|
+
import {forwardRef, useMemo} from 'react'
|
|
3
3
|
import {styled} from 'styled-components'
|
|
4
|
-
import {
|
|
5
|
-
import {ThemeProps, _responsive} from '../../styles'
|
|
4
|
+
import {ThemeProps, _getArrayProp, _responsive} from '../../styles'
|
|
6
5
|
import {Skeleton, SkeletonProps} from './skeleton'
|
|
7
6
|
|
|
8
7
|
const Root = styled(Skeleton)<{$size: number[]; $style: ThemeFontKey}>((
|
|
@@ -67,7 +66,7 @@ export const TextSkeleton = forwardRef(function TextSkeleton(
|
|
|
67
66
|
ref: React.Ref<HTMLDivElement>,
|
|
68
67
|
) {
|
|
69
68
|
const {size = 2, ...restProps} = props
|
|
70
|
-
const $size =
|
|
69
|
+
const $size = useMemo(() => _getArrayProp(size), [size])
|
|
71
70
|
|
|
72
71
|
return <Root {...restProps} $size={$size} ref={ref} $style="text" />
|
|
73
72
|
})
|
|
@@ -82,7 +81,7 @@ export const LabelSkeleton = forwardRef(function TextSkeleton(
|
|
|
82
81
|
ref: React.Ref<HTMLDivElement>,
|
|
83
82
|
) {
|
|
84
83
|
const {size = 2, ...restProps} = props
|
|
85
|
-
const $size =
|
|
84
|
+
const $size = useMemo(() => _getArrayProp(size), [size])
|
|
86
85
|
|
|
87
86
|
return <Root {...restProps} $size={$size} ref={ref} $style="label" />
|
|
88
87
|
})
|
|
@@ -97,7 +96,7 @@ export const HeadingSkeleton = forwardRef(function TextSkeleton(
|
|
|
97
96
|
ref: React.Ref<HTMLDivElement>,
|
|
98
97
|
) {
|
|
99
98
|
const {size = 2, ...restProps} = props
|
|
100
|
-
const $size =
|
|
99
|
+
const $size = useMemo(() => _getArrayProp(size), [size])
|
|
101
100
|
|
|
102
101
|
return <Root {...restProps} $size={$size} ref={ref} $style="heading" />
|
|
103
102
|
})
|
|
@@ -112,7 +111,7 @@ export const CodeSkeleton = forwardRef(function TextSkeleton(
|
|
|
112
111
|
ref: React.Ref<HTMLDivElement>,
|
|
113
112
|
) {
|
|
114
113
|
const {size = 2, ...restProps} = props
|
|
115
|
-
const $size =
|
|
114
|
+
const $size = useMemo(() => _getArrayProp(size), [size])
|
|
116
115
|
|
|
117
116
|
return <Root {...restProps} $size={$size} ref={ref} $style="code" />
|
|
118
117
|
})
|