swarm-ui: add Dialog/ConfirmDialog sections to the components page
mara (#4172): the components page was out of date against its own stated rule ("a new primitive gets a section here the same day it's added"). Dialog and ConfirmDialog are real standalone exported primitives (AgentsPage uses both directly) with no demo section. FormField deliberately stays excluded — its own comment already says it's not a reachable primitive, just TextField/SelectField's shared internal wrapper, so it was never meant to get one. Also gave the Table demo's "detail" column a multiselect filter, so the checkbox popover and reset-filters button — real, daily-used Table behavior — are actually shown rather than an unfiltered grid.
This commit is contained in:
parent
b0edb5b2cc
commit
61f60d0039
1 changed files with 65 additions and 1 deletions
|
|
@ -20,6 +20,8 @@ import {
|
||||||
type SelectOption,
|
type SelectOption,
|
||||||
} from "../ui/select-field/SelectField.js";
|
} from "../ui/select-field/SelectField.js";
|
||||||
import { Button, type ButtonVariant } from "../ui/button/Button.js";
|
import { Button, type ButtonVariant } from "../ui/button/Button.js";
|
||||||
|
import { Dialog } from "../ui/dialog/Dialog.js";
|
||||||
|
import { ConfirmDialog } from "../ui/confirm-dialog/ConfirmDialog.js";
|
||||||
import { Badge, type BadgeTone } from "@hive/shared/badge.js";
|
import { Badge, type BadgeTone } from "@hive/shared/badge.js";
|
||||||
import { GearIcon } from "@hive/shared/icons.js";
|
import { GearIcon } from "@hive/shared/icons.js";
|
||||||
import { Dropdown, type DropdownOption } from "@hive/shared/dropdown.js";
|
import { Dropdown, type DropdownOption } from "@hive/shared/dropdown.js";
|
||||||
|
|
@ -62,7 +64,17 @@ interface Row {
|
||||||
|
|
||||||
const TABLE_COLUMNS: TableColumn<Row>[] = [
|
const TABLE_COLUMNS: TableColumn<Row>[] = [
|
||||||
{ key: "name", header: "name", render: (r) => r.name },
|
{ key: "name", header: "name", render: (r) => r.name },
|
||||||
{ key: "detail", header: "detail", render: (r) => r.detail },
|
{
|
||||||
|
key: "detail",
|
||||||
|
header: "detail",
|
||||||
|
render: (r) => r.detail,
|
||||||
|
// One filterable column, multiselect mode — the checkbox-list popover
|
||||||
|
// + reset-filters button are both real `Table` behavior an operator
|
||||||
|
// hits daily (`AgentsPage`/`HivesPage`), so the demo shows them rather
|
||||||
|
// than a plain unfilterable grid.
|
||||||
|
filterValues: (r) => [r.detail],
|
||||||
|
filterMode: "multiselect",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "status",
|
key: "status",
|
||||||
header: "status",
|
header: "status",
|
||||||
|
|
@ -181,6 +193,46 @@ function BadgeToggleSample() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `Dialog` and `ConfirmDialog` both need `open` state to actually toggle —
|
||||||
|
// same "controlled sample needs its own wrapper" reasoning as
|
||||||
|
// `TextFieldSample` above.
|
||||||
|
function DialogSample() {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button onClick={() => setOpen(true)}>open dialog</Button>
|
||||||
|
<Dialog open={open} onClose={() => setOpen(false)} label="sample dialog">
|
||||||
|
<p>
|
||||||
|
Plain content — <code>Dialog</code> supplies the modal wiring (focus
|
||||||
|
trap, Escape, backdrop-click) and the close button; the caller owns
|
||||||
|
everything else, including its own heading if it wants one.
|
||||||
|
</p>
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ConfirmDialogSample() {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button onClick={() => setOpen(true)}>open confirm dialog</Button>
|
||||||
|
<ConfirmDialog
|
||||||
|
open={open}
|
||||||
|
label="sample confirm dialog"
|
||||||
|
onCancel={() => setOpen(false)}
|
||||||
|
onConfirm={() => setOpen(false)}
|
||||||
|
confirmLabel="confirm"
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
The message is caller-owned <code>children</code>, same as{" "}
|
||||||
|
<code>Dialog</code> — only the button row and spacing are shared.
|
||||||
|
</p>
|
||||||
|
</ConfirmDialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function ComponentsPage() {
|
export function ComponentsPage() {
|
||||||
return (
|
return (
|
||||||
<Panel title="components" icon="🧰">
|
<Panel title="components" icon="🧰">
|
||||||
|
|
@ -278,6 +330,18 @@ export function ComponentsPage() {
|
||||||
</div>
|
</div>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
|
<Section title="Dialog">
|
||||||
|
<Sample label="modal, caller-owned content">
|
||||||
|
<DialogSample />
|
||||||
|
</Sample>
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
<Section title="ConfirmDialog">
|
||||||
|
<Sample label="modal, cancel/confirm button row">
|
||||||
|
<ConfirmDialogSample />
|
||||||
|
</Sample>
|
||||||
|
</Section>
|
||||||
|
|
||||||
<Section title="Badge (@hive/shared — used by swarm-ui and the per-agent page)">
|
<Section title="Badge (@hive/shared — used by swarm-ui and the per-agent page)">
|
||||||
<div class="components-chip-row">
|
<div class="components-chip-row">
|
||||||
{BADGE_TONES.map((tone) => (
|
{BADGE_TONES.map((tone) => (
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue