@beweco/aurora-ui 0.6.41 → 0.6.43

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
@@ -6973,7 +6973,7 @@ var DayMonthPicker = function (_a) {
6973
6973
  var currentYearDate = $14e0f24ef4ac5c92$export$d0bdf45af03a6ea3($14e0f24ef4ac5c92$export$aa8b41735afcabd2());
6974
6974
  var pickerValue = (value === null || value === void 0 ? void 0 : value.type) === "dayMonth" ? value.dayMonth : null;
6975
6975
  var rangeValue = (value === null || value === void 0 ? void 0 : value.type) === "dayMonthRange" ? value.dayMonthRange : null;
6976
- return (jsxRuntime.jsxs("div", { className: "w-full flex flex-wrap xs:gap-5 justify-between items-center", children: [jsxRuntime.jsxs(react.RadioGroup, { color: "primary", orientation: "horizontal", size: "sm", value: mode, onValueChange: handleModeChange, children: [jsxRuntime.jsx(react.Radio, { value: "single", children: t.dayMonthSingleOption }), jsxRuntime.jsx(react.Radio, { value: "range", children: t.dayMonthRangeOption })] }), mode === "single" ? (pickerValue ? (jsxRuntime.jsx(DatePicker, { value: pickerValue, onChange: handleSingleChange, "aria-label": t.dayMonthAriaLabel, endContent: jsxRuntime.jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-40 ".concat(NO_YEAR_CLASS) }, "dmp-c")) : (jsxRuntime.jsx(DatePicker, { defaultValue: currentYearDate, onChange: handleSingleChange, "aria-label": t.dayMonthAriaLabel, endContent: jsxRuntime.jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-40 ".concat(NO_YEAR_CLASS) }, "dmp-u"))) : (rangeValue ? (jsxRuntime.jsx(DateRangePicker, { value: rangeValue, onChange: handleRangeChange, "aria-label": t.dayMonthRangeAriaLabel, endContent: jsxRuntime.jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-xs ".concat(NO_YEAR_CLASS) }, "dmpr-c")) : (jsxRuntime.jsx(DateRangePicker, { defaultValue: { start: currentYearDate, end: currentYearDate }, onChange: handleRangeChange, "aria-label": t.dayMonthRangeAriaLabel, endContent: jsxRuntime.jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-xs ".concat(NO_YEAR_CLASS) }, "dmpr-u")))] }));
6976
+ return (jsxRuntime.jsxs("div", { className: "w-full flex flex-wrap xs:gap-5 justify-between items-center", children: [jsxRuntime.jsxs(react.RadioGroup, { color: "primary", orientation: "horizontal", size: "sm", value: mode, onValueChange: handleModeChange, children: [jsxRuntime.jsx(react.Radio, { value: "single", children: t.dayMonthSingleOption }), jsxRuntime.jsx(react.Radio, { value: "range", children: t.dayMonthRangeOption })] }), mode === "single" ? (jsxRuntime.jsx(DatePicker, { value: pickerValue, placeholderValue: currentYearDate, onChange: handleSingleChange, "aria-label": t.dayMonthAriaLabel, endContent: jsxRuntime.jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-40 ".concat(NO_YEAR_CLASS) })) : (jsxRuntime.jsx(DateRangePicker, { value: rangeValue, placeholderValue: currentYearDate, onChange: handleRangeChange, "aria-label": t.dayMonthRangeAriaLabel, endContent: jsxRuntime.jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-xs ".concat(NO_YEAR_CLASS) }))] }));
6977
6977
  };
6978
6978
 
6979
6979
  /**
@@ -8198,17 +8198,21 @@ var SegmentationBuilder = React.forwardRef(function (_a, ref) {
8198
8198
  });
8199
8199
  SegmentationBuilder.displayName = "SegmentationBuilder";
8200
8200
 
8201
+ var SENTINEL_KEY = "__tags-filter-sentinel__";
8201
8202
  var DEFAULT_TRANSLATIONS = {
8202
8203
  placeholder: "Nombre de la etiqueta",
8203
8204
  labelSelect: "Selecciona etiqueta",
8204
8205
  labelSelected: "Etiquetas actuales",
8205
8206
  emptySelectedMessage: "No hay etiquetas seleccionadas",
8206
8207
  errorLoadingPrefix: "Error al cargar etiquetas",
8208
+ loadingMoreLabel: "Cargando más etiquetas…",
8209
+ endOfListMessage: "",
8207
8210
  };
8208
8211
  function toggleArrayItem(array, item, compareFn) {
8209
8212
  var index = array.findIndex(function (existing) { return compareFn(existing, item); });
8210
- if (index >= 0)
8213
+ if (index >= 0) {
8211
8214
  return array.filter(function (_, i) { return i !== index; });
8215
+ }
8212
8216
  return __spreadArray(__spreadArray([], array, true), [item], false);
8213
8217
  }
8214
8218
  var defaultCompareTags = function (a, b) {
@@ -8223,28 +8227,56 @@ var defaultGetTagKey = function (tag) { var _a; return (_a = tag.id) !== null &&
8223
8227
  * Cumple con i18n mediante la prop `translations`.
8224
8228
  */
8225
8229
  function TagsFilter(_a) {
8226
- var items = _a.items, value = _a.value, onChange = _a.onChange, _b = _a.translations, translations = _b === void 0 ? {} : _b, error = _a.error, _c = _a.isLoading, isLoading = _c === void 0 ? false : _c, _d = _a.className, className = _d === void 0 ? "" : _d, ariaLabel = _a["aria-label"], _e = _a.required, required = _e === void 0 ? false : _e, _f = _a.compareTags, compareTags = _f === void 0 ? defaultCompareTags : _f, _g = _a.getTagKey, getTagKey = _g === void 0 ? defaultGetTagKey : _g;
8230
+ var items = _a.items, value = _a.value, onChange = _a.onChange, _b = _a.translations, translations = _b === void 0 ? {} : _b, error = _a.error, _c = _a.isLoading, isLoading = _c === void 0 ? false : _c, _d = _a.className, className = _d === void 0 ? "" : _d, ariaLabel = _a["aria-label"], _e = _a.required, required = _e === void 0 ? false : _e, _f = _a.compareTags, compareTags = _f === void 0 ? defaultCompareTags : _f, _g = _a.getTagKey, getTagKey = _g === void 0 ? defaultGetTagKey : _g, onInputChange = _a.onInputChange, _h = _a.hasMore, hasMore = _h === void 0 ? false : _h, _j = _a.isLoadingMore, isLoadingMore = _j === void 0 ? false : _j, onLoadMore = _a.onLoadMore, _k = _a.loadMoreRootMargin, loadMoreRootMargin = _k === void 0 ? "0px" : _k;
8227
8231
  var t = __assign(__assign({}, DEFAULT_TRANSLATIONS), translations);
8228
- var _h = React.useState(""), inputValue = _h[0], setInputValue = _h[1];
8229
- var _j = React.useState(0), autocompleteKey = _j[0], setAutocompleteKey = _j[1];
8232
+ var _l = React.useState(""), inputValue = _l[0], setInputValue = _l[1];
8233
+ var _m = React.useState(0), autocompleteKey = _m[0], setAutocompleteKey = _m[1];
8230
8234
  var selectedList = value !== null && value !== void 0 ? value : [];
8235
+ var _o = React.useState(null), sentinelNode = _o[0], setSentinelNode = _o[1];
8236
+ React.useEffect(function () {
8237
+ if (!onLoadMore || !sentinelNode || !hasMore) {
8238
+ return;
8239
+ }
8240
+ var observer = new IntersectionObserver(function (entries) {
8241
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
8242
+ var entry = entries_1[_i];
8243
+ if (entry.isIntersecting && hasMore && !isLoadingMore) {
8244
+ onLoadMore();
8245
+ }
8246
+ }
8247
+ }, {
8248
+ root: sentinelNode.closest("ul"),
8249
+ rootMargin: loadMoreRootMargin,
8250
+ threshold: 0,
8251
+ });
8252
+ observer.observe(sentinelNode);
8253
+ return function () { return observer.disconnect(); };
8254
+ }, [onLoadMore, hasMore, isLoadingMore, loadMoreRootMargin, sentinelNode]);
8231
8255
  var handleTagToggle = React.useCallback(function (tag) {
8232
8256
  var next = toggleArrayItem(selectedList, tag, compareTags);
8233
8257
  onChange(next);
8234
8258
  }, [selectedList, compareTags, onChange]);
8235
8259
  var getFilteredAvailable = React.useCallback(function (selected) {
8236
- var search = inputValue.trim().toLowerCase();
8237
8260
  var available = items.filter(function (tag) { return !selected.some(function (s) { return compareTags(s, tag); }); });
8261
+ // Si el padre escucha onInputChange, asumimos que él controla `items`
8262
+ // según el query (filtrado server-side) y no aplicamos filtro local.
8263
+ if (onInputChange)
8264
+ return available;
8265
+ var search = inputValue.trim().toLowerCase();
8238
8266
  if (!search)
8239
8267
  return available;
8240
8268
  return available.filter(function (tag) {
8241
8269
  return tag.value.toLowerCase().includes(search);
8242
8270
  });
8243
- }, [items, inputValue, compareTags]);
8271
+ }, [items, inputValue, compareTags, onInputChange]);
8244
8272
  var filteredItems = getFilteredAvailable(selectedList);
8273
+ var showSentinel = Boolean(onLoadMore) && (hasMore || Boolean(t.endOfListMessage));
8274
+ var itemsWithSentinel = showSentinel
8275
+ ? __spreadArray(__spreadArray([], filteredItems, true), [{ id: SENTINEL_KEY, value: "" }], false) : filteredItems;
8245
8276
  var handleAutocompleteSelection = React.useCallback(function (key) {
8246
- if (key == null)
8277
+ if (key == null) {
8247
8278
  return;
8279
+ }
8248
8280
  var tag = items.find(function (item) { return getTagKey(item) === key || item.value === key; });
8249
8281
  if (tag) {
8250
8282
  handleTagToggle(tag);
@@ -8255,7 +8287,10 @@ function TagsFilter(_a) {
8255
8287
  if (isLoading) {
8256
8288
  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" }) }) }));
8257
8289
  }
8258
- return (jsxRuntime.jsxs("div", { 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: setInputValue, selectedKey: null, items: filteredItems, onSelectionChange: handleAutocompleteSelection,
8290
+ return (jsxRuntime.jsxs("div", { 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) {
8291
+ setInputValue(v);
8292
+ onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange(v);
8293
+ }, selectedKey: null, items: itemsWithSentinel, onSelectionChange: handleAutocompleteSelection,
8259
8294
  // "focus" keeps the menu tied to focus; prefer opening when typing.
8260
8295
  menuTrigger: "input",
8261
8296
  // When the filtered list is empty, avoid keeping an open overlay that blocks the modal.
@@ -8268,7 +8303,14 @@ function TagsFilter(_a) {
8268
8303
  }, listboxProps: {
8269
8304
  className: "max-h-[200px] overflow-y-auto",
8270
8305
  }, className: "w-full", children: function (item) {
8271
- var tag = item;
8306
+ var candidate = item;
8307
+ if (candidate.id === SENTINEL_KEY) {
8308
+ 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) {
8309
+ var _a;
8310
+ setSentinelNode((_a = node === null || node === void 0 ? void 0 : node.closest("li")) !== null && _a !== void 0 ? _a : null);
8311
+ }, className: "flex items-center justify-center py-1", children: isLoadingMore ? (jsxRuntime.jsx(react.Spinner, { size: "sm", "aria-label": t.loadingMoreLabel })) : !hasMore && t.endOfListMessage ? (jsxRuntime.jsx("span", { className: "text-tiny text-default-500", children: t.endOfListMessage })) : (jsxRuntime.jsx("span", { "aria-hidden": true, style: { height: 1, width: 1 } })) }) }, SENTINEL_KEY));
8312
+ }
8313
+ var tag = candidate;
8272
8314
  return (jsxRuntime.jsx(react.AutocompleteItem, { textValue: tag.value, children: tag.value }, getTagKey(tag)));
8273
8315
  } }, autocompleteKey)] }), jsxRuntime.jsx(react.Divider, {}), jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [jsxRuntime.jsx(H4, { className: "text-tiny text-left text-default-700", children: t.labelSelected }), selectedList.length > 0 ? (jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 max-h-[80px] overflow-y-auto", children: __spreadArray([], selectedList, true).reverse().map(function (tag) { return (jsxRuntime.jsx(Chip, { variant: "flat", color: "primary", size: "sm", onClose: function () { return handleTagToggle(tag); }, children: tag.value }, getTagKey(tag))); }) })) : (jsxRuntime.jsx(P, { className: "text-tiny italic text-default-500", children: t.emptySelectedMessage }))] })] }))] }));
8274
8316
  }
package/dist/index.esm.js CHANGED
@@ -6974,7 +6974,7 @@ var DayMonthPicker = function (_a) {
6974
6974
  var currentYearDate = $14e0f24ef4ac5c92$export$d0bdf45af03a6ea3($14e0f24ef4ac5c92$export$aa8b41735afcabd2());
6975
6975
  var pickerValue = (value === null || value === void 0 ? void 0 : value.type) === "dayMonth" ? value.dayMonth : null;
6976
6976
  var rangeValue = (value === null || value === void 0 ? void 0 : value.type) === "dayMonthRange" ? value.dayMonthRange : null;
6977
- return (jsxs("div", { className: "w-full flex flex-wrap xs:gap-5 justify-between items-center", children: [jsxs(RadioGroup, { color: "primary", orientation: "horizontal", size: "sm", value: mode, onValueChange: handleModeChange, children: [jsx(Radio, { value: "single", children: t.dayMonthSingleOption }), jsx(Radio, { value: "range", children: t.dayMonthRangeOption })] }), mode === "single" ? (pickerValue ? (jsx(DatePicker, { value: pickerValue, onChange: handleSingleChange, "aria-label": t.dayMonthAriaLabel, endContent: jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-40 ".concat(NO_YEAR_CLASS) }, "dmp-c")) : (jsx(DatePicker, { defaultValue: currentYearDate, onChange: handleSingleChange, "aria-label": t.dayMonthAriaLabel, endContent: jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-40 ".concat(NO_YEAR_CLASS) }, "dmp-u"))) : (rangeValue ? (jsx(DateRangePicker, { value: rangeValue, onChange: handleRangeChange, "aria-label": t.dayMonthRangeAriaLabel, endContent: jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-xs ".concat(NO_YEAR_CLASS) }, "dmpr-c")) : (jsx(DateRangePicker, { defaultValue: { start: currentYearDate, end: currentYearDate }, onChange: handleRangeChange, "aria-label": t.dayMonthRangeAriaLabel, endContent: jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-xs ".concat(NO_YEAR_CLASS) }, "dmpr-u")))] }));
6977
+ return (jsxs("div", { className: "w-full flex flex-wrap xs:gap-5 justify-between items-center", children: [jsxs(RadioGroup, { color: "primary", orientation: "horizontal", size: "sm", value: mode, onValueChange: handleModeChange, children: [jsx(Radio, { value: "single", children: t.dayMonthSingleOption }), jsx(Radio, { value: "range", children: t.dayMonthRangeOption })] }), mode === "single" ? (jsx(DatePicker, { value: pickerValue, placeholderValue: currentYearDate, onChange: handleSingleChange, "aria-label": t.dayMonthAriaLabel, endContent: jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-40 ".concat(NO_YEAR_CLASS) })) : (jsx(DateRangePicker, { value: rangeValue, placeholderValue: currentYearDate, onChange: handleRangeChange, "aria-label": t.dayMonthRangeAriaLabel, endContent: jsx(IconComponent, { icon: "solar:calendar-outline" }), className: "w-full md:w-auto md:max-w-xs ".concat(NO_YEAR_CLASS) }))] }));
6978
6978
  };
6979
6979
 
6980
6980
  /**
@@ -8199,17 +8199,21 @@ var SegmentationBuilder = forwardRef(function (_a, ref) {
8199
8199
  });
8200
8200
  SegmentationBuilder.displayName = "SegmentationBuilder";
8201
8201
 
8202
+ var SENTINEL_KEY = "__tags-filter-sentinel__";
8202
8203
  var DEFAULT_TRANSLATIONS = {
8203
8204
  placeholder: "Nombre de la etiqueta",
8204
8205
  labelSelect: "Selecciona etiqueta",
8205
8206
  labelSelected: "Etiquetas actuales",
8206
8207
  emptySelectedMessage: "No hay etiquetas seleccionadas",
8207
8208
  errorLoadingPrefix: "Error al cargar etiquetas",
8209
+ loadingMoreLabel: "Cargando más etiquetas…",
8210
+ endOfListMessage: "",
8208
8211
  };
8209
8212
  function toggleArrayItem(array, item, compareFn) {
8210
8213
  var index = array.findIndex(function (existing) { return compareFn(existing, item); });
8211
- if (index >= 0)
8214
+ if (index >= 0) {
8212
8215
  return array.filter(function (_, i) { return i !== index; });
8216
+ }
8213
8217
  return __spreadArray(__spreadArray([], array, true), [item], false);
8214
8218
  }
8215
8219
  var defaultCompareTags = function (a, b) {
@@ -8224,28 +8228,56 @@ var defaultGetTagKey = function (tag) { var _a; return (_a = tag.id) !== null &&
8224
8228
  * Cumple con i18n mediante la prop `translations`.
8225
8229
  */
8226
8230
  function TagsFilter(_a) {
8227
- var items = _a.items, value = _a.value, onChange = _a.onChange, _b = _a.translations, translations = _b === void 0 ? {} : _b, error = _a.error, _c = _a.isLoading, isLoading = _c === void 0 ? false : _c, _d = _a.className, className = _d === void 0 ? "" : _d, ariaLabel = _a["aria-label"], _e = _a.required, required = _e === void 0 ? false : _e, _f = _a.compareTags, compareTags = _f === void 0 ? defaultCompareTags : _f, _g = _a.getTagKey, getTagKey = _g === void 0 ? defaultGetTagKey : _g;
8231
+ var items = _a.items, value = _a.value, onChange = _a.onChange, _b = _a.translations, translations = _b === void 0 ? {} : _b, error = _a.error, _c = _a.isLoading, isLoading = _c === void 0 ? false : _c, _d = _a.className, className = _d === void 0 ? "" : _d, ariaLabel = _a["aria-label"], _e = _a.required, required = _e === void 0 ? false : _e, _f = _a.compareTags, compareTags = _f === void 0 ? defaultCompareTags : _f, _g = _a.getTagKey, getTagKey = _g === void 0 ? defaultGetTagKey : _g, onInputChange = _a.onInputChange, _h = _a.hasMore, hasMore = _h === void 0 ? false : _h, _j = _a.isLoadingMore, isLoadingMore = _j === void 0 ? false : _j, onLoadMore = _a.onLoadMore, _k = _a.loadMoreRootMargin, loadMoreRootMargin = _k === void 0 ? "0px" : _k;
8228
8232
  var t = __assign(__assign({}, DEFAULT_TRANSLATIONS), translations);
8229
- var _h = useState(""), inputValue = _h[0], setInputValue = _h[1];
8230
- var _j = useState(0), autocompleteKey = _j[0], setAutocompleteKey = _j[1];
8233
+ var _l = useState(""), inputValue = _l[0], setInputValue = _l[1];
8234
+ var _m = useState(0), autocompleteKey = _m[0], setAutocompleteKey = _m[1];
8231
8235
  var selectedList = value !== null && value !== void 0 ? value : [];
8236
+ var _o = useState(null), sentinelNode = _o[0], setSentinelNode = _o[1];
8237
+ useEffect(function () {
8238
+ if (!onLoadMore || !sentinelNode || !hasMore) {
8239
+ return;
8240
+ }
8241
+ var observer = new IntersectionObserver(function (entries) {
8242
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
8243
+ var entry = entries_1[_i];
8244
+ if (entry.isIntersecting && hasMore && !isLoadingMore) {
8245
+ onLoadMore();
8246
+ }
8247
+ }
8248
+ }, {
8249
+ root: sentinelNode.closest("ul"),
8250
+ rootMargin: loadMoreRootMargin,
8251
+ threshold: 0,
8252
+ });
8253
+ observer.observe(sentinelNode);
8254
+ return function () { return observer.disconnect(); };
8255
+ }, [onLoadMore, hasMore, isLoadingMore, loadMoreRootMargin, sentinelNode]);
8232
8256
  var handleTagToggle = useCallback(function (tag) {
8233
8257
  var next = toggleArrayItem(selectedList, tag, compareTags);
8234
8258
  onChange(next);
8235
8259
  }, [selectedList, compareTags, onChange]);
8236
8260
  var getFilteredAvailable = useCallback(function (selected) {
8237
- var search = inputValue.trim().toLowerCase();
8238
8261
  var available = items.filter(function (tag) { return !selected.some(function (s) { return compareTags(s, tag); }); });
8262
+ // Si el padre escucha onInputChange, asumimos que él controla `items`
8263
+ // según el query (filtrado server-side) y no aplicamos filtro local.
8264
+ if (onInputChange)
8265
+ return available;
8266
+ var search = inputValue.trim().toLowerCase();
8239
8267
  if (!search)
8240
8268
  return available;
8241
8269
  return available.filter(function (tag) {
8242
8270
  return tag.value.toLowerCase().includes(search);
8243
8271
  });
8244
- }, [items, inputValue, compareTags]);
8272
+ }, [items, inputValue, compareTags, onInputChange]);
8245
8273
  var filteredItems = getFilteredAvailable(selectedList);
8274
+ var showSentinel = Boolean(onLoadMore) && (hasMore || Boolean(t.endOfListMessage));
8275
+ var itemsWithSentinel = showSentinel
8276
+ ? __spreadArray(__spreadArray([], filteredItems, true), [{ id: SENTINEL_KEY, value: "" }], false) : filteredItems;
8246
8277
  var handleAutocompleteSelection = useCallback(function (key) {
8247
- if (key == null)
8278
+ if (key == null) {
8248
8279
  return;
8280
+ }
8249
8281
  var tag = items.find(function (item) { return getTagKey(item) === key || item.value === key; });
8250
8282
  if (tag) {
8251
8283
  handleTagToggle(tag);
@@ -8256,7 +8288,10 @@ function TagsFilter(_a) {
8256
8288
  if (isLoading) {
8257
8289
  return (jsx("div", { className: "flex flex-col gap-4 ".concat(className), children: jsx("div", { className: "flex justify-center py-4", children: jsx(Spinner, { size: "sm" }) }) }));
8258
8290
  }
8259
- return (jsxs("div", { className: "flex flex-col gap-4 ".concat(className), children: [error && (jsxs("div", { className: "text-danger text-small py-2", children: [t.errorLoadingPrefix, ": ", error] })), !error && (jsxs(Fragment, { children: [jsxs("div", { className: "flex flex-col gap-3", children: [jsxs(H4, { className: "text-tiny text-left text-default-700", children: [t.labelSelect, required && jsx("span", { className: "text-danger ml-0.5", children: "*" })] }), jsx(AuraAutocomplete, { placeholder: t.placeholder, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : t.placeholder, inputValue: inputValue, onInputChange: setInputValue, selectedKey: null, items: filteredItems, onSelectionChange: handleAutocompleteSelection,
8291
+ return (jsxs("div", { className: "flex flex-col gap-4 ".concat(className), children: [error && (jsxs("div", { className: "text-danger text-small py-2", children: [t.errorLoadingPrefix, ": ", error] })), !error && (jsxs(Fragment, { children: [jsxs("div", { className: "flex flex-col gap-3", children: [jsxs(H4, { className: "text-tiny text-left text-default-700", children: [t.labelSelect, required && jsx("span", { className: "text-danger ml-0.5", children: "*" })] }), jsx(AuraAutocomplete, { placeholder: t.placeholder, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : t.placeholder, inputValue: inputValue, onInputChange: function (v) {
8292
+ setInputValue(v);
8293
+ onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange(v);
8294
+ }, selectedKey: null, items: itemsWithSentinel, onSelectionChange: handleAutocompleteSelection,
8260
8295
  // "focus" keeps the menu tied to focus; prefer opening when typing.
8261
8296
  menuTrigger: "input",
8262
8297
  // When the filtered list is empty, avoid keeping an open overlay that blocks the modal.
@@ -8269,7 +8304,14 @@ function TagsFilter(_a) {
8269
8304
  }, listboxProps: {
8270
8305
  className: "max-h-[200px] overflow-y-auto",
8271
8306
  }, className: "w-full", children: function (item) {
8272
- var tag = item;
8307
+ var candidate = item;
8308
+ if (candidate.id === SENTINEL_KEY) {
8309
+ return (jsx(AutocompleteItem, { textValue: "", isReadOnly: true, className: "opacity-100 cursor-default data-[hover=true]:bg-transparent", children: jsx("div", { ref: function (node) {
8310
+ var _a;
8311
+ setSentinelNode((_a = node === null || node === void 0 ? void 0 : node.closest("li")) !== null && _a !== void 0 ? _a : null);
8312
+ }, className: "flex items-center justify-center py-1", children: isLoadingMore ? (jsx(Spinner, { size: "sm", "aria-label": t.loadingMoreLabel })) : !hasMore && t.endOfListMessage ? (jsx("span", { className: "text-tiny text-default-500", children: t.endOfListMessage })) : (jsx("span", { "aria-hidden": true, style: { height: 1, width: 1 } })) }) }, SENTINEL_KEY));
8313
+ }
8314
+ var tag = candidate;
8273
8315
  return (jsx(AutocompleteItem, { textValue: tag.value, children: tag.value }, getTagKey(tag)));
8274
8316
  } }, autocompleteKey)] }), jsx(Divider, {}), jsxs("div", { className: "flex flex-col gap-3", children: [jsx(H4, { className: "text-tiny text-left text-default-700", children: t.labelSelected }), selectedList.length > 0 ? (jsx("div", { className: "flex flex-wrap gap-2 max-h-[80px] overflow-y-auto", children: __spreadArray([], selectedList, true).reverse().map(function (tag) { return (jsx(Chip, { variant: "flat", color: "primary", size: "sm", onClose: function () { return handleTagToggle(tag); }, children: tag.value }, getTagKey(tag))); }) })) : (jsx(P, { className: "text-tiny italic text-default-500", children: t.emptySelectedMessage }))] })] }))] }));
8275
8317
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DayMonthPicker.d.ts","sourceRoot":"","sources":["../../../../../src/components/drawer-filters/_internal/DayMonthPicker.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAKxE,UAAU,mBAAmB;IAC5B,IAAI,EAAE,UAAU,GAAG,eAAe,CAAC;IACnC,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;CAC5C;AAED,UAAU,mBAAmB;IAC5B,KAAK,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC/C,YAAY,CAAC,EAAE,yBAAyB,CAAC;CACzC;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA2GxD,CAAC"}
1
+ {"version":3,"file":"DayMonthPicker.d.ts","sourceRoot":"","sources":["../../../../../src/components/drawer-filters/_internal/DayMonthPicker.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAKxE,UAAU,mBAAmB;IAC5B,IAAI,EAAE,UAAU,GAAG,eAAe,CAAC;IACnC,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;CAC5C;AAED,UAAU,mBAAmB;IAC5B,KAAK,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC/C,YAAY,CAAC,EAAE,yBAAyB,CAAC;CACzC;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAqFxD,CAAC"}
@@ -9,7 +9,7 @@ import type { TagsFilterProps } from "./TagsFilter.types";
9
9
  export declare function TagsFilter<T extends {
10
10
  id?: string;
11
11
  value: string;
12
- }>({ items, value, onChange, translations, error, isLoading, className, "aria-label": ariaLabel, required, compareTags, getTagKey, }: TagsFilterProps<T>): React.ReactElement;
12
+ }>({ items, value, onChange, translations, error, isLoading, className, "aria-label": ariaLabel, required, compareTags, getTagKey, onInputChange, hasMore, isLoadingMore, onLoadMore, loadMoreRootMargin, }: TagsFilterProps<T>): React.ReactElement;
13
13
  export declare namespace TagsFilter {
14
14
  var displayName: string;
15
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TagsFilter.d.ts","sourceRoot":"","sources":["../../../../src/components/tags-filter/TagsFilter.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAAE,eAAe,EAA0B,MAAM,oBAAoB,CAAC;AA+BlF;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,EACpE,KAAK,EACL,KAAK,EACL,QAAQ,EACR,YAAiB,EACjB,KAAK,EACL,SAAiB,EACjB,SAAc,EACd,YAAY,EAAE,SAAS,EACvB,QAAgB,EAChB,WAA2D,EAC3D,SAAkD,GAClD,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,YAAY,CAyIzC;yBArJe,UAAU"}
1
+ {"version":3,"file":"TagsFilter.d.ts","sourceRoot":"","sources":["../../../../src/components/tags-filter/TagsFilter.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EACX,eAAe,EAEf,MAAM,oBAAoB,CAAC;AAqC5B;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,EACpE,KAAK,EACL,KAAK,EACL,QAAQ,EACR,YAAiB,EACjB,KAAK,EACL,SAAiB,EACjB,SAAc,EACd,YAAY,EAAE,SAAS,EACvB,QAAgB,EAChB,WAA2D,EAC3D,SAAkD,EAClD,aAAa,EACb,OAAe,EACf,aAAqB,EACrB,UAAU,EACV,kBAA0B,GAC1B,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,YAAY,CA0MzC;yBA3Ne,UAAU"}
@@ -22,6 +22,10 @@ export type TagsFilterTranslations = {
22
22
  emptySelectedMessage?: string;
23
23
  /** Prefijo del mensaje de error (ej. "Error al cargar etiquetas") */
24
24
  errorLoadingPrefix?: string;
25
+ /** Texto sr-only del spinner inline mientras se cargan más páginas. */
26
+ loadingMoreLabel?: string;
27
+ /** Texto opcional al final de la lista cuando ya no hay más. Default: "" (oculto). */
28
+ endOfListMessage?: string;
25
29
  };
26
30
  export interface TagsFilterProps<T extends TagItem = TagItem> {
27
31
  /** Lista de etiquetas disponibles (ej. desde API) */
@@ -46,5 +50,23 @@ export interface TagsFilterProps<T extends TagItem = TagItem> {
46
50
  compareTags?: (a: T, b: T) => boolean;
47
51
  /** Función para obtener clave única de una etiqueta (por defecto: id ?? value) */
48
52
  getTagKey?: (tag: T) => string;
53
+ /**
54
+ * Se invoca cada vez que el usuario escribe en el input de búsqueda.
55
+ * Útil para filtrado server-side: el padre puede llamar a un endpoint con el valor
56
+ * y actualizar `items` con los resultados.
57
+ *
58
+ * Importante: cuando este callback está definido, el componente desactiva su
59
+ * filtro client-side sobre `items` (solo excluye los ya seleccionados). Se asume
60
+ * que el padre controla qué items se muestran según el query.
61
+ */
62
+ onInputChange?: (value: string) => void;
63
+ /** Hay más páginas disponibles. Si false, no se intenta cargar más. */
64
+ hasMore?: boolean;
65
+ /** Se está cargando la siguiente página (muestra spinner inline al final). */
66
+ isLoadingMore?: boolean;
67
+ /** Callback que se invoca cuando el componente necesita cargar la siguiente página. Solo se llama si hasMore && !isLoadingMore. */
68
+ onLoadMore?: () => void;
69
+ /** Margen para precarga del IntersectionObserver. Default: "0px". */
70
+ loadMoreRootMargin?: string;
49
71
  }
50
72
  //# sourceMappingURL=TagsFilter.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TagsFilter.types.d.ts","sourceRoot":"","sources":["../../../../src/components/tags-filter/TagsFilter.types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,OAAO;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACpC,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO;IAC3D,qDAAqD;IACrD,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,0CAA0C;IAC1C,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,2DAA2D;IAC3D,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAClC,uFAAuF;IACvF,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2GAA2G;IAC3G,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wEAAwE;IACxE,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC;IACtC,kFAAkF;IAClF,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC;CAC/B"}
1
+ {"version":3,"file":"TagsFilter.types.d.ts","sourceRoot":"","sources":["../../../../src/components/tags-filter/TagsFilter.types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,OAAO;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACpC,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sFAAsF;IACtF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO;IAC3D,qDAAqD;IACrD,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,0CAA0C;IAC1C,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,2DAA2D;IAC3D,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAClC,uFAAuF;IACvF,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2GAA2G;IAC3G,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wEAAwE;IACxE,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC;IACtC,kFAAkF;IAClF,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC;IAC/B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mIAAmI;IACnI,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beweco/aurora-ui",
3
- "version": "0.6.41",
3
+ "version": "0.6.43",
4
4
  "description": "Bewe Aurora UI Component Library",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "module": "./dist/index.esm.js",