From 4b1d7da4bfe4c32b1166388fcb121c2e0ee74c7a Mon Sep 17 00:00:00 2001 From: castastrophe Date: Fri, 19 Jul 2024 10:52:02 -0400 Subject: [PATCH 1/8] feat(storybook): add localization tooling --- .storybook/decorators/language.js | 26 ++++++++++++---- .storybook/decorators/text-direction.js | 30 ------------------- .storybook/modes/index.js | 40 ++++++++++++++++++++++++- .storybook/package.json | 4 ++- .storybook/types/global.js | 24 ++++----------- yarn.lock | 8 +++++ 6 files changed, 77 insertions(+), 55 deletions(-) delete mode 100644 .storybook/decorators/text-direction.js diff --git a/.storybook/decorators/language.js b/.storybook/decorators/language.js index a49621d0563..97c16114d94 100644 --- a/.storybook/decorators/language.js +++ b/.storybook/decorators/language.js @@ -1,5 +1,7 @@ -import { makeDecorator, useEffect } from "@storybook/preview-api"; -import { fetchContainers } from "./helpers.js"; +import { allFakers } from "@faker-js/faker"; +import { makeDecorator, useEffect } from '@storybook/preview-api'; +import { capitalize } from "lodash-es"; +import { fetchContainers } from "./helpers"; /* global Typekit */ /** @@ -17,9 +19,21 @@ export const withLanguageWrapper = makeDecorator({ viewMode, } = context; - useEffect(() => { - const isNotEnglish = lang && lang !== "en-US"; + const isNotEnglish = lang && lang !== "en-US"; + const isRTL = ["ar", "fa", "he"].includes(lang); + + // @todo: this can't be used for VRT because the strings are random + // Attach the generator tool to the parameters for use in the story + context.generator = allFakers?.[lang]; + + // Add a custom generator for titles + context.generator.lorem.title = (count) => capitalize(context.generator.lorem.words(count)); + // Add a textDirection property to the globals for use in the story + context.globals.textDirection = isRTL ? "rtl" : "ltr"; + + + useEffect(() => { // If it is US-language or unset use the rok6rmo Adobe font web project id (smaller size), // otherwise use the mge7bvf kit with all the language settings (larger size) const kitId = isNotEnglish ? "mge7bvf" : "rok6rmo"; @@ -55,10 +69,12 @@ export const withLanguageWrapper = makeDecorator({ } catch (e) {/* empty */} } + // Set the language and direction on the relevant containers for (const container of fetchContainers(id, viewMode === "docs")) { container.lang = lang; + container.dir = !isRTL ? "ltr" : "rtl"; } - }, [lang]); + }, [lang, isNotEnglish, isRTL, viewMode, id]); return StoryFn(context); }, diff --git a/.storybook/decorators/text-direction.js b/.storybook/decorators/text-direction.js deleted file mode 100644 index 8f4168a109c..00000000000 --- a/.storybook/decorators/text-direction.js +++ /dev/null @@ -1,30 +0,0 @@ -import { makeDecorator, useEffect } from "@storybook/preview-api"; -import { fetchContainers } from "./helpers.js"; - -/** - * @type import('@storybook/csf').DecoratorFunction - * @description Sets the text direction of the document, using the global set with a toolbar control. These properties are assigned to the document root element. - **/ -export const withTextDirectionWrapper = makeDecorator({ - name: "withTextDirectionWrapper", - parameterName: "textDecoration", - wrapper: (StoryFn, context) => { - const { - globals: { - textDirection = "ltr", - } = {}, - id, - viewMode, - } = context; - - useEffect(() => { - if (!textDirection) return; - - for (const container of fetchContainers(id, viewMode === "docs")) { - container.dir = textDirection; - } - }, [textDirection]); - - return StoryFn(context); - }, -}); diff --git a/.storybook/modes/index.js b/.storybook/modes/index.js index 1b570d6c2e1..2c0a46275b9 100644 --- a/.storybook/modes/index.js +++ b/.storybook/modes/index.js @@ -13,12 +13,19 @@ const modes = { "Light | LTR": { + color: "light", + lang: "en_US", + context: "legacy", + }, + "Context: Express": { + scale: "medium", color: "light", textDirection: "ltr", + context: "express", }, "Dark | RTL": { color: "dark", - textDirection: "rtl", + lang: "ar", }, "S1 | Light | LTR": { context: "legacy", @@ -40,3 +47,34 @@ export const disableDefaultModes = { return acc; }, {}), }; + +export const mobile = { + "Mobile": { + scale: "large", + }, +}; + +export const viewports = { + small: { + width: 480, + }, +}; + +export const i18n = { + // This is the default language, so we don't need to specify it here + // "English": { + // lang: "en_US", + // }, + "Hebrew": { + lang: "he", + }, + "Japanese": { + lang: "ja", + }, + "Korean": { + lang: "ko", + }, + "Arabic": { + lang: "ar", + }, +}; diff --git a/.storybook/package.json b/.storybook/package.json index d37b6a81b1c..59728d0f3a8 100644 --- a/.storybook/package.json +++ b/.storybook/package.json @@ -9,9 +9,9 @@ "exports": { ".": "./preview.js", "./blocks": "./blocks/index.js", + "./blocks/*": "./blocks/*", "./decorators": "./decorators/index.js", "./decorators/*": "./decorators/*", - "./deprecated/*": "./deprecated/*", "./loaders": "./loaders/index.js", "./loaders/*": "./loaders/*", "./main": "./main.js", @@ -20,6 +20,7 @@ "./modes/*": "./modes/*", "./package.json": "./package.json", "./preview": "./preview.js", + "./templates/*": "./templates/*", "./types": "./types/index.js", "./types/*": "./types/*" }, @@ -40,6 +41,7 @@ "@etchteam/storybook-addon-status": "^5.0.0", "@storybook/addon-a11y": "^8.4.7", "@storybook/addon-actions": "^8.4.7", + "@faker-js/faker": "^8.4.1", "@storybook/addon-console": "^3.0.0", "@storybook/addon-designs": "^8.0.4", "@storybook/addon-docs": "^8.4.7", diff --git a/.storybook/types/global.js b/.storybook/types/global.js index aceccb44c4c..1417ad07fe8 100644 --- a/.storybook/types/global.js +++ b/.storybook/types/global.js @@ -47,19 +47,6 @@ export default { dynamicTitle: true, }, }, - textDirection: { - title: "Text direction", - description: "Direction of the content flow", - defaultValue: "ltr", - type: "string", - toolbar: { - items: [ - { value: "ltr", title: "Left to right" }, - { value: "rtl", title: "Right to left" }, - ], - dynamicTitle: true, - }, - }, // @todo https://jira.corp.adobe.com/browse/CSS-314 reducedMotion: { title: "Reduce motion", @@ -77,14 +64,15 @@ export default { lang: { title: "Language", description: "Language of the content", - defaultValue: "en-US", + defaultValue: "en_US", type: "string", toolbar: { items: [ - { value: "en-US", title: "🇺🇸", right: "English (US)" }, - { value: "ja", title: "🇯🇵", right: "日本語" }, - { value: "ko", title: "🇰🇷", right: "한국어" }, - { value: "zh", title: "🇨🇳", right: "中文" }, + { value: "en_US", title: "English", right: "English (US)" }, + { value: "he", title: "Hebrew", right: "עִברִית" }, + { value: "ja", title: "Japanese", right: "日本語" }, + { value: "ko", title: "Korean", right: "한국어" }, + { value: "ar", title: "Arabic", right: "عربي" }, ], dynamicTitle: true, }, diff --git a/yarn.lock b/yarn.lock index a5f72ca728c..da1ba13d9c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1953,6 +1953,13 @@ __metadata: languageName: node linkType: hard +"@faker-js/faker@npm:^8.4.1": + version: 8.4.1 + resolution: "@faker-js/faker@npm:8.4.1" + checksum: 10c0/4f2aecddcfdc2cc8b50b2d15d1e37302a7c7a5bbd184ae910a9d271bc11248533ca74dcdd4a9ccbe20410553e7af0f6a4d334c5b955635e09a32ddf4a64942d4 + languageName: node + linkType: hard + "@fastify/busboy@npm:^2.0.0": version: 2.1.1 resolution: "@fastify/busboy@npm:2.1.1" @@ -3830,6 +3837,7 @@ __metadata: "@babel/core": "npm:^7.26.0" "@chromaui/addon-visual-tests": "npm:^1.0.0" "@etchteam/storybook-addon-status": "npm:^5.0.0" + "@faker-js/faker": "npm:^8.4.1" "@spectrum-css/table": "workspace:^" "@spectrum-css/tokens": "workspace:^" "@spectrum-css/typography": "workspace:^" From 2b2f788b555c40b20a5a54ec5c04c52c185a1e9e Mon Sep 17 00:00:00 2001 From: Rise Erpelding Date: Mon, 4 Nov 2024 14:27:54 -0600 Subject: [PATCH 2/8] chore: remove textdirection errors --- .storybook/decorators/index.js | 1 - .storybook/preview.js | 2 -- 2 files changed, 3 deletions(-) diff --git a/.storybook/decorators/index.js b/.storybook/decorators/index.js index 059919173ba..2303747236e 100644 --- a/.storybook/decorators/index.js +++ b/.storybook/decorators/index.js @@ -17,7 +17,6 @@ export { withIconSpriteSheet } from "./icon-sprites.js"; export { withLanguageWrapper } from "./language.js"; export { withReducedMotionWrapper } from "./reduce-motion.js"; export { withTestingPreviewWrapper } from "./testing-preview.js"; -export { withTextDirectionWrapper } from "./text-direction.js"; /* This is exported but must be opted-into on a component-by-component basis */ export { withUnderlayWrapper } from "./underlay.js"; diff --git a/.storybook/preview.js b/.storybook/preview.js index 3c92dcfe186..05c6aa95f37 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -7,7 +7,6 @@ import { withLanguageWrapper, withReducedMotionWrapper, withTestingPreviewWrapper, - withTextDirectionWrapper } from "./decorators"; import { FontLoader, @@ -124,7 +123,6 @@ export default { decorators: [ withLanguageWrapper, withReducedMotionWrapper, - withTextDirectionWrapper, withContextWrapper, withTestingPreviewWrapper, withArgEvents, From 395db17f032d6ad0e873449ff0fd508d39493623 Mon Sep 17 00:00:00 2001 From: Rise Erpelding Date: Mon, 4 Nov 2024 20:17:40 -0600 Subject: [PATCH 3/8] docs(textfield): add WithLocaleText story --- components/textfield/stories/template.js | 41 +++++++++++++++++++ .../textfield/stories/textfield.stories.js | 5 ++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/components/textfield/stories/template.js b/components/textfield/stories/template.js index cdb23da0a80..c11f9867203 100644 --- a/components/textfield/stories/template.js +++ b/components/textfield/stories/template.js @@ -298,3 +298,44 @@ export const KeyboardFocusTemplate = (args, context) => Container({ }, context)} ` }, context); + +export const LocaleWrapper = (args, context) => { + const translations = { + en: { + labelText: "Username", + value: "john_doe", + }, + ja: { + labelText: "ユーザー名", + value: "山田太郎", + }, + zh: { + labelText: "用户名", + value: "张伟", + }, + ko: { + labelText: "사용자 이름", + value: "김철수", + }, + ar: { + labelText: "اسم المستخدم", + value: "محمد_أحمد", + }, + he: { + labelText: "שם משתמש", + value: "דני123", + }, + fa: { + labelText: "نام کاربری", + value: "علی_رضا", + }, + th: { + labelText: "ชื่อผู้ใช้", + value: "สมชาย", + }, + }; + const { lang } = context.globals; + const { labelText, value } = translations[lang] ?? translations.en; + + return Template({ ...args, labelText, value }, context); +}; diff --git a/components/textfield/stories/textfield.stories.js b/components/textfield/stories/textfield.stories.js index e86ce3a5d4f..26b0ca1e61f 100644 --- a/components/textfield/stories/textfield.stories.js +++ b/components/textfield/stories/textfield.stories.js @@ -3,7 +3,7 @@ import { disableDefaultModes } from "@spectrum-css/preview/modes"; import { isDisabled, isFocused, isInvalid, isKeyboardFocused, isLoading, isQuiet, isReadOnly, isRequired, isValid, size } from "@spectrum-css/preview/types"; import metadata from "../metadata/metadata.json"; import packageJson from "../package.json"; -import { HelpTextOptions, KeyboardFocusTemplate, Template, TextFieldOptions } from "./template.js"; +import { HelpTextOptions, KeyboardFocusTemplate, LocaleWrapper, Template, TextFieldOptions } from "./template.js"; import { TextFieldGroup } from "./textfield.test.js"; /** @@ -149,6 +149,9 @@ export const Default = TextFieldGroup.bind({}); Default.tags = ["!autodocs"]; Default.args = {}; +export const WithLocaleText = LocaleWrapper.bind({}); +WithLocaleText.tags = ["!autodocs"]; + // ********* DOCS ONLY ********* // export const Standard = TextFieldOptions.bind({}); From edc0109e20c4f2b4f22d7eded656f7148f37481a Mon Sep 17 00:00:00 2001 From: Rise Erpelding Date: Mon, 4 Nov 2024 20:23:33 -0600 Subject: [PATCH 4/8] docs(storybook): add more language controls --- .storybook/types/global.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.storybook/types/global.js b/.storybook/types/global.js index 1417ad07fe8..deddda0c24e 100644 --- a/.storybook/types/global.js +++ b/.storybook/types/global.js @@ -73,6 +73,9 @@ export default { { value: "ja", title: "Japanese", right: "日本語" }, { value: "ko", title: "Korean", right: "한국어" }, { value: "ar", title: "Arabic", right: "عربي" }, + { value: "zh", title: "Chinese", right: "中文" }, + { value: "fa", title: "Persian", right: "فارسی" }, + { value: "th", title: "Thai", right: "ไทย" }, ], dynamicTitle: true, }, From 566aeb7dcc2d6f610169cedcd1fd1d93c7d7cd8b Mon Sep 17 00:00:00 2001 From: Rise Erpelding Date: Mon, 4 Nov 2024 20:35:32 -0600 Subject: [PATCH 5/8] chore: remove faker --- .storybook/decorators/language.js | 9 --------- .storybook/package.json | 1 - yarn.lock | 8 -------- 3 files changed, 18 deletions(-) diff --git a/.storybook/decorators/language.js b/.storybook/decorators/language.js index 97c16114d94..3ae9a83db9c 100644 --- a/.storybook/decorators/language.js +++ b/.storybook/decorators/language.js @@ -1,6 +1,4 @@ -import { allFakers } from "@faker-js/faker"; import { makeDecorator, useEffect } from '@storybook/preview-api'; -import { capitalize } from "lodash-es"; import { fetchContainers } from "./helpers"; /* global Typekit */ @@ -22,13 +20,6 @@ export const withLanguageWrapper = makeDecorator({ const isNotEnglish = lang && lang !== "en-US"; const isRTL = ["ar", "fa", "he"].includes(lang); - // @todo: this can't be used for VRT because the strings are random - // Attach the generator tool to the parameters for use in the story - context.generator = allFakers?.[lang]; - - // Add a custom generator for titles - context.generator.lorem.title = (count) => capitalize(context.generator.lorem.words(count)); - // Add a textDirection property to the globals for use in the story context.globals.textDirection = isRTL ? "rtl" : "ltr"; diff --git a/.storybook/package.json b/.storybook/package.json index 59728d0f3a8..f52ed2787d5 100644 --- a/.storybook/package.json +++ b/.storybook/package.json @@ -41,7 +41,6 @@ "@etchteam/storybook-addon-status": "^5.0.0", "@storybook/addon-a11y": "^8.4.7", "@storybook/addon-actions": "^8.4.7", - "@faker-js/faker": "^8.4.1", "@storybook/addon-console": "^3.0.0", "@storybook/addon-designs": "^8.0.4", "@storybook/addon-docs": "^8.4.7", diff --git a/yarn.lock b/yarn.lock index da1ba13d9c4..a5f72ca728c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1953,13 +1953,6 @@ __metadata: languageName: node linkType: hard -"@faker-js/faker@npm:^8.4.1": - version: 8.4.1 - resolution: "@faker-js/faker@npm:8.4.1" - checksum: 10c0/4f2aecddcfdc2cc8b50b2d15d1e37302a7c7a5bbd184ae910a9d271bc11248533ca74dcdd4a9ccbe20410553e7af0f6a4d334c5b955635e09a32ddf4a64942d4 - languageName: node - linkType: hard - "@fastify/busboy@npm:^2.0.0": version: 2.1.1 resolution: "@fastify/busboy@npm:2.1.1" @@ -3837,7 +3830,6 @@ __metadata: "@babel/core": "npm:^7.26.0" "@chromaui/addon-visual-tests": "npm:^1.0.0" "@etchteam/storybook-addon-status": "npm:^5.0.0" - "@faker-js/faker": "npm:^8.4.1" "@spectrum-css/table": "workspace:^" "@spectrum-css/tokens": "workspace:^" "@spectrum-css/typography": "workspace:^" From f0b7ff3af42d931a4a075192d69ecf5557b094f6 Mon Sep 17 00:00:00 2001 From: Rise Erpelding Date: Tue, 5 Nov 2024 09:37:36 -0600 Subject: [PATCH 6/8] chore: add back deprecated exports --- .storybook/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.storybook/package.json b/.storybook/package.json index f52ed2787d5..31b7264ce45 100644 --- a/.storybook/package.json +++ b/.storybook/package.json @@ -12,6 +12,7 @@ "./blocks/*": "./blocks/*", "./decorators": "./decorators/index.js", "./decorators/*": "./decorators/*", + "./deprecated/*": "./deprecated/*", "./loaders": "./loaders/index.js", "./loaders/*": "./loaders/*", "./main": "./main.js", From afd2dacd52796b5d474f87145f7d9ebaed7b790b Mon Sep 17 00:00:00 2001 From: Rise Erpelding Date: Tue, 5 Nov 2024 10:45:44 -0600 Subject: [PATCH 7/8] feat: support langs in vrts --- components/textfield/stories/template.js | 10 ++++-- .../textfield/stories/textfield.stories.js | 6 ++-- .../textfield/stories/textfield.test.js | 31 ++++++++++++++++++- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/components/textfield/stories/template.js b/components/textfield/stories/template.js index c11f9867203..105bf14627b 100644 --- a/components/textfield/stories/template.js +++ b/components/textfield/stories/template.js @@ -334,8 +334,14 @@ export const LocaleWrapper = (args, context) => { value: "สมชาย", }, }; - const { lang } = context.globals; + + const { lang: contextLang } = context.globals; + const lang = args.lang || contextLang; const { labelText, value } = translations[lang] ?? translations.en; - return Template({ ...args, labelText, value }, context); + return html` +
+ ${Template({ ...args, labelText, value }, context)} +
+ `; }; diff --git a/components/textfield/stories/textfield.stories.js b/components/textfield/stories/textfield.stories.js index 26b0ca1e61f..37b80f734c6 100644 --- a/components/textfield/stories/textfield.stories.js +++ b/components/textfield/stories/textfield.stories.js @@ -3,8 +3,8 @@ import { disableDefaultModes } from "@spectrum-css/preview/modes"; import { isDisabled, isFocused, isInvalid, isKeyboardFocused, isLoading, isQuiet, isReadOnly, isRequired, isValid, size } from "@spectrum-css/preview/types"; import metadata from "../metadata/metadata.json"; import packageJson from "../package.json"; -import { HelpTextOptions, KeyboardFocusTemplate, LocaleWrapper, Template, TextFieldOptions } from "./template.js"; -import { TextFieldGroup } from "./textfield.test.js"; +import { HelpTextOptions, KeyboardFocusTemplate, Template, TextFieldOptions } from "./template.js"; +import { TextFieldGroup, TextFieldLocaleGroup } from "./textfield.test.js"; /** * Text fields are text boxes that allow users to input custom text entries with a keyboard. Various decorations can be displayed around the field to communicate the entry requirements. @@ -149,7 +149,7 @@ export const Default = TextFieldGroup.bind({}); Default.tags = ["!autodocs"]; Default.args = {}; -export const WithLocaleText = LocaleWrapper.bind({}); +export const WithLocaleText = TextFieldLocaleGroup.bind({}); WithLocaleText.tags = ["!autodocs"]; // ********* DOCS ONLY ********* // diff --git a/components/textfield/stories/textfield.test.js b/components/textfield/stories/textfield.test.js index 43d5614e8c0..de37f759fa7 100644 --- a/components/textfield/stories/textfield.test.js +++ b/components/textfield/stories/textfield.test.js @@ -1,5 +1,5 @@ import { Variants } from "@spectrum-css/preview/decorators"; -import { Template } from "./template.js"; +import { LocaleWrapper, Template } from "./template.js"; export const TextFieldGroup = Variants({ Template, @@ -63,3 +63,32 @@ export const TextFieldGroup = Variants({ isReadOnly: true, }] }); + +export const TextFieldLocaleGroup = Variants({ + Template: LocaleWrapper, + withSizes: false, + testData: [{ + testHeading: "English", + }, { + testHeading: "Hebrew", + lang: "he", + }, { + testHeading: "Japanese", + lang: "ja", + }, { + testHeading: "Korean", + lang: "ko", + }, { + testHeading: "Arabic", + lang: "ar", + }, { + testHeading: "Chinese", + lang: "zh", + }, { + testHeading: "Persian", + lang: "fa", + }, { + testHeading: "Thai", + lang: "th", + }] +}); From d437d2083f4eed586468fb3b851eba8179abdca7 Mon Sep 17 00:00:00 2001 From: Rise Erpelding Date: Thu, 14 Nov 2024 06:16:14 -0600 Subject: [PATCH 8/8] feat(storybook): add translations from a single source --- .storybook/intl/translations.json | 154 +++++++++++++++++++++++ .storybook/package.json | 1 + .storybook/preview.js | 3 + components/textfield/stories/template.js | 40 +----- 4 files changed, 162 insertions(+), 36 deletions(-) create mode 100644 .storybook/intl/translations.json diff --git a/.storybook/intl/translations.json b/.storybook/intl/translations.json new file mode 100644 index 00000000000..939580a4a90 --- /dev/null +++ b/.storybook/intl/translations.json @@ -0,0 +1,154 @@ +{ + "ar": { + "accordion.text": "", + "actionbutton.text": "", + "assetcard.name": "", + "assetlist.file": "", + "badge.label": "", + "button.label": "", + "combobox.text": "", + "fieldlabel.label": "اسم المستخدم", + "helptext.text": "", + "logicbutton.button": "", + "menu.menuItem": "", + "millercolumns.file": "", + "picker.placeholder": "", + "search.value": "", + "tag.label": "", + "textfield.value": "محمد_أحمد", + "treeview.value": "" + }, + "en": { + "accordion.text": "", + "actionbutton.text": "", + "assetcard.name": "", + "assetlist.file": "", + "badge.label": "", + "button.label": "", + "combobox.text": "", + "fieldlabel.label": "Username", + "helptext.text": "", + "logicbutton.button": "", + "menu.menuItem": "", + "millercolumns.file": "", + "picker.placeholder": "", + "search.value": "", + "tag.label": "", + "textfield.value": "john_doe", + "treeview.value": "" + }, + "fa": { + "accordion.text": "", + "actionbutton.text": "", + "assetcard.name": "", + "assetlist.file": "", + "badge.label": "", + "button.label": "", + "combobox.text": "", + "fieldlabel.label": "نام کاربری", + "helptext.text": "", + "logicbutton.button": "", + "menu.menuItem": "", + "millercolumns.file": "", + "picker.placeholder": "", + "search.value": "", + "tag.label": "", + "textfield.value": "علی_رضا", + "treeview.value": "" + }, + "he": { + "accordion.text": "", + "actionbutton.text": "", + "assetcard.name": "", + "assetlist.file": "", + "badge.label": "", + "button.label": "", + "combobox.text": "", + "fieldlabel.label": "שם משתמש", + "helptext.text": "", + "logicbutton.button": "", + "menu.menuItem": "", + "millercolumns.file": "", + "picker.placeholder": "", + "search.value": "", + "tag.label": "", + "textfield.value": "דני123", + "treeview.value": "" + }, + "ja": { + "accordion.text": "", + "actionbutton.text": "", + "assetcard.name": "", + "assetlist.file": "", + "badge.label": "", + "button.label": "", + "combobox.text": "", + "fieldlabel.label": "ユーザー名", + "helptext.text": "", + "logicbutton.button": "", + "menu.menuItem": "", + "millercolumns.file": "", + "picker.placeholder": "", + "search.value": "", + "tag.label": "", + "textfield.value": "山田太郎", + "treeview.value": "" + }, + "ko": { + "accordion.text": "", + "actionbutton.text": "", + "assetcard.name": "", + "assetlist.file": "", + "badge.label": "", + "button.label": "", + "combobox.text": "", + "fieldlabel.label": "사용자 이름", + "helptext.text": "", + "logicbutton.button": "", + "menu.menuItem": "", + "millercolumns.file": "", + "picker.placeholder": "", + "search.value": "", + "tag.label": "", + "textfield.value": "김철수", + "treeview.value": "" + }, + "th": { + "accordion.text": "", + "actionbutton.text": "", + "assetcard.name": "", + "assetlist.file": "", + "badge.label": "", + "button.label": "", + "combobox.text": "", + "fieldlabel.label": "ชื่อผู้ใช้", + "helptext.text": "", + "logicbutton.button": "", + "menu.menuItem": "", + "millercolumns.file": "", + "picker.placeholder": "", + "search.value": "", + "tag.label": "", + "textfield.value": "สมชาย", + "treeview.value": "" + }, + "zh": { + "accordion.text": "", + "actionbutton.text": "", + "assetcard.name": "", + "assetlist.file": "", + "badge.label": "", + "button.label": "", + "combobox.text": "", + "fieldlabel.label": "用户名", + "helptext.text": "", + "logicbutton.button": "", + "menu.menuItem": "", + "millercolumns.file": "", + "picker.placeholder": "", + "search.value": "", + "tag.label": "", + "textfield.value": "张伟", + "treeview.value": "" + } +} diff --git a/.storybook/package.json b/.storybook/package.json index 31b7264ce45..d2858e5089a 100644 --- a/.storybook/package.json +++ b/.storybook/package.json @@ -22,6 +22,7 @@ "./package.json": "./package.json", "./preview": "./preview.js", "./templates/*": "./templates/*", + "./translations": "./intl/translations.json", "./types": "./types/index.js", "./types/*": "./types/*" }, diff --git a/.storybook/preview.js b/.storybook/preview.js index 05c6aa95f37..75337f3c5e7 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -8,6 +8,7 @@ import { withReducedMotionWrapper, withTestingPreviewWrapper, } from "./decorators"; +import translations from "./intl/translations.json"; import { FontLoader, IconLoader, @@ -34,6 +35,8 @@ setConsoleOptions({ ], }); +export { translations }; + /** @type import('@storybook/types').StorybookParameters & import('@storybook/types').API_Layout */ export const parameters = { layout: "centered", diff --git a/components/textfield/stories/template.js b/components/textfield/stories/template.js index 105bf14627b..3eda08b34b3 100644 --- a/components/textfield/stories/template.js +++ b/components/textfield/stories/template.js @@ -2,6 +2,7 @@ import { Template as FieldLabel } from "@spectrum-css/fieldlabel/stories/templat import { Template as HelpText } from "@spectrum-css/helptext/stories/template.js"; import { Template as Icon } from "@spectrum-css/icon/stories/template.js"; import { Container, getRandomId } from "@spectrum-css/preview/decorators"; +import translations from "@spectrum-css/preview/translations"; import { Template as ProgressCircle } from "@spectrum-css/progresscircle/stories/template.js"; import { html } from "lit"; import { classMap } from "lit/directives/class-map.js"; @@ -300,44 +301,11 @@ export const KeyboardFocusTemplate = (args, context) => Container({ }, context); export const LocaleWrapper = (args, context) => { - const translations = { - en: { - labelText: "Username", - value: "john_doe", - }, - ja: { - labelText: "ユーザー名", - value: "山田太郎", - }, - zh: { - labelText: "用户名", - value: "张伟", - }, - ko: { - labelText: "사용자 이름", - value: "김철수", - }, - ar: { - labelText: "اسم المستخدم", - value: "محمد_أحمد", - }, - he: { - labelText: "שם משתמש", - value: "דני123", - }, - fa: { - labelText: "نام کاربری", - value: "علی_رضا", - }, - th: { - labelText: "ชื่อผู้ใช้", - value: "สมชาย", - }, - }; - const { lang: contextLang } = context.globals; const lang = args.lang || contextLang; - const { labelText, value } = translations[lang] ?? translations.en; + const langTranslations = translations[lang] ?? translations.en; + const labelText = langTranslations["fieldlabel.label"]; + const value = langTranslations["textfield.value"]; return html`