Collection
incubatingStatus of this Document
This report was published by the User Journal Graph Community Group . It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups .
Title: org.openuji.specs.ujg.collection.v1
Status: incubating implementation extension for self-contained multi-item collection projections carried in UJG Core extensions.
1. Namespace
Canonical namespace string:
org.openuji.specs.ujg.collection.v1Payload location:
extensions["org.openuji.specs.ujg.collection.v1"]Published JSON Schema:
https://ujg.specs.openuji.org/ed/ns/collection.schema.json
2. Purpose
This extension describes how a node presents a list, search result, queue, table, gallery, or other collection-style projection.
It exists so that generators can implement a collection directly from one self-contained payload that answers:
what the collection reads,
how each item is projected,
which filters, sorts, and search affordances exist,
how selection works,
how pagination works,
which bulk or item actions appear,
what loading, empty, and error posture apply,
which appearance roles matter.
It is intentionally separate from org.openuji.specs.ujg.record.v1 so that collection surfaces remain small
and easy to overview.
3. Scope
This extension covers:
collection source and read posture,
item projection,
filters,
sort options,
search posture,
selection mode,
pagination mode,
bulk and item action placeholders,
loading, empty, and error posture,
appearance roles needed for generation.
The extension is self-contained and may refer to UJG node IDs for follow-up transitions, but it does not require private objects from other extensions.
4. Non-goals
This extension does not standardize:
SQL queries,
API query strings,
GraphQL documents,
vendor table components,
virtualization engines,
index backends.
5. Primary Attachment Targets
StateTemplateCompositeState
State is the preferred host for effective collection views. Template is the preferred reusable
host for shared list or grid shells. CompositeState is the preferred host for subflow-wide
defaults.
6. Secondary Attachment Targets
Journeyfor broad defaults such as pagination posture or common search affordances
7. Discouraged Or Disallowed Attachment Targets
Transitionis discouraged because transitions normally act on a collection rather than define it.OutgoingTransitionGroupis discouraged because it is not a collection host.Routeis discouraged because routing metadata belongs in Routing.MessageBundleis disallowed in normal use.UJGDocumentis disallowed because Core extensions are node-scoped.
8. Inheritance Model
For a state-level collection projection, generators should apply inheritance in this order:
Journeyeach enclosing
CompositeState, from outermost to innermostresolved
Template, iftemplateRefis presentthe local
State
Template inheritance is the main mechanism for reusable collection shells. State attachment is the main mechanism for effective collection specialization.
9. Precedence And Override Rules
Use this precedence order:
StateTemplateinnermost
CompositeStateouter
CompositeStateJourney
Merge and replacement rules:
itemTypeRef,source,search,selectionMode,pagination,loadingPosture,emptyPosture, anderrorPostureare singular values or objects. The more specific value replaces the inherited one.filters,sorts,itemActions, andbulkActionsmerge byname.itemProjectionmerges bynamefor sections or displayed properties.appearanceRolesmerges by key.a more specific filter, sort, action, or projected property may suppress an inherited one by repeating the same identity and setting
disabled: true.
10. Property Vocabulary
itemTypeRef: identity of the item type projected by the collection. Expected shape: string. Allowed categories: published schema IDs, model IDs, or opaque external identifiers. Implementation intent: tells generators what the collection contains.source: read contract posture. Expected shape: object withcontractRefand optionaltiming,blocking, andcacheHint. Allowed categories are the same generic categories used for record reads. Implementation intent: gives generators a transport-neutral collection read posture.itemProjection: how a single item is summarized. Expected shape: object with optionallayout,properties, andappearanceRole. Implementation intent: lets generators render list items, table rows, cards, or terminal rows without inventing a separate record model.filters: available filters. Expected shape: array of filter objects withname,kind, and optionaloptions,multiple, anddisabled. Implementation intent: declares available filter affordances in a portable way.sorts: available sort modes. Expected shape: array of sort objects withnameand optionaldirectionanddefault. Implementation intent: declares the available sort choices.search: search posture. Expected shape: object with optionalenabled,mode, andplaceholderRole. Allowed categories formode:prefix,contains,full-text. Implementation intent: tells generators whether to render search and how to frame it.selectionMode: item selection posture. Expected shape: string. Allowed categories:none,single,multiple. Implementation intent: distinguishes browse-only collections from selectable collections.pagination: pagination posture. Expected shape: object withmodeand optionalsizeHint. Allowed categories formode:none,page,cursor,infinite. Implementation intent: communicates the collection paging model without defining transport details.itemActions: item-scoped action placeholders. Expected shape: array of objects withnameand optionaltransitionRef,kind,appearanceRole, anddisabled. Implementation intent: reserves item action affordances without defining the command payload here.bulkActions: collection-scoped action placeholders. Expected shape: array of objects withnameand optionaltransitionRef,kind,appearanceRole, anddisabled. Implementation intent: reserves bulk action affordances when selection is enabled.loadingPosture: loading presentation posture. Expected shape: string. Allowed categories:skeleton,spinner,placeholder,silent.emptyPosture: empty presentation posture. Expected shape: string. Allowed categories:blank,message,suggest-search,fallback.errorPosture: error presentation posture. Expected shape: string. Allowed categories:inline,banner,full-state,fallback.appearanceRoles: semantic appearance bindings. Expected shape: object keyed by roles such assurface,item,filterBar,emptyState, orbulkActionBar. Implementation intent: gives generators stable semantic render roles.
11. Recommended Controlled Values
Recommended itemProjection.layout values:
listtablecardsgridstream
Recommended filter kind values:
choicemultichoicerangedatetoggle
Recommended pagination.mode values:
nonepagecursorinfinite
12. Processing Model
A generator implementing this extension should:
Resolve the effective collection payload using the inheritance and precedence rules above.
Resolve the
sourceposture and normalized item projection.Apply filters, sorts, search, selection, pagination, and action posture.
Apply loading, empty, error, and appearance posture.
Combine the resulting collection projection with Templates for shared shells, with Routing for route entry, and with L10n when the node also has
copyRef.Materialize a target-specific collection implementation while leaving graph navigation under Graph control.
13. Cross-Stack Interpretation Notes
Web: map to search pages, index pages, dashboards, list views, tables, and galleries.
Native: map to lists, grouped lists, cards, picker surfaces, and infinite feeds.
CMS: map to content indexes, editorial queues, media browsers, and review lists.
Commerce: map to catalog grids, order lists, inventory lists, and return queues.
CLI or headless or background: map to tabular terminal output, search results, or paged reports.
14. Published JSON Schema
The published schema for this extension is defined below and is published at
https://ujg.specs.openuji.org/ed/ns/collection.schema.json.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ujg.specs.openuji.org/ed/ns/collection.schema.json",
"title": "UJG Collection Extension Payload",
"type": "object",
"additionalProperties": false,
"properties": {
"itemTypeRef": { "type": "string" },
"source": { "$ref": "#/$defs/source" },
"itemProjection": { "$ref": "#/$defs/itemProjection" },
"filters": {
"type": "array",
"items": { "$ref": "#/$defs/filter" }
},
"sorts": {
"type": "array",
"items": { "$ref": "#/$defs/sort" }
},
"search": { "$ref": "#/$defs/search" },
"selectionMode": {
"type": "string",
"enum": ["none", "single", "multiple"]
},
"pagination": { "$ref": "#/$defs/pagination" },
"itemActions": {
"type": "array",
"items": { "$ref": "#/$defs/action" }
},
"bulkActions": {
"type": "array",
"items": { "$ref": "#/$defs/action" }
},
"loadingPosture": {
"type": "string",
"enum": ["skeleton", "spinner", "placeholder", "silent"]
},
"emptyPosture": {
"type": "string",
"enum": ["blank", "message", "suggest-search", "fallback"]
},
"errorPosture": {
"type": "string",
"enum": ["inline", "banner", "full-state", "fallback"]
},
"appearanceRoles": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"$defs": {
"source": {
"type": "object",
"additionalProperties": false,
"properties": {
"contractRef": { "type": "string" },
"timing": {
"type": "string",
"enum": ["startup", "on-enter", "on-visible", "on-demand"]
},
"blocking": {
"type": "string",
"enum": ["required", "deferred", "non-blocking"]
},
"cacheHint": {
"type": "string",
"enum": ["none", "request", "session", "stable", "revalidate"]
}
},
"required": ["contractRef"]
},
"itemProjection": {
"type": "object",
"additionalProperties": false,
"properties": {
"layout": {
"type": "string",
"enum": ["list", "table", "cards", "grid", "stream"]
},
"properties": {
"type": "array",
"items": { "$ref": "#/$defs/property" }
},
"appearanceRole": { "type": "string" }
}
},
"property": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"kind": { "type": "string" },
"appearanceRole": { "type": "string" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"filter": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"kind": {
"type": "string",
"enum": ["choice", "multichoice", "range", "date", "toggle"]
},
"options": {
"type": "array",
"items": {
"oneOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "integer" }
]
}
},
"multiple": { "type": "boolean" },
"disabled": { "type": "boolean" }
},
"required": ["name", "kind"]
},
"sort": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"direction": {
"type": "string",
"enum": ["asc", "desc"]
},
"default": { "type": "boolean" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"search": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"mode": {
"type": "string",
"enum": ["prefix", "contains", "full-text"]
},
"placeholderRole": { "type": "string" }
}
},
"pagination": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"type": "string",
"enum": ["none", "page", "cursor", "infinite"]
},
"sizeHint": {
"type": "integer",
"minimum": 1
}
},
"required": ["mode"]
},
"action": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"transitionRef": { "type": "string" },
"kind": { "type": "string" },
"appearanceRole": { "type": "string" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
}
}
} {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ujg.specs.openuji.org/ed/ns/collection.schema.json",
"title": "UJG Collection Extension Payload",
"type": "object",
"additionalProperties": false,
"properties": {
"itemTypeRef": { "type": "string" },
"source": { "$ref": "#/$defs/source" },
"itemProjection": { "$ref": "#/$defs/itemProjection" },
"filters": {
"type": "array",
"items": { "$ref": "#/$defs/filter" }
},
"sorts": {
"type": "array",
"items": { "$ref": "#/$defs/sort" }
},
"search": { "$ref": "#/$defs/search" },
"selectionMode": {
"type": "string",
"enum": ["none", "single", "multiple"]
},
"pagination": { "$ref": "#/$defs/pagination" },
"itemActions": {
"type": "array",
"items": { "$ref": "#/$defs/action" }
},
"bulkActions": {
"type": "array",
"items": { "$ref": "#/$defs/action" }
},
"loadingPosture": {
"type": "string",
"enum": ["skeleton", "spinner", "placeholder", "silent"]
},
"emptyPosture": {
"type": "string",
"enum": ["blank", "message", "suggest-search", "fallback"]
},
"errorPosture": {
"type": "string",
"enum": ["inline", "banner", "full-state", "fallback"]
},
"appearanceRoles": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"$defs": {
"source": {
"type": "object",
"additionalProperties": false,
"properties": {
"contractRef": { "type": "string" },
"timing": {
"type": "string",
"enum": ["startup", "on-enter", "on-visible", "on-demand"]
},
"blocking": {
"type": "string",
"enum": ["required", "deferred", "non-blocking"]
},
"cacheHint": {
"type": "string",
"enum": ["none", "request", "session", "stable", "revalidate"]
}
},
"required": ["contractRef"]
},
"itemProjection": {
"type": "object",
"additionalProperties": false,
"properties": {
"layout": {
"type": "string",
"enum": ["list", "table", "cards", "grid", "stream"]
},
"properties": {
"type": "array",
"items": { "$ref": "#/$defs/property" }
},
"appearanceRole": { "type": "string" }
}
},
"property": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"kind": { "type": "string" },
"appearanceRole": { "type": "string" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"filter": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"kind": {
"type": "string",
"enum": ["choice", "multichoice", "range", "date", "toggle"]
},
"options": {
"type": "array",
"items": {
"oneOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "integer" }
]
}
},
"multiple": { "type": "boolean" },
"disabled": { "type": "boolean" }
},
"required": ["name", "kind"]
},
"sort": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"direction": {
"type": "string",
"enum": ["asc", "desc"]
},
"default": { "type": "boolean" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
},
"search": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"mode": {
"type": "string",
"enum": ["prefix", "contains", "full-text"]
},
"placeholderRole": { "type": "string" }
}
},
"pagination": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"type": "string",
"enum": ["none", "page", "cursor", "infinite"]
},
"sizeHint": {
"type": "integer",
"minimum": 1
}
},
"required": ["mode"]
},
"action": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"transitionRef": { "type": "string" },
"kind": { "type": "string" },
"appearanceRole": { "type": "string" },
"disabled": { "type": "boolean" }
},
"required": ["name"]
}
}
} 15. Minimal Example Payload
{
"@id": "urn:state:orders",
"@type": "State",
"extensions": {
"org.openuji.specs.ujg.collection.v1": {
"itemTypeRef": "urn:model:order",
"source": {
"contractRef": "urn:contract:orders-search",
"timing": "on-enter",
"blocking": "required",
"cacheHint": "revalidate"
},
"itemProjection": {
"layout": "table",
"properties": [
{ "name": "orderNumber" },
{ "name": "customer" },
{ "name": "total" },
{ "name": "status" }
]
},
"filters": [
{ "name": "status", "kind": "multichoice", "options": ["open", "paid", "cancelled"] }
],
"sorts": [
{ "name": "createdAt", "direction": "desc", "default": true }
],
"search": { "enabled": true, "mode": "contains" },
"selectionMode": "multiple",
"pagination": { "mode": "page", "sizeHint": 25 },
"bulkActions": [
{ "name": "export", "transitionRef": "urn:transition:orders-export" }
],
"loadingPosture": "skeleton",
"emptyPosture": "suggest-search",
"errorPosture": "banner",
"appearanceRoles": {
"surface": "orders-index",
"filterBar": "search-toolbar"
}
}
}
} {
"@id": "urn:state:orders",
"@type": "State",
"extensions": {
"org.openuji.specs.ujg.collection.v1": {
"itemTypeRef": "urn:model:order",
"source": {
"contractRef": "urn:contract:orders-search",
"timing": "on-enter",
"blocking": "required",
"cacheHint": "revalidate"
},
"itemProjection": {
"layout": "table",
"properties": [
{ "name": "orderNumber" },
{ "name": "customer" },
{ "name": "total" },
{ "name": "status" }
]
},
"filters": [
{ "name": "status", "kind": "multichoice", "options": ["open", "paid", "cancelled"] }
],
"sorts": [
{ "name": "createdAt", "direction": "desc", "default": true }
],
"search": { "enabled": true, "mode": "contains" },
"selectionMode": "multiple",
"pagination": { "mode": "page", "sizeHint": 25 },
"bulkActions": [
{ "name": "export", "transitionRef": "urn:transition:orders-export" }
],
"loadingPosture": "skeleton",
"emptyPosture": "suggest-search",
"errorPosture": "banner",
"appearanceRoles": {
"surface": "orders-index",
"filterBar": "search-toolbar"
}
}
}
} 16. Graduation Guidance
Thin parts that may later graduate into optional modules or shared references include:
a collection type reference,
a pagination-mode reference,
a filter-definition reference.
The following should remain extension-only:
item projection layout,
action placeholders,
search and selection posture,
loading and empty-state presentation posture.