Repository navigation
Protocol: Add DetailView display hints — hideEmpty, primaryField, summaryFields, collapseWhenEmpty #838
Description
Background
Based on a platform-wide DetailView UX audit (see cross-repo issue in objectstack-ai/objectui), the current spec schemas lack several display-hint properties that renderers need to deliver intelligent default behavior. The protocol already has rich layout primitives (FormSectionSchema, RecordDetailsProps, RecordActivityProps, ResponsiveConfigSchema), but is missing a few critical fields that prevent renderers from optimizing empty-state, header, and activity panel behavior without hardcoding.
This issue covers protocol-only changes. The corresponding renderer consumption work is tracked in objectstack-ai/objectui.
Changes Required
1. FormSectionSchema — add hideEmpty + emptyPlaceholder
File: packages/spec/src/ui/view.zod.ts
Current:
export const FormSectionSchema = z.object({
label: I18nLabelSchema.optional(),
collapsible: z.boolean().default(false),
collapsed: z.boolean().default(false),
columns: z.enum(['1', '2', '3', '4']).default('2'),
fields: z.array(z.union([z.string(), FormFieldSchema])),
});Add:
hideEmpty: z.boolean().optional()
.describe('Hide fields with null/undefined/empty string values'),
emptyPlaceholder: I18nLabelSchema.optional()
.describe('Placeholder text for empty values when hideEmpty is false (default: "—")'),Also consider adding 'auto' to the columns enum so renderers can infer optimal column count:
columns: z.enum(['auto', '1', '2', '3', '4']).default('2'),2. RecordDetailsProps — add hideEmpty, primaryField, summaryFields
File: packages/spec/src/ui/component.zod.ts
Add to existing RecordDetailsProps:
hideEmpty: z.boolean().default(false)
.describe('Hide fields with empty values in detail display'),
primaryField: z.string().optional()
.describe('Field name to use as record title in header (e.g. "name"). Renderer falls back to first text field or objectName.'),
summaryFields: z.array(z.string()).max(5).optional()
.describe('Key fields to render as badges/chips in the header area (e.g. ["status", "priority"])'),3. RecordActivityProps — add collapseWhenEmpty, emptyActions
File: packages/spec/src/ui/component.zod.ts
Add to existing RecordActivityProps:
collapseWhenEmpty: z.boolean().default(false)
.describe('Auto-collapse activity panel when no feed items exist'),
emptyActions: z.array(z.string()).optional()
.describe('Quick-action IDs to surface when timeline is empty (e.g. ["log_call", "send_email"])'),Tests to Add
File: packages/spec/src/ui/view.test.ts
FormSectionSchemaacceptshideEmpty: trueFormSectionSchemaacceptsemptyPlaceholderstringFormSectionSchemaacceptscolumns: 'auto'- Backward compat: existing schemas without new fields still parse
File: packages/spec/src/ui/component.test.ts
RecordDetailsPropsacceptsprimaryField,summaryFields,hideEmptyRecordActivityPropsacceptscollapseWhenEmpty,emptyActions- Backward compat:
RecordDetailsProps.parse({})still works with defaults
Documentation Updates
content/docs/references/ui/component.mdx— add new properties to RecordDetailsProps and RecordActivityProps tablescontent/docs/protocol/objectui/layout-dsl.mdx— addhideEmptyexample in Section Definitioncontent/docs/guides/metadata/view.mdx— add best-practice example showinghideEmpty+columns: 'auto'
Non-Breaking
All additions are optional fields with defaults — zero impact on existing schema consumers.
Cross-Repo
- objectstack-ai/objectui will track the renderer consumption of these new properties (cross-repo issue)
Activity