@viliha/vui-ui 1.15.0 → 1.16.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/AGENT.md CHANGED
@@ -348,6 +348,8 @@ Never hand-build an HTML table; always use `RecordView`. Configure columns throu
348
348
 
349
349
  Long cell text never wraps: cells truncate to one line at `maxCellChars` (view prop; defaults to `NEXT_PUBLIC_MAX_CELL_CHARS` or 25) with an ellipsis + hover tooltip. Override a column with the field's `maxChars` (`0` = never truncate). Don't add your own `truncate`/`title` on cells — it's built in.
350
350
 
351
+ A choice field (`options`) shows the option's **label** in the cell (e.g. `SYSTEM` → "System") while staying editable — don't use `render` just to map an enum to a friendly label. To customize the full-page form's breadcrumb, pass a `crumbs` array to `RecordForm` (each `{ label, onClick? }`, last = current page) — e.g. to add an "Access" parent or rename "Create new role" → "New Role".
352
+
351
353
  Sorting follows column visibility by default; use `sortable` to decouple them — `sortable: true` sorts a field with no column (e.g. a `hideInTable` name shown via `getPrimary`), `sortable: false` locks a visible column. Set the flag; don't rewire the Sort dropdown or headers.
352
354
 
353
355
  Form controls come from the field: `options` → `Select`, `input: "combobox"` → a searchable `Combobox` (`@viliha/vui-ui/combobox`, use for long lists), `input: "number" | "date"` → native inputs. For anything the built-ins don't cover (checkbox, radio group, slider, custom widget), set `renderInput({ value, onChange, field, invalid })` on the field — it drops any component into the Add/Edit form while the field keeps its label, required mark, and Save validation. Don't hand-build a `<form>`.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,27 @@ backward-compatible features, **major** for breaking changes.
7
7
 
8
8
  To upgrade, see [Upgrading](./AGENT.md#upgrading) in the agent guide.
9
9
 
10
+ ## 1.16.0 — 2026-07-27
11
+
12
+ ### Added
13
+
14
+ - **Configurable page-form breadcrumb.** `RecordForm` (page layout) takes a
15
+ `crumbs` prop that fully replaces the default `Home › {title} › Create/Update
16
+ {singular}` trail — add parents (e.g. an "Access" section), rename the last
17
+ crumb ("New Role"), or reshape it per route. Each crumb is `{ label, onClick? }`;
18
+ the last is the current page. The `Crumb` type is re-exported from
19
+ `@viliha/vui-ui/record-view` (also in `@viliha/vui-ui/breadcrumbs`).
20
+
21
+ ### Changed
22
+
23
+ - **Choice-field cells show the option label, not the raw value.** A field with
24
+ `options` now renders its matching label in the table (e.g. `SYSTEM` →
25
+ "System") while staying editable — no need for a read-only `render` just to map
26
+ an enum to a friendly label. Falls back to the raw value when unmatched.
27
+
28
+ **For agents:** use `options` labels for enum columns (not `render`), and pass
29
+ `crumbs` to `RecordForm` to shape a route's breadcrumb. Docs: `/docs/data-table`.
30
+
10
31
  ## 1.15.0 — 2026-07-27
11
32
 
12
33
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viliha/vui-ui",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "description": "Vui UI — a clean, token-driven React admin/CRM component library built on Tailwind CSS v4, shadcn-style patterns, and Radix Icons. Ships as TypeScript source (Just-in-Time), compiled by the consuming app.",
5
5
  "license": "MIT",
6
6
  "author": "Suman Bonakurthi",
@@ -34,6 +34,7 @@ import {
34
34
 
35
35
  import { cn } from "./utils";
36
36
  import { Breadcrumbs, type Crumb } from "./breadcrumbs";
37
+ export type { Crumb } from "./breadcrumbs";
37
38
  import { Button } from "./button";
38
39
  import { Checkbox } from "./checkbox";
39
40
  import { Input } from "./input";
@@ -1170,7 +1171,12 @@ export function RecordView<T extends { id: RowId }>({
1170
1171
  );
1171
1172
  }
1172
1173
  const value = String(row[field.key] ?? "");
1173
- const clip = clipCell(value, field.maxChars ?? maxCellChars);
1174
+ // For a choice field, show the option's friendly label (e.g. SYSTEM
1175
+ // "System") while the cell stays editable — no `render`, no read-only.
1176
+ const display = Array.isArray(field.options)
1177
+ ? (field.options.find((o) => o.value === value)?.label ?? value)
1178
+ : value;
1179
+ const clip = clipCell(display, field.maxChars ?? maxCellChars);
1174
1180
  const cellKey = `${row.id}:${field.key}`;
1175
1181
  const hoverActions =
1176
1182
  (field.editable || (field.copyable && value)) ? (
@@ -2074,6 +2080,11 @@ interface DetailPanelProps<T extends { id: RowId }> {
2074
2080
  /** Persist the in-progress draft under this key (e.g. the route), so a
2075
2081
  * half-filled form survives leaving and returning via the open-tabs strip. */
2076
2082
  persistKey?: string;
2083
+ /** Page-form breadcrumb override (fully configurable). When set, these crumbs
2084
+ * replace the default `Home › {title} › Create/Update {singular}` — so you can
2085
+ * add parents ("Access") or rename the last crumb ("New Role"). Build each
2086
+ * crumb as `{ label, onClick? }`; the last one is the current page. */
2087
+ crumbs?: Crumb[];
2077
2088
  }
2078
2089
 
2079
2090
  function RecordDetailPanel<T extends { id: RowId }>({
@@ -2093,6 +2104,7 @@ function RecordDetailPanel<T extends { id: RowId }>({
2093
2104
  onHome,
2094
2105
  formDescription,
2095
2106
  persistKey,
2107
+ crumbs,
2096
2108
  }: DetailPanelProps<T>) {
2097
2109
  const draftKey = persistKey ? `${persistKey}::draft` : undefined;
2098
2110
  const [draft, setDraft] = usePersistentState<T>(draftKey, row);
@@ -2364,11 +2376,14 @@ function RecordDetailPanel<T extends { id: RowId }>({
2364
2376
  <div className="flex h-12 shrink-0 items-center border-b border-border px-4">
2365
2377
  <Breadcrumbs
2366
2378
  onBack={onCancel}
2367
- crumbs={[
2368
- ...(onHome ? [{ label: "Home", onClick: onHome }] : []),
2369
- { label: title ?? singular, onClick: onCancel },
2370
- { label: crumb },
2371
- ] as Crumb[]}
2379
+ crumbs={
2380
+ crumbs ??
2381
+ ([
2382
+ ...(onHome ? [{ label: "Home", onClick: onHome }] : []),
2383
+ { label: title ?? singular, onClick: onCancel },
2384
+ { label: crumb },
2385
+ ] as Crumb[])
2386
+ }
2372
2387
  />
2373
2388
  </div>
2374
2389
  {/* Content — form card (left) + optional documentation panel (right). */}