@boxcustodia/library 2.0.0-alpha.12 → 2.0.0-alpha.14

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 +1087 -720
  3. package/dist/index.es.js +7011 -56097
  4. package/dist/theme.css +1 -1
  5. package/package.json +34 -26
  6. package/src/__doc__/Examples.tsx +1 -1
  7. package/src/__doc__/Intro.mdx +3 -3
  8. package/src/__doc__/Tabs.mdx +112 -0
  9. package/src/__doc__/V2.mdx +1246 -0
  10. package/src/components/accordion/accordion.stories.tsx +143 -0
  11. package/src/components/accordion/accordion.tsx +135 -0
  12. package/src/components/accordion/index.ts +1 -0
  13. package/src/components/alert/alert.stories.tsx +24 -4
  14. package/src/components/alert/alert.tsx +17 -9
  15. package/src/components/alert-dialog/alert-dialog.stories.tsx +24 -0
  16. package/src/components/alert-dialog/alert-dialog.test.tsx +1 -1
  17. package/src/components/alert-dialog/alert-dialog.tsx +58 -10
  18. package/src/components/auto-complete/auto-complete.stories.tsx +616 -200
  19. package/src/components/auto-complete/auto-complete.tsx +420 -68
  20. package/src/components/auto-complete/index.ts +0 -1
  21. package/src/components/avatar/avatar.stories.tsx +162 -21
  22. package/src/components/avatar/avatar.tsx +79 -20
  23. package/src/components/button/button.stories.tsx +219 -294
  24. package/src/components/button/button.test.tsx +10 -17
  25. package/src/components/button/button.tsx +78 -19
  26. package/src/components/button/components/base-button.tsx +30 -53
  27. package/src/components/button/index.ts +0 -1
  28. package/src/components/calendar/calendar.stories.tsx +1 -1
  29. package/src/components/calendar/calendar.tsx +4 -4
  30. package/src/components/card/card.stories.tsx +141 -69
  31. package/src/components/card/card.tsx +155 -54
  32. package/src/components/center/center.stories.tsx +22 -39
  33. package/src/components/checkbox/checkbox.stories.tsx +25 -5
  34. package/src/components/checkbox/checkbox.tsx +76 -15
  35. package/src/components/checkbox-group/checkbox-group.stories.tsx +116 -28
  36. package/src/components/checkbox-group/checkbox-group.tsx +84 -3
  37. package/src/components/combobox/combobox.stories.tsx +33 -23
  38. package/src/components/combobox/combobox.tsx +99 -77
  39. package/src/components/date-picker/date-input.stories.tsx +14 -6
  40. package/src/components/date-picker/date-input.tsx +2 -2
  41. package/src/components/date-picker/date-picker.model.ts +13 -4
  42. package/src/components/date-picker/date-picker.stories.tsx +38 -12
  43. package/src/components/date-picker/date-picker.tsx +28 -14
  44. package/src/components/dialog/dialog.stories.tsx +18 -0
  45. package/src/components/dialog/dialog.test.tsx +1 -1
  46. package/src/components/dialog/dialog.tsx +51 -20
  47. package/src/components/divider/divider.stories.tsx +126 -51
  48. package/src/components/divider/divider.tsx +16 -16
  49. package/src/components/dropzone/dropzone.stories.tsx +71 -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 +165 -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 +227 -4
  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 +4 -4
  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 +276 -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 +31 -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 +154 -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 +29 -9
  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 +767 -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 +373 -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 +155 -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 +323 -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 +365 -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 +67 -37
  130. package/src/utils/index.ts +1 -1
  131. package/src/__doc__/Migration.mdx +0 -475
  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,294 +0,0 @@
1
- import { faker } from "@faker-js/faker";
2
- import { Meta, StoryObj } from "@storybook/react-vite";
3
- import { useState } from "react";
4
- import { Avatar, Button, MultiSelect } from "../../components";
5
-
6
- const generateRandomOption = () => ({
7
- label: faker.person.fullName(),
8
- value: faker.string.uuid(),
9
- });
10
-
11
- const items = faker.helpers.multiple(generateRandomOption, { count: 10 });
12
-
13
- const meta: Meta<typeof MultiSelect> = {
14
- title: "Data entry/MultiSelect",
15
- component: MultiSelect,
16
- args: {
17
- items,
18
- },
19
- parameters: {
20
- badges: ["new"],
21
- },
22
- };
23
-
24
- export default meta;
25
-
26
- type Story = StoryObj<typeof MultiSelect>;
27
-
28
- export const Default: Story = {
29
- args: {
30
- withCheckbox: false,
31
- defaultValue: [items[0].value],
32
- },
33
- };
34
-
35
- export const Primary: Story = {
36
- args: {
37
- variant: "primary",
38
- defaultValue: [items[0].value],
39
- },
40
- };
41
-
42
- export const Secondary: Story = {
43
- args: {
44
- variant: "secondary",
45
- defaultValue: [items[0].value],
46
- },
47
- };
48
-
49
- export const OnlyOptions: Story = {
50
- args: {
51
- showSelectAll: false,
52
- showSearch: false,
53
- defaultValue: [items[0].value],
54
- },
55
- };
56
-
57
- export const Destructive: Story = {
58
- args: {
59
- variant: "error",
60
- defaultValue: [items[0].value],
61
- },
62
- };
63
-
64
- /**
65
- * Por defecto el componente `MultiSelect` espera `items` con la siguiente interfaz
66
- *
67
- * ```tsx
68
- * interface Option = {
69
- * label: string;
70
- * value: string;
71
- * }
72
- * ```
73
- *
74
- * En caso de tener un objeto con otra interfaz utilizar la propiedad `valueKey` para identificar el valor y `labelKey` para identificar el label
75
- *
76
- * ```tsx
77
- * type Animal = {
78
- * key: string;
79
- * name: string;
80
- * emoji: string;
81
- * }
82
- *
83
- * const animals: Animal[] = [
84
- * { key: "cat", name: "Cat", emoji: "🐱" },
85
- * { key: "dog", name: "Dog", emoji: "🐶" },
86
- * ];
87
- *
88
- * <MultiSelect
89
- * valueKey="key"
90
- * labelKey="name"
91
- * items={animals}
92
- * />
93
- *
94
- * ```
95
- */
96
-
97
- export const CustomObject: Story = {
98
- render: () => {
99
- type Animal = {
100
- key: string;
101
- name: string;
102
- emoji: string;
103
- };
104
-
105
- const animals: Animal[] = [
106
- { key: "cat", name: "Cat", emoji: "🐱" },
107
- { key: "dog", name: "Dog", emoji: "🐶" },
108
- ];
109
-
110
- return (
111
- <MultiSelect<Animal>
112
- items={animals}
113
- valueKey="key"
114
- labelKey="name"
115
- renderOption={(item: Animal) => `${item.emoji} ${item.name}`}
116
- />
117
- );
118
- },
119
- };
120
-
121
- const dataDisabled = [
122
- {
123
- label: faker.person.fullName(),
124
- value: faker.string.uuid(),
125
- disabled: true,
126
- },
127
- {
128
- label: faker.person.fullName(),
129
- value: faker.string.uuid(),
130
- disabled: false,
131
- },
132
- {
133
- label: faker.person.fullName(),
134
- value: faker.string.uuid(),
135
- disabled: true,
136
- },
137
- {
138
- label: faker.person.fullName(),
139
- value: faker.string.uuid(),
140
- disabled: false,
141
- },
142
- ];
143
-
144
- /**
145
- * Se puede deshabilitar cada opción
146
- *
147
- * ```tsx
148
- * const data = [
149
- * {
150
- * label: faker.person.fullName(),
151
- * value: faker.string.uuid(),
152
- * disabled: true,
153
- * }
154
- * ]
155
- *
156
- * ```
157
- */
158
- export const WithDisabledOptions: Story = {
159
- args: {
160
- items: dataDisabled,
161
- },
162
- };
163
-
164
- const data = [
165
- {
166
- label: faker.person.fullName(),
167
- value: faker.string.uuid(),
168
- image: faker.image.avatar(),
169
- },
170
- {
171
- label: faker.person.fullName(),
172
- value: faker.string.uuid(),
173
- image: faker.image.avatar(),
174
- },
175
- {
176
- label: faker.person.fullName(),
177
- value: faker.string.uuid(),
178
- image: faker.image.avatar(),
179
- },
180
- {
181
- label: faker.person.fullName(),
182
- value: faker.string.uuid(),
183
- image: faker.image.avatar(),
184
- },
185
- ];
186
-
187
- /**
188
- * Se puede customizar el contenido que se renderiza por cada opción
189
- *
190
- * ```tsx
191
- * const data = [
192
- * {
193
- * label: faker.person.fullName(),
194
- * value: faker.string.uuid(),
195
- * image: faker.image.avatar(),
196
- * }
197
- * ]
198
- *
199
- * <MultiSelect
200
- * items={data}
201
- * renderOption={(option) => (
202
- * <div className="flex items-center gap-2">
203
- * <Avatar
204
- * src={option.image}
205
- * alt={option.label}
206
- * className="w-6 h-6"
207
- * />
208
- * {option.label}
209
- * </div>
210
- * )}
211
- * />
212
- * ```
213
- */
214
- export const CustomRender: Story = {
215
- args: {
216
- items: data,
217
- renderOption: (option) => (
218
- <div className="flex items-center gap-2">
219
- <Avatar src={option.image} alt={option.label} className="w-6 h-6" />
220
- {option.label}
221
- </div>
222
- ),
223
- },
224
- };
225
-
226
- export const Disabled: Story = {
227
- args: {
228
- disabled: true,
229
- },
230
- };
231
-
232
- export const ControlledValue: Story = {
233
- args: {
234
- defaultValue: [items[0].value],
235
- },
236
- render: (args) => {
237
- const [value, setValue] = useState([items[0].value]);
238
- return (
239
- <div className="space-y-2">
240
- <div className="flex gap-2 items-center ">
241
- <Button onClick={() => setValue([items[0].value])}>
242
- Seleccionar primera opción
243
- </Button>
244
- <Button onClick={() => setValue([])}>Limpiar selección</Button>
245
- <Button onClick={() => setValue(items.map((item) => item.value))}>
246
- Seleccionar todas las opciones
247
- </Button>
248
- </div>
249
-
250
- <MultiSelect {...args} value={value} onChange={setValue} />
251
- <pre className="rounded-md bg-slate-950 p-4 text-white">
252
- <code className="block">
253
- Selected:{" "}
254
- <span className="text-blue-300">
255
- {JSON.stringify(value, null, 2)}
256
- </span>
257
- </code>
258
- </pre>
259
- </div>
260
- );
261
- },
262
- };
263
-
264
- /**
265
- * Se puede controlar el estado de apertura del popover
266
- *
267
- * ```tsx
268
- * type OpenProps = {
269
- * open?: boolean;
270
- * onOpenChange?: (open: boolean) => void;
271
- * defaultOpen?: boolean;
272
- * };
273
- * ```
274
- */
275
- export const ControlledOpen: Story = {
276
- render: () => {
277
- const [open, setOpen] = useState(false);
278
- return (
279
- <div className="space-y-2">
280
- <div className="flex gap-2 items-center">
281
- <Button onClick={() => setOpen(true)}>Abrir</Button>
282
- <Button onClick={() => setOpen(false)}>Cerrar</Button>
283
- </div>
284
-
285
- <MultiSelect
286
- open={open}
287
- onOpenChange={setOpen}
288
- items={items}
289
- defaultOpen
290
- />
291
- </div>
292
- );
293
- },
294
- };
@@ -1,300 +0,0 @@
1
- import { useControllableState } from "@radix-ui/react-use-controllable-state";
2
- import { type VariantProps } from "class-variance-authority";
3
- import { CheckIcon, ChevronsUpDown, XIcon } from "lucide-react";
4
- import * as React from "react";
5
- import { Option, OverrideProps } from "@/models";
6
- import { Tag } from "../../components/tag";
7
- import { cn } from "../../lib";
8
- import {
9
- AutoCompleteEmpty,
10
- AutoCompleteGroup,
11
- AutoCompleteInput,
12
- AutoCompleteItem,
13
- AutoCompleteList,
14
- AutoCompleteRoot,
15
- } from "../auto-complete";
16
- import { Divider } from "../divider";
17
- import { PopoverPopup, PopoverRoot, PopoverTrigger } from "../popover";
18
- import { useMultiSelect } from "./hooks/use-multi-select";
19
- import { multiSelectVariants } from "./multi-select.variants";
20
-
21
- type OpenProps = {
22
- open?: boolean;
23
- onOpenChange?: (open: boolean) => void;
24
- defaultOpen?: boolean;
25
- };
26
-
27
- type MultiSelectProps<TItem extends Record<string, any>> = OverrideProps<
28
- React.ButtonHTMLAttributes<HTMLButtonElement> &
29
- OpenProps &
30
- VariantProps<typeof multiSelectVariants>,
31
- {
32
- items: TItem[];
33
- /**
34
- * Identificador del valor del elemento
35
- * @default "value"
36
- */
37
- valueKey?: keyof TItem;
38
- /**
39
- * Identificador del label del elemento
40
- * @default "label"
41
- */
42
- value?: string[];
43
- onChange?: (value: string[]) => void;
44
- defaultValue?: string[];
45
- labelKey?: keyof TItem;
46
- placeholder?: string;
47
- /**
48
- * Cantidad máxima de elementos que se van a visualizar
49
- * @default 3
50
- */
51
- maxCount?: number;
52
- className?: string;
53
- renderOption?: (item: TItem) => React.ReactNode;
54
- withCheckbox?: boolean;
55
- /**
56
- * Para mostrar o no la barra de búsqueda
57
- * @default true
58
- */
59
- showSearch?: boolean;
60
- /**
61
- * Para mostrar o no el "Seleccionar todos"
62
- * @default true
63
- */
64
- showSelectAll?: boolean;
65
- /**
66
- * Props del PopoverRoot
67
- */
68
- rootProps?: React.ComponentPropsWithoutRef<typeof PopoverRoot>;
69
- }
70
- >;
71
-
72
- export const MultiSelect = <TItem extends Record<string, any> = Option>({
73
- items = [],
74
- value,
75
- valueKey = "value" as keyof TItem,
76
- labelKey = "label" as keyof TItem,
77
- onChange,
78
- variant,
79
- defaultValue = [],
80
- placeholder = "Seleccionar",
81
- maxCount = 3,
82
- className,
83
- renderOption = (item: TItem) => item[labelKey],
84
- withCheckbox = false,
85
- showSearch = true,
86
- showSelectAll = true,
87
- rootProps,
88
- ...props
89
- }: MultiSelectProps<TItem>) => {
90
- const [values = [], setValues] = useControllableState<string[]>({
91
- prop: value,
92
- onChange: onChange,
93
- defaultProp: defaultValue,
94
- });
95
-
96
- const [isPopoverOpen, setIsPopoverOpen] = useControllableState({
97
- prop: props.open,
98
- onChange: props.onOpenChange,
99
- defaultProp: props.defaultOpen || false,
100
- });
101
-
102
- const allowedOptions = React.useMemo(
103
- () => items.filter((i: TItem): boolean => !i.disabled),
104
- [items],
105
- );
106
-
107
- const {
108
- handleInputKeyDown,
109
- toggleOption,
110
- handleClear,
111
- handleTogglePopover,
112
- clearExtraOptions,
113
- toggleAll,
114
- } = useMultiSelect({
115
- valueKey,
116
- values,
117
- setValues,
118
- items,
119
- maxCount,
120
- setIsPopoverOpen,
121
- });
122
-
123
- return (
124
- <PopoverRoot
125
- open={isPopoverOpen}
126
- onOpenChange={setIsPopoverOpen}
127
- data-slot="multi-select"
128
- {...rootProps}
129
- >
130
- <PopoverTrigger
131
- {...(props as React.ButtonHTMLAttributes<HTMLButtonElement>)}
132
- data-slot="multi-select-trigger"
133
- onClick={handleTogglePopover}
134
- className={cn(
135
- "flex w-full p-1 rounded-md border border-input min-h-10 h-auto items-center justify-between bg-inherit hover:bg-inherit",
136
- className,
137
- )}
138
- >
139
- {values.length > 0 ? (
140
- <div className="flex justify-between items-center w-full">
141
- <div
142
- className="flex flex-wrap items-center"
143
- data-slot="multi-select-tags"
144
- >
145
- {values.slice(0, maxCount).map((value) => {
146
- const option = items.find((o) => o[valueKey] === value);
147
- const IconComponent = option?.icon;
148
- return (
149
- <Tag
150
- key={value}
151
- data-slot="multi-select-tag"
152
- className={cn(multiSelectVariants({ variant }))}
153
- closable
154
- onClose={() => toggleOption(value)}
155
- >
156
- {IconComponent && (
157
- <IconComponent className="h-4 w-4 mr-2" />
158
- )}
159
- {option && renderOption?.(option)}
160
- </Tag>
161
- );
162
- })}
163
- {values.length > maxCount && (
164
- <Tag
165
- data-slot="multi-select-tag"
166
- className={cn(multiSelectVariants({ variant }))}
167
- closable
168
- onClose={clearExtraOptions}
169
- >
170
- {`+ ${values.length - maxCount} más`}
171
- </Tag>
172
- )}
173
- </div>
174
- <div className="flex items-center justify-between">
175
- <XIcon
176
- data-slot="multi-select-clear"
177
- className="h-4 mx-2 cursor-pointer text-muted-foreground"
178
- onClick={(event) => {
179
- event.stopPropagation();
180
- handleClear();
181
- }}
182
- />
183
- <Divider
184
- data-slot="multi-select-divider"
185
- orientation="vertical"
186
- className="flex min-h-6 h-full"
187
- />
188
- <ChevronsUpDown
189
- data-slot="multi-select-trigger-icon"
190
- className="h-4 mx-2 cursor-pointer text-muted-foreground"
191
- />
192
- </div>
193
- </div>
194
- ) : (
195
- <div
196
- className="flex items-center justify-between w-full mx-auto"
197
- data-slot="multi-select-trigger-empty"
198
- >
199
- <span
200
- className="text-sm text-foreground font-normal mx-2"
201
- data-slot="multi-select-placeholder"
202
- >
203
- {placeholder}
204
- </span>
205
- <ChevronsUpDown
206
- data-slot="multi-select-trigger-icon"
207
- className="h-4 cursor-pointer text-muted-foreground mx-2"
208
- />
209
- </div>
210
- )}
211
- </PopoverTrigger>
212
- <PopoverPopup
213
- data-slot="multi-select-content"
214
- className="p-0 min-w-(--anchor-width)"
215
- align="start"
216
- >
217
- <AutoCompleteRoot>
218
- {showSearch && (
219
- <AutoCompleteInput
220
- data-slot="multi-select-input"
221
- placeholder="Buscar..."
222
- onKeyDown={handleInputKeyDown}
223
- />
224
- )}
225
- <AutoCompleteList data-slot="multi-select-list">
226
- <AutoCompleteEmpty data-slot="multi-select-empty">
227
- No results found.
228
- </AutoCompleteEmpty>
229
- <AutoCompleteGroup data-slot="multi-select-group">
230
- {showSelectAll && (
231
- <AutoCompleteItem
232
- data-slot="multi-select-item"
233
- key="all"
234
- onSelect={toggleAll}
235
- className={cn(
236
- "cursor-pointer",
237
- !withCheckbox &&
238
- values.length === allowedOptions.length &&
239
- "bg-accent text-accent-foreground",
240
- )}
241
- >
242
- {withCheckbox && (
243
- <div
244
- className={cn(
245
- "mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary",
246
- values.length === allowedOptions.length
247
- ? "bg-primary text-primary-foreground"
248
- : "opacity-50 [&_svg]:invisible",
249
- )}
250
- >
251
- <CheckIcon className="h-4 w-4" />
252
- </div>
253
- )}
254
- <span>(Seleccionar todo)</span>
255
- </AutoCompleteItem>
256
- )}
257
- {items.map((option) => {
258
- const isSelected = values.includes(option[valueKey]);
259
- return (
260
- <AutoCompleteItem
261
- data-slot="multi-select-item"
262
- key={option[valueKey]}
263
- onSelect={() =>
264
- !option.disabled && toggleOption(option[valueKey])
265
- }
266
- className={cn(
267
- option.disabled
268
- ? "!bg-neutral-50 !text-neutral-400"
269
- : "cursor-pointer",
270
- !withCheckbox &&
271
- isSelected &&
272
- "!bg-accent !text-accent-foreground",
273
- )}
274
- >
275
- {withCheckbox && (
276
- <div
277
- className={cn(
278
- "mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary",
279
- isSelected
280
- ? "bg-primary text-primary-foreground"
281
- : "opacity-50 [&_svg]:invisible",
282
- )}
283
- >
284
- <CheckIcon className="h-4 w-4" />
285
- </div>
286
- )}
287
- {option.icon && (
288
- <option.icon className="mr-2 h-4 w-4 text-muted-foreground" />
289
- )}
290
- <span>{renderOption?.(option)}</span>
291
- </AutoCompleteItem>
292
- );
293
- })}
294
- </AutoCompleteGroup>
295
- </AutoCompleteList>
296
- </AutoCompleteRoot>
297
- </PopoverPopup>
298
- </PopoverRoot>
299
- );
300
- };
@@ -1,22 +0,0 @@
1
- import { cva } from "class-variance-authority";
2
-
3
- export const multiSelectVariants = cva(
4
- "m-1 transition ease-in-out delay-150 duration-300",
5
- {
6
- variants: {
7
- variant: {
8
- default:
9
- "border-foreground/10 border text-foreground bg-card hover:bg-card/80",
10
- primary:
11
- "border-foreground/10 border text-foreground bg-primary text-primary-foreground hover:bg-primary/80",
12
- secondary:
13
- "border-foreground/60 border bg-secondary text-secondary-foreground hover:bg-secondary/80",
14
- error:
15
- "border-transparent bg-error text-error-foreground hover:bg-error/80",
16
- },
17
- },
18
- defaultVariants: {
19
- variant: "default",
20
- },
21
- },
22
- );
@@ -1,27 +0,0 @@
1
- import { ButtonHTMLAttributes } from "react";
2
- import { DOTS } from "../../../hooks";
3
- import { cn } from "../../../lib";
4
-
5
- interface PaginationOptionProps
6
- extends ButtonHTMLAttributes<HTMLButtonElement> {
7
- isActive?: boolean;
8
- }
9
-
10
- const PaginationOption = ({
11
- isActive = false,
12
- ...props
13
- }: PaginationOptionProps) => (
14
- <button
15
- {...props}
16
- data-slot="pagination-option"
17
- data-active={isActive}
18
- data-dots={props.children === DOTS}
19
- className={cn(
20
- "transition-colors border py-2 px-4 w-[50px] h-full data-[active=false]:hover:bg-accent",
21
- "data-[active=true]:bg-primary data-[active=true]:text-primary-foreground data-[active=true]:border-transparent data-[active=true]:hover:bg-primary/90",
22
- props.className,
23
- )}
24
- />
25
- );
26
-
27
- export { PaginationOption, type PaginationOptionProps };
@@ -1 +0,0 @@
1
- export * from "./show";