summaryrefslogtreecommitdiffstats
path: root/browser/components/storybook/.storybook/addon-pseudo-localization/withPseudoLocalization.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/storybook/.storybook/addon-pseudo-localization/withPseudoLocalization.mjs')
-rw-r--r--browser/components/storybook/.storybook/addon-pseudo-localization/withPseudoLocalization.mjs89
1 files changed, 89 insertions, 0 deletions
diff --git a/browser/components/storybook/.storybook/addon-pseudo-localization/withPseudoLocalization.mjs b/browser/components/storybook/.storybook/addon-pseudo-localization/withPseudoLocalization.mjs
new file mode 100644
index 0000000000..9d6c62af38
--- /dev/null
+++ b/browser/components/storybook/.storybook/addon-pseudo-localization/withPseudoLocalization.mjs
@@ -0,0 +1,89 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { useEffect, useGlobals, addons } from "@storybook/addons";
+import {
+ DIRECTIONS,
+ DIRECTION_BY_STRATEGY,
+ UPDATE_STRATEGY_EVENT,
+ FLUENT_CHANGED,
+} from "./constants.mjs";
+import { provideFluent } from "../fluent-utils.mjs";
+
+/**
+ * withPseudoLocalization is a Storybook decorator that handles emitting an
+ * event to update translations when a new pseudo localization strategy is
+ * applied. It also handles setting a "dir" attribute on the root element in the
+ * Storybook iframe.
+ *
+ * @param {Function} StoryFn - Provided by Storybook, used to render the story.
+ * @param {Object} context - Provided by Storybook, data about the story.
+ * @returns {Function} StoryFn with a modified "dir" attr set.
+ */
+export const withPseudoLocalization = (StoryFn, context) => {
+ const [{ pseudoStrategy }] = useGlobals();
+ const direction = DIRECTION_BY_STRATEGY[pseudoStrategy] || DIRECTIONS.ltr;
+ const isInDocs = context.viewMode === "docs";
+ const channel = addons.getChannel();
+
+ useEffect(() => {
+ if (pseudoStrategy) {
+ channel.emit(UPDATE_STRATEGY_EVENT, pseudoStrategy);
+ }
+ }, [pseudoStrategy]);
+
+ useEffect(() => {
+ if (isInDocs) {
+ document.documentElement.setAttribute("dir", DIRECTIONS.ltr);
+ let storyElements = document.querySelectorAll(".docs-story");
+ storyElements.forEach(element => element.setAttribute("dir", direction));
+ } else {
+ document.documentElement.setAttribute("dir", direction);
+ }
+ }, [direction, isInDocs]);
+
+ return StoryFn();
+};
+
+/**
+ * withFluentStrings is a Storybook decorator that handles emitting an
+ * event to update the Fluent strings shown in the Fluent panel.
+ *
+ * @param {Function} StoryFn - Provided by Storybook, used to render the story.
+ * @param {Object} context - Provided by Storybook, data about the story.
+ * @returns {Function} StoryFn unmodified.
+ */
+export const withFluentStrings = (StoryFn, context) => {
+ const [{ fluentStrings }, updateGlobals] = useGlobals();
+ const channel = addons.getChannel();
+
+ const fileName = context.component + ".ftl";
+ let strings = [];
+
+ if (context.parameters?.fluent && fileName) {
+ if (fluentStrings.hasOwnProperty(fileName)) {
+ strings = fluentStrings[fileName];
+ } else {
+ let resource = provideFluent(context.parameters.fluent, fileName);
+ for (let message of resource.body) {
+ strings.push([
+ message.id,
+ [
+ message.value,
+ ...Object.entries(message.attributes).map(
+ ([key, value]) => ` .${key} = ${value}`
+ ),
+ ].join("\n"),
+ ]);
+ }
+ updateGlobals({
+ fluentStrings: { ...fluentStrings, [fileName]: strings },
+ });
+ }
+ }
+
+ channel.emit(FLUENT_CHANGED, strings);
+
+ return StoryFn();
+};