@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,1159 @@
|
|
|
1
|
+
import React, { useState, useEffect, useMemo } from "react";
|
|
2
|
+
import { FaSync, FaSave, FaTrash, FaEdit } from "react-icons/fa";
|
|
3
|
+
import {
|
|
4
|
+
ITButton,
|
|
5
|
+
ITInput,
|
|
6
|
+
ITSelect,
|
|
7
|
+
ITSearchSelect,
|
|
8
|
+
ITDatePicker,
|
|
9
|
+
ITTimePicker,
|
|
10
|
+
ITCalendar,
|
|
11
|
+
ITSlideToggle,
|
|
12
|
+
ITDropfile,
|
|
13
|
+
ITFormBuilder,
|
|
14
|
+
UploadStatus
|
|
15
|
+
} from "../index";
|
|
16
|
+
import { ShowcaseLayout } from "./ShowcaseLayout";
|
|
17
|
+
|
|
18
|
+
// 1. ITButton Showcase
|
|
19
|
+
export const ButtonShowcase = () => {
|
|
20
|
+
const [color, setColor] = useState<any>("primary");
|
|
21
|
+
const [size, setSize] = useState<any>("medium");
|
|
22
|
+
const [variant, setVariant] = useState<any>("filled");
|
|
23
|
+
const [disabled, setDisabled] = useState(false);
|
|
24
|
+
const [withIcon, setWithIcon] = useState(false);
|
|
25
|
+
const [clickCount, setClickCount] = useState(0);
|
|
26
|
+
|
|
27
|
+
const code = `<ITButton\n label="Hacer Click"\n color="${color}"\n size="${size}"\n variant="${variant}"${withIcon ? '\n icon={<FaSync />}' : ""}\n disabled={${disabled}}\n onClick={() => console.log('Click!')}\n/>`;
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<ShowcaseLayout
|
|
31
|
+
title="ITButton"
|
|
32
|
+
description="Botón premium con soporte completo de variantes, colores del tema, icono y estados."
|
|
33
|
+
code={code}
|
|
34
|
+
demo={
|
|
35
|
+
<div className="flex flex-col items-center gap-3">
|
|
36
|
+
<ITButton
|
|
37
|
+
label="Hacer Click"
|
|
38
|
+
color={color}
|
|
39
|
+
size={size}
|
|
40
|
+
variant={variant}
|
|
41
|
+
disabled={disabled}
|
|
42
|
+
icon={withIcon ? <FaSync /> : undefined}
|
|
43
|
+
onClick={() => setClickCount(c => c + 1)}
|
|
44
|
+
/>
|
|
45
|
+
{clickCount > 0 && (
|
|
46
|
+
<span className="text-xs font-mono text-slate-500 animate-pulse">
|
|
47
|
+
Clicks registrados: {clickCount}
|
|
48
|
+
</span>
|
|
49
|
+
)}
|
|
50
|
+
</div>
|
|
51
|
+
}
|
|
52
|
+
controls={
|
|
53
|
+
<>
|
|
54
|
+
<ITSelect
|
|
55
|
+
name="color"
|
|
56
|
+
label="Color"
|
|
57
|
+
value={color}
|
|
58
|
+
onChange={(e: any) => setColor(e.target.value)}
|
|
59
|
+
options={[
|
|
60
|
+
{ label: "Primary", value: "primary" },
|
|
61
|
+
{ label: "Secondary", value: "secondary" },
|
|
62
|
+
{ label: "Success", value: "success" },
|
|
63
|
+
{ label: "Danger", value: "danger" },
|
|
64
|
+
{ label: "Warning", value: "warning" },
|
|
65
|
+
{ label: "Info", value: "info" },
|
|
66
|
+
{ label: "Purple", value: "purple" },
|
|
67
|
+
{ label: "Gray", value: "gray" }
|
|
68
|
+
]}
|
|
69
|
+
/>
|
|
70
|
+
<ITSelect
|
|
71
|
+
name="size"
|
|
72
|
+
label="Tamaño"
|
|
73
|
+
value={size}
|
|
74
|
+
onChange={(e: any) => setSize(e.target.value)}
|
|
75
|
+
options={[
|
|
76
|
+
{ label: "Small", value: "small" },
|
|
77
|
+
{ label: "Medium", value: "medium" },
|
|
78
|
+
{ label: "Large", value: "large" }
|
|
79
|
+
]}
|
|
80
|
+
/>
|
|
81
|
+
<ITSelect
|
|
82
|
+
name="variant"
|
|
83
|
+
label="Variante"
|
|
84
|
+
value={variant}
|
|
85
|
+
onChange={(e: any) => setVariant(e.target.value)}
|
|
86
|
+
options={[
|
|
87
|
+
{ label: "Filled", value: "filled" },
|
|
88
|
+
{ label: "Outlined", value: "outlined" },
|
|
89
|
+
{ label: "Raised", value: "raised" },
|
|
90
|
+
{ label: "Rounded", value: "rounded" },
|
|
91
|
+
{ label: "Text", value: "text" },
|
|
92
|
+
{ label: "Raised Text", value: "raised-text" },
|
|
93
|
+
{ label: "Link", value: "link" }
|
|
94
|
+
]}
|
|
95
|
+
/>
|
|
96
|
+
<div className="flex items-center justify-between pt-2">
|
|
97
|
+
<span className="text-sm font-semibold text-gray-700">Con Icono</span>
|
|
98
|
+
<ITSlideToggle isOn={withIcon} onToggle={setWithIcon} size="sm" />
|
|
99
|
+
</div>
|
|
100
|
+
<div className="flex items-center justify-between">
|
|
101
|
+
<span className="text-sm font-semibold text-gray-700">Deshabilitado</span>
|
|
102
|
+
<ITSlideToggle isOn={disabled} onToggle={setDisabled} activeColor="danger" size="sm" />
|
|
103
|
+
</div>
|
|
104
|
+
</>
|
|
105
|
+
}
|
|
106
|
+
gallery={
|
|
107
|
+
<div className="space-y-6">
|
|
108
|
+
<div>
|
|
109
|
+
<h4 className="text-sm font-bold text-slate-700 mb-3">Con Icono</h4>
|
|
110
|
+
<div className="flex flex-wrap gap-3">
|
|
111
|
+
<ITButton label="Guardar" icon={<FaSave />} color="success" />
|
|
112
|
+
<ITButton label="Editar" icon={<FaEdit />} color="info" />
|
|
113
|
+
<ITButton label="Eliminar" icon={<FaTrash />} color="danger" variant="outlined" />
|
|
114
|
+
<ITButton label="Sincronizar" icon={<FaSync />} variant="text" />
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
<div>
|
|
118
|
+
<h4 className="text-sm font-bold text-slate-700 mb-3">Variantes</h4>
|
|
119
|
+
<div className="flex flex-wrap gap-3">
|
|
120
|
+
<ITButton label="Filled" variant="filled" />
|
|
121
|
+
<ITButton label="Outlined" variant="outlined" />
|
|
122
|
+
<ITButton label="Raised" variant="raised" />
|
|
123
|
+
<ITButton label="Rounded" variant="rounded" />
|
|
124
|
+
<ITButton label="Text" variant="text" />
|
|
125
|
+
<ITButton label="Link" variant="link" />
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
<div>
|
|
129
|
+
<h4 className="text-sm font-bold text-slate-700 mb-3">Colores Semánticos</h4>
|
|
130
|
+
<div className="flex flex-wrap gap-3">
|
|
131
|
+
<ITButton label="Primary" color="primary" />
|
|
132
|
+
<ITButton label="Secondary" color="secondary" />
|
|
133
|
+
<ITButton label="Success" color="success" />
|
|
134
|
+
<ITButton label="Danger" color="danger" />
|
|
135
|
+
<ITButton label="Warning" color="warning" />
|
|
136
|
+
<ITButton label="Info" color="info" />
|
|
137
|
+
<ITButton label="Purple" color="purple" />
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// 2. ITInput Showcase
|
|
147
|
+
export const InputShowcase = () => {
|
|
148
|
+
const [selectedInput, setSelectedInput] = useState<
|
|
149
|
+
"text" | "password" | "select" | "searchselect" | "datepicker" | "timepicker" | "toggle" | "dropfile" | "form"
|
|
150
|
+
>("text");
|
|
151
|
+
|
|
152
|
+
const [textVal, setTextVal] = useState("usuario_admin");
|
|
153
|
+
const [passVal, setPassVal] = useState("secreto123");
|
|
154
|
+
const [selectVal, setSelectVal] = useState("admin");
|
|
155
|
+
const [searchSelectVal, setSearchSelectVal] = useState("MX");
|
|
156
|
+
const [dateVal, setDateVal] = useState<any>(new Date());
|
|
157
|
+
const [timeVal, setTimeVal] = useState("08:00");
|
|
158
|
+
const [toggleVal, setToggleVal] = useState(true);
|
|
159
|
+
const [fileVal, setFileVal] = useState<File | null>(null);
|
|
160
|
+
|
|
161
|
+
const [formData, setFormData] = useState({
|
|
162
|
+
name: "",
|
|
163
|
+
email: "",
|
|
164
|
+
password: "",
|
|
165
|
+
role: "",
|
|
166
|
+
country: "",
|
|
167
|
+
birthday: new Date(),
|
|
168
|
+
meetingTime: "09:30",
|
|
169
|
+
newsletter: false,
|
|
170
|
+
file: null as File | null
|
|
171
|
+
});
|
|
172
|
+
const [submittedData, setSubmittedData] = useState<any>(null);
|
|
173
|
+
|
|
174
|
+
const [label, setLabel] = useState("Nombre de Usuario");
|
|
175
|
+
const [placeholder, setPlaceholder] = useState("Escribe tu apodo...");
|
|
176
|
+
const [variant, setVariant] = useState<any>("primary");
|
|
177
|
+
const [disabled, setDisabled] = useState(false);
|
|
178
|
+
const [required, setRequired] = useState(false);
|
|
179
|
+
const [errorInput, setErrorInput] = useState("");
|
|
180
|
+
|
|
181
|
+
const [formVariant, setFormVariant] = useState<any>("primary");
|
|
182
|
+
const [formDisabled, setFormDisabled] = useState(false);
|
|
183
|
+
const [showFormErrors, setShowFormErrors] = useState(false);
|
|
184
|
+
|
|
185
|
+
const formErrors = showFormErrors ? {
|
|
186
|
+
name: "El nombre es obligatorio",
|
|
187
|
+
email: "Formato de correo no válido",
|
|
188
|
+
password: "La contraseña es muy corta",
|
|
189
|
+
role: "Debes elegir un rol administrativo",
|
|
190
|
+
country: "Debes elegir tu país de residencia",
|
|
191
|
+
birthday: "Fecha incorrecta",
|
|
192
|
+
meetingTime: "Hora no permitida",
|
|
193
|
+
file: "Debes adjuntar un archivo"
|
|
194
|
+
} : {} as any;
|
|
195
|
+
|
|
196
|
+
useEffect(() => {
|
|
197
|
+
if (selectedInput !== "form") {
|
|
198
|
+
const DEFAULT_PROPS: Record<string, { label: string; placeholder: string }> = {
|
|
199
|
+
text: { label: "Nombre de Usuario", placeholder: "Escribe tu apodo..." },
|
|
200
|
+
password: { label: "Contraseña", placeholder: "Introduce tu clave..." },
|
|
201
|
+
select: { label: "Rol Administrativo", placeholder: "Selecciona un rol" },
|
|
202
|
+
searchselect: { label: "País de Origen", placeholder: "Buscar país..." },
|
|
203
|
+
datepicker: { label: "Fecha de Registro", placeholder: "Elige una fecha" },
|
|
204
|
+
timepicker: { label: "Hora de Turno", placeholder: "Elige una hora" },
|
|
205
|
+
toggle: { label: "Habilitar Notificaciones", placeholder: "" },
|
|
206
|
+
dropfile: { label: "Subir Documento", placeholder: "" }
|
|
207
|
+
};
|
|
208
|
+
const defaults = DEFAULT_PROPS[selectedInput];
|
|
209
|
+
if (defaults) {
|
|
210
|
+
setLabel(defaults.label);
|
|
211
|
+
setPlaceholder(defaults.placeholder);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}, [selectedInput]);
|
|
215
|
+
|
|
216
|
+
const code = useMemo(() => {
|
|
217
|
+
if (selectedInput === "text") {
|
|
218
|
+
return `<ITInput\n name="username"\n label="${label}"\n placeholder="${placeholder}"\n value="${textVal}"\n onChange={(e) => setVal(e.target.value)}\n variant="${variant}"\n disabled={${disabled}}\n required={${required}}\n error=${errorInput === "true" ? "{true}" : (errorInput ? `"${errorInput}"` : "undefined")}\n/>`;
|
|
219
|
+
}
|
|
220
|
+
if (selectedInput === "password") {
|
|
221
|
+
return `<ITInput\n name="password"\n type="password"\n label="${label}"\n placeholder="${placeholder}"\n value="${passVal}"\n onChange={(e) => setVal(e.target.value)}\n variant="${variant}"\n disabled={${disabled}}\n required={${required}}\n error=${errorInput === "true" ? "{true}" : (errorInput ? `"${errorInput}"` : "undefined")}\n/>`;
|
|
222
|
+
}
|
|
223
|
+
if (selectedInput === "select") {
|
|
224
|
+
return `<ITSelect\n name="user_role"\n label="${label}"\n value="${selectVal}"\n onChange={(e) => setVal(e.target.value)}\n options={[\n { label: "Administrador", value: "admin" },\n { label: "Colaborador", value: "staff" },\n { label: "Auditor Externo", value: "auditor" }\n ]}\n disabled={${disabled}}\n required={${required}}\n error=${errorInput === "true" ? "{true}" : (errorInput ? `"${errorInput}"` : "undefined")}\n/>`;
|
|
225
|
+
}
|
|
226
|
+
if (selectedInput === "searchselect") {
|
|
227
|
+
return `<ITSearchSelect\n name="user_country"\n label="${label}"\n placeholder="${placeholder}"\n value="${searchSelectVal}"\n onChange={(val) => setVal(val)}\n options={[\n { label: "México", value: "MX" },\n { label: "España", value: "ES" },\n { label: "Colombia", value: "CO" },\n { label: "Argentina", value: "AR" },\n { label: "Perú", value: "PE" }\n ]}\n disabled={${disabled}}\n required={${required}}\n error=${errorInput === "true" ? "{true}" : (errorInput ? `"${errorInput}"` : "undefined")}\n/>`;
|
|
228
|
+
}
|
|
229
|
+
if (selectedInput === "datepicker") {
|
|
230
|
+
return `<ITDatePicker\n name="birthday"\n label="${label}"\n placeholder="${placeholder}"\n value={dateVal}\n onChange={(e) => setVal(e.target.value)}\n variant="${variant}"\n disabled={${disabled}}\n required={${required}}\n error=${errorInput === "true" ? "{true}" : (errorInput ? `"${errorInput}"` : "undefined")}\n/>`;
|
|
231
|
+
}
|
|
232
|
+
if (selectedInput === "timepicker") {
|
|
233
|
+
return `<ITTimePicker\n name="meeting_time"\n label="${label}"\n placeholder="${placeholder}"\n value="${timeVal}"\n onChange={(e) => setVal(e.target.value)}\n variant="${variant}"\n disabled={${disabled}}\n required={${required}}\n error=${errorInput === "true" ? "{true}" : (errorInput ? `"${errorInput}"` : "undefined")}\n/>`;
|
|
234
|
+
}
|
|
235
|
+
if (selectedInput === "toggle") {
|
|
236
|
+
return `<ITSlideToggle\n label="${label}"\n isOn={${toggleVal}}\n onToggle={(val) => setVal(val)}\n disabled={${disabled}}\n/>`;
|
|
237
|
+
}
|
|
238
|
+
if (selectedInput === "dropfile") {
|
|
239
|
+
return `<ITDropfile\n onFileSelect={(file) => setFile(file)}\n uploadStatus={${fileVal ? "UploadStatus.UPLOADED" : "UploadStatus.PENDING"}}\n/>`;
|
|
240
|
+
}
|
|
241
|
+
return `// Formulario Completo AXZY con todos los tipos de Input:\n<form onSubmit={handleSubmit} className="space-y-4">\n <ITInput label="Nombre Completo" name="name" value={name} onChange={...} />\n <ITInput label="Correo" name="email" value={email} onChange={...} />\n <ITInput label="Contraseña" type="password" name="password" value={password} onChange={...} />\n \n <ITSelect label="Rol de Usuario" value={role} options={roles} onChange={...} />\n <ITSearchSelect label="País" value={country} options={countries} onChange={...} />\n \n <ITDatePicker label="Nacimiento" value={birthday} onChange={...} />\n <ITTimePicker label="Hora de Entrada" value={time} onChange={...} />\n \n <ITSlideToggle label="Boletín" isOn={newsletter} onToggle={...} />\n <ITDropfile label="Documento" onFileSelect={...} />\n \n <ITButton type="submit" label="Enviar Formulario" />\n</form>`;
|
|
242
|
+
}, [selectedInput, label, placeholder, variant, disabled, required, errorInput, textVal, passVal, selectVal, searchSelectVal, dateVal, timeVal, toggleVal, fileVal]);
|
|
243
|
+
|
|
244
|
+
const tabs = [
|
|
245
|
+
{ id: "text", label: "Texto" },
|
|
246
|
+
{ id: "password", label: "Contraseña" },
|
|
247
|
+
{ id: "select", label: "Select" },
|
|
248
|
+
{ id: "searchselect", label: "SearchSelect" },
|
|
249
|
+
{ id: "datepicker", label: "DatePicker" },
|
|
250
|
+
{ id: "timepicker", label: "TimePicker" },
|
|
251
|
+
{ id: "toggle", label: "SlideToggle" },
|
|
252
|
+
{ id: "dropfile", label: "Dropfile" },
|
|
253
|
+
{ id: "form", label: "Formulario" }
|
|
254
|
+
];
|
|
255
|
+
|
|
256
|
+
const renderActiveInput = () => {
|
|
257
|
+
switch (selectedInput) {
|
|
258
|
+
case "text":
|
|
259
|
+
return (
|
|
260
|
+
<div className="w-full max-w-sm">
|
|
261
|
+
<ITInput
|
|
262
|
+
name="sandbox_username"
|
|
263
|
+
label={label}
|
|
264
|
+
placeholder={placeholder}
|
|
265
|
+
value={textVal}
|
|
266
|
+
onChange={(e: any) => setTextVal(e.target.value)}
|
|
267
|
+
onBlur={() => { }}
|
|
268
|
+
variant={variant}
|
|
269
|
+
disabled={disabled}
|
|
270
|
+
required={required}
|
|
271
|
+
error={errorInput === "true" ? true : (errorInput || undefined)}
|
|
272
|
+
/>
|
|
273
|
+
</div>
|
|
274
|
+
);
|
|
275
|
+
case "password":
|
|
276
|
+
return (
|
|
277
|
+
<div className="w-full max-w-sm">
|
|
278
|
+
<ITInput
|
|
279
|
+
name="sandbox_password"
|
|
280
|
+
type="password"
|
|
281
|
+
label={label}
|
|
282
|
+
placeholder={placeholder}
|
|
283
|
+
value={passVal}
|
|
284
|
+
onChange={(e: any) => setPassVal(e.target.value)}
|
|
285
|
+
onBlur={() => { }}
|
|
286
|
+
variant={variant}
|
|
287
|
+
disabled={disabled}
|
|
288
|
+
required={required}
|
|
289
|
+
error={errorInput === "true" ? true : (errorInput || undefined)}
|
|
290
|
+
/>
|
|
291
|
+
</div>
|
|
292
|
+
);
|
|
293
|
+
case "select":
|
|
294
|
+
return (
|
|
295
|
+
<div className="w-full max-w-sm">
|
|
296
|
+
<ITSelect
|
|
297
|
+
name="sandbox_select"
|
|
298
|
+
label={label}
|
|
299
|
+
value={selectVal}
|
|
300
|
+
onChange={(e: any) => setSelectVal(e.target.value)}
|
|
301
|
+
options={[
|
|
302
|
+
{ label: "Administrador", value: "admin" },
|
|
303
|
+
{ label: "Colaborador", value: "staff" },
|
|
304
|
+
{ label: "Auditor Externo", value: "auditor" }
|
|
305
|
+
]}
|
|
306
|
+
disabled={disabled}
|
|
307
|
+
required={required}
|
|
308
|
+
error={errorInput === "true" ? true : (errorInput || undefined)}
|
|
309
|
+
/>
|
|
310
|
+
</div>
|
|
311
|
+
);
|
|
312
|
+
case "searchselect":
|
|
313
|
+
return (
|
|
314
|
+
<div className="w-full max-w-sm">
|
|
315
|
+
<ITSearchSelect
|
|
316
|
+
name="sandbox_searchselect"
|
|
317
|
+
label={label}
|
|
318
|
+
placeholder={placeholder}
|
|
319
|
+
value={searchSelectVal}
|
|
320
|
+
onChange={(val: string) => setSearchSelectVal(val)}
|
|
321
|
+
options={[
|
|
322
|
+
{ label: "México", value: "MX" },
|
|
323
|
+
{ label: "España", value: "ES" },
|
|
324
|
+
{ label: "Colombia", value: "CO" },
|
|
325
|
+
{ label: "Argentina", value: "AR" },
|
|
326
|
+
{ label: "Perú", value: "PE" }
|
|
327
|
+
]}
|
|
328
|
+
disabled={disabled}
|
|
329
|
+
required={required}
|
|
330
|
+
error={errorInput === "true" ? true : (errorInput || undefined)}
|
|
331
|
+
/>
|
|
332
|
+
</div>
|
|
333
|
+
);
|
|
334
|
+
case "datepicker":
|
|
335
|
+
return (
|
|
336
|
+
<div className="w-full max-w-sm">
|
|
337
|
+
<ITDatePicker
|
|
338
|
+
name="sandbox_datepicker"
|
|
339
|
+
label={label}
|
|
340
|
+
value={dateVal}
|
|
341
|
+
onChange={(e: any) => setDateVal(e.target.value)}
|
|
342
|
+
variant={variant}
|
|
343
|
+
disabled={disabled}
|
|
344
|
+
required={required}
|
|
345
|
+
error={errorInput === "true" ? true : (errorInput || undefined)}
|
|
346
|
+
/>
|
|
347
|
+
</div>
|
|
348
|
+
);
|
|
349
|
+
case "timepicker":
|
|
350
|
+
return (
|
|
351
|
+
<div className="w-full max-w-sm">
|
|
352
|
+
<ITTimePicker
|
|
353
|
+
name="sandbox_timepicker"
|
|
354
|
+
label={label}
|
|
355
|
+
placeholder={placeholder}
|
|
356
|
+
value={timeVal}
|
|
357
|
+
onChange={(e: any) => setTimeVal(e.target.value)}
|
|
358
|
+
onBlur={() => { }}
|
|
359
|
+
variant={variant}
|
|
360
|
+
disabled={disabled}
|
|
361
|
+
required={required}
|
|
362
|
+
error={errorInput === "true" ? true : (errorInput || undefined)}
|
|
363
|
+
/>
|
|
364
|
+
</div>
|
|
365
|
+
);
|
|
366
|
+
case "toggle":
|
|
367
|
+
return (
|
|
368
|
+
<div className="w-full max-w-sm flex items-center justify-between p-4 bg-slate-50 dark:bg-slate-800/40 border border-slate-100 dark:border-slate-800 rounded-xl">
|
|
369
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">{label || "Toggle Switch"}</span>
|
|
370
|
+
<ITSlideToggle
|
|
371
|
+
isOn={toggleVal}
|
|
372
|
+
onToggle={setToggleVal}
|
|
373
|
+
disabled={disabled}
|
|
374
|
+
activeColor={variant === "primary" ? "success" : variant}
|
|
375
|
+
/>
|
|
376
|
+
</div>
|
|
377
|
+
);
|
|
378
|
+
case "dropfile":
|
|
379
|
+
return (
|
|
380
|
+
<div className="w-full max-w-sm">
|
|
381
|
+
{label && <label className="text-sm font-medium text-gray-700 dark:text-slate-300 mb-1.5 block">{label}</label>}
|
|
382
|
+
<ITDropfile
|
|
383
|
+
onFileSelect={setFileVal}
|
|
384
|
+
uploadStatus={fileVal ? UploadStatus.UPLOADED : UploadStatus.PENDING}
|
|
385
|
+
/>
|
|
386
|
+
</div>
|
|
387
|
+
);
|
|
388
|
+
case "form":
|
|
389
|
+
return (
|
|
390
|
+
<form
|
|
391
|
+
onSubmit={(e) => {
|
|
392
|
+
e.preventDefault();
|
|
393
|
+
setSubmittedData(formData);
|
|
394
|
+
}}
|
|
395
|
+
className="w-full max-w-lg space-y-5 bg-white dark:bg-slate-900 border border-slate-100 dark:border-slate-800 p-6 rounded-2xl shadow-sm"
|
|
396
|
+
>
|
|
397
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
398
|
+
<ITInput
|
|
399
|
+
name="form_name"
|
|
400
|
+
label="Nombre Completo"
|
|
401
|
+
placeholder="Juan Pérez"
|
|
402
|
+
value={formData.name}
|
|
403
|
+
onChange={(e: any) => setFormData(prev => ({ ...prev, name: e.target.value }))}
|
|
404
|
+
variant={formVariant}
|
|
405
|
+
disabled={formDisabled}
|
|
406
|
+
required={true}
|
|
407
|
+
error={formErrors.name}
|
|
408
|
+
touched={showFormErrors ? true : undefined}
|
|
409
|
+
/>
|
|
410
|
+
<ITInput
|
|
411
|
+
name="form_email"
|
|
412
|
+
label="Correo Electrónico"
|
|
413
|
+
placeholder="juan@ejemplo.com"
|
|
414
|
+
value={formData.email}
|
|
415
|
+
onChange={(e: any) => setFormData(prev => ({ ...prev, email: e.target.value }))}
|
|
416
|
+
variant={formVariant}
|
|
417
|
+
disabled={formDisabled}
|
|
418
|
+
required={true}
|
|
419
|
+
error={formErrors.email}
|
|
420
|
+
touched={showFormErrors ? true : undefined}
|
|
421
|
+
/>
|
|
422
|
+
</div>
|
|
423
|
+
|
|
424
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
425
|
+
<ITInput
|
|
426
|
+
name="form_password"
|
|
427
|
+
label="Contraseña"
|
|
428
|
+
type="password"
|
|
429
|
+
placeholder="••••••••"
|
|
430
|
+
value={formData.password}
|
|
431
|
+
onChange={(e: any) => setFormData(prev => ({ ...prev, password: e.target.value }))}
|
|
432
|
+
variant={formVariant}
|
|
433
|
+
disabled={formDisabled}
|
|
434
|
+
required={true}
|
|
435
|
+
error={formErrors.password}
|
|
436
|
+
touched={showFormErrors ? true : undefined}
|
|
437
|
+
/>
|
|
438
|
+
<ITSelect
|
|
439
|
+
name="form_role"
|
|
440
|
+
label="Rol de Usuario"
|
|
441
|
+
value={formData.role}
|
|
442
|
+
onChange={(e: any) => setFormData(prev => ({ ...prev, role: e.target.value }))}
|
|
443
|
+
options={[
|
|
444
|
+
{ label: "Administrador", value: "admin" },
|
|
445
|
+
{ label: "Colaborador", value: "staff" },
|
|
446
|
+
{ label: "Auditor Externo", value: "auditor" }
|
|
447
|
+
]}
|
|
448
|
+
disabled={formDisabled}
|
|
449
|
+
required={true}
|
|
450
|
+
error={formErrors.role}
|
|
451
|
+
touched={showFormErrors ? true : undefined}
|
|
452
|
+
/>
|
|
453
|
+
</div>
|
|
454
|
+
|
|
455
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
456
|
+
<ITSearchSelect
|
|
457
|
+
name="form_country"
|
|
458
|
+
label="País de Residencia"
|
|
459
|
+
value={formData.country}
|
|
460
|
+
onChange={(val: string) => setFormData(prev => ({ ...prev, country: val }))}
|
|
461
|
+
options={[
|
|
462
|
+
{ label: "México", value: "MX" },
|
|
463
|
+
{ label: "España", value: "ES" },
|
|
464
|
+
{ label: "Colombia", value: "CO" },
|
|
465
|
+
{ label: "Argentina", value: "AR" },
|
|
466
|
+
{ label: "Perú", value: "PE" }
|
|
467
|
+
]}
|
|
468
|
+
disabled={formDisabled}
|
|
469
|
+
required={true}
|
|
470
|
+
error={formErrors.country}
|
|
471
|
+
touched={showFormErrors ? true : undefined}
|
|
472
|
+
/>
|
|
473
|
+
<ITDatePicker
|
|
474
|
+
name="form_birthday"
|
|
475
|
+
label="Fecha de Nacimiento"
|
|
476
|
+
value={formData.birthday}
|
|
477
|
+
onChange={(e: any) => setFormData(prev => ({ ...prev, birthday: e.target.value }))}
|
|
478
|
+
variant={formVariant}
|
|
479
|
+
disabled={formDisabled}
|
|
480
|
+
required={true}
|
|
481
|
+
error={formErrors.birthday}
|
|
482
|
+
touched={showFormErrors ? true : undefined}
|
|
483
|
+
/>
|
|
484
|
+
</div>
|
|
485
|
+
|
|
486
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 items-center">
|
|
487
|
+
<ITTimePicker
|
|
488
|
+
name="form_time"
|
|
489
|
+
label="Hora de Entrada"
|
|
490
|
+
value={formData.meetingTime}
|
|
491
|
+
onChange={(e: any) => setFormData(prev => ({ ...prev, meetingTime: e.target.value }))}
|
|
492
|
+
variant={formVariant}
|
|
493
|
+
disabled={formDisabled}
|
|
494
|
+
required={true}
|
|
495
|
+
error={formErrors.meetingTime}
|
|
496
|
+
touched={showFormErrors ? true : undefined}
|
|
497
|
+
/>
|
|
498
|
+
<div className="flex items-center justify-between p-3 bg-slate-50 dark:bg-slate-800/40 border border-slate-100 dark:border-slate-800 rounded-xl h-[64px]">
|
|
499
|
+
<span className="text-xs font-semibold text-slate-700 dark:text-slate-300">Recibir Boletín</span>
|
|
500
|
+
<ITSlideToggle
|
|
501
|
+
isOn={formData.newsletter}
|
|
502
|
+
onToggle={(val) => setFormData(prev => ({ ...prev, newsletter: val }))}
|
|
503
|
+
disabled={formDisabled}
|
|
504
|
+
size="sm"
|
|
505
|
+
/>
|
|
506
|
+
</div>
|
|
507
|
+
</div>
|
|
508
|
+
|
|
509
|
+
<ITDropfile
|
|
510
|
+
onFileSelect={(file) => setFormData(prev => ({ ...prev, file }))}
|
|
511
|
+
uploadStatus={formData.file ? UploadStatus.UPLOADED : UploadStatus.PENDING}
|
|
512
|
+
/>
|
|
513
|
+
{formErrors.file && <p className="text-xs text-red-500 mt-1">{formErrors.file}</p>}
|
|
514
|
+
|
|
515
|
+
<div className="flex justify-end pt-2">
|
|
516
|
+
<ITButton label="Enviar Formulario" color={formVariant} type="submit" disabled={formDisabled} />
|
|
517
|
+
</div>
|
|
518
|
+
|
|
519
|
+
{submittedData && (
|
|
520
|
+
<div className="mt-4 p-4 bg-slate-950 text-emerald-400 font-mono text-[10px] sm:text-xs rounded-xl border border-slate-800">
|
|
521
|
+
<p className="font-bold mb-2">✓ Submit Data (JSON):</p>
|
|
522
|
+
<pre className="whitespace-pre-wrap">
|
|
523
|
+
{JSON.stringify(
|
|
524
|
+
{
|
|
525
|
+
...submittedData,
|
|
526
|
+
birthday: submittedData.birthday instanceof Date ? submittedData.birthday.toLocaleDateString() : submittedData.birthday,
|
|
527
|
+
file: submittedData.file ? submittedData.file.name : null
|
|
528
|
+
},
|
|
529
|
+
null,
|
|
530
|
+
2
|
|
531
|
+
)}
|
|
532
|
+
</pre>
|
|
533
|
+
</div>
|
|
534
|
+
)}
|
|
535
|
+
</form>
|
|
536
|
+
);
|
|
537
|
+
default:
|
|
538
|
+
return null;
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
return (
|
|
543
|
+
<div className="w-full space-y-6">
|
|
544
|
+
<div className="flex flex-wrap gap-1 bg-slate-100 dark:bg-slate-800 p-1 rounded-xl border border-slate-200 dark:border-slate-700">
|
|
545
|
+
{tabs.map((tab) => (
|
|
546
|
+
<button
|
|
547
|
+
key={tab.id}
|
|
548
|
+
onClick={() => {
|
|
549
|
+
setSelectedInput(tab.id as any);
|
|
550
|
+
setSubmittedData(null);
|
|
551
|
+
}}
|
|
552
|
+
className={`px-3 py-1.5 text-xs font-medium rounded-lg transition-all ${selectedInput === tab.id
|
|
553
|
+
? "bg-white dark:bg-slate-700 text-slate-800 dark:text-white shadow-sm border border-slate-200 dark:border-slate-600"
|
|
554
|
+
: "text-slate-500 hover:text-slate-800 dark:hover:text-slate-200 border border-transparent"
|
|
555
|
+
}`}
|
|
556
|
+
>
|
|
557
|
+
{tab.label}
|
|
558
|
+
</button>
|
|
559
|
+
))}
|
|
560
|
+
</div>
|
|
561
|
+
|
|
562
|
+
<ShowcaseLayout
|
|
563
|
+
title="ITInput Suite"
|
|
564
|
+
description={
|
|
565
|
+
selectedInput === "form"
|
|
566
|
+
? "Formulario unificado con todos los tipos de campos de entrada (Texto, Menú, Búsqueda, Fechas, Horas, Toggles y Archivos) para validar su correcto comportamiento visual."
|
|
567
|
+
: `Sandbox interactivo para experimentar con el componente individual de tipo ${selectedInput.toUpperCase()}.`
|
|
568
|
+
}
|
|
569
|
+
code={code}
|
|
570
|
+
demo={renderActiveInput()}
|
|
571
|
+
controls={
|
|
572
|
+
selectedInput === "form" ? (
|
|
573
|
+
<>
|
|
574
|
+
<ITSelect
|
|
575
|
+
name="form_variant_ctrl"
|
|
576
|
+
label="Variante de Color de Botón"
|
|
577
|
+
value={formVariant}
|
|
578
|
+
onChange={(e: any) => setFormVariant(e.target.value)}
|
|
579
|
+
options={[
|
|
580
|
+
{ label: "Primary", value: "primary" },
|
|
581
|
+
{ label: "Secondary", value: "secondary" },
|
|
582
|
+
{ label: "Success", value: "success" },
|
|
583
|
+
{ label: "Danger", value: "danger" },
|
|
584
|
+
{ label: "Warning", value: "warning" },
|
|
585
|
+
{ label: "Info", value: "info" }
|
|
586
|
+
]}
|
|
587
|
+
/>
|
|
588
|
+
<div className="flex items-center justify-between pt-2">
|
|
589
|
+
<span className="text-sm font-semibold text-gray-700 dark:text-slate-300">Simular Errores</span>
|
|
590
|
+
<ITSlideToggle isOn={showFormErrors} onToggle={setShowFormErrors} size="sm" />
|
|
591
|
+
</div>
|
|
592
|
+
<div className="flex items-center justify-between">
|
|
593
|
+
<span className="text-sm font-semibold text-gray-700 dark:text-slate-300">Deshabilitar Todo</span>
|
|
594
|
+
<ITSlideToggle isOn={formDisabled} onToggle={setFormDisabled} activeColor="danger" size="sm" />
|
|
595
|
+
</div>
|
|
596
|
+
</>
|
|
597
|
+
) : (
|
|
598
|
+
<>
|
|
599
|
+
<ITInput
|
|
600
|
+
name="label_ctrl"
|
|
601
|
+
label="Etiqueta (Label)"
|
|
602
|
+
value={label}
|
|
603
|
+
onChange={(e: any) => setLabel(e.target.value)}
|
|
604
|
+
onBlur={() => { }}
|
|
605
|
+
/>
|
|
606
|
+
{["text", "password", "searchselect", "datepicker", "timepicker"].includes(selectedInput) && (
|
|
607
|
+
<ITInput
|
|
608
|
+
name="placeholder_ctrl"
|
|
609
|
+
label="Placeholder"
|
|
610
|
+
value={placeholder}
|
|
611
|
+
onChange={(e: any) => setPlaceholder(e.target.value)}
|
|
612
|
+
onBlur={() => { }}
|
|
613
|
+
/>
|
|
614
|
+
)}
|
|
615
|
+
{["text", "password", "datepicker", "timepicker", "toggle"].includes(selectedInput) && (
|
|
616
|
+
<ITSelect
|
|
617
|
+
name="variant_ctrl"
|
|
618
|
+
label="Variante de Color"
|
|
619
|
+
value={variant}
|
|
620
|
+
onChange={(e: any) => setVariant(e.target.value)}
|
|
621
|
+
options={[
|
|
622
|
+
{ label: "Primary", value: "primary" },
|
|
623
|
+
{ label: "Secondary", value: "secondary" },
|
|
624
|
+
{ label: "Success", value: "success" },
|
|
625
|
+
{ label: "Danger", value: "danger" },
|
|
626
|
+
{ label: "Warning", value: "warning" },
|
|
627
|
+
{ label: "Info", value: "info" }
|
|
628
|
+
]}
|
|
629
|
+
/>
|
|
630
|
+
)}
|
|
631
|
+
<ITInput
|
|
632
|
+
name="error_ctrl"
|
|
633
|
+
label="Mensaje de Error"
|
|
634
|
+
value={errorInput}
|
|
635
|
+
onChange={(e: any) => setErrorInput(e.target.value)}
|
|
636
|
+
onBlur={() => { }}
|
|
637
|
+
placeholder="Ej. Formato inválido"
|
|
638
|
+
/>
|
|
639
|
+
<div className="flex items-center justify-between pt-2">
|
|
640
|
+
<span className="text-sm font-semibold text-gray-700 dark:text-slate-300">Requerido</span>
|
|
641
|
+
<ITSlideToggle isOn={required} onToggle={setRequired} size="sm" />
|
|
642
|
+
</div>
|
|
643
|
+
<div className="flex items-center justify-between">
|
|
644
|
+
<span className="text-sm font-semibold text-gray-700 dark:text-slate-300">Deshabilitado</span>
|
|
645
|
+
<ITSlideToggle isOn={disabled} onToggle={setDisabled} activeColor="danger" size="sm" />
|
|
646
|
+
</div>
|
|
647
|
+
</>
|
|
648
|
+
)
|
|
649
|
+
}
|
|
650
|
+
gallery={
|
|
651
|
+
selectedInput === "form" ? (
|
|
652
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
653
|
+
<ITInput name="g1" label="Input Estándar" placeholder="Ingresa datos..." onChange={() => { }} onBlur={() => { }} />
|
|
654
|
+
<ITInput name="g2" label="Input Con Error" value="Email no válido" error="El formato del correo es incorrecto" onChange={() => { }} onBlur={() => { }} touched />
|
|
655
|
+
<ITInput name="g3" label="Input Deshabilitado" placeholder="Solo lectura" disabled onChange={() => { }} onBlur={() => { }} />
|
|
656
|
+
<ITInput name="g4" label="Input Contraseña" type="password" value="secreto123" onChange={() => { }} onBlur={() => { }} />
|
|
657
|
+
</div>
|
|
658
|
+
) : undefined
|
|
659
|
+
}
|
|
660
|
+
/>
|
|
661
|
+
</div>
|
|
662
|
+
);
|
|
663
|
+
};
|
|
664
|
+
|
|
665
|
+
// 3. ITSelect Showcase
|
|
666
|
+
export const SelectShowcase = () => {
|
|
667
|
+
const [val, setVal] = useState("");
|
|
668
|
+
const [label, setLabel] = useState("Rol Administrativo");
|
|
669
|
+
const [disabled, setDisabled] = useState(false);
|
|
670
|
+
const [error, setError] = useState("");
|
|
671
|
+
|
|
672
|
+
const options = [
|
|
673
|
+
{ label: "Administrador Supremo", value: "SUPERADMIN" },
|
|
674
|
+
{ label: "Operador de Planta", value: "OPERATOR" },
|
|
675
|
+
{ label: "Auditor Externo", value: "AUDITOR" }
|
|
676
|
+
];
|
|
677
|
+
|
|
678
|
+
const code = `<ITSelect\n name="role"\n label="${label}"\n value="${val}"\n options={[\n { label: 'Administrador Supremo', value: 'SUPERADMIN' },\n { label: 'Operador de Planta', value: 'OPERATOR' },\n { label: 'Auditor Externo', value: 'AUDITOR' }\n ]}\n disabled={${disabled}}\n error=${error ? `"${error}"` : "undefined"}\n onChange={(e) => setVal(e.target.value)}\n/>`;
|
|
679
|
+
|
|
680
|
+
return (
|
|
681
|
+
<ShowcaseLayout
|
|
682
|
+
title="ITSelect"
|
|
683
|
+
description="Menú desplegable de selección simple optimizado con los estilos visuales AXZY."
|
|
684
|
+
code={code}
|
|
685
|
+
demo={
|
|
686
|
+
<div className="w-full max-w-sm">
|
|
687
|
+
<ITSelect
|
|
688
|
+
name="showcase_select"
|
|
689
|
+
label={label}
|
|
690
|
+
value={val}
|
|
691
|
+
options={options}
|
|
692
|
+
disabled={disabled}
|
|
693
|
+
error={error || undefined}
|
|
694
|
+
onChange={(e: any) => setVal(e.target.value)}
|
|
695
|
+
/>
|
|
696
|
+
{val && (
|
|
697
|
+
<p className="mt-2 text-xs text-slate-500 font-mono">Selección: "{val}"</p>
|
|
698
|
+
)}
|
|
699
|
+
</div>
|
|
700
|
+
}
|
|
701
|
+
controls={
|
|
702
|
+
<>
|
|
703
|
+
<ITInput name="label_ctrl" label="Label" value={label} onChange={(e: any) => setLabel(e.target.value)} onBlur={() => { }} />
|
|
704
|
+
<ITInput name="err_ctrl" label="Mensaje de Error" value={error} onChange={(e: any) => setError(e.target.value)} onBlur={() => { }} />
|
|
705
|
+
<div className="flex items-center justify-between pt-2">
|
|
706
|
+
<span className="text-sm font-semibold text-gray-700">Deshabilitado</span>
|
|
707
|
+
<ITSlideToggle isOn={disabled} onToggle={setDisabled} activeColor="danger" size="sm" />
|
|
708
|
+
</div>
|
|
709
|
+
</>
|
|
710
|
+
}
|
|
711
|
+
gallery={
|
|
712
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
713
|
+
<ITSelect name="s1" label="Opción Simple" options={[{ label: "Chile", value: "cl" }]} onChange={() => { }} />
|
|
714
|
+
<ITSelect name="s2" label="Select Con Error" options={[]} error="Este campo es obligatorio" touched onChange={() => { }} />
|
|
715
|
+
</div>
|
|
716
|
+
}
|
|
717
|
+
/>
|
|
718
|
+
);
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
// 4. ITSearchSelect Showcase
|
|
722
|
+
export const SearchSelectShowcase = () => {
|
|
723
|
+
const [val, setVal] = useState<any>("");
|
|
724
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
725
|
+
const [disabled, setDisabled] = useState(false);
|
|
726
|
+
|
|
727
|
+
const options = [
|
|
728
|
+
{ label: "Argentina", value: "AR" },
|
|
729
|
+
{ label: "Brasil", value: "BR" },
|
|
730
|
+
{ label: "Colombia", value: "CO" },
|
|
731
|
+
{ label: "México", value: "MX" },
|
|
732
|
+
{ label: "Perú", value: "PE" },
|
|
733
|
+
{ label: "España", value: "ES" }
|
|
734
|
+
];
|
|
735
|
+
|
|
736
|
+
const code = `<ITSearchSelect\n name="country"\n label="Seleccionar País"\n value="${val}"\n options={[\n { label: 'Argentina', value: 'AR' },\n { label: 'Brasil', value: 'BR' },...\n ]}\n isLoading={${isLoading}}\n disabled={${disabled}}\n onChange={(value) => setVal(value)}\n/>`;
|
|
737
|
+
|
|
738
|
+
return (
|
|
739
|
+
<ShowcaseLayout
|
|
740
|
+
title="ITSearchSelect"
|
|
741
|
+
description="Selector avanzado con barra de búsqueda para filtrar colecciones grandes o cargar opciones remotas."
|
|
742
|
+
code={code}
|
|
743
|
+
demo={
|
|
744
|
+
<div className="w-full max-w-sm">
|
|
745
|
+
<ITSearchSelect
|
|
746
|
+
name="country"
|
|
747
|
+
label="Seleccionar País"
|
|
748
|
+
value={val}
|
|
749
|
+
options={options}
|
|
750
|
+
isLoading={isLoading}
|
|
751
|
+
disabled={disabled}
|
|
752
|
+
onChange={(value) => setVal(value)}
|
|
753
|
+
/>
|
|
754
|
+
{val && (
|
|
755
|
+
<p className="mt-2 text-xs text-slate-500 font-mono">País seleccionado: "{val}"</p>
|
|
756
|
+
)}
|
|
757
|
+
</div>
|
|
758
|
+
}
|
|
759
|
+
controls={
|
|
760
|
+
<>
|
|
761
|
+
<div className="flex items-center justify-between">
|
|
762
|
+
<span className="text-sm font-semibold text-gray-700">Estado de Carga (Loading)</span>
|
|
763
|
+
<ITSlideToggle isOn={isLoading} onToggle={setIsLoading} size="sm" />
|
|
764
|
+
</div>
|
|
765
|
+
<div className="flex items-center justify-between">
|
|
766
|
+
<span className="text-sm font-semibold text-gray-700">Deshabilitado</span>
|
|
767
|
+
<ITSlideToggle isOn={disabled} onToggle={setDisabled} activeColor="danger" size="sm" />
|
|
768
|
+
</div>
|
|
769
|
+
</>
|
|
770
|
+
}
|
|
771
|
+
/>
|
|
772
|
+
);
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
// 5. ITDatePicker Showcase
|
|
776
|
+
export const DatePickerShowcase = () => {
|
|
777
|
+
const [val, setVal] = useState<any>(new Date());
|
|
778
|
+
const [range, setRange] = useState(false);
|
|
779
|
+
const [disabled, setDisabled] = useState(false);
|
|
780
|
+
const [variant, setVariant] = useState<any>("primary");
|
|
781
|
+
|
|
782
|
+
const handleDateChange = (e: any) => {
|
|
783
|
+
setVal(e.target.value);
|
|
784
|
+
};
|
|
785
|
+
|
|
786
|
+
const code = `<ITDatePicker\n name="date"\n label="Fecha de Auditoría"\n value={${range ? "dateRange" : "singleDate"}}\n range={${range}}\n variant="${variant}"\n disabled={${disabled}}\n onChange={(e) => setVal(e.target.value)}\n/>`;
|
|
787
|
+
|
|
788
|
+
return (
|
|
789
|
+
<ShowcaseLayout
|
|
790
|
+
title="ITDatePicker"
|
|
791
|
+
description="Calendario de entrada de fechas estático y flotante con soporte para selección de rangos."
|
|
792
|
+
code={code}
|
|
793
|
+
demo={
|
|
794
|
+
<div className="w-full max-w-sm">
|
|
795
|
+
<ITDatePicker
|
|
796
|
+
name="showcase_datepicker"
|
|
797
|
+
label="Fecha del Evento"
|
|
798
|
+
value={val}
|
|
799
|
+
range={range}
|
|
800
|
+
variant={variant}
|
|
801
|
+
disabled={disabled}
|
|
802
|
+
onChange={handleDateChange}
|
|
803
|
+
/>
|
|
804
|
+
{val && (
|
|
805
|
+
<p className="mt-2 text-xs text-slate-500 font-mono">
|
|
806
|
+
Valor actual: {range && Array.isArray(val)
|
|
807
|
+
? `Rango: ${val[0]?.toLocaleDateString() || "?"} - ${val[1]?.toLocaleDateString() || "?"}`
|
|
808
|
+
: val instanceof Date
|
|
809
|
+
? val.toLocaleDateString()
|
|
810
|
+
: String(val)
|
|
811
|
+
}
|
|
812
|
+
</p>
|
|
813
|
+
)}
|
|
814
|
+
</div>
|
|
815
|
+
}
|
|
816
|
+
controls={
|
|
817
|
+
<>
|
|
818
|
+
<ITSelect
|
|
819
|
+
name="variant_ctrl"
|
|
820
|
+
label="Tema de Color"
|
|
821
|
+
value={variant}
|
|
822
|
+
onChange={(e: any) => setVariant(e.target.value)}
|
|
823
|
+
options={[
|
|
824
|
+
{ label: "Primary", value: "primary" },
|
|
825
|
+
{ label: "Secondary", value: "secondary" },
|
|
826
|
+
{ label: "Success", value: "success" },
|
|
827
|
+
{ label: "Danger", value: "danger" },
|
|
828
|
+
{ label: "Warning", value: "warning" },
|
|
829
|
+
{ label: "Info", value: "info" }
|
|
830
|
+
]}
|
|
831
|
+
/>
|
|
832
|
+
<div className="flex items-center justify-between pt-2">
|
|
833
|
+
<span className="text-sm font-semibold text-gray-700">Selección de Rango</span>
|
|
834
|
+
<ITSlideToggle isOn={range} onToggle={(r) => { setRange(r); setVal(r ? [new Date(), new Date()] : new Date()); }} size="sm" />
|
|
835
|
+
</div>
|
|
836
|
+
<div className="flex items-center justify-between">
|
|
837
|
+
<span className="text-sm font-semibold text-gray-700">Deshabilitado</span>
|
|
838
|
+
<ITSlideToggle isOn={disabled} onToggle={setDisabled} activeColor="danger" size="sm" />
|
|
839
|
+
</div>
|
|
840
|
+
</>
|
|
841
|
+
}
|
|
842
|
+
/>
|
|
843
|
+
);
|
|
844
|
+
};
|
|
845
|
+
|
|
846
|
+
// 6. ITTimePicker Showcase
|
|
847
|
+
export const TimePickerShowcase = () => {
|
|
848
|
+
const [val, setVal] = useState("09:30");
|
|
849
|
+
const [variant, setVariant] = useState<any>("primary");
|
|
850
|
+
const [disabled, setDisabled] = useState(false);
|
|
851
|
+
|
|
852
|
+
const code = `<ITTimePicker\n name="time"\n label="Hora de Inicio"\n value="${val}"\n variant="${variant}"\n disabled={${disabled}}\n onChange={(e) => setVal(e.target.value)}\n/>`;
|
|
853
|
+
|
|
854
|
+
return (
|
|
855
|
+
<ShowcaseLayout
|
|
856
|
+
title="ITTimePicker"
|
|
857
|
+
description="Selector de horas y minutos con panel interactivo de scroll suave."
|
|
858
|
+
code={code}
|
|
859
|
+
demo={
|
|
860
|
+
<div className="w-full max-w-sm">
|
|
861
|
+
<ITTimePicker
|
|
862
|
+
name="showcase_time"
|
|
863
|
+
label="Hora de Inicio"
|
|
864
|
+
value={val}
|
|
865
|
+
variant={variant}
|
|
866
|
+
disabled={disabled}
|
|
867
|
+
onChange={(e: any) => setVal(e.target.value)}
|
|
868
|
+
onBlur={() => { }}
|
|
869
|
+
/>
|
|
870
|
+
{val && (
|
|
871
|
+
<p className="mt-2 text-xs text-slate-500 font-mono">Hora elegida: "{val}"</p>
|
|
872
|
+
)}
|
|
873
|
+
</div>
|
|
874
|
+
}
|
|
875
|
+
controls={
|
|
876
|
+
<>
|
|
877
|
+
<ITSelect
|
|
878
|
+
name="variant_ctrl"
|
|
879
|
+
label="Variante"
|
|
880
|
+
value={variant}
|
|
881
|
+
onChange={(e: any) => setVariant(e.target.value)}
|
|
882
|
+
options={[
|
|
883
|
+
{ label: "Primary", value: "primary" },
|
|
884
|
+
{ label: "Secondary", value: "secondary" },
|
|
885
|
+
{ label: "Success", value: "success" },
|
|
886
|
+
{ label: "Danger", value: "danger" },
|
|
887
|
+
{ label: "Warning", value: "warning" },
|
|
888
|
+
{ label: "Info", value: "info" },
|
|
889
|
+
{ label: "Purple", value: "purple" }
|
|
890
|
+
]}
|
|
891
|
+
/>
|
|
892
|
+
<div className="flex items-center justify-between pt-2">
|
|
893
|
+
<span className="text-sm font-semibold text-gray-700">Deshabilitado</span>
|
|
894
|
+
<ITSlideToggle isOn={disabled} onToggle={setDisabled} activeColor="danger" size="sm" />
|
|
895
|
+
</div>
|
|
896
|
+
</>
|
|
897
|
+
}
|
|
898
|
+
/>
|
|
899
|
+
);
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
// 7. ITCalendar Showcase
|
|
903
|
+
export const CalendarShowcase = () => {
|
|
904
|
+
const [mode, setMode] = useState<'month' | 'week' | 'day'>('month');
|
|
905
|
+
const [selectionMode, setSelectionMode] = useState<'single' | 'range'>('single');
|
|
906
|
+
const [calendarVariant, setCalendarVariant] = useState<any>("primary");
|
|
907
|
+
const [events] = useState<any[]>([
|
|
908
|
+
{ id: "1", title: "Planificación de Sprint", start: new Date(), end: new Date(new Date().getTime() + 60 * 60 * 1000), color: "#3b82f6" },
|
|
909
|
+
{ id: "2", title: "Revisión Técnica", start: new Date(new Date().setDate(new Date().getDate() + 2)), end: new Date(new Date().setDate(new Date().getDate() + 2)), color: "#10b981" }
|
|
910
|
+
]);
|
|
911
|
+
|
|
912
|
+
const code = `<ITCalendar\n mode="${mode}"\n selectionMode="${selectionMode}"\n variant="${calendarVariant}"\n events={[\n { id: '1', title: 'Sprint Planning', start: new Date(), end: new Date() }\n ]}\n onSlotClick={(date) => alert(date)}\n/>`;
|
|
913
|
+
|
|
914
|
+
return (
|
|
915
|
+
<ShowcaseLayout
|
|
916
|
+
title="ITCalendar"
|
|
917
|
+
description="Calendario completo con soporte para eventos y agendamiento diario/semanal."
|
|
918
|
+
code={code}
|
|
919
|
+
demo={
|
|
920
|
+
<div className="w-full h-[450px]">
|
|
921
|
+
<ITCalendar
|
|
922
|
+
mode={mode}
|
|
923
|
+
selectionMode={selectionMode}
|
|
924
|
+
variant={calendarVariant}
|
|
925
|
+
events={events}
|
|
926
|
+
onSlotClick={(date) => alert(`Click en horario: ${date.toLocaleString()}`)}
|
|
927
|
+
onEventClick={(evt) => alert(`Detalle del Evento: ${evt.title}`)}
|
|
928
|
+
/>
|
|
929
|
+
</div>
|
|
930
|
+
}
|
|
931
|
+
controls={
|
|
932
|
+
<>
|
|
933
|
+
<ITSelect
|
|
934
|
+
name="mode_ctrl"
|
|
935
|
+
label="Modo de Vista"
|
|
936
|
+
value={mode}
|
|
937
|
+
onChange={(e: any) => setMode(e.target.value)}
|
|
938
|
+
options={[
|
|
939
|
+
{ label: "Mes (Month)", value: "month" },
|
|
940
|
+
{ label: "Semana (Week)", value: "week" },
|
|
941
|
+
{ label: "Día (Day)", value: "day" }
|
|
942
|
+
]}
|
|
943
|
+
/>
|
|
944
|
+
<ITSelect
|
|
945
|
+
name="sel_ctrl"
|
|
946
|
+
label="Modo de Selección"
|
|
947
|
+
value={selectionMode}
|
|
948
|
+
onChange={(e: any) => setSelectionMode(e.target.value)}
|
|
949
|
+
options={[
|
|
950
|
+
{ label: "Single", value: "single" },
|
|
951
|
+
{ label: "Range", value: "range" }
|
|
952
|
+
]}
|
|
953
|
+
/>
|
|
954
|
+
<ITSelect
|
|
955
|
+
name="var_ctrl"
|
|
956
|
+
label="Variante de Color"
|
|
957
|
+
value={calendarVariant}
|
|
958
|
+
onChange={(e: any) => setCalendarVariant(e.target.value)}
|
|
959
|
+
options={[
|
|
960
|
+
{ label: "Primary", value: "primary" },
|
|
961
|
+
{ label: "Secondary", value: "secondary" },
|
|
962
|
+
{ label: "Success", value: "success" },
|
|
963
|
+
{ label: "Danger", value: "danger" },
|
|
964
|
+
{ label: "Warning", value: "warning" },
|
|
965
|
+
{ label: "Info", value: "info" }
|
|
966
|
+
]}
|
|
967
|
+
/>
|
|
968
|
+
</>
|
|
969
|
+
}
|
|
970
|
+
/>
|
|
971
|
+
);
|
|
972
|
+
};
|
|
973
|
+
|
|
974
|
+
// 8. ITSlideToggle Showcase
|
|
975
|
+
export const SlideToggleShowcase = () => {
|
|
976
|
+
const [isOn, setIsOn] = useState(false);
|
|
977
|
+
const [activeColor, setActiveColor] = useState<any>("success");
|
|
978
|
+
const [size, setSize] = useState<any>("md");
|
|
979
|
+
const [disabled, setDisabled] = useState(false);
|
|
980
|
+
|
|
981
|
+
const code = `<ITSlideToggle\n isOn={${isOn}}\n onToggle={(state) => setIsOn(state)}\n activeColor="${activeColor}"\n size="${size}"\n disabled={${disabled}}\n/>`;
|
|
982
|
+
|
|
983
|
+
return (
|
|
984
|
+
<ShowcaseLayout
|
|
985
|
+
title="ITSlideToggle"
|
|
986
|
+
description="Interruptor de alternancia (Switch) estilizado para cambiar estados binarios."
|
|
987
|
+
code={code}
|
|
988
|
+
demo={
|
|
989
|
+
<div className="flex flex-col items-center gap-3">
|
|
990
|
+
<ITSlideToggle
|
|
991
|
+
isOn={isOn}
|
|
992
|
+
onToggle={setIsOn}
|
|
993
|
+
activeColor={activeColor}
|
|
994
|
+
size={size}
|
|
995
|
+
disabled={disabled}
|
|
996
|
+
/>
|
|
997
|
+
<span className="text-xs font-mono text-slate-500">
|
|
998
|
+
Estado: {isOn ? "ENCENDIDO" : "APAGADO"}
|
|
999
|
+
</span>
|
|
1000
|
+
</div>
|
|
1001
|
+
}
|
|
1002
|
+
controls={
|
|
1003
|
+
<>
|
|
1004
|
+
<ITSelect
|
|
1005
|
+
name="col_ctrl"
|
|
1006
|
+
label="Color Activo"
|
|
1007
|
+
value={activeColor}
|
|
1008
|
+
onChange={(e: any) => setActiveColor(e.target.value)}
|
|
1009
|
+
options={[
|
|
1010
|
+
{ label: "Success (Verde)", value: "success" },
|
|
1011
|
+
{ label: "Primary (Azul)", value: "primary" },
|
|
1012
|
+
{ label: "Danger (Rojo)", value: "danger" },
|
|
1013
|
+
{ label: "Warning (Naranja)", value: "warning" },
|
|
1014
|
+
{ label: "Purple (Morado)", value: "purple" }
|
|
1015
|
+
]}
|
|
1016
|
+
/>
|
|
1017
|
+
<ITSelect
|
|
1018
|
+
name="sz_ctrl"
|
|
1019
|
+
label="Tamaño"
|
|
1020
|
+
value={size}
|
|
1021
|
+
onChange={(e: any) => setSize(e.target.value)}
|
|
1022
|
+
options={[
|
|
1023
|
+
{ label: "Small", value: "sm" },
|
|
1024
|
+
{ label: "Medium", value: "md" },
|
|
1025
|
+
{ label: "Large", value: "lg" }
|
|
1026
|
+
]}
|
|
1027
|
+
/>
|
|
1028
|
+
<div className="flex items-center justify-between pt-2">
|
|
1029
|
+
<span className="text-sm font-semibold text-gray-700">Deshabilitar Switch</span>
|
|
1030
|
+
<ITSlideToggle isOn={disabled} onToggle={setDisabled} activeColor="danger" size="sm" />
|
|
1031
|
+
</div>
|
|
1032
|
+
</>
|
|
1033
|
+
}
|
|
1034
|
+
gallery={
|
|
1035
|
+
<div className="flex flex-wrap items-center gap-6">
|
|
1036
|
+
<ITSlideToggle initialState={false} size="sm" />
|
|
1037
|
+
<ITSlideToggle initialState={true} activeColor="primary" size="md" />
|
|
1038
|
+
<ITSlideToggle initialState={true} activeColor="purple" size="lg" />
|
|
1039
|
+
<ITSlideToggle initialState={true} disabled size="md" />
|
|
1040
|
+
</div>
|
|
1041
|
+
}
|
|
1042
|
+
/>
|
|
1043
|
+
);
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
// 9. ITDropfile Showcase
|
|
1047
|
+
export const DropfileShowcase = () => {
|
|
1048
|
+
const [selectedFile, setSelectedFile] = useState<File | null>(null);
|
|
1049
|
+
const [status, setStatus] = useState<any>("pendiente");
|
|
1050
|
+
|
|
1051
|
+
const code = `<ITDropfile\n onFileSelect={(file) => setSelectedFile(file)}\n uploadStatus="${status}"\n showStatusBadge={true}\n/>`;
|
|
1052
|
+
|
|
1053
|
+
return (
|
|
1054
|
+
<ShowcaseLayout
|
|
1055
|
+
title="ITDropfile"
|
|
1056
|
+
description="Área interactiva para arrastrar y soltar archivos, con previsualización de imágenes y barra de progreso."
|
|
1057
|
+
code={code}
|
|
1058
|
+
demo={
|
|
1059
|
+
<div className="w-full max-w-md">
|
|
1060
|
+
<ITDropfile
|
|
1061
|
+
onFileSelect={(file) => setSelectedFile(file)}
|
|
1062
|
+
uploadStatus={status}
|
|
1063
|
+
onStatusChange={(st) => setStatus(st)}
|
|
1064
|
+
/>
|
|
1065
|
+
{selectedFile && (
|
|
1066
|
+
<div className="mt-4 p-3 bg-slate-50 dark:bg-slate-900 border rounded-lg text-xs font-mono">
|
|
1067
|
+
<p>Nombre: {selectedFile.name}</p>
|
|
1068
|
+
<p>Tamaño: {(selectedFile.size / 1024).toFixed(1)} KB</p>
|
|
1069
|
+
<p>Tipo: {selectedFile.type}</p>
|
|
1070
|
+
</div>
|
|
1071
|
+
)}
|
|
1072
|
+
</div>
|
|
1073
|
+
}
|
|
1074
|
+
controls={
|
|
1075
|
+
<>
|
|
1076
|
+
<ITSelect
|
|
1077
|
+
name="status_ctrl"
|
|
1078
|
+
label="Forzar Estado de Subida"
|
|
1079
|
+
value={status}
|
|
1080
|
+
onChange={(e: any) => setStatus(e.target.value)}
|
|
1081
|
+
options={[
|
|
1082
|
+
{ label: "Pendiente", value: "pendiente" },
|
|
1083
|
+
{ label: "Subiendo (Uploading)", value: "subiendo" },
|
|
1084
|
+
{ label: "Subido (Uploaded)", value: "subido" },
|
|
1085
|
+
{ label: "Error", value: "error" }
|
|
1086
|
+
]}
|
|
1087
|
+
/>
|
|
1088
|
+
</>
|
|
1089
|
+
}
|
|
1090
|
+
/>
|
|
1091
|
+
);
|
|
1092
|
+
};
|
|
1093
|
+
|
|
1094
|
+
// 10. ITFormBuilder Showcase
|
|
1095
|
+
export const FormBuilderShowcase = () => {
|
|
1096
|
+
const [values, setValues] = useState({
|
|
1097
|
+
name: "",
|
|
1098
|
+
email: "",
|
|
1099
|
+
country: "MX",
|
|
1100
|
+
accept: false
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
const handleChange = (e: any) => {
|
|
1104
|
+
const { name, value, type, checked } = e.target;
|
|
1105
|
+
setValues(prev => ({
|
|
1106
|
+
...prev,
|
|
1107
|
+
[name]: type === "checkbox" ? checked : value
|
|
1108
|
+
}));
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
const config: any = [
|
|
1112
|
+
{ name: "name", label: "Nombre Completo", type: "text", required: true },
|
|
1113
|
+
{ name: "email", label: "Correo de Contacto", type: "email", required: true },
|
|
1114
|
+
{
|
|
1115
|
+
name: "country",
|
|
1116
|
+
label: "País Operación",
|
|
1117
|
+
type: "select",
|
|
1118
|
+
options: [
|
|
1119
|
+
{ label: "México", value: "MX" },
|
|
1120
|
+
{ label: "Chile", value: "CL" },
|
|
1121
|
+
{ label: "Perú", value: "PE" }
|
|
1122
|
+
]
|
|
1123
|
+
},
|
|
1124
|
+
{ name: "accept", label: "Acepto términos y condiciones", type: "checkbox" }
|
|
1125
|
+
];
|
|
1126
|
+
|
|
1127
|
+
const code = `<ITFormBuilder\n config={[\n { name: 'name', label: 'Nombre', type: 'text', required: true },\n { name: 'email', label: 'Email', type: 'email' },\n ...\n ]}\n values={formValues}\n handleChange={handleFormChange}\n/>`;
|
|
1128
|
+
|
|
1129
|
+
return (
|
|
1130
|
+
<ShowcaseLayout
|
|
1131
|
+
title="ITFormBuilder"
|
|
1132
|
+
description="Generador dinámico de formularios basado en un esquema estructurado JSON."
|
|
1133
|
+
code={code}
|
|
1134
|
+
demo={
|
|
1135
|
+
<div className="w-full max-w-md bg-white dark:bg-slate-900 p-6 rounded-2xl border shadow-sm space-y-6">
|
|
1136
|
+
<ITFormBuilder
|
|
1137
|
+
config={config}
|
|
1138
|
+
values={values}
|
|
1139
|
+
handleChange={handleChange}
|
|
1140
|
+
handleBlur={() => { }}
|
|
1141
|
+
touched={{}}
|
|
1142
|
+
errors={{}}
|
|
1143
|
+
/>
|
|
1144
|
+
<div className="pt-4 border-t border-slate-100 dark:border-slate-800">
|
|
1145
|
+
<h5 className="text-xs font-bold uppercase text-slate-400 mb-2">Valores del Formulario (JSON):</h5>
|
|
1146
|
+
<pre className="p-3 bg-slate-950 text-emerald-400 text-xs rounded-lg overflow-x-auto font-mono">
|
|
1147
|
+
{JSON.stringify(values, null, 2)}
|
|
1148
|
+
</pre>
|
|
1149
|
+
</div>
|
|
1150
|
+
</div>
|
|
1151
|
+
}
|
|
1152
|
+
controls={
|
|
1153
|
+
<div className="p-2 bg-slate-50 dark:bg-slate-900 rounded-lg text-xs">
|
|
1154
|
+
<p className="text-slate-500">El formulario se genera dinámicamente inyectando un array de campos configurados.</p>
|
|
1155
|
+
</div>
|
|
1156
|
+
}
|
|
1157
|
+
/>
|
|
1158
|
+
);
|
|
1159
|
+
};
|