@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.
- package/dist/index.cjs +576 -398
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +1463 -86
- package/dist/index.d.ts +1463 -86
- package/dist/index.js +597 -417
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/App.tsx +19 -54
- package/src/components/alert/alert.doc.mdx +48 -0
- package/src/components/alert/alert.props.ts +7 -0
- package/src/components/alert/alert.tsx +8 -0
- package/src/components/avatar/avatar.doc.mdx +48 -0
- package/src/components/avatar/avatar.props.ts +8 -0
- package/src/components/avatar/avatar.tsx +25 -5
- package/src/components/badget/badget.doc.mdx +46 -0
- package/src/components/badget/badget.props.ts +6 -0
- package/src/components/badget/badget.tsx +11 -0
- package/src/components/breadcrumbs/breadcrumbs.doc.mdx +57 -0
- package/src/components/breadcrumbs/breadcrumbs.props.ts +6 -0
- package/src/components/breadcrumbs/breadcrumbs.tsx +12 -0
- package/src/components/button/button.doc.mdx +59 -0
- package/src/components/button/button.props.ts +12 -0
- package/src/components/button/button.tsx +11 -0
- package/src/components/calendar/calendar.doc.mdx +75 -0
- package/src/components/calendar/calendar.props.ts +27 -7
- package/src/components/calendar/calendar.tsx +13 -0
- package/src/components/card/card.doc.mdx +54 -0
- package/src/components/card/card.props.ts +11 -0
- package/src/components/card/card.tsx +13 -0
- package/src/components/checkbox/checkbox.doc.mdx +54 -0
- package/src/components/checkbox/checkbox.props.ts +7 -0
- package/src/components/checkbox/checkbox.tsx +9 -0
- package/src/components/confirm-dialog/confirm-dialog.doc.mdx +60 -0
- package/src/components/confirm-dialog/confirm-dialog.props.ts +9 -0
- package/src/components/confirm-dialog/confirm-dialog.tsx +19 -0
- package/src/components/data-table/ITDataTable.doc.mdx +59 -0
- package/src/components/data-table/dataTable.props.ts +15 -0
- package/src/components/data-table/dataTable.tsx +178 -73
- package/src/components/date-picker/date-picker.doc.mdx +65 -0
- package/src/components/date-picker/date-picker.props.ts +17 -0
- package/src/components/date-picker/datePicker.tsx +31 -1
- package/src/components/dialog/dialog.doc.mdx +54 -0
- package/src/components/dialog/dialog.props.ts +7 -0
- package/src/components/dialog/dialog.tsx +26 -0
- package/src/components/divider/divider.doc.mdx +42 -0
- package/src/components/divider/divider.props.ts +5 -0
- package/src/components/divider/divider.tsx +16 -0
- package/src/components/drawer/drawer.doc.mdx +59 -0
- package/src/components/drawer/drawer.props.ts +9 -0
- package/src/components/drawer/drawer.tsx +20 -0
- package/src/components/dropfile/dropfile.doc.mdx +59 -0
- package/src/components/dropfile/dropfile.props.ts +41 -0
- package/src/components/dropfile/dropfile.tsx +21 -33
- package/src/components/empty-state/empty-state.doc.mdx +50 -0
- package/src/components/empty-state/empty-state.props.ts +5 -0
- package/src/components/empty-state/empty-state.tsx +16 -0
- package/src/components/flex/flex.doc.mdx +59 -0
- package/src/components/flex/flex.props.ts +13 -0
- package/src/components/flex/flex.tsx +15 -0
- package/src/components/form-builder/fieldRenderer.tsx +52 -2
- package/src/components/form-builder/formBuilder.doc.mdx +124 -0
- package/src/components/form-builder/formBuilder.props.ts +12 -2
- package/src/components/form-builder/formBuilder.tsx +31 -0
- package/src/components/form-header/form-header.doc.mdx +38 -0
- package/src/components/form-header/form-header.props.ts +3 -0
- package/src/components/form-header/form-header.stories.tsx +53 -0
- package/src/components/form-header/form-header.tsx +11 -0
- package/src/components/grid/grid.doc.mdx +54 -0
- package/src/components/grid/grid.props.ts +13 -0
- package/src/components/grid/grid.tsx +19 -0
- package/src/components/image/image.doc.mdx +44 -0
- package/src/components/image/image.props.ts +5 -0
- package/src/components/image/image.stories.tsx +49 -0
- package/src/components/image/image.tsx +19 -0
- package/src/components/input/input.doc.mdx +70 -0
- package/src/components/input/input.props.ts +34 -2
- package/src/components/input/input.tsx +29 -0
- package/src/components/layout/layout.doc.mdx +51 -0
- package/src/components/layout/layout.props.ts +5 -0
- package/src/components/layout/layout.tsx +29 -2
- package/src/components/loader/loader.doc.mdx +43 -0
- package/src/components/loader/loader.props.ts +4 -0
- package/src/components/loader/loader.tsx +17 -0
- package/src/components/navbar/navbar.doc.mdx +77 -0
- package/src/components/navbar/navbar.props.ts +37 -1
- package/src/components/navbar/navbar.stories.tsx +84 -0
- package/src/components/navbar/navbar.tsx +27 -0
- package/src/components/page/page.doc.mdx +80 -0
- package/src/components/page/page.props.ts +21 -0
- package/src/components/page/page.tsx +18 -0
- package/src/components/page-header/page-header.doc.mdx +54 -0
- package/src/components/page-header/page-header.props.ts +9 -0
- package/src/components/page-header/page-header.tsx +15 -0
- package/src/components/pagination/pagination.doc.mdx +62 -0
- package/src/components/pagination/pagination.props.ts +11 -32
- package/src/components/pagination/pagination.tsx +17 -0
- package/src/components/popover/popover.doc.mdx +53 -0
- package/src/components/popover/popover.props.ts +8 -0
- package/src/components/popover/popover.tsx +13 -0
- package/src/components/progress/progress.doc.mdx +48 -0
- package/src/components/progress/progress.props.ts +8 -0
- package/src/components/progress/progress.tsx +9 -0
- package/src/components/radio/radio.doc.mdx +62 -0
- package/src/components/radio/radio.props.ts +11 -0
- package/src/components/radio/radio.tsx +18 -0
- package/src/components/search-select/search-select.doc.mdx +72 -0
- package/src/components/search-select/search-select.props.ts +23 -18
- package/src/components/search-select/search-select.tsx +27 -2
- package/src/components/searchTable/searchTable.doc.mdx +79 -0
- package/src/components/searchTable/searchTable.props.ts +42 -3
- package/src/components/searchTable/searchTable.stories.tsx +74 -0
- package/src/components/searchTable/searchTable.tsx +23 -0
- package/src/components/segmented-control/segmented-control.doc.mdx +60 -0
- package/src/components/segmented-control/segmented-control.props.ts +12 -0
- package/src/components/segmented-control/segmented-control.tsx +15 -0
- package/src/components/select/select.doc.mdx +75 -0
- package/src/components/select/select.props.ts +22 -0
- package/src/components/select/select.tsx +2 -5
- package/src/components/sidebar/sidebar.doc.mdx +86 -0
- package/src/components/sidebar/sidebar.props.ts +22 -0
- package/src/components/sidebar/sidebar.tsx +22 -0
- package/src/components/skeleton/skeleton.doc.mdx +43 -0
- package/src/components/skeleton/skeleton.props.ts +8 -0
- package/src/components/skeleton/skeleton.tsx +10 -0
- package/src/components/slide/slide.doc.mdx +46 -0
- package/src/components/slide/slide.props.ts +11 -24
- package/src/components/slide/slide.tsx +10 -1
- package/src/components/slider/slider.doc.mdx +49 -0
- package/src/components/slider/slider.props.ts +9 -0
- package/src/components/slider/slider.tsx +15 -0
- package/src/components/stack/stack.doc.mdx +126 -0
- package/src/components/stack/stack.props.ts +18 -0
- package/src/components/stack/stack.stories.tsx +221 -16
- package/src/components/stack/stack.tsx +21 -0
- package/src/components/stat-card/stat-card.doc.mdx +48 -0
- package/src/components/stat-card/stat-card.props.ts +9 -0
- package/src/components/stat-card/stat-card.tsx +10 -0
- package/src/components/stepper/stepper.doc.mdx +54 -0
- package/src/components/stepper/stepper.props.ts +11 -1
- package/src/components/stepper/stepper.tsx +15 -0
- package/src/components/table/table.doc.mdx +58 -0
- package/src/components/table/table.props.ts +17 -0
- package/src/components/table/table.tsx +199 -84
- package/src/components/tabs/tabs.doc.mdx +52 -0
- package/src/components/tabs/tabs.props.ts +11 -0
- package/src/components/tabs/tabs.tsx +14 -0
- package/src/components/text/text.doc.mdx +41 -0
- package/src/components/text/text.props.ts +5 -0
- package/src/components/text/text.stories.tsx +67 -0
- package/src/components/text/text.tsx +10 -0
- package/src/components/textarea/textarea.doc.mdx +64 -0
- package/src/components/textarea/textarea.props.ts +11 -0
- package/src/components/textarea/textarea.tsx +16 -0
- package/src/components/theme-provider/themeProvider.doc.mdx +75 -0
- package/src/components/theme-provider/themeProvider.props.ts +3 -0
- package/src/components/theme-provider/themeProvider.stories.tsx +59 -0
- package/src/components/theme-provider/themeProvider.tsx +14 -0
- package/src/components/time-picker/timePicker.doc.mdx +68 -0
- package/src/components/time-picker/timePicker.props.ts +14 -0
- package/src/components/time-picker/timePicker.tsx +22 -1
- package/src/components/toast/toast.doc.mdx +50 -0
- package/src/components/toast/toast.props.ts +5 -0
- package/src/components/toast/toast.tsx +21 -0
- package/src/components/tooltip/tooltip.doc.mdx +47 -0
- package/src/components/tooltip/tooltip.props.ts +6 -0
- package/src/components/tooltip/tooltip.tsx +19 -0
- package/src/components/topbar/topbar.doc.mdx +69 -0
- package/src/components/topbar/topbar.props.ts +15 -0
- package/src/components/topbar/topbar.tsx +38 -0
- package/src/components/triple-filter/tripleFilter.doc.mdx +62 -0
- package/src/components/triple-filter/tripleFilter.props.ts +7 -0
- package/src/components/triple-filter/tripleFilter.tsx +32 -0
- package/src/index.css +2 -0
- package/src/showcases/DataShowcases.tsx +529 -45
- package/src/showcases/FormShowcases.tsx +399 -29
- package/src/showcases/HomeShowcase.tsx +252 -272
- package/src/showcases/LayoutPrimitivesShowcases.tsx +1224 -248
- package/src/showcases/PageShowcases.tsx +688 -391
- package/src/showcases/ShowcaseLayout.tsx +237 -73
- package/src/showcases/StructureShowcases.tsx +846 -73
- package/src/types/table.types.ts +1 -1
- 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
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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={
|
|
162
|
+
options={resolvedOptions}
|
|
113
163
|
name={name}
|
|
114
164
|
disabled={isDisabled as boolean}
|
|
115
165
|
label={label || ""}
|