anentrypoint-design 0.0.356 → 0.0.357
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/dist/247420.css +43 -0
- package/dist/247420.js +25 -25
- package/package.json +1 -1
- package/src/components/spreadsheet-preview.js +78 -0
- package/src/components.js +2 -0
- package/src/css/app-shell/kits-appended.css +43 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anentrypoint-design",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.357",
|
|
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",
|
|
@@ -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,8 @@ export {
|
|
|
33
33
|
|
|
34
34
|
export { ContextPane } from './components/context-pane.js';
|
|
35
35
|
|
|
36
|
+
export { SpreadsheetPreview } from './components/spreadsheet-preview.js';
|
|
37
|
+
|
|
36
38
|
export {
|
|
37
39
|
fileGlyph, fmtFileSize,
|
|
38
40
|
FileIcon, FileRow, FileGrid, FileSkeleton, sortFiles, FileToolbar, RootsPicker,
|
|
@@ -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; }
|