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
package/ui/block/Subheading.js
CHANGED
|
@@ -10,8 +10,8 @@ const SUBHEADING_CLASS = getModuleClass(SUBHEADING_CSS, "subheading");
|
|
|
10
10
|
* @kind component
|
|
11
11
|
* @see https://shelving.cc/ui/Subheading
|
|
12
12
|
*/
|
|
13
|
-
export function Subheading({ level = "3", children, ...props }) {
|
|
13
|
+
export function Subheading({ level = "3", children, className, ...props }) {
|
|
14
14
|
const Element = `h${level}`;
|
|
15
15
|
return (_jsx(Element, { className: getClass(SUBHEADING_CLASS, //
|
|
16
|
-
getBlockClass(props)), children: children }));
|
|
16
|
+
getBlockClass(props), className), children: children }));
|
|
17
17
|
}
|
package/ui/block/Subheading.tsx
CHANGED
|
@@ -20,13 +20,14 @@ export type SubheadingProps = HeadingProps;
|
|
|
20
20
|
* @kind component
|
|
21
21
|
* @see https://shelving.cc/ui/Subheading
|
|
22
22
|
*/
|
|
23
|
-
export function Subheading({ level = "3", children, ...props }: SubheadingProps): ReactElement {
|
|
23
|
+
export function Subheading({ level = "3", children, className, ...props }: SubheadingProps): ReactElement {
|
|
24
24
|
const Element: `h${typeof level}` = `h${level}`;
|
|
25
25
|
return (
|
|
26
26
|
<Element
|
|
27
27
|
className={getClass(
|
|
28
28
|
SUBHEADING_CLASS, //
|
|
29
29
|
getBlockClass(props),
|
|
30
|
+
className,
|
|
30
31
|
)}
|
|
31
32
|
>
|
|
32
33
|
{children}
|
package/ui/block/Title.d.ts
CHANGED
|
@@ -13,4 +13,4 @@ export type TitleProps = HeadingProps;
|
|
|
13
13
|
* @kind component
|
|
14
14
|
* @see https://shelving.cc/ui/Title
|
|
15
15
|
*/
|
|
16
|
-
export declare function Title({ level, children, ...props }: TitleProps): ReactElement;
|
|
16
|
+
export declare function Title({ level, children, className, ...props }: TitleProps): ReactElement;
|
package/ui/block/Title.js
CHANGED
|
@@ -10,8 +10,8 @@ const TITLE_CLASS = getModuleClass(TITLE_CSS, "title");
|
|
|
10
10
|
* @kind component
|
|
11
11
|
* @see https://shelving.cc/ui/Title
|
|
12
12
|
*/
|
|
13
|
-
export function Title({ level = "1", children, ...props }) {
|
|
13
|
+
export function Title({ level = "1", children, className, ...props }) {
|
|
14
14
|
const Element = `h${level}`;
|
|
15
15
|
return (_jsx(Element, { className: getClass(TITLE_CLASS, //
|
|
16
|
-
getBlockClass(props)), children: children }));
|
|
16
|
+
getBlockClass(props), className), children: children }));
|
|
17
17
|
}
|
package/ui/block/Title.tsx
CHANGED
|
@@ -20,13 +20,14 @@ export type TitleProps = HeadingProps;
|
|
|
20
20
|
* @kind component
|
|
21
21
|
* @see https://shelving.cc/ui/Title
|
|
22
22
|
*/
|
|
23
|
-
export function Title({ level = "1", children, ...props }: TitleProps): ReactElement {
|
|
23
|
+
export function Title({ level = "1", children, className, ...props }: TitleProps): ReactElement {
|
|
24
24
|
const Element: `h${typeof level}` = `h${level}`;
|
|
25
25
|
return (
|
|
26
26
|
<Element
|
|
27
27
|
className={getClass(
|
|
28
28
|
TITLE_CLASS, //
|
|
29
29
|
getBlockClass(props),
|
|
30
|
+
className,
|
|
30
31
|
)}
|
|
31
32
|
>
|
|
32
33
|
{children}
|
package/ui/block/Video.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { type ReactElement } from "react";
|
|
2
2
|
import type { SpaceVariants } from "../style/Space.js";
|
|
3
3
|
import type { WidthVariants } from "../style/Width.js";
|
|
4
|
-
import type { OptionalChildProps } from "../util/props.js";
|
|
4
|
+
import type { ClassProps, OptionalChildProps } from "../util/props.js";
|
|
5
5
|
/**
|
|
6
6
|
* Props for `Video` — space and width variants plus optional `children`.
|
|
7
7
|
*
|
|
8
8
|
* @see https://shelving.cc/ui/VideoProps
|
|
9
9
|
*/
|
|
10
|
-
export interface VideoProps extends SpaceVariants, WidthVariants, OptionalChildProps {
|
|
10
|
+
export interface VideoProps extends SpaceVariants, WidthVariants, OptionalChildProps, ClassProps {
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Video container element.
|
|
@@ -18,4 +18,4 @@ export interface VideoProps extends SpaceVariants, WidthVariants, OptionalChildP
|
|
|
18
18
|
* @example <Video><video src="/clip.mp4" /></Video>
|
|
19
19
|
* @see https://shelving.cc/ui/Video
|
|
20
20
|
*/
|
|
21
|
-
export declare function Video({ children, ...props }: VideoProps): ReactElement;
|
|
21
|
+
export declare function Video({ children, className, ...props }: VideoProps): ReactElement;
|
package/ui/block/Video.js
CHANGED
|
@@ -13,8 +13,8 @@ const VIDEO_CLASS = getModuleClass(VIDEO_CSS, "video");
|
|
|
13
13
|
* @example <Video><video src="/clip.mp4" /></Video>
|
|
14
14
|
* @see https://shelving.cc/ui/Video
|
|
15
15
|
*/
|
|
16
|
-
export function Video({ children, ...props }) {
|
|
16
|
+
export function Video({ children, className, ...props }) {
|
|
17
17
|
const ref = useRef(null);
|
|
18
18
|
return (_jsx("figure", { ref: ref, className: getClass(VIDEO_CLASS, //
|
|
19
|
-
getBlockClass(props)), children: children }));
|
|
19
|
+
getBlockClass(props), className), children: children }));
|
|
20
20
|
}
|
package/ui/block/Video.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { getBlockClass } from "../style/Block.js";
|
|
|
3
3
|
import type { SpaceVariants } from "../style/Space.js";
|
|
4
4
|
import type { WidthVariants } from "../style/Width.js";
|
|
5
5
|
import { getClass, getModuleClass } from "../util/css.js";
|
|
6
|
-
import type { OptionalChildProps } from "../util/props.js";
|
|
6
|
+
import type { ClassProps, OptionalChildProps } from "../util/props.js";
|
|
7
7
|
import VIDEO_CSS from "./Video.module.css";
|
|
8
8
|
|
|
9
9
|
const VIDEO_CLASS = getModuleClass(VIDEO_CSS, "video");
|
|
@@ -13,7 +13,7 @@ const VIDEO_CLASS = getModuleClass(VIDEO_CSS, "video");
|
|
|
13
13
|
*
|
|
14
14
|
* @see https://shelving.cc/ui/VideoProps
|
|
15
15
|
*/
|
|
16
|
-
export interface VideoProps extends SpaceVariants, WidthVariants, OptionalChildProps {}
|
|
16
|
+
export interface VideoProps extends SpaceVariants, WidthVariants, OptionalChildProps, ClassProps {}
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Video container element.
|
|
@@ -24,7 +24,7 @@ export interface VideoProps extends SpaceVariants, WidthVariants, OptionalChildP
|
|
|
24
24
|
* @example <Video><video src="/clip.mp4" /></Video>
|
|
25
25
|
* @see https://shelving.cc/ui/Video
|
|
26
26
|
*/
|
|
27
|
-
export function Video({ children, ...props }: VideoProps): ReactElement {
|
|
27
|
+
export function Video({ children, className, ...props }: VideoProps): ReactElement {
|
|
28
28
|
const ref = useRef<HTMLElement | null>(null);
|
|
29
29
|
|
|
30
30
|
return (
|
|
@@ -33,6 +33,7 @@ export function Video({ children, ...props }: VideoProps): ReactElement {
|
|
|
33
33
|
className={getClass(
|
|
34
34
|
VIDEO_CLASS, //
|
|
35
35
|
getBlockClass(props),
|
|
36
|
+
className,
|
|
36
37
|
)}
|
|
37
38
|
>
|
|
38
39
|
{children}
|
package/ui/button/Button.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ReactElement } from "react";
|
|
|
2
2
|
import { type FlexVariants } from "../style/Flex.js";
|
|
3
3
|
import { type StatusVariants } from "../style/Status.js";
|
|
4
4
|
import { type TypographyVariants } from "../style/Typography.js";
|
|
5
|
+
import type { ClassProps } from "../util/props.js";
|
|
5
6
|
import { type ClickableProps } from "./Clickable.js";
|
|
6
7
|
/**
|
|
7
8
|
* Styling variants for a `Button`, combining flex, color, status, and typography options with button-specific toggles.
|
|
@@ -33,7 +34,7 @@ export declare function getButtonClass(variants: ButtonVariants): string;
|
|
|
33
34
|
*
|
|
34
35
|
* @see https://shelving.cc/ui/ButtonProps
|
|
35
36
|
*/
|
|
36
|
-
export interface ButtonProps extends ButtonVariants, ClickableProps {
|
|
37
|
+
export interface ButtonProps extends ButtonVariants, ClickableProps, ClassProps {
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
40
|
* Render either a `<button>` or an `<a href="">` styled as a button, based on whether an `onClick` or `href` prop is provided.
|
|
@@ -43,4 +44,4 @@ export interface ButtonProps extends ButtonVariants, ClickableProps {
|
|
|
43
44
|
* @kind component
|
|
44
45
|
* @see https://shelving.cc/ui/Button
|
|
45
46
|
*/
|
|
46
|
-
export declare function Button(props: ButtonProps): ReactElement;
|
|
47
|
+
export declare function Button({ className, ...props }: ButtonProps): ReactElement;
|
package/ui/button/Button.js
CHANGED
|
@@ -23,6 +23,6 @@ export function getButtonClass(variants) {
|
|
|
23
23
|
* @kind component
|
|
24
24
|
* @see https://shelving.cc/ui/Button
|
|
25
25
|
*/
|
|
26
|
-
export function Button(props) {
|
|
27
|
-
return _jsx(Clickable, { ...props, className: getButtonClass(props) });
|
|
26
|
+
export function Button({ className, ...props }) {
|
|
27
|
+
return _jsx(Clickable, { ...props, className: getClass(getButtonClass(props), className) });
|
|
28
28
|
}
|
package/ui/button/Button.md
CHANGED
|
@@ -8,6 +8,7 @@ A clickable styled as a solid button. Renders an `<a href="">` when given `href`
|
|
|
8
8
|
- `strong` marks the default action in a form — a filled background instead of an outline. `plain` and `outline` drop the background until hover/focus.
|
|
9
9
|
- `color=` / `status=` move the tint anchor, so the background, border and label re-derive from the same ladder; `small` tightens the padding.
|
|
10
10
|
- `getButtonClass(variants)` returns the same `className` the component composes — use it to style a non-`<button>` element as a button when `Button` itself doesn't fit.
|
|
11
|
+
- `className` attaches an app class to one button, merged after the computed classes so an app stylesheet wins — see `ClassProps`.
|
|
11
12
|
|
|
12
13
|
## Usage
|
|
13
14
|
|
|
@@ -33,6 +34,15 @@ import { Row } from "shelving/ui";
|
|
|
33
34
|
</Row>
|
|
34
35
|
```
|
|
35
36
|
|
|
37
|
+
### A one-off treatment
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { Button } from "shelving/ui";
|
|
41
|
+
|
|
42
|
+
// `.spongy-press` lives in the app's own stylesheet — use it for what the theme hooks below can't express.
|
|
43
|
+
<Button className="spongy-press" strong onClick={claim}>Claim</Button>
|
|
44
|
+
```
|
|
45
|
+
|
|
36
46
|
### Reusing the button class
|
|
37
47
|
|
|
38
48
|
```tsx
|
|
@@ -50,11 +60,14 @@ import { getButtonClass } from "shelving/ui";
|
|
|
50
60
|
|
|
51
61
|
`--button-padding` and `--button-small-padding` set the `padding` shorthand, so a single value pads both axes equally and a two-value override pads block and inline separately (e.g. `var(--space-small) var(--space-normal)`).
|
|
52
62
|
|
|
63
|
+
`--button-shadow`, `--button-hover-transform` and the `--button-active-*` pressed-state hooks are static and apply to every button, with one exception: `plain` and `outline` never paint a box shadow in any state — they have no fill until hover, so a raised edge under them reads broken. The hover and pressed transforms still apply to them, so all buttons move together. `--button-transition` already covers animating the press and release.
|
|
64
|
+
|
|
53
65
|
| Variable | Styles | Default |
|
|
54
66
|
|---|---|---|
|
|
55
67
|
| `--button-background` | Surface fill | `var(--tint-90)` |
|
|
56
68
|
| `--button-hover-background` | Surface fill on hover / focus | `var(--tint-95)` |
|
|
57
69
|
| `--button-hover-border` | Border on hover / focus | `var(--button-stroke) solid var(--tint-90)` |
|
|
70
|
+
| `--button-hover-transform` | Transform on hover / focus | `none` |
|
|
58
71
|
| `--button-text` | Label colour | `var(--tint-50)` |
|
|
59
72
|
| `--button-border` | Border shorthand | `var(--button-stroke) solid var(--tint-80)` |
|
|
60
73
|
| `--button-stroke` | Border / outline thickness | `var(--stroke-normal)` (2px) |
|
|
@@ -68,6 +81,11 @@ import { getButtonClass } from "shelving/ui";
|
|
|
68
81
|
| `--button-weight` | Font weight | `var(--weight-strong)` (700) |
|
|
69
82
|
| `--button-size` | Font size | `var(--size-normal)` |
|
|
70
83
|
| `--button-leading` | Line height | `var(--leading)` |
|
|
84
|
+
| `--button-shadow` | Box shadow (never on `plain` / `outline`) | `none` |
|
|
85
|
+
| `--button-active-background` | Surface fill while pressed | `var(--button-hover-background)` |
|
|
86
|
+
| `--button-active-border` | Border while pressed | `var(--button-hover-border)` |
|
|
87
|
+
| `--button-active-shadow` | Box shadow while pressed | `var(--button-shadow)` |
|
|
88
|
+
| `--button-active-transform` | Transform while pressed | `var(--button-hover-transform)` |
|
|
71
89
|
| `--button-transition` | Transition | `all var(--duration-fast)` (150ms) |
|
|
72
90
|
| `--button-focus-border` | Focus outline | `var(--stroke-focus) solid var(--color-focus)` |
|
|
73
91
|
| `--button-disabled-opacity` | Opacity when disabled | `0.5` |
|
|
@@ -84,3 +102,13 @@ import { getButtonClass } from "shelving/ui";
|
|
|
84
102
|
--button-padding: var(--space-small) var(--space-normal);
|
|
85
103
|
}
|
|
86
104
|
```
|
|
105
|
+
|
|
106
|
+
```css
|
|
107
|
+
/* Theme: buttons are raised and press down flat — `plain` and `outline` press down too but never cast a shadow. */
|
|
108
|
+
:root {
|
|
109
|
+
--button-shadow: 0 0.25rem 0 var(--tint-80);
|
|
110
|
+
--button-active-transform: translateY(0.2rem);
|
|
111
|
+
--button-active-shadow: 0 0.05rem 0 var(--tint-80);
|
|
112
|
+
--button-transition: all var(--duration-fast) cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
113
|
+
}
|
|
114
|
+
```
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
/* Style. */
|
|
32
32
|
background: var(--button-background, var(--tint-90));
|
|
33
33
|
color: var(--button-text, var(--tint-50));
|
|
34
|
+
box-shadow: var(--button-shadow, none);
|
|
34
35
|
transition: var(--button-transition, all var(--duration-fast));
|
|
35
36
|
cursor: pointer;
|
|
36
37
|
outline: var(--button-focus-border, var(--stroke-focus) solid var(--color-focus));
|
|
@@ -55,6 +56,15 @@
|
|
|
55
56
|
&:focus:not(:focus-visible) {
|
|
56
57
|
border: var(--button-hover-border, var(--button-stroke, var(--stroke-normal)) solid var(--tint-90));
|
|
57
58
|
background: var(--button-hover-background, var(--tint-95));
|
|
59
|
+
transform: var(--button-hover-transform, none);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&:enabled:active,
|
|
63
|
+
&:any-link:active {
|
|
64
|
+
border: var(--button-active-border, var(--button-hover-border, var(--button-stroke, var(--stroke-normal)) solid var(--tint-90)));
|
|
65
|
+
background: var(--button-active-background, var(--button-hover-background, var(--tint-95)));
|
|
66
|
+
transform: var(--button-active-transform, var(--button-hover-transform, none));
|
|
67
|
+
box-shadow: var(--button-active-shadow, var(--button-shadow, none));
|
|
58
68
|
}
|
|
59
69
|
|
|
60
70
|
/* Variants */
|
|
@@ -101,13 +111,21 @@
|
|
|
101
111
|
border-color: transparent;
|
|
102
112
|
}
|
|
103
113
|
|
|
104
|
-
&.plain
|
|
105
|
-
|
|
106
|
-
|
|
114
|
+
&.plain {
|
|
115
|
+
box-shadow: none;
|
|
116
|
+
|
|
117
|
+
&:not(:enabled:hover, :any-link:hover, :focus) {
|
|
118
|
+
border-color: transparent;
|
|
119
|
+
background: transparent;
|
|
120
|
+
}
|
|
107
121
|
}
|
|
108
122
|
|
|
109
|
-
&.outline
|
|
110
|
-
|
|
123
|
+
&.outline {
|
|
124
|
+
box-shadow: none;
|
|
125
|
+
|
|
126
|
+
&:not(:enabled:hover, :any-link:hover, :focus) {
|
|
127
|
+
background: transparent;
|
|
128
|
+
}
|
|
111
129
|
}
|
|
112
130
|
}
|
|
113
131
|
}
|
package/ui/button/Button.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { type FlexVariants, getFlexClass } from "../style/Flex.js";
|
|
|
3
3
|
import { getStatusClass, type StatusVariants } from "../style/Status.js";
|
|
4
4
|
import { getTypographyClass, type TypographyVariants } from "../style/Typography.js";
|
|
5
5
|
import { getClass, getModuleClass } from "../util/css.js";
|
|
6
|
+
import type { ClassProps } from "../util/props.js";
|
|
6
7
|
import BUTTON_CSS from "./Button.module.css";
|
|
7
8
|
import { Clickable, type ClickableProps } from "./Clickable.js";
|
|
8
9
|
|
|
@@ -45,7 +46,7 @@ export function getButtonClass(variants: ButtonVariants): string {
|
|
|
45
46
|
*
|
|
46
47
|
* @see https://shelving.cc/ui/ButtonProps
|
|
47
48
|
*/
|
|
48
|
-
export interface ButtonProps extends ButtonVariants, ClickableProps {}
|
|
49
|
+
export interface ButtonProps extends ButtonVariants, ClickableProps, ClassProps {}
|
|
49
50
|
|
|
50
51
|
/**
|
|
51
52
|
* Render either a `<button>` or an `<a href="">` styled as a button, based on whether an `onClick` or `href` prop is provided.
|
|
@@ -55,6 +56,6 @@ export interface ButtonProps extends ButtonVariants, ClickableProps {}
|
|
|
55
56
|
* @kind component
|
|
56
57
|
* @see https://shelving.cc/ui/Button
|
|
57
58
|
*/
|
|
58
|
-
export function Button(props: ButtonProps): ReactElement {
|
|
59
|
-
return <Clickable {...props} className={getButtonClass(props)} />;
|
|
59
|
+
export function Button({ className, ...props }: ButtonProps): ReactElement {
|
|
60
|
+
return <Clickable {...props} className={getClass(getButtonClass(props), className)} />;
|
|
60
61
|
}
|
package/ui/button/Clickable.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { MouseEvent, ReactElement, ReactNode } from "react";
|
|
2
2
|
import type { Path } from "../../util/path.js";
|
|
3
3
|
import type { ImmutableURI, URIString } from "../../util/uri.js";
|
|
4
|
-
import type { OptionalChildProps } from "../util/props.js";
|
|
4
|
+
import type { ClassProps, OptionalChildProps } from "../util/props.js";
|
|
5
5
|
/**
|
|
6
6
|
* Handler for a clickable `onClick` event.
|
|
7
7
|
* - Returned value (if defined) is notified to the user using `notifySuccess()`
|
|
@@ -36,12 +36,12 @@ export interface ClickableProps extends OptionalChildProps {
|
|
|
36
36
|
*
|
|
37
37
|
* @see https://shelving.cc/ui/StylableClickableProps
|
|
38
38
|
*/
|
|
39
|
-
export interface StylableClickableProps extends ClickableProps {
|
|
40
|
-
className?: string | undefined;
|
|
39
|
+
export interface StylableClickableProps extends ClickableProps, ClassProps {
|
|
41
40
|
}
|
|
42
41
|
/**
|
|
43
42
|
* Render either a `<button>`, an `<a href="">`, or a plain `<span>` based on whether an `onClick` or `href` prop is provided.
|
|
44
43
|
* - `href` renders a `LinkClickable`; `onClick` renders a `ButtonClickable`; neither renders a `SpanClickable`.
|
|
44
|
+
* - Dispatches on defined values (not key presence) so wrappers can always spread `href={href}` through, even when it's `undefined`.
|
|
45
45
|
*
|
|
46
46
|
* @kind component
|
|
47
47
|
* @example <Clickable href="/about">About</Clickable>
|
package/ui/button/Clickable.js
CHANGED
|
@@ -6,10 +6,12 @@ import { isURLActive } from "../../util/index.js";
|
|
|
6
6
|
import { getLink } from "../../util/link.js";
|
|
7
7
|
import { LOADING } from "../misc/Loading.js";
|
|
8
8
|
import { requireMeta } from "../misc/MetaContext.js";
|
|
9
|
+
import { getClass } from "../util/css.js";
|
|
9
10
|
import { callNotifiedElement } from "../util/notice.js";
|
|
10
11
|
/**
|
|
11
12
|
* Render either a `<button>`, an `<a href="">`, or a plain `<span>` based on whether an `onClick` or `href` prop is provided.
|
|
12
13
|
* - `href` renders a `LinkClickable`; `onClick` renders a `ButtonClickable`; neither renders a `SpanClickable`.
|
|
14
|
+
* - Dispatches on defined values (not key presence) so wrappers can always spread `href={href}` through, even when it's `undefined`.
|
|
13
15
|
*
|
|
14
16
|
* @kind component
|
|
15
17
|
* @example <Clickable href="/about">About</Clickable>
|
|
@@ -17,7 +19,7 @@ import { callNotifiedElement } from "../util/notice.js";
|
|
|
17
19
|
* @see https://shelving.cc/ui/Clickable
|
|
18
20
|
*/
|
|
19
21
|
export function Clickable(props) {
|
|
20
|
-
return
|
|
22
|
+
return props.href !== undefined ? (_jsx(LinkClickable, { ...props })) : props.onClick !== undefined ? (_jsx(ButtonClickable, { ...props })) : (_jsx(SpanClickable, { ...props }));
|
|
21
23
|
}
|
|
22
24
|
/**
|
|
23
25
|
* Render an `<a href="">` element, resolving its `href` against the current page URL and marking it active when it matches.
|
|
@@ -33,7 +35,7 @@ export function LinkClickable({ href, disabled = !href, target, download, title,
|
|
|
33
35
|
const link = disabled ? undefined : getLink(href, url, root);
|
|
34
36
|
// Is this link "active" compared to the current URL?
|
|
35
37
|
const active = isURLActive(link, url);
|
|
36
|
-
return (_jsx("a", { href: link?.href, title: title, download: download, target: target, className: className, "aria-current": active ? "page" : undefined, children: children }));
|
|
38
|
+
return (_jsx("a", { href: link?.href, title: title, download: download, target: target, className: getClass(className) || undefined, "aria-current": active ? "page" : undefined, children: children }));
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
39
41
|
* Render a `<button>` element that runs its `onClick` handler through a `BusyStore` and shows a loading spinner while busy.
|
|
@@ -48,7 +50,7 @@ export function ButtonClickable({ onClick, disabled = !onClick, title, children
|
|
|
48
50
|
const store = useInstance(BusyStore, undefined);
|
|
49
51
|
// Track the `busy/unbusy` state of the button to show a loading spinner appropriately.
|
|
50
52
|
const busy = useStore(store.busy).value;
|
|
51
|
-
return (_jsx("button", { type: "button", title: title, disabled: busy || disabled, className: className, onClick: disabled
|
|
53
|
+
return (_jsx("button", { type: "button", title: title, disabled: busy || disabled, className: getClass(className) || undefined, onClick: disabled
|
|
52
54
|
? undefined
|
|
53
55
|
: e => {
|
|
54
56
|
if (!store.busy.value && onClick) {
|
|
@@ -65,5 +67,5 @@ export function ButtonClickable({ onClick, disabled = !onClick, title, children
|
|
|
65
67
|
*/
|
|
66
68
|
export function SpanClickable({ title, children = "Click", //
|
|
67
69
|
className, }) {
|
|
68
|
-
return (_jsx("span", { title: title, className: className, children: children }));
|
|
70
|
+
return (_jsx("span", { title: title, className: getClass(className) || undefined, children: children }));
|
|
69
71
|
}
|
package/ui/button/Clickable.tsx
CHANGED
|
@@ -8,8 +8,9 @@ import type { Path } from "../../util/path.js";
|
|
|
8
8
|
import type { ImmutableURI, URIString } from "../../util/uri.js";
|
|
9
9
|
import { LOADING } from "../misc/Loading.js";
|
|
10
10
|
import { requireMeta } from "../misc/MetaContext.js";
|
|
11
|
+
import { getClass } from "../util/css.js";
|
|
11
12
|
import { callNotifiedElement } from "../util/notice.js";
|
|
12
|
-
import type { OptionalChildProps } from "../util/props.js";
|
|
13
|
+
import type { ClassProps, OptionalChildProps } from "../util/props.js";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Handler for a clickable `onClick` event.
|
|
@@ -47,13 +48,12 @@ export interface ClickableProps extends OptionalChildProps {
|
|
|
47
48
|
*
|
|
48
49
|
* @see https://shelving.cc/ui/StylableClickableProps
|
|
49
50
|
*/
|
|
50
|
-
export interface StylableClickableProps extends ClickableProps {
|
|
51
|
-
className?: string | undefined;
|
|
52
|
-
}
|
|
51
|
+
export interface StylableClickableProps extends ClickableProps, ClassProps {}
|
|
53
52
|
|
|
54
53
|
/**
|
|
55
54
|
* Render either a `<button>`, an `<a href="">`, or a plain `<span>` based on whether an `onClick` or `href` prop is provided.
|
|
56
55
|
* - `href` renders a `LinkClickable`; `onClick` renders a `ButtonClickable`; neither renders a `SpanClickable`.
|
|
56
|
+
* - Dispatches on defined values (not key presence) so wrappers can always spread `href={href}` through, even when it's `undefined`.
|
|
57
57
|
*
|
|
58
58
|
* @kind component
|
|
59
59
|
* @example <Clickable href="/about">About</Clickable>
|
|
@@ -61,9 +61,9 @@ export interface StylableClickableProps extends ClickableProps {
|
|
|
61
61
|
* @see https://shelving.cc/ui/Clickable
|
|
62
62
|
*/
|
|
63
63
|
export function Clickable(props: StylableClickableProps): ReactElement {
|
|
64
|
-
return
|
|
64
|
+
return props.href !== undefined ? (
|
|
65
65
|
<LinkClickable {...props} />
|
|
66
|
-
) :
|
|
66
|
+
) : props.onClick !== undefined ? (
|
|
67
67
|
<ButtonClickable {...props} />
|
|
68
68
|
) : (
|
|
69
69
|
<SpanClickable {...props} />
|
|
@@ -100,7 +100,7 @@ export function LinkClickable({
|
|
|
100
100
|
title={title}
|
|
101
101
|
download={download}
|
|
102
102
|
target={target}
|
|
103
|
-
className={className}
|
|
103
|
+
className={getClass(className) || undefined}
|
|
104
104
|
aria-current={active ? "page" : undefined}
|
|
105
105
|
>
|
|
106
106
|
{children}
|
|
@@ -134,7 +134,7 @@ export function ButtonClickable({
|
|
|
134
134
|
type="button"
|
|
135
135
|
title={title}
|
|
136
136
|
disabled={busy || disabled}
|
|
137
|
-
className={className}
|
|
137
|
+
className={getClass(className) || undefined}
|
|
138
138
|
onClick={
|
|
139
139
|
disabled
|
|
140
140
|
? undefined
|
|
@@ -165,7 +165,7 @@ export function SpanClickable({
|
|
|
165
165
|
return (
|
|
166
166
|
<span //
|
|
167
167
|
title={title}
|
|
168
|
-
className={className}
|
|
168
|
+
className={getClass(className) || undefined}
|
|
169
169
|
>
|
|
170
170
|
{children}
|
|
171
171
|
</span>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type ReactElement } from "react";
|
|
2
|
+
import type { ClassProps } from "../util/props.js";
|
|
2
3
|
import { type ButtonVariants } from "./Button.js";
|
|
3
4
|
/**
|
|
4
5
|
* Component props for a `<FullscreenButton>`
|
|
5
6
|
*
|
|
6
7
|
* @see https://shelving.cc/ui/FullscreenButtonProps
|
|
7
8
|
*/
|
|
8
|
-
export interface FullscreenButtonProps extends ButtonVariants {
|
|
9
|
+
export interface FullscreenButtonProps extends ButtonVariants, ClassProps {
|
|
9
10
|
/**
|
|
10
11
|
* CSS selector to identify the parent element to toggle fullscreen status on.
|
|
11
12
|
* @default "body, figure"
|
|
@@ -25,7 +26,4 @@ export interface FullscreenButtonProps extends ButtonVariants {
|
|
|
25
26
|
* @example <Video><video src="/clip.mp4" /><FullscreenButton /></Video>
|
|
26
27
|
* @see https://shelving.cc/ui/FullscreenButton
|
|
27
28
|
*/
|
|
28
|
-
export declare function FullscreenButton({ target, ...props }:
|
|
29
|
-
[x: string]: any;
|
|
30
|
-
target?: string | undefined;
|
|
31
|
-
}): ReactElement | null;
|
|
29
|
+
export declare function FullscreenButton({ target, ...props }: FullscreenButtonProps): ReactElement | null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ArrowsPointingInIcon, ArrowsPointingOutIcon } from "@heroicons/react/16/solid";
|
|
2
2
|
import { type ReactElement, useEffect, useState } from "react";
|
|
3
|
+
import type { ClassProps } from "../util/props.js";
|
|
3
4
|
import { Button, type ButtonVariants } from "./Button.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -7,7 +8,7 @@ import { Button, type ButtonVariants } from "./Button.js";
|
|
|
7
8
|
*
|
|
8
9
|
* @see https://shelving.cc/ui/FullscreenButtonProps
|
|
9
10
|
*/
|
|
10
|
-
export interface FullscreenButtonProps extends ButtonVariants {
|
|
11
|
+
export interface FullscreenButtonProps extends ButtonVariants, ClassProps {
|
|
11
12
|
/**
|
|
12
13
|
* CSS selector to identify the parent element to toggle fullscreen status on.
|
|
13
14
|
* @default "body, figure"
|
|
@@ -28,7 +29,7 @@ export interface FullscreenButtonProps extends ButtonVariants {
|
|
|
28
29
|
* @example <Video><video src="/clip.mp4" /><FullscreenButton /></Video>
|
|
29
30
|
* @see https://shelving.cc/ui/FullscreenButton
|
|
30
31
|
*/
|
|
31
|
-
export function FullscreenButton({ target = "body, figure", ...props }): ReactElement | null {
|
|
32
|
+
export function FullscreenButton({ target = "body, figure", ...props }: FullscreenButtonProps): ReactElement | null {
|
|
32
33
|
const [isFull, setFull] = useState(() => typeof document !== "undefined" && !!document.fullscreenElement);
|
|
33
34
|
|
|
34
35
|
useEffect(() => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ReactElement } from "react";
|
|
2
2
|
import type { Callback } from "../../util/function.js";
|
|
3
|
-
import type { OptionalChildProps } from "../util/index.js";
|
|
3
|
+
import type { ClassProps, OptionalChildProps } from "../util/index.js";
|
|
4
4
|
import { type ButtonVariants } from "./Button.js";
|
|
5
5
|
/**
|
|
6
6
|
* Context for providing a "retry" callback to descendant `<RetryButton>` elements.
|
|
@@ -15,7 +15,7 @@ export declare const RetryContext: import("react").Context<Callback | undefined>
|
|
|
15
15
|
*
|
|
16
16
|
* @see https://shelving.cc/ui/RetryButtonProps
|
|
17
17
|
*/
|
|
18
|
-
export interface RetryButtonProps extends ButtonVariants, OptionalChildProps {
|
|
18
|
+
export interface RetryButtonProps extends ButtonVariants, OptionalChildProps, ClassProps {
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Button that retries the nearest `<Catcher>` error boundary when clicked.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ArrowPathIcon } from "@heroicons/react/16/solid";
|
|
2
2
|
import { createContext, type ReactElement, use } from "react";
|
|
3
3
|
import type { Callback } from "../../util/function.js";
|
|
4
|
-
import type { OptionalChildProps } from "../util/index.js";
|
|
4
|
+
import type { ClassProps, OptionalChildProps } from "../util/index.js";
|
|
5
5
|
import { Button, type ButtonVariants } from "./Button.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -19,7 +19,7 @@ RetryContext.displayName = "RetryContext";
|
|
|
19
19
|
*
|
|
20
20
|
* @see https://shelving.cc/ui/RetryButtonProps
|
|
21
21
|
*/
|
|
22
|
-
export interface RetryButtonProps extends ButtonVariants, OptionalChildProps {}
|
|
22
|
+
export interface RetryButtonProps extends ButtonVariants, OptionalChildProps, ClassProps {}
|
|
23
23
|
|
|
24
24
|
const _RETRY_CHILDREN = (
|
|
25
25
|
<>
|
|
@@ -1,5 +1,5 @@
|
|
|
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
|
import { type ButtonVariants } from "./Button.js";
|
|
4
4
|
/**
|
|
5
5
|
* Component props for `<SubmitButton>`, a form submit button.
|
|
@@ -10,7 +10,7 @@ import { type ButtonVariants } from "./Button.js";
|
|
|
10
10
|
*
|
|
11
11
|
* @see https://shelving.cc/ui/SubmitButtonProps
|
|
12
12
|
*/
|
|
13
|
-
export interface SubmitButtonProps extends ButtonVariants, OptionalChildProps {
|
|
13
|
+
export interface SubmitButtonProps extends ButtonVariants, OptionalChildProps, ClassProps {
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* Submit button for a form that disables itself and shows a spinner while the form is busy.
|
|
@@ -20,4 +20,4 @@ export interface SubmitButtonProps extends ButtonVariants, OptionalChildProps {
|
|
|
20
20
|
* @example <SubmitButton>Save changes</SubmitButton>
|
|
21
21
|
* @see https://shelving.cc/ui/SubmitButton
|
|
22
22
|
*/
|
|
23
|
-
export declare function SubmitButton({ children, strong, color, full, ...props }: SubmitButtonProps): ReactElement;
|
|
23
|
+
export declare function SubmitButton({ children, strong, color, full, className, ...props }: SubmitButtonProps): ReactElement;
|
|
@@ -3,6 +3,7 @@ import { ArrowRightIcon } from "@heroicons/react/24/solid";
|
|
|
3
3
|
import { useStore } from "../../react/useStore.js";
|
|
4
4
|
import { requireForm } from "../form/FormContext.js";
|
|
5
5
|
import { LOADING } from "../misc/Loading.js";
|
|
6
|
+
import { getClass } from "../util/css.js";
|
|
6
7
|
import { getButtonClass } from "./Button.js";
|
|
7
8
|
const _SUBMIT_CHILDREN = (_jsxs(_Fragment, { children: ["Save", _jsx(ArrowRightIcon, {})] }));
|
|
8
9
|
/**
|
|
@@ -13,8 +14,8 @@ const _SUBMIT_CHILDREN = (_jsxs(_Fragment, { children: ["Save", _jsx(ArrowRightI
|
|
|
13
14
|
* @example <SubmitButton>Save changes</SubmitButton>
|
|
14
15
|
* @see https://shelving.cc/ui/SubmitButton
|
|
15
16
|
*/
|
|
16
|
-
export function SubmitButton({ children = _SUBMIT_CHILDREN, strong = true, color = "primary", full = true, ...props }) {
|
|
17
|
+
export function SubmitButton({ children = _SUBMIT_CHILDREN, strong = true, color = "primary", full = true, className, ...props }) {
|
|
17
18
|
const form = requireForm();
|
|
18
19
|
const busy = useStore(form.busy).value;
|
|
19
|
-
return (_jsx("button", { type: "submit", disabled: busy, className: getButtonClass({ strong, color, full, ...props }), children: busy ? LOADING : children }));
|
|
20
|
+
return (_jsx("button", { type: "submit", disabled: busy, className: getClass(getButtonClass({ strong, color, full, ...props }), className), children: busy ? LOADING : children }));
|
|
20
21
|
}
|
|
@@ -3,7 +3,8 @@ import type { ReactElement } from "react";
|
|
|
3
3
|
import { useStore } from "../../react/useStore.js";
|
|
4
4
|
import { requireForm } from "../form/FormContext.js";
|
|
5
5
|
import { LOADING } from "../misc/Loading.js";
|
|
6
|
-
import
|
|
6
|
+
import { getClass } from "../util/css.js";
|
|
7
|
+
import type { ClassProps, OptionalChildProps } from "../util/props.js";
|
|
7
8
|
import { type ButtonVariants, getButtonClass } from "./Button.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -15,7 +16,7 @@ import { type ButtonVariants, getButtonClass } from "./Button.js";
|
|
|
15
16
|
*
|
|
16
17
|
* @see https://shelving.cc/ui/SubmitButtonProps
|
|
17
18
|
*/
|
|
18
|
-
export interface SubmitButtonProps extends ButtonVariants, OptionalChildProps {}
|
|
19
|
+
export interface SubmitButtonProps extends ButtonVariants, OptionalChildProps, ClassProps {}
|
|
19
20
|
|
|
20
21
|
const _SUBMIT_CHILDREN = (
|
|
21
22
|
<>
|
|
@@ -37,12 +38,13 @@ export function SubmitButton({
|
|
|
37
38
|
strong = true,
|
|
38
39
|
color = "primary",
|
|
39
40
|
full = true,
|
|
41
|
+
className,
|
|
40
42
|
...props
|
|
41
43
|
}: SubmitButtonProps): ReactElement {
|
|
42
44
|
const form = requireForm();
|
|
43
45
|
const busy = useStore(form.busy).value;
|
|
44
46
|
return (
|
|
45
|
-
<button type="submit" disabled={busy} className={getButtonClass({ strong, color, full, ...props })}>
|
|
47
|
+
<button type="submit" disabled={busy} className={getClass(getButtonClass({ strong, color, full, ...props }), className)}>
|
|
46
48
|
{busy ? LOADING : children}
|
|
47
49
|
</button>
|
|
48
50
|
);
|
package/ui/dialog/Dialog.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ReactElement } from "react";
|
|
2
2
|
import type { Callback } from "../../util/function.js";
|
|
3
|
-
import type
|
|
4
|
-
import type { OptionalChildProps } from "../util/props.js";
|
|
3
|
+
import { type ButtonVariants } from "../button/Button.js";
|
|
4
|
+
import type { ClassProps, OptionalChildProps } from "../util/props.js";
|
|
5
5
|
/**
|
|
6
6
|
* Props for `<Dialog>` — optional `children` content and an `onClose` callback.
|
|
7
7
|
*
|
|
@@ -25,12 +25,14 @@ export declare const Dialog: import("react").MemoExoticComponent<({ children, on
|
|
|
25
25
|
*
|
|
26
26
|
* @see https://shelving.cc/ui/DialogCloseButtonProps
|
|
27
27
|
*/
|
|
28
|
-
export interface DialogCloseButtonProps extends ButtonVariants, OptionalChildProps {
|
|
28
|
+
export interface DialogCloseButtonProps extends ButtonVariants, OptionalChildProps, ClassProps {
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Button that closes its wrapping `<dialog>`, showing an X icon by default.
|
|
32
|
+
* - Styled with the shared `Button` classes (positioning comes from the `<Dialog>`'s own `.close` wrapper rules).
|
|
33
|
+
* - `plain` by default so only the icon shows until hover or focus — pass `plain={false}` for a solid button.
|
|
32
34
|
*
|
|
33
35
|
* @kind component
|
|
34
36
|
* @see https://shelving.cc/ui/DialogCloseButton
|
|
35
37
|
*/
|
|
36
|
-
export declare function DialogCloseButton({ children, ...variants }: DialogCloseButtonProps): ReactElement;
|
|
38
|
+
export declare function DialogCloseButton({ children, plain, className, ...variants }: DialogCloseButtonProps): ReactElement;
|