@saas-ui/react 2.11.2 → 3.0.0-alpha.1

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 (343) hide show
  1. package/CHANGELOG.md +13 -148
  2. package/dist/chunk-32JGENDB.js +19 -0
  3. package/dist/chunk-FZW2DYK3.js +19 -0
  4. package/dist/chunk-KHRLZUV4.js +35 -0
  5. package/dist/chunk-KTLWEUNW.js +1 -0
  6. package/dist/chunk-PKI6YH2V.js +31 -0
  7. package/dist/chunk-RTMS5TJN.js +10 -0
  8. package/dist/chunk-VBIVLREP.js +45 -0
  9. package/dist/chunk-VDXTEASE.js +117 -0
  10. package/dist/components/app-shell/index.cjs +68 -0
  11. package/dist/components/app-shell/index.d.cts +30 -0
  12. package/dist/components/app-shell/index.d.ts +30 -0
  13. package/dist/components/app-shell/index.js +45 -0
  14. package/dist/components/breadcrumbs/index.cjs +60 -0
  15. package/dist/components/breadcrumbs/index.d.cts +18 -0
  16. package/dist/components/breadcrumbs/index.d.ts +18 -0
  17. package/dist/components/breadcrumbs/index.js +37 -0
  18. package/dist/components/button/index.cjs +65 -0
  19. package/dist/components/button/index.d.cts +12 -0
  20. package/dist/components/button/index.d.ts +12 -0
  21. package/dist/components/button/index.js +45 -0
  22. package/dist/components/checkbox/index.cjs +45 -0
  23. package/dist/components/checkbox/index.d.cts +11 -0
  24. package/dist/components/checkbox/index.d.ts +11 -0
  25. package/dist/components/checkbox/index.js +20 -0
  26. package/dist/components/close-button/index.cjs +142 -0
  27. package/dist/components/close-button/index.d.cts +8 -0
  28. package/dist/components/close-button/index.d.ts +8 -0
  29. package/dist/components/close-button/index.js +9 -0
  30. package/dist/components/command/index.cjs +56 -0
  31. package/dist/components/command/index.d.cts +6 -0
  32. package/dist/components/command/index.d.ts +6 -0
  33. package/dist/components/command/index.js +33 -0
  34. package/dist/components/dialog/index.cjs +243 -0
  35. package/dist/components/dialog/index.d.cts +27 -0
  36. package/dist/components/dialog/index.d.ts +27 -0
  37. package/dist/components/dialog/index.js +73 -0
  38. package/dist/components/drawer/index.cjs +237 -0
  39. package/dist/components/drawer/index.d.cts +28 -0
  40. package/dist/components/drawer/index.d.ts +28 -0
  41. package/dist/components/drawer/index.js +65 -0
  42. package/dist/components/icon-badge/index.cjs +70 -0
  43. package/dist/components/icon-badge/index.d.cts +16 -0
  44. package/dist/components/icon-badge/index.d.ts +16 -0
  45. package/dist/components/icon-badge/index.js +38 -0
  46. package/dist/components/icons/index.cjs +155 -0
  47. package/dist/components/icons/index.d.cts +19 -0
  48. package/dist/components/icons/index.d.ts +19 -0
  49. package/dist/components/icons/index.js +35 -0
  50. package/dist/components/input-group/index.cjs +56 -0
  51. package/dist/components/input-group/index.d.cts +13 -0
  52. package/dist/components/input-group/index.d.ts +13 -0
  53. package/dist/components/input-group/index.js +8 -0
  54. package/dist/components/link/index.cjs +71 -0
  55. package/dist/components/link/index.d.cts +13 -0
  56. package/dist/components/link/index.d.ts +13 -0
  57. package/dist/components/link/index.js +20 -0
  58. package/dist/components/loading-overlay/index.cjs +1921 -0
  59. package/dist/components/loading-overlay/index.d.cts +13 -0
  60. package/dist/components/loading-overlay/index.d.ts +13 -0
  61. package/dist/components/loading-overlay/index.js +1878 -0
  62. package/dist/components/navbar/index.cjs +65 -0
  63. package/dist/components/navbar/index.d.cts +18 -0
  64. package/dist/components/navbar/index.d.ts +18 -0
  65. package/dist/components/navbar/index.js +42 -0
  66. package/dist/components/number-input/index.cjs +82 -0
  67. package/dist/components/number-input/index.d.cts +13 -0
  68. package/dist/components/number-input/index.d.ts +13 -0
  69. package/dist/components/number-input/index.js +32 -0
  70. package/dist/components/password-input/index.cjs +284 -0
  71. package/dist/components/password-input/index.d.cts +18 -0
  72. package/dist/components/password-input/index.d.ts +18 -0
  73. package/dist/components/password-input/index.js +231 -0
  74. package/dist/components/persona/index.cjs +181 -0
  75. package/dist/components/persona/index.d.cts +93 -0
  76. package/dist/components/persona/index.d.ts +93 -0
  77. package/dist/components/persona/index.js +149 -0
  78. package/dist/components/pin-input/index.cjs +51 -0
  79. package/dist/components/pin-input/index.d.cts +12 -0
  80. package/dist/components/pin-input/index.d.ts +12 -0
  81. package/dist/components/pin-input/index.js +26 -0
  82. package/dist/components/radio/index.cjs +48 -0
  83. package/dist/components/radio/index.d.cts +12 -0
  84. package/dist/components/radio/index.d.ts +12 -0
  85. package/dist/components/radio/index.js +22 -0
  86. package/dist/components/search-input/index.cjs +244 -0
  87. package/dist/components/search-input/index.d.cts +15 -0
  88. package/dist/components/search-input/index.d.ts +15 -0
  89. package/dist/components/search-input/index.js +120 -0
  90. package/dist/components/select/index.cjs +233 -0
  91. package/dist/components/select/index.d.cts +32 -0
  92. package/dist/components/select/index.d.ts +32 -0
  93. package/dist/components/select/index.js +100 -0
  94. package/dist/components/sidebar/index.cjs +134 -0
  95. package/dist/components/sidebar/index.d.cts +85 -0
  96. package/dist/components/sidebar/index.d.ts +85 -0
  97. package/dist/components/sidebar/index.js +108 -0
  98. package/dist/components/spinner/index.cjs +44 -0
  99. package/dist/components/spinner/index.d.cts +10 -0
  100. package/dist/components/spinner/index.d.ts +10 -0
  101. package/dist/components/spinner/index.js +8 -0
  102. package/dist/components/steps/index.cjs +191 -0
  103. package/dist/components/steps/index.d.cts +31 -0
  104. package/dist/components/steps/index.d.ts +31 -0
  105. package/dist/components/steps/index.js +71 -0
  106. package/dist/components/switch/index.cjs +48 -0
  107. package/dist/components/switch/index.d.cts +18 -0
  108. package/dist/components/switch/index.d.ts +18 -0
  109. package/dist/components/switch/index.js +23 -0
  110. package/dist/index.cjs +8460 -0
  111. package/dist/index.d.cts +26 -0
  112. package/dist/index.d.ts +25 -7
  113. package/dist/index.js +8395 -36
  114. package/package.json +26 -22
  115. package/src/components/app-shell/app-shell.recipe.ts +52 -0
  116. package/src/components/app-shell/app-shell.stories.tsx +51 -0
  117. package/src/components/app-shell/app-shell.tsx +94 -0
  118. package/src/components/app-shell/index.ts +3 -0
  119. package/src/components/breadcrumbs/breadcrumb.stories.tsx +17 -0
  120. package/src/components/breadcrumbs/breadcrumb.tsx +36 -0
  121. package/src/components/breadcrumbs/index.ts +1 -0
  122. package/src/components/breadcrumbs/namespace.ts +8 -0
  123. package/src/components/button/button.recipe.ts +182 -0
  124. package/src/components/button/button.stories.tsx +99 -0
  125. package/src/components/button/button.tsx +55 -0
  126. package/src/components/button/index.ts +2 -0
  127. package/src/components/checkbox/checkbox.tsx +26 -0
  128. package/src/components/checkbox/index.ts +2 -0
  129. package/src/components/close-button/close-button.stories.tsx +12 -0
  130. package/src/components/close-button/close-button.tsx +18 -0
  131. package/src/components/close-button/index.ts +2 -0
  132. package/src/components/command/command.recipe.ts +17 -0
  133. package/src/components/command/command.stories.tsx +47 -0
  134. package/src/components/command/command.tsx +50 -0
  135. package/src/components/command/index.ts +1 -0
  136. package/src/components/dialog/dialog.tsx +67 -0
  137. package/src/components/dialog/index.ts +1 -0
  138. package/src/components/dialog/namespace.ts +18 -0
  139. package/src/components/drawer/drawer.tsx +57 -0
  140. package/src/components/drawer/index.ts +3 -0
  141. package/src/components/drawer/namespace.ts +19 -0
  142. package/src/components/grid-list/grid-list.recipe.ts +113 -0
  143. package/src/components/icon-badge/icon-badge.recipe.ts +57 -0
  144. package/src/components/icon-badge/icon-badge.stories.tsx +38 -0
  145. package/src/components/icon-badge/icon-badge.tsx +59 -0
  146. package/src/components/icon-badge/index.ts +2 -0
  147. package/src/components/icons/create-icon.tsx +41 -0
  148. package/src/components/icons/icons.tsx +119 -0
  149. package/src/components/icons/index.ts +1 -0
  150. package/src/components/input-group/index.ts +1 -0
  151. package/src/components/input-group/input-group.tsx +46 -0
  152. package/src/components/link/index.ts +2 -0
  153. package/src/components/link/link.stories.tsx +17 -0
  154. package/src/components/link/link.test.tsx +33 -0
  155. package/src/components/link/link.tsx +27 -0
  156. package/src/components/loading-overlay/index.ts +1 -0
  157. package/src/components/loading-overlay/loading-overlay.recipe.ts +61 -0
  158. package/src/components/loading-overlay/loading-overlay.stories.tsx +68 -0
  159. package/src/components/loading-overlay/loading-overlay.tsx +54 -0
  160. package/src/components/loading-overlay/namespace.ts +7 -0
  161. package/src/components/navbar/index.ts +1 -0
  162. package/src/components/navbar/namespace.ts +9 -0
  163. package/src/components/navbar/navbar.recipe.ts +109 -0
  164. package/src/components/navbar/navbar.stories.tsx +435 -0
  165. package/src/components/navbar/navbar.test.tsx +49 -0
  166. package/src/components/navbar/navbar.tsx +39 -0
  167. package/src/components/number-input/index.ts +2 -0
  168. package/src/components/number-input/number-input.tsx +41 -0
  169. package/src/components/password-input/index.ts +2 -0
  170. package/src/components/password-input/password-input.tsx +93 -0
  171. package/src/components/persona/index.ts +2 -0
  172. package/src/components/persona/namespace.ts +18 -0
  173. package/src/components/persona/persona-primitive.tsx +220 -0
  174. package/src/components/persona/persona.recipe.ts +94 -0
  175. package/src/components/persona/persona.stories.tsx +101 -0
  176. package/src/components/persona/persona.tsx +142 -0
  177. package/src/components/pin-input/index.ts +2 -0
  178. package/src/components/pin-input/pin-input.tsx +36 -0
  179. package/src/components/radio/index.ts +2 -0
  180. package/src/components/radio/radio.tsx +27 -0
  181. package/src/components/search-input/index.ts +2 -0
  182. package/src/components/search-input/search-input.stories.tsx +63 -0
  183. package/src/components/search-input/search-input.tsx +134 -0
  184. package/src/components/select/index.ts +1 -0
  185. package/src/components/select/namespace.ts +18 -0
  186. package/src/components/select/select.tsx +135 -0
  187. package/src/components/sidebar/index.ts +7 -0
  188. package/src/components/sidebar/namespace.ts +27 -0
  189. package/src/components/sidebar/sidebar-item.recipe.ts +65 -0
  190. package/src/components/sidebar/sidebar.recipe.ts +237 -0
  191. package/src/components/sidebar/sidebar.stories.tsx +903 -0
  192. package/src/components/sidebar/sidebar.tsx +208 -0
  193. package/src/components/spinner/index.ts +2 -0
  194. package/src/components/spinner/spinner.stories.tsx +19 -0
  195. package/src/components/spinner/spinner.tsx +21 -0
  196. package/src/components/steps/index.ts +1 -0
  197. package/src/components/steps/namespace.ts +16 -0
  198. package/src/components/steps/steps.tsx +82 -0
  199. package/src/components/switch/index.ts +3 -0
  200. package/src/components/switch/switch.tsx +39 -0
  201. package/src/compositions/accordion.tsx +47 -0
  202. package/src/compositions/action-bar.tsx +40 -0
  203. package/src/compositions/alert.tsx +51 -0
  204. package/src/compositions/avatar.tsx +74 -0
  205. package/src/compositions/blockquote.tsx +31 -0
  206. package/src/compositions/checkbox-card.tsx +57 -0
  207. package/src/compositions/checkbox.tsx +25 -0
  208. package/src/compositions/clipboard.tsx +107 -0
  209. package/src/compositions/color-mode.tsx +65 -0
  210. package/src/compositions/data-list.tsx +37 -0
  211. package/src/compositions/empty-state.tsx +34 -0
  212. package/src/compositions/field.tsx +33 -0
  213. package/src/compositions/file-button.tsx +166 -0
  214. package/src/compositions/hover-card.tsx +35 -0
  215. package/src/compositions/link-button.tsx +12 -0
  216. package/src/compositions/menu.tsx +108 -0
  217. package/src/compositions/native-select.tsx +57 -0
  218. package/src/compositions/pagination.tsx +207 -0
  219. package/src/compositions/popover.tsx +58 -0
  220. package/src/compositions/progress-circle.tsx +37 -0
  221. package/src/compositions/progress.tsx +40 -0
  222. package/src/compositions/prose.tsx +264 -0
  223. package/src/compositions/provider.tsx +12 -0
  224. package/src/compositions/radio-card.tsx +57 -0
  225. package/src/compositions/radio.tsx +24 -0
  226. package/src/compositions/rating.tsx +27 -0
  227. package/src/compositions/segmented-control.tsx +47 -0
  228. package/src/compositions/skeleton.tsx +44 -0
  229. package/src/compositions/slider.tsx +53 -0
  230. package/src/compositions/stat.tsx +75 -0
  231. package/src/compositions/status.tsx +29 -0
  232. package/src/compositions/stepper-input.tsx +49 -0
  233. package/src/compositions/tag.tsx +39 -0
  234. package/src/compositions/timeline.tsx +17 -0
  235. package/src/compositions/toaster.tsx +43 -0
  236. package/src/compositions/toggle-tip.tsx +62 -0
  237. package/src/compositions/tooltip.tsx +46 -0
  238. package/src/index.ts +6 -7
  239. package/src/preset.ts +9 -0
  240. package/src/provider/index.ts +4 -0
  241. package/src/provider/sui-provider.tsx +34 -0
  242. package/src/provider/use-link.test.tsx +60 -0
  243. package/src/provider/use-link.tsx +13 -0
  244. package/src/styled-system/create-recipe-context.tsx +91 -0
  245. package/src/styled-system/create-slot-recipe-context.tsx +188 -0
  246. package/src/styled-system/empty.ts +7 -0
  247. package/src/styled-system/factory.types.ts +11 -0
  248. package/src/theme/animation-styles.ts +53 -0
  249. package/src/theme/breakpoints.ts +11 -0
  250. package/src/theme/conditions.ts +26 -0
  251. package/src/theme/fluid-font-sizes.ts +65 -0
  252. package/src/theme/global-css.ts +94 -0
  253. package/src/theme/index.ts +72 -0
  254. package/src/theme/layer-styles.ts +116 -0
  255. package/src/theme/recipes/chakra/accordion.ts +145 -0
  256. package/src/theme/recipes/chakra/action-bar.ts +62 -0
  257. package/src/theme/recipes/chakra/alert.ts +157 -0
  258. package/src/theme/recipes/chakra/avatar.ts +141 -0
  259. package/src/theme/recipes/chakra/badge.ts +67 -0
  260. package/src/theme/recipes/chakra/blockquote.ts +83 -0
  261. package/src/theme/recipes/chakra/breadcrumb.ts +94 -0
  262. package/src/theme/recipes/chakra/card.ts +99 -0
  263. package/src/theme/recipes/chakra/checkbox-card.ts +212 -0
  264. package/src/theme/recipes/chakra/checkbox.ts +70 -0
  265. package/src/theme/recipes/chakra/checkmark.ts +83 -0
  266. package/src/theme/recipes/chakra/code.ts +17 -0
  267. package/src/theme/recipes/chakra/collapsible.ts +20 -0
  268. package/src/theme/recipes/chakra/container.ts +26 -0
  269. package/src/theme/recipes/chakra/data-list.ts +80 -0
  270. package/src/theme/recipes/chakra/dialog.ts +225 -0
  271. package/src/theme/recipes/chakra/drawer.ts +201 -0
  272. package/src/theme/recipes/chakra/editable.ts +88 -0
  273. package/src/theme/recipes/chakra/empty-state.ts +88 -0
  274. package/src/theme/recipes/chakra/field.ts +68 -0
  275. package/src/theme/recipes/chakra/fieldset.ts +62 -0
  276. package/src/theme/recipes/chakra/file-upload.ts +96 -0
  277. package/src/theme/recipes/chakra/heading.ts +27 -0
  278. package/src/theme/recipes/chakra/hover-card.ts +68 -0
  279. package/src/theme/recipes/chakra/icon.ts +30 -0
  280. package/src/theme/recipes/chakra/input-addon.ts +40 -0
  281. package/src/theme/recipes/chakra/input.ts +96 -0
  282. package/src/theme/recipes/chakra/kbd.ts +60 -0
  283. package/src/theme/recipes/chakra/link.ts +37 -0
  284. package/src/theme/recipes/chakra/list.ts +67 -0
  285. package/src/theme/recipes/chakra/mark.ts +27 -0
  286. package/src/theme/recipes/chakra/menu.ts +124 -0
  287. package/src/theme/recipes/chakra/native-select.ts +140 -0
  288. package/src/theme/recipes/chakra/number-input.ts +115 -0
  289. package/src/theme/recipes/chakra/pin-input.ts +27 -0
  290. package/src/theme/recipes/chakra/popover.ts +86 -0
  291. package/src/theme/recipes/chakra/progress-circle.ts +94 -0
  292. package/src/theme/recipes/chakra/progress.ts +127 -0
  293. package/src/theme/recipes/chakra/radio-card.ts +220 -0
  294. package/src/theme/recipes/chakra/radio-group.ts +72 -0
  295. package/src/theme/recipes/chakra/radiomark.ts +107 -0
  296. package/src/theme/recipes/chakra/rating-group.ts +94 -0
  297. package/src/theme/recipes/chakra/segment-group.ts +117 -0
  298. package/src/theme/recipes/chakra/select.ts +282 -0
  299. package/src/theme/recipes/chakra/separator.ts +51 -0
  300. package/src/theme/recipes/chakra/skeleton.ts +53 -0
  301. package/src/theme/recipes/chakra/skip-nav-link.ts +34 -0
  302. package/src/theme/recipes/chakra/slider.ts +178 -0
  303. package/src/theme/recipes/chakra/spinner.ts +32 -0
  304. package/src/theme/recipes/chakra/stat.ts +79 -0
  305. package/src/theme/recipes/chakra/status.ts +48 -0
  306. package/src/theme/recipes/chakra/steps.ts +218 -0
  307. package/src/theme/recipes/chakra/switch.ts +167 -0
  308. package/src/theme/recipes/chakra/table.ts +172 -0
  309. package/src/theme/recipes/chakra/tabs.ts +280 -0
  310. package/src/theme/recipes/chakra/tag.ts +131 -0
  311. package/src/theme/recipes/chakra/textarea.ts +88 -0
  312. package/src/theme/recipes/chakra/timeline.ts +138 -0
  313. package/src/theme/recipes/chakra/toast.ts +96 -0
  314. package/src/theme/recipes/chakra/tooltip.ts +40 -0
  315. package/src/theme/recipes.ts +46 -0
  316. package/src/theme/semantic-tokens/colors.ts +403 -0
  317. package/src/theme/semantic-tokens/radii.ts +7 -0
  318. package/src/theme/semantic-tokens/shadows.ts +52 -0
  319. package/src/theme/slot-recipes.ts +104 -0
  320. package/src/theme/text-styles.ts +39 -0
  321. package/src/theme/tokens/animations.ts +8 -0
  322. package/src/theme/tokens/aspect-ratios.ts +10 -0
  323. package/src/theme/tokens/blurs.ts +12 -0
  324. package/src/theme/tokens/borders.ts +9 -0
  325. package/src/theme/tokens/colors.ts +177 -0
  326. package/src/theme/tokens/cursor.ts +12 -0
  327. package/src/theme/tokens/durations.ts +11 -0
  328. package/src/theme/tokens/easings.ts +10 -0
  329. package/src/theme/tokens/font-sizes.ts +20 -0
  330. package/src/theme/tokens/font-weights.ts +13 -0
  331. package/src/theme/tokens/fonts.ts +15 -0
  332. package/src/theme/tokens/keyframes.ts +173 -0
  333. package/src/theme/tokens/letter-spacing.ts +9 -0
  334. package/src/theme/tokens/line-heights.ts +19 -0
  335. package/src/theme/tokens/radius.ts +18 -0
  336. package/src/theme/tokens/sizes.ts +71 -0
  337. package/src/theme/tokens/spacing.ts +38 -0
  338. package/src/theme/tokens/z-indices.ts +34 -0
  339. package/src/theme/utils.ts +46 -0
  340. package/dist/index.d.mts +0 -8
  341. package/dist/index.js.map +0 -1
  342. package/dist/index.mjs +0 -11
  343. package/dist/index.mjs.map +0 -1
@@ -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,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,37 @@
1
+ import { DataList as ChakraDataList, IconButton } from "@chakra-ui/react"
2
+ import { ToggleTip } from "compositions/ui/toggle-tip"
3
+ import { forwardRef } from "react"
4
+ import { HiOutlineInformationCircle } from "react-icons/hi2"
5
+
6
+ export const DataListRoot = ChakraDataList.Root
7
+
8
+ interface ItemProps extends ChakraDataList.ItemProps {
9
+ label: React.ReactNode
10
+ value: React.ReactNode
11
+ info?: React.ReactNode
12
+ grow?: boolean
13
+ }
14
+
15
+ export const DataListItem = forwardRef<HTMLDivElement, ItemProps>(
16
+ function DataListItem(props, ref) {
17
+ const { label, info, value, children, grow, ...rest } = props
18
+ return (
19
+ <ChakraDataList.Item ref={ref} {...rest}>
20
+ <ChakraDataList.ItemLabel flex={grow ? "1" : undefined}>
21
+ {label}
22
+ {info && (
23
+ <ToggleTip content={info}>
24
+ <IconButton variant="ghost" aria-label="info" size="2xs">
25
+ <HiOutlineInformationCircle />
26
+ </IconButton>
27
+ </ToggleTip>
28
+ )}
29
+ </ChakraDataList.ItemLabel>
30
+ <ChakraDataList.ItemValue flex={grow ? "1" : undefined}>
31
+ {value}
32
+ </ChakraDataList.ItemValue>
33
+ {children}
34
+ </ChakraDataList.Item>
35
+ )
36
+ },
37
+ )
@@ -0,0 +1,34 @@
1
+ import { EmptyState as ChakraEmptyState, VStack } from "@chakra-ui/react"
2
+ import { forwardRef } from "react"
3
+
4
+ export interface EmptyStateProps extends ChakraEmptyState.RootProps {
5
+ title: string
6
+ description?: string
7
+ icon?: React.ReactNode
8
+ }
9
+
10
+ export const EmptyState = forwardRef<HTMLDivElement, EmptyStateProps>(
11
+ function EmptyState(props, ref) {
12
+ const { title, description, icon, children, ...rest } = props
13
+ return (
14
+ <ChakraEmptyState.Root ref={ref} {...rest}>
15
+ <ChakraEmptyState.Content>
16
+ {icon && (
17
+ <ChakraEmptyState.Indicator>{icon}</ChakraEmptyState.Indicator>
18
+ )}
19
+ {description ? (
20
+ <VStack textAlign="center">
21
+ <ChakraEmptyState.Title>{title}</ChakraEmptyState.Title>
22
+ <ChakraEmptyState.Description>
23
+ {description}
24
+ </ChakraEmptyState.Description>
25
+ </VStack>
26
+ ) : (
27
+ <ChakraEmptyState.Title>{title}</ChakraEmptyState.Title>
28
+ )}
29
+ {children}
30
+ </ChakraEmptyState.Content>
31
+ </ChakraEmptyState.Root>
32
+ )
33
+ },
34
+ )
@@ -0,0 +1,33 @@
1
+ import { Field as ChakraField } from "@chakra-ui/react"
2
+ import { forwardRef } from "react"
3
+
4
+ export interface FieldProps extends Omit<ChakraField.RootProps, "label"> {
5
+ label?: React.ReactNode
6
+ helperText?: React.ReactNode
7
+ errorText?: React.ReactNode
8
+ optionalText?: React.ReactNode
9
+ }
10
+
11
+ export const Field = forwardRef<HTMLDivElement, FieldProps>(
12
+ function Field(props, ref) {
13
+ const { label, children, helperText, errorText, optionalText, ...rest } =
14
+ props
15
+ return (
16
+ <ChakraField.Root ref={ref} {...rest}>
17
+ {label && (
18
+ <ChakraField.Label>
19
+ {label}
20
+ <ChakraField.RequiredIndicator fallback={optionalText} />
21
+ </ChakraField.Label>
22
+ )}
23
+ {children}
24
+ {helperText && (
25
+ <ChakraField.HelperText>{helperText}</ChakraField.HelperText>
26
+ )}
27
+ {errorText && (
28
+ <ChakraField.ErrorText>{errorText}</ChakraField.ErrorText>
29
+ )}
30
+ </ChakraField.Root>
31
+ )
32
+ },
33
+ )
@@ -0,0 +1,166 @@
1
+ "use client"
2
+
3
+ import type { ButtonProps, RecipeProps } from "@chakra-ui/react"
4
+ import {
5
+ Button,
6
+ FileUpload as ChakraFileUpload,
7
+ Icon,
8
+ IconButton,
9
+ Span,
10
+ Text,
11
+ useFileUploadContext,
12
+ useRecipe,
13
+ } from "@chakra-ui/react"
14
+ import { forwardRef } from "react"
15
+ import { LuFile, LuUpload, LuX } from "react-icons/lu"
16
+
17
+ export interface FileUploadRootProps extends ChakraFileUpload.RootProps {
18
+ inputProps?: React.InputHTMLAttributes<HTMLInputElement>
19
+ }
20
+
21
+ export const FileUploadRoot = forwardRef<HTMLInputElement, FileUploadRootProps>(
22
+ function FileUploadRoot(props, ref) {
23
+ const { children, inputProps, ...rest } = props
24
+ return (
25
+ <ChakraFileUpload.Root {...rest}>
26
+ <ChakraFileUpload.HiddenInput ref={ref} {...inputProps} />
27
+ {children}
28
+ </ChakraFileUpload.Root>
29
+ )
30
+ },
31
+ )
32
+
33
+ export interface FileUploadDropzoneProps
34
+ extends ChakraFileUpload.DropzoneProps {
35
+ label: React.ReactNode
36
+ description?: React.ReactNode
37
+ }
38
+
39
+ export const FileUploadDropzone = forwardRef<
40
+ HTMLInputElement,
41
+ FileUploadDropzoneProps
42
+ >(function FileUploadDropzone(props, ref) {
43
+ const { children, label, description, ...rest } = props
44
+ return (
45
+ <ChakraFileUpload.Dropzone ref={ref} {...rest}>
46
+ <Icon fontSize="xl" color="fg.muted">
47
+ <LuUpload />
48
+ </Icon>
49
+ <ChakraFileUpload.DropzoneContent>
50
+ <div>{label}</div>
51
+ {description && <Text color="fg.muted">{description}</Text>}
52
+ </ChakraFileUpload.DropzoneContent>
53
+ {children}
54
+ </ChakraFileUpload.Dropzone>
55
+ )
56
+ })
57
+
58
+ interface VisibilityProps {
59
+ showSize?: boolean
60
+ clearable?: boolean
61
+ }
62
+
63
+ interface FileUploadItemProps extends VisibilityProps {
64
+ file: File
65
+ }
66
+
67
+ const FileUploadItem = (props: FileUploadItemProps) => {
68
+ const { file, showSize, clearable } = props
69
+ return (
70
+ <ChakraFileUpload.Item file={file}>
71
+ <ChakraFileUpload.ItemPreview asChild>
72
+ <Icon fontSize="lg" color="fg.muted">
73
+ <LuFile />
74
+ </Icon>
75
+ </ChakraFileUpload.ItemPreview>
76
+
77
+ {showSize ? (
78
+ <ChakraFileUpload.ItemContent>
79
+ <ChakraFileUpload.ItemName />
80
+ <ChakraFileUpload.ItemSizeText />
81
+ </ChakraFileUpload.ItemContent>
82
+ ) : (
83
+ <ChakraFileUpload.ItemName flex="1" />
84
+ )}
85
+
86
+ {clearable && (
87
+ <ChakraFileUpload.ItemDeleteTrigger asChild>
88
+ <IconButton variant="ghost" color="fg.muted" size="xs">
89
+ <LuX />
90
+ </IconButton>
91
+ </ChakraFileUpload.ItemDeleteTrigger>
92
+ )}
93
+ </ChakraFileUpload.Item>
94
+ )
95
+ }
96
+
97
+ interface FileUploadListProps
98
+ extends VisibilityProps,
99
+ ChakraFileUpload.ItemGroupProps {
100
+ files?: File[]
101
+ }
102
+
103
+ export const FileUploadList = forwardRef<HTMLUListElement, FileUploadListProps>(
104
+ function FileUploadList(props, ref) {
105
+ const { showSize, clearable, files, ...rest } = props
106
+
107
+ const fileUpload = useFileUploadContext()
108
+ const acceptedFiles = files ?? fileUpload.acceptedFiles
109
+
110
+ if (acceptedFiles.length === 0) return null
111
+
112
+ return (
113
+ <ChakraFileUpload.ItemGroup ref={ref} {...rest}>
114
+ {acceptedFiles.map((file) => (
115
+ <FileUploadItem
116
+ key={file.name}
117
+ file={file}
118
+ showSize={showSize}
119
+ clearable={clearable}
120
+ />
121
+ ))}
122
+ </ChakraFileUpload.ItemGroup>
123
+ )
124
+ },
125
+ )
126
+
127
+ type Assign<T, U> = Omit<T, keyof U> & U
128
+
129
+ interface FileInputProps extends Assign<ButtonProps, RecipeProps<"input">> {
130
+ placeholder?: React.ReactNode
131
+ }
132
+
133
+ export const FileInput = forwardRef<HTMLButtonElement, FileInputProps>(
134
+ function FileInput(props, ref) {
135
+ const inputRecipe = useRecipe({ key: "input" })
136
+ const [recipeProps, restProps] = inputRecipe.splitVariantProps(props)
137
+ const { placeholder = "Select file(s)", ...rest } = restProps
138
+ return (
139
+ <ChakraFileUpload.Trigger asChild>
140
+ <Button
141
+ unstyled
142
+ py="0"
143
+ ref={ref}
144
+ {...rest}
145
+ css={[inputRecipe(recipeProps), props.css]}
146
+ >
147
+ <ChakraFileUpload.Context>
148
+ {({ acceptedFiles }) => {
149
+ if (acceptedFiles.length === 1) {
150
+ return <span>{acceptedFiles[0].name}</span>
151
+ }
152
+ if (acceptedFiles.length > 1) {
153
+ return <span>{acceptedFiles.length} files</span>
154
+ }
155
+ return <Span color="fg.subtle">{placeholder}</Span>
156
+ }}
157
+ </ChakraFileUpload.Context>
158
+ </Button>
159
+ </ChakraFileUpload.Trigger>
160
+ )
161
+ },
162
+ )
163
+
164
+ export const FileUploadLabel = ChakraFileUpload.Label
165
+ export const FileUploadClearTrigger = ChakraFileUpload.ClearTrigger
166
+ export const FileUploadTrigger = ChakraFileUpload.Trigger
@@ -0,0 +1,35 @@
1
+ import { HoverCard, Portal } from "@chakra-ui/react"
2
+ import { forwardRef } from "react"
3
+
4
+ interface HoverCardContentProps extends HoverCard.ContentProps {
5
+ portalled?: boolean
6
+ portalRef?: React.RefObject<HTMLElement>
7
+ }
8
+
9
+ export const HoverCardContent = forwardRef<
10
+ HTMLDivElement,
11
+ HoverCardContentProps
12
+ >(function HoverCardContent(props, ref) {
13
+ const { portalled = true, portalRef, ...rest } = props
14
+
15
+ return (
16
+ <Portal disabled={!portalled} container={portalRef}>
17
+ <HoverCard.Positioner>
18
+ <HoverCard.Content ref={ref} {...rest} />
19
+ </HoverCard.Positioner>
20
+ </Portal>
21
+ )
22
+ })
23
+
24
+ export const HoverCardArrow = forwardRef<HTMLDivElement, HoverCard.ArrowProps>(
25
+ function HoverCardArrow(props, ref) {
26
+ return (
27
+ <HoverCard.Arrow ref={ref} {...props}>
28
+ <HoverCard.ArrowTip />
29
+ </HoverCard.Arrow>
30
+ )
31
+ },
32
+ )
33
+
34
+ export const HoverCardRoot = HoverCard.Root
35
+ export const HoverCardTrigger = HoverCard.Trigger
@@ -0,0 +1,12 @@
1
+ "use client"
2
+
3
+ import type { HTMLChakraProps, RecipeProps } from "@chakra-ui/react"
4
+ import { createRecipeContext } from "@chakra-ui/react"
5
+
6
+ export interface LinkButtonProps
7
+ extends HTMLChakraProps<"a", RecipeProps<"button">> {}
8
+
9
+ const { withContext } = createRecipeContext({ key: "button" })
10
+
11
+ // Replace "a" with your framework's link component
12
+ export const LinkButton = withContext<HTMLAnchorElement, LinkButtonProps>("a")
@@ -0,0 +1,108 @@
1
+ "use client"
2
+
3
+ import { AbsoluteCenter, Menu as ChakraMenu, Portal } from "@chakra-ui/react"
4
+ import { forwardRef } from "react"
5
+ import { LuCheck, LuChevronRight } from "react-icons/lu"
6
+
7
+ interface MenuContentProps extends ChakraMenu.ContentProps {
8
+ portalled?: boolean
9
+ portalRef?: React.RefObject<HTMLElement>
10
+ }
11
+
12
+ export const MenuContent = forwardRef<HTMLDivElement, MenuContentProps>(
13
+ function MenuContent(props, ref) {
14
+ const { portalled = true, portalRef, ...rest } = props
15
+ return (
16
+ <Portal disabled={!portalled} container={portalRef}>
17
+ <ChakraMenu.Positioner>
18
+ <ChakraMenu.Content ref={ref} {...rest} />
19
+ </ChakraMenu.Positioner>
20
+ </Portal>
21
+ )
22
+ },
23
+ )
24
+
25
+ export const MenuArrow = forwardRef<HTMLDivElement, ChakraMenu.ArrowProps>(
26
+ function MenuArrow(props, ref) {
27
+ return (
28
+ <ChakraMenu.Arrow ref={ref} {...props}>
29
+ <ChakraMenu.ArrowTip />
30
+ </ChakraMenu.Arrow>
31
+ )
32
+ },
33
+ )
34
+
35
+ export const MenuCheckboxItem = forwardRef<
36
+ HTMLDivElement,
37
+ ChakraMenu.CheckboxItemProps
38
+ >(function MenuCheckboxItem(props, ref) {
39
+ return (
40
+ <ChakraMenu.CheckboxItem ref={ref} {...props}>
41
+ <ChakraMenu.ItemIndicator hidden={false}>
42
+ <LuCheck />
43
+ </ChakraMenu.ItemIndicator>
44
+ {props.children}
45
+ </ChakraMenu.CheckboxItem>
46
+ )
47
+ })
48
+
49
+ export const MenuRadioItem = forwardRef<
50
+ HTMLDivElement,
51
+ ChakraMenu.RadioItemProps
52
+ >(function MenuRadioItem(props, ref) {
53
+ const { children, ...rest } = props
54
+ return (
55
+ <ChakraMenu.RadioItem ps="8" ref={ref} {...rest}>
56
+ <AbsoluteCenter axis="horizontal" left="4" asChild>
57
+ <ChakraMenu.ItemIndicator>
58
+ <LuCheck />
59
+ </ChakraMenu.ItemIndicator>
60
+ </AbsoluteCenter>
61
+ <ChakraMenu.ItemText>{children}</ChakraMenu.ItemText>
62
+ </ChakraMenu.RadioItem>
63
+ )
64
+ })
65
+
66
+ export const MenuItemGroup = forwardRef<
67
+ HTMLDivElement,
68
+ ChakraMenu.ItemGroupProps
69
+ >(function MenuItemGroup(props, ref) {
70
+ const { title, children, ...rest } = props
71
+ return (
72
+ <ChakraMenu.ItemGroup ref={ref} {...rest}>
73
+ {title && (
74
+ <ChakraMenu.ItemGroupLabel userSelect="none">
75
+ {title}
76
+ </ChakraMenu.ItemGroupLabel>
77
+ )}
78
+ {children}
79
+ </ChakraMenu.ItemGroup>
80
+ )
81
+ })
82
+
83
+ export interface MenuTriggerItemProps extends ChakraMenu.ItemProps {
84
+ startIcon?: React.ReactNode
85
+ }
86
+
87
+ export const MenuTriggerItem = forwardRef<HTMLDivElement, MenuTriggerItemProps>(
88
+ function MenuTriggerItem(props, ref) {
89
+ const { startIcon, children, ...rest } = props
90
+ return (
91
+ <ChakraMenu.TriggerItem ref={ref} {...rest}>
92
+ {startIcon}
93
+ {children}
94
+ <LuChevronRight />
95
+ </ChakraMenu.TriggerItem>
96
+ )
97
+ },
98
+ )
99
+
100
+ export const MenuRadioItemGroup = ChakraMenu.RadioItemGroup
101
+ export const MenuContextTrigger = ChakraMenu.ContextTrigger
102
+ export const MenuRoot = ChakraMenu.Root
103
+ export const MenuSeparator = ChakraMenu.Separator
104
+
105
+ export const MenuItem = ChakraMenu.Item
106
+ export const MenuItemText = ChakraMenu.ItemText
107
+ export const MenuItemCommand = ChakraMenu.ItemCommand
108
+ export const MenuTrigger = ChakraMenu.Trigger