@sanity/ui 2.14.2 → 2.14.4-canary.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 +86 -66
- package/dist/_chunks-cjs/_visual-editing.js.map +1 -1
- package/dist/_chunks-es/_visual-editing.mjs +86 -66
- package/dist/_chunks-es/_visual-editing.mjs.map +1 -1
- package/dist/_legacy/_visual-editing.esm.js +86 -66
- package/dist/_legacy/_visual-editing.esm.js.map +1 -1
- package/dist/index.d.mts +26 -6
- package/dist/index.d.ts +26 -6
- package/dist/index.esm.js +162 -174
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +159 -171
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +162 -174
- package/dist/index.mjs.map +1 -1
- package/package.json +44 -58
- package/src/core/components/toast/styles.ts +57 -53
- package/src/core/components/toast/toast.tsx +127 -34
- package/src/core/components/toast/toastLayer.tsx +50 -0
- package/src/core/components/toast/toastProvider.tsx +27 -124
- package/src/core/constants.ts +42 -29
- package/src/core/hooks/useDelayedState.ts +2 -1
- package/src/core/primitives/grid/grid.tsx +1 -0
- package/src/core/primitives/popover/popoverCard.tsx +20 -8
- package/src/core/primitives/tooltip/tooltip.tsx +24 -61
- package/src/core/primitives/tooltip/tooltipCard.tsx +7 -6
- package/src/core/utils/layer/layer.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/ui",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.4-canary.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"sanity",
|
|
6
6
|
"ui",
|
|
@@ -61,32 +61,6 @@
|
|
|
61
61
|
"_visual-editing.js",
|
|
62
62
|
"theme.js"
|
|
63
63
|
],
|
|
64
|
-
"scripts": {
|
|
65
|
-
"build": "run-s clean pkg:build pkg:check figma:pkg:build",
|
|
66
|
-
"clean": "rimraf .workshop dist",
|
|
67
|
-
"commit": "cz",
|
|
68
|
-
"cypress:dev": "run-p dev cypress:open",
|
|
69
|
-
"cypress:open": "cypress open",
|
|
70
|
-
"cypress:run": "cypress run",
|
|
71
|
-
"dev": "run-p storybook:dev workshop:dev",
|
|
72
|
-
"figma:pkg:build": "cd figma && pnpm build",
|
|
73
|
-
"format": "prettier --write --cache --ignore-unknown .",
|
|
74
|
-
"lint": "eslint . --ext .cjs,.js,.jsx,.mjs,.ts,.tsx",
|
|
75
|
-
"pkg:build": "pkg build --strict",
|
|
76
|
-
"pkg:check": "pkg --strict",
|
|
77
|
-
"prepare": "husky install",
|
|
78
|
-
"prepack": "pnpm build",
|
|
79
|
-
"release": "semantic-release",
|
|
80
|
-
"storybook:build": "storybook build",
|
|
81
|
-
"storybook:dev": "storybook dev -p 6006",
|
|
82
|
-
"test": "jest",
|
|
83
|
-
"test:browser": "start-server-and-test 'run-s workshop:build workshop:start' http://localhost:1337 'run-s cypress:run'",
|
|
84
|
-
"ts:check": "tsc",
|
|
85
|
-
"watch": "pkg watch --strict",
|
|
86
|
-
"workshop:build": "workshop build",
|
|
87
|
-
"workshop:dev": "workshop dev",
|
|
88
|
-
"workshop:start": "http-server -a localhost -c-0 -p 1337 -s -P http://localhost:1337/index.html? dist"
|
|
89
|
-
},
|
|
90
64
|
"commitlint": {
|
|
91
65
|
"extends": [
|
|
92
66
|
"@commitlint/config-conventional"
|
|
@@ -120,7 +94,7 @@
|
|
|
120
94
|
"@sanity/color": "^3.0.6",
|
|
121
95
|
"@sanity/icons": "^3.6.0",
|
|
122
96
|
"csstype": "^3.1.3",
|
|
123
|
-
"framer-motion": "^12.4.
|
|
97
|
+
"framer-motion": "^12.4.7",
|
|
124
98
|
"react-compiler-runtime": "19.0.0-beta-e1e972c-20250221",
|
|
125
99
|
"react-refractor": "^2.2.0",
|
|
126
100
|
"use-effect-event": "^1.0.2"
|
|
@@ -135,21 +109,21 @@
|
|
|
135
109
|
"@sanity/pkg-utils": "^6.13.4",
|
|
136
110
|
"@sanity/prettier-config": "^1.0.3",
|
|
137
111
|
"@sanity/semantic-release-preset": "^5.0.0",
|
|
138
|
-
"@sanity/ui-workshop": "^2.0.
|
|
139
|
-
"@storybook/addon-a11y": "^8.
|
|
140
|
-
"@storybook/addon-docs": "^8.
|
|
141
|
-
"@storybook/addon-essentials": "^8.
|
|
142
|
-
"@storybook/addon-interactions": "^8.
|
|
143
|
-
"@storybook/addon-links": "^8.
|
|
144
|
-
"@storybook/addon-mdx-gfm": "^8.
|
|
145
|
-
"@storybook/addon-storysource": "^8.
|
|
146
|
-
"@storybook/addon-themes": "^8.
|
|
147
|
-
"@storybook/blocks": "^8.
|
|
148
|
-
"@storybook/manager-api": "^8.
|
|
149
|
-
"@storybook/react": "^8.
|
|
150
|
-
"@storybook/react-vite": "^8.
|
|
151
|
-
"@storybook/test": "^8.
|
|
152
|
-
"@storybook/theming": "^8.
|
|
112
|
+
"@sanity/ui-workshop": "^2.0.30",
|
|
113
|
+
"@storybook/addon-a11y": "^8.6.2",
|
|
114
|
+
"@storybook/addon-docs": "^8.6.2",
|
|
115
|
+
"@storybook/addon-essentials": "^8.6.2",
|
|
116
|
+
"@storybook/addon-interactions": "^8.6.2",
|
|
117
|
+
"@storybook/addon-links": "^8.6.2",
|
|
118
|
+
"@storybook/addon-mdx-gfm": "^8.6.2",
|
|
119
|
+
"@storybook/addon-storysource": "^8.6.2",
|
|
120
|
+
"@storybook/addon-themes": "^8.6.2",
|
|
121
|
+
"@storybook/blocks": "^8.6.2",
|
|
122
|
+
"@storybook/manager-api": "^8.6.2",
|
|
123
|
+
"@storybook/react": "^8.6.2",
|
|
124
|
+
"@storybook/react-vite": "^8.6.2",
|
|
125
|
+
"@storybook/test": "^8.6.2",
|
|
126
|
+
"@storybook/theming": "^8.6.2",
|
|
153
127
|
"@testing-library/dom": "^10.4.0",
|
|
154
128
|
"@testing-library/jest-dom": "^6.6.3",
|
|
155
129
|
"@testing-library/react": "^16.2.0",
|
|
@@ -171,7 +145,7 @@
|
|
|
171
145
|
"cypress-real-events": "^1.14.0",
|
|
172
146
|
"cz-conventional-changelog": "^3.3.0",
|
|
173
147
|
"eslint": "^8.57.1",
|
|
174
|
-
"eslint-config-prettier": "^10.0.
|
|
148
|
+
"eslint-config-prettier": "^10.0.2",
|
|
175
149
|
"eslint-plugin-boundaries": "^5.0.1",
|
|
176
150
|
"eslint-plugin-import": "^2.31.0",
|
|
177
151
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
@@ -195,7 +169,7 @@
|
|
|
195
169
|
"rimraf": "^5.0.5",
|
|
196
170
|
"semantic-release": "^24.2.3",
|
|
197
171
|
"start-server-and-test": "^2.0.10",
|
|
198
|
-
"storybook": "^8.
|
|
172
|
+
"storybook": "^8.6.2",
|
|
199
173
|
"styled-components": "^6.1.15",
|
|
200
174
|
"tsconfig-paths": "^4.2.0",
|
|
201
175
|
"typescript": "5.7.3",
|
|
@@ -208,25 +182,37 @@
|
|
|
208
182
|
"react-is": "^18 || >=19.0.0-0",
|
|
209
183
|
"styled-components": "^5.2 || ^6"
|
|
210
184
|
},
|
|
211
|
-
"packageManager": "pnpm@9.15.5",
|
|
212
185
|
"engines": {
|
|
213
186
|
"node": ">=14.0.0"
|
|
214
187
|
},
|
|
215
188
|
"publishConfig": {
|
|
216
189
|
"access": "public"
|
|
217
190
|
},
|
|
218
|
-
"pnpm": {
|
|
219
|
-
"overrides": {
|
|
220
|
-
"@types/react": "$@types/react",
|
|
221
|
-
"@types/react-dom": "$@types/react-dom",
|
|
222
|
-
"@types/react-is": "$@types/react-is",
|
|
223
|
-
"conventional-changelog-conventionalcommits": ">= 8.0.0",
|
|
224
|
-
"react": "$react",
|
|
225
|
-
"react-dom": "$react-dom",
|
|
226
|
-
"react-is": "$react-is"
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
191
|
"esm.sh": {
|
|
230
192
|
"bundle": false
|
|
193
|
+
},
|
|
194
|
+
"scripts": {
|
|
195
|
+
"build": "run-s clean pkg:build pkg:check figma:pkg:build",
|
|
196
|
+
"clean": "rimraf .workshop dist",
|
|
197
|
+
"commit": "cz",
|
|
198
|
+
"cypress:dev": "run-p dev cypress:open",
|
|
199
|
+
"cypress:open": "cypress open",
|
|
200
|
+
"cypress:run": "cypress run",
|
|
201
|
+
"dev": "run-p storybook:dev workshop:dev",
|
|
202
|
+
"figma:pkg:build": "cd figma && pnpm build",
|
|
203
|
+
"format": "prettier --write --cache --ignore-unknown .",
|
|
204
|
+
"lint": "eslint . --ext .cjs,.js,.jsx,.mjs,.ts,.tsx",
|
|
205
|
+
"pkg:build": "pkg build --strict",
|
|
206
|
+
"pkg:check": "pkg --strict",
|
|
207
|
+
"release": "semantic-release",
|
|
208
|
+
"storybook:build": "storybook build",
|
|
209
|
+
"storybook:dev": "storybook dev -p 6006",
|
|
210
|
+
"test": "jest",
|
|
211
|
+
"test:browser": "start-server-and-test 'run-s workshop:build workshop:start' http://localhost:1337 'run-s cypress:run'",
|
|
212
|
+
"ts:check": "tsc",
|
|
213
|
+
"watch": "pkg watch --strict",
|
|
214
|
+
"workshop:build": "workshop build",
|
|
215
|
+
"workshop:dev": "workshop dev",
|
|
216
|
+
"workshop:start": "http-server -a localhost -c-0 -p 1337 -s -P http://localhost:1337/index.html? dist"
|
|
231
217
|
}
|
|
232
|
-
}
|
|
218
|
+
}
|
|
@@ -1,64 +1,68 @@
|
|
|
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
|
+
will-change: opacity, transform;
|
|
33
|
+
|
|
34
|
+
&[data-has-duration] {
|
|
35
|
+
padding-bottom: calc(${LOADING_BAR_HEIGHT}px / 2);
|
|
17
36
|
}
|
|
18
37
|
`
|
|
19
38
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
`
|
|
37
|
-
|
|
38
|
-
return css`
|
|
39
|
-
pointer-events: all;
|
|
40
|
-
width: 100%;
|
|
41
|
-
position: relative;
|
|
42
|
-
overflow: hidden;
|
|
43
|
-
overflow: clip;
|
|
44
|
-
padding-bottom: ${LOADING_BAR_HEIGHT}px;
|
|
45
|
-
&::before {
|
|
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
|
-
}
|
|
39
|
+
export const LoadingBar = styled.div`
|
|
40
|
+
display: flex;
|
|
41
|
+
position: absolute;
|
|
42
|
+
bottom: 0px;
|
|
43
|
+
top: 0px;
|
|
44
|
+
left: 0px;
|
|
45
|
+
right: 0px;
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
z-index: -1;
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
overflow: clip;
|
|
50
|
+
background: transparent;
|
|
51
|
+
align-items: flex-end;
|
|
52
|
+
will-change: opacity;
|
|
53
|
+
`
|
|
58
54
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
will-change: opacity;
|
|
62
|
-
}
|
|
63
|
-
`
|
|
55
|
+
type LoadingBarProgressProps = Omit<React.ComponentProps<typeof Card>, 'tone'> & {
|
|
56
|
+
tone: ThemeColorStateToneKey
|
|
64
57
|
}
|
|
58
|
+
export const LoadingBarProgress = styled<React.ComponentType<LoadingBarProgressProps>>(Card)`
|
|
59
|
+
display: block;
|
|
60
|
+
height: 100%;
|
|
61
|
+
width: 100%;
|
|
62
|
+
transform-origin: 0% 50%;
|
|
63
|
+
background-color: ${(props) => {
|
|
64
|
+
const {color} = getTheme_v2(props.theme)
|
|
65
|
+
|
|
66
|
+
return color.button.default[props.tone].enabled.bg
|
|
67
|
+
}};
|
|
68
|
+
`
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import {CloseIcon} from '@sanity/icons'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import {motion, type Variants} from 'framer-motion'
|
|
3
|
+
import {usePrefersReducedMotion} from '../../hooks/usePrefersReducedMotion'
|
|
4
4
|
import {Box, Button, Flex, Stack, Text, Card} from '../../primitives'
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
LoadingBar,
|
|
8
|
+
LoadingBarProgress,
|
|
9
|
+
BUTTON_TONE,
|
|
10
|
+
STATUS_CARD_TONE,
|
|
11
|
+
TextBox,
|
|
12
|
+
StyledToast,
|
|
13
|
+
} from './styles'
|
|
8
14
|
|
|
9
15
|
/**
|
|
10
16
|
* @public
|
|
@@ -12,27 +18,14 @@ import {rootStyles, TextBox} from './styles'
|
|
|
12
18
|
export interface ToastProps {
|
|
13
19
|
closable?: boolean
|
|
14
20
|
description?: React.ReactNode
|
|
15
|
-
onClose
|
|
21
|
+
onClose: () => void
|
|
16
22
|
radius?: number | number[]
|
|
17
23
|
title?: React.ReactNode
|
|
18
24
|
status?: 'error' | 'warning' | 'success' | 'info'
|
|
19
25
|
duration?: number
|
|
26
|
+
updatedAt?: number
|
|
20
27
|
}
|
|
21
28
|
|
|
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
29
|
const ROLES = {
|
|
37
30
|
error: 'alert',
|
|
38
31
|
warning: 'alert',
|
|
@@ -40,10 +33,6 @@ const ROLES = {
|
|
|
40
33
|
info: 'alert',
|
|
41
34
|
} as const
|
|
42
35
|
|
|
43
|
-
const StyledToast = styled(Card)<{$duration?: number; tone: ThemeColorStateToneKey} & ThemeProps>(
|
|
44
|
-
rootStyles,
|
|
45
|
-
)
|
|
46
|
-
|
|
47
36
|
/**
|
|
48
37
|
* The `Toast` component gives feedback to users when an action has taken place.
|
|
49
38
|
*
|
|
@@ -52,25 +41,62 @@ const StyledToast = styled(Card)<{$duration?: number; tone: ThemeColorStateToneK
|
|
|
52
41
|
* @public
|
|
53
42
|
*/
|
|
54
43
|
export function Toast(
|
|
55
|
-
props: ToastProps &
|
|
44
|
+
props: ToastProps &
|
|
45
|
+
Omit<
|
|
46
|
+
React.HTMLProps<HTMLDivElement>,
|
|
47
|
+
| 'as'
|
|
48
|
+
| 'height'
|
|
49
|
+
| 'ref'
|
|
50
|
+
| 'title'
|
|
51
|
+
| 'onAnimationStart'
|
|
52
|
+
| 'onDragStart'
|
|
53
|
+
| 'onDragEnd'
|
|
54
|
+
| 'onDrag'
|
|
55
|
+
>,
|
|
56
56
|
): React.JSX.Element {
|
|
57
|
-
const {
|
|
57
|
+
const {
|
|
58
|
+
closable,
|
|
59
|
+
description,
|
|
60
|
+
duration,
|
|
61
|
+
onClose,
|
|
62
|
+
radius = 3,
|
|
63
|
+
title,
|
|
64
|
+
status,
|
|
65
|
+
updatedAt,
|
|
66
|
+
...restProps
|
|
67
|
+
} = props
|
|
58
68
|
const cardTone = status ? STATUS_CARD_TONE[status] : 'default'
|
|
59
69
|
const buttonTone = status ? BUTTON_TONE[status] : 'default'
|
|
60
70
|
const role = status ? ROLES[status] : 'status'
|
|
61
71
|
|
|
72
|
+
const prefersReducedMotion = usePrefersReducedMotion()
|
|
73
|
+
|
|
74
|
+
// eslint-disable-next-line prefer-const
|
|
75
|
+
let visualDuration = prefersReducedMotion ? 0 : 0.26
|
|
76
|
+
// visualDuration = 5
|
|
77
|
+
const transition = visualDuration ? {type: 'spring', visualDuration, bounce: 0.25} : {duration: 0}
|
|
78
|
+
|
|
79
|
+
const hasDuration = duration && isFinite(duration)
|
|
80
|
+
|
|
62
81
|
return (
|
|
63
|
-
<
|
|
82
|
+
<MotionToast
|
|
64
83
|
data-ui="Toast"
|
|
65
84
|
role={role}
|
|
66
85
|
{...restProps}
|
|
67
|
-
|
|
86
|
+
data-has-duration={hasDuration ? '' : undefined}
|
|
87
|
+
custom={visualDuration satisfies number}
|
|
68
88
|
radius={radius}
|
|
69
89
|
shadow={2}
|
|
70
90
|
tone={cardTone}
|
|
71
|
-
|
|
91
|
+
forwardedAs="li"
|
|
92
|
+
layout="position"
|
|
93
|
+
variants={container}
|
|
94
|
+
initial={['hidden', 'initial'] satisfies ContainerVariants[]}
|
|
95
|
+
animate={['visible', 'slideIn'] satisfies ContainerVariants[]}
|
|
96
|
+
exit={['hidden', 'slideOut'] satisfies ContainerVariants[]}
|
|
97
|
+
transition={transition}
|
|
72
98
|
>
|
|
73
|
-
<
|
|
99
|
+
<MotionFlex align="flex-start" variants={content} transition={transition}>
|
|
74
100
|
<TextBox flex={1} padding={3}>
|
|
75
101
|
<Stack space={3}>
|
|
76
102
|
{title && (
|
|
@@ -79,9 +105,9 @@ export function Toast(
|
|
|
79
105
|
</Text>
|
|
80
106
|
)}
|
|
81
107
|
{description && (
|
|
82
|
-
<
|
|
108
|
+
<MotionText muted size={1} variants={content} transition={transition}>
|
|
83
109
|
{description}
|
|
84
|
-
</
|
|
110
|
+
</MotionText>
|
|
85
111
|
)}
|
|
86
112
|
</Stack>
|
|
87
113
|
</TextBox>
|
|
@@ -99,9 +125,76 @@ export function Toast(
|
|
|
99
125
|
/>
|
|
100
126
|
</Box>
|
|
101
127
|
)}
|
|
102
|
-
</
|
|
103
|
-
|
|
128
|
+
</MotionFlex>
|
|
129
|
+
{hasDuration && (
|
|
130
|
+
<MotionLoadiongBar variants={content} transition={transition}>
|
|
131
|
+
<Card
|
|
132
|
+
tone={cardTone}
|
|
133
|
+
radius={radius}
|
|
134
|
+
style={{
|
|
135
|
+
position: 'absolute',
|
|
136
|
+
right: -2,
|
|
137
|
+
left: -2,
|
|
138
|
+
top: 0,
|
|
139
|
+
bottom: 2,
|
|
140
|
+
zIndex: 1,
|
|
141
|
+
}}
|
|
142
|
+
/>
|
|
143
|
+
<MotionLoadiongBarProgress
|
|
144
|
+
key={`${duration}-${updatedAt}`}
|
|
145
|
+
tone={cardTone}
|
|
146
|
+
initial={{scaleX: 0}}
|
|
147
|
+
animate={{scaleX: 1}}
|
|
148
|
+
transition={{delay: visualDuration, duration: duration / 1_000, ease: 'linear'}}
|
|
149
|
+
onAnimationComplete={onClose}
|
|
150
|
+
/>
|
|
151
|
+
</MotionLoadiongBar>
|
|
152
|
+
)}
|
|
153
|
+
</MotionToast>
|
|
104
154
|
)
|
|
105
155
|
}
|
|
106
156
|
|
|
107
157
|
Toast.displayName = 'Toast'
|
|
158
|
+
|
|
159
|
+
const container = {
|
|
160
|
+
initial: {y: 32, scale: 0.5, zIndex: 1},
|
|
161
|
+
hidden: {opacity: 0},
|
|
162
|
+
visible: (visualDuration: number) => {
|
|
163
|
+
if (!visualDuration) return {opacity: 1}
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
opacity: 1,
|
|
167
|
+
transition: {
|
|
168
|
+
when: 'beforeChildren',
|
|
169
|
+
staggerChildren: visualDuration / 3,
|
|
170
|
+
duration: visualDuration / 3,
|
|
171
|
+
},
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
slideIn: {
|
|
175
|
+
y: 0,
|
|
176
|
+
scale: 1,
|
|
177
|
+
},
|
|
178
|
+
slideOut: {
|
|
179
|
+
zIndex: 0,
|
|
180
|
+
scale: 0.75,
|
|
181
|
+
},
|
|
182
|
+
} satisfies Variants
|
|
183
|
+
type ContainerVariants = keyof typeof container
|
|
184
|
+
|
|
185
|
+
const content = {
|
|
186
|
+
hidden: {
|
|
187
|
+
opacity: 0,
|
|
188
|
+
},
|
|
189
|
+
visible: {
|
|
190
|
+
opacity: 1,
|
|
191
|
+
},
|
|
192
|
+
} satisfies Variants
|
|
193
|
+
|
|
194
|
+
const MotionToast = motion.create(StyledToast)
|
|
195
|
+
const MotionFlex = motion.create(Flex)
|
|
196
|
+
|
|
197
|
+
const MotionText = motion.create(Text)
|
|
198
|
+
|
|
199
|
+
const MotionLoadiongBar = motion.create(LoadingBar)
|
|
200
|
+
const MotionLoadiongBarProgress = 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
|
+
`
|