@orianatech/pire 0.7.0 → 0.8.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.
@@ -11,20 +11,39 @@ export interface ComboBoxProps {
11
11
  defaultValue?: string;
12
12
  onChange?: (value: string | null) => void;
13
13
  /**
14
- * Free-text as typed, on every keystroke.
14
+ * Free-text as typed, on every keystroke. Debounce it before calling the server.
15
15
  *
16
- * Server-side search is only partly supported. `options` is passed to React Aria as
17
- * `defaultItems`, so React Aria applies its own local "contains" filter on top of
18
- * whatever you supply: any result whose `label` does not literally contain the typed
19
- * text is hidden client-side, and when the local filter matches nothing the menu
20
- * closes. Fuzzy, synonym, code-to-description and server-ranked matches are therefore
21
- * dropped. Use this to observe input (analytics, a debounced prefetch, mirroring the
22
- * text elsewhere), or for server search only where the returned labels are guaranteed
23
- * to contain the query as a substring. For true server-driven search with no local
24
- * filtering, use ValueHelpField.
16
+ * Without `isFilteredExternally`, React Aria also applies its own local "contains" filter,
17
+ * so a result whose label does not literally contain the typed text is hidden client-side.
25
18
  */
26
19
  onInputChange?: (text: string) => void;
27
20
  options?: Array<string | ComboBoxOption>;
21
+ /**
22
+ * `options` is the final list and React Aria filters nothing locally. Required for server
23
+ * search: fuzzy matches, synonyms, code-to-description and server ranking do not survive a
24
+ * local "contains" pass.
25
+ *
26
+ * Turns `options` into a controlled collection, so the popover reflects exactly what you
27
+ * pass — including an empty list, which is why `isLoading` and `emptyLabel` exist.
28
+ */
29
+ isFilteredExternally?: boolean;
30
+ /**
31
+ * Shows a loading row instead of closing the popover. Without it a 300ms debounce reads as
32
+ * a menu that flickers open and shut.
33
+ *
34
+ * Also blocks selection while it is set: confirming here would commit an item from the
35
+ * previous response.
36
+ */
37
+ isLoading?: boolean;
38
+ /** Overrides the dictionary's `comboBoxLoading`. */
39
+ loadingLabel?: string;
40
+ /**
41
+ * Shown when the server answered with nothing. Without it the popover closes and the user
42
+ * cannot tell a bad query from a slow one.
43
+ */
44
+ emptyLabel?: React.ReactNode;
45
+ /** Called when the list is scrolled near its end, for paginated results. */
46
+ onLoadMore?: () => void;
28
47
  placeholder?: string;
29
48
  description?: React.ReactNode;
30
49
  errorMessage?: React.ReactNode;
@@ -42,4 +61,4 @@ export interface ComboBoxProps {
42
61
  }
43
62
  /** Type-ahead picker for lists too long to scroll — material, cost centre, G/L account.
44
63
  * Below ~10 fixed options use Select; for master-data search with several columns use ValueHelpField. */
45
- export declare function ComboBox({ label, value, defaultValue, onChange, onInputChange, options, description, errorMessage, size, fullWidth, className, style, ...rest }: ComboBoxProps): React.JSX.Element;
64
+ export declare function ComboBox({ label, value, defaultValue, onChange, onInputChange, options, description, errorMessage, size, fullWidth, isFilteredExternally, isLoading, loadingLabel, emptyLabel, onLoadMore, className, style, ...rest }: ComboBoxProps): React.JSX.Element;
@@ -11,20 +11,39 @@ export interface ComboBoxProps {
11
11
  defaultValue?: string;
12
12
  onChange?: (value: string | null) => void;
13
13
  /**
14
- * Free-text as typed, on every keystroke.
14
+ * Free-text as typed, on every keystroke. Debounce it before calling the server.
15
15
  *
16
- * Server-side search is only partly supported. `options` is passed to React Aria as
17
- * `defaultItems`, so React Aria applies its own local "contains" filter on top of
18
- * whatever you supply: any result whose `label` does not literally contain the typed
19
- * text is hidden client-side, and when the local filter matches nothing the menu
20
- * closes. Fuzzy, synonym, code-to-description and server-ranked matches are therefore
21
- * dropped. Use this to observe input (analytics, a debounced prefetch, mirroring the
22
- * text elsewhere), or for server search only where the returned labels are guaranteed
23
- * to contain the query as a substring. For true server-driven search with no local
24
- * filtering, use ValueHelpField.
16
+ * Without `isFilteredExternally`, React Aria also applies its own local "contains" filter,
17
+ * so a result whose label does not literally contain the typed text is hidden client-side.
25
18
  */
26
19
  onInputChange?: (text: string) => void;
27
20
  options?: Array<string | ComboBoxOption>;
21
+ /**
22
+ * `options` is the final list and React Aria filters nothing locally. Required for server
23
+ * search: fuzzy matches, synonyms, code-to-description and server ranking do not survive a
24
+ * local "contains" pass.
25
+ *
26
+ * Turns `options` into a controlled collection, so the popover reflects exactly what you
27
+ * pass — including an empty list, which is why `isLoading` and `emptyLabel` exist.
28
+ */
29
+ isFilteredExternally?: boolean;
30
+ /**
31
+ * Shows a loading row instead of closing the popover. Without it a 300ms debounce reads as
32
+ * a menu that flickers open and shut.
33
+ *
34
+ * Also blocks selection while it is set: confirming here would commit an item from the
35
+ * previous response.
36
+ */
37
+ isLoading?: boolean;
38
+ /** Overrides the dictionary's `comboBoxLoading`. */
39
+ loadingLabel?: string;
40
+ /**
41
+ * Shown when the server answered with nothing. Without it the popover closes and the user
42
+ * cannot tell a bad query from a slow one.
43
+ */
44
+ emptyLabel?: React.ReactNode;
45
+ /** Called when the list is scrolled near its end, for paginated results. */
46
+ onLoadMore?: () => void;
28
47
  placeholder?: string;
29
48
  description?: React.ReactNode;
30
49
  errorMessage?: React.ReactNode;
@@ -42,5 +61,5 @@ export interface ComboBoxProps {
42
61
  }
43
62
  /** Type-ahead picker for lists too long to scroll — material, cost centre, G/L account.
44
63
  * Below ~10 fixed options use Select; for master-data search with several columns use ValueHelpField. */
45
- export declare function ComboBox({ label, value, defaultValue, onChange, onInputChange, options, description, errorMessage, size, fullWidth, className, style, ...rest }: ComboBoxProps): React.JSX.Element;
64
+ export declare function ComboBox({ label, value, defaultValue, onChange, onInputChange, options, description, errorMessage, size, fullWidth, isFilteredExternally, isLoading, loadingLabel, emptyLabel, onLoadMore, className, style, ...rest }: ComboBoxProps): React.JSX.Element;
46
65
  //# sourceMappingURL=ComboBox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ComboBox.d.ts","sourceRoot":"","sources":["../../../src/components/forms/ComboBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAOpC,MAAM,WAAW,cAAc;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE;AAE1G,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4GAA4G;IAC5G,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAKD;0GAC0G;AAC1G,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAY,EAC1F,WAAW,EAAE,YAAY,EAAE,IAAW,EAAE,SAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,qBAkCrG"}
1
+ {"version":3,"file":"ComboBox.d.ts","sourceRoot":"","sources":["../../../src/components/forms/ComboBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAOpC,MAAM,WAAW,cAAc;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE;AAE1G,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;IACzC;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4GAA4G;IAC5G,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAKD;0GAC0G;AAC1G,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAY,EAC1F,WAAW,EAAE,YAAY,EAAE,IAAW,EAAE,SAAgB,EAAE,oBAAoB,EAAE,SAAS,EACzF,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,qBAiEjF"}
@@ -7,18 +7,27 @@ export interface MultiComboBoxProps {
7
7
  defaultValue?: string[];
8
8
  onChange?: (values: string[]) => void;
9
9
  /**
10
- * Free-text as typed, on every keystroke.
10
+ * Free-text as typed, on every keystroke. Debounce it before calling the server.
11
11
  *
12
- * Server-side search is only partly supported, exactly as on ComboBox. `options` is passed
13
- * to React Aria as `defaultItems`, so React Aria applies its own local "contains" filter on
14
- * top of whatever you supply: any result whose `label` does not literally contain the typed
15
- * text is hidden client-side, and when the local filter matches nothing the menu closes.
16
- * Fuzzy, synonym, code-to-description and server-ranked matches are therefore dropped. Use
17
- * this to observe input (analytics, a debounced prefetch), or for server search only where
18
- * the returned labels are guaranteed to contain the query as a substring.
12
+ * Without `isFilteredExternally`, React Aria also applies its own local "contains" filter,
13
+ * so a result whose label does not literally contain the typed text is hidden client-side.
19
14
  */
20
15
  onInputChange?: (text: string) => void;
21
16
  options?: Array<string | ComboBoxOption>;
17
+ /**
18
+ * `options` is the final list and React Aria filters nothing locally. Same meaning and same
19
+ * name as on `ComboBox`. Required for server search, where fuzzy matches, synonyms and
20
+ * server ranking do not survive a local "contains" pass.
21
+ */
22
+ isFilteredExternally?: boolean;
23
+ /** Shows a loading row instead of closing the popover, and blocks selection while set. */
24
+ isLoading?: boolean;
25
+ /** Overrides the dictionary's `comboBoxLoading`. */
26
+ loadingLabel?: string;
27
+ /** Shown when the server answered with nothing, so a bad query reads differently from a slow one. */
28
+ emptyLabel?: React.ReactNode;
29
+ /** Called when the list is scrolled near its end, for paginated results. */
30
+ onLoadMore?: () => void;
22
31
  placeholder?: string;
23
32
  description?: React.ReactNode;
24
33
  errorMessage?: React.ReactNode;
@@ -55,4 +64,4 @@ export interface MultiComboBoxProps {
55
64
  * component nested inside it — a TagGroup there registers its tags as listbox items and then
56
65
  * crashes looking for grid state. Each chip's remove button is an ordinary Tab stop instead,
57
66
  * and removals are announced through the live region below. */
58
- export declare function MultiComboBox({ label, value, defaultValue, onChange, onInputChange, options, description, errorMessage, allowsCustomValue, size, fullWidth, className, style, ...rest }: MultiComboBoxProps): React.JSX.Element;
67
+ export declare function MultiComboBox({ label, value, defaultValue, onChange, onInputChange, options, description, errorMessage, allowsCustomValue, size, isFilteredExternally, isLoading, loadingLabel, emptyLabel, onLoadMore, fullWidth, className, style, ...rest }: MultiComboBoxProps): React.JSX.Element;
@@ -7,18 +7,27 @@ export interface MultiComboBoxProps {
7
7
  defaultValue?: string[];
8
8
  onChange?: (values: string[]) => void;
9
9
  /**
10
- * Free-text as typed, on every keystroke.
10
+ * Free-text as typed, on every keystroke. Debounce it before calling the server.
11
11
  *
12
- * Server-side search is only partly supported, exactly as on ComboBox. `options` is passed
13
- * to React Aria as `defaultItems`, so React Aria applies its own local "contains" filter on
14
- * top of whatever you supply: any result whose `label` does not literally contain the typed
15
- * text is hidden client-side, and when the local filter matches nothing the menu closes.
16
- * Fuzzy, synonym, code-to-description and server-ranked matches are therefore dropped. Use
17
- * this to observe input (analytics, a debounced prefetch), or for server search only where
18
- * the returned labels are guaranteed to contain the query as a substring.
12
+ * Without `isFilteredExternally`, React Aria also applies its own local "contains" filter,
13
+ * so a result whose label does not literally contain the typed text is hidden client-side.
19
14
  */
20
15
  onInputChange?: (text: string) => void;
21
16
  options?: Array<string | ComboBoxOption>;
17
+ /**
18
+ * `options` is the final list and React Aria filters nothing locally. Same meaning and same
19
+ * name as on `ComboBox`. Required for server search, where fuzzy matches, synonyms and
20
+ * server ranking do not survive a local "contains" pass.
21
+ */
22
+ isFilteredExternally?: boolean;
23
+ /** Shows a loading row instead of closing the popover, and blocks selection while set. */
24
+ isLoading?: boolean;
25
+ /** Overrides the dictionary's `comboBoxLoading`. */
26
+ loadingLabel?: string;
27
+ /** Shown when the server answered with nothing, so a bad query reads differently from a slow one. */
28
+ emptyLabel?: React.ReactNode;
29
+ /** Called when the list is scrolled near its end, for paginated results. */
30
+ onLoadMore?: () => void;
22
31
  placeholder?: string;
23
32
  description?: React.ReactNode;
24
33
  errorMessage?: React.ReactNode;
@@ -55,5 +64,5 @@ export interface MultiComboBoxProps {
55
64
  * component nested inside it — a TagGroup there registers its tags as listbox items and then
56
65
  * crashes looking for grid state. Each chip's remove button is an ordinary Tab stop instead,
57
66
  * and removals are announced through the live region below. */
58
- export declare function MultiComboBox({ label, value, defaultValue, onChange, onInputChange, options, description, errorMessage, allowsCustomValue, size, fullWidth, className, style, ...rest }: MultiComboBoxProps): React.JSX.Element;
67
+ export declare function MultiComboBox({ label, value, defaultValue, onChange, onInputChange, options, description, errorMessage, allowsCustomValue, size, isFilteredExternally, isLoading, loadingLabel, emptyLabel, onLoadMore, fullWidth, className, style, ...rest }: MultiComboBoxProps): React.JSX.Element;
59
68
  //# sourceMappingURL=MultiComboBox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultiComboBox.d.ts","sourceRoot":"","sources":["../../../src/components/forms/MultiComboBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACtC;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAKD;;;;;;;;;;;;;;;;;;;;kEAoBkE;AAClE,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAY,EAC/F,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAE,IAAW,EACzD,SAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,qBAkHlE"}
1
+ {"version":3,"file":"MultiComboBox.d.ts","sourceRoot":"","sources":["../../../src/components/forms/MultiComboBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACtC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;IACzC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,0FAA0F;IAC1F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qGAAqG;IACrG,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAKD;;;;;;;;;;;;;;;;;;;;kEAoBkE;AAClE,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAY,EAC/F,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAE,IAAW,EACzD,oBAAoB,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EACrE,SAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,qBAqIlE"}
@@ -481,6 +481,13 @@
481
481
  .pire-menu-section-title{display:block;padding:var(--sp-1) var(--sp-3);font:var(--type-label);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--text-secondary)}
482
482
  .pire-menu-separator{border:0;border-top:var(--border-w-hairline) solid var(--border-subtle);margin:var(--sp-1) 0}
483
483
 
484
+ /* ---- ComboBox async status ----------------------------------------------- */
485
+ /* Same height as an option row so the popover does not resize when results replace the
486
+ loading line — a popover that jumps has already moved the row under the pointer. */
487
+ .pire-listbox-status{display:flex;align-items:center;min-height:var(--row-h-condensed);padding:0 var(--sp-3);font:var(--type-caption);color:var(--text-secondary)}
488
+ .pire-option-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
489
+ .pire-option-secondary{flex:0 0 auto;font:var(--type-code);color:var(--text-tertiary)}
490
+
484
491
  /* ---- PageBand ------------------------------------------------------------ */
485
492
  .pire-pageband{display:flex;flex-direction:column;gap:var(--sp-3);padding:var(--sp-4) var(--page-pad-x);background:var(--surface-card)}
486
493
  .pire-pageband[data-surface="page"]{background:var(--surface-page)}
@@ -33,6 +33,8 @@ export interface PireMessages {
33
33
  toastRegionLabel: string;
34
34
  /** Accessible name of the button that opens a ComboBox's list. */
35
35
  comboBoxShowSuggestions: string;
36
+ /** Row shown in the popover while a server search is in flight. */
37
+ comboBoxLoading: string;
36
38
  /** Accessible name of the button that opens the calendar popover. */
37
39
  datePickerOpenCalendar: string;
38
40
  datePickerPreviousMonth: string;
@@ -33,6 +33,8 @@ export interface PireMessages {
33
33
  toastRegionLabel: string;
34
34
  /** Accessible name of the button that opens a ComboBox's list. */
35
35
  comboBoxShowSuggestions: string;
36
+ /** Row shown in the popover while a server search is in flight. */
37
+ comboBoxLoading: string;
36
38
  /** Accessible name of the button that opens the calendar popover. */
37
39
  datePickerOpenCalendar: string;
38
40
  datePickerPreviousMonth: string;
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/i18n/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,iBAAiB,EAAE,MAAM,CAAC;IAE1B,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IAEzB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAC;IAEvB,6DAA6D;IAC7D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IAEzB,kEAAkE;IAClE,uBAAuB,EAAE,MAAM,CAAC;IAEhC,qEAAqE;IACrE,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAE5B,oDAAoD;IACpD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAE5B,kEAAkE;IAClE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qFAAqF;IACrF,uBAAuB,EAAE,MAAM,CAAC;IAChC,uEAAuE;IACvE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,qBAAqB,EAAE,MAAM,CAAC;IAC9B,uDAAuD;IACvD,qBAAqB,EAAE,MAAM,CAAC;IAE9B,mDAAmD;IACnD,eAAe,EAAE,MAAM,CAAC;IACxB,wFAAwF;IACxF,eAAe,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAE9B,0FAA0F;IAC1F,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,UAAU,EAAE,YAuCxB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,YAuCxB,CAAC"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/i18n/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,iBAAiB,EAAE,MAAM,CAAC;IAE1B,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IAEzB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAC;IAEvB,6DAA6D;IAC7D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IAEzB,kEAAkE;IAClE,uBAAuB,EAAE,MAAM,CAAC;IAChC,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IAExB,qEAAqE;IACrE,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAE5B,oDAAoD;IACpD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAE5B,kEAAkE;IAClE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qFAAqF;IACrF,uBAAuB,EAAE,MAAM,CAAC;IAChC,uEAAuE;IACvE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,qBAAqB,EAAE,MAAM,CAAC;IAC9B,uDAAuD;IACvD,qBAAqB,EAAE,MAAM,CAAC;IAE9B,mDAAmD;IACnD,eAAe,EAAE,MAAM,CAAC;IACxB,wFAAwF;IACxF,eAAe,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAE9B,0FAA0F;IAC1F,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,UAAU,EAAE,YAwCxB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,YAwCxB,CAAC"}
package/dist/index.cjs CHANGED
@@ -892,6 +892,7 @@ var enMessages = {
892
892
  toastDismiss: "Dismiss",
893
893
  toastRegionLabel: "Notifications",
894
894
  comboBoxShowSuggestions: "Show suggestions",
895
+ comboBoxLoading: "Searching\u2026",
895
896
  datePickerOpenCalendar: "Open calendar",
896
897
  datePickerPreviousMonth: "Previous month",
897
898
  datePickerNextMonth: "Next month",
@@ -923,6 +924,7 @@ var esMessages = {
923
924
  toastDismiss: "Descartar",
924
925
  toastRegionLabel: "Notificaciones",
925
926
  comboBoxShowSuggestions: "Mostrar sugerencias",
927
+ comboBoxLoading: "Buscando\u2026",
926
928
  datePickerOpenCalendar: "Abrir calendario",
927
929
  datePickerPreviousMonth: "Mes anterior",
928
930
  datePickerNextMonth: "Mes siguiente",
@@ -974,12 +976,19 @@ function ComboBox({
974
976
  errorMessage,
975
977
  size = "md",
976
978
  fullWidth = true,
979
+ isFilteredExternally,
980
+ isLoading,
981
+ loadingLabel,
982
+ emptyLabel,
983
+ onLoadMore,
977
984
  className,
978
985
  style,
979
986
  ...rest
980
987
  }) {
981
988
  const msg = usePireMessages();
982
989
  const items = options.map(norm2);
990
+ const collection = isFilteredExternally ? { items } : { defaultItems: items };
991
+ const showsStatus = isLoading || isFilteredExternally && items.length === 0 && emptyLabel != null;
983
992
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
984
993
  import_react_aria_components15.ComboBox,
985
994
  {
@@ -987,9 +996,13 @@ function ComboBox({
987
996
  style,
988
997
  selectedKey: value,
989
998
  defaultSelectedKey: defaultValue,
990
- onSelectionChange: (k) => onChange?.(k == null ? null : String(k)),
999
+ onSelectionChange: (k) => {
1000
+ if (isLoading) return;
1001
+ onChange?.(k == null ? null : String(k));
1002
+ },
991
1003
  onInputChange,
992
- defaultItems: items,
1004
+ ...collection,
1005
+ allowsEmptyCollection: isFilteredExternally || isLoading,
993
1006
  menuTrigger: "input",
994
1007
  validationBehavior: "aria",
995
1008
  ...rest,
@@ -1014,10 +1027,21 @@ function ComboBox({
1014
1027
  ),
1015
1028
  description ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_aria_components15.Text, { slot: "description", className: "pire-field-hint", children: description }) : null,
1016
1029
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_aria_components15.FieldError, { className: "pire-field-error", children: errorMessage }),
1017
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_aria_components15.Popover, { className: "pire-popover", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_aria_components15.ListBox, { className: "pire-listbox", children: (item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_aria_components15.ListBoxItem, { className: "pire-option", id: item.value, textValue: item.label, isDisabled: item.isDisabled, children: [
1018
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { flex: 1 }, children: item.label }),
1019
- item.secondary ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { font: "var(--type-code)", color: "var(--text-tertiary)" }, children: item.secondary }) : null
1020
- ] }) }) })
1030
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_aria_components15.Popover, { className: "pire-popover", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1031
+ import_react_aria_components15.ListBox,
1032
+ {
1033
+ className: "pire-listbox",
1034
+ onScroll: onLoadMore ? (e) => {
1035
+ const el = e.currentTarget;
1036
+ if (el.scrollHeight - el.scrollTop - el.clientHeight < 48) onLoadMore();
1037
+ } : void 0,
1038
+ renderEmptyState: showsStatus ? () => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "pire-listbox-status", role: "status", "aria-live": "polite", children: isLoading ? loadingLabel ?? msg.comboBoxLoading : emptyLabel }) : void 0,
1039
+ children: (item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_aria_components15.ListBoxItem, { className: "pire-option", id: item.value, textValue: item.label, isDisabled: item.isDisabled, children: [
1040
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pire-option-label", children: item.label }),
1041
+ item.secondary ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pire-option-secondary", children: item.secondary }) : null
1042
+ ] })
1043
+ }
1044
+ ) })
1021
1045
  ]
1022
1046
  }
1023
1047
  );
@@ -1039,6 +1063,11 @@ function MultiComboBox({
1039
1063
  errorMessage,
1040
1064
  allowsCustomValue,
1041
1065
  size = "md",
1066
+ isFilteredExternally,
1067
+ isLoading,
1068
+ loadingLabel,
1069
+ emptyLabel,
1070
+ onLoadMore,
1042
1071
  fullWidth = true,
1043
1072
  className,
1044
1073
  style,
@@ -1046,6 +1075,8 @@ function MultiComboBox({
1046
1075
  }) {
1047
1076
  const msg = usePireMessages();
1048
1077
  const items = React7.useMemo(() => options.map(norm3), [options]);
1078
+ const collection = isFilteredExternally ? { items } : { defaultItems: items };
1079
+ const showsStatus = isLoading || isFilteredExternally && items.length === 0 && emptyLabel != null;
1049
1080
  const [uncontrolled, setUncontrolled] = React7.useState(defaultValue ?? []);
1050
1081
  const [announcement, setAnnouncement] = React7.useState("");
1051
1082
  const inputRef = React7.useRef(null);
@@ -1091,9 +1122,12 @@ function MultiComboBox({
1091
1122
  style,
1092
1123
  selectionMode: "multiple",
1093
1124
  value: values,
1094
- onChange: (keys) => commit(keys.map(String)),
1125
+ onChange: (keys) => {
1126
+ if (!isLoading) commit(keys.map(String));
1127
+ },
1095
1128
  onInputChange,
1096
- defaultItems: items,
1129
+ ...collection,
1130
+ allowsEmptyCollection: isFilteredExternally || isLoading,
1097
1131
  menuTrigger: "input",
1098
1132
  validationBehavior: "aria",
1099
1133
  ...rest,
@@ -1136,10 +1170,21 @@ function MultiComboBox({
1136
1170
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_aria_components16.VisuallyHidden, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-live": "polite", children: announcement }) }),
1137
1171
  description ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_aria_components16.Text, { slot: "description", className: "pire-field-hint", children: description }) : null,
1138
1172
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_aria_components16.FieldError, { className: "pire-field-error", children: errorMessage }),
1139
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_aria_components16.Popover, { className: "pire-popover", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_aria_components16.ListBox, { className: "pire-listbox", children: (item) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_aria_components16.ListBoxItem, { className: "pire-option", id: item.value, textValue: item.label, isDisabled: item.isDisabled, children: [
1140
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { flex: 1 }, children: item.label }),
1141
- item.secondary ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { font: "var(--type-code)", color: "var(--text-tertiary)" }, children: item.secondary }) : null
1142
- ] }) }) })
1173
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_aria_components16.Popover, { className: "pire-popover", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1174
+ import_react_aria_components16.ListBox,
1175
+ {
1176
+ className: "pire-listbox",
1177
+ onScroll: onLoadMore ? (e) => {
1178
+ const el = e.currentTarget;
1179
+ if (el.scrollHeight - el.scrollTop - el.clientHeight < 48) onLoadMore();
1180
+ } : void 0,
1181
+ renderEmptyState: showsStatus ? () => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "pire-listbox-status", role: "status", "aria-live": "polite", children: isLoading ? loadingLabel ?? msg.comboBoxLoading : emptyLabel }) : void 0,
1182
+ children: (item) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_aria_components16.ListBoxItem, { className: "pire-option", id: item.value, textValue: item.label, isDisabled: item.isDisabled, children: [
1183
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "pire-option-label", children: item.label }),
1184
+ item.secondary ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "pire-option-secondary", children: item.secondary }) : null
1185
+ ] })
1186
+ }
1187
+ ) })
1143
1188
  ]
1144
1189
  }
1145
1190
  );