myshell-react-lib 0.1.4 → 0.1.6
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 +52 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
- package/src/common/assets/audio-playing.json +0 -3657
- package/src/common/constants/constants.ts +0 -24
- package/src/common/constants/types/common.ts +0 -10
- package/src/common/hooks/useAudioPlayer.tsx +0 -198
- package/src/common/hooks/useDevice.ts +0 -26
- package/src/common/hooks/useNativeBridge.ts +0 -42
- package/src/common/hooks/useNotification.tsx +0 -179
- package/src/common/hooks/useWindowWidth.ts +0 -19
- package/src/common/utils/common-helper.ts +0 -81
- package/src/components/ItemDemo.tsx +0 -15
- package/src/components/accordion.tsx +0 -126
- package/src/components/alert-dialog.tsx +0 -148
- package/src/components/alert.tsx +0 -65
- package/src/components/aspect-ratio.tsx +0 -7
- package/src/components/audio-player.tsx +0 -60
- package/src/components/audio-playing.tsx +0 -33
- package/src/components/avatar.tsx +0 -133
- package/src/components/badge.tsx +0 -67
- package/src/components/button/button.styles.ts +0 -258
- package/src/components/button/button.tsx +0 -215
- package/src/components/button/icon-button.styles.ts +0 -101
- package/src/components/button/icon-button.tsx +0 -100
- package/src/components/button/index.tsx +0 -3
- package/src/components/button/link-button.tsx +0 -184
- package/src/components/cascader.tsx +0 -175
- package/src/components/checkbox.tsx +0 -135
- package/src/components/command.tsx +0 -155
- package/src/components/context-menu.tsx +0 -198
- package/src/components/count-down.tsx +0 -83
- package/src/components/custom-notification.tsx +0 -95
- package/src/components/dialog.tsx +0 -158
- package/src/components/drawer.tsx +0 -116
- package/src/components/dropdown-menu.tsx +0 -196
- package/src/components/energy-progress.tsx +0 -55
- package/src/components/form.tsx +0 -201
- package/src/components/group.tsx +0 -9
- package/src/components/guide.tsx +0 -243
- package/src/components/icon.tsx +0 -96
- package/src/components/icons/index.tsx +0 -13
- package/src/components/icons/outline/ArrowLeftIcon.tsx +0 -28
- package/src/components/icons/outline/ArrowUpTrayIcon.tsx +0 -28
- package/src/components/icons/outline/CheckCircleIcon.tsx +0 -27
- package/src/components/icons/outline/ConfigIcon.tsx +0 -42
- package/src/components/icons/outline/DownIcon.tsx +0 -18
- package/src/components/icons/outline/FilterIcon.tsx +0 -20
- package/src/components/icons/outline/PencilSquareIcon.tsx +0 -28
- package/src/components/icons/outline/WindowIcon.tsx +0 -26
- package/src/components/icons/solid/CaretDownIcon.tsx +0 -22
- package/src/components/icons/solid/CodeIcon.tsx +0 -25
- package/src/components/icons/solid/DragIcon.tsx +0 -24
- package/src/components/icons/solid/PhoneIcon.tsx +0 -29
- package/src/components/icons/solid/RectangleGroupIcon.tsx +0 -26
- package/src/components/image.tsx +0 -151
- package/src/components/input.tsx +0 -118
- package/src/components/label.tsx +0 -26
- package/src/components/link.tsx +0 -123
- package/src/components/marquee/index.css +0 -15
- package/src/components/marquee/marquee.tsx +0 -220
- package/src/components/masonry.tsx +0 -138
- package/src/components/menubar.tsx +0 -234
- package/src/components/mobile/m-tooltip.tsx +0 -34
- package/src/components/modal.tsx +0 -561
- package/src/components/navigation-bar.tsx +0 -100
- package/src/components/number-input.tsx +0 -143
- package/src/components/page-content.tsx +0 -16
- package/src/components/popover.tsx +0 -191
- package/src/components/progress.tsx +0 -80
- package/src/components/radio-group.tsx +0 -44
- package/src/components/scroll-area.tsx +0 -49
- package/src/components/search-bar.tsx +0 -140
- package/src/components/secondary-navigation-bar.tsx +0 -328
- package/src/components/select.tsx +0 -273
- package/src/components/separator.tsx +0 -31
- package/src/components/sheet.tsx +0 -143
- package/src/components/skeleton.tsx +0 -20
- package/src/components/slider.tsx +0 -160
- package/src/components/spinner.tsx +0 -50
- package/src/components/swiper/index.module.scss +0 -88
- package/src/components/swiper/index.tsx +0 -319
- package/src/components/switch.tsx +0 -67
- package/src/components/tabs.tsx +0 -325
- package/src/components/textarea.tsx +0 -71
- package/src/components/toast/toast.tsx +0 -182
- package/src/components/toast/toaster.tsx +0 -160
- package/src/components/toast/use-toast.tsx +0 -248
- package/src/components/toggle-group.tsx +0 -64
- package/src/components/toggle.tsx +0 -46
- package/src/components/tooltip.tsx +0 -283
- package/src/components/typography.tsx +0 -437
- package/src/index.ts +0 -70
- package/src/lib/utils.ts +0 -62
- package/src/stories/Accordion.stories.tsx +0 -64
- package/src/stories/AccordionItem.stories.tsx +0 -48
- package/src/stories/Avatar.stories.ts +0 -58
- package/src/stories/Badge.stories.tsx +0 -40
- package/src/stories/BannerSwiper.stories.tsx +0 -102
- package/src/stories/Button.stories.tsx +0 -543
- package/src/stories/Checkbox.stories.tsx +0 -161
- package/src/stories/Configure.mdx +0 -341
- package/src/stories/CssProperties.mdx +0 -30
- package/src/stories/Description.stories.ts +0 -70
- package/src/stories/Display.stories.ts +0 -64
- package/src/stories/FeaturedSwiper.stories.tsx +0 -6978
- package/src/stories/GridSwiper.stories.tsx +0 -1407
- package/src/stories/Guide.stories.tsx +0 -247
- package/src/stories/Heading.stories.ts +0 -89
- package/src/stories/Icon.stories.ts +0 -77
- package/src/stories/IconButton.stories.tsx +0 -301
- package/src/stories/IconTextButton.stories.ts +0 -59
- package/src/stories/Image.stories.ts +0 -55
- package/src/stories/Input.stories.tsx +0 -203
- package/src/stories/Modal.stories.tsx +0 -144
- package/src/stories/NavigationBar.stories.tsx +0 -81
- package/src/stories/Notification.stories.tsx +0 -276
- package/src/stories/Popover.stories.tsx +0 -100
- package/src/stories/SearchBar.stories.ts +0 -43
- package/src/stories/SecondaryNavigationBar.stories.tsx +0 -199
- package/src/stories/Select.stories.tsx +0 -107
- package/src/stories/Separator.stories.tsx +0 -49
- package/src/stories/Spinner.stories.tsx +0 -48
- package/src/stories/SubHeading.stories.ts +0 -64
- package/src/stories/Swich.stories.tsx +0 -69
- package/src/stories/Tabs.stories.tsx +0 -90
- package/src/stories/Text.stories.ts +0 -78
- package/src/stories/Textarea.stories.tsx +0 -155
- package/src/stories/Toast.stories.tsx +0 -424
- package/src/stories/Tooltip.stories.tsx +0 -244
- package/src/stories/ViewAutoSwiper.stories.tsx +0 -1408
- package/src/styles/components-dark.scss +0 -212
- package/src/styles/components-light.scss +0 -210
- package/src/styles/design-dark.scss +0 -330
- package/src/styles/design-light.scss +0 -345
- package/src/styles/design2-dark.scss +0 -319
- package/src/styles/design2-light.scss +0 -364
- package/src/styles/font.css +0 -19
- package/src/styles/global.scss +0 -251
- package/src/styles/md-viewer.scss +0 -155
- package/src/styles/new-tokens.scss +0 -255
- package/src/styles/tokens.scss +0 -401
- package/src/types/scss.d.ts +0 -24
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
|
|
3
|
-
import { cn } from '@/lib/utils';
|
|
4
|
-
|
|
5
|
-
import { Text } from './typography';
|
|
6
|
-
|
|
7
|
-
export type TextareaProps =
|
|
8
|
-
React.TextareaHTMLAttributes<HTMLTextAreaElement> & {
|
|
9
|
-
maxLengthClassName?: string;
|
|
10
|
-
};
|
|
11
|
-
const Textarea = React.forwardRef<
|
|
12
|
-
HTMLTextAreaElement,
|
|
13
|
-
TextareaProps & { error?: string }
|
|
14
|
-
>(
|
|
15
|
-
(
|
|
16
|
-
{ className, maxLength, value, error, maxLengthClassName, ...props },
|
|
17
|
-
ref
|
|
18
|
-
) => {
|
|
19
|
-
return (
|
|
20
|
-
<div>
|
|
21
|
-
<div className="relative">
|
|
22
|
-
<textarea
|
|
23
|
-
className={cn(
|
|
24
|
-
'w-full min-h-[123px] p-3 pb-10 rounded-lg border border-Colors-Border-Default bg-Colors-Background-Normal-Primary-Active ',
|
|
25
|
-
'text-sm text-Colors-Text-Default placeholder:text-Colors-Text-Subtlest ring-offset-cc-Focus-Rings-Brand-default',
|
|
26
|
-
'hover:border-hovered bg-cc-Input-bg-default hover:bg-cc-Input-bg-hover disabled:bg-cc-Input-bg-disabled aria-[invalid=true]:border-Colors-Border-Critical aria-[invalid=true]:hover:bg-Colors-Background-Critical-Subtle',
|
|
27
|
-
'aria-[invalid=true]:focus-visible:ring-error file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-Colors-Text-Subtler',
|
|
28
|
-
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cc-Focus-Rings-Brand-default focus-visible:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-30',
|
|
29
|
-
(maxLength && (value?.toString()?.length || 0) > maxLength) ||
|
|
30
|
-
error
|
|
31
|
-
? 'border-Colors-Border-Critical hover:bg-Colors-Background-Critical-Subtle focus-visible:ring-error'
|
|
32
|
-
: '',
|
|
33
|
-
className
|
|
34
|
-
)}
|
|
35
|
-
ref={ref}
|
|
36
|
-
maxLength={maxLength}
|
|
37
|
-
value={value}
|
|
38
|
-
{...props}
|
|
39
|
-
/>
|
|
40
|
-
{maxLength ? (
|
|
41
|
-
<div
|
|
42
|
-
className={cn(
|
|
43
|
-
'absolute text-right bottom-5 right-4 border-Colors-Border-Default',
|
|
44
|
-
maxLengthClassName
|
|
45
|
-
)}
|
|
46
|
-
>
|
|
47
|
-
<Text size="sm" color="subtlest">{`${
|
|
48
|
-
value?.toString()?.length || 0
|
|
49
|
-
}/${maxLength}`}</Text>
|
|
50
|
-
</div>
|
|
51
|
-
) : null}
|
|
52
|
-
</div>
|
|
53
|
-
{error && (
|
|
54
|
-
<div className="w-full">
|
|
55
|
-
<Text
|
|
56
|
-
className="text-wrap"
|
|
57
|
-
size="sm"
|
|
58
|
-
weight="regular"
|
|
59
|
-
color="critical"
|
|
60
|
-
>
|
|
61
|
-
{error}
|
|
62
|
-
</Text>
|
|
63
|
-
</div>
|
|
64
|
-
)}
|
|
65
|
-
</div>
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
);
|
|
69
|
-
Textarea.displayName = 'Textarea';
|
|
70
|
-
|
|
71
|
-
export { Textarea };
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import * as ToastPrimitives from '@radix-ui/react-toast';
|
|
4
|
-
import { cva, type VariantProps } from 'class-variance-authority';
|
|
5
|
-
import * as React from 'react';
|
|
6
|
-
import { cn } from '@/lib/utils';
|
|
7
|
-
import XMarkIcon from '@heroicons/react/24/outline/esm/XMarkIcon';
|
|
8
|
-
|
|
9
|
-
const ToastProvider = ToastPrimitives.Provider;
|
|
10
|
-
|
|
11
|
-
const viewportPositionVariants = cva(
|
|
12
|
-
'fixed z-[1000001] flex max-h-screen w-full p-0 gap-2',
|
|
13
|
-
{
|
|
14
|
-
variants: {
|
|
15
|
-
position: {
|
|
16
|
-
'top-left': 'top-6 left-6 flex-col items-start',
|
|
17
|
-
'top-center': 'top-6 left-1/2 -translate-x-1/2 flex-col items-center',
|
|
18
|
-
'top-right': 'top-6 right-6 flex-col items-end',
|
|
19
|
-
'bottom-left': 'bottom-6 left-6 flex-col-reverse items-start',
|
|
20
|
-
'bottom-center':
|
|
21
|
-
'bottom-6 left-1/2 -translate-x-1/2 flex-col-reverse items-center',
|
|
22
|
-
'bottom-right': 'bottom-6 right-6 flex-col-reverse items-end',
|
|
23
|
-
'left-center': 'left-6 top-1/2 -translate-y-1/2 flex-row items-center',
|
|
24
|
-
'right-center':
|
|
25
|
-
'right-6 top-1/2 -translate-y-1/2 flex-row-reverse items-center',
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
defaultVariants: {
|
|
29
|
-
position: 'top-right',
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
interface ToastViewportProps
|
|
35
|
-
extends React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport> {
|
|
36
|
-
position?:
|
|
37
|
-
| 'top-left'
|
|
38
|
-
| 'top-center'
|
|
39
|
-
| 'top-right'
|
|
40
|
-
| 'bottom-left'
|
|
41
|
-
| 'bottom-center'
|
|
42
|
-
| 'bottom-right'
|
|
43
|
-
| 'left-center'
|
|
44
|
-
| 'right-center';
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const ToastViewport = React.forwardRef<
|
|
48
|
-
React.ElementRef<typeof ToastPrimitives.Viewport>,
|
|
49
|
-
ToastViewportProps
|
|
50
|
-
>(({ className, position, ...props }, ref) => (
|
|
51
|
-
<ToastPrimitives.Viewport
|
|
52
|
-
ref={ref}
|
|
53
|
-
className={cn(viewportPositionVariants({ position }), className)}
|
|
54
|
-
{...props}
|
|
55
|
-
/>
|
|
56
|
-
));
|
|
57
|
-
ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
|
|
58
|
-
|
|
59
|
-
const toastVariants = cva(
|
|
60
|
-
'group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border border-Colors-Border-Opaque p-6 pr-8 shadow-modal-default transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 max-w-md',
|
|
61
|
-
{
|
|
62
|
-
variants: {
|
|
63
|
-
variant: {
|
|
64
|
-
info: 'bg-Colors-Background-Normal-Primary-Default p-4',
|
|
65
|
-
warning: 'bg-Colors-Background-Normal-Primary-Default p-4',
|
|
66
|
-
error: 'bg-Colors-Background-Normal-Primary-Default p-4',
|
|
67
|
-
success: 'bg-Colors-Background-Normal-Primary-Default p-4',
|
|
68
|
-
},
|
|
69
|
-
position: {
|
|
70
|
-
'top-left':
|
|
71
|
-
'data-[state=open]:slide-in-from-left-full data-[state=closed]:slide-out-to-left-full',
|
|
72
|
-
'top-center':
|
|
73
|
-
'data-[state=open]:slide-in-from-top-full data-[state=closed]:slide-out-to-top-full',
|
|
74
|
-
'top-right':
|
|
75
|
-
'data-[state=open]:slide-in-from-right-full data-[state=closed]:slide-out-to-right-full',
|
|
76
|
-
'bottom-left':
|
|
77
|
-
'data-[state=open]:slide-in-from-left-full data-[state=closed]:slide-out-to-left-full',
|
|
78
|
-
'bottom-center':
|
|
79
|
-
'data-[state=open]:slide-in-from-bottom-full data-[state=closed]:slide-out-to-bottom-full',
|
|
80
|
-
'bottom-right':
|
|
81
|
-
'data-[state=open]:slide-in-from-right-full data-[state=closed]:slide-out-to-right-full',
|
|
82
|
-
'left-center':
|
|
83
|
-
'data-[state=open]:slide-in-from-left-full data-[state=closed]:slide-out-to-left-full',
|
|
84
|
-
'right-center':
|
|
85
|
-
'data-[state=open]:slide-in-from-right-full data-[state=closed]:slide-out-to-right-full',
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
defaultVariants: {
|
|
89
|
-
variant: 'info',
|
|
90
|
-
position: 'top-right',
|
|
91
|
-
},
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
const Toast = React.forwardRef<
|
|
96
|
-
React.ElementRef<typeof ToastPrimitives.Root>,
|
|
97
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &
|
|
98
|
-
VariantProps<typeof toastVariants>
|
|
99
|
-
>(({ className, variant, position, ...props }, ref) => {
|
|
100
|
-
return (
|
|
101
|
-
<ToastPrimitives.Root
|
|
102
|
-
ref={ref}
|
|
103
|
-
className={cn(toastVariants({ variant, position }), className)}
|
|
104
|
-
data-position={position}
|
|
105
|
-
{...props}
|
|
106
|
-
/>
|
|
107
|
-
);
|
|
108
|
-
});
|
|
109
|
-
Toast.displayName = ToastPrimitives.Root.displayName;
|
|
110
|
-
|
|
111
|
-
const ToastAction = React.forwardRef<
|
|
112
|
-
React.ElementRef<typeof ToastPrimitives.Action>,
|
|
113
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>
|
|
114
|
-
>(({ className, ...props }, ref) => (
|
|
115
|
-
<ToastPrimitives.Action
|
|
116
|
-
ref={ref}
|
|
117
|
-
className={cn(
|
|
118
|
-
'inline-flex h-8 shrink-0 items-center justify-center rounded-md border border-slate-200 bg-transparent px-3 text-sm font-medium ring-offset-white transition-colors hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-slate-100/40 group-[.destructive]:hover:border-red-500/30 group-[.destructive]:hover:bg-red-500 group-[.destructive]:hover:text-slate-50 group-[.destructive]:focus:ring-red-500 dark:border-slate-800 dark:ring-offset-slate-950 dark:hover:bg-slate-800 dark:focus:ring-slate-300 dark:group-[.destructive]:border-slate-800/40 dark:group-[.destructive]:hover:border-red-900/30 dark:group-[.destructive]:hover:bg-red-900 dark:group-[.destructive]:hover:text-slate-50 dark:group-[.destructive]:focus:ring-red-900',
|
|
119
|
-
className
|
|
120
|
-
)}
|
|
121
|
-
{...props}
|
|
122
|
-
/>
|
|
123
|
-
));
|
|
124
|
-
ToastAction.displayName = ToastPrimitives.Action.displayName;
|
|
125
|
-
|
|
126
|
-
const ToastClose = React.forwardRef<
|
|
127
|
-
React.ElementRef<typeof ToastPrimitives.Close>,
|
|
128
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>
|
|
129
|
-
>(({ className, ...props }, ref) => (
|
|
130
|
-
<ToastPrimitives.Close
|
|
131
|
-
ref={ref}
|
|
132
|
-
className={cn(
|
|
133
|
-
'absolute right-4 top-4 rounded-md p-1 text-slate-950/50 transition-opacity hover:text-slate-950 outline-none focus:outline-none focus:ring-2 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600 dark:text-slate-50/50 dark:hover:text-slate-50',
|
|
134
|
-
className
|
|
135
|
-
)}
|
|
136
|
-
toast-close=""
|
|
137
|
-
{...props}
|
|
138
|
-
>
|
|
139
|
-
<XMarkIcon className="h-5 w-5" />
|
|
140
|
-
</ToastPrimitives.Close>
|
|
141
|
-
));
|
|
142
|
-
ToastClose.displayName = ToastPrimitives.Close.displayName;
|
|
143
|
-
|
|
144
|
-
const ToastTitle = React.forwardRef<
|
|
145
|
-
React.ElementRef<typeof ToastPrimitives.Title>,
|
|
146
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>
|
|
147
|
-
>(({ className, ...props }, ref) => (
|
|
148
|
-
<ToastPrimitives.Title
|
|
149
|
-
ref={ref}
|
|
150
|
-
className={cn('text-sm font-semibold', className)}
|
|
151
|
-
{...props}
|
|
152
|
-
/>
|
|
153
|
-
));
|
|
154
|
-
ToastTitle.displayName = ToastPrimitives.Title.displayName;
|
|
155
|
-
|
|
156
|
-
const ToastDescription = React.forwardRef<
|
|
157
|
-
React.ElementRef<typeof ToastPrimitives.Description>,
|
|
158
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>
|
|
159
|
-
>(({ className, ...props }, ref) => (
|
|
160
|
-
<ToastPrimitives.Description
|
|
161
|
-
ref={ref}
|
|
162
|
-
className={cn('text-sm opacity-90', className)}
|
|
163
|
-
{...props}
|
|
164
|
-
/>
|
|
165
|
-
));
|
|
166
|
-
ToastDescription.displayName = ToastPrimitives.Description.displayName;
|
|
167
|
-
|
|
168
|
-
type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;
|
|
169
|
-
|
|
170
|
-
type ToastActionElement = React.ReactElement<typeof ToastAction>;
|
|
171
|
-
|
|
172
|
-
export {
|
|
173
|
-
type ToastProps,
|
|
174
|
-
type ToastActionElement,
|
|
175
|
-
ToastProvider,
|
|
176
|
-
ToastViewport,
|
|
177
|
-
Toast,
|
|
178
|
-
ToastTitle,
|
|
179
|
-
ToastDescription,
|
|
180
|
-
ToastClose,
|
|
181
|
-
ToastAction,
|
|
182
|
-
};
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import CheckCircleIcon from '@heroicons/react/24/outline/esm/CheckCircleIcon';
|
|
4
|
-
import ExclamationCircleIcon from '@heroicons/react/24/outline/esm/ExclamationCircleIcon';
|
|
5
|
-
import InformationCircleIcon from '@heroicons/react/24/outline/esm/InformationCircleIcon';
|
|
6
|
-
import XCircleIcon from '@heroicons/react/24/outline/esm/XCircleIcon';
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
Toast,
|
|
10
|
-
ToastClose,
|
|
11
|
-
ToastDescription,
|
|
12
|
-
ToastProvider,
|
|
13
|
-
ToastTitle,
|
|
14
|
-
ToastViewport,
|
|
15
|
-
} from './toast';
|
|
16
|
-
import { useToast } from './use-toast';
|
|
17
|
-
import { cn } from '@/lib/utils';
|
|
18
|
-
import React from 'react';
|
|
19
|
-
|
|
20
|
-
type ToastVariant = 'info' | 'success' | 'warning' | 'error' | null | undefined;
|
|
21
|
-
|
|
22
|
-
export interface ToasterProps {
|
|
23
|
-
position?:
|
|
24
|
-
| 'top-left'
|
|
25
|
-
| 'top-center'
|
|
26
|
-
| 'top-right'
|
|
27
|
-
| 'bottom-left'
|
|
28
|
-
| 'bottom-center'
|
|
29
|
-
| 'bottom-right'
|
|
30
|
-
| 'left-center'
|
|
31
|
-
| 'right-center';
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function Toaster({ position = 'top-right' }: ToasterProps = {}) {
|
|
35
|
-
const { toasts } = useToast();
|
|
36
|
-
|
|
37
|
-
// 按位置分组
|
|
38
|
-
const positionGroups = React.useMemo(() => {
|
|
39
|
-
const groups: Record<string, typeof toasts> = {};
|
|
40
|
-
|
|
41
|
-
const allPositions = [
|
|
42
|
-
'top-left',
|
|
43
|
-
'top-center',
|
|
44
|
-
'top-right',
|
|
45
|
-
'bottom-left',
|
|
46
|
-
'bottom-center',
|
|
47
|
-
'bottom-right',
|
|
48
|
-
'left-center',
|
|
49
|
-
'right-center',
|
|
50
|
-
];
|
|
51
|
-
|
|
52
|
-
// 初始化所有位置组
|
|
53
|
-
allPositions.forEach((pos) => {
|
|
54
|
-
groups[pos] = [];
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// 将每个Toast按其position分组,如果没有指定则使用默认位置
|
|
58
|
-
toasts.forEach((toast) => {
|
|
59
|
-
const toastPosition = toast.position || position;
|
|
60
|
-
if (groups[toastPosition]) {
|
|
61
|
-
groups[toastPosition].push(toast);
|
|
62
|
-
} else {
|
|
63
|
-
// 如果位置不在预定义列表中,则使用默认位置
|
|
64
|
-
groups[position].push(toast);
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
return groups;
|
|
69
|
-
}, [toasts, position]);
|
|
70
|
-
|
|
71
|
-
const renderToast = (toast: any) => {
|
|
72
|
-
const {
|
|
73
|
-
id,
|
|
74
|
-
title,
|
|
75
|
-
description,
|
|
76
|
-
action,
|
|
77
|
-
variant,
|
|
78
|
-
position: toastPosition,
|
|
79
|
-
} = toast;
|
|
80
|
-
|
|
81
|
-
const renderIcon = (variant: ToastVariant) => {
|
|
82
|
-
switch (variant) {
|
|
83
|
-
case 'info':
|
|
84
|
-
return (
|
|
85
|
-
<InformationCircleIcon className="h-6 w-6 text-cc-Icon-Featured-icon-fg-Info" />
|
|
86
|
-
);
|
|
87
|
-
case 'success':
|
|
88
|
-
return (
|
|
89
|
-
<CheckCircleIcon className="h-6 w-6 text-cc-Icon-Featured-icon-fg-Success" />
|
|
90
|
-
);
|
|
91
|
-
case 'warning':
|
|
92
|
-
return (
|
|
93
|
-
<ExclamationCircleIcon className="h-6 w-6 text-cc-Icon-Featured-icon-fg-Warning" />
|
|
94
|
-
);
|
|
95
|
-
case 'error':
|
|
96
|
-
return (
|
|
97
|
-
<XCircleIcon className="h-6 w-6 text-cc-Icon-Featured-icon-fg-Error" />
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const getBackgroundColor = (variant: ToastVariant) => {
|
|
103
|
-
switch (variant) {
|
|
104
|
-
case 'info':
|
|
105
|
-
return 'bg-Colors-Background-Info-Default';
|
|
106
|
-
case 'success':
|
|
107
|
-
return 'bg-Colors-Background-Success-Default';
|
|
108
|
-
case 'warning':
|
|
109
|
-
return 'bg-Colors-Background-Warning-Default';
|
|
110
|
-
case 'error':
|
|
111
|
-
return 'bg-Colors-Background-Critical-Default';
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
return (
|
|
116
|
-
<Toast key={id} {...toast} position={toastPosition}>
|
|
117
|
-
<div className="flex flex-col gap-3">
|
|
118
|
-
<div className="flex items-start gap-3">
|
|
119
|
-
<div
|
|
120
|
-
className={cn(
|
|
121
|
-
'flex h-10 w-10 flex-shrink-0 flex-grow-0 items-center justify-center rounded-full',
|
|
122
|
-
getBackgroundColor(variant)
|
|
123
|
-
)}
|
|
124
|
-
>
|
|
125
|
-
{renderIcon(variant)}
|
|
126
|
-
</div>
|
|
127
|
-
<div className="grid gap-1">
|
|
128
|
-
{title && (
|
|
129
|
-
<ToastTitle className="text-base text-Colors-Text-Default">
|
|
130
|
-
{title}
|
|
131
|
-
</ToastTitle>
|
|
132
|
-
)}
|
|
133
|
-
{description && (
|
|
134
|
-
<ToastDescription className="text-sm text-Colors-Text-Subtle">
|
|
135
|
-
{description}
|
|
136
|
-
</ToastDescription>
|
|
137
|
-
)}
|
|
138
|
-
{action}
|
|
139
|
-
</div>
|
|
140
|
-
</div>
|
|
141
|
-
</div>
|
|
142
|
-
<ToastClose />
|
|
143
|
-
</Toast>
|
|
144
|
-
);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
return (
|
|
148
|
-
<ToastProvider>
|
|
149
|
-
{/* 为每个位置渲染一个ToastViewport */}
|
|
150
|
-
{Object.entries(positionGroups).map(([pos, toastsForPosition]) => (
|
|
151
|
-
<React.Fragment key={pos}>
|
|
152
|
-
{toastsForPosition.map(renderToast)}
|
|
153
|
-
{toastsForPosition.length > 0 && (
|
|
154
|
-
<ToastViewport position={pos as any} />
|
|
155
|
-
)}
|
|
156
|
-
</React.Fragment>
|
|
157
|
-
))}
|
|
158
|
-
</ToastProvider>
|
|
159
|
-
);
|
|
160
|
-
}
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
// Inspired by react-hot-toast library
|
|
4
|
-
import * as React from 'react';
|
|
5
|
-
import { ToastActionElement, ToastProps } from './toast';
|
|
6
|
-
import { Text } from '../typography';
|
|
7
|
-
import Link from '../link';
|
|
8
|
-
const TOAST_LIMIT = 8;
|
|
9
|
-
const TOAST_REMOVE_DELAY = 1000;
|
|
10
|
-
|
|
11
|
-
type ToasterToast = ToastProps & {
|
|
12
|
-
id: string;
|
|
13
|
-
title?: React.ReactNode;
|
|
14
|
-
description?: React.ReactNode;
|
|
15
|
-
action?: ToastActionElement;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const actionTypes = {
|
|
19
|
-
ADD_TOAST: 'ADD_TOAST',
|
|
20
|
-
UPDATE_TOAST: 'UPDATE_TOAST',
|
|
21
|
-
DISMISS_TOAST: 'DISMISS_TOAST',
|
|
22
|
-
REMOVE_TOAST: 'REMOVE_TOAST',
|
|
23
|
-
} as const;
|
|
24
|
-
|
|
25
|
-
let count = 0;
|
|
26
|
-
|
|
27
|
-
function genId() {
|
|
28
|
-
count = (count + 1) % Number.MAX_SAFE_INTEGER;
|
|
29
|
-
|
|
30
|
-
return count.toString();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
type ActionType = typeof actionTypes;
|
|
34
|
-
|
|
35
|
-
type Action =
|
|
36
|
-
| {
|
|
37
|
-
type: ActionType['ADD_TOAST'];
|
|
38
|
-
toast: ToasterToast;
|
|
39
|
-
}
|
|
40
|
-
| {
|
|
41
|
-
type: ActionType['UPDATE_TOAST'];
|
|
42
|
-
toast: Partial<ToasterToast>;
|
|
43
|
-
}
|
|
44
|
-
| {
|
|
45
|
-
type: ActionType['DISMISS_TOAST'];
|
|
46
|
-
toastId?: ToasterToast['id'];
|
|
47
|
-
}
|
|
48
|
-
| {
|
|
49
|
-
type: ActionType['REMOVE_TOAST'];
|
|
50
|
-
toastId?: ToasterToast['id'];
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
interface State {
|
|
54
|
-
toasts: ToasterToast[];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>();
|
|
58
|
-
|
|
59
|
-
const addToRemoveQueue = (toastId: string) => {
|
|
60
|
-
if (toastTimeouts.has(toastId)) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const timeout = setTimeout(() => {
|
|
65
|
-
toastTimeouts.delete(toastId);
|
|
66
|
-
dispatch({
|
|
67
|
-
type: 'REMOVE_TOAST',
|
|
68
|
-
toastId,
|
|
69
|
-
});
|
|
70
|
-
}, TOAST_REMOVE_DELAY);
|
|
71
|
-
|
|
72
|
-
toastTimeouts.set(toastId, timeout);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
export const reducer = (state: State, action: Action): State => {
|
|
76
|
-
switch (action.type) {
|
|
77
|
-
case 'ADD_TOAST':
|
|
78
|
-
return {
|
|
79
|
-
...state,
|
|
80
|
-
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
case 'UPDATE_TOAST':
|
|
84
|
-
return {
|
|
85
|
-
...state,
|
|
86
|
-
toasts: state.toasts.map((t) =>
|
|
87
|
-
t.id === action.toast.id ? { ...t, ...action.toast } : t
|
|
88
|
-
),
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
case 'DISMISS_TOAST': {
|
|
92
|
-
const { toastId } = action;
|
|
93
|
-
|
|
94
|
-
// ! Side effects ! - This could be extracted into a dismissToast() action,
|
|
95
|
-
// but I'll keep it here for simplicity
|
|
96
|
-
if (toastId) {
|
|
97
|
-
addToRemoveQueue(toastId);
|
|
98
|
-
} else {
|
|
99
|
-
state.toasts.forEach((toast) => {
|
|
100
|
-
addToRemoveQueue(toast.id);
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
...state,
|
|
106
|
-
toasts: state.toasts.map((t) =>
|
|
107
|
-
t.id === toastId || toastId === undefined
|
|
108
|
-
? {
|
|
109
|
-
...t,
|
|
110
|
-
open: false,
|
|
111
|
-
}
|
|
112
|
-
: t
|
|
113
|
-
),
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
case 'REMOVE_TOAST':
|
|
117
|
-
if (action.toastId === undefined) {
|
|
118
|
-
return {
|
|
119
|
-
...state,
|
|
120
|
-
toasts: [],
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return {
|
|
125
|
-
...state,
|
|
126
|
-
toasts: state.toasts.filter((t) => t.id !== action.toastId),
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
const listeners: Array<(state: State) => void> = [];
|
|
132
|
-
|
|
133
|
-
let memoryState: State = { toasts: [] };
|
|
134
|
-
|
|
135
|
-
function dispatch(action: Action) {
|
|
136
|
-
memoryState = reducer(memoryState, action);
|
|
137
|
-
listeners.forEach((listener) => {
|
|
138
|
-
listener(memoryState);
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
type Toast = Omit<ToasterToast, 'id'> & {
|
|
143
|
-
actions?: {
|
|
144
|
-
dismissText?: string;
|
|
145
|
-
view?: string;
|
|
146
|
-
viewUrl?: string;
|
|
147
|
-
};
|
|
148
|
-
toastId?: string;
|
|
149
|
-
position?:
|
|
150
|
-
| 'top-left'
|
|
151
|
-
| 'top-center'
|
|
152
|
-
| 'top-right'
|
|
153
|
-
| 'bottom-left'
|
|
154
|
-
| 'bottom-center'
|
|
155
|
-
| 'bottom-right'
|
|
156
|
-
| 'left-center'
|
|
157
|
-
| 'right-center';
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
function toast({ actions, toastId, position, ...props }: Toast) {
|
|
161
|
-
const id = toastId || genId();
|
|
162
|
-
|
|
163
|
-
const update = (props: ToasterToast) =>
|
|
164
|
-
dispatch({
|
|
165
|
-
type: 'UPDATE_TOAST',
|
|
166
|
-
toast: { ...props, id },
|
|
167
|
-
});
|
|
168
|
-
const dismiss = () => dispatch({ type: 'DISMISS_TOAST', toastId: id });
|
|
169
|
-
|
|
170
|
-
dispatch({
|
|
171
|
-
type: 'ADD_TOAST',
|
|
172
|
-
toast: {
|
|
173
|
-
...props,
|
|
174
|
-
position,
|
|
175
|
-
...(actions && {
|
|
176
|
-
action: (
|
|
177
|
-
<div className="flex justify-start items-center gap-2">
|
|
178
|
-
{actions?.dismissText && (
|
|
179
|
-
<Text
|
|
180
|
-
size="sm"
|
|
181
|
-
weight="medium"
|
|
182
|
-
color="brand"
|
|
183
|
-
className="cursor-pointer"
|
|
184
|
-
onClick={() => {
|
|
185
|
-
dismiss();
|
|
186
|
-
}}
|
|
187
|
-
>
|
|
188
|
-
{actions?.dismissText}
|
|
189
|
-
</Text>
|
|
190
|
-
)}
|
|
191
|
-
{actions?.view && actions.viewUrl && (
|
|
192
|
-
<Link
|
|
193
|
-
href={actions.viewUrl}
|
|
194
|
-
target="_blank"
|
|
195
|
-
rel="noreferrer noopener"
|
|
196
|
-
>
|
|
197
|
-
<div className="flex items-center gap-1.5">
|
|
198
|
-
<Text
|
|
199
|
-
size="sm"
|
|
200
|
-
weight="medium"
|
|
201
|
-
color="default"
|
|
202
|
-
className="cursor-pointer"
|
|
203
|
-
>
|
|
204
|
-
{actions.view}
|
|
205
|
-
</Text>
|
|
206
|
-
</div>
|
|
207
|
-
</Link>
|
|
208
|
-
)}
|
|
209
|
-
</div>
|
|
210
|
-
),
|
|
211
|
-
}),
|
|
212
|
-
id,
|
|
213
|
-
open: true,
|
|
214
|
-
onOpenChange: (open) => {
|
|
215
|
-
if (!open) dismiss();
|
|
216
|
-
},
|
|
217
|
-
},
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
return {
|
|
221
|
-
id,
|
|
222
|
-
dismiss,
|
|
223
|
-
update,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function useToast() {
|
|
228
|
-
const [state, setState] = React.useState<State>(memoryState);
|
|
229
|
-
|
|
230
|
-
React.useEffect(() => {
|
|
231
|
-
listeners.push(setState);
|
|
232
|
-
|
|
233
|
-
return () => {
|
|
234
|
-
const index = listeners.indexOf(setState);
|
|
235
|
-
if (index > -1) {
|
|
236
|
-
listeners.splice(index, 1);
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
}, [state]);
|
|
240
|
-
|
|
241
|
-
return {
|
|
242
|
-
...state,
|
|
243
|
-
toast,
|
|
244
|
-
dismiss: (toastId?: string) => dispatch({ type: 'DISMISS_TOAST', toastId }),
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
export { toast, useToast };
|