@axzydev/axzy_ui_system 1.3.2 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -233,6 +233,11 @@ function useFloatingPanel(anchorRef, isOpen, {
233
233
 
234
234
  // src/hooks/useTableState.ts
235
235
  import { useCallback as useCallback4, useMemo as useMemo2, useState as useState4 } from "react";
236
+ var isEmptyFilterValue = (value) => {
237
+ if (value === void 0 || value === null || value === "") return true;
238
+ if (Array.isArray(value)) return value[0] == null && value[1] == null;
239
+ return false;
240
+ };
236
241
  function useTableState({
237
242
  defaultItemsPerPage = 10,
238
243
  initialSort = null
@@ -257,7 +262,7 @@ function useTableState({
257
262
  const handleFilterChange = useCallback4(
258
263
  (key, value) => {
259
264
  setFilters((prev) => {
260
- if (value === void 0 || value === null || value === "") {
265
+ if (isEmptyFilterValue(value)) {
261
266
  const next = { ...prev };
262
267
  delete next[key];
263
268
  return next;
@@ -2093,9 +2098,10 @@ function tableHeaderCell(className, density = "normal") {
2093
2098
  return clsx11(densityStyles[density].header, "align-top", className);
2094
2099
  }
2095
2100
  var tableBody = "divide-y divide-secondary-100";
2096
- var tableRow = "hover:bg-secondary-50/50 transition-colors duration-150 group";
2101
+ var tableRow = "hover:bg-[var(--color-table-rowHover,var(--color-secondary-50))] transition-colors duration-150 group";
2097
2102
  var tableRowClickable = "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-inset";
2098
2103
  var tableCardClickable = "cursor-pointer rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500";
2104
+ var tableCardHover = "hover:bg-[var(--color-table-rowHover,var(--color-secondary-50))] transition-colors duration-150";
2099
2105
  function tableCell(className, density = "normal") {
2100
2106
  return clsx11(densityStyles[density].cell, "align-middle", className);
2101
2107
  }
@@ -3594,9 +3600,9 @@ function useVirtualRows({
3594
3600
  }
3595
3601
 
3596
3602
  // src/components/organisms/data-table/dataTable.tsx
3597
- import clsx21 from "clsx";
3598
- import { useState as useState17, useEffect as useEffect7, useCallback as useCallback7, useRef as useRef11 } from "react";
3599
- import { FaCheck as FaCheck2, FaSpinner, FaTimes as FaTimes4, FaTable, FaThLarge } from "react-icons/fa";
3603
+ import clsx23 from "clsx";
3604
+ import { useState as useState19, useEffect as useEffect9, useCallback as useCallback7, useRef as useRef13 } from "react";
3605
+ import { FaCheck as FaCheck2, FaSpinner, FaTimes as FaTimes5, FaTable, FaThLarge } from "react-icons/fa";
3600
3606
  import { MdOutlineSwapVert } from "react-icons/md";
3601
3607
 
3602
3608
  // src/components/molecules/pagination/pagination.tsx
@@ -3889,445 +3895,240 @@ function ITPagination({
3889
3895
  return /* @__PURE__ */ jsx20("nav", { "aria-label": "Pagination", className: clsx20("inline-flex", className), children: renderPaginationControls() });
3890
3896
  }
3891
3897
 
3892
- // src/utils/table.utils.ts
3893
- var formatCurrencyMX = (value) => {
3894
- return value.toLocaleString("es-MX", {
3895
- style: "currency",
3896
- currency: "MXN"
3897
- });
3898
- };
3899
- var getNestedValue = (obj, path) => {
3900
- return path.split(".").reduce((acc, part) => acc && acc[part], obj);
3901
- };
3902
- var ROW_CLICK_IGNORE_SELECTOR = 'button, a, input, select, textarea, [role="button"], [role="link"], [data-row-click-ignore]';
3903
- function isInteractiveTarget(target, boundary = null) {
3904
- if (!(target instanceof Element)) return false;
3905
- const interactive = target.closest(ROW_CLICK_IGNORE_SELECTOR);
3906
- if (!interactive) return false;
3907
- if (boundary instanceof Node && interactive === boundary) return false;
3908
- return true;
3909
- }
3910
-
3911
- // src/components/organisms/data-table/dataTable.tsx
3912
- import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
3913
- var getNestedValue2 = (obj, path) => {
3914
- return path.split(".").reduce((acc, part) => acc && acc[part], obj);
3915
- };
3916
- var EMPTY_OBJECT = {};
3917
- function ITDataTable({
3918
- columns,
3919
- fetchData,
3920
- debounceMs = 500,
3921
- externalFilters = EMPTY_OBJECT,
3922
- loadingIndicator,
3923
- fetchOnMount = true,
3924
- reloadTrigger,
3925
- containerClassName,
3898
+ // src/components/molecules/search-select/search-select.tsx
3899
+ import { useState as useState17, useEffect as useEffect7, useRef as useRef11, useMemo as useMemo7 } from "react";
3900
+ import { createPortal as createPortal3 } from "react-dom";
3901
+ import clsx21 from "clsx";
3902
+ import { FaSearch as FaSearch2, FaTimes as FaTimes4 } from "react-icons/fa";
3903
+ import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
3904
+ function ITSearchSelect({
3905
+ name,
3906
+ options = [],
3907
+ label,
3908
+ placeholder = "Selecciona una opci\xF3n",
3909
+ valueField = "value",
3910
+ labelField = "label",
3911
+ value,
3912
+ onChange,
3913
+ onBlur,
3914
+ disabled = false,
3926
3915
  className,
3927
- variant = "default",
3916
+ touched,
3917
+ required,
3918
+ error,
3919
+ readOnly = false,
3920
+ onSearch,
3921
+ isLoading = false,
3922
+ noResultsMessage = "No se encontraron resultados",
3928
3923
  size = "md",
3929
- itemsPerPageOptions = [5, 10, 20],
3930
- defaultItemsPerPage = 10,
3931
- title,
3932
- renderCard,
3933
- defaultView,
3934
- showVerticalBorder = true,
3935
- verticalBorderClassname,
3936
- onRowClick,
3937
- layout = "auto",
3938
- density = "normal",
3939
- autoCardBreakpoint = 0,
3940
- virtualized = false,
3941
- virtualizedMaxHeight = 400,
3942
- rowHeight,
3943
- overscan = 5,
3944
- stickyHeader = false
3924
+ renderOption,
3925
+ clearable = true,
3926
+ onClear
3945
3927
  }) {
3946
- const [viewMode, setViewMode] = useState17(defaultView || "table");
3947
- const { ref: rootRef, width: containerWidth } = useElementSize();
3948
- const [data, setData] = useState17([]);
3949
- const [totalItems, setTotalItems] = useState17(0);
3950
- const [isLoading, setIsLoading] = useState17(fetchOnMount);
3951
- const isFixed = layout === "fixed";
3952
- const forcedCards = autoCardBreakpoint > 0 && containerWidth > 0 && containerWidth < autoCardBreakpoint;
3953
- const effectiveView = forcedCards ? "cards" : viewMode;
3954
- const hasColumnWidths = columns.some((col) => col.width != null);
3955
- const tableLayoutClass = isFixed ? "w-full text-sm text-left text-secondary-600 transition-opacity duration-300" : "min-w-max w-full text-sm text-left text-secondary-600 transition-opacity duration-300";
3956
- const isTableVirtual = virtualized && effectiveView === "table";
3957
- const isStickyHeader = stickyHeader && isTableVirtual;
3958
- const resolvedRowHeight = rowHeight ?? getRowHeight(size, density);
3959
- const columnCount = columns.length;
3960
- const scrollOuterClass = isTableVirtual ? "relative min-h-[200px]" : "overflow-x-auto relative min-h-[200px]";
3961
- const {
3962
- currentPage,
3963
- itemsPerPage,
3964
- filters,
3965
- sortConfig,
3966
- goToPage,
3967
- handleFilterChange,
3968
- handleSort,
3969
- handleItemsPerPageChange
3970
- } = useTableState({ defaultItemsPerPage });
3971
- const {
3972
- scrollRef,
3973
- startIndex,
3974
- endIndex,
3975
- topSpacerHeight,
3976
- bottomSpacerHeight
3977
- } = useVirtualRows({
3978
- count: data.length,
3979
- rowHeight: resolvedRowHeight,
3980
- overscan,
3981
- enabled: isTableVirtual,
3982
- resetKey: `${currentPage}-${itemsPerPage}`
3928
+ const [isOpen, setIsOpen] = useState17(false);
3929
+ const [searchTerm, setSearchTerm] = useState17("");
3930
+ const [isFocused, setIsFocused] = useState17(false);
3931
+ const [localTouched, setLocalTouched] = useState17(false);
3932
+ const containerRef = useRef11(null);
3933
+ const inputWrapperRef = useRef11(null);
3934
+ const timeoutRef = useRef11(null);
3935
+ const { panelRef, style: panelStyle } = useFloatingPanel(inputWrapperRef, isOpen, {
3936
+ estimatedHeight: 260,
3937
+ matchWidth: true
3983
3938
  });
3984
- const windowData = isTableVirtual ? data.slice(startIndex, endIndex + 1) : data;
3985
- const debounceTimerRef = useRef11(null);
3986
- const hasFetchedRef = useRef11(false);
3987
- const fetchDataRef = useRef11(fetchData);
3988
- fetchDataRef.current = fetchData;
3989
- const externalFiltersRef = useRef11(externalFilters);
3990
- externalFiltersRef.current = externalFilters;
3991
- const externalKey = JSON.stringify(externalFilters);
3992
- const computedTotalPages = Math.ceil(totalItems / itemsPerPage) || 1;
3993
- const performFetch = useCallback7(async () => {
3994
- setIsLoading(true);
3995
- try {
3996
- const response = await fetchDataRef.current({
3997
- page: currentPage,
3998
- limit: itemsPerPage,
3999
- filters: { ...filters, ...externalFiltersRef.current },
4000
- sort: sortConfig || void 0
4001
- });
4002
- setData(response.data || []);
4003
- setTotalItems(response.total || 0);
4004
- hasFetchedRef.current = true;
4005
- } catch (error) {
4006
- console.error("ITDataTable: Error fetching data", error);
4007
- setData([]);
4008
- setTotalItems(0);
4009
- hasFetchedRef.current = true;
4010
- } finally {
4011
- setIsLoading(false);
4012
- }
4013
- }, [currentPage, itemsPerPage, filters, sortConfig]);
4014
- const performFetchRef = useRef11(performFetch);
4015
- performFetchRef.current = performFetch;
3939
+ const selectedOption = useMemo7(() => {
3940
+ return options.find((opt) => opt[valueField] === value);
3941
+ }, [options, value, valueField]);
4016
3942
  useEffect7(() => {
4017
- if (!fetchOnMount && !hasFetchedRef.current) return;
4018
- if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
4019
- debounceTimerRef.current = setTimeout(() => {
4020
- performFetchRef.current();
4021
- }, debounceMs);
4022
- return () => {
4023
- if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
4024
- };
4025
- }, [currentPage, itemsPerPage, sortConfig, filters, externalKey, reloadTrigger, fetchOnMount, debounceMs]);
4026
- const renderFilterInput = (col) => {
4027
- if (!col.filter) return null;
4028
- if (col.type === "boolean") {
4029
- const currentValue = filters[col.key];
4030
- const nextValue = currentValue === void 0 ? true : currentValue === true ? false : void 0;
4031
- const getToggleLabel = () => {
4032
- if (currentValue === void 0) return "Mostrar todos";
4033
- if (currentValue === true) return "Filtrar solo verdaderos";
4034
- return "Filtrar solo falsos";
4035
- };
4036
- return /* @__PURE__ */ jsx21(
4037
- "button",
4038
- {
4039
- 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",
4040
- onClick: () => handleFilterChange(col.key, nextValue),
4041
- "aria-label": `${getToggleLabel()} para ${col.label}`,
4042
- title: `${getToggleLabel()} para ${col.label}`,
4043
- disabled: isLoading,
4044
- children: /* @__PURE__ */ jsx21("div", { className: "relative w-10 h-5 bg-secondary-300 rounded-full", children: /* @__PURE__ */ jsx21(
4045
- "div",
4046
- {
4047
- className: clsx21(
4048
- "absolute top-0.5 w-4 h-4 rounded-full transition-all duration-300 shadow-sm",
4049
- {
4050
- "left-0.5 bg-secondary-400": currentValue === void 0,
4051
- "left-5 bg-slate-500": currentValue === true,
4052
- "left-0.5 bg-secondary-500": currentValue === false
4053
- }
4054
- )
4055
- }
4056
- ) })
4057
- }
4058
- );
3943
+ if (!isFocused) {
3944
+ setSearchTerm(selectedOption ? String(selectedOption[labelField]) : "");
4059
3945
  }
4060
- if (col.filter === "catalog" && col.catalogOptions) {
4061
- if (col.catalogOptions.loading) {
4062
- return /* @__PURE__ */ jsx21(FaSpinner, { className: "animate-spin", "aria-label": "Cargando opciones", title: "Cargando opciones" });
4063
- }
4064
- if (col.catalogOptions.error) {
4065
- return /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-danger-500 text-xs", children: "Error cargando" });
3946
+ }, [selectedOption, isFocused, labelField]);
3947
+ useEffect7(() => {
3948
+ function handleClickOutside(event) {
3949
+ const target = event.target;
3950
+ const inContainer = containerRef.current?.contains(target);
3951
+ const inPanel = panelRef.current?.contains(target);
3952
+ if (!inContainer && !inPanel) {
3953
+ setIsOpen(false);
4066
3954
  }
4067
- return /* @__PURE__ */ jsx21(
4068
- ITSelect,
4069
- {
4070
- name: `filter-${col.key}`,
4071
- options: [
4072
- { value: "", label: "Todos" },
4073
- ...col.catalogOptions.data.map((item) => ({
4074
- value: String(item.id),
4075
- label: item.name
4076
- }))
4077
- ],
4078
- value: String(filters[col.key] || ""),
4079
- onChange: (e) => {
4080
- const value = e.target.value === "" ? void 0 : e.target.value;
4081
- handleFilterChange(col.key, value);
4082
- },
4083
- onBlur: () => {
4084
- },
4085
- className: "w-full text-xs",
4086
- disabled: isLoading
4087
- }
4088
- );
4089
3955
  }
4090
- return /* @__PURE__ */ jsx21(
4091
- ITInput,
4092
- {
4093
- name: `filter-${col.key}`,
4094
- className: "w-full text-xs",
4095
- placeholder: "Buscar...",
4096
- value: String(filters[col.key] || ""),
4097
- onChange: (e) => handleFilterChange(col.key, e.target.value),
4098
- onBlur: () => {
4099
- },
4100
- disabled: isLoading
4101
- }
3956
+ document.addEventListener("mousedown", handleClickOutside);
3957
+ return () => document.removeEventListener("mousedown", handleClickOutside);
3958
+ }, []);
3959
+ const selectedLabel = selectedOption ? String(selectedOption[labelField]) : "";
3960
+ const filteredOptions = useMemo7(() => {
3961
+ if (onSearch) return options;
3962
+ if (!searchTerm || !isFocused || searchTerm === selectedLabel) return options;
3963
+ return options.filter(
3964
+ (opt) => String(opt[labelField]).toLowerCase().includes(searchTerm.toLowerCase())
4102
3965
  );
3966
+ }, [options, searchTerm, selectedLabel, onSearch, labelField, isFocused]);
3967
+ const handleInputChange = (e) => {
3968
+ const query = e.target.value;
3969
+ setSearchTerm(query);
3970
+ setIsOpen(true);
3971
+ if (onSearch) {
3972
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
3973
+ timeoutRef.current = setTimeout(() => {
3974
+ onSearch(query);
3975
+ }, 500);
3976
+ }
4103
3977
  };
4104
- const renderCellContent = (col, row) => {
4105
- const value = getNestedValue2(row, col.key);
4106
- if (col.render) return col.render(row);
4107
- switch (col.type) {
4108
- case "number":
4109
- return typeof value === "number" && col.currencyMX ? formatCurrencyMX(value) : value;
4110
- case "boolean":
4111
- return value ? /* @__PURE__ */ jsx21(FaCheck2, { className: "text-success-500", "aria-label": "Verdadero", title: "Verdadero" }) : /* @__PURE__ */ jsx21(FaTimes4, { className: "text-danger-500", "aria-label": "Falso", title: "Falso" });
4112
- case "actions":
4113
- return col.actions ? col.actions(row) : null;
4114
- case "catalog":
4115
- if (col.catalogOptions) {
4116
- const catalogItem = col.catalogOptions.data.find((item) => item.id === value);
4117
- return catalogItem?.name || value;
4118
- }
4119
- return value;
4120
- default:
4121
- return value;
3978
+ const handleSelect = (option) => {
3979
+ if (onChange) {
3980
+ onChange(option[valueField], option);
4122
3981
  }
3982
+ setSearchTerm(String(option[labelField]));
3983
+ setIsOpen(false);
4123
3984
  };
4124
- const renderDefaultCard = (row) => {
4125
- const dataCols = columns.filter((c) => c.type !== "actions");
4126
- const actionCol = columns.find((c) => c.type === "actions");
4127
- return /* @__PURE__ */ jsxs18("div", { className: "bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700 p-3 space-y-2 shadow-sm", children: [
4128
- dataCols.map((col) => /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between gap-2", children: [
4129
- /* @__PURE__ */ jsx21("span", { className: "text-[10px] font-bold uppercase tracking-wider text-slate-400 whitespace-nowrap flex-shrink-0 min-w-[70px]", children: col.label }),
4130
- /* @__PURE__ */ jsx21("span", { className: "text-sm font-medium text-slate-800 dark:text-white text-right truncate", children: renderCellContent(col, row) })
4131
- ] }, col.key)),
4132
- actionCol?.actions && /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-end gap-2 pt-2 border-t border-slate-100 dark:border-slate-700", children: actionCol.actions(row) })
4133
- ] });
3985
+ const handleClear = () => {
3986
+ setSearchTerm("");
3987
+ setIsOpen(true);
3988
+ if (onSearch) onSearch("");
3989
+ if (value !== void 0 && value !== null && value !== "") {
3990
+ onChange?.("", void 0);
3991
+ }
3992
+ onClear?.();
4134
3993
  };
4135
- const segCtrlClass = (mode) => `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${effectiveView === mode ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`;
4136
- const handleRowClick = (row) => (event) => {
4137
- if (!onRowClick || isLoading || isInteractiveTarget(event.target, event.currentTarget)) return;
4138
- onRowClick(row, event);
3994
+ const handleFocus = () => {
3995
+ if (disabled || readOnly) return;
3996
+ setIsFocused(true);
3997
+ setIsOpen(true);
4139
3998
  };
4140
- const handleRowKeyDown = (row) => (event) => {
4141
- if (!onRowClick || isLoading) return;
4142
- if (event.target !== event.currentTarget) return;
4143
- if (event.key !== "Enter" && event.key !== " ") return;
4144
- event.preventDefault();
4145
- onRowClick(row, event);
3999
+ const handleInputBlur = (e) => {
4000
+ setTimeout(() => {
4001
+ setIsFocused(false);
4002
+ setLocalTouched(true);
4003
+ onBlur?.(e);
4004
+ }, 200);
4146
4005
  };
4147
- const tableEl = /* @__PURE__ */ jsxs18(
4148
- "table",
4149
- {
4150
- className: clsx21(
4151
- tableLayoutClass,
4152
- showVerticalBorder && "[&_th]:border-r [&_th:last-child]:border-r-0 [&_td]:border-r [&_td:last-child]:border-r-0",
4153
- showVerticalBorder && (verticalBorderClassname || "[&_th]:border-slate-100 dark:[&_th]:border-slate-700/30 [&_td]:border-slate-100 dark:[&_td]:border-slate-700/30"),
4154
- isLoading ? "opacity-50" : "opacity-100",
4155
- variantStyles[variant],
4156
- sizeStyles[size],
4157
- className
4158
- ),
4159
- style: isFixed ? { tableLayout: "fixed" } : void 0,
4160
- "aria-rowcount": isTableVirtual ? data.length + 1 : void 0,
4161
- children: [
4162
- hasColumnWidths && /* @__PURE__ */ jsx21("colgroup", { children: columns.map((col) => /* @__PURE__ */ jsx21(
4163
- "col",
4164
- {
4165
- style: col.width != null ? { width: typeof col.width === "number" ? `${col.width}px` : col.width } : void 0
4166
- },
4167
- col.key
4168
- )) }),
4169
- /* @__PURE__ */ jsx21("thead", { children: /* @__PURE__ */ jsx21(
4170
- "tr",
4006
+ const inputTheme = theme.input || {};
4007
+ const isTouched = touched !== void 0 ? touched : localTouched;
4008
+ const isEmpty = value === void 0 || value === null || String(value).trim() === "";
4009
+ const effectiveError = error !== void 0 && error !== false ? error === true ? "Este campo es requerido" : error : required && isEmpty ? "Este campo es requerido" : void 0;
4010
+ const hasError = isTouched && !!effectiveError;
4011
+ const errorMessage = typeof effectiveError === "string" ? effectiveError : "Este campo es requerido";
4012
+ const showClearButton = clearable && !disabled && !readOnly && (searchTerm.length > 0 || !isEmpty);
4013
+ const getInputStyle = () => {
4014
+ const sizeConfig = inputSizeTokens[size] ?? inputSizeTokens.md;
4015
+ const style = {
4016
+ backgroundColor: inputTheme.backgroundColor || "#ffffff",
4017
+ borderColor: inputTheme.borderColor || "var(--color-secondary-300)",
4018
+ borderRadius: inputTheme.borderRadius || "0.5rem",
4019
+ padding: sizeConfig.padding,
4020
+ fontSize: sizeConfig.fontSize,
4021
+ borderWidth: "1px",
4022
+ borderStyle: "solid",
4023
+ transition: "all 0.2s",
4024
+ color: "var(--it-input-text-color, var(--color-secondary-900))",
4025
+ width: "100%"
4026
+ };
4027
+ if (disabled) {
4028
+ style.backgroundColor = inputTheme.disabled?.backgroundColor || "var(--color-secondary-100)";
4029
+ style.borderColor = inputTheme.disabled?.borderColor || "var(--color-secondary-200)";
4030
+ style.opacity = 0.7;
4031
+ style.cursor = "not-allowed";
4032
+ }
4033
+ if (hasError) {
4034
+ style.borderColor = inputTheme.error?.borderColor || "red";
4035
+ if (isFocused) {
4036
+ style.boxShadow = inputTheme.error?.ring;
4037
+ }
4038
+ } else if (isFocused && !readOnly) {
4039
+ style.boxShadow = inputTheme.focus?.ring;
4040
+ style.borderColor = inputTheme.focus?.borderColor;
4041
+ }
4042
+ return style;
4043
+ };
4044
+ return /* @__PURE__ */ jsxs18("div", { className: clsx21("w-full flex flex-col gap-1.5", className, isOpen && "relative z-30"), ref: containerRef, children: [
4045
+ label && /* @__PURE__ */ jsxs18(
4046
+ ITText,
4047
+ {
4048
+ as: "label",
4049
+ className: clsx21("text-sm font-medium text-secondary-700 dark:text-slate-300", {
4050
+ "text-danger-500": hasError
4051
+ }),
4052
+ children: [
4053
+ /* @__PURE__ */ jsx21(ITText, { as: "span", children: label }),
4054
+ required && /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-danger-500 ml-1", children: "*" })
4055
+ ]
4056
+ }
4057
+ ),
4058
+ /* @__PURE__ */ jsxs18("div", { className: "relative", children: [
4059
+ /* @__PURE__ */ jsxs18("div", { ref: inputWrapperRef, className: "relative flex items-center", children: [
4060
+ /* @__PURE__ */ jsx21(
4061
+ "input",
4171
4062
  {
4172
- className: clsx21(tableHeaderRow, "dark:text-slate-200"),
4173
- "aria-rowindex": isTableVirtual ? 1 : void 0,
4174
- children: columns.map((col) => /* @__PURE__ */ jsx21(
4175
- "th",
4176
- {
4177
- scope: "col",
4178
- className: clsx21(
4179
- tableHeaderCell(col.className, density),
4180
- col.align && tableAlignClasses[col.align],
4181
- isStickyHeader && "sticky top-0 z-10 bg-secondary-50"
4182
- ),
4183
- style: col.minWidth != null || isStickyHeader ? {
4184
- ...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
4185
- ...isStickyHeader ? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" } : {}
4186
- } : void 0,
4187
- children: /* @__PURE__ */ jsxs18("div", { className: isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]", children: [
4188
- /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between gap-2", children: [
4189
- /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
4190
- col.sortable && col.type !== "actions" && /* @__PURE__ */ jsx21(
4191
- "button",
4192
- {
4193
- onClick: () => handleSort(col.key),
4194
- disabled: isLoading,
4195
- className: `p-1 rounded-md transition-colors ${sortConfig?.key === col.key ? "bg-secondary-200 text-secondary-900" : "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"} disabled:opacity-50`,
4196
- title: `Ordenar por ${col.label}`,
4197
- children: /* @__PURE__ */ jsx21(MdOutlineSwapVert, { className: "w-4 h-4", "aria-hidden": "true" })
4198
- }
4199
- )
4200
- ] }),
4201
- /* @__PURE__ */ jsx21("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
4202
- ] })
4203
- },
4204
- col.key
4205
- ))
4063
+ type: "text",
4064
+ name,
4065
+ value: searchTerm,
4066
+ onChange: handleInputChange,
4067
+ onFocus: handleFocus,
4068
+ onBlur: handleInputBlur,
4069
+ disabled,
4070
+ readOnly,
4071
+ placeholder,
4072
+ className: "outline-none pr-10",
4073
+ style: getInputStyle(),
4074
+ autoComplete: "off"
4206
4075
  }
4207
- ) }),
4208
- /* @__PURE__ */ jsx21("tbody", { className: clsx21(tableBody, "dark:divide-slate-700/30"), children: data.length > 0 ? /* @__PURE__ */ jsxs18(Fragment4, { children: [
4209
- isTableVirtual && topSpacerHeight > 0 && /* @__PURE__ */ jsx21("tr", { "aria-hidden": "true", style: { height: topSpacerHeight }, children: /* @__PURE__ */ jsx21("td", { colSpan: columnCount, style: { padding: 0, border: 0 } }) }),
4210
- windowData.map((row, windowIndex) => {
4211
- const absoluteIndex = isTableVirtual ? startIndex + windowIndex : windowIndex;
4212
- return /* @__PURE__ */ jsx21(
4213
- "tr",
4214
- {
4215
- "aria-rowindex": isTableVirtual ? absoluteIndex + 2 : void 0,
4216
- className: clsx21(
4217
- tableRow,
4218
- variant === "striped" && absoluteIndex % 2 === 0 && "bg-secondary-50/40 dark:bg-slate-800/20",
4219
- onRowClick && !isLoading && tableRowClickable
4220
- ),
4221
- tabIndex: onRowClick && !isLoading ? 0 : void 0,
4222
- onClick: onRowClick && !isLoading ? handleRowClick(row) : void 0,
4223
- onKeyDown: onRowClick && !isLoading ? handleRowKeyDown(row) : void 0,
4224
- children: columns.map((col) => {
4225
- const rawValue = getNestedValue2(row, col.key);
4226
- const truncateTitle = col.truncate && (typeof rawValue === "string" || typeof rawValue === "number") ? String(rawValue) : void 0;
4227
- return /* @__PURE__ */ jsx21(
4228
- "td",
4229
- {
4230
- className: clsx21(
4231
- tableCell(col.className, density),
4232
- col.align && tableAlignClasses[col.align]
4233
- ),
4234
- style: col.minWidth != null ? { minWidth: `${col.minWidth}px` } : void 0,
4235
- title: truncateTitle,
4236
- children: col.type === "actions" ? /* @__PURE__ */ jsx21("div", { className: tableActionsCell, children: renderCellContent(col, row) }) : /* @__PURE__ */ jsx21("div", { className: clsx21(tableCellText, col.truncate && "truncate"), children: renderCellContent(col, row) })
4237
- },
4238
- `${absoluteIndex}-${col.key}`
4239
- );
4240
- })
4076
+ ),
4077
+ /* @__PURE__ */ jsxs18("div", { className: "absolute right-3 flex items-center gap-2 text-secondary-400", children: [
4078
+ isLoading && /* @__PURE__ */ jsx21("div", { className: "pointer-events-none animate-spin h-4 w-4 border-2 border-primary-500 border-t-transparent rounded-full" }),
4079
+ !isLoading && showClearButton && /* @__PURE__ */ jsx21(
4080
+ "button",
4081
+ {
4082
+ type: "button",
4083
+ "aria-label": "Limpiar",
4084
+ title: "Limpiar",
4085
+ onMouseDown: (e) => {
4086
+ e.preventDefault();
4087
+ handleClear();
4241
4088
  },
4242
- absoluteIndex
4243
- );
4244
- }),
4245
- isTableVirtual && bottomSpacerHeight > 0 && /* @__PURE__ */ jsx21("tr", { "aria-hidden": "true", style: { height: bottomSpacerHeight }, children: /* @__PURE__ */ jsx21("td", { colSpan: columnCount, style: { padding: 0, border: 0 } }) })
4246
- ] }) : /* @__PURE__ */ jsx21("tr", { children: /* @__PURE__ */ jsx21("td", { colSpan: columns.length, className: "px-6 py-12 text-center", children: !isLoading && /* @__PURE__ */ jsxs18("div", { className: tableEmptyContent, children: [
4247
- /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
4248
- /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
4249
- ] }) }) }) })
4250
- ]
4251
- }
4252
- );
4253
- return /* @__PURE__ */ jsxs18("div", { ref: rootRef, className: clsx21("space-y-4 w-full relative", containerClassName), children: [
4254
- /* @__PURE__ */ jsxs18("div", { className: tableContainer, style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
4255
- title && /* @__PURE__ */ jsxs18("div", { className: "px-6 py-5 flex items-center justify-between", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
4256
- /* @__PURE__ */ jsx21(ITText, { as: "h2", className: "text-xl font-bold text-secondary-900 leading-tight", children: title }),
4257
- /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3", children: [
4258
- isLoading && /* @__PURE__ */ jsx21("div", { className: "text-secondary-400", children: loadingIndicator || /* @__PURE__ */ jsx21(FaSpinner, { className: "animate-spin text-primary-500 text-xl" }) }),
4259
- /* @__PURE__ */ jsxs18("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", children: [
4260
- /* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("table"), disabled: forcedCards, className: segCtrlClass("table"), children: [
4261
- /* @__PURE__ */ jsx21(FaTable, { size: 11 }),
4262
- "Table"
4263
- ] }),
4264
- /* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("cards"), className: segCtrlClass("cards"), children: [
4265
- /* @__PURE__ */ jsx21(FaThLarge, { size: 11 }),
4266
- "Cards"
4267
- ] })
4268
- ] })
4089
+ className: "flex items-center justify-center text-secondary-400 hover:text-secondary-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-400 rounded-full",
4090
+ children: /* @__PURE__ */ jsx21(FaTimes4, { size: 14 })
4091
+ }
4092
+ ),
4093
+ !isLoading && !showClearButton && /* @__PURE__ */ jsx21(FaSearch2, { size: 14, className: clsx21("pointer-events-none", { "text-primary-500": isFocused }) })
4269
4094
  ] })
4270
4095
  ] }),
4271
- !title && /* @__PURE__ */ jsx21("div", { className: "flex justify-end px-4 pt-3", children: /* @__PURE__ */ jsxs18("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", children: [
4272
- /* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("table"), disabled: forcedCards, className: segCtrlClass("table"), children: [
4273
- /* @__PURE__ */ jsx21(FaTable, { size: 11 }),
4274
- "Table"
4275
- ] }),
4276
- /* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("cards"), className: segCtrlClass("cards"), children: [
4277
- /* @__PURE__ */ jsx21(FaThLarge, { size: 11 }),
4278
- "Cards"
4279
- ] })
4280
- ] }) }),
4281
- /* @__PURE__ */ jsxs18("div", { className: scrollOuterClass, children: [
4282
- isLoading && /* @__PURE__ */ jsx21("div", { className: "absolute inset-0 z-20 flex items-center justify-center bg-white/40 backdrop-blur-[2px] transition-all duration-300", children: /* @__PURE__ */ jsx21("div", { className: "flex flex-col items-center gap-3 p-6 rounded-2xl shadow-xl border border-secondary-100 animate-in fade-in zoom-in duration-300", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: loadingIndicator || /* @__PURE__ */ jsxs18(Fragment4, { children: [
4283
- /* @__PURE__ */ jsx21(FaSpinner, { className: "animate-spin text-primary-500 text-4xl" }),
4284
- /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-sm font-semibold text-secondary-600 animate-pulse", children: "Cargando datos..." })
4285
- ] }) }) }),
4286
- effectiveView === "cards" ? /* @__PURE__ */ jsx21("div", { className: "p-4 space-y-3 max-h-[400px] overflow-y-auto", children: data.length > 0 ? data.map((row, i) => /* @__PURE__ */ jsx21(
4287
- "div",
4288
- {
4289
- className: clsx21(onRowClick && !isLoading && tableCardClickable),
4290
- role: onRowClick && !isLoading ? "button" : void 0,
4291
- tabIndex: onRowClick && !isLoading ? 0 : void 0,
4292
- onClick: onRowClick && !isLoading ? handleRowClick(row) : void 0,
4293
- onKeyDown: onRowClick && !isLoading ? handleRowKeyDown(row) : void 0,
4294
- children: renderCard ? renderCard(row) : renderDefaultCard(row)
4295
- },
4296
- i
4297
- )) : !isLoading && /* @__PURE__ */ jsxs18("div", { className: clsx21(tableEmptyContent, "py-12"), children: [
4298
- /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
4299
- /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
4300
- ] }) }) : isTableVirtual ? /* @__PURE__ */ jsx21(
4096
+ isOpen && createPortal3(
4097
+ /* @__PURE__ */ jsx21(
4301
4098
  "div",
4302
4099
  {
4303
- ref: scrollRef,
4304
- className: "overflow-x-auto overflow-y-auto",
4305
- style: { maxHeight: virtualizedMaxHeight },
4306
- children: tableEl
4100
+ ref: panelRef,
4101
+ style: panelStyle,
4102
+ className: "bg-white dark:bg-slate-900 border border-secondary-200 dark:border-slate-800 rounded-lg shadow-xl overflow-hidden animate-in fade-in zoom-in duration-200 origin-top",
4103
+ children: /* @__PURE__ */ jsx21("div", { className: "max-h-60 overflow-y-auto", children: filteredOptions.length > 0 ? filteredOptions.map((option) => {
4104
+ const isSelected = value === option[valueField];
4105
+ return /* @__PURE__ */ jsx21(
4106
+ ITText,
4107
+ {
4108
+ as: "div",
4109
+ onClick: () => handleSelect(option),
4110
+ className: clsx21(
4111
+ "px-4 py-2 text-sm cursor-pointer transition-colors",
4112
+ isSelected ? "bg-primary-50 dark:bg-primary-950/40 text-primary-700 dark:text-primary-300 font-medium" : "hover:bg-secondary-50 dark:hover:bg-slate-800 text-secondary-700 dark:text-slate-300"
4113
+ ),
4114
+ children: renderOption ? renderOption(option, { isSelected, searchTerm }) : /* @__PURE__ */ jsx21(ITText, { as: "span", children: option[labelField] })
4115
+ },
4116
+ option[valueField]
4117
+ );
4118
+ }) : /* @__PURE__ */ jsx21(ITText, { as: "div", className: "px-4 py-6 text-sm text-center text-secondary-500 italic", children: isLoading ? "Cargando..." : noResultsMessage }) })
4307
4119
  }
4308
- ) : tableEl
4309
- ] })
4120
+ ),
4121
+ document.body
4122
+ )
4310
4123
  ] }),
4311
- /* @__PURE__ */ jsx21("div", { className: "rounded-b-xl px-6 py-4", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: /* @__PURE__ */ jsx21(
4312
- ITPagination,
4313
- {
4314
- currentPage,
4315
- totalPages: computedTotalPages,
4316
- onPageChange: goToPage,
4317
- color: "primary",
4318
- itemsPerPageOptions,
4319
- itemsPerPage,
4320
- onItemsPerPageChange: handleItemsPerPageChange,
4321
- totalItems
4322
- }
4323
- ) })
4124
+ hasError && /* @__PURE__ */ jsx21(ITText, { as: "p", className: "text-danger-500 text-xs mt-1", children: errorMessage })
4324
4125
  ] });
4325
4126
  }
4326
4127
 
4327
4128
  // src/components/molecules/date-picker/datePicker.tsx
4328
4129
  import clsx22 from "clsx";
4329
4130
  import React5, { useEffect as useEffect8, useRef as useRef12, useState as useState18 } from "react";
4330
- import { createPortal as createPortal3 } from "react-dom";
4131
+ import { createPortal as createPortal4 } from "react-dom";
4331
4132
  import { FaCalendarAlt } from "react-icons/fa";
4332
4133
  import { isBefore as isBefore2 } from "date-fns";
4333
4134
  import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
@@ -4537,7 +4338,7 @@ function ITDatePicker({
4537
4338
  onClick: handleIconClick
4538
4339
  }
4539
4340
  ),
4540
- isOpen && createPortal3(
4341
+ isOpen && createPortal4(
4541
4342
  /* @__PURE__ */ jsx22(
4542
4343
  "div",
4543
4344
  {
@@ -4577,13 +4378,513 @@ function ITDatePicker({
4577
4378
  ] });
4578
4379
  }
4579
4380
 
4580
- // src/components/organisms/dialog/dialog.tsx
4581
- import { createPortal as createPortal4 } from "react-dom";
4582
- import { useEffect as useEffect9, useRef as useRef13 } from "react";
4381
+ // src/utils/table.utils.ts
4382
+ var formatCurrencyMX = (value) => {
4383
+ return value.toLocaleString("es-MX", {
4384
+ style: "currency",
4385
+ currency: "MXN"
4386
+ });
4387
+ };
4388
+ var getNestedValue = (obj, path) => {
4389
+ return path.split(".").reduce((acc, part) => acc && acc[part], obj);
4390
+ };
4391
+ var ROW_CLICK_IGNORE_SELECTOR = 'button, a, input, select, textarea, [role="button"], [role="link"], [data-row-click-ignore]';
4392
+ function isInteractiveTarget(target, boundary = null) {
4393
+ if (!(target instanceof Element)) return false;
4394
+ const interactive = target.closest(ROW_CLICK_IGNORE_SELECTOR);
4395
+ if (!interactive) return false;
4396
+ if (boundary instanceof Node && interactive === boundary) return false;
4397
+ return true;
4398
+ }
4399
+
4400
+ // src/components/organisms/data-table/dataTable.tsx
4401
+ import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
4402
+ var getNestedValue2 = (obj, path) => {
4403
+ return path.split(".").reduce((acc, part) => acc && acc[part], obj);
4404
+ };
4405
+ var EMPTY_OBJECT = {};
4406
+ function ITDataTable({
4407
+ columns,
4408
+ fetchData,
4409
+ debounceMs = 500,
4410
+ externalFilters = EMPTY_OBJECT,
4411
+ loadingIndicator,
4412
+ fetchOnMount = true,
4413
+ reloadTrigger,
4414
+ containerClassName,
4415
+ className,
4416
+ variant = "default",
4417
+ size = "md",
4418
+ itemsPerPageOptions = [5, 10, 20],
4419
+ defaultItemsPerPage = 10,
4420
+ title,
4421
+ renderCard,
4422
+ defaultView,
4423
+ showVerticalBorder = true,
4424
+ verticalBorderClassname,
4425
+ onRowClick,
4426
+ layout = "auto",
4427
+ density = "normal",
4428
+ autoCardBreakpoint = 0,
4429
+ virtualized = false,
4430
+ virtualizedMaxHeight = 400,
4431
+ rowHeight,
4432
+ overscan = 5,
4433
+ stickyHeader = false
4434
+ }) {
4435
+ const [viewMode, setViewMode] = useState19(defaultView || "table");
4436
+ const { ref: rootRef, width: containerWidth } = useElementSize();
4437
+ const [data, setData] = useState19([]);
4438
+ const [totalItems, setTotalItems] = useState19(0);
4439
+ const [isLoading, setIsLoading] = useState19(fetchOnMount);
4440
+ const isFixed = layout === "fixed";
4441
+ const forcedCards = autoCardBreakpoint > 0 && containerWidth > 0 && containerWidth < autoCardBreakpoint;
4442
+ const effectiveView = forcedCards ? "cards" : viewMode;
4443
+ const hasColumnWidths = columns.some((col) => col.width != null);
4444
+ const tableLayoutClass = isFixed ? "w-full text-sm text-left text-secondary-600 transition-opacity duration-300" : "min-w-max w-full text-sm text-left text-secondary-600 transition-opacity duration-300";
4445
+ const isTableVirtual = virtualized && effectiveView === "table";
4446
+ const isStickyHeader = stickyHeader && isTableVirtual;
4447
+ const resolvedRowHeight = rowHeight ?? getRowHeight(size, density);
4448
+ const columnCount = columns.length;
4449
+ const scrollOuterClass = isTableVirtual ? "relative min-h-[200px]" : "overflow-x-auto relative min-h-[200px]";
4450
+ const {
4451
+ currentPage,
4452
+ itemsPerPage,
4453
+ filters,
4454
+ sortConfig,
4455
+ goToPage,
4456
+ handleFilterChange,
4457
+ handleSort,
4458
+ handleItemsPerPageChange
4459
+ } = useTableState({ defaultItemsPerPage });
4460
+ const {
4461
+ scrollRef,
4462
+ startIndex,
4463
+ endIndex,
4464
+ topSpacerHeight,
4465
+ bottomSpacerHeight
4466
+ } = useVirtualRows({
4467
+ count: data.length,
4468
+ rowHeight: resolvedRowHeight,
4469
+ overscan,
4470
+ enabled: isTableVirtual,
4471
+ resetKey: `${currentPage}-${itemsPerPage}`
4472
+ });
4473
+ const windowData = isTableVirtual ? data.slice(startIndex, endIndex + 1) : data;
4474
+ const debounceTimerRef = useRef13(null);
4475
+ const hasFetchedRef = useRef13(false);
4476
+ const fetchDataRef = useRef13(fetchData);
4477
+ fetchDataRef.current = fetchData;
4478
+ const externalFiltersRef = useRef13(externalFilters);
4479
+ externalFiltersRef.current = externalFilters;
4480
+ const externalKey = JSON.stringify(externalFilters);
4481
+ const computedTotalPages = Math.ceil(totalItems / itemsPerPage) || 1;
4482
+ const performFetch = useCallback7(async () => {
4483
+ setIsLoading(true);
4484
+ try {
4485
+ const response = await fetchDataRef.current({
4486
+ page: currentPage,
4487
+ limit: itemsPerPage,
4488
+ filters: { ...filters, ...externalFiltersRef.current },
4489
+ sort: sortConfig || void 0
4490
+ });
4491
+ setData(response.data || []);
4492
+ setTotalItems(response.total || 0);
4493
+ hasFetchedRef.current = true;
4494
+ } catch (error) {
4495
+ console.error("ITDataTable: Error fetching data", error);
4496
+ setData([]);
4497
+ setTotalItems(0);
4498
+ hasFetchedRef.current = true;
4499
+ } finally {
4500
+ setIsLoading(false);
4501
+ }
4502
+ }, [currentPage, itemsPerPage, filters, sortConfig]);
4503
+ const performFetchRef = useRef13(performFetch);
4504
+ performFetchRef.current = performFetch;
4505
+ useEffect9(() => {
4506
+ if (!fetchOnMount && !hasFetchedRef.current) return;
4507
+ if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
4508
+ debounceTimerRef.current = setTimeout(() => {
4509
+ performFetchRef.current();
4510
+ }, debounceMs);
4511
+ return () => {
4512
+ if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
4513
+ };
4514
+ }, [currentPage, itemsPerPage, sortConfig, filters, externalKey, reloadTrigger, fetchOnMount, debounceMs]);
4515
+ const renderFilterInput = (col) => {
4516
+ if (!col.filter) return null;
4517
+ if (col.type === "boolean") {
4518
+ const currentValue = filters[col.key];
4519
+ const nextValue = currentValue === void 0 ? true : currentValue === true ? false : void 0;
4520
+ const getToggleLabel = () => {
4521
+ if (currentValue === void 0) return "Mostrar todos";
4522
+ if (currentValue === true) return "Filtrar solo verdaderos";
4523
+ return "Filtrar solo falsos";
4524
+ };
4525
+ return /* @__PURE__ */ jsx23(
4526
+ "button",
4527
+ {
4528
+ 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",
4529
+ onClick: () => handleFilterChange(col.key, nextValue),
4530
+ "aria-label": `${getToggleLabel()} para ${col.label}`,
4531
+ title: `${getToggleLabel()} para ${col.label}`,
4532
+ disabled: isLoading,
4533
+ children: /* @__PURE__ */ jsx23("div", { className: "relative w-10 h-5 bg-secondary-300 rounded-full", children: /* @__PURE__ */ jsx23(
4534
+ "div",
4535
+ {
4536
+ className: clsx23(
4537
+ "absolute top-0.5 w-4 h-4 rounded-full transition-all duration-300 shadow-sm",
4538
+ {
4539
+ "left-0.5 bg-secondary-400": currentValue === void 0,
4540
+ "left-5 bg-slate-500": currentValue === true,
4541
+ "left-0.5 bg-secondary-500": currentValue === false
4542
+ }
4543
+ )
4544
+ }
4545
+ ) })
4546
+ }
4547
+ );
4548
+ }
4549
+ if (col.filter === "catalog" && col.catalogOptions) {
4550
+ if (col.catalogOptions.loading) {
4551
+ return /* @__PURE__ */ jsx23(FaSpinner, { className: "animate-spin", "aria-label": "Cargando opciones", title: "Cargando opciones" });
4552
+ }
4553
+ if (col.catalogOptions.error) {
4554
+ return /* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-danger-500 text-xs", children: "Error cargando" });
4555
+ }
4556
+ return /* @__PURE__ */ jsx23(
4557
+ ITSelect,
4558
+ {
4559
+ name: `filter-${col.key}`,
4560
+ options: [
4561
+ { value: "", label: "Todos" },
4562
+ ...col.catalogOptions.data.map((item) => ({
4563
+ value: String(item.id),
4564
+ label: item.name
4565
+ }))
4566
+ ],
4567
+ value: String(filters[col.key] || ""),
4568
+ onChange: (e) => {
4569
+ const value = e.target.value === "" ? void 0 : e.target.value;
4570
+ handleFilterChange(col.key, value);
4571
+ },
4572
+ onBlur: () => {
4573
+ },
4574
+ className: "w-full text-xs",
4575
+ disabled: isLoading
4576
+ }
4577
+ );
4578
+ }
4579
+ if (col.filter === "search" && col.catalogOptions) {
4580
+ if (col.catalogOptions.loading) {
4581
+ return /* @__PURE__ */ jsx23(FaSpinner, { className: "animate-spin", "aria-label": "Cargando opciones", title: "Cargando opciones" });
4582
+ }
4583
+ if (col.catalogOptions.error) {
4584
+ return /* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-danger-500 text-xs", children: "Error cargando" });
4585
+ }
4586
+ const searchValue = filters[col.key];
4587
+ return /* @__PURE__ */ jsx23(
4588
+ ITSearchSelect,
4589
+ {
4590
+ name: `filter-${col.key}`,
4591
+ options: col.catalogOptions.data.map((item) => ({
4592
+ value: item.id,
4593
+ label: item.name
4594
+ })),
4595
+ value: typeof searchValue === "string" || typeof searchValue === "number" ? searchValue : "",
4596
+ onChange: (value) => handleFilterChange(col.key, value === "" ? void 0 : value),
4597
+ onSearch: col.catalogOptions.onSearch,
4598
+ isLoading: col.catalogOptions.loading,
4599
+ size: "sm",
4600
+ placeholder: "Buscar...",
4601
+ clearable: true,
4602
+ className: "w-full",
4603
+ onBlur: () => {
4604
+ },
4605
+ disabled: isLoading
4606
+ }
4607
+ );
4608
+ }
4609
+ if (col.filter === "date") {
4610
+ const dateValue = filters[col.key];
4611
+ return /* @__PURE__ */ jsx23(
4612
+ ITDatePicker,
4613
+ {
4614
+ name: `filter-${col.key}`,
4615
+ value: dateValue instanceof Date ? dateValue : void 0,
4616
+ onChange: (e) => handleFilterChange(col.key, e.target.value),
4617
+ minDate: col.dateFilterOptions?.minDate,
4618
+ maxDate: col.dateFilterOptions?.maxDate,
4619
+ size: "sm",
4620
+ placeholder: "dd/mm/aaaa",
4621
+ className: "w-full",
4622
+ disabled: isLoading
4623
+ }
4624
+ );
4625
+ }
4626
+ if (col.filter === "date-range") {
4627
+ const rangeValue = filters[col.key];
4628
+ return /* @__PURE__ */ jsx23(
4629
+ ITDatePicker,
4630
+ {
4631
+ name: `filter-${col.key}`,
4632
+ range: true,
4633
+ value: Array.isArray(rangeValue) ? rangeValue : void 0,
4634
+ onChange: (e) => handleFilterChange(col.key, e.target.value),
4635
+ minDate: col.dateFilterOptions?.minDate,
4636
+ maxDate: col.dateFilterOptions?.maxDate,
4637
+ size: "sm",
4638
+ placeholder: "dd/mm/aaaa - dd/mm/aaaa",
4639
+ className: "w-full",
4640
+ disabled: isLoading
4641
+ }
4642
+ );
4643
+ }
4644
+ return /* @__PURE__ */ jsx23(
4645
+ ITInput,
4646
+ {
4647
+ name: `filter-${col.key}`,
4648
+ className: "w-full text-xs",
4649
+ placeholder: "Buscar...",
4650
+ value: String(filters[col.key] || ""),
4651
+ onChange: (e) => handleFilterChange(col.key, e.target.value),
4652
+ onBlur: () => {
4653
+ },
4654
+ disabled: isLoading
4655
+ }
4656
+ );
4657
+ };
4658
+ const renderCellContent = (col, row) => {
4659
+ const value = getNestedValue2(row, col.key);
4660
+ if (col.render) return col.render(row);
4661
+ switch (col.type) {
4662
+ case "number":
4663
+ return typeof value === "number" && col.currencyMX ? formatCurrencyMX(value) : value;
4664
+ case "boolean":
4665
+ return value ? /* @__PURE__ */ jsx23(FaCheck2, { className: "text-success-500", "aria-label": "Verdadero", title: "Verdadero" }) : /* @__PURE__ */ jsx23(FaTimes5, { className: "text-danger-500", "aria-label": "Falso", title: "Falso" });
4666
+ case "actions":
4667
+ return col.actions ? col.actions(row) : null;
4668
+ case "catalog":
4669
+ if (col.catalogOptions) {
4670
+ const catalogItem = col.catalogOptions.data.find((item) => item.id === value);
4671
+ return catalogItem?.name || value;
4672
+ }
4673
+ return value;
4674
+ default:
4675
+ return value;
4676
+ }
4677
+ };
4678
+ const renderDefaultCard = (row) => {
4679
+ const dataCols = columns.filter((c) => c.type !== "actions");
4680
+ const actionCol = columns.find((c) => c.type === "actions");
4681
+ return /* @__PURE__ */ jsxs20("div", { className: "bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700 p-3 space-y-2 shadow-sm", children: [
4682
+ dataCols.map((col) => /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between gap-2", children: [
4683
+ /* @__PURE__ */ jsx23("span", { className: "text-[10px] font-bold uppercase tracking-wider text-slate-400 whitespace-nowrap flex-shrink-0 min-w-[70px]", children: col.label }),
4684
+ /* @__PURE__ */ jsx23("span", { className: "text-sm font-medium text-slate-800 dark:text-white text-right truncate", children: renderCellContent(col, row) })
4685
+ ] }, col.key)),
4686
+ actionCol?.actions && /* @__PURE__ */ jsx23("div", { className: "flex items-center justify-end gap-2 pt-2 border-t border-slate-100 dark:border-slate-700", children: actionCol.actions(row) })
4687
+ ] });
4688
+ };
4689
+ const segCtrlClass = (mode) => `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${effectiveView === mode ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`;
4690
+ const handleRowClick = (row) => (event) => {
4691
+ if (!onRowClick || isLoading || isInteractiveTarget(event.target, event.currentTarget)) return;
4692
+ onRowClick(row, event);
4693
+ };
4694
+ const handleRowKeyDown = (row) => (event) => {
4695
+ if (!onRowClick || isLoading) return;
4696
+ if (event.target !== event.currentTarget) return;
4697
+ if (event.key !== "Enter" && event.key !== " ") return;
4698
+ event.preventDefault();
4699
+ onRowClick(row, event);
4700
+ };
4701
+ const tableEl = /* @__PURE__ */ jsxs20(
4702
+ "table",
4703
+ {
4704
+ className: clsx23(
4705
+ tableLayoutClass,
4706
+ showVerticalBorder && "[&_th]:border-r [&_th:last-child]:border-r-0 [&_td]:border-r [&_td:last-child]:border-r-0",
4707
+ showVerticalBorder && (verticalBorderClassname || "[&_th]:border-slate-100 dark:[&_th]:border-slate-700/30 [&_td]:border-slate-100 dark:[&_td]:border-slate-700/30"),
4708
+ isLoading ? "opacity-50" : "opacity-100",
4709
+ variantStyles[variant],
4710
+ sizeStyles[size],
4711
+ className
4712
+ ),
4713
+ style: isFixed ? { tableLayout: "fixed" } : void 0,
4714
+ "aria-rowcount": isTableVirtual ? data.length + 1 : void 0,
4715
+ children: [
4716
+ hasColumnWidths && /* @__PURE__ */ jsx23("colgroup", { children: columns.map((col) => /* @__PURE__ */ jsx23(
4717
+ "col",
4718
+ {
4719
+ style: col.width != null ? { width: typeof col.width === "number" ? `${col.width}px` : col.width } : void 0
4720
+ },
4721
+ col.key
4722
+ )) }),
4723
+ /* @__PURE__ */ jsx23("thead", { children: /* @__PURE__ */ jsx23(
4724
+ "tr",
4725
+ {
4726
+ className: clsx23(tableHeaderRow, "dark:text-slate-200"),
4727
+ "aria-rowindex": isTableVirtual ? 1 : void 0,
4728
+ children: columns.map((col) => /* @__PURE__ */ jsx23(
4729
+ "th",
4730
+ {
4731
+ scope: "col",
4732
+ className: clsx23(
4733
+ tableHeaderCell(col.className, density),
4734
+ col.align && tableAlignClasses[col.align],
4735
+ isStickyHeader && "sticky top-0 z-10 bg-secondary-50"
4736
+ ),
4737
+ style: col.minWidth != null || isStickyHeader ? {
4738
+ ...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
4739
+ ...isStickyHeader ? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" } : {}
4740
+ } : void 0,
4741
+ children: /* @__PURE__ */ jsxs20("div", { className: isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]", children: [
4742
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between gap-2", children: [
4743
+ /* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
4744
+ col.sortable && col.type !== "actions" && /* @__PURE__ */ jsx23(
4745
+ "button",
4746
+ {
4747
+ onClick: () => handleSort(col.key),
4748
+ disabled: isLoading,
4749
+ className: `p-1 rounded-md transition-colors ${sortConfig?.key === col.key ? "bg-secondary-200 text-secondary-900" : "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"} disabled:opacity-50`,
4750
+ title: `Ordenar por ${col.label}`,
4751
+ children: /* @__PURE__ */ jsx23(MdOutlineSwapVert, { className: "w-4 h-4", "aria-hidden": "true" })
4752
+ }
4753
+ )
4754
+ ] }),
4755
+ /* @__PURE__ */ jsx23("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
4756
+ ] })
4757
+ },
4758
+ col.key
4759
+ ))
4760
+ }
4761
+ ) }),
4762
+ /* @__PURE__ */ jsx23("tbody", { className: clsx23(tableBody, "dark:divide-slate-700/30"), children: data.length > 0 ? /* @__PURE__ */ jsxs20(Fragment4, { children: [
4763
+ isTableVirtual && topSpacerHeight > 0 && /* @__PURE__ */ jsx23("tr", { "aria-hidden": "true", style: { height: topSpacerHeight }, children: /* @__PURE__ */ jsx23("td", { colSpan: columnCount, style: { padding: 0, border: 0 } }) }),
4764
+ windowData.map((row, windowIndex) => {
4765
+ const absoluteIndex = isTableVirtual ? startIndex + windowIndex : windowIndex;
4766
+ return /* @__PURE__ */ jsx23(
4767
+ "tr",
4768
+ {
4769
+ "aria-rowindex": isTableVirtual ? absoluteIndex + 2 : void 0,
4770
+ className: clsx23(
4771
+ tableRow,
4772
+ variant === "striped" && absoluteIndex % 2 === 0 && "bg-secondary-50/40 dark:bg-slate-800/20",
4773
+ onRowClick && !isLoading && tableRowClickable
4774
+ ),
4775
+ tabIndex: onRowClick && !isLoading ? 0 : void 0,
4776
+ onClick: onRowClick && !isLoading ? handleRowClick(row) : void 0,
4777
+ onKeyDown: onRowClick && !isLoading ? handleRowKeyDown(row) : void 0,
4778
+ children: columns.map((col) => {
4779
+ const rawValue = getNestedValue2(row, col.key);
4780
+ const truncateTitle = col.truncate && (typeof rawValue === "string" || typeof rawValue === "number") ? String(rawValue) : void 0;
4781
+ return /* @__PURE__ */ jsx23(
4782
+ "td",
4783
+ {
4784
+ className: clsx23(
4785
+ tableCell(col.className, density),
4786
+ col.align && tableAlignClasses[col.align]
4787
+ ),
4788
+ style: col.minWidth != null ? { minWidth: `${col.minWidth}px` } : void 0,
4789
+ title: truncateTitle,
4790
+ children: col.type === "actions" ? /* @__PURE__ */ jsx23("div", { className: tableActionsCell, children: renderCellContent(col, row) }) : /* @__PURE__ */ jsx23("div", { className: clsx23(tableCellText, col.truncate && "truncate"), children: renderCellContent(col, row) })
4791
+ },
4792
+ `${absoluteIndex}-${col.key}`
4793
+ );
4794
+ })
4795
+ },
4796
+ absoluteIndex
4797
+ );
4798
+ }),
4799
+ isTableVirtual && bottomSpacerHeight > 0 && /* @__PURE__ */ jsx23("tr", { "aria-hidden": "true", style: { height: bottomSpacerHeight }, children: /* @__PURE__ */ jsx23("td", { colSpan: columnCount, style: { padding: 0, border: 0 } }) })
4800
+ ] }) : /* @__PURE__ */ jsx23("tr", { children: /* @__PURE__ */ jsx23("td", { colSpan: columns.length, className: "px-6 py-12 text-center", children: !isLoading && /* @__PURE__ */ jsxs20("div", { className: tableEmptyContent, children: [
4801
+ /* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
4802
+ /* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
4803
+ ] }) }) }) })
4804
+ ]
4805
+ }
4806
+ );
4807
+ return /* @__PURE__ */ jsxs20("div", { ref: rootRef, className: clsx23("space-y-4 w-full relative", containerClassName), children: [
4808
+ /* @__PURE__ */ jsxs20("div", { className: tableContainer, style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
4809
+ title && /* @__PURE__ */ jsxs20("div", { className: "px-6 py-5 flex items-center justify-between", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
4810
+ /* @__PURE__ */ jsx23(ITText, { as: "h2", className: "text-xl font-bold text-secondary-900 leading-tight", children: title }),
4811
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-3", children: [
4812
+ isLoading && /* @__PURE__ */ jsx23("div", { className: "text-secondary-400", children: loadingIndicator || /* @__PURE__ */ jsx23(FaSpinner, { className: "animate-spin text-primary-500 text-xl" }) }),
4813
+ /* @__PURE__ */ jsxs20("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", children: [
4814
+ /* @__PURE__ */ jsxs20("button", { onClick: () => setViewMode("table"), disabled: forcedCards, className: segCtrlClass("table"), children: [
4815
+ /* @__PURE__ */ jsx23(FaTable, { size: 11 }),
4816
+ "Table"
4817
+ ] }),
4818
+ /* @__PURE__ */ jsxs20("button", { onClick: () => setViewMode("cards"), className: segCtrlClass("cards"), children: [
4819
+ /* @__PURE__ */ jsx23(FaThLarge, { size: 11 }),
4820
+ "Cards"
4821
+ ] })
4822
+ ] })
4823
+ ] })
4824
+ ] }),
4825
+ !title && /* @__PURE__ */ jsx23("div", { className: "flex justify-end px-4 pt-3", children: /* @__PURE__ */ jsxs20("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", children: [
4826
+ /* @__PURE__ */ jsxs20("button", { onClick: () => setViewMode("table"), disabled: forcedCards, className: segCtrlClass("table"), children: [
4827
+ /* @__PURE__ */ jsx23(FaTable, { size: 11 }),
4828
+ "Table"
4829
+ ] }),
4830
+ /* @__PURE__ */ jsxs20("button", { onClick: () => setViewMode("cards"), className: segCtrlClass("cards"), children: [
4831
+ /* @__PURE__ */ jsx23(FaThLarge, { size: 11 }),
4832
+ "Cards"
4833
+ ] })
4834
+ ] }) }),
4835
+ /* @__PURE__ */ jsxs20("div", { className: scrollOuterClass, children: [
4836
+ isLoading && /* @__PURE__ */ jsx23("div", { className: "absolute inset-0 z-20 flex items-center justify-center bg-white/40 backdrop-blur-[2px] transition-all duration-300", children: /* @__PURE__ */ jsx23("div", { className: "flex flex-col items-center gap-3 p-6 rounded-2xl shadow-xl border border-secondary-100 animate-in fade-in zoom-in duration-300", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: loadingIndicator || /* @__PURE__ */ jsxs20(Fragment4, { children: [
4837
+ /* @__PURE__ */ jsx23(FaSpinner, { className: "animate-spin text-primary-500 text-4xl" }),
4838
+ /* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-sm font-semibold text-secondary-600 animate-pulse", children: "Cargando datos..." })
4839
+ ] }) }) }),
4840
+ effectiveView === "cards" ? /* @__PURE__ */ jsx23("div", { className: "p-4 space-y-3 max-h-[400px] overflow-y-auto", children: data.length > 0 ? data.map((row, i) => /* @__PURE__ */ jsx23(
4841
+ "div",
4842
+ {
4843
+ className: clsx23(tableCardHover, onRowClick && !isLoading && tableCardClickable),
4844
+ role: onRowClick && !isLoading ? "button" : void 0,
4845
+ tabIndex: onRowClick && !isLoading ? 0 : void 0,
4846
+ onClick: onRowClick && !isLoading ? handleRowClick(row) : void 0,
4847
+ onKeyDown: onRowClick && !isLoading ? handleRowKeyDown(row) : void 0,
4848
+ children: renderCard ? renderCard(row) : renderDefaultCard(row)
4849
+ },
4850
+ i
4851
+ )) : !isLoading && /* @__PURE__ */ jsxs20("div", { className: clsx23(tableEmptyContent, "py-12"), children: [
4852
+ /* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
4853
+ /* @__PURE__ */ jsx23(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
4854
+ ] }) }) : isTableVirtual ? /* @__PURE__ */ jsx23(
4855
+ "div",
4856
+ {
4857
+ ref: scrollRef,
4858
+ className: "overflow-x-auto overflow-y-auto",
4859
+ style: { maxHeight: virtualizedMaxHeight },
4860
+ children: tableEl
4861
+ }
4862
+ ) : tableEl
4863
+ ] })
4864
+ ] }),
4865
+ /* @__PURE__ */ jsx23("div", { className: "rounded-b-xl px-6 py-4", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: /* @__PURE__ */ jsx23(
4866
+ ITPagination,
4867
+ {
4868
+ currentPage,
4869
+ totalPages: computedTotalPages,
4870
+ onPageChange: goToPage,
4871
+ color: "primary",
4872
+ itemsPerPageOptions,
4873
+ itemsPerPage,
4874
+ onItemsPerPageChange: handleItemsPerPageChange,
4875
+ totalItems
4876
+ }
4877
+ ) })
4878
+ ] });
4879
+ }
4880
+
4881
+ // src/components/organisms/dialog/dialog.tsx
4882
+ import { createPortal as createPortal5 } from "react-dom";
4883
+ import { useEffect as useEffect10, useRef as useRef14 } from "react";
4583
4884
  import { FaRegTimesCircle } from "react-icons/fa";
4584
4885
 
4585
4886
  // src/components/molecules/form-header/form-header.tsx
4586
- import { FaTimes as FaTimes5 } from "react-icons/fa";
4887
+ import { FaTimes as FaTimes6 } from "react-icons/fa";
4587
4888
 
4588
4889
  // src/theme/theme-context.ts
4589
4890
  import { createContext, useContext } from "react";
@@ -4676,7 +4977,7 @@ var getContrastTextColor = (bgColor, palette2, isDarkMode) => {
4676
4977
  };
4677
4978
 
4678
4979
  // src/components/molecules/form-header/form-header.tsx
4679
- import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
4980
+ import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
4680
4981
  function ITFormHeader({
4681
4982
  title,
4682
4983
  onClose,
@@ -4690,23 +4991,23 @@ function ITFormHeader({
4690
4991
  palette2,
4691
4992
  isDarkMode
4692
4993
  );
4693
- return /* @__PURE__ */ jsxs20("div", { className: `bg-primary-500 ${textColorClass} px-6 py-4 rounded-t-lg flex justify-center items-center relative ${className}`, children: [
4694
- /* @__PURE__ */ jsx23(ITText, { as: "h2", className: "text-lg font-semibold text-center", style: { color: "inherit" }, children: title }),
4695
- onClose && /* @__PURE__ */ jsx23(
4994
+ return /* @__PURE__ */ jsxs21("div", { className: `bg-primary-500 ${textColorClass} px-6 py-4 rounded-t-lg flex justify-center items-center relative ${className}`, children: [
4995
+ /* @__PURE__ */ jsx24(ITText, { as: "h2", className: "text-lg font-semibold text-center", style: { color: "inherit" }, children: title }),
4996
+ onClose && /* @__PURE__ */ jsx24(
4696
4997
  "button",
4697
4998
  {
4698
4999
  onClick: onClose,
4699
5000
  className: `absolute right-4 ${textColorClass} hover:opacity-80 transition-colors duration-200 p-1 rounded-full`,
4700
5001
  style: { color: "inherit" },
4701
5002
  "aria-label": "Cerrar",
4702
- children: /* @__PURE__ */ jsx23(FaTimes5, { className: "w-4 h-4" })
5003
+ children: /* @__PURE__ */ jsx24(FaTimes6, { className: "w-4 h-4" })
4703
5004
  }
4704
5005
  )
4705
5006
  ] });
4706
5007
  }
4707
5008
 
4708
5009
  // src/components/organisms/dialog/dialog.tsx
4709
- import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
5010
+ import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
4710
5011
  function ITDialog({
4711
5012
  isOpen,
4712
5013
  onClose,
@@ -4716,9 +5017,9 @@ function ITDialog({
4716
5017
  useFormHeader = false,
4717
5018
  fullScreen = false
4718
5019
  }) {
4719
- const modalRef = useRef13(null);
5020
+ const modalRef = useRef14(null);
4720
5021
  useClickOutside_default(modalRef, onClose);
4721
- useEffect9(() => {
5022
+ useEffect10(() => {
4722
5023
  const handleEscape = (event) => {
4723
5024
  if (event.key === "Escape") {
4724
5025
  onClose();
@@ -4733,12 +5034,12 @@ function ITDialog({
4733
5034
  }, [isOpen, onClose]);
4734
5035
  if (!isOpen) return null;
4735
5036
  if (typeof document === "undefined") return null;
4736
- const content = /* @__PURE__ */ jsx24(
5037
+ const content = /* @__PURE__ */ jsx25(
4737
5038
  "div",
4738
5039
  {
4739
5040
  "data-it-dialog": "true",
4740
5041
  className: `fixed inset-0 flex ${fullScreen ? "items-stretch" : "items-center justify-center"} bg-slate-900/50 z-[60]`,
4741
- children: /* @__PURE__ */ jsx24(
5042
+ children: /* @__PURE__ */ jsx25(
4742
5043
  "div",
4743
5044
  {
4744
5045
  ref: modalRef,
@@ -4751,41 +5052,41 @@ function ITDialog({
4751
5052
  borderColor: theme.card.borderColor,
4752
5053
  borderStyle: "solid"
4753
5054
  },
4754
- children: useFormHeader && title ? /* @__PURE__ */ jsxs21(Fragment5, { children: [
4755
- /* @__PURE__ */ jsx24(ITFormHeader, { title, onClose }),
4756
- /* @__PURE__ */ jsx24("div", { className: fullScreen ? "flex-1 overflow-auto p-6" : "p-6", children })
4757
- ] }) : /* @__PURE__ */ jsxs21(Fragment5, { children: [
4758
- /* @__PURE__ */ jsx24(
5055
+ children: useFormHeader && title ? /* @__PURE__ */ jsxs22(Fragment5, { children: [
5056
+ /* @__PURE__ */ jsx25(ITFormHeader, { title, onClose }),
5057
+ /* @__PURE__ */ jsx25("div", { className: fullScreen ? "flex-1 overflow-auto p-6" : "p-6", children })
5058
+ ] }) : /* @__PURE__ */ jsxs22(Fragment5, { children: [
5059
+ /* @__PURE__ */ jsx25(
4759
5060
  "button",
4760
5061
  {
4761
5062
  className: "absolute top-2 right-2 text-secondary-600 hover:text-secondary-900",
4762
5063
  onClick: onClose,
4763
- children: /* @__PURE__ */ jsx24(FaRegTimesCircle, {})
5064
+ children: /* @__PURE__ */ jsx25(FaRegTimesCircle, {})
4764
5065
  }
4765
5066
  ),
4766
- title && /* @__PURE__ */ jsx24(ITText, { as: "h2", className: "text-xl font-semibold mb-4", children: title }),
4767
- /* @__PURE__ */ jsx24("div", { children })
5067
+ title && /* @__PURE__ */ jsx25(ITText, { as: "h2", className: "text-xl font-semibold mb-4", children: title }),
5068
+ /* @__PURE__ */ jsx25("div", { children })
4768
5069
  ] })
4769
5070
  }
4770
5071
  )
4771
5072
  }
4772
5073
  );
4773
- return createPortal4(content, document.body);
5074
+ return createPortal5(content, document.body);
4774
5075
  }
4775
5076
 
4776
5077
  // src/components/atoms/divider/divider.tsx
4777
- import clsx23 from "clsx";
4778
- import { jsx as jsx25 } from "react/jsx-runtime";
5078
+ import clsx24 from "clsx";
5079
+ import { jsx as jsx26 } from "react/jsx-runtime";
4779
5080
  function ITDivider({
4780
5081
  orientation = "horizontal",
4781
5082
  className,
4782
5083
  color = "bg-slate-200 dark:bg-slate-700",
4783
5084
  thickness = orientation === "horizontal" ? "h-px" : "w-px"
4784
5085
  }) {
4785
- return /* @__PURE__ */ jsx25(
5086
+ return /* @__PURE__ */ jsx26(
4786
5087
  "div",
4787
5088
  {
4788
- className: clsx23(
5089
+ className: clsx24(
4789
5090
  "flex-shrink-0",
4790
5091
  orientation === "horizontal" ? "w-full" : "self-stretch",
4791
5092
  thickness,
@@ -4797,10 +5098,10 @@ function ITDivider({
4797
5098
  }
4798
5099
 
4799
5100
  // src/components/organisms/drawer/drawer.tsx
4800
- import clsx24 from "clsx";
4801
- import { FaTimes as FaTimes6 } from "react-icons/fa";
4802
- import { useRef as useRef14 } from "react";
4803
- import { Fragment as Fragment6, jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
5101
+ import clsx25 from "clsx";
5102
+ import { FaTimes as FaTimes7 } from "react-icons/fa";
5103
+ import { useRef as useRef15 } from "react";
5104
+ import { Fragment as Fragment6, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
4804
5105
  function ITDrawer({
4805
5106
  isOpen,
4806
5107
  onClose,
@@ -4811,15 +5112,15 @@ function ITDrawer({
4811
5112
  className,
4812
5113
  style
4813
5114
  }) {
4814
- const panelRef = useRef14(null);
5115
+ const panelRef = useRef15(null);
4815
5116
  useClickOutside_default(panelRef, onClose);
4816
- return /* @__PURE__ */ jsx26(Fragment6, { children: isOpen && /* @__PURE__ */ jsxs22("div", { className: "fixed inset-0 z-[50] flex", children: [
4817
- /* @__PURE__ */ jsx26("div", { className: "absolute inset-0 bg-black/40 backdrop-blur-sm transition-opacity" }),
4818
- /* @__PURE__ */ jsxs22(
5117
+ return /* @__PURE__ */ jsx27(Fragment6, { children: isOpen && /* @__PURE__ */ jsxs23("div", { className: "fixed inset-0 z-[50] flex", children: [
5118
+ /* @__PURE__ */ jsx27("div", { className: "absolute inset-0 bg-black/40 backdrop-blur-sm transition-opacity" }),
5119
+ /* @__PURE__ */ jsxs23(
4819
5120
  "div",
4820
5121
  {
4821
5122
  ref: panelRef,
4822
- className: clsx24(
5123
+ className: clsx25(
4823
5124
  "relative z-10 h-full bg-white dark:bg-slate-900 shadow-2xl flex flex-col transition-transform duration-300",
4824
5125
  position === "right" ? "ml-auto" : "mr-auto",
4825
5126
  size,
@@ -4827,18 +5128,18 @@ function ITDrawer({
4827
5128
  ),
4828
5129
  style,
4829
5130
  children: [
4830
- title && /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-slate-700", children: [
4831
- /* @__PURE__ */ jsx26(ITText, { as: "h2", className: "text-lg font-bold text-slate-800 dark:text-white", children: title }),
4832
- /* @__PURE__ */ jsx26(
5131
+ title && /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-slate-700", children: [
5132
+ /* @__PURE__ */ jsx27(ITText, { as: "h2", className: "text-lg font-bold text-slate-800 dark:text-white", children: title }),
5133
+ /* @__PURE__ */ jsx27(
4833
5134
  "button",
4834
5135
  {
4835
5136
  onClick: onClose,
4836
5137
  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",
4837
- children: /* @__PURE__ */ jsx26(FaTimes6, { size: 14 })
5138
+ children: /* @__PURE__ */ jsx27(FaTimes7, { size: 14 })
4838
5139
  }
4839
5140
  )
4840
5141
  ] }),
4841
- /* @__PURE__ */ jsx26("div", { className: "flex-1 overflow-y-auto p-5", children })
5142
+ /* @__PURE__ */ jsx27("div", { className: "flex-1 overflow-y-auto p-5", children })
4842
5143
  ]
4843
5144
  }
4844
5145
  )
@@ -4846,27 +5147,27 @@ function ITDrawer({
4846
5147
  }
4847
5148
 
4848
5149
  // src/components/molecules/empty-state/empty-state.tsx
4849
- import clsx25 from "clsx";
5150
+ import clsx26 from "clsx";
4850
5151
  import { FaInbox } from "react-icons/fa";
4851
- import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
5152
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
4852
5153
  function ITEmptyState({
4853
- icon = /* @__PURE__ */ jsx27(FaInbox, { size: 40 }),
5154
+ icon = /* @__PURE__ */ jsx28(FaInbox, { size: 40 }),
4854
5155
  title,
4855
5156
  description,
4856
5157
  action,
4857
5158
  className
4858
5159
  }) {
4859
- return /* @__PURE__ */ jsxs23("div", { className: clsx25("flex flex-col items-center justify-center py-16 px-6 text-center", className), children: [
4860
- /* @__PURE__ */ jsx27("div", { className: "text-slate-300 dark:text-slate-600 mb-4", children: icon }),
4861
- /* @__PURE__ */ jsx27(ITText, { as: "h3", className: "text-lg font-bold text-slate-700 dark:text-slate-200 mb-1", children: title }),
4862
- description && /* @__PURE__ */ jsx27(ITText, { as: "p", className: "text-sm text-slate-400 dark:text-slate-500 max-w-sm mb-4", children: description }),
4863
- action && /* @__PURE__ */ jsx27("div", { children: action })
5160
+ return /* @__PURE__ */ jsxs24("div", { className: clsx26("flex flex-col items-center justify-center py-16 px-6 text-center", className), children: [
5161
+ /* @__PURE__ */ jsx28("div", { className: "text-slate-300 dark:text-slate-600 mb-4", children: icon }),
5162
+ /* @__PURE__ */ jsx28(ITText, { as: "h3", className: "text-lg font-bold text-slate-700 dark:text-slate-200 mb-1", children: title }),
5163
+ description && /* @__PURE__ */ jsx28(ITText, { as: "p", className: "text-sm text-slate-400 dark:text-slate-500 max-w-sm mb-4", children: description }),
5164
+ action && /* @__PURE__ */ jsx28("div", { children: action })
4864
5165
  ] });
4865
5166
  }
4866
5167
 
4867
5168
  // src/components/atoms/flex/flex.tsx
4868
- import clsx26 from "clsx";
4869
- import { jsx as jsx28 } from "react/jsx-runtime";
5169
+ import clsx27 from "clsx";
5170
+ import { jsx as jsx29 } from "react/jsx-runtime";
4870
5171
  var directionMap = {
4871
5172
  row: "flex-row",
4872
5173
  column: "flex-col",
@@ -4915,10 +5216,10 @@ function ITFlex({
4915
5216
  flexBasis: typeof basis === "number" ? `${basis * 0.25}rem` : basis,
4916
5217
  ...style
4917
5218
  };
4918
- return /* @__PURE__ */ jsx28(
5219
+ return /* @__PURE__ */ jsx29(
4919
5220
  Component,
4920
5221
  {
4921
- className: clsx26(
5222
+ className: clsx27(
4922
5223
  "flex",
4923
5224
  directionMap[direction],
4924
5225
  align && alignMap[align],
@@ -4937,33 +5238,33 @@ function ITFlex({
4937
5238
  import { useMemo as useMemo10 } from "react";
4938
5239
 
4939
5240
  // src/components/organisms/form-builder/formBuilder.context.tsx
4940
- import React6, { createContext as createContext2, useContext as useContext2, useState as useState19 } from "react";
4941
- import { jsx as jsx29 } from "react/jsx-runtime";
5241
+ import React7, { createContext as createContext2, useContext as useContext2, useState as useState20 } from "react";
5242
+ import { jsx as jsx30 } from "react/jsx-runtime";
4942
5243
  var ITFormBuilderContext = createContext2(void 0);
4943
5244
  var ITFormBuilderProvider = ({
4944
5245
  children,
4945
5246
  value
4946
5247
  }) => {
4947
- const [fieldRegistry, setFieldRegistry] = useState19({});
4948
- const registerField = React6.useCallback((name, config2) => {
5248
+ const [fieldRegistry, setFieldRegistry] = useState20({});
5249
+ const registerField = React7.useCallback((name, config2) => {
4949
5250
  setFieldRegistry((prev) => ({ ...prev, [name]: config2 }));
4950
5251
  }, []);
4951
- const unregisterField = React6.useCallback((name) => {
5252
+ const unregisterField = React7.useCallback((name) => {
4952
5253
  setFieldRegistry((prev) => {
4953
5254
  const next = { ...prev };
4954
5255
  delete next[name];
4955
5256
  return next;
4956
5257
  });
4957
5258
  }, []);
4958
- const getFieldConfig = React6.useCallback(
5259
+ const getFieldConfig = React7.useCallback(
4959
5260
  (name) => fieldRegistry[name],
4960
5261
  [fieldRegistry]
4961
5262
  );
4962
- const getAllFieldConfigs = React6.useCallback(
5263
+ const getAllFieldConfigs = React7.useCallback(
4963
5264
  () => Object.values(fieldRegistry),
4964
5265
  [fieldRegistry]
4965
5266
  );
4966
- const contextValue = React6.useMemo(
5267
+ const contextValue = React7.useMemo(
4967
5268
  () => ({
4968
5269
  ...value,
4969
5270
  registerField,
@@ -4973,7 +5274,7 @@ var ITFormBuilderProvider = ({
4973
5274
  }),
4974
5275
  [value, registerField, unregisterField, getFieldConfig, getAllFieldConfigs]
4975
5276
  );
4976
- return /* @__PURE__ */ jsx29(ITFormBuilderContext.Provider, { value: contextValue, children });
5277
+ return /* @__PURE__ */ jsx30(ITFormBuilderContext.Provider, { value: contextValue, children });
4977
5278
  };
4978
5279
  var useITFormBuilderContext = () => {
4979
5280
  const context = useContext2(ITFormBuilderContext);
@@ -4988,11 +5289,11 @@ import { memo, useCallback as useCallback8, useEffect as useEffect12, useMemo as
4988
5289
  import clsx29 from "clsx";
4989
5290
 
4990
5291
  // src/components/molecules/time-picker/timePicker.tsx
4991
- import clsx27 from "clsx";
4992
- import { useEffect as useEffect10, useRef as useRef15, useState as useState20 } from "react";
4993
- import { createPortal as createPortal5 } from "react-dom";
5292
+ import clsx28 from "clsx";
5293
+ import { useEffect as useEffect11, useRef as useRef16, useState as useState21 } from "react";
5294
+ import { createPortal as createPortal6 } from "react-dom";
4994
5295
  import { FaClock } from "react-icons/fa";
4995
- import { jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
5296
+ import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
4996
5297
  function ITTimePicker({
4997
5298
  name,
4998
5299
  value,
@@ -5009,12 +5310,12 @@ function ITTimePicker({
5009
5310
  variant = "primary",
5010
5311
  color = "primary"
5011
5312
  }) {
5012
- const [isOpen, setIsOpen] = useState20(false);
5013
- const [inputValue, setInputValue] = useState20(value || "");
5014
- const [isValidTime, setIsValidTime] = useState20(true);
5015
- const wrapperRef = useRef15(null);
5016
- const hoursRef = useRef15(null);
5017
- const minutesRef = useRef15(null);
5313
+ const [isOpen, setIsOpen] = useState21(false);
5314
+ const [inputValue, setInputValue] = useState21(value || "");
5315
+ const [isValidTime, setIsValidTime] = useState21(true);
5316
+ const wrapperRef = useRef16(null);
5317
+ const hoursRef = useRef16(null);
5318
+ const minutesRef = useRef16(null);
5018
5319
  const { panelRef: dropdownRef, style: panelStyle } = useFloatingPanel(
5019
5320
  wrapperRef,
5020
5321
  isOpen && !disabled,
@@ -5028,7 +5329,7 @@ function ITTimePicker({
5028
5329
  const isThemeColor = color in theme.colors;
5029
5330
  const highlightColor = isThemeColor ? theme.colors[color][50] : "#f3f4f6";
5030
5331
  const activeColor = isThemeColor ? theme.colors[color][100] : "#e5e7eb";
5031
- useEffect10(() => {
5332
+ useEffect11(() => {
5032
5333
  setInputValue(value || "");
5033
5334
  }, [value]);
5034
5335
  const validateTime = (timeString) => {
@@ -5037,7 +5338,7 @@ function ITTimePicker({
5037
5338
  };
5038
5339
  const currentHour = validateTime(inputValue) ? inputValue.split(":")[0] : null;
5039
5340
  const currentMinute = validateTime(inputValue) ? inputValue.split(":")[1] : null;
5040
- useEffect10(() => {
5341
+ useEffect11(() => {
5041
5342
  if (isOpen) {
5042
5343
  setTimeout(() => {
5043
5344
  if (hoursRef.current && currentHour) {
@@ -5107,8 +5408,8 @@ function ITTimePicker({
5107
5408
  { length: 60 },
5108
5409
  (_, i) => i.toString().padStart(2, "0")
5109
5410
  );
5110
- return /* @__PURE__ */ jsxs24("div", { ref: wrapperRef, className: clsx27("relative w-full", className), children: [
5111
- /* @__PURE__ */ jsx30(
5411
+ return /* @__PURE__ */ jsxs25("div", { ref: wrapperRef, className: clsx28("relative w-full", className), children: [
5412
+ /* @__PURE__ */ jsx31(
5112
5413
  ITInput,
5113
5414
  {
5114
5415
  name,
@@ -5125,7 +5426,7 @@ function ITTimePicker({
5125
5426
  size,
5126
5427
  touched,
5127
5428
  error: !isValidTime ? "Hora inv\xE1lida" : typeof error === "string" ? error : void 0,
5128
- iconRight: /* @__PURE__ */ jsx30(
5429
+ iconRight: /* @__PURE__ */ jsx31(
5129
5430
  FaClock,
5130
5431
  {
5131
5432
  onClick: () => {
@@ -5133,7 +5434,7 @@ function ITTimePicker({
5133
5434
  setIsOpen(!isOpen);
5134
5435
  }
5135
5436
  },
5136
- className: clsx27(
5437
+ className: clsx28(
5137
5438
  "cursor-pointer transition-colors",
5138
5439
  disabled ? "text-slate-400 cursor-not-allowed" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"
5139
5440
  )
@@ -5141,31 +5442,31 @@ function ITTimePicker({
5141
5442
  )
5142
5443
  }
5143
5444
  ),
5144
- isOpen && !disabled && createPortal5(
5145
- /* @__PURE__ */ jsxs24(
5445
+ isOpen && !disabled && createPortal6(
5446
+ /* @__PURE__ */ jsxs25(
5146
5447
  "div",
5147
5448
  {
5148
5449
  ref: dropdownRef,
5149
5450
  className: "bg-white border border-secondary-100 shadow-xl rounded-xl w-64 overflow-hidden flex flex-col animate-in fade-in zoom-in-95 duration-200 origin-top it-timepicker-dropdown",
5150
5451
  style: panelStyle,
5151
5452
  children: [
5152
- /* @__PURE__ */ jsxs24("div", { className: "flex bg-secondary-50 border-b border-secondary-100 text-xs font-semibold text-secondary-500 uppercase tracking-wider", children: [
5153
- /* @__PURE__ */ jsx30(ITText, { as: "div", className: "flex-1 text-center py-2 border-r border-secondary-100", children: "Horas" }),
5154
- /* @__PURE__ */ jsx30(ITText, { as: "div", className: "flex-1 text-center py-2", children: "Minutos" })
5453
+ /* @__PURE__ */ jsxs25("div", { className: "flex bg-secondary-50 border-b border-secondary-100 text-xs font-semibold text-secondary-500 uppercase tracking-wider", children: [
5454
+ /* @__PURE__ */ jsx31(ITText, { as: "div", className: "flex-1 text-center py-2 border-r border-secondary-100", children: "Horas" }),
5455
+ /* @__PURE__ */ jsx31(ITText, { as: "div", className: "flex-1 text-center py-2", children: "Minutos" })
5155
5456
  ] }),
5156
- /* @__PURE__ */ jsxs24("div", { className: "flex h-56 relative bg-white", children: [
5157
- /* @__PURE__ */ jsx30(
5457
+ /* @__PURE__ */ jsxs25("div", { className: "flex h-56 relative bg-white", children: [
5458
+ /* @__PURE__ */ jsx31(
5158
5459
  "div",
5159
5460
  {
5160
5461
  ref: hoursRef,
5161
5462
  className: "flex-1 overflow-y-auto no-scrollbar border-r border-secondary-50 scroll-smooth relative",
5162
- children: /* @__PURE__ */ jsx30("div", { className: "py-2", children: hoursList.map((h) => {
5463
+ children: /* @__PURE__ */ jsx31("div", { className: "py-2", children: hoursList.map((h) => {
5163
5464
  const isSelected = currentHour === h;
5164
- return /* @__PURE__ */ jsx30(
5465
+ return /* @__PURE__ */ jsx31(
5165
5466
  "div",
5166
5467
  {
5167
5468
  "data-value": h,
5168
- className: clsx27(
5469
+ className: clsx28(
5169
5470
  "text-center py-2 cursor-pointer transition-all duration-200 text-sm font-medium mx-2 rounded-lg my-1",
5170
5471
  isSelected ? "text-slate-900 shadow-sm" : "text-slate-600 hover:text-slate-900"
5171
5472
  ),
@@ -5188,18 +5489,18 @@ function ITTimePicker({
5188
5489
  }) })
5189
5490
  }
5190
5491
  ),
5191
- /* @__PURE__ */ jsx30(
5492
+ /* @__PURE__ */ jsx31(
5192
5493
  "div",
5193
5494
  {
5194
5495
  ref: minutesRef,
5195
5496
  className: "flex-1 overflow-y-auto no-scrollbar scroll-smooth relative",
5196
- children: /* @__PURE__ */ jsx30("div", { className: "py-2", children: minutesList.map((m) => {
5497
+ children: /* @__PURE__ */ jsx31("div", { className: "py-2", children: minutesList.map((m) => {
5197
5498
  const isSelected = currentMinute === m;
5198
- return /* @__PURE__ */ jsx30(
5499
+ return /* @__PURE__ */ jsx31(
5199
5500
  "div",
5200
5501
  {
5201
5502
  "data-value": m,
5202
- className: clsx27(
5503
+ className: clsx28(
5203
5504
  "text-center py-2 cursor-pointer transition-all duration-200 text-sm font-medium mx-2 rounded-lg my-1",
5204
5505
  isSelected ? "text-slate-900 shadow-sm" : "text-slate-600 hover:text-slate-900"
5205
5506
  ),
@@ -5222,16 +5523,16 @@ function ITTimePicker({
5222
5523
  }) })
5223
5524
  }
5224
5525
  ),
5225
- /* @__PURE__ */ jsx30("div", { className: "absolute top-1/2 left-0 right-0 h-10 -mt-5 bg-black/5 pointer-events-none border-y border-black/10 z-10" })
5526
+ /* @__PURE__ */ jsx31("div", { className: "absolute top-1/2 left-0 right-0 h-10 -mt-5 bg-black/5 pointer-events-none border-y border-black/10 z-10" })
5226
5527
  ] }),
5227
- /* @__PURE__ */ jsx30("div", { className: "p-3 bg-secondary-50 border-t border-secondary-100 flex justify-end", children: /* @__PURE__ */ jsx30(
5528
+ /* @__PURE__ */ jsx31("div", { className: "p-3 bg-secondary-50 border-t border-secondary-100 flex justify-end", children: /* @__PURE__ */ jsx31(
5228
5529
  ITButton,
5229
5530
  {
5230
5531
  variant: "solid",
5231
5532
  color,
5232
5533
  size: "sm",
5233
5534
  onClick: handleConfirm,
5234
- children: /* @__PURE__ */ jsx30(ITText, { as: "span", children: "Aceptar" })
5535
+ children: /* @__PURE__ */ jsx31(ITText, { as: "span", children: "Aceptar" })
5235
5536
  }
5236
5537
  ) })
5237
5538
  ]
@@ -5242,236 +5543,6 @@ function ITTimePicker({
5242
5543
  ] });
5243
5544
  }
5244
5545
 
5245
- // src/components/molecules/search-select/search-select.tsx
5246
- import { useState as useState21, useEffect as useEffect11, useRef as useRef16, useMemo as useMemo7 } from "react";
5247
- import { createPortal as createPortal6 } from "react-dom";
5248
- import clsx28 from "clsx";
5249
- import { FaSearch as FaSearch2, FaTimes as FaTimes7 } from "react-icons/fa";
5250
- import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
5251
- function ITSearchSelect({
5252
- name,
5253
- options = [],
5254
- label,
5255
- placeholder = "Selecciona una opci\xF3n",
5256
- valueField = "value",
5257
- labelField = "label",
5258
- value,
5259
- onChange,
5260
- onBlur,
5261
- disabled = false,
5262
- className,
5263
- touched,
5264
- required,
5265
- error,
5266
- readOnly = false,
5267
- onSearch,
5268
- isLoading = false,
5269
- noResultsMessage = "No se encontraron resultados",
5270
- size = "md",
5271
- renderOption,
5272
- clearable = true,
5273
- onClear
5274
- }) {
5275
- const [isOpen, setIsOpen] = useState21(false);
5276
- const [searchTerm, setSearchTerm] = useState21("");
5277
- const [isFocused, setIsFocused] = useState21(false);
5278
- const [localTouched, setLocalTouched] = useState21(false);
5279
- const containerRef = useRef16(null);
5280
- const inputWrapperRef = useRef16(null);
5281
- const timeoutRef = useRef16(null);
5282
- const { panelRef, style: panelStyle } = useFloatingPanel(inputWrapperRef, isOpen, {
5283
- estimatedHeight: 260,
5284
- matchWidth: true
5285
- });
5286
- const selectedOption = useMemo7(() => {
5287
- return options.find((opt) => opt[valueField] === value);
5288
- }, [options, value, valueField]);
5289
- useEffect11(() => {
5290
- if (!isFocused) {
5291
- setSearchTerm(selectedOption ? String(selectedOption[labelField]) : "");
5292
- }
5293
- }, [selectedOption, isFocused, labelField]);
5294
- useEffect11(() => {
5295
- function handleClickOutside(event) {
5296
- const target = event.target;
5297
- const inContainer = containerRef.current?.contains(target);
5298
- const inPanel = panelRef.current?.contains(target);
5299
- if (!inContainer && !inPanel) {
5300
- setIsOpen(false);
5301
- }
5302
- }
5303
- document.addEventListener("mousedown", handleClickOutside);
5304
- return () => document.removeEventListener("mousedown", handleClickOutside);
5305
- }, []);
5306
- const selectedLabel = selectedOption ? String(selectedOption[labelField]) : "";
5307
- const filteredOptions = useMemo7(() => {
5308
- if (onSearch) return options;
5309
- if (!searchTerm || !isFocused || searchTerm === selectedLabel) return options;
5310
- return options.filter(
5311
- (opt) => String(opt[labelField]).toLowerCase().includes(searchTerm.toLowerCase())
5312
- );
5313
- }, [options, searchTerm, selectedLabel, onSearch, labelField, isFocused]);
5314
- const handleInputChange = (e) => {
5315
- const query = e.target.value;
5316
- setSearchTerm(query);
5317
- setIsOpen(true);
5318
- if (onSearch) {
5319
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
5320
- timeoutRef.current = setTimeout(() => {
5321
- onSearch(query);
5322
- }, 500);
5323
- }
5324
- };
5325
- const handleSelect = (option) => {
5326
- if (onChange) {
5327
- onChange(option[valueField], option);
5328
- }
5329
- setSearchTerm(String(option[labelField]));
5330
- setIsOpen(false);
5331
- };
5332
- const handleClear = () => {
5333
- setSearchTerm("");
5334
- setIsOpen(true);
5335
- if (onSearch) onSearch("");
5336
- if (value !== void 0 && value !== null && value !== "") {
5337
- onChange?.("", void 0);
5338
- }
5339
- onClear?.();
5340
- };
5341
- const handleFocus = () => {
5342
- if (disabled || readOnly) return;
5343
- setIsFocused(true);
5344
- setIsOpen(true);
5345
- };
5346
- const handleInputBlur = (e) => {
5347
- setTimeout(() => {
5348
- setIsFocused(false);
5349
- setLocalTouched(true);
5350
- onBlur?.(e);
5351
- }, 200);
5352
- };
5353
- const inputTheme = theme.input || {};
5354
- const isTouched = touched !== void 0 ? touched : localTouched;
5355
- const isEmpty = value === void 0 || value === null || String(value).trim() === "";
5356
- const effectiveError = error !== void 0 && error !== false ? error === true ? "Este campo es requerido" : error : required && isEmpty ? "Este campo es requerido" : void 0;
5357
- const hasError = isTouched && !!effectiveError;
5358
- const errorMessage = typeof effectiveError === "string" ? effectiveError : "Este campo es requerido";
5359
- const showClearButton = clearable && !disabled && !readOnly && (searchTerm.length > 0 || !isEmpty);
5360
- const getInputStyle = () => {
5361
- const sizeConfig = inputSizeTokens[size] ?? inputSizeTokens.md;
5362
- const style = {
5363
- backgroundColor: inputTheme.backgroundColor || "#ffffff",
5364
- borderColor: inputTheme.borderColor || "var(--color-secondary-300)",
5365
- borderRadius: inputTheme.borderRadius || "0.5rem",
5366
- padding: sizeConfig.padding,
5367
- fontSize: sizeConfig.fontSize,
5368
- borderWidth: "1px",
5369
- borderStyle: "solid",
5370
- transition: "all 0.2s",
5371
- color: "var(--it-input-text-color, var(--color-secondary-900))",
5372
- width: "100%"
5373
- };
5374
- if (disabled) {
5375
- style.backgroundColor = inputTheme.disabled?.backgroundColor || "var(--color-secondary-100)";
5376
- style.borderColor = inputTheme.disabled?.borderColor || "var(--color-secondary-200)";
5377
- style.opacity = 0.7;
5378
- style.cursor = "not-allowed";
5379
- }
5380
- if (hasError) {
5381
- style.borderColor = inputTheme.error?.borderColor || "red";
5382
- if (isFocused) {
5383
- style.boxShadow = inputTheme.error?.ring;
5384
- }
5385
- } else if (isFocused && !readOnly) {
5386
- style.boxShadow = inputTheme.focus?.ring;
5387
- style.borderColor = inputTheme.focus?.borderColor;
5388
- }
5389
- return style;
5390
- };
5391
- return /* @__PURE__ */ jsxs25("div", { className: clsx28("w-full flex flex-col gap-1.5", className, isOpen && "relative z-30"), ref: containerRef, children: [
5392
- label && /* @__PURE__ */ jsxs25(
5393
- ITText,
5394
- {
5395
- as: "label",
5396
- className: clsx28("text-sm font-medium text-secondary-700 dark:text-slate-300", {
5397
- "text-danger-500": hasError
5398
- }),
5399
- children: [
5400
- /* @__PURE__ */ jsx31(ITText, { as: "span", children: label }),
5401
- required && /* @__PURE__ */ jsx31(ITText, { as: "span", className: "text-danger-500 ml-1", children: "*" })
5402
- ]
5403
- }
5404
- ),
5405
- /* @__PURE__ */ jsxs25("div", { className: "relative", children: [
5406
- /* @__PURE__ */ jsxs25("div", { ref: inputWrapperRef, className: "relative flex items-center", children: [
5407
- /* @__PURE__ */ jsx31(
5408
- "input",
5409
- {
5410
- type: "text",
5411
- name,
5412
- value: searchTerm,
5413
- onChange: handleInputChange,
5414
- onFocus: handleFocus,
5415
- onBlur: handleInputBlur,
5416
- disabled,
5417
- readOnly,
5418
- placeholder,
5419
- className: "outline-none pr-10",
5420
- style: getInputStyle(),
5421
- autoComplete: "off"
5422
- }
5423
- ),
5424
- /* @__PURE__ */ jsxs25("div", { className: "absolute right-3 flex items-center gap-2 text-secondary-400", children: [
5425
- isLoading && /* @__PURE__ */ jsx31("div", { className: "pointer-events-none animate-spin h-4 w-4 border-2 border-primary-500 border-t-transparent rounded-full" }),
5426
- !isLoading && showClearButton && /* @__PURE__ */ jsx31(
5427
- "button",
5428
- {
5429
- type: "button",
5430
- "aria-label": "Limpiar",
5431
- title: "Limpiar",
5432
- onMouseDown: (e) => {
5433
- e.preventDefault();
5434
- handleClear();
5435
- },
5436
- className: "flex items-center justify-center text-secondary-400 hover:text-secondary-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-400 rounded-full",
5437
- children: /* @__PURE__ */ jsx31(FaTimes7, { size: 14 })
5438
- }
5439
- ),
5440
- !isLoading && !showClearButton && /* @__PURE__ */ jsx31(FaSearch2, { size: 14, className: clsx28("pointer-events-none", { "text-primary-500": isFocused }) })
5441
- ] })
5442
- ] }),
5443
- isOpen && createPortal6(
5444
- /* @__PURE__ */ jsx31(
5445
- "div",
5446
- {
5447
- ref: panelRef,
5448
- style: panelStyle,
5449
- className: "bg-white dark:bg-slate-900 border border-secondary-200 dark:border-slate-800 rounded-lg shadow-xl overflow-hidden animate-in fade-in zoom-in duration-200 origin-top",
5450
- children: /* @__PURE__ */ jsx31("div", { className: "max-h-60 overflow-y-auto", children: filteredOptions.length > 0 ? filteredOptions.map((option) => {
5451
- const isSelected = value === option[valueField];
5452
- return /* @__PURE__ */ jsx31(
5453
- ITText,
5454
- {
5455
- as: "div",
5456
- onClick: () => handleSelect(option),
5457
- className: clsx28(
5458
- "px-4 py-2 text-sm cursor-pointer transition-colors",
5459
- isSelected ? "bg-primary-50 dark:bg-primary-950/40 text-primary-700 dark:text-primary-300 font-medium" : "hover:bg-secondary-50 dark:hover:bg-slate-800 text-secondary-700 dark:text-slate-300"
5460
- ),
5461
- children: renderOption ? renderOption(option, { isSelected, searchTerm }) : /* @__PURE__ */ jsx31(ITText, { as: "span", children: option[labelField] })
5462
- },
5463
- option[valueField]
5464
- );
5465
- }) : /* @__PURE__ */ jsx31(ITText, { as: "div", className: "px-4 py-6 text-sm text-center text-secondary-500 italic", children: isLoading ? "Cargando..." : noResultsMessage }) })
5466
- }
5467
- ),
5468
- document.body
5469
- )
5470
- ] }),
5471
- hasError && /* @__PURE__ */ jsx31(ITText, { as: "p", className: "text-danger-500 text-xs mt-1", children: errorMessage })
5472
- ] });
5473
- }
5474
-
5475
5546
  // src/components/organisms/form-builder/useFormBuilder.ts
5476
5547
  import { useMemo as useMemo8 } from "react";
5477
5548
  var useFieldRules = (config2, dependentValues) => {
@@ -7904,6 +7975,7 @@ import {
7904
7975
  FaThLarge as FaThLarge2
7905
7976
  } from "react-icons/fa";
7906
7977
  import { MdOutlineSwapVert as MdOutlineSwapVert2 } from "react-icons/md";
7978
+ import { isSameDay as isSameDay2, startOfDay as startOfDay2, endOfDay } from "date-fns";
7907
7979
  import { Fragment as Fragment9, jsx as jsx59, jsxs as jsxs46 } from "react/jsx-runtime";
7908
7980
  function ITTable({
7909
7981
  columns,
@@ -7987,15 +8059,32 @@ function ITTable({
7987
8059
  }, [data, sortConfig, columns]);
7988
8060
  const filteredData = sortedData.filter(
7989
8061
  (row) => columns.every((col) => {
7990
- if (!col.filter || filters[col.key] === void 0 || filters[col.key] === "")
8062
+ const rawFilter = filters[col.key];
8063
+ if (!col.filter || rawFilter === void 0 || rawFilter === "") return true;
8064
+ if (Array.isArray(rawFilter) && rawFilter[0] == null && rawFilter[1] == null) {
7991
8065
  return true;
8066
+ }
7992
8067
  const value = getNestedValue(row, col.key);
7993
- const filterValue = String(filters[col.key]).toLowerCase();
8068
+ if (col.filter === "date" || col.filter === "date-range") {
8069
+ const rowDate = value instanceof Date ? value : new Date(String(value));
8070
+ if (isNaN(rowDate.getTime())) return false;
8071
+ if (col.filter === "date") {
8072
+ return isSameDay2(rowDate, rawFilter);
8073
+ }
8074
+ const [start, end] = rawFilter;
8075
+ if (start && rowDate.getTime() < startOfDay2(start).getTime()) return false;
8076
+ if (end && rowDate.getTime() > endOfDay(end).getTime()) return false;
8077
+ return true;
8078
+ }
8079
+ if (col.filter === "search") {
8080
+ return String(value) === String(rawFilter);
8081
+ }
8082
+ const filterValue = String(rawFilter).toLowerCase();
7994
8083
  switch (col.type) {
7995
8084
  case "number":
7996
8085
  return String(value).includes(filterValue);
7997
8086
  case "boolean":
7998
- return value === filters[col.key];
8087
+ return value === rawFilter;
7999
8088
  case "catalog": {
8000
8089
  if (!col.catalogOptions) return true;
8001
8090
  const catalogItem = col.catalogOptions.data.find(
@@ -8101,6 +8190,75 @@ function ITTable({
8101
8190
  }
8102
8191
  );
8103
8192
  }
8193
+ if (col.filter === "search" && col.catalogOptions) {
8194
+ if (col.catalogOptions.loading) {
8195
+ return /* @__PURE__ */ jsx59(
8196
+ FaSpinner3,
8197
+ {
8198
+ className: "animate-spin",
8199
+ "aria-label": "Cargando opciones",
8200
+ title: "Cargando opciones"
8201
+ }
8202
+ );
8203
+ }
8204
+ if (col.catalogOptions.error) {
8205
+ return /* @__PURE__ */ jsx59(ITText, { as: "span", className: "text-danger-500 text-xs", children: "Error cargando" });
8206
+ }
8207
+ const searchValue = filters[col.key];
8208
+ return /* @__PURE__ */ jsx59(
8209
+ ITSearchSelect,
8210
+ {
8211
+ name: `filter-${col.key}`,
8212
+ options: col.catalogOptions.data.map((item) => ({
8213
+ value: item.id,
8214
+ label: item.name
8215
+ })),
8216
+ value: typeof searchValue === "string" || typeof searchValue === "number" ? searchValue : "",
8217
+ onChange: (value) => handleFilterChange(col.key, value === "" ? void 0 : value),
8218
+ onSearch: col.catalogOptions.onSearch,
8219
+ isLoading: col.catalogOptions.loading,
8220
+ size: "sm",
8221
+ placeholder: "Buscar...",
8222
+ clearable: true,
8223
+ className: "w-full",
8224
+ onBlur: () => {
8225
+ }
8226
+ }
8227
+ );
8228
+ }
8229
+ if (col.filter === "date") {
8230
+ const dateValue = filters[col.key];
8231
+ return /* @__PURE__ */ jsx59(
8232
+ ITDatePicker,
8233
+ {
8234
+ name: `filter-${col.key}`,
8235
+ value: dateValue instanceof Date ? dateValue : void 0,
8236
+ onChange: (e) => handleFilterChange(col.key, e.target.value),
8237
+ minDate: col.dateFilterOptions?.minDate,
8238
+ maxDate: col.dateFilterOptions?.maxDate,
8239
+ size: "sm",
8240
+ placeholder: "dd/mm/aaaa",
8241
+ className: "w-full"
8242
+ }
8243
+ );
8244
+ }
8245
+ if (col.filter === "date-range") {
8246
+ const rangeValue = filters[col.key];
8247
+ return /* @__PURE__ */ jsx59(
8248
+ ITDatePicker,
8249
+ {
8250
+ name: `filter-${col.key}`,
8251
+ range: true,
8252
+ value: Array.isArray(rangeValue) ? rangeValue : void 0,
8253
+ onChange: (e) => handleFilterChange(col.key, e.target.value),
8254
+ minDate: col.dateFilterOptions?.minDate,
8255
+ maxDate: col.dateFilterOptions?.maxDate,
8256
+ size: "sm",
8257
+ placeholder: "dd/mm/aaaa - dd/mm/aaaa",
8258
+ className: "w-full"
8259
+ }
8260
+ );
8261
+ }
8104
8262
  return /* @__PURE__ */ jsx59(
8105
8263
  ITInput,
8106
8264
  {
@@ -8231,7 +8389,7 @@ function ITTable({
8231
8389
  effectiveView === "cards" ? /* @__PURE__ */ jsx59("div", { className: "p-4 space-y-3 max-h-[400px] overflow-y-auto", children: currentData.length > 0 ? currentData.map((row, i) => /* @__PURE__ */ jsx59(
8232
8390
  "div",
8233
8391
  {
8234
- className: clsx43(onRowClick && tableCardClickable),
8392
+ className: clsx43(tableCardHover, onRowClick && tableCardClickable),
8235
8393
  role: onRowClick ? "button" : void 0,
8236
8394
  tabIndex: onRowClick ? 0 : void 0,
8237
8395
  onClick: onRowClick ? handleRowClick(row) : void 0,
@@ -10178,8 +10336,10 @@ var DEFAULT_PALETTE = {
10178
10336
  // Slate-700
10179
10337
  rowBg: "#ffffff",
10180
10338
  // White
10181
- rowText: "#1e293b"
10339
+ rowText: "#1e293b",
10182
10340
  // Slate-800
10341
+ rowHover: "#f1f5f9"
10342
+ // Slate-100
10183
10343
  }
10184
10344
  };
10185
10345
  var PRESETS = [
@@ -10204,7 +10364,8 @@ var PRESETS = [
10204
10364
  headerBg: "#f1f5f9",
10205
10365
  headerText: "#334155",
10206
10366
  rowBg: "#ffffff",
10207
- rowText: "#0f172a"
10367
+ rowText: "#0f172a",
10368
+ rowHover: "#1e293b"
10208
10369
  }
10209
10370
  }
10210
10371
  },
@@ -10229,7 +10390,8 @@ var PRESETS = [
10229
10390
  headerBg: "#fff1f2",
10230
10391
  headerText: "#881337",
10231
10392
  rowBg: "#ffffff",
10232
- rowText: "#1c1212"
10393
+ rowText: "#1c1212",
10394
+ rowHover: "#fff1f2"
10233
10395
  }
10234
10396
  }
10235
10397
  },
@@ -10254,7 +10416,8 @@ var PRESETS = [
10254
10416
  headerBg: "#f0fdfa",
10255
10417
  headerText: "#115e59",
10256
10418
  rowBg: "#ffffff",
10257
- rowText: "#042f2e"
10419
+ rowText: "#042f2e",
10420
+ rowHover: "#f0fdfa"
10258
10421
  }
10259
10422
  }
10260
10423
  },
@@ -10279,7 +10442,8 @@ var PRESETS = [
10279
10442
  headerBg: "#fefce8",
10280
10443
  headerText: "#713f12",
10281
10444
  rowBg: "#ffffff",
10282
- rowText: "#292524"
10445
+ rowText: "#292524",
10446
+ rowHover: "#fefce8"
10283
10447
  }
10284
10448
  }
10285
10449
  },
@@ -10304,7 +10468,8 @@ var PRESETS = [
10304
10468
  headerBg: "#f0fdf4",
10305
10469
  headerText: "#166534",
10306
10470
  rowBg: "#ffffff",
10307
- rowText: "#052e16"
10471
+ rowText: "#052e16",
10472
+ rowHover: "#f0fdf4"
10308
10473
  }
10309
10474
  }
10310
10475
  }
@@ -10584,6 +10749,7 @@ function ITThemeProvider({
10584
10749
  let tableRowText = palette2.table.rowText;
10585
10750
  let tableHeaderBg = palette2.table.headerBg;
10586
10751
  let tableHeaderText = palette2.table.headerText;
10752
+ let tableRowHover = palette2.table.rowHover;
10587
10753
  let navbarBg = palette2.layout.navbarBg;
10588
10754
  let navbarText = palette2.layout.navbarText;
10589
10755
  let sidebarBg = palette2.layout.sidebarBg;
@@ -10601,6 +10767,9 @@ function ITThemeProvider({
10601
10767
  if (!isLightColor2(tableHeaderText)) {
10602
10768
  tableHeaderText = `color-mix(in srgb, ${palette2.table.headerText} 20%, #f9fafb)`;
10603
10769
  }
10770
+ if (isLightColor2(tableRowHover)) {
10771
+ tableRowHover = `color-mix(in srgb, ${palette2.table.rowHover} 12%, #1f2937)`;
10772
+ }
10604
10773
  if (isLightColor2(navbarBg)) {
10605
10774
  navbarBg = `color-mix(in srgb, ${palette2.layout.navbarBg} 8%, #111827)`;
10606
10775
  }
@@ -10626,7 +10795,10 @@ function ITThemeProvider({
10626
10795
  }
10627
10796
  if (isLightColor2(tableHeaderText)) {
10628
10797
  tableHeaderText = `color-mix(in srgb, ${palette2.table.headerText} 30%, #334155)`;
10629
- } else if (!isLightColor2(tableHeaderText) && isVeryDarkColor(palette2.table.headerText)) {
10798
+ } else if (!isLightColor2(tableHeaderText) && isVeryDarkColor(tableHeaderText)) {
10799
+ }
10800
+ if (!isLightColor2(tableRowHover)) {
10801
+ tableRowHover = isVeryDarkColor(palette2.table.rowHover) ? "#f1f5f9" : `color-mix(in srgb, ${palette2.table.rowHover} 12%, #f8fafc)`;
10630
10802
  }
10631
10803
  if (!isLightColor2(navbarBg)) {
10632
10804
  navbarBg = isVeryDarkColor(palette2.layout.navbarBg) ? "#ffffff" : `color-mix(in srgb, ${palette2.layout.navbarBg} 8%, #ffffff)`;
@@ -10836,6 +11008,7 @@ function ITThemeProvider({
10836
11008
  --color-table-headerText: ${tableHeaderText} !important;
10837
11009
  --color-table-rowBg: ${tableRowBg} !important;
10838
11010
  --color-table-rowText: ${tableRowText} !important;
11011
+ --color-table-rowHover: ${tableRowHover} !important;
10839
11012
 
10840
11013
  /* Native library variables integration */
10841
11014
  --it-sidebar-bg: var(--color-sidebarBg);
@@ -11179,7 +11352,7 @@ function ITThemeProvider({
11179
11352
  color: var(--color-table-rowText) !important;
11180
11353
  }
11181
11354
  tbody tr:hover {
11182
- background-color: color-mix(in srgb, var(--color-primary) 8%, var(--color-table-rowBg)) !important;
11355
+ background-color: var(--color-table-rowHover) !important;
11183
11356
  }
11184
11357
 
11185
11358
  /* Animation for Saved Indicator */
@@ -11941,7 +12114,8 @@ function ITThemeProvider({
11941
12114
  "table.headerBg",
11942
12115
  "table.headerText",
11943
12116
  "table.rowBg",
11944
- "table.rowText"
12117
+ "table.rowText",
12118
+ "table.rowHover"
11945
12119
  ].map((key) => /* @__PURE__ */ jsx71(ColorRow, { colorKey: key }, key)) })
11946
12120
  }
11947
12121
  ]