@foi/design-system 0.0.19 → 0.0.20

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