@you-agent-factory/components 0.0.0 → 0.0.2
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/LICENSE.md +21 -0
- package/README.md +38 -7
- package/dist/category-paths.d.ts +3 -0
- package/dist/charts/chart-state-panel.d.ts +11 -0
- package/dist/charts/chart.d.ts +35 -0
- package/dist/charts/index.d.ts +5 -0
- package/dist/charts/index.js +287 -0
- package/dist/chunks/action-row.js +39 -0
- package/dist/chunks/alert-panel.js +182 -0
- package/dist/chunks/button.js +193 -0
- package/dist/chunks/cn.js +6 -0
- package/dist/chunks/factory-emulator-controls.js +123 -0
- package/dist/chunks/package-form-field.js +546 -0
- package/dist/chunks/scroll-area.js +261 -0
- package/dist/chunks/surface-panel.js +73 -0
- package/dist/chunks/table-layout.js +292 -0
- package/dist/chunks/typography-roles.js +26 -0
- package/dist/chunks/typography.js +129 -0
- package/dist/chunks/widget-frame.js +344 -0
- package/dist/data-display/code-panel.d.ts +12 -0
- package/dist/data-display/data-table.d.ts +27 -0
- package/dist/data-display/description-list.d.ts +4 -0
- package/{src/data-display/index.ts → dist/data-display/index.d.ts} +4 -26
- package/dist/data-display/index.js +20 -0
- package/dist/data-display/table-layout.d.ts +8 -0
- package/dist/data-display/table.d.ts +14 -0
- package/dist/factory-emulator/factory-emulator-controls.d.ts +23 -0
- package/dist/factory-emulator/index.d.ts +6 -0
- package/dist/factory-emulator/index.js +6 -0
- package/dist/feedback/alert-panel-semantics.d.ts +11 -0
- package/dist/feedback/alert-panel.d.ts +29 -0
- package/dist/feedback/index.d.ts +6 -0
- package/dist/feedback/index.js +10 -0
- package/dist/feedback/skeleton.d.ts +2 -0
- package/dist/forms/index.d.ts +19 -0
- package/dist/forms/index.js +37 -0
- package/dist/forms/package-checkbox.d.ts +3 -0
- package/dist/forms/package-enum-select.d.ts +42 -0
- package/dist/forms/package-file-input.d.ts +3 -0
- package/dist/forms/package-form-field.d.ts +49 -0
- package/dist/forms/package-input.d.ts +6 -0
- package/dist/forms/package-native-select.d.ts +3 -0
- package/dist/forms/package-select.d.ts +32 -0
- package/dist/forms/package-textarea.d.ts +10 -0
- package/dist/forms/select-icons.d.ts +3 -0
- package/dist/graphs/graph-edge-path.d.ts +18 -0
- package/dist/graphs/graph-edge.d.ts +15 -0
- package/dist/graphs/graph-node-button.d.ts +11 -0
- package/dist/graphs/graph-node-handle-badge.d.ts +5 -0
- package/dist/graphs/graph-node-handle.d.ts +18 -0
- package/dist/graphs/graph-node-shell.d.ts +13 -0
- package/dist/graphs/graph-node-state-indicator.d.ts +6 -0
- package/dist/graphs/graph-node-state.d.ts +23 -0
- package/dist/graphs/graph-viewport-surface.d.ts +5 -0
- package/dist/graphs/index.d.ts +13 -0
- package/dist/graphs/index.js +614 -0
- package/{src/icons/index.ts → dist/icons/index.d.ts} +1 -2
- package/dist/icons/index.js +4 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +145 -0
- package/dist/layout/action-row.d.ts +8 -0
- package/{src/layout/index.ts → dist/layout/index.d.ts} +1 -3
- package/dist/layout/index.js +9 -0
- package/dist/layout/surface-panel.d.ts +15 -0
- package/{src/navigation/index.ts → dist/navigation/index.d.ts} +1 -2
- package/dist/navigation/index.js +4 -0
- package/dist/overlays/collapsible.d.ts +5 -0
- package/dist/overlays/dialog.d.ts +16 -0
- package/dist/overlays/index.d.ts +10 -0
- package/dist/overlays/index.js +27 -0
- package/dist/overlays/overlay-layout.d.ts +6 -0
- package/dist/overlays/popover.d.ts +6 -0
- package/dist/overlays/scroll-area.d.ts +9 -0
- package/dist/primitives/button-link.d.ts +5 -0
- package/dist/primitives/button.d.ts +9 -0
- package/dist/primitives/icon-button-shell.d.ts +10 -0
- package/{src/primitives/index.ts → dist/primitives/index.d.ts} +2 -19
- package/dist/primitives/index.js +49 -0
- package/dist/primitives/package-text.d.ts +6 -0
- package/dist/primitives/typography-roles.d.ts +12 -0
- package/dist/primitives/typography.d.ts +36 -0
- package/dist/recipes/index.d.ts +14 -0
- package/dist/recipes/index.js +32 -0
- package/dist/recipes/widget-frame-content.d.ts +24 -0
- package/dist/recipes/widget-frame-disclosure.d.ts +33 -0
- package/dist/recipes/widget-frame-layout.d.ts +12 -0
- package/dist/recipes/widget-frame-skeleton.d.ts +2 -0
- package/dist/recipes/widget-frame-states.d.ts +15 -0
- package/dist/recipes/widget-frame-typography.d.ts +10 -0
- package/dist/recipes/widget-frame.d.ts +12 -0
- package/{src → dist}/styles.css +36 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +16 -0
- package/dist/testing/render.d.ts +5 -0
- package/{src/tokens/index.ts → dist/tokens/index.d.ts} +1 -2
- package/dist/tokens/index.js +4 -0
- package/dist/utilities/cn.d.ts +1 -0
- package/{src/utilities/index.ts → dist/utilities/index.d.ts} +1 -3
- package/dist/utilities/index.js +6 -0
- package/package.json +65 -64
- package/docs/README.md +0 -83
- package/docs/button.md +0 -119
- package/docs/charts.md +0 -325
- package/docs/data-display-code-panel.md +0 -120
- package/docs/feedback-alert-panel.md +0 -117
- package/docs/feedback-skeleton.md +0 -54
- package/docs/forms-form-field.md +0 -490
- package/docs/forms-input-primitives.md +0 -311
- package/docs/forms-select-primitives.md +0 -362
- package/docs/graphs.md +0 -250
- package/docs/layout-display-primitives.md +0 -211
- package/docs/overlays.md +0 -414
- package/docs/table-data-table.md +0 -331
- package/docs/typography-roles.md +0 -182
- package/docs/widget-frame-recipes.md +0 -273
- package/src/category-paths.ts +0 -20
- package/src/charts/chart-state-panel.tsx +0 -103
- package/src/charts/chart.tsx +0 -287
- package/src/charts/index.ts +0 -21
- package/src/data-display/code-panel.tsx +0 -67
- package/src/data-display/data-table.tsx +0 -180
- package/src/data-display/description-list.tsx +0 -24
- package/src/data-display/table-layout.ts +0 -12
- package/src/data-display/table.tsx +0 -131
- package/src/feedback/alert-panel-semantics.ts +0 -75
- package/src/feedback/alert-panel.tsx +0 -187
- package/src/feedback/index.ts +0 -21
- package/src/feedback/skeleton.tsx +0 -16
- package/src/forms/index.ts +0 -73
- package/src/forms/package-checkbox.tsx +0 -50
- package/src/forms/package-enum-select.tsx +0 -185
- package/src/forms/package-file-input.tsx +0 -25
- package/src/forms/package-form-field.tsx +0 -202
- package/src/forms/package-input.tsx +0 -25
- package/src/forms/package-native-select.tsx +0 -25
- package/src/forms/package-select.tsx +0 -209
- package/src/forms/package-textarea.tsx +0 -35
- package/src/forms/select-icons.tsx +0 -35
- package/src/graphs/graph-edge-path.ts +0 -241
- package/src/graphs/graph-edge.tsx +0 -130
- package/src/graphs/graph-interactive-example.tsx +0 -187
- package/src/graphs/graph-node-button.tsx +0 -51
- package/src/graphs/graph-node-handle-badge.tsx +0 -108
- package/src/graphs/graph-node-handle.ts +0 -28
- package/src/graphs/graph-node-shell.tsx +0 -111
- package/src/graphs/graph-node-state-indicator.tsx +0 -47
- package/src/graphs/graph-node-state.ts +0 -111
- package/src/graphs/graph-viewport-surface.tsx +0 -27
- package/src/graphs/index.ts +0 -41
- package/src/index.ts +0 -209
- package/src/layout/action-row.tsx +0 -53
- package/src/layout/surface-panel.tsx +0 -91
- package/src/overlays/collapsible.tsx +0 -22
- package/src/overlays/dialog.tsx +0 -148
- package/src/overlays/index.ts +0 -31
- package/src/overlays/overlay-layout.ts +0 -9
- package/src/overlays/popover.tsx +0 -29
- package/src/overlays/scroll-area.tsx +0 -78
- package/src/primitives/button-link.tsx +0 -22
- package/src/primitives/button.tsx +0 -258
- package/src/primitives/icon-button-shell.tsx +0 -49
- package/src/primitives/package-text.tsx +0 -29
- package/src/primitives/typography-roles.ts +0 -12
- package/src/primitives/typography.tsx +0 -165
- package/src/recipes/index.ts +0 -61
- package/src/recipes/widget-frame-content.tsx +0 -114
- package/src/recipes/widget-frame-disclosure.tsx +0 -161
- package/src/recipes/widget-frame-layout.ts +0 -40
- package/src/recipes/widget-frame-skeleton.tsx +0 -16
- package/src/recipes/widget-frame-states.tsx +0 -99
- package/src/recipes/widget-frame-typography.ts +0 -19
- package/src/recipes/widget-frame.tsx +0 -84
- package/src/testing/index.ts +0 -13
- package/src/testing/render.tsx +0 -16
- package/src/utilities/cn.ts +0 -5
- /package/{src → dist}/styles/color-palette-presets.css +0 -0
- /package/{src → dist}/styles/color-role-tokens.css +0 -0
- /package/{src → dist}/styles/layout-role-tokens.css +0 -0
- /package/{src → dist}/styles/text-color-role-tokens.css +0 -0
- /package/{src → dist}/styles/typography-role-tokens.css +0 -0
- /package/{src → dist}/styles/typography-role-utilities.css +0 -0
- /package/{src → dist}/styles/typography-roles.css +0 -0
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
# Widget frame and layout recipes
|
|
2
|
-
|
|
3
|
-
Domain-free widget frame shells and layout recipes for dashboard-like panels.
|
|
4
|
-
Use these components when you need framed content regions with consistent
|
|
5
|
-
typography, state treatments, disclosure controls, and responsive layout helpers
|
|
6
|
-
without importing dashboard features, bento grids, API clients, or app state.
|
|
7
|
-
|
|
8
|
-
## Required setup
|
|
9
|
-
|
|
10
|
-
Import package styles once in your host application before rendering recipes:
|
|
11
|
-
|
|
12
|
-
```css
|
|
13
|
-
@import "@you-agent-factory/components/styles.css";
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
Recipes depend on package role tokens (`--color-surface`, `--shadow-af-card`,
|
|
17
|
-
typography roles) and Tailwind utility classes compiled from those tokens. They
|
|
18
|
-
do not require dashboard `styles.css`, dashboard providers, generated OpenAPI
|
|
19
|
-
types, React Query, Zustand, or app localization context.
|
|
20
|
-
|
|
21
|
-
## Import paths
|
|
22
|
-
|
|
23
|
-
Prefer the recipes category entrypoint for tree-shaking and explicit category
|
|
24
|
-
boundaries:
|
|
25
|
-
|
|
26
|
-
```ts
|
|
27
|
-
import {
|
|
28
|
-
WidgetFrame,
|
|
29
|
-
WidgetSubtitle,
|
|
30
|
-
WidgetDetailCopy,
|
|
31
|
-
WidgetEmptyState,
|
|
32
|
-
WidgetEmptyStateTitle,
|
|
33
|
-
WidgetEmptyStateText,
|
|
34
|
-
WidgetLoadingState,
|
|
35
|
-
WidgetErrorState,
|
|
36
|
-
WidgetSuccessState,
|
|
37
|
-
WidgetFrameDisclosure,
|
|
38
|
-
WidgetFrameDisclosureTrigger,
|
|
39
|
-
WidgetFrameDisclosurePanel,
|
|
40
|
-
widgetFrameDetailCardClass,
|
|
41
|
-
} from "@you-agent-factory/components/recipes";
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
The same exports are also available from the package root:
|
|
45
|
-
|
|
46
|
-
```ts
|
|
47
|
-
import { WidgetFrame } from "@you-agent-factory/components";
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Host ownership
|
|
51
|
-
|
|
52
|
-
The package owns presentation markup, layout classes, and accessibility
|
|
53
|
-
semantics for frame shells. Host applications own everything domain-specific:
|
|
54
|
-
|
|
55
|
-
| Concern | Owner |
|
|
56
|
-
| --- | --- |
|
|
57
|
-
| User-visible copy (titles, messages, labels) | Host |
|
|
58
|
-
| Data fetching, caching, and error mapping | Host |
|
|
59
|
-
| Domain models (factory, work, session, provider) | Host |
|
|
60
|
-
| Collapsed/expanded boolean state | Host |
|
|
61
|
-
| Header and body action callbacks | Host |
|
|
62
|
-
| Bento grid composition, drag/resize, widget selection | Dashboard feature code |
|
|
63
|
-
| Durable cross-route or persisted UI state | Host |
|
|
64
|
-
|
|
65
|
-
Pass copy and state into recipe components as props and children. Do not expect
|
|
66
|
-
recipes to read from your routers, stores, or API layers.
|
|
67
|
-
|
|
68
|
-
## Composition overview
|
|
69
|
-
|
|
70
|
-
A typical framed panel stacks:
|
|
71
|
-
|
|
72
|
-
1. `WidgetFrame` — card shell with title, optional `headerAction`, and scrollable body.
|
|
73
|
-
2. Content primitives — `WidgetSubtitle`, `WidgetDetailCopy`, or arbitrary host children.
|
|
74
|
-
3. State shells — `WidgetLoadingState`, `WidgetErrorState`, `WidgetSuccessState`, or `WidgetEmptyState`.
|
|
75
|
-
4. Optional disclosure — `WidgetFrameDisclosure` + controlled trigger/panel pair.
|
|
76
|
-
|
|
77
|
-
```tsx
|
|
78
|
-
import { useState } from "react";
|
|
79
|
-
import {
|
|
80
|
-
WidgetDetailCopy,
|
|
81
|
-
WidgetEmptyStateText,
|
|
82
|
-
WidgetEmptyStateTitle,
|
|
83
|
-
WidgetFrame,
|
|
84
|
-
WidgetFrameDisclosure,
|
|
85
|
-
WidgetFrameDisclosurePanel,
|
|
86
|
-
WidgetFrameDisclosureTrigger,
|
|
87
|
-
WidgetLoadingState,
|
|
88
|
-
WidgetSubtitle,
|
|
89
|
-
} from "@you-agent-factory/components/recipes";
|
|
90
|
-
|
|
91
|
-
export function ExamplePanel({
|
|
92
|
-
loading,
|
|
93
|
-
title,
|
|
94
|
-
}: {
|
|
95
|
-
loading: boolean;
|
|
96
|
-
title: string;
|
|
97
|
-
}) {
|
|
98
|
-
const [expanded, setExpanded] = useState(false);
|
|
99
|
-
const panelID = "example-panel-details";
|
|
100
|
-
|
|
101
|
-
return (
|
|
102
|
-
<WidgetFrame
|
|
103
|
-
headerAction={
|
|
104
|
-
<button type="button" onClick={() => undefined}>
|
|
105
|
-
Refresh
|
|
106
|
-
</button>
|
|
107
|
-
}
|
|
108
|
-
title={title}
|
|
109
|
-
>
|
|
110
|
-
<WidgetSubtitle>42 host-provided items</WidgetSubtitle>
|
|
111
|
-
{loading ? (
|
|
112
|
-
<WidgetLoadingState>
|
|
113
|
-
<WidgetEmptyStateTitle>Loading content</WidgetEmptyStateTitle>
|
|
114
|
-
<WidgetEmptyStateText>Host-provided loading message.</WidgetEmptyStateText>
|
|
115
|
-
</WidgetLoadingState>
|
|
116
|
-
) : (
|
|
117
|
-
<WidgetDetailCopy>Host-provided detail copy.</WidgetDetailCopy>
|
|
118
|
-
)}
|
|
119
|
-
<WidgetFrameDisclosure>
|
|
120
|
-
<WidgetFrameDisclosureTrigger
|
|
121
|
-
controlsID={panelID}
|
|
122
|
-
expanded={expanded}
|
|
123
|
-
onExpandedChange={setExpanded}
|
|
124
|
-
>
|
|
125
|
-
{expanded ? "Collapse details" : "Expand details"}
|
|
126
|
-
</WidgetFrameDisclosureTrigger>
|
|
127
|
-
<WidgetFrameDisclosurePanel expanded={expanded} id={panelID}>
|
|
128
|
-
<WidgetDetailCopy>Host-provided disclosure content.</WidgetDetailCopy>
|
|
129
|
-
</WidgetFrameDisclosurePanel>
|
|
130
|
-
</WidgetFrameDisclosure>
|
|
131
|
-
</WidgetFrame>
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## Key props and layout helpers
|
|
137
|
-
|
|
138
|
-
### `WidgetFrame`
|
|
139
|
-
|
|
140
|
-
| Prop | Purpose |
|
|
141
|
-
| --- | --- |
|
|
142
|
-
| `title` | Required accessible name (`aria-label` on the frame article). |
|
|
143
|
-
| `children` | Host content region inside the body grid. |
|
|
144
|
-
| `headerAction` | Optional header tools slot (buttons, menus). A spacer preserves header height when omitted. |
|
|
145
|
-
| `wide` | Applies minimum body height for wide dashboard columns. |
|
|
146
|
-
| `bodyScroll` | Enables scrollable body (`overflow-auto`). Defaults to `true`. |
|
|
147
|
-
| `className` / `bodyClassName` | Host layout overrides. Apply `widgetFrameDetailCardClass` via `className` when rendering description lists. |
|
|
148
|
-
|
|
149
|
-
Layout constants exported for host composition:
|
|
150
|
-
|
|
151
|
-
- `widgetFrameDetailCardClass` — description-list spacing inside framed detail cards.
|
|
152
|
-
- `WIDGET_FRAME_MIN_WIDTH_CLASS` — `min-w-0` shrink guard for grid parents.
|
|
153
|
-
- `WIDGET_FRAME_WIDE_BODY_CLASS` — minimum body height for wide layouts.
|
|
154
|
-
- `WIDGET_FRAME_RESPONSIVE_SHELL_CLASS` — full-width responsive shell helper.
|
|
155
|
-
|
|
156
|
-
### State shells
|
|
157
|
-
|
|
158
|
-
| Component | Semantics | Host provides |
|
|
159
|
-
| --- | --- | --- |
|
|
160
|
-
| `WidgetLoadingState` | `role="status"`, `aria-busy="true"` | Loading copy via children; optional `placeholder` or `showDefaultPlaceholder={false}`. |
|
|
161
|
-
| `WidgetErrorState` | `role="alert"` | Error title and message via children. |
|
|
162
|
-
| `WidgetSuccessState` | `role="status"` | Success title and message via children. |
|
|
163
|
-
| `WidgetEmptyState` | Neutral dashed panel | Empty title/text via `WidgetEmptyStateTitle` / `WidgetEmptyStateText` or arbitrary children. |
|
|
164
|
-
|
|
165
|
-
State shells never invent domain-specific text. All user-visible strings come from
|
|
166
|
-
the host.
|
|
167
|
-
|
|
168
|
-
### Disclosure (collapsed / expanded)
|
|
169
|
-
|
|
170
|
-
Use controlled state from the host:
|
|
171
|
-
|
|
172
|
-
- `WidgetFrameDisclosureTrigger` requires `controlsID`, `expanded`, and optional `onExpandedChange`.
|
|
173
|
-
- `WidgetFrameDisclosurePanel` requires matching `id` and `expanded`.
|
|
174
|
-
- Triggers expose `aria-expanded`, `aria-controls`, keyboard focus rings, and `type="button"`.
|
|
175
|
-
- Panels use the `hidden` attribute when collapsed.
|
|
176
|
-
|
|
177
|
-
Icon-only triggers must pass `aria-label`. Labeled triggers use visible button text.
|
|
178
|
-
|
|
179
|
-
### Responsive layout helpers
|
|
180
|
-
|
|
181
|
-
For Storybook demos and host layout tests:
|
|
182
|
-
|
|
183
|
-
- `widgetFrameStoryShellStyle(maxWidth)` — bounded shell wrapper style object.
|
|
184
|
-
- `widgetFrameHasNoHorizontalOverflow(element)` — pure helper for overflow checks.
|
|
185
|
-
- `WIDGET_FRAME_STORY_SHELL_DATA_ATTR` — `data-widget-frame-story-shell` marker for test shells.
|
|
186
|
-
|
|
187
|
-
## Accessibility expectations
|
|
188
|
-
|
|
189
|
-
- Frame title renders as a level-3 heading inside a landmark `article` labeled with the same title text.
|
|
190
|
-
- Loading, error, and success regions use appropriate live-region roles; do not nest conflicting roles.
|
|
191
|
-
- Disclosure triggers are keyboard operable buttons with visible `focus-visible` outlines.
|
|
192
|
-
- Header actions supplied by the host must include accessible names (`aria-label` or visible text).
|
|
193
|
-
- Host copy inside alerts and status regions should use heading + body structure for screen-reader scanability.
|
|
194
|
-
|
|
195
|
-
## Storybook visual reference
|
|
196
|
-
|
|
197
|
-
Package Storybook lives under `Recipes/WidgetFrame`. Stories use package imports
|
|
198
|
-
and package token decorators only — no dashboard providers.
|
|
199
|
-
|
|
200
|
-
| Story | Storybook id | Demonstrates |
|
|
201
|
-
| --- | --- | --- |
|
|
202
|
-
| Success content | `recipes-widgetframe--success-content` | Default framed content |
|
|
203
|
-
| Empty state | `recipes-widgetframe--empty-state` | Host-provided empty copy |
|
|
204
|
-
| Loading state | `recipes-widgetframe--loading-state` | `WidgetLoadingState` + placeholder |
|
|
205
|
-
| Error state | `recipes-widgetframe--error-state` | `WidgetErrorState` alert treatment |
|
|
206
|
-
| Success state | `recipes-widgetframe--success-state` | `WidgetSuccessState` treatment |
|
|
207
|
-
| Collapsed disclosure | `recipes-widgetframe--collapsed-disclosure` | Controlled collapse + expand interaction |
|
|
208
|
-
| Expanded disclosure | `recipes-widgetframe--expanded-disclosure` | Expanded panel visibility |
|
|
209
|
-
| Responsive compact | `recipes-widgetframe--responsive-compact` | 360px bounded shell |
|
|
210
|
-
| Responsive medium | `recipes-widgetframe--responsive-medium` | 768px bounded shell |
|
|
211
|
-
| Responsive wide | `recipes-widgetframe--responsive-wide` | 1280px bounded shell |
|
|
212
|
-
|
|
213
|
-
Run package Storybook locally:
|
|
214
|
-
|
|
215
|
-
```bash
|
|
216
|
-
cd ui/packages/components
|
|
217
|
-
bun run storybook
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
Browser verification for documented stories:
|
|
221
|
-
|
|
222
|
-
```bash
|
|
223
|
-
cd ui/packages/components
|
|
224
|
-
bun run verify:widget-frame-docs
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
Responsive overflow checks (compact + wide at mobile and desktop viewports):
|
|
228
|
-
|
|
229
|
-
```bash
|
|
230
|
-
cd ui/packages/components
|
|
231
|
-
bun run verify:widget-frame-responsive
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
## Allowed dependencies
|
|
235
|
-
|
|
236
|
-
Recipe source may import:
|
|
237
|
-
|
|
238
|
-
- Package utilities (`cn` from `@you-agent-factory/components/utilities`)
|
|
239
|
-
- Package token CSS via the host `styles.css` import
|
|
240
|
-
- React and `react-dom` peer dependencies
|
|
241
|
-
|
|
242
|
-
Recipe source must **not** import:
|
|
243
|
-
|
|
244
|
-
- Dashboard feature modules, routes, or bento grid (`react-grid-layout`)
|
|
245
|
-
- Generated OpenAPI clients or dashboard API adapters
|
|
246
|
-
- React Query, Zustand, Monaco, Sonner, or dashboard i18n/session providers
|
|
247
|
-
- Factory/work/session/provider domain types
|
|
248
|
-
|
|
249
|
-
`check:package-boundary` enforces these rules in CI.
|
|
250
|
-
|
|
251
|
-
## Source-copy guidance
|
|
252
|
-
|
|
253
|
-
Teams may copy recipe files into a host repository to customize markup while
|
|
254
|
-
keeping the same token foundation:
|
|
255
|
-
|
|
256
|
-
1. Import `@you-agent-factory/components/styles.css` in the host app.
|
|
257
|
-
2. Copy only the recipe files you need from `src/recipes/`.
|
|
258
|
-
3. Keep copied code on the package side of your boundary — do not pull dashboard
|
|
259
|
-
modules into copied recipe files.
|
|
260
|
-
4. Retain host ownership of copy, data fetching, disclosure state, and action handlers.
|
|
261
|
-
|
|
262
|
-
**No source-copy CLI or generator ships with this package.** Copy-and-adapt
|
|
263
|
-
workflows are manual and maintained by the host application.
|
|
264
|
-
|
|
265
|
-
## Dashboard integration note
|
|
266
|
-
|
|
267
|
-
The dashboard keeps bento composition (`AgentBentoCard`, grid layout, widget
|
|
268
|
-
picker) in feature code. Dashboard widgets import recipe content primitives from
|
|
269
|
-
`@you-agent-factory/components/recipes` while `DashboardWidgetFrame` remains a
|
|
270
|
-
dashboard-owned wrapper that applies bento-specific chrome.
|
|
271
|
-
|
|
272
|
-
When adopting recipes outside the dashboard, compose `WidgetFrame` directly and
|
|
273
|
-
supply your own header actions, state, and slot content.
|
package/src/category-paths.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/** Planned deep import paths for `@you-agent-factory/components` category entrypoints. */
|
|
2
|
-
export const COMPONENT_CATEGORY_EXPORT_PATHS = [
|
|
3
|
-
"primitives",
|
|
4
|
-
"forms",
|
|
5
|
-
"layout",
|
|
6
|
-
"feedback",
|
|
7
|
-
"data-display",
|
|
8
|
-
"navigation",
|
|
9
|
-
"overlays",
|
|
10
|
-
"charts",
|
|
11
|
-
"graphs",
|
|
12
|
-
"recipes",
|
|
13
|
-
"icons",
|
|
14
|
-
"utilities",
|
|
15
|
-
"testing",
|
|
16
|
-
"tokens",
|
|
17
|
-
] as const;
|
|
18
|
-
|
|
19
|
-
export type ComponentCategoryExportPath =
|
|
20
|
-
(typeof COMPONENT_CATEGORY_EXPORT_PATHS)[number];
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../utilities/cn";
|
|
4
|
-
|
|
5
|
-
import type { ChartPresentation } from "./chart";
|
|
6
|
-
|
|
7
|
-
export type ChartStateStatus = "empty" | "error" | "loading" | "success";
|
|
8
|
-
|
|
9
|
-
export interface ChartStatePanelProps extends HTMLAttributes<HTMLDivElement> {
|
|
10
|
-
action?: ReactNode;
|
|
11
|
-
description: string;
|
|
12
|
-
presentation?: ChartPresentation;
|
|
13
|
-
status: ChartStateStatus;
|
|
14
|
-
title: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// tailwind-exception: intrinsic-sizing
|
|
18
|
-
const CHART_STATE_PANEL_CLASS =
|
|
19
|
-
"flex h-full min-h-[14rem] min-w-0 w-full flex-1 flex-col justify-center";
|
|
20
|
-
// tailwind-exception: intrinsic-sizing
|
|
21
|
-
const CHART_STATE_PANEL_EMBEDDED_CLASS =
|
|
22
|
-
"grid min-h-[14rem] min-w-0 w-full flex-1 flex-col items-start justify-center gap-1.5 p-0 [&_h3]:m-0";
|
|
23
|
-
const CHART_STATE_PANEL_STANDALONE_SHELL_CLASS =
|
|
24
|
-
"grid min-h-60 items-start gap-1.5 rounded-2xl border border-dashed border-outline-variant bg-surface-container-low p-5 [&_h3]:m-0";
|
|
25
|
-
const CHART_STATE_PANEL_TITLE_CLASS =
|
|
26
|
-
"m-0 text-title-medium font-semibold text-on-surface";
|
|
27
|
-
const CHART_STATE_PANEL_DESCRIPTION_CLASS = "m-0 text-body-medium text-on-surface-variant";
|
|
28
|
-
const CHART_STATE_PANEL_SKELETON_CLASS = "animate-pulse rounded-xl bg-af-overlay";
|
|
29
|
-
|
|
30
|
-
function chartStateRole(status: ChartStateStatus): "alert" | "status" {
|
|
31
|
-
return status === "error" ? "alert" : "status";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function chartStateLive(status: ChartStateStatus): "assertive" | "polite" {
|
|
35
|
-
return status === "error" ? "assertive" : "polite";
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function ChartStatePanel({
|
|
39
|
-
action,
|
|
40
|
-
className,
|
|
41
|
-
description,
|
|
42
|
-
presentation = "standalone",
|
|
43
|
-
status,
|
|
44
|
-
title,
|
|
45
|
-
...props
|
|
46
|
-
}: ChartStatePanelProps) {
|
|
47
|
-
const embedded = presentation === "embedded";
|
|
48
|
-
const role = chartStateRole(status);
|
|
49
|
-
const ariaLive = chartStateLive(status);
|
|
50
|
-
const loading = status === "loading";
|
|
51
|
-
|
|
52
|
-
const content = (
|
|
53
|
-
<>
|
|
54
|
-
{loading ? (
|
|
55
|
-
<div aria-hidden="true" className="grid w-full gap-3">
|
|
56
|
-
<div className={cn(CHART_STATE_PANEL_SKELETON_CLASS, "h-4 w-32")} />
|
|
57
|
-
<div className={cn(CHART_STATE_PANEL_SKELETON_CLASS, "h-28 w-full")} />
|
|
58
|
-
</div>
|
|
59
|
-
) : null}
|
|
60
|
-
<h3 className={CHART_STATE_PANEL_TITLE_CLASS}>{title}</h3>
|
|
61
|
-
<p className={CHART_STATE_PANEL_DESCRIPTION_CLASS}>{description}</p>
|
|
62
|
-
{action ? <div className="mt-2">{action}</div> : null}
|
|
63
|
-
</>
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
if (!embedded) {
|
|
67
|
-
return (
|
|
68
|
-
<div
|
|
69
|
-
aria-busy={loading || undefined}
|
|
70
|
-
aria-live={ariaLive}
|
|
71
|
-
className={cn(
|
|
72
|
-
CHART_STATE_PANEL_STANDALONE_SHELL_CLASS,
|
|
73
|
-
CHART_STATE_PANEL_CLASS,
|
|
74
|
-
className,
|
|
75
|
-
)}
|
|
76
|
-
data-chart-presentation={presentation}
|
|
77
|
-
data-chart-state={status}
|
|
78
|
-
role={role}
|
|
79
|
-
{...props}
|
|
80
|
-
>
|
|
81
|
-
{content}
|
|
82
|
-
</div>
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return (
|
|
87
|
-
<div
|
|
88
|
-
aria-busy={loading || undefined}
|
|
89
|
-
aria-live={ariaLive}
|
|
90
|
-
className={cn(
|
|
91
|
-
CHART_STATE_PANEL_EMBEDDED_CLASS,
|
|
92
|
-
CHART_STATE_PANEL_CLASS,
|
|
93
|
-
className,
|
|
94
|
-
)}
|
|
95
|
-
data-chart-presentation={presentation}
|
|
96
|
-
data-chart-state={status}
|
|
97
|
-
role={role}
|
|
98
|
-
{...props}
|
|
99
|
-
>
|
|
100
|
-
{content}
|
|
101
|
-
</div>
|
|
102
|
-
);
|
|
103
|
-
}
|
package/src/charts/chart.tsx
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
CSSProperties,
|
|
3
|
-
HTMLAttributes,
|
|
4
|
-
MouseEvent as ReactMouseEvent,
|
|
5
|
-
ReactNode,
|
|
6
|
-
} from "react";
|
|
7
|
-
import { createContext, useContext } from "react";
|
|
8
|
-
import {
|
|
9
|
-
Legend as RechartsLegend,
|
|
10
|
-
Tooltip as RechartsTooltip,
|
|
11
|
-
ResponsiveContainer,
|
|
12
|
-
type TooltipContentProps,
|
|
13
|
-
} from "recharts";
|
|
14
|
-
import type {
|
|
15
|
-
LegendPayload,
|
|
16
|
-
Props as RechartsLegendContentProps,
|
|
17
|
-
} from "recharts/types/component/DefaultLegendContent";
|
|
18
|
-
import type {
|
|
19
|
-
NameType,
|
|
20
|
-
ValueType,
|
|
21
|
-
} from "recharts/types/component/DefaultTooltipContent";
|
|
22
|
-
|
|
23
|
-
import { cn } from "../utilities/cn";
|
|
24
|
-
|
|
25
|
-
export interface ChartConfigEntry {
|
|
26
|
-
color: string;
|
|
27
|
-
label: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export type ChartConfig = Record<string, ChartConfigEntry>;
|
|
31
|
-
|
|
32
|
-
const ChartContext = createContext<ChartConfig | null>(null);
|
|
33
|
-
|
|
34
|
-
export type ChartPresentation = "embedded" | "standalone";
|
|
35
|
-
|
|
36
|
-
// tailwind-exception: intrinsic-sizing
|
|
37
|
-
const CHART_CONTAINER_STANDALONE_CLASS =
|
|
38
|
-
"relative h-[18rem] rounded-2xl border border-outline bg-surface-container-low p-4 text-on-surface";
|
|
39
|
-
// tailwind-exception: intrinsic-sizing
|
|
40
|
-
const CHART_CONTAINER_EMBEDDED_CLASS =
|
|
41
|
-
"relative flex h-full min-h-0 min-w-0 w-full flex-1 flex-col text-on-surface";
|
|
42
|
-
const DEFAULT_CHART_INITIAL_DIMENSION = { height: 288, width: 640 } as const;
|
|
43
|
-
|
|
44
|
-
const CHART_LEGEND_BUTTON_CLASS =
|
|
45
|
-
"inline-flex min-h-0 items-center justify-center rounded-md border border-transparent bg-transparent px-0 py-1 text-left text-xs font-normal text-on-surface-variant focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-af-focus";
|
|
46
|
-
|
|
47
|
-
function chartContainerClassName(
|
|
48
|
-
presentation: ChartPresentation,
|
|
49
|
-
className?: string,
|
|
50
|
-
): string {
|
|
51
|
-
return cn(
|
|
52
|
-
presentation === "embedded"
|
|
53
|
-
? CHART_CONTAINER_EMBEDDED_CLASS
|
|
54
|
-
: CHART_CONTAINER_STANDALONE_CLASS,
|
|
55
|
-
className,
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function useChartConfig() {
|
|
60
|
-
const context = useContext(ChartContext);
|
|
61
|
-
|
|
62
|
-
if (context === null) {
|
|
63
|
-
throw new Error("Chart components must be rendered inside ChartContainer.");
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return context;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function ChartContainer({
|
|
70
|
-
children,
|
|
71
|
-
className,
|
|
72
|
-
config,
|
|
73
|
-
footer,
|
|
74
|
-
interactionAttributes,
|
|
75
|
-
overlay,
|
|
76
|
-
presentation = "standalone",
|
|
77
|
-
rootAttributes,
|
|
78
|
-
style,
|
|
79
|
-
title,
|
|
80
|
-
}: {
|
|
81
|
-
children: ReactNode;
|
|
82
|
-
className?: string;
|
|
83
|
-
config: ChartConfig;
|
|
84
|
-
footer?: ReactNode;
|
|
85
|
-
interactionAttributes?: HTMLAttributes<HTMLDivElement>;
|
|
86
|
-
overlay?: ReactNode;
|
|
87
|
-
presentation?: ChartPresentation;
|
|
88
|
-
rootAttributes?: Record<string, string>;
|
|
89
|
-
style?: CSSProperties;
|
|
90
|
-
title: string;
|
|
91
|
-
}) {
|
|
92
|
-
const chartSurface = (
|
|
93
|
-
<ResponsiveContainer
|
|
94
|
-
height="100%"
|
|
95
|
-
initialDimension={DEFAULT_CHART_INITIAL_DIMENSION}
|
|
96
|
-
minHeight={0}
|
|
97
|
-
minWidth={0}
|
|
98
|
-
width="100%"
|
|
99
|
-
>
|
|
100
|
-
{children}
|
|
101
|
-
</ResponsiveContainer>
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
<ChartContext.Provider value={config}>
|
|
106
|
-
<div
|
|
107
|
-
aria-label={title}
|
|
108
|
-
className={chartContainerClassName(presentation, className)}
|
|
109
|
-
data-chart-container=""
|
|
110
|
-
data-chart-presentation={presentation}
|
|
111
|
-
role="img"
|
|
112
|
-
{...interactionAttributes}
|
|
113
|
-
{...rootAttributes}
|
|
114
|
-
style={
|
|
115
|
-
{
|
|
116
|
-
...Object.fromEntries(
|
|
117
|
-
Object.entries(config).map(([key, value]) => [
|
|
118
|
-
`--color-${key}`,
|
|
119
|
-
value.color,
|
|
120
|
-
]),
|
|
121
|
-
),
|
|
122
|
-
...style,
|
|
123
|
-
} as CSSProperties
|
|
124
|
-
}
|
|
125
|
-
>
|
|
126
|
-
{overlay ? (
|
|
127
|
-
<div className="pointer-events-none absolute inset-0">{overlay}</div>
|
|
128
|
-
) : null}
|
|
129
|
-
{footer ? (
|
|
130
|
-
<div className="flex min-h-0 flex-1 basis-0 flex-col">
|
|
131
|
-
<div className="h-full min-h-0 flex-1 basis-0">{chartSurface}</div>
|
|
132
|
-
{footer}
|
|
133
|
-
</div>
|
|
134
|
-
) : (
|
|
135
|
-
chartSurface
|
|
136
|
-
)}
|
|
137
|
-
</div>
|
|
138
|
-
</ChartContext.Provider>
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export const ChartTooltip = RechartsTooltip;
|
|
143
|
-
export const ChartLegend = RechartsLegend;
|
|
144
|
-
|
|
145
|
-
export function ChartTooltipContent({
|
|
146
|
-
active,
|
|
147
|
-
className,
|
|
148
|
-
label,
|
|
149
|
-
payload,
|
|
150
|
-
}: TooltipContentProps<ValueType, NameType> & { className?: string }) {
|
|
151
|
-
const config = useChartConfig();
|
|
152
|
-
|
|
153
|
-
if (!active || !payload?.length) {
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return (
|
|
158
|
-
<div
|
|
159
|
-
className={cn(
|
|
160
|
-
"grid min-w-40 gap-2 rounded-xl border border-outline bg-surface-container-high px-3 py-2 text-sm shadow-af-card",
|
|
161
|
-
className,
|
|
162
|
-
)}
|
|
163
|
-
>
|
|
164
|
-
<p className="m-0 font-semibold text-on-surface">{String(label)}</p>
|
|
165
|
-
<div className="grid gap-1">
|
|
166
|
-
{payload.map((entry) => {
|
|
167
|
-
const key = entry.dataKey?.toString() ?? "";
|
|
168
|
-
const item = config[key];
|
|
169
|
-
|
|
170
|
-
return (
|
|
171
|
-
<div
|
|
172
|
-
className="flex items-center justify-between gap-3 text-on-surface-variant"
|
|
173
|
-
key={key}
|
|
174
|
-
>
|
|
175
|
-
<div className="flex items-center gap-2">
|
|
176
|
-
<span
|
|
177
|
-
className="h-2.5 w-2.5 rounded-full"
|
|
178
|
-
style={{
|
|
179
|
-
backgroundColor:
|
|
180
|
-
item?.color ?? entry.color ?? "currentColor",
|
|
181
|
-
}}
|
|
182
|
-
/>
|
|
183
|
-
<span>{item?.label ?? key}</span>
|
|
184
|
-
</div>
|
|
185
|
-
<span className="font-medium text-on-surface">{entry.value}</span>
|
|
186
|
-
</div>
|
|
187
|
-
);
|
|
188
|
-
})}
|
|
189
|
-
</div>
|
|
190
|
-
</div>
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export function ChartLegendContent({
|
|
195
|
-
className,
|
|
196
|
-
getToggleLabel,
|
|
197
|
-
hiddenSeries = new Set<string>(),
|
|
198
|
-
itemClassName,
|
|
199
|
-
onToggleSeries,
|
|
200
|
-
payload,
|
|
201
|
-
swatchClassName,
|
|
202
|
-
}: RechartsLegendContentProps & {
|
|
203
|
-
className?: string;
|
|
204
|
-
getToggleLabel?: (label: string, hidden: boolean) => string;
|
|
205
|
-
hiddenSeries?: ReadonlySet<string>;
|
|
206
|
-
itemClassName?: string;
|
|
207
|
-
onToggleSeries?: (key: string) => void;
|
|
208
|
-
swatchClassName?: string;
|
|
209
|
-
}) {
|
|
210
|
-
const config = useChartConfig();
|
|
211
|
-
|
|
212
|
-
if (!payload?.length) {
|
|
213
|
-
return null;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const stopChartInteraction = (event: ReactMouseEvent<HTMLButtonElement>) => {
|
|
217
|
-
event.stopPropagation();
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
return (
|
|
221
|
-
<div
|
|
222
|
-
className={cn(
|
|
223
|
-
"flex flex-wrap items-center gap-4 pt-3 text-xs text-on-surface-variant",
|
|
224
|
-
className,
|
|
225
|
-
)}
|
|
226
|
-
>
|
|
227
|
-
{payload.map((entry: LegendPayload) => {
|
|
228
|
-
const key = entry.dataKey?.toString() ?? "";
|
|
229
|
-
const item = config[key];
|
|
230
|
-
const label = item?.label ?? key;
|
|
231
|
-
const hidden = hiddenSeries.has(key);
|
|
232
|
-
const content = (
|
|
233
|
-
<>
|
|
234
|
-
<span
|
|
235
|
-
aria-hidden="true"
|
|
236
|
-
className={cn(
|
|
237
|
-
"rounded-full",
|
|
238
|
-
swatchClassName ?? "h-2.5 w-2.5",
|
|
239
|
-
hidden ? "border border-outline bg-surface-container-low" : "",
|
|
240
|
-
)}
|
|
241
|
-
style={{
|
|
242
|
-
backgroundColor: hidden
|
|
243
|
-
? undefined
|
|
244
|
-
: (item?.color ?? entry.color ?? "currentColor"),
|
|
245
|
-
}}
|
|
246
|
-
/>
|
|
247
|
-
<span>{label}</span>
|
|
248
|
-
</>
|
|
249
|
-
);
|
|
250
|
-
|
|
251
|
-
if (!onToggleSeries) {
|
|
252
|
-
return (
|
|
253
|
-
<div
|
|
254
|
-
className={cn("flex items-center gap-2", itemClassName)}
|
|
255
|
-
key={key}
|
|
256
|
-
>
|
|
257
|
-
{content}
|
|
258
|
-
</div>
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return (
|
|
263
|
-
<button
|
|
264
|
-
aria-label={getToggleLabel?.(label, hidden) ?? label}
|
|
265
|
-
aria-pressed={!hidden}
|
|
266
|
-
className={cn(
|
|
267
|
-
CHART_LEGEND_BUTTON_CLASS,
|
|
268
|
-
hidden ? "text-on-surface-disabled" : "",
|
|
269
|
-
itemClassName,
|
|
270
|
-
)}
|
|
271
|
-
data-chart-legend-series={key}
|
|
272
|
-
data-chart-legend-series-hidden={hidden ? "true" : "false"}
|
|
273
|
-
key={key}
|
|
274
|
-
onClick={(event) => {
|
|
275
|
-
event.stopPropagation();
|
|
276
|
-
onToggleSeries(key);
|
|
277
|
-
}}
|
|
278
|
-
onMouseDown={stopChartInteraction}
|
|
279
|
-
type="button"
|
|
280
|
-
>
|
|
281
|
-
{content}
|
|
282
|
-
</button>
|
|
283
|
-
);
|
|
284
|
-
})}
|
|
285
|
-
</div>
|
|
286
|
-
);
|
|
287
|
-
}
|
package/src/charts/index.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/** Stable category path for `@you-agent-factory/components/charts`. */
|
|
2
|
-
export const COMPONENTS_CATEGORY = "charts" as const;
|
|
3
|
-
|
|
4
|
-
export type ComponentsCategory = typeof COMPONENTS_CATEGORY;
|
|
5
|
-
|
|
6
|
-
export {
|
|
7
|
-
ChartContainer,
|
|
8
|
-
ChartLegend,
|
|
9
|
-
ChartLegendContent,
|
|
10
|
-
ChartTooltip,
|
|
11
|
-
ChartTooltipContent,
|
|
12
|
-
type ChartConfig,
|
|
13
|
-
type ChartConfigEntry,
|
|
14
|
-
type ChartPresentation,
|
|
15
|
-
} from "./chart";
|
|
16
|
-
|
|
17
|
-
export {
|
|
18
|
-
ChartStatePanel,
|
|
19
|
-
type ChartStatePanelProps,
|
|
20
|
-
type ChartStateStatus,
|
|
21
|
-
} from "./chart-state-panel";
|