@openwarelabs/ui 0.3.1 → 0.5.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.
Files changed (71) hide show
  1. package/README.md +8 -7
  2. package/dist/components/Calendar/Calendar.d.cts +58 -0
  3. package/dist/components/Calendar/Calendar.d.ts +58 -0
  4. package/dist/components/Calendar/DateRangePicker.d.cts +39 -0
  5. package/dist/components/Calendar/DateRangePicker.d.ts +39 -0
  6. package/dist/components/Calendar/RangeCalendar.d.cts +38 -0
  7. package/dist/components/Calendar/RangeCalendar.d.ts +38 -0
  8. package/dist/components/Calendar/dates.d.cts +13 -0
  9. package/dist/components/Calendar/dates.d.ts +13 -0
  10. package/dist/components/ChainOfThought/ChainOfThought.d.cts +44 -0
  11. package/dist/components/ChainOfThought/ChainOfThought.d.ts +44 -0
  12. package/dist/components/Chat/ChatConversation.d.cts +48 -0
  13. package/dist/components/Chat/ChatConversation.d.ts +48 -0
  14. package/dist/components/Chat/ChatLoader.d.cts +21 -0
  15. package/dist/components/Chat/ChatLoader.d.ts +21 -0
  16. package/dist/components/Chat/ChatMessage.d.cts +93 -0
  17. package/dist/components/Chat/ChatMessage.d.ts +93 -0
  18. package/dist/components/ChatSource/ChatSource.d.cts +58 -0
  19. package/dist/components/ChatSource/ChatSource.d.ts +58 -0
  20. package/dist/components/ChatTool/ChatTool.d.cts +89 -0
  21. package/dist/components/ChatTool/ChatTool.d.ts +89 -0
  22. package/dist/components/ColorPicker/ColorArea.d.cts +44 -0
  23. package/dist/components/ColorPicker/ColorArea.d.ts +44 -0
  24. package/dist/components/ColorPicker/ColorSlider.d.cts +53 -0
  25. package/dist/components/ColorPicker/ColorSlider.d.ts +53 -0
  26. package/dist/components/ColorPicker/ColorSwatchPicker.d.cts +43 -0
  27. package/dist/components/ColorPicker/ColorSwatchPicker.d.ts +43 -0
  28. package/dist/components/ColorPicker/color.d.cts +91 -0
  29. package/dist/components/ColorPicker/color.d.ts +91 -0
  30. package/dist/components/DateField/DateField.d.cts +47 -0
  31. package/dist/components/DateField/DateField.d.ts +47 -0
  32. package/dist/components/DateField/SegmentedField.d.cts +63 -0
  33. package/dist/components/DateField/SegmentedField.d.ts +63 -0
  34. package/dist/components/DateField/TimeField.d.cts +52 -0
  35. package/dist/components/DateField/TimeField.d.ts +52 -0
  36. package/dist/components/Field/Field.d.cts +17 -5
  37. package/dist/components/Field/Field.d.ts +17 -5
  38. package/dist/components/FileDropZone/FileDropZone.d.cts +1 -1
  39. package/dist/components/FileDropZone/FileDropZone.d.ts +1 -1
  40. package/dist/components/Form/Form.d.cts +63 -0
  41. package/dist/components/Form/Form.d.ts +63 -0
  42. package/dist/components/InputOTP/InputOTP.d.cts +7 -1
  43. package/dist/components/InputOTP/InputOTP.d.ts +7 -1
  44. package/dist/components/ListBox/ListBox.d.cts +65 -0
  45. package/dist/components/ListBox/ListBox.d.ts +65 -0
  46. package/dist/components/Meter/Meter.d.cts +62 -0
  47. package/dist/components/Meter/Meter.d.ts +62 -0
  48. package/dist/components/PromptInput/PromptInput.d.cts +95 -0
  49. package/dist/components/PromptInput/PromptInput.d.ts +95 -0
  50. package/dist/components/PromptInput/PromptSuggestion.d.cts +36 -0
  51. package/dist/components/PromptInput/PromptSuggestion.d.ts +36 -0
  52. package/dist/components/Prose/Prose.d.cts +22 -0
  53. package/dist/components/Prose/Prose.d.ts +22 -0
  54. package/dist/components/Slider/Slider.d.cts +7 -1
  55. package/dist/components/Slider/Slider.d.ts +7 -1
  56. package/dist/components/TextShimmer/TextShimmer.d.cts +20 -0
  57. package/dist/components/TextShimmer/TextShimmer.d.ts +20 -0
  58. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.d.cts +74 -0
  59. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.d.ts +74 -0
  60. package/dist/components/Toolbar/Toolbar.d.cts +36 -0
  61. package/dist/components/Toolbar/Toolbar.d.ts +36 -0
  62. package/dist/components.css +3557 -38
  63. package/dist/index.cjs +7391 -3179
  64. package/dist/index.cjs.map +4 -4
  65. package/dist/index.d.cts +45 -0
  66. package/dist/index.d.ts +45 -0
  67. package/dist/index.js +7478 -3214
  68. package/dist/index.js.map +4 -4
  69. package/dist/openware-ui.iife.js +7 -6
  70. package/dist/styles.css +3557 -38
  71. package/package.json +1 -1
@@ -1,18 +1,30 @@
1
1
  import { type ReactElement, type ReactNode } from "react";
2
+ import { type ValidityMessages } from "../Form/Form.cjs";
2
3
  export interface FieldProps {
3
- /** The label, set above the control. */
4
- label: ReactNode;
4
+ /** The label, set above the control. Leave it out for a control that has its own, like a Checkbox. */
5
+ label?: ReactNode;
5
6
  /** One control: an Input, Textarea, Select, or any element that takes an id. */
6
7
  children: ReactElement;
7
8
  /** A muted line under the control. */
8
9
  hint?: ReactNode;
9
- /** An error under the control; it also marks the control invalid. */
10
+ /** An error under the control; it also marks the control invalid. Inside a Form, it takes the place of the Form's. */
10
11
  error?: ReactNode;
12
+ /**
13
+ * The field's name, for a control with no `name` of its own (Select, Combobox, Switch, DatePicker): Field submits
14
+ * the control's `value` (or `checked`) under it in a hidden input, and inside a Form shows the Form's error for it.
15
+ * The control must be controlled; a string, a number, true or an array of them is sent.
16
+ */
17
+ name?: string;
18
+ /**
19
+ * Inside a Form, what to say when one of the browser's checks fails, in place of its own message: one string for
20
+ * any check, or one per check, like { valueMissing: "Enter your work email.", typeMismatch: "…" }.
21
+ */
22
+ errorMessages?: ValidityMessages;
11
23
  className?: string;
12
24
  }
13
25
  /**
14
26
  * A label above a control, with an optional hint and error below. Field wires them together:
15
27
  * it gives the control an id (unless it has one), points aria-describedby at the hint and error,
16
- * and marks it invalid when there is an error.
28
+ * and marks it invalid when there is an error. Inside a Form, it shows the Form's error for its control's name.
17
29
  */
18
- export declare function Field({ label, children, hint, error, className }: FieldProps): import("react").JSX.Element;
30
+ export declare function Field({ label, children, hint, error, name: nameProp, errorMessages, className }: FieldProps): import("react").JSX.Element;
@@ -1,18 +1,30 @@
1
1
  import { type ReactElement, type ReactNode } from "react";
2
+ import { type ValidityMessages } from "../Form/Form.js";
2
3
  export interface FieldProps {
3
- /** The label, set above the control. */
4
- label: ReactNode;
4
+ /** The label, set above the control. Leave it out for a control that has its own, like a Checkbox. */
5
+ label?: ReactNode;
5
6
  /** One control: an Input, Textarea, Select, or any element that takes an id. */
6
7
  children: ReactElement;
7
8
  /** A muted line under the control. */
8
9
  hint?: ReactNode;
9
- /** An error under the control; it also marks the control invalid. */
10
+ /** An error under the control; it also marks the control invalid. Inside a Form, it takes the place of the Form's. */
10
11
  error?: ReactNode;
12
+ /**
13
+ * The field's name, for a control with no `name` of its own (Select, Combobox, Switch, DatePicker): Field submits
14
+ * the control's `value` (or `checked`) under it in a hidden input, and inside a Form shows the Form's error for it.
15
+ * The control must be controlled; a string, a number, true or an array of them is sent.
16
+ */
17
+ name?: string;
18
+ /**
19
+ * Inside a Form, what to say when one of the browser's checks fails, in place of its own message: one string for
20
+ * any check, or one per check, like { valueMissing: "Enter your work email.", typeMismatch: "…" }.
21
+ */
22
+ errorMessages?: ValidityMessages;
11
23
  className?: string;
12
24
  }
13
25
  /**
14
26
  * A label above a control, with an optional hint and error below. Field wires them together:
15
27
  * it gives the control an id (unless it has one), points aria-describedby at the hint and error,
16
- * and marks it invalid when there is an error.
28
+ * and marks it invalid when there is an error. Inside a Form, it shows the Form's error for its control's name.
17
29
  */
18
- export declare function Field({ label, children, hint, error, className }: FieldProps): import("react").JSX.Element;
30
+ export declare function Field({ label, children, hint, error, name: nameProp, errorMessages, className }: FieldProps): import("react").JSX.Element;
@@ -18,7 +18,7 @@ export interface FileDropZoneProps {
18
18
  * @default <UploadIcon /> */
19
19
  icon?: ReactNode;
20
20
  disabled?: boolean;
21
- /** The form field name for the file input. */
21
+ /** The form field name for the file input. A form submits the files from the last accepted pick or drop. */
22
22
  name?: string;
23
23
  className?: string;
24
24
  }
@@ -18,7 +18,7 @@ export interface FileDropZoneProps {
18
18
  * @default <UploadIcon /> */
19
19
  icon?: ReactNode;
20
20
  disabled?: boolean;
21
- /** The form field name for the file input. */
21
+ /** The form field name for the file input. A form submits the files from the last accepted pick or drop. */
22
22
  name?: string;
23
23
  className?: string;
24
24
  }
@@ -0,0 +1,63 @@
1
+ import { type FormEvent, type FormHTMLAttributes, type MutableRefObject, type ReactNode, type RefObject } from "react";
2
+ /** What onSubmit and validate get: each name in the form with its value, or a string[] when the name appears more than once. */
3
+ export type FormValues = Record<string, string | string[]>;
4
+ /** Messages by field name. */
5
+ export type FormErrors = Partial<Record<string, string>>;
6
+ /** The browser's own checks, by their ValidityState names. */
7
+ export type ValidityCheck = "valueMissing" | "typeMismatch" | "patternMismatch" | "tooShort" | "tooLong" | "rangeUnderflow" | "rangeOverflow" | "stepMismatch" | "badInput";
8
+ /** What to say when a browser check fails: one message for any of them, or one per check. */
9
+ export type ValidityMessages = string | Partial<Record<ValidityCheck, string>>;
10
+ /** What a Form tells the components inside it, through the render function or useFormStatus(). */
11
+ export interface FormStatus {
12
+ /** True while the promise onSubmit returned is pending. */
13
+ isSubmitting: boolean;
14
+ /** The errors showing now, by field name. */
15
+ errors: FormErrors;
16
+ }
17
+ export interface FormProps extends Omit<FormHTMLAttributes<HTMLFormElement>, "onSubmit" | "children"> {
18
+ /**
19
+ * Called with the values once every check passes. Return a promise to keep the form busy until it settles; if it
20
+ * rejects, the error's message shows in FormError ("That didn't work. Try again." when it has none). Without
21
+ * onSubmit, a valid form submits the usual way, to its `action`.
22
+ */
23
+ onSubmit?(values: FormValues, event: FormEvent<HTMLFormElement>): unknown;
24
+ /** Checks the values after the browser's own checks, for rules it can't express: return { [name]: message } for what's wrong. */
25
+ validate?(values: FormValues): FormErrors | void;
26
+ /** Errors from the server, by field name. Each shows under its field until the person changes that field. */
27
+ validationErrors?: FormErrors;
28
+ /** The fields and buttons, or a function of the form's status: ({ isSubmitting, errors }) => … */
29
+ children?: ReactNode | ((status: FormStatus) => ReactNode);
30
+ }
31
+ /** @internal What a Field tells its Form, so the Form can word its errors, focus it and tell which field lost focus. */
32
+ export interface FormFieldEntry {
33
+ name: string | undefined;
34
+ root: RefObject<HTMLElement>;
35
+ controlId: string;
36
+ errorMessages: ValidityMessages | undefined;
37
+ }
38
+ interface FormContextValue {
39
+ status: FormStatus;
40
+ formError: string | undefined;
41
+ register(entry: MutableRefObject<FormFieldEntry>): () => void;
42
+ changed(name: string): void;
43
+ addErrorSlot(): () => void;
44
+ }
45
+ /** @internal */
46
+ export declare const FormContext: import("react").Context<FormContextValue | null>;
47
+ /**
48
+ * A form that checks its fields before it submits. On submit it runs the browser's checks (required, type, minLength,
49
+ * pattern, min, max…), then `validate`, then any `validationErrors`; each message shows under its Field and focus goes to
50
+ * the first wrong field. Only when everything passes does it call onSubmit with the values.
51
+ */
52
+ export declare const Form: import("react").ForwardRefExoticComponent<FormProps & import("react").RefAttributes<HTMLFormElement>>;
53
+ export interface FormErrorProps {
54
+ className?: string;
55
+ }
56
+ /**
57
+ * Where a Form says why a submission failed: the message from a rejected onSubmit, in a danger Alert (role="alert").
58
+ * Put it just above the buttons. Without one, the Form shows the message at its end.
59
+ */
60
+ export declare function FormError({ className }: FormErrorProps): import("react").JSX.Element | null;
61
+ /** The status of the Form around a component, for a submit button that shows `loading` while it submits. */
62
+ export declare function useFormStatus(): FormStatus;
63
+ export {};
@@ -0,0 +1,63 @@
1
+ import { type FormEvent, type FormHTMLAttributes, type MutableRefObject, type ReactNode, type RefObject } from "react";
2
+ /** What onSubmit and validate get: each name in the form with its value, or a string[] when the name appears more than once. */
3
+ export type FormValues = Record<string, string | string[]>;
4
+ /** Messages by field name. */
5
+ export type FormErrors = Partial<Record<string, string>>;
6
+ /** The browser's own checks, by their ValidityState names. */
7
+ export type ValidityCheck = "valueMissing" | "typeMismatch" | "patternMismatch" | "tooShort" | "tooLong" | "rangeUnderflow" | "rangeOverflow" | "stepMismatch" | "badInput";
8
+ /** What to say when a browser check fails: one message for any of them, or one per check. */
9
+ export type ValidityMessages = string | Partial<Record<ValidityCheck, string>>;
10
+ /** What a Form tells the components inside it, through the render function or useFormStatus(). */
11
+ export interface FormStatus {
12
+ /** True while the promise onSubmit returned is pending. */
13
+ isSubmitting: boolean;
14
+ /** The errors showing now, by field name. */
15
+ errors: FormErrors;
16
+ }
17
+ export interface FormProps extends Omit<FormHTMLAttributes<HTMLFormElement>, "onSubmit" | "children"> {
18
+ /**
19
+ * Called with the values once every check passes. Return a promise to keep the form busy until it settles; if it
20
+ * rejects, the error's message shows in FormError ("That didn't work. Try again." when it has none). Without
21
+ * onSubmit, a valid form submits the usual way, to its `action`.
22
+ */
23
+ onSubmit?(values: FormValues, event: FormEvent<HTMLFormElement>): unknown;
24
+ /** Checks the values after the browser's own checks, for rules it can't express: return { [name]: message } for what's wrong. */
25
+ validate?(values: FormValues): FormErrors | void;
26
+ /** Errors from the server, by field name. Each shows under its field until the person changes that field. */
27
+ validationErrors?: FormErrors;
28
+ /** The fields and buttons, or a function of the form's status: ({ isSubmitting, errors }) => … */
29
+ children?: ReactNode | ((status: FormStatus) => ReactNode);
30
+ }
31
+ /** @internal What a Field tells its Form, so the Form can word its errors, focus it and tell which field lost focus. */
32
+ export interface FormFieldEntry {
33
+ name: string | undefined;
34
+ root: RefObject<HTMLElement>;
35
+ controlId: string;
36
+ errorMessages: ValidityMessages | undefined;
37
+ }
38
+ interface FormContextValue {
39
+ status: FormStatus;
40
+ formError: string | undefined;
41
+ register(entry: MutableRefObject<FormFieldEntry>): () => void;
42
+ changed(name: string): void;
43
+ addErrorSlot(): () => void;
44
+ }
45
+ /** @internal */
46
+ export declare const FormContext: import("react").Context<FormContextValue | null>;
47
+ /**
48
+ * A form that checks its fields before it submits. On submit it runs the browser's checks (required, type, minLength,
49
+ * pattern, min, max…), then `validate`, then any `validationErrors`; each message shows under its Field and focus goes to
50
+ * the first wrong field. Only when everything passes does it call onSubmit with the values.
51
+ */
52
+ export declare const Form: import("react").ForwardRefExoticComponent<FormProps & import("react").RefAttributes<HTMLFormElement>>;
53
+ export interface FormErrorProps {
54
+ className?: string;
55
+ }
56
+ /**
57
+ * Where a Form says why a submission failed: the message from a rejected onSubmit, in a danger Alert (role="alert").
58
+ * Put it just above the buttons. Without one, the Form shows the message at its end.
59
+ */
60
+ export declare function FormError({ className }: FormErrorProps): import("react").JSX.Element | null;
61
+ /** The status of the Form around a component, for a submit button that shows `loading` while it submits. */
62
+ export declare function useFormStatus(): FormStatus;
63
+ export {};
@@ -22,10 +22,16 @@ export interface InputOTPProps {
22
22
  "aria-label"?: string;
23
23
  /** The form field name; a hidden input carries the whole code. */
24
24
  name?: string;
25
+ /** Names the code by another element's id, in place of aria-label. */
26
+ "aria-labelledby"?: string;
27
+ /** Ids of the hint or error that describe it, read from every box; Field sets this. */
28
+ "aria-describedby"?: string;
29
+ /** The id of the first box, so a Field's label points at it and clicking the label starts there; Field sets this. */
30
+ id?: string;
25
31
  className?: string;
26
32
  }
27
33
  /**
28
34
  * A one-time code in separate boxes. Typing moves forward, Backspace moves back,
29
35
  * and pasting a code fills every box. The browser can fill it from a text message.
30
36
  */
31
- export declare function InputOTP({ length, value, defaultValue, onChange, onComplete, type, groupSize, isInvalid, disabled, autoFocus, "aria-label": ariaLabel, name, className, }: InputOTPProps): import("react").JSX.Element;
37
+ export declare function InputOTP({ length, value, defaultValue, onChange, onComplete, type, groupSize, isInvalid, disabled, autoFocus, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, id, name, className, }: InputOTPProps): import("react").JSX.Element;
@@ -22,10 +22,16 @@ export interface InputOTPProps {
22
22
  "aria-label"?: string;
23
23
  /** The form field name; a hidden input carries the whole code. */
24
24
  name?: string;
25
+ /** Names the code by another element's id, in place of aria-label. */
26
+ "aria-labelledby"?: string;
27
+ /** Ids of the hint or error that describe it, read from every box; Field sets this. */
28
+ "aria-describedby"?: string;
29
+ /** The id of the first box, so a Field's label points at it and clicking the label starts there; Field sets this. */
30
+ id?: string;
25
31
  className?: string;
26
32
  }
27
33
  /**
28
34
  * A one-time code in separate boxes. Typing moves forward, Backspace moves back,
29
35
  * and pasting a code fills every box. The browser can fill it from a text message.
30
36
  */
31
- export declare function InputOTP({ length, value, defaultValue, onChange, onComplete, type, groupSize, isInvalid, disabled, autoFocus, "aria-label": ariaLabel, name, className, }: InputOTPProps): import("react").JSX.Element;
37
+ export declare function InputOTP({ length, value, defaultValue, onChange, onComplete, type, groupSize, isInvalid, disabled, autoFocus, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, id, name, className, }: InputOTPProps): import("react").JSX.Element;
@@ -0,0 +1,65 @@
1
+ import { type ReactElement, type ReactNode, type RefAttributes } from "react";
2
+ import type { SelectOption } from "../Select/Select.cjs";
3
+ /** An option, shaped like Select's, with an optional icon. */
4
+ export interface ListBoxOption extends SelectOption {
5
+ /** A 16px icon between the checkmark and the label. */
6
+ icon?: ReactNode;
7
+ /** Plain text for type-to-find, when `label` isn't a string. */
8
+ textValue?: string;
9
+ }
10
+ /** Options under a heading, like a Select's groups. */
11
+ export interface ListBoxGroup {
12
+ /** The heading, shown in uppercase above the options and read out as the group's name. */
13
+ label: string;
14
+ options: ListBoxOption[];
15
+ }
16
+ export type ListBoxItem = ListBoxOption | ListBoxGroup;
17
+ export type ListBoxSelectionMode = "single" | "multiple";
18
+ /** ListBox's props for one selection mode: `value` is a string in single mode and an array in multiple mode. */
19
+ export interface ListBoxModeProps<Mode extends ListBoxSelectionMode> {
20
+ /** The options, and groups of options under a heading. */
21
+ options: ListBoxItem[];
22
+ /** `single` chooses one option; `multiple` any number.
23
+ * @default "single" */
24
+ selectionMode?: Mode;
25
+ /** The selected option's value in single mode ("" for none), or the selected values in multiple mode. */
26
+ value?: Mode extends "multiple" ? string[] : string;
27
+ /** The starting value when uncontrolled.
28
+ * @default "" or [] */
29
+ defaultValue?: Mode extends "multiple" ? string[] : string;
30
+ /** Called with the new value: a string in single mode, the selected values in the options' order in multiple mode. */
31
+ onChange?(value: Mode extends "multiple" ? string[] : string): void;
32
+ /** Keeps at least one option selected: choosing the selected option again doesn't clear it.
33
+ * @default false */
34
+ disallowEmptySelection?: boolean;
35
+ /** Shown in the list when there are no options.
36
+ * @default "No options" */
37
+ emptyMessage?: ReactNode;
38
+ /** Scrolls the options past this height, e.g. 240 or "40vh". */
39
+ maxHeight?: number | string;
40
+ /** md rows are 36px; sm rows are 32px with 12px text, like a small Select's list.
41
+ * @default "md" */
42
+ size?: "sm" | "md";
43
+ /** Shows the list as wrong: a red border, and a red halo when focused. Also sets aria-invalid. Field passes it.
44
+ * @default false */
45
+ isInvalid?: boolean;
46
+ /** The options can be moved through and read, but the selection can't change.
47
+ * @default false */
48
+ isReadOnly?: boolean;
49
+ /** Fades the list and takes it out of the tab order.
50
+ * @default false */
51
+ disabled?: boolean;
52
+ id?: string;
53
+ /** Names the list for screen readers when it isn't in a Field. */
54
+ "aria-label"?: string;
55
+ "aria-labelledby"?: string;
56
+ "aria-describedby"?: string;
57
+ className?: string;
58
+ }
59
+ /** ListBox's props. `value`, `defaultValue` and `onChange` take a string in single mode and an array in multiple mode. */
60
+ export interface ListBoxProps extends ListBoxModeProps<ListBoxSelectionMode> {
61
+ }
62
+ /**
63
+ * Select's list of options on its own: a choice that stays on the page. `selectionMode="multiple"` makes `value` an array.
64
+ */
65
+ export declare const ListBox: <Mode extends ListBoxSelectionMode = "single">(props: ListBoxModeProps<Mode> & RefAttributes<HTMLDivElement>) => ReactElement | null;
@@ -0,0 +1,65 @@
1
+ import { type ReactElement, type ReactNode, type RefAttributes } from "react";
2
+ import type { SelectOption } from "../Select/Select.js";
3
+ /** An option, shaped like Select's, with an optional icon. */
4
+ export interface ListBoxOption extends SelectOption {
5
+ /** A 16px icon between the checkmark and the label. */
6
+ icon?: ReactNode;
7
+ /** Plain text for type-to-find, when `label` isn't a string. */
8
+ textValue?: string;
9
+ }
10
+ /** Options under a heading, like a Select's groups. */
11
+ export interface ListBoxGroup {
12
+ /** The heading, shown in uppercase above the options and read out as the group's name. */
13
+ label: string;
14
+ options: ListBoxOption[];
15
+ }
16
+ export type ListBoxItem = ListBoxOption | ListBoxGroup;
17
+ export type ListBoxSelectionMode = "single" | "multiple";
18
+ /** ListBox's props for one selection mode: `value` is a string in single mode and an array in multiple mode. */
19
+ export interface ListBoxModeProps<Mode extends ListBoxSelectionMode> {
20
+ /** The options, and groups of options under a heading. */
21
+ options: ListBoxItem[];
22
+ /** `single` chooses one option; `multiple` any number.
23
+ * @default "single" */
24
+ selectionMode?: Mode;
25
+ /** The selected option's value in single mode ("" for none), or the selected values in multiple mode. */
26
+ value?: Mode extends "multiple" ? string[] : string;
27
+ /** The starting value when uncontrolled.
28
+ * @default "" or [] */
29
+ defaultValue?: Mode extends "multiple" ? string[] : string;
30
+ /** Called with the new value: a string in single mode, the selected values in the options' order in multiple mode. */
31
+ onChange?(value: Mode extends "multiple" ? string[] : string): void;
32
+ /** Keeps at least one option selected: choosing the selected option again doesn't clear it.
33
+ * @default false */
34
+ disallowEmptySelection?: boolean;
35
+ /** Shown in the list when there are no options.
36
+ * @default "No options" */
37
+ emptyMessage?: ReactNode;
38
+ /** Scrolls the options past this height, e.g. 240 or "40vh". */
39
+ maxHeight?: number | string;
40
+ /** md rows are 36px; sm rows are 32px with 12px text, like a small Select's list.
41
+ * @default "md" */
42
+ size?: "sm" | "md";
43
+ /** Shows the list as wrong: a red border, and a red halo when focused. Also sets aria-invalid. Field passes it.
44
+ * @default false */
45
+ isInvalid?: boolean;
46
+ /** The options can be moved through and read, but the selection can't change.
47
+ * @default false */
48
+ isReadOnly?: boolean;
49
+ /** Fades the list and takes it out of the tab order.
50
+ * @default false */
51
+ disabled?: boolean;
52
+ id?: string;
53
+ /** Names the list for screen readers when it isn't in a Field. */
54
+ "aria-label"?: string;
55
+ "aria-labelledby"?: string;
56
+ "aria-describedby"?: string;
57
+ className?: string;
58
+ }
59
+ /** ListBox's props. `value`, `defaultValue` and `onChange` take a string in single mode and an array in multiple mode. */
60
+ export interface ListBoxProps extends ListBoxModeProps<ListBoxSelectionMode> {
61
+ }
62
+ /**
63
+ * Select's list of options on its own: a choice that stays on the page. `selectionMode="multiple"` makes `value` an array.
64
+ */
65
+ export declare const ListBox: <Mode extends ListBoxSelectionMode = "single">(props: ListBoxModeProps<Mode> & RefAttributes<HTMLDivElement>) => ReactElement | null;
@@ -0,0 +1,62 @@
1
+ import { type ReactNode } from "react";
2
+ import type { ProgressTone } from "../Progress/Progress.cjs";
3
+ export interface MeterProps {
4
+ /** The amount measured, from min to max. */
5
+ value: number;
6
+ /** @default 0 */
7
+ min?: number;
8
+ /** @default 100 */
9
+ max?: number;
10
+ /** Shown above the bar, and names it for screen readers. */
11
+ label?: ReactNode;
12
+ /** Shows the value label at the right of the label.
13
+ * @default true */
14
+ showValue?: boolean;
15
+ /**
16
+ * The text shown and read out for the value: a string ("Strong"), or a function given the value, min and max
17
+ * formatted with `formatOptions`, such as `({ value, max }) => \`${value} of ${max}\``. Defaults to the formatted value.
18
+ */
19
+ valueLabel?: string | ((formatted: {
20
+ value: string;
21
+ min: string;
22
+ max: string;
23
+ }) => string);
24
+ /**
25
+ * How the value is written, as Intl.NumberFormat options. The percent style shows where the value sits in the range;
26
+ * any other formats the value itself, such as `{ style: "unit", unit: "gigabyte" }`.
27
+ * @default { style: "percent" }
28
+ */
29
+ formatOptions?: Intl.NumberFormatOptions;
30
+ /** The locale numbers are written in, such as "de-CH". Defaults to the browser's. */
31
+ locale?: string;
32
+ /** The fill's colour. Leave it out to work it out from `low`, `high` and `optimum`; with none of those, it's primary. */
33
+ tone?: ProgressTone;
34
+ /** Values below this are in the low range, as on the meter element.
35
+ * @default min */
36
+ low?: number;
37
+ /** Values above this are in the high range.
38
+ * @default max */
39
+ high?: number;
40
+ /**
41
+ * The best value. The range it's in is good (success), the middle range otherwise middling (warning), and the range
42
+ * at the far end bad (danger). With optimum between low and high, both outer ranges are middling.
43
+ * @default halfway between min and max
44
+ */
45
+ optimum?: number;
46
+ /** sm is 4px; md is 8px.
47
+ * @default "sm" */
48
+ size?: "sm" | "md";
49
+ /** Draws the bar as this many separate blocks, such as 4 for a password's strength. */
50
+ segments?: number;
51
+ id?: string;
52
+ /** Names the meter for screen readers when there's no `label`. */
53
+ "aria-label"?: string;
54
+ "aria-labelledby"?: string;
55
+ "aria-describedby"?: string;
56
+ className?: string;
57
+ }
58
+ /**
59
+ * An amount within a known range: storage used, runs against a plan's limit, a password's strength. Unlike ProgressBar,
60
+ * it doesn't mean something will finish.
61
+ */
62
+ export declare function Meter({ value, min, max, label, showValue, valueLabel, formatOptions, locale, tone, low, high, optimum, size, segments, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, className, }: MeterProps): import("react").JSX.Element;
@@ -0,0 +1,62 @@
1
+ import { type ReactNode } from "react";
2
+ import type { ProgressTone } from "../Progress/Progress.js";
3
+ export interface MeterProps {
4
+ /** The amount measured, from min to max. */
5
+ value: number;
6
+ /** @default 0 */
7
+ min?: number;
8
+ /** @default 100 */
9
+ max?: number;
10
+ /** Shown above the bar, and names it for screen readers. */
11
+ label?: ReactNode;
12
+ /** Shows the value label at the right of the label.
13
+ * @default true */
14
+ showValue?: boolean;
15
+ /**
16
+ * The text shown and read out for the value: a string ("Strong"), or a function given the value, min and max
17
+ * formatted with `formatOptions`, such as `({ value, max }) => \`${value} of ${max}\``. Defaults to the formatted value.
18
+ */
19
+ valueLabel?: string | ((formatted: {
20
+ value: string;
21
+ min: string;
22
+ max: string;
23
+ }) => string);
24
+ /**
25
+ * How the value is written, as Intl.NumberFormat options. The percent style shows where the value sits in the range;
26
+ * any other formats the value itself, such as `{ style: "unit", unit: "gigabyte" }`.
27
+ * @default { style: "percent" }
28
+ */
29
+ formatOptions?: Intl.NumberFormatOptions;
30
+ /** The locale numbers are written in, such as "de-CH". Defaults to the browser's. */
31
+ locale?: string;
32
+ /** The fill's colour. Leave it out to work it out from `low`, `high` and `optimum`; with none of those, it's primary. */
33
+ tone?: ProgressTone;
34
+ /** Values below this are in the low range, as on the meter element.
35
+ * @default min */
36
+ low?: number;
37
+ /** Values above this are in the high range.
38
+ * @default max */
39
+ high?: number;
40
+ /**
41
+ * The best value. The range it's in is good (success), the middle range otherwise middling (warning), and the range
42
+ * at the far end bad (danger). With optimum between low and high, both outer ranges are middling.
43
+ * @default halfway between min and max
44
+ */
45
+ optimum?: number;
46
+ /** sm is 4px; md is 8px.
47
+ * @default "sm" */
48
+ size?: "sm" | "md";
49
+ /** Draws the bar as this many separate blocks, such as 4 for a password's strength. */
50
+ segments?: number;
51
+ id?: string;
52
+ /** Names the meter for screen readers when there's no `label`. */
53
+ "aria-label"?: string;
54
+ "aria-labelledby"?: string;
55
+ "aria-describedby"?: string;
56
+ className?: string;
57
+ }
58
+ /**
59
+ * An amount within a known range: storage used, runs against a plan's limit, a password's strength. Unlike ProgressBar,
60
+ * it doesn't mean something will finish.
61
+ */
62
+ export declare function Meter({ value, min, max, label, showValue, valueLabel, formatOptions, locale, tone, low, high, optimum, size, segments, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, className, }: MeterProps): import("react").JSX.Element;
@@ -0,0 +1,95 @@
1
+ import { type KeyboardEvent, type ReactNode } from "react";
2
+ /** A file attached to the message, shown as a chip above the text. */
3
+ export interface PromptAttachment {
4
+ /** Identifies it to onRemoveAttachment, and keys its chip. */
5
+ id: string;
6
+ /** The file name, shown on the chip (a long one is cut short before its extension) and read out by its remove button. */
7
+ name: string;
8
+ /** Bytes, shown under the name: "48 kB". */
9
+ size?: number;
10
+ /** The MIME type, such as "image/png". With the name, it picks the chip's icon when there's no preview. */
11
+ type?: string;
12
+ /** An image to show as the chip's thumbnail: an object URL from URL.createObjectURL, or any image URL. */
13
+ previewUrl?: string;
14
+ }
15
+ export interface PromptInputProps {
16
+ /** The text, when controlled. Clear it yourself in onSubmit. */
17
+ value?: string;
18
+ /** The starting text when uncontrolled. The box clears itself after each send.
19
+ * @default "" */
20
+ defaultValue?: string;
21
+ /** Called with the text on every change. */
22
+ onChange?(value: string): void;
23
+ /**
24
+ * Called on Enter or the send button with the text (trimmed) and the attachments. It isn't called while there's
25
+ * nothing to send (no text and no attachments), while streaming, or while disabled.
26
+ */
27
+ onSubmit?(value: string, attachments: PromptAttachment[]): void;
28
+ /** The agent is replying: the send button becomes a Stop button and Escape in the box stops it. The next message can
29
+ * be typed meanwhile, but not sent.
30
+ * @default false */
31
+ isStreaming?: boolean;
32
+ /** Called by the Stop button, and by Escape in the box, while streaming. */
33
+ onStop?(): void;
34
+ /** The files attached so far, as chips above the text. You keep the list: add to it in onAttach and take from it in
35
+ * onRemoveAttachment. */
36
+ attachments?: PromptAttachment[];
37
+ /** Called with the files picked with the paperclip, pasted, or dropped on the box. Giving it shows the paperclip. */
38
+ onAttach?(files: File[]): void;
39
+ /** Called with an attachment's id when its remove button is pressed. Giving it shows the remove buttons. */
40
+ onRemoveAttachment?(id: string): void;
41
+ /** File types to accept, as for <input accept>: "image/*,.log,.txt". Other files are turned away with a message. */
42
+ accept?: string;
43
+ /** Lets several files be attached at once.
44
+ * @default true */
45
+ multiple?: boolean;
46
+ /** Controls at the start of the toolbar under the text, after the paperclip: a model Select, a toggle. Buttons here
47
+ * should be size sm. */
48
+ startActions?: ReactNode;
49
+ /** Controls at the end of the toolbar, before the send button. */
50
+ endActions?: ReactNode;
51
+ /** A muted line under the box, such as how to send: "Enter to send, Shift + Enter for a new line". The text box
52
+ * points to it with aria-describedby. */
53
+ hint?: ReactNode;
54
+ /** @default "Message the agent…" */
55
+ placeholder?: string;
56
+ /** Names the text box for screen readers. It's "Message" unless something else labels it: aria-labelledby, or an id
57
+ * that a <label> points to, as in a Field. */
58
+ "aria-label"?: string;
59
+ "aria-labelledby"?: string;
60
+ "aria-describedby"?: string;
61
+ /** The text box's id. Field sets it. */
62
+ id?: string;
63
+ /** Marks the box invalid: a danger border, and aria-invalid on the text box. Field sets it from its error.
64
+ * @default false */
65
+ isInvalid?: boolean;
66
+ /** Turns off the text box, its buttons and the controls in the toolbar, and fades the box.
67
+ * @default false */
68
+ disabled?: boolean;
69
+ /** Focuses the text box when it appears. Use it where typing is plainly the next step, such as a new chat.
70
+ * @default false */
71
+ autoFocus?: boolean;
72
+ /** The most characters the text can have. A quiet count shows once it's 80% full. */
73
+ maxLength?: number;
74
+ /** The rows of text the box shows when it's empty.
75
+ * @default 1 */
76
+ minRows?: number;
77
+ /** The most rows it grows to; past that, the text scrolls.
78
+ * @default 8 */
79
+ maxRows?: number;
80
+ /** md for a chat page, sm for a side panel or a reply box.
81
+ * @default "md" */
82
+ size?: "sm" | "md";
83
+ /** The locale for attachment sizes and the character count, such as "de-CH". Defaults to the browser's. */
84
+ locale?: string;
85
+ /** Called for each key in the text box before the box's own keys. Call event.preventDefault() to take a key over, for
86
+ * example the Up arrow to edit the last message. */
87
+ onKeyDown?(event: KeyboardEvent<HTMLTextAreaElement>): void;
88
+ /** Classes for the outer element, which holds the box and the hint. */
89
+ className?: string;
90
+ }
91
+ /**
92
+ * The box you write to the agent in. Enter sends and Shift+Enter starts a new line; it grows with the text, takes files
93
+ * from a picker, the clipboard or a drop, and turns its send button into Stop while the agent replies.
94
+ */
95
+ export declare const PromptInput: import("react").ForwardRefExoticComponent<PromptInputProps & import("react").RefAttributes<HTMLTextAreaElement>>;