From d10ac7313d51d8781395ada2f0f3479e639c4409 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Date: Mon, 15 Jun 2026 08:32:16 +0500 Subject: [PATCH 1/2] feat(spec): model action-param translations in TranslationData (_actions.params) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Action labels localize via `objects.._actions..label` bundle keys, but action PARAMS (the dialog form fields) had no translation path — the `_actions` translation schema only modeled label/confirmText/successMessage, so a param's label/helpText/placeholder/options could not be localized and rendered English in a zh UI. Add an optional `params` record to the action translation schema (in ObjectTranslationDataSchema._actions, globalActions, and the secondary ObjectTranslationNodeSchema._actions): _actions..params..{ label?, helpText?, placeholder?, options? } `options` maps a select value → translated label. All optional and additive, so existing bundles are unaffected. objectui's `useObjectLabel().actionParamText()` already reads this exact key path; this unblocks authoring the bundle entries. Tests: 1149 spec tests pass (translation/i18n-resolver/typegen); DTS build green. --- packages/spec/src/system/translation.zod.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/spec/src/system/translation.zod.ts b/packages/spec/src/system/translation.zod.ts index c33833eade..24a8d01853 100644 --- a/packages/spec/src/system/translation.zod.ts +++ b/packages/spec/src/system/translation.zod.ts @@ -79,6 +79,12 @@ export const ObjectTranslationDataSchema = lazySchema(() => z.object({ label: z.string().optional().describe('Translated action label'), confirmText: z.string().optional().describe('Translated confirmation prompt'), successMessage: z.string().optional().describe('Translated success toast/message'), + params: z.record(z.string(), z.object({ + label: z.string().optional().describe('Translated action parameter label'), + helpText: z.string().optional().describe('Translated action parameter help/hint text'), + placeholder: z.string().optional().describe('Translated action parameter placeholder'), + options: z.record(z.string(), z.string()).optional().describe('Param select option value to translated label'), + })).optional().describe('Action parameter translations keyed by parameter name'), })).optional().describe('Action translations keyed by action name'), /** @@ -145,6 +151,12 @@ export const TranslationDataSchema = lazySchema(() => z.object({ label: z.string().optional().describe('Translated action label'), confirmText: z.string().optional().describe('Translated confirmation prompt'), successMessage: z.string().optional().describe('Translated success toast/message'), + params: z.record(z.string(), z.object({ + label: z.string().optional().describe('Translated action parameter label'), + helpText: z.string().optional().describe('Translated action parameter help/hint text'), + placeholder: z.string().optional().describe('Translated action parameter placeholder'), + options: z.record(z.string(), z.string()).optional().describe('Param select option value to translated label'), + })).optional().describe('Action parameter translations keyed by parameter name'), })).optional().describe('Global action translations keyed by action name'), /** @@ -466,6 +478,12 @@ export const ObjectTranslationNodeSchema = lazySchema(() => z.object({ _actions: z.record(z.string(), z.object({ label: z.string().optional().describe('Translated action label'), confirmMessage: z.string().optional().describe('Translated confirmation message'), + params: z.record(z.string(), z.object({ + label: z.string().optional().describe('Translated action parameter label'), + helpText: z.string().optional().describe('Translated action parameter help/hint text'), + placeholder: z.string().optional().describe('Translated action parameter placeholder'), + options: z.record(z.string(), z.string()).optional().describe('Param select option value to translated label'), + })).optional().describe('Action parameter translations keyed by parameter name'), })).optional().describe('Action translations keyed by action name'), /** Notification message translations keyed by notification name */ From f399acc381490a9fa5d4d9f421e4c62dcf9cd5b4 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Date: Mon, 15 Jun 2026 08:43:19 +0500 Subject: [PATCH 2/2] chore(changeset): action-param translation schema --- .changeset/action-param-translations.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/action-param-translations.md diff --git a/.changeset/action-param-translations.md b/.changeset/action-param-translations.md new file mode 100644 index 0000000000..c404f867b9 --- /dev/null +++ b/.changeset/action-param-translations.md @@ -0,0 +1,5 @@ +--- +"@objectstack/spec": patch +--- + +feat(spec): model action-param translations in TranslationData (`_actions.params`) so action param label/helpText/placeholder/options can be localized via the keys+bundles path. Additive and optional — existing bundles unaffected.