myshell-react-lib 0.1.5 → 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.
Files changed (145) hide show
  1. package/dist/index.cjs +50 -2
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +6 -1
  4. package/dist/index.js.map +1 -1
  5. package/package.json +1 -2
  6. package/src/common/assets/audio-playing.json +0 -3657
  7. package/src/common/constants/constants.ts +0 -24
  8. package/src/common/constants/types/common.ts +0 -10
  9. package/src/common/hooks/useAudioPlayer.tsx +0 -198
  10. package/src/common/hooks/useDevice.ts +0 -26
  11. package/src/common/hooks/useNativeBridge.ts +0 -42
  12. package/src/common/hooks/useNotification.tsx +0 -179
  13. package/src/common/hooks/useWindowWidth.ts +0 -19
  14. package/src/common/utils/common-helper.ts +0 -81
  15. package/src/components/ItemDemo.tsx +0 -15
  16. package/src/components/accordion.tsx +0 -126
  17. package/src/components/alert-dialog.tsx +0 -148
  18. package/src/components/alert.tsx +0 -65
  19. package/src/components/aspect-ratio.tsx +0 -7
  20. package/src/components/audio-player.tsx +0 -60
  21. package/src/components/audio-playing.tsx +0 -33
  22. package/src/components/avatar.tsx +0 -133
  23. package/src/components/badge.tsx +0 -67
  24. package/src/components/button/button.styles.ts +0 -258
  25. package/src/components/button/button.tsx +0 -215
  26. package/src/components/button/icon-button.styles.ts +0 -103
  27. package/src/components/button/icon-button.tsx +0 -100
  28. package/src/components/button/index.tsx +0 -3
  29. package/src/components/button/link-button.tsx +0 -184
  30. package/src/components/cascader.tsx +0 -175
  31. package/src/components/checkbox.tsx +0 -135
  32. package/src/components/command.tsx +0 -155
  33. package/src/components/context-menu.tsx +0 -198
  34. package/src/components/count-down.tsx +0 -83
  35. package/src/components/custom-notification.tsx +0 -95
  36. package/src/components/dialog.tsx +0 -158
  37. package/src/components/drawer.tsx +0 -116
  38. package/src/components/dropdown-menu.tsx +0 -196
  39. package/src/components/energy-progress.tsx +0 -55
  40. package/src/components/form.tsx +0 -201
  41. package/src/components/group.tsx +0 -9
  42. package/src/components/guide.tsx +0 -243
  43. package/src/components/icon.tsx +0 -96
  44. package/src/components/icons/index.tsx +0 -13
  45. package/src/components/icons/outline/ArrowLeftIcon.tsx +0 -28
  46. package/src/components/icons/outline/ArrowUpTrayIcon.tsx +0 -28
  47. package/src/components/icons/outline/CheckCircleIcon.tsx +0 -27
  48. package/src/components/icons/outline/ConfigIcon.tsx +0 -42
  49. package/src/components/icons/outline/DownIcon.tsx +0 -18
  50. package/src/components/icons/outline/FilterIcon.tsx +0 -20
  51. package/src/components/icons/outline/PencilSquareIcon.tsx +0 -28
  52. package/src/components/icons/outline/WindowIcon.tsx +0 -26
  53. package/src/components/icons/solid/CaretDownIcon.tsx +0 -22
  54. package/src/components/icons/solid/CodeIcon.tsx +0 -25
  55. package/src/components/icons/solid/DragIcon.tsx +0 -24
  56. package/src/components/icons/solid/PhoneIcon.tsx +0 -29
  57. package/src/components/icons/solid/RectangleGroupIcon.tsx +0 -26
  58. package/src/components/image.tsx +0 -152
  59. package/src/components/input.tsx +0 -118
  60. package/src/components/label.tsx +0 -26
  61. package/src/components/link.tsx +0 -123
  62. package/src/components/marquee/index.css +0 -15
  63. package/src/components/marquee/marquee.tsx +0 -220
  64. package/src/components/masonry.tsx +0 -138
  65. package/src/components/menubar.tsx +0 -234
  66. package/src/components/mobile/m-tooltip.tsx +0 -34
  67. package/src/components/modal.tsx +0 -561
  68. package/src/components/navigation-bar.tsx +0 -100
  69. package/src/components/number-input.tsx +0 -143
  70. package/src/components/page-content.tsx +0 -16
  71. package/src/components/popover.tsx +0 -191
  72. package/src/components/progress.tsx +0 -80
  73. package/src/components/radio-group.tsx +0 -44
  74. package/src/components/scroll-area.tsx +0 -49
  75. package/src/components/search-bar.tsx +0 -140
  76. package/src/components/secondary-navigation-bar.tsx +0 -328
  77. package/src/components/select.tsx +0 -273
  78. package/src/components/separator.tsx +0 -31
  79. package/src/components/sheet.tsx +0 -143
  80. package/src/components/skeleton.tsx +0 -20
  81. package/src/components/slider.tsx +0 -160
  82. package/src/components/spinner.tsx +0 -50
  83. package/src/components/swiper/index.module.scss +0 -88
  84. package/src/components/swiper/index.tsx +0 -319
  85. package/src/components/switch.tsx +0 -67
  86. package/src/components/tabs.tsx +0 -325
  87. package/src/components/textarea.tsx +0 -71
  88. package/src/components/toast/toast.tsx +0 -182
  89. package/src/components/toast/toaster.tsx +0 -160
  90. package/src/components/toast/use-toast.tsx +0 -248
  91. package/src/components/toggle-group.tsx +0 -64
  92. package/src/components/toggle.tsx +0 -46
  93. package/src/components/tooltip.tsx +0 -283
  94. package/src/components/typography.tsx +0 -437
  95. package/src/index.ts +0 -70
  96. package/src/lib/utils.ts +0 -62
  97. package/src/stories/Accordion.stories.tsx +0 -64
  98. package/src/stories/AccordionItem.stories.tsx +0 -48
  99. package/src/stories/Avatar.stories.ts +0 -58
  100. package/src/stories/Badge.stories.tsx +0 -40
  101. package/src/stories/BannerSwiper.stories.tsx +0 -102
  102. package/src/stories/Button.stories.tsx +0 -543
  103. package/src/stories/Checkbox.stories.tsx +0 -161
  104. package/src/stories/Configure.mdx +0 -341
  105. package/src/stories/CssProperties.mdx +0 -30
  106. package/src/stories/Description.stories.ts +0 -70
  107. package/src/stories/Display.stories.ts +0 -64
  108. package/src/stories/FeaturedSwiper.stories.tsx +0 -6978
  109. package/src/stories/GridSwiper.stories.tsx +0 -1407
  110. package/src/stories/Guide.stories.tsx +0 -247
  111. package/src/stories/Heading.stories.ts +0 -89
  112. package/src/stories/Icon.stories.ts +0 -77
  113. package/src/stories/IconButton.stories.tsx +0 -301
  114. package/src/stories/IconTextButton.stories.ts +0 -59
  115. package/src/stories/Image.stories.ts +0 -55
  116. package/src/stories/Input.stories.tsx +0 -203
  117. package/src/stories/Modal.stories.tsx +0 -144
  118. package/src/stories/NavigationBar.stories.tsx +0 -81
  119. package/src/stories/Notification.stories.tsx +0 -276
  120. package/src/stories/Popover.stories.tsx +0 -100
  121. package/src/stories/SearchBar.stories.ts +0 -43
  122. package/src/stories/SecondaryNavigationBar.stories.tsx +0 -199
  123. package/src/stories/Select.stories.tsx +0 -107
  124. package/src/stories/Separator.stories.tsx +0 -49
  125. package/src/stories/Spinner.stories.tsx +0 -48
  126. package/src/stories/SubHeading.stories.ts +0 -64
  127. package/src/stories/Swich.stories.tsx +0 -69
  128. package/src/stories/Tabs.stories.tsx +0 -90
  129. package/src/stories/Text.stories.ts +0 -78
  130. package/src/stories/Textarea.stories.tsx +0 -155
  131. package/src/stories/Toast.stories.tsx +0 -424
  132. package/src/stories/Tooltip.stories.tsx +0 -244
  133. package/src/stories/ViewAutoSwiper.stories.tsx +0 -1408
  134. package/src/styles/components-dark.scss +0 -212
  135. package/src/styles/components-light.scss +0 -210
  136. package/src/styles/design-dark.scss +0 -330
  137. package/src/styles/design-light.scss +0 -345
  138. package/src/styles/design2-dark.scss +0 -319
  139. package/src/styles/design2-light.scss +0 -364
  140. package/src/styles/font.css +0 -19
  141. package/src/styles/global.scss +0 -251
  142. package/src/styles/md-viewer.scss +0 -155
  143. package/src/styles/new-tokens.scss +0 -255
  144. package/src/styles/tokens.scss +0 -401
  145. package/src/types/scss.d.ts +0 -24
@@ -1,319 +0,0 @@
1
- /* eslint-disable import/order */
2
-
3
- 'use client';
4
-
5
- import { cva } from 'class-variance-authority';
6
- import { useEffect, useMemo, useRef, useState } from 'react';
7
- import type { Swiper as SwiperType } from 'swiper';
8
- import { useRouter } from 'next/navigation';
9
- import {
10
- Autoplay,
11
- Navigation,
12
- FreeMode,
13
- Scrollbar,
14
- Mousewheel,
15
- Grid,
16
- } from 'swiper/modules';
17
- import { Swiper as SwiperComponent, SwiperSlide } from 'swiper/react';
18
- import type { AutoplayOptions } from 'swiper/types';
19
-
20
- /* eslint-disable import/no-unassigned-import */
21
- import 'swiper/css';
22
- // import 'swiper/swiper-bundle.css';
23
- import 'swiper/css/navigation';
24
- import 'swiper/css/free-mode';
25
- import 'swiper/css/grid';
26
- import 'swiper/css/pagination';
27
- // import 'swiper/css/scrollbar';
28
-
29
- import { cn } from '@/lib/utils';
30
- import styles from './index.module.scss';
31
-
32
- const swiperVariants = cva('', {
33
- variants: {
34
- rounded: {
35
- none: 'rounded-none',
36
- sm: 'rounded-sm',
37
- default: 'rounded',
38
- md: 'rounded-md',
39
- lg: 'rounded-lg',
40
- xl: 'rounded-xl',
41
- '2xl': 'rounded-2xl',
42
- '3xl': 'rounded-3xl',
43
- full: 'rounded-full',
44
- },
45
- },
46
- defaultVariants: {
47
- rounded: 'none',
48
- },
49
- });
50
-
51
- export interface SwiperProps {
52
- /**
53
- * 轮播间隔延迟毫秒
54
- */
55
- delay?: number;
56
- /**
57
- * 是否自动播放
58
- */
59
- autoplay?: boolean;
60
- /**
61
- * 是否循环
62
- */
63
- loop?: boolean;
64
- /**
65
- * 一屏显示slider数量,number|'auto'
66
- */
67
- slidesPerView?: number | 'auto';
68
- /**
69
- * 轮播数据
70
- */
71
- dataList: any;
72
- /**
73
- * 轮播类型 ,目前是特殊的'banner' | 'featured',其他自由配置
74
- */
75
- swiperType: 'default' | 'banner' | 'featured' | 'grid';
76
- /**
77
- * 行数,仅在swiperType为'grid'时生效
78
- */
79
- gridRows?: number;
80
- /**
81
- * 轮播子组件
82
- */
83
- component?: React.ElementType;
84
- /**
85
- * Swiperbox样式覆盖
86
- */
87
- className?: string;
88
- /**
89
- * Swiper item样式覆盖
90
- */
91
- componentClassName?: string;
92
- /**
93
- * Swiper Slide item样式覆盖
94
- */
95
- slideClassName?: string;
96
- // todo del
97
- rounded?:
98
- | 'none'
99
- | 'sm'
100
- | 'default'
101
- | 'md'
102
- | 'lg'
103
- | 'xl'
104
- | '2xl'
105
- | '3xl'
106
- | 'full';
107
- /**
108
- * 从哪里来,点击跳转时带在url上
109
- */
110
- from?: string;
111
-
112
- /**
113
- * 是否居中显示
114
- */
115
- centeredSlides?: boolean;
116
-
117
- // 间距
118
- spaceBetween?: number;
119
- /**
120
- * 是否是移动端
121
- */
122
- isMobile?: boolean;
123
- }
124
-
125
- export function Swiper(props: SwiperProps) {
126
- const {
127
- className,
128
- componentClassName,
129
- slideClassName,
130
- rounded = 'none',
131
- delay = 4000,
132
- loop = true,
133
- slidesPerView = 1,
134
- dataList = [],
135
- swiperType = 'default',
136
- from = '',
137
- component,
138
- autoplay,
139
- spaceBetween = 12,
140
- centeredSlides = true,
141
- gridRows = 3,
142
- isMobile = false,
143
- } = props;
144
- const isBanner = swiperType === 'banner';
145
- const isFeatured = swiperType === 'featured';
146
- const isGrid = swiperType === 'grid';
147
- const router = useRouter();
148
- const Com = component || 'div';
149
- const swiperList = useMemo(() => {
150
- const { length } = dataList;
151
- if (length < 2 || isGrid || isFeatured) {
152
- return dataList;
153
- }
154
-
155
- // 抽出最后一个元素放在开头,确保UI逻辑正确
156
- const newList = dataList.slice(0);
157
- const last = newList.pop()!;
158
- newList.unshift(last);
159
-
160
- return newList;
161
- }, [dataList]);
162
-
163
- const autoPlayOptions: AutoplayOptions = {
164
- delay,
165
- };
166
-
167
- const swiperRef = useRef<SwiperType>();
168
- const fgconfigs = {
169
- 0: {
170
- slidesPerView: 1.014,
171
- spaceBetween: 12,
172
- },
173
- 590: {
174
- slidesPerView: 2.1,
175
- slidesPerGroup: 2,
176
- },
177
- 768: {
178
- slidesPerView: 1,
179
- },
180
- 1024: {
181
- slidesPerView: 2,
182
- slidesPerGroup: 2,
183
- },
184
- 1280: {
185
- slidesPerView: 3,
186
- slidesPerGroup: 3,
187
- },
188
- 1536: {
189
- slidesPerView: 4,
190
- slidesPerGroup: 4,
191
- },
192
- };
193
- const breakpoints = {
194
- default: {},
195
- banner: {
196
- 769: {
197
- spaceBetween: 20,
198
- },
199
- },
200
- featured: fgconfigs,
201
- grid: fgconfigs,
202
- };
203
- const swiperConfigs = {
204
- spaceBetween: isFeatured ? 20 : isGrid ? 0 : spaceBetween,
205
- autoplay:
206
- swiperList?.length > 1 && (autoplay || isBanner)
207
- ? autoPlayOptions
208
- : false,
209
- loop: !isFeatured && !isGrid && swiperList?.length > 1 ? loop : false,
210
- slidesPerView: isBanner ? 'auto' : slidesPerView,
211
- centeredSlides: isGrid || isFeatured ? false : centeredSlides,
212
- initialSlide: isBanner ? 1 : 0,
213
- navigation: !isGrid,
214
- freeMode: (isFeatured || isGrid) && !isMobile,
215
- scrollbar: (isFeatured || isGrid) && !isMobile,
216
-
217
- ...((isFeatured || isGrid) && !isMobile
218
- ? {
219
- mousewheel: {
220
- forceToAxis: true, // 仅水平滚动
221
- },
222
- }
223
- : {}),
224
- ...(isGrid ? { grid: { rows: gridRows } } : {}),
225
- modules: [Autoplay, Navigation, FreeMode, Scrollbar, Mousewheel, Grid],
226
- };
227
-
228
- const [animate, setAnimate] = useState(false);
229
- useEffect(() => {
230
- // delay transition animation.
231
- // because swiper.js add `.swiper-slide-prev`/`.swiper-slide-next` in a delay,
232
- // which will introduced an unexpected animated when first load.
233
- setTimeout(() => {
234
- setAnimate(true);
235
- }, 200);
236
- }, []);
237
-
238
- const handleSlideItemClick = (
239
- e: React.MouseEvent<HTMLDivElement>,
240
- gotoUrl: string,
241
- index: number
242
- ) => {
243
- const swiper = swiperRef.current;
244
- if (!swiper) {
245
- return;
246
- }
247
- if (swiper.realIndex === index) {
248
- const hasParam = gotoUrl.includes('?') ? '&' : '?';
249
- // goToHandle?.(`${gotoUrl}${hasParam}from=Explore_Banner`);
250
- const fromParam = from ? `from=${from}` : '';
251
- const url = `${gotoUrl}${hasParam}${fromParam}`;
252
- if (!(url.startsWith('https') || url.startsWith('http'))) {
253
- router.push(url);
254
- } else {
255
- window.open(url);
256
- }
257
- } else if (e.target) {
258
- const rect = (e.target as HTMLElement)?.getBoundingClientRect();
259
- const screenWidth = window.innerWidth;
260
- if (rect.left < screenWidth / 2 && rect.right < screenWidth / 2) {
261
- // 元素离左边屏幕更近
262
- swiper.slidePrev();
263
- } else if (rect.left > screenWidth / 2 && rect.right > screenWidth / 2) {
264
- // 元素离右边屏幕更近
265
- swiper.slideNext();
266
- }
267
- }
268
- };
269
-
270
- return (
271
- <div className={styles.swiperBox}>
272
- <SwiperComponent
273
- observer
274
- observeParents
275
- {...swiperConfigs}
276
- breakpoints={breakpoints[swiperType]}
277
- className={cn(
278
- 'w-[100vw] md:w-full h-auto flex-shrink-0',
279
- isBanner && 'banner-swiper h-[220px] md:h-auto',
280
- isFeatured && 'feature-swiper !pl-4 !pr-3 md:!px-4',
281
- isGrid && 'grid-swiper h-full !ml-auto !mr-auto !pl-4 !pr-3 md:!px-0',
282
- animate && styles.animate,
283
- className
284
- )}
285
- onInit={(swiper) => {
286
- swiperRef.current = swiper;
287
- }}
288
- >
289
- {swiperList.map((item: any, index: number) => (
290
- <SwiperSlide
291
- /* eslint-disable-next-line react/no-array-index-key */
292
- key={index}
293
- className={cn(
294
- isBanner &&
295
- 'banner-swiper-slide !w-[90%] md:!w-[98%] h-[220px] md:h-auto max-w-[1200px] aspect-[4/1] rounded-2xl opacity-30',
296
- isFeatured && 'rounded-2xl !w-[100%-32px] md:!w-[100%-72px]',
297
- isGrid &&
298
- 'grid-swiper-slide !w-[100%-32px] md:!w-[100%-72px] !h-[100%/3] flex justify-center items-center rounded-2xl',
299
- 'text-clip',
300
- slideClassName
301
- )}
302
- >
303
- <Com
304
- item={item}
305
- index={index}
306
- onClick={handleSlideItemClick}
307
- className={cn(
308
- swiperVariants({ rounded }),
309
- (isBanner || isFeatured) && 'rounded-2xl',
310
- componentClassName
311
- )}
312
- isLine={gridRows && (index + 1) % gridRows !== 0}
313
- />
314
- </SwiperSlide>
315
- ))}
316
- </SwiperComponent>
317
- </div>
318
- );
319
- }
@@ -1,67 +0,0 @@
1
- 'use client';
2
-
3
- import * as SwitchPrimitives from '@radix-ui/react-switch';
4
- import { cva, type VariantProps } from 'class-variance-authority';
5
- import * as React from 'react';
6
-
7
- import { cn } from '@/lib/utils';
8
-
9
- const switchSize = {
10
- sm: 'w-7 h-4',
11
- md: 'w-[34px] h-5',
12
- lg: 'w-10 h-6',
13
- } as const;
14
-
15
- const switchRootVariants = cva(
16
- 'peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cc-Focus-Rings-Brand-default focus-visible:ring-offset-2 data-[state=unchecked]:focus-visible:bg-cc-Switch-bg-default disabled:cursor-not-allowed disabled:opacity-30 data-[state="checked"]:bg-cc-Switch-bg-on data-[state="unchecked"]:bg-cc-Switch-bg-default',
17
- {
18
- variants: {
19
- size: switchSize,
20
- },
21
- defaultVariants: {
22
- size: 'lg',
23
- },
24
- }
25
- );
26
-
27
- const switchThumbVariants = cva(
28
- 'pointer-events-none block rounded-full bg-cc-Switch-fg-on ring-0 transition-transform data-[state=unchecked]:translate-x-0',
29
- {
30
- variants: {
31
- size: {
32
- sm: 'w-3 h-3 data-[state=checked]:translate-x-3',
33
- md: 'w-4 h-4 data-[state=checked]:translate-x-[14px]',
34
- lg: 'w-5 h-5 data-[state=checked]:translate-x-4',
35
- },
36
- },
37
- defaultVariants: {
38
- size: 'lg',
39
- },
40
- }
41
- );
42
-
43
- const Switch = React.forwardRef<
44
- React.ElementRef<typeof SwitchPrimitives.Root>,
45
- React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> &
46
- VariantProps<typeof switchRootVariants> & {
47
- label?: string;
48
- labelClassName?: string;
49
- }
50
- >(({ className, size, label, labelClassName, ...props }, ref) => {
51
- const Component = label ? 'div' : React.Fragment;
52
- return (
53
- <Component className="flex items-center justify-center space-x-1.5 text-Colors-Text-Default">
54
- <SwitchPrimitives.Root
55
- className={cn(switchRootVariants({ size }), className, '')}
56
- {...props}
57
- ref={ref}
58
- >
59
- <SwitchPrimitives.Thumb className={cn(switchThumbVariants({ size }))} />
60
- </SwitchPrimitives.Root>
61
- {label && <span className={cn('text-sm', labelClassName)}>{label}</span>}
62
- </Component>
63
- );
64
- });
65
- Switch.displayName = SwitchPrimitives.Root.displayName;
66
-
67
- export { Switch };
@@ -1,325 +0,0 @@
1
- 'use client';
2
-
3
- import * as TabsPrimitive from '@radix-ui/react-tabs';
4
- import { cva } from 'class-variance-authority';
5
- import * as React from 'react';
6
-
7
- import { cn } from '@/lib/utils';
8
-
9
- import { Badge } from './badge';
10
- import { Icon } from './icon';
11
- import Link from './link';
12
- import { Tooltip } from './tooltip';
13
- import { Text } from './typography';
14
-
15
- type TItems = {
16
- label?: string;
17
- value: string;
18
- count?: number | string;
19
- tooltip?: {
20
- description?: string;
21
- open?: boolean;
22
- variant?: 'default' | 'info' | 'message';
23
- };
24
- icon?: React.ElementType;
25
- disabled?: boolean;
26
- link?: string;
27
- hasUnRead?: boolean;
28
- children?: string | React.ReactNode;
29
- className?: string;
30
- onClickCallback?: (value: string) => void;
31
- };
32
-
33
- const tabListVariants = cva(
34
- 'relative inline-flex items-center justify-center overflow-hidden',
35
- {
36
- variants: {
37
- size: {
38
- sm: 'h-6',
39
- md: 'h-9',
40
- lg: 'h-12',
41
- },
42
- variant: {
43
- button:
44
- 'w-full border border-Colors-Border-Default bg-Colors-Background-Neutral-Primary-Default p-0.5',
45
- underline: 'border-b border-Colors-Border-Default space-x-6',
46
- icon: 'border border-Colors-Border-Default bg-Colors-Background-Neutral-Primary-Default p-0.5',
47
- },
48
- rounded: {
49
- default: '',
50
- full: 'rounded-full',
51
- },
52
- },
53
- compoundVariants: [
54
- {
55
- variant: 'button',
56
- size: 'lg',
57
- className: 'min-w-[320px]',
58
- },
59
- {
60
- variant: 'button',
61
- size: 'md',
62
- className: 'min-w-[218px]',
63
- },
64
- {
65
- variant: 'button',
66
- size: 'sm',
67
- className: 'min-w-[180px]',
68
- },
69
- {
70
- variant: 'underline',
71
- size: 'lg',
72
- className: 'h-8',
73
- },
74
- {
75
- variant: 'underline',
76
- size: 'md',
77
- className: 'h-7',
78
- },
79
- {
80
- variant: 'underline',
81
- size: 'sm',
82
- className: 'h-6',
83
- },
84
- {
85
- rounded: 'default',
86
- size: 'lg',
87
- className: 'rounded-xl',
88
- },
89
- {
90
- rounded: 'default',
91
- size: 'md',
92
- className: 'rounded-lg',
93
- },
94
- {
95
- rounded: 'default',
96
- size: 'sm',
97
- className: 'rounded-md',
98
- },
99
- ],
100
- defaultVariants: {
101
- size: 'lg',
102
- variant: 'button',
103
- rounded: 'default',
104
- },
105
- }
106
- );
107
-
108
- const tabVariants = cva(
109
- 'relative inline-flex w-full h-full items-center justify-center overflow-hidden whitespace-nowrap font-medium text-Colors-Text-Subtler aria-[selected=true]:text-Colors-Text-Brand-Default aria-[selected=true]:bg-Colors-Background-Normal-Primary-Active aria-[selected=true]:shadow-background-default [&>div>span]:hover:text-Colors-Text-Brand-Default disabled:pointer-events-none disabled:text-Colors-Text-Disabled [&>div>span]:disabled:text-Colors-Text-Disabled data-[state=active]:text-Colors-Text-Brand-Default',
110
- {
111
- variants: {
112
- size: {
113
- sm: 'text-xs',
114
- md: 'text-sm',
115
- lg: 'text-base',
116
- },
117
- variant: {
118
- button:
119
- 'px-3 py-2.5 flex-1 rounded-full transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-Colors-Background-Normal-Primary-Active data-[state=active]:shadow-background-default ',
120
- underline:
121
- 'flex items-baseline pb-2 rounded-none data-[state=active]:border-b-2 data-[state=active]:border-b-brand',
122
- icon: 'px-4',
123
- },
124
- rounded: {
125
- default: '',
126
- full: 'rounded-full',
127
- },
128
- },
129
- compoundVariants: [
130
- {
131
- rounded: 'default',
132
- size: 'lg',
133
- className: 'rounded-xl',
134
- },
135
- {
136
- rounded: 'default',
137
- size: 'md',
138
- className: 'rounded-lg',
139
- },
140
- {
141
- rounded: 'default',
142
- size: 'sm',
143
- className: 'rounded-md',
144
- },
145
- ],
146
- defaultVariants: {
147
- size: 'lg',
148
- variant: 'button',
149
- rounded: 'default',
150
- },
151
- }
152
- );
153
-
154
- const Tabs = React.forwardRef<
155
- React.ElementRef<typeof TabsPrimitive.Root>,
156
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root> & {
157
- variant?: 'button' | 'underline' | 'icon';
158
- size?: 'sm' | 'md' | 'lg';
159
- rounded?: 'default' | 'full';
160
- /**
161
- * 是否为链接
162
- */
163
- isLink?: boolean;
164
- listClassName?: string;
165
- items?: TItems[];
166
- }
167
- >(
168
- (
169
- {
170
- className,
171
- listClassName,
172
- variant = 'button',
173
- size,
174
- isLink = false,
175
- rounded = 'default',
176
- items,
177
- ...props
178
- },
179
- ref
180
- ) => (
181
- <TabsPrimitive.Root ref={ref} className={cn(className)} {...props}>
182
- <div className="w-full flex justify-center items-center">
183
- <TabsPrimitive.List
184
- ref={ref}
185
- className={cn(
186
- '',
187
- tabListVariants({ variant, size, rounded }),
188
- listClassName
189
- )}
190
- {...props}
191
- >
192
- {items?.map((item) => {
193
- return (
194
- <Tab
195
- key={item.value}
196
- isLink={isLink}
197
- variant={variant}
198
- size={size}
199
- rounded={rounded}
200
- {...item}
201
- />
202
- );
203
- })}
204
- </TabsPrimitive.List>
205
- </div>
206
- {!isLink && (
207
- <div className="w-full">
208
- {items?.map((item) => {
209
- return (
210
- <TabsContent value={item.value}>{item.children}</TabsContent>
211
- );
212
- })}
213
- </div>
214
- )}
215
- </TabsPrimitive.Root>
216
- )
217
- );
218
- Tabs.displayName = TabsPrimitive.Root.displayName;
219
-
220
- const Tab = React.forwardRef<
221
- React.ElementRef<typeof TabsPrimitive.Trigger>,
222
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> & {
223
- variant?: 'button' | 'underline' | 'icon';
224
- size?: 'sm' | 'md' | 'lg';
225
- rounded?: 'default' | 'full';
226
- isLink?: boolean;
227
- link?: string;
228
- count?: number | string;
229
- label?: string;
230
- icon?: React.ElementType;
231
- tooltip?: {
232
- description?: string;
233
- open?: boolean;
234
- variant?: 'default' | 'info' | 'message';
235
- };
236
- hasUnRead?: boolean;
237
- onClickCallback?: (value: string) => void;
238
- }
239
- >(
240
- (
241
- {
242
- className,
243
- variant,
244
- size,
245
- isLink,
246
- link,
247
- count,
248
- label,
249
- icon,
250
- tooltip,
251
- hasUnRead,
252
- rounded = 'default',
253
- onClickCallback,
254
- ...props
255
- },
256
- ref
257
- ) => {
258
- return (
259
- <Tooltip triggerClassName="w-full h-full flex-1" {...tooltip}>
260
- <TabsPrimitive.Trigger
261
- ref={ref}
262
- className={cn(
263
- 'tabtrigger min-w-fit',
264
- tabVariants({ variant, size, rounded }),
265
- className
266
- )}
267
- {...props}
268
- onClick={(e) => {
269
- e.stopPropagation();
270
- onClickCallback?.(props.value);
271
- }}
272
- >
273
- {isLink && link ? (
274
- <Link
275
- prefetch
276
- href={link}
277
- className={cn(
278
- 'relative h-full w-full flex justify-center items-center'
279
- )}
280
- onClick={(e) => () => {
281
- e.preventDefault();
282
- }}
283
- >
284
- {label}
285
- {hasUnRead && <Badge className="-mt-2.5" />}
286
- </Link>
287
- ) : (
288
- <div className="relative flex justify-center items-center">
289
- {label && <Text className="text-inherit">{label}</Text>}
290
- {icon && (
291
- <Icon component={icon} size="md" className="text-inherit" />
292
- )}
293
- {count ? (
294
- <Text size="sm" className="ml-1 text-Colors-Text-Subtlest">
295
- {count}
296
- </Text>
297
- ) : null}
298
- {hasUnRead && <Badge className="-mt-2.5" />}
299
- </div>
300
- )}
301
- </TabsPrimitive.Trigger>
302
- </Tooltip>
303
- );
304
- }
305
- );
306
- Tab.displayName = TabsPrimitive.Trigger.displayName;
307
-
308
- const TabsContent = React.forwardRef<
309
- React.ElementRef<typeof TabsPrimitive.Content>,
310
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
311
- >(({ className, ...props }, ref) => {
312
- return (
313
- <TabsPrimitive.Content
314
- ref={ref}
315
- className={cn(
316
- 'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0',
317
- className
318
- )}
319
- {...props}
320
- />
321
- );
322
- });
323
- TabsContent.displayName = TabsPrimitive.Content.displayName;
324
-
325
- export { Tabs, Tab, TabsContent };