@dcs-tech/ui 0.6.0 → 0.7.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 +27 -0
- package/dist/{ChartImageMenu-CuuFnW9q.js → ChartImageMenu-C6MwKKjc.js} +39 -26
- package/dist/{SummaryImage-CoEFzMl6.js → SummaryImage-OHJHjCqe.js} +1 -1
- package/dist/{SummarySeeAll-C_OUs3kn.js → SummarySeeAll-BYrvXSJ6.js} +1 -1
- package/dist/assets/fileTask.worker-BHT1olUk.js +1 -0
- package/dist/{exportEngine-CDLYHH0d.js → exportEngine-S8JHzYbS.js} +377 -382
- package/dist/file-worker.js +1 -0
- package/dist/{fileActions-KSaVGnaE.js → fileActions-COf5Q4Eg.js} +2 -2
- package/dist/index.js +4000 -3916
- package/dist/runFileTask--4YjQH7Y.js +210 -0
- package/dist/types/components/DataTable/export/exportEngine.d.ts +11 -4
- package/dist/types/components/Dialog/DialogHost.d.ts +1 -0
- package/dist/types/components/FileEngine/FileEngineProvider.d.ts +20 -1
- package/dist/types/components/FileEngine/index.d.ts +1 -1
- package/dist/types/components/UIProvider/UIHostContext.d.ts +20 -0
- package/dist/types/components/UIProvider/UIProvider.d.ts +2 -0
- package/dist/types/components/UIProvider/index.d.ts +2 -0
- package/dist/types/core/types/fileEngine.types.d.ts +51 -0
- package/dist/types/core/types/form.types.d.ts +4 -0
- package/dist/types/file/fileEngine.d.ts +2 -1
- package/dist/types/file/tasks/runFileTask.d.ts +4 -1
- package/dist/types/file/workerPool.d.ts +1 -0
- package/dist/types/index.d.ts +6 -4
- package/package.json +3 -2
- package/dist/assets/fileTask.worker-FQSUtwcz.js +0 -1
- package/dist/runFileTask-BClLQjmv.js +0 -109
package/README.md
CHANGED
|
@@ -69,6 +69,33 @@ The table's runtime dependencies (`@tanstack/react-table`, `@tanstack/react-virt
|
|
|
69
69
|
`@tanstack/match-sorter-utils`, `exceljs`, `pdfmake` — loaded on the first PDF export —
|
|
70
70
|
and `react-icons`) install with the package.
|
|
71
71
|
|
|
72
|
+
## Files and the background worker
|
|
73
|
+
|
|
74
|
+
Exports (DataTable, chart images, your own reports) run through one file engine that
|
|
75
|
+
`UIProvider` sets up. Excel and PDF files build in a **background worker**, so a large
|
|
76
|
+
export does not freeze the page.
|
|
77
|
+
|
|
78
|
+
The worker ships as its own file and imports `exceljs` and `pdfmake` by package name, so
|
|
79
|
+
**your bundler must treat it as a worker entry**:
|
|
80
|
+
|
|
81
|
+
- **Vite** and **webpack 5**: nothing to do. They follow the package's
|
|
82
|
+
`new Worker(new URL(…, import.meta.url))` and bundle the worker themselves.
|
|
83
|
+
- **Anything else**: build a worker from `@dcs-tech/ui/file-worker` with your bundler and hand it
|
|
84
|
+
to the engine:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
// file.worker.ts — bundled by your setup as a module worker
|
|
88
|
+
import '@dcs-tech/ui/file-worker';
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
<UIProvider fileEngine={{ createWorker: () => new Worker('/assets/file.worker.js', { type: 'module' }) }}>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
If a worker cannot start, the engine builds the same file on the main thread instead.
|
|
96
|
+
`fileEngine={{ workers: 'off' }}` always uses the main thread. Large PDF fonts (a script font)
|
|
97
|
+
belong on the engine, so they reach each worker once: `fileEngine={{ pdfFonts: { fonts, vfs } }}`.
|
|
98
|
+
|
|
72
99
|
## Theming
|
|
73
100
|
|
|
74
101
|
Every colour, size and spacing value is a CSS custom property. Override them on
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { A as e, C as t, Cn as n, Dn as r, E as i, En as a, F as o, J as s, L as c, N as l, Nn as u, O as d, P as f, Q as p, R as m, S as h, T as g, Tn as _, Y as v, _ as y, b, c as x, d as S, et as C, ft as w, g as T, h as ee, i as te, j as ne, kn as re, l as ie, r as ae, rt as oe, st as E, ut as se, w as ce, y as le } from "./geometry-ChwYB45B.js";
|
|
3
|
-
import { a as ue,
|
|
4
|
-
import { t as he } from "./runFileTask
|
|
3
|
+
import { a as ue, l as de, n as fe, o as pe, u as me } from "./fileActions-COf5Q4Eg.js";
|
|
4
|
+
import { t as he } from "./runFileTask--4YjQH7Y.js";
|
|
5
5
|
import ge, { cloneElement as _e, createContext as ve, forwardRef as ye, useCallback as D, useContext as be, useEffect as O, useId as xe, useLayoutEffect as Se, useMemo as Ce, useRef as k, useState as A, useSyncExternalStore as we } from "react";
|
|
6
6
|
import { Fragment as Te, jsx as j, jsxs as M } from "react/jsx-runtime";
|
|
7
7
|
import { createPortal as Ee } from "react-dom";
|
|
@@ -505,25 +505,28 @@ var B = class extends Error {
|
|
|
505
505
|
}
|
|
506
506
|
};
|
|
507
507
|
function it(e) {
|
|
508
|
-
let t = [], n = /* @__PURE__ */ new Set(), r = !1, i = 0, a = (
|
|
508
|
+
let t = [], n = /* @__PURE__ */ new Set(), r = !1, i = 0, a = () => {
|
|
509
|
+
let t = e.create();
|
|
510
|
+
return e.init !== void 0 && t.postMessage(e.init), {
|
|
511
|
+
worker: t,
|
|
512
|
+
started: !1
|
|
513
|
+
};
|
|
514
|
+
}, o = (r) => {
|
|
509
515
|
n.delete(r), t.length < e.size ? t.push(r) : r.worker.terminate();
|
|
510
|
-
},
|
|
516
|
+
}, s = (e) => {
|
|
511
517
|
n.delete(e), e.worker.terminate();
|
|
512
518
|
};
|
|
513
519
|
return {
|
|
514
520
|
get broken() {
|
|
515
521
|
return r;
|
|
516
522
|
},
|
|
517
|
-
run(
|
|
523
|
+
run(e, { signal: c, progress: l }) {
|
|
518
524
|
return new Promise((u, d) => {
|
|
519
525
|
if (r) return d(new B("unavailable", "Workers are unavailable"));
|
|
520
526
|
if (c.aborted) return d(new DOMException("Aborted", "AbortError"));
|
|
521
527
|
let f;
|
|
522
528
|
try {
|
|
523
|
-
f = t.pop() ??
|
|
524
|
-
worker: e.create(),
|
|
525
|
-
started: !1
|
|
526
|
-
};
|
|
529
|
+
f = t.pop() ?? a();
|
|
527
530
|
} catch (e) {
|
|
528
531
|
return r = !0, d(new B("unavailable", `Worker could not be created: ${String(e)}`));
|
|
529
532
|
}
|
|
@@ -534,24 +537,24 @@ function it(e) {
|
|
|
534
537
|
let t = e.data;
|
|
535
538
|
if (t && t.id === p) {
|
|
536
539
|
if (f.started = !0, t.type === "progress") return l(t.fraction);
|
|
537
|
-
m(),
|
|
540
|
+
m(), o(f), t.type === "done" ? u(t.buffer) : d(Error(t.message));
|
|
538
541
|
}
|
|
539
542
|
}, g = (e) => {
|
|
540
|
-
e.preventDefault?.(), m(),
|
|
543
|
+
e.preventDefault?.(), m(), s(f), f.started ? d(Error(e.message || "The file worker stopped unexpectedly")) : (r = !0, d(new B("unavailable", e.message || "The file worker failed to start")));
|
|
541
544
|
}, _ = () => {
|
|
542
|
-
m(),
|
|
545
|
+
m(), s(f), d(/* @__PURE__ */ Error("The file worker sent a message that could not be read"));
|
|
543
546
|
}, v = () => {
|
|
544
|
-
m(),
|
|
547
|
+
m(), s(f), d(c.reason ?? new DOMException("Aborted", "AbortError"));
|
|
545
548
|
};
|
|
546
549
|
f.worker.addEventListener("message", h), f.worker.addEventListener("error", g), f.worker.addEventListener("messageerror", _), c.addEventListener("abort", v);
|
|
547
550
|
try {
|
|
548
551
|
f.worker.postMessage({
|
|
549
552
|
type: "run",
|
|
550
553
|
id: p,
|
|
551
|
-
task:
|
|
554
|
+
task: e
|
|
552
555
|
});
|
|
553
556
|
} catch (e) {
|
|
554
|
-
m(),
|
|
557
|
+
m(), o(f), d(new B("uncloneable", e instanceof Error ? e.message : String(e)));
|
|
555
558
|
}
|
|
556
559
|
});
|
|
557
560
|
},
|
|
@@ -566,7 +569,7 @@ var V = class extends Error {
|
|
|
566
569
|
constructor(e, t) {
|
|
567
570
|
super(t), this.name = "FileEngineError", this.code = e;
|
|
568
571
|
}
|
|
569
|
-
}, at = (e, t, n) =>
|
|
572
|
+
}, at = (e, t, n) => ue(e, me(t.filename) + pe(t.format), t.format, n, t.title ?? t.filename), ot = () => typeof navigator > "u" ? void 0 : navigator.userActivation?.isActive, H = (e) => e instanceof Error ? e.message : String(e), st = () => new Worker(new URL("./assets/fileTask.worker-BHT1olUk.js", import.meta.url), { type: "module" }), ct = () => typeof Worker < "u", lt = 0;
|
|
570
573
|
function ut(e = {}) {
|
|
571
574
|
let t = Me(e), n = e.deliver ?? at, r = `file-${++lt}-`, i = [], a = 0, o = !1, s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Set(), d = null, f = t.workers === "auto" && (!!e.createWorker || ct()), p = () => {
|
|
572
575
|
if (!f) return null;
|
|
@@ -574,20 +577,30 @@ function ut(e = {}) {
|
|
|
574
577
|
let n = typeof navigator < "u" && navigator.hardwareConcurrency ? navigator.hardwareConcurrency : t.concurrency;
|
|
575
578
|
d = it({
|
|
576
579
|
size: Math.max(1, Math.min(t.concurrency, n)),
|
|
577
|
-
create: e.createWorker ?? st
|
|
580
|
+
create: e.createWorker ?? st,
|
|
581
|
+
...e.pdfFonts ? { init: {
|
|
582
|
+
type: "init",
|
|
583
|
+
pdfFonts: e.pdfFonts
|
|
584
|
+
} } : {}
|
|
578
585
|
});
|
|
579
586
|
}
|
|
580
587
|
return d;
|
|
581
|
-
}, m = async (
|
|
582
|
-
let
|
|
583
|
-
if (
|
|
584
|
-
|
|
585
|
-
} catch (
|
|
586
|
-
if (!(
|
|
587
|
-
|
|
588
|
+
}, m = async (t, n, r) => {
|
|
589
|
+
let i = p(), a;
|
|
590
|
+
if (i && !i.broken) try {
|
|
591
|
+
a = await i.run(t, r);
|
|
592
|
+
} catch (n) {
|
|
593
|
+
if (!(n instanceof B)) throw n;
|
|
594
|
+
a = await he(t, {
|
|
595
|
+
...r,
|
|
596
|
+
pdfFonts: e.pdfFonts
|
|
597
|
+
});
|
|
588
598
|
}
|
|
589
|
-
else
|
|
590
|
-
|
|
599
|
+
else a = await he(t, {
|
|
600
|
+
...r,
|
|
601
|
+
pdfFonts: e.pdfFonts
|
|
602
|
+
});
|
|
603
|
+
return new Blob([a], { type: fe[n] });
|
|
591
604
|
}, h = (e) => i.find((t) => t.id === e), g = () => u.forEach((e) => e()), _ = (e, t) => {
|
|
592
605
|
i = i.map((n) => n.id === e ? {
|
|
593
606
|
...n,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as e } from "./ChartImageMenu-
|
|
2
|
+
import { t as e } from "./ChartImageMenu-C6MwKKjc.js";
|
|
3
3
|
import { n as t } from "./summaryChartData-pNvzaEHp.js";
|
|
4
4
|
import { jsx as n } from "react/jsx-runtime";
|
|
5
5
|
// src/components/DataTable/summary/SummaryImage.tsx
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as e } from "./ChartImageMenu-
|
|
2
|
+
import { t as e } from "./ChartImageMenu-C6MwKKjc.js";
|
|
3
3
|
import { t } from "./ChartView-nS4f4EU_.js";
|
|
4
4
|
import { J as n, Tt as r, U as i, ot as a } from "./geometry-ChwYB45B.js";
|
|
5
5
|
import { n as o, o as s, s as c } from "./scrollArea-DAlVT5U7.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=()=>new DOMException(`Aborted`,`AbortError`);async function t(t,n){if(n.signal?.aborted)throw e();switch(t.kind){case`xlsx`:return l(t.workbook,n);case`pdf`:return p(t,n);default:throw Error(`Unknown file task: ${t.kind}`)}}const n=globalThis;async function r(){let e=await import(`exceljs`),t=[e.default?.default,e.default,e,n.ExcelJS].find(e=>e&&typeof e.Workbook==`function`);if(!t)throw Error(`ExcelJS did not load`);return t}async function i(){let e=await import(`pdfmake/build/pdfmake.js`),t=[e.default?.default,e.default,e,n.pdfMake].find(e=>e&&typeof e.createPdf==`function`);if(!t)throw Error(`pdfmake did not load`);let r=await import(`pdfmake/build/vfs_fonts.js`);return{pdfMake:t,vfs:[r?.default,r,r?.pdfMake?.vfs,r?.default?.pdfMake?.vfs,t.vfs,n.pdfMake?.vfs].find(e=>e&&e[`Roboto-Regular.ttf`])}}const a=e=>ArrayBuffer.isView(e)?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):e,o=e=>`FF`+e.replace(`#`,``).toUpperCase();function s(e,t){if(t&&((t.bold!==void 0||t.italic!==void 0||t.size||t.color)&&(e.font={...e.font??{},...t.bold===void 0?{}:{bold:t.bold},...t.italic===void 0?{}:{italic:t.italic},...t.size?{size:t.size}:{},...t.color?{color:{argb:o(t.color)}}:{}}),t.fill&&(e.fill={type:`pattern`,pattern:`solid`,fgColor:{argb:o(t.fill)}}),t.align&&(e.alignment={horizontal:t.align,vertical:`middle`}),t.numFmt&&(typeof e.value==`number`||e.value instanceof Date)&&(e.numFmt=t.numFmt),t.borderTop||t.borderBottom)){let n=e=>({style:e.style,...e.color?{color:{argb:o(e.color)}}:{}});e.border={...t.borderTop?{top:n(t.borderTop)}:{},...t.borderBottom?{bottom:n(t.borderBottom)}:{}}}}function c(e,t,n){let r=e.addRow(t.values);t.style?.bold&&(r.font={bold:!0}),t.merge&&n>1&&e.mergeCells(r.number,1,r.number,n);let i=t.merge?1:Math.max(t.values.length,0);for(let e=0;e<i;e++){let n=r.getCell(e+1);s(n,t.style),s(n,t.cells?.[e])}}async function l(t,n){let i=new(await(r())).Workbook,l=Math.max(1,t.sheets.reduce((e,t)=>e+t.rows.length,0)),u=Math.max(1,Math.floor(l/50)),d=0;for(let r of t.sheets){let t=i.addWorksheet(r.name),a=r.columns.length;t.columns=r.columns.map((e,t)=>({key:String(t),width:e.width}));for(let e of r.before??[])c(t,e,a);let f=t.addRow(r.columns.map(e=>e.header));f.font={bold:r.headerStyle?.bold??!0},f.eachCell((e,t)=>{let n=r.columns[t-1]?.align;n&&(e.alignment={horizontal:n,vertical:`middle`}),s(e,r.headerStyle)});let p=f.number;r.freeze?t.views=[{state:`frozen`,ySplit:r.freeze.rows??0,xSplit:r.freeze.cols??0}]:r.freezeHeader!==!1&&(t.views=[{state:`frozen`,ySplit:p}]),r.rows.forEach((i,a)=>{let c=t.addRow(i),f=r.cellStyles?.[a],p=r.stripe&&a%2==1;if(r.columns.forEach((e,t)=>{let n=c.getCell(t+1);e.numFmt&&(typeof n.value==`number`||n.value instanceof Date)&&(n.numFmt=e.numFmt),e.align&&(n.alignment={horizontal:e.align,vertical:`middle`}),p&&(n.fill={type:`pattern`,pattern:`solid`,fgColor:{argb:o(r.stripe)}}),s(n,e.style),s(n,f?.[t])}),++d%u===0){if(n.signal?.aborted)throw e();n.progress(d/l*.9)}}),r.autoFilter&&r.rows.length>0&&(t.autoFilter={from:{row:p,column:1},to:{row:p,column:a}});for(let e of r.after??[])c(t,e,a)}let f=await i.xlsx.writeBuffer();return n.progress(1),a(f)}const u={Roboto:{normal:`Roboto-Regular.ttf`,bold:`Roboto-Medium.ttf`,italics:`Roboto-Italic.ttf`,bolditalics:`Roboto-MediumItalic.ttf`}};function d(e){let t=e.hLineWidth??1,n=e.edgeLineWidth??t;return{hLineWidth:(e,r)=>e===0||e===(r.table.headerRows??0)||e===r.table.body.length?n:t,vLineWidth:()=>e.vLineWidth??1,...e.hLineColor?{hLineColor:()=>e.hLineColor}:{},...e.vLineColor?{vLineColor:()=>e.vLineColor}:{},...e.paddingX===void 0?{}:{paddingLeft:()=>e.paddingX,paddingRight:()=>e.paddingX},...e.paddingY===void 0?{}:{paddingTop:()=>e.paddingY,paddingBottom:()=>e.paddingY}}}function f(e){return(t,n)=>({text:e.text.replace(/\{page\}/g,String(t)).replace(/\{pages\}/g,String(n)),...e.font?{font:e.font}:{},alignment:e.alignment??`center`,fontSize:e.fontSize??8,...e.color?{color:e.color}:{},...e.margin?{margin:e.margin}:{}})}async function p(t,n){let r=n.pdfFonts?{fonts:{...n.pdfFonts.fonts,...t.fonts?.fonts},vfs:n.pdfFonts.vfs||t.fonts?.vfs?{...n.pdfFonts.vfs,...t.fonts?.vfs}:void 0}:t.fonts,a=t.footer?{...t.document,footer:f(t.footer)}:t.document,o=t.tableLayouts?Object.fromEntries(Object.entries(t.tableLayouts).map(([e,t])=>[e,d(t)])):void 0,{pdfMake:s,vfs:c}=await i();if(n.progress(.1),n.signal?.aborted)throw e();let l={...u,...r?.fonts??{}},p=r?.vfs?{...c??{},...r.vfs}:c,m=await new Promise((e,t)=>{try{let n=s.createPdf(a,o,l,p).getStream(),r=[];n.on(`data`,e=>r.push(e)),n.on(`error`,t),n.on(`end`,()=>{let t=new Uint8Array(r.reduce((e,t)=>e+t.byteLength,0)),n=0;for(let e of r)t.set(e,n),n+=e.byteLength;e(t.buffer)}),n.end()}catch(e){t(e)}});return n.progress(1),m}let m;const h=self;h.onmessage=async e=>{if(e.data.type===`init`){m=e.data.pdfFonts;return}let{id:n,task:r}=e.data;try{let e=await t(r,{progress:e=>h.postMessage({type:`progress`,id:n,fraction:e}),pdfFonts:m});h.postMessage({type:`done`,id:n,buffer:e},[e])}catch(e){h.postMessage({type:`error`,id:n,message:e instanceof Error?e.message:String(e)})}};
|