diff --git a/.changeset/address-geo-unique-ids.md b/.changeset/address-geo-unique-ids.md deleted file mode 100644 index e0e4d3b595..0000000000 --- a/.changeset/address-geo-unique-ids.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@object-ui/fields': patch ---- - -AddressField / GeolocationField sub-inputs now derive their DOM ids from a `useId()` prefix + sub-field name (the RadioField / CheckboxesField `groupId` paradigm) instead of hardcoded literals ("street", "city", "state", "zipCode", "country", "latitude", "longitude"). Two address or geolocation fields in one form no longer produce duplicate DOM ids, and each sub-label's `htmlFor` resolves to and focuses its own field's input instead of the first match in the document (#3343). diff --git a/.changeset/app-shell-sidebars-derived-area-visibility.md b/.changeset/app-shell-sidebars-derived-area-visibility.md deleted file mode 100644 index 97d8736adb..0000000000 --- a/.changeset/app-shell-sidebars-derived-area-visibility.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -`AppSidebar` and `UnifiedSidebar` area switchers now adopt the derived area -visibility introduced for `AppSchemaRenderer` in objectui#3311, closing the -same visible-but-empty gap in the console shells (objectui#3319). - -Both sidebars inlined their own area switcher without any area-level -filtering, so an area whose navigation items were **all** gated away -(`visible` expression, `requiredPermissions`, `requiresObject` / -`requiresService` capability gates) still appeared in the switcher and -rendered an empty navigation — and a fully gated *first* area was even -auto-activated, landing the user on an empty sidebar. - -## What changed - -- **Shared predicate, not a second implementation.** Both switchers now call - `hasVisibleNavigationItems` from `@object-ui/layout` — the exact guards - `NavigationRenderer` applies per item — so the switcher can never disagree - with the rendered navigation. In `UnifiedSidebar`, `action` items count as - content (it wires `onAction`, framework#4509); in `AppSidebar` they do not - (it wires none). -- **The active area is elected among visible areas only**: first visible by - default, re-elected when the active area is gated away, and a gating change - that merely *reveals* an area never steals the user's current selection. -- `areas: any[]` tightened to `NavigationArea[]` in both components. - -No authorable area-level key is introduced — visibility stays derived, per -the objectui#3311 ruling. diff --git a/.changeset/area-visibility-derived-from-items.md b/.changeset/area-visibility-derived-from-items.md deleted file mode 100644 index 6b8c75213c..0000000000 --- a/.changeset/area-visibility-derived-from-items.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -"@object-ui/layout": minor ---- - -`AppSchemaRenderer` now derives area visibility from the items inside the -area, closing the visible-but-empty regression the spec 17.0.0 area-key -retirement left behind (objectui#3311, option C of the recorded ruling). - -Spec 17.0.0 retired the authorable area-level `visible` / -`requiredPermissions` (`AREA_VISIBLE_RETIRED` / -`AREA_REQUIRED_PERMISSIONS_RETIRED`) — an area is a layout grouping, not an -access boundary — and objectui followed in #3315 by deleting the area -switcher's filter. Correct on the contract, but it changed the navigation -surface: an area whose items are **all** gated away used to disappear from -the switcher and instead rendered as a selectable, empty area. - -## What changed - -- **Area visibility is now derived, not authored.** An area appears in the - switcher iff at least one of its navigation items survives the exact - item-level guards `NavigationRenderer` applies: the `visible` expression, - `requiredPermissions`, the `requiresObject` / `requiresService` runtime - capability gates, and — for `action` items — the presence of an `onAction` - dispatcher (framework#4509: without one they are not rendered, so they - cannot carry an area either). Separators never count; a `group` counts only - through its children. -- **The active area is elected among visible areas only.** A fully gated - first area is no longer auto-activated, and when a gating change hides the - currently active area the shell re-elects the first visible one. A gating - change that merely *reveals* an area never yanks the user away from where - they are. -- **An area with no items at all derives the same way**: no visible item → - hidden. (Boundary recorded in objectui#3311.) -- New export `hasVisibleNavigationItems(items, options)` from - `@object-ui/layout` — the predicate behind the derivation, usable by other - shells that render their own area switchers. - -No authorable key is involved anywhere: the platform's `.strict()` area -object still rejects the retired keys, and the derivation — computed from the -same guards that decide what renders — cannot disagree with the rendered -navigation, so there is nothing for a metadata author to get wrong. diff --git a/.changeset/aria-required-five-more-sites.md b/.changeset/aria-required-five-more-sites.md deleted file mode 100644 index b3a3f72be7..0000000000 --- a/.changeset/aria-required-five-more-sites.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -'@object-ui/components': patch -'@object-ui/app-shell': patch -'@object-ui/plugin-detail': patch ---- - -Deliver the required state to the control in the five renderers outside the object form that still painted it as an asterisk only (objectui#3299 — the same defect #3290/#3298 fixed in `form.tsx`). - -Each site converges on the reference shape (`EmbeddableForm.tsx`): the control carries `aria-required={required || undefined}` and the asterisk is `aria-hidden="true"`, so assistive tech announces required once, as a state — instead of hearing a bare "asterisk" folded into the accessible name, or nothing at all. - -- `@object-ui/app-shell` — `ActionParamDialog` (both the boolean row and the default branch, delivered through the real field widgets' `toDomProps` whitelist) and `CreateViewDialog` (display label, machine name, and every type-specific required-field selector). -- `@object-ui/components` — the custom `ActionParamDialog` (all five typed branches, including the Radix select trigger) and `FieldContainer`, whose existing Slot injection (`id` / `aria-describedby` / `aria-invalid`) now also injects `aria-required`, covering every consumer in one place. -- `@object-ui/plugin-detail` — `InlineCreateRelated`'s create-tab inputs. - -Deliberately NOT the native `required` attribute (#3290 ruling): each of these hosts runs its own validation, and native `required` would arm the browser's constraint-validation bubble beside it. The SDUI controls that already use native `required` (`renderers/form/{input,textarea,select,checkbox}.tsx`, `basic/text-input.tsx`) are unchanged — they don't have a second validator, so their channel is already correct. diff --git a/.changeset/aria-required-reaches-the-control.md b/.changeset/aria-required-reaches-the-control.md deleted file mode 100644 index 40a226d10d..0000000000 --- a/.changeset/aria-required-reaches-the-control.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -"@object-ui/components": patch ---- - -The required state now reaches the input control as `aria-required`, instead of -existing only as part of the control's accessible name (objectui#3290). - -The form renderer has always computed a correct `required` — the static -`required` flag merged with the `requiredWhen` CEL verdict — and then spent it -on exactly one thing: the red asterisk in ``. That asterisk carried -`aria-label="required"`, so the only path from the computed state to assistive -tech was `