@flood-md/agent 0.2.12 → 0.2.13
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/DESIGN.md +10 -1
- package/README.md +9 -4
- package/SKILL.md +16 -5
- package/dist/catalog.json +742 -214
- package/dist/materials/component-alert-dialog.md +1 -0
- package/dist/materials/component-app-shell.md +1 -1
- package/dist/materials/component-bar-chart.md +52 -0
- package/dist/materials/component-bar-list.md +41 -0
- package/dist/materials/component-box-plot.md +46 -0
- package/dist/materials/component-bullet-chart.md +43 -0
- package/dist/materials/component-code-snippet.md +3 -1
- package/dist/materials/component-collection-toolbar.md +2 -0
- package/dist/materials/component-command-palette.md +1 -0
- package/dist/materials/component-copy-button.md +2 -0
- package/dist/materials/component-dialog.md +2 -0
- package/dist/materials/component-donut-chart.md +46 -0
- package/dist/materials/component-drawer.md +2 -0
- package/dist/materials/component-dumbbell-chart.md +46 -0
- package/dist/materials/component-heatmap.md +45 -0
- package/dist/materials/component-histogram.md +46 -0
- package/dist/materials/component-image-preview.md +1 -0
- package/dist/materials/component-line-chart.md +50 -0
- package/dist/materials/component-menu.md +2 -0
- package/dist/materials/component-range-chart.md +46 -0
- package/dist/materials/component-scatter-chart.md +48 -0
- package/dist/materials/component-sheet.md +1 -0
- package/dist/materials/component-table.md +1 -1
- package/dist/materials/component-waterfall-chart.md +47 -0
- package/dist/materials/guide-agent-knowledge.md +5 -5
- package/dist/materials/guide-agents.md +35 -2
- package/dist/materials/guide-charts.md +34 -0
- package/dist/materials/guide-foundations.md +2 -2
- package/dist/materials/guide-installation.md +6 -6
- package/dist/materials/guide-introduction.md +2 -1
- package/dist/materials/guide-motion.md +12 -0
- package/dist/materials/guide-skills.md +10 -0
- package/dist/materials/recipe-collection-views.md +3 -0
- package/dist/materials/recipe-navigation-workspace.md +3 -0
- package/dist/materials/recipe-record-management.md +92 -58
- package/knowledge.json +16 -0
- package/lib/inspect.d.ts +14 -2
- package/lib/inspect.mjs +63 -9
- package/manifest.json +11 -1
- package/package.json +1 -1
- package/references/component-families.md +10 -0
- package/references/flood-composition/SKILL.md +7 -0
- package/references/flood-data-display/SKILL.md +85 -0
- package/references/flood-forms/SKILL.md +5 -0
- package/references/flood-overlays/SKILL.md +5 -0
- package/references/flood-records/SKILL.md +13 -4
- package/references/flood-screen-composition/SKILL.md +48 -0
- package/references/flood-verification/SKILL.md +32 -0
- package/references/flood-visual-review/SKILL.md +59 -0
- package/references/rendered-review.md +49 -3
- package/references/routing.md +2 -1
- package/rules.json +34 -2
- package/workflows.json +22 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# ScatterChart
|
|
2
|
+
|
|
3
|
+
Paired numeric observations for inspecting how two measures vary together.
|
|
4
|
+
|
|
5
|
+
Connect Flood once using [the installation guide](https://flood.md/docs/installation). Then import the components you use; no per-component add command is needed.
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
"use client";
|
|
11
|
+
|
|
12
|
+
import { FloodRoot, ScatterChart } from "@flood-md/react";
|
|
13
|
+
import "@flood-md/react/styles.css";
|
|
14
|
+
|
|
15
|
+
export function Example() {
|
|
16
|
+
return (
|
|
17
|
+
<FloodRoot>
|
|
18
|
+
<ScatterChart label="Response time by traffic" xLabel="Requests / sec" yLabel="Response time (ms)" points={[
|
|
19
|
+
{id:"run-1", label:"Run 1", x:12, y:110},
|
|
20
|
+
{id:"run-2", label:"Run 2", x:52, y:162},
|
|
21
|
+
{id:"run-3", label:"Run 3", x:104, y:301}
|
|
22
|
+
]} />
|
|
23
|
+
</FloodRoot>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Design notes
|
|
29
|
+
|
|
30
|
+
- Give each point a stable ID and finite x and y values. Label both axes with their units.
|
|
31
|
+
- Use matching xDomain and yDomain to compare separate plots. Use formatX and formatY for localized values.
|
|
32
|
+
- Inspect the nearest point with the pointer or traverse observations in supplied order with the keyboard.
|
|
33
|
+
|
|
34
|
+
## API reference
|
|
35
|
+
|
|
36
|
+
| Prop | Values | Default |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| `label` | `string` | `Required` |
|
|
39
|
+
| `xLabel` | `string` | `Required` |
|
|
40
|
+
| `yLabel` | `string` | `Required` |
|
|
41
|
+
| `points` | `readonly ScatterChartPoint[]` | `Required` |
|
|
42
|
+
| `xDomain` | `readonly [number, number]` | `—` |
|
|
43
|
+
| `yDomain` | `readonly [number, number]` | `—` |
|
|
44
|
+
| `formatX` | `(value: number) => string` | `—` |
|
|
45
|
+
| `formatY` | `(value: number) => string` | `—` |
|
|
46
|
+
| `emptyLabel` | `string` | `—` |
|
|
47
|
+
| `navigationLabel` | `string` | `—` |
|
|
48
|
+
| `Native HTML props` | `Omit<HTMLAttributes<HTMLDivElement>, "children" \| "role" \| "aria-label">` | `Forwarded` |
|
|
@@ -44,6 +44,7 @@ export function Example() {
|
|
|
44
44
|
| `closeLabel` | `string` | `—` |
|
|
45
45
|
| `closeOnOutsideClick` | `boolean` | `—` |
|
|
46
46
|
| `initialFocusRef` | `RefObject<HTMLElement \| null>` | `—` |
|
|
47
|
+
| `getFallbackFocus` | `() => HTMLElement \| null` | `—` |
|
|
47
48
|
| `size` | `"sm" \| "md" \| "lg"` | `"md"` |
|
|
48
49
|
| `footer` | `ReactNode` | `—` |
|
|
49
50
|
| `Native HTML props` | `Omit<Omit<HTMLAttributes<HTMLDialogElement>, "children" \| "title" \| "role">, "side">` | `Forwarded` |
|
|
@@ -28,7 +28,7 @@ export function Example() {
|
|
|
28
28
|
|
|
29
29
|
- Caption is required and remains the accessible table name with hideCaption. Supply table sections and correct native header/cell associations.
|
|
30
30
|
- Native table props, className/style and HTMLTableElement ref target the actual table. Set style.minWidth when horizontal overflow is preferable to compressed columns.
|
|
31
|
-
- Flood ScrollArea owns horizontal scrolling and keyboard access.
|
|
31
|
+
- Flood ScrollArea owns horizontal scrolling and keyboard access. Set maxViewportHeight for bounded vertical scrolling with stable clearance for the overlay rail. scrollLabel names the viewport independently.
|
|
32
32
|
- Use data-numeric on headers/cells for end alignment and tabular figures; data-align=start/center/end gives logical alignment. No automatic sorting, selection, pagination or data access.
|
|
33
33
|
- Striped and compact/comfortable density are opt-in presentation. Available in 0.2.4.
|
|
34
34
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# WaterfallChart
|
|
2
|
+
|
|
3
|
+
Signed changes and checkpoints along a running total.
|
|
4
|
+
|
|
5
|
+
Connect Flood once using [the installation guide](https://flood.md/docs/installation). Then import the components you use; no per-component add command is needed.
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
"use client";
|
|
11
|
+
|
|
12
|
+
import { FloodRoot, WaterfallChart } from "@flood-md/react";
|
|
13
|
+
import "@flood-md/react/styles.css";
|
|
14
|
+
|
|
15
|
+
export function Example() {
|
|
16
|
+
return (
|
|
17
|
+
<FloodRoot>
|
|
18
|
+
<WaterfallChart label="Net revenue (USD)" steps={[
|
|
19
|
+
{id:"gross", label:"Gross", value:32000, kind:"total"},
|
|
20
|
+
{id:"refunds", label:"Refunds", value:-4500},
|
|
21
|
+
{id:"fees", label:"Fees", value:-2500},
|
|
22
|
+
{id:"net", label:"Net", value:25000, kind:"total"}
|
|
23
|
+
]} />
|
|
24
|
+
</FloodRoot>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Design notes
|
|
30
|
+
|
|
31
|
+
- A change adds its signed value to the running total. A total is an absolute checkpoint that replaces the running total.
|
|
32
|
+
- Use the same domain for charts you want to compare. It must contain zero and every intermediate total. Use formatValue to add units.
|
|
33
|
+
- Hover, tap or use the keyboard to inspect exact changes and running totals. Decreases use a dashed outline.
|
|
34
|
+
|
|
35
|
+
## API reference
|
|
36
|
+
|
|
37
|
+
| Prop | Values | Default |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| `label` | `string` | `Required` |
|
|
40
|
+
| `steps` | `readonly WaterfallChartStep[]` | `Required` |
|
|
41
|
+
| `domain` | `readonly [number, number]` | `—` |
|
|
42
|
+
| `formatValue` | `(value: number) => string` | `—` |
|
|
43
|
+
| `changeLabel` | `string` | `—` |
|
|
44
|
+
| `totalLabel` | `string` | `—` |
|
|
45
|
+
| `emptyLabel` | `string` | `—` |
|
|
46
|
+
| `navigationLabel` | `string` | `—` |
|
|
47
|
+
| `Native HTML props` | `Omit<HTMLAttributes<HTMLDivElement>, "children" \| "role" \| "aria-label">` | `Forwarded` |
|
|
@@ -7,11 +7,11 @@ The same package sources build the website, CLI results and agent instructions.
|
|
|
7
7
|
## Discover, then read
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
npx @flood-md/cli@0.2.
|
|
11
|
-
npx @flood-md/cli@0.2.
|
|
12
|
-
npx @flood-md/cli@0.2.
|
|
13
|
-
npx @flood-md/cli@0.2.
|
|
14
|
-
npx @flood-md/cli@0.2.
|
|
10
|
+
npx @flood-md/cli@0.2.13 info --json
|
|
11
|
+
npx @flood-md/cli@0.2.13 catalog --kind workflow --group foundations
|
|
12
|
+
npx @flood-md/cli@0.2.13 catalog --kind component --search table
|
|
13
|
+
npx @flood-md/cli@0.2.13 read recipe:table-bulk-actions
|
|
14
|
+
npx @flood-md/cli@0.2.13 read component:data-table
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
These commands return JSON and do not install dependencies, edit files, execute
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Using Flood with an agent
|
|
2
2
|
|
|
3
|
+
Flood pairs a React design system with a workflow for agents building and
|
|
4
|
+
reviewing interfaces. Each release connects component contracts, runnable
|
|
5
|
+
recipes and focused skills through the same catalog.
|
|
6
|
+
|
|
3
7
|
Start with the host's instructions, package.json, flood.json and installed
|
|
4
8
|
flood/DESIGN.md. Use matching package/CLI versions and declarations. A newer
|
|
5
9
|
website example does not add APIs to an older installation.
|
|
@@ -82,8 +86,37 @@ component pages. Before completion use verification. For a color-only change,
|
|
|
82
86
|
load customization and the relevant token roles; unrelated guides stay unloaded.
|
|
83
87
|
|
|
84
88
|
Clients supporting the skill-folder convention can discover it. Others can read
|
|
85
|
-
it explicitly
|
|
86
|
-
|
|
89
|
+
it explicitly. For a client that reads project instructions such as `AGENTS.md`,
|
|
90
|
+
add a short trigger to the existing instructions at the scope where Flood is used:
|
|
91
|
+
|
|
92
|
+
```markdown
|
|
93
|
+
For UI work in this project, read `.agents/skills/flood-ui/SKILL.md` first.
|
|
94
|
+
Follow its routing for the screen or component you are changing. Check the
|
|
95
|
+
installed component contract. For visible changes, use the visual review workflow
|
|
96
|
+
to exercise the affected states and inspect screenshots from the running app.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Use the `installedEntry` path in `flood/manifest.json` if it differs. The
|
|
100
|
+
installer preserves `AGENTS.md`; add this trigger yourself if it suits your client.
|
|
101
|
+
|
|
102
|
+
## Review the running interface
|
|
103
|
+
|
|
104
|
+
When composing a new flow, start from a nearby recipe, check the installed
|
|
105
|
+
component contracts and apply the workflow for the task. For example, use the
|
|
106
|
+
[record management recipe](recipes/record-management.md) to see how a collection
|
|
107
|
+
preserves filters, scroll and focus around a detail Drawer and edit form.
|
|
108
|
+
|
|
109
|
+
For a visual issue, exercise the actual state and inspect the captured evidence.
|
|
110
|
+
If it repeats, check the smallest component or layout that can enforce the fix.
|
|
111
|
+
Add a browser assertion when behavior can be measured. Use the relevant workflow
|
|
112
|
+
or a runnable example for decisions that depend on the task, such as information
|
|
113
|
+
hierarchy or which details should stay visible. Use clean runs to test whether
|
|
114
|
+
agents discover and apply new guidance on another task.
|
|
115
|
+
|
|
116
|
+
For a full-window AppShell route, use
|
|
117
|
+
[`assertWorkspaceScroll`](../packages/agent/references/rendered-review.md#require-workspace-scroll-in-browser-tests)
|
|
118
|
+
in the browser suite. Exercise both the populated and filtered states so
|
|
119
|
+
document scrolling fails the test on either state.
|
|
87
120
|
|
|
88
121
|
The rules index is data, not an executable policy engine. It cannot make an agent
|
|
89
122
|
obey guidance or certify accessibility. Host checks and Flood's repository
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Charts
|
|
2
|
+
|
|
3
|
+
[Try the three latency charts](https://flood.md/docs/charts#latency-example)
|
|
4
|
+
with one shared service filter, or pick a chart below and copy its React example.
|
|
5
|
+
For setup in React or Next.js, see [Installation](installation.md).
|
|
6
|
+
|
|
7
|
+
## Trends and comparisons
|
|
8
|
+
|
|
9
|
+
- [LineChart](https://flood.md/components/line-chart) shows how a measure changes over time. Compare this week with last week on the same scale.
|
|
10
|
+
- [Sparkline](https://flood.md/components/sparkline) shows a small trend beside a value in a table or summary.
|
|
11
|
+
- [BarChart](https://flood.md/components/bar-chart) compares categories. Group series to compare actual and planned values, or use percent stacks to compare their shares.
|
|
12
|
+
- [BarList](https://flood.md/components/bar-list) ranks named values, such as traffic sources, where the labels and counts matter as much as the bars.
|
|
13
|
+
- [BulletChart](https://flood.md/components/bullet-chart) compares a single value with a target and optional reference bands.
|
|
14
|
+
|
|
15
|
+
## Distributions and relationships
|
|
16
|
+
|
|
17
|
+
- [Histogram](https://flood.md/components/histogram) shows how often values fall into intervals. Use it to see whether requests cluster near 100 ms or have a long tail.
|
|
18
|
+
- [BoxPlot](https://flood.md/components/box-plot) compares the median, quartiles and endpoints across groups, such as latency by service.
|
|
19
|
+
- [ScatterChart](https://flood.md/components/scatter-chart) shows the relationship between two measurements, such as throughput and response time.
|
|
20
|
+
- [Heatmap](https://flood.md/components/heatmap) shows patterns across two dimensions, such as activity by day and hour.
|
|
21
|
+
- [RangeChart](https://flood.md/components/range-chart) shows an interval for each item, such as a forecast range.
|
|
22
|
+
|
|
23
|
+
## Parts of a whole and change
|
|
24
|
+
|
|
25
|
+
- [DonutChart](https://flood.md/components/donut-chart) shows a few shares of one whole, such as spending by category.
|
|
26
|
+
- [WaterfallChart](https://flood.md/components/waterfall-chart) explains how individual increases and decreases add up to a final value.
|
|
27
|
+
- [DumbbellChart](https://flood.md/components/dumbbell-chart) compares two values for each category, such as before and after a rollout.
|
|
28
|
+
|
|
29
|
+
## Inspecting values
|
|
30
|
+
|
|
31
|
+
Give each chart a name that includes its measure. Keep units consistent across
|
|
32
|
+
axis labels and value formatting. Hover or focus interactive plots to inspect
|
|
33
|
+
values, then use the arrow keys to move through the data. Where readers need to
|
|
34
|
+
scan or copy many exact values, provide the data in a table alongside the chart.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Foundations tokens · 0.2.
|
|
1
|
+
# Foundations tokens · 0.2.13
|
|
2
2
|
|
|
3
|
-
This guide describes the **0.2.
|
|
3
|
+
This guide describes the **0.2.13** foundation exports. Keep Flood packages at
|
|
4
4
|
matching exact versions. Existing 0.1.1 installs use their earlier token contract.
|
|
5
5
|
|
|
6
6
|
Foundations separates fixed reference values (`ref`) from semantic roles (`sys`).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Installation · 0.2.
|
|
1
|
+
# Installation · 0.2.13
|
|
2
2
|
|
|
3
|
-
The commands below target version 0.2.
|
|
3
|
+
The commands below target version 0.2.13. Verify registry availability before installation; for local source evaluation, see the tarball instructions at the end of this guide.
|
|
4
4
|
|
|
5
5
|
Use Node.js 22.12 or newer and an existing npm-based React/Next.js project.
|
|
6
6
|
React 18.3/19 is supported; React 19 and Next.js App Router are integration targets.
|
|
@@ -15,8 +15,8 @@ repeat installation when you start using another component.
|
|
|
15
15
|
## Connect with the CLI
|
|
16
16
|
|
|
17
17
|
```sh
|
|
18
|
-
npx @flood-md/cli@0.2.
|
|
19
|
-
npx @flood-md/cli@0.2.
|
|
18
|
+
npx @flood-md/cli@0.2.13 init --dry-run
|
|
19
|
+
npx @flood-md/cli@0.2.13 init
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
The installer adds exact matching tokens, React and agent packages. It creates
|
|
@@ -40,7 +40,7 @@ No Tailwind configuration or font CDN is needed. The foundations profile is dark
|
|
|
40
40
|
only; legacy theme behavior remains available outside `FloodRoot`.
|
|
41
41
|
|
|
42
42
|
```sh
|
|
43
|
-
npx @flood-md/cli@0.2.
|
|
43
|
+
npx @flood-md/cli@0.2.13 doctor
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Doctor checks package versions and guide presence, not stylesheet imports or
|
|
@@ -50,7 +50,7 @@ reference `flood/DESIGN.md` from its existing instructions.
|
|
|
50
50
|
## Manual package installation
|
|
51
51
|
|
|
52
52
|
```sh
|
|
53
|
-
npm install --save-exact @flood-md/tokens@0.2.
|
|
53
|
+
npm install --save-exact @flood-md/tokens@0.2.13 @flood-md/react@0.2.13 @flood-md/agent@0.2.13
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
Import the stylesheet and use `FloodRoot` as above. Manual installation does not
|
|
@@ -16,6 +16,7 @@ them without a separate content service.
|
|
|
16
16
|
| [Project UI](project-ui.md) | Optional semantic @/ui/button imports in your application |
|
|
17
17
|
| [Layout](layout.md) | Intrinsic actions, responsive forms, choice sizing, gaps and hierarchy |
|
|
18
18
|
| [Components](components.md) | Available controls, props and form composition |
|
|
19
|
+
| [Charts](charts.md) | Choose a chart by the question it answers and try the live latency example |
|
|
19
20
|
| [Base component inventory](base-components.md) | Available primitives and controls in the base release |
|
|
20
21
|
| [Customization](theming.md) | Scoped dark foundations overrides and legacy theme boundaries |
|
|
21
22
|
| [Foundations](foundations.md) | Typed semantic tokens and neutral dark profile for 0.2.11 |
|
|
@@ -30,7 +31,7 @@ them without a separate content service.
|
|
|
30
31
|
|
|
31
32
|
## Versions
|
|
32
33
|
|
|
33
|
-
This branch documents **version 0.2.
|
|
34
|
+
This branch documents **version 0.2.13**; source availability does
|
|
34
35
|
not establish npm publication. Use matching exact versions of the Flood packages. Documentation on `main` can describe later work; the
|
|
35
36
|
[release tags](https://github.com/tillwithered/flood.md/releases) preserve the
|
|
36
37
|
source and docs for each release. Installed `flood/DESIGN.md` takes precedence
|
|
@@ -54,6 +54,18 @@ behavior of their children. State updates and focus take effect immediately.
|
|
|
54
54
|
| `CodeSnippet`, `Card`, `DataList`, `DataListItem`, `FileItem`, `FileList`, `AvatarGroup` | Embedded actions and avatars own motion. Reading order and record layout remain stable. |
|
|
55
55
|
| `Badge`, `DescriptionList`, `Table`, `Image`, `List`, `Figure`, `Metric`, `Timeline`, `ColorSwatch`, `FileMeta` | Static content. Changes to data, labels and supporting media render immediately. |
|
|
56
56
|
| `Sparkline` | Hover briefly strengthens the latest point and area. Data changes render immediately. |
|
|
57
|
+
| `LineChart` | Crosshair, markers and local line emphasis track the pointer continuously. The readout shows the nearest recorded sample and lifts clear of the marker near the trailing edge. On exit the readout and marks fade in place from their last pointer position. |
|
|
58
|
+
| `BarList` | Uses Meter's value transition and the same fast highlight as chart inspection. Labels and values update immediately. |
|
|
59
|
+
| `BarChart` | Uses the fast motion role to emphasize the inspected group while its neighbors dim. The readout updates with the active category and column geometry stays fixed. |
|
|
60
|
+
| `DonutChart` | Uses the fast motion role for the inspected segment's outline. Category colors, fills and geometry stay fixed, and the center readout updates immediately. |
|
|
61
|
+
| `Heatmap` | Moves the value tooltip immediately to the inspected cell and keeps the matrix fixed. Visual gutters share the adjacent cells' hit areas. |
|
|
62
|
+
| `ScatterChart` | Highlights the inspected observation and presents its coordinates. Points keep their positions. |
|
|
63
|
+
| `RangeChart` | Highlights the inspected interval while its exact bounds update immediately. |
|
|
64
|
+
| `BulletChart` | Uses the Meter transition for the actual value. Target marks and exact values update immediately. |
|
|
65
|
+
| `WaterfallChart` | Highlights the inspected step and shows the change and running balance. |
|
|
66
|
+
| `Histogram` | Shows exact bin bounds and count as inspection moves. Bin geometry stays fixed. |
|
|
67
|
+
| `BoxPlot` | Highlights the inspected distribution and anchors its summary to the median. The tooltip prefers the right side and flips when space runs out. |
|
|
68
|
+
| `DumbbellChart` | Highlights the inspected comparison without moving its marks. The readout updates immediately. |
|
|
57
69
|
| `Avatar` | Loaded image eases in within a fixed frame. Fallback text is immediately available. |
|
|
58
70
|
| `DataTable` | Selected row paint, chevron rotation and a short height transition for row details. Sorting, pagination and column resize update geometry immediately. |
|
|
59
71
|
| `Tooltip`, `Popover`, `Menu`, `ContextMenu`, `HoverCard`, `CommandPalette`, `Dialog`, `AlertDialog`, `Drawer`, `Sheet`, `ImagePreview` | Anchored entrances follow placement. Modal and edge panels have their own timing. Sheet uses the bottom Drawer entrance. Controls, focus, close and positioning retain their native behavior. |
|
|
@@ -13,11 +13,19 @@ The hierarchy workflow covers task/group/field roles, common control tracks and
|
|
|
13
13
|
relationship spacing. It complements editorial decisions and the spacing workflow;
|
|
14
14
|
it does not prescribe one screen template.
|
|
15
15
|
|
|
16
|
+
The screen composition workflow helps choose page structure and reading order
|
|
17
|
+
for landing pages, workspaces, forms and documentation. Review it by running
|
|
18
|
+
the user's find, compare or act task in the rendered screen.
|
|
19
|
+
|
|
16
20
|
The records workflow covers list/detail information selection, stable scan
|
|
17
21
|
positions and the distinction between category, lifecycle state, priority and
|
|
18
22
|
time. It includes examples where those attributes should remain visible, rather
|
|
19
23
|
than a universal rule to hide metadata or limit badge counts.
|
|
20
24
|
|
|
25
|
+
Visual review exercises the running UI, captures the affected states and checks
|
|
26
|
+
the screenshots before handoff. Use it for new UI, screenshot feedback and
|
|
27
|
+
visible regressions. Keep browser evidence with the findings or the fix.
|
|
28
|
+
|
|
21
29
|
Use [Agent knowledge](agent-knowledge.md) to discover these workflows by semantic
|
|
22
30
|
group and read the installed version. The catalog separates prerequisites from
|
|
23
31
|
optional related components; grouping is not a request to load every skill.
|
|
@@ -40,6 +48,7 @@ Layout and task recipes assembled from existing primitives.
|
|
|
40
48
|
| --- | --- | --- |
|
|
41
49
|
| flood-composition | Build or review Flood UI from existing library primitives before adding composites. Use for component, website, playground and host-interface work, especially when a layout fix risks replacing a reusable element with custom markup. | [Read skill](/agent/references/flood-composition/SKILL.md) |
|
|
42
50
|
| flood-interface-content | Write or review Flood interface content with editorial decisions about copy, labels, hierarchy and states. Use for visible UI text and reference adaptation; not typography styling, campaigns or rewriting user documents. | [Read skill](/agent/references/flood-interface-content/SKILL.md) |
|
|
51
|
+
| flood-screen-composition | Choose the layout, reading order and first useful action for a Flood screen. Use for new screens or when an existing page is hard to scan, compare or act on. | [Read skill](/agent/references/flood-screen-composition/SKILL.md) |
|
|
43
52
|
| flood-hierarchy | Establish visual hierarchy, shared form tracks and vertical rhythm in Flood screens, forms and overlays. Use when titles, groups and labels compete or a composed interface feels flat; not a fixed page template. | [Read skill](/agent/references/flood-hierarchy/SKILL.md) |
|
|
44
53
|
| flood-spacing | Diagnose Flood spacing, density, nested radii and alignment from rendered geometry. Use for large gaps, crowded rows or shifting compositions. | [Read skill](/agent/references/flood-spacing/SKILL.md) |
|
|
45
54
|
| flood-records | Compose record lists and detail views with a clear metadata hierarchy. Use for crowded status/category/priority/date rows, drifting scan positions or deciding between a list and a comparison table. | [Read skill](/agent/references/flood-records/SKILL.md) |
|
|
@@ -74,6 +83,7 @@ Accessibility, evidence and regression checks.
|
|
|
74
83
|
| flood-interface-content | Write or review Flood interface content with editorial decisions about copy, labels, hierarchy and states. Use for visible UI text and reference adaptation; not typography styling, campaigns or rewriting user documents. | [Read skill](/agent/references/flood-interface-content/SKILL.md) |
|
|
75
84
|
| flood-accessibility | Review Flood interface names, keyboard flow, focus, perception and reflow in the actual host. Use for interaction or accessibility acceptance. | [Read skill](/agent/references/flood-accessibility/SKILL.md) |
|
|
76
85
|
| flood-verification | Verify Flood component or composed-interface changes against applicable contracts and actual evidence. Use for stabilization, regression or completion review. | [Read skill](/agent/references/flood-verification/SKILL.md) |
|
|
86
|
+
| flood-visual-review | Review rendered Flood UI with Playwright or equivalent browser tooling. Use for visual bugs, screenshot feedback, new or changed UI, and visual regressions across interaction states. | [Read skill](/agent/references/flood-visual-review/SKILL.md) |
|
|
77
87
|
|
|
78
88
|
## Motion
|
|
79
89
|
|
|
@@ -239,6 +239,9 @@ defines reset scope and supplies canClear for any state held by quickFilters.
|
|
|
239
239
|
At most two task-important quick properties remain inline; additional properties
|
|
240
240
|
belong inside Filters. Summaries outside the panel name the property and preserve
|
|
241
241
|
any-match meaning. Container width, rather than viewport size, governs reflow.
|
|
242
|
+
When search and filters share a wide row with a status or view selector, use
|
|
243
|
+
`align="end"` on CollectionToolbar. Check that the final control reaches the
|
|
244
|
+
row's trailing content edge and that the row wraps with enlarged text.
|
|
242
245
|
The Projects table places its Columns control in CollectionToolbar's `actions`
|
|
243
246
|
slot via DataTable's `toolbar` render function. It shares the tool row with
|
|
244
247
|
search and filters, and the commands wrap as a group in a narrow container.
|
|
@@ -62,6 +62,9 @@ embedded shell an explicit block size. Choose `scroll="page"` for natural
|
|
|
62
62
|
document scrolling. Place a persistent top bar and footer in the shell slots,
|
|
63
63
|
and PageHeader inside main. The shell has a skip target and owns the scroll
|
|
64
64
|
boundary; the host owns routes and persisted choices.
|
|
65
|
+
For a full-window workspace with a padded content edge, use
|
|
66
|
+
`scrollContentInset="none"` when that padding already clears the overlay rail.
|
|
67
|
+
Verify that the document width stays fixed as its collection grows and shrinks.
|
|
65
68
|
|
|
66
69
|
For a single Sidebar, opt into `navigationDrawer` with a width threshold in CSS
|
|
67
70
|
pixels and a `renderContent(close)` function. AppShell observes its own width.
|
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
[Open the working composition](/playground/records).
|
|
4
4
|
|
|
5
|
-
Search requests, narrow the
|
|
6
|
-
Drawer. Saving
|
|
5
|
+
Search requests, narrow the table by status, open one request, and edit it in a
|
|
6
|
+
Drawer. Saving updates the request and returns to the same table.
|
|
7
7
|
The example uses in-memory fixtures that reset on reload.
|
|
8
8
|
|
|
9
9
|
## Choose where details open
|
|
10
10
|
|
|
11
11
|
Use a Drawer for a bounded inspection or edit that starts and ends in the same
|
|
12
12
|
list. Use a destination page for details that need a stable URL, substantial
|
|
13
|
-
room, or several independent tasks.
|
|
14
|
-
because opening its Drawer is an action on the current screen.
|
|
13
|
+
room, or several independent tasks.
|
|
15
14
|
|
|
16
15
|
When users compare several attributes, DataTable can use a `primaryAction`
|
|
17
16
|
in the identity column. Pass the Drawer trigger handlers and ref to that
|
|
18
17
|
action. Check the row background, title and description, checkbox and any
|
|
19
18
|
secondary menu independently. Use `toolbar` and `inset="roomy"` for a heading
|
|
20
|
-
and filters that share the table surface.
|
|
19
|
+
and filters that share the table surface. Use the request title as the visible
|
|
20
|
+
action and keep its ID beside it for disambiguation.
|
|
21
21
|
|
|
22
22
|
```tsx
|
|
23
23
|
<Drawer title="Review workspace access" size="lg"
|
|
@@ -52,6 +52,10 @@ reading area. Compose the body from Section for separately named content,
|
|
|
52
52
|
DescriptionList for facts and Fieldset for related controls. Check wrapping and
|
|
53
53
|
scrolling with the longest title and a real footer action before selecting a size.
|
|
54
54
|
Use the group heading size inside a detail Drawer to keep the record name prominent.
|
|
55
|
+
Keep the request facts in one DescriptionList and use a compact, captioned Table
|
|
56
|
+
for related records that have comparable columns, such as activity dates and events.
|
|
57
|
+
Give that table its own heading when it identifies a distinct section. The Drawer
|
|
58
|
+
body owns vertical scrolling and the footer keeps the next action within reach.
|
|
55
59
|
|
|
56
60
|
When the detail contains line items and a total, use the Table footer to mark
|
|
57
61
|
the summary and keep its amount aligned with the line-item amounts. A row header
|
|
@@ -69,13 +73,14 @@ labels the total, and the Table footer supplies the separator and emphasis.
|
|
|
69
73
|
## Keep browsing state and edit state separate
|
|
70
74
|
|
|
71
75
|
Keep search, filter, accepted records and the open record ID in the host.
|
|
72
|
-
Keep the
|
|
76
|
+
Keep the DataTable and its ScrollArea mounted while the Drawer is open. Reset the
|
|
73
77
|
scroll position only when the user changes the query or filter.
|
|
74
78
|
|
|
75
79
|
Entering edit mode copies the selected record. Cancel edit returns to details
|
|
76
80
|
without changing accepted data. Saving replaces the record by stable ID.
|
|
77
|
-
Recompute matches using the existing search and filter.
|
|
78
|
-
|
|
81
|
+
Recompute matches using the existing search and filter. Use a floating ToastRegion
|
|
82
|
+
for the save result so it cannot move the table. If the updated record leaves
|
|
83
|
+
the results, explain why and preserve the query. For a remote save, close
|
|
79
84
|
on accepted data and retain the draft with actionable feedback on failure.
|
|
80
85
|
|
|
81
86
|
## Restore focus to a useful place
|
|
@@ -83,8 +88,9 @@ on accepted data and retain the draft with actionable feedback on failure.
|
|
|
83
88
|
Forward the Drawer trigger props from the single overlay to the row action
|
|
84
89
|
that opens it. Focus Edit request when details open, Subject when editing starts,
|
|
85
90
|
and Edit request after Cancel edit. On close, return focus to the same row
|
|
86
|
-
action without scrolling.
|
|
87
|
-
|
|
91
|
+
action without scrolling. Drawer resolves `getFallbackFocus` after closing
|
|
92
|
+
if the row left the results. The recipe returns Search requests and keeps
|
|
93
|
+
the current query.
|
|
88
94
|
|
|
89
95
|
Keep subject and ID together in the list. Status earns a stable trailing slot
|
|
90
96
|
because users filter and compare by it. Put owner and the longer summary in the
|
|
@@ -105,9 +111,10 @@ Drawer's conditional detail content.
|
|
|
105
111
|
|
|
106
112
|
import {useEffect, useId, useLayoutEffect, useRef, useState, type FormEvent} from "react";
|
|
107
113
|
import {
|
|
108
|
-
|
|
109
|
-
Field, Grid, Heading, Inline, Input,
|
|
110
|
-
Stack, StatusIndicator, Surface,
|
|
114
|
+
Button, DataTable, DescriptionList, Drawer, EmptyState,
|
|
115
|
+
Field, Grid, Heading, Inline, Input, SearchInput, Section, Select,
|
|
116
|
+
Stack, StatusIndicator, Surface, Table, ToastRegion,
|
|
117
|
+
type DataTableColumn, type ToastItem,
|
|
111
118
|
} from "@flood-md/react";
|
|
112
119
|
|
|
113
120
|
const statuses = {
|
|
@@ -125,6 +132,24 @@ type RequestRecord = {
|
|
|
125
132
|
summary: string;
|
|
126
133
|
};
|
|
127
134
|
|
|
135
|
+
const requestColumns: DataTableColumn[] = [
|
|
136
|
+
{id: "subject", label: "Subject", sortable: true},
|
|
137
|
+
{id: "status", label: "Status", sortable: true},
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
const activityByRequest: Record<string, readonly {date: string; activity: string}[]> = {
|
|
141
|
+
"REQ-105": [
|
|
142
|
+
{date: "2026-11-10", activity: "Access issue reported"},
|
|
143
|
+
{date: "2026-11-11", activity: "Identity verified"},
|
|
144
|
+
{date: "2026-11-12", activity: "Recovery link sent"},
|
|
145
|
+
],
|
|
146
|
+
"REQ-117": [
|
|
147
|
+
{date: "2026-11-11", activity: "Permission review requested"},
|
|
148
|
+
{date: "2026-11-12", activity: "Regional roles exported"},
|
|
149
|
+
],
|
|
150
|
+
};
|
|
151
|
+
const activityDate = new Intl.DateTimeFormat("en", {month: "short", day: "numeric", timeZone: "UTC"});
|
|
152
|
+
|
|
128
153
|
const fixtures: RequestRecord[] = [
|
|
129
154
|
{id: "REQ-104", title: "Update billing address", owner: "Mina Chen", status: "new", summary: "Use the new address on future invoices."},
|
|
130
155
|
{id: "REQ-105", title: "Restore workspace access", owner: "Alex Morgan", status: "active", summary: "A teammate cannot sign in after changing email."},
|
|
@@ -157,25 +182,20 @@ export function RecordManagement() {
|
|
|
157
182
|
const [status, setStatus] = useState<Status | "all">("all");
|
|
158
183
|
const [recordId, setRecordId] = useState<string | null>(null);
|
|
159
184
|
const [draft, setDraft] = useState<RequestRecord | null>(null);
|
|
160
|
-
const [notice, setNotice] = useState(
|
|
185
|
+
const [notice, setNotice] = useState<ToastItem | null>(null);
|
|
161
186
|
const search = useRef<HTMLInputElement>(null);
|
|
162
|
-
const
|
|
187
|
+
const table = useRef<HTMLDivElement>(null);
|
|
163
188
|
const subject = useRef<HTMLInputElement>(null);
|
|
164
189
|
const edit = useRef<HTMLButtonElement>(null);
|
|
165
|
-
const opener = useRef<HTMLButtonElement>(null);
|
|
166
|
-
const restore = useRef(false);
|
|
167
190
|
const returnToEdit = useRef(false);
|
|
168
191
|
const selected = records.find(record => record.id === recordId);
|
|
192
|
+
const activity = selected ? activityByRequest[selected.id] : undefined;
|
|
169
193
|
const results = records.filter(record => matchesRequest(record, query, status));
|
|
170
194
|
const editing = draft !== null;
|
|
171
195
|
const open = selected !== undefined;
|
|
172
196
|
|
|
173
197
|
useBrowserLayoutEffect(() => {
|
|
174
|
-
if (
|
|
175
|
-
restore.current = false;
|
|
176
|
-
const target = opener.current?.isConnected ? opener.current : search.current;
|
|
177
|
-
target?.focus({preventScroll: true});
|
|
178
|
-
} else if (editing) {
|
|
198
|
+
if (editing) {
|
|
179
199
|
subject.current?.focus({preventScroll: true});
|
|
180
200
|
} else if (open && returnToEdit.current) {
|
|
181
201
|
returnToEdit.current = false;
|
|
@@ -186,12 +206,11 @@ export function RecordManagement() {
|
|
|
186
206
|
function changeQuery(nextQuery: string, nextStatus: Status | "all") {
|
|
187
207
|
setQuery(nextQuery);
|
|
188
208
|
setStatus(nextStatus);
|
|
189
|
-
setNotice(
|
|
190
|
-
|
|
209
|
+
setNotice(null);
|
|
210
|
+
table.current?.querySelector('[role="region"][aria-label="Requests"]')?.scrollTo({top: 0});
|
|
191
211
|
}
|
|
192
212
|
|
|
193
213
|
function closeRecord() {
|
|
194
|
-
restore.current = true;
|
|
195
214
|
returnToEdit.current = false;
|
|
196
215
|
setDraft(null);
|
|
197
216
|
setRecordId(null);
|
|
@@ -208,9 +227,12 @@ export function RecordManagement() {
|
|
|
208
227
|
}
|
|
209
228
|
const updated = {...draft, title, owner: draft.owner.trim()};
|
|
210
229
|
setRecords(current => current.map(record => record.id === updated.id ? updated : record));
|
|
211
|
-
setNotice(
|
|
212
|
-
|
|
213
|
-
: `${updated.id} updated
|
|
230
|
+
setNotice({
|
|
231
|
+
id: updated.id,
|
|
232
|
+
title: `${updated.id} updated`,
|
|
233
|
+
description: matchesRequest(updated, query, status) ? undefined : "It no longer matches your search or filter.",
|
|
234
|
+
status: "success",
|
|
235
|
+
});
|
|
214
236
|
closeRecord();
|
|
215
237
|
}
|
|
216
238
|
|
|
@@ -245,35 +267,37 @@ export function RecordManagement() {
|
|
|
245
267
|
open={open}
|
|
246
268
|
onOpenChange={open => { if (!open) closeRecord(); }}
|
|
247
269
|
initialFocusRef={edit}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
270
|
+
getFallbackFocus={() => search.current}
|
|
271
|
+
trigger={({ref, onClick, ...trigger}) =>
|
|
272
|
+
<Surface elevation="raised" padding="0" className="request-table-frame">
|
|
273
|
+
<DataTable ref={table} caption="Requests" hideCaption inset="roomy" minWidth="min-content"
|
|
274
|
+
maxViewportHeight="26rem" stickyHeader pageSize={fixtures.length}
|
|
275
|
+
columns={requestColumns} rows={results.map(record => ({
|
|
276
|
+
id: record.id,
|
|
277
|
+
cells: {status: <StatusIndicator {...statuses[record.status]} size="sm" />},
|
|
278
|
+
sortValues: {status: statuses[record.status].label},
|
|
279
|
+
primaryAction: {
|
|
280
|
+
column: "subject", title: record.title, description: record.id,
|
|
281
|
+
buttonProps: {
|
|
282
|
+
...trigger,
|
|
283
|
+
"aria-expanded": open && record.id === recordId,
|
|
284
|
+
"aria-label": `${record.title}, ${record.id}`,
|
|
285
|
+
onClick: event => {
|
|
286
|
+
ref(event.currentTarget);
|
|
287
|
+
setRecordId(record.id);
|
|
288
|
+
onClick?.(event);
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
}))}
|
|
293
|
+
emptyContent={<EmptyState title="No matching requests" actions={<Button variant="subtle" onClick={() => {
|
|
294
|
+
search.current?.focus({preventScroll: true});
|
|
295
|
+
changeQuery("", "all");
|
|
296
|
+
}}>Clear filters</Button>} />} />
|
|
273
297
|
</Surface>}
|
|
274
298
|
footer={draft
|
|
275
|
-
? <Inline gap="2"><Button
|
|
276
|
-
<Button
|
|
299
|
+
? <Inline gap="2"><Button variant="subtle" onClick={cancelEdit}>Cancel edit</Button>
|
|
300
|
+
<Button type="submit" form={formId}>Save changes</Button></Inline>
|
|
277
301
|
: <Button ref={edit} onClick={() => { if (selected) setDraft({...selected}); }}>Edit request</Button>}
|
|
278
302
|
>
|
|
279
303
|
{draft
|
|
@@ -297,13 +321,23 @@ export function RecordManagement() {
|
|
|
297
321
|
</Field>
|
|
298
322
|
</Stack>
|
|
299
323
|
</form>
|
|
300
|
-
: selected && <DescriptionList items={[
|
|
324
|
+
: selected && <Stack gap="8"><DescriptionList items={[
|
|
301
325
|
{id: "request-id", term: "Request ID", description: selected.id},
|
|
302
326
|
{id: "owner", term: "Owner", description: selected.owner || "Unassigned"},
|
|
303
327
|
{id: "status", term: "Status", description: <StatusIndicator {...statuses[selected.status]} />},
|
|
304
|
-
]} />
|
|
328
|
+
]} />
|
|
329
|
+
{activity && <Section title="Activity" headingLevel={3} headingSize="group">
|
|
330
|
+
<Table caption="Request activity" hideCaption density="compact">
|
|
331
|
+
<thead><tr><th scope="col">Date</th><th scope="col">Event</th></tr></thead>
|
|
332
|
+
<tbody>{activity.map(item => <tr key={item.date}>
|
|
333
|
+
<td><time dateTime={item.date}>{activityDate.format(new Date(item.date))}</time></td>
|
|
334
|
+
<td>{item.activity}</td>
|
|
335
|
+
</tr>)}</tbody>
|
|
336
|
+
</Table>
|
|
337
|
+
</Section>}
|
|
338
|
+
</Stack>}
|
|
305
339
|
</Drawer>
|
|
306
|
-
{notice
|
|
340
|
+
<ToastRegion items={notice ? [notice] : []} onDismiss={() => setNotice(null)} />
|
|
307
341
|
</Stack>
|
|
308
342
|
</section>;
|
|
309
343
|
}
|