anentrypoint-design 0.0.247 → 0.0.248

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anentrypoint-design",
3
- "version": "0.0.247",
3
+ "version": "0.0.248",
4
4
  "description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
5
5
  "type": "module",
6
6
  "main": "./dist/247420.js",
@@ -7,6 +7,7 @@
7
7
  // keeps scripts/lint-classes.mjs passing without a PREFIXES change).
8
8
 
9
9
  import * as webjsx from '../../vendor/webjsx/index.js';
10
+ import { Pill } from './shell.js';
10
11
  const h = webjsx.createElement;
11
12
 
12
13
  // ---------------------------------------------------------------------------
@@ -38,9 +39,9 @@ export function PhaseWalk({ phases = DEFAULT_PHASES, reached = [], gapKinds = []
38
39
  export function TreeNode({ ts, kind, variant = '', phase, id, keyLabel, reason, deviationLabel, residuals } = {}) {
39
40
  const cls = 'ds-tree-node' + (variant ? ' is-' + variant : '');
40
41
  const pills = [
41
- phase ? h('span', { key: 'phase', class: 'ds-pill' }, phase) : null,
42
- id ? h('span', { key: 'id', class: 'ds-pill' }, id) : null,
43
- keyLabel ? h('span', { key: 'key', class: 'ds-pill' }, keyLabel) : null,
42
+ phase ? Pill({ key: 'phase', children: phase }) : null,
43
+ id ? Pill({ key: 'id', children: id }) : null,
44
+ keyLabel ? Pill({ key: 'key', children: keyLabel }) : null,
44
45
  ].filter(Boolean);
45
46
  return h('div', { class: cls },
46
47
  ts != null ? h('span', { class: 'ds-tree-node-ts' }, ts) : null,
@@ -128,8 +129,8 @@ export function SessionRow({ sessId, phaseWalkProps, events, verbs, prd, muts, r
128
129
  // ---------------------------------------------------------------------------
129
130
  export function DevRow({ ts, event, sess, operation, residuals } = {}) {
130
131
  const pills = [
131
- sess ? h('span', { key: 'sess', class: 'ds-pill' }, sess) : null,
132
- operation ? h('span', { key: 'op', class: 'ds-pill' }, operation) : null,
132
+ sess ? Pill({ key: 'sess', children: sess }) : null,
133
+ operation ? Pill({ key: 'op', children: operation }) : null,
133
134
  ].filter(Boolean);
134
135
  return h('div', { class: 'ds-dev-row' },
135
136
  ts != null ? h('span', { class: 'ds-tree-node-ts' }, ts) : null,
@@ -19,6 +19,19 @@ export function Toolbar({ leading = [], trailing = [], dense = false, children }
19
19
  );
20
20
  }
21
21
 
22
+ // ---------------------------------------------------------------------------
23
+ // ToolbarRow — a flat, wrapping row of arbitrary action nodes (buttons,
24
+ // inputs, chips) with no leading/center/trailing slot structure. Toolbar's
25
+ // three-slot split is the wrong shape when a caller just wants "this row of
26
+ // controls, left to right, wrapping on narrow viewports" — the exact shape
27
+ // gmsniff's panels.js hand-rolled as a bare '.gm-toolbar' div because Toolbar
28
+ // didn't cover it. Accepts children as varargs or a single array.
29
+ // ---------------------------------------------------------------------------
30
+ export function ToolbarRow(...actions) {
31
+ const flat = actions.length === 1 && Array.isArray(actions[0]) ? actions[0] : actions;
32
+ return h('div', { class: 'ds-ep-toolbar-row', role: 'toolbar' }, ...kids(flat));
33
+ }
34
+
22
35
  export function Tabs({ items = [], active, onChange, children, 'aria-label': ariaLabel } = {}) {
23
36
  // Roving tabindex + arrow nav per WAI-ARIA tabs pattern.
24
37
  // Only the active tab is in the tab order; arrows move focus + activate.
@@ -144,6 +157,42 @@ export function PropertyField({ label, hint, inline = false, children } = {}) {
144
157
  );
145
158
  }
146
159
 
160
+ // ---------------------------------------------------------------------------
161
+ // PropertyGridRow — a PropertyGrid row wrapper with a bottom-border divider
162
+ // (last-child border suppressed), for editors that need a stronger per-row
163
+ // visual separation than the default PropertyGrid gap gives (e.g. a list of
164
+ // independently-editable records like PRD/mutable rows). Generalizes
165
+ // gmsniff's gm-propgrid-row.
166
+ // ---------------------------------------------------------------------------
167
+ export function PropertyGridRow({ children, key } = {}) {
168
+ return h('div', { key, class: 'ds-ep-propgrid-row' }, ...kids(children));
169
+ }
170
+
171
+ // ---------------------------------------------------------------------------
172
+ // InlineEditableField — a borderless-until-focus text input that inherits
173
+ // surrounding font (no boxed input chrome), with an explicit error state
174
+ // (aria-invalid + danger-token border) for live per-field validation.
175
+ // Generalizes gmsniff's gm-inline-input / gm-field-error pair. Renders a
176
+ // <textarea> when multiline is set (for longer free-text edits), else a
177
+ // single-line <input>.
178
+ // ---------------------------------------------------------------------------
179
+ export function InlineEditableField({ value = '', placeholder, onInput, onChange, error, multiline = false, rows = 3, ariaLabel, disabled = false } = {}) {
180
+ const cls = 'ds-ep-inline-input' + (error ? ' has-error' : '');
181
+ const common = {
182
+ class: cls,
183
+ value,
184
+ placeholder,
185
+ disabled: disabled ? 'disabled' : null,
186
+ 'aria-label': ariaLabel,
187
+ 'aria-invalid': error ? 'true' : null,
188
+ oninput: onInput ? (e) => onInput(e.target.value, e) : null,
189
+ onchange: onChange ? (e) => onChange(e.target.value, e) : null,
190
+ };
191
+ return multiline
192
+ ? h('textarea', { ...common, rows })
193
+ : h('input', { ...common, type: 'text' });
194
+ }
195
+
147
196
  export function Dock({ top, left, right, bottom, center } = {}) {
148
197
  return h('div', { class: 'ds-ep-dock' },
149
198
  top != null ? h('div', { class: 'ds-ep-dock-top' }, ...kids(top)) : null,
@@ -538,6 +587,48 @@ export function toast({ message, kind = 'info', duration = 3000 } = {}) {
538
587
  return dismiss;
539
588
  }
540
589
 
590
+ // ---------------------------------------------------------------------------
591
+ // Pager — prev/next paginator with a page label. Generalizes gmsniff's
592
+ // gm-pager. page is 1-indexed; pageCount<=1 disables both buttons (no
593
+ // divide-by-zero, no dead-end enabled control). total (optional) renders an
594
+ // item-count suffix ("42 items") alongside the page label.
595
+ // ---------------------------------------------------------------------------
596
+ export function Pager({ page = 1, pageCount = 1, onPage, total, itemLabel = 'items' } = {}) {
597
+ const safeCount = Math.max(1, pageCount || 1);
598
+ const safePage = Math.min(Math.max(1, page || 1), safeCount);
599
+ const atStart = safePage <= 1;
600
+ const atEnd = safePage >= safeCount;
601
+ return h('div', { class: 'ds-ep-pager', role: 'group', 'aria-label': 'pagination' },
602
+ h('button', {
603
+ type: 'button', class: 'ds-ep-pager-btn', disabled: atStart ? 'disabled' : null,
604
+ 'aria-label': 'previous page',
605
+ onclick: () => { if (!atStart && onPage) onPage(safePage - 1); },
606
+ }, '<-'),
607
+ h('span', { class: 'ds-ep-pager-label' },
608
+ 'page ' + safePage + ' / ' + safeCount + (total != null ? ' (' + total + ' ' + itemLabel + ')' : '')),
609
+ h('button', {
610
+ type: 'button', class: 'ds-ep-pager-btn', disabled: atEnd ? 'disabled' : null,
611
+ 'aria-label': 'next page',
612
+ onclick: () => { if (!atEnd && onPage) onPage(safePage + 1); },
613
+ }, '->')
614
+ );
615
+ }
616
+
617
+ // ---------------------------------------------------------------------------
618
+ // JsonViewer — pre-formatted monospace data preview (max-height + scroll),
619
+ // generalizing gmsniff's gm-json. Accepts a pre-stringified string OR any
620
+ // value (objects/arrays get JSON.stringify(v, null, 2); null/undefined render
621
+ // the empty-state text rather than the literal string "undefined"/"null").
622
+ // ---------------------------------------------------------------------------
623
+ export function JsonViewer({ value, emptyText = 'no data', maxHeight } = {}) {
624
+ let text;
625
+ if (value == null) text = null;
626
+ else if (typeof value === 'string') text = value;
627
+ else { try { text = JSON.stringify(value, null, 2); } catch { text = String(value); } }
628
+ if (!text) return h('div', { class: 'ds-ep-json ds-ep-json-empty' }, emptyText);
629
+ return h('pre', { class: 'ds-ep-json', style: maxHeight ? ('max-height:' + maxHeight) : null }, text);
630
+ }
631
+
541
632
  export function IconButtonGroup({ items = [], value, onChange, dense = false } = {}) {
542
633
  return h('div', { class: 'ds-ep-btngrp' + (dense ? ' dense' : ''), role: 'group' },
543
634
  ...items.map((it) => h('button', {
@@ -71,6 +71,16 @@ export function Badge({ children, variant = 'default', tone = 'neutral' }) {
71
71
  return h('span', { class: 'ds-badge ds-badge-' + variant + ' tone-' + tone }, children);
72
72
  }
73
73
 
74
+ // Pill — plain non-interactive label chip for tag-like annotations (a phase
75
+ // name, an id, a subsystem tag). Distinct from Chip (status-tone indicator),
76
+ // Badge (count/variant marker), and FilterPills (interactive toggle-group):
77
+ // Pill renders no button, carries no pressed/active state, just a small
78
+ // rounded label. tone is a semantic keyword ('' | 'accent' | 'muted'),
79
+ // never a raw color — every visual rides colors_and_type.css tokens.
80
+ export function Pill({ tone = '', children, key } = {}) {
81
+ return h('span', { key, class: 'ds-pill' + (tone ? ' tone-' + tone : '') }, children);
82
+ }
83
+
74
84
  export function Glyph({ children, color, size = 'base', label } = {}) {
75
85
  // Font-size is var-driven per size class (--glyph-size-{size}) so themes can
76
86
  // retune glyph scale; inline fallback keeps sizing if the SDK CSS hasn't
package/src/components.js CHANGED
@@ -4,7 +4,7 @@ import * as webjsx from '../vendor/webjsx/index.js';
4
4
  export const h = webjsx.createElement;
5
5
 
6
6
  export {
7
- Brand, Chip, Btn, Glyph, Icon, IconButton, Badge,
7
+ Brand, Chip, Btn, Glyph, Icon, IconButton, Badge, Pill,
8
8
  Topbar, Crumb, Side, Status, AppShell,
9
9
  WorkspaceShell, WorkspaceRail,
10
10
  Heading, Lede, Dot, Rail
@@ -71,14 +71,15 @@ export {
71
71
  } from './components/interaction-primitives.js';
72
72
 
73
73
  export {
74
- Toolbar, Tabs,
74
+ Toolbar, ToolbarRow, Tabs,
75
75
  TreeView, TreeItem,
76
- PropertyGrid, PropertyField,
76
+ PropertyGrid, PropertyField, PropertyGridRow, InlineEditableField,
77
77
  Dock, IconButtonGroup,
78
78
  ResizeHandle, SplitPanel,
79
79
  ContextMenu, useContextMenu,
80
80
  Drawer, Dialog, FocusTrap,
81
81
  Toast, toast,
82
+ Pager, JsonViewer,
82
83
  useMediaQuery,
83
84
  BP_SM, BP_MD, BP_LG, BP_XL
84
85
  } from './components/editor-primitives.js';