shelving 1.290.0 → 1.291.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shelving",
3
- "version": "1.290.0",
3
+ "version": "1.291.0",
4
4
  "author": "Dave Houlbrooke <dave@shax.com>",
5
5
  "repository": {
6
6
  "type": "git",
@@ -40,7 +40,7 @@ export interface ChoiceSchemaOptions<O extends string, I = never> extends Schema
40
40
  readonly value?: O | I;
41
41
  /**
42
42
  * Input control hint for downstream UIs.
43
- * - When not set, a UI picks the control from the number of options.
43
+ * @default "radio" for 8 or fewer options, otherwise "select"
44
44
  */
45
45
  readonly input?: ChoiceInputType | undefined;
46
46
  }
@@ -55,7 +55,7 @@ export interface ChoiceSchemaOptions<O extends string, I = never> extends Schema
55
55
  export declare class ChoiceSchema<O extends string, I = never> extends Schema<O> {
56
56
  readonly value: O | I | undefined;
57
57
  readonly options: ChoiceOptions<O>;
58
- readonly input: ChoiceInputType | undefined;
58
+ readonly input: ChoiceInputType;
59
59
  constructor({ one, title, placeholder, options, value, input, ...rest }: ChoiceSchemaOptions<O, I>);
60
60
  /**
61
61
  * Get an unknown value as one of the allowed choices, or `undefined` if it isn't one.
@@ -1,5 +1,5 @@
1
1
  import { isArray } from "../util/array.js";
2
- import { isProp } from "../util/object.js";
2
+ import { getKeys, isProp } from "../util/object.js";
3
3
  import { Schema } from "./Schema.js";
4
4
  /** Get a `ChoiceOptions` object for a set of `PossibleChoiceOptions`. */
5
5
  function _getChoiceOptions(options) {
@@ -8,6 +8,8 @@ function _getChoiceOptions(options) {
8
8
  function _getChoiceOption(k) {
9
9
  return [k, k];
10
10
  }
11
+ /** Maximum number of options for which a `ChoiceSchema` defaults to radio inputs. */
12
+ const MAX_RADIO_OPTIONS = 8;
11
13
  /**
12
14
  * Schema that validates a value against a fixed set of allowed string choices.
13
15
  *
@@ -22,7 +24,7 @@ export class ChoiceSchema extends Schema {
22
24
  constructor({ one = "choice", title = "Choice", placeholder = `No ${one}`, options, value, input, ...rest }) {
23
25
  super({ one, title, value, placeholder, ...rest });
24
26
  this.options = _getChoiceOptions(options);
25
- this.input = input;
27
+ this.input = input ?? (getKeys(this.options).length <= MAX_RADIO_OPTIONS ? "radio" : "select");
26
28
  }
27
29
  /**
28
30
  * Get an unknown value as one of the allowed choices, or `undefined` if it isn't one.
@@ -83,7 +83,6 @@ export interface ChoiceSchemaInputProps extends SchemaInputProps<ChoiceSchema<st
83
83
  * Show a choice input for a `ChoiceSchema` — radio inputs or a select.
84
84
  *
85
85
  * - The schema's `input` picks the control: `"radio"` for radio inputs, `"select"` for a select.
86
- * - When `input` is not set, it shows radio inputs for up to 8 options, otherwise a select.
87
86
  * - The value is normalised through the schema's `get()`, so invalid or sentinel values (e.g. a `CountrySchema`'s `"detect"`) resolve to a real option or fall back to the placeholder rather than mis-selecting the first option.
88
87
  *
89
88
  * @returns A `ChoiceRadioInputs` or `SelectInput` element bound to the schema.
@@ -14,7 +14,6 @@ import { isArray } from "../../util/array.js";
14
14
  import { isData } from "../../util/data.js";
15
15
  import { isDictionary } from "../../util/dictionary.js";
16
16
  import { getNumber } from "../../util/number.js";
17
- import { getKeys } from "../../util/object.js";
18
17
  import { getSource, requireSource } from "../../util/source.js";
19
18
  import { getString } from "../../util/string.js";
20
19
  import { Field } from "../form/Field.js";
@@ -97,7 +96,6 @@ export function NumberSchemaInput({ schema, value, ...props }) {
97
96
  * Show a choice input for a `ChoiceSchema` — radio inputs or a select.
98
97
  *
99
98
  * - The schema's `input` picks the control: `"radio"` for radio inputs, `"select"` for a select.
100
- * - When `input` is not set, it shows radio inputs for up to 8 options, otherwise a select.
101
99
  * - The value is normalised through the schema's `get()`, so invalid or sentinel values (e.g. a `CountrySchema`'s `"detect"`) resolve to a real option or fall back to the placeholder rather than mis-selecting the first option.
102
100
  *
103
101
  * @returns A `ChoiceRadioInputs` or `SelectInput` element bound to the schema.
@@ -108,8 +106,7 @@ export function NumberSchemaInput({ schema, value, ...props }) {
108
106
  export function ChoiceSchemaInput({ schema, value, ...props }) {
109
107
  const choice = requireSource(ChoiceSchema, schema);
110
108
  const string = choice.get(value);
111
- const input = choice.input ?? (getKeys(choice.options).length <= 8 ? "radio" : "select");
112
- if (input === "radio")
109
+ if (choice.input === "radio")
113
110
  return _jsx(ChoiceRadioInputs, { ...schema, value: string, ...props });
114
111
  return _jsx(SelectInput, { ...schema, value: string, ...props });
115
112
  }
@@ -17,8 +17,8 @@ The schema-to-input mapping:
17
17
  | `NumberSchema` | `<NumberInput>` (formatted on blur) |
18
18
  | `DateSchema` | `<DateInput>` |
19
19
  | `BooleanSchema` | `<CheckboxInput>` |
20
- | `ChoiceSchema` (`input: "radio"`, or ≤ 8 options) | `<ChoiceRadioInputs>` |
21
- | `ChoiceSchema` (`input: "select"`, or > 8 options) | `<SelectInput>` |
20
+ | `ChoiceSchema` (`input: "radio"`, the default for ≤ 8 options) | `<ChoiceRadioInputs>` |
21
+ | `ChoiceSchema` (`input: "select"`, the default for > 8 options) | `<SelectInput>` |
22
22
  | `ArraySchema` | `<ArrayInput>` |
23
23
  | `DictionarySchema` | `<DictionaryInput>` |
24
24
  | `DataSchema` | `<DataInput>` |
@@ -15,7 +15,6 @@ import { isArray } from "../../util/array.js";
15
15
  import { type Data, isData } from "../../util/data.js";
16
16
  import { isDictionary } from "../../util/dictionary.js";
17
17
  import { getNumber } from "../../util/number.js";
18
- import { getKeys } from "../../util/object.js";
19
18
  import { getSource, requireSource } from "../../util/source.js";
20
19
  import { getString } from "../../util/string.js";
21
20
  import type { ValidatorType } from "../../util/validate.js";
@@ -151,7 +150,6 @@ export interface ChoiceSchemaInputProps extends SchemaInputProps<ChoiceSchema<st
151
150
  * Show a choice input for a `ChoiceSchema` — radio inputs or a select.
152
151
  *
153
152
  * - The schema's `input` picks the control: `"radio"` for radio inputs, `"select"` for a select.
154
- * - When `input` is not set, it shows radio inputs for up to 8 options, otherwise a select.
155
153
  * - The value is normalised through the schema's `get()`, so invalid or sentinel values (e.g. a `CountrySchema`'s `"detect"`) resolve to a real option or fall back to the placeholder rather than mis-selecting the first option.
156
154
  *
157
155
  * @returns A `ChoiceRadioInputs` or `SelectInput` element bound to the schema.
@@ -162,8 +160,7 @@ export interface ChoiceSchemaInputProps extends SchemaInputProps<ChoiceSchema<st
162
160
  export function ChoiceSchemaInput({ schema, value, ...props }: ChoiceSchemaInputProps): ReactElement {
163
161
  const choice = requireSource(ChoiceSchema, schema);
164
162
  const string = choice.get(value);
165
- const input = choice.input ?? (getKeys(choice.options).length <= 8 ? "radio" : "select");
166
- if (input === "radio") return <ChoiceRadioInputs {...schema} value={string} {...props} />;
163
+ if (choice.input === "radio") return <ChoiceRadioInputs {...schema} value={string} {...props} />;
167
164
  return <SelectInput {...schema} value={string} {...props} />;
168
165
  }
169
166