@foi/design-system 0.0.19 → 0.0.21

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 (46) hide show
  1. package/README.md +293 -241
  2. package/dist/{DatePicker.utils-BAUVa26Q.js → DatePicker.utils-D6aKFBuv.js} +1 -1
  3. package/dist/{DatePicker.utils-BAUVa26Q.js.map → DatePicker.utils-D6aKFBuv.js.map} +1 -1
  4. package/dist/{IconButton-C3x-E-ot.js → Toast-CBlo7bSf.js} +457 -296
  5. package/dist/Toast-CBlo7bSf.js.map +1 -0
  6. package/dist/components/atoms/Badge/Badge.d.ts +4 -0
  7. package/dist/components/atoms/Badge/Badge.emotion.d.ts +3 -0
  8. package/dist/components/atoms/Badge/Badge.interface.d.ts +16 -0
  9. package/dist/components/atoms/Badge/index.d.ts +5 -0
  10. package/dist/hocs/ThemeProvider/components/atoms/Badge.d.ts +13 -0
  11. package/dist/hocs/ThemeProvider/components/index.d.ts +2 -1
  12. package/dist/hocs/ThemeProvider/interfaces/Components.interface.d.ts +1 -0
  13. package/dist/hooks.mjs +1 -2
  14. package/dist/index.d.ts +16 -13
  15. package/dist/index.mjs +5698 -536
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/theme/dark/components/atoms/Badge.d.ts +13 -0
  18. package/dist/theme/dark/components/index.d.ts +10 -0
  19. package/dist/theme/dark/index.d.ts +10 -0
  20. package/dist/theme/index.d.ts +10 -0
  21. package/dist/{theme-BjrtNRDQ.js → theme-CXMwXBVS.js} +51 -47
  22. package/dist/theme-CXMwXBVS.js.map +1 -0
  23. package/dist/theme.d.ts +23 -0
  24. package/dist/theme.mjs +1 -1
  25. package/dist/utilities.mjs +1 -1
  26. package/package.json +1 -13
  27. package/dist/IconButton-C3x-E-ot.js.map +0 -1
  28. package/dist/RadioGroup-Cvt9MtvM.js +0 -456
  29. package/dist/RadioGroup-Cvt9MtvM.js.map +0 -1
  30. package/dist/RadioGroup.context-v_CCYB7_.js +0 -392
  31. package/dist/RadioGroup.context-v_CCYB7_.js.map +0 -1
  32. package/dist/Switch-6eNmT34-.js +0 -4196
  33. package/dist/Switch-6eNmT34-.js.map +0 -1
  34. package/dist/ThemeProvider-C_PzAJz3.js +0 -44
  35. package/dist/ThemeProvider-C_PzAJz3.js.map +0 -1
  36. package/dist/Toast-_9W7YGxS.js +0 -146
  37. package/dist/Toast-_9W7YGxS.js.map +0 -1
  38. package/dist/atoms.d.ts +0 -21
  39. package/dist/atoms.mjs +0 -4
  40. package/dist/hocs.d.ts +0 -2
  41. package/dist/hocs.mjs +0 -2
  42. package/dist/molecules.d.ts +0 -10
  43. package/dist/molecules.mjs +0 -3
  44. package/dist/theme-BjrtNRDQ.js.map +0 -1
  45. package/dist/useStateCallback-B4O93zzK.js +0 -32
  46. package/dist/useStateCallback-B4O93zzK.js.map +0 -1
package/README.md CHANGED
@@ -44,6 +44,7 @@ npm publish --access public
44
44
 
45
45
  | Component | Description |
46
46
  | ------------- | ------------------------------------------------------------------------------------------ |
47
+ | `Badge` | Notification indicator that wraps any element — shows a count, overflow cap, or dot |
47
48
  | `Button` | Primary action button with variant/size/color support |
48
49
  | `Checkbox` | Single checkbox — standalone, RHF, or inside a group |
49
50
  | `Chip` | Compact inline label for statuses and tags — themed variants, accepts text or ReactNode |
@@ -83,9 +84,7 @@ All field components share the same integration pattern. Define a Zod schema, pa
83
84
  import { useForm } from 'react-hook-form';
84
85
  import { zodResolver } from '@hookform/resolvers/zod';
85
86
  import { z } from 'zod';
86
- import TextField from '@components/atoms/TextField';
87
- import NumberField from '@components/atoms/NumberField';
88
- import Button from '@components/atoms/Button';
87
+ import { TextField, NumberField, Button } from '@foi/design-system';
89
88
 
90
89
  const schema = z.object({
91
90
  email: z.string().email('Invalid email'),
@@ -164,8 +163,7 @@ A text input field with a floating label, helper text, and full error state inte
164
163
  ### Example
165
164
 
166
165
  ```tsx
167
- import TextField from '@components/atoms/TextField';
168
- import Icon from '@components/atoms/Icon';
166
+ import { TextField, Icon } from '@foi/design-system';
169
167
 
170
168
  <TextField
171
169
  name='email'
@@ -209,7 +207,7 @@ All `TextField` props apply except `type`, `endAdornment`, and `startAdornment`
209
207
  ### Example
210
208
 
211
209
  ```tsx
212
- import NumberField from '@components/atoms/NumberField';
210
+ import { NumberField } from '@foi/design-system';
213
211
 
214
212
  // Standard — quantity picker with bounds
215
213
  <NumberField
@@ -237,8 +235,8 @@ import NumberField from '@components/atoms/NumberField';
237
235
  Wrap your app in `ThemeProvider` and pass one or more named themes. The active theme is selected by the `theme` prop and its tokens are injected as CSS custom properties that every component consumes.
238
236
 
239
237
  ```tsx
240
- import ThemeProvider from '@hocs/ThemeProvider';
241
- import darkTheme from './themes/dark';
238
+ import { ThemeProvider } from '@foi/design-system';
239
+ import { darkTheme } from '@foi/design-system/theme';
242
240
 
243
241
  <ThemeProvider themes={[darkTheme]} theme='dark'>
244
242
  <App />
@@ -254,32 +252,32 @@ Each variant contains:
254
252
  - `ROOT` — static styles applied unconditionally (e.g. `border-radius`, `background-color`)
255
253
  - `EVENTS` — styles scoped to interaction states. The complete set of possible states is:
256
254
 
257
- | State | Description |
258
- | --- | --- |
259
- | `ENABLED` | Default resting state — element is interactive and fully visible |
260
- | `VALUE` | The filled or selected part of the element (e.g. track fill, typed text colour) |
261
- | `HOVER` | While the pointer is over the element |
262
- | `ACTIVE` | While the element is being pressed |
263
- | `FOCUS` | When the element has keyboard focus |
264
- | `ERROR` | Container styles when validation fails |
265
- | `ERROR_VALUE` | Value part when in error state |
266
- | `ERROR_HOVER` | Hover while in error state |
267
- | `ERROR_ACTIVE` | Press while in error state |
268
- | `ERROR_FOCUS` | Focus while in error state |
269
- | `DISABLED` | When the element is not interactive |
270
- | `DISABLED_VALUE` | Value part when disabled |
271
- | `LOADING` | During a pending async operation |
272
- | `LOADING_VALUE` | Value part during loading |
255
+ | State | Description |
256
+ | ---------------- | ------------------------------------------------------------------------------- |
257
+ | `ENABLED` | Default resting state — element is interactive and fully visible |
258
+ | `VALUE` | The filled or selected part of the element (e.g. track fill, typed text colour) |
259
+ | `HOVER` | While the pointer is over the element |
260
+ | `ACTIVE` | While the element is being pressed |
261
+ | `FOCUS` | When the element has keyboard focus |
262
+ | `ERROR` | Container styles when validation fails |
263
+ | `ERROR_VALUE` | Value part when in error state |
264
+ | `ERROR_HOVER` | Hover while in error state |
265
+ | `ERROR_ACTIVE` | Press while in error state |
266
+ | `ERROR_FOCUS` | Focus while in error state |
267
+ | `DISABLED` | When the element is not interactive |
268
+ | `DISABLED_VALUE` | Value part when disabled |
269
+ | `LOADING` | During a pending async operation |
270
+ | `LOADING_VALUE` | Value part during loading |
273
271
 
274
272
  Not every component uses all states — each component defines only the states relevant to its interaction model. The TypeScript type exported from the component's theme file tells you exactly which states are available:
275
273
 
276
274
  ```ts
277
- import type { EVENTS } from '@hocs/ThemeProvider/components/atoms/Button';
278
- // Autocomplete will show only the states Button actually supports
275
+ import type { BUTTON } from '@foi/design-system/theme';
276
+ // BUTTON includes the EVENTS type — autocomplete shows only the states Button supports
279
277
  ```
280
278
 
281
279
  ```ts
282
- import type { BUTTON } from '@hocs/ThemeProvider/components/atoms/Button';
280
+ import type { BUTTON } from '@foi/design-system/theme';
283
281
 
284
282
  const component = {
285
283
  BUTTON: {
@@ -347,8 +345,8 @@ An async data table that delegates all data operations to the server via `onFetc
347
345
  ### Defining columns
348
346
 
349
347
  ```tsx
350
- import DataGrid from '@components/organisms/DataGrid';
351
- import type { DataGridColumn } from '@components/organisms/DataGrid';
348
+ import { DataGrid } from '@foi/design-system';
349
+ import type { DataGridColumn } from '@foi/design-system';
352
350
 
353
351
  interface Product {
354
352
  id: number;
@@ -375,7 +373,7 @@ const columns: DataGridColumn<Product>[] = [
375
373
  `label` accepts any `ReactNode`. A plain string is automatically wrapped in the themed `--DATAGRID-thLabel` span so it inherits the header typography. Pass a custom node to render icons, badges, or anything else without that wrapper:
376
374
 
377
375
  ```tsx
378
- import Icon from '@components/atoms/Icon';
376
+ import { Icon } from '@foi/design-system';
379
377
 
380
378
  {
381
379
  key: 'price',
@@ -441,9 +439,7 @@ A portal-based overlay dialog. Renders into `document.body` so it sits above all
441
439
  ### Basic usage
442
440
 
443
441
  ```tsx
444
- import Modal from '@components/molecules/Modal';
445
- import Button from '@components/atoms/Button';
446
- import Icon from '@components/atoms/Icon';
442
+ import { Modal, Button, Icon } from '@foi/design-system';
447
443
 
448
444
  const [open, setOpen] = useState(false);
449
445
 
@@ -493,29 +489,86 @@ Apply `--MODAL-title` to the title element inside `header` to receive the themed
493
489
  | Backdrop click | ✓ | — |
494
490
  | Escape key | ✓ | — |
495
491
 
492
+ ## Badge
493
+
494
+ Wraps any element and overlays a small indicator at one of its corners. Renders a numeric count, a capped overflow label (`max+`), or a plain dot.
495
+
496
+ ### Props
497
+
498
+ | Prop | Type | Default | Description |
499
+ | ---------- | -------------------------------------------------------------- | ------------- | ------------------------------------------------- |
500
+ | `children` | `ReactNode` | — | Element to wrap |
501
+ | `count` | `number` | — | Number to display; hidden when `0` or `undefined` |
502
+ | `max` | `number` | — | Cap value — shows `max+` when `count` exceeds it |
503
+ | `dot` | `boolean` | `false` | Show a small dot instead of a number |
504
+ | `position` | `'top-right' \| 'top-left' \| 'bottom-right' \| 'bottom-left'` | `'top-right'` | Corner where the indicator is placed |
505
+ | `variant` | `string` | `'default'` | Theme variant |
506
+ | `theme` | `EVENTS` | — | One-off token override |
507
+
508
+ The indicator animates in with a spring-scale effect on mount. The animation direction adapts automatically to the chosen `position`.
509
+
510
+ ### Example
511
+
512
+ ```tsx
513
+ import { Badge, IconButton, Icon } from '@foi/design-system';
514
+
515
+ // Count
516
+ <Badge count={5}>
517
+ <IconButton icon={<Icon name='notifications' />} onClick={openNotifications} />
518
+ </Badge>
519
+
520
+ // Overflow cap — displays "999+"
521
+ <Badge count={1200} max={999}>
522
+ <IconButton icon={<Icon name='mail' />} onClick={openMail} />
523
+ </Badge>
524
+
525
+ // Dot — no number
526
+ <Badge dot position='bottom-right'>
527
+ <IconButton icon={<Icon name='settings' />} onClick={openSettings} />
528
+ </Badge>
529
+ ```
530
+
531
+ ### Theming
532
+
533
+ ```ts
534
+ import type { BADGE } from '@foi/design-system/theme';
535
+
536
+ const badge = {
537
+ BADGE: {
538
+ DEFAULT: {
539
+ EVENTS: {
540
+ ENABLED: {
541
+ 'background-color': '#ef4444',
542
+ 'color-primary': '#ffffff',
543
+ },
544
+ },
545
+ },
546
+ },
547
+ } as const satisfies BADGE;
548
+ ```
549
+
496
550
  ## Button
497
551
 
498
552
  The primary interactive element. Accepts any `ReactNode` as children and natively supports all standard `<button>` HTML attributes.
499
553
 
500
554
  ### Props
501
555
 
502
- | Prop | Type | Default | Description |
503
- | ----------- | ---------------------- | ----------- | -------------------------------------------------------- |
504
- | `children` | `ReactNode` | — | Button label or content |
505
- | `type` | `'button' \| 'submit'` | `'button'` | HTML button type |
506
- | `iconStart` | `JSX.Element` | — | Icon rendered before the label |
507
- | `iconEnd` | `JSX.Element` | — | Icon rendered after the label |
508
- | `loading` | `boolean` | `false` | Shows a loading indicator; button stays mounted |
509
- | `disabled` | `boolean` | `false` | Prevents interaction |
510
- | `className` | `string` | — | Extra CSS class |
511
- | `variant` | `string` | `'default'` | Theme variant |
512
- | `theme` | `EVENTS` | — | One-off token override |
556
+ | Prop | Type | Default | Description |
557
+ | ----------- | ---------------------- | ----------- | ----------------------------------------------- |
558
+ | `children` | `ReactNode` | — | Button label or content |
559
+ | `type` | `'button' \| 'submit'` | `'button'` | HTML button type |
560
+ | `iconStart` | `JSX.Element` | — | Icon rendered before the label |
561
+ | `iconEnd` | `JSX.Element` | — | Icon rendered after the label |
562
+ | `loading` | `boolean` | `false` | Shows a loading indicator; button stays mounted |
563
+ | `disabled` | `boolean` | `false` | Prevents interaction |
564
+ | `className` | `string` | — | Extra CSS class |
565
+ | `variant` | `string` | `'default'` | Theme variant |
566
+ | `theme` | `EVENTS` | — | One-off token override |
513
567
 
514
568
  ### Example
515
569
 
516
570
  ```tsx
517
- import Button from '@components/atoms/Button';
518
- import Icon from '@components/atoms/Icon';
571
+ import { Button, Icon } from '@foi/design-system';
519
572
 
520
573
  <Button onClick={handleSave}>Guardar</Button>
521
574
  <Button type='submit' iconStart={<Icon name='send' />}>Enviar</Button>
@@ -529,18 +582,18 @@ Renders a single icon from the [Material Symbols Rounded](https://fonts.google.c
529
582
 
530
583
  ### Props
531
584
 
532
- | Prop | Type | Default | Description |
533
- | ----------- | ----------------------------- | -------- | ---------------------------------------- |
534
- | `name` | `string` | — | Material Symbols ligature name |
535
- | `fill` | `boolean` | `false` | Use the filled variant of the icon |
536
- | `size` | `'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Icon size |
537
- | `className` | `string` | — | Extra CSS class |
538
- | `style` | `CSSProperties` | — | Inline styles |
585
+ | Prop | Type | Default | Description |
586
+ | ----------- | ------------------------------ | ------- | ---------------------------------- |
587
+ | `name` | `string` | — | Material Symbols ligature name |
588
+ | `fill` | `boolean` | `false` | Use the filled variant of the icon |
589
+ | `size` | `'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Icon size |
590
+ | `className` | `string` | — | Extra CSS class |
591
+ | `style` | `CSSProperties` | — | Inline styles |
539
592
 
540
593
  ### Example
541
594
 
542
595
  ```tsx
543
- import Icon from '@components/atoms/Icon';
596
+ import { Icon } from '@foi/design-system';
544
597
 
545
598
  <Icon name='home' />
546
599
  <Icon name='search' size='lg' />
@@ -553,21 +606,20 @@ A button that renders a single icon with no visible text. Accepts all standard `
553
606
 
554
607
  ### Props
555
608
 
556
- | Prop | Type | Default | Description |
557
- | ----------- | ------------- | ----------- | ------------------------------------------------------ |
558
- | `icon` | `JSX.Element` | — | Icon element to render (use `<Icon />`) |
559
- | `onClick` | `function` | — | Click handler |
560
- | `isFlipped` | `boolean` | `false` | Mirrors the icon horizontally (useful for arrows) |
561
- | `disabled` | `boolean` | `false` | Prevents interaction |
562
- | `className` | `string` | — | Extra CSS class |
563
- | `variant` | `string` | `'default'` | Theme variant |
564
- | `theme` | `EVENTS` | — | One-off token override |
609
+ | Prop | Type | Default | Description |
610
+ | ----------- | ------------- | ----------- | ------------------------------------------------- |
611
+ | `icon` | `JSX.Element` | — | Icon element to render (use `<Icon />`) |
612
+ | `onClick` | `function` | — | Click handler |
613
+ | `isFlipped` | `boolean` | `false` | Mirrors the icon horizontally (useful for arrows) |
614
+ | `disabled` | `boolean` | `false` | Prevents interaction |
615
+ | `className` | `string` | — | Extra CSS class |
616
+ | `variant` | `string` | `'default'` | Theme variant |
617
+ | `theme` | `EVENTS` | — | One-off token override |
565
618
 
566
619
  ### Example
567
620
 
568
621
  ```tsx
569
- import IconButton from '@components/atoms/IconButton';
570
- import Icon from '@components/atoms/Icon';
622
+ import { IconButton, Icon } from '@foi/design-system';
571
623
 
572
624
  <IconButton icon={<Icon name='close' />} onClick={() => setOpen(false)} />
573
625
  <IconButton icon={<Icon name='arrow_forward' />} isFlipped onClick={goBack} />
@@ -579,31 +631,31 @@ A single checkbox. Can be used standalone (controlled or RHF), or as a child of
579
631
 
580
632
  ### Props
581
633
 
582
- | Prop | Type | Default | Description |
583
- | --------------- | ------------------------- | ----------- | ----------------------------------------------------- |
584
- | `name` | `string` | — | RHF field name (required in standalone RHF mode) |
585
- | `control` | `Control` | — | RHF control object |
586
- | `checked` | `boolean` | — | Controlled mode value (use with `onChecked`) |
587
- | `onChecked` | `(checked: boolean) => void` | — | Controlled mode change handler |
588
- | `label` | `string` | — | Text label next to the checkbox |
589
- | `icon` | `JSX.Element` | checkmark | Custom icon shown when checked |
590
- | `disabled` | `boolean` | `false` | Prevents interaction |
591
- | `helperText` | `string` | — | Hint text below the checkbox |
592
- | `showErrorText` | `boolean` | `true` | Show validation error message |
593
- | `variant` | `string` | `'default'` | Theme variant |
594
- | `theme` | `EVENTS` | — | One-off token override |
634
+ | Prop | Type | Default | Description |
635
+ | --------------- | ---------------------------- | ----------- | ------------------------------------------------ |
636
+ | `name` | `string` | — | RHF field name (required in standalone RHF mode) |
637
+ | `control` | `Control` | — | RHF control object |
638
+ | `checked` | `boolean` | — | Controlled mode value (use with `onChecked`) |
639
+ | `onChecked` | `(checked: boolean) => void` | — | Controlled mode change handler |
640
+ | `label` | `string` | — | Text label next to the checkbox |
641
+ | `icon` | `JSX.Element` | checkmark | Custom icon shown when checked |
642
+ | `disabled` | `boolean` | `false` | Prevents interaction |
643
+ | `helperText` | `string` | — | Hint text below the checkbox |
644
+ | `showErrorText` | `boolean` | `true` | Show validation error message |
645
+ | `variant` | `string` | `'default'` | Theme variant |
646
+ | `theme` | `EVENTS` | — | One-off token override |
595
647
 
596
648
  ### Example
597
649
 
598
650
  ```tsx
599
- import Checkbox from '@components/atoms/Checkbox';
651
+ import { Checkbox } from '@foi/design-system';
600
652
 
601
653
  // RHF
602
- <Checkbox name='agree' control={control} label='Acepto los términos' />
654
+ <Checkbox name='agree' control={control} label='Acepto los términos' />;
603
655
 
604
656
  // Controlled
605
657
  const [checked, setChecked] = useState(false);
606
- <Checkbox checked={checked} onChecked={setChecked} label='Recordarme' />
658
+ <Checkbox checked={checked} onChecked={setChecked} label='Recordarme' />;
607
659
  ```
608
660
 
609
661
  ## Radio
@@ -612,14 +664,14 @@ A single radio button. Always used inside `RadioGroup` — it receives its state
612
664
 
613
665
  ### Props
614
666
 
615
- | Prop | Type | Default | Description |
616
- | ----------- | ------------- | ----------- | ------------------------------------------------ |
617
- | `value` | `string` | — | The value this option represents |
618
- | `label` | `string` | — | Text label next to the radio |
619
- | `icon` | `JSX.Element` | filled dot | Custom icon shown when selected |
620
- | `disabled` | `boolean` | `false` | Overrides the group `disabled` for this item |
621
- | `variant` | `string` | `'default'` | Theme variant |
622
- | `theme` | `EVENTS` | — | One-off token override |
667
+ | Prop | Type | Default | Description |
668
+ | ---------- | ------------- | ----------- | -------------------------------------------- |
669
+ | `value` | `string` | — | The value this option represents |
670
+ | `label` | `string` | — | Text label next to the radio |
671
+ | `icon` | `JSX.Element` | filled dot | Custom icon shown when selected |
672
+ | `disabled` | `boolean` | `false` | Overrides the group `disabled` for this item |
673
+ | `variant` | `string` | `'default'` | Theme variant |
674
+ | `theme` | `EVENTS` | — | One-off token override |
623
675
 
624
676
  ## Select
625
677
 
@@ -627,34 +679,34 @@ A dropdown select field backed by a virtual-scroll list. Integrates with RHF and
627
679
 
628
680
  ### Props
629
681
 
630
- | Prop | Type | Default | Description |
631
- | ------------------ | --------------- | ----------- | --------------------------------------------------------- |
632
- | `name` | `string` | — | RHF field name |
633
- | `label` | `string` | — | Floating label |
634
- | `control` | `Control` | — | RHF control object |
635
- | `options` | `OptionProp[]` | — | List of `{ value, label, description? }` items |
636
- | `disabled` | `boolean` | `false` | Prevents interaction |
637
- | `range` | `number` | `100` | Options per page (virtual scroll activates above 3) |
638
- | `hasSearch` | `boolean` | `false` | Shows a search input — filters after 3 characters |
639
- | `hasDescription` | `boolean` | `false` | Renders a secondary description line per option |
640
- | `hasStaticOptions` | `boolean` | `false` | Renders dropdown inline (no absolute positioning) |
641
- | `helperText` | `string` | — | Hint text below the field |
642
- | `showErrorText` | `boolean` | `true` | Show validation error message |
643
- | `hasPadding` | `boolean` | `false` | Add bottom padding for helper/error text |
644
- | `variant` | `string` | `'default'` | Theme variant |
645
- | `theme` | `EVENTS` | — | One-off token override |
682
+ | Prop | Type | Default | Description |
683
+ | ------------------ | -------------- | ----------- | --------------------------------------------------- |
684
+ | `name` | `string` | — | RHF field name |
685
+ | `label` | `string` | — | Floating label |
686
+ | `control` | `Control` | — | RHF control object |
687
+ | `options` | `OptionProp[]` | — | List of `{ value, label, description? }` items |
688
+ | `disabled` | `boolean` | `false` | Prevents interaction |
689
+ | `range` | `number` | `100` | Options per page (virtual scroll activates above 3) |
690
+ | `hasSearch` | `boolean` | `false` | Shows a search input — filters after 3 characters |
691
+ | `hasDescription` | `boolean` | `false` | Renders a secondary description line per option |
692
+ | `hasStaticOptions` | `boolean` | `false` | Renders dropdown inline (no absolute positioning) |
693
+ | `helperText` | `string` | — | Hint text below the field |
694
+ | `showErrorText` | `boolean` | `true` | Show validation error message |
695
+ | `hasPadding` | `boolean` | `false` | Add bottom padding for helper/error text |
696
+ | `variant` | `string` | `'default'` | Theme variant |
697
+ | `theme` | `EVENTS` | — | One-off token override |
646
698
 
647
699
  ### Example
648
700
 
649
701
  ```tsx
650
- import Select from '@components/atoms/Select';
702
+ import { Select } from '@foi/design-system';
651
703
 
652
704
  const options = [
653
705
  { value: 'cl', label: 'Chile' },
654
706
  { value: 'ar', label: 'Argentina', description: 'Buenos Aires' },
655
707
  ];
656
708
 
657
- <Select name='country' control={control} label='País' options={options} hasSearch />
709
+ <Select name='country' control={control} label='País' options={options} hasSearch />;
658
710
  ```
659
711
 
660
712
  ## DatePicker
@@ -663,28 +715,28 @@ A date input field with an inline or floating calendar. Stores a `Date` value in
663
715
 
664
716
  ### Props
665
717
 
666
- | Prop | Type | Default | Description |
667
- | ------------------ | ---------------- | ----------- | -------------------------------------------------------- |
668
- | `name` | `string` | — | RHF field name |
669
- | `label` | `string` | — | Floating label |
670
- | `control` | `Control` | — | RHF control object |
671
- | `language` | `'es' \| 'en'` | browser | Date format and labels (`DD/MM/YYYY` vs `MM/DD/YYYY`) |
672
- | `minDate` | `Date` | — | Earliest selectable date |
673
- | `maxDate` | `Date` | — | Latest selectable date |
674
- | `disablePast` | `boolean` | `false` | Disables all dates before today |
675
- | `disableFuture` | `boolean` | `false` | Disables all dates after today |
676
- | `hasStaticOptions` | `boolean` | `false` | Renders calendar inline instead of floating |
677
- | `disabled` | `boolean` | `false` | Prevents interaction |
678
- | `helperText` | `string` | — | Hint text below the field |
679
- | `showErrorText` | `boolean` | `true` | Show validation error message |
680
- | `hasPadding` | `boolean` | `false` | Add bottom padding for helper/error text |
681
- | `variant` | `string` | `'default'` | Theme variant |
682
- | `theme` | `EVENTS` | — | One-off token override |
718
+ | Prop | Type | Default | Description |
719
+ | ------------------ | -------------- | ----------- | ----------------------------------------------------- |
720
+ | `name` | `string` | — | RHF field name |
721
+ | `label` | `string` | — | Floating label |
722
+ | `control` | `Control` | — | RHF control object |
723
+ | `language` | `'es' \| 'en'` | browser | Date format and labels (`DD/MM/YYYY` vs `MM/DD/YYYY`) |
724
+ | `minDate` | `Date` | — | Earliest selectable date |
725
+ | `maxDate` | `Date` | — | Latest selectable date |
726
+ | `disablePast` | `boolean` | `false` | Disables all dates before today |
727
+ | `disableFuture` | `boolean` | `false` | Disables all dates after today |
728
+ | `hasStaticOptions` | `boolean` | `false` | Renders calendar inline instead of floating |
729
+ | `disabled` | `boolean` | `false` | Prevents interaction |
730
+ | `helperText` | `string` | — | Hint text below the field |
731
+ | `showErrorText` | `boolean` | `true` | Show validation error message |
732
+ | `hasPadding` | `boolean` | `false` | Add bottom padding for helper/error text |
733
+ | `variant` | `string` | `'default'` | Theme variant |
734
+ | `theme` | `EVENTS` | — | One-off token override |
683
735
 
684
736
  ### Example
685
737
 
686
738
  ```tsx
687
- import DatePicker from '@components/atoms/DatePicker';
739
+ import { DatePicker } from '@foi/design-system';
688
740
 
689
741
  <DatePicker
690
742
  name='birthDate'
@@ -693,7 +745,7 @@ import DatePicker from '@components/atoms/DatePicker';
693
745
  language='es'
694
746
  disableFuture
695
747
  maxDate={new Date('2005-01-01')}
696
- />
748
+ />;
697
749
  ```
698
750
 
699
751
  ## Switch
@@ -702,23 +754,22 @@ A toggle switch that stores a `boolean` value in RHF.
702
754
 
703
755
  ### Props
704
756
 
705
- | Prop | Type | Default | Description |
706
- | ----------- | ---------- | ----------- | ------------------------------------------- |
707
- | `name` | `string` | — | RHF field name |
708
- | `control` | `Control` | — | RHF control object |
709
- | `label` | `string` | — | Text label next to the switch |
710
- | `iconOn` | `JSX.Element` | — | Icon on the thumb when on |
711
- | `iconOff` | `JSX.Element` | — | Icon on the thumb when off |
712
- | `disabled` | `boolean` | `false` | Prevents interaction |
713
- | `helperText`| `string` | — | Hint text below the switch |
714
- | `variant` | `string` | `'default'` | Theme variant |
715
- | `theme` | `EVENTS` | — | One-off token override |
757
+ | Prop | Type | Default | Description |
758
+ | ------------ | ------------- | ----------- | ----------------------------- |
759
+ | `name` | `string` | — | RHF field name |
760
+ | `control` | `Control` | — | RHF control object |
761
+ | `label` | `string` | — | Text label next to the switch |
762
+ | `iconOn` | `JSX.Element` | — | Icon on the thumb when on |
763
+ | `iconOff` | `JSX.Element` | — | Icon on the thumb when off |
764
+ | `disabled` | `boolean` | `false` | Prevents interaction |
765
+ | `helperText` | `string` | — | Hint text below the switch |
766
+ | `variant` | `string` | `'default'` | Theme variant |
767
+ | `theme` | `EVENTS` | — | One-off token override |
716
768
 
717
769
  ### Example
718
770
 
719
771
  ```tsx
720
- import Switch from '@components/atoms/Switch';
721
- import Icon from '@components/atoms/Icon';
772
+ import { Switch, Icon } from '@foi/design-system';
722
773
 
723
774
  <Switch
724
775
  name='notifications'
@@ -726,7 +777,7 @@ import Icon from '@components/atoms/Icon';
726
777
  label='Activar notificaciones'
727
778
  iconOn={<Icon name='notifications' />}
728
779
  iconOff={<Icon name='notifications_off' />}
729
- />
780
+ />;
730
781
  ```
731
782
 
732
783
  ## Slider
@@ -735,28 +786,28 @@ A range slider that stores a `number[]` value in RHF. Single-thumb mode uses a 1
735
786
 
736
787
  ### Props
737
788
 
738
- | Prop | Type | Default | Description |
739
- | ------------ | ------------------------------- | -------------- | ------------------------------------------------------ |
740
- | `name` | `string` | — | RHF field name |
741
- | `control` | `Control` | — | RHF control object |
742
- | `min` | `number` | — | Minimum value |
743
- | `max` | `number` | — | Maximum value (`Infinity` disables click-to-seek) |
744
- | `step` | `number` | `1` | Snap granularity |
745
- | `distance` | `number` | `0` | Minimum gap between thumbs (range mode only) |
746
- | `direction` | `'horizontal' \| 'vertical'` | `'horizontal'` | Slider orientation |
747
- | `track` | `'normal' \| 'inverted'` | `'normal'` | Fill direction of the track |
748
- | `showMarks` | `boolean` | `false` | Show a dot at every `step` position |
749
- | `iconMin` | `JSX.Element` | — | Icon inside the min/single thumb |
750
- | `iconMax` | `JSX.Element` | — | Icon inside the max thumb (range mode only) |
751
- | `helperText` | `string` | — | Hint text below the slider |
752
- | `disabled` | `boolean` | `false` | Prevents interaction |
753
- | `variant` | `string` | `'default'` | Theme variant |
754
- | `theme` | `EVENTS` | — | One-off token override |
789
+ | Prop | Type | Default | Description |
790
+ | ------------ | ---------------------------- | -------------- | ------------------------------------------------- |
791
+ | `name` | `string` | — | RHF field name |
792
+ | `control` | `Control` | — | RHF control object |
793
+ | `min` | `number` | — | Minimum value |
794
+ | `max` | `number` | — | Maximum value (`Infinity` disables click-to-seek) |
795
+ | `step` | `number` | `1` | Snap granularity |
796
+ | `distance` | `number` | `0` | Minimum gap between thumbs (range mode only) |
797
+ | `direction` | `'horizontal' \| 'vertical'` | `'horizontal'` | Slider orientation |
798
+ | `track` | `'normal' \| 'inverted'` | `'normal'` | Fill direction of the track |
799
+ | `showMarks` | `boolean` | `false` | Show a dot at every `step` position |
800
+ | `iconMin` | `JSX.Element` | — | Icon inside the min/single thumb |
801
+ | `iconMax` | `JSX.Element` | — | Icon inside the max thumb (range mode only) |
802
+ | `helperText` | `string` | — | Hint text below the slider |
803
+ | `disabled` | `boolean` | `false` | Prevents interaction |
804
+ | `variant` | `string` | `'default'` | Theme variant |
805
+ | `theme` | `EVENTS` | — | One-off token override |
755
806
 
756
807
  ### Example
757
808
 
758
809
  ```tsx
759
- import Slider from '@components/atoms/Slider';
810
+ import { Slider } from '@foi/design-system';
760
811
 
761
812
  // Single thumb — value is [number]
762
813
  <Slider name='volume' control={control} min={0} max={100} />
@@ -771,23 +822,27 @@ An animated placeholder rendered while content is loading. Has no logic — simp
771
822
 
772
823
  ### Props
773
824
 
774
- | Prop | Type | Default | Description |
775
- | ----------- | --------------------------------- | ---------------- | -------------------------------- |
776
- | `variant` | `'rectangular' \| 'circular'` | `'rectangular'` | Shape of the placeholder |
777
- | `width` | `string \| number` | — | CSS width or pixel number |
778
- | `height` | `string \| number` | — | CSS height or pixel number |
779
- | `className` | `string` | — | Extra CSS class |
825
+ | Prop | Type | Default | Description |
826
+ | ----------- | ----------------------------- | --------------- | -------------------------- |
827
+ | `variant` | `'rectangular' \| 'circular'` | `'rectangular'` | Shape of the placeholder |
828
+ | `width` | `string \| number` | — | CSS width or pixel number |
829
+ | `height` | `string \| number` | — | CSS height or pixel number |
830
+ | `className` | `string` | — | Extra CSS class |
780
831
 
781
832
  ### Example
782
833
 
783
834
  ```tsx
784
- import Skeleton from '@components/atoms/Skeleton';
835
+ import { Skeleton } from '@foi/design-system';
785
836
 
786
837
  // While loading a user avatar
787
- {isLoading ? <Skeleton variant='circular' width={40} height={40} /> : <Avatar src={user.photo} />}
838
+ {
839
+ isLoading ? <Skeleton variant='circular' width={40} height={40} /> : <Avatar src={user.photo} />;
840
+ }
788
841
 
789
842
  // While loading a text block
790
- {isLoading ? <Skeleton width='100%' height={20} /> : <p>{content}</p>}
843
+ {
844
+ isLoading ? <Skeleton width='100%' height={20} /> : <p>{content}</p>;
845
+ }
791
846
  ```
792
847
 
793
848
  ## Pagination
@@ -796,20 +851,20 @@ A standalone page-navigation bar. `DataGrid` uses this internally, but it can al
796
851
 
797
852
  ### Props
798
853
 
799
- | Prop | Type | Default | Description |
800
- | ------------------ | ------------------ | ------- | --------------------------------------------------- |
801
- | `page` | `number` | — | Zero-based current page index |
802
- | `total` | `number` | — | Total row count (used to compute page count) |
803
- | `pageSize` | `number` | — | Rows per page |
804
- | `onPageChange` | `(page: number) => void` | — | Fired when the user navigates to a different page |
805
- | `pageSizeOptions` | `number[]` | — | Shows a rows-per-page selector with these options |
806
- | `onPageSizeChange` | `(size: number) => void` | — | Fired when the user changes the page size |
807
- | `loading` | `boolean` | `false` | Disables all controls while data is fetching |
854
+ | Prop | Type | Default | Description |
855
+ | ------------------ | ------------------------ | ------- | ------------------------------------------------- |
856
+ | `page` | `number` | — | Zero-based current page index |
857
+ | `total` | `number` | — | Total row count (used to compute page count) |
858
+ | `pageSize` | `number` | — | Rows per page |
859
+ | `onPageChange` | `(page: number) => void` | — | Fired when the user navigates to a different page |
860
+ | `pageSizeOptions` | `number[]` | — | Shows a rows-per-page selector with these options |
861
+ | `onPageSizeChange` | `(size: number) => void` | — | Fired when the user changes the page size |
862
+ | `loading` | `boolean` | `false` | Disables all controls while data is fetching |
808
863
 
809
864
  ### Example
810
865
 
811
866
  ```tsx
812
- import Pagination from '@components/atoms/Pagination';
867
+ import { Pagination } from '@foi/design-system';
813
868
 
814
869
  <Pagination
815
870
  page={page}
@@ -818,7 +873,7 @@ import Pagination from '@components/atoms/Pagination';
818
873
  onPageChange={setPage}
819
874
  pageSizeOptions={[10, 25, 50]}
820
875
  onPageSizeChange={setPageSize}
821
- />
876
+ />;
822
877
  ```
823
878
 
824
879
  ## CheckboxGroup
@@ -827,24 +882,23 @@ Manages a set of `Checkbox` children as a `string[]` RHF field. The group value
827
882
 
828
883
  ### Props
829
884
 
830
- | Prop | Type | Default | Description |
831
- | --------------- | ------------------------------ | ------------ | ----------------------------------------------- |
832
- | `name` | `string` | — | RHF field name |
833
- | `control` | `Control` | — | RHF control object |
834
- | `children` | `ReactNode` | — | `<Checkbox>` elements (each must have `value`) |
835
- | `label` | `string` | — | Group label above the checkboxes |
836
- | `direction` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout direction of the items |
837
- | `disabled` | `boolean` | `false` | Disables all children |
838
- | `helperText` | `string` | — | Hint text below the group |
839
- | `showErrorText` | `boolean` | `true` | Show validation error message |
840
- | `variant` | `string` | `'default'` | Theme variant |
841
- | `theme` | `EVENTS` | — | One-off token override |
885
+ | Prop | Type | Default | Description |
886
+ | --------------- | ---------------------------- | ------------ | ---------------------------------------------- |
887
+ | `name` | `string` | — | RHF field name |
888
+ | `control` | `Control` | — | RHF control object |
889
+ | `children` | `ReactNode` | — | `<Checkbox>` elements (each must have `value`) |
890
+ | `label` | `string` | — | Group label above the checkboxes |
891
+ | `direction` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout direction of the items |
892
+ | `disabled` | `boolean` | `false` | Disables all children |
893
+ | `helperText` | `string` | — | Hint text below the group |
894
+ | `showErrorText` | `boolean` | `true` | Show validation error message |
895
+ | `variant` | `string` | `'default'` | Theme variant |
896
+ | `theme` | `EVENTS` | — | One-off token override |
842
897
 
843
898
  ### Example
844
899
 
845
900
  ```tsx
846
- import CheckboxGroup from '@components/molecules/CheckboxGroup';
847
- import Checkbox from '@components/atoms/Checkbox';
901
+ import { CheckboxGroup, Checkbox } from '@foi/design-system';
848
902
 
849
903
  const schema = z.object({
850
904
  skills: z.array(z.string()).min(1, 'Selecciona al menos una'),
@@ -854,7 +908,7 @@ const schema = z.object({
854
908
  <Checkbox value='react' label='React' />
855
909
  <Checkbox value='vue' label='Vue' />
856
910
  <Checkbox value='svelte' label='Svelte' />
857
- </CheckboxGroup>
911
+ </CheckboxGroup>;
858
912
  ```
859
913
 
860
914
  ## CheckboxTree
@@ -863,31 +917,30 @@ A hierarchical checkbox group. The parent checkbox controls all children simulta
863
917
 
864
918
  ### Props
865
919
 
866
- | Prop | Type | Default | Description |
867
- | ------------------- | ------------- | ---------------- | ---------------------------------------------------- |
868
- | `name` | `string` | — | RHF field name |
869
- | `control` | `Control` | — | RHF control object |
870
- | `children` | `ReactNode` | — | `<Checkbox>` elements (each must have `value`) |
871
- | `label` | `string` | — | Label on the parent (select-all) checkbox |
872
- | `iconChecked` | `JSX.Element` | checkmark | Icon on the parent when all children are checked |
873
- | `iconIndeterminate` | `JSX.Element` | dash | Icon on the parent when some children are checked |
874
- | `disabled` | `boolean` | `false` | Disables the parent and all children |
875
- | `helperText` | `string` | — | Hint text below the tree |
876
- | `showErrorText` | `boolean` | `true` | Show validation error message |
877
- | `variant` | `string` | `'default'` | Theme variant |
878
- | `theme` | `EVENTS` | — | One-off token override |
920
+ | Prop | Type | Default | Description |
921
+ | ------------------- | ------------- | ----------- | ------------------------------------------------- |
922
+ | `name` | `string` | — | RHF field name |
923
+ | `control` | `Control` | — | RHF control object |
924
+ | `children` | `ReactNode` | — | `<Checkbox>` elements (each must have `value`) |
925
+ | `label` | `string` | — | Label on the parent (select-all) checkbox |
926
+ | `iconChecked` | `JSX.Element` | checkmark | Icon on the parent when all children are checked |
927
+ | `iconIndeterminate` | `JSX.Element` | dash | Icon on the parent when some children are checked |
928
+ | `disabled` | `boolean` | `false` | Disables the parent and all children |
929
+ | `helperText` | `string` | — | Hint text below the tree |
930
+ | `showErrorText` | `boolean` | `true` | Show validation error message |
931
+ | `variant` | `string` | `'default'` | Theme variant |
932
+ | `theme` | `EVENTS` | — | One-off token override |
879
933
 
880
934
  ### Example
881
935
 
882
936
  ```tsx
883
- import CheckboxTree from '@components/molecules/CheckboxTree';
884
- import Checkbox from '@components/atoms/Checkbox';
937
+ import { CheckboxTree, Checkbox } from '@foi/design-system';
885
938
 
886
939
  <CheckboxTree name='permissions' control={control} label='Seleccionar todo'>
887
940
  <Checkbox value='read' label='Leer' />
888
941
  <Checkbox value='write' label='Escribir' />
889
942
  <Checkbox value='delete' label='Eliminar' />
890
- </CheckboxTree>
943
+ </CheckboxTree>;
891
944
  ```
892
945
 
893
946
  ## RadioGroup
@@ -896,24 +949,23 @@ Manages a set of `Radio` children as a single `string` RHF field. The value is t
896
949
 
897
950
  ### Props
898
951
 
899
- | Prop | Type | Default | Description |
900
- | --------------- | ------------------------------ | ------------ | ---------------------------------------------- |
901
- | `name` | `string` | — | RHF field name |
902
- | `control` | `Control` | — | RHF control object |
903
- | `children` | `ReactNode` | — | `<Radio>` elements (each must have `value`) |
904
- | `label` | `string` | — | Group label above the radios |
905
- | `direction` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout direction of the items |
906
- | `disabled` | `boolean` | `false` | Disables all children |
907
- | `helperText` | `string` | — | Hint text below the group |
908
- | `showErrorText` | `boolean` | `true` | Show validation error message |
909
- | `variant` | `string` | `'default'` | Theme variant |
910
- | `theme` | `EVENTS` | — | One-off token override |
952
+ | Prop | Type | Default | Description |
953
+ | --------------- | ---------------------------- | ------------ | ------------------------------------------- |
954
+ | `name` | `string` | — | RHF field name |
955
+ | `control` | `Control` | — | RHF control object |
956
+ | `children` | `ReactNode` | — | `<Radio>` elements (each must have `value`) |
957
+ | `label` | `string` | — | Group label above the radios |
958
+ | `direction` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout direction of the items |
959
+ | `disabled` | `boolean` | `false` | Disables all children |
960
+ | `helperText` | `string` | — | Hint text below the group |
961
+ | `showErrorText` | `boolean` | `true` | Show validation error message |
962
+ | `variant` | `string` | `'default'` | Theme variant |
963
+ | `theme` | `EVENTS` | — | One-off token override |
911
964
 
912
965
  ### Example
913
966
 
914
967
  ```tsx
915
- import RadioGroup from '@components/molecules/RadioGroup';
916
- import Radio from '@components/atoms/Radio';
968
+ import { RadioGroup, Radio } from '@foi/design-system';
917
969
 
918
970
  const schema = z.object({
919
971
  plan: z.string().min(1, 'Selecciona un plan'),
@@ -923,7 +975,7 @@ const schema = z.object({
923
975
  <Radio value='free' label='Gratis' />
924
976
  <Radio value='pro' label='Pro' />
925
977
  <Radio value='enterprise' label='Enterprise' />
926
- </RadioGroup>
978
+ </RadioGroup>;
927
979
  ```
928
980
 
929
981
  ## Chip
@@ -932,19 +984,19 @@ A compact inline label for displaying statuses, tags, or categories. Height is f
932
984
 
933
985
  ### Props
934
986
 
935
- | Prop | Type | Default | Description |
936
- | ----------- | ----------- | ----------- | ------------------------------------------------------------- |
937
- | `children` | `ReactNode` | — | Label text or custom content |
938
- | `variant` | `string` | `'default'` | Theme variant — any key defined under `CHIP` in your theme |
939
- | `className` | `string` | — | Extra CSS class |
940
- | `theme` | `EVENTS` | — | One-off token override |
987
+ | Prop | Type | Default | Description |
988
+ | ----------- | ----------- | ----------- | ---------------------------------------------------------- |
989
+ | `children` | `ReactNode` | — | Label text or custom content |
990
+ | `variant` | `string` | `'default'` | Theme variant — any key defined under `CHIP` in your theme |
991
+ | `className` | `string` | — | Extra CSS class |
992
+ | `theme` | `EVENTS` | — | One-off token override |
941
993
 
942
994
  When `children` is a plain string it is wrapped in a `span.--CHIP-label` that applies horizontal padding. Pass a `ReactNode` to render custom content (e.g. icon + text) directly inside the chip.
943
995
 
944
996
  ### Example
945
997
 
946
998
  ```tsx
947
- import Chip from '@components/atoms/Chip';
999
+ import { Chip } from '@foi/design-system';
948
1000
 
949
1001
  // Plain string — wrapped in a padded span automatically
950
1002
  <Chip>Activo</Chip>
@@ -974,7 +1026,7 @@ A notification system built around a React context. `ThemeProvider` automaticall
974
1026
  ### `useToast`
975
1027
 
976
1028
  ```tsx
977
- import { useToast } from '@hooks';
1029
+ import { useToast } from '@foi/design-system/hooks';
978
1030
 
979
1031
  const { push } = useToast();
980
1032
 
@@ -992,19 +1044,19 @@ push('Archivo guardado', { variant: 'success', icon: 'check_circle' });
992
1044
 
993
1045
  ### `ToastPosition`
994
1046
 
995
- | Value | Description |
996
- | ----------------- | ------------ |
997
- | `'bottom-right'` | Default |
1047
+ | Value | Description |
1048
+ | ----------------- | ------------- |
1049
+ | `'bottom-right'` | Default |
998
1050
  | `'bottom-center'` | Bottom center |
999
- | `'bottom-left'` | Bottom left |
1000
- | `'top-right'` | Top right |
1001
- | `'top-center'` | Top center |
1002
- | `'top-left'` | Top left |
1051
+ | `'bottom-left'` | Bottom left |
1052
+ | `'top-right'` | Top right |
1053
+ | `'top-center'` | Top center |
1054
+ | `'top-left'` | Top left |
1003
1055
 
1004
1056
  ### Example
1005
1057
 
1006
1058
  ```tsx
1007
- import { useToast } from '@hooks';
1059
+ import { useToast } from '@foi/design-system/hooks';
1008
1060
 
1009
1061
  const Notifier = () => {
1010
1062
  const { push } = useToast();
@@ -1027,7 +1079,7 @@ const Notifier = () => {
1027
1079
  Toast variants are defined in the theme under the `TOAST` key. Each variant must be self-contained (all tokens, not just overrides) because `useCreateComponentStyles` loads only the requested variant:
1028
1080
 
1029
1081
  ```ts
1030
- import type { TOAST } from '@hocs/ThemeProvider/components/molecules/Toast';
1082
+ import type { TOAST } from '@foi/design-system/theme';
1031
1083
 
1032
1084
  const toast = {
1033
1085
  TOAST: {