anentrypoint-design 0.0.213 → 0.0.215

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.213",
3
+ "version": "0.0.215",
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",
@@ -91,7 +91,7 @@ function AgentControls({ agents, selectedAgent, models, selectedModel, busy, sta
91
91
  busy
92
92
  ? Btn({ key: 'stop', onClick: () => onStop && onStop(), children: 'stop', title: 'Stop streaming' })
93
93
  : Btn({ key: 'new', onClick: () => onNewChat && onNewChat(), children: 'new', title: 'New chat' }),
94
- h('span', { key: 'st', class: 'agentchat-status', role: 'status', 'aria-live': 'polite' },
94
+ h('span', { key: 'st', class: 'agentchat-status', role: 'status', 'aria-live': 'polite', 'aria-atomic': 'true' },
95
95
  h('span', { class: 'status-dot-disc ' + (busy ? 'status-dot-live' : ''), 'aria-hidden': 'true' }),
96
96
  h('span', {}, status || (busy ? 'streaming…' : 'ready'))),
97
97
  // Host-supplied transcript actions (copy-all / export-md / export-json):
@@ -119,6 +119,7 @@ function CwdBar({ cwd, editing, draft, onEdit, onSave, onCancel, onClear, onDraf
119
119
  placeholder: 'absolute path (blank = server default)',
120
120
  'aria-describedby': hint ? 'agentchat-cwd-hint' : null,
121
121
  'aria-invalid': error ? 'true' : null,
122
+ 'aria-busy': checking ? 'true' : null,
122
123
  oninput: (e) => onDraft && onDraft(e.target.value) }),
123
124
  Btn({ key: 'save', variant: 'primary', disabled: !!(error || checking), onClick: () => onSave && onSave(), children: 'save' }),
124
125
  Btn({ key: 'cancel', onClick: () => onCancel && onCancel(), children: 'cancel' }),
@@ -372,7 +373,7 @@ export function AgentChat(props = {}) {
372
373
  CwdBar({ cwd, editing: cwdEditing, draft: cwdDraft, error: cwdError, checking: cwdChecking,
373
374
  onEdit: onCwdEdit, onSave: onCwdSave, onCancel: onCwdCancel, onClear: onCwdClear, onDraft: onCwdDraft }),
374
375
  ...(banners || []).filter(Boolean),
375
- h('div', { class: 'agentchat-head', role: 'banner' },
376
+ h('div', { class: 'agentchat-head' },
376
377
  h('h2', { class: 'agentchat-title' }, name + (selectedModel ? ' · ' + selectedModel : '')),
377
378
  h('span', { class: 'agentchat-sub', 'aria-live': 'polite' },
378
379
  // Derive the busy label from the same status prop the controls use, so a
@@ -211,6 +211,7 @@ function ToolCallNode(p) {
211
211
  const status = p.status || (p.error ? 'error' : (p.result != null ? 'done' : 'running'));
212
212
  const argsText = typeof p.args === 'string' ? p.args : JSON.stringify(p.args || {}, null, 2);
213
213
  const resultText = p.result == null ? '' : (typeof p.result === 'string' ? p.result : JSON.stringify(p.result, null, 2));
214
+ const hasArgs = p.args != null && argsText !== '{}' && argsText.trim() !== '';
214
215
  // Default-open while running or on error so the user sees live progress / failure detail;
215
216
  // collapse on success unless the caller explicitly overrides with open:true.
216
217
  const defaultOpen = p.open != null ? !!p.open : (status === 'running' || status === 'error');
@@ -236,18 +237,20 @@ function ToolCallNode(p) {
236
237
  h('span', { class: 'chat-tool-status' }, status)
237
238
  ),
238
239
  h('div', { class: 'chat-tool-body' },
239
- h('div', { class: 'chat-tool-section' },
240
- sectionLabel('args', argsText),
241
- h('pre', { class: 'chat-tool-pre' }, h('code', {}, argsText))),
242
- resultText ? h('div', { class: 'chat-tool-section' },
243
- sectionLabel(p.error ? 'error' : 'result', resultText),
244
- h('pre', { class: 'chat-tool-pre' + (p.error ? ' is-error' : '') }, h('code', {}, resultText)))
245
- // A finished tool with no output would otherwise render no result
246
- // section, reading identically to a still-running tool. Show an
247
- // explicit placeholder so "done, empty" is distinguishable.
248
- : (status === 'done' ? h('div', { class: 'chat-tool-section' },
249
- h('div', { class: 'chat-tool-section-label' }, 'result'),
250
- h('pre', { class: 'chat-tool-pre chat-tool-empty' }, h('code', {}, '(no output)'))) : null)
240
+ ...[
241
+ hasArgs ? h('div', { class: 'chat-tool-section' },
242
+ sectionLabel('args', argsText),
243
+ h('pre', { class: 'chat-tool-pre' }, h('code', {}, argsText))) : null,
244
+ resultText ? h('div', { class: 'chat-tool-section' },
245
+ sectionLabel(p.error ? 'error' : 'result', resultText),
246
+ h('pre', { class: 'chat-tool-pre' + (p.error ? ' is-error' : '') }, h('code', {}, resultText)))
247
+ // A finished tool with no output would otherwise render no result
248
+ // section, reading identically to a still-running tool. Show an
249
+ // explicit placeholder so "done, empty" is distinguishable.
250
+ : (status === 'done' ? h('div', { class: 'chat-tool-section' },
251
+ h('div', { class: 'chat-tool-section-label' }, 'result'),
252
+ h('pre', { class: 'chat-tool-pre chat-tool-empty' }, h('code', {}, '(no output)'))) : null)
253
+ ].filter(Boolean)
251
254
  )
252
255
  );
253
256
  }
@@ -521,6 +524,7 @@ export function ChatComposer({ value, onInput, onSend, onAttach, onEmoji, onMenu
521
524
  },
522
525
  contextLine,
523
526
  h('textarea', { ref: taRef, placeholder, rows: 1, 'aria-label': 'message input',
527
+ disabled: !!disabled, 'aria-disabled': disabled ? 'true' : null,
524
528
  oninput: autoGrow,
525
529
  onpaste: (e) => {
526
530
  const cd = e.clipboardData;
@@ -83,7 +83,7 @@ export function ChannelItem({ id, name, type = 'text', active, voiceActive, voic
83
83
  title: a.title || '',
84
84
  'data-action': a.id || '',
85
85
  onclick: (e) => handleActionClick(a, e)
86
- }, a.icon || a.label || ''))
86
+ }, a.icon || a.label || 'more'))
87
87
  ) : null
88
88
  ),
89
89
  voiceActive && participants.length ? h('div', { class: 'cm-ch-voice-users' },
@@ -185,6 +185,7 @@ export function WorksList({ works = [], openedIndex = -1, onToggle }) {
185
185
  w.meta != null ? h('span', {}, w.meta) : null,
186
186
  Icon(isOpen ? 'chevron-down' : 'chevron-right')),
187
187
  active: isOpen,
188
+ expanded: isOpen,
188
189
  onClick: () => onToggle && onToggle(isOpen ? -1 : i)
189
190
  }),
190
191
  isOpen ? h('div', { class: 'work-detail', 'data-work-index': String(i) },
@@ -352,12 +353,17 @@ export function SearchInput({ value = '', placeholder = 'search…', onInput, on
352
353
  });
353
354
  }
354
355
 
355
- export function TextField({ label, value = '', type = 'text', placeholder = '', onInput, onChange, name, key, hint, multiline, rows = 4, maxLength, min, max, 'aria-label': ariaLabel }) {
356
+ export function TextField({ label, value = '', type = 'text', placeholder = '', onInput, onChange, name, key, hint, multiline, rows = 4, maxLength, min, max, error, title, 'aria-label': ariaLabel, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy }) {
357
+ const errorId = error != null ? ((key ? key : 'tf') + '-err') : null;
358
+ const describedBy = ariaDescribedBy || errorId || null;
356
359
  const input = multiline
357
360
  ? h('textarea', {
358
361
  key: 'i', name, rows, placeholder, value,
359
362
  maxlength: maxLength != null ? maxLength : null,
360
363
  'aria-label': ariaLabel || null,
364
+ 'aria-invalid': error != null ? 'true' : (ariaInvalid || null),
365
+ 'aria-describedby': describedBy,
366
+ title: title || null,
361
367
  oninput: onInput ? (e) => onInput(e.target.value, e) : null,
362
368
  onchange: onChange ? (e) => onChange(e.target.value, e) : null
363
369
  })
@@ -367,14 +373,20 @@ export function TextField({ label, value = '', type = 'text', placeholder = '',
367
373
  min: min != null ? String(min) : null,
368
374
  max: max != null ? String(max) : null,
369
375
  'aria-label': ariaLabel || null,
376
+ 'aria-invalid': error != null ? 'true' : (ariaInvalid || null),
377
+ 'aria-describedby': describedBy,
378
+ title: title || null,
370
379
  oninput: onInput ? (e) => onInput(e.target.value, e) : null,
371
380
  onchange: onChange ? (e) => onChange(e.target.value, e) : null
372
381
  });
373
382
  return h('label', { key, class: 'ds-field' },
374
- label != null ? h('span', { key: 'l', class: 'ds-field-label' }, label) : null,
375
- input,
376
- maxLength != null ? h('span', { key: 'c', class: 'ds-field-count' }, String(value.length) + '/' + maxLength) : null,
377
- hint != null ? h('span', { key: 'h', class: 'ds-field-hint' }, hint) : null
383
+ ...[
384
+ label != null ? h('span', { key: 'l', class: 'ds-field-label' }, label) : null,
385
+ input,
386
+ error != null ? h('span', { key: 'e', id: errorId, class: 'ds-field-error', role: 'alert', 'aria-live': 'polite', 'aria-atomic': 'true' }, error) : null,
387
+ maxLength != null ? h('span', { key: 'c', class: 'ds-field-count' }, String(value.length) + '/' + maxLength) : null,
388
+ hint != null ? h('span', { key: 'h', class: 'ds-field-hint' }, hint) : null
389
+ ].filter(Boolean)
378
390
  );
379
391
  }
380
392
 
@@ -428,7 +440,11 @@ export function EventList({ items, events, emptyText = 'no events', rankPad = 3,
428
440
  rail: it.rail,
429
441
  // Forward a disclosure state when the host marks the row as a toggle,
430
442
  // so a clickable event row announces aria-expanded.
431
- expanded: it.expanded
443
+ expanded: it.expanded,
444
+ detail: it.detail,
445
+ actions: it.actions,
446
+ highlight: it.highlight,
447
+ meta: it.meta
432
448
  }))
433
449
  );
434
450
  }
@@ -271,9 +271,9 @@ function matchEvent(e, spec) {
271
271
 
272
272
  export function formatShortcut(combo) {
273
273
  const s = parseCombo(combo);
274
- const mod = s.mod ? (IS_MAC ? '' : 'Ctrl+') : '';
275
- const shift = s.shift ? (IS_MAC ? '⇧' : 'Shift+') : '';
276
- const alt = s.alt ? (IS_MAC ? '⌥' : 'Alt+') : '';
274
+ const mod = s.mod ? (IS_MAC ? 'Cmd+' : 'Ctrl+') : '';
275
+ const shift = s.shift ? 'Shift+' : '';
276
+ const alt = s.alt ? 'Alt+' : '';
277
277
  const key = s.key.length === 1 ? s.key.toUpperCase() : s.key;
278
278
  return mod + alt + shift + key;
279
279
  }
@@ -296,10 +296,25 @@ export function useKeyboardShortcut(map = {}, { scope = 'global', enabled = true
296
296
 
297
297
  export function ShortcutHint({ combo, kind = 'kbd' } = {}) { return h('kbd', { class: 'ds-kbd ds-kbd-' + kind }, formatShortcut(combo || '')); }
298
298
 
299
+ function shortcutCaps(keys) {
300
+ const caps = [];
301
+ let n = 0;
302
+ const alts = String(keys || '').split(' / ');
303
+ alts.forEach((alt, ai) => {
304
+ if (ai > 0) caps.push(h('span', { key: 'sep-alt-' + (n++), class: 'ds-kbd-sep' }, ' / '));
305
+ const steps = alt.split(' then ');
306
+ steps.forEach((step, si) => {
307
+ if (si > 0) caps.push(h('span', { key: 'sep-then-' + (n++), class: 'ds-kbd-sep' }, ' then '));
308
+ caps.push(h('kbd', { key: 'cap-' + (n++), class: 'ds-kbd' }, step));
309
+ });
310
+ });
311
+ return caps;
312
+ }
313
+
299
314
  export function ShortcutList({ shortcuts = [] } = {}) {
300
315
  return h('div', { class: 'ds-shortcuts-hint' },
301
316
  ...shortcuts.map(s => h('div', { class: 'ds-shortcut-row' },
302
- h('kbd', { class: 'ds-kbd' }, s.keys || s.combo || ''),
317
+ h('span', { class: 'ds-kbd-caps' }, ...shortcutCaps(s.keys || s.combo || '')),
303
318
  h('span', { class: 'ds-kbd-label' }, s.desc || s.description || s.label || ''))));
304
319
  }
305
320
 
@@ -94,11 +94,11 @@ export function ConversationList({ sessions = [], selected, groups, search, capt
94
94
  h('div', { key: 'head', class: 'ds-session-head' },
95
95
  onNew ? h('button', { key: 'new', type: 'button', class: 'ds-session-new', onclick: onNew, 'aria-label': newLabel },
96
96
  Icon('pencil'), h('span', { key: 'l' }, newLabel)) : null,
97
- search ? h('input', {
98
- key: 'search', type: 'search', class: 'ds-session-search',
99
- value: search.value || '', placeholder: search.placeholder || 'Search conversations',
100
- 'aria-label': search.placeholder || 'Search conversations',
101
- oninput: (e) => search.onInput && search.onInput(e.target.value),
97
+ search ? SearchInput({
98
+ key: 'search', value: search.value || '',
99
+ label: search.placeholder || 'Search conversations',
100
+ placeholder: search.placeholder || 'Search conversations',
101
+ onInput: (v) => search.onInput && search.onInput(v),
102
102
  }) : null),
103
103
  // Per-tab caption telling the user what selecting a row does on this surface
104
104
  // (chat = resume the conversation, history = browse its events) so visually
@@ -342,7 +342,7 @@ function wsResize(col, dx, persist = true) {
342
342
  const next = Math.max(lo, Math.min(hi, Math.round(cur + dx)));
343
343
  shell.style.setProperty('--ws-' + col + '-w', next + 'px');
344
344
  const handle = shell.querySelector('.ws-resizer-' + col);
345
- if (handle) handle.setAttribute('aria-valuenow', String(next));
345
+ if (handle) { handle.setAttribute('aria-valuenow', String(next)); handle.setAttribute('aria-valuetext', next + ' pixels'); }
346
346
  // Commit to storage only on a settled move (pointerup / keyboard), not on
347
347
  // every pointermove frame (that fired dozens of synchronous writes per drag).
348
348
  if (persist) { try { localStorage.setItem('ds.ws.w.' + col, String(next)); } catch (_) {} }
@@ -380,12 +380,12 @@ function WsResizer(col) {
380
380
  const seedNow = (el) => {
381
381
  if (!el) return;
382
382
  const track = el.closest('.ws-shell') && el.closest('.ws-shell').querySelector('.ws-' + col);
383
- if (track) el.setAttribute('aria-valuenow', String(Math.round(track.getBoundingClientRect().width)));
383
+ if (track) { const w = Math.round(track.getBoundingClientRect().width); el.setAttribute('aria-valuenow', String(w)); el.setAttribute('aria-valuetext', w + ' pixels'); }
384
384
  };
385
385
  return h('div', {
386
386
  class: 'ws-resizer ws-resizer-' + col, role: 'separator', tabindex: '0',
387
387
  'aria-orientation': 'vertical', 'aria-label': 'resize ' + col + ' column (arrow keys)',
388
- 'aria-valuemin': String(lo), 'aria-valuemax': String(hi),
388
+ 'aria-valuemin': String(lo), 'aria-valuemax': String(hi), 'aria-valuetext': String(hi) + ' pixels',
389
389
  onpointerdown: onDown, onkeydown: onKey, ref: seedNow,
390
390
  });
391
391
  }
@@ -492,7 +492,7 @@ export function WorkspaceShell({ rail, sessions, main, pane, crumb, status, narr
492
492
  // (any button click inside) auto-closes it, mirroring AppShell.
493
493
  hasSessions
494
494
  ? h('div', { class: 'ws-sessions', role: 'complementary', 'aria-label': 'conversations',
495
- onclick: (e) => { if (narrow && e.target.closest('button, a')) closeWsDrawers(); } }, sessions)
495
+ onclick: (e) => { if (narrow && e.target.closest('button, a, [role="button"]')) closeWsDrawers(); } }, sessions)
496
496
  : null,
497
497
  // Primary content column, with an optional thin crumb bar on top. On
498
498
  // mobile the crumb hosts the drawer toggles (sessions on the left, pane
@@ -135,7 +135,7 @@ export function VoiceSettingsModal({ open = false, mode = 'ptt', inputId, output
135
135
  h('div', { class: 'vx-modal', role: 'dialog', 'aria-modal': 'true', 'aria-label': 'Voice settings' },
136
136
  h('div', { class: 'vx-modal-head' },
137
137
  h('h2', { class: 'vx-modal-title' }, 'Voice settings'),
138
- h('button', { type: 'button', class: 'vx-modal-x', 'aria-label': 'close', onclick: () => onClose && onClose() }, '×')
138
+ h('button', { type: 'button', class: 'vx-modal-x', 'aria-label': 'close', onclick: () => onClose && onClose() }, Icon('x'))
139
139
  ),
140
140
  h('div', { class: 'vx-modal-body' },
141
141
  seg({ label: 'Mode', children: