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:
exportconstFormSectionSchema=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
FormSectionSchema accepts hideEmpty: trueFormSectionSchema accepts emptyPlaceholder stringFormSectionSchema accepts columns: 'auto'- Backward compat: existing schemas without new fields still parse
File:packages/spec/src/ui/component.test.ts
RecordDetailsProps accepts primaryField, summaryFields, hideEmptyRecordActivityProps accepts collapseWhenEmpty, 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 — add hideEmpty example in Section Definitioncontent/docs/guides/metadata/view.mdx — add best-practice example showing hideEmpty + 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)
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— addhideEmpty+emptyPlaceholderFile:
packages/spec/src/ui/view.zod.tsCurrent:
Add:
Also consider adding
'auto'to thecolumnsenum so renderers can infer optimal column count:2.
RecordDetailsProps— addhideEmpty,primaryField,summaryFieldsFile:
packages/spec/src/ui/component.zod.tsAdd to existing
RecordDetailsProps:3.
RecordActivityProps— addcollapseWhenEmpty,emptyActionsFile:
packages/spec/src/ui/component.zod.tsAdd to existing
RecordActivityProps:Tests to Add
File:
packages/spec/src/ui/view.test.tsFormSectionSchemaacceptshideEmpty: trueFormSectionSchemaacceptsemptyPlaceholderstringFormSectionSchemaacceptscolumns: 'auto'File:
packages/spec/src/ui/component.test.tsRecordDetailsPropsacceptsprimaryField,summaryFields,hideEmptyRecordActivityPropsacceptscollapseWhenEmpty,emptyActionsRecordDetailsProps.parse({})still works with defaultsDocumentation 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