mirror of
https://github.com/storybookjs/storybook.git
synced 2025-03-21 05:02:39 +08:00
Merge branch 'master' of github.com:storybooks/storybook into addon-resources
This commit is contained in:
commit
593387bd59
20
.babelrc
20
.babelrc
@ -28,6 +28,26 @@
|
||||
"@babel/preset-env",
|
||||
"babel-preset-vue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"test": [
|
||||
"./lib/core/src/server",
|
||||
"./lib/node-logger",
|
||||
"./lib/codemod",
|
||||
"./addons/storyshots",
|
||||
"./addons/storysource/src/loader",
|
||||
"./app/**/src/server/**"
|
||||
],
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"node": "8.11"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
19
.bithoundrc
19
.bithoundrc
@ -1,19 +0,0 @@
|
||||
{
|
||||
"ignore": [
|
||||
"addons/**/.storybook/**/*.js",
|
||||
"lib/cli/generators/**/.stories/**.js",
|
||||
"*.ts"
|
||||
],
|
||||
"critics": {
|
||||
"wc": {
|
||||
"limit": 500
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"mute": [
|
||||
"shelljs",
|
||||
"eslint-plugin-json",
|
||||
"remark-lint-code-eslint"
|
||||
]
|
||||
}
|
||||
}
|
@ -36,20 +36,11 @@ jobs:
|
||||
root: .
|
||||
paths:
|
||||
- node_modules
|
||||
- examples/angular-cli/node_modules
|
||||
- examples/cra-kitchen-sink/node_modules
|
||||
- examples/mithril-kitchen-sink/node_modules
|
||||
- examples/official-storybook/node_modules
|
||||
- examples/polymer-cli/node_modules
|
||||
- examples/vue-kitchen-sink/node_modules
|
||||
- examples/svelte-kitchen-sink/node_modules
|
||||
- examples/marko-cli/node_modules
|
||||
- examples/html-kitchen-sink/node_modules
|
||||
- examples/riot-kitchen-sink/node_modules
|
||||
- examples
|
||||
- addons
|
||||
- app
|
||||
- lib
|
||||
example-kitchen-sinks:
|
||||
examples:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
@ -78,6 +69,11 @@ jobs:
|
||||
command: |
|
||||
cd examples/angular-cli
|
||||
yarn build-storybook
|
||||
- run:
|
||||
name: Build ember-cli
|
||||
command: |
|
||||
cd examples/ember-cli
|
||||
yarn build-storybook
|
||||
- run:
|
||||
name: Build polymer-cli
|
||||
command: |
|
||||
@ -140,6 +136,11 @@ jobs:
|
||||
command: |
|
||||
cd examples/angular-cli
|
||||
yarn storybook --smoke-test
|
||||
- run:
|
||||
name: Run ember-cli (smoke test)
|
||||
command: |
|
||||
cd examples/ember-cli
|
||||
yarn storybook --smoke-test
|
||||
- run:
|
||||
name: Run polymer-cli (smoke test)
|
||||
command: |
|
||||
@ -165,7 +166,7 @@ jobs:
|
||||
command: |
|
||||
cd examples/riot-kitchen-sink
|
||||
yarn storybook --smoke-test
|
||||
react-native:
|
||||
native-smoke-tests:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
@ -173,22 +174,12 @@ jobs:
|
||||
at: .
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: yarn bootstrap --reactnative --reactnativeapp
|
||||
- run:
|
||||
name: Run React-Native example
|
||||
command: |
|
||||
cd examples/react-native-vanilla
|
||||
yarn storybook --smoke-test
|
||||
command: yarn bootstrap --reactnativeapp
|
||||
- run:
|
||||
name: Run React-Native-App example
|
||||
command: |
|
||||
cd examples/crna-kitchen-sink
|
||||
cd examples-native/crna-kitchen-sink
|
||||
yarn storybook --smoke-test
|
||||
- run:
|
||||
name: Run React-Native unit tests
|
||||
command: |
|
||||
yarn test --coverage --runInBand --reactnative
|
||||
yarn coverage
|
||||
docs:
|
||||
<<: *defaults
|
||||
steps:
|
||||
@ -226,7 +217,7 @@ jobs:
|
||||
- run:
|
||||
name: Lint
|
||||
command: yarn lint
|
||||
unit-test:
|
||||
test:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
@ -248,10 +239,8 @@ jobs:
|
||||
- run:
|
||||
name: Upload coverage
|
||||
command: yarn coverage
|
||||
cli:
|
||||
cli-test:
|
||||
<<: *defaults
|
||||
docker:
|
||||
- image: andthensome/docker-node-rsync
|
||||
environment:
|
||||
BASH_ENV: ~/.bashrc
|
||||
steps:
|
||||
@ -262,10 +251,8 @@ jobs:
|
||||
name: Test
|
||||
command: yarn test --cli
|
||||
no_output_timeout: 1800
|
||||
cli-latest-cra:
|
||||
cli-test-latest-cra:
|
||||
<<: *defaults
|
||||
docker:
|
||||
- image: andthensome/docker-node-rsync
|
||||
environment:
|
||||
BASH_ENV: ~/.bashrc
|
||||
steps:
|
||||
@ -285,24 +272,24 @@ workflows:
|
||||
requires:
|
||||
- docs
|
||||
- build
|
||||
- example-kitchen-sinks:
|
||||
- examples:
|
||||
requires:
|
||||
- build
|
||||
- smoke-tests:
|
||||
requires:
|
||||
- build
|
||||
- react-native:
|
||||
- native-smoke-tests:
|
||||
requires:
|
||||
- build
|
||||
- unit-test:
|
||||
- test:
|
||||
requires:
|
||||
- build
|
||||
- coverage:
|
||||
requires:
|
||||
- unit-test
|
||||
- cli:
|
||||
- test
|
||||
- cli-test:
|
||||
requires:
|
||||
- build
|
||||
- cli-latest-cra:
|
||||
- cli-test-latest-cra:
|
||||
requires:
|
||||
- build
|
||||
|
@ -57,6 +57,7 @@ module.exports = {
|
||||
{
|
||||
devDependencies: [
|
||||
'examples/**',
|
||||
'examples-native/**',
|
||||
'**/example/**',
|
||||
'*.js',
|
||||
'**/*.test.js',
|
||||
|
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@ -28,13 +28,13 @@
|
||||
|
||||
/examples/angular-cli/ @igor-dv @alterx
|
||||
/examples/cra-kitchen-sink/ @ndelangen @UsulPro @hypnosphi
|
||||
/examples/crna-kitchen-sink/ @Gongreg @danielduan
|
||||
/examples/official-storybook/ @hypnosphi @danielduan @UsulPro
|
||||
/examples/polymer-cli/ @naipath @igor-dv
|
||||
/examples/react-native-vanilla/ @tmeasday @danielduan
|
||||
/examples/vue-kitchen-sink/ @igor-dv @alexandrebodin
|
||||
/examples/svelte-kitchen-sink/ @plumpNation
|
||||
|
||||
/examples-native/crna-kitchen-sink/ @Gongreg @danielduan
|
||||
|
||||
/lib/addons/ @ndelangen @theinterned
|
||||
/lib/channel-postmessage/ @mnmtanish @ndelangen
|
||||
/lib/channel-websocket/ @mnmtanish @ndelangen
|
||||
|
1
.remarkignore
Normal file
1
.remarkignore
Normal file
@ -0,0 +1 @@
|
||||
CHANGELOG.md
|
@ -18,15 +18,17 @@ object Project : Project({
|
||||
vcsRoot(OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster1)
|
||||
vcsRoot(OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
|
||||
|
||||
buildType(OpenSourceProjects_Storybook_Bootstrap)
|
||||
buildType(OpenSourceProjects_Storybook_CliTestLatestCra)
|
||||
buildType(OpenSourceProjects_Storybook_Examples)
|
||||
buildType(OpenSourceProjects_Storybook_Danger)
|
||||
buildType(OpenSourceProjects_Storybook_ReactNative)
|
||||
buildType(OpenSourceProjects_Storybook_NativeSmokeTests)
|
||||
buildType(OpenSourceProjects_Storybook_Docs)
|
||||
buildType(OpenSourceProjects_Storybook_Build_2)
|
||||
buildType(OpenSourceProjects_Storybook_CliTest)
|
||||
buildType(OpenSourceProjects_Storybook_Test)
|
||||
buildType(OpenSourceProjects_Storybook_Lint)
|
||||
buildType(OpenSourceProjects_Storybook_Lint_Warnings)
|
||||
buildType(OpenSourceProjects_Storybook_SmokeTests)
|
||||
buildType(OpenSourceProjects_Storybook_Chromatic)
|
||||
|
||||
|
78
.teamcity/OpenSourceProjects_Storybook/buildTypes/OpenSourceProjects_Storybook_Bootstrap.kt
vendored
Normal file
78
.teamcity/OpenSourceProjects_Storybook/buildTypes/OpenSourceProjects_Storybook_Bootstrap.kt
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
package OpenSourceProjects_Storybook.buildTypes
|
||||
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.commitStatusPublisher
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildSteps.script
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.vcs
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.retryBuild
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.VcsTrigger
|
||||
|
||||
object OpenSourceProjects_Storybook_Bootstrap : BuildType({
|
||||
uuid = "9f9177e7-9ec9-4e2e-aabb-d304fd667712"
|
||||
id = "OpenSourceProjects_Storybook_Bootstrap"
|
||||
name = "Bootstrap"
|
||||
|
||||
artifactRules = """
|
||||
addons/*/dist/** => dist.zip/addons
|
||||
addons/storyshots/*/dist/** => dist.zip/addons/storyshots
|
||||
app/*/dist/** => dist.zip/app
|
||||
lib/*/dist/** => dist.zip/lib
|
||||
""".trimIndent()
|
||||
|
||||
vcs {
|
||||
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Bootstrap"
|
||||
scriptContent = """
|
||||
#!/bin/sh
|
||||
|
||||
set -e -x
|
||||
|
||||
yarn
|
||||
yarn bootstrap --core
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
|
||||
triggers {
|
||||
vcs {
|
||||
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
|
||||
triggerRules = "-:comment=^TeamCity change:**"
|
||||
branchFilter = """
|
||||
+:pull/*
|
||||
+:release/*
|
||||
+:master
|
||||
+:snyk-fix-*
|
||||
""".trimIndent()
|
||||
enabled = false
|
||||
}
|
||||
retryBuild {
|
||||
delaySeconds = 60
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
features {
|
||||
commitStatusPublisher {
|
||||
publisher = github {
|
||||
githubUrl = "https://api.github.com"
|
||||
authType = personalToken {
|
||||
token = "credentialsJSON:5ffe2d7e-531e-4f6f-b1fc-a41bfea26eaa"
|
||||
}
|
||||
}
|
||||
param("github_oauth_user", "Hypnosphi")
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
doesNotContain("env.OS", "Windows")
|
||||
}
|
||||
|
||||
cleanup {
|
||||
artifacts(days = 1)
|
||||
}
|
||||
})
|
@ -4,8 +4,9 @@ import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.commitStatusPublisher
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.failureConditions.BuildFailureOnMetric
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.failureConditions.failOnMetricChange
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.VcsTrigger
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.vcs
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.VcsTrigger
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.finishBuildTrigger
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.retryBuild
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.merge
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.ui.*
|
||||
@ -32,12 +33,17 @@ object OpenSourceProjects_Storybook_Build_2 : BuildType({
|
||||
+:pull/*
|
||||
+:release/*
|
||||
+:master
|
||||
+:dependencies.io-*
|
||||
+:snyk-fix-*
|
||||
""".trimIndent()
|
||||
}
|
||||
retryBuild {
|
||||
delaySeconds = 60
|
||||
}
|
||||
finishBuildTrigger {
|
||||
enabled = false
|
||||
buildTypeExtId = "OpenSourceProjects_Storybook_Bootstrap"
|
||||
successfulOnly = true
|
||||
branchFilter = ""
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +70,9 @@ object OpenSourceProjects_Storybook_Build_2 : BuildType({
|
||||
param("github_oauth_user", "Hypnosphi")
|
||||
}
|
||||
merge {
|
||||
branchFilter = "+:dependencies.io-*"
|
||||
branchFilter = """
|
||||
+:snyk-fix-*
|
||||
""".trimIndent()
|
||||
destinationBranch = "<default>"
|
||||
commitMessage = "Merge branch '%teamcity.build.branch%'"
|
||||
}
|
||||
@ -86,7 +94,7 @@ object OpenSourceProjects_Storybook_Build_2 : BuildType({
|
||||
onDependencyCancel = FailureAction.ADD_PROBLEM
|
||||
}
|
||||
}
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_ReactNative) {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_NativeSmokeTests) {
|
||||
snapshot {
|
||||
onDependencyCancel = FailureAction.ADD_PROBLEM
|
||||
}
|
||||
@ -106,5 +114,10 @@ object OpenSourceProjects_Storybook_Build_2 : BuildType({
|
||||
onDependencyCancel = FailureAction.ADD_PROBLEM
|
||||
}
|
||||
}
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_CliTest) {
|
||||
snapshot {
|
||||
onDependencyCancel = FailureAction.ADD_PROBLEM
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -21,17 +21,16 @@ object OpenSourceProjects_Storybook_Chromatic : BuildType({
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Bootstrap"
|
||||
scriptContent = """
|
||||
yarn
|
||||
yarn bootstrap --core
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "Chromatic"
|
||||
scriptContent = "yarn chromatic"
|
||||
scriptContent = """
|
||||
#!/bin/sh
|
||||
|
||||
set -e -x
|
||||
|
||||
yarn
|
||||
yarn chromatic
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
@ -49,6 +48,15 @@ object OpenSourceProjects_Storybook_Chromatic : BuildType({
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Bootstrap) {
|
||||
snapshot {
|
||||
onDependencyFailure = FailureAction.FAIL_TO_START
|
||||
}
|
||||
|
||||
artifacts {
|
||||
artifactRules = "dist.zip!**"
|
||||
}
|
||||
}
|
||||
allApps {
|
||||
dependency(config) {
|
||||
snapshot {}
|
||||
|
@ -3,9 +3,6 @@ package OpenSourceProjects_Storybook.buildTypes
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.commitStatusPublisher
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildSteps.script
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.vcs
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.retryBuild
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.VcsTrigger
|
||||
|
||||
object OpenSourceProjects_Storybook_CliTest : BuildType({
|
||||
uuid = "b1db1a3a-a4cf-46ea-8f55-98b86611f92e"
|
||||
@ -18,33 +15,18 @@ object OpenSourceProjects_Storybook_CliTest : BuildType({
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Bootstrap"
|
||||
scriptContent = """
|
||||
yarn
|
||||
yarn bootstrap --core
|
||||
""".trimIndent()
|
||||
dockerImage = "andthensome/docker-node-rsync"
|
||||
}
|
||||
script {
|
||||
name = "Test"
|
||||
scriptContent = "yarn test --cli"
|
||||
dockerImage = "andthensome/docker-node-rsync"
|
||||
}
|
||||
}
|
||||
scriptContent = """
|
||||
#!/bin/sh
|
||||
|
||||
triggers {
|
||||
vcs {
|
||||
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
|
||||
triggerRules = "-:comment=^TeamCity change:**"
|
||||
branchFilter = """
|
||||
+:pull/*
|
||||
+:release/*
|
||||
+:master
|
||||
+:dependencies.io-*
|
||||
set -e -x
|
||||
|
||||
yarn
|
||||
yarn test --cli
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
retryBuild {}
|
||||
}
|
||||
|
||||
features {
|
||||
@ -59,6 +41,18 @@ object OpenSourceProjects_Storybook_CliTest : BuildType({
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Bootstrap) {
|
||||
snapshot {
|
||||
onDependencyFailure = FailureAction.FAIL_TO_START
|
||||
}
|
||||
|
||||
artifacts {
|
||||
artifactRules = "dist.zip!**"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
doesNotContain("env.OS", "Windows")
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.commitStatusPublisher
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildSteps.script
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.vcs
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.retryBuild
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.VcsTrigger
|
||||
|
||||
object OpenSourceProjects_Storybook_CliTestLatestCra : BuildType({
|
||||
@ -17,18 +18,17 @@ object OpenSourceProjects_Storybook_CliTestLatestCra : BuildType({
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Bootstrap"
|
||||
scriptContent = """
|
||||
yarn
|
||||
yarn bootstrap --core
|
||||
""".trimIndent()
|
||||
dockerImage = "andthensome/docker-node-rsync"
|
||||
}
|
||||
script {
|
||||
name = "Test"
|
||||
scriptContent = "yarn test-latest-cra"
|
||||
dockerImage = "andthensome/docker-node-rsync"
|
||||
scriptContent = """
|
||||
#!/bin/sh
|
||||
|
||||
set -e -x
|
||||
|
||||
yarn
|
||||
yarn test-latest-cra
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,7 +36,13 @@ object OpenSourceProjects_Storybook_CliTestLatestCra : BuildType({
|
||||
vcs {
|
||||
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
|
||||
triggerRules = "-:comment=^TeamCity change:**"
|
||||
branchFilter = """
|
||||
+:pull/*
|
||||
+:release/*
|
||||
+:master
|
||||
""".trimIndent()
|
||||
}
|
||||
retryBuild {}
|
||||
}
|
||||
|
||||
features {
|
||||
@ -51,6 +57,18 @@ object OpenSourceProjects_Storybook_CliTestLatestCra : BuildType({
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Bootstrap) {
|
||||
snapshot {
|
||||
onDependencyFailure = FailureAction.FAIL_TO_START
|
||||
}
|
||||
|
||||
artifacts {
|
||||
artifactRules = "dist.zip!**"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
doesNotContain("env.OS", "Windows")
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ object OpenSourceProjects_Storybook_Danger : BuildType({
|
||||
name = "Danger"
|
||||
|
||||
params {
|
||||
password("env.DANGER_GITHUB_API_TOKEN", "credentialsJSON:8fa112e0-d0e0-4f9f-9f18-01471a999b4d", display = ParameterDisplay.HIDDEN)
|
||||
param("env.PULL_REQUEST_URL", "https://github.com/storybooks/storybook/%teamcity.build.branch%")
|
||||
password("env.DANGER_GITHUB_API_TOKEN", "credentialsJSON:7f0943ab-dfca-49dd-b926-03062007bfd0")
|
||||
param("env.PULL_REQUEST_URL", "https://github.com/storybooks/storybook/pull/%teamcity.build.branch%")
|
||||
}
|
||||
|
||||
vcs {
|
||||
@ -24,14 +24,16 @@ object OpenSourceProjects_Storybook_Danger : BuildType({
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Install"
|
||||
scriptContent = "yarn"
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "Danger"
|
||||
scriptContent = "yarn danger ci"
|
||||
scriptContent = """
|
||||
#!/bin/sh
|
||||
|
||||
set -e -x
|
||||
|
||||
yarn
|
||||
yarn danger ci
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
@ -39,7 +41,6 @@ object OpenSourceProjects_Storybook_Danger : BuildType({
|
||||
triggers {
|
||||
vcs {
|
||||
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
|
||||
triggerRules = "-:comment=^TeamCity change:**"
|
||||
branchFilter = """
|
||||
+:*
|
||||
-:master
|
||||
@ -60,6 +61,12 @@ object OpenSourceProjects_Storybook_Danger : BuildType({
|
||||
}
|
||||
param("github_oauth_user", "Hypnosphi")
|
||||
}
|
||||
feature {
|
||||
type = "pullRequests"
|
||||
param("filterAuthorRole", "EVERYBODY")
|
||||
param("authenticationType", "token")
|
||||
param("secure:accessToken", "credentialsJSON:5ffe2d7e-531e-4f6f-b1fc-a41bfea26eaa")
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
|
@ -3,7 +3,6 @@ package OpenSourceProjects_Storybook.buildTypes
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.commitStatusPublisher
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildSteps.script
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.vcs
|
||||
|
||||
object OpenSourceProjects_Storybook_Docs : BuildType({
|
||||
uuid = "1bda59b5-d08d-4fd8-b317-953e7d79d881"
|
||||
@ -22,23 +21,18 @@ object OpenSourceProjects_Storybook_Docs : BuildType({
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Install"
|
||||
workingDir = "docs"
|
||||
scriptContent = "yarn install --frozen-lockfile"
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "Build"
|
||||
workingDir = "docs"
|
||||
scriptContent = "yarn build"
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
scriptContent = """
|
||||
#!/bin/sh
|
||||
|
||||
triggers {
|
||||
vcs {
|
||||
enabled = false
|
||||
set -e -x
|
||||
|
||||
yarn --frozen-lockfile
|
||||
yarn build
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,21 +23,14 @@ examples/official-storybook/image-snapshots/__image_snapshots__ => image-snapsho
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Bootstrap"
|
||||
scriptContent = """
|
||||
yarn
|
||||
yarn bootstrap --core
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "official-storybook"
|
||||
scriptContent = """
|
||||
#!/bin/sh
|
||||
|
||||
set -e -x
|
||||
|
||||
|
||||
yarn
|
||||
cd examples/official-storybook
|
||||
rm -rf storybook-static
|
||||
yarn build-storybook
|
||||
@ -90,6 +83,15 @@ examples/official-storybook/image-snapshots/__image_snapshots__ => image-snapsho
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Bootstrap) {
|
||||
snapshot {
|
||||
onDependencyFailure = FailureAction.FAIL_TO_START
|
||||
}
|
||||
|
||||
artifacts {
|
||||
artifactRules = "dist.zip!**"
|
||||
}
|
||||
}
|
||||
allApps {
|
||||
dependency(config) {
|
||||
snapshot {}
|
||||
|
@ -3,7 +3,8 @@ package OpenSourceProjects_Storybook.buildTypes
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.commitStatusPublisher
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildSteps.script
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.vcs
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.failureConditions.BuildFailureOnMetric
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.failureConditions.failOnMetricChange
|
||||
|
||||
object OpenSourceProjects_Storybook_Lint : BuildType({
|
||||
uuid = "42cfbb9a-f35b-4f96-afae-0b508927a737"
|
||||
@ -17,24 +18,18 @@ object OpenSourceProjects_Storybook_Lint : BuildType({
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Bootstrap"
|
||||
name = "Lint"
|
||||
scriptContent = """
|
||||
#!/bin/sh
|
||||
|
||||
set -e -x
|
||||
|
||||
yarn
|
||||
yarn bootstrap --core --docs
|
||||
yarn bootstrap --docs
|
||||
yarn lint:ci
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "Lint"
|
||||
scriptContent = "yarn lint:ci"
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
|
||||
triggers {
|
||||
vcs {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
features {
|
||||
@ -49,6 +44,18 @@ object OpenSourceProjects_Storybook_Lint : BuildType({
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Bootstrap) {
|
||||
snapshot {
|
||||
onDependencyFailure = FailureAction.FAIL_TO_START
|
||||
}
|
||||
|
||||
artifacts {
|
||||
artifactRules = "dist.zip!**"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
doesNotContain("env.OS", "Windows")
|
||||
}
|
||||
@ -56,4 +63,15 @@ object OpenSourceProjects_Storybook_Lint : BuildType({
|
||||
cleanup {
|
||||
artifacts(days = 1)
|
||||
}
|
||||
|
||||
failureConditions {
|
||||
failOnMetricChange {
|
||||
metric = BuildFailureOnMetric.MetricType.INSPECTION_ERROR_COUNT
|
||||
threshold = 0
|
||||
units = BuildFailureOnMetric.MetricUnit.DEFAULT_UNIT
|
||||
comparison = BuildFailureOnMetric.MetricComparison.MORE
|
||||
compareTo = value()
|
||||
param("anchorBuild", "lastSuccessful")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
91
.teamcity/OpenSourceProjects_Storybook/buildTypes/OpenSourceProjects_Storybook_Lint_Warnings.kt
vendored
Normal file
91
.teamcity/OpenSourceProjects_Storybook/buildTypes/OpenSourceProjects_Storybook_Lint_Warnings.kt
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
package OpenSourceProjects_Storybook.buildTypes
|
||||
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.commitStatusPublisher
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildSteps.script
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.vcs
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.failureConditions.BuildFailureOnMetric
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.failureConditions.failOnMetricChange
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.VcsTrigger
|
||||
|
||||
object OpenSourceProjects_Storybook_Lint_Warnings : BuildType({
|
||||
uuid = "42cfbb9a-f35b-4f96-afae-0b508927a738"
|
||||
id = "OpenSourceProjects_Storybook_Lint_Warnings"
|
||||
name = "Lint Warnings"
|
||||
|
||||
vcs {
|
||||
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
|
||||
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Lint"
|
||||
scriptContent = """
|
||||
#!/bin/sh
|
||||
|
||||
set -e -x
|
||||
|
||||
yarn
|
||||
yarn bootstrap --docs
|
||||
yarn lint:ci
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
|
||||
triggers {
|
||||
vcs {
|
||||
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
|
||||
triggerRules = "-:comment=^TeamCity change:**"
|
||||
branchFilter = """
|
||||
+:pull/*
|
||||
+:release/*
|
||||
+:master
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
features {
|
||||
commitStatusPublisher {
|
||||
publisher = github {
|
||||
githubUrl = "https://api.github.com"
|
||||
authType = personalToken {
|
||||
token = "credentialsJSON:5ffe2d7e-531e-4f6f-b1fc-a41bfea26eaa"
|
||||
}
|
||||
}
|
||||
param("github_oauth_user", "Hypnosphi")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Bootstrap) {
|
||||
snapshot {
|
||||
onDependencyFailure = FailureAction.FAIL_TO_START
|
||||
}
|
||||
|
||||
artifacts {
|
||||
artifactRules = "dist.zip!**"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
doesNotContain("env.OS", "Windows")
|
||||
}
|
||||
|
||||
cleanup {
|
||||
artifacts(days = 1)
|
||||
}
|
||||
|
||||
failureConditions {
|
||||
failOnMetricChange {
|
||||
metric = BuildFailureOnMetric.MetricType.INSPECTION_WARN_COUNT
|
||||
threshold = 0
|
||||
units = BuildFailureOnMetric.MetricUnit.DEFAULT_UNIT
|
||||
comparison = BuildFailureOnMetric.MetricComparison.MORE
|
||||
compareTo = value()
|
||||
param("anchorBuild", "lastSuccessful")
|
||||
}
|
||||
}
|
||||
})
|
@ -4,12 +4,10 @@ import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.commitStatusPublisher
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildSteps.script
|
||||
|
||||
object OpenSourceProjects_Storybook_ReactNative : BuildType({
|
||||
object OpenSourceProjects_Storybook_NativeSmokeTests : BuildType({
|
||||
uuid = "ac276912-df1a-44f1-8de2-056276193ce8"
|
||||
id = "OpenSourceProjects_Storybook_ReactNative"
|
||||
name = "React Native"
|
||||
|
||||
artifactRules = "examples/react-native-vanilla/coverage/lcov-report => coverage.zip"
|
||||
id = "OpenSourceProjects_Storybook_NativeSmokeTests"
|
||||
name = "Native Smoke Tests"
|
||||
|
||||
params {
|
||||
param("env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD", "true")
|
||||
@ -22,38 +20,20 @@ object OpenSourceProjects_Storybook_ReactNative : BuildType({
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Bootstrap"
|
||||
scriptContent = """
|
||||
yarn
|
||||
yarn bootstrap --core --reactnative --reactnativeapp
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "react-native-vanilla"
|
||||
scriptContent = """
|
||||
cd examples/react-native-vanilla
|
||||
yarn storybook --smoke-test
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "crna-kitchen-sink"
|
||||
scriptContent = """
|
||||
cd examples/crna-kitchen-sink
|
||||
#!/bin/sh
|
||||
|
||||
set -e -x
|
||||
|
||||
yarn
|
||||
yarn bootstrap --reactnativeapp
|
||||
cd examples-native/crna-kitchen-sink
|
||||
yarn storybook --smoke-test
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "Test"
|
||||
scriptContent = """
|
||||
yarn test --reactnative --coverage --runInBand --teamcity
|
||||
yarn coverage
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
|
||||
features {
|
||||
@ -68,6 +48,18 @@ object OpenSourceProjects_Storybook_ReactNative : BuildType({
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Bootstrap) {
|
||||
snapshot {
|
||||
onDependencyFailure = FailureAction.FAIL_TO_START
|
||||
}
|
||||
|
||||
artifacts {
|
||||
artifactRules = "dist.zip!**"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
doesNotContain("env.OS", "Windows")
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package OpenSourceProjects_Storybook.buildTypes
|
||||
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.commitStatusPublisher
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildSteps.script
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.failureConditions.BuildFailureOnMetric
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.failureConditions.failOnMetricChange
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.VcsTrigger
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.vcs
|
||||
|
||||
object OpenSourceProjects_Storybook_SBNext : BuildType({
|
||||
uuid = "dc66f07a-281f-4434-97ca-f1480b7cfc51"
|
||||
id = "OpenSourceProjects_Storybook_SBNext"
|
||||
name = "SBNext"
|
||||
|
||||
artifactRules = "ui/out => demo.zip"
|
||||
|
||||
vcs {
|
||||
root("OpenSourceProjects_Storybook_SBNext")
|
||||
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Install"
|
||||
scriptContent = "yarn"
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "Lint"
|
||||
scriptContent = "yarn lint"
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "Test"
|
||||
enabled = false
|
||||
scriptContent = "yarn test"
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "Build"
|
||||
workingDir = "server"
|
||||
scriptContent = "yarn build"
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "Export"
|
||||
workingDir = "demo"
|
||||
scriptContent = "yarn export"
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
|
||||
triggers {
|
||||
vcs {
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
doesNotContain("env.OS", "Windows")
|
||||
}
|
||||
})
|
@ -16,11 +16,8 @@ object OpenSourceProjects_Storybook_SmokeTests : BuildType({
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Bootstrap"
|
||||
scriptContent = """
|
||||
yarn
|
||||
yarn bootstrap --core
|
||||
""".trimIndent()
|
||||
name = "Install"
|
||||
scriptContent = "yarn"
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
allApps {
|
||||
@ -65,6 +62,18 @@ object OpenSourceProjects_Storybook_SmokeTests : BuildType({
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Bootstrap) {
|
||||
snapshot {
|
||||
onDependencyFailure = FailureAction.FAIL_TO_START
|
||||
}
|
||||
|
||||
artifacts {
|
||||
artifactRules = "dist.zip!**"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
doesNotContain("env.OS", "Windows")
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package OpenSourceProjects_Storybook.buildTypes
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildFeatures.commitStatusPublisher
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.buildSteps.script
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.triggers.vcs
|
||||
|
||||
object OpenSourceProjects_Storybook_Test : BuildType({
|
||||
uuid = "9f9177e7-9ec9-4e2e-aabb-d304fd667711"
|
||||
@ -18,30 +17,20 @@ object OpenSourceProjects_Storybook_Test : BuildType({
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Bootstrap"
|
||||
scriptContent = """
|
||||
yarn
|
||||
yarn bootstrap --core
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "Test"
|
||||
scriptContent = """
|
||||
#!/bin/sh
|
||||
|
||||
set -e -x
|
||||
|
||||
yarn
|
||||
yarn test --core --coverage --runInBand --teamcity
|
||||
yarn coverage
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
}
|
||||
|
||||
triggers {
|
||||
vcs {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
features {
|
||||
commitStatusPublisher {
|
||||
publisher = github {
|
||||
@ -54,6 +43,18 @@ object OpenSourceProjects_Storybook_Test : BuildType({
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Bootstrap) {
|
||||
snapshot {
|
||||
onDependencyFailure = FailureAction.FAIL_TO_START
|
||||
}
|
||||
|
||||
artifacts {
|
||||
artifactRules = "dist.zip!**"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
doesNotContain("env.OS", "Windows")
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ enum class StorybookApp(val appName: String, val exampleDir: String, val merged:
|
||||
MITHRIL("Mithril", "mithril-kitchen-sink"),
|
||||
HTML("HTML", "html-kitchen-sink"),
|
||||
MARKO("Marko", "marko-cli"),
|
||||
HYPERAPP("Hyperapp", "hyperapp-kitchen-sink", false),
|
||||
SVELTE("Svelte", "svelte-kitchen-sink"),
|
||||
RIOT("Riot", "riot-kitchen-sink");
|
||||
RIOT("Riot", "riot-kitchen-sink"),
|
||||
EMBER("Ember", "ember-cli");
|
||||
|
||||
val lowerName = appName.toLowerCase()
|
||||
|
||||
@ -36,14 +36,6 @@ enum class StorybookApp(val appName: String, val exampleDir: String, val merged:
|
||||
artifactRules = artifactPath
|
||||
|
||||
steps {
|
||||
script {
|
||||
name = "Bootstrap"
|
||||
scriptContent = """
|
||||
yarn
|
||||
yarn bootstrap --core
|
||||
""".trimIndent()
|
||||
dockerImage = "node:%docker.node.version%"
|
||||
}
|
||||
script {
|
||||
name = "build"
|
||||
scriptContent = """
|
||||
@ -51,6 +43,7 @@ enum class StorybookApp(val appName: String, val exampleDir: String, val merged:
|
||||
|
||||
set -e -x
|
||||
|
||||
yarn
|
||||
cd examples/$exampleDir
|
||||
yarn build-storybook
|
||||
""".trimIndent()
|
||||
@ -82,6 +75,18 @@ enum class StorybookApp(val appName: String, val exampleDir: String, val merged:
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Bootstrap) {
|
||||
snapshot {
|
||||
onDependencyFailure = FailureAction.FAIL_TO_START
|
||||
}
|
||||
|
||||
artifacts {
|
||||
artifactRules = "dist.zip!**"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requirements {
|
||||
doesNotContain("env.OS", "Windows")
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package OpenSourceProjects_Storybook.patches.buildTypes
|
||||
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2017_2.ui.*
|
||||
|
||||
/*
|
||||
This patch script was generated by TeamCity on settings change in UI.
|
||||
To apply the patch, change the buildType with uuid = '759f0116-2f7d-4c03-8220-56e4ab03be3a' (id = 'OpenSourceProjects_Storybook_Danger')
|
||||
accordingly, and delete the patch script.
|
||||
*/
|
||||
changeBuildType("759f0116-2f7d-4c03-8220-56e4ab03be3a") {
|
||||
params {
|
||||
expect {
|
||||
password("env.DANGER_GITHUB_API_TOKEN", "credentialsJSON:7f0943ab-dfca-49dd-b926-03062007bfd0")
|
||||
}
|
||||
update {
|
||||
password("env.DANGER_GITHUB_API_TOKEN", "credentialsJSON:9ac87388-d267-4def-a10e-3e596369f644")
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ object OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMa
|
||||
id = "OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster1"
|
||||
name = "https://github.com/storybooks/storybook#refs/heads/master (1)"
|
||||
url = "git@github.com:storybooks/storybook.git"
|
||||
branchSpec = "+:refs/(pull/*)/head"
|
||||
authMethod = uploadedKey {
|
||||
userName = "git"
|
||||
uploadedKey = "Storybook bot"
|
||||
|
@ -1,19 +1,22 @@
|
||||
## Addon / Framework Support Table
|
||||
|
||||
| | [React](app/react)|[React Native](app/react-native)|[Vue](app/vue)|[Angular](app/angular)| [Polymer](app/polymer)| [Mithril](app/mithril)| [HTML](app/html)| [Marko](app/marko)| [Svelte](app/svelte)| [Riot](app/riot)|
|
||||
| ----------- |:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|
|
||||
|[a11y](addons/a11y) |+| |+|+|+|+|+|+| | |
|
||||
|[actions](addons/actions) |+|+|+|+|+|+|+|+|+|+|
|
||||
|[backgrounds](addons/backgrounds) |+| |+|+|+|+|+|+|+|+|
|
||||
|[centered](addons/centered) |+| |+|+| |+|+| |+| |
|
||||
|[events](addons/events) |+| |+|+|+|+|+|+| | |
|
||||
|[graphql](addons/graphql) |+| | | | | | | | | |
|
||||
|[info](addons/info) |+| | | | | | | | | |
|
||||
|[jest](addons/jest) |+| | |+| | |+| | | |
|
||||
|[knobs](addons/knobs) |+|+|+|+|+|+|+|+|+|+|
|
||||
|[links](addons/links) |+|+|+|+|+|+|+| |+|+|
|
||||
|[notes](addons/notes) |+| |+|+|+|+|+| |+|+|
|
||||
|[options](addons/options) |+|+|+|+|+|+|+| |+|+|
|
||||
|[storyshots](addons/storyshots) |+|+|+|+| | |+| |+|+|
|
||||
|[storysource](addons/storysource)|+| |+|+|+|+|+|+|+|+|
|
||||
|[viewport](addons/viewport) |+| |+|+|+|+|+|+|+|+|
|
||||
## Addon / Framework Support Table
|
||||
|
||||
| | [React](app/react)|[React Native](app/react-native)|[Vue](app/vue)|[Angular](app/angular)| [Polymer](app/polymer)| [Mithril](app/mithril)| [HTML](app/html)| [Marko](app/marko)| [Svelte](app/svelte)| [Riot](app/riot)| [Ember](app/ember)|
|
||||
| ----------- |:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|
|
||||
|[a11y](addons/a11y) |+| |+|+|+|+|+|+| | |+|
|
||||
|[actions](addons/actions) |+|+|+|+|+|+|+|+|+|+|+|
|
||||
|[backgrounds](addons/backgrounds) |+|*|+|+|+|+|+|+|+|+|+|
|
||||
|[centered](addons/centered) |+| |+|+| |+|+| |+| |+|
|
||||
|[events](addons/events) |+| |+|+|+|+|+|+| | |+|
|
||||
|[graphql](addons/graphql) |+| | | | | | | | | | |
|
||||
|[google-analytics](addons/google-analytics) |+|+|+|+|+|+|+|+|+|+|+|
|
||||
|[info](addons/info) |+| | | | | | | | | | |
|
||||
|[jest](addons/jest) |+| | |+| | |+| | | | |
|
||||
|[knobs](addons/knobs) |+|+*|+|+|+|+|+|+|+|+|+|
|
||||
|[links](addons/links) |+|+|+|+|+|+|+| |+|+|+|
|
||||
|[notes](addons/notes) |+|+*|+|+|+|+|+| |+|+|+|
|
||||
|[options](addons/options) |+|+|+|+|+|+|+| |+|+|+|
|
||||
|[storyshots](addons/storyshots) |+|+|+|+| | |+| |+|+| |
|
||||
|[storysource](addons/storysource) |+| |+|+|+|+|+|+|+|+|+|
|
||||
|[viewport](addons/viewport) |+| |+|+|+|+|+|+|+|+|+|
|
||||
|
||||
`*` - React Native on device addon (addons/onDevice-\<name>)
|
||||
|
203
CHANGELOG.md
203
CHANGELOG.md
@ -1,3 +1,192 @@
|
||||
# 4.0.0-rc.1
|
||||
|
||||
2018-October-18
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- Angular: expose webpackFinal extension [#4431](https://github.com/storybooks/storybook/pull/4431)
|
||||
- Addon-Knobs: fix ints as values [#4465](https://github.com/storybooks/storybook/pull/4465)
|
||||
|
||||
#### Maintenance
|
||||
|
||||
- Add Angular 6 fixture to the sb-cli tests [#4464](https://github.com/storybooks/storybook/pull/4464)
|
||||
|
||||
#### Dependency Upgrades
|
||||
|
||||
- Require React 16.3 as a peer dependency [#4458](https://github.com/storybooks/storybook/pull/4458)
|
||||
- Bump @ember/test-helpers from 0.7.26 to 0.7.27 [#4455](https://github.com/storybooks/storybook/pull/4455)
|
||||
- Bump eslint-plugin-jest from 21.25.0 to 21.25.1 [#4456](https://github.com/storybooks/storybook/pull/4456)
|
||||
- Bump autoprefixer from 9.2.0 to 9.2.1 [#4457](https://github.com/storybooks/storybook/pull/4457)
|
||||
- Bump @types/node from 10.11.7 to 10.12.0 [#4434](https://github.com/storybooks/storybook/pull/4434)
|
||||
- Bump ember-cli-inject-live-reload from 2.0.0 to 2.0.1 [#4435](https://github.com/storybooks/storybook/pull/4435)
|
||||
- Bump gatsby-plugin-sharp from 1.6.48 to 2.0.7 in /docs [#4438](https://github.com/storybooks/storybook/pull/4438)
|
||||
- Bump marked from 0.4.0 to 0.5.1 in /docs [#4437](https://github.com/storybooks/storybook/pull/4437)
|
||||
- Bump highlight.js from 9.12.0 to 9.13.0 in /docs [#4440](https://github.com/storybooks/storybook/pull/4440)
|
||||
|
||||
# 4.0.0-rc.0
|
||||
|
||||
2018-October-15
|
||||
|
||||
#### Features
|
||||
|
||||
- Addon: google analytics [#4138](https://github.com/storybooks/storybook/pull/4138)
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- Improve environment var loading [#4413](https://github.com/storybooks/storybook/pull/4413)
|
||||
|
||||
#### Maintenance
|
||||
|
||||
- Skip preflight check when starting cra kitchen sink [#4408](https://github.com/storybooks/storybook/pull/4408)
|
||||
- Change crna-kitchen-sink path and Some CI maintenance [#4409](https://github.com/storybooks/storybook/pull/4409)
|
||||
- Create ember entry point to official storybook [#4426](https://github.com/storybooks/storybook/pull/4426)
|
||||
|
||||
#### Dependency Upgrades
|
||||
|
||||
- Bump ember-cli from 3.4.3 to 3.5.0 [#4429](https://github.com/storybooks/storybook/pull/4429)
|
||||
- Bump react-native-modal-selector from 0.0.27 to 0.0.29 [#4428](https://github.com/storybooks/storybook/pull/4428)
|
||||
- Bump ember-cli-inject-live-reload from 1.8.2 to 1.10.1 [#4423](https://github.com/storybooks/storybook/pull/4423)
|
||||
- Bump html-webpack-plugin from 4.0.0-beta.1 to 4.0.0-beta.2 [#4421](https://github.com/storybooks/storybook/pull/4421)
|
||||
- Bump react-scripts from 2.0.4 to 2.0.5 [#4420](https://github.com/storybooks/storybook/pull/4420)
|
||||
- Bump autoprefixer from 9.1.5 to 9.2.0 [#4417](https://github.com/storybooks/storybook/pull/4417)
|
||||
- Bump redux from 4.0.0 to 4.0.1 [#4419](https://github.com/storybooks/storybook/pull/4419)
|
||||
- Bump ts-loader from 5.2.1 to 5.2.2 [#4418](https://github.com/storybooks/storybook/pull/4418)
|
||||
- Bump eslint-plugin-jest from 21.24.1 to 21.25.0 [#4424](https://github.com/storybooks/storybook/pull/4424)
|
||||
- Bump lazy-universal-dotenv from 1.9.1 to 2.0.0 [#4422](https://github.com/storybooks/storybook/pull/4422)
|
||||
|
||||
# 4.0.0-alpha.25
|
||||
|
||||
2018-October-13
|
||||
|
||||
#### Breaking Changes
|
||||
|
||||
- CLI: Rename CLI to sb [#4345](https://github.com/storybooks/storybook/pull/4345)
|
||||
- React Native: Remove the packager from storybook [#4261](https://github.com/storybooks/storybook/pull/4261)
|
||||
- React-Native: On-device addons [#4381](https://github.com/storybooks/storybook/pull/4381)
|
||||
|
||||
#### Features
|
||||
|
||||
- Storybook version update check [#4334](https://github.com/storybooks/storybook/pull/4334)
|
||||
- CLI: specify project type interactively or as option [#4184](https://github.com/storybooks/storybook/pull/4184)
|
||||
- Addon-Jest: expand supported file types [#3983](https://github.com/storybooks/storybook/pull/3983)
|
||||
- CLI-less Node api [#4344](https://github.com/storybooks/storybook/pull/4344)
|
||||
- React-Native: Updated channel to support async option [#4326](https://github.com/storybooks/storybook/pull/4326)
|
||||
- React-Native: On-device addons for notes, knobs, backgrounds [#4327](https://github.com/storybooks/storybook/pull/4327)
|
||||
- Angular: Add support for "baseUrl" and "paths" from angular-cli [#4162](https://github.com/storybooks/storybook/pull/4162)
|
||||
- Angular: Added basePath support [#4323](https://github.com/storybooks/storybook/pull/4323)
|
||||
- Vue: support string-only component [#4285](https://github.com/storybooks/storybook/pull/4285)
|
||||
- Storyshots: Add snapshot serializer option [#4283](https://github.com/storybooks/storybook/pull/4283)
|
||||
- Storyshots: Support story-specific options as function [#4282](https://github.com/storybooks/storybook/pull/4282)
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- React-native: Remove deprecated attempt to load default addons [#4308](https://github.com/storybooks/storybook/pull/4308)
|
||||
- Fix panel layouts [#4304](https://github.com/storybooks/storybook/pull/4304)
|
||||
- [logging] better error logging for when opn fails to opn [#4348](https://github.com/storybooks/storybook/pull/4348)
|
||||
- Fix iPhone viewport dimensions [#4293](https://github.com/storybooks/storybook/pull/4293)
|
||||
- Fix Array.js value to string [#4336](https://github.com/storybooks/storybook/pull/4336)
|
||||
- Fixes to cli ember support [#4318](https://github.com/storybooks/storybook/pull/4318)
|
||||
- Update `addon-jest` to new propType [#4252](https://github.com/storybooks/storybook/pull/4252)
|
||||
|
||||
#### Maintenance
|
||||
|
||||
- Remove CRNA fixture [#4346](https://github.com/storybooks/storybook/pull/4346)
|
||||
- Try to fix cli tests [#4338](https://github.com/storybooks/storybook/pull/4338)
|
||||
- Updated installation for Angular [#4302](https://github.com/storybooks/storybook/pull/4302)
|
||||
- Fix the broken lint [#4310](https://github.com/storybooks/storybook/pull/4310)
|
||||
- [ember] add dependencies to root application [#4309](https://github.com/storybooks/storybook/pull/4309)
|
||||
|
||||
#### Dependency Upgrades
|
||||
|
||||
- Knobs/replace datepicker [#4380](https://github.com/storybooks/storybook/pull/4380)
|
||||
- Re-generate lockfiles [#4404](https://github.com/storybooks/storybook/pull/4404)
|
||||
- Run `yarn upgrade-interactive --latest` in root and docs [#4403](https://github.com/storybooks/storybook/pull/4403)
|
||||
- chore(deps): #4267 upgrade lodash to latest [#4284](https://github.com/storybooks/storybook/pull/4284)
|
||||
- Bump express from 4.16.3 to 4.16.4 [#4370](https://github.com/storybooks/storybook/pull/4370)
|
||||
- Bump @angular/cli from 6.2.4 to 6.2.5 [#4390](https://github.com/storybooks/storybook/pull/4390)
|
||||
- CHANGE back to use html-webpack-plugin to keep compatibility with plugins that depend on it [#4375](https://github.com/storybooks/storybook/pull/4375)
|
||||
- Bump danger from 4.4.6 to 4.4.7 [#4365](https://github.com/storybooks/storybook/pull/4365)
|
||||
- Bump @storybook/react from 3.4.8 to 3.4.11 in /docs [#4354](https://github.com/storybooks/storybook/pull/4354)
|
||||
- Bump sitemap from 1.13.0 to 2.0.1 in /docs [#4356](https://github.com/storybooks/storybook/pull/4356)
|
||||
- Bump husky from 1.1.1 to 1.1.2 [#4358](https://github.com/storybooks/storybook/pull/4358)
|
||||
- Tech/upgrades 5 [#4347](https://github.com/storybooks/storybook/pull/4347)
|
||||
|
||||
# 4.0.0-alpha.24
|
||||
|
||||
2018-October-04
|
||||
|
||||
#### Features
|
||||
|
||||
- Ember: add ember support [#4237](https://github.com/storybooks/storybook/pull/4237)
|
||||
- Riot: support the tagConstructor option [#4258](https://github.com/storybooks/storybook/pull/4258)
|
||||
- Presets: Add "addons" and "config" to preset extensions [#4240](https://github.com/storybooks/storybook/pull/4240)
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- Webpack: Fix broken SVGs [#4260](https://github.com/storybooks/storybook/pull/4260)
|
||||
- Babel/minify: use `builtIns: false` [#4262](https://github.com/storybooks/storybook/pull/4262)
|
||||
- Addon-Notes: Fix how markdownOptions are passed to marked [#4242](https://github.com/storybooks/storybook/pull/4242)
|
||||
- Addon-Knobs: Fix broken colorpicker [#4222](https://github.com/storybooks/storybook/pull/4222)
|
||||
|
||||
# 4.0.0-alpha.23
|
||||
|
||||
2018-September-25
|
||||
|
||||
#### Features
|
||||
|
||||
- Angular build time optimization [#4118](https://github.com/storybooks/storybook/pull/4118)
|
||||
- Pass Jest done callback to testMethod [#3853](https://github.com/storybooks/storybook/pull/3853)
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- Fix getstorybook CLI [#4213](https://github.com/storybooks/storybook/pull/4213)
|
||||
- FIX regression devtool, in case of cross domain parent, window.parent might throw [#4199](https://github.com/storybooks/storybook/pull/4199)
|
||||
|
||||
#### Dependency Upgrades
|
||||
|
||||
- Upgrade deps dealing with license issues [#4228](https://github.com/storybooks/storybook/pull/4228)
|
||||
- Use @emotion/snapshot-serializer [#4206](https://github.com/storybooks/storybook/pull/4206)
|
||||
|
||||
# 4.0.0-alpha.22
|
||||
|
||||
2018-September-19
|
||||
|
||||
#### Features
|
||||
|
||||
- Storyshots: story params support [#4176](https://github.com/storybooks/storybook/pull/4176)
|
||||
- Addon-options: story params support [#3965](https://github.com/storybooks/storybook/pull/3965)
|
||||
- Presets - API generalization [#4173](https://github.com/storybooks/storybook/pull/4173)
|
||||
- start-storybook: open browser tab on first compilation [#4149](https://github.com/storybooks/storybook/pull/4149)
|
||||
- start-storybook: suggest an alternative when the port is occupied [#4146](https://github.com/storybooks/storybook/pull/4146)
|
||||
- Merge webpack optimisation configs [#4121](https://github.com/storybooks/storybook/pull/4121)
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- Angular cli - fix prebuild [#4187](https://github.com/storybooks/storybook/pull/4187)
|
||||
- Presets - add babelDefault extension [#4155](https://github.com/storybooks/storybook/pull/4155)
|
||||
- CHANGE index.html.ejs to use files over chunks && UPGRADE generate-page-webpack-plugin [#4134](https://github.com/storybooks/storybook/pull/4134)
|
||||
- Allow replacing of stories (with warning rather than error) [#4061](https://github.com/storybooks/storybook/pull/4061)
|
||||
|
||||
#### Maintenance
|
||||
|
||||
- CLI refactor [#4168](https://github.com/storybooks/storybook/pull/4168)
|
||||
- Fix linter warnings [#4172](https://github.com/storybooks/storybook/pull/4172)
|
||||
- Remove gh-pages deploy in favor of netlify [#4128](https://github.com/storybooks/storybook/pull/4128)
|
||||
|
||||
#### Dependency Upgrades
|
||||
|
||||
- [core]: widen `airbnb-js-shims` dep range [#4189](https://github.com/storybooks/storybook/pull/4189)
|
||||
- Updating react-split-pane to version 0.1.84 [#4153](https://github.com/storybooks/storybook/pull/4153)
|
||||
- Riot tag loader missing in cli [#4122](https://github.com/storybooks/storybook/pull/4122)
|
||||
|
||||
# 3.4.11
|
||||
|
||||
2018-September-17
|
||||
|
||||
#### Dependencies
|
||||
|
||||
- Allow v1 or v2 in airbnb-js-shims [#4190](https://github.com/storybooks/storybook/pull/4190)
|
||||
|
||||
# 4.0.0-alpha.21
|
||||
|
||||
2018-September-07
|
||||
@ -17,8 +206,8 @@
|
||||
|
||||
#### Other
|
||||
|
||||
- [WIP] Refactor core and frameworks to work with presets [#4043](https://github.com/storybooks/storybook/pull/4043)
|
||||
- [WIP] presets - merge default babel configs [#4107](https://github.com/storybooks/storybook/pull/4107)
|
||||
- \[WIP\] Refactor core and frameworks to work with presets [#4043](https://github.com/storybooks/storybook/pull/4043)
|
||||
- \[WIP\] presets - merge default babel configs [#4107](https://github.com/storybooks/storybook/pull/4107)
|
||||
|
||||
# 4.0.0-alpha.20
|
||||
|
||||
@ -95,7 +284,7 @@ Not published to NPM
|
||||
- Temp revert the 36a2676 [#4062](https://github.com/storybooks/storybook/pull/4062)
|
||||
- Remove deprecation of --db-path and --enable-db [#4030](https://github.com/storybooks/storybook/pull/4030)
|
||||
- Remove git info extraction [#4031](https://github.com/storybooks/storybook/pull/4031)
|
||||
- Fixed homepage links [skip ci] [#4008](https://github.com/storybooks/storybook/pull/4008)
|
||||
- Fixed homepage links \[skip ci\] [#4008](https://github.com/storybooks/storybook/pull/4008)
|
||||
- CHANGE html-webpack-plugin for generate-page-plugin [#3919](https://github.com/storybooks/storybook/pull/3919)
|
||||
|
||||
# 4.0.0-alpha.16
|
||||
@ -108,7 +297,7 @@ Not published to NPM
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- [BUG FIX] Use fixed version of react-dev-utils [#3959](https://github.com/storybooks/storybook/pull/3959)
|
||||
- \[BUG FIX\] Use fixed version of react-dev-utils [#3959](https://github.com/storybooks/storybook/pull/3959)
|
||||
- Inline emotion css calls that require theme to avoid using state [#3950](https://github.com/storybooks/storybook/pull/3950)
|
||||
|
||||
#### Dependency Upgrades
|
||||
@ -998,7 +1187,7 @@ Read on for more improvements, fixes, 1In addition, there are hundreds of depend
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- [Addon-storyshots] Remove default options on "goto" call [#3298](https://github.com/storybooks/storybook/pull/3298)
|
||||
- \[Addon-storyshots\] Remove default options on "goto" call [#3298](https://github.com/storybooks/storybook/pull/3298)
|
||||
- CLI: add error handling for latest_version helper [#3297](https://github.com/storybooks/storybook/pull/3297)
|
||||
- Refactor CLI to use `npm` and `yarn` instead of third party packages [#3275](https://github.com/storybooks/storybook/pull/3275)
|
||||
- Fix issue when extending webpack config [#3279](https://github.com/storybooks/storybook/pull/3279)
|
||||
@ -1058,7 +1247,7 @@ Read on for more improvements, fixes, 1In addition, there are hundreds of depend
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- [Hotfix] Use published webpack 4 compatible fork of react-dev-utils [#3312](https://github.com/storybooks/storybook/pull/3312)
|
||||
- \[Hotfix\] Use published webpack 4 compatible fork of react-dev-utils [#3312](https://github.com/storybooks/storybook/pull/3312)
|
||||
|
||||
# 4.0.0-alpha.0
|
||||
|
||||
@ -1085,7 +1274,7 @@ Read on for more improvements, fixes, 1In addition, there are hundreds of depend
|
||||
#### Bug Fixes
|
||||
|
||||
- Update react-native symlink resolving and add support for flow [#3306](https://github.com/storybooks/storybook/pull/3306)
|
||||
- [Addon-storyshots] Remove default options on "goto" call [#3298](https://github.com/storybooks/storybook/pull/3298)
|
||||
- \[Addon-storyshots\] Remove default options on "goto" call [#3298](https://github.com/storybooks/storybook/pull/3298)
|
||||
- Remove onDeviceUI animation to support Detox screenshots [#3272](https://github.com/storybooks/storybook/pull/3272)
|
||||
- Angular: use resolveLoader from cliCommonConfig [#3251](https://github.com/storybooks/storybook/pull/3251)
|
||||
|
||||
|
@ -60,13 +60,6 @@ You can also pick suites from CLI. Suites available are listed below.
|
||||
This option executes test from `<rootdir>/app/react`, `<rootdir>/app/vue`, and `<rootdir>/lib`.
|
||||
Before the tests are ran, the project must be bootstrapped with core. You can accomplish this with `yarn bootstrap --core`
|
||||
|
||||
##### React-Native example Tests
|
||||
|
||||
`yarn test --reactnative`
|
||||
|
||||
This option executes tests from `<rootdir>/app/react-native`.
|
||||
Before these tests are ran, the project must be bootstrapped with the React Native example enabled. You can accomplish this by running `yarn bootstrap --reactnative`
|
||||
|
||||
##### CRA-kitchen-sink - Image snapshots using Storyshots
|
||||
|
||||
`yarn test --image`
|
||||
@ -312,6 +305,14 @@ The current manual release sequence is as follows:
|
||||
- Clean, build and publish the release
|
||||
- Cut and paste the changelog to the github release page, and mark it as a (pre-) release
|
||||
|
||||
**NOTE:** The very first time you publish a scoped package (`@storybook/x`) you need to make sure that it's package.json contains the following
|
||||
|
||||
```js
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
```
|
||||
|
||||
This sequence applies to both releases and pre-releases, but differs slightly between the two.
|
||||
|
||||
**NOTE: This is a work in progress. Don't try this unless you know what you're doing. We hope to automate this in CI, so this process is designed with that in mind.**
|
||||
|
54
MAINTAINERS.md
Normal file
54
MAINTAINERS.md
Normal file
@ -0,0 +1,54 @@
|
||||
This document will document some of the processes that members of the documentation team should adhere to.
|
||||
|
||||
# PR Process
|
||||
|
||||
1. Triage with the correct [label](#labels)
|
||||
2. If there a change related to it ensure it has been published and tested before closing
|
||||
|
||||
# Labels
|
||||
|
||||
| label name | purpose |
|
||||
|:--------------:|:------------|
|
||||
| accessibility | |
|
||||
| addon:(name) | |
|
||||
| app:(name) | |
|
||||
| api:(name) | |
|
||||
| cleanup | Minor cleanup style change that won't show up in release changelog |
|
||||
| bug | |
|
||||
| cli | |
|
||||
| good first review | |
|
||||
| compatibility with other tools | |
|
||||
| patch | Bugfix & documentation PR that need to be picked to release branch |
|
||||
| picked | Patch PRs cherry-picked to master |
|
||||
| compatibility with other tools | |
|
||||
| components | |
|
||||
| core | |
|
||||
| decorators | |
|
||||
| dependencies:update | |
|
||||
| dependencies | |
|
||||
| discussion | |
|
||||
| do not merge | |
|
||||
| documentation | |
|
||||
| feature request | |
|
||||
| good first issue | |
|
||||
| has workaround | |
|
||||
| help wanted | |
|
||||
| high priority | |
|
||||
| in progress | |
|
||||
| inactive | |
|
||||
| maintenance | |
|
||||
| merged | |
|
||||
| needs example | |
|
||||
| needs more info | |
|
||||
| needs rebase | |
|
||||
| needs reproduction | |
|
||||
| needs review | |
|
||||
| performance issue | |
|
||||
| presets | |
|
||||
| question / support | |
|
||||
| ready | |
|
||||
| security | |
|
||||
| todo | |
|
||||
| typescript | |
|
||||
| ui | |
|
||||
| won't fix | |
|
104
MIGRATION.md
104
MIGRATION.md
@ -3,12 +3,16 @@
|
||||
## Table of contents
|
||||
|
||||
- [From version 3.4.x to 4.0.x](#from-version-34x-to-40x)
|
||||
- [React 16.3](#react-163)
|
||||
- [Keyboard shortcuts moved](#keyboard-shortcuts-moved)
|
||||
- [Removed addWithInfo](#removed-add-with-info)
|
||||
- [Removed RN packager](#removed-rn-packager)
|
||||
- [Removed RN addons](#removed-rn-addons)
|
||||
- [Storyshots changes](#storyshots-changes)
|
||||
- [Webpack 4](#webpack-4)
|
||||
- [Babel 7](#babel-7)
|
||||
- [Create-react-app](#create-react-app)
|
||||
- [CLI rename](#cli-rename)
|
||||
- [From version 3.3.x to 3.4.x](#from-version-33x-to-34x)
|
||||
- [From version 3.2.x to 3.3.x](#from-version-32x-to-33x)
|
||||
- [Refactored Knobs](#refactored-knobs)
|
||||
@ -24,9 +28,35 @@
|
||||
- [Packages renaming](#packages-renaming)
|
||||
- [Deprecated embedded addons](#deprecated-embedded-addons)
|
||||
|
||||
## From 3.4.x to 4.0
|
||||
## From version 3.4.x to 4.0.x
|
||||
|
||||
With 4.0 as our first major release in over a year, we've collected a lot of cleanup tasks. All deprecations have been marked for months, so we hope that there will be no significant impact on your project.
|
||||
With 4.0 as our first major release in over a year, we've collected a lot of cleanup tasks. Most of the deprecations have been marked for months, so we hope that there will be no significant impact on your project.
|
||||
|
||||
### React 16.3+
|
||||
|
||||
Storybook uses [Emotion](https://emotion.sh/) for styling which currently requires React 16.3 and above.
|
||||
|
||||
If you're using Storybook for anything other than React, you probably don't need to worry about this.
|
||||
|
||||
However, if you're developing React components, this means you need to upgrade to 16.3 or higher to use Storybook 4.0.
|
||||
|
||||
> **NOTE:** This is a temporary requirement, and we plan to restore 15.x compatibility in a near-term 4.x release.
|
||||
|
||||
Also, here's the error you'll get if you're running an older version of React:
|
||||
|
||||
```
|
||||
core.browser.esm.js:15 Uncaught TypeError: Object(...) is not a function
|
||||
at Module../node_modules/@emotion/core/dist/core.browser.esm.js (core.browser.esm.js:15)
|
||||
at __webpack_require__ (bootstrap:724)
|
||||
at fn (bootstrap:101)
|
||||
at Module../node_modules/@emotion/styled-base/dist/styled-base.browser.esm.js (styled-base.browser.esm.js:1)
|
||||
at __webpack_require__ (bootstrap:724)
|
||||
at fn (bootstrap:101)
|
||||
at Module../node_modules/@emotion/styled/dist/styled.esm.js (styled.esm.js:1)
|
||||
at __webpack_require__ (bootstrap:724)
|
||||
at fn (bootstrap:101)
|
||||
at Object../node_modules/@storybook/components/dist/navigation/MenuLink.js (MenuLink.js:12)
|
||||
```
|
||||
|
||||
### Generic addons
|
||||
|
||||
@ -46,6 +76,12 @@ import { number } from "@storybook/addon-knobs";
|
||||
|
||||
4.0 also reversed the order of addon-knob's `select` knob keys/values, which had been called `selectV2` prior to this breaking change. See the knobs [package README](https://github.com/storybooks/storybook/blob/master/addons/knobs/README.md#select) for usage.
|
||||
|
||||
### Knobs URL parameters
|
||||
|
||||
Addon-knobs no longer updates the URL parameters interactively as you edit a knob. This is a UI change but it shouldn't break any code because old URLs are still supported.
|
||||
|
||||
In 3.x, editing knobs updated the URL parameters interactively. The implementation had performance and architectural problems. So in 4.0, we changed this to a "copy" button tp the addon which generates a URL with the updated knob values and copies it to the clipboard.
|
||||
|
||||
### Keyboard shortcuts moved
|
||||
|
||||
- Addon Panel to `Z`
|
||||
@ -57,6 +93,14 @@ import { number } from "@storybook/addon-knobs";
|
||||
|
||||
`Addon-info`'s `addWithInfo` has been marked deprecated since 3.2. In 4.0 we've removed it completely. See the package [README](https://github.com/storybooks/storybook/blob/master/addons/info/README.md) for the proper usage.
|
||||
|
||||
### Removed RN packager
|
||||
|
||||
Since storybook version v4.0 packager is removed from storybook. The suggested storybook usage is to include it inside your app.
|
||||
If you want to keep the old behaviour, you have to start the packager yourself with a different project root.
|
||||
`npm run storybook start -p 7007 | react-native start --projectRoot storybook`
|
||||
|
||||
Removed cli options: `--packager-port --root --projectRoots -r, --reset-cache --skip-packager --haul --platform --metro-config`
|
||||
|
||||
### Removed RN addons
|
||||
|
||||
The `@storybook/react-native` had built-in addons (`addon-actions` and `addon-links`) that have been marked as deprecated since 3.x. They have been fully removed in 4.x. If your project still uses the built-ins, you'll need to add explicit dependencies on `@storybook/addon-actions` and/or `@storybook/addon-links` and import directly from those packages.
|
||||
@ -82,11 +126,55 @@ Storybook now uses webpack 4. If you have a [custom webpack config](https://stor
|
||||
|
||||
Storybook now uses Babel 7. There's a couple of cases when it can break with your app:
|
||||
|
||||
* If you aren't using Babel yourself, and don't have .babelrc, install following dependencies:
|
||||
```
|
||||
npm i -D @babel/core babel-loader@next
|
||||
```
|
||||
* If you're using Babel 6, make sure that you have direct dependencies on `babel-core@6` and `babel-loader@7`.
|
||||
- If you aren't using Babel yourself, and don't have .babelrc, install following dependencies:
|
||||
```
|
||||
npm i -D @babel/core babel-loader@next
|
||||
```
|
||||
- If you're using Babel 6, make sure that you have direct dependencies on `babel-core@6` and `babel-loader@7` and that you have a `.babelrc` in your project directory.
|
||||
|
||||
### Create-react-app
|
||||
|
||||
If you are using `create-react-app` (aka CRA), you may need to do some manual steps to upgrade, depending on the setup.
|
||||
|
||||
- `create-react-app@1` may require manual migrations.
|
||||
- If you're adding storybook for the first time, it should just work: `sb init` should add the correct dependencies.
|
||||
- If you've upgrading an existing project, your `package.json` probably already uses Babel 6, making it incompatible with `@storybook/react@4` which uses Babel 7. There are two ways to make it compatible, each of which is spelled out in detail in the next section:
|
||||
- Upgrade to Babel 7 if you are not dependent on Babel 6-specific features.
|
||||
- Migrate Babel 6 if you're heavily dependent on some Babel 6-specific features).
|
||||
- `create-react-app@2` should be compatible as is, since it uses babel 7.
|
||||
|
||||
#### Upgrade CRA1 to babel 7
|
||||
|
||||
```
|
||||
yarn remove babel-core babel-runtime
|
||||
yarn add @babel/core babel-loader --dev
|
||||
```
|
||||
|
||||
#### Migrate CRA1 while keeping babel 6
|
||||
|
||||
```
|
||||
yarn add babel-loader@7
|
||||
```
|
||||
|
||||
Also make sure you have a `.babelrc` in your project directory. You probably already do if you are using Babel 6 features (otherwise you should consider upgrading to Babel 7 instead). If you don't have one, here's a simple one that works:
|
||||
|
||||
```json
|
||||
{
|
||||
"presets": ["env", "react"]
|
||||
}
|
||||
```
|
||||
|
||||
### start-storybook opens browser automatically
|
||||
|
||||
If you're using `start-storybook` on CI, you may need to opt out of this using the new `--ci` flag.
|
||||
|
||||
### CLI Rename
|
||||
|
||||
We've deprecated the `getstorybook` CLI in 4.0. The new way to install storybook is `sb init`. We recommend using `npx` for convenience and to make sure you're always using the latest version of the CLI:
|
||||
|
||||
```
|
||||
npx -p @storybook/cli@rc sb init
|
||||
```
|
||||
|
||||
## From version 3.3.x to 3.4.x
|
||||
|
||||
@ -203,7 +291,7 @@ To update your app to use the new package names, you can use the cli:
|
||||
npm install --global @storybook/cli
|
||||
|
||||
# if you run this inside a v2 app, it should perform the necessary codemods.
|
||||
getstorybook
|
||||
storybook init
|
||||
```
|
||||
|
||||
#### Details
|
||||
|
153
README.md
153
README.md
@ -10,21 +10,24 @@
|
||||
[](#backers)
|
||||
[](#sponsors)
|
||||
[](https://github.com/storybooks/storybook/blob/master/LICENSE)
|
||||
|
||||
<!-- [](https://www.browserstack.com/automate/public-build/<badge_key>) -->
|
||||
|
||||
* * *
|
||||
---
|
||||
|
||||
Storybook is a development environment for UI components.
|
||||
It allows you to browse a component library, view the different states of each component, and interactively develop and test components.
|
||||
|
||||
## Intro
|
||||
|
||||

|
||||
<center>
|
||||
<img src="media/storybook-intro.gif" width="100%" />
|
||||
</center>
|
||||
|
||||
README for:
|
||||
- [](https://github.com/storybooks/storybook)
|
||||
- [](https://github.com/storybooks/storybook/tree/release/3.4)
|
||||
|
||||
- [](https://github.com/storybooks/storybook)
|
||||
- [](https://github.com/storybooks/storybook/tree/release/3.4)
|
||||
|
||||
Storybook runs outside of your app. This allows you to develop UI components in isolation, which can improve component reuse, testability, and development speed. You can build quickly without having to worry about application-specific dependencies.
|
||||
|
||||
@ -34,38 +37,36 @@ Storybook comes with a lot of [addons](https://storybook.js.org/addons/introduct
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Getting Started](#getting-started)
|
||||
- [Projects](#projects)
|
||||
- [Supported Frameworks](#supported-frameworks)
|
||||
- [Sub Projects](#sub-projects)
|
||||
- [Addons](#addons)
|
||||
- [Live Examples](#live-examples) 💪
|
||||
- [Badges](#badges)
|
||||
- [Contributing](#contributing)
|
||||
- [Development scripts](#development-scripts)
|
||||
- [Backers](#backers)
|
||||
- [Sponsors](#sponsors)
|
||||
- 🚀[Getting Started](#getting-started)
|
||||
- 📒[Projects](#projects)
|
||||
- 🛠[Supported Frameworks & Examples](#supported-frameworks)
|
||||
- 🚇[Sub Projects](#sub-projects)
|
||||
- 🔗[Addons](#addons)
|
||||
- 🏅[Badges & Presentation materials](#badges--presentation-materials)
|
||||
- 👥[Community](#community)
|
||||
- 👏[Contributing](#contributing)
|
||||
- 👨💻[Development scripts](#development-scripts)
|
||||
- 💵[Backers](#backers)
|
||||
- 💸[Sponsors](#sponsors)
|
||||
|
||||
## Getting Started
|
||||
|
||||
First install storybook:
|
||||
|
||||
```sh
|
||||
npm i -g @storybook/cli
|
||||
cd my-react-app
|
||||
getstorybook
|
||||
npx -p @storybook/cli@rc sb init
|
||||
```
|
||||
|
||||
The `-g` global install is used to run our cli tool in your project directory to generate templates for your existing projects. To avoid the global install and start your project manually, take a look at our [Slow Start Guide](https://storybook.js.org/basics/slow-start-guide/).
|
||||
If you'd rather set up your project manually, take a look at our [Slow Start Guide](https://storybook.js.org/basics/slow-start-guide/).
|
||||
|
||||
Once it's installed, you can `npm run storybook` and it will run the development server on your local machine, and give you a URL to browse some sample stories.
|
||||
|
||||
**Storybook v2.x migration note**: If you're using Storybook v2.x and want to shift to 3.x version the easiest way is:
|
||||
**Storybook v2.x migration note**: If you're using Storybook v2.x and want to shift to 4.x version the easiest way is:
|
||||
|
||||
```sh
|
||||
npm i -g @storybook/cli
|
||||
cd my-storybook-v2-app
|
||||
getstorybook
|
||||
npx -p @storybook/cli@rc sb init
|
||||
```
|
||||
|
||||
It runs a codemod to update all package names. Read all migration details in our [Migration Guide](MIGRATION.md)
|
||||
@ -78,69 +79,49 @@ For additional help, join us [in our Slack](https://now-examples-slackin-rrirkqo
|
||||
|
||||
### Supported Frameworks
|
||||
|
||||
- [React](app/react) [](app/react)
|
||||
- [React Native](app/react-native) [](app/react-native)
|
||||
- [Vue](app/vue) [](app/vue)
|
||||
- [Angular](app/angular) [](app/angular)
|
||||
- [Polymer](app/polymer) [](app/polymer)
|
||||
- [Mithril](app/mithril) <sup>alpha</sup> [](app/mithril)
|
||||
- [Marko](app/marko) <sup>alpha</sup> [](app/marko)
|
||||
- [HTML](app/html) <sup>alpha</sup> [](app/html)
|
||||
- [Svelte](app/svelte) <sup>alpha</sup> [](app/svelte)
|
||||
- [Riot](app/riot) <sup>alpha</sup> [](app/riot)
|
||||
| Framework | Demo latest | Demo prerelease | |
|
||||
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
||||
| [React](app/react) | [v3.4.x](https://release-3-4--storybooks-official.netlify.com), [v3.3.x](https://release-3-3--storybooks-official.netlify.com) | [v4.0.0-alpha](https://storybooks-official.netlify.com) | [](app/react) |
|
||||
| [React Native](app/react-native) | - | - | [](app/react-native) |
|
||||
| [Vue](app/vue) | [v3.4.x](https://release-3-4--storybooks-vue.netlify.com/), [v3.3.x](https://release-3-3--storybooks-vue.netlify.com/) | [v4.0.0-alpha](https://storybooks-vue.netlify.com/) | [](app/vue) |
|
||||
| [Angular](app/angular) | [v3.4.x](https://release-3-4--storybooks-angular.netlify.com/), [v3.3.x](https://release-3-3--storybooks-angular.netlify.com/) | [v4.0.0-alpha](https://storybooks-angular.netlify.com/) | [](app/angular) |
|
||||
| [Polymer](app/polymer) | [v3.4.x](https://release-3-4--storybooks-polymer.netlify.com/) | [v4.0.0-alpha](https://storybooks-polymer.netlify.com/) | [](app/polymer) |
|
||||
| [Mithril](app/mithril) <sup>alpha</sup> | - | [v4.0.0-alpha](https://storybooks-mithril.netlify.com/) | [](app/mithril) |
|
||||
| [Marko](app/marko) <sup>alpha</sup> | - | [v4.0.0-alpha](https://storybooks-marko.netlify.com/) | [](app/marko) |
|
||||
| [HTML](app/html) <sup>alpha</sup> | - | [v4.0.0-alpha](https://storybooks-html.netlify.com/) | [](app/html) |
|
||||
| [Svelte](app/svelte) <sup>alpha</sup> | - | [v4.0.0-alpha](https://storybooks-svelte.netlify.com/) | [](app/svelte) |
|
||||
| [Riot](app/riot) <sup>alpha</sup> | - | [v4.0.0-alpha](https://storybooks-riot.netlify.com/) | [](app/riot) |
|
||||
| [Ember](app/ember) <sup>alpha</sup> | - | [v4.0.0-alpha](https://storybooks-ember.netlify.com/) | [](app/ember) |
|
||||
|
||||
### Sub Projects
|
||||
|
||||
- [CLI](lib/cli) - Streamlined installation for a variety of app types
|
||||
- [examples](examples) - Code examples to illustrate different Storybook use cases
|
||||
- [CLI](lib/cli) - Streamlined installation for a variety of app types
|
||||
- [examples](examples) - Code examples to illustrate different Storybook use cases
|
||||
|
||||
### Addons
|
||||
|
||||
- [a11y](addons/a11y/) - Test components for user accessibility in Storybook
|
||||
- [actions](addons/actions/) - Log actions as users interact with components in the Storybook UI
|
||||
- [backgrounds](addons/backgrounds/) - Let users choose backgrounds in the Storybook UI
|
||||
- [centered](addons/centered/) - Center the alignment of your components within the Storybook UI
|
||||
- [events](addons/events/) - Interactively fire events to components that respond to EventEmitter
|
||||
- [graphql](addons/graphql/) - Query a GraphQL server within Storybook stories
|
||||
- [info](addons/info/) - Annotate stories with extra component usage information
|
||||
- [jest](addons/jest/) - View the results of components' unit tests in Storybook
|
||||
- [knobs](addons/knobs/) - Interactively edit component prop data in the Storybook UI
|
||||
- [links](addons/links/) - Create links between stories
|
||||
- [notes](addons/notes/) - Annotate Storybook stories with notes
|
||||
- [options](addons/options/) - Customize the Storybook UI in code
|
||||
- [storyshots](addons/storyshots/) - Easy snapshot testing for components in Storybook
|
||||
- [storysource](addons/storysource/) - View the code of your stories within the Storybook UI
|
||||
- [viewport](addons/viewport/) - Change display sizes and layouts for responsive components using Storybook
|
||||
| Addons | |
|
||||
| ------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| [a11y](addons/a11y/) | Test components for user accessibility in Storybook |
|
||||
| [actions](addons/actions/) | Log actions as users interact with components in the Storybook UI |
|
||||
| [backgrounds](addons/backgrounds/) | Let users choose backgrounds in the Storybook UI |
|
||||
| [centered](addons/centered/) | Center the alignment of your components within the Storybook UI |
|
||||
| [events](addons/events/) | Interactively fire events to components that respond to EventEmitter |
|
||||
| [graphql](addons/graphql/) | Query a GraphQL server within Storybook stories |
|
||||
| [google-analytics](addons/google-analytics) | Reports google analytics on stories |
|
||||
| [info](addons/info/) | Annotate stories with extra component usage information |
|
||||
| [jest](addons/jest/) | View the results of components' unit tests in Storybook |
|
||||
| [knobs](addons/knobs/) | Interactively edit component prop data in the Storybook UI |
|
||||
| [links](addons/links/) | Create links between stories |
|
||||
| [notes](addons/notes/) | Annotate Storybook stories with notes |
|
||||
| [options](addons/options/) | Customize the Storybook UI in code |
|
||||
| [storyshots](addons/storyshots/) | Easy snapshot testing for components in Storybook |
|
||||
| [storysource](addons/storysource/) | View the code of your stories within the Storybook UI |
|
||||
| [viewport](addons/viewport/) | Change display sizes and layouts for responsive components using Storybook |
|
||||
|
||||
See [Addon / Framework Support Table](ADDONS_SUPPORT.md)
|
||||
|
||||
## Live Examples
|
||||
|
||||
### 4.0.alpha
|
||||
> Note, this is an Alpha version which may not be well tested. Features in this version are not final.
|
||||
|
||||
- [React Official](https://storybooks-official.netlify.com)
|
||||
- [Vue](https://storybooks-vue.netlify.com/)
|
||||
- [Angular](https://storybooks-angular.netlify.com/)
|
||||
- [Polymer](https://storybooks-polymer.netlify.com/)
|
||||
- [Mithril](https://storybooks-mithril.netlify.com/)
|
||||
- [Marko](https://storybooks-marko.netlify.com/)
|
||||
- [HTML](https://storybooks-html.netlify.com/)
|
||||
- [Svelte](https://storybooks-svelte.netlify.com/)
|
||||
- [Riot](https://storybooks-riot.netlify.com/)
|
||||
|
||||
### 3.4
|
||||
- [React Official](https://release-3-4--storybooks-official.netlify.com)
|
||||
- [Vue](https://release-3-4--storybooks-vue.netlify.com/)
|
||||
- [Angular](https://release-3-4--storybooks-angular.netlify.com/)
|
||||
- [Polymer](https://release-3-4--storybooks-polymer.netlify.com/)
|
||||
|
||||
### 3.3
|
||||
- [React Official](https://release-3-3--storybooks-official.netlify.com)
|
||||
- [Vue](https://release-3-3--storybooks-vue.netlify.com/)
|
||||
- [Angular](https://release-3-3--storybooks-angular.netlify.com/)
|
||||
|
||||
## Badges
|
||||
## Badges & Presentation materials
|
||||
|
||||
We have a badge ! Link it to your live Storybook example.
|
||||
|
||||
@ -150,14 +131,24 @@ We have a badge ! Link it to your live Storybook example.
|
||||
[](link to site)
|
||||
```
|
||||
|
||||
If you're looking for material to use in your presentation about storybook, like logo's video material and the colors we use etc, you can find all of that at our [press repo](https://github.com/storybooks/press).
|
||||
|
||||
## Community
|
||||
|
||||
- Tweeting via [@storybookjs](https://twitter.com/storybookjs)
|
||||
- Blogging at [Medium](https://medium.com/storybookjs)
|
||||
- Chatting on [Slack](https://now-examples-slackin-rrirkqohko.now.sh/)
|
||||
- Discussions on [Discord](https://discord.gg/sMFvFsG)
|
||||
- Streaming saved at [Youtube](https://www.youtube.com/channel/UCr7Quur3eIyA_oe8FNYexfg)
|
||||
|
||||
## Contributing
|
||||
|
||||
[](https://github.com/storybooks/storybook/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
|
||||
|
||||
We welcome contributions to Storybook!
|
||||
|
||||
- ⇄ Pull requests and ★ Stars are always welcome.
|
||||
- Read our [contributing guide](CONTRIBUTING.md) to get started.
|
||||
- ⇄ Pull requests and ★ Stars are always welcome.
|
||||
- Read our [contributing guide](CONTRIBUTING.md) to get started.
|
||||
|
||||
### Development scripts
|
||||
|
||||
@ -174,16 +165,16 @@ We welcome contributions to Storybook!
|
||||
|
||||
> boolean check if code conforms to linting rules - uses remark & eslint
|
||||
|
||||
- `yarn lint:js` - will check js
|
||||
- `yarn lint:md` - will check markdown + code samples
|
||||
- `yarn lint:js` - will check js
|
||||
- `yarn lint:md` - will check markdown + code samples
|
||||
|
||||
- `yarn lint:js --fix` - will automatically fix js
|
||||
- `yarn lint:js --fix` - will automatically fix js
|
||||
|
||||
#### `yarn test`
|
||||
|
||||
> boolean check if unit tests all pass - uses jest
|
||||
|
||||
- `yarn run test --core --watch` - will run core tests in watch-mode
|
||||
- `yarn run test --core --watch` - will run core tests in watch-mode
|
||||
|
||||
### Sponsors
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
* [Supporting other frameworks and libraries](#supporting-other-frameworks-and-libraries)
|
||||
+ [Polymer & Webcomponents](#polymer---webcomponents)
|
||||
+ [Aurelia](#aurelia)
|
||||
+ [Ember](#ember)
|
||||
* [Breaking changes](#breaking-changes)
|
||||
+ [Addon API](#addon-api)
|
||||
+ [API for adding stories](#api-for-adding-stories)
|
||||
@ -69,10 +68,6 @@ Storybook for Polymer is currently in development, and will support custom eleme
|
||||
|
||||
We're reaching out to the Aurelia maintainers to cooperate on this.
|
||||
|
||||
### Ember
|
||||
|
||||
We're reaching out to the Ember maintainers to cooperate on this.
|
||||
|
||||
## Breaking changes
|
||||
|
||||
### Addon API
|
||||
@ -92,7 +87,7 @@ We have a new logo, so next step is a overhaul of our documentation site.
|
||||
|
||||
### Record videos and write blog post on how to use, tweak & develop storybook
|
||||
|
||||
- writing addons,
|
||||
- writing addons,
|
||||
- choosing the right addons.
|
||||
- how to start developing on our codebase.
|
||||
- how to use storybook itself and the CLI.
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-a11y",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "a11y addon for storybook",
|
||||
"keywords": [
|
||||
"a11y",
|
||||
@ -11,6 +11,9 @@
|
||||
"verify"
|
||||
],
|
||||
"homepage": "https://github.com/storybooks/storybook#readme",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
@ -25,12 +28,12 @@
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/styled": "0.10.5",
|
||||
"@storybook/addons": "4.0.0-alpha.21",
|
||||
"@storybook/client-logger": "4.0.0-alpha.21",
|
||||
"@storybook/components": "4.0.0-alpha.21",
|
||||
"@storybook/core-events": "4.0.0-alpha.21",
|
||||
"axe-core": "^3.0.3",
|
||||
"@emotion/styled": "^0.10.6",
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"@storybook/client-logger": "4.0.0-rc.1",
|
||||
"@storybook/components": "4.0.0-rc.1",
|
||||
"@storybook/core-events": "4.0.0-rc.1",
|
||||
"axe-core": "^3.1.2",
|
||||
"global": "^4.3.2",
|
||||
"prop-types": "^15.6.2"
|
||||
},
|
||||
|
@ -19,6 +19,12 @@ const Violations = styled.span(({ theme }) => ({
|
||||
color: theme.failColor,
|
||||
}));
|
||||
|
||||
const PanelWrapper = styled.div({
|
||||
height: '100%',
|
||||
overflow: 'auto',
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
class Panel extends Component {
|
||||
static propTypes = {
|
||||
active: PropTypes.bool.isRequired,
|
||||
@ -78,7 +84,7 @@ class Panel extends Component {
|
||||
const { active } = this.props;
|
||||
|
||||
return active ? (
|
||||
<div>
|
||||
<PanelWrapper>
|
||||
<Tabs
|
||||
tabs={[
|
||||
{
|
||||
@ -94,7 +100,7 @@ class Panel extends Component {
|
||||
<ActionBar>
|
||||
<ActionButton onClick={this.requestCheck}>RERUN TEST</ActionButton>
|
||||
</ActionBar>
|
||||
</div>
|
||||
</PanelWrapper>
|
||||
) : null;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
{
|
||||
"name": "@storybook/addon-actions",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "Action Logger addon for storybook",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
],
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/actions",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
@ -20,15 +23,15 @@
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/core": "^0.13.0",
|
||||
"@emotion/provider": "0.11.1",
|
||||
"@emotion/styled": "0.10.5",
|
||||
"@storybook/addons": "4.0.0-alpha.21",
|
||||
"@storybook/components": "4.0.0-alpha.21",
|
||||
"@storybook/core-events": "4.0.0-alpha.21",
|
||||
"@emotion/core": "^0.13.1",
|
||||
"@emotion/provider": "^0.11.2",
|
||||
"@emotion/styled": "^0.10.6",
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"@storybook/components": "4.0.0-rc.1",
|
||||
"@storybook/core-events": "4.0.0-rc.1",
|
||||
"deep-equal": "^1.0.1",
|
||||
"global": "^4.3.2",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"lodash": "^4.17.11",
|
||||
"make-error": "^1.3.5",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-inspector": "^2.3.0",
|
||||
|
@ -38,5 +38,5 @@ export const Wrapper = styled.div({
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
position: 'relative',
|
||||
minHeight: '100%',
|
||||
height: '100%',
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Based on http://backbonejs.org/docs/backbone.html#section-164
|
||||
import { document, Element } from 'global';
|
||||
import isEqual from 'lodash.isequal';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import addons from '@storybook/addons';
|
||||
import Events from '@storybook/core-events';
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-backgrounds",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "A storybook addon to show different backgrounds for your preview",
|
||||
"keywords": [
|
||||
"addon",
|
||||
@ -8,7 +8,10 @@
|
||||
"react",
|
||||
"storybook"
|
||||
],
|
||||
"homepage": "https://storybook.js.org",
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/backgrounds",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
@ -24,16 +27,13 @@
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/styled": "0.10.5",
|
||||
"@storybook/addons": "4.0.0-alpha.21",
|
||||
"@storybook/core-events": "4.0.0-alpha.21",
|
||||
"@emotion/styled": "^0.10.6",
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"@storybook/core-events": "4.0.0-rc.1",
|
||||
"global": "^4.3.2",
|
||||
"prop-types": "^15.6.2",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vue": "^2.5.17"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
|
1
addons/centered/ember.js
Normal file
1
addons/centered/ember.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('./dist/ember');
|
@ -1,7 +1,22 @@
|
||||
{
|
||||
"name": "@storybook/addon-centered",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "Storybook decorator to center components",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"storybook"
|
||||
],
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/centered",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/storybooks/storybook.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": "Muhammed Thanish <mnmtanish@gmail.com>",
|
||||
"main": "dist/index.js",
|
||||
|
25
addons/centered/src/ember.js
Normal file
25
addons/centered/src/ember.js
Normal file
@ -0,0 +1,25 @@
|
||||
import { document } from 'global';
|
||||
import styles from './styles';
|
||||
|
||||
export default function(storyFn) {
|
||||
const { template, context } = storyFn();
|
||||
|
||||
const element = document.createElement('div');
|
||||
Object.assign(element.style, styles.style);
|
||||
|
||||
const innerElement = document.createElement('div');
|
||||
Object.assign(innerElement.style, styles.innerStyle);
|
||||
|
||||
element.appendChild(innerElement);
|
||||
|
||||
// the inner element should append the parent
|
||||
innerElement.appendTo = function appendTo(el) {
|
||||
el.appendChild(element);
|
||||
};
|
||||
|
||||
return {
|
||||
template,
|
||||
context,
|
||||
element: innerElement,
|
||||
};
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-events",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "Add events to your Storybook stories.",
|
||||
"keywords": [
|
||||
"addon",
|
||||
@ -8,9 +8,16 @@
|
||||
"react",
|
||||
"storybook"
|
||||
],
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/events",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:storybooks/storybook.git"
|
||||
"url": "https://github.com/storybooks/storybook.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
@ -19,9 +26,9 @@
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/styled": "0.10.5",
|
||||
"@storybook/addons": "4.0.0-alpha.21",
|
||||
"@storybook/core-events": "4.0.0-alpha.21",
|
||||
"@emotion/styled": "^0.10.6",
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"@storybook/core-events": "4.0.0-rc.1",
|
||||
"format-json": "^1.0.3",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-lifecycles-compat": "^3.0.4",
|
||||
|
25
addons/google-analytics/README.md
Normal file
25
addons/google-analytics/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Storybook Addon Google Analytics
|
||||
|
||||
Storybook Addon Google Analytics can be used to support google analytics in [Storybook](https://storybook.js.org).
|
||||
|
||||
[Framework Support](https://github.com/storybooks/storybook/blob/master/ADDONS_SUPPORT.md)
|
||||
|
||||
## Getting Started
|
||||
|
||||
Install:
|
||||
|
||||
```sh
|
||||
npm i -D @storybook/addon-google-analytics
|
||||
```
|
||||
|
||||
Then, add following content to `.storybook/addons.js`
|
||||
|
||||
```js
|
||||
import '@storybook/addon-google-analytics/register';
|
||||
```
|
||||
|
||||
Then, set an environment variable
|
||||
|
||||
```
|
||||
window.STORYBOOK_GA_ID = UA-000000-01
|
||||
```
|
31
addons/google-analytics/package.json
Normal file
31
addons/google-analytics/package.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "@storybook/addon-google-analytics",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "Storybook addon for google analytics",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"storybook"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/google-analytics",
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/storybooks/storybook.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
"scripts": {
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"global": "^4.3.2",
|
||||
"react-ga": "^2.5.3"
|
||||
}
|
||||
}
|
1
addons/google-analytics/src/index.js
Normal file
1
addons/google-analytics/src/index.js
Normal file
@ -0,0 +1 @@
|
||||
export default {};
|
17
addons/google-analytics/src/register.js
Normal file
17
addons/google-analytics/src/register.js
Normal file
@ -0,0 +1,17 @@
|
||||
import addons from '@storybook/addons';
|
||||
import { window } from 'global';
|
||||
import ReactGA from 'react-ga';
|
||||
|
||||
addons.register('storybook/google-analytics', api => {
|
||||
ReactGA.initialize(window.STORYBOOK_GA_ID);
|
||||
|
||||
api.onStory((kind, story) => {
|
||||
let path = window.location.pathname;
|
||||
|
||||
if (path === '/') {
|
||||
path = '';
|
||||
}
|
||||
|
||||
ReactGA.pageview(`${path}/${kind}/${story}`);
|
||||
});
|
||||
});
|
@ -1,11 +1,15 @@
|
||||
{
|
||||
"name": "@storybook/addon-graphql",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "Storybook addon to display the GraphiQL IDE",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"storybook"
|
||||
],
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/graphql",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
@ -21,8 +25,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"global": "^4.3.2",
|
||||
"graphiql": "^0.11.11",
|
||||
"graphql": "^0.13.2",
|
||||
"graphiql": "^0.12.0",
|
||||
"graphql": "^14.0.2",
|
||||
"prop-types": "^15.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@ -1,7 +1,18 @@
|
||||
{
|
||||
"name": "@storybook/addon-info",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "A Storybook addon to show additional information for your stories.",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"storybook"
|
||||
],
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/info",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/storybooks/storybook.git"
|
||||
@ -13,13 +24,13 @@
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/styled": "0.10.5",
|
||||
"@storybook/addons": "4.0.0-alpha.21",
|
||||
"@storybook/client-logger": "4.0.0-alpha.21",
|
||||
"@storybook/components": "4.0.0-alpha.21",
|
||||
"@emotion/styled": "^0.10.6",
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"@storybook/client-logger": "4.0.0-rc.1",
|
||||
"@storybook/components": "4.0.0-rc.1",
|
||||
"core-js": "2.5.7",
|
||||
"global": "^4.3.2",
|
||||
"marksy": "^6.0.3",
|
||||
"marksy": "^6.1.0",
|
||||
"nested-object-assign": "^1.0.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-addons-create-fragment": "^15.5.3",
|
||||
@ -27,7 +38,7 @@
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react-test-renderer": "^16.4.2"
|
||||
"react-test-renderer": "^16.5.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
|
@ -1,6 +1,63 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`addon Info should render <Info /> and external markdown 1`] = `
|
||||
.emotion-4 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
justify-content: space-between;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
font-size: .88em;
|
||||
font-family: Menlo,Monaco,"Courier New",monospace;
|
||||
background-color: #fafafa;
|
||||
padding: .5rem;
|
||||
line-height: 1.5;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.emotion-2 {
|
||||
overflow: hidden;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 3px;
|
||||
background-color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
padding: 3px 10px;
|
||||
-webkit-align-self: flex-start;
|
||||
-ms-flex-item-align: start;
|
||||
align-self: flex-start;
|
||||
-webkit-flex-shrink: 0;
|
||||
-ms-flex-negative: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.emotion-2:hover {
|
||||
background-color: #f4f7fa;
|
||||
border-color: #ddd;
|
||||
}
|
||||
|
||||
.emotion-2:active {
|
||||
background-color: #e9ecef;
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
.emotion-0 {
|
||||
-webkit-transition: -webkit-transform .2s ease;
|
||||
-webkit-transition: transform .2s ease;
|
||||
transition: transform .2s ease;
|
||||
height: 16px;
|
||||
-webkit-transform: translateY(-100%) translateY(-6px);
|
||||
-ms-transform: translateY(-100%) translateY(-6px);
|
||||
transform: translateY(-100%) translateY(-6px);
|
||||
}
|
||||
|
||||
<deprecated>
|
||||
<Story
|
||||
PropTable={[Function]}
|
||||
@ -1262,6 +1319,63 @@ exports[`addon Info should render <Info /> and external markdown 1`] = `
|
||||
`;
|
||||
|
||||
exports[`addon Info should render <Info /> and markdown 1`] = `
|
||||
.emotion-4 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
justify-content: space-between;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
font-size: .88em;
|
||||
font-family: Menlo,Monaco,"Courier New",monospace;
|
||||
background-color: #fafafa;
|
||||
padding: .5rem;
|
||||
line-height: 1.5;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.emotion-2 {
|
||||
overflow: hidden;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 3px;
|
||||
background-color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
padding: 3px 10px;
|
||||
-webkit-align-self: flex-start;
|
||||
-ms-flex-item-align: start;
|
||||
align-self: flex-start;
|
||||
-webkit-flex-shrink: 0;
|
||||
-ms-flex-negative: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.emotion-2:hover {
|
||||
background-color: #f4f7fa;
|
||||
border-color: #ddd;
|
||||
}
|
||||
|
||||
.emotion-2:active {
|
||||
background-color: #e9ecef;
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
.emotion-0 {
|
||||
-webkit-transition: -webkit-transform .2s ease;
|
||||
-webkit-transition: transform .2s ease;
|
||||
transition: transform .2s ease;
|
||||
height: 16px;
|
||||
-webkit-transform: translateY(-100%) translateY(-6px);
|
||||
-ms-transform: translateY(-100%) translateY(-6px);
|
||||
transform: translateY(-100%) translateY(-6px);
|
||||
}
|
||||
|
||||
<deprecated>
|
||||
<Story
|
||||
PropTable={[Function]}
|
||||
|
@ -26,47 +26,47 @@ Array [
|
||||
`;
|
||||
|
||||
exports[`PropTable multiLineText should include all propTypes by default 1`] = `
|
||||
<ForwardRef>
|
||||
<Table>
|
||||
<thead>
|
||||
<tr>
|
||||
<ForwardRef
|
||||
<Th
|
||||
bordered={true}
|
||||
>
|
||||
property
|
||||
</ForwardRef>
|
||||
<ForwardRef
|
||||
</Th>
|
||||
<Th
|
||||
bordered={true}
|
||||
>
|
||||
propType
|
||||
</ForwardRef>
|
||||
<ForwardRef
|
||||
</Th>
|
||||
<Th
|
||||
bordered={true}
|
||||
>
|
||||
required
|
||||
</ForwardRef>
|
||||
<ForwardRef
|
||||
</Th>
|
||||
<Th
|
||||
bordered={true}
|
||||
>
|
||||
default
|
||||
</ForwardRef>
|
||||
<ForwardRef
|
||||
</Th>
|
||||
<Th
|
||||
bordered={true}
|
||||
>
|
||||
description
|
||||
</ForwardRef>
|
||||
</Th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
key="foo"
|
||||
>
|
||||
<ForwardRef
|
||||
<Td
|
||||
bordered={true}
|
||||
code={true}
|
||||
>
|
||||
foo
|
||||
</ForwardRef>
|
||||
<ForwardRef
|
||||
</Td>
|
||||
<Td
|
||||
bordered={true}
|
||||
code={true}
|
||||
>
|
||||
@ -78,21 +78,21 @@ exports[`PropTable multiLineText should include all propTypes by default 1`] = `
|
||||
}
|
||||
}
|
||||
/>
|
||||
</ForwardRef>
|
||||
<ForwardRef
|
||||
</Td>
|
||||
<Td
|
||||
bordered={true}
|
||||
>
|
||||
-
|
||||
</ForwardRef>
|
||||
<ForwardRef
|
||||
</Td>
|
||||
<Td
|
||||
bordered={true}
|
||||
>
|
||||
-
|
||||
</ForwardRef>
|
||||
<ForwardRef
|
||||
</Td>
|
||||
<Td
|
||||
bordered={true}
|
||||
/>
|
||||
</tr>
|
||||
</tbody>
|
||||
</ForwardRef>
|
||||
</Table>
|
||||
`;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
|
||||
/* eslint-disable no-underscore-dangle,react/forbid-foreign-prop-types */
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
|
@ -42,7 +42,7 @@ but this can mean you'll experience merge conflicts on this file in the future.
|
||||
|
||||
## Generating the test results
|
||||
|
||||
You need to make sure the generated test-restuls file exists before you start storybook.
|
||||
You need to make sure the generated test-results file exists before you start storybook.
|
||||
During development you will likely start jest in watch-mode
|
||||
and so the json file will be re-generated every time code or tests change.
|
||||
|
||||
@ -52,7 +52,7 @@ npm run test:generate-output -- --watch
|
||||
|
||||
This change will then be HMR (hot module reloaded) using webpack and displayed by this addon.
|
||||
|
||||
If you want to pre-run jest automaticly during development or a static build,
|
||||
If you want to pre-run jest automatically during development or a static build,
|
||||
you may need to consider that if your tests fail, the script receives a non-0 exit code and will exit.
|
||||
You could create a `prebuild:storybook` npm script, which will never fail by appending `|| true`:
|
||||
|
||||
@ -77,7 +77,7 @@ import '@storybook/addon-jest/register';
|
||||
|
||||
## Usage
|
||||
|
||||
Assuming that you have created a test files `MyComponent.test.js` and `MyOtherComponent.test.js`
|
||||
Assuming that you have created test files `MyComponent.test.js` and `MyOtherComponent.test.js`
|
||||
|
||||
In your `story.js`
|
||||
|
||||
@ -136,15 +136,15 @@ storiesOf('MyComponent', module).add('Story', () => <div>Jest results disabled h
|
||||
### withTests(options)
|
||||
|
||||
- **options.results**: OBJECT jest output results. _mandatory_
|
||||
- **filesExt**: STRING test file extention. _optional_. This allow you to write "MyComponent" and not "MyComponent.test.js". It will be used as regex to find your file results. Default value is `((\\.specs?)|(\\.tests?))?(\\.js)?$`. That mean it will match: MyComponent.js, MyComponent.test.js, MyComponent.tests.js, MyComponent.spec.js, MyComponent.specs.js...
|
||||
- **filesExt**: STRING test file extension. _optional_. This allows you to write "MyComponent" and not "MyComponent.test.js". It will be used as regex to find your file results. Default value is `((\\.specs?)|(\\.tests?))?(\\.js)?$`. That means it will match: MyComponent.js, MyComponent.test.js, MyComponent.tests.js, MyComponent.spec.js, MyComponent.specs.js...
|
||||
|
||||
## Usage with Angular
|
||||
|
||||
Assuming that you have created a test files `my.component.spec.ts` and `my-other.comonent.spec.ts`
|
||||
Assuming that you have created test files `my.component.spec.ts` and `my-other.comonent.spec.ts`
|
||||
|
||||
Configure Jest with [jest-preset-angular](https://www.npmjs.com/package/jest-preset-angular)
|
||||
|
||||
In project`s`typings.d.ts` add
|
||||
In project's `typings.d.ts` add
|
||||
|
||||
```ts
|
||||
declare module '*.json' {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-jest",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "React storybook addon that show component jest report",
|
||||
"keywords": [
|
||||
"addon",
|
||||
@ -11,11 +11,16 @@
|
||||
"storybook",
|
||||
"unit-testing"
|
||||
],
|
||||
"homepage": "https://storybook.js.org",
|
||||
"bugs": "https://github.com/storybooks/storybook",
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/jest",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/storybooks/storybook"
|
||||
"url": "https://github.com/storybooks/storybook.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": "Renaud Tertrais <renaud.tertrais@gmail.com> (https://github.com/renaudtertrais)",
|
||||
@ -25,11 +30,12 @@
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/styled": "0.10.5",
|
||||
"@storybook/addons": "4.0.0-alpha.21",
|
||||
"@storybook/components": "4.0.0-alpha.21",
|
||||
"@emotion/styled": "^0.10.6",
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"@storybook/components": "4.0.0-rc.1",
|
||||
"global": "^4.3.2",
|
||||
"prop-types": "^15.6.2",
|
||||
"upath": "^1.1.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@ -1,17 +1,18 @@
|
||||
import addons from '@storybook/addons';
|
||||
import deprecate from 'util-deprecate';
|
||||
import { normalize } from 'upath';
|
||||
|
||||
const findTestResults = (testFiles, jestTestResults, jestTestFilesExt) =>
|
||||
Object.values(testFiles).map(name => {
|
||||
const fileName = `${name}${jestTestFilesExt}`;
|
||||
if (jestTestResults && jestTestResults.testResults) {
|
||||
return {
|
||||
fileName,
|
||||
name,
|
||||
result: jestTestResults.testResults.find(t =>
|
||||
new RegExp(`${name}${jestTestFilesExt}`).test(t.name)
|
||||
),
|
||||
result: jestTestResults.testResults.find(t => normalize(t.name).includes(fileName)),
|
||||
};
|
||||
}
|
||||
return { name };
|
||||
return { fileName, name };
|
||||
});
|
||||
|
||||
const emitAddTests = ({ kind, story, testFiles, options }) => {
|
||||
|
@ -7,7 +7,7 @@ import Panel from './components/Panel';
|
||||
addons.register('storybook/tests', api => {
|
||||
const channel = addons.getChannel();
|
||||
addons.addPanel('storybook/tests/panel', {
|
||||
title: <PanelTitle channel={addons.getChannel()} api={api} />,
|
||||
title: () => <PanelTitle channel={channel} api={api} />,
|
||||
// eslint-disable-next-line react/prop-types
|
||||
render: ({ active }) => <Panel channel={channel} api={api} active={active} />,
|
||||
});
|
||||
|
@ -263,13 +263,15 @@ Allows you to get a value from a list of radio buttons from the user.
|
||||
```js
|
||||
import { radios } from '@storybook/addon-knobs';
|
||||
|
||||
const label = 'Fruits';
|
||||
const options = {
|
||||
Kiwi: 'kiwi',
|
||||
Guava: 'guava',
|
||||
Watermelon: 'watermelon',
|
||||
};
|
||||
};
|
||||
const defaultValue = 'kiwi';
|
||||
|
||||
const = radios(name, options, defaultValue);
|
||||
const value = radios(label, options, defaultValue);
|
||||
```
|
||||
|
||||
### files
|
||||
|
@ -1,7 +1,18 @@
|
||||
{
|
||||
"name": "@storybook/addon-knobs",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "Storybook Addon Prop Editor Component",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"storybook"
|
||||
],
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/knobs",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/storybooks/storybook.git"
|
||||
@ -13,10 +24,10 @@
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/styled": "0.10.5",
|
||||
"@storybook/addons": "4.0.0-alpha.21",
|
||||
"@storybook/components": "4.0.0-alpha.21",
|
||||
"@storybook/core-events": "4.0.0-alpha.21",
|
||||
"@emotion/styled": "^0.10.6",
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"@storybook/components": "4.0.0-rc.1",
|
||||
"@storybook/core-events": "4.0.0-rc.1",
|
||||
"copy-to-clipboard": "^3.0.8",
|
||||
"escape-html": "^1.0.3",
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
@ -24,13 +35,9 @@
|
||||
"prop-types": "^15.6.2",
|
||||
"qs": "^6.5.2",
|
||||
"react-color": "^2.14.1",
|
||||
"react-datetime": "^2.15.0",
|
||||
"react-lifecycles-compat": "^3.0.4",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vue": "^2.5.17"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ const getTimestamp = () => +new Date();
|
||||
const DEFAULT_GROUP_ID = 'ALL';
|
||||
|
||||
const PanelWrapper = styled.div({
|
||||
height: '100%',
|
||||
overflow: 'auto',
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
|
@ -28,7 +28,9 @@ class ArrayType extends React.Component {
|
||||
render() {
|
||||
const { knob } = this.props;
|
||||
|
||||
return <Textarea id={knob.name} value={knob.value} onChange={this.handleChange} size="flex" />;
|
||||
const value = knob.value.join(knob.separator);
|
||||
|
||||
return <Textarea id={knob.name} value={value} onChange={this.handleChange} size="flex" />;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,13 @@ class ColorType extends React.Component {
|
||||
document.addEventListener('mousedown', this.handleWindowMouseDown);
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const { knob } = this.props;
|
||||
const { displayColorPicker } = this.state;
|
||||
|
||||
return nextProps.knob.value !== knob.value;
|
||||
return (
|
||||
nextProps.knob.value !== knob.value || nextState.displayColorPicker !== displayColorPicker
|
||||
);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
139
addons/knobs/src/components/types/Date.js
Normal file
139
addons/knobs/src/components/types/Date.js
Normal file
@ -0,0 +1,139 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from '@emotion/styled';
|
||||
import { Input } from '@storybook/components';
|
||||
|
||||
const FlexSpaced = styled.div({
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
'& > *': {
|
||||
marginLeft: 10,
|
||||
},
|
||||
'& > *:first-child': {
|
||||
marginLeft: 0,
|
||||
},
|
||||
});
|
||||
const FlexInput = styled(Input)({ flex: 1 });
|
||||
|
||||
const formatDate = date => {
|
||||
const year = `000${date.getFullYear()}`.slice(-4);
|
||||
const month = `0${date.getMonth() + 1}`.slice(-2);
|
||||
const day = `0${date.getDate()}`.slice(-2);
|
||||
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
const formatTime = date => {
|
||||
const hours = `0${date.getHours()}`.slice(-2);
|
||||
const minutes = `0${date.getMinutes()}`.slice(-2);
|
||||
|
||||
return `${hours}:${minutes}`;
|
||||
};
|
||||
|
||||
class DateType extends Component {
|
||||
static getDerivedStateFromProps() {
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
state = {
|
||||
valid: undefined,
|
||||
};
|
||||
|
||||
componentDidUpdate() {
|
||||
const { knob } = this.props;
|
||||
const { valid } = this.state;
|
||||
const value = new Date(knob.value);
|
||||
|
||||
if (valid !== false) {
|
||||
this.dateInput.value = formatDate(value);
|
||||
this.timeInput.value = formatTime(value);
|
||||
}
|
||||
}
|
||||
|
||||
onDateChange = e => {
|
||||
const { knob, onChange } = this.props;
|
||||
const { state } = this;
|
||||
|
||||
let valid = false;
|
||||
const [year, month, day] = e.target.value.split('-');
|
||||
const result = new Date(knob.value);
|
||||
if (result.getTime()) {
|
||||
result.setFullYear(parseInt(year, 10));
|
||||
result.setMonth(parseInt(month, 10) - 1);
|
||||
result.setDate(parseInt(day, 10));
|
||||
if (result.getTime()) {
|
||||
valid = true;
|
||||
onChange(result.getTime());
|
||||
}
|
||||
}
|
||||
if (valid !== state.valid) {
|
||||
this.setState({ valid });
|
||||
}
|
||||
};
|
||||
|
||||
onTimeChange = e => {
|
||||
const { knob, onChange } = this.props;
|
||||
const { state } = this;
|
||||
|
||||
let valid = false;
|
||||
const [hours, minutes] = e.target.value.split(':');
|
||||
const result = new Date(knob.value);
|
||||
if (result.getTime()) {
|
||||
result.setHours(parseInt(hours, 10));
|
||||
result.setMinutes(parseInt(minutes, 10));
|
||||
if (result.getTime()) {
|
||||
onChange(result.getTime());
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
if (valid !== state.valid) {
|
||||
this.setState({ valid });
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { knob } = this.props;
|
||||
const { name } = knob;
|
||||
const { valid } = this.state;
|
||||
|
||||
return name ? (
|
||||
<FlexSpaced style={{ display: 'flex' }}>
|
||||
<FlexInput
|
||||
type="date"
|
||||
max="9999-12-31" // I do this because of a rendering bug in chrome
|
||||
ref={el => {
|
||||
this.dateInput = el;
|
||||
}}
|
||||
id={`${name}date`}
|
||||
onChange={this.onDateChange}
|
||||
/>
|
||||
<FlexInput
|
||||
type="time"
|
||||
id={`${name}time`}
|
||||
ref={el => {
|
||||
this.timeInput = el;
|
||||
}}
|
||||
onChange={this.onTimeChange}
|
||||
/>
|
||||
{!valid ? <div>invalid</div> : null}
|
||||
</FlexSpaced>
|
||||
) : null;
|
||||
}
|
||||
}
|
||||
|
||||
DateType.defaultProps = {
|
||||
knob: {},
|
||||
onChange: value => value,
|
||||
};
|
||||
|
||||
DateType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.number,
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
DateType.serialize = value => new Date(value).getTime() || new Date().getTime();
|
||||
DateType.deserialize = value => new Date(value).getTime() || new Date().getTime();
|
||||
|
||||
export default DateType;
|
@ -1,50 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import Datetime from 'react-datetime';
|
||||
|
||||
import style from './styles';
|
||||
|
||||
const DateInput = styled(Datetime)(style);
|
||||
|
||||
class DateType extends React.Component {
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const { knob } = this.props;
|
||||
|
||||
return nextProps.knob.value !== knob.value;
|
||||
}
|
||||
|
||||
handleChange = date => {
|
||||
const { onChange } = this.props;
|
||||
const value = date.valueOf();
|
||||
|
||||
onChange(value);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { knob } = this.props;
|
||||
|
||||
return (
|
||||
<DateInput
|
||||
value={knob.value ? new Date(knob.value) : null}
|
||||
type="date"
|
||||
onChange={this.handleChange}
|
||||
size="flex"
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
DateType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.number,
|
||||
}).isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
DateType.serialize = value => String(value);
|
||||
DateType.deserialize = value => parseFloat(value);
|
||||
|
||||
export default DateType;
|
@ -1,202 +0,0 @@
|
||||
import { Input } from '@storybook/components';
|
||||
|
||||
export default ({ theme, size }) => ({
|
||||
...Input.sizes({ size, theme }),
|
||||
'&.rdt': {
|
||||
position: 'relative',
|
||||
},
|
||||
'& > input': {
|
||||
width: '100%',
|
||||
height: 32,
|
||||
...Input.styles({ theme }),
|
||||
...Input.alignment({ theme }),
|
||||
},
|
||||
'& .rdtPicker': {
|
||||
display: 'none',
|
||||
position: 'absolute',
|
||||
width: 200,
|
||||
padding: 4,
|
||||
marginTop: 1,
|
||||
zIndex: 99999,
|
||||
background: theme.barFill,
|
||||
},
|
||||
'&.rdtOpen .rdtPicker': {
|
||||
display: 'block',
|
||||
},
|
||||
'&.rdt .rdtPicker': {
|
||||
boxShadow: 'none',
|
||||
position: 'static',
|
||||
},
|
||||
|
||||
'& .rdtPicker .rdtTimeToggle': {
|
||||
textAlign: 'center',
|
||||
fontSize: 11,
|
||||
},
|
||||
|
||||
'& .rdtPicker table': {
|
||||
width: '100%',
|
||||
margin: 0,
|
||||
},
|
||||
'& .rdtPicker td, & .rdtPicker th': {
|
||||
textAlign: 'center',
|
||||
height: 32,
|
||||
boxSizing: 'border-box',
|
||||
},
|
||||
'& .rdtPicker td': {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
'& .rdtPicker td.rdtDay:hover, & .rdtPicker td.rdtHour:hover, & .rdtPicker td.rdtMinute:hover, & .rdtPicker td.rdtSecond:hover, & .rdtPicker .rdtTimeToggle:hover': {
|
||||
color: theme.highlightColor,
|
||||
textDecoration: 'underline',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
'& .rdtPicker td.rdtOld, & .rdtPicker td.rdtNew': {
|
||||
color: '#999999',
|
||||
},
|
||||
'& .rdtPicker td.rdtToday': {
|
||||
position: 'relative',
|
||||
},
|
||||
'& .rdtPicker td.rdtToday:before': {
|
||||
content: '""',
|
||||
display: 'inline-block',
|
||||
borderLeft: '7px solid transparent',
|
||||
borderBottom: `7px solid ${theme.highlightColor}`,
|
||||
borderTopColor: 'rgba(0, 0, 0, 0.2)',
|
||||
position: 'absolute',
|
||||
bottom: 4,
|
||||
right: 4,
|
||||
},
|
||||
'& .rdtPicker td.rdtActive, & .rdtPicker td.rdtActive:hover': {
|
||||
backgroundColor: theme.highlightColor,
|
||||
color: '#fff',
|
||||
textShadow:
|
||||
'0 -1px 0 rgba(0,0,0,0.25), 0 1px 0 rgba(0,0,0,0.25), -1px 0 0 rgba(0,0,0,0.25), 1px 0 0 rgba(0,0,0,0.25)',
|
||||
},
|
||||
'& .rdtPicker td.rdtActive.rdtToday:before': {
|
||||
borderBottomColor: '#fff',
|
||||
},
|
||||
'& .rdtPicker td.rdtDisabled, & .rdtPicker td.rdtDisabled:hover': {
|
||||
background: 'none',
|
||||
color: '#999999',
|
||||
cursor: 'not-allowed',
|
||||
},
|
||||
|
||||
'& .rdtPicker td span.rdtOld': {
|
||||
color: '#999999',
|
||||
},
|
||||
'& .rdtPicker td span.rdtDisabled, & .rdtPicker td span.rdtDisabled:hover': {
|
||||
background: 'none',
|
||||
color: '#999999',
|
||||
cursor: 'not-allowed',
|
||||
},
|
||||
'& .rdtPicker th': {
|
||||
borderBottom: `1px solid ${theme.highlightColor}`,
|
||||
},
|
||||
'& .rdtPicker .dow': {
|
||||
width: '14.2857%',
|
||||
fontSize: 11,
|
||||
borderBottom: 'none',
|
||||
},
|
||||
'& .rdtPicker th.rdtSwitch': {
|
||||
width: 100,
|
||||
fontSize: 11,
|
||||
},
|
||||
'& .rdtPicker th.rdtNext, & .rdtPicker th.rdtPrev': {
|
||||
fontSize: 11,
|
||||
verticalAlign: 'middle',
|
||||
},
|
||||
|
||||
'& .rdtPrev span, & .rdtNext span': {
|
||||
display: 'block',
|
||||
userSelect: 'none',
|
||||
},
|
||||
|
||||
'& .rdtPicker th.rdtDisabled, & .rdtPicker th.rdtDisabled:hover': {
|
||||
background: 'none',
|
||||
color: '#999999',
|
||||
cursor: 'not-allowed',
|
||||
},
|
||||
'& .rdtPicker thead tr:first-child th': {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
'& .rdtPicker thead tr:first-child th:hover': {
|
||||
color: theme.highlightColor,
|
||||
},
|
||||
|
||||
'& .rdtPicker tfoot': {
|
||||
borderTop: '1px solid #f9f9f9',
|
||||
},
|
||||
|
||||
'& .rdtPicker button': {
|
||||
border: 'none',
|
||||
background: 'none',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
'& .rdtPicker button:hover': {
|
||||
color: theme.highlightColor,
|
||||
},
|
||||
|
||||
'& .rdtPicker thead button': {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
|
||||
'& td.rdtMonth, & td.rdtYear': {
|
||||
height: 50,
|
||||
width: '25%',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
'& td.rdtMonth:hover, & td.rdtYear:hover': {
|
||||
color: theme.highlightColor,
|
||||
},
|
||||
|
||||
'& td.rdtDay': {
|
||||
fontSize: 11,
|
||||
},
|
||||
|
||||
'& .rdtCounters': {
|
||||
display: 'inline-block',
|
||||
},
|
||||
|
||||
'& .rdtCounters > div': {
|
||||
float: 'left',
|
||||
},
|
||||
|
||||
'& .rdtCounter': {
|
||||
height: 100,
|
||||
width: 40,
|
||||
},
|
||||
|
||||
'& .rdtCounterSeparator': {
|
||||
lineHeight: '100px',
|
||||
},
|
||||
|
||||
'& .rdtCounter .rdtBtn': {
|
||||
height: '40%',
|
||||
lineHeight: '40px',
|
||||
cursor: 'pointer',
|
||||
display: 'block',
|
||||
fontSize: 11,
|
||||
|
||||
userSelect: 'none',
|
||||
},
|
||||
'& .rdtCounter .rdtBtn:hover': {
|
||||
color: theme.highlightColor,
|
||||
},
|
||||
'& .rdtCounter .rdtCount': {
|
||||
height: '20%',
|
||||
fontSize: 11,
|
||||
},
|
||||
|
||||
'& .rdtMilli': {
|
||||
verticalSlign: 'middle',
|
||||
paddingLeft: 8,
|
||||
width: 48,
|
||||
},
|
||||
|
||||
'& .rdtMilli input': {
|
||||
width: '100%',
|
||||
fontSize: 11,
|
||||
marginTop: 37,
|
||||
},
|
||||
});
|
@ -36,7 +36,7 @@ SelectType.defaultProps = {
|
||||
SelectType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
value: PropTypes.any,
|
||||
options: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
|
@ -1,11 +1,15 @@
|
||||
{
|
||||
"name": "@storybook/addon-links",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "Story Links addon for storybook",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"storybook"
|
||||
],
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/links",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
@ -20,9 +24,9 @@
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@storybook/addons": "4.0.0-alpha.21",
|
||||
"@storybook/components": "4.0.0-alpha.21",
|
||||
"@storybook/core-events": "4.0.0-alpha.21",
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"@storybook/components": "4.0.0-rc.1",
|
||||
"@storybook/core-events": "4.0.0-rc.1",
|
||||
"global": "^4.3.2",
|
||||
"prop-types": "^15.6.2"
|
||||
},
|
||||
|
@ -1,12 +1,19 @@
|
||||
{
|
||||
"name": "@storybook/addon-notes",
|
||||
"version": "4.0.0-alpha.21",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "Write notes for your Storybook stories.",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"notes",
|
||||
"storybook"
|
||||
],
|
||||
"homepage": "https://github.com/storybooks/storybook/tree/master/addons/notes",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/storybooks/storybook.git"
|
||||
@ -18,9 +25,9 @@
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/styled": "0.10.5",
|
||||
"@storybook/addons": "4.0.0-alpha.21",
|
||||
"marked": "^0.5.0",
|
||||
"@emotion/styled": "^0.10.6",
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"marked": "^0.5.1",
|
||||
"prop-types": "^15.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@ -2,8 +2,7 @@ import addons, { makeDecorator } from '@storybook/addons';
|
||||
import marked from 'marked';
|
||||
|
||||
function renderMarkdown(text, options) {
|
||||
marked.setOptions({ ...marked.defaults, options });
|
||||
return marked(text);
|
||||
return marked(text, { ...marked.defaults, ...options });
|
||||
}
|
||||
|
||||
export const withNotes = makeDecorator({
|
||||
|
89
addons/ondevice-backgrounds/README.md
Normal file
89
addons/ondevice-backgrounds/README.md
Normal file
@ -0,0 +1,89 @@
|
||||
# Storybook Addon On Device Backgrounds
|
||||
|
||||
Storybook On Device Background Addon can be used to change background colors inside the the simulator in [Storybook](https://storybook.js.org).
|
||||
|
||||
[Framework Support](https://github.com/storybooks/storybook/blob/master/ADDONS_SUPPORT.md)
|
||||
|
||||

|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm i -D @storybook/addon-ondevice-backgrounds
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Then create a file called `rn-addons.js` in your storybook config.
|
||||
|
||||
Add following content to it:
|
||||
|
||||
```js
|
||||
import '@storybook/addon-ondevice-backgrounds/register';
|
||||
```
|
||||
|
||||
Then import `rn-addons.js` next to your `getStorybookUI` call.
|
||||
```js
|
||||
import './rn-addons';
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Then write your stories like this:
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react-native';
|
||||
import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';
|
||||
|
||||
storiesOf('Button', module)
|
||||
.addDecorator(
|
||||
withBackgrounds([
|
||||
{ name: 'twitter', value: '#00aced', default: true },
|
||||
{ name: 'facebook', value: '#3b5998' },
|
||||
])
|
||||
)
|
||||
.add('with text', () => <Text>Click me</Text>);
|
||||
```
|
||||
|
||||
You can add the backgrounds to all stories with `addDecorator` in `.storybook/config.js`:
|
||||
|
||||
```js
|
||||
import { addDecorator } from '@storybook/react-native'; // <- or your storybook framework
|
||||
import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';
|
||||
|
||||
addDecorator(
|
||||
withBackgrounds([
|
||||
{ name: 'twitter', value: '#00aced', default: true },
|
||||
{ name: 'facebook', value: '#3b5998' },
|
||||
])
|
||||
);
|
||||
```
|
||||
|
||||
If you want to override backgrounds for a single story or group of stories, pass the `backgrounds` parameter:
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react-native';
|
||||
|
||||
storiesOf('Button', module)
|
||||
.addParameters({
|
||||
backgrounds: [
|
||||
{ name: 'red', value: '#F44336' },
|
||||
{ name: 'blue', value: '#2196F3', default: true },
|
||||
],
|
||||
})
|
||||
.add('with text', () => <button>Click me</button>);
|
||||
```
|
||||
|
||||
If you don't want to use backgrounds for a story, you can set the `backgrounds` parameter to `[]`, or use `{ disable: true }` to skip the addon:
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react-native';
|
||||
|
||||
storiesOf('Button', module).add('with text', () => <button>Click me</button>, {
|
||||
backgrounds: { disable: true },
|
||||
});
|
||||
```
|
BIN
addons/ondevice-backgrounds/docs/demo.png
Normal file
BIN
addons/ondevice-backgrounds/docs/demo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 230 KiB |
36
addons/ondevice-backgrounds/package.json
Normal file
36
addons/ondevice-backgrounds/package.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "@storybook/addon-ondevice-backgrounds",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "A storybook addon to show different backgrounds for your preview",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"background",
|
||||
"react",
|
||||
"storybook"
|
||||
],
|
||||
"homepage": "https://storybook.js.org",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybooks/storybook/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/storybooks/storybook.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
"scripts": {
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"prop-types": "^15.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
}
|
1
addons/ondevice-backgrounds/register.js
Normal file
1
addons/ondevice-backgrounds/register.js
Normal file
@ -0,0 +1 @@
|
||||
require('./dist/register');
|
112
addons/ondevice-backgrounds/src/BackgroundPanel.js
Normal file
112
addons/ondevice-backgrounds/src/BackgroundPanel.js
Normal file
@ -0,0 +1,112 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { View, Text } from 'react-native';
|
||||
import Events from './constants';
|
||||
import Swatch from './Swatch';
|
||||
|
||||
const defaultBackground = {
|
||||
name: 'default',
|
||||
value: 'transparent',
|
||||
};
|
||||
|
||||
const instructionsHtml = `
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { withBackgrounds } from '@storybook/addon-backgrounds';
|
||||
|
||||
storiesOf('First Component', module)
|
||||
.addDecorator(withBackgrounds([
|
||||
{ name: 'twitter', value: '#00aced' },
|
||||
{ name: 'facebook', value: '#3b5998" },
|
||||
]))
|
||||
.add("First Button", () => <button>Click me</button>);
|
||||
`.trim();
|
||||
|
||||
const Instructions = () => (
|
||||
<View>
|
||||
<Text style={{ fontSize: 16 }}>Setup Instructions</Text>
|
||||
<Text>
|
||||
Please add the background decorator definition to your story. The background decorate accepts
|
||||
an array of items, which should include a name for your color (preferably the css class name)
|
||||
and the corresponding color / image value.
|
||||
</Text>
|
||||
<Text>
|
||||
Below is an example of how to add the background decorator to your story definition.
|
||||
</Text>
|
||||
<Text>{instructionsHtml}</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
export default class BackgroundPanel extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = { backgrounds: [] };
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { channel } = this.props;
|
||||
|
||||
this.onSet = channel.on(Events.SET, data => {
|
||||
const backgrounds = [...data];
|
||||
|
||||
this.setState({ backgrounds });
|
||||
});
|
||||
|
||||
this.onUnset = channel.on(Events.UNSET, () => {
|
||||
this.setState({ backgrounds: [] });
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const { channel } = this.props;
|
||||
channel.removeListener(Events.SET, this.onSet);
|
||||
channel.removeListener(Events.UNSET, this.onUnset);
|
||||
}
|
||||
|
||||
setBackgroundFromSwatch = background => {
|
||||
this.update(background);
|
||||
};
|
||||
|
||||
update(background) {
|
||||
const { channel } = this.props;
|
||||
channel.emit(Events.UPDATE_BACKGROUND, background);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { active } = this.props;
|
||||
const { backgrounds = [] } = this.state;
|
||||
|
||||
if (!active) {
|
||||
return null;
|
||||
}
|
||||
if (!backgrounds.length) return <Instructions />;
|
||||
|
||||
const hasDefault = backgrounds.filter(x => x.default).length;
|
||||
if (!hasDefault) backgrounds.push(defaultBackground);
|
||||
|
||||
return (
|
||||
<View>
|
||||
{backgrounds.map(({ value, name }) => (
|
||||
<View key={`${name} ${value}`}>
|
||||
<Swatch value={value} name={name} setBackground={this.setBackgroundFromSwatch} />
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
BackgroundPanel.propTypes = {
|
||||
active: PropTypes.bool.isRequired,
|
||||
api: PropTypes.shape({
|
||||
getQueryParam: PropTypes.func,
|
||||
setQueryParams: PropTypes.func,
|
||||
}).isRequired,
|
||||
channel: PropTypes.shape({
|
||||
emit: PropTypes.func,
|
||||
on: PropTypes.func,
|
||||
removeListener: PropTypes.func,
|
||||
}),
|
||||
};
|
||||
BackgroundPanel.defaultProps = {
|
||||
channel: undefined,
|
||||
};
|
30
addons/ondevice-backgrounds/src/Swatch.js
Normal file
30
addons/ondevice-backgrounds/src/Swatch.js
Normal file
@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { TouchableOpacity, View, Text } from 'react-native';
|
||||
|
||||
const Swatch = ({ name, value, setBackground }) => (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
borderRadius: 4,
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgba(0,0,0,0.2)',
|
||||
marginTop: 10,
|
||||
marginBottom: 20,
|
||||
marginHorizontal: 10,
|
||||
}}
|
||||
onPress={() => setBackground(value)}
|
||||
>
|
||||
<View style={{ flex: 1, backgroundColor: value, height: 40 }} />
|
||||
<View style={{ padding: 4, flexDirection: 'row', justifyContent: 'space-between' }}>
|
||||
<Text>{name}:</Text>
|
||||
<Text>{value}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
Swatch.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
setBackground: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default Swatch;
|
8
addons/ondevice-backgrounds/src/constants.js
Normal file
8
addons/ondevice-backgrounds/src/constants.js
Normal file
@ -0,0 +1,8 @@
|
||||
export const ADDON_ID = 'storybook-addon-background';
|
||||
export const PANEL_ID = `${ADDON_ID}/background-panel`;
|
||||
|
||||
export default {
|
||||
SET: `${ADDON_ID}:set`,
|
||||
UNSET: `${ADDON_ID}:unset`,
|
||||
UPDATE_BACKGROUND: `${ADDON_ID}:update`,
|
||||
};
|
52
addons/ondevice-backgrounds/src/container.js
Normal file
52
addons/ondevice-backgrounds/src/container.js
Normal file
@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import Events from './constants';
|
||||
|
||||
export default class Container extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { background: props.initialBackground || '' };
|
||||
this.onBackgroundChange = this.onBackgroundChange.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { channel } = this.props;
|
||||
// Listen to the notes and render it.
|
||||
channel.on(Events.UPDATE_BACKGROUND, this.onBackgroundChange);
|
||||
}
|
||||
|
||||
// This is some cleanup tasks when the Notes panel is unmounting.
|
||||
componentWillUnmount() {
|
||||
const { channel } = this.props;
|
||||
channel.removeListener(Events.UPDATE_BACKGROUND, this.onBackgroundChange);
|
||||
}
|
||||
|
||||
onBackgroundChange(background) {
|
||||
this.setState({ background });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { background } = this.state;
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1, backgroundColor: background || 'transparent' }}>{children}</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Container.propTypes = {
|
||||
channel: PropTypes.shape({
|
||||
emit: PropTypes.func,
|
||||
on: PropTypes.func,
|
||||
removeListener: PropTypes.func,
|
||||
}),
|
||||
initialBackground: PropTypes.string,
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
Container.defaultProps = {
|
||||
channel: undefined,
|
||||
initialBackground: '',
|
||||
};
|
34
addons/ondevice-backgrounds/src/index.js
Normal file
34
addons/ondevice-backgrounds/src/index.js
Normal file
@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
|
||||
import addons, { makeDecorator } from '@storybook/addons';
|
||||
|
||||
import Events from './constants';
|
||||
import Container from './container';
|
||||
|
||||
export const withBackgrounds = makeDecorator({
|
||||
name: 'withBackgrounds',
|
||||
parameterName: 'backgrounds',
|
||||
skipIfNoParametersOrOptions: true,
|
||||
allowDeprecatedUsage: true,
|
||||
wrapper: (getStory, context, { options, parameters }) => {
|
||||
const data = parameters || options || [];
|
||||
const backgrounds = Array.isArray(data) ? data : Object.values(data);
|
||||
|
||||
let background = 'transparent';
|
||||
if (backgrounds.length !== 0) {
|
||||
addons.getChannel().emit(Events.SET, backgrounds);
|
||||
|
||||
const defaultOrFirst = backgrounds.find(x => x.default) || backgrounds[0];
|
||||
|
||||
if (defaultOrFirst) {
|
||||
background = defaultOrFirst.value;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Container initialBackground={background} channel={addons.getChannel()}>
|
||||
{getStory(context)}
|
||||
</Container>
|
||||
);
|
||||
},
|
||||
});
|
14
addons/ondevice-backgrounds/src/register.js
Normal file
14
addons/ondevice-backgrounds/src/register.js
Normal file
@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import addons from '@storybook/addons';
|
||||
|
||||
import { ADDON_ID, PANEL_ID } from './constants';
|
||||
import BackgroundPanel from './BackgroundPanel';
|
||||
|
||||
addons.register(ADDON_ID, api => {
|
||||
const channel = addons.getChannel();
|
||||
addons.addPanel(PANEL_ID, {
|
||||
title: 'Backgrounds',
|
||||
// eslint-disable-next-line react/prop-types
|
||||
render: ({ active }) => <BackgroundPanel channel={channel} api={api} active={active} />,
|
||||
});
|
||||
});
|
38
addons/ondevice-knobs/README.md
Normal file
38
addons/ondevice-knobs/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Storybook Addon On Device Knobs
|
||||
|
||||
Storybook Addon On Device Knobs allow you to edit React props dynamically using the Storybook UI.
|
||||
You can also use Knobs as a dynamic variable inside stories in [Storybook](https://storybook.js.org).
|
||||
|
||||
[Framework Support](https://github.com/storybooks/storybook/blob/master/ADDONS_SUPPORT.md)
|
||||
|
||||
This is how Knobs look like:
|
||||
|
||||
[](https://storybooks-official.netlify.com/?knob-Dollars=12.5&knob-Name=Storyteller&knob-Years%20in%20NY=9&knob-background=%23ffff00&knob-Age=70&knob-Items%5B0%5D=Laptop&knob-Items%5B1%5D=Book&knob-Items%5B2%5D=Whiskey&knob-Other%20Fruit=lime&knob-Birthday=1484870400000&knob-Nice=true&knob-Styles=%7B%22border%22%3A%223px%20solid%20%23ff00ff%22%2C%22padding%22%3A%2210px%22%7D&knob-Fruit=apple&selectedKind=Addons%7CKnobs.withKnobs&selectedStory=tweaks%20static%20values&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybooks%2Fstorybook-addon-knobs)
|
||||
|
||||
**This addon is a wrapper for addon [@storybook/addon-knobs](https://github.com/storybooks/storybook/blob/master/addons/knobs).
|
||||
Refer to its documentation to understand how to use knobs**
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
First of all, you need to install knobs into your project.
|
||||
|
||||
```sh
|
||||
npm install @storybook/addon-ondevice-knobs
|
||||
```
|
||||
|
||||
Then create a file called `rn-addons.js` in your storybook config.
|
||||
|
||||
```js
|
||||
import '@storybook/addon-ondevice-knobs/register';
|
||||
```
|
||||
|
||||
|
||||
Then import `rn-addons.js` next to your `getStorybookUI` call.
|
||||
```js
|
||||
import './rn-addons';
|
||||
```
|
||||
|
||||
Now, write your stories with knobs.
|
||||
|
||||
**Refer to [@storybook/addon-knobs](https://github.com/storybooks/storybook/blob/master/addons/knobs) to learn how to write stories.**
|
39
addons/ondevice-knobs/package.json
Normal file
39
addons/ondevice-knobs/package.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "@storybook/addon-ondevice-knobs",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "Display storybook story knobs on your deviced.",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"knobs",
|
||||
"ondevice",
|
||||
"react-native",
|
||||
"storybook"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/storybooks/storybook.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
"scripts": {
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"deep-equal": "^1.0.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-native-color-picker": "^0.4.0",
|
||||
"react-native-modal-datetime-picker": "^5.1.0",
|
||||
"react-native-modal-selector": "^0.0.29",
|
||||
"react-native-switch": "^1.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@storybook/addon-knobs": "4.0.0-alpha.24",
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
}
|
1
addons/ondevice-knobs/register.js
Normal file
1
addons/ondevice-knobs/register.js
Normal file
@ -0,0 +1 @@
|
||||
require('./dist/index').register();
|
72
addons/ondevice-knobs/src/GroupTabs.js
Normal file
72
addons/ondevice-knobs/src/GroupTabs.js
Normal file
@ -0,0 +1,72 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { ScrollView, Text, TouchableOpacity } from 'react-native';
|
||||
|
||||
class GroupTabs extends Component {
|
||||
renderTab(name, group) {
|
||||
let { title } = group;
|
||||
if (typeof title === 'function') {
|
||||
title = title();
|
||||
}
|
||||
|
||||
const { onGroupSelect, selectedGroup } = this.props;
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
marginRight: 15,
|
||||
paddingBottom: 10,
|
||||
}}
|
||||
key={name}
|
||||
onPress={() => onGroupSelect(name)}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: selectedGroup === name ? 'black' : '#ccc',
|
||||
fontSize: 17,
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { groups } = this.props;
|
||||
|
||||
const entries = groups ? Object.entries(groups) : null;
|
||||
|
||||
return entries && entries.length ? (
|
||||
<ScrollView
|
||||
horizontal
|
||||
style={{
|
||||
marginHorizontal: 10,
|
||||
flexDirection: 'row',
|
||||
marginBottom: 10,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#ccc',
|
||||
}}
|
||||
>
|
||||
{entries.map(([key, value]) => this.renderTab(key, value))}
|
||||
</ScrollView>
|
||||
) : (
|
||||
<Text>no groups available</Text>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
GroupTabs.defaultProps = {
|
||||
groups: {},
|
||||
onGroupSelect: () => {},
|
||||
selectedGroup: null,
|
||||
};
|
||||
|
||||
GroupTabs.propTypes = {
|
||||
// eslint-disable-next-line react/forbid-prop-types
|
||||
groups: PropTypes.object,
|
||||
onGroupSelect: PropTypes.func,
|
||||
selectedGroup: PropTypes.string,
|
||||
};
|
||||
|
||||
export default GroupTabs;
|
39
addons/ondevice-knobs/src/PropField.js
Normal file
39
addons/ondevice-knobs/src/PropField.js
Normal file
@ -0,0 +1,39 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { View, Text } from 'react-native';
|
||||
import React from 'react';
|
||||
import TypeMap from './types';
|
||||
|
||||
const InvalidType = () => <Text style={{ margin: 10 }}>Invalid Type</Text>;
|
||||
|
||||
const PropField = ({ onChange, onPress, knob }) => {
|
||||
const InputType = TypeMap[knob.type] || InvalidType;
|
||||
|
||||
return (
|
||||
<View>
|
||||
{!knob.hideLabel ? (
|
||||
<Text
|
||||
style={{
|
||||
marginLeft: 10,
|
||||
fontSize: 14,
|
||||
color: 'rgb(68, 68, 68)',
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{`${knob.name}`}
|
||||
</Text>
|
||||
) : null}
|
||||
<InputType knob={knob} onChange={onChange} onPress={onPress} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
PropField.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.any,
|
||||
}).isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onPress: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default PropField;
|
56
addons/ondevice-knobs/src/PropForm.js
Normal file
56
addons/ondevice-knobs/src/PropForm.js
Normal file
@ -0,0 +1,56 @@
|
||||
/* eslint no-underscore-dangle: 0 */
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { View } from 'react-native';
|
||||
import PropField from './PropField';
|
||||
|
||||
export default class propForm extends React.Component {
|
||||
makeChangeHandler(name, type) {
|
||||
return value => {
|
||||
const { onFieldChange } = this.props;
|
||||
const change = { name, type, value };
|
||||
onFieldChange(change);
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { knobs, onFieldClick } = this.props;
|
||||
|
||||
return (
|
||||
<View>
|
||||
{knobs.map(knob => {
|
||||
const changeHandler = this.makeChangeHandler(knob.name, knob.type);
|
||||
return (
|
||||
<PropField
|
||||
key={knob.name}
|
||||
name={knob.name}
|
||||
type={knob.type}
|
||||
value={knob.value}
|
||||
knob={knob}
|
||||
onChange={changeHandler}
|
||||
onPress={onFieldClick}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
propForm.displayName = 'propForm';
|
||||
|
||||
propForm.defaultProps = {
|
||||
knobs: [],
|
||||
};
|
||||
|
||||
propForm.propTypes = {
|
||||
knobs: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.any,
|
||||
})
|
||||
),
|
||||
onFieldChange: PropTypes.func.isRequired,
|
||||
onFieldClick: PropTypes.func.isRequired,
|
||||
};
|
14
addons/ondevice-knobs/src/index.js
Normal file
14
addons/ondevice-knobs/src/index.js
Normal file
@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import addons from '@storybook/addons';
|
||||
import Panel from './panel';
|
||||
|
||||
export function register() {
|
||||
addons.register('RNKNOBS', () => {
|
||||
const channel = addons.getChannel();
|
||||
addons.addPanel('RNKNOBS', {
|
||||
title: 'Knobs',
|
||||
// eslint-disable-next-line react/prop-types
|
||||
render: ({ active }) => <Panel channel={channel} active={active} />,
|
||||
});
|
||||
});
|
||||
}
|
170
addons/ondevice-knobs/src/panel.js
Normal file
170
addons/ondevice-knobs/src/panel.js
Normal file
@ -0,0 +1,170 @@
|
||||
import React from 'react';
|
||||
import { View, Text, TouchableOpacity } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import GroupTabs from './GroupTabs';
|
||||
import PropForm from './PropForm';
|
||||
|
||||
const getTimestamp = () => +new Date();
|
||||
|
||||
const DEFAULT_GROUP_ID = 'ALL';
|
||||
|
||||
export default class Panel extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
this.setKnobs = this.setKnobs.bind(this);
|
||||
this.reset = this.reset.bind(this);
|
||||
this.setOptions = this.setOptions.bind(this);
|
||||
this.onGroupSelect = this.onGroupSelect.bind(this);
|
||||
|
||||
this.state = { knobs: {}, groupId: DEFAULT_GROUP_ID };
|
||||
this.options = {};
|
||||
|
||||
this.lastEdit = getTimestamp();
|
||||
this.loadedFromUrl = false;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { channel } = this.props;
|
||||
|
||||
channel.on('addon:knobs:setKnobs', this.setKnobs);
|
||||
channel.on('addon:knobs:setOptions', this.setOptions);
|
||||
|
||||
channel.on('selectStory', this.reset);
|
||||
|
||||
channel.emit('forceReRender');
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const { channel } = this.props;
|
||||
channel.removeListener('addon:knobs:setKnobs', this.setKnobs);
|
||||
channel.removeListener('selectStory', this.reset);
|
||||
}
|
||||
|
||||
onGroupSelect(name) {
|
||||
this.setState({ groupId: name });
|
||||
}
|
||||
|
||||
setOptions(options = { timestamps: false }) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
setKnobs({ knobs, timestamp }) {
|
||||
if (!this.options.timestamps || !timestamp || this.lastEdit <= timestamp) {
|
||||
this.setState({ knobs });
|
||||
}
|
||||
}
|
||||
|
||||
reset = () => {
|
||||
const { channel } = this.props;
|
||||
this.setState({ knobs: {} });
|
||||
channel.emit('addon:knobs:reset');
|
||||
};
|
||||
|
||||
emitChange(changedKnob) {
|
||||
const { channel } = this.props;
|
||||
channel.emit('addon:knobs:knobChange', changedKnob);
|
||||
}
|
||||
|
||||
handleChange(changedKnob) {
|
||||
this.lastEdit = getTimestamp();
|
||||
const { knobs } = this.state;
|
||||
const { name } = changedKnob;
|
||||
const newKnobs = { ...knobs };
|
||||
newKnobs[name] = {
|
||||
...newKnobs[name],
|
||||
...changedKnob,
|
||||
};
|
||||
|
||||
this.setState({ knobs: newKnobs });
|
||||
|
||||
this.setState({ knobs: newKnobs }, this.emitChange(changedKnob));
|
||||
}
|
||||
|
||||
handleClick(knob) {
|
||||
const { channel } = this.props;
|
||||
|
||||
channel.emit('addon:knobs:knobClick', knob);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { active } = this.props;
|
||||
|
||||
if (!active) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { knobs, groupId } = this.state;
|
||||
|
||||
const groups = {};
|
||||
const groupIds = [];
|
||||
|
||||
let knobsArray = Object.keys(knobs);
|
||||
|
||||
knobsArray.filter(key => knobs[key].groupId).forEach(key => {
|
||||
const knobKeyGroupId = knobs[key].groupId;
|
||||
groupIds.push(knobKeyGroupId);
|
||||
groups[knobKeyGroupId] = {
|
||||
render: () => <Text id={knobKeyGroupId}>{knobKeyGroupId}</Text>,
|
||||
title: knobKeyGroupId,
|
||||
};
|
||||
});
|
||||
|
||||
if (groupIds.length > 0) {
|
||||
groups[DEFAULT_GROUP_ID] = {
|
||||
render: () => <Text id={DEFAULT_GROUP_ID}>{DEFAULT_GROUP_ID}</Text>,
|
||||
title: DEFAULT_GROUP_ID,
|
||||
};
|
||||
if (groupId !== DEFAULT_GROUP_ID) {
|
||||
knobsArray = knobsArray.filter(key => knobs[key].groupId === groupId);
|
||||
}
|
||||
}
|
||||
|
||||
knobsArray = knobsArray.map(key => knobs[key]);
|
||||
|
||||
if (knobsArray.length === 0) {
|
||||
return <Text>NO KNOBS</Text>;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
{groupIds.length > 0 && (
|
||||
<GroupTabs groups={groups} onGroupSelect={this.onGroupSelect} selectedGroup={groupId} />
|
||||
)}
|
||||
<View>
|
||||
<PropForm
|
||||
knobs={knobsArray}
|
||||
onFieldChange={this.handleChange}
|
||||
onFieldClick={this.handleClick}
|
||||
/>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
borderRadius: 2,
|
||||
borderWidth: 1,
|
||||
borderColor: '#f7f4f4',
|
||||
padding: 4,
|
||||
margin: 10,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
onPress={this.reset}
|
||||
>
|
||||
<Text>RESET</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Panel.propTypes = {
|
||||
active: PropTypes.bool.isRequired,
|
||||
channel: PropTypes.shape({
|
||||
emit: PropTypes.func,
|
||||
on: PropTypes.func,
|
||||
removeListener: PropTypes.func,
|
||||
}).isRequired,
|
||||
onReset: PropTypes.object, // eslint-disable-line
|
||||
};
|
53
addons/ondevice-knobs/src/types/Array.js
Normal file
53
addons/ondevice-knobs/src/types/Array.js
Normal file
@ -0,0 +1,53 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import { TextInput } from 'react-native';
|
||||
|
||||
function formatArray(value, separator) {
|
||||
if (value === '') {
|
||||
return [];
|
||||
}
|
||||
return value.split(separator);
|
||||
}
|
||||
|
||||
const ArrayType = ({ knob, onChange }) => (
|
||||
<TextInput
|
||||
id={knob.name}
|
||||
underlineColorAndroid="transparent"
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: '#f7f4f4',
|
||||
borderRadius: 2,
|
||||
fontSize: 13,
|
||||
padding: 5,
|
||||
margin: 10,
|
||||
color: '#555',
|
||||
}}
|
||||
value={knob.value.join(knob.separator)}
|
||||
onChangeText={e => onChange(formatArray(e, knob.separator))}
|
||||
/>
|
||||
);
|
||||
|
||||
ArrayType.defaultProps = {
|
||||
knob: {},
|
||||
onChange: value => value,
|
||||
};
|
||||
|
||||
ArrayType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.array,
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
ArrayType.serialize = value => value;
|
||||
ArrayType.deserialize = value => {
|
||||
if (Array.isArray(value)) return value;
|
||||
|
||||
return Object.keys(value)
|
||||
.sort()
|
||||
.reduce((array, key) => [...array, value[key]], []);
|
||||
};
|
||||
|
||||
export default ArrayType;
|
39
addons/ondevice-knobs/src/types/Boolean.js
Normal file
39
addons/ondevice-knobs/src/types/Boolean.js
Normal file
@ -0,0 +1,39 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { View } from 'react-native';
|
||||
import { Switch } from 'react-native-switch';
|
||||
import React from 'react';
|
||||
|
||||
class BooleanType extends React.Component {
|
||||
onValueChange = () => {
|
||||
const { onChange, knob } = this.props;
|
||||
onChange(!knob.value);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { knob } = this.props;
|
||||
|
||||
return (
|
||||
<View style={{ margin: 10 }}>
|
||||
<Switch id={knob.name} onValueChange={this.onValueChange} value={knob.value} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
BooleanType.defaultProps = {
|
||||
knob: {},
|
||||
onChange: value => value,
|
||||
};
|
||||
|
||||
BooleanType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.bool,
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
BooleanType.serialize = value => (value ? String(value) : null);
|
||||
BooleanType.deserialize = value => value === 'true';
|
||||
|
||||
export default BooleanType;
|
25
addons/ondevice-knobs/src/types/Button.js
Normal file
25
addons/ondevice-knobs/src/types/Button.js
Normal file
@ -0,0 +1,25 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { TouchableOpacity, Text } from 'react-native';
|
||||
|
||||
const ButtonType = ({ knob, onPress }) => (
|
||||
<TouchableOpacity style={{ margin: 10 }} onPress={() => onPress(knob)}>
|
||||
<Text style={{ fontSize: 17, color: '#007aff' }}>{knob.name}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
ButtonType.defaultProps = {
|
||||
knob: {},
|
||||
};
|
||||
|
||||
ButtonType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
}),
|
||||
onPress: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
ButtonType.serialize = value => value;
|
||||
ButtonType.deserialize = value => value;
|
||||
|
||||
export default ButtonType;
|
101
addons/ondevice-knobs/src/types/Color.js
Normal file
101
addons/ondevice-knobs/src/types/Color.js
Normal file
@ -0,0 +1,101 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { Text, Modal, View, TouchableOpacity, TouchableWithoutFeedback } from 'react-native';
|
||||
import { ColorPicker, fromHsv } from 'react-native-color-picker';
|
||||
|
||||
class ColorType extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
displayColorPicker: false,
|
||||
};
|
||||
}
|
||||
|
||||
openColorPicker = () => {
|
||||
this.setState({
|
||||
displayColorPicker: true,
|
||||
});
|
||||
};
|
||||
|
||||
closeColorPicker = () => {
|
||||
this.setState({
|
||||
displayColorPicker: false,
|
||||
});
|
||||
};
|
||||
|
||||
onChangeColor = color => {
|
||||
const { onChange } = this.props;
|
||||
|
||||
onChange(fromHsv(color));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { knob } = this.props;
|
||||
const { displayColorPicker } = this.state;
|
||||
const colorStyle = {
|
||||
borderColor: 'rgb(247, 244, 244)',
|
||||
width: 30,
|
||||
height: 20,
|
||||
borderRadius: 2,
|
||||
margin: 10,
|
||||
backgroundColor: knob.value,
|
||||
};
|
||||
return (
|
||||
<View>
|
||||
<TouchableOpacity style={colorStyle} onPress={this.openColorPicker} />
|
||||
<Modal
|
||||
supportedOrientations={['portrait', 'landscape']}
|
||||
transparent
|
||||
visible={displayColorPicker}
|
||||
onRequestClose={this.closeColorPicker}
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={this.closeColorPicker}>
|
||||
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
||||
<TouchableWithoutFeedback>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: 'white',
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgb(247, 244, 244)',
|
||||
width: 250,
|
||||
height: 250,
|
||||
padding: 10,
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
onPress={this.closeColorPicker}
|
||||
style={{ alignSelf: 'flex-end', padding: 5 }}
|
||||
>
|
||||
<Text style={{ fontSize: 18, fontWeight: 'bold' }}>X</Text>
|
||||
</TouchableOpacity>
|
||||
<ColorPicker
|
||||
onColorSelected={this.onChangeColor}
|
||||
defaultColor={knob.value}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</Modal>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ColorType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
ColorType.defaultProps = {
|
||||
knob: {},
|
||||
onChange: value => value,
|
||||
};
|
||||
|
||||
ColorType.serialize = value => value;
|
||||
ColorType.deserialize = value => value;
|
||||
|
||||
export default ColorType;
|
103
addons/ondevice-knobs/src/types/Date.js
Normal file
103
addons/ondevice-knobs/src/types/Date.js
Normal file
@ -0,0 +1,103 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { TouchableOpacity, Text, View } from 'react-native';
|
||||
import DateTimePicker from 'react-native-modal-datetime-picker';
|
||||
|
||||
// TODO seconds support
|
||||
class DateType extends PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
isDateVisible: false,
|
||||
isTimeVisible: false,
|
||||
};
|
||||
}
|
||||
|
||||
showDatePicker = () => {
|
||||
this.setState({ isDateVisible: true });
|
||||
};
|
||||
|
||||
showTimePicker = () => {
|
||||
this.setState({ isTimeVisible: true });
|
||||
};
|
||||
|
||||
hidePicker = () => {
|
||||
this.setState({ isDateVisible: false, isTimeVisible: false });
|
||||
};
|
||||
|
||||
onDatePicked = date => {
|
||||
const value = date.valueOf();
|
||||
const { onChange } = this.props;
|
||||
onChange(value);
|
||||
this.hidePicker();
|
||||
};
|
||||
|
||||
render() {
|
||||
const { knob } = this.props;
|
||||
|
||||
const { isTimeVisible, isDateVisible } = this.state;
|
||||
const d = new Date(knob.value);
|
||||
|
||||
// https://stackoverflow.com/a/30272803
|
||||
const dateString = [
|
||||
`0${d.getDate()}`.slice(-2),
|
||||
`0${d.getMonth() + 1}`.slice(-2),
|
||||
d.getFullYear(),
|
||||
].join('-');
|
||||
const timeString = `${`0${d.getHours()}`.slice(-2)}:${`0${d.getMinutes()}`.slice(-2)}`;
|
||||
|
||||
return (
|
||||
<View style={{ margin: 10 }}>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: '#f7f4f4',
|
||||
borderRadius: 2,
|
||||
padding: 5,
|
||||
}}
|
||||
onPress={this.showDatePicker}
|
||||
>
|
||||
<Text style={{ fontSize: 13, color: '#555' }}>{dateString}</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: '#f7f4f4',
|
||||
borderRadius: 2,
|
||||
padding: 5,
|
||||
marginLeft: 5,
|
||||
}}
|
||||
onPress={this.showTimePicker}
|
||||
>
|
||||
<Text style={{ fontSize: 13, color: '#555' }}>{timeString}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<DateTimePicker
|
||||
date={d}
|
||||
isVisible={isTimeVisible || isDateVisible}
|
||||
mode={isTimeVisible ? 'time' : 'date'}
|
||||
onConfirm={this.onDatePicked}
|
||||
onCancel={this.hidePicker}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
DateType.defaultProps = {
|
||||
knob: {},
|
||||
onChange: value => value,
|
||||
};
|
||||
|
||||
DateType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.number,
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
DateType.serialize = value => String(value);
|
||||
DateType.deserialize = value => parseFloat(value);
|
||||
|
||||
export default DateType;
|
72
addons/ondevice-knobs/src/types/Number.js
Normal file
72
addons/ondevice-knobs/src/types/Number.js
Normal file
@ -0,0 +1,72 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { TextInput, View, Slider } from 'react-native';
|
||||
|
||||
class NumberType extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.renderNormal = this.renderNormal.bind(this);
|
||||
this.renderRange = this.renderRange.bind(this);
|
||||
}
|
||||
|
||||
renderNormal() {
|
||||
const { knob, onChange } = this.props;
|
||||
|
||||
return (
|
||||
<TextInput
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: '#f7f4f4',
|
||||
borderRadius: 2,
|
||||
fontSize: 13,
|
||||
padding: 5,
|
||||
color: '#555',
|
||||
}}
|
||||
underlineColorAndroid="transparent"
|
||||
value={knob.value.toString()}
|
||||
keyboardType="numeric"
|
||||
onChangeText={val => onChange(parseFloat(val))}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderRange() {
|
||||
const { knob, onChange } = this.props;
|
||||
|
||||
return (
|
||||
<Slider
|
||||
value={knob.value}
|
||||
minimumValue={knob.min}
|
||||
maximumValue={knob.max}
|
||||
step={knob.step}
|
||||
onSlidingComplete={val => onChange(parseFloat(val))}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { knob } = this.props;
|
||||
|
||||
return (
|
||||
<View style={{ margin: 10 }}>{knob.range ? this.renderRange() : this.renderNormal()}</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
NumberType.defaultProps = {
|
||||
knob: {},
|
||||
onChange: value => value,
|
||||
};
|
||||
|
||||
NumberType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.number,
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
NumberType.serialize = value => String(value);
|
||||
NumberType.deserialize = value => parseFloat(value);
|
||||
|
||||
export default NumberType;
|
95
addons/ondevice-knobs/src/types/Object.js
Normal file
95
addons/ondevice-knobs/src/types/Object.js
Normal file
@ -0,0 +1,95 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { TextInput } from 'react-native';
|
||||
import deepEqual from 'deep-equal';
|
||||
|
||||
const styles = {
|
||||
borderWidth: 1,
|
||||
borderColor: '#f7f4f4',
|
||||
borderRadius: 2,
|
||||
fontSize: 13,
|
||||
padding: 5,
|
||||
margin: 10,
|
||||
color: '#555',
|
||||
};
|
||||
|
||||
class ObjectType extends React.Component {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
getJSONString() {
|
||||
const { json, jsonString } = this.state;
|
||||
const { knob } = this.props;
|
||||
|
||||
// If there is an error in the JSON, we need to give that errored JSON.
|
||||
if (this.failed) return jsonString;
|
||||
|
||||
// If the editor value and the knob value is the same, we need to return the
|
||||
// editor value as it allow user to add new fields to the JSON.
|
||||
if (deepEqual(json, knob.value)) return jsonString;
|
||||
|
||||
// If the knob's value is different from the editor, it seems like
|
||||
// there's a outside change and we need to get that.
|
||||
return JSON.stringify(knob.value, null, 2);
|
||||
}
|
||||
|
||||
handleChange = value => {
|
||||
const { onChange } = this.props;
|
||||
const newState = {
|
||||
jsonString: value,
|
||||
};
|
||||
|
||||
try {
|
||||
newState.json = JSON.parse(value.trim());
|
||||
onChange(newState.json);
|
||||
this.failed = false;
|
||||
} catch (err) {
|
||||
this.failed = true;
|
||||
}
|
||||
|
||||
this.setState(newState);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { knob } = this.props;
|
||||
const jsonString = this.getJSONString();
|
||||
const extraStyle = {};
|
||||
|
||||
if (this.failed) {
|
||||
extraStyle.borderWidth = 1;
|
||||
extraStyle.borderColor = '#fadddd';
|
||||
extraStyle.backgroundColor = '#fff5f5';
|
||||
}
|
||||
|
||||
return (
|
||||
<TextInput
|
||||
id={knob.name}
|
||||
style={{ ...styles, ...extraStyle }}
|
||||
value={jsonString}
|
||||
onChangeText={this.handleChange}
|
||||
multiline
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectType.defaultProps = {
|
||||
knob: {},
|
||||
onChange: value => value,
|
||||
};
|
||||
|
||||
ObjectType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
ObjectType.serialize = object => JSON.stringify(object);
|
||||
ObjectType.deserialize = value => (value ? JSON.parse(value) : {});
|
||||
|
||||
export default ObjectType;
|
69
addons/ondevice-knobs/src/types/Select.js
Normal file
69
addons/ondevice-knobs/src/types/Select.js
Normal file
@ -0,0 +1,69 @@
|
||||
/* eslint no-underscore-dangle: 0 */
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import { View, TextInput } from 'react-native';
|
||||
import React from 'react';
|
||||
import ModalPicker from 'react-native-modal-selector';
|
||||
|
||||
class SelectType extends React.Component {
|
||||
getOptions = ({ options }) => {
|
||||
if (Array.isArray(options)) {
|
||||
return options.map(val => ({ key: val, label: val }));
|
||||
}
|
||||
|
||||
return Object.keys(options).map(key => ({ label: key, key: options[key] }));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { knob, onChange } = this.props;
|
||||
|
||||
const options = this.getOptions(knob);
|
||||
|
||||
const selected = options.filter(({ key }) => knob.value === key)[0].label;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<ModalPicker
|
||||
data={options}
|
||||
initValue={knob.value}
|
||||
onChange={option => onChange(option.key)}
|
||||
animationType="none"
|
||||
>
|
||||
<TextInput
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: '#f7f4f4',
|
||||
borderRadius: 2,
|
||||
padding: 5,
|
||||
color: '#555',
|
||||
margin: 10,
|
||||
}}
|
||||
editable={false}
|
||||
value={selected}
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
</ModalPicker>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SelectType.defaultProps = {
|
||||
knob: {},
|
||||
onChange: value => value,
|
||||
};
|
||||
|
||||
SelectType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
options: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
||||
selectV2: PropTypes.bool,
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
SelectType.serialize = value => value;
|
||||
SelectType.deserialize = value => value;
|
||||
|
||||
export default SelectType;
|
39
addons/ondevice-knobs/src/types/Text.js
Normal file
39
addons/ondevice-knobs/src/types/Text.js
Normal file
@ -0,0 +1,39 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { TextInput } from 'react-native';
|
||||
|
||||
const TextType = ({ knob, onChange }) => (
|
||||
<TextInput
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: '#f7f4f4',
|
||||
borderRadius: 2,
|
||||
fontSize: 13,
|
||||
padding: 5,
|
||||
margin: 10,
|
||||
color: '#555',
|
||||
}}
|
||||
id={knob.name}
|
||||
value={knob.value}
|
||||
onChangeText={onChange}
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
);
|
||||
|
||||
TextType.defaultProps = {
|
||||
knob: {},
|
||||
onChange: value => value,
|
||||
};
|
||||
|
||||
TextType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
TextType.serialize = value => value;
|
||||
TextType.deserialize = value => value;
|
||||
|
||||
export default TextType;
|
21
addons/ondevice-knobs/src/types/index.js
Normal file
21
addons/ondevice-knobs/src/types/index.js
Normal file
@ -0,0 +1,21 @@
|
||||
import TextType from './Text';
|
||||
import NumberType from './Number';
|
||||
import ColorType from './Color';
|
||||
import BooleanType from './Boolean';
|
||||
import ObjectType from './Object';
|
||||
import SelectType from './Select';
|
||||
import ArrayType from './Array';
|
||||
import DateType from './Date';
|
||||
import ButtonType from './Button';
|
||||
|
||||
export default {
|
||||
text: TextType,
|
||||
number: NumberType,
|
||||
color: ColorType,
|
||||
boolean: BooleanType,
|
||||
object: ObjectType,
|
||||
select: SelectType,
|
||||
array: ArrayType,
|
||||
date: DateType,
|
||||
button: ButtonType,
|
||||
};
|
48
addons/ondevice-notes/README.md
Normal file
48
addons/ondevice-notes/README.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Storybook Addon On Device Notes
|
||||
|
||||
Storybook Addon On Device Notes allows you to write notes (text or markdown) for your stories in [Storybook](https://storybook.js.org).
|
||||
|
||||
[Framework Support](https://github.com/storybooks/storybook/blob/master/ADDONS_SUPPORT.md)
|
||||
|
||||

|
||||
|
||||
### Getting Started
|
||||
**NOTE: Documentation on master branch is for alpha version, stable release is on [release/3.4](https://github.com/storybooks/storybook/tree/release/3.4/addons/)**
|
||||
|
||||
```sh
|
||||
yarn add -D @storybook/addon-ondevice-notes
|
||||
```
|
||||
|
||||
Then create a file called `rn-addons.js` in your storybook config.
|
||||
|
||||
Add following content to it:
|
||||
|
||||
```js
|
||||
import '@storybook/addon-ondevice-notes/register';
|
||||
```
|
||||
|
||||
Then import `rn-addons.js` next to your `getStorybookUI` call.
|
||||
```js
|
||||
import './rn-addons';
|
||||
```
|
||||
|
||||
Then add the `withNotes` decorator to all stories in your `config.js`:
|
||||
|
||||
```js
|
||||
// Import from @storybook/X where X is your framework
|
||||
import { addDecorator } from '@storybook/react-native';
|
||||
import { withNotes } from '@storybook/addon-ondevice-notes';
|
||||
|
||||
addDecorator(withNotes);
|
||||
```
|
||||
|
||||
You can use the `notes` parameter to add a note to each story:
|
||||
|
||||
```js
|
||||
import { storiesOf } from '@storybook/react-native';
|
||||
|
||||
import Component from './Component';
|
||||
|
||||
storiesOf('Component', module)
|
||||
.add('with some emoji', () => <Component />, { notes: 'A very simple component' });
|
||||
```
|
BIN
addons/ondevice-notes/docs/demo.png
Normal file
BIN
addons/ondevice-notes/docs/demo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 253 KiB |
32
addons/ondevice-notes/package.json
Normal file
32
addons/ondevice-notes/package.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "@storybook/addon-ondevice-notes",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "Write notes for your Storybook stories.",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"notes",
|
||||
"storybook"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/storybooks/storybook.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
"scripts": {
|
||||
"prepare": "node ../../scripts/prepare.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@storybook/addons": "4.0.0-rc.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-native-simple-markdown": "^1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
}
|
1
addons/ondevice-notes/register.js
Normal file
1
addons/ondevice-notes/register.js
Normal file
@ -0,0 +1 @@
|
||||
require('./dist/register.js');
|
42
addons/ondevice-notes/src/__tests__/index.js
Normal file
42
addons/ondevice-notes/src/__tests__/index.js
Normal file
@ -0,0 +1,42 @@
|
||||
import addons from '@storybook/addons';
|
||||
import { withNotes } from '..';
|
||||
|
||||
addons.getChannel = jest.fn();
|
||||
|
||||
describe('Storybook Addon Notes', () => {
|
||||
it('should inject text from `notes` parameter', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
|
||||
const getStory = jest.fn();
|
||||
const context = { parameters: { notes: 'hello' } };
|
||||
|
||||
withNotes(getStory, context);
|
||||
expect(channel.emit).toHaveBeenCalledWith('storybook/notes/add_notes', 'hello');
|
||||
expect(getStory).toHaveBeenCalledWith(context);
|
||||
});
|
||||
|
||||
it('should inject text even if no `notes` parameter is set to reset the addon', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
|
||||
const getStory = jest.fn();
|
||||
const context = {};
|
||||
|
||||
withNotes(getStory, context);
|
||||
expect(channel.emit).toHaveBeenCalled();
|
||||
expect(getStory).toHaveBeenCalledWith(context);
|
||||
});
|
||||
|
||||
it('should inject markdown from `notes.markdown` parameter', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
|
||||
const getStory = jest.fn();
|
||||
const context = { parameters: { notes: { markdown: '# hello' } } };
|
||||
|
||||
withNotes(getStory, context);
|
||||
expect(channel.emit).toHaveBeenCalledWith('storybook/notes/add_notes', '# hello');
|
||||
expect(getStory).toHaveBeenCalledWith(context);
|
||||
});
|
||||
});
|
34
addons/ondevice-notes/src/index.js
Normal file
34
addons/ondevice-notes/src/index.js
Normal file
@ -0,0 +1,34 @@
|
||||
import addons, { makeDecorator } from '@storybook/addons';
|
||||
|
||||
export const withNotes = makeDecorator({
|
||||
name: 'withNotes',
|
||||
parameterName: 'notes',
|
||||
wrapper: (getStory, context, { options, parameters }) => {
|
||||
const channel = addons.getChannel();
|
||||
|
||||
const storyOptions = parameters || options;
|
||||
|
||||
if (!storyOptions) {
|
||||
channel.emit('storybook/notes/add_notes', '');
|
||||
|
||||
return getStory(context);
|
||||
}
|
||||
|
||||
const { text, markdown } =
|
||||
typeof storyOptions === 'string' ? { text: storyOptions } : storyOptions;
|
||||
|
||||
if (!text && !markdown) {
|
||||
throw new Error('You must set of one of `text` or `markdown` on the `notes` parameter');
|
||||
}
|
||||
|
||||
channel.emit('storybook/notes/add_notes', text || markdown);
|
||||
|
||||
return getStory(context);
|
||||
},
|
||||
});
|
||||
|
||||
export const withMarkdownNotes = (text, options) =>
|
||||
withNotes({
|
||||
markdown: text,
|
||||
markdownOptions: options,
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user