@boxcustodia/library 2.0.0-alpha.13 → 2.0.0-alpha.15

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 (174) hide show
  1. package/dist/index.cjs.js +1 -138
  2. package/dist/index.d.ts +1083 -717
  3. package/dist/index.es.js +7059 -56179
  4. package/dist/theme.css +1 -1
  5. package/package.json +34 -26
  6. package/src/__doc__/Changelog.mdx +6 -6
  7. package/src/__doc__/Examples.tsx +1 -1
  8. package/src/__doc__/Intro.mdx +3 -3
  9. package/src/__doc__/Tabs.mdx +112 -0
  10. package/src/__doc__/V2.mdx +1245 -0
  11. package/src/components/accordion/accordion.stories.tsx +143 -0
  12. package/src/components/accordion/accordion.tsx +135 -0
  13. package/src/components/accordion/index.ts +1 -0
  14. package/src/components/alert/alert.stories.tsx +24 -4
  15. package/src/components/alert/alert.tsx +17 -9
  16. package/src/components/alert-dialog/alert-dialog.stories.tsx +24 -0
  17. package/src/components/alert-dialog/alert-dialog.test.tsx +1 -1
  18. package/src/components/alert-dialog/alert-dialog.tsx +58 -10
  19. package/src/components/auto-complete/auto-complete.stories.tsx +615 -200
  20. package/src/components/auto-complete/auto-complete.tsx +420 -68
  21. package/src/components/auto-complete/index.ts +0 -1
  22. package/src/components/avatar/avatar.stories.tsx +162 -21
  23. package/src/components/avatar/avatar.tsx +79 -20
  24. package/src/components/button/button.stories.tsx +236 -294
  25. package/src/components/button/button.test.tsx +10 -17
  26. package/src/components/button/button.tsx +53 -18
  27. package/src/components/button/components/base-button.tsx +25 -53
  28. package/src/components/button/index.ts +0 -1
  29. package/src/components/calendar/calendar.stories.tsx +1 -1
  30. package/src/components/calendar/calendar.tsx +4 -4
  31. package/src/components/card/card.stories.tsx +140 -69
  32. package/src/components/card/card.tsx +155 -54
  33. package/src/components/center/center.stories.tsx +22 -39
  34. package/src/components/checkbox/checkbox.stories.tsx +25 -5
  35. package/src/components/checkbox/checkbox.tsx +76 -15
  36. package/src/components/checkbox-group/checkbox-group.stories.tsx +116 -28
  37. package/src/components/checkbox-group/checkbox-group.tsx +84 -3
  38. package/src/components/combobox/combobox.stories.tsx +33 -23
  39. package/src/components/combobox/combobox.tsx +120 -104
  40. package/src/components/date-picker/date-input.stories.tsx +14 -6
  41. package/src/components/date-picker/date-input.tsx +3 -3
  42. package/src/components/date-picker/date-picker.model.ts +13 -4
  43. package/src/components/date-picker/date-picker.stories.tsx +38 -12
  44. package/src/components/date-picker/date-picker.tsx +29 -15
  45. package/src/components/dialog/dialog.stories.tsx +18 -0
  46. package/src/components/dialog/dialog.test.tsx +1 -1
  47. package/src/components/dialog/dialog.tsx +51 -20
  48. package/src/components/divider/divider.stories.tsx +6 -0
  49. package/src/components/dropzone/dropzone.stories.tsx +70 -90
  50. package/src/components/dropzone/dropzone.tsx +383 -105
  51. package/src/components/dropzone/index.ts +0 -1
  52. package/src/components/empty/empty.stories.tsx +164 -0
  53. package/src/components/empty/empty.tsx +156 -0
  54. package/src/components/empty/index.ts +1 -0
  55. package/src/components/field/field.stories.tsx +226 -3
  56. package/src/components/field/field.tsx +77 -42
  57. package/src/components/form/form.stories.tsx +320 -197
  58. package/src/components/form/form.tsx +3 -23
  59. package/src/components/index.ts +2 -6
  60. package/src/components/input/input.stories.tsx +5 -5
  61. package/src/components/input/input.tsx +5 -5
  62. package/src/components/kbd/kbd.stories.tsx +1 -0
  63. package/src/components/label/label.stories.tsx +16 -0
  64. package/src/components/label/label.tsx +13 -2
  65. package/src/components/loader/loader.stories.tsx +7 -5
  66. package/src/components/loader/loader.tsx +8 -3
  67. package/src/components/menu/menu-primitives.tsx +207 -196
  68. package/src/components/menu/menu.stories.tsx +275 -146
  69. package/src/components/menu/menu.tsx +146 -54
  70. package/src/components/number-input/number-input.stories.tsx +27 -4
  71. package/src/components/number-input/number-input.test.tsx +2 -2
  72. package/src/components/number-input/number-input.tsx +29 -33
  73. package/src/components/otp/index.ts +1 -0
  74. package/src/components/otp/otp.stories.tsx +209 -0
  75. package/src/components/otp/otp.tsx +100 -0
  76. package/src/components/pagination/index.ts +1 -0
  77. package/src/components/pagination/pagination.model.ts +2 -0
  78. package/src/components/pagination/pagination.stories.tsx +153 -59
  79. package/src/components/pagination/pagination.test.tsx +122 -57
  80. package/src/components/pagination/pagination.tsx +575 -77
  81. package/src/components/password/password.stories.tsx +18 -3
  82. package/src/components/password/password.tsx +26 -10
  83. package/src/components/popover/popover.stories.tsx +26 -5
  84. package/src/components/popover/popover.tsx +15 -23
  85. package/src/components/progress/progress.stories.tsx +1 -0
  86. package/src/components/radio-group/index.ts +1 -0
  87. package/src/components/radio-group/radio-group.stories.tsx +251 -0
  88. package/src/components/radio-group/radio-group.tsx +212 -0
  89. package/src/components/scroll-area/scroll-area.stories.tsx +1 -0
  90. package/src/components/select/select.stories.tsx +118 -19
  91. package/src/components/select/select.tsx +67 -62
  92. package/src/components/skeleton/skeleton.stories.tsx +1 -0
  93. package/src/components/stack/stack.stories.tsx +179 -89
  94. package/src/components/stack/stack.tsx +2 -2
  95. package/src/components/stepper/index.ts +1 -1
  96. package/src/components/stepper/stepper.stories.tsx +766 -83
  97. package/src/components/stepper/stepper.test.tsx +18 -18
  98. package/src/components/stepper/stepper.tsx +554 -0
  99. package/src/components/switch/switch.stories.tsx +15 -1
  100. package/src/components/switch/switch.tsx +17 -4
  101. package/src/components/table/index.ts +0 -2
  102. package/src/components/table/table.stories.tsx +131 -18
  103. package/src/components/table/table.test.tsx +1 -1
  104. package/src/components/table/table.tsx +183 -77
  105. package/src/components/tabs/tabs.stories.tsx +372 -155
  106. package/src/components/tabs/tabs.test.tsx +12 -12
  107. package/src/components/tabs/tabs.tsx +72 -149
  108. package/src/components/tag/index.ts +0 -1
  109. package/src/components/tag/tag.stories.tsx +147 -120
  110. package/src/components/tag/tag.tsx +47 -95
  111. package/src/components/textarea/textarea.stories.tsx +8 -22
  112. package/src/components/textarea/textarea.tsx +17 -79
  113. package/src/components/timeline/timeline.stories.tsx +322 -42
  114. package/src/components/timeline/timeline.tsx +359 -132
  115. package/src/components/toast/toast.stories.tsx +1 -0
  116. package/src/components/tooltip/tooltip.tsx +11 -9
  117. package/src/components/tree/index.ts +0 -1
  118. package/src/components/tree/tree.stories.tsx +364 -408
  119. package/src/components/tree/tree.test.tsx +163 -0
  120. package/src/components/tree/tree.tsx +212 -36
  121. package/src/hooks/useAsync/__doc__/useAsync.stories.tsx +5 -5
  122. package/src/hooks/useClipboard/__doc__/useClipboard.stories.tsx +1 -3
  123. package/src/hooks/useDebounceCallback/__doc__/useDebouncedCallback.stories.tsx +6 -6
  124. package/src/hooks/useDocumentTitle/__doc__/useDocumentTitle.stories.tsx +1 -1
  125. package/src/hooks/useEventListener/__test__/useEventListener.test.tsx +1 -1
  126. package/src/hooks/useLocalStorage/__doc__/useLocalStorage.stories.tsx +1 -1
  127. package/src/hooks/usePagination/usePagination.tsx +36 -24
  128. package/src/styles/theme.css +1 -1
  129. package/src/utils/form.tsx +69 -37
  130. package/src/utils/index.ts +1 -1
  131. package/src/__doc__/Migration.mdx +0 -451
  132. package/src/components/auto-complete/auto-complete-primitives.tsx +0 -155
  133. package/src/components/background-image/background-image.stories.tsx +0 -21
  134. package/src/components/background-image/background-image.test.tsx +0 -29
  135. package/src/components/background-image/background-image.tsx +0 -23
  136. package/src/components/background-image/index.ts +0 -1
  137. package/src/components/button/button.variants.ts +0 -44
  138. package/src/components/button/components/loader-overlay.tsx +0 -21
  139. package/src/components/button/components/loading-icon.tsx +0 -47
  140. package/src/components/dropzone/upload-primitives.tsx +0 -310
  141. package/src/components/dropzone/use-dropzone.ts +0 -122
  142. package/src/components/empty-state/empty-state.stories.tsx +0 -56
  143. package/src/components/empty-state/empty-state.tsx +0 -39
  144. package/src/components/empty-state/index.ts +0 -1
  145. package/src/components/heading/heading.stories.tsx +0 -74
  146. package/src/components/heading/heading.tsx +0 -28
  147. package/src/components/heading/heading.variants.ts +0 -27
  148. package/src/components/heading/index.ts +0 -1
  149. package/src/components/kbd/kbd.variants.ts +0 -26
  150. package/src/components/menu/util/render-menu-item.tsx +0 -54
  151. package/src/components/multi-select/hooks/use-multi-select.ts +0 -66
  152. package/src/components/multi-select/index.ts +0 -1
  153. package/src/components/multi-select/multi-select.stories.tsx +0 -294
  154. package/src/components/multi-select/multi-select.tsx +0 -300
  155. package/src/components/multi-select/multi-select.variants.ts +0 -22
  156. package/src/components/pagination/components/pagination-option.tsx +0 -27
  157. package/src/components/show/index.ts +0 -1
  158. package/src/components/show/show.stories.tsx +0 -197
  159. package/src/components/show/show.test.tsx +0 -41
  160. package/src/components/show/show.tsx +0 -16
  161. package/src/components/stepper/Stepper.tsx +0 -190
  162. package/src/components/stepper/context/stepper-context.tsx +0 -11
  163. package/src/components/table/table-primitives.tsx +0 -122
  164. package/src/components/table/table.model.ts +0 -20
  165. package/src/components/table-pagination/index.ts +0 -2
  166. package/src/components/table-pagination/table-pagination.model.ts +0 -2
  167. package/src/components/table-pagination/table-pagination.stories.tsx +0 -23
  168. package/src/components/table-pagination/table-pagination.test.tsx +0 -32
  169. package/src/components/table-pagination/table-pagination.tsx +0 -108
  170. package/src/components/tabs/context/tabs-context.tsx +0 -14
  171. package/src/components/tag/tag.variants.ts +0 -31
  172. package/src/components/timeline/timeline-status.ts +0 -5
  173. package/src/components/tree/hooks/use-controllable-tree-state.ts +0 -80
  174. package/src/components/tree/tree-primitives.tsx +0 -126
@@ -1,122 +0,0 @@
1
- import { useCallback, useState } from "react";
2
-
3
- export type FileErrorCode =
4
- | "INVALID_EXTENSION"
5
- | "FILE_TOO_LARGE"
6
- | "MAX_FILES_EXCEEDED";
7
-
8
- export type FileError = {
9
- file: File;
10
- errorMessage: string;
11
- errorCode: FileErrorCode;
12
- };
13
-
14
- type UseDropzoneProps = {
15
- onDrop: (acceptedFiles: File[], rejectedFiles: File[]) => void;
16
- onError?: (fileErrors: FileError[]) => void;
17
- allowedExtensions?: string[];
18
- maxFileSize?: number;
19
- maxFiles?: number;
20
- };
21
-
22
- export const useDropzone = ({
23
- onDrop,
24
- onError,
25
- allowedExtensions = [],
26
- maxFileSize = 5 * 1024 * 1024,
27
- maxFiles = Infinity,
28
- }: UseDropzoneProps) => {
29
- const [isDragActive, setIsDragActive] = useState(false);
30
-
31
- const handleDragOver = useCallback((e: React.DragEvent<HTMLDivElement>) => {
32
- e.preventDefault();
33
- e.stopPropagation();
34
- }, []);
35
-
36
- const handleDragEnter = useCallback((e: React.DragEvent<HTMLDivElement>) => {
37
- e.preventDefault();
38
- e.stopPropagation();
39
- setIsDragActive(true);
40
- }, []);
41
-
42
- const handleDragLeave = useCallback((e: React.DragEvent<HTMLDivElement>) => {
43
- e.preventDefault();
44
- e.stopPropagation();
45
- setIsDragActive(false);
46
- }, []);
47
-
48
- const validateFiles = (files: File[]): [File[], File[], FileError[]] => {
49
- const [rejected = [], accepted = [], fileErrors = []] = files.reduce(
50
- (
51
- [rejected, accepted, fileErrors]: [File[], File[], FileError[]],
52
- file,
53
- ) => {
54
- if (
55
- allowedExtensions.length > 0 &&
56
- !allowedExtensions.includes(file.type)
57
- ) {
58
- rejected.push(file);
59
- fileErrors.push({
60
- file,
61
- errorMessage: "Extensión no permitida",
62
- errorCode: "INVALID_EXTENSION",
63
- });
64
- return [rejected, accepted, fileErrors];
65
- }
66
- if (file.size > maxFileSize) {
67
- rejected.push(file);
68
- fileErrors.push({
69
- file,
70
- errorMessage: "Archivo demasiado grande",
71
- errorCode: "FILE_TOO_LARGE",
72
- });
73
- return [rejected, accepted, fileErrors];
74
- }
75
- if (maxFiles && maxFiles < accepted.length + 1) {
76
- rejected.push(file);
77
- fileErrors.push({
78
- file,
79
- errorMessage: "Límite de archivos excedido",
80
- errorCode: "MAX_FILES_EXCEEDED",
81
- });
82
- return [rejected, accepted, fileErrors];
83
- }
84
- accepted.push(file);
85
- return [rejected, accepted, fileErrors];
86
- },
87
- [[], [], []],
88
- );
89
-
90
- // Ejecutar onError si hay errores y el callback está definido
91
- if (fileErrors.length > 0 && onError) {
92
- onError(fileErrors);
93
- }
94
-
95
- return [rejected, accepted, fileErrors];
96
- };
97
-
98
- const handleDrop = useCallback(
99
- (e: React.DragEvent<HTMLDivElement>) => {
100
- e.preventDefault();
101
- e.stopPropagation();
102
- setIsDragActive(false);
103
-
104
- const newFiles = Array.from(e.dataTransfer.files);
105
- const [rejected = [], accepted = []] = validateFiles(newFiles);
106
-
107
- onDrop(accepted, rejected);
108
- },
109
- [allowedExtensions, maxFileSize, maxFiles, onDrop, onError],
110
- );
111
-
112
- return {
113
- isDragActive,
114
- validateFiles,
115
- dropzoneProps: {
116
- onDragOver: handleDragOver,
117
- onDragEnter: handleDragEnter,
118
- onDragLeave: handleDragLeave,
119
- onDrop: handleDrop,
120
- },
121
- };
122
- };
@@ -1,56 +0,0 @@
1
- import { Meta, StoryObj } from "@storybook/react-vite";
2
- import { MessageSquareMore } from "lucide-react";
3
- import { Button, EmptyState, Stack } from "../../components";
4
-
5
- /**
6
- * El componente EmptyState proporciona una interfaz visual para mostrar cuando no hay datos o contenido disponible.
7
- *
8
- * ### Características principales
9
- * - Soporte para íconos personalizados
10
- * - Título y descripción configurables
11
- * - Capacidad de agregar acciones mediante children
12
- */
13
- const meta: Meta<typeof EmptyState> = {
14
- title: "others/EmptyState",
15
- component: EmptyState,
16
- args: {
17
- title: "No hay resultados",
18
- description: "Intenta buscar algo diferente",
19
- },
20
- argTypes: {
21
- icon: {
22
- control: false,
23
- },
24
- children: {
25
- control: false,
26
- },
27
- },
28
- };
29
-
30
- export default meta;
31
-
32
- type Story = StoryObj<typeof EmptyState>;
33
-
34
- /**
35
- * Ejemplo básico del EmptyState con título y descripción
36
- */
37
- export const Default: Story = {};
38
-
39
- /**
40
- * Ejemplo con ícono personalizado y botones de acción.
41
- * Demuestra cómo agregar interactividad al estado vacío.
42
- */
43
- export const Actions: Story = {
44
- render: () => (
45
- <EmptyState
46
- icon={<MessageSquareMore className="h-12 w-12" />}
47
- title="No tienes mensajes"
48
- description="Intenta crear uno nuevo"
49
- >
50
- <Stack>
51
- <Button variant="outline">Importar</Button>
52
- <Button>Crear nuevo</Button>
53
- </Stack>
54
- </EmptyState>
55
- ),
56
- };
@@ -1,39 +0,0 @@
1
- import { FolderSearch } from "lucide-react";
2
- import { ComponentPropsWithoutRef, ReactNode } from "react";
3
- import { cn } from "../../lib";
4
- import { Heading } from "../heading";
5
-
6
- type Props = ComponentPropsWithoutRef<"div"> & {
7
- icon?: ReactNode;
8
- title?: ReactNode;
9
- description?: ReactNode;
10
- };
11
-
12
- export const EmptyState = ({
13
- icon = <FolderSearch className="w-12 h-12" />,
14
- title = "No hay resultados",
15
- description,
16
- className,
17
- children,
18
- ...props
19
- }: Props) => (
20
- <div
21
- className={cn("flex flex-col gap-2 justify-center items-center", className)}
22
- data-slot="empty-state"
23
- {...props}
24
- >
25
- <div className="text-muted-foreground" data-slot="empty-state-icon">
26
- {icon}
27
- </div>
28
- <Heading className="empty:hidden" data-slot="empty-state-title">
29
- {title}
30
- </Heading>
31
- <p
32
- className="py-1 text-sm text-center text-muted-foreground empty:hidden"
33
- data-slot="empty-state-description"
34
- >
35
- {description}
36
- </p>
37
- {children}
38
- </div>
39
- );
@@ -1 +0,0 @@
1
- export * from "./empty-state";
@@ -1,74 +0,0 @@
1
- import { faker } from "@faker-js/faker";
2
- import { Meta, StoryObj } from "@storybook/react-vite";
3
- import { Heading } from "../../components";
4
-
5
- const meta: Meta<typeof Heading> = {
6
- title: "typography/Heading",
7
- component: Heading,
8
- args: {
9
- children: faker.lorem.sentence(),
10
- },
11
- argTypes: {
12
- children: {
13
- control: false,
14
- },
15
- size: {
16
- options: ["sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl"],
17
- control: { type: "select" },
18
- defaultValue: "xl",
19
- description: "The font size of the heading. xl is the default.",
20
- },
21
- weight: {
22
- options: ["normal", "medium", "semibold", "bold"],
23
- control: { type: "select" },
24
- defaultValue: "semibold",
25
- description: "The font weight of the heading. semibold is the default.",
26
- },
27
- },
28
- };
29
-
30
- export default meta;
31
-
32
- type Story = StoryObj<typeof Heading>;
33
-
34
- export const Default: Story = {};
35
-
36
- export const Sizes: Story = {
37
- render: () => (
38
- <>
39
- <Heading size="sm">Heading sm (14px)</Heading>
40
- <Heading size="md">Heading md (16px)</Heading>
41
- <Heading size="lg">Heading lg (18px)</Heading>
42
- <Heading size="xl">Heading xl (20px)</Heading>
43
- <Heading size="2xl">Heading 2xl (24px)</Heading>
44
- <Heading size="3xl">Heading 3xl (28px)</Heading>
45
- <Heading size="4xl">Heading 4xl (32px)</Heading>
46
- <Heading size="5xl">Heading 5xl (36px)</Heading>
47
- <Heading size="6xl">Heading 6xl (40px)</Heading>
48
- </>
49
- ),
50
- };
51
-
52
- export const Weights: Story = {
53
- render: () => (
54
- <>
55
- <Heading weight="normal">Heading normal</Heading>
56
- <Heading weight="medium">Heading medium</Heading>
57
- <Heading weight="semibold">Heading semibold</Heading>
58
- <Heading weight="bold">Heading bold</Heading>
59
- </>
60
- ),
61
- };
62
-
63
- export const As: Story = {
64
- render: () => (
65
- <>
66
- <Heading as="h1">Heading as h1</Heading>
67
- <Heading as="h2">Heading as h2</Heading>
68
- <Heading as="h3">Heading as h3</Heading>
69
- <Heading as="h4">Heading as h4</Heading>
70
- <Heading as="h5">Heading as h5</Heading>
71
- <Heading as="h6">Heading as h6</Heading>
72
- </>
73
- ),
74
- };
@@ -1,28 +0,0 @@
1
- import { VariantProps } from "class-variance-authority";
2
- import { cn } from "../../lib";
3
- import { HeadingVariants } from "./heading.variants";
4
-
5
- type Props<C extends React.ElementType> = VariantProps<
6
- typeof HeadingVariants
7
- > & {
8
- as?: C;
9
- } & Omit<React.ComponentPropsWithoutRef<C>, "as">;
10
-
11
- export const Heading = <C extends React.ElementType = "h2">({
12
- className,
13
- size,
14
- weight,
15
- as,
16
- ...props
17
- }: Props<C>) => {
18
- const Comp = as || "h2";
19
- return (
20
- <Comp
21
- className={cn(HeadingVariants({ size, weight }), className)}
22
- {...props}
23
- data-slot="heading"
24
- data-size={size}
25
- data-weight={weight}
26
- />
27
- );
28
- };
@@ -1,27 +0,0 @@
1
- import { cva } from "class-variance-authority";
2
-
3
- export const HeadingVariants = cva([], {
4
- variants: {
5
- size: {
6
- sm: "text-[14px]",
7
- md: "text-[16px]",
8
- lg: "text-[18px]",
9
- xl: "text-[20px]",
10
- "2xl": "text-[24px]",
11
- "3xl": "text-[28px]",
12
- "4xl": "text-[32px]",
13
- "5xl": "text-[36px]",
14
- "6xl": "text-[40px]",
15
- },
16
- weight: {
17
- normal: "font-normal",
18
- medium: "font-medium",
19
- semibold: "font-semibold",
20
- bold: "font-bold",
21
- },
22
- },
23
- defaultVariants: {
24
- size: "xl",
25
- weight: "semibold",
26
- },
27
- });
@@ -1 +0,0 @@
1
- export * from "./heading";
@@ -1,26 +0,0 @@
1
- import { cva } from "class-variance-authority";
2
-
3
- export const KbdVariants = cva(
4
- [
5
- "inline-flex select-none items-center gap-1 rounded border bg-muted px-1.5 font-medium text-muted-foreground",
6
- ],
7
- {
8
- variants: {
9
- variant: {
10
- default: "border-transparent bg-secondary text-secondary-foreground",
11
- secondary: "border-transparent bg-primary text-primary-foreground",
12
- error: "border-transparent bg-error text-error-foreground",
13
- outline: "text-foreground",
14
- },
15
- size: {
16
- default: "px-1.5 py-0.5 text-xs",
17
- sm: "px-2 py-0.5 text-sm",
18
- lg: "px-4 py-1 text-lg",
19
- },
20
- },
21
- defaultVariants: {
22
- variant: "default",
23
- size: "default",
24
- },
25
- },
26
- );
@@ -1,54 +0,0 @@
1
- import React from "react";
2
- import { MenuItemType } from "../menu";
3
- import {
4
- MenuCheckboxItem,
5
- MenuItem,
6
- MenuLabel,
7
- MenuRadioItem,
8
- MenuSeparator,
9
- MenuSub,
10
- MenuSubContent,
11
- MenuSubTrigger,
12
- } from "../menu-primitives";
13
-
14
- export const renderMenuItem = (item: MenuItemType, children?: any) => {
15
- switch (item.type) {
16
- case "item":
17
- return (
18
- <MenuItem {...item}>
19
- {item.label} {children}
20
- </MenuItem>
21
- );
22
- case "checkbox":
23
- return (
24
- <MenuCheckboxItem {...item}>
25
- {item.label} {children}
26
- </MenuCheckboxItem>
27
- );
28
- case "radio":
29
- return (
30
- <MenuRadioItem {...item}>
31
- {item.label} {children}
32
- </MenuRadioItem>
33
- );
34
- case "label":
35
- return <MenuLabel {...item}>{item.label} </MenuLabel>;
36
- case "separator":
37
- return <MenuSeparator {...item} />;
38
- case "submenu":
39
- return (
40
- <MenuSub>
41
- <MenuSubTrigger {...item}>{item.label}</MenuSubTrigger>
42
- <MenuSubContent>
43
- {item.items?.map((subItem, index) => (
44
- <React.Fragment key={index}>
45
- {renderMenuItem(subItem)}
46
- </React.Fragment>
47
- ))}
48
- </MenuSubContent>
49
- </MenuSub>
50
- );
51
- default:
52
- return null;
53
- }
54
- };
@@ -1,66 +0,0 @@
1
- type Props = {
2
- valueKey: string | number | symbol;
3
- values: string[];
4
- setValues: (values: string[]) => void;
5
- items: any[];
6
- maxCount: number;
7
- setIsPopoverOpen: (open: any) => void;
8
- };
9
-
10
- export const useMultiSelect = ({
11
- valueKey,
12
- values,
13
- setValues,
14
- items,
15
- maxCount,
16
- setIsPopoverOpen,
17
- }: Props) => {
18
- const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
19
- if (event.key === "Enter") {
20
- setIsPopoverOpen(true);
21
- } else if (event.key === "Backspace" && !event.currentTarget.value) {
22
- const newSelectedValues = [...values];
23
- newSelectedValues.pop();
24
- setValues?.(newSelectedValues);
25
- }
26
- };
27
-
28
- const toggleOption = (option: string) => {
29
- const newSelectedValues = values.includes(option)
30
- ? values.filter((value) => value !== option)
31
- : [...values, option];
32
- setValues?.(newSelectedValues);
33
- };
34
-
35
- const handleClear = () => {
36
- setValues?.([]);
37
- };
38
-
39
- const handleTogglePopover = () => {
40
- setIsPopoverOpen((prev: boolean) => !prev);
41
- };
42
-
43
- const clearExtraOptions = () => {
44
- const newSelectedValues = values.slice(0, maxCount);
45
- setValues?.(newSelectedValues);
46
- };
47
-
48
- const toggleAll = () => {
49
- const allowedItems = items.filter((option) => !option.disabled);
50
- if (values.length === allowedItems.length) {
51
- handleClear();
52
- } else {
53
- const allValues = allowedItems.map((option) => option[valueKey]);
54
- setValues?.(allValues);
55
- }
56
- };
57
-
58
- return {
59
- handleInputKeyDown,
60
- toggleOption,
61
- handleClear,
62
- handleTogglePopover,
63
- clearExtraOptions,
64
- toggleAll,
65
- };
66
- };
@@ -1 +0,0 @@
1
- export * from "./multi-select";