Skip to content

objectui: element:button forwards bodyExtra to the ActionRunner; the object-form params arm becomes a deprecation window (#5777 objectui half) #6837

Description

@os-zhuang

Blocked-by: #6819

Part of #5777 (maintainer ruling 2026-08-06, direction A — spec half landed via PR #6819). This is the objectui half the ruling split out: «objectui ActionRunner 兼容窗(弃用告警下继续接受旧 object-params 一个版本窗口)拆 objectui 子单,Blocked-by: spec 半边». Filed by the domain:spec seat at ACCEPT time per multi-repo rule 3; routing label (repo:objectui) left to the triage seat — single-producer territory, only pm:queue set here.

The measured contract (from the spec-half dev's report — verified sites, not guesses)

The blocking hop is NOT the ActionRunner — it is packages/components/src/renderers/basic/elements.tsx: the element:button click handler builds an EXPLICIT forward whitelist of action keys (type/name/label/description/target/openIn/endpoint/method/navigate/to/opensInNewTab/confirmText/successMessage/errorMessage/refreshAfter) mirroring the old spec pick list. It must gain bodyExtra: action.bodyExtra. Everything below that hop is already wired:

  • ActionRunner's ActionDef already declares bodyExtra?: SpecActionInput['bodyExtra'];
  • useConsoleActionRuntime's apiHandler already does Object.assign(body, resolvePageVarTokens(action.bodyExtra, pageVars)){{page.*}} tokens resolve exactly as they did under the old object-form params.

The compat window the ruling ordered lives at ActionRunner's existing Array.isArray(action.params) fork: keep treating a NON-array params as the static payload for one version window, emit a deprecation warning naming bodyExtra, then delete that arm. The discriminator stays Array.isArray; the two keys read as payload = {...bodyExtra} merged last over collected params.

Two secondary sites for the same card:

  • ActionRunner.executeAPI's no-custom-handler fallback (body = JSON.stringify(action.params || context.data || {})) never reads bodyExtra at all;
  • packages/types/src/ui-action.ts's inline-action prop type.

Why it matters now

Until this lands, the divergence window documented in PR #6819 is open: a page authored with bodyExtra (or an old-key page rewritten by the ADR-0087 conversion at load) validates and publishes, then is dropped one hop before the runner. Direction: spec accepts ahead of the renderer — never the reverse — but the window should be short.

Boundary

⛔ Object-form params on a type:'url' inline action is a THIRD meaning (interpolateTarget's ${param.X} scope, executeUrl's params.newTab) — out of scope here, tracked as finding #6828; do not fold a rewrite of it into the deprecation arm.

Refs: #5777 (ruling), PR #6819 (spec half, incl. the divergence-window section), #6828 (url third meaning, held finding).

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions