@tristan2828/ui-foundation 4.18.3 → 4.18.4

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.
@@ -887,7 +887,9 @@ Checklist is the reference (`checklist` in `widgetEdits`). It's built on
887
887
  on the item (not its box, not a link in it) or its pencil ("Edit item
888
888
  2") turns it into the form's row (`renderItem`, the same fields as the
889
889
  form's `ListEditor` row), an editable value like any above: Enter or
890
- leaving saves, Esc gives up, one open at a time.
890
+ leaving saves, Esc gives up, one open at a time. The row lays its parts
891
+ out side by side as `ListEditor`'s does, so a fragment (the box, then
892
+ the text's `Field`) needs no wrapper of its own.
891
893
  - **Add at the end.** "Add item" opens a new row; Enter saves it and
892
894
  opens the next, the caret already in it, so a run of items goes in from
893
895
  the keyboard. Esc on an empty one closes it; nothing is sent.
@@ -124,6 +124,8 @@ export type EditInPlaceListOptions<TItem> = {
124
124
  /**
125
125
  * The item's own fields while it's edited: the form's row (what its
126
126
  * ListEditor's `renderItem` shows), as controls over `props.value`.
127
+ * Laid out in a row as ListEditor's is: a fragment's parts sit side by
128
+ * side, and a single element fills the row.
127
129
  */
128
130
  renderItem: (props: EditListItemProps<TItem>) => ReactNode;
129
131
  /** How the item reads when it isn't being edited. Its own controls (a done box) keep working. */
@@ -35,6 +35,13 @@ function locate(current, item, index) {
35
35
  const found = current.findIndex((other) => sameItem(other, item));
36
36
  return found === -1 ? index : found;
37
37
  }
38
+ // The form's row, in place too: ListEditor lays `renderItem` out in a
39
+ // row, so its parts (a done box, then the text box) sit side by side
40
+ // there and here alike. One element (an app's own row) fills it, as it
41
+ // filled the field's column before.
42
+ function ItemRow({ children }) {
43
+ return _jsx("span", { className: "flex min-w-0 items-start gap-2 [&>:only-child]:flex-1", children: children });
44
+ }
38
45
  // The list's schema, run on the list this draft would make. A message
39
46
  // about this item comes first, then one about the list as a whole (too
40
47
  // many items).
@@ -110,7 +117,7 @@ export function EditableList({ label, edit, emptyLabel }) {
110
117
  const itemEdit = (index) => ({
111
118
  kind: 'text',
112
119
  value: items[index],
113
- control: (props) => edit.renderItem({ ...props, index, isNew: false }),
120
+ control: (props) => _jsx(ItemRow, { children: edit.renderItem({ ...props, index, isNew: false }) }),
114
121
  schema: { safeParse: (draft) => checkItem(edit, items, index, draft) },
115
122
  save: (item) => edit.save((current) => {
116
123
  const at = locate(current, items[index], index);
@@ -121,7 +128,7 @@ export function EditableList({ label, edit, emptyLabel }) {
121
128
  const addEdit = {
122
129
  kind: 'text',
123
130
  value: edit.newItem(),
124
- control: (props) => edit.renderItem({ ...props, index: items.length, isNew: true }),
131
+ control: (props) => _jsx(ItemRow, { children: edit.renderItem({ ...props, index: items.length, isNew: true }) }),
125
132
  schema: { safeParse: (draft) => checkItem(edit, items, items.length, draft) },
126
133
  save: (item) => edit.save((current) => [...current, item]),
127
134
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tristan2828/ui-foundation",
3
- "version": "4.18.3",
3
+ "version": "4.18.4",
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": {