├── .prettierignore ├── manager.js ├── preview.js ├── manager.d.ts ├── preview.d.ts ├── src ├── manager.ts ├── index.ts ├── stories │ ├── locales │ │ ├── ja.ts │ │ ├── en.ts │ │ └── fr.ts │ ├── Test.tsx │ └── test.stories.tsx ├── preview.ts └── withI18Next.tsx ├── .storybook ├── preview-head.html ├── local-preset.js ├── main.ts ├── preview.ts └── i18next.ts ├── .prettierrc ├── .gitignore ├── vite.config.js ├── tsconfig.json ├── LICENSE ├── .github └── workflows │ └── npmpublish.yml ├── scripts ├── eject-typescript.js └── prepublish-checks.js ├── tsup.config.ts ├── package.json ├── README.md └── CHANGELOG.md /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | -------------------------------------------------------------------------------- /manager.js: -------------------------------------------------------------------------------- 1 | import './dist/manager'; 2 | -------------------------------------------------------------------------------- /preview.js: -------------------------------------------------------------------------------- 1 | export * from "./dist/preview"; 2 | -------------------------------------------------------------------------------- /manager.d.ts: -------------------------------------------------------------------------------- 1 | export * from './dist/manager.d'; 2 | -------------------------------------------------------------------------------- /preview.d.ts: -------------------------------------------------------------------------------- 1 | export * from './dist/preview.d'; 2 | -------------------------------------------------------------------------------- /src/manager.ts: -------------------------------------------------------------------------------- 1 | export * from 'storybook-i18n/manager'; 2 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // make it work with --isolatedModules 2 | export default {}; 3 | -------------------------------------------------------------------------------- /.storybook/preview-head.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": false, 3 | "singleQuote": true, 4 | "tabWidth": 4 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | storybook-static/ 4 | build-storybook.log 5 | .DS_Store 6 | .env 7 | .idea 8 | .npmrc -------------------------------------------------------------------------------- /src/stories/locales/ja.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | hello: 'こんにちは', 3 | world: '世界', 4 | click_one: '{{count}}クリック', 5 | click_other: '{{count}}クリック', 6 | }; 7 | -------------------------------------------------------------------------------- /src/stories/locales/en.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | hello: 'Hello', 3 | world: 'World', 4 | click_one: '{{count}} click', 5 | click_other: '{{count}} clicks', 6 | }; 7 | -------------------------------------------------------------------------------- /src/stories/locales/fr.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | hello: 'Bonjour', 3 | world: 'Monde', 4 | click_one: '{{count}} clic', 5 | click_other: '{{count}} clics', 6 | }; 7 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }); 8 | -------------------------------------------------------------------------------- /.storybook/local-preset.js: -------------------------------------------------------------------------------- 1 | import {fileURLToPath} from 'node:url'; 2 | 3 | /** 4 | * to load the built addon in this test Storybook 5 | */ 6 | export function previewAnnotations(entry = []) { 7 | return [...entry, fileURLToPath(import.meta.resolve('../dist/preview.js'))]; 8 | } 9 | 10 | export function managerEntries(entry = []) { 11 | return [...entry, fileURLToPath(import.meta.resolve('../dist/manager.js'))]; 12 | } 13 | -------------------------------------------------------------------------------- /src/preview.ts: -------------------------------------------------------------------------------- 1 | import type {Renderer, ProjectAnnotations} from 'storybook/internal/types'; 2 | import i18n from 'storybook-i18n/preview'; 3 | import {withI18Next} from './withI18Next'; 4 | 5 | const i18nDecorators = i18n.decorators || []; 6 | 7 | const preview: ProjectAnnotations = { 8 | ...i18n, 9 | // @ts-ignore 10 | decorators: [...i18nDecorators, withI18Next], 11 | }; 12 | 13 | export default preview; 14 | -------------------------------------------------------------------------------- /.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import {defineMain} from '@storybook/react-vite/node'; 2 | 3 | const config = defineMain({ 4 | stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], 5 | addons: [ 6 | '@storybook/addon-links', 7 | '@storybook/addon-essentials', 8 | '@storybook/addon-interactions', 9 | import.meta.resolve('./local-preset.js'), 10 | ], 11 | framework: '@storybook/react-vite', 12 | }); 13 | 14 | export default config; 15 | -------------------------------------------------------------------------------- /src/stories/Test.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import type {FC} from 'react'; 3 | import {useTranslation, Trans} from 'react-i18next'; 4 | 5 | const Test: FC = () => { 6 | const {t} = useTranslation(); 7 | const [count, setCount] = useState(0); 8 | 9 | const onClick = () => setCount((count) => count + 1); 10 | 11 | return ( 12 |
13 | {t('hello')}{' '} 14 | 15 | world 16 | 17 |
18 | 19 |
20 |
21 | ); 22 | }; 23 | 24 | export default Test; 25 | -------------------------------------------------------------------------------- /.storybook/preview.ts: -------------------------------------------------------------------------------- 1 | import type {Preview} from '@storybook/react-vite'; 2 | import i18n from './i18next'; 3 | 4 | const preview: Preview = { 5 | initialGlobals: { 6 | locale: 'en', 7 | locales: { 8 | en: {icon: '🇺🇸', title: 'English', right: 'EN'}, 9 | fr: {icon: '🇫🇷', title: 'Français', right: 'FR'}, 10 | ja: {icon: '🇯🇵', title: '日本語', right: 'JP'}, 11 | }, 12 | }, 13 | parameters: { 14 | backgrounds: { 15 | default: 'light', 16 | }, 17 | controls: { 18 | matchers: { 19 | color: /(background|color)$/i, 20 | date: /Date$/, 21 | }, 22 | }, 23 | i18n, 24 | }, 25 | }; 26 | 27 | export default preview; 28 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "skipLibCheck": true, 5 | "target": "esnext", // Node 20 according to https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping#node-20 6 | "allowJs": true, 7 | "resolveJsonModule": true, 8 | "moduleDetection": "force", 9 | "moduleResolution": "bundler", 10 | "module": "preserve", 11 | "jsx": "react", 12 | "isolatedModules": true, 13 | "verbatimModuleSyntax": true, 14 | "strict": true, 15 | "noUncheckedIndexedAccess": true, 16 | "noImplicitOverride": true, 17 | "noImplicitAny": true, 18 | "lib": ["esnext", "dom", "dom.iterable"], 19 | "baseUrl": ".", 20 | "rootDir": "." 21 | }, 22 | "include": ["src/**/*", "tsup.config.ts"] 23 | } 24 | -------------------------------------------------------------------------------- /src/stories/test.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import type {Meta, StoryObj} from '@storybook/react'; 3 | import Test from './Test'; 4 | 5 | // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export 6 | const meta: Meta = { 7 | title: 'Test', 8 | component: Test, 9 | }; 10 | 11 | export default meta; 12 | 13 | export const Default: StoryObj = { 14 | render: () => , 15 | }; 16 | 17 | export const English: StoryObj = { 18 | parameters: { 19 | locale: 'en', 20 | }, 21 | render: () => , 22 | }; 23 | 24 | export const French: StoryObj = { 25 | parameters: { 26 | locale: 'fr', 27 | }, 28 | render: () => , 29 | }; 30 | 31 | export const Japanese: StoryObj = { 32 | parameters: { 33 | locale: 'ja', 34 | }, 35 | render: () => , 36 | }; 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Storybook contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.storybook/i18next.ts: -------------------------------------------------------------------------------- 1 | import {initReactI18next} from 'react-i18next'; 2 | import i18n from 'i18next'; 3 | import Backend from 'i18next-http-backend'; 4 | import LanguageDetector from 'i18next-browser-languagedetector'; 5 | import en from '../src/stories/locales/en'; 6 | import fr from '../src/stories/locales/fr'; 7 | import ja from '../src/stories/locales/ja'; 8 | 9 | const languages: Record = {en, fr, ja}; 10 | 11 | const ns = ['common']; 12 | const supportedLngs = ['en', 'fr', 'ja']; 13 | const resources = ns.reduce((acc, n) => { 14 | supportedLngs.forEach((lng) => { 15 | if (!acc[lng]) acc[lng] = {}; 16 | acc[lng] = { 17 | ...acc[lng], 18 | [n]: languages[lng], 19 | }; 20 | }); 21 | return acc; 22 | }, {} as Record); 23 | 24 | i18n.use(initReactI18next) 25 | .use(LanguageDetector) 26 | .use(Backend) 27 | .init({ 28 | //debug: true, 29 | lng: 'en', 30 | fallbackLng: 'en', 31 | defaultNS: 'common', 32 | ns, 33 | interpolation: {escapeValue: false}, 34 | react: {useSuspense: false}, 35 | supportedLngs, 36 | resources, 37 | }); 38 | 39 | export default i18n; 40 | -------------------------------------------------------------------------------- /.github/workflows/npmpublish.yml: -------------------------------------------------------------------------------- 1 | name: npm_publish 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v1 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 12 15 | - name: Cache node modules 16 | uses: actions/cache@v1 17 | with: 18 | path: node_modules 19 | key: dependencies 20 | - run: yarn 21 | - run: yarn test 22 | - run: yarn prepare 23 | 24 | publish-npm: 25 | needs: build 26 | runs-on: ubuntu-latest 27 | steps: 28 | - uses: actions/checkout@v1 29 | - uses: actions/setup-node@v1 30 | with: 31 | node-version: 12 32 | registry-url: https://registry.npmjs.org/ 33 | - name: Cache node modules 34 | uses: actions/cache@v1 35 | with: 36 | path: node_modules 37 | key: dependencies 38 | - run: yarn 39 | - run: npm publish 40 | env: 41 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 42 | 43 | # publish-gpr: 44 | # needs: build 45 | # runs-on: ubuntu-latest 46 | # steps: 47 | # - uses: actions/checkout@v1 48 | # - uses: actions/setup-node@v1 49 | # with: 50 | # node-version: 12 51 | # registry-url: https://npm.pkg.github.com/ 52 | # scope: '@your-github-username' 53 | # - run: npm ci 54 | # - run: npm publish 55 | # env: 56 | # NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} 57 | -------------------------------------------------------------------------------- /scripts/eject-typescript.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zx 2 | 3 | // Copy TS files and delete src 4 | await $`cp -r ./src ./srcTS`; 5 | await $`rm -rf ./src`; 6 | await $`mkdir ./src`; 7 | 8 | // Install Babel and TS preset 9 | console.log(chalk.green` 10 | 11 | 🔃 Installing dependencies... 12 | 13 | `); 14 | await $`npm install --save-dev @babel/cli @babel/preset-typescript --ignore-scripts`; 15 | 16 | // Convert TS code to JS 17 | await $`babel --no-babelrc --presets @babel/preset-typescript ./srcTS -d ./src --extensions \".js,.jsx,.ts,.tsx\" --ignore "./srcTS/typings.d.ts"`; 18 | 19 | // Format the newly created .js files 20 | console.log(chalk.green` 21 | 22 | 💅 Format the newly created .js files... 23 | 24 | `); 25 | await $`prettier --write ./src`; 26 | 27 | // Add in minimal files required for the TS build setup 28 | console.log(chalk.green` 29 | 30 | ➕ Add minimal files required for the TS build setup 31 | 32 | `); 33 | await $`prettier --write ./src`; 34 | await $`touch ./src/dummy.ts`; 35 | await $`printf "export {};" >> ./src/dummy.ts`; 36 | 37 | await $`touch ./src/typings.d.ts`; 38 | await $`printf 'declare module "global";' >> ./src/typings.d.ts`; 39 | 40 | // Clean up 41 | await $`rm -rf ./srcTS`; 42 | console.log(chalk.green` 43 | 44 | 🧹 Clean up... 45 | 46 | `); 47 | await $`npm uninstall @babel/cli @babel/preset-typescript --ignore-scripts`; 48 | 49 | console.log( 50 | chalk.green.bold` 51 | TypeScript Ejection complete!`, 52 | chalk.green` 53 | Addon code converted with JS. The TypeScript build setup is still available in case you want to adopt TypeScript in the future. 54 | `, 55 | ); 56 | -------------------------------------------------------------------------------- /src/withI18Next.tsx: -------------------------------------------------------------------------------- 1 | import React, {Fragment} from 'react'; 2 | import type {ReactNode} from 'react'; 3 | import {useEffect, useGlobals, useState} from 'storybook/preview-api'; 4 | import type { 5 | PartialStoryFn as StoryFunction, 6 | Renderer, 7 | StoryContext, 8 | } from 'storybook/internal/types'; 9 | import {I18nextProvider} from 'react-i18next'; 10 | 11 | export const withI18Next = ( 12 | story: StoryFunction, 13 | context: StoryContext, 14 | ) => { 15 | const { 16 | parameters: {i18n}, 17 | } = context; 18 | 19 | if (i18n === undefined) { 20 | console.error(`The 'i18n' parameter is missing in 'parameters' configuration of preview.js. Define the 'i18n' parameter as follows: 21 | parameters: { 22 | i18n, 23 | }, 24 | `); 25 | } 26 | 27 | const language = i18n?.language; 28 | 29 | const [{locale}] = useGlobals(); 30 | const [key, setKey] = useState(0); 31 | 32 | useEffect(() => { 33 | if (i18n) { 34 | i18n.on('languageChanged', () => { 35 | setKey(Date.now()); 36 | }); 37 | return () => i18n.off('languageChanged'); 38 | } 39 | }, [i18n]); 40 | 41 | useEffect(() => { 42 | if (i18n && locale && language && locale !== language) { 43 | i18n.changeLanguage(locale); 44 | } 45 | }, [language, locale, i18n]); 46 | 47 | return ( 48 | 49 | 50 | {story(context) as ReactNode | null} 51 | 52 | 53 | ); 54 | }; 55 | -------------------------------------------------------------------------------- /scripts/prepublish-checks.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zx 2 | 3 | import boxen from 'boxen'; 4 | import dedent from 'dedent'; 5 | import {readFile} from 'node:fs/promises'; 6 | import {globalPackages as globalManagerPackages} from 'storybook/internal/manager/globals'; 7 | import {globalPackages as globalPreviewPackages} from 'storybook/internal/preview/globals'; 8 | 9 | const packageJson = await readFile('./package.json', 'utf8').then(JSON.parse); 10 | 11 | const name = packageJson.name; 12 | const displayName = packageJson.storybook.displayName; 13 | 14 | let exitCode = 0; 15 | $.verbose = false; 16 | 17 | /** 18 | * Check that meta data has been updated 19 | */ 20 | if (name.includes('addon-kit') || displayName.includes('Addon Kit')) { 21 | console.error( 22 | boxen( 23 | dedent` 24 | ${chalk.red.bold('Missing metadata')} 25 | 26 | ${chalk.red(dedent`Your package name and/or displayName includes default values from the Addon Kit. 27 | The addon gallery filters out all such addons. 28 | 29 | Please configure appropriate metadata before publishing your addon. For more info, see: 30 | https://storybook.js.org/docs/react/addons/addon-catalog#addon-metadata`)}`, 31 | {padding: 1, borderColor: 'red'}, 32 | ), 33 | ); 34 | 35 | exitCode = 1; 36 | } 37 | 38 | /** 39 | * Check that README has been updated 40 | */ 41 | const readmeTestStrings = 42 | '# Storybook Addon Kit|Click the \\*\\*Use this template\\*\\* button to get started.|https://user-images.githubusercontent.com/42671/106809879-35b32000-663a-11eb-9cdc-89f178b5273f.gif'; 43 | 44 | if ((await $`cat README.md | grep -E ${readmeTestStrings}`.exitCode) == 0) { 45 | console.error( 46 | boxen( 47 | dedent` 48 | ${chalk.red.bold('README not updated')} 49 | 50 | ${chalk.red(dedent`You are using the default README.md file that comes with the addon kit. 51 | Please update it to provide info on what your addon does and how to use it.`)} 52 | `, 53 | {padding: 1, borderColor: 'red'}, 54 | ), 55 | ); 56 | 57 | exitCode = 1; 58 | } 59 | 60 | /** 61 | * Check that globalized packages are not incorrectly listed as peer dependencies 62 | */ 63 | const peerDependencies = Object.keys(packageJson.peerDependencies || {}); 64 | const globalPackages = [...globalManagerPackages, ...globalPreviewPackages]; 65 | peerDependencies.forEach((dependency) => { 66 | if (globalPackages.includes(dependency)) { 67 | console.error( 68 | boxen( 69 | dedent` 70 | ${chalk.red.bold('Unnecessary peer dependency')} 71 | 72 | ${chalk.red(dedent`You have a peer dependency on ${chalk.bold(dependency)} which is most likely unnecessary 73 | as that is provided by Storybook directly. 74 | Check the "bundling" section in README.md for more information. 75 | If you are absolutely sure you are doing it correct, you should remove this check from scripts/prepublish-checks.js.`)} 76 | `, 77 | {padding: 1, borderColor: 'red'}, 78 | ), 79 | ); 80 | 81 | exitCode = 1; 82 | } 83 | }); 84 | 85 | process.exit(exitCode); 86 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig, type Options} from 'tsup'; 2 | 3 | const NODE_TARGET = 'node20.19'; // Minimum Node version supported by Storybook 10 4 | 5 | export default defineConfig(async () => { 6 | // reading the three types of entries from package.json, which has the following structure: 7 | // { 8 | // ... 9 | // "bundler": { 10 | // "managerEntries": ["./src/manager.ts"], 11 | // "previewEntries": ["./src/preview.ts", "./src/index.ts"] 12 | // "nodeEntries": ["./src/preset.ts"] 13 | // } 14 | // } 15 | const packageJson = (await import('./package.json', {with: {type: 'json'}})) 16 | .default; 17 | 18 | const { 19 | bundler: {managerEntries = [], previewEntries = [], nodeEntries = []}, 20 | } = packageJson; 21 | 22 | const commonConfig: Options = { 23 | /* 24 | keep this line commented until https://github.com/egoist/tsup/issues/1270 is resolved 25 | clean: options.watch ? false : true, 26 | */ 27 | clean: false, 28 | format: ['esm'], 29 | treeshake: true, 30 | splitting: true, 31 | /* 32 | The following packages are provided by Storybook and should always be externalized 33 | Meaning they shouldn't be bundled with the addon, and they shouldn't be regular dependencies either 34 | */ 35 | external: ['react', 'react-dom', '@storybook/icons'], 36 | }; 37 | 38 | const configs: Options[] = []; 39 | 40 | /* 41 | manager entries are entries meant to be loaded into the manager UI 42 | they'll have manager-specific packages externalized and they won't be usable in node 43 | they won't have types generated for them as they're usually loaded automatically by Storybook 44 | */ 45 | if (managerEntries.length) { 46 | configs.push({ 47 | ...commonConfig, 48 | entry: managerEntries, 49 | platform: 'browser', 50 | target: 'esnext', // we can use esnext for manager entries since Storybook will bundle the addon's manager entries again anyway 51 | }); 52 | } 53 | 54 | /* 55 | preview entries are entries meant to be loaded into the preview iframe 56 | they'll have preview-specific packages externalized and they won't be usable in node 57 | they'll have types generated for them so they can be imported by users when setting up Portable Stories or using CSF factories 58 | */ 59 | if (previewEntries.length) { 60 | configs.push({ 61 | ...commonConfig, 62 | entry: previewEntries, 63 | platform: 'browser', 64 | target: 'esnext', // we can use esnext for preview entries since the builders will bundle the addon's preview entries again anyway 65 | dts: true, 66 | }); 67 | } 68 | 69 | /* 70 | node entries are entries meant to be used in node-only 71 | this is useful for presets, which are loaded by Storybook when setting up configurations 72 | they won't have types generated for them as they're usually loaded automatically by Storybook 73 | */ 74 | if (nodeEntries.length) { 75 | configs.push({ 76 | ...commonConfig, 77 | entry: nodeEntries, 78 | platform: 'node', 79 | target: NODE_TARGET, 80 | }); 81 | } 82 | 83 | return configs; 84 | }); 85 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "storybook-react-i18next", 3 | "version": "10.0.1", 4 | "description": "Add react-i18next support to Storybook", 5 | "keywords": [ 6 | "storybook-addons", 7 | "storybook-i18n", 8 | "react-i18next", 9 | "i18next", 10 | "i18n", 11 | "localization", 12 | "internationalization" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/stevensacks/storybook-react-i18next" 17 | }, 18 | "license": "MIT", 19 | "author": "Steven Sacks", 20 | "type": "module", 21 | "exports": { 22 | ".": { 23 | "types": "./dist/index.d.ts", 24 | "default": "./dist/index.js" 25 | }, 26 | "./preview": { 27 | "types": "./dist/preview.d.ts", 28 | "default": "./dist/preview.js" 29 | }, 30 | "./manager": "./dist/manager.js", 31 | "./package.json": "./package.json" 32 | }, 33 | "files": [ 34 | "dist/**/*", 35 | "README.md", 36 | "*.js", 37 | "*.d.ts" 38 | ], 39 | "scripts": { 40 | "prebuild": "node -e \"fs.rmSync('./dist', { recursive: true, force: true })\"", 41 | "build": "tsup", 42 | "build-storybook": "storybook build", 43 | "build:watch": "npm run build -- --watch", 44 | "eject-ts": "zx scripts/eject-typescript.js", 45 | "format": "prettier --write .", 46 | "lint": "eslint --cache .", 47 | "lint:fix": "pnpm lint --fix", 48 | "prerelease": "zx scripts/prepublish-checks.js", 49 | "release": "npm run build && auto shipit", 50 | "start": "run-p build:watch \"storybook --quiet\"", 51 | "storybook": "storybook dev -p 6006", 52 | "test": "echo \"Error: no test specified\" && exit 1" 53 | }, 54 | "dependencies": { 55 | "storybook-i18n": "^10.0.2" 56 | }, 57 | "devDependencies": { 58 | "@eslint/js": "^9.36.0", 59 | "@storybook/react-vite": "^10.0.0", 60 | "@types/node": "^20", 61 | "@types/react": "^18.2.65", 62 | "@types/react-dom": "^18.2.21", 63 | "@vitejs/plugin-react": "^4.7.0", 64 | "auto": "^11.3.0", 65 | "boxen": "^8.0.1", 66 | "eslint": "^9.36.0", 67 | "eslint-config-prettier": "^10.1.8", 68 | "eslint-plugin-prettier": "^5.5.4", 69 | "eslint-plugin-react": "^7.37.5", 70 | "eslint-plugin-storybook": "^10.0.0", 71 | "i18next": "25.6.0", 72 | "i18next-browser-languagedetector": "8.2.0", 73 | "i18next-http-backend": "3.0.2", 74 | "npm-run-all2": "^8.0.4", 75 | "prettier": "^3.6.2", 76 | "prompts": "^2.4.2", 77 | "react": "^18.2.0", 78 | "react-dom": "^18.2.0", 79 | "storybook": "^10.0.0", 80 | "ts-dedent": "^2.2.0", 81 | "tsup": "^8.5.0", 82 | "typescript": "^5.8.3", 83 | "typescript-eslint": "^8.44.1", 84 | "vite": "^7.0.5", 85 | "zx": "^8.7.1" 86 | }, 87 | "peerDependencies": { 88 | "i18next": "^22.0.0 || ^23.0.0 || ^24.0.0 || ^25.0.0", 89 | "i18next-browser-languagedetector": "^7.0.0 || ^8.0.0", 90 | "i18next-http-backend": "^2.0.0 || ^3.0.0", 91 | "react-i18next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", 92 | "storybook": "^9.0.0 || ^10.0.0" 93 | }, 94 | "publishConfig": { 95 | "access": "public" 96 | }, 97 | "bundler": { 98 | "exportEntries": [ 99 | "src/index.ts" 100 | ], 101 | "managerEntries": [ 102 | "src/manager.ts" 103 | ], 104 | "previewEntries": [ 105 | "src/preview.ts", 106 | "src/index.ts" 107 | ] 108 | }, 109 | "storybook": { 110 | "displayName": "Storybook react-i18next addon", 111 | "supportedFrameworks": [ 112 | "react" 113 | ], 114 | "icon": "https://user-images.githubusercontent.com/321738/63501763-88dbf600-c4cc-11e9-96cd-94adadc2fd72.png" 115 | }, 116 | "packageManager": "pnpm@10.0.0", 117 | "pnpm": { 118 | "onlyBuiltDependencies": [ 119 | "esbuild" 120 | ] 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Storybook react-i18next addon 2 | 3 | Easy react-i18next Storybook integration. 4 | 5 | Required Peer Dependencies: 6 | * Version 10.x - storybook - `^10.0.0` 7 | * Version 4.x - storybook - `^9.0.0` 8 | * Version 3.x - storybook - `^8.0.0` 9 | 10 | * i18next - `^22.0.0 || ^23.0.0 || ^24.0.0 || ^25.0.0` 11 | * i18next-browser-languagedetector - `^7.0.0 || ^8.0.0` 12 | * i18next-http-backend: `^2.0.0 || ^3.0.0` 13 | * react-i18next - `^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0` 14 | 15 | This Storybook addon assumes your project is already set up with [i18next](https://www.i18next.com/overview/getting-started) and [react-i18next](https://react.i18next.com/getting-started), with all the required packages installed, and that it is properly configured and working. 16 | 17 | ## Installation 18 | 19 | Install this addon as a devDependency. 20 | 21 | ```bash 22 | npm i -D storybook-react-i18next 23 | ``` 24 | 25 | You will need to install `i18next` and `react-i18next` as dependencies to your project if they are not already installed. 26 | ```bash 27 | npm i -S i18next react-i18next i18next-browser-languagedetector i18next-http-backend 28 | ``` 29 | 30 | ## Usage 31 | 32 | After installing, follow these 3 steps to enable this addon in Storybook. 33 | 34 | ### main.ts 35 | Insert this addon into your addons array: 36 | ```typescript 37 | { 38 | addons: [ 39 | // other addons... 40 | 'storybook-react-i18next', 41 | ] 42 | } 43 | ``` 44 | --- 45 | 46 | ### i18next.ts 47 | Create a file in your `.storybook` folder called `i18next.ts` (or whatever you like). 48 | 49 | In this file, copy and paste the below code and make whatever modifications you need (paths to resource files, languages, etc.). 50 | ```typescript 51 | import {initReactI18next} from 'react-i18next'; 52 | import i18n from 'i18next'; 53 | import Backend from 'i18next-http-backend'; 54 | import LanguageDetector from 'i18next-browser-languagedetector'; 55 | 56 | const ns = ['common']; 57 | const supportedLngs = ['en', 'fr', 'ja']; 58 | const resources = ns.reduce((acc, n) => { 59 | supportedLngs.forEach((lng) => { 60 | if (!acc[lng]) acc[lng] = {}; 61 | acc[lng] = { 62 | ...acc[lng], 63 | [n]: require(`../public/locales/${lng}/${n}.json`), 64 | }; 65 | }); 66 | return acc; 67 | }, {}); 68 | 69 | i18n.use(initReactI18next) 70 | .use(LanguageDetector) 71 | .use(Backend) 72 | .init({ 73 | //debug: true, 74 | lng: 'en', 75 | fallbackLng: 'en', 76 | defaultNS: 'common', 77 | ns, 78 | interpolation: {escapeValue: false}, 79 | react: {useSuspense: false}, 80 | supportedLngs, 81 | resources, 82 | }); 83 | 84 | export default i18n; 85 | ``` 86 | 87 | Refer to the [i18next Configuration Options](https://www.i18next.com/overview/configuration-options) documentation for detailed information about the configuration options. 88 | 89 | --- 90 | 91 | ### preview.ts 92 | In your `preview.ts`, you need to add the `locales` and `locale` to` initialGlobals` (or `globals` if you're not using the latest version of storybook), as well as adding `i18n` that you exported from the above file to parameters. 93 | 94 | `locales` is an object where the keys are the "ids" of the locales/languages and the values are the names you want to display in the dropdown. 95 | 96 | `locale` is what you want the default locale to be. 97 | 98 | ```typescript 99 | import i18n from './i18next'; 100 | 101 | const preview: Preview = { 102 | initialGlobals: { 103 | locale: 'en', 104 | locales: { 105 | en: 'English', 106 | fr: 'Français', 107 | ja: '日本語', 108 | }, 109 | }, 110 | parameters: { 111 | i18n, 112 | }, 113 | }; 114 | 115 | export default preview; 116 | ``` 117 | 118 | You can also use full locale strings as keys. It depends on your i18next configuration. 119 | 120 | ```typescript 121 | import i18n from './i18next'; 122 | 123 | const preview: Preview = { 124 | initialGlobals: { 125 | locale: 'en_US', 126 | locales: { 127 | en_US: 'English (US)', 128 | en_GB: 'English (GB)', 129 | fr_FR: 'Français', 130 | ja_JP: '日本語', 131 | }, 132 | }, 133 | parameters: { 134 | i18n, 135 | }, 136 | }; 137 | 138 | export default preview; 139 | ``` 140 | 141 | 142 | The `locales` object can also have values as an object with keys of `title`, `left`, or `right`. 143 | 144 | This is useful if you want to include an emoji flag or some other string to the left or right side. 145 | 146 | For example: 147 | ```typescript 148 | import i18n from './i18next'; 149 | 150 | const preview: Preview = { 151 | initialGlobals: { 152 | locale: "en", 153 | locales: { 154 | en: {icon: '🇺🇸', title: 'English', right: 'EN'}, 155 | fr: {icon: '🇫🇷', title: 'Français', right: 'FR'}, 156 | ja: {icon: '🇯🇵', title: '日本語', right: 'JP'}, 157 | }, 158 | }, 159 | parameters: { 160 | i18n, 161 | }, 162 | }; 163 | 164 | export default preview; 165 | ``` 166 | 167 | Or something like this: 168 | ```typescript 169 | import i18n from './i18next'; 170 | 171 | const preview: Preview = { 172 | initialGlobals: { 173 | locale: 'en_US', 174 | locales: { 175 | en_US: {title: 'English', right: 'US'}, 176 | en_GB: {title: 'English', right: 'GB'}, 177 | fr_FR: {title: 'Français', right: 'FR'}, 178 | ja_JP: {title: '日本語', right: 'JP'}, 179 | }, 180 | }, 181 | parameters: { 182 | i18n, 183 | }, 184 | }; 185 | 186 | export default preview; 187 | ``` 188 | 189 | ## Story Parameters Locale 190 | 191 | If you want to have a story use a specific locale, set it in that Story's parameters. 192 | 193 | ```typescript jsx 194 | export const Default: StoryObj = { 195 | render: () => , 196 | }; 197 | 198 | export const Japanese: StoryObj = { 199 | parameters: { 200 | locale: 'ja', 201 | }, 202 | render: () => , 203 | }; 204 | ``` 205 | Note that doing this switches the current locale to the parameter one, so when you change to a story without a parameter, it will stay at the last selected locale. 206 | 207 | In the above example, if you view the Japanese story and then click back on the Default story, the locale will stay `ja`. 208 | 209 | --- 210 | Once you have finished these steps and launch storybook, you should see a globe icon in the toolbar. 211 | 212 | Clicking this globe icon will show a dropdown with the locales you defined in `parameters`. 213 | 214 | Switching locales will use the strings defined in your locale json files. 215 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # v4.0.13 (Fri Nov 07 2025) 2 | 3 | #### 🐛 Bug Fix 4 | 5 | - feat: migrate to storybook 10 [#42](https://github.com/stevensacks/storybook-react-i18next/pull/42) ([@stevensacks](https://github.com/stevensacks)) 6 | 7 | #### ⚠️ Pushed to `main` 8 | 9 | - fix: remove react as peerDep ([@stevensacks](https://github.com/stevensacks)) 10 | 11 | #### Authors: 1 12 | 13 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 14 | 15 | --- 16 | 17 | # v4.0.12 (Sat Nov 01 2025) 18 | 19 | #### ⚠️ Pushed to `main` 20 | 21 | - chore: resolve conflicts ([@stevensacks](https://github.com/stevensacks)) 22 | - chore: add support for react-i18next 16.x ([@stevensacks](https://github.com/stevensacks)) 23 | 24 | #### Authors: 1 25 | 26 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 27 | 28 | --- 29 | 30 | # v4.0.11 (Fri Jun 13 2025) 31 | 32 | #### ⚠️ Pushed to `main` 33 | 34 | - Merge branch 'main' of github.com:stevensacks/storybook-react-i18next ([@stevensacks](https://github.com/stevensacks)) 35 | - fix: git issue ([@stevensacks](https://github.com/stevensacks)) 36 | 37 | #### Authors: 1 38 | 39 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 40 | 41 | --- 42 | 43 | # v4.0.9 (Fri Jun 13 2025) 44 | 45 | #### ⚠️ Pushed to `main` 46 | 47 | - fix: storybook 9 peerDep ([@stevensacks](https://github.com/stevensacks)) 48 | 49 | #### Authors: 1 50 | 51 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 52 | 53 | --- 54 | 55 | # v4.0.8 (Wed Jun 11 2025) 56 | 57 | #### ⚠️ Pushed to `main` 58 | 59 | - Merge branch 'main' of github.com:stevensacks/storybook-react-i18next ([@stevensacks](https://github.com/stevensacks)) 60 | - fix: set storybook peerDep to workspace ([@stevensacks](https://github.com/stevensacks)) 61 | - fix: more explicit react peerDependency ([@stevensacks](https://github.com/stevensacks)) 62 | 63 | #### Authors: 1 64 | 65 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 66 | 67 | --- 68 | 69 | # v4.0.7 (Wed Jun 11 2025) 70 | 71 | #### ⚠️ Pushed to `main` 72 | 73 | - chore: remove peerDependency check ([@stevensacks](https://github.com/stevensacks)) 74 | - Merge branch 'main' of github.com:stevensacks/storybook-react-i18next ([@stevensacks](https://github.com/stevensacks)) 75 | - fix: add react to external in tsup ([@stevensacks](https://github.com/stevensacks)) 76 | 77 | #### Authors: 1 78 | 79 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 80 | 81 | --- 82 | 83 | # v4.0.6 (Wed Jun 11 2025) 84 | 85 | #### ⚠️ Pushed to `main` 86 | 87 | - fix: remove tsup js file ([@stevensacks](https://github.com/stevensacks)) 88 | 89 | #### Authors: 1 90 | 91 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 92 | 93 | --- 94 | 95 | # v4.0.5 (Wed Jun 11 2025) 96 | 97 | #### 🐛 Bug Fix 98 | 99 | - Revert "Add `react` to `peerDependencies` to prevent multiple React versions from being bundled" [#38](https://github.com/stevensacks/storybook-react-i18next/pull/38) ([@stevensacks](https://github.com/stevensacks)) 100 | - Add `react` to `peerDependencies` to prevent multiple React versions from being bundled [#37](https://github.com/stevensacks/storybook-react-i18next/pull/37) ([@odanado](https://github.com/odanado)) 101 | 102 | #### Authors: 2 103 | 104 | - odan ([@odanado](https://github.com/odanado)) 105 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 106 | 107 | --- 108 | 109 | # v4.0.4 (Fri Jun 06 2025) 110 | 111 | #### ⚠️ Pushed to `main` 112 | 113 | - Merge branch 'main' of github.com:stevensacks/storybook-react-i18next ([@stevensacks](https://github.com/stevensacks)) 114 | - fix: storybook-i18n updated for globe icon ([@stevensacks](https://github.com/stevensacks)) 115 | 116 | #### Authors: 1 117 | 118 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 119 | 120 | --- 121 | 122 | # v4.0.3 (Wed May 28 2025) 123 | 124 | #### ⚠️ Pushed to `main` 125 | 126 | - feat: storybook 9 release ([@stevensacks](https://github.com/stevensacks)) 127 | 128 | #### Authors: 1 129 | 130 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 131 | 132 | --- 133 | 134 | # v4.0.2 (Fri May 23 2025) 135 | 136 | #### ⚠️ Pushed to `main` 137 | 138 | - feat: upgrade deps ([@stevensacks](https://github.com/stevensacks)) 139 | 140 | #### Authors: 1 141 | 142 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 143 | 144 | --- 145 | 146 | # v3.3.2 (Sun May 04 2025) 147 | 148 | #### ⚠️ Pushed to `main` 149 | 150 | - fix: use node 20 for build ([@stevensacks](https://github.com/stevensacks)) 151 | - chore: add storybook packageManager ([@stevensacks](https://github.com/stevensacks)) 152 | - fix: storybook scripts to v9 ([@stevensacks](https://github.com/stevensacks)) 153 | - feat: add storybook 9 support ([@stevensacks](https://github.com/stevensacks)) 154 | 155 | #### Authors: 1 156 | 157 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 158 | 159 | --- 160 | 161 | # v3.2.2 (Wed Apr 30 2025) 162 | 163 | #### ⚠️ Pushed to `main` 164 | 165 | - merge: merge in changes ([@stevensacks](https://github.com/stevensacks)) 166 | - fix: add i18next v25 to peerDependencies ([@stevensacks](https://github.com/stevensacks)) 167 | 168 | #### Authors: 1 169 | 170 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 171 | 172 | --- 173 | 174 | # v3.1.9 (Mon Jan 20 2025) 175 | 176 | #### ⚠️ Pushed to `main` 177 | 178 | - ci: update to checkout v4 ([@stevensacks](https://github.com/stevensacks)) 179 | - feat: support i18next-http-backend 3.x ([@stevensacks](https://github.com/stevensacks)) 180 | 181 | #### Authors: 1 182 | 183 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 184 | 185 | --- 186 | 187 | # v3.1.8 (Tue Dec 10 2024) 188 | 189 | #### ⚠️ Pushed to `main` 190 | 191 | - feat: remove react from peerDeps for react 19 compat ([@stevensacks](https://github.com/stevensacks)) 192 | 193 | #### Authors: 1 194 | 195 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 196 | 197 | --- 198 | 199 | # v3.1.7 (Mon Jul 29 2024) 200 | 201 | #### ⚠️ Pushed to `main` 202 | 203 | - Merge branch 'main' of github.com:stevensacks/storybook-react-i18next ([@stevensacks](https://github.com/stevensacks)) 204 | - fix: storybook/test should be in devDependencies, not dependencies ([@stevensacks](https://github.com/stevensacks)) 205 | 206 | #### Authors: 1 207 | 208 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 209 | 210 | --- 211 | 212 | # v3.1.6 (Mon Jul 29 2024) 213 | 214 | #### ⚠️ Pushed to `main` 215 | 216 | - Merge branch 'main' of github.com:stevensacks/storybook-react-i18next ([@stevensacks](https://github.com/stevensacks)) 217 | - feat: change to storybook 8.2 initialGlobals ([@stevensacks](https://github.com/stevensacks)) 218 | 219 | #### Authors: 1 220 | 221 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 222 | 223 | --- 224 | 225 | # v3.1.5 (Mon Jul 22 2024) 226 | 227 | #### ⚠️ Pushed to `main` 228 | 229 | - docs: update README for latest version of storybook initialGlobals ([@stevensacks](https://github.com/stevensacks)) 230 | 231 | #### Authors: 1 232 | 233 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 234 | 235 | --- 236 | 237 | # v3.1.4 (Mon Jul 22 2024) 238 | 239 | #### 🐛 Bug Fix 240 | 241 | - add friendly error message if i18n is undefined [#29](https://github.com/stevensacks/storybook-react-i18next/pull/29) ([@odanado](https://github.com/odanado)) 242 | 243 | #### ⚠️ Pushed to `main` 244 | 245 | - Merge branch 'main' of github.com:stevensacks/storybook-react-i18next ([@stevensacks](https://github.com/stevensacks)) 246 | - ci: use node 18 for build ([@stevensacks](https://github.com/stevensacks)) 247 | 248 | #### Authors: 2 249 | 250 | - odanado ([@odanado](https://github.com/odanado)) 251 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 252 | 253 | --- 254 | 255 | # v3.1.3 (Mon Jul 22 2024) 256 | 257 | #### ⚠️ Pushed to `main` 258 | 259 | - Merge branch 'main' of github.com:stevensacks/storybook-react-i18next ([@stevensacks](https://github.com/stevensacks)) 260 | - docs: update README to reflect react-i18next 15.x ([@stevensacks](https://github.com/stevensacks)) 261 | 262 | #### Authors: 1 263 | 264 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 265 | 266 | --- 267 | 268 | # v3.1.2 (Mon Jul 22 2024) 269 | 270 | #### ⚠️ Pushed to `main` 271 | 272 | - chore: add react-i18next 15.x to peerDependencies ([@stevensacks](https://github.com/stevensacks)) 273 | 274 | #### Authors: 1 275 | 276 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 277 | 278 | --- 279 | 280 | # v3.0.2 (Tue May 14 2024) 281 | 282 | #### ⚠️ Pushed to `main` 283 | 284 | - chore: update README with supported versions ([@stevensacks](https://github.com/stevensacks)) 285 | - feat: add support for i18next-browser-languagedetector ^8.0.0 ([@stevensacks](https://github.com/stevensacks)) 286 | 287 | #### Authors: 1 288 | 289 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 290 | 291 | --- 292 | 293 | # v2.1.3 (Fri Mar 15 2024) 294 | 295 | #### ⚠️ Pushed to `main` 296 | 297 | - feat: bump major version for storybook 8 ([@stevensacks](https://github.com/stevensacks)) 298 | - feat: update storybook-i18n to 3.x ([@stevensacks](https://github.com/stevensacks)) 299 | 300 | #### Authors: 1 301 | 302 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 303 | 304 | --- 305 | 306 | # v2.1.3 (Fri Mar 15 2024) 307 | 308 | #### ⚠️ Pushed to `main` 309 | 310 | - feat: update storybook-i18n to 3.x ([@stevensacks](https://github.com/stevensacks)) 311 | 312 | #### Authors: 1 313 | 314 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 315 | 316 | --- 317 | 318 | # v2.1.2 (Thu Mar 14 2024) 319 | 320 | #### ⚠️ Pushed to `main` 321 | 322 | - feat: storybook 8 release ([@stevensacks](https://github.com/stevensacks)) 323 | 324 | #### Authors: 1 325 | 326 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 327 | 328 | --- 329 | 330 | # v2.0.11 (Wed Mar 06 2024) 331 | 332 | #### 🐛 Bug Fix 333 | 334 | - feat: storybook 8 [#27](https://github.com/stevensacks/storybook-react-i18next/pull/27) ([@stevensacks](https://github.com/stevensacks)) 335 | 336 | #### Authors: 1 337 | 338 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 339 | 340 | --- 341 | 342 | # v2.0.10 (Fri Dec 22 2023) 343 | 344 | #### ⚠️ Pushed to `main` 345 | 346 | - chore: update scripts ([@stevensacks](https://github.com/stevensacks)) 347 | - feat: support react-i18next 14.x ([@stevensacks](https://github.com/stevensacks)) 348 | 349 | #### Authors: 1 350 | 351 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 352 | 353 | --- 354 | 355 | # v2.0.4 (Mon Nov 27 2023) 356 | 357 | #### 🐛 Bug Fix 358 | 359 | - feat: add support for 'defaultRichTextElements' in IntlProvider [#10](https://github.com/stevensacks/storybook-react-intl/pull/10) ([@ridvankaradag](https://github.com/ridvankaradag)) 360 | 361 | #### ⚠️ Pushed to `main` 362 | 363 | - remove unnecessary peer deps ([@stevensacks](https://github.com/stevensacks)) 364 | - add boxen ([@stevensacks](https://github.com/stevensacks)) 365 | - update addonkit to latest ([@stevensacks](https://github.com/stevensacks)) 366 | - update script ([@stevensacks](https://github.com/stevensacks)) 367 | - update tsup config ([@stevensacks](https://github.com/stevensacks)) 368 | - update scripts ([@stevensacks](https://github.com/stevensacks)) 369 | - update deps ([@stevensacks](https://github.com/stevensacks)) 370 | - chore: update gitignore ([@stevensacks](https://github.com/stevensacks)) 371 | - chore: repository url fix ([@stevensacks](https://github.com/stevensacks)) 372 | 373 | #### Authors: 2 374 | 375 | - Rıdvan Karadağ ([@ridvankaradag](https://github.com/ridvankaradag)) 376 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 377 | 378 | --- 379 | 380 | # v2.0.4 (Mon Nov 27 2023) 381 | 382 | #### 🐛 Bug Fix 383 | 384 | - feat: add support for 'defaultRichTextElements' in IntlProvider [#10](https://github.com/stevensacks/storybook-react-intl/pull/10) ([@ridvankaradag](https://github.com/ridvankaradag)) 385 | 386 | #### ⚠️ Pushed to `main` 387 | 388 | - remove unnecessary peer deps ([@stevensacks](https://github.com/stevensacks)) 389 | - add boxen ([@stevensacks](https://github.com/stevensacks)) 390 | - update addonkit to latest ([@stevensacks](https://github.com/stevensacks)) 391 | - update script ([@stevensacks](https://github.com/stevensacks)) 392 | - update tsup config ([@stevensacks](https://github.com/stevensacks)) 393 | - update scripts ([@stevensacks](https://github.com/stevensacks)) 394 | - update deps ([@stevensacks](https://github.com/stevensacks)) 395 | - chore: update gitignore ([@stevensacks](https://github.com/stevensacks)) 396 | - chore: repository url fix ([@stevensacks](https://github.com/stevensacks)) 397 | 398 | #### Authors: 2 399 | 400 | - Rıdvan Karadağ ([@ridvankaradag](https://github.com/ridvankaradag)) 401 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 402 | 403 | --- 404 | 405 | # v2.0.4 (Mon Nov 27 2023) 406 | 407 | #### 🐛 Bug Fix 408 | 409 | - feat: add support for 'defaultRichTextElements' in IntlProvider [#10](https://github.com/stevensacks/storybook-react-intl/pull/10) ([@ridvankaradag](https://github.com/ridvankaradag)) 410 | 411 | #### ⚠️ Pushed to `main` 412 | 413 | - chore: update gitignore ([@stevensacks](https://github.com/stevensacks)) 414 | - chore: repository url fix ([@stevensacks](https://github.com/stevensacks)) 415 | 416 | #### Authors: 2 417 | 418 | - Rıdvan Karadağ ([@ridvankaradag](https://github.com/ridvankaradag)) 419 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 420 | 421 | --- 422 | 423 | # v2.0.4 (Mon Nov 27 2023) 424 | 425 | #### 🐛 Bug Fix 426 | 427 | - feat: add support for 'defaultRichTextElements' in IntlProvider [#10](https://github.com/stevensacks/storybook-react-intl/pull/10) ([@ridvankaradag](https://github.com/ridvankaradag)) 428 | 429 | #### ⚠️ Pushed to `main` 430 | 431 | - chore: update gitignore ([@stevensacks](https://github.com/stevensacks)) 432 | - chore: repository url fix ([@stevensacks](https://github.com/stevensacks)) 433 | 434 | #### Authors: 2 435 | 436 | - Rıdvan Karadağ ([@ridvankaradag](https://github.com/ridvankaradag)) 437 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 438 | 439 | --- 440 | 441 | # v2.0.4 (Mon Nov 27 2023) 442 | 443 | #### 🐛 Bug Fix 444 | 445 | - feat: add support for 'defaultRichTextElements' in IntlProvider [#10](https://github.com/stevensacks/storybook-react-intl/pull/10) ([@ridvankaradag](https://github.com/ridvankaradag)) 446 | 447 | #### ⚠️ Pushed to `main` 448 | 449 | - chore: repository url fix ([@stevensacks](https://github.com/stevensacks)) 450 | 451 | #### Authors: 2 452 | 453 | - Rıdvan Karadağ ([@ridvankaradag](https://github.com/ridvankaradag)) 454 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 455 | 456 | --- 457 | 458 | # v2.0.4 (Mon Nov 27 2023) 459 | 460 | #### 🐛 Bug Fix 461 | 462 | - feat: add support for 'defaultRichTextElements' in IntlProvider [#10](https://github.com/stevensacks/storybook-react-intl/pull/10) ([@ridvankaradag](https://github.com/ridvankaradag)) 463 | 464 | #### ⚠️ Pushed to `main` 465 | 466 | - chore: repository url fix ([@stevensacks](https://github.com/stevensacks)) 467 | 468 | #### Authors: 2 469 | 470 | - Rıdvan Karadağ ([@ridvankaradag](https://github.com/ridvankaradag)) 471 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 472 | 473 | --- 474 | 475 | # v2.0.4 (Mon Nov 27 2023) 476 | 477 | #### 🐛 Bug Fix 478 | 479 | - feat: add support for 'defaultRichTextElements' in IntlProvider [#10](https://github.com/stevensacks/storybook-react-intl/pull/10) ([@ridvankaradag](https://github.com/ridvankaradag)) 480 | 481 | #### ⚠️ Pushed to `main` 482 | 483 | - chore: repository url fix ([@stevensacks](https://github.com/stevensacks)) 484 | 485 | #### Authors: 2 486 | 487 | - Rıdvan Karadağ ([@ridvankaradag](https://github.com/ridvankaradag)) 488 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 489 | 490 | --- 491 | 492 | # v2.0.4 (Mon Nov 27 2023) 493 | 494 | #### 🐛 Bug Fix 495 | 496 | - feat: add support for 'defaultRichTextElements' in IntlProvider [#10](https://github.com/stevensacks/storybook-react-intl/pull/10) ([@ridvankaradag](https://github.com/ridvankaradag)) 497 | 498 | #### ⚠️ Pushed to `main` 499 | 500 | - chore: repository url fix ([@stevensacks](https://github.com/stevensacks)) 501 | 502 | #### Authors: 2 503 | 504 | - Rıdvan Karadağ ([@ridvankaradag](https://github.com/ridvankaradag)) 505 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 506 | 507 | --- 508 | 509 | # v2.0.4 (Mon Nov 27 2023) 510 | 511 | #### 🐛 Bug Fix 512 | 513 | - feat: add support for 'defaultRichTextElements' in IntlProvider [#10](https://github.com/stevensacks/storybook-react-intl/pull/10) ([@ridvankaradag](https://github.com/ridvankaradag)) 514 | 515 | #### ⚠️ Pushed to `main` 516 | 517 | - chore: repository url fix ([@stevensacks](https://github.com/stevensacks)) 518 | 519 | #### Authors: 2 520 | 521 | - Rıdvan Karadağ ([@ridvankaradag](https://github.com/ridvankaradag)) 522 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 523 | 524 | --- 525 | 526 | # v2.0.3 (Tue Aug 29 2023) 527 | 528 | #### 🐛 Bug Fix 529 | 530 | - Chore: Update minor/patch dependencies [#9](https://github.com/stevensacks/storybook-react-intl/pull/9) ([@timgcarlson](https://github.com/timgcarlson)) 531 | 532 | #### ⚠️ Pushed to `main` 533 | 534 | - merge: fix merge conflicts ([@stevensacks](https://github.com/stevensacks)) 535 | - chore: update storybook-i18n and storybook ([@stevensacks](https://github.com/stevensacks)) 536 | 537 | #### Authors: 2 538 | 539 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 540 | - Tim Carlson ([@timgcarlson](https://github.com/timgcarlson)) 541 | 542 | --- 543 | 544 | # v2.0.2 (Mon May 29 2023) 545 | 546 | #### ⚠️ Pushed to `main` 547 | 548 | - chore(project): update deps ([@stevensacks](https://github.com/stevensacks)) 549 | - update docs to make clear to export preview ([@stevensacks](https://github.com/stevensacks)) 550 | 551 | #### Authors: 1 552 | 553 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 554 | 555 | --- 556 | 557 | # v1.1.4 (Fri Apr 07 2023) 558 | 559 | #### ⚠️ Pushed to `main` 560 | 561 | - remove hot ([@stevensacks](https://github.com/stevensacks)) 562 | - fix type issue ([@stevensacks](https://github.com/stevensacks)) 563 | - fix yarn lock ([@stevensacks](https://github.com/stevensacks)) 564 | - fix merge ([@stevensacks](https://github.com/stevensacks)) 565 | - set up and working ([@stevensacks](https://github.com/stevensacks)) 566 | 567 | #### Authors: 1 568 | 569 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 570 | 571 | --- 572 | 573 | # v1.1.2 (Fri Apr 07 2023) 574 | 575 | #### 🐛 Bug Fix 576 | 577 | - chore: Update storybook depencies [#8](https://github.com/stevensacks/storybook-react-intl/pull/8) ([@rodrigofeijao](https://github.com/rodrigofeijao)) 578 | 579 | #### ⚠️ Pushed to `main` 580 | 581 | - Merge branch 'main' of github.com:stevensacks/storybook-react-intl ([@stevensacks](https://github.com/stevensacks)) 582 | 583 | #### Authors: 2 584 | 585 | - Rodrigo Feijao ([@rodrigofeijao](https://github.com/rodrigofeijao)) 586 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 587 | 588 | --- 589 | 590 | # v1.0.6 (Thu Jul 14 2022) 591 | 592 | #### ⚠️ Pushed to `main` 593 | 594 | - fix(ReactIntl): type issue with storybook story ([@stevensacks](https://github.com/stevensacks)) 595 | - chore(deps): add support for SB 6.5, React 18, Intl 6 ([@stevensacks](https://github.com/stevensacks)) 596 | 597 | #### Authors: 1 598 | 599 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 600 | 601 | --- 602 | 603 | # v1.0.5 (Mon Jan 31 2022) 604 | 605 | #### ⚠️ Pushed to `main` 606 | 607 | - Merge branch 'main' of github.com:stevensacks/storybook-react-intl ([@stevensacks](https://github.com/stevensacks)) 608 | - fix(hooks): use storybook hooks instead of react ([@stevensacks](https://github.com/stevensacks)) 609 | 610 | #### Authors: 1 611 | 612 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 613 | 614 | --- 615 | 616 | # v1.0.4 (Tue Jan 04 2022) 617 | 618 | #### ⚠️ Pushed to `main` 619 | 620 | - feat(tool): show tool in Docs panel ([@stevensacks](https://github.com/stevensacks)) 621 | 622 | #### Authors: 1 623 | 624 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 625 | 626 | --- 627 | 628 | # v1.0.3 (Fri Dec 24 2021) 629 | 630 | #### ⚠️ Pushed to `main` 631 | 632 | - fix(deps): remove storybook-i18n as peer dependency ([@stevensacks](https://github.com/stevensacks)) 633 | 634 | #### Authors: 1 635 | 636 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 637 | 638 | --- 639 | 640 | # v1.0.2 (Wed Dec 22 2021) 641 | 642 | #### ⚠️ Pushed to `main` 643 | 644 | - Merge branch 'main' of github.com:stevensacks/storybook-react-intl ([@stevensacks](https://github.com/stevensacks)) 645 | - chore(deps): update peer dependencies ([@stevensacks](https://github.com/stevensacks)) 646 | 647 | #### Authors: 1 648 | 649 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 650 | 651 | --- 652 | 653 | # v0.9.4 (Wed Dec 22 2021) 654 | 655 | #### ⚠️ Pushed to `main` 656 | 657 | - fix(package): merge conflicts ([@stevensacks](https://github.com/stevensacks)) 658 | - chore(deps): update to storybook 6.4 ([@stevensacks](https://github.com/stevensacks)) 659 | 660 | #### Authors: 1 661 | 662 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 663 | 664 | --- 665 | 666 | # v0.9.3 (Wed Dec 22 2021) 667 | 668 | #### ⚠️ Pushed to `main` 669 | 670 | - docs(README): update usage instructions ([@stevensacks](https://github.com/stevensacks)) 671 | 672 | #### Authors: 1 673 | 674 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 675 | 676 | --- 677 | 678 | # v0.9.2 (Sun Sep 12 2021) 679 | 680 | #### 🐛 Bug Fix 681 | 682 | - fix IntlProvider initialize [#4](https://github.com/stevensacks/storybook-react-intl/pull/4) ([@kongkx](https://github.com/kongkx)) 683 | 684 | #### ⚠️ Pushed to `main` 685 | 686 | - initial commit and README ([@stevensacks](https://github.com/stevensacks)) 687 | - Initial commit ([@stevensacks](https://github.com/stevensacks)) 688 | 689 | #### Authors: 2 690 | 691 | - [@kongkx](https://github.com/kongkx) 692 | - Steven Sacks ([@stevensacks](https://github.com/stevensacks)) 693 | --------------------------------------------------------------------------------