@axzydev/axzy_ui_system 1.2.1 → 1.2.3
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 +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +82 -1
- package/dist/index.css.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/App.tsx +354 -0
- package/src/assets/logo.png +0 -0
- package/src/assets/react.svg +1 -0
- package/src/components/alert/alert.props.ts +13 -0
- package/src/components/alert/alert.stories.tsx +41 -0
- package/src/components/alert/alert.tsx +53 -0
- package/src/components/avatar/avatar.props.ts +14 -0
- package/src/components/avatar/avatar.stories.tsx +46 -0
- package/src/components/avatar/avatar.tsx +53 -0
- package/src/components/badget/badget.props.ts +12 -0
- package/src/components/badget/badget.stories.tsx +76 -0
- package/src/components/badget/badget.tsx +61 -0
- package/src/components/breadcrumbs/breadcrumbs.props.ts +13 -0
- package/src/components/breadcrumbs/breadcrumbs.stories.tsx +21 -0
- package/src/components/breadcrumbs/breadcrumbs.tsx +34 -0
- package/src/components/button/button.props.ts +18 -0
- package/src/components/button/button.stories.tsx +174 -0
- package/src/components/button/button.tsx +117 -0
- package/src/components/calendar/calendar.props.ts +33 -0
- package/src/components/calendar/calendar.stories.tsx +91 -0
- package/src/components/calendar/calendar.tsx +608 -0
- package/src/components/calendar/index.ts +3 -0
- package/src/components/card/card.props.ts +13 -0
- package/src/components/card/card.stories.tsx +58 -0
- package/src/components/card/card.tsx +79 -0
- package/src/components/checkbox/checkbox.props.ts +11 -0
- package/src/components/checkbox/checkbox.stories.tsx +54 -0
- package/src/components/checkbox/checkbox.tsx +52 -0
- package/src/components/confirm-dialog/confirm-dialog.props.ts +14 -0
- package/src/components/confirm-dialog/confirm-dialog.stories.tsx +33 -0
- package/src/components/confirm-dialog/confirm-dialog.tsx +45 -0
- package/src/components/data-table/ITDataTable.stories.tsx +213 -0
- package/src/components/data-table/dataTable.props.ts +69 -0
- package/src/components/data-table/dataTable.tsx +313 -0
- package/src/components/date-picker/date-picker.props.ts +30 -0
- package/src/components/date-picker/date-picker.stories.tsx +90 -0
- package/src/components/date-picker/datePicker.tsx +307 -0
- package/src/components/dialog/dialog.props.ts +9 -0
- package/src/components/dialog/dialog.stories.tsx +80 -0
- package/src/components/dialog/dialog.tsx +88 -0
- package/src/components/divider/divider.props.ts +8 -0
- package/src/components/divider/divider.stories.tsx +34 -0
- package/src/components/divider/divider.tsx +21 -0
- package/src/components/drawer/drawer.props.ts +14 -0
- package/src/components/drawer/drawer.stories.tsx +41 -0
- package/src/components/drawer/drawer.tsx +53 -0
- package/src/components/dropfile/dropfile.stories.tsx +75 -0
- package/src/components/dropfile/dropfile.tsx +407 -0
- package/src/components/empty-state/empty-state.props.ts +9 -0
- package/src/components/empty-state/empty-state.stories.tsx +20 -0
- package/src/components/empty-state/empty-state.tsx +21 -0
- package/src/components/flex/flex.props.ts +22 -0
- package/src/components/flex/flex.stories.tsx +71 -0
- package/src/components/flex/flex.tsx +79 -0
- package/src/components/form-builder/fieldRenderer.tsx +218 -0
- package/src/components/form-builder/formBuilder.context.tsx +70 -0
- package/src/components/form-builder/formBuilder.props.ts +43 -0
- package/src/components/form-builder/formBuilder.stories.tsx +317 -0
- package/src/components/form-builder/formBuilder.tsx +186 -0
- package/src/components/form-builder/useFormBuilder.ts +80 -0
- package/src/components/form-header/form-header.props.ts +5 -0
- package/src/components/form-header/form-header.tsx +38 -0
- package/src/components/grid/grid.props.ts +17 -0
- package/src/components/grid/grid.stories.tsx +72 -0
- package/src/components/grid/grid.tsx +69 -0
- package/src/components/image/image.props.ts +7 -0
- package/src/components/image/image.tsx +38 -0
- package/src/components/input/input.props.ts +49 -0
- package/src/components/input/input.stories.tsx +115 -0
- package/src/components/input/input.tsx +615 -0
- package/src/components/layout/layout.props.ts +10 -0
- package/src/components/layout/layout.stories.tsx +114 -0
- package/src/components/layout/layout.tsx +80 -0
- package/src/components/loader/loader.props.ts +8 -0
- package/src/components/loader/loader.stories.tsx +105 -0
- package/src/components/loader/loader.tsx +108 -0
- package/src/components/navbar/navbar.props.ts +37 -0
- package/src/components/navbar/navbar.tsx +328 -0
- package/src/components/page/page.props.ts +19 -0
- package/src/components/page/page.stories.tsx +98 -0
- package/src/components/page/page.tsx +90 -0
- package/src/components/page-header/page-header.props.ts +11 -0
- package/src/components/page-header/page-header.stories.tsx +61 -0
- package/src/components/page-header/page-header.tsx +62 -0
- package/src/components/pagination/pagination.props.ts +53 -0
- package/src/components/pagination/pagination.stories.tsx +111 -0
- package/src/components/pagination/pagination.tsx +241 -0
- package/src/components/popover/popover.props.ts +12 -0
- package/src/components/popover/popover.stories.tsx +25 -0
- package/src/components/popover/popover.tsx +45 -0
- package/src/components/progress/progress.props.ts +12 -0
- package/src/components/progress/progress.stories.tsx +40 -0
- package/src/components/progress/progress.tsx +52 -0
- package/src/components/radio/radio.props.ts +16 -0
- package/src/components/radio/radio.stories.tsx +50 -0
- package/src/components/radio/radio.tsx +58 -0
- package/src/components/search-select/index.ts +2 -0
- package/src/components/search-select/search-select.props.ts +46 -0
- package/src/components/search-select/search-select.stories.tsx +129 -0
- package/src/components/search-select/search-select.tsx +229 -0
- package/src/components/searchTable/components/EditableCell.tsx +149 -0
- package/src/components/searchTable/components/PaginationControls.tsx +86 -0
- package/src/components/searchTable/components/PaginationInfo.tsx +20 -0
- package/src/components/searchTable/components/SearchAndSortBar.tsx +53 -0
- package/src/components/searchTable/components/SearchInput.tsx +33 -0
- package/src/components/searchTable/components/SortButton.tsx +50 -0
- package/src/components/searchTable/components/TableEmptyState.tsx +22 -0
- package/src/components/searchTable/components/TableHeader.tsx +35 -0
- package/src/components/searchTable/components/TableHeaderCell.tsx +43 -0
- package/src/components/searchTable/components/TableRow.tsx +144 -0
- package/src/components/searchTable/searchTable.props.ts +56 -0
- package/src/components/searchTable/searchTable.tsx +187 -0
- package/src/components/segmented-control/segmented-control.props.ts +18 -0
- package/src/components/segmented-control/segmented-control.stories.tsx +63 -0
- package/src/components/segmented-control/segmented-control.tsx +52 -0
- package/src/components/select/select.props.ts +25 -0
- package/src/components/select/select.stories.tsx +86 -0
- package/src/components/select/select.tsx +150 -0
- package/src/components/sidebar/sidebar.props.ts +28 -0
- package/src/components/sidebar/sidebar.stories.tsx +117 -0
- package/src/components/sidebar/sidebar.tsx +313 -0
- package/src/components/skeleton/skeleton.props.ts +12 -0
- package/src/components/skeleton/skeleton.stories.tsx +30 -0
- package/src/components/skeleton/skeleton.tsx +45 -0
- package/src/components/slide/slide.props.ts +45 -0
- package/src/components/slide/slide.stories.tsx +121 -0
- package/src/components/slide/slide.tsx +109 -0
- package/src/components/slider/slider.props.ts +10 -0
- package/src/components/slider/slider.stories.tsx +30 -0
- package/src/components/slider/slider.tsx +49 -0
- package/src/components/stack/stack.props.ts +19 -0
- package/src/components/stack/stack.stories.tsx +79 -0
- package/src/components/stack/stack.tsx +79 -0
- package/src/components/stat-card/stat-card.props.ts +13 -0
- package/src/components/stat-card/stat-card.stories.tsx +41 -0
- package/src/components/stat-card/stat-card.tsx +44 -0
- package/src/components/stepper/stepper.css +26 -0
- package/src/components/stepper/stepper.props.ts +29 -0
- package/src/components/stepper/stepper.stories.tsx +155 -0
- package/src/components/stepper/stepper.tsx +227 -0
- package/src/components/table/table.props.ts +43 -0
- package/src/components/table/table.stories.tsx +189 -0
- package/src/components/table/table.tsx +376 -0
- package/src/components/tabs/tabs.props.ts +18 -0
- package/src/components/tabs/tabs.stories.tsx +32 -0
- package/src/components/tabs/tabs.tsx +74 -0
- package/src/components/text/text.props.ts +9 -0
- package/src/components/text/text.tsx +20 -0
- package/src/components/textarea/textarea.props.ts +15 -0
- package/src/components/textarea/textarea.stories.tsx +27 -0
- package/src/components/textarea/textarea.tsx +55 -0
- package/src/components/theme-provider/themeProvider.props.ts +28 -0
- package/src/components/theme-provider/themeProvider.tsx +1854 -0
- package/src/components/time-picker/timePicker.props.ts +16 -0
- package/src/components/time-picker/timePicker.stories.tsx +131 -0
- package/src/components/time-picker/timePicker.tsx +317 -0
- package/src/components/toast/toast.css +32 -0
- package/src/components/toast/toast.props.ts +13 -0
- package/src/components/toast/toast.stories.tsx +138 -0
- package/src/components/toast/toast.tsx +87 -0
- package/src/components/tooltip/tooltip.props.ts +11 -0
- package/src/components/tooltip/tooltip.stories.tsx +20 -0
- package/src/components/tooltip/tooltip.tsx +55 -0
- package/src/components/topbar/topbar.props.ts +21 -0
- package/src/components/topbar/topbar.stories.tsx +80 -0
- package/src/components/topbar/topbar.tsx +205 -0
- package/src/components/triple-filter/tripleFilter.props.ts +15 -0
- package/src/components/triple-filter/tripleFilter.stories.tsx +32 -0
- package/src/components/triple-filter/tripleFilter.tsx +50 -0
- package/src/dev.css +2 -0
- package/src/hooks/useClickOutside.ts +21 -0
- package/src/hooks/useDebouncedSearch.ts +55 -0
- package/src/hooks/useEditableRow.ts +157 -0
- package/src/hooks/useTableState.ts +122 -0
- package/src/index.css +168 -0
- package/src/index.ts +165 -0
- package/src/main.tsx +9 -0
- package/src/showcases/DataShowcases.tsx +260 -0
- package/src/showcases/FeedbackShowcases.tsx +268 -0
- package/src/showcases/FormShowcases.tsx +1159 -0
- package/src/showcases/HomeShowcase.tsx +324 -0
- package/src/showcases/LayoutPrimitivesShowcases.tsx +569 -0
- package/src/showcases/NavigationShowcases.tsx +193 -0
- package/src/showcases/PageShowcases.tsx +207 -0
- package/src/showcases/ShowcaseLayout.tsx +139 -0
- package/src/showcases/StructureShowcases.tsx +152 -0
- package/src/types/badget.types.ts +37 -0
- package/src/types/button.types.ts +16 -0
- package/src/types/colors.types.ts +3 -0
- package/src/types/field.types.ts +103 -0
- package/src/types/formik.types.ts +15 -0
- package/src/types/input.types.ts +14 -0
- package/src/types/loader.types.ts +9 -0
- package/src/types/sizes.types.ts +1 -0
- package/src/types/table.types.ts +15 -0
- package/src/types/toast.types.ts +8 -0
- package/src/types/yup.types.ts +11 -0
- package/src/utils/color.utils.ts +99 -0
- package/src/utils/styles.ts +120 -0
- package/src/utils/table.utils.ts +10 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import ITSlider from "./slider";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof ITSlider> = {
|
|
6
|
+
title: "Components/Inputs/ITSlider",
|
|
7
|
+
component: ITSlider,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
type Story = StoryObj<typeof ITSlider>;
|
|
13
|
+
|
|
14
|
+
export const Default: Story = {
|
|
15
|
+
render: () => {
|
|
16
|
+
const [val, setVal] = useState(50);
|
|
17
|
+
return <ITSlider value={val} onChange={setVal} min={0} max={100} label="Volume" />;
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const WithRange: Story = {
|
|
22
|
+
render: () => {
|
|
23
|
+
const [val, setVal] = useState(3);
|
|
24
|
+
return <ITSlider value={val} onChange={setVal} min={1} max={10} step={1} label="Items per page" />;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const Disabled: Story = {
|
|
29
|
+
render: () => <ITSlider value={40} onChange={() => {}} disabled label="Disabled" />,
|
|
30
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import { ITSliderProps } from "./slider.props";
|
|
3
|
+
import ITText from "@/components/text/text";
|
|
4
|
+
|
|
5
|
+
export default function ITSlider({
|
|
6
|
+
value,
|
|
7
|
+
onChange,
|
|
8
|
+
min = 0,
|
|
9
|
+
max = 100,
|
|
10
|
+
step = 1,
|
|
11
|
+
label,
|
|
12
|
+
disabled = false,
|
|
13
|
+
className,
|
|
14
|
+
}: ITSliderProps) {
|
|
15
|
+
return (
|
|
16
|
+
<div className={clsx("flex flex-col gap-1.5", className)}>
|
|
17
|
+
{label && (
|
|
18
|
+
<ITText as="label" className="text-xs font-semibold text-gray-600 dark:text-gray-400">
|
|
19
|
+
{label}: {value}
|
|
20
|
+
</ITText>
|
|
21
|
+
)}
|
|
22
|
+
<div className="relative w-full h-5 flex items-center">
|
|
23
|
+
<input
|
|
24
|
+
type="range"
|
|
25
|
+
min={min}
|
|
26
|
+
max={max}
|
|
27
|
+
step={step}
|
|
28
|
+
value={value}
|
|
29
|
+
onChange={(e) => onChange(Number(e.target.value))}
|
|
30
|
+
disabled={disabled}
|
|
31
|
+
className={clsx(
|
|
32
|
+
"w-full h-1.5 appearance-none rounded-full outline-none cursor-pointer",
|
|
33
|
+
"bg-gray-200 dark:bg-gray-700",
|
|
34
|
+
"accent-primary-500",
|
|
35
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
36
|
+
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
|
|
37
|
+
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-primary-500",
|
|
38
|
+
"[&::-webkit-slider-thumb]:shadow-md [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-white",
|
|
39
|
+
"[&::-webkit-slider-thumb]:hover:bg-primary-600 [&::-webkit-slider-thumb]:transition-colors",
|
|
40
|
+
"[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:rounded-full",
|
|
41
|
+
"[&::-moz-range-thumb]:bg-primary-500 [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-white",
|
|
42
|
+
"[&::-moz-range-track]:bg-gray-200 dark:[&::-moz-range-track]:bg-gray-700",
|
|
43
|
+
"[&::-moz-range-track]:rounded-full [&::-moz-range-track]:h-1.5"
|
|
44
|
+
)}
|
|
45
|
+
/>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactNode, CSSProperties, ElementType } from "react";
|
|
2
|
+
|
|
3
|
+
export type StackDirection = "row" | "column" | "row-reverse" | "column-reverse";
|
|
4
|
+
export type StackAlignment = "start" | "end" | "center" | "stretch" | "baseline";
|
|
5
|
+
export type StackJustify = "start" | "end" | "center" | "between" | "around" | "evenly";
|
|
6
|
+
export type StackWrap = "nowrap" | "wrap" | "wrap-reverse";
|
|
7
|
+
|
|
8
|
+
export interface ITStackProps {
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
direction?: StackDirection;
|
|
11
|
+
spacing?: number;
|
|
12
|
+
alignItems?: StackAlignment;
|
|
13
|
+
justifyContent?: StackJustify;
|
|
14
|
+
flexWrap?: StackWrap;
|
|
15
|
+
divider?: ReactNode;
|
|
16
|
+
className?: string;
|
|
17
|
+
style?: CSSProperties;
|
|
18
|
+
as?: ElementType;
|
|
19
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import ITStack from "./stack";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof ITStack> = {
|
|
5
|
+
title: "Layout/ITStack",
|
|
6
|
+
component: ITStack,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
argTypes: {
|
|
9
|
+
direction: {
|
|
10
|
+
control: "select",
|
|
11
|
+
options: ["row", "column", "row-reverse", "column-reverse"],
|
|
12
|
+
},
|
|
13
|
+
spacing: { control: { type: "range", min: 0, max: 16, step: 1 } },
|
|
14
|
+
alignItems: {
|
|
15
|
+
control: "select",
|
|
16
|
+
options: [undefined, "start", "end", "center", "stretch", "baseline"],
|
|
17
|
+
},
|
|
18
|
+
justifyContent: {
|
|
19
|
+
control: "select",
|
|
20
|
+
options: [undefined, "start", "end", "center", "between", "around", "evenly"],
|
|
21
|
+
},
|
|
22
|
+
flexWrap: {
|
|
23
|
+
control: "select",
|
|
24
|
+
options: [undefined, "nowrap", "wrap", "wrap-reverse"],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default meta;
|
|
30
|
+
type Story = StoryObj<typeof ITStack>;
|
|
31
|
+
|
|
32
|
+
const Box = ({ children, className = "" }: { children: string; className?: string }) => (
|
|
33
|
+
<div className={`bg-primary-100 text-primary-800 rounded-lg p-4 text-center font-medium ${className}`}>
|
|
34
|
+
{children}
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export const Vertical: Story = {
|
|
39
|
+
args: { direction: "column", spacing: 2, children: null },
|
|
40
|
+
render: (args) => (
|
|
41
|
+
<ITStack {...args}>
|
|
42
|
+
<Box>Item 1</Box>
|
|
43
|
+
<Box>Item 2</Box>
|
|
44
|
+
<Box>Item 3</Box>
|
|
45
|
+
</ITStack>
|
|
46
|
+
),
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const Horizontal: Story = {
|
|
50
|
+
args: { direction: "row", spacing: 2, children: null },
|
|
51
|
+
render: (args) => (
|
|
52
|
+
<ITStack {...args}>
|
|
53
|
+
<Box>Item 1</Box>
|
|
54
|
+
<Box>Item 2</Box>
|
|
55
|
+
<Box>Item 3</Box>
|
|
56
|
+
</ITStack>
|
|
57
|
+
),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const WithDivider: Story = {
|
|
61
|
+
args: { direction: "row", spacing: 2, divider: <div className="w-px bg-gray-300 self-stretch" /> },
|
|
62
|
+
render: (args) => (
|
|
63
|
+
<ITStack {...args}>
|
|
64
|
+
<Box>Item 1</Box>
|
|
65
|
+
<Box>Item 2</Box>
|
|
66
|
+
<Box>Item 3</Box>
|
|
67
|
+
</ITStack>
|
|
68
|
+
),
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const Centered: Story = {
|
|
72
|
+
args: { direction: "row", spacing: 4, alignItems: "center", justifyContent: "center", className: "h-40 bg-gray-50 rounded-xl" },
|
|
73
|
+
render: (args) => (
|
|
74
|
+
<ITStack {...args}>
|
|
75
|
+
<Box>Center</Box>
|
|
76
|
+
<Box>Middle</Box>
|
|
77
|
+
</ITStack>
|
|
78
|
+
),
|
|
79
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import { Children, cloneElement, isValidElement, Fragment } from "react";
|
|
3
|
+
import { ITStackProps, StackDirection, StackAlignment, StackJustify, StackWrap } from "./stack.props";
|
|
4
|
+
|
|
5
|
+
const directionMap: Record<StackDirection, string> = {
|
|
6
|
+
row: "flex-row",
|
|
7
|
+
column: "flex-col",
|
|
8
|
+
"row-reverse": "flex-row-reverse",
|
|
9
|
+
"column-reverse": "flex-col-reverse",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const alignMap: Record<StackAlignment, string> = {
|
|
13
|
+
start: "items-start",
|
|
14
|
+
end: "items-end",
|
|
15
|
+
center: "items-center",
|
|
16
|
+
stretch: "items-stretch",
|
|
17
|
+
baseline: "items-baseline",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const justifyMap: Record<StackJustify, string> = {
|
|
21
|
+
start: "justify-start",
|
|
22
|
+
end: "justify-end",
|
|
23
|
+
center: "justify-center",
|
|
24
|
+
between: "justify-between",
|
|
25
|
+
around: "justify-around",
|
|
26
|
+
evenly: "justify-evenly",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const wrapMap: Record<StackWrap, string> = {
|
|
30
|
+
nowrap: "flex-nowrap",
|
|
31
|
+
wrap: "flex-wrap",
|
|
32
|
+
"wrap-reverse": "flex-wrap-reverse",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default function ITStack({
|
|
36
|
+
children,
|
|
37
|
+
direction = "column",
|
|
38
|
+
spacing = 0,
|
|
39
|
+
alignItems,
|
|
40
|
+
justifyContent,
|
|
41
|
+
flexWrap,
|
|
42
|
+
divider,
|
|
43
|
+
className,
|
|
44
|
+
style,
|
|
45
|
+
as: Component = "div",
|
|
46
|
+
}: ITStackProps) {
|
|
47
|
+
const hasDivider = divider !== undefined;
|
|
48
|
+
const items = Children.toArray(children);
|
|
49
|
+
|
|
50
|
+
const resolvedStyle: React.CSSProperties = {
|
|
51
|
+
gap: spacing > 0 ? `${spacing * 0.25}rem` : undefined,
|
|
52
|
+
...style,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<Component
|
|
57
|
+
className={clsx(
|
|
58
|
+
"flex",
|
|
59
|
+
directionMap[direction],
|
|
60
|
+
alignItems && alignMap[alignItems],
|
|
61
|
+
justifyContent && justifyMap[justifyContent],
|
|
62
|
+
flexWrap && wrapMap[flexWrap],
|
|
63
|
+
className
|
|
64
|
+
)}
|
|
65
|
+
style={resolvedStyle}
|
|
66
|
+
>
|
|
67
|
+
{hasDivider
|
|
68
|
+
? items.map((child, index) => (
|
|
69
|
+
<Fragment key={index}>
|
|
70
|
+
{child}
|
|
71
|
+
{index < items.length - 1 && isValidElement(divider)
|
|
72
|
+
? cloneElement(divider, { key: `divider-${index}` })
|
|
73
|
+
: null}
|
|
74
|
+
</Fragment>
|
|
75
|
+
))
|
|
76
|
+
: children}
|
|
77
|
+
</Component>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ReactNode, CSSProperties } from "react";
|
|
2
|
+
|
|
3
|
+
export interface ITStatCardProps {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string | number;
|
|
6
|
+
trend?: string;
|
|
7
|
+
trendDirection?: "up" | "down" | "neutral";
|
|
8
|
+
icon?: ReactNode;
|
|
9
|
+
color?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
style?: CSSProperties;
|
|
12
|
+
onClick?: () => void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import ITStatCard from "./stat-card";
|
|
3
|
+
import { FaArrowUp, FaArrowDown } from "react-icons/fa";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof ITStatCard> = {
|
|
6
|
+
title: "Components/Data Display/ITStatCard",
|
|
7
|
+
component: ITStatCard,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
type Story = StoryObj<typeof ITStatCard>;
|
|
13
|
+
|
|
14
|
+
export const Default: Story = {
|
|
15
|
+
args: {
|
|
16
|
+
label: "Usuarios Activos",
|
|
17
|
+
value: "1,245",
|
|
18
|
+
trend: "+12.5%",
|
|
19
|
+
trendDirection: "up",
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const Negative: Story = {
|
|
24
|
+
args: {
|
|
25
|
+
label: "Tickets Abiertos",
|
|
26
|
+
value: "23",
|
|
27
|
+
trend: "-8.2%",
|
|
28
|
+
trendDirection: "down",
|
|
29
|
+
color: "bg-rose-50 dark:bg-rose-950/20",
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const WithIcon: Story = {
|
|
34
|
+
args: {
|
|
35
|
+
label: "Ventas Hoy",
|
|
36
|
+
value: "$4,320",
|
|
37
|
+
trend: "+5.4%",
|
|
38
|
+
trendDirection: "up",
|
|
39
|
+
icon: <FaArrowUp size={12} />,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import { ITStatCardProps } from "./stat-card.props";
|
|
3
|
+
import ITText from "@/components/text/text";
|
|
4
|
+
|
|
5
|
+
const trendColors = {
|
|
6
|
+
up: "text-emerald-600 bg-emerald-50 dark:text-emerald-400 dark:bg-emerald-950/30",
|
|
7
|
+
down: "text-rose-600 bg-rose-50 dark:text-rose-400 dark:bg-rose-950/30",
|
|
8
|
+
neutral: "text-slate-500 bg-slate-100 dark:text-slate-400 dark:bg-slate-800",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function ITStatCard({
|
|
12
|
+
label,
|
|
13
|
+
value,
|
|
14
|
+
trend,
|
|
15
|
+
trendDirection = trend && trend.startsWith("-") ? "down" : "neutral",
|
|
16
|
+
icon,
|
|
17
|
+
color = "bg-primary-50 dark:bg-primary-950/20",
|
|
18
|
+
className,
|
|
19
|
+
style,
|
|
20
|
+
onClick,
|
|
21
|
+
}: ITStatCardProps) {
|
|
22
|
+
return (
|
|
23
|
+
<div
|
|
24
|
+
className={clsx("rounded-xl p-4 border border-slate-100 dark:border-slate-800", color, className)}
|
|
25
|
+
style={style}
|
|
26
|
+
onClick={onClick}
|
|
27
|
+
role={onClick ? "button" : undefined}
|
|
28
|
+
tabIndex={onClick ? 0 : undefined}
|
|
29
|
+
>
|
|
30
|
+
<div className="flex items-start justify-between mb-1">
|
|
31
|
+
<ITText as="span" className="text-xs font-medium text-slate-400 dark:text-slate-500">{label}</ITText>
|
|
32
|
+
{icon && <span className="text-slate-400">{icon}</span>}
|
|
33
|
+
</div>
|
|
34
|
+
<div className="flex items-baseline gap-2">
|
|
35
|
+
<ITText as="span" className="text-2xl font-bold text-slate-800 dark:text-white">{value}</ITText>
|
|
36
|
+
{trend && (
|
|
37
|
+
<ITText as="span" className={clsx("text-[11px] font-semibold px-1.5 py-0.5 rounded-md", trendColors[trendDirection])}>
|
|
38
|
+
{trend}
|
|
39
|
+
</ITText>
|
|
40
|
+
)}
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
@keyframes slideInRight {
|
|
2
|
+
from {
|
|
3
|
+
opacity: 0;
|
|
4
|
+
transform: translateX(24px);
|
|
5
|
+
}
|
|
6
|
+
to {
|
|
7
|
+
opacity: 1;
|
|
8
|
+
transform: translateX(0);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
@keyframes slideInLeft {
|
|
12
|
+
from {
|
|
13
|
+
opacity: 0;
|
|
14
|
+
transform: translateX(-24px);
|
|
15
|
+
}
|
|
16
|
+
to {
|
|
17
|
+
opacity: 1;
|
|
18
|
+
transform: translateX(0);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
.animate-slide-in-right {
|
|
22
|
+
animation: slideInRight 320ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
|
|
23
|
+
}
|
|
24
|
+
.animate-slide-in-left {
|
|
25
|
+
animation: slideInLeft 320ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
|
|
26
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
export type IconType = React.ReactNode;
|
|
4
|
+
|
|
5
|
+
export interface Step {
|
|
6
|
+
label: string;
|
|
7
|
+
content: React.ReactNode;
|
|
8
|
+
icon?: IconType;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ITStepperProps {
|
|
12
|
+
steps: Step[];
|
|
13
|
+
currentStep: number;
|
|
14
|
+
onFinish?: () => void;
|
|
15
|
+
onStepChange?: (step: number) => void;
|
|
16
|
+
allowClickToJump?: boolean;
|
|
17
|
+
useIcons?: boolean;
|
|
18
|
+
disableNext?: boolean;
|
|
19
|
+
containerClassName?: string;
|
|
20
|
+
stepClassName?: string;
|
|
21
|
+
scrollableContent?: boolean;
|
|
22
|
+
maxContentHeight?: string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Semantic theme color for active steps and buttons.
|
|
26
|
+
* Default: 'primary'
|
|
27
|
+
*/
|
|
28
|
+
color?: string;
|
|
29
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import ITStepper from "./stepper";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { FaUser, FaIdCard, FaCheckCircle } from "react-icons/fa";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof ITStepper> = {
|
|
7
|
+
title: "Components/Layout & Navigation/ITStepper",
|
|
8
|
+
component: ITStepper,
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: "padded", // Gives the stepper breathing room
|
|
11
|
+
},
|
|
12
|
+
tags: ["autodocs"],
|
|
13
|
+
argTypes: {
|
|
14
|
+
color: {
|
|
15
|
+
control: "select",
|
|
16
|
+
options: ["primary", "secondary", "success", "danger", "warning", "info", "purple"],
|
|
17
|
+
},
|
|
18
|
+
currentStep: {
|
|
19
|
+
control: { type: "number", min: 0, max: 2 },
|
|
20
|
+
},
|
|
21
|
+
allowClickToJump: {
|
|
22
|
+
control: "boolean",
|
|
23
|
+
},
|
|
24
|
+
useIcons: {
|
|
25
|
+
control: "boolean",
|
|
26
|
+
},
|
|
27
|
+
scrollableContent: {
|
|
28
|
+
control: "boolean",
|
|
29
|
+
},
|
|
30
|
+
disableNext: {
|
|
31
|
+
control: "boolean",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default meta;
|
|
37
|
+
type Story = StoryObj<typeof ITStepper>;
|
|
38
|
+
|
|
39
|
+
// --- MOCK CONTENT ---
|
|
40
|
+
|
|
41
|
+
const step1Content = (
|
|
42
|
+
<div className="flex flex-col gap-4">
|
|
43
|
+
<h3 className="text-lg font-bold">Personal Information</h3>
|
|
44
|
+
<p className="text-gray-600">Please provide your basic details to get started.</p>
|
|
45
|
+
<div className="grid grid-cols-2 gap-4 mt-4">
|
|
46
|
+
<div className="bg-gray-100 h-10 rounded animate-pulse"></div>
|
|
47
|
+
<div className="bg-gray-100 h-10 rounded animate-pulse"></div>
|
|
48
|
+
<div className="bg-gray-100 h-10 rounded animate-pulse col-span-2"></div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const step2Content = (
|
|
54
|
+
<div className="flex flex-col gap-4">
|
|
55
|
+
<h3 className="text-lg font-bold">Address Details</h3>
|
|
56
|
+
<p className="text-gray-600">Where should we send your documents?</p>
|
|
57
|
+
<div className="grid grid-cols-3 gap-4 mt-4">
|
|
58
|
+
<div className="bg-gray-100 h-10 rounded animate-pulse col-span-3"></div>
|
|
59
|
+
<div className="bg-gray-100 h-10 rounded animate-pulse col-span-2"></div>
|
|
60
|
+
<div className="bg-gray-100 h-10 rounded animate-pulse"></div>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const step3Content = (
|
|
66
|
+
<div className="flex flex-col gap-4 items-center justify-center h-full text-center py-8">
|
|
67
|
+
<FaCheckCircle className="w-16 h-16 text-success-500 mb-4" />
|
|
68
|
+
<h3 className="text-2xl font-bold">You're all set!</h3>
|
|
69
|
+
<p className="text-gray-600 max-w-sm">Review your information before final submission. If everything looks good, click Finish.</p>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const longScrollableContent = (
|
|
74
|
+
<div className="flex flex-col gap-4">
|
|
75
|
+
<h3 className="text-lg font-bold">Terms and Conditions</h3>
|
|
76
|
+
{Array.from({ length: 15 }).map((_, i) => (
|
|
77
|
+
<p key={i} className="text-gray-600">
|
|
78
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
|
79
|
+
</p>
|
|
80
|
+
))}
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const basicSteps = [
|
|
85
|
+
{ label: "Personal Info", content: step1Content },
|
|
86
|
+
{ label: "Address", content: step2Content },
|
|
87
|
+
{ label: "Confirmation", content: step3Content },
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
const iconSteps = [
|
|
91
|
+
{ label: "Account", icon: <FaUser />, content: step1Content },
|
|
92
|
+
{ label: "Identity", icon: <FaIdCard />, content: step2Content },
|
|
93
|
+
{ label: "Complete", icon: <FaCheckCircle />, content: step3Content },
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
const scrollableSteps = [
|
|
97
|
+
{ label: "Terms", content: longScrollableContent },
|
|
98
|
+
{ label: "Privacy Policy", content: longScrollableContent },
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
// --- INTERACTIVE WRAPPERS ---
|
|
103
|
+
|
|
104
|
+
const StepperWrapper = (args: any) => {
|
|
105
|
+
const [currentStep, setCurrentStep] = useState(0);
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<ITStepper
|
|
109
|
+
{...args}
|
|
110
|
+
currentStep={currentStep}
|
|
111
|
+
onStepChange={setCurrentStep}
|
|
112
|
+
onFinish={() => alert("Stepper Finished!")}
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
// --- STORIES ---
|
|
119
|
+
|
|
120
|
+
export const Default: Story = {
|
|
121
|
+
render: (args) => <StepperWrapper {...args} />,
|
|
122
|
+
args: {
|
|
123
|
+
steps: basicSteps,
|
|
124
|
+
color: "primary",
|
|
125
|
+
allowClickToJump: true,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const WithIcons: Story = {
|
|
130
|
+
render: (args) => <StepperWrapper {...args} />,
|
|
131
|
+
args: {
|
|
132
|
+
steps: iconSteps,
|
|
133
|
+
color: "purple",
|
|
134
|
+
useIcons: true,
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const StrictSequential: Story = {
|
|
139
|
+
render: (args) => <StepperWrapper {...args} />,
|
|
140
|
+
args: {
|
|
141
|
+
steps: basicSteps,
|
|
142
|
+
color: "danger",
|
|
143
|
+
allowClickToJump: false, // User must use Next/Back buttons
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const ScrollableContent: Story = {
|
|
148
|
+
render: (args) => <StepperWrapper {...args} />,
|
|
149
|
+
args: {
|
|
150
|
+
steps: scrollableSteps,
|
|
151
|
+
color: "info",
|
|
152
|
+
scrollableContent: true,
|
|
153
|
+
maxContentHeight: "300px", // Restricts height to demonstrate scrolling
|
|
154
|
+
},
|
|
155
|
+
};
|