You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(spec): object-kanban props declare limit, the row cap objectui already implements (#16562)
* feat(spec): object-kanban props declare `limit`, the row cap objectui already reads
`ComponentPropsMap['object-kanban']` is strict and refused `limit` by name
while objectui's plugin-kanban reads `schema.limit` as the query's `$top`,
`OBJECT_KANBAN_DATA_SOURCE` maps `limit: 'limit'`, `KanbanSchema` declares
`limit?: number` and the plugin docs teach `limit: 250`. Declare the key
(`z.number().int().positive().optional()`), pin both directions (the
documented shape parses; an undeclared sibling is still refused), and add
the minor changeset.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno
* chore(spec): regenerate authorable-surface and reference docs for object-kanban `limit`
`pnpm --filter @objectstack/spec build` (gen:schema) adds the
`ui/ObjectKanbanProps:limit` row to `authorable-surface/ui.json`;
`check:generated` proved only `content/docs/references/**` stale and
`gen:docs` regenerated it. No `api-surface/` shard moves — a key on an
existing props map adds no export.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno
---------
Co-authored-by: Claude <noreply@anthropic.com>
feat(spec): `ComponentPropsMap['object-kanban']` declares `limit`, the row cap four objectui faces already implement (#16503, the spec half of objectui#8172)
6
+
7
+
`object-kanban` gains one optional authorable key:
8
+
9
+
```ts
10
+
limit: z.number().int().positive().optional()
11
+
```
12
+
13
+
Maximum number of records loaded onto the board (row cap), lowered to the top-level `$top` of the board's one query. The renderer default stays 100 and is documented rather than declared, so an unset key remains unset. The component-level `dataSource.limit` wins when both are set, and a bound named view's `pagination.pageSize` fills the key only when the component authored none — the `ElementDataSourceGate` precedence table, unchanged.
14
+
15
+
Measured at the objectui pin this repo builds against (`.objectui-sha` = `a472b0716`): `plugin-kanban` reads `schema.limit` as the query's `$top` (wired by objectui#4025), `OBJECT_KANBAN_DATA_SOURCE` maps `limit: 'limit'`, `KanbanSchema` declares `limit?: number`, and `content/docs/plugins/plugin-kanban.mdx` teaches it with a typed snippet (`limit: 250`) plus a Properties row. The strict props map refused the key by name, so an author following the published docs wrote a node the save gate rejected with the same `unrecognized_keys` verdict a typo gets. Decision batch #68 (2026-09-07, option A): the contract declares the capability that is already implemented, documented and in use.
16
+
17
+
Widening a published accept set (Clause-② yes): `safeParse({ objectName: 'x', limit: 250 })` now succeeds; every other undeclared key on the node is refused exactly as before. objectui#8172 publishes the key in the registry declaration on its side.
Copy file name to clipboardExpand all lines: content/docs/references/ui/component.mdx
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -457,6 +457,7 @@ Sort field and direction pair
457
457
|**groupBy**|`string`| optional | Field whose values become the board columns |
458
458
|**columns**|`any[]`| optional | Swimlane definitions (`{ id, title }` per `groupBy` value, or bare value strings) — NOT a field projection |
459
459
|**filter**|`any`| optional | Base query filter, handed to the wire `$filter`|
460
+
|**limit**|`integer`| optional | Maximum number of records loaded onto the board (row cap); lowered to the query's top-level `$top` (renderer default 100). The component-level `dataSource.limit` wins when both are set; a bound view's `pagination.pageSize` fills it only when unset |
* `readLimit`/`writeLimit` keyed by `ElementDataSourceLimitKey`). The board
2693
+
* has no `pagination` read point, so declaring that spelling here would name
2694
+
* a key the renderer ignores — the accepted-and-dropped defect this section
2695
+
* exists to remove. Same shape as the `element:record_picker` and
2696
+
* `record:related_list` row caps (one `$top` contract, not a third dialect),
2697
+
* and like them the renderer's 100 is documented rather than declared:
2698
+
* a schema default would materialize `limit: 100` on every parsed board.
2699
+
*/
2700
+
limit: z.number().int().positive().optional()
2701
+
.describe("Maximum number of records loaded onto the board (row cap); lowered to the query's top-level `$top` (renderer default 100). The component-level `dataSource.limit` wins when both are set; a bound view's `pagination.pageSize` fills it only when unset"),
2665
2702
data: z.array(z.unknown()).optional().describe('Static inline cards — bypasses the object query'),
2666
2703
cardTitle: z.string().optional().describe('Field rendered as each card title'),
2667
2704
titleField: z.string().optional().describe('Legacy fallback for `cardTitle` (the board reads `cardTitle || titleField`). Prefer `cardTitle`'),
0 commit comments