@lerianstudio/sindarian-ui 1.4.0-beta.2 → 1.4.0-beta.4
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/components/entity-box/index.d.ts +11 -2
- package/dist/components/entity-box/index.d.ts.map +1 -1
- package/dist/components/entity-box/index.js +3 -3
- package/dist/components/form/input-field/index.d.ts +12 -2
- package/dist/components/form/input-field/index.d.ts.map +1 -1
- package/dist/components/form/input-field/index.js +29 -5
- package/dist/components/form/select-field/index.d.ts +29 -5
- package/dist/components/form/select-field/index.d.ts.map +1 -1
- package/dist/components/form/select-field/index.js +33 -10
- package/dist/components/page-header/index.d.ts +8 -2
- package/dist/components/page-header/index.d.ts.map +1 -1
- package/dist/components/page-header/index.js +4 -4
- package/dist/components/ui/badge/index.d.ts +8 -0
- package/dist/components/ui/badge/index.d.ts.map +1 -1
- package/dist/components/ui/badge/index.js +9 -1
- package/dist/components/ui/form.d.ts +4 -4
- package/dist/components/ui/form.d.ts.map +1 -1
- package/dist/components/ui/form.js +12 -6
- package/dist/components/ui/multiple-select/index.d.ts +11 -3
- package/dist/components/ui/multiple-select/index.d.ts.map +1 -1
- package/dist/components/ui/select/index.d.ts +5 -0
- package/dist/components/ui/select/index.d.ts.map +1 -1
- package/dist/components/ui/select/index.js +24 -1
- package/dist/domain/blotter/index.d.ts +2 -2
- package/dist/domain/delinquency-aging/aging-buckets.d.ts.map +1 -1
- package/dist/domain/delinquency-aging/aging-buckets.js +1 -1
- package/dist/domain/delinquency-aging/index.d.ts.map +1 -1
- package/dist/domain/delinquency-aging/index.js +1 -1
- package/dist/domain/figure/index.d.ts +11 -9
- package/dist/domain/figure/index.d.ts.map +1 -1
- package/dist/domain/figure/index.js +8 -8
- package/dist/domain/key-id/index.d.ts +1 -1
- package/dist/domain/key-id/index.d.ts.map +1 -1
- package/dist/domain/key-id/index.js +1 -1
- package/dist/domain/section-label/index.d.ts +10 -7
- package/dist/domain/section-label/index.d.ts.map +1 -1
- package/dist/domain/status-rail/index.d.ts +1 -1
- package/dist/domain/status-rail/index.d.ts.map +1 -1
- package/dist/domain/status-rail/index.js +8 -4
- package/dist/enterprise/alert-banner/index.d.ts +5 -3
- package/dist/enterprise/alert-banner/index.d.ts.map +1 -1
- package/dist/enterprise/alert-banner/index.js +2 -2
- package/dist/enterprise/data-table/column-size.d.ts +70 -0
- package/dist/enterprise/data-table/column-size.d.ts.map +1 -0
- package/dist/enterprise/data-table/column-size.js +103 -0
- package/dist/enterprise/data-table/index.d.ts.map +1 -1
- package/dist/enterprise/data-table/index.js +22 -2
- package/dist/enterprise/date-range-picker/index.d.ts.map +1 -1
- package/dist/enterprise/date-range-picker/index.js +1 -2
- package/dist/enterprise/stat-card/index.d.ts +3 -3
- package/dist/enterprise/stat-card/index.d.ts.map +1 -1
- package/dist/enterprise/stat-card/index.js +1 -1
- package/dist/enterprise/status-badge/index.js +1 -1
- package/dist/enterprise/virtualized-table/index.d.ts +18 -2
- package/dist/enterprise/virtualized-table/index.d.ts.map +1 -1
- package/dist/enterprise/virtualized-table/index.js +31 -4
- package/dist/esm/components/entity-box/index.d.ts +11 -2
- package/dist/esm/components/entity-box/index.d.ts.map +1 -1
- package/dist/esm/components/entity-box/index.js +3 -3
- package/dist/esm/components/form/input-field/index.d.ts +12 -2
- package/dist/esm/components/form/input-field/index.d.ts.map +1 -1
- package/dist/esm/components/form/input-field/index.js +29 -5
- package/dist/esm/components/form/select-field/index.d.ts +29 -5
- package/dist/esm/components/form/select-field/index.d.ts.map +1 -1
- package/dist/esm/components/form/select-field/index.js +33 -10
- package/dist/esm/components/page-header/index.d.ts +8 -2
- package/dist/esm/components/page-header/index.d.ts.map +1 -1
- package/dist/esm/components/page-header/index.js +4 -4
- package/dist/esm/components/ui/badge/index.d.ts +8 -0
- package/dist/esm/components/ui/badge/index.d.ts.map +1 -1
- package/dist/esm/components/ui/badge/index.js +9 -1
- package/dist/esm/components/ui/form.d.ts +4 -4
- package/dist/esm/components/ui/form.d.ts.map +1 -1
- package/dist/esm/components/ui/form.js +12 -6
- package/dist/esm/components/ui/multiple-select/index.d.ts +11 -3
- package/dist/esm/components/ui/multiple-select/index.d.ts.map +1 -1
- package/dist/esm/components/ui/select/index.d.ts +5 -0
- package/dist/esm/components/ui/select/index.d.ts.map +1 -1
- package/dist/esm/components/ui/select/index.js +24 -1
- package/dist/esm/domain/blotter/index.d.ts +2 -2
- package/dist/esm/domain/delinquency-aging/aging-buckets.d.ts.map +1 -1
- package/dist/esm/domain/delinquency-aging/aging-buckets.js +1 -1
- package/dist/esm/domain/delinquency-aging/index.d.ts.map +1 -1
- package/dist/esm/domain/delinquency-aging/index.js +1 -1
- package/dist/esm/domain/figure/index.d.ts +11 -9
- package/dist/esm/domain/figure/index.d.ts.map +1 -1
- package/dist/esm/domain/figure/index.js +8 -8
- package/dist/esm/domain/key-id/index.d.ts +1 -1
- package/dist/esm/domain/key-id/index.d.ts.map +1 -1
- package/dist/esm/domain/key-id/index.js +1 -1
- package/dist/esm/domain/section-label/index.d.ts +10 -7
- package/dist/esm/domain/section-label/index.d.ts.map +1 -1
- package/dist/esm/domain/status-rail/index.d.ts +1 -1
- package/dist/esm/domain/status-rail/index.d.ts.map +1 -1
- package/dist/esm/domain/status-rail/index.js +8 -4
- package/dist/esm/enterprise/alert-banner/index.d.ts +5 -3
- package/dist/esm/enterprise/alert-banner/index.d.ts.map +1 -1
- package/dist/esm/enterprise/alert-banner/index.js +2 -2
- package/dist/esm/enterprise/data-table/column-size.d.ts +70 -0
- package/dist/esm/enterprise/data-table/column-size.d.ts.map +1 -0
- package/dist/esm/enterprise/data-table/column-size.js +97 -0
- package/dist/esm/enterprise/data-table/index.d.ts.map +1 -1
- package/dist/esm/enterprise/data-table/index.js +22 -2
- package/dist/esm/enterprise/date-range-picker/index.d.ts.map +1 -1
- package/dist/esm/enterprise/date-range-picker/index.js +1 -2
- package/dist/esm/enterprise/stat-card/index.d.ts +3 -3
- package/dist/esm/enterprise/stat-card/index.d.ts.map +1 -1
- package/dist/esm/enterprise/stat-card/index.js +1 -1
- package/dist/esm/enterprise/status-badge/index.js +1 -1
- package/dist/esm/enterprise/virtualized-table/index.d.ts +18 -2
- package/dist/esm/enterprise/virtualized-table/index.d.ts.map +1 -1
- package/dist/esm/enterprise/virtualized-table/index.js +31 -4
- package/dist/esm/lib/typography.d.ts +21 -6
- package/dist/esm/lib/typography.d.ts.map +1 -1
- package/dist/esm/lib/typography.js +20 -5
- package/dist/globals.css +51 -16
- package/dist/lib/typography.d.ts +21 -6
- package/dist/lib/typography.d.ts.map +1 -1
- package/dist/lib/typography.js +20 -5
- package/package.json +1 -1
|
@@ -112,5 +112,5 @@ export function StatusBadge({ status, label, variantMap, withIcon = false, unkno
|
|
|
112
112
|
// The glyph follows the resolved variant; an unknown/non-severity variant has
|
|
113
113
|
// no cue, so the badge gracefully renders label-only even with withIcon set.
|
|
114
114
|
const cue = withIcon ? SEVERITY_CUE[variant] : undefined;
|
|
115
|
-
return (_jsxs(Badge, { variant: variant, className:
|
|
115
|
+
return (_jsxs(Badge, { variant: variant, className: className, children: [cue ? (_jsxs(_Fragment, { children: [_jsx(cue.Icon, { "aria-hidden": true, className: "size-3.5 shrink-0" }), _jsxs("span", { className: "sr-only", children: [cue.word, ": "] })] })) : null, label ?? humanize(status)] }));
|
|
116
116
|
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { type ColumnDef } from '@tanstack/react-table';
|
|
2
2
|
export type VirtualizedTableProps<TData> = {
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Same shape as DataTable: standard TanStack `ColumnDef<T>`. A column that
|
|
5
|
+
* declares none keeps its equal share of the row.
|
|
6
|
+
*
|
|
7
|
+
* Declared sizing does NOT mean the same thing in the kit's two table paths.
|
|
8
|
+
* Here, flex rows PIN all three: `size`, `minSize` and `maxSize` are honoured
|
|
9
|
+
* exactly as declared. DataTable renders real `<th>`/`<td>` under CSS auto
|
|
10
|
+
* table layout, where `size` is only a PREFERRED width, `minSize` a floor,
|
|
11
|
+
* and `maxSize` is ignored outright. A column that must not grow past a width
|
|
12
|
+
* belongs here.
|
|
13
|
+
*/
|
|
4
14
|
columns: ColumnDef<TData, unknown>[];
|
|
5
15
|
/** The full dataset, already in memory. Only the visible window renders. */
|
|
6
16
|
data: TData[];
|
|
@@ -21,6 +31,12 @@ export type VirtualizedTableProps<TData> = {
|
|
|
21
31
|
scrollAreaLabel?: string;
|
|
22
32
|
/** Applied to the outer wrapper (the scroll container's parent). */
|
|
23
33
|
className?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Extra classes merged onto every header cell, after the kit label voice —
|
|
36
|
+
* the same seam DataTable exposes, so a screen that switches between the two
|
|
37
|
+
* render paths quiets both column heads with one prop instead of one.
|
|
38
|
+
*/
|
|
39
|
+
headClassName?: string;
|
|
24
40
|
};
|
|
25
|
-
export declare function VirtualizedTable<TData>({ columns, data, rowHeight, maxHeight, scrollAreaLabel, className }: VirtualizedTableProps<TData>): import("react").JSX.Element;
|
|
41
|
+
export declare function VirtualizedTable<TData>({ columns, data, rowHeight, maxHeight, scrollAreaLabel, className, headClassName }: VirtualizedTableProps<TData>): import("react").JSX.Element;
|
|
26
42
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/enterprise/virtualized-table/index.tsx"],"names":[],"mappings":"AA+BA,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/enterprise/virtualized-table/index.tsx"],"names":[],"mappings":"AA+BA,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,uBAAuB,CAAA;AAW9B,MAAM,MAAM,qBAAqB,CAAC,KAAK,IAAI;IACzC;;;;;;;;;;OAUG;IACH,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAA;IACpC,4EAA4E;IAC5E,IAAI,EAAE,KAAK,EAAE,CAAA;IACb;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC3B,yEAAyE;IACzE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAKD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,EACtC,OAAO,EACP,IAAI,EACJ,SAAc,EACd,SAAe,EACf,eAAyC,EACzC,SAAS,EACT,aAAa,EACd,EAAE,qBAAqB,CAAC,KAAK,CAAC,+BAkO9B"}
|
|
@@ -31,10 +31,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
31
31
|
import { useEffect, useRef, useState } from 'react';
|
|
32
32
|
import { flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';
|
|
33
33
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
34
|
+
import { LABEL_VOICE_CLASS } from '../../lib/typography.js';
|
|
34
35
|
import { cn } from '../../lib/utils.js';
|
|
36
|
+
import { readDeclaredColumnSize, readDeclaredGroupSize, UNSIZED_DEFAULT_COLUMN } from '../data-table/column-size.js';
|
|
35
37
|
/** Rows rendered just outside the viewport to keep fast scrolls smooth. */
|
|
36
38
|
const OVERSCAN = 8;
|
|
37
|
-
export function VirtualizedTable({ columns, data, rowHeight = 40, maxHeight = 480, scrollAreaLabel = 'Scrollable table rows', className }) {
|
|
39
|
+
export function VirtualizedTable({ columns, data, rowHeight = 40, maxHeight = 480, scrollAreaLabel = 'Scrollable table rows', className, headClassName }) {
|
|
38
40
|
const scrollRef = useRef(null);
|
|
39
41
|
const [isScrollable, setIsScrollable] = useState(false);
|
|
40
42
|
// A number is px; a string is used verbatim (e.g. '60vh').
|
|
@@ -42,6 +44,10 @@ export function VirtualizedTable({ columns, data, rowHeight = 40, maxHeight = 48
|
|
|
42
44
|
const table = useReactTable({
|
|
43
45
|
data,
|
|
44
46
|
columns,
|
|
47
|
+
// Keeps `columnDef.size`/`minSize`/`maxSize` meaning "declared" — see
|
|
48
|
+
// ../data-table/column-size. `getSize()` is unaffected; it falls back to
|
|
49
|
+
// the library defaults itself.
|
|
50
|
+
defaultColumn: UNSIZED_DEFAULT_COLUMN,
|
|
45
51
|
getCoreRowModel: getCoreRowModel()
|
|
46
52
|
});
|
|
47
53
|
const rows = table.getRowModel().rows;
|
|
@@ -94,11 +100,23 @@ export function VirtualizedTable({ columns, data, rowHeight = 40, maxHeight = 48
|
|
|
94
100
|
// its position among its siblings.
|
|
95
101
|
const firstLeaf = header.column.getLeafColumns()[0];
|
|
96
102
|
const start = leafPosition.get(firstLeaf?.id ?? header.column.id);
|
|
97
|
-
|
|
103
|
+
// A group header spans leaf columns whose body cells carry
|
|
104
|
+
// their own widths, so its size comes from those leaves, not
|
|
105
|
+
// from the group def (which declares nothing). A leaf header
|
|
106
|
+
// reads its own column, as before.
|
|
107
|
+
const size = header.subHeaders.length > 0
|
|
108
|
+
? readDeclaredGroupSize(header.column.getLeafColumns())
|
|
109
|
+
: readDeclaredColumnSize(header.column);
|
|
110
|
+
return (_jsx("div", { role: "columnheader", "aria-colindex": (start ?? 0) + 1, "aria-colspan": header.colSpan > 1 ? header.colSpan : undefined,
|
|
111
|
+
// A declared width must not be flexed away; without one the
|
|
112
|
+
// cell keeps its colSpan share of the row, as before.
|
|
113
|
+
style: size?.width === undefined
|
|
114
|
+
? { flex: `${header.colSpan} 1 0%`, ...size }
|
|
115
|
+
: { flex: '0 0 auto', ...size },
|
|
98
116
|
// Header height is independent of rowHeight: pinning it to a
|
|
99
117
|
// small rowHeight (32) clipped the uppercase label against its
|
|
100
118
|
// own padding. Padding sizes it; min-h keeps a stable rule.
|
|
101
|
-
className:
|
|
119
|
+
className: cn('min-h-10 px-4 py-2.5 text-left', LABEL_VOICE_CLASS, headClassName), children: header.isPlaceholder
|
|
102
120
|
? null
|
|
103
121
|
: flexRender(header.column.columnDef.header, header.getContext()) }, header.id));
|
|
104
122
|
}) }, headerGroup.id))) }), _jsx("div", { ref: scrollRef, role: "rowgroup", "data-testid": "virtualized-table-viewport", "aria-label": isScrollable ? scrollAreaLabel : undefined, tabIndex: isScrollable ? 0 : undefined, className: "focus-visible:ring-ring relative overflow-auto focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none", style: { maxHeight: viewportMaxHeight }, children: _jsx("div", { role: "presentation", className: "relative w-full", style: { height: totalSize }, children: virtualRows.map((virtualItem) => {
|
|
@@ -106,6 +124,15 @@ export function VirtualizedTable({ columns, data, rowHeight = 40, maxHeight = 48
|
|
|
106
124
|
return (_jsx("div", { role: "row", "aria-rowindex": virtualItem.index + headerRowCount + 1, "data-index": virtualItem.index, className: "border-border absolute left-0 flex w-full items-center border-b text-sm", style: {
|
|
107
125
|
height: virtualItem.size,
|
|
108
126
|
transform: `translateY(${virtualItem.start}px)`
|
|
109
|
-
}, children: row.getVisibleCells().map((cell, i) =>
|
|
127
|
+
}, children: row.getVisibleCells().map((cell, i) => {
|
|
128
|
+
const size = readDeclaredColumnSize(cell.column);
|
|
129
|
+
return (_jsx("div", { role: "cell", "aria-colindex": i + 1,
|
|
130
|
+
// An inline `flex` beats the class, so a sized column
|
|
131
|
+
// stops flexing while every other column renders
|
|
132
|
+
// exactly as it did before.
|
|
133
|
+
style: size?.width === undefined
|
|
134
|
+
? size
|
|
135
|
+
: { flex: '0 0 auto', ...size }, className: "flex-1 truncate px-4", children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id));
|
|
136
|
+
}) }, row.id));
|
|
110
137
|
}) }) })] }) }));
|
|
111
138
|
}
|
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* THE canonical quiet-label voice:
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* THE canonical quiet-label voice: sentence-case, one step down in size,
|
|
3
|
+
* medium weight, muted ink. Used by column heads, panel headings, key/value
|
|
4
|
+
* labels, captions — anywhere the console needs a quiet label.
|
|
5
|
+
*
|
|
6
|
+
* This is product-console's table-head voice, copied rather than invented. The
|
|
7
|
+
* kit's own `TableHead` paints `text-muted-foreground … font-medium` inside a
|
|
8
|
+
* `text-sm` `Table` (`components/ui/table/index.tsx:20,90`), and
|
|
9
|
+
* product-console renders every data table through that primitive
|
|
10
|
+
* (`src/components/table/data-table.tsx:14`). It replaced the retired "Ledger"
|
|
11
|
+
* voice — `text-[11px] uppercase tracking-[0.08em]` — which shouted a register
|
|
12
|
+
* no sibling console speaks.
|
|
6
13
|
*
|
|
7
14
|
* Do NOT re-state the cluster by hand; compose extra classes via
|
|
8
15
|
* `cn(LABEL_VOICE_CLASS, ...)`.
|
|
9
16
|
*/
|
|
10
|
-
export declare const LABEL_VOICE_CLASS = "text-
|
|
17
|
+
export declare const LABEL_VOICE_CLASS = "text-sm font-medium text-muted-foreground";
|
|
11
18
|
/**
|
|
12
19
|
* Alias of {@link LABEL_VOICE_CLASS} for section headings. Kept as a distinct
|
|
13
20
|
* name so section-level headings can diverge later without touching every
|
|
14
21
|
* quiet-label call site.
|
|
22
|
+
*
|
|
23
|
+
* It stays an alias on purpose. product-console's panel/section TITLE voice is
|
|
24
|
+
* `text-muted-foreground text-lg font-medium` (`EntityBoxHeaderTitle`,
|
|
25
|
+
* `components/entity-box/index.tsx:108`) — but that voice already ships as a
|
|
26
|
+
* component, and every live `SectionLabel` call site is a caption or a small
|
|
27
|
+
* heading (a stat-card label, an inline rate label), not an EntityBox-scale
|
|
28
|
+
* panel title. Promoting this constant to `text-lg` would duplicate a voice the
|
|
29
|
+
* kit already owns and inflate those captions.
|
|
15
30
|
*/
|
|
16
|
-
export declare const SECTION_LABEL_CLASS = "text-
|
|
31
|
+
export declare const SECTION_LABEL_CLASS = "text-sm font-medium text-muted-foreground";
|
|
17
32
|
//# sourceMappingURL=typography.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typography.d.ts","sourceRoot":"","sources":["../../../src/lib/typography.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"typography.d.ts","sourceRoot":"","sources":["../../../src/lib/typography.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB,8CAA8C,CAAA;AAE5E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,8CAAoB,CAAA"}
|
|
@@ -1,16 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* THE canonical quiet-label voice:
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* THE canonical quiet-label voice: sentence-case, one step down in size,
|
|
3
|
+
* medium weight, muted ink. Used by column heads, panel headings, key/value
|
|
4
|
+
* labels, captions — anywhere the console needs a quiet label.
|
|
5
|
+
*
|
|
6
|
+
* This is product-console's table-head voice, copied rather than invented. The
|
|
7
|
+
* kit's own `TableHead` paints `text-muted-foreground … font-medium` inside a
|
|
8
|
+
* `text-sm` `Table` (`components/ui/table/index.tsx:20,90`), and
|
|
9
|
+
* product-console renders every data table through that primitive
|
|
10
|
+
* (`src/components/table/data-table.tsx:14`). It replaced the retired "Ledger"
|
|
11
|
+
* voice — `text-[11px] uppercase tracking-[0.08em]` — which shouted a register
|
|
12
|
+
* no sibling console speaks.
|
|
6
13
|
*
|
|
7
14
|
* Do NOT re-state the cluster by hand; compose extra classes via
|
|
8
15
|
* `cn(LABEL_VOICE_CLASS, ...)`.
|
|
9
16
|
*/
|
|
10
|
-
export const LABEL_VOICE_CLASS = 'text-
|
|
17
|
+
export const LABEL_VOICE_CLASS = 'text-sm font-medium text-muted-foreground';
|
|
11
18
|
/**
|
|
12
19
|
* Alias of {@link LABEL_VOICE_CLASS} for section headings. Kept as a distinct
|
|
13
20
|
* name so section-level headings can diverge later without touching every
|
|
14
21
|
* quiet-label call site.
|
|
22
|
+
*
|
|
23
|
+
* It stays an alias on purpose. product-console's panel/section TITLE voice is
|
|
24
|
+
* `text-muted-foreground text-lg font-medium` (`EntityBoxHeaderTitle`,
|
|
25
|
+
* `components/entity-box/index.tsx:108`) — but that voice already ships as a
|
|
26
|
+
* component, and every live `SectionLabel` call site is a caption or a small
|
|
27
|
+
* heading (a stat-card label, an inline rate label), not an EntityBox-scale
|
|
28
|
+
* panel title. Promoting this constant to `text-lg` would duplicate a voice the
|
|
29
|
+
* kit already owns and inflate those captions.
|
|
15
30
|
*/
|
|
16
31
|
export const SECTION_LABEL_CLASS = LABEL_VOICE_CLASS;
|
package/dist/globals.css
CHANGED
|
@@ -138,27 +138,27 @@
|
|
|
138
138
|
--color-system-error-surface: hsl(var(--system-error-surface));
|
|
139
139
|
--color-system-error-h1a: hsl(var(--system-error-h1a));
|
|
140
140
|
--color-system-error-border: hsl(var(--system-error-border));
|
|
141
|
-
--color-system-error-text: hsl(var(--system-error-text)
|
|
141
|
+
--color-system-error-text: hsl(var(--system-error-text));
|
|
142
142
|
--color-system-success: hsl(var(--system-success));
|
|
143
143
|
--color-system-success-surface: hsl(var(--system-success-surface));
|
|
144
144
|
--color-system-success-h1a: hsl(var(--system-success-h1a));
|
|
145
145
|
--color-system-success-border: hsl(var(--system-success-border));
|
|
146
|
-
--color-system-success-text: hsl(var(--system-success-text)
|
|
146
|
+
--color-system-success-text: hsl(var(--system-success-text));
|
|
147
147
|
--color-system-info: hsl(var(--system-info));
|
|
148
148
|
--color-system-info-surface: hsl(var(--system-info-surface));
|
|
149
149
|
--color-system-info-h1a: hsl(var(--system-info-h1a));
|
|
150
150
|
--color-system-info-border: hsl(var(--system-info-border));
|
|
151
|
-
--color-system-info-text: hsl(var(--system-info-text)
|
|
151
|
+
--color-system-info-text: hsl(var(--system-info-text));
|
|
152
152
|
--color-system-alert: hsl(var(--system-alert));
|
|
153
153
|
--color-system-alert-surface: hsl(var(--system-alert-surface));
|
|
154
154
|
--color-system-alert-h1a: hsl(var(--system-alert-h1a));
|
|
155
155
|
--color-system-alert-border: hsl(var(--system-alert-border));
|
|
156
|
-
--color-system-alert-text: hsl(var(--system-alert-text)
|
|
156
|
+
--color-system-alert-text: hsl(var(--system-alert-text));
|
|
157
157
|
--color-system-purple: hsl(var(--system-purple));
|
|
158
158
|
--color-system-purple-surface: hsl(var(--system-purple-surface));
|
|
159
159
|
--color-system-purple-h1a: hsl(var(--system-purple-h1a));
|
|
160
160
|
--color-system-purple-border: hsl(var(--system-purple-border));
|
|
161
|
-
--color-system-purple-text: hsl(var(--system-purple-text)
|
|
161
|
+
--color-system-purple-text: hsl(var(--system-purple-text));
|
|
162
162
|
|
|
163
163
|
/* Ledger + reconciliation tokens */
|
|
164
164
|
--color-credit: hsl(var(--credit));
|
|
@@ -243,7 +243,14 @@
|
|
|
243
243
|
--muted-foreground: 240 5% 34%; /* base/600 = #52525B */
|
|
244
244
|
--accent: 56 99% 50%; /* #FEED02 (sunglow) */
|
|
245
245
|
--accent-foreground: 240 10% 4%; /* base/800 for contrast on yellow */
|
|
246
|
-
|
|
246
|
+
/*
|
|
247
|
+
Shadcn — Destructive. Darkened one step to red/600. red/500 under white
|
|
248
|
+
was 3.78:1, under AA, for both roles this token plays: the fill beneath
|
|
249
|
+
`--destructive-foreground` (the Critical badge, every destructive
|
|
250
|
+
button) and the plain body ink of a field/form error message on white.
|
|
251
|
+
red/600 lifts both to 4.80:1. The hue is unchanged; only the step moved.
|
|
252
|
+
*/
|
|
253
|
+
--destructive: 0 72% 51%; /* red/600 = #DC2626 */
|
|
247
254
|
--destructive-foreground: 0 0% 100%; /* white */
|
|
248
255
|
--border: 240 5% 90%; /* base/200 = #E4E4E7 */
|
|
249
256
|
--input: 0 0% 100%; /* base/white */
|
|
@@ -263,27 +270,27 @@
|
|
|
263
270
|
--system-error-surface: 0 86% 97%; /* red/50 = #FEF2F2 */
|
|
264
271
|
--system-error-h1a: 0 74% 35%; /* red/800 = #991B1B */
|
|
265
272
|
--system-error-border: 0 84% 60% / 0.5; /* #EF4444 50% */
|
|
266
|
-
--system-error-text: 0 74% 35%; /* #991B1B
|
|
273
|
+
--system-error-text: 0 74% 35%; /* #991B1B */
|
|
267
274
|
--system-success: 142 76% 36%; /* green/600 = #16A34A */
|
|
268
275
|
--system-success-surface: 139 76% 97%; /* green/50 = #F0FDF4 */
|
|
269
276
|
--system-success-h1a: 143 64% 24%; /* green/800 = #166534 */
|
|
270
277
|
--system-success-border: 142 76% 36% / 0.5; /* #16A34A 50% */
|
|
271
|
-
--system-success-text: 143 64% 24%; /* #166534
|
|
278
|
+
--system-success-text: 143 64% 24%; /* #166534 */
|
|
272
279
|
--system-info: 221 83% 53%; /* blue/600 = #2563EB */
|
|
273
280
|
--system-info-surface: 214 100% 97%; /* blue/50 = #EFF6FF */
|
|
274
281
|
--system-info-h1a: 224 76% 40%; /* blue/800 = #1E40AF */
|
|
275
282
|
--system-info-border: 221 83% 53% / 0.5; /* #2563EB 50% */
|
|
276
|
-
--system-info-text: 224 76% 40%; /* #1E40AF
|
|
283
|
+
--system-info-text: 224 76% 40%; /* #1E40AF */
|
|
277
284
|
--system-alert: 48 96% 47%; /* yellow/500 = #EAB308 */
|
|
278
285
|
--system-alert-surface: 55 92% 95%; /* yellow/50 = #FEFCE8 */
|
|
279
286
|
--system-alert-h1a: 36 92% 29%; /* yellow/800 = #854D0E */
|
|
280
287
|
--system-alert-border: 48 96% 47% / 0.5; /* #EAB308 50% */
|
|
281
|
-
--system-alert-text: 36 92% 29%; /* #854D0E
|
|
288
|
+
--system-alert-text: 36 92% 29%; /* #854D0E */
|
|
282
289
|
--system-purple: 271 81% 56%; /* purple/600 = #9333EA */
|
|
283
290
|
--system-purple-surface: 270 100% 98%; /* purple/50 = #FAF5FF */
|
|
284
291
|
--system-purple-h1a: 273 67% 39%; /* purple/800 = #6B21A8 */
|
|
285
292
|
--system-purple-border: 271 81% 56% / 0.5; /* #9333EA 50% */
|
|
286
|
-
--system-purple-text: 273 67% 39%; /* #6B21A8
|
|
293
|
+
--system-purple-text: 273 67% 39%; /* #6B21A8 */
|
|
287
294
|
|
|
288
295
|
/* Shadow color token for dark mode adaptation */
|
|
289
296
|
--shadow-color: 0 0% 0%;
|
|
@@ -377,35 +384,35 @@
|
|
|
377
384
|
/* Shadcn — System Error */
|
|
378
385
|
--system-error: 0 91% 71%; /* red/400 = #F87171 */
|
|
379
386
|
--system-error-surface: 0 75% 15%; /* red/950 = #450A0A */
|
|
380
|
-
--system-error-text: 0 94% 82%; /* red/300 = #FCA5A5
|
|
387
|
+
--system-error-text: 0 94% 82%; /* red/300 = #FCA5A5 */
|
|
381
388
|
--system-error-h1a: 0 96% 89%; /* red/200 = #FECACA */
|
|
382
389
|
--system-error-border: 0 94% 82% / 0.3; /* #FCA5A5 30% */
|
|
383
390
|
|
|
384
391
|
/* Shadcn — System Success */
|
|
385
392
|
--system-success: 142 69% 58%; /* green/400 = #4ADE80 */
|
|
386
393
|
--system-success-surface: 145 80% 10%; /* green/950 = #052E16 */
|
|
387
|
-
--system-success-text: 142 77% 73%; /* green/300 = #86EFAC
|
|
394
|
+
--system-success-text: 142 77% 73%; /* green/300 = #86EFAC */
|
|
388
395
|
--system-success-h1a: 141 79% 85%; /* green/200 = #BBF7D0 */
|
|
389
396
|
--system-success-border: 142 69% 58% / 0.3; /* #4ADE80 30% */
|
|
390
397
|
|
|
391
398
|
/* Shadcn — System Info */
|
|
392
399
|
--system-info: 213 94% 68%; /* blue/400 = #60A5FA */
|
|
393
400
|
--system-info-surface: 226 57% 21%; /* blue/950 = #172554 */
|
|
394
|
-
--system-info-text: 212 96% 78%; /* blue/300 = #93C5FD
|
|
401
|
+
--system-info-text: 212 96% 78%; /* blue/300 = #93C5FD */
|
|
395
402
|
--system-info-h1a: 213 97% 87%; /* blue/200 = #BFDBFE */
|
|
396
403
|
--system-info-border: 213 94% 68% / 0.3; /* #60A5FA 30% */
|
|
397
404
|
|
|
398
405
|
/* Shadcn — System Alert */
|
|
399
406
|
--system-alert: 48 96% 53%; /* yellow/400 = #FACC15 */
|
|
400
407
|
--system-alert-surface: 26 83% 14%; /* yellow/950 = #422006 */
|
|
401
|
-
--system-alert-text: 48 97% 77%; /* yellow/300 = #FDE68A
|
|
408
|
+
--system-alert-text: 48 97% 77%; /* yellow/300 = #FDE68A */
|
|
402
409
|
--system-alert-h1a: 53 98% 77%; /* yellow/200 = #FEF08A */
|
|
403
410
|
--system-alert-border: 48 96% 53% / 0.3; /* #FACC15 30% */
|
|
404
411
|
|
|
405
412
|
/* Shadcn — System Purple */
|
|
406
413
|
--system-purple: 270 95% 75%; /* purple/400 = #C084FC */
|
|
407
414
|
--system-purple-surface: 266 86% 13%; /* purple/950 = #3B0764 */
|
|
408
|
-
--system-purple-text: 269 97% 85%; /* purple/300 = #D8B4FE
|
|
415
|
+
--system-purple-text: 269 97% 85%; /* purple/300 = #D8B4FE */
|
|
409
416
|
--system-purple-h1a: 269 100% 92%; /* purple/200 = #E9D5FF */
|
|
410
417
|
--system-purple-border: 270 95% 75% / 0.3; /* #C084FC 30% */
|
|
411
418
|
|
|
@@ -604,3 +611,31 @@
|
|
|
604
611
|
mask: radial-gradient(21px 13px at 50% 102%, #0000 98%, #000) 50%
|
|
605
612
|
calc(100% - 16px) / 64px 100% repeat-x;
|
|
606
613
|
}
|
|
614
|
+
|
|
615
|
+
/*
|
|
616
|
+
Reduced-motion floor.
|
|
617
|
+
|
|
618
|
+
Every animated surface in the kit already carries a `motion-safe:` variant,
|
|
619
|
+
but that variant is a Tailwind utility: it only becomes
|
|
620
|
+
`@media (prefers-reduced-motion: no-preference)` after the CONSUMER compiles
|
|
621
|
+
Tailwind over the kit's dist. A consumer whose content globs miss a file, one
|
|
622
|
+
on an older kit, or one who writes `animate-in` in its own code gets no guard
|
|
623
|
+
at all — which is why `grep prefers-reduced-motion` over the shipped
|
|
624
|
+
stylesheet found nothing to point at.
|
|
625
|
+
|
|
626
|
+
This block is plain CSS with no variant and no build step between it and the
|
|
627
|
+
reader, and it ships verbatim (`copy:styles` copies every .css under src).
|
|
628
|
+
Animation
|
|
629
|
+
is dropped rather than shortened, so an overlay renders its final geometry
|
|
630
|
+
immediately; Radix reads a computed `animation-name: none` as "nothing to wait
|
|
631
|
+
for" and unmounts on close instead of hanging on an `animationend` that never
|
|
632
|
+
fires. Transitions are deliberately left alone: hover and focus affordances
|
|
633
|
+
are feedback, not motion effects.
|
|
634
|
+
*/
|
|
635
|
+
@media (prefers-reduced-motion: reduce) {
|
|
636
|
+
[class*='animate-'],
|
|
637
|
+
[data-state='open'],
|
|
638
|
+
[data-state='closed'] {
|
|
639
|
+
animation: none !important;
|
|
640
|
+
}
|
|
641
|
+
}
|
package/dist/lib/typography.d.ts
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* THE canonical quiet-label voice:
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* THE canonical quiet-label voice: sentence-case, one step down in size,
|
|
3
|
+
* medium weight, muted ink. Used by column heads, panel headings, key/value
|
|
4
|
+
* labels, captions — anywhere the console needs a quiet label.
|
|
5
|
+
*
|
|
6
|
+
* This is product-console's table-head voice, copied rather than invented. The
|
|
7
|
+
* kit's own `TableHead` paints `text-muted-foreground … font-medium` inside a
|
|
8
|
+
* `text-sm` `Table` (`components/ui/table/index.tsx:20,90`), and
|
|
9
|
+
* product-console renders every data table through that primitive
|
|
10
|
+
* (`src/components/table/data-table.tsx:14`). It replaced the retired "Ledger"
|
|
11
|
+
* voice — `text-[11px] uppercase tracking-[0.08em]` — which shouted a register
|
|
12
|
+
* no sibling console speaks.
|
|
6
13
|
*
|
|
7
14
|
* Do NOT re-state the cluster by hand; compose extra classes via
|
|
8
15
|
* `cn(LABEL_VOICE_CLASS, ...)`.
|
|
9
16
|
*/
|
|
10
|
-
export declare const LABEL_VOICE_CLASS = "text-
|
|
17
|
+
export declare const LABEL_VOICE_CLASS = "text-sm font-medium text-muted-foreground";
|
|
11
18
|
/**
|
|
12
19
|
* Alias of {@link LABEL_VOICE_CLASS} for section headings. Kept as a distinct
|
|
13
20
|
* name so section-level headings can diverge later without touching every
|
|
14
21
|
* quiet-label call site.
|
|
22
|
+
*
|
|
23
|
+
* It stays an alias on purpose. product-console's panel/section TITLE voice is
|
|
24
|
+
* `text-muted-foreground text-lg font-medium` (`EntityBoxHeaderTitle`,
|
|
25
|
+
* `components/entity-box/index.tsx:108`) — but that voice already ships as a
|
|
26
|
+
* component, and every live `SectionLabel` call site is a caption or a small
|
|
27
|
+
* heading (a stat-card label, an inline rate label), not an EntityBox-scale
|
|
28
|
+
* panel title. Promoting this constant to `text-lg` would duplicate a voice the
|
|
29
|
+
* kit already owns and inflate those captions.
|
|
15
30
|
*/
|
|
16
|
-
export declare const SECTION_LABEL_CLASS = "text-
|
|
31
|
+
export declare const SECTION_LABEL_CLASS = "text-sm font-medium text-muted-foreground";
|
|
17
32
|
//# sourceMappingURL=typography.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typography.d.ts","sourceRoot":"","sources":["../../src/lib/typography.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"typography.d.ts","sourceRoot":"","sources":["../../src/lib/typography.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB,8CAA8C,CAAA;AAE5E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,8CAAoB,CAAA"}
|
package/dist/lib/typography.js
CHANGED
|
@@ -2,18 +2,33 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SECTION_LABEL_CLASS = exports.LABEL_VOICE_CLASS = void 0;
|
|
4
4
|
/**
|
|
5
|
-
* THE canonical quiet-label voice:
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* THE canonical quiet-label voice: sentence-case, one step down in size,
|
|
6
|
+
* medium weight, muted ink. Used by column heads, panel headings, key/value
|
|
7
|
+
* labels, captions — anywhere the console needs a quiet label.
|
|
8
|
+
*
|
|
9
|
+
* This is product-console's table-head voice, copied rather than invented. The
|
|
10
|
+
* kit's own `TableHead` paints `text-muted-foreground … font-medium` inside a
|
|
11
|
+
* `text-sm` `Table` (`components/ui/table/index.tsx:20,90`), and
|
|
12
|
+
* product-console renders every data table through that primitive
|
|
13
|
+
* (`src/components/table/data-table.tsx:14`). It replaced the retired "Ledger"
|
|
14
|
+
* voice — `text-[11px] uppercase tracking-[0.08em]` — which shouted a register
|
|
15
|
+
* no sibling console speaks.
|
|
9
16
|
*
|
|
10
17
|
* Do NOT re-state the cluster by hand; compose extra classes via
|
|
11
18
|
* `cn(LABEL_VOICE_CLASS, ...)`.
|
|
12
19
|
*/
|
|
13
|
-
exports.LABEL_VOICE_CLASS = 'text-
|
|
20
|
+
exports.LABEL_VOICE_CLASS = 'text-sm font-medium text-muted-foreground';
|
|
14
21
|
/**
|
|
15
22
|
* Alias of {@link LABEL_VOICE_CLASS} for section headings. Kept as a distinct
|
|
16
23
|
* name so section-level headings can diverge later without touching every
|
|
17
24
|
* quiet-label call site.
|
|
25
|
+
*
|
|
26
|
+
* It stays an alias on purpose. product-console's panel/section TITLE voice is
|
|
27
|
+
* `text-muted-foreground text-lg font-medium` (`EntityBoxHeaderTitle`,
|
|
28
|
+
* `components/entity-box/index.tsx:108`) — but that voice already ships as a
|
|
29
|
+
* component, and every live `SectionLabel` call site is a caption or a small
|
|
30
|
+
* heading (a stat-card label, an inline rate label), not an EntityBox-scale
|
|
31
|
+
* panel title. Promoting this constant to `text-lg` would duplicate a voice the
|
|
32
|
+
* kit already owns and inflate those captions.
|
|
18
33
|
*/
|
|
19
34
|
exports.SECTION_LABEL_CLASS = exports.LABEL_VOICE_CLASS;
|