fix(uix): SYS-5 — drop double-written attrs owned by syncAttrs (drawer, popover)

Both parts register with `syncAttrs: true`, so the runtime writes their
morfo-declared attrs to the DOM after render — overwriting any provider re-set
(the dialog-001 mechanism). The providers re-declared the same attrs anyway:

- drawer Content [drawer-007]: dropped manual `role: 'dialog'` + `aria-modal`.
  The morfo Content declares `role: 'dialog'` and `aria-modal` (condition: the
  registered `modal` source = `variant === 'overlay'` = isOverlay) — identical
  values. Browser-verified: after the change the Content still has
  role="dialog" + aria-modal="true" on an overlay drawer, now from the morfo.
- popover Close [popover-001]: dropped manual `type: 'button'` +
  `aria-label`. The morfo Close declares `type` and `aria-label` via
  `commonRef('buttons.close')`, which syncAttrs already wrote (the provider's
  POPOVER_LANGS.CLOSE re-set was dead). Removed the now-orphan import.

Single authority per attribute (rule 7.7). check: 0 new errors; drawer +
popover provider tests 7/7.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
active-uix
dev 3 months ago
parent 8606232125
commit 729f3c0b45

@ -1041,8 +1041,10 @@ export class DrawerContentProvider {
return {
...this.runtimePart.props,
role: 'dialog' as const,
'aria-modal': this.provider.isOverlay ? true : undefined,
// role ('dialog') + aria-modal (condition: `modal` source = isOverlay) are
// declared by the morfo Content part and written by syncAttrs, which runs
// after render and would overwrite a provider re-set anyway (SYS-5 / the
// dialog-001 mechanism). The morfo is the single authority — not re-set here.
'aria-describedby': this.provider.descriptionId.current || undefined,
'aria-labelledby': this.provider.titleId.current || undefined,
'data-state': getDataOpenClosed(this.provider.opts.open.current),

@ -17,7 +17,6 @@ import type {
} from '../../types';
import { KEYS } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { POPOVER_LANGS } from './langs';
import { contains } from '$adom';
import type { TimerHandle } from '$timer';
@ -752,8 +751,9 @@ export class PopoverCloseProvider {
readonly props = $derived.by(() => ({
...this.runtimePart.props,
type: 'button' as const,
'aria-label': this.provider.soma.langs.ts(POPOVER_LANGS.CLOSE),
// type ('button') + aria-label (commonRef 'buttons.close') are declared by
// the morfo Close part + written by syncAttrs (which overwrites a provider
// re-set after render, SYS-5). The morfo is the single authority.
onclick: this.onclick
}));
}

Loading…
Cancel
Save

Powered by TurnKey Linux.