diff --git a/src/uix/morfo/components/button.ts b/src/uix/morfo/components/button.ts index 76433753c..cb428a031 100644 --- a/src/uix/morfo/components/button.ts +++ b/src/uix/morfo/components/button.ts @@ -81,13 +81,23 @@ export const buttonMorfo = { kind: 'public', defaultElement: 'button', optional: false, + // Button's loading state is fully expressed by the `data-loading` + // presence flag (declared below) — eidos CSS already uses + // `[data-loading]`, NOT `[data-state='loading']`. The morfo + // previously declared a redundant `data-state ∈ [idle, loading]` + // enum that: + // (a) duplicated `data-loading` + // (b) emitted `data-state="idle"` on every non-loading button, + // which CLOBBERED the host disclosure's `data-state="open|closed"` + // whenever Button was used as the chrome for a + // RowDetailTrigger / ExpandTrigger / DropdownMenu Trigger + // (audit 2026-05-27 caught this). + // `data-state` removed entirely. The book doctrine favours + // "presence = active state, absence = rest" for binary states + // (data-disabled, data-loading). 'idle' is not a value — it's + // the natural rest where no flag is emitted. states: ['idle', 'loading'], data: [ - { - attr: 'data-state', - values: ['idle', 'loading'], - value: v.stateRef('loading') - }, { /** * Resolved visual color. Per doctrine, when intent is