Skip to content

Commit 60ba54f

Browse files
xuyushun441-sysos-zhuangclaude
authored
docs(showcase+skill): ADR-0047 UX round 2 — tabs XOR dropdowns, no auto-derive (#1798)
- showcase task views: move the dropdown userFilters demo from the default view (which demonstrates filter tabs) to the Task List view — the toolbar renders one filter element style per view, never both. - objectstack-ui skill: update decision rules for the new renderer contract — filter elements render only when explicitly configured (no auto-derive; omission = clean toolbar), tabs XOR dropdowns, visualization switcher is a compact dropdown controlled solely via the allowedVisualizations whitelist. Companion to objectui#1680 (renderer behavior change). Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent d01c427 commit 60ba54f

2 files changed

Lines changed: 34 additions & 17 deletions

File tree

examples/app-showcase/src/views/task.view.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,21 @@ export const TaskViews = defineView({
2828

2929
// ADR-0047 — in-view filter tabs (ViewTab presets). Each tab applies
3030
// its own filter rules on top of the view's base criteria; the first
31-
// tab is the unfiltered default.
31+
// tab is the unfiltered default. Filter tabs and dropdown filters are
32+
// MUTUALLY EXCLUSIVE on the toolbar (Airtable's Elements choice):
33+
// this view demonstrates tabs; the `tabular` view below demonstrates
34+
// dropdowns. Configuring both renders tabs only.
3235
tabs: [
3336
{ name: 'all_tasks', label: 'All', isDefault: true },
3437
{ name: 'in_progress', label: 'In Progress', filter: [{ field: 'status', operator: 'equals', value: 'in_progress' }] },
3538
{ name: 'urgent', label: 'Urgent', icon: 'flame', filter: [{ field: 'priority', operator: 'equals', value: 'urgent' }] },
3639
{ name: 'done', label: 'Done', filter: [{ field: 'status', operator: 'equals', value: 'done' }] },
3740
],
3841

39-
// ADR-0047 — end-user quick-filter dropdowns (Airtable "User filters").
40-
// Options/labels are inferred from the field definitions; `priority`
41-
// shows per-option record counts.
42-
userFilters: {
43-
element: 'dropdown',
44-
fields: [
45-
{ field: 'status' },
46-
{ field: 'priority', showCount: true },
47-
{ field: 'done', type: 'boolean' },
48-
],
49-
},
50-
5142
// ADR-0047 — runtime visualization whitelist (Airtable "Appearance →
52-
// Visualizations"). Users can flip between these renderers; types
53-
// whose bindings don't resolve are hidden by the client regardless.
43+
// Visualizations"). Rendered as a compact dropdown in the toolbar's
44+
// right cluster; types whose bindings don't resolve are hidden by the
45+
// client regardless.
5446
appearance: {
5547
allowedVisualizations: ['grid', 'kanban', 'gallery', 'calendar'],
5648
},
@@ -71,6 +63,20 @@ export const TaskViews = defineView({
7163
{ field: 'status' },
7264
{ field: 'estimate_hours' },
7365
],
66+
67+
// ADR-0047 — end-user quick-filter dropdowns (Airtable "User
68+
// filters", Elements: dropdowns). Options/labels are inferred from
69+
// the field definitions; `priority` shows per-option record counts.
70+
// Counterpart to the default view's `tabs` — one element style per
71+
// view, never both.
72+
userFilters: {
73+
element: 'dropdown',
74+
fields: [
75+
{ field: 'status' },
76+
{ field: 'priority', showCount: true },
77+
{ field: 'done', type: 'boolean' },
78+
],
79+
},
7480
},
7581

7682
// 1 ── Grid ─────────────────────────────────────────────────────────

skills/objectstack-ui/SKILL.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,19 @@ appearance: { allowedVisualizations: ['grid', 'kanban', 'gallery'] },
264264
Rules:
265265
- Every `field` MUST exist on the source object — reference diagnostics
266266
(`_diagnostics`) flag unknown fields; treat `valid: false` as a failed write.
267-
- Omit `userFilters` entirely when unsure: the renderer auto-derives dropdowns
268-
from select/boolean fields. **Omission is correct.**
267+
- **Tabs XOR dropdowns — never both on one view.** The toolbar renders ONE
268+
filter element style (Airtable's Elements choice). If a view configures
269+
both `tabs` and `userFilters`, tabs win and the dropdowns never render.
270+
Want both demos? Put them on different views.
271+
- **Omit `userFilters` when unsure — omission means a clean toolbar.** Filter
272+
elements render only when explicitly configured; nothing is auto-derived.
273+
In data mode the saved-views switcher already covers the preset use case,
274+
so most views need no filter elements at all.
275+
- `userFilters: { element: 'dropdown' }` (no `fields`) is valid shorthand:
276+
the renderer fills the field list from the object's select/boolean fields.
277+
- The visualization switcher renders as a compact dropdown in the toolbar's
278+
right cluster. Authors only control the `allowedVisualizations` whitelist;
279+
a single-entry whitelist locks the visualization (no switcher).
269280

270281
### Sorting
271282

0 commit comments

Comments
 (0)