@kanzo-tech/ui 0.10.0 → 0.12.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/dist/charts/chart-stat.d.ts +12 -10
- package/dist/charts/chart-stat.d.ts.map +1 -1
- package/dist/charts/chart-stat.js +21 -16
- package/dist/charts/chart-stat.js.map +1 -1
- package/dist/composites/language-picker.d.ts +44 -0
- package/dist/composites/language-picker.d.ts.map +1 -0
- package/dist/composites/language-picker.js +163 -0
- package/dist/composites/language-picker.js.map +1 -0
- package/dist/guard-corpus.d.ts.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +693 -667
- package/dist/index.js.map +1 -1
- package/dist/layouts/empty.d.ts +54 -0
- package/dist/layouts/empty.d.ts.map +1 -0
- package/dist/layouts/empty.js +99 -0
- package/dist/layouts/empty.js.map +1 -0
- package/dist/layouts/gated.d.ts +24 -0
- package/dist/layouts/gated.d.ts.map +1 -0
- package/dist/layouts/gated.js +46 -0
- package/dist/layouts/gated.js.map +1 -0
- package/dist/layouts/section.d.ts +30 -5
- package/dist/layouts/section.d.ts.map +1 -1
- package/dist/layouts/section.js +71 -53
- package/dist/layouts/section.js.map +1 -1
- package/dist/lib/use-async-collection.d.ts +57 -0
- package/dist/lib/use-async-collection.d.ts.map +1 -0
- package/dist/lib/use-async-collection.js +43 -0
- package/dist/lib/use-async-collection.js.map +1 -0
- package/dist/lib/use-debounced-commit.d.ts +28 -0
- package/dist/lib/use-debounced-commit.d.ts.map +1 -0
- package/dist/lib/use-debounced-commit.js +26 -0
- package/dist/lib/use-debounced-commit.js.map +1 -0
- package/dist/shark-parity.divergences.d.ts.map +1 -1
- package/dist/simples/date-picker.d.ts.map +1 -1
- package/dist/simples/date-picker.js +66 -60
- package/dist/simples/date-picker.js.map +1 -1
- package/dist/simples/field.d.ts +42 -3
- package/dist/simples/field.d.ts.map +1 -1
- package/dist/simples/field.js +143 -105
- package/dist/simples/field.js.map +1 -1
- package/dist/simples/floating-panel.js +1 -1
- package/dist/simples/floating-panel.js.map +1 -1
- package/dist/simples/locale.d.ts +4 -0
- package/dist/simples/locale.d.ts.map +1 -0
- package/dist/simples/locale.js +8 -0
- package/dist/simples/locale.js.map +1 -0
- package/dist/simples/segment-group.d.ts.map +1 -1
- package/dist/simples/segment-group.js +67 -61
- package/dist/simples/segment-group.js.map +1 -1
- package/dist/simples/stat.d.ts +45 -0
- package/dist/simples/stat.d.ts.map +1 -0
- package/dist/simples/stat.js +155 -0
- package/dist/simples/stat.js.map +1 -0
- package/dist/table/actions-column.d.ts +20 -0
- package/dist/table/actions-column.d.ts.map +1 -0
- package/dist/table/actions-column.js +38 -0
- package/dist/table/actions-column.js.map +1 -0
- package/dist/table/data-table-content.d.ts.map +1 -1
- package/dist/table/data-table-content.js +31 -20
- package/dist/table/data-table-content.js.map +1 -1
- package/dist/table.d.ts +2 -0
- package/dist/table.d.ts.map +1 -1
- package/dist/table.js +13 -11
- package/dist/table.js.map +1 -1
- package/package.json +5 -5
- package/dist/simples/stat-tile.d.ts +0 -31
- package/dist/simples/stat-tile.d.ts.map +0 -1
- package/dist/simples/stat-tile.js +0 -64
- package/dist/simples/stat-tile.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-content.js","sources":["../../src/table/data-table-content.tsx"],"sourcesContent":["\"use client\";\n\nimport { flexRender } from \"@tanstack/react-table\";\nimport type React from \"react\";\nimport { cn } from \"../lib/cn.js\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableFooter,\n TableHead,\n TableHeader,\n TableRow,\n} from \"../simples/table.js\";\nimport { useDataTableContext } from \"./data-table-root.js\";\n\nexport interface DataTableContentProps<TData = unknown>\n extends Omit<React.ComponentProps<typeof Table>, \"children\"> {\n /** Shown in place of the body when there are no rows. */\n empty?: React.ReactNode;\n /** Row activation. Cells that stop propagation still win. */\n onRowClick?: (row: TData) => void;\n /** Applied to the bordered box; the remaining props reach the `<table>`. */\n className?: string;\n}\n\n/**\n * `clip` rather than `hidden`, but only when the header pins to the ENCLOSING region: `hidden`\n * makes this box a scroll container, so a sticky `th` would pin to it instead of to whatever\n * scrolls. `clip` still clips the rounded corners without being one, so the stickiness passes\n * through. Given a `maxHeight` the wrapper inside is the scroll container, and this box is back to\n * being nothing but a border.\n */\nconst boxOverflow = (regionScrolled: boolean) =>\n regionScrolled ? \"overflow-clip\" : \"overflow-hidden\";\n\n/**\n * ARIA contract for `onRowClick`: a `<tr>` is not an interactive role, so the row is made\n * reachable (`tabIndex=0`) and activatable (Enter/Space) rather than being a mouse-only\n * target. Activation is ignored when the key lands on a control inside the row, which keeps\n * a button or checkbox cell behaving as itself.\n */\nexport function DataTableContent<TData = unknown>(props: DataTableContentProps<TData>) {\n const {\n empty = \"No results.\",\n onRowClick,\n className,\n stickyHeader = false,\n maxHeight,\n ...rest\n } = props;\n const table = useDataTableContext<TData>();\n const regionScrolled = stickyHeader && maxHeight === undefined;\n\n const rows = table.getRowModel().rows;\n const colSpan = table.getVisibleLeafColumns().length || 1;\n const hasFooter = table\n .getFooterGroups()\n .some((group) => group.headers.some((header) => header.column.columnDef.footer));\n\n return (\n <div\n className={cn(boxOverflow(regionScrolled), \"rounded-lg border border-border\", className)}\n data-slot=\"data-table-content\"\n >\n <Table maxHeight={maxHeight} stickyHeader={stickyHeader} {...rest}>\n <TableHeader>\n {table.getHeaderGroups().map((group) => (\n <TableRow key={group.id}>\n {group.headers.map((header) => (\n <TableHead
|
|
1
|
+
{"version":3,"file":"data-table-content.js","sources":["../../src/table/data-table-content.tsx"],"sourcesContent":["\"use client\";\n\nimport { flexRender } from \"@tanstack/react-table\";\nimport type React from \"react\";\nimport { cn } from \"../lib/cn.js\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableFooter,\n TableHead,\n TableHeader,\n TableRow,\n} from \"../simples/table.js\";\nimport { useDataTableContext } from \"./data-table-root.js\";\n\nexport interface DataTableContentProps<TData = unknown>\n extends Omit<React.ComponentProps<typeof Table>, \"children\"> {\n /** Shown in place of the body when there are no rows. */\n empty?: React.ReactNode;\n /** Row activation. Cells that stop propagation still win. */\n onRowClick?: (row: TData) => void;\n /** Applied to the bordered box; the remaining props reach the `<table>`. */\n className?: string;\n}\n\n/**\n * `clip` rather than `hidden`, but only when the header pins to the ENCLOSING region: `hidden`\n * makes this box a scroll container, so a sticky `th` would pin to it instead of to whatever\n * scrolls. `clip` still clips the rounded corners without being one, so the stickiness passes\n * through. Given a `maxHeight` the wrapper inside is the scroll container, and this box is back to\n * being nothing but a border.\n */\nconst boxOverflow = (regionScrolled: boolean) =>\n regionScrolled ? \"overflow-clip\" : \"overflow-hidden\";\n\n/**\n * ARIA contract for `onRowClick`: a `<tr>` is not an interactive role, so the row is made\n * reachable (`tabIndex=0`) and activatable (Enter/Space) rather than being a mouse-only\n * target. Activation is ignored when the key lands on a control inside the row, which keeps\n * a button or checkbox cell behaving as itself.\n */\nexport function DataTableContent<TData = unknown>(props: DataTableContentProps<TData>) {\n const {\n empty = \"No results.\",\n onRowClick,\n className,\n stickyHeader = false,\n maxHeight,\n ...rest\n } = props;\n const table = useDataTableContext<TData>();\n const regionScrolled = stickyHeader && maxHeight === undefined;\n\n const rows = table.getRowModel().rows;\n const defaultSize = table._getDefaultColumnDef().size;\n const colSpan = table.getVisibleLeafColumns().length || 1;\n const hasFooter = table\n .getFooterGroups()\n .some((group) => group.headers.some((header) => header.column.columnDef.footer));\n\n return (\n <div\n className={cn(boxOverflow(regionScrolled), \"rounded-lg border border-border\", className)}\n data-slot=\"data-table-content\"\n >\n <Table maxHeight={maxHeight} stickyHeader={stickyHeader} {...rest}>\n <TableHeader>\n {table.getHeaderGroups().map((group) => (\n <TableRow key={group.id}>\n {group.headers.map((header) => (\n // Only a column that declares its own `size` gets a width. TanStack merges a\n // default of 150 into every column, and applying that would fix the whole table.\n <TableHead\n key={header.id}\n style={\n header.column.columnDef.size === defaultSize\n ? undefined\n : { width: header.getSize() }\n }\n >\n {header.isPlaceholder\n ? null\n : flexRender(header.column.columnDef.header, header.getContext())}\n </TableHead>\n ))}\n </TableRow>\n ))}\n </TableHeader>\n\n <TableBody>\n {rows.length ? (\n rows.map((row) => (\n <TableRow\n className={onRowClick ? \"cursor-pointer\" : undefined}\n data-state={row.getIsSelected() ? \"selected\" : undefined}\n key={row.id}\n onClick={onRowClick ? () => onRowClick(row.original) : undefined}\n onKeyDown={\n onRowClick\n ? (event) => {\n if (event.target !== event.currentTarget) return;\n if (event.key !== \"Enter\" && event.key !== \" \") return;\n event.preventDefault();\n onRowClick(row.original);\n }\n : undefined\n }\n tabIndex={onRowClick ? 0 : undefined}\n >\n {row.getVisibleCells().map((cell) => (\n <TableCell key={cell.id}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell\n className=\"h-24 whitespace-normal text-center text-muted-foreground\"\n colSpan={colSpan}\n >\n {empty}\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n\n {/* Only render a <tfoot> when a column actually defines a `footer` — TanStack's\n getFooterGroups() always returns groups, so an unguarded map would emit an empty\n footer row on every table. */}\n {hasFooter && (\n <TableFooter>\n {table.getFooterGroups().map((group) => (\n <TableRow key={group.id}>\n {group.headers.map((header) => (\n <TableCell key={header.id}>\n {header.isPlaceholder\n ? null\n : flexRender(header.column.columnDef.footer, header.getContext())}\n </TableCell>\n ))}\n </TableRow>\n ))}\n </TableFooter>\n )}\n </Table>\n </div>\n );\n}\n"],"names":[],"mappings":";;;;;;AAiCA;AASO;AACL;AAAM;AACI;AACR;AACA;AACe;AACf;AACG;AAYL;AACE;AAAC;AAAA;AACwF;AAC7E;AAGR;AAG0B;AAAA;AAAA;AAGlB;AAAC;AAAA;AAK+B;AAKoC;AAAA;AATtD;AAAA;AActB;AAKM;AAAC;AAAA;AAC4C;AACI;AAEQ;AAI/C;AAGuB;AAEzB;AAEqB;AAM1B;AAAA;AAlBQ;AAuBX;AAAC;AAAA;AACW;AACV;AAEC;AAAA;AAIT;AAkBE;AAEJ;AAAA;AAGN;;;;"}
|
package/dist/table.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export { DataTablePagination } from './table/data-table-pagination.js';
|
|
|
10
10
|
export type { DataTablePaginationProps } from './table/data-table-pagination.js';
|
|
11
11
|
export { selectColumn } from './table/select-column.js';
|
|
12
12
|
export type { SelectColumnOptions } from './table/select-column.js';
|
|
13
|
+
export { actionsColumn } from './table/actions-column.js';
|
|
14
|
+
export type { ActionsColumnOptions } from './table/actions-column.js';
|
|
13
15
|
export { sortableHeader } from './table/sortableHeader.js';
|
|
14
16
|
export type { CellContext, ColumnDef, HeaderContext, Row, Table, } from '@tanstack/react-table';
|
|
15
17
|
//# sourceMappingURL=table.d.ts.map
|
package/dist/table.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACxE,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAChF,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,YAAY,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACxE,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAChF,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,YAAY,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAItE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAK3D,YAAY,EACV,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,KAAK,GAClD,MAAM,uBAAuB,CAAC"}
|
package/dist/table.js
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { facetFilterFn as t, useDataTable as o } from "./table/use-data-table.js";
|
|
2
2
|
import { DataTableRoot as l, useDataTableContext as b } from "./table/data-table-root.js";
|
|
3
|
-
import { DataTableFacetFilter as
|
|
4
|
-
import { DataTableContent as
|
|
3
|
+
import { DataTableFacetFilter as n, DataTableSearch as T, DataTableToolbar as f, DataTableViewOptions as p } from "./table/data-table-toolbar.js";
|
|
4
|
+
import { DataTableContent as D } from "./table/data-table-content.js";
|
|
5
5
|
import { DataTablePagination as s } from "./table/data-table-pagination.js";
|
|
6
|
-
import { selectColumn as
|
|
7
|
-
import {
|
|
6
|
+
import { selectColumn as u } from "./table/select-column.js";
|
|
7
|
+
import { actionsColumn as F } from "./table/actions-column.js";
|
|
8
|
+
import { sortableHeader as g } from "./table/sortableHeader.js";
|
|
8
9
|
export {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
D as DataTableContent,
|
|
11
|
+
n as DataTableFacetFilter,
|
|
11
12
|
s as DataTablePagination,
|
|
12
13
|
l as DataTableRoot,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
T as DataTableSearch,
|
|
15
|
+
f as DataTableToolbar,
|
|
16
|
+
p as DataTableViewOptions,
|
|
17
|
+
F as actionsColumn,
|
|
16
18
|
t as facetFilterFn,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
u as selectColumn,
|
|
20
|
+
g as sortableHeader,
|
|
19
21
|
o as useDataTable,
|
|
20
22
|
b as useDataTableContext
|
|
21
23
|
};
|
package/dist/table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"table.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanzo-tech/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Kanzo shared UI — domain-free components over Ark UI and tailwind-variants, themed by tokens.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -95,8 +95,8 @@
|
|
|
95
95
|
"tailwind-merge": "^3.6.0",
|
|
96
96
|
"tailwind-variants": "^3.2.2",
|
|
97
97
|
"tw-animate-css": "^1.4.0",
|
|
98
|
-
"@kanzo-tech/mosaic": "0.
|
|
99
|
-
"@kanzo-tech/theme": "0.
|
|
98
|
+
"@kanzo-tech/mosaic": "0.12.0",
|
|
99
|
+
"@kanzo-tech/theme": "0.12.0"
|
|
100
100
|
},
|
|
101
101
|
"devDependencies": {
|
|
102
102
|
"@codemirror/autocomplete": "^6.18.6",
|
|
@@ -122,12 +122,12 @@
|
|
|
122
122
|
"rollup-plugin-preserve-directives": "^0.4.0",
|
|
123
123
|
"tailwindcss": "4"
|
|
124
124
|
},
|
|
125
|
-
"//size-limit": "Budgets OUR shipped code only. `ignore` mirrors the build's `external` list in vite.config.ts — anything externalised resolves from the consumer's node_modules, so counting it here measures the ecosystem, not us; keep the two lists in sync. Barrel measured at 35.27 kB brotlied, budget set just above so real growth trips the gate. The analytics budget (then spelled `charts`) went 4 kB -> 6 kB when the five preset charts became a composable grammar (measured 5.47 kB), then 6 kB -> 60 kB when ChartFilter/ChartSearch/ChartSlider brought Select, Combobox, Input, Field and Slider into the subpath (measured 56.01 kB). That last jump is mostly an artefact of measuring a subpath in isolation: in an app that also imports the root barrel those modules are the same files and dedupe, so the incremental cost is far smaller. The root barrel went 38 kB -> 42 kB (measured 40.66 kB) for the AI-assist compounds: real growth, and growth nobody downloads unless they import it. That is the point -- this gauge measures the WHOLE library, not what a consumer pays. The gauge that measures the latter is 'one component (tree-shaken)' below: Button resolves to 1.08 kB and three of our modules, with no trace of the AI code, so tree-shaking is doing its job. Treat this budget as a change detector for the library's total size and that one as the regression gate for consumer cost. Rebaselined 2026-07-31: analytics measured 66.30 kB against a stale 60 kB budget, so the gate was already red before the colour work touched it -- measured by removing that work's only addition to the subpath (`useThemeTick` reading the palette through the theme context), which moves the figure by 0.03 kB. The growth is somebody else's and is not attributed here, because the minified bundle does not say and a note that guessed would be worse than one that does not: what is recorded is the number and the fact that it predates this branch. Budget set to 68 kB, just above the measurement, so the next real growth trips it again. Rebaselined 2026-08-18: the root barrel went 42 kB -> 42.5 kB (measured 42.12 kB, against 41.54 kB at fb8e5b5) when the core's axes became a generated declaration the barrel carries -- the JSON is 302 B -> 648 B of it, brotlied on its own, and the rest is the one resolution chain. The other three gauges did not move at all, `one component` included, so no consumer of a component pays for it; see `/docs/design/colour` for the four figures and how to re-derive them. Measured again 2026-08-20, and NOT rebaselined: 42.12 kB -> 42.32 kB across one branch that took four modules OUT of the barrel (`complete`, `suggest`, `use-ai` and the `Suggestion` type left for @kanzo-tech/ai) and put two IN (`Diagnostic`, `Questionnaire`). Net +0.20 kB, which is the honest reading and the only one available: the two movements cannot be separated from a single minified bundle, and a note that guessed at the split would be worse than one that says it did not. The AI compounds' arrival is recorded above as 38 -> 42 kB, so their departure is worth about that much and the two new components spent it. Still under the 43 kB gate, so the gate is untouched.",
|
|
125
|
+
"//size-limit": "Budgets OUR shipped code only. `ignore` mirrors the build's `external` list in vite.config.ts — anything externalised resolves from the consumer's node_modules, so counting it here measures the ecosystem, not us; keep the two lists in sync. Barrel measured at 35.27 kB brotlied, budget set just above so real growth trips the gate. The analytics budget (then spelled `charts`) went 4 kB -> 6 kB when the five preset charts became a composable grammar (measured 5.47 kB), then 6 kB -> 60 kB when ChartFilter/ChartSearch/ChartSlider brought Select, Combobox, Input, Field and Slider into the subpath (measured 56.01 kB). That last jump is mostly an artefact of measuring a subpath in isolation: in an app that also imports the root barrel those modules are the same files and dedupe, so the incremental cost is far smaller. The root barrel went 38 kB -> 42 kB (measured 40.66 kB) for the AI-assist compounds: real growth, and growth nobody downloads unless they import it. That is the point -- this gauge measures the WHOLE library, not what a consumer pays. The gauge that measures the latter is 'one component (tree-shaken)' below: Button resolves to 1.08 kB and three of our modules, with no trace of the AI code, so tree-shaking is doing its job. Treat this budget as a change detector for the library's total size and that one as the regression gate for consumer cost. Rebaselined 2026-07-31: analytics measured 66.30 kB against a stale 60 kB budget, so the gate was already red before the colour work touched it -- measured by removing that work's only addition to the subpath (`useThemeTick` reading the palette through the theme context), which moves the figure by 0.03 kB. The growth is somebody else's and is not attributed here, because the minified bundle does not say and a note that guessed would be worse than one that does not: what is recorded is the number and the fact that it predates this branch. Budget set to 68 kB, just above the measurement, so the next real growth trips it again. Rebaselined 2026-08-18: the root barrel went 42 kB -> 42.5 kB (measured 42.12 kB, against 41.54 kB at fb8e5b5) when the core's axes became a generated declaration the barrel carries -- the JSON is 302 B -> 648 B of it, brotlied on its own, and the rest is the one resolution chain. The other three gauges did not move at all, `one component` included, so no consumer of a component pays for it; see `/docs/design/colour` for the four figures and how to re-derive them. Measured again 2026-08-20, and NOT rebaselined: 42.12 kB -> 42.32 kB across one branch that took four modules OUT of the barrel (`complete`, `suggest`, `use-ai` and the `Suggestion` type left for @kanzo-tech/ai) and put two IN (`Diagnostic`, `Questionnaire`). Net +0.20 kB, which is the honest reading and the only one available: the two movements cannot be separated from a single minified bundle, and a note that guessed at the split would be worse than one that says it did not. The AI compounds' arrival is recorded above as 38 -> 42 kB, so their departure is worth about that much and the two new components spent it. Still under the 43 kB gate, so the gate is untouched. Raised 2026-09-30, 43.5 kB -> 44 kB, as a decision (Ángel): the root barrel measured 43.57 kB after four issues from keasy landed in one day -- `FieldRequiredIndicator`'s `fallback` (+0.13 kB), the `Empty*` parts (+0.20), the `Stat*` compound that replaced `StatTile` and the copied `MetricCard` (+0.25) and the `Gated*` parts (+0.18). Three compounds the library did not have, each with its second call site in keasy, each replacing code keasy copied. `one component (tree-shaken)` did not move (1.26 kB), so no consumer of a component pays for them. Budget set just above the measurement so the next growth trips it again. Raised 2026-09-30, 44 kB -> 45.5 kB, as a decision (Ángel; branch `feat/form-primitives`): the barrel measured 45.09 kB after `LanguagePicker`, `useAsyncCollection`, `useDebouncedCommit`, the `Field` bridge on `DatePicker` and `SegmentGroup`, `FieldHelper`'s `tone`, `FieldGroup`'s `columns` and `LocaleProvider` landed together for a form generator that was carrying its own copies. `one component (tree-shaken)` did not move (1.26 kB), so no consumer of a component pays for them; analytics went 66.24 -> 67.13 kB and stays under its 68 kB.",
|
|
126
126
|
"size-limit": [
|
|
127
127
|
{
|
|
128
128
|
"name": "root barrel (JS)",
|
|
129
129
|
"path": "dist/index.js",
|
|
130
|
-
"limit": "
|
|
130
|
+
"limit": "45.5 kB",
|
|
131
131
|
"ignore": [
|
|
132
132
|
"react",
|
|
133
133
|
"react-dom",
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export interface StatTileDelta {
|
|
2
|
-
/** Signed change; its magnitude is shown, its sign + `goodWhenUp` pick the colour. */
|
|
3
|
-
value: number;
|
|
4
|
-
/** The comparison period, e.g. "vs last month". */
|
|
5
|
-
label?: string;
|
|
6
|
-
/**
|
|
7
|
-
* Unit for the magnitude — `"%"`, `"pp"`, `"ms"`, `"°C"`. Sits against the number, before the
|
|
8
|
-
* label, because "+8.2 vs last week" is a different claim from "+8.2% vs last week".
|
|
9
|
-
*/
|
|
10
|
-
unit?: string;
|
|
11
|
-
/** Whether an increase is good (green) or bad (red). Default `true`. */
|
|
12
|
-
goodWhenUp?: boolean;
|
|
13
|
-
}
|
|
14
|
-
export interface StatTileProps {
|
|
15
|
-
/** Sentence case, no trailing colon. */
|
|
16
|
-
label: string;
|
|
17
|
-
value: string | number;
|
|
18
|
-
/** Optional prefix for a numeric value, e.g. "$". */
|
|
19
|
-
prefix?: string;
|
|
20
|
-
delta?: StatTileDelta;
|
|
21
|
-
/** Optional ~12-point trend, drawn as a sparkline. */
|
|
22
|
-
trend?: readonly number[];
|
|
23
|
-
className?: string;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* A headline figure with its label, an optional signed delta and a trend sparkline — the form for
|
|
27
|
-
* when a single number, not a plot, is the answer (dataviz). The value uses proportional figures;
|
|
28
|
-
* the delta is a reserved status colour paired with a direction icon, never colour alone.
|
|
29
|
-
*/
|
|
30
|
-
export declare function StatTile({ label, value, prefix, delta, trend, className }: StatTileProps): import("react").JSX.Element;
|
|
31
|
-
//# sourceMappingURL=stat-tile.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stat-tile.d.ts","sourceRoot":"","sources":["../../src/simples/stat-tile.tsx"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,sDAAsD;IACtD,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8BD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,aAAa,+BA4CxF"}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { jsxs as c, jsx as n } from "react/jsx-runtime";
|
|
2
|
-
import { TrendingUpIcon as p, TrendingDownIcon as w } from "lucide-react";
|
|
3
|
-
import { cn as x } from "../lib/cn.js";
|
|
4
|
-
function f(t) {
|
|
5
|
-
return new Intl.NumberFormat("en-US", {
|
|
6
|
-
notation: Math.abs(t) >= 1e4 ? "compact" : "standard",
|
|
7
|
-
maximumFractionDigits: 1
|
|
8
|
-
}).format(t);
|
|
9
|
-
}
|
|
10
|
-
function N({ points: t }) {
|
|
11
|
-
const e = Math.min(...t), i = Math.max(...t) - e || 1, l = t.length > 1 ? 72 / (t.length - 1) : 72, o = t.map((d, u) => [u * l, 22 - (d - e) / i * 22]), m = o.map(([d, u], g) => `${g ? "L" : "M"}${d.toFixed(1)},${u.toFixed(1)}`).join(" "), a = o[o.length - 1] ?? [0, 0];
|
|
12
|
-
return /* @__PURE__ */ c("svg", { "aria-hidden": !0, className: "overflow-visible", height: 22, viewBox: "0 0 72 22", width: 72, children: [
|
|
13
|
-
/* @__PURE__ */ n(
|
|
14
|
-
"path",
|
|
15
|
-
{
|
|
16
|
-
className: "text-muted-foreground",
|
|
17
|
-
d: m,
|
|
18
|
-
fill: "none",
|
|
19
|
-
stroke: "currentColor",
|
|
20
|
-
strokeLinecap: "round",
|
|
21
|
-
strokeLinejoin: "round",
|
|
22
|
-
strokeWidth: 1.5
|
|
23
|
-
}
|
|
24
|
-
),
|
|
25
|
-
/* @__PURE__ */ n("circle", { className: "fill-primary", cx: a[0], cy: a[1], r: 2.5 })
|
|
26
|
-
] });
|
|
27
|
-
}
|
|
28
|
-
function k({ label: t, value: s, prefix: h, delta: e, trend: r, className: i }) {
|
|
29
|
-
const l = typeof s == "number" ? `${h ?? ""}${f(s)}` : s, o = e ? e.value >= 0 : !1, m = e ? o === (e.goodWhenUp ?? !0) : !1, a = o ? p : w;
|
|
30
|
-
return /* @__PURE__ */ c(
|
|
31
|
-
"div",
|
|
32
|
-
{
|
|
33
|
-
className: x("flex flex-col gap-1 rounded-xl border bg-card p-4 shadow-xs/5", i),
|
|
34
|
-
"data-slot": "stat-tile",
|
|
35
|
-
children: [
|
|
36
|
-
/* @__PURE__ */ n("span", { className: "text-muted-foreground text-sm", children: t }),
|
|
37
|
-
/* @__PURE__ */ c("div", { className: "flex items-end justify-between gap-3", children: [
|
|
38
|
-
/* @__PURE__ */ n("span", { className: "font-semibold text-2xl leading-none tracking-tight text-foreground", children: l }),
|
|
39
|
-
r && r.length > 1 && /* @__PURE__ */ n(N, { points: r })
|
|
40
|
-
] }),
|
|
41
|
-
e && /* @__PURE__ */ c(
|
|
42
|
-
"span",
|
|
43
|
-
{
|
|
44
|
-
className: x(
|
|
45
|
-
"flex items-center gap-1 text-xs font-medium",
|
|
46
|
-
m ? "text-success" : "text-destructive-foreground"
|
|
47
|
-
),
|
|
48
|
-
children: [
|
|
49
|
-
/* @__PURE__ */ n(a, { className: "size-3.5" }),
|
|
50
|
-
e.value > 0 ? "+" : "",
|
|
51
|
-
f(e.value),
|
|
52
|
-
e.unit,
|
|
53
|
-
e.label && /* @__PURE__ */ n("span", { className: "text-muted-foreground font-normal", children: e.label })
|
|
54
|
-
]
|
|
55
|
-
}
|
|
56
|
-
)
|
|
57
|
-
]
|
|
58
|
-
}
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
export {
|
|
62
|
-
k as StatTile
|
|
63
|
-
};
|
|
64
|
-
//# sourceMappingURL=stat-tile.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stat-tile.js","sources":["../../src/simples/stat-tile.tsx"],"sourcesContent":["import { TrendingDownIcon, TrendingUpIcon } from \"lucide-react\";\nimport { cn } from \"../lib/cn.js\";\n\n/** Auto-compact per the dataviz stat-tile contract: 1,284 · 12.9K · $4.2M. */\nfunction compact(v: number): string {\n return new Intl.NumberFormat(\"en-US\", {\n notation: Math.abs(v) >= 10000 ? \"compact\" : \"standard\",\n maximumFractionDigits: 1,\n }).format(v);\n}\n\nexport interface StatTileDelta {\n /** Signed change; its magnitude is shown, its sign + `goodWhenUp` pick the colour. */\n value: number;\n /** The comparison period, e.g. \"vs last month\". */\n label?: string;\n /**\n * Unit for the magnitude — `\"%\"`, `\"pp\"`, `\"ms\"`, `\"°C\"`. Sits against the number, before the\n * label, because \"+8.2 vs last week\" is a different claim from \"+8.2% vs last week\".\n */\n unit?: string;\n /** Whether an increase is good (green) or bad (red). Default `true`. */\n goodWhenUp?: boolean;\n}\n\nexport interface StatTileProps {\n /** Sentence case, no trailing colon. */\n label: string;\n value: string | number;\n /** Optional prefix for a numeric value, e.g. \"$\". */\n prefix?: string;\n delta?: StatTileDelta;\n /** Optional ~12-point trend, drawn as a sparkline. */\n trend?: readonly number[];\n className?: string;\n}\n\nfunction Sparkline({ points }: { points: readonly number[] }) {\n const w = 72;\n const h = 22;\n const min = Math.min(...points);\n const max = Math.max(...points);\n const range = max - min || 1;\n const step = points.length > 1 ? w / (points.length - 1) : w;\n const coords = points.map((p, i) => [i * step, h - ((p - min) / range) * h] as const);\n const d = coords.map(([x, y], i) => `${i ? \"L\" : \"M\"}${x.toFixed(1)},${y.toFixed(1)}`).join(\" \");\n const last = coords[coords.length - 1] ?? [0, 0];\n return (\n <svg aria-hidden className=\"overflow-visible\" height={h} viewBox={`0 0 ${w} ${h}`} width={w}>\n {/* A 1.5px trend line is a graphical object carrying information, so it owes 3:1. Diluted it\n measured 2.91:1 on the light page (3.33–3.35 in dark); step 11 solid is 9.19 and 8.52. */}\n <path\n className=\"text-muted-foreground\"\n d={d}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n />\n <circle className=\"fill-primary\" cx={last[0]} cy={last[1]} r={2.5} />\n </svg>\n );\n}\n\n/**\n * A headline figure with its label, an optional signed delta and a trend sparkline — the form for\n * when a single number, not a plot, is the answer (dataviz). The value uses proportional figures;\n * the delta is a reserved status colour paired with a direction icon, never colour alone.\n */\nexport function StatTile({ label, value, prefix, delta, trend, className }: StatTileProps) {\n const shown = typeof value === \"number\" ? `${prefix ?? \"\"}${compact(value)}` : value;\n const up = delta ? delta.value >= 0 : false;\n const good = delta ? up === (delta.goodWhenUp ?? true) : false;\n const DeltaIcon = up ? TrendingUpIcon : TrendingDownIcon;\n\n return (\n <div\n // **`Card`'s surface, at `Card`'s radius.** This read `rounded-lg` with no shadow — one step\n // below every panel in the library (`Card`, `Alert`, `Popover` and `HoverCard` are all\n // `rounded-xl`; `Dialog` and `Sheet` are `rounded-2xl`) and missing the lift they all carry.\n // Nothing argued for the difference; it is a component Shark has no file for, so the only\n // thing holding its appearance to the house was somebody remembering, and\n // `shark-parity.test.ts` compares names and never a class string.\n //\n // Still its own element rather than a composed `Card`: `Card` is an `<article>` on a 24px\n // `--space` with `gap-4`, and a tile is a 16px box with `gap-1`. Composing it would mean\n // overriding both, which is a heavier lie than sharing the three surface utilities.\n className={cn(\"flex flex-col gap-1 rounded-xl border bg-card p-4 shadow-xs/5\", className)}\n data-slot=\"stat-tile\"\n >\n <span className=\"text-muted-foreground text-sm\">{label}</span>\n <div className=\"flex items-end justify-between gap-3\">\n <span className=\"font-semibold text-2xl leading-none tracking-tight text-foreground\">\n {shown}\n </span>\n {trend && trend.length > 1 && <Sparkline points={trend} />}\n </div>\n {delta && (\n <span\n className={cn(\n \"flex items-center gap-1 text-xs font-medium\",\n good ? \"text-success\" : \"text-destructive-foreground\",\n )}\n >\n <DeltaIcon className=\"size-3.5\" />\n {delta.value > 0 ? \"+\" : \"\"}\n {compact(delta.value)}\n {delta.unit}\n {delta.label && <span className=\"text-muted-foreground font-normal\">{delta.label}</span>}\n </span>\n )}\n </div>\n );\n}\n"],"names":["compact","v","Sparkline","points","min","range","step","coords","p","i","d","x","y","last","jsxs","jsx","StatTile","label","value","prefix","delta","trend","className","shown","up","good","DeltaIcon","TrendingUpIcon","TrendingDownIcon","cn"],"mappings":";;;AAIA,SAASA,EAAQC,GAAmB;AAClC,SAAO,IAAI,KAAK,aAAa,SAAS;AAAA,IACpC,UAAU,KAAK,IAAIA,CAAC,KAAK,MAAQ,YAAY;AAAA,IAC7C,uBAAuB;AAAA,EAAA,CACxB,EAAE,OAAOA,CAAC;AACb;AA4BA,SAASC,EAAU,EAAE,QAAAC,KAAyC;AAG5D,QAAMC,IAAM,KAAK,IAAI,GAAGD,CAAM,GAExBE,IADM,KAAK,IAAI,GAAGF,CAAM,IACVC,KAAO,GACrBE,IAAOH,EAAO,SAAS,IAAI,MAAKA,EAAO,SAAS,KAAK,IACrDI,IAASJ,EAAO,IAAI,CAACK,GAAGC,MAAM,CAACA,IAAIH,GAAM,MAAME,IAAIJ,KAAOC,IAAS,EAAC,CAAU,GAC9EK,IAAIH,EAAO,IAAI,CAAC,CAACI,GAAGC,CAAC,GAAGH,MAAM,GAAGA,IAAI,MAAM,GAAG,GAAGE,EAAE,QAAQ,CAAC,CAAC,IAAIC,EAAE,QAAQ,CAAC,CAAC,EAAE,EAAE,KAAK,GAAG,GACzFC,IAAON,EAAOA,EAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC;AAC/C,SACE,gBAAAO,EAAC,OAAA,EAAI,eAAW,IAAC,WAAU,oBAAmB,QAAQ,IAAG,SAAS,aAAiB,OAAO,IAGxF,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,GAAAL;AAAA,QACA,MAAK;AAAA,QACL,QAAO;AAAA,QACP,eAAc;AAAA,QACd,gBAAe;AAAA,QACf,aAAa;AAAA,MAAA;AAAA,IAAA;AAAA,IAEf,gBAAAK,EAAC,UAAA,EAAO,WAAU,gBAAe,IAAIF,EAAK,CAAC,GAAG,IAAIA,EAAK,CAAC,GAAG,GAAG,IAAA,CAAK;AAAA,EAAA,GACrE;AAEJ;AAOO,SAASG,EAAS,EAAE,OAAAC,GAAO,OAAAC,GAAO,QAAAC,GAAQ,OAAAC,GAAO,OAAAC,GAAO,WAAAC,KAA4B;AACzF,QAAMC,IAAQ,OAAOL,KAAU,WAAW,GAAGC,KAAU,EAAE,GAAGnB,EAAQkB,CAAK,CAAC,KAAKA,GACzEM,IAAKJ,IAAQA,EAAM,SAAS,IAAI,IAChCK,IAAOL,IAAQI,OAAQJ,EAAM,cAAc,MAAQ,IACnDM,IAAYF,IAAKG,IAAiBC;AAExC,SACE,gBAAAd;AAAA,IAAC;AAAA,IAAA;AAAA,MAWC,WAAWe,EAAG,iEAAiEP,CAAS;AAAA,MACxF,aAAU;AAAA,MAEV,UAAA;AAAA,QAAA,gBAAAP,EAAC,QAAA,EAAK,WAAU,iCAAiC,UAAAE,GAAM;AAAA,QACvD,gBAAAH,EAAC,OAAA,EAAI,WAAU,wCACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sEACb,UAAAQ,GACH;AAAA,UACCF,KAASA,EAAM,SAAS,KAAK,gBAAAN,EAACb,GAAA,EAAU,QAAQmB,EAAA,CAAO;AAAA,QAAA,GAC1D;AAAA,QACCD,KACC,gBAAAN;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWe;AAAA,cACT;AAAA,cACAJ,IAAO,iBAAiB;AAAA,YAAA;AAAA,YAG1B,UAAA;AAAA,cAAA,gBAAAV,EAACW,GAAA,EAAU,WAAU,WAAA,CAAW;AAAA,cAC/BN,EAAM,QAAQ,IAAI,MAAM;AAAA,cACxBpB,EAAQoB,EAAM,KAAK;AAAA,cACnBA,EAAM;AAAA,cACNA,EAAM,SAAS,gBAAAL,EAAC,UAAK,WAAU,qCAAqC,YAAM,MAAA,CAAM;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACnF;AAAA,IAAA;AAAA,EAAA;AAIR;"}
|