pixelon 0.3.23 → 0.3.25

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
@@ -1641,6 +1641,130 @@ function parseContent(content) {
1641
1641
 
1642
1642
  const DISPLAY_COMPONENTS = /* @__PURE__ */ new Set(["card", "badge"]);
1643
1643
 
1644
+ const useAppHeight$5 = () => {
1645
+ React.useEffect(() => {
1646
+ const setDrawerHeight = () => {
1647
+ const fullViewportHeight = window.innerHeight;
1648
+ const documentHeight = document.documentElement.clientHeight;
1649
+ const drawerHeight = Math.max(fullViewportHeight, documentHeight);
1650
+ document.documentElement.style.setProperty(
1651
+ "--app-height",
1652
+ `${drawerHeight}px`
1653
+ );
1654
+ document.documentElement.style.setProperty(
1655
+ "--drawer-height",
1656
+ `${drawerHeight}px`
1657
+ );
1658
+ document.documentElement.style.setProperty(
1659
+ "--viewport-height",
1660
+ `${fullViewportHeight}px`
1661
+ );
1662
+ };
1663
+ setDrawerHeight();
1664
+ window.addEventListener("resize", setDrawerHeight);
1665
+ window.addEventListener("orientationchange", setDrawerHeight);
1666
+ document.addEventListener("fullscreenchange", setDrawerHeight);
1667
+ return () => {
1668
+ window.removeEventListener("resize", setDrawerHeight);
1669
+ window.removeEventListener("orientationchange", setDrawerHeight);
1670
+ document.removeEventListener("fullscreenchange", setDrawerHeight);
1671
+ };
1672
+ }, []);
1673
+ };
1674
+
1675
+ const Drawer$1 = ({
1676
+ isOpen,
1677
+ onClose,
1678
+ children,
1679
+ title,
1680
+ headerExtra,
1681
+ footer,
1682
+ showCloseButton = true,
1683
+ closeOnOverlayClick = true,
1684
+ closeOnEscape = true,
1685
+ className = ""
1686
+ }) => {
1687
+ const [visible, setVisible] = React.useState(false);
1688
+ const [animating, setAnimating] = React.useState(false);
1689
+ const contentRef = React.useRef(null);
1690
+ useAppHeight$5();
1691
+ React.useEffect(() => {
1692
+ if (isOpen) {
1693
+ setVisible(true);
1694
+ requestAnimationFrame(() => {
1695
+ requestAnimationFrame(() => setAnimating(true));
1696
+ });
1697
+ } else {
1698
+ setAnimating(false);
1699
+ const timer = setTimeout(() => setVisible(false), 300);
1700
+ return () => clearTimeout(timer);
1701
+ }
1702
+ }, [isOpen]);
1703
+ React.useEffect(() => {
1704
+ if (isOpen) {
1705
+ document.body.style.overflow = "hidden";
1706
+ return () => {
1707
+ document.body.style.overflow = "";
1708
+ };
1709
+ }
1710
+ }, [isOpen]);
1711
+ React.useEffect(() => {
1712
+ if (!isOpen || !closeOnEscape) return;
1713
+ const handleEscape = (e) => {
1714
+ if (e.key === "Escape") onClose();
1715
+ };
1716
+ document.addEventListener("keydown", handleEscape);
1717
+ return () => document.removeEventListener("keydown", handleEscape);
1718
+ }, [isOpen, onClose, closeOnEscape]);
1719
+ const handleOverlayClick = React.useCallback((e) => {
1720
+ if (e.target === e.currentTarget && closeOnOverlayClick) {
1721
+ onClose();
1722
+ }
1723
+ }, [onClose, closeOnOverlayClick]);
1724
+ if (!visible) return null;
1725
+ const prefix = COMPONENT_PREFIX$1;
1726
+ const overlayClasses = [
1727
+ `${prefix}drawer-overlay`,
1728
+ animating && `${prefix}drawer-overlay--visible`
1729
+ ].filter(Boolean).join(" ");
1730
+ const drawerClasses = [
1731
+ `${prefix}drawer`,
1732
+ animating && `${prefix}drawer--open`,
1733
+ className
1734
+ ].filter(Boolean).join(" ");
1735
+ return ReactDOM.createPortal(
1736
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: overlayClasses, onClick: handleOverlayClick, children: /* @__PURE__ */ jsxRuntime.jsxs(
1737
+ "div",
1738
+ {
1739
+ className: drawerClasses,
1740
+ role: "dialog",
1741
+ "aria-modal": "true",
1742
+ "aria-labelledby": title ? `${prefix}drawer-title` : void 0,
1743
+ children: [
1744
+ (title || showCloseButton || headerExtra) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${prefix}drawer__header`, children: [
1745
+ title && /* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${prefix}drawer-title`, className: `${prefix}drawer__title`, children: title }),
1746
+ headerExtra && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${prefix}drawer__header-extra`, children: headerExtra }),
1747
+ showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
1748
+ "button",
1749
+ {
1750
+ type: "button",
1751
+ className: `${prefix}drawer__close`,
1752
+ onClick: onClose,
1753
+ "aria-label": "Cerrar",
1754
+ children: "\u2715"
1755
+ }
1756
+ )
1757
+ ] }),
1758
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: contentRef, className: `${prefix}drawer__content`, children }),
1759
+ footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${prefix}drawer__footer`, children: footer })
1760
+ ]
1761
+ }
1762
+ ) }),
1763
+ document.body
1764
+ );
1765
+ };
1766
+ Drawer$1.displayName = "Drawer";
1767
+
1644
1768
  function createEventBus() {
1645
1769
  const handlers = {};
1646
1770
  let externalBridge = null;
@@ -1671,6 +1795,7 @@ const CHAT_EVENT = {
1671
1795
  RETRY_MESSAGE: "retryMessage",
1672
1796
  PLACEHOLDER_UPDATED: "placeholderUpdated",
1673
1797
  THINKING_UPDATED: "thinkingUpdated",
1798
+ INPUT_DISABLED: "inputDisabled",
1674
1799
  CLOSE: "close"
1675
1800
  };
1676
1801
  const chatEventBus = createEventBus();
@@ -1698,20 +1823,167 @@ function useComponentInteraction({
1698
1823
  return { emitInteraction, isConfirmed };
1699
1824
  }
1700
1825
 
1826
+ const MOBILE_BREAKPOINT$3 = 640;
1827
+ const useIsMobile$4 = () => {
1828
+ const [isMobile, setIsMobile] = React.useState(
1829
+ typeof window !== "undefined" ? window.innerWidth < MOBILE_BREAKPOINT$3 : false
1830
+ );
1831
+ React.useEffect(() => {
1832
+ const mq = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT$3 - 1}px)`);
1833
+ const handler = (e) => setIsMobile(e.matches);
1834
+ mq.addEventListener("change", handler);
1835
+ return () => mq.removeEventListener("change", handler);
1836
+ }, []);
1837
+ return isMobile;
1838
+ };
1701
1839
  const SelectWithConfirm = ({
1702
1840
  component,
1703
1841
  eventBus,
1704
1842
  assistantMessageId = ""
1705
1843
  }) => {
1706
1844
  const [selected, setSelected] = React.useState(null);
1845
+ const [isDrawerOpen, setIsDrawerOpen] = React.useState(false);
1846
+ const [searchValue, setSearchValue] = React.useState("");
1847
+ const searchInputRef = React.useRef(null);
1848
+ const isMobile = useIsMobile$4();
1707
1849
  const { field_name, value, ...componentProps } = component.props;
1850
+ const options = componentProps.options || [];
1851
+ const placeholder = componentProps.placeholder || "Seleccionar...";
1852
+ const label = componentProps.label || "";
1708
1853
  const { emitInteraction, isConfirmed } = useComponentInteraction({
1709
1854
  eventBus,
1710
1855
  fieldName: component.props.field_name,
1711
1856
  componentType: component.type,
1712
1857
  assistantMessageId
1713
1858
  });
1859
+ const handleConfirm = () => {
1860
+ if (selected) {
1861
+ emitInteraction(selected.value, selected.label);
1862
+ setIsDrawerOpen(false);
1863
+ }
1864
+ };
1865
+ const filteredOptions = searchValue ? options.filter((opt) => opt.label.toLowerCase().includes(searchValue.toLowerCase())) : options;
1866
+ React.useEffect(() => {
1867
+ if (isDrawerOpen && searchInputRef.current) {
1868
+ setTimeout(() => searchInputRef.current?.focus(), 350);
1869
+ }
1870
+ }, [isDrawerOpen]);
1714
1871
  if (isConfirmed) return null;
1872
+ if (isMobile) {
1873
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-select-with-confirm", children: [
1874
+ label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "px-chat-select-with-confirm__label", children: label }),
1875
+ /* @__PURE__ */ jsxRuntime.jsxs(
1876
+ "div",
1877
+ {
1878
+ className: `px-chat-select-with-confirm__trigger ${isDrawerOpen ? "px-chat-select-with-confirm__trigger--open" : ""}`,
1879
+ onClick: () => setIsDrawerOpen(true),
1880
+ role: "button",
1881
+ tabIndex: 0,
1882
+ onKeyDown: (e) => {
1883
+ if (e.key === "Enter" || e.key === " ") setIsDrawerOpen(true);
1884
+ },
1885
+ children: [
1886
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `px-chat-select-with-confirm__trigger-text ${!selected ? "px-chat-select-with-confirm__trigger-text--placeholder" : ""}`, children: selected ? selected.label : placeholder }),
1887
+ selected && /* @__PURE__ */ jsxRuntime.jsx(
1888
+ "button",
1889
+ {
1890
+ type: "button",
1891
+ className: "px-chat-select-with-confirm__clear",
1892
+ onClick: (e) => {
1893
+ e.stopPropagation();
1894
+ setSelected(null);
1895
+ },
1896
+ "aria-label": "Limpiar selecci\xF3n",
1897
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.CLOSE, size: "small" })
1898
+ }
1899
+ ),
1900
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-select-with-confirm__chevron", children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.CHEVRON_DOWN, size: "small" }) })
1901
+ ]
1902
+ }
1903
+ ),
1904
+ /* @__PURE__ */ jsxRuntime.jsx(
1905
+ Button$1,
1906
+ {
1907
+ variant: "primary",
1908
+ size: "small",
1909
+ disabled: !selected,
1910
+ onClick: handleConfirm,
1911
+ children: "Confirmar"
1912
+ }
1913
+ ),
1914
+ /* @__PURE__ */ jsxRuntime.jsx(
1915
+ Drawer$1,
1916
+ {
1917
+ isOpen: isDrawerOpen,
1918
+ onClose: () => {
1919
+ setIsDrawerOpen(false);
1920
+ setSearchValue("");
1921
+ },
1922
+ title: label || placeholder,
1923
+ footer: /* @__PURE__ */ jsxRuntime.jsx(
1924
+ Button$1,
1925
+ {
1926
+ variant: "primary",
1927
+ size: "medium",
1928
+ disabled: !selected,
1929
+ onClick: handleConfirm,
1930
+ fullWidth: true,
1931
+ children: "Confirmar"
1932
+ }
1933
+ ),
1934
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-select-drawer", children: [
1935
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-select-drawer__search", children: [
1936
+ /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.SEARCH, size: "small" }),
1937
+ /* @__PURE__ */ jsxRuntime.jsx(
1938
+ "input",
1939
+ {
1940
+ ref: searchInputRef,
1941
+ type: "text",
1942
+ className: "px-chat-select-drawer__search-input",
1943
+ value: searchValue,
1944
+ onChange: (e) => setSearchValue(e.target.value),
1945
+ placeholder: "Buscar..."
1946
+ }
1947
+ ),
1948
+ searchValue && /* @__PURE__ */ jsxRuntime.jsx(
1949
+ "button",
1950
+ {
1951
+ type: "button",
1952
+ className: "px-chat-select-drawer__search-clear",
1953
+ onClick: () => setSearchValue(""),
1954
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.CLOSE, size: "small" })
1955
+ }
1956
+ )
1957
+ ] }),
1958
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "px-chat-select-drawer__options", role: "listbox", children: filteredOptions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("li", { className: "px-chat-select-drawer__empty", children: "No hay opciones disponibles" }) : filteredOptions.map((option) => {
1959
+ const isSelected = selected?.value === option.value;
1960
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1961
+ "li",
1962
+ {
1963
+ className: `px-chat-select-drawer__option ${isSelected ? "px-chat-select-drawer__option--selected" : ""} ${option.disabled ? "px-chat-select-drawer__option--disabled" : ""}`,
1964
+ onClick: () => {
1965
+ if (!option.disabled) {
1966
+ setSelected(option);
1967
+ setIsDrawerOpen(false);
1968
+ setSearchValue("");
1969
+ }
1970
+ },
1971
+ role: "option",
1972
+ "aria-selected": isSelected,
1973
+ children: [
1974
+ option.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-select-drawer__option-icon", children: option.icon }),
1975
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-select-drawer__option-label", children: option.label }),
1976
+ isSelected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-select-drawer__option-check", children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.CHECK, size: "small" }) })
1977
+ ]
1978
+ },
1979
+ option.value
1980
+ );
1981
+ }) })
1982
+ ] })
1983
+ }
1984
+ )
1985
+ ] });
1986
+ }
1715
1987
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-select-with-confirm", children: [
1716
1988
  /* @__PURE__ */ jsxRuntime.jsx(
1717
1989
  Select$2,
@@ -1720,6 +1992,7 @@ const SelectWithConfirm = ({
1720
1992
  ...componentProps,
1721
1993
  variant: "chat",
1722
1994
  mode: "single",
1995
+ showSearch: true,
1723
1996
  hideErrorSpace: true,
1724
1997
  allowClear: true,
1725
1998
  onClear: () => setSelected(null),
@@ -1732,27 +2005,185 @@ const SelectWithConfirm = ({
1732
2005
  variant: "primary",
1733
2006
  size: "small",
1734
2007
  disabled: !selected,
1735
- onClick: () => selected && emitInteraction(selected.value, selected.label),
2008
+ onClick: handleConfirm,
1736
2009
  children: "Confirmar"
1737
2010
  }
1738
2011
  )
1739
2012
  ] });
1740
2013
  };
1741
2014
 
2015
+ const MOBILE_BREAKPOINT$2 = 640;
2016
+ const useIsMobile$3 = () => {
2017
+ const [isMobile, setIsMobile] = React.useState(
2018
+ typeof window !== "undefined" ? window.innerWidth < MOBILE_BREAKPOINT$2 : false
2019
+ );
2020
+ React.useEffect(() => {
2021
+ const mq = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT$2 - 1}px)`);
2022
+ const handler = (e) => setIsMobile(e.matches);
2023
+ mq.addEventListener("change", handler);
2024
+ return () => mq.removeEventListener("change", handler);
2025
+ }, []);
2026
+ return isMobile;
2027
+ };
1742
2028
  const SelectMultipleWithConfirm = ({
1743
2029
  component,
1744
2030
  eventBus,
1745
2031
  assistantMessageId = ""
1746
2032
  }) => {
1747
2033
  const [selectedOptions, setSelectedOptions] = React.useState([]);
2034
+ const [isDrawerOpen, setIsDrawerOpen] = React.useState(false);
2035
+ const [searchValue, setSearchValue] = React.useState("");
2036
+ const searchInputRef = React.useRef(null);
2037
+ const isMobile = useIsMobile$3();
1748
2038
  const { field_name, value, ...componentProps } = component.props;
2039
+ const options = componentProps.options || [];
2040
+ const placeholder = componentProps.placeholder || "Seleccionar...";
2041
+ const label = componentProps.label || "";
1749
2042
  const { emitInteraction, isConfirmed } = useComponentInteraction({
1750
2043
  eventBus,
1751
2044
  fieldName: component.props.field_name,
1752
2045
  componentType: component.type,
1753
2046
  assistantMessageId
1754
2047
  });
2048
+ const handleConfirm = () => {
2049
+ if (selectedOptions.length > 0) {
2050
+ emitInteraction(
2051
+ selectedOptions.map((o) => o.value),
2052
+ selectedOptions.map((o) => o.label).join(", ")
2053
+ );
2054
+ setIsDrawerOpen(false);
2055
+ }
2056
+ };
2057
+ const toggleOption = (option) => {
2058
+ if (option.disabled) return;
2059
+ const isSelected = selectedOptions.some((sel) => sel.value === option.value);
2060
+ if (isSelected) {
2061
+ setSelectedOptions(selectedOptions.filter((sel) => sel.value !== option.value));
2062
+ } else {
2063
+ setSelectedOptions([...selectedOptions, option]);
2064
+ }
2065
+ };
2066
+ const filteredOptions = searchValue ? options.filter((opt) => opt.label.toLowerCase().includes(searchValue.toLowerCase())) : options;
2067
+ React.useEffect(() => {
2068
+ if (isDrawerOpen && searchInputRef.current) {
2069
+ setTimeout(() => searchInputRef.current?.focus(), 350);
2070
+ }
2071
+ }, [isDrawerOpen]);
1755
2072
  if (isConfirmed) return null;
2073
+ if (isMobile) {
2074
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-select-with-confirm", children: [
2075
+ label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "px-chat-select-with-confirm__label", children: label }),
2076
+ /* @__PURE__ */ jsxRuntime.jsxs(
2077
+ "div",
2078
+ {
2079
+ className: `px-chat-select-with-confirm__trigger ${isDrawerOpen ? "px-chat-select-with-confirm__trigger--open" : ""}`,
2080
+ onClick: () => setIsDrawerOpen(true),
2081
+ role: "button",
2082
+ tabIndex: 0,
2083
+ onKeyDown: (e) => {
2084
+ if (e.key === "Enter" || e.key === " ") setIsDrawerOpen(true);
2085
+ },
2086
+ children: [
2087
+ selectedOptions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-select-with-confirm__trigger-text px-chat-select-with-confirm__trigger-text--placeholder", children: placeholder }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-select-with-confirm__trigger-tags", children: selectedOptions.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-select-with-confirm__trigger-tag", children: [
2088
+ opt.label,
2089
+ /* @__PURE__ */ jsxRuntime.jsx(
2090
+ "button",
2091
+ {
2092
+ type: "button",
2093
+ className: "px-chat-select-with-confirm__trigger-tag-remove",
2094
+ onClick: (e) => {
2095
+ e.stopPropagation();
2096
+ setSelectedOptions(selectedOptions.filter((s) => s.value !== opt.value));
2097
+ },
2098
+ "aria-label": `Quitar ${opt.label}`,
2099
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.CLOSE, size: "small" })
2100
+ }
2101
+ )
2102
+ ] }, opt.value)) }),
2103
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-select-with-confirm__chevron", children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.CHEVRON_DOWN, size: "small" }) })
2104
+ ]
2105
+ }
2106
+ ),
2107
+ /* @__PURE__ */ jsxRuntime.jsx(
2108
+ Button$1,
2109
+ {
2110
+ variant: "primary",
2111
+ size: "small",
2112
+ disabled: selectedOptions.length === 0,
2113
+ onClick: handleConfirm,
2114
+ children: "Confirmar"
2115
+ }
2116
+ ),
2117
+ /* @__PURE__ */ jsxRuntime.jsx(
2118
+ Drawer$1,
2119
+ {
2120
+ isOpen: isDrawerOpen,
2121
+ onClose: () => {
2122
+ setIsDrawerOpen(false);
2123
+ setSearchValue("");
2124
+ },
2125
+ title: label || placeholder,
2126
+ footer: /* @__PURE__ */ jsxRuntime.jsxs(
2127
+ Button$1,
2128
+ {
2129
+ variant: "primary",
2130
+ size: "medium",
2131
+ disabled: selectedOptions.length === 0,
2132
+ onClick: handleConfirm,
2133
+ fullWidth: true,
2134
+ children: [
2135
+ "Confirmar",
2136
+ selectedOptions.length > 0 ? ` (${selectedOptions.length})` : ""
2137
+ ]
2138
+ }
2139
+ ),
2140
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-select-drawer", children: [
2141
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-select-drawer__search", children: [
2142
+ /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.SEARCH, size: "small" }),
2143
+ /* @__PURE__ */ jsxRuntime.jsx(
2144
+ "input",
2145
+ {
2146
+ ref: searchInputRef,
2147
+ type: "text",
2148
+ className: "px-chat-select-drawer__search-input",
2149
+ value: searchValue,
2150
+ onChange: (e) => setSearchValue(e.target.value),
2151
+ placeholder: "Buscar..."
2152
+ }
2153
+ ),
2154
+ searchValue && /* @__PURE__ */ jsxRuntime.jsx(
2155
+ "button",
2156
+ {
2157
+ type: "button",
2158
+ className: "px-chat-select-drawer__search-clear",
2159
+ onClick: () => setSearchValue(""),
2160
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.CLOSE, size: "small" })
2161
+ }
2162
+ )
2163
+ ] }),
2164
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "px-chat-select-drawer__options", role: "listbox", "aria-multiselectable": "true", children: filteredOptions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("li", { className: "px-chat-select-drawer__empty", children: "No hay opciones disponibles" }) : filteredOptions.map((option) => {
2165
+ const isSelected = selectedOptions.some((sel) => sel.value === option.value);
2166
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2167
+ "li",
2168
+ {
2169
+ className: `px-chat-select-drawer__option ${isSelected ? "px-chat-select-drawer__option--selected" : ""} ${option.disabled ? "px-chat-select-drawer__option--disabled" : ""}`,
2170
+ onClick: () => toggleOption(option),
2171
+ role: "option",
2172
+ "aria-selected": isSelected,
2173
+ children: [
2174
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `px-chat-select-drawer__checkbox ${isSelected ? "px-chat-select-drawer__checkbox--checked" : ""}`, children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.CHECK, size: "small" }) }),
2175
+ option.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-select-drawer__option-icon", children: option.icon }),
2176
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-select-drawer__option-label", children: option.label })
2177
+ ]
2178
+ },
2179
+ option.value
2180
+ );
2181
+ }) })
2182
+ ] })
2183
+ }
2184
+ )
2185
+ ] });
2186
+ }
1756
2187
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-select-with-confirm", children: [
1757
2188
  /* @__PURE__ */ jsxRuntime.jsx(
1758
2189
  Select$2,
@@ -1761,10 +2192,11 @@ const SelectMultipleWithConfirm = ({
1761
2192
  ...componentProps,
1762
2193
  variant: "chat",
1763
2194
  mode: "multiple",
2195
+ showSearch: true,
1764
2196
  hideErrorSpace: true,
1765
2197
  allowClear: true,
1766
2198
  onClear: () => setSelectedOptions([]),
1767
- onChangeMultiple: (_values, options) => setSelectedOptions(options)
2199
+ onChangeMultiple: (_values, opts) => setSelectedOptions(opts)
1768
2200
  }
1769
2201
  ),
1770
2202
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1773,10 +2205,7 @@ const SelectMultipleWithConfirm = ({
1773
2205
  variant: "primary",
1774
2206
  size: "small",
1775
2207
  disabled: selectedOptions.length === 0,
1776
- onClick: () => emitInteraction(
1777
- selectedOptions.map((o) => o.value),
1778
- selectedOptions.map((o) => o.label).join(", ")
1779
- ),
2208
+ onClick: handleConfirm,
1780
2209
  children: "Confirmar"
1781
2210
  }
1782
2211
  )
@@ -1830,130 +2259,6 @@ const InputWithConfirm = ({
1830
2259
  ] });
1831
2260
  };
1832
2261
 
1833
- const useAppHeight$5 = () => {
1834
- React.useEffect(() => {
1835
- const setDrawerHeight = () => {
1836
- const fullViewportHeight = window.innerHeight;
1837
- const documentHeight = document.documentElement.clientHeight;
1838
- const drawerHeight = Math.max(fullViewportHeight, documentHeight);
1839
- document.documentElement.style.setProperty(
1840
- "--app-height",
1841
- `${drawerHeight}px`
1842
- );
1843
- document.documentElement.style.setProperty(
1844
- "--drawer-height",
1845
- `${drawerHeight}px`
1846
- );
1847
- document.documentElement.style.setProperty(
1848
- "--viewport-height",
1849
- `${fullViewportHeight}px`
1850
- );
1851
- };
1852
- setDrawerHeight();
1853
- window.addEventListener("resize", setDrawerHeight);
1854
- window.addEventListener("orientationchange", setDrawerHeight);
1855
- document.addEventListener("fullscreenchange", setDrawerHeight);
1856
- return () => {
1857
- window.removeEventListener("resize", setDrawerHeight);
1858
- window.removeEventListener("orientationchange", setDrawerHeight);
1859
- document.removeEventListener("fullscreenchange", setDrawerHeight);
1860
- };
1861
- }, []);
1862
- };
1863
-
1864
- const Drawer$1 = ({
1865
- isOpen,
1866
- onClose,
1867
- children,
1868
- title,
1869
- headerExtra,
1870
- footer,
1871
- showCloseButton = true,
1872
- closeOnOverlayClick = true,
1873
- closeOnEscape = true,
1874
- className = ""
1875
- }) => {
1876
- const [visible, setVisible] = React.useState(false);
1877
- const [animating, setAnimating] = React.useState(false);
1878
- const contentRef = React.useRef(null);
1879
- useAppHeight$5();
1880
- React.useEffect(() => {
1881
- if (isOpen) {
1882
- setVisible(true);
1883
- requestAnimationFrame(() => {
1884
- requestAnimationFrame(() => setAnimating(true));
1885
- });
1886
- } else {
1887
- setAnimating(false);
1888
- const timer = setTimeout(() => setVisible(false), 300);
1889
- return () => clearTimeout(timer);
1890
- }
1891
- }, [isOpen]);
1892
- React.useEffect(() => {
1893
- if (isOpen) {
1894
- document.body.style.overflow = "hidden";
1895
- return () => {
1896
- document.body.style.overflow = "";
1897
- };
1898
- }
1899
- }, [isOpen]);
1900
- React.useEffect(() => {
1901
- if (!isOpen || !closeOnEscape) return;
1902
- const handleEscape = (e) => {
1903
- if (e.key === "Escape") onClose();
1904
- };
1905
- document.addEventListener("keydown", handleEscape);
1906
- return () => document.removeEventListener("keydown", handleEscape);
1907
- }, [isOpen, onClose, closeOnEscape]);
1908
- const handleOverlayClick = React.useCallback((e) => {
1909
- if (e.target === e.currentTarget && closeOnOverlayClick) {
1910
- onClose();
1911
- }
1912
- }, [onClose, closeOnOverlayClick]);
1913
- if (!visible) return null;
1914
- const prefix = COMPONENT_PREFIX$1;
1915
- const overlayClasses = [
1916
- `${prefix}drawer-overlay`,
1917
- animating && `${prefix}drawer-overlay--visible`
1918
- ].filter(Boolean).join(" ");
1919
- const drawerClasses = [
1920
- `${prefix}drawer`,
1921
- animating && `${prefix}drawer--open`,
1922
- className
1923
- ].filter(Boolean).join(" ");
1924
- return ReactDOM.createPortal(
1925
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: overlayClasses, onClick: handleOverlayClick, children: /* @__PURE__ */ jsxRuntime.jsxs(
1926
- "div",
1927
- {
1928
- className: drawerClasses,
1929
- role: "dialog",
1930
- "aria-modal": "true",
1931
- "aria-labelledby": title ? `${prefix}drawer-title` : void 0,
1932
- children: [
1933
- (title || showCloseButton || headerExtra) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${prefix}drawer__header`, children: [
1934
- title && /* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${prefix}drawer-title`, className: `${prefix}drawer__title`, children: title }),
1935
- headerExtra && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${prefix}drawer__header-extra`, children: headerExtra }),
1936
- showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
1937
- "button",
1938
- {
1939
- type: "button",
1940
- className: `${prefix}drawer__close`,
1941
- onClick: onClose,
1942
- "aria-label": "Cerrar",
1943
- children: "\u2715"
1944
- }
1945
- )
1946
- ] }),
1947
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: contentRef, className: `${prefix}drawer__content`, children }),
1948
- footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${prefix}drawer__footer`, children: footer })
1949
- ]
1950
- }
1951
- ) }),
1952
- document.body
1953
- );
1954
- };
1955
- Drawer$1.displayName = "Drawer";
1956
-
1957
2262
  const CHAT_CONFIG_DEFAULTS = {
1958
2263
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
1959
2264
  locale: "es-ES",
@@ -3548,12 +3853,6 @@ const thinkingActions = {
3548
3853
  hide: () => setChatStore(CHAT_STORE_KEYS.ASSISTANT_THINKING_INDICATOR, { visible: false }),
3549
3854
  setThinking: (isThinking) => {
3550
3855
  setChatStore(CHAT_STORE_KEYS.ASSISTANT_THINKING_INDICATOR, { visible: isThinking });
3551
- if (isThinking) {
3552
- chatInputActions.setSendDisabled(true);
3553
- } else {
3554
- const currentInput = chatStore.get(CHAT_STORE_KEYS.CHAT_INPUT);
3555
- chatInputActions.updateButtonVisibility(currentInput.hasText, currentInput.hasAttachments);
3556
- }
3557
3856
  }
3558
3857
  };
3559
3858
  const scrollButtonActions = {
@@ -4566,9 +4865,9 @@ const useChatHandlers = ({
4566
4865
  clearAttachments,
4567
4866
  scrollToLastUserMessage
4568
4867
  }) => {
4569
- const isThinking = () => chatStore.get(CHAT_STORE_KEYS.ASSISTANT_THINKING_INDICATOR).visible;
4868
+ const isInputDisabled = () => chatStore.get(CHAT_STORE_KEYS.CHAT_INPUT).buttonSend.disabled;
4570
4869
  const handleSendWithFiles = (content, files) => {
4571
- if (isThinking()) return;
4870
+ if (isInputDisabled()) return;
4572
4871
  if (!content.trim() && (!files || files.length === 0)) return;
4573
4872
  combinedActions.handleMessageSend();
4574
4873
  onSend(content, files);
@@ -4579,7 +4878,7 @@ const useChatHandlers = ({
4579
4878
  const handleInputKeyDown = (e, inputValue, attachments) => {
4580
4879
  if (e.key === "Enter" && !e.shiftKey) {
4581
4880
  e.preventDefault();
4582
- if (isThinking()) return;
4881
+ if (isInputDisabled()) return;
4583
4882
  handleSendWithFiles(inputValue, attachments);
4584
4883
  }
4585
4884
  };
@@ -4916,12 +5215,21 @@ const Chat = ({
4916
5215
  const unsubComponent = eventBus.on(CHAT_EVENT.COMPONENT_INTERACTION, () => {
4917
5216
  scrollToTopActions.activate();
4918
5217
  });
5218
+ const unsubInputDisabled = eventBus.on(CHAT_EVENT.INPUT_DISABLED, ({ disabled }) => {
5219
+ if (disabled) {
5220
+ chatInputActions.setSendDisabled(true);
5221
+ } else {
5222
+ const { hasText, hasAttachments } = chatStore.get(CHAT_STORE_KEYS.CHAT_INPUT);
5223
+ chatInputActions.updateButtonVisibility(hasText, hasAttachments);
5224
+ }
5225
+ });
4919
5226
  return () => {
4920
5227
  unsubMessages();
4921
5228
  unsubHeader();
4922
5229
  unsubPlaceholder();
4923
5230
  unsubThinking();
4924
5231
  unsubComponent();
5232
+ unsubInputDisabled();
4925
5233
  };
4926
5234
  }, [eventBus]);
4927
5235
  const handleSend = (content, files) => {
@@ -5006,33 +5314,37 @@ const Chat = ({
5006
5314
  ref: messagesContainerRef,
5007
5315
  onClick: handleMainClick,
5008
5316
  children: [
5009
- messageGroups.map((group, groupIndex) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
5010
- /* @__PURE__ */ jsxRuntime.jsx(DateDivider, { date: group.date }),
5011
- group.messages.map((msg, msgIndex) => {
5012
- const key = msg.id ?? `${groupIndex}-${msgIndex}`;
5013
- return msg.role === "user" ? /* @__PURE__ */ jsxRuntime.jsx(
5014
- UserMessage,
5015
- {
5016
- content: msg.content,
5017
- timestamp: msg.timestamp,
5018
- status: msg.status,
5019
- onRetry: msg.status === "failed" ? () => handleRetry(msg) : void 0,
5020
- files: msg.files
5021
- },
5022
- key
5023
- ) : /* @__PURE__ */ jsxRuntime.jsx(
5024
- AssistantMessage,
5025
- {
5026
- content: msg.content,
5027
- timestamp: msg.timestamp,
5028
- files: msg.files,
5029
- eventBus,
5030
- messageId: msg.id
5031
- },
5032
- key
5033
- );
5034
- })
5035
- ] }, `${group.date.getTime()}-${groupIndex}`)),
5317
+ messageGroups.map((group, groupIndex) => {
5318
+ const isToday = group.date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
5319
+ const showDivider = !(messageGroups.length === 1 && isToday);
5320
+ return /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
5321
+ showDivider && /* @__PURE__ */ jsxRuntime.jsx(DateDivider, { date: group.date }),
5322
+ group.messages.map((msg, msgIndex) => {
5323
+ const key = msg.id ?? `${groupIndex}-${msgIndex}`;
5324
+ return msg.role === "user" ? /* @__PURE__ */ jsxRuntime.jsx(
5325
+ UserMessage,
5326
+ {
5327
+ content: msg.content,
5328
+ timestamp: msg.timestamp,
5329
+ status: msg.status,
5330
+ onRetry: msg.status === "failed" ? () => handleRetry(msg) : void 0,
5331
+ files: msg.files
5332
+ },
5333
+ key
5334
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
5335
+ AssistantMessage,
5336
+ {
5337
+ content: msg.content,
5338
+ timestamp: msg.timestamp,
5339
+ files: msg.files,
5340
+ eventBus,
5341
+ messageId: msg.id
5342
+ },
5343
+ key
5344
+ );
5345
+ })
5346
+ ] }, `${group.date.getTime()}-${groupIndex}`);
5347
+ }),
5036
5348
  showThinking && /* @__PURE__ */ jsxRuntime.jsx(AssistantThinkingIndicator, {}),
5037
5349
  /* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
5038
5350
  ]