anentrypoint-design 0.0.356 → 0.0.358

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.356",
3
+ "version": "0.0.358",
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",
@@ -70,6 +70,20 @@ export function BarRow({ label, value, pct = 0, tone } = {}) {
70
70
  h('span', { class: 'ds-bar-row-value', 'aria-hidden': 'true' }, value));
71
71
  }
72
72
 
73
+ // ---------------------------------------------------------------------------
74
+ // RateCell — a tone-colored numeric cell for dense admin/observability tables
75
+ // (percentile latency columns, success-rate columns). Ported from docstudio's
76
+ // admin-observability-views.js endpointsView() success-rate coloring, which
77
+ // had no kit equivalent: a plain Table cell has no notion of a value implying
78
+ // good/warn/bad. Host computes the tone (this component has no opinion on
79
+ // thresholds, matching Table's onSort host-owns-logic convention) and passes
80
+ // it plus the display text; renders inline so it drops into any Table row.
81
+ // ---------------------------------------------------------------------------
82
+ export function RateCell({ value, tone = 'neutral' } = {}) {
83
+ const cls = 'ds-rate-cell ds-rate-cell-' + tone;
84
+ return h('span', { class: cls }, value == null ? '–' : String(value));
85
+ }
86
+
73
87
  // ---------------------------------------------------------------------------
74
88
  // StatTile / StatsGrid — compact KPI tiles, denser than the existing .kpi.
75
89
  // cls on StatTile selects an accent variant: '' | 'rate-big' | 'err-rate'.
@@ -0,0 +1,78 @@
1
+ // SpreadsheetPreview — tabbed inline spreadsheet/CSV viewer, ported from
2
+ // docstudio's documents/xls-preview.js. The kit does no parsing (no SheetJS
3
+ // dependency): the host hands over an already-parsed `workbook` shape and
4
+ // this component only renders tabs + a table + loading/error/truncation
5
+ // states, reusing the existing Skeleton/Alert primitives rather than
6
+ // inventing new visual language.
7
+
8
+ import * as webjsx from '../../vendor/webjsx/index.js';
9
+ import { Skeleton, Alert } from './content.js';
10
+ const h = webjsx.createElement;
11
+
12
+ const DEFAULT_MAX_ROWS = 500;
13
+ const DEFAULT_MAX_COLS = 80;
14
+
15
+ // workbook: { sheetNames: string[], sheets: { [name]: string[][] } }
16
+ export function SpreadsheetPreview({
17
+ workbook, activeSheet, onSheetChange,
18
+ maxRows = DEFAULT_MAX_ROWS, maxCols = DEFAULT_MAX_COLS,
19
+ truncated, loading, error, errorActionLabel = 'retry', onErrorAction,
20
+ key,
21
+ } = {}) {
22
+ if (loading) {
23
+ return h('div', { key, class: 'ds-sheet-preview is-loading' },
24
+ Skeleton({ height: '1.8em', width: '40%', label: 'loading spreadsheet' }),
25
+ Skeleton({ height: '14em', width: '100%' }));
26
+ }
27
+
28
+ if (error) {
29
+ return h('div', { key, class: 'ds-sheet-preview is-error' },
30
+ Alert({
31
+ kind: 'error',
32
+ title: 'could not preview this file',
33
+ children: [String(error)],
34
+ }),
35
+ onErrorAction ? h('button', {
36
+ type: 'button', class: 'ds-sheet-preview-error-action', onclick: onErrorAction,
37
+ }, errorActionLabel) : null);
38
+ }
39
+
40
+ const sheetNames = (workbook && workbook.sheetNames) || [];
41
+ if (!sheetNames.length) {
42
+ return h('div', { key, class: 'ds-sheet-preview is-empty' }, 'no sheets found');
43
+ }
44
+
45
+ const active = activeSheet && sheetNames.includes(activeSheet) ? activeSheet : sheetNames[0];
46
+ const rowsRaw = (workbook.sheets && workbook.sheets[active]) || [];
47
+
48
+ const rowOverflow = rowsRaw.length > maxRows;
49
+ const rows = rowsRaw.slice(0, maxRows);
50
+ const colOverflow = rows.some((r) => Array.isArray(r) && r.length > maxCols);
51
+ const clampedRows = rows.map((r) => (Array.isArray(r) ? r.slice(0, maxCols) : r));
52
+ const isTruncated = truncated || rowOverflow || colOverflow;
53
+
54
+ const isNumeric = (v) => v !== '' && v != null && !isNaN(Number(v));
55
+
56
+ return h('div', { key, class: 'ds-sheet-preview' },
57
+ sheetNames.length > 1 ? h('div', {
58
+ class: 'ds-sheet-preview-tabbar', role: 'tablist', 'aria-label': 'sheets',
59
+ }, ...sheetNames.map((name) => h('button', {
60
+ key: name, type: 'button', role: 'tab',
61
+ 'aria-selected': name === active ? 'true' : 'false',
62
+ tabindex: name === active ? '0' : '-1',
63
+ class: 'ds-sheet-preview-tab' + (name === active ? ' is-active' : ''),
64
+ onclick: () => onSheetChange && onSheetChange(name),
65
+ }, name))) : null,
66
+ isTruncated ? h('div', { class: 'ds-sheet-preview-truncated', role: 'status' },
67
+ 'showing first ' + clampedRows.length + ' rows' + (colOverflow ? ' (columns truncated)' : '') + ' — full file has more data') : null,
68
+ h('div', { class: 'ds-sheet-preview-body' },
69
+ clampedRows.length === 0
70
+ ? h('div', { class: 'ds-sheet-preview-empty' }, 'empty sheet')
71
+ : h('table', { class: 'ds-sheet-preview-table' },
72
+ h('thead', {}, h('tr', {},
73
+ ...(clampedRows[0] || []).map((cell, i) => h('th', { key: i, scope: 'col' }, cell == null ? '' : String(cell))))),
74
+ h('tbody', {}, ...clampedRows.slice(1).map((row, ri) => h('tr', { key: ri },
75
+ ...row.map((cell, ci) => h('td', {
76
+ key: ci, class: isNumeric(cell) ? 'num' : null,
77
+ }, cell == null ? '' : String(cell)))))))));
78
+ }
package/src/components.js CHANGED
@@ -33,6 +33,13 @@ export {
33
33
 
34
34
  export { ContextPane } from './components/context-pane.js';
35
35
 
36
+ export { SpreadsheetPreview } from './components/spreadsheet-preview.js';
37
+
38
+ export {
39
+ DEFAULT_PHASES, PhaseWalk, TreeNode, BarRow, RateCell,
40
+ StatTile, StatsGrid, SubGrid, SessionRow, DevRow, LiveLogEntry, LiveLog
41
+ } from './components/data-density.js';
42
+
36
43
  export {
37
44
  fileGlyph, fmtFileSize,
38
45
  FileIcon, FileRow, FileGrid, FileSkeleton, sortFiles, FileToolbar, RootsPicker,
@@ -77,6 +77,16 @@
77
77
  .ds-stat-val.err-rate { font-size: clamp(24px, 7cqi, 32px); color: var(--warn); }
78
78
  .ds-stat-lbl { font-size: var(--fs-micro); color: var(--fg-3); margin-top: 2px; }
79
79
 
80
+ /* RateCell — tone-colored numeric table cell (success-rate / percentile-latency
81
+ columns), ported from docstudio's endpointsView() success-rate coloring.
82
+ Neutral at rest; color carries meaning only, matching Table's sortable-header
83
+ restraint pattern. */
84
+ .ds-rate-cell { font-variant-numeric: tabular-nums; font-weight: 600; }
85
+ .ds-rate-cell-neutral { color: var(--fg-2); font-weight: 400; }
86
+ .ds-rate-cell-good { color: var(--success); }
87
+ .ds-rate-cell-warn { color: var(--warn); }
88
+ .ds-rate-cell-bad { color: var(--danger); }
89
+
80
90
  /* Inline row — flex row with centered items and a small gap, for demo/kit
81
91
  markup that needs to lay siblings out horizontally without an inline style. */
82
92
  .ds-inline-row { display: flex; align-items: center; gap: var(--space-2, 8px); }
@@ -385,3 +385,46 @@
385
385
  .ds-avatar-sm { width: 24px; height: 24px; font-size: 10px; }
386
386
  .ds-avatar-md { width: 36px; height: 36px; font-size: 12px; }
387
387
  .ds-avatar-lg { width: 48px; height: 48px; font-size: 15px; }
388
+
389
+ /* SpreadsheetPreview — tabbed inline spreadsheet/CSV viewer (docstudio
390
+ xls-preview.js port). Tabs reuse the same neutral-at-rest pattern as
391
+ Table's sortable headers; the truncation banner is persistent and never
392
+ hides the table underneath. */
393
+ .ds-sheet-preview { display: flex; flex-direction: column; gap: var(--space-2, 8px); min-width: 0; }
394
+ .ds-sheet-preview-tabbar {
395
+ display: flex; gap: var(--space-1, 4px); overflow-x: auto; -webkit-overflow-scrolling: touch;
396
+ border-bottom: 1px solid var(--border, var(--bg-3));
397
+ }
398
+ .ds-sheet-preview-tab {
399
+ flex-shrink: 0; background: none; border: none; cursor: pointer;
400
+ padding: var(--space-1-5, 5px) var(--space-2-5, 10px);
401
+ font: inherit; color: var(--fg-3); border-bottom: 2px solid transparent;
402
+ }
403
+ .ds-sheet-preview-tab:hover { color: var(--fg); }
404
+ .ds-sheet-preview-tab:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: -2px; }
405
+ .ds-sheet-preview-tab.is-active { color: var(--fg); border-bottom-color: var(--accent-ink, var(--accent)); }
406
+ .ds-sheet-preview-truncated {
407
+ font-size: var(--fs-tiny, 12px); color: var(--fg-3);
408
+ padding: var(--space-1, 4px) var(--space-2, 8px);
409
+ background: var(--bg-2); border-radius: var(--r-1, 6px);
410
+ }
411
+ .ds-sheet-preview-body { overflow: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
412
+ .ds-sheet-preview-table { min-width: 100%; border-collapse: collapse; font-size: var(--fs-sm, 13px); }
413
+ .ds-sheet-preview-table th, .ds-sheet-preview-table td {
414
+ padding: var(--space-1-5, 5px) var(--space-2, 8px);
415
+ border-bottom: 1px solid var(--border, var(--bg-3));
416
+ text-align: left; white-space: nowrap;
417
+ }
418
+ .ds-sheet-preview-table thead th {
419
+ position: sticky; top: 0; background: var(--bg-2); color: var(--fg-3);
420
+ font-weight: 600; z-index: 1;
421
+ }
422
+ .ds-sheet-preview-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
423
+ .ds-sheet-preview-empty { padding: var(--space-3, 16px); color: var(--fg-3); }
424
+ .ds-sheet-preview-error-action {
425
+ align-self: flex-start; background: none; border: 1px solid var(--border, var(--bg-3));
426
+ border-radius: var(--r-1, 6px); padding: var(--space-1, 4px) var(--space-2-5, 10px);
427
+ font: inherit; color: var(--fg); cursor: pointer;
428
+ }
429
+ .ds-sheet-preview-error-action:hover { background: var(--bg-2); }
430
+ .ds-sheet-preview-error-action:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: 2px; }