@questpie/admin 0.0.1 → 1.0.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 (250) hide show
  1. package/README.md +439 -424
  2. package/dist/auth-layout-M8K8_q5R.mjs +181 -0
  3. package/dist/auth-layout-M8K8_q5R.mjs.map +1 -0
  4. package/dist/bulk-upload-dialog-h7zXD78Y.mjs +274 -0
  5. package/dist/bulk-upload-dialog-h7zXD78Y.mjs.map +1 -0
  6. package/dist/{components/ui/card.mjs → card-BKHjBQfw.mjs} +8 -8
  7. package/dist/card-BKHjBQfw.mjs.map +1 -0
  8. package/dist/client/styles/index.css +434 -0
  9. package/dist/client-BCGpkAz6.mjs +22635 -0
  10. package/dist/client-BCGpkAz6.mjs.map +1 -0
  11. package/dist/client-CcWZbkBP.d.mts +13585 -0
  12. package/dist/client-CcWZbkBP.d.mts.map +1 -0
  13. package/dist/client.d.mts +3 -0
  14. package/dist/client.mjs +14 -0
  15. package/dist/content-locales-provider-BXvuIgfg.mjs +1650 -0
  16. package/dist/content-locales-provider-BXvuIgfg.mjs.map +1 -0
  17. package/dist/dashboard-page-B4PGEdc2.mjs +2500 -0
  18. package/dist/dashboard-page-B4PGEdc2.mjs.map +1 -0
  19. package/dist/dashboard-page-CVlyR40m.mjs +6 -0
  20. package/dist/dropzone-Do3awXKd.mjs +634 -0
  21. package/dist/dropzone-Do3awXKd.mjs.map +1 -0
  22. package/dist/{views/auth/forgot-password-form.mjs → forgot-password-page-Bcp-An4Y.mjs} +87 -14
  23. package/dist/forgot-password-page-Bcp-An4Y.mjs.map +1 -0
  24. package/dist/forgot-password-page-CIILVhfo.mjs +7 -0
  25. package/dist/index-B9Xwk4hi.d.mts +2753 -0
  26. package/dist/index-B9Xwk4hi.d.mts.map +1 -0
  27. package/dist/index.d.mts +3 -0
  28. package/dist/index.mjs +14 -0
  29. package/dist/login-page-8K7fo0qK.mjs +7 -0
  30. package/dist/login-page-CP4gA-dl.mjs +298 -0
  31. package/dist/login-page-CP4gA-dl.mjs.map +1 -0
  32. package/dist/preview-utils-BKQ9-TMa.mjs +65 -0
  33. package/dist/preview-utils-BKQ9-TMa.mjs.map +1 -0
  34. package/dist/{views/auth/reset-password-form.mjs → reset-password-page-BqfDmLxA.mjs} +111 -14
  35. package/dist/reset-password-page-BqfDmLxA.mjs.map +1 -0
  36. package/dist/reset-password-page-DLATv0xQ.mjs +7 -0
  37. package/dist/runtime-6VZM878K.mjs +69 -0
  38. package/dist/runtime-6VZM878K.mjs.map +1 -0
  39. package/dist/saved-views.types-BMsz5mCy.d.mts +42 -0
  40. package/dist/saved-views.types-BMsz5mCy.d.mts.map +1 -0
  41. package/dist/server.d.mts +250 -0
  42. package/dist/server.d.mts.map +1 -0
  43. package/dist/server.mjs +832 -0
  44. package/dist/server.mjs.map +1 -0
  45. package/dist/setup-page-CMZ5P_OE.mjs +6 -0
  46. package/dist/setup-page-YAP_fzqh.mjs +264 -0
  47. package/dist/setup-page-YAP_fzqh.mjs.map +1 -0
  48. package/dist/shared.d.mts +57 -0
  49. package/dist/shared.d.mts.map +1 -0
  50. package/dist/shared.mjs +3 -0
  51. package/dist/{hooks/use-auth.mjs → use-auth-BoLmWtmU.mjs} +42 -30
  52. package/dist/use-auth-BoLmWtmU.mjs.map +1 -0
  53. package/package.json +48 -197
  54. package/.turbo/turbo-build.log +0 -108
  55. package/CHANGELOG.md +0 -10
  56. package/STATUS.md +0 -917
  57. package/VALIDATION.md +0 -602
  58. package/components.json +0 -24
  59. package/dist/__tests__/setup.mjs +0 -38
  60. package/dist/__tests__/test-utils.mjs +0 -45
  61. package/dist/__tests__/vitest.d.mjs +0 -3
  62. package/dist/components/admin-app.mjs +0 -69
  63. package/dist/components/fields/array-field.mjs +0 -190
  64. package/dist/components/fields/checkbox-field.mjs +0 -34
  65. package/dist/components/fields/custom-field.mjs +0 -32
  66. package/dist/components/fields/date-field.mjs +0 -41
  67. package/dist/components/fields/datetime-field.mjs +0 -42
  68. package/dist/components/fields/email-field.mjs +0 -37
  69. package/dist/components/fields/embedded-collection.mjs +0 -253
  70. package/dist/components/fields/field-types.mjs +0 -1
  71. package/dist/components/fields/field-utils.mjs +0 -10
  72. package/dist/components/fields/field-wrapper.mjs +0 -34
  73. package/dist/components/fields/index.mjs +0 -23
  74. package/dist/components/fields/json-field.mjs +0 -243
  75. package/dist/components/fields/locale-badge.mjs +0 -16
  76. package/dist/components/fields/number-field.mjs +0 -39
  77. package/dist/components/fields/password-field.mjs +0 -37
  78. package/dist/components/fields/relation-field.mjs +0 -104
  79. package/dist/components/fields/relation-picker.mjs +0 -229
  80. package/dist/components/fields/relation-select.mjs +0 -188
  81. package/dist/components/fields/rich-text-editor/index.mjs +0 -897
  82. package/dist/components/fields/select-field.mjs +0 -41
  83. package/dist/components/fields/switch-field.mjs +0 -34
  84. package/dist/components/fields/text-field.mjs +0 -38
  85. package/dist/components/fields/textarea-field.mjs +0 -38
  86. package/dist/components/index.mjs +0 -59
  87. package/dist/components/primitives/checkbox-input.mjs +0 -127
  88. package/dist/components/primitives/date-input.mjs +0 -303
  89. package/dist/components/primitives/index.mjs +0 -12
  90. package/dist/components/primitives/number-input.mjs +0 -104
  91. package/dist/components/primitives/select-input.mjs +0 -177
  92. package/dist/components/primitives/tag-input.mjs +0 -135
  93. package/dist/components/primitives/text-input.mjs +0 -39
  94. package/dist/components/primitives/textarea-input.mjs +0 -37
  95. package/dist/components/primitives/toggle-input.mjs +0 -31
  96. package/dist/components/primitives/types.mjs +0 -12
  97. package/dist/components/ui/accordion.mjs +0 -55
  98. package/dist/components/ui/avatar.mjs +0 -54
  99. package/dist/components/ui/badge.mjs +0 -34
  100. package/dist/components/ui/button.mjs +0 -48
  101. package/dist/components/ui/checkbox.mjs +0 -21
  102. package/dist/components/ui/combobox.mjs +0 -163
  103. package/dist/components/ui/dialog.mjs +0 -95
  104. package/dist/components/ui/dropdown-menu.mjs +0 -138
  105. package/dist/components/ui/field.mjs +0 -113
  106. package/dist/components/ui/input-group.mjs +0 -82
  107. package/dist/components/ui/input.mjs +0 -17
  108. package/dist/components/ui/label.mjs +0 -15
  109. package/dist/components/ui/popover.mjs +0 -56
  110. package/dist/components/ui/scroll-area.mjs +0 -38
  111. package/dist/components/ui/select.mjs +0 -100
  112. package/dist/components/ui/separator.mjs +0 -16
  113. package/dist/components/ui/sheet.mjs +0 -90
  114. package/dist/components/ui/sidebar.mjs +0 -387
  115. package/dist/components/ui/skeleton.mjs +0 -14
  116. package/dist/components/ui/spinner.mjs +0 -16
  117. package/dist/components/ui/switch.mjs +0 -22
  118. package/dist/components/ui/table.mjs +0 -68
  119. package/dist/components/ui/tabs.mjs +0 -48
  120. package/dist/components/ui/textarea.mjs +0 -15
  121. package/dist/components/ui/tooltip.mjs +0 -44
  122. package/dist/config/component-registry.mjs +0 -38
  123. package/dist/config/index.mjs +0 -129
  124. package/dist/hooks/admin-provider.mjs +0 -70
  125. package/dist/hooks/index.mjs +0 -7
  126. package/dist/hooks/store.mjs +0 -178
  127. package/dist/hooks/use-collection-db.mjs +0 -146
  128. package/dist/hooks/use-collection.mjs +0 -112
  129. package/dist/hooks/use-global.mjs +0 -46
  130. package/dist/hooks/use-mobile.mjs +0 -20
  131. package/dist/lib/utils.mjs +0 -10
  132. package/dist/styles/index.css +0 -336
  133. package/dist/styles/index.mjs +0 -1
  134. package/dist/utils/index.mjs +0 -9
  135. package/dist/views/auth/auth-layout.mjs +0 -52
  136. package/dist/views/auth/index.mjs +0 -6
  137. package/dist/views/auth/login-form.mjs +0 -156
  138. package/dist/views/collection/auto-form-fields.mjs +0 -525
  139. package/dist/views/collection/collection-form.mjs +0 -91
  140. package/dist/views/collection/collection-list.mjs +0 -76
  141. package/dist/views/collection/form-field.mjs +0 -42
  142. package/dist/views/collection/index.mjs +0 -6
  143. package/dist/views/common/index.mjs +0 -4
  144. package/dist/views/common/locale-switcher.mjs +0 -39
  145. package/dist/views/common/version-history.mjs +0 -272
  146. package/dist/views/index.mjs +0 -9
  147. package/dist/views/layout/admin-layout.mjs +0 -40
  148. package/dist/views/layout/admin-router.mjs +0 -95
  149. package/dist/views/layout/admin-sidebar.mjs +0 -63
  150. package/dist/views/layout/index.mjs +0 -5
  151. package/src/__tests__/setup.ts +0 -44
  152. package/src/__tests__/test-utils.tsx +0 -49
  153. package/src/__tests__/vitest.d.ts +0 -9
  154. package/src/components/admin-app.tsx +0 -221
  155. package/src/components/fields/array-field.tsx +0 -237
  156. package/src/components/fields/checkbox-field.tsx +0 -47
  157. package/src/components/fields/custom-field.tsx +0 -50
  158. package/src/components/fields/date-field.tsx +0 -65
  159. package/src/components/fields/datetime-field.tsx +0 -67
  160. package/src/components/fields/email-field.tsx +0 -51
  161. package/src/components/fields/embedded-collection.tsx +0 -315
  162. package/src/components/fields/field-types.ts +0 -162
  163. package/src/components/fields/field-utils.ts +0 -6
  164. package/src/components/fields/field-wrapper.tsx +0 -52
  165. package/src/components/fields/index.ts +0 -66
  166. package/src/components/fields/json-field.tsx +0 -440
  167. package/src/components/fields/locale-badge.tsx +0 -15
  168. package/src/components/fields/number-field.tsx +0 -57
  169. package/src/components/fields/password-field.tsx +0 -51
  170. package/src/components/fields/relation-field.tsx +0 -243
  171. package/src/components/fields/relation-picker.tsx +0 -402
  172. package/src/components/fields/relation-select.tsx +0 -327
  173. package/src/components/fields/rich-text-editor/index.tsx +0 -1337
  174. package/src/components/fields/select-field.tsx +0 -61
  175. package/src/components/fields/switch-field.tsx +0 -47
  176. package/src/components/fields/text-field.tsx +0 -55
  177. package/src/components/fields/textarea-field.tsx +0 -55
  178. package/src/components/index.ts +0 -40
  179. package/src/components/primitives/checkbox-input.tsx +0 -193
  180. package/src/components/primitives/date-input.tsx +0 -401
  181. package/src/components/primitives/index.ts +0 -24
  182. package/src/components/primitives/number-input.tsx +0 -132
  183. package/src/components/primitives/select-input.tsx +0 -296
  184. package/src/components/primitives/tag-input.tsx +0 -200
  185. package/src/components/primitives/text-input.tsx +0 -49
  186. package/src/components/primitives/textarea-input.tsx +0 -46
  187. package/src/components/primitives/toggle-input.tsx +0 -36
  188. package/src/components/primitives/types.ts +0 -235
  189. package/src/components/ui/accordion.tsx +0 -72
  190. package/src/components/ui/avatar.tsx +0 -106
  191. package/src/components/ui/badge.tsx +0 -48
  192. package/src/components/ui/button.tsx +0 -53
  193. package/src/components/ui/card.tsx +0 -94
  194. package/src/components/ui/checkbox.tsx +0 -27
  195. package/src/components/ui/combobox.tsx +0 -290
  196. package/src/components/ui/dialog.tsx +0 -151
  197. package/src/components/ui/dropdown-menu.tsx +0 -254
  198. package/src/components/ui/field.tsx +0 -227
  199. package/src/components/ui/input-group.tsx +0 -149
  200. package/src/components/ui/input.tsx +0 -20
  201. package/src/components/ui/label.tsx +0 -18
  202. package/src/components/ui/popover.tsx +0 -88
  203. package/src/components/ui/scroll-area.tsx +0 -53
  204. package/src/components/ui/select.tsx +0 -192
  205. package/src/components/ui/separator.tsx +0 -23
  206. package/src/components/ui/sheet.tsx +0 -127
  207. package/src/components/ui/sidebar.tsx +0 -723
  208. package/src/components/ui/skeleton.tsx +0 -13
  209. package/src/components/ui/spinner.tsx +0 -10
  210. package/src/components/ui/switch.tsx +0 -32
  211. package/src/components/ui/table.tsx +0 -99
  212. package/src/components/ui/tabs.tsx +0 -82
  213. package/src/components/ui/textarea.tsx +0 -18
  214. package/src/components/ui/tooltip.tsx +0 -70
  215. package/src/config/component-registry.ts +0 -190
  216. package/src/config/index.ts +0 -1099
  217. package/src/hooks/README.md +0 -269
  218. package/src/hooks/admin-provider.tsx +0 -110
  219. package/src/hooks/index.ts +0 -41
  220. package/src/hooks/store.ts +0 -248
  221. package/src/hooks/use-auth.ts +0 -168
  222. package/src/hooks/use-collection-db.ts +0 -209
  223. package/src/hooks/use-collection.ts +0 -156
  224. package/src/hooks/use-global.ts +0 -69
  225. package/src/hooks/use-mobile.ts +0 -21
  226. package/src/lib/utils.ts +0 -6
  227. package/src/styles/index.css +0 -340
  228. package/src/utils/index.ts +0 -6
  229. package/src/views/auth/auth-layout.tsx +0 -77
  230. package/src/views/auth/forgot-password-form.tsx +0 -192
  231. package/src/views/auth/index.ts +0 -21
  232. package/src/views/auth/login-form.tsx +0 -229
  233. package/src/views/auth/reset-password-form.tsx +0 -232
  234. package/src/views/collection/auto-form-fields.tsx +0 -982
  235. package/src/views/collection/collection-form.tsx +0 -186
  236. package/src/views/collection/collection-list.tsx +0 -223
  237. package/src/views/collection/form-field.tsx +0 -52
  238. package/src/views/collection/index.ts +0 -15
  239. package/src/views/common/index.ts +0 -8
  240. package/src/views/common/locale-switcher.tsx +0 -45
  241. package/src/views/common/version-history.tsx +0 -406
  242. package/src/views/index.ts +0 -25
  243. package/src/views/layout/admin-layout.tsx +0 -117
  244. package/src/views/layout/admin-router.tsx +0 -206
  245. package/src/views/layout/admin-sidebar.tsx +0 -185
  246. package/src/views/layout/index.ts +0 -12
  247. package/tsconfig.json +0 -13
  248. package/tsconfig.tsbuildinfo +0 -1
  249. package/tsdown.config.ts +0 -13
  250. package/vitest.config.ts +0 -29
@@ -1,61 +0,0 @@
1
- import { Controller } from "react-hook-form";
2
- import { SelectInput } from "../primitives/select-input";
3
- import { FieldWrapper } from "./field-wrapper";
4
- import { useResolvedControl } from "./field-utils";
5
- import type { SelectFieldProps } from "./field-types";
6
-
7
- export function SelectField<TValue extends string = string>({
8
- name,
9
- label,
10
- description,
11
- placeholder,
12
- required,
13
- disabled,
14
- localized,
15
- locale,
16
- control,
17
- className,
18
- options,
19
- loadOptions,
20
- multiple,
21
- clearable,
22
- maxSelections,
23
- emptyMessage,
24
- }: SelectFieldProps<TValue>) {
25
- const resolvedControl = useResolvedControl(control);
26
-
27
- return (
28
- <Controller
29
- name={name}
30
- control={resolvedControl}
31
- render={({ field, fieldState }) => (
32
- <FieldWrapper
33
- name={name}
34
- label={label}
35
- description={description}
36
- required={required}
37
- disabled={disabled}
38
- localized={localized}
39
- locale={locale}
40
- error={fieldState.error?.message}
41
- >
42
- <SelectInput<TValue>
43
- id={name}
44
- value={field.value ?? (multiple ? [] : null)}
45
- onChange={field.onChange}
46
- options={options}
47
- loadOptions={loadOptions}
48
- multiple={multiple}
49
- clearable={clearable}
50
- maxSelections={maxSelections}
51
- emptyMessage={emptyMessage}
52
- placeholder={placeholder}
53
- disabled={disabled}
54
- aria-invalid={!!fieldState.error}
55
- className={className}
56
- />
57
- </FieldWrapper>
58
- )}
59
- />
60
- );
61
- }
@@ -1,47 +0,0 @@
1
- import { Controller } from "react-hook-form";
2
- import { ToggleInput } from "../primitives/toggle-input";
3
- import { FieldWrapper } from "./field-wrapper";
4
- import { useResolvedControl } from "./field-utils";
5
- import type { BooleanFieldProps } from "./field-types";
6
-
7
- export function SwitchField({
8
- name,
9
- label,
10
- description,
11
- required,
12
- disabled,
13
- localized,
14
- locale,
15
- control,
16
- className,
17
- }: BooleanFieldProps) {
18
- const resolvedControl = useResolvedControl(control);
19
-
20
- return (
21
- <Controller
22
- name={name}
23
- control={resolvedControl}
24
- render={({ field, fieldState }) => (
25
- <FieldWrapper
26
- name={name}
27
- label={label}
28
- description={description}
29
- required={required}
30
- disabled={disabled}
31
- localized={localized}
32
- locale={locale}
33
- error={fieldState.error?.message}
34
- >
35
- <ToggleInput
36
- id={name}
37
- value={!!field.value}
38
- onChange={field.onChange}
39
- disabled={disabled}
40
- aria-invalid={!!fieldState.error}
41
- className={className}
42
- />
43
- </FieldWrapper>
44
- )}
45
- />
46
- );
47
- }
@@ -1,55 +0,0 @@
1
- import { Controller } from "react-hook-form";
2
- import { TextInput } from "../primitives/text-input";
3
- import { FieldWrapper } from "./field-wrapper";
4
- import { useResolvedControl } from "./field-utils";
5
- import type { TextFieldProps } from "./field-types";
6
-
7
- export function TextField({
8
- name,
9
- label,
10
- description,
11
- placeholder,
12
- required,
13
- disabled,
14
- localized,
15
- locale,
16
- control,
17
- className,
18
- type = "text",
19
- maxLength,
20
- autoComplete,
21
- }: TextFieldProps) {
22
- const resolvedControl = useResolvedControl(control);
23
-
24
- return (
25
- <Controller
26
- name={name}
27
- control={resolvedControl}
28
- render={({ field, fieldState }) => (
29
- <FieldWrapper
30
- name={name}
31
- label={label}
32
- description={description}
33
- required={required}
34
- disabled={disabled}
35
- localized={localized}
36
- locale={locale}
37
- error={fieldState.error?.message}
38
- >
39
- <TextInput
40
- id={name}
41
- value={field.value ?? ""}
42
- onChange={field.onChange}
43
- type={type}
44
- placeholder={placeholder}
45
- disabled={disabled}
46
- maxLength={maxLength}
47
- autoComplete={autoComplete}
48
- aria-invalid={!!fieldState.error}
49
- className={className}
50
- />
51
- </FieldWrapper>
52
- )}
53
- />
54
- );
55
- }
@@ -1,55 +0,0 @@
1
- import { Controller } from "react-hook-form";
2
- import { TextareaInput } from "../primitives/textarea-input";
3
- import { FieldWrapper } from "./field-wrapper";
4
- import { useResolvedControl } from "./field-utils";
5
- import type { TextareaFieldProps } from "./field-types";
6
-
7
- export function TextareaField({
8
- name,
9
- label,
10
- description,
11
- placeholder,
12
- required,
13
- disabled,
14
- localized,
15
- locale,
16
- control,
17
- className,
18
- rows,
19
- maxLength,
20
- autoResize,
21
- }: TextareaFieldProps) {
22
- const resolvedControl = useResolvedControl(control);
23
-
24
- return (
25
- <Controller
26
- name={name}
27
- control={resolvedControl}
28
- render={({ field, fieldState }) => (
29
- <FieldWrapper
30
- name={name}
31
- label={label}
32
- description={description}
33
- required={required}
34
- disabled={disabled}
35
- localized={localized}
36
- locale={locale}
37
- error={fieldState.error?.message}
38
- >
39
- <TextareaInput
40
- id={name}
41
- value={field.value ?? ""}
42
- onChange={field.onChange}
43
- placeholder={placeholder}
44
- disabled={disabled}
45
- rows={rows}
46
- maxLength={maxLength}
47
- autoResize={autoResize}
48
- aria-invalid={!!fieldState.error}
49
- className={className}
50
- />
51
- </FieldWrapper>
52
- )}
53
- />
54
- );
55
- }
@@ -1,40 +0,0 @@
1
- // Re-export all shadcn UI components
2
-
3
- // MAIN ENTRY POINT
4
- export { AdminApp } from "./admin-app";
5
- export type { AdminAppProps } from "./admin-app";
6
-
7
- // View components - re-export from new views directory
8
- // @deprecated Import from '@questpie/admin/views' instead
9
- export * from "../views";
10
-
11
- // Field components (RelationSelect, RelationPicker, etc.)
12
- export * from "./fields";
13
-
14
- // UI components (only export existing ones)
15
- export * from "./ui/accordion";
16
- export * from "./ui/avatar";
17
- export * from "./ui/badge";
18
- export * from "./ui/button";
19
- export * from "./ui/card";
20
- export * from "./ui/checkbox";
21
- export * from "./ui/combobox";
22
- export * from "./ui/dialog";
23
- export * from "./ui/dropdown-menu";
24
- export * from "./ui/field";
25
- export * from "./ui/input";
26
- export * from "./ui/input-group";
27
- export * from "./ui/label";
28
- export * from "./ui/popover";
29
- export * from "./ui/scroll-area";
30
- export * from "./ui/select";
31
- export * from "./ui/separator";
32
- export * from "./ui/sheet";
33
- export * from "./ui/sidebar";
34
- export * from "./ui/skeleton";
35
- export * from "./ui/spinner";
36
- export * from "./ui/switch";
37
- export * from "./ui/table";
38
- export * from "./ui/tabs";
39
- export * from "./ui/textarea";
40
- export * from "./ui/tooltip";
@@ -1,193 +0,0 @@
1
- "use client";
2
-
3
- import { Checkbox } from "../ui/checkbox";
4
- import { cn } from "../../lib/utils";
5
- import type {
6
- CheckboxInputProps,
7
- CheckboxGroupProps,
8
- RadioGroupProps,
9
- } from "./types";
10
-
11
- /**
12
- * Checkbox Input Primitive
13
- *
14
- * A single checkbox with value/onChange pattern.
15
- *
16
- * @example
17
- * ```tsx
18
- * <CheckboxInput
19
- * value={isAccepted}
20
- * onChange={setIsAccepted}
21
- * />
22
- * ```
23
- */
24
- export function CheckboxInput({
25
- value,
26
- onChange,
27
- disabled,
28
- className,
29
- id,
30
- "aria-invalid": ariaInvalid,
31
- }: CheckboxInputProps) {
32
- return (
33
- <Checkbox
34
- id={id}
35
- checked={value}
36
- onCheckedChange={(checked) => onChange(checked === true)}
37
- disabled={disabled}
38
- aria-invalid={ariaInvalid}
39
- className={cn(className)}
40
- />
41
- );
42
- }
43
-
44
- /**
45
- * Checkbox Group Primitive
46
- *
47
- * A group of checkboxes for multi-selection.
48
- * Returns an array of selected values.
49
- *
50
- * @example
51
- * ```tsx
52
- * <CheckboxGroup
53
- * value={selectedCategories}
54
- * onChange={setSelectedCategories}
55
- * options={[
56
- * { value: "news", label: "News" },
57
- * { value: "blog", label: "Blog" },
58
- * { value: "tutorial", label: "Tutorial" },
59
- * ]}
60
- * orientation="vertical"
61
- * />
62
- * ```
63
- */
64
- export function CheckboxGroup<TValue extends string = string>({
65
- value,
66
- onChange,
67
- options,
68
- orientation = "vertical",
69
- disabled,
70
- className,
71
- id,
72
- "aria-invalid": ariaInvalid,
73
- }: CheckboxGroupProps<TValue>) {
74
- const handleChange = (optionValue: TValue, checked: boolean) => {
75
- if (checked) {
76
- onChange([...value, optionValue]);
77
- } else {
78
- onChange(value.filter((v) => v !== optionValue));
79
- }
80
- };
81
-
82
- return (
83
- <div
84
- id={id}
85
- role="group"
86
- aria-invalid={ariaInvalid}
87
- className={cn(
88
- "flex gap-3",
89
- orientation === "vertical" ? "flex-col" : "flex-row flex-wrap",
90
- className,
91
- )}
92
- >
93
- {options.map((option) => {
94
- const optionId = `${id}-${String(option.value)}`;
95
- return (
96
- <div
97
- key={String(option.value)}
98
- className={cn(
99
- "flex items-center gap-2",
100
- option.disabled || disabled
101
- ? "opacity-50 cursor-not-allowed"
102
- : "cursor-pointer",
103
- )}
104
- >
105
- <CheckboxInput
106
- id={optionId}
107
- value={value.includes(option.value)}
108
- onChange={(checked) => handleChange(option.value, checked)}
109
- disabled={option.disabled || disabled}
110
- />
111
- <label htmlFor={optionId} className="text-sm cursor-pointer">
112
- {option.label}
113
- </label>
114
- </div>
115
- );
116
- })}
117
- </div>
118
- );
119
- }
120
-
121
- /**
122
- * Radio Group Primitive
123
- *
124
- * A group of radio buttons for single selection.
125
- * Returns the selected value or null.
126
- *
127
- * @example
128
- * ```tsx
129
- * <RadioGroup
130
- * value={selectedPriority}
131
- * onChange={setSelectedPriority}
132
- * options={[
133
- * { value: "low", label: "Low" },
134
- * { value: "medium", label: "Medium" },
135
- * { value: "high", label: "High" },
136
- * ]}
137
- * />
138
- * ```
139
- */
140
- export function RadioGroup<TValue extends string = string>({
141
- value,
142
- onChange,
143
- options,
144
- orientation = "vertical",
145
- disabled,
146
- className,
147
- id,
148
- "aria-invalid": ariaInvalid,
149
- }: RadioGroupProps<TValue>) {
150
- return (
151
- <div
152
- id={id}
153
- role="radiogroup"
154
- aria-invalid={ariaInvalid}
155
- className={cn(
156
- "flex gap-3",
157
- orientation === "vertical" ? "flex-col" : "flex-row flex-wrap",
158
- className,
159
- )}
160
- >
161
- {options.map((option) => {
162
- const optionId = `${id}-${String(option.value)}`;
163
- return (
164
- <div
165
- key={String(option.value)}
166
- className={cn(
167
- "flex items-center gap-2",
168
- option.disabled || disabled
169
- ? "opacity-50 cursor-not-allowed"
170
- : "cursor-pointer",
171
- )}
172
- >
173
- <input
174
- type="radio"
175
- id={optionId}
176
- name={id}
177
- checked={value === option.value}
178
- onChange={() => onChange(option.value)}
179
- disabled={option.disabled || disabled}
180
- className={cn(
181
- "size-4 shrink-0 accent-primary",
182
- "disabled:cursor-not-allowed disabled:opacity-50",
183
- )}
184
- />
185
- <label htmlFor={optionId} className="text-sm cursor-pointer">
186
- {option.label}
187
- </label>
188
- </div>
189
- );
190
- })}
191
- </div>
192
- );
193
- }