@yarcl/react 0.1.0 → 0.2.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/README.md +14 -2
- package/{src/apply.ts → dist/apply.d.ts} +4 -23
- package/dist/apply.js +37 -0
- package/dist/classes.d.ts +13 -0
- package/dist/classes.js +22 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +58 -0
- package/dist/color.js +49 -32
- package/dist/components/Accordion.d.ts +96 -0
- package/dist/components/Accordion.js +148 -0
- package/dist/components/Alert.d.ts +60 -0
- package/dist/components/Alert.js +61 -0
- package/dist/components/Avatar.d.ts +100 -0
- package/dist/components/Avatar.js +89 -0
- package/dist/components/Badge.d.ts +44 -0
- package/dist/components/Badge.js +43 -0
- package/dist/components/Breadcrumb.d.ts +77 -0
- package/dist/components/Breadcrumb.js +126 -0
- package/dist/components/Button.d.ts +18 -0
- package/dist/components/Button.js +33 -0
- package/dist/components/ButtonGroup.d.ts +29 -0
- package/dist/components/ButtonGroup.js +37 -0
- package/dist/components/Card.d.ts +36 -0
- package/dist/components/Card.js +26 -0
- package/dist/components/Checkbox.d.ts +28 -0
- package/dist/components/Checkbox.js +38 -0
- package/dist/components/Combobox.d.ts +75 -0
- package/dist/components/Combobox.js +362 -0
- package/dist/components/CommandPalette.d.ts +92 -0
- package/dist/components/CommandPalette.js +293 -0
- package/dist/components/DatePicker.d.ts +157 -0
- package/dist/components/DatePicker.js +230 -0
- package/dist/components/Dialog.d.ts +25 -0
- package/dist/components/Dialog.js +29 -0
- package/dist/components/Divider.d.ts +23 -0
- package/dist/components/Divider.js +25 -0
- package/dist/components/Drawer.d.ts +21 -0
- package/dist/components/Drawer.js +25 -0
- package/dist/components/EmptyState.d.ts +51 -0
- package/dist/components/EmptyState.js +47 -0
- package/dist/components/Field.d.ts +27 -0
- package/dist/components/Field.js +59 -0
- package/dist/components/Heading.d.ts +26 -0
- package/dist/components/Heading.js +25 -0
- package/dist/components/HoverCard.d.ts +47 -0
- package/dist/components/HoverCard.js +53 -0
- package/dist/components/IconButton.d.ts +19 -0
- package/dist/components/IconButton.js +32 -0
- package/dist/components/Inline.d.ts +21 -0
- package/dist/components/Inline.js +24 -0
- package/dist/components/Input.d.ts +19 -0
- package/dist/components/Input.js +25 -0
- package/dist/components/Label.d.ts +46 -0
- package/dist/components/Label.js +33 -0
- package/dist/components/Link.d.ts +27 -0
- package/dist/components/Link.js +26 -0
- package/dist/components/Menu.d.ts +73 -0
- package/dist/components/Menu.js +143 -0
- package/dist/components/Modal.d.ts +45 -0
- package/dist/components/Modal.js +110 -0
- package/dist/components/NumberInput.d.ts +49 -0
- package/dist/components/NumberInput.js +130 -0
- package/dist/components/Pagination.d.ts +86 -0
- package/dist/components/Pagination.js +119 -0
- package/dist/components/Popover.d.ts +72 -0
- package/dist/components/Popover.js +87 -0
- package/dist/components/Progress.d.ts +60 -0
- package/dist/components/Progress.js +59 -0
- package/dist/components/Radio.d.ts +32 -0
- package/dist/components/Radio.js +47 -0
- package/dist/components/RadioGroup.d.ts +57 -0
- package/dist/components/RadioGroup.js +68 -0
- package/dist/components/Select.d.ts +47 -0
- package/dist/components/Select.js +138 -0
- package/dist/components/Skeleton.d.ts +46 -0
- package/dist/components/Skeleton.js +40 -0
- package/dist/components/Slider.d.ts +126 -0
- package/dist/components/Slider.js +166 -0
- package/dist/components/Spinner.d.ts +23 -0
- package/dist/components/Spinner.js +23 -0
- package/dist/components/Stack.d.ts +35 -0
- package/dist/components/Stack.js +24 -0
- package/dist/components/Switch.d.ts +27 -0
- package/dist/components/Switch.js +33 -0
- package/dist/components/Table.d.ts +71 -0
- package/dist/components/Table.js +61 -0
- package/dist/components/Tabs.d.ts +66 -0
- package/dist/components/Tabs.js +109 -0
- package/dist/components/Text.d.ts +32 -0
- package/dist/components/Text.js +28 -0
- package/dist/components/Textarea.d.ts +15 -0
- package/dist/components/Textarea.js +24 -0
- package/dist/components/Toast.d.ts +90 -0
- package/dist/components/Toast.js +156 -0
- package/dist/components/ToggleGroup.d.ts +79 -0
- package/dist/components/ToggleGroup.js +101 -0
- package/dist/components/Tooltip.d.ts +46 -0
- package/dist/components/Tooltip.js +62 -0
- package/dist/components/VisuallyHidden.d.ts +18 -0
- package/dist/components/VisuallyHidden.js +22 -0
- package/dist/contrast.d.ts +32 -0
- package/dist/css.d.ts +2 -2
- package/dist/css.js +193 -157
- package/dist/define.d.ts +40 -15
- package/dist/define.js +30 -27
- package/dist/demo.d.ts +2 -0
- package/dist/demo.js +2 -0
- package/dist/esbuild.cjs +5 -0
- package/dist/esbuild.d.ts +4 -0
- package/dist/esbuild.js +6 -0
- package/dist/field-context.d.ts +16 -0
- package/dist/field-context.js +17 -0
- package/dist/floating.d.ts +12 -0
- package/dist/floating.js +52 -0
- package/dist/hooks.d.ts +1 -0
- package/dist/hooks.js +12 -0
- package/{src/index.ts → dist/index.d.ts} +11 -33
- package/dist/index.js +50 -0
- package/dist/init.d.ts +18 -0
- package/dist/init.js +224 -0
- package/dist/plugin.d.ts +10 -26
- package/dist/plugin.js +152 -78
- package/dist/reference/DemoYarcl.d.ts +12 -0
- package/dist/reference/DemoYarcl.js +312 -0
- package/dist/reference/DesignReference.d.ts +24 -0
- package/dist/reference/DesignReference.js +403 -0
- package/dist/reference/index.js +2 -0
- package/dist/rollup.cjs +5 -0
- package/dist/rollup.d.ts +4 -0
- package/dist/rollup.js +6 -0
- package/dist/rspack.cjs +5 -0
- package/dist/rspack.d.ts +4 -0
- package/dist/rspack.js +6 -0
- package/dist/runtime.d.ts +13 -0
- package/dist/runtime.js +30 -0
- package/dist/setup.d.ts +6 -0
- package/dist/setup.js +33 -0
- package/{src → dist}/styles.css +224 -106
- package/dist/themes/bloom.d.ts +295 -0
- package/dist/themes/bloom.js +202 -0
- package/dist/themes/brutalist.d.ts +277 -0
- package/dist/themes/brutalist.js +199 -0
- package/dist/themes/compact.d.ts +274 -0
- package/dist/themes/compact.js +200 -0
- package/dist/themes/contract.d.ts +23 -0
- package/dist/themes/editorial.d.ts +277 -0
- package/dist/themes/editorial.js +183 -0
- package/dist/themes/index.d.ts +1425 -0
- package/dist/themes/index.js +45 -0
- package/{src/types.ts → dist/types.d.ts} +40 -37
- package/dist/vite.cjs +5 -0
- package/dist/vite.d.ts +4 -0
- package/dist/vite.js +6 -0
- package/dist/webpack.cjs +5 -0
- package/dist/webpack.d.ts +4 -0
- package/dist/webpack.js +6 -0
- package/dist/yarcl.config.d.ts +276 -0
- package/dist/yarcl.config.js +273 -0
- package/package.json +69 -17
- package/src/classes.ts +0 -23
- package/src/color.ts +0 -48
- package/src/components/Accordion.tsx +0 -274
- package/src/components/Alert.tsx +0 -85
- package/src/components/Badge.tsx +0 -79
- package/src/components/Breadcrumb.tsx +0 -239
- package/src/components/Button.tsx +0 -58
- package/src/components/ButtonGroup.tsx +0 -61
- package/src/components/Card.tsx +0 -50
- package/src/components/Checkbox.tsx +0 -49
- package/src/components/Combobox.tsx +0 -522
- package/src/components/CommandPalette.tsx +0 -452
- package/src/components/DatePicker.tsx +0 -432
- package/src/components/Dialog.tsx +0 -39
- package/src/components/Divider.tsx +0 -34
- package/src/components/Drawer.tsx +0 -31
- package/src/components/Field.tsx +0 -61
- package/src/components/Heading.tsx +0 -40
- package/src/components/HoverCard.tsx +0 -108
- package/src/components/IconButton.tsx +0 -59
- package/src/components/Inline.tsx +0 -42
- package/src/components/Input.tsx +0 -28
- package/src/components/Label.tsx +0 -58
- package/src/components/Link.tsx +0 -41
- package/src/components/Menu.tsx +0 -207
- package/src/components/Modal.tsx +0 -164
- package/src/components/NumberInput.tsx +0 -208
- package/src/components/Pagination.tsx +0 -227
- package/src/components/Popover.tsx +0 -140
- package/src/components/Progress.tsx +0 -122
- package/src/components/Radio.tsx +0 -59
- package/src/components/RadioGroup.tsx +0 -114
- package/src/components/Select.tsx +0 -197
- package/src/components/Skeleton.tsx +0 -95
- package/src/components/Slider.tsx +0 -315
- package/src/components/Spinner.tsx +0 -38
- package/src/components/Stack.tsx +0 -57
- package/src/components/Switch.tsx +0 -42
- package/src/components/Table.tsx +0 -99
- package/src/components/Tabs.tsx +0 -159
- package/src/components/Text.tsx +0 -67
- package/src/components/Textarea.tsx +0 -26
- package/src/components/Toast.tsx +0 -190
- package/src/components/ToggleGroup.tsx +0 -227
- package/src/components/Tooltip.tsx +0 -78
- package/src/contrast.ts +0 -82
- package/src/css.ts +0 -228
- package/src/define.check.ts +0 -259
- package/src/define.ts +0 -379
- package/src/field-context.ts +0 -31
- package/src/floating.tsx +0 -61
- package/src/hooks.ts +0 -19
- package/src/plugin.ts +0 -94
- package/src/reference/DesignReference.tsx +0 -374
- package/src/runtime.ts +0 -38
- package/src/themes/bloom.ts +0 -72
- package/src/themes/brutalist.ts +0 -63
- package/src/themes/compact.ts +0 -63
- package/src/themes/contract.ts +0 -24
- package/src/themes/editorial.ts +0 -55
- package/src/themes/index.ts +0 -47
- package/src/yarcl.config.ts +0 -104
- /package/{src/reference/index.ts → dist/reference/index.d.ts} +0 -0
- /package/{src → dist}/reference/reference.css +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useConfig, useDefaults } from "../runtime.js";
|
|
2
|
+
import { colorClass, cx, gapClass, paddingClass, radiusClass, softVariantClass, typeClass } from "../classes.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/Alert.tsx
|
|
5
|
+
/**
|
|
6
|
+
* An inline message that stays on the page, e.g. a warning above a form.
|
|
7
|
+
* For transient messages use {@link toast}.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <Alert color="warning" title="Trial ends in 3 days" action={<Button size="sm">Upgrade</Button>}>
|
|
12
|
+
* Add a payment method to keep your projects.
|
|
13
|
+
* </Alert>
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
function Alert({ title, icon, action, color, variant, radius, gap, padding, textStyle, onDismiss, live, className, children, ...props }) {
|
|
17
|
+
const own = useDefaults("Alert");
|
|
18
|
+
const config = useConfig();
|
|
19
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
20
|
+
role: live === "assertive" ? "alert" : live === "polite" ? "status" : void 0,
|
|
21
|
+
className: cx("yarcl-alert", colorClass(color ?? own.color), softVariantClass(variant ?? own.variant), radiusClass(radius ?? own.radius), gapClass(gap ?? own.gap), paddingClass(padding ?? own.padding), typeClass(textStyle ?? own.textStyle ?? config.defaults.labelStyle), className),
|
|
22
|
+
...props,
|
|
23
|
+
children: [
|
|
24
|
+
icon != null && /* @__PURE__ */ jsx("span", {
|
|
25
|
+
className: "yarcl-alert-icon",
|
|
26
|
+
children: icon
|
|
27
|
+
}),
|
|
28
|
+
/* @__PURE__ */ jsxs("div", {
|
|
29
|
+
className: "yarcl-alert-text",
|
|
30
|
+
children: [title != null && /* @__PURE__ */ jsx("div", {
|
|
31
|
+
className: "yarcl-alert-title",
|
|
32
|
+
children: title
|
|
33
|
+
}), children != null && /* @__PURE__ */ jsx("div", {
|
|
34
|
+
className: "yarcl-alert-body",
|
|
35
|
+
children
|
|
36
|
+
})]
|
|
37
|
+
}),
|
|
38
|
+
action != null && /* @__PURE__ */ jsx("div", {
|
|
39
|
+
className: "yarcl-alert-action",
|
|
40
|
+
children: action
|
|
41
|
+
}),
|
|
42
|
+
onDismiss && /* @__PURE__ */ jsx("button", {
|
|
43
|
+
type: "button",
|
|
44
|
+
className: "yarcl-alert-dismiss",
|
|
45
|
+
"aria-label": "Dismiss",
|
|
46
|
+
onClick: onDismiss,
|
|
47
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
48
|
+
viewBox: "0 0 24 24",
|
|
49
|
+
fill: "none",
|
|
50
|
+
stroke: "currentColor",
|
|
51
|
+
strokeWidth: "2",
|
|
52
|
+
strokeLinecap: "round",
|
|
53
|
+
"aria-hidden": "true",
|
|
54
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 6l12 12M18 6 6 18" })
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { Alert };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
2
|
+
import type { Color, ComponentSize, Radius, Variant } from '../types';
|
|
3
|
+
/** Props for {@link Avatar}. */
|
|
4
|
+
export interface AvatarProps extends Omit<ComponentProps<'span'>, 'children' | 'color'> {
|
|
5
|
+
/** Image URL. When it cannot load, the fallback is shown. */
|
|
6
|
+
src?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Person's name. Used for the fallback initials and accessible name when `alt` is omitted.
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <Avatar name="Ada Lovelace" />
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
name?: string;
|
|
15
|
+
/** Alternative text for the avatar. Pass an empty string for a decorative avatar. */
|
|
16
|
+
alt?: string;
|
|
17
|
+
/** Content shown instead of initials when no image is available. */
|
|
18
|
+
fallback?: ReactNode;
|
|
19
|
+
/** Called after the image fails to load. */
|
|
20
|
+
onImageError?: () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Diameter from the `sizes` config.
|
|
23
|
+
* @default config.defaults.size
|
|
24
|
+
*/
|
|
25
|
+
size?: ComponentSize<'Avatar'>;
|
|
26
|
+
/**
|
|
27
|
+
* Corner radius from the `radii` config.
|
|
28
|
+
* @default 'rounded'
|
|
29
|
+
*/
|
|
30
|
+
radius?: Radius | 'size';
|
|
31
|
+
/**
|
|
32
|
+
* Fallback color from the `colors` config.
|
|
33
|
+
* @default config.defaults.color
|
|
34
|
+
*/
|
|
35
|
+
color?: Color;
|
|
36
|
+
/**
|
|
37
|
+
* Fallback style recipe from the `variants` config.
|
|
38
|
+
* @default config.defaults.softVariant
|
|
39
|
+
*/
|
|
40
|
+
variant?: Variant;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A person image with initials or custom fallback content when an image is unavailable.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```tsx
|
|
47
|
+
* <Avatar name="Ada Lovelace" src="/ada.jpg" />
|
|
48
|
+
* <Avatar name="Grace Hopper" color="success" />
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function Avatar({ src, name, alt, fallback, onImageError, size, radius, color, variant, className, role, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ...props }: AvatarProps): import("react").JSX.Element;
|
|
52
|
+
/** Props for {@link AvatarGroup}. */
|
|
53
|
+
export interface AvatarGroupProps extends Omit<ComponentProps<'div'>, 'color'> {
|
|
54
|
+
/** Direct `Avatar` children to arrange in an overlapping row. */
|
|
55
|
+
children?: ReactNode;
|
|
56
|
+
/**
|
|
57
|
+
* Maximum number of avatars to show before an overflow count.
|
|
58
|
+
* @example
|
|
59
|
+
* ```tsx
|
|
60
|
+
* <AvatarGroup max={3}>…</AvatarGroup>
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
max?: number;
|
|
64
|
+
/** Total number of people when not every avatar is rendered. Used with `max`. */
|
|
65
|
+
total?: number;
|
|
66
|
+
/** Accessible label for the overflow count. Receives the number of hidden avatars. */
|
|
67
|
+
overflowLabel?: (count: number) => string;
|
|
68
|
+
/**
|
|
69
|
+
* Avatar diameter from the `sizes` config.
|
|
70
|
+
* @default config.defaults.size
|
|
71
|
+
*/
|
|
72
|
+
size?: ComponentSize<'AvatarGroup'>;
|
|
73
|
+
/**
|
|
74
|
+
* Avatar corner radius from the `radii` config.
|
|
75
|
+
* @default config.defaults.radius
|
|
76
|
+
*/
|
|
77
|
+
radius?: Radius | 'size';
|
|
78
|
+
/**
|
|
79
|
+
* Fallback color from the `colors` config.
|
|
80
|
+
* @default config.defaults.color
|
|
81
|
+
*/
|
|
82
|
+
color?: Color;
|
|
83
|
+
/**
|
|
84
|
+
* Fallback style recipe from the `variants` config.
|
|
85
|
+
* @default config.defaults.softVariant
|
|
86
|
+
*/
|
|
87
|
+
variant?: Variant;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* An overlapping row of avatars. Group token props apply to avatars that do not set their own values.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```tsx
|
|
94
|
+
* <AvatarGroup max={3} aria-label="Project members">
|
|
95
|
+
* <Avatar name="Ada Lovelace" />
|
|
96
|
+
* <Avatar name="Grace Hopper" />
|
|
97
|
+
* </AvatarGroup>
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare function AvatarGroup({ children, max, total, overflowLabel, size, radius, color, variant, className, role, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ...props }: AvatarGroupProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { useDefaults } from "../runtime.js";
|
|
2
|
+
import { colorClass, cx, radiusClass, sizeClass, softVariantClass } from "../classes.js";
|
|
3
|
+
import { Children, cloneElement, isValidElement, useState } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/Avatar.tsx
|
|
6
|
+
function initials(name) {
|
|
7
|
+
return name?.trim().split(/\s+/).filter(Boolean).slice(0, 2).map((part) => part[0]?.toLocaleUpperCase()).join("") ?? "";
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A person image with initials or custom fallback content when an image is unavailable.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <Avatar name="Ada Lovelace" src="/ada.jpg" />
|
|
15
|
+
* <Avatar name="Grace Hopper" color="success" />
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
function Avatar({ src, name, alt, fallback, onImageError, size, radius, color, variant, className, role, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }) {
|
|
19
|
+
const own = useDefaults("Avatar");
|
|
20
|
+
const [failedSrc, setFailedSrc] = useState();
|
|
21
|
+
const decorative = alt === "" && ariaLabel == null && ariaLabelledBy == null && role == null;
|
|
22
|
+
const label = ariaLabel ?? (alt === "" ? void 0 : alt ?? name);
|
|
23
|
+
const labelled = label != null || ariaLabelledBy != null;
|
|
24
|
+
return /* @__PURE__ */ jsx("span", {
|
|
25
|
+
...props,
|
|
26
|
+
role: role ?? (labelled ? "img" : void 0),
|
|
27
|
+
"aria-label": ariaLabelledBy == null ? label : void 0,
|
|
28
|
+
"aria-labelledby": ariaLabelledBy,
|
|
29
|
+
className: cx("yarcl-avatar", sizeClass(size ?? own.size, "Avatar"), radiusClass(radius ?? own.radius, size ?? own.size), colorClass(color ?? own.color), softVariantClass(variant ?? own.variant), className),
|
|
30
|
+
children: src && failedSrc !== src ? /* @__PURE__ */ jsx("img", {
|
|
31
|
+
className: "yarcl-avatar-image",
|
|
32
|
+
src,
|
|
33
|
+
alt: "",
|
|
34
|
+
"aria-hidden": "true",
|
|
35
|
+
onError: () => {
|
|
36
|
+
setFailedSrc(src);
|
|
37
|
+
onImageError?.();
|
|
38
|
+
}
|
|
39
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
40
|
+
className: "yarcl-avatar-fallback",
|
|
41
|
+
"aria-hidden": labelled || decorative || void 0,
|
|
42
|
+
children: fallback ?? initials(name)
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* An overlapping row of avatars. Group token props apply to avatars that do not set their own values.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```tsx
|
|
51
|
+
* <AvatarGroup max={3} aria-label="Project members">
|
|
52
|
+
* <Avatar name="Ada Lovelace" />
|
|
53
|
+
* <Avatar name="Grace Hopper" />
|
|
54
|
+
* </AvatarGroup>
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
function AvatarGroup({ children, max, total, overflowLabel = (count) => `${count} more`, size, radius, color, variant, className, role, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }) {
|
|
58
|
+
const own = useDefaults("AvatarGroup");
|
|
59
|
+
const avatarOwn = useDefaults("Avatar");
|
|
60
|
+
const avatars = Children.toArray(children).filter((child) => isValidElement(child) && child.type === Avatar);
|
|
61
|
+
const limit = max == null ? avatars.length : Math.max(0, Math.floor(max));
|
|
62
|
+
const visible = avatars.slice(0, limit);
|
|
63
|
+
const hidden = Math.max((total ?? avatars.length) - visible.length, 0);
|
|
64
|
+
const groupSize = size ?? own.size ?? avatarOwn.size;
|
|
65
|
+
const groupRadius = radius ?? own.radius ?? avatarOwn.radius;
|
|
66
|
+
const groupColor = color ?? own.color ?? avatarOwn.color;
|
|
67
|
+
const groupVariant = variant ?? own.variant ?? avatarOwn.variant;
|
|
68
|
+
const labelled = ariaLabel != null || ariaLabelledBy != null;
|
|
69
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
70
|
+
...props,
|
|
71
|
+
role: role ?? (labelled ? "group" : void 0),
|
|
72
|
+
"aria-label": ariaLabelledBy == null ? ariaLabel : void 0,
|
|
73
|
+
"aria-labelledby": ariaLabelledBy,
|
|
74
|
+
className: cx("yarcl-avatar-group", sizeClass(groupSize, "AvatarGroup"), radiusClass(groupRadius, groupSize), colorClass(groupColor), softVariantClass(groupVariant), className),
|
|
75
|
+
children: [visible.map((avatar) => cloneElement(avatar, {
|
|
76
|
+
size: avatar.props.size ?? groupSize,
|
|
77
|
+
radius: avatar.props.radius ?? groupRadius,
|
|
78
|
+
color: avatar.props.color ?? groupColor,
|
|
79
|
+
variant: avatar.props.variant ?? groupVariant
|
|
80
|
+
})), hidden > 0 && /* @__PURE__ */ jsxs("span", {
|
|
81
|
+
className: "yarcl-avatar yarcl-avatar-overflow",
|
|
82
|
+
role: "img",
|
|
83
|
+
"aria-label": overflowLabel(hidden),
|
|
84
|
+
children: ["+", hidden]
|
|
85
|
+
})]
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { Avatar, AvatarGroup };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import type { Color, ComponentSize, Radius, Variant } from '../types';
|
|
3
|
+
/** Props for {@link Badge}. */
|
|
4
|
+
export interface BadgeProps extends Omit<ComponentProps<'span'>, 'color'> {
|
|
5
|
+
/**
|
|
6
|
+
* Semantic color, from the `colors` config.
|
|
7
|
+
* @default config.defaults.color
|
|
8
|
+
*/
|
|
9
|
+
color?: Color;
|
|
10
|
+
/**
|
|
11
|
+
* Style recipe, from the `variants` config.
|
|
12
|
+
* @default config.defaults.softVariant
|
|
13
|
+
*/
|
|
14
|
+
variant?: Variant;
|
|
15
|
+
/**
|
|
16
|
+
* Scales with the size's font size, from the `sizes` config.
|
|
17
|
+
* @default config.defaults.size
|
|
18
|
+
*/
|
|
19
|
+
size?: ComponentSize<'Badge'>;
|
|
20
|
+
/**
|
|
21
|
+
* Corner radius, from the `radii` config.
|
|
22
|
+
* @default config.defaults.radius
|
|
23
|
+
*/
|
|
24
|
+
radius?: Radius | 'size';
|
|
25
|
+
/** Shows a remove button, making the badge a removable tag. Called when it is pressed. */
|
|
26
|
+
onRemove?: () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Accessible label of the remove button.
|
|
29
|
+
* @default 'Remove'
|
|
30
|
+
*/
|
|
31
|
+
removeLabel?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A small label for status, counts or categories. With `onRemove`, a removable tag.
|
|
35
|
+
* Uses the same variant recipes as {@link Button}.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* <Badge color="success">Active</Badge>
|
|
40
|
+
* <Badge onRemove={() => removeTag('react')}>react</Badge>
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function Badge({ color, variant, size, radius, onRemove, removeLabel, className, children, ...props }: BadgeProps): import("react").JSX.Element;
|
|
44
|
+
export declare function BadgeRemove(props: Omit<ComponentProps<'button'>, 'children'>): import("react").JSX.Element;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useDefaults } from "../runtime.js";
|
|
2
|
+
import { colorClass, cx, radiusClass, sizeClass, softVariantClass } from "../classes.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/Badge.tsx
|
|
5
|
+
/**
|
|
6
|
+
* A small label for status, counts or categories. With `onRemove`, a removable tag.
|
|
7
|
+
* Uses the same variant recipes as {@link Button}.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <Badge color="success">Active</Badge>
|
|
12
|
+
* <Badge onRemove={() => removeTag('react')}>react</Badge>
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
function Badge({ color, variant, size, radius, onRemove, removeLabel = "Remove", className, children, ...props }) {
|
|
16
|
+
const own = useDefaults("Badge");
|
|
17
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
18
|
+
className: cx("yarcl-badge", colorClass(color ?? own.color), softVariantClass(variant ?? own.variant), sizeClass(size ?? own.size, "Badge"), radiusClass(radius ?? own.radius, size ?? own.size), className),
|
|
19
|
+
...props,
|
|
20
|
+
children: [children, onRemove && /* @__PURE__ */ jsx(BadgeRemove, {
|
|
21
|
+
"aria-label": removeLabel,
|
|
22
|
+
onClick: onRemove
|
|
23
|
+
})]
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function BadgeRemove(props) {
|
|
27
|
+
return /* @__PURE__ */ jsx("button", {
|
|
28
|
+
type: "button",
|
|
29
|
+
className: "yarcl-badge-remove",
|
|
30
|
+
...props,
|
|
31
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
32
|
+
viewBox: "0 0 24 24",
|
|
33
|
+
fill: "none",
|
|
34
|
+
stroke: "currentColor",
|
|
35
|
+
strokeWidth: "2.5",
|
|
36
|
+
strokeLinecap: "round",
|
|
37
|
+
"aria-hidden": "true",
|
|
38
|
+
children: /* @__PURE__ */ jsx("path", { d: "M7 7l10 10M17 7 7 17" })
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { Badge, BadgeRemove };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
2
|
+
import type { Color, TextStyle } from '../types';
|
|
3
|
+
import type { LinkProps } from './Link';
|
|
4
|
+
/** Props for {@link Breadcrumb}. Accepts all native `<nav>` attributes except `color`. */
|
|
5
|
+
export interface BreadcrumbProps extends Omit<ComponentProps<'nav'>, 'color'> {
|
|
6
|
+
/** `Breadcrumb.Item`s, from the root to the current page. */
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Content between items. Hidden from screen readers.
|
|
10
|
+
* @default a chevron icon
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <Breadcrumb separator="/">…</Breadcrumb>
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
separator?: ReactNode;
|
|
17
|
+
/** Collapses the middle of the trail into an expandable ellipsis when there are more items than this. Without it, the trail never collapses. */
|
|
18
|
+
maxItems?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Items shown before the ellipsis when collapsed.
|
|
21
|
+
* @default 1
|
|
22
|
+
*/
|
|
23
|
+
itemsBeforeCollapse?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Items shown after the ellipsis when collapsed.
|
|
26
|
+
* @default 2
|
|
27
|
+
*/
|
|
28
|
+
itemsAfterCollapse?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Accessible label of the ellipsis button.
|
|
31
|
+
* @default 'Show all breadcrumbs'
|
|
32
|
+
*/
|
|
33
|
+
expandLabel?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Text style, from the `typography.styles` config.
|
|
36
|
+
* @default config.defaults.textStyle
|
|
37
|
+
*/
|
|
38
|
+
textStyle?: TextStyle;
|
|
39
|
+
/**
|
|
40
|
+
* Link color, from the `colors` config.
|
|
41
|
+
* @default config.defaults.color
|
|
42
|
+
*/
|
|
43
|
+
color?: Color;
|
|
44
|
+
/**
|
|
45
|
+
* When to underline the links.
|
|
46
|
+
* @default 'hover'
|
|
47
|
+
*/
|
|
48
|
+
underline?: LinkProps['underline'];
|
|
49
|
+
}
|
|
50
|
+
declare function BreadcrumbRoot({ children, separator, maxItems, itemsBeforeCollapse, itemsAfterCollapse, expandLabel, textStyle, color, underline, className, 'aria-label': ariaLabel, ...props }: BreadcrumbProps): import("react").JSX.Element;
|
|
51
|
+
/** Props for `Breadcrumb.Item`. Accepts all native `<a>` attributes except `color`. */
|
|
52
|
+
export interface BreadcrumbItemProps extends Omit<ComponentProps<'a'>, 'color'> {
|
|
53
|
+
/** The item's label. */
|
|
54
|
+
children?: ReactNode;
|
|
55
|
+
/** Where the item links to. Without it, the item renders as plain text. */
|
|
56
|
+
href?: string;
|
|
57
|
+
}
|
|
58
|
+
declare function BreadcrumbItem({ href, className, children, ...props }: BreadcrumbItemProps): import("react").JSX.Element;
|
|
59
|
+
/**
|
|
60
|
+
* Shows where the current page sits in a hierarchy. The last item is the current page
|
|
61
|
+
* and gets `aria-current="page"`. Set `maxItems` to collapse long trails into an ellipsis
|
|
62
|
+
* that expands the full trail.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```tsx
|
|
66
|
+
* <Breadcrumb maxItems={4}>
|
|
67
|
+
* <Breadcrumb.Item href="/">Home</Breadcrumb.Item>
|
|
68
|
+
* <Breadcrumb.Item href="/projects">Projects</Breadcrumb.Item>
|
|
69
|
+
* <Breadcrumb.Item href="/projects/apollo">Apollo</Breadcrumb.Item>
|
|
70
|
+
* <Breadcrumb.Item>Settings</Breadcrumb.Item>
|
|
71
|
+
* </Breadcrumb>
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare const Breadcrumb: typeof BreadcrumbRoot & {
|
|
75
|
+
Item: typeof BreadcrumbItem;
|
|
76
|
+
};
|
|
77
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { useConfig, useDefaults } from "../runtime.js";
|
|
2
|
+
import { colorClass, cx, typeClass } from "../classes.js";
|
|
3
|
+
import { Children, createContext, isValidElement, useContext, useRef, useState } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/Breadcrumb.tsx
|
|
6
|
+
var BreadcrumbItemContext = createContext(null);
|
|
7
|
+
function ChevronIcon() {
|
|
8
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
9
|
+
viewBox: "0 0 24 24",
|
|
10
|
+
fill: "none",
|
|
11
|
+
stroke: "currentColor",
|
|
12
|
+
strokeWidth: "2",
|
|
13
|
+
strokeLinecap: "round",
|
|
14
|
+
strokeLinejoin: "round",
|
|
15
|
+
"aria-hidden": "true",
|
|
16
|
+
children: /* @__PURE__ */ jsx("path", { d: "m9 6 6 6-6 6" })
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function Separator({ children }) {
|
|
20
|
+
return /* @__PURE__ */ jsx("span", {
|
|
21
|
+
className: "yarcl-breadcrumb-separator",
|
|
22
|
+
"aria-hidden": "true",
|
|
23
|
+
children
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function BreadcrumbRoot({ children, separator = /* @__PURE__ */ jsx(ChevronIcon, {}), maxItems, itemsBeforeCollapse = 1, itemsAfterCollapse = 2, expandLabel = "Show all breadcrumbs", textStyle, color, underline = "hover", className, "aria-label": ariaLabel = "Breadcrumb", ...props }) {
|
|
27
|
+
const config = useConfig();
|
|
28
|
+
const own = useDefaults("Breadcrumb");
|
|
29
|
+
const [expanded, setExpanded] = useState(false);
|
|
30
|
+
const focusNext = useRef(false);
|
|
31
|
+
const items = Children.toArray(children).filter(isValidElement);
|
|
32
|
+
const resolvedColor = color ?? own.color ?? config.defaults.color;
|
|
33
|
+
const before = Math.max(0, itemsBeforeCollapse);
|
|
34
|
+
const after = Math.max(1, itemsAfterCollapse);
|
|
35
|
+
const collapsible = maxItems !== void 0 && items.length > maxItems && before + after < items.length;
|
|
36
|
+
const collapsed = collapsible && !expanded;
|
|
37
|
+
const hiddenEnd = items.length - after;
|
|
38
|
+
const context = (index) => ({
|
|
39
|
+
current: index === items.length - 1,
|
|
40
|
+
separator,
|
|
41
|
+
color: resolvedColor,
|
|
42
|
+
underline,
|
|
43
|
+
itemRef: collapsible && index === before ? (node) => {
|
|
44
|
+
if (node && focusNext.current) {
|
|
45
|
+
focusNext.current = false;
|
|
46
|
+
node.focus();
|
|
47
|
+
}
|
|
48
|
+
} : void 0
|
|
49
|
+
});
|
|
50
|
+
const rendered = [];
|
|
51
|
+
items.forEach((item, index) => {
|
|
52
|
+
if (collapsed && index >= before && index < hiddenEnd) {
|
|
53
|
+
if (index === before) rendered.push(/* @__PURE__ */ jsxs("li", {
|
|
54
|
+
className: "yarcl-breadcrumb-item",
|
|
55
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
56
|
+
type: "button",
|
|
57
|
+
className: "yarcl-breadcrumb-ellipsis",
|
|
58
|
+
"aria-label": expandLabel,
|
|
59
|
+
onClick: () => {
|
|
60
|
+
focusNext.current = true;
|
|
61
|
+
setExpanded(true);
|
|
62
|
+
},
|
|
63
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
64
|
+
"aria-hidden": "true",
|
|
65
|
+
children: "…"
|
|
66
|
+
})
|
|
67
|
+
}), /* @__PURE__ */ jsx(Separator, { children: separator })]
|
|
68
|
+
}, "yarcl-breadcrumb-ellipsis"));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
rendered.push(/* @__PURE__ */ jsx(BreadcrumbItemContext.Provider, {
|
|
72
|
+
value: context(index),
|
|
73
|
+
children: item
|
|
74
|
+
}, item.key ?? index));
|
|
75
|
+
});
|
|
76
|
+
return /* @__PURE__ */ jsx("nav", {
|
|
77
|
+
"aria-label": ariaLabel,
|
|
78
|
+
className: cx("yarcl-breadcrumb", typeClass(textStyle ?? own.textStyle ?? config.defaults.textStyle), colorClass(resolvedColor), className),
|
|
79
|
+
...props,
|
|
80
|
+
children: /* @__PURE__ */ jsx("ol", {
|
|
81
|
+
className: "yarcl-breadcrumb-list",
|
|
82
|
+
children: rendered
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function BreadcrumbItem({ href, className, children, ...props }) {
|
|
87
|
+
const context = useContext(BreadcrumbItemContext);
|
|
88
|
+
if (!context) throw new Error("yarcl: <Breadcrumb.Item> must be inside <Breadcrumb>");
|
|
89
|
+
const { current, separator, color, underline, itemRef } = context;
|
|
90
|
+
return /* @__PURE__ */ jsxs("li", {
|
|
91
|
+
className: "yarcl-breadcrumb-item",
|
|
92
|
+
children: [href ? /* @__PURE__ */ jsx("a", {
|
|
93
|
+
ref: itemRef,
|
|
94
|
+
href,
|
|
95
|
+
"aria-current": current ? "page" : void 0,
|
|
96
|
+
className: cx("yarcl-link", current ? "yarcl-breadcrumb-current yarcl-link-underline-none" : `yarcl-link-underline-${underline}`, colorClass(color), className),
|
|
97
|
+
...props,
|
|
98
|
+
children
|
|
99
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
100
|
+
ref: itemRef,
|
|
101
|
+
tabIndex: itemRef ? -1 : void 0,
|
|
102
|
+
"aria-current": current ? "page" : void 0,
|
|
103
|
+
className: cx("yarcl-breadcrumb-text", current && "yarcl-breadcrumb-current", className),
|
|
104
|
+
...props,
|
|
105
|
+
children
|
|
106
|
+
}), !current && /* @__PURE__ */ jsx(Separator, { children: separator })]
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Shows where the current page sits in a hierarchy. The last item is the current page
|
|
111
|
+
* and gets `aria-current="page"`. Set `maxItems` to collapse long trails into an ellipsis
|
|
112
|
+
* that expands the full trail.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```tsx
|
|
116
|
+
* <Breadcrumb maxItems={4}>
|
|
117
|
+
* <Breadcrumb.Item href="/">Home</Breadcrumb.Item>
|
|
118
|
+
* <Breadcrumb.Item href="/projects">Projects</Breadcrumb.Item>
|
|
119
|
+
* <Breadcrumb.Item href="/projects/apollo">Apollo</Breadcrumb.Item>
|
|
120
|
+
* <Breadcrumb.Item>Settings</Breadcrumb.Item>
|
|
121
|
+
* </Breadcrumb>
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
var Breadcrumb = Object.assign(BreadcrumbRoot, { Item: BreadcrumbItem });
|
|
125
|
+
//#endregion
|
|
126
|
+
export { Breadcrumb };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import type { TokenProps, VariantProps } from '../types';
|
|
3
|
+
/** Props for {@link Button}. Accepts all native `<button>` attributes except `color`. */
|
|
4
|
+
export interface ButtonProps extends Omit<ComponentProps<'button'>, 'color'>, TokenProps<'Button'>, VariantProps {
|
|
5
|
+
/** Shows a {@link Spinner}, disables the button and sets `aria-busy`. */
|
|
6
|
+
loading?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A button styled from the consumer's design tokens.
|
|
10
|
+
* Shares the base size scale with {@link Input}; component size overrides can adjust either one.
|
|
11
|
+
* Icons (`<svg>`) inside are sized from the size's `iconSize`.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <Button size="lg" color="danger" variant="outline" radius="pill">Delete</Button>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function Button({ size, radius, color, variant, loading, disabled, className, type, children, ...props }: ButtonProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useDefaults } from "../runtime.js";
|
|
2
|
+
import { colorClass, cx, radiusClass, sizeClass, variantClass } from "../classes.js";
|
|
3
|
+
import { useButtonGroup } from "./ButtonGroup.js";
|
|
4
|
+
import { Spinner } from "./Spinner.js";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/Button.tsx
|
|
7
|
+
/**
|
|
8
|
+
* A button styled from the consumer's design tokens.
|
|
9
|
+
* Shares the base size scale with {@link Input}; component size overrides can adjust either one.
|
|
10
|
+
* Icons (`<svg>`) inside are sized from the size's `iconSize`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <Button size="lg" color="danger" variant="outline" radius="pill">Delete</Button>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function Button({ size, radius, color, variant, loading, disabled, className, type = "button", children, ...props }) {
|
|
18
|
+
const own = useDefaults("Button");
|
|
19
|
+
const group = useButtonGroup();
|
|
20
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
21
|
+
type,
|
|
22
|
+
className: cx("yarcl-button", sizeClass(size ?? group?.size ?? own.size, "Button"), radiusClass(radius ?? group?.radius ?? own.radius, size ?? group?.size ?? own.size), colorClass(color ?? group?.color ?? own.color), variantClass(variant ?? group?.variant ?? own.variant), className),
|
|
23
|
+
disabled: disabled || loading,
|
|
24
|
+
"aria-busy": loading || void 0,
|
|
25
|
+
...props,
|
|
26
|
+
children: [loading && /* @__PURE__ */ jsx(Spinner, {
|
|
27
|
+
label: "",
|
|
28
|
+
"aria-hidden": "true"
|
|
29
|
+
}), children]
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { Button };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ComponentProps } from 'react';
|
|
2
|
+
import type { TokenProps, VariantProps } from '../types';
|
|
3
|
+
export declare function useButtonGroup(): (TokenProps<"Button"> & VariantProps) | null;
|
|
4
|
+
/** Props for {@link ButtonGroup}. Token props are passed down to every button inside. */
|
|
5
|
+
export interface ButtonGroupProps extends Omit<ComponentProps<'div'>, 'color'>, TokenProps<'Button'>, VariantProps {
|
|
6
|
+
/**
|
|
7
|
+
* Joins the buttons into one control with shared borders.
|
|
8
|
+
* @default true
|
|
9
|
+
*/
|
|
10
|
+
attached?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Direction of the buttons.
|
|
13
|
+
* @default 'horizontal'
|
|
14
|
+
*/
|
|
15
|
+
orientation?: 'horizontal' | 'vertical';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Groups related {@link Button}s and {@link IconButton}s. Buttons inherit `size`, `color`,
|
|
19
|
+
* `variant` and `radius` from the group unless they set their own. Give the group an `aria-label`.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* <ButtonGroup aria-label="Pagination" variant="outline">
|
|
24
|
+
* <Button>Previous</Button>
|
|
25
|
+
* <Button>Next</Button>
|
|
26
|
+
* </ButtonGroup>
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function ButtonGroup({ size, color, variant, radius, attached, orientation, className, ...props }: ButtonGroupProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { cx } from "../classes.js";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/ButtonGroup.tsx
|
|
5
|
+
var ButtonGroupContext = createContext(null);
|
|
6
|
+
function useButtonGroup() {
|
|
7
|
+
return useContext(ButtonGroupContext);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Groups related {@link Button}s and {@link IconButton}s. Buttons inherit `size`, `color`,
|
|
11
|
+
* `variant` and `radius` from the group unless they set their own. Give the group an `aria-label`.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <ButtonGroup aria-label="Pagination" variant="outline">
|
|
16
|
+
* <Button>Previous</Button>
|
|
17
|
+
* <Button>Next</Button>
|
|
18
|
+
* </ButtonGroup>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
function ButtonGroup({ size, color, variant, radius, attached = true, orientation = "horizontal", className, ...props }) {
|
|
22
|
+
return /* @__PURE__ */ jsx(ButtonGroupContext.Provider, {
|
|
23
|
+
value: {
|
|
24
|
+
size,
|
|
25
|
+
color,
|
|
26
|
+
variant,
|
|
27
|
+
radius
|
|
28
|
+
},
|
|
29
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
30
|
+
role: "group",
|
|
31
|
+
className: cx("yarcl-button-group", `yarcl-button-group-${orientation}`, attached && "yarcl-button-group-attached", className),
|
|
32
|
+
...props
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { ButtonGroup, useButtonGroup };
|