@twentyfirstmedia/ui-core 0.4.0 → 0.6.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/ICONS-LICENSE +175 -0
- package/dist/components/admin.d.ts.map +1 -1
- package/dist/components/admin.js +31 -21
- package/dist/components/admin.js.map +1 -1
- package/dist/components/agents.d.ts.map +1 -1
- package/dist/components/agents.js +21 -18
- package/dist/components/agents.js.map +1 -1
- package/dist/components/app-chrome.d.ts.map +1 -1
- package/dist/components/app-chrome.js +5 -5
- package/dist/components/app-chrome.js.map +1 -1
- package/dist/components/approvals.d.ts.map +1 -1
- package/dist/components/approvals.js +2 -2
- package/dist/components/approvals.js.map +1 -1
- package/dist/components/building-blocks.d.ts.map +1 -1
- package/dist/components/building-blocks.js +13 -10
- package/dist/components/building-blocks.js.map +1 -1
- package/dist/components/charts.d.ts +2 -2
- package/dist/components/charts.d.ts.map +1 -1
- package/dist/components/charts.js +14 -11
- package/dist/components/charts.js.map +1 -1
- package/dist/components/chat.d.ts +2 -2
- package/dist/components/chat.d.ts.map +1 -1
- package/dist/components/chat.js +22 -18
- package/dist/components/chat.js.map +1 -1
- package/dist/components/commerce.d.ts.map +1 -1
- package/dist/components/commerce.js +20 -16
- package/dist/components/commerce.js.map +1 -1
- package/dist/components/data-display.d.ts +0 -5
- package/dist/components/data-display.d.ts.map +1 -1
- package/dist/components/data-display.js +41 -22
- package/dist/components/data-display.js.map +1 -1
- package/dist/components/data-table.d.ts +2 -2
- package/dist/components/data-table.d.ts.map +1 -1
- package/dist/components/data-table.js +3 -3
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/developer.d.ts.map +1 -1
- package/dist/components/developer.js +7 -6
- package/dist/components/developer.js.map +1 -1
- package/dist/components/feedback.d.ts.map +1 -1
- package/dist/components/feedback.js +5 -4
- package/dist/components/feedback.js.map +1 -1
- package/dist/components/forms.d.ts.map +1 -1
- package/dist/components/forms.js +63 -21
- package/dist/components/forms.js.map +1 -1
- package/dist/components/foundation.d.ts.map +1 -1
- package/dist/components/foundation.js +13 -9
- package/dist/components/foundation.js.map +1 -1
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -1
- package/dist/components/index.js.map +1 -1
- package/dist/components/inputs.d.ts.map +1 -1
- package/dist/components/inputs.js +33 -8
- package/dist/components/inputs.js.map +1 -1
- package/dist/components/mail.d.ts.map +1 -1
- package/dist/components/mail.js +5 -5
- package/dist/components/mail.js.map +1 -1
- package/dist/components/media.d.ts.map +1 -1
- package/dist/components/media.js +62 -11
- package/dist/components/media.js.map +1 -1
- package/dist/components/navigation.d.ts +3 -1
- package/dist/components/navigation.d.ts.map +1 -1
- package/dist/components/navigation.js +287 -20
- package/dist/components/navigation.js.map +1 -1
- package/dist/components/operations.d.ts.map +1 -1
- package/dist/components/operations.js +10 -10
- package/dist/components/operations.js.map +1 -1
- package/dist/components/overlays.d.ts.map +1 -1
- package/dist/components/overlays.js +2 -2
- package/dist/components/overlays.js.map +1 -1
- package/dist/components/previews.js +2 -2
- package/dist/components/previews.js.map +1 -1
- package/dist/components/primitives.js +2 -2
- package/dist/components/primitives.js.map +1 -1
- package/dist/components/qr-code.d.ts +8 -0
- package/dist/components/qr-code.d.ts.map +1 -0
- package/dist/components/qr-code.js +18 -0
- package/dist/components/qr-code.js.map +1 -0
- package/dist/components/real-estate.d.ts.map +1 -1
- package/dist/components/real-estate.js +5 -5
- package/dist/components/real-estate.js.map +1 -1
- package/dist/components/rich-text-editor.d.ts.map +1 -1
- package/dist/components/rich-text-editor.js +1 -1
- package/dist/components/rich-text-editor.js.map +1 -1
- package/dist/components/select-menu.js +1 -1
- package/dist/components/select-menu.js.map +1 -1
- package/dist/components/shell.d.ts +0 -4
- package/dist/components/shell.d.ts.map +1 -1
- package/dist/components/shell.js +100 -7
- package/dist/components/shell.js.map +1 -1
- package/dist/components/site.d.ts.map +1 -1
- package/dist/components/site.js +8 -6
- package/dist/components/site.js.map +1 -1
- package/dist/components/status.d.ts.map +1 -1
- package/dist/components/status.js +2 -2
- package/dist/components/status.js.map +1 -1
- package/dist/components/system.d.ts.map +1 -1
- package/dist/components/system.js +3 -2
- package/dist/components/system.js.map +1 -1
- package/dist/components/types.d.ts +257 -18
- package/dist/components/types.d.ts.map +1 -1
- package/dist/components/workspace.d.ts.map +1 -1
- package/dist/components/workspace.js +15 -12
- package/dist/components/workspace.js.map +1 -1
- package/dist/icon-library.d.ts +254 -3
- package/dist/icon-library.d.ts.map +1 -1
- package/dist/icon-library.js +518 -14
- package/dist/icon-library.js.map +1 -1
- package/dist/qr.d.ts +14 -0
- package/dist/qr.d.ts.map +1 -0
- package/dist/qr.js +298 -0
- package/dist/qr.js.map +1 -0
- package/dist/strings.d.ts +30 -4
- package/dist/strings.d.ts.map +1 -1
- package/dist/strings.js +15 -0
- package/dist/strings.js.map +1 -1
- package/dist/themes.css +2345 -176
- package/package.json +2 -1
- package/src/components/admin.tsx +66 -23
- package/src/components/agents.tsx +22 -20
- package/src/components/app-chrome.tsx +9 -5
- package/src/components/approvals.tsx +3 -1
- package/src/components/building-blocks.tsx +24 -13
- package/src/components/charts.tsx +17 -12
- package/src/components/chat.tsx +54 -31
- package/src/components/commerce.tsx +58 -24
- package/src/components/data-display.tsx +106 -38
- package/src/components/data-table.tsx +11 -7
- package/src/components/developer.tsx +15 -6
- package/src/components/feedback.tsx +5 -3
- package/src/components/forms.tsx +101 -23
- package/src/components/foundation.tsx +9 -5
- package/src/components/index.ts +10 -1
- package/src/components/inputs.tsx +44 -7
- package/src/components/mail.tsx +7 -3
- package/src/components/media.tsx +88 -16
- package/src/components/navigation.tsx +651 -71
- package/src/components/operations.tsx +17 -8
- package/src/components/overlays.tsx +7 -2
- package/src/components/previews.tsx +2 -2
- package/src/components/primitives.tsx +2 -2
- package/src/components/qr-code.tsx +30 -0
- package/src/components/real-estate.tsx +7 -4
- package/src/components/rich-text-editor.tsx +7 -1
- package/src/components/select-menu.tsx +1 -1
- package/src/components/shell.tsx +237 -11
- package/src/components/site.tsx +18 -4
- package/src/components/status.tsx +2 -0
- package/src/components/system.tsx +3 -2
- package/src/components/types.ts +261 -18
- package/src/components/workspace.tsx +37 -15
- package/src/icon-library.ts +523 -18
- package/src/qr.ts +300 -0
- package/src/strings.ts +56 -1
|
@@ -34,18 +34,26 @@ import type {
|
|
|
34
34
|
* in de-DE, "$1,305.50" in en-US): the number animates, the text around it stays, and decimals and
|
|
35
35
|
* grouping are kept. The final text is always `value` itself.
|
|
36
36
|
*/
|
|
37
|
+
const useIsoLayoutEffect = typeof window === "undefined" ? React.useEffect : React.useLayoutEffect;
|
|
38
|
+
|
|
37
39
|
export function CountUp(p: CountUpProps) {
|
|
38
40
|
const { locale } = useFormat();
|
|
39
41
|
const o = parseFormatted(p.value, locale),
|
|
40
42
|
fmt = (n: number, shape: FormattedNumber) => formatLike(n, shape, locale),
|
|
41
43
|
// numbers are shown in the locale too; strings end exactly as given
|
|
42
44
|
final = o && typeof p.value === "number" ? fmt(p.value, o) : String(p.value),
|
|
43
|
-
|
|
45
|
+
// the server (and readers without scripts, print, share images) get the final value; the
|
|
46
|
+
// client starts at zero before the first paint and counts up
|
|
47
|
+
st = React.useState(final),
|
|
44
48
|
last = React.useRef(0),
|
|
45
49
|
first = React.useRef(true),
|
|
46
50
|
el = React.useRef<HTMLSpanElement>(null);
|
|
51
|
+
useIsoLayoutEffect(() => {
|
|
52
|
+
if (o && p.animate !== false && !reduced(el.current)) st[1](fmt(0, o));
|
|
53
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- only before the first count
|
|
54
|
+
}, []);
|
|
47
55
|
React.useEffect(() => {
|
|
48
|
-
if (!o || reduced(el.current)) {
|
|
56
|
+
if (!o || p.animate === false || reduced(el.current)) {
|
|
49
57
|
st[1](final);
|
|
50
58
|
return;
|
|
51
59
|
}
|
|
@@ -77,7 +85,7 @@ export function CountUp(p: CountUpProps) {
|
|
|
77
85
|
};
|
|
78
86
|
}, [p.value, locale]);
|
|
79
87
|
return (
|
|
80
|
-
<span ref={el} className={p.className}>
|
|
88
|
+
<span style={p.style} ref={el} className={p.className}>
|
|
81
89
|
{st[0]}
|
|
82
90
|
</span>
|
|
83
91
|
);
|
|
@@ -86,6 +94,7 @@ export function StatTile(p: StatTileProps) {
|
|
|
86
94
|
const tint = p.tint || "sky";
|
|
87
95
|
return (
|
|
88
96
|
<div
|
|
97
|
+
style={p.style}
|
|
89
98
|
className={cx(
|
|
90
99
|
"tf-stat",
|
|
91
100
|
tint === "placeholder" ? "tf-stat-placeholder" : "tf-bg-" + tint,
|
|
@@ -150,7 +159,7 @@ export function EventCard(p: EventCardProps) {
|
|
|
150
159
|
const k = KIND[p.kind || "meeting"] || (KIND.meeting as [IconName, Tint]),
|
|
151
160
|
tint = p.tint || k[1];
|
|
152
161
|
return (
|
|
153
|
-
<div className={cx("tf-event", "tf-bg-" + tint, p.className)}>
|
|
162
|
+
<div style={p.style} className={cx("tf-event", "tf-bg-" + tint, p.className)}>
|
|
154
163
|
<div className="tf-event-head">
|
|
155
164
|
<span className="tf-event-kind">
|
|
156
165
|
<Icon name={p.icon || k[0]} size={14} />
|
|
@@ -195,7 +204,7 @@ export function Panel(p: PanelProps) {
|
|
|
195
204
|
}
|
|
196
205
|
export function PageHeader(p: PageHeaderProps) {
|
|
197
206
|
return (
|
|
198
|
-
<header className="tf-header">
|
|
207
|
+
<header style={p.style} className={cx("tf-header", p.className)}>
|
|
199
208
|
<div>
|
|
200
209
|
{p.crumbs && (
|
|
201
210
|
<div
|
|
@@ -203,7 +212,7 @@ export function PageHeader(p: PageHeaderProps) {
|
|
|
203
212
|
marginBottom: 8,
|
|
204
213
|
}}
|
|
205
214
|
>
|
|
206
|
-
<Breadcrumb items={p.crumbs} />
|
|
215
|
+
<Breadcrumb items={p.crumbs} linkAs={p.crumbLinkAs} />
|
|
207
216
|
</div>
|
|
208
217
|
)}
|
|
209
218
|
<h1 className="tf-header-title">{p.title}</h1>
|
|
@@ -255,8 +264,12 @@ export function Table(p: TableProps) {
|
|
|
255
264
|
const box = React.useRef<HTMLDivElement>(null);
|
|
256
265
|
useScrollFocus(box);
|
|
257
266
|
return (
|
|
258
|
-
<div
|
|
259
|
-
|
|
267
|
+
<div
|
|
268
|
+
style={p.style}
|
|
269
|
+
ref={box}
|
|
270
|
+
className={cx("tf-table-scroll", p.stack && "tf-table-stackbox", p.className)}
|
|
271
|
+
>
|
|
272
|
+
<table className={cx("tf-table", p.stack && "stack")}>
|
|
260
273
|
<thead>
|
|
261
274
|
<tr>
|
|
262
275
|
{cols.map((c) => (
|
|
@@ -287,7 +300,11 @@ export function Table(p: TableProps) {
|
|
|
287
300
|
{(p.rows || []).map((r, i) => (
|
|
288
301
|
<tr key={i}>
|
|
289
302
|
{cols.map((c) => (
|
|
290
|
-
<td
|
|
303
|
+
<td
|
|
304
|
+
key={c.key}
|
|
305
|
+
className={c.align === "right" ? "tf-num" : undefined}
|
|
306
|
+
data-label={p.stack ? c.label : undefined}
|
|
307
|
+
>
|
|
291
308
|
{c.render ? c.render(r) : r[c.key]}
|
|
292
309
|
</td>
|
|
293
310
|
))}
|
|
@@ -300,34 +317,42 @@ export function Table(p: TableProps) {
|
|
|
300
317
|
}
|
|
301
318
|
export function ListRow(p: ListRowProps) {
|
|
302
319
|
const t = useStrings(DATA_DISPLAY_STRINGS);
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
320
|
+
const Link = (p.linkAs || "a") as React.ElementType;
|
|
321
|
+
const interactive = !!(p.onClick || p.href);
|
|
322
|
+
const lines = (n: number | undefined) =>
|
|
323
|
+
n ? ({ "--lines": n } as React.CSSProperties) : undefined;
|
|
324
|
+
const title = (
|
|
325
|
+
<span className={cx("tf-row-title", p.titleLines && "clamp")} style={lines(p.titleLines)}>
|
|
326
|
+
{p.unread && <span className="tf-unread" role="img" aria-label={t.unread} />}
|
|
327
|
+
{p.titleLines ? <span className="tf-row-clamp">{p.title}</span> : p.title}
|
|
328
|
+
</span>
|
|
329
|
+
);
|
|
330
|
+
const content = (hit: boolean) => (
|
|
331
|
+
<>
|
|
310
332
|
{p.leading ||
|
|
311
333
|
(p.avatar ? (
|
|
312
334
|
<Avatar name={p.avatar} size={36} />
|
|
313
335
|
) : (
|
|
314
336
|
<TintIcon icon={p.icon || "mail"} tint={p.tint || "plain"} size={36} />
|
|
315
337
|
))}
|
|
316
|
-
<span
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
338
|
+
<span className="tf-row-text">
|
|
339
|
+
{hit && interactive ? (
|
|
340
|
+
p.href ? (
|
|
341
|
+
<Link className="tf-row-hit" href={p.href} onClick={p.onClick}>
|
|
342
|
+
{title}
|
|
343
|
+
</Link>
|
|
344
|
+
) : (
|
|
345
|
+
<button type="button" className="tf-row-hit" onClick={p.onClick}>
|
|
346
|
+
{title}
|
|
347
|
+
</button>
|
|
348
|
+
)
|
|
349
|
+
) : (
|
|
350
|
+
title
|
|
351
|
+
)}
|
|
325
352
|
{p.subtitle && (
|
|
326
353
|
<span
|
|
327
|
-
className="tf-row-sub"
|
|
328
|
-
style={
|
|
329
|
-
display: "block",
|
|
330
|
-
}}
|
|
354
|
+
className={cx("tf-row-sub", (p.subtitleLines || 1) > 1 && "clamp")}
|
|
355
|
+
style={lines(p.subtitleLines)}
|
|
331
356
|
>
|
|
332
357
|
{p.subtitle}
|
|
333
358
|
</span>
|
|
@@ -337,18 +362,59 @@ export function ListRow(p: ListRowProps) {
|
|
|
337
362
|
{p.meta}
|
|
338
363
|
{p.trailing}
|
|
339
364
|
</span>
|
|
365
|
+
{p.actions && <span className="tf-row-actions">{p.actions}</span>}
|
|
366
|
+
</>
|
|
367
|
+
);
|
|
368
|
+
// own buttons, or nothing to click: a plain row (with a stretched hit area when interactive)
|
|
369
|
+
if (p.actions || !interactive)
|
|
370
|
+
return (
|
|
371
|
+
<div
|
|
372
|
+
style={p.style}
|
|
373
|
+
className={cx(
|
|
374
|
+
"tf-row-item",
|
|
375
|
+
interactive ? "has-hit" : "static",
|
|
376
|
+
p.actions && "has-actions",
|
|
377
|
+
p.className,
|
|
378
|
+
)}
|
|
379
|
+
aria-current={p.active ? "true" : undefined}
|
|
380
|
+
>
|
|
381
|
+
{content(true)}
|
|
382
|
+
</div>
|
|
383
|
+
);
|
|
384
|
+
if (p.href)
|
|
385
|
+
return (
|
|
386
|
+
<Link
|
|
387
|
+
href={p.href}
|
|
388
|
+
style={p.style}
|
|
389
|
+
className={cx("tf-row-item", p.className)}
|
|
390
|
+
aria-current={p.active ? "true" : undefined}
|
|
391
|
+
onClick={p.onClick}
|
|
392
|
+
>
|
|
393
|
+
{content(false)}
|
|
394
|
+
</Link>
|
|
395
|
+
);
|
|
396
|
+
return (
|
|
397
|
+
<button
|
|
398
|
+
style={p.style}
|
|
399
|
+
type="button"
|
|
400
|
+
className={cx("tf-row-item", p.className)}
|
|
401
|
+
aria-current={p.active ? "true" : undefined}
|
|
402
|
+
onClick={p.onClick}
|
|
403
|
+
>
|
|
404
|
+
{content(false)}
|
|
340
405
|
</button>
|
|
341
406
|
);
|
|
342
407
|
}
|
|
343
408
|
export function Timeline(p: TimelineProps) {
|
|
344
409
|
return (
|
|
345
410
|
<ol
|
|
346
|
-
className="tf-timeline tf-stagger"
|
|
347
|
-
style={
|
|
348
|
-
{
|
|
411
|
+
className={cx("tf-timeline tf-stagger", p.className)}
|
|
412
|
+
style={{
|
|
413
|
+
...({
|
|
349
414
|
"--base": (p.delay || 200) + "ms",
|
|
350
|
-
} as React.CSSProperties
|
|
351
|
-
|
|
415
|
+
} as React.CSSProperties),
|
|
416
|
+
...p.style,
|
|
417
|
+
}}
|
|
352
418
|
>
|
|
353
419
|
{(p.items || []).map((it, i) => (
|
|
354
420
|
<li key={i} className="tf-tl-item">
|
|
@@ -377,7 +443,7 @@ export function FileRow(p: FileRowProps) {
|
|
|
377
443
|
const strings = useStrings(DATA_DISPLAY_STRINGS);
|
|
378
444
|
const t = FT[p.kind || "doc"] || (FT.doc as [IconName, Tint]);
|
|
379
445
|
return (
|
|
380
|
-
<div className="tf-file">
|
|
446
|
+
<div style={p.style} className={cx("tf-file", p.className)}>
|
|
381
447
|
<TintIcon icon={t[0]} tint={t[1]} />
|
|
382
448
|
<div
|
|
383
449
|
style={{
|
|
@@ -395,7 +461,7 @@ export function FileRow(p: FileRowProps) {
|
|
|
395
461
|
export function KanbanColumn(p: KanbanColumnProps) {
|
|
396
462
|
const t = useStrings(DATA_DISPLAY_STRINGS);
|
|
397
463
|
return (
|
|
398
|
-
<section className="tf-kanban" aria-label={p.title}>
|
|
464
|
+
<section style={p.style} className={cx("tf-kanban", p.className)} aria-label={p.title}>
|
|
399
465
|
<div className="tf-kanban-head">
|
|
400
466
|
<span
|
|
401
467
|
className="tf-row"
|
|
@@ -442,7 +508,8 @@ export function Progress(p: ProgressProps) {
|
|
|
442
508
|
const v = Math.max(0, Math.min(100, p.value || 0));
|
|
443
509
|
return (
|
|
444
510
|
<div
|
|
445
|
-
|
|
511
|
+
style={p.style}
|
|
512
|
+
className={cx("tf-progress", p.tint && "tf-progress-" + p.tint, p.className)}
|
|
446
513
|
role="progressbar"
|
|
447
514
|
aria-valuenow={v}
|
|
448
515
|
aria-valuemin={0}
|
|
@@ -468,10 +535,11 @@ export function ProgressRing(p: ProgressRingProps) {
|
|
|
468
535
|
on = useMounted(150);
|
|
469
536
|
return (
|
|
470
537
|
<div
|
|
471
|
-
className="tf-ring"
|
|
538
|
+
className={cx("tf-ring", p.className)}
|
|
472
539
|
style={{
|
|
473
540
|
width: size,
|
|
474
541
|
height: size,
|
|
542
|
+
...p.style,
|
|
475
543
|
}}
|
|
476
544
|
role="img"
|
|
477
545
|
aria-label={(p.label || t.progress) + " " + formatPercent(v, { maximumFractionDigits: 2 })}
|
|
@@ -7,7 +7,7 @@ import { cx } from "../cx.js";
|
|
|
7
7
|
import { SearchField } from "./inputs.js";
|
|
8
8
|
import { Popover, Tooltip } from "./overlays.js";
|
|
9
9
|
import { Menu } from "./feedback.js";
|
|
10
|
-
import type { DataTableProps, FilterBarProps, FilterDef } from "./types.js";
|
|
10
|
+
import type { BaseProps, DataTableProps, FilterBarProps, FilterDef } from "./types.js";
|
|
11
11
|
|
|
12
12
|
/* ── Data table: sort, select + bulk bar, column toggles, sticky head, expandable rows ── */
|
|
13
13
|
export function FilterBar(p: FilterBarProps) {
|
|
@@ -22,7 +22,7 @@ export function FilterBar(p: FilterBarProps) {
|
|
|
22
22
|
}
|
|
23
23
|
const avail = (p.filters || []).filter((f) => keys.indexOf(f.key) < 0);
|
|
24
24
|
return (
|
|
25
|
-
<div className="tf-filterbar">
|
|
25
|
+
<div style={p.style} className={cx("tf-filterbar", p.className)}>
|
|
26
26
|
{p.search && (
|
|
27
27
|
<SearchField
|
|
28
28
|
placeholder={p.search}
|
|
@@ -120,10 +120,12 @@ export function FilterBar(p: FilterBarProps) {
|
|
|
120
120
|
);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
export function AddFilterMenu(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
export function AddFilterMenu(
|
|
124
|
+
p: BaseProps & {
|
|
125
|
+
avail: FilterDef[];
|
|
126
|
+
onPick?: (key: string, option: string) => void;
|
|
127
|
+
},
|
|
128
|
+
) {
|
|
127
129
|
const t = useStrings(DATA_TABLE_STRINGS);
|
|
128
130
|
const step = React.useState<FilterDef | null>(null);
|
|
129
131
|
const cur = step[0];
|
|
@@ -150,6 +152,8 @@ export function AddFilterMenu(p: {
|
|
|
150
152
|
);
|
|
151
153
|
return (
|
|
152
154
|
<Menu
|
|
155
|
+
style={p.style}
|
|
156
|
+
className={p.className}
|
|
153
157
|
items={p.avail.map((f) => ({
|
|
154
158
|
label: f.label,
|
|
155
159
|
icon: f.icon || "filter",
|
|
@@ -224,7 +228,7 @@ export function DataTable<R extends Record<string, any> = Record<string, any>>(
|
|
|
224
228
|
const span = vis.length + (p.selectable ? 1 : 0) + (p.renderExpanded ? 1 : 0);
|
|
225
229
|
const selRows = rows.filter((r) => selected.indexOf(r[rk]) >= 0);
|
|
226
230
|
return (
|
|
227
|
-
<div className={cx("tf-dt", p.className)}>
|
|
231
|
+
<div className={cx("tf-dt", p.className)} style={p.style}>
|
|
228
232
|
{(p.toolbar || p.columnToggle !== false) && (
|
|
229
233
|
<div className="tf-dt-toolbar">
|
|
230
234
|
{p.toolbar}
|
|
@@ -38,6 +38,7 @@ export function LogView(p: LogViewProps) {
|
|
|
38
38
|
className={cx("tf-log", p.className)}
|
|
39
39
|
style={{
|
|
40
40
|
maxHeight: p.maxHeight,
|
|
41
|
+
...p.style,
|
|
41
42
|
}}
|
|
42
43
|
>
|
|
43
44
|
{p.title && (
|
|
@@ -90,7 +91,7 @@ export function SecretField(p: SecretFieldProps) {
|
|
|
90
91
|
copied = React.useState(false);
|
|
91
92
|
const masked = (p.prefix || "") + "••••••••" + (p.last4 || "");
|
|
92
93
|
return (
|
|
93
|
-
<div className="tf-secret">
|
|
94
|
+
<div style={p.style} className={cx("tf-secret", p.className)}>
|
|
94
95
|
<Icon name="key" size={15} />
|
|
95
96
|
<span className="tf-mono tf-secret-val">{shown[0] && p.value ? p.value : masked}</span>
|
|
96
97
|
{p.meta && <span className="tf-secret-meta">{p.meta}</span>}
|
|
@@ -173,7 +174,15 @@ export function MoneyInput(p: MoneyInputProps) {
|
|
|
173
174
|
}
|
|
174
175
|
const sym = formatMoney(0, p.currency).replace(/[\d.,\s]/g, "");
|
|
175
176
|
return (
|
|
176
|
-
<FormField
|
|
177
|
+
<FormField
|
|
178
|
+
style={p.style}
|
|
179
|
+
className={p.className}
|
|
180
|
+
id={id}
|
|
181
|
+
label={p.label}
|
|
182
|
+
hint={p.hint}
|
|
183
|
+
error={p.error}
|
|
184
|
+
required={p.required}
|
|
185
|
+
>
|
|
177
186
|
<div className="tf-money">
|
|
178
187
|
<span
|
|
179
188
|
className="tf-inputwrap"
|
|
@@ -248,7 +257,7 @@ export function MoneyInput(p: MoneyInputProps) {
|
|
|
248
257
|
|
|
249
258
|
export function SettingsLayout(p: SettingsLayoutProps) {
|
|
250
259
|
return (
|
|
251
|
-
<div className="tf-settings">
|
|
260
|
+
<div style={p.style} className={cx("tf-settings", p.className)}>
|
|
252
261
|
{(p.sections || []).map((s, i) => (
|
|
253
262
|
<section key={s.id || i} className="tf-settings-row">
|
|
254
263
|
<div className="tf-settings-label">
|
|
@@ -321,7 +330,7 @@ export function StatCell(p: StatCellProps) {
|
|
|
321
330
|
const up = p.delta != null && p.delta >= 0,
|
|
322
331
|
good = p.invert ? !up : up;
|
|
323
332
|
return (
|
|
324
|
-
<div className={cx("tf-statcell", p.tint && "tf-bg-" + p.tint, p.className)}>
|
|
333
|
+
<div style={p.style} className={cx("tf-statcell", p.tint && "tf-bg-" + p.tint, p.className)}>
|
|
325
334
|
<div className="tf-statcell-top">
|
|
326
335
|
<span className="tf-statcell-label">{p.label}</span>
|
|
327
336
|
{p.icon && <TintIcon icon={p.icon} tint={p.iconTint || "plain"} />}
|
|
@@ -363,7 +372,7 @@ export function UptimeBar(p: UptimeBarProps) {
|
|
|
363
372
|
const days = (p.days || []).map((d) => (typeof d === "string" ? { status: d } : d)),
|
|
364
373
|
hov = React.useState<number | null>(null);
|
|
365
374
|
return (
|
|
366
|
-
<div className="tf-uptime">
|
|
375
|
+
<div style={p.style} className={cx("tf-uptime", p.className)}>
|
|
367
376
|
<div
|
|
368
377
|
className="tf-uptime-bar"
|
|
369
378
|
onPointerLeave={() => {
|
|
@@ -408,7 +417,7 @@ export function Meter(p: MeterProps) {
|
|
|
408
417
|
tone =
|
|
409
418
|
p.tone || (pct >= (p.danger || 90) ? "blush" : pct >= (p.warn || 75) ? "butter" : "mint");
|
|
410
419
|
return (
|
|
411
|
-
<div className="tf-meter">
|
|
420
|
+
<div style={p.style} className={cx("tf-meter", p.className)}>
|
|
412
421
|
<div className="tf-usage-top">
|
|
413
422
|
<span>{p.label}</span>
|
|
414
423
|
<b>{p.text || formatPercent(pct)}</b>
|
|
@@ -38,6 +38,7 @@ export function Skeleton(p: SkeletonProps) {
|
|
|
38
38
|
style={{
|
|
39
39
|
width: p.width,
|
|
40
40
|
height: p.height || (v === "circle" ? p.width : undefined),
|
|
41
|
+
...p.style,
|
|
41
42
|
}}
|
|
42
43
|
/>
|
|
43
44
|
);
|
|
@@ -185,7 +186,7 @@ export function Modal(p: ModalProps) {
|
|
|
185
186
|
const pr = usePresence(p.open ?? true);
|
|
186
187
|
if (!pr.mounted) return null;
|
|
187
188
|
return (
|
|
188
|
-
<div {...leaving(pr.closing)} className="tf-modal-wrap" style={p.style}>
|
|
189
|
+
<div {...leaving(pr.closing)} className={cx("tf-modal-wrap", p.className)} style={p.style}>
|
|
189
190
|
<div className="tf-backdrop" aria-hidden />
|
|
190
191
|
<div className="tf-modal" role="dialog" aria-modal="true" aria-label={p.title}>
|
|
191
192
|
<span className="tf-modal-close">
|
|
@@ -214,7 +215,7 @@ export function Modal(p: ModalProps) {
|
|
|
214
215
|
|
|
215
216
|
export function Toast(p: ToastProps) {
|
|
216
217
|
return (
|
|
217
|
-
<div className="tf-toast" role="status">
|
|
218
|
+
<div style={p.style} className={cx("tf-toast", p.className)} role="status">
|
|
218
219
|
<TintIcon icon={p.icon || "check"} tint={p.tint || "mint"} />
|
|
219
220
|
{p.children}
|
|
220
221
|
{p.action && (
|
|
@@ -228,7 +229,7 @@ export function Toast(p: ToastProps) {
|
|
|
228
229
|
|
|
229
230
|
export function EmptyState(p: EmptyStateProps) {
|
|
230
231
|
return (
|
|
231
|
-
<div className="tf-empty tf-in">
|
|
232
|
+
<div style={p.style} className={cx("tf-empty tf-in", p.className)}>
|
|
232
233
|
<TintIcon icon={p.icon || "sparkle"} tint={p.tint || "sky"} size={44} />
|
|
233
234
|
<p className="tf-empty-title">{p.title}</p>
|
|
234
235
|
{p.text && <p className="tf-empty-text">{p.text}</p>}
|
|
@@ -258,6 +259,7 @@ export function Alert(p: AlertProps) {
|
|
|
258
259
|
const tone = p.tone || "info";
|
|
259
260
|
return (
|
|
260
261
|
<div
|
|
262
|
+
style={p.style}
|
|
261
263
|
className={cx("tf-alert", "tf-alert-" + tone, p.className)}
|
|
262
264
|
role={tone === "danger" || tone === "warning" ? "alert" : "status"}
|
|
263
265
|
>
|