You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2026/08/29 14:24:19 UTC
(causeway) 01/06: docs(openspec): propose collection headings
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch htmx
in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 61e126c61fdd207b5ba69a6dacdb2aa57a0da2dc
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Sat Aug 29 15:37:29 2026 +0200
docs(openspec): propose collection headings
---
.../enhance-collection-headings/.openspec.yaml | 2 +
.../changes/enhance-collection-headings/design.md | 67 ++++++++++++++++++++++
.../enhance-collection-headings/proposal.md | 32 +++++++++++
.../specs/domain-web-components/spec.md | 42 ++++++++++++++
.../generic-htmx-web-component-viewer/spec.md | 27 +++++++++
.../specs/graphql-web-component-context/spec.md | 19 ++++++
.../changes/enhance-collection-headings/tasks.md | 24 ++++++++
7 files changed, 213 insertions(+)
diff --git a/openspec/changes/enhance-collection-headings/.openspec.yaml b/openspec/changes/enhance-collection-headings/.openspec.yaml
new file mode 100644
index 00000000000..50adc91034f
--- /dev/null
+++ b/openspec/changes/enhance-collection-headings/.openspec.yaml
@@ -0,0 +1,2 @@
+schema: spec-driven
+created: 2026-08-29
diff --git a/openspec/changes/enhance-collection-headings/design.md b/openspec/changes/enhance-collection-headings/design.md
new file mode 100644
index 00000000000..6db46b7318a
--- /dev/null
+++ b/openspec/changes/enhance-collection-headings/design.md
@@ -0,0 +1,67 @@
+## Context
+
+`<cw-collection>` already renders a semantic heading shell and has styling for a smaller collection description, but it derives its heading from the legacy HTML `label` attribute or the member id and does not select canonical collection metadata.
+The component also turns the collection wrapper's disabled reason into visible prose, producing messages such as “Cannot edit a mixed-in collection” even though collection contents remain useful and readable.
+Rich GraphQL wrappers already expose canonical `metadata.friendlyName` and `metadata.description`, so no schema expansion is required.
+
+## Goals / Non-Goals
+
+**Goals:**
+
+- Support application-authored collection names and descriptions with `named` and `described-as`.
+- Use canonical collection friendly names and descriptions when HTML does not override them.
+- Present descriptions below headings with quiet, smaller typography and accessible association.
+- Remove visible collection-level unmodifiable noise without changing read-only semantics.
+- Demonstrate selective combinations in Petclinic.
+
+**Non-Goals:**
+
+- Make collections editable.
+- Hide disabled reasons for properties, actions, parameters, or associated collection actions.
+- Change Rich GraphQL metadata fields or metamodel facet semantics.
+- Add toolkit-specific collection heading behavior.
+
+## Decisions
+
+### Resolve names and descriptions with explicit precedence
+
+The name precedence is `named`, legacy `label`, canonical `metadata.friendlyName`, then a humanized member id.
+The description precedence is `described-as`, canonical `metadata.description`, then no description.
+Blank explicit values are treated as absent, and a description equal to the resolved name after trimmed case-insensitive comparison is suppressed.
+
+Keeping `label` as a compatibility alias avoids breaking existing pages while making `named` the preferred domain-language attribute.
+Using light-DOM heading slots was rejected because the existing generated shell owns loading, error, empty, table, and Grid states consistently.
+
+### Select collection metadata through the existing requirement
+
+Collection requirement translation will request only supported `friendlyName` and `description` fields under the member's `metadata` wrapper.
+The component reads accepted values from the current response data rather than from schema introspection descriptors.
+This follows property metadata behavior and preserves targeted, additive GraphQL reads.
+
+### Keep disabled state but omit collection-level explanation markup
+
+The collection continues receiving hidden and disabled wrapper state and remains read-only.
+It will not render the collection wrapper's disabled boolean or reason as text, title, or tooltip.
+Member cells and associated actions retain their own authorization and usability semantics.
+
+### Retain one accessible heading shell
+
+The existing `<h2>` and optional following description remain the collection's accessible name and description through `aria-labelledby` and `aria-describedby`.
+CSS will give the description explicit inline padding, subdued color, smaller text, and spacing directly below the label before collection content.
+
+## Risks / Trade-offs
+
+- [Risk] Existing pages rely on visible collection disabled reasons. → Limit suppression to the collection wrapper; actionable controls retain their own reasons.
+- [Risk] Additional metadata broadens every selected collection query. → Select only fields supported by introspection and reuse the current bounded member read.
+- [Risk] Two HTML name attributes could conflict. → Define deterministic `named` precedence and retain `label` only for compatibility.
+- [Risk] Duplicate descriptions add noise. → Suppress descriptions equal to the resolved name.
+
+## Migration Plan
+
+No migration is required.
+Existing `label` attributes continue to work, while pages can adopt `named` and `described-as` incrementally.
+Rollback removes the two attributes, metadata selection, Petclinic examples, and collection-specific presentation changes.
+
+## Open Questions
+
+None.
diff --git a/openspec/changes/enhance-collection-headings/proposal.md b/openspec/changes/enhance-collection-headings/proposal.md
new file mode 100644
index 00000000000..fa0d73c0f56
--- /dev/null
+++ b/openspec/changes/enhance-collection-headings/proposal.md
@@ -0,0 +1,32 @@
+## Why
+
+Collection cards currently cannot express application-authored names and descriptions using the domain vocabulary requested by HTML page authors, and their visible unmodifiable reasons add noise without helping users interact with read-only collection contents.
+Collection headings should consistently present either canonical metamodel text or explicit HTML overrides, while Petclinic demonstrates both paths selectively.
+
+## What Changes
+
+- Add `named` and `described-as` attributes to `<cw-collection>` for application-authored heading overrides.
+- Load canonical collection `friendlyName` and `description` metadata through the existing targeted object context.
+- Resolve collection heading text with explicit HTML overrides taking precedence over canonical metadata and safe fallbacks.
+- Render a non-duplicate collection description directly below its label using subdued, smaller typography.
+- Stop rendering collection-level disabled or unmodifiable reasons as visible labels or tooltips while retaining read-only collection behavior.
+- Add selective Petclinic collection names and descriptions, using both `@CollectionLayout(describedAs)` and HTML `described-as` examples.
+- Add component, context, GraphQL integration, Petclinic integration, and browser regression coverage.
+
+## Capabilities
+
+### New Capabilities
+
+None.
+
+### Modified Capabilities
+
+- `domain-web-components`: Extend collection heading semantics, HTML overrides, description presentation, and quiet read-only behavior.
+- `graphql-web-component-context`: Select supported canonical collection heading metadata in targeted member reads.
+- `generic-htmx-web-component-viewer`: Demonstrate and verify selective collection names and descriptions in Petclinic.
+
+## Impact
+
+Affected code is limited to the framework-owned collection component and styles, targeted GraphQL selection state, existing test fixtures, and Petclinic domain/page examples.
+The change adds no dependency, route, toolkit, persistence, or shared application-shell behavior.
+Existing `label` markup remains compatible, while `named` is the preferred collection-name override.
diff --git a/openspec/changes/enhance-collection-headings/specs/domain-web-components/spec.md b/openspec/changes/enhance-collection-headings/specs/domain-web-components/spec.md
new file mode 100644
index 00000000000..cfcd5fe9aa4
--- /dev/null
+++ b/openspec/changes/enhance-collection-headings/specs/domain-web-components/spec.md
@@ -0,0 +1,42 @@
+## ADDED Requirements
+
+### Requirement: Semantic collection headings
+The `<cw-collection>` component SHALL render one semantic collection heading from an explicit HTML name, canonical member metadata, or a safe member-id fallback.
+It SHALL render a distinct available description directly below that heading in subdued, smaller text and associate both texts with every collection presentation state.
+
+#### Scenario: HTML supplies both overrides
+- **WHEN** a collection declares non-blank `named` and `described-as` attributes
+- **THEN** those values are the rendered collection name and description
+- **AND** they override canonical friendly-name and description metadata
+
+#### Scenario: Canonical metadata supplies heading text
+- **WHEN** no applicable HTML override exists and the collection response supplies canonical `metadata.friendlyName` or `metadata.description`
+- **THEN** each available value is used independently
+- **AND** a missing value falls back to a humanized member id for the name or no description for the description
+
+#### Scenario: Legacy label remains present
+- **WHEN** a collection declares the existing `label` attribute without `named`
+- **THEN** the label remains the effective name for backward compatibility
+- **AND** `named` takes precedence when both are non-blank
+
+#### Scenario: Description duplicates resolved name
+- **WHEN** the candidate description equals the resolved name after trimming and case-insensitive comparison
+- **THEN** no duplicate description is rendered or referenced
+
+#### Scenario: Heading attributes change
+- **WHEN** `named`, `described-as`, `label`, or the member id changes while the component is connected
+- **THEN** the current collection shell rerenders with the newly resolved accessible heading
+- **AND** collection data is not independently reloaded solely for the text change
+
+### Requirement: Quiet read-only collection presentation
+Collection wrappers SHALL remain read-only and authorization-aware without rendering their disabled or unmodifiable boolean or reason as visible explanatory text, a label, or a tooltip.
+
+#### Scenario: Mixed-in collection is unmodifiable
+- **WHEN** a readable mixed-in collection reports a disabled reason such as “Cannot edit a mixed-in collection”
+- **THEN** its rows, heading, description, paging, and applicable associated actions remain available
+- **AND** the collection-level reason is not rendered as text or tooltip
+
+#### Scenario: Member or associated action is disabled
+- **WHEN** an individual row member or associated action has its own disabled state and reason
+- **THEN** that control retains its established semantic state and explanation
+- **AND** collection-level suppression does not broaden authorization or enable mutation
diff --git a/openspec/changes/enhance-collection-headings/specs/generic-htmx-web-component-viewer/spec.md b/openspec/changes/enhance-collection-headings/specs/generic-htmx-web-component-viewer/spec.md
new file mode 100644
index 00000000000..412d61d96c7
--- /dev/null
+++ b/openspec/changes/enhance-collection-headings/specs/generic-htmx-web-component-viewer/spec.md
@@ -0,0 +1,27 @@
+## ADDED Requirements
+
+### Requirement: Petclinic collection heading demonstrations
+The Petclinic HTMX application SHALL selectively demonstrate canonical collection descriptions, HTML-authored collection names, and HTML-authored collection description overrides without requiring application-specific component code.
+
+#### Scenario: Domain facet supplies a description
+- **WHEN** a Petclinic collection annotated with `@CollectionLayout(describedAs)` is rendered without an HTML description override
+- **THEN** its canonical description appears below the effective collection name
+- **AND** collections without a description remain free of placeholder prose
+
+#### Scenario: HTML supplies collection heading overrides
+- **WHEN** a Petclinic resource page declares `named` or `described-as` on selected `<cw-collection>` elements
+- **THEN** those explicit values appear for those collections only
+- **AND** the same component continues using canonical metadata or fallbacks for other collections
+
+#### Scenario: Petclinic owner visits are rendered
+- **WHEN** the mixed-in owner visits collection loads
+- **THEN** its selected name and description are visible and accessible
+- **AND** “Cannot edit a mixed-in collection” or an equivalent collection-level tooltip is absent
+
+### Requirement: Petclinic collection heading regression coverage
+Petclinic integration and browser acceptance SHALL verify canonical and HTML-authored collection heading combinations, quiet read-only collection presentation, and unaffected collection navigation and actions.
+
+#### Scenario: Petclinic heading combinations are exercised
+- **WHEN** integration and browser tests inspect selected home and owner collections
+- **THEN** names and descriptions follow documented precedence and selective application
+- **AND** existing rows, links, paging, responsive behavior, add/remove/book actions, and error monitoring remain valid
diff --git a/openspec/changes/enhance-collection-headings/specs/graphql-web-component-context/spec.md b/openspec/changes/enhance-collection-headings/specs/graphql-web-component-context/spec.md
new file mode 100644
index 00000000000..43526b5dd70
--- /dev/null
+++ b/openspec/changes/enhance-collection-headings/specs/graphql-web-component-context/spec.md
@@ -0,0 +1,19 @@
+## ADDED Requirements
+
+### Requirement: Targeted collection heading metadata
+A semantic collection requirement SHALL select supported canonical `friendlyName` and `description` fields from the collection wrapper's existing metadata object alongside collection visibility and usability state.
+
+#### Scenario: Collection metadata fields are supported
+- **WHEN** targeted introspection finds `metadata.friendlyName` or `metadata.description` on a requested collection wrapper
+- **THEN** the object-context selection includes only the supported heading metadata fields
+- **AND** accepted response metadata is delivered with the current collection requirement state
+
+#### Scenario: Collection metadata is unavailable or partially erroneous
+- **WHEN** the wrapper lacks either heading field or GraphQL reports a nullable field-local error
+- **THEN** the remaining supported collection state stays usable
+- **AND** the component can apply explicit HTML overrides or safe fallbacks without a complete-schema read
+
+#### Scenario: Collection heading attribute changes
+- **WHEN** an HTML-only name or description override changes after metadata has loaded
+- **THEN** the component reuses the current requirement state
+- **AND** no extra GraphQL request is issued solely for presentation text
diff --git a/openspec/changes/enhance-collection-headings/tasks.md b/openspec/changes/enhance-collection-headings/tasks.md
new file mode 100644
index 00000000000..3f0bb0b01d8
--- /dev/null
+++ b/openspec/changes/enhance-collection-headings/tasks.md
@@ -0,0 +1,24 @@
+## 1. Collection metadata and heading behavior
+
+- [ ] 1.1 Extend targeted collection requirements to select supported canonical friendly-name and description metadata.
+- [ ] 1.2 Implement `named` and `described-as` collection attributes with documented precedence, compatibility, duplicate suppression, and reactive rerendering.
+- [ ] 1.3 Remove visible collection-level disabled or unmodifiable reason markup while preserving read-only and member/action semantics.
+- [ ] 1.4 Refine collection description styling below the label with accessible subdued typography.
+
+## 2. Foundation regression coverage
+
+- [ ] 2.1 Add object-context tests for targeted collection metadata selection, partial support, and request reuse.
+- [ ] 2.2 Add collection component tests for canonical and HTML heading precedence, reactive attributes, accessibility, duplicate suppression, and quiet unmodifiable state.
+- [ ] 2.3 Update stylesheet and component-contract coverage for the new public attributes and description presentation.
+
+## 3. Petclinic demonstrations
+
+- [ ] 3.1 Add selective `@CollectionLayout(describedAs)` descriptions to Petclinic collections.
+- [ ] 3.2 Add selective `named` and `described-as` overrides to Petclinic HTML pages while leaving other collections metadata-driven or unchanged.
+- [ ] 3.3 Extend Petclinic integration and Playwright assertions for names, descriptions, omitted unmodifiable noise, and unaffected interactions.
+
+## 4. Validation and archive readiness
+
+- [ ] 4.1 Run foundation tests and package verification.
+- [ ] 4.2 Run Petclinic integration and Playwright acceptance.
+- [ ] 4.3 Run strict OpenSpec validation, compilation, license, diff, and working-tree checks.