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.
Files changed (206) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/App.js +19 -7
  3. package/dist/components/form-controls/AutocompleteInput.d.ts +11 -3
  4. package/dist/components/form-controls/AutocompleteInput.d.ts.map +1 -1
  5. package/dist/components/form-controls/AutocompleteInput.js +411 -31
  6. package/dist/components/form-controls/Button.d.ts +3 -0
  7. package/dist/components/form-controls/Button.d.ts.map +1 -1
  8. package/dist/components/form-controls/Button.js +160 -19
  9. package/dist/components/form-controls/Checkbox.d.ts +14 -0
  10. package/dist/components/form-controls/Checkbox.d.ts.map +1 -0
  11. package/dist/components/form-controls/Checkbox.js +79 -0
  12. package/dist/components/form-controls/DateInput.d.ts +24 -4
  13. package/dist/components/form-controls/DateInput.d.ts.map +1 -1
  14. package/dist/components/form-controls/DateInput.js +492 -70
  15. package/dist/components/form-controls/DatePicker.d.ts +4 -3
  16. package/dist/components/form-controls/DatePicker.d.ts.map +1 -1
  17. package/dist/components/form-controls/DatePicker.js +26 -30
  18. package/dist/components/form-controls/Input.d.ts +10 -1
  19. package/dist/components/form-controls/Input.d.ts.map +1 -1
  20. package/dist/components/form-controls/Input.js +17 -10
  21. package/dist/components/form-controls/LinkButton.d.ts +15 -0
  22. package/dist/components/form-controls/LinkButton.d.ts.map +1 -0
  23. package/dist/components/form-controls/LinkButton.js +248 -0
  24. package/dist/components/form-controls/Pagination.d.ts +1 -0
  25. package/dist/components/form-controls/Pagination.d.ts.map +1 -1
  26. package/dist/components/form-controls/Pagination.js +3 -40
  27. package/dist/components/form-controls/RadioButtonGroup.d.ts +62 -0
  28. package/dist/components/form-controls/RadioButtonGroup.d.ts.map +1 -0
  29. package/dist/components/form-controls/RadioButtonGroup.js +220 -0
  30. package/dist/components/form-controls/SearchSelectInput-OLD.d.ts +68 -0
  31. package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +1 -0
  32. package/dist/components/form-controls/SearchSelectInput-OLD.js +963 -0
  33. package/dist/components/form-controls/SearchSelectInput.d.ts +70 -0
  34. package/dist/components/form-controls/SearchSelectInput.d.ts.map +1 -0
  35. package/dist/components/form-controls/SearchSelectInput.js +336 -0
  36. package/dist/components/form-controls/index.d.ts +9 -1
  37. package/dist/components/form-controls/index.d.ts.map +1 -1
  38. package/dist/components/form-controls/index.js +4 -0
  39. package/dist/components/layout/Accordion.d.ts +13 -0
  40. package/dist/components/layout/Accordion.d.ts.map +1 -0
  41. package/dist/components/layout/Accordion.js +67 -0
  42. package/dist/components/layout/AppLayout.d.ts +3 -2
  43. package/dist/components/layout/AppLayout.d.ts.map +1 -1
  44. package/dist/components/layout/AppLayout.js +104 -31
  45. package/dist/components/layout/Card.d.ts +8 -3
  46. package/dist/components/layout/Card.d.ts.map +1 -1
  47. package/dist/components/layout/Card.js +18 -19
  48. package/dist/components/layout/Collection.js +1 -1
  49. package/dist/components/layout/DataTable.d.ts +3 -1
  50. package/dist/components/layout/DataTable.d.ts.map +1 -1
  51. package/dist/components/layout/DataTable.js +34 -29
  52. package/dist/components/layout/index.d.ts +2 -0
  53. package/dist/components/layout/index.d.ts.map +1 -1
  54. package/dist/components/layout/index.js +1 -0
  55. package/dist/components/utils/Avatar.d.ts +49 -0
  56. package/dist/components/utils/Avatar.d.ts.map +1 -0
  57. package/dist/components/utils/Avatar.js +93 -0
  58. package/dist/components/utils/Badge.d.ts +3 -0
  59. package/dist/components/utils/Badge.d.ts.map +1 -1
  60. package/dist/components/utils/Badge.js +131 -26
  61. package/dist/components/utils/Dialog.d.ts.map +1 -1
  62. package/dist/components/utils/Dialog.js +6 -1
  63. package/dist/components/utils/Filter.d.ts +57 -0
  64. package/dist/components/utils/Filter.d.ts.map +1 -0
  65. package/dist/components/utils/Filter.js +581 -0
  66. package/dist/components/utils/FiltersDialog.d.ts +21 -0
  67. package/dist/components/utils/FiltersDialog.d.ts.map +1 -0
  68. package/dist/components/utils/FiltersDialog.js +104 -0
  69. package/dist/components/utils/Loader.js +2 -2
  70. package/dist/components/utils/RoadMap.d.ts +59 -0
  71. package/dist/components/utils/RoadMap.d.ts.map +1 -0
  72. package/dist/components/utils/RoadMap.js +139 -0
  73. package/dist/components/utils/Snackbar.d.ts +13 -0
  74. package/dist/components/utils/Snackbar.d.ts.map +1 -0
  75. package/dist/components/utils/Snackbar.js +122 -0
  76. package/dist/components/utils/SnackbarContainer.d.ts +7 -0
  77. package/dist/components/utils/SnackbarContainer.d.ts.map +1 -0
  78. package/dist/components/utils/SnackbarContainer.js +25 -0
  79. package/dist/components/utils/iconUtils.d.ts +16 -0
  80. package/dist/components/utils/iconUtils.d.ts.map +1 -0
  81. package/dist/components/utils/iconUtils.js +40 -0
  82. package/dist/components/utils/index.d.ts +12 -0
  83. package/dist/components/utils/index.d.ts.map +1 -1
  84. package/dist/components/utils/index.js +6 -0
  85. package/dist/contexts/AppLayoutContext.d.ts +40 -0
  86. package/dist/contexts/AppLayoutContext.d.ts.map +1 -0
  87. package/dist/contexts/AppLayoutContext.js +98 -0
  88. package/dist/contexts/ListCrudContext.d.ts +50 -0
  89. package/dist/contexts/ListCrudContext.d.ts.map +1 -0
  90. package/dist/contexts/ListCrudContext.js +253 -0
  91. package/dist/contexts/SnackbarContext.d.ts +26 -0
  92. package/dist/contexts/SnackbarContext.d.ts.map +1 -0
  93. package/dist/contexts/SnackbarContext.js +34 -0
  94. package/dist/contexts/index.d.ts +6 -0
  95. package/dist/contexts/index.d.ts.map +1 -1
  96. package/dist/contexts/index.js +6 -0
  97. package/dist/contexts/presets.js +6 -6
  98. package/dist/docs/AccordionDocs.d.ts +4 -0
  99. package/dist/docs/AccordionDocs.d.ts.map +1 -0
  100. package/dist/docs/AccordionDocs.js +21 -0
  101. package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +3 -5
  102. package/dist/docs/AutocompleteInputDocs.js +1 -1
  103. package/dist/docs/AvatarDocs.d.ts +4 -0
  104. package/dist/docs/AvatarDocs.d.ts.map +1 -0
  105. package/dist/docs/AvatarDocs.js +7 -0
  106. package/dist/docs/BadgeDocs.d.ts.map +1 -1
  107. package/dist/docs/BadgeDocs.js +4 -2
  108. package/dist/docs/ButtonDocs.d.ts.map +1 -1
  109. package/dist/docs/ButtonDocs.js +1 -1
  110. package/dist/docs/CardDocs.d.ts.map +1 -1
  111. package/dist/docs/CardDocs.js +17 -8
  112. package/dist/docs/CheckboxDocs.d.ts +4 -0
  113. package/dist/docs/CheckboxDocs.d.ts.map +1 -0
  114. package/dist/docs/CheckboxDocs.js +7 -0
  115. package/dist/docs/DataTableDocs.d.ts.map +1 -1
  116. package/dist/docs/DataTableDocs.js +9 -5
  117. package/dist/docs/DateInputDocs.d.ts +1 -0
  118. package/dist/docs/DateInputDocs.d.ts.map +1 -1
  119. package/dist/docs/DateInputDocs.js +7 -9
  120. package/dist/docs/DatePickerDocs.d.ts +1 -0
  121. package/dist/docs/DatePickerDocs.d.ts.map +1 -1
  122. package/dist/docs/DatePickerDocs.js +6 -8
  123. package/dist/docs/DialogDocs.js +1 -1
  124. package/dist/docs/DocAdmin.d.ts +4 -0
  125. package/dist/docs/DocAdmin.d.ts.map +1 -0
  126. package/dist/docs/DocAdmin.js +68 -0
  127. package/dist/docs/DocsMenu.d.ts.map +1 -1
  128. package/dist/docs/DocsMenu.js +3 -3
  129. package/dist/docs/DocsRouter.d.ts.map +1 -1
  130. package/dist/docs/DocsRouter.js +13 -1
  131. package/dist/docs/DropdownMenuDocs.js +1 -1
  132. package/dist/docs/ExampleFormDocs.d.ts +4 -0
  133. package/dist/docs/ExampleFormDocs.d.ts.map +1 -0
  134. package/dist/docs/ExampleFormDocs.js +148 -0
  135. package/dist/docs/FilterDocs.d.ts +4 -0
  136. package/dist/docs/FilterDocs.d.ts.map +1 -0
  137. package/dist/docs/FilterDocs.js +112 -0
  138. package/dist/docs/InputDocs.d.ts.map +1 -1
  139. package/dist/docs/InputDocs.js +11 -1
  140. package/dist/docs/LinkButtonDocs.d.ts +4 -0
  141. package/dist/docs/LinkButtonDocs.d.ts.map +1 -0
  142. package/dist/docs/LinkButtonDocs.js +7 -0
  143. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +2 -0
  144. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -0
  145. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +29 -0
  146. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts +2 -0
  147. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +1 -0
  148. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +7 -0
  149. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts +2 -0
  150. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -0
  151. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +57 -0
  152. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts +9 -0
  153. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +1 -0
  154. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +30 -0
  155. package/dist/docs/PaginationDocs.js +6 -6
  156. package/dist/docs/RadioButtonGroupDocs.d.ts +4 -0
  157. package/dist/docs/RadioButtonGroupDocs.d.ts.map +1 -0
  158. package/dist/docs/RadioButtonGroupDocs.js +46 -0
  159. package/dist/docs/RoadMapDocs.d.ts +4 -0
  160. package/dist/docs/RoadMapDocs.d.ts.map +1 -0
  161. package/dist/docs/RoadMapDocs.js +171 -0
  162. package/dist/docs/SearchSelectInputDocs.d.ts +4 -0
  163. package/dist/docs/SearchSelectInputDocs.d.ts.map +1 -0
  164. package/dist/docs/SearchSelectInputDocs.js +168 -0
  165. package/dist/docs/SnackbarDocs.d.ts +4 -0
  166. package/dist/docs/SnackbarDocs.d.ts.map +1 -0
  167. package/dist/docs/SnackbarDocs.js +50 -0
  168. package/dist/docs/TabsGroupDocs.d.ts.map +1 -1
  169. package/dist/docs/TabsGroupDocs.js +12 -1
  170. package/dist/docs/docMockServices/empresaService.d.ts +38 -0
  171. package/dist/docs/docMockServices/empresaService.d.ts.map +1 -0
  172. package/dist/docs/docMockServices/empresaService.js +117 -0
  173. package/dist/docs/docMockServices/index.d.ts +9 -0
  174. package/dist/docs/docMockServices/index.d.ts.map +1 -0
  175. package/dist/docs/docMockServices/index.js +8 -0
  176. package/dist/docs/docMockServices/initialData.d.ts +6 -0
  177. package/dist/docs/docMockServices/initialData.d.ts.map +1 -0
  178. package/dist/docs/docMockServices/initialData.js +132 -0
  179. package/dist/docs/docMockServices/interfaces.d.ts +26 -0
  180. package/dist/docs/docMockServices/interfaces.d.ts.map +1 -0
  181. package/dist/docs/docMockServices/interfaces.js +1 -0
  182. package/dist/docs/docMockServices/personaEmpresaService.d.ts +43 -0
  183. package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +1 -0
  184. package/dist/docs/docMockServices/personaEmpresaService.js +113 -0
  185. package/dist/docs/docMockServices/personaService.d.ts +39 -0
  186. package/dist/docs/docMockServices/personaService.d.ts.map +1 -0
  187. package/dist/docs/docMockServices/personaService.js +181 -0
  188. package/dist/hooks/index.d.ts +2 -0
  189. package/dist/hooks/index.d.ts.map +1 -1
  190. package/dist/hooks/index.js +1 -0
  191. package/dist/hooks/useAsyncRequest.d.ts +17 -0
  192. package/dist/hooks/useAsyncRequest.d.ts.map +1 -0
  193. package/dist/hooks/useAsyncRequest.js +70 -0
  194. package/dist/index.css +1 -1
  195. package/dist/index.d.ts +23 -1
  196. package/dist/index.d.ts.map +1 -1
  197. package/dist/index.js +11 -0
  198. package/dist/index.js.map +1 -1
  199. package/dist/templates/forms/ContactForm.js +2 -2
  200. package/dist/templates/forms/LoginForm.js +1 -1
  201. package/dist/templates/forms/RegistrationForm.js +1 -1
  202. package/dist/templates/layouts/SidebarLayout.d.ts.map +1 -1
  203. package/dist/templates/layouts/SidebarLayout.js +3 -2
  204. package/dist/templates/patterns/FormPattern.d.ts.map +1 -1
  205. package/dist/templates/patterns/FormPattern.js +4 -3
  206. 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 = new Date(date);
6
- d.setHours(0, 0, 0, 0);
7
- return d;
6
+ const d = dayjs(date);
7
+ return d.startOf("day");
8
8
  };
9
9
  const isSameDay = (a, b) => {
10
- return (a.getFullYear() === b.getFullYear() &&
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 new Date(year, month + 1, 0).getDate();
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(() => createDateAtMidnight(new Date()), []);
26
- const initial = React.useMemo(() => {
27
- const base = value ?? initialViewDate ?? today;
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.getMonth(),
30
- year: base.getFullYear(),
27
+ month: base.month(),
28
+ year: base.year(),
31
29
  };
32
- }, [value, initialViewDate, today]);
33
- const [view, setView] = React.useState(initial);
30
+ }, [initialViewDate, today]);
31
+ const [view, setView] = React.useState(() => getViewFromValue(value));
34
32
  React.useEffect(() => {
35
- if (value) {
36
- setView({
37
- month: value.getMonth(),
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 = new Date(targetYear, targetMonth, day);
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 = new Date(view.year, view.month, 1);
76
- const firstWeekday = firstDayOfMonth.getDay(); // 0-6, Sunday=0
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 && !isNaN(value.getTime()) ? createDateAtMidnight(value) : null;
119
- const monthName = new Date(view.year, view.month, 1).toLocaleString("es-ES", {
120
- month: "long",
121
- });
122
- return (_jsxs("div", { className: `inline-flex flex-col rounded-lg border border-[var(--color-border-default)]
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 = new Date(year, month, day);
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.FC<InputProps>;
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;AAE1B,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;CAC5B;AAED,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CA0EtC,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
- export const Input = ({ label, error, icon, iconPosition = "left", size = "md", className = "", id, ...props }) => {
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 focus:ring-1
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 = error
17
- ? `border-[var(--color-border-error)] focus:border-[var(--color-border-error)] focus:ring-[var(--color-border-error)]`
18
- : `border-[var(--color-border-default)] focus:border-[var(--color-border-focus)] focus:ring-[var(--color-border-focus)]`;
19
- const inputClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${className}`;
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
- return (_jsx("i", { className: `fa ${icon} ${iconClasses} text-[var(--color-text-muted)] absolute top-1/2 transform -translate-y-1/2 ${iconPosition === "left" ? "left-3" : "right-3"}` }));
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
+ };
@@ -11,6 +11,7 @@ export interface PaginationProps {
11
11
  page?: number;
12
12
  pages?: number;
13
13
  total?: number;
14
+ isLoading?: boolean;
14
15
  }
15
16
  export declare const Pagination: React.FC<PaginationProps>;
16
17
  //# sourceMappingURL=Pagination.d.ts.map
@@ -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;CAChB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAsHhD,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" }) }), _jsxs("div", { className: "text-xs", 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, "aria-label": "P\u00E1gina siguiente" }) }), _jsx("div", { children: _jsx(Button, { variant: "ghost", size: "sm", icon: "fa-angle-double-right", onClick: goToLastPage, disabled: isLastPage || !hasPages, "aria-label": "\u00DAltima p\u00E1gina" }) })] })
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"}