Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Storybook template for i18n #4764

Merged
merged 56 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
08e9f26
clean and order .use(LanguageDetector)
simoncrypta Mar 15, 2022
1243f7e
add storybook template for i18n
simoncrypta Mar 15, 2022
8a890a0
add configure storybook to i18n CLI
simoncrypta Mar 15, 2022
b7db6b4
add configure-storybook task to i18n
simoncrypta Mar 15, 2022
61595df
Merge branch 'main' into sg-i18n-storybook
simoncrypta Mar 15, 2022
26625e2
Merge branch 'main' into sg-i18n-storybook
simoncrypta Mar 15, 2022
ab1c305
Merge branch 'main' into sg-i18n-storybook
thedavidprice Mar 16, 2022
6174a25
Update comment
simoncrypta Mar 20, 2022
e2951fe
Update storybook.preview.js.template
simoncrypta Mar 20, 2022
695cd65
Fix lint storybook.preview.js.template
simoncrypta Mar 20, 2022
5e15bde
Merge branch 'main' into sg-i18n-storybook
Mar 22, 2022
268a0ce
remove unused eslint-disable-next-line
simoncrypta Mar 22, 2022
269f356
Merge branch 'main' into sg-i18n-storybook
simoncrypta Mar 22, 2022
71f7790
Merge branch 'main' into sg-i18n-storybook
simoncrypta Mar 27, 2022
e78f832
move configure-storybook to cli lib
simoncrypta Mar 27, 2022
7045baa
update path of configureStorybook for chakra
simoncrypta Mar 27, 2022
fe3b6de
fix path mistake
simoncrypta Mar 27, 2022
0d56277
remove checkStorybookStatus
simoncrypta Mar 27, 2022
33fb45e
use wild import to match with other configs
simoncrypta Mar 27, 2022
1d2d4d5
Merge both storybook config if file exist
simoncrypta Mar 27, 2022
72b89f3
newStorybookPreview is already read
simoncrypta Mar 28, 2022
c13169d
React component must start with a uppercase letter
simoncrypta Mar 28, 2022
78f336b
remove decoration for CurrentStorybookConfig
simoncrypta Mar 28, 2022
aa86430
update comment for languageDetector
simoncrypta Mar 28, 2022
c826417
Update naming for current config
simoncrypta Mar 28, 2022
7758eed
Update naming for current config
simoncrypta Mar 28, 2022
c0b959a
Update naming for current config
simoncrypta Mar 28, 2022
f80003f
Update naming for current config
simoncrypta Mar 28, 2022
bb42cf1
Update naming for current config
simoncrypta Mar 28, 2022
9a3a315
Update naming for current config
simoncrypta Mar 28, 2022
d34fe81
Update naming for current config
simoncrypta Mar 28, 2022
aef8671
Update naming for storybookPreviewConfig
simoncrypta Mar 28, 2022
273710d
Update naming for storybookPreviewConfig
simoncrypta Mar 28, 2022
f3a5303
Update naming for decorators export
simoncrypta Mar 28, 2022
4405069
Update regex to be more specific
simoncrypta Mar 28, 2022
371ec68
Update naming
simoncrypta Mar 28, 2022
6dc8069
Update naming
simoncrypta Mar 28, 2022
b94c0e5
Update naming
simoncrypta Mar 28, 2022
94c0246
Fix the mess
Mar 28, 2022
97e6cb4
Merge branch 'main' into sg-i18n-storybook
Mar 28, 2022
15e0289
fix get path
Mar 28, 2022
92a397f
Update naming configureStorybook
simoncrypta Mar 29, 2022
78bd63d
Update naming
simoncrypta Mar 29, 2022
95a38dd
Simplify code
simoncrypta Mar 29, 2022
b741e61
update naming
simoncrypta Mar 29, 2022
d4b074d
Update naming
simoncrypta Mar 29, 2022
1d64c27
Update naming
simoncrypta Mar 29, 2022
1b12ff7
Merge branch 'main' into sg-i18n-storybook
simoncrypta Mar 29, 2022
18bb8b7
Merge branch 'main' into sg-i18n-storybook
simoncrypta Mar 29, 2022
20db020
Update packages/cli/src/commands/setup/i18n/i18n.js
Tobbe Mar 29, 2022
8c4c5e9
hoc naming
Tobbe Mar 29, 2022
f904d15
Merge branch 'main' into sg-i18n-storybook
Tobbe Mar 29, 2022
f192fbe
configureStorybook: Format code and tweak regex
Tobbe Mar 29, 2022
bea1975
storybook preview config: Add eslint comment
Tobbe Mar 29, 2022
9339169
Apply suggestions from code review
Tobbe Mar 30, 2022
e1b353a
Merge branch 'main' into sg-i18n-storybook
Tobbe Mar 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion packages/cli/src/commands/setup/i18n/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { errorTelemetry } from '@redwoodjs/telemetry'

import { getPaths, writeFile } from '../../../lib'
import c from '../../../lib/colors'
import configureStorybook from '../../../lib/configureStorybook.js'

export const command = 'i18n'
export const description = 'Set up i18n'
Expand Down Expand Up @@ -72,7 +73,7 @@ export const handler = async ({ force }) => {
},
},
{
title: 'Configuring i18n...',
title: 'Configure i18n...',
task: () => {
/**
* Write i18n.js in web/src
Expand Down Expand Up @@ -169,6 +170,17 @@ export const handler = async ({ force }) => {
}
},
},
{
title: 'Configuring Storybook...',
task: async () =>
configureStorybook(
{ force },
fs.readFileSync(
path.join(__dirname, 'templates', 'storybook.preview.js.template'),
'utf-8'
)
),
},
{
title: 'One more thing...',
task: (_ctx, task) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ export default HomePage
*/

i18n
.use(initReactI18next)
// detect user language
simoncrypta marked this conversation as resolved.
Show resolved Hide resolved
// learn more: https://github.com/i18next/i18next-browser-languageDetector
.use(LanguageDetector)
.use(initReactI18next)
.init({
interpolation: { escapeValue: false }, // React already does escaping
fallbackLng: 'en',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as React from 'react'
import { I18nextProvider } from 'react-i18next'
import i18n from 'web/src/i18n'

export const globalTypes = {
Tobbe marked this conversation as resolved.
Show resolved Hide resolved
locale: {
name: 'Locale',
description: 'Internationalization locale',
defaultValue: 'en',
toolbar: {
icon: 'globe',
items: [
{ value: 'en', right: '🇺🇸', title: 'English' },
{ value: 'fr', right: '🇫🇷', title: 'Français' },
],
},
},
}

// We're following Storybook's naming convention here. See for example
// https://github.com/storybookjs/addon-kit/blob/main/src/withGlobals.ts
// Unfortunately that will make eslint complain, so we have to disable it when
// using a hook below
Tobbe marked this conversation as resolved.
Show resolved Hide resolved
const withI18n = (StoryFn, context) => {
simoncrypta marked this conversation as resolved.
Show resolved Hide resolved
// eslint-disable-next-line react-hooks/rules-of-hooks
simoncrypta marked this conversation as resolved.
Show resolved Hide resolved
React.useEffect(() => {
i18n.changeLanguage(context.globals.locale)
}, [context.globals.locale])

return (
simoncrypta marked this conversation as resolved.
Show resolved Hide resolved
<I18nextProvider i18n={i18n}>
<StoryFn />
</I18nextProvider>
)
}

export const decorators = [withI18n]
23 changes: 17 additions & 6 deletions packages/cli/src/commands/setup/ui/libraries/chakra-ui.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import fs from 'fs'
import path from 'path'

import execa from 'execa'
import Listr from 'listr'

import c from '../../../../lib/colors'
import {
checkStorybookStatus,
configureStorybook,
} from '../tasks/configure-storybook'
import configureStorybook from '../../../../lib/configureStorybook.js'
import { checkSetupStatus, wrapWithChakraProvider } from '../tasks/setup-chakra'

export const command = 'chakra-ui'
Expand Down Expand Up @@ -62,8 +62,19 @@ export async function handler({ force, install }) {
},
{
title: 'Configure Storybook...',
skip: () => checkStorybookStatus({ force }) === 'done',
task: async () => configureStorybook(),
task: async () =>
configureStorybook(
{ force },
fs.readFileSync(
path.join(
__dirname,
'..',
'templates',
'storybook.preview.js.template'
),
'utf-8'
)
),
},
])

Expand Down
40 changes: 0 additions & 40 deletions packages/cli/src/commands/setup/ui/tasks/configure-storybook.js

This file was deleted.

71 changes: 71 additions & 0 deletions packages/cli/src/lib/configureStorybook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import fs from 'fs-extra'

import { getPaths } from '.'

/**
* Configure Storybook for the given template by creating a custom preview config
*/
export default function configureStorybook({ force }, newStorybookPreview) {
simoncrypta marked this conversation as resolved.
Show resolved Hide resolved
const storybookPreviewConfigPath = getPaths().web.storybookPreviewConfig

let storybookPreviewConfig
/**
* Check if storybookPreviewConfigPath already exists.
* Merge both files if it does.
* By removing import react and export decorator from new config
* And put new config inside current config after last import
*/
if (fs.existsSync(storybookPreviewConfigPath)) {
if (force) {
fs.unlinkSync(storybookPreviewConfigPath)
storybookPreviewConfig = newStorybookPreview
} else {
const currentConfig = fs
.readFileSync(storybookPreviewConfigPath)
.toString()

const newDecoratorsName = newStorybookPreview.match(
/export const decorators = \[(.*?)\]/
)[1]

const currentDecoratorsName = currentConfig.match(
/export const decorators = \[(.*?)\]/
)[1]

const decoratorsExport = `export const decorators = [${currentDecoratorsName}, ${newDecoratorsName}]`

const insideNewStorybookConfigWithoutReactAndDecoration =
newStorybookPreview
.replace(/import \* as React from 'react'/, '')
.replace(/export const decorators = .*/, '')

const currentConfigWithoutDecoration = currentConfig.replace(
/export const decorators = .*/,
''
)

const reversedCurrentConfig = currentConfigWithoutDecoration
.split('\n')
.reverse()

const indexOfLastImport = reversedCurrentConfig.findIndex((value) =>
/^import /.test(value)
)
reversedCurrentConfig.splice(
indexOfLastImport,
0,
insideNewStorybookConfigWithoutReactAndDecoration
)
storybookPreviewConfig =
reversedCurrentConfig.reverse().join(`\n`) +
`\n` +
currentConfig +
`\n` +
decoratorsExport
}
} else {
storybookPreviewConfig = newStorybookPreview
}

fs.outputFileSync(storybookPreviewConfigPath, storybookPreviewConfig)
}