twico-ui 1.13.0 → 1.14.0

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.d.cts CHANGED
@@ -1989,6 +1989,11 @@ interface DatatableColumn<T = any> {
1989
1989
  wrapText?: boolean;
1990
1990
  /** Distinct values for the "is any of" multi-value filter (recommended in server mode). */
1991
1991
  valueOptions?: Array<string | { value: string; label: string }>;
1992
+ /** Async loader for the "is any of" filter's options — searchable/lazy server-backed values (for a
1993
+ * large reference/master list). Called with the type-ahead query (debounced; `""` primes the list)
1994
+ * and takes precedence over `valueOptions` for the filter picker, which then loads server-side
1995
+ * (no local filtering) with a loading state. */
1996
+ loadValueOptions?: (query: string) => Promise<Array<string | { value: string; label: string }>>;
1992
1997
  /** Format the raw value to a string/number for display. */
1993
1998
  valueFormatter?: (value: any, row: T) => React.ReactNode;
1994
1999
  /** Fully custom cell renderer (badges, avatars, etc.). */
package/dist/index.d.ts CHANGED
@@ -1989,6 +1989,11 @@ interface DatatableColumn<T = any> {
1989
1989
  wrapText?: boolean;
1990
1990
  /** Distinct values for the "is any of" multi-value filter (recommended in server mode). */
1991
1991
  valueOptions?: Array<string | { value: string; label: string }>;
1992
+ /** Async loader for the "is any of" filter's options — searchable/lazy server-backed values (for a
1993
+ * large reference/master list). Called with the type-ahead query (debounced; `""` primes the list)
1994
+ * and takes precedence over `valueOptions` for the filter picker, which then loads server-side
1995
+ * (no local filtering) with a loading state. */
1996
+ loadValueOptions?: (query: string) => Promise<Array<string | { value: string; label: string }>>;
1992
1997
  /** Format the raw value to a string/number for display. */
1993
1998
  valueFormatter?: (value: any, row: T) => React.ReactNode;
1994
1999
  /** Fully custom cell renderer (badges, avatars, etc.). */
package/dist/index.mjs CHANGED
@@ -8625,6 +8625,53 @@ function Caret({ pos }) {
8625
8625
  const left = Math.max(12, Math.min(pos.anchorX - pos.left, pos.width - 20));
8626
8626
  return /* @__PURE__ */ jsx("span", { className: "twc-dt__caret", style: { left } });
8627
8627
  }
8628
+ function AsyncFilterValue({ col, value, onChange }) {
8629
+ const [opts, setOpts] = React51__default.useState([]);
8630
+ const [loading, setLoading] = React51__default.useState(false);
8631
+ const reqRef = React51__default.useRef(0);
8632
+ const debRef = React51__default.useRef();
8633
+ const load = React51__default.useCallback((query) => {
8634
+ const id = ++reqRef.current;
8635
+ setLoading(true);
8636
+ Promise.resolve(col.loadValueOptions(query)).then(
8637
+ (res) => {
8638
+ if (reqRef.current === id) {
8639
+ setOpts((Array.isArray(res) ? res : []).map((o) => typeof o === "string" ? { value: o, label: o } : o));
8640
+ setLoading(false);
8641
+ }
8642
+ },
8643
+ () => {
8644
+ if (reqRef.current === id) setLoading(false);
8645
+ }
8646
+ );
8647
+ }, [col]);
8648
+ React51__default.useEffect(() => {
8649
+ load("");
8650
+ return () => clearTimeout(debRef.current);
8651
+ }, [load]);
8652
+ const onInput = React51__default.useCallback((q) => {
8653
+ clearTimeout(debRef.current);
8654
+ debRef.current = setTimeout(() => load(q), 250);
8655
+ }, [load]);
8656
+ const selected = Array.isArray(value) ? value : [];
8657
+ const merged = React51__default.useMemo(() => {
8658
+ const seen2 = new Set(opts.map((o) => o.value));
8659
+ return [...selected.filter((v) => !seen2.has(v)).map((v) => ({ value: v, label: String(v) })), ...opts];
8660
+ }, [opts, selected]);
8661
+ return /* @__PURE__ */ jsx(
8662
+ MultiSelect,
8663
+ {
8664
+ portal: true,
8665
+ placeholder: "Any of\u2026",
8666
+ value: selected,
8667
+ options: merged,
8668
+ filter: false,
8669
+ loading,
8670
+ onInputChange: onInput,
8671
+ onChange
8672
+ }
8673
+ );
8674
+ }
8628
8675
  function EditCell({ col, value, options, onChange, onCommit, onCommitValue, onCancel, onKeyDown }) {
8629
8676
  const ref = React51__default.useRef(null);
8630
8677
  const isSelect = col.editType === "select" || options && col.editType !== "text";
@@ -11273,7 +11320,14 @@ function Datatable({
11273
11320
  }))
11274
11321
  }
11275
11322
  ) }),
11276
- /* @__PURE__ */ jsx("div", { className: "twc-dt__f-val", children: op.noInput ? null : op.multi ? /* @__PURE__ */ jsx(
11323
+ /* @__PURE__ */ jsx("div", { className: "twc-dt__f-val", children: op.noInput ? null : op.multi ? col.loadValueOptions ? /* @__PURE__ */ jsx(
11324
+ AsyncFilterValue,
11325
+ {
11326
+ col,
11327
+ value: f.value,
11328
+ onChange: (vals) => setFilters((arr) => arr.map((x) => x.id === f.id ? { ...x, value: vals } : x))
11329
+ }
11330
+ ) : /* @__PURE__ */ jsx(
11277
11331
  MultiSelect,
11278
11332
  {
11279
11333
  portal: true,