@dowel-ui/react 0.5.0 → 0.7.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 +1 -1
- package/dist/blocks/admin-dashboard/meta.js +31 -0
- package/dist/blocks/admin-dashboard/meta.js.map +1 -0
- package/dist/blocks/agent-console/meta.js +27 -0
- package/dist/blocks/agent-console/meta.js.map +1 -0
- package/dist/blocks/ai-dashboard/meta.js +25 -0
- package/dist/blocks/ai-dashboard/meta.js.map +1 -0
- package/dist/blocks/ai-workspace/meta.js +33 -0
- package/dist/blocks/ai-workspace/meta.js.map +1 -0
- package/dist/blocks/analytics/meta.js +24 -0
- package/dist/blocks/analytics/meta.js.map +1 -0
- package/dist/blocks/billing/meta.js +25 -0
- package/dist/blocks/billing/meta.js.map +1 -0
- package/dist/blocks/command-center/meta.js +28 -0
- package/dist/blocks/command-center/meta.js.map +1 -0
- package/dist/blocks/crm/meta.js +32 -0
- package/dist/blocks/crm/meta.js.map +1 -0
- package/dist/blocks/onboarding/meta.js +23 -0
- package/dist/blocks/onboarding/meta.js.map +1 -0
- package/dist/components/accordion/accordion.js +1 -1
- package/dist/components/accordion/accordion.js.map +1 -1
- package/dist/components/activity-feed/activity-feed.js +1 -1
- package/dist/components/activity-feed/activity-feed.js.map +1 -1
- package/dist/components/ai-agent-plan/ai-agent-plan.js +1 -1
- package/dist/components/ai-agent-plan/ai-agent-plan.js.map +1 -1
- package/dist/components/ai-extraction-review/ai-extraction-review.js +1 -1
- package/dist/components/ai-extraction-review/ai-extraction-review.js.map +1 -1
- package/dist/components/ai-prompt-input/ai-prompt-input.js +1 -1
- package/dist/components/ai-prompt-input/ai-prompt-input.js.map +1 -1
- package/dist/components/ai-reasoning/ai-reasoning.js +1 -1
- package/dist/components/ai-reasoning/ai-reasoning.js.map +1 -1
- package/dist/components/ai-response/ai-response.js +2 -2
- package/dist/components/ai-response/ai-response.js.map +1 -1
- package/dist/components/ai-tool/ai-tool.js +2 -2
- package/dist/components/ai-tool/ai-tool.js.map +1 -1
- package/dist/components/alert/alert.d.ts +1 -1
- package/dist/components/avatar/avatar.d.ts +1 -1
- package/dist/components/badge/badge.d.ts +1 -1
- package/dist/components/breadcrumb/breadcrumb.d.ts +52 -0
- package/dist/components/breadcrumb/breadcrumb.d.ts.map +1 -0
- package/dist/components/breadcrumb/breadcrumb.js +141 -0
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -0
- package/dist/components/breadcrumb/index.d.ts +2 -0
- package/dist/components/breadcrumb/index.js +2 -0
- package/dist/components/breadcrumb/meta.js +17 -0
- package/dist/components/breadcrumb/meta.js.map +1 -0
- package/dist/components/button/button.d.ts +1 -1
- package/dist/components/calendar/calendar.js +2 -2
- package/dist/components/calendar/calendar.js.map +1 -1
- package/dist/components/code-block/code-block.js +1 -1
- package/dist/components/code-block/code-block.js.map +1 -1
- package/dist/components/collapsible/collapsible.d.ts +30 -0
- package/dist/components/collapsible/collapsible.d.ts.map +1 -0
- package/dist/components/collapsible/collapsible.js +38 -0
- package/dist/components/collapsible/collapsible.js.map +1 -0
- package/dist/components/collapsible/index.d.ts +2 -0
- package/dist/components/collapsible/index.js +2 -0
- package/dist/components/collapsible/meta.js +17 -0
- package/dist/components/collapsible/meta.js.map +1 -0
- package/dist/components/combobox/combobox.js +2 -2
- package/dist/components/combobox/combobox.js.map +1 -1
- package/dist/components/command/command.js +1 -1
- package/dist/components/command/command.js.map +1 -1
- package/dist/components/data-table/data-table.d.ts.map +1 -1
- package/dist/components/data-table/data-table.js +4 -1
- package/dist/components/data-table/data-table.js.map +1 -1
- package/dist/components/dialog/dialog.js +2 -2
- package/dist/components/dialog/dialog.js.map +1 -1
- package/dist/components/diff-viewer/diff-viewer.js +4 -4
- package/dist/components/diff-viewer/diff-viewer.js.map +1 -1
- package/dist/components/direction/direction.d.ts +35 -0
- package/dist/components/direction/direction.d.ts.map +1 -0
- package/dist/components/direction/direction.js +14 -0
- package/dist/components/direction/direction.js.map +1 -0
- package/dist/components/direction/index.d.ts +2 -0
- package/dist/components/direction/index.js +2 -0
- package/dist/components/direction/meta.js +17 -0
- package/dist/components/direction/meta.js.map +1 -0
- package/dist/components/drawer/drawer.js +1 -1
- package/dist/components/drawer/drawer.js.map +1 -1
- package/dist/components/dropdown-menu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/dropdown-menu/dropdown-menu.js +9 -8
- package/dist/components/dropdown-menu/dropdown-menu.js.map +1 -1
- package/dist/components/input/input.js +1 -1
- package/dist/components/input/input.js.map +1 -1
- package/dist/components/log-viewer/log-viewer.js +2 -2
- package/dist/components/log-viewer/log-viewer.js.map +1 -1
- package/dist/components/meter/meter.js +1 -1
- package/dist/components/meter/meter.js.map +1 -1
- package/dist/components/pagination/pagination.d.ts.map +1 -1
- package/dist/components/pagination/pagination.js +3 -2
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/permission-matrix/permission-matrix.js +3 -3
- package/dist/components/permission-matrix/permission-matrix.js.map +1 -1
- package/dist/components/progress/progress.d.ts +1 -1
- package/dist/components/record-diff/record-diff.js +4 -4
- package/dist/components/record-diff/record-diff.js.map +1 -1
- package/dist/components/select/select.js +2 -2
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/sheet/sheet.d.ts.map +1 -1
- package/dist/components/sheet/sheet.js +2 -2
- package/dist/components/sheet/sheet.js.map +1 -1
- package/dist/components/sidebar/index.d.ts +2 -0
- package/dist/components/sidebar/index.js +2 -0
- package/dist/components/sidebar/meta.js +17 -0
- package/dist/components/sidebar/meta.js.map +1 -0
- package/dist/components/sidebar/sidebar.d.ts +69 -0
- package/dist/components/sidebar/sidebar.d.ts.map +1 -0
- package/dist/components/sidebar/sidebar.js +256 -0
- package/dist/components/sidebar/sidebar.js.map +1 -0
- package/dist/components/spinner/spinner.d.ts +1 -1
- package/dist/components/table/table.js +2 -2
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/tags-input/tags-input.js +1 -1
- package/dist/components/tags-input/tags-input.js.map +1 -1
- package/dist/components/textarea/index.d.ts +2 -0
- package/dist/components/textarea/index.js +2 -0
- package/dist/components/textarea/meta.js +17 -0
- package/dist/components/textarea/meta.js.map +1 -0
- package/dist/components/textarea/textarea.d.ts +43 -0
- package/dist/components/textarea/textarea.d.ts.map +1 -0
- package/dist/components/textarea/textarea.js +119 -0
- package/dist/components/textarea/textarea.js.map +1 -0
- package/dist/components/time-range-picker/time-range-picker.js +3 -3
- package/dist/components/time-range-picker/time-range-picker.js.map +1 -1
- package/dist/components/toast/toast.d.ts +1 -1
- package/dist/components/toast/toast.d.ts.map +1 -1
- package/dist/components/toast/toast.js +2 -2
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.js +7 -2
- package/dist/lib/styles.d.ts +16 -1
- package/dist/lib/styles.d.ts.map +1 -1
- package/dist/lib/styles.js +16 -1
- package/dist/lib/styles.js.map +1 -1
- package/dist/registry/blocks.d.ts.map +1 -1
- package/dist/registry/blocks.js +27 -9
- package/dist/registry/blocks.js.map +1 -1
- package/dist/registry/components.d.ts.map +1 -1
- package/dist/registry/components.js +60 -50
- package/dist/registry/components.js.map +1 -1
- package/dist/registry/schema.d.ts +8 -0
- package/dist/registry/schema.d.ts.map +1 -1
- package/dist/registry/schema.js.map +1 -1
- package/package.json +5 -4
- package/src/components/accordion/accordion.tsx +1 -1
- package/src/components/activity-feed/activity-feed.tsx +1 -1
- package/src/components/ai-agent-plan/ai-agent-plan.tsx +0 -0
- package/src/components/ai-extraction-review/ai-extraction-review.tsx +1 -1
- package/src/components/ai-prompt-input/ai-prompt-input.tsx +1 -1
- package/src/components/ai-reasoning/ai-reasoning.tsx +1 -1
- package/src/components/ai-response/ai-response.tsx +2 -2
- package/src/components/ai-tool/ai-tool.tsx +2 -2
- package/src/components/breadcrumb/breadcrumb.tsx +157 -0
- package/src/components/breadcrumb/index.ts +10 -0
- package/src/components/breadcrumb/meta.ts +19 -0
- package/src/components/calendar/calendar.tsx +2 -2
- package/src/components/code-block/code-block.tsx +1 -1
- package/src/components/collapsible/collapsible.tsx +63 -0
- package/src/components/collapsible/index.ts +6 -0
- package/src/components/collapsible/meta.ts +16 -0
- package/src/components/combobox/combobox.tsx +2 -2
- package/src/components/command/command.tsx +1 -1
- package/src/components/data-table/data-table.tsx +14 -3
- package/src/components/dialog/dialog.tsx +2 -2
- package/src/components/diff-viewer/diff-viewer.tsx +4 -4
- package/src/components/direction/direction.tsx +38 -0
- package/src/components/direction/index.ts +1 -0
- package/src/components/direction/meta.ts +19 -0
- package/src/components/drawer/drawer.tsx +1 -1
- package/src/components/dropdown-menu/dropdown-menu.tsx +14 -8
- package/src/components/input/input.tsx +1 -1
- package/src/components/log-viewer/log-viewer.tsx +2 -2
- package/src/components/meter/meter.tsx +1 -1
- package/src/components/pagination/pagination.tsx +13 -2
- package/src/components/permission-matrix/permission-matrix.tsx +4 -4
- package/src/components/record-diff/record-diff.tsx +4 -4
- package/src/components/select/select.tsx +2 -2
- package/src/components/sheet/sheet.tsx +8 -4
- package/src/components/sidebar/index.ts +19 -0
- package/src/components/sidebar/meta.ts +25 -0
- package/src/components/sidebar/sidebar.tsx +374 -0
- package/src/components/table/table.tsx +3 -3
- package/src/components/tags-input/tags-input.tsx +1 -1
- package/src/components/textarea/index.ts +1 -0
- package/src/components/textarea/meta.ts +21 -0
- package/src/components/textarea/textarea.tsx +210 -0
- package/src/components/time-range-picker/time-range-picker.tsx +3 -3
- package/src/components/toast/toast.tsx +14 -6
- package/src/index.ts +5 -0
- package/src/lib/styles.ts +16 -0
- package/src/registry/blocks.ts +18 -0
- package/src/registry/components.ts +10 -0
- package/src/registry/schema.ts +8 -0
- package/src/blocks/admin-users/admin-users.tsx +0 -251
- package/src/blocks/admin-users/index.ts +0 -1
- package/src/blocks/admin-users/meta.ts +0 -27
- package/src/blocks/ai-chat/ai-chat.tsx +0 -280
- package/src/blocks/ai-chat/index.ts +0 -7
- package/src/blocks/ai-chat/meta.ts +0 -32
- package/src/blocks/dashboard/dashboard.tsx +0 -192
- package/src/blocks/dashboard/index.ts +0 -6
- package/src/blocks/dashboard/meta.ts +0 -18
- package/src/blocks/forgot-password/forgot-password.tsx +0 -158
- package/src/blocks/forgot-password/index.ts +0 -1
- package/src/blocks/forgot-password/meta.ts +0 -18
- package/src/blocks/login/index.ts +0 -1
- package/src/blocks/login/login.tsx +0 -178
- package/src/blocks/login/meta.ts +0 -18
- package/src/blocks/pricing/index.ts +0 -1
- package/src/blocks/pricing/meta.ts +0 -18
- package/src/blocks/pricing/pricing.tsx +0 -176
- package/src/blocks/settings/index.ts +0 -6
- package/src/blocks/settings/meta.ts +0 -29
- package/src/blocks/settings/settings.tsx +0 -317
- package/src/blocks/signup/index.ts +0 -1
- package/src/blocks/signup/meta.ts +0 -18
- package/src/blocks/signup/signup.tsx +0 -240
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ they want to change something.
|
|
|
54
54
|
|
|
55
55
|
## What is in it
|
|
56
56
|
|
|
57
|
-
**
|
|
57
|
+
**75 components** and **17 blocks**, every one keyboard-operable and audited for
|
|
58
58
|
contrast.
|
|
59
59
|
|
|
60
60
|
**AI** — the reason this library exists
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/blocks/admin-dashboard/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "admin-dashboard",
|
|
5
|
+
kind: "block",
|
|
6
|
+
title: "Admin dashboard",
|
|
7
|
+
description: "An administration console: the shell every admin page shares — navigation, breadcrumb, account menu — and the overview that is its front page, with what needs attention first.",
|
|
8
|
+
category: "layout",
|
|
9
|
+
status: "stable",
|
|
10
|
+
access: "pro",
|
|
11
|
+
dependencies: [],
|
|
12
|
+
registryDependencies: [
|
|
13
|
+
"alert",
|
|
14
|
+
"avatar",
|
|
15
|
+
"badge",
|
|
16
|
+
"breadcrumb",
|
|
17
|
+
"button",
|
|
18
|
+
"card",
|
|
19
|
+
"dropdown-menu",
|
|
20
|
+
"empty-state",
|
|
21
|
+
"metric-delta",
|
|
22
|
+
"sidebar",
|
|
23
|
+
"table"
|
|
24
|
+
],
|
|
25
|
+
files: ["admin-dashboard.tsx"],
|
|
26
|
+
a11y: "What needs attention comes first and is the only loud part of the page; it is not a live region, because the list is there on load and re-announcing it on every refresh would make the console unusable. The navigation is a landmark called Admin, the breadcrumb another, so neither is one more thing called 'navigation'. The current page carries aria-current, a count beside a nav item says what it counts, the account menu is named after its owner, and each Open button is named after its account. Every status is a word, with colour agreeing rather than replacing."
|
|
27
|
+
});
|
|
28
|
+
//#endregion
|
|
29
|
+
export { meta };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/blocks/admin-dashboard/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"admin-dashboard\",\n kind: \"block\",\n title: \"Admin dashboard\",\n description:\n \"An administration console: the shell every admin page shares — navigation, breadcrumb, account menu — and the overview that is its front page, with what needs attention first.\",\n category: \"layout\",\n status: \"stable\",\n access: \"pro\",\n dependencies: [],\n registryDependencies: [\n \"alert\",\n \"avatar\",\n \"badge\",\n \"breadcrumb\",\n \"button\",\n \"card\",\n \"dropdown-menu\",\n \"empty-state\",\n \"metric-delta\",\n \"sidebar\",\n \"table\",\n ],\n files: [\"admin-dashboard.tsx\"],\n a11y:\n \"What needs attention comes first and is the only loud part of the page; it is not a live \" +\n \"region, because the list is there on load and re-announcing it on every refresh would \" +\n \"make the console unusable. The navigation is a landmark called Admin, the breadcrumb \" +\n \"another, so neither is one more thing called 'navigation'. The current page carries \" +\n \"aria-current, a count beside a nav item says what it counts, the account menu is named \" +\n \"after its owner, and each Open button is named after its account. Every status is a word, \" +\n \"with colour agreeing rather than replacing.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,MAAM;CACN,OAAO;CACP,aACE;CACF,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,cAAc,CAAC;CACf,sBAAsB;EACpB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,OAAO,CAAC,qBAAqB;CAC7B,MACE;AAOJ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/blocks/agent-console/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "agent-console",
|
|
5
|
+
kind: "block",
|
|
6
|
+
title: "Agent console",
|
|
7
|
+
description: "One agent run, watched: the plan it is working from, the approval it is blocked on, and the ledger of what it has already done.",
|
|
8
|
+
category: "ai",
|
|
9
|
+
status: "stable",
|
|
10
|
+
dependencies: [],
|
|
11
|
+
registryDependencies: [
|
|
12
|
+
"ai-action-ledger",
|
|
13
|
+
"ai-agent-plan",
|
|
14
|
+
"ai-agent-status",
|
|
15
|
+
"ai-approval-request",
|
|
16
|
+
"ai-token-usage",
|
|
17
|
+
"button",
|
|
18
|
+
"card",
|
|
19
|
+
"empty-state"
|
|
20
|
+
],
|
|
21
|
+
files: ["agent-console.tsx"],
|
|
22
|
+
a11y: "Whatever the run is blocked on is rendered first rather than below a scrolling plan, because it is the only part of the page waiting on a person. This is the one agent on the page, so its status announces its own transitions — a list of runs each doing that would be noise, which is why the underlying component makes it opt in. Every completed action states whether it can be undone, offset or not taken back at all, in words, since presenting all three behind one Undo is a lie discovered after the click."
|
|
23
|
+
});
|
|
24
|
+
//#endregion
|
|
25
|
+
export { meta };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/blocks/agent-console/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"agent-console\",\n kind: \"block\",\n title: \"Agent console\",\n description:\n \"One agent run, watched: the plan it is working from, the approval it is blocked on, and the ledger of what it has already done.\",\n category: \"ai\",\n status: \"stable\",\n dependencies: [],\n registryDependencies: [\n \"ai-action-ledger\",\n \"ai-agent-plan\",\n \"ai-agent-status\",\n \"ai-approval-request\",\n \"ai-token-usage\",\n \"button\",\n \"card\",\n \"empty-state\",\n ],\n files: [\"agent-console.tsx\"],\n a11y:\n \"Whatever the run is blocked on is rendered first rather than below a scrolling plan, \" +\n \"because it is the only part of the page waiting on a person. This is the one agent on the \" +\n \"page, so its status announces its own transitions — a list of runs each doing that would \" +\n \"be noise, which is why the underlying component makes it opt in. Every completed action \" +\n \"states whether it can be undone, offset or not taken back at all, in words, since \" +\n \"presenting all three behind one Undo is a lie discovered after the click.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,MAAM;CACN,OAAO;CACP,aACE;CACF,UAAU;CACV,QAAQ;CACR,cAAc,CAAC;CACf,sBAAsB;EACpB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,OAAO,CAAC,mBAAmB;CAC3B,MACE;AAMJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/blocks/ai-dashboard/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "ai-dashboard",
|
|
5
|
+
kind: "block",
|
|
6
|
+
title: "AI dashboard",
|
|
7
|
+
description: "What the AI features cost and whether they worked: tokens, spend, failure rate, a breakdown by model, and the runs still going.",
|
|
8
|
+
category: "ai",
|
|
9
|
+
status: "stable",
|
|
10
|
+
dependencies: [],
|
|
11
|
+
registryDependencies: [
|
|
12
|
+
"ai-agent-status",
|
|
13
|
+
"ai-token-usage",
|
|
14
|
+
"card",
|
|
15
|
+
"empty-state",
|
|
16
|
+
"metric-delta",
|
|
17
|
+
"table"
|
|
18
|
+
],
|
|
19
|
+
files: ["ai-dashboard.tsx"],
|
|
20
|
+
a11y: "Spend and failure rate are declared lower-is-better, so a rising bill is not painted green — which is the mistake most usage dashboards make. The totals row is a real table footer rather than a last body row that looks like one, because inside the body it is announced as another model and there is no model called Total. Statuses in the run list do not announce their own changes: several runs each doing that turns a list into a stream of interruptions, and watching one run is the agent console's job."
|
|
21
|
+
});
|
|
22
|
+
//#endregion
|
|
23
|
+
export { meta };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/blocks/ai-dashboard/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"ai-dashboard\",\n kind: \"block\",\n title: \"AI dashboard\",\n description:\n \"What the AI features cost and whether they worked: tokens, spend, failure rate, a breakdown by model, and the runs still going.\",\n category: \"ai\",\n status: \"stable\",\n dependencies: [],\n registryDependencies: [\n \"ai-agent-status\",\n \"ai-token-usage\",\n \"card\",\n \"empty-state\",\n \"metric-delta\",\n \"table\",\n ],\n files: [\"ai-dashboard.tsx\"],\n a11y:\n \"Spend and failure rate are declared lower-is-better, so a rising bill is not painted green \" +\n \"— which is the mistake most usage dashboards make. The totals row is a real table footer \" +\n \"rather than a last body row that looks like one, because inside the body it is announced \" +\n \"as another model and there is no model called Total. Statuses in the run list do not \" +\n \"announce their own changes: several runs each doing that turns a list into a stream of \" +\n \"interruptions, and watching one run is the agent console's job.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,MAAM;CACN,OAAO;CACP,aACE;CACF,UAAU;CACV,QAAQ;CACR,cAAc,CAAC;CACf,sBAAsB;EACpB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,OAAO,CAAC,kBAAkB;CAC1B,MACE;AAMJ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/blocks/ai-workspace/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "ai-workspace",
|
|
5
|
+
kind: "block",
|
|
6
|
+
title: "AI workspace",
|
|
7
|
+
description: "A whole AI application surface: conversations down one side, the active transcript with reasoning, tool calls and sources in the middle, and the context — window usage, attachments and a structured result — on the other.",
|
|
8
|
+
category: "ai",
|
|
9
|
+
status: "stable",
|
|
10
|
+
access: "pro",
|
|
11
|
+
dependencies: [],
|
|
12
|
+
registryDependencies: [
|
|
13
|
+
"ai-conversation",
|
|
14
|
+
"ai-message",
|
|
15
|
+
"ai-model-selector",
|
|
16
|
+
"ai-prompt-input",
|
|
17
|
+
"ai-reasoning",
|
|
18
|
+
"ai-response",
|
|
19
|
+
"ai-sources",
|
|
20
|
+
"ai-structured-output",
|
|
21
|
+
"ai-token-usage",
|
|
22
|
+
"ai-tool",
|
|
23
|
+
"button",
|
|
24
|
+
"empty-state",
|
|
25
|
+
"sidebar"
|
|
26
|
+
],
|
|
27
|
+
files: ["ai-workspace.tsx"],
|
|
28
|
+
a11y: "Three landmarks, each named: the conversation list is a navigation called Conversations, the transcript is the main content, and the context is a complementary region called Context, so a screen reader user can jump between them and skip the one they do not want. The transcript is a list and never a live region; the response state is announced from a separate status line, so a streaming answer does not read itself aloud token by token. Each attachment's remove button is named after its file. On a narrow screen the conversation list becomes a sheet with a focus trap and an Escape key, not a div slid over content that stays reachable by Tab."
|
|
29
|
+
});
|
|
30
|
+
//#endregion
|
|
31
|
+
export { meta };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/blocks/ai-workspace/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"ai-workspace\",\n kind: \"block\",\n title: \"AI workspace\",\n description:\n \"A whole AI application surface: conversations down one side, the active transcript with reasoning, tool calls and sources in the middle, and the context — window usage, attachments and a structured result — on the other.\",\n category: \"ai\",\n status: \"stable\",\n access: \"pro\",\n dependencies: [],\n registryDependencies: [\n \"ai-conversation\",\n \"ai-message\",\n \"ai-model-selector\",\n \"ai-prompt-input\",\n \"ai-reasoning\",\n \"ai-response\",\n \"ai-sources\",\n \"ai-structured-output\",\n \"ai-token-usage\",\n \"ai-tool\",\n \"button\",\n \"empty-state\",\n \"sidebar\",\n ],\n files: [\"ai-workspace.tsx\"],\n a11y:\n \"Three landmarks, each named: the conversation list is a navigation called Conversations, \" +\n \"the transcript is the main content, and the context is a complementary region called \" +\n \"Context, so a screen reader user can jump between them and skip the one they do not want. \" +\n \"The transcript is a list and never a live region; the response state is announced from a \" +\n \"separate status line, so a streaming answer does not read itself aloud token by token. \" +\n \"Each attachment's remove button is named after its file. On a narrow screen the \" +\n \"conversation list becomes a sheet with a focus trap and an Escape key, not a div slid \" +\n \"over content that stays reachable by Tab.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,MAAM;CACN,OAAO;CACP,aACE;CACF,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,cAAc,CAAC;CACf,sBAAsB;EACpB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,OAAO,CAAC,kBAAkB;CAC1B,MACE;AAQJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/blocks/analytics/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "analytics",
|
|
5
|
+
kind: "block",
|
|
6
|
+
title: "Analytics",
|
|
7
|
+
description: "An analytics page: headline metrics against the previous period, a series over time, and the breakdown that made it up.",
|
|
8
|
+
category: "data",
|
|
9
|
+
status: "stable",
|
|
10
|
+
dependencies: [],
|
|
11
|
+
registryDependencies: [
|
|
12
|
+
"button",
|
|
13
|
+
"card",
|
|
14
|
+
"metric-delta",
|
|
15
|
+
"select",
|
|
16
|
+
"table"
|
|
17
|
+
],
|
|
18
|
+
files: ["analytics.tsx"],
|
|
19
|
+
a11y: "The bars are declared as a single image with a one-sentence summary — where the series started, where it ended, and where its extremes were — rather than as forty separately labelled elements, which reads as noise instead of a shape. The exact numbers live in a real table that is collapsed for everyone and revealed for everyone from a control on the page, rather than in a visually-hidden copy only screen readers can reach, because the hidden copy is the one that goes stale. The range selector is a select rather than a tab set: tabs promise panels, and a range selector has none — it changes the data behind the whole page, so styled-as-tabs it points every tab at a panel that does not exist."
|
|
20
|
+
});
|
|
21
|
+
//#endregion
|
|
22
|
+
export { meta };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/blocks/analytics/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"analytics\",\n kind: \"block\",\n title: \"Analytics\",\n description:\n \"An analytics page: headline metrics against the previous period, a series over time, and the breakdown that made it up.\",\n category: \"data\",\n status: \"stable\",\n dependencies: [],\n registryDependencies: [\"button\", \"card\", \"metric-delta\", \"select\", \"table\"],\n files: [\"analytics.tsx\"],\n a11y:\n \"The bars are declared as a single image with a one-sentence summary — where the series \" +\n \"started, where it ended, and where its extremes were — rather than as forty separately \" +\n \"labelled elements, which reads as noise instead of a shape. The exact numbers live in a \" +\n \"real table that is collapsed for everyone and revealed for everyone from a control on the \" +\n \"page, rather than in a visually-hidden copy only screen readers can reach, because the \" +\n \"hidden copy is the one that goes stale. The range selector is a select rather than a tab \" +\n \"set: tabs promise panels, and a range selector has none — it changes the data behind the \" +\n \"whole page, so styled-as-tabs it points every tab at a panel that does not exist.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,MAAM;CACN,OAAO;CACP,aACE;CACF,UAAU;CACV,QAAQ;CACR,cAAc,CAAC;CACf,sBAAsB;EAAC;EAAU;EAAQ;EAAgB;EAAU;CAAO;CAC1E,OAAO,CAAC,eAAe;CACvB,MACE;AAQJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/blocks/billing/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "billing",
|
|
5
|
+
kind: "block",
|
|
6
|
+
title: "Billing",
|
|
7
|
+
description: "A billing page: the current plan, metered usage against its limits, the payment method and the invoice history.",
|
|
8
|
+
category: "data",
|
|
9
|
+
status: "stable",
|
|
10
|
+
dependencies: [],
|
|
11
|
+
registryDependencies: [
|
|
12
|
+
"badge",
|
|
13
|
+
"button",
|
|
14
|
+
"card",
|
|
15
|
+
"empty-state",
|
|
16
|
+
"progress",
|
|
17
|
+
"table"
|
|
18
|
+
],
|
|
19
|
+
files: ["billing.tsx"],
|
|
20
|
+
a11y: "Every usage meter states where it stands in words — \"8 of 10 seats used, 2 left\", or how far over the limit it is — because a bar that turns red says nothing to a screen reader and nothing to anyone who cannot tell the colours apart; the bar itself is hidden from the accessibility tree so the same fact is not announced twice. Each invoice download is named after its invoice rather than being one of ten identical \"Download\" links, which is all a links list would show. A card's last four digits are spoken as digits instead of as a four-figure number. Dates carry a machine-readable time element."
|
|
21
|
+
});
|
|
22
|
+
//#endregion
|
|
23
|
+
export { meta };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/blocks/billing/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"billing\",\n kind: \"block\",\n title: \"Billing\",\n description:\n \"A billing page: the current plan, metered usage against its limits, the payment method and the invoice history.\",\n category: \"data\",\n status: \"stable\",\n dependencies: [],\n registryDependencies: [\"badge\", \"button\", \"card\", \"empty-state\", \"progress\", \"table\"],\n files: [\"billing.tsx\"],\n a11y:\n 'Every usage meter states where it stands in words — \"8 of 10 seats used, 2 left\", or how ' +\n \"far over the limit it is — because a bar that turns red says nothing to a screen reader and \" +\n \"nothing to anyone who cannot tell the colours apart; the bar itself is hidden from the \" +\n \"accessibility tree so the same fact is not announced twice. Each invoice download is named \" +\n 'after its invoice rather than being one of ten identical \"Download\" links, which is all a ' +\n \"links list would show. A card's last four digits are spoken as digits instead of as a \" +\n \"four-figure number. Dates carry a machine-readable time element.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,MAAM;CACN,OAAO;CACP,aACE;CACF,UAAU;CACV,QAAQ;CACR,cAAc,CAAC;CACf,sBAAsB;EAAC;EAAS;EAAU;EAAQ;EAAe;EAAY;CAAO;CACpF,OAAO,CAAC,aAAa;CACrB,MACE;AAOJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/blocks/command-center/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "command-center",
|
|
5
|
+
kind: "block",
|
|
6
|
+
title: "Command center",
|
|
7
|
+
description: "Operations at a glance: service health worst-first, open incidents by severity, capacity meters, a filterable log stream, and a command palette for every action an operator reaches for.",
|
|
8
|
+
category: "data",
|
|
9
|
+
status: "stable",
|
|
10
|
+
access: "pro",
|
|
11
|
+
dependencies: [],
|
|
12
|
+
registryDependencies: [
|
|
13
|
+
"alert",
|
|
14
|
+
"badge",
|
|
15
|
+
"button",
|
|
16
|
+
"card",
|
|
17
|
+
"command",
|
|
18
|
+
"empty-state",
|
|
19
|
+
"log-viewer",
|
|
20
|
+
"meter"
|
|
21
|
+
],
|
|
22
|
+
files: ["command-center.tsx"],
|
|
23
|
+
a11y: "The overall status is one sentence computed from the worst service, and it comes first — 'one service is down' rather than a wall of tiles to scan. It is not a live region: the page is refreshed by the application, and a status that re-announces on every poll is one nobody can work beside. Health and severity are words on every row, sorted on, with colour agreeing rather than replacing. ⌘K opens the palette but the Actions button is always visible, so the shortcut is an accelerator and not the only way in. New log lines are not read aloud unless asked."
|
|
24
|
+
});
|
|
25
|
+
//#endregion
|
|
26
|
+
export { meta };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/blocks/command-center/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"command-center\",\n kind: \"block\",\n title: \"Command center\",\n description:\n \"Operations at a glance: service health worst-first, open incidents by severity, capacity meters, a filterable log stream, and a command palette for every action an operator reaches for.\",\n category: \"data\",\n status: \"stable\",\n access: \"pro\",\n dependencies: [],\n registryDependencies: [\n \"alert\",\n \"badge\",\n \"button\",\n \"card\",\n \"command\",\n \"empty-state\",\n \"log-viewer\",\n \"meter\",\n ],\n files: [\"command-center.tsx\"],\n a11y:\n \"The overall status is one sentence computed from the worst service, and it comes first — \" +\n \"'one service is down' rather than a wall of tiles to scan. It is not a live region: the \" +\n \"page is refreshed by the application, and a status that re-announces on every poll is one \" +\n \"nobody can work beside. Health and severity are words on every row, sorted on, with colour \" +\n \"agreeing rather than replacing. ⌘K opens the palette but the Actions button is always \" +\n \"visible, so the shortcut is an accelerator and not the only way in. New log lines are not \" +\n \"read aloud unless asked.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,MAAM;CACN,OAAO;CACP,aACE;CACF,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,cAAc,CAAC;CACf,sBAAsB;EACpB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,OAAO,CAAC,oBAAoB;CAC5B,MACE;AAOJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/blocks/crm/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "crm",
|
|
5
|
+
kind: "block",
|
|
6
|
+
title: "CRM",
|
|
7
|
+
description: "A sales pipeline: open value by stage, the deals in it with filtering and sorting, the win rate and cycle length, and the last few touches.",
|
|
8
|
+
category: "data",
|
|
9
|
+
status: "stable",
|
|
10
|
+
access: "pro",
|
|
11
|
+
dependencies: ["@tanstack/react-table"],
|
|
12
|
+
registryDependencies: [
|
|
13
|
+
"activity-feed",
|
|
14
|
+
"avatar",
|
|
15
|
+
"badge",
|
|
16
|
+
"button",
|
|
17
|
+
"card",
|
|
18
|
+
"data-table",
|
|
19
|
+
"empty-state",
|
|
20
|
+
"input",
|
|
21
|
+
"label",
|
|
22
|
+
"meter",
|
|
23
|
+
"metric-delta",
|
|
24
|
+
"select"
|
|
25
|
+
],
|
|
26
|
+
files: ["crm.tsx"],
|
|
27
|
+
a11y: "The pipeline is one bar split by stage, with the same figures listed beside it as numbers, so nobody reads a proportion off a coloured segment; the meter announces the total and its legend names every stage. Sales cycle is declared lower-is-better, so a slowing pipeline is not painted green. The deal filter has a real label and announces the matching count politely, and each Open button is named after its deal rather than being one of ten identical buttons."
|
|
28
|
+
});
|
|
29
|
+
//#endregion
|
|
30
|
+
export { meta };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/blocks/crm/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"crm\",\n kind: \"block\",\n title: \"CRM\",\n description:\n \"A sales pipeline: open value by stage, the deals in it with filtering and sorting, the win rate and cycle length, and the last few touches.\",\n category: \"data\",\n status: \"stable\",\n access: \"pro\",\n dependencies: [\"@tanstack/react-table\"],\n registryDependencies: [\n \"activity-feed\",\n \"avatar\",\n \"badge\",\n \"button\",\n \"card\",\n \"data-table\",\n \"empty-state\",\n \"input\",\n \"label\",\n \"meter\",\n \"metric-delta\",\n \"select\",\n ],\n files: [\"crm.tsx\"],\n a11y:\n \"The pipeline is one bar split by stage, with the same figures listed beside it as numbers, \" +\n \"so nobody reads a proportion off a coloured segment; the meter announces the total and its \" +\n \"legend names every stage. Sales cycle is declared lower-is-better, so a slowing pipeline is not painted \" +\n \"green. The deal filter has a real label and announces the matching count politely, and \" +\n \"each Open button is named after its deal rather than being one of ten identical buttons.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,MAAM;CACN,OAAO;CACP,aACE;CACF,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,cAAc,CAAC,uBAAuB;CACtC,sBAAsB;EACpB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,OAAO,CAAC,SAAS;CACjB,MACE;AAKJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/blocks/onboarding/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "onboarding",
|
|
5
|
+
kind: "block",
|
|
6
|
+
title: "Onboarding",
|
|
7
|
+
description: "A setup checklist: what is done, which step is current, and what is blocked and why.",
|
|
8
|
+
category: "feedback",
|
|
9
|
+
status: "stable",
|
|
10
|
+
dependencies: [],
|
|
11
|
+
registryDependencies: [
|
|
12
|
+
"badge",
|
|
13
|
+
"button",
|
|
14
|
+
"card",
|
|
15
|
+
"progress"
|
|
16
|
+
],
|
|
17
|
+
files: ["onboarding.tsx"],
|
|
18
|
+
a11y: "Every step states its state in a word — Done, In progress, Not started, Blocked — because a green tick announces nothing and means nothing to a reader who cannot tell the colours apart; the tick and the step number are decoration on top of that. Progress is given as a count rather than only as a bar, and the bar is hidden so the same fact is not announced twice. The current step carries aria-current, so it can be found rather than merely seen. Blocked is a distinct state from not-started and says why. Each step's action is named after its step, so six buttons are not six identical \"Start\" entries in a controls list."
|
|
19
|
+
});
|
|
20
|
+
//#endregion
|
|
21
|
+
export { meta };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/blocks/onboarding/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"onboarding\",\n kind: \"block\",\n title: \"Onboarding\",\n description:\n \"A setup checklist: what is done, which step is current, and what is blocked and why.\",\n category: \"feedback\",\n status: \"stable\",\n dependencies: [],\n registryDependencies: [\"badge\", \"button\", \"card\", \"progress\"],\n files: [\"onboarding.tsx\"],\n a11y:\n \"Every step states its state in a word — Done, In progress, Not started, Blocked — because \" +\n \"a green tick announces nothing and means nothing to a reader who cannot tell the colours \" +\n \"apart; the tick and the step number are decoration on top of that. Progress is given as a \" +\n \"count rather than only as a bar, and the bar is hidden so the same fact is not announced \" +\n \"twice. The current step carries aria-current, so it can be found rather than merely seen. \" +\n \"Blocked is a distinct state from not-started and says why. Each step's action is named \" +\n 'after its step, so six buttons are not six identical \"Start\" entries in a controls list.',\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,MAAM;CACN,OAAO;CACP,aACE;CACF,UAAU;CACV,QAAQ;CACR,cAAc,CAAC;CACf,sBAAsB;EAAC;EAAS;EAAU;EAAQ;CAAU;CAC5D,OAAO,CAAC,gBAAgB;CACxB,MACE;AAOJ,CAAC"}
|
|
@@ -23,7 +23,7 @@ function AccordionTrigger({ className, children, ...props }) {
|
|
|
23
23
|
className: "flex",
|
|
24
24
|
children: /* @__PURE__ */ jsxs(Accordion.Trigger, {
|
|
25
25
|
"data-slot": "accordion-trigger",
|
|
26
|
-
className: cn("flex flex-1 items-start justify-between gap-4 py-4 text-
|
|
26
|
+
className: cn("flex flex-1 items-start justify-between gap-4 py-4 text-start text-sm font-medium", "transition-colors duration-[var(--duration-fast)] hover:text-primary", "disabled:pointer-events-none disabled:opacity-55", "[&[data-state=open]>svg]:rotate-180", focusRing, className),
|
|
27
27
|
...props,
|
|
28
28
|
children: [children, /* @__PURE__ */ jsx("svg", {
|
|
29
29
|
viewBox: "0 0 24 24",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accordion.js","names":["Accordion","AccordionPrimitive"],"sources":["../../../src/components/accordion/accordion.tsx"],"sourcesContent":["\"use client\";\n\nimport { Accordion as AccordionPrimitive } from \"radix-ui\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nimport { focusRing } from \"@/lib/styles\";\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Vertically stacked sections that expand to reveal their content.\n *\n * Use `type=\"single\"` for a set where one answer at a time is the point (an\n * FAQ), and `type=\"multiple\"` where sections are independent (settings groups).\n */\nexport const Accordion = AccordionPrimitive.Root;\n\nexport type AccordionItemProps = ComponentPropsWithRef<typeof AccordionPrimitive.Item>;\n\nexport function AccordionItem({ className, ...props }: AccordionItemProps) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn(\"border-b border-border last:border-b-0\", className)}\n {...props}\n />\n );\n}\n\nexport type AccordionTriggerProps = ComponentPropsWithRef<typeof AccordionPrimitive.Trigger>;\n\nexport function AccordionTrigger({ className, children, ...props }: AccordionTriggerProps) {\n return (\n // The primitive requires the trigger to sit inside a Header so the button\n // carries a heading role — without it the sections are unreachable by\n // heading navigation, which is how many screen reader users move around.\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n \"flex flex-1 items-start justify-between gap-4 py-4 text-
|
|
1
|
+
{"version":3,"file":"accordion.js","names":["Accordion","AccordionPrimitive"],"sources":["../../../src/components/accordion/accordion.tsx"],"sourcesContent":["\"use client\";\n\nimport { Accordion as AccordionPrimitive } from \"radix-ui\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nimport { focusRing } from \"@/lib/styles\";\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Vertically stacked sections that expand to reveal their content.\n *\n * Use `type=\"single\"` for a set where one answer at a time is the point (an\n * FAQ), and `type=\"multiple\"` where sections are independent (settings groups).\n */\nexport const Accordion = AccordionPrimitive.Root;\n\nexport type AccordionItemProps = ComponentPropsWithRef<typeof AccordionPrimitive.Item>;\n\nexport function AccordionItem({ className, ...props }: AccordionItemProps) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn(\"border-b border-border last:border-b-0\", className)}\n {...props}\n />\n );\n}\n\nexport type AccordionTriggerProps = ComponentPropsWithRef<typeof AccordionPrimitive.Trigger>;\n\nexport function AccordionTrigger({ className, children, ...props }: AccordionTriggerProps) {\n return (\n // The primitive requires the trigger to sit inside a Header so the button\n // carries a heading role — without it the sections are unreachable by\n // heading navigation, which is how many screen reader users move around.\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n \"flex flex-1 items-start justify-between gap-4 py-4 text-start text-sm font-medium\",\n \"transition-colors duration-[var(--duration-fast)] hover:text-primary\",\n \"disabled:pointer-events-none disabled:opacity-55\",\n \"[&[data-state=open]>svg]:rotate-180\",\n focusRing,\n className,\n )}\n {...props}\n >\n {children}\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className=\"size-4 shrink-0 translate-y-0.5 text-muted-foreground transition-transform duration-[var(--duration-normal)] ease-[var(--ease-out-quint)]\"\n >\n <path\n d=\"m6 9 6 6 6-6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\nexport type AccordionContentProps = ComponentPropsWithRef<typeof AccordionPrimitive.Content>;\n\nexport function AccordionContent({ className, children, ...props }: AccordionContentProps) {\n return (\n <AccordionPrimitive.Content\n data-slot=\"accordion-content\"\n className={cn(\n // The height keyframes read --radix-accordion-content-height, which the\n // primitive measures; overflow-hidden keeps the content clipped as the\n // box grows rather than spilling over the section below.\n \"overflow-hidden text-sm text-muted-foreground\",\n \"data-[state=closed]:animate-accordion-close data-[state=open]:animate-accordion-open\",\n className,\n )}\n {...props}\n >\n <div className={cn(\"pb-4\")}>{children}</div>\n </AccordionPrimitive.Content>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAcA,MAAaA,cAAYC,UAAmB;AAI5C,SAAgB,cAAc,EAAE,WAAW,GAAG,SAA6B;CACzE,OACE,oBAACA,UAAmB,MAApB;EACE,aAAU;EACV,WAAW,GAAG,0CAA0C,SAAS;EACjE,GAAI;CACL,CAAA;AAEL;AAIA,SAAgB,iBAAiB,EAAE,WAAW,UAAU,GAAG,SAAgC;CACzF,OAIE,oBAACA,UAAmB,QAApB;EAA2B,WAAU;EACnC,UAAA,qBAACA,UAAmB,SAApB;GACE,aAAU;GACV,WAAW,GACT,qFACA,wEACA,oDACA,uCACA,WACA,SACF;GACA,GAAI;GAVN,UAAA,CAYG,UACD,oBAAC,OAAD;IACE,SAAQ;IACR,MAAK;IACL,eAAY;IACZ,WAAU;IAEV,UAAA,oBAAC,QAAD;KACE,GAAE;KACF,QAAO;KACP,aAAY;KACZ,eAAc;KACd,gBAAe;IAChB,CAAA;GACE,CAAA,CACqB;;CACH,CAAA;AAE/B;AAIA,SAAgB,iBAAiB,EAAE,WAAW,UAAU,GAAG,SAAgC;CACzF,OACE,oBAACA,UAAmB,SAApB;EACE,aAAU;EACV,WAAW,GAIT,iDACA,wFACA,SACF;EACA,GAAI;EAEJ,UAAA,oBAAC,OAAD;GAAK,WAAW,GAAG,MAAM;GAAI;EAAc,CAAA;CACjB,CAAA;AAEhC"}
|
|
@@ -21,7 +21,7 @@ function ActivityItem({ className, last, ...props }) {
|
|
|
21
21
|
return /* @__PURE__ */ jsx("li", {
|
|
22
22
|
"data-slot": "activity-item",
|
|
23
23
|
"data-last": last || void 0,
|
|
24
|
-
className: cn("relative flex gap-3 pb-6 last:pb-0", "before:absolute before:top-7 before:bottom-1 before:
|
|
24
|
+
className: cn("relative flex gap-3 pb-6 last:pb-0", "before:absolute before:start-[0.6875rem] before:top-7 before:bottom-1 before:w-px before:bg-border", "last:before:hidden data-[last]:before:hidden", className),
|
|
25
25
|
...props
|
|
26
26
|
});
|
|
27
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity-feed.js","names":[],"sources":["../../../src/components/activity-feed/activity-feed.tsx"],"sourcesContent":["import { Slot } from \"radix-ui\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * A chronological list of events.\n *\n * An ordered list underneath, because the order is the meaning: a screen reader\n * announces the position and count, and \"3 of 12\" is information a row of divs\n * cannot convey. The connecting line is drawn with a pseudo-element rather than\n * a real node so it never appears in the accessibility tree.\n */\nexport function ActivityFeed({ className, ...props }: ComponentPropsWithRef<\"ol\">) {\n return <ol data-slot=\"activity-feed\" className={cn(\"flex flex-col\", className)} {...props} />;\n}\n\nexport interface ActivityItemProps extends ComponentPropsWithRef<\"li\"> {\n /** Draws no connecting line below. Set this on the last item. */\n last?: boolean;\n}\n\nexport function ActivityItem({ className, last, ...props }: ActivityItemProps) {\n return (\n <li\n data-slot=\"activity-item\"\n data-last={last || undefined}\n className={cn(\n \"relative flex gap-3 pb-6 last:pb-0\",\n // The rail is a pseudo-element on the item, so it is decorative by\n // construction rather than by remembering an aria-hidden.\n \"before:absolute before:top-7 before:bottom-1 before:
|
|
1
|
+
{"version":3,"file":"activity-feed.js","names":[],"sources":["../../../src/components/activity-feed/activity-feed.tsx"],"sourcesContent":["import { Slot } from \"radix-ui\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * A chronological list of events.\n *\n * An ordered list underneath, because the order is the meaning: a screen reader\n * announces the position and count, and \"3 of 12\" is information a row of divs\n * cannot convey. The connecting line is drawn with a pseudo-element rather than\n * a real node so it never appears in the accessibility tree.\n */\nexport function ActivityFeed({ className, ...props }: ComponentPropsWithRef<\"ol\">) {\n return <ol data-slot=\"activity-feed\" className={cn(\"flex flex-col\", className)} {...props} />;\n}\n\nexport interface ActivityItemProps extends ComponentPropsWithRef<\"li\"> {\n /** Draws no connecting line below. Set this on the last item. */\n last?: boolean;\n}\n\nexport function ActivityItem({ className, last, ...props }: ActivityItemProps) {\n return (\n <li\n data-slot=\"activity-item\"\n data-last={last || undefined}\n className={cn(\n \"relative flex gap-3 pb-6 last:pb-0\",\n // The rail is a pseudo-element on the item, so it is decorative by\n // construction rather than by remembering an aria-hidden.\n \"before:absolute before:start-[0.6875rem] before:top-7 before:bottom-1 before:w-px before:bg-border\",\n \"last:before:hidden data-[last]:before:hidden\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport interface ActivityIndicatorProps extends ComponentPropsWithRef<\"div\"> {\n asChild?: boolean;\n}\n\n/** The marker on the rail. Decorative: the item's text says what happened. */\nexport function ActivityIndicator({ className, asChild, ...props }: ActivityIndicatorProps) {\n const Comp = asChild ? Slot.Root : \"div\";\n\n return (\n <Comp\n data-slot=\"activity-indicator\"\n aria-hidden=\"true\"\n className={cn(\n \"relative z-[var(--z-base)] grid size-6 shrink-0 place-items-center rounded-full\",\n \"border border-border bg-background text-muted-foreground\",\n \"[&_svg:not([class*='size-'])]:size-3\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function ActivityContent({ className, ...props }: ComponentPropsWithRef<\"div\">) {\n return (\n <div\n data-slot=\"activity-content\"\n className={cn(\"flex min-w-0 flex-1 flex-col gap-1 pt-0.5\", className)}\n {...props}\n />\n );\n}\n\nexport function ActivityTitle({ className, ...props }: ComponentPropsWithRef<\"p\">) {\n return (\n <p\n data-slot=\"activity-title\"\n className={cn(\"text-sm leading-snug text-foreground\", className)}\n {...props}\n />\n );\n}\n\nexport interface ActivityTimeProps extends ComponentPropsWithRef<\"time\"> {\n /** Machine-readable timestamp. Required — a relative label alone is ambiguous. */\n dateTime: string;\n}\n\n/**\n * When the event happened.\n *\n * `dateTime` is required rather than optional: \"2 hours ago\" is meaningless in\n * a page read a day later, or by anything parsing the feed, and a `<time>` with\n * no datetime is just a span.\n */\nexport function ActivityTime({ className, dateTime, ...props }: ActivityTimeProps) {\n return (\n <time\n data-slot=\"activity-time\"\n dateTime={dateTime}\n className={cn(\"text-xs text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nexport function ActivityDescription({ className, ...props }: ComponentPropsWithRef<\"div\">) {\n return (\n <div\n data-slot=\"activity-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;AAaA,SAAgB,aAAa,EAAE,WAAW,GAAG,SAAsC;CACjF,OAAO,oBAAC,MAAD;EAAI,aAAU;EAAgB,WAAW,GAAG,iBAAiB,SAAS;EAAG,GAAI;CAAQ,CAAA;AAC9F;AAOA,SAAgB,aAAa,EAAE,WAAW,MAAM,GAAG,SAA4B;CAC7E,OACE,oBAAC,MAAD;EACE,aAAU;EACV,aAAW,QAAQ,KAAA;EACnB,WAAW,GACT,sCAGA,sGACA,gDACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;;AAOA,SAAgB,kBAAkB,EAAE,WAAW,SAAS,GAAG,SAAiC;CAC1F,MAAM,OAAO,UAAU,KAAK,OAAO;CAEnC,OACE,oBAAC,MAAD;EACE,aAAU;EACV,eAAY;EACZ,WAAW,GACT,mFACA,4DACA,wCACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAgB,gBAAgB,EAAE,WAAW,GAAG,SAAuC;CACrF,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,6CAA6C,SAAS;EACpE,GAAI;CACL,CAAA;AAEL;AAEA,SAAgB,cAAc,EAAE,WAAW,GAAG,SAAqC;CACjF,OACE,oBAAC,KAAD;EACE,aAAU;EACV,WAAW,GAAG,wCAAwC,SAAS;EAC/D,GAAI;CACL,CAAA;AAEL;;;;;;;;AAcA,SAAgB,aAAa,EAAE,WAAW,UAAU,GAAG,SAA4B;CACjF,OACE,oBAAC,QAAD;EACE,aAAU;EACA;EACV,WAAW,GAAG,iCAAiC,SAAS;EACxD,GAAI;CACL,CAAA;AAEL;AAEA,SAAgB,oBAAoB,EAAE,WAAW,GAAG,SAAuC;CACzF,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,iCAAiC,SAAS;EACxD,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -95,7 +95,7 @@ function AgentPlanStep({ className, step, nested = false, ...props }) {
|
|
|
95
95
|
"data-slot": "agent-plan-step",
|
|
96
96
|
"data-status": status,
|
|
97
97
|
"aria-current": status === "running" ? "step" : void 0,
|
|
98
|
-
className: cn("flex flex-col gap-1", nested && "
|
|
98
|
+
className: cn("flex flex-col gap-1", nested && "ms-5", className),
|
|
99
99
|
...props,
|
|
100
100
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
101
101
|
className: "flex items-start gap-2",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-agent-plan.js","names":[],"sources":["../../../src/components/ai-agent-plan/ai-agent-plan.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useContext,\n useMemo,\n useState,\n type ComponentPropsWithRef,\n type ReactNode,\n} from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * What an agent intends to do, and how far through it is.\n *\n * Not a stepper. A wizard's steps are decided up front and never change; an\n * agent's plan is a hypothesis it revises as it learns — it adds a step when a\n * lookup fails, drops one that turned out to be unnecessary, and reorders when\n * a dependency appears. Every stepper treats its step list as fixed, so a plan\n * rendered in one either silently mutates under the reader or re-renders from\n * scratch and loses their place.\n *\n * So revision is the feature here, not an edge case. When the plan changes, the\n * change is announced — \"the model added a step\" is information, and watching a\n * list quietly grow is not the same as being told.\n *\n * Approval is not here. Deciding whether a plan may run is a different\n * component with a different shape; this one displays and reports.\n */\n\nexport type StepStatus = \"pending\" | \"running\" | \"done\" | \"failed\" | \"skipped\";\n\nexport interface PlanStep {\n id: string;\n title: string;\n status: StepStatus;\n /** What the step will do, or what it found. Shown under the title. */\n detail?: string;\n /** Why it failed. Shown only when the status is \"failed\". */\n error?: string;\n /** One level of sub-steps. Deeper nesting is a tree, which this is not. */\n steps?: PlanStep[];\n}\n\nconst STATUS_LABEL: Record<StepStatus, string> = {\n pending: \"Not started\",\n running: \"In progress\",\n done: \"Done\",\n failed: \"Failed\",\n skipped: \"Skipped\",\n};\n\n/** Flattens one level, so counting and \"step N of M\" include sub-steps. */\nfunction flatten(steps: PlanStep[]): PlanStep[] {\n return steps.flatMap((step) => [step, ...(step.steps ?? [])]);\n}\n\nfunction describeRevision(added: PlanStep[], removed: number): string {\n const parts: string[] = [];\n if (added.length === 1 && added[0]) parts.push(`Plan updated: added \"${added[0].title}\"`);\n else if (added.length > 1) parts.push(`Plan updated: ${String(added.length)} steps added`);\n if (removed === 1) parts.push(\"1 step removed\");\n else if (removed > 1) parts.push(`${String(removed)} steps removed`);\n return parts.join(\", \");\n}\n\ninterface PlanContextValue {\n steps: PlanStep[];\n flat: PlanStep[];\n currentIndex: number;\n}\n\nconst PlanContext = createContext<PlanContextValue | null>(null);\n\nfunction usePlanContext(component: string): PlanContextValue {\n const context = useContext(PlanContext);\n if (!context) {\n throw new Error(`${component} must be rendered inside <AgentPlan>.`);\n }\n return context;\n}\n\nexport interface AgentPlanProps extends Omit<ComponentPropsWithRef<\"div\">, \"children\"> {\n steps: PlanStep[];\n /** Names the plan, so the list is not an unlabelled sequence. */\n label: string;\n children?: ReactNode;\n}\n\nexport function AgentPlan({ className, steps, label, children, ...props }: AgentPlanProps) {\n const flat = useMemo(() => flatten(steps), [steps]);\n const ids = flat.map((step) => step.id);\n\n // Revision detection, adjusted during render rather than in an effect: an\n // effect would announce a frame after the change is already on screen, and a\n // ref read during render is unsafe under concurrent rendering.\n const [seen, setSeen] = useState<string[]>(ids);\n const [revision, setRevision] = useState(\"\");\n\n if (ids.join(\"\u0000\") !== seen.join(\"\u0000\")) {\n const added = flat.filter((step) => !seen.includes(step.id));\n const removed = seen.filter((id) => !ids.includes(id)).length;\n setSeen(ids);\n // A plan whose steps only changed status has not been revised. Only\n // structural change is worth interrupting for.\n setRevision(added.length > 0 || removed > 0 ? describeRevision(added, removed) : \"\");\n }\n\n const currentIndex = flat.findIndex((step) => step.status === \"running\");\n\n const context = useMemo<PlanContextValue>(\n () => ({ steps, flat, currentIndex }),\n [steps, flat, currentIndex],\n );\n\n return (\n <PlanContext.Provider value={context}>\n <div\n data-slot=\"agent-plan\"\n aria-label={label}\n role=\"group\"\n className={cn(\"flex flex-col gap-2\", className)}\n {...props}\n >\n {children ?? (\n <>\n <AgentPlanSummary />\n <AgentPlanSteps />\n </>\n )}\n\n {/* Structural changes only. Announcing every status transition would\n talk over the reader continuously on a plan of any length. */}\n <span aria-live=\"polite\" data-slot=\"agent-plan-revision\" className=\"sr-only\">\n {revision}\n </span>\n </div>\n </PlanContext.Provider>\n );\n}\n\n/** \"Step 3 of 6\" plus the overall state, in words. */\nexport function AgentPlanSummary({ className, ...props }: ComponentPropsWithRef<\"p\">) {\n const { flat, currentIndex } = usePlanContext(\"AgentPlanSummary\");\n\n const done = flat.filter((step) => step.status === \"done\").length;\n const failed = flat.filter((step) => step.status === \"failed\").length;\n const running = currentIndex >= 0;\n const started = flat.some((step) => step.status !== \"pending\");\n\n const message = !started\n ? `Proposed plan, ${String(flat.length)} steps`\n : running\n ? `Step ${String(currentIndex + 1)} of ${String(flat.length)}`\n : failed > 0\n ? `${String(done)} of ${String(flat.length)} done, ${String(failed)} failed`\n : `${String(done)} of ${String(flat.length)} done`;\n\n return (\n <p\n data-slot=\"agent-plan-summary\"\n className={cn(\"text-xs text-muted-foreground tabular-nums\", className)}\n {...props}\n >\n {message}\n </p>\n );\n}\n\nexport function AgentPlanSteps({ className, ...props }: ComponentPropsWithRef<\"ol\">) {\n const { steps } = usePlanContext(\"AgentPlanSteps\");\n\n return (\n // An ordered list: a plan is a sequence, and the order carries meaning that\n // an unordered list would throw away.\n <ol\n data-slot=\"agent-plan-steps\"\n className={cn(\"flex list-none flex-col gap-1\", className)}\n {...props}\n >\n {steps.map((step) => (\n <AgentPlanStep key={step.id} step={step} />\n ))}\n </ol>\n );\n}\n\nexport interface AgentPlanStepProps extends Omit<ComponentPropsWithRef<\"li\">, \"children\"> {\n step: PlanStep;\n /** Set on sub-steps. Not part of the public API surface. */\n nested?: boolean;\n}\n\nexport function AgentPlanStep({\n className,\n step,\n nested = false,\n ...props\n}: AgentPlanStepProps) {\n const { status, title, detail, error, steps: children } = step;\n\n return (\n <li\n data-slot=\"agent-plan-step\"\n data-status={status}\n // Marks where the reader is in the sequence without moving focus, which\n // would fight anyone reading ahead.\n aria-current={status === \"running\" ? \"step\" : undefined}\n className={cn(\"flex flex-col gap-1\", nested && \"ml-5\", className)}\n {...props}\n >\n <div className=\"flex items-start gap-2\">\n <StepMarker status={status} />\n\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span\n className={cn(\n \"text-sm\",\n status === \"pending\" && \"text-muted-foreground\",\n status === \"skipped\" && \"text-muted-foreground line-through\",\n status === \"failed\" && \"text-destructive\",\n status === \"running\" && \"font-medium\",\n )}\n >\n {title}\n {/* Status in text, always. The marker is a shape and a colour, and\n neither is information on its own. */}\n <span className=\"sr-only\">, {STATUS_LABEL[status]}</span>\n </span>\n\n {detail ? <span className=\"text-xs text-muted-foreground\">{detail}</span> : null}\n {status === \"failed\" && error ? (\n <span data-slot=\"agent-plan-error\" className=\"text-xs text-destructive\">\n {error}\n </span>\n ) : null}\n </div>\n </div>\n\n {children && children.length > 0 ? (\n <ol className=\"flex list-none flex-col gap-1\">\n {children.map((child) => (\n <AgentPlanStep key={child.id} step={child} nested />\n ))}\n </ol>\n ) : null}\n </li>\n );\n}\n\n/**\n * The status shape.\n *\n * aria-hidden throughout: every marker repeats what the step already states in\n * text, and announcing both means hearing the status twice per step.\n */\nfunction StepMarker({ status }: { status: StepStatus }) {\n const base = \"mt-0.5 grid size-4 shrink-0 place-items-center rounded-full border text-[9px]\";\n\n if (status === \"running\") {\n return (\n // Deliberately not data-motion=\"indicator\". The bar for that exemption is\n // that stopping the animation would say something false, and it would\n // not: the step already states \"In progress\" in text and carries\n // aria-current. This pulse is reinforcement, so under reduced motion it\n // stops like any other decoration.\n <span\n aria-hidden=\"true\"\n data-slot=\"agent-plan-marker\"\n className={cn(base, \"animate-pulse-soft border-primary bg-primary/15 text-primary\")}\n >\n <span className=\"size-1.5 rounded-full bg-primary\" />\n </span>\n );\n }\n\n return (\n <span\n aria-hidden=\"true\"\n data-slot=\"agent-plan-marker\"\n className={cn(\n base,\n status === \"done\" && \"border-success bg-success text-success-foreground\",\n status === \"failed\" && \"border-destructive bg-destructive text-destructive-foreground\",\n status === \"skipped\" && \"border-border-strong text-muted-foreground\",\n status === \"pending\" && \"border-border-strong\",\n )}\n >\n {status === \"done\" ? \"✓\" : status === \"failed\" ? \"✕\" : status === \"skipped\" ? \"–\" : null}\n </span>\n );\n}\n"],"mappings":";;;;;AA6CA,MAAM,eAA2C;CAC/C,SAAS;CACT,SAAS;CACT,MAAM;CACN,QAAQ;CACR,SAAS;AACX;;AAGA,SAAS,QAAQ,OAA+B;CAC9C,OAAO,MAAM,SAAS,SAAS,CAAC,MAAM,GAAI,KAAK,SAAS,CAAC,CAAE,CAAC;AAC9D;AAEA,SAAS,iBAAiB,OAAmB,SAAyB;CACpE,MAAM,QAAkB,CAAC;CACzB,IAAI,MAAM,WAAW,KAAK,MAAM,IAAI,MAAM,KAAK,wBAAwB,MAAM,EAAE,CAAC,MAAM,EAAE;MACnF,IAAI,MAAM,SAAS,GAAG,MAAM,KAAK,iBAAiB,OAAO,MAAM,MAAM,EAAE,aAAa;CACzF,IAAI,YAAY,GAAG,MAAM,KAAK,gBAAgB;MACzC,IAAI,UAAU,GAAG,MAAM,KAAK,GAAG,OAAO,OAAO,EAAE,eAAe;CACnE,OAAO,MAAM,KAAK,IAAI;AACxB;AAQA,MAAM,cAAc,cAAuC,IAAI;AAE/D,SAAS,eAAe,WAAqC;CAC3D,MAAM,UAAU,WAAW,WAAW;CACtC,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,GAAG,UAAU,sCAAsC;CAErE,OAAO;AACT;AASA,SAAgB,UAAU,EAAE,WAAW,OAAO,OAAO,UAAU,GAAG,SAAyB;CACzF,MAAM,OAAO,cAAc,QAAQ,KAAK,GAAG,CAAC,KAAK,CAAC;CAClD,MAAM,MAAM,KAAK,KAAK,SAAS,KAAK,EAAE;CAKtC,MAAM,CAAC,MAAM,WAAW,SAAmB,GAAG;CAC9C,MAAM,CAAC,UAAU,eAAe,SAAS,EAAE;CAE3C,IAAI,IAAI,KAAK,IAAG,MAAM,KAAK,KAAK,IAAG,GAAG;EACpC,MAAM,QAAQ,KAAK,QAAQ,SAAS,CAAC,KAAK,SAAS,KAAK,EAAE,CAAC;EAC3D,MAAM,UAAU,KAAK,QAAQ,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC;EACvD,QAAQ,GAAG;EAGX,YAAY,MAAM,SAAS,KAAK,UAAU,IAAI,iBAAiB,OAAO,OAAO,IAAI,EAAE;CACrF;CAEA,MAAM,eAAe,KAAK,WAAW,SAAS,KAAK,WAAW,SAAS;CAEvE,MAAM,UAAU,eACP;EAAE;EAAO;EAAM;CAAa,IACnC;EAAC;EAAO;EAAM;CAAY,CAC5B;CAEA,OACE,oBAAC,YAAY,UAAb;EAAsB,OAAO;EAC3B,UAAA,qBAAC,OAAD;GACE,aAAU;GACV,cAAY;GACZ,MAAK;GACL,WAAW,GAAG,uBAAuB,SAAS;GAC9C,GAAI;GALN,UAAA,CAOG,YACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,kBAAD,CAAmB,CAAA,GACnB,oBAAC,gBAAD,CAAiB,CAAA,CACjB,EAAA,CAAA,GAKJ,oBAAC,QAAD;IAAM,aAAU;IAAS,aAAU;IAAsB,WAAU;IAChE,UAAA;GACG,CAAA,CACH;;CACe,CAAA;AAE1B;;AAGA,SAAgB,iBAAiB,EAAE,WAAW,GAAG,SAAqC;CACpF,MAAM,EAAE,MAAM,iBAAiB,eAAe,kBAAkB;CAEhE,MAAM,OAAO,KAAK,QAAQ,SAAS,KAAK,WAAW,MAAM,CAAC,CAAC;CAC3D,MAAM,SAAS,KAAK,QAAQ,SAAS,KAAK,WAAW,QAAQ,CAAC,CAAC;CAC/D,MAAM,UAAU,gBAAgB;CAGhC,MAAM,UAAU,CAFA,KAAK,MAAM,SAAS,KAAK,WAAW,SAE7B,IACnB,kBAAkB,OAAO,KAAK,MAAM,EAAE,UACtC,UACE,QAAQ,OAAO,eAAe,CAAC,EAAE,MAAM,OAAO,KAAK,MAAM,MACzD,SAAS,IACP,GAAG,OAAO,IAAI,EAAE,MAAM,OAAO,KAAK,MAAM,EAAE,SAAS,OAAO,MAAM,EAAE,WAClE,GAAG,OAAO,IAAI,EAAE,MAAM,OAAO,KAAK,MAAM,EAAE;CAElD,OACE,oBAAC,KAAD;EACE,aAAU;EACV,WAAW,GAAG,8CAA8C,SAAS;EACrE,GAAI;EAEH,UAAA;CACA,CAAA;AAEP;AAEA,SAAgB,eAAe,EAAE,WAAW,GAAG,SAAsC;CACnF,MAAM,EAAE,UAAU,eAAe,gBAAgB;CAEjD,OAGE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GAAG,iCAAiC,SAAS;EACxD,GAAI;EAEH,UAAA,MAAM,KAAK,SACV,oBAAC,eAAD,EAAmC,KAAO,GAAtB,KAAK,EAAiB,CAC3C;CACC,CAAA;AAER;AAQA,SAAgB,cAAc,EAC5B,WACA,MACA,SAAS,OACT,GAAG,SACkB;CACrB,MAAM,EAAE,QAAQ,OAAO,QAAQ,OAAO,OAAO,aAAa;CAE1D,OACE,qBAAC,MAAD;EACE,aAAU;EACV,eAAa;EAGb,gBAAc,WAAW,YAAY,SAAS,KAAA;EAC9C,WAAW,GAAG,uBAAuB,UAAU,QAAQ,SAAS;EAChE,GAAI;EAPN,UAAA,CASE,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,YAAD,EAAoB,OAAS,CAAA,GAE7B,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,qBAAC,QAAD;MACE,WAAW,GACT,WACA,WAAW,aAAa,yBACxB,WAAW,aAAa,sCACxB,WAAW,YAAY,oBACvB,WAAW,aAAa,aAC1B;MAPF,UAAA,CASG,OAGD,qBAAC,QAAD;OAAM,WAAU;OAAhB,UAAA,CAA0B,MAAG,aAAa,OAAc;MACpD,CAAA,CAAA;;KAEL,SAAS,oBAAC,QAAD;MAAM,WAAU;MAAiC,UAAA;KAAa,CAAA,IAAI;KAC3E,WAAW,YAAY,QACtB,oBAAC,QAAD;MAAM,aAAU;MAAmB,WAAU;MAC1C,UAAA;KACG,CAAA,IACJ;IACD;GACF,CAAA,CAAA;EAEJ,CAAA,GAAA,YAAY,SAAS,SAAS,IAC7B,oBAAC,MAAD;GAAI,WAAU;GACX,UAAA,SAAS,KAAK,UACb,oBAAC,eAAD;IAA8B,MAAM;IAAO,QAAA;GAAQ,GAA/B,MAAM,EAAyB,CACpD;EACC,CAAA,IACF,IACF;;AAER;;;;;;;AAQA,SAAS,WAAW,EAAE,UAAkC;CACtD,MAAM,OAAO;CAEb,IAAI,WAAW,WACb,OAME,oBAAC,QAAD;EACE,eAAY;EACZ,aAAU;EACV,WAAW,GAAG,MAAM,8DAA8D;EAElF,UAAA,oBAAC,QAAD,EAAM,WAAU,mCAAoC,CAAA;CAChD,CAAA;CAIV,OACE,oBAAC,QAAD;EACE,eAAY;EACZ,aAAU;EACV,WAAW,GACT,MACA,WAAW,UAAU,qDACrB,WAAW,YAAY,iEACvB,WAAW,aAAa,8CACxB,WAAW,aAAa,sBAC1B;EAEC,UAAA,WAAW,SAAS,MAAM,WAAW,WAAW,MAAM,WAAW,YAAY,MAAM;CAChF,CAAA;AAEV"}
|
|
1
|
+
{"version":3,"file":"ai-agent-plan.js","names":[],"sources":["../../../src/components/ai-agent-plan/ai-agent-plan.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useContext,\n useMemo,\n useState,\n type ComponentPropsWithRef,\n type ReactNode,\n} from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * What an agent intends to do, and how far through it is.\n *\n * Not a stepper. A wizard's steps are decided up front and never change; an\n * agent's plan is a hypothesis it revises as it learns — it adds a step when a\n * lookup fails, drops one that turned out to be unnecessary, and reorders when\n * a dependency appears. Every stepper treats its step list as fixed, so a plan\n * rendered in one either silently mutates under the reader or re-renders from\n * scratch and loses their place.\n *\n * So revision is the feature here, not an edge case. When the plan changes, the\n * change is announced — \"the model added a step\" is information, and watching a\n * list quietly grow is not the same as being told.\n *\n * Approval is not here. Deciding whether a plan may run is a different\n * component with a different shape; this one displays and reports.\n */\n\nexport type StepStatus = \"pending\" | \"running\" | \"done\" | \"failed\" | \"skipped\";\n\nexport interface PlanStep {\n id: string;\n title: string;\n status: StepStatus;\n /** What the step will do, or what it found. Shown under the title. */\n detail?: string;\n /** Why it failed. Shown only when the status is \"failed\". */\n error?: string;\n /** One level of sub-steps. Deeper nesting is a tree, which this is not. */\n steps?: PlanStep[];\n}\n\nconst STATUS_LABEL: Record<StepStatus, string> = {\n pending: \"Not started\",\n running: \"In progress\",\n done: \"Done\",\n failed: \"Failed\",\n skipped: \"Skipped\",\n};\n\n/** Flattens one level, so counting and \"step N of M\" include sub-steps. */\nfunction flatten(steps: PlanStep[]): PlanStep[] {\n return steps.flatMap((step) => [step, ...(step.steps ?? [])]);\n}\n\nfunction describeRevision(added: PlanStep[], removed: number): string {\n const parts: string[] = [];\n if (added.length === 1 && added[0]) parts.push(`Plan updated: added \"${added[0].title}\"`);\n else if (added.length > 1) parts.push(`Plan updated: ${String(added.length)} steps added`);\n if (removed === 1) parts.push(\"1 step removed\");\n else if (removed > 1) parts.push(`${String(removed)} steps removed`);\n return parts.join(\", \");\n}\n\ninterface PlanContextValue {\n steps: PlanStep[];\n flat: PlanStep[];\n currentIndex: number;\n}\n\nconst PlanContext = createContext<PlanContextValue | null>(null);\n\nfunction usePlanContext(component: string): PlanContextValue {\n const context = useContext(PlanContext);\n if (!context) {\n throw new Error(`${component} must be rendered inside <AgentPlan>.`);\n }\n return context;\n}\n\nexport interface AgentPlanProps extends Omit<ComponentPropsWithRef<\"div\">, \"children\"> {\n steps: PlanStep[];\n /** Names the plan, so the list is not an unlabelled sequence. */\n label: string;\n children?: ReactNode;\n}\n\nexport function AgentPlan({ className, steps, label, children, ...props }: AgentPlanProps) {\n const flat = useMemo(() => flatten(steps), [steps]);\n const ids = flat.map((step) => step.id);\n\n // Revision detection, adjusted during render rather than in an effect: an\n // effect would announce a frame after the change is already on screen, and a\n // ref read during render is unsafe under concurrent rendering.\n const [seen, setSeen] = useState<string[]>(ids);\n const [revision, setRevision] = useState(\"\");\n\n if (ids.join(\"\u0000\") !== seen.join(\"\u0000\")) {\n const added = flat.filter((step) => !seen.includes(step.id));\n const removed = seen.filter((id) => !ids.includes(id)).length;\n setSeen(ids);\n // A plan whose steps only changed status has not been revised. Only\n // structural change is worth interrupting for.\n setRevision(added.length > 0 || removed > 0 ? describeRevision(added, removed) : \"\");\n }\n\n const currentIndex = flat.findIndex((step) => step.status === \"running\");\n\n const context = useMemo<PlanContextValue>(\n () => ({ steps, flat, currentIndex }),\n [steps, flat, currentIndex],\n );\n\n return (\n <PlanContext.Provider value={context}>\n <div\n data-slot=\"agent-plan\"\n aria-label={label}\n role=\"group\"\n className={cn(\"flex flex-col gap-2\", className)}\n {...props}\n >\n {children ?? (\n <>\n <AgentPlanSummary />\n <AgentPlanSteps />\n </>\n )}\n\n {/* Structural changes only. Announcing every status transition would\n talk over the reader continuously on a plan of any length. */}\n <span aria-live=\"polite\" data-slot=\"agent-plan-revision\" className=\"sr-only\">\n {revision}\n </span>\n </div>\n </PlanContext.Provider>\n );\n}\n\n/** \"Step 3 of 6\" plus the overall state, in words. */\nexport function AgentPlanSummary({ className, ...props }: ComponentPropsWithRef<\"p\">) {\n const { flat, currentIndex } = usePlanContext(\"AgentPlanSummary\");\n\n const done = flat.filter((step) => step.status === \"done\").length;\n const failed = flat.filter((step) => step.status === \"failed\").length;\n const running = currentIndex >= 0;\n const started = flat.some((step) => step.status !== \"pending\");\n\n const message = !started\n ? `Proposed plan, ${String(flat.length)} steps`\n : running\n ? `Step ${String(currentIndex + 1)} of ${String(flat.length)}`\n : failed > 0\n ? `${String(done)} of ${String(flat.length)} done, ${String(failed)} failed`\n : `${String(done)} of ${String(flat.length)} done`;\n\n return (\n <p\n data-slot=\"agent-plan-summary\"\n className={cn(\"text-xs text-muted-foreground tabular-nums\", className)}\n {...props}\n >\n {message}\n </p>\n );\n}\n\nexport function AgentPlanSteps({ className, ...props }: ComponentPropsWithRef<\"ol\">) {\n const { steps } = usePlanContext(\"AgentPlanSteps\");\n\n return (\n // An ordered list: a plan is a sequence, and the order carries meaning that\n // an unordered list would throw away.\n <ol\n data-slot=\"agent-plan-steps\"\n className={cn(\"flex list-none flex-col gap-1\", className)}\n {...props}\n >\n {steps.map((step) => (\n <AgentPlanStep key={step.id} step={step} />\n ))}\n </ol>\n );\n}\n\nexport interface AgentPlanStepProps extends Omit<ComponentPropsWithRef<\"li\">, \"children\"> {\n step: PlanStep;\n /** Set on sub-steps. Not part of the public API surface. */\n nested?: boolean;\n}\n\nexport function AgentPlanStep({\n className,\n step,\n nested = false,\n ...props\n}: AgentPlanStepProps) {\n const { status, title, detail, error, steps: children } = step;\n\n return (\n <li\n data-slot=\"agent-plan-step\"\n data-status={status}\n // Marks where the reader is in the sequence without moving focus, which\n // would fight anyone reading ahead.\n aria-current={status === \"running\" ? \"step\" : undefined}\n className={cn(\"flex flex-col gap-1\", nested && \"ms-5\", className)}\n {...props}\n >\n <div className=\"flex items-start gap-2\">\n <StepMarker status={status} />\n\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span\n className={cn(\n \"text-sm\",\n status === \"pending\" && \"text-muted-foreground\",\n status === \"skipped\" && \"text-muted-foreground line-through\",\n status === \"failed\" && \"text-destructive\",\n status === \"running\" && \"font-medium\",\n )}\n >\n {title}\n {/* Status in text, always. The marker is a shape and a colour, and\n neither is information on its own. */}\n <span className=\"sr-only\">, {STATUS_LABEL[status]}</span>\n </span>\n\n {detail ? <span className=\"text-xs text-muted-foreground\">{detail}</span> : null}\n {status === \"failed\" && error ? (\n <span data-slot=\"agent-plan-error\" className=\"text-xs text-destructive\">\n {error}\n </span>\n ) : null}\n </div>\n </div>\n\n {children && children.length > 0 ? (\n <ol className=\"flex list-none flex-col gap-1\">\n {children.map((child) => (\n <AgentPlanStep key={child.id} step={child} nested />\n ))}\n </ol>\n ) : null}\n </li>\n );\n}\n\n/**\n * The status shape.\n *\n * aria-hidden throughout: every marker repeats what the step already states in\n * text, and announcing both means hearing the status twice per step.\n */\nfunction StepMarker({ status }: { status: StepStatus }) {\n const base = \"mt-0.5 grid size-4 shrink-0 place-items-center rounded-full border text-[9px]\";\n\n if (status === \"running\") {\n return (\n // Deliberately not data-motion=\"indicator\". The bar for that exemption is\n // that stopping the animation would say something false, and it would\n // not: the step already states \"In progress\" in text and carries\n // aria-current. This pulse is reinforcement, so under reduced motion it\n // stops like any other decoration.\n <span\n aria-hidden=\"true\"\n data-slot=\"agent-plan-marker\"\n className={cn(base, \"animate-pulse-soft border-primary bg-primary/15 text-primary\")}\n >\n <span className=\"size-1.5 rounded-full bg-primary\" />\n </span>\n );\n }\n\n return (\n <span\n aria-hidden=\"true\"\n data-slot=\"agent-plan-marker\"\n className={cn(\n base,\n status === \"done\" && \"border-success bg-success text-success-foreground\",\n status === \"failed\" && \"border-destructive bg-destructive text-destructive-foreground\",\n status === \"skipped\" && \"border-border-strong text-muted-foreground\",\n status === \"pending\" && \"border-border-strong\",\n )}\n >\n {status === \"done\" ? \"✓\" : status === \"failed\" ? \"✕\" : status === \"skipped\" ? \"–\" : null}\n </span>\n );\n}\n"],"mappings":"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"}
|
|
@@ -227,7 +227,7 @@ function ReviewField({ field, source, decision, streaming, lowConfidenceBelow, a
|
|
|
227
227
|
}),
|
|
228
228
|
sourced ? /* @__PURE__ */ jsx(FieldButton, {
|
|
229
229
|
"aria-label": `Show in source — ${field.label}`,
|
|
230
|
-
className: "
|
|
230
|
+
className: "ms-auto",
|
|
231
231
|
onClick: onActivate,
|
|
232
232
|
children: "Show in source"
|
|
233
233
|
}) : null
|