@axzydev/axzy_ui_system 1.2.0 → 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 -197
- 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,260 @@
|
|
|
1
|
+
import React, { useState, useMemo, useCallback } from "react";
|
|
2
|
+
import {
|
|
3
|
+
ITTable,
|
|
4
|
+
ITDataTable,
|
|
5
|
+
ITBadget,
|
|
6
|
+
ITImage,
|
|
7
|
+
ITInput,
|
|
8
|
+
ITSelect,
|
|
9
|
+
ITSlideToggle,
|
|
10
|
+
ITDataTableFetchParams,
|
|
11
|
+
ITDataTableResponse
|
|
12
|
+
} from "../index";
|
|
13
|
+
import { ShowcaseLayout } from "./ShowcaseLayout";
|
|
14
|
+
|
|
15
|
+
// 1. ITTable Showcase
|
|
16
|
+
export const TableShowcase = () => {
|
|
17
|
+
const [variant, setVariant] = useState<any>("default");
|
|
18
|
+
const [size, setSize] = useState<any>("md");
|
|
19
|
+
|
|
20
|
+
const columns: any = [
|
|
21
|
+
{ key: "id", label: "ID", type: "number" },
|
|
22
|
+
{ key: "name", label: "Nombre", type: "string" },
|
|
23
|
+
{ key: "role", label: "Rol", type: "string" },
|
|
24
|
+
{
|
|
25
|
+
key: "status",
|
|
26
|
+
label: "Estado",
|
|
27
|
+
type: "actions",
|
|
28
|
+
render: (row: any) => (
|
|
29
|
+
<ITBadget
|
|
30
|
+
label={row.status ? "Conectado" : "Inactivo"}
|
|
31
|
+
color={row.status ? "success" : "danger"}
|
|
32
|
+
size="small"
|
|
33
|
+
/>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
const data = [
|
|
39
|
+
{ id: 101, name: "Esteban Dido", role: "Auditor", status: true },
|
|
40
|
+
{ id: 102, name: "Elsa Pato", role: "Administrador", status: true },
|
|
41
|
+
{ id: 103, name: "Aquiles Baeza", role: "Operador", status: false }
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const code = `<ITTable\n columns={columns}\n data={data}\n variant="${variant}"\n size="${size}"\n/>`;
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<ShowcaseLayout
|
|
48
|
+
title="ITTable"
|
|
49
|
+
description="Base de renderizado de tablas estructuradas con soporte de alineamiento y tipado estricto."
|
|
50
|
+
code={code}
|
|
51
|
+
demo={
|
|
52
|
+
<div className="w-full bg-white dark:bg-slate-900 border rounded-xl overflow-hidden shadow-sm">
|
|
53
|
+
<ITTable
|
|
54
|
+
columns={columns}
|
|
55
|
+
data={data}
|
|
56
|
+
variant={variant}
|
|
57
|
+
size={size}
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
}
|
|
61
|
+
controls={
|
|
62
|
+
<>
|
|
63
|
+
<ITSelect
|
|
64
|
+
name="var_ctrl"
|
|
65
|
+
label="Variante Estilo"
|
|
66
|
+
value={variant}
|
|
67
|
+
onChange={(e: any) => setVariant(e.target.value)}
|
|
68
|
+
options={[
|
|
69
|
+
{ label: "Default", value: "default" },
|
|
70
|
+
{ label: "Striped (Cebra)", value: "striped" },
|
|
71
|
+
{ label: "Bordered (Bordes)", value: "bordered" },
|
|
72
|
+
{ label: "Clean (Limpio)", value: "clean" }
|
|
73
|
+
]}
|
|
74
|
+
/>
|
|
75
|
+
<ITSelect
|
|
76
|
+
name="sz_ctrl"
|
|
77
|
+
label="Tamaño Filas"
|
|
78
|
+
value={size}
|
|
79
|
+
onChange={(e: any) => setSize(e.target.value)}
|
|
80
|
+
options={[
|
|
81
|
+
{ label: "Small (sm)", value: "sm" },
|
|
82
|
+
{ label: "Medium (md)", value: "md" },
|
|
83
|
+
{ label: "Large (lg)", value: "lg" }
|
|
84
|
+
]}
|
|
85
|
+
/>
|
|
86
|
+
</>
|
|
87
|
+
}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// 2. ITDataTable Showcase
|
|
93
|
+
export const DataTableShowcase = () => {
|
|
94
|
+
const userColumns = useMemo(() => [
|
|
95
|
+
{ key: "id", label: "ID", type: "number" as const },
|
|
96
|
+
{ key: "name", label: "Nombre", type: "string" as const, filter: true },
|
|
97
|
+
{ key: "role", label: "Rol", type: "string" as const, filter: true },
|
|
98
|
+
{ key: "active", label: "Activo", type: "boolean" as const, filter: true }
|
|
99
|
+
], []);
|
|
100
|
+
|
|
101
|
+
const fetchData = useCallback(async (params: ITDataTableFetchParams): Promise<ITDataTableResponse<any>> => {
|
|
102
|
+
await new Promise(resolve => setTimeout(resolve, 600));
|
|
103
|
+
let mockData = [
|
|
104
|
+
{ id: 1, name: "Juan Pérez", role: "Administrador", active: true },
|
|
105
|
+
{ id: 2, name: "María García", role: "Usuario", active: true },
|
|
106
|
+
{ id: 3, name: "Pedro López", role: "Usuario", active: false },
|
|
107
|
+
{ id: 4, name: "Ana Torres", role: "Editor", active: true },
|
|
108
|
+
{ id: 5, name: "Luis Gómez", role: "Administrador", active: false }
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
if (params.filters) {
|
|
112
|
+
Object.keys(params.filters).forEach(key => {
|
|
113
|
+
const filterVal = params.filters[key];
|
|
114
|
+
if (filterVal) {
|
|
115
|
+
mockData = mockData.filter(item =>
|
|
116
|
+
String((item as any)[key]).toLowerCase().includes(String(filterVal).toLowerCase())
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
data: mockData,
|
|
124
|
+
total: mockData.length
|
|
125
|
+
};
|
|
126
|
+
}, []);
|
|
127
|
+
|
|
128
|
+
const code = `<ITDataTable\n columns={[\n { key: 'id', label: 'ID', type: 'number' },\n { key: 'name', label: 'Nombre', type: 'string', filter: true }\n ]}\n fetchData={api.fetchUsers}\n/>`;
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<ShowcaseLayout
|
|
132
|
+
title="ITDataTable"
|
|
133
|
+
description="Tabla de datos auto-suficiente con carga dinámica, paginación integrada y filtros avanzados."
|
|
134
|
+
code={code}
|
|
135
|
+
demo={
|
|
136
|
+
<div className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl overflow-hidden shadow-md">
|
|
137
|
+
<ITDataTable
|
|
138
|
+
columns={userColumns}
|
|
139
|
+
fetchData={fetchData}
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
142
|
+
}
|
|
143
|
+
controls={
|
|
144
|
+
<div className="p-2 bg-slate-50 dark:bg-slate-900 rounded-lg text-xs space-y-2">
|
|
145
|
+
<p className="text-slate-500">Esta tabla consume una función de carga de datos que se autogestiona en ordenamiento, paginado y filtros.</p>
|
|
146
|
+
<div className="p-2 bg-amber-50 dark:bg-amber-950/20 border border-amber-200 dark:border-amber-900 rounded text-amber-800 dark:text-amber-300">
|
|
147
|
+
Prueba a escribir en los inputs de filtro de la tabla!
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
}
|
|
151
|
+
/>
|
|
152
|
+
);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// 3. ITBadget Showcase
|
|
156
|
+
export const BadgetShowcase = () => {
|
|
157
|
+
const [color, setColor] = useState<any>("success");
|
|
158
|
+
const [size, setSize] = useState<any>("medium");
|
|
159
|
+
const [labelText, setLabelText] = useState("Activo");
|
|
160
|
+
|
|
161
|
+
const code = `<ITBadget\n label="${labelText}"\n color="${color}"\n size="${size}"\n/>`;
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<ShowcaseLayout
|
|
165
|
+
title="ITBadget"
|
|
166
|
+
description="Badges (etiquetas) estilizados para representar estados o categorías de items."
|
|
167
|
+
code={code}
|
|
168
|
+
demo={
|
|
169
|
+
<ITBadget label={labelText} color={color} size={size} />
|
|
170
|
+
}
|
|
171
|
+
controls={
|
|
172
|
+
<>
|
|
173
|
+
<ITInput
|
|
174
|
+
name="label"
|
|
175
|
+
label="Texto"
|
|
176
|
+
value={labelText}
|
|
177
|
+
onChange={(e: any) => setLabelText(e.target.value)}
|
|
178
|
+
onBlur={() => { }}
|
|
179
|
+
/>
|
|
180
|
+
<ITSelect
|
|
181
|
+
name="color"
|
|
182
|
+
label="Color"
|
|
183
|
+
value={color}
|
|
184
|
+
onChange={(e: any) => setColor(e.target.value)}
|
|
185
|
+
options={[
|
|
186
|
+
{ label: "Primary", value: "primary" },
|
|
187
|
+
{ label: "Secondary", value: "secondary" },
|
|
188
|
+
{ label: "Success", value: "success" },
|
|
189
|
+
{ label: "Danger", value: "danger" },
|
|
190
|
+
{ label: "Warning", value: "warning" },
|
|
191
|
+
{ label: "Info", value: "info" }
|
|
192
|
+
]}
|
|
193
|
+
/>
|
|
194
|
+
<ITSelect
|
|
195
|
+
name="size"
|
|
196
|
+
label="Tamaño"
|
|
197
|
+
value={size}
|
|
198
|
+
onChange={(e: any) => setSize(e.target.value)}
|
|
199
|
+
options={[
|
|
200
|
+
{ label: "Small", value: "small" },
|
|
201
|
+
{ label: "Medium", value: "medium" },
|
|
202
|
+
{ label: "Large", value: "large" }
|
|
203
|
+
]}
|
|
204
|
+
/>
|
|
205
|
+
</>
|
|
206
|
+
}
|
|
207
|
+
gallery={
|
|
208
|
+
<div className="flex flex-wrap items-center gap-4">
|
|
209
|
+
<ITBadget label="Primary" color="primary" />
|
|
210
|
+
<ITBadget label="Secondary" color="secondary" />
|
|
211
|
+
<ITBadget label="Success" color="success" />
|
|
212
|
+
<ITBadget label="Danger" color="danger" />
|
|
213
|
+
<ITBadget label="Warning" color="warning" />
|
|
214
|
+
<ITBadget label="Info" color="info" />
|
|
215
|
+
<span className="mx-4 text-slate-300">|</span>
|
|
216
|
+
<ITBadget label="Small" color="primary" size="small" />
|
|
217
|
+
<ITBadget label="Medium" color="primary" size="medium" />
|
|
218
|
+
<ITBadget label="Large" color="primary" size="large" />
|
|
219
|
+
</div>
|
|
220
|
+
}
|
|
221
|
+
/>
|
|
222
|
+
);
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// 4. ITImage Showcase
|
|
226
|
+
export const ImageShowcase = () => {
|
|
227
|
+
const [broken, setBroken] = useState(false);
|
|
228
|
+
const src = broken ? "https://nonexistent.image.site/broken.jpg" : "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=400&q=80";
|
|
229
|
+
|
|
230
|
+
const code = `<ITImage\n src="${src}"\n alt="Imagen Abstracta"\n fallback="https://placehold.co/400x200?text=No+Preview"\n className="rounded-xl object-cover h-40"\n/>`;
|
|
231
|
+
|
|
232
|
+
return (
|
|
233
|
+
<ShowcaseLayout
|
|
234
|
+
title="ITImage"
|
|
235
|
+
description="Componente de renderizado de imágenes inteligente con cargador interno y fallback automático ante fallas de red."
|
|
236
|
+
code={code}
|
|
237
|
+
demo={
|
|
238
|
+
<div className="w-full max-w-sm flex flex-col items-center gap-3">
|
|
239
|
+
<ITImage
|
|
240
|
+
src={src}
|
|
241
|
+
alt="Demo abstracta"
|
|
242
|
+
fallback="https://placehold.co/400x200?text=Error+Carga+Imagen"
|
|
243
|
+
className="rounded-xl object-cover h-40 w-full shadow-md"
|
|
244
|
+
/>
|
|
245
|
+
<span className="text-xs text-slate-500 font-mono">
|
|
246
|
+
{broken ? "Cargando URL Rota (Fallback Activo)" : "Cargando URL Correcta"}
|
|
247
|
+
</span>
|
|
248
|
+
</div>
|
|
249
|
+
}
|
|
250
|
+
controls={
|
|
251
|
+
<>
|
|
252
|
+
<div className="flex items-center justify-between pt-2">
|
|
253
|
+
<span className="text-sm font-semibold text-gray-700">Forzar Error de Carga (URL rota)</span>
|
|
254
|
+
<ITSlideToggle isOn={broken} onToggle={setBroken} activeColor="danger" size="sm" />
|
|
255
|
+
</div>
|
|
256
|
+
</>
|
|
257
|
+
}
|
|
258
|
+
/>
|
|
259
|
+
);
|
|
260
|
+
};
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
ITDialog,
|
|
4
|
+
ITButton,
|
|
5
|
+
ITSlideToggle,
|
|
6
|
+
ITToast,
|
|
7
|
+
ITInput,
|
|
8
|
+
ITSelect,
|
|
9
|
+
ITLoader,
|
|
10
|
+
ITGrid,
|
|
11
|
+
ITStack,
|
|
12
|
+
useITTheme
|
|
13
|
+
} from "../index";
|
|
14
|
+
import { PRESETS } from "../components/theme-provider/themeProvider";
|
|
15
|
+
import { ShowcaseLayout } from "./ShowcaseLayout";
|
|
16
|
+
|
|
17
|
+
// 1. ITDialog Showcase
|
|
18
|
+
export const DialogShowcase = () => {
|
|
19
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
20
|
+
const [useFormHeader, setUseFormHeader] = useState(true);
|
|
21
|
+
|
|
22
|
+
const code = `<ITDialog\n isOpen={${isOpen}}\n onClose={() => setIsOpen(false)}\n title="Confirmación de Auditoría"\n useFormHeader={${useFormHeader}}\n>\n <p>¿Estás seguro de registrar esta auditoría?</p>\n</ITDialog>`;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<ShowcaseLayout
|
|
26
|
+
title="ITDialog"
|
|
27
|
+
description="Cajas de diálogo modales con overlay oscuro y soporte de cabeceras de formulario."
|
|
28
|
+
code={code}
|
|
29
|
+
demo={
|
|
30
|
+
<div>
|
|
31
|
+
<ITButton label="Abrir Ventana Modal" color="primary" onClick={() => setIsOpen(true)} />
|
|
32
|
+
<ITDialog
|
|
33
|
+
isOpen={isOpen}
|
|
34
|
+
onClose={() => setIsOpen(false)}
|
|
35
|
+
title="Confirmación de Auditoría"
|
|
36
|
+
useFormHeader={useFormHeader}
|
|
37
|
+
>
|
|
38
|
+
<div className="p-6 space-y-4">
|
|
39
|
+
<p className="text-sm text-slate-600 dark:text-slate-300">
|
|
40
|
+
Se guardará un registro inmutable en los logs de la blockchain corporativa. Esta acción es irreversible.
|
|
41
|
+
</p>
|
|
42
|
+
<div className="flex justify-end gap-3 pt-4 border-t">
|
|
43
|
+
<ITButton label="Cancelar" variant="ghost" onClick={() => setIsOpen(false)} />
|
|
44
|
+
<ITButton label="Autorizar" color="success" onClick={() => { alert("Transacción firmada!"); setIsOpen(false); }} />
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</ITDialog>
|
|
48
|
+
</div>
|
|
49
|
+
}
|
|
50
|
+
controls={
|
|
51
|
+
<>
|
|
52
|
+
<div className="flex items-center justify-between pt-2">
|
|
53
|
+
<span className="text-sm font-semibold text-gray-700">Usar Cabecera de Formulario</span>
|
|
54
|
+
<ITSlideToggle isOn={useFormHeader} onToggle={setUseFormHeader} size="sm" />
|
|
55
|
+
</div>
|
|
56
|
+
</>
|
|
57
|
+
}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// 2. ITToast Showcase
|
|
63
|
+
export const ToastShowcase = () => {
|
|
64
|
+
const [visible, setVisible] = useState(false);
|
|
65
|
+
const [type, setType] = useState<any>("success");
|
|
66
|
+
const [msg, setMsg] = useState("¡La operación se procesó con éxito!");
|
|
67
|
+
|
|
68
|
+
const code = `<ITToast\n message="${msg}"\n type="${type}"\n duration={3000}\n onClose={() => setVisible(false)}\n/>`;
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<ShowcaseLayout
|
|
72
|
+
title="ITToast"
|
|
73
|
+
description="Alertas efímeras del sistema flotantes para notificar eventos inmediatos al usuario."
|
|
74
|
+
code={code}
|
|
75
|
+
demo={
|
|
76
|
+
<div>
|
|
77
|
+
<ITButton label="Lanzar Notificación" color="purple" onClick={() => setVisible(true)} />
|
|
78
|
+
{visible && (
|
|
79
|
+
<ITToast
|
|
80
|
+
message={msg}
|
|
81
|
+
type={type}
|
|
82
|
+
duration={3000}
|
|
83
|
+
onClose={() => setVisible(false)}
|
|
84
|
+
/>
|
|
85
|
+
)}
|
|
86
|
+
</div>
|
|
87
|
+
}
|
|
88
|
+
controls={
|
|
89
|
+
<>
|
|
90
|
+
<ITInput name="msg_ctrl" label="Mensaje" value={msg} onChange={(e: any) => setMsg(e.target.value)} onBlur={() => { }} />
|
|
91
|
+
<ITSelect
|
|
92
|
+
name="type_ctrl"
|
|
93
|
+
label="Tipo de Notificación"
|
|
94
|
+
value={type}
|
|
95
|
+
onChange={(e: any) => setType(e.target.value)}
|
|
96
|
+
options={[
|
|
97
|
+
{ label: "Success (Éxito)", value: "success" },
|
|
98
|
+
{ label: "Error (Peligro)", value: "error" },
|
|
99
|
+
{ label: "Warning (Advertencia)", value: "warning" },
|
|
100
|
+
{ label: "Info (Información)", value: "info" }
|
|
101
|
+
]}
|
|
102
|
+
/>
|
|
103
|
+
</>
|
|
104
|
+
}
|
|
105
|
+
gallery={
|
|
106
|
+
<div className="flex flex-wrap gap-3">
|
|
107
|
+
<ITButton label="Toast Exito" color="success" size="small" onClick={() => { setMsg("Operación exitosa!"); setType("success"); setVisible(true); }} />
|
|
108
|
+
<ITButton label="Toast Error" color="danger" size="small" onClick={() => { setMsg("Ocurrió un fallo de red."); setType("error"); setVisible(true); }} />
|
|
109
|
+
<ITButton label="Toast Warning" color="warning" size="small" onClick={() => { setMsg("Licencia por expirar."); setType("warning"); setVisible(true); }} />
|
|
110
|
+
<ITButton label="Toast Info" color="info" size="small" onClick={() => { setMsg("Actualización disponible."); setType("info"); setVisible(true); }} />
|
|
111
|
+
</div>
|
|
112
|
+
}
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// 3. ITLoader Showcase
|
|
118
|
+
export const LoaderShowcase = () => {
|
|
119
|
+
const [variant, setVariant] = useState<any>("spinner");
|
|
120
|
+
const [size, setSize] = useState<any>("md");
|
|
121
|
+
const [color, setColor] = useState("primary");
|
|
122
|
+
|
|
123
|
+
const code = `<ITLoader\n variant="${variant}"\n size="${size}"\n color="${color}"\n/>`;
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<ShowcaseLayout
|
|
127
|
+
title="ITLoader"
|
|
128
|
+
description="Indicadores de carga animados con soporte para múltiples estilos visuales."
|
|
129
|
+
code={code}
|
|
130
|
+
demo={
|
|
131
|
+
<div className="w-full max-w-xs flex items-center justify-center min-h-[80px]">
|
|
132
|
+
<ITLoader variant={variant} size={size} color={color} />
|
|
133
|
+
</div>
|
|
134
|
+
}
|
|
135
|
+
controls={
|
|
136
|
+
<>
|
|
137
|
+
<ITSelect
|
|
138
|
+
name="var_ctrl"
|
|
139
|
+
label="Tipo de Cargador"
|
|
140
|
+
value={variant}
|
|
141
|
+
onChange={(e: any) => setVariant(e.target.value)}
|
|
142
|
+
options={[
|
|
143
|
+
{ label: "Spinner (Círculo)", value: "spinner" },
|
|
144
|
+
{ label: "Dots (Puntos)", value: "dots" },
|
|
145
|
+
{ label: "Bar (Barra)", value: "bar" },
|
|
146
|
+
{ label: "Pulse (Pulso)", value: "pulse" }
|
|
147
|
+
]}
|
|
148
|
+
/>
|
|
149
|
+
<ITSelect
|
|
150
|
+
name="sz_ctrl"
|
|
151
|
+
label="Tamaño"
|
|
152
|
+
value={size}
|
|
153
|
+
onChange={(e: any) => setSize(e.target.value)}
|
|
154
|
+
options={[
|
|
155
|
+
{ label: "Extra Small (xs)", value: "xs" },
|
|
156
|
+
{ label: "Small (sm)", value: "sm" },
|
|
157
|
+
{ label: "Medium (md)", value: "md" },
|
|
158
|
+
{ label: "Large (lg)", value: "lg" },
|
|
159
|
+
{ label: "Extra Large (xl)", value: "xl" }
|
|
160
|
+
]}
|
|
161
|
+
/>
|
|
162
|
+
<ITSelect
|
|
163
|
+
name="col_ctrl"
|
|
164
|
+
label="Color"
|
|
165
|
+
value={color}
|
|
166
|
+
onChange={(e: any) => setColor(e.target.value)}
|
|
167
|
+
options={[
|
|
168
|
+
{ label: "Primary", value: "primary" },
|
|
169
|
+
{ label: "Secondary", value: "secondary" },
|
|
170
|
+
{ label: "Success", value: "success" },
|
|
171
|
+
{ label: "Danger", value: "danger" },
|
|
172
|
+
{ label: "Warning", value: "warning" },
|
|
173
|
+
{ label: "Info", value: "info" }
|
|
174
|
+
]}
|
|
175
|
+
/>
|
|
176
|
+
</>
|
|
177
|
+
}
|
|
178
|
+
gallery={
|
|
179
|
+
<div className="flex flex-wrap items-center gap-6">
|
|
180
|
+
<ITLoader variant="spinner" size="md" color="primary" />
|
|
181
|
+
<ITLoader variant="dots" size="md" color="success" />
|
|
182
|
+
<div className="w-32"><ITLoader variant="bar" size="md" color="danger" /></div>
|
|
183
|
+
<ITLoader variant="pulse" size="md" color="purple" />
|
|
184
|
+
</div>
|
|
185
|
+
}
|
|
186
|
+
/>
|
|
187
|
+
);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// 4. ITThemeProvider Showcase
|
|
191
|
+
export const ThemeProviderShowcase = () => {
|
|
192
|
+
const { applyPreset, resolvedTheme, darkModeMode, setDarkModeMode } = useITTheme();
|
|
193
|
+
|
|
194
|
+
const code = `// En index.tsx o App.tsx\n<ITThemeProvider>\n <App />\n</ITThemeProvider>\n\n// En tu componente:\nconst { palette, resolvedTheme, darkModeMode, setDarkModeMode, applyPreset } = useITTheme();`;
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<ShowcaseLayout
|
|
198
|
+
title="ITThemeProvider"
|
|
199
|
+
description="Inyector dinámico de tokens CSS que gestiona el modo oscuro/claro y las paletas de colores unificadas."
|
|
200
|
+
code={code}
|
|
201
|
+
demo={
|
|
202
|
+
<ITStack spacing={5} className="w-full max-w-md">
|
|
203
|
+
<div>
|
|
204
|
+
<span className="text-xs font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-3 block">
|
|
205
|
+
Modo de Apariencia
|
|
206
|
+
</span>
|
|
207
|
+
<div className="flex flex-wrap gap-2">
|
|
208
|
+
{(["light", "dark", "system"] as const).map((mode) => (
|
|
209
|
+
<ITButton
|
|
210
|
+
key={mode}
|
|
211
|
+
label={mode === "light" ? "☀️ Claro" : mode === "dark" ? "🌙 Oscuro" : "💻 Sistema"}
|
|
212
|
+
color={darkModeMode === mode ? "primary" : "secondary"}
|
|
213
|
+
onClick={() => setDarkModeMode(mode)}
|
|
214
|
+
size="small"
|
|
215
|
+
/>
|
|
216
|
+
))}
|
|
217
|
+
</div>
|
|
218
|
+
<p className="text-xs text-slate-500 mt-2">
|
|
219
|
+
Tema actual: <strong>{resolvedTheme === "dark" ? "Oscuro" : "Claro"}</strong>
|
|
220
|
+
</p>
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
<div>
|
|
224
|
+
<span className="text-xs font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-3 block">
|
|
225
|
+
Presets Rápidos
|
|
226
|
+
</span>
|
|
227
|
+
<ITGrid container spacing={2}>
|
|
228
|
+
{PRESETS.map((preset) => {
|
|
229
|
+
const dotColors = [preset.colors.primary, preset.colors.secondary, preset.colors.ternary, preset.colors.success];
|
|
230
|
+
return (
|
|
231
|
+
<ITGrid key={preset.name} item xs={6}>
|
|
232
|
+
<button
|
|
233
|
+
onClick={() => applyPreset(preset.colors)}
|
|
234
|
+
className="w-full flex items-center gap-2.5 px-3 py-2.5 rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900/50 hover:border-slate-300 dark:hover:border-slate-600 transition-colors text-left"
|
|
235
|
+
>
|
|
236
|
+
<div className="flex -space-x-1">
|
|
237
|
+
{dotColors.map((c, i) => (
|
|
238
|
+
<span
|
|
239
|
+
key={i}
|
|
240
|
+
className="w-3.5 h-3.5 rounded-full border border-white dark:border-slate-800"
|
|
241
|
+
style={{ backgroundColor: c }}
|
|
242
|
+
/>
|
|
243
|
+
))}
|
|
244
|
+
</div>
|
|
245
|
+
<span className="text-xs font-semibold text-slate-700 dark:text-slate-300 truncate">
|
|
246
|
+
{preset.name.replace(/ [\w]+$/, "")}
|
|
247
|
+
</span>
|
|
248
|
+
</button>
|
|
249
|
+
</ITGrid>
|
|
250
|
+
);
|
|
251
|
+
})}
|
|
252
|
+
</ITGrid>
|
|
253
|
+
</div>
|
|
254
|
+
</ITStack>
|
|
255
|
+
}
|
|
256
|
+
controls={
|
|
257
|
+
<ITStack spacing={3}>
|
|
258
|
+
<p className="text-xs text-slate-500">
|
|
259
|
+
Haz clic en el botón flotante de paleta 🎨 en la esquina inferior derecha para abrir el diseñador completo.
|
|
260
|
+
</p>
|
|
261
|
+
<p className="text-xs text-slate-500">
|
|
262
|
+
Allí puedes ajustar cada color, guardar temas personalizados y alternar entre modo claro/oscuro.
|
|
263
|
+
</p>
|
|
264
|
+
</ITStack>
|
|
265
|
+
}
|
|
266
|
+
/>
|
|
267
|
+
);
|
|
268
|
+
};
|