@saas-ui/react 2.11.2 → 3.0.0-alpha.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 (232) hide show
  1. package/CHANGELOG.md +7 -154
  2. package/dist/index.cjs +8461 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +26 -0
  5. package/dist/index.d.ts +25 -7
  6. package/dist/index.js +8415 -35
  7. package/dist/index.js.map +1 -1
  8. package/package.json +24 -21
  9. package/src/components/accordion.tsx +47 -0
  10. package/src/components/action-bar.tsx +40 -0
  11. package/src/components/alert.tsx +51 -0
  12. package/src/components/app-shell/app-shell.recipe.ts +52 -0
  13. package/src/components/app-shell/app-shell.stories.tsx +51 -0
  14. package/src/components/app-shell/app-shell.tsx +94 -0
  15. package/src/components/app-shell/index.ts +3 -0
  16. package/src/components/avatar.tsx +74 -0
  17. package/src/components/blockquote.tsx +31 -0
  18. package/src/components/breadcrumbs/breadcrumb.stories.tsx +17 -0
  19. package/src/components/breadcrumbs/breadcrumb.tsx +36 -0
  20. package/src/components/breadcrumbs/index.ts +1 -0
  21. package/src/components/breadcrumbs/namespace.ts +8 -0
  22. package/src/components/button/button.recipe.ts +182 -0
  23. package/src/components/button/button.stories.tsx +99 -0
  24. package/src/components/button/button.tsx +55 -0
  25. package/src/components/button/index.ts +2 -0
  26. package/src/components/checkbox/checkbox.tsx +26 -0
  27. package/src/components/checkbox/index.ts +2 -0
  28. package/src/components/checkbox-card.tsx +57 -0
  29. package/src/components/checkbox.tsx +25 -0
  30. package/src/components/clipboard.tsx +107 -0
  31. package/src/components/close-button/close-button.stories.tsx +12 -0
  32. package/src/components/close-button/close-button.tsx +18 -0
  33. package/src/components/close-button/index.ts +2 -0
  34. package/src/components/color-mode.tsx +65 -0
  35. package/src/components/command/command.recipe.ts +17 -0
  36. package/src/components/command/command.stories.tsx +47 -0
  37. package/src/components/command/command.tsx +50 -0
  38. package/src/components/command/index.ts +1 -0
  39. package/src/components/data-list.tsx +37 -0
  40. package/src/components/dialog/dialog.tsx +66 -0
  41. package/src/components/dialog/index.ts +1 -0
  42. package/src/components/dialog/namespace.ts +18 -0
  43. package/src/components/drawer/drawer.tsx +56 -0
  44. package/src/components/drawer/index.ts +3 -0
  45. package/src/components/drawer/namespace.ts +19 -0
  46. package/src/components/empty-state.tsx +34 -0
  47. package/src/components/field.tsx +33 -0
  48. package/src/components/file-button.tsx +166 -0
  49. package/src/components/grid-list/grid-list.recipe.ts +113 -0
  50. package/src/components/hover-card.tsx +35 -0
  51. package/src/components/icon-badge/icon-badge.recipe.ts +57 -0
  52. package/src/components/icon-badge/icon-badge.stories.tsx +38 -0
  53. package/src/components/icon-badge/icon-badge.tsx +59 -0
  54. package/src/components/icon-badge/index.ts +2 -0
  55. package/src/components/icons/create-icon.tsx +41 -0
  56. package/src/components/icons/icons.tsx +121 -0
  57. package/src/components/icons/index.ts +1 -0
  58. package/src/components/input-group/index.ts +1 -0
  59. package/src/components/input-group/input-group.tsx +46 -0
  60. package/src/components/link/index.ts +2 -0
  61. package/src/components/link/link.stories.tsx +17 -0
  62. package/src/components/link/link.test.tsx +33 -0
  63. package/src/components/link/link.tsx +27 -0
  64. package/src/components/link-button.tsx +12 -0
  65. package/src/components/loading-overlay/index.ts +1 -0
  66. package/src/components/loading-overlay/loading-overlay.recipe.ts +61 -0
  67. package/src/components/loading-overlay/loading-overlay.stories.tsx +68 -0
  68. package/src/components/loading-overlay/loading-overlay.tsx +54 -0
  69. package/src/components/loading-overlay/namespace.ts +7 -0
  70. package/src/components/menu.tsx +108 -0
  71. package/src/components/native-select.tsx +57 -0
  72. package/src/components/navbar/index.ts +1 -0
  73. package/src/components/navbar/namespace.ts +9 -0
  74. package/src/components/navbar/navbar.recipe.ts +109 -0
  75. package/src/components/navbar/navbar.stories.tsx +435 -0
  76. package/src/components/navbar/navbar.test.tsx +49 -0
  77. package/src/components/navbar/navbar.tsx +39 -0
  78. package/src/components/number-input/index.ts +2 -0
  79. package/src/components/number-input/number-input.tsx +41 -0
  80. package/src/components/pagination.tsx +207 -0
  81. package/src/components/password-input/index.ts +2 -0
  82. package/src/components/password-input/password-input.tsx +98 -0
  83. package/src/components/persona/index.ts +2 -0
  84. package/src/components/persona/namespace.ts +18 -0
  85. package/src/components/persona/persona-primitive.tsx +220 -0
  86. package/src/components/persona/persona.recipe.ts +94 -0
  87. package/src/components/persona/persona.stories.tsx +101 -0
  88. package/src/components/persona/persona.tsx +143 -0
  89. package/src/components/pin-input/index.ts +2 -0
  90. package/src/components/pin-input/pin-input.tsx +36 -0
  91. package/src/components/popover.tsx +58 -0
  92. package/src/components/progress-circle.tsx +37 -0
  93. package/src/components/progress.tsx +40 -0
  94. package/src/components/prose.tsx +264 -0
  95. package/src/components/provider.tsx +12 -0
  96. package/src/components/radio/index.ts +2 -0
  97. package/src/components/radio/radio.tsx +27 -0
  98. package/src/components/radio-card.tsx +57 -0
  99. package/src/components/radio.tsx +24 -0
  100. package/src/components/rating.tsx +27 -0
  101. package/src/components/search-input/index.ts +2 -0
  102. package/src/components/search-input/search-input.stories.tsx +63 -0
  103. package/src/components/search-input/search-input.tsx +134 -0
  104. package/src/components/segmented-control.tsx +47 -0
  105. package/src/components/select/index.ts +1 -0
  106. package/src/components/select/namespace.ts +18 -0
  107. package/src/components/select/select.tsx +135 -0
  108. package/src/components/sidebar/index.ts +7 -0
  109. package/src/components/sidebar/namespace.ts +27 -0
  110. package/src/components/sidebar/sidebar-item.recipe.ts +65 -0
  111. package/src/components/sidebar/sidebar.recipe.ts +237 -0
  112. package/src/components/sidebar/sidebar.stories.tsx +903 -0
  113. package/src/components/sidebar/sidebar.tsx +204 -0
  114. package/src/components/skeleton.tsx +44 -0
  115. package/src/components/slider.tsx +53 -0
  116. package/src/components/spinner/index.ts +2 -0
  117. package/src/components/spinner/spinner.stories.tsx +19 -0
  118. package/src/components/spinner/spinner.tsx +21 -0
  119. package/src/components/stat.tsx +75 -0
  120. package/src/components/status.tsx +29 -0
  121. package/src/components/stepper-input.tsx +49 -0
  122. package/src/components/steps/index.ts +1 -0
  123. package/src/components/steps/namespace.ts +16 -0
  124. package/src/components/steps/steps.tsx +82 -0
  125. package/src/components/switch/index.ts +3 -0
  126. package/src/components/switch/switch.tsx +39 -0
  127. package/src/components/tag.tsx +39 -0
  128. package/src/components/timeline.tsx +17 -0
  129. package/src/components/toaster.tsx +43 -0
  130. package/src/components/toggle-tip.tsx +62 -0
  131. package/src/components/tooltip.tsx +46 -0
  132. package/src/index.ts +6 -7
  133. package/src/preset.ts +9 -0
  134. package/src/provider/index.ts +4 -0
  135. package/src/provider/sui-provider.tsx +34 -0
  136. package/src/provider/use-link.test.tsx +60 -0
  137. package/src/provider/use-link.tsx +13 -0
  138. package/src/theme/animation-styles.ts +53 -0
  139. package/src/theme/breakpoints.ts +11 -0
  140. package/src/theme/conditions.ts +26 -0
  141. package/src/theme/fluid-font-sizes.ts +65 -0
  142. package/src/theme/global-css.ts +94 -0
  143. package/src/theme/index.ts +72 -0
  144. package/src/theme/layer-styles.ts +116 -0
  145. package/src/theme/recipes/chakra/accordion.ts +145 -0
  146. package/src/theme/recipes/chakra/action-bar.ts +62 -0
  147. package/src/theme/recipes/chakra/alert.ts +157 -0
  148. package/src/theme/recipes/chakra/avatar.ts +141 -0
  149. package/src/theme/recipes/chakra/badge.ts +67 -0
  150. package/src/theme/recipes/chakra/blockquote.ts +83 -0
  151. package/src/theme/recipes/chakra/breadcrumb.ts +94 -0
  152. package/src/theme/recipes/chakra/card.ts +99 -0
  153. package/src/theme/recipes/chakra/checkbox-card.ts +212 -0
  154. package/src/theme/recipes/chakra/checkbox.ts +70 -0
  155. package/src/theme/recipes/chakra/checkmark.ts +83 -0
  156. package/src/theme/recipes/chakra/code.ts +17 -0
  157. package/src/theme/recipes/chakra/collapsible.ts +20 -0
  158. package/src/theme/recipes/chakra/container.ts +26 -0
  159. package/src/theme/recipes/chakra/data-list.ts +80 -0
  160. package/src/theme/recipes/chakra/dialog.ts +225 -0
  161. package/src/theme/recipes/chakra/drawer.ts +201 -0
  162. package/src/theme/recipes/chakra/editable.ts +88 -0
  163. package/src/theme/recipes/chakra/empty-state.ts +88 -0
  164. package/src/theme/recipes/chakra/field.ts +68 -0
  165. package/src/theme/recipes/chakra/fieldset.ts +62 -0
  166. package/src/theme/recipes/chakra/file-upload.ts +96 -0
  167. package/src/theme/recipes/chakra/heading.ts +27 -0
  168. package/src/theme/recipes/chakra/hover-card.ts +68 -0
  169. package/src/theme/recipes/chakra/icon.ts +30 -0
  170. package/src/theme/recipes/chakra/input-addon.ts +40 -0
  171. package/src/theme/recipes/chakra/input.ts +96 -0
  172. package/src/theme/recipes/chakra/kbd.ts +60 -0
  173. package/src/theme/recipes/chakra/link.ts +37 -0
  174. package/src/theme/recipes/chakra/list.ts +67 -0
  175. package/src/theme/recipes/chakra/mark.ts +27 -0
  176. package/src/theme/recipes/chakra/menu.ts +124 -0
  177. package/src/theme/recipes/chakra/native-select.ts +140 -0
  178. package/src/theme/recipes/chakra/number-input.ts +115 -0
  179. package/src/theme/recipes/chakra/pin-input.ts +27 -0
  180. package/src/theme/recipes/chakra/popover.ts +86 -0
  181. package/src/theme/recipes/chakra/progress-circle.ts +94 -0
  182. package/src/theme/recipes/chakra/progress.ts +127 -0
  183. package/src/theme/recipes/chakra/radio-card.ts +220 -0
  184. package/src/theme/recipes/chakra/radio-group.ts +72 -0
  185. package/src/theme/recipes/chakra/radiomark.ts +107 -0
  186. package/src/theme/recipes/chakra/rating-group.ts +94 -0
  187. package/src/theme/recipes/chakra/segment-group.ts +117 -0
  188. package/src/theme/recipes/chakra/select.ts +282 -0
  189. package/src/theme/recipes/chakra/separator.ts +51 -0
  190. package/src/theme/recipes/chakra/skeleton.ts +53 -0
  191. package/src/theme/recipes/chakra/skip-nav-link.ts +34 -0
  192. package/src/theme/recipes/chakra/slider.ts +178 -0
  193. package/src/theme/recipes/chakra/spinner.ts +32 -0
  194. package/src/theme/recipes/chakra/stat.ts +79 -0
  195. package/src/theme/recipes/chakra/status.ts +48 -0
  196. package/src/theme/recipes/chakra/steps.ts +218 -0
  197. package/src/theme/recipes/chakra/switch.ts +167 -0
  198. package/src/theme/recipes/chakra/table.ts +172 -0
  199. package/src/theme/recipes/chakra/tabs.ts +280 -0
  200. package/src/theme/recipes/chakra/tag.ts +131 -0
  201. package/src/theme/recipes/chakra/textarea.ts +88 -0
  202. package/src/theme/recipes/chakra/timeline.ts +138 -0
  203. package/src/theme/recipes/chakra/toast.ts +96 -0
  204. package/src/theme/recipes/chakra/tooltip.ts +40 -0
  205. package/src/theme/recipes.ts +46 -0
  206. package/src/theme/semantic-tokens/colors.ts +403 -0
  207. package/src/theme/semantic-tokens/radii.ts +7 -0
  208. package/src/theme/semantic-tokens/shadows.ts +52 -0
  209. package/src/theme/slot-recipes.ts +104 -0
  210. package/src/theme/text-styles.ts +39 -0
  211. package/src/theme/tokens/animations.ts +8 -0
  212. package/src/theme/tokens/aspect-ratios.ts +10 -0
  213. package/src/theme/tokens/blurs.ts +12 -0
  214. package/src/theme/tokens/borders.ts +9 -0
  215. package/src/theme/tokens/colors.ts +177 -0
  216. package/src/theme/tokens/cursor.ts +12 -0
  217. package/src/theme/tokens/durations.ts +11 -0
  218. package/src/theme/tokens/easings.ts +10 -0
  219. package/src/theme/tokens/font-sizes.ts +20 -0
  220. package/src/theme/tokens/font-weights.ts +13 -0
  221. package/src/theme/tokens/fonts.ts +15 -0
  222. package/src/theme/tokens/keyframes.ts +173 -0
  223. package/src/theme/tokens/letter-spacing.ts +9 -0
  224. package/src/theme/tokens/line-heights.ts +19 -0
  225. package/src/theme/tokens/radius.ts +18 -0
  226. package/src/theme/tokens/sizes.ts +71 -0
  227. package/src/theme/tokens/spacing.ts +38 -0
  228. package/src/theme/tokens/z-indices.ts +34 -0
  229. package/src/theme/utils.ts +46 -0
  230. package/dist/index.d.mts +0 -8
  231. package/dist/index.mjs +0 -11
  232. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,182 @@
1
+ import { defineRecipe } from '@chakra-ui/react'
2
+
3
+ export const buttonRecipe = defineRecipe({
4
+ className: 'chakra-button',
5
+ base: {
6
+ display: 'inline-flex',
7
+ appearance: 'none',
8
+ alignItems: 'center',
9
+ justifyContent: 'center',
10
+ userSelect: 'none',
11
+ position: 'relative',
12
+ whiteSpace: 'nowrap',
13
+ verticalAlign: 'middle',
14
+ cursor: 'pointer',
15
+ flexShrink: '0',
16
+ outline: '0',
17
+ lineHeight: '1.2',
18
+ isolation: 'isolate',
19
+ fontWeight: 'medium',
20
+ transitionProperty: 'common',
21
+ transitionDuration: 'moderate',
22
+ focusVisibleRing: 'outside',
23
+ _disabled: {
24
+ layerStyle: 'disabled',
25
+ },
26
+ _icon: {
27
+ fontSize: '1em',
28
+ flexShrink: 0,
29
+ },
30
+ },
31
+
32
+ variants: {
33
+ size: {
34
+ xs: {
35
+ gap: '1',
36
+ h: '6',
37
+ minW: '6',
38
+ textStyle: 'xs',
39
+ borderRadius: 'sm',
40
+ px: '2',
41
+ },
42
+ sm: {
43
+ gap: '2',
44
+ h: '7',
45
+ minW: '8',
46
+ textStyle: 'sm',
47
+ borderRadius: 'md',
48
+ px: '3',
49
+ },
50
+ md: {
51
+ gap: '2',
52
+ h: '8',
53
+ minW: '8',
54
+ borderRadius: 'md',
55
+ textStyle: 'sm',
56
+ px: '4',
57
+ },
58
+ lg: {
59
+ gap: '3',
60
+ h: '10',
61
+ minW: '10',
62
+ borderRadius: 'lg',
63
+ textStyle: 'md',
64
+ px: '5',
65
+ },
66
+ xl: {
67
+ gap: '3',
68
+ h: '12',
69
+ minW: '12',
70
+ borderRadius: 'lg',
71
+ textStyle: 'lg',
72
+ px: '6',
73
+ },
74
+ },
75
+
76
+ variant: {
77
+ solid: {
78
+ bg: 'colorPalette.solid',
79
+ boxShadow: 'sm',
80
+ color: 'colorPalette.contrast',
81
+ _hover: {
82
+ bg: 'colorPalette.solid/90',
83
+ },
84
+ _expanded: {
85
+ bg: 'colorPalette.solid/90',
86
+ },
87
+ },
88
+
89
+ subtle: {
90
+ bg: 'colorPalette.muted',
91
+ color: 'colorPalette.fg',
92
+ _hover: {
93
+ bg: 'colorPalette.subtle',
94
+ },
95
+ _expanded: {
96
+ bg: 'colorPalette.subtle',
97
+ },
98
+ },
99
+
100
+ glass: {
101
+ bg: 'colorPalette.solid',
102
+ color: 'colorPalette.contrast',
103
+ '--btn-shadow': 'shadows.sm',
104
+ boxShadow:
105
+ '0 0 0 1px rgba(0,0,0,0.4) inset, 0px 2px 0px 0px rgba(255,255,255,0.2) inset, var(--btn-shadow)',
106
+ textShadow: '0 1px 2px rgba(0,0,0,0.3)',
107
+ _after: {
108
+ content: '""',
109
+ position: 'absolute',
110
+ top: '0',
111
+ left: '0',
112
+ right: '0',
113
+ bottom: '0',
114
+ background: 'linear-gradient(180deg, white 40%, rgba(0,0,0,0.2))',
115
+ opacity: 0.2,
116
+ transitionProperty: 'opacity',
117
+ transitionDuration: 'moderate',
118
+ pointerEvents: 'none',
119
+ },
120
+ _hover: {
121
+ bg: 'colorPalette.solid',
122
+ _after: {
123
+ opacity: 0.24,
124
+ },
125
+ },
126
+ _expanded: {
127
+ bg: 'colorPalette.solid',
128
+ _after: {
129
+ opacity: 0.24,
130
+ },
131
+ },
132
+ },
133
+
134
+ surface: {
135
+ bg: 'colorPalette.surface',
136
+ borderWidth: '0.5px',
137
+ borderColor: 'colorPalette.emphasized',
138
+ color: 'colorPalette.fg',
139
+ shadow: 'sm',
140
+ shadowColor: 'colorPalette.emphasized',
141
+ _hover: {
142
+ bg: 'colorPalette.muted',
143
+ },
144
+ _expanded: {
145
+ bg: 'colorPalette.muted',
146
+ },
147
+ },
148
+
149
+ outline: {
150
+ borderWidth: '0.5px',
151
+ borderColor: 'colorPalette.emphasized',
152
+ color: 'colorPalette.fg',
153
+ _hover: {
154
+ bg: 'colorPalette.muted',
155
+ },
156
+ _expanded: {
157
+ bg: 'colorPalette.muted',
158
+ },
159
+ },
160
+
161
+ ghost: {
162
+ color: 'colorPalette.fg',
163
+ _hover: {
164
+ bg: 'colorPalette.muted',
165
+ },
166
+ _expanded: {
167
+ bg: 'colorPalette.muted',
168
+ },
169
+ },
170
+
171
+ plain: {
172
+ color: 'colorPalette.fg',
173
+ },
174
+ },
175
+ },
176
+
177
+ defaultVariants: {
178
+ size: 'md',
179
+ variant: 'solid',
180
+ colorPalette: 'gray',
181
+ },
182
+ })
@@ -0,0 +1,99 @@
1
+ import React from 'react'
2
+
3
+ import { Box, HStack, Stack } from '@chakra-ui/react'
4
+
5
+ import { Button } from './button.tsx'
6
+
7
+ export default {
8
+ title: 'Components/Button',
9
+ component: Button,
10
+ }
11
+
12
+ export const Default = {
13
+ args: {
14
+ children: 'Default button',
15
+ },
16
+ }
17
+
18
+ export const Variants = {
19
+ render: () => (
20
+ <Stack gap="4">
21
+ <HStack>
22
+ <Button variant="glass" colorPalette="indigo">
23
+ Primary
24
+ </Button>
25
+ <Button variant="surface">Secondary</Button>
26
+ </HStack>
27
+ <HStack>
28
+ <Button variant="solid">Solid</Button>
29
+ <Button variant="glass">Glass</Button>
30
+ <Button variant="surface">Surface</Button>
31
+ <Button variant="outline">Outline</Button>
32
+ <Button variant="subtle">Subtle</Button>
33
+ <Button variant="ghost">Ghost</Button>
34
+ </HStack>
35
+ <HStack>
36
+ <Button variant="solid" colorPalette="neutral">
37
+ Solid
38
+ </Button>
39
+ <Button variant="glass" colorPalette="neutral">
40
+ Glass
41
+ </Button>
42
+ <Button variant="surface" colorPalette="neutral">
43
+ Surface
44
+ </Button>
45
+ <Button variant="outline" colorPalette="neutral">
46
+ Outline
47
+ </Button>
48
+ <Button variant="subtle" colorPalette="neutral">
49
+ Subtle
50
+ </Button>
51
+ <Button variant="ghost" colorPalette="neutral">
52
+ Ghost
53
+ </Button>
54
+ </HStack>
55
+ <HStack>
56
+ <Button variant="solid" colorPalette="blue">
57
+ Solid
58
+ </Button>
59
+ <Button variant="glass" colorPalette="blue">
60
+ Glass
61
+ </Button>
62
+ <Button variant="surface" colorPalette="blue">
63
+ Surface
64
+ </Button>
65
+ <Button variant="outline" colorPalette="blue">
66
+ Outline
67
+ </Button>
68
+ <Button variant="subtle" colorPalette="blue">
69
+ Subtle
70
+ </Button>
71
+ <Button variant="ghost" colorPalette="blue">
72
+ Ghost
73
+ </Button>
74
+ </HStack>
75
+ </Stack>
76
+ ),
77
+ }
78
+
79
+ export const Sizes = {
80
+ render: () => (
81
+ <HStack>
82
+ <Button size="xs" variant="glass">
83
+ XSmall
84
+ </Button>
85
+ <Button size="sm" variant="glass">
86
+ Small
87
+ </Button>
88
+ <Button size="md" variant="glass">
89
+ Medium
90
+ </Button>
91
+ <Button size="lg" variant="glass">
92
+ Large
93
+ </Button>
94
+ <Button size="xl" variant="glass">
95
+ XLarge
96
+ </Button>
97
+ </HStack>
98
+ ),
99
+ }
@@ -0,0 +1,55 @@
1
+ import { forwardRef } from 'react'
2
+
3
+ import type { ButtonProps as ButtonPrimitiveProps } from '@chakra-ui/react'
4
+ import {
5
+ AbsoluteCenter,
6
+ Button as ButtonPrimitive,
7
+ Span,
8
+ Spinner,
9
+ } from '@chakra-ui/react'
10
+
11
+ interface ButtonLoadingProps {
12
+ loading?: boolean
13
+ loadingText?: React.ReactNode
14
+ }
15
+
16
+ export interface ButtonProps extends ButtonPrimitiveProps, ButtonLoadingProps {}
17
+
18
+ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
19
+ function Button(props, ref) {
20
+ const {
21
+ loading,
22
+ disabled,
23
+ loadingText,
24
+ children,
25
+ variant = 'glass',
26
+ colorPalette = variant === 'glass' ? 'accent' : 'gray',
27
+ ...rest
28
+ } = props
29
+ return (
30
+ <ButtonPrimitive
31
+ colorPalette={colorPalette}
32
+ disabled={loading || disabled}
33
+ variant={variant as any}
34
+ ref={ref}
35
+ {...rest}
36
+ >
37
+ {loading && !loadingText ? (
38
+ <>
39
+ <AbsoluteCenter display="inline-flex">
40
+ <Spinner size="inherit" color="inherit" />
41
+ </AbsoluteCenter>
42
+ <Span opacity={0}>{children}</Span>
43
+ </>
44
+ ) : loading && loadingText ? (
45
+ <>
46
+ <Spinner size="inherit" color="inherit" />
47
+ {loadingText}
48
+ </>
49
+ ) : (
50
+ children
51
+ )}
52
+ </ButtonPrimitive>
53
+ )
54
+ },
55
+ )
@@ -0,0 +1,2 @@
1
+ export { Button } from './button.tsx'
2
+ export type { ButtonProps } from './button.tsx'
@@ -0,0 +1,26 @@
1
+ import { forwardRef } from 'react'
2
+
3
+ import { Checkbox as ChakraCheckbox } from '@chakra-ui/react'
4
+
5
+ export interface CheckboxProps extends ChakraCheckbox.RootProps {
6
+ icon?: React.ReactNode
7
+ inputProps?: React.InputHTMLAttributes<HTMLInputElement>
8
+ rootRef?: React.Ref<HTMLLabelElement>
9
+ }
10
+
11
+ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
12
+ function Checkbox(props, ref) {
13
+ const { icon, children, inputProps, rootRef, ...rest } = props
14
+ return (
15
+ <ChakraCheckbox.Root ref={rootRef} {...rest}>
16
+ <ChakraCheckbox.HiddenInput ref={ref} {...inputProps} />
17
+ <ChakraCheckbox.Control>
18
+ {icon || <ChakraCheckbox.Indicator />}
19
+ </ChakraCheckbox.Control>
20
+ {children != null && (
21
+ <ChakraCheckbox.Label>{children}</ChakraCheckbox.Label>
22
+ )}
23
+ </ChakraCheckbox.Root>
24
+ )
25
+ },
26
+ )
@@ -0,0 +1,2 @@
1
+ export { Checkbox } from './checkbox.tsx'
2
+ export type { CheckboxProps } from './checkbox.tsx'
@@ -0,0 +1,57 @@
1
+ import { CheckboxCard as ChakraCheckboxCard } from "@chakra-ui/react"
2
+ import { Fragment, forwardRef } from "react"
3
+
4
+ export interface CheckboxCardProps extends ChakraCheckboxCard.RootProps {
5
+ icon?: React.ReactElement
6
+ label?: React.ReactNode
7
+ description?: React.ReactNode
8
+ addon?: React.ReactNode
9
+ indicator?: React.ReactNode | null
10
+ indicatorPlacement?: "start" | "end" | "inside"
11
+ inputProps?: React.InputHTMLAttributes<HTMLInputElement>
12
+ }
13
+
14
+ export const CheckboxCard = forwardRef<HTMLInputElement, CheckboxCardProps>(
15
+ function CheckboxCard(props, ref) {
16
+ const {
17
+ inputProps,
18
+ label,
19
+ description,
20
+ icon,
21
+ addon,
22
+ indicator = <ChakraCheckboxCard.Indicator />,
23
+ indicatorPlacement = "end",
24
+ ...rest
25
+ } = props
26
+
27
+ const hasContent = label || description || icon
28
+ const ContentWrapper = indicator ? ChakraCheckboxCard.Content : Fragment
29
+
30
+ return (
31
+ <ChakraCheckboxCard.Root {...rest}>
32
+ <ChakraCheckboxCard.HiddenInput ref={ref} {...inputProps} />
33
+ <ChakraCheckboxCard.Control>
34
+ {indicatorPlacement === "start" && indicator}
35
+ {hasContent && (
36
+ <ContentWrapper>
37
+ {icon}
38
+ {label && (
39
+ <ChakraCheckboxCard.Label>{label}</ChakraCheckboxCard.Label>
40
+ )}
41
+ {description && (
42
+ <ChakraCheckboxCard.Description>
43
+ {description}
44
+ </ChakraCheckboxCard.Description>
45
+ )}
46
+ {indicatorPlacement === "inside" && indicator}
47
+ </ContentWrapper>
48
+ )}
49
+ {indicatorPlacement === "end" && indicator}
50
+ </ChakraCheckboxCard.Control>
51
+ {addon && <ChakraCheckboxCard.Addon>{addon}</ChakraCheckboxCard.Addon>}
52
+ </ChakraCheckboxCard.Root>
53
+ )
54
+ },
55
+ )
56
+
57
+ export const CheckboxCardIndicator = ChakraCheckboxCard.Indicator
@@ -0,0 +1,25 @@
1
+ import { Checkbox as ChakraCheckbox } from "@chakra-ui/react"
2
+ import { forwardRef } from "react"
3
+
4
+ export interface CheckboxProps extends ChakraCheckbox.RootProps {
5
+ icon?: React.ReactNode
6
+ inputProps?: React.InputHTMLAttributes<HTMLInputElement>
7
+ rootRef?: React.Ref<HTMLLabelElement>
8
+ }
9
+
10
+ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
11
+ function Checkbox(props, ref) {
12
+ const { icon, children, inputProps, rootRef, ...rest } = props
13
+ return (
14
+ <ChakraCheckbox.Root ref={rootRef} {...rest}>
15
+ <ChakraCheckbox.HiddenInput ref={ref} {...inputProps} />
16
+ <ChakraCheckbox.Control>
17
+ {icon || <ChakraCheckbox.Indicator />}
18
+ </ChakraCheckbox.Control>
19
+ {children != null && (
20
+ <ChakraCheckbox.Label>{children}</ChakraCheckbox.Label>
21
+ )}
22
+ </ChakraCheckbox.Root>
23
+ )
24
+ },
25
+ )
@@ -0,0 +1,107 @@
1
+ import type { ButtonProps, InputProps } from "@chakra-ui/react"
2
+ import {
3
+ Button,
4
+ Clipboard as ChakraClipboard,
5
+ IconButton,
6
+ Input,
7
+ } from "@chakra-ui/react"
8
+ import { forwardRef } from "react"
9
+ import { LuCheck, LuClipboard, LuLink } from "react-icons/lu"
10
+
11
+ const ClipboardIcon = forwardRef<
12
+ HTMLDivElement,
13
+ ChakraClipboard.IndicatorProps
14
+ >(function ClipboardIcon(props, ref) {
15
+ return (
16
+ <ChakraClipboard.Indicator copied={<LuCheck />} {...props} ref={ref}>
17
+ <LuClipboard />
18
+ </ChakraClipboard.Indicator>
19
+ )
20
+ })
21
+
22
+ const ClipboardCopyText = forwardRef<
23
+ HTMLDivElement,
24
+ ChakraClipboard.IndicatorProps
25
+ >(function ClipboardCopyText(props, ref) {
26
+ return (
27
+ <ChakraClipboard.Indicator copied="Copied" {...props} ref={ref}>
28
+ Copy
29
+ </ChakraClipboard.Indicator>
30
+ )
31
+ })
32
+
33
+ export const ClipboardLabel = forwardRef<
34
+ HTMLLabelElement,
35
+ ChakraClipboard.LabelProps
36
+ >(function ClipboardLabel(props, ref) {
37
+ return (
38
+ <ChakraClipboard.Label
39
+ textStyle="sm"
40
+ fontWeight="medium"
41
+ display="inline-block"
42
+ mb="1"
43
+ {...props}
44
+ ref={ref}
45
+ />
46
+ )
47
+ })
48
+
49
+ export const ClipboardButton = forwardRef<HTMLButtonElement, ButtonProps>(
50
+ function ClipboardButton(props, ref) {
51
+ return (
52
+ <ChakraClipboard.Trigger asChild>
53
+ <Button ref={ref} size="sm" variant="surface" {...props}>
54
+ <ClipboardIcon />
55
+ <ClipboardCopyText />
56
+ </Button>
57
+ </ChakraClipboard.Trigger>
58
+ )
59
+ },
60
+ )
61
+
62
+ export const ClipboardLink = forwardRef<HTMLButtonElement, ButtonProps>(
63
+ function ClipboardLink(props, ref) {
64
+ return (
65
+ <ChakraClipboard.Trigger asChild>
66
+ <Button
67
+ unstyled
68
+ variant="plain"
69
+ size="xs"
70
+ display="inline-flex"
71
+ alignItems="center"
72
+ gap="2"
73
+ ref={ref}
74
+ {...props}
75
+ >
76
+ <LuLink />
77
+ <ClipboardCopyText />
78
+ </Button>
79
+ </ChakraClipboard.Trigger>
80
+ )
81
+ },
82
+ )
83
+
84
+ export const ClipboardIconButton = forwardRef<HTMLButtonElement, ButtonProps>(
85
+ function ClipboardIconButton(props, ref) {
86
+ return (
87
+ <ChakraClipboard.Trigger asChild>
88
+ <IconButton ref={ref} size="xs" variant="subtle" {...props}>
89
+ <ClipboardIcon />
90
+ <ClipboardCopyText srOnly />
91
+ </IconButton>
92
+ </ChakraClipboard.Trigger>
93
+ )
94
+ },
95
+ )
96
+
97
+ export const ClipboardInput = forwardRef<HTMLInputElement, InputProps>(
98
+ function ClipboardInputElement(props, ref) {
99
+ return (
100
+ <ChakraClipboard.Input asChild>
101
+ <Input ref={ref} {...props} />
102
+ </ChakraClipboard.Input>
103
+ )
104
+ },
105
+ )
106
+
107
+ export const ClipboardRoot = ChakraClipboard.Root
@@ -0,0 +1,12 @@
1
+ import React from 'react'
2
+
3
+ import { CloseButton } from './close-button.tsx'
4
+
5
+ export default {
6
+ title: 'Components/CloseButton',
7
+ component: CloseButton,
8
+ }
9
+
10
+ export const Default = {
11
+ args: {},
12
+ }
@@ -0,0 +1,18 @@
1
+ import { forwardRef } from 'react'
2
+
3
+ import type { ButtonProps } from '@chakra-ui/react'
4
+ import { IconButton as ChakraIconButton } from '@chakra-ui/react'
5
+
6
+ import { CloseIcon } from '../icons/icons.tsx'
7
+
8
+ export interface CloseButtonProps extends ButtonProps {}
9
+
10
+ export const CloseButton = forwardRef<HTMLButtonElement, CloseButtonProps>(
11
+ function CloseButton(props, ref) {
12
+ return (
13
+ <ChakraIconButton variant="ghost" aria-label="Close" ref={ref} {...props}>
14
+ {props.children ?? <CloseIcon />}
15
+ </ChakraIconButton>
16
+ )
17
+ },
18
+ )
@@ -0,0 +1,2 @@
1
+ export { CloseButton } from './close-button.tsx'
2
+ export type { CloseButtonProps } from './close-button.tsx'
@@ -0,0 +1,65 @@
1
+ "use client"
2
+
3
+ import type { IconButtonProps } from "@chakra-ui/react"
4
+ import { ClientOnly, IconButton, Skeleton } from "@chakra-ui/react"
5
+ import { ThemeProvider, useTheme } from "next-themes"
6
+ import type { ThemeProviderProps } from "next-themes/dist/types"
7
+ import { forwardRef } from "react"
8
+ import { LuMoon, LuSun } from "react-icons/lu"
9
+
10
+ export function ColorModeProvider(props: ThemeProviderProps) {
11
+ return (
12
+ <ThemeProvider attribute="class" disableTransitionOnChange {...props} />
13
+ )
14
+ }
15
+
16
+ export function useColorMode() {
17
+ const { resolvedTheme, setTheme } = useTheme()
18
+ const toggleColorMode = () => {
19
+ setTheme(resolvedTheme === "light" ? "dark" : "light")
20
+ }
21
+ return {
22
+ colorMode: resolvedTheme,
23
+ setColorMode: setTheme,
24
+ toggleColorMode,
25
+ }
26
+ }
27
+
28
+ export function useColorModeValue<T>(light: T, dark: T) {
29
+ const { colorMode } = useColorMode()
30
+ return colorMode === "light" ? light : dark
31
+ }
32
+
33
+ export function ColorModeIcon() {
34
+ const { colorMode } = useColorMode()
35
+ return colorMode === "light" ? <LuSun /> : <LuMoon />
36
+ }
37
+
38
+ interface ColorModeButtonProps extends Omit<IconButtonProps, "aria-label"> {}
39
+
40
+ export const ColorModeButton = forwardRef<
41
+ HTMLButtonElement,
42
+ ColorModeButtonProps
43
+ >(function ColorModeButton(props, ref) {
44
+ const { toggleColorMode } = useColorMode()
45
+ return (
46
+ <ClientOnly fallback={<Skeleton boxSize="8" />}>
47
+ <IconButton
48
+ onClick={toggleColorMode}
49
+ variant="ghost"
50
+ aria-label="Toggle color mode"
51
+ size="sm"
52
+ ref={ref}
53
+ {...props}
54
+ css={{
55
+ _icon: {
56
+ width: "5",
57
+ height: "5",
58
+ },
59
+ }}
60
+ >
61
+ <ColorModeIcon />
62
+ </IconButton>
63
+ </ClientOnly>
64
+ )
65
+ })
@@ -0,0 +1,17 @@
1
+ import { defineRecipe } from '@chakra-ui/react'
2
+
3
+ export const commandRecipe = defineRecipe({
4
+ className: 'sui-command',
5
+ base: {
6
+ display: 'inline-flex',
7
+ gap: 1,
8
+ '[role=tooltip] > &': {
9
+ ms: 1,
10
+ _before: {
11
+ content: '"•"',
12
+ me: 1,
13
+ fontSize: 'xs',
14
+ },
15
+ },
16
+ },
17
+ })