@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.
- package/dist/_chunks-cjs/_visual-editing.js +1293 -1215
- package/dist/_chunks-cjs/_visual-editing.js.map +1 -1
- package/dist/_chunks-cjs/buildCommand.js +28 -10
- package/dist/_chunks-cjs/buildCommand.js.map +1 -1
- package/dist/_chunks-es/_visual-editing.mjs +1284 -1202
- package/dist/_chunks-es/_visual-editing.mjs.map +1 -1
- package/dist/_visual-editing.d.mts +528 -358
- package/dist/_visual-editing.d.ts +528 -358
- package/dist/cli.js +1 -1
- package/dist/css.d.mts +143 -73
- package/dist/css.d.ts +143 -73
- package/dist/css.js +329 -472
- package/dist/css.js.map +1 -1
- package/dist/css.mjs +330 -473
- package/dist/css.mjs.map +1 -1
- package/dist/index.d.mts +1362 -869
- package/dist/index.d.ts +1362 -869
- package/dist/index.js +383 -308
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +387 -312
- package/dist/index.mjs.map +1 -1
- package/dist/sanity-palette.css +105 -1
- package/dist/sanity-palette.min.css +1 -0
- package/dist/sanity-theme.css +4571 -1
- package/dist/sanity-theme.min.css +1 -0
- package/dist/system.css +22053 -21946
- package/dist/system.min.css +1 -0
- package/dist/theme.d.mts +51 -106
- package/dist/theme.d.ts +51 -106
- package/dist/theme.js +9 -9
- package/dist/theme.js.map +1 -1
- package/dist/theme.mjs +9 -9
- package/dist/theme.mjs.map +1 -1
- package/package.json +10 -5
- package/src/cli/buildCommand.ts +46 -19
- package/src/css/_comp.ts +2 -2
- package/src/css/{compile/compileStyle.ts → _compileStyle.ts} +7 -7
- package/src/css/{system.style.ts → _system.style.ts} +3 -2
- package/src/css/aspects/display/display.ts +1 -0
- package/src/css/aspects/display/types.ts +2 -3
- package/src/css/aspects/flex/types.ts +4 -12
- package/src/css/aspects/flexItem/types.ts +1 -3
- package/src/css/aspects/font/types.ts +1 -3
- package/src/css/aspects/grid/grid.ts +1 -0
- package/src/css/aspects/grid/types.ts +5 -9
- package/src/css/aspects/gridItem/gridItem.ts +1 -1
- package/src/css/aspects/gridItem/types.ts +7 -18
- package/src/css/aspects/height/height.ts +3 -4
- package/src/css/aspects/inset/inset.ts +1 -0
- package/src/css/aspects/margin/margin.ts +1 -0
- package/src/css/aspects/margin/types.ts +1 -0
- package/src/css/aspects/maxWidth/maxWidth.ts +1 -0
- package/src/css/aspects/maxWidth/types.ts +1 -0
- package/src/css/aspects/minWidth/minWidth.ts +1 -0
- package/src/css/aspects/minWidth/types.ts +2 -0
- package/src/css/aspects/overflow/overflow.ts +1 -0
- package/src/css/aspects/padding/padding.ts +1 -0
- package/src/css/aspects/pointerEvents/pointerEvents.ts +1 -0
- package/src/css/aspects/position/position.ts +1 -0
- package/src/css/aspects/shadow/shadow.ts +1 -0
- package/src/css/aspects/textOverflow/textOverflow.ts +1 -0
- package/src/css/aspects/textOverflow/types.ts +1 -0
- package/src/css/aspects/width/types.ts +2 -0
- package/src/css/aspects/width/width.ts +1 -0
- package/src/css/{compile/compilePalette.ts → compilePalette.ts} +14 -10
- package/src/css/compileSystem.ts +7 -0
- package/src/css/{compile/compileTheme.ts → compileTheme.ts} +1 -0
- package/src/css/{compile/compileTheme_v3.ts → compileTheme_v3.ts} +123 -104
- package/src/css/components/breadcrumbs/breadcrumbs.ts +1 -0
- package/src/css/components/dialog/dialog.ts +7 -0
- package/src/css/components/menu/menu.ts +2 -0
- package/src/css/components/skeleton/skeleton.ts +4 -0
- package/src/css/components/skeleton/types.ts +4 -0
- package/src/css/components/toast/toast.ts +5 -0
- package/src/css/components/tree/tree.ts +1 -0
- package/src/css/composeClassNames.ts +4 -2
- package/src/css/constants.ts +2 -0
- package/src/css/index.ts +3 -3
- package/src/css/primitives/_arrow/_arrow.ts +3 -0
- package/src/css/primitives/_input/input.ts +2 -0
- package/src/css/primitives/_selectable/_selectable.style.ts +1 -2
- package/src/css/primitives/_selectable/selectable.ts +1 -2
- package/src/css/primitives/avatar/avatar.style.ts +5 -8
- package/src/css/primitives/avatar/avatar.ts +6 -0
- package/src/css/primitives/avatar/types.ts +1 -0
- package/src/css/primitives/box/types.ts +1 -3
- package/src/css/primitives/button/button.ts +4 -21
- package/src/css/primitives/button/index.ts +1 -0
- package/src/css/primitives/button/types.ts +18 -0
- package/src/css/primitives/card/card.style.ts +3 -6
- package/src/css/primitives/card/card.ts +2 -2
- package/src/css/primitives/card/types.ts +2 -2
- package/src/css/primitives/checkbox/checkbox.ts +2 -0
- package/src/css/primitives/container/container.ts +1 -0
- package/src/css/primitives/container/types.ts +1 -0
- package/src/css/primitives/kbd/kbd.ts +1 -0
- package/src/css/primitives/label/types.ts +7 -2
- package/src/css/primitives/popover/popover.ts +2 -0
- package/src/css/primitives/radio/radio.ts +1 -0
- package/src/css/primitives/select/select.ts +2 -0
- package/src/css/primitives/spinner/spinner.ts +2 -0
- package/src/css/primitives/switch/switch.ts +5 -0
- package/src/css/primitives/text/types.ts +4 -0
- package/src/css/primitives/textArea/textArea.ts +1 -0
- package/src/css/primitives/textInput/textInput.ts +1 -0
- package/src/css/primitives/tooltip/tooltip.ts +2 -0
- package/src/css/scopeClassName.ts +1 -0
- package/src/css/types.ts +9 -12
- package/src/css/util.ts +5 -0
- package/src/css/utils/srOnly/srOnly.ts +3 -1
- package/src/css/varNames.ts +131 -141
- package/src/css/vars.ts +1 -6
- package/src/theme/palette/constants.ts +2 -0
- package/src/theme/palette/types.ts +3 -0
- package/src/theme/types.ts +2 -6
- package/src/theme/v0/focusRing.ts +1 -3
- package/src/theme/v0/font.ts +6 -18
- package/src/theme/v0/layer.ts +1 -3
- package/src/theme/v0/shadow.ts +2 -6
- package/src/theme/v2/avatar.ts +1 -3
- package/src/theme/v2/color/_system.ts +1 -3
- package/src/theme/v2/color/avatar.ts +2 -6
- package/src/theme/v2/color/badge.ts +2 -6
- package/src/theme/v2/color/button.ts +3 -9
- package/src/theme/v2/color/color.ts +3 -9
- package/src/theme/v2/color/input.ts +3 -9
- package/src/theme/v2/color/kbd.ts +1 -3
- package/src/theme/v2/color/selectable.ts +2 -6
- package/src/theme/v2/color/state.ts +1 -3
- package/src/theme/v2/color/syntax.ts +1 -3
- package/src/theme/v2/input.ts +1 -3
- package/src/theme/v2/theme.ts +2 -6
- package/src/theme/v3/buildTheme_v3.ts +1 -0
- package/src/theme/v3/color/color.ts +6 -4
- package/src/theme/v3/color/renderColor.ts +4 -1
- package/src/theme/v3/defaultTokens.ts +1 -0
- package/src/theme/v3/resolveTokens.ts +9 -9
- package/src/ui/RootClassNames.tsx +3 -0
- package/src/ui/StyleTags.tsx +3 -1
- package/src/ui/_compat/theme/themeColorProvider.tsx +2 -6
- package/src/ui/_compat/theme/themeProvider.tsx +2 -6
- package/src/ui/_compat/theme/types.ts +1 -3
- package/src/ui/_compat/theme/useRootTheme.ts +1 -3
- package/src/ui/_compat/theme/useTheme.ts +2 -6
- package/src/ui/components/autocomplete/__workshop__/constrainedHeight.tsx +2 -2
- package/src/ui/components/autocomplete/autocomplete.tsx +86 -114
- package/src/ui/components/autocomplete/autocompleteOption.tsx +2 -0
- package/src/ui/components/autocomplete/types.ts +3 -8
- package/src/ui/components/breadcrumbs/breadcrumbs.tsx +27 -21
- package/src/ui/components/dialog/dialog.tsx +89 -291
- package/src/ui/components/dialog/dialogCard.tsx +183 -0
- package/src/ui/components/dialog/isTargetWithinScope.ts +14 -0
- package/src/ui/components/hotkeys/hotkeys.tsx +33 -15
- package/src/ui/components/menu/__workshop__/asComponent.tsx +6 -6
- package/src/ui/components/menu/menu.tsx +27 -33
- package/src/ui/components/menu/menuButton.tsx +10 -14
- package/src/ui/components/menu/menuDivider.tsx +25 -13
- package/src/ui/components/menu/menuGroup.tsx +34 -26
- package/src/ui/components/menu/menuItem.tsx +51 -40
- package/src/ui/components/skeleton/codeSkeleton.tsx +53 -0
- package/src/ui/components/skeleton/headingSkeleton.tsx +52 -0
- package/src/ui/components/skeleton/index.ts +3 -0
- package/src/ui/components/skeleton/labelSkeleton.tsx +51 -0
- package/src/ui/components/skeleton/skeleton.tsx +39 -16
- package/src/ui/components/skeleton/textSkeleton.tsx +31 -110
- package/src/ui/components/tab/tab.tsx +23 -19
- package/src/ui/components/tab/tabList.tsx +34 -33
- package/src/ui/components/tab/tabPanel.tsx +25 -19
- package/src/ui/components/toast/toast.tsx +21 -16
- package/src/ui/components/toast/toastLayer.tsx +28 -10
- package/src/ui/components/toast/toastProvider.tsx +2 -6
- package/src/ui/components/toast/types.ts +2 -6
- package/src/ui/components/toast/useToast.ts +1 -3
- package/src/ui/components/tree/tree.tsx +194 -187
- package/src/ui/components/tree/treeGroup.tsx +25 -5
- package/src/ui/components/tree/treeItem.tsx +35 -23
- package/src/ui/hooks/useClickOutside.ts +2 -6
- package/src/ui/hooks/useClickOutsideEvent.ts +3 -9
- package/src/ui/primitives/_selectable/selectable.tsx +33 -20
- package/src/ui/primitives/avatar/avatar.tsx +28 -31
- package/src/ui/primitives/avatar/avatarCounter.tsx +33 -25
- package/src/ui/primitives/avatar/avatarStack.tsx +31 -24
- package/src/ui/primitives/avatar/types.ts +2 -0
- package/src/ui/primitives/badge/__workshop__/props.tsx +1 -9
- package/src/ui/primitives/badge/__workshop__/tones.tsx +1 -6
- package/src/ui/primitives/badge/badge.tsx +33 -32
- package/src/ui/primitives/badge/types.ts +2 -1
- package/src/ui/primitives/box/box.tsx +59 -29
- package/src/ui/primitives/button/__workshop__/sanityUploadButton.tsx +3 -3
- package/src/ui/primitives/button/__workshop__/uploadButton.tsx +2 -1
- package/src/ui/primitives/button/button.test.tsx +1 -15
- package/src/ui/primitives/button/button.tsx +64 -70
- package/src/ui/primitives/card/__workshop__/asComponent.tsx +3 -3
- package/src/ui/primitives/card/card.tsx +22 -22
- package/src/ui/primitives/card/cardProvider.tsx +2 -0
- package/src/ui/primitives/checkbox/checkbox.tsx +26 -15
- package/src/ui/primitives/code/code.tsx +24 -22
- package/src/ui/primitives/container/container.tsx +26 -15
- package/src/ui/primitives/flex/flex.tsx +21 -19
- package/src/ui/primitives/grid/grid.tsx +21 -16
- package/src/ui/primitives/heading/heading.tsx +42 -19
- package/src/ui/primitives/inline/inline.tsx +26 -23
- package/src/ui/primitives/kbd/kbd.tsx +25 -23
- package/src/ui/primitives/label/label.tsx +41 -26
- package/src/ui/primitives/popover/popover.tsx +281 -277
- package/src/ui/primitives/popover/popoverCard.tsx +119 -118
- package/src/ui/primitives/radio/radio.tsx +30 -14
- package/src/ui/primitives/select/select.tsx +24 -16
- package/src/ui/primitives/spinner/animatedSpinnerIcon.tsx +4 -2
- package/src/ui/primitives/spinner/spinner.tsx +24 -12
- package/src/ui/primitives/stack/stack.tsx +27 -18
- package/src/ui/primitives/switch/switch.tsx +31 -14
- package/src/ui/primitives/text/text.tsx +42 -24
- package/src/ui/primitives/textArea/textArea.tsx +33 -18
- package/src/ui/primitives/textInput/textInput.tsx +28 -40
- package/src/ui/primitives/tooltip/constants.ts +1 -1
- package/src/ui/primitives/tooltip/tooltip.tsx +76 -59
- package/src/ui/primitives/tooltip/tooltipCard.tsx +89 -82
- package/src/ui/primitives/types.ts +1 -3
- package/src/ui/types/avatar.ts +3 -6
- package/src/ui/types/badge.ts +1 -3
- package/src/ui/types/button.ts +1 -3
- package/src/ui/types/card.ts +1 -3
- package/src/ui/types/dialog.ts +1 -3
- package/src/ui/types/props.ts +20 -10
- package/src/ui/utils/arrow/arrow.tsx +40 -14
- package/src/ui/utils/boundaryElement/boundaryElementProvider.tsx +2 -6
- package/src/ui/utils/boundaryElement/types.ts +1 -3
- package/src/ui/utils/boundaryElement/useBoundaryElement.ts +1 -3
- package/src/ui/utils/elementQuery/elementQuery.tsx +36 -14
- package/src/ui/utils/errorBoundary.tsx +2 -0
- package/src/ui/utils/index.ts +0 -1
- package/src/ui/utils/layer/layer.tsx +23 -93
- package/src/ui/utils/layer/layerCard.tsx +92 -0
- package/src/ui/utils/layer/layerProvider.tsx +2 -6
- package/src/ui/utils/layer/useLayer.ts +1 -3
- package/src/ui/utils/portal/portal.ts +2 -6
- package/src/ui/utils/portal/portalProvider.tsx +2 -6
- package/src/ui/utils/portal/types.ts +1 -3
- package/src/ui/utils/portal/usePortal.ts +1 -3
- package/src/ui/utils/srOnly/srOnly.tsx +25 -20
- package/src/ui/utils/virtualList/virtualList.tsx +36 -24
- package/src/css/compile/compileRule.ts +0 -97
- package/src/css/compile/compileRules.test.ts +0 -36
- package/src/css/compile/compileRules.ts +0 -43
- package/src/css/compile/compileSystem.ts +0 -7
- package/src/css/compile/types.ts +0 -6
- package/src/css/primitives/_selectable/_contants.ts +0 -11
- package/src/css/primitives/card/_constants.ts +0 -13
- package/src/ui/utils/conditionalWrapper/conditionalWrapper.tsx +0 -23
- package/src/ui/utils/conditionalWrapper/index.ts +0 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import {CloseIcon} from '@sanity/icons'
|
|
2
|
+
import {
|
|
3
|
+
dialogCardRoot,
|
|
4
|
+
dialogContent,
|
|
5
|
+
dialogFooter,
|
|
6
|
+
dialogHeader,
|
|
7
|
+
dialogLayout,
|
|
8
|
+
} from '@sanity/ui/css'
|
|
9
|
+
import {ForwardedRef, ReactNode, useCallback, useEffect, useImperativeHandle, useRef} from 'react'
|
|
10
|
+
|
|
11
|
+
import {focusFirstDescendant} from '../../helpers'
|
|
12
|
+
import {useClickOutsideEvent, useGlobalKeyDown} from '../../hooks'
|
|
13
|
+
import {Box, Button, Card, CardElementType, CardOwnProps, Flex, Text} from '../../primitives'
|
|
14
|
+
import {Props} from '../../types'
|
|
15
|
+
import {useBoundaryElement, useLayer, usePortal} from '../../utils'
|
|
16
|
+
import {isTargetWithinScope} from './isTargetWithinScope'
|
|
17
|
+
|
|
18
|
+
/** @internal */
|
|
19
|
+
export const DEFAULT_DIALOG_CARD_ELEMENT = 'div'
|
|
20
|
+
|
|
21
|
+
/** @internal */
|
|
22
|
+
export type DialogCardOwnProps = CardOwnProps & {
|
|
23
|
+
/**
|
|
24
|
+
* @beta
|
|
25
|
+
*/
|
|
26
|
+
__unstable_autoFocus: boolean
|
|
27
|
+
/**
|
|
28
|
+
* @beta
|
|
29
|
+
*/
|
|
30
|
+
__unstable_hideCloseButton: boolean
|
|
31
|
+
children: ReactNode
|
|
32
|
+
contentRef?: ForwardedRef<HTMLDivElement>
|
|
33
|
+
footer: ReactNode
|
|
34
|
+
header: ReactNode
|
|
35
|
+
id: string
|
|
36
|
+
onClickOutside?: () => void
|
|
37
|
+
onClose?: () => void
|
|
38
|
+
portal?: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** @internal */
|
|
42
|
+
export type DialogCardElementType = CardElementType
|
|
43
|
+
|
|
44
|
+
/** @internal */
|
|
45
|
+
export type DialogCardProps<E extends DialogCardElementType = DialogCardElementType> = Props<
|
|
46
|
+
DialogCardOwnProps,
|
|
47
|
+
E
|
|
48
|
+
>
|
|
49
|
+
|
|
50
|
+
/** @internal */
|
|
51
|
+
|
|
52
|
+
export function DialogCard<E extends DialogCardElementType = typeof DEFAULT_DIALOG_CARD_ELEMENT>(
|
|
53
|
+
props: DialogCardProps<E>,
|
|
54
|
+
) {
|
|
55
|
+
const {
|
|
56
|
+
__unstable_autoFocus: autoFocus,
|
|
57
|
+
__unstable_hideCloseButton: hideCloseButton,
|
|
58
|
+
as = DEFAULT_DIALOG_CARD_ELEMENT,
|
|
59
|
+
children,
|
|
60
|
+
contentRef: forwardedContentRef,
|
|
61
|
+
footer,
|
|
62
|
+
header,
|
|
63
|
+
id,
|
|
64
|
+
onClickOutside,
|
|
65
|
+
onClose,
|
|
66
|
+
portal: portalProp,
|
|
67
|
+
ref: forwardedRef,
|
|
68
|
+
...rest
|
|
69
|
+
} = props as DialogCardProps<typeof DEFAULT_DIALOG_CARD_ELEMENT>
|
|
70
|
+
|
|
71
|
+
const portal = usePortal()
|
|
72
|
+
const portalElement = portalProp ? portal.elements?.[portalProp] || null : portal.element
|
|
73
|
+
const boundaryElement = useBoundaryElement().element
|
|
74
|
+
const ref = useRef<HTMLDivElement | null>(null)
|
|
75
|
+
const contentRef = useRef<HTMLDivElement | null>(null)
|
|
76
|
+
const layer = useLayer()
|
|
77
|
+
const {isTopLayer} = layer
|
|
78
|
+
const labelId = `${id}_label`
|
|
79
|
+
const showCloseButton = Boolean(onClose) && hideCloseButton === false
|
|
80
|
+
const showHeader = Boolean(header) || showCloseButton
|
|
81
|
+
|
|
82
|
+
useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(forwardedRef, () => ref.current)
|
|
83
|
+
useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(
|
|
84
|
+
forwardedContentRef,
|
|
85
|
+
() => contentRef.current,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (!autoFocus) return
|
|
90
|
+
|
|
91
|
+
// On mount: focus the first focusable element
|
|
92
|
+
if (ref.current) {
|
|
93
|
+
focusFirstDescendant(ref.current)
|
|
94
|
+
}
|
|
95
|
+
}, [autoFocus, ref])
|
|
96
|
+
|
|
97
|
+
useGlobalKeyDown(
|
|
98
|
+
useCallback(
|
|
99
|
+
(event: KeyboardEvent) => {
|
|
100
|
+
if (!isTopLayer || !onClose) return
|
|
101
|
+
|
|
102
|
+
const target = document.activeElement
|
|
103
|
+
|
|
104
|
+
if (target && !isTargetWithinScope(boundaryElement, portalElement, target)) {
|
|
105
|
+
// Ignore key presses when the focused element is outside of scope
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (event.key === 'Escape') {
|
|
110
|
+
event.preventDefault()
|
|
111
|
+
event.stopPropagation()
|
|
112
|
+
onClose()
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
[boundaryElement, isTopLayer, onClose, portalElement],
|
|
116
|
+
),
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
useClickOutsideEvent(
|
|
120
|
+
isTopLayer &&
|
|
121
|
+
onClickOutside &&
|
|
122
|
+
((event) => {
|
|
123
|
+
const target = event.target as Node | null
|
|
124
|
+
|
|
125
|
+
if (target && !isTargetWithinScope(boundaryElement, portalElement, target)) {
|
|
126
|
+
// Ignore clicks outside of the scope
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
onClickOutside()
|
|
131
|
+
}),
|
|
132
|
+
() => [ref.current],
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<Card {...rest} as={as} className={dialogCardRoot()} display="flex" ref={ref}>
|
|
137
|
+
<Flex className={dialogLayout()} direction="column" flex={1}>
|
|
138
|
+
{showHeader && (
|
|
139
|
+
<Box className={dialogHeader()} position="relative">
|
|
140
|
+
<Flex align="flex-start" padding={3}>
|
|
141
|
+
<Box flex={1} padding={2}>
|
|
142
|
+
{header && (
|
|
143
|
+
<Text id={labelId} size={1} weight="semibold">
|
|
144
|
+
{header}
|
|
145
|
+
</Text>
|
|
146
|
+
)}
|
|
147
|
+
</Box>
|
|
148
|
+
{showCloseButton && (
|
|
149
|
+
<Box flex="none">
|
|
150
|
+
<Button
|
|
151
|
+
aria-label="Close dialog"
|
|
152
|
+
disabled={!onClose}
|
|
153
|
+
icon={CloseIcon}
|
|
154
|
+
mode="bleed"
|
|
155
|
+
onClick={onClose}
|
|
156
|
+
padding={2}
|
|
157
|
+
/>
|
|
158
|
+
</Box>
|
|
159
|
+
)}
|
|
160
|
+
</Flex>
|
|
161
|
+
</Box>
|
|
162
|
+
)}
|
|
163
|
+
<Box
|
|
164
|
+
className={dialogContent()}
|
|
165
|
+
flex={1}
|
|
166
|
+
overflow="auto"
|
|
167
|
+
position="relative"
|
|
168
|
+
ref={contentRef}
|
|
169
|
+
tabIndex={-1}
|
|
170
|
+
>
|
|
171
|
+
{children}
|
|
172
|
+
</Box>
|
|
173
|
+
{footer && (
|
|
174
|
+
<Box className={dialogFooter()} position="relative">
|
|
175
|
+
{footer}
|
|
176
|
+
</Box>
|
|
177
|
+
)}
|
|
178
|
+
</Flex>
|
|
179
|
+
</Card>
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
DialogCard.displayName = 'DialogCard'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {containsOrEqualsElement} from '../../helpers'
|
|
2
|
+
|
|
3
|
+
export function isTargetWithinScope(
|
|
4
|
+
boundaryElement: HTMLElement | null,
|
|
5
|
+
portalElement: HTMLElement | null,
|
|
6
|
+
target: Node,
|
|
7
|
+
): boolean {
|
|
8
|
+
if (!boundaryElement || !portalElement) return true
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
containsOrEqualsElement(boundaryElement, target) ||
|
|
12
|
+
containsOrEqualsElement(portalElement, target)
|
|
13
|
+
)
|
|
14
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {GapStyleProps, RadiusStyleProps, ResponsiveProp} from '@sanity/ui/css'
|
|
2
2
|
import {FontTextSize, Space} from '@sanity/ui/theme'
|
|
3
|
-
import {ForwardedRef, forwardRef} from 'react'
|
|
4
3
|
|
|
5
4
|
import {Box, KBD} from '../../primitives'
|
|
6
|
-
import {Props} from '../../types'
|
|
5
|
+
import {ComponentType, Props} from '../../types'
|
|
7
6
|
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
/** @public */
|
|
8
|
+
export const DEFAULT_HOTKEYS_ELEMENT = 'kbd'
|
|
9
|
+
|
|
10
|
+
/** @public */
|
|
11
|
+
export interface HotkeysOwnProps extends GapStyleProps, RadiusStyleProps {
|
|
12
12
|
fontSize?: ResponsiveProp<FontTextSize>
|
|
13
13
|
padding?: ResponsiveProp<Space>
|
|
14
14
|
/** @deprecated Use `gap` instead. */
|
|
@@ -16,16 +16,35 @@ export interface HotkeysProps extends GapStyleProps, RadiusStyleProps {
|
|
|
16
16
|
keys?: string[]
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/** @public */
|
|
20
|
+
export type HotkeysElementType = 'kbd' | ComponentType
|
|
21
|
+
|
|
22
|
+
/** @public */
|
|
23
|
+
export type HotkeysProps<E extends HotkeysElementType = HotkeysElementType> = Props<
|
|
24
|
+
HotkeysOwnProps,
|
|
25
|
+
E
|
|
26
|
+
>
|
|
27
|
+
|
|
19
28
|
/**
|
|
20
29
|
* Represent hotkeys (a keyboard combination) with semantic `<kbd>` elements.
|
|
21
30
|
*
|
|
22
31
|
* @public
|
|
23
32
|
*/
|
|
24
|
-
export
|
|
25
|
-
props:
|
|
26
|
-
ref: ForwardedRef<HTMLDivElement>,
|
|
33
|
+
export function Hotkeys<E extends HotkeysElementType = typeof DEFAULT_HOTKEYS_ELEMENT>(
|
|
34
|
+
props: HotkeysProps<E>,
|
|
27
35
|
) {
|
|
28
|
-
const {
|
|
36
|
+
const {
|
|
37
|
+
as = DEFAULT_HOTKEYS_ELEMENT,
|
|
38
|
+
fontSize,
|
|
39
|
+
gap,
|
|
40
|
+
gapX,
|
|
41
|
+
gapY,
|
|
42
|
+
keys,
|
|
43
|
+
padding,
|
|
44
|
+
radius,
|
|
45
|
+
space = 0.5,
|
|
46
|
+
...rest
|
|
47
|
+
} = props as HotkeysProps<typeof DEFAULT_HOTKEYS_ELEMENT>
|
|
29
48
|
|
|
30
49
|
if (!keys || keys.length === 0) {
|
|
31
50
|
return undefined
|
|
@@ -33,14 +52,13 @@ export const Hotkeys = forwardRef(function Hotkeys(
|
|
|
33
52
|
|
|
34
53
|
return (
|
|
35
54
|
<Box
|
|
36
|
-
as=
|
|
55
|
+
as={as}
|
|
37
56
|
data-ui="Hotkeys"
|
|
38
|
-
{...
|
|
57
|
+
{...rest}
|
|
39
58
|
display="flex"
|
|
40
59
|
gap={gap ?? space}
|
|
41
60
|
gapX={gapX}
|
|
42
61
|
gapY={gapY}
|
|
43
|
-
ref={ref}
|
|
44
62
|
>
|
|
45
63
|
{keys.map((key, i) => (
|
|
46
64
|
<KBD fontSize={fontSize} key={i} padding={padding} radius={radius}>
|
|
@@ -49,6 +67,6 @@ export const Hotkeys = forwardRef(function Hotkeys(
|
|
|
49
67
|
))}
|
|
50
68
|
</Box>
|
|
51
69
|
)
|
|
52
|
-
}
|
|
70
|
+
}
|
|
53
71
|
|
|
54
|
-
Hotkeys.displayName = '
|
|
72
|
+
Hotkeys.displayName = 'Hotkeys'
|
|
@@ -5,11 +5,11 @@ 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, ...
|
|
8
|
+
const {children, req, ...rest} = props
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
11
|
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
|
12
|
-
<a data-required={req} {...
|
|
12
|
+
<a data-required={req} {...rest} href="#" ref={ref}>
|
|
13
13
|
{children}
|
|
14
14
|
</a>
|
|
15
15
|
)
|
|
@@ -25,16 +25,16 @@ export default function AsComponentStory() {
|
|
|
25
25
|
id="test"
|
|
26
26
|
menu={
|
|
27
27
|
<Menu>
|
|
28
|
-
<MenuItem as={CustomLink} data-as="a" {...props} padding={3}>
|
|
28
|
+
<MenuItem as={CustomLink} data-as="a" {...props} padding={3} req="1">
|
|
29
29
|
<Text>Component 1</Text>
|
|
30
30
|
</MenuItem>
|
|
31
|
-
<MenuItem as={CustomLink} data-as="a" {...props} padding={3}>
|
|
31
|
+
<MenuItem as={CustomLink} data-as="a" {...props} padding={3} req="2">
|
|
32
32
|
<Text>Component 2</Text>
|
|
33
33
|
</MenuItem>
|
|
34
|
-
<MenuItem as={CustomLink} data-as="a" {...props} padding={3}>
|
|
34
|
+
<MenuItem as={CustomLink} data-as="a" {...props} padding={3} req="3">
|
|
35
35
|
<Text>Component 3</Text>
|
|
36
36
|
</MenuItem>
|
|
37
|
-
<MenuItem as={CustomLink} data-as="a" {...props} padding={3}>
|
|
37
|
+
<MenuItem as={CustomLink} data-as="a" {...props} padding={3} req="4">
|
|
38
38
|
<Text>Component 3</Text>
|
|
39
39
|
</MenuItem>
|
|
40
40
|
</Menu>
|
|
@@ -1,32 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
menu,
|
|
5
|
-
PaddingStyleProps,
|
|
6
|
-
ResponsiveProp,
|
|
7
|
-
} from '@sanity/ui/css'
|
|
8
|
-
import {Space} from '@sanity/ui/theme'
|
|
9
|
-
import {
|
|
10
|
-
ForwardedRef,
|
|
11
|
-
forwardRef,
|
|
12
|
-
useCallback,
|
|
13
|
-
useEffect,
|
|
14
|
-
useImperativeHandle,
|
|
15
|
-
useMemo,
|
|
16
|
-
useRef,
|
|
17
|
-
} from 'react'
|
|
1
|
+
import {composeClassNames, menu, type PaddingStyleProps, type ResponsiveProp} from '@sanity/ui/css'
|
|
2
|
+
import type {Space} from '@sanity/ui/theme'
|
|
3
|
+
import {useCallback, useEffect, useImperativeHandle, useMemo, useRef} from 'react'
|
|
18
4
|
|
|
19
5
|
import {useClickOutsideEvent, useGlobalKeyDown} from '../../hooks'
|
|
20
6
|
import {Box, Stack} from '../../primitives'
|
|
21
|
-
import {Props} from '../../types'
|
|
7
|
+
import type {ComponentType, Props} from '../../types'
|
|
22
8
|
import {useLayer} from '../../utils'
|
|
23
|
-
import {MenuContext, MenuContextValue} from './menuContext'
|
|
9
|
+
import {MenuContext, type MenuContextValue} from './menuContext'
|
|
24
10
|
import {useMenuController} from './useMenuController'
|
|
25
11
|
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
12
|
+
/** @public */
|
|
13
|
+
export const DEFAULT_MENU_ELEMENT = 'div'
|
|
14
|
+
|
|
15
|
+
/** @public */
|
|
16
|
+
export type MenuOwnProps = PaddingStyleProps & {
|
|
30
17
|
/**
|
|
31
18
|
* @deprecated Use `shouldFocus="first"` instead.
|
|
32
19
|
*/
|
|
@@ -35,6 +22,7 @@ export interface MenuProps extends PaddingStyleProps, Pick<GapStyleProps, 'gap'>
|
|
|
35
22
|
* @deprecated Use `shouldFocus="last"` instead.
|
|
36
23
|
*/
|
|
37
24
|
'focusLast'?: boolean
|
|
25
|
+
'gap'?: ResponsiveProp<Space>
|
|
38
26
|
'onClickOutside'?: (event: MouseEvent) => void
|
|
39
27
|
'onEscape'?: () => void
|
|
40
28
|
'onItemClick'?: () => void
|
|
@@ -48,16 +36,20 @@ export interface MenuProps extends PaddingStyleProps, Pick<GapStyleProps, 'gap'>
|
|
|
48
36
|
// 'onBlurCapture'?: (event: FocusEvent) => void
|
|
49
37
|
}
|
|
50
38
|
|
|
39
|
+
/** @public */
|
|
40
|
+
export type MenuElementType = 'div' | 'span' | ComponentType
|
|
41
|
+
|
|
42
|
+
/** @public */
|
|
43
|
+
export type MenuProps<E extends MenuElementType = MenuElementType> = Props<MenuOwnProps, E>
|
|
44
|
+
|
|
51
45
|
/**
|
|
52
46
|
* The `Menu` component is a building block for application menus.
|
|
53
47
|
*
|
|
54
48
|
* @public
|
|
55
49
|
*/
|
|
56
|
-
export
|
|
57
|
-
props: Props<MenuProps, 'div'>,
|
|
58
|
-
forwardedRef: ForwardedRef<HTMLDivElement>,
|
|
59
|
-
) {
|
|
50
|
+
export function Menu<E extends MenuElementType = typeof DEFAULT_MENU_ELEMENT>(props: MenuProps<E>) {
|
|
60
51
|
const {
|
|
52
|
+
as = DEFAULT_MENU_ELEMENT,
|
|
61
53
|
children,
|
|
62
54
|
className,
|
|
63
55
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -65,7 +57,6 @@ export const Menu = forwardRef(function Menu(
|
|
|
65
57
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
66
58
|
focusLast,
|
|
67
59
|
gap,
|
|
68
|
-
// onBlurCapture,
|
|
69
60
|
onClickOutside,
|
|
70
61
|
onEscape,
|
|
71
62
|
onItemClick,
|
|
@@ -73,11 +64,13 @@ export const Menu = forwardRef(function Menu(
|
|
|
73
64
|
onKeyDown,
|
|
74
65
|
originElement,
|
|
75
66
|
padding = 1,
|
|
67
|
+
ref: forwardedRef,
|
|
76
68
|
registerElement,
|
|
77
69
|
shouldFocus: _shouldFocus,
|
|
78
70
|
space = 1,
|
|
79
|
-
...
|
|
80
|
-
} = props
|
|
71
|
+
...rest
|
|
72
|
+
} = props as MenuProps<typeof DEFAULT_MENU_ELEMENT>
|
|
73
|
+
|
|
81
74
|
const shouldFocus =
|
|
82
75
|
_shouldFocus ?? ((props.focusFirst && 'first') || (props.focusLast && 'last') || null)
|
|
83
76
|
|
|
@@ -181,7 +174,8 @@ export const Menu = forwardRef(function Menu(
|
|
|
181
174
|
<MenuContext.Provider value={value}>
|
|
182
175
|
<Box
|
|
183
176
|
data-ui="Menu"
|
|
184
|
-
{...
|
|
177
|
+
{...rest}
|
|
178
|
+
as={as}
|
|
185
179
|
className={composeClassNames(className, menu())}
|
|
186
180
|
onKeyDown={handleKeyDown}
|
|
187
181
|
overflow="auto"
|
|
@@ -195,6 +189,6 @@ export const Menu = forwardRef(function Menu(
|
|
|
195
189
|
</Box>
|
|
196
190
|
</MenuContext.Provider>
|
|
197
191
|
)
|
|
198
|
-
}
|
|
192
|
+
}
|
|
199
193
|
|
|
200
|
-
Menu.displayName = '
|
|
194
|
+
Menu.displayName = 'Menu'
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
cloneElement,
|
|
4
4
|
FocusEvent,
|
|
5
5
|
ForwardedRef,
|
|
6
|
-
forwardRef,
|
|
7
6
|
KeyboardEvent,
|
|
8
7
|
MouseEvent as ReactMouseEvent,
|
|
9
8
|
ReactElement,
|
|
@@ -19,10 +18,8 @@ import {ButtonProps, Popover, PopoverProps} from '../../primitives'
|
|
|
19
18
|
import {Placement, Props, Radius} from '../../types'
|
|
20
19
|
import {MenuProps} from './menu'
|
|
21
20
|
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
*/
|
|
25
|
-
export interface MenuButtonProps {
|
|
21
|
+
/** @public */
|
|
22
|
+
export type MenuButtonProps = {
|
|
26
23
|
/**
|
|
27
24
|
* @beta Do not use in production.
|
|
28
25
|
*/
|
|
@@ -31,7 +28,7 @@ export interface MenuButtonProps {
|
|
|
31
28
|
* @deprecated Use `popover={{boundaryElement: element}}` instead.
|
|
32
29
|
*/
|
|
33
30
|
boundaryElement?: HTMLElement
|
|
34
|
-
button: ReactElement<
|
|
31
|
+
button: ReactElement<ButtonProps>
|
|
35
32
|
id: string
|
|
36
33
|
menu?: ReactElement
|
|
37
34
|
onClose?: () => void
|
|
@@ -58,6 +55,7 @@ export interface MenuButtonProps {
|
|
|
58
55
|
* @deprecated Use `popover={{preventOverflow: true}}` instead.
|
|
59
56
|
*/
|
|
60
57
|
preventOverflow?: boolean
|
|
58
|
+
ref?: ForwardedRef<HTMLButtonElement | null>
|
|
61
59
|
}
|
|
62
60
|
|
|
63
61
|
/**
|
|
@@ -65,10 +63,7 @@ export interface MenuButtonProps {
|
|
|
65
63
|
*
|
|
66
64
|
* @public
|
|
67
65
|
*/
|
|
68
|
-
export
|
|
69
|
-
props: MenuButtonProps,
|
|
70
|
-
forwardedRef: ForwardedRef<HTMLButtonElement | null>,
|
|
71
|
-
) {
|
|
66
|
+
export function MenuButton(props: MenuButtonProps) {
|
|
72
67
|
const {
|
|
73
68
|
__unstable_disableRestoreFocusOnClose: disableRestoreFocusOnClose = false,
|
|
74
69
|
boundaryElement: deprecated_boundaryElement,
|
|
@@ -83,6 +78,7 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
83
78
|
popover,
|
|
84
79
|
popoverRadius: deprecated_popoverRadius,
|
|
85
80
|
preventOverflow: deprecated_preventOverflow,
|
|
81
|
+
ref: forwardedRef,
|
|
86
82
|
} = props
|
|
87
83
|
const [open, setOpen] = useState(false)
|
|
88
84
|
const [shouldFocus, setShouldFocus] = useState<'first' | 'last' | null>(null)
|
|
@@ -221,7 +217,7 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
221
217
|
const button = useMemo(() => {
|
|
222
218
|
if (!buttonProp) return null
|
|
223
219
|
|
|
224
|
-
const buttonProps = {
|
|
220
|
+
const buttonProps: ButtonProps<'button'> = {
|
|
225
221
|
'data-ui': 'MenuButton',
|
|
226
222
|
id,
|
|
227
223
|
'onClick': handleButtonClick,
|
|
@@ -231,7 +227,7 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
231
227
|
'aria-expanded': open,
|
|
232
228
|
'ref': setButtonElement,
|
|
233
229
|
'selected': buttonProp.props.selected ?? open,
|
|
234
|
-
}
|
|
230
|
+
}
|
|
235
231
|
|
|
236
232
|
return cloneElement(buttonProp, buttonProps)
|
|
237
233
|
}, [buttonProp, handleButtonClick, handleButtonKeyDown, handleMouseDown, id, open])
|
|
@@ -270,6 +266,6 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
270
266
|
{button || <></>}
|
|
271
267
|
</Popover>
|
|
272
268
|
)
|
|
273
|
-
}
|
|
269
|
+
}
|
|
274
270
|
|
|
275
|
-
MenuButton.displayName = '
|
|
271
|
+
MenuButton.displayName = 'MenuButton'
|
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
import {composeClassNames, menuDivider} from '@sanity/ui/css'
|
|
2
|
-
import {ForwardedRef, forwardRef} from 'react'
|
|
3
2
|
|
|
4
|
-
import {Props} from '../../types'
|
|
3
|
+
import {ComponentType, Props} from '../../types'
|
|
4
|
+
|
|
5
|
+
/** @public */
|
|
6
|
+
export const DEFAULT_MENU_DIVIDER_ELEMENT = 'hr'
|
|
5
7
|
|
|
6
8
|
/** @public */
|
|
7
9
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
export type MenuDividerOwnProps = {}
|
|
11
|
+
|
|
12
|
+
/** @public */
|
|
13
|
+
export type MenuDividerElementType = 'div' | 'hr' | 'span' | ComponentType
|
|
14
|
+
|
|
15
|
+
/** @public */
|
|
16
|
+
export type MenuDividerProps<E extends MenuDividerElementType = MenuDividerElementType> = Props<
|
|
17
|
+
MenuDividerOwnProps,
|
|
18
|
+
E
|
|
19
|
+
>
|
|
20
|
+
|
|
21
|
+
/** @public */
|
|
22
|
+
export function MenuDivider<E extends MenuDividerElementType = typeof DEFAULT_MENU_DIVIDER_ELEMENT>(
|
|
23
|
+
props: MenuDividerProps<E>,
|
|
16
24
|
) {
|
|
17
|
-
const {
|
|
25
|
+
const {
|
|
26
|
+
as: Element = DEFAULT_MENU_DIVIDER_ELEMENT,
|
|
27
|
+
className,
|
|
28
|
+
...rest
|
|
29
|
+
} = props as MenuDividerProps<typeof DEFAULT_MENU_DIVIDER_ELEMENT>
|
|
18
30
|
|
|
19
|
-
return <
|
|
20
|
-
}
|
|
31
|
+
return <Element {...rest} className={composeClassNames(className, menuDivider())} />
|
|
32
|
+
}
|
|
21
33
|
|
|
22
34
|
MenuDivider.displayName = 'MenuDivider'
|