@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
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
import { ReactNode, CSSProperties, ElementType } from "react";
|
|
2
2
|
|
|
3
|
+
/** Flex direction: "row" | "column" | "row-reverse" | "column-reverse". */
|
|
3
4
|
export type StackDirection = "row" | "column" | "row-reverse" | "column-reverse";
|
|
5
|
+
|
|
6
|
+
/** Cross-axis alignment: "start" | "end" | "center" | "stretch" | "baseline". */
|
|
4
7
|
export type StackAlignment = "start" | "end" | "center" | "stretch" | "baseline";
|
|
8
|
+
|
|
9
|
+
/** Main-axis justification: "start" | "end" | "center" | "between" | "around" | "evenly". */
|
|
5
10
|
export type StackJustify = "start" | "end" | "center" | "between" | "around" | "evenly";
|
|
11
|
+
|
|
12
|
+
/** Flex wrap behaviour: "nowrap" | "wrap" | "wrap-reverse". */
|
|
6
13
|
export type StackWrap = "nowrap" | "wrap" | "wrap-reverse";
|
|
7
14
|
|
|
15
|
+
/** Props for the ITStack flex layout component. */
|
|
8
16
|
export interface ITStackProps {
|
|
17
|
+
/** Stack children elements. */
|
|
9
18
|
children?: ReactNode;
|
|
19
|
+
/** Flex direction. Default: "column". */
|
|
10
20
|
direction?: StackDirection;
|
|
21
|
+
/** Spacing between children in 0.25rem units (0–12). Default: 0. */
|
|
11
22
|
spacing?: number;
|
|
23
|
+
/** Cross-axis alignment. */
|
|
12
24
|
alignItems?: StackAlignment;
|
|
25
|
+
/** Main-axis justification. */
|
|
13
26
|
justifyContent?: StackJustify;
|
|
27
|
+
/** Whether children should wrap. */
|
|
14
28
|
flexWrap?: StackWrap;
|
|
29
|
+
/** Optional divider element inserted between children. */
|
|
15
30
|
divider?: ReactNode;
|
|
31
|
+
/** Additional CSS classes on the container. */
|
|
16
32
|
className?: string;
|
|
33
|
+
/** Inline styles on the container. */
|
|
17
34
|
style?: CSSProperties;
|
|
35
|
+
/** HTML element type to render as. Default: "div". */
|
|
18
36
|
as?: ElementType;
|
|
19
37
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { useState } from "react";
|
|
2
3
|
import ITStack from "./stack";
|
|
3
4
|
|
|
4
5
|
const meta: Meta<typeof ITStack> = {
|
|
@@ -9,19 +10,31 @@ const meta: Meta<typeof ITStack> = {
|
|
|
9
10
|
direction: {
|
|
10
11
|
control: "select",
|
|
11
12
|
options: ["row", "column", "row-reverse", "column-reverse"],
|
|
13
|
+
description: "Flex direction. Default: column.",
|
|
14
|
+
},
|
|
15
|
+
spacing: {
|
|
16
|
+
control: { type: "range", min: 0, max: 16, step: 1 },
|
|
17
|
+
description: "Gap between children in 0.25rem units. Default: 0.",
|
|
12
18
|
},
|
|
13
|
-
spacing: { control: { type: "range", min: 0, max: 16, step: 1 } },
|
|
14
19
|
alignItems: {
|
|
15
20
|
control: "select",
|
|
16
21
|
options: [undefined, "start", "end", "center", "stretch", "baseline"],
|
|
22
|
+
description: "Cross-axis alignment.",
|
|
17
23
|
},
|
|
18
24
|
justifyContent: {
|
|
19
25
|
control: "select",
|
|
20
26
|
options: [undefined, "start", "end", "center", "between", "around", "evenly"],
|
|
27
|
+
description: "Main-axis justification.",
|
|
21
28
|
},
|
|
22
29
|
flexWrap: {
|
|
23
30
|
control: "select",
|
|
24
31
|
options: [undefined, "nowrap", "wrap", "wrap-reverse"],
|
|
32
|
+
description: "Flex wrap behavior.",
|
|
33
|
+
},
|
|
34
|
+
as: {
|
|
35
|
+
control: "select",
|
|
36
|
+
options: ["div", "section", "nav", "ul", "ol", "main", "article", "header", "footer", "aside", "form"],
|
|
37
|
+
description: "HTML element to render.",
|
|
25
38
|
},
|
|
26
39
|
},
|
|
27
40
|
};
|
|
@@ -35,8 +48,10 @@ const Box = ({ children, className = "" }: { children: string; className?: strin
|
|
|
35
48
|
</div>
|
|
36
49
|
);
|
|
37
50
|
|
|
51
|
+
// ── Basic direction examples ──
|
|
52
|
+
|
|
38
53
|
export const Vertical: Story = {
|
|
39
|
-
args: { direction: "column", spacing: 2
|
|
54
|
+
args: { direction: "column", spacing: 2 },
|
|
40
55
|
render: (args) => (
|
|
41
56
|
<ITStack {...args}>
|
|
42
57
|
<Box>Item 1</Box>
|
|
@@ -47,7 +62,7 @@ export const Vertical: Story = {
|
|
|
47
62
|
};
|
|
48
63
|
|
|
49
64
|
export const Horizontal: Story = {
|
|
50
|
-
args: { direction: "row", spacing: 2
|
|
65
|
+
args: { direction: "row", spacing: 2 },
|
|
51
66
|
render: (args) => (
|
|
52
67
|
<ITStack {...args}>
|
|
53
68
|
<Box>Item 1</Box>
|
|
@@ -57,23 +72,213 @@ export const Horizontal: Story = {
|
|
|
57
72
|
),
|
|
58
73
|
};
|
|
59
74
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
75
|
+
// ── All direction variants ──
|
|
76
|
+
|
|
77
|
+
export const AllDirections: Story = {
|
|
78
|
+
render: () => (
|
|
79
|
+
<ITStack spacing={6}>
|
|
80
|
+
{(["column", "row", "column-reverse", "row-reverse"] as const).map((dir) => (
|
|
81
|
+
<div key={dir}>
|
|
82
|
+
<p className="text-xs font-semibold text-slate-400 mb-1.5 uppercase tracking-wider">{dir}</p>
|
|
83
|
+
<div className="bg-slate-50 dark:bg-slate-900/50 rounded-xl p-4 border border-dashed border-slate-200 dark:border-slate-700">
|
|
84
|
+
<ITStack direction={dir} spacing={2}>
|
|
85
|
+
<Box>First</Box>
|
|
86
|
+
<Box>Second</Box>
|
|
87
|
+
<Box>Third</Box>
|
|
88
|
+
</ITStack>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
))}
|
|
67
92
|
</ITStack>
|
|
68
93
|
),
|
|
69
94
|
};
|
|
70
95
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
96
|
+
// ── Spacing variants ──
|
|
97
|
+
|
|
98
|
+
export const SpacingVariants: Story = {
|
|
99
|
+
render: () => (
|
|
100
|
+
<ITStack spacing={4}>
|
|
101
|
+
{[0, 1, 2, 4, 6, 8, 10, 12].map((gap) => (
|
|
102
|
+
<div key={gap}>
|
|
103
|
+
<p className="text-xs font-semibold text-slate-400 mb-1.5">spacing={gap} — {gap * 0.25}rem</p>
|
|
104
|
+
<div className="bg-slate-50 dark:bg-slate-900/50 rounded-xl p-4">
|
|
105
|
+
<ITStack direction="row" spacing={gap}>
|
|
106
|
+
<Box>Item 1</Box>
|
|
107
|
+
<Box>Item 2</Box>
|
|
108
|
+
<Box>Item 3</Box>
|
|
109
|
+
</ITStack>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
))}
|
|
113
|
+
</ITStack>
|
|
114
|
+
),
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// ── Justify Content showcase ──
|
|
118
|
+
|
|
119
|
+
export const JustifyContent: Story = {
|
|
120
|
+
render: () => (
|
|
121
|
+
<ITStack spacing={2}>
|
|
122
|
+
{(["start", "center", "end", "between", "around", "evenly"] as const).map((j) => (
|
|
123
|
+
<div key={j}>
|
|
124
|
+
<p className="text-xs font-semibold text-slate-400 mb-1.5">{j}</p>
|
|
125
|
+
<div className="bg-slate-50 dark:bg-slate-900/50 rounded-xl p-4">
|
|
126
|
+
<ITStack direction="row" spacing={2} justifyContent={j} className="w-full">
|
|
127
|
+
<div className="w-10 h-10 rounded-lg bg-primary-400/60" />
|
|
128
|
+
<div className="w-10 h-10 rounded-lg bg-cyan-400/60" />
|
|
129
|
+
<div className="w-10 h-10 rounded-lg bg-violet-400/60" />
|
|
130
|
+
</ITStack>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
))}
|
|
134
|
+
</ITStack>
|
|
135
|
+
),
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// ── Align Items showcase ──
|
|
139
|
+
|
|
140
|
+
export const AlignItems: Story = {
|
|
141
|
+
render: () => (
|
|
142
|
+
<ITStack spacing={2}>
|
|
143
|
+
{(["start", "center", "end", "stretch", "baseline"] as const).map((a) => (
|
|
144
|
+
<div key={a}>
|
|
145
|
+
<p className="text-xs font-semibold text-slate-400 mb-1.5">{a}</p>
|
|
146
|
+
<div className="bg-slate-50 dark:bg-slate-900/50 rounded-xl p-4">
|
|
147
|
+
<ITStack direction="row" spacing={2} alignItems={a} className="h-20 border border-dashed border-slate-300 dark:border-slate-600 rounded-lg">
|
|
148
|
+
<div className="w-10 h-6 rounded bg-primary-400/60" />
|
|
149
|
+
<div className="w-10 h-12 rounded bg-cyan-400/60" />
|
|
150
|
+
<div className="w-10 h-8 rounded bg-violet-400/60" />
|
|
151
|
+
</ITStack>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
))}
|
|
155
|
+
</ITStack>
|
|
156
|
+
),
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// ── With interactive controls ──
|
|
160
|
+
|
|
161
|
+
export const Playground: Story = {
|
|
162
|
+
render: function PlaygroundStory() {
|
|
163
|
+
const [direction, setDirection] = useState<"row" | "column">("column");
|
|
164
|
+
const [spacing, setSpacing] = useState(3);
|
|
165
|
+
const [showDivider, setShowDivider] = useState(false);
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<ITStack spacing={6}>
|
|
169
|
+
<ITStack direction="row" spacing={3} flexWrap="wrap">
|
|
170
|
+
<label className="flex items-center gap-2 text-sm">
|
|
171
|
+
<span className="text-slate-500">Direction:</span>
|
|
172
|
+
<select value={direction} onChange={(e) => setDirection(e.target.value as any)} className="rounded border px-2 py-1 text-sm bg-white dark:bg-slate-800">
|
|
173
|
+
<option value="column">Column</option>
|
|
174
|
+
<option value="row">Row</option>
|
|
175
|
+
</select>
|
|
176
|
+
</label>
|
|
177
|
+
<label className="flex items-center gap-2 text-sm">
|
|
178
|
+
<span className="text-slate-500">Spacing:</span>
|
|
179
|
+
<input type="range" min={0} max={12} value={spacing} onChange={(e) => setSpacing(Number(e.target.value))} className="w-24" />
|
|
180
|
+
<span className="text-xs font-mono">{spacing}</span>
|
|
181
|
+
</label>
|
|
182
|
+
<label className="flex items-center gap-2 text-sm">
|
|
183
|
+
<input type="checkbox" checked={showDivider} onChange={(e) => setShowDivider(e.target.checked)} />
|
|
184
|
+
<span className="text-slate-500">Divider</span>
|
|
185
|
+
</label>
|
|
186
|
+
</ITStack>
|
|
187
|
+
<div className="bg-slate-50 dark:bg-slate-900/50 rounded-xl p-6 border border-dashed border-slate-200 dark:border-slate-700">
|
|
188
|
+
<ITStack
|
|
189
|
+
direction={direction}
|
|
190
|
+
spacing={spacing}
|
|
191
|
+
divider={showDivider ? <div className={`${direction === "row" ? "w-px h-8" : "h-px w-full"} bg-slate-300 dark:bg-slate-600 self-center`} /> : undefined}
|
|
192
|
+
>
|
|
193
|
+
<Box>Item 1</Box>
|
|
194
|
+
<Box>Item 2</Box>
|
|
195
|
+
<Box>Item 3</Box>
|
|
196
|
+
</ITStack>
|
|
197
|
+
</div>
|
|
198
|
+
<pre className="text-xs bg-slate-950 text-slate-200 rounded-lg p-3 overflow-x-auto">
|
|
199
|
+
{`<ITStack direction="${direction}" spacing={${spacing}}${showDivider ? `\n divider={${direction === "row" ? '<div className="w-px h-8" />' : '<div className="h-px w-full" />'}}` : ""}>
|
|
200
|
+
<Box>Item 1</Box>
|
|
201
|
+
<Box>Item 2</Box>
|
|
202
|
+
<Box>Item 3</Box>
|
|
203
|
+
</ITStack>`}
|
|
204
|
+
</pre>
|
|
205
|
+
</ITStack>
|
|
206
|
+
);
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// ── Real-world examples ──
|
|
211
|
+
|
|
212
|
+
export const ToolbarExample: Story = {
|
|
213
|
+
render: () => (
|
|
214
|
+
<div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 w-full max-w-lg">
|
|
215
|
+
<ITStack direction="row" spacing={2} justifyContent="between" alignItems="center">
|
|
216
|
+
<ITStack direction="row" spacing={1} alignItems="center">
|
|
217
|
+
<p className="text-sm font-bold text-slate-700 dark:text-slate-200">Document</p>
|
|
218
|
+
<span className="text-xs text-slate-400">• Saved</span>
|
|
219
|
+
</ITStack>
|
|
220
|
+
<ITStack direction="row" spacing={1}>
|
|
221
|
+
<div className="px-3 py-1.5 rounded-md bg-primary-500 text-white text-xs font-medium cursor-pointer">Save</div>
|
|
222
|
+
<div className="px-3 py-1.5 rounded-md bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300 text-xs cursor-pointer">Cancel</div>
|
|
223
|
+
</ITStack>
|
|
224
|
+
</ITStack>
|
|
225
|
+
</div>
|
|
226
|
+
),
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export const FormRowExample: Story = {
|
|
230
|
+
render: () => (
|
|
231
|
+
<div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 w-full max-w-xl">
|
|
232
|
+
<ITStack direction="row" spacing={3} flexWrap="wrap">
|
|
233
|
+
{["First Name", "Last Name", "Email"].map((label) => (
|
|
234
|
+
<div key={label} className="flex-1 min-w-[140px]">
|
|
235
|
+
<p className="text-xs font-semibold text-slate-500 mb-1">{label}</p>
|
|
236
|
+
<input className="w-full h-9 rounded-md border border-slate-200 dark:border-slate-600 bg-slate-50 dark:bg-slate-800/50 px-3 text-sm" placeholder={label} readOnly />
|
|
237
|
+
</div>
|
|
238
|
+
))}
|
|
239
|
+
</ITStack>
|
|
240
|
+
</div>
|
|
241
|
+
),
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
export const TagCloudExample: Story = {
|
|
245
|
+
render: () => {
|
|
246
|
+
const tags = ["React", "TypeScript", "Tailwind CSS", "Vite", "Storybook", "CSS Variables", "Flexbox", "Accessibility", "Dark Mode", "Theming", "Responsive"];
|
|
247
|
+
return (
|
|
248
|
+
<div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 w-full max-w-lg">
|
|
249
|
+
<ITStack direction="row" spacing={1} flexWrap="wrap">
|
|
250
|
+
{tags.map((tag) => (
|
|
251
|
+
<span key={tag} className="px-2.5 py-1 rounded-full text-xs font-medium bg-primary-50 text-primary-700 dark:bg-primary-900/30 dark:text-primary-400 border border-primary-200 dark:border-primary-800">
|
|
252
|
+
{tag}
|
|
253
|
+
</span>
|
|
254
|
+
))}
|
|
255
|
+
</ITStack>
|
|
256
|
+
</div>
|
|
257
|
+
);
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export const SectionWithDividers: Story = {
|
|
262
|
+
render: () => (
|
|
263
|
+
<div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 w-full max-w-sm">
|
|
264
|
+
<ITStack spacing={0} divider={<div className="h-px bg-slate-100 dark:bg-slate-700" />}>
|
|
265
|
+
{["Profile Settings", "Security & Privacy", "Notifications", "Billing & Plans", "API Keys"].map((item, i) => (
|
|
266
|
+
<div key={item} className="flex items-center justify-between py-3 px-4 hover:bg-slate-50 dark:hover:bg-slate-800/50 cursor-pointer transition-colors">
|
|
267
|
+
<span className="text-sm text-slate-700 dark:text-slate-200">{item}</span>
|
|
268
|
+
<span className="text-slate-300 dark:text-slate-600">→</span>
|
|
269
|
+
</div>
|
|
270
|
+
))}
|
|
271
|
+
</ITStack>
|
|
272
|
+
</div>
|
|
273
|
+
),
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
export const CenteredHero: Story = {
|
|
277
|
+
render: () => (
|
|
278
|
+
<ITStack spacing={4} alignItems="center" justifyContent="center" className="h-64 bg-slate-50 dark:bg-slate-900/50 rounded-xl border border-dashed border-slate-200 dark:border-slate-700">
|
|
279
|
+
<h2 className="text-2xl font-bold text-slate-800 dark:text-white">Welcome back</h2>
|
|
280
|
+
<p className="text-slate-500 dark:text-slate-400 text-sm">Select a workspace to continue</p>
|
|
281
|
+
<div className="px-4 py-2 rounded-lg bg-primary-500 text-white text-sm font-medium cursor-pointer">Get Started</div>
|
|
77
282
|
</ITStack>
|
|
78
283
|
),
|
|
79
284
|
};
|
|
@@ -32,6 +32,27 @@ const wrapMap: Record<StackWrap, string> = {
|
|
|
32
32
|
"wrap-reverse": "flex-wrap-reverse",
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Simplified flex stack with consistent spacing (gap) for arranging children in a row or column.
|
|
37
|
+
* Supports an optional divider element between children.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* <ITStack direction="row" spacing={4} alignItems="center">
|
|
42
|
+
* <ITButton>Cancel</ITButton>
|
|
43
|
+
* <ITButton variant="primary">Save</ITButton>
|
|
44
|
+
* </ITStack>
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* <ITStack direction="column" spacing={2} divider={<hr />}>
|
|
50
|
+
* <p>Item 1</p>
|
|
51
|
+
* <p>Item 2</p>
|
|
52
|
+
* <p>Item 3</p>
|
|
53
|
+
* </ITStack>
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
35
56
|
export default function ITStack({
|
|
36
57
|
children,
|
|
37
58
|
direction = "column",
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './stat-card.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# ITStatCard
|
|
7
|
+
|
|
8
|
+
Metric card displaying a label, value, and optional trend indicator with color theme.
|
|
9
|
+
|
|
10
|
+
## Props
|
|
11
|
+
|
|
12
|
+
| Prop | Type | Default | Description |
|
|
13
|
+
|------|------|---------|-------------|
|
|
14
|
+
| `label` | `string` | — | Card label |
|
|
15
|
+
| `value` | `string \| number` | — | Primary metric value |
|
|
16
|
+
| `trend` | `'up' \| 'down' \| 'neutral'` | — | Trend direction |
|
|
17
|
+
| `trendValue` | `string \| number` | — | Trend percentage or value |
|
|
18
|
+
| `icon` | `ReactNode` | — | Icon displayed on the card |
|
|
19
|
+
| `color` | `string` | — | Color theme |
|
|
20
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Card size variant |
|
|
21
|
+
| `subtitle` | `string` | — | Secondary descriptive text |
|
|
22
|
+
| `loading` | `boolean` | `false` | Show loading skeleton |
|
|
23
|
+
| `onClick` | `() => void` | — | Click handler |
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { ITStatCard } from '@axzydev/axzy_ui_system';
|
|
29
|
+
|
|
30
|
+
<ITStatCard label="Revenue" value="$12,430" trend="up" trendValue="12.5%" color="success" />
|
|
31
|
+
<ITStatCard label="Users" value="1,024" icon={<UsersIcon />} size="lg" />
|
|
32
|
+
<ITStatCard label="Bounce Rate" value="42%" trend="down" trendValue="3.1%" color="danger" subtitle="vs last week" />
|
|
33
|
+
<ITStatCard label="Loading" loading />
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Notes
|
|
37
|
+
|
|
38
|
+
- `trend` direction renders an arrow indicator with formatted `trendValue`
|
|
39
|
+
- `loading` shows a skeleton placeholder for async data
|
|
40
|
+
- Three sizes: sm, md, lg
|
|
41
|
+
- Clickable via `onClick` for drill-down dashboards
|
|
42
|
+
- `subtitle` provides supporting context below the value
|
|
43
|
+
|
|
44
|
+
## Stories
|
|
45
|
+
|
|
46
|
+
<Primary />
|
|
47
|
+
<Controls />
|
|
48
|
+
<Stories />
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { ReactNode, CSSProperties } from "react";
|
|
2
2
|
|
|
3
3
|
export interface ITStatCardProps {
|
|
4
|
+
/** The metric label displayed above the value. */
|
|
4
5
|
label: string;
|
|
6
|
+
/** The primary numeric or string value shown in the card. */
|
|
5
7
|
value: string | number;
|
|
8
|
+
/** Optional trend indicator text (e.g. "+12%", "-3"). */
|
|
6
9
|
trend?: string;
|
|
10
|
+
/** Direction of the trend, used to color the trend badge. */
|
|
7
11
|
trendDirection?: "up" | "down" | "neutral";
|
|
12
|
+
/** Icon element rendered next to the label in the top-right corner. */
|
|
8
13
|
icon?: ReactNode;
|
|
14
|
+
/** Background color class for the card (e.g. "bg-primary-50 dark:bg-primary-950/20"). */
|
|
9
15
|
color?: string;
|
|
16
|
+
/** Additional CSS classes for the outermost wrapper. */
|
|
10
17
|
className?: string;
|
|
18
|
+
/** Inline styles applied to the card container. */
|
|
11
19
|
style?: CSSProperties;
|
|
20
|
+
/** Click handler — when provided the card gains button semantics. */
|
|
12
21
|
onClick?: () => void;
|
|
13
22
|
}
|
|
@@ -8,6 +8,16 @@ const trendColors = {
|
|
|
8
8
|
neutral: "text-slate-500 bg-slate-100 dark:text-slate-400 dark:bg-slate-800",
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* A metric card displaying a value with an optional trend indicator and icon.
|
|
13
|
+
* Automatically detects trend direction from the trend string prefix.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* <ITStatCard label="Revenue" value="$12,430" trend="+12%" trendDirection="up" icon={<FaDollarSign />} />
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* <ITStatCard label="Users" value={1042} trend="-3%" trendDirection="down" onClick={() => navigate("/users")} />
|
|
20
|
+
*/
|
|
11
21
|
export default function ITStatCard({
|
|
12
22
|
label,
|
|
13
23
|
value,
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './stepper.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# ITStepper
|
|
7
|
+
|
|
8
|
+
Step-by-step wizard indicator for multi-step workflows with configurable layout and icons.
|
|
9
|
+
|
|
10
|
+
## Props
|
|
11
|
+
|
|
12
|
+
| Prop | Type | Default | Description |
|
|
13
|
+
|------|------|---------|-------------|
|
|
14
|
+
| `steps` | `{ label: string; description?: string; icon?: ReactNode }[]` | — | Step definitions |
|
|
15
|
+
| `activeStep` | `number` | `0` | Zero-indexed active step |
|
|
16
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout orientation |
|
|
17
|
+
| `variant` | `'default' \| 'dot' \| 'icon'` | `'default'` | Visual style variant |
|
|
18
|
+
| `clickable` | `boolean` | `false` | Allow clicking steps to navigate |
|
|
19
|
+
| `onStepClick` | `(index: number) => void` | — | Click handler for step navigation |
|
|
20
|
+
| `color` | `string` | — | Color theme |
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { ITStepper } from '@axzydev/axzy_ui_system';
|
|
26
|
+
|
|
27
|
+
const steps = [
|
|
28
|
+
{ label: 'Details', description: 'Enter your info' },
|
|
29
|
+
{ label: 'Payment', description: 'Choose method' },
|
|
30
|
+
{ label: 'Confirm', description: 'Review and submit' },
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
<ITStepper steps={steps} activeStep={0} />
|
|
34
|
+
<ITStepper steps={steps} activeStep={1} variant="dot" orientation="vertical" />
|
|
35
|
+
<ITStepper steps={[
|
|
36
|
+
{ label: 'Upload', icon: <UploadIcon /> },
|
|
37
|
+
{ label: 'Review', icon: <CheckIcon /> },
|
|
38
|
+
]} variant="icon" />
|
|
39
|
+
<ITStepper steps={steps} clickable onStepClick={(i) => console.log(i)} />
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Notes
|
|
43
|
+
|
|
44
|
+
- `variant="default"` shows numbered step circles
|
|
45
|
+
- `variant="dot"` shows minimal dot indicators
|
|
46
|
+
- `variant="icon"` uses custom icons per step instead of numbers
|
|
47
|
+
- `clickable` + `onStepClick` enables step-based navigation
|
|
48
|
+
- Optional `description` renders below each step label
|
|
49
|
+
|
|
50
|
+
## Stories
|
|
51
|
+
|
|
52
|
+
<Primary />
|
|
53
|
+
<Controls />
|
|
54
|
+
<Stories />
|
|
@@ -9,18 +9,28 @@ export interface Step {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export interface ITStepperProps {
|
|
12
|
+
/** Array of step objects defining label, content, and optional icon. */
|
|
12
13
|
steps: Step[];
|
|
14
|
+
/** Zero-based index of the currently active step. */
|
|
13
15
|
currentStep: number;
|
|
16
|
+
/** Called when the user clicks "Finish" on the last step. */
|
|
14
17
|
onFinish?: () => void;
|
|
18
|
+
/** Called whenever the active step changes, receiving the new index. */
|
|
15
19
|
onStepChange?: (step: number) => void;
|
|
20
|
+
/** Whether clicking on completed or current step indicators jumps to that step. */
|
|
16
21
|
allowClickToJump?: boolean;
|
|
22
|
+
/** When true, renders step icons (if provided) instead of numeric indicators. */
|
|
17
23
|
useIcons?: boolean;
|
|
24
|
+
/** Disables the "Next" / "Finish" button. */
|
|
18
25
|
disableNext?: boolean;
|
|
26
|
+
/** Additional CSS classes for the outermost wrapper. */
|
|
19
27
|
containerClassName?: string;
|
|
28
|
+
/** Additional CSS classes for the content panel. */
|
|
20
29
|
stepClassName?: string;
|
|
30
|
+
/** Makes the step content area vertically scrollable. */
|
|
21
31
|
scrollableContent?: boolean;
|
|
32
|
+
/** Maximum height of the scrollable content area (CSS value, e.g. "400px"). */
|
|
22
33
|
maxContentHeight?: string;
|
|
23
|
-
|
|
24
34
|
/**
|
|
25
35
|
* Semantic theme color for active steps and buttons.
|
|
26
36
|
* Default: 'primary'
|
|
@@ -6,6 +6,21 @@ import ITButton from "../button/button";
|
|
|
6
6
|
import { FaChevronLeft, FaChevronRight, FaCheck } from "react-icons/fa";
|
|
7
7
|
import ITText from "@/components/text/text";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* A step-by-step wizard / progress indicator with animated content transitions,
|
|
11
|
+
* clickable step navigation, and configurable icons.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* <ITStepper
|
|
15
|
+
* steps={[
|
|
16
|
+
* { label: "Details", content: <StepOneForm /> },
|
|
17
|
+
* { label: "Review", content: <StepTwoReview />, icon: <FaClipboardCheck /> },
|
|
18
|
+
* ]}
|
|
19
|
+
* currentStep={0}
|
|
20
|
+
* onStepChange={setStep}
|
|
21
|
+
* onFinish={() => alert("Done!")}
|
|
22
|
+
* />
|
|
23
|
+
*/
|
|
9
24
|
export default function ITStepper({
|
|
10
25
|
steps,
|
|
11
26
|
currentStep,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Meta, Title, Description, Primary, Controls, Stories } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './table.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# ITTable
|
|
7
|
+
|
|
8
|
+
Basic data table with column definitions, sorting, and configurable visual variants.
|
|
9
|
+
|
|
10
|
+
## Props
|
|
11
|
+
|
|
12
|
+
| Prop | Type | Default | Description |
|
|
13
|
+
|------|------|---------|-------------|
|
|
14
|
+
| `columns` | `{ key: string; label: string; render?: (value, row) => ReactNode; sortable?: boolean; width?: string }[]` | — | Column definitions |
|
|
15
|
+
| `data` | `Record<string, any>[]` | — | Row data array |
|
|
16
|
+
| `variant` | `'default' \| 'striped' \| 'bordered'` | `'default'` | Visual style variant |
|
|
17
|
+
| `sortKey` | `string` | — | Current sort column key |
|
|
18
|
+
| `sortDirection` | `'asc' \| 'desc'` | — | Current sort direction |
|
|
19
|
+
| `onSort` | `(key: string, direction: 'asc' \| 'desc') => void` | — | Sort handler |
|
|
20
|
+
| `onRowClick` | `(row: Record<string, any>) => void` | — | Row click handler |
|
|
21
|
+
| `loading` | `boolean` | `false` | Show loading state |
|
|
22
|
+
| `emptyMessage` | `string` | `'No data'` | Empty state message |
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { ITTable } from '@axzydev/axzy_ui_system';
|
|
28
|
+
|
|
29
|
+
const columns = [
|
|
30
|
+
{ key: 'name', label: 'Name', sortable: true },
|
|
31
|
+
{ key: 'role', label: 'Role' },
|
|
32
|
+
{ key: 'status', label: 'Status', render: (v) => <ITBadge>{v}</ITBadge> },
|
|
33
|
+
];
|
|
34
|
+
const data = [
|
|
35
|
+
{ name: 'Alice', role: 'Admin', status: 'Active' },
|
|
36
|
+
{ name: 'Bob', role: 'Editor', status: 'Inactive' },
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
<ITTable columns={columns} data={data} />
|
|
40
|
+
<ITTable columns={columns} data={data} variant="striped" sortKey="name" sortDirection="asc" />
|
|
41
|
+
<ITTable columns={columns} data={data} variant="bordered" onRowClick={(row) => console.log(row)} />
|
|
42
|
+
<ITTable columns={columns} data={[]} emptyMessage="No records found" />
|
|
43
|
+
<ITTable columns={columns} data={data} loading />
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Notes
|
|
47
|
+
|
|
48
|
+
- `columns[].render` provides custom cell rendering via render function
|
|
49
|
+
- `columns[].sortable` enables column header sort toggles
|
|
50
|
+
- Sorting controlled via `sortKey`, `sortDirection`, and `onSort`
|
|
51
|
+
- `onRowClick` fires with the row data on click
|
|
52
|
+
- Three visual variants: default (no borders), striped (alternating rows), bordered (full grid)
|
|
53
|
+
|
|
54
|
+
## Stories
|
|
55
|
+
|
|
56
|
+
<Primary />
|
|
57
|
+
<Controls />
|
|
58
|
+
<Stories />
|
|
@@ -31,13 +31,30 @@ export interface Column<T = any> {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export interface ITTableProps<T> {
|
|
34
|
+
/** Column definitions: key, label, type, sortable behavior, filters, and custom rendering. */
|
|
34
35
|
columns: Column<T>[];
|
|
36
|
+
/** Additional CSS classes for the outermost container. */
|
|
35
37
|
containerClassName?: string;
|
|
38
|
+
/** The data array to render in the table body. */
|
|
36
39
|
data: T[];
|
|
40
|
+
/** Visual variant: "default", "striped", "bordered", "borderless". */
|
|
37
41
|
variant?: TableVariants;
|
|
42
|
+
/** Additional CSS classes for the root table wrapper. */
|
|
38
43
|
className?: string;
|
|
44
|
+
/** Row size preset: "sm" | "md" | "lg". */
|
|
39
45
|
size?: TableSize;
|
|
46
|
+
/** Available options for the per-page selector (e.g. [5, 10, 20]). */
|
|
40
47
|
itemsPerPageOptions?: Array<number>;
|
|
48
|
+
/** Default number of rows shown per page. */
|
|
41
49
|
defaultItemsPerPage?: number;
|
|
50
|
+
/** Optional title rendered above the table in the header section. */
|
|
42
51
|
title?: string;
|
|
52
|
+
/** Custom card renderer for mobile/tablet responsive view. Receives the row data. */
|
|
53
|
+
renderCard?: (row: T) => React.ReactNode;
|
|
54
|
+
/** Initial view mode. Defaults to "table". */
|
|
55
|
+
defaultView?: "table" | "cards";
|
|
56
|
+
/** Whether to show vertical borders between columns. Defaults to true. */
|
|
57
|
+
showVerticalBorder?: boolean;
|
|
58
|
+
/** Custom class for vertical borders (overrides the default subtle gray). */
|
|
59
|
+
verticalBorderClassname?: string;
|
|
43
60
|
}
|