@anker-in/headless-ui 0.0.10 → 0.0.12

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 (140) hide show
  1. package/CONTRIBUTING.md +6 -1
  2. package/dist/cjs/components/badge.js +1 -1
  3. package/dist/cjs/components/badge.js.map +2 -2
  4. package/dist/cjs/components/button.js +1 -1
  5. package/dist/cjs/components/button.js.map +2 -2
  6. package/dist/cjs/components/checkbox.d.ts +8 -1
  7. package/dist/cjs/components/checkbox.js +1 -1
  8. package/dist/cjs/components/checkbox.js.map +3 -3
  9. package/dist/cjs/components/dialog.js +1 -1
  10. package/dist/cjs/components/dialog.js.map +2 -2
  11. package/dist/cjs/components/heading.d.ts +9 -1
  12. package/dist/cjs/components/heading.js +1 -1
  13. package/dist/cjs/components/heading.js.map +3 -3
  14. package/dist/cjs/components/index.d.ts +1 -0
  15. package/dist/cjs/components/index.js +1 -1
  16. package/dist/cjs/components/index.js.map +2 -2
  17. package/dist/cjs/components/input.d.ts +1 -1
  18. package/dist/cjs/components/input.js +1 -1
  19. package/dist/cjs/components/input.js.map +2 -2
  20. package/dist/cjs/components/popover.js +1 -1
  21. package/dist/cjs/components/popover.js.map +2 -2
  22. package/dist/cjs/components/radio.d.ts +13 -2
  23. package/dist/cjs/components/radio.js +1 -1
  24. package/dist/cjs/components/radio.js.map +3 -3
  25. package/dist/cjs/components/skeleton.d.ts +6 -3
  26. package/dist/cjs/components/skeleton.js +4 -1
  27. package/dist/cjs/components/skeleton.js.map +3 -3
  28. package/dist/cjs/components/text.d.ts +8 -4
  29. package/dist/cjs/components/text.js +1 -1
  30. package/dist/cjs/components/text.js.map +3 -3
  31. package/dist/cjs/icons/spinner.js +1 -1
  32. package/dist/cjs/icons/spinner.js.map +2 -2
  33. package/dist/cjs/stories/badge.stories.js +1 -1
  34. package/dist/cjs/stories/badge.stories.js.map +2 -2
  35. package/dist/cjs/stories/button.stories.js +1 -1
  36. package/dist/cjs/stories/button.stories.js.map +2 -2
  37. package/dist/cjs/stories/checkbox.stories.d.ts +44 -3
  38. package/dist/cjs/stories/checkbox.stories.js +1 -1
  39. package/dist/cjs/stories/checkbox.stories.js.map +3 -3
  40. package/dist/cjs/stories/dialog.stories.js +1 -1
  41. package/dist/cjs/stories/dialog.stories.js.map +2 -2
  42. package/dist/cjs/stories/heading.stories.d.ts +68 -0
  43. package/dist/cjs/stories/heading.stories.js +2 -0
  44. package/dist/cjs/stories/heading.stories.js.map +7 -0
  45. package/dist/cjs/stories/input.stories.js +1 -1
  46. package/dist/cjs/stories/input.stories.js.map +2 -2
  47. package/dist/cjs/stories/popover.stories.js +1 -1
  48. package/dist/cjs/stories/popover.stories.js.map +2 -2
  49. package/dist/cjs/stories/radio.stories.d.ts +34 -3
  50. package/dist/cjs/stories/radio.stories.js +1 -1
  51. package/dist/cjs/stories/radio.stories.js.map +3 -3
  52. package/dist/cjs/stories/skeleton.stories.d.ts +9 -3
  53. package/dist/cjs/stories/skeleton.stories.js +1 -1
  54. package/dist/cjs/stories/skeleton.stories.js.map +3 -3
  55. package/dist/cjs/stories/text.stories.d.ts +57 -4
  56. package/dist/cjs/stories/text.stories.js +9 -1
  57. package/dist/cjs/stories/text.stories.js.map +3 -3
  58. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  59. package/dist/esm/components/badge.js +1 -1
  60. package/dist/esm/components/badge.js.map +2 -2
  61. package/dist/esm/components/button.js +1 -1
  62. package/dist/esm/components/button.js.map +2 -2
  63. package/dist/esm/components/checkbox.d.ts +8 -1
  64. package/dist/esm/components/checkbox.js +1 -1
  65. package/dist/esm/components/checkbox.js.map +3 -3
  66. package/dist/esm/components/dialog.js +1 -1
  67. package/dist/esm/components/dialog.js.map +2 -2
  68. package/dist/esm/components/heading.d.ts +9 -1
  69. package/dist/esm/components/heading.js +1 -1
  70. package/dist/esm/components/heading.js.map +3 -3
  71. package/dist/esm/components/index.d.ts +1 -0
  72. package/dist/esm/components/index.js +1 -1
  73. package/dist/esm/components/index.js.map +2 -2
  74. package/dist/esm/components/input.d.ts +1 -1
  75. package/dist/esm/components/input.js +1 -1
  76. package/dist/esm/components/input.js.map +2 -2
  77. package/dist/esm/components/popover.js +1 -1
  78. package/dist/esm/components/popover.js.map +2 -2
  79. package/dist/esm/components/radio.d.ts +13 -2
  80. package/dist/esm/components/radio.js +1 -1
  81. package/dist/esm/components/radio.js.map +3 -3
  82. package/dist/esm/components/skeleton.d.ts +6 -3
  83. package/dist/esm/components/skeleton.js +4 -1
  84. package/dist/esm/components/skeleton.js.map +3 -3
  85. package/dist/esm/components/text.d.ts +8 -4
  86. package/dist/esm/components/text.js +1 -1
  87. package/dist/esm/components/text.js.map +3 -3
  88. package/dist/esm/icons/spinner.js +1 -1
  89. package/dist/esm/icons/spinner.js.map +2 -2
  90. package/dist/esm/stories/badge.stories.js +1 -1
  91. package/dist/esm/stories/badge.stories.js.map +2 -2
  92. package/dist/esm/stories/button.stories.js +1 -1
  93. package/dist/esm/stories/button.stories.js.map +2 -2
  94. package/dist/esm/stories/checkbox.stories.d.ts +44 -3
  95. package/dist/esm/stories/checkbox.stories.js +1 -1
  96. package/dist/esm/stories/checkbox.stories.js.map +3 -3
  97. package/dist/esm/stories/dialog.stories.js +1 -1
  98. package/dist/esm/stories/dialog.stories.js.map +2 -2
  99. package/dist/esm/stories/heading.stories.d.ts +68 -0
  100. package/dist/esm/stories/heading.stories.js +2 -0
  101. package/dist/esm/stories/heading.stories.js.map +7 -0
  102. package/dist/esm/stories/input.stories.js +1 -1
  103. package/dist/esm/stories/input.stories.js.map +2 -2
  104. package/dist/esm/stories/popover.stories.js +1 -1
  105. package/dist/esm/stories/popover.stories.js.map +2 -2
  106. package/dist/esm/stories/radio.stories.d.ts +34 -3
  107. package/dist/esm/stories/radio.stories.js +1 -1
  108. package/dist/esm/stories/radio.stories.js.map +3 -3
  109. package/dist/esm/stories/skeleton.stories.d.ts +9 -3
  110. package/dist/esm/stories/skeleton.stories.js +1 -1
  111. package/dist/esm/stories/skeleton.stories.js.map +3 -3
  112. package/dist/esm/stories/text.stories.d.ts +57 -4
  113. package/dist/esm/stories/text.stories.js +9 -1
  114. package/dist/esm/stories/text.stories.js.map +3 -3
  115. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  116. package/package.json +1 -1
  117. package/src/components/badge.tsx +5 -5
  118. package/src/components/button.tsx +14 -14
  119. package/src/components/checkbox.tsx +33 -17
  120. package/src/components/dialog.tsx +12 -9
  121. package/src/components/heading.tsx +59 -4
  122. package/src/components/index.ts +1 -0
  123. package/src/components/input.tsx +9 -9
  124. package/src/components/popover.tsx +1 -1
  125. package/src/components/radio.tsx +60 -25
  126. package/src/components/skeleton.tsx +33 -2
  127. package/src/components/text.tsx +45 -16
  128. package/src/icons/spinner.tsx +1 -1
  129. package/src/stories/badge.stories.tsx +1 -1
  130. package/src/stories/button.stories.tsx +1 -1
  131. package/src/stories/checkbox.stories.tsx +82 -5
  132. package/src/stories/dialog.stories.tsx +8 -8
  133. package/src/stories/heading.stories.tsx +88 -0
  134. package/src/stories/input.stories.tsx +2 -2
  135. package/src/stories/popover.stories.tsx +2 -2
  136. package/src/stories/radio.stories.tsx +51 -15
  137. package/src/stories/skeleton.stories.tsx +41 -7
  138. package/src/stories/text.stories.tsx +93 -10
  139. package/src/styles/global.css +5 -5
  140. package/style.css +246 -186
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anker-in/headless-ui",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "type": "commonjs",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "types": "./dist/cjs/index.d.ts",
@@ -4,14 +4,14 @@ import { type VariantProps, cva } from 'class-variance-authority'
4
4
  import { cn } from '../helpers/index.js'
5
5
 
6
6
  const badgeVariants = cva(
7
- 'inline-flex items-center rounded-[20px] border px-[10px] py-1 text-xs font-medium transition-colors focus:outline-none',
7
+ 'ai-inline-flex ai-items-center ai-font-medium ai-rounded-[20px] ai-border ai-px-[10px] ai-py-1 ai-text-xs ai-transition-colors focus:ai-outline-none',
8
8
  {
9
9
  variants: {
10
10
  variant: {
11
- default: 'bg-badge text-badge-foreground border-transparent',
12
- secondary: 'bg-secondary text-secondary-foreground border-transparent',
13
- destructive: 'bg-destructive text-destructive-foreground border-transparent',
14
- outline: 'text-foreground',
11
+ default: 'ai-bg-badge ai-text-badge-foreground ai-border-transparent',
12
+ secondary: 'ai-bg-secondary ai-text-secondary-foreground ai-border-transparent',
13
+ destructive: 'ai-bg-destructive ai-text-destructive-foreground ai-border-transparent',
14
+ outline: 'ai-text-foreground',
15
15
  },
16
16
  },
17
17
  defaultVariants: {
@@ -11,22 +11,22 @@ import { cn } from '../helpers/index.js'
11
11
  * Button Variants
12
12
  */
13
13
  const buttonVariants = cva(
14
- 'ring-offset-background focus-visible:ring-ring rounded-btn inline-flex items-center justify-center whitespace-nowrap text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
14
+ 'ai-ring-offset-background focus-visible:ai-ring-ring ai-rounded-btn ai-inline-flex ai-items-center ai-justify-center ai-whitespace-nowrap ai-text-sm ai-font-medium ai-transition-colors focus-visible:ai-outline-none focus-visible:ai-ring-2 focus-visible:ai-ring-offset-2 disabled:ai-pointer-events-none disabled:ai-opacity-50',
15
15
  {
16
16
  variants: {
17
17
  variant: {
18
18
  primary:
19
- 'bg-btn-primary text-btn-primary-foreground hover:bg-btn-primary-active disabled:bg-btn-primary-disabled disabled:text-btn-primary-disabled-foreground',
19
+ 'ai-bg-btn-primary ai-text-btn-primary-foreground hover:ai-bg-btn-primary-active disabled:ai-bg-btn-primary-disabled disabled:ai-text-btn-primary-disabled-foreground',
20
20
  secondary:
21
- 'bg-btn-secondary border-primary text-btn-secondary-foreground hover:bg-btn-secondary-active hover:text-btn-secondary disabled:bg-btn-secondary-disabled disabled:text-btn-secondary-disabled-foreground border border-solid',
22
- link: 'text-primary underline-offset-4 hover:underline',
23
- ghost: 'hover:bg-btn-primary hover:text-btn-primary-foreground',
21
+ 'ai-bg-btn-secondary ai-border-primary ai-text-btn-secondary-foreground hover:ai-bg-btn-secondary-active hover:ai-text-btn-secondary disabled:ai-bg-btn-secondary-disabled disabled:ai-text-btn-secondary-disabled-foreground ai-border ai-border-solid',
22
+ link: 'ai-text-primary ai-underline-offset-4 hover:ai-underline',
23
+ ghost: 'hover:ai-bg-btn-primary hover:ai-text-btn-primary-foreground',
24
24
  },
25
25
  size: {
26
- sm: 'h-8 px-3 py-1',
27
- base: 'h-10 px-4 py-2',
28
- lg: 'h-11 px-8',
29
- icon: 'size-10 rounded-full',
26
+ sm: 'ai-h-8 ai-px-3 ai-py-1 ai-text-[12px]',
27
+ base: 'ai-h-10 ai-px-4 ai-py-2 ai-text-[14px]',
28
+ lg: 'ai-h-11 ai-px-8 ai-text-[16px]',
29
+ icon: 'ai-size-10 ai-rounded-full',
30
30
  },
31
31
  /** hover 状态下的动画效果,需要注意不同variant 下的效果 */
32
32
  hoverEffect: {
@@ -39,13 +39,13 @@ const buttonVariants = cva(
39
39
  variant: 'primary',
40
40
  hoverEffect: 'slide',
41
41
  class:
42
- 'before:rounded-btn hover:bg-btn-primary before:bg-btn-primary-active relative overflow-hidden before:absolute before:inset-y-0 before:w-full before:-translate-x-full before:transition-transform before:duration-300 before:ease-in-out before:content-[""] hover:before:translate-x-0',
42
+ 'ai-z-[1] before:-ai-z-[1] before:ai-rounded-btn hover:!ai-bg-btn-primary before:ai-bg-btn-primary-active ai-relative ai-overflow-hidden before:ai-absolute before:ai-inset-y-0 before:ai-w-full before:-ai-translate-x-full before:ai-transition-transform before:ai-duration-300 before:ai-ease-in-out before:ai-content-[""] hover:before:ai-translate-x-0',
43
43
  },
44
44
  {
45
45
  variant: 'secondary',
46
46
  hoverEffect: 'slide',
47
47
  class:
48
- 'before:rounded-btn hover:bg-btn-secondary before:bg-btn-secondary-active relative overflow-hidden before:absolute before:inset-y-0 before:w-full before:-translate-x-full before:transition-transform before:duration-300 before:ease-in-out before:content-[""] hover:before:translate-x-0',
48
+ 'ai-z-[1] before:-ai-z-[1] before:ai-rounded-btn hover:!ai-bg-btn-secondary before:ai-bg-btn-secondary-active ai-relative ai-overflow-hidden before:ai-absolute before:ai-inset-y-0 before:ai-w-full before:-ai-translate-x-full before:ai-transition-transform before:ai-duration-300 before:ai-ease-in-out before:ai-content-[""] hover:before:ai-translate-x-0',
49
49
  },
50
50
  ],
51
51
  defaultVariants: {
@@ -90,7 +90,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
90
90
  className={cn(
91
91
  buttonVariants({ variant, size, hoverEffect }),
92
92
  {
93
- 'cursor-not-allowed': disabled,
93
+ 'ai-cursor-not-allowed': disabled,
94
94
  },
95
95
  className
96
96
  )}
@@ -102,13 +102,13 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
102
102
  <span style={{ display: 'contents', visibility: 'hidden' }} aria-hidden>
103
103
  {children}
104
104
  </span>
105
- <span className="absolute">
105
+ <span className="ai-absolute">
106
106
  <Spinner />
107
107
  </span>
108
108
  <VisuallyHidden>{children}</VisuallyHidden>
109
109
  </>
110
110
  ) : (
111
- <span className="z-[1]">{children}</span>
111
+ children
112
112
  )}
113
113
  </Comp>
114
114
  )
@@ -5,24 +5,40 @@ import * as CheckboxPrimitive from '@radix-ui/react-checkbox'
5
5
  import { CheckIcon } from '@radix-ui/react-icons'
6
6
 
7
7
  import { cn } from '../helpers/index.js'
8
+ import { cva, type VariantProps } from 'class-variance-authority'
8
9
 
9
- const Checkbox = React.forwardRef<
10
- React.ElementRef<typeof CheckboxPrimitive.Root>,
11
- React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
12
- >(({ className, ...props }, ref) => (
13
- <CheckboxPrimitive.Root
14
- ref={ref}
15
- className={cn(
16
- 'border-primary ring-offset-background focus-visible:ring-ring data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground peer size-4 shrink-0 rounded-sm border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
17
- className
18
- )}
19
- {...props}
20
- >
21
- <CheckboxPrimitive.Indicator className={cn('flex items-center justify-center text-current')}>
22
- <CheckIcon className="size-4" />
23
- </CheckboxPrimitive.Indicator>
24
- </CheckboxPrimitive.Root>
25
- ))
10
+ const checkboxVariants = cva(
11
+ 'ai-border-primary ai-ring-offset-background focus-visible:ai-ring-ring data-[state=checked]:ai-bg-primary data-[state=checked]:ai-text-primary-foreground ai-peer ai-shrink-0 ai-rounded-sm ai-border focus-visible:ai-outline-none focus-visible:ai-ring-2 focus-visible:ai-ring-offset-2 disabled:ai-cursor-not-allowed disabled:ai-opacity-50 disabled:ai-bg-btn-primary-disabled',
12
+ {
13
+ variants: {
14
+ size: {
15
+ sm: 'ai-size-[14px]',
16
+ base: 'ai-size-4',
17
+ lg: 'ai-size-5',
18
+ },
19
+ },
20
+ defaultVariants: {
21
+ size: 'base',
22
+ },
23
+ }
24
+ )
25
+
26
+ interface CheckboxProps
27
+ extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>,
28
+ VariantProps<typeof checkboxVariants> {}
29
+
30
+ const Checkbox = React.forwardRef<React.ElementRef<typeof CheckboxPrimitive.Root>, CheckboxProps>(
31
+ ({ className, size, ...props }, ref) => (
32
+ <CheckboxPrimitive.Root ref={ref} className={cn(checkboxVariants({ size }), className)} {...props}>
33
+ <CheckboxPrimitive.Indicator
34
+ className={cn('ai-flex ai-items-center ai-justify-center ai-text-current ai-w-full ai-h-full')}
35
+ >
36
+ <CheckIcon />
37
+ </CheckboxPrimitive.Indicator>
38
+ </CheckboxPrimitive.Root>
39
+ )
40
+ )
26
41
  Checkbox.displayName = CheckboxPrimitive.Root.displayName
27
42
 
28
43
  export default Checkbox
44
+ export type { CheckboxProps }
@@ -21,7 +21,7 @@ const DialogOverlay = React.forwardRef<
21
21
  <DialogPrimitive.Overlay
22
22
  ref={ref}
23
23
  className={cn(
24
- 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80',
24
+ 'data-[state=open]:ai-animate-in data-[state=closed]:ai-animate-out data-[state=closed]:ai-fade-out-0 data-[state=open]:ai-fade-in-0 ai-fixed ai-inset-0 ai-z-50 ai-bg-black/80',
25
25
  className
26
26
  )}
27
27
  {...props}
@@ -38,15 +38,15 @@ const DialogContent = React.forwardRef<
38
38
  <DialogPrimitive.Content
39
39
  ref={ref}
40
40
  className={cn(
41
- 'bg-background 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%] fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg',
41
+ 'ai-bg-background data-[state=open]:ai-animate-in data-[state=closed]:ai-animate-out data-[state=closed]:ai-fade-out-0 data-[state=open]:ai-fade-in-0 data-[state=closed]:ai-zoom-out-95 data-[state=open]:ai-zoom-in-95 data-[state=closed]:ai-slide-out-to-left-1/2 data-[state=closed]:ai-slide-out-to-top-[48%] data-[state=open]:ai-slide-in-from-left-1/2 data-[state=open]:ai-slide-in-from-top-[48%] ai-fixed ai-left-1/2 ai-top-1/2 ai-z-50 ai-grid ai-w-full ai-max-w-lg -ai-translate-x-1/2 -ai-translate-y-1/2 ai-gap-4 ai-border ai-p-6 ai-shadow-lg ai-duration-200 sm:ai-rounded-lg',
42
42
  className
43
43
  )}
44
44
  {...props}
45
45
  >
46
46
  {children}
47
- <DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none">
48
- <Cross2Icon className="size-4" />
49
- <span className="sr-only">Close</span>
47
+ <DialogPrimitive.Close className="ai-ring-offset-background focus:ai-ring-ring data-[state=open]:ai-bg-accent data-[state=open]:ai-text-muted-foreground ai-absolute ai-right-4 ai-top-4 ai-rounded-sm ai-opacity-70 ai-transition-opacity hover:ai-opacity-100 focus:ai-outline-none focus:ai-ring-2 focus:ai-ring-offset-2 disabled:ai-pointer-events-none">
48
+ <Cross2Icon className="ai-size-4" />
49
+ <span className="ai-sr-only">Close</span>
50
50
  </DialogPrimitive.Close>
51
51
  </DialogPrimitive.Content>
52
52
  </DialogPortal>
@@ -54,12 +54,15 @@ const DialogContent = React.forwardRef<
54
54
  DialogContent.displayName = DialogPrimitive.Content.displayName
55
55
 
56
56
  const DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
57
- <div className={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)} {...props} />
57
+ <div className={cn('ai-flex ai-flex-col ai-space-y-1.5 ai-text-center sm:ai-text-left', className)} {...props} />
58
58
  )
59
59
  DialogHeader.displayName = 'DialogHeader'
60
60
 
61
61
  const DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
62
- <div className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)} {...props} />
62
+ <div
63
+ className={cn('ai-flex ai-flex-col-reverse sm:ai-flex-row sm:ai-justify-end sm:ai-space-x-2', className)}
64
+ {...props}
65
+ />
63
66
  )
64
67
  DialogFooter.displayName = 'DialogFooter'
65
68
 
@@ -69,7 +72,7 @@ const DialogTitle = React.forwardRef<
69
72
  >(({ className, ...props }, ref) => (
70
73
  <DialogPrimitive.Title
71
74
  ref={ref}
72
- className={cn('text-lg font-semibold leading-none tracking-tight', className)}
75
+ className={cn('ai-text-lg ai-font-semibold ai-leading-none ai-tracking-tight', className)}
73
76
  {...props}
74
77
  />
75
78
  ))
@@ -79,7 +82,7 @@ const DialogDescription = React.forwardRef<
79
82
  React.ElementRef<typeof DialogPrimitive.Description>,
80
83
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
81
84
  >(({ className, ...props }, ref) => (
82
- <DialogPrimitive.Description ref={ref} className={cn('text-muted-foreground text-sm', className)} {...props} />
85
+ <DialogPrimitive.Description ref={ref} className={cn('ai-text-muted-foreground ai-text-sm', className)} {...props} />
83
86
  ))
84
87
  DialogDescription.displayName = DialogPrimitive.Description.displayName
85
88
 
@@ -1,19 +1,73 @@
1
1
  import { cn } from '../helpers/index.js'
2
2
  import { Slot } from '@radix-ui/react-slot'
3
+ import { cva, type VariantProps } from 'class-variance-authority'
3
4
  import React from 'react'
4
5
 
6
+ const headingVariants = cva('', {
7
+ variants: {
8
+ size: {
9
+ 1: 'ai-text-xs',
10
+ 2: 'ai-text-sm',
11
+ 3: 'ai-text-base',
12
+ 4: 'ai-text-lg',
13
+ 5: 'ai-text-xl',
14
+ 6: 'ai-text-2xl',
15
+ 7: 'ai-text-3xl',
16
+ 8: 'ai-text-4xl',
17
+ 9: 'ai-text-5xl',
18
+ },
19
+ weights: {
20
+ light: 'ai-font-light',
21
+ normal: 'ai-font-normal',
22
+ medium: 'ai-font-medium',
23
+ bold: 'ai-font-bold',
24
+ },
25
+ },
26
+ defaultVariants: {
27
+ size: 3,
28
+ weights: 'normal',
29
+ },
30
+ })
31
+
5
32
  type HeadingElement = React.ElementRef<'h1'>
6
33
 
7
- interface HeadingProps extends React.ComponentPropsWithoutRef<'h1'> {
34
+ interface HeadingProps extends React.ComponentPropsWithoutRef<'h1'>, VariantProps<typeof headingVariants> {
8
35
  as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | undefined
9
36
  asChild?: boolean
37
+ color?: string
38
+ html?: string
10
39
  }
11
40
 
12
41
  const Heading = React.forwardRef<HeadingElement, HeadingProps>((props, forwardedRef) => {
13
- const { children, className, asChild, as: Tag = 'h1', color, ...headingProps } = props
42
+ const { children, className, size, weights, asChild, as: Tag = 'h1', color, html, ...headingProps } = props
43
+ const htmlContentProps = html
44
+ ? {
45
+ dangerouslySetInnerHTML: { __html: html },
46
+ }
47
+ : null
48
+
49
+ const styleProps = color
50
+ ? {
51
+ style: {
52
+ color,
53
+ },
54
+ }
55
+ : null
14
56
  return (
15
- <Slot data-accent-color={color || undefined} {...headingProps} ref={forwardedRef} className={cn('', className)}>
16
- {asChild ? children : <Tag>{children}</Tag>}
57
+ <Slot
58
+ {...headingProps}
59
+ ref={forwardedRef}
60
+ className={cn(
61
+ headingVariants({
62
+ size,
63
+ weights,
64
+ }),
65
+ className
66
+ )}
67
+ {...htmlContentProps}
68
+ {...styleProps}
69
+ >
70
+ {asChild ? children : <Tag>{htmlContentProps ? null : children}</Tag>}
17
71
  </Slot>
18
72
  )
19
73
  })
@@ -21,3 +75,4 @@ const Heading = React.forwardRef<HeadingElement, HeadingProps>((props, forwarded
21
75
  Heading.displayName = 'Heading'
22
76
 
23
77
  export { Heading }
78
+ export type { HeadingProps }
@@ -14,4 +14,5 @@ export * from './popover.js'
14
14
  export * from './radio.js'
15
15
  export * from './dialog.js'
16
16
  export * from './text.js'
17
+ export * from './heading.js'
17
18
  export { default as Theme } from './theme.js'
@@ -2,17 +2,17 @@
2
2
 
3
3
  import * as React from 'react'
4
4
  import { cn } from '../helpers/index.js'
5
- import type { ComponentPropsWithout, RemovedProps } from '@/helpers/component-props'
5
+ import type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js'
6
6
  import { cva, type VariantProps } from 'class-variance-authority'
7
7
 
8
8
  const inputVariants = cva(
9
- 'border-input bg-background focus-visible:ring-ring ring-offset-background flex h-2 flex-row items-center overflow-hidden rounded-md border px-3 focus-visible:ring-2 focus-visible:ring-offset-2',
9
+ 'ai-border-input ai-bg-background focus-visible:ai-ring-ring ai-ring-offset-background ai-flex ai-flex-row ai-items-center ai-overflow-hidden ai-rounded-md ai-border ai-px-3 focus-visible:ai-ring-2 focus-visible:ai-ring-offset-2',
10
10
  {
11
11
  variants: {
12
12
  size: {
13
- sm: 'h-8',
14
- base: 'h-10',
15
- lg: 'h-12',
13
+ sm: 'ai-h-8',
14
+ base: 'ai-h-10',
15
+ lg: 'ai-h-12',
16
16
  },
17
17
  },
18
18
  defaultVariants: {
@@ -42,9 +42,9 @@ const InputSlot = React.forwardRef<InputSlotElement, InputSlotProps>((props, for
42
42
  <div
43
43
  ref={forwardedRef}
44
44
  {...slotProps}
45
- className={cn('flex h-full items-center px-2', className, {
46
- '-order-1 pl-0': side === 'left',
47
- 'order-2 pr-0': side === 'right',
45
+ className={cn('ai-flex ai-h-full ai-items-center ai-px-2', className, {
46
+ '-ai-order-1 ai-pl-0': side === 'left',
47
+ 'ai-order-2 ai-pr-0': side === 'right',
48
48
  })}
49
49
  >
50
50
  {children}
@@ -59,7 +59,7 @@ const Input = React.forwardRef<React.ElementRef<'input'>, InputProps>(
59
59
  <input
60
60
  type={type}
61
61
  className={cn(
62
- 'placeholder:text-muted-foreground flex size-full text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50'
62
+ 'placeholder:ai-text-muted-foreground ai-flex ai-size-full ai-text-sm file:ai-border-0 file:ai-bg-transparent file:ai-text-sm file:ai-font-medium focus-visible:ai-outline-none disabled:ai-cursor-not-allowed disabled:ai-opacity-50'
63
63
  )}
64
64
  ref={ref}
65
65
  {...props}
@@ -19,7 +19,7 @@ const PopoverContent = React.forwardRef<
19
19
  align={align}
20
20
  sideOffset={sideOffset}
21
21
  className={cn(
22
- 'bg-popover text-popover-foreground 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-none',
22
+ 'ai-bg-popover ai-text-popover-foreground data-[state=open]:ai-animate-in data-[state=closed]:ai-animate-out data-[state=closed]:ai-fade-out-0 data-[state=open]:ai-fade-in-0 data-[state=closed]:ai-zoom-out-95 data-[state=open]:ai-zoom-in-95 data-[side=bottom]:ai-slide-in-from-top-2 data-[side=left]:ai-slide-in-from-right-2 data-[side=right]:ai-slide-in-from-left-2 data-[side=top]:ai-slide-in-from-bottom-2 ai-z-50 ai-w-72 ai-rounded-md ai-border ai-p-4 ai-shadow-md ai-outline-none',
23
23
  className
24
24
  )}
25
25
  {...props}
@@ -3,36 +3,71 @@
3
3
  import * as React from 'react'
4
4
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group'
5
5
  import { CheckIcon } from '@radix-ui/react-icons'
6
-
6
+ import { cva, type VariantProps } from 'class-variance-authority'
7
7
  import { cn } from '../helpers/index.js'
8
8
 
9
- const RadioGroup = React.forwardRef<
10
- React.ElementRef<typeof RadioGroupPrimitive.Root>,
11
- React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
12
- >(({ className, ...props }, ref) => {
13
- return <RadioGroupPrimitive.Root className={cn('grid gap-2', className)} {...props} ref={ref} />
9
+ const RadioContext = React.createContext<{ size?: 'sm' | 'base' | 'lg' }>({
10
+ size: 'base',
14
11
  })
12
+
13
+ const radioGroupVariants = cva(
14
+ 'ai-border-primary ai-text-primary ai-ring-offset-background focus-visible:ai-ring-ring ai-aspect-square ai-rounded-full ai-border focus:ai-outline-none focus-visible:ai-ring-2 focus-visible:ai-ring-offset-2 disabled:ai-cursor-not-allowed disabled:ai-opacity-50 data-[state=checked]:ai-bg-primary data-[state=checked]:ai-text-primary-foreground',
15
+ {
16
+ variants: {
17
+ size: {
18
+ sm: 'ai-size-[14px]',
19
+ base: 'ai-size-4',
20
+ lg: 'ai-size-5',
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ size: 'base',
25
+ },
26
+ }
27
+ )
28
+
29
+ interface RadioGroupProps extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {
30
+ /** 尺寸 */
31
+ size?: 'sm' | 'base' | 'lg'
32
+ }
33
+
34
+ const RadioGroup = React.forwardRef<React.ElementRef<typeof RadioGroupPrimitive.Root>, RadioGroupProps>(
35
+ ({ className, children, size, ...props }, ref) => {
36
+ return (
37
+ <RadioGroupPrimitive.Root className={cn('grid gap-2', className)} {...props} ref={ref}>
38
+ <RadioContext.Provider value={{ size }}>{children}</RadioContext.Provider>
39
+ </RadioGroupPrimitive.Root>
40
+ )
41
+ }
42
+ )
15
43
  RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
16
44
 
17
- const RadioGroupItem = React.forwardRef<
18
- React.ElementRef<typeof RadioGroupPrimitive.Item>,
19
- React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
20
- >(({ className, ...props }, ref) => {
21
- return (
22
- <RadioGroupPrimitive.Item
23
- ref={ref}
24
- className={cn(
25
- 'border-primary text-primary ring-offset-background focus-visible:ring-ring aspect-square size-4 rounded-full border focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
26
- className
27
- )}
28
- {...props}
29
- >
30
- <RadioGroupPrimitive.Indicator className="flex items-center justify-center">
31
- <CheckIcon className="text-primary size-2.5 fill-current" />
32
- </RadioGroupPrimitive.Indicator>
33
- </RadioGroupPrimitive.Item>
34
- )
35
- })
45
+ interface RadioGroupItemProps
46
+ extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,
47
+ VariantProps<typeof radioGroupVariants> {}
48
+
49
+ const RadioGroupItem = React.forwardRef<React.ElementRef<typeof RadioGroupPrimitive.Item>, RadioGroupItemProps>(
50
+ ({ className, size, ...props }, ref) => {
51
+ const { size: sizeFromParent } = React.useContext(RadioContext)
52
+ return (
53
+ <RadioGroupPrimitive.Item
54
+ ref={ref}
55
+ className={cn(
56
+ radioGroupVariants({
57
+ size: size ?? sizeFromParent,
58
+ }),
59
+ className
60
+ )}
61
+ {...props}
62
+ >
63
+ <RadioGroupPrimitive.Indicator className="ai-flex ai-items-center ai-justify-center ai-text-current ai-w-full ai-h-full">
64
+ <CheckIcon />
65
+ </RadioGroupPrimitive.Indicator>
66
+ </RadioGroupPrimitive.Item>
67
+ )
68
+ }
69
+ )
36
70
  RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
37
71
 
38
72
  export { RadioGroup, RadioGroupItem }
73
+ export type { RadioGroupProps, RadioGroupItemProps }
@@ -1,10 +1,41 @@
1
1
  import * as React from 'react'
2
2
  import { cn } from '../helpers/index.js'
3
+ import { Slot } from '@radix-ui/react-slot'
4
+ import type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js'
3
5
 
4
- function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
5
- return <div className={cn('bg-skeleton size-12 animate-pulse', className)} {...props} />
6
+ type SkeletonElement = React.ElementRef<'span'>
7
+
8
+ interface SkeletonProps extends ComponentPropsWithout<'span', RemovedProps> {
9
+ /** 是否正在加载 */
10
+ loading?: boolean
6
11
  }
7
12
 
13
+ const Skeleton = React.forwardRef<SkeletonElement, SkeletonProps>((props, forwardedRef) => {
14
+ const { children, className, loading = true, ...skeletonProps } = props
15
+
16
+ if (!loading) return children
17
+ const Tag = React.isValidElement(children) ? Slot : 'span'
18
+
19
+ return (
20
+ <Tag
21
+ ref={forwardedRef}
22
+ className={cn(
23
+ `ai-bg-skeleton ai-animate-pulse empty:ai-block data-[inline-skeleton=true]:ai-leading-[0] !ai-bg-none !ai-bg-clip-border !ai-border-none !ai-shadow-none
24
+ !ai-text-transparent !ai-outline-none !ai-select-none !ai-cursor-default !ai-pointer-events-none !ai-decoration-clone
25
+ after:!ai-invisible before:!ai-invisible [&>*]:!ai-invisible
26
+ `,
27
+ className
28
+ )}
29
+ data-inline-skeleton={React.isValidElement(children) ? undefined : true}
30
+ tabIndex={-1}
31
+ {...skeletonProps}
32
+ >
33
+ {children}
34
+ </Tag>
35
+ )
36
+ })
37
+
8
38
  Skeleton.displayName = 'Skeleton'
9
39
 
10
40
  export default Skeleton
41
+ export type { SkeletonProps }
@@ -6,41 +6,70 @@ import { type VariantProps, cva } from 'class-variance-authority'
6
6
  const textVariants = cva('', {
7
7
  variants: {
8
8
  size: {
9
- 1: 'text-xs',
10
- 2: 'text-sm',
11
- 3: 'text-base',
12
- 4: 'text-lg',
13
- 5: 'text-xl',
14
- 6: 'text-2xl',
15
- 7: 'text-3xl',
16
- 8: 'text-4xl',
17
- 9: 'text-5xl',
9
+ 1: 'ai-text-xs',
10
+ 2: 'ai-text-sm',
11
+ 3: 'ai-text-base',
12
+ 4: 'ai-text-lg',
13
+ 5: 'ai-text-xl',
14
+ 6: 'ai-text-2xl',
15
+ 7: 'ai-text-3xl',
16
+ 8: 'ai-text-4xl',
17
+ 9: 'ai-text-5xl',
18
18
  },
19
+ weights: {
20
+ light: 'ai-font-light',
21
+ normal: 'ai-font-normal',
22
+ medium: 'ai-font-medium',
23
+ bold: 'ai-font-bold',
24
+ },
25
+ },
26
+ defaultVariants: {
27
+ size: 3,
28
+ weights: 'normal',
19
29
  },
20
30
  })
21
31
 
22
32
  type TextElement = React.ElementRef<'span'>
23
- interface TextProps extends React.ComponentPropsWithoutRef<'span'> {
33
+ interface TextProps extends React.ComponentPropsWithoutRef<'span'>, VariantProps<typeof textVariants> {
24
34
  as?: 'div' | 'label' | 'p' | 'span' | undefined
25
35
  asChild?: boolean
26
36
  color?: string
37
+ /** 相当于 dangerouslySetInnerHTML */
38
+ html?: string
27
39
  }
28
40
 
29
- const Text = React.forwardRef<TextElement, TextProps & VariantProps<typeof textVariants>>((props, forwardedRef) => {
30
- const { children, size, className, asChild, as: Tag = 'span', color, ...textProps } = props
41
+ const Text = React.forwardRef<TextElement, TextProps>((props, forwardedRef) => {
42
+ const { children, size, weights, className, asChild, as: Tag = 'span', color, html, ...textProps } = props
43
+
44
+ const htmlContentProps = html
45
+ ? {
46
+ dangerouslySetInnerHTML: { __html: html },
47
+ }
48
+ : null
49
+
50
+ const styleProps = color
51
+ ? {
52
+ style: {
53
+ color,
54
+ },
55
+ }
56
+ : null
57
+
31
58
  return (
32
59
  <Slot
33
60
  {...textProps}
34
61
  ref={forwardedRef}
35
62
  className={cn(
36
63
  textVariants({
37
- size: size,
64
+ size,
65
+ weights,
38
66
  }),
39
- className,
40
- color
67
+ className
41
68
  )}
69
+ {...htmlContentProps}
70
+ {...styleProps}
42
71
  >
43
- {asChild ? children : <Tag>{children}</Tag>}
72
+ {asChild ? children : <Tag>{htmlContentProps ? null : children}</Tag>}
44
73
  </Slot>
45
74
  )
46
75
  })
@@ -8,7 +8,7 @@ export interface SpinnerProps {
8
8
  const Spinner = ({ size = 'sm', color = '#ffffff' }: SpinnerProps) => {
9
9
  return (
10
10
  <svg
11
- className="animate-spin"
11
+ className="ai-animate-spin"
12
12
  width="20"
13
13
  height="20"
14
14
  viewBox="0 0 20 20"
@@ -33,7 +33,7 @@ export const Default: Story = {}
33
33
  export const Examples: Story = {
34
34
  render() {
35
35
  return (
36
- <div className="flex flex-col space-y-4">
36
+ <div className="ai-flex ai-flex-col ai-space-y-4">
37
37
  <Badge variant="default">Default</Badge>
38
38
  <Badge variant="secondary">Secondary</Badge>
39
39
  <Badge variant="destructive">Destructive</Badge>
@@ -83,7 +83,7 @@ export const WithIcon: Story = {
83
83
  size: 'lg',
84
84
  children: (
85
85
  <>
86
- WithIcon <SearchIcon className="ml-2" />
86
+ WithIcon <SearchIcon className="ai-ml-2" />
87
87
  </>
88
88
  ),
89
89
  },