@axzydev/axzy_ui_system 1.2.1 → 1.2.2
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.css +82 -1
- package/dist/index.css.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/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,79 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import {
|
|
3
|
+
ITFlexProps,
|
|
4
|
+
FlexDirection,
|
|
5
|
+
FlexAlign,
|
|
6
|
+
FlexJustify,
|
|
7
|
+
FlexWrap,
|
|
8
|
+
} from "./flex.props";
|
|
9
|
+
|
|
10
|
+
const directionMap: Record<FlexDirection, string> = {
|
|
11
|
+
row: "flex-row",
|
|
12
|
+
column: "flex-col",
|
|
13
|
+
"row-reverse": "flex-row-reverse",
|
|
14
|
+
"column-reverse": "flex-col-reverse",
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const alignMap: Record<FlexAlign, string> = {
|
|
18
|
+
start: "items-start",
|
|
19
|
+
end: "items-end",
|
|
20
|
+
center: "items-center",
|
|
21
|
+
stretch: "items-stretch",
|
|
22
|
+
baseline: "items-baseline",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const justifyMap: Record<FlexJustify, string> = {
|
|
26
|
+
start: "justify-start",
|
|
27
|
+
end: "justify-end",
|
|
28
|
+
center: "justify-center",
|
|
29
|
+
between: "justify-between",
|
|
30
|
+
around: "justify-around",
|
|
31
|
+
evenly: "justify-evenly",
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const wrapMap: Record<FlexWrap, string> = {
|
|
35
|
+
nowrap: "flex-nowrap",
|
|
36
|
+
wrap: "flex-wrap",
|
|
37
|
+
"wrap-reverse": "flex-wrap-reverse",
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default function ITFlex({
|
|
41
|
+
children,
|
|
42
|
+
direction = "row",
|
|
43
|
+
align,
|
|
44
|
+
justify,
|
|
45
|
+
wrap,
|
|
46
|
+
gap = 0,
|
|
47
|
+
grow,
|
|
48
|
+
shrink,
|
|
49
|
+
basis,
|
|
50
|
+
className,
|
|
51
|
+
style,
|
|
52
|
+
as: Component = "div",
|
|
53
|
+
onClick,
|
|
54
|
+
}: ITFlexProps) {
|
|
55
|
+
const resolvedStyle: React.CSSProperties = {
|
|
56
|
+
gap: gap > 0 ? `${gap * 0.25}rem` : undefined,
|
|
57
|
+
flexGrow: typeof grow === "boolean" ? (grow ? 1 : 0) : grow,
|
|
58
|
+
flexShrink: typeof shrink === "boolean" ? (shrink ? 1 : 0) : shrink,
|
|
59
|
+
flexBasis: typeof basis === "number" ? `${basis * 0.25}rem` : basis,
|
|
60
|
+
...style,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Component
|
|
65
|
+
className={clsx(
|
|
66
|
+
"flex",
|
|
67
|
+
directionMap[direction],
|
|
68
|
+
align && alignMap[align],
|
|
69
|
+
justify && justifyMap[justify],
|
|
70
|
+
wrap && wrapMap[wrap],
|
|
71
|
+
className
|
|
72
|
+
)}
|
|
73
|
+
style={resolvedStyle}
|
|
74
|
+
onClick={onClick}
|
|
75
|
+
>
|
|
76
|
+
{children}
|
|
77
|
+
</Component>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import React, { memo, useCallback, useEffect } from "react";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
import { FieldConfigV2 } from "@/types/field.types";
|
|
4
|
+
import { useITFormBuilderContext } from "./formBuilder.context";
|
|
5
|
+
import ITInput from "../input/input";
|
|
6
|
+
import ITSelect from "../select/select";
|
|
7
|
+
import ITDatePicker from "../date-picker/datePicker";
|
|
8
|
+
import ITTimePicker from "../time-picker/timePicker";
|
|
9
|
+
import { useFieldRules } from "./useFormBuilder";
|
|
10
|
+
import { getColSpanClass, getGridColsClass } from "@/utils/styles";
|
|
11
|
+
import ITText from "@/components/text/text";
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
interface ITFieldRendererProps {
|
|
16
|
+
config: FieldConfigV2;
|
|
17
|
+
columns?: number;
|
|
18
|
+
value?: any;
|
|
19
|
+
error?: string;
|
|
20
|
+
touched?: boolean;
|
|
21
|
+
dependentValues?: Record<string, any>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const ITFieldRenderer = ({
|
|
25
|
+
config,
|
|
26
|
+
columns = 12,
|
|
27
|
+
value,
|
|
28
|
+
error,
|
|
29
|
+
touched,
|
|
30
|
+
dependentValues = {},
|
|
31
|
+
}: ITFieldRendererProps) => {
|
|
32
|
+
const context = useITFormBuilderContext();
|
|
33
|
+
const { isVisible, isRequired, isDisabled, dynamicProps } = useFieldRules(
|
|
34
|
+
config,
|
|
35
|
+
dependentValues,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
context.registerField(config.name, config);
|
|
40
|
+
return () => {
|
|
41
|
+
context.unregisterField(config.name);
|
|
42
|
+
};
|
|
43
|
+
}, [config.name]);
|
|
44
|
+
|
|
45
|
+
if (!isVisible) return null;
|
|
46
|
+
|
|
47
|
+
const activeConfig = {
|
|
48
|
+
...config,
|
|
49
|
+
...dynamicProps,
|
|
50
|
+
required: isRequired,
|
|
51
|
+
disabled: isDisabled,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const {
|
|
55
|
+
name,
|
|
56
|
+
label,
|
|
57
|
+
type,
|
|
58
|
+
placeholder,
|
|
59
|
+
options,
|
|
60
|
+
valueField,
|
|
61
|
+
labelField,
|
|
62
|
+
formatNumber,
|
|
63
|
+
showHintLength,
|
|
64
|
+
leftIcon,
|
|
65
|
+
rightIcon,
|
|
66
|
+
} = activeConfig;
|
|
67
|
+
|
|
68
|
+
const handleChangeWrapper = useCallback(
|
|
69
|
+
async (val: any) => {
|
|
70
|
+
const finalValue = val?.target ? val.target.value : val;
|
|
71
|
+
await context.setFieldValue(name, finalValue);
|
|
72
|
+
if (activeConfig.onChangeAction) {
|
|
73
|
+
await activeConfig.onChangeAction(finalValue, context);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
[name, context]
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const renderField = () => {
|
|
80
|
+
switch (type) {
|
|
81
|
+
case "text":
|
|
82
|
+
case "password":
|
|
83
|
+
case "number":
|
|
84
|
+
case "email":
|
|
85
|
+
return (
|
|
86
|
+
<ITInput
|
|
87
|
+
type={type === "email" ? "text" : type}
|
|
88
|
+
name={name}
|
|
89
|
+
label={label || ""}
|
|
90
|
+
placeholder={placeholder}
|
|
91
|
+
disabled={isDisabled as boolean}
|
|
92
|
+
value={value !== undefined ? value : activeConfig.defaultValue || ""}
|
|
93
|
+
onChange={handleChangeWrapper}
|
|
94
|
+
onBlur={context.handleBlur}
|
|
95
|
+
currencyFormat={activeConfig.currencyFormat}
|
|
96
|
+
touched={touched}
|
|
97
|
+
error={error}
|
|
98
|
+
required={isRequired as boolean}
|
|
99
|
+
iconRight={rightIcon}
|
|
100
|
+
iconLeft={leftIcon}
|
|
101
|
+
showHintLength={showHintLength}
|
|
102
|
+
maxLength={activeConfig.maxLength}
|
|
103
|
+
minLength={activeConfig.minLength}
|
|
104
|
+
rows={activeConfig.rows}
|
|
105
|
+
formatNumber={formatNumber}
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
case "select":
|
|
110
|
+
return (
|
|
111
|
+
<ITSelect
|
|
112
|
+
options={(Array.isArray(options) ? options : []) as any}
|
|
113
|
+
name={name}
|
|
114
|
+
disabled={isDisabled as boolean}
|
|
115
|
+
label={label || ""}
|
|
116
|
+
placeholder={placeholder}
|
|
117
|
+
value={value !== undefined ? value : activeConfig.defaultValue || ""}
|
|
118
|
+
valueField={valueField}
|
|
119
|
+
labelField={labelField}
|
|
120
|
+
onChange={handleChangeWrapper}
|
|
121
|
+
onBlur={context.handleBlur}
|
|
122
|
+
touched={touched}
|
|
123
|
+
error={error}
|
|
124
|
+
required={isRequired as boolean}
|
|
125
|
+
/>
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
case "date":
|
|
129
|
+
return (
|
|
130
|
+
<ITDatePicker
|
|
131
|
+
name={name}
|
|
132
|
+
disabled={isDisabled as boolean}
|
|
133
|
+
label={label || ""}
|
|
134
|
+
value={value}
|
|
135
|
+
onChange={handleChangeWrapper}
|
|
136
|
+
placeholder={placeholder}
|
|
137
|
+
onBlur={context.handleBlur}
|
|
138
|
+
touched={touched}
|
|
139
|
+
error={error}
|
|
140
|
+
required={isRequired as boolean}
|
|
141
|
+
/>
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
case "time":
|
|
145
|
+
return (
|
|
146
|
+
<ITTimePicker
|
|
147
|
+
name={name}
|
|
148
|
+
disabled={isDisabled as boolean}
|
|
149
|
+
label={label || ""}
|
|
150
|
+
value={value}
|
|
151
|
+
onChange={handleChangeWrapper}
|
|
152
|
+
placeholder={placeholder}
|
|
153
|
+
onBlur={context.handleBlur}
|
|
154
|
+
touched={touched}
|
|
155
|
+
error={error}
|
|
156
|
+
required={isRequired as boolean}
|
|
157
|
+
/>
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
case "custom":
|
|
161
|
+
if (activeConfig.component) {
|
|
162
|
+
const CustomComponent = activeConfig.component;
|
|
163
|
+
return (
|
|
164
|
+
<CustomComponent
|
|
165
|
+
{...activeConfig}
|
|
166
|
+
value={value}
|
|
167
|
+
onChange={handleChangeWrapper}
|
|
168
|
+
onBlur={context.handleBlur}
|
|
169
|
+
error={error}
|
|
170
|
+
touched={touched}
|
|
171
|
+
context={context}
|
|
172
|
+
/>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
|
|
177
|
+
case "section":
|
|
178
|
+
return (
|
|
179
|
+
<div className={clsx("w-full col-span-full", activeConfig.className)}>
|
|
180
|
+
{label && (
|
|
181
|
+
<ITText as="h4" className="text-lg font-semibold text-gray-800 mb-4">
|
|
182
|
+
{label}
|
|
183
|
+
</ITText>
|
|
184
|
+
)}
|
|
185
|
+
<div className={clsx("grid gap-y-6 gap-x-5", getGridColsClass(columns as any))}>
|
|
186
|
+
{activeConfig.fields?.map((childConfig) => (
|
|
187
|
+
<ITFieldRenderer
|
|
188
|
+
key={childConfig.name}
|
|
189
|
+
config={childConfig}
|
|
190
|
+
columns={columns}
|
|
191
|
+
/>
|
|
192
|
+
))}
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
case "array":
|
|
198
|
+
return (
|
|
199
|
+
<div className="p-4 border-2 border-dashed border-gray-200 rounded-xl">
|
|
200
|
+
<ITText as="p" className="text-sm text-gray-500 text-center">
|
|
201
|
+
Array Field: {label}
|
|
202
|
+
</ITText>
|
|
203
|
+
</div>
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
default:
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<div className={clsx(getColSpanClass(activeConfig.column, columns), activeConfig.className)}>
|
|
213
|
+
{renderField()}
|
|
214
|
+
</div>
|
|
215
|
+
);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export default memo(ITFieldRenderer);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React, { createContext, useContext, useEffect, useState } from 'react';
|
|
2
|
+
import { FieldConfigV2, FieldContextV2 } from '@/types/field.types';
|
|
3
|
+
import * as Yup from 'yup';
|
|
4
|
+
|
|
5
|
+
interface ITFormBuilderContextType extends FieldContextV2 {
|
|
6
|
+
config: FieldConfigV2[];
|
|
7
|
+
isSubmitting: boolean;
|
|
8
|
+
isValidating: boolean;
|
|
9
|
+
submitCount: number;
|
|
10
|
+
initialValues: Record<string, any>;
|
|
11
|
+
errors: Record<string, string>;
|
|
12
|
+
touched: Record<string, boolean>;
|
|
13
|
+
handleBlur: (e: any) => void;
|
|
14
|
+
handleChange: (e: any) => void;
|
|
15
|
+
registerField: (name: string, config: FieldConfigV2) => void;
|
|
16
|
+
unregisterField: (name: string) => void;
|
|
17
|
+
getFieldConfig: (name: string) => FieldConfigV2 | undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const ITFormBuilderContext = createContext<ITFormBuilderContextType | undefined>(undefined);
|
|
21
|
+
|
|
22
|
+
export const ITFormBuilderProvider = ({
|
|
23
|
+
children,
|
|
24
|
+
value,
|
|
25
|
+
}: {
|
|
26
|
+
children: React.ReactNode;
|
|
27
|
+
value: Omit<ITFormBuilderContextType, 'registerField' | 'unregisterField' | 'getFieldConfig'>;
|
|
28
|
+
}) => {
|
|
29
|
+
const [fieldRegistry, setFieldRegistry] = useState<Record<string, FieldConfigV2>>({});
|
|
30
|
+
|
|
31
|
+
const registerField = React.useCallback((name: string, config: FieldConfigV2) => {
|
|
32
|
+
setFieldRegistry((prev) => ({ ...prev, [name]: config }));
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
const unregisterField = React.useCallback((name: string) => {
|
|
36
|
+
setFieldRegistry((prev) => {
|
|
37
|
+
const newRegistry = { ...prev };
|
|
38
|
+
delete newRegistry[name];
|
|
39
|
+
return newRegistry;
|
|
40
|
+
});
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
const getFieldConfig = React.useCallback((name: string) => {
|
|
44
|
+
return fieldRegistry[name];
|
|
45
|
+
}, [fieldRegistry]);
|
|
46
|
+
|
|
47
|
+
const contextValue = React.useMemo(
|
|
48
|
+
() => ({
|
|
49
|
+
...value,
|
|
50
|
+
registerField,
|
|
51
|
+
unregisterField,
|
|
52
|
+
getFieldConfig,
|
|
53
|
+
}),
|
|
54
|
+
[value, registerField, unregisterField, getFieldConfig]
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<ITFormBuilderContext.Provider value={contextValue}>
|
|
59
|
+
{children}
|
|
60
|
+
</ITFormBuilderContext.Provider>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const useITFormBuilderContext = () => {
|
|
65
|
+
const context = useContext(ITFormBuilderContext);
|
|
66
|
+
if (!context) {
|
|
67
|
+
throw new Error('useITFormBuilderContext must be used within an ITFormBuilderProvider');
|
|
68
|
+
}
|
|
69
|
+
return context;
|
|
70
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { FieldConfig, FieldConfigV2 } from "@/types/field.types";
|
|
2
|
+
|
|
3
|
+
export interface ITFormBuilderProps {
|
|
4
|
+
// Legacy
|
|
5
|
+
fields?: FieldConfig[];
|
|
6
|
+
|
|
7
|
+
// V2 Architecture
|
|
8
|
+
config?: FieldConfigV2[];
|
|
9
|
+
|
|
10
|
+
columns?: number;
|
|
11
|
+
values: any;
|
|
12
|
+
handleChange: (
|
|
13
|
+
event:
|
|
14
|
+
| React.ChangeEvent<HTMLInputElement>
|
|
15
|
+
| React.FocusEvent<HTMLInputElement>
|
|
16
|
+
| React.ChangeEvent<HTMLSelectElement>
|
|
17
|
+
| { target: { name: string; value: any } }
|
|
18
|
+
) => void;
|
|
19
|
+
handleBlur: (
|
|
20
|
+
event:
|
|
21
|
+
| React.FocusEvent<HTMLInputElement>
|
|
22
|
+
| React.FocusEvent<HTMLSelectElement, Element>
|
|
23
|
+
| React.FocusEvent<HTMLTextAreaElement, Element>
|
|
24
|
+
| { target: { name: string; value: any } }
|
|
25
|
+
) => void;
|
|
26
|
+
touched: any;
|
|
27
|
+
errors: any;
|
|
28
|
+
setFieldValue?: (
|
|
29
|
+
field: string,
|
|
30
|
+
value: any,
|
|
31
|
+
shouldValidate?: boolean
|
|
32
|
+
) => Promise<void | any>;
|
|
33
|
+
setFieldTouched?: (
|
|
34
|
+
field: string,
|
|
35
|
+
touched?: boolean,
|
|
36
|
+
shouldValidate?: boolean
|
|
37
|
+
) => Promise<void | any>;
|
|
38
|
+
setFieldError?: (
|
|
39
|
+
field: string,
|
|
40
|
+
message: string | undefined
|
|
41
|
+
) => void;
|
|
42
|
+
isSubmitting?: boolean;
|
|
43
|
+
}
|