@sanity/ui 2.14.4 → 2.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks-cjs/_visual-editing.js +60 -42
- package/dist/_chunks-cjs/_visual-editing.js.map +1 -1
- package/dist/_chunks-es/_visual-editing.mjs +60 -42
- package/dist/_chunks-es/_visual-editing.mjs.map +1 -1
- package/dist/_legacy/_visual-editing.esm.js +60 -42
- package/dist/_legacy/_visual-editing.esm.js.map +1 -1
- package/dist/index.d.mts +32 -6
- package/dist/index.d.ts +32 -6
- package/dist/index.esm.js +194 -180
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +192 -178
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +194 -180
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -21
- package/src/core/components/toast/styles.ts +64 -52
- package/src/core/components/toast/toast.tsx +123 -34
- package/src/core/components/toast/toastLayer.tsx +50 -0
- package/src/core/components/toast/toastProvider.tsx +56 -142
- package/src/core/components/toast/types.ts +6 -0
- package/src/core/constants.ts +42 -29
- package/src/core/primitives/popover/popoverCard.tsx +20 -8
- package/src/core/primitives/tooltip/tooltipCard.tsx +7 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"sanity",
|
|
6
6
|
"ui",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"@sanity/icons": "^3.7.0",
|
|
122
122
|
"csstype": "^3.1.3",
|
|
123
123
|
"framer-motion": "^12.4.7",
|
|
124
|
-
"react-compiler-runtime": "19.0.0-beta-
|
|
124
|
+
"react-compiler-runtime": "19.0.0-beta-40c6c23-20250301",
|
|
125
125
|
"react-refractor": "^2.2.0",
|
|
126
126
|
"use-effect-event": "^1.0.2"
|
|
127
127
|
},
|
|
@@ -135,21 +135,21 @@
|
|
|
135
135
|
"@sanity/pkg-utils": "^6.13.4",
|
|
136
136
|
"@sanity/prettier-config": "^1.0.3",
|
|
137
137
|
"@sanity/semantic-release-preset": "^5.0.0",
|
|
138
|
-
"@sanity/ui-workshop": "^2.0.
|
|
139
|
-
"@storybook/addon-a11y": "^8.6.
|
|
140
|
-
"@storybook/addon-docs": "^8.6.
|
|
141
|
-
"@storybook/addon-essentials": "^8.6.
|
|
142
|
-
"@storybook/addon-interactions": "^8.6.
|
|
143
|
-
"@storybook/addon-links": "^8.6.
|
|
144
|
-
"@storybook/addon-mdx-gfm": "^8.6.
|
|
145
|
-
"@storybook/addon-storysource": "^8.6.
|
|
146
|
-
"@storybook/addon-themes": "^8.6.
|
|
147
|
-
"@storybook/blocks": "^8.6.
|
|
148
|
-
"@storybook/manager-api": "^8.6.
|
|
149
|
-
"@storybook/react": "^8.6.
|
|
150
|
-
"@storybook/react-vite": "^8.6.
|
|
151
|
-
"@storybook/test": "^8.6.
|
|
152
|
-
"@storybook/theming": "^8.6.
|
|
138
|
+
"@sanity/ui-workshop": "^2.0.31",
|
|
139
|
+
"@storybook/addon-a11y": "^8.6.3",
|
|
140
|
+
"@storybook/addon-docs": "^8.6.3",
|
|
141
|
+
"@storybook/addon-essentials": "^8.6.3",
|
|
142
|
+
"@storybook/addon-interactions": "^8.6.3",
|
|
143
|
+
"@storybook/addon-links": "^8.6.3",
|
|
144
|
+
"@storybook/addon-mdx-gfm": "^8.6.3",
|
|
145
|
+
"@storybook/addon-storysource": "^8.6.3",
|
|
146
|
+
"@storybook/addon-themes": "^8.6.3",
|
|
147
|
+
"@storybook/blocks": "^8.6.3",
|
|
148
|
+
"@storybook/manager-api": "^8.6.3",
|
|
149
|
+
"@storybook/react": "^8.6.3",
|
|
150
|
+
"@storybook/react-vite": "^8.6.3",
|
|
151
|
+
"@storybook/test": "^8.6.3",
|
|
152
|
+
"@storybook/theming": "^8.6.3",
|
|
153
153
|
"@testing-library/dom": "^10.4.0",
|
|
154
154
|
"@testing-library/jest-dom": "^6.6.3",
|
|
155
155
|
"@testing-library/react": "^16.2.0",
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
165
165
|
"@typescript-eslint/parser": "^7.18.0",
|
|
166
166
|
"@vitejs/plugin-react": "^4.3.4",
|
|
167
|
-
"babel-plugin-react-compiler": "19.0.0-beta-
|
|
167
|
+
"babel-plugin-react-compiler": "19.0.0-beta-40c6c23-20250301",
|
|
168
168
|
"babel-plugin-styled-components": "^2.1.4",
|
|
169
169
|
"commitizen": "^4.3.1",
|
|
170
170
|
"cypress": "^13.17.0",
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
"eslint-plugin-import": "^2.31.0",
|
|
177
177
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
178
178
|
"eslint-plugin-react": "^7.37.4",
|
|
179
|
-
"eslint-plugin-react-compiler": "19.0.0-beta-
|
|
179
|
+
"eslint-plugin-react-compiler": "19.0.0-beta-40c6c23-20250301",
|
|
180
180
|
"eslint-plugin-react-hooks": "experimental",
|
|
181
181
|
"eslint-plugin-storybook": "^0.11.3",
|
|
182
182
|
"http-server": "^14.1.1",
|
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
"lint-staged": "^14.0.1",
|
|
188
188
|
"module-alias": "^2.2.3",
|
|
189
189
|
"npm-run-all2": "^5.0.2",
|
|
190
|
-
"prettier": "^3.5.
|
|
190
|
+
"prettier": "^3.5.3",
|
|
191
191
|
"react": "^19.0.0",
|
|
192
192
|
"react-dom": "^19.0.0",
|
|
193
193
|
"react-is": "^19.0.0",
|
|
@@ -195,7 +195,7 @@
|
|
|
195
195
|
"rimraf": "^5.0.5",
|
|
196
196
|
"semantic-release": "^24.2.3",
|
|
197
197
|
"start-server-and-test": "^2.0.10",
|
|
198
|
-
"storybook": "^8.6.
|
|
198
|
+
"storybook": "^8.6.3",
|
|
199
199
|
"styled-components": "^6.1.15",
|
|
200
200
|
"tsconfig-paths": "^4.2.0",
|
|
201
201
|
"typescript": "5.7.3",
|
|
@@ -1,64 +1,76 @@
|
|
|
1
|
-
import {styled
|
|
1
|
+
import {styled} from 'styled-components'
|
|
2
2
|
import {ThemeColorStateToneKey, getTheme_v2} from '../../../theme'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
3
|
+
import {Card, Flex} from '../../primitives'
|
|
4
|
+
import type {ButtonTone} from '../../types'
|
|
5
|
+
|
|
6
|
+
const LOADING_BAR_HEIGHT = 2
|
|
7
|
+
|
|
8
|
+
export const STATUS_CARD_TONE = {
|
|
9
|
+
error: 'critical',
|
|
10
|
+
warning: 'caution',
|
|
11
|
+
success: 'positive',
|
|
12
|
+
info: 'neutral',
|
|
13
|
+
} satisfies {[key: string]: ThemeColorStateToneKey}
|
|
14
|
+
|
|
15
|
+
export const BUTTON_TONE = {
|
|
16
|
+
error: 'critical',
|
|
17
|
+
warning: 'caution',
|
|
18
|
+
success: 'positive',
|
|
19
|
+
info: 'neutral',
|
|
20
|
+
} satisfies {[key: string]: ButtonTone}
|
|
6
21
|
|
|
7
22
|
export const TextBox = styled(Flex)`
|
|
8
23
|
overflow-x: auto;
|
|
9
24
|
`
|
|
10
25
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
26
|
+
export const StyledToast = styled(Card)`
|
|
27
|
+
pointer-events: all;
|
|
28
|
+
width: 100%;
|
|
29
|
+
position: relative;
|
|
30
|
+
overflow: hidden;
|
|
31
|
+
overflow: clip;
|
|
32
|
+
|
|
33
|
+
&[data-has-duration] {
|
|
34
|
+
padding-bottom: calc(${LOADING_BAR_HEIGHT}px / 2);
|
|
17
35
|
}
|
|
18
36
|
`
|
|
19
37
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
`
|
|
38
|
+
export const LoadingBar = styled.div`
|
|
39
|
+
display: flex;
|
|
40
|
+
position: absolute;
|
|
41
|
+
bottom: 0px;
|
|
42
|
+
top: 0px;
|
|
43
|
+
left: 0px;
|
|
44
|
+
right: 0px;
|
|
45
|
+
pointer-events: none;
|
|
46
|
+
z-index: -1;
|
|
47
|
+
overflow: hidden;
|
|
48
|
+
overflow: clip;
|
|
49
|
+
background: transparent;
|
|
50
|
+
align-items: flex-end;
|
|
51
|
+
will-change: opacity;
|
|
52
|
+
`
|
|
37
53
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
content: '';
|
|
47
|
-
position: absolute;
|
|
48
|
-
bottom: 0px;
|
|
49
|
-
height: ${LOADING_BAR_HEIGHT}px;
|
|
50
|
-
background: ${loadingBarColor};
|
|
51
|
-
animation-name: ${loadingAnimation};
|
|
52
|
-
animation-duration: ${props.$duration}ms;
|
|
53
|
-
animation-fill-mode: both;
|
|
54
|
-
animation-timing-function: linear;
|
|
55
|
-
opacity: var(${POPOVER_MOTION_CONTENT_OPACITY_PROPERTY}, 1);
|
|
56
|
-
will-change: width;
|
|
57
|
-
}
|
|
54
|
+
export const LoadingBarMask = styled(Card)`
|
|
55
|
+
position: absolute;
|
|
56
|
+
top: 0;
|
|
57
|
+
left: -${LOADING_BAR_HEIGHT}px;
|
|
58
|
+
right: -${LOADING_BAR_HEIGHT}px;
|
|
59
|
+
bottom: ${LOADING_BAR_HEIGHT}px;
|
|
60
|
+
z-index: 1;
|
|
61
|
+
`
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
will-change: opacity;
|
|
62
|
-
}
|
|
63
|
-
`
|
|
63
|
+
type LoadingBarProgressProps = Omit<React.ComponentProps<typeof Card>, 'tone'> & {
|
|
64
|
+
tone: ThemeColorStateToneKey
|
|
64
65
|
}
|
|
66
|
+
export const LoadingBarProgress = styled<React.ComponentType<LoadingBarProgressProps>>(Card)`
|
|
67
|
+
display: block;
|
|
68
|
+
height: 100%;
|
|
69
|
+
width: 100%;
|
|
70
|
+
transform-origin: 0% 50%;
|
|
71
|
+
background-color: ${(props) => {
|
|
72
|
+
const {color} = getTheme_v2(props.theme)
|
|
73
|
+
|
|
74
|
+
return color.button.default[props.tone].enabled.bg
|
|
75
|
+
}};
|
|
76
|
+
`
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import {CloseIcon} from '@sanity/icons'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {Box, Button, Flex, Stack, Text
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
|
|
2
|
+
import {motion, type Variant, type Variants} from 'framer-motion'
|
|
3
|
+
import {usePrefersReducedMotion} from '../../hooks/usePrefersReducedMotion'
|
|
4
|
+
import {Box, Button, Flex, Stack, Text} from '../../primitives'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
LoadingBar,
|
|
8
|
+
LoadingBarProgress,
|
|
9
|
+
BUTTON_TONE,
|
|
10
|
+
STATUS_CARD_TONE,
|
|
11
|
+
TextBox,
|
|
12
|
+
StyledToast,
|
|
13
|
+
LoadingBarMask,
|
|
14
|
+
} from './styles'
|
|
8
15
|
|
|
9
16
|
/**
|
|
10
17
|
* @public
|
|
@@ -12,27 +19,14 @@ import {rootStyles, TextBox} from './styles'
|
|
|
12
19
|
export interface ToastProps {
|
|
13
20
|
closable?: boolean
|
|
14
21
|
description?: React.ReactNode
|
|
15
|
-
onClose
|
|
22
|
+
onClose: () => void
|
|
16
23
|
radius?: number | number[]
|
|
17
24
|
title?: React.ReactNode
|
|
18
25
|
status?: 'error' | 'warning' | 'success' | 'info'
|
|
19
26
|
duration?: number
|
|
27
|
+
updatedAt?: number
|
|
20
28
|
}
|
|
21
29
|
|
|
22
|
-
const STATUS_CARD_TONE: {[key: string]: ThemeColorStateToneKey} = {
|
|
23
|
-
error: 'critical',
|
|
24
|
-
warning: 'caution',
|
|
25
|
-
success: 'positive',
|
|
26
|
-
info: 'neutral',
|
|
27
|
-
} as const
|
|
28
|
-
|
|
29
|
-
const BUTTON_TONE = {
|
|
30
|
-
error: 'critical',
|
|
31
|
-
warning: 'caution',
|
|
32
|
-
success: 'positive',
|
|
33
|
-
info: 'neutral',
|
|
34
|
-
} satisfies {[key: string]: ButtonTone}
|
|
35
|
-
|
|
36
30
|
const ROLES = {
|
|
37
31
|
error: 'alert',
|
|
38
32
|
warning: 'alert',
|
|
@@ -40,9 +34,9 @@ const ROLES = {
|
|
|
40
34
|
info: 'alert',
|
|
41
35
|
} as const
|
|
42
36
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
// Support pattern used by Sanity Studio, that works around the lack of `duration: Infinity` support in older @sanity/ui versions
|
|
38
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value
|
|
39
|
+
const LONG_ENOUGH_BUT_NOT_TOO_LONG = 1000 * 60 * 60 * 24 * 24
|
|
46
40
|
|
|
47
41
|
/**
|
|
48
42
|
* The `Toast` component gives feedback to users when an action has taken place.
|
|
@@ -52,25 +46,63 @@ const StyledToast = styled(Card)<{$duration?: number; tone: ThemeColorStateToneK
|
|
|
52
46
|
* @public
|
|
53
47
|
*/
|
|
54
48
|
export function Toast(
|
|
55
|
-
props: ToastProps &
|
|
49
|
+
props: ToastProps &
|
|
50
|
+
Omit<
|
|
51
|
+
React.HTMLProps<HTMLDivElement>,
|
|
52
|
+
| 'as'
|
|
53
|
+
| 'height'
|
|
54
|
+
| 'ref'
|
|
55
|
+
| 'title'
|
|
56
|
+
| 'onAnimationStart'
|
|
57
|
+
| 'onDragStart'
|
|
58
|
+
| 'onDragEnd'
|
|
59
|
+
| 'onDrag'
|
|
60
|
+
>,
|
|
56
61
|
): React.JSX.Element {
|
|
57
|
-
const {
|
|
62
|
+
const {
|
|
63
|
+
closable,
|
|
64
|
+
description,
|
|
65
|
+
duration,
|
|
66
|
+
onClose,
|
|
67
|
+
radius = 3,
|
|
68
|
+
title,
|
|
69
|
+
status,
|
|
70
|
+
updatedAt,
|
|
71
|
+
...restProps
|
|
72
|
+
} = props
|
|
58
73
|
const cardTone = status ? STATUS_CARD_TONE[status] : 'default'
|
|
59
74
|
const buttonTone = status ? BUTTON_TONE[status] : 'default'
|
|
60
75
|
const role = status ? ROLES[status] : 'status'
|
|
61
76
|
|
|
77
|
+
const prefersReducedMotion = usePrefersReducedMotion()
|
|
78
|
+
|
|
79
|
+
const visualDuration: number = prefersReducedMotion ? 0 : 0.26
|
|
80
|
+
const transition = visualDuration ? {type: 'spring', visualDuration, bounce: 0.25} : {duration: 0}
|
|
81
|
+
|
|
82
|
+
const hasDuration = duration && isFinite(duration) && duration < LONG_ENOUGH_BUT_NOT_TOO_LONG
|
|
83
|
+
const initial: ContainerVariants[] = ['hidden', 'initial']
|
|
84
|
+
const animate: ContainerVariants[] = ['visible', 'slideIn']
|
|
85
|
+
const exit: ContainerVariants[] = ['hidden', 'slideOut']
|
|
86
|
+
|
|
62
87
|
return (
|
|
63
|
-
<
|
|
88
|
+
<MotionToast
|
|
64
89
|
data-ui="Toast"
|
|
65
90
|
role={role}
|
|
66
91
|
{...restProps}
|
|
67
|
-
|
|
92
|
+
data-has-duration={hasDuration ? '' : undefined}
|
|
93
|
+
custom={visualDuration}
|
|
68
94
|
radius={radius}
|
|
69
95
|
shadow={2}
|
|
70
96
|
tone={cardTone}
|
|
71
|
-
|
|
97
|
+
forwardedAs="li"
|
|
98
|
+
layout="position"
|
|
99
|
+
variants={container}
|
|
100
|
+
initial={initial}
|
|
101
|
+
animate={animate}
|
|
102
|
+
exit={exit}
|
|
103
|
+
transition={transition}
|
|
72
104
|
>
|
|
73
|
-
<
|
|
105
|
+
<MotionFlex align="flex-start" variants={content} transition={transition}>
|
|
74
106
|
<TextBox flex={1} padding={3}>
|
|
75
107
|
<Stack space={3}>
|
|
76
108
|
{title && (
|
|
@@ -79,9 +111,9 @@ export function Toast(
|
|
|
79
111
|
</Text>
|
|
80
112
|
)}
|
|
81
113
|
{description && (
|
|
82
|
-
<
|
|
114
|
+
<MotionText muted size={1} variants={content} transition={transition}>
|
|
83
115
|
{description}
|
|
84
|
-
</
|
|
116
|
+
</MotionText>
|
|
85
117
|
)}
|
|
86
118
|
</Stack>
|
|
87
119
|
</TextBox>
|
|
@@ -99,9 +131,66 @@ export function Toast(
|
|
|
99
131
|
/>
|
|
100
132
|
</Box>
|
|
101
133
|
)}
|
|
102
|
-
</
|
|
103
|
-
|
|
134
|
+
</MotionFlex>
|
|
135
|
+
{hasDuration && (
|
|
136
|
+
<MotionLoadingBar variants={content} transition={transition}>
|
|
137
|
+
<LoadingBarMask tone={cardTone} radius={radius} />
|
|
138
|
+
<MotionLoadingBarProgress
|
|
139
|
+
key={`progress-${updatedAt}`}
|
|
140
|
+
tone={cardTone}
|
|
141
|
+
initial={{scaleX: 0}}
|
|
142
|
+
animate={{scaleX: 1}}
|
|
143
|
+
transition={{delay: visualDuration, duration: duration / 1_000, ease: 'linear'}}
|
|
144
|
+
onAnimationComplete={onClose}
|
|
145
|
+
/>
|
|
146
|
+
</MotionLoadingBar>
|
|
147
|
+
)}
|
|
148
|
+
</MotionToast>
|
|
104
149
|
)
|
|
105
150
|
}
|
|
106
151
|
|
|
107
152
|
Toast.displayName = 'Toast'
|
|
153
|
+
|
|
154
|
+
const container = {
|
|
155
|
+
initial: {y: 32, scale: 0.5, zIndex: 1},
|
|
156
|
+
hidden: {opacity: 0},
|
|
157
|
+
visible: (visualDuration: number) => {
|
|
158
|
+
if (!visualDuration) return {opacity: 1}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
opacity: 1,
|
|
162
|
+
transition: {
|
|
163
|
+
when: 'beforeChildren',
|
|
164
|
+
staggerChildren: visualDuration / 3,
|
|
165
|
+
duration: visualDuration / 3,
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
slideIn: {
|
|
170
|
+
y: 0,
|
|
171
|
+
scale: 1,
|
|
172
|
+
},
|
|
173
|
+
slideOut: {
|
|
174
|
+
zIndex: 0,
|
|
175
|
+
scale: 0.75,
|
|
176
|
+
},
|
|
177
|
+
} satisfies Variants
|
|
178
|
+
type ContainerVariants = keyof typeof container
|
|
179
|
+
|
|
180
|
+
const content = {
|
|
181
|
+
initial: {
|
|
182
|
+
willChange: 'transform',
|
|
183
|
+
},
|
|
184
|
+
hidden: {
|
|
185
|
+
opacity: 0,
|
|
186
|
+
},
|
|
187
|
+
visible: {
|
|
188
|
+
opacity: 1,
|
|
189
|
+
},
|
|
190
|
+
} satisfies Partial<Record<ContainerVariants, Variant>>
|
|
191
|
+
|
|
192
|
+
const MotionToast = motion.create(StyledToast)
|
|
193
|
+
const MotionFlex = motion.create(Flex)
|
|
194
|
+
const MotionText = motion.create(Text)
|
|
195
|
+
const MotionLoadingBar = motion.create(LoadingBar)
|
|
196
|
+
const MotionLoadingBarProgress = motion.create(LoadingBarProgress)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {styled} from 'styled-components'
|
|
2
|
+
import {Grid} from '../../primitives/grid'
|
|
3
|
+
import {useLayer} from '../../utils'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export interface ToastLayerProps {
|
|
9
|
+
children: React.ReactNode
|
|
10
|
+
padding?: number | number[]
|
|
11
|
+
paddingX?: number | number[]
|
|
12
|
+
paddingY?: number | number[]
|
|
13
|
+
gap?: number | number[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export function ToastLayer(props: ToastLayerProps): React.JSX.Element {
|
|
20
|
+
const {children, padding = 4, paddingX, paddingY, gap = 3} = props
|
|
21
|
+
const {zIndex} = useLayer()
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<StyledLayer
|
|
25
|
+
forwardedAs="ul"
|
|
26
|
+
data-ui="ToastProvider"
|
|
27
|
+
padding={padding}
|
|
28
|
+
paddingX={paddingX}
|
|
29
|
+
paddingY={paddingY}
|
|
30
|
+
gap={gap}
|
|
31
|
+
columns={1}
|
|
32
|
+
style={{zIndex}}
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
</StyledLayer>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
ToastLayer.displayName = 'ToastLayer'
|
|
40
|
+
|
|
41
|
+
const StyledLayer = styled(Grid)`
|
|
42
|
+
box-sizing: border-box;
|
|
43
|
+
position: fixed;
|
|
44
|
+
right: 0;
|
|
45
|
+
bottom: 0;
|
|
46
|
+
list-style: none;
|
|
47
|
+
pointer-events: none;
|
|
48
|
+
max-width: 420px;
|
|
49
|
+
width: 100%;
|
|
50
|
+
`
|