@beweco/aurora-ui 0.6.61 → 0.6.63

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.cjs.js CHANGED
@@ -341,7 +341,7 @@ var Input = function (_a) {
341
341
  } })));
342
342
  };
343
343
 
344
- var defaultTranslations$f = {
344
+ var defaultTranslations$g = {
345
345
  addHolidayTitle: "Add holiday",
346
346
  dayOption: "Day",
347
347
  dateRangeOption: "Date range",
@@ -365,7 +365,7 @@ var INITIAL_HOLIDAY_STATE = {
365
365
  */
366
366
  var AddHolidayForm = function (_a) {
367
367
  var onAddHoliday = _a.onAddHoliday, translations = _a.translations, className = _a.className, radioGroupProps = _a.radioGroupProps, dateRangePickerProps = _a.dateRangePickerProps, buttonProps = _a.buttonProps;
368
- var t = __assign(__assign({}, defaultTranslations$f), translations);
368
+ var t = __assign(__assign({}, defaultTranslations$g), translations);
369
369
  var _b = React.useState(INITIAL_HOLIDAY_STATE), newHoliday = _b[0], setNewHoliday = _b[1];
370
370
  /**
371
371
  * A boolean flag that determines if a date has been set.
@@ -435,7 +435,7 @@ var P = function (_a) {
435
435
  return (jsxRuntime.jsx("p", __assign({ className: react.cn("text-tiny text-default-500 font-normal", className) }, props, { children: children })));
436
436
  };
437
437
 
438
- var defaultTranslations$e = {
438
+ var defaultTranslations$f = {
439
439
  title: "Analytics",
440
440
  description: "Monthly growth of your metrics during the selected period",
441
441
  viewDetails: "View Details",
@@ -489,7 +489,7 @@ var formatMonth = function (month) {
489
489
  var AnalyticsCard = function (_a) {
490
490
  var _b, _c;
491
491
  var data = _a.data, _d = _a.showTimePeriods, showTimePeriods = _d === void 0 ? true : _d, _e = _a.showDropdownMenu, showDropdownMenu = _e === void 0 ? true : _e, _f = _a.showMetricCards, showMetricCards = _f === void 0 ? true : _f, onChartChange = _a.onChartChange, onMenuAction = _a.onMenuAction, onTimePeriodChange = _a.onTimePeriodChange, _g = _a.translations, translations = _g === void 0 ? {} : _g, props = __rest(_a, ["data", "showTimePeriods", "showDropdownMenu", "showMetricCards", "onChartChange", "onMenuAction", "onTimePeriodChange", "translations"]);
492
- var t = __assign(__assign({}, defaultTranslations$e), translations);
492
+ var t = __assign(__assign({}, defaultTranslations$f), translations);
493
493
  var _h = React.useState((_c = (_b = data[0]) === null || _b === void 0 ? void 0 : _b.key) !== null && _c !== void 0 ? _c : ""), activeChart = _h[0], setActiveChart = _h[1];
494
494
  var activeChartData = React.useMemo(function () {
495
495
  var _a;
@@ -652,7 +652,7 @@ var DEFAULT_PREDEFINED_COLORS = [
652
652
  /**
653
653
  * Default translations (Spanish)
654
654
  */
655
- var defaultTranslations$d = {
655
+ var defaultTranslations$e = {
656
656
  label: "Color",
657
657
  placeholder: "Ingresa código hex",
658
658
  customColorLabel: "Color personalizado",
@@ -717,7 +717,7 @@ var ColorPicker = React.forwardRef(function (_a, ref) {
717
717
  var value = _a.value, onChange = _a.onChange, label = _a.label, _b = _a.required, required = _b === void 0 ? false : _b, _c = _a.disabled, disabled = _c === void 0 ? false : _c, _d = _a.error, error = _d === void 0 ? false : _d, errorText = _a.errorText, _e = _a.predefinedColors, predefinedColors = _e === void 0 ? DEFAULT_PREDEFINED_COLORS : _e, _f = _a.enableRecentColors, enableRecentColors = _f === void 0 ? true : _f, _g = _a.maxRecentColors, maxRecentColors = _g === void 0 ? 6 : _g, _h = _a.recentColorsStorageKey, recentColorsStorageKey = _h === void 0 ? "aurora-ui-recent-colors" : _h, _j = _a.showPredefinedColors, showPredefinedColors = _j === void 0 ? true : _j, _k = _a.translations, translations = _k === void 0 ? {} : _k, _l = _a.className, className = _l === void 0 ? "" : _l, id = _a.id, name = _a.name;
718
718
  var generatedId = React.useId();
719
719
  var inputId = id || generatedId;
720
- var t = __assign(__assign({}, defaultTranslations$d), translations);
720
+ var t = __assign(__assign({}, defaultTranslations$e), translations);
721
721
  // Local state for text input — holds the hex digits WITHOUT the leading "#".
722
722
  // The "#" is rendered as a fixed startContent prefix.
723
723
  var _m = React.useState(stripHash(value)), textValue = _m[0], setTextValue = _m[1];
@@ -1848,7 +1848,7 @@ var countries = [
1848
1848
  ];
1849
1849
  var uniqueCountries = Array.from(new Map(countries.map(function (item) { return [item.code + item.name, item]; })).values());
1850
1850
  // Traducciones por defecto
1851
- var defaultTranslations$c = {
1851
+ var defaultTranslations$d = {
1852
1852
  label: "Teléfono",
1853
1853
  placeholder: "Número de teléfono",
1854
1854
  searchPlaceholder: "Buscar país...",
@@ -1932,7 +1932,7 @@ var defaultCurrencyOptions = (function () {
1932
1932
  euroOption
1933
1933
  ], false), base.slice(zaIdx + 1), true);
1934
1934
  })();
1935
- var defaultTranslations$b = {
1935
+ var defaultTranslations$c = {
1936
1936
  label: "Importe",
1937
1937
  placeholder: "0",
1938
1938
  searchPlaceholder: "Buscar país o moneda...",
@@ -2397,7 +2397,7 @@ var Currency = function (_a) {
2397
2397
  var portalDropdownRef = React.useRef(null);
2398
2398
  var _q = React.useState({}), dropdownPosition = _q[0], setDropdownPosition = _q[1];
2399
2399
  var _r = React.useState(options), filteredOptions = _r[0], setFilteredOptions = _r[1];
2400
- var t = __assign(__assign({}, defaultTranslations$b), translations);
2400
+ var t = __assign(__assign({}, defaultTranslations$c), translations);
2401
2401
  var getCountryName = function (opt) { var _a, _b; return (_b = (_a = t.countries) === null || _a === void 0 ? void 0 : _a[opt.country]) !== null && _b !== void 0 ? _b : opt.name; };
2402
2402
  var finalLabel = label !== null && label !== void 0 ? label : t.label;
2403
2403
  React.useEffect(function () {
@@ -2557,7 +2557,7 @@ function useBreakpoint() {
2557
2557
  }
2558
2558
 
2559
2559
  // Default translations in Spanish
2560
- var defaultTranslations$a = {
2560
+ var defaultTranslations$b = {
2561
2561
  emptyStateMessage: "No hay contenido disponible",
2562
2562
  emptyStateButtonText: "Agregar contenido",
2563
2563
  previousButtonLabel: "Anterior",
@@ -2583,7 +2583,7 @@ var defaultTranslations$a = {
2583
2583
  */
2584
2584
  var ContentCarousel = function (_a) {
2585
2585
  var items = _a.items, onItemClick = _a.onItemClick, _b = _a.className, className = _b === void 0 ? "" : _b, _c = _a.emptyStateRedirectPath, emptyStateRedirectPath = _c === void 0 ? "" : _c, _d = _a.translations, translations = _d === void 0 ? {} : _d, renderFooter = _a.renderFooter, renderHeader = _a.renderHeader, renderBody = _a.renderBody, _e = _a.haveChip, haveChip = _e === void 0 ? false : _e;
2586
- var t = __assign(__assign({}, defaultTranslations$a), translations);
2586
+ var t = __assign(__assign({}, defaultTranslations$b), translations);
2587
2587
  var breakpoint = useBreakpoint();
2588
2588
  var isMobile = breakpoint === "mobile";
2589
2589
  var isTablet = breakpoint === "tablet";
@@ -2788,7 +2788,7 @@ function CarouselItemComponent(_a) {
2788
2788
  }
2789
2789
 
2790
2790
  // Default translations in Spanish
2791
- var defaultTranslations$9 = {
2791
+ var defaultTranslations$a = {
2792
2792
  editButtonLabel: "Editar",
2793
2793
  deleteButtonLabel: "Eliminar",
2794
2794
  publishButtonLabel: "Publicar",
@@ -2815,7 +2815,7 @@ var defaultTranslations$9 = {
2815
2815
  */
2816
2816
  var SocialMediaBar = function (_a) {
2817
2817
  var platform = _a.platform, _b = _a.badgeOnly, badgeOnly = _b === void 0 ? false : _b, _c = _a.showPreview, showPreview = _c === void 0 ? false : _c, onEdit = _a.onEdit, onDelete = _a.onDelete, onPublish = _a.onPublish, onPreview = _a.onPreview, _d = _a.actionsAlwaysVisible, actionsAlwaysVisible = _d === void 0 ? false : _d, _e = _a.isHovered, isHovered = _e === void 0 ? false : _e, _f = _a.className, className = _f === void 0 ? "" : _f, _g = _a.translations, translations = _g === void 0 ? {} : _g, customBadge = _a.customBadge, customActions = _a.customActions;
2818
- var t = __assign(__assign({}, defaultTranslations$9), translations);
2818
+ var t = __assign(__assign({}, defaultTranslations$a), translations);
2819
2819
  // Determine visibility of actions
2820
2820
  var showActions = actionsAlwaysVisible || isHovered;
2821
2821
  return (jsxRuntime.jsxs("div", { className: "flex items-center justify-between ".concat(className), children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [customBadge || (jsxRuntime.jsxs("div", { className: "backdrop-blur-xl border border-white/30 rounded-full px-3 py-1.5 shadow-xl flex items-center gap-2", style: {
@@ -2891,7 +2891,7 @@ var SocialMediaCarousel = function (_a) {
2891
2891
  };
2892
2892
 
2893
2893
  // Traducciones por defecto en español
2894
- var defaultTranslations$8 = {
2894
+ var defaultTranslations$9 = {
2895
2895
  dayOption: "Día específico",
2896
2896
  dateRangeOption: "Rango de fechas",
2897
2897
  selectDateAriaLabel: "Seleccionar fecha",
@@ -2909,7 +2909,7 @@ var DateSelector = function (_a) {
2909
2909
  var _f = React.useState(initialDate || null), date = _f[0], setDate = _f[1];
2910
2910
  var _g = React.useState(initialDateRange || null), dateRange = _g[0], setDateRange = _g[1];
2911
2911
  // Combinar traducciones por defecto con las proporcionadas
2912
- var t = __assign(__assign({}, defaultTranslations$8), translations);
2912
+ var t = __assign(__assign({}, defaultTranslations$9), translations);
2913
2913
  var handleTypeChange = function (value) {
2914
2914
  var newType = value;
2915
2915
  setType(newType);
@@ -3221,7 +3221,7 @@ var KanbanComponent = function (_a) {
3221
3221
  var Kanban = React.memo(KanbanComponent);
3222
3222
  Kanban.displayName = "Kanban";
3223
3223
 
3224
- var defaultTranslations$7 = {
3224
+ var defaultTranslations$8 = {
3225
3225
  previewAlt: "Vista previa de imagen",
3226
3226
  removeButtonAriaLabel: "Eliminar imagen",
3227
3227
  emptyStateText: "No hay imágenes para mostrar",
@@ -3254,7 +3254,7 @@ var normalizeImages = function (images) {
3254
3254
  };
3255
3255
  var ImagePreview = function (_a) {
3256
3256
  var images = _a.images, _b = _a.size, size = _b === void 0 ? "small" : _b, onRemove = _a.onRemove, _c = _a.showRemoveButton, showRemoveButton = _c === void 0 ? true : _c, _d = _a.className, className = _d === void 0 ? "" : _d, _e = _a.translations, translations = _e === void 0 ? {} : _e, _f = _a.backgroundColor, backgroundColor = _f === void 0 ? "bg-white dark:bg-gray-800" : _f, _g = _a.radius, radius = _g === void 0 ? "lg" : _g, _h = _a.showBorder, showBorder = _h === void 0 ? true : _h, onImageClick = _a.onImageClick;
3257
- var t = __assign(__assign({}, defaultTranslations$7), translations);
3257
+ var t = __assign(__assign({}, defaultTranslations$8), translations);
3258
3258
  var normalizedImages = normalizeImages(images);
3259
3259
  var sizeClass = sizeClasses[size];
3260
3260
  var radiusClass = radiusClasses[radius];
@@ -3780,7 +3780,7 @@ var VALID_STEP_COLORS$1 = [
3780
3780
  "danger",
3781
3781
  "default",
3782
3782
  ];
3783
- var defaultTranslations$6 = {
3783
+ var defaultTranslations$7 = {
3784
3784
  checkIconTitle: "Check",
3785
3785
  };
3786
3786
  function getContainerCSSVars$1(color) {
@@ -3825,7 +3825,7 @@ function getCircleStyle$1(status) {
3825
3825
  var VerticalSteps = React.forwardRef(function (_a, ref) {
3826
3826
  var _b = _a.color, color = _b === void 0 ? "primary" : _b, _c = _a.steps, stepsProp = _c === void 0 ? [] : _c, _d = _a.defaultStep, defaultStep = _d === void 0 ? 0 : _d, onStepChange = _a.onStepChange, currentStepProp = _a.currentStep, _e = _a.hideProgressBars, hideProgressBars = _e === void 0 ? false : _e, _f = _a.hideInactiveDescriptions, hideInactiveDescriptions = _f === void 0 ? false : _f, stepClassName = _a.stepClassName, className = _a.className, translations = _a.translations, props = __rest(_a, ["color", "steps", "defaultStep", "onStepChange", "currentStep", "hideProgressBars", "hideInactiveDescriptions", "stepClassName", "className", "translations"]);
3827
3827
  var _g = $458b0a5536c1a7cf$export$40bfa8c7b0832715(currentStepProp, defaultStep, onStepChange), currentStep = _g[0], setCurrentStep = _g[1];
3828
- var t = __assign(__assign({}, defaultTranslations$6), translations);
3828
+ var t = __assign(__assign({}, defaultTranslations$7), translations);
3829
3829
  var steps = React.useMemo(function () {
3830
3830
  if (typeof stepsProp === "number") {
3831
3831
  return Array.from({ length: stepsProp }, function () { return ({}); });
@@ -3989,7 +3989,7 @@ var Phone = function (_a) {
3989
3989
  var portalDropdownRef = React.useRef(null);
3990
3990
  var _l = React.useState({}), dropdownPosition = _l[0], setDropdownPosition = _l[1];
3991
3991
  var _m = React.useState(uniqueCountries), filteredCountries = _m[0], setFilteredCountries = _m[1];
3992
- var t = __assign(__assign({}, defaultTranslations$c), translations);
3992
+ var t = __assign(__assign({}, defaultTranslations$d), translations);
3993
3993
  var getCountryName = function (country) { var _a, _b; return (_b = (_a = t.countries) === null || _a === void 0 ? void 0 : _a[country.country]) !== null && _b !== void 0 ? _b : country.name; };
3994
3994
  var finalLabel = label || t.label;
3995
3995
  React.useEffect(function () {
@@ -4088,7 +4088,7 @@ var Phone = function (_a) {
4088
4088
  : ""), onClick: function () { return handleCountrySelect(country); }, children: [jsxRuntime.jsx("span", { className: "mr-3", children: jsxRuntime.jsx(FlagIcon, { countryCode: country.country, size: "md" }) }), jsxRuntime.jsx("span", { className: "flex-1 text-left text-default-500", children: getCountryName(country) }), jsxRuntime.jsx("span", { className: "text-xs text-default-500", children: country.code })] }, "".concat(country.code, "-").concat(country.country))); })) : (jsxRuntime.jsx("div", { className: "px-4 py-2 text-sm text-default-500", children: t.noCountriesFound })) })] }), document.body)] }));
4089
4089
  };
4090
4090
 
4091
- var defaultTranslations$5 = {
4091
+ var defaultTranslations$6 = {
4092
4092
  message: "The Winter 2024 Release is here: new editor, analytics API, and so much more.",
4093
4093
  buttonText: "Explore",
4094
4094
  closeButtonLabel: "Close Banner",
@@ -4098,7 +4098,7 @@ var defaultTranslations$5 = {
4098
4098
  */
4099
4099
  var PromotionalBanner = function (_a) {
4100
4100
  var message = _a.message, buttonText = _a.buttonText, _b = _a.messageHref, messageHref = _b === void 0 ? "#" : _b, _c = _a.buttonHref, buttonHref = _c === void 0 ? "#" : _c, _d = _a.showCloseButton, showCloseButton = _d === void 0 ? true : _d, _e = _a.isVisible, isVisible = _e === void 0 ? true : _e, _f = _a.gradientColors, gradientColors = _f === void 0 ? ["default-100", "danger-100", "secondary-100"] : _f, _g = _a.buttonGradientColors, buttonGradientColors = _g === void 0 ? ["#F871A0", "#9353D3"] : _g, onClose = _a.onClose, onMessageClick = _a.onMessageClick, onButtonClick = _a.onButtonClick, _h = _a.messageLinkProps, messageLinkProps = _h === void 0 ? {} : _h, _j = _a.buttonProps, buttonProps = _j === void 0 ? {} : _j, _k = _a.translations, translations = _k === void 0 ? {} : _k;
4101
- var t = __assign(__assign({}, defaultTranslations$5), translations);
4101
+ var t = __assign(__assign({}, defaultTranslations$6), translations);
4102
4102
  var finalMessage = message || t.message;
4103
4103
  var finalButtonText = buttonText || t.buttonText;
4104
4104
  var handleClose = function () {
@@ -5015,7 +5015,7 @@ var TimeInput = function (_a) {
5015
5015
  * />
5016
5016
  * ```
5017
5017
  */
5018
- var defaultTranslations$4 = {
5018
+ var defaultTranslations$5 = {
5019
5019
  /** Label for the start time input field */
5020
5020
  from: "Desde",
5021
5021
  /** Label for the end time input field */
@@ -5073,7 +5073,7 @@ var defaultTranslations$4 = {
5073
5073
  */
5074
5074
  var ScheduleRow = function (_a) {
5075
5075
  var day = _a.day, daySchedule = _a.daySchedule, _b = _a.translations, translations = _b === void 0 ? {} : _b, _c = _a.showCopyToAll, showCopyToAll = _c === void 0 ? false : _c, onChange = _a.onChange, onCopyToAll = _a.onCopyToAll;
5076
- var t = __assign(__assign({}, defaultTranslations$4), translations);
5076
+ var t = __assign(__assign({}, defaultTranslations$5), translations);
5077
5077
  /**
5078
5078
  * @function validateTimeSlots
5079
5079
  * @description Validates all time slots to ensure the "from" time is not after the "to" time.
@@ -5226,7 +5226,7 @@ var Select = function (_a) {
5226
5226
  } })) }));
5227
5227
  };
5228
5228
 
5229
- var defaultTranslations$3 = {
5229
+ var defaultTranslations$4 = {
5230
5230
  username: "tu_negocio",
5231
5231
  sendMessage: "Enviar mensaje",
5232
5232
  viewMore: "ver más",
@@ -5251,7 +5251,7 @@ var defaultTranslations$3 = {
5251
5251
  */
5252
5252
  var SocialMediaPreview = function (_a) {
5253
5253
  var platform = _a.platform, imageUrl = _a.imageUrl, caption = _a.caption, _b = _a.variant, variant = _b === void 0 ? "full" : _b, _c = _a.postAspectRatio, postAspectRatio = _c === void 0 ? "square" : _c, _d = _a.showHeader, showHeader = _d === void 0 ? true : _d, _e = _a.maxCaptionLength, maxCaptionLength = _e === void 0 ? 125 : _e, onToggleCaption = _a.onToggleCaption, showFullCaption = _a.showFullCaption, username = _a.username, avatarUrl = _a.avatarUrl, _f = _a.translations, translations = _f === void 0 ? {} : _f, _g = _a.className, className = _g === void 0 ? "" : _g, _h = _a.imageProps, imageProps = _h === void 0 ? {} : _h, _j = _a.showEditButton, showEditButton = _j === void 0 ? false : _j, onEditClick = _a.onEditClick;
5254
- var t = __assign(__assign({}, defaultTranslations$3), translations);
5254
+ var t = __assign(__assign({}, defaultTranslations$4), translations);
5255
5255
  var displayUsername = username || t.username;
5256
5256
  var shouldTruncate = variant === "compact" && caption.length > maxCaptionLength;
5257
5257
  // Get aspect ratio based on postAspectRatio prop
@@ -5333,7 +5333,7 @@ var Textarea = function (_a) {
5333
5333
  };
5334
5334
 
5335
5335
  // Traducciones por defecto en español según las reglas de diseño
5336
- var defaultTranslations$2 = {
5336
+ var defaultTranslations$3 = {
5337
5337
  lightTheme: "Claro",
5338
5338
  darkTheme: "Oscuro",
5339
5339
  };
@@ -5349,7 +5349,7 @@ var defaultTranslations$2 = {
5349
5349
  var ThemePicker = function (_a) {
5350
5350
  var value = _a.value, onChange = _a.onChange, className = _a.className, _b = _a.translations, translations = _b === void 0 ? {} : _b;
5351
5351
  // Combinar traducciones por defecto con las proporcionadas
5352
- var t = __assign(__assign({}, defaultTranslations$2), translations);
5352
+ var t = __assign(__assign({}, defaultTranslations$3), translations);
5353
5353
  var themes = [
5354
5354
  {
5355
5355
  key: "light",
@@ -5778,7 +5778,7 @@ var TwoColumnLayoutAgent = function (_a) {
5778
5778
  };
5779
5779
 
5780
5780
  // Traducciones por defecto en español
5781
- var defaultTranslations$1 = {
5781
+ var defaultTranslations$2 = {
5782
5782
  uploadText: "Da clic y selecciona tus archivos",
5783
5783
  subText: "",
5784
5784
  dragText: "Suelta el archivo aquí",
@@ -6128,7 +6128,7 @@ var UploadFile = function (_a) {
6128
6128
  var _q = React.useState(""), selectedImageUrl = _q[0], setSelectedImageUrl = _q[1];
6129
6129
  var _r = React.useState(null); _r[0]; var setOriginalFile = _r[1];
6130
6130
  // Combinar traducciones por defecto con las proporcionadas
6131
- var t = React.useMemo(function () { return (__assign(__assign({}, defaultTranslations$1), translations)); }, [translations]);
6131
+ var t = React.useMemo(function () { return (__assign(__assign({}, defaultTranslations$2), translations)); }, [translations]);
6132
6132
  // Actualizar texto si se pasa como prop (retrocompatibilidad)
6133
6133
  var finalText = text || t.uploadText;
6134
6134
  var finalSubText = subText || t.subText;
@@ -6314,6 +6314,185 @@ var UploadFile = function (_a) {
6314
6314
  };
6315
6315
  UploadFile.displayName = "UploadFile";
6316
6316
 
6317
+ /**
6318
+ * Jitter pseudo-aleatorio determinista en [0,1), sembrado SOLO por el índice.
6319
+ * Misma constante Knuth (2654435761) que `computeStripJitter`/`computeBoxJitter`
6320
+ * de beweanalytics — nunca `Math.random()`.
6321
+ */
6322
+ function jitter(index) {
6323
+ return ((index * 2654435761) % 1000) / 1000;
6324
+ }
6325
+ /**
6326
+ * Cuartiles por interpolación lineal (R-7, el default de numpy/Excel).
6327
+ * Espeja `computeQuartiles` de beweanalytics para coherencia entre repos.
6328
+ */
6329
+ function computeQuartilesFromRaw(values) {
6330
+ if (values.length === 0) {
6331
+ return { min: 0, q1: 0, median: 0, q3: 0, max: 0 };
6332
+ }
6333
+ var sorted = __spreadArray([], values, true).sort(function (a, b) { return a - b; });
6334
+ var n = sorted.length;
6335
+ var first = sorted[0];
6336
+ var last = sorted[n - 1];
6337
+ var percentile = function (p) {
6338
+ if (n === 1) {
6339
+ return first;
6340
+ }
6341
+ var h = (n - 1) * p;
6342
+ var lo = Math.floor(h);
6343
+ var hi = Math.ceil(h);
6344
+ var loVal = sorted[lo];
6345
+ if (lo === hi) {
6346
+ return loVal;
6347
+ }
6348
+ var hiVal = sorted[hi];
6349
+ return loVal + (h - lo) * (hiVal - loVal);
6350
+ };
6351
+ return {
6352
+ min: first,
6353
+ q1: percentile(0.25),
6354
+ median: percentile(0.5),
6355
+ q3: percentile(0.75),
6356
+ max: last,
6357
+ };
6358
+ }
6359
+ /** Un grupo cae al fallback si tiene pocos datos o trae valores crudos. */
6360
+ function shouldFallback(group, minN) {
6361
+ var _a, _b;
6362
+ return group.n < minN || ((_b = (_a = group.rawValues) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
6363
+ }
6364
+ var TO_SECONDS = {
6365
+ s: 1,
6366
+ min: 60,
6367
+ h: 3600,
6368
+ d: 86400,
6369
+ };
6370
+ /**
6371
+ * Elige la unidad de display (s/min/h/d) más legible para un valor de
6372
+ * referencia (típicamente la mediana) y devuelve el `factor` por el que
6373
+ * multiplicar los valores en `baseUnit` para obtener la unidad elegida.
6374
+ */
6375
+ function pickDisplayUnit(value, base) {
6376
+ if (base === "none") {
6377
+ return { unit: "", factor: 1 };
6378
+ }
6379
+ var seconds = Math.abs(value) * TO_SECONDS[base];
6380
+ var unit = "s";
6381
+ if (seconds >= TO_SECONDS.d) {
6382
+ unit = "d";
6383
+ }
6384
+ else if (seconds >= TO_SECONDS.h) {
6385
+ unit = "h";
6386
+ }
6387
+ else if (seconds >= TO_SECONDS.min) {
6388
+ unit = "min";
6389
+ }
6390
+ return { unit: unit, factor: TO_SECONDS[base] / TO_SECONDS[unit] };
6391
+ }
6392
+ /**
6393
+ * Path SVG del cuerpo del violin: polígono cerrado y espejado sobre `centerX`.
6394
+ * El ancho de cada bin es proporcional a su count (normalizado al bin máximo)
6395
+ * escalado a `halfWidth` px. `valueToY` mapea el valor medio del bin a la Y en px.
6396
+ */
6397
+ function buildDensityPath(bins, centerX, halfWidth, valueToY) {
6398
+ if (bins.length === 0) {
6399
+ return "";
6400
+ }
6401
+ var maxCount = Math.max.apply(Math, __spreadArray(__spreadArray([], bins.map(function (b) { return b.count; }), false), [1], false));
6402
+ var pts = bins.map(function (b) {
6403
+ var mid = (b.x0 + b.x1) / 2;
6404
+ return { y: valueToY(mid), w: (b.count / maxCount) * halfWidth };
6405
+ });
6406
+ var right = pts.map(function (p) { return "".concat(centerX + p.w, ",").concat(p.y); });
6407
+ var left = __spreadArray([], pts, true).reverse().map(function (p) { return "".concat(centerX - p.w, ",").concat(p.y); });
6408
+ return "M ".concat(right.join(" L "), " L ").concat(left.join(" L "), " Z");
6409
+ }
6410
+
6411
+ var COLOR_STROKE$1 = "#4338ca";
6412
+ var COLOR_MEDIAN$1 = "#1e3a8a";
6413
+ var COLOR_POINT = "#6366f1";
6414
+ var BOX_HALF = 10;
6415
+ var JITTER_SPAN = 22;
6416
+ /**
6417
+ * Fallback para grupos con n<20: caja (q1–q3) + mediana + puntos crudos con
6418
+ * jitter horizontal determinista. Un violin de 8 puntos miente; aquí se ve cada
6419
+ * punto real (caso Guru). Si faltan `rawValues`, cae a caja desde percentiles.
6420
+ */
6421
+ function ViolinFallback(_a) {
6422
+ var _b;
6423
+ var group = _a.group, centerX = _a.centerX, valueToY = _a.valueToY;
6424
+ var raw = (_b = group.rawValues) !== null && _b !== void 0 ? _b : [];
6425
+ var q = raw.length > 0
6426
+ ? computeQuartilesFromRaw(raw)
6427
+ : {
6428
+ min: group.p5,
6429
+ q1: group.p25,
6430
+ median: group.p50,
6431
+ q3: group.p75,
6432
+ max: group.p95,
6433
+ };
6434
+ return (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("line", { x1: centerX, x2: centerX, y1: valueToY(q.min), y2: valueToY(q.max), stroke: COLOR_STROKE$1, strokeWidth: 1 }), jsxRuntime.jsx("rect", { x: centerX - BOX_HALF, y: valueToY(q.q3), width: BOX_HALF * 2, height: Math.max(0, valueToY(q.q1) - valueToY(q.q3)), fill: COLOR_STROKE$1, fillOpacity: 0.18, stroke: COLOR_STROKE$1 }), jsxRuntime.jsx("line", { x1: centerX - BOX_HALF, x2: centerX + BOX_HALF, y1: valueToY(q.median), y2: valueToY(q.median), stroke: COLOR_MEDIAN$1, strokeWidth: 2 }), raw.map(function (value, idx) { return (jsxRuntime.jsx("circle", { cx: centerX + (jitter(idx) - 0.5) * JITTER_SPAN, cy: valueToY(value), r: 2.5, fill: COLOR_POINT, fillOpacity: 0.8 }, "".concat(value, "-").concat(idx))); })] }));
6435
+ }
6436
+
6437
+ var MARGIN = { top: 24, right: 16, bottom: 40, left: 44 };
6438
+ var VIEW_WIDTH = 640;
6439
+ var VIOLIN_HALF_WIDTH = 46;
6440
+ var COLOR_BODY = "#c7d2fe";
6441
+ var COLOR_STROKE = "#4338ca";
6442
+ var COLOR_MEDIAN = "#1e3a8a";
6443
+ var COLOR_AXIS = "#6b7280";
6444
+ var defaultTranslations$1 = {
6445
+ emptyState: "Sin datos de distribución",
6446
+ sampleSizeLabel: "n",
6447
+ outliersLabel: "outliers",
6448
+ };
6449
+ function formatTick(value, factor, unit) {
6450
+ var scaled = value * factor;
6451
+ var rounded = Math.round(scaled * 10) / 10;
6452
+ return unit ? "".concat(rounded).concat(unit) : "".concat(rounded);
6453
+ }
6454
+ /**
6455
+ * ViolinPlot — distribución por grupo como densidad espejada (SVG puro), con
6456
+ * mediana/cuartiles superpuestos y `n=` visible. Cuando un grupo tiene n<20 (o
6457
+ * trae `rawValues`) degrada a box/strip (`ViolinFallback`): un violin de pocos
6458
+ * puntos miente. La estadística llega pre-calculada del SQL (payload chico).
6459
+ *
6460
+ * Sin `ResponsiveContainer` (no renderiza en happy-dom y complica el test):
6461
+ * `<svg viewBox>` + `width="100%"`. Autocontenido, sin HeroUI, para render
6462
+ * server-side directo en tests.
6463
+ */
6464
+ function ViolinPlot(_a) {
6465
+ var groups = _a.groups, valueLabel = _a.valueLabel, _b = _a.baseUnit, baseUnit = _b === void 0 ? "none" : _b, formatValue = _a.formatValue, _c = _a.height, height = _c === void 0 ? 320 : _c, _d = _a.minSampleForViolin, minSampleForViolin = _d === void 0 ? 20 : _d, _e = _a.translations, translations = _e === void 0 ? {} : _e;
6466
+ var t = __assign(__assign({}, defaultTranslations$1), translations);
6467
+ if (groups.length === 0) {
6468
+ return (jsxRuntime.jsx("svg", { viewBox: "0 0 ".concat(VIEW_WIDTH, " ").concat(height), width: "100%", role: "img", "aria-label": valueLabel, children: jsxRuntime.jsx("text", { x: VIEW_WIDTH / 2, y: height / 2, textAnchor: "middle", fill: COLOR_AXIS, children: t.emptyState }) }));
6469
+ }
6470
+ var plotTop = MARGIN.top;
6471
+ var plotBottom = height - MARGIN.bottom;
6472
+ var plotHeight = plotBottom - plotTop;
6473
+ // Escala Y común a todos los grupos (de 0 al p95 máximo, con margen).
6474
+ var maxValue = Math.max.apply(Math, __spreadArray(__spreadArray([], groups.map(function (g) { return g.p95; }), false), [1], false));
6475
+ var valueToY = function (v) {
6476
+ return plotBottom - (v / maxValue) * plotHeight;
6477
+ };
6478
+ var refMedian = groups.map(function (g) { return g.p50; }).sort(function (a, b) { return a - b; })[Math.floor(groups.length / 2)];
6479
+ var _f = pickDisplayUnit(refMedian, baseUnit), unit = _f.unit, factor = _f.factor;
6480
+ var fmt = formatValue !== null && formatValue !== void 0 ? formatValue : (function (v) { return formatTick(v, factor, unit); });
6481
+ var columnWidth = (VIEW_WIDTH - MARGIN.left - MARGIN.right) / groups.length;
6482
+ return (jsxRuntime.jsxs("svg", { viewBox: "0 0 ".concat(VIEW_WIDTH, " ").concat(height), width: "100%", role: "img", "aria-label": valueLabel, children: [[0, maxValue / 2, maxValue].map(function (v) { return (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("line", { x1: MARGIN.left, x2: VIEW_WIDTH - MARGIN.right, y1: valueToY(v), y2: valueToY(v), stroke: "#e5e7eb", strokeDasharray: "3 3" }), jsxRuntime.jsx("text", { x: MARGIN.left - 6, y: valueToY(v) + 4, textAnchor: "end", fontSize: 11, fill: COLOR_AXIS, children: fmt(v) })] }, v)); }), groups.map(function (group, i) {
6483
+ var centerX = MARGIN.left + columnWidth * (i + 0.5);
6484
+ return (jsxRuntime.jsxs("g", { children: [shouldFallback(group, minSampleForViolin) ? (jsxRuntime.jsx(ViolinFallback, { group: group, centerX: centerX, valueToY: valueToY })) : (jsxRuntime.jsx(ViolinBody, { group: group, centerX: centerX, valueToY: valueToY })), jsxRuntime.jsx("text", { x: centerX, y: plotBottom + 16, textAnchor: "middle", fontSize: 12, fill: COLOR_AXIS, children: group.label }), jsxRuntime.jsxs("text", { x: centerX, y: plotBottom + 30, textAnchor: "middle", fontSize: 10, fill: COLOR_AXIS, children: [t.sampleSizeLabel, "=", group.n, group.nExcluded > 0
6485
+ ? " \u00B7 \u2212".concat(group.nExcluded, " ").concat(t.outliersLabel)
6486
+ : ""] })] }, group.label));
6487
+ })] }));
6488
+ }
6489
+ function ViolinBody(_a) {
6490
+ var group = _a.group, centerX = _a.centerX, valueToY = _a.valueToY;
6491
+ var path = buildDensityPath(group.bins, centerX, VIOLIN_HALF_WIDTH, valueToY);
6492
+ var boxHalf = 8;
6493
+ return (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("path", { d: path, fill: COLOR_BODY, fillOpacity: 0.55, stroke: COLOR_STROKE, strokeWidth: 1 }), jsxRuntime.jsx("line", { x1: centerX, x2: centerX, y1: valueToY(group.p5), y2: valueToY(group.p95), stroke: COLOR_MEDIAN, strokeWidth: 1 }), jsxRuntime.jsx("rect", { x: centerX - boxHalf, y: valueToY(group.p75), width: boxHalf * 2, height: Math.max(0, valueToY(group.p25) - valueToY(group.p75)), fill: COLOR_STROKE, fillOpacity: 0.25, stroke: COLOR_STROKE }), jsxRuntime.jsx("line", { x1: centerX - boxHalf, x2: centerX + boxHalf, y1: valueToY(group.p50), y2: valueToY(group.p50), stroke: COLOR_MEDIAN, strokeWidth: 2 })] }));
6494
+ }
6495
+
6317
6496
  function resolvePreviewActions(previewAction, ctaType, ctaLabel, ctaValue) {
6318
6497
  var _a;
6319
6498
  var fromProp = (_a = previewAction === null || previewAction === void 0 ? void 0 : previewAction.filter(function (a) {
@@ -8158,11 +8337,13 @@ var SegmentationBuilder = React.forwardRef(function (_a, ref) {
8158
8337
  SegmentationBuilder.displayName = "SegmentationBuilder";
8159
8338
 
8160
8339
  var SENTINEL_KEY = "__tags-filter-sentinel__";
8340
+ var EMPTY_KEY = "__tags-filter-empty__";
8161
8341
  var DEFAULT_TRANSLATIONS = {
8162
8342
  placeholder: "Nombre de la etiqueta",
8163
8343
  labelSelect: "Selecciona etiqueta",
8164
8344
  labelSelected: "Etiquetas actuales",
8165
8345
  emptySelectedMessage: "No hay etiquetas seleccionadas",
8346
+ emptyAvailableMessage: "No hay etiquetas disponibles",
8166
8347
  errorLoadingPrefix: "Error al cargar etiquetas",
8167
8348
  loadingMoreLabel: "Cargando más etiquetas…",
8168
8349
  endOfListMessage: "",
@@ -8229,9 +8410,26 @@ function TagsFilter(_a) {
8229
8410
  });
8230
8411
  }, [items, inputValue, compareTags, onInputChange]);
8231
8412
  var filteredItems = getFilteredAvailable(selectedList);
8232
- var showSentinel = Boolean(onLoadMore) && (hasMore || Boolean(t.endOfListMessage));
8233
- var itemsWithSentinel = showSentinel
8234
- ? __spreadArray(__spreadArray([], filteredItems, true), [{ id: SENTINEL_KEY, value: "" }], false) : filteredItems;
8413
+ // El sentinel es quien monta el IntersectionObserver, así que tiene que
8414
+ // seguir en la colección mientras quede algo por traer o haya una carga en
8415
+ // curso: sin él, `onLoadMore` no se vuelve a disparar nunca.
8416
+ var showSentinel = Boolean(onLoadMore) &&
8417
+ (hasMore || isLoadingMore || Boolean(t.endOfListMessage));
8418
+ var isAvailableEmpty = filteredItems.length === 0;
8419
+ // Sin nada que ofrecer se inyecta un item de solo lectura con el mensaje de
8420
+ // vacío: así el desplegable explica por qué está vacío en vez de no abrirse
8421
+ // (o abrirse en blanco), y la colección nunca queda realmente vacía.
8422
+ //
8423
+ // Es el último recurso, no el primero: si aún hay páginas por cargar o una
8424
+ // petición en vuelo, gana el sentinel. De lo contrario bastaría con que la
8425
+ // página cargada no tuviera coincidencias (o con seleccionar todas sus
8426
+ // etiquetas) para anunciar "no hay etiquetas" y cortar la paginación.
8427
+ var canPaginate = Boolean(onLoadMore) && hasMore;
8428
+ var showEmptyItem = isAvailableEmpty && !canPaginate && !isLoadingMore;
8429
+ var itemsWithSentinel = showEmptyItem
8430
+ ? [{ id: EMPTY_KEY, value: "" }]
8431
+ : showSentinel
8432
+ ? __spreadArray(__spreadArray([], filteredItems, true), [{ id: SENTINEL_KEY, value: "" }], false) : filteredItems;
8235
8433
  var handleAutocompleteSelection = React.useCallback(function (key) {
8236
8434
  if (key == null) {
8237
8435
  return;
@@ -8250,9 +8448,16 @@ function TagsFilter(_a) {
8250
8448
  setInputValue(v);
8251
8449
  onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange(v);
8252
8450
  }, selectedKey: null, items: itemsWithSentinel, onSelectionChange: handleAutocompleteSelection,
8253
- // "focus" keeps the menu tied to focus; prefer opening when typing.
8254
- menuTrigger: "input",
8255
- // When the filtered list is empty, avoid keeping an open overlay that blocks the modal.
8451
+ // El item de vacío no es seleccionable ni navegable con teclado:
8452
+ // es un mensaje, no una opción.
8453
+ disabledKeys: [EMPTY_KEY],
8454
+ // TECH-1640: el desplegable abre al enfocar/hacer clic, no solo al
8455
+ // escribir. Un selector de etiquetas debe enseñar lo que hay sin
8456
+ // exigir que el usuario recuerde el nombre.
8457
+ menuTrigger: "focus",
8458
+ // Salvo carga en curso, la colección siempre trae algo que mostrar
8459
+ // (ver `itemsWithSentinel`). Se mantiene el flag para que un hueco
8460
+ // transitorio no abra un overlay vacío sobre el modal padre.
8256
8461
  allowsEmptyCollection: false, shouldCloseOnBlur: true, popoverProps: {
8257
8462
  // isNonModal: false would render a full-screen invisible backdrop that
8258
8463
  // intercepts pointer events, blocking the parent modal's close button.
@@ -8263,6 +8468,9 @@ function TagsFilter(_a) {
8263
8468
  className: "max-h-[200px] overflow-y-auto",
8264
8469
  }, className: "w-full", children: function (item) {
8265
8470
  var candidate = item;
8471
+ if (candidate.id === EMPTY_KEY) {
8472
+ return (jsxRuntime.jsx(react.AutocompleteItem, { textValue: t.emptyAvailableMessage, isReadOnly: true, className: "opacity-100 cursor-default data-[hover=true]:bg-transparent", children: jsxRuntime.jsx("span", { className: "text-tiny text-default-500", children: t.emptyAvailableMessage }) }, EMPTY_KEY));
8473
+ }
8266
8474
  if (candidate.id === SENTINEL_KEY) {
8267
8475
  return (jsxRuntime.jsx(react.AutocompleteItem, { textValue: "", isReadOnly: true, className: "opacity-100 cursor-default data-[hover=true]:bg-transparent", children: jsxRuntime.jsx("div", { ref: function (node) {
8268
8476
  var _a;
@@ -9107,6 +9315,7 @@ exports.Tooltip = Tooltip;
9107
9315
  exports.TwoColumnLayoutAgent = TwoColumnLayoutAgent;
9108
9316
  exports.UploadFile = UploadFile;
9109
9317
  exports.VerticalSteps = VerticalSteps;
9318
+ exports.ViolinPlot = ViolinPlot;
9110
9319
  exports.WhatsAppPreview = WhatsAppPreview;
9111
9320
  exports.Wizard = Wizard;
9112
9321
  exports.WizardNavigation = WizardNavigation;
@@ -9115,7 +9324,7 @@ exports.applyCustomPrimaryColor = applyCustomPrimaryColor;
9115
9324
  exports.createCurrencyFormatter = createCurrencyFormatter;
9116
9325
  exports.defaultCountries = uniqueCountries;
9117
9326
  exports.defaultCurrencyOptions = defaultCurrencyOptions;
9118
- exports.defaultTranslations = defaultTranslations$4;
9327
+ exports.defaultTranslations = defaultTranslations$5;
9119
9328
  exports.forceLightOnlyThemeBeforeReact = forceLightOnlyThemeBeforeReact;
9120
9329
  exports.formatAuroraThemeTooltip = formatAuroraThemeTooltip;
9121
9330
  exports.generateThemeColorScale = generateThemeColorScale;