@axzydev/axzy_ui_system 1.2.6 → 1.2.8

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 (185) hide show
  1. package/dist/index.cjs +777 -535
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +1 -1
  4. package/dist/index.css.map +1 -1
  5. package/dist/index.d.cts +1470 -87
  6. package/dist/index.d.ts +1470 -87
  7. package/dist/index.js +799 -555
  8. package/dist/index.js.map +1 -1
  9. package/package.json +1 -1
  10. package/src/App.tsx +19 -54
  11. package/src/components/alert/alert.doc.mdx +48 -0
  12. package/src/components/alert/alert.props.ts +7 -0
  13. package/src/components/alert/alert.tsx +8 -0
  14. package/src/components/avatar/avatar.doc.mdx +48 -0
  15. package/src/components/avatar/avatar.props.ts +8 -0
  16. package/src/components/avatar/avatar.tsx +25 -5
  17. package/src/components/badget/badget.doc.mdx +46 -0
  18. package/src/components/badget/badget.props.ts +6 -0
  19. package/src/components/badget/badget.tsx +11 -0
  20. package/src/components/breadcrumbs/breadcrumbs.doc.mdx +57 -0
  21. package/src/components/breadcrumbs/breadcrumbs.props.ts +6 -0
  22. package/src/components/breadcrumbs/breadcrumbs.tsx +12 -0
  23. package/src/components/button/button.doc.mdx +59 -0
  24. package/src/components/button/button.props.ts +12 -0
  25. package/src/components/button/button.tsx +11 -0
  26. package/src/components/calendar/calendar.doc.mdx +75 -0
  27. package/src/components/calendar/calendar.props.ts +27 -7
  28. package/src/components/calendar/calendar.tsx +13 -0
  29. package/src/components/card/card.doc.mdx +54 -0
  30. package/src/components/card/card.props.ts +11 -0
  31. package/src/components/card/card.tsx +13 -0
  32. package/src/components/checkbox/checkbox.doc.mdx +54 -0
  33. package/src/components/checkbox/checkbox.props.ts +7 -0
  34. package/src/components/checkbox/checkbox.tsx +9 -0
  35. package/src/components/confirm-dialog/confirm-dialog.doc.mdx +60 -0
  36. package/src/components/confirm-dialog/confirm-dialog.props.ts +9 -0
  37. package/src/components/confirm-dialog/confirm-dialog.tsx +19 -0
  38. package/src/components/data-table/ITDataTable.doc.mdx +59 -0
  39. package/src/components/data-table/dataTable.props.ts +15 -0
  40. package/src/components/data-table/dataTable.tsx +178 -73
  41. package/src/components/date-picker/date-picker.doc.mdx +65 -0
  42. package/src/components/date-picker/date-picker.props.ts +17 -0
  43. package/src/components/date-picker/datePicker.tsx +31 -1
  44. package/src/components/dialog/dialog.doc.mdx +54 -0
  45. package/src/components/dialog/dialog.props.ts +7 -0
  46. package/src/components/dialog/dialog.tsx +26 -0
  47. package/src/components/divider/divider.doc.mdx +42 -0
  48. package/src/components/divider/divider.props.ts +5 -0
  49. package/src/components/divider/divider.tsx +16 -0
  50. package/src/components/drawer/drawer.doc.mdx +59 -0
  51. package/src/components/drawer/drawer.props.ts +9 -0
  52. package/src/components/drawer/drawer.tsx +20 -0
  53. package/src/components/dropfile/dropfile.doc.mdx +59 -0
  54. package/src/components/dropfile/dropfile.props.ts +41 -0
  55. package/src/components/dropfile/dropfile.tsx +21 -33
  56. package/src/components/empty-state/empty-state.doc.mdx +50 -0
  57. package/src/components/empty-state/empty-state.props.ts +5 -0
  58. package/src/components/empty-state/empty-state.tsx +16 -0
  59. package/src/components/flex/flex.doc.mdx +59 -0
  60. package/src/components/flex/flex.props.ts +13 -0
  61. package/src/components/flex/flex.tsx +15 -0
  62. package/src/components/form-builder/fieldRenderer.tsx +52 -2
  63. package/src/components/form-builder/formBuilder.doc.mdx +124 -0
  64. package/src/components/form-builder/formBuilder.props.ts +12 -2
  65. package/src/components/form-builder/formBuilder.tsx +31 -0
  66. package/src/components/form-header/form-header.doc.mdx +38 -0
  67. package/src/components/form-header/form-header.props.ts +3 -0
  68. package/src/components/form-header/form-header.stories.tsx +53 -0
  69. package/src/components/form-header/form-header.tsx +11 -0
  70. package/src/components/grid/grid.doc.mdx +54 -0
  71. package/src/components/grid/grid.props.ts +13 -0
  72. package/src/components/grid/grid.tsx +26 -2
  73. package/src/components/image/image.doc.mdx +44 -0
  74. package/src/components/image/image.props.ts +5 -0
  75. package/src/components/image/image.stories.tsx +49 -0
  76. package/src/components/image/image.tsx +19 -0
  77. package/src/components/input/input.doc.mdx +70 -0
  78. package/src/components/input/input.props.ts +34 -2
  79. package/src/components/input/input.tsx +29 -0
  80. package/src/components/layout/layout.doc.mdx +51 -0
  81. package/src/components/layout/layout.props.ts +5 -0
  82. package/src/components/layout/layout.tsx +41 -17
  83. package/src/components/loader/loader.doc.mdx +43 -0
  84. package/src/components/loader/loader.props.ts +4 -0
  85. package/src/components/loader/loader.tsx +17 -0
  86. package/src/components/navbar/navbar.doc.mdx +77 -0
  87. package/src/components/navbar/navbar.props.ts +37 -1
  88. package/src/components/navbar/navbar.stories.tsx +84 -0
  89. package/src/components/navbar/navbar.tsx +78 -46
  90. package/src/components/page/page.doc.mdx +80 -0
  91. package/src/components/page/page.props.ts +25 -0
  92. package/src/components/page/page.tsx +35 -7
  93. package/src/components/page-header/page-header.doc.mdx +54 -0
  94. package/src/components/page-header/page-header.props.ts +11 -0
  95. package/src/components/page-header/page-header.stories.tsx +14 -0
  96. package/src/components/page-header/page-header.tsx +50 -15
  97. package/src/components/pagination/pagination.doc.mdx +62 -0
  98. package/src/components/pagination/pagination.props.ts +11 -32
  99. package/src/components/pagination/pagination.tsx +17 -0
  100. package/src/components/popover/popover.doc.mdx +53 -0
  101. package/src/components/popover/popover.props.ts +8 -0
  102. package/src/components/popover/popover.tsx +13 -0
  103. package/src/components/progress/progress.doc.mdx +48 -0
  104. package/src/components/progress/progress.props.ts +8 -0
  105. package/src/components/progress/progress.tsx +9 -0
  106. package/src/components/radio/radio.doc.mdx +62 -0
  107. package/src/components/radio/radio.props.ts +11 -0
  108. package/src/components/radio/radio.tsx +18 -0
  109. package/src/components/search-select/search-select.doc.mdx +72 -0
  110. package/src/components/search-select/search-select.props.ts +23 -18
  111. package/src/components/search-select/search-select.tsx +27 -2
  112. package/src/components/searchTable/searchTable.doc.mdx +79 -0
  113. package/src/components/searchTable/searchTable.props.ts +42 -3
  114. package/src/components/searchTable/searchTable.stories.tsx +74 -0
  115. package/src/components/searchTable/searchTable.tsx +23 -0
  116. package/src/components/segmented-control/segmented-control.doc.mdx +60 -0
  117. package/src/components/segmented-control/segmented-control.props.ts +12 -0
  118. package/src/components/segmented-control/segmented-control.tsx +15 -0
  119. package/src/components/select/select.doc.mdx +75 -0
  120. package/src/components/select/select.props.ts +22 -0
  121. package/src/components/select/select.tsx +2 -5
  122. package/src/components/sidebar/sidebar.doc.mdx +86 -0
  123. package/src/components/sidebar/sidebar.props.ts +22 -0
  124. package/src/components/sidebar/sidebar.tsx +22 -0
  125. package/src/components/skeleton/skeleton.doc.mdx +43 -0
  126. package/src/components/skeleton/skeleton.props.ts +8 -0
  127. package/src/components/skeleton/skeleton.tsx +10 -0
  128. package/src/components/slide/slide.doc.mdx +46 -0
  129. package/src/components/slide/slide.props.ts +11 -24
  130. package/src/components/slide/slide.tsx +10 -1
  131. package/src/components/slider/slider.doc.mdx +49 -0
  132. package/src/components/slider/slider.props.ts +9 -0
  133. package/src/components/slider/slider.tsx +15 -0
  134. package/src/components/stack/stack.doc.mdx +126 -0
  135. package/src/components/stack/stack.props.ts +18 -0
  136. package/src/components/stack/stack.stories.tsx +221 -16
  137. package/src/components/stack/stack.tsx +21 -0
  138. package/src/components/stat-card/stat-card.doc.mdx +48 -0
  139. package/src/components/stat-card/stat-card.props.ts +9 -0
  140. package/src/components/stat-card/stat-card.tsx +10 -0
  141. package/src/components/stepper/stepper.doc.mdx +54 -0
  142. package/src/components/stepper/stepper.props.ts +11 -1
  143. package/src/components/stepper/stepper.tsx +15 -0
  144. package/src/components/table/table.doc.mdx +58 -0
  145. package/src/components/table/table.props.ts +17 -0
  146. package/src/components/table/table.tsx +199 -84
  147. package/src/components/tabs/tabs.doc.mdx +52 -0
  148. package/src/components/tabs/tabs.props.ts +11 -0
  149. package/src/components/tabs/tabs.tsx +14 -0
  150. package/src/components/text/text.doc.mdx +41 -0
  151. package/src/components/text/text.props.ts +5 -0
  152. package/src/components/text/text.stories.tsx +67 -0
  153. package/src/components/text/text.tsx +10 -0
  154. package/src/components/textarea/textarea.doc.mdx +64 -0
  155. package/src/components/textarea/textarea.props.ts +11 -0
  156. package/src/components/textarea/textarea.tsx +16 -0
  157. package/src/components/theme-provider/themeProvider.doc.mdx +75 -0
  158. package/src/components/theme-provider/themeProvider.props.ts +3 -0
  159. package/src/components/theme-provider/themeProvider.stories.tsx +59 -0
  160. package/src/components/theme-provider/themeProvider.tsx +14 -0
  161. package/src/components/time-picker/timePicker.doc.mdx +68 -0
  162. package/src/components/time-picker/timePicker.props.ts +14 -0
  163. package/src/components/time-picker/timePicker.tsx +22 -1
  164. package/src/components/toast/toast.doc.mdx +50 -0
  165. package/src/components/toast/toast.props.ts +5 -0
  166. package/src/components/toast/toast.tsx +21 -0
  167. package/src/components/tooltip/tooltip.doc.mdx +47 -0
  168. package/src/components/tooltip/tooltip.props.ts +6 -0
  169. package/src/components/tooltip/tooltip.tsx +19 -0
  170. package/src/components/topbar/topbar.doc.mdx +69 -0
  171. package/src/components/topbar/topbar.props.ts +15 -0
  172. package/src/components/topbar/topbar.tsx +38 -0
  173. package/src/components/triple-filter/tripleFilter.doc.mdx +62 -0
  174. package/src/components/triple-filter/tripleFilter.props.ts +7 -0
  175. package/src/components/triple-filter/tripleFilter.tsx +32 -0
  176. package/src/index.css +17 -0
  177. package/src/showcases/DataShowcases.tsx +529 -45
  178. package/src/showcases/FormShowcases.tsx +399 -29
  179. package/src/showcases/HomeShowcase.tsx +252 -272
  180. package/src/showcases/LayoutPrimitivesShowcases.tsx +1224 -248
  181. package/src/showcases/PageShowcases.tsx +868 -151
  182. package/src/showcases/ShowcaseLayout.tsx +237 -73
  183. package/src/showcases/StructureShowcases.tsx +1039 -97
  184. package/src/types/table.types.ts +1 -1
  185. package/src/utils/styles.ts +2 -1
@@ -0,0 +1,59 @@
1
+ import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
2
+ import * as Stories from './drawer.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # ITDrawer
7
+
8
+ A sliding panel that emerges from the left or right edge with a backdrop overlay. Includes an optional title bar with close button and a scrollable body. Ideal for side panels, navigation menus, filters, and detail views.
9
+
10
+ ## Props
11
+
12
+ | Prop | Type | Default | Description |
13
+ |------|------|---------|-------------|
14
+ | `isOpen` | `boolean` | — | Controls drawer visibility. |
15
+ | `onClose` | `() => void` | — | Called on overlay click or close button press. |
16
+ | `position` | `"left" \| "right"` | `"right"` | Screen edge the drawer attaches to. |
17
+ | `size` | `string` | `"w-80"` | Tailwind width class (e.g., `"w-72"`, `"w-96"`). |
18
+ | `title` | `ReactNode` | — | Optional heading in the drawer header. |
19
+ | `children` | `ReactNode` | — | Content displayed in the drawer body. |
20
+ | `className` | `string` | — | Additional CSS classes for the drawer panel. |
21
+ | `style` | `CSSProperties` | — | Inline styles for the drawer panel. |
22
+
23
+ ## Usage
24
+
25
+ ```tsx
26
+ import { ITDrawer } from '@axzydev/axzy_ui_system';
27
+
28
+ <ITDrawer
29
+ isOpen={menuOpen}
30
+ onClose={() => setMenuOpen(false)}
31
+ title="Navigation"
32
+ position="left"
33
+ size="w-72"
34
+ >
35
+ <NavMenu />
36
+ </ITDrawer>
37
+
38
+ <ITDrawer
39
+ isOpen={filterOpen}
40
+ onClose={() => setFilterOpen(false)}
41
+ title="Filters"
42
+ >
43
+ <FilterPanel />
44
+ </ITDrawer>
45
+ ```
46
+
47
+ ## Notes
48
+
49
+ - The overlay uses `bg-black/40 backdrop-blur-sm` for a blurred background effect.
50
+ - Overlay click outside the panel dismisses the drawer via `useClickOutside`.
51
+ - The body area scrolls independently (`overflow-y-auto`), keeping the header fixed.
52
+ - Default size `w-80` (320px); adjust with any Tailwind width class like `w-96` (384px) or `w-[400px]`.
53
+ - No built-in footer slot — add buttons or actions directly in the children content.
54
+
55
+ ## Stories
56
+
57
+ <Primary />
58
+ <Controls />
59
+ <Stories />
@@ -1,14 +1,23 @@
1
1
  import { ReactNode, CSSProperties } from "react";
2
2
 
3
+ /** Screen edge from which the drawer slides in: "left" | "right". */
3
4
  export type DrawerPosition = "left" | "right";
4
5
 
5
6
  export interface ITDrawerProps {
7
+ /** Controls whether the drawer is visible. */
6
8
  isOpen: boolean;
9
+ /** Callback fired when the overlay is clicked or the close button is pressed. */
7
10
  onClose: () => void;
11
+ /** Edge the drawer attaches to. @default "right" */
8
12
  position?: DrawerPosition;
13
+ /** Tailwind width class (e.g. "w-80", "w-96"). @default "w-80" */
9
14
  size?: string;
15
+ /** Optional heading rendered in the drawer header. */
10
16
  title?: ReactNode;
17
+ /** Content displayed in the drawer body. */
11
18
  children?: ReactNode;
19
+ /** Additional CSS classes for the drawer panel. */
12
20
  className?: string;
21
+ /** Inline styles for the drawer panel. */
13
22
  style?: CSSProperties;
14
23
  }
@@ -5,6 +5,26 @@ import useClickOutside from "@/hooks/useClickOutside";
5
5
  import { useRef } from "react";
6
6
  import ITText from "@/components/text/text";
7
7
 
8
+ /**
9
+ * Sliding panel drawer from the left or right screen edge.
10
+ *
11
+ * Renders an overlay backdrop with a horizontally-anchored panel that slides
12
+ * in. Includes an optional title bar with close button and a scrollable body
13
+ * area. Uses the `useClickOutside` hook for overlay dismissal.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <ITDrawer
18
+ * isOpen={menuOpen}
19
+ * onClose={() => setMenuOpen(false)}
20
+ * title="Navigation"
21
+ * position="left"
22
+ * size="w-72"
23
+ * >
24
+ * <NavMenu />
25
+ * </ITDrawer>
26
+ * ```
27
+ */
8
28
  export default function ITDrawer({
9
29
  isOpen,
10
30
  onClose,
@@ -0,0 +1,59 @@
1
+ import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
2
+ import * as Stories from './dropfile.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # ITDropfile
7
+
8
+ A drag-and-drop file upload zone with preview support for images. Tracks upload lifecycle with status enumeration and provides confirm/cancel actions. Configurable accepted file types limit which formats are allowed.
9
+
10
+ ## Props
11
+
12
+ | Prop | Type | Default | Description |
13
+ |------|------|---------|-------------|
14
+ | `onFileSelect` | `(file: File \| null) => void` | — | Called when a file is selected or cleared. |
15
+ | `onCancel` | `() => void` | — | Called when the user cancels the current selection. |
16
+ | `onSubmit` | `(file: File) => void` | — | Called when the user confirms and submits the file. |
17
+ | `acceptedFileTypes` | `FileTypeEnum[]` | — | List of accepted MIME types (PDF, XLS, CSV, PNG, JPG, etc.). |
18
+ | `contentClassName` | `string` | — | CSS classes for the preview/content area. |
19
+ | `containerClassName` | `string` | — | CSS classes for the outermost container. |
20
+ | `showStatusBadge` | `boolean` | — | Whether to show the status badge (pending/uploading/uploaded/error). |
21
+ | `uploadStatus` | `UploadStatus` | — | Externally controlled upload status. |
22
+ | `onStatusChange` | `(status: UploadStatus) => void` | — | Callback when upload status changes. |
23
+ | `initialPreviewUrl` | `string \| null` | — | Initial preview URL shown before any file is selected (e.g., editing an existing entry). |
24
+
25
+ ### Enums
26
+
27
+ | Enum | Values |
28
+ |------|--------|
29
+ | `UploadStatus` | `PENDING` (`"pendiente"`), `UPLOADING` (`"subiendo"`), `UPLOADED` (`"subido"`), `ERROR` (`"error"`) |
30
+ | `FileTypeEnum` | `PDF`, `XLS`, `XLSX`, `CSV`, `PNG`, `JPG`, `JPEG` |
31
+
32
+ ## Usage
33
+
34
+ ```tsx
35
+ import { ITDropfile, UploadStatus, FileTypeEnum } from '@axzydev/axzy_ui_system';
36
+
37
+ <ITDropfile
38
+ onFileSelect={(file) => setSelectedFile(file)}
39
+ onSubmit={(file) => uploadFile(file)}
40
+ onCancel={() => clearFile()}
41
+ acceptedFileTypes={[FileTypeEnum.PNG, FileTypeEnum.JPG, FileTypeEnum.PDF]}
42
+ uploadStatus={UploadStatus.PENDING}
43
+ showStatusBadge
44
+ />
45
+ ```
46
+
47
+ ## Notes
48
+
49
+ - Displays image preview for image file types; shows a file icon for non-image types.
50
+ - The `uploadStatus` and `showStatusBadge` props enable external lifecycle control and visual feedback.
51
+ - `initialPreviewUrl` is useful for edit forms where an existing file is already associated.
52
+ - Only one file at a time is supported — selecting a new file replaces the current one.
53
+ - The confirm/cancel flow gives users a chance to review their selection before submission.
54
+
55
+ ## Stories
56
+
57
+ <Primary />
58
+ <Controls />
59
+ <Stories />
@@ -0,0 +1,41 @@
1
+ /** Allowed file MIME types for the dropzone */
2
+ export enum FileTypeEnum {
3
+ PDF = "application/pdf",
4
+ XLS = "application/vnd.ms-excel",
5
+ XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
6
+ CSV = "text/csv",
7
+ PNG = "image/png",
8
+ JPG = "image/jpg",
9
+ JPEG = "image/jpeg",
10
+ }
11
+
12
+ /** Upload lifecycle status */
13
+ export enum UploadStatus {
14
+ PENDING = "pendiente",
15
+ UPLOADING = "subiendo",
16
+ UPLOADED = "subido",
17
+ ERROR = "error",
18
+ }
19
+
20
+ export interface ITDropfileProps {
21
+ /** Called when a file is selected or cleared. */
22
+ onFileSelect: (file: File | null) => void;
23
+ /** Called when the user cancels the current selection. */
24
+ onCancel?: () => void;
25
+ /** Called when the user confirms and submits the file. */
26
+ onSubmit?: (file: File) => void;
27
+ /** List of accepted MIME types. */
28
+ acceptedFileTypes?: FileTypeEnum[];
29
+ /** Additional classes for the preview/content area. */
30
+ contentClassName?: string;
31
+ /** Additional classes for the outermost container. */
32
+ containerClassName?: string;
33
+ /** Whether to show the status badge (pending/uploading/uploaded/error). */
34
+ showStatusBadge?: boolean;
35
+ /** Externally controlled upload status. */
36
+ uploadStatus?: UploadStatus;
37
+ /** Callback when upload status changes. */
38
+ onStatusChange?: (status: UploadStatus) => void;
39
+ /** An initial preview URL to display before any file is selected. */
40
+ initialPreviewUrl?: string | null;
41
+ }
@@ -3,40 +3,28 @@ import { useDropzone } from "react-dropzone";
3
3
  // import pdfjsLib from "@/hooks/pdf"; // Disabled as hook is missing
4
4
  import clsx from "clsx";
5
5
  import ITText from "@/components/text/text";
6
+ import { ITDropfileProps, FileTypeEnum, UploadStatus } from "./dropfile.props";
7
+ export { FileTypeEnum, UploadStatus } from "./dropfile.props";
6
8
 
7
- /** Enum con tipos de archivo permitidos */
8
- export enum FileTypeEnum {
9
- PDF = "application/pdf",
10
- XLS = "application/vnd.ms-excel",
11
- XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
12
- CSV = "text/csv",
13
- PNG = "image/png",
14
- JPG = "image/jpg",
15
- JPEG = "image/jpeg",
16
- }
17
-
18
- /** Enum para el estado de subida */
19
- export enum UploadStatus {
20
- PENDING = "pendiente",
21
- UPLOADING = "subiendo",
22
- UPLOADED = "subido",
23
- ERROR = "error",
24
- }
25
-
26
- /** Props del componente */
27
- export interface ITDropfileProps {
28
- onFileSelect: (file: File | null) => void;
29
- onCancel?: () => void;
30
- onSubmit?: (file: File) => void;
31
- acceptedFileTypes?: FileTypeEnum[];
32
- contentClassName?: string;
33
- containerClassName?: string;
34
- showStatusBadge?: boolean;
35
- uploadStatus?: UploadStatus;
36
- onStatusChange?: (status: UploadStatus) => void;
37
- initialPreviewUrl?: string | null;
38
- }
39
-
9
+ /**
10
+ * Drag-and-drop file uploader with preview, status tracking, and confirmation flow.
11
+ *
12
+ * Supports configurable accepted file types (PDF, Excel, CSV, images), visual
13
+ * drag-active feedback, image previews, and a three-step workflow: select →
14
+ * confirm → upload. Upload status is tracked internally or controlled
15
+ * externally via the `uploadStatus` prop. Re-exports `FileTypeEnum` and
16
+ * `UploadStatus` enums for consuming code.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * <ITDropfile
21
+ * onFileSelect={(file) => setSelectedFile(file)}
22
+ * onSubmit={(file) => uploadToServer(file)}
23
+ * acceptedFileTypes={[FileTypeEnum.PDF, FileTypeEnum.XLSX]}
24
+ * showStatusBadge
25
+ * />
26
+ * ```
27
+ */
40
28
  const ITDropfile: React.FC<ITDropfileProps> = ({
41
29
  onFileSelect,
42
30
  onCancel,
@@ -0,0 +1,50 @@
1
+ import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
2
+ import * as Stories from './empty-state.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # ITEmptyState
7
+
8
+ A placeholder component for displaying a message when no data is available. Configurable icon, title, description, and an action slot for contextual buttons.
9
+
10
+ ## Props
11
+
12
+ | Prop | Type | Default | Description |
13
+ |------|------|---------|-------------|
14
+ | `icon` | `ReactNode` | `<FaInbox size={40} />` | Icon or illustration displayed above the title. |
15
+ | `title` | `string` | — | Primary heading text (required). |
16
+ | `description` | `string` | — | Secondary explanatory text. |
17
+ | `action` | `ReactNode` | — | Action element (typically a button) rendered below the description. |
18
+ | `className` | `string` | — | Additional CSS classes for the wrapper. |
19
+
20
+ ## Usage
21
+
22
+ ```tsx
23
+ import { ITEmptyState } from '@axzydev/axzy_ui_system';
24
+
25
+ <ITEmptyState
26
+ title="No results"
27
+ description="No data found for the selected filters."
28
+ action={<ITButton label="Clear filters" variant="outlined" size="small" />}
29
+ />
30
+
31
+ <ITEmptyState
32
+ icon={<FaDatabase size={48} />}
33
+ title="No records"
34
+ description="Create your first record to get started."
35
+ action={<ITButton label="Create Record" variant="primary" />}
36
+ />
37
+ ```
38
+
39
+ ## Notes
40
+
41
+ - Default icon is `FaInbox` from react-icons — override with any ReactNode for custom illustrations.
42
+ - The `action` slot accepts any ReactNode, most commonly an `ITButton` for navigation or reset actions.
43
+ - Centers all content vertically and horizontally within its container.
44
+ - Works well as a fallback inside tables, cards, and search result containers.
45
+
46
+ ## Stories
47
+
48
+ <Primary />
49
+ <Controls />
50
+ <Stories />
@@ -1,9 +1,14 @@
1
1
  import { ReactNode } from "react";
2
2
 
3
3
  export interface ITEmptyStateProps {
4
+ /** Icon or illustration displayed above the title. @default <FaInbox size={40} /> */
4
5
  icon?: ReactNode;
6
+ /** Primary heading text (required). */
5
7
  title: string;
8
+ /** Secondary explanatory text shown below the title. */
6
9
  description?: string;
10
+ /** Action element (typically a button) rendered below the description. */
7
11
  action?: ReactNode;
12
+ /** Additional CSS classes for the wrapper element. */
8
13
  className?: string;
9
14
  }
@@ -3,6 +3,22 @@ import { ITEmptyStateProps } from "./empty-state.props";
3
3
  import { FaInbox } from "react-icons/fa";
4
4
  import ITText from "@/components/text/text";
5
5
 
6
+ /**
7
+ * Placeholder display for empty data sets.
8
+ *
9
+ * Shows a large icon, a title, an optional description, and an optional
10
+ * call-to-action element (usually a button). Centered vertically and
11
+ * horizontally within its container.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * <ITEmptyState
16
+ * title="No results found"
17
+ * description="Try adjusting your search or filters."
18
+ * action={<ITButton label="Clear filters" variant="outlined" onClick={clearFilters} />}
19
+ * />
20
+ * ```
21
+ */
6
22
  export default function ITEmptyState({
7
23
  icon = <FaInbox size={40} />,
8
24
  title,
@@ -0,0 +1,59 @@
1
+ import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
2
+ import * as Stories from './flex.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # ITFlex
7
+
8
+ A complete flexbox layout container exposing the full CSS Flexbox API through React props. Supports direction, wrap, alignment, justification, gap, grow, shrink, basis, and custom element rendering.
9
+
10
+ ## Props
11
+
12
+ | Prop | Type | Default | Description |
13
+ |------|------|---------|-------------|
14
+ | `children` | `ReactNode` | — | Child elements inside the flex container. |
15
+ | `direction` | `"row" \| "column" \| "row-reverse" \| "column-reverse"` | — | Main axis direction. |
16
+ | `align` | `"start" \| "end" \| "center" \| "stretch" \| "baseline"` | — | Cross-axis alignment. |
17
+ | `justify` | `"start" \| "end" \| "center" \| "between" \| "around" \| "evenly"` | — | Main-axis justification. |
18
+ | `wrap` | `"nowrap" \| "wrap" \| "wrap-reverse"` | — | Wrapping behavior. |
19
+ | `gap` | `number` | — | Gap between children in units of `0.25rem`. |
20
+ | `grow` | `boolean \| number` | — | Flex grow factor. `true` = 1, `false` = 0, or pass a number. |
21
+ | `shrink` | `boolean \| number` | — | Flex shrink factor. Works like `grow`. |
22
+ | `basis` | `string \| number` | — | Flex basis value. Numbers multiplied by `0.25rem`; strings used as-is. |
23
+ | `className` | `string` | — | Additional CSS classes. |
24
+ | `style` | `CSSProperties` | — | Inline styles. |
25
+ | `as` | `ElementType` | `"div"` | Custom HTML element type to render. |
26
+ | `onClick` | `(e: React.MouseEvent) => void` | — | Click handler. |
27
+
28
+ ## Usage
29
+
30
+ ```tsx
31
+ import { ITFlex } from '@axzydev/axzy_ui_system';
32
+
33
+ <ITFlex direction="row" gap={3} justify="between" align="center">
34
+ <div>Left</div>
35
+ <div>Center</div>
36
+ <div>Right</div>
37
+ </ITFlex>
38
+
39
+ <ITFlex direction="column" gap={2} className="h-60">
40
+ <ITFlex grow className="bg-primary-100 rounded-lg p-4">
41
+ <span>Grow (flex: 1)</span>
42
+ </ITFlex>
43
+ <div className="w-full">Fixed height</div>
44
+ </ITFlex>
45
+ ```
46
+
47
+ ## Notes
48
+
49
+ - `gap` accepts an integer where `1` = `0.25rem` (4px), `4` = `1rem` (16px), etc., matching Tailwind's spacing scale.
50
+ - The `as` prop allows rendering as a `<section>`, `<nav>`, `<form>`, or any other semantic HTML element.
51
+ - `grow` and `shrink` accept `boolean` for quick on/off or `number` for precise flex factor control.
52
+ - Combine `basis`, `grow`, and `shrink` for complete flex item control on the container itself.
53
+ - All flex props are optional — the component renders as a standard `div` when no layout props are set.
54
+
55
+ ## Stories
56
+
57
+ <Primary />
58
+ <Controls />
59
+ <Stories />
@@ -6,17 +6,30 @@ export type FlexJustify = "start" | "end" | "center" | "between" | "around" | "e
6
6
  export type FlexWrap = "nowrap" | "wrap" | "wrap-reverse";
7
7
 
8
8
  export interface ITFlexProps {
9
+ /** Child elements to render inside the flex container */
9
10
  children?: ReactNode;
11
+ /** Main axis direction: "row" | "column" | "row-reverse" | "column-reverse" */
10
12
  direction?: FlexDirection;
13
+ /** Cross-axis alignment: "start" | "end" | "center" | "stretch" | "baseline" */
11
14
  align?: FlexAlign;
15
+ /** Main-axis justification: "start" | "end" | "center" | "between" | "around" | "evenly" */
12
16
  justify?: FlexJustify;
17
+ /** Wrapping behavior: "nowrap" | "wrap" | "wrap-reverse" */
13
18
  wrap?: FlexWrap;
19
+ /** Gap between children in units of 0.25rem */
14
20
  gap?: number;
21
+ /** Flex grow factor. Pass `true` for 1, `false` for 0, or a number */
15
22
  grow?: boolean | number;
23
+ /** Flex shrink factor. Pass `true` for 1, `false` for 0, or a number */
16
24
  shrink?: boolean | number;
25
+ /** Flex basis value. Numbers are multiplied by 0.25rem; strings used as-is */
17
26
  basis?: string | number;
27
+ /** Additional CSS classes */
18
28
  className?: string;
29
+ /** Inline styles */
19
30
  style?: CSSProperties;
31
+ /** Custom HTML element type to render instead of the default `div` */
20
32
  as?: ElementType;
33
+ /** Click handler */
21
34
  onClick?: (e: React.MouseEvent) => void;
22
35
  }
@@ -37,6 +37,21 @@ const wrapMap: Record<FlexWrap, string> = {
37
37
  "wrap-reverse": "flex-wrap-reverse",
38
38
  };
39
39
 
40
+ /**
41
+ * A complete flexbox container with all alignment and spacing options.
42
+ *
43
+ * @example
44
+ * <ITFlex direction="row" justify="between" align="center" gap={4}>
45
+ * <div>Left</div>
46
+ * <div>Right</div>
47
+ * </ITFlex>
48
+ *
49
+ * @example
50
+ * <ITFlex direction="column" gap={2} as="section">
51
+ * <header>Title</header>
52
+ * <main>Content</main>
53
+ * </ITFlex>
54
+ */
40
55
  export default function ITFlex({
41
56
  children,
42
57
  direction = "row",
@@ -1,4 +1,4 @@
1
- import React, { memo, useCallback, useEffect } from "react";
1
+ import React, { memo, useCallback, useEffect, useState } from "react";
2
2
  import clsx from "clsx";
3
3
  import { FieldConfigV2 } from "@/types/field.types";
4
4
  import { useITFormBuilderContext } from "./formBuilder.context";
@@ -6,9 +6,30 @@ import ITInput from "../input/input";
6
6
  import ITSelect from "../select/select";
7
7
  import ITDatePicker from "../date-picker/datePicker";
8
8
  import ITTimePicker from "../time-picker/timePicker";
9
+ import ITSearchSelect from "../search-select/search-select";
9
10
  import { useFieldRules } from "./useFormBuilder";
10
11
  import { getColSpanClass, getGridColsClass } from "@/utils/styles";
11
12
  import ITText from "@/components/text/text";
13
+ import { FaSpinner } from "react-icons/fa";
14
+
15
+ function useAsyncOptions(options: FieldConfigV2["options"], depends: any[]) {
16
+ const [resolved, setResolved] = useState<{ value: string; label: string }[]>([]);
17
+ const [loading, setLoading] = useState(false);
18
+
19
+ useEffect(() => {
20
+ if (typeof options === "function") {
21
+ setLoading(true);
22
+ options().then((result) => {
23
+ setResolved(result.map(o => ({ value: String(o.value), label: o.label })));
24
+ setLoading(false);
25
+ });
26
+ } else if (Array.isArray(options)) {
27
+ setResolved(options.map(o => ({ value: String(o.value), label: o.label })));
28
+ }
29
+ }, depends);
30
+
31
+ return { options: resolved, loading };
32
+ }
12
33
 
13
34
 
14
35
 
@@ -65,6 +86,8 @@ const ITFieldRenderer = ({
65
86
  rightIcon,
66
87
  } = activeConfig;
67
88
 
89
+ const { options: resolvedOptions, loading: optionsLoading } = useAsyncOptions(options, [options, dependentValues]);
90
+
68
91
  const handleChangeWrapper = useCallback(
69
92
  async (val: any) => {
70
93
  const finalValue = val?.target ? val.target.value : val;
@@ -107,9 +130,36 @@ const ITFieldRenderer = ({
107
130
  );
108
131
 
109
132
  case "select":
133
+ if (optionsLoading) {
134
+ return (
135
+ <div className="flex items-center gap-2 py-3">
136
+ <FaSpinner className="animate-spin text-primary-500" />
137
+ <ITText as="span" className="text-sm text-slate-500">Cargando opciones...</ITText>
138
+ </div>
139
+ );
140
+ }
141
+ if (typeof options === "function") {
142
+ return (
143
+ <ITSearchSelect
144
+ options={resolvedOptions}
145
+ name={name}
146
+ disabled={isDisabled as boolean}
147
+ label={label || ""}
148
+ placeholder={placeholder}
149
+ value={value !== undefined ? value : activeConfig.defaultValue || ""}
150
+ valueField={valueField || "value"}
151
+ labelField={labelField || "label"}
152
+ onChange={(val: any) => handleChangeWrapper(val)}
153
+ onBlur={context.handleBlur}
154
+ touched={touched}
155
+ error={error}
156
+ required={isRequired as boolean}
157
+ />
158
+ );
159
+ }
110
160
  return (
111
161
  <ITSelect
112
- options={(Array.isArray(options) ? options : []) as any}
162
+ options={resolvedOptions}
113
163
  name={name}
114
164
  disabled={isDisabled as boolean}
115
165
  label={label || ""}