Add shared configuration for storybook in new '@essex/storybook-config' package. (#836)
* add common storybook config package * semver * update turbo in ci * add @fluentui/react resolve alias * lint updates * run formatter * ignore storybook output; drop node 18 b/c of storybook * update sb config * run formatter * use regexp in default transpile matchers * Run formatter * add make rome_fix script public * remove an addon * Remove another addon * peer out sb deps * run format * add storybook-static to eslintignore * restore 18.x
This commit is contained in:
Родитель
160a9be1f5
Коммит
cefe996078
|
@ -6,5 +6,6 @@ coverage/
|
|||
public/
|
||||
docs/
|
||||
.yarn/
|
||||
storybook-static/
|
||||
.pnp.*
|
||||
yarn.lock
|
|
@ -59,12 +59,17 @@ jobs:
|
|||
- run: yarn install
|
||||
|
||||
- name: TurboRepo local server
|
||||
uses: felixmosh/turborepo-gh-artifacts@v1
|
||||
uses: felixmosh/turborepo-gh-artifacts@v2
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
server-token: ${{ secrets.TURBO_SERVER_TOKEN }}
|
||||
|
||||
- run: yarn ci --api="http://127.0.0.1:9080" --token="${{ secrets.TURBO_SERVER_TOKEN }}" --team="essex"
|
||||
- run: yarn ci
|
||||
env:
|
||||
TURBO_API: 'http://127.0.0.1:9080'
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_SERVER_TOKEN }}
|
||||
TURBO_TEAM: 'essex'
|
||||
|
||||
- run: yarn is_clean
|
||||
|
||||
- name: Publish coverage to codecov.io
|
||||
|
|
|
@ -12,6 +12,7 @@ packages/*/docsTemp/
|
|||
|
||||
# Testing Output
|
||||
coverage/
|
||||
storybook-static/
|
||||
test-report.xml
|
||||
|
||||
linked_data/
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
declined:
|
||||
- "@essex/storybook-config"
|
||||
- "@essex/test-stories"
|
|
@ -7,6 +7,13 @@ packageExtensions:
|
|||
fork-ts-checker-webpack-plugin@*:
|
||||
dependencies:
|
||||
"@types/tapable": ^1.0.6
|
||||
"@storybook/store@*":
|
||||
peerDependenciesMeta:
|
||||
react: { optional: true }
|
||||
react-dom: { optional: true }
|
||||
"@storybook/addon-docs@*":
|
||||
peerDependencies:
|
||||
"@babel/core": "*"
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
|
|
|
@ -15,16 +15,16 @@
|
|||
"_ci_packages": "turbo run ci",
|
||||
"_essex_lint": "essex check --formatter none",
|
||||
"_essex_lint_fix": "essex fix --formatter none",
|
||||
"_rome_check": "rome ci .",
|
||||
"rome_check": "rome ci .",
|
||||
"format": "rome format . --write",
|
||||
"_rome_check_apply": "rome check --apply-suggested .",
|
||||
"rome_fix": "rome check --apply-suggested .",
|
||||
"clean": "turbo run clean",
|
||||
"check": "run-s _rome_check _check_packages _essex_lint",
|
||||
"check-deps": "turbo run check-deps",
|
||||
"fix": "run-s _fix_packages _essex_lint_fix format _rome_check_apply",
|
||||
"fix": "run-s _fix_packages _essex_lint_fix format rome_fix",
|
||||
"build": "turbo run build",
|
||||
"test": "turbo run test",
|
||||
"ci": "run-s _rome_check _ci_packages _essex_lint",
|
||||
"ci": "run-s rome_check _ci_packages _essex_lint",
|
||||
"is_clean": "essex git-is-clean",
|
||||
"update_sdks": "yarn dlx @yarnpkg/sdks vscode",
|
||||
"release": "run-s clean _version_cut ci _release_packages"
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"name": "@essex/storybook-config",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build": "tsc -b ."
|
||||
},
|
||||
"exports": {
|
||||
".": "./lib/index.js",
|
||||
"./main": "./lib/main.js",
|
||||
"./main.js": "./lib/main.js",
|
||||
"./preview": "./lib/preview.js",
|
||||
"./preview.js": "./lib/preview.js",
|
||||
"./babel.config": "./lib/babel.config.js",
|
||||
"./babel.config.js": "./lib/babel.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@open-wc/webpack-import-meta-loader": "^0.4.7",
|
||||
"hsluv": "^1.0.0",
|
||||
"react-docgen-typescript": "^2.2.2",
|
||||
"react-is": "^18.2.0",
|
||||
"resolve-typescript-plugin": "^2.0.0",
|
||||
"tslib": "^2.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.16.5",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@essex/tsconfig-node": "workspace:^",
|
||||
"@fluentui/react": "^8.104.6",
|
||||
"@storybook/addon-essentials": "^6.5.15",
|
||||
"@storybook/addon-interactions": "^6.5.15",
|
||||
"@storybook/addon-links": "^6.5.15",
|
||||
"@storybook/react": "^6.5.15",
|
||||
"@thematic/core": "^4.0.4",
|
||||
"@thematic/fluent": "^5.0.5",
|
||||
"@thematic/react": "^2.1.6",
|
||||
"@types/open-wc__webpack-import-meta-loader": "^0",
|
||||
"@types/react": "^18.0.27",
|
||||
"@types/styled-components": "^5.1.26",
|
||||
"@types/webpack": "^5.28.0",
|
||||
"react": "^18.2.0",
|
||||
"rimraf": "^4.1.1",
|
||||
"styled-components": "^5.3.6",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": ">= 7",
|
||||
"@babel/preset-env": ">= 7",
|
||||
"@babel/preset-react": ">= 7",
|
||||
"@babel/preset-typescript": ">= 7",
|
||||
"@fluentui/react": ">= 8",
|
||||
"@storybook/addon-essentials": ">= 6",
|
||||
"@storybook/addon-interactions": ">= 6",
|
||||
"@storybook/addon-links": ">= 6",
|
||||
"@storybook/react": ">= 6",
|
||||
"@thematic/core": ">= 4",
|
||||
"@thematic/fluent": ">= 5",
|
||||
"@thematic/react": ">= 2",
|
||||
"react": ">= 18",
|
||||
"react-dom": ">= 18",
|
||||
"styled-components": ">= 5"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { initializeIcons, Toggle } from '@fluentui/react'
|
||||
import type { StoryFnReactReturnType } from '@storybook/react/dist/ts3.9/client/preview/types'
|
||||
import { loadById } from '@thematic/core'
|
||||
import { loadFluentTheme, ThematicFluentProvider } from '@thematic/fluent'
|
||||
import { ApplicationStyles } from '@thematic/react'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import styled, { ThemeProvider } from 'styled-components'
|
||||
|
||||
initializeIcons()
|
||||
/**
|
||||
* ThematicFluentDecorator configures both Thematic and the Fluent wrapper
|
||||
* @param storyFn
|
||||
*/
|
||||
export const ThematicFluentDecorator = (
|
||||
storyFn: any,
|
||||
): StoryFnReactReturnType => {
|
||||
const [dark, setDark] = useState(false)
|
||||
// load a non-standard theme, so it is obvious that it isn't the default
|
||||
// this helps identify problems with theme application in Fluent, which looks a lot like our default essex theme
|
||||
const thematicTheme = useMemo(
|
||||
() =>
|
||||
loadById('autumn', {
|
||||
dark,
|
||||
}),
|
||||
[dark],
|
||||
)
|
||||
const fluentTheme = useMemo(
|
||||
() => loadFluentTheme(thematicTheme),
|
||||
[thematicTheme],
|
||||
)
|
||||
const handleDarkChange = useCallback(
|
||||
(_e: unknown, v: boolean | undefined) => {
|
||||
setDark(v ?? false)
|
||||
},
|
||||
[],
|
||||
)
|
||||
return (
|
||||
<ThematicFluentProvider theme={thematicTheme}>
|
||||
<style>
|
||||
{`* {
|
||||
box-sizing: border-box;
|
||||
}`}
|
||||
</style>
|
||||
<ApplicationStyles />
|
||||
<Toggle label="Dark mode" checked={dark} onChange={handleDarkChange} />
|
||||
<ThemeProvider theme={fluentTheme}>
|
||||
<Container>{storyFn(undefined, undefined)}</Container>
|
||||
</ThemeProvider>
|
||||
</ThematicFluentProvider>
|
||||
)
|
||||
}
|
||||
|
||||
const Container = styled.div`
|
||||
padding: 20px;
|
||||
border: 1px solid ${({ theme }) => theme.application().faint().hex()};
|
||||
`
|
|
@ -0,0 +1,18 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
module.exports = {
|
||||
presets: [
|
||||
[require.resolve('@babel/preset-react'), { runtime: 'automatic' }],
|
||||
[
|
||||
require.resolve('@babel/preset-env'),
|
||||
{
|
||||
targets: {
|
||||
esmodules: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
[require.resolve('@babel/preset-typescript'), {}],
|
||||
],
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
throw new Error('')
|
|
@ -0,0 +1,119 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import ResolveTypescriptPlugin from 'resolve-typescript-plugin'
|
||||
import type {
|
||||
Configuration as WebpackConfig,
|
||||
RuleSetRule,
|
||||
WebpackPluginInstance,
|
||||
} from 'webpack'
|
||||
|
||||
export interface EssexStorybookConfig {
|
||||
stories?: string[]
|
||||
staticDirs?: string[]
|
||||
resolveAliases?: Record<string, string>
|
||||
transpileMatch: (string | RegExp)[]
|
||||
}
|
||||
|
||||
const DEFAULT_STORIES = [
|
||||
/**
|
||||
* search sibling packages by default
|
||||
*/
|
||||
'../../*/src/**/*.stories.@(mdx|js|jsx|ts|tsx)',
|
||||
]
|
||||
const DEFAULT_STATIC_DIRS: string[] = []
|
||||
const DEFAULT_TRANSPILE_MATCHES = [/@essex\/components/, /styled-components/]
|
||||
|
||||
export function configure({
|
||||
stories = DEFAULT_STORIES,
|
||||
staticDirs = DEFAULT_STATIC_DIRS,
|
||||
resolveAliases = {},
|
||||
transpileMatch = [],
|
||||
}: EssexStorybookConfig) {
|
||||
return {
|
||||
stories,
|
||||
staticDirs,
|
||||
addons: [
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-interactions',
|
||||
],
|
||||
framework: '@storybook/react',
|
||||
typescript: {
|
||||
reactDocgen: require.resolve('react-docgen-typescript'),
|
||||
reactDocgenTypescriptOptions: {
|
||||
compilerOptions: {
|
||||
allowSyntheticDefaultImports: false,
|
||||
esModuleInterop: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
webpackFinal(config: WebpackConfig) {
|
||||
// mute build output
|
||||
if (process.env['CI'] || process.env['SB_QUIET']) {
|
||||
config.stats = 'errors-only'
|
||||
config.plugins = config.plugins?.filter(
|
||||
(plugin: WebpackPluginInstance) =>
|
||||
plugin.constructor.name !== 'ProgressPlugin',
|
||||
)
|
||||
}
|
||||
|
||||
if (!config.resolve) {
|
||||
config.resolve = {}
|
||||
}
|
||||
|
||||
config.resolve.alias = {
|
||||
...(config.resolve.alias ?? {}),
|
||||
'styled-components': require.resolve('styled-components'),
|
||||
hsluv: require.resolve('hsluv'),
|
||||
'@thematic/react': require.resolve('@thematic/react'),
|
||||
'@thematic/fluent': require.resolve('@thematic/fluent'),
|
||||
'@fluentui/react': require.resolve('@fluentui/react'),
|
||||
...resolveAliases,
|
||||
}
|
||||
|
||||
// resolve files ending with .ts
|
||||
if (!config.resolve.plugins) {
|
||||
config.resolve.plugins = []
|
||||
}
|
||||
// Resolve extensions from TS code
|
||||
config.resolve.plugins.push(new ResolveTypescriptPlugin())
|
||||
|
||||
// run transpiler over monorepo linked projects
|
||||
const firstRule = config.module?.rules?.[0] as RuleSetRule | undefined
|
||||
|
||||
if (firstRule != null) {
|
||||
const transpileMatchRules: RuleSetRule[] = [
|
||||
...DEFAULT_TRANSPILE_MATCHES,
|
||||
transpileMatch,
|
||||
].map((match) => {
|
||||
return {
|
||||
...firstRule,
|
||||
include: match,
|
||||
exclude: undefined,
|
||||
}
|
||||
})
|
||||
const importMeta = {
|
||||
test: /\.js$/,
|
||||
loader: require.resolve('@open-wc/webpack-import-meta-loader'),
|
||||
}
|
||||
const handleMjs = {
|
||||
test: /\.mjs$/,
|
||||
include: /node_modules/,
|
||||
type: 'javascript/auto',
|
||||
}
|
||||
config.module!.rules!.push(
|
||||
...transpileMatchRules,
|
||||
importMeta,
|
||||
handleMjs,
|
||||
)
|
||||
} else {
|
||||
throw new Error('unexpected incoming webpack config')
|
||||
}
|
||||
|
||||
return config
|
||||
},
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { addDecorator } from '@storybook/react'
|
||||
|
||||
import { ThematicFluentDecorator } from './ThematicFluentDecorator.js'
|
||||
|
||||
addDecorator(ThematicFluentDecorator)
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"extends": "@essex/tsconfig-node",
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"outDir": "lib",
|
||||
"jsx": "react-jsx",
|
||||
"declaration": true
|
||||
},
|
||||
"include": ["src/**/*.ts*"]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
const config = require('@essex/storybook-config/babel.config')
|
||||
|
||||
module.exports = config
|
|
@ -0,0 +1,6 @@
|
|||
const { configure } = require('@essex/storybook-config/main')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = configure({
|
||||
stories: [path.join(__dirname, '../src/*.stories.tsx')],
|
||||
})
|
|
@ -0,0 +1,3 @@
|
|||
const config = require('@essex/storybook-config/lib/preview.js')
|
||||
|
||||
module.exports = config
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "@essex/test-stories",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"clean": "rimraf dist storybook_static",
|
||||
"build": "build-storybook",
|
||||
"start": "start-storybook"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/microsoft/essex-js-build.git",
|
||||
"directory": "packages/test-suite-lib"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.16.5",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@essex/scripts": "workspace:^",
|
||||
"@essex/storybook-config": "workspace:^",
|
||||
"@essex/tsconfig-base": "workspace:^",
|
||||
"@storybook/addon-essentials": "^6.5.15",
|
||||
"@storybook/addon-interactions": "^6.5.15",
|
||||
"@storybook/addon-links": "^6.5.15",
|
||||
"@storybook/react": "^6.5.15",
|
||||
"@types/react": "^18.0.27"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
const Component = () => <div>A story lives here</div>
|
||||
|
||||
const meta = {
|
||||
title: '@essex:components/Tree',
|
||||
component: Component,
|
||||
}
|
||||
export default meta
|
||||
|
||||
export const Basic = () => <Component />
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"extends": "../config-ts-base/tsconfig",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib",
|
||||
"resolveJsonModule": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
31
rome.json
31
rome.json
|
@ -1,5 +1,16 @@
|
|||
{
|
||||
"$schema": "./node_modules/rome/configuration_schema.json",
|
||||
"files": {
|
||||
"ignore": [
|
||||
"dist",
|
||||
"lib",
|
||||
"build",
|
||||
"storybook-static",
|
||||
".turbo",
|
||||
".pnp.cjs",
|
||||
".pnp.loader.mjs"
|
||||
]
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
|
@ -7,15 +18,7 @@
|
|||
"suspicious": {
|
||||
"noExplicitAny": "off"
|
||||
}
|
||||
},
|
||||
"ignore": [
|
||||
"dist",
|
||||
"lib",
|
||||
"build",
|
||||
".turbo",
|
||||
".pnp.cjs",
|
||||
".pnp.loader.mjs"
|
||||
]
|
||||
}
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
|
@ -26,14 +29,6 @@
|
|||
}
|
||||
},
|
||||
"formatter": {
|
||||
"indentStyle": "tab",
|
||||
"ignore": [
|
||||
"dist",
|
||||
"lib",
|
||||
"build",
|
||||
".turbo",
|
||||
".pnp.cjs",
|
||||
".pnp.loader.mjs"
|
||||
]
|
||||
"indentStyle": "tab"
|
||||
}
|
||||
}
|
8812
yarn.lock
8812
yarn.lock
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче