@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.
Files changed (223) hide show
  1. package/README.md +14 -2
  2. package/{src/apply.ts → dist/apply.d.ts} +4 -23
  3. package/dist/apply.js +37 -0
  4. package/dist/classes.d.ts +13 -0
  5. package/dist/classes.js +22 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +58 -0
  8. package/dist/color.js +49 -32
  9. package/dist/components/Accordion.d.ts +96 -0
  10. package/dist/components/Accordion.js +148 -0
  11. package/dist/components/Alert.d.ts +60 -0
  12. package/dist/components/Alert.js +61 -0
  13. package/dist/components/Avatar.d.ts +100 -0
  14. package/dist/components/Avatar.js +89 -0
  15. package/dist/components/Badge.d.ts +44 -0
  16. package/dist/components/Badge.js +43 -0
  17. package/dist/components/Breadcrumb.d.ts +77 -0
  18. package/dist/components/Breadcrumb.js +126 -0
  19. package/dist/components/Button.d.ts +18 -0
  20. package/dist/components/Button.js +33 -0
  21. package/dist/components/ButtonGroup.d.ts +29 -0
  22. package/dist/components/ButtonGroup.js +37 -0
  23. package/dist/components/Card.d.ts +36 -0
  24. package/dist/components/Card.js +26 -0
  25. package/dist/components/Checkbox.d.ts +28 -0
  26. package/dist/components/Checkbox.js +38 -0
  27. package/dist/components/Combobox.d.ts +75 -0
  28. package/dist/components/Combobox.js +362 -0
  29. package/dist/components/CommandPalette.d.ts +92 -0
  30. package/dist/components/CommandPalette.js +293 -0
  31. package/dist/components/DatePicker.d.ts +157 -0
  32. package/dist/components/DatePicker.js +230 -0
  33. package/dist/components/Dialog.d.ts +25 -0
  34. package/dist/components/Dialog.js +29 -0
  35. package/dist/components/Divider.d.ts +23 -0
  36. package/dist/components/Divider.js +25 -0
  37. package/dist/components/Drawer.d.ts +21 -0
  38. package/dist/components/Drawer.js +25 -0
  39. package/dist/components/EmptyState.d.ts +51 -0
  40. package/dist/components/EmptyState.js +47 -0
  41. package/dist/components/Field.d.ts +27 -0
  42. package/dist/components/Field.js +59 -0
  43. package/dist/components/Heading.d.ts +26 -0
  44. package/dist/components/Heading.js +25 -0
  45. package/dist/components/HoverCard.d.ts +47 -0
  46. package/dist/components/HoverCard.js +53 -0
  47. package/dist/components/IconButton.d.ts +19 -0
  48. package/dist/components/IconButton.js +32 -0
  49. package/dist/components/Inline.d.ts +21 -0
  50. package/dist/components/Inline.js +24 -0
  51. package/dist/components/Input.d.ts +19 -0
  52. package/dist/components/Input.js +25 -0
  53. package/dist/components/Label.d.ts +46 -0
  54. package/dist/components/Label.js +33 -0
  55. package/dist/components/Link.d.ts +27 -0
  56. package/dist/components/Link.js +26 -0
  57. package/dist/components/Menu.d.ts +73 -0
  58. package/dist/components/Menu.js +143 -0
  59. package/dist/components/Modal.d.ts +45 -0
  60. package/dist/components/Modal.js +110 -0
  61. package/dist/components/NumberInput.d.ts +49 -0
  62. package/dist/components/NumberInput.js +130 -0
  63. package/dist/components/Pagination.d.ts +86 -0
  64. package/dist/components/Pagination.js +119 -0
  65. package/dist/components/Popover.d.ts +72 -0
  66. package/dist/components/Popover.js +87 -0
  67. package/dist/components/Progress.d.ts +60 -0
  68. package/dist/components/Progress.js +59 -0
  69. package/dist/components/Radio.d.ts +32 -0
  70. package/dist/components/Radio.js +47 -0
  71. package/dist/components/RadioGroup.d.ts +57 -0
  72. package/dist/components/RadioGroup.js +68 -0
  73. package/dist/components/Select.d.ts +47 -0
  74. package/dist/components/Select.js +138 -0
  75. package/dist/components/Skeleton.d.ts +46 -0
  76. package/dist/components/Skeleton.js +40 -0
  77. package/dist/components/Slider.d.ts +126 -0
  78. package/dist/components/Slider.js +166 -0
  79. package/dist/components/Spinner.d.ts +23 -0
  80. package/dist/components/Spinner.js +23 -0
  81. package/dist/components/Stack.d.ts +35 -0
  82. package/dist/components/Stack.js +24 -0
  83. package/dist/components/Switch.d.ts +27 -0
  84. package/dist/components/Switch.js +33 -0
  85. package/dist/components/Table.d.ts +71 -0
  86. package/dist/components/Table.js +61 -0
  87. package/dist/components/Tabs.d.ts +66 -0
  88. package/dist/components/Tabs.js +109 -0
  89. package/dist/components/Text.d.ts +32 -0
  90. package/dist/components/Text.js +28 -0
  91. package/dist/components/Textarea.d.ts +15 -0
  92. package/dist/components/Textarea.js +24 -0
  93. package/dist/components/Toast.d.ts +90 -0
  94. package/dist/components/Toast.js +156 -0
  95. package/dist/components/ToggleGroup.d.ts +79 -0
  96. package/dist/components/ToggleGroup.js +101 -0
  97. package/dist/components/Tooltip.d.ts +46 -0
  98. package/dist/components/Tooltip.js +62 -0
  99. package/dist/components/VisuallyHidden.d.ts +18 -0
  100. package/dist/components/VisuallyHidden.js +22 -0
  101. package/dist/contrast.d.ts +32 -0
  102. package/dist/css.d.ts +2 -2
  103. package/dist/css.js +193 -157
  104. package/dist/define.d.ts +40 -15
  105. package/dist/define.js +30 -27
  106. package/dist/demo.d.ts +2 -0
  107. package/dist/demo.js +2 -0
  108. package/dist/esbuild.cjs +5 -0
  109. package/dist/esbuild.d.ts +4 -0
  110. package/dist/esbuild.js +6 -0
  111. package/dist/field-context.d.ts +16 -0
  112. package/dist/field-context.js +17 -0
  113. package/dist/floating.d.ts +12 -0
  114. package/dist/floating.js +52 -0
  115. package/dist/hooks.d.ts +1 -0
  116. package/dist/hooks.js +12 -0
  117. package/{src/index.ts → dist/index.d.ts} +11 -33
  118. package/dist/index.js +50 -0
  119. package/dist/init.d.ts +18 -0
  120. package/dist/init.js +224 -0
  121. package/dist/plugin.d.ts +10 -26
  122. package/dist/plugin.js +152 -78
  123. package/dist/reference/DemoYarcl.d.ts +12 -0
  124. package/dist/reference/DemoYarcl.js +312 -0
  125. package/dist/reference/DesignReference.d.ts +24 -0
  126. package/dist/reference/DesignReference.js +403 -0
  127. package/dist/reference/index.js +2 -0
  128. package/dist/rollup.cjs +5 -0
  129. package/dist/rollup.d.ts +4 -0
  130. package/dist/rollup.js +6 -0
  131. package/dist/rspack.cjs +5 -0
  132. package/dist/rspack.d.ts +4 -0
  133. package/dist/rspack.js +6 -0
  134. package/dist/runtime.d.ts +13 -0
  135. package/dist/runtime.js +30 -0
  136. package/dist/setup.d.ts +6 -0
  137. package/dist/setup.js +33 -0
  138. package/{src → dist}/styles.css +224 -106
  139. package/dist/themes/bloom.d.ts +295 -0
  140. package/dist/themes/bloom.js +202 -0
  141. package/dist/themes/brutalist.d.ts +277 -0
  142. package/dist/themes/brutalist.js +199 -0
  143. package/dist/themes/compact.d.ts +274 -0
  144. package/dist/themes/compact.js +200 -0
  145. package/dist/themes/contract.d.ts +23 -0
  146. package/dist/themes/editorial.d.ts +277 -0
  147. package/dist/themes/editorial.js +183 -0
  148. package/dist/themes/index.d.ts +1425 -0
  149. package/dist/themes/index.js +45 -0
  150. package/{src/types.ts → dist/types.d.ts} +40 -37
  151. package/dist/vite.cjs +5 -0
  152. package/dist/vite.d.ts +4 -0
  153. package/dist/vite.js +6 -0
  154. package/dist/webpack.cjs +5 -0
  155. package/dist/webpack.d.ts +4 -0
  156. package/dist/webpack.js +6 -0
  157. package/dist/yarcl.config.d.ts +276 -0
  158. package/dist/yarcl.config.js +273 -0
  159. package/package.json +69 -17
  160. package/src/classes.ts +0 -23
  161. package/src/color.ts +0 -48
  162. package/src/components/Accordion.tsx +0 -274
  163. package/src/components/Alert.tsx +0 -85
  164. package/src/components/Badge.tsx +0 -79
  165. package/src/components/Breadcrumb.tsx +0 -239
  166. package/src/components/Button.tsx +0 -58
  167. package/src/components/ButtonGroup.tsx +0 -61
  168. package/src/components/Card.tsx +0 -50
  169. package/src/components/Checkbox.tsx +0 -49
  170. package/src/components/Combobox.tsx +0 -522
  171. package/src/components/CommandPalette.tsx +0 -452
  172. package/src/components/DatePicker.tsx +0 -432
  173. package/src/components/Dialog.tsx +0 -39
  174. package/src/components/Divider.tsx +0 -34
  175. package/src/components/Drawer.tsx +0 -31
  176. package/src/components/Field.tsx +0 -61
  177. package/src/components/Heading.tsx +0 -40
  178. package/src/components/HoverCard.tsx +0 -108
  179. package/src/components/IconButton.tsx +0 -59
  180. package/src/components/Inline.tsx +0 -42
  181. package/src/components/Input.tsx +0 -28
  182. package/src/components/Label.tsx +0 -58
  183. package/src/components/Link.tsx +0 -41
  184. package/src/components/Menu.tsx +0 -207
  185. package/src/components/Modal.tsx +0 -164
  186. package/src/components/NumberInput.tsx +0 -208
  187. package/src/components/Pagination.tsx +0 -227
  188. package/src/components/Popover.tsx +0 -140
  189. package/src/components/Progress.tsx +0 -122
  190. package/src/components/Radio.tsx +0 -59
  191. package/src/components/RadioGroup.tsx +0 -114
  192. package/src/components/Select.tsx +0 -197
  193. package/src/components/Skeleton.tsx +0 -95
  194. package/src/components/Slider.tsx +0 -315
  195. package/src/components/Spinner.tsx +0 -38
  196. package/src/components/Stack.tsx +0 -57
  197. package/src/components/Switch.tsx +0 -42
  198. package/src/components/Table.tsx +0 -99
  199. package/src/components/Tabs.tsx +0 -159
  200. package/src/components/Text.tsx +0 -67
  201. package/src/components/Textarea.tsx +0 -26
  202. package/src/components/Toast.tsx +0 -190
  203. package/src/components/ToggleGroup.tsx +0 -227
  204. package/src/components/Tooltip.tsx +0 -78
  205. package/src/contrast.ts +0 -82
  206. package/src/css.ts +0 -228
  207. package/src/define.check.ts +0 -259
  208. package/src/define.ts +0 -379
  209. package/src/field-context.ts +0 -31
  210. package/src/floating.tsx +0 -61
  211. package/src/hooks.ts +0 -19
  212. package/src/plugin.ts +0 -94
  213. package/src/reference/DesignReference.tsx +0 -374
  214. package/src/runtime.ts +0 -38
  215. package/src/themes/bloom.ts +0 -72
  216. package/src/themes/brutalist.ts +0 -63
  217. package/src/themes/compact.ts +0 -63
  218. package/src/themes/contract.ts +0 -24
  219. package/src/themes/editorial.ts +0 -55
  220. package/src/themes/index.ts +0 -47
  221. package/src/yarcl.config.ts +0 -104
  222. /package/{src/reference/index.ts → dist/reference/index.d.ts} +0 -0
  223. /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 };