@openwarelabs/ui 0.3.0 → 0.4.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 (51) hide show
  1. package/README.md +9 -8
  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/ColorPicker/ColorArea.d.cts +44 -0
  11. package/dist/components/ColorPicker/ColorArea.d.ts +44 -0
  12. package/dist/components/ColorPicker/ColorSlider.d.cts +53 -0
  13. package/dist/components/ColorPicker/ColorSlider.d.ts +53 -0
  14. package/dist/components/ColorPicker/ColorSwatchPicker.d.cts +43 -0
  15. package/dist/components/ColorPicker/ColorSwatchPicker.d.ts +43 -0
  16. package/dist/components/ColorPicker/color.d.cts +91 -0
  17. package/dist/components/ColorPicker/color.d.ts +91 -0
  18. package/dist/components/DateField/DateField.d.cts +47 -0
  19. package/dist/components/DateField/DateField.d.ts +47 -0
  20. package/dist/components/DateField/SegmentedField.d.cts +63 -0
  21. package/dist/components/DateField/SegmentedField.d.ts +63 -0
  22. package/dist/components/DateField/TimeField.d.cts +52 -0
  23. package/dist/components/DateField/TimeField.d.ts +52 -0
  24. package/dist/components/Field/Field.d.cts +17 -5
  25. package/dist/components/Field/Field.d.ts +17 -5
  26. package/dist/components/FileDropZone/FileDropZone.d.cts +1 -1
  27. package/dist/components/FileDropZone/FileDropZone.d.ts +1 -1
  28. package/dist/components/Form/Form.d.cts +63 -0
  29. package/dist/components/Form/Form.d.ts +63 -0
  30. package/dist/components/InputOTP/InputOTP.d.cts +7 -1
  31. package/dist/components/InputOTP/InputOTP.d.ts +7 -1
  32. package/dist/components/ListBox/ListBox.d.cts +65 -0
  33. package/dist/components/ListBox/ListBox.d.ts +65 -0
  34. package/dist/components/Meter/Meter.d.cts +62 -0
  35. package/dist/components/Meter/Meter.d.ts +62 -0
  36. package/dist/components/Slider/Slider.d.cts +7 -1
  37. package/dist/components/Slider/Slider.d.ts +7 -1
  38. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.d.cts +74 -0
  39. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.d.ts +74 -0
  40. package/dist/components/Toolbar/Toolbar.d.cts +36 -0
  41. package/dist/components/Toolbar/Toolbar.d.ts +36 -0
  42. package/dist/components.css +1007 -12
  43. package/dist/index.cjs +3999 -1261
  44. package/dist/index.cjs.map +4 -4
  45. package/dist/index.d.cts +25 -0
  46. package/dist/index.d.ts +25 -0
  47. package/dist/index.js +3955 -1191
  48. package/dist/index.js.map +4 -4
  49. package/dist/openware-ui.iife.js +6 -6
  50. package/dist/styles.css +1007 -12
  51. package/package.json +1 -1
@@ -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;
@@ -22,6 +22,12 @@ export interface SliderProps<V extends SliderValue = number> {
22
22
  formatValue?(value: number): string;
23
23
  /** Names the slider when there's no visible label. */
24
24
  "aria-label"?: string;
25
+ /** Names the slider by another element's id, such as a Field's label. */
26
+ "aria-labelledby"?: string;
27
+ /** Ids of the hint or error that describe it; Field sets this. */
28
+ "aria-describedby"?: string;
29
+ /** The id of the (first) handle's input, so a Field's label points at it; Field sets this. */
30
+ id?: string;
25
31
  disabled?: boolean;
26
32
  className?: string;
27
33
  }
@@ -29,5 +35,5 @@ export interface SliderProps<V extends SliderValue = number> {
29
35
  * Picks a number, or a range, by dragging. It's built on native range inputs, so the arrow keys,
30
36
  * PageUp, PageDown, Home and End work as people expect.
31
37
  */
32
- export declare function Slider<V extends SliderValue = number>({ value, defaultValue, onChange, onChangeEnd, min, max, step, label, showValue, formatValue, "aria-label": ariaLabel, disabled, className, }: SliderProps<V>): import("react").JSX.Element;
38
+ export declare function Slider<V extends SliderValue = number>({ value, defaultValue, onChange, onChangeEnd, min, max, step, label, showValue, formatValue, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, id, disabled, className, }: SliderProps<V>): import("react").JSX.Element;
33
39
  export {};
@@ -22,6 +22,12 @@ export interface SliderProps<V extends SliderValue = number> {
22
22
  formatValue?(value: number): string;
23
23
  /** Names the slider when there's no visible label. */
24
24
  "aria-label"?: string;
25
+ /** Names the slider by another element's id, such as a Field's label. */
26
+ "aria-labelledby"?: string;
27
+ /** Ids of the hint or error that describe it; Field sets this. */
28
+ "aria-describedby"?: string;
29
+ /** The id of the (first) handle's input, so a Field's label points at it; Field sets this. */
30
+ id?: string;
25
31
  disabled?: boolean;
26
32
  className?: string;
27
33
  }
@@ -29,5 +35,5 @@ export interface SliderProps<V extends SliderValue = number> {
29
35
  * Picks a number, or a range, by dragging. It's built on native range inputs, so the arrow keys,
30
36
  * PageUp, PageDown, Home and End work as people expect.
31
37
  */
32
- export declare function Slider<V extends SliderValue = number>({ value, defaultValue, onChange, onChangeEnd, min, max, step, label, showValue, formatValue, "aria-label": ariaLabel, disabled, className, }: SliderProps<V>): import("react").JSX.Element;
38
+ export declare function Slider<V extends SliderValue = number>({ value, defaultValue, onChange, onChangeEnd, min, max, step, label, showValue, formatValue, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, id, disabled, className, }: SliderProps<V>): import("react").JSX.Element;
33
39
  export {};
@@ -0,0 +1,74 @@
1
+ import { type ReactNode } from "react";
2
+ export interface ToggleButtonGroupOption {
3
+ /** Identifies the option in `value`. */
4
+ value: string;
5
+ /** The visible text. Leave it out for an icon-only option, and give that an aria-label. */
6
+ label?: ReactNode;
7
+ /** A 16px icon before the label, or on its own. */
8
+ icon?: ReactNode;
9
+ /** Names an icon-only option for screen readers; a tooltip shows the same words. */
10
+ "aria-label"?: string;
11
+ /** Greys the option out; the arrow keys skip it.
12
+ * @default false */
13
+ disabled?: boolean;
14
+ }
15
+ export interface ToggleButtonGroupProps {
16
+ /** The toggles, in order. */
17
+ options: ToggleButtonGroupOption[];
18
+ /** `multiple` lets any number be on, like bold and italic; `single` allows at most one, like an alignment.
19
+ * Either way all can be off, unless `disallowEmptySelection`.
20
+ * @default "single" */
21
+ selectionMode?: "single" | "multiple";
22
+ /** What's on: in single mode a value, or "" for none; in multiple mode an array of values. Leave it out to let the
23
+ * group keep its own state. */
24
+ value?: string | string[];
25
+ /** The starting value when uncontrolled.
26
+ * @default "" or [] */
27
+ defaultValue?: string | string[];
28
+ /** Called with the new value: a string ("" for none) in single mode, an array in the options' order in multiple mode. */
29
+ onChange?(value: string | string[]): void;
30
+ /** Keeps one option on: pressing the only one that's on leaves it on.
31
+ * @default false */
32
+ disallowEmptySelection?: boolean;
33
+ /** sm 32px, md 40px tall, like Button. Inside a Toolbar it takes the toolbar's size.
34
+ * @default "md" */
35
+ size?: "sm" | "md";
36
+ /** Inside a Toolbar it takes the toolbar's orientation.
37
+ * @default "horizontal" */
38
+ orientation?: "horizontal" | "vertical";
39
+ /** Disables every option, keeping what's on visible.
40
+ * @default false */
41
+ disabled?: boolean;
42
+ /** Names the group for screen readers, e.g. "Text style". */
43
+ "aria-label"?: string;
44
+ /** The id of a visible label for the group, in place of aria-label. */
45
+ "aria-labelledby"?: string;
46
+ /** The id of a hint or description for the group. */
47
+ "aria-describedby"?: string;
48
+ /** An id for the group's element. */
49
+ id?: string;
50
+ /** Extra classes for the group. */
51
+ className?: string;
52
+ }
53
+ type SharedProps = Omit<ToggleButtonGroupProps, "selectionMode" | "value" | "defaultValue" | "onChange">;
54
+ /** The props in single mode: `value` is one option's value, or "" when none is on. */
55
+ export type ToggleButtonGroupSingleProps = SharedProps & {
56
+ selectionMode?: "single";
57
+ value?: string;
58
+ defaultValue?: string;
59
+ onChange?(value: string): void;
60
+ };
61
+ /** The props in multiple mode: `value` is the values of the options that are on. */
62
+ export type ToggleButtonGroupMultipleProps = SharedProps & {
63
+ selectionMode: "multiple";
64
+ value?: string[];
65
+ defaultValue?: string[];
66
+ onChange?(value: string[]): void;
67
+ };
68
+ /**
69
+ * Toggle buttons joined into one control: several can be on (bold, italic, underline) or at most one (an alignment),
70
+ * and, unlike a SegmentedControl, all can be off. On its own it's one tab stop with the arrow keys moving between its
71
+ * buttons; inside a Toolbar it leaves the arrow keys to the toolbar.
72
+ */
73
+ export declare function ToggleButtonGroup(props: ToggleButtonGroupSingleProps | ToggleButtonGroupMultipleProps): import("react").JSX.Element;
74
+ export {};
@@ -0,0 +1,74 @@
1
+ import { type ReactNode } from "react";
2
+ export interface ToggleButtonGroupOption {
3
+ /** Identifies the option in `value`. */
4
+ value: string;
5
+ /** The visible text. Leave it out for an icon-only option, and give that an aria-label. */
6
+ label?: ReactNode;
7
+ /** A 16px icon before the label, or on its own. */
8
+ icon?: ReactNode;
9
+ /** Names an icon-only option for screen readers; a tooltip shows the same words. */
10
+ "aria-label"?: string;
11
+ /** Greys the option out; the arrow keys skip it.
12
+ * @default false */
13
+ disabled?: boolean;
14
+ }
15
+ export interface ToggleButtonGroupProps {
16
+ /** The toggles, in order. */
17
+ options: ToggleButtonGroupOption[];
18
+ /** `multiple` lets any number be on, like bold and italic; `single` allows at most one, like an alignment.
19
+ * Either way all can be off, unless `disallowEmptySelection`.
20
+ * @default "single" */
21
+ selectionMode?: "single" | "multiple";
22
+ /** What's on: in single mode a value, or "" for none; in multiple mode an array of values. Leave it out to let the
23
+ * group keep its own state. */
24
+ value?: string | string[];
25
+ /** The starting value when uncontrolled.
26
+ * @default "" or [] */
27
+ defaultValue?: string | string[];
28
+ /** Called with the new value: a string ("" for none) in single mode, an array in the options' order in multiple mode. */
29
+ onChange?(value: string | string[]): void;
30
+ /** Keeps one option on: pressing the only one that's on leaves it on.
31
+ * @default false */
32
+ disallowEmptySelection?: boolean;
33
+ /** sm 32px, md 40px tall, like Button. Inside a Toolbar it takes the toolbar's size.
34
+ * @default "md" */
35
+ size?: "sm" | "md";
36
+ /** Inside a Toolbar it takes the toolbar's orientation.
37
+ * @default "horizontal" */
38
+ orientation?: "horizontal" | "vertical";
39
+ /** Disables every option, keeping what's on visible.
40
+ * @default false */
41
+ disabled?: boolean;
42
+ /** Names the group for screen readers, e.g. "Text style". */
43
+ "aria-label"?: string;
44
+ /** The id of a visible label for the group, in place of aria-label. */
45
+ "aria-labelledby"?: string;
46
+ /** The id of a hint or description for the group. */
47
+ "aria-describedby"?: string;
48
+ /** An id for the group's element. */
49
+ id?: string;
50
+ /** Extra classes for the group. */
51
+ className?: string;
52
+ }
53
+ type SharedProps = Omit<ToggleButtonGroupProps, "selectionMode" | "value" | "defaultValue" | "onChange">;
54
+ /** The props in single mode: `value` is one option's value, or "" when none is on. */
55
+ export type ToggleButtonGroupSingleProps = SharedProps & {
56
+ selectionMode?: "single";
57
+ value?: string;
58
+ defaultValue?: string;
59
+ onChange?(value: string): void;
60
+ };
61
+ /** The props in multiple mode: `value` is the values of the options that are on. */
62
+ export type ToggleButtonGroupMultipleProps = SharedProps & {
63
+ selectionMode: "multiple";
64
+ value?: string[];
65
+ defaultValue?: string[];
66
+ onChange?(value: string[]): void;
67
+ };
68
+ /**
69
+ * Toggle buttons joined into one control: several can be on (bold, italic, underline) or at most one (an alignment),
70
+ * and, unlike a SegmentedControl, all can be off. On its own it's one tab stop with the arrow keys moving between its
71
+ * buttons; inside a Toolbar it leaves the arrow keys to the toolbar.
72
+ */
73
+ export declare function ToggleButtonGroup(props: ToggleButtonGroupSingleProps | ToggleButtonGroupMultipleProps): import("react").JSX.Element;
74
+ export {};
@@ -0,0 +1,36 @@
1
+ import { type HTMLAttributes } from "react";
2
+ export interface ToolbarProps extends HTMLAttributes<HTMLDivElement> {
3
+ /** Names the toolbar for screen readers, e.g. "Formatting". Every toolbar needs a name, from this or aria-labelledby. */
4
+ "aria-label"?: string;
5
+ /** The id of a visible heading that names the toolbar, in place of aria-label. */
6
+ "aria-labelledby"?: string;
7
+ /** Which way it runs. The arrow keys follow it: Left and Right across a horizontal toolbar, Up and Down a vertical one.
8
+ * @default "horizontal" */
9
+ orientation?: "horizontal" | "vertical";
10
+ /** `raised` is a bar of its own: a surface with a hairline border and a soft shadow. `plain` has no ground, for a
11
+ * toolbar in a card or panel header.
12
+ * @default "raised" */
13
+ variant?: "raised" | "plain";
14
+ /** The bar's padding and gaps, and the size its ToggleButtonGroups and separators take. Give its Buttons the same size.
15
+ * @default "md" */
16
+ size?: "sm" | "md";
17
+ }
18
+ export interface ToolbarSeparatorProps {
19
+ /** Extra classes for the line. */
20
+ className?: string;
21
+ }
22
+ interface ToolbarContextValue {
23
+ orientation: "horizontal" | "vertical";
24
+ size: "sm" | "md";
25
+ }
26
+ /** Lets what's inside a Toolbar follow its orientation and size, and leave the arrow keys to it. */
27
+ export declare const ToolbarContext: import("react").Context<ToolbarContextValue | null>;
28
+ /**
29
+ * A row of controls for one context: an editor's formatting bar, a table's actions. It's a single tab stop: the
30
+ * arrow keys move between every control inside it, ToggleButtonGroups' buttons included, and Tab leaves it, coming
31
+ * back to the control that was focused last.
32
+ */
33
+ export declare const Toolbar: import("react").ForwardRefExoticComponent<ToolbarProps & import("react").RefAttributes<HTMLDivElement>>;
34
+ /** A line between groups of controls in a Toolbar, across the toolbar's direction. */
35
+ export declare function ToolbarSeparator({ className }: ToolbarSeparatorProps): import("react").JSX.Element;
36
+ export {};