myshell-react-lib 0.1.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/README.md +268 -0
- package/dist/assets/audio-playing.json +3657 -0
- package/dist/index.cjs +9654 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1431 -0
- package/dist/index.d.ts +1431 -0
- package/dist/index.js +8788 -0
- package/dist/index.js.map +1 -0
- package/package.json +140 -0
- package/src/common/assets/audio-playing.json +3657 -0
- package/src/common/constants/constants.ts +24 -0
- package/src/common/constants/types/common.ts +10 -0
- package/src/common/hooks/useAudioPlayer.tsx +198 -0
- package/src/common/hooks/useDevice.ts +26 -0
- package/src/common/hooks/useNativeBridge.ts +42 -0
- package/src/common/hooks/useNotification.tsx +179 -0
- package/src/common/hooks/useWindowWidth.ts +19 -0
- package/src/common/utils/common-helper.ts +81 -0
- package/src/components/ItemDemo.tsx +15 -0
- package/src/components/accordion.tsx +126 -0
- package/src/components/alert-dialog.tsx +148 -0
- package/src/components/alert.tsx +65 -0
- package/src/components/aspect-ratio.tsx +7 -0
- package/src/components/audio-player.tsx +58 -0
- package/src/components/avatar.tsx +133 -0
- package/src/components/badge.tsx +65 -0
- package/src/components/button/button.styles.ts +258 -0
- package/src/components/button/button.tsx +215 -0
- package/src/components/button/icon-button.styles.ts +101 -0
- package/src/components/button/icon-button.tsx +100 -0
- package/src/components/button/index.tsx +3 -0
- package/src/components/button/link-button.tsx +184 -0
- package/src/components/cascader.tsx +175 -0
- package/src/components/checkbox.tsx +135 -0
- package/src/components/command.tsx +155 -0
- package/src/components/context-menu.tsx +198 -0
- package/src/components/count-down.tsx +83 -0
- package/src/components/custom-notification.tsx +95 -0
- package/src/components/dialog.tsx +158 -0
- package/src/components/drawer.tsx +116 -0
- package/src/components/dropdown-menu.tsx +196 -0
- package/src/components/energy-progress.tsx +55 -0
- package/src/components/form.tsx +201 -0
- package/src/components/group.tsx +9 -0
- package/src/components/guide.tsx +243 -0
- package/src/components/icon.tsx +89 -0
- package/src/components/icons/outline/DownIcon.tsx +18 -0
- package/src/components/icons/outline/FilterIcon.tsx +21 -0
- package/src/components/icons/outline/arrow-left.tsx +16 -0
- package/src/components/icons/outline/arrow-up-tray.tsx +16 -0
- package/src/components/icons/outline/check-circle.tsx +17 -0
- package/src/components/icons/outline/config.tsx +42 -0
- package/src/components/icons/outline/pencil-square.tsx +16 -0
- package/src/components/icons/outline/trash.tsx +17 -0
- package/src/components/icons/outline/window.tsx +16 -0
- package/src/components/icons/outline/x-circle.tsx +17 -0
- package/src/components/icons/outline/x-mark.tsx +16 -0
- package/src/components/icons/solid/audio-playing.tsx +31 -0
- package/src/components/icons/solid/caret-down.tsx +14 -0
- package/src/components/icons/solid/code.tsx +18 -0
- package/src/components/icons/solid/drag.tsx +14 -0
- package/src/components/icons/solid/phone.tsx +23 -0
- package/src/components/icons/solid/rectangle-group.tsx +14 -0
- package/src/components/image.tsx +151 -0
- package/src/components/input.tsx +118 -0
- package/src/components/label.tsx +26 -0
- package/src/components/link.tsx +123 -0
- package/src/components/marquee/index.css +15 -0
- package/src/components/marquee/marquee.tsx +220 -0
- package/src/components/masonry.tsx +138 -0
- package/src/components/menubar.tsx +234 -0
- package/src/components/mobile/m-tooltip.tsx +34 -0
- package/src/components/modal.tsx +561 -0
- package/src/components/navigation-bar.tsx +100 -0
- package/src/components/number-input.tsx +143 -0
- package/src/components/page-content.tsx +16 -0
- package/src/components/popover.tsx +191 -0
- package/src/components/progress.tsx +80 -0
- package/src/components/radio-group.tsx +44 -0
- package/src/components/scroll-area.tsx +49 -0
- package/src/components/search-bar.tsx +140 -0
- package/src/components/secondary-navigation-bar.tsx +307 -0
- package/src/components/select.tsx +273 -0
- package/src/components/separator.tsx +31 -0
- package/src/components/sheet.tsx +143 -0
- package/src/components/skeleton.tsx +20 -0
- package/src/components/slider.tsx +160 -0
- package/src/components/spinner.tsx +48 -0
- package/src/components/swiper/index.module.scss +88 -0
- package/src/components/swiper/index.tsx +319 -0
- package/src/components/switch.tsx +67 -0
- package/src/components/tabs.tsx +325 -0
- package/src/components/textarea.tsx +71 -0
- package/src/components/toast/toast.tsx +182 -0
- package/src/components/toast/toaster.tsx +160 -0
- package/src/components/toast/use-toast.tsx +248 -0
- package/src/components/toggle-group.tsx +64 -0
- package/src/components/toggle.tsx +46 -0
- package/src/components/tooltip.tsx +283 -0
- package/src/components/typography.tsx +437 -0
- package/src/index.ts +66 -0
- package/src/lib/utils.ts +62 -0
- package/src/stories/Accordion.stories.tsx +64 -0
- package/src/stories/AccordionItem.stories.tsx +48 -0
- package/src/stories/Avatar.stories.ts +58 -0
- package/src/stories/Badge.stories.tsx +40 -0
- package/src/stories/BannerSwiper.stories.tsx +102 -0
- package/src/stories/Button.stories.tsx +543 -0
- package/src/stories/Checkbox.stories.tsx +161 -0
- package/src/stories/Configure.mdx +341 -0
- package/src/stories/CssProperties.mdx +30 -0
- package/src/stories/Description.stories.ts +70 -0
- package/src/stories/Display.stories.ts +64 -0
- package/src/stories/FeaturedSwiper.stories.tsx +6978 -0
- package/src/stories/GridSwiper.stories.tsx +1407 -0
- package/src/stories/Guide.stories.tsx +247 -0
- package/src/stories/Heading.stories.ts +89 -0
- package/src/stories/Icon.stories.ts +77 -0
- package/src/stories/IconButton.stories.tsx +301 -0
- package/src/stories/IconTextButton.stories.ts +59 -0
- package/src/stories/Image.stories.ts +55 -0
- package/src/stories/Input.stories.tsx +203 -0
- package/src/stories/Modal.stories.tsx +144 -0
- package/src/stories/NavigationBar.stories.tsx +81 -0
- package/src/stories/Notification.stories.tsx +276 -0
- package/src/stories/Popover.stories.tsx +100 -0
- package/src/stories/SearchBar.stories.ts +43 -0
- package/src/stories/SecondaryNavigationBar.stories.tsx +199 -0
- package/src/stories/Select.stories.tsx +107 -0
- package/src/stories/Separator.stories.tsx +49 -0
- package/src/stories/Spinner.stories.tsx +48 -0
- package/src/stories/SubHeading.stories.ts +64 -0
- package/src/stories/Swich.stories.tsx +69 -0
- package/src/stories/Tabs.stories.tsx +90 -0
- package/src/stories/Text.stories.ts +78 -0
- package/src/stories/Textarea.stories.tsx +155 -0
- package/src/stories/Toast.stories.tsx +424 -0
- package/src/stories/Tooltip.stories.tsx +244 -0
- package/src/stories/ViewAutoSwiper.stories.tsx +1408 -0
- package/src/styles/components-dark.scss +212 -0
- package/src/styles/components-light.scss +210 -0
- package/src/styles/design-dark.scss +330 -0
- package/src/styles/design-light.scss +345 -0
- package/src/styles/design2-dark.scss +319 -0
- package/src/styles/design2-light.scss +364 -0
- package/src/styles/font.css +19 -0
- package/src/styles/global.scss +251 -0
- package/src/styles/md-viewer.scss +155 -0
- package/src/styles/new-tokens.scss +255 -0
- package/src/styles/tokens.scss +401 -0
- package/src/types/scss.d.ts +24 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
|
|
6
|
+
import { cn } from '@/lib/utils';
|
|
7
|
+
|
|
8
|
+
import { Icon } from './icon';
|
|
9
|
+
import { Separator } from './separator';
|
|
10
|
+
import { Text } from './typography';
|
|
11
|
+
import DownIcon from './icons/outline/DownIcon';
|
|
12
|
+
|
|
13
|
+
const Accordion = AccordionPrimitive.Root;
|
|
14
|
+
|
|
15
|
+
export type AccordionItemProps = React.ComponentPropsWithoutRef<
|
|
16
|
+
typeof AccordionPrimitive.Item
|
|
17
|
+
> & {
|
|
18
|
+
count?: number;
|
|
19
|
+
label?: string;
|
|
20
|
+
headerClassName?: string;
|
|
21
|
+
triggerClassName?: string;
|
|
22
|
+
sticky?: boolean;
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
};
|
|
25
|
+
const AccordionItem = React.forwardRef<
|
|
26
|
+
React.ElementRef<typeof AccordionPrimitive.Item>,
|
|
27
|
+
AccordionItemProps
|
|
28
|
+
>((props, ref) => {
|
|
29
|
+
const { className, triggerClassName, sticky, children, label, count } = props;
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<AccordionPrimitive.Item
|
|
33
|
+
ref={ref}
|
|
34
|
+
className={cn('w-full', className)}
|
|
35
|
+
{...props}
|
|
36
|
+
>
|
|
37
|
+
<AccordionTrigger
|
|
38
|
+
label={label}
|
|
39
|
+
count={count}
|
|
40
|
+
className={triggerClassName as string}
|
|
41
|
+
sticky={sticky}
|
|
42
|
+
/>
|
|
43
|
+
<AccordionContent>{children}</AccordionContent>
|
|
44
|
+
</AccordionPrimitive.Item>
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
AccordionItem.displayName = 'AccordionItem';
|
|
49
|
+
|
|
50
|
+
type AccordionTriggerProps = React.ComponentPropsWithoutRef<
|
|
51
|
+
typeof AccordionPrimitive.Trigger
|
|
52
|
+
> & {
|
|
53
|
+
count?: number;
|
|
54
|
+
label?: string;
|
|
55
|
+
sticky?: boolean;
|
|
56
|
+
headerClassName?: string;
|
|
57
|
+
};
|
|
58
|
+
const AccordionTrigger = React.forwardRef<
|
|
59
|
+
React.ElementRef<typeof AccordionPrimitive.Trigger>,
|
|
60
|
+
AccordionTriggerProps
|
|
61
|
+
>((props, ref) => {
|
|
62
|
+
const {
|
|
63
|
+
className,
|
|
64
|
+
headerClassName = '',
|
|
65
|
+
count,
|
|
66
|
+
label,
|
|
67
|
+
sticky,
|
|
68
|
+
...rest
|
|
69
|
+
} = props;
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<AccordionPrimitive.Header
|
|
73
|
+
className={cn('flex', headerClassName, sticky && 'sticky top-0 z-10')}
|
|
74
|
+
>
|
|
75
|
+
<AccordionPrimitive.Trigger
|
|
76
|
+
ref={ref}
|
|
77
|
+
{...rest}
|
|
78
|
+
className={cn(
|
|
79
|
+
'flex flex-1 items-center justify-between font-medium transition-all [&[data-state=closed]>div>div>div>svg]:-rotate-90', // [&[data-state=open]>div>div>svg]:rotate-180
|
|
80
|
+
className
|
|
81
|
+
)}
|
|
82
|
+
>
|
|
83
|
+
<div className="w-full flex flex-col justify-center">
|
|
84
|
+
<div className="py-3">
|
|
85
|
+
<Separator />
|
|
86
|
+
</div>
|
|
87
|
+
<div className="w-full flex justify-between items-center py-1.5">
|
|
88
|
+
<div className="flex justify-center items-center space-x-1">
|
|
89
|
+
<Icon
|
|
90
|
+
component={DownIcon}
|
|
91
|
+
size="2xs"
|
|
92
|
+
className="fill-Colors-Foreground-Subtlest"
|
|
93
|
+
/>
|
|
94
|
+
<Text size="lg" weight="medium" className="truncate text-left">
|
|
95
|
+
{label}
|
|
96
|
+
</Text>
|
|
97
|
+
</div>
|
|
98
|
+
{count ? (
|
|
99
|
+
<Text size="sm" color="subtlest" className="flex-shrink-0">
|
|
100
|
+
{count}
|
|
101
|
+
</Text>
|
|
102
|
+
) : null}
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</AccordionPrimitive.Trigger>
|
|
106
|
+
</AccordionPrimitive.Header>
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
|
|
110
|
+
|
|
111
|
+
const AccordionContent = React.forwardRef<
|
|
112
|
+
React.ElementRef<typeof AccordionPrimitive.Content>,
|
|
113
|
+
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
|
|
114
|
+
>(({ className, children, ...props }, ref) => (
|
|
115
|
+
<AccordionPrimitive.Content
|
|
116
|
+
ref={ref}
|
|
117
|
+
{...props}
|
|
118
|
+
className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
|
119
|
+
>
|
|
120
|
+
<div className={cn(className)}>{children}</div>
|
|
121
|
+
</AccordionPrimitive.Content>
|
|
122
|
+
));
|
|
123
|
+
|
|
124
|
+
AccordionContent.displayName = AccordionPrimitive.Content.displayName;
|
|
125
|
+
|
|
126
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
|
|
6
|
+
import { buttonVariants } from './button/button';
|
|
7
|
+
import { cn } from '@/lib/utils';
|
|
8
|
+
|
|
9
|
+
const AlertDialog = AlertDialogPrimitive.Root;
|
|
10
|
+
|
|
11
|
+
const AlertDialogPortal = AlertDialogPrimitive.Portal;
|
|
12
|
+
|
|
13
|
+
const AlertDialogTrigger = React.forwardRef<
|
|
14
|
+
React.ElementRef<typeof AlertDialogPrimitive.Trigger>,
|
|
15
|
+
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Trigger>
|
|
16
|
+
>(({ className, ...props }, ref) => (
|
|
17
|
+
<AlertDialogPrimitive.Trigger
|
|
18
|
+
ref={ref}
|
|
19
|
+
className={cn(
|
|
20
|
+
'ring-offset-cc-Focus-Rings-Brand-default focus-visible:outline-none focus-visible:shadow-none focus-visible:ring-2 focus-visible:ring-cc-Focus-Rings-Brand-default focus-visible:ring-offset-1',
|
|
21
|
+
className
|
|
22
|
+
)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
));
|
|
26
|
+
AlertDialogTrigger.displayName = AlertDialogPrimitive.Trigger.displayName;
|
|
27
|
+
|
|
28
|
+
const AlertDialogOverlay = React.forwardRef<
|
|
29
|
+
React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
|
|
30
|
+
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
|
|
31
|
+
>(({ className, ...props }, ref) => (
|
|
32
|
+
<AlertDialogPrimitive.Overlay
|
|
33
|
+
className={cn(
|
|
34
|
+
'fixed inset-0 z-50 bg-Colors-Background-Utilities-Overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
|
35
|
+
className
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
ref={ref}
|
|
39
|
+
/>
|
|
40
|
+
));
|
|
41
|
+
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
|
42
|
+
|
|
43
|
+
const AlertDialogContent = React.forwardRef<
|
|
44
|
+
React.ElementRef<typeof AlertDialogPrimitive.Content>,
|
|
45
|
+
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>
|
|
46
|
+
>(({ className, ...props }, ref) => (
|
|
47
|
+
<AlertDialogPortal>
|
|
48
|
+
<AlertDialogOverlay />
|
|
49
|
+
<AlertDialogPrimitive.Content
|
|
50
|
+
ref={ref}
|
|
51
|
+
className={cn(
|
|
52
|
+
'fixed left-[50%] top-[50%] z-50 grid w-full rounded-4xl max-w-lg translate-x-[-50%] translate-y-[-50%] bg-Colors-Background-Normal-Primary-Default shadow-modal-default duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] ring-offset-cc-Focus-Rings-Brand-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cc-Focus-Rings-Brand-default focus-visible:ring-offset-1',
|
|
53
|
+
className
|
|
54
|
+
)}
|
|
55
|
+
{...props}
|
|
56
|
+
/>
|
|
57
|
+
</AlertDialogPortal>
|
|
58
|
+
));
|
|
59
|
+
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
|
|
60
|
+
|
|
61
|
+
function AlertDialogHeader({
|
|
62
|
+
className,
|
|
63
|
+
...props
|
|
64
|
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
65
|
+
return (
|
|
66
|
+
<div
|
|
67
|
+
className={cn('flex flex-col p-4 text-Colors-Text-Default', className)}
|
|
68
|
+
{...props}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
AlertDialogHeader.displayName = 'AlertDialogHeader';
|
|
73
|
+
|
|
74
|
+
function AlertDialogFooter({
|
|
75
|
+
className,
|
|
76
|
+
...props
|
|
77
|
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
78
|
+
return (
|
|
79
|
+
<div
|
|
80
|
+
className={cn('flex justify-end p-4 space-x-4', className)}
|
|
81
|
+
{...props}
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
AlertDialogFooter.displayName = 'AlertDialogFooter';
|
|
86
|
+
|
|
87
|
+
const AlertDialogTitle = React.forwardRef<
|
|
88
|
+
React.ElementRef<typeof AlertDialogPrimitive.Title>,
|
|
89
|
+
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
|
|
90
|
+
>(({ className, ...props }, ref) => (
|
|
91
|
+
<AlertDialogPrimitive.Title
|
|
92
|
+
ref={ref}
|
|
93
|
+
className={cn('text-xl font-normal', className)}
|
|
94
|
+
{...props}
|
|
95
|
+
/>
|
|
96
|
+
));
|
|
97
|
+
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
|
98
|
+
|
|
99
|
+
const AlertDialogDescription = React.forwardRef<
|
|
100
|
+
React.ElementRef<typeof AlertDialogPrimitive.Description>,
|
|
101
|
+
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
|
|
102
|
+
>(({ className, ...props }, ref) => (
|
|
103
|
+
<AlertDialogPrimitive.Description
|
|
104
|
+
ref={ref}
|
|
105
|
+
className={cn('text-sm text-Colors-Text-Subtle px-4', className)}
|
|
106
|
+
{...props}
|
|
107
|
+
/>
|
|
108
|
+
));
|
|
109
|
+
AlertDialogDescription.displayName =
|
|
110
|
+
AlertDialogPrimitive.Description.displayName;
|
|
111
|
+
|
|
112
|
+
const AlertDialogAction = React.forwardRef<
|
|
113
|
+
React.ElementRef<typeof AlertDialogPrimitive.Action>,
|
|
114
|
+
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
|
|
115
|
+
>(({ className, ...props }, ref) => (
|
|
116
|
+
<AlertDialogPrimitive.Action
|
|
117
|
+
ref={ref}
|
|
118
|
+
className={cn(buttonVariants(), className)}
|
|
119
|
+
{...props}
|
|
120
|
+
/>
|
|
121
|
+
));
|
|
122
|
+
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
|
|
123
|
+
|
|
124
|
+
const AlertDialogCancel = React.forwardRef<
|
|
125
|
+
React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
|
|
126
|
+
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
|
|
127
|
+
>(({ className, ...props }, ref) => (
|
|
128
|
+
<AlertDialogPrimitive.Cancel
|
|
129
|
+
ref={ref}
|
|
130
|
+
className={cn(buttonVariants({ variant: 'secondary' }), className)}
|
|
131
|
+
{...props}
|
|
132
|
+
/>
|
|
133
|
+
));
|
|
134
|
+
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
|
135
|
+
|
|
136
|
+
export {
|
|
137
|
+
AlertDialog,
|
|
138
|
+
AlertDialogPortal,
|
|
139
|
+
AlertDialogOverlay,
|
|
140
|
+
AlertDialogTrigger,
|
|
141
|
+
AlertDialogContent,
|
|
142
|
+
AlertDialogHeader,
|
|
143
|
+
AlertDialogFooter,
|
|
144
|
+
AlertDialogTitle,
|
|
145
|
+
AlertDialogDescription,
|
|
146
|
+
AlertDialogAction,
|
|
147
|
+
AlertDialogCancel,
|
|
148
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
|
|
6
|
+
const alertVariants = cva(
|
|
7
|
+
'relative rounded-xl border flex justify-center flex-col md:flex-row md:justify-between items-center gap-3 py-2 px-3 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-Colors-Text-Default',
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default:
|
|
12
|
+
'bg-Colors-Background-Normal-Primary-Default text-Colors-Text-Default',
|
|
13
|
+
destructive:
|
|
14
|
+
'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',
|
|
15
|
+
warning:
|
|
16
|
+
'bg-surface-accent-yellow-subtlest border-surface-accent-yellow-subtle text-Colors-Text-Default',
|
|
17
|
+
info: 'bg-surface-accent-blue-subtlest border-surface-accent-blue-subtle text-Colors-Text-Default',
|
|
18
|
+
error:
|
|
19
|
+
'bg-surface-accent-red-subtlest border-surface-accent-red-subtle text-Colors-Text-Default',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
variant: 'default',
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const Alert = React.forwardRef<
|
|
29
|
+
HTMLDivElement,
|
|
30
|
+
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
|
|
31
|
+
>(({ className, variant, ...props }, ref) => (
|
|
32
|
+
<div
|
|
33
|
+
ref={ref}
|
|
34
|
+
role="alert"
|
|
35
|
+
className={cn(alertVariants({ variant }), className)}
|
|
36
|
+
{...props}
|
|
37
|
+
/>
|
|
38
|
+
));
|
|
39
|
+
Alert.displayName = 'Alert';
|
|
40
|
+
|
|
41
|
+
const AlertTitle = React.forwardRef<
|
|
42
|
+
HTMLParagraphElement,
|
|
43
|
+
React.HTMLAttributes<HTMLHeadingElement>
|
|
44
|
+
>(({ className, ...props }, ref) => (
|
|
45
|
+
<h5
|
|
46
|
+
ref={ref}
|
|
47
|
+
className={cn('mb-1 font-medium leading-none tracking-tight', className)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
));
|
|
51
|
+
AlertTitle.displayName = 'AlertTitle';
|
|
52
|
+
|
|
53
|
+
const AlertDescription = React.forwardRef<
|
|
54
|
+
HTMLParagraphElement,
|
|
55
|
+
React.HTMLAttributes<HTMLParagraphElement>
|
|
56
|
+
>(({ className, ...props }, ref) => (
|
|
57
|
+
<div
|
|
58
|
+
ref={ref}
|
|
59
|
+
className={cn('text-base [&_p]:leading-relaxed', className)}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
));
|
|
63
|
+
AlertDescription.displayName = 'AlertDescription';
|
|
64
|
+
|
|
65
|
+
export { Alert, AlertDescription, AlertTitle };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import PlayIcon from '@heroicons/react/20/solid/esm/PlayIcon';
|
|
2
|
+
import { useAudio } from 'react-use';
|
|
3
|
+
|
|
4
|
+
import useAudioPlayer from '@/common/hooks/useAudioPlayer';
|
|
5
|
+
import { IconButton } from './button/icon-button';
|
|
6
|
+
import AudioPlaying from './icons/solid/audio-playing';
|
|
7
|
+
import { durationFormatter, getPercent } from '@/common/utils/common-helper';
|
|
8
|
+
|
|
9
|
+
export interface IAudioProps {
|
|
10
|
+
src: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default function AudioPlayer({ src }: IAudioProps) {
|
|
14
|
+
const AudioComp = useAudioPlayer();
|
|
15
|
+
|
|
16
|
+
const [audio, state, controls, ref] = useAudio(
|
|
17
|
+
<AudioComp src={src} onEnded={() => controls.seek(0)} />
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const { paused, time, playing } = state;
|
|
21
|
+
const duration = state.duration || ref.current?.duration || 0;
|
|
22
|
+
|
|
23
|
+
const onAudioToggle = () => {
|
|
24
|
+
if (paused) {
|
|
25
|
+
// 避免同时播放多个音频
|
|
26
|
+
const audios = document.getElementsByTagName('audio');
|
|
27
|
+
// eslint-disable-next-line no-plusplus
|
|
28
|
+
for (let i = 0, len = audios.length; i < len; i++) {
|
|
29
|
+
audios[i].pause();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
controls.play();
|
|
33
|
+
} else {
|
|
34
|
+
controls.pause();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div className="flex flex-col space-y-1 w-full overflow-hidden">
|
|
40
|
+
<div
|
|
41
|
+
className="bg-Colors-Background-Brand-Default h-px w-full items-start"
|
|
42
|
+
style={{ width: `${getPercent(time, duration) * 100}%` }}
|
|
43
|
+
/>
|
|
44
|
+
<div className="flex items-center space-x-3">
|
|
45
|
+
<IconButton className="w-6 h-6" onClick={onAudioToggle}>
|
|
46
|
+
{paused ? <PlayIcon className="w-3 h-3 ml-0.5" /> : <AudioPlaying />}
|
|
47
|
+
</IconButton>
|
|
48
|
+
<div className="flex flex-col grow overflow-hidden">
|
|
49
|
+
<div className="text-sm text-Colors-Text-Brand-Default truncate">
|
|
50
|
+
{durationFormatter(((playing || paused) && time) || duration)}
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
{audio}
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Primitive } from '@radix-ui/react-primitive';
|
|
4
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
|
|
7
|
+
import { cn } from '@/lib/utils';
|
|
8
|
+
|
|
9
|
+
type ImageLoadingStatus = 'loading' | 'loaded' | 'error';
|
|
10
|
+
|
|
11
|
+
const avatarVariants = cva(
|
|
12
|
+
'relative flex shrink-0 overflow-hidden bg-Colors-Background-Neutral-Primary-Default',
|
|
13
|
+
{
|
|
14
|
+
variants: {
|
|
15
|
+
size: {
|
|
16
|
+
xs: 'w-5 h-5 rounded', // 20 4
|
|
17
|
+
sm: 'w-6 h-6 rounded-md', // 24 6
|
|
18
|
+
md: 'w-8 h-8 rounded-lg', // 32 8
|
|
19
|
+
lg: 'w-9 h-9 rounded-lg', // 36 8
|
|
20
|
+
xl: 'w-12 h-12 rounded-xl', // 48 10 no
|
|
21
|
+
'2xl': 'w-14 h-14 rounded-xl', // 56 12
|
|
22
|
+
'3xl': 'w-16 h-16 rounded-xl', // 64 12
|
|
23
|
+
'4xl': 'w-18 h-18 rounded-2xl', // 72 14 no
|
|
24
|
+
'5xl': 'w-21 h-21 rounded-2xl', // 84 16
|
|
25
|
+
'6xl': 'w-24 h-24 rounded-3xl', // 96 20
|
|
26
|
+
'7xl': 'w-30 h-30 rounded-4xl', // 120 24
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
defaultVariants: {
|
|
30
|
+
size: 'md',
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const AvatarRoot = React.forwardRef<
|
|
36
|
+
React.ElementRef<typeof Primitive.span>,
|
|
37
|
+
React.ComponentPropsWithoutRef<typeof Primitive.span> &
|
|
38
|
+
VariantProps<typeof avatarVariants>
|
|
39
|
+
>(({ className, size = 'md', ...passProps }, ref) => (
|
|
40
|
+
<Primitive.span
|
|
41
|
+
ref={ref}
|
|
42
|
+
className={cn(avatarVariants({ size }), className)}
|
|
43
|
+
{...passProps}
|
|
44
|
+
/>
|
|
45
|
+
));
|
|
46
|
+
AvatarRoot.displayName = 'Avatar';
|
|
47
|
+
|
|
48
|
+
const AvatarImage = React.forwardRef<
|
|
49
|
+
React.ElementRef<typeof Primitive.img>,
|
|
50
|
+
React.ComponentPropsWithoutRef<typeof Primitive.img>
|
|
51
|
+
>(({ className, onLoad, onError, ...props }, ref) => {
|
|
52
|
+
const [loadingStatus, setLoadingStatus] =
|
|
53
|
+
React.useState<ImageLoadingStatus>('loading');
|
|
54
|
+
const handleLoad = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
|
|
55
|
+
setLoadingStatus('loaded');
|
|
56
|
+
if (onLoad) {
|
|
57
|
+
onLoad(event);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const handleError = (
|
|
61
|
+
event: React.SyntheticEvent<HTMLImageElement, Event>
|
|
62
|
+
) => {
|
|
63
|
+
setLoadingStatus('error');
|
|
64
|
+
if (onError) {
|
|
65
|
+
onError(event);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return loadingStatus !== 'error' ? (
|
|
70
|
+
<Primitive.img
|
|
71
|
+
ref={ref}
|
|
72
|
+
className={cn('aspect-square h-full w-full object-cover', className)}
|
|
73
|
+
onLoad={handleLoad}
|
|
74
|
+
onError={handleError}
|
|
75
|
+
{...props}
|
|
76
|
+
/>
|
|
77
|
+
) : (
|
|
78
|
+
<Primitive.span
|
|
79
|
+
ref={ref}
|
|
80
|
+
className={cn(
|
|
81
|
+
'flex h-full w-full items-center justify-center bg-Colors-Background-Neutral-Primary-Default',
|
|
82
|
+
className
|
|
83
|
+
)}
|
|
84
|
+
{...props}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
AvatarImage.displayName = 'AvatarImage';
|
|
89
|
+
|
|
90
|
+
const Avatar = React.forwardRef<
|
|
91
|
+
React.ElementRef<typeof Primitive.img>,
|
|
92
|
+
React.ComponentPropsWithoutRef<typeof Primitive.img> &
|
|
93
|
+
VariantProps<typeof avatarVariants> & {
|
|
94
|
+
variant?: 'bot' | 'user' | 'widget';
|
|
95
|
+
border?: boolean;
|
|
96
|
+
rootStyle?: React.CSSProperties;
|
|
97
|
+
}
|
|
98
|
+
>(
|
|
99
|
+
(
|
|
100
|
+
{
|
|
101
|
+
className,
|
|
102
|
+
rootStyle,
|
|
103
|
+
size,
|
|
104
|
+
src,
|
|
105
|
+
variant = 'bot',
|
|
106
|
+
border = true,
|
|
107
|
+
...passProps
|
|
108
|
+
},
|
|
109
|
+
ref
|
|
110
|
+
) => {
|
|
111
|
+
const defaultSrc =
|
|
112
|
+
variant === 'user'
|
|
113
|
+
? 'https://www.myshellstatic.com/cdn-cgi/image/quality=40,format=webp/image/user/avatar/default/20240715/avatar.png'
|
|
114
|
+
: 'https://www.myshellstatic.com/cdn-cgi/image/quality=40,format=webp/image/bot/logo/20240106/default.png';
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<AvatarRoot
|
|
118
|
+
size={size}
|
|
119
|
+
className={cn(
|
|
120
|
+
border && 'border-Colors-Border-Default border-[0.3px]',
|
|
121
|
+
className
|
|
122
|
+
)}
|
|
123
|
+
style={rootStyle}
|
|
124
|
+
>
|
|
125
|
+
<AvatarImage ref={ref} {...passProps} src={src || defaultSrc} />
|
|
126
|
+
</AvatarRoot>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
Avatar.displayName = 'Avatar';
|
|
132
|
+
|
|
133
|
+
export { Avatar, AvatarRoot, AvatarImage };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/* eslint-disable react/require-default-props */
|
|
2
|
+
/* eslint-disable import/no-unused-modules */
|
|
3
|
+
|
|
4
|
+
import { VariantProps, cva } from 'class-variance-authority';
|
|
5
|
+
import { ClassNameValue } from 'tailwind-merge';
|
|
6
|
+
|
|
7
|
+
import { cn } from '@/lib/utils';
|
|
8
|
+
|
|
9
|
+
const badgeVariants = cva(
|
|
10
|
+
'rounded-full flex items-center justify-center text-Colors-Text-Default',
|
|
11
|
+
{
|
|
12
|
+
variants: {
|
|
13
|
+
status: {
|
|
14
|
+
default: 'w-2 h-2 bg-Colors-Foreground-Critical-Default',
|
|
15
|
+
unRead:
|
|
16
|
+
'min-w-2 min-h-4 bg-Colors-Foreground-Critical-Default px-1.5 text-Colors-Text-Static-White text-2xs font-medium',
|
|
17
|
+
cardUnRead:
|
|
18
|
+
'min-w-4 min-h-4 bg-Colors-Foreground-Critical-Default px-1.5 text-Colors-Text-Static-White text-2xs font-medium',
|
|
19
|
+
public:
|
|
20
|
+
'w-2.5 h-2.5 bg-Colors-Utit border-[2px] bg-Colors-Utility-Lake-Blue-50 border-Colors-Utility-Lake-Blue-10',
|
|
21
|
+
private:
|
|
22
|
+
'w-2.5 h-2.5 bg-Colors-Utility-Khaki-50 border-Colors-Utility-Khaki-10 border-[2px]',
|
|
23
|
+
hidden:
|
|
24
|
+
'w-2.5 h-2.5 bg-Colors-Utility-Gray-40 border-Colors-Utility-Gray-10 border-[2px]',
|
|
25
|
+
new: 'w-8.5 h-4 pb-0.5 flex juctify-center items-center bg-Colors-Foreground-Critical-Default px-1.5',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: {
|
|
29
|
+
status: 'default',
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
interface BadgeProps extends VariantProps<typeof badgeVariants> {
|
|
34
|
+
className?: ClassNameValue;
|
|
35
|
+
status?:
|
|
36
|
+
| 'default'
|
|
37
|
+
| 'unRead'
|
|
38
|
+
| 'cardUnRead'
|
|
39
|
+
| 'public'
|
|
40
|
+
| 'private'
|
|
41
|
+
| 'hidden'
|
|
42
|
+
| 'new';
|
|
43
|
+
count?: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default function Badge(props: BadgeProps) {
|
|
47
|
+
const { status, count, className } = props;
|
|
48
|
+
const unReadCount = count && count < 100 ? count : '99+';
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div className={cn(badgeVariants({ status }), className)}>
|
|
52
|
+
{status === 'new' ? (
|
|
53
|
+
<span className="text-2xs font-medium text-Colors-Text-Static-White leading-[1.3]">
|
|
54
|
+
New
|
|
55
|
+
</span>
|
|
56
|
+
) : (
|
|
57
|
+
<span className="font-medium text-2xs leading-[1.3]">
|
|
58
|
+
{unReadCount && (status === 'unRead' || status === 'cardUnRead')
|
|
59
|
+
? count
|
|
60
|
+
: null}
|
|
61
|
+
</span>
|
|
62
|
+
)}
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|