flysoft-react-ui 0.5.0 → 0.5.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/App.d.ts.map +1 -1
- package/dist/App.js +19 -7
- package/dist/components/form-controls/AutocompleteInput.d.ts +11 -3
- package/dist/components/form-controls/AutocompleteInput.d.ts.map +1 -1
- package/dist/components/form-controls/AutocompleteInput.js +411 -31
- package/dist/components/form-controls/Button.d.ts +3 -0
- package/dist/components/form-controls/Button.d.ts.map +1 -1
- package/dist/components/form-controls/Button.js +160 -19
- package/dist/components/form-controls/Checkbox.d.ts +14 -0
- package/dist/components/form-controls/Checkbox.d.ts.map +1 -0
- package/dist/components/form-controls/Checkbox.js +79 -0
- package/dist/components/form-controls/DateInput.d.ts +24 -4
- package/dist/components/form-controls/DateInput.d.ts.map +1 -1
- package/dist/components/form-controls/DateInput.js +492 -70
- package/dist/components/form-controls/DatePicker.d.ts +4 -3
- package/dist/components/form-controls/DatePicker.d.ts.map +1 -1
- package/dist/components/form-controls/DatePicker.js +26 -30
- package/dist/components/form-controls/Input.d.ts +10 -1
- package/dist/components/form-controls/Input.d.ts.map +1 -1
- package/dist/components/form-controls/Input.js +17 -10
- package/dist/components/form-controls/LinkButton.d.ts +15 -0
- package/dist/components/form-controls/LinkButton.d.ts.map +1 -0
- package/dist/components/form-controls/LinkButton.js +248 -0
- package/dist/components/form-controls/Pagination.d.ts +1 -0
- package/dist/components/form-controls/Pagination.d.ts.map +1 -1
- package/dist/components/form-controls/Pagination.js +3 -40
- package/dist/components/form-controls/RadioButtonGroup.d.ts +62 -0
- package/dist/components/form-controls/RadioButtonGroup.d.ts.map +1 -0
- package/dist/components/form-controls/RadioButtonGroup.js +220 -0
- package/dist/components/form-controls/SearchSelectInput-OLD.d.ts +68 -0
- package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +1 -0
- package/dist/components/form-controls/SearchSelectInput-OLD.js +963 -0
- package/dist/components/form-controls/SearchSelectInput.d.ts +70 -0
- package/dist/components/form-controls/SearchSelectInput.d.ts.map +1 -0
- package/dist/components/form-controls/SearchSelectInput.js +336 -0
- package/dist/components/form-controls/index.d.ts +9 -1
- package/dist/components/form-controls/index.d.ts.map +1 -1
- package/dist/components/form-controls/index.js +4 -0
- package/dist/components/layout/Accordion.d.ts +13 -0
- package/dist/components/layout/Accordion.d.ts.map +1 -0
- package/dist/components/layout/Accordion.js +67 -0
- package/dist/components/layout/AppLayout.d.ts +3 -2
- package/dist/components/layout/AppLayout.d.ts.map +1 -1
- package/dist/components/layout/AppLayout.js +104 -31
- package/dist/components/layout/Card.d.ts +8 -3
- package/dist/components/layout/Card.d.ts.map +1 -1
- package/dist/components/layout/Card.js +18 -19
- package/dist/components/layout/Collection.js +1 -1
- package/dist/components/layout/DataTable.d.ts +3 -1
- package/dist/components/layout/DataTable.d.ts.map +1 -1
- package/dist/components/layout/DataTable.js +34 -29
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/components/layout/index.js +1 -0
- package/dist/components/utils/Avatar.d.ts +49 -0
- package/dist/components/utils/Avatar.d.ts.map +1 -0
- package/dist/components/utils/Avatar.js +93 -0
- package/dist/components/utils/Badge.d.ts +3 -0
- package/dist/components/utils/Badge.d.ts.map +1 -1
- package/dist/components/utils/Badge.js +131 -26
- package/dist/components/utils/Dialog.d.ts.map +1 -1
- package/dist/components/utils/Dialog.js +6 -1
- package/dist/components/utils/Filter.d.ts +57 -0
- package/dist/components/utils/Filter.d.ts.map +1 -0
- package/dist/components/utils/Filter.js +581 -0
- package/dist/components/utils/FiltersDialog.d.ts +21 -0
- package/dist/components/utils/FiltersDialog.d.ts.map +1 -0
- package/dist/components/utils/FiltersDialog.js +104 -0
- package/dist/components/utils/Loader.js +2 -2
- package/dist/components/utils/RoadMap.d.ts +59 -0
- package/dist/components/utils/RoadMap.d.ts.map +1 -0
- package/dist/components/utils/RoadMap.js +139 -0
- package/dist/components/utils/Snackbar.d.ts +13 -0
- package/dist/components/utils/Snackbar.d.ts.map +1 -0
- package/dist/components/utils/Snackbar.js +122 -0
- package/dist/components/utils/SnackbarContainer.d.ts +7 -0
- package/dist/components/utils/SnackbarContainer.d.ts.map +1 -0
- package/dist/components/utils/SnackbarContainer.js +25 -0
- package/dist/components/utils/iconUtils.d.ts +16 -0
- package/dist/components/utils/iconUtils.d.ts.map +1 -0
- package/dist/components/utils/iconUtils.js +40 -0
- package/dist/components/utils/index.d.ts +12 -0
- package/dist/components/utils/index.d.ts.map +1 -1
- package/dist/components/utils/index.js +6 -0
- package/dist/contexts/AppLayoutContext.d.ts +40 -0
- package/dist/contexts/AppLayoutContext.d.ts.map +1 -0
- package/dist/contexts/AppLayoutContext.js +98 -0
- package/dist/contexts/ListCrudContext.d.ts +50 -0
- package/dist/contexts/ListCrudContext.d.ts.map +1 -0
- package/dist/contexts/ListCrudContext.js +253 -0
- package/dist/contexts/SnackbarContext.d.ts +26 -0
- package/dist/contexts/SnackbarContext.d.ts.map +1 -0
- package/dist/contexts/SnackbarContext.js +34 -0
- package/dist/contexts/index.d.ts +6 -0
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/contexts/index.js +6 -0
- package/dist/contexts/presets.js +6 -6
- package/dist/docs/AccordionDocs.d.ts +4 -0
- package/dist/docs/AccordionDocs.d.ts.map +1 -0
- package/dist/docs/AccordionDocs.js +21 -0
- package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +3 -5
- package/dist/docs/AutocompleteInputDocs.js +1 -1
- package/dist/docs/AvatarDocs.d.ts +4 -0
- package/dist/docs/AvatarDocs.d.ts.map +1 -0
- package/dist/docs/AvatarDocs.js +7 -0
- package/dist/docs/BadgeDocs.d.ts.map +1 -1
- package/dist/docs/BadgeDocs.js +4 -2
- package/dist/docs/ButtonDocs.d.ts.map +1 -1
- package/dist/docs/ButtonDocs.js +1 -1
- package/dist/docs/CardDocs.d.ts.map +1 -1
- package/dist/docs/CardDocs.js +17 -8
- package/dist/docs/CheckboxDocs.d.ts +4 -0
- package/dist/docs/CheckboxDocs.d.ts.map +1 -0
- package/dist/docs/CheckboxDocs.js +7 -0
- package/dist/docs/DataTableDocs.d.ts.map +1 -1
- package/dist/docs/DataTableDocs.js +9 -5
- package/dist/docs/DateInputDocs.d.ts +1 -0
- package/dist/docs/DateInputDocs.d.ts.map +1 -1
- package/dist/docs/DateInputDocs.js +7 -9
- package/dist/docs/DatePickerDocs.d.ts +1 -0
- package/dist/docs/DatePickerDocs.d.ts.map +1 -1
- package/dist/docs/DatePickerDocs.js +6 -8
- package/dist/docs/DialogDocs.js +1 -1
- package/dist/docs/DocAdmin.d.ts +4 -0
- package/dist/docs/DocAdmin.d.ts.map +1 -0
- package/dist/docs/DocAdmin.js +68 -0
- package/dist/docs/DocsMenu.d.ts.map +1 -1
- package/dist/docs/DocsMenu.js +3 -3
- package/dist/docs/DocsRouter.d.ts.map +1 -1
- package/dist/docs/DocsRouter.js +13 -1
- package/dist/docs/DropdownMenuDocs.js +1 -1
- package/dist/docs/ExampleFormDocs.d.ts +4 -0
- package/dist/docs/ExampleFormDocs.d.ts.map +1 -0
- package/dist/docs/ExampleFormDocs.js +148 -0
- package/dist/docs/FilterDocs.d.ts +4 -0
- package/dist/docs/FilterDocs.d.ts.map +1 -0
- package/dist/docs/FilterDocs.js +112 -0
- package/dist/docs/InputDocs.d.ts.map +1 -1
- package/dist/docs/InputDocs.js +11 -1
- package/dist/docs/LinkButtonDocs.d.ts +4 -0
- package/dist/docs/LinkButtonDocs.d.ts.map +1 -0
- package/dist/docs/LinkButtonDocs.js +7 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +29 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +7 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +57 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts +9 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +30 -0
- package/dist/docs/PaginationDocs.js +6 -6
- package/dist/docs/RadioButtonGroupDocs.d.ts +4 -0
- package/dist/docs/RadioButtonGroupDocs.d.ts.map +1 -0
- package/dist/docs/RadioButtonGroupDocs.js +46 -0
- package/dist/docs/RoadMapDocs.d.ts +4 -0
- package/dist/docs/RoadMapDocs.d.ts.map +1 -0
- package/dist/docs/RoadMapDocs.js +171 -0
- package/dist/docs/SearchSelectInputDocs.d.ts +4 -0
- package/dist/docs/SearchSelectInputDocs.d.ts.map +1 -0
- package/dist/docs/SearchSelectInputDocs.js +168 -0
- package/dist/docs/SnackbarDocs.d.ts +4 -0
- package/dist/docs/SnackbarDocs.d.ts.map +1 -0
- package/dist/docs/SnackbarDocs.js +50 -0
- package/dist/docs/TabsGroupDocs.d.ts.map +1 -1
- package/dist/docs/TabsGroupDocs.js +12 -1
- package/dist/docs/docMockServices/empresaService.d.ts +38 -0
- package/dist/docs/docMockServices/empresaService.d.ts.map +1 -0
- package/dist/docs/docMockServices/empresaService.js +117 -0
- package/dist/docs/docMockServices/index.d.ts +9 -0
- package/dist/docs/docMockServices/index.d.ts.map +1 -0
- package/dist/docs/docMockServices/index.js +8 -0
- package/dist/docs/docMockServices/initialData.d.ts +6 -0
- package/dist/docs/docMockServices/initialData.d.ts.map +1 -0
- package/dist/docs/docMockServices/initialData.js +132 -0
- package/dist/docs/docMockServices/interfaces.d.ts +26 -0
- package/dist/docs/docMockServices/interfaces.d.ts.map +1 -0
- package/dist/docs/docMockServices/interfaces.js +1 -0
- package/dist/docs/docMockServices/personaEmpresaService.d.ts +43 -0
- package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +1 -0
- package/dist/docs/docMockServices/personaEmpresaService.js +113 -0
- package/dist/docs/docMockServices/personaService.d.ts +39 -0
- package/dist/docs/docMockServices/personaService.d.ts.map +1 -0
- package/dist/docs/docMockServices/personaService.js +181 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useAsyncRequest.d.ts +17 -0
- package/dist/hooks/useAsyncRequest.d.ts.map +1 -0
- package/dist/hooks/useAsyncRequest.js +70 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/templates/forms/ContactForm.js +2 -2
- package/dist/templates/forms/LoginForm.js +1 -1
- package/dist/templates/forms/RegistrationForm.js +1 -1
- package/dist/templates/layouts/SidebarLayout.d.ts.map +1 -1
- package/dist/templates/layouts/SidebarLayout.js +3 -2
- package/dist/templates/patterns/FormPattern.d.ts.map +1 -1
- package/dist/templates/patterns/FormPattern.js +4 -3
- package/package.json +5 -2
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
+
import dayjs, {} from "dayjs";
|
|
3
4
|
import { Button } from "./Button";
|
|
4
5
|
const createDateAtMidnight = (date) => {
|
|
5
|
-
const d =
|
|
6
|
-
d.
|
|
7
|
-
return d;
|
|
6
|
+
const d = dayjs(date);
|
|
7
|
+
return d.startOf("day");
|
|
8
8
|
};
|
|
9
9
|
const isSameDay = (a, b) => {
|
|
10
|
-
return
|
|
11
|
-
a.getMonth() === b.getMonth() &&
|
|
12
|
-
a.getDate() === b.getDate());
|
|
10
|
+
return a.isSame(b, "day");
|
|
13
11
|
};
|
|
14
12
|
const getDaysInMonth = (year, month) => {
|
|
15
|
-
return
|
|
13
|
+
return dayjs().year(year).month(month).daysInMonth();
|
|
16
14
|
};
|
|
17
15
|
const getWeekdayLabels = (startWeekOn) => {
|
|
18
16
|
const base = ["D", "L", "M", "X", "J", "V", "S"];
|
|
@@ -22,23 +20,19 @@ const getWeekdayLabels = (startWeekOn) => {
|
|
|
22
20
|
return [...base.slice(1), base[0]];
|
|
23
21
|
};
|
|
24
22
|
export const DatePicker = ({ value, onChange, initialViewDate, startWeekOn = "sunday", className = "", }) => {
|
|
25
|
-
const today = React.useMemo(() =>
|
|
26
|
-
const
|
|
27
|
-
const base =
|
|
23
|
+
const today = React.useMemo(() => dayjs().startOf("day"), []);
|
|
24
|
+
const getViewFromValue = React.useCallback((val) => {
|
|
25
|
+
const base = val ?? initialViewDate ?? today;
|
|
28
26
|
return {
|
|
29
|
-
month: base.
|
|
30
|
-
year: base.
|
|
27
|
+
month: base.month(),
|
|
28
|
+
year: base.year(),
|
|
31
29
|
};
|
|
32
|
-
}, [
|
|
33
|
-
const [view, setView] = React.useState(
|
|
30
|
+
}, [initialViewDate, today]);
|
|
31
|
+
const [view, setView] = React.useState(() => getViewFromValue(value));
|
|
34
32
|
React.useEffect(() => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
year: value.getFullYear(),
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
}, [value]);
|
|
33
|
+
// Sincronizar la vista con el valor actual, incluso si es null/undefined
|
|
34
|
+
setView(getViewFromValue(value));
|
|
35
|
+
}, [value, getViewFromValue]);
|
|
42
36
|
const handlePrevMonth = () => {
|
|
43
37
|
setView((prev) => {
|
|
44
38
|
const month = prev.month === 0 ? 11 : prev.month - 1;
|
|
@@ -62,7 +56,7 @@ export const DatePicker = ({ value, onChange, initialViewDate, startWeekOn = "su
|
|
|
62
56
|
const handleSelectDay = (day, month, year) => {
|
|
63
57
|
const targetMonth = month !== undefined ? month : view.month;
|
|
64
58
|
const targetYear = year !== undefined ? year : view.year;
|
|
65
|
-
const date =
|
|
59
|
+
const date = dayjs().year(targetYear).month(targetMonth).date(day);
|
|
66
60
|
onChange?.(createDateAtMidnight(date));
|
|
67
61
|
// Si el día es de otro mes, cambiar la vista
|
|
68
62
|
if (month !== undefined && month !== view.month) {
|
|
@@ -72,8 +66,8 @@ export const DatePicker = ({ value, onChange, initialViewDate, startWeekOn = "su
|
|
|
72
66
|
setView({ month: targetMonth, year: targetYear });
|
|
73
67
|
}
|
|
74
68
|
};
|
|
75
|
-
const firstDayOfMonth =
|
|
76
|
-
const firstWeekday = firstDayOfMonth.
|
|
69
|
+
const firstDayOfMonth = dayjs().year(view.year).month(view.month).date(1);
|
|
70
|
+
const firstWeekday = firstDayOfMonth.day(); // 0-6, Sunday=0
|
|
77
71
|
const daysInMonth = getDaysInMonth(view.year, view.month);
|
|
78
72
|
const weekdayLabels = getWeekdayLabels(startWeekOn);
|
|
79
73
|
const offset = startWeekOn === "sunday"
|
|
@@ -115,15 +109,17 @@ export const DatePicker = ({ value, onChange, initialViewDate, startWeekOn = "su
|
|
|
115
109
|
}
|
|
116
110
|
weeks.push(currentWeek);
|
|
117
111
|
}
|
|
118
|
-
const selectedDate = value &&
|
|
119
|
-
const monthName =
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
112
|
+
const selectedDate = value && value.isValid() ? createDateAtMidnight(value) : null;
|
|
113
|
+
const monthName = dayjs()
|
|
114
|
+
.year(view.year)
|
|
115
|
+
.month(view.month)
|
|
116
|
+
.date(1)
|
|
117
|
+
.format("MMMM");
|
|
118
|
+
return (_jsxs("div", { className: `inline-flex flex-col rounded-lg border border-[var(--color-border-default)]
|
|
123
119
|
bg-[var(--color-bg-default)] p-3 shadow-sm font-[var(--font-default)] text-sm ${className}`, children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { type: "button", size: "sm", variant: "ghost", icon: "fa-angle-double-left", onClick: handlePrevYear, "aria-label": "A\u00F1o anterior" }), _jsx(Button, { type: "button", size: "sm", variant: "ghost", icon: "fa-angle-left", onClick: handlePrevMonth, "aria-label": "Mes anterior" })] }), _jsx("div", { className: "text-center", children: _jsxs("div", { className: "text-[var(--color-text-primary)] font-medium capitalize", children: [monthName, " ", view.year] }) }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { type: "button", size: "sm", variant: "ghost", icon: "fa-angle-right", onClick: handleNextMonth, "aria-label": "Mes siguiente" }), _jsx(Button, { type: "button", size: "sm", variant: "ghost", icon: "fa-angle-double-right", onClick: handleNextYear, "aria-label": "A\u00F1o siguiente" })] })] }), _jsx("div", { className: "grid grid-cols-7 gap-1 mb-1", children: weekdayLabels.map((label) => (_jsx("div", { className: "text-xs text-center text-[var(--color-text-secondary)]", children: label }, label))) }), _jsx("div", { className: "grid grid-rows-6 gap-1", children: weeks.map((week, rowIndex) => (_jsx("div", { className: "grid grid-cols-7 gap-1", children: week.map((dayInfo, index) => {
|
|
124
120
|
const { day, month, year } = dayInfo;
|
|
125
121
|
const isCurrentMonth = month === view.month && year === view.year;
|
|
126
|
-
const date =
|
|
122
|
+
const date = dayjs().year(year).month(month).date(day);
|
|
127
123
|
const isToday = isSameDay(date, today);
|
|
128
124
|
const isSelected = selectedDate !== null && isSameDay(date, selectedDate);
|
|
129
125
|
let dayClasses = "w-8 h-8 flex items-center justify-center rounded-full cursor-pointer text-xs";
|
|
@@ -6,6 +6,15 @@ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElem
|
|
|
6
6
|
iconPosition?: "left" | "right";
|
|
7
7
|
size?: "sm" | "md" | "lg";
|
|
8
8
|
children?: React.ReactNode;
|
|
9
|
+
/**
|
|
10
|
+
* Callback cuando se hace click en el ícono. Si está definido, el ícono será clickeable.
|
|
11
|
+
*/
|
|
12
|
+
onIconClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Si es true, el input será de solo lectura. No se podrá modificar pero no se verá como disabled.
|
|
15
|
+
* Por defecto es false.
|
|
16
|
+
*/
|
|
17
|
+
readOnly?: boolean;
|
|
9
18
|
}
|
|
10
|
-
export declare const Input: React.
|
|
19
|
+
export declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
11
20
|
//# sourceMappingURL=Input.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC7D;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,KAAK,qFA4FjB,CAAC"}
|
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
|
|
3
|
+
import { normalizeIconClass } from "../utils/iconUtils";
|
|
4
|
+
export const Input = React.forwardRef(({ label, error, icon, iconPosition = "left", size = "md", className = "", id, onIconClick, readOnly = false, ...props }, ref) => {
|
|
4
5
|
const inputId = id || `input-${Math.random().toString(36).substr(2, 9)}`;
|
|
5
6
|
const baseClasses = `
|
|
6
|
-
w-full border rounded-lg transition-colors focus:outline-none
|
|
7
|
+
w-full border rounded-lg transition-colors focus:outline-none
|
|
7
8
|
disabled:opacity-50 disabled:cursor-not-allowed
|
|
8
9
|
font-[var(--font-default)] text-[var(--color-text-primary)]
|
|
9
|
-
bg-[var(--color-bg-default)]
|
|
10
10
|
`;
|
|
11
|
+
const readOnlyClasses = readOnly
|
|
12
|
+
? `border-transparent bg-transparent focus:ring-0`
|
|
13
|
+
: `focus:ring-1 bg-[var(--color-bg-default)]`;
|
|
11
14
|
const sizeClasses = {
|
|
12
15
|
sm: "px-3 py-1.5 text-sm",
|
|
13
16
|
md: "px-4 py-2 text-base",
|
|
14
17
|
lg: "px-6 py-3 text-lg",
|
|
15
18
|
};
|
|
16
|
-
const stateClasses =
|
|
17
|
-
?
|
|
18
|
-
:
|
|
19
|
-
|
|
19
|
+
const stateClasses = readOnly
|
|
20
|
+
? ""
|
|
21
|
+
: error
|
|
22
|
+
? `border-[var(--color-border-error)] focus:border-[var(--color-border-error)] focus:ring-[var(--color-border-error)]`
|
|
23
|
+
: `border-[var(--color-border-default)] focus:border-[var(--color-border-focus)] focus:ring-[var(--color-border-focus)]`;
|
|
24
|
+
const inputClasses = `${baseClasses} ${readOnlyClasses} ${sizeClasses[size]} ${stateClasses} ${className}`;
|
|
20
25
|
const iconClasses = size === "sm" ? "w-4 h-4" : size === "md" ? "w-5 h-5" : "w-6 h-6";
|
|
21
26
|
const renderIcon = () => {
|
|
22
27
|
if (!icon)
|
|
23
28
|
return null;
|
|
24
|
-
|
|
29
|
+
const iconElement = (_jsx("i", { className: `${normalizeIconClass(icon)} ${iconClasses} text-[var(--color-text-muted)] absolute top-1/2 transform -translate-y-1/2 ${iconPosition === "left" ? "left-3" : "right-3"} ${onIconClick && !readOnly ? "cursor-pointer hover:text-[var(--color-primary)] transition-colors" : ""}`, onClick: readOnly ? undefined : onIconClick }));
|
|
30
|
+
return iconElement;
|
|
25
31
|
};
|
|
26
|
-
return (_jsxs("div", { className: "w-full", children: [label && (_jsx("label", { htmlFor: inputId, className: "block text-sm text-[var(--color-primary)] mb-1 font-[var(--font-default)]", children: label })), _jsxs("div", { className: "relative", children: [icon && iconPosition === "left" && renderIcon(), _jsx("input", { id: inputId, className: `${inputClasses} ${icon && iconPosition === "left" ? "pl-10" : ""} ${icon && iconPosition === "right" ? "pr-10" : ""}`, ...props }), icon && iconPosition === "right" && renderIcon()] }), error && (_jsx("p", { className: "mt-1 text-sm text-[var(--color-danger)] font-[var(--font-default)]", children: error }))] }));
|
|
27
|
-
};
|
|
32
|
+
return (_jsxs("div", { className: "w-full", children: [label && (_jsx("label", { htmlFor: inputId, className: "block text-sm text-[var(--color-primary)] mb-1 font-[var(--font-default)]", children: label })), _jsxs("div", { className: "relative", children: [icon && iconPosition === "left" && renderIcon(), _jsx("input", { ref: ref, id: inputId, className: `${inputClasses} ${icon && iconPosition === "left" ? "pl-10" : ""} ${icon && iconPosition === "right" ? "pr-10" : ""}`, autoComplete: "off", readOnly: readOnly, ...props }), icon && iconPosition === "right" && renderIcon()] }), error && (_jsx("p", { className: "mt-1 text-sm text-[var(--color-danger)] font-[var(--font-default)]", children: error }))] }));
|
|
33
|
+
});
|
|
34
|
+
Input.displayName = "Input";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface LinkButtonProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "href"> {
|
|
3
|
+
to: string;
|
|
4
|
+
target?: string;
|
|
5
|
+
variant?: "primary" | "outline" | "ghost";
|
|
6
|
+
size?: "sm" | "md" | "lg";
|
|
7
|
+
color?: "primary" | "secondary" | "success" | "warning" | "danger" | "info";
|
|
8
|
+
bg?: string;
|
|
9
|
+
textColor?: string;
|
|
10
|
+
icon?: string;
|
|
11
|
+
iconPosition?: "left" | "right";
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
}
|
|
14
|
+
export declare const LinkButton: React.FC<LinkButtonProps>;
|
|
15
|
+
//# sourceMappingURL=LinkButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkButton.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/LinkButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAmC1B,MAAM,WAAW,eACf,SAAQ,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1C,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AASD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAgThD,CAAC"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Link } from "react-router-dom";
|
|
4
|
+
import { normalizeIconClass } from "../utils/iconUtils";
|
|
5
|
+
// Función helper para convertir nombres de colores comunes a valores CSS válidos
|
|
6
|
+
const getColorValue = (color) => {
|
|
7
|
+
if (!color)
|
|
8
|
+
return undefined;
|
|
9
|
+
// Si ya es un valor CSS válido (hex, rgb, rgba, hsl, etc.), retornarlo
|
|
10
|
+
if (color.startsWith("#") ||
|
|
11
|
+
color.startsWith("rgb") ||
|
|
12
|
+
color.startsWith("hsl")) {
|
|
13
|
+
return color;
|
|
14
|
+
}
|
|
15
|
+
// Mapeo de nombres de colores comunes
|
|
16
|
+
const colorMap = {
|
|
17
|
+
white: "#ffffff",
|
|
18
|
+
black: "#000000",
|
|
19
|
+
"gray-800": "#1f2937",
|
|
20
|
+
"gray-700": "#374151",
|
|
21
|
+
"gray-600": "#4b5563",
|
|
22
|
+
"gray-500": "#6b7280",
|
|
23
|
+
"gray-400": "#9ca3af",
|
|
24
|
+
"gray-300": "#d1d5db",
|
|
25
|
+
"gray-200": "#e5e7eb",
|
|
26
|
+
"gray-100": "#f3f4f6",
|
|
27
|
+
"gray-50": "#f9fafb",
|
|
28
|
+
};
|
|
29
|
+
return colorMap[color.toLowerCase()] || color;
|
|
30
|
+
};
|
|
31
|
+
export const LinkButton = ({ to, target, variant = "primary", size = "md", color = "primary", bg, textColor, icon, iconPosition = "left", children, className = "", onClick, ...props }) => {
|
|
32
|
+
const [ripples, setRipples] = React.useState([]);
|
|
33
|
+
const baseClasses = `
|
|
34
|
+
inline-flex items-center justify-center font-medium rounded-sm transition-colors
|
|
35
|
+
cursor-pointer relative overflow-hidden no-underline outline-none focus:outline-none
|
|
36
|
+
focus-visible:outline-none active:outline-none focus:ring-0 focus:ring-offset-0
|
|
37
|
+
font-[var(--font-default)]
|
|
38
|
+
`;
|
|
39
|
+
// Mapeo de clases para variant primary con color primary (usa Tailwind)
|
|
40
|
+
const getVariantClasses = (variantType, colorType) => {
|
|
41
|
+
// Solo usar clases Tailwind para primary con color primary
|
|
42
|
+
if (colorType === "primary") {
|
|
43
|
+
if (variantType === "primary") {
|
|
44
|
+
return `
|
|
45
|
+
bg-[var(--color-primary)] text-[var(--color-primary-contrast)]
|
|
46
|
+
hover:bg-[var(--color-primary-dark)]
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
49
|
+
else if (variantType === "outline") {
|
|
50
|
+
return `
|
|
51
|
+
border border-[var(--color-primary)] text-[var(--color-primary)]
|
|
52
|
+
hover:bg-[var(--color-bg-secondary)]
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return `
|
|
57
|
+
text-[var(--color-primary)] hover:bg-[var(--color-bg-secondary)]
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Para otros colores, retornar clases base sin color (se aplicarán con estilos inline)
|
|
62
|
+
if (variantType === "primary") {
|
|
63
|
+
return ``;
|
|
64
|
+
}
|
|
65
|
+
else if (variantType === "outline") {
|
|
66
|
+
return `border hover:bg-[var(--color-bg-secondary)]`;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return `hover:bg-[var(--color-bg-secondary)]`;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
// Si se proporciona bg personalizado, no usar las clases de variante
|
|
73
|
+
const variantClasses = bg ? "" : getVariantClasses(variant, color);
|
|
74
|
+
// Determinar si necesitamos usar estilos inline para colores del sistema
|
|
75
|
+
const needsInlineStyles = !bg && color !== "primary";
|
|
76
|
+
const sizeClasses = {
|
|
77
|
+
sm: `${children ? "px-3 py-1.5" : "p-1.5"} text-sm`,
|
|
78
|
+
md: `${children ? "px-4 py-2" : "p-2"} text-base`,
|
|
79
|
+
lg: `${children ? "px-6 py-3" : "p-3"} text-lg`,
|
|
80
|
+
};
|
|
81
|
+
// Clases adicionales para variant outline cuando hay bg personalizado
|
|
82
|
+
const outlineClasses = bg && variant === "outline" ? "border" : "";
|
|
83
|
+
const classes = `${baseClasses} ${variantClasses} ${sizeClasses[size]} ${outlineClasses} ${className}`;
|
|
84
|
+
// Función para obtener el valor de una variable CSS
|
|
85
|
+
const getCSSVariable = (varName) => {
|
|
86
|
+
if (typeof window !== "undefined") {
|
|
87
|
+
const value = getComputedStyle(document.documentElement)
|
|
88
|
+
.getPropertyValue(varName)
|
|
89
|
+
.trim();
|
|
90
|
+
// Si no se encuentra la variable, intentar con el prefijo flysoft
|
|
91
|
+
if (!value && varName.startsWith("--color-")) {
|
|
92
|
+
const flysoftVarName = varName.replace("--color-", "--flysoft-");
|
|
93
|
+
return (getComputedStyle(document.documentElement)
|
|
94
|
+
.getPropertyValue(flysoftVarName)
|
|
95
|
+
.trim() || value);
|
|
96
|
+
}
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
return "";
|
|
100
|
+
};
|
|
101
|
+
// Estilos inline para colores personalizados o colores del sistema (no primary)
|
|
102
|
+
const inlineStyles = bg
|
|
103
|
+
? {
|
|
104
|
+
backgroundColor: variant === "primary" ? getColorValue(bg) || bg : undefined,
|
|
105
|
+
color: getColorValue(textColor) ||
|
|
106
|
+
textColor ||
|
|
107
|
+
(variant === "primary" ? "#ffffff" : getColorValue(bg) || bg),
|
|
108
|
+
borderColor: variant === "outline" ? getColorValue(bg) || bg : undefined,
|
|
109
|
+
...(variant === "ghost" && {
|
|
110
|
+
color: getColorValue(textColor) || textColor || getColorValue(bg) || bg,
|
|
111
|
+
}),
|
|
112
|
+
}
|
|
113
|
+
: needsInlineStyles
|
|
114
|
+
? {
|
|
115
|
+
...(variant === "primary" && {
|
|
116
|
+
backgroundColor: getCSSVariable(`--color-${color}`),
|
|
117
|
+
color: getCSSVariable(`--color-${color}-contrast`) || "#ffffff",
|
|
118
|
+
}),
|
|
119
|
+
...(variant === "outline" && {
|
|
120
|
+
borderColor: getCSSVariable(`--color-${color}`),
|
|
121
|
+
color: getCSSVariable(`--color-${color}`),
|
|
122
|
+
}),
|
|
123
|
+
...(variant === "ghost" && {
|
|
124
|
+
color: getCSSVariable(`--color-${color}`),
|
|
125
|
+
}),
|
|
126
|
+
}
|
|
127
|
+
: {};
|
|
128
|
+
// Función para oscurecer un color (para hover en variant primary con bg personalizado)
|
|
129
|
+
const darkenColor = (color, percent) => {
|
|
130
|
+
const hex = color.replace("#", "");
|
|
131
|
+
const num = parseInt(hex, 16);
|
|
132
|
+
const r = Math.max(0, Math.floor((num >> 16) * (1 - percent / 100)));
|
|
133
|
+
const g = Math.max(0, Math.floor(((num >> 8) & 0x00ff) * (1 - percent / 100)));
|
|
134
|
+
const b = Math.max(0, Math.floor((num & 0x0000ff) * (1 - percent / 100)));
|
|
135
|
+
return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, "0")}`;
|
|
136
|
+
};
|
|
137
|
+
const renderIcon = () => {
|
|
138
|
+
if (!icon)
|
|
139
|
+
return null;
|
|
140
|
+
const iconClasses = size === "sm" ? "w-4 h-4" : size === "md" ? "w-5 h-5" : "w-6 h-6";
|
|
141
|
+
return (_jsx("i", { className: `${normalizeIconClass(icon)} ${iconClasses} ${children ? (iconPosition === "right" ? "ml-2" : "mr-2") : ""} mt-0.5` }));
|
|
142
|
+
};
|
|
143
|
+
// Determinar el color del ripple basado en el variant y si hay bg personalizado
|
|
144
|
+
const rippleColor = bg
|
|
145
|
+
? variant === "primary"
|
|
146
|
+
? "rgba(255, 255, 255, 0.45)"
|
|
147
|
+
: "rgba(0, 0, 0, 0.15)"
|
|
148
|
+
: variant === "primary"
|
|
149
|
+
? "rgba(255, 255, 255, 0.45)"
|
|
150
|
+
: "rgba(0, 0, 0, 0.15)";
|
|
151
|
+
const handleClick = (event) => {
|
|
152
|
+
const targetElement = event.currentTarget;
|
|
153
|
+
if (targetElement) {
|
|
154
|
+
const rect = targetElement.getBoundingClientRect();
|
|
155
|
+
const size = Math.max(rect.width, rect.height) * 1.2;
|
|
156
|
+
const x = event.clientX - rect.left;
|
|
157
|
+
const y = event.clientY - rect.top;
|
|
158
|
+
const id = window.performance.now();
|
|
159
|
+
const newRipple = { id, x, y, size };
|
|
160
|
+
setRipples((prev) => [...prev, newRipple]);
|
|
161
|
+
window.setTimeout(() => {
|
|
162
|
+
setRipples((prev) => prev.filter((ripple) => ripple.id !== id));
|
|
163
|
+
}, 600);
|
|
164
|
+
}
|
|
165
|
+
onClick?.(event);
|
|
166
|
+
};
|
|
167
|
+
// Determinar si es una ruta externa (http/https) o interna
|
|
168
|
+
const isExternal = to.startsWith("http://") || to.startsWith("https://") || to.startsWith("mailto:") || to.startsWith("tel:");
|
|
169
|
+
// Combinar estilos inline - agregar outline: none para asegurar que no aparezca
|
|
170
|
+
const combinedStyles = {
|
|
171
|
+
...inlineStyles,
|
|
172
|
+
outline: "none",
|
|
173
|
+
outlineWidth: "0",
|
|
174
|
+
outlineStyle: "none",
|
|
175
|
+
outlineOffset: "0",
|
|
176
|
+
WebkitTapHighlightColor: "transparent",
|
|
177
|
+
boxShadow: "none",
|
|
178
|
+
};
|
|
179
|
+
const linkProps = {
|
|
180
|
+
className: classes,
|
|
181
|
+
style: combinedStyles,
|
|
182
|
+
onClick: handleClick,
|
|
183
|
+
onFocus: (e) => {
|
|
184
|
+
e.currentTarget.style.outline = "none";
|
|
185
|
+
e.currentTarget.style.outlineWidth = "0";
|
|
186
|
+
e.currentTarget.style.outlineStyle = "none";
|
|
187
|
+
e.currentTarget.style.outlineOffset = "0";
|
|
188
|
+
e.currentTarget.style.boxShadow = "none";
|
|
189
|
+
},
|
|
190
|
+
onBlur: (e) => {
|
|
191
|
+
e.currentTarget.style.outline = "none";
|
|
192
|
+
e.currentTarget.style.outlineWidth = "0";
|
|
193
|
+
e.currentTarget.style.outlineStyle = "none";
|
|
194
|
+
e.currentTarget.style.outlineOffset = "0";
|
|
195
|
+
e.currentTarget.style.boxShadow = "none";
|
|
196
|
+
},
|
|
197
|
+
onKeyDown: (e) => {
|
|
198
|
+
// Eliminar outline cuando se presiona cualquier tecla
|
|
199
|
+
if (e.key === "Tab" || e.key === "Enter" || e.key === " ") {
|
|
200
|
+
e.currentTarget.style.outline = "none";
|
|
201
|
+
e.currentTarget.style.outlineWidth = "0";
|
|
202
|
+
e.currentTarget.style.outlineStyle = "none";
|
|
203
|
+
e.currentTarget.style.outlineOffset = "0";
|
|
204
|
+
e.currentTarget.style.boxShadow = "none";
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
onMouseEnter: (e) => {
|
|
208
|
+
if (variant === "primary") {
|
|
209
|
+
if (bg) {
|
|
210
|
+
const hoverBg = darkenColor(getColorValue(bg) || bg, 15);
|
|
211
|
+
e.currentTarget.style.backgroundColor = hoverBg;
|
|
212
|
+
}
|
|
213
|
+
else if (needsInlineStyles) {
|
|
214
|
+
const hoverBg = getCSSVariable(`--color-${color}-dark`);
|
|
215
|
+
e.currentTarget.style.backgroundColor = hoverBg;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
onMouseLeave: (e) => {
|
|
220
|
+
if (variant === "primary") {
|
|
221
|
+
if (bg) {
|
|
222
|
+
e.currentTarget.style.backgroundColor = getColorValue(bg) || bg;
|
|
223
|
+
}
|
|
224
|
+
else if (needsInlineStyles) {
|
|
225
|
+
e.currentTarget.style.backgroundColor = getCSSVariable(`--color-${color}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
...props,
|
|
230
|
+
};
|
|
231
|
+
if (isExternal) {
|
|
232
|
+
const externalTarget = target || "_blank";
|
|
233
|
+
return (_jsxs("a", { href: to, target: externalTarget, rel: externalTarget === "_blank" ? "noopener noreferrer" : undefined, ...linkProps, children: [_jsx("span", { className: "absolute inset-0 pointer-events-none", children: ripples.map((ripple) => (_jsx("span", { className: "absolute rounded-full opacity-40 flysoft-button-ripple", style: {
|
|
234
|
+
top: ripple.y,
|
|
235
|
+
left: ripple.x,
|
|
236
|
+
width: ripple.size,
|
|
237
|
+
height: ripple.size,
|
|
238
|
+
backgroundColor: rippleColor,
|
|
239
|
+
} }, ripple.id))) }), _jsxs("span", { className: "relative inline-flex items-center justify-center", children: [icon && iconPosition === "left" && renderIcon(), children, icon && iconPosition === "right" && renderIcon()] })] }));
|
|
240
|
+
}
|
|
241
|
+
return (_jsxs(Link, { to: to, ...linkProps, children: [_jsx("span", { className: "absolute inset-0 pointer-events-none", children: ripples.map((ripple) => (_jsx("span", { className: "absolute rounded-full opacity-40 flysoft-button-ripple", style: {
|
|
242
|
+
top: ripple.y,
|
|
243
|
+
left: ripple.x,
|
|
244
|
+
width: ripple.size,
|
|
245
|
+
height: ripple.size,
|
|
246
|
+
backgroundColor: rippleColor,
|
|
247
|
+
} }, ripple.id))) }), _jsxs("span", { className: "relative inline-flex items-center justify-center", children: [icon && iconPosition === "left" && renderIcon(), children, icon && iconPosition === "right" && renderIcon()] })] }));
|
|
248
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/Pagination.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/Pagination.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA0FhD,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { useSearchParams } from "react-router-dom";
|
|
4
4
|
import { Button } from "./Button";
|
|
5
|
-
export const Pagination = ({ fieldName = "pagina", page = 1, pages = 1, total = 0, }) => {
|
|
5
|
+
export const Pagination = ({ fieldName = "pagina", page = 1, pages = 1, total = 0, isLoading = false, }) => {
|
|
6
6
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
7
7
|
const navigateToPage = (newPage) => {
|
|
8
8
|
if (newPage < 1 || newPage > pages || newPage === page) {
|
|
@@ -19,42 +19,5 @@ export const Pagination = ({ fieldName = "pagina", page = 1, pages = 1, total =
|
|
|
19
19
|
const isFirstPage = page <= 1;
|
|
20
20
|
const isLastPage = page >= pages;
|
|
21
21
|
const hasPages = pages > 1;
|
|
22
|
-
return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { children: _jsx(Button, { variant: "ghost", size: "sm", icon: "fa-angle-double-left", onClick: goToFirstPage, disabled: isFirstPage || !hasPages, "aria-label": "Primera p\u00E1gina" }) }), _jsx("div", { children: _jsx(Button, { variant: "ghost", size: "sm", icon: "fa-angle-left", onClick: goToPreviousPage, disabled: isFirstPage || !hasPages, "aria-label": "P\u00E1gina anterior" }) }),
|
|
23
|
-
// <div className="flex flex-col items-center gap-0 font-[var(--font-default)]">
|
|
24
|
-
// {/* Botones de navegación */}
|
|
25
|
-
// <div className="flex items-center gap-2">
|
|
26
|
-
//
|
|
27
|
-
// {/* Texto de página */}
|
|
28
|
-
// <span
|
|
29
|
-
// className="text-xs px-3 leading-none"
|
|
30
|
-
// style={{ color: "var(--color-text-primary)" }}
|
|
31
|
-
// >
|
|
32
|
-
// Página {page} de {pages}
|
|
33
|
-
// </span>
|
|
34
|
-
// <Button
|
|
35
|
-
// variant="ghost"
|
|
36
|
-
// size="sm"
|
|
37
|
-
// icon="fa-angle-right"
|
|
38
|
-
// onClick={goToNextPage}
|
|
39
|
-
// disabled={isLastPage || !hasPages}
|
|
40
|
-
// aria-label="Página siguiente"
|
|
41
|
-
// />
|
|
42
|
-
// <Button
|
|
43
|
-
// variant="ghost"
|
|
44
|
-
// size="sm"
|
|
45
|
-
// icon="fa-angle-double-right"
|
|
46
|
-
// onClick={goToLastPage}
|
|
47
|
-
// disabled={isLastPage || !hasPages}
|
|
48
|
-
// aria-label="Última página"
|
|
49
|
-
// />
|
|
50
|
-
// </div>
|
|
51
|
-
// {/* Texto de elementos */}
|
|
52
|
-
// <span
|
|
53
|
-
// className="text-xs leading-none"
|
|
54
|
-
// style={{ color: "var(--color-text-secondary)" }}
|
|
55
|
-
// >
|
|
56
|
-
// {total} elemento{total !== 1 ? "s" : ""}
|
|
57
|
-
// </span>
|
|
58
|
-
// </div>
|
|
59
|
-
);
|
|
22
|
+
return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { children: _jsx(Button, { variant: "ghost", size: "sm", icon: "fa-angle-double-left", onClick: goToFirstPage, disabled: isFirstPage || !hasPages || isLoading, "aria-label": "Primera p\u00E1gina" }) }), _jsx("div", { children: _jsx(Button, { variant: "ghost", size: "sm", icon: "fa-angle-left", onClick: goToPreviousPage, disabled: isFirstPage || !hasPages || isLoading, "aria-label": "P\u00E1gina anterior" }) }), _jsx("div", { className: `text-xs h-[32px] min-w-[100px] text-center flex flex-col justify-center`, children: isLoading ? (_jsx(_Fragment, { children: _jsx("span", { className: "block", children: "Cargando..." }) })) : (_jsxs(_Fragment, { children: [_jsxs("span", { className: "block", children: ["P\u00E1gina ", page, " de ", pages] }), _jsxs("span", { className: "block", children: [total, " elemento", total !== 1 ? "s" : ""] })] })) }), _jsx("div", { children: _jsx(Button, { variant: "ghost", size: "sm", icon: "fa-angle-right", onClick: goToNextPage, disabled: isLastPage || !hasPages || isLoading, "aria-label": "P\u00E1gina siguiente" }) }), _jsx("div", { children: _jsx(Button, { variant: "ghost", size: "sm", icon: "fa-angle-double-right", onClick: goToLastPage, disabled: isLastPage || !hasPages || isLoading, "aria-label": "\u00DAltima p\u00E1gina" }) })] }));
|
|
60
23
|
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface RadioOption {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string | number;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface RadioButtonGroupProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "children"> {
|
|
8
|
+
/**
|
|
9
|
+
* Array de opciones para renderizar radios automáticamente
|
|
10
|
+
*/
|
|
11
|
+
options: RadioOption[];
|
|
12
|
+
/**
|
|
13
|
+
* Valor seleccionado (controlado)
|
|
14
|
+
*/
|
|
15
|
+
value?: string | number;
|
|
16
|
+
/**
|
|
17
|
+
* Callback cuando cambia la selección
|
|
18
|
+
* Puede recibir un valor directo o un evento (para compatibilidad con react-hook-form)
|
|
19
|
+
*/
|
|
20
|
+
onChange?: ((value: string | number) => void) | React.ChangeEventHandler<HTMLInputElement>;
|
|
21
|
+
/**
|
|
22
|
+
* Posición del label para todas las opciones
|
|
23
|
+
*/
|
|
24
|
+
labelPosition?: "left" | "right";
|
|
25
|
+
/**
|
|
26
|
+
* Tamaño de los radio buttons
|
|
27
|
+
*/
|
|
28
|
+
size?: "sm" | "md" | "lg";
|
|
29
|
+
/**
|
|
30
|
+
* Mensaje de error a mostrar
|
|
31
|
+
*/
|
|
32
|
+
error?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Dirección del layout: vertical (columna) o horizontal (fila)
|
|
35
|
+
*/
|
|
36
|
+
direction?: "vertical" | "horizontal";
|
|
37
|
+
/**
|
|
38
|
+
* Espaciado entre opciones
|
|
39
|
+
*/
|
|
40
|
+
gap?: "sm" | "md" | "lg";
|
|
41
|
+
/**
|
|
42
|
+
* Nombre del campo (para react-hook-form)
|
|
43
|
+
*/
|
|
44
|
+
name?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Estado deshabilitado
|
|
47
|
+
*/
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Callback cuando pierde el foco
|
|
51
|
+
* Puede recibir un evento (para compatibilidad con react-hook-form) o ser una función sin parámetros
|
|
52
|
+
*/
|
|
53
|
+
onBlur?: (() => void) | React.FocusEventHandler<HTMLInputElement>;
|
|
54
|
+
/**
|
|
55
|
+
* Si es true, el radio group será de solo lectura. Las opciones no seleccionadas se verán deshabilitadas
|
|
56
|
+
* y la seleccionada se verá igual, pero no se podrá cambiar el valor.
|
|
57
|
+
* Por defecto es false.
|
|
58
|
+
*/
|
|
59
|
+
readOnly?: boolean;
|
|
60
|
+
}
|
|
61
|
+
export declare const RadioButtonGroup: React.ForwardRefExoticComponent<RadioButtonGroupProps & React.RefAttributes<HTMLInputElement>>;
|
|
62
|
+
//# sourceMappingURL=RadioButtonGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioButtonGroup.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/RadioButtonGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAC3E;;OAEG;IACH,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,EACL,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC,GAClC,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IAC/C;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC;;OAEG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,SAAS,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACtC;;OAEG;IACH,GAAG,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IAClE;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,gBAAgB,gGAmV5B,CAAC"}
|