swarm-ui: give Panel an optional header icon slot
Adds an `icon` prop to Panel (small emoji glyph left of the title, aria-hidden, chosen per panel with no default) and wires it into every current Panel caller: hives (bee), create-agent's form (robot) and info panel (identity card, moved off the info panel's body copy where it started as a one-off), jobs (puzzle piece), the components gallery itself (toolbox), and the 404 page (compass). Adds a components-page demo section and a whimsy-section pointer in the design guide. Closes: #3508
This commit is contained in:
parent
582b5cf83d
commit
b25aa157df
9 changed files with 49 additions and 15 deletions
|
|
@ -15,6 +15,10 @@
|
|||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.ui-panel-icon {
|
||||
font-size: 1.2em;
|
||||
line-height: 1;
|
||||
}
|
||||
/* `margin-left: auto` (not `justify-content: space-between` on the
|
||||
header) so actions still land at the right edge even on the rare
|
||||
panel that has actions but no title. */
|
||||
|
|
|
|||
|
|
@ -11,22 +11,44 @@
|
|||
// dedicated row stealing vertical space from the panel's actual
|
||||
// content either). `HivesPage`'s refresh-interval picker is the
|
||||
// motivating caller.
|
||||
//
|
||||
// `icon` is a small header glyph, left of the title — the swarm-ui
|
||||
// design guide's own whimsy reference (before this, the guide only
|
||||
// pointed at the dashboard's matrix-rain background). Grew out of
|
||||
// CreateAgentPage's one-off 🪪 dropped straight into a panel's body
|
||||
// copy: mara's call on review was that a single ad-hoc emoji isn't
|
||||
// whimsy in the guide's sense (small, delightful, *consistent*), it
|
||||
// should be a real theme every panel can opt into the same way. Plain
|
||||
// `string` (an emoji literal), not an icon-library asset — same
|
||||
// lightweight-glyph precedent `RefreshIntervalPicker`'s 🕐 set before
|
||||
// this. Chosen per panel, no default: not every panel needs one, and
|
||||
// there's no single semantic mapping (e.g. "jobs" pages) worth
|
||||
// hardcoding. `aria-hidden` — decorative only, the title text still
|
||||
// carries the actual label, so this never becomes a second source of
|
||||
// truth an assistive-tech user has to parse.
|
||||
import type { ComponentChildren } from 'preact';
|
||||
import './Panel.css';
|
||||
|
||||
export function Panel({
|
||||
title,
|
||||
icon,
|
||||
actions,
|
||||
children,
|
||||
}: {
|
||||
title?: string;
|
||||
icon?: string;
|
||||
actions?: ComponentChildren;
|
||||
children: ComponentChildren;
|
||||
}) {
|
||||
return (
|
||||
<section class="ui-panel">
|
||||
{title || actions ? (
|
||||
{title || icon || actions ? (
|
||||
<div class="ui-panel-header">
|
||||
{icon ? (
|
||||
<span class="ui-panel-icon" aria-hidden="true">
|
||||
{icon}
|
||||
</span>
|
||||
) : null}
|
||||
{title ? <h2 class="ui-panel-title">{title}</h2> : null}
|
||||
{actions ? <div class="ui-panel-actions">{actions}</div> : null}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue