@declarion/react 0.1.93 → 0.2.1

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.
Files changed (34) hide show
  1. package/dist-lib/DraggableChildrenTable-C5cpmctN.js +261 -0
  2. package/dist-lib/DraggableChildrenTable-C5cpmctN.js.map +1 -0
  3. package/dist-lib/components/detail-layout/AssociatedBlock.d.ts +1 -0
  4. package/dist-lib/components/detail-layout/ChildrenBlock.d.ts +2 -1
  5. package/dist-lib/components/detail-layout/DetailAuditStrip.d.ts +13 -0
  6. package/dist-lib/components/detail-layout/DetailHighlights.d.ts +15 -0
  7. package/dist-lib/components/detail-layout/ErrorSummary.d.ts +11 -0
  8. package/dist-lib/components/detail-layout/FieldRow.d.ts +21 -0
  9. package/dist-lib/components/detail-layout/LayoutRenderer.d.ts +2 -0
  10. package/dist-lib/components/detail-layout/blockMeta.d.ts +4 -0
  11. package/dist-lib/components/detail-layout/index.d.ts +4 -0
  12. package/dist-lib/components/fields/JsonField.d.ts +1 -0
  13. package/dist-lib/components/fields/cells/factories/emptyCell.d.ts +2 -0
  14. package/dist-lib/components/primitives/SectionCard.d.ts +6 -1
  15. package/dist-lib/components/primitives/dataTableStyles.d.ts +4 -0
  16. package/dist-lib/components/primitives/index.d.ts +1 -1
  17. package/dist-lib/components/shared/AuditMetaStrip.d.ts +11 -0
  18. package/dist-lib/components/shared/HighlightsStrip.d.ts +10 -0
  19. package/dist-lib/components/shared/RecordHeader.d.ts +15 -0
  20. package/dist-lib/components/shared/StatusStepper.d.ts +13 -0
  21. package/dist-lib/components/shared/toast/DeclarionToast.d.ts +31 -0
  22. package/dist-lib/{useUserLocale-GBIXbEE6.js → dataTableStyles-DiIApmjb.js} +1669 -1570
  23. package/dist-lib/dataTableStyles-DiIApmjb.js.map +1 -0
  24. package/dist-lib/declarion-react.css +1 -1
  25. package/dist-lib/index.js +6247 -5179
  26. package/dist-lib/index.js.map +1 -1
  27. package/dist-lib/lib/child-config.d.ts +1 -1
  28. package/dist-lib/lib/toast.d.ts +49 -16
  29. package/dist-lib/stores/appearance.d.ts +3 -0
  30. package/dist-lib/types/schema.d.ts +21 -3
  31. package/package.json +1 -1
  32. package/dist-lib/DraggableChildrenTable-IfspXSFA.js +0 -281
  33. package/dist-lib/DraggableChildrenTable-IfspXSFA.js.map +0 -1
  34. package/dist-lib/useUserLocale-GBIXbEE6.js.map +0 -1
@@ -0,0 +1,261 @@
1
+ import { Qt as e, Xt as t, Zt as n, a as r, ft as i, i as a, n as o, r as s, t as c } from "./dataTableStyles-DiIApmjb.js";
2
+ import { useCallback as l, useMemo as u, useRef as d } from "react";
3
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
4
+ import { DndContext as m, PointerSensor as h, closestCenter as g, useSensor as _, useSensors as v } from "@dnd-kit/core";
5
+ import { SortableContext as y, useSortable as b, verticalListSortingStrategy as x } from "@dnd-kit/sortable";
6
+ import { CSS as S } from "@dnd-kit/utilities";
7
+ //#region src/components/detail-layout/DraggableChildrenTable.tsx
8
+ function C({ config: t, childEntity: r, schema: a, rows: c, onChange: b, validationErrors: S, refs: C }) {
9
+ let T = d(null), E = t.position_field, D = t.columns, O = v(_(h, { activationConstraint: { distance: 5 } })), k = new Set(Array.isArray(t.foreign_key) ? t.foreign_key : [t.foreign_key]), A = D.filter((e) => {
10
+ if (k.has(e) || e === E) return !1;
11
+ let t = r.fields.get(e);
12
+ return !(!t || t.auto || t.primary);
13
+ }), j = new Set(D.filter((e) => {
14
+ if (e === E) return !0;
15
+ let t = r.fields.get(e);
16
+ return t && (t.auto || t.primary);
17
+ })), M = D.filter((e) => e !== E), N = u(() => c.filter((e) => !e._deleted).map((e) => e._key), [c]), P = l((e, t, n) => {
18
+ b(c.map((r) => r._key === e ? {
19
+ ...r,
20
+ [t]: n,
21
+ _dirty: !0
22
+ } : r));
23
+ }, [c, b]), F = l(() => {
24
+ let e = c.filter((e) => !e._deleted).reduce((e, t) => {
25
+ let n = typeof t[E] == "number" ? t[E] : -1;
26
+ return Math.max(e, n);
27
+ }, -1), n = {
28
+ _key: crypto.randomUUID(),
29
+ _dirty: !0,
30
+ [E]: e + 1
31
+ }, i = t.quick_add?.defaults ?? {};
32
+ for (let e of A) {
33
+ let t = r.fields.get(e);
34
+ t && (i[e] === void 0 ? t.default === void 0 ? t.type === "bool" && (n[e] = !1) : n[e] = t.default : n[e] = i[e]);
35
+ }
36
+ b([...c, n]);
37
+ }, [
38
+ c,
39
+ b,
40
+ A,
41
+ r,
42
+ t.quick_add?.defaults,
43
+ E
44
+ ]), I = l((e) => {
45
+ b(c.map((t) => t._key === e ? {
46
+ ...t,
47
+ _deleted: !0
48
+ } : t));
49
+ }, [c, b]), L = l((e) => {
50
+ b(c.map((t) => t._key === e ? {
51
+ ...t,
52
+ _deleted: !1
53
+ } : t));
54
+ }, [c, b]), R = l((e) => {
55
+ let { active: t, over: n } = e;
56
+ if (!n || t.id === n.id) return;
57
+ let r = c.filter((e) => !e._deleted), i = c.filter((e) => e._deleted), a = r.findIndex((e) => e._key === String(t.id)), o = r.findIndex((e) => e._key === String(n.id));
58
+ if (a === -1 || o === -1) return;
59
+ let s = [...r], [l] = s.splice(a, 1);
60
+ s.splice(o, 0, l), b([...s.map((e, t) => ({
61
+ ...e,
62
+ [E]: t,
63
+ _dirty: e[E] === t ? e._dirty : !0
64
+ })), ...i]);
65
+ }, [
66
+ c,
67
+ b,
68
+ E
69
+ ]), z = l((e) => {
70
+ let t = e.target, n = t.closest("td");
71
+ if (!n) return;
72
+ let r = n.closest("tr");
73
+ if (!r) return;
74
+ let i = r.closest("tbody");
75
+ if (!i) return;
76
+ let a = Array.from(r.cells).indexOf(n), o = Array.from(i.rows).indexOf(r);
77
+ if (e.key === "Tab") {
78
+ let t = e.shiftKey ? -1 : 1, n = Array.from(i.rows), r = o, s = a + t;
79
+ for (; r >= 0 && r < n.length;) if (s >= 0 && s < n[r].cells.length) {
80
+ let i = n[r].cells[s].querySelector("input, select, textarea, [tabindex]");
81
+ if (i) {
82
+ e.preventDefault(), i.focus();
83
+ return;
84
+ }
85
+ s += t;
86
+ } else r += t, s = t > 0 ? 0 : (n[r]?.cells.length ?? 1) - 1;
87
+ } else if (e.key === "Enter") {
88
+ e.preventDefault();
89
+ let t = Array.from(i.rows);
90
+ if (o < t.length - 1) {
91
+ let e = t[o + 1].cells[a]?.querySelector("input, select, textarea, [tabindex]");
92
+ e && e.focus();
93
+ } else F(), requestAnimationFrame(() => {
94
+ let e = i.querySelectorAll("tr"), t = e[e.length - 1];
95
+ if (t) {
96
+ let e = t.querySelector("input, select, textarea, [tabindex]");
97
+ e && e.focus();
98
+ }
99
+ });
100
+ } else e.key === "Escape" && t.blur?.();
101
+ }, [F]), B = o;
102
+ return /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("div", {
103
+ style: { overflowX: "auto" },
104
+ children: /* @__PURE__ */ f(m, {
105
+ sensors: O,
106
+ collisionDetection: g,
107
+ onDragEnd: R,
108
+ children: /* @__PURE__ */ p("table", {
109
+ ref: T,
110
+ style: s,
111
+ onKeyDown: z,
112
+ children: [/* @__PURE__ */ f("thead", { children: /* @__PURE__ */ p("tr", { children: [
113
+ /* @__PURE__ */ f("th", { style: {
114
+ ...B,
115
+ width: 32,
116
+ padding: "0 4px"
117
+ } }),
118
+ M.map((e) => {
119
+ let t = r.fields.get(e);
120
+ return /* @__PURE__ */ f("th", {
121
+ style: B,
122
+ children: t ? i(t, e, a.entities) : e
123
+ }, e);
124
+ }),
125
+ /* @__PURE__ */ f("th", { style: {
126
+ ...B,
127
+ width: 40
128
+ } })
129
+ ] }) }), /* @__PURE__ */ f(y, {
130
+ items: N,
131
+ strategy: x,
132
+ children: /* @__PURE__ */ f("tbody", { children: c.map((e) => /* @__PURE__ */ f(w, {
133
+ row: e,
134
+ columns: M,
135
+ editableColumns: A,
136
+ displayOnlyColumns: j,
137
+ childEntity: r,
138
+ validationErrors: S,
139
+ refs: C,
140
+ onCellChange: P,
141
+ onDelete: I,
142
+ onUndoDelete: L
143
+ }, e._key)) })
144
+ })]
145
+ })
146
+ })
147
+ }), /* @__PURE__ */ f("div", {
148
+ style: { marginTop: 8 },
149
+ children: /* @__PURE__ */ f(n, {
150
+ kind: "ghost",
151
+ size: "xs",
152
+ icon: /* @__PURE__ */ f(e.plus, { size: 12 }),
153
+ onClick: F,
154
+ children: "Add row"
155
+ })
156
+ })] });
157
+ }
158
+ function w({ row: n, columns: i, editableColumns: o, displayOnlyColumns: s, childEntity: l, validationErrors: u, refs: d, onCellChange: m, onDelete: h, onUndoDelete: g }) {
159
+ let _ = a(), v = !!n._deleted, y = u?.[n._key], { attributes: x, listeners: C, setNodeRef: w, transform: T, transition: E, isDragging: D } = b({
160
+ id: n._key,
161
+ disabled: v
162
+ }), O = {
163
+ transform: S.Translate.toString(T),
164
+ transition: E,
165
+ zIndex: D ? 10 : void 0,
166
+ opacity: D ? .5 : void 0
167
+ }, k = c, A = {
168
+ padding: "4px 4px",
169
+ borderBottom: "1px solid var(--divider)",
170
+ verticalAlign: "middle"
171
+ };
172
+ return /* @__PURE__ */ p("tr", {
173
+ ref: w,
174
+ style: {
175
+ ...O,
176
+ opacity: v ? .5 : O?.opacity ?? 1
177
+ },
178
+ children: [
179
+ /* @__PURE__ */ f("td", {
180
+ style: {
181
+ padding: "4px 4px",
182
+ borderBottom: "1px solid var(--divider)",
183
+ width: 32,
184
+ verticalAlign: "middle"
185
+ },
186
+ children: !v && /* @__PURE__ */ f("button", {
187
+ type: "button",
188
+ style: {
189
+ cursor: "grab",
190
+ padding: 4,
191
+ color: "var(--text-3)",
192
+ background: "transparent",
193
+ border: 0,
194
+ display: "inline-flex"
195
+ },
196
+ ...x,
197
+ ...C,
198
+ children: /* @__PURE__ */ f(e.grid, { size: 14 })
199
+ })
200
+ }),
201
+ i.map((e) => {
202
+ let t = l.fields.get(e), i = y?.includes(e), a = s.has(e), c = o.includes(e);
203
+ return v || a || !c ? /* @__PURE__ */ f("td", {
204
+ style: {
205
+ ...k,
206
+ textDecoration: v ? "line-through" : "none"
207
+ },
208
+ children: t ? r({
209
+ field: t,
210
+ fieldName: e,
211
+ value: n[e],
212
+ mode: "display",
213
+ record: n,
214
+ refs: d,
215
+ locale: _
216
+ }) : String(n[e] ?? "")
217
+ }, e) : /* @__PURE__ */ f("td", {
218
+ style: {
219
+ ...A,
220
+ outline: i ? "1px solid var(--danger)" : "none",
221
+ outlineOffset: -1,
222
+ borderRadius: i ? 4 : 0
223
+ },
224
+ title: i ? `${e} is required` : void 0,
225
+ children: t ? r({
226
+ field: t,
227
+ fieldName: e,
228
+ value: n[e],
229
+ mode: "edit",
230
+ onChange: (t) => m(n._key, e, t),
231
+ record: n,
232
+ refs: d,
233
+ locale: _
234
+ }) : String(n[e] ?? "")
235
+ }, e);
236
+ }),
237
+ /* @__PURE__ */ f("td", {
238
+ style: {
239
+ padding: "4px 8px",
240
+ borderBottom: "1px solid var(--divider)",
241
+ verticalAlign: "middle"
242
+ },
243
+ children: v ? /* @__PURE__ */ f(t, {
244
+ size: 24,
245
+ icon: /* @__PURE__ */ f(e.refresh, { size: 12 }),
246
+ onClick: () => g(n._key),
247
+ title: "Undo delete"
248
+ }) : /* @__PURE__ */ f(t, {
249
+ size: 24,
250
+ icon: /* @__PURE__ */ f(e.trash, { size: 12 }),
251
+ onClick: () => h(n._key),
252
+ title: "Delete row"
253
+ })
254
+ })
255
+ ]
256
+ });
257
+ }
258
+ //#endregion
259
+ export { C as DraggableChildrenTable };
260
+
261
+ //# sourceMappingURL=DraggableChildrenTable-C5cpmctN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DraggableChildrenTable-C5cpmctN.js","names":[],"sources":["../src/components/detail-layout/DraggableChildrenTable.tsx"],"sourcesContent":["import { useCallback, useMemo, useRef } from \"react\";\nimport {\n DndContext,\n closestCenter,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from \"@dnd-kit/core\";\nimport {\n SortableContext,\n verticalListSortingStrategy,\n useSortable,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { Btn, Icon, IconBtn } from \"@/components/primitives\";\nimport {\n dataTableStyle,\n dataTableHeadCellStyle,\n dataTableCellStyle,\n} from \"@/components/primitives/dataTableStyles\";\nimport { fieldDisplayName } from \"@/types/schema\";\nimport type { Entity, Schema } from \"@/types/schema\";\nimport { renderField } from \"@/components/fields\";\nimport type { RefsMap } from \"@/components/fields\";\nimport { useUserLocale } from \"@/hooks/useUserLocale\";\nimport type { PendingChildRow } from \"./LayoutRenderer\";\nimport type { ResolvedChildConfig } from \"@/lib/child-config\";\n\ninterface DraggableChildrenTableProps {\n config: ResolvedChildConfig;\n childEntity: Entity;\n schema: Schema;\n rows: PendingChildRow[];\n onChange: (rows: PendingChildRow[]) => void;\n validationErrors?: Record<string, string[]>;\n refs?: RefsMap;\n}\n\n// DraggableChildrenTable renders child rows with drag handles for reordering.\n// Used when position_field is configured on a child relation.\nexport function DraggableChildrenTable({\n config,\n childEntity,\n schema,\n rows,\n onChange,\n validationErrors,\n refs,\n}: DraggableChildrenTableProps) {\n const tableRef = useRef<HTMLTableElement>(null);\n const positionField = config.position_field!;\n const columns = config.columns;\n\n // distance: 5 separates click from drag.\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n );\n\n // Editable columns: exclude FK, auto, primary, and position_field.\n const fkSet = new Set(Array.isArray(config.foreign_key) ? config.foreign_key : [config.foreign_key]);\n const editableColumns = columns.filter((col) => {\n if (fkSet.has(col)) return false;\n if (col === positionField) return false;\n const field = childEntity.fields.get(col);\n if (!field) return false;\n if (field.auto || field.primary) return false;\n return true;\n });\n\n // Display-only columns (auto/primary but visible in column list, or position_field).\n const displayOnlyColumns = new Set(\n columns.filter((col) => {\n if (col === positionField) return true;\n const field = childEntity.fields.get(col);\n return field && (field.auto || field.primary);\n }),\n );\n\n // Visible columns: exclude position_field from display since it's managed by drag.\n const visibleColumns = columns.filter((col) => col !== positionField);\n\n // Row IDs for SortableContext - only non-deleted rows participate in drag.\n const rowIds = useMemo(\n () => rows.filter((r) => !r._deleted).map((r) => r._key),\n [rows],\n );\n\n const handleCellChange = useCallback(\n (rowKey: string, fieldName: string, value: unknown) => {\n const updated = rows.map((row) =>\n row._key === rowKey\n ? { ...row, [fieldName]: value, _dirty: true }\n : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleAddRow = useCallback(() => {\n const maxPosition = rows\n .filter((r) => !r._deleted)\n .reduce((max, r) => {\n const pos = typeof r[positionField] === \"number\" ? (r[positionField] as number) : -1;\n return Math.max(max, pos);\n }, -1);\n\n const newRow: PendingChildRow = {\n _key: crypto.randomUUID(),\n _dirty: true,\n [positionField]: maxPosition + 1,\n };\n // Pre-fill from quick_add.defaults first, then field-level defaults.\n const quickDefaults = config.quick_add?.defaults ?? {};\n for (const col of editableColumns) {\n const field = childEntity.fields.get(col);\n if (!field) continue;\n if (quickDefaults[col] !== undefined) {\n newRow[col] = quickDefaults[col];\n } else if (field.default !== undefined) {\n newRow[col] = field.default;\n } else if (field.type === \"bool\") {\n newRow[col] = false;\n }\n }\n onChange([...rows, newRow]);\n }, [rows, onChange, editableColumns, childEntity, config.quick_add?.defaults, positionField]);\n\n const handleDeleteRow = useCallback(\n (rowKey: string) => {\n const updated = rows.map((row) =>\n row._key === rowKey ? { ...row, _deleted: true } : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleUndoDelete = useCallback(\n (rowKey: string) => {\n const updated = rows.map((row) =>\n row._key === rowKey ? { ...row, _deleted: false } : row,\n );\n onChange(updated);\n },\n [rows, onChange],\n );\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n if (!over || active.id === over.id) return;\n\n // Reorder non-deleted rows.\n const nonDeleted = rows.filter((r) => !r._deleted);\n const deleted = rows.filter((r) => r._deleted);\n\n const oldIndex = nonDeleted.findIndex((r) => r._key === String(active.id));\n const newIndex = nonDeleted.findIndex((r) => r._key === String(over.id));\n if (oldIndex === -1 || newIndex === -1) return;\n\n // Move the row.\n const reordered = [...nonDeleted];\n const [moved] = reordered.splice(oldIndex, 1);\n reordered.splice(newIndex, 0, moved);\n\n // Re-assign sequential position values and mark dirty only if position changed.\n const withPositions = reordered.map((row, index) => ({\n ...row,\n [positionField]: index,\n _dirty: row[positionField] !== index ? true : row._dirty,\n }));\n\n // Append deleted rows at the end (they'll be excluded from payload).\n onChange([...withPositions, ...deleted]);\n },\n [rows, onChange, positionField],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTableElement>) => {\n const target = e.target as HTMLElement;\n const cell = target.closest(\"td\");\n if (!cell) return;\n const row = cell.closest(\"tr\");\n if (!row) return;\n const tbody = row.closest(\"tbody\");\n if (!tbody) return;\n\n const cellIndex = Array.from(row.cells).indexOf(cell as HTMLTableCellElement);\n const rowIndex = Array.from(tbody.rows).indexOf(row as HTMLTableRowElement);\n\n if (e.key === \"Tab\") {\n const direction = e.shiftKey ? -1 : 1;\n const allRows = Array.from(tbody.rows);\n let nextRow = rowIndex;\n let nextCell = cellIndex + direction;\n\n while (nextRow >= 0 && nextRow < allRows.length) {\n if (nextCell >= 0 && nextCell < allRows[nextRow].cells.length) {\n const nextTd = allRows[nextRow].cells[nextCell];\n const input = nextTd.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (input) {\n e.preventDefault();\n input.focus();\n return;\n }\n nextCell += direction;\n } else {\n nextRow += direction;\n nextCell = direction > 0 ? 0 : (allRows[nextRow]?.cells.length ?? 1) - 1;\n }\n }\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n const allRows = Array.from(tbody.rows);\n if (rowIndex < allRows.length - 1) {\n const nextTd = allRows[rowIndex + 1].cells[cellIndex];\n const input = nextTd?.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (input) input.focus();\n } else {\n handleAddRow();\n requestAnimationFrame(() => {\n const newRows = tbody.querySelectorAll(\"tr\");\n const lastRow = newRows[newRows.length - 1];\n if (lastRow) {\n const firstInput = lastRow.querySelector(\"input, select, textarea, [tabindex]\") as HTMLElement | null;\n if (firstInput) firstInput.focus();\n }\n });\n }\n } else if (e.key === \"Escape\") {\n (target as HTMLElement).blur?.();\n }\n },\n [handleAddRow],\n );\n\n // Shared table chrome - see primitives/dataTableStyles.ts.\n const thStyle = dataTableHeadCellStyle;\n\n return (\n <div>\n <div style={{ overflowX: \"auto\" }}>\n <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>\n <table\n ref={tableRef}\n style={dataTableStyle}\n onKeyDown={handleKeyDown}\n >\n <thead>\n <tr>\n <th style={{ ...thStyle, width: 32, padding: \"0 4px\" }} />\n {visibleColumns.map((col) => {\n const field = childEntity.fields.get(col);\n return (\n <th key={col} style={thStyle}>\n {field ? fieldDisplayName(field, col, schema.entities) : col}\n </th>\n );\n })}\n <th style={{ ...thStyle, width: 40 }} />\n </tr>\n </thead>\n <SortableContext items={rowIds} strategy={verticalListSortingStrategy}>\n <tbody>\n {rows.map((row) => (\n <SortableRow\n key={row._key}\n row={row}\n columns={visibleColumns}\n editableColumns={editableColumns}\n displayOnlyColumns={displayOnlyColumns}\n childEntity={childEntity}\n validationErrors={validationErrors}\n refs={refs}\n onCellChange={handleCellChange}\n onDelete={handleDeleteRow}\n onUndoDelete={handleUndoDelete}\n />\n ))}\n </tbody>\n </SortableContext>\n </table>\n </DndContext>\n </div>\n <div style={{ marginTop: 8 }}>\n <Btn kind=\"ghost\" size=\"xs\" icon={<Icon.plus size={12} />} onClick={handleAddRow}>\n Add row\n </Btn>\n </div>\n </div>\n );\n}\n\n// SortableRow wraps a table row with drag-and-drop support.\ninterface SortableRowProps {\n row: PendingChildRow;\n columns: string[];\n editableColumns: string[];\n displayOnlyColumns: Set<string>;\n childEntity: Entity;\n validationErrors?: Record<string, string[]>;\n refs?: RefsMap;\n onCellChange: (rowKey: string, fieldName: string, value: unknown) => void;\n onDelete: (rowKey: string) => void;\n onUndoDelete: (rowKey: string) => void;\n}\n\nfunction SortableRow({\n row,\n columns,\n editableColumns,\n displayOnlyColumns,\n childEntity,\n validationErrors,\n refs,\n onCellChange,\n onDelete,\n onUndoDelete,\n}: SortableRowProps) {\n const userLocale = useUserLocale();\n const isDeleted = !!row._deleted;\n const rowErrors = validationErrors?.[row._key];\n\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: row._key, disabled: isDeleted });\n\n const style = {\n transform: CSS.Translate.toString(transform),\n transition,\n zIndex: isDragging ? 10 : undefined,\n opacity: isDragging ? 0.5 : undefined,\n };\n\n const cellStyle = dataTableCellStyle;\n const editCellStyle: React.CSSProperties = {\n padding: \"4px 4px\",\n borderBottom: \"1px solid var(--divider)\",\n verticalAlign: \"middle\",\n };\n\n return (\n <tr ref={setNodeRef} style={{ ...style, opacity: isDeleted ? 0.5 : style?.opacity ?? 1 }}>\n <td style={{ padding: \"4px 4px\", borderBottom: \"1px solid var(--divider)\", width: 32, verticalAlign: \"middle\" }}>\n {!isDeleted && (\n <button\n type=\"button\"\n style={{\n cursor: \"grab\",\n padding: 4,\n color: \"var(--text-3)\",\n background: \"transparent\",\n border: 0,\n display: \"inline-flex\",\n }}\n {...attributes}\n {...listeners}\n >\n <Icon.grid size={14} />\n </button>\n )}\n </td>\n {columns.map((col) => {\n const field = childEntity.fields.get(col);\n const hasError = rowErrors?.includes(col);\n const isDisplayOnly = displayOnlyColumns.has(col);\n const isEditable = editableColumns.includes(col);\n\n if (isDeleted || isDisplayOnly || !isEditable) {\n return (\n <td\n key={col}\n style={{\n ...cellStyle,\n textDecoration: isDeleted ? \"line-through\" : \"none\",\n }}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"display\",\n record: row as Record<string, unknown>,\n refs,\n locale: userLocale,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n }\n\n return (\n <td\n key={col}\n style={{\n ...editCellStyle,\n outline: hasError ? \"1px solid var(--danger)\" : \"none\",\n outlineOffset: -1,\n borderRadius: hasError ? 4 : 0,\n }}\n title={hasError ? `${col} is required` : undefined}\n >\n {field\n ? renderField({\n field,\n fieldName: col,\n value: row[col],\n mode: \"edit\",\n onChange: (val) => onCellChange(row._key, col, val),\n record: row as Record<string, unknown>,\n refs,\n locale: userLocale,\n })\n : String(row[col] ?? \"\")}\n </td>\n );\n })}\n <td style={{ padding: \"4px 8px\", borderBottom: \"1px solid var(--divider)\", verticalAlign: \"middle\" }}>\n {isDeleted ? (\n <IconBtn\n size={24}\n icon={<Icon.refresh size={12} />}\n onClick={() => onUndoDelete(row._key)}\n title=\"Undo delete\"\n />\n ) : (\n <IconBtn\n size={24}\n icon={<Icon.trash size={12} />}\n onClick={() => onDelete(row._key)}\n title=\"Delete row\"\n />\n )}\n </td>\n </tr>\n );\n}\n"],"mappings":"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"}
@@ -15,5 +15,6 @@ export declare function resolveAssociatedToolbarActions(actions: Record<string,
15
15
  export declare function resolveAssociatedForeignKey(entities: Record<string, Entity>, parentEntityCode: string, assocCode: string): string | null;
16
16
  export declare function associatedEditableColumns(entity: Entity, columns: string[], foreignKey: string): Set<string>;
17
17
  export declare function associatedDraftEditableColumns(entity: Entity, columns: string[], foreignKey: string): Set<string>;
18
+ export declare function findMissingRequiredAssociatedFields(values: Record<string, unknown>, columns: string[], entity: Entity, foreignKey: string): string[];
18
19
  export declare function AssociatedBlock({ node, ctx }: AssociatedBlockProps): import("react/jsx-runtime").JSX.Element | null;
19
20
  export {};
@@ -1,3 +1,4 @@
1
+ import type { ReactNode } from "react";
1
2
  import type { LayoutNode, Schema } from "../../types/schema";
2
3
  import { type ResolvedChildConfig } from "../../lib/child-config";
3
4
  import type { LayoutContext } from "./LayoutRenderer";
@@ -11,5 +12,5 @@ export interface ChildDisplayProps {
11
12
  parentId: string;
12
13
  schema: Schema;
13
14
  }
14
- export declare function ChildrenBlock({ node, ctx }: ChildrenBlockProps): import("react/jsx-runtime").JSX.Element | null;
15
+ export declare function ChildrenBlock({ node, ctx }: ChildrenBlockProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
15
16
  export {};
@@ -0,0 +1,13 @@
1
+ import type { Entity, Schema, Screen } from "../../types/schema";
2
+ import type { RefsMap } from "../../components/fields";
3
+ interface DetailAuditStripProps {
4
+ screen: Screen;
5
+ entity: Entity;
6
+ entityCode: string;
7
+ record: Record<string, unknown>;
8
+ refs?: RefsMap;
9
+ schema: Schema;
10
+ locale: string;
11
+ }
12
+ export declare function DetailAuditStrip({ screen, entity, entityCode, record, refs, schema, locale, }: DetailAuditStripProps): import("react/jsx-runtime").JSX.Element | null;
13
+ export {};
@@ -0,0 +1,15 @@
1
+ import type { Entity, Schema, Screen } from "../../types/schema";
2
+ import type { StatusInfo } from "../../types/api";
3
+ import type { RefsMap } from "../../components/fields";
4
+ interface DetailHighlightsProps {
5
+ screen: Screen;
6
+ entity: Entity;
7
+ entityCode: string;
8
+ record: Record<string, unknown>;
9
+ refs?: RefsMap;
10
+ objectStatuses?: StatusInfo[];
11
+ schema: Schema;
12
+ locale: string;
13
+ }
14
+ export declare function DetailHighlights({ screen, entity, entityCode, record, refs, objectStatuses, schema, locale, }: DetailHighlightsProps): import("react/jsx-runtime").JSX.Element | null;
15
+ export {};
@@ -0,0 +1,11 @@
1
+ export interface FieldErrorEntry {
2
+ name: string;
3
+ label: string;
4
+ message: string;
5
+ }
6
+ interface ErrorSummaryProps {
7
+ errors: FieldErrorEntry[];
8
+ onJump?: (name: string) => void;
9
+ }
10
+ export declare function ErrorSummary({ errors, onJump }: ErrorSummaryProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export {};
@@ -0,0 +1,21 @@
1
+ import type { ReactNode } from "react";
2
+ export declare const SPAN_FIELD_TYPES: ReadonlySet<string>;
3
+ export interface FieldsGridProps {
4
+ columns?: number;
5
+ children: ReactNode;
6
+ }
7
+ export declare function FieldsGrid({ columns, children }: FieldsGridProps): import("react/jsx-runtime").JSX.Element;
8
+ export interface FieldRowProps {
9
+ label: ReactNode;
10
+ children: ReactNode;
11
+ span?: boolean;
12
+ required?: boolean;
13
+ error?: string;
14
+ hint?: ReactNode;
15
+ actions?: ReactNode;
16
+ mode?: "display" | "edit";
17
+ htmlFor?: string;
18
+ labelId?: string;
19
+ "data-testid"?: string;
20
+ }
21
+ export declare function FieldRow({ label, children, span, required, error, hint, actions, mode, htmlFor, labelId, "data-testid": testId, }: FieldRowProps): import("react/jsx-runtime").JSX.Element;
@@ -27,6 +27,8 @@ export interface LayoutContext {
27
27
  pendingChildren?: Record<string, PendingChildRow[]>;
28
28
  onChildrenChange?: (childCode: string, rows: PendingChildRow[]) => void;
29
29
  childValidationErrors?: Record<string, Record<string, string[]>>;
30
+ fieldErrors?: Record<string, string>;
31
+ withinCard?: boolean;
30
32
  }
31
33
  interface LayoutRendererProps {
32
34
  nodes: LayoutNode[];
@@ -0,0 +1,4 @@
1
+ import type { LayoutNode } from "../../types/schema";
2
+ import type { LayoutContext } from "./LayoutRenderer";
3
+ export declare function resolveBlockLabel(node: LayoutNode, ctx: LayoutContext): string;
4
+ export declare function resolveBlockIcon(node: LayoutNode, ctx: LayoutContext): string | undefined;
@@ -4,6 +4,10 @@ export { LayoutColumn } from "./LayoutColumn";
4
4
  export { LayoutTabs } from "./LayoutTabs";
5
5
  export { SectionBlock } from "./SectionBlock";
6
6
  export { FieldsBlock } from "./FieldsBlock";
7
+ export { FieldRow, FieldsGrid, type FieldRowProps, type FieldsGridProps } from "./FieldRow";
8
+ export { ErrorSummary, type FieldErrorEntry } from "./ErrorSummary";
9
+ export { DetailHighlights } from "./DetailHighlights";
10
+ export { DetailAuditStrip } from "./DetailAuditStrip";
7
11
  export { ChildrenBlock, type ChildDisplayProps } from "./ChildrenBlock";
8
12
  export { ChildrenTable } from "./ChildrenTable";
9
13
  export { EditableChildrenTable } from "./EditableChildrenTable";
@@ -1,2 +1,3 @@
1
1
  import type { FieldRendererProps } from "./index";
2
+ export declare function isEmptyJsonValue(value: unknown): boolean;
2
3
  export declare function JsonField({ value, mode, onChange, fieldId }: FieldRendererProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import type { ReactElement } from "react";
2
+ export declare const EMPTY_CELL: ReactElement;
@@ -5,15 +5,20 @@ export type SectionBadge = {
5
5
  tone?: PillTone;
6
6
  dot?: boolean;
7
7
  };
8
+ export type SectionEmphasis = "primary" | "secondary";
8
9
  export type SectionCardProps = {
9
10
  title: ReactNode;
10
11
  subtitle?: ReactNode;
11
12
  right?: ReactNode;
12
13
  badge?: SectionBadge;
14
+ count?: number;
13
15
  children?: ReactNode;
16
+ footer?: ReactNode;
14
17
  collapsible?: boolean;
15
18
  defaultOpen?: boolean;
16
19
  icon?: ReactNode;
20
+ emphasis?: SectionEmphasis;
21
+ headingLevel?: number;
17
22
  padding?: string;
18
23
  };
19
- export declare function SectionCard({ title, subtitle, right, badge, children, collapsible, defaultOpen, icon, padding, }: SectionCardProps): import("react/jsx-runtime").JSX.Element;
24
+ export declare function SectionCard({ title, subtitle, right, badge, count, children, footer, collapsible, defaultOpen, icon, emphasis, headingLevel, padding, }: SectionCardProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import type { CSSProperties } from "react";
2
+ export declare const dataTableStyle: CSSProperties;
3
+ export declare const dataTableHeadCellStyle: CSSProperties;
4
+ export declare const dataTableCellStyle: CSSProperties;
@@ -19,7 +19,7 @@ export type { HoverCardProps, HoverCardAlign } from "./HoverCard";
19
19
  export { Chip } from "./Chip";
20
20
  export type { ChipProps } from "./Chip";
21
21
  export { SectionCard } from "./SectionCard";
22
- export type { SectionCardProps, SectionBadge } from "./SectionCard";
22
+ export type { SectionCardProps, SectionBadge, SectionEmphasis } from "./SectionCard";
23
23
  export { RecordIdBadge } from "./RecordIdBadge";
24
24
  export type { RecordIdBadgeProps } from "./RecordIdBadge";
25
25
  export { RowField } from "./RowField";
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from "react";
2
+ export interface AuditStripLine {
3
+ label: ReactNode;
4
+ by?: ReactNode;
5
+ at?: ReactNode;
6
+ }
7
+ interface AuditMetaStripProps {
8
+ lines: AuditStripLine[];
9
+ }
10
+ export declare function AuditMetaStrip({ lines }: AuditMetaStripProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export {};
@@ -0,0 +1,10 @@
1
+ import { type ReactNode } from "react";
2
+ export interface HighlightItem {
3
+ label: string;
4
+ value: ReactNode;
5
+ }
6
+ interface HighlightsStripProps {
7
+ items: HighlightItem[];
8
+ }
9
+ export declare function HighlightsStrip({ items }: HighlightsStripProps): import("react/jsx-runtime").JSX.Element | null;
10
+ export {};
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from "react";
2
+ interface RecordHeaderProps {
3
+ icon?: ReactNode;
4
+ avatarName?: string;
5
+ title: string;
6
+ recordId?: string;
7
+ highlights?: ReactNode;
8
+ mode: "display" | "edit" | "create";
9
+ dirty?: boolean;
10
+ showBack?: boolean;
11
+ onBack?: () => void;
12
+ right?: ReactNode;
13
+ }
14
+ export declare function RecordHeader({ icon, avatarName, title, recordId, highlights, mode, dirty, showBack, onBack, right, }: RecordHeaderProps): import("react/jsx-runtime").JSX.Element;
15
+ export {};
@@ -0,0 +1,13 @@
1
+ export interface StatusStage {
2
+ code: string;
3
+ label: string;
4
+ }
5
+ interface StatusStepperProps {
6
+ stages: StatusStage[];
7
+ current: string | undefined;
8
+ selectable?: Set<string>;
9
+ onSelect?: (code: string) => void;
10
+ compact?: boolean;
11
+ }
12
+ export declare function StatusStepper({ stages, current, selectable, onSelect, compact, }: StatusStepperProps): import("react/jsx-runtime").JSX.Element;
13
+ export {};
@@ -0,0 +1,31 @@
1
+ /** The five toast variants. `loading` transforms in place via `toast.update`. */
2
+ export type ToastType = "success" | "error" | "warning" | "info" | "loading";
3
+ /** A single trailing action button rendered in the toast's action row. */
4
+ export interface ToastAction {
5
+ label: string;
6
+ onClick: () => void;
7
+ }
8
+ /** Everything needed to render one toast. Built by the `lib/toast` facade. */
9
+ export interface ToastModel {
10
+ id: string | number;
11
+ type: ToastType;
12
+ title: string;
13
+ /** Optional body line - selectable so users can quote it in a ticket. */
14
+ message?: string;
15
+ /** Auto-dismiss after this many ms. 0 = sticky (never auto-dismisses). */
16
+ duration: number;
17
+ sticky: boolean;
18
+ action?: ToastAction;
19
+ /** Correlation id, shown top-right in mono, selectable, included in Copy. */
20
+ requestId?: string;
21
+ /** Expandable detail block (stack trace, server payload) - selectable. */
22
+ details?: string;
23
+ /** Repeat-rollup count. >1 renders a ×N badge instead of a new toast. */
24
+ count?: number;
25
+ /** Re-stamped on every `toast.update` so the dismiss timer re-arms. */
26
+ createdAt: number;
27
+ }
28
+ export declare function DeclarionToast({ model, onClose }: {
29
+ model: ToastModel;
30
+ onClose: () => void;
31
+ }): import("react/jsx-runtime").JSX.Element;