shelving 1.282.2 → 1.284.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 +2 -2
- package/ui/README.md +2 -1
- package/ui/block/Address.d.ts +7 -7
- package/ui/block/Address.js +6 -6
- package/ui/block/Address.tsx +10 -9
- package/ui/block/Block.d.ts +3 -3
- package/ui/block/Block.js +3 -2
- package/ui/block/Block.tsx +5 -4
- package/ui/block/Blockquote.d.ts +3 -3
- package/ui/block/Blockquote.js +2 -2
- package/ui/block/Blockquote.tsx +4 -3
- package/ui/block/Caption.d.ts +3 -3
- package/ui/block/Caption.js +3 -3
- package/ui/block/Caption.tsx +5 -4
- package/ui/block/Card.d.ts +3 -2
- package/ui/block/Card.js +2 -2
- package/ui/block/Card.tsx +4 -2
- package/ui/block/Column.d.ts +3 -3
- package/ui/block/Column.js +2 -2
- package/ui/block/Column.tsx +4 -3
- package/ui/block/Definitions.d.ts +3 -3
- package/ui/block/Definitions.js +2 -2
- package/ui/block/Definitions.tsx +4 -3
- package/ui/block/Details.d.ts +3 -2
- package/ui/block/Details.js +2 -2
- package/ui/block/Details.tsx +4 -3
- package/ui/block/Divider.d.ts +3 -2
- package/ui/block/Divider.js +2 -2
- package/ui/block/Divider.tsx +4 -2
- package/ui/block/Heading.d.ts +3 -3
- package/ui/block/Heading.js +2 -2
- package/ui/block/Heading.tsx +4 -3
- package/ui/block/Image.d.ts +3 -2
- package/ui/block/Image.js +2 -2
- package/ui/block/Image.tsx +4 -2
- package/ui/block/Label.d.ts +1 -1
- package/ui/block/Label.js +2 -2
- package/ui/block/Label.tsx +2 -1
- package/ui/block/List.d.ts +3 -2
- package/ui/block/List.js +4 -4
- package/ui/block/List.tsx +6 -4
- package/ui/block/Panel.d.ts +3 -3
- package/ui/block/Panel.js +2 -2
- package/ui/block/Panel.tsx +4 -3
- package/ui/block/Paragraph.d.ts +3 -3
- package/ui/block/Paragraph.js +2 -2
- package/ui/block/Paragraph.tsx +4 -3
- package/ui/block/Preformatted.d.ts +3 -3
- package/ui/block/Preformatted.js +2 -2
- package/ui/block/Preformatted.tsx +4 -3
- package/ui/block/Row.d.ts +3 -3
- package/ui/block/Row.js +2 -2
- package/ui/block/Row.tsx +4 -3
- package/ui/block/Section.js +1 -1
- package/ui/block/Section.tsx +1 -0
- package/ui/block/Subheading.d.ts +1 -1
- package/ui/block/Subheading.js +2 -2
- package/ui/block/Subheading.tsx +2 -1
- package/ui/block/Title.d.ts +1 -1
- package/ui/block/Title.js +2 -2
- package/ui/block/Title.tsx +2 -1
- package/ui/block/Video.d.ts +3 -3
- package/ui/block/Video.js +2 -2
- package/ui/block/Video.tsx +4 -3
- package/ui/button/Button.d.ts +3 -2
- package/ui/button/Button.js +2 -2
- package/ui/button/Button.md +28 -0
- package/ui/button/Button.module.css +23 -5
- package/ui/button/Button.tsx +4 -3
- package/ui/button/Clickable.d.ts +3 -3
- package/ui/button/Clickable.js +6 -4
- package/ui/button/Clickable.tsx +9 -9
- package/ui/button/FullscreenButton.d.ts +3 -5
- package/ui/button/FullscreenButton.tsx +3 -2
- package/ui/button/RetryButton.d.ts +2 -2
- package/ui/button/RetryButton.tsx +2 -2
- package/ui/button/SubmitButton.d.ts +3 -3
- package/ui/button/SubmitButton.js +3 -2
- package/ui/button/SubmitButton.tsx +5 -3
- package/ui/dialog/Dialog.d.ts +6 -4
- package/ui/dialog/Dialog.js +7 -4
- package/ui/dialog/Dialog.tsx +19 -7
- package/ui/dialog/Modal.d.ts +3 -3
- package/ui/dialog/Modal.js +3 -3
- package/ui/dialog/Modal.tsx +5 -5
- package/ui/docs/DocumentationButtons.d.ts +3 -2
- package/ui/docs/DocumentationButtons.js +2 -2
- package/ui/docs/DocumentationButtons.tsx +4 -1
- package/ui/form/Field.d.ts +3 -3
- package/ui/form/Field.js +2 -2
- package/ui/form/Field.tsx +4 -3
- package/ui/form/Form.d.ts +2 -2
- package/ui/form/Form.js +3 -2
- package/ui/form/Form.tsx +5 -3
- package/ui/form/FormFields.d.ts +1 -1
- package/ui/form/FormFields.js +2 -2
- package/ui/form/FormFields.tsx +2 -2
- package/ui/form/FormFooter.d.ts +3 -3
- package/ui/form/FormFooter.js +2 -2
- package/ui/form/FormFooter.tsx +4 -4
- package/ui/form/FormMessage.d.ts +2 -2
- package/ui/form/FormMessage.tsx +2 -3
- package/ui/form/Progress.d.ts +3 -2
- package/ui/form/Progress.js +2 -2
- package/ui/form/Progress.tsx +4 -2
- package/ui/inline/Code.d.ts +3 -3
- package/ui/inline/Code.js +2 -2
- package/ui/inline/Code.tsx +4 -3
- package/ui/inline/Deleted.d.ts +3 -3
- package/ui/inline/Deleted.js +2 -2
- package/ui/inline/Deleted.tsx +4 -3
- package/ui/inline/Emphasis.d.ts +3 -3
- package/ui/inline/Emphasis.js +2 -2
- package/ui/inline/Emphasis.tsx +4 -3
- package/ui/inline/Inserted.d.ts +3 -3
- package/ui/inline/Inserted.js +2 -2
- package/ui/inline/Inserted.tsx +4 -3
- package/ui/inline/Link.d.ts +3 -2
- package/ui/inline/Link.js +2 -2
- package/ui/inline/Link.tsx +4 -2
- package/ui/inline/Mark.d.ts +3 -3
- package/ui/inline/Mark.js +2 -2
- package/ui/inline/Mark.tsx +4 -3
- package/ui/inline/Small.d.ts +3 -3
- package/ui/inline/Small.js +2 -2
- package/ui/inline/Small.tsx +4 -3
- package/ui/inline/Span.d.ts +3 -3
- package/ui/inline/Span.js +3 -2
- package/ui/inline/Span.tsx +5 -4
- package/ui/inline/Strong.d.ts +3 -3
- package/ui/inline/Strong.js +2 -2
- package/ui/inline/Strong.tsx +4 -3
- package/ui/inline/Subscript.d.ts +3 -3
- package/ui/inline/Subscript.js +3 -3
- package/ui/inline/Subscript.tsx +5 -5
- package/ui/inline/Superscript.d.ts +3 -3
- package/ui/inline/Superscript.js +3 -3
- package/ui/inline/Superscript.tsx +5 -5
- package/ui/input/ArrayInput.js +2 -2
- package/ui/input/ArrayInput.tsx +2 -1
- package/ui/input/ArrayRadioInputs.d.ts +1 -1
- package/ui/input/ArrayRadioInputs.js +2 -2
- package/ui/input/ArrayRadioInputs.tsx +2 -1
- package/ui/input/ButtonInput.d.ts +1 -1
- package/ui/input/ButtonInput.js +2 -2
- package/ui/input/ButtonInput.tsx +2 -1
- package/ui/input/CheckboxInput.d.ts +1 -1
- package/ui/input/CheckboxInput.js +2 -2
- package/ui/input/CheckboxInput.tsx +2 -0
- package/ui/input/ChoiceRadioInputs.js +2 -2
- package/ui/input/ChoiceRadioInputs.tsx +2 -1
- package/ui/input/DataInput.js +2 -2
- package/ui/input/DataInput.tsx +2 -1
- package/ui/input/DateInput.d.ts +1 -1
- package/ui/input/DateInput.js +2 -2
- package/ui/input/DateInput.tsx +2 -1
- package/ui/input/DictionaryInput.js +2 -2
- package/ui/input/DictionaryInput.tsx +2 -1
- package/ui/input/FileInput.d.ts +1 -1
- package/ui/input/FileInput.js +3 -2
- package/ui/input/FileInput.tsx +3 -1
- package/ui/input/Input.d.ts +10 -3
- package/ui/input/Input.js +2 -2
- package/ui/input/Input.tsx +11 -4
- package/ui/input/NumberInput.d.ts +1 -1
- package/ui/input/NumberInput.js +2 -2
- package/ui/input/NumberInput.tsx +2 -1
- package/ui/input/OutputInput.d.ts +1 -1
- package/ui/input/OutputInput.js +2 -2
- package/ui/input/OutputInput.tsx +2 -2
- package/ui/input/Popover.d.ts +4 -2
- package/ui/input/Popover.js +4 -3
- package/ui/input/Popover.tsx +6 -3
- package/ui/input/PopoverButton.d.ts +28 -0
- package/ui/input/{ButtonPopover.js → PopoverButton.js} +10 -8
- package/ui/input/PopoverButton.tsx +44 -0
- package/ui/input/PopoverButtonInput.d.ts +27 -0
- package/ui/input/{ButtonInputPopover.js → PopoverButtonInput.js} +10 -8
- package/ui/input/PopoverButtonInput.tsx +44 -0
- package/ui/input/QueryInput.d.ts +1 -1
- package/ui/input/QueryInput.js +2 -2
- package/ui/input/QueryInput.tsx +2 -0
- package/ui/input/RadioInput.d.ts +1 -1
- package/ui/input/RadioInput.js +2 -2
- package/ui/input/RadioInput.tsx +2 -0
- package/ui/input/SchemaInput.d.ts +1 -1
- package/ui/input/SchemaInput.js +2 -2
- package/ui/input/SchemaInput.tsx +2 -2
- package/ui/input/SelectInput.js +2 -2
- package/ui/input/SelectInput.tsx +2 -1
- package/ui/input/TextInput.d.ts +1 -1
- package/ui/input/TextInput.js +3 -3
- package/ui/input/TextInput.tsx +3 -2
- package/ui/input/index.d.ts +2 -2
- package/ui/input/index.js +2 -2
- package/ui/input/index.ts +2 -2
- package/ui/menu/Menu.d.ts +5 -5
- package/ui/menu/Menu.js +4 -4
- package/ui/menu/Menu.tsx +7 -6
- package/ui/misc/Icon.d.ts +2 -1
- package/ui/misc/Icon.js +2 -1
- package/ui/misc/Icon.tsx +3 -1
- package/ui/misc/Loading.d.ts +2 -3
- package/ui/misc/Loading.js +2 -2
- package/ui/misc/Loading.tsx +10 -3
- package/ui/misc/Tag.d.ts +3 -2
- package/ui/misc/Tag.js +2 -2
- package/ui/misc/Tag.tsx +4 -3
- package/ui/notice/Message.d.ts +3 -3
- package/ui/notice/Message.js +2 -2
- package/ui/notice/Message.tsx +4 -3
- package/ui/notice/Notice.d.ts +3 -3
- package/ui/notice/Notice.js +2 -2
- package/ui/notice/Notice.tsx +4 -2
- package/ui/notice/Notices.d.ts +3 -2
- package/ui/notice/Notices.js +2 -2
- package/ui/notice/Notices.tsx +4 -3
- package/ui/table/Cell.d.ts +3 -3
- package/ui/table/Cell.js +2 -2
- package/ui/table/Cell.tsx +4 -3
- package/ui/table/Table.d.ts +3 -3
- package/ui/table/Table.js +2 -2
- package/ui/table/Table.tsx +4 -3
- package/ui/tree/TreeBreadcrumbs.d.ts +3 -2
- package/ui/tree/TreeBreadcrumbs.js +2 -2
- package/ui/tree/TreeBreadcrumbs.tsx +4 -2
- package/ui/tree/TreeButton.d.ts +2 -1
- package/ui/tree/TreeButton.tsx +2 -1
- package/ui/util/ClassProps.md +56 -0
- package/ui/util/css.d.ts +1 -1
- package/ui/util/css.js +2 -2
- package/ui/util/css.test.ts +29 -0
- package/ui/util/css.ts +2 -2
- package/ui/util/props.d.ts +12 -0
- package/ui/util/props.test.tsx +100 -0
- package/ui/util/props.ts +13 -0
- package/ui/input/ButtonInputPopover.d.ts +0 -25
- package/ui/input/ButtonInputPopover.tsx +0 -41
- package/ui/input/ButtonPopover.d.ts +0 -25
- package/ui/input/ButtonPopover.tsx +0 -40
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
|
-
import type { OptionalChildProps } from "../util/props.js";
|
|
2
|
+
import type { ClassProps, OptionalChildProps } from "../util/props.js";
|
|
3
3
|
/**
|
|
4
4
|
* Props for `Superscript` — optional `children`.
|
|
5
5
|
*
|
|
6
6
|
* @see https://shelving.cc/ui/SuperscriptProps
|
|
7
7
|
*/
|
|
8
|
-
export interface SuperscriptProps extends OptionalChildProps {
|
|
8
|
+
export interface SuperscriptProps extends OptionalChildProps, ClassProps {
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Superscript text — renders a `<sup>` element for typographically raised text (e.g. exponents, footnote markers).
|
|
@@ -14,4 +14,4 @@ export interface SuperscriptProps extends OptionalChildProps {
|
|
|
14
14
|
* @example <>E = mc<Superscript>2</Superscript></>
|
|
15
15
|
* @see https://shelving.cc/ui/Superscript
|
|
16
16
|
*/
|
|
17
|
-
export declare function Superscript({ children }: SuperscriptProps): ReactElement;
|
|
17
|
+
export declare function Superscript({ children, className }: SuperscriptProps): ReactElement;
|
package/ui/inline/Superscript.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { getModuleClass } from "../util/css.js";
|
|
2
|
+
import { getClass, getModuleClass } from "../util/css.js";
|
|
3
3
|
import SUPERSCRIPT_CSS from "./Superscript.module.css";
|
|
4
4
|
const SUPERSCRIPT_CLASS = getModuleClass(SUPERSCRIPT_CSS, "superscript");
|
|
5
5
|
/**
|
|
@@ -9,6 +9,6 @@ const SUPERSCRIPT_CLASS = getModuleClass(SUPERSCRIPT_CSS, "superscript");
|
|
|
9
9
|
* @example <>E = mc<Superscript>2</Superscript></>
|
|
10
10
|
* @see https://shelving.cc/ui/Superscript
|
|
11
11
|
*/
|
|
12
|
-
export function Superscript({ children }) {
|
|
13
|
-
return _jsx("sup", { className: SUPERSCRIPT_CLASS, children: children });
|
|
12
|
+
export function Superscript({ children, className }) {
|
|
13
|
+
return _jsx("sup", { className: getClass(SUPERSCRIPT_CLASS, className), children: children });
|
|
14
14
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
|
-
import { getModuleClass } from "../util/css.js";
|
|
3
|
-
import type { OptionalChildProps } from "../util/props.js";
|
|
2
|
+
import { getClass, getModuleClass } from "../util/css.js";
|
|
3
|
+
import type { ClassProps, OptionalChildProps } from "../util/props.js";
|
|
4
4
|
import SUPERSCRIPT_CSS from "./Superscript.module.css";
|
|
5
5
|
|
|
6
6
|
const SUPERSCRIPT_CLASS = getModuleClass(SUPERSCRIPT_CSS, "superscript");
|
|
@@ -10,7 +10,7 @@ const SUPERSCRIPT_CLASS = getModuleClass(SUPERSCRIPT_CSS, "superscript");
|
|
|
10
10
|
*
|
|
11
11
|
* @see https://shelving.cc/ui/SuperscriptProps
|
|
12
12
|
*/
|
|
13
|
-
export interface SuperscriptProps extends OptionalChildProps {}
|
|
13
|
+
export interface SuperscriptProps extends OptionalChildProps, ClassProps {}
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Superscript text — renders a `<sup>` element for typographically raised text (e.g. exponents, footnote markers).
|
|
@@ -19,6 +19,6 @@ export interface SuperscriptProps extends OptionalChildProps {}
|
|
|
19
19
|
* @example <>E = mc<Superscript>2</Superscript></>
|
|
20
20
|
* @see https://shelving.cc/ui/Superscript
|
|
21
21
|
*/
|
|
22
|
-
export function Superscript({ children }: SuperscriptProps): ReactElement {
|
|
23
|
-
return <sup className={SUPERSCRIPT_CLASS}>{children}</sup>;
|
|
22
|
+
export function Superscript({ children, className }: SuperscriptProps): ReactElement {
|
|
23
|
+
return <sup className={getClass(SUPERSCRIPT_CLASS, className)}>{children}</sup>;
|
|
24
24
|
}
|
package/ui/input/ArrayInput.js
CHANGED
|
@@ -10,12 +10,12 @@ import { ButtonInput } from "./ButtonInput.js";
|
|
|
10
10
|
import { SchemaInput } from "./SchemaInput.js";
|
|
11
11
|
export function ArrayInput({ name,
|
|
12
12
|
// title,
|
|
13
|
-
placeholder, required = false, disabled = false, message = "", value = [], onValue, one = "item", many = `${one}s`, min = 0, max = Number.POSITIVE_INFINITY, items, }) {
|
|
13
|
+
placeholder, required = false, disabled = false, message = "", value = [], onValue, one = "item", many = `${one}s`, min = 0, max = Number.POSITIVE_INFINITY, items, className, }) {
|
|
14
14
|
const messages = splitMessage(message);
|
|
15
15
|
const length = value.length;
|
|
16
16
|
const disableRemove = disabled || length <= min;
|
|
17
17
|
const addNewItem = () => onValue([...value, items.value]);
|
|
18
|
-
return (_jsxs(Column, { children: [length ? (value.map((v, i) => {
|
|
18
|
+
return (_jsxs(Column, { className: className, children: [length ? (value.map((v, i) => {
|
|
19
19
|
const k = i.toString();
|
|
20
20
|
return (_jsxs(Row, { children: [_jsx(SchemaInput, { name: k, schema: items, value: v, onValue: x => onValue(withArrayIndex(value, i, x)), message: messages[k], disabled: disabled }), _jsx(Button, { onClick: () => onValue(omitArrayIndex(value, i)), disabled: disableRemove, title: disableRemove ? `Minimum ${formatUnit(min, one, { unitDisplay: "long", one, many })}` : `Remove ${one}`, children: _jsx(XMarkIcon, {}) })] }, k));
|
|
21
21
|
})) : (_jsx(ButtonInput, { onClick: addNewItem, name: name, required: required && min > 1, disabled: disabled, children: placeholder })), _jsxs(Row, { children: [_jsxs(Button //
|
package/ui/input/ArrayInput.tsx
CHANGED
|
@@ -50,13 +50,14 @@ export function ArrayInput({
|
|
|
50
50
|
min = 0,
|
|
51
51
|
max = Number.POSITIVE_INFINITY,
|
|
52
52
|
items,
|
|
53
|
+
className,
|
|
53
54
|
}: ArrayInputProps<unknown>): ReactElement {
|
|
54
55
|
const messages = splitMessage(message);
|
|
55
56
|
const length = value.length;
|
|
56
57
|
const disableRemove = disabled || length <= min;
|
|
57
58
|
const addNewItem = () => onValue([...value, items.value]);
|
|
58
59
|
return (
|
|
59
|
-
<Column>
|
|
60
|
+
<Column className={className}>
|
|
60
61
|
{length ? (
|
|
61
62
|
value.map((v, i) => {
|
|
62
63
|
const k = i.toString();
|
|
@@ -21,4 +21,4 @@ export interface ArrayRadioInputsProps<T> extends ValueInputProps<T> {
|
|
|
21
21
|
* @example <ArrayRadioInputs name="size" items={["s", "m", "l"]} value={size} onValue={setSize} />
|
|
22
22
|
* @see https://shelving.cc/ui/ArrayRadioInputs
|
|
23
23
|
*/
|
|
24
|
-
export declare function ArrayRadioInputs<T>({ value, onValue, required, items, formatter, ...props }: ArrayRadioInputsProps<T>): ReactElement;
|
|
24
|
+
export declare function ArrayRadioInputs<T>({ value, onValue, required, items, formatter, className, ...props }: ArrayRadioInputsProps<T>): ReactElement;
|
|
@@ -11,8 +11,8 @@ import { RadioInput } from "./RadioInput.js";
|
|
|
11
11
|
* @example <ArrayRadioInputs name="size" items={["s", "m", "l"]} value={size} onValue={setSize} />
|
|
12
12
|
* @see https://shelving.cc/ui/ArrayRadioInputs
|
|
13
13
|
*/
|
|
14
|
-
export function ArrayRadioInputs({ value, onValue, required = false, items, formatter = formatValue, ...props }) {
|
|
15
|
-
return (_jsxs(Column, { children: [items.map((v, i) => {
|
|
14
|
+
export function ArrayRadioInputs({ value, onValue, required = false, items, formatter = formatValue, className, ...props }) {
|
|
15
|
+
return (_jsxs(Column, { className: className, children: [items.map((v, i) => {
|
|
16
16
|
return (_jsx(RadioInput //
|
|
17
17
|
, { value: value === v, onValue: () => onValue(v), required: required, ...props, children: formatter(v) }, i.toString()));
|
|
18
18
|
}), !required ? (_jsx(RadioInput //
|
|
@@ -31,10 +31,11 @@ export function ArrayRadioInputs<T>({
|
|
|
31
31
|
required = false,
|
|
32
32
|
items,
|
|
33
33
|
formatter = formatValue,
|
|
34
|
+
className,
|
|
34
35
|
...props
|
|
35
36
|
}: ArrayRadioInputsProps<T>): ReactElement {
|
|
36
37
|
return (
|
|
37
|
-
<Column>
|
|
38
|
+
<Column className={className}>
|
|
38
39
|
{items.map((v, i) => {
|
|
39
40
|
return (
|
|
40
41
|
<RadioInput //
|
|
@@ -18,4 +18,4 @@ export interface ButtonInputProps extends InputProps, ClickableProps, FlexVarian
|
|
|
18
18
|
* @example <ButtonInput name="choose" onClick={open}>Choose…</ButtonInput>
|
|
19
19
|
* @see https://shelving.cc/ui/ButtonInput
|
|
20
20
|
*/
|
|
21
|
-
export declare function ButtonInput({ title, placeholder, children, ...props }: ButtonInputProps): ReactElement;
|
|
21
|
+
export declare function ButtonInput({ title, placeholder, children, className, ...props }: ButtonInputProps): ReactElement;
|
package/ui/input/ButtonInput.js
CHANGED
|
@@ -14,7 +14,7 @@ import INPUT_CSS from "./Input.module.css";
|
|
|
14
14
|
* @example <ButtonInput name="choose" onClick={open}>Choose…</ButtonInput>
|
|
15
15
|
* @see https://shelving.cc/ui/ButtonInput
|
|
16
16
|
*/
|
|
17
|
-
export function ButtonInput({ title, placeholder, children = title, ...props }) {
|
|
17
|
+
export function ButtonInput({ title, placeholder, children = title, className, ...props }) {
|
|
18
18
|
const hasChildren = notNullish(children);
|
|
19
|
-
return (_jsx(Clickable, { ...props, className: getClass(getInputClass(props), getModuleClass(INPUT_CSS, "button"), getFlexClass(props), hasChildren && getModuleClass(INPUT_CSS, "placeholder")), children: hasChildren ? children : placeholder }));
|
|
19
|
+
return (_jsx(Clickable, { ...props, className: getClass(getInputClass(props), getModuleClass(INPUT_CSS, "button"), getFlexClass(props), hasChildren && getModuleClass(INPUT_CSS, "placeholder"), className), children: hasChildren ? children : placeholder }));
|
|
20
20
|
}
|
package/ui/input/ButtonInput.tsx
CHANGED
|
@@ -22,7 +22,7 @@ export interface ButtonInputProps extends InputProps, ClickableProps, FlexVarian
|
|
|
22
22
|
* @example <ButtonInput name="choose" onClick={open}>Choose…</ButtonInput>
|
|
23
23
|
* @see https://shelving.cc/ui/ButtonInput
|
|
24
24
|
*/
|
|
25
|
-
export function ButtonInput({ title, placeholder, children = title, ...props }: ButtonInputProps): ReactElement {
|
|
25
|
+
export function ButtonInput({ title, placeholder, children = title, className, ...props }: ButtonInputProps): ReactElement {
|
|
26
26
|
const hasChildren = notNullish(children);
|
|
27
27
|
return (
|
|
28
28
|
<Clickable
|
|
@@ -32,6 +32,7 @@ export function ButtonInput({ title, placeholder, children = title, ...props }:
|
|
|
32
32
|
getModuleClass(INPUT_CSS, "button"),
|
|
33
33
|
getFlexClass(props),
|
|
34
34
|
hasChildren && getModuleClass(INPUT_CSS, "placeholder"),
|
|
35
|
+
className,
|
|
35
36
|
)}
|
|
36
37
|
>
|
|
37
38
|
{hasChildren ? children : placeholder}
|
|
@@ -17,4 +17,4 @@ export interface CheckboxProps extends ValueInputProps<boolean>, OptionalChildPr
|
|
|
17
17
|
* @example <CheckboxInput name="agree" value={agree} onValue={setAgree}>I agree</CheckboxInput>
|
|
18
18
|
* @see https://shelving.cc/ui/CheckboxInput
|
|
19
19
|
*/
|
|
20
|
-
export declare function CheckboxInput({ name, title, placeholder, required, disabled, message, value, onValue, children, ...props }: CheckboxProps): ReactElement;
|
|
20
|
+
export declare function CheckboxInput({ name, title, placeholder, required, disabled, message, value, onValue, children, className, ...props }: CheckboxProps): ReactElement;
|
|
@@ -12,7 +12,7 @@ const INPUT_LABEL_CLASS = getModuleClass(INPUT_CSS, "label");
|
|
|
12
12
|
* @example <CheckboxInput name="agree" value={agree} onValue={setAgree}>I agree</CheckboxInput>
|
|
13
13
|
* @see https://shelving.cc/ui/CheckboxInput
|
|
14
14
|
*/
|
|
15
|
-
export function CheckboxInput({ name, title, placeholder = title || "Yes", required = false, disabled = false, message = "", value = false, onValue, children = placeholder, ...props }) {
|
|
15
|
+
export function CheckboxInput({ name, title, placeholder = title || "Yes", required = false, disabled = false, message = "", value = false, onValue, children = placeholder, className, ...props }) {
|
|
16
16
|
return (_jsxs("label", { className: getClass(getInputClass(props), //
|
|
17
|
-
getFlexClass(props), INPUT_LABEL_CLASS), children: [_jsx("input", { className: getModuleClass(INPUT_CSS, "radio"), type: "checkbox", name: name, defaultChecked: !!value, onChange: e => onValue?.(!!e.currentTarget.checked), disabled: disabled, required: required, title: message, "aria-invalid": !!message }), _jsx("span", { children: children })] }));
|
|
17
|
+
getFlexClass(props), INPUT_LABEL_CLASS, className), children: [_jsx("input", { className: getModuleClass(INPUT_CSS, "radio"), type: "checkbox", name: name, defaultChecked: !!value, onChange: e => onValue?.(!!e.currentTarget.checked), disabled: disabled, required: required, title: message, "aria-invalid": !!message }), _jsx("span", { children: children })] }));
|
|
18
18
|
}
|
|
@@ -32,6 +32,7 @@ export function CheckboxInput({
|
|
|
32
32
|
value = false,
|
|
33
33
|
onValue,
|
|
34
34
|
children = placeholder,
|
|
35
|
+
className,
|
|
35
36
|
...props
|
|
36
37
|
}: CheckboxProps): ReactElement {
|
|
37
38
|
return (
|
|
@@ -40,6 +41,7 @@ export function CheckboxInput({
|
|
|
40
41
|
getInputClass(props), //
|
|
41
42
|
getFlexClass(props),
|
|
42
43
|
INPUT_LABEL_CLASS,
|
|
44
|
+
className,
|
|
43
45
|
)}
|
|
44
46
|
>
|
|
45
47
|
<input
|
|
@@ -4,10 +4,10 @@ import { Row } from "../block/Row.js";
|
|
|
4
4
|
import { RadioInput } from "./RadioInput.js";
|
|
5
5
|
/** Maximum number of options to show in a row. */
|
|
6
6
|
const MAX_ROW_OPTIONS = 2;
|
|
7
|
-
export function ChoiceRadioInputs({ required = false, value = "", onValue, wrap = false, column, options, ...props }) {
|
|
7
|
+
export function ChoiceRadioInputs({ required = false, value = "", onValue, wrap = false, column, options, className, ...props }) {
|
|
8
8
|
const entries = getProps(options);
|
|
9
9
|
const hasMany = entries.length > MAX_ROW_OPTIONS;
|
|
10
|
-
return (_jsxs(Row, { wrap: wrap, column: column ?? hasMany, children: [entries.map(([k, t]) => (_jsx(RadioInput //
|
|
10
|
+
return (_jsxs(Row, { wrap: wrap, column: column ?? hasMany, className: className, children: [entries.map(([k, t]) => (_jsx(RadioInput //
|
|
11
11
|
, { value: value === k, onValue: () => onValue(k), required: required, ...props, children: t }, k))), !required ? (_jsx(RadioInput //
|
|
12
12
|
, { value: !value, onValue: () => onValue(undefined), required: required, ...props })) : null] }));
|
|
13
13
|
}
|
|
@@ -40,12 +40,13 @@ export function ChoiceRadioInputs({
|
|
|
40
40
|
wrap = false,
|
|
41
41
|
column,
|
|
42
42
|
options,
|
|
43
|
+
className,
|
|
43
44
|
...props
|
|
44
45
|
}: ChoiceRadioInputsProps<string>): ReactElement {
|
|
45
46
|
const entries = getProps(options);
|
|
46
47
|
const hasMany = entries.length > MAX_ROW_OPTIONS;
|
|
47
48
|
return (
|
|
48
|
-
<Row wrap={wrap} column={column ?? hasMany}>
|
|
49
|
+
<Row wrap={wrap} column={column ?? hasMany} className={className}>
|
|
49
50
|
{entries.map(([k, t]) => (
|
|
50
51
|
<RadioInput //
|
|
51
52
|
key={k}
|
package/ui/input/DataInput.js
CHANGED
|
@@ -9,9 +9,9 @@ export function DataInput({
|
|
|
9
9
|
// placeholder,
|
|
10
10
|
// required = false,
|
|
11
11
|
// disabled = false,
|
|
12
|
-
message = "", value = {}, onValue, props, }) {
|
|
12
|
+
message = "", value = {}, onValue, props, className, }) {
|
|
13
13
|
const messages = splitMessage(message);
|
|
14
14
|
const entries = getProps(props);
|
|
15
|
-
return (_jsx(Row, { column: entries.length > 2, children: entries.map(([k, s]) => (_jsx(SchemaInput //
|
|
15
|
+
return (_jsx(Row, { column: entries.length > 2, className: className, children: entries.map(([k, s]) => (_jsx(SchemaInput //
|
|
16
16
|
, { name: k, schema: s, value: value[k], onValue: x => onValue(withProp(value, k, x)), message: messages[k] }, k))) }));
|
|
17
17
|
}
|
package/ui/input/DataInput.tsx
CHANGED
|
@@ -37,11 +37,12 @@ export function DataInput({
|
|
|
37
37
|
value = {},
|
|
38
38
|
onValue,
|
|
39
39
|
props,
|
|
40
|
+
className,
|
|
40
41
|
}: DataInputProps<Data>): ReactElement {
|
|
41
42
|
const messages = splitMessage(message);
|
|
42
43
|
const entries = getProps(props);
|
|
43
44
|
return (
|
|
44
|
-
<Row column={entries.length > 2}>
|
|
45
|
+
<Row column={entries.length > 2} className={className}>
|
|
45
46
|
{entries.map(([k, s]) => (
|
|
46
47
|
<SchemaInput //
|
|
47
48
|
key={k}
|
package/ui/input/DateInput.d.ts
CHANGED
|
@@ -22,4 +22,4 @@ export interface DateInputProps extends ValueInputProps<string, PossibleDate>, I
|
|
|
22
22
|
* @see https://shelving.cc/ui/DateInput
|
|
23
23
|
*/
|
|
24
24
|
export declare function DateInput({ name, title, placeholder, // Placeholder must be defined or `:placeholder-shown` CSS rules won't show.
|
|
25
|
-
required, disabled, message, value, onValue, min, max, input, step, ...variants }: DateInputProps): ReactElement;
|
|
25
|
+
required, disabled, message, value, onValue, min, max, input, step, className, ...variants }: DateInputProps): ReactElement;
|
package/ui/input/DateInput.js
CHANGED
|
@@ -18,10 +18,10 @@ const _DATE_TO_STRING = {
|
|
|
18
18
|
* @see https://shelving.cc/ui/DateInput
|
|
19
19
|
*/
|
|
20
20
|
export function DateInput({ name, title = "", placeholder = title, // Placeholder must be defined or `:placeholder-shown` CSS rules won't show.
|
|
21
|
-
required = false, disabled = false, message = "", value, onValue, min, max, input = "date", step, ...variants }) {
|
|
21
|
+
required = false, disabled = false, message = "", value, onValue, min, max, input = "date", step, className, ...variants }) {
|
|
22
22
|
const onChange = (e) => {
|
|
23
23
|
onValue?.(e.currentTarget.value ?? undefined);
|
|
24
24
|
};
|
|
25
25
|
const dateToString = _DATE_TO_STRING[input];
|
|
26
|
-
return (_jsx("input", { name: name, type: input, min: dateToString(min), max: dateToString(max), disabled: disabled, required: required, defaultValue: dateToString(value), placeholder: placeholder || " ", className: getClass(getInputClass(variants), getModuleClass(INPUT_CSS, "text")), onChange: onChange, onInput: onChange, title: message, "aria-invalid": !!message, step: step }));
|
|
26
|
+
return (_jsx("input", { name: name, type: input, min: dateToString(min), max: dateToString(max), disabled: disabled, required: required, defaultValue: dateToString(value), placeholder: placeholder || " ", className: getClass(getInputClass(variants), getModuleClass(INPUT_CSS, "text"), className), onChange: onChange, onInput: onChange, title: message, "aria-invalid": !!message, step: step }));
|
|
27
27
|
}
|
package/ui/input/DateInput.tsx
CHANGED
|
@@ -45,6 +45,7 @@ export function DateInput({
|
|
|
45
45
|
max,
|
|
46
46
|
input = "date",
|
|
47
47
|
step,
|
|
48
|
+
className,
|
|
48
49
|
...variants
|
|
49
50
|
}: DateInputProps): ReactElement {
|
|
50
51
|
const onChange = (e: SyntheticEvent<HTMLInputElement>) => {
|
|
@@ -63,7 +64,7 @@ export function DateInput({
|
|
|
63
64
|
required={required}
|
|
64
65
|
defaultValue={dateToString(value)}
|
|
65
66
|
placeholder={placeholder || " "}
|
|
66
|
-
className={getClass(getInputClass(variants), getModuleClass(INPUT_CSS, "text"))}
|
|
67
|
+
className={getClass(getInputClass(variants), getModuleClass(INPUT_CSS, "text"), className)}
|
|
67
68
|
onChange={onChange}
|
|
68
69
|
onInput={onChange}
|
|
69
70
|
title={message}
|
|
@@ -11,12 +11,12 @@ import { SchemaInput } from "./SchemaInput.js";
|
|
|
11
11
|
import { TextInput } from "./TextInput.js";
|
|
12
12
|
export function DictionaryInput({ name,
|
|
13
13
|
// title,
|
|
14
|
-
placeholder, required = false, disabled = false, message = "", value = {}, onValue, one = "item", many = `${one}s`, min = 0, max = Number.POSITIVE_INFINITY, items, }) {
|
|
14
|
+
placeholder, required = false, disabled = false, message = "", value = {}, onValue, one = "item", many = `${one}s`, min = 0, max = Number.POSITIVE_INFINITY, items, className, }) {
|
|
15
15
|
const messages = splitMessage(message);
|
|
16
16
|
const length = Object.keys(value).length;
|
|
17
17
|
const disableRemove = disabled || length <= min;
|
|
18
18
|
const addNewItem = () => onValue({ ...value, [one]: items.value });
|
|
19
|
-
return (_jsxs(Row, { column: true, children: [length ? (Object.entries(value).map(([k, v], i) => {
|
|
19
|
+
return (_jsxs(Row, { column: true, className: className, children: [length ? (Object.entries(value).map(([k, v], i) => {
|
|
20
20
|
const r = i.toString();
|
|
21
21
|
const message = messages[r];
|
|
22
22
|
return (_jsxs(Row, { children: [_jsx(TextInput, { name: `${r}-key`, value: k, onValue: x => {
|
|
@@ -52,13 +52,14 @@ export function DictionaryInput({
|
|
|
52
52
|
min = 0,
|
|
53
53
|
max = Number.POSITIVE_INFINITY,
|
|
54
54
|
items,
|
|
55
|
+
className,
|
|
55
56
|
}: DictionaryInputProps<unknown>): ReactElement {
|
|
56
57
|
const messages = splitMessage(message);
|
|
57
58
|
const length = Object.keys(value).length;
|
|
58
59
|
const disableRemove = disabled || length <= min;
|
|
59
60
|
const addNewItem = () => onValue({ ...value, [one]: items.value });
|
|
60
61
|
return (
|
|
61
|
-
<Row column>
|
|
62
|
+
<Row column className={className}>
|
|
62
63
|
{length ? (
|
|
63
64
|
Object.entries(value).map(([k, v], i) => {
|
|
64
65
|
const r = i.toString();
|
package/ui/input/FileInput.d.ts
CHANGED
|
@@ -17,4 +17,4 @@ export interface FileInputProps extends ValueInputProps<string | File>, InputVar
|
|
|
17
17
|
* @example <FileInput name="avatar" types={{ png: "image/png" }} onValue={setFile} />
|
|
18
18
|
* @see https://shelving.cc/ui/FileInput
|
|
19
19
|
*/
|
|
20
|
-
export declare function FileInput({ name, title, placeholder, required, disabled, message, onValue, types, ...variants }: FileInputProps): ReactElement;
|
|
20
|
+
export declare function FileInput({ name, title, placeholder, required, disabled, message, onValue, types, className, ...variants }: FileInputProps): ReactElement;
|
package/ui/input/FileInput.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { getClass } from "../util/css.js";
|
|
2
3
|
import { getInputClass } from "./Input.js";
|
|
3
4
|
/**
|
|
4
5
|
* File picker input that emits the selected `File` through `onValue`.
|
|
@@ -10,12 +11,12 @@ import { getInputClass } from "./Input.js";
|
|
|
10
11
|
*/
|
|
11
12
|
export function FileInput({ name, title, placeholder = title, required = false, disabled = false, message,
|
|
12
13
|
// value,
|
|
13
|
-
onValue, types = {}, ...variants }) {
|
|
14
|
+
onValue, types = {}, className, ...variants }) {
|
|
14
15
|
const onChange = (e) => {
|
|
15
16
|
const files = e.currentTarget.files;
|
|
16
17
|
if (files)
|
|
17
18
|
for (const file of files)
|
|
18
19
|
onValue(file);
|
|
19
20
|
};
|
|
20
|
-
return (_jsx("input", { name: name, type: "file", accept: Object.values(types).join(","), required: required, disabled: disabled, placeholder: placeholder, className: getInputClass(variants), onChange: onChange, onInput: onChange, multiple: false, title: message, "aria-invalid": !!message }));
|
|
21
|
+
return (_jsx("input", { name: name, type: "file", accept: Object.values(types).join(","), required: required, disabled: disabled, placeholder: placeholder, className: getClass(getInputClass(variants), className), onChange: onChange, onInput: onChange, multiple: false, title: message, "aria-invalid": !!message }));
|
|
21
22
|
}
|
package/ui/input/FileInput.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactElement, SyntheticEvent } from "react";
|
|
2
2
|
import type { FileTypes } from "../../util/file.js";
|
|
3
|
+
import { getClass } from "../util/css.js";
|
|
3
4
|
import { getInputClass, type InputVariants, type ValueInputProps } from "./Input.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -29,6 +30,7 @@ export function FileInput({
|
|
|
29
30
|
// value,
|
|
30
31
|
onValue,
|
|
31
32
|
types = {},
|
|
33
|
+
className,
|
|
32
34
|
...variants
|
|
33
35
|
}: FileInputProps): ReactElement {
|
|
34
36
|
const onChange = (e: SyntheticEvent<HTMLInputElement>) => {
|
|
@@ -44,7 +46,7 @@ export function FileInput({
|
|
|
44
46
|
required={required}
|
|
45
47
|
disabled={disabled}
|
|
46
48
|
placeholder={placeholder}
|
|
47
|
-
className={getInputClass(variants)}
|
|
49
|
+
className={getClass(getInputClass(variants), className)}
|
|
48
50
|
onChange={onChange}
|
|
49
51
|
onInput={onChange}
|
|
50
52
|
multiple={false}
|
package/ui/input/Input.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { type WidthVariants } from "../style/Width.js";
|
|
3
|
-
import type { ChildProps } from "../util/props.js";
|
|
3
|
+
import type { ChildProps, ClassProps } from "../util/props.js";
|
|
4
4
|
/**
|
|
5
5
|
* Styling variants shared by every form input — currently the `width` variant (`width="narrow"`, `"normal"`, `"wide"`, `"full"`, `"fit"`).
|
|
6
6
|
* - Extends `WidthVariants` so any input can be sized (e.g. `<CheckboxInput width="fit">` to shrink to its content).
|
|
@@ -23,7 +23,7 @@ export declare function getInputClass(props: InputVariants): string;
|
|
|
23
23
|
*
|
|
24
24
|
* @see https://shelving.cc/ui/InputProps
|
|
25
25
|
*/
|
|
26
|
-
export interface InputProps {
|
|
26
|
+
export interface InputProps extends ClassProps {
|
|
27
27
|
/** The `name=""` prop of the input. */
|
|
28
28
|
name: string;
|
|
29
29
|
/** Friendly title for the input. */
|
|
@@ -46,9 +46,16 @@ export interface ValueInputProps<O, I = never> extends InputProps {
|
|
|
46
46
|
}
|
|
47
47
|
/** Input that is loading. */
|
|
48
48
|
export declare const LOADING_INPUT: import("react").JSX.Element;
|
|
49
|
+
/**
|
|
50
|
+
* Props for `InputWrapper` — the wrapped `children` plus an optional `className`.
|
|
51
|
+
*
|
|
52
|
+
* @see https://shelving.cc/ui/InputWrapperProps
|
|
53
|
+
*/
|
|
54
|
+
export interface InputWrapperProps extends ChildProps, ClassProps {
|
|
55
|
+
}
|
|
49
56
|
/**
|
|
50
57
|
* Wraps an input with support for absolutely-positioned `data-slot` icon elements on either side.
|
|
51
58
|
* - This is so you can put an icon before or after an input.
|
|
52
59
|
* @kind component
|
|
53
60
|
*/
|
|
54
|
-
export declare function InputWrapper({ children }:
|
|
61
|
+
export declare function InputWrapper({ children, className }: InputWrapperProps): ReactElement;
|
package/ui/input/Input.js
CHANGED
|
@@ -21,6 +21,6 @@ export const LOADING_INPUT = _jsx("div", { className: getClass(getInputClass({})
|
|
|
21
21
|
* - This is so you can put an icon before or after an input.
|
|
22
22
|
* @kind component
|
|
23
23
|
*/
|
|
24
|
-
export function InputWrapper({ children }) {
|
|
25
|
-
return _jsx("div", { className: getClass(getInputClass({}), getModuleClass(INPUT_CSS, "wrapper")), children: children });
|
|
24
|
+
export function InputWrapper({ children, className }) {
|
|
25
|
+
return _jsx("div", { className: getClass(getInputClass({}), getModuleClass(INPUT_CSS, "wrapper"), className), children: children });
|
|
26
26
|
}
|
package/ui/input/Input.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { LOADING } from "../misc/Loading.js";
|
|
|
3
3
|
import { getFlexClass } from "../style/Flex.js";
|
|
4
4
|
import { getWidthClass, type WidthVariants } from "../style/Width.js";
|
|
5
5
|
import { getClass, getModuleClass } from "../util/css.js";
|
|
6
|
-
import type { ChildProps } from "../util/props.js";
|
|
6
|
+
import type { ChildProps, ClassProps } from "../util/props.js";
|
|
7
7
|
import INPUT_CSS from "./Input.module.css";
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -31,7 +31,7 @@ export function getInputClass(props: InputVariants): string {
|
|
|
31
31
|
*
|
|
32
32
|
* @see https://shelving.cc/ui/InputProps
|
|
33
33
|
*/
|
|
34
|
-
export interface InputProps {
|
|
34
|
+
export interface InputProps extends ClassProps {
|
|
35
35
|
/** The `name=""` prop of the input. */
|
|
36
36
|
name: string;
|
|
37
37
|
/** Friendly title for the input. */
|
|
@@ -57,11 +57,18 @@ export interface ValueInputProps<O, I = never> extends InputProps {
|
|
|
57
57
|
/** Input that is loading. */
|
|
58
58
|
export const LOADING_INPUT = <div className={getClass(getInputClass({}), getFlexClass({}))}>{LOADING}</div>;
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Props for `InputWrapper` — the wrapped `children` plus an optional `className`.
|
|
62
|
+
*
|
|
63
|
+
* @see https://shelving.cc/ui/InputWrapperProps
|
|
64
|
+
*/
|
|
65
|
+
export interface InputWrapperProps extends ChildProps, ClassProps {}
|
|
66
|
+
|
|
60
67
|
/**
|
|
61
68
|
* Wraps an input with support for absolutely-positioned `data-slot` icon elements on either side.
|
|
62
69
|
* - This is so you can put an icon before or after an input.
|
|
63
70
|
* @kind component
|
|
64
71
|
*/
|
|
65
|
-
export function InputWrapper({ children }:
|
|
66
|
-
return <div className={getClass(getInputClass({}), getModuleClass(INPUT_CSS, "wrapper"))}>{children}</div>;
|
|
72
|
+
export function InputWrapper({ children, className }: InputWrapperProps): ReactElement {
|
|
73
|
+
return <div className={getClass(getInputClass({}), getModuleClass(INPUT_CSS, "wrapper"), className)}>{children}</div>;
|
|
67
74
|
}
|
|
@@ -21,5 +21,5 @@ export interface NumberInputProps extends ValueInputProps<number>, InputVariants
|
|
|
21
21
|
* @see https://shelving.cc/ui/NumberInput
|
|
22
22
|
*/
|
|
23
23
|
export declare function NumberInput({ name, title, placeholder, // Placeholder must be defined or `:placeholder-shown` CSS rules won't show.
|
|
24
|
-
required, disabled, message, value, onValue, formatter, ...variants }: NumberInputProps): ReactElement;
|
|
24
|
+
required, disabled, message, value, onValue, formatter, className, ...variants }: NumberInputProps): ReactElement;
|
|
25
25
|
export {};
|
package/ui/input/NumberInput.js
CHANGED
|
@@ -16,7 +16,7 @@ export function NumberInput({ name, title = "", placeholder = title, // Placehol
|
|
|
16
16
|
required = false, disabled = false, message = "", value, onValue,
|
|
17
17
|
// min = Number.NEGATIVE_INFINITY,
|
|
18
18
|
// max = Number.POSITIVE_INFINITY,
|
|
19
|
-
formatter = formatNumber, ...variants }) {
|
|
19
|
+
formatter = formatNumber, className, ...variants }) {
|
|
20
20
|
const onChange = ({ currentTarget }) => {
|
|
21
21
|
onValue?.(getNumber(currentTarget.value) ?? undefined);
|
|
22
22
|
};
|
|
@@ -24,5 +24,5 @@ formatter = formatNumber, ...variants }) {
|
|
|
24
24
|
const num = getNumber(currentTarget.value);
|
|
25
25
|
currentTarget.value = num !== undefined ? formatter(num) : "";
|
|
26
26
|
};
|
|
27
|
-
return (_jsx("input", { name: name, type: "text", inputMode: "decimal", defaultValue: value !== undefined ? formatter(value) : "", required: required, disabled: disabled, placeholder: placeholder || " ", className: getClass(getInputClass(variants), getModuleClass(INPUT_CSS, "text")), onChange: onChange, onInput: onChange, onBlur: onBlur, title: message, "aria-invalid": !!message }));
|
|
27
|
+
return (_jsx("input", { name: name, type: "text", inputMode: "decimal", defaultValue: value !== undefined ? formatter(value) : "", required: required, disabled: disabled, placeholder: placeholder || " ", className: getClass(getInputClass(variants), getModuleClass(INPUT_CSS, "text"), className), onChange: onChange, onInput: onChange, onBlur: onBlur, title: message, "aria-invalid": !!message }));
|
|
28
28
|
}
|
package/ui/input/NumberInput.tsx
CHANGED
|
@@ -39,6 +39,7 @@ export function NumberInput({
|
|
|
39
39
|
// min = Number.NEGATIVE_INFINITY,
|
|
40
40
|
// max = Number.POSITIVE_INFINITY,
|
|
41
41
|
formatter = formatNumber,
|
|
42
|
+
className,
|
|
42
43
|
...variants
|
|
43
44
|
}: NumberInputProps): ReactElement {
|
|
44
45
|
const onChange = ({ currentTarget }: SyntheticEvent<HTMLInputElement>) => {
|
|
@@ -59,7 +60,7 @@ export function NumberInput({
|
|
|
59
60
|
required={required}
|
|
60
61
|
disabled={disabled}
|
|
61
62
|
placeholder={placeholder || " "}
|
|
62
|
-
className={getClass(getInputClass(variants), getModuleClass(INPUT_CSS, "text"))}
|
|
63
|
+
className={getClass(getInputClass(variants), getModuleClass(INPUT_CSS, "text"), className)}
|
|
63
64
|
onChange={onChange}
|
|
64
65
|
onInput={onChange}
|
|
65
66
|
onBlur={onBlur}
|
|
@@ -17,4 +17,4 @@ export interface OutputInputProps extends InputProps, OptionalChildProps, FlexVa
|
|
|
17
17
|
* @example <OutputInput title="Status">Active</OutputInput>
|
|
18
18
|
* @see https://shelving.cc/ui/OutputInput
|
|
19
19
|
*/
|
|
20
|
-
export declare function OutputInput({ title, placeholder, children, ...props }: OutputInputProps): ReactElement;
|
|
20
|
+
export declare function OutputInput({ title, placeholder, children, className, ...props }: OutputInputProps): ReactElement;
|
package/ui/input/OutputInput.js
CHANGED
|
@@ -12,7 +12,7 @@ import INPUT_CSS from "./Input.module.css";
|
|
|
12
12
|
* @example <OutputInput title="Status">Active</OutputInput>
|
|
13
13
|
* @see https://shelving.cc/ui/OutputInput
|
|
14
14
|
*/
|
|
15
|
-
export function OutputInput({ title, placeholder, children = title, ...props }) {
|
|
15
|
+
export function OutputInput({ title, placeholder, children = title, className, ...props }) {
|
|
16
16
|
const hasChildren = notNullish(children);
|
|
17
|
-
return (_jsx("output", { ...props, className: getClass(getInputClass(props), getFlexClass(props), hasChildren && getModuleClass(INPUT_CSS, "placeholder")), children: hasChildren ? children : placeholder }));
|
|
17
|
+
return (_jsx("output", { ...props, className: getClass(getInputClass(props), getFlexClass(props), hasChildren && getModuleClass(INPUT_CSS, "placeholder"), className), children: hasChildren ? children : placeholder }));
|
|
18
18
|
}
|
package/ui/input/OutputInput.tsx
CHANGED
|
@@ -21,12 +21,12 @@ export interface OutputInputProps extends InputProps, OptionalChildProps, FlexVa
|
|
|
21
21
|
* @example <OutputInput title="Status">Active</OutputInput>
|
|
22
22
|
* @see https://shelving.cc/ui/OutputInput
|
|
23
23
|
*/
|
|
24
|
-
export function OutputInput({ title, placeholder, children = title, ...props }: OutputInputProps): ReactElement {
|
|
24
|
+
export function OutputInput({ title, placeholder, children = title, className, ...props }: OutputInputProps): ReactElement {
|
|
25
25
|
const hasChildren = notNullish(children);
|
|
26
26
|
return (
|
|
27
27
|
<output
|
|
28
28
|
{...props}
|
|
29
|
-
className={getClass(getInputClass(props), getFlexClass(props), hasChildren && getModuleClass(INPUT_CSS, "placeholder"))}
|
|
29
|
+
className={getClass(getInputClass(props), getFlexClass(props), hasChildren && getModuleClass(INPUT_CSS, "placeholder"), className)}
|
|
30
30
|
>
|
|
31
31
|
{hasChildren ? children : placeholder}
|
|
32
32
|
</output>
|
package/ui/input/Popover.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
/** biome-ignore-all lint/a11y/useKeyWithClickEvents: This is fine we're only using this to listen for clicks on child buttons. */
|
|
3
3
|
import type { ReactElement, ReactNode } from "react";
|
|
4
4
|
import type { Callback } from "../../util/function.js";
|
|
5
|
+
import type { ClassProps } from "../util/props.js";
|
|
5
6
|
/**
|
|
6
7
|
* Children tuple for `Popover`: a leading trigger node followed by the popover's contents.
|
|
7
8
|
*
|
|
@@ -23,7 +24,7 @@ export type PopoverChildren = readonly [
|
|
|
23
24
|
*
|
|
24
25
|
* @see https://shelving.cc/ui/PopoverProps
|
|
25
26
|
*/
|
|
26
|
-
export interface PopoverProps {
|
|
27
|
+
export interface PopoverProps extends ClassProps {
|
|
27
28
|
/** Children for the popover. */
|
|
28
29
|
children: PopoverChildren;
|
|
29
30
|
/** Callback that gets called when the Popover closes. */
|
|
@@ -35,6 +36,7 @@ export interface PopoverProps {
|
|
|
35
36
|
* Trigger element that reveals a floating popover panel beside it when active or focused.
|
|
36
37
|
* - The first `children` node is the trigger; the rest become the popover contents.
|
|
37
38
|
* - Closes on blur away or `Escape`, calling `onClose`.
|
|
39
|
+
* - `className` lands on the floating panel rather than the wrapper, since the panel is the surface worth styling.
|
|
38
40
|
*
|
|
39
41
|
* @returns A wrapper element containing the trigger and (when open) the popover panel.
|
|
40
42
|
* @example <Popover>{trigger}{panelContent}</Popover>
|
|
@@ -43,4 +45,4 @@ export interface PopoverProps {
|
|
|
43
45
|
* @todo DH: Would love to use new HTML `popover="auto"` functionality for this but the anchor positioning it needs is not supported everywhere yet.
|
|
44
46
|
*/
|
|
45
47
|
export declare function Popover({ children: [trigger, ...popover], //
|
|
46
|
-
onClose, open, }: PopoverProps): ReactElement;
|
|
48
|
+
onClose, open, className, }: PopoverProps): ReactElement;
|
package/ui/input/Popover.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { isTruthy } from "../../util/boolean.js";
|
|
3
|
-
import { getModuleClass } from "../util/css.js";
|
|
3
|
+
import { getClass, getModuleClass } from "../util/css.js";
|
|
4
4
|
import { eventPreventDefault } from "../util/event.js";
|
|
5
5
|
import { eventLoopFocus } from "../util/focus.js";
|
|
6
6
|
import styles from "./Popover.module.css";
|
|
@@ -8,6 +8,7 @@ import styles from "./Popover.module.css";
|
|
|
8
8
|
* Trigger element that reveals a floating popover panel beside it when active or focused.
|
|
9
9
|
* - The first `children` node is the trigger; the rest become the popover contents.
|
|
10
10
|
* - Closes on blur away or `Escape`, calling `onClose`.
|
|
11
|
+
* - `className` lands on the floating panel rather than the wrapper, since the panel is the surface worth styling.
|
|
11
12
|
*
|
|
12
13
|
* @returns A wrapper element containing the trigger and (when open) the popover panel.
|
|
13
14
|
* @example <Popover>{trigger}{panelContent}</Popover>
|
|
@@ -16,11 +17,11 @@ import styles from "./Popover.module.css";
|
|
|
16
17
|
* @todo DH: Would love to use new HTML `popover="auto"` functionality for this but the anchor positioning it needs is not supported everywhere yet.
|
|
17
18
|
*/
|
|
18
19
|
export function Popover({ children: [trigger, ...popover], //
|
|
19
|
-
onClose, open = popover.flat().some(isTruthy), }) {
|
|
20
|
+
onClose, open = popover.flat().some(isTruthy), className, }) {
|
|
20
21
|
return (_jsxs("div", { className: getModuleClass(styles, "wrap"), onBlur: e => {
|
|
21
22
|
if (e.relatedTarget)
|
|
22
23
|
eventLoopFocus(e);
|
|
23
24
|
else
|
|
24
25
|
onClose?.();
|
|
25
|
-
}, onKeyDown: e => e.key === "Escape" && onClose?.(), children: [trigger, open ? (_jsx("section", { className: getModuleClass(styles, "panel"), onMouseDown: eventPreventDefault, children: popover })) : null] }));
|
|
26
|
+
}, onKeyDown: e => e.key === "Escape" && onClose?.(), children: [trigger, open ? (_jsx("section", { className: getClass(getModuleClass(styles, "panel"), className), onMouseDown: eventPreventDefault, children: popover })) : null] }));
|
|
26
27
|
}
|