@ai-matrx/design-system 0.49.54 → 0.49.56
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/CHANGELOG.md +16 -0
- package/dist/data-table/copy-helpers.d.cts +2 -2
- package/dist/data-table/copy-helpers.d.ts +2 -2
- package/dist/data-table/drill-chart.cjs +44 -6
- package/dist/data-table/drill-chart.cjs.map +1 -1
- package/dist/data-table/drill-chart.d.cts +8 -3
- package/dist/data-table/drill-chart.d.ts +8 -3
- package/dist/data-table/drill-chart.js +44 -6
- package/dist/data-table/drill-chart.js.map +1 -1
- package/dist/data-table/filter-engine.d.cts +2 -2
- package/dist/data-table/filter-engine.d.ts +2 -2
- package/dist/data-table/host.d.cts +2 -2
- package/dist/data-table/host.d.ts +2 -2
- package/dist/data-table/index.cjs +116 -40
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +28 -6
- package/dist/data-table/index.d.ts +28 -6
- package/dist/data-table/index.js +116 -40
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/infer-filter.d.cts +2 -2
- package/dist/data-table/infer-filter.d.ts +2 -2
- package/dist/data-table/layered-filters.d.cts +2 -2
- package/dist/data-table/layered-filters.d.ts +2 -2
- package/dist/data-table/query-control.d.cts +2 -2
- package/dist/data-table/query-control.d.ts +2 -2
- package/dist/data-table/types.d.cts +2 -2
- package/dist/data-table/types.d.ts +2 -2
- package/dist/data-table/url-state.d.cts +2 -2
- package/dist/data-table/url-state.d.ts +2 -2
- package/dist/data-table/xlsx.d.cts +2 -2
- package/dist/data-table/xlsx.d.ts +2 -2
- package/dist/{drill-cISpem5b.d.cts → drill-qJ5gHL2F.d.cts} +11 -0
- package/dist/{drill-cISpem5b.d.ts → drill-qJ5gHL2F.d.ts} +11 -0
- package/dist/{layered-filters-ma_P0GDG.d.ts → layered-filters-CTdPPgxf.d.ts} +1 -1
- package/dist/{layered-filters-RHe2Kzrs.d.cts → layered-filters-HFquDviC.d.cts} +1 -1
- package/dist/styles.css +5 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,10 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
### Unreleased
|
|
4
4
|
|
|
5
|
+
- **A desktop panel hosted in a bottom sheet gets 44px rows on a phone, not 36px** (W-72, PB-08 dry run, 2026-10-01). `.matrx-mobile-sheet .h-7` raised its `min-height` floor to `2.75rem` (was `2.25rem`). The rule is unlayered, so at 36px it also beat a host's layered 44px `matrx-touch-targets` floor — the chat-options sheet's Tools / Skills rows measured 36px on a phone. Proof: `styles.test.ts` "floors every mobile-sheet h-7 row" (red on HEAD). Consumer action: none.
|
|
6
|
+
|
|
7
|
+
- **The grouped answer shows a group's attributes at a glance, says what each number counts, sorts by a pivot column, and the chart stacks Measures** (lane DRILL-FLIP-FIXES, VERIFY-DRILL-FINAL R2, R5, L2, L3, L5 — the old Spend and users usage screens' last did-better rows, 2026-10-01). `MatrxDrillAnswerTable` takes `attributes` (`MatrxDrillAttribute`: text columns beside the numbers, each the one value an outermost group holds of another Dimension — the costliest requests' person, agent, model; `read` returns undefined while reading, null for none); a Measure's or a Dimension's `description` (≤140 characters) is its column header's tooltip; each named pivot column's header sorts the groups by its own cell (`drillPivotSortKey(measure, value)` = `across:<measure>:<value>`, read by `buildDrillTree`). `MatrxDrillChart` / `drillChartQuestions` take `stack` (two or more additive Measures drawn as one stacked bar per period, no split; a Measure that does not add up is refused in words; `MatrxDrillChartPlan.stack`). Proof: `drill-flip-fixes.test.tsx` (7; red on HEAD). Consumer action: none required; a host passes `attributes`, `description` and `stack` to adopt.
|
|
8
|
+
|
|
5
9
|
- **The grouped answer searches, opens a group's record, keeps a value's colour, and reads a moment** (lane DRILL-PARITY-LAST, the old users usage page's did-better rows, 2026-09-30). `MatrxDrillAnswerTable` takes `search` (a box that keeps the groups whose words hold the text — a person's email, a choice's words; an outer group stays when one of its own matches; "N of M groups"); a Dimension's `entity` (a record kind) makes each group row offer that record's own doors — open, preview and `TableDoors.menu` (new, the record kind's own menu items from the host's `resolveEntityDoors`) — in the row's ⋯ menu and on a right-click through the host's `ContextMenuBoundary` (rows carry `data-row-id`, the table its `data-matrx-table-id`); a Dimension's `colorFor` (a chart token, `drillTokenColor` / `drillValueColor`) colours that value's share bar and its chart series; a Measure's `moment` (e.g. "Last active", epoch ms) never shows a share or a change. Proof: `drill-parity-last.test.tsx` (9; 8 red on HEAD). Consumer action: none required; a host passes `search`, `entity`, `colorFor`, `moment` and `TableDoors.menu` to adopt.
|
|
6
10
|
- **The drill answer's coverage and Pareto lines are labels, not sentences** (lane DRILL-LIVE-FIXES, interface text is layout, 2026-09-30). Coverage reads `$100.00 of $400.00 (25%)` (was "This slice is $100.00 of the $400.00 the whole window holds (25%)."), with "This slice's share of the whole window" in its tooltip; a Pareto line that never reaches its share reads `All 5 shown make 20% of Cost` (the groups past the limit are already the table's own "N more" row). Proof: `drill-usage-adoptions.test.tsx`, `drill-pareto-and-row-actions.test.tsx`. Consumer action: none.
|
|
7
11
|
- **The drill chart's value axis says the number the Measure printed, never the raw value** (localhost walk of `/administration/usage`, 2026-09-30). When a Measure's format converts its unit (the usage explorer stores dollars and prints points at 20,000 a dollar) and the printed tick is too long for the axis, the tick used to compact the RAW value, so a 9,000,000-point day read `450` under "Cost (points) by day". `drillChartAxisNumber` now compacts the number the format printed (`9.0M`), keeping a one-character currency sign (`$1.2k`). Proof: `drill-chart-axis.test.ts`. Consumer action: none.
|
|
8
12
|
|
|
13
|
+
## 0.49.56
|
|
14
|
+
|
|
15
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
16
|
+
`git diff npm/design-system/v0.49.55..npm/design-system/v0.49.56 -- apps/shared/design-system`).
|
|
17
|
+
No source changes intended and no consumer action required.
|
|
18
|
+
|
|
19
|
+
## 0.49.55
|
|
20
|
+
|
|
21
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
22
|
+
`git diff npm/design-system/v0.49.54..npm/design-system/v0.49.55 -- apps/shared/design-system`).
|
|
23
|
+
No source changes intended and no consumer action required.
|
|
24
|
+
|
|
9
25
|
## 0.49.54
|
|
10
26
|
|
|
11
27
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgentPayloadInput } from './copy-types.cjs';
|
|
2
|
-
import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../layered-filters-
|
|
2
|
+
import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../layered-filters-HFquDviC.cjs';
|
|
3
3
|
import '../content-transfer.cjs';
|
|
4
4
|
import 'react';
|
|
5
5
|
import '@ai-matrx/kit/content-transfer';
|
|
@@ -7,7 +7,7 @@ import '../content-transfer/icon.cjs';
|
|
|
7
7
|
import './table-style.cjs';
|
|
8
8
|
import '../types-JnZD8wM0.cjs';
|
|
9
9
|
import './grouping.cjs';
|
|
10
|
-
import '../drill-
|
|
10
|
+
import '../drill-qJ5gHL2F.cjs';
|
|
11
11
|
import './fill.cjs';
|
|
12
12
|
import './facets.cjs';
|
|
13
13
|
import './spreadsheet.cjs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgentPayloadInput } from './copy-types.js';
|
|
2
|
-
import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../layered-filters-
|
|
2
|
+
import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../layered-filters-CTdPPgxf.js';
|
|
3
3
|
import '../content-transfer.js';
|
|
4
4
|
import 'react';
|
|
5
5
|
import '@ai-matrx/kit/content-transfer';
|
|
@@ -7,7 +7,7 @@ import '../content-transfer/icon.js';
|
|
|
7
7
|
import './table-style.js';
|
|
8
8
|
import '../types-JnZD8wM0.js';
|
|
9
9
|
import './grouping.js';
|
|
10
|
-
import '../drill-
|
|
10
|
+
import '../drill-qJ5gHL2F.js';
|
|
11
11
|
import './fill.js';
|
|
12
12
|
import './facets.js';
|
|
13
13
|
import './spreadsheet.js';
|
|
@@ -310,9 +310,16 @@ function drillChartQuestions(question, seriesLimit = MATRX_DRILL_CHART_SERIES_LI
|
|
|
310
310
|
const timeInBy = question.by.find((ref) => parseDimensionRef(ref).grain !== null);
|
|
311
311
|
const firstTime = context.dimensions.find((d) => d.kind === "time");
|
|
312
312
|
const time = timeInBy ?? context.time ?? (firstTime ? `${firstTime.key}:${drillAutoGrain(question.window ?? null, context.now, firstTime.grains ?? MATRX_DRILL_DEFAULT_GRAINS)}` : null);
|
|
313
|
-
const
|
|
313
|
+
const stack = context.stack && context.stack.length >= 2 ? [...context.stack] : null;
|
|
314
|
+
const split = stack ? null : question.by.find((ref) => parseDimensionRef(ref).grain === null && dimensionFor(context.dimensions, ref)?.kind !== "time") ?? null;
|
|
314
315
|
const refuse = (sentence) => ({ ...base, time, split, refused: sentence, first: [], periodsHint: null });
|
|
315
316
|
if (!time) return refuse("This answer has no time to chart it over.");
|
|
317
|
+
if (stack) {
|
|
318
|
+
const missing = stack.find((k) => !context.measures.some((m) => m.key === k));
|
|
319
|
+
if (missing) return refuse(`There is no Measure "${missing}" to chart.`);
|
|
320
|
+
const loose = stack.map((k) => context.measures.find((m) => m.key === k)).find((m) => !m.additive || m.moment);
|
|
321
|
+
if (loose) return refuse(`${loose.label} does not add up, so it cannot be stacked.`);
|
|
322
|
+
}
|
|
316
323
|
if (!measure) return refuse(`There is no Measure "${measureKey}" to chart.`);
|
|
317
324
|
if (split && !measure.additive) {
|
|
318
325
|
return refuse(
|
|
@@ -325,13 +332,13 @@ function drillChartQuestions(question, seriesLimit = MATRX_DRILL_CHART_SERIES_LI
|
|
|
325
332
|
const periodsHint = Number.isFinite(days) && days > 0 ? Math.ceil(days / GRAIN_DAYS[grain]) + 1 : null;
|
|
326
333
|
const where = trailWhere(question);
|
|
327
334
|
const window = question.window ?? null;
|
|
328
|
-
const show = [measureKey];
|
|
335
|
+
const show = stack ?? [measureKey];
|
|
329
336
|
const first = [];
|
|
330
337
|
if (split) {
|
|
331
338
|
first.push({ key: "series", by: [split], where, show, sort: { key: measureKey, direction: "desc" }, limit, window });
|
|
332
339
|
}
|
|
333
340
|
first.push({ key: "periods", by: [time], where, show, sort: null, limit: periodsHint ? clampLimit(periodsHint, ceiling) : null, window });
|
|
334
|
-
return { ...base, time, split, refused: null, first, periodsHint };
|
|
341
|
+
return { ...base, ...stack ? { measure: stack[0], stack } : {}, time, split, refused: null, first, periodsHint };
|
|
335
342
|
}
|
|
336
343
|
function drillChartCellsQuestion(plan, question, series) {
|
|
337
344
|
if (plan.refused || !plan.split || !plan.time) return null;
|
|
@@ -405,6 +412,35 @@ function drillChartData(plan, answers, dimensions, measures, emptyLabel = "No va
|
|
|
405
412
|
values: {}
|
|
406
413
|
};
|
|
407
414
|
});
|
|
415
|
+
if (plan.stack) {
|
|
416
|
+
const keys = plan.stack;
|
|
417
|
+
const readOf = (row, k) => {
|
|
418
|
+
const v = row?.measures[k];
|
|
419
|
+
return v === null || v === void 0 ? null : v;
|
|
420
|
+
};
|
|
421
|
+
const totalRow = periodRows.find((r) => rowKind(r) === "total");
|
|
422
|
+
for (const [i, p] of periodBase.entries()) {
|
|
423
|
+
const row = groups[i];
|
|
424
|
+
let sum = null;
|
|
425
|
+
for (const k of keys) {
|
|
426
|
+
const v = readOf(row, k);
|
|
427
|
+
p.values[`m:${k}`] = v;
|
|
428
|
+
if (v !== null) sum = (sum ?? 0) + v;
|
|
429
|
+
}
|
|
430
|
+
p.total = sum;
|
|
431
|
+
}
|
|
432
|
+
const totals = keys.map((k) => readOf(totalRow, k));
|
|
433
|
+
const total = totals.every((t) => t === null) ? null : totals.reduce((a, t) => a + (t ?? 0), 0);
|
|
434
|
+
return {
|
|
435
|
+
time,
|
|
436
|
+
split: null,
|
|
437
|
+
measure: m,
|
|
438
|
+
series: keys.map((k, i) => ({ key: `m:${k}`, value: null, label: measures.find((x) => x.key === k)?.label ?? k, other: false, total: totals[i] ?? null })),
|
|
439
|
+
periods: periodBase,
|
|
440
|
+
total,
|
|
441
|
+
says
|
|
442
|
+
};
|
|
443
|
+
}
|
|
408
444
|
if (!split) {
|
|
409
445
|
const key = "all";
|
|
410
446
|
for (const p of periodBase) p.values[key] = p.total;
|
|
@@ -531,6 +567,7 @@ function MatrxDrillChart({
|
|
|
531
567
|
answers,
|
|
532
568
|
seriesLimit = MATRX_DRILL_CHART_SERIES_LIMIT,
|
|
533
569
|
measure: measureKey,
|
|
570
|
+
stack,
|
|
534
571
|
time,
|
|
535
572
|
ceiling,
|
|
536
573
|
paths = NO_PATHS,
|
|
@@ -542,8 +579,8 @@ function MatrxDrillChart({
|
|
|
542
579
|
className
|
|
543
580
|
}) {
|
|
544
581
|
const plan = (0, import_react.useMemo)(
|
|
545
|
-
() => drillChartQuestions(question, seriesLimit, { dimensions, measures, measure: measureKey, time, ceiling }),
|
|
546
|
-
[question, seriesLimit, dimensions, measures, measureKey, time, ceiling]
|
|
582
|
+
() => drillChartQuestions(question, seriesLimit, { dimensions, measures, measure: measureKey, stack, time, ceiling }),
|
|
583
|
+
[question, seriesLimit, dimensions, measures, measureKey, stack, time, ceiling]
|
|
547
584
|
);
|
|
548
585
|
const data = (0, import_react.useMemo)(() => drillChartData(plan, answers, dimensions, measures, emptyLabel), [plan, answers, dimensions, measures, emptyLabel]);
|
|
549
586
|
const measure = measures.find((m) => m.key === plan.measure);
|
|
@@ -551,7 +588,8 @@ function MatrxDrillChart({
|
|
|
551
588
|
const [hover, setHover] = (0, import_react.useState)(null);
|
|
552
589
|
const segmentClicked = (0, import_react.useRef)(false);
|
|
553
590
|
const plotRef = (0, import_react.useRef)(null);
|
|
554
|
-
const
|
|
591
|
+
const measureWords = plan.stack ? plan.stack.map((k) => measures.find((m) => m.key === k)?.label ?? k).join(" and ") : measure?.label ?? plan.measure;
|
|
592
|
+
const title = plan.time ? `${measureWords} by ${dimensionRefLabel(dimensions, plan.time).replace(/^.* by /, "")}${plan.split ? `, split by ${dimensionRefLabel(dimensions, plan.split)}` : ""}` : measureWords;
|
|
555
593
|
const frame = (body) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { "data-matrx-drill-chart": true, "aria-label": title, className: cn("flex min-w-0 flex-col gap-1.5 px-2 py-2", className), children: [
|
|
556
594
|
note ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { "data-matrx-drill-chart-note": true, className: "text-xs text-muted-foreground", children: note }) : null,
|
|
557
595
|
body
|