@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.
- package/README.md +223 -0
- package/docs/README.md +83 -0
- package/docs/button.md +119 -0
- package/docs/charts.md +325 -0
- package/docs/data-display-code-panel.md +120 -0
- package/docs/feedback-alert-panel.md +117 -0
- package/docs/feedback-skeleton.md +54 -0
- package/docs/forms-form-field.md +490 -0
- package/docs/forms-input-primitives.md +311 -0
- package/docs/forms-select-primitives.md +362 -0
- package/docs/graphs.md +250 -0
- package/docs/layout-display-primitives.md +211 -0
- package/docs/overlays.md +414 -0
- package/docs/table-data-table.md +331 -0
- package/docs/typography-roles.md +182 -0
- package/docs/widget-frame-recipes.md +273 -0
- package/package.json +161 -0
- package/src/category-paths.ts +20 -0
- package/src/charts/chart-state-panel.tsx +103 -0
- package/src/charts/chart.tsx +287 -0
- package/src/charts/index.ts +21 -0
- package/src/data-display/code-panel.tsx +67 -0
- package/src/data-display/data-table.tsx +180 -0
- package/src/data-display/description-list.tsx +24 -0
- package/src/data-display/index.ts +34 -0
- package/src/data-display/table-layout.ts +12 -0
- package/src/data-display/table.tsx +131 -0
- package/src/feedback/alert-panel-semantics.ts +75 -0
- package/src/feedback/alert-panel.tsx +187 -0
- package/src/feedback/index.ts +21 -0
- package/src/feedback/skeleton.tsx +16 -0
- package/src/forms/index.ts +73 -0
- package/src/forms/package-checkbox.tsx +50 -0
- package/src/forms/package-enum-select.tsx +185 -0
- package/src/forms/package-file-input.tsx +25 -0
- package/src/forms/package-form-field.tsx +202 -0
- package/src/forms/package-input.tsx +25 -0
- package/src/forms/package-native-select.tsx +25 -0
- package/src/forms/package-select.tsx +209 -0
- package/src/forms/package-textarea.tsx +35 -0
- package/src/forms/select-icons.tsx +35 -0
- package/src/graphs/graph-edge-path.ts +241 -0
- package/src/graphs/graph-edge.tsx +130 -0
- package/src/graphs/graph-interactive-example.tsx +187 -0
- package/src/graphs/graph-node-button.tsx +51 -0
- package/src/graphs/graph-node-handle-badge.tsx +108 -0
- package/src/graphs/graph-node-handle.ts +28 -0
- package/src/graphs/graph-node-shell.tsx +111 -0
- package/src/graphs/graph-node-state-indicator.tsx +47 -0
- package/src/graphs/graph-node-state.ts +111 -0
- package/src/graphs/graph-viewport-surface.tsx +27 -0
- package/src/graphs/index.ts +41 -0
- package/src/icons/index.ts +4 -0
- package/src/index.ts +209 -0
- package/src/layout/action-row.tsx +53 -0
- package/src/layout/index.ts +9 -0
- package/src/layout/surface-panel.tsx +91 -0
- package/src/navigation/index.ts +4 -0
- package/src/overlays/collapsible.tsx +22 -0
- package/src/overlays/dialog.tsx +148 -0
- package/src/overlays/index.ts +31 -0
- package/src/overlays/overlay-layout.ts +9 -0
- package/src/overlays/popover.tsx +29 -0
- package/src/overlays/scroll-area.tsx +78 -0
- package/src/primitives/button-link.tsx +22 -0
- package/src/primitives/button.tsx +258 -0
- package/src/primitives/icon-button-shell.tsx +49 -0
- package/src/primitives/index.ts +31 -0
- package/src/primitives/package-text.tsx +29 -0
- package/src/primitives/typography-roles.ts +12 -0
- package/src/primitives/typography.tsx +165 -0
- package/src/recipes/index.ts +61 -0
- package/src/recipes/widget-frame-content.tsx +114 -0
- package/src/recipes/widget-frame-disclosure.tsx +161 -0
- package/src/recipes/widget-frame-layout.ts +40 -0
- package/src/recipes/widget-frame-skeleton.tsx +16 -0
- package/src/recipes/widget-frame-states.tsx +99 -0
- package/src/recipes/widget-frame-typography.ts +19 -0
- package/src/recipes/widget-frame.tsx +84 -0
- package/src/styles/color-palette-presets.css +167 -0
- package/src/styles/color-role-tokens.css +163 -0
- package/src/styles/layout-role-tokens.css +27 -0
- package/src/styles/text-color-role-tokens.css +29 -0
- package/src/styles/typography-role-tokens.css +72 -0
- package/src/styles/typography-role-utilities.css +73 -0
- package/src/styles/typography-roles.css +53 -0
- package/src/styles.css +32 -0
- package/src/testing/index.ts +13 -0
- package/src/testing/render.tsx +16 -0
- package/src/tokens/index.ts +4 -0
- package/src/utilities/cn.ts +5 -0
- package/src/utilities/index.ts +6 -0
|
@@ -0,0 +1,273 @@
|
|
|
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/package.json
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@you-agent-factory/components",
|
|
3
|
+
"description": "Reusable presentation components, design tokens, and docs for You Agent Factory UIs.",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"homepage": "https://github.com/portpowered/you-agent-factory#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/portpowered/you-agent-factory.git",
|
|
11
|
+
"directory": "ui/packages/components"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/portpowered/you-agent-factory/issues"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"README.md",
|
|
21
|
+
"docs/**/*.md",
|
|
22
|
+
"src/**/*.css",
|
|
23
|
+
"src/**/*.ts",
|
|
24
|
+
"src/**/*.tsx",
|
|
25
|
+
"!src/**/*.test.ts",
|
|
26
|
+
"!src/**/*.test.tsx",
|
|
27
|
+
"!src/**/*.stories.ts",
|
|
28
|
+
"!src/**/*.stories.tsx",
|
|
29
|
+
"!src/**/*.harness.test.ts",
|
|
30
|
+
"!src/**/*.integration.test.tsx",
|
|
31
|
+
"!src/**/storybook-*.ts",
|
|
32
|
+
"!src/**/storybook-*.tsx",
|
|
33
|
+
"!src/**/package-*-story-support.tsx",
|
|
34
|
+
"!src/**/*story-fixtures.ts",
|
|
35
|
+
"!src/**/overlay-story*.ts",
|
|
36
|
+
"!src/**/compile-package-token-styles.ts",
|
|
37
|
+
"!src/**/package-token-fixture-usage.ts",
|
|
38
|
+
"!src/**/package-token-styles-fixture.css",
|
|
39
|
+
"!src/testing/package-browser-shims.ts",
|
|
40
|
+
"!src/testing/react-flow-test-shims.ts",
|
|
41
|
+
"!src/testing/vitest.setup.ts",
|
|
42
|
+
"!src/vite-aliases.ts"
|
|
43
|
+
],
|
|
44
|
+
"sideEffects": [
|
|
45
|
+
"*.css",
|
|
46
|
+
"**/*.css"
|
|
47
|
+
],
|
|
48
|
+
"exports": {
|
|
49
|
+
".": {
|
|
50
|
+
"types": "./src/index.ts",
|
|
51
|
+
"default": "./src/index.ts"
|
|
52
|
+
},
|
|
53
|
+
"./styles.css": "./src/styles.css",
|
|
54
|
+
"./primitives": {
|
|
55
|
+
"types": "./src/primitives/index.ts",
|
|
56
|
+
"default": "./src/primitives/index.ts"
|
|
57
|
+
},
|
|
58
|
+
"./forms": {
|
|
59
|
+
"types": "./src/forms/index.ts",
|
|
60
|
+
"default": "./src/forms/index.ts"
|
|
61
|
+
},
|
|
62
|
+
"./layout": {
|
|
63
|
+
"types": "./src/layout/index.ts",
|
|
64
|
+
"default": "./src/layout/index.ts"
|
|
65
|
+
},
|
|
66
|
+
"./feedback": {
|
|
67
|
+
"types": "./src/feedback/index.ts",
|
|
68
|
+
"default": "./src/feedback/index.ts"
|
|
69
|
+
},
|
|
70
|
+
"./data-display": {
|
|
71
|
+
"types": "./src/data-display/index.ts",
|
|
72
|
+
"default": "./src/data-display/index.ts"
|
|
73
|
+
},
|
|
74
|
+
"./navigation": {
|
|
75
|
+
"types": "./src/navigation/index.ts",
|
|
76
|
+
"default": "./src/navigation/index.ts"
|
|
77
|
+
},
|
|
78
|
+
"./overlays": {
|
|
79
|
+
"types": "./src/overlays/index.ts",
|
|
80
|
+
"default": "./src/overlays/index.ts"
|
|
81
|
+
},
|
|
82
|
+
"./charts": {
|
|
83
|
+
"types": "./src/charts/index.ts",
|
|
84
|
+
"default": "./src/charts/index.ts"
|
|
85
|
+
},
|
|
86
|
+
"./graphs": {
|
|
87
|
+
"types": "./src/graphs/index.ts",
|
|
88
|
+
"default": "./src/graphs/index.ts"
|
|
89
|
+
},
|
|
90
|
+
"./recipes": {
|
|
91
|
+
"types": "./src/recipes/index.ts",
|
|
92
|
+
"default": "./src/recipes/index.ts"
|
|
93
|
+
},
|
|
94
|
+
"./icons": {
|
|
95
|
+
"types": "./src/icons/index.ts",
|
|
96
|
+
"default": "./src/icons/index.ts"
|
|
97
|
+
},
|
|
98
|
+
"./utilities": {
|
|
99
|
+
"types": "./src/utilities/index.ts",
|
|
100
|
+
"default": "./src/utilities/index.ts"
|
|
101
|
+
},
|
|
102
|
+
"./testing": {
|
|
103
|
+
"types": "./src/testing/index.ts",
|
|
104
|
+
"default": "./src/testing/index.ts"
|
|
105
|
+
},
|
|
106
|
+
"./tokens": {
|
|
107
|
+
"types": "./src/tokens/index.ts",
|
|
108
|
+
"default": "./src/tokens/index.ts"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"scripts": {
|
|
112
|
+
"build-storybook": "storybook build --loglevel warn",
|
|
113
|
+
"check:package-boundary": "node scripts/check-package-boundary.mjs",
|
|
114
|
+
"check:package-dependency-direction": "node scripts/check-package-dependency-direction.mjs",
|
|
115
|
+
"storybook": "storybook dev -p 6017",
|
|
116
|
+
"test": "bun run test:unit && bun run check:package-boundary && bun run check:package-dependency-direction",
|
|
117
|
+
"test:unit": "vitest run --config vitest.config.ts",
|
|
118
|
+
"typecheck": "tsc -b --noEmit --pretty false",
|
|
119
|
+
"verify": "bun run typecheck && bun run test:unit && bun run build-storybook && bun run check:package-boundary && bun run check:package-dependency-direction",
|
|
120
|
+
"verify:form-field-storybook-browser": "node scripts/verify-package-form-field-storybook-browser.mjs",
|
|
121
|
+
"verify:graph-storybook-viewport-browser": "node scripts/verify-graph-storybook-viewport-browser.mjs",
|
|
122
|
+
"verify:storybook-browser": "node scripts/verify-package-storybook-browser.mjs",
|
|
123
|
+
"verify:storybook-layout-responsive": "node scripts/run-package-layout-display-browser-check.mjs",
|
|
124
|
+
"verify:widget-frame-docs": "node scripts/verify-widget-frame-storybook-docs.mjs",
|
|
125
|
+
"verify:widget-frame-responsive": "node scripts/verify-widget-frame-storybook-responsive.mjs"
|
|
126
|
+
},
|
|
127
|
+
"dependencies": {
|
|
128
|
+
"@radix-ui/react-collapsible": "^1.1.12",
|
|
129
|
+
"@radix-ui/react-dialog": "^1.1.15",
|
|
130
|
+
"@radix-ui/react-popover": "^1.1.15",
|
|
131
|
+
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
132
|
+
"@radix-ui/react-select": "^2.3.0",
|
|
133
|
+
"@radix-ui/react-slot": "^1.2.3",
|
|
134
|
+
"@xyflow/react": "^12.10.2",
|
|
135
|
+
"recharts": "^3.8.1"
|
|
136
|
+
},
|
|
137
|
+
"peerDependencies": {
|
|
138
|
+
"react": "^19.0.0",
|
|
139
|
+
"react-dom": "^19.0.0"
|
|
140
|
+
},
|
|
141
|
+
"devDependencies": {
|
|
142
|
+
"@storybook/react-vite": "^10.3.5",
|
|
143
|
+
"@tailwindcss/node": "^4.2.2",
|
|
144
|
+
"@tailwindcss/vite": "^4.2.2",
|
|
145
|
+
"@vitejs/plugin-react-swc": "^4.1.0",
|
|
146
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
147
|
+
"@testing-library/react": "^16.3.0",
|
|
148
|
+
"@testing-library/user-event": "^14.6.1",
|
|
149
|
+
"@types/react": "^19.2.2",
|
|
150
|
+
"@types/react-dom": "^19.2.2",
|
|
151
|
+
"happy-dom": "^20.9.0",
|
|
152
|
+
"jest-axe": "^10.0.0",
|
|
153
|
+
"react": "^19.0.0",
|
|
154
|
+
"react-dom": "^19.0.0",
|
|
155
|
+
"storybook": "^10.3.5",
|
|
156
|
+
"tailwindcss": "^4.2.2",
|
|
157
|
+
"typescript": "~5.9.3",
|
|
158
|
+
"vite": "^7.1.7",
|
|
159
|
+
"vitest": "4.1.3"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
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];
|
|
@@ -0,0 +1,103 @@
|
|
|
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
|
+
}
|