@beweco/aurora-ui 0.6.75 → 0.6.76-qa.103
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/assets/css/styles.css +1 -1
- package/dist/index.cjs.js +364 -109
- package/dist/index.esm.js +357 -110
- package/dist/types/components/area-line-chart/AreaLineChart.d.ts +1 -1
- package/dist/types/components/area-line-chart/AreaLineChart.d.ts.map +1 -1
- package/dist/types/components/area-line-chart/AreaLineChart.types.d.ts +12 -0
- package/dist/types/components/area-line-chart/AreaLineChart.types.d.ts.map +1 -1
- package/dist/types/components/autocomplete/AutoComplete.d.ts +16 -0
- package/dist/types/components/autocomplete/AutoComplete.d.ts.map +1 -1
- package/dist/types/components/autocomplete/AutoComplete.types.d.ts +12 -0
- package/dist/types/components/autocomplete/AutoComplete.types.d.ts.map +1 -1
- package/dist/types/components/button/Button.d.ts +1 -0
- package/dist/types/components/button/Button.d.ts.map +1 -1
- package/dist/types/components/button/Button.types.d.ts +15 -0
- package/dist/types/components/button/Button.types.d.ts.map +1 -1
- package/dist/types/components/donut-chart/DonutChart.d.ts.map +1 -1
- package/dist/types/components/donut-chart/DonutChart.types.d.ts +2 -0
- package/dist/types/components/donut-chart/DonutChart.types.d.ts.map +1 -1
- package/dist/types/components/donut-chart/donut-chart.utils.d.ts +7 -0
- package/dist/types/components/donut-chart/donut-chart.utils.d.ts.map +1 -1
- package/dist/types/components/donut-chart/index.d.ts +1 -1
- package/dist/types/components/donut-chart/index.d.ts.map +1 -1
- package/dist/types/components/phone/Phone.d.ts.map +1 -1
- package/dist/types/components/tags-filter/TagsFilter.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/providers/theme/index.d.ts +1 -0
- package/dist/types/providers/theme/index.d.ts.map +1 -1
- package/dist/types/providers/theme/linda-tones.d.ts +53 -0
- package/dist/types/providers/theme/linda-tones.d.ts.map +1 -0
- package/dist/types/providers/theme/useThemeManager.d.ts.map +1 -1
- package/dist/types/utils/dismiss-control.d.ts +47 -1
- package/dist/types/utils/dismiss-control.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -284,6 +284,10 @@ exports.HolidayType = void 0;
|
|
|
284
284
|
HolidayType["DateRange"] = "dateRange";
|
|
285
285
|
})(exports.HolidayType || (exports.HolidayType = {}));
|
|
286
286
|
|
|
287
|
+
var CLASE_AURA = {
|
|
288
|
+
ring: "linda-aura-ring",
|
|
289
|
+
surface: "linda-aura",
|
|
290
|
+
};
|
|
287
291
|
/**
|
|
288
292
|
* Botón genérico basado en HeroUI siguiendo las reglas de diseño BeweOS.
|
|
289
293
|
*
|
|
@@ -294,10 +298,24 @@ exports.HolidayType = void 0;
|
|
|
294
298
|
* - isLoading: On, Off
|
|
295
299
|
* - Radius: md (por defecto)
|
|
296
300
|
* - isIconOnly: True, False
|
|
301
|
+
* - ai: aura de Linda para las acciones que hace la IA (ver `Button.types.ts`)
|
|
297
302
|
*/
|
|
298
303
|
var Button = function (_a) {
|
|
299
|
-
var _b = _a.color, color = _b === void 0 ? "primary" : _b, _c = _a.size, size = _c === void 0 ? "md" : _c, _d = _a.variant, variant = _d === void 0 ? "solid" : _d, _e = _a.radius, radius = _e === void 0 ? "sm" : _e, startContent = _a.startContent, endContent = _a.endContent, _f = _a.isLoading, isLoading = _f === void 0 ? false : _f, _g = _a.isIconOnly, isIconOnly = _g === void 0 ? false : _g, props = __rest(_a, ["color", "size", "variant", "radius", "startContent", "endContent", "isLoading", "isIconOnly"]);
|
|
300
|
-
|
|
304
|
+
var _b = _a.color, color = _b === void 0 ? "primary" : _b, _c = _a.size, size = _c === void 0 ? "md" : _c, _d = _a.variant, variant = _d === void 0 ? "solid" : _d, _e = _a.radius, radius = _e === void 0 ? "sm" : _e, startContent = _a.startContent, endContent = _a.endContent, _f = _a.isLoading, isLoading = _f === void 0 ? false : _f, _g = _a.isIconOnly, isIconOnly = _g === void 0 ? false : _g, ai = _a.ai, className = _a.className, children = _a.children, props = __rest(_a, ["color", "size", "variant", "radius", "startContent", "endContent", "isLoading", "isIconOnly", "ai", "className", "children"]);
|
|
305
|
+
/*
|
|
306
|
+
* El contenido se envuelve para poder subirlo por encima del aura.
|
|
307
|
+
*
|
|
308
|
+
* Y tiene que ser un elemento: `<Button>Crear campaña</Button>` pasa un NODO DE
|
|
309
|
+
* TEXTO, que no es posicionable, así que ningún selector puede sacarlo del fondo del
|
|
310
|
+
* apilado —el aura, que sí está posicionada, le pasaría por encima—. Con `ring` daría
|
|
311
|
+
* igual porque esa capa es solo el canto; con `surface` el texto se leería a través
|
|
312
|
+
* del degradado.
|
|
313
|
+
*/
|
|
314
|
+
var contenido = ai ? (jsxRuntime.jsx("span", { className: "linda-aura-content", children: children })) : (children);
|
|
315
|
+
var clases = [ai ? CLASE_AURA[ai] : "", className]
|
|
316
|
+
.filter(Boolean)
|
|
317
|
+
.join(" ");
|
|
318
|
+
return (jsxRuntime.jsx(react.Button, __assign({}, props, { color: color, size: size, variant: variant, radius: radius, startContent: startContent, endContent: endContent, isLoading: isLoading, isIconOnly: isIconOnly, className: clases || undefined, children: contenido })));
|
|
301
319
|
};
|
|
302
320
|
|
|
303
321
|
var DatePicker = function (_a) {
|
|
@@ -581,9 +599,9 @@ function ChartTooltip(_a) {
|
|
|
581
599
|
})] }));
|
|
582
600
|
}
|
|
583
601
|
function AreaLineChart(_a) {
|
|
584
|
-
var data = _a.data, xAxisKey = _a.xAxisKey, series = _a.series, title = _a.title, value = _a.value, trend = _a.trend, _b = _a.height, height = _b === void 0 ? 200 : _b, _c = _a.className, className = _c === void 0 ? "" : _c, _d = _a.wrappedInCard, wrappedInCard = _d === void 0 ? false : _d, formatTooltipValue = _a.formatTooltipValue, _e = _a.yAxisDomain, yAxisDomain = _e === void 0 ? [0, "dataMax + 100"] : _e;
|
|
602
|
+
var data = _a.data, xAxisKey = _a.xAxisKey, series = _a.series, title = _a.title, value = _a.value, trend = _a.trend, _b = _a.height, height = _b === void 0 ? 200 : _b, _c = _a.className, className = _c === void 0 ? "" : _c, _d = _a.wrappedInCard, wrappedInCard = _d === void 0 ? false : _d, formatTooltipValue = _a.formatTooltipValue, _e = _a.yAxisDomain, yAxisDomain = _e === void 0 ? [0, "dataMax + 100"] : _e, _f = _a.xAxisInterval, xAxisInterval = _f === void 0 ? "preserveStartEnd" : _f;
|
|
585
603
|
var hasHeader = title != null || value != null || trend != null || series.length > 0;
|
|
586
|
-
var content = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasHeader && (jsxRuntime.jsxs("div", { className: "flex items-start justify-between mb-6", children: [jsxRuntime.jsxs("div", { children: [title != null && (jsxRuntime.jsx(H3, { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide mb-1", children: title })), value != null && (jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2", children: [jsxRuntime.jsx("span", { className: "text-2xl font-bold text-gray-900", children: value }), trend != null && (jsxRuntime.jsx("span", { className: "text-xs font-medium text-yellow-600 bg-yellow-50 px-2 py-1 rounded", children: trend }))] }))] }), series.length > 0 && (jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-4", children: series.map(function (s) { return (jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("svg", { width: "16", height: "2", viewBox: "0 0 16 2", fill: "none", children: jsxRuntime.jsx("line", { x1: "0", y1: "1", x2: "16", y2: "1", stroke: s.color, strokeWidth: "2" }) }), jsxRuntime.jsx("span", { className: "text-xs text-gray-600 font-medium", children: s.label })] }, s.dataKey)); }) }))] })), jsxRuntime.jsx("div", { className: "w-full", style: { height: "".concat(height, "px") }, children: jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: jsxRuntime.jsxs(recharts.LineChart, { data: data, margin: { top: 5, right: 5, left: 5, bottom: 5 }, children: [jsxRuntime.jsx("defs", { children: series.map(function (s) { return (jsxRuntime.jsxs("linearGradient", { id: "area-line-chart-".concat(s.dataKey), x1: "0", y1: "0", x2: "0", y2: "1", children: [jsxRuntime.jsx("stop", { offset: "0%", stopColor: s.color, stopOpacity: 0.3 }), jsxRuntime.jsx("stop", { offset: "50%", stopColor: s.color, stopOpacity: 0.15 }), jsxRuntime.jsx("stop", { offset: "100%", stopColor: s.color, stopOpacity: 0 })] }, s.dataKey)); }) }), jsxRuntime.jsx(recharts.XAxis, { dataKey: xAxisKey, axisLine: false, tickLine: false, tick: { fill: "#9ca3af", fontSize: 12 }, dy: 10 }), jsxRuntime.jsx(recharts.YAxis, { axisLine: false, tickLine: false, tick: { fill: "transparent", fontSize: 0 }, width: 0, tickCount: 6, domain: yAxisDomain, allowDecimals: false }), jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3", stroke: "#d1d5db", strokeOpacity: 0.5, vertical: false, horizontal: true }), jsxRuntime.jsx(recharts.Tooltip, { content: jsxRuntime.jsx(ChartTooltip, { series: series, formatValue: formatTooltipValue }) }), series.map(function (s) { return (jsxRuntime.jsx(recharts.Area, { type: "natural", dataKey: s.dataKey, stroke: "none", fill: "url(#area-line-chart-".concat(s.dataKey, ")"), animationDuration: 1500, animationEasing: "ease-in-out" }, "area-".concat(s.dataKey))); }), series.map(function (s) { return (jsxRuntime.jsx(recharts.Line, { type: "natural", dataKey: s.dataKey, name: s.dataKey, stroke: s.color, strokeWidth: 3, dot: false, activeDot: {
|
|
604
|
+
var content = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasHeader && (jsxRuntime.jsxs("div", { className: "flex items-start justify-between mb-6", children: [jsxRuntime.jsxs("div", { children: [title != null && (jsxRuntime.jsx(H3, { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide mb-1", children: title })), value != null && (jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2", children: [jsxRuntime.jsx("span", { className: "text-2xl font-bold text-gray-900", children: value }), trend != null && (jsxRuntime.jsx("span", { className: "text-xs font-medium text-yellow-600 bg-yellow-50 px-2 py-1 rounded", children: trend }))] }))] }), series.length > 0 && (jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-4", children: series.map(function (s) { return (jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("svg", { width: "16", height: "2", viewBox: "0 0 16 2", fill: "none", children: jsxRuntime.jsx("line", { x1: "0", y1: "1", x2: "16", y2: "1", stroke: s.color, strokeWidth: "2" }) }), jsxRuntime.jsx("span", { className: "text-xs text-gray-600 font-medium", children: s.label })] }, s.dataKey)); }) }))] })), jsxRuntime.jsx("div", { className: "w-full", style: { height: "".concat(height, "px") }, children: jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: jsxRuntime.jsxs(recharts.LineChart, { data: data, margin: { top: 5, right: 5, left: 5, bottom: 5 }, children: [jsxRuntime.jsx("defs", { children: series.map(function (s) { return (jsxRuntime.jsxs("linearGradient", { id: "area-line-chart-".concat(s.dataKey), x1: "0", y1: "0", x2: "0", y2: "1", children: [jsxRuntime.jsx("stop", { offset: "0%", stopColor: s.color, stopOpacity: 0.3 }), jsxRuntime.jsx("stop", { offset: "50%", stopColor: s.color, stopOpacity: 0.15 }), jsxRuntime.jsx("stop", { offset: "100%", stopColor: s.color, stopOpacity: 0 })] }, s.dataKey)); }) }), jsxRuntime.jsx(recharts.XAxis, { dataKey: xAxisKey, axisLine: false, tickLine: false, tick: { fill: "#9ca3af", fontSize: 12 }, dy: 10, interval: xAxisInterval }), jsxRuntime.jsx(recharts.YAxis, { axisLine: false, tickLine: false, tick: { fill: "transparent", fontSize: 0 }, width: 0, tickCount: 6, domain: yAxisDomain, allowDecimals: false }), jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3", stroke: "#d1d5db", strokeOpacity: 0.5, vertical: false, horizontal: true }), jsxRuntime.jsx(recharts.Tooltip, { content: jsxRuntime.jsx(ChartTooltip, { series: series, formatValue: formatTooltipValue }) }), series.map(function (s) { return (jsxRuntime.jsx(recharts.Area, { type: "natural", dataKey: s.dataKey, stroke: "none", fill: "url(#area-line-chart-".concat(s.dataKey, ")"), animationDuration: 1500, animationEasing: "ease-in-out" }, "area-".concat(s.dataKey))); }), series.map(function (s) { return (jsxRuntime.jsx(recharts.Line, { type: "natural", dataKey: s.dataKey, name: s.dataKey, stroke: s.color, strokeWidth: 3, dot: false, activeDot: {
|
|
587
605
|
r: 6,
|
|
588
606
|
fill: s.color,
|
|
589
607
|
stroke: "#fff",
|
|
@@ -595,6 +613,139 @@ function AreaLineChart(_a) {
|
|
|
595
613
|
return jsxRuntime.jsx("div", { className: className, children: content });
|
|
596
614
|
}
|
|
597
615
|
|
|
616
|
+
/**
|
|
617
|
+
* Interacciones que un popover no-modal NO debe tratar como "clic fuera".
|
|
618
|
+
*
|
|
619
|
+
* El problema que resuelve: `useOverlay` de react-aria trata cualquier
|
|
620
|
+
* pulsación fuera del popover como interacción externa y, cuando el popover es
|
|
621
|
+
* el overlay visible más reciente, hace `stopPropagation()` + `preventDefault()`
|
|
622
|
+
* sobre el `pointerdown` **y** sobre el `click`
|
|
623
|
+
* (`@react-aria/overlays/useOverlay`). El evento nunca llega a su destino, así
|
|
624
|
+
* que `usePress` no registra la pulsación y `onPress` no se dispara: el primer
|
|
625
|
+
* clic solo cierra el desplegable.
|
|
626
|
+
*
|
|
627
|
+
* Para un clic en la página de fondo eso es lo correcto: descartar el
|
|
628
|
+
* desplegable sin activar nada por debajo. Dentro del mismo diálogo no: ahí el
|
|
629
|
+
* usuario está rellenando un formulario y espera que su clic llegue. Y como los
|
|
630
|
+
* buscadores se reabren al recuperar el foco, el clic siguiente se volvía a
|
|
631
|
+
* tragar — un callejón sin salida del que solo se salía vaciando el campo.
|
|
632
|
+
*
|
|
633
|
+
* La única palanca es `shouldCloseOnInteractOutside`: es el guardián de esos dos
|
|
634
|
+
* `preventDefault`. Devolviendo `false` para lo que no es realmente "fuera", la
|
|
635
|
+
* pulsación llega intacta. El desplegable sigue cerrándose igual, pero por
|
|
636
|
+
* pérdida de foco (`shouldCloseOnBlur`) en vez de por interacción externa.
|
|
637
|
+
*/
|
|
638
|
+
var _a, _b;
|
|
639
|
+
/**
|
|
640
|
+
* Marca un botón como control de cierre de su contenedor. Los popovers de Aura
|
|
641
|
+
* no lo cuentan como interacción externa, así que su pulsación no se pierde.
|
|
642
|
+
*/
|
|
643
|
+
var DISMISS_CONTROL_ATTRIBUTE = "data-aura-dismiss";
|
|
644
|
+
/** Props a esparcir en un control de cierre: `<Button {...dismissControlProps} />`. */
|
|
645
|
+
var dismissControlProps = (_a = {},
|
|
646
|
+
_a[DISMISS_CONTROL_ATTRIBUTE] = "true",
|
|
647
|
+
_a);
|
|
648
|
+
/**
|
|
649
|
+
* Marca el contenedor de una superficie modal propia (wizard, panel a medida).
|
|
650
|
+
* No hace falta en `Modal` ni `Drawer`: los diálogos de HeroUI ya traen
|
|
651
|
+
* `role="dialog"`, que cuenta igual.
|
|
652
|
+
*/
|
|
653
|
+
var CONTAINER_ATTRIBUTE = "data-aura-container";
|
|
654
|
+
/** Props a esparcir en el contenedor: `<div {...containerProps}>`. */
|
|
655
|
+
var containerProps = (_b = {},
|
|
656
|
+
_b[CONTAINER_ATTRIBUTE] = "true",
|
|
657
|
+
_b);
|
|
658
|
+
/**
|
|
659
|
+
* Selector de controles de cierre. Incluye `[aria-label="Close"]` para cubrir
|
|
660
|
+
* los botones de cerrar internos de HeroUI (Modal, Drawer), que no admiten
|
|
661
|
+
* atributos propios.
|
|
662
|
+
*/
|
|
663
|
+
var DISMISS_CONTROL_SELECTOR = "[".concat(DISMISS_CONTROL_ATTRIBUTE, "],[aria-label=\"Close\"]");
|
|
664
|
+
/** Selector del contenedor modal: el marcado de Aura o un diálogo estándar. */
|
|
665
|
+
var CONTAINER_SELECTOR = "[".concat(CONTAINER_ATTRIBUTE, "],[role=\"dialog\"],[role=\"alertdialog\"]");
|
|
666
|
+
var matchesAncestor = function (element, selector) {
|
|
667
|
+
if (!element || typeof element.closest !== "function") {
|
|
668
|
+
return false;
|
|
669
|
+
}
|
|
670
|
+
return element.closest(selector) != null;
|
|
671
|
+
};
|
|
672
|
+
/** `true` si el elemento es un control de cierre (o está dentro de uno). */
|
|
673
|
+
var isDismissControl = function (element) { return matchesAncestor(element, DISMISS_CONTROL_SELECTOR); };
|
|
674
|
+
/**
|
|
675
|
+
* `true` si el elemento vive dentro de una superficie modal: un diálogo estándar
|
|
676
|
+
* o un contenedor marcado con `containerProps`.
|
|
677
|
+
*
|
|
678
|
+
* Es la condición que decide si un componente con popover no-modal necesita el
|
|
679
|
+
* predicado de más abajo. Fuera de una superficie así, HeroUI ya resuelve el
|
|
680
|
+
* caso por su cuenta (`ariaShouldCloseOnInteractOutside` cierra el desplegable
|
|
681
|
+
* y devuelve `false`, de modo que la pulsación llega a su destino); solo falla
|
|
682
|
+
* cuando hay un diálogo de por medio, y ahí entra el nuestro.
|
|
683
|
+
*/
|
|
684
|
+
var isInsideDismissContainer = function (element) { return matchesAncestor(element, CONTAINER_SELECTOR); };
|
|
685
|
+
/**
|
|
686
|
+
* Predicado listo para `popoverProps.shouldCloseOnInteractOutside` de un
|
|
687
|
+
* componente con popover no-modal.
|
|
688
|
+
*
|
|
689
|
+
* Devuelve `false` —no es interacción externa— en tres casos:
|
|
690
|
+
*
|
|
691
|
+
* 1. Dentro del propio componente: el popover vive en un portal, así que el
|
|
692
|
+
* campo de búsqueda queda fuera de él y una pulsación sobre el texto se
|
|
693
|
+
* contaba como externa.
|
|
694
|
+
* 2. Sobre un control de cierre del contenedor propio.
|
|
695
|
+
* 3. Dentro del mismo diálogo/contenedor que el componente: seguir rellenando
|
|
696
|
+
* el formulario no es descartar el desplegable.
|
|
697
|
+
*
|
|
698
|
+
* Las exenciones 2 y 3 se limitan al contenedor del propio componente. Un
|
|
699
|
+
* control de cierre suelto en la página —la X de un toast, la de un banner— no
|
|
700
|
+
* tiene nada que ver con este desplegable, así que sigue contando como externo
|
|
701
|
+
* y lo cierra.
|
|
702
|
+
*
|
|
703
|
+
* @param element Elemento donde ha empezado la interacción.
|
|
704
|
+
* @param root Raíz del componente.
|
|
705
|
+
*/
|
|
706
|
+
var shouldClosePopoverOnInteractOutside = function (element, root) {
|
|
707
|
+
var _a;
|
|
708
|
+
if (root === null || root === void 0 ? void 0 : root.contains(element)) {
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
var container = (_a = root === null || root === void 0 ? void 0 : root.closest) === null || _a === void 0 ? void 0 : _a.call(root, CONTAINER_SELECTOR);
|
|
712
|
+
if (isDismissControl(element)) {
|
|
713
|
+
// Sin contenedor propio no hay a quién eximir: el control de cierre es
|
|
714
|
+
// de otra cosa y su pulsación descarta el desplegable como cualquier otra.
|
|
715
|
+
return container ? !container.contains(element) : true;
|
|
716
|
+
}
|
|
717
|
+
if (!matchesAncestor(element, CONTAINER_SELECTOR)) {
|
|
718
|
+
return true;
|
|
719
|
+
}
|
|
720
|
+
// Solo exime el contenedor propio: un diálogo distinto sigue siendo externo.
|
|
721
|
+
return !(container === null || container === void 0 ? void 0 : container.contains(element));
|
|
722
|
+
};
|
|
723
|
+
/**
|
|
724
|
+
* Mezcla las `popoverProps` de un consumidor con el predicado por defecto, para
|
|
725
|
+
* que un componente con popover no-modal no trate como "clic fuera" lo que no lo
|
|
726
|
+
* es (ver `shouldClosePopoverOnInteractOutside`).
|
|
727
|
+
*
|
|
728
|
+
* Llamar solo cuando el componente está dentro de una superficie modal
|
|
729
|
+
* (`isInsideDismissContainer`). Fuera de ella HeroUI trae su propio default y
|
|
730
|
+
* hay que dejárselo: instalar cualquier predicado lo desactiva, porque su mezcla
|
|
731
|
+
* es por truthiness (`@heroui/autocomplete` → `use-autocomplete`).
|
|
732
|
+
*
|
|
733
|
+
* El consumidor puede sustituir el predicado pasando el suyo — es la salida para
|
|
734
|
+
* casos a medida, no la puerta a `() => true`. Pasar `shouldCloseOnInteractOutside:
|
|
735
|
+
* undefined` NO desactiva el default: para eso hay que pasar un predicado propio.
|
|
736
|
+
*
|
|
737
|
+
* @param popoverProps Las que llegan del consumidor, si las hay.
|
|
738
|
+
* @param getRoot Lector de la raíz del componente. Es una función y no un
|
|
739
|
+
* valor porque el `ref` todavía es `null` en el primer
|
|
740
|
+
* render: hay que leerlo cuando ocurre la interacción.
|
|
741
|
+
*/
|
|
742
|
+
var withPopoverDismissDefaults = function (popoverProps, getRoot) {
|
|
743
|
+
var _a;
|
|
744
|
+
return (__assign(__assign({}, popoverProps), { shouldCloseOnInteractOutside: (_a = popoverProps === null || popoverProps === void 0 ? void 0 : popoverProps.shouldCloseOnInteractOutside) !== null && _a !== void 0 ? _a : (function (element) {
|
|
745
|
+
return shouldClosePopoverOnInteractOutside(element, getRoot());
|
|
746
|
+
}) }));
|
|
747
|
+
};
|
|
748
|
+
|
|
598
749
|
/** Clases del wrapper del icono: margen derecho y alineación igual para lupa e iconos custom */
|
|
599
750
|
var ICON_WRAPPER_CLASSNAME = "mr-2 flex shrink-0 items-center [&_svg]:shrink-0";
|
|
600
751
|
var DEFAULT_ICON = (jsxRuntime.jsx(IconComponent, { icon: "solar:magnifer-outline", className: "text-default-400 pointer-events-none shrink-0", size: "sm", "aria-hidden": true }));
|
|
@@ -607,15 +758,39 @@ var DEFAULT_ICON = (jsxRuntime.jsx(IconComponent, { icon: "solar:magnifer-outlin
|
|
|
607
758
|
* - labelPlacement: Outside
|
|
608
759
|
* - Size: sm, md, lg (configurable)
|
|
609
760
|
* - Icono: lupa por defecto; acepta prop icon para personalizar u ocultar (null).
|
|
761
|
+
*
|
|
762
|
+
* **Dentro de un modal, drawer o contenedor marcado con `containerProps`**, el
|
|
763
|
+
* desplegable deja de contar como "clic fuera" lo que ocurre dentro del propio
|
|
764
|
+
* componente, sobre un control de cierre del contenedor o dentro de ese mismo
|
|
765
|
+
* contenedor: react-aria hace `preventDefault()` sobre esas pulsaciones y el
|
|
766
|
+
* control de destino nunca llegaba a recibir su `onPress` (ver
|
|
767
|
+
* `shouldClosePopoverOnInteractOutside`). Sigue cerrándose, por la vía del
|
|
768
|
+
* `shouldCloseOnBlur` del combobox de HeroUI — no por `onBlurWithin` del
|
|
769
|
+
* overlay, que está gateado por el mismo predicado.
|
|
770
|
+
*
|
|
771
|
+
* **Fuera de un contenedor así no se instala nada**: HeroUI ya resuelve ese caso
|
|
772
|
+
* con `ariaShouldCloseOnInteractOutside`, y como su mezcla es por truthiness,
|
|
773
|
+
* poner un predicado propio lo desactivaría y volvería a tragarse la pulsación.
|
|
774
|
+
*
|
|
775
|
+
* Un consumidor puede sustituir el predicado con su propio
|
|
776
|
+
* `popoverProps.shouldCloseOnInteractOutside`; entonces manda el suyo siempre.
|
|
610
777
|
*/
|
|
611
778
|
var AuraAutocomplete = function (_a) {
|
|
612
|
-
var label = _a.label, id = _a.id, icon = _a.icon, _b = _a.size, size = _b === void 0 ? "md" : _b, _c = _a.variant, variant = _c === void 0 ? "bordered" : _c, _d = _a.radius, radius = _d === void 0 ? "md" : _d, props = __rest(_a, ["label", "id", "icon", "size", "variant", "radius"]);
|
|
779
|
+
var label = _a.label, id = _a.id, icon = _a.icon, _b = _a.size, size = _b === void 0 ? "md" : _b, _c = _a.variant, variant = _c === void 0 ? "bordered" : _c, _d = _a.radius, radius = _d === void 0 ? "md" : _d, popoverProps = _a.popoverProps, props = __rest(_a, ["label", "id", "icon", "size", "variant", "radius", "popoverProps"]);
|
|
613
780
|
var generatedId = React.useId();
|
|
781
|
+
// El desplegable se renderiza en un portal, así que el campo de búsqueda
|
|
782
|
+
// queda fuera de él. Sin esta raíz el predicado no puede distinguir lo que
|
|
783
|
+
// pasa dentro del componente de un clic real de fuera. Se guarda en estado
|
|
784
|
+
// —y no en un ref— porque de ella depende SI se instala el predicado, y eso
|
|
785
|
+
// hay que decidirlo en render: un ref no dispara el re-render que hace falta.
|
|
786
|
+
var _e = React.useState(null), root = _e[0], setRoot = _e[1];
|
|
614
787
|
var autoId = id || generatedId;
|
|
615
788
|
var resolvedIcon = icon === undefined ? DEFAULT_ICON : icon;
|
|
616
789
|
var hasIcon = resolvedIcon != null;
|
|
617
790
|
var endContent = hasIcon ? (jsxRuntime.jsx("span", { className: ICON_WRAPPER_CLASSNAME, children: resolvedIcon })) : null;
|
|
618
|
-
return (jsxRuntime.jsxs("div", { children: [label && (jsxRuntime.jsx("label", { htmlFor: autoId, className: "block mb-2 text-tiny text-default-600", children: label })), jsxRuntime.jsx(react.Autocomplete, __assign({}, props, { id: autoId, label: undefined, labelPlacement: "outside", variant: variant, size: size, radius: radius, endContent: endContent,
|
|
791
|
+
return (jsxRuntime.jsxs("div", { ref: setRoot, children: [label && (jsxRuntime.jsx("label", { htmlFor: autoId, className: "block mb-2 text-tiny text-default-600", children: label })), jsxRuntime.jsx(react.Autocomplete, __assign({}, props, { id: autoId, label: undefined, labelPlacement: "outside", variant: variant, size: size, radius: radius, endContent: endContent, popoverProps: isInsideDismissContainer(root)
|
|
792
|
+
? withPopoverDismissDefaults(popoverProps, function () { return root; })
|
|
793
|
+
: popoverProps, classNames: __assign({ base: "[&_[data-slot=input-wrapper][data-focus=true]]:!border-primary-500", popoverContent: "aura-popover-content [&_li[data-hover=true]]:!bg-primary-50 [&_li[data-hover=true]]:!text-default-600 [&_li]:!text-default-500" }, (hasIcon && { selectorButton: "!hidden" })) }))] }));
|
|
619
794
|
};
|
|
620
795
|
|
|
621
796
|
/**
|
|
@@ -2967,6 +3142,20 @@ function computeTotal(data) {
|
|
|
2967
3142
|
function isDonutEmpty(data) {
|
|
2968
3143
|
return data.length === 0 || computeTotal(data) === 0;
|
|
2969
3144
|
}
|
|
3145
|
+
/**
|
|
3146
|
+
* Formatea `percent` (0-1) como entero + "%", excepto cuando la porción es
|
|
3147
|
+
* real (>0) pero redondea a 0 — ahí muestra "<1%" en vez de "0%", que se lee
|
|
3148
|
+
* como "no hay nada" y confunde cuando sí hay dato (ej. 4 de 2357 = 0.17%).
|
|
3149
|
+
* `lessThanOneLabel` permite traducir el texto (ver `DonutChartTranslations`).
|
|
3150
|
+
*/
|
|
3151
|
+
function formatDonutPercent(percent, lessThanOneLabel) {
|
|
3152
|
+
if (lessThanOneLabel === void 0) { lessThanOneLabel = "<1%"; }
|
|
3153
|
+
if (!Number.isFinite(percent) || percent <= 0) {
|
|
3154
|
+
return "0%";
|
|
3155
|
+
}
|
|
3156
|
+
var rounded = Math.round(percent * 100);
|
|
3157
|
+
return rounded === 0 ? lessThanOneLabel : "".concat(rounded, "%");
|
|
3158
|
+
}
|
|
2970
3159
|
/**
|
|
2971
3160
|
* Resuelve las proporciones y el color final de cada categoría.
|
|
2972
3161
|
* El color propio de cada dato tiene prioridad; si falta, se cicla `palette` por índice.
|
|
@@ -2984,6 +3173,7 @@ function computeSlices(data, palette) {
|
|
|
2984
3173
|
var DEFAULT_TRANSLATIONS$b = {
|
|
2985
3174
|
emptyState: "Sin datos para mostrar",
|
|
2986
3175
|
totalLabel: "Total",
|
|
3176
|
+
lessThanOnePercent: "<1%",
|
|
2987
3177
|
};
|
|
2988
3178
|
/**
|
|
2989
3179
|
* DonutChart - Gráfico circular (pie o donut, según `innerRadiusRatio`) con
|
|
@@ -3002,7 +3192,7 @@ var DonutChart = function (_a) {
|
|
|
3002
3192
|
return formatValue ? formatValue(value) : String(value);
|
|
3003
3193
|
};
|
|
3004
3194
|
var isDonut = innerRadiusRatio > 0;
|
|
3005
|
-
return (jsxRuntime.jsxs("div", { className: className, children: [jsxRuntime.jsxs("div", { className: "relative w-full", style: { height: height }, children: [jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: jsxRuntime.jsxs(recharts.PieChart, { children: [jsxRuntime.jsx(recharts.Pie, { data: slices, dataKey: "value", nameKey: "name", innerRadius: isDonut ? "".concat(innerRadiusRatio * 100, "%") : 0, outerRadius: "90%", stroke: "none", children: slices.map(function (slice) { return (jsxRuntime.jsx(recharts.Cell, { fill: slice.color }, slice.name)); }) }), jsxRuntime.jsx(recharts.Tooltip, { formatter: function (value) { return format(value); } })] }) }), isDonut && showTotal && (jsxRuntime.jsxs("div", { className: "aurora-donut-total pointer-events-none absolute inset-0 flex flex-col items-center justify-center", "aria-hidden": "true", children: [jsxRuntime.jsx("span", { className: "text-xs text-foreground-500", children: t.totalLabel }), jsxRuntime.jsx("span", { className: "text-xl font-semibold", children: format(total) })] }))] }), showLegend && (jsxRuntime.jsx("ul", { className: "mt-3 flex flex-wrap gap-3", children: slices.map(function (slice) { return (jsxRuntime.jsxs("li", { className: "flex items-center gap-1.5 text-xs", children: [jsxRuntime.jsx("span", { className: "h-2 w-2 rounded-full", style: { backgroundColor: slice.color }, "aria-hidden": "true" }), jsxRuntime.jsx("span", { children: slice.name }), jsxRuntime.
|
|
3195
|
+
return (jsxRuntime.jsxs("div", { className: className, children: [jsxRuntime.jsxs("div", { className: "relative w-full", style: { height: height }, children: [jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: jsxRuntime.jsxs(recharts.PieChart, { children: [jsxRuntime.jsx(recharts.Pie, { data: slices, dataKey: "value", nameKey: "name", innerRadius: isDonut ? "".concat(innerRadiusRatio * 100, "%") : 0, outerRadius: "90%", stroke: "none", children: slices.map(function (slice) { return (jsxRuntime.jsx(recharts.Cell, { fill: slice.color }, slice.name)); }) }), jsxRuntime.jsx(recharts.Tooltip, { formatter: function (value) { return format(value); } })] }) }), isDonut && showTotal && (jsxRuntime.jsxs("div", { className: "aurora-donut-total pointer-events-none absolute inset-0 flex flex-col items-center justify-center", "aria-hidden": "true", children: [jsxRuntime.jsx("span", { className: "text-xs text-foreground-500", children: t.totalLabel }), jsxRuntime.jsx("span", { className: "text-xl font-semibold", children: format(total) })] }))] }), showLegend && (jsxRuntime.jsx("ul", { className: "mt-3 flex flex-wrap gap-3", children: slices.map(function (slice) { return (jsxRuntime.jsxs("li", { className: "flex items-center gap-1.5 text-xs", children: [jsxRuntime.jsx("span", { className: "h-2 w-2 rounded-full", style: { backgroundColor: slice.color }, "aria-hidden": "true" }), jsxRuntime.jsx("span", { children: slice.name }), jsxRuntime.jsx("span", { className: "text-foreground-500", children: formatDonutPercent(slice.percent, t.lessThanOnePercent) })] }, slice.name)); }) }))] }));
|
|
3006
3196
|
};
|
|
3007
3197
|
|
|
3008
3198
|
var H1 = function (_a) {
|
|
@@ -4020,96 +4210,6 @@ var MenuClaw = React.memo(function MenuClaw(_a) {
|
|
|
4020
4210
|
}) }), helpSection ? (jsxRuntime.jsx("div", { className: "mt-auto flex flex-col items-center justify-center", children: jsxRuntime.jsx(react.Button, { fullWidth: true, className: "text-default-500 data-[hover=true]:text-default-600", startContent: jsxRuntime.jsx(IconComponent, { className: "text-default-500", icon: "solar:info-circle-line-duotone", size: "md" }), variant: "light", onPress: handleHelpClick, isIconOnly: collapsed, children: !collapsed ? (jsxRuntime.jsx("span", { className: "menu-claw-collapsible truncate", children: helpSection.title })) : null }) })) : null] }) })] }));
|
|
4021
4211
|
});
|
|
4022
4212
|
|
|
4023
|
-
/**
|
|
4024
|
-
* Interacciones que un popover no-modal NO debe tratar como "clic fuera".
|
|
4025
|
-
*
|
|
4026
|
-
* El problema que resuelve: `useOverlay` de react-aria trata cualquier
|
|
4027
|
-
* pulsación fuera del popover como interacción externa y, cuando el popover es
|
|
4028
|
-
* el overlay visible más reciente, hace `stopPropagation()` + `preventDefault()`
|
|
4029
|
-
* sobre el `pointerdown` **y** sobre el `click`
|
|
4030
|
-
* (`@react-aria/overlays/useOverlay`). El evento nunca llega a su destino, así
|
|
4031
|
-
* que `usePress` no registra la pulsación y `onPress` no se dispara: el primer
|
|
4032
|
-
* clic solo cierra el desplegable.
|
|
4033
|
-
*
|
|
4034
|
-
* Para un clic en la página de fondo eso es lo correcto: descartar el
|
|
4035
|
-
* desplegable sin activar nada por debajo. Dentro del mismo diálogo no: ahí el
|
|
4036
|
-
* usuario está rellenando un formulario y espera que su clic llegue. Y como los
|
|
4037
|
-
* buscadores se reabren al recuperar el foco, el clic siguiente se volvía a
|
|
4038
|
-
* tragar — un callejón sin salida del que solo se salía vaciando el campo.
|
|
4039
|
-
*
|
|
4040
|
-
* La única palanca es `shouldCloseOnInteractOutside`: es el guardián de esos dos
|
|
4041
|
-
* `preventDefault`. Devolviendo `false` para lo que no es realmente "fuera", la
|
|
4042
|
-
* pulsación llega intacta. El desplegable sigue cerrándose igual, pero por
|
|
4043
|
-
* pérdida de foco (`shouldCloseOnBlur`) en vez de por interacción externa.
|
|
4044
|
-
*/
|
|
4045
|
-
var _a, _b;
|
|
4046
|
-
/**
|
|
4047
|
-
* Marca un botón como control de cierre de su contenedor. Los popovers de Aura
|
|
4048
|
-
* no lo cuentan como interacción externa, así que su pulsación no se pierde.
|
|
4049
|
-
*/
|
|
4050
|
-
var DISMISS_CONTROL_ATTRIBUTE = "data-aura-dismiss";
|
|
4051
|
-
/** Props a esparcir en un control de cierre: `<Button {...dismissControlProps} />`. */
|
|
4052
|
-
var dismissControlProps = (_a = {},
|
|
4053
|
-
_a[DISMISS_CONTROL_ATTRIBUTE] = "true",
|
|
4054
|
-
_a);
|
|
4055
|
-
/**
|
|
4056
|
-
* Marca el contenedor de una superficie modal propia (wizard, panel a medida).
|
|
4057
|
-
* No hace falta en `Modal` ni `Drawer`: los diálogos de HeroUI ya traen
|
|
4058
|
-
* `role="dialog"`, que cuenta igual.
|
|
4059
|
-
*/
|
|
4060
|
-
var CONTAINER_ATTRIBUTE = "data-aura-container";
|
|
4061
|
-
/** Props a esparcir en el contenedor: `<div {...containerProps}>`. */
|
|
4062
|
-
var containerProps = (_b = {},
|
|
4063
|
-
_b[CONTAINER_ATTRIBUTE] = "true",
|
|
4064
|
-
_b);
|
|
4065
|
-
/**
|
|
4066
|
-
* Selector de controles de cierre. Incluye `[aria-label="Close"]` para cubrir
|
|
4067
|
-
* los botones de cerrar internos de HeroUI (Modal, Drawer), que no admiten
|
|
4068
|
-
* atributos propios.
|
|
4069
|
-
*/
|
|
4070
|
-
var DISMISS_CONTROL_SELECTOR = "[".concat(DISMISS_CONTROL_ATTRIBUTE, "],[aria-label=\"Close\"]");
|
|
4071
|
-
/** Selector del contenedor modal: el marcado de Aura o un diálogo estándar. */
|
|
4072
|
-
var CONTAINER_SELECTOR = "[".concat(CONTAINER_ATTRIBUTE, "],[role=\"dialog\"],[role=\"alertdialog\"]");
|
|
4073
|
-
var matchesAncestor = function (element, selector) {
|
|
4074
|
-
if (!element || typeof element.closest !== "function") {
|
|
4075
|
-
return false;
|
|
4076
|
-
}
|
|
4077
|
-
return element.closest(selector) != null;
|
|
4078
|
-
};
|
|
4079
|
-
/** `true` si el elemento es un control de cierre (o está dentro de uno). */
|
|
4080
|
-
var isDismissControl = function (element) { return matchesAncestor(element, DISMISS_CONTROL_SELECTOR); };
|
|
4081
|
-
/**
|
|
4082
|
-
* Predicado listo para `popoverProps.shouldCloseOnInteractOutside` de un
|
|
4083
|
-
* componente con popover no-modal.
|
|
4084
|
-
*
|
|
4085
|
-
* Devuelve `false` —no es interacción externa— en tres casos:
|
|
4086
|
-
*
|
|
4087
|
-
* 1. Dentro del propio componente: el popover vive en un portal, así que el
|
|
4088
|
-
* campo de búsqueda queda fuera de él y una pulsación sobre el texto se
|
|
4089
|
-
* contaba como externa.
|
|
4090
|
-
* 2. Sobre un control de cierre del contenedor.
|
|
4091
|
-
* 3. Dentro del mismo diálogo/contenedor que el componente: seguir rellenando
|
|
4092
|
-
* el formulario no es descartar el desplegable.
|
|
4093
|
-
*
|
|
4094
|
-
* @param element Elemento donde ha empezado la interacción.
|
|
4095
|
-
* @param root Raíz del componente.
|
|
4096
|
-
*/
|
|
4097
|
-
var shouldClosePopoverOnInteractOutside = function (element, root) {
|
|
4098
|
-
var _a;
|
|
4099
|
-
if (root === null || root === void 0 ? void 0 : root.contains(element)) {
|
|
4100
|
-
return false;
|
|
4101
|
-
}
|
|
4102
|
-
if (isDismissControl(element)) {
|
|
4103
|
-
return false;
|
|
4104
|
-
}
|
|
4105
|
-
if (!matchesAncestor(element, CONTAINER_SELECTOR)) {
|
|
4106
|
-
return true;
|
|
4107
|
-
}
|
|
4108
|
-
// Solo exime el contenedor propio: un diálogo distinto sigue siendo externo.
|
|
4109
|
-
var container = (_a = root === null || root === void 0 ? void 0 : root.closest) === null || _a === void 0 ? void 0 : _a.call(root, CONTAINER_SELECTOR);
|
|
4110
|
-
return !(container === null || container === void 0 ? void 0 : container.contains(element));
|
|
4111
|
-
};
|
|
4112
|
-
|
|
4113
4213
|
var StepIndicator = function (_a) {
|
|
4114
4214
|
var currentStep = _a.currentStep, totalSteps = _a.totalSteps, _b = _a.color, color = _b === void 0 ? "primary" : _b, _c = _a.showStepText, showStepText = _c === void 0 ? true : _c, stepTextFormatter = _a.stepTextFormatter, className = _a.className, props = __rest(_a, ["currentStep", "totalSteps", "color", "showStepText", "stepTextFormatter", "className"]);
|
|
4115
4215
|
var progressPercentage = Math.min((currentStep / totalSteps) * 100, 100);
|
|
@@ -4464,13 +4564,6 @@ var Phone = function (_a) {
|
|
|
4464
4564
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
4465
4565
|
};
|
|
4466
4566
|
}, [isDropdownOpen]);
|
|
4467
|
-
// El dropdown se portea a `body` con posición absoluta fija; cerrarlo cuando
|
|
4468
|
-
// un ancestro hace scroll para que no quede flotando fuera de lugar.
|
|
4469
|
-
useCloseOnAncestorScroll({
|
|
4470
|
-
isOpen: isDropdownOpen,
|
|
4471
|
-
onClose: function () { return setIsDropdownOpen(false); },
|
|
4472
|
-
contentRef: portalDropdownRef,
|
|
4473
|
-
});
|
|
4474
4567
|
var handleCountrySelect = function (country) {
|
|
4475
4568
|
setSelectedCountry(country);
|
|
4476
4569
|
setIsDropdownOpen(false);
|
|
@@ -8958,7 +9051,9 @@ function TagsFilter(_a) {
|
|
|
8958
9051
|
var _m = React.useState(0), autocompleteKey = _m[0], setAutocompleteKey = _m[1];
|
|
8959
9052
|
var selectedList = value !== null && value !== void 0 ? value : [];
|
|
8960
9053
|
var _o = React.useState(null), sentinelNode = _o[0], setSentinelNode = _o[1];
|
|
8961
|
-
|
|
9054
|
+
// En estado y no en un ref: de la raíz depende SI se instala el predicado
|
|
9055
|
+
// (solo dentro de una superficie modal), y eso se decide en render.
|
|
9056
|
+
var _p = React.useState(null), root = _p[0], setRoot = _p[1];
|
|
8962
9057
|
React.useEffect(function () {
|
|
8963
9058
|
if (!onLoadMore || !sentinelNode || !hasMore) {
|
|
8964
9059
|
return;
|
|
@@ -9030,7 +9125,7 @@ function TagsFilter(_a) {
|
|
|
9030
9125
|
if (isLoading) {
|
|
9031
9126
|
return (jsxRuntime.jsx("div", { className: "flex flex-col gap-4 ".concat(className), children: jsxRuntime.jsx("div", { className: "flex justify-center py-4", children: jsxRuntime.jsx(react.Spinner, { size: "sm" }) }) }));
|
|
9032
9127
|
}
|
|
9033
|
-
return (jsxRuntime.jsxs("div", { ref:
|
|
9128
|
+
return (jsxRuntime.jsxs("div", { ref: setRoot, className: "flex flex-col gap-4 ".concat(className), children: [error && (jsxRuntime.jsxs("div", { className: "text-danger text-small py-2", children: [t.errorLoadingPrefix, ": ", error] })), !error && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [jsxRuntime.jsxs(H4, { className: "text-tiny text-left text-default-700", children: [t.labelSelect, required && jsxRuntime.jsx("span", { className: "text-danger ml-0.5", children: "*" })] }), jsxRuntime.jsx(AuraAutocomplete, { placeholder: t.placeholder, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : t.placeholder, inputValue: inputValue, onInputChange: function (v) {
|
|
9034
9129
|
setInputValue(v);
|
|
9035
9130
|
onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange(v);
|
|
9036
9131
|
}, selectedKey: null, items: itemsWithSentinel, onSelectionChange: handleAutocompleteSelection,
|
|
@@ -9064,9 +9159,16 @@ function TagsFilter(_a) {
|
|
|
9064
9159
|
// click de toda interacción externa, así que su `onPress` no se
|
|
9065
9160
|
// disparaba y el contenedor no se podía cerrar mientras el
|
|
9066
9161
|
// desplegable estuviera abierto (ver `shouldClosePopoverOnInteractOutside`).
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9162
|
+
//
|
|
9163
|
+
// Solo dentro de una superficie modal: fuera de ella HeroUI ya
|
|
9164
|
+
// resuelve el caso por su cuenta, y como su mezcla es por
|
|
9165
|
+
// truthiness, instalar cualquier predicado lo desactivaría y la
|
|
9166
|
+
// pulsación volvería a perderse.
|
|
9167
|
+
shouldCloseOnInteractOutside: isInsideDismissContainer(root)
|
|
9168
|
+
? function (element) {
|
|
9169
|
+
return shouldClosePopoverOnInteractOutside(element, root);
|
|
9170
|
+
}
|
|
9171
|
+
: undefined,
|
|
9070
9172
|
}, listboxProps: {
|
|
9071
9173
|
className: "max-h-[200px] overflow-y-auto",
|
|
9072
9174
|
}, className: "w-full", children: function (item) {
|
|
@@ -9644,6 +9746,127 @@ function removeCustomPrimaryColor() {
|
|
|
9644
9746
|
}
|
|
9645
9747
|
}
|
|
9646
9748
|
|
|
9749
|
+
/**
|
|
9750
|
+
* Los tres tonos del aura de Linda, derivados del `primary` de la agencia.
|
|
9751
|
+
*
|
|
9752
|
+
* Linda no tiene color propio: es el `primary` que el negocio eligió en el onboarding,
|
|
9753
|
+
* y por eso aquí no hay ni un color escrito. Lo único que se fija es CUÁNTO se gira ese
|
|
9754
|
+
* tono y en qué banda de luz se pinta.
|
|
9755
|
+
*/
|
|
9756
|
+
/**
|
|
9757
|
+
* Grados que se gira el `primary` para cada tono, en el orden en que se pintan.
|
|
9758
|
+
*
|
|
9759
|
+
* Son muchos grados a propósito. La gracia del aura es que haya MÁS DE UN COLOR: con
|
|
9760
|
+
* un giro discreto —del orden de 18°, el que usa un degradado de profundidad— salen
|
|
9761
|
+
* tres versiones del mismo tono y el resultado se lee como un plano. A ±55° el salto
|
|
9762
|
+
* se ve como otro color y sigue dentro de la familia del `primary`, que es lo que
|
|
9763
|
+
* permite que esto funcione con la agencia número siete sin tocar nada.
|
|
9764
|
+
*
|
|
9765
|
+
* El tono del medio va casi sin girar: es el que ancla el conjunto al color de la
|
|
9766
|
+
* agencia, para que el aura se lea como suya y no como una decoración pegada encima.
|
|
9767
|
+
*/
|
|
9768
|
+
var GIROS = [-56, 8, 54];
|
|
9769
|
+
/**
|
|
9770
|
+
* Banda de luz en la que se pintan los tres tonos, en porcentaje HSL.
|
|
9771
|
+
*
|
|
9772
|
+
* Los tonos NO heredan la luz del `primary`, y esto es lo que más se nota: un primary
|
|
9773
|
+
* oscuro y poco saturado sobre una superficie clara se lee como una mancha gris —sucia,
|
|
9774
|
+
* no como color—, y uno casi blanco desaparece contra el fondo. Se llevan al paso medio
|
|
9775
|
+
* de la escala, que es el que funciona en los dos casos.
|
|
9776
|
+
*/
|
|
9777
|
+
var BANDA_LUZ = { min: 52, max: 72 };
|
|
9778
|
+
/**
|
|
9779
|
+
* Banda de saturación de los tres tonos, en porcentaje HSL.
|
|
9780
|
+
*
|
|
9781
|
+
* El techo es lo que evita que el aura grite. A plena saturación los tonos dejan de ser
|
|
9782
|
+
* ambiente y pasan a ser tres focos de color encima de un control de 40 pt: bonito en
|
|
9783
|
+
* una captura, insoportable en una barra que se mira todo el día.
|
|
9784
|
+
*
|
|
9785
|
+
* ⚠️ **Y hay una razón que no es estética.** Girar el tono puede caer en un rojo vivo:
|
|
9786
|
+
* un `primary` amarillo —51°— girado −56° aterriza en 355°, que a saturación 100 se lee
|
|
9787
|
+
* como un estado de error alrededor de un botón que no ha fallado. Visto al renderizarlo,
|
|
9788
|
+
* no razonándolo. Bajado a 65 el mismo tono es un rosa apagado y vuelve a leerse como lo
|
|
9789
|
+
* que es: decoración.
|
|
9790
|
+
*
|
|
9791
|
+
* El suelo existe por lo contrario: un `primary` casi gris da tres tonos que no se
|
|
9792
|
+
* distinguen entre sí, y entonces no hay degradado que ver —el aura se lee como una
|
|
9793
|
+
* mancha plana—.
|
|
9794
|
+
*/
|
|
9795
|
+
var BANDA_SATURACION = { min: 35, max: 65 };
|
|
9796
|
+
var VUELTA = 360;
|
|
9797
|
+
/** `H S% L%` — el formato exacto en el que HeroUI guarda sus variables de color. */
|
|
9798
|
+
var TRIPLETE = /^\s*(-?\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)%\s*$/;
|
|
9799
|
+
/**
|
|
9800
|
+
* Lee el triplete que HeroUI deja en una variable de color.
|
|
9801
|
+
*
|
|
9802
|
+
* Devuelve `null` en vez de lanzar: esto corre en un efecto de tema y el valor puede
|
|
9803
|
+
* no estar todavía —la clase del tema aún no está en el `<html>`, o el consumidor no
|
|
9804
|
+
* cargó la hoja de estilos—. Un aura que no se pinta es un problema menor; una
|
|
9805
|
+
* excepción que tumba el provider de tema, no.
|
|
9806
|
+
*/
|
|
9807
|
+
function parseHslTriplet(value) {
|
|
9808
|
+
var encontrado = TRIPLETE.exec(value);
|
|
9809
|
+
if (!encontrado) {
|
|
9810
|
+
return null;
|
|
9811
|
+
}
|
|
9812
|
+
var h = encontrado[1], s = encontrado[2], l = encontrado[3];
|
|
9813
|
+
return { h: Number(h), s: Number(s), l: Number(l) };
|
|
9814
|
+
}
|
|
9815
|
+
/** Deja un ángulo dentro de `[0, 360)`, venga de donde venga. */
|
|
9816
|
+
function normalizarTono(grados) {
|
|
9817
|
+
return ((grados % VUELTA) + VUELTA) % VUELTA;
|
|
9818
|
+
}
|
|
9819
|
+
function acotar(valor, min, max) {
|
|
9820
|
+
return Math.min(Math.max(valor, min), max);
|
|
9821
|
+
}
|
|
9822
|
+
/**
|
|
9823
|
+
* Los tres tonos del aura, listos para escribirse en una variable CSS.
|
|
9824
|
+
*
|
|
9825
|
+
* Se redondean a entero: es un degradado decorativo, y las décimas de grado solo
|
|
9826
|
+
* alargan la hoja de estilos.
|
|
9827
|
+
*/
|
|
9828
|
+
function deriveLindaTones(primary) {
|
|
9829
|
+
var luz = Math.round(acotar(primary.l, BANDA_LUZ.min, BANDA_LUZ.max));
|
|
9830
|
+
var saturacion = Math.round(acotar(primary.s, BANDA_SATURACION.min, BANDA_SATURACION.max));
|
|
9831
|
+
var tonos = GIROS.map(function (giro) {
|
|
9832
|
+
return "".concat(Math.round(normalizarTono(primary.h + giro)), " ").concat(saturacion, "% ").concat(luz, "%");
|
|
9833
|
+
});
|
|
9834
|
+
return tonos;
|
|
9835
|
+
}
|
|
9836
|
+
/** Las variables que se escriben en el `<html>`, en el orden en que se pintan. */
|
|
9837
|
+
var LINDA_TONE_PROPERTIES = [
|
|
9838
|
+
"--linda-1",
|
|
9839
|
+
"--linda-2",
|
|
9840
|
+
"--linda-3",
|
|
9841
|
+
];
|
|
9842
|
+
/**
|
|
9843
|
+
* Escribe los tres tonos del aura a partir del valor de `--heroui-primary`.
|
|
9844
|
+
*
|
|
9845
|
+
* Si el primary no se puede leer, **borra los que hubiera** y devuelve `false`. Es lo
|
|
9846
|
+
* contrario de dejarlos: unos tonos viejos son de otro tema, y un aura del color
|
|
9847
|
+
* anterior es peor que un aura que no se pinta —la CSS del efecto ya está escrita para
|
|
9848
|
+
* desaparecer sin sus variables—.
|
|
9849
|
+
*/
|
|
9850
|
+
function applyLindaTones(style, primaryValue) {
|
|
9851
|
+
var primary = parseHslTriplet(primaryValue);
|
|
9852
|
+
if (!primary) {
|
|
9853
|
+
removeLindaTones(style);
|
|
9854
|
+
return false;
|
|
9855
|
+
}
|
|
9856
|
+
var tonos = deriveLindaTones(primary);
|
|
9857
|
+
LINDA_TONE_PROPERTIES.forEach(function (propiedad, indice) {
|
|
9858
|
+
style.setProperty(propiedad, tonos[indice]);
|
|
9859
|
+
});
|
|
9860
|
+
return true;
|
|
9861
|
+
}
|
|
9862
|
+
/** Quita los tres tonos del aura. */
|
|
9863
|
+
function removeLindaTones(style) {
|
|
9864
|
+
for (var _i = 0, LINDA_TONE_PROPERTIES_1 = LINDA_TONE_PROPERTIES; _i < LINDA_TONE_PROPERTIES_1.length; _i++) {
|
|
9865
|
+
var propiedad = LINDA_TONE_PROPERTIES_1[_i];
|
|
9866
|
+
style.removeProperty(propiedad);
|
|
9867
|
+
}
|
|
9868
|
+
}
|
|
9869
|
+
|
|
9647
9870
|
/**
|
|
9648
9871
|
* Custom hook to manage the theme state and side effects.
|
|
9649
9872
|
* Supports both named ThemeColor values and arbitrary hex colors.
|
|
@@ -9689,6 +9912,30 @@ var useThemeManager = function () {
|
|
|
9689
9912
|
removeCustomPrimaryColor();
|
|
9690
9913
|
}
|
|
9691
9914
|
}, [customHex, mode]);
|
|
9915
|
+
/*
|
|
9916
|
+
* Los tres tonos del aura de Linda, derivados del primary que acaba de quedar fijado.
|
|
9917
|
+
*
|
|
9918
|
+
* Va DESPUÉS de los dos efectos de arriba y depende de lo mismo que ellos, que es lo
|
|
9919
|
+
* que garantiza que lea el primary definitivo: React ejecuta los efectos en orden de
|
|
9920
|
+
* declaración, así que aquí la clase del tema ya está en el `<html>` y el hex a medida
|
|
9921
|
+
* ya está escrito o retirado.
|
|
9922
|
+
*
|
|
9923
|
+
* Se lee del estilo COMPUTADO y no de `customHex` a propósito: el primary llega por
|
|
9924
|
+
* dos caminos —el hex del negocio o la clase de una de las familias de tema— y el
|
|
9925
|
+
* computado es el único sitio donde los dos han convergido. Derivarlo solo de
|
|
9926
|
+
* `customHex` dejaría sin aura a toda agencia que use una familia tal cual.
|
|
9927
|
+
*/
|
|
9928
|
+
/*
|
|
9929
|
+
* `customHex` y `rawTheme` están en la lista aunque el cuerpo no los lea: son la señal
|
|
9930
|
+
* de que el `<html>` acaba de cambiar. La entrada real de este efecto es el estilo
|
|
9931
|
+
* computado, que la regla no puede ver, y sin ellos el aura se quedaría con los tonos
|
|
9932
|
+
* del tema anterior.
|
|
9933
|
+
*/
|
|
9934
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: ver el comentario de arriba
|
|
9935
|
+
React.useEffect(function () {
|
|
9936
|
+
var html = document.documentElement;
|
|
9937
|
+
applyLindaTones(html.style, getComputedStyle(html).getPropertyValue("--heroui-primary"));
|
|
9938
|
+
}, [customHex, rawTheme]);
|
|
9692
9939
|
var setMode = React.useCallback(function (newMode) {
|
|
9693
9940
|
var effectiveMode = newMode === "dark" ? "light" : newMode;
|
|
9694
9941
|
var newTheme = color === "blue" ? effectiveMode : "".concat(color, "-").concat(effectiveMode);
|
|
@@ -9861,6 +10108,7 @@ exports.InputPassword = InputPassword;
|
|
|
9861
10108
|
exports.Kanban = Kanban;
|
|
9862
10109
|
exports.KanbanCard = KanbanCard;
|
|
9863
10110
|
exports.KanbanColumn = KanbanColumn;
|
|
10111
|
+
exports.LINDA_TONE_PROPERTIES = LINDA_TONE_PROPERTIES;
|
|
9864
10112
|
exports.LindaIcon = LindaIcon;
|
|
9865
10113
|
exports.MenuClaw = MenuClaw;
|
|
9866
10114
|
exports.MenuComponent = MenuComponent;
|
|
@@ -9911,6 +10159,7 @@ exports.Wizard = Wizard;
|
|
|
9911
10159
|
exports.WizardNavigation = WizardNavigation;
|
|
9912
10160
|
exports.WizardSidebar = WizardSidebar;
|
|
9913
10161
|
exports.applyCustomPrimaryColor = applyCustomPrimaryColor;
|
|
10162
|
+
exports.applyLindaTones = applyLindaTones;
|
|
9914
10163
|
exports.computeBars = computeBars;
|
|
9915
10164
|
exports.computeMax = computeMax;
|
|
9916
10165
|
exports.computeSlices = computeSlices;
|
|
@@ -9920,9 +10169,11 @@ exports.createCurrencyFormatter = createCurrencyFormatter;
|
|
|
9920
10169
|
exports.defaultCountries = uniqueCountries;
|
|
9921
10170
|
exports.defaultCurrencyOptions = defaultCurrencyOptions;
|
|
9922
10171
|
exports.defaultTranslations = defaultTranslations$5;
|
|
10172
|
+
exports.deriveLindaTones = deriveLindaTones;
|
|
9923
10173
|
exports.dismissControlProps = dismissControlProps;
|
|
9924
10174
|
exports.forceLightOnlyThemeBeforeReact = forceLightOnlyThemeBeforeReact;
|
|
9925
10175
|
exports.formatAuroraThemeTooltip = formatAuroraThemeTooltip;
|
|
10176
|
+
exports.formatDonutPercent = formatDonutPercent;
|
|
9926
10177
|
exports.generateThemeColorScale = generateThemeColorScale;
|
|
9927
10178
|
exports.getContrastForeground = getContrastForeground;
|
|
9928
10179
|
exports.getRegisteredThemeColorBases = getRegisteredThemeColorBases;
|
|
@@ -9935,9 +10186,12 @@ exports.isDonutEmpty = isDonutEmpty;
|
|
|
9935
10186
|
exports.isExactThemeColor = isExactThemeColor;
|
|
9936
10187
|
exports.isGroupState = isGroupState;
|
|
9937
10188
|
exports.isHexColor = isHexColor;
|
|
10189
|
+
exports.isInsideDismissContainer = isInsideDismissContainer;
|
|
9938
10190
|
exports.isRankedBarListEmpty = isRankedBarListEmpty;
|
|
9939
10191
|
exports.isSegmentationGroup = isSegmentationGroup;
|
|
10192
|
+
exports.parseHslTriplet = parseHslTriplet;
|
|
9940
10193
|
exports.removeCustomPrimaryColor = removeCustomPrimaryColor;
|
|
10194
|
+
exports.removeLindaTones = removeLindaTones;
|
|
9941
10195
|
exports.shouldClosePopoverOnInteractOutside = shouldClosePopoverOnInteractOutside;
|
|
9942
10196
|
exports.sizeMap = sizeMap;
|
|
9943
10197
|
exports.themeColors = themeColors;
|
|
@@ -9946,6 +10200,7 @@ exports.useCloseOnAncestorScroll = useCloseOnAncestorScroll;
|
|
|
9946
10200
|
exports.useMediaQuery = useMediaQuery;
|
|
9947
10201
|
exports.useNavigationLoading = useNavigationLoading;
|
|
9948
10202
|
exports.useThemeContext = useThemeContext;
|
|
10203
|
+
exports.withPopoverDismissDefaults = withPopoverDismissDefaults;
|
|
9949
10204
|
Object.keys(react).forEach(function (k) {
|
|
9950
10205
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
9951
10206
|
enumerable: true,
|