@sanity/ui 2.0.0-alpha.2 → 2.0.0-alpha.21
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.cjs.mjs +28 -0
- package/dist/index.d.ts +476 -12
- package/dist/index.esm.js +1326 -524
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1353 -523
- package/dist/index.js.map +1 -1
- package/package.json +6 -8
- package/src/components/autocomplete/autocomplete.tsx +6 -0
- package/src/components/dialog/constants.ts +4 -0
- package/src/components/dialog/dialog.tsx +79 -15
- package/src/components/hotkeys/hotkeys.tsx +2 -0
- package/src/components/menu/menu.tsx +2 -0
- package/src/components/menu/menuButton.tsx +2 -0
- package/src/components/menu/menuGroup.tsx +22 -23
- package/src/components/menu/menuItem.tsx +29 -35
- package/src/components/tab/tab.tsx +4 -1
- package/src/components/toast/toast.tsx +4 -0
- package/src/primitives/_selectable/style.ts +2 -1
- package/src/primitives/avatar/avatar.tsx +16 -9
- package/src/primitives/avatar/avatarCounter.tsx +3 -3
- package/src/primitives/avatar/styles.ts +1 -1
- package/src/primitives/badge/badge.tsx +7 -3
- package/src/primitives/box/box.tsx +3 -0
- package/src/primitives/button/__workshop__/sanityUploadButton.tsx +2 -1
- package/src/primitives/button/button.tsx +7 -3
- package/src/primitives/button/styles.ts +9 -2
- package/src/primitives/card/card.tsx +4 -0
- package/src/primitives/card/styles.ts +2 -0
- package/src/primitives/checkbox/checkbox.tsx +2 -0
- package/src/primitives/code/code.tsx +1 -0
- package/src/primitives/container/container.tsx +2 -0
- package/src/primitives/flex/flex.tsx +2 -0
- package/src/primitives/grid/grid.tsx +2 -0
- package/src/primitives/heading/heading.tsx +2 -0
- package/src/primitives/inline/inline.tsx +3 -0
- package/src/primitives/kbd/kbd.tsx +2 -0
- package/src/primitives/label/label.tsx +2 -0
- package/src/primitives/popover/popover.tsx +6 -1
- package/src/primitives/radio/radio.tsx +2 -0
- package/src/primitives/select/select.tsx +2 -0
- package/src/primitives/select/styles.ts +2 -0
- package/src/primitives/spinner/spinner.tsx +2 -0
- package/src/primitives/stack/stack.tsx +2 -0
- package/src/primitives/switch/switch.tsx +4 -0
- package/src/primitives/text/text.tsx +3 -0
- package/src/primitives/textArea/textArea.tsx +4 -1
- package/src/primitives/textInput/textInput.tsx +10 -1
- package/src/primitives/tooltip/__workshop__/customPortal.tsx +99 -0
- package/src/primitives/tooltip/__workshop__/index.ts +15 -0
- package/src/primitives/tooltip/__workshop__/overflowingBoundary.tsx +73 -0
- package/src/primitives/tooltip/__workshop__/resizableBoundary.tsx +85 -0
- package/src/primitives/tooltip/constants.ts +1 -0
- package/src/primitives/tooltip/tooltip.test.tsx +192 -0
- package/src/primitives/tooltip/tooltip.tsx +109 -33
- package/src/primitives/types.ts +4 -0
- package/src/styles/input/textInputStyle.ts +11 -6
- package/src/theme/_internal/__workshop__/build/story.tsx +288 -0
- package/src/theme/_internal/__workshop__/build/theme.ts +3 -0
- package/src/theme/_internal/__workshop__/index.ts +14 -0
- package/src/theme/_internal/build/buildTheme.test.ts +78 -0
- package/src/theme/_internal/build/buildTheme.ts +16 -0
- package/src/theme/_internal/build/colorTheme/buildColorTheme.test.ts +185 -0
- package/src/theme/_internal/build/colorTheme/buildColorTheme.ts +164 -0
- package/src/theme/_internal/build/colorTheme/renderColorTheme.ts +242 -0
- package/src/theme/_internal/build/colorTheme/resolveColorTokens.ts +121 -0
- package/src/theme/_internal/build/defaults/colorPalette.ts +8 -0
- package/src/theme/_internal/build/defaults/colorTokens.ts +147 -0
- package/src/theme/_internal/build/helpers.ts +65 -0
- package/src/theme/_internal/build/index.ts +1 -0
- package/src/theme/_internal/config/helpers.ts +47 -0
- package/src/theme/_internal/config/index.ts +3 -0
- package/src/theme/_internal/config/token/index.ts +2 -0
- package/src/theme/_internal/config/token/parseTokenKey.test.ts +72 -0
- package/src/theme/_internal/config/token/parseTokenKey.ts +88 -0
- package/src/theme/_internal/config/token/parseTokenValue.test.ts +45 -0
- package/src/theme/_internal/config/token/parseTokenValue.ts +123 -0
- package/src/theme/_internal/config/types.ts +137 -0
- package/src/theme/_internal/constants.ts +48 -0
- package/src/theme/_internal/helpers.ts +19 -0
- package/src/theme/_internal/index.ts +5 -0
- package/src/theme/_internal/types.ts +91 -0
- package/src/theme/index.ts +1 -0
- package/src/theme/lib/color-fns/blend/multiply.ts +2 -2
- package/src/theme/lib/color-fns/blend/screen.ts +2 -2
- package/src/theme/lib/color-fns/convert.ts +15 -1
- package/src/theme/lib/color-fns/parse.ts +7 -3
- package/src/theme/lib/color-fns/types.ts +11 -0
- package/src/theme/lib/theme/avatar.ts +2 -0
- package/src/theme/lib/theme/color/_legacy/createColorTheme.ts +7 -0
- package/src/theme/lib/theme/color/_legacy/index.ts +1 -0
- package/src/theme/lib/theme/color/_legacy/legacyColor.ts +3997 -0
- package/src/theme/studioTheme/color.ts +98 -82
- package/src/theme/studioTheme/helpers.ts +15 -1
- package/src/theme/studioTheme/theme.ts +5 -5
- package/src/theme/studioTheme/tints.ts +244 -84
- package/src/types/button.ts +5 -0
|
@@ -4,7 +4,7 @@ import styled from 'styled-components'
|
|
|
4
4
|
|
|
5
5
|
const SanityUploadButton = styled(Button).attrs({forwardedAs: 'label'})`
|
|
6
6
|
& input {
|
|
7
|
-
|
|
7
|
+
appearance: none;
|
|
8
8
|
overflow: hidden;
|
|
9
9
|
overflow: clip;
|
|
10
10
|
top: 0;
|
|
@@ -14,6 +14,7 @@ const SanityUploadButton = styled(Button).attrs({forwardedAs: 'label'})`
|
|
|
14
14
|
opacity: 0;
|
|
15
15
|
position: absolute;
|
|
16
16
|
max-width: 0;
|
|
17
|
+
width: -webkit-fill-available;
|
|
17
18
|
width: stretch;
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -5,7 +5,7 @@ import {useArrayProp} from '../../hooks'
|
|
|
5
5
|
import {ThemeProps} from '../../styles'
|
|
6
6
|
import {responsiveRadiusStyle, ResponsiveRadiusStyleProps} from '../../styles/internal'
|
|
7
7
|
import {useTheme} from '../../theme'
|
|
8
|
-
import {ButtonMode, ButtonTextAlign, ButtonTone, FlexJustify} from '../../types'
|
|
8
|
+
import {ButtonMode, ButtonTextAlign, ButtonTone, ButtonWidth, FlexJustify} from '../../types'
|
|
9
9
|
import {Box} from '../box'
|
|
10
10
|
import {Flex} from '../flex'
|
|
11
11
|
import {Spinner} from '../spinner'
|
|
@@ -34,10 +34,12 @@ export interface ButtonProps extends ResponsivePaddingProps, ResponsiveRadiusPro
|
|
|
34
34
|
text?: React.ReactNode
|
|
35
35
|
tone?: ButtonTone
|
|
36
36
|
type?: 'button' | 'reset' | 'submit'
|
|
37
|
+
width?: ButtonWidth
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
const Root = styled.button<
|
|
40
|
-
{$mode: ButtonMode; $tone: ButtonTone} & ResponsiveRadiusStyleProps &
|
|
41
|
+
{$mode: ButtonMode; $tone: ButtonTone; $width?: ButtonWidth} & ResponsiveRadiusStyleProps &
|
|
42
|
+
ThemeProps
|
|
41
43
|
>(responsiveRadiusStyle, buttonBaseStyles, buttonColorStyles)
|
|
42
44
|
|
|
43
45
|
const LoadingBox = styled.div`
|
|
@@ -59,7 +61,7 @@ const LoadingBox = styled.div`
|
|
|
59
61
|
* @public
|
|
60
62
|
*/
|
|
61
63
|
export const Button = forwardRef(function Button(
|
|
62
|
-
props: ButtonProps & Omit<React.HTMLProps<HTMLButtonElement>, 'as'>,
|
|
64
|
+
props: ButtonProps & Omit<React.HTMLProps<HTMLButtonElement>, 'as' | 'width'>,
|
|
63
65
|
ref: React.ForwardedRef<HTMLButtonElement>,
|
|
64
66
|
) {
|
|
65
67
|
const {
|
|
@@ -86,6 +88,7 @@ export const Button = forwardRef(function Button(
|
|
|
86
88
|
tone = 'default',
|
|
87
89
|
type = 'button',
|
|
88
90
|
muted = false,
|
|
91
|
+
width,
|
|
89
92
|
...restProps
|
|
90
93
|
} = props
|
|
91
94
|
|
|
@@ -128,6 +131,7 @@ export const Button = forwardRef(function Button(
|
|
|
128
131
|
disabled={Boolean(loading || disabled)}
|
|
129
132
|
ref={ref}
|
|
130
133
|
type={type}
|
|
134
|
+
$width={width}
|
|
131
135
|
>
|
|
132
136
|
{Boolean(loading) && (
|
|
133
137
|
<LoadingBox>
|
|
@@ -2,13 +2,13 @@ import {css} from 'styled-components'
|
|
|
2
2
|
import {ThemeProps} from '../../styles'
|
|
3
3
|
import {_colorVarsStyle} from '../../styles/colorVars'
|
|
4
4
|
import {focusRingBorderStyle, focusRingStyle} from '../../styles/internal'
|
|
5
|
-
import {ButtonMode, ButtonTone} from '../../types'
|
|
5
|
+
import {ButtonMode, ButtonTone, ButtonWidth} from '../../types'
|
|
6
6
|
import {CSSObject} from '../../types/styled'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @internal
|
|
10
10
|
*/
|
|
11
|
-
export function buttonBaseStyles(): ReturnType<typeof css> {
|
|
11
|
+
export function buttonBaseStyles({$width}: {$width?: ButtonWidth}): ReturnType<typeof css> {
|
|
12
12
|
return css`
|
|
13
13
|
-webkit-font-smoothing: inherit;
|
|
14
14
|
appearance: none;
|
|
@@ -27,6 +27,13 @@ export function buttonBaseStyles(): ReturnType<typeof css> {
|
|
|
27
27
|
text-align: left;
|
|
28
28
|
position: relative;
|
|
29
29
|
|
|
30
|
+
${$width === 'fill' &&
|
|
31
|
+
css`
|
|
32
|
+
width: -moz-available;
|
|
33
|
+
width: -webkit-fill-available;
|
|
34
|
+
width: stretch;
|
|
35
|
+
`}
|
|
36
|
+
|
|
30
37
|
& > span {
|
|
31
38
|
display: block;
|
|
32
39
|
flex: 1;
|
|
@@ -48,6 +48,9 @@ const Root = styled(Box)<
|
|
|
48
48
|
>(responsiveBorderStyle, responsiveRadiusStyle, responsiveShadowStyle, cardStyle)
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
+
* The `Card` component acts much like a `Box`, but with a background and foreground color.
|
|
52
|
+
* Components within a `Card` inherit its colors.
|
|
53
|
+
*
|
|
51
54
|
* @public
|
|
52
55
|
*/
|
|
53
56
|
export const Card = forwardRef(function Card(
|
|
@@ -76,6 +79,7 @@ export const Card = forwardRef(function Card(
|
|
|
76
79
|
const rootTheme = useRootTheme()
|
|
77
80
|
const tone = toneProp === 'inherit' ? rootTheme.tone : toneProp
|
|
78
81
|
|
|
82
|
+
// TODO: Consider adding the wrapper approach for nested cards in which the tones are not changing, avoid unnecessary ThemeColorProvider
|
|
79
83
|
return (
|
|
80
84
|
<ThemeColorProvider scheme={scheme} tone={tone}>
|
|
81
85
|
<Root
|
|
@@ -11,6 +11,7 @@ import {codeBaseStyle} from './styles'
|
|
|
11
11
|
*/
|
|
12
12
|
export interface CodeProps {
|
|
13
13
|
as?: React.ElementType | keyof JSX.IntrinsicElements
|
|
14
|
+
/** Define the language to use for syntax highlighting. */
|
|
14
15
|
language?: string
|
|
15
16
|
size?: number | number[]
|
|
16
17
|
weight?: string
|
|
@@ -13,6 +13,8 @@ export interface GridProps extends Omit<BoxProps, 'display'>, ResponsiveGridProp
|
|
|
13
13
|
const Root = styled(Box)<ResponsiveGridStyleProps>(responsiveGridStyle)
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
+
* The `Grid` component is for building 2-dimensional layers (based on CSS grid).
|
|
17
|
+
*
|
|
16
18
|
* @public
|
|
17
19
|
*/
|
|
18
20
|
export const Grid = forwardRef(function Grid(
|
|
@@ -10,12 +10,15 @@ import {ResponsiveInlineSpaceStyleProps} from './types'
|
|
|
10
10
|
* @public
|
|
11
11
|
*/
|
|
12
12
|
export interface InlineProps extends Omit<BoxProps, 'display'> {
|
|
13
|
+
/** The spacing between children. */
|
|
13
14
|
space?: number | number[]
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
const Root = styled(Box)<ResponsiveInlineSpaceStyleProps>(inlineBaseStyle, inlineSpaceStyle)
|
|
17
18
|
|
|
18
19
|
/**
|
|
20
|
+
* The `Inline` component is a layout utility for aligning and spacing items horizontally.
|
|
21
|
+
*
|
|
19
22
|
* @public
|
|
20
23
|
*/
|
|
21
24
|
export const Inline = forwardRef(function Inline(
|
|
@@ -59,6 +59,7 @@ export interface PopoverProps
|
|
|
59
59
|
overflow?: BoxOverflow
|
|
60
60
|
padding?: number | number[]
|
|
61
61
|
placement?: Placement
|
|
62
|
+
/** Whether or not to render the popover in a portal element. */
|
|
62
63
|
portal?: boolean | string
|
|
63
64
|
preventOverflow?: boolean
|
|
64
65
|
referenceBoundary?: HTMLElement | null
|
|
@@ -72,7 +73,11 @@ export interface PopoverProps
|
|
|
72
73
|
width?: PopoverWidth | PopoverWidth[]
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* The `Popover` component is used to display some content on top of another.
|
|
78
|
+
*
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
76
81
|
export const Popover = memo(
|
|
77
82
|
forwardRef(function Popover(
|
|
78
83
|
props: PopoverProps &
|
|
@@ -15,6 +15,8 @@ export interface StackProps extends BoxProps {
|
|
|
15
15
|
const Root = styled(Box)<ResponsiveStackSpaceStyleProps>(stackBaseStyle, responsiveStackSpaceStyle)
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
+
* The `Stack` component is used to place elements on top of each other.
|
|
19
|
+
*
|
|
18
20
|
* @public
|
|
19
21
|
*/
|
|
20
22
|
export const Stack = forwardRef(function Stack(
|
|
@@ -23,6 +23,10 @@ const Track = styled.span(switchTrackStyles)
|
|
|
23
23
|
const Thumb = styled.span<{$checked?: boolean; $indeterminate?: boolean}>(switchThumbStyles)
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
+
* The `Switch` component allows the user to toggle a setting on and off.
|
|
27
|
+
*
|
|
28
|
+
* Extends all properties of an `<input type="checkbox" />` element, except type.
|
|
29
|
+
*
|
|
26
30
|
* @public
|
|
27
31
|
*/
|
|
28
32
|
export const Switch = forwardRef(function Switch(
|
|
@@ -17,6 +17,7 @@ export interface TextProps {
|
|
|
17
17
|
accent?: boolean
|
|
18
18
|
align?: TextAlign | TextAlign[]
|
|
19
19
|
as?: React.ElementType | keyof JSX.IntrinsicElements
|
|
20
|
+
/** When `true` the text color will be muted. */
|
|
20
21
|
muted?: boolean
|
|
21
22
|
size?: number | number[]
|
|
22
23
|
/**
|
|
@@ -43,6 +44,8 @@ const SpanWithTextOverflow = styled.span`
|
|
|
43
44
|
`
|
|
44
45
|
|
|
45
46
|
/**
|
|
47
|
+
* The `Text` component is an agile, themed typographic element.
|
|
48
|
+
*
|
|
46
49
|
* @public
|
|
47
50
|
*/
|
|
48
51
|
export const Text = forwardRef(function Text(
|
|
@@ -48,6 +48,9 @@ const Presentation = styled.div<ResponsiveRadiusStyleProps & TextInputRepresenta
|
|
|
48
48
|
)
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
+
* A multiline text input.
|
|
52
|
+
*
|
|
53
|
+
|
|
51
54
|
* @public
|
|
52
55
|
*/
|
|
53
56
|
export const TextArea = forwardRef(function TextArea(
|
|
@@ -60,7 +63,7 @@ export const TextArea = forwardRef(function TextArea(
|
|
|
60
63
|
disabled = false,
|
|
61
64
|
fontSize = 2,
|
|
62
65
|
padding = 3,
|
|
63
|
-
radius =
|
|
66
|
+
radius = 2,
|
|
64
67
|
weight,
|
|
65
68
|
...restProps
|
|
66
69
|
} = props
|
|
@@ -50,6 +50,10 @@ export type TextInputType =
|
|
|
50
50
|
* @public
|
|
51
51
|
*/
|
|
52
52
|
export interface TextInputProps {
|
|
53
|
+
/**
|
|
54
|
+
* @beta
|
|
55
|
+
*/
|
|
56
|
+
__unstable_disableFocusRing?: boolean
|
|
53
57
|
border?: boolean
|
|
54
58
|
/**
|
|
55
59
|
* @beta
|
|
@@ -140,6 +144,8 @@ const TextInputClearButton = styled(Button)({
|
|
|
140
144
|
})
|
|
141
145
|
|
|
142
146
|
/**
|
|
147
|
+
* Single line text input.
|
|
148
|
+
*
|
|
143
149
|
* @public
|
|
144
150
|
*/
|
|
145
151
|
export const TextInput = forwardRef(function TextInput(
|
|
@@ -147,6 +153,7 @@ export const TextInput = forwardRef(function TextInput(
|
|
|
147
153
|
forwardedRef: React.Ref<HTMLInputElement>,
|
|
148
154
|
) {
|
|
149
155
|
const {
|
|
156
|
+
__unstable_disableFocusRing,
|
|
150
157
|
border = true,
|
|
151
158
|
clearButton,
|
|
152
159
|
disabled = false,
|
|
@@ -156,7 +163,7 @@ export const TextInput = forwardRef(function TextInput(
|
|
|
156
163
|
onClear,
|
|
157
164
|
padding: paddingProp = 3,
|
|
158
165
|
prefix,
|
|
159
|
-
radius: radiusProp =
|
|
166
|
+
radius: radiusProp = 2,
|
|
160
167
|
readOnly,
|
|
161
168
|
space: spaceProp = 3,
|
|
162
169
|
suffix,
|
|
@@ -219,6 +226,7 @@ export const TextInput = forwardRef(function TextInput(
|
|
|
219
226
|
() => (
|
|
220
227
|
<Presentation
|
|
221
228
|
$hasPrefix={$hasPrefix}
|
|
229
|
+
$unstableDisableFocusRing={__unstable_disableFocusRing}
|
|
222
230
|
$hasSuffix={$hasSuffix}
|
|
223
231
|
$radius={radius}
|
|
224
232
|
$scheme={rootTheme.scheme}
|
|
@@ -247,6 +255,7 @@ export const TextInput = forwardRef(function TextInput(
|
|
|
247
255
|
</Presentation>
|
|
248
256
|
),
|
|
249
257
|
[
|
|
258
|
+
__unstable_disableFocusRing,
|
|
250
259
|
border,
|
|
251
260
|
fontSize,
|
|
252
261
|
icon,
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BoundaryElementProvider,
|
|
3
|
+
Button,
|
|
4
|
+
Card,
|
|
5
|
+
Flex,
|
|
6
|
+
Portal,
|
|
7
|
+
PortalProvider,
|
|
8
|
+
Stack,
|
|
9
|
+
Text,
|
|
10
|
+
Tooltip,
|
|
11
|
+
} from '@sanity/ui'
|
|
12
|
+
import {useBoolean, useSelect, useText} from '@sanity/ui-workshop'
|
|
13
|
+
import {useState} from 'react'
|
|
14
|
+
import {WORKSHOP_PLACEMENT_OPTIONS} from '../../../__workshop__/constants'
|
|
15
|
+
|
|
16
|
+
const PORTAL_OPTIONS = {
|
|
17
|
+
'(true)': true,
|
|
18
|
+
'(false)': false,
|
|
19
|
+
portal1: 'portal1',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default function CustomPortalStory() {
|
|
23
|
+
const content = useText(
|
|
24
|
+
'Content',
|
|
25
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut mollis consectetur malesuada. Sed lobortis est dolor, eget imperdiet velit placerat et. Aenean posuere mi non aliquet iaculis. Donec fermentum pulvinar purus at sagittis. Ut tincidunt massa odio, sed finibus justo ullamcorper id. Nam venenatis justo non ligula elementum cursus. Pellentesque laoreet justo in mollis sagittis. In lacinia ornare ultrices. Suspendisse potenti.',
|
|
26
|
+
)
|
|
27
|
+
const placement = useSelect('Placement', WORKSHOP_PLACEMENT_OPTIONS, 'top')
|
|
28
|
+
const portal = useSelect('Portal', PORTAL_OPTIONS, undefined, 'Props')
|
|
29
|
+
const useBoundaryElement = useBoolean('Use boundary element', true)
|
|
30
|
+
|
|
31
|
+
const [portal1Element, setPortal1Element] = useState<HTMLDivElement | null>(null)
|
|
32
|
+
const [boundaryElement, setBoundaryElement] = useState<HTMLDivElement | null>(null)
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<PortalProvider
|
|
36
|
+
__unstable_elements={{
|
|
37
|
+
portal1: portal1Element,
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<Flex align="center" height="fill" justify="center">
|
|
41
|
+
<BoundaryElementProvider element={useBoundaryElement ? boundaryElement : null}>
|
|
42
|
+
<Card
|
|
43
|
+
border
|
|
44
|
+
padding={4}
|
|
45
|
+
ref={setBoundaryElement}
|
|
46
|
+
style={{
|
|
47
|
+
height: 'calc(100vh - 100px)',
|
|
48
|
+
position: 'relative',
|
|
49
|
+
width: '500px',
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
<Text>Boundary element</Text>
|
|
53
|
+
<Flex align="center" height="fill" justify="center">
|
|
54
|
+
<Flex justify="center">
|
|
55
|
+
<Stack space={2}>
|
|
56
|
+
<Tooltip
|
|
57
|
+
boundaryElement={useBoundaryElement ? boundaryElement : null}
|
|
58
|
+
content={<Text size={1}>{content}</Text>}
|
|
59
|
+
padding={2}
|
|
60
|
+
placement={placement}
|
|
61
|
+
portal={portal}
|
|
62
|
+
>
|
|
63
|
+
<Button mode="bleed" text="Tooltip" />
|
|
64
|
+
</Tooltip>
|
|
65
|
+
</Stack>
|
|
66
|
+
</Flex>
|
|
67
|
+
</Flex>
|
|
68
|
+
</Card>
|
|
69
|
+
</BoundaryElementProvider>
|
|
70
|
+
</Flex>
|
|
71
|
+
|
|
72
|
+
<Card
|
|
73
|
+
border
|
|
74
|
+
margin={4}
|
|
75
|
+
padding={4}
|
|
76
|
+
ref={setPortal1Element}
|
|
77
|
+
style={{
|
|
78
|
+
left: 0,
|
|
79
|
+
position: 'absolute',
|
|
80
|
+
top: 0,
|
|
81
|
+
width: '175px',
|
|
82
|
+
}}
|
|
83
|
+
tone="critical"
|
|
84
|
+
/>
|
|
85
|
+
|
|
86
|
+
<Portal __unstable_name="portal1">
|
|
87
|
+
<Stack space={4}>
|
|
88
|
+
<Text size={1} weight="medium">
|
|
89
|
+
Portal 1 content
|
|
90
|
+
</Text>
|
|
91
|
+
<Text size={1}>
|
|
92
|
+
The tooltip's max-width should not exceed this container's width (minus padding) if it's
|
|
93
|
+
set to use this portal
|
|
94
|
+
</Text>
|
|
95
|
+
</Stack>
|
|
96
|
+
</Portal>
|
|
97
|
+
</PortalProvider>
|
|
98
|
+
)
|
|
99
|
+
}
|
|
@@ -10,5 +10,20 @@ export default defineScope({
|
|
|
10
10
|
title: 'Props',
|
|
11
11
|
component: lazy(() => import('./props')),
|
|
12
12
|
},
|
|
13
|
+
{
|
|
14
|
+
name: 'resizableBoundary',
|
|
15
|
+
title: 'Resizable Boundary',
|
|
16
|
+
component: lazy(() => import('./resizableBoundary')),
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'overflowBoundary',
|
|
20
|
+
title: 'Overflowing Boundary',
|
|
21
|
+
component: lazy(() => import('./overflowingBoundary')),
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'customPortalStory',
|
|
25
|
+
title: 'Custom Portal',
|
|
26
|
+
component: lazy(() => import('./customPortal')),
|
|
27
|
+
},
|
|
13
28
|
],
|
|
14
29
|
})
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {BoundaryElementProvider, Button, Card, Code, Flex, Stack, Text, Tooltip} from '@sanity/ui'
|
|
2
|
+
import {useBoolean, useSelect, useText} from '@sanity/ui-workshop'
|
|
3
|
+
import {useCallback, useState} from 'react'
|
|
4
|
+
import {WORKSHOP_PLACEMENT_OPTIONS} from '../../../__workshop__/constants'
|
|
5
|
+
|
|
6
|
+
export default function OverflowingBoundaryStory() {
|
|
7
|
+
const content = useText(
|
|
8
|
+
'Content',
|
|
9
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut mollis consectetur malesuada. Sed lobortis est dolor, eget imperdiet velit placerat et. Aenean posuere mi non aliquet iaculis. Donec fermentum pulvinar purus at sagittis. Ut tincidunt massa odio, sed finibus justo ullamcorper id. Nam venenatis justo non ligula elementum cursus. Pellentesque laoreet justo in mollis sagittis. In lacinia ornare ultrices. Suspendisse potenti.',
|
|
10
|
+
)
|
|
11
|
+
const placement = useSelect('Placement', WORKSHOP_PLACEMENT_OPTIONS, 'top')
|
|
12
|
+
const portal = useBoolean('Portal', false)
|
|
13
|
+
const useBoundaryElement = useBoolean('Use boundary element', true)
|
|
14
|
+
|
|
15
|
+
const [boundaryElement, setBoundaryElement] = useState<HTMLDivElement | null>(null)
|
|
16
|
+
const [buttonsVisible, setButtonsVisible] = useState(true)
|
|
17
|
+
|
|
18
|
+
const handleHideButtons = useCallback(() => {
|
|
19
|
+
setButtonsVisible(false)
|
|
20
|
+
}, [])
|
|
21
|
+
|
|
22
|
+
const handleShowButtons = useCallback(() => {
|
|
23
|
+
setButtonsVisible(true)
|
|
24
|
+
}, [])
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<Flex align="center" height="fill" justify="center" style={{height: '200vh'}}>
|
|
28
|
+
<BoundaryElementProvider element={useBoundaryElement ? boundaryElement : null}>
|
|
29
|
+
<Card
|
|
30
|
+
border
|
|
31
|
+
ref={setBoundaryElement}
|
|
32
|
+
style={{
|
|
33
|
+
height: 'calc(100vh - 100px)',
|
|
34
|
+
overflow: 'hidden',
|
|
35
|
+
position: 'relative',
|
|
36
|
+
resize: 'both',
|
|
37
|
+
width: '500px',
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<Flex align="center" height="fill" justify="center">
|
|
41
|
+
<Flex justify="center">
|
|
42
|
+
<Stack space={2}>
|
|
43
|
+
<Code size={1}>Placement: {placement}</Code>
|
|
44
|
+
<Button
|
|
45
|
+
disabled={buttonsVisible}
|
|
46
|
+
fontSize={1}
|
|
47
|
+
onClick={handleShowButtons}
|
|
48
|
+
text="Show buttons"
|
|
49
|
+
/>
|
|
50
|
+
</Stack>
|
|
51
|
+
</Flex>
|
|
52
|
+
</Flex>
|
|
53
|
+
|
|
54
|
+
{buttonsVisible && (
|
|
55
|
+
<Tooltip
|
|
56
|
+
content={<Text size={1}>{content}</Text>}
|
|
57
|
+
padding={2}
|
|
58
|
+
placement={placement}
|
|
59
|
+
portal={portal}
|
|
60
|
+
>
|
|
61
|
+
<Button
|
|
62
|
+
mode="bleed"
|
|
63
|
+
onClick={handleHideButtons}
|
|
64
|
+
style={{position: 'absolute', top: 10, right: 10}}
|
|
65
|
+
text="Tooltip"
|
|
66
|
+
/>
|
|
67
|
+
</Tooltip>
|
|
68
|
+
)}
|
|
69
|
+
</Card>
|
|
70
|
+
</BoundaryElementProvider>
|
|
71
|
+
</Flex>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import {BoundaryElementProvider, Button, Card, Code, Flex, Text, Tooltip} from '@sanity/ui'
|
|
2
|
+
import {useBoolean, useSelect, useText} from '@sanity/ui-workshop'
|
|
3
|
+
import {useState} from 'react'
|
|
4
|
+
import {WORKSHOP_PLACEMENT_OPTIONS} from '../../../__workshop__/constants'
|
|
5
|
+
|
|
6
|
+
export default function ResizableBoundaryStory() {
|
|
7
|
+
const content = useText(
|
|
8
|
+
'Content',
|
|
9
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut mollis consectetur malesuada. Sed lobortis est dolor, eget imperdiet velit placerat et. Aenean posuere mi non aliquet iaculis. Donec fermentum pulvinar purus at sagittis. Ut tincidunt massa odio, sed finibus justo ullamcorper id. Nam venenatis justo non ligula elementum cursus. Pellentesque laoreet justo in mollis sagittis. In lacinia ornare ultrices. Suspendisse potenti.',
|
|
10
|
+
)
|
|
11
|
+
const placement = useSelect('Placement', WORKSHOP_PLACEMENT_OPTIONS, 'right')
|
|
12
|
+
const portal = useBoolean('Portal', true)
|
|
13
|
+
const useBoundaryElement = useBoolean('Use boundary element', true)
|
|
14
|
+
|
|
15
|
+
const [boundaryElement, setBoundaryElement] = useState<HTMLDivElement | null>(null)
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Flex align="center" height="fill" justify="center">
|
|
19
|
+
<BoundaryElementProvider element={useBoundaryElement ? boundaryElement : null}>
|
|
20
|
+
<Card
|
|
21
|
+
border
|
|
22
|
+
ref={setBoundaryElement}
|
|
23
|
+
style={{
|
|
24
|
+
height: 'calc(100vh - 100px)',
|
|
25
|
+
overflow: 'hidden',
|
|
26
|
+
position: 'relative',
|
|
27
|
+
resize: 'both',
|
|
28
|
+
width: '500px',
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
<Flex align="center" height="fill" justify="center">
|
|
32
|
+
<Flex justify="center">
|
|
33
|
+
<Code size={1}>Placement: {placement}</Code>
|
|
34
|
+
</Flex>
|
|
35
|
+
</Flex>
|
|
36
|
+
|
|
37
|
+
<Tooltip
|
|
38
|
+
content={<Text size={1}>{content}</Text>}
|
|
39
|
+
padding={2}
|
|
40
|
+
placement={placement}
|
|
41
|
+
portal={portal}
|
|
42
|
+
>
|
|
43
|
+
<Button mode="bleed" style={{position: 'absolute', top: 10, left: 10}} text="Tooltip" />
|
|
44
|
+
</Tooltip>
|
|
45
|
+
<Tooltip
|
|
46
|
+
content={<Text size={1}>{content}</Text>}
|
|
47
|
+
padding={2}
|
|
48
|
+
placement={placement}
|
|
49
|
+
portal={portal}
|
|
50
|
+
>
|
|
51
|
+
<Button
|
|
52
|
+
mode="bleed"
|
|
53
|
+
style={{position: 'absolute', top: 10, right: 10}}
|
|
54
|
+
text="Tooltip"
|
|
55
|
+
/>
|
|
56
|
+
</Tooltip>
|
|
57
|
+
<Tooltip
|
|
58
|
+
content={<Text size={1}>{content}</Text>}
|
|
59
|
+
padding={2}
|
|
60
|
+
placement={placement}
|
|
61
|
+
portal={portal}
|
|
62
|
+
>
|
|
63
|
+
<Button
|
|
64
|
+
mode="bleed"
|
|
65
|
+
style={{position: 'absolute', bottom: 10, left: 10}}
|
|
66
|
+
text="Tooltip"
|
|
67
|
+
/>
|
|
68
|
+
</Tooltip>
|
|
69
|
+
<Tooltip
|
|
70
|
+
content={<Text size={1}>{content}</Text>}
|
|
71
|
+
padding={2}
|
|
72
|
+
placement={placement}
|
|
73
|
+
portal={portal}
|
|
74
|
+
>
|
|
75
|
+
<Button
|
|
76
|
+
mode="bleed"
|
|
77
|
+
style={{position: 'absolute', bottom: 10, right: 10}}
|
|
78
|
+
text="Tooltip"
|
|
79
|
+
/>
|
|
80
|
+
</Tooltip>
|
|
81
|
+
</Card>
|
|
82
|
+
</BoundaryElementProvider>
|
|
83
|
+
</Flex>
|
|
84
|
+
)
|
|
85
|
+
}
|