@sanity/ui 4.2.0 → 5.0.0-alpha.10
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/README.md +194 -28
- package/bin/sanity-ui.js +14 -0
- package/dist/_chunks-es/LazyRefractor.js +20 -0
- package/dist/_chunks-es/LazyRefractor.js.map +1 -0
- package/dist/cli/checks.js +148 -0
- package/dist/cli/config.js +23 -0
- package/dist/cli/detect.js +181 -0
- package/dist/cli/doctor.js +49 -0
- package/dist/cli/index.js +69 -0
- package/dist/cli/init.js +189 -0
- package/dist/cli/install.js +79 -0
- package/dist/cli/log.js +66 -0
- package/dist/cli/selfPackage.js +11 -0
- package/dist/cli/styles.js +185 -0
- package/dist/cli/test-utils.js +8 -0
- package/dist/cli/tsconfig.js +236 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/versions.js +45 -0
- package/dist/index.d.ts +1203 -1469
- package/dist/index.js +2123 -1989
- package/dist/index.js.map +1 -1
- package/dist/polyfills.d.ts +1 -0
- package/dist/polyfills.js +5 -0
- package/dist/polyfills.js.map +1 -0
- package/dist/styles.css +1 -547
- package/package.json +57 -58
- package/src/cli/checks.test.ts +38 -0
- package/src/cli/checks.ts +200 -0
- package/src/cli/config.ts +44 -0
- package/src/cli/detect.test.ts +191 -0
- package/src/cli/detect.ts +205 -0
- package/src/cli/doctor.test.ts +52 -0
- package/src/cli/doctor.ts +65 -0
- package/src/cli/index.ts +77 -0
- package/src/cli/init.ts +225 -0
- package/src/cli/install.test.ts +52 -0
- package/src/cli/install.ts +108 -0
- package/src/cli/log.ts +79 -0
- package/src/cli/selfPackage.ts +14 -0
- package/src/cli/styles.test.ts +130 -0
- package/src/cli/styles.ts +205 -0
- package/src/cli/test-utils.ts +10 -0
- package/src/cli/tsconfig.test.ts +174 -0
- package/src/cli/tsconfig.ts +282 -0
- package/src/cli/types.ts +77 -0
- package/src/cli/versions.test.ts +35 -0
- package/src/cli/versions.ts +41 -0
- package/src/components/badge/Badge.tsx +53 -0
- package/src/components/badge/badge.css +6 -0
- package/src/components/badge/badge.props.ts +31 -0
- package/src/components/box/Box.tsx +30 -0
- package/src/components/box/box.css +4 -0
- package/src/components/box/box.props.ts +29 -0
- package/src/components/button/Button.tsx +78 -0
- package/src/components/button/button.css +72 -0
- package/src/components/button/button.props.ts +122 -0
- package/src/components/card/Card.tsx +31 -0
- package/src/components/card/card.css +4 -0
- package/src/components/card/card.props.ts +58 -0
- package/src/components/checkbox/Checkbox.tsx +64 -0
- package/src/components/checkbox/checkbox.css +100 -0
- package/src/components/checkbox/checkbox.props.ts +33 -0
- package/src/components/code/Code.tsx +38 -0
- package/src/components/code/LazyRefractor.tsx +9 -0
- package/src/components/code/code.css +40 -0
- package/src/components/code/code.props.ts +44 -0
- package/src/components/container/Container.tsx +30 -0
- package/src/components/container/container.css +4 -0
- package/src/components/container/container.props.ts +28 -0
- package/src/components/dialog/Dialog.tsx +139 -0
- package/src/components/dialog/dialog.css +49 -0
- package/src/components/dialog/dialog.props.ts +45 -0
- package/src/components/divider/Divider.tsx +23 -0
- package/src/components/divider/divider.props.ts +9 -0
- package/src/components/eyebrow/Eyebrow.tsx +54 -0
- package/src/components/eyebrow/eyebrow.css +11 -0
- package/src/components/eyebrow/eyebrow.props.ts +28 -0
- package/src/components/flex/Flex.tsx +30 -0
- package/src/components/flex/flex.css +4 -0
- package/src/components/flex/flex.props.ts +33 -0
- package/src/components/grid/Grid.tsx +30 -0
- package/src/components/grid/grid.css +4 -0
- package/src/components/grid/grid.props.ts +33 -0
- package/src/components/h-stack/HStack.tsx +34 -0
- package/src/components/h-stack/hStack.props.ts +17 -0
- package/src/components/heading/Heading.tsx +54 -0
- package/src/components/heading/heading.css +9 -0
- package/src/components/heading/heading.props.ts +31 -0
- package/src/components/icon/Icon.tsx +24 -0
- package/src/components/icon/icon.css +17 -0
- package/src/components/icon/icon.props.ts +35 -0
- package/src/components/icon-button/IconButton.tsx +32 -0
- package/src/components/icon-button/iconButton.props.ts +31 -0
- package/src/components/index.css +28 -0
- package/src/components/indicator/Indicator.tsx +42 -0
- package/src/components/indicator/indicator.css +4 -0
- package/src/components/indicator/indicator.props.ts +24 -0
- package/src/components/indicator-stack/IndicatorStack.tsx +31 -0
- package/src/components/indicator-stack/indicator-stack.css +7 -0
- package/src/components/indicator-stack/indicatorStack.props.ts +15 -0
- package/src/components/inline/Inline.tsx +38 -0
- package/src/components/inline/inline.css +4 -0
- package/src/components/inline/inline.props.ts +100 -0
- package/src/components/label/Label.tsx +34 -0
- package/src/components/label/label.css +3 -0
- package/src/components/label/label.props.ts +25 -0
- package/src/components/link/Link.tsx +29 -0
- package/src/components/link/link.css +12 -0
- package/src/components/link/link.props.ts +23 -0
- package/src/components/list/List.tsx +167 -0
- package/src/components/list/list.css +25 -0
- package/src/components/list/list.props.ts +130 -0
- package/src/components/popover/Popover.tsx +85 -0
- package/src/components/popover/popover.css +21 -0
- package/src/components/popover/popover.props.ts +38 -0
- package/src/components/press-area/PressArea.tsx +29 -0
- package/src/components/press-area/press-area.css +22 -0
- package/src/components/press-area/pressArea.props.ts +16 -0
- package/src/components/radio/Radio.tsx +48 -0
- package/src/components/radio/radio.css +97 -0
- package/src/components/radio/radio.props.ts +25 -0
- package/src/components/skip-to-content/SkipToContent.tsx +35 -0
- package/src/components/skip-to-content/skip-to-content.css +9 -0
- package/src/components/skip-to-content/skipToContent.props.ts +25 -0
- package/src/components/spinner/Spinner.tsx +28 -0
- package/src/components/spinner/spinner.css +10 -0
- package/src/components/spinner/spinner.props.ts +19 -0
- package/src/components/switch/Switch.tsx +48 -0
- package/src/components/switch/switch.css +119 -0
- package/src/components/switch/switch.props.ts +25 -0
- package/src/components/text/Text.tsx +53 -0
- package/src/components/text/text.css +9 -0
- package/src/components/text/text.props.ts +28 -0
- package/src/components/tooltip/Tooltip.tsx +97 -0
- package/src/components/tooltip/tooltip.css +31 -0
- package/src/components/tooltip/tooltip.props.ts +36 -0
- package/src/components/tooltip-group/TooltipGroup.tsx +64 -0
- package/src/components/tooltip-group/tooltipGroup.props.ts +15 -0
- package/src/components/v-stack/VStack.tsx +32 -0
- package/src/components/v-stack/vStack.props.ts +17 -0
- package/src/components/visually-hidden/VisuallyHidden.tsx +29 -0
- package/src/components/visually-hidden/visually-hidden.css +9 -0
- package/src/components/visually-hidden/visuallyHidden.props.ts +23 -0
- package/src/css/classes/dynamic/flex-child.css +5 -0
- package/src/css/classes/dynamic/grid-child.css +8 -0
- package/src/css/classes/dynamic/grid-parent.css +6 -0
- package/src/css/classes/dynamic/height.css +5 -0
- package/src/css/classes/dynamic/index.css +7 -0
- package/src/css/classes/dynamic/line-clamp.css +5 -0
- package/src/css/classes/dynamic/readme.md +3 -0
- package/src/css/classes/dynamic/width.css +7 -0
- package/src/css/classes/dynamic/z-index.css +3 -0
- package/src/css/classes/generic/display.css +10 -0
- package/src/css/classes/generic/flex.css +24 -0
- package/src/css/classes/generic/grid.css +7 -0
- package/src/css/classes/generic/index.css +7 -0
- package/src/css/classes/generic/overflow.css +19 -0
- package/src/css/classes/generic/placement.css +202 -0
- package/src/css/classes/generic/position.css +7 -0
- package/src/css/classes/generic/readme.md +3 -0
- package/src/css/classes/generic/text-align.css +5 -0
- package/src/css/classes/index.css +4 -0
- package/src/css/classes/local/animation.css +4 -0
- package/src/css/classes/local/border.css +20 -0
- package/src/css/classes/local/index.css +6 -0
- package/src/css/classes/local/readme.md +3 -0
- package/src/css/classes/local/text-overflow.css +5 -0
- package/src/css/classes/local/text-trim.css +45 -0
- package/src/css/classes/local/tone.css +75 -0
- package/src/css/classes/local/top-anchor.css +4 -0
- package/src/css/classes/system/color.css +223 -0
- package/src/css/classes/system/container.css +8 -0
- package/src/css/classes/system/font-family.css +2 -0
- package/src/css/classes/system/font-weight.css +4 -0
- package/src/css/classes/system/gap.css +37 -0
- package/src/css/classes/system/index.css +10 -0
- package/src/css/classes/system/inset.css +56 -0
- package/src/css/classes/system/margin.css +148 -0
- package/src/css/classes/system/padding.css +78 -0
- package/src/css/classes/system/radius.css +10 -0
- package/src/css/classes/system/readme.md +3 -0
- package/src/css/classes/system/shadow.css +6 -0
- package/src/css/classes/system/typography.css +31 -0
- package/src/css/global/font-face.css +20 -0
- package/src/css/global/index.css +2 -0
- package/src/css/global/reset.css +76 -0
- package/src/css/tokens/index.css +3 -0
- package/src/css/tokens/opacity.css +6 -0
- package/src/css/tokens/semantic.css +25 -0
- package/src/css/tokens/surface.css +27 -0
- package/src/hooks/useIsClient.ts +10 -0
- package/src/index.css +18 -0
- package/src/index.ts +65 -0
- package/src/polyfills.ts +15 -0
- package/src/props/border.ts +51 -0
- package/src/props/flexChild.ts +29 -0
- package/src/props/flexParent.ts +47 -0
- package/src/props/gap.ts +31 -0
- package/src/props/gridChild.ts +50 -0
- package/src/props/gridParent.ts +45 -0
- package/src/props/height.ts +29 -0
- package/src/props/layout.ts +44 -0
- package/src/props/margin.ts +59 -0
- package/src/props/overflow.ts +30 -0
- package/src/props/padding.ts +59 -0
- package/src/props/placement.ts +16 -0
- package/src/props/position.ts +52 -0
- package/src/props/shadow.ts +15 -0
- package/src/props/tone.ts +15 -0
- package/src/props/typography.ts +62 -0
- package/src/props/width.ts +29 -0
- package/src/props/zIndex.ts +15 -0
- package/src/styles.css.d.ts +1 -0
- package/src/styles.css.node.js +2 -0
- package/src/styles.css.test.ts +24 -0
- package/src/types/Button.ts +8 -0
- package/src/types/Code.ts +6 -0
- package/src/types/Container.ts +3 -0
- package/src/types/Density.ts +3 -0
- package/src/types/Display.ts +11 -0
- package/src/types/Eyebrow.ts +3 -0
- package/src/types/Flex.ts +22 -0
- package/src/types/FontWeight.ts +3 -0
- package/src/types/Grid.ts +3 -0
- package/src/types/Heading.ts +6 -0
- package/src/types/Icon.ts +3 -0
- package/src/types/Interactive.ts +8 -0
- package/src/types/List.ts +2 -0
- package/src/types/Overflow.ts +3 -0
- package/src/types/Placement.ts +16 -0
- package/src/types/Position.ts +3 -0
- package/src/types/PropDef.ts +73 -0
- package/src/types/Radius.ts +3 -0
- package/src/types/Responsive.ts +10 -0
- package/src/types/Shadow.ts +3 -0
- package/src/types/Space.ts +15 -0
- package/src/types/Text.ts +3 -0
- package/src/types/TextAlign.ts +3 -0
- package/src/types/Tone.ts +3 -0
- package/src/utils/getProps.test.ts +156 -0
- package/src/utils/getProps.ts +156 -0
- package/src/utils/mergeTriggerProps.ts +66 -0
- package/src/utils/renderPortal.tsx +14 -0
- package/src/utils/suffixClassName.ts +5 -0
- package/src/version.ts +3 -0
- package/LICENSE +0 -21
- package/dist/_system-CTe2lb5l.d.ts +0 -40
- package/dist/_system-CTe2lb5l.d.ts.map +0 -1
- package/dist/arrow-BmX6qbAS.js +0 -170
- package/dist/arrow-BmX6qbAS.js.map +0 -1
- package/dist/autocomplete.d.ts +0 -140
- package/dist/autocomplete.d.ts.map +0 -1
- package/dist/autocomplete.js +0 -470
- package/dist/autocomplete.js.map +0 -1
- package/dist/breadcrumbs.d.ts +0 -18
- package/dist/breadcrumbs.d.ts.map +0 -1
- package/dist/breadcrumbs.js +0 -119
- package/dist/breadcrumbs.js.map +0 -1
- package/dist/button-BNyKSDyA.js +0 -180
- package/dist/button-BNyKSDyA.js.map +0 -1
- package/dist/button-dnqMFkWg.d.ts +0 -76
- package/dist/button-dnqMFkWg.d.ts.map +0 -1
- package/dist/card-C0a0wQTc.d.ts +0 -7
- package/dist/card-C0a0wQTc.d.ts.map +0 -1
- package/dist/code.d.ts +0 -20
- package/dist/code.d.ts.map +0 -1
- package/dist/code.js +0 -90
- package/dist/code.js.map +0 -1
- package/dist/codeFontStyle-84SMhFtI.js +0 -11
- package/dist/codeFontStyle-84SMhFtI.js.map +0 -1
- package/dist/component-DVlwaWB-.d.ts +0 -25
- package/dist/component-DVlwaWB-.d.ts.map +0 -1
- package/dist/element-BYgCE_iK.js +0 -51
- package/dist/element-BYgCE_iK.js.map +0 -1
- package/dist/factory-BzXTX8_Q.js +0 -3056
- package/dist/factory-BzXTX8_Q.js.map +0 -1
- package/dist/flex-DmbDG2ks.js +0 -76
- package/dist/flex-DmbDG2ks.js.map +0 -1
- package/dist/font-EtfxKPUz.d.ts +0 -49
- package/dist/font-EtfxKPUz.d.ts.map +0 -1
- package/dist/getElementRef-Jw7gY0eV.js +0 -102
- package/dist/getElementRef-Jw7gY0eV.js.map +0 -1
- package/dist/getScopedTheme-C-sZsyAz.js +0 -267
- package/dist/getScopedTheme-C-sZsyAz.js.map +0 -1
- package/dist/getTheme_v2-y09KqtEb.js +0 -487
- package/dist/getTheme_v2-y09KqtEb.js.map +0 -1
- package/dist/grid-6JSgMj1O.js +0 -115
- package/dist/grid-6JSgMj1O.js.map +0 -1
- package/dist/helpers-C8xxXAQC.js +0 -63
- package/dist/helpers-C8xxXAQC.js.map +0 -1
- package/dist/hotkeys-CaHsQlsO.js +0 -168
- package/dist/hotkeys-CaHsQlsO.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/layer-Bl5R3uNR.js +0 -61
- package/dist/layer-Bl5R3uNR.js.map +0 -1
- package/dist/layer-ChlP9Ik6.d.ts +0 -242
- package/dist/layer-ChlP9Ik6.d.ts.map +0 -1
- package/dist/menu.d.ts +0 -146
- package/dist/menu.d.ts.map +0 -1
- package/dist/menu.js +0 -626
- package/dist/menu.js.map +0 -1
- package/dist/popover-B7-28L8y.js +0 -408
- package/dist/popover-B7-28L8y.js.map +0 -1
- package/dist/popover-CMlQeKn0.d.ts +0 -96
- package/dist/popover-CMlQeKn0.d.ts.map +0 -1
- package/dist/popover.d.ts +0 -2
- package/dist/popover.js +0 -3
- package/dist/refractor-CC48DwHi.js +0 -20
- package/dist/refractor-CC48DwHi.js.map +0 -1
- package/dist/responsiveFont-CilwaORG.js +0 -55
- package/dist/responsiveFont-CilwaORG.js.map +0 -1
- package/dist/rgba-BSYaEUW6.d.ts +0 -846
- package/dist/rgba-BSYaEUW6.d.ts.map +0 -1
- package/dist/selectable-B0GUIL74.d.ts +0 -7
- package/dist/selectable-B0GUIL74.d.ts.map +0 -1
- package/dist/stack-rsNFPq2-.js +0 -112
- package/dist/stack-rsNFPq2-.js.map +0 -1
- package/dist/styles-css.d.ts +0 -2
- package/dist/styles-css.js +0 -4
- package/dist/textInput-pSfQjkmx.js +0 -313
- package/dist/textInput-pSfQjkmx.js.map +0 -1
- package/dist/theme.d.ts +0 -280
- package/dist/theme.d.ts.map +0 -1
- package/dist/theme.js +0 -55
- package/dist/theme.js.map +0 -1
- package/dist/toast.d.ts +0 -73
- package/dist/toast.d.ts.map +0 -1
- package/dist/toast.js +0 -302
- package/dist/toast.js.map +0 -1
- package/dist/tooltip.d.ts +0 -88
- package/dist/tooltip.d.ts.map +0 -1
- package/dist/tooltip.js +0 -435
- package/dist/tooltip.js.map +0 -1
- package/dist/useClickOutsideEvent-wGLGWBZN.js +0 -36
- package/dist/useClickOutsideEvent-wGLGWBZN.js.map +0 -1
- package/dist/useElementSize-BJvbGHq8.js +0 -51
- package/dist/useElementSize-BJvbGHq8.js.map +0 -1
- package/dist/useLayer-D1usxIE0.js +0 -712
- package/dist/useLayer-D1usxIE0.js.map +0 -1
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom radio control, base
|
|
3
|
+
*/
|
|
4
|
+
.sui-RadioMark {
|
|
5
|
+
/* Background and border colours are computed relatively in hover states;
|
|
6
|
+
we use custom properties to make this easier */
|
|
7
|
+
--background-color: var(--backdrop);
|
|
8
|
+
--border-color: var(--separator-high);
|
|
9
|
+
background-color: var(--background-color);
|
|
10
|
+
border: 1px solid var(--border-color);
|
|
11
|
+
transition: var(--hover-transition);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Custom radio marker
|
|
16
|
+
*/
|
|
17
|
+
.sui-RadioMark:after {
|
|
18
|
+
content: '';
|
|
19
|
+
background: var(--active-foreground-emphasized);
|
|
20
|
+
border-radius: var(--radius-round);
|
|
21
|
+
display: block;
|
|
22
|
+
inset: 0;
|
|
23
|
+
position: absolute;
|
|
24
|
+
opacity: 0;
|
|
25
|
+
transition: inset 100ms linear;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Hover - uses relative border/background colours to darken/lighten in both normal & error state
|
|
30
|
+
*/
|
|
31
|
+
/** Radio border (unchecked) */
|
|
32
|
+
.sui-Radio:hover .sui-RadioMark {
|
|
33
|
+
border-color: light-dark(
|
|
34
|
+
oklch(from var(--border-color) calc(l - var(--hover-lightness-delta)) c h),
|
|
35
|
+
oklch(from var(--border-color) calc(l + var(--hover-lightness-delta)) c h)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Radio background (checked) */
|
|
40
|
+
.sui-Radio:hover .sui-RadioInput:is(:checked) + .sui-RadioMark {
|
|
41
|
+
background-color: light-dark(
|
|
42
|
+
oklch(from var(--background-color) calc(l - var(--hover-lightness-delta)) c h),
|
|
43
|
+
oklch(from var(--background-color) calc(l + var(--hover-lightness-delta)) c h)
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Focus
|
|
49
|
+
*/
|
|
50
|
+
.sui-RadioInput:focus-visible + .sui-RadioMark {
|
|
51
|
+
outline: var(--focus-outline);
|
|
52
|
+
outline-offset: var(--focus-offset);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Checked
|
|
57
|
+
*/
|
|
58
|
+
.sui-RadioInput:checked + .sui-RadioMark {
|
|
59
|
+
--background-color: var(--active-background-emphasized);
|
|
60
|
+
--border-color: transparent;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.sui-RadioInput:checked + .sui-RadioMark:after {
|
|
64
|
+
inset: 4px;
|
|
65
|
+
opacity: 1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Disabled
|
|
70
|
+
*/
|
|
71
|
+
.sui-RadioInput:disabled + .sui-RadioMark {
|
|
72
|
+
--background-color: var(--inert-background);
|
|
73
|
+
--border-color: var(--separator-low);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.sui-RadioInput:disabled + .sui-RadioMark:after {
|
|
77
|
+
background: light-dark(var(--gray-300), var(--gray-500));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Turn hover (and all pointer events) off for disabled radios */
|
|
81
|
+
.sui-Radio:has(:disabled) {
|
|
82
|
+
pointer-events: none;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Error
|
|
87
|
+
*/
|
|
88
|
+
.sui-RadioMark.sui-error {
|
|
89
|
+
--border-color: var(--error-separator);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Error, checked
|
|
94
|
+
*/
|
|
95
|
+
.sui-RadioInput:checked + .sui-RadioMark.sui-error {
|
|
96
|
+
--background-color: var(--error-background-emphasized);
|
|
97
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {type MarginProps, marginProps} from '../../props/margin'
|
|
2
|
+
import {type PropDef} from '../../types/PropDef'
|
|
3
|
+
|
|
4
|
+
/** @beta */
|
|
5
|
+
export interface RadioProps extends React.ComponentProps<'input'>, MarginProps {
|
|
6
|
+
/**
|
|
7
|
+
* Applies error styling to the radio mark.
|
|
8
|
+
* @remarks Use when form validation fails. Pair with a visible error message. The prop is visual only.
|
|
9
|
+
*/
|
|
10
|
+
error?: boolean
|
|
11
|
+
/**
|
|
12
|
+
* Visible label next to the radio.
|
|
13
|
+
*/
|
|
14
|
+
label: React.ReactNode
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const radioProps: Record<string, PropDef> = {
|
|
18
|
+
error: {
|
|
19
|
+
type: 'boolean',
|
|
20
|
+
},
|
|
21
|
+
label: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
},
|
|
24
|
+
...marginProps,
|
|
25
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import clsx from 'clsx'
|
|
2
|
+
|
|
3
|
+
import {getProps} from '../../utils/getProps'
|
|
4
|
+
import {suffixClassName} from '../../utils/suffixClassName'
|
|
5
|
+
import {Link} from '../link/Link'
|
|
6
|
+
import {Text} from '../text/Text'
|
|
7
|
+
import {VisuallyHidden} from '../visually-hidden/VisuallyHidden'
|
|
8
|
+
import {type SkipToContentProps, skipToContentProps} from './skipToContent.props'
|
|
9
|
+
|
|
10
|
+
const skipToContentClassName = suffixClassName('sui-SkipToContent')
|
|
11
|
+
|
|
12
|
+
/** @beta */
|
|
13
|
+
export function SkipToContent(props: SkipToContentProps) {
|
|
14
|
+
const {className, label, style, ...rest} = getProps(props, skipToContentProps)
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<VisuallyHidden
|
|
18
|
+
as={Link}
|
|
19
|
+
underlined={false}
|
|
20
|
+
className={clsx(
|
|
21
|
+
skipToContentClassName,
|
|
22
|
+
'sui-position-absolute sui-top2 sui-left2 sui-display-inline-block sui-z-index sui-py2 sui-px3 sui-radius2 sui-text-body1',
|
|
23
|
+
className,
|
|
24
|
+
)}
|
|
25
|
+
style={style}
|
|
26
|
+
data-ui="SkipToContent"
|
|
27
|
+
visibleOnFocus
|
|
28
|
+
{...rest}
|
|
29
|
+
>
|
|
30
|
+
<Text size={1}>{label}</Text>
|
|
31
|
+
</VisuallyHidden>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type {SkipToContentProps}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {type PropDef} from '../../types/PropDef'
|
|
2
|
+
|
|
3
|
+
/** @beta */
|
|
4
|
+
export interface SkipToContentProps extends React.ComponentProps<'a'> {
|
|
5
|
+
/**
|
|
6
|
+
* Same-page fragment to jump to.
|
|
7
|
+
* @remarks Note: The hash character # is required for proper linking.
|
|
8
|
+
*/
|
|
9
|
+
href: string
|
|
10
|
+
/**
|
|
11
|
+
* Visible and announced text.
|
|
12
|
+
*/
|
|
13
|
+
label: string
|
|
14
|
+
/**
|
|
15
|
+
* Not accepted.
|
|
16
|
+
* @remarks Pass text via `label`.
|
|
17
|
+
*/
|
|
18
|
+
children?: never
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const skipToContentProps: Record<string, PropDef> = {
|
|
22
|
+
label: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
},
|
|
25
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {SpinnerIcon} from '@sanity/icons/Spinner'
|
|
2
|
+
import clsx from 'clsx'
|
|
3
|
+
|
|
4
|
+
import {getProps} from '../../utils/getProps'
|
|
5
|
+
import {suffixClassName} from '../../utils/suffixClassName'
|
|
6
|
+
import {Icon} from '../icon/Icon'
|
|
7
|
+
import {type SpinnerProps, spinnerProps} from './spinner.props'
|
|
8
|
+
|
|
9
|
+
const spinnerClassName = suffixClassName('sui-Spinner')
|
|
10
|
+
|
|
11
|
+
/** @public */
|
|
12
|
+
export function Spinner({size = 2, ...props}: SpinnerProps) {
|
|
13
|
+
const {className, style, ...rest} = getProps({size, ...props}, spinnerProps)
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<Icon
|
|
17
|
+
icon={SpinnerIcon}
|
|
18
|
+
className={clsx(spinnerClassName, className)}
|
|
19
|
+
style={style}
|
|
20
|
+
data-ui="Spinner"
|
|
21
|
+
role="status"
|
|
22
|
+
aria-label="Loading..."
|
|
23
|
+
{...rest}
|
|
24
|
+
/>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type {SpinnerProps}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {ICON_SIZE, type IconSize} from '../../types/Icon'
|
|
2
|
+
import {type PropDef} from '../../types/PropDef'
|
|
3
|
+
import type {Responsive} from '../../types/Responsive'
|
|
4
|
+
|
|
5
|
+
/** @public */
|
|
6
|
+
export interface SpinnerProps extends React.ComponentProps<'svg'> {
|
|
7
|
+
/**
|
|
8
|
+
* Size of the spinner icon.
|
|
9
|
+
*/
|
|
10
|
+
size?: Responsive<IconSize>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const spinnerProps: Record<string, PropDef> = {
|
|
14
|
+
size: {
|
|
15
|
+
type: 'union',
|
|
16
|
+
className: 'icon-body',
|
|
17
|
+
values: ICON_SIZE,
|
|
18
|
+
},
|
|
19
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import clsx from 'clsx'
|
|
2
|
+
|
|
3
|
+
import {getProps} from '../../utils/getProps'
|
|
4
|
+
import {suffixClassName} from '../../utils/suffixClassName'
|
|
5
|
+
import {Flex} from '../flex/Flex'
|
|
6
|
+
import {Label} from '../label/Label'
|
|
7
|
+
import {VisuallyHidden} from '../visually-hidden/VisuallyHidden'
|
|
8
|
+
import {type SwitchProps, switchProps} from './switch.props'
|
|
9
|
+
|
|
10
|
+
const switchClassName = suffixClassName('sui-Switch')
|
|
11
|
+
const switchInputClassName = suffixClassName('sui-SwitchInput')
|
|
12
|
+
const switchMarkClassName = suffixClassName('sui-SwitchMark')
|
|
13
|
+
|
|
14
|
+
/** @beta */
|
|
15
|
+
export function Switch(props: SwitchProps) {
|
|
16
|
+
const {className, style, disabled, error, label, ...rest} = getProps(props, switchProps)
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<Label
|
|
20
|
+
className={clsx(switchClassName, 'sui-position-relative', className)}
|
|
21
|
+
style={style}
|
|
22
|
+
data-ui="Switch"
|
|
23
|
+
disabled={props.disabled}
|
|
24
|
+
error={error}
|
|
25
|
+
>
|
|
26
|
+
<VisuallyHidden
|
|
27
|
+
as="input"
|
|
28
|
+
type="checkbox"
|
|
29
|
+
role="switch"
|
|
30
|
+
className={switchInputClassName}
|
|
31
|
+
disabled={disabled}
|
|
32
|
+
{...rest}
|
|
33
|
+
/>
|
|
34
|
+
|
|
35
|
+
<Flex
|
|
36
|
+
as="span"
|
|
37
|
+
className={clsx(switchMarkClassName, error && 'sui-error')}
|
|
38
|
+
alignItems="center"
|
|
39
|
+
radius={6}
|
|
40
|
+
aria-hidden="true"
|
|
41
|
+
/>
|
|
42
|
+
|
|
43
|
+
{label}
|
|
44
|
+
</Label>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type {SwitchProps}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom switch control, base
|
|
3
|
+
*/
|
|
4
|
+
.sui-SwitchMark {
|
|
5
|
+
/* Background and border colours are computed relatively in hover states;
|
|
6
|
+
we use custom properties to make this easier */
|
|
7
|
+
--background-color: var(--backdrop);
|
|
8
|
+
--border-color: var(--separator-high);
|
|
9
|
+
/* Switch size stored as custom properties to be used with calc
|
|
10
|
+
for active switch marker's x-axis translation */
|
|
11
|
+
--width: 25px;
|
|
12
|
+
--height: 17px;
|
|
13
|
+
background-color: var(--background-color);
|
|
14
|
+
border: 1px solid var(--border-color);
|
|
15
|
+
width: var(--width);
|
|
16
|
+
height: var(--height);
|
|
17
|
+
transition: var(--hover-transition);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Custom switch marker
|
|
22
|
+
*/
|
|
23
|
+
.sui-SwitchMark:after {
|
|
24
|
+
content: '';
|
|
25
|
+
display: block;
|
|
26
|
+
background-color: var(--foreground-high);
|
|
27
|
+
width: 7px;
|
|
28
|
+
height: 7px;
|
|
29
|
+
border-radius: var(--radius-round);
|
|
30
|
+
translate: 50%;
|
|
31
|
+
transition: translate 100ms linear;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Hover - uses relative border/background colours to darken/lighten in both normal & error state
|
|
36
|
+
*/
|
|
37
|
+
/** Switch border (unchecked) */
|
|
38
|
+
.sui-Switch:hover .sui-SwitchMark {
|
|
39
|
+
border-color: light-dark(
|
|
40
|
+
oklch(from var(--border-color) calc(l - var(--hover-lightness-delta)) c h),
|
|
41
|
+
oklch(from var(--border-color) calc(l + var(--hover-lightness-delta)) c h)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Switch background (checked) */
|
|
46
|
+
.sui-Switch:hover .sui-SwitchInput:is(:checked) + .sui-SwitchMark {
|
|
47
|
+
background-color: light-dark(
|
|
48
|
+
oklch(from var(--background-color) calc(l - var(--hover-lightness-delta)) c h),
|
|
49
|
+
oklch(from var(--background-color) calc(l + var(--hover-lightness-delta)) c h)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Focus
|
|
55
|
+
*/
|
|
56
|
+
.sui-SwitchInput:focus-visible + .sui-SwitchMark {
|
|
57
|
+
outline: var(--focus-outline);
|
|
58
|
+
outline-offset: var(--focus-offset);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Checked
|
|
63
|
+
*/
|
|
64
|
+
.sui-SwitchInput:checked + .sui-SwitchMark {
|
|
65
|
+
--background-color: var(--active-background-emphasized);
|
|
66
|
+
--border-color: transparent;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.sui-SwitchInput:checked + .sui-SwitchMark:after {
|
|
70
|
+
background-color: var(--active-foreground-emphasized);
|
|
71
|
+
translate: calc(var(--width) - 175%);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Disabled
|
|
76
|
+
*/
|
|
77
|
+
.sui-SwitchInput:disabled + .sui-SwitchMark {
|
|
78
|
+
--background-color: var(--inert-background);
|
|
79
|
+
--border-color: var(--separator-low);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.sui-SwitchInput:disabled + .sui-SwitchMark:after {
|
|
83
|
+
background: var(--inert-foreground);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Turn hover (and all pointer events) off for disabled switches */
|
|
87
|
+
.sui-Switch:has(:disabled) {
|
|
88
|
+
pointer-events: none;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Disabled and checked
|
|
93
|
+
*/
|
|
94
|
+
.sui-SwitchInput:disabled:checked + .sui-SwitchMark {
|
|
95
|
+
--background-color: var(--inert-foreground);
|
|
96
|
+
--border-color: transparent;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.sui-SwitchInput:disabled:checked + .sui-SwitchMark:after {
|
|
100
|
+
background-color: var(--inert-background);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Error
|
|
105
|
+
*/
|
|
106
|
+
.sui-SwitchMark.sui-error {
|
|
107
|
+
--border-color: var(--error-separator);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.sui-SwitchMark.sui-error:after {
|
|
111
|
+
background-color: var(--error-separator);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Error and checked
|
|
116
|
+
*/
|
|
117
|
+
.sui-SwitchInput:checked + .sui-SwitchMark.sui-error {
|
|
118
|
+
--background-color: var(--error-background-emphasized);
|
|
119
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {type MarginProps, marginProps} from '../../props/margin'
|
|
2
|
+
import {type PropDef} from '../../types/PropDef'
|
|
3
|
+
|
|
4
|
+
/** @beta */
|
|
5
|
+
export interface SwitchProps extends React.ComponentProps<'input'>, MarginProps {
|
|
6
|
+
/**
|
|
7
|
+
* Applies error styling to the switch track.
|
|
8
|
+
* @remarks Use when form validation fails. Pair with a visible error message. The prop is visual only.
|
|
9
|
+
*/
|
|
10
|
+
error?: boolean
|
|
11
|
+
/**
|
|
12
|
+
* Visible label next to the switch.
|
|
13
|
+
*/
|
|
14
|
+
label: React.ReactNode
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const switchProps: Record<string, PropDef> = {
|
|
18
|
+
error: {
|
|
19
|
+
type: 'boolean',
|
|
20
|
+
},
|
|
21
|
+
label: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
},
|
|
24
|
+
...marginProps,
|
|
25
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import clsx from 'clsx'
|
|
2
|
+
import type {ComponentPropsWithRef, ElementType} from 'react'
|
|
3
|
+
|
|
4
|
+
import {getProps} from '../../utils/getProps'
|
|
5
|
+
import {suffixClassName} from '../../utils/suffixClassName'
|
|
6
|
+
import {type TextProps, textProps} from './text.props'
|
|
7
|
+
|
|
8
|
+
const textClassName = suffixClassName('sui-Text')
|
|
9
|
+
|
|
10
|
+
/** @public */
|
|
11
|
+
export function Text<T extends ElementType = 'span'>({
|
|
12
|
+
size = 2,
|
|
13
|
+
...props
|
|
14
|
+
}: TextProps<T> & Omit<ComponentPropsWithRef<T>, keyof TextProps<T>>) {
|
|
15
|
+
const {as, children, className, style, ...rest} = getProps({size, ...props}, textProps)
|
|
16
|
+
const Component = as || 'span'
|
|
17
|
+
|
|
18
|
+
if (props.truncate && props.trim) {
|
|
19
|
+
return (
|
|
20
|
+
<Component
|
|
21
|
+
className={clsx(
|
|
22
|
+
textClassName,
|
|
23
|
+
className?.replace('sui-line-clamp', '').replace('sui-text-overflow', ''),
|
|
24
|
+
)}
|
|
25
|
+
style={style}
|
|
26
|
+
data-ui="Text"
|
|
27
|
+
{...rest}
|
|
28
|
+
>
|
|
29
|
+
<span
|
|
30
|
+
className={clsx(
|
|
31
|
+
'sui-overflow-hidden',
|
|
32
|
+
props.truncate === 1 ? 'sui-text-overflow' : 'sui-line-clamp',
|
|
33
|
+
)}
|
|
34
|
+
>
|
|
35
|
+
{children}
|
|
36
|
+
</span>
|
|
37
|
+
</Component>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<Component
|
|
43
|
+
className={clsx(textClassName, props.truncate && 'sui-overflow-hidden', className)}
|
|
44
|
+
style={style}
|
|
45
|
+
data-ui="Text"
|
|
46
|
+
{...rest}
|
|
47
|
+
>
|
|
48
|
+
{children}
|
|
49
|
+
</Component>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type {TextProps}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {type TypographyProps, typographyProps} from '../../props/typography'
|
|
2
|
+
import {type PropDef} from '../../types/PropDef'
|
|
3
|
+
import type {Responsive} from '../../types/Responsive'
|
|
4
|
+
import {TEXT_SIZE, type TextSize} from '../../types/Text'
|
|
5
|
+
|
|
6
|
+
/** @public */
|
|
7
|
+
export interface TextProps<T extends React.ElementType = 'span'> extends TypographyProps {
|
|
8
|
+
/**
|
|
9
|
+
* HTML element to render.
|
|
10
|
+
*/
|
|
11
|
+
as?: T
|
|
12
|
+
/**
|
|
13
|
+
* Sets font size.
|
|
14
|
+
*/
|
|
15
|
+
size?: Responsive<TextSize>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const textProps: Record<string, PropDef> = {
|
|
19
|
+
as: {
|
|
20
|
+
type: 'string',
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
type: 'union',
|
|
24
|
+
className: 'text-body',
|
|
25
|
+
values: TEXT_SIZE,
|
|
26
|
+
},
|
|
27
|
+
...typographyProps,
|
|
28
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import clsx from 'clsx'
|
|
2
|
+
import {cloneElement, useId, useState, type ToggleEvent} from 'react'
|
|
3
|
+
|
|
4
|
+
import {useIsClient} from '../../hooks/useIsClient'
|
|
5
|
+
import {getProps} from '../../utils/getProps'
|
|
6
|
+
import {mergeTriggerProps} from '../../utils/mergeTriggerProps'
|
|
7
|
+
import {renderPortal} from '../../utils/renderPortal'
|
|
8
|
+
import {suffixClassName} from '../../utils/suffixClassName'
|
|
9
|
+
import {type TooltipProps, tooltipProps} from './tooltip.props'
|
|
10
|
+
|
|
11
|
+
const tooltipClassName = suffixClassName('sui-Tooltip')
|
|
12
|
+
|
|
13
|
+
function TooltipRoot({
|
|
14
|
+
placement = 'bottom',
|
|
15
|
+
...props
|
|
16
|
+
}: TooltipProps & {
|
|
17
|
+
triggerProps?: Record<string, unknown>
|
|
18
|
+
}) {
|
|
19
|
+
const {
|
|
20
|
+
children,
|
|
21
|
+
className,
|
|
22
|
+
style,
|
|
23
|
+
id: idProp,
|
|
24
|
+
anchorName,
|
|
25
|
+
content,
|
|
26
|
+
portal,
|
|
27
|
+
triggerProps: forwardedTriggerProps,
|
|
28
|
+
...rest
|
|
29
|
+
} = getProps({placement, ...props}, tooltipProps)
|
|
30
|
+
const reactId = useId()
|
|
31
|
+
const id = idProp || reactId
|
|
32
|
+
const [dismissed, setDismissed] = useState(false)
|
|
33
|
+
const isClient = useIsClient()
|
|
34
|
+
|
|
35
|
+
const triggerProps = {
|
|
36
|
+
'aria-describedby': id,
|
|
37
|
+
'interestfor': id,
|
|
38
|
+
'style': {anchorName: `--anchor-${anchorName || id}`},
|
|
39
|
+
'onMouseLeave': () => {
|
|
40
|
+
setDismissed(false)
|
|
41
|
+
},
|
|
42
|
+
'onBlur': () => {
|
|
43
|
+
setDismissed(false)
|
|
44
|
+
},
|
|
45
|
+
'onClick': () => {
|
|
46
|
+
setDismissed(true)
|
|
47
|
+
document.getElementById(id)?.hidePopover()
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const trigger = children.type.forwardsTriggerProps
|
|
52
|
+
? cloneElement(children, {triggerProps})
|
|
53
|
+
: cloneElement(children, mergeTriggerProps(children.props, forwardedTriggerProps, triggerProps))
|
|
54
|
+
|
|
55
|
+
const handleBeforeToggle = (e: ToggleEvent) => {
|
|
56
|
+
if (e.newState === 'open' && dismissed) {
|
|
57
|
+
e.preventDefault()
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
{trigger}
|
|
64
|
+
|
|
65
|
+
{renderPortal(
|
|
66
|
+
<div
|
|
67
|
+
className={clsx(
|
|
68
|
+
tooltipClassName,
|
|
69
|
+
'sui-px2 sui-py1 sui-radius2 sui-position-fixed sui-shadow2',
|
|
70
|
+
className,
|
|
71
|
+
)}
|
|
72
|
+
style={{
|
|
73
|
+
...style,
|
|
74
|
+
positionAnchor: `--anchor-${anchorName || id}`,
|
|
75
|
+
}}
|
|
76
|
+
data-ui="Tooltip"
|
|
77
|
+
role="tooltip"
|
|
78
|
+
popover="hint"
|
|
79
|
+
id={id}
|
|
80
|
+
onBeforeToggle={handleBeforeToggle}
|
|
81
|
+
{...rest}
|
|
82
|
+
>
|
|
83
|
+
{content}
|
|
84
|
+
</div>,
|
|
85
|
+
isClient,
|
|
86
|
+
portal,
|
|
87
|
+
)}
|
|
88
|
+
</>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** @beta */
|
|
93
|
+
export const Tooltip = Object.assign(TooltipRoot, {
|
|
94
|
+
forwardsTriggerProps: true,
|
|
95
|
+
}) as typeof TooltipRoot
|
|
96
|
+
|
|
97
|
+
export type {TooltipProps}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[interestfor] {
|
|
2
|
+
--tooltip-delay: var(--tooltip-delay-group, 500ms);
|
|
3
|
+
/* The interestfor polyfill looks for intereset delay variables */
|
|
4
|
+
--interest-delay-start: var(--tooltip-delay);
|
|
5
|
+
--interest-delay-end: 0ms;
|
|
6
|
+
interest-delay-start: var(--tooltip-delay);
|
|
7
|
+
interest-delay-end: 0ms;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.sui-Tooltip {
|
|
11
|
+
background: var(--backdrop);
|
|
12
|
+
visibility: hidden;
|
|
13
|
+
opacity: 0;
|
|
14
|
+
scale: 0.9;
|
|
15
|
+
transition: none;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.sui-Tooltip:popover-open {
|
|
19
|
+
visibility: visible;
|
|
20
|
+
opacity: 1;
|
|
21
|
+
scale: 1;
|
|
22
|
+
transition: var(--fade-in-transition);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@starting-style {
|
|
26
|
+
.sui-Tooltip:popover-open {
|
|
27
|
+
visibility: hidden;
|
|
28
|
+
opacity: 0;
|
|
29
|
+
scale: 0.9;
|
|
30
|
+
}
|
|
31
|
+
}
|