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