@you-agent-factory/components 0.0.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 (92) hide show
  1. package/README.md +223 -0
  2. package/docs/README.md +83 -0
  3. package/docs/button.md +119 -0
  4. package/docs/charts.md +325 -0
  5. package/docs/data-display-code-panel.md +120 -0
  6. package/docs/feedback-alert-panel.md +117 -0
  7. package/docs/feedback-skeleton.md +54 -0
  8. package/docs/forms-form-field.md +490 -0
  9. package/docs/forms-input-primitives.md +311 -0
  10. package/docs/forms-select-primitives.md +362 -0
  11. package/docs/graphs.md +250 -0
  12. package/docs/layout-display-primitives.md +211 -0
  13. package/docs/overlays.md +414 -0
  14. package/docs/table-data-table.md +331 -0
  15. package/docs/typography-roles.md +182 -0
  16. package/docs/widget-frame-recipes.md +273 -0
  17. package/package.json +161 -0
  18. package/src/category-paths.ts +20 -0
  19. package/src/charts/chart-state-panel.tsx +103 -0
  20. package/src/charts/chart.tsx +287 -0
  21. package/src/charts/index.ts +21 -0
  22. package/src/data-display/code-panel.tsx +67 -0
  23. package/src/data-display/data-table.tsx +180 -0
  24. package/src/data-display/description-list.tsx +24 -0
  25. package/src/data-display/index.ts +34 -0
  26. package/src/data-display/table-layout.ts +12 -0
  27. package/src/data-display/table.tsx +131 -0
  28. package/src/feedback/alert-panel-semantics.ts +75 -0
  29. package/src/feedback/alert-panel.tsx +187 -0
  30. package/src/feedback/index.ts +21 -0
  31. package/src/feedback/skeleton.tsx +16 -0
  32. package/src/forms/index.ts +73 -0
  33. package/src/forms/package-checkbox.tsx +50 -0
  34. package/src/forms/package-enum-select.tsx +185 -0
  35. package/src/forms/package-file-input.tsx +25 -0
  36. package/src/forms/package-form-field.tsx +202 -0
  37. package/src/forms/package-input.tsx +25 -0
  38. package/src/forms/package-native-select.tsx +25 -0
  39. package/src/forms/package-select.tsx +209 -0
  40. package/src/forms/package-textarea.tsx +35 -0
  41. package/src/forms/select-icons.tsx +35 -0
  42. package/src/graphs/graph-edge-path.ts +241 -0
  43. package/src/graphs/graph-edge.tsx +130 -0
  44. package/src/graphs/graph-interactive-example.tsx +187 -0
  45. package/src/graphs/graph-node-button.tsx +51 -0
  46. package/src/graphs/graph-node-handle-badge.tsx +108 -0
  47. package/src/graphs/graph-node-handle.ts +28 -0
  48. package/src/graphs/graph-node-shell.tsx +111 -0
  49. package/src/graphs/graph-node-state-indicator.tsx +47 -0
  50. package/src/graphs/graph-node-state.ts +111 -0
  51. package/src/graphs/graph-viewport-surface.tsx +27 -0
  52. package/src/graphs/index.ts +41 -0
  53. package/src/icons/index.ts +4 -0
  54. package/src/index.ts +209 -0
  55. package/src/layout/action-row.tsx +53 -0
  56. package/src/layout/index.ts +9 -0
  57. package/src/layout/surface-panel.tsx +91 -0
  58. package/src/navigation/index.ts +4 -0
  59. package/src/overlays/collapsible.tsx +22 -0
  60. package/src/overlays/dialog.tsx +148 -0
  61. package/src/overlays/index.ts +31 -0
  62. package/src/overlays/overlay-layout.ts +9 -0
  63. package/src/overlays/popover.tsx +29 -0
  64. package/src/overlays/scroll-area.tsx +78 -0
  65. package/src/primitives/button-link.tsx +22 -0
  66. package/src/primitives/button.tsx +258 -0
  67. package/src/primitives/icon-button-shell.tsx +49 -0
  68. package/src/primitives/index.ts +31 -0
  69. package/src/primitives/package-text.tsx +29 -0
  70. package/src/primitives/typography-roles.ts +12 -0
  71. package/src/primitives/typography.tsx +165 -0
  72. package/src/recipes/index.ts +61 -0
  73. package/src/recipes/widget-frame-content.tsx +114 -0
  74. package/src/recipes/widget-frame-disclosure.tsx +161 -0
  75. package/src/recipes/widget-frame-layout.ts +40 -0
  76. package/src/recipes/widget-frame-skeleton.tsx +16 -0
  77. package/src/recipes/widget-frame-states.tsx +99 -0
  78. package/src/recipes/widget-frame-typography.ts +19 -0
  79. package/src/recipes/widget-frame.tsx +84 -0
  80. package/src/styles/color-palette-presets.css +167 -0
  81. package/src/styles/color-role-tokens.css +163 -0
  82. package/src/styles/layout-role-tokens.css +27 -0
  83. package/src/styles/text-color-role-tokens.css +29 -0
  84. package/src/styles/typography-role-tokens.css +72 -0
  85. package/src/styles/typography-role-utilities.css +73 -0
  86. package/src/styles/typography-roles.css +53 -0
  87. package/src/styles.css +32 -0
  88. package/src/testing/index.ts +13 -0
  89. package/src/testing/render.tsx +16 -0
  90. package/src/tokens/index.ts +4 -0
  91. package/src/utilities/cn.ts +5 -0
  92. package/src/utilities/index.ts +6 -0
@@ -0,0 +1,258 @@
1
+ import { Slot } from "@radix-ui/react-slot";
2
+ import {
3
+ type ButtonHTMLAttributes,
4
+ Children,
5
+ cloneElement,
6
+ forwardRef,
7
+ isValidElement,
8
+ type KeyboardEvent,
9
+ type MouseEvent,
10
+ type ReactNode,
11
+ type Ref,
12
+ } from "react";
13
+
14
+ import { cn } from "../utilities/cn";
15
+
16
+ const BUTTON_LOADING_CONTENT_CLASS = "inline-flex items-center justify-center gap-2";
17
+ const BUTTON_LOADING_HIDDEN_CONTENT_CLASS = "opacity-0";
18
+ const BUTTON_LOADING_OVERLAY_CLASS =
19
+ "pointer-events-none absolute inset-0 inline-flex items-center justify-center";
20
+
21
+ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
22
+ asChild?: boolean;
23
+ loading?: boolean;
24
+ tone?:
25
+ | "default"
26
+ | "destructive"
27
+ | "outline"
28
+ | "secondary"
29
+ | "ghost"
30
+ | "warning";
31
+ size?: "default" | "icon" | "iconPill" | "lg" | "pill" | "sm";
32
+ }
33
+
34
+ const BUTTON_BASE_CLASS =
35
+ "inline-flex min-h-11 items-center justify-center gap-2 rounded-xl border font-semibold outline-none transition-colors focus-visible:ring-2 focus-visible:ring-af-focus-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:border-outline disabled:bg-surface-container-low disabled:text-on-surface-disabled";
36
+ const BUTTON_TONE_CLASS: Record<NonNullable<ButtonProps["tone"]>, string> = {
37
+ default:
38
+ "border-primary bg-primary text-on-primary hover:border-on-primary-container hover:bg-on-primary-container",
39
+ destructive:
40
+ "border-error bg-error text-on-error hover:border-af-danger-hover hover:bg-af-danger-hover",
41
+ ghost:
42
+ "border-transparent bg-transparent text-on-surface-variant hover:bg-af-overlay hover:text-on-surface",
43
+ outline:
44
+ "border-outline bg-surface-container-high text-on-surface hover:border-outline-variant hover:bg-af-overlay",
45
+ secondary:
46
+ "border-outline-variant bg-surface-container-low text-primary hover:border-primary hover:bg-af-overlay",
47
+ warning:
48
+ "border-af-warning-border bg-warning-container text-on-warning-container hover:border-af-warning-border hover:bg-warning-container hover:text-on-warning-container",
49
+ };
50
+ const BUTTON_SIZE_CLASS: Record<NonNullable<ButtonProps["size"]>, string> = {
51
+ default: "px-4 py-2.5 text-sm",
52
+ icon: "h-11 w-11 px-0 py-0",
53
+ iconPill: "h-10 min-h-10 w-10 rounded-full px-0 py-0",
54
+ lg: "px-5 py-3 text-base",
55
+ pill: "min-h-9 rounded-full px-3 py-2 text-xs",
56
+ sm: "min-h-9 rounded-lg px-3 py-2 text-xs",
57
+ };
58
+
59
+ export const buttonVariants = ({
60
+ className,
61
+ size = "default",
62
+ tone = "default",
63
+ }: Pick<ButtonProps, "className" | "size" | "tone">) =>
64
+ cn(
65
+ BUTTON_BASE_CLASS,
66
+ BUTTON_TONE_CLASS[tone],
67
+ BUTTON_SIZE_CLASS[size],
68
+ className,
69
+ );
70
+
71
+ function ButtonLoadingSpinner() {
72
+ return (
73
+ <svg
74
+ aria-hidden="true"
75
+ className="size-4 animate-spin"
76
+ fill="none"
77
+ focusable="false"
78
+ viewBox="0 0 16 16"
79
+ >
80
+ <circle
81
+ className="text-on-surface-disabled"
82
+ cx="8"
83
+ cy="8"
84
+ r="6"
85
+ stroke="currentColor"
86
+ strokeWidth="1.5"
87
+ />
88
+ <path
89
+ d="M8 2a6 6 0 0 1 6 6"
90
+ stroke="currentColor"
91
+ strokeLinecap="round"
92
+ strokeWidth="1.5"
93
+ />
94
+ </svg>
95
+ );
96
+ }
97
+
98
+ function renderButtonContent(
99
+ children: ReactNode,
100
+ loading: boolean,
101
+ ): ReactNode {
102
+ if (!loading) {
103
+ return children;
104
+ }
105
+
106
+ return (
107
+ <>
108
+ <span
109
+ className={cn(
110
+ BUTTON_LOADING_CONTENT_CLASS,
111
+ BUTTON_LOADING_HIDDEN_CONTENT_CLASS,
112
+ )}
113
+ >
114
+ {children}
115
+ </span>
116
+ <span aria-hidden="true" className={BUTTON_LOADING_OVERLAY_CLASS}>
117
+ <ButtonLoadingSpinner />
118
+ </span>
119
+ </>
120
+ );
121
+ }
122
+
123
+ function suppressSlottedActivation(event: KeyboardEvent | MouseEvent): void {
124
+ event.preventDefault();
125
+ const nativeEvent = event.nativeEvent;
126
+ if (typeof nativeEvent.stopImmediatePropagation === "function") {
127
+ nativeEvent.stopImmediatePropagation();
128
+ return;
129
+ }
130
+ event.stopPropagation();
131
+ }
132
+
133
+ function shouldSuppressSlottedKeyboardActivation(
134
+ event: KeyboardEvent,
135
+ ): boolean {
136
+ return event.key === "Enter" || event.key === " ";
137
+ }
138
+
139
+ type SlottedChildProps = {
140
+ "aria-busy"?: boolean | "true" | "false";
141
+ "aria-disabled"?: boolean | "true" | "false";
142
+ className?: string;
143
+ href?: string;
144
+ onClick?: (event: MouseEvent<HTMLElement>) => void;
145
+ onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;
146
+ ref?: Ref<HTMLElement>;
147
+ };
148
+
149
+ function mergeRefs<T>(...refs: Array<Ref<T> | undefined>): Ref<T> {
150
+ return (value) => {
151
+ for (const ref of refs) {
152
+ if (typeof ref === "function") {
153
+ ref(value);
154
+ } else if (ref && typeof ref === "object") {
155
+ ref.current = value;
156
+ }
157
+ }
158
+ };
159
+ }
160
+
161
+ function renderBlockedAsChildButton(
162
+ {
163
+ children,
164
+ className,
165
+ loading,
166
+ props,
167
+ ref,
168
+ size,
169
+ tone,
170
+ }: {
171
+ children: ReactNode;
172
+ className?: string;
173
+ loading: boolean;
174
+ props: Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children">;
175
+ ref: Ref<HTMLButtonElement>;
176
+ size: NonNullable<ButtonProps["size"]>;
177
+ tone: NonNullable<ButtonProps["tone"]>;
178
+ },
179
+ ) {
180
+ const child = Children.only(children);
181
+ if (!isValidElement<SlottedChildProps>(child)) {
182
+ throw new Error("Button with asChild requires a single React element child.");
183
+ }
184
+
185
+ return cloneElement(child, {
186
+ ...props,
187
+ "aria-busy": loading || undefined,
188
+ "aria-disabled": true,
189
+ className: buttonVariants({
190
+ className: cn("pointer-events-none", className, child.props.className),
191
+ size,
192
+ tone,
193
+ }),
194
+ href: undefined,
195
+ onClick: suppressSlottedActivation,
196
+ onKeyDown: (event: KeyboardEvent<HTMLElement>) => {
197
+ if (shouldSuppressSlottedKeyboardActivation(event)) {
198
+ suppressSlottedActivation(event);
199
+ }
200
+ },
201
+ ref: mergeRefs(ref, child.props.ref),
202
+ });
203
+ }
204
+
205
+ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
206
+ function Button(
207
+ {
208
+ asChild = false,
209
+ children,
210
+ className,
211
+ disabled,
212
+ loading = false,
213
+ onClick,
214
+ onKeyDown,
215
+ size = "default",
216
+ tone = "default",
217
+ type = "button",
218
+ ...props
219
+ },
220
+ ref,
221
+ ) {
222
+ const isInteractionBlocked = disabled || loading;
223
+ const showLoadingOverlay = loading && !asChild;
224
+
225
+ if (asChild && isInteractionBlocked) {
226
+ return renderBlockedAsChildButton({
227
+ children,
228
+ className,
229
+ loading,
230
+ props,
231
+ ref,
232
+ size,
233
+ tone,
234
+ });
235
+ }
236
+
237
+ const Component = asChild ? Slot : "button";
238
+
239
+ return (
240
+ <Component
241
+ aria-busy={loading || undefined}
242
+ className={buttonVariants({
243
+ className: cn(showLoadingOverlay && "relative", className),
244
+ size,
245
+ tone,
246
+ })}
247
+ disabled={asChild ? undefined : isInteractionBlocked}
248
+ onClick={onClick}
249
+ onKeyDown={onKeyDown}
250
+ ref={ref}
251
+ {...(!asChild ? { type } : undefined)}
252
+ {...props}
253
+ >
254
+ {renderButtonContent(children, showLoadingOverlay)}
255
+ </Component>
256
+ );
257
+ },
258
+ );
@@ -0,0 +1,49 @@
1
+ import { forwardRef } from "react";
2
+
3
+ import { cn } from "../utilities/cn";
4
+ import { Button, type ButtonProps } from "./button";
5
+
6
+ const ICON_BUTTON_SHELL_BASE_CLASS = "relative shrink-0";
7
+ const ICON_BUTTON_SHELL_SIZE_CLASS = "h-10 w-10 rounded-lg";
8
+ const ICON_BUTTON_SHELL_TONE_CLASS = {
9
+ dangerGhost:
10
+ "text-on-surface-subtle hover:border-af-danger-border hover:bg-error-container hover:text-on-error-container",
11
+ } as const;
12
+
13
+ type IconButtonShellTone =
14
+ | ButtonProps["tone"]
15
+ | keyof typeof ICON_BUTTON_SHELL_TONE_CLASS;
16
+
17
+ export interface IconButtonShellProps
18
+ extends Omit<ButtonProps, "size" | "tone"> {
19
+ tone?: IconButtonShellTone;
20
+ }
21
+
22
+ export const IconButtonShell = forwardRef<
23
+ HTMLButtonElement,
24
+ IconButtonShellProps
25
+ >(function IconButtonShell(
26
+ { className, tone = "outline", ...props },
27
+ ref,
28
+ ) {
29
+ const buttonTone = tone === "dangerGhost" ? "ghost" : tone;
30
+ const toneClassName =
31
+ tone === "dangerGhost"
32
+ ? ICON_BUTTON_SHELL_TONE_CLASS.dangerGhost
33
+ : undefined;
34
+
35
+ return (
36
+ <Button
37
+ className={cn(
38
+ ICON_BUTTON_SHELL_BASE_CLASS,
39
+ ICON_BUTTON_SHELL_SIZE_CLASS,
40
+ toneClassName,
41
+ className,
42
+ )}
43
+ ref={ref}
44
+ size="icon"
45
+ tone={buttonTone}
46
+ {...props}
47
+ />
48
+ );
49
+ });
@@ -0,0 +1,31 @@
1
+ /** Stable category path for `@you-agent-factory/components/primitives`. */
2
+ export const COMPONENTS_CATEGORY = "primitives" as const;
3
+
4
+ export type ComponentsCategory = typeof COMPONENTS_CATEGORY;
5
+
6
+ export { Button, buttonVariants } from "./button";
7
+ export type { ButtonProps } from "./button";
8
+ export { ButtonLink } from "./button-link";
9
+ export type { ButtonLinkProps } from "./button-link";
10
+ export { IconButtonShell } from "./icon-button-shell";
11
+ export type { IconButtonShellProps } from "./icon-button-shell";
12
+ export { PackageText } from "./package-text";
13
+ export type { PackageTextProps, PackageTextVariant } from "./package-text";
14
+
15
+ export { Code, Heading, Label, Text } from "./typography";
16
+ export type { CodeProps, HeadingProps, LabelProps, TextProps, TextVariant } from "./typography";
17
+
18
+ export {
19
+ BODY_CODE_CLASS,
20
+ BODY_TEXT_CLASS,
21
+ CAPTION_TEXT_CLASS,
22
+ DENSE_BODY_TEXT_CLASS,
23
+ MUTED_TEXT_CLASS,
24
+ PAGE_HEADING_CLASS,
25
+ SECTION_HEADING_CLASS,
26
+ SUPPORTING_CODE_CLASS,
27
+ SUPPORTING_LABEL_CLASS,
28
+ SUPPORTING_TEXT_CLASS,
29
+ TEXT_TRUNCATE_CLASS,
30
+ TEXT_WRAP_CLASS,
31
+ } from "./typography-roles";
@@ -0,0 +1,29 @@
1
+ import type { ComponentPropsWithoutRef } from "react";
2
+
3
+ import { cn } from "../utilities/cn";
4
+
5
+ export type PackageTextVariant = "body" | "title";
6
+
7
+ export type PackageTextProps = ComponentPropsWithoutRef<"p"> & {
8
+ variant?: PackageTextVariant;
9
+ };
10
+
11
+ export function PackageText({
12
+ children,
13
+ className,
14
+ variant = "body",
15
+ ...props
16
+ }: PackageTextProps) {
17
+ return (
18
+ <p
19
+ className={cn(
20
+ variant === "title" ? "text-title-large" : "text-body-medium",
21
+ "text-on-surface",
22
+ className,
23
+ )}
24
+ {...props}
25
+ >
26
+ {children}
27
+ </p>
28
+ );
29
+ }
@@ -0,0 +1,12 @@
1
+ export const PAGE_HEADING_CLASS = "af-page-heading";
2
+ export const SECTION_HEADING_CLASS = "af-section-heading";
3
+ export const BODY_TEXT_CLASS = "af-body-text";
4
+ export const SUPPORTING_TEXT_CLASS = "af-supporting-text";
5
+ export const MUTED_TEXT_CLASS = "af-muted-text";
6
+ export const CAPTION_TEXT_CLASS = "af-caption-text";
7
+ export const DENSE_BODY_TEXT_CLASS = "af-dense-body-text";
8
+ export const SUPPORTING_LABEL_CLASS = "af-supporting-label";
9
+ export const BODY_CODE_CLASS = "af-body-code";
10
+ export const SUPPORTING_CODE_CLASS = "af-supporting-code";
11
+ export const TEXT_TRUNCATE_CLASS = "af-text-truncate";
12
+ export const TEXT_WRAP_CLASS = "af-text-wrap";
@@ -0,0 +1,165 @@
1
+ import {
2
+ type ElementType,
3
+ forwardRef,
4
+ type HTMLAttributes,
5
+ type ReactNode,
6
+ } from "react";
7
+
8
+ import { cn } from "../utilities/cn";
9
+ import {
10
+ BODY_CODE_CLASS,
11
+ BODY_TEXT_CLASS,
12
+ CAPTION_TEXT_CLASS,
13
+ DENSE_BODY_TEXT_CLASS,
14
+ MUTED_TEXT_CLASS,
15
+ PAGE_HEADING_CLASS,
16
+ SECTION_HEADING_CLASS,
17
+ SUPPORTING_CODE_CLASS,
18
+ SUPPORTING_LABEL_CLASS,
19
+ SUPPORTING_TEXT_CLASS,
20
+ TEXT_TRUNCATE_CLASS,
21
+ TEXT_WRAP_CLASS,
22
+ } from "./typography-roles";
23
+
24
+ type TypographyElementProps = HTMLAttributes<HTMLElement> & {
25
+ as?: ElementType;
26
+ children?: ReactNode;
27
+ dateTime?: string;
28
+ htmlFor?: string;
29
+ type?: "button" | "reset" | "submit";
30
+ };
31
+
32
+ type TypographyOverflowProps = {
33
+ truncate?: boolean;
34
+ wrap?: boolean;
35
+ };
36
+
37
+ function typographyOverflowClass({
38
+ truncate,
39
+ wrap,
40
+ }: TypographyOverflowProps): string | undefined {
41
+ if (truncate) {
42
+ return TEXT_TRUNCATE_CLASS;
43
+ }
44
+
45
+ if (wrap) {
46
+ return TEXT_WRAP_CLASS;
47
+ }
48
+
49
+ return undefined;
50
+ }
51
+
52
+ const TEXT_VARIANT_CLASS = {
53
+ body: BODY_TEXT_CLASS,
54
+ supporting: SUPPORTING_TEXT_CLASS,
55
+ muted: MUTED_TEXT_CLASS,
56
+ caption: CAPTION_TEXT_CLASS,
57
+ dense: DENSE_BODY_TEXT_CLASS,
58
+ } as const;
59
+
60
+ export type TextVariant = keyof typeof TEXT_VARIANT_CLASS;
61
+
62
+ export interface TextProps
63
+ extends TypographyElementProps,
64
+ TypographyOverflowProps {
65
+ variant?: TextVariant;
66
+ }
67
+
68
+ export const Text = forwardRef<HTMLElement, TextProps>(function Text(
69
+ {
70
+ as: Component = "p",
71
+ children,
72
+ className,
73
+ truncate,
74
+ variant = "body",
75
+ wrap,
76
+ ...props
77
+ },
78
+ ref,
79
+ ) {
80
+ return (
81
+ <Component
82
+ className={cn(
83
+ TEXT_VARIANT_CLASS[variant],
84
+ typographyOverflowClass({ truncate, wrap }),
85
+ className,
86
+ )}
87
+ ref={ref}
88
+ {...props}
89
+ >
90
+ {children}
91
+ </Component>
92
+ );
93
+ });
94
+
95
+ export interface HeadingProps
96
+ extends TypographyElementProps,
97
+ TypographyOverflowProps {
98
+ level?: "page" | "section";
99
+ }
100
+
101
+ export const Heading = forwardRef<HTMLElement, HeadingProps>(function Heading(
102
+ { as, children, className, level = "section", truncate, wrap, ...props },
103
+ ref,
104
+ ) {
105
+ const Component = as ?? (level === "page" ? "h1" : "h3");
106
+
107
+ return (
108
+ <Component
109
+ className={cn(
110
+ level === "page" ? PAGE_HEADING_CLASS : SECTION_HEADING_CLASS,
111
+ typographyOverflowClass({ truncate, wrap }),
112
+ className,
113
+ )}
114
+ ref={ref}
115
+ {...props}
116
+ >
117
+ {children}
118
+ </Component>
119
+ );
120
+ });
121
+
122
+ export interface LabelProps
123
+ extends TypographyElementProps,
124
+ TypographyOverflowProps {}
125
+
126
+ export const Label = forwardRef<HTMLElement, LabelProps>(function Label(
127
+ { as: Component = "span", children, className, truncate, wrap, ...props },
128
+ ref,
129
+ ) {
130
+ return (
131
+ <Component
132
+ className={cn(
133
+ SUPPORTING_LABEL_CLASS,
134
+ typographyOverflowClass({ truncate, wrap }),
135
+ className,
136
+ )}
137
+ ref={ref}
138
+ {...props}
139
+ >
140
+ {children}
141
+ </Component>
142
+ );
143
+ });
144
+
145
+ export interface CodeProps extends TypographyElementProps {
146
+ size?: "body" | "supporting";
147
+ }
148
+
149
+ export const Code = forwardRef<HTMLElement, CodeProps>(function Code(
150
+ { as: Component = "code", children, className, size = "body", ...props },
151
+ ref,
152
+ ) {
153
+ return (
154
+ <Component
155
+ className={cn(
156
+ size === "body" ? BODY_CODE_CLASS : SUPPORTING_CODE_CLASS,
157
+ className,
158
+ )}
159
+ ref={ref}
160
+ {...props}
161
+ >
162
+ {children}
163
+ </Component>
164
+ );
165
+ });
@@ -0,0 +1,61 @@
1
+ /** Stable category path for `@you-agent-factory/components/recipes`. */
2
+ export const COMPONENTS_CATEGORY = "recipes" as const;
3
+
4
+ export type ComponentsCategory = typeof COMPONENTS_CATEGORY;
5
+
6
+ export {
7
+ WidgetFrameDisclosure,
8
+ WidgetFrameDisclosureIcon,
9
+ WidgetFrameDisclosurePanel,
10
+ WidgetFrameDisclosureTrigger,
11
+ } from "./widget-frame-disclosure";
12
+ export type {
13
+ WidgetFrameDisclosureIconProps,
14
+ WidgetFrameDisclosurePanelProps,
15
+ WidgetFrameDisclosureProps,
16
+ WidgetFrameDisclosureTriggerProps,
17
+ } from "./widget-frame-disclosure";
18
+ export {
19
+ WidgetDetailCopy,
20
+ WidgetEmptyState,
21
+ WidgetEmptyStateText,
22
+ WidgetEmptyStateTitle,
23
+ WidgetSubtitle,
24
+ } from "./widget-frame-content";
25
+ export type {
26
+ WidgetDetailCopyProps,
27
+ WidgetEmptyStateProps,
28
+ WidgetEmptyStateTextProps,
29
+ WidgetEmptyStateTitleProps,
30
+ WidgetSubtitleProps,
31
+ } from "./widget-frame-content";
32
+ export { WidgetFrameSkeleton } from "./widget-frame-skeleton";
33
+ export {
34
+ WidgetErrorState,
35
+ WidgetLoadingState,
36
+ WidgetSuccessState,
37
+ } from "./widget-frame-states";
38
+ export type {
39
+ WidgetErrorStateProps,
40
+ WidgetLoadingStateProps,
41
+ WidgetSuccessStateProps,
42
+ } from "./widget-frame-states";
43
+ export {
44
+ WIDGET_FRAME_MIN_WIDTH_CLASS,
45
+ WIDGET_FRAME_OVERFLOW_TOLERANCE_PX,
46
+ WIDGET_FRAME_RESPONSIVE_SHELL_CLASS,
47
+ WIDGET_FRAME_STORY_SHELL_DATA_ATTR,
48
+ WIDGET_FRAME_WIDE_BODY_CLASS,
49
+ widgetFrameDetailCardClass,
50
+ widgetFrameHasNoHorizontalOverflow,
51
+ widgetFrameStoryShellStyle,
52
+ } from "./widget-frame-layout";
53
+ export { WidgetFrame } from "./widget-frame";
54
+ export type { WidgetFrameProps } from "./widget-frame";
55
+ export {
56
+ WIDGET_FRAME_BODY_TEXT_CLASS,
57
+ WIDGET_FRAME_SECTION_HEADING_CLASS,
58
+ WIDGET_FRAME_SUBTITLE_CLASS,
59
+ WIDGET_FRAME_SUPPORTING_LABEL_CLASS,
60
+ WIDGET_FRAME_SUPPORTING_LABELS_CLASS,
61
+ } from "./widget-frame-typography";