bo-grid 0.7.0 → 0.8.0
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/README.md +34 -8
- package/dist/grid/Cell.svelte +2 -2
- package/dist/grid/Grid.svelte +31 -2
- package/dist/grid/theme.d.ts +10 -0
- package/dist/grid/theme.js +6 -0
- package/dist/sparkline/Sparkline.svelte +8 -2
- package/dist/sparkline/sparkline-render.d.ts +4 -1
- package/dist/sparkline/sparkline-render.js +5 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,14 +16,16 @@ matrix, a **Leaderboard** with rank medals and score bars, a **Tree** file
|
|
|
16
16
|
explorer, a drag-to-reorder **Tasks** list, and a **1M-row** trade tape windowed
|
|
17
17
|
from a synthetic source — switch between them with the tabs.
|
|
18
18
|
|
|
19
|
-
> **Status:
|
|
20
|
-
> single/multi/controlled
|
|
21
|
-
>
|
|
22
|
-
>
|
|
23
|
-
>
|
|
24
|
-
>
|
|
25
|
-
>
|
|
26
|
-
>
|
|
19
|
+
> **Status: actively developed.** Working: config-driven columns, virtual scroll,
|
|
20
|
+
> sort (single / multi / controlled), filtering (global, per-column row, header
|
|
21
|
+
> filter menus with set / number / date filters, quick search, controlled +
|
|
22
|
+
> server-side), multi-cell selection + live aggregation, grouping (nested, sticky,
|
|
23
|
+
> subtotals), pivot, tree data, master-detail, a server-side `RowSource` for huge
|
|
24
|
+
> datasets, CSV/Excel export, column management (reorder, resize, pin L/R, hide,
|
|
25
|
+
> autosize, tool panel, column menu), spreadsheet editing (inline + typed editors,
|
|
26
|
+
> validation, copy/paste, fill handle, undo/redo), row selection, pagination,
|
|
27
|
+
> sparklines, realtime flash, heatmaps, theming, and full keyboard a11y.
|
|
28
|
+
> **SSR/SvelteKit-safe.**
|
|
27
29
|
> Unit tests (Vitest), type-check, a headless mount smoke-test, an SSR render
|
|
28
30
|
> check, and library + demo bundle-size budgets all run in CI. A formal WCAG audit
|
|
29
31
|
> is the main thing left — see the roadmap.
|
|
@@ -290,6 +292,30 @@ these:
|
|
|
290
292
|
}
|
|
291
293
|
```
|
|
292
294
|
|
|
295
|
+
Native form controls (checkboxes, date pickers, number spinners, search inputs,
|
|
296
|
+
scrollbars) follow the theme automatically via `color-scheme` + `accent-color`.
|
|
297
|
+
A custom theme defaults to dark; set `scheme: 'light'` (or `--bo-grid-scheme:
|
|
298
|
+
light`) for a light one.
|
|
299
|
+
|
|
300
|
+
**Tokens** cover colour, typography (`mono`/`sans`/`fontSize`), shape (`radius`),
|
|
301
|
+
and density (`cellPad`, plus the `rowHeight` prop) — so the whole look is yours.
|
|
302
|
+
Numeric columns use tabular figures so digits line up. A few looks:
|
|
303
|
+
|
|
304
|
+
```svelte
|
|
305
|
+
<!-- Compact / dense -->
|
|
306
|
+
<Grid {rows} {columns} rowHeight={28}
|
|
307
|
+
theme={{ fontSize: '12px', cellPad: '6px' }} height={640} />
|
|
308
|
+
|
|
309
|
+
<!-- Roomy & rounded -->
|
|
310
|
+
<Grid {rows} {columns} rowHeight={44}
|
|
311
|
+
theme={{ radius: '16px', cellPad: '16px', fontSize: '14px' }} height={640} />
|
|
312
|
+
|
|
313
|
+
<!-- Branded -->
|
|
314
|
+
<Grid {rows} {columns}
|
|
315
|
+
theme={{ bg: '#0b1020', headerBg: '#0d1226', up: '#22d3ee', down: '#fb7185',
|
|
316
|
+
selBorder: '#22d3ee', radius: '12px' }} height={640} />
|
|
317
|
+
```
|
|
318
|
+
|
|
293
319
|
## Server-side / large datasets
|
|
294
320
|
|
|
295
321
|
Instead of an in-memory `rows` array, back the grid with a **`RowSource`** — the
|
package/dist/grid/Cell.svelte
CHANGED
|
@@ -251,9 +251,9 @@
|
|
|
251
251
|
position: relative;
|
|
252
252
|
display: flex;
|
|
253
253
|
align-items: center;
|
|
254
|
-
padding: 0 8px;
|
|
254
|
+
padding: 0 var(--bo-cell-pad, 8px);
|
|
255
255
|
height: 100%;
|
|
256
|
-
font-size: 13px;
|
|
256
|
+
font-size: var(--bo-font-size, 13px);
|
|
257
257
|
line-height: 1.4;
|
|
258
258
|
overflow: hidden;
|
|
259
259
|
white-space: nowrap;
|
package/dist/grid/Grid.svelte
CHANGED
|
@@ -1803,6 +1803,15 @@
|
|
|
1803
1803
|
--bo-header-h: var(--bo-grid-header-h, 28px);
|
|
1804
1804
|
--bo-mono: var(--bo-grid-mono, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace);
|
|
1805
1805
|
--bo-sans: var(--bo-grid-sans, Inter, "Segoe UI", system-ui, sans-serif);
|
|
1806
|
+
/* Layout/density tokens (override via --bo-grid-* for a custom look). */
|
|
1807
|
+
--bo-radius: var(--bo-grid-radius, 8px);
|
|
1808
|
+
--bo-font-size: var(--bo-grid-font-size, 13px);
|
|
1809
|
+
--bo-cell-pad: var(--bo-grid-cell-pad, 8px);
|
|
1810
|
+
|
|
1811
|
+
/* Theme native controls (checkboxes, date pickers, number spinners, search
|
|
1812
|
+
clear buttons, scrollbars) and accent fills to match the grid theme. */
|
|
1813
|
+
color-scheme: var(--bo-grid-scheme, dark);
|
|
1814
|
+
accent-color: var(--bo-up);
|
|
1806
1815
|
|
|
1807
1816
|
display: flex;
|
|
1808
1817
|
flex-direction: column;
|
|
@@ -1810,7 +1819,7 @@
|
|
|
1810
1819
|
font-family: var(--bo-sans);
|
|
1811
1820
|
background: var(--bo-bg);
|
|
1812
1821
|
border: 0.5px solid var(--bo-border);
|
|
1813
|
-
border-radius:
|
|
1822
|
+
border-radius: var(--bo-radius);
|
|
1814
1823
|
overflow: hidden;
|
|
1815
1824
|
outline: none;
|
|
1816
1825
|
}
|
|
@@ -1893,7 +1902,7 @@
|
|
|
1893
1902
|
display: flex;
|
|
1894
1903
|
align-items: center;
|
|
1895
1904
|
gap: 4px;
|
|
1896
|
-
padding: 0 8px;
|
|
1905
|
+
padding: 0 var(--bo-cell-pad, 8px);
|
|
1897
1906
|
min-width: 0;
|
|
1898
1907
|
font: inherit;
|
|
1899
1908
|
font-size: 11px;
|
|
@@ -2037,6 +2046,26 @@
|
|
|
2037
2046
|
overflow-y: auto;
|
|
2038
2047
|
overflow-x: hidden;
|
|
2039
2048
|
user-select: none;
|
|
2049
|
+
/* Thin, themed scrollbars (Firefox) — Chromium/Safari below. */
|
|
2050
|
+
scrollbar-width: thin;
|
|
2051
|
+
scrollbar-color: color-mix(in srgb, var(--bo-text-dim) 55%, transparent) transparent;
|
|
2052
|
+
}
|
|
2053
|
+
.viewport::-webkit-scrollbar {
|
|
2054
|
+
width: 10px;
|
|
2055
|
+
height: 10px;
|
|
2056
|
+
}
|
|
2057
|
+
.viewport::-webkit-scrollbar-thumb {
|
|
2058
|
+
background: color-mix(in srgb, var(--bo-text-dim) 45%, transparent);
|
|
2059
|
+
border: 2px solid transparent;
|
|
2060
|
+
background-clip: padding-box;
|
|
2061
|
+
border-radius: 6px;
|
|
2062
|
+
}
|
|
2063
|
+
.viewport::-webkit-scrollbar-thumb:hover {
|
|
2064
|
+
background: color-mix(in srgb, var(--bo-text-dim) 70%, transparent);
|
|
2065
|
+
background-clip: padding-box;
|
|
2066
|
+
}
|
|
2067
|
+
.viewport::-webkit-scrollbar-corner {
|
|
2068
|
+
background: transparent;
|
|
2040
2069
|
}
|
|
2041
2070
|
.empty {
|
|
2042
2071
|
position: absolute;
|
package/dist/grid/theme.d.ts
CHANGED
|
@@ -20,6 +20,16 @@ export interface GridTheme {
|
|
|
20
20
|
headerH?: string;
|
|
21
21
|
mono?: string;
|
|
22
22
|
sans?: string;
|
|
23
|
+
/** Native-control color scheme: themes checkboxes, date pickers, number
|
|
24
|
+
spinners, search-clear buttons and scrollbars. Defaults to dark. */
|
|
25
|
+
scheme?: 'light' | 'dark';
|
|
26
|
+
/** Outer corner radius (e.g. '8px', '0', '14px'). Default 8px. */
|
|
27
|
+
radius?: string;
|
|
28
|
+
/** Cell/row font size (e.g. '13px', '12px'). Default 13px. */
|
|
29
|
+
fontSize?: string;
|
|
30
|
+
/** Horizontal cell padding — the main density lever (e.g. '8px', '12px').
|
|
31
|
+
Pair with `rowHeight` for a fully compact or roomy look. Default 8px. */
|
|
32
|
+
cellPad?: string;
|
|
23
33
|
}
|
|
24
34
|
/** Serialize a theme to a CSS `--bo-grid-*: …;` declaration string. */
|
|
25
35
|
export declare function themeVars(theme: GridTheme): string;
|
package/dist/grid/theme.js
CHANGED
|
@@ -15,6 +15,10 @@ const VARS = {
|
|
|
15
15
|
headerH: '--bo-grid-header-h',
|
|
16
16
|
mono: '--bo-grid-mono',
|
|
17
17
|
sans: '--bo-grid-sans',
|
|
18
|
+
scheme: '--bo-grid-scheme',
|
|
19
|
+
radius: '--bo-grid-radius',
|
|
20
|
+
fontSize: '--bo-grid-font-size',
|
|
21
|
+
cellPad: '--bo-grid-cell-pad',
|
|
18
22
|
};
|
|
19
23
|
/** Serialize a theme to a CSS `--bo-grid-*: …;` declaration string. */
|
|
20
24
|
export function themeVars(theme) {
|
|
@@ -40,6 +44,7 @@ export const darkTheme = {
|
|
|
40
44
|
amber: '#f59e0b',
|
|
41
45
|
selFill: 'rgba(99,102,241,0.16)',
|
|
42
46
|
selBorder: '#6366f1',
|
|
47
|
+
scheme: 'dark',
|
|
43
48
|
};
|
|
44
49
|
// A deliberate light palette (not an inverted dark one): near-white surfaces,
|
|
45
50
|
// stronger green/red for contrast on light, subtle borders.
|
|
@@ -57,4 +62,5 @@ export const lightTheme = {
|
|
|
57
62
|
amber: '#d97706',
|
|
58
63
|
selFill: 'rgba(99,102,241,0.12)',
|
|
59
64
|
selBorder: '#6366f1',
|
|
65
|
+
scheme: 'light',
|
|
60
66
|
};
|
|
@@ -16,7 +16,13 @@
|
|
|
16
16
|
// sparklines run this, so the realtime feed never repaints off-screen charts.
|
|
17
17
|
$effect(() => {
|
|
18
18
|
const ctx = setupHiDpiCanvas(canvas, width, height);
|
|
19
|
-
|
|
19
|
+
// Pull the grid's up/down colors so candles follow the active theme
|
|
20
|
+
// (inherited --bo-up/--bo-down; falls back to the built-in defaults).
|
|
21
|
+
const cs = getComputedStyle(canvas);
|
|
22
|
+
drawCandles(ctx, candles, width, height, {
|
|
23
|
+
up: cs.getPropertyValue('--bo-up').trim() || undefined,
|
|
24
|
+
down: cs.getPropertyValue('--bo-down').trim() || undefined,
|
|
25
|
+
});
|
|
20
26
|
});
|
|
21
27
|
|
|
22
28
|
const label = $derived(summarize(candles));
|
|
@@ -66,7 +72,7 @@
|
|
|
66
72
|
font-family: var(--bo-mono, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace);
|
|
67
73
|
font-size: 10px;
|
|
68
74
|
color: var(--bo-text, #e5e5e5);
|
|
69
|
-
background: #
|
|
75
|
+
background: var(--bo-header-bg, #0f0f0f);
|
|
70
76
|
border: 0.5px solid var(--bo-border, rgba(255, 255, 255, 0.12));
|
|
71
77
|
border-radius: 4px;
|
|
72
78
|
pointer-events: none;
|
|
@@ -9,7 +9,10 @@ export declare function setupHiDpiCanvas(canvas: HTMLCanvasElement, cssW: number
|
|
|
9
9
|
* Draw compact candlesticks. Body shows open→close, wick shows low→high.
|
|
10
10
|
* Color by per-candle direction. Canvas (not SVG) so 100+ of these stay cheap.
|
|
11
11
|
*/
|
|
12
|
-
export declare function drawCandles(ctx: CanvasRenderingContext2D, candles: Candle[], w: number, h: number
|
|
12
|
+
export declare function drawCandles(ctx: CanvasRenderingContext2D, candles: Candle[], w: number, h: number, colors?: {
|
|
13
|
+
up?: string;
|
|
14
|
+
down?: string;
|
|
15
|
+
}): void;
|
|
13
16
|
/** Screen-reader text — canvas alone is invisible to AT, so we narrate trend. */
|
|
14
17
|
export declare function summarize(candles: Candle[]): string;
|
|
15
18
|
/** Which candle index sits under an x offset (for hover tooltips). */
|
|
@@ -37,10 +37,12 @@ function yOf(price, ext, h, pad) {
|
|
|
37
37
|
* Draw compact candlesticks. Body shows open→close, wick shows low→high.
|
|
38
38
|
* Color by per-candle direction. Canvas (not SVG) so 100+ of these stay cheap.
|
|
39
39
|
*/
|
|
40
|
-
export function drawCandles(ctx, candles, w, h) {
|
|
40
|
+
export function drawCandles(ctx, candles, w, h, colors = {}) {
|
|
41
41
|
ctx.clearRect(0, 0, w, h);
|
|
42
42
|
if (candles.length === 0)
|
|
43
43
|
return;
|
|
44
|
+
const upColor = colors.up || UP;
|
|
45
|
+
const downColor = colors.down || DOWN;
|
|
44
46
|
const ext = priceExtent(candles);
|
|
45
47
|
const pad = 2;
|
|
46
48
|
const n = candles.length;
|
|
@@ -50,8 +52,8 @@ export function drawCandles(ctx, candles, w, h) {
|
|
|
50
52
|
const c = candles[i];
|
|
51
53
|
const cx = i * slot + slot / 2;
|
|
52
54
|
const up = c.close >= c.open;
|
|
53
|
-
ctx.strokeStyle = up ?
|
|
54
|
-
ctx.fillStyle = up ?
|
|
55
|
+
ctx.strokeStyle = up ? upColor : downColor;
|
|
56
|
+
ctx.fillStyle = up ? upColor : downColor;
|
|
55
57
|
// wick
|
|
56
58
|
ctx.beginPath();
|
|
57
59
|
ctx.moveTo(Math.round(cx) + 0.5, yOf(c.high, ext, h, pad));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bo-grid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Tiny, fast Svelte 5 data grid: canvas sparklines, batched realtime cell updates, and virtual scrolling. A free, fintech-focused alternative to heavyweight grids.",
|