@allxsmith/bestax-bulma 5.26.4 → 5.26.6

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 (45) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/extras.css +1 -1
  4. package/dist/extras.css.map +1 -1
  5. package/dist/index.cjs +445 -55
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.esm.js +445 -55
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/types/form/Autocomplete.d.ts +6 -1
  10. package/dist/types/form/DateInput.d.ts +8 -4
  11. package/dist/types/form/DateTimeInput.d.ts +8 -4
  12. package/dist/types/form/FormContext.d.ts +47 -0
  13. package/dist/types/form/Input.d.ts +4 -3
  14. package/dist/types/form/Numberinput.d.ts +11 -1
  15. package/dist/types/form/Select.d.ts +4 -3
  16. package/dist/types/form/TextArea.d.ts +4 -3
  17. package/dist/types/form/TimeInput.d.ts +8 -4
  18. package/dist/types/form/_pickerInternals/Calendar.d.ts +45 -4
  19. package/dist/types/form/_pickerInternals/dateUtils.d.ts +17 -0
  20. package/dist/types/form/_pickerInternals/pickerTypes.d.ts +14 -0
  21. package/dist/types/helpers/statusRegion.d.ts +1 -0
  22. package/dist/types-cjs/form/Autocomplete.d.ts +6 -1
  23. package/dist/types-cjs/form/DateInput.d.ts +8 -4
  24. package/dist/types-cjs/form/DateTimeInput.d.ts +8 -4
  25. package/dist/types-cjs/form/FormContext.d.ts +47 -0
  26. package/dist/types-cjs/form/Input.d.ts +4 -3
  27. package/dist/types-cjs/form/Numberinput.d.ts +11 -1
  28. package/dist/types-cjs/form/Select.d.ts +4 -3
  29. package/dist/types-cjs/form/TextArea.d.ts +4 -3
  30. package/dist/types-cjs/form/TimeInput.d.ts +8 -4
  31. package/dist/types-cjs/form/_pickerInternals/Calendar.d.ts +45 -4
  32. package/dist/types-cjs/form/_pickerInternals/dateUtils.d.ts +17 -0
  33. package/dist/types-cjs/form/_pickerInternals/pickerTypes.d.ts +14 -0
  34. package/dist/types-cjs/helpers/statusRegion.d.ts +1 -0
  35. package/dist/versions/bestax-no-dark-mode.css +1 -1
  36. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  37. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  38. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  39. package/dist/versions/bestax-no-helpers.css +1 -1
  40. package/dist/versions/bestax-no-helpers.css.map +1 -1
  41. package/dist/versions/bestax-prefixed.css +1 -1
  42. package/dist/versions/bestax-prefixed.css.map +1 -1
  43. package/package.json +1 -1
  44. package/src/scss/form/_dateinput.scss +8 -1
  45. package/src/scss/form/_taginput.scss +8 -0
@@ -37,7 +37,12 @@ export interface AutocompleteProps extends Omit<React.HTMLAttributes<HTMLDivElem
37
37
  placeholder?: string;
38
38
  /** Object property to use as the display field. */
39
39
  field?: string;
40
- /** Whether to show a clear button. */
40
+ /**
41
+ * Whether to show a clear button while the input holds a value.
42
+ * It hides while the input is disabled, and gives way to a loading
43
+ * spinner at the same right edge: the one `loading` draws, or that of a
44
+ * `Control` with `isLoading` around the Autocomplete.
45
+ */
41
46
  clearable?: boolean;
42
47
  /** Open dropdown when input is focused. */
43
48
  openOnFocus?: boolean;
@@ -5,9 +5,12 @@ import { DateInputBaseProps } from './DateInputBase.js';
5
5
  /**
6
6
  * Props for the DateInput convenience wrapper. Extends `DateInputBaseProps`
7
7
  * with Field-level (label, horizontal) and Control-level (icons, loading) props.
8
- * Inside an existing `Control` it renders no `Control` of its own, so set the
9
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
10
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
8
+ * Inside an existing `Control` it renders no `Control` of its own, so its
9
+ * Control-level props do nothing there and warn in development; set them on
10
+ * that `Control` instead. In `inline` mode it renders no `Control` anywhere,
11
+ * so they do nothing inside a `Control` or out, and warn in development
12
+ * there too. Inside an outer `Field`, or a `Control` with no `Field` around
13
+ * it, it renders no `Field` of its own either.
11
14
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
12
15
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
13
16
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -52,7 +55,8 @@ export interface DateInputProps extends DateInputBaseProps {
52
55
  /**
53
56
  * Shows a loading spinner on the `Control` it renders, and hides the
54
57
  * launcher (`triggerIcon`) while it does. Inside your own `Control` it
55
- * renders none, so this draws nothing; set `isLoading` on that `Control`.
58
+ * renders none, so this draws nothing and warns in development; set
59
+ * `isLoading` on that `Control`.
56
60
  * Under `prefers-reduced-motion: reduce` the spinner stops and stays
57
61
  * drawn (with bestax's CSS loaded).
58
62
  */
@@ -5,9 +5,12 @@ import { DateTimeInputBaseProps } from './DateTimeInputBase.js';
5
5
  /**
6
6
  * Props for the DateTimeInput convenience wrapper. Extends
7
7
  * `DateTimeInputBaseProps` with Field-level and Control-level props.
8
- * Inside an existing `Control` it renders no `Control` of its own, so set the
9
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
10
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
8
+ * Inside an existing `Control` it renders no `Control` of its own, so its
9
+ * Control-level props do nothing there and warn in development; set them on
10
+ * that `Control` instead. In `inline` mode it renders no `Control` anywhere,
11
+ * so they do nothing inside a `Control` or out, and warn in development
12
+ * there too. Inside an outer `Field`, or a `Control` with no `Field` around
13
+ * it, it renders no `Field` of its own either.
11
14
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
12
15
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
13
16
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -50,7 +53,8 @@ export interface DateTimeInputProps extends DateTimeInputBaseProps {
50
53
  /**
51
54
  * Shows a loading spinner on the `Control` it renders, and hides the
52
55
  * launcher (`triggerIcon`) while it does. Inside your own `Control` it
53
- * renders none, so this draws nothing; set `isLoading` on that `Control`.
56
+ * renders none, so this draws nothing and warns in development; set
57
+ * `isLoading` on that `Control`.
54
58
  * Under `prefers-reduced-motion: reduce` the spinner stops and stays
55
59
  * drawn (with bestax's CSS loaded).
56
60
  */
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { ControlBaseProps } from './Control.js';
2
3
  /**
3
4
  * Hook to detect if the component is inside a Field wrapper.
4
5
  * Form components use this to skip rendering their own Field.
@@ -43,6 +44,52 @@ interface OwnFieldOptions extends FieldShapingProps {
43
44
  * Internal; not part of the public API.
44
45
  */
45
46
  export declare const rendersOwnField: (component: string, options: OwnFieldOptions) => boolean;
47
+ /** The props a convenience form wrapper hands its own `Control`. Internal. */
48
+ export interface ControlLevelProps {
49
+ /** Shows the `Control`'s loading spinner. */
50
+ isLoading?: boolean;
51
+ /** The `Control`'s left icon. */
52
+ iconLeft?: ControlBaseProps['iconLeft'];
53
+ /** Shortcut for the left icon's name. */
54
+ iconLeftName?: string;
55
+ /** Shortcut for the left icon's size. */
56
+ iconLeftSize?: ControlBaseProps['iconLeftSize'];
57
+ /** The `Control`'s right icon. */
58
+ iconRight?: ControlBaseProps['iconRight'];
59
+ /** Shortcut for the right icon's name. */
60
+ iconRightName?: string;
61
+ /** Shortcut for the right icon's size. */
62
+ iconRightSize?: ControlBaseProps['iconRightSize'];
63
+ /** Reserves the `Control`'s left icon space. */
64
+ hasIconsLeft?: boolean;
65
+ /** Reserves the `Control`'s right icon space. */
66
+ hasIconsRight?: boolean;
67
+ /** Expands the `Control`. */
68
+ isExpanded?: boolean;
69
+ /** Set on the `Control` as its `size`. */
70
+ controlSize?: ControlBaseProps['size'];
71
+ /** Set on the `Control` as its class. */
72
+ controlClassName?: string;
73
+ }
74
+ interface OwnControlOptions extends ControlLevelProps {
75
+ /** `useInsideControl()` as the wrapper read it. */
76
+ insideControl: boolean;
77
+ /** A picker's `inline`, which renders no `Control` inside one or out. */
78
+ inline?: boolean;
79
+ }
80
+ /**
81
+ * Whether a convenience form wrapper renders a `Control` of its own (#921):
82
+ * only outside one. Inside a `Control` it renders none, so the props it
83
+ * would have handed its own do nothing there, and it warns in development,
84
+ * naming them and saying to set them on that `Control`. An `inline` picker
85
+ * renders none in either place, so it drops them inside a `Control` or not,
86
+ * and its warning says so without pointing at a `Control`. A wrapper passes
87
+ * only the props it hands its own `Control`, as the caller gave them, so a
88
+ * default the wrapper fills in itself never warns. A prop counts when it is
89
+ * truthy, since a falsy one would change nothing on a `Control` either.
90
+ * Internal; not part of the public API.
91
+ */
92
+ export declare const rendersOwnControl: (component: string, options: OwnControlOptions) => boolean;
46
93
  /**
47
94
  * The id a labeled Field wants its single composed control to adopt (#495).
48
95
  * `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the
@@ -8,9 +8,10 @@ import { InputBaseProps } from './InputBase.js';
8
8
  * Composes Field, Control, and Input into a single convenience component.
9
9
  * Supports all Input props, plus Field-level (label, horizontal) and
10
10
  * Control-level (icons, loading) props.
11
- * Inside an existing `Control` it renders no `Control` of its own, so set the
12
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
13
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
11
+ * Inside an existing `Control` it renders no `Control` of its own, so its
12
+ * Control-level props do nothing there and warn in development; set them on
13
+ * that `Control` instead. Inside an outer `Field`, or a `Control` with no
14
+ * `Field` around it, it renders no `Field` of its own either.
14
15
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
15
16
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
16
17
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -45,7 +45,14 @@ export interface NumberinputProps extends Omit<React.InputHTMLAttributes<HTMLInp
45
45
  controlsRounded?: boolean;
46
46
  /** Uses compact button spacing. */
47
47
  compact?: boolean;
48
- /** Removes button borders and background. */
48
+ /**
49
+ * Renders the plusminus controls without a `.field` row of their own, so
50
+ * they join the row of a `Field` with `hasAddons` or `grouped` they sit
51
+ * in. On by default inside a `Field`, unless a `Control` is anywhere above
52
+ * it: a `Control` stacks its children, so there the controls keep their
53
+ * own row.
54
+ * @defaultValue auto
55
+ */
49
56
  bare?: boolean;
50
57
  /** Style variant for the control buttons. */
51
58
  variant?: NumberinputVariant;
@@ -57,6 +64,9 @@ export interface NumberinputProps extends Omit<React.InputHTMLAttributes<HTMLInp
57
64
  * Shows a loading spinner on the input's control.
58
65
  * Under `prefers-reduced-motion: reduce` the spinner stops and stays
59
66
  * drawn (with bestax's CSS loaded).
67
+ * Use this rather than `isLoading` on a `Control` around the Numberinput:
68
+ * that spinner sits at the `Control`'s right edge, on top of whichever
69
+ * button is there, while this one stays inside the input.
60
70
  */
61
71
  isLoading?: boolean;
62
72
  /** Enables exponential step increments when holding buttons. */
@@ -8,9 +8,10 @@ import { SelectBaseProps } from './SelectBase.js';
8
8
  * Composes Field, Control, and SelectBase into a single convenience component.
9
9
  * Supports all SelectBase props, plus Field-level (label, horizontal) and
10
10
  * Control-level (icons) props.
11
- * Inside an existing `Control` it renders no `Control` of its own, so set the
12
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
13
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
11
+ * Inside an existing `Control` it renders no `Control` of its own, so its
12
+ * Control-level props do nothing there and warn in development; set them on
13
+ * that `Control` instead. Inside an outer `Field`, or a `Control` with no
14
+ * `Field` around it, it renders no `Field` of its own either.
14
15
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
15
16
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
16
17
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -8,9 +8,10 @@ import { TextAreaBaseProps } from './TextAreaBase.js';
8
8
  * Composes Field, Control, and TextAreaBase into a single convenience component.
9
9
  * Supports all TextAreaBase props, plus Field-level (label, horizontal) and
10
10
  * Control-level (loading) props.
11
- * Inside an existing `Control` it renders no `Control` of its own, so set the
12
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
13
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
11
+ * Inside an existing `Control` it renders no `Control` of its own, so its
12
+ * Control-level props do nothing there and warn in development; set them on
13
+ * that `Control` instead. Inside an outer `Field`, or a `Control` with no
14
+ * `Field` around it, it renders no `Field` of its own either.
14
15
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
15
16
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
16
17
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -5,9 +5,12 @@ import { TimeInputBaseProps } from './TimeInputBase.js';
5
5
  /**
6
6
  * Props for the TimeInput convenience wrapper. Extends `TimeInputBaseProps`
7
7
  * with Field-level (label, horizontal) and Control-level (icons, loading) props.
8
- * Inside an existing `Control` it renders no `Control` of its own, so set the
9
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
10
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
8
+ * Inside an existing `Control` it renders no `Control` of its own, so its
9
+ * Control-level props do nothing there and warn in development; set them on
10
+ * that `Control` instead. In `inline` mode it renders no `Control` anywhere,
11
+ * so they do nothing inside a `Control` or out, and warn in development
12
+ * there too. Inside an outer `Field`, or a `Control` with no `Field` around
13
+ * it, it renders no `Field` of its own either.
11
14
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
12
15
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
13
16
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -52,7 +55,8 @@ export interface TimeInputProps extends TimeInputBaseProps {
52
55
  /**
53
56
  * Shows a loading spinner on the `Control` it renders, and hides the
54
57
  * launcher (`triggerIcon`) while it does. Inside your own `Control` it
55
- * renders none, so this draws nothing; set `isLoading` on that `Control`.
58
+ * renders none, so this draws nothing and warns in development; set
59
+ * `isLoading` on that `Control`.
56
60
  * Under `prefers-reduced-motion: reduce` the spinner stops and stays
57
61
  * drawn (with bestax's CSS loaded).
58
62
  */
@@ -1,9 +1,8 @@
1
1
  import React from 'react';
2
- import { DateGranularity, DayOfWeek, PickerLabels } from './pickerTypes.js';
3
- export interface CalendarProps {
4
- value: Date | null;
2
+ import { DateGranularity, DateRangeValue, DayOfWeek, PickerLabels } from './pickerTypes.js';
3
+ /** What every calendar takes, whichever way it picks. */
4
+ interface CalendarBaseProps {
5
5
  focusedDate: Date;
6
- onSelect: (d: Date) => void;
7
6
  onFocusedDateChange: (d: Date) => void;
8
7
  /**
9
8
  * Earliest selectable date. One before year 1, or none, counts as the start
@@ -47,6 +46,48 @@ export interface CalendarProps {
47
46
  */
48
47
  granularity?: DateGranularity;
49
48
  }
49
+ /** A calendar that picks one day, month or year. */
50
+ interface CalendarSingleProps {
51
+ /** The selected date. */
52
+ value: Date | null;
53
+ /** Called with a picked date, or the first day of a picked period. */
54
+ onSelect: (d: Date) => void;
55
+ range?: never;
56
+ onRangeSelect?: never;
57
+ allowDisabledInRange?: never;
58
+ }
59
+ /** A calendar that picks a range of days. */
60
+ interface CalendarRangeProps {
61
+ /**
62
+ * The committed range, start first, which turns on range mode. The day grid
63
+ * then picks two days: the first pick marks a start inside the calendar and
64
+ * commits nothing, and the second calls `onRangeSelect` with both ends. A
65
+ * pick that cannot end the range starts a new one instead: one before the
66
+ * start, or one past a disabled day unless `allowDisabledInRange` is set.
67
+ * While a start is pending the grid previews the range to the hovered day,
68
+ * or to the focused day, and hides the committed one. A range with a start
69
+ * and no end opens with that start pending. Escape takes back a pending pick
70
+ * and stops there, so a popover around the calendar stays open; a pending
71
+ * start that came from `range` is not a pick, and Escape goes on.
72
+ */
73
+ range: DateRangeValue;
74
+ /** Called with both ends once the second day is picked. */
75
+ onRangeSelect: (start: Date, end: Date) => void;
76
+ /**
77
+ * Let a range include days that `shouldDisableDate` or `unselectableDates`
78
+ * disable. Its ends can still not be such days.
79
+ */
80
+ allowDisabledInRange?: boolean;
81
+ /** Only the day grid picks a range. */
82
+ granularity?: 'day';
83
+ value?: never;
84
+ onSelect?: never;
85
+ }
86
+ /**
87
+ * The calendar picks one date through `value` and `onSelect`, or a range
88
+ * through `range` and `onRangeSelect`, and its props take exactly one pair.
89
+ */
90
+ export type CalendarProps = CalendarBaseProps & (CalendarSingleProps | CalendarRangeProps);
50
91
  /**
51
92
  * Selects the calendar's focused cell, the one tab stop of whichever grid or
52
93
  * year list is on show, for a popover to put focus on as it opens. It runs
@@ -60,6 +60,23 @@ export declare function isDayUnselectable(d: Date, c: DayConstraints): boolean;
60
60
  * of 3pm on a month's last day leaves that day, and so its month, selectable.
61
61
  */
62
62
  export declare function isPeriodUnselectable(d: Date, granularity: DateGranularity, c: DayConstraints): boolean;
63
+ /**
64
+ * The most days {@link canCloseRange} walks between a range's ends, about
65
+ * eleven years. A span it would have to walk further is refused, so the check
66
+ * stays cheap enough to run on every pointer move over the calendar.
67
+ */
68
+ export declare const RANGE_WALK_LIMIT = 4000;
69
+ /**
70
+ * Whether `end` can close a range that opens on `start`: it falls on `start`'s
71
+ * day or later, and, unless `allowDisabled`, no day between the two is one
72
+ * that `shouldDisableDate` or `unselectableDates` disables. Checking that
73
+ * walks the days between, so with either rule set and `allowDisabled` off,
74
+ * an `end` more than {@link RANGE_WALK_LIMIT} days after `start` is refused.
75
+ * The ends' own constraints, `min` and `max` among them, are the caller's to
76
+ * check. Bounds can't fall between two days inside them, so they are not
77
+ * walked.
78
+ */
79
+ export declare function canCloseRange(start: Date, end: Date, c: DayConstraints, allowDisabled?: boolean): boolean;
63
80
  export declare function addDays(d: Date, n: number): Date;
64
81
  export declare function addMonths(d: Date, n: number): Date;
65
82
  export declare function addYears(d: Date, n: number): Date;
@@ -3,6 +3,11 @@ export type HourFormat = '12' | '24';
3
3
  export type DayOfWeek = 0 | 1 | 2 | 3 | 4 | 5 | 6;
4
4
  /** The unit a date picker selects: a day, a month or a year. */
5
5
  export type DateGranularity = 'day' | 'month' | 'year';
6
+ /**
7
+ * A range of days, start first. Either end may be `null` while the range is
8
+ * half filled, and `[null, null]` is empty.
9
+ */
10
+ export type DateRangeValue = [Date | null, Date | null];
6
11
  /**
7
12
  * Translatable strings used across all four pickers. Pass via the `labels`
8
13
  * prop to override defaults; consumers manage their own locale-driven mapping.
@@ -19,6 +24,15 @@ export interface PickerLabels {
19
24
  chooseMonth?: string;
20
25
  /** Launcher, popover and year list name when the picker selects a year. */
21
26
  chooseYear?: string;
27
+ /** Range picking: names the start of a range, in the calendar and the field. */
28
+ rangeStart?: string;
29
+ /** Range picking: names the end of a range, in the calendar and the field. */
30
+ rangeEnd?: string;
31
+ /**
32
+ * Range picking: describes the day a pending range would end on, the one
33
+ * the pointer or the keyboard is on, until it is picked.
34
+ */
35
+ rangePreviewEnd?: string;
22
36
  hours?: string;
23
37
  minutes?: string;
24
38
  seconds?: string;
@@ -13,6 +13,7 @@ export declare const announceDelay = 100;
13
13
  * again.
14
14
  */
15
15
  export declare const announcementLifetime = 1000;
16
+ export declare const visuallyHidden: React.CSSProperties;
16
17
  /**
17
18
  * Reads an element out roughly the way a screen reader would: its text, with
18
19
  * an element's `aria-label`, or an image's `alt`, standing in for what's
@@ -37,7 +37,12 @@ export interface AutocompleteProps extends Omit<React.HTMLAttributes<HTMLDivElem
37
37
  placeholder?: string;
38
38
  /** Object property to use as the display field. */
39
39
  field?: string;
40
- /** Whether to show a clear button. */
40
+ /**
41
+ * Whether to show a clear button while the input holds a value.
42
+ * It hides while the input is disabled, and gives way to a loading
43
+ * spinner at the same right edge: the one `loading` draws, or that of a
44
+ * `Control` with `isLoading` around the Autocomplete.
45
+ */
41
46
  clearable?: boolean;
42
47
  /** Open dropdown when input is focused. */
43
48
  openOnFocus?: boolean;
@@ -5,9 +5,12 @@ import { DateInputBaseProps } from './DateInputBase.js';
5
5
  /**
6
6
  * Props for the DateInput convenience wrapper. Extends `DateInputBaseProps`
7
7
  * with Field-level (label, horizontal) and Control-level (icons, loading) props.
8
- * Inside an existing `Control` it renders no `Control` of its own, so set the
9
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
10
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
8
+ * Inside an existing `Control` it renders no `Control` of its own, so its
9
+ * Control-level props do nothing there and warn in development; set them on
10
+ * that `Control` instead. In `inline` mode it renders no `Control` anywhere,
11
+ * so they do nothing inside a `Control` or out, and warn in development
12
+ * there too. Inside an outer `Field`, or a `Control` with no `Field` around
13
+ * it, it renders no `Field` of its own either.
11
14
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
12
15
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
13
16
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -52,7 +55,8 @@ export interface DateInputProps extends DateInputBaseProps {
52
55
  /**
53
56
  * Shows a loading spinner on the `Control` it renders, and hides the
54
57
  * launcher (`triggerIcon`) while it does. Inside your own `Control` it
55
- * renders none, so this draws nothing; set `isLoading` on that `Control`.
58
+ * renders none, so this draws nothing and warns in development; set
59
+ * `isLoading` on that `Control`.
56
60
  * Under `prefers-reduced-motion: reduce` the spinner stops and stays
57
61
  * drawn (with bestax's CSS loaded).
58
62
  */
@@ -5,9 +5,12 @@ import { DateTimeInputBaseProps } from './DateTimeInputBase.js';
5
5
  /**
6
6
  * Props for the DateTimeInput convenience wrapper. Extends
7
7
  * `DateTimeInputBaseProps` with Field-level and Control-level props.
8
- * Inside an existing `Control` it renders no `Control` of its own, so set the
9
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
10
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
8
+ * Inside an existing `Control` it renders no `Control` of its own, so its
9
+ * Control-level props do nothing there and warn in development; set them on
10
+ * that `Control` instead. In `inline` mode it renders no `Control` anywhere,
11
+ * so they do nothing inside a `Control` or out, and warn in development
12
+ * there too. Inside an outer `Field`, or a `Control` with no `Field` around
13
+ * it, it renders no `Field` of its own either.
11
14
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
12
15
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
13
16
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -50,7 +53,8 @@ export interface DateTimeInputProps extends DateTimeInputBaseProps {
50
53
  /**
51
54
  * Shows a loading spinner on the `Control` it renders, and hides the
52
55
  * launcher (`triggerIcon`) while it does. Inside your own `Control` it
53
- * renders none, so this draws nothing; set `isLoading` on that `Control`.
56
+ * renders none, so this draws nothing and warns in development; set
57
+ * `isLoading` on that `Control`.
54
58
  * Under `prefers-reduced-motion: reduce` the spinner stops and stays
55
59
  * drawn (with bestax's CSS loaded).
56
60
  */
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { ControlBaseProps } from './Control.js';
2
3
  /**
3
4
  * Hook to detect if the component is inside a Field wrapper.
4
5
  * Form components use this to skip rendering their own Field.
@@ -43,6 +44,52 @@ interface OwnFieldOptions extends FieldShapingProps {
43
44
  * Internal; not part of the public API.
44
45
  */
45
46
  export declare const rendersOwnField: (component: string, options: OwnFieldOptions) => boolean;
47
+ /** The props a convenience form wrapper hands its own `Control`. Internal. */
48
+ export interface ControlLevelProps {
49
+ /** Shows the `Control`'s loading spinner. */
50
+ isLoading?: boolean;
51
+ /** The `Control`'s left icon. */
52
+ iconLeft?: ControlBaseProps['iconLeft'];
53
+ /** Shortcut for the left icon's name. */
54
+ iconLeftName?: string;
55
+ /** Shortcut for the left icon's size. */
56
+ iconLeftSize?: ControlBaseProps['iconLeftSize'];
57
+ /** The `Control`'s right icon. */
58
+ iconRight?: ControlBaseProps['iconRight'];
59
+ /** Shortcut for the right icon's name. */
60
+ iconRightName?: string;
61
+ /** Shortcut for the right icon's size. */
62
+ iconRightSize?: ControlBaseProps['iconRightSize'];
63
+ /** Reserves the `Control`'s left icon space. */
64
+ hasIconsLeft?: boolean;
65
+ /** Reserves the `Control`'s right icon space. */
66
+ hasIconsRight?: boolean;
67
+ /** Expands the `Control`. */
68
+ isExpanded?: boolean;
69
+ /** Set on the `Control` as its `size`. */
70
+ controlSize?: ControlBaseProps['size'];
71
+ /** Set on the `Control` as its class. */
72
+ controlClassName?: string;
73
+ }
74
+ interface OwnControlOptions extends ControlLevelProps {
75
+ /** `useInsideControl()` as the wrapper read it. */
76
+ insideControl: boolean;
77
+ /** A picker's `inline`, which renders no `Control` inside one or out. */
78
+ inline?: boolean;
79
+ }
80
+ /**
81
+ * Whether a convenience form wrapper renders a `Control` of its own (#921):
82
+ * only outside one. Inside a `Control` it renders none, so the props it
83
+ * would have handed its own do nothing there, and it warns in development,
84
+ * naming them and saying to set them on that `Control`. An `inline` picker
85
+ * renders none in either place, so it drops them inside a `Control` or not,
86
+ * and its warning says so without pointing at a `Control`. A wrapper passes
87
+ * only the props it hands its own `Control`, as the caller gave them, so a
88
+ * default the wrapper fills in itself never warns. A prop counts when it is
89
+ * truthy, since a falsy one would change nothing on a `Control` either.
90
+ * Internal; not part of the public API.
91
+ */
92
+ export declare const rendersOwnControl: (component: string, options: OwnControlOptions) => boolean;
46
93
  /**
47
94
  * The id a labeled Field wants its single composed control to adopt (#495).
48
95
  * `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the
@@ -8,9 +8,10 @@ import { InputBaseProps } from './InputBase.js';
8
8
  * Composes Field, Control, and Input into a single convenience component.
9
9
  * Supports all Input props, plus Field-level (label, horizontal) and
10
10
  * Control-level (icons, loading) props.
11
- * Inside an existing `Control` it renders no `Control` of its own, so set the
12
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
13
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
11
+ * Inside an existing `Control` it renders no `Control` of its own, so its
12
+ * Control-level props do nothing there and warn in development; set them on
13
+ * that `Control` instead. Inside an outer `Field`, or a `Control` with no
14
+ * `Field` around it, it renders no `Field` of its own either.
14
15
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
15
16
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
16
17
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -45,7 +45,14 @@ export interface NumberinputProps extends Omit<React.InputHTMLAttributes<HTMLInp
45
45
  controlsRounded?: boolean;
46
46
  /** Uses compact button spacing. */
47
47
  compact?: boolean;
48
- /** Removes button borders and background. */
48
+ /**
49
+ * Renders the plusminus controls without a `.field` row of their own, so
50
+ * they join the row of a `Field` with `hasAddons` or `grouped` they sit
51
+ * in. On by default inside a `Field`, unless a `Control` is anywhere above
52
+ * it: a `Control` stacks its children, so there the controls keep their
53
+ * own row.
54
+ * @defaultValue auto
55
+ */
49
56
  bare?: boolean;
50
57
  /** Style variant for the control buttons. */
51
58
  variant?: NumberinputVariant;
@@ -57,6 +64,9 @@ export interface NumberinputProps extends Omit<React.InputHTMLAttributes<HTMLInp
57
64
  * Shows a loading spinner on the input's control.
58
65
  * Under `prefers-reduced-motion: reduce` the spinner stops and stays
59
66
  * drawn (with bestax's CSS loaded).
67
+ * Use this rather than `isLoading` on a `Control` around the Numberinput:
68
+ * that spinner sits at the `Control`'s right edge, on top of whichever
69
+ * button is there, while this one stays inside the input.
60
70
  */
61
71
  isLoading?: boolean;
62
72
  /** Enables exponential step increments when holding buttons. */
@@ -8,9 +8,10 @@ import { SelectBaseProps } from './SelectBase.js';
8
8
  * Composes Field, Control, and SelectBase into a single convenience component.
9
9
  * Supports all SelectBase props, plus Field-level (label, horizontal) and
10
10
  * Control-level (icons) props.
11
- * Inside an existing `Control` it renders no `Control` of its own, so set the
12
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
13
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
11
+ * Inside an existing `Control` it renders no `Control` of its own, so its
12
+ * Control-level props do nothing there and warn in development; set them on
13
+ * that `Control` instead. Inside an outer `Field`, or a `Control` with no
14
+ * `Field` around it, it renders no `Field` of its own either.
14
15
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
15
16
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
16
17
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -8,9 +8,10 @@ import { TextAreaBaseProps } from './TextAreaBase.js';
8
8
  * Composes Field, Control, and TextAreaBase into a single convenience component.
9
9
  * Supports all TextAreaBase props, plus Field-level (label, horizontal) and
10
10
  * Control-level (loading) props.
11
- * Inside an existing `Control` it renders no `Control` of its own, so set the
12
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
13
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
11
+ * Inside an existing `Control` it renders no `Control` of its own, so its
12
+ * Control-level props do nothing there and warn in development; set them on
13
+ * that `Control` instead. Inside an outer `Field`, or a `Control` with no
14
+ * `Field` around it, it renders no `Field` of its own either.
14
15
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
15
16
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
16
17
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -5,9 +5,12 @@ import { TimeInputBaseProps } from './TimeInputBase.js';
5
5
  /**
6
6
  * Props for the TimeInput convenience wrapper. Extends `TimeInputBaseProps`
7
7
  * with Field-level (label, horizontal) and Control-level (icons, loading) props.
8
- * Inside an existing `Control` it renders no `Control` of its own, so set the
9
- * Control-level props on that `Control` instead. Inside an outer `Field`, or a
10
- * `Control` with no `Field` around it, it renders no `Field` of its own either.
8
+ * Inside an existing `Control` it renders no `Control` of its own, so its
9
+ * Control-level props do nothing there and warn in development; set them on
10
+ * that `Control` instead. In `inline` mode it renders no `Control` anywhere,
11
+ * so they do nothing inside a `Control` or out, and warn in development
12
+ * there too. Inside an outer `Field`, or a `Control` with no `Field` around
13
+ * it, it renders no `Field` of its own either.
11
14
  * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that
12
15
  * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and
13
16
  * warns in development. Wrap the `Control` in a `Field` instead, and set the
@@ -52,7 +55,8 @@ export interface TimeInputProps extends TimeInputBaseProps {
52
55
  /**
53
56
  * Shows a loading spinner on the `Control` it renders, and hides the
54
57
  * launcher (`triggerIcon`) while it does. Inside your own `Control` it
55
- * renders none, so this draws nothing; set `isLoading` on that `Control`.
58
+ * renders none, so this draws nothing and warns in development; set
59
+ * `isLoading` on that `Control`.
56
60
  * Under `prefers-reduced-motion: reduce` the spinner stops and stays
57
61
  * drawn (with bestax's CSS loaded).
58
62
  */