shelving 1.258.4 → 1.258.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shelving",
3
- "version": "1.258.4",
3
+ "version": "1.258.6",
4
4
  "author": "Dave Houlbrooke <dave@shax.com>",
5
5
  "repository": {
6
6
  "type": "git",
@@ -51,6 +51,19 @@ export declare class ChoiceSchema<O extends string, I = never> extends Schema<O>
51
51
  * Create a new `ChoiceSchema`.
52
52
  */
53
53
  constructor({ one, title, placeholder, options, value, ...rest }: ChoiceSchemaOptions<O, I>);
54
+ /**
55
+ * Get an unknown value as one of the allowed choices, or `undefined` if it isn't one.
56
+ *
57
+ * - Non-throwing counterpart to `validate()`, which defers to this and throws when it returns `undefined`.
58
+ * - Use it to normalise a value for display (e.g. in a form input) without raising on invalid or sentinel values.
59
+ *
60
+ * @param unsafeValue The unknown input value to coerce (defaults to this schema's `value`).
61
+ * @returns The valid choice key, or `undefined` if the value is not one of the allowed choices.
62
+ * @example schema.get("yes") // "yes"
63
+ * @example schema.get("nope") // undefined
64
+ * @see https://shelving.cc/schema/ChoiceSchema/get
65
+ */
66
+ get(unsafeValue?: unknown): O | undefined;
54
67
  /**
55
68
  * Validate an unknown value as one of the allowed choices.
56
69
  *
@@ -29,6 +29,23 @@ export class ChoiceSchema extends Schema {
29
29
  super({ one, title, value, placeholder, ...rest });
30
30
  this.options = _getChoiceOptions(options);
31
31
  }
32
+ /**
33
+ * Get an unknown value as one of the allowed choices, or `undefined` if it isn't one.
34
+ *
35
+ * - Non-throwing counterpart to `validate()`, which defers to this and throws when it returns `undefined`.
36
+ * - Use it to normalise a value for display (e.g. in a form input) without raising on invalid or sentinel values.
37
+ *
38
+ * @param unsafeValue The unknown input value to coerce (defaults to this schema's `value`).
39
+ * @returns The valid choice key, or `undefined` if the value is not one of the allowed choices.
40
+ * @example schema.get("yes") // "yes"
41
+ * @example schema.get("nope") // undefined
42
+ * @see https://shelving.cc/schema/ChoiceSchema/get
43
+ */
44
+ get(unsafeValue = this.value) {
45
+ if (typeof unsafeValue === "string" && isProp(this.options, unsafeValue))
46
+ return unsafeValue;
47
+ return undefined;
48
+ }
32
49
  /**
33
50
  * Validate an unknown value as one of the allowed choices.
34
51
  *
@@ -39,8 +56,9 @@ export class ChoiceSchema extends Schema {
39
56
  * @see https://shelving.cc/schema/ChoiceSchema/validate
40
57
  */
41
58
  validate(unsafeValue = this.value) {
42
- if (typeof unsafeValue === "string" && isProp(this.options, unsafeValue))
43
- return unsafeValue;
59
+ const value = this.get(unsafeValue);
60
+ if (value !== undefined)
61
+ return value;
44
62
  throw unsafeValue ? `Unknown ${this.one}` : "Required";
45
63
  }
46
64
  /**
@@ -22,23 +22,8 @@ export interface CountrySchemaOptions extends SchemaOptions {
22
22
  * @see https://shelving.cc/schema/CountrySchema
23
23
  */
24
24
  export declare class CountrySchema extends ChoiceSchema<Country, PossibleCountry> {
25
- /**
26
- * Create a new `CountrySchema`.
27
- *
28
- * @example new CountrySchema({ value: "GB" })
29
- * @see https://shelving.cc/schema/CountrySchema
30
- */
31
25
  constructor({ one, title, value, ...options }?: CountrySchemaOptions);
32
- /**
33
- * Validate an unknown input value and return a valid country code.
34
- *
35
- * @param unsafeValue The value to validate (defaults to this schema's `value`).
36
- * @returns The validated ISO 3166 country code.
37
- * @throws `string` `"Required"` if the value is empty, or `` `Unknown ${one}` `` if it is not a known country.
38
- * @example schema.validate("GB") // "GB"
39
- * @see https://shelving.cc/schema/CountrySchema/validate
40
- */
41
- validate(unsafeValue?: unknown): Country;
26
+ get(unsafeValue?: unknown): Country | undefined;
42
27
  }
43
28
  /**
44
29
  * Sugar instance of `CountrySchema` for a required ISO 3166 country code, e.g. `GB`. Equivalent to `new CountrySchema({})`.
@@ -13,29 +13,11 @@ import { NULLABLE } from "./NullableSchema.js";
13
13
  * @see https://shelving.cc/schema/CountrySchema
14
14
  */
15
15
  export class CountrySchema extends ChoiceSchema {
16
- /**
17
- * Create a new `CountrySchema`.
18
- *
19
- * @example new CountrySchema({ value: "GB" })
20
- * @see https://shelving.cc/schema/CountrySchema
21
- */
22
16
  constructor({ one = "country", title = "Country", value = "detect", ...options } = {}) {
23
17
  super({ one, title, options: COUNTRIES, value, ...options });
24
18
  }
25
- /**
26
- * Validate an unknown input value and return a valid country code.
27
- *
28
- * @param unsafeValue The value to validate (defaults to this schema's `value`).
29
- * @returns The validated ISO 3166 country code.
30
- * @throws `string` `"Required"` if the value is empty, or `` `Unknown ${one}` `` if it is not a known country.
31
- * @example schema.validate("GB") // "GB"
32
- * @see https://shelving.cc/schema/CountrySchema/validate
33
- */
34
- validate(unsafeValue = this.value) {
35
- const country = getCountry(unsafeValue);
36
- if (country)
37
- return super.validate(country);
38
- throw unsafeValue === "detect" ? "Required" : `Unknown ${this.one}`;
19
+ get(unsafeValue = this.value) {
20
+ return getCountry(unsafeValue);
39
21
  }
40
22
  }
41
23
  /**
@@ -1,4 +1,3 @@
1
- import { formatNumber } from "../util/format.js";
2
1
  import type { SchemaOptions } from "./Schema.js";
3
2
  import { Schema } from "./Schema.js";
4
3
  /**
@@ -21,11 +20,6 @@ export interface NumberSchemaOptions extends SchemaOptions {
21
20
  readonly max?: number | undefined;
22
21
  /** Rounding step the value is snapped to (e.g. `1` for integers). */
23
22
  readonly step?: number | undefined;
24
- /**
25
- * Format the number for display in downstream UIs.
26
- * @default formatNumber
27
- */
28
- readonly format?: typeof formatNumber | undefined;
29
23
  }
30
24
  /**
31
25
  * Schema that defines a valid number.
@@ -47,7 +41,7 @@ export declare class NumberSchema extends Schema<number> {
47
41
  /**
48
42
  * Create a new `NumberSchema`.
49
43
  */
50
- constructor({ one, title, min, max, step, format, value, ...options }: NumberSchemaOptions);
44
+ constructor({ one, title, min, max, step, value, ...options }: NumberSchemaOptions);
51
45
  /**
52
46
  * Validate an unknown value and coerce it to a number.
53
47
  *
@@ -21,7 +21,7 @@ export class NumberSchema extends Schema {
21
21
  /**
22
22
  * Create a new `NumberSchema`.
23
23
  */
24
- constructor({ one = "number", title = "Number", min = Number.NEGATIVE_INFINITY, max = Number.POSITIVE_INFINITY, step, format = formatNumber, value, ...options }) {
24
+ constructor({ one = "number", title = "Number", min = Number.NEGATIVE_INFINITY, max = Number.POSITIVE_INFINITY, step, value, ...options }) {
25
25
  super({ one, title, value, ...options });
26
26
  this.min = min;
27
27
  this.max = max;
@@ -6,15 +6,6 @@
6
6
  @import "../style/Tint.module.css";
7
7
 
8
8
  @layer components {
9
- .wrap {
10
- position: relative;
11
-
12
- /* Children */
13
- && > * {
14
- margin: 0;
15
- }
16
- }
17
-
18
9
  .panel {
19
10
  /* Box */
20
11
  display: block;
@@ -23,7 +14,7 @@
23
14
  right: 0;
24
15
  top: calc(100% + var(--popover-offset-y, var(--space-xsmall)));
25
16
  z-index: 1000;
26
- max-height: var(--popover-max-height, 30vh);
17
+ max-height: var(--popover-height, 30vh);
27
18
  border-radius: var(--popover-radius, var(--radius-xsmall));
28
19
  border: var(--popover-border, var(--popover-stroke, var(--stroke-normal)) solid var(--tint-80));
29
20
  padding: var(--popover-padding, var(--space-small));
@@ -35,7 +26,18 @@
35
26
  overscroll-behavior-y: contain;
36
27
 
37
28
  /* Style */
38
- background: var(--popover-color-bg, var(--tint-100));
29
+ background: var(--popover-background, var(--tint-100));
39
30
  box-shadow: var(--popover-shadow, var(--shadow-small));
40
31
  }
41
32
  }
33
+
34
+ @layer overrides {
35
+ .wrap {
36
+ position: relative;
37
+
38
+ /* Children */
39
+ && > * {
40
+ margin: 0;
41
+ }
42
+ }
43
+ }
@@ -84,6 +84,8 @@ export interface ChoiceSchemaInputProps extends SchemaInputProps<ChoiceSchema<st
84
84
  /**
85
85
  * Show a choice input for a `ChoiceSchema` — radio inputs for up to 8 options, otherwise a select.
86
86
  *
87
+ * - 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
  * @returns A `ChoiceRadioInputs` or `SelectInput` element bound to the schema.
88
90
  * @kind component
89
91
  * @example <ChoiceSchemaInput name="role" schema={ROLE} />
@@ -96,16 +96,19 @@ export function NumberSchemaInput({ schema, value, ...props }) {
96
96
  /**
97
97
  * Show a choice input for a `ChoiceSchema` — radio inputs for up to 8 options, otherwise a select.
98
98
  *
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.
100
+ *
99
101
  * @returns A `ChoiceRadioInputs` or `SelectInput` element bound to the schema.
100
102
  * @kind component
101
103
  * @example <ChoiceSchemaInput name="role" schema={ROLE} />
102
104
  * @see https://shelving.cc/ui/ChoiceSchemaInput
103
105
  */
104
106
  export function ChoiceSchemaInput({ schema, value, ...props }) {
105
- const { options } = requireSource(ChoiceSchema, schema);
106
- if (getKeys(options).length <= 8)
107
- return _jsx(ChoiceRadioInputs, { ...schema, value: getString(value), ...props });
108
- return _jsx(SelectInput, { ...schema, value: getString(value), ...props });
107
+ const choice = requireSource(ChoiceSchema, schema);
108
+ const string = choice.get(value);
109
+ if (getKeys(choice.options).length <= 8)
110
+ return _jsx(ChoiceRadioInputs, { ...schema, value: string, ...props });
111
+ return _jsx(SelectInput, { ...schema, value: string, ...props });
109
112
  }
110
113
  /**
111
114
  * Show a `CheckboxInput` for a `BooleanSchema`.
@@ -152,15 +152,18 @@ export interface ChoiceSchemaInputProps extends SchemaInputProps<ChoiceSchema<st
152
152
  /**
153
153
  * Show a choice input for a `ChoiceSchema` — radio inputs for up to 8 options, otherwise a select.
154
154
  *
155
+ * - 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
+ *
155
157
  * @returns A `ChoiceRadioInputs` or `SelectInput` element bound to the schema.
156
158
  * @kind component
157
159
  * @example <ChoiceSchemaInput name="role" schema={ROLE} />
158
160
  * @see https://shelving.cc/ui/ChoiceSchemaInput
159
161
  */
160
162
  export function ChoiceSchemaInput({ schema, value, ...props }: ChoiceSchemaInputProps): ReactElement {
161
- const { options } = requireSource(ChoiceSchema, schema);
162
- if (getKeys(options).length <= 8) return <ChoiceRadioInputs {...schema} value={getString(value)} {...props} />;
163
- return <SelectInput {...schema} value={getString(value)} {...props} />;
163
+ const choice = requireSource(ChoiceSchema, schema);
164
+ const string = choice.get(value);
165
+ if (getKeys(choice.options).length <= 8) return <ChoiceRadioInputs {...schema} value={string} {...props} />;
166
+ return <SelectInput {...schema} value={string} {...props} />;
164
167
  }
165
168
 
166
169
  /**