@axzydev/axzy_ui_system 1.2.7 → 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 (184) hide show
  1. package/dist/index.cjs +576 -398
  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 +1463 -86
  6. package/dist/index.d.ts +1463 -86
  7. package/dist/index.js +597 -417
  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 +19 -0
  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 +29 -2
  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 +27 -0
  90. package/src/components/page/page.doc.mdx +80 -0
  91. package/src/components/page/page.props.ts +21 -0
  92. package/src/components/page/page.tsx +18 -0
  93. package/src/components/page-header/page-header.doc.mdx +54 -0
  94. package/src/components/page-header/page-header.props.ts +9 -0
  95. package/src/components/page-header/page-header.tsx +15 -0
  96. package/src/components/pagination/pagination.doc.mdx +62 -0
  97. package/src/components/pagination/pagination.props.ts +11 -32
  98. package/src/components/pagination/pagination.tsx +17 -0
  99. package/src/components/popover/popover.doc.mdx +53 -0
  100. package/src/components/popover/popover.props.ts +8 -0
  101. package/src/components/popover/popover.tsx +13 -0
  102. package/src/components/progress/progress.doc.mdx +48 -0
  103. package/src/components/progress/progress.props.ts +8 -0
  104. package/src/components/progress/progress.tsx +9 -0
  105. package/src/components/radio/radio.doc.mdx +62 -0
  106. package/src/components/radio/radio.props.ts +11 -0
  107. package/src/components/radio/radio.tsx +18 -0
  108. package/src/components/search-select/search-select.doc.mdx +72 -0
  109. package/src/components/search-select/search-select.props.ts +23 -18
  110. package/src/components/search-select/search-select.tsx +27 -2
  111. package/src/components/searchTable/searchTable.doc.mdx +79 -0
  112. package/src/components/searchTable/searchTable.props.ts +42 -3
  113. package/src/components/searchTable/searchTable.stories.tsx +74 -0
  114. package/src/components/searchTable/searchTable.tsx +23 -0
  115. package/src/components/segmented-control/segmented-control.doc.mdx +60 -0
  116. package/src/components/segmented-control/segmented-control.props.ts +12 -0
  117. package/src/components/segmented-control/segmented-control.tsx +15 -0
  118. package/src/components/select/select.doc.mdx +75 -0
  119. package/src/components/select/select.props.ts +22 -0
  120. package/src/components/select/select.tsx +2 -5
  121. package/src/components/sidebar/sidebar.doc.mdx +86 -0
  122. package/src/components/sidebar/sidebar.props.ts +22 -0
  123. package/src/components/sidebar/sidebar.tsx +22 -0
  124. package/src/components/skeleton/skeleton.doc.mdx +43 -0
  125. package/src/components/skeleton/skeleton.props.ts +8 -0
  126. package/src/components/skeleton/skeleton.tsx +10 -0
  127. package/src/components/slide/slide.doc.mdx +46 -0
  128. package/src/components/slide/slide.props.ts +11 -24
  129. package/src/components/slide/slide.tsx +10 -1
  130. package/src/components/slider/slider.doc.mdx +49 -0
  131. package/src/components/slider/slider.props.ts +9 -0
  132. package/src/components/slider/slider.tsx +15 -0
  133. package/src/components/stack/stack.doc.mdx +126 -0
  134. package/src/components/stack/stack.props.ts +18 -0
  135. package/src/components/stack/stack.stories.tsx +221 -16
  136. package/src/components/stack/stack.tsx +21 -0
  137. package/src/components/stat-card/stat-card.doc.mdx +48 -0
  138. package/src/components/stat-card/stat-card.props.ts +9 -0
  139. package/src/components/stat-card/stat-card.tsx +10 -0
  140. package/src/components/stepper/stepper.doc.mdx +54 -0
  141. package/src/components/stepper/stepper.props.ts +11 -1
  142. package/src/components/stepper/stepper.tsx +15 -0
  143. package/src/components/table/table.doc.mdx +58 -0
  144. package/src/components/table/table.props.ts +17 -0
  145. package/src/components/table/table.tsx +199 -84
  146. package/src/components/tabs/tabs.doc.mdx +52 -0
  147. package/src/components/tabs/tabs.props.ts +11 -0
  148. package/src/components/tabs/tabs.tsx +14 -0
  149. package/src/components/text/text.doc.mdx +41 -0
  150. package/src/components/text/text.props.ts +5 -0
  151. package/src/components/text/text.stories.tsx +67 -0
  152. package/src/components/text/text.tsx +10 -0
  153. package/src/components/textarea/textarea.doc.mdx +64 -0
  154. package/src/components/textarea/textarea.props.ts +11 -0
  155. package/src/components/textarea/textarea.tsx +16 -0
  156. package/src/components/theme-provider/themeProvider.doc.mdx +75 -0
  157. package/src/components/theme-provider/themeProvider.props.ts +3 -0
  158. package/src/components/theme-provider/themeProvider.stories.tsx +59 -0
  159. package/src/components/theme-provider/themeProvider.tsx +14 -0
  160. package/src/components/time-picker/timePicker.doc.mdx +68 -0
  161. package/src/components/time-picker/timePicker.props.ts +14 -0
  162. package/src/components/time-picker/timePicker.tsx +22 -1
  163. package/src/components/toast/toast.doc.mdx +50 -0
  164. package/src/components/toast/toast.props.ts +5 -0
  165. package/src/components/toast/toast.tsx +21 -0
  166. package/src/components/tooltip/tooltip.doc.mdx +47 -0
  167. package/src/components/tooltip/tooltip.props.ts +6 -0
  168. package/src/components/tooltip/tooltip.tsx +19 -0
  169. package/src/components/topbar/topbar.doc.mdx +69 -0
  170. package/src/components/topbar/topbar.props.ts +15 -0
  171. package/src/components/topbar/topbar.tsx +38 -0
  172. package/src/components/triple-filter/tripleFilter.doc.mdx +62 -0
  173. package/src/components/triple-filter/tripleFilter.props.ts +7 -0
  174. package/src/components/triple-filter/tripleFilter.tsx +32 -0
  175. package/src/index.css +2 -0
  176. package/src/showcases/DataShowcases.tsx +529 -45
  177. package/src/showcases/FormShowcases.tsx +399 -29
  178. package/src/showcases/HomeShowcase.tsx +252 -272
  179. package/src/showcases/LayoutPrimitivesShowcases.tsx +1224 -248
  180. package/src/showcases/PageShowcases.tsx +688 -391
  181. package/src/showcases/ShowcaseLayout.tsx +237 -73
  182. package/src/showcases/StructureShowcases.tsx +846 -73
  183. package/src/types/table.types.ts +1 -1
  184. package/src/utils/styles.ts +2 -1
@@ -0,0 +1,124 @@
1
+ import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
2
+ import * as Stories from './formBuilder.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # ITFormBuilder
7
+
8
+ A dynamic form generator that renders fields from JSON-like configuration (V1 or V2). Integrates with Formik and Yup for validation. Supports conditional rendering, calculated fields, grid layout, async validation, and custom components.
9
+
10
+ ## Props
11
+
12
+ | Prop | Type | Default | Description |
13
+ |------|------|---------|-------------|
14
+ | `fields` | `FieldConfig[]` | — | Legacy V1 field definitions (backward compatible). |
15
+ | `config` | `FieldConfigV2[]` | — | V2 field configuration array with conditional logic, dynamic props, and grid layout. |
16
+ | `columns` | `number` | — | Number of grid columns (1–12). |
17
+ | `values` | `any` | — | Current form values keyed by field name. |
18
+ | `handleChange` | `(event) => void` | — | Change handler for input, select, and textarea elements. |
19
+ | `handleBlur` | `(event) => void` | — | Blur handler for input, select, and textarea elements. |
20
+ | `touched` | `any` | — | Touch state keyed by field name. |
21
+ | `errors` | `any` | — | Validation errors keyed by field name. |
22
+ | `setFieldValue` | `(field, value, shouldValidate?) => Promise<void>` | — | Programmatically set a field value. |
23
+ | `setFieldTouched` | `(field, touched?, shouldValidate?) => Promise<void>` | — | Programmatically mark a field as touched. |
24
+ | `setFieldError` | `(field, message?) => void` | — | Programmatically set a field-level error. |
25
+ | `isSubmitting` | `boolean` | — | Whether the form is currently submitting. |
26
+
27
+ ### FieldConfigV2 Key Properties
28
+
29
+ | Property | Type | Description |
30
+ |----------|------|-------------|
31
+ | `type` | `"text" \| "number" \| "password" \| "email" \| "select" \| "date" \| "time" \| "checkbox" \| "radio" \| "array" \| "section" \| "custom"` | Field input type. |
32
+ | `column` | `number \| { sm?, md?, lg?, xl? }` | Grid column span (responsive object or single number). |
33
+ | `dependsOn` | `string[]` | Sibling field names to watch for conditional re-evaluation. |
34
+ | `renderWhen` | `(values) => boolean` | When false, the field is not rendered or submitted. |
35
+ | `dynamicProps` | `(values) => Partial<FieldConfigV2>` | Dynamically override field props based on form state. |
36
+ | `validation` | `Yup.AnySchema` | Per-field Yup validation schema. |
37
+ | `asyncValidation` | `(value, values) => Promise<string \| null>` | Async per-field validation returning error string. |
38
+ | `onChangeAction` | `(val, context) => void \| Promise<void>` | Lifecycle hook for side effects (e.g., calculate totals). |
39
+ | `options` | `Array \| () => Promise<Array>` | Select/radio options, sync or async. |
40
+ | `component` | `React.ComponentType` | Custom renderer for `type: "custom"`. |
41
+
42
+ ## Usage
43
+
44
+ ```tsx
45
+ import { ITFormBuilder } from '@axzydev/axzy_ui_system';
46
+ import { Formik } from 'formik';
47
+ import * as Yup from 'yup';
48
+
49
+ const schema = Yup.object({
50
+ email: Yup.string().email("Invalid email").required("Required"),
51
+ password: Yup.string().min(8).required("Required"),
52
+ });
53
+
54
+ const fields = [
55
+ { name: "email", label: "Email", type: "email", required: true, column: { sm: 12 } },
56
+ { name: "password", label: "Password", type: "password", required: true, column: { sm: 12 } },
57
+ {
58
+ name: "subtotal",
59
+ label: "Subtotal",
60
+ type: "number",
61
+ currencyFormat: true,
62
+ column: { sm: 12, md: 4 },
63
+ onChangeAction: (val, { setFieldValue }) => {
64
+ const num = parseFloat(val) || 0;
65
+ setFieldValue("total", (num * 1.16).toFixed(2));
66
+ },
67
+ },
68
+ {
69
+ name: "total",
70
+ label: "Total",
71
+ type: "number",
72
+ currencyFormat: true,
73
+ disabled: true,
74
+ column: { sm: 12, md: 4 },
75
+ },
76
+ {
77
+ name: "rfc",
78
+ label: "RFC",
79
+ type: "text",
80
+ dependsOn: ["country"],
81
+ renderWhen: (vals) => vals.country === "MX",
82
+ required: true,
83
+ column: { sm: 12, md: 6 },
84
+ },
85
+ ];
86
+
87
+ <Formik
88
+ initialValues={{ email: "", password: "", subtotal: "", total: "", rfc: "" }}
89
+ validationSchema={schema}
90
+ onSubmit={handleSubmit}
91
+ >
92
+ {(formikProps) => (
93
+ <form onSubmit={formikProps.handleSubmit}>
94
+ <ITFormBuilder
95
+ config={fields}
96
+ columns={12}
97
+ values={formikProps.values}
98
+ handleChange={formikProps.handleChange}
99
+ handleBlur={formikProps.handleBlur}
100
+ touched={formikProps.touched}
101
+ errors={formikProps.errors}
102
+ setFieldValue={formikProps.setFieldValue}
103
+ />
104
+ <button type="submit">Submit</button>
105
+ </form>
106
+ )}
107
+ </Formik>
108
+ ```
109
+
110
+ ## Notes
111
+
112
+ - Supports both legacy V1 (`fields` prop) and enterprise V2 (`config` prop) field configurations.
113
+ - V2 fields support a powerful rules engine: `dependsOn`, `renderWhen`, and `dynamicProps` for conditional behavior.
114
+ - `onChangeAction` enables real-time field calculations and cross-field updates.
115
+ - Grid layout uses a responsive 12-column system with per-breakpoint column span configuration.
116
+ - Field types include `section` (grouping with collapsible regions) and `array` (dynamic repeatable lists).
117
+ - Fully Formik-compatible — requires Formik context wrapping for state management.
118
+ - `custom` type allows injecting arbitrary React components for complete layout control.
119
+
120
+ ## Stories
121
+
122
+ <Primary />
123
+ <Controls />
124
+ <Stories />
@@ -1,14 +1,17 @@
1
1
  import { FieldConfig, FieldConfigV2 } from "@/types/field.types";
2
2
 
3
3
  export interface ITFormBuilderProps {
4
- // Legacy
4
+ /** Legacy field definitions (V1). Use `config` for the V2 architecture instead */
5
5
  fields?: FieldConfig[];
6
6
 
7
- // V2 Architecture
7
+ /** V2 field configuration array. Preferred over the legacy `fields` prop */
8
8
  config?: FieldConfigV2[];
9
9
 
10
+ /** Number of grid columns (1-12) */
10
11
  columns?: number;
12
+ /** Current form values keyed by field name */
11
13
  values: any;
14
+ /** Change handler for input, select, and textarea elements */
12
15
  handleChange: (
13
16
  event:
14
17
  | React.ChangeEvent<HTMLInputElement>
@@ -16,6 +19,7 @@ export interface ITFormBuilderProps {
16
19
  | React.ChangeEvent<HTMLSelectElement>
17
20
  | { target: { name: string; value: any } }
18
21
  ) => void;
22
+ /** Blur handler for input, select, and textarea elements */
19
23
  handleBlur: (
20
24
  event:
21
25
  | React.FocusEvent<HTMLInputElement>
@@ -23,21 +27,27 @@ export interface ITFormBuilderProps {
23
27
  | React.FocusEvent<HTMLTextAreaElement, Element>
24
28
  | { target: { name: string; value: any } }
25
29
  ) => void;
30
+ /** Touch state keyed by field name */
26
31
  touched: any;
32
+ /** Validation errors keyed by field name */
27
33
  errors: any;
34
+ /** Programmatically set a field value */
28
35
  setFieldValue?: (
29
36
  field: string,
30
37
  value: any,
31
38
  shouldValidate?: boolean
32
39
  ) => Promise<void | any>;
40
+ /** Programmatically mark a field as touched */
33
41
  setFieldTouched?: (
34
42
  field: string,
35
43
  touched?: boolean,
36
44
  shouldValidate?: boolean
37
45
  ) => Promise<void | any>;
46
+ /** Programmatically set a field-level error message */
38
47
  setFieldError?: (
39
48
  field: string,
40
49
  message: string | undefined
41
50
  ) => void;
51
+ /** Whether the form is currently submitting */
42
52
  isSubmitting?: boolean;
43
53
  }
@@ -20,6 +20,37 @@ function buildDependentValues(
20
20
  return deps;
21
21
  }
22
22
 
23
+ /**
24
+ * Dynamic form generator from field definitions with validation support.
25
+ * Renders a responsive grid of inputs, selects, and date pickers based on
26
+ * the provided field configuration. Supports both legacy (`fields`) and
27
+ * V2 (`config`) field definition formats.
28
+ *
29
+ * @example
30
+ * <ITFormBuilder
31
+ * fields={[
32
+ * { name: "email", label: "Email", type: "text", required: true, column: 6 },
33
+ * { name: "role", label: "Role", type: "select", options: [{ id: 1, label: "Admin" }], column: 6 },
34
+ * ]}
35
+ * values={formValues}
36
+ * handleChange={handleChange}
37
+ * handleBlur={handleBlur}
38
+ * touched={touched}
39
+ * errors={errors}
40
+ * columns={12}
41
+ * />
42
+ *
43
+ * @example
44
+ * <ITFormBuilder
45
+ * config={v2FieldConfigs}
46
+ * values={formValues}
47
+ * handleChange={handleChange}
48
+ * handleBlur={handleBlur}
49
+ * touched={touched}
50
+ * errors={errors}
51
+ * isSubmitting={loading}
52
+ * />
53
+ */
23
54
  export default function ITFormBuilder({
24
55
  fields,
25
56
  config,
@@ -0,0 +1,38 @@
1
+ import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
2
+ import * as Stories from './form-header.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # ITFormHeader
7
+
8
+ A colored header bar for modal dialogs and form containers. Displays a title centered on a primary-colored background, with an optional close (X) button on the right side.
9
+
10
+ ## Props
11
+
12
+ | Prop | Type | Default | Description |
13
+ |------|------|---------|-------------|
14
+ | `title` | `string` | required | Header title text, centered in the bar. |
15
+ | `onClose` | `() => void` | `undefined` | Optional close button handler. When provided, an X button renders. |
16
+ | `className` | `string` | `undefined` | Additional CSS classes applied to the container. |
17
+
18
+ ## Usage
19
+
20
+ ```tsx
21
+ import { ITFormHeader } from '@axzydev/axzy_ui_system';
22
+
23
+ <ITFormHeader title="Edit Record" />
24
+ <ITFormHeader title="Confirm" onClose={() => handleClose()} />
25
+ ```
26
+
27
+ ## Notes
28
+
29
+ - Uses the theme primary color as the background.
30
+ - The title truncates with ellipsis when it overflows the available width.
31
+ - Close button is only rendered when `onClose` is provided.
32
+ - Intended for use inside modals, drawers, or form panels.
33
+
34
+ ## Stories
35
+
36
+ <Primary />
37
+ <Controls />
38
+ <Stories />
@@ -1,5 +1,8 @@
1
1
  export interface ITFormHeaderProps {
2
+ /** Header title text */
2
3
  title: string;
4
+ /** Optional close button click handler. If omitted, no close button is rendered */
3
5
  onClose?: () => void;
6
+ /** Additional CSS classes */
4
7
  className?: string;
5
8
  }
@@ -0,0 +1,53 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import ITFormHeader from './form-header';
3
+
4
+ const meta = {
5
+ title: 'Components/Feedback/ITFormHeader',
6
+ component: ITFormHeader,
7
+ parameters: { layout: 'centered' },
8
+ tags: ['autodocs'],
9
+ argTypes: {
10
+ title: { control: 'text', description: 'The title displayed in the header' },
11
+ onClose: { control: false, description: 'Optional close button handler' },
12
+ className: { control: 'text', description: 'Additional CSS classes' },
13
+ },
14
+ } satisfies Meta<typeof ITFormHeader>;
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof meta>;
18
+
19
+ export const Default: Story = {
20
+ args: { title: 'Form Header' },
21
+ render: (args) => (
22
+ <div className="w-80">
23
+ <ITFormHeader {...args} />
24
+ </div>
25
+ ),
26
+ };
27
+
28
+ export const WithClose: Story = {
29
+ args: { title: 'Editable Form' },
30
+ render: (args) => (
31
+ <div className="w-80">
32
+ <ITFormHeader {...args} onClose={() => alert('Close clicked')} />
33
+ </div>
34
+ ),
35
+ };
36
+
37
+ export const LongTitle: Story = {
38
+ args: { title: 'Confirmación de Auditoría de Expediente Clínico' },
39
+ render: (args) => (
40
+ <div className="w-80">
41
+ <ITFormHeader {...args} />
42
+ </div>
43
+ ),
44
+ };
45
+
46
+ export const ShortTitle: Story = {
47
+ args: { title: 'Edit' },
48
+ render: (args) => (
49
+ <div className="w-80">
50
+ <ITFormHeader {...args} />
51
+ </div>
52
+ ),
53
+ };
@@ -4,6 +4,17 @@ import { useITThemeSafe } from "../theme-provider/themeProvider";
4
4
  import { getContrastTextColor } from "@/utils/color.utils";
5
5
  import ITText from "@/components/text/text";
6
6
 
7
+ /**
8
+ * Colored header bar for modals and forms with an optional close button.
9
+ * Uses the theme's primary color as the background and automatically
10
+ * calculates a contrasting text color for readability.
11
+ *
12
+ * @example
13
+ * <ITFormHeader title="Create User" onClose={() => setOpen(false)} />
14
+ *
15
+ * @example
16
+ * <ITFormHeader title="Details" className="rounded-none" />
17
+ */
7
18
  export default function ITFormHeader({
8
19
  title,
9
20
  onClose,
@@ -0,0 +1,54 @@
1
+ import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
2
+ import * as Stories from './grid.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # ITGrid
7
+
8
+ A responsive 12-column CSS grid system for building flexible layouts. Supports grid container and item modes, configurable column spans per breakpoint, and customizable gap spacing.
9
+
10
+ ## Props
11
+
12
+ | Prop | Type | Default | Description |
13
+ |------|------|---------|-------------|
14
+ | `children` | `ReactNode` | `undefined` | Child elements rendered inside the grid. |
15
+ | `container` | `boolean` | `false` | When true, renders as a CSS grid parent. |
16
+ | `item` | `boolean` | `false` | When true, renders as a CSS grid child with column span. |
17
+ | `spacing` | `number` | `undefined` | Gap between children in units of 0.25rem. Container only. |
18
+ | `columns` | `number` | `12` | Number of grid columns (1-12). Container only. |
19
+ | `xs` | `number` | `undefined` | Column span at base breakpoint (mobile). Falls back to `sm`. |
20
+ | `sm` | `number` | `undefined` | Column span at the `sm` breakpoint. |
21
+ | `md` | `number` | `undefined` | Column span at the `md` breakpoint. |
22
+ | `lg` | `number` | `undefined` | Column span at the `lg` breakpoint. |
23
+ | `xl` | `number` | `undefined` | Column span at the `xl` breakpoint. |
24
+ | `className` | `string` | `undefined` | Additional CSS classes. |
25
+ | `style` | `CSSProperties` | `undefined` | Inline styles. |
26
+ | `as` | `ElementType` | `'div'` | Custom HTML element type to render instead of div. |
27
+
28
+ ## Usage
29
+
30
+ ```tsx
31
+ import { ITGrid } from '@axzydev/axzy_ui_system';
32
+
33
+ <ITGrid container spacing={3}>
34
+ <ITGrid item xs={12} md={8}>
35
+ <div>Main content</div>
36
+ </ITGrid>
37
+ <ITGrid item xs={12} md={4}>
38
+ <div>Sidebar</div>
39
+ </ITGrid>
40
+ </ITGrid>
41
+ ```
42
+
43
+ ## Notes
44
+
45
+ - Uses CSS Grid under the hood with responsive breakpoint classes.
46
+ - Omitting both `container` and `item` renders a plain `div` with no grid behavior.
47
+ - Breakpoint spans cascade down: if `lg` is not set, it inherits `md`, then `sm`, then `xs`.
48
+ - `spacing` multiplies by 0.25rem internally (spacing={2} = 0.5rem gap).
49
+
50
+ ## Stories
51
+
52
+ <Primary />
53
+ <Controls />
54
+ <Stories />
@@ -1,17 +1,30 @@
1
1
  import { ReactNode, CSSProperties, ElementType } from "react";
2
2
 
3
3
  export interface ITGridProps {
4
+ /** Child elements */
4
5
  children?: ReactNode;
6
+ /** Render as a grid container (CSS grid parent) */
5
7
  container?: boolean;
8
+ /** Render as a grid item (CSS grid child). If neither `container` nor `item` is set, renders a plain div */
6
9
  item?: boolean;
10
+ /** Gap between grid children in units of 0.25rem. Only applies when `container` is true */
7
11
  spacing?: number;
12
+ /** Number of grid columns (1-12). Only applies when `container` is true */
8
13
  columns?: number;
14
+ /** Column span at the base breakpoint (mobile). Falls back to `sm` if not set */
9
15
  xs?: number;
16
+ /** Column span at the `sm` breakpoint */
10
17
  sm?: number;
18
+ /** Column span at the `md` breakpoint */
11
19
  md?: number;
20
+ /** Column span at the `lg` breakpoint */
12
21
  lg?: number;
22
+ /** Column span at the `xl` breakpoint */
13
23
  xl?: number;
24
+ /** Additional CSS classes */
14
25
  className?: string;
26
+ /** Inline styles */
15
27
  style?: CSSProperties;
28
+ /** Custom HTML element type to render instead of the default `div` */
16
29
  as?: ElementType;
17
30
  }
@@ -18,6 +18,25 @@ function gridColsClass(cols: number) {
18
18
  return `grid-cols-${clamped}`;
19
19
  }
20
20
 
21
+ /**
22
+ * Responsive 12-column CSS grid layout system.
23
+ * Renders as a grid container when `container` is true, as a column-spanning
24
+ * item when `item` is true. Supports breakpoint-aware column spans and
25
+ * configurable spacing between items.
26
+ *
27
+ * @example
28
+ * <ITGrid container columns={12} spacing={4}>
29
+ * <ITGrid item xs={12} md={6}>Sidebar</ITGrid>
30
+ * <ITGrid item xs={12} md={6}>Content</ITGrid>
31
+ * </ITGrid>
32
+ *
33
+ * @example
34
+ * <ITGrid container columns={3} spacing={2} as="section">
35
+ * <ITGrid item>Card 1</ITGrid>
36
+ * <ITGrid item>Card 2</ITGrid>
37
+ * <ITGrid item>Card 3</ITGrid>
38
+ * </ITGrid>
39
+ */
21
40
  export default function ITGrid({
22
41
  children,
23
42
  container,
@@ -0,0 +1,44 @@
1
+ import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
2
+ import * as Stories from './image.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # ITImage
7
+
8
+ An image component with automatic fallback on load error. Uses a native `<img>` element with an error boundary that swaps the source to a fallback URL when the primary image fails to load.
9
+
10
+ ## Props
11
+
12
+ | Prop | Type | Default | Description |
13
+ |------|------|---------|-------------|
14
+ | `src` | `string` | required | Source URL of the image. |
15
+ | `alt` | `string` | `undefined` | Alt text for accessibility. |
16
+ | `className` | `string` | `undefined` | Additional CSS classes for the wrapper. |
17
+ | `fallback` | `string` | `undefined` | Fallback image URL shown when `src` fails to load. |
18
+ | `onClick` | `() => void` | `undefined` | Click handler on the image. |
19
+
20
+ ## Usage
21
+
22
+ ```tsx
23
+ import { ITImage } from '@axzydev/axzy_ui_system';
24
+
25
+ <ITImage
26
+ src="https://example.com/photo.jpg"
27
+ alt="Profile photo"
28
+ fallback="https://example.com/default-avatar.jpg"
29
+ />
30
+ <ITImage src="https://example.com/logo.png" />
31
+ ```
32
+
33
+ ## Notes
34
+
35
+ - Handles `onerror` internally to swap to the `fallback` URL.
36
+ - The wrapper is an inline-block `div` with full width/height for responsive sizing within a sized parent.
37
+ - If no `fallback` is provided and the image errors, the broken image icon is shown.
38
+ - Uses `object-cover` to fill the container while maintaining aspect ratio.
39
+
40
+ ## Stories
41
+
42
+ <Primary />
43
+ <Controls />
44
+ <Stories />
@@ -1,7 +1,12 @@
1
1
  export interface ITImageProps {
2
+ /** Source URL of the image */
2
3
  src: string;
4
+ /** Alt text for accessibility */
3
5
  alt?: string;
6
+ /** Additional CSS classes */
4
7
  className?: string;
8
+ /** Fallback image URL shown when the primary `src` fails to load */
5
9
  fallback?: string;
10
+ /** Click handler */
6
11
  onClick?: () => void;
7
12
  }
@@ -0,0 +1,49 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import ITImage from './image';
3
+
4
+ const meta = {
5
+ title: 'Components/Data Display/ITImage',
6
+ component: ITImage,
7
+ parameters: { layout: 'centered' },
8
+ tags: ['autodocs'],
9
+ argTypes: {
10
+ src: { control: 'text', description: 'Image source URL' },
11
+ alt: { control: 'text', description: 'Alternative text for accessibility' },
12
+ fallback: { control: 'text', description: 'Fallback image URL shown when the primary src fails to load' },
13
+ className: { control: 'text', description: 'Additional CSS classes for the wrapper' },
14
+ onClick: { control: false, description: 'Click handler' },
15
+ },
16
+ } satisfies Meta<typeof ITImage>;
17
+
18
+ export default meta;
19
+ type Story = StoryObj<typeof meta>;
20
+
21
+ const containerStyle = { width: 256, height: 192 };
22
+
23
+ export const Default: Story = {
24
+ args: {
25
+ src: 'https://picsum.photos/256/192',
26
+ alt: 'Random image',
27
+ className: 'rounded-lg overflow-hidden',
28
+ },
29
+ render: (args) => <div style={containerStyle}><ITImage {...args} /></div>,
30
+ };
31
+
32
+ export const WithFallbackError: Story = {
33
+ args: {
34
+ src: 'https://invalid-url/does-not-exist.jpg',
35
+ alt: 'Broken image',
36
+ fallback: 'https://picsum.photos/256/192?grayscale',
37
+ className: 'rounded-lg overflow-hidden',
38
+ },
39
+ render: (args) => <div style={containerStyle}><ITImage {...args} /></div>,
40
+ };
41
+
42
+ export const SquareAspectRatio: Story = {
43
+ args: {
44
+ src: 'https://picsum.photos/200/200',
45
+ alt: 'Square image',
46
+ className: 'rounded-full overflow-hidden',
47
+ },
48
+ render: (args) => <div style={{ width: 128, height: 128 }}><ITImage {...args} /></div>,
49
+ };
@@ -1,6 +1,25 @@
1
1
  import { useState } from "react";
2
2
  import { ITImageProps } from "./image.props";
3
3
 
4
+ /**
5
+ * Image component with automatic fallback on load error.
6
+ * Displays the primary `src` image and gracefully switches to the
7
+ * `fallback` image if loading fails.
8
+ *
9
+ * @example
10
+ * <ITImage
11
+ * src="https://example.com/photo.jpg"
12
+ * fallback="/images/placeholder.png"
13
+ * alt="User photo"
14
+ * />
15
+ *
16
+ * @example
17
+ * <ITImage
18
+ * src="/assets/logo.svg"
19
+ * alt="Company Logo"
20
+ * className="w-32 h-32 rounded-full"
21
+ * />
22
+ */
4
23
  const ITImage = ({
5
24
  src,
6
25
  alt,
@@ -0,0 +1,70 @@
1
+ import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
2
+ import * as Stories from './input.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # ITInput
7
+
8
+ A versatile form input component supporting text, password, email, number, textarea, checkbox, and radio types. Features labels, validation errors, left/right icons, helper text with character count, currency formatting, and configurable sizes.
9
+
10
+ ## Props
11
+
12
+ | Prop | Type | Default | Description |
13
+ |------|------|---------|-------------|
14
+ | `name` | `string` | required | Field name used for form identification. |
15
+ | `type` | `'text' \| 'password' \| 'number' \| 'email' \| 'checkbox' \| 'radio' \| 'textarea'` | `'text'` | Input type. |
16
+ | `label` | `string` | `undefined` | Label displayed above the input. |
17
+ | `placeholder` | `string` | `undefined` | Placeholder text. |
18
+ | `value` | `any` | `undefined` | Current input value. |
19
+ | `onChange` | `(event: any) => void` | required | Change event handler. |
20
+ | `onBlur` | `(event) => void` | `undefined` | Blur event handler. |
21
+ | `onKeyDown` | `(event) => void` | `undefined` | Keydown event handler. |
22
+ | `error` | `string \| boolean` | `undefined` | Validation error message. Pass `true` for generic error styling. |
23
+ | `touched` | `boolean` | `undefined` | Whether the field has been touched by the user. |
24
+ | `required` | `boolean` | `false` | Mark the field as required (adds asterisk to label). |
25
+ | `disabled` | `boolean` | `false` | Disable the input. |
26
+ | `size` | `SizesTypes` | `'md'` | Size preset: `xs`, `sm`, `md`, `lg`, `xl`. |
27
+ | `variant` | `ColorsTypes` | `undefined` | Color variant from the theme palette. |
28
+ | `iconLeft` | `ReactNode` | `undefined` | Icon element rendered on the left side. |
29
+ | `iconRight` | `ReactNode` | `undefined` | Icon element rendered on the right side. |
30
+ | `maxLength` | `number` | `undefined` | Maximum allowed character length. |
31
+ | `minLength` | `number` | `undefined` | Minimum allowed character length. |
32
+ | `showHintLength` | `boolean` | `false` | Show character count hint below the input. |
33
+ | `currencyFormat` | `boolean` | `false` | Enable currency formatting for number inputs (MX locale). |
34
+ | `formatNumber` | `boolean` | `false` | Enable number formatting on blur. |
35
+ | `autoFocus` | `boolean` | `false` | Auto-focus the input on mount. |
36
+ | `focusContent` | `boolean` | `false` | Select all content on click/focus. |
37
+ | `readOnly` | `boolean` | `false` | Render the input in read-only mode. |
38
+ | `min` | `number` | `undefined` | Minimum numeric value for number inputs. |
39
+ | `max` | `number` | `undefined` | Maximum numeric value for number inputs. |
40
+ | `rows` | `number` | `undefined` | Number of visible rows for textarea. |
41
+ | `checked` | `boolean` | `undefined` | Checked state for checkbox and radio types. |
42
+ | `containerClassName` | `string` | `undefined` | Additional CSS classes for the outer container. |
43
+ | `labelClassName` | `string` | `undefined` | Additional CSS classes for the label. |
44
+ | `className` | `string` | `undefined` | Additional CSS classes for the input element. |
45
+ | `onClick` | `() => void` | `undefined` | Click handler for the input. |
46
+
47
+ ## Usage
48
+
49
+ ```tsx
50
+ import { ITInput } from '@axzydev/axzy_ui_system';
51
+
52
+ <ITInput name="email" label="Email" type="email" placeholder="example@mail.com" />
53
+ <ITInput name="password" label="Password" type="password" iconLeft={<FaLock />} />
54
+ <ITInput name="bio" label="Bio" type="textarea" rows={4} />
55
+ <ITInput name="qty" label="Quantity" type="number" min={0} max={100} />
56
+ ```
57
+
58
+ ## Notes
59
+
60
+ - Error message only displays when both `error` and `touched` are truthy.
61
+ - `showHintLength` with `maxLength` displays a counter (e.g. "45/200").
62
+ - Currency formatting uses MX locale by default when `currencyFormat` is true.
63
+ - Icons rendered via `iconLeft`/`iconRight` can be clickable React nodes (e.g. a toggle visibility button).
64
+ - Checkbox and radio types render inline labels instead of stacked layout.
65
+
66
+ ## Stories
67
+
68
+ <Primary />
69
+ <Controls />
70
+ <Stories />