anentrypoint-design 0.0.146 → 0.0.147

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.
@@ -303,11 +303,12 @@ export function CommandPalette({ open, items = [], onSelect, onClose } = {}) {
303
303
  h('div', { class: 'ov-cmd-panel', role: 'dialog', 'aria-label': 'Command palette', onkeydown: onKey },
304
304
  h('input', {
305
305
  type: 'text', class: 'ov-cmd-input', placeholder: 'Type a command…',
306
- 'aria-label': 'Filter commands',
306
+ 'aria-label': 'command search',
307
+ 'aria-controls': 'ov-cmd-list',
307
308
  oninput: (e) => { filterText = e.target.value; active = 0; renderInner(); },
308
309
  ref: (el) => { if (!el || el._ovCmdIn) return; el._ovCmdIn = true; inputEl = el; queueMicrotask(() => el.focus()); },
309
310
  }),
310
- h('div', { class: 'ov-cmd-list', role: 'listbox',
311
+ h('div', { class: 'ov-cmd-list', id: 'ov-cmd-list', role: 'listbox',
311
312
  ref: (el) => { if (!el) return; listEl = el; queueMicrotask(renderInner); } })
312
313
  )
313
314
  );
@@ -43,8 +43,26 @@ export function Btn({ href = '#', variant = 'default', children, onClick, 'aria-
43
43
  }, children);
44
44
  }
45
45
 
46
- export function Glyph({ children, color }) {
47
- return h('span', { class: 'glyph', style: color ? `color:${color}` : '' }, children);
46
+ export function IconButton({ icon, onClick, title, size = 'base', variant = 'ghost', disabled = false }) {
47
+ const cls = 'ds-icon-btn ds-icon-btn-' + variant + ' ds-icon-btn-' + size + (disabled ? ' is-disabled' : '');
48
+ return h('button', {
49
+ type: 'button',
50
+ class: cls,
51
+ title,
52
+ 'aria-label': title,
53
+ disabled: disabled ? true : null,
54
+ onclick: (e) => { if (disabled) { e.preventDefault(); return; } if (onClick) onClick(e); }
55
+ }, Glyph({ children: icon, size }));
56
+ }
57
+
58
+ export function Badge({ children, variant = 'default', tone = 'neutral' }) {
59
+ return h('span', { class: 'ds-badge ds-badge-' + variant + ' tone-' + tone }, children);
60
+ }
61
+
62
+ export function Glyph({ children, color, size = 'base' }) {
63
+ const fontSize = size === 'sm' ? '11px' : (size === 'lg' ? '16px' : '13px');
64
+ const style = `font-size:${fontSize}` + (color ? `;color:${color}` : '');
65
+ return h('span', { class: 'glyph', style }, children);
48
66
  }
49
67
 
50
68
  export function Topbar({ brand = '247420', leaf = '', items = [], active = '', onNav, search } = {}) {
@@ -113,23 +131,40 @@ export function Status({ left = [], right = [] } = {}) {
113
131
  );
114
132
  }
115
133
 
134
+ // Toggle the mobile sidebar drawer. Pure-DOM because AppShell is stateless
135
+ // chrome; the class lives on .app-body and is read by the ≤900px media query.
136
+ function toggleSide(open) {
137
+ const body = document.querySelector('.app-body');
138
+ if (!body) return;
139
+ const next = open != null ? open : !body.classList.contains('side-open');
140
+ body.classList.toggle('side-open', next);
141
+ const btn = document.querySelector('.app-side-toggle');
142
+ if (btn) btn.setAttribute('aria-expanded', next ? 'true' : 'false');
143
+ }
144
+
116
145
  export function AppShell({ topbar, crumb, side, main, status, narrow } = {}) {
117
146
  const hasSide = Boolean(side);
118
147
  const sideNode = hasSide ? side : h('aside', { class: 'app-side', 'aria-hidden': 'true' });
119
148
  return h('div', { class: 'app' },
120
149
  h('a', { href: '#app-main', class: 'skip-link' }, 'skip to main content'),
150
+ hasSide ? h('button', {
151
+ class: 'app-side-toggle', type: 'button',
152
+ 'aria-label': 'toggle navigation', 'aria-expanded': 'false', 'aria-controls': 'app-main',
153
+ onclick: () => toggleSide(),
154
+ }, '☰') : null,
121
155
  topbar || null,
122
156
  crumb || null,
123
157
  h('div', { class: 'app-body' + (hasSide ? '' : ' no-side') },
124
- h('div', { class: 'app-side-shell' }, sideNode),
158
+ h('div', { class: 'app-side-scrim', 'aria-hidden': 'true', onclick: () => toggleSide(false) }),
159
+ h('div', { class: 'app-side-shell', onclick: (e) => { if (e.target.closest('a')) toggleSide(false); } }, sideNode),
125
160
  h('main', { class: 'app-main' + (narrow ? ' narrow' : ''), id: 'app-main' }, ...(Array.isArray(main) ? main : [main]))
126
161
  ),
127
162
  status || null
128
163
  );
129
164
  }
130
165
 
131
- export function Heading({ level = 1, children, style = '' }) {
132
- return h('h' + level, { style }, children);
166
+ export function Heading({ level = 1, children, style = '', 'aria-level': ariaLevel }) {
167
+ return h('h' + level, { style, 'aria-level': ariaLevel != null ? String(ariaLevel) : null }, children);
133
168
  }
134
169
 
135
170
  export function Lede({ children }) {
package/src/components.js CHANGED
@@ -4,13 +4,13 @@ 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,
7
+ Brand, Chip, Btn, Glyph, IconButton, Badge,
8
8
  Topbar, Crumb, Side, Status, AppShell,
9
9
  Heading, Lede, Dot, Rail
10
10
  } from './components/shell.js';
11
11
 
12
12
  export {
13
- Panel, Row, RowLink,
13
+ Panel, Card, Row, RowLink,
14
14
  Hero, Install, Receipt, Changelog,
15
15
  WorksList, WritingList, Manifesto, Section, PageHeader,
16
16
  Kpi, Table, SearchInput, TextField, Select, EventList,
@@ -134,7 +134,7 @@ export function makeChatPage(ctx) {
134
134
  ? Panel({ title: 'no providers configured', children: Receipt({ rows: [
135
135
  ['set API key', 'go to keys tab, click a provider chip to set its key'],
136
136
  ['then reload', 'refresh this page to see providers here'],
137
- ['or use acptoapi', 'run acptoapi server on localhost:4800 for local LLMs'],
137
+ ['or use a gateway', 'run a gateway server on localhost:4800 for local LLMs'],
138
138
  ] }) })
139
139
  : Panel({ title: 'configured providers', children: h('div', { class: 'fd-chip-wrap' },
140
140
  ...providers.map(p => Chip({ tone: p.configured ? (p.available ? 'ok' : 'warn') : 'miss', children: p.name + (p.configured ? (p.available ? ' ●' : ' ○') : '') }))) }),
@@ -45,7 +45,7 @@ export function makeCorePages(ctx) {
45
45
  const skills = h0.pi.skills.size;
46
46
  const health = (typeof h0.pi.health === 'function') ? h0.pi.health() : { ok: true };
47
47
  return [
48
- Hero({ title: 'freddie', body: 'open js agent harness — pi-mono · xstate · floosie · anentrypoint-design.', accent: h0.version || 'web' }),
48
+ Hero({ title: 'assistant', body: 'open js agent harness — in-page agent runtime.', accent: h0.version || 'web' }),
49
49
  Kpi({ items: [[sessions.length, 'sessions'], [tools, 'tools'], [skills, 'skills']] }),
50
50
  Panel({ title: 'quick start', children: Receipt({ rows: [
51
51
  ['open chat', "click 'chat' in sidebar — set a working directory and pick a skill"],
@@ -42,7 +42,7 @@ export function createFreddieDashboard({ instance, bootHost, osSurfaces, loading
42
42
 
43
43
  function buildSide() {
44
44
  const sections = [{
45
- group: 'FREDDIE',
45
+ group: 'ASSISTANT',
46
46
  items: ROUTES.map(r => ({
47
47
  glyph: r.glyph, label: r.label, href: '#fd-' + r.path,
48
48
  active: state.active === r.path,
@@ -63,8 +63,8 @@ export function createFreddieDashboard({ instance, bootHost, osSurfaces, loading
63
63
  function view() {
64
64
  const route = allRoutes.find(r => r.path === state.active) || ROUTES[1];
65
65
  return AppShell({
66
- topbar: Topbar({ brand: 'freddie', leaf: 'dashboard', items: [], active: '' }),
67
- crumb: Crumb({ trail: ['freddie', instance.id], leaf: route.path, right: state.error ? Chip({ tone: 'miss', children: 'error' }) : Chip({ tone: 'ok', children: 'live' }) }),
66
+ topbar: Topbar({ brand: 'assistant', leaf: 'dashboard', items: [], active: '' }),
67
+ crumb: Crumb({ trail: ['assistant', instance.id], leaf: route.path, right: state.error ? Chip({ tone: 'miss', children: 'error' }) : Chip({ tone: 'ok', children: 'live' }) }),
68
68
  side: buildSide(),
69
69
  main: state.body || EmptyState({ text: loadingText || 'loading…', glyph: '◌' }),
70
70
  status: Status({ left: ['ds-247420 · webjsx · ' + allRoutes.length + ' routes', 'instance=' + instance.id], right: [state.ts] }),
@@ -39,6 +39,8 @@ export function createDesktopShell({ root = document.body, wm, registry, brand =
39
39
 
40
40
  const menubar = document.createElement('div');
41
41
  menubar.className = 'os-menubar';
42
+ menubar.setAttribute('role', 'menubar');
43
+ menubar.setAttribute('aria-label', 'Desktop menu bar');
42
44
 
43
45
  const homeBtn = makeBtn(icons.home, '', 'home');
44
46
  homeBtn.title = 'apps';