@tristan2828/ui-foundation 3.6.0 → 3.8.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.
|
@@ -103,7 +103,31 @@ is a filled-in example while the Widgets demo is still here).
|
|
|
103
103
|
controls named by position ("Item 2 text"), a per-item `FieldError`
|
|
104
104
|
(a server 422 at `["body", "checklist", 2, "text"]` arrives as
|
|
105
105
|
`fieldErrors["checklist.2.text"]` and binds to that row), and a summary
|
|
106
|
-
in the table, never the items
|
|
106
|
+
in the table, never the items — and a `computed` field copies
|
|
107
|
+
Progress (`checklistState`): `readOnly` in `openapi.yaml` and absent
|
|
108
|
+
from `<Entity>Create`/`<Entity>Update`, one SQL expression in the
|
|
109
|
+
router that the filter and sort use (correlated `EXISTS`, or a scalar
|
|
110
|
+
subquery for a count, so they hold across pages), a Python mirror on
|
|
111
|
+
the model for the value each row reads back with, a test that the two
|
|
112
|
+
agree for every value, the mocks recomputing it on every write and
|
|
113
|
+
ignoring any client-sent value, a read-only column and a filter, and
|
|
114
|
+
nothing on the form):
|
|
115
|
+
|
|
116
|
+
**Keep column definitions stable.** Build them once
|
|
117
|
+
(`useMemo(() => build<Entity>Columns(), [])`) from nothing that loads
|
|
118
|
+
later. TanStack's `flexRender` treats each column's `cell` as a
|
|
119
|
+
component, so rebuilt columns remount every cell: focus is lost and the
|
|
120
|
+
table flickers when, say, reference names arrive after the rows. Data
|
|
121
|
+
that arrives later reaches the cells through context, as
|
|
122
|
+
`category-names.tsx` does for category names.
|
|
123
|
+
|
|
124
|
+
**A `yes/no` marked `toggle`** copies In Stock's cell
|
|
125
|
+
(`in-stock-toggle.tsx`, cell pattern 15): a `Switch` in its own
|
|
126
|
+
component that PATCHes the one field through an optimistic mutation
|
|
127
|
+
(`useToggleWidgetInStockMutation`: every cached list page updates at
|
|
128
|
+
once and is restored if the save fails, with a toast naming the row),
|
|
129
|
+
then refetches the lists. Its specs cover a flip that saves, the
|
|
130
|
+
keyboard, and a failed save putting the switch back.
|
|
107
131
|
- `src/routes/widgets/use-widgets.ts`, `use-categories.ts` →
|
|
108
132
|
`src/routes/<entity>/use-<entity>.ts` (TanStack Query hooks over the
|
|
109
133
|
new gateway module)
|
|
@@ -330,3 +330,23 @@ A person: an assignee or an owner.
|
|
|
330
330
|
- **Cost:** a column of faces draws the eye more than any other cell. Use
|
|
331
331
|
it when *who* matters most in the row, not as decoration.
|
|
332
332
|
|
|
333
|
+
## 15. Yes/no you flip in the row
|
|
334
|
+
|
|
335
|
+
A yes/no the user changes more often than they open the form ("available
|
|
336
|
+
now", "happened"). Widget's In Stock column is the reference
|
|
337
|
+
(`src/routes/widgets/in-stock-toggle.tsx`).
|
|
338
|
+
|
|
339
|
+
- **A `Switch`, never a checkbox.** It acts at once; a checkbox in a row
|
|
340
|
+
reads as "select this row".
|
|
341
|
+
- **It saves on its own:** a PATCH of that one field, not the form. Show
|
|
342
|
+
the new value at once (optimistic) and put it back, with a toast naming
|
|
343
|
+
the row, if the save fails (`useToggleWidgetInStockMutation`).
|
|
344
|
+
- **Keep the word beside it** (pattern 12), `aria-hidden` since the switch
|
|
345
|
+
announces its own state. Give the switch a row-specific name
|
|
346
|
+
(`In stock: ${row.original.name}`).
|
|
347
|
+
- Its own component in its own file, rendered from the column's `cell`,
|
|
348
|
+
so the hook lives in a component and the columns stay stable
|
|
349
|
+
([`add-an-entity.md`](add-an-entity.md) "Keep column definitions
|
|
350
|
+
stable").
|
|
351
|
+
- **Cost:** one click changes data, with no confirmation. Only for values
|
|
352
|
+
that are cheap to flip back; never for anything destructive.
|
|
@@ -33,7 +33,12 @@ One or two sentences: what one record is, and who uses the screens.
|
|
|
33
33
|
(to another entity — name it; a searchable combobox), `multi reference`
|
|
34
34
|
(to any number of records of another entity — name it; chips with a
|
|
35
35
|
searchable dropdown, names as badges in the table, an any-of filter;
|
|
36
|
-
the other entity's list endpoint must also accept `ids`)
|
|
36
|
+
the other entity's list endpoint must also accept `ids`),
|
|
37
|
+
`computed` (read-only: the server works it out from other data on
|
|
38
|
+
every read and never stores it — give its rule, and if it's a choice,
|
|
39
|
+
its values in sort order with a label for each; a read-only column, a filter and a sort the
|
|
40
|
+
server evaluates, never on the form). A count of related records is a
|
|
41
|
+
`computed` integer.
|
|
37
42
|
- *Close variants* (built by a small, stated change to the nearest
|
|
38
43
|
pattern): `integer` (from decimal), `url` (from email — a format
|
|
39
44
|
check), `date` (from date-time — no time part).
|
|
@@ -50,7 +55,8 @@ One or two sentences: what one record is, and who uses the screens.
|
|
|
50
55
|
a screen — a Base UI `Select` can't take `""` as an item value, so the
|
|
51
56
|
pattern needs a sentinel and gets the display wrong without one.
|
|
52
57
|
- **List**: `column` if it shows in the table, and `sortable` if you can
|
|
53
|
-
sort by it; blank if it's form-only.
|
|
58
|
+
sort by it; blank if it's form-only. A `yes/no` can also say `toggle`:
|
|
59
|
+
flipped straight from its row, saved on its own (cell pattern 15).
|
|
54
60
|
- **Filter**: `search` (the text search box), `yes` (a filter control), or
|
|
55
61
|
blank.
|
|
56
62
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tristan2828/ui-foundation",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"description": "Shared UI foundation for contract-first, database-backed React apps: shadcn primitives, DataTable/EntityForm composites, auth, the gateway error seam, design tokens, lint rules and the AI playbook.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|