@axzydev/axzy_ui_system 1.4.7 → 1.5.0
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/README.md +2 -11
- package/dist/index.cjs +2174 -1570
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +232 -19
- package/dist/index.d.ts +232 -19
- package/dist/index.js +1838 -1238
- package/dist/index.js.map +1 -1
- package/dist/layered.css +1 -1
- package/package.json +3 -16
- package/src/App.tsx +90 -73
- package/src/components/atoms/badget/badget.tsx +23 -5
- package/src/components/atoms/chip/chip.tsx +3 -1
- package/src/components/atoms/image/image.tsx +3 -1
- package/src/components/atoms/input/input.tsx +8 -5
- package/src/components/atoms/loader/loader.tsx +3 -1
- package/src/components/atoms/slide/slide.props.ts +12 -0
- package/src/components/atoms/slide/slide.tsx +3 -0
- package/src/components/molecules/alert/alert.tsx +3 -1
- package/src/components/molecules/breadcrumbs/breadcrumbs.tsx +3 -1
- package/src/components/molecules/calendar/calendar.tsx +9 -6
- package/src/components/molecules/card/card.tsx +5 -2
- package/src/components/molecules/chip-input/chip-input.tsx +9 -7
- package/src/components/molecules/date-picker/datePicker.tsx +9 -9
- package/src/components/molecules/dropdown-menu/dropdown-menu.props.ts +1 -1
- package/src/components/molecules/dropdown-menu/dropdown-menu.tsx +6 -3
- package/src/components/molecules/field/field.tsx +3 -1
- package/src/components/molecules/form-header/form-header.tsx +3 -1
- package/src/components/molecules/line-bar-chart/line-bar-chart.props.ts +2 -2
- package/src/components/molecules/line-bar-chart/line-bar-chart.tsx +20 -15
- package/src/components/molecules/masked-input/masked-input.tsx +3 -1
- package/src/components/molecules/multi-select/multi-select.tsx +12 -9
- package/src/components/molecules/pagination/pagination.tsx +11 -5
- package/src/components/molecules/search-select/search-select.tsx +11 -9
- package/src/components/molecules/select/select.tsx +6 -4
- package/src/components/molecules/stepper/stepper.tsx +6 -4
- package/src/components/molecules/table/table.props.ts +10 -2
- package/src/components/molecules/table/table.tsx +163 -114
- package/src/components/molecules/time-picker/timePicker.tsx +8 -6
- package/src/components/molecules/wysiwyg/wysiwyg.tsx +23 -12
- package/src/components/organisms/confirm-dialog/confirm-dialog.props.ts +4 -4
- package/src/components/organisms/confirm-dialog/confirm-dialog.tsx +16 -8
- package/src/components/organisms/data-table/dataTable.props.ts +3 -2
- package/src/components/organisms/data-table/dataTable.tsx +149 -81
- package/src/components/organisms/dialog/dialog.tsx +3 -0
- package/src/components/organisms/drawer/drawer.tsx +3 -0
- package/src/components/organisms/dropfile/dropfile.tsx +19 -17
- package/src/components/organisms/form-builder/fieldRenderer.tsx +4 -2
- package/src/components/organisms/navbar/navbar.tsx +4 -2
- package/src/components/organisms/page-header/page-header.tsx +3 -1
- package/src/components/organisms/searchTable/components/PaginationControls.tsx +8 -6
- package/src/components/organisms/searchTable/components/PaginationInfo.tsx +3 -1
- package/src/components/organisms/searchTable/components/SearchAndSortBar.tsx +7 -5
- package/src/components/organisms/searchTable/components/SearchInput.tsx +4 -2
- package/src/components/organisms/searchTable/components/SortButton.tsx +13 -11
- package/src/components/organisms/searchTable/components/TableEmptyState.tsx +4 -2
- package/src/components/organisms/searchTable/components/TableRow.tsx +6 -4
- package/src/components/organisms/searchTable/searchTable.tsx +4 -2
- package/src/components/organisms/sidebar/sidebar.props.ts +1 -1
- package/src/components/organisms/sidebar/sidebar.tsx +9 -4
- package/src/components/organisms/toast/toast.tsx +3 -1
- package/src/components/organisms/topbar/topbar.tsx +4 -2
- package/src/components/templates/page/page.props.ts +4 -4
- package/src/components/templates/page/page.tsx +6 -4
- package/src/components/theme-provider/themeProvider.tsx +28 -17
- package/src/dev.css +77 -2
- package/src/global.d.ts +10 -0
- package/src/i18n/context.ts +9 -0
- package/src/i18n/index.ts +22 -0
- package/src/i18n/locales/en.ts +163 -0
- package/src/i18n/locales/es.ts +165 -0
- package/src/i18n/provider.tsx +44 -0
- package/src/i18n/translator.ts +82 -0
- package/src/i18n/types.ts +54 -0
- package/src/i18n/useITTranslation.ts +20 -0
- package/src/index.css +0 -1
- package/src/index.ts +9 -3
- package/src/sandbox/LandingShowcase.tsx +224 -580
- package/src/sandbox/NotFoundShowcase.tsx +51 -36
- package/src/sandbox/TopbarSearch.tsx +6 -4
- package/src/sandbox/controls.tsx +180 -0
- package/src/sandbox/i18n.ts +1929 -0
- package/src/sandbox/icons.tsx +25 -0
- package/src/sandbox/locale.tsx +72 -0
- package/src/sandbox/ui.tsx +377 -0
- package/src/sandbox/useHashRoute.ts +46 -10
- package/src/showcases/DataShowcases.tsx +201 -80
- package/src/showcases/FeedbackShowcases.tsx +37 -30
- package/src/showcases/FormShowcases.tsx +302 -214
- package/src/showcases/GettingStartedShowcase.tsx +151 -145
- package/src/showcases/HelpShowcase.tsx +126 -128
- package/src/showcases/HomeShowcase.tsx +678 -482
- package/src/showcases/LayoutPrimitivesShowcases.tsx +129 -114
- package/src/showcases/NavigationShowcases.tsx +45 -37
- package/src/showcases/PageShowcases.tsx +171 -152
- package/src/showcases/ProductoDetalle.tsx +272 -129
- package/src/showcases/ShowcaseLayout.tsx +270 -216
- package/src/showcases/SizesShowcase.tsx +123 -64
- package/src/showcases/StructureShowcases.tsx +157 -131
- package/src/showcases/portfolioUi.tsx +153 -0
- package/src/showcases/techIcons.ts +3 -0
- package/src/types/table.types.ts +110 -0
- package/src/utils/table.utils.ts +10 -2
- package/src/components/atoms/avatar/avatar.doc.mdx +0 -48
- package/src/components/atoms/avatar/avatar.stories.tsx +0 -64
- package/src/components/atoms/badget/badget.doc.mdx +0 -46
- package/src/components/atoms/badget/badget.stories.tsx +0 -75
- package/src/components/atoms/button/button.doc.mdx +0 -59
- package/src/components/atoms/button/button.stories.tsx +0 -173
- package/src/components/atoms/checkbox/checkbox.doc.mdx +0 -54
- package/src/components/atoms/checkbox/checkbox.stories.tsx +0 -53
- package/src/components/atoms/chip/chip.doc.mdx +0 -47
- package/src/components/atoms/chip/chip.stories.tsx +0 -64
- package/src/components/atoms/divider/divider.doc.mdx +0 -42
- package/src/components/atoms/divider/divider.stories.tsx +0 -33
- package/src/components/atoms/flex/flex.doc.mdx +0 -59
- package/src/components/atoms/flex/flex.stories.tsx +0 -70
- package/src/components/atoms/grid/grid.doc.mdx +0 -54
- package/src/components/atoms/grid/grid.stories.tsx +0 -71
- package/src/components/atoms/image/image.doc.mdx +0 -44
- package/src/components/atoms/image/image.stories.tsx +0 -48
- package/src/components/atoms/input/input.doc.mdx +0 -70
- package/src/components/atoms/input/input.stories.tsx +0 -113
- package/src/components/atoms/input-number/input-number.doc.mdx +0 -74
- package/src/components/atoms/input-number/input-number.stories.tsx +0 -111
- package/src/components/atoms/loader/loader.doc.mdx +0 -43
- package/src/components/atoms/loader/loader.stories.tsx +0 -104
- package/src/components/atoms/popover/popover.doc.mdx +0 -53
- package/src/components/atoms/popover/popover.stories.tsx +0 -24
- package/src/components/atoms/progress/progress.doc.mdx +0 -48
- package/src/components/atoms/progress/progress.stories.tsx +0 -39
- package/src/components/atoms/radio/radio.doc.mdx +0 -62
- package/src/components/atoms/radio/radio.stories.tsx +0 -48
- package/src/components/atoms/segmented-control/segmented-control.doc.mdx +0 -60
- package/src/components/atoms/segmented-control/segmented-control.stories.tsx +0 -62
- package/src/components/atoms/skeleton/skeleton.doc.mdx +0 -43
- package/src/components/atoms/skeleton/skeleton.stories.tsx +0 -29
- package/src/components/atoms/slide/slide.doc.mdx +0 -46
- package/src/components/atoms/slide/slide.stories.tsx +0 -120
- package/src/components/atoms/slider/slider.doc.mdx +0 -49
- package/src/components/atoms/slider/slider.stories.tsx +0 -29
- package/src/components/atoms/stack/stack.doc.mdx +0 -126
- package/src/components/atoms/stack/stack.stories.tsx +0 -283
- package/src/components/atoms/text/text.doc.mdx +0 -41
- package/src/components/atoms/text/text.stories.tsx +0 -66
- package/src/components/atoms/textarea/textarea.doc.mdx +0 -64
- package/src/components/atoms/textarea/textarea.stories.tsx +0 -26
- package/src/components/atoms/tooltip/tooltip.doc.mdx +0 -47
- package/src/components/atoms/tooltip/tooltip.stories.tsx +0 -19
- package/src/components/isolation/isolation.stories.tsx +0 -202
- package/src/components/molecules/accordion/accordion.doc.mdx +0 -47
- package/src/components/molecules/accordion/accordion.stories.tsx +0 -68
- package/src/components/molecules/alert/alert.doc.mdx +0 -48
- package/src/components/molecules/alert/alert.stories.tsx +0 -40
- package/src/components/molecules/breadcrumbs/breadcrumbs.doc.mdx +0 -57
- package/src/components/molecules/breadcrumbs/breadcrumbs.stories.tsx +0 -20
- package/src/components/molecules/calendar/calendar.doc.mdx +0 -76
- package/src/components/molecules/calendar/calendar.stories.tsx +0 -90
- package/src/components/molecules/card/card.doc.mdx +0 -54
- package/src/components/molecules/card/card.stories.tsx +0 -57
- package/src/components/molecules/chip-input/chip-input.doc.mdx +0 -44
- package/src/components/molecules/chip-input/chip-input.stories.tsx +0 -52
- package/src/components/molecules/date-picker/date-picker.doc.mdx +0 -65
- package/src/components/molecules/date-picker/date-picker.stories.tsx +0 -88
- package/src/components/molecules/dropdown-menu/dropdown-menu.doc.mdx +0 -46
- package/src/components/molecules/dropdown-menu/dropdown-menu.stories.tsx +0 -41
- package/src/components/molecules/empty-state/empty-state.doc.mdx +0 -50
- package/src/components/molecules/empty-state/empty-state.stories.tsx +0 -19
- package/src/components/molecules/field/field.doc.mdx +0 -43
- package/src/components/molecules/field/field.stories.tsx +0 -42
- package/src/components/molecules/form-header/form-header.doc.mdx +0 -38
- package/src/components/molecules/form-header/form-header.stories.tsx +0 -52
- package/src/components/molecules/masked-input/masked-input.doc.mdx +0 -78
- package/src/components/molecules/masked-input/masked-input.stories.tsx +0 -126
- package/src/components/molecules/multi-select/multi-select.doc.mdx +0 -55
- package/src/components/molecules/multi-select/multi-select.stories.tsx +0 -59
- package/src/components/molecules/pagination/pagination.doc.mdx +0 -62
- package/src/components/molecules/pagination/pagination.stories.tsx +0 -110
- package/src/components/molecules/search-select/search-select.doc.mdx +0 -77
- package/src/components/molecules/search-select/search-select.stories.tsx +0 -146
- package/src/components/molecules/select/select.doc.mdx +0 -75
- package/src/components/molecules/select/select.stories.tsx +0 -85
- package/src/components/molecules/stat-card/stat-card.doc.mdx +0 -48
- package/src/components/molecules/stat-card/stat-card.stories.tsx +0 -40
- package/src/components/molecules/stepper/stepper.doc.mdx +0 -54
- package/src/components/molecules/stepper/stepper.stories.tsx +0 -154
- package/src/components/molecules/table/table.doc.mdx +0 -123
- package/src/components/molecules/table/table.stories.tsx +0 -402
- package/src/components/molecules/tabs/tabs.doc.mdx +0 -52
- package/src/components/molecules/tabs/tabs.stories.tsx +0 -31
- package/src/components/molecules/time-picker/timePicker.doc.mdx +0 -68
- package/src/components/molecules/time-picker/timePicker.stories.tsx +0 -130
- package/src/components/molecules/wysiwyg/wysiwyg.stories.tsx +0 -95
- package/src/components/organisms/confirm-dialog/confirm-dialog.doc.mdx +0 -60
- package/src/components/organisms/confirm-dialog/confirm-dialog.stories.tsx +0 -32
- package/src/components/organisms/data-table/ITDataTable.doc.mdx +0 -115
- package/src/components/organisms/data-table/ITDataTable.stories.tsx +0 -353
- package/src/components/organisms/dialog/dialog.doc.mdx +0 -54
- package/src/components/organisms/dialog/dialog.stories.tsx +0 -126
- package/src/components/organisms/drawer/drawer.doc.mdx +0 -59
- package/src/components/organisms/drawer/drawer.stories.tsx +0 -40
- package/src/components/organisms/dropfile/dropfile.doc.mdx +0 -74
- package/src/components/organisms/dropfile/dropfile.stories.tsx +0 -93
- package/src/components/organisms/form-builder/formBuilder.doc.mdx +0 -251
- package/src/components/organisms/form-builder/formBuilder.stories.tsx +0 -914
- package/src/components/organisms/navbar/navbar.doc.mdx +0 -77
- package/src/components/organisms/navbar/navbar.stories.tsx +0 -83
- package/src/components/organisms/page-header/page-header.doc.mdx +0 -54
- package/src/components/organisms/page-header/page-header.stories.tsx +0 -74
- package/src/components/organisms/searchTable/searchTable.doc.mdx +0 -79
- package/src/components/organisms/searchTable/searchTable.stories.tsx +0 -73
- package/src/components/organisms/sidebar/sidebar.doc.mdx +0 -176
- package/src/components/organisms/sidebar/sidebar.stories.tsx +0 -234
- package/src/components/organisms/toast/toast.doc.mdx +0 -50
- package/src/components/organisms/toast/toast.stories.tsx +0 -137
- package/src/components/organisms/topbar/topbar.doc.mdx +0 -72
- package/src/components/organisms/topbar/topbar.stories.tsx +0 -79
- package/src/components/organisms/triple-filter/tripleFilter.doc.mdx +0 -62
- package/src/components/organisms/triple-filter/tripleFilter.stories.tsx +0 -31
- package/src/components/templates/layout/layout.doc.mdx +0 -53
- package/src/components/templates/layout/layout.stories.tsx +0 -113
- package/src/components/templates/page/page.doc.mdx +0 -86
- package/src/components/templates/page/page.stories.tsx +0 -97
- package/src/components/theme-provider/themeProvider.doc.mdx +0 -85
- package/src/components/theme-provider/themeProvider.stories.tsx +0 -58
|
@@ -3,6 +3,7 @@ import { ITConfirmDialogProps } from "./confirm-dialog.props";
|
|
|
3
3
|
import ITButton from "@/components/atoms/button/button";
|
|
4
4
|
import { FaExclamationTriangle } from "react-icons/fa";
|
|
5
5
|
import ITText from "@/components/atoms/text/text";
|
|
6
|
+
import { useITTranslation } from "@/i18n";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Confirmation modal dialog for destructive or critical actions.
|
|
@@ -27,15 +28,22 @@ export default function ITConfirmDialog({
|
|
|
27
28
|
isOpen,
|
|
28
29
|
onClose,
|
|
29
30
|
onConfirm,
|
|
30
|
-
title
|
|
31
|
-
message
|
|
32
|
-
confirmLabel
|
|
33
|
-
cancelLabel
|
|
31
|
+
title,
|
|
32
|
+
message,
|
|
33
|
+
confirmLabel,
|
|
34
|
+
cancelLabel,
|
|
34
35
|
variant = "primary",
|
|
35
36
|
loading = false,
|
|
36
37
|
}: ITConfirmDialogProps) {
|
|
38
|
+
const { t } = useITTranslation();
|
|
39
|
+
|
|
37
40
|
if (!isOpen) return null;
|
|
38
41
|
|
|
42
|
+
const resolvedTitle = title ?? t("confirmDialog.title");
|
|
43
|
+
const resolvedMessage = message ?? t("confirmDialog.message");
|
|
44
|
+
const resolvedConfirmLabel = confirmLabel ?? t("common.confirm");
|
|
45
|
+
const resolvedCancelLabel = cancelLabel ?? t("common.cancel");
|
|
46
|
+
|
|
39
47
|
return (
|
|
40
48
|
<div className="fixed inset-0 z-[60] flex items-center justify-center p-4">
|
|
41
49
|
<div className="absolute inset-0 bg-black/40 backdrop-blur-sm" onClick={onClose} />
|
|
@@ -50,13 +58,13 @@ export default function ITConfirmDialog({
|
|
|
50
58
|
<FaExclamationTriangle className="text-amber-600" size={18} />
|
|
51
59
|
</div>
|
|
52
60
|
<div className="flex-1">
|
|
53
|
-
<ITText as="h3" className="text-lg font-bold text-slate-800 dark:text-white">{
|
|
54
|
-
<ITText as="p" className="text-sm text-slate-500 dark:text-slate-400 mt-1">{
|
|
61
|
+
<ITText as="h3" className="text-lg font-bold text-slate-800 dark:text-white">{resolvedTitle}</ITText>
|
|
62
|
+
<ITText as="p" className="text-sm text-slate-500 dark:text-slate-400 mt-1">{resolvedMessage}</ITText>
|
|
55
63
|
</div>
|
|
56
64
|
</div>
|
|
57
65
|
<div className="flex justify-end gap-3 mt-6">
|
|
58
|
-
<ITButton label={
|
|
59
|
-
<ITButton label={
|
|
66
|
+
<ITButton label={resolvedCancelLabel} variant="outlined" size="sm" onClick={onClose} disabled={loading} />
|
|
67
|
+
<ITButton label={resolvedConfirmLabel} color={variant} size="sm" onClick={onConfirm} disabled={loading} />
|
|
60
68
|
</div>
|
|
61
69
|
</div>
|
|
62
70
|
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
import { Column } from "@/components/molecules/table/table.props";
|
|
3
|
-
import { ColumnFilters, TableDensity } from "@/types/table.types";
|
|
3
|
+
import { ColumnFilters, TableDensity, TableDesignProps } from "@/types/table.types";
|
|
4
4
|
|
|
5
5
|
/** Parameters passed to `fetchData` every time pagination, filters, or sorting change. */
|
|
6
6
|
export interface ITDataTableFetchParams {
|
|
@@ -31,7 +31,8 @@ export interface ITDataTableResponse<T> {
|
|
|
31
31
|
total: number;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
export interface ITDataTableProps<T extends Record<string, unknown>>
|
|
34
|
+
export interface ITDataTableProps<T extends Record<string, unknown>>
|
|
35
|
+
extends TableDesignProps {
|
|
35
36
|
/**
|
|
36
37
|
* The column configuration array matching ITTable but adapted for Server-Side processing
|
|
37
38
|
*/
|
|
@@ -13,6 +13,7 @@ import ITSearchSelect from "@/components/molecules/search-select/search-select";
|
|
|
13
13
|
import ITDatePicker from "@/components/molecules/date-picker/datePicker";
|
|
14
14
|
import { Column } from "@/components/molecules/table/table.props";
|
|
15
15
|
import { formatCurrencyMX, getPinnedColumnMeta, isInteractiveTarget } from "@/utils/table.utils";
|
|
16
|
+
import { useITTranslation, toIntlLocale } from "@/i18n";
|
|
16
17
|
import { ITDataTableProps } from "./dataTable.props";
|
|
17
18
|
import ITText from "@/components/atoms/text/text";
|
|
18
19
|
import {
|
|
@@ -85,13 +86,55 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
85
86
|
rowHeight,
|
|
86
87
|
overscan = 5,
|
|
87
88
|
stickyHeader = false,
|
|
89
|
+
showViewToggle = true,
|
|
90
|
+
design,
|
|
91
|
+
colors,
|
|
92
|
+
containerStyle,
|
|
93
|
+
cardClassName,
|
|
94
|
+
cardStyle,
|
|
95
|
+
toolbarClassName,
|
|
96
|
+
toolbarStyle,
|
|
97
|
+
headerClassName,
|
|
98
|
+
headerStyle,
|
|
99
|
+
headerCellClassName,
|
|
100
|
+
headerCellStyle,
|
|
101
|
+
rowClassName,
|
|
102
|
+
rowStyle,
|
|
103
|
+
cellClassName,
|
|
104
|
+
cellStyle,
|
|
105
|
+
cardsClassName,
|
|
106
|
+
cardsStyle,
|
|
107
|
+
footerClassName,
|
|
108
|
+
footerStyle,
|
|
88
109
|
}: ITDataTableProps<T>) {
|
|
110
|
+
const { t, locale } = useITTranslation();
|
|
89
111
|
const [viewMode, setViewMode] = useState<"table" | "cards">(defaultView || "table");
|
|
90
112
|
const { ref: rootRef, width: containerWidth } = useElementSize<HTMLDivElement>();
|
|
91
113
|
const [data, setData] = useState<T[]>([]);
|
|
92
114
|
const [totalItems, setTotalItems] = useState(0);
|
|
93
115
|
const [isLoading, setIsLoading] = useState(fetchOnMount);
|
|
94
116
|
|
|
117
|
+
// Per-instance color overrides written as local `--color-table-*` variables.
|
|
118
|
+
// Declared on the wrapper (an ancestor), they beat the global theme's
|
|
119
|
+
// `:root` values for this subtree only.
|
|
120
|
+
const colorVars = {
|
|
121
|
+
...(colors?.headerBg ? { "--color-table-headerBg": colors.headerBg } : {}),
|
|
122
|
+
...(colors?.headerText ? { "--color-table-headerText": colors.headerText } : {}),
|
|
123
|
+
...(colors?.rowBg ? { "--color-table-rowBg": colors.rowBg } : {}),
|
|
124
|
+
...(colors?.rowText ? { "--color-table-rowText": colors.rowText } : {}),
|
|
125
|
+
...(colors?.rowHover ? { "--color-table-rowHover": colors.rowHover } : {}),
|
|
126
|
+
} as React.CSSProperties;
|
|
127
|
+
|
|
128
|
+
/** Merge a `design` slot with its flat shortcut (flat wins) into className/style. */
|
|
129
|
+
const mergeSlot = (
|
|
130
|
+
slot: { className?: string; style?: React.CSSProperties } | undefined,
|
|
131
|
+
flatClassName?: string,
|
|
132
|
+
flatStyle?: React.CSSProperties
|
|
133
|
+
) => ({
|
|
134
|
+
className: clsx(slot?.className, flatClassName),
|
|
135
|
+
style: { ...slot?.style, ...flatStyle } as React.CSSProperties,
|
|
136
|
+
});
|
|
137
|
+
|
|
95
138
|
const isFixed = layout === "fixed";
|
|
96
139
|
const forcedCards =
|
|
97
140
|
autoCardBreakpoint > 0 && containerWidth > 0 && containerWidth < autoCardBreakpoint;
|
|
@@ -198,17 +241,21 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
198
241
|
currentValue === undefined ? true : currentValue === true ? false : undefined;
|
|
199
242
|
|
|
200
243
|
const getToggleLabel = () => {
|
|
201
|
-
if (currentValue === undefined) return "
|
|
202
|
-
if (currentValue === true) return "
|
|
203
|
-
return "
|
|
244
|
+
if (currentValue === undefined) return t("table.showAll");
|
|
245
|
+
if (currentValue === true) return t("table.filterTrue");
|
|
246
|
+
return t("table.filterFalse");
|
|
204
247
|
};
|
|
248
|
+
const toggleLabel = t("table.filterToggle", {
|
|
249
|
+
action: getToggleLabel(),
|
|
250
|
+
label: col.label,
|
|
251
|
+
});
|
|
205
252
|
|
|
206
253
|
return (
|
|
207
254
|
<button
|
|
208
255
|
className="flex items-center justify-center cursor-pointer focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 rounded-full p-1 transition-all duration-200"
|
|
209
256
|
onClick={() => handleFilterChange(col.key, nextValue)}
|
|
210
|
-
aria-label={
|
|
211
|
-
title={
|
|
257
|
+
aria-label={toggleLabel}
|
|
258
|
+
title={toggleLabel}
|
|
212
259
|
disabled={isLoading}
|
|
213
260
|
>
|
|
214
261
|
<div className="relative w-10 h-5 bg-secondary-300 rounded-full">
|
|
@@ -229,16 +276,16 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
229
276
|
|
|
230
277
|
if (col.filter === "catalog" && col.catalogOptions) {
|
|
231
278
|
if (col.catalogOptions.loading) {
|
|
232
|
-
return <FaSpinner className="animate-spin" aria-label="
|
|
279
|
+
return <FaSpinner className="animate-spin" aria-label={t("common.loadingOptions")} title={t("common.loadingOptions")} />;
|
|
233
280
|
}
|
|
234
281
|
if (col.catalogOptions.error) {
|
|
235
|
-
return <ITText as="span" className="text-danger-500 text-xs">
|
|
282
|
+
return <ITText as="span" className="text-danger-500 text-xs">{t("common.loadError")}</ITText>;
|
|
236
283
|
}
|
|
237
284
|
return (
|
|
238
285
|
<ITSelect
|
|
239
286
|
name={`filter-${col.key}`}
|
|
240
287
|
options={[
|
|
241
|
-
{ value: "", label: "
|
|
288
|
+
{ value: "", label: t("common.all") },
|
|
242
289
|
...col.catalogOptions.data.map((item) => ({
|
|
243
290
|
value: String(item.id),
|
|
244
291
|
label: item.name,
|
|
@@ -258,10 +305,10 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
258
305
|
|
|
259
306
|
if (col.filter === "search" && col.catalogOptions) {
|
|
260
307
|
if (col.catalogOptions.loading) {
|
|
261
|
-
return <FaSpinner className="animate-spin" aria-label="
|
|
308
|
+
return <FaSpinner className="animate-spin" aria-label={t("common.loadingOptions")} title={t("common.loadingOptions")} />;
|
|
262
309
|
}
|
|
263
310
|
if (col.catalogOptions.error) {
|
|
264
|
-
return <ITText as="span" className="text-danger-500 text-xs">
|
|
311
|
+
return <ITText as="span" className="text-danger-500 text-xs">{t("common.loadError")}</ITText>;
|
|
265
312
|
}
|
|
266
313
|
const searchValue = filters[col.key];
|
|
267
314
|
return (
|
|
@@ -280,7 +327,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
280
327
|
onSearch={col.catalogOptions.onSearch}
|
|
281
328
|
isLoading={col.catalogOptions.loading}
|
|
282
329
|
size="sm"
|
|
283
|
-
placeholder="
|
|
330
|
+
placeholder={t("common.search")}
|
|
284
331
|
clearable
|
|
285
332
|
className="w-full"
|
|
286
333
|
onBlur={() => {}}
|
|
@@ -299,7 +346,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
299
346
|
minDate={col.dateFilterOptions?.minDate}
|
|
300
347
|
maxDate={col.dateFilterOptions?.maxDate}
|
|
301
348
|
size="sm"
|
|
302
|
-
placeholder="
|
|
349
|
+
placeholder={t("datePicker.placeholder")}
|
|
303
350
|
className="w-full"
|
|
304
351
|
disabled={isLoading}
|
|
305
352
|
/>
|
|
@@ -319,7 +366,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
319
366
|
minDate={col.dateFilterOptions?.minDate}
|
|
320
367
|
maxDate={col.dateFilterOptions?.maxDate}
|
|
321
368
|
size="sm"
|
|
322
|
-
placeholder="
|
|
369
|
+
placeholder={t("datePicker.rangePlaceholder")}
|
|
323
370
|
className="w-full"
|
|
324
371
|
disabled={isLoading}
|
|
325
372
|
/>
|
|
@@ -330,7 +377,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
330
377
|
<ITInput
|
|
331
378
|
name={`filter-${col.key}`}
|
|
332
379
|
className="w-full text-xs"
|
|
333
|
-
placeholder="
|
|
380
|
+
placeholder={t("common.search")}
|
|
334
381
|
value={String(filters[col.key] || "")}
|
|
335
382
|
onChange={(e) => handleFilterChange(col.key, e.target.value)}
|
|
336
383
|
onBlur={() => {}}
|
|
@@ -345,12 +392,12 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
345
392
|
|
|
346
393
|
switch (col.type) {
|
|
347
394
|
case "number":
|
|
348
|
-
return typeof value === "number" && col.currencyMX ? formatCurrencyMX(value) : value;
|
|
395
|
+
return typeof value === "number" && col.currencyMX ? formatCurrencyMX(value, toIntlLocale(locale)) : value;
|
|
349
396
|
case "boolean":
|
|
350
397
|
return value ? (
|
|
351
|
-
<FaCheck className="text-success-500" aria-label="
|
|
398
|
+
<FaCheck className="text-success-500" aria-label={t("common.true")} title={t("common.true")} />
|
|
352
399
|
) : (
|
|
353
|
-
<FaTimes className="text-danger-500" aria-label="
|
|
400
|
+
<FaTimes className="text-danger-500" aria-label={t("common.false")} title={t("common.false")} />
|
|
354
401
|
);
|
|
355
402
|
case "actions":
|
|
356
403
|
return col.actions ? col.actions(row) : null;
|
|
@@ -409,6 +456,29 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
409
456
|
onRowClick(row, event);
|
|
410
457
|
};
|
|
411
458
|
|
|
459
|
+
const containerSlot = mergeSlot(design?.container, containerClassName, containerStyle);
|
|
460
|
+
const cardSlot = mergeSlot(design?.card, cardClassName, cardStyle);
|
|
461
|
+
const toolbarSlot = mergeSlot(design?.toolbar, toolbarClassName, toolbarStyle);
|
|
462
|
+
const headerSlot = mergeSlot(design?.header, headerClassName, headerStyle);
|
|
463
|
+
const headerCellSlot = mergeSlot(design?.headerCell, headerCellClassName, headerCellStyle);
|
|
464
|
+
const rowSlot = mergeSlot(design?.row, rowClassName, rowStyle);
|
|
465
|
+
const cellSlot = mergeSlot(design?.cell, cellClassName, cellStyle);
|
|
466
|
+
const cardsSlot = mergeSlot(design?.cards, cardsClassName, cardsStyle);
|
|
467
|
+
const footerSlot = mergeSlot(design?.footer, footerClassName, footerStyle);
|
|
468
|
+
|
|
469
|
+
const viewToggle = (
|
|
470
|
+
<div className="flex items-center bg-slate-100 dark:bg-slate-800/80 rounded-lg p-0.5 border border-slate-200 dark:border-slate-700/50">
|
|
471
|
+
<button onClick={() => setViewMode("table")} disabled={forcedCards} className={segCtrlClass("table")}>
|
|
472
|
+
<FaTable size={11} />
|
|
473
|
+
{t("table.viewTable")}
|
|
474
|
+
</button>
|
|
475
|
+
<button onClick={() => setViewMode("cards")} className={segCtrlClass("cards")}>
|
|
476
|
+
<FaThLarge size={11} />
|
|
477
|
+
{t("table.viewCards")}
|
|
478
|
+
</button>
|
|
479
|
+
</div>
|
|
480
|
+
);
|
|
481
|
+
|
|
412
482
|
const tableEl = (
|
|
413
483
|
<table
|
|
414
484
|
className={clsx(
|
|
@@ -439,7 +509,8 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
439
509
|
)}
|
|
440
510
|
<thead>
|
|
441
511
|
<tr
|
|
442
|
-
className={clsx(tableHeaderRow, "dark:text-slate-200")}
|
|
512
|
+
className={clsx(tableHeaderRow, "dark:text-slate-200", headerSlot.className)}
|
|
513
|
+
style={headerSlot.style}
|
|
443
514
|
aria-rowindex={isTableVirtual ? 1 : undefined}
|
|
444
515
|
>
|
|
445
516
|
{columns.map((col) => {
|
|
@@ -455,23 +526,23 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
455
526
|
isPinned && "sticky",
|
|
456
527
|
isStickyHeader && "sticky top-0 bg-secondary-50",
|
|
457
528
|
isPinned ? "z-[15]" : isStickyHeader && "z-10",
|
|
458
|
-
isPinned && (col.pinned === "left" ? "it-table-pinned-left" : "it-table-pinned-right")
|
|
529
|
+
isPinned && (col.pinned === "left" ? "it-table-pinned-left" : "it-table-pinned-right"),
|
|
530
|
+
headerCellSlot.className,
|
|
531
|
+
col.headerClassName
|
|
459
532
|
)}
|
|
460
|
-
style={
|
|
461
|
-
col.minWidth != null
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
: undefined
|
|
474
|
-
}
|
|
533
|
+
style={{
|
|
534
|
+
...(col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {}),
|
|
535
|
+
...(isStickyHeader || isPinned
|
|
536
|
+
? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" }
|
|
537
|
+
: {}),
|
|
538
|
+
...(isPinned
|
|
539
|
+
? pin.side === "left"
|
|
540
|
+
? { left: pin.offset }
|
|
541
|
+
: { right: pin.offset }
|
|
542
|
+
: {}),
|
|
543
|
+
...headerCellSlot.style,
|
|
544
|
+
...col.headerStyle,
|
|
545
|
+
}}
|
|
475
546
|
>
|
|
476
547
|
<div className={isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]"}>
|
|
477
548
|
<div className="flex items-center justify-between gap-2">
|
|
@@ -485,7 +556,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
485
556
|
? "bg-secondary-200 text-secondary-900"
|
|
486
557
|
: "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"
|
|
487
558
|
} disabled:opacity-50`}
|
|
488
|
-
title={
|
|
559
|
+
title={t("table.sortBy", { label: col.label })}
|
|
489
560
|
>
|
|
490
561
|
<MdOutlineSwapVert className="w-4 h-4" aria-hidden="true" />
|
|
491
562
|
</button>
|
|
@@ -516,8 +587,10 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
516
587
|
className={clsx(
|
|
517
588
|
tableRow,
|
|
518
589
|
variant === "striped" && absoluteIndex % 2 === 0 && "bg-secondary-50/40 dark:bg-slate-800/20",
|
|
519
|
-
onRowClick && !isLoading && tableRowClickable
|
|
590
|
+
onRowClick && !isLoading && tableRowClickable,
|
|
591
|
+
rowSlot.className
|
|
520
592
|
)}
|
|
593
|
+
style={rowSlot.style}
|
|
521
594
|
tabIndex={onRowClick && !isLoading ? 0 : undefined}
|
|
522
595
|
onClick={onRowClick && !isLoading ? handleRowClick(row) : undefined}
|
|
523
596
|
onKeyDown={onRowClick && !isLoading ? handleRowKeyDown(row) : undefined}
|
|
@@ -539,20 +612,20 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
539
612
|
col.align && tableAlignClasses[col.align],
|
|
540
613
|
isPinned && "sticky bg-[var(--color-table-rowBg,white)] group-hover:bg-[var(--color-table-rowHover,var(--color-secondary-50))]",
|
|
541
614
|
isPinned && (col.pinned === "left" ? "it-table-pinned-left" : "it-table-pinned-right"),
|
|
542
|
-
isPinned && "z-[1]"
|
|
615
|
+
isPinned && "z-[1]",
|
|
616
|
+
cellSlot.className,
|
|
617
|
+
col.cellClassName
|
|
543
618
|
)}
|
|
544
|
-
style={
|
|
545
|
-
col.minWidth != null
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
: undefined
|
|
555
|
-
}
|
|
619
|
+
style={{
|
|
620
|
+
...(col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {}),
|
|
621
|
+
...(isPinned
|
|
622
|
+
? pin.side === "left"
|
|
623
|
+
? { left: pin.offset }
|
|
624
|
+
: { right: pin.offset }
|
|
625
|
+
: {}),
|
|
626
|
+
...cellSlot.style,
|
|
627
|
+
...col.cellStyle,
|
|
628
|
+
}}
|
|
556
629
|
title={truncateTitle}
|
|
557
630
|
>
|
|
558
631
|
{col.type === "actions" ? (
|
|
@@ -581,8 +654,8 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
581
654
|
<td colSpan={columns.length} className="px-6 py-12 text-center">
|
|
582
655
|
{!isLoading && (
|
|
583
656
|
<div className={tableEmptyContent}>
|
|
584
|
-
<ITText as="span" className="text-lg">
|
|
585
|
-
<ITText as="span" className="text-sm mt-1">
|
|
657
|
+
<ITText as="span" className="text-lg">{t("table.noResults")}</ITText>
|
|
658
|
+
<ITText as="span" className="text-sm mt-1">{t("table.adjustFilters")}</ITText>
|
|
586
659
|
</div>
|
|
587
660
|
)}
|
|
588
661
|
</td>
|
|
@@ -593,10 +666,20 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
593
666
|
);
|
|
594
667
|
|
|
595
668
|
return (
|
|
596
|
-
<div
|
|
597
|
-
|
|
669
|
+
<div
|
|
670
|
+
ref={rootRef}
|
|
671
|
+
className={clsx("space-y-4 w-full relative", containerSlot.className)}
|
|
672
|
+
style={{ ...colorVars, ...containerSlot.style }}
|
|
673
|
+
>
|
|
674
|
+
<div
|
|
675
|
+
className={clsx(tableContainer, cardSlot.className)}
|
|
676
|
+
style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)', ...cardSlot.style }}
|
|
677
|
+
>
|
|
598
678
|
{title && (
|
|
599
|
-
<div
|
|
679
|
+
<div
|
|
680
|
+
className={clsx("px-6 py-5 flex items-center justify-between", toolbarSlot.className)}
|
|
681
|
+
style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)', ...toolbarSlot.style }}
|
|
682
|
+
>
|
|
600
683
|
<ITText as="h2" className="text-xl font-bold text-secondary-900 leading-tight">{title}</ITText>
|
|
601
684
|
<div className="flex items-center gap-3">
|
|
602
685
|
{isLoading && (
|
|
@@ -604,32 +687,14 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
604
687
|
{loadingIndicator || <FaSpinner className="animate-spin text-primary-500 text-xl" />}
|
|
605
688
|
</div>
|
|
606
689
|
)}
|
|
607
|
-
|
|
608
|
-
<button onClick={() => setViewMode("table")} disabled={forcedCards} className={segCtrlClass("table")}>
|
|
609
|
-
<FaTable size={11} />
|
|
610
|
-
Table
|
|
611
|
-
</button>
|
|
612
|
-
<button onClick={() => setViewMode("cards")} className={segCtrlClass("cards")}>
|
|
613
|
-
<FaThLarge size={11} />
|
|
614
|
-
Cards
|
|
615
|
-
</button>
|
|
616
|
-
</div>
|
|
690
|
+
{showViewToggle && viewToggle}
|
|
617
691
|
</div>
|
|
618
692
|
</div>
|
|
619
693
|
)}
|
|
620
694
|
|
|
621
|
-
{!title && (
|
|
622
|
-
<div className="flex justify-end px-4 pt-3">
|
|
623
|
-
|
|
624
|
-
<button onClick={() => setViewMode("table")} disabled={forcedCards} className={segCtrlClass("table")}>
|
|
625
|
-
<FaTable size={11} />
|
|
626
|
-
Table
|
|
627
|
-
</button>
|
|
628
|
-
<button onClick={() => setViewMode("cards")} className={segCtrlClass("cards")}>
|
|
629
|
-
<FaThLarge size={11} />
|
|
630
|
-
Cards
|
|
631
|
-
</button>
|
|
632
|
-
</div>
|
|
695
|
+
{!title && showViewToggle && (
|
|
696
|
+
<div className={clsx("flex justify-end px-4 pt-3", toolbarSlot.className)} style={toolbarSlot.style}>
|
|
697
|
+
{viewToggle}
|
|
633
698
|
</div>
|
|
634
699
|
)}
|
|
635
700
|
|
|
@@ -640,7 +705,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
640
705
|
{loadingIndicator || (
|
|
641
706
|
<>
|
|
642
707
|
<FaSpinner className="animate-spin text-primary-500 text-4xl" />
|
|
643
|
-
<ITText as="span" className="text-sm font-semibold text-secondary-600 animate-pulse">
|
|
708
|
+
<ITText as="span" className="text-sm font-semibold text-secondary-600 animate-pulse">{t("table.loading")}</ITText>
|
|
644
709
|
</>
|
|
645
710
|
)}
|
|
646
711
|
</div>
|
|
@@ -648,7 +713,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
648
713
|
)}
|
|
649
714
|
|
|
650
715
|
{effectiveView === "cards" ? (
|
|
651
|
-
<div className="p-4 space-y-3 max-h-[400px] overflow-y-auto">
|
|
716
|
+
<div className={clsx("p-4 space-y-3 max-h-[400px] overflow-y-auto", cardsSlot.className)} style={cardsSlot.style}>
|
|
652
717
|
{data.length > 0 ? (
|
|
653
718
|
data.map((row, i) => (
|
|
654
719
|
<div
|
|
@@ -665,8 +730,8 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
665
730
|
) : (
|
|
666
731
|
!isLoading && (
|
|
667
732
|
<div className={clsx(tableEmptyContent, "py-12")}>
|
|
668
|
-
<ITText as="span" className="text-lg">
|
|
669
|
-
<ITText as="span" className="text-sm mt-1">
|
|
733
|
+
<ITText as="span" className="text-lg">{t("table.noResults")}</ITText>
|
|
734
|
+
<ITText as="span" className="text-sm mt-1">{t("table.adjustFilters")}</ITText>
|
|
670
735
|
</div>
|
|
671
736
|
)
|
|
672
737
|
)}
|
|
@@ -685,7 +750,10 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
685
750
|
</div>
|
|
686
751
|
</div>
|
|
687
752
|
|
|
688
|
-
<div
|
|
753
|
+
<div
|
|
754
|
+
className={clsx("rounded-b-xl px-6 py-4", footerSlot.className)}
|
|
755
|
+
style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)', ...footerSlot.style }}
|
|
756
|
+
>
|
|
689
757
|
<ITPagination
|
|
690
758
|
currentPage={currentPage}
|
|
691
759
|
totalPages={computedTotalPages}
|
|
@@ -6,6 +6,7 @@ import { ITDialogProps } from "./dialog.props";
|
|
|
6
6
|
import useClickOutside from "@/hooks/useClickOutside";
|
|
7
7
|
import ITFormHeader from "@/components/molecules/form-header/form-header";
|
|
8
8
|
import ITText from "@/components/atoms/text/text";
|
|
9
|
+
import { useITTranslation } from "@/i18n";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Modal dialog rendered via React portal with overlay backdrop.
|
|
@@ -42,6 +43,7 @@ export default function ITDialog({
|
|
|
42
43
|
useFormHeader = false,
|
|
43
44
|
fullScreen = false,
|
|
44
45
|
}: ITDialogProps) {
|
|
46
|
+
const { t } = useITTranslation();
|
|
45
47
|
const modalRef = useRef<HTMLDivElement>(null);
|
|
46
48
|
|
|
47
49
|
useClickOutside(modalRef, onClose);
|
|
@@ -100,6 +102,7 @@ export default function ITDialog({
|
|
|
100
102
|
<button
|
|
101
103
|
className="absolute top-2 right-2 text-secondary-600 hover:text-secondary-900"
|
|
102
104
|
onClick={onClose}
|
|
105
|
+
aria-label={t("common.close")}
|
|
103
106
|
>
|
|
104
107
|
<FaRegTimesCircle />
|
|
105
108
|
</button>
|
|
@@ -4,6 +4,7 @@ import { FaTimes } from "react-icons/fa";
|
|
|
4
4
|
import useClickOutside from "@/hooks/useClickOutside";
|
|
5
5
|
import { useRef } from "react";
|
|
6
6
|
import ITText from "@/components/atoms/text/text";
|
|
7
|
+
import { useITTranslation } from "@/i18n";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Sliding panel drawer from the left or right screen edge.
|
|
@@ -35,6 +36,7 @@ export default function ITDrawer({
|
|
|
35
36
|
className,
|
|
36
37
|
style,
|
|
37
38
|
}: ITDrawerProps) {
|
|
39
|
+
const { t } = useITTranslation();
|
|
38
40
|
const panelRef = useRef<HTMLDivElement>(null);
|
|
39
41
|
useClickOutside(panelRef, onClose);
|
|
40
42
|
|
|
@@ -58,6 +60,7 @@ export default function ITDrawer({
|
|
|
58
60
|
<ITText as="h2" className="text-lg font-bold text-slate-800 dark:text-white">{title}</ITText>
|
|
59
61
|
<button
|
|
60
62
|
onClick={onClose}
|
|
63
|
+
aria-label={t("common.close")}
|
|
61
64
|
className="w-8 h-8 flex items-center justify-center rounded-lg hover:bg-slate-100 dark:hover:bg-slate-800 text-slate-400 hover:text-slate-600 transition-colors"
|
|
62
65
|
>
|
|
63
66
|
<FaTimes size={14} />
|