@cosmicdrift/kumiko-renderer 0.399.0 → 0.401.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/app/entity-edit-prefill.js +7 -1
- package/dist/app/form-schema.js +42 -17
- package/dist/app/projection-detail-body.js +7 -0
- package/dist/app/projection-detail-header-model.d.ts +1 -1
- package/dist/app/projection-detail-header-model.js +2 -2
- package/dist/app/projection-detail-header-region.d.ts +1 -0
- package/dist/app/projection-detail-header-region.js +1 -1
- package/dist/app/projection-detail-header.js +4 -2
- package/dist/app/projection-detail-navigation.d.ts +1 -0
- package/dist/app/projection-detail-navigation.js +9 -1
- package/dist/app/use-related-list-tab-counts.d.ts +5 -0
- package/dist/app/use-related-list-tab-counts.js +68 -0
- package/dist/components/embedded-list-field.js +69 -91
- package/dist/components/embedded-list-paste.d.ts +2 -0
- package/dist/components/embedded-list-paste.js +73 -0
- package/dist/components/related-list-section.js +4 -8
- package/dist/components/render-edit-helpers.js +2 -2
- package/dist/components/render-field-choice-inputs.js +1 -1
- package/dist/components/use-reference-column-lookups.d.ts +6 -0
- package/dist/components/use-reference-column-lookups.js +36 -0
- package/dist/components/use-render-list-columns.d.ts +2 -3
- package/dist/components/use-render-list-columns.js +4 -31
- package/dist/embedded-list-types.d.ts +117 -0
- package/dist/embedded-list-types.js +1 -0
- package/dist/headless/form/form-controller.js +9 -1
- package/dist/headless/index.d.ts +1 -1
- package/dist/headless/index.js +1 -1
- package/dist/headless/view-model/edit.js +40 -50
- package/dist/headless/view-model/embedded-list-cells.d.ts +12 -0
- package/dist/headless/view-model/embedded-list-cells.js +49 -0
- package/dist/headless/view-model/embedded-list.d.ts +1 -1
- package/dist/headless/view-model/embedded-list.js +1 -1
- package/dist/headless/view-model/index.d.ts +1 -1
- package/dist/headless/view-model/index.js +1 -1
- package/dist/headless/view-model/list.js +2 -3
- package/dist/headless/view-model/types.d.ts +23 -6
- package/dist/hooks/related-list-parent-payload.d.ts +2 -0
- package/dist/hooks/related-list-parent-payload.js +7 -0
- package/dist/i18n-defaults.js +3 -0
- package/dist/primitives.d.ts +4 -88
- package/dist/web/app/dashboard-body.js +3 -3
- package/dist/web/app/dashboard-panels.d.ts +2 -1
- package/dist/web/app/dashboard-panels.js +11 -3
- package/dist/web/app/dashboard-reference-list-table.d.ts +17 -0
- package/dist/web/app/dashboard-reference-list-table.js +47 -0
- package/dist/web/lib/file-upload-form-data.d.ts +2 -0
- package/dist/web/lib/file-upload-form-data.js +2 -0
- package/dist/web/lib/upload-file-ref.d.ts +1 -1
- package/dist/web/primitives/data-table-cell.d.ts +2 -0
- package/dist/web/primitives/data-table-cell.js +1 -1
- package/dist/web/primitives/embedded-file-cell.d.ts +11 -0
- package/dist/web/primitives/embedded-file-cell.js +50 -0
- package/dist/web/primitives/embedded-list-cards.d.ts +38 -0
- package/dist/web/primitives/embedded-list-cards.js +71 -0
- package/dist/web/primitives/embedded-list-cell.d.ts +41 -0
- package/dist/web/primitives/embedded-list-cell.js +132 -0
- package/dist/web/primitives/embedded-list-input.d.ts +1 -1
- package/dist/web/primitives/embedded-list-input.js +29 -142
- package/dist/web/primitives/file-upload.d.ts +2 -1
- package/dist/web/primitives/file-upload.js +2 -1
- package/dist/web/primitives/input-choice-kinds.js +1 -1
- package/dist/web/primitives/input-optional-props.d.ts +2 -1
- package/dist/web/primitives/input-optional-props.js +2 -1
- package/dist/web/primitives/locale-number.d.ts +3 -0
- package/dist/web/primitives/locale-number.js +8 -0
- package/dist/web/primitives/number-input.d.ts +2 -1
- package/dist/web/primitives/number-input.js +4 -11
- package/dist/web/primitives/segmented-select.d.ts +6 -1
- package/dist/web/primitives/segmented-select.js +8 -4
- package/dist/web/widgets/dashboard-list.d.ts +2 -0
- package/dist/web/widgets/dashboard-list.js +2 -0
- package/dist/web/widgets/status-badge.d.ts +1 -0
- package/dist/web/widgets/status-badge.js +1 -1
- package/package.json +5 -5
- package/src/changes.json +6 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useRef } from "react";
|
|
3
|
+
import { statusToneForOptionTone } from "../../index.js";
|
|
3
4
|
import { cn } from "../lib/cn.js";
|
|
5
|
+
import { TONE_PILL } from "../widgets/status-badge.js";
|
|
4
6
|
const EQUAL_WIDTH_MAX_SEGMENTS = 4;
|
|
5
7
|
// WAI-ARIA radiogroup pattern (role="radiogroup" + role="radio" children):
|
|
6
8
|
// arrow keys move focus AND selection in the same step, only the checked
|
|
7
9
|
// segment (or the first when none is checked) sits in the tab order.
|
|
8
|
-
export function SegmentedControl({ id, name, value, onChange, options, disabled, required, hasError, labelProps, }) {
|
|
10
|
+
export function SegmentedControl({ id, name, value, onChange, options, disabled, required, hasError, labelProps, tones, size, }) {
|
|
9
11
|
const buttonRefs = useRef([]);
|
|
10
12
|
// An unknown/legacy value checks no segment; the first one must still be tabbable.
|
|
11
13
|
const selectedIndex = options.findIndex((opt) => opt.value === value);
|
|
@@ -41,8 +43,10 @@ export function SegmentedControl({ id, name, value, onChange, options, disabled,
|
|
|
41
43
|
// their segment instead of leaving one tall and its siblings short.
|
|
42
44
|
options.length <= EQUAL_WIDTH_MAX_SEGMENTS
|
|
43
45
|
? "inline-grid max-w-full grid-flow-col auto-cols-fr"
|
|
44
|
-
: "inline-flex w-fit flex-wrap", "min-h-9 overflow-hidden rounded-md border", hasError === true ? "border-destructive" : "border-input"), children: [_jsx("input", { type: "hidden", name: name, value: value }), options.map((opt, index) => {
|
|
46
|
+
: "inline-flex w-fit flex-wrap", size === "touch" ? "min-h-11" : "min-h-9", "overflow-hidden rounded-md border", hasError === true ? "border-destructive" : "border-input"), children: [_jsx("input", { type: "hidden", name: name, value: value }), options.map((opt, index) => {
|
|
45
47
|
const checked = opt.value === value;
|
|
48
|
+
const declaredTone = tones !== undefined && Object.hasOwn(tones, opt.value) ? tones[opt.value] : undefined;
|
|
49
|
+
const badgeTone = declaredTone !== undefined ? statusToneForOptionTone(declaredTone) : undefined;
|
|
46
50
|
return (_jsx("button", { ref: (node) => {
|
|
47
51
|
buttonRefs.current[index] = node;
|
|
48
52
|
}, type: "button", role: "radio", "aria-checked": checked, tabIndex: index === tabStopIndex ? 0 : -1, disabled: disabled === true || opt.disabled === true, "data-testid": `segmented-${id}-${opt.value}`, onClick: () => onChange(opt.value), onKeyDown: (e) => handleKeyDown(e, index), className: cn(
|
|
@@ -61,8 +65,8 @@ export function SegmentedControl({ id, name, value, onChange, options, disabled,
|
|
|
61
65
|
// and the next row's top border cut a notch into the row above.
|
|
62
66
|
// Harmless on a single-row layout: there's no leftover space to
|
|
63
67
|
// grow into, so `w-fit` on the container still holds.
|
|
64
|
-
"-ml-px -mt-px grow border-l border-t px-3 py-1.5 text-center text-sm transition-colors", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50", hasError === true ? "border-destructive/50" : "border-border", checked
|
|
65
|
-
? "bg-primary/10
|
|
68
|
+
"-ml-px -mt-px grow border-l border-t px-3 py-1.5 text-center text-sm transition-colors", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50", hasError === true ? "border-destructive/50" : "border-border", size === "touch" && "min-h-11", checked
|
|
69
|
+
? cn("font-semibold", badgeTone !== undefined ? TONE_PILL[badgeTone] : "bg-primary/10 text-primary")
|
|
66
70
|
: "bg-transparent font-medium text-foreground hover:bg-accent"), children: opt.label }, opt.value));
|
|
67
71
|
})] }));
|
|
68
72
|
}
|
|
@@ -5,6 +5,8 @@ export type DashboardListColumn = {
|
|
|
5
5
|
readonly label: string;
|
|
6
6
|
readonly display?: "bar" | "badge" | "datetime";
|
|
7
7
|
readonly badgeToneField?: string;
|
|
8
|
+
/** Resolves the raw cell value to display text, e.g. a reference id to its label. */
|
|
9
|
+
readonly renderValue?: (value: unknown, row: Readonly<Record<string, unknown>>) => string;
|
|
8
10
|
};
|
|
9
11
|
type Row = Readonly<Record<string, unknown>>;
|
|
10
12
|
/** Compact 40px-row table for dashboard lists with optional bar/badge
|
|
@@ -31,6 +31,8 @@ function Cell({ column, row, formatPercent, formatNumber, formatDateTime, transl
|
|
|
31
31
|
return EMPTY_VALUE_PLACEHOLDER;
|
|
32
32
|
return _jsx("span", { className: "tabular-nums", children: formatDateTime(atMs) });
|
|
33
33
|
}
|
|
34
|
+
if (column.renderValue !== undefined)
|
|
35
|
+
return column.renderValue(raw, row);
|
|
34
36
|
if (typeof raw === "number")
|
|
35
37
|
return _jsx("span", { className: "tabular-nums", children: formatNumber(raw) });
|
|
36
38
|
if (raw === undefined || raw === null || raw === "")
|
|
@@ -4,6 +4,7 @@ export declare const STATUS_TONE_TEXT: Record<StatusTone, string>;
|
|
|
4
4
|
/** `accent` is a brand-colored call-out (e.g. "3 suggestions"), not a status —
|
|
5
5
|
* hence not part of `StatusTone`, which toasts and select options share. */
|
|
6
6
|
export type StatusBadgeTone = StatusTone | "accent";
|
|
7
|
+
export declare const TONE_PILL: Record<StatusBadgeTone, string>;
|
|
7
8
|
/** Pill badge with a status dot. Caller maps domain values to a tone
|
|
8
9
|
* (e.g. operational→ok, investigating→warn) and passes the translated
|
|
9
10
|
* label as children. */
|
|
@@ -8,7 +8,7 @@ export const STATUS_TONE_TEXT = {
|
|
|
8
8
|
muted: "text-muted-foreground",
|
|
9
9
|
};
|
|
10
10
|
// `muted` maps to the neutral tokens, not a status-* palette.
|
|
11
|
-
const TONE_PILL = {
|
|
11
|
+
export const TONE_PILL = {
|
|
12
12
|
accent: "bg-primary/10 text-primary",
|
|
13
13
|
ok: "bg-status-ok-surface text-status-ok",
|
|
14
14
|
warn: "bg-status-warn-surface text-status-warn",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.401.0",
|
|
4
4
|
"description": "React renderer for Kumiko screens. The root export holds the platform-agnostic logic (primitives contract, hooks, KumikoScreen, navigation and SSE abstractions); ./headless the DOM-free UI logic, ./live the HTTP dispatcher, ./web the browser bindings (HTML primitives, history navigation, EventSource live events, createKumikoApp).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
52
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
51
|
+
"@cosmicdrift/kumiko-framework": "0.401.0",
|
|
52
|
+
"@cosmicdrift/kumiko-types": "0.401.0",
|
|
53
53
|
"@types/qrcode": "^1.5.5",
|
|
54
54
|
"class-variance-authority": "^0.7.1",
|
|
55
55
|
"clsx": "^2.1.1",
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@cosmicdrift/kumiko-locale-de": "0.
|
|
83
|
-
"@cosmicdrift/kumiko-testing": "0.
|
|
82
|
+
"@cosmicdrift/kumiko-locale-de": "0.401.0",
|
|
83
|
+
"@cosmicdrift/kumiko-testing": "0.401.0",
|
|
84
84
|
"@tailwindcss/cli": "^4.3.3",
|
|
85
85
|
"@testing-library/react": "^16.3.3",
|
|
86
86
|
"@testing-library/user-event": "^14.6.8",
|
package/src/changes.json
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.401.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "Dashboard list panels show the target's label for reference columns",
|
|
6
|
+
"detail": "A reference column in a dashboard list panel showed the stored id. It now resolves the target record's label and links to it, using the same lookup as entity lists."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.399.0",
|
|
4
10
|
"type": "improvement",
|