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.
Files changed (151) hide show
  1. package/README.md +268 -0
  2. package/dist/assets/audio-playing.json +3657 -0
  3. package/dist/index.cjs +9654 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +1431 -0
  6. package/dist/index.d.ts +1431 -0
  7. package/dist/index.js +8788 -0
  8. package/dist/index.js.map +1 -0
  9. package/package.json +140 -0
  10. package/src/common/assets/audio-playing.json +3657 -0
  11. package/src/common/constants/constants.ts +24 -0
  12. package/src/common/constants/types/common.ts +10 -0
  13. package/src/common/hooks/useAudioPlayer.tsx +198 -0
  14. package/src/common/hooks/useDevice.ts +26 -0
  15. package/src/common/hooks/useNativeBridge.ts +42 -0
  16. package/src/common/hooks/useNotification.tsx +179 -0
  17. package/src/common/hooks/useWindowWidth.ts +19 -0
  18. package/src/common/utils/common-helper.ts +81 -0
  19. package/src/components/ItemDemo.tsx +15 -0
  20. package/src/components/accordion.tsx +126 -0
  21. package/src/components/alert-dialog.tsx +148 -0
  22. package/src/components/alert.tsx +65 -0
  23. package/src/components/aspect-ratio.tsx +7 -0
  24. package/src/components/audio-player.tsx +58 -0
  25. package/src/components/avatar.tsx +133 -0
  26. package/src/components/badge.tsx +65 -0
  27. package/src/components/button/button.styles.ts +258 -0
  28. package/src/components/button/button.tsx +215 -0
  29. package/src/components/button/icon-button.styles.ts +101 -0
  30. package/src/components/button/icon-button.tsx +100 -0
  31. package/src/components/button/index.tsx +3 -0
  32. package/src/components/button/link-button.tsx +184 -0
  33. package/src/components/cascader.tsx +175 -0
  34. package/src/components/checkbox.tsx +135 -0
  35. package/src/components/command.tsx +155 -0
  36. package/src/components/context-menu.tsx +198 -0
  37. package/src/components/count-down.tsx +83 -0
  38. package/src/components/custom-notification.tsx +95 -0
  39. package/src/components/dialog.tsx +158 -0
  40. package/src/components/drawer.tsx +116 -0
  41. package/src/components/dropdown-menu.tsx +196 -0
  42. package/src/components/energy-progress.tsx +55 -0
  43. package/src/components/form.tsx +201 -0
  44. package/src/components/group.tsx +9 -0
  45. package/src/components/guide.tsx +243 -0
  46. package/src/components/icon.tsx +89 -0
  47. package/src/components/icons/outline/DownIcon.tsx +18 -0
  48. package/src/components/icons/outline/FilterIcon.tsx +21 -0
  49. package/src/components/icons/outline/arrow-left.tsx +16 -0
  50. package/src/components/icons/outline/arrow-up-tray.tsx +16 -0
  51. package/src/components/icons/outline/check-circle.tsx +17 -0
  52. package/src/components/icons/outline/config.tsx +42 -0
  53. package/src/components/icons/outline/pencil-square.tsx +16 -0
  54. package/src/components/icons/outline/trash.tsx +17 -0
  55. package/src/components/icons/outline/window.tsx +16 -0
  56. package/src/components/icons/outline/x-circle.tsx +17 -0
  57. package/src/components/icons/outline/x-mark.tsx +16 -0
  58. package/src/components/icons/solid/audio-playing.tsx +31 -0
  59. package/src/components/icons/solid/caret-down.tsx +14 -0
  60. package/src/components/icons/solid/code.tsx +18 -0
  61. package/src/components/icons/solid/drag.tsx +14 -0
  62. package/src/components/icons/solid/phone.tsx +23 -0
  63. package/src/components/icons/solid/rectangle-group.tsx +14 -0
  64. package/src/components/image.tsx +151 -0
  65. package/src/components/input.tsx +118 -0
  66. package/src/components/label.tsx +26 -0
  67. package/src/components/link.tsx +123 -0
  68. package/src/components/marquee/index.css +15 -0
  69. package/src/components/marquee/marquee.tsx +220 -0
  70. package/src/components/masonry.tsx +138 -0
  71. package/src/components/menubar.tsx +234 -0
  72. package/src/components/mobile/m-tooltip.tsx +34 -0
  73. package/src/components/modal.tsx +561 -0
  74. package/src/components/navigation-bar.tsx +100 -0
  75. package/src/components/number-input.tsx +143 -0
  76. package/src/components/page-content.tsx +16 -0
  77. package/src/components/popover.tsx +191 -0
  78. package/src/components/progress.tsx +80 -0
  79. package/src/components/radio-group.tsx +44 -0
  80. package/src/components/scroll-area.tsx +49 -0
  81. package/src/components/search-bar.tsx +140 -0
  82. package/src/components/secondary-navigation-bar.tsx +307 -0
  83. package/src/components/select.tsx +273 -0
  84. package/src/components/separator.tsx +31 -0
  85. package/src/components/sheet.tsx +143 -0
  86. package/src/components/skeleton.tsx +20 -0
  87. package/src/components/slider.tsx +160 -0
  88. package/src/components/spinner.tsx +48 -0
  89. package/src/components/swiper/index.module.scss +88 -0
  90. package/src/components/swiper/index.tsx +319 -0
  91. package/src/components/switch.tsx +67 -0
  92. package/src/components/tabs.tsx +325 -0
  93. package/src/components/textarea.tsx +71 -0
  94. package/src/components/toast/toast.tsx +182 -0
  95. package/src/components/toast/toaster.tsx +160 -0
  96. package/src/components/toast/use-toast.tsx +248 -0
  97. package/src/components/toggle-group.tsx +64 -0
  98. package/src/components/toggle.tsx +46 -0
  99. package/src/components/tooltip.tsx +283 -0
  100. package/src/components/typography.tsx +437 -0
  101. package/src/index.ts +66 -0
  102. package/src/lib/utils.ts +62 -0
  103. package/src/stories/Accordion.stories.tsx +64 -0
  104. package/src/stories/AccordionItem.stories.tsx +48 -0
  105. package/src/stories/Avatar.stories.ts +58 -0
  106. package/src/stories/Badge.stories.tsx +40 -0
  107. package/src/stories/BannerSwiper.stories.tsx +102 -0
  108. package/src/stories/Button.stories.tsx +543 -0
  109. package/src/stories/Checkbox.stories.tsx +161 -0
  110. package/src/stories/Configure.mdx +341 -0
  111. package/src/stories/CssProperties.mdx +30 -0
  112. package/src/stories/Description.stories.ts +70 -0
  113. package/src/stories/Display.stories.ts +64 -0
  114. package/src/stories/FeaturedSwiper.stories.tsx +6978 -0
  115. package/src/stories/GridSwiper.stories.tsx +1407 -0
  116. package/src/stories/Guide.stories.tsx +247 -0
  117. package/src/stories/Heading.stories.ts +89 -0
  118. package/src/stories/Icon.stories.ts +77 -0
  119. package/src/stories/IconButton.stories.tsx +301 -0
  120. package/src/stories/IconTextButton.stories.ts +59 -0
  121. package/src/stories/Image.stories.ts +55 -0
  122. package/src/stories/Input.stories.tsx +203 -0
  123. package/src/stories/Modal.stories.tsx +144 -0
  124. package/src/stories/NavigationBar.stories.tsx +81 -0
  125. package/src/stories/Notification.stories.tsx +276 -0
  126. package/src/stories/Popover.stories.tsx +100 -0
  127. package/src/stories/SearchBar.stories.ts +43 -0
  128. package/src/stories/SecondaryNavigationBar.stories.tsx +199 -0
  129. package/src/stories/Select.stories.tsx +107 -0
  130. package/src/stories/Separator.stories.tsx +49 -0
  131. package/src/stories/Spinner.stories.tsx +48 -0
  132. package/src/stories/SubHeading.stories.ts +64 -0
  133. package/src/stories/Swich.stories.tsx +69 -0
  134. package/src/stories/Tabs.stories.tsx +90 -0
  135. package/src/stories/Text.stories.ts +78 -0
  136. package/src/stories/Textarea.stories.tsx +155 -0
  137. package/src/stories/Toast.stories.tsx +424 -0
  138. package/src/stories/Tooltip.stories.tsx +244 -0
  139. package/src/stories/ViewAutoSwiper.stories.tsx +1408 -0
  140. package/src/styles/components-dark.scss +212 -0
  141. package/src/styles/components-light.scss +210 -0
  142. package/src/styles/design-dark.scss +330 -0
  143. package/src/styles/design-light.scss +345 -0
  144. package/src/styles/design2-dark.scss +319 -0
  145. package/src/styles/design2-light.scss +364 -0
  146. package/src/styles/font.css +19 -0
  147. package/src/styles/global.scss +251 -0
  148. package/src/styles/md-viewer.scss +155 -0
  149. package/src/styles/new-tokens.scss +255 -0
  150. package/src/styles/tokens.scss +401 -0
  151. package/src/types/scss.d.ts +24 -0
@@ -0,0 +1,437 @@
1
+ /* eslint-disable react/jsx-props-no-spreading */
2
+ /* eslint-disable react/display-name */
3
+
4
+ import { cva, type VariantProps } from 'class-variance-authority';
5
+ import { sanitize } from 'isomorphic-dompurify';
6
+ import * as React from 'react';
7
+
8
+ import { cn } from '@/lib/utils';
9
+
10
+ type DisplayProps = React.HTMLAttributes<HTMLElement> &
11
+ VariantProps<typeof displayVariants>;
12
+ type HeadingProps = React.HTMLAttributes<HTMLElement> &
13
+ VariantProps<typeof headingVariants>;
14
+ type SubHeadingProps = React.HTMLAttributes<HTMLElement> &
15
+ VariantProps<typeof subHeadingVariants>;
16
+ type TextProps = React.HTMLAttributes<HTMLElement> &
17
+ VariantProps<typeof textVariants>;
18
+ type DescriptionProps = React.HTMLAttributes<HTMLElement> &
19
+ VariantProps<typeof descriptionVariants>;
20
+
21
+ const colorMap = {
22
+ default: 'text-Colors-Text-Default',
23
+ subtle: 'text-Colors-Text-Subtle',
24
+ subtler: 'text-Colors-Text-Subtler',
25
+ subtlest: 'text-Colors-Text-Subtlest',
26
+ disabled: 'text-Colors-Text-Disabled',
27
+ inverse: 'text-Colors-Text-Bolder',
28
+ static: 'text-Colors-Text-Static-White',
29
+ 'static-black': 'text-Colors-Text-Static-White',
30
+ brand: 'text-Colors-Text-Brand-Default',
31
+ critical: 'text-Colors-Text-Critical-Default',
32
+ 'critical-bolder': 'text-Colors-Text-Critical-Bolder',
33
+ warning: 'text-Colors-Text-Warning-Default',
34
+ 'warning-bolder': 'text-Colors-Text-Warning-Bolder',
35
+ success: 'text-Colors-Text-Success-Default',
36
+ 'success-bolder': 'text-Colors-Text-Success-Bolder',
37
+ };
38
+ const lineClampMap = {
39
+ 1: 'line-clamp-1',
40
+ 2: 'line-clamp-2',
41
+ 3: 'line-clamp-3',
42
+ 4: 'line-clamp-4',
43
+ 5: 'line-clamp-5',
44
+ 6: 'line-clamp-6',
45
+ };
46
+
47
+ const displayVariants = cva('font-semibold', {
48
+ variants: {
49
+ size: {
50
+ '2xl': 'text-7xl',
51
+ xl: 'text-5xl',
52
+ lg: 'text-3xl',
53
+ md: 'text-2xl',
54
+ sm: 'text-xl',
55
+ xs: 'text-lg',
56
+ },
57
+ color: colorMap,
58
+ lineClamp: lineClampMap,
59
+ },
60
+ defaultVariants: {
61
+ size: 'lg',
62
+ color: 'default',
63
+ },
64
+ });
65
+
66
+ const headingVariants = cva('font-medium', {
67
+ variants: {
68
+ size: {
69
+ h1: 'text-2xl',
70
+ h2: 'text-xl',
71
+ h3: 'text-lg',
72
+ h4: 'text-base',
73
+ h5: 'text-sm',
74
+ },
75
+ color: colorMap,
76
+ lineClamp: lineClampMap,
77
+ },
78
+ defaultVariants: {
79
+ size: 'h1',
80
+ color: 'default',
81
+ },
82
+ });
83
+
84
+ const subHeadingVariants = cva('text-Colors-Text-Default', {
85
+ variants: {
86
+ size: {
87
+ sm: 'text-xs',
88
+ lg: 'text-sm',
89
+ },
90
+ color: colorMap,
91
+ lineClamp: lineClampMap,
92
+ },
93
+ defaultVariants: {
94
+ size: 'lg',
95
+ color: 'default',
96
+ },
97
+ });
98
+
99
+ const textVariants = cva('', {
100
+ variants: {
101
+ size: {
102
+ xs: 'text-xs',
103
+ sm: 'text-sm',
104
+ lg: 'text-base',
105
+ },
106
+ weight: {
107
+ regular: 'font-normal',
108
+ medium: 'font-medium',
109
+ semibold: 'font-semibold',
110
+ },
111
+ color: colorMap,
112
+ lineClamp: lineClampMap,
113
+ },
114
+ defaultVariants: {
115
+ size: 'lg',
116
+ weight: 'regular',
117
+ color: 'default',
118
+ },
119
+ });
120
+
121
+ const descriptionVariants = cva('', {
122
+ variants: {
123
+ size: {
124
+ lg: 'text-xs',
125
+ sm: 'text-2xs',
126
+ },
127
+ weight: {
128
+ regular: 'font-normal',
129
+ medium: 'font-medium',
130
+ },
131
+ color: colorMap,
132
+ lineClamp: lineClampMap,
133
+ },
134
+ defaultVariants: {
135
+ size: 'lg',
136
+ weight: 'regular',
137
+ color: 'subtler',
138
+ },
139
+ });
140
+
141
+ const HComponentMap = {
142
+ h1: 'h1',
143
+ h2: 'h2',
144
+ h3: 'h3',
145
+ h4: 'h4',
146
+ h5: 'h5',
147
+ h6: 'h6',
148
+ } as const;
149
+
150
+ const TextComponentMap = {
151
+ p: 'p',
152
+ blockquote: 'blockquote',
153
+ span: 'span',
154
+ code: 'code',
155
+ bold: 'b',
156
+ italic: 'i',
157
+ strikethrough: 's',
158
+ underline: 'u',
159
+ } as const;
160
+
161
+ type BlockProps = {
162
+ underline?: boolean;
163
+ strikethrough?: boolean;
164
+ strong?: boolean;
165
+ italic?: boolean;
166
+ dangerous?: boolean;
167
+ };
168
+ const renderBlock = (
169
+ {
170
+ underline = false,
171
+ strikethrough = false,
172
+ strong = false,
173
+ italic = false,
174
+ }: BlockProps,
175
+ defaultValue: 'p' | 'span' = 'p'
176
+ ) => {
177
+ const underlineValue = underline && 'underline';
178
+ const strikethroughValue = strikethrough && 'strikethrough';
179
+ const strongValue = strong && 'bold';
180
+ const italicValue = italic && 'italic';
181
+
182
+ return TextComponentMap[
183
+ underlineValue ||
184
+ strikethroughValue ||
185
+ strongValue ||
186
+ italicValue ||
187
+ defaultValue
188
+ ];
189
+ };
190
+
191
+ export const dangerouText = (text: string) => {
192
+ return sanitize(`${text}`, {
193
+ ADD_ATTR: ['target'],
194
+ FORBID_TAGS: [
195
+ 'style',
196
+ 'form',
197
+ 'input',
198
+ 'checkbox',
199
+ 'svg',
200
+ 'script',
201
+ 'iframe',
202
+ 'object',
203
+ 'embed',
204
+ 'applet',
205
+ 'meta',
206
+ 'link',
207
+ 'button',
208
+ 'textarea',
209
+ 'select',
210
+ 'option',
211
+ 'img',
212
+ ],
213
+ FORBID_ATTR: ['action', 'style', 'data-*', 'aria-*', 'srcset', 'on*'],
214
+ });
215
+ };
216
+
217
+ export const Heading = React.forwardRef<
218
+ HTMLHeadingElement,
219
+ HeadingProps & BlockProps
220
+ >((props, ref) => {
221
+ const {
222
+ className,
223
+ size,
224
+ color,
225
+ lineClamp,
226
+ children,
227
+ dangerous,
228
+ ...passProps
229
+ } = props;
230
+ const Comp = HComponentMap[size || 'h1'];
231
+
232
+ const text = dangerous && dangerouText(`${children}`);
233
+
234
+ return (
235
+ <Comp
236
+ ref={ref}
237
+ className={cn(headingVariants({ size, color, lineClamp }), className)}
238
+ {...passProps}
239
+ {...(dangerous && { dangerouslySetInnerHTML: { __html: `${text}` } })}
240
+ >
241
+ {!dangerous ? children : null}
242
+ </Comp>
243
+ );
244
+ });
245
+
246
+ export const Display = React.forwardRef<
247
+ HTMLElement & HTMLParagraphElement,
248
+ DisplayProps & BlockProps
249
+ >((props, ref) => {
250
+ const {
251
+ className,
252
+ size,
253
+ color,
254
+ lineClamp,
255
+ underline,
256
+ strikethrough,
257
+ strong,
258
+ italic,
259
+ children,
260
+ dangerous,
261
+ ...passProps
262
+ } = props;
263
+ const Comp = renderBlock(
264
+ {
265
+ underline,
266
+ strikethrough,
267
+ strong,
268
+ italic,
269
+ },
270
+ 'span'
271
+ );
272
+ const text = dangerous && dangerouText(`${children}`);
273
+
274
+ return (
275
+ <Comp
276
+ ref={ref}
277
+ className={cn(displayVariants({ size, color, lineClamp }), className)}
278
+ {...passProps}
279
+ {...(dangerous && { dangerouslySetInnerHTML: { __html: `${text}` } })}
280
+ >
281
+ {!dangerous ? children : null}
282
+ </Comp>
283
+ );
284
+ });
285
+
286
+ export const Title = Heading;
287
+
288
+ export const SubHeading = React.forwardRef<
289
+ HTMLParagraphElement,
290
+ SubHeadingProps
291
+ >((props, ref) => {
292
+ const { className, size, color, children, lineClamp, ...passProps } = props;
293
+
294
+ return (
295
+ <p
296
+ ref={ref}
297
+ className={cn(subHeadingVariants({ size, color, lineClamp }), className)}
298
+ {...passProps}
299
+ >
300
+ {children}
301
+ </p>
302
+ );
303
+ });
304
+
305
+ export const SubTitle = SubHeading;
306
+
307
+ export const Text = React.forwardRef<
308
+ HTMLElement & HTMLParagraphElement,
309
+ TextProps & BlockProps
310
+ >((props, ref) => {
311
+ const {
312
+ className,
313
+ size,
314
+ weight,
315
+ color,
316
+ lineClamp,
317
+ underline,
318
+ strikethrough,
319
+ strong,
320
+ italic,
321
+ children,
322
+ dangerous,
323
+ ...passProps
324
+ } = props;
325
+ const Comp = renderBlock(
326
+ {
327
+ underline,
328
+ strikethrough,
329
+ strong,
330
+ italic,
331
+ },
332
+ 'span'
333
+ );
334
+ const text = dangerous && dangerouText(`${children}`);
335
+
336
+ return (
337
+ <Comp
338
+ ref={ref}
339
+ className={cn(
340
+ textVariants({ size, weight, color, lineClamp }),
341
+ className
342
+ )}
343
+ {...passProps}
344
+ {...(dangerous && { dangerouslySetInnerHTML: { __html: `${text}` } })}
345
+ >
346
+ {!dangerous ? children : null}
347
+ </Comp>
348
+ );
349
+ });
350
+
351
+ export const Paragraph = React.forwardRef<
352
+ HTMLElement & HTMLParagraphElement,
353
+ TextProps & BlockProps
354
+ >((props, ref) => {
355
+ const {
356
+ className,
357
+ size,
358
+ weight,
359
+ color,
360
+ lineClamp,
361
+ underline,
362
+ strikethrough,
363
+ strong,
364
+ italic,
365
+ children,
366
+ dangerous,
367
+ ...passProps
368
+ } = props;
369
+ const Comp = renderBlock(
370
+ {
371
+ underline,
372
+ strikethrough,
373
+ strong,
374
+ italic,
375
+ },
376
+ 'p'
377
+ );
378
+ const text = dangerous && dangerouText(`${children}`);
379
+
380
+ return (
381
+ <Comp
382
+ ref={ref}
383
+ className={cn(
384
+ textVariants({ size, weight, color, lineClamp }),
385
+ className
386
+ )}
387
+ {...passProps}
388
+ {...(dangerous && { dangerouslySetInnerHTML: { __html: `${text}` } })}
389
+ >
390
+ {!dangerous ? children : null}
391
+ </Comp>
392
+ );
393
+ });
394
+
395
+ export const Description = React.forwardRef<
396
+ HTMLParagraphElement,
397
+ DescriptionProps & BlockProps
398
+ >((props, ref) => {
399
+ const {
400
+ className,
401
+ size,
402
+ weight,
403
+ color,
404
+ lineClamp,
405
+ underline,
406
+ strikethrough,
407
+ strong,
408
+ italic,
409
+ children,
410
+ dangerous,
411
+ ...passProps
412
+ } = props;
413
+ const Comp = renderBlock(
414
+ {
415
+ underline,
416
+ strikethrough,
417
+ strong,
418
+ italic,
419
+ },
420
+ 'span'
421
+ );
422
+ const text = dangerous && dangerouText(`${children}`);
423
+
424
+ return (
425
+ <Comp
426
+ ref={ref}
427
+ className={cn(
428
+ descriptionVariants({ size, weight, color, lineClamp }),
429
+ className
430
+ )}
431
+ {...passProps}
432
+ {...(dangerous && { dangerouslySetInnerHTML: { __html: `${text}` } })}
433
+ >
434
+ {!dangerous ? children : null}
435
+ </Comp>
436
+ );
437
+ });
package/src/index.ts ADDED
@@ -0,0 +1,66 @@
1
+ // 导出组件
2
+ export * from './components/accordion';
3
+ export * from './components/alert';
4
+ export * from './components/alert-dialog';
5
+ export * from './components/aspect-ratio';
6
+ export * from './components/audio-player';
7
+ export * from './components/avatar';
8
+ export * from './components/badge';
9
+ export * from './components/button/button';
10
+ export * from './components/cascader';
11
+ export * from './components/checkbox';
12
+ export * from './components/command';
13
+ export * from './components/context-menu';
14
+ export * from './components/count-down';
15
+ export * from './components/dialog';
16
+ export * from './components/drawer';
17
+ export * from './components/dropdown-menu';
18
+ export * from './components/form';
19
+ export * from './components/group';
20
+ export * from './components/guide';
21
+ export * from './components/icon';
22
+ export * from './components/button/icon-button';
23
+ export * from './components/image';
24
+ export * from './components/input';
25
+ export * from './components/label';
26
+ export * from './components/link';
27
+ export * from './components/masonry';
28
+ export * from './components/menubar';
29
+ export * from './components/modal';
30
+ export * from './components/navigation-bar';
31
+ export * from './components/number-input';
32
+ export * from './components/page-content';
33
+ export * from './components/popover';
34
+ export * from './components/progress';
35
+ export * from './components/radio-group';
36
+ export * from './components/scroll-area';
37
+ export * from './components/search-bar';
38
+ export * from './components/secondary-navigation-bar';
39
+ export * from './components/select';
40
+ export * from './components/separator';
41
+ export * from './components/sheet';
42
+ export * from './components/skeleton';
43
+ export * from './components/slider';
44
+ export * from './components/spinner';
45
+ export * from './components/switch';
46
+ export * from './components/tabs';
47
+ export * from './components/textarea';
48
+ export * from './components/toggle';
49
+ export * from './components/toggle-group';
50
+ export * from './components/tooltip';
51
+ export * from './components/typography';
52
+
53
+ // 导出特殊组件
54
+ export * from './components/toast/toast';
55
+ export * from './components/toast/toaster';
56
+ export * from './components/toast/use-toast';
57
+
58
+ // 导出轮播组件
59
+ export * from './components/swiper';
60
+
61
+ // 导出hooks
62
+ export * from './common/hooks/useNotification';
63
+ export * from './common/hooks/useNativeBridge';
64
+ export * from './common/hooks/useDevice';
65
+ export * from './common/hooks/useWindowWidth';
66
+ export * from './common/hooks/useAudioPlayer';
@@ -0,0 +1,62 @@
1
+ import { type ClassValue, clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ // import { locales } from '@/lib/config';
5
+
6
+ export function cn(...inputs: ClassValue[]) {
7
+ return twMerge(clsx(inputs));
8
+ }
9
+
10
+ export function getAlternatesMap(pathname: string, isMobile?: boolean) {
11
+ // const langMap = {} as Record<string, string>;
12
+ // locales.forEach(locale => {
13
+ // langMap[locale] = `https://app.myshell.ai/${locale}/${pathname}`;
14
+ // });
15
+ const defaultUrl = `https://app.myshell.ai/${pathname}`;
16
+
17
+ return {
18
+ canonical: defaultUrl,
19
+ media: {
20
+ 'only screen and (max-width: 768px)': `https://app.myshell.ai/m/${pathname}`,
21
+ },
22
+
23
+ // languages: {
24
+ // 'x-default': defaultUrl,
25
+ // ...langMap
26
+ // }
27
+ };
28
+ }
29
+
30
+ export function limitStringLength(str: string, limit: number) {
31
+ if (str.length > limit) {
32
+ return `${str.substring(0, limit)}...`;
33
+ }
34
+
35
+ return str;
36
+ }
37
+
38
+ export function loadImage(src: string): Promise<HTMLImageElement> {
39
+ return new Promise((resolve, reject) => {
40
+ const img = new Image();
41
+ img.onload = () => resolve(img);
42
+ img.onerror = reject;
43
+ img.src = src;
44
+ });
45
+ }
46
+
47
+ export function loadImageDimensions(
48
+ url: string
49
+ ): Promise<{ width: number; height: number }> {
50
+ return new Promise<{ width: number; height: number }>((resolve, reject) => {
51
+ const image = new Image();
52
+ image.onload = () => {
53
+ resolve({ width: image.width, height: image.height });
54
+ URL.revokeObjectURL(url);
55
+ };
56
+ image.onerror = () => {
57
+ reject(new Error('Failed to load image.'));
58
+ URL.revokeObjectURL(url);
59
+ };
60
+ image.src = url;
61
+ });
62
+ }
@@ -0,0 +1,64 @@
1
+ /* eslint-disable import/no-unused-modules */
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import { fn } from '@storybook/test';
4
+ import React from 'react';
5
+
6
+ import ItemDemo from '../components/ItemDemo';
7
+ import { Accordion, AccordionItem } from '../components/accordion';
8
+
9
+ import { AccordionItemDemo } from './AccordionItem.stories';
10
+
11
+ type AccordionItemType = typeof AccordionItem & any;
12
+
13
+ const meta = {
14
+ title: 'Components/数据展示/Accordion-折叠面板',
15
+ component: Accordion,
16
+ subcomponents: { AccordionItem: AccordionItem as AccordionItemType },
17
+ parameters: {
18
+ // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
19
+ layout: 'centered',
20
+ },
21
+ // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
22
+ tags: ['autodocs'],
23
+ args: {
24
+ type: 'single',
25
+ collapsible: true,
26
+ },
27
+ } satisfies Meta<typeof Accordion>;
28
+ export default meta;
29
+
30
+ type Story = StoryObj<typeof meta>;
31
+
32
+ // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
33
+ export const Demo: Story = {
34
+ args: {
35
+ ...meta.args, // 继承默认参数
36
+ },
37
+ render: (args) => {
38
+ return (
39
+ <div className="w-[40vw] px-3 rounded-md">
40
+ <Accordion {...args}>
41
+ <AccordionItem {...AccordionItemDemo.args} value="accordion-item1">
42
+ <ItemDemo />
43
+ </AccordionItem>
44
+ <AccordionItem
45
+ {...AccordionItemDemo.args}
46
+ value="accordion-item2"
47
+ label="accordion item 2"
48
+ count={0}
49
+ >
50
+ <ItemDemo />
51
+ </AccordionItem>
52
+ <AccordionItem
53
+ {...AccordionItemDemo.args}
54
+ value="accordion-item3"
55
+ label="accordion item 3"
56
+ count={3}
57
+ >
58
+ <ItemDemo />
59
+ </AccordionItem>
60
+ </Accordion>
61
+ </div>
62
+ );
63
+ },
64
+ };
@@ -0,0 +1,48 @@
1
+ /* eslint-disable import/no-unused-modules */
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import { fn } from '@storybook/test';
4
+ import React from 'react';
5
+
6
+ import ItemDemo from '../components/ItemDemo';
7
+ import { Accordion, AccordionItem } from '../components/accordion';
8
+
9
+ const meta = {
10
+ title: 'Components/数据展示/Accordion-折叠面板',
11
+ component: AccordionItem,
12
+ parameters: {
13
+ // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
14
+ layout: 'centered',
15
+ },
16
+ // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
17
+ tags: ['autodocs'],
18
+
19
+ // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
20
+ args: {
21
+ label: 'accordion item 1',
22
+ value: 'item1',
23
+ count: 6,
24
+ triggerClassName: '',
25
+ },
26
+ argTypes: {},
27
+ } satisfies Meta<typeof AccordionItem>;
28
+
29
+ export default meta;
30
+
31
+ type Story = StoryObj<typeof AccordionItem>;
32
+
33
+ export const AccordionItemDemo: Story = {
34
+ args: {
35
+ ...meta.args, // 继承默认参数
36
+ },
37
+ render: (args) => {
38
+ return (
39
+ <div className="w-[40vw] px-3 rounded-md">
40
+ <Accordion type="single" collapsible>
41
+ <AccordionItem {...args}>
42
+ <ItemDemo />
43
+ </AccordionItem>
44
+ </Accordion>
45
+ </div>
46
+ );
47
+ },
48
+ };