@orianatech/pire 0.7.0 → 0.9.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"}
@@ -0,0 +1,57 @@
1
+ import * as React from 'react';
2
+ export interface PireFile {
3
+ /** The browser's `File`. Pire uploads nothing — that is the app's job. */
4
+ file: File;
5
+ /** Object URL, only for images with `showPreview`. Revoked on unmount. */
6
+ previewUrl?: string;
7
+ }
8
+ export interface FileRejection {
9
+ file: File;
10
+ reason: 'size' | 'type';
11
+ }
12
+ export interface FileUploadProps {
13
+ label?: React.ReactNode;
14
+ /** Controlled / uncontrolled, the same pair as `Tabs` and `MultiComboBox`. */
15
+ value?: PireFile[];
16
+ defaultValue?: PireFile[];
17
+ onChange?: (files: PireFile[]) => void;
18
+ /** Mime types or extensions, exactly as `FileTrigger.acceptedFileTypes` takes them. */
19
+ acceptedFileTypes?: readonly string[];
20
+ allowsMultiple?: boolean;
21
+ /** Ceiling in bytes. Oversized files are rejected and reported, never held. */
22
+ maxSize?: number;
23
+ /** Rejections, so the app can word its own message. */
24
+ onError?: (rejections: FileRejection[]) => void;
25
+ /** Thumbnail for images. Turn it off for CSVs, where a thumbnail says nothing. */
26
+ showPreview?: boolean;
27
+ /** Upload progress 0–100, while the app is doing the uploading. */
28
+ uploadProgress?: number;
29
+ /** Overrides the dictionary's `fileUploadChoose`. */
30
+ chooseLabel?: string;
31
+ description?: React.ReactNode;
32
+ errorMessage?: React.ReactNode;
33
+ isInvalid?: boolean;
34
+ isDisabled?: boolean;
35
+ isRequired?: boolean;
36
+ isReadOnly?: boolean;
37
+ fullWidth?: boolean;
38
+ name?: string;
39
+ className?: string;
40
+ style?: React.CSSProperties;
41
+ }
42
+ /** Human-readable size. Deliberately not localised digits: `toLocaleString` on the number only. */
43
+ export declare function formatFileSize(bytes: number): string;
44
+ /** Splits a picked list into keepers and rejections, without uploading or mutating anything. */
45
+ export declare function screenFiles(files: File[], { maxSize, acceptedFileTypes }: {
46
+ maxSize?: number;
47
+ acceptedFileTypes?: readonly string[];
48
+ }): {
49
+ accepted: File[];
50
+ rejected: FileRejection[];
51
+ };
52
+ /**
53
+ * File picker with a list of what was chosen. Pire hands back `File`s through `onChange` and
54
+ * uploads nothing: the app owns the `FormData`, the request and the progress it reports back
55
+ * through `uploadProgress`.
56
+ */
57
+ export declare function FileUpload({ label, value, defaultValue, onChange, acceptedFileTypes, allowsMultiple, maxSize, onError, showPreview, uploadProgress, chooseLabel, description, errorMessage, isInvalid, isDisabled, isReadOnly, isRequired, fullWidth, className, style, }: FileUploadProps): React.JSX.Element;
@@ -0,0 +1,58 @@
1
+ import * as React from 'react';
2
+ export interface PireFile {
3
+ /** The browser's `File`. Pire uploads nothing — that is the app's job. */
4
+ file: File;
5
+ /** Object URL, only for images with `showPreview`. Revoked on unmount. */
6
+ previewUrl?: string;
7
+ }
8
+ export interface FileRejection {
9
+ file: File;
10
+ reason: 'size' | 'type';
11
+ }
12
+ export interface FileUploadProps {
13
+ label?: React.ReactNode;
14
+ /** Controlled / uncontrolled, the same pair as `Tabs` and `MultiComboBox`. */
15
+ value?: PireFile[];
16
+ defaultValue?: PireFile[];
17
+ onChange?: (files: PireFile[]) => void;
18
+ /** Mime types or extensions, exactly as `FileTrigger.acceptedFileTypes` takes them. */
19
+ acceptedFileTypes?: readonly string[];
20
+ allowsMultiple?: boolean;
21
+ /** Ceiling in bytes. Oversized files are rejected and reported, never held. */
22
+ maxSize?: number;
23
+ /** Rejections, so the app can word its own message. */
24
+ onError?: (rejections: FileRejection[]) => void;
25
+ /** Thumbnail for images. Turn it off for CSVs, where a thumbnail says nothing. */
26
+ showPreview?: boolean;
27
+ /** Upload progress 0–100, while the app is doing the uploading. */
28
+ uploadProgress?: number;
29
+ /** Overrides the dictionary's `fileUploadChoose`. */
30
+ chooseLabel?: string;
31
+ description?: React.ReactNode;
32
+ errorMessage?: React.ReactNode;
33
+ isInvalid?: boolean;
34
+ isDisabled?: boolean;
35
+ isRequired?: boolean;
36
+ isReadOnly?: boolean;
37
+ fullWidth?: boolean;
38
+ name?: string;
39
+ className?: string;
40
+ style?: React.CSSProperties;
41
+ }
42
+ /** Human-readable size. Deliberately not localised digits: `toLocaleString` on the number only. */
43
+ export declare function formatFileSize(bytes: number): string;
44
+ /** Splits a picked list into keepers and rejections, without uploading or mutating anything. */
45
+ export declare function screenFiles(files: File[], { maxSize, acceptedFileTypes }: {
46
+ maxSize?: number;
47
+ acceptedFileTypes?: readonly string[];
48
+ }): {
49
+ accepted: File[];
50
+ rejected: FileRejection[];
51
+ };
52
+ /**
53
+ * File picker with a list of what was chosen. Pire hands back `File`s through `onChange` and
54
+ * uploads nothing: the app owns the `FormData`, the request and the progress it reports back
55
+ * through `uploadProgress`.
56
+ */
57
+ export declare function FileUpload({ label, value, defaultValue, onChange, acceptedFileTypes, allowsMultiple, maxSize, onError, showPreview, uploadProgress, chooseLabel, description, errorMessage, isInvalid, isDisabled, isReadOnly, isRequired, fullWidth, className, style, }: FileUploadProps): React.JSX.Element;
58
+ //# sourceMappingURL=FileUpload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../../src/components/forms/FileUpload.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,MAAM,WAAW,QAAQ;IACvB,0EAA0E;IAC1E,IAAI,EAAE,IAAI,CAAC;IACX,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACvC,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IAChD,kFAAkF;IAClF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,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,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;AAID,mGAAmG;AACnG,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED,gGAAgG;AAChG,wBAAgB,WAAW,CACzB,KAAK,EAAE,IAAI,EAAE,EACb,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC1F;IAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,CAwBjD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EACzF,WAAkB,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAC1E,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,SAAgB,EAAE,SAAS,EAAE,KAAK,GAClF,EAAE,eAAe,qBA2EjB"}
@@ -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"}
@@ -40,9 +40,16 @@ export interface SideNavProps extends Omit<React.HTMLAttributes<HTMLElement>, 'o
40
40
  defaultExpandedIds?: string[];
41
41
  /** Fires with every expanded id after a toggle, controlled or not. */
42
42
  onExpandedChange?: (ids: string[]) => void;
43
- /** 48px icon rail. Labels move into tooltips, and second-level items are not rendered at all —
44
- * see the note on {@link SideNav}. */
43
+ /** 48px icon rail. Labels move into tooltips or, for a group, into its flyout. */
45
44
  collapsed?: boolean;
45
+ /**
46
+ * In the rail, a group opens its children in a flyout beside it. On by default: without it the
47
+ * rail records an expansion nothing can draw, leaving second-level destinations reachable only
48
+ * by expanding the nav again.
49
+ *
50
+ * Pass `false` for the previous behaviour, where a rail group toggles expansion invisibly.
51
+ */
52
+ railFlyout?: boolean;
46
53
  footer?: React.ReactNode;
47
54
  }
48
55
  /** Primary navigation. A first-level entry is either a destination (icon + label, selectable) or a
@@ -63,12 +70,11 @@ export interface SideNavProps extends Omit<React.HTMLAttributes<HTMLElement>, 'o
63
70
  * UA's `[hidden] { display: none }`, leaving collapsed children focusable under
64
71
  * `aria-hidden="true"`. `.pire-sidenav-subnav[hidden]` in `components.css` is that guard.
65
72
  * - **`collapsed` and expansion are different axes, and the rail wins.** With `collapsed` set there
66
- * are no labels, and a second level is nothing *but* labels, so children are not rendered in the
67
- * rail. A group's row becomes an ordinary icon button that records the expansion (so the group is
68
- * already open when the rail expands) and lights up while it holds `value`, which is the one thing
69
- * a rail must still communicate. It follows that a nav with collapsible groups needs a way back
70
- * out of the rail `ShellBar`'s `onMenu` — or 25 of those 35 destinations are unreachable, for
71
- * everyone, exactly as the labels already are.
73
+ * are no labels, and a second level is nothing *but* labels. A group therefore opens its children
74
+ * in a flyout beside the rail (`railFlyout`, on by default) rather than inline. With
75
+ * `railFlyout={false}` the row falls back to recording the expansion silently which leaves
76
+ * second-level destinations reachable only by expanding the nav again, so it is off the
77
+ * accessible path and exists for compatibility.
72
78
  * - **Several groups can be open at once**, and there is no accordion mode. Closing the group you
73
79
  * are in to open another is the wrong trade in a nav whose whole job is showing where you are. */
74
- export declare function SideNav({ groups, value, onChange, expandedIds, defaultExpandedIds, onExpandedChange, collapsed, footer, className, ...rest }: SideNavProps): React.JSX.Element;
80
+ export declare function SideNav({ groups, value, onChange, expandedIds, defaultExpandedIds, onExpandedChange, collapsed, railFlyout, footer, className, ...rest }: SideNavProps): React.JSX.Element;
@@ -40,9 +40,16 @@ export interface SideNavProps extends Omit<React.HTMLAttributes<HTMLElement>, 'o
40
40
  defaultExpandedIds?: string[];
41
41
  /** Fires with every expanded id after a toggle, controlled or not. */
42
42
  onExpandedChange?: (ids: string[]) => void;
43
- /** 48px icon rail. Labels move into tooltips, and second-level items are not rendered at all —
44
- * see the note on {@link SideNav}. */
43
+ /** 48px icon rail. Labels move into tooltips or, for a group, into its flyout. */
45
44
  collapsed?: boolean;
45
+ /**
46
+ * In the rail, a group opens its children in a flyout beside it. On by default: without it the
47
+ * rail records an expansion nothing can draw, leaving second-level destinations reachable only
48
+ * by expanding the nav again.
49
+ *
50
+ * Pass `false` for the previous behaviour, where a rail group toggles expansion invisibly.
51
+ */
52
+ railFlyout?: boolean;
46
53
  footer?: React.ReactNode;
47
54
  }
48
55
  /** Primary navigation. A first-level entry is either a destination (icon + label, selectable) or a
@@ -63,13 +70,12 @@ export interface SideNavProps extends Omit<React.HTMLAttributes<HTMLElement>, 'o
63
70
  * UA's `[hidden] { display: none }`, leaving collapsed children focusable under
64
71
  * `aria-hidden="true"`. `.pire-sidenav-subnav[hidden]` in `components.css` is that guard.
65
72
  * - **`collapsed` and expansion are different axes, and the rail wins.** With `collapsed` set there
66
- * are no labels, and a second level is nothing *but* labels, so children are not rendered in the
67
- * rail. A group's row becomes an ordinary icon button that records the expansion (so the group is
68
- * already open when the rail expands) and lights up while it holds `value`, which is the one thing
69
- * a rail must still communicate. It follows that a nav with collapsible groups needs a way back
70
- * out of the rail `ShellBar`'s `onMenu` — or 25 of those 35 destinations are unreachable, for
71
- * everyone, exactly as the labels already are.
73
+ * are no labels, and a second level is nothing *but* labels. A group therefore opens its children
74
+ * in a flyout beside the rail (`railFlyout`, on by default) rather than inline. With
75
+ * `railFlyout={false}` the row falls back to recording the expansion silently which leaves
76
+ * second-level destinations reachable only by expanding the nav again, so it is off the
77
+ * accessible path and exists for compatibility.
72
78
  * - **Several groups can be open at once**, and there is no accordion mode. Closing the group you
73
79
  * are in to open another is the wrong trade in a nav whose whole job is showing where you are. */
74
- export declare function SideNav({ groups, value, onChange, expandedIds, defaultExpandedIds, onExpandedChange, collapsed, footer, className, ...rest }: SideNavProps): React.JSX.Element;
80
+ export declare function SideNav({ groups, value, onChange, expandedIds, defaultExpandedIds, onExpandedChange, collapsed, railFlyout, footer, className, ...rest }: SideNavProps): React.JSX.Element;
75
81
  //# sourceMappingURL=SideNav.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SideNav.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/SideNav.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B;;;;8EAI8E;AAC9E,MAAM,WAAW,gBAAgB;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAE/E,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;wEAGoE;IACpE,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAAG,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE;AAEtE,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IACvF,uDAAuD;IACvD,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;mGAC+F;IAC/F,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC;sEACkE;IAClE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;mCAE+B;IAC/B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3C;2CACuC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;qGAyBqG;AACrG,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAClG,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,YAAY,qBAgHtD"}
1
+ {"version":3,"file":"SideNav.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/SideNav.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B;;;;8EAI8E;AAC9E,MAAM,WAAW,gBAAgB;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAE/E,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;wEAGoE;IACpE,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAAG,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE;AAEtE,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IACvF,uDAAuD;IACvD,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;mGAC+F;IAC/F,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC;sEACkE;IAClE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;mCAE+B;IAC/B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3C,kFAAkF;IAClF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B;AAaD;;;;;;;;;;;;;;;;;;;;;;;;qGAwBqG;AACrG,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAClG,SAAS,EAAE,UAAiB,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,YAAY,qBAwIzE"}
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import { type FileUploadProps } from '../forms/FileUpload.cjs';
3
+ export interface FileDropZoneProps extends Omit<FileUploadProps, 'chooseLabel'> {
4
+ /** Instruction inside the zone. Overrides the dictionary's `fileDropZonePrompt`. */
5
+ promptLabel?: React.ReactNode;
6
+ /** `compact` for an import modal, where the zone competes with a table for height. */
7
+ height?: 'compact' | 'regular';
8
+ }
9
+ /**
10
+ * The large drop surface, for import screens and anywhere a file is the point of the page.
11
+ *
12
+ * Built on React Aria's `DropZone`, so it is a real drop target for keyboard and assistive tech —
13
+ * not a div with `onDragOver`. It still contains a `FileTrigger`, because drag-and-drop alone is
14
+ * not an accessible way to supply a file.
15
+ */
16
+ export declare function FileDropZone({ label, value, defaultValue, onChange, acceptedFileTypes, allowsMultiple, maxSize, onError, showPreview, uploadProgress, promptLabel, height, description, errorMessage, isInvalid, isDisabled, isReadOnly, isRequired, fullWidth, className, style, }: FileDropZoneProps): React.JSX.Element;
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+ import { type FileUploadProps } from '../forms/FileUpload.js';
3
+ export interface FileDropZoneProps extends Omit<FileUploadProps, 'chooseLabel'> {
4
+ /** Instruction inside the zone. Overrides the dictionary's `fileDropZonePrompt`. */
5
+ promptLabel?: React.ReactNode;
6
+ /** `compact` for an import modal, where the zone competes with a table for height. */
7
+ height?: 'compact' | 'regular';
8
+ }
9
+ /**
10
+ * The large drop surface, for import screens and anywhere a file is the point of the page.
11
+ *
12
+ * Built on React Aria's `DropZone`, so it is a real drop target for keyboard and assistive tech —
13
+ * not a div with `onDragOver`. It still contains a `FileTrigger`, because drag-and-drop alone is
14
+ * not an accessible way to supply a file.
15
+ */
16
+ export declare function FileDropZone({ label, value, defaultValue, onChange, acceptedFileTypes, allowsMultiple, maxSize, onError, showPreview, uploadProgress, promptLabel, height, description, errorMessage, isInvalid, isDisabled, isReadOnly, isRequired, fullWidth, className, style, }: FileDropZoneProps): React.JSX.Element;
17
+ //# sourceMappingURL=FileDropZone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileDropZone.d.ts","sourceRoot":"","sources":["../../../src/components/patterns/FileDropZone.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,EAA+B,KAAK,eAAe,EAAiB,MAAM,qBAAqB,CAAC;AAIvG,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC;IAC7E,oFAAoF;IACpF,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,sFAAsF;IACtF,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CAChC;AAID;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EACzF,WAAkB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAkB,EAAE,WAAW,EAAE,YAAY,EAC9F,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,SAAgB,EAAE,SAAS,EAAE,KAAK,GAClF,EAAE,iBAAiB,qBAyFnB"}
@@ -481,6 +481,37 @@
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
+ /* ---- FileUpload / FileDropZone ------------------------------------------- */
485
+ .pire-fileupload-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-1)}
486
+ .pire-fileupload-item{display:flex;align-items:center;gap:var(--sp-2);min-height:var(--row-h-condensed);padding:0 var(--sp-2);border:1px solid var(--border-subtle);border-radius:var(--radius-1);background:var(--surface-card)}
487
+ .pire-fileupload-icon{flex:0 0 auto;color:var(--text-secondary)}
488
+ .pire-fileupload-thumb{flex:0 0 auto;width:24px;height:24px;object-fit:cover;border-radius:var(--radius-1)}
489
+ .pire-fileupload-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--type-body)}
490
+ .pire-fileupload-size{flex:0 0 auto;font:var(--type-caption);color:var(--text-secondary);font-variant-numeric:tabular-nums}
491
+ .pire-dropzone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sp-2);padding:var(--sp-6);border:1px dashed var(--border-default);border-radius:var(--radius-2);background:var(--surface-sunken);color:var(--text-secondary);text-align:center;transition:var(--transition-surface)}
492
+ .pire-dropzone[data-height="compact"]{padding:var(--sp-4)}
493
+ /* React Aria sets data-drop-target while a drag hovers, and data-focus-visible on keyboard
494
+ focus — the zone is a real drop target, so both states have to read as active. */
495
+ .pire-dropzone[data-drop-target]{border-color:var(--accent-bg);border-style:solid;background:var(--accent-subtle-bg)}
496
+ .pire-dropzone[data-focus-visible]{outline:var(--focus-w) solid var(--focus-color);outline-offset:var(--focus-offset)}
497
+ .pire-dropzone[data-disabled]{background:var(--surface-disabled);color:var(--text-disabled);border-color:var(--border-subtle)}
498
+ .pire-dropzone-icon{color:var(--text-tertiary)}
499
+ .pire-dropzone-prompt{font:var(--type-body)}
500
+
501
+ /* ---- SideNav rail flyout -------------------------------------------------- */
502
+ /* Matches the expanded nav's width so the flyout is not visibly narrower than the menu it
503
+ stands in for. The rows drop the second-level indent: there is no first level beside them
504
+ here, so the indent would be measuring against something that is not on screen. */
505
+ .pire-sidenav-flyout{min-width:var(--sidenav-w)}
506
+ .pire-sidenav-flyout .pire-menu-item{padding-left:var(--sp-4)}
507
+
508
+ /* ---- ComboBox async status ----------------------------------------------- */
509
+ /* Same height as an option row so the popover does not resize when results replace the
510
+ loading line — a popover that jumps has already moved the row under the pointer. */
511
+ .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)}
512
+ .pire-option-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
513
+ .pire-option-secondary{flex:0 0 auto;font:var(--type-code);color:var(--text-tertiary)}
514
+
484
515
  /* ---- PageBand ------------------------------------------------------------ */
485
516
  .pire-pageband{display:flex;flex-direction:column;gap:var(--sp-3);padding:var(--sp-4) var(--page-pad-x);background:var(--surface-card)}
486
517
  .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;
@@ -61,6 +63,14 @@ export interface PireMessages {
61
63
  paginationRowsPerPage: string;
62
64
  /** Landmark name of the main SideNav. Override it when a screen has more than one nav. */
63
65
  sideNavLabel: string;
66
+ /** Button that opens the OS file picker. */
67
+ fileUploadChoose: string;
68
+ /** Removes one picked file. `{name}` is replaced with the file name. */
69
+ fileUploadRemoveNamed: string;
70
+ /** Label on the progress bar while the app uploads. */
71
+ fileUploadUploading: string;
72
+ /** Instruction inside the drop surface. */
73
+ fileDropZonePrompt: string;
64
74
  }
65
75
  export declare const enMessages: PireMessages;
66
76
  export declare const esMessages: PireMessages;
@@ -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;
@@ -61,6 +63,14 @@ export interface PireMessages {
61
63
  paginationRowsPerPage: string;
62
64
  /** Landmark name of the main SideNav. Override it when a screen has more than one nav. */
63
65
  sideNavLabel: string;
66
+ /** Button that opens the OS file picker. */
67
+ fileUploadChoose: string;
68
+ /** Removes one picked file. `{name}` is replaced with the file name. */
69
+ fileUploadRemoveNamed: string;
70
+ /** Label on the progress bar while the app uploads. */
71
+ fileUploadUploading: string;
72
+ /** Instruction inside the drop surface. */
73
+ fileDropZonePrompt: string;
64
74
  }
65
75
  export declare const enMessages: PireMessages;
66
76
  export declare const esMessages: PireMessages;
@@ -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;IAErB,4CAA4C;IAC5C,gBAAgB,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,qBAAqB,EAAE,MAAM,CAAC;IAC9B,uDAAuD;IACvD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,2CAA2C;IAC3C,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,UAAU,EAAE,YA6CxB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,YA6CxB,CAAC"}