@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,25 @@
|
|
|
1
|
+
import { type ModalProps } from './Modal';
|
|
2
|
+
import type { Radius } from '../types';
|
|
3
|
+
/** Props for {@link Dialog}. */
|
|
4
|
+
export interface DialogProps extends ModalProps {
|
|
5
|
+
/**
|
|
6
|
+
* Corner radius, from the `radii` config.
|
|
7
|
+
* @default config.defaults.radius
|
|
8
|
+
*/
|
|
9
|
+
radius?: Radius;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A modal dialog built on the native `<dialog>` element: focus is trapped, the page behind is inert
|
|
13
|
+
* and doesn't scroll, and Esc closes it.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <Dialog
|
|
18
|
+
* trigger={<Button color="danger">Delete</Button>}
|
|
19
|
+
* title="Delete project?"
|
|
20
|
+
* description="This can't be undone."
|
|
21
|
+
* footer={<Button color="danger" onClick={remove}>Delete</Button>}
|
|
22
|
+
* />
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function Dialog(props: DialogProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useDefaults } from "../runtime.js";
|
|
2
|
+
import { Modal } from "./Modal.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/Dialog.tsx
|
|
5
|
+
/**
|
|
6
|
+
* A modal dialog built on the native `<dialog>` element: focus is trapped, the page behind is inert
|
|
7
|
+
* and doesn't scroll, and Esc closes it.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <Dialog
|
|
12
|
+
* trigger={<Button color="danger">Delete</Button>}
|
|
13
|
+
* title="Delete project?"
|
|
14
|
+
* description="This can't be undone."
|
|
15
|
+
* footer={<Button color="danger" onClick={remove}>Delete</Button>}
|
|
16
|
+
* />
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
function Dialog(props) {
|
|
20
|
+
const own = useDefaults("Dialog");
|
|
21
|
+
return /* @__PURE__ */ jsx(Modal, {
|
|
22
|
+
...props,
|
|
23
|
+
size: props.size ?? own.size,
|
|
24
|
+
radius: props.radius ?? (own.radius === "size" ? void 0 : own.radius),
|
|
25
|
+
className: "yarcl-dialog"
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { Dialog };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
/** Props for {@link Divider}. */
|
|
3
|
+
export interface DividerProps extends Omit<ComponentProps<'hr'>, 'children'> {
|
|
4
|
+
/**
|
|
5
|
+
* Direction of the line. Use `'vertical'` inside an {@link Inline}.
|
|
6
|
+
* @default 'horizontal'
|
|
7
|
+
*/
|
|
8
|
+
orientation?: 'horizontal' | 'vertical';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A thin separator line in the neutral border color.
|
|
12
|
+
* Spacing around it comes from the parent's `gap`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <Stack>
|
|
17
|
+
* <Text>Above</Text>
|
|
18
|
+
* <Divider />
|
|
19
|
+
* <Text>Below</Text>
|
|
20
|
+
* </Stack>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function Divider({ orientation, className, ...props }: DividerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { cx } from "../classes.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
//#region src/components/Divider.tsx
|
|
4
|
+
/**
|
|
5
|
+
* A thin separator line in the neutral border color.
|
|
6
|
+
* Spacing around it comes from the parent's `gap`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* <Stack>
|
|
11
|
+
* <Text>Above</Text>
|
|
12
|
+
* <Divider />
|
|
13
|
+
* <Text>Below</Text>
|
|
14
|
+
* </Stack>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function Divider({ orientation = "horizontal", className, ...props }) {
|
|
18
|
+
return /* @__PURE__ */ jsx("hr", {
|
|
19
|
+
className: cx("yarcl-divider", `yarcl-divider-${orientation}`, className),
|
|
20
|
+
"aria-orientation": orientation === "vertical" ? "vertical" : void 0,
|
|
21
|
+
...props
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { Divider };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ModalProps } from './Modal';
|
|
2
|
+
/** Props for {@link Drawer}. */
|
|
3
|
+
export interface DrawerProps extends ModalProps {
|
|
4
|
+
/**
|
|
5
|
+
* Edge the drawer is attached to.
|
|
6
|
+
* @default 'right'
|
|
7
|
+
*/
|
|
8
|
+
side?: 'left' | 'right';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A modal panel that slides in from the left or right edge. Same behavior as {@link Dialog}:
|
|
12
|
+
* focus is trapped, the page behind is inert, Esc closes it.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <Drawer side="left" trigger={<Button>Menu</Button>} title="Navigation">
|
|
17
|
+
* <Stack as="nav">…</Stack>
|
|
18
|
+
* </Drawer>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function Drawer({ side, ...props }: DrawerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useDefaults } from "../runtime.js";
|
|
2
|
+
import { Modal } from "./Modal.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/Drawer.tsx
|
|
5
|
+
/**
|
|
6
|
+
* A modal panel that slides in from the left or right edge. Same behavior as {@link Dialog}:
|
|
7
|
+
* focus is trapped, the page behind is inert, Esc closes it.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <Drawer side="left" trigger={<Button>Menu</Button>} title="Navigation">
|
|
12
|
+
* <Stack as="nav">…</Stack>
|
|
13
|
+
* </Drawer>
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
function Drawer({ side = "right", ...props }) {
|
|
17
|
+
const own = useDefaults("Drawer");
|
|
18
|
+
return /* @__PURE__ */ jsx(Modal, {
|
|
19
|
+
...props,
|
|
20
|
+
size: props.size ?? own.size,
|
|
21
|
+
className: `yarcl-drawer yarcl-drawer-${side}`
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { Drawer };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
2
|
+
import type { Color, Spacing, TextStyle } from '../types';
|
|
3
|
+
/** Props for {@link EmptyState}. */
|
|
4
|
+
export interface EmptyStateProps extends Omit<ComponentProps<'div'>, 'children' | 'color' | 'title'> {
|
|
5
|
+
/** Main message. */
|
|
6
|
+
title: ReactNode;
|
|
7
|
+
/** Supporting text below the title. */
|
|
8
|
+
description?: ReactNode;
|
|
9
|
+
/** Decorative content shown above the title. */
|
|
10
|
+
icon?: ReactNode;
|
|
11
|
+
/** Actions shown below the description, usually buttons or links. */
|
|
12
|
+
actions?: ReactNode;
|
|
13
|
+
/**
|
|
14
|
+
* Semantic heading level for the title.
|
|
15
|
+
* @default 2
|
|
16
|
+
*/
|
|
17
|
+
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
18
|
+
/**
|
|
19
|
+
* Icon color, from the `colors` config.
|
|
20
|
+
* @default config.defaults.color
|
|
21
|
+
*/
|
|
22
|
+
color?: Color;
|
|
23
|
+
/**
|
|
24
|
+
* Space between content, from the `spacing` config.
|
|
25
|
+
* @default config.defaults.gap
|
|
26
|
+
*/
|
|
27
|
+
gap?: Spacing;
|
|
28
|
+
/**
|
|
29
|
+
* Inner spacing, from the `spacing` config.
|
|
30
|
+
* @default config.defaults.padding
|
|
31
|
+
*/
|
|
32
|
+
padding?: Spacing;
|
|
33
|
+
/**
|
|
34
|
+
* Description typography, from the `typography.styles` config.
|
|
35
|
+
* @default config.defaults.textStyle
|
|
36
|
+
*/
|
|
37
|
+
textStyle?: TextStyle;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A centered message for a view that has no content yet or no matching results.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* <EmptyState
|
|
45
|
+
* title="No projects yet"
|
|
46
|
+
* description="Create a project to start organizing your work."
|
|
47
|
+
* actions={<Button>Create project</Button>}
|
|
48
|
+
* />
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function EmptyState({ title, description, icon, actions, headingLevel, color, gap, padding, textStyle, className, ...props }: EmptyStateProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useConfig, useDefaults } from "../runtime.js";
|
|
2
|
+
import { colorClass, cx, gapClass, paddingClass, typeClass } from "../classes.js";
|
|
3
|
+
import { Heading } from "./Heading.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/EmptyState.tsx
|
|
6
|
+
/**
|
|
7
|
+
* A centered message for a view that has no content yet or no matching results.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <EmptyState
|
|
12
|
+
* title="No projects yet"
|
|
13
|
+
* description="Create a project to start organizing your work."
|
|
14
|
+
* actions={<Button>Create project</Button>}
|
|
15
|
+
* />
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
function EmptyState({ title, description, icon, actions, headingLevel = 2, color, gap, padding, textStyle, className, ...props }) {
|
|
19
|
+
const own = useDefaults("EmptyState");
|
|
20
|
+
const config = useConfig();
|
|
21
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
22
|
+
className: cx("yarcl-empty-state", colorClass(color ?? own.color), gapClass(gap ?? own.gap), paddingClass(padding ?? own.padding), typeClass(textStyle ?? own.textStyle ?? config.defaults.textStyle), className),
|
|
23
|
+
...props,
|
|
24
|
+
children: [
|
|
25
|
+
icon != null && /* @__PURE__ */ jsx("div", {
|
|
26
|
+
className: "yarcl-empty-state-icon",
|
|
27
|
+
"aria-hidden": "true",
|
|
28
|
+
children: icon
|
|
29
|
+
}),
|
|
30
|
+
/* @__PURE__ */ jsx(Heading, {
|
|
31
|
+
level: headingLevel,
|
|
32
|
+
className: "yarcl-empty-state-title",
|
|
33
|
+
children: title
|
|
34
|
+
}),
|
|
35
|
+
description != null && /* @__PURE__ */ jsx("p", {
|
|
36
|
+
className: "yarcl-empty-state-description",
|
|
37
|
+
children: description
|
|
38
|
+
}),
|
|
39
|
+
actions != null && /* @__PURE__ */ jsx("div", {
|
|
40
|
+
className: "yarcl-empty-state-actions",
|
|
41
|
+
children: actions
|
|
42
|
+
})
|
|
43
|
+
]
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { EmptyState };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
2
|
+
/** Props for {@link Field}. */
|
|
3
|
+
export interface FieldProps extends Omit<ComponentProps<'div'>, 'children'> {
|
|
4
|
+
/** Visible label for the control. */
|
|
5
|
+
label: ReactNode;
|
|
6
|
+
/** Helper text shown below the control. */
|
|
7
|
+
description?: ReactNode;
|
|
8
|
+
/** Error message. When set, the control is marked invalid and styled with `defaults.errorColor`. */
|
|
9
|
+
error?: ReactNode;
|
|
10
|
+
/** Marks the control as required and shows an indicator next to the label. */
|
|
11
|
+
required?: boolean;
|
|
12
|
+
/** A single form control: {@link Input}, {@link Textarea}, {@link Checkbox}, {@link Switch} or {@link Slider}. */
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Wraps a form control with a label, helper text and an error message.
|
|
17
|
+
* The control receives `id`, `aria-describedby`, `aria-invalid` and `required` automatically;
|
|
18
|
+
* don't set its `id` yourself.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <Field label="Email" description="We never share it." error={errors.email} required>
|
|
23
|
+
* <Input type="email" />
|
|
24
|
+
* </Field>
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function Field({ label, description, error, required, children, className, ...props }: FieldProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useConfig } from "../runtime.js";
|
|
2
|
+
import { cx, typeClass } from "../classes.js";
|
|
3
|
+
import { FieldContext } from "../field-context.js";
|
|
4
|
+
import { Label } from "./Label.js";
|
|
5
|
+
import { useId } from "react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/components/Field.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Wraps a form control with a label, helper text and an error message.
|
|
10
|
+
* The control receives `id`, `aria-describedby`, `aria-invalid` and `required` automatically;
|
|
11
|
+
* don't set its `id` yourself.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <Field label="Email" description="We never share it." error={errors.email} required>
|
|
16
|
+
* <Input type="email" />
|
|
17
|
+
* </Field>
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
function Field({ label, description, error, required, children, className, ...props }) {
|
|
21
|
+
const config = useConfig();
|
|
22
|
+
const id = useId();
|
|
23
|
+
const descriptionId = description != null ? `${id}-description` : void 0;
|
|
24
|
+
const errorId = error != null && error !== false ? `${id}-error` : void 0;
|
|
25
|
+
return /* @__PURE__ */ jsx(FieldContext.Provider, {
|
|
26
|
+
value: {
|
|
27
|
+
id,
|
|
28
|
+
labelId: `${id}-label`,
|
|
29
|
+
describedBy: cx(descriptionId, errorId) || void 0,
|
|
30
|
+
invalid: errorId != null,
|
|
31
|
+
required
|
|
32
|
+
},
|
|
33
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
34
|
+
className: cx("yarcl-field", className),
|
|
35
|
+
...props,
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ jsx(Label, {
|
|
38
|
+
id: `${id}-label`,
|
|
39
|
+
htmlFor: id,
|
|
40
|
+
required,
|
|
41
|
+
children: label
|
|
42
|
+
}),
|
|
43
|
+
children,
|
|
44
|
+
descriptionId && /* @__PURE__ */ jsx("p", {
|
|
45
|
+
className: cx("yarcl-field-description", typeClass(config.defaults.helperStyle)),
|
|
46
|
+
id: descriptionId,
|
|
47
|
+
children: description
|
|
48
|
+
}),
|
|
49
|
+
errorId && /* @__PURE__ */ jsx("p", {
|
|
50
|
+
className: cx("yarcl-field-error", typeClass(config.defaults.helperStyle)),
|
|
51
|
+
id: errorId,
|
|
52
|
+
children: error
|
|
53
|
+
})
|
|
54
|
+
]
|
|
55
|
+
})
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { Field };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import type { Color, TextStyle } from '../types';
|
|
3
|
+
/** Props for {@link Heading}. */
|
|
4
|
+
export interface HeadingProps extends Omit<ComponentProps<'h2'>, 'color'> {
|
|
5
|
+
/** Heading level: renders `<h1>` … `<h6>`. Choose by document structure, not by size. */
|
|
6
|
+
level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
7
|
+
/**
|
|
8
|
+
* Text style, from the `typography.styles` config. Overrides the level's style when the
|
|
9
|
+
* visual size should differ from the document structure.
|
|
10
|
+
* @default config.typography.headings[`h${level}`]
|
|
11
|
+
*/
|
|
12
|
+
textStyle?: TextStyle;
|
|
13
|
+
/** Semantic color, from the `colors` config. Uses the default text color when omitted. */
|
|
14
|
+
color?: Color;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A section heading. Renders `<h1>` … `<h6>` styled with the level's text style from
|
|
18
|
+
* `typography.headings`; `textStyle` overrides the look without changing the level.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <Heading level={1}>Settings</Heading>
|
|
23
|
+
* <Heading level={2} textStyle="display">Big section title</Heading>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function Heading({ level, textStyle, color, className, ...props }: HeadingProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useConfig } from "../runtime.js";
|
|
2
|
+
import { colorClass, cx, typeClass } from "../classes.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/Heading.tsx
|
|
5
|
+
/**
|
|
6
|
+
* A section heading. Renders `<h1>` … `<h6>` styled with the level's text style from
|
|
7
|
+
* `typography.headings`; `textStyle` overrides the look without changing the level.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <Heading level={1}>Settings</Heading>
|
|
12
|
+
* <Heading level={2} textStyle="display">Big section title</Heading>
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
function Heading({ level, textStyle, color, className, ...props }) {
|
|
16
|
+
const config = useConfig();
|
|
17
|
+
const Tag = `h${level}`;
|
|
18
|
+
const style = textStyle ?? config.typography.headings[`h${level}`];
|
|
19
|
+
return /* @__PURE__ */ jsx(Tag, {
|
|
20
|
+
className: cx("yarcl-heading", typeClass(style), color && cx("yarcl-text-colored", colorClass(color)), className),
|
|
21
|
+
...props
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { Heading };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type Placement } from '@floating-ui/react';
|
|
2
|
+
import { type ReactElement, type ReactNode } from 'react';
|
|
3
|
+
import type { Radius, Spacing } from '../types';
|
|
4
|
+
/** Props for {@link HoverCard}. */
|
|
5
|
+
export interface HoverCardProps {
|
|
6
|
+
/** Rich preview content. Can contain links; the pointer can move into the card without closing it. */
|
|
7
|
+
content: ReactNode;
|
|
8
|
+
/** A single focusable element, usually a {@link Link}. */
|
|
9
|
+
children: ReactElement;
|
|
10
|
+
/**
|
|
11
|
+
* Preferred side. Flips when there isn't room.
|
|
12
|
+
* @default 'bottom'
|
|
13
|
+
*/
|
|
14
|
+
placement?: Placement;
|
|
15
|
+
/**
|
|
16
|
+
* Delay before opening, in ms.
|
|
17
|
+
* @default config.timing.hoverOpenDelay
|
|
18
|
+
*/
|
|
19
|
+
openDelay?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Delay before closing after the pointer leaves, in ms.
|
|
22
|
+
* @default config.timing.hoverCloseDelay
|
|
23
|
+
*/
|
|
24
|
+
closeDelay?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Inner padding, from the `spacing` config.
|
|
27
|
+
* @default config.defaults.padding
|
|
28
|
+
*/
|
|
29
|
+
padding?: Spacing;
|
|
30
|
+
/**
|
|
31
|
+
* Corner radius, from the `radii` config.
|
|
32
|
+
* @default config.defaults.radius
|
|
33
|
+
*/
|
|
34
|
+
radius?: Radius;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A preview card shown on hover or focus, e.g. for a user or a link.
|
|
38
|
+
* Supplementary only: don't put content here that isn't reachable elsewhere.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* <HoverCard content={<UserPreview id="ada" />}>
|
|
43
|
+
* <Link href="/users/ada">@ada</Link>
|
|
44
|
+
* </HoverCard>
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function HoverCard({ content, children, placement, openDelay, closeDelay, padding, radius, }: HoverCardProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useConfig, useDefaults } from "../runtime.js";
|
|
2
|
+
import { cx, paddingClass, radiusClass } from "../classes.js";
|
|
3
|
+
import { floatingMiddleware, useTrigger } from "../floating.js";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { FloatingPortal, autoUpdate, safePolygon, useDismiss, useFloating, useFocus, useHover, useInteractions } from "@floating-ui/react";
|
|
7
|
+
//#region src/components/HoverCard.tsx
|
|
8
|
+
/**
|
|
9
|
+
* A preview card shown on hover or focus, e.g. for a user or a link.
|
|
10
|
+
* Supplementary only: don't put content here that isn't reachable elsewhere.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <HoverCard content={<UserPreview id="ada" />}>
|
|
15
|
+
* <Link href="/users/ada">@ada</Link>
|
|
16
|
+
* </HoverCard>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
function HoverCard({ content, children, placement = "bottom", openDelay, closeDelay, padding, radius }) {
|
|
20
|
+
const own = useDefaults("HoverCard");
|
|
21
|
+
const config = useConfig();
|
|
22
|
+
const delay = {
|
|
23
|
+
open: openDelay ?? config.timing.hoverOpenDelay,
|
|
24
|
+
close: closeDelay ?? config.timing.hoverCloseDelay
|
|
25
|
+
};
|
|
26
|
+
const [open, setOpen] = useState(false);
|
|
27
|
+
const { refs, floatingStyles, context } = useFloating({
|
|
28
|
+
open,
|
|
29
|
+
onOpenChange: setOpen,
|
|
30
|
+
placement,
|
|
31
|
+
transform: false,
|
|
32
|
+
whileElementsMounted: autoUpdate,
|
|
33
|
+
middleware: floatingMiddleware({ gap: 8 })
|
|
34
|
+
});
|
|
35
|
+
const { getReferenceProps, getFloatingProps } = useInteractions([
|
|
36
|
+
useHover(context, {
|
|
37
|
+
delay,
|
|
38
|
+
handleClose: safePolygon()
|
|
39
|
+
}),
|
|
40
|
+
useFocus(context),
|
|
41
|
+
useDismiss(context)
|
|
42
|
+
]);
|
|
43
|
+
const trigger = useTrigger(children, refs.setReference, getReferenceProps);
|
|
44
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [trigger, open && /* @__PURE__ */ jsx(FloatingPortal, { children: /* @__PURE__ */ jsx("div", {
|
|
45
|
+
ref: refs.setFloating,
|
|
46
|
+
style: floatingStyles,
|
|
47
|
+
className: cx("yarcl-floating yarcl-panel yarcl-hover-card", paddingClass(padding ?? own.padding), radiusClass(radius ?? own.radius)),
|
|
48
|
+
...getFloatingProps(),
|
|
49
|
+
children: content
|
|
50
|
+
}) })] });
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { HoverCard };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import type { TokenProps, VariantProps } from '../types';
|
|
3
|
+
/** Props for {@link IconButton}. `aria-label` is required because the button has no visible text. */
|
|
4
|
+
export interface IconButtonProps extends Omit<ComponentProps<'button'>, 'color'>, TokenProps<'IconButton'>, VariantProps {
|
|
5
|
+
/** Shows a {@link Spinner}, disables the button and sets `aria-busy`. */
|
|
6
|
+
loading?: boolean;
|
|
7
|
+
/** Accessible name, announced by screen readers in place of visible text. */
|
|
8
|
+
'aria-label': string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A square button containing only an icon.
|
|
12
|
+
* Width equals the control height, so it lines up with {@link Button} and {@link Input} of the same size.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <IconButton aria-label="Search" variant="ghost"><SearchIcon /></IconButton>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function IconButton({ size, radius, color, variant, loading, disabled, className, type, children, ...props }: IconButtonProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,32 @@
|
|
|
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/IconButton.tsx
|
|
7
|
+
/**
|
|
8
|
+
* A square button containing only an icon.
|
|
9
|
+
* Width equals the control height, so it lines up with {@link Button} and {@link Input} of the same size.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <IconButton aria-label="Search" variant="ghost"><SearchIcon /></IconButton>
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
function IconButton({ size, radius, color, variant, loading, disabled, className, type = "button", children, ...props }) {
|
|
17
|
+
const own = useDefaults("IconButton");
|
|
18
|
+
const group = useButtonGroup();
|
|
19
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
20
|
+
type,
|
|
21
|
+
className: cx("yarcl-button yarcl-icon-button", sizeClass(size ?? group?.size ?? own.size, "IconButton"), radiusClass(radius ?? group?.radius ?? own.radius, size ?? group?.size ?? own.size), colorClass(color ?? group?.color ?? own.color), variantClass(variant ?? group?.variant ?? own.variant), className),
|
|
22
|
+
disabled: disabled || loading,
|
|
23
|
+
"aria-busy": loading || void 0,
|
|
24
|
+
...props,
|
|
25
|
+
children: [loading && /* @__PURE__ */ jsx(Spinner, {
|
|
26
|
+
label: "",
|
|
27
|
+
"aria-hidden": "true"
|
|
28
|
+
}), !loading && children]
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { IconButton };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { LayoutProps } from './Stack';
|
|
2
|
+
/** Props for {@link Inline}. */
|
|
3
|
+
export interface InlineProps extends LayoutProps {
|
|
4
|
+
/**
|
|
5
|
+
* Wraps children onto new lines when they don't fit.
|
|
6
|
+
* @default true
|
|
7
|
+
*/
|
|
8
|
+
wrap?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Lays out children horizontally with a gap from the spacing scale. Centers children vertically by default.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <Inline gap="tight" justify="end">
|
|
16
|
+
* <Button variant="outline">Cancel</Button>
|
|
17
|
+
* <Button>Save</Button>
|
|
18
|
+
* </Inline>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function Inline({ as, gap, align, justify, wrap, className, ...props }: InlineProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useDefaults } from "../runtime.js";
|
|
2
|
+
import { cx, gapClass } from "../classes.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/Inline.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Lays out children horizontally with a gap from the spacing scale. Centers children vertically by default.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* <Inline gap="tight" justify="end">
|
|
11
|
+
* <Button variant="outline">Cancel</Button>
|
|
12
|
+
* <Button>Save</Button>
|
|
13
|
+
* </Inline>
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
function Inline({ as = "div", gap, align = "center", justify, wrap = true, className, ...props }) {
|
|
17
|
+
const own = useDefaults("Inline");
|
|
18
|
+
return /* @__PURE__ */ jsx(as, {
|
|
19
|
+
className: cx("yarcl-inline", gapClass(gap ?? own.gap), `yarcl-align-${align}`, justify && `yarcl-justify-${justify}`, !wrap && "yarcl-inline-nowrap", className),
|
|
20
|
+
...props
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { Inline };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import type { TokenProps } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Props for {@link Input}. Accepts all native `<input>` attributes except
|
|
5
|
+
* `color` and `size`, which are replaced by design tokens.
|
|
6
|
+
*/
|
|
7
|
+
export interface InputProps extends Omit<ComponentProps<'input'>, 'color' | 'size'>, TokenProps<'Input'> {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A text input styled from the consumer's design tokens.
|
|
11
|
+
* Shares the base size scale with {@link Button}; component size overrides can adjust either one.
|
|
12
|
+
* `color` sets the focus border and ring. Inside a {@link Field}, it is labelled and described automatically.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <Input size="lg" placeholder="Email" />
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function Input(props: InputProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useDefaults } from "../runtime.js";
|
|
2
|
+
import { colorClass, cx, radiusClass, sizeClass } from "../classes.js";
|
|
3
|
+
import { useFieldProps } from "../field-context.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/Input.tsx
|
|
6
|
+
/**
|
|
7
|
+
* A text input styled from the consumer's design tokens.
|
|
8
|
+
* Shares the base size scale with {@link Button}; component size overrides can adjust either one.
|
|
9
|
+
* `color` sets the focus border and ring. Inside a {@link Field}, it is labelled and described automatically.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <Input size="lg" placeholder="Email" />
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
function Input(props) {
|
|
17
|
+
const own = useDefaults("Input");
|
|
18
|
+
const { size, radius, color, className, ...rest } = useFieldProps(props);
|
|
19
|
+
return /* @__PURE__ */ jsx("input", {
|
|
20
|
+
className: cx("yarcl-input", sizeClass(size ?? own.size, "Input"), radiusClass(radius ?? own.radius, size ?? own.size), colorClass(color ?? own.color), className),
|
|
21
|
+
...rest
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { Input };
|