UNPKG

storybook-addon-rtl

Version:
1 lines 10.8 kB
{"version":3,"sources":["../src/constants.ts","../src/utils.ts","../src/components/DirectionArrowsIcon.tsx","../src/components/Tool.tsx","../src/manager.ts"],"names":["ADDON_ID","TOOL_ID","INITIALIZE_EVENT_ID","UPDATE_EVENT_ID","getDefaultTextDirection","api","queryParam","htmlDirection","DirectionArrowsIcon","direction","theme","useTheme","React","Tool","dirState","setDirState","useState","channel","useChannel","updateEvent","IconButton","addons","setDirectionOnStoryChange","types","viewMode","lastUserInteractionValue","STORY_RENDERED","lastUpdate","paramValue","newDirection"],"mappings":"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","file":"manager.mjs","sourcesContent":["export const ADDON_ID = \"storybook/rtl\";\nexport const TOOL_ID = `${ADDON_ID}/rtl-tool`;\n\nexport const INITIALIZE_EVENT_ID = `${ADDON_ID}/rtl-initialize`;\n/**\n * The ID for an event that is emitted in the Storybook channel whenever an change to the direction happens.\n * Events of this type should be accompanied by a parameter with a type of {@link RTLChangeEvent}\n */\nexport const UPDATE_EVENT_ID = `${ADDON_ID}/rtl-update`;\n\nexport type RTLDirection = \"rtl\" | \"ltr\";\n\nexport type RTLChangeEvent = {\n direction: RTLDirection;\n /**\n * Whether this event is the result of a user interaction,\n * or something else (like the initial state, or the parameter of a story)\n */\n userInteraction: boolean;\n};\n","import { API } from \"@storybook/manager-api\";\nimport { RTLDirection } from \"./constants\";\n\nexport function getDefaultTextDirection(api: API) {\n const queryParam = api.getQueryParam(\"direction\");\n const htmlDirection = window\n .getComputedStyle(document.documentElement)\n .direction.toLowerCase();\n return queryParam || htmlDirection || \"ltr\";\n}\n\nexport function setTextDirection(direction: RTLDirection) {\n document.documentElement.dir = direction;\n}\n","import { useTheme } from \"@storybook/theming\";\nimport React from \"react\";\nimport { RTLDirection } from \"src/constants\";\n\n// There are a lot of specific translate and scale values in this file that were picked based on trial/error\n// based on what looks the most balanced.\n/**\n * An icon with two arrows pointing in different directions.\n * Depending on the direction parameter, one of the arrows will be emphasized with color and scale.\n */\nexport const DirectionArrowsIcon = ({\n direction,\n}: {\n direction: RTLDirection;\n}) => {\n const theme = useTheme();\n const ariaLabel =\n direction === \"ltr\"\n ? \"Switch direction to right-to-left.\"\n : \"Switch Direction to left-to-right\";\n return (\n <div\n aria-label={ariaLabel}\n style={{\n width: \"20px\",\n height: \"20px\",\n position: \"relative\",\n }}\n >\n <div\n style={{\n marginBottom: \"-45%\",\n top: 0,\n display: \"flex\",\n justifyContent: \"center\",\n backgroundColor: \"transparent\",\n width: \"100%\",\n transition: \"transform 0.3s\",\n transform:\n direction === \"rtl\" ? \"scale(0.5) translate(0, -35%)\" : \"scale(1)\",\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 512 512\"\n style={{\n transition: \"fill 0.3s\",\n\n fill:\n direction === \"ltr\" ? theme.barSelectedColor : theme.barTextColor,\n height: \"100%\",\n width: \"80%\",\n }}\n >\n <path d=\"M502.6 278.6l-128 128c-12.51 12.51-32.76 12.49-45.25 0c-12.5-12.5-12.5-32.75 0-45.25L402.8 288H32C14.31 288 0 273.7 0 255.1S14.31 224 32 224h370.8l-73.38-73.38c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l128 128C515.1 245.9 515.1 266.1 502.6 278.6z\" />\n </svg>\n </div>\n <div\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n backgroundColor: \"transparent\",\n width: \"100%\",\n scale: direction === \"rtl\" ? 1 : 0.5,\n transition: \"transform 0.3s\",\n transform:\n direction === \"ltr\"\n ? \"scale(0.5) translate(0, -1px)\"\n : \"scale(1) translate(0, -20%)\",\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 512 512\"\n style={{\n transition: \"fill 0.3s\",\n\n fill:\n direction === \"rtl\" ? theme.barSelectedColor : theme.barTextColor,\n transform: \"rotate(180deg)\",\n height: \"100%\",\n width: \"80%\",\n }}\n >\n <path d=\"M502.6 278.6l-128 128c-12.51 12.51-32.76 12.49-45.25 0c-12.5-12.5-12.5-32.75 0-45.25L402.8 288H32C14.31 288 0 273.7 0 255.1S14.31 224 32 224h370.8l-73.38-73.38c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l128 128C515.1 245.9 515.1 266.1 502.6 278.6z\" />\n </svg>\n </div>\n </div>\n );\n};\n","import React, { useState } from \"react\";\nimport { useChannel } from \"@storybook/manager-api\";\nimport { RTLDirection, UPDATE_EVENT_ID } from \"src/constants\";\nimport { IconButton } from \"@storybook/components\";\nimport { DirectionArrowsIcon } from \"./DirectionArrowsIcon\";\n\nexport const Tool = () => {\n const [dirState, setDirState] = useState<{ direction: RTLDirection }>({\n direction: \"ltr\",\n });\n const channel = useChannel({\n [UPDATE_EVENT_ID]: (updateEvent) => {\n setDirState({ direction: updateEvent.direction });\n },\n });\n return (\n <>\n <IconButton\n title=\"Text Direction\"\n placeholder=\"Text Direction\"\n onClick={() => {\n channel(UPDATE_EVENT_ID, {\n direction: dirState.direction === \"rtl\" ? \"ltr\" : \"rtl\",\n userInteraction: true,\n });\n }}\n >\n <DirectionArrowsIcon direction={dirState.direction} />\n </IconButton>\n </>\n );\n};\n","import { API, addons, types } from \"@storybook/manager-api\";\nimport { ADDON_ID, RTLDirection, TOOL_ID, UPDATE_EVENT_ID } from \"./constants\";\nimport { getDefaultTextDirection } from \"./utils\";\nimport { STORY_RENDERED } from \"@storybook/core-events\";\nimport { Tool } from \"./components/Tool\";\n\naddons.register(ADDON_ID, (api) => {\n setDirectionOnStoryChange(api);\n\n addons.add(TOOL_ID, {\n id: \"rtl-tool\",\n hidden: true,\n type: types.TOOL,\n title: \"RTL\",\n disabled: true,\n match: ({ viewMode }) => {\n return viewMode === \"story\";\n },\n render: Tool,\n });\n});\n\nexport function setDirectionOnStoryChange(api: API) {\n const channel = addons.getChannel();\n // Keep track of the most recent value that was a result of user interaction\n // so we can return to this value whenever a story is opened that does not have a parameter\n let lastUserInteractionValue: RTLDirection;\n // Whenever a story is rendered, update the state to represent the parameter value of the story.\n // We do this here and not in the panel component because we want the parameter to be respected\n // even if the panel is never opened\n channel.on(STORY_RENDERED, () => {\n const lastUpdate = channel.last(UPDATE_EVENT_ID)?.[0];\n lastUserInteractionValue = lastUpdate?.userInteraction\n ? lastUpdate.direction\n : lastUserInteractionValue;\n\n const paramValue = api.getCurrentParameter(\"direction\");\n let newDirection;\n if (paramValue) {\n newDirection = paramValue;\n } else if (lastUserInteractionValue) {\n newDirection = lastUserInteractionValue;\n } else {\n newDirection = getDefaultTextDirection(api);\n }\n channel.emit(UPDATE_EVENT_ID, {\n direction: newDirection,\n userInteraction: false,\n });\n });\n}\n"]}