Resolved merge conflict

This commit is contained in:
Neville Mehta 2018-04-28 16:32:12 -07:00
commit bb20d63db0
338 changed files with 10159 additions and 4509 deletions

View File

@ -46,21 +46,6 @@ jobs:
- addons
- app
- lib
danger:
<<: *defaults
environment:
- TOKEN_HEAD: 49aa9a6549007391dfcef9c76fca32a73560fd8
steps:
- checkout
- restore_cache:
name: "Restore core dependencies cache"
keys:
- core-dependencies-{{ checksum "yarn.lock" }}
- run:
name: "Danger"
command: |
echo $DANGER_GITHUB_API_TOKEN
DANGER_GITHUB_API_TOKEN=${TOKEN_HEAD}3 yarn danger ci
example-kitchen-sinks:
<<: *defaults
steps:
@ -106,10 +91,6 @@ jobs:
command: |
cd examples/mithril-kitchen-sink
yarn build-storybook
- run:
name: "Visually test storybook"
command: |
yarn chromatic
- run:
name: "Run image snapshots"
command: yarn test --image
@ -322,9 +303,6 @@ workflows:
build_accept_deploy:
jobs:
- build
- danger:
requires:
- build
- example-kitchen-sinks:
requires:
- build

View File

@ -10,5 +10,5 @@ Does this need an update to the documentation?
If your answer is yes to any of these, please make sure to include it in your PR.
Please tag your pull request with at least one of the following:
For maintainers only: Please tag your pull request with at least one of the following:
`["cleanup", "BREAKING CHANGE", "feature request", "bug", "documentation", "maintenance", "dependencies", "other"]`

1
.gitignore vendored
View File

@ -22,3 +22,4 @@ storybook-static
integration/__image_snapshots__/__diff_output__
.jest-test-results.json
/examples/cra-kitchen-sink/src/__image_snapshots__/__diff_output__/
lib/*.jar

View File

@ -0,0 +1,108 @@
package OpenSourceProjects_Storybook
import OpenSourceProjects_Storybook.buildTypes.*
import OpenSourceProjects_Storybook.vcsRoots.*
import OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster
import jetbrains.buildServer.configs.kotlin.v2017_2.*
import jetbrains.buildServer.configs.kotlin.v2017_2.Project
import jetbrains.buildServer.configs.kotlin.v2017_2.projectFeatures.VersionedSettings
import jetbrains.buildServer.configs.kotlin.v2017_2.projectFeatures.versionedSettings
object Project : Project({
uuid = "69382d9b-7791-418a-9ff6-1c83b86ed6b5"
id = "OpenSourceProjects_Storybook"
parentId = "OpenSourceProjects"
name = "Storybook"
description = "https://storybook.js.org/"
vcsRoot(OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster1)
vcsRoot(OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
buildType(OpenSourceProjects_Storybook_CliTestLatestCra)
buildType(OpenSourceProjects_Storybook_Examples)
buildType(OpenSourceProjects_Storybook_Danger)
buildType(OpenSourceProjects_Storybook_ReactNative)
buildType(OpenSourceProjects_Storybook_Docs)
buildType(OpenSourceProjects_Storybook_Build_2)
buildType(OpenSourceProjects_Storybook_CliTest)
buildType(OpenSourceProjects_Storybook_Test)
buildType(OpenSourceProjects_Storybook_Lint)
buildType(OpenSourceProjects_Storybook_SmokeTests)
buildType(OpenSourceProjects_Storybook_Chromatic)
allApps {
buildType(config)
}
features {
versionedSettings {
id = "PROJECT_EXT_258"
mode = VersionedSettings.Mode.ENABLED
buildSettingsMode = VersionedSettings.BuildSettingsMode.PREFER_SETTINGS_FROM_VCS
rootExtId = OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster.id
showChanges = true
settingsFormat = VersionedSettings.Format.KOTLIN
storeSecureParamsOutsideOfVcs = true
}
feature {
type = "buildtype-graphs"
id = "PROJECT_EXT_132"
param("series", """
[
{
"type": "valueType",
"title": "Build Duration (all stages)",
"key": "BuildDuration"
}
]
""".trimIndent())
param("format", "duration")
param("hideFilters", "")
param("title", "Build Duration")
param("defaultFilters", "")
param("seriesTitle", "Serie")
}
feature {
id = "PROJECT_EXT_259"
type = "IssueTracker"
param("secure:password", "")
param("name", "storybooks/storybook")
param("pattern", """#(\d+)""")
param("authType", "anonymous")
param("repository", "https://github.com/storybooks/storybook")
param("type", "GithubIssues")
param("secure:accessToken", "")
param("username", "")
}
allApps {
feature {
id = "PROJECT_EXT_264_$lowerName"
type = "ReportTab"
param("startPage", "$lowerName.zip!index.html")
param("title", appName)
param("type", "BuildReportTab")
}
}
feature {
id = "PROJECT_EXT_267"
type = "ReportTab"
param("startPage", "official.zip!index.html")
param("title", "Official")
param("type", "BuildReportTab")
}
feature {
type = "ReportTab"
id = "PROJECT_EXT_272"
param("startPage", "docs.zip!index.html")
param("title", "Docs")
param("type", "BuildReportTab")
}
feature {
type = "ReportTab"
id = "PROJECT_EXT_274"
param("startPage", "demo.zip!index.html")
param("title", "Demo")
param("type", "BuildReportTab")
}
}
})

View File

@ -0,0 +1,88 @@
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
enum class StorybookApp(val appName: String, val exampleDir: String, val merged: Boolean = true) {
CRA("CRA", "cra-kitchen-sink"),
VUE("Vue", "vue-kitchen-sink"),
ANGULAR("Angular", "angular-cli"),
POLYMER("Polymer", "polymer-cli"),
MITHRIL("Mithril", "mithril-kitchen-sink"),
HTML("HTML", "html-kitchen-sink", false);
val lowerName = appName.toLowerCase()
val artifactPath = "examples/$exampleDir/storybook-static => $lowerName.zip"
val config = object : BuildType(init@{
uuid = "8cc5f747-4ca7-4f0d-940d-b0c422f501a6-$lowerName"
id = "OpenSourceProjects_Storybook_$appName"
name = appName
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
}
if (!merged) return@init
artifactRules = artifactPath
steps {
script {
name = "Bootstrap"
scriptContent = """
yarn
yarn bootstrap --core
""".trimIndent()
dockerImage = "node:latest"
}
script {
name = "build"
scriptContent = """
#!/bin/sh
set -e -x
cd examples/$exampleDir
yarn build-storybook
""".trimIndent()
dockerImage = "node:latest"
}
}
failureConditions {
failOnMetricChange {
metric = BuildFailureOnMetric.MetricType.ARTIFACT_SIZE
threshold = 50
units = BuildFailureOnMetric.MetricUnit.PERCENTS
comparison = BuildFailureOnMetric.MetricComparison.LESS
compareTo = build {
buildRule = lastSuccessful()
}
}
}
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")
}
}) {}
}
fun allApps(handler: StorybookApp.() -> Unit) =
StorybookApp.values().forEach { it.handler() }

View File

@ -0,0 +1,99 @@
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.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.buildFeatures.merge
import jetbrains.buildServer.configs.kotlin.v2017_2.ui.*
object OpenSourceProjects_Storybook_Build_2 : BuildType({
uuid = "2b9c73e2-0a6e-47ca-95ae-729cac42be2b"
id = "OpenSourceProjects_Storybook_Build_2"
name = "Build"
allowExternalStatus = true
type = BuildTypeSettings.Type.COMPOSITE
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
showDependenciesChanges = true
}
triggers {
vcs {
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
triggerRules = "-:comment=^TeamCity change:**"
}
}
failureConditions {
failOnMetricChange {
metric = BuildFailureOnMetric.MetricType.TEST_COUNT
threshold = 20
units = BuildFailureOnMetric.MetricUnit.PERCENTS
comparison = BuildFailureOnMetric.MetricComparison.LESS
compareTo = build {
buildRule = lastSuccessful()
}
}
}
features {
commitStatusPublisher {
publisher = github {
githubUrl = "https://api.github.com"
authType = personalToken {
token = "credentialsJSON:5ffe2d7e-531e-4f6f-b1fc-a41bfea26eaa"
}
}
param("github_oauth_user", "Hypnosphi")
}
merge {
branchFilter = "+:dependencies.io-*"
destinationBranch = "<default>"
commitMessage = "Merge branch '%teamcity.build.branch%'"
}
}
dependencies {
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Docs) {
snapshot {
onDependencyCancel = FailureAction.ADD_PROBLEM
}
}
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Examples) {
snapshot {
onDependencyCancel = FailureAction.ADD_PROBLEM
}
}
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Lint) {
snapshot {
onDependencyCancel = FailureAction.ADD_PROBLEM
}
}
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_ReactNative) {
snapshot {
onDependencyCancel = FailureAction.ADD_PROBLEM
}
}
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_SmokeTests) {
snapshot {
onDependencyCancel = FailureAction.ADD_PROBLEM
}
}
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Test) {
snapshot {
onDependencyCancel = FailureAction.ADD_PROBLEM
}
}
dependency(OpenSourceProjects_Storybook.buildTypes.OpenSourceProjects_Storybook_Chromatic) {
snapshot {
onDependencyCancel = FailureAction.ADD_PROBLEM
}
}
}
})

View File

@ -0,0 +1,69 @@
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
object OpenSourceProjects_Storybook_Chromatic : BuildType({
uuid = "8cc5f747-4ca7-4f0d-940d-b0c422f501a6-chromatic"
id = "OpenSourceProjects_Storybook_Chromatic"
name = "Chromatic"
params {
param("env.CI_BRANCH", "%teamcity.build.branch%")
}
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
}
steps {
script {
name = "Bootstrap"
scriptContent = """
yarn
yarn bootstrap --core
""".trimIndent()
dockerImage = "node:latest"
}
script {
name = "Chromatic"
scriptContent = "yarn chromatic"
dockerImage = "node:latest"
}
}
features {
commitStatusPublisher {
publisher = github {
githubUrl = "https://api.github.com"
authType = personalToken {
token = "credentialsJSON:5ffe2d7e-531e-4f6f-b1fc-a41bfea26eaa"
}
}
param("github_oauth_user", "Hypnosphi")
}
}
dependencies {
allApps {
dependency(config) {
snapshot {}
if (merged) {
artifacts {
cleanDestination = true
artifactRules = "$lowerName.zip!** => examples/$exampleDir/storybook-static"
}
}
}
}
}
requirements {
doesNotContain("env.OS", "Windows")
}
})

View File

@ -0,0 +1,61 @@
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.VcsTrigger
object OpenSourceProjects_Storybook_CliTest : BuildType({
uuid = "b1db1a3a-a4cf-46ea-8f55-98b86611f92e"
id = "OpenSourceProjects_Storybook_CliTest"
name = "CLI test"
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
}
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"
}
}
triggers {
vcs {
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
triggerRules = "-:comment=^TeamCity change:**"
}
}
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)
}
})

View File

@ -0,0 +1,61 @@
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.VcsTrigger
object OpenSourceProjects_Storybook_CliTestLatestCra : BuildType({
uuid = "d4320bd8-6094-4dd6-9bed-e13d6f0d12e2"
id = "OpenSourceProjects_Storybook_CliTestLatestCra"
name = "CLI test, latest CRA"
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
}
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"
}
}
triggers {
vcs {
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
triggerRules = "-:comment=^TeamCity change:**"
}
}
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)
}
})

View File

@ -0,0 +1,68 @@
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.VcsTrigger
object OpenSourceProjects_Storybook_Danger : BuildType({
uuid = "759f0116-2f7d-4c03-8220-56e4ab03be3a"
id = "OpenSourceProjects_Storybook_Danger"
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%")
}
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster1)
buildDefaultBranch = false
}
steps {
script {
name = "Install"
scriptContent = "yarn"
dockerImage = "node:latest"
}
script {
name = "Danger"
scriptContent = "yarn danger ci"
dockerImage = "node:latest"
}
}
triggers {
vcs {
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
triggerRules = "-:comment=^TeamCity change:**"
branchFilter = """
+:*
-: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")
}
}
requirements {
doesNotContain("env.OS", "Windows")
}
cleanup {
artifacts(days = 1)
}
})

View File

@ -0,0 +1,64 @@
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"
id = "OpenSourceProjects_Storybook_Docs"
name = "Docs"
artifactRules = "docs/public => docs.zip"
params {
param("Deploy branch", "release/3.4")
}
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
}
steps {
script {
name = "Install"
workingDir = "docs"
scriptContent = "yarn install --frozen-lockfile"
dockerImage = "node:latest"
}
script {
name = "Build"
workingDir = "docs"
scriptContent = "yarn build"
dockerImage = "node:latest"
}
}
triggers {
vcs {
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)
}
})

View File

@ -0,0 +1,110 @@
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
object OpenSourceProjects_Storybook_Examples : BuildType({
uuid = "8cc5f747-4ca7-4f0d-940d-b0c422f501a6"
id = "OpenSourceProjects_Storybook_Examples"
name = "Examples"
artifactRules = """
${StorybookApp.values().map { it.artifactPath }.joinToString("\n")}
examples/official-storybook/storybook-static => official.zip
examples/official-storybook/image-snapshots/__image_snapshots__ => image-snapshots
""".trimIndent()
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
}
steps {
script {
name = "Bootstrap"
scriptContent = """
yarn
yarn bootstrap --core
""".trimIndent()
dockerImage = "node:latest"
}
script {
name = "official-storybook"
scriptContent = """
#!/bin/sh
set -e -x
cd examples/official-storybook
rm -rf storybook-static
yarn build-storybook
""".trimIndent()
dockerImage = "node:latest"
}
script {
name = "Image storyshots"
scriptContent = """
#!/bin/sh
set -e -x
# Workaround for https://github.com/GoogleChrome/puppeteer/issues/290
apt-get update
apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \
libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \
ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
yarn test --image --teamcity
""".trimIndent()
dockerImage = "node:8"
}
}
failureConditions {
failOnMetricChange {
metric = BuildFailureOnMetric.MetricType.ARTIFACT_SIZE
threshold = 50
units = BuildFailureOnMetric.MetricUnit.PERCENTS
comparison = BuildFailureOnMetric.MetricComparison.LESS
compareTo = build {
buildRule = lastSuccessful()
}
}
}
features {
commitStatusPublisher {
publisher = github {
githubUrl = "https://api.github.com"
authType = personalToken {
token = "credentialsJSON:5ffe2d7e-531e-4f6f-b1fc-a41bfea26eaa"
}
}
param("github_oauth_user", "Hypnosphi")
}
}
dependencies {
allApps {
dependency(config) {
snapshot {}
if (merged) {
artifacts {
cleanDestination = true
artifactRules = "$lowerName.zip!** => examples/$exampleDir/storybook-static"
}
}
}
}
}
requirements {
doesNotContain("env.OS", "Windows")
}
})

View File

@ -0,0 +1,59 @@
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_Lint : BuildType({
uuid = "42cfbb9a-f35b-4f96-afae-0b508927a737"
id = "OpenSourceProjects_Storybook_Lint"
name = "Lint"
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
}
steps {
script {
name = "Bootstrap"
scriptContent = """
yarn
yarn bootstrap --core --docs
""".trimIndent()
dockerImage = "node:latest"
}
script {
name = "Lint"
scriptContent = "yarn lint:ci"
dockerImage = "node:latest"
}
}
triggers {
vcs {
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)
}
})

View File

@ -0,0 +1,74 @@
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
object OpenSourceProjects_Storybook_ReactNative : BuildType({
uuid = "ac276912-df1a-44f1-8de2-056276193ce8"
id = "OpenSourceProjects_Storybook_ReactNative"
name = "React Native"
artifactRules = "examples/react-native-vanilla/coverage/lcov-report => coverage.zip"
params {
param("env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD", "true")
}
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
cleanCheckout = true
}
steps {
script {
name = "Bootstrap"
scriptContent = """
yarn
yarn bootstrap --core --reactnative --reactnativeapp
""".trimIndent()
dockerImage = "node:latest"
}
script {
name = "react-native-vanilla"
scriptContent = """
cd examples/react-native-vanilla
yarn storybook --smoke-test
""".trimIndent()
dockerImage = "node:latest"
}
script {
name = "crna-kitchen-sink"
scriptContent = """
cd examples/crna-kitchen-sink
yarn storybook --smoke-test
""".trimIndent()
dockerImage = "node:latest"
}
script {
name = "Test"
scriptContent = """
yarn test --reactnative --coverage --runInBand --teamcity
yarn coverage
""".trimIndent()
dockerImage = "node:latest"
}
}
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")
}
})

View File

@ -0,0 +1,62 @@
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:latest"
}
script {
name = "Lint"
scriptContent = "yarn lint"
dockerImage = "node:latest"
}
script {
name = "Test"
enabled = false
scriptContent = "yarn test"
dockerImage = "node:latest"
}
script {
name = "Build"
workingDir = "server"
scriptContent = "yarn build"
dockerImage = "node:latest"
}
script {
name = "Export"
workingDir = "demo"
scriptContent = "yarn export"
dockerImage = "node:latest"
}
}
triggers {
vcs {
}
}
requirements {
doesNotContain("env.OS", "Windows")
}
})

View File

@ -0,0 +1,71 @@
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
object OpenSourceProjects_Storybook_SmokeTests : BuildType({
uuid = "1ea2b5bd-28f6-44f5-8ab3-6c659ce8fbd6"
id = "OpenSourceProjects_Storybook_SmokeTests"
name = "Smoke tests"
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
}
steps {
script {
name = "Bootstrap"
scriptContent = """
yarn
yarn bootstrap --core
""".trimIndent()
dockerImage = "node:latest"
}
allApps {
if (merged) {
script {
name = appName
scriptContent = """
#!/bin/sh
set -e -x
cd examples/$exampleDir
yarn storybook --smoke-test
""".trimIndent()
dockerImage = "node:latest"
}
}
}
script {
name = "official-storybook"
scriptContent = """
#!/bin/sh
set -e -x
cd examples/official-storybook
yarn storybook --smoke-test
""".trimIndent()
dockerImage = "node:latest"
}
}
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")
}
})

View File

@ -0,0 +1,64 @@
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"
id = "OpenSourceProjects_Storybook_Test"
name = "Test"
artifactRules = "coverage/lcov-report => coverage.zip"
vcs {
root(OpenSourceProjects_Storybook.vcsRoots.OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster)
}
steps {
script {
name = "Bootstrap"
scriptContent = """
yarn
yarn bootstrap --core
""".trimIndent()
dockerImage = "node:latest"
}
script {
name = "Test"
scriptContent = """
yarn test --core --coverage --runInBand --teamcity
yarn coverage
""".trimIndent()
dockerImage = "node:latest"
}
}
triggers {
vcs {
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)
}
})

View File

@ -0,0 +1,35 @@
package OpenSourceProjects_Storybook
import jetbrains.buildServer.configs.kotlin.v2017_2.*
/*
The settings script is an entry point for defining a single
TeamCity project. TeamCity looks for the 'settings.kts' file in a
project directory and runs it if it's found, so the script name
shouldn't be changed and its package should be the same as the
project's id.
The script should contain a single call to the project() function
with a Project instance or an init function as an argument.
VcsRoots, BuildTypes, and Templates of this project must be
registered inside project using the vcsRoot(), buildType(), and
template() methods respectively.
Subprojects can be defined either in their own settings.kts or by
calling the subProjects() method in this project.
To debug settings scripts in command-line, run the
mvnDebug org.jetbrains.teamcity:teamcity-configs-maven-plugin:generate
command and attach your debugger to the port 8000.
To debug in IntelliJ Idea, open the 'Maven Projects' tool window (View ->
Tool Windows -> Maven Projects), find the generate task
node (Plugins -> teamcity-configs -> teamcity-configs:generate),
the 'Debug' option is available in the context menu for the task.
*/
version = "2017.2"
project(OpenSourceProjects_Storybook.Project)

View File

@ -0,0 +1,21 @@
package OpenSourceProjects_Storybook.vcsRoots
import jetbrains.buildServer.configs.kotlin.v2017_2.*
import jetbrains.buildServer.configs.kotlin.v2017_2.vcs.GitVcsRoot
object OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster : GitVcsRoot({
uuid = "cec03c4b-d52c-42a0-8e9e-53bde85d6b33"
id = "OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster"
name = "https://github.com/storybooks/storybook#refs/heads/master"
url = "git@github.com:storybooks/storybook.git"
branchSpec = """
+:refs/(pull/*)/head
+:refs/heads/(release/3.4)
+:refs/heads/(master)
+:refs/heads/(dependencies.io-*)
""".trimIndent()
authMethod = uploadedKey {
userName = "git"
uploadedKey = "Storybook bot"
}
})

View File

@ -0,0 +1,16 @@
package OpenSourceProjects_Storybook.vcsRoots
import jetbrains.buildServer.configs.kotlin.v2017_2.*
import jetbrains.buildServer.configs.kotlin.v2017_2.vcs.GitVcsRoot
object OpenSourceProjects_Storybook_HttpsGithubComStorybooksStorybookRefsHeadsMaster1 : GitVcsRoot({
uuid = "5cacf90a-381a-4c73-9aa3-57f6439b545e"
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"
}
})

View File

@ -0,0 +1,16 @@
package OpenSourceProjects_Storybook.vcsRoots
import jetbrains.buildServer.configs.kotlin.v2017_2.*
import jetbrains.buildServer.configs.kotlin.v2017_2.vcs.GitVcsRoot
object OpenSourceProjects_Storybook_SBNext : GitVcsRoot({
uuid = "f0bd8d49-0f6a-4859-9d26-d066af4b5d6d"
id = "OpenSourceProjects_Storybook_SBNext"
name = "SBNext"
url = "git@github.com:storybooks/SBNext.git"
branch = "refs/heads/POC-bundler"
authMethod = uploadedKey {
userName = "git"
uploadedKey = "Storybook bot"
}
})

104
.teamcity/pom.xml vendored Normal file
View File

@ -0,0 +1,104 @@
<?xml version="1.0"?>
<project>
<modelVersion>4.0.0</modelVersion>
<name>OpenSourceProjects_Storybook Config DSL Script</name>
<groupId>OpenSourceProjects_Storybook</groupId>
<artifactId>OpenSourceProjects_Storybook_dsl</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.jetbrains.teamcity</groupId>
<artifactId>configs-dsl-kotlin-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<repositories>
<repository>
<id>jetbrains-all</id>
<url>http://download.jetbrains.com/teamcity-repository</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>teamcity-server</id>
<url>https://teamcity.jetbrains.com/app/dsl-plugins-repository</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>JetBrains</id>
<url>http://download.jetbrains.com/teamcity-repository</url>
</pluginRepository>
</pluginRepositories>
<build>
<sourceDirectory>.</sourceDirectory>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<configuration/>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jetbrains.teamcity</groupId>
<artifactId>teamcity-configs-maven-plugin</artifactId>
<version>${teamcity.dsl.version}</version>
<configuration>
<format>kotlin</format>
<dstDir>target/generated-configs</dstDir>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jetbrains.teamcity</groupId>
<artifactId>configs-dsl-kotlin</artifactId>
<version>${teamcity.dsl.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.teamcity</groupId>
<artifactId>configs-dsl-kotlin-plugins</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-script-runtime</artifactId>
<version>${kotlin.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,3 +1,516 @@
# 4.0.0-alpha.4
2018-April-27
#### Breaking Changes
- Knobs: add escapeHTML option; use it by default in Vue, Angular, and Polymer [#3473](https://github.com/storybooks/storybook/pull/3473)
#### Features
- Added `actions` to addon-actions to create multiple actions [#3352](https://github.com/storybooks/storybook/pull/3352)
- Add excludedPropTypes as an option to info addon [#3468](https://github.com/storybooks/storybook/pull/3468)
- Addon-background: add Vue support [#3488](https://github.com/storybooks/storybook/pull/3488)
- Suppress verbose build output [#3487](https://github.com/storybooks/storybook/pull/3487)
- Provide a configuration option to limit the number of actions logged [#3447](https://github.com/storybooks/storybook/pull/3447)
- Add IStory interface. [#3482](https://github.com/storybooks/storybook/pull/3482)
- Add option to clear action logger [#3459](https://github.com/storybooks/storybook/pull/3459)
#### Bug Fixes
- Fix auto focus of searchbox [#3494](https://github.com/storybooks/storybook/pull/3494)
- Don't try to access the devtools hook if we are cross-origin [#3485](https://github.com/storybooks/storybook/pull/3485)
- Improve yarn detection [#3453](https://github.com/storybooks/storybook/pull/3453)
#### Maintenance
- Refactor error and "no preview" views into core [#3457](https://github.com/storybooks/storybook/pull/3457)
- Refactor templates into core [#3422](https://github.com/storybooks/storybook/pull/3422)
#### Dependency Upgrades
<details>
<summary>
15 Upgrades
</summary>
- Upgraded `@storybook/addon-actions` in `/docs` from "3.4.1" to "3.4.2" [#3478](https://github.com/storybooks/storybook/pull/3478)
- Upgraded `@storybook/addon-links` in `/docs` from "3.4.1" to "3.4.2" [#3478](https://github.com/storybooks/storybook/pull/3478)
- Upgraded `@storybook/addons` in `/docs` from "3.4.1" to "3.4.2" [#3478](https://github.com/storybooks/storybook/pull/3478)
- Upgraded `@storybook/react` in `/docs` from "3.4.1" to "3.4.2" [#3478](https://github.com/storybooks/storybook/pull/3478)
- Upgraded `gatsby-link` in `/docs` from "1.6.40" to "1.6.41" [#3478](https://github.com/storybooks/storybook/pull/3478)
- Upgraded `gatsby-plugin-sharp` in `/docs` from "1.6.42" to "1.6.43" [#3478](https://github.com/storybooks/storybook/pull/3478)
- Upgraded `gatsby-remark-autolink-headers` in `/docs` from "1.4.16" to "1.4.17" [#3478](https://github.com/storybooks/storybook/pull/3478)
- Upgraded `gatsby-remark-copy-linked-files` in `/docs` from "1.5.31" to "1.5.32" [#3478](https://github.com/storybooks/storybook/pull/3478)
- Upgraded `gatsby-remark-images` in `/docs` from "1.5.61" to "1.5.62" [#3478](https://github.com/storybooks/storybook/pull/3478)
- Upgraded `gatsby` in `/docs` from "1.9.252" to "1.9.253" [#3478](https://github.com/storybooks/storybook/pull/3478)
- Upgrade redux to 4.0.0 [#3470](https://github.com/storybooks/storybook/pull/3470)
- Upgrade sass-loader to 7.0.1 & stop bringing node-sass bin to each user [#3467](https://github.com/storybooks/storybook/pull/3467)
- Upgrate ts-node to 6.0.0 [#3460](https://github.com/storybooks/storybook/pull/3460)
- Upgrade to json5@1.0.1 [#3466](https://github.com/storybooks/storybook/pull/3466)
- Update webpack-hot-middleware to fix HMR [#3463](https://github.com/storybooks/storybook/pull/3463)
</details>
# 3.4.3
2018-April-27
#### Features
- Suppress verbose build output [#3487](https://github.com/storybooks/storybook/pull/3487)
#### Bug Fixes
- Improve yarn detection [#3453](https://github.com/storybooks/storybook/pull/3453)
- Don't try to access the devtools hook if we are cross-origin [#3485](https://github.com/storybooks/storybook/pull/3485)
#### Dependency Upgrades
- Update webpack-hot-middleware to fix HMR [#3463](https://github.com/storybooks/storybook/pull/3463)
# 4.0.0-alpha.3
2018-April-17
Also includes changes from 3.4.2
#### Features
- Mobile device view: toggling stories panel with ☰ button [#3337](https://github.com/storybooks/storybook/pull/3337)
- Add lit-html support [#3433](https://github.com/storybooks/storybook/pull/3433)
- Addon info prop options [#3428](https://github.com/storybooks/storybook/pull/3428)
- Use per-story parameters in Notes addon [#3373](https://github.com/storybooks/storybook/pull/3373)
#### Bug Fixes
- Fixed Duplicate declaration h [#3409](https://github.com/storybooks/storybook/pull/3409)
- Storyshots integrity tests options [#3418](https://github.com/storybooks/storybook/pull/3418)
- Debounce Knob input to improve performance, fix number Knob undefined/NaN [#3412](https://github.com/storybooks/storybook/pull/3412)
- Fix double quotes in prop table and add additional examples [#3401](https://github.com/storybooks/storybook/pull/3401)
#### Documentation
- doc(addon-jest): fix option name [#3420](https://github.com/storybooks/storybook/pull/3420)
- Storyshots integrity tests fixes - README [#3419](https://github.com/storybooks/storybook/pull/3419)
#### Maintenance
- viewport-addon: configure => configureViewport [#3414](https://github.com/storybooks/storybook/pull/3414)
#### Dependency Upgrades
<details>
<summary>
94 Upgrades
</summary>
- Upgraded `chalk` in `/` from "2.3.2" to "2.4.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `danger` in `/` from "3.4.7" to "3.5.1" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `prettier` in `/` from "1.12.0" to "1.12.1" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `app/react` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `prettier` in `addons/storysource` from "1.12.0" to "1.12.1" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `react-modal` in `lib/ui` from "3.3.2" to "3.4.1" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `chalk` in `lib/core` from "2.3.2" to "2.4.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `lib/core` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `app/angular` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `app/mithril` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `app/polymer` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `app/react-native` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `app/vue` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `chalk` in `lib/cli` from "2.3.2" to "2.4.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `examples/cra-kitchen-sink` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `examples/mithril-kitchen-sink` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `examples/polymer-cli` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `webpack` in `examples/vue-kitchen-sink` from "4.5.0" to "4.6.0" [#3440](https://github.com/storybooks/storybook/pull/3440)
- Upgraded `gatsby-source-filesystem` in `/docs` from "1.5.32" to "1.5.33" [#3439](https://github.com/storybooks/storybook/pull/3439)
- Upgraded `gatsby` in `/docs` from "1.9.251" to "1.9.252" [#3439](https://github.com/storybooks/storybook/pull/3439)
- Update lerna in / from 2.10.1 to 2.10.2 [#3431](https://github.com/storybooks/storybook/pull/3431)
- Update gatsby in /docs from 1.9.250 to 1.9.251 [#3430](https://github.com/storybooks/storybook/pull/3430)
- Upgraded `@angular/common` in `/` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/compiler` in `/` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/core` in `/` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/forms` in `/` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/platform-browser` in `/` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/platform-browser-dynamic` in `/` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `babel-eslint` in `/` from "8.2.2" to "8.2.3" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `danger` in `/` from "3.4.5" to "3.4.7" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `eslint-plugin-import` in `/` from "2.10.0" to "2.11.0" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `lerna` in `/` from "2.10.0" to "2.10.1" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `prettier` in `/` from "1.11.1" to "1.12.0" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react` in `/` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-dom` in `/` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-test-renderer` in `/` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-dom` in `addons/centered` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-lifecycles-compat` in `addons/background` from "3.0.0" to "3.0.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-lifecycles-compat` in `addons/events` from "3.0.0" to "3.0.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `glamorous` in `app/react` from "4.12.1" to "4.12.3" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@types/react` in `addons/notes` from "16.3.5" to "16.3.11" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `glamorous` in `addons/actions` from "4.12.1" to "4.12.3" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-inspector` in `addons/actions` from "2.2.2" to "2.3.0" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `glamorous` in `lib/components` from "4.12.1" to "4.12.3" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `glamorous` in `addons/a11y` from "4.12.1" to "4.12.3" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `glamorous` in `addons/info` from "4.12.1" to "4.12.3" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-lifecycles-compat` in `addons/info` from "3.0.0" to "3.0.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-test-renderer` in `addons/info` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `glamorous` in `addons/jest` from "4.12.1" to "4.12.3" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `moment` in `addons/knobs` from "2.22.0" to "2.22.1" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-color` in `addons/knobs` from "2.14.0" to "2.14.1" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-lifecycles-compat` in `addons/knobs` from "3.0.0" to "3.0.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react` in `addons/links` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-dom` in `addons/links` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `prettier` in `addons/storysource` from "1.11.1" to "1.12.0" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-lifecycles-compat` in `lib/ui` from "3.0.0" to "3.0.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `autoprefixer` in `lib/core` from "8.2.0" to "8.3.0" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `postcss-loader` in `lib/core` from "2.1.3" to "2.1.4" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `puppeteer` in `addons/storyshots` from "1.2.0" to "1.3.0" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react` in `addons/storyshots` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-dom` in `addons/storyshots` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react` in `app/angular` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-dom` in `app/angular` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react` in `app/mithril` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-dom` in `app/mithril` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react` in `app/polymer` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-dom` in `app/polymer` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react` in `app/vue` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-dom` in `app/vue` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `update-notifier` in `lib/cli` from "2.4.0" to "2.5.0" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `npx` in `lib/cli` from "10.0.1" to "10.2.0" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/common` in `examples/angular-cli` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/compiler` in `examples/angular-cli` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/core` in `examples/angular-cli` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/forms` in `examples/angular-cli` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/platform-browser` in `examples/angular-cli` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/platform-browser-dynamic` in `examples/angular-cli` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `rxjs` in `examples/angular-cli` from "5.5.8" to "5.5.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@angular/compiler-cli` in `examples/angular-cli` from "5.2.9" to "5.2.10" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@types/node` in `examples/angular-cli` from "9.6.2" to "9.6.5" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react` in `examples/cra-kitchen-sink` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-dom` in `examples/cra-kitchen-sink` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-lifecycles-compat` in `examples/cra-kitchen-sink` from "3.0.0" to "3.0.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react` in `examples/official-storybook` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `react-dom` in `examples/official-storybook` from "16.3.1" to "16.3.2" [#3429](https://github.com/storybooks/storybook/pull/3429)
- Upgraded `@storybook/addon-actions` in `/docs` from "3.4.0" to "3.4.1" [#3426](https://github.com/storybooks/storybook/pull/3426)
- Upgraded `@storybook/addon-links` in `/docs` from "3.4.0" to "3.4.1" [#3426](https://github.com/storybooks/storybook/pull/3426)
- Upgraded `@storybook/addons` in `/docs` from "3.4.0" to "3.4.1" [#3426](https://github.com/storybooks/storybook/pull/3426)
- Upgraded `@storybook/react` in `/docs` from "3.4.0" to "3.4.1" [#3426](https://github.com/storybooks/storybook/pull/3426)
- Upgraded `gatsby-plugin-sharp` in `/docs` from "1.6.41" to "1.6.42" [#3426](https://github.com/storybooks/storybook/pull/3426)
- Upgraded `gatsby-remark-images` in `/docs` from "1.5.60" to "1.5.61" [#3426](https://github.com/storybooks/storybook/pull/3426)
- Upgraded `gatsby-source-filesystem` in `/docs` from "1.5.29" to "1.5.32" [#3426](https://github.com/storybooks/storybook/pull/3426)
- Upgraded `gatsby-transformer-remark` in `/docs` from "1.7.39" to "1.7.40" [#3426](https://github.com/storybooks/storybook/pull/3426)
- Upgraded `gatsby` in `/docs` from "1.9.247" to "1.9.250" [#3426](https://github.com/storybooks/storybook/pull/3426)
</details>
# 3.4.2
2018-April-17
#### Bug Fixes
- Serialize boolean type only for non-nullable values [#3432](https://github.com/storybooks/storybook/pull/3432)
- Addon actions: fix slow logging [#3133](https://github.com/storybooks/storybook/pull/3133)
#### Documentation
- Fix storyshots readme for image snapshotting [#3397](https://github.com/storybooks/storybook/pull/3397)
# 4.0.0-alpha.2
2018-April-10
Also includes changes from 3.4.1
#### Breaking Changes
- Change addon panel keyboard shortcut to shift-meta-z [#3378](https://github.com/storybooks/storybook/pull/3378)
- Move server/config to core [#3261](https://github.com/storybooks/storybook/pull/3261)
#### Features
- React native Typescript transform [#3209](https://github.com/storybooks/storybook/pull/3209)
- Split vendor and runtime chunk in static builds [#3316](https://github.com/storybooks/storybook/pull/3316)
- Persist background for @addon/background [#3331](https://github.com/storybooks/storybook/pull/3331)
- feat(notes): add marked options [#3225](https://github.com/storybooks/storybook/pull/3225)
#### Bug Fixes
- Enforce addons store being a singleton by storing it in global variable [#3383](https://github.com/storybooks/storybook/pull/3383)
- Scroll to top of the page when changing story [#3338](https://github.com/storybooks/storybook/pull/3338)
- Fix HtmlWebpackPlugin error [#3328](https://github.com/storybooks/storybook/pull/3328)
#### Maintenance
- Remove usages of deprecated React lifecycle methods [#3327](https://github.com/storybooks/storybook/pull/3327)
#### Dependency Upgrades
<details>
<summary>
142 Updates
</summary>
- Migrate to react-lifecycles-compat@3 [#3392](https://github.com/storybooks/storybook/pull/3392)
- Upgrade dev dependencies in Angular example [#3391](https://github.com/storybooks/storybook/pull/3391)
- Upgraded `gatsby-remark-copy-linked-files` in `/docs` from "1.5.30" to "1.5.31" [#3388](https://github.com/storybooks/storybook/pull/3388)
- Upgraded `gatsby-source-filesystem` in `/docs` from "1.5.28" to "1.5.29" [#3388](https://github.com/storybooks/storybook/pull/3388)
- Upgraded `gatsby` in `/docs` from "1.9.246" to "1.9.247" [#3388](https://github.com/storybooks/storybook/pull/3388)
- Upgraded `lerna` in `/` from "2.9.1" to "2.10.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `babel-preset-minify` in `app/react` from "0.3.0" to "0.4.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `core-js` in `app/react` from "2.5.4" to "2.5.5" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-hot-middleware` in `app/react` from "2.21.2" to "2.22.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-dev-middleware` in `lib/core` from "3.1.1" to "3.1.2" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-hot-middleware` in `lib/core` from "2.21.2" to "2.22.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `core-js` in `app/angular` from "2.5.4" to "2.5.5" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `ts-loader` in `app/angular` from "4.1.0" to "4.2.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-hot-middleware` in `app/angular` from "2.21.2" to "2.22.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `zone.js` in `app/angular` from "0.8.25" to "0.8.26" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `babel-preset-minify` in `app/mithril` from "0.3.0" to "0.4.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `core-js` in `app/mithril` from "2.5.4" to "2.5.5" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-hot-middleware` in `app/mithril` from "2.21.2" to "2.22.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `@webcomponents/webcomponentsjs` in `app/polymer` from "1.1.1" to "1.2.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `babel-preset-minify` in `app/polymer` from "0.3.0" to "0.4.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `core-js` in `app/polymer` from "2.5.4" to "2.5.5" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-hot-middleware` in `app/polymer` from "2.21.2" to "2.22.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `babel-preset-minify` in `app/react-native` from "0.3.0" to "0.4.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `url-parse` in `app/react-native` from "1.2.0" to "1.3.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-dev-middleware` in `app/react-native` from "3.1.1" to "3.1.2" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-hot-middleware` in `app/react-native` from "2.21.2" to "2.22.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `babel-preset-minify` in `app/vue` from "0.3.0" to "0.4.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `core-js` in `app/vue` from "2.5.4" to "2.5.5" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-hot-middleware` in `app/vue` from "2.21.2" to "2.22.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `core-js` in `examples/angular-cli` from "2.5.4" to "2.5.5" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `zone.js` in `examples/angular-cli` from "0.8.25" to "0.8.26" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `@angular/cli` in `examples/angular-cli` from "1.7.3" to "1.7.4" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `@webcomponents/webcomponentsjs` in `examples/polymer-cli` from "1.1.1" to "1.2.0" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-dev-server` in `examples/polymer-cli` from "3.1.1" to "3.1.3" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `webpack-dev-server` in `examples/vue-kitchen-sink` from "3.1.1" to "3.1.3" [#3387](https://github.com/storybooks/storybook/pull/3387)
- Upgraded `lint-staged` in `/` from "7.0.3" to "7.0.4" [#3368](https://github.com/storybooks/storybook/pull/3368)
- Upgraded `webpack-dev-middleware` in `lib/core` from "3.1.0" to "3.1.1" [#3368](https://github.com/storybooks/storybook/pull/3368)
- Upgraded `webpack-dev-middleware` in `app/react-native` from "3.1.0" to "3.1.1" [#3368](https://github.com/storybooks/storybook/pull/3368)
- Upgraded `react` in `/` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-dom` in `/` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-test-renderer` in `/` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-dom` in `addons/centered` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `app/react` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `@types/react` in `addons/notes` from "16.3.4" to "16.3.5" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-test-renderer` in `addons/info` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react` in `addons/links` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-dom` in `addons/links` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `lib/core` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react` in `addons/storyshots` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-dom` in `addons/storyshots` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react` in `app/angular` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-dom` in `app/angular` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `app/angular` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `zone.js` in `app/angular` from "0.8.24" to "0.8.25" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react` in `app/mithril` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-dom` in `app/mithril` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `app/mithril` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react` in `app/polymer` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-dom` in `app/polymer` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `app/polymer` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `app/react-native` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react` in `app/vue` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-dom` in `app/vue` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `app/vue` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `zone.js` in `examples/angular-cli` from "0.8.24" to "0.8.25" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `protractor` in `examples/angular-cli` from "5.3.0" to "5.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react` in `examples/cra-kitchen-sink` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-dom` in `examples/cra-kitchen-sink` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-scripts` in `examples/cra-kitchen-sink` from "1.1.3" to "1.1.4" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `examples/cra-kitchen-sink` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `examples/mithril-kitchen-sink` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `examples/polymer-cli` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `webpack` in `examples/vue-kitchen-sink` from "4.4.1" to "4.5.0" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react` in `examples/official-storybook` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `react-dom` in `examples/official-storybook` from "16.3.0" to "16.3.1" [#3357](https://github.com/storybooks/storybook/pull/3357)
- Upgraded `gatsby-remark-autolink-headers` in `/docs` from "1.4.15" to "1.4.16" [#3356](https://github.com/storybooks/storybook/pull/3356)
- Upgraded `gatsby` in `/docs` from "1.9.244" to "1.9.246" [#3356](https://github.com/storybooks/storybook/pull/3356)
- Upgraded `danger` in `/` from "3.4.4" to "3.4.5" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `lint-staged` in `/` from "7.0.2" to "7.0.3" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `react-lifecycles-compat` in `addons/background` from "1.1.1" to "1.1.4" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `react-lifecycles-compat` in `addons/events` from "1.1.1" to "1.1.4" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `html-webpack-plugin` in `app/react` from "3.1.0" to "3.2.0" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `@types/react` in `addons/notes` from "16.3.1" to "16.3.4" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `axe-core` in `addons/a11y` from "3.0.0" to "3.0.1" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `react-lifecycles-compat` in `addons/info` from "1.1.1" to "1.1.4" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `react-lifecycles-compat` in `addons/knobs` from "1.1.1" to "1.1.4" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `react-lifecycles-compat` in `lib/ui` from "1.1.1" to "1.1.4" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `html-webpack-plugin` in `app/angular` from "3.1.0" to "3.2.0" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `html-webpack-plugin` in `app/mithril` from "3.1.0" to "3.2.0" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `html-webpack-plugin` in `app/polymer` from "3.1.0" to "3.2.0" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `html-webpack-plugin` in `app/react-native` from "3.1.0" to "3.2.0" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `html-webpack-plugin` in `app/vue` from "3.1.0" to "3.2.0" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `@types/node` in `examples/angular-cli` from "9.6.1" to "9.6.2" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `react-lifecycles-compat` in `examples/cra-kitchen-sink` from "1.1.1" to "1.1.4" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `react-scripts` in `examples/cra-kitchen-sink` from "1.1.1" to "1.1.3" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Upgraded `html-webpack-plugin` in `examples/polymer-cli` from "3.1.0" to "3.2.0" [#3350](https://github.com/storybooks/storybook/pull/3350)
- Update gatsby-source-filesystem in /docs from 1.5.27 to 1.5.28 [#3349](https://github.com/storybooks/storybook/pull/3349)
- Update gatsby in /docs from 1.9.243 to 1.9.244 [#3345](https://github.com/storybooks/storybook/pull/3345)
- Upgraded `danger` in `/` from "3.3.2" to "3.4.4" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `eslint-plugin-import` in `/` from "2.9.0" to "2.10.0" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `lerna` in `/` from "2.5.1" to "2.9.1" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `lint-staged` in `/` from "7.0.0" to "7.0.2" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `react-lifecycles-compat` in `addons/background` from "1.1.0" to "1.1.1" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `react-lifecycles-compat` in `addons/events` from "1.1.0" to "1.1.1" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `react-textarea-autosize` in `addons/events` from "6.1.0-0" to "6.1.0" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `babel-plugin-react-docgen` in `app/react` from "1.8.3" to "1.9.0" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `nodemon` in `app/react` from "1.17.2" to "1.17.3" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `@types/react` in `addons/notes` from "16.1.0" to "16.3.1" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `react-lifecycles-compat` in `addons/info` from "1.1.0" to "1.1.1" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `moment` in `addons/knobs` from "2.21.0" to "2.22.0" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `react-lifecycles-compat` in `addons/knobs` from "1.1.0" to "1.1.1" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `react-textarea-autosize` in `addons/knobs` from "6.1.0-0" to "6.1.0" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `react-lifecycles-compat` in `lib/ui` from "1.1.0" to "1.1.1" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `serve-favicon` in `lib/core` from "2.4.5" to "2.5.0" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `zone.js` in `app/angular` from "0.8.20" to "0.8.24" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `nodemon` in `app/angular` from "1.17.2" to "1.17.3" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `nodemon` in `app/mithril` from "1.17.2" to "1.17.3" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `nodemon` in `app/polymer` from "1.17.2" to "1.17.3" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `ws` in `app/react-native` from "5.1.0" to "5.1.1" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `nodemon` in `app/vue` from "1.17.2" to "1.17.3" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `react-lifecycles-compat` in `examples/cra-kitchen-sink` from "1.1.0" to "1.1.1" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Upgraded `zone.js` in `examples/angular-cli` from "0.8.20" to "0.8.24" [#3343](https://github.com/storybooks/storybook/pull/3343)
- Migrate to axe-core@3.0.0 [#3332](https://github.com/storybooks/storybook/pull/3332)
- Migrate to ws@5 [#3334](https://github.com/storybooks/storybook/pull/3334)
- Upgraded `@storybook/addon-actions` in `/docs` from "3.3.15" to "3.4.0" [#3325](https://github.com/storybooks/storybook/pull/3325)
- Upgraded `@storybook/addon-links` in `/docs` from "3.3.15" to "3.4.0" [#3325](https://github.com/storybooks/storybook/pull/3325)
- Upgraded `@storybook/addons` in `/docs` from "3.3.15" to "3.4.0" [#3325](https://github.com/storybooks/storybook/pull/3325)
- Upgraded `@storybook/react` in `/docs` from "3.3.15" to "3.4.0" [#3325](https://github.com/storybooks/storybook/pull/3325)
- Update gatsby-remark-autolink-headers in /docs from 1.4.13 to 1.4.15 [#3314](https://github.com/storybooks/storybook/pull/3314)
- Upgraded `webpack` in `app/react` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `webpack` in `lib/core` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `webpack` in `app/angular` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `webpack` in `app/mithril` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `webpack` in `app/polymer` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `webpack` in `app/react-native` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `webpack` in `app/vue` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `webpack` in `examples/cra-kitchen-sink` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `@types/node` in `examples/angular-cli` from "9.6.0" to "9.6.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `webpack` in `examples/mithril-kitchen-sink` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `webpack` in `examples/polymer-cli` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Upgraded `webpack` in `examples/vue-kitchen-sink` from "4.3.0" to "4.4.1" [#3315](https://github.com/storybooks/storybook/pull/3315)
- Add babel-core dev-deps [#3319](https://github.com/storybooks/storybook/pull/3319)
</details>
# 3.4.1
2018-April-10
#### Features
- Make storybook addons channel available globally in `window` [#3243](https://github.com/storybooks/storybook/pull/3243)
#### Bug Fixes
- Scroll preview pane for non-percentage heights [#3342](https://github.com/storybooks/storybook/pull/3342)
- Replacing Report Fragment with div [#3372](https://github.com/storybooks/storybook/pull/3372)
- Don't use direct react dependency in core [#3382](https://github.com/storybooks/storybook/pull/3382)
#### Documentation
- Add typescript docs [#3361](https://github.com/storybooks/storybook/pull/3361)
- Update links of the live examples for the new release [#3197](https://github.com/storybooks/storybook/pull/3197)
# 3.4.0
2018-March-30
Welcome to Storybook 3.4 with the following key improvements:
- Polymer 2 support [#2225](https://github.com/storybooks/storybook/pull/2225)
- Angular and Vue storyshots [#2564](https://github.com/storybooks/storybook/pull/2564)
- Add image snapshots to addon-storyshots [#2413](https://github.com/storybooks/storybook/pull/2413)
- Multiple story hierarchies [#2452](https://github.com/storybooks/storybook/pull/2452)
- Addon-storysource: story source in addon pane [#2885](https://github.com/storybooks/storybook/pull/2885)
Read on for more improvements, fixes, 1In addition, there are hundreds of dependency upgrades in the 3.4 release, so to see the details, please see the changelogs for `3.4.0-rc.*` and `3.4.0-alpha.*`.
#### Features
- Bind window access if `window` is defined; add `addons channel` access too [#3243](https://github.com/storybooks/storybook/pull/3243)
- Fix screenshots tests & add getScreenshotOption to storyshots [#3102](https://github.com/storybooks/storybook/pull/3102)
- Add `__STORYBOOK_CLIENT_API__` for external tools [#3058](https://github.com/storybooks/storybook/pull/3058)
- Addon storysource: select stories from inside of the StoryPanel [#3154](https://github.com/storybooks/storybook/pull/3154)
- Storyshots: env.NODE_PATH support [#2873](https://github.com/storybooks/storybook/pull/2873)
- Knobs: Select knob key/value ordering [#1745](https://github.com/storybooks/storybook/pull/1745)
- Angular: Add option to pass custom styles for ng components [#2856](https://github.com/storybooks/storybook/pull/2856)
- Core: Add watch mode for build-storybook [#2866](https://github.com/storybooks/storybook/pull/2866)
- Core: Add `__dirname` support [#2791](https://github.com/storybooks/storybook/pull/2791)
- Pass default webpack config as third argument in Full Control Mode [#2796](https://github.com/storybooks/storybook/pull/2796)
- Angular and Vue storyshots [#2564](https://github.com/storybooks/storybook/pull/2564)
- Addon-info: Added "Copy button" for code example [#2713](https://github.com/storybooks/storybook/pull/2713)
- Angular: Serve styles and assets using .angular-cli webpack configuration [#2735](https://github.com/storybooks/storybook/pull/2735)
- API: Added an event that is emitted when a channel is created. [#2711](https://github.com/storybooks/storybook/pull/2711)
- Addon-a11y: Handle components with delayed rendering [#2651](https://github.com/storybooks/storybook/pull/2651)
- Polymer 2 support [#2225](https://github.com/storybooks/storybook/pull/2225)
- Add image snapshots to addon-storyshots [#2413](https://github.com/storybooks/storybook/pull/2413)
- Angular template support for Storybook [#2690](https://github.com/storybooks/storybook/pull/2690)
- Custom tsconfig.json for angular apps. [#2669](https://github.com/storybooks/storybook/pull/2669)
- Multiple story hierarchies [#2452](https://github.com/storybooks/storybook/pull/2452)
- Change template story files extension to .ts [#2594](https://github.com/storybooks/storybook/pull/2594)
- Use store revisions to ensure that stories re-render on HMR. [#2605](https://github.com/storybooks/storybook/pull/2605)
- Ability to force re-render a story [#2463](https://github.com/storybooks/storybook/pull/2463)
- Introduce framework-independent core library [#2241](https://github.com/storybooks/storybook/pull/2241)
#### Bug Fixes
- [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)
- Object proptype is shown in addon-info proptable [#3255](https://github.com/storybooks/storybook/pull/3255)
- Fix storyshots renderer and serializer options [#3252](https://github.com/storybooks/storybook/pull/3252)
- Angular: use resolveLoader from cliCommonConfig [#3251](https://github.com/storybooks/storybook/pull/3251)
- Delaying update of height and width in Layout [#3180](https://github.com/storybooks/storybook/pull/3180)
- Add 'waitUntil' option to puppeteer of storyshots [#3156](https://github.com/storybooks/storybook/pull/3156)
- Move polymer loader to peerDependencies [#3161](https://github.com/storybooks/storybook/pull/3161)
- Addons: avoid mixing manager and preview code together [#3068](https://github.com/storybooks/storybook/pull/3068)
- React-Native: Fix by moving managerPath export to `server.js` [#2947](https://github.com/storybooks/storybook/pull/2947)
- Addon-Info: Add type check to PropType on OneOf [#2653](https://github.com/storybooks/storybook/pull/2653)
- Vue: Support .vue extension resolving [#2896](https://github.com/storybooks/storybook/pull/2896)
- UI: remove zero on story loading [#2857](https://github.com/storybooks/storybook/pull/2857)
- Angular: remove entryComponents prop from metadata [#2790](https://github.com/storybooks/storybook/pull/2790)
- Use process.exitCode instead of process.exit() [#2717](https://github.com/storybooks/storybook/pull/2717)
- Angular: knobs with template [#2766](https://github.com/storybooks/storybook/pull/2766)
- Remove polymer-cli dependency [#2741](https://github.com/storybooks/storybook/pull/2741)
- Add scss for components in angular apps by default. [#2703](https://github.com/storybooks/storybook/pull/2703)
#### Documentation
- Add example for @ngrx/store [#3233](https://github.com/storybooks/storybook/pull/3233)
- Fix missing declaration in Angular example [#3213](https://github.com/storybooks/storybook/pull/3213)
- Update ADDONS_SUPPORT.md [#3114](https://github.com/storybooks/storybook/pull/3114)
- StoryShots: Document ref mocking [#2869](https://github.com/storybooks/storybook/pull/2869)
- Extending webpack section is no longer needed for the common usage [#2826](https://github.com/storybooks/storybook/pull/2826)
- Updating Vue Jest Config [#2821](https://github.com/storybooks/storybook/pull/2821)
- Angular inheritance example [#2787](https://github.com/storybooks/storybook/pull/2787)
- Revisit addon/framework support [#3046](https://github.com/storybooks/storybook/pull/3046)
- Docs live examples [#3019](https://github.com/storybooks/storybook/pull/3019)
- Mention new supported frameworks [#2895](https://github.com/storybooks/storybook/pull/2895)
- Update writing addons documentation [#2951](https://github.com/storybooks/storybook/pull/2951)
- Update docs on LinkTo in addon-links [#2926](https://github.com/storybooks/storybook/pull/2926)
#### Maintenance
- Fix errors on starting example Angular app [#3078](https://github.com/storybooks/storybook/pull/3078)
- Use WatchMissingNodeModulesPlugin from react-dev-utils package [#3141](https://github.com/storybooks/storybook/pull/3141)
- Don't use exact versions in peerDependencies [#3073](https://github.com/storybooks/storybook/pull/3073)
- Remove integration tests [#3052](https://github.com/storybooks/storybook/pull/3052)
- Fix "dev" script to be cross-platform [#2922](https://github.com/storybooks/storybook/pull/2922)
- Typescript distribution [#2846](https://github.com/storybooks/storybook/pull/2846)
- Use UTC timezone in formatting too for knobs test [#2861](https://github.com/storybooks/storybook/pull/2861)
- ADD autolabeler.yml for <https://github.com/probot/autolabeler> [#2809](https://github.com/storybooks/storybook/pull/2809)
- Fix css warning in angular-cli example [#2789](https://github.com/storybooks/storybook/pull/2789)
- Move more things to core [#2788](https://github.com/storybooks/storybook/pull/2788)
- Change ng stories dir [#2672](https://github.com/storybooks/storybook/pull/2672)
- Only update CLI snapsots on postpublish script, skip smoke tests [#2671](https://github.com/storybooks/storybook/pull/2671)
- Fix the timezone for example dates [#2654](https://github.com/storybooks/storybook/pull/2654)
- Update prereq yarn install level [#2638](https://github.com/storybooks/storybook/pull/2638)
- Separate stories in angular-cli example [#2592](https://github.com/storybooks/storybook/pull/2592)
# 4.0.0-alpha.1
2018-March-29
@ -115,199 +628,6 @@
- Update gatsby in /docs from 1.9.236 to 1.9.238 [#3249](https://github.com/storybooks/storybook/pull/3249)
</details>
# 3.4.0
2018-March-30
Welcome to Storybook 3.4 with the following key improvements:
- Polymer 2 support [#2225](https://github.com/storybooks/storybook/pull/2225)
- Angular and Vue storyshots [#2564](https://github.com/storybooks/storybook/pull/2564)
- Add image snapshots to addon-storyshots [#2413](https://github.com/storybooks/storybook/pull/2413)
- Multiple story hierarchies [#2452](https://github.com/storybooks/storybook/pull/2452)
- Addon-storysource: story source in addon pane [#2885](https://github.com/storybooks/storybook/pull/2885)
Read on for more improvements, fixes, 1In addition, there are hundreds of dependency upgrades in the 3.4 release, so to see the details, please see the changelogs for `3.4.0-rc.*` and `3.4.0-alpha.*`.
#### Features
- Bind window access if `window` is defined; add `addons channel` access too [#3243](https://github.com/storybooks/storybook/pull/3243)
- Fix screenshots tests & add getScreenshotOption to storyshots [#3102](https://github.com/storybooks/storybook/pull/3102)
- Add `__STORYBOOK_CLIENT_API__` for external tools [#3058](https://github.com/storybooks/storybook/pull/3058)
- Addon storysource: select stories from inside of the StoryPanel [#3154](https://github.com/storybooks/storybook/pull/3154)
- Storyshots: env.NODE_PATH support [#2873](https://github.com/storybooks/storybook/pull/2873)
- Knobs: Select knob key/value ordering [#1745](https://github.com/storybooks/storybook/pull/1745)
- Angular: Add option to pass custom styles for ng components [#2856](https://github.com/storybooks/storybook/pull/2856)
- Core: Add watch mode for build-storybook [#2866](https://github.com/storybooks/storybook/pull/2866)
- Core: Add `__dirname` support [#2791](https://github.com/storybooks/storybook/pull/2791)
- Pass default webpack config as third argument in Full Control Mode [#2796](https://github.com/storybooks/storybook/pull/2796)
- Angular and Vue storyshots [#2564](https://github.com/storybooks/storybook/pull/2564)
- Addon-info: Added "Copy button" for code example [#2713](https://github.com/storybooks/storybook/pull/2713)
- Angular: Serve styles and assets using .angular-cli webpack configuration [#2735](https://github.com/storybooks/storybook/pull/2735)
- API: Added an event that is emitted when a channel is created. [#2711](https://github.com/storybooks/storybook/pull/2711)
- Addon-a11y: Handle components with delayed rendering [#2651](https://github.com/storybooks/storybook/pull/2651)
- Polymer 2 support [#2225](https://github.com/storybooks/storybook/pull/2225)
- Add image snapshots to addon-storyshots [#2413](https://github.com/storybooks/storybook/pull/2413)
- Angular template support for Storybook [#2690](https://github.com/storybooks/storybook/pull/2690)
- Custom tsconfig.json for angular apps. [#2669](https://github.com/storybooks/storybook/pull/2669)
- Multiple story hierarchies [#2452](https://github.com/storybooks/storybook/pull/2452)
- Change template story files extension to .ts [#2594](https://github.com/storybooks/storybook/pull/2594)
- Use store revisions to ensure that stories re-render on HMR. [#2605](https://github.com/storybooks/storybook/pull/2605)
- Ability to force re-render a story [#2463](https://github.com/storybooks/storybook/pull/2463)
- Introduce framework-independent core library [#2241](https://github.com/storybooks/storybook/pull/2241)
#### Bug Fixes
- [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)
- Object proptype is shown in addon-info proptable [#3255](https://github.com/storybooks/storybook/pull/3255)
- Fix storyshots renderer and serializer options [#3252](https://github.com/storybooks/storybook/pull/3252)
- Angular: use resolveLoader from cliCommonConfig [#3251](https://github.com/storybooks/storybook/pull/3251)
- Delaying update of height and width in Layout [#3180](https://github.com/storybooks/storybook/pull/3180)
- Add 'waitUntil' option to puppeteer of storyshots [#3156](https://github.com/storybooks/storybook/pull/3156)
- Move polymer loader to peerDependencies [#3161](https://github.com/storybooks/storybook/pull/3161)
- Addons: avoid mixing manager and preview code together [#3068](https://github.com/storybooks/storybook/pull/3068)
- React-Native: Fix by moving managerPath export to `server.js` [#2947](https://github.com/storybooks/storybook/pull/2947)
- Addon-Info: Add type check to PropType on OneOf [#2653](https://github.com/storybooks/storybook/pull/2653)
- Vue: Support .vue extension resolving [#2896](https://github.com/storybooks/storybook/pull/2896)
- UI: remove zero on story loading [#2857](https://github.com/storybooks/storybook/pull/2857)
- Angular: remove entryComponents prop from metadata [#2790](https://github.com/storybooks/storybook/pull/2790)
- Use process.exitCode instead of process.exit() [#2717](https://github.com/storybooks/storybook/pull/2717)
- Angular: knobs with template [#2766](https://github.com/storybooks/storybook/pull/2766)
- Remove polymer-cli dependency [#2741](https://github.com/storybooks/storybook/pull/2741)
- Add scss for components in angular apps by default. [#2703](https://github.com/storybooks/storybook/pull/2703)
#### Documentation
- Add example for @ngrx/store [#3233](https://github.com/storybooks/storybook/pull/3233)
- Fix missing declaration in Angular example [#3213](https://github.com/storybooks/storybook/pull/3213)
- Update ADDONS_SUPPORT.md [#3114](https://github.com/storybooks/storybook/pull/3114)
- StoryShots: Document ref mocking [#2869](https://github.com/storybooks/storybook/pull/2869)
- Extending webpack section is no longer needed for the common usage [#2826](https://github.com/storybooks/storybook/pull/2826)
- Updating Vue Jest Config [#2821](https://github.com/storybooks/storybook/pull/2821)
- Angular inheritance example [#2787](https://github.com/storybooks/storybook/pull/2787)
- Revisit addon/framework support [#3046](https://github.com/storybooks/storybook/pull/3046)
- Docs live examples [#3019](https://github.com/storybooks/storybook/pull/3019)
- Mention new supported frameworks [#2895](https://github.com/storybooks/storybook/pull/2895)
- Update writing addons documentation [#2951](https://github.com/storybooks/storybook/pull/2951)
- Update docs on LinkTo in addon-links [#2926](https://github.com/storybooks/storybook/pull/2926)
#### Maintenance
- Fix errors on starting example Angular app [#3078](https://github.com/storybooks/storybook/pull/3078)
- Use WatchMissingNodeModulesPlugin from react-dev-utils package [#3141](https://github.com/storybooks/storybook/pull/3141)
- Don't use exact versions in peerDependencies [#3073](https://github.com/storybooks/storybook/pull/3073)
- Remove integration tests [#3052](https://github.com/storybooks/storybook/pull/3052)
- Fix "dev" script to be cross-platform [#2922](https://github.com/storybooks/storybook/pull/2922)
- Typescript distribution [#2846](https://github.com/storybooks/storybook/pull/2846)
- Use UTC timezone in formatting too for knobs test [#2861](https://github.com/storybooks/storybook/pull/2861)
- ADD autolabeler.yml for <https://github.com/probot/autolabeler> [#2809](https://github.com/storybooks/storybook/pull/2809)
- Fix css warning in angular-cli example [#2789](https://github.com/storybooks/storybook/pull/2789)
- Move more things to core [#2788](https://github.com/storybooks/storybook/pull/2788)
- Change ng stories dir [#2672](https://github.com/storybooks/storybook/pull/2672)
- Only update CLI snapsots on postpublish script, skip smoke tests [#2671](https://github.com/storybooks/storybook/pull/2671)
- Fix the timezone for example dates [#2654](https://github.com/storybooks/storybook/pull/2654)
- Update prereq yarn install level [#2638](https://github.com/storybooks/storybook/pull/2638)
- Separate stories in angular-cli example [#2592](https://github.com/storybooks/storybook/pull/2592)
# 3.4.0
2018-March-30
Welcome to Storybook 3.4 with the following key improvements:
- Polymer 2 support [#2225](https://github.com/storybooks/storybook/pull/2225)
- Angular and Vue storyshots [#2564](https://github.com/storybooks/storybook/pull/2564)
- Add image snapshots to addon-storyshots [#2413](https://github.com/storybooks/storybook/pull/2413)
- Multiple story hierarchies [#2452](https://github.com/storybooks/storybook/pull/2452)
- Addon-storysource: story source in addon pane [#2885](https://github.com/storybooks/storybook/pull/2885)
Read on for more improvements, fixes, 1In addition, there are hundreds of dependency upgrades in the 3.4 release, so to see the details, please see the changelogs for `3.4.0-rc.*` and `3.4.0-alpha.*`.
#### Features
- Bind window access if `window` is defined; add `addons channel` access too [#3243](https://github.com/storybooks/storybook/pull/3243)
- Fix screenshots tests & add getScreenshotOption to storyshots [#3102](https://github.com/storybooks/storybook/pull/3102)
- Add `__STORYBOOK_CLIENT_API__` for external tools [#3058](https://github.com/storybooks/storybook/pull/3058)
- Addon storysource: select stories from inside of the StoryPanel [#3154](https://github.com/storybooks/storybook/pull/3154)
- Storyshots: env.NODE_PATH support [#2873](https://github.com/storybooks/storybook/pull/2873)
- Knobs: Select knob key/value ordering [#1745](https://github.com/storybooks/storybook/pull/1745)
- Angular: Add option to pass custom styles for ng components [#2856](https://github.com/storybooks/storybook/pull/2856)
- Core: Add watch mode for build-storybook [#2866](https://github.com/storybooks/storybook/pull/2866)
- Core: Add `__dirname` support [#2791](https://github.com/storybooks/storybook/pull/2791)
- Pass default webpack config as third argument in Full Control Mode [#2796](https://github.com/storybooks/storybook/pull/2796)
- Angular and Vue storyshots [#2564](https://github.com/storybooks/storybook/pull/2564)
- Addon-info: Added "Copy button" for code example [#2713](https://github.com/storybooks/storybook/pull/2713)
- Angular: Serve styles and assets using .angular-cli webpack configuration [#2735](https://github.com/storybooks/storybook/pull/2735)
- API: Added an event that is emitted when a channel is created. [#2711](https://github.com/storybooks/storybook/pull/2711)
- Addon-a11y: Handle components with delayed rendering [#2651](https://github.com/storybooks/storybook/pull/2651)
- Polymer 2 support [#2225](https://github.com/storybooks/storybook/pull/2225)
- Add image snapshots to addon-storyshots [#2413](https://github.com/storybooks/storybook/pull/2413)
- Angular template support for Storybook [#2690](https://github.com/storybooks/storybook/pull/2690)
- Custom tsconfig.json for angular apps. [#2669](https://github.com/storybooks/storybook/pull/2669)
- Multiple story hierarchies [#2452](https://github.com/storybooks/storybook/pull/2452)
- Change template story files extension to .ts [#2594](https://github.com/storybooks/storybook/pull/2594)
- Use store revisions to ensure that stories re-render on HMR. [#2605](https://github.com/storybooks/storybook/pull/2605)
- Ability to force re-render a story [#2463](https://github.com/storybooks/storybook/pull/2463)
- Introduce framework-independent core library [#2241](https://github.com/storybooks/storybook/pull/2241)
#### Bug Fixes
- [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)
- Object proptype is shown in addon-info proptable [#3255](https://github.com/storybooks/storybook/pull/3255)
- Fix storyshots renderer and serializer options [#3252](https://github.com/storybooks/storybook/pull/3252)
- Angular: use resolveLoader from cliCommonConfig [#3251](https://github.com/storybooks/storybook/pull/3251)
- Delaying update of height and width in Layout [#3180](https://github.com/storybooks/storybook/pull/3180)
- Add 'waitUntil' option to puppeteer of storyshots [#3156](https://github.com/storybooks/storybook/pull/3156)
- Move polymer loader to peerDependencies [#3161](https://github.com/storybooks/storybook/pull/3161)
- Addons: avoid mixing manager and preview code together [#3068](https://github.com/storybooks/storybook/pull/3068)
- React-Native: Fix by moving managerPath export to `server.js` [#2947](https://github.com/storybooks/storybook/pull/2947)
- Addon-Info: Add type check to PropType on OneOf [#2653](https://github.com/storybooks/storybook/pull/2653)
- Vue: Support .vue extension resolving [#2896](https://github.com/storybooks/storybook/pull/2896)
- UI: remove zero on story loading [#2857](https://github.com/storybooks/storybook/pull/2857)
- Angular: remove entryComponents prop from metadata [#2790](https://github.com/storybooks/storybook/pull/2790)
- Use process.exitCode instead of process.exit() [#2717](https://github.com/storybooks/storybook/pull/2717)
- Angular: knobs with template [#2766](https://github.com/storybooks/storybook/pull/2766)
- Remove polymer-cli dependency [#2741](https://github.com/storybooks/storybook/pull/2741)
- Add scss for components in angular apps by default. [#2703](https://github.com/storybooks/storybook/pull/2703)
#### Documentation
- Add example for @ngrx/store [#3233](https://github.com/storybooks/storybook/pull/3233)
- Fix missing declaration in Angular example [#3213](https://github.com/storybooks/storybook/pull/3213)
- Update ADDONS_SUPPORT.md [#3114](https://github.com/storybooks/storybook/pull/3114)
- StoryShots: Document ref mocking [#2869](https://github.com/storybooks/storybook/pull/2869)
- Extending webpack section is no longer needed for the common usage [#2826](https://github.com/storybooks/storybook/pull/2826)
- Updating Vue Jest Config [#2821](https://github.com/storybooks/storybook/pull/2821)
- Angular inheritance example [#2787](https://github.com/storybooks/storybook/pull/2787)
- Revisit addon/framework support [#3046](https://github.com/storybooks/storybook/pull/3046)
- Docs live examples [#3019](https://github.com/storybooks/storybook/pull/3019)
- Mention new supported frameworks [#2895](https://github.com/storybooks/storybook/pull/2895)
- Update writing addons documentation [#2951](https://github.com/storybooks/storybook/pull/2951)
- Update docs on LinkTo in addon-links [#2926](https://github.com/storybooks/storybook/pull/2926)
#### Maintenance
- Fix errors on starting example Angular app [#3078](https://github.com/storybooks/storybook/pull/3078)
- Use WatchMissingNodeModulesPlugin from react-dev-utils package [#3141](https://github.com/storybooks/storybook/pull/3141)
- Don't use exact versions in peerDependencies [#3073](https://github.com/storybooks/storybook/pull/3073)
- Remove integration tests [#3052](https://github.com/storybooks/storybook/pull/3052)
- Fix "dev" script to be cross-platform [#2922](https://github.com/storybooks/storybook/pull/2922)
- Typescript distribution [#2846](https://github.com/storybooks/storybook/pull/2846)
- Use UTC timezone in formatting too for knobs test [#2861](https://github.com/storybooks/storybook/pull/2861)
- ADD autolabeler.yml for <https://github.com/probot/autolabeler> [#2809](https://github.com/storybooks/storybook/pull/2809)
- Fix css warning in angular-cli example [#2789](https://github.com/storybooks/storybook/pull/2789)
- Move more things to core [#2788](https://github.com/storybooks/storybook/pull/2788)
- Change ng stories dir [#2672](https://github.com/storybooks/storybook/pull/2672)
- Only update CLI snapsots on postpublish script, skip smoke tests [#2671](https://github.com/storybooks/storybook/pull/2671)
- Fix the timezone for example dates [#2654](https://github.com/storybooks/storybook/pull/2654)
- Update prereq yarn install level [#2638](https://github.com/storybooks/storybook/pull/2638)
- Separate stories in angular-cli example [#2592](https://github.com/storybooks/storybook/pull/2592)
>>>>>>> ea4634b1d... 3.4.0 changelog
# 3.4.0-rc.4

View File

@ -17,6 +17,14 @@
- [Packages renaming](#packages-renaming)
- [Deprecated embedded addons](#deprecated-embedded-addons)
## From 3.4.x to 4.0
* Keyboard shortcuts have been moved:
- Addon Panel to `Z`
- Stories Panel to `X`
- Show Search to `O`
- Addon Panel right side to `G`
## From version 3.3.x to 3.4.x
There are no expected breaking changes in the 3.4.x release, but 3.4 contains a major refactor to make it easier to support new frameworks, and we will document any breaking changes here if they arise.

View File

@ -1,5 +1,6 @@
# Storybook
[![Build Status on TeamCity](https://teamcity.jetbrains.com/app/rest/builds/buildType:OpenSourceProjects_Storybook_Build_2/statusIcon.svg)](https://teamcity.jetbrains.com/viewType.html?buildTypeId=OpenSourceProjects_Storybook_Build_2&branch_OpenSourceProjects_Storybook=%3Cdefault%3E&tab=buildTypeStatusDiv)
[![Build Status on CircleCI](https://circleci.com/gh/storybooks/storybook.svg?style=shield)](https://circleci.com/gh/storybooks/storybook)
[![CodeFactor](https://www.codefactor.io/repository/github/storybooks/storybook/badge)](https://www.codefactor.io/repository/github/storybooks/storybook)
[![Known Vulnerabilities](https://snyk.io/test/github/storybooks/storybook/badge.svg)](https://snyk.io/test/github/storybooks/storybook)
@ -102,7 +103,7 @@ See [Addon / Framework Support Table](ADDONS_SUPPORT.md)
## Live Examples
### 4.0.alpha
> Note, this is an Alpha version. Some of the features still might not be released
> 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/)
@ -152,7 +153,7 @@ We welcome contributions to Storybook!
> boolean check if unit tests all pass - uses jest
- `yarn test:watch` - will run tests in watch-mode
- `yarn run test --core --watch` - will run core tests in watch-mode
### Backers

View File

@ -1 +0,0 @@
import '../register';

View File

@ -1,17 +0,0 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import Faker from 'faker';
import { checkA11y } from './../../../src';
import Button from './component';
const text = Faker.lorem.words();
storiesOf('<Button />', module)
.addDecorator(checkA11y)
.add('Default', () => <Button />)
.add('Content', () => <Button content={text} />)
.add('Label', () => <Button label={text} />)
.add('Disabled', () => <Button disabled content={text} />)
.add('Invalid contrast', () => <Button contrast="wrong" content={Faker.lorem.words()} />);

View File

@ -1,20 +0,0 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import Faker from 'faker';
import * as Form from './components';
import { checkA11y } from './../../../src';
const label = Faker.lorem.word();
const placeholder = Faker.lorem.word();
storiesOf('<Form />', module)
.addDecorator(checkA11y)
.add('Without Label', () => <Form.Row input={<Form.Input />} />)
.add('With label', () => (
<Form.Row label={<Form.Label content={label} id="1" />} input={<Form.Input id="1" />} />
))
.add('With placeholder', () => (
<Form.Row input={<Form.Input id="1" placeholder={placeholder} />} />
));

View File

@ -1,16 +0,0 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import Faker from 'faker';
import { checkA11y } from './../../../src';
import Image from './component';
const image = Faker.image.animals();
const alt = Faker.lorem.words();
storiesOf('<Image />', module)
.addDecorator(checkA11y)
.add('Without alt', () => <Image src={image} />)
.add('With alt', () => <Image src={image} alt={alt} />)
.add('Presentation', () => <Image presentation src={image} />);

View File

@ -1,26 +0,0 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import Faker from 'faker';
import { checkA11y } from './../../../src';
import * as Typography from './components';
// eslint-disable-next-line no-script-url
const href = 'javascript:void 0';
storiesOf('<Typography />', module)
.addDecorator(checkA11y)
.add('Correct', () => (
<div>
<Typography.Heading level={1}>{Faker.lorem.sentence()}</Typography.Heading>
<Typography.Text>{Faker.lorem.paragraph()}</Typography.Text>
<Typography.Link content={`${Faker.lorem.words(4)}...`} href={href} />
</div>
))
.add('Empty Heading', () => <Typography.Heading level={2} />)
.add('Empty Paragraph', () => <Typography.Text />)
.add('Empty Link', () => <Typography.Link href={href} />)
.add('Link without href', () => <Typography.Link content={`${Faker.lorem.words(4)}...`} />);

View File

@ -1,7 +0,0 @@
import * as storybook from '@storybook/react';
const req = require.context('./components/', true, /stories\.js$/);
const loadStories = () => req.keys().forEach(req);
storybook.configure(loadStories, module);

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-a11y",
"version": "4.0.0-alpha.1",
"version": "4.0.0-alpha.4",
"description": "a11y addon for storybook",
"keywords": [
"a11y",
@ -25,20 +25,16 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/client-logger": "4.0.0-alpha.1",
"@storybook/components": "4.0.0-alpha.1",
"@storybook/addons": "4.0.0-alpha.4",
"@storybook/client-logger": "4.0.0-alpha.4",
"@storybook/components": "4.0.0-alpha.4",
"axe-core": "^3.0.1",
"babel-runtime": "^6.26.0",
"glamor": "^2.20.40",
"glamorous": "^4.12.1",
"glamorous": "^4.12.4",
"prop-types": "^15.6.1"
},
"devDependencies": {
"@storybook/react": "4.0.0-alpha.1",
"faker": "^4.1.0"
},
"peerDependencies": {
"@storybook/addons": "^3.3.0",
"react": "*",
"react-dom": "*"
}

View File

@ -7,7 +7,7 @@
[![Storybook Slack](https://now-examples-slackin-rrirkqohko.now.sh/badge.svg)](https://now-examples-slackin-rrirkqohko.now.sh/)
[![Backers on Open Collective](https://opencollective.com/storybook/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/storybook/sponsors/badge.svg)](#sponsors)
* * *
---
Storybook Addon Actions can be used to display data received by event handlers in [Storybook](https://storybook.js.org).
@ -35,37 +35,91 @@ Import the `action` function and use it to create actions handlers. When creatin
```js
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { action, configureActions } from '@storybook/addon-actions';
import Button from './button';
storiesOf('Button', module).add('default view', () => (
<Button onClick={action('button-click')}>Hello World!</Button>
));
```
## Multiple actions
If your story requires multiple actions, it may be convenient to use `actions` to create many at once:
```js
import { storiesOf } from '@storybook/react';
import { actions } from '@storybook/addon-actions';
import Button from './button';
// This will lead to { onClick: action('onClick'), ... }
const eventsFromNames = actions('onClick', 'onDoubleClick');
// This will lead to { onClick: action('clicked'), ... }
const eventsFromObject = actions({ onClick: 'clicked', onDoubleClick: 'double clicked' });
storiesOf('Button', module)
.add('default view', () => (
<Button onClick={ action('button-click') }>
Hello World!
</Button>
))
.add('default view', () => <Button {...eventsFromNames}>Hello World!</Button>)
.add('default view, different actions', () => (
<Button {...eventsFromObject}>Hello World!</Button>
));
```
## Action Decorators
If you wish to process action data before sending them over to the logger, you can do it with action decorators.
`decorateAction` takes an array of decorator functions. Each decorator function is passed an array of arguments, and should return a new arguments array to use. `decorateAction` returns a function that can be used like `action` but will log the modified arguments instead of the original arguments.
`decorate` takes an array of decorator functions. Each decorator function is passed an array of arguments, and should return a new arguments array to use. `decorate` returns a object with two functions: `action` and `actions`, that act like the above, except they log the modified arguments instead of the original arguments.
```js
import { decorateAction } from '@storybook/addon-actions';
import { decorate } from '@storybook/addon-actions';
import Button from './button';
const firstArgAction = decorateAction([
args => args.slice(0, 1)
]);
const firstArg = decorate([args => args.slice(0, 1)]);
storiesOf('Button', module)
.add('default view', () => (
<Button onClick={ firstArgAction('button-click') }>
Hello World!
</Button>
))
storiesOf('Button', module).add('default view', () => (
<Button onClick={firstArg.action('button-click')}>Hello World!</Button>
));
```
## Configuration
Arguments which are passed to the action call will have to be serialized while be "transfered"
over the channel.
This is not very optimal and can cause lag when large objects are being logged, for this reason it is possible
to configure a maximum depth.
The action logger, by default, will log all actions fired during the lifetime of the story. After a while
this can make the storybook laggy. As a workaround, you can configure an upper limit to how many actions should
be logged.
To apply the configuration globally use the `configureActions` function in your `config.js` file.
```js
import { configureActions } from '@storybook/addon-actions';
configureActions({
depth: 100,
// Limit the number of items logged into the actions panel
limit: 20,
})
```
To apply the configuration per action use:
```js
action('my-action', {
depth: 5,
})
```
### Available Options
|Name|Type|Description|Default|
|---|---|---|---|
|`depth`|Number|Configures the transfered depth of any logged objects.|`10`|
|`clearOnStoryChange`|Boolean|Flag whether to clear the action logger when switching away from the current story.|`true`|
|`limit`|Number|Limits the number of items logged in the action logger|`50`|

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-actions",
"version": "4.0.0-alpha.1",
"version": "4.0.0-alpha.4",
"description": "Action Logger addon for storybook",
"keywords": [
"storybook"
@ -20,20 +20,19 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/components": "4.0.0-alpha.1",
"@storybook/addons": "4.0.0-alpha.4",
"@storybook/components": "4.0.0-alpha.4",
"babel-runtime": "^6.26.0",
"deep-equal": "^1.0.1",
"glamor": "^2.20.40",
"glamorous": "^4.12.1",
"glamorous": "^4.12.4",
"global": "^4.3.2",
"make-error": "^1.3.4",
"prop-types": "^15.6.1",
"react-inspector": "^2.2.2",
"react-inspector": "^2.3.0",
"uuid": "^3.2.1"
},
"peerDependencies": {
"@storybook/addons": "^3.3.0",
"react": "*",
"react-dom": "*"
"react": "*"
}
}

View File

@ -14,14 +14,26 @@ export default class ActionLogger extends React.Component {
super(props, ...args);
this.state = { actions: [] };
this._actionListener = action => this.addAction(action);
this._storyChangeListener = () => this.handleStoryChange();
}
componentDidMount() {
this.props.channel.on(EVENT_ID, this._actionListener);
this.stopListeningOnStory = this.props.api.onStory(this._storyChangeListener);
}
componentWillUnmount() {
this.props.channel.removeListener(EVENT_ID, this._actionListener);
if (this.stopListeningOnStory) {
this.stopListeningOnStory();
}
}
handleStoryChange() {
const { actions } = this.state;
if (actions.length > 0 && actions[0].options.clearOnStoryChange) {
this.clearActions();
}
}
addAction(action) {
@ -36,7 +48,7 @@ export default class ActionLogger extends React.Component {
action.count = 1; // eslint-disable-line
actions.unshift(action);
}
this.setState({ actions });
this.setState({ actions: actions.slice(0, action.options.limit) });
}
clearActions() {
@ -54,6 +66,9 @@ export default class ActionLogger extends React.Component {
ActionLogger.propTypes = {
channel: PropTypes.object, // eslint-disable-line react/forbid-prop-types
api: PropTypes.shape({
onStory: PropTypes.func.isRequired,
}).isRequired,
};
ActionLogger.defaultProps = {
channel: {},

View File

@ -1,6 +1,8 @@
import { action, actions, decorate, configureActions, decorateAction } from './preview';
// addons, panels and events get unique names using a prefix
export const ADDON_ID = 'storybook/actions';
export const PANEL_ID = `${ADDON_ID}/actions-panel`;
export const EVENT_ID = `${ADDON_ID}/action-event`;
export { action, decorateAction } from './preview';
export { action, actions, decorate, configureActions, decorateAction };

View File

@ -1,25 +1,25 @@
import { DecycleError } from './errors';
import { getPropertiesList, typeReplacer } from './util';
import { getPropertiesList, typeReplacer, omitProperty } from './util';
import { CYCLIC_KEY } from './';
import { objectType } from './types';
import { DEPTH_KEY } from './types/object/configureDepth';
const { hasOwnProperty } = Object.prototype;
export default function decycle(object, depth = 10) {
const objects = new WeakMap();
let isCyclic = false;
const res = (function derez(value, path, _depth) {
const res = (function derez(value, path, _depth, _branchDepthMax) {
let oldPath;
let obj;
if (Object(value) === value && _depth > depth) {
const name = value.constructor ? value.constructor.name : typeof value;
return `[${name}...]`;
}
let maxDepth = _branchDepthMax;
const result = typeReplacer(value);
@ -51,19 +51,40 @@ export default function decycle(object, depth = 10) {
if (Array.isArray(value)) {
obj = [];
for (let i = 0; i < value.length; i += 1) {
obj[i] = derez(value[i], `${path}[${i}]`, _depth + 1);
obj[i] = derez(value[i], `${path}[${i}]`, _depth + 1, maxDepth);
}
} else {
obj = objectType.serialize(value);
getPropertiesList(value).forEach(name => {
try {
obj[name] = derez(value[name], `${path}[${JSON.stringify(name)}]`, _depth + 1);
} catch (error) {
console.error(error); // eslint-disable-line no-console
obj[name] = new DecycleError(error.message);
let newDepth;
if (hasOwnProperty.call(obj, DEPTH_KEY)) {
if (_depth + 1 < maxDepth) {
const depthKey = obj[DEPTH_KEY];
newDepth = depthKey === 0 ? 0 : _depth + depthKey;
maxDepth = newDepth >= depth ? depth : newDepth;
}
});
delete obj[DEPTH_KEY];
}
if (_depth <= maxDepth) {
getPropertiesList(value).forEach(name => {
if (!omitProperty(name)) {
try {
obj[name] = derez(
value[name],
`${path}[${JSON.stringify(name)}]`,
_depth + 1,
maxDepth
);
} catch (error) {
console.error(error); // eslint-disable-line no-console
obj[name] = new DecycleError(error.message);
}
}
});
}
}
if (_depth === 0 && value instanceof Object && isCyclic) {
@ -74,7 +95,7 @@ export default function decycle(object, depth = 10) {
}
return value;
})(object, '$', 0);
})(object, '$', 0, depth);
return res;
}

View File

@ -1,11 +1,15 @@
import objectType from '../';
import { DEPTH_KEY } from '../configureDepth';
describe('Object', () => {
it('Serializes Object', () => {
function C() {}
const c = new C();
expect(objectType.serialize(c)).toEqual({ [objectType.KEY]: 'C' });
expect(objectType.serialize(c)).toEqual({
[DEPTH_KEY]: 2,
[objectType.KEY]: 'C',
});
});
it('Deserializes Object', () => {

View File

@ -0,0 +1,7 @@
export const DEPTH_KEY = '$___storybook.depthKey';
export default function configureDepth(obj, depth = 0) {
obj[DEPTH_KEY] = depth; // eslint-disable-line no-param-reassign
return obj;
}

View File

@ -1,12 +1,21 @@
import createNamedObject from './createNamedObject';
import getObjectName from './getObjectName';
import configureDepth from './configureDepth';
const maxDepth = 2;
const KEY = '$___storybook.objectName';
const objectType = {
KEY,
// is: (value) => , // not used
serialize: value => ({ [KEY]: getObjectName(value) }),
serialize: value => {
const objectName = getObjectName(value);
if (objectName === 'Object') {
return { [KEY]: objectName };
}
return configureDepth({ [KEY]: objectName }, maxDepth);
},
deserialize: value => createNamedObject(value, KEY),
};

View File

@ -5,3 +5,4 @@ export muteProperty from './muteProperty';
export prepareArguments from './prepareArguments';
export typeReviver from './typeReviver';
export typeReplacer from './typeReplacer';
export omitProperty from './omitProperty';

View File

@ -0,0 +1,3 @@
export default function omitProperty(name) {
return name.startsWith('__') || name.startsWith('STORYBOOK_');
}

View File

@ -1,12 +1,8 @@
import { decycle } from '../index';
export default function prepareArguments(arg) {
if (arg && typeof arg.preventDefault !== 'undefined') {
return JSON.stringify(`[${arg.constructor.name}]`);
}
export default function prepareArguments(arg, depth) {
try {
return JSON.stringify(decycle(arg));
return JSON.stringify(decycle(arg, depth));
} catch (error) {
return error.toString(); // IE still cyclic.
}

View File

@ -4,11 +4,11 @@ import ActionLogger from './containers/ActionLogger';
import { ADDON_ID, PANEL_ID } from './';
export function register() {
addons.register(ADDON_ID, () => {
addons.register(ADDON_ID, api => {
const channel = addons.getChannel();
addons.addPanel(PANEL_ID, {
title: 'Action Logger',
render: () => <ActionLogger channel={channel} />,
render: () => <ActionLogger channel={channel} api={api} />,
});
});
}

View File

@ -0,0 +1,90 @@
import addons from '@storybook/addons';
import { action, configureActions } from '../../';
jest.mock('@storybook/addons');
const getChannelData = channel =>
channel.emit.mock.calls[channel.emit.mock.calls.length - 1][1].data;
describe('Action', () => {
const channel = { emit: jest.fn() };
addons.getChannel.mockReturnValue(channel);
it('with one argument', () => {
action('test-action')('one');
expect(getChannelData(channel).args[0]).toEqual('"one"');
});
it('with multiple arguments', () => {
action('test-action')('one', 'two', 'three');
expect(getChannelData(channel).args).toEqual(['"one"', '"two"', '"three"']);
});
it('with global depth configuration', () => {
const depth = 1;
configureActions({
depth,
});
action('test-action')({
root: {
one: {
two: 'foo',
},
},
});
expect(getChannelData(channel).args[0]).toEqual(
JSON.stringify({
'$___storybook.objectName': 'Object',
root: {
'$___storybook.objectName': 'Object',
one: {
'$___storybook.objectName': 'Object',
},
},
})
);
});
it('per action depth option overrides global config', () => {
configureActions({
depth: 1,
});
action('test-action', { depth: 3 })({
root: {
one: {
two: {
three: {
four: {
five: 'foo',
},
},
},
},
},
});
expect(getChannelData(channel).args[0]).toEqual(
JSON.stringify({
'$___storybook.objectName': 'Object',
root: {
'$___storybook.objectName': 'Object',
one: {
'$___storybook.objectName': 'Object',
two: {
'$___storybook.objectName': 'Object',
three: {
'$___storybook.objectName': 'Object',
},
},
},
},
})
);
});
});

View File

@ -0,0 +1,22 @@
import { config } from '../configureActions';
import { configureActions } from '../../';
describe('Configure Actions', () => {
it('can configure actions', () => {
const depth = 100;
const clearOnStoryChange = false;
const limit = 20;
configureActions({
depth,
clearOnStoryChange,
limit,
});
expect(config).toEqual({
depth,
clearOnStoryChange,
limit,
});
});
});

View File

@ -1,7 +1,7 @@
import addons from '@storybook/addons';
import uuid from 'uuid/v1';
import { action } from './preview';
import { undefinedType, symbolType } from './lib/types';
import { action } from '../';
import { undefinedType, symbolType } from '../../lib/types';
jest.mock('uuid/v1');
jest.mock('@storybook/addons');

View File

@ -1,17 +1,24 @@
import addons from '@storybook/addons';
import uuid from 'uuid/v1';
import { EVENT_ID } from './';
import { canConfigureName, prepareArguments } from './lib/util';
import addons from '@storybook/addons';
import { EVENT_ID } from '../';
import { canConfigureName, prepareArguments } from '../lib/util';
import { config } from './configureActions';
export default function action(name, options = {}) {
const actionOptions = {
...config,
...options,
};
export function action(name) {
// eslint-disable-next-line no-shadow
const handler = function action(..._args) {
const args = _args.map(prepareArguments);
const args = _args.map(arg => prepareArguments(arg, actionOptions.depth));
const channel = addons.getChannel();
const id = uuid();
channel.emit(EVENT_ID, {
id,
data: { name, args },
options: actionOptions,
});
};
@ -20,13 +27,3 @@ export function action(name) {
}
return handler;
}
export function decorateAction(decorators) {
return name => {
const callAction = action(name);
return (..._args) => {
const decorated = decorators.reduce((args, fn) => fn(args), _args);
callAction(...decorated);
};
};
}

View File

@ -0,0 +1,24 @@
import action from './action';
export default function actions(...args) {
let options = {};
const names = args;
// last argument can be options
if (names.length !== 1 && typeof args[args.length - 1] !== 'string') {
options = names.pop();
}
let namesObject = names[0];
if (names.length !== 1 || typeof namesObject === 'string') {
namesObject = {};
names.forEach(name => {
namesObject[name] = name;
});
}
const actionsObject = {};
Object.keys(namesObject).forEach(name => {
actionsObject[name] = action(namesObject[name], options);
});
return actionsObject;
}

View File

@ -0,0 +1,9 @@
export const config = {
depth: 10,
clearOnStoryChange: true,
limit: 50,
};
export function configureActions(options = {}) {
Object.assign(config, options);
}

View File

@ -0,0 +1,31 @@
import action from './action';
import actions from './actions';
function applyDecorators(decorators, actionCallback) {
return (..._args) => {
const decorated = decorators.reduce((args, fn) => fn(args), _args);
actionCallback(...decorated);
};
}
export function decorateAction(decorators) {
return (name, options) => {
const callAction = action(name, options);
return applyDecorators(decorators, callAction);
};
}
export function decorate(decorators) {
const decorated = decorateAction(decorators);
return {
action: decorated,
actions: (...args) => {
const rawActions = actions(...args);
const decoratedActions = {};
Object.keys(rawActions).forEach(name => {
decoratedActions[name] = applyDecorators(decorators, rawActions[name]);
});
return decoratedActions;
},
};
}

View File

@ -0,0 +1,4 @@
export { default as action } from './action';
export { default as actions } from './actions';
export { configureActions } from './configureActions';
export { decorateAction, decorate } from './decorateAction';

View File

@ -76,3 +76,10 @@ storiesOf("Button", module)
> import { storiesOf } from '@storybook/mithril';
> import backgrounds from "@storybook/addon-backgrounds/mithril";
> ```
> In the case of Vue, use these imports:
>
> ```js
> import { storiesOf } from '@storybook/vue';
> import backgrounds from "@storybook/addon-backgrounds/vue";
> ```

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-backgrounds",
"version": "4.0.0-alpha.1",
"version": "4.0.0-alpha.4",
"description": "A storybook addon to show different backgrounds for your preview",
"keywords": [
"addon",
@ -24,13 +24,16 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "4.0.0-alpha.4",
"babel-runtime": "^6.26.0",
"global": "^4.3.2",
"prop-types": "^15.6.1",
"react-lifecycles-compat": "^1.1.4"
"react-lifecycles-compat": "^3.0.2"
},
"devDependencies": {
"vue": "^2.5.16"
},
"peerDependencies": {
"@storybook/addons": "^3.3.0",
"react": "*"
}
}

View File

@ -0,0 +1,42 @@
import Vue from 'vue';
import { vueHandler } from '../vue';
describe('Vue handler', () => {
it('Returns a component with a created function', () => {
const testChannel = { emit: jest.fn() };
const testStory = () => ({ template: '<div> testStory </div>' });
const testContext = {
kind: 'Foo',
story: 'bar baz',
};
const testBackground = [
{ name: 'twitter', value: '#00aced' },
{ name: 'facebook', value: '#3b5998', default: true },
];
const component = vueHandler(testChannel, testBackground)(testStory, testContext);
expect(component).toMatchObject({
created: expect.any(Function),
beforeDestroy: expect.any(Function),
render: expect.any(Function),
});
});
it('Subscribes to the channel on creation', () => {
const testChannel = { emit: jest.fn() };
const testStory = () => ({ render: h => h('div', ['testStory']) });
const testContext = {
kind: 'Foo',
story: 'bar baz',
};
const testBackground = [
{ name: 'twitter', value: '#00aced' },
{ name: 'facebook', value: '#3b5998', default: true },
];
new Vue(vueHandler(testChannel, testBackground)(testStory, testContext)).$mount();
expect(testChannel.emit).toHaveBeenCalledTimes(1);
expect(testChannel.emit).toHaveBeenCalledWith('background-set', expect.any(Array));
});
});

View File

@ -1,5 +1,5 @@
import React from 'react';
import polyfill from 'react-lifecycles-compat';
import { polyfill } from 'react-lifecycles-compat';
import PropTypes from 'prop-types';
import addons from '@storybook/addons';

View File

@ -0,0 +1,28 @@
import addons from '@storybook/addons';
export const vueHandler = (channel, backgrounds) => (getStory, context) => ({
data() {
return {
context,
getStory,
story: getStory(context),
};
},
render(h) {
return h(this.story);
},
created() {
channel.emit('background-set', backgrounds);
},
beforeDestroy() {
channel.emit('background-unset');
},
});
export default function makeDecorator(backgrounds) {
const channel = addons.getChannel();
return vueHandler(channel, backgrounds);
}

1
addons/background/vue.js Normal file
View File

@ -0,0 +1 @@
module.exports = require('./dist/vue');

View File

@ -1,12 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Example</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="content"></div>
<script src="bundle.js"></script>
</body>
</html>

View File

@ -1,8 +0,0 @@
import ReactDOM from 'react-dom';
import { document } from 'global';
import decorator from '../src';
const content = decorator(() => 'Hello World!');
const wrapper = document.querySelector('#content');
ReactDOM.render(content, wrapper);

View File

@ -1,3 +0,0 @@
body {
margin: 0;
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-centered",
"version": "4.0.0-alpha.1",
"version": "4.0.0-alpha.4",
"description": "Storybook decorator to center components",
"license": "MIT",
"author": "Muhammed Thanish <mnmtanish@gmail.com>",
@ -10,13 +10,6 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"babel-runtime": "^6.26.0",
"global": "^4.3.2"
},
"devDependencies": {
"react-dom": "^16.3.1"
},
"peerDependencies": {
"react": "*"
}
}

View File

@ -1,3 +1,4 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import React from 'react';
const style = {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-events",
"version": "4.0.0-alpha.1",
"version": "4.0.0-alpha.4",
"description": "Add events to your Storybook stories.",
"keywords": [
"addon",
@ -16,19 +16,17 @@
"url": "git@github.com:storybooks/storybook.git"
},
"scripts": {
"build-storybook": "build-storybook",
"prepare": "node ../../scripts/prepare.js",
"storybook": "start-storybook -p 6006"
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "4.0.0-alpha.4",
"babel-runtime": "^6.26.0",
"format-json": "^1.0.3",
"prop-types": "^15.6.1",
"react-lifecycles-compat": "^1.1.4",
"react-lifecycles-compat": "^3.0.2",
"react-textarea-autosize": "^6.1.0"
},
"peerDependencies": {
"@storybook/addons": "^3.3.0",
"react": "*"
}
}

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import polyfill from 'react-lifecycles-compat';
import { polyfill } from 'react-lifecycles-compat';
import json from 'format-json';
import Textarea from 'react-textarea-autosize';
import PropTypes from 'prop-types';

View File

@ -1,3 +0,0 @@
import * as storybook from '@storybook/react';
storybook.configure(() => require('./stories'), module);

View File

@ -1,7 +0,0 @@
const ignore = 0;
module.exports = {
rules: {
'import/no-unresolved': ignore,
},
};

View File

@ -1,15 +0,0 @@
{
"name": "graphql-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"keywords": [],
"author": "Muhammed Thanish <mnmtanish@gmail.com> (http://thanish.me/)",
"license": "MIT",
"dependencies": {
"cors": "^2.8.0",
"express": "^4.15.5",
"express-graphql": "^0.5.4",
"graphql": "^0.7.0"
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-graphql",
"version": "4.0.0-alpha.1",
"version": "4.0.0-alpha.4",
"description": "Storybook addon to display the GraphiQL IDE",
"keywords": [
"storybook"
@ -17,9 +17,7 @@
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": {
"deploy-storybook": "storybook-to-ghpages",
"prepare": "node ../../scripts/prepare.js",
"storybook": "start-storybook -p 9001"
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"babel-runtime": "^6.26.0",
@ -28,9 +26,6 @@
"graphql": "^0.13.2",
"prop-types": "^15.6.1"
},
"devDependencies": {
"@storybook/react": "4.0.0-alpha.1"
},
"peerDependencies": {
"react": "*"
}

View File

@ -1 +0,0 @@
import '@storybook/addon-actions/register';

View File

@ -1,11 +0,0 @@
import React from 'react';
import { configure, setAddon, addDecorator } from '@storybook/react';
import InfoAddon from '../src/';
addDecorator(story => <div style={{ padding: 20 }}>{story()}</div>);
setAddon(InfoAddon);
configure(() => {
require('../example/story');
}, module);

View File

@ -1,4 +0,0 @@
module.exports = () => {
// This is the default webpack config defined in the `../webpack.config.js`
// modify as you need.
};

View File

@ -1,28 +0,0 @@
// IMPORTANT
// ---------
// This is an auto generated file with React CDK.
// Do not modify this file.
// Use `.storybook/user/modify_webpack_config.js instead`.
const path = require('path');
const updateConfig = require('./user/modify_webpack_config');
const config = {
module: {
loaders: [
{
test: /\.css?$/,
loaders: ['style', 'raw'],
include: path.resolve(__dirname, '../'),
},
{
test: /\.json?$/,
loaders: ['json'],
include: path.resolve(__dirname, '../'),
},
],
},
};
updateConfig(config);
module.exports = config;

View File

@ -137,6 +137,7 @@ setDefaults({
maxPropArrayLength: 10, // Displays the first 10 items in the default prop array
maxPropStringLength: 100, // Displays the first 100 characters in the default prop string,
TableComponent: props => {}, // Override the component used to render the props table
excludedPropTypes: [], // Will exclude any respective properties whose name is included in array
}
```

View File

@ -1,21 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
const Button = ({ disabled, label, onClick }) => (
<button disabled={disabled} onClick={onClick}>
{label}
</button>
);
Button.propTypes = {
label: PropTypes.string.isRequired,
disabled: PropTypes.bool,
onClick: PropTypes.func,
};
Button.defaultProps = {
disabled: false,
onClick() {},
};
export default Button;

View File

@ -1,181 +0,0 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import Button from './Button';
storiesOf('Button').addWithInfo(
'simple usage',
'This is the basic usage with the button with providing a label to show the text.',
() => (
<div>
<Button label="The Button" onClick={action('onClick')} />
<br />
<p>Click the "?" mark at top-right to view the info.</p>
</div>
)
);
storiesOf('Button').addWithInfo(
'simple usage (inline info)',
`
This is the basic usage with the button with providing a label to show the text.
`,
() => <Button label="The Button" onClick={action('onClick')} />,
{ inline: true }
);
storiesOf('Button').addWithInfo(
'simple usage (disable source)',
`
This is the basic usage with the button with providing a label to show the text.
`,
() => <Button label="The Button" onClick={action('onClick')} />,
{ source: false, inline: true }
);
storiesOf('Button').addWithInfo(
'simple usage (no header)',
`
This is the basic usage with the button with providing a label to show the text.
`,
() => <Button label="The Button" onClick={action('onClick')} />,
{ header: false, inline: true }
);
storiesOf('Button').addWithInfo(
'simple usage (no prop tables)',
`
This is the basic usage with the button with providing a label to show the text.
`,
() => <Button label="The Button" onClick={action('onClick')} />,
{ propTables: false, inline: true }
);
storiesOf('Button').addWithInfo(
'simple usage (custom propTables)',
`
This is the basic usage with the button with providing a label to show the text.
Since, the story source code is wrapped inside a div, info addon can't figure out propTypes on it's own.
So, we need to give relevant React component classes manually using \`propTypes\` option as shown below:
~~~js
storiesOf('Button')
.addWithInfo(
'simple usage (custom propTables)',
<info>,
<storyFn>,
{ inline: true, propTables: [Button]}
);
~~~
`,
() => (
<div>
<Button label="The Button" onClick={action('onClick')} />
<br />
</div>
),
{ inline: true, propTables: [Button] }
);
storiesOf('Button').addWithInfo(
'simple usage (JSX description)',
<div>
<h2>This is a JSX info section</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ornare massa rutrum metus
commodo, a mattis velit dignissim. Fusce vestibulum turpis sed massa egestas pharetra. Sed at
libero nulla.
</p>
<p>
<a href="https://github.com/storybooks/react-storybook-addon-info">This is a link</a>
</p>
<p>
<img alt="350x150" src="http://placehold.it/350x150" />
</p>
</div>,
() => (
<div>
<Button label="The Button" onClick={action('onClick')} />
<br />
<p>Click the "?" mark at top-right to view the info.</p>
</div>
)
);
storiesOf('Button').addWithInfo(
'simple usage (inline JSX description)',
<div>
<h2>This is a JSX info section</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ornare massa rutrum metus
commodo, a mattis velit dignissim. Fusce vestibulum turpis sed massa egestas pharetra. Sed at
libero nulla.
</p>
<p>
<a href="https://github.com/storybooks/react-storybook-addon-info">This is a link</a>
</p>
<p>
<img alt="350x150" src="http://placehold.it/350x150" />
</p>
</div>,
() => <Button label="The Button" onClick={action('onClick')} />,
{ inline: true }
);
storiesOf('Button').addWithInfo(
'simple usage (maxPropsInLine === 1)',
`
This is the basic usage with the button with providing a label to show the text.
`,
() => <Button label="The Button" onClick={action('onClick')} />,
{ inline: true, maxPropsIntoLine: 1 }
);
storiesOf('Button').addWithInfo(
'simple usage (maxPropObjectKeys === 5)',
`
This is the basic usage with the button with providing a label to show the text.
`,
() => <Button label="The Button" object={{ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }} />,
{ inline: true, maxPropObjectKeys: 5 }
);
storiesOf('Button').addWithInfo(
'simple usage (maxPropArrayLength === 8)',
`
This is the basic usage with the button with providing a label to show the text.
`,
() => <Button label="The Button" array={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]} />,
{ inline: true, maxPropArrayLength: 8 }
);
storiesOf('Button').addWithInfo(
'simple usage (maxPropStringLength === 10)',
`
This is the basic usage with the button with providing a label to show the text.
`,
() => <Button label="The Button" string="1 2 3 4 5 6 7 8" />,
{ inline: true, maxPropStringLength: 5 }
);
storiesOf('Button').addWithInfo(
'with custom styles',
`
This is an example of how to customize the styles of the info components.
For the full styles available, see \`./src/components/Story.js\`
`,
() => <Button label="The Button" onClick={action('onClick')} />,
{
inline: true,
styles: stylesheet => ({
...stylesheet,
infoPage: {
backgroundColor: '#ccc',
},
}),
}
);

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-info",
"version": "4.0.0-alpha.1",
"version": "4.0.0-alpha.4",
"description": "A Storybook addon to show additional information for your stories.",
"license": "MIT",
"main": "dist/index.js",
@ -10,31 +10,27 @@
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": {
"prepare": "node ../../scripts/prepare.js",
"publish-storybook": "bash .scripts/publish_storybook.sh",
"storybook": "start-storybook -p 9010"
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/client-logger": "4.0.0-alpha.1",
"@storybook/components": "4.0.0-alpha.1",
"@storybook/client-logger": "4.0.0-alpha.4",
"@storybook/components": "4.0.0-alpha.4",
"babel-runtime": "^6.26.0",
"core-js": "2.5.5",
"glamor": "^2.20.40",
"glamorous": "^4.12.1",
"glamorous": "^4.12.4",
"global": "^4.3.2",
"marksy": "^6.0.3",
"nested-object-assign": "^1.0.1",
"prop-types": "^15.6.1",
"react-addons-create-fragment": "^15.5.3",
"react-lifecycles-compat": "^1.1.4",
"react-lifecycles-compat": "^3.0.2",
"util-deprecate": "^1.0.2"
},
"devDependencies": {
"@storybook/addon-actions": "4.0.0-alpha.1",
"@storybook/react": "4.0.0-alpha.1",
"react-test-renderer": "^16.3.1"
"react-test-renderer": "^16.3.2"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
"react": "*"
}
}

View File

@ -20,6 +20,7 @@ exports[`addon Info should render <Info /> and markdown 1`] = `
}
}
context={Object {}}
excludedPropTypes={Array []}
info="# Test story
## with markdown info
containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
@ -796,12 +797,15 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
val={[Function]}
>
<PropVal
level={1}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
theme={
Object {
"button": Object {
@ -932,6 +936,7 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
val={
Object {
"a": "a",
@ -940,9 +945,11 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
}
>
<PropVal
level={1}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
theme={
Object {
"button": Object {
@ -1041,139 +1048,187 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
>
<span>
{
<span
style={
<PreviewObject
level={1}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
val={
Object {
"color": "#666",
"a": "a",
"b": "b",
}
}
valueStyles={
Object {
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
{
<span
key="k0/.0"
style={
Object {
"color": "#666",
}
}
>
a
</span>
:
<PropVal
key="v0/.0"
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
theme={Object {}}
val="a"
valueStyles={
Object {
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
{
<span
style={
key="k0/.0"
>
<span
style={
Object {
"color": "#666",
}
}
>
a
</span>
</span>
:
<PropVal
key="v0/.0"
level={2}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
theme={Object {}}
val="a"
valueStyles={
Object {
"color": "#22a",
"wordBreak": "break-word",
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
"
a
"
</span>
</PropVal>
,
<span
key="k1/.0"
style={
Object {
"color": "#666",
}
}
>
b
</span>
:
<PropVal
key="v1/.0"
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
theme={Object {}}
val="b"
valueStyles={
Object {
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
<span
style={
Object {
"color": "#22a",
"wordBreak": "break-word",
}
}
>
a
</span>
</PropVal>
,
<span
style={
key="k1/.0"
>
<span
style={
Object {
"color": "#666",
}
}
>
b
</span>
</span>
:
<PropVal
key="v1/.0"
level={2}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
theme={Object {}}
val="b"
valueStyles={
Object {
"color": "#22a",
"wordBreak": "break-word",
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
"
b
"
</span>
</PropVal>
}
</span>
<span
style={
Object {
"color": "#22a",
"wordBreak": "break-word",
}
}
>
b
</span>
</PropVal>
}
</span>
</PreviewObject>
}
</span>
</PropVal>
@ -1202,6 +1257,7 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
val={
Array [
1,
@ -1211,9 +1267,11 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
}
>
<PropVal
level={1}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
theme={
Object {
"button": Object {
@ -1313,171 +1371,229 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
>
<span>
{
<span
style={
<PreviewArray
level={1}
maxPropArrayLength={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
val={
Array [
1,
2,
3,
]
}
valueStyles={
Object {
"color": "#666",
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
[
<PropVal
key="n0/.0"
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
theme={Object {}}
val={1}
valueStyles={
<span
style={
Object {
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
"color": "#666",
}
}
>
<span>
{
<span
style={
[
<span
key="n0/.0"
>
<PropVal
level={2}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
theme={Object {}}
val={1}
valueStyles={
Object {
"color": "#a11",
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
1
</span>
}
<span>
{
<span
style={
Object {
"color": "#a11",
}
}
>
1
</span>
}
</span>
</PropVal>
</span>
</PropVal>
,
<PropVal
key="n1/.0"
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
theme={Object {}}
val={2}
valueStyles={
Object {
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
<span>
{
<span
style={
,
<span
key="n1/.0"
>
<PropVal
level={2}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
theme={Object {}}
val={2}
valueStyles={
Object {
"color": "#a11",
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
2
</span>
}
<span>
{
<span
style={
Object {
"color": "#a11",
}
}
>
2
</span>
}
</span>
</PropVal>
</span>
</PropVal>
,
<PropVal
key="n2/.0"
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
theme={Object {}}
val={3}
valueStyles={
Object {
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
<span>
{
<span
style={
,
<span
key="n2/.0"
>
<PropVal
level={2}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
theme={Object {}}
val={3}
valueStyles={
Object {
"color": "#a11",
"array": Object {
"color": "#666",
},
"attr": Object {
"color": "#666",
},
"bool": Object {
"color": "#a11",
},
"empty": Object {
"color": "#777",
},
"func": Object {
"color": "#170",
},
"number": Object {
"color": "#a11",
},
"object": Object {
"color": "#666",
},
"string": Object {
"color": "#22a",
"wordBreak": "break-word",
},
}
}
>
3
</span>
}
<span>
{
<span
style={
Object {
"color": "#a11",
}
}
>
3
</span>
}
</span>
</PropVal>
</span>
</PropVal>
]
</span>
]
</span>
</PreviewArray>
}
</span>
</PropVal>
@ -1506,12 +1622,15 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
val={7}
>
<PropVal
level={1}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
theme={
Object {
"button": Object {
@ -1638,16 +1757,20 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
<span
style={Object {}}
>
"
<ThemedComponent
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
val="seven"
>
<PropVal
level={1}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
theme={
Object {
"button": Object {
@ -1747,12 +1870,11 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
}
}
>
"
seven
"
</span>
</PropVal>
</ThemedComponent>
"
</span>
</span>
</span>
@ -1967,12 +2089,14 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
" Component
</h2>
<Component
excludedPropTypes={Array []}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
type={[Function]}
>
<PropTable
excludedPropTypes={Array []}
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}

View File

@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
import 'core-js/fn/array/includes';
import { Table, Td, Th } from '@storybook/components';
import PropVal from './PropVal';
@ -22,6 +23,16 @@ export const multiLineText = input => {
));
};
const determineIncludedPropTypes = (propDefinitions, excludedPropTypes) => {
if (excludedPropTypes.length === 0) {
return propDefinitions;
}
return propDefinitions.filter(
propDefinition => !excludedPropTypes.includes(propDefinition.property)
);
};
export default function PropTable(props) {
const {
type,
@ -29,13 +40,16 @@ export default function PropTable(props) {
maxPropArrayLength,
maxPropStringLength,
propDefinitions,
excludedPropTypes,
} = props;
if (!type) {
return null;
}
if (!propDefinitions.length) {
const includedPropDefinitions = determineIncludedPropTypes(propDefinitions, excludedPropTypes);
if (!includedPropDefinitions.length) {
return <small>No propTypes defined!</small>;
}
@ -57,7 +71,7 @@ export default function PropTable(props) {
</tr>
</thead>
<tbody>
{propDefinitions.map(row => (
{includedPropDefinitions.map(row => (
<tr key={row.property}>
<Td bordered code>
{row.property}
@ -85,12 +99,14 @@ PropTable.displayName = 'PropTable';
PropTable.defaultProps = {
type: null,
propDefinitions: [],
excludedPropTypes: [],
};
PropTable.propTypes = {
type: PropTypes.func,
maxPropObjectKeys: PropTypes.number.isRequired,
maxPropArrayLength: PropTypes.number.isRequired,
maxPropStringLength: PropTypes.number.isRequired,
excludedPropTypes: PropTypes.arrayOf(PropTypes.string),
propDefinitions: PropTypes.arrayOf(
PropTypes.shape({
property: PropTypes.string.isRequired,

View File

@ -1,12 +1,42 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import { multiLineText } from './PropTable';
import PropTable, { multiLineText } from './PropTable';
describe('PropTable', () => {
describe('multiLineText', () => {
const singleLine = 'Foo bar baz';
const unixMultiLineText = 'foo \n bar \n baz';
const windowsMultiLineText = 'foo \r bar \r baz';
const propDefinitions = [
{
defaultValue: undefined,
description: '',
propType: { name: 'string' },
property: 'foo',
required: false,
},
];
const FooComponent = () => <div />;
const propTableProps = {
type: FooComponent,
maxPropArrayLength: 5,
maxPropObjectKeys: 5,
maxPropStringLength: 5,
propDefinitions,
};
it('should include all propTypes by default', () => {
const wrapper = mount(<PropTable {...propTableProps} />);
expect(wrapper).toMatchSnapshot();
});
it('should exclude excluded propTypes', () => {
const props = { ...propTableProps, excludedPropTypes: ['foo'] };
const wrapper = mount(<PropTable {...props} />);
expect(wrapper).toMatchSnapshot();
});
it('should return a blank string for a null input', () => {
expect(multiLineText(null)).toBe(null);

View File

@ -38,31 +38,117 @@ const getValueStyles = (codeColors = {}) => ({
},
});
function previewArray(val, maxPropArrayLength, valueStyles) {
function indent(breakIntoNewLines, level, isBlock) {
return (
breakIntoNewLines && (
<span>
<br />
{`${Array(level).join(' ')} `}
{!isBlock && ' '}
</span>
)
);
}
function PreviewArray({
val,
level,
maxPropArrayLength,
maxPropStringLength,
maxPropsIntoLine,
valueStyles,
}) {
const items = {};
const breakIntoNewLines = val.length > maxPropsIntoLine;
val.slice(0, maxPropArrayLength).forEach((item, i) => {
items[`n${i}`] = <PropVal val={item} valueStyles={valueStyles} />;
items[`c${i}`] = ', ';
items[`n${i}`] = (
<span>
{indent(breakIntoNewLines, level)}
<PropVal
val={item}
level={level + 1}
valueStyles={valueStyles}
maxPropStringLength={maxPropStringLength}
maxPropsIntoLine={maxPropsIntoLine}
/>
</span>
);
items[`c${i}`] = ',';
});
if (val.length > maxPropArrayLength) {
items.last = '…';
items.last = (
<span>
{indent(breakIntoNewLines, level)}
{'…'}
</span>
);
} else {
delete items[`c${val.length - 1}`];
}
return <span style={valueStyles.array}>[{createFragment(items)}]</span>;
return (
<span style={valueStyles.array}>
[{createFragment(items)}
{indent(breakIntoNewLines, level, true)}]
</span>
);
}
function previewObject(val, maxPropObjectKeys, valueStyles) {
PreviewArray.propTypes = {
val: PropTypes.any, // eslint-disable-line
maxPropArrayLength: PropTypes.number.isRequired,
maxPropStringLength: PropTypes.number.isRequired,
maxPropsIntoLine: PropTypes.number.isRequired,
level: PropTypes.number.isRequired,
valueStyles: PropTypes.shape({
func: PropTypes.object,
attr: PropTypes.object,
object: PropTypes.object,
array: PropTypes.object,
number: PropTypes.object,
string: PropTypes.object,
bool: PropTypes.object,
empty: PropTypes.object,
}).isRequired,
};
function PreviewObject({
val,
level,
maxPropObjectKeys,
maxPropStringLength,
maxPropsIntoLine,
valueStyles,
}) {
const names = Object.keys(val);
const items = {};
const breakIntoNewLines = names.length > maxPropsIntoLine;
names.slice(0, maxPropObjectKeys).forEach((name, i) => {
items[`k${i}`] = <span style={valueStyles.attr}>{name}</span>;
items[`k${i}`] = (
<span>
{indent(breakIntoNewLines, level)}
<span style={valueStyles.attr}>{name}</span>
</span>
);
items[`c${i}`] = ': ';
items[`v${i}`] = <PropVal val={val[name]} valueStyles={valueStyles} />;
items[`m${i}`] = ', ';
items[`v${i}`] = (
<PropVal
val={val[name]}
level={level + 1}
valueStyles={valueStyles}
maxPropStringLength={maxPropStringLength}
maxPropsIntoLine={maxPropsIntoLine}
/>
);
items[`m${i}`] = ',';
});
if (names.length > maxPropObjectKeys) {
items.rest = '…';
items.rest = (
<span>
{indent(breakIntoNewLines, level)}
{'…'}
</span>
);
} else {
delete items[`m${names.length - 1}`];
}
@ -70,13 +156,39 @@ function previewObject(val, maxPropObjectKeys, valueStyles) {
<span style={valueStyles.object}>
{'{'}
{createFragment(items)}
{indent(breakIntoNewLines, level, true)}
{'}'}
</span>
);
}
PreviewObject.propTypes = {
val: PropTypes.any, // eslint-disable-line
maxPropObjectKeys: PropTypes.number.isRequired,
maxPropStringLength: PropTypes.number.isRequired,
maxPropsIntoLine: PropTypes.number.isRequired,
level: PropTypes.number.isRequired,
valueStyles: PropTypes.shape({
func: PropTypes.object,
attr: PropTypes.object,
object: PropTypes.object,
array: PropTypes.object,
number: PropTypes.object,
string: PropTypes.object,
bool: PropTypes.object,
empty: PropTypes.object,
}).isRequired,
};
function PropVal(props) {
const { maxPropObjectKeys, maxPropArrayLength, maxPropStringLength, theme } = props;
const {
level,
maxPropObjectKeys,
maxPropArrayLength,
maxPropStringLength,
maxPropsIntoLine,
theme,
} = props;
let { val } = props;
const { codeColors } = theme || {};
let braceWrap = true;
@ -89,12 +201,23 @@ function PropVal(props) {
if (val.length > maxPropStringLength) {
val = `${val.slice(0, maxPropStringLength)}`;
}
content = <span style={valueStyles.string}>"{val}"</span>;
content = <span style={valueStyles.string}>{val}</span>;
braceWrap = false;
} else if (typeof val === 'boolean') {
content = <span style={valueStyles.bool}>{`${val}`}</span>;
} else if (Array.isArray(val)) {
content = previewArray(val, maxPropArrayLength, valueStyles);
content = (
<PreviewArray
{...{
val,
level,
maxPropArrayLength,
maxPropStringLength,
maxPropsIntoLine,
valueStyles,
}}
/>
);
} else if (typeof val === 'function') {
content = <span style={valueStyles.func}>{val.name ? `${val.name}()` : 'anonymous()'}</span>;
} else if (!val) {
@ -108,7 +231,18 @@ function PropVal(props) {
</span>
);
} else {
content = previewObject(val, maxPropObjectKeys, valueStyles);
content = (
<PreviewObject
{...{
val,
level,
maxPropObjectKeys,
maxPropStringLength,
maxPropsIntoLine,
valueStyles,
}}
/>
);
}
if (!braceWrap) return content;
@ -121,6 +255,8 @@ PropVal.defaultProps = {
maxPropObjectKeys: 3,
maxPropArrayLength: 3,
maxPropStringLength: 50,
maxPropsIntoLine: 3,
level: 1,
theme: {},
valueStyles: null,
};
@ -130,6 +266,8 @@ PropVal.propTypes = {
maxPropObjectKeys: PropTypes.number,
maxPropArrayLength: PropTypes.number,
maxPropStringLength: PropTypes.number,
maxPropsIntoLine: PropTypes.number,
level: PropTypes.number,
theme: PropTypes.shape({
codeColors: PropTypes.object,
}),

View File

@ -45,12 +45,15 @@ export default function Props(props) {
<span>
=
<span style={propValueStyle}>
{typeof nodeProps[name] === 'string' && '"'}
<PropVal
val={nodeProps[name]}
maxPropObjectKeys={maxPropObjectKeys}
maxPropArrayLength={maxPropArrayLength}
maxPropStringLength={maxPropStringLength}
maxPropsIntoLine={maxPropsIntoLine}
/>
{typeof nodeProps[name] === 'string' && '"'}
</span>
</span>
)}

View File

@ -1,7 +1,7 @@
/* eslint no-underscore-dangle: 0 */
import React, { createElement } from 'react';
import polyfill from 'react-lifecycles-compat';
import { polyfill } from 'react-lifecycles-compat';
import PropTypes from 'prop-types';
import global from 'global';
import { baseFonts } from '@storybook/components';
@ -331,7 +331,12 @@ class Story extends React.Component {
const array = Array.from(types.keys());
array.sort((a, b) => getName(a) > getName(b));
const { maxPropObjectKeys, maxPropArrayLength, maxPropStringLength } = this.props;
const {
maxPropObjectKeys,
maxPropArrayLength,
maxPropStringLength,
excludedPropTypes,
} = this.props;
const propTables = array.map((type, i) => (
// eslint-disable-next-line react/no-array-index-key
<div key={`${getName(type)}_${i}`}>
@ -341,6 +346,7 @@ class Story extends React.Component {
maxPropObjectKeys={maxPropObjectKeys}
maxPropArrayLength={maxPropArrayLength}
maxPropStringLength={maxPropStringLength}
excludedPropTypes={excludedPropTypes}
/>
</div>
));
@ -389,6 +395,7 @@ Story.propTypes = {
maxPropObjectKeys: PropTypes.number.isRequired,
maxPropArrayLength: PropTypes.number.isRequired,
maxPropStringLength: PropTypes.number.isRequired,
excludedPropTypes: PropTypes.arrayOf(PropTypes.string),
};
Story.defaultProps = {
@ -401,6 +408,7 @@ Story.defaultProps = {
showHeader: true,
showSource: true,
components: {},
excludedPropTypes: [],
};
polyfill(Story);

View File

@ -1,5 +1,36 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PropTable multiLineText should exclude excluded propTypes 1`] = `
<PropTable
excludedPropTypes={
Array [
"foo",
]
}
maxPropArrayLength={5}
maxPropObjectKeys={5}
maxPropStringLength={5}
propDefinitions={
Array [
Object {
"defaultValue": undefined,
"description": "",
"propType": Object {
"name": "string",
},
"property": "foo",
"required": false,
},
]
}
type={[Function]}
>
<small>
No propTypes defined!
</small>
</PropTable>
`;
exports[`PropTable multiLineText should have 2 br tags for 3 lines of text 1`] = `
Array [
<span>
@ -18,3 +49,144 @@ Array [
</span>,
]
`;
exports[`PropTable multiLineText should include all propTypes by default 1`] = `
<PropTable
excludedPropTypes={Array []}
maxPropArrayLength={5}
maxPropObjectKeys={5}
maxPropStringLength={5}
propDefinitions={
Array [
Object {
"defaultValue": undefined,
"description": "",
"propType": Object {
"name": "string",
},
"property": "foo",
"required": false,
},
]
}
type={[Function]}
>
<glamorous(table)>
<table
className="css-1ytzlk7"
>
<thead>
<tr>
<glamorous(th)
bordered={true}
>
<th
className="css-d52hbj"
>
property
</th>
</glamorous(th)>
<glamorous(th)
bordered={true}
>
<th
className="css-d52hbj"
>
propType
</th>
</glamorous(th)>
<glamorous(th)
bordered={true}
>
<th
className="css-d52hbj"
>
required
</th>
</glamorous(th)>
<glamorous(th)
bordered={true}
>
<th
className="css-d52hbj"
>
default
</th>
</glamorous(th)>
<glamorous(th)
bordered={true}
>
<th
className="css-d52hbj"
>
description
</th>
</glamorous(th)>
</tr>
</thead>
<tbody>
<tr
key="foo"
>
<glamorous(td)
bordered={true}
code={true}
>
<td
className="css-1ygfcef"
>
foo
</td>
</glamorous(td)>
<glamorous(td)
bordered={true}
code={true}
>
<td
className="css-1ygfcef"
>
<PrettyPropType
depth={1}
propType={
Object {
"name": "string",
}
}
>
<span>
string
</span>
</PrettyPropType>
</td>
</glamorous(td)>
<glamorous(td)
bordered={true}
>
<td
className="css-d52hbj"
>
-
</td>
</glamorous(td)>
<glamorous(td)
bordered={true}
>
<td
className="css-d52hbj"
>
-
</td>
</glamorous(td)>
<glamorous(td)
bordered={true}
>
<td
className="css-d52hbj"
/>
</glamorous(td)>
</tr>
</tbody>
</table>
</glamorous(table)>
</PropTable>
`;

View File

@ -78,6 +78,7 @@ function addInfo(storyFn, context, infoOptions) {
maxPropArrayLength: options.maxPropArrayLength,
maxPropsIntoLine: options.maxPropsIntoLine,
maxPropStringLength: options.maxPropStringLength,
excludedPropTypes: options.excludedPropTypes,
};
return <Story {...props}>{storyFn(context)}</Story>;
}

View File

@ -116,7 +116,7 @@ storiesOf('MyComponent', module)
### withTests(options)
- **options.results**: OBJECT jest output results. *mandatory*
- **filteExt**: STRING test file extention. *optionnal*. 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 extention. *optionnal*. 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...
## TODO

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-jest",
"version": "4.0.0-alpha.1",
"version": "4.0.0-alpha.4",
"description": "React storybook addon that show component jest report",
"keywords": [
"addon",
@ -25,16 +25,15 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/components": "4.0.0-alpha.1",
"@storybook/addons": "4.0.0-alpha.4",
"@storybook/components": "4.0.0-alpha.4",
"babel-runtime": "^6.26.0",
"glamor": "^2.20.40",
"glamorous": "^4.12.1",
"glamorous": "^4.12.4",
"global": "^4.3.2",
"prop-types": "^15.6.1"
},
"peerDependencies": {
"@storybook/addons": "^3.3.0",
"react": "*",
"react-dom": "*"
"react": "*"
}
}

View File

@ -1 +0,0 @@
import '../src/register';

View File

@ -1,12 +0,0 @@
// IMPORTANT
// ---------
// This is an auto generated file with React CDK.
// Do not modify this file.
import { configure } from '@storybook/react';
function loadStories() {
require('../example/stories');
}
configure(loadStories, module);

View File

@ -1,4 +0,0 @@
module.exports = () => {
// This is the default webpack config defined in the `../webpack.config.js`
// modify as you need.
};

View File

@ -1,23 +0,0 @@
// IMPORTANT
// ---------
// This is an auto generated file with React CDK.
// Do not modify this file.
// Use `.storybook/user/modify_webpack_config.js instead`.
const path = require('path');
const updateConfig = require('./user/modify_webpack_config');
const config = {
module: {
loaders: [
{
test: /\.css?$/,
loaders: ['style', 'raw'],
include: path.resolve(__dirname, '../'),
},
],
},
};
updateConfig(config);
module.exports = config;

View File

@ -161,6 +161,7 @@ const groupId = 'GROUP-ID1';
const value = text(label, defaultValue, groupId);
```
### boolean
Allows you to get a boolean value from the user.
@ -311,7 +312,7 @@ const options = {
Rainbow: ['red', 'orange', 'etc'],
None: null,
};
const defaultValue = 'Red';
const defaultValue = 'red';
const groupId = 'GROUP-ID1';
const value = selectV2(label, options, defaultValue, groupId);
@ -385,6 +386,9 @@ const stories = storiesOf('Storybook Knobs', module);
stories.addDecorator(withKnobsOptions({
debounce: { wait: number, leading: boolean}, // Same as lodash debounce.
timestamps: true // Doesn't emit events while user is typing.
escapeHTML: true // Escapes strings to be safe for inserting as innerHTML. This option is true by default in storybook for Vue, Angular, and Polymer, because those frameworks allow rendering plain HTML.
// You can still set it to false, but it's strongly unrecommendend in cases when you host your storybook on some route of your main site or web app.
}));
```

View File

@ -1,115 +0,0 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import moment from 'moment';
import {
withKnobs,
number,
object,
boolean,
text,
select,
date,
array,
color,
files,
} from '../../src';
const stories = storiesOf('Example of Knobs', module);
stories.addDecorator(withKnobs);
stories.add('simple example', () => <button>{text('Label', 'Hello Button')}</button>);
stories.add('with all knobs', () => {
const name = text('Name', 'Tom Cary');
const dob = date('DOB', new Date('January 20 1887'));
const bold = boolean('Bold', false);
const selectedColor = color('Color', 'black');
const favoriteNumber = number('Favorite Number', 42);
const comfortTemp = number('Comfort Temp', 72, { range: true, min: 60, max: 90, step: 1 });
const passions = array('Passions', ['Fishing', 'Skiing']);
const images = files('Happy Picture', 'image/*', [
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiARwMCyEWcOFPAAAAP0lEQVQoz8WQMQoAIAwDL/7/z3GwghSp4KDZyiUpBMCYUgd8rehtH16/l3XewgU2KAzapjXBbNFaPS6lDMlKB6OiDv3iAH1OAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTAxLTI4VDEyOjExOjMzLTA3OjAwlAHQBgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wMS0yOFQxMjoxMTozMy0wNzowMOVcaLoAAAAASUVORK5CYII=',
]);
const customStyle = object('Style', {
fontFamily: 'Arial',
padding: 20,
});
const style = {
...customStyle,
fontWeight: bold ? 800 : 400,
favoriteNumber,
color: selectedColor,
};
return (
<div style={style}>
I'm {name} and I was born on "{moment(dob).format('DD MMM YYYY')}" I like:{' '}
<ul>{passions.map(p => <li key={p}>{p}</li>)}</ul>
<p>My favorite number is {favoriteNumber}.</p>
<p>My most comfortable room temperature is {comfortTemp} degrees Fahrenheit.</p>
<p>
When I am happy I look like this: <img src={images[0]} alt="happy" />
</p>
</div>
);
});
stories.add('dates Knob', () => {
const today = date('today');
const dob = date('DOB', null);
const myDob = date('My DOB', new Date('July 07 1993'));
return (
<ul style={{ listStyleType: 'none', listStyle: 'none', paddingLeft: '15px' }}>
<li>
<p>
<b>Javascript Date</b> default value, passes date value
</p>
<blockquote>
<code>const myDob = date('My DOB', new Date('July 07 1993'));</code>
<pre>{`// I was born in: "${moment(myDob).format('DD MMM YYYY')}"`}</pre>
</blockquote>
</li>
<li>
<p>
<b>undefined</b> default value passes today's date
</p>
<blockquote>
<code>const today = date('today');</code>
<pre>{`// Today's date is: "${moment(today).format('DD MMM YYYY')}"`}</pre>
</blockquote>
</li>
<li>
<p>
<b>null</b> default value passes null value
</p>
<blockquote>
<code>const dob = date('DOB', null);</code>
<pre>
{`// You were born in: "${
dob ? moment(dob).format('DD MMM YYYY') : 'Please select date.'
}"`}
</pre>
</blockquote>
</li>
</ul>
);
});
stories.add('dynamic knobs', () => {
const showOptional = select('Show optional', ['yes', 'no'], 'yes');
return (
<div>
<div>{text('compulsary', 'I must be here')}</div>
{showOptional === 'yes' ? <div>{text('optional', 'I can disapear')}</div> : null}
</div>
);
});
stories.add('without any knob', () => <button>This is a button</button>);

View File

@ -1,103 +0,0 @@
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import * as moment from 'moment';
import {
withKnobs,
number,
color,
object,
boolean,
text,
select,
date
} from '../../storybook-addon-knobs';
const stories = storiesOf('Example of Knobs', module);
stories.addDecorator(withKnobs);
stories.add('simple example', () => (
<button>{text('Label', 'Hello Button')}</button>
));
stories.add('with all knobs', () => {
const name = text('Name', 'Tom Cary');
const dob = date('DOB', new Date('January 20 1887'));
const bold = boolean('Bold', false);
const selectedColor = color('Color', 'black');
const favoriteNumber = number('Favorite Number', 42);
const comfortTemp = number('Comfort Temp', 72, { range: true, min: 60, max: 90, step: 1 });
const textDecoration = select('Decoration', {
none: 'None',
underline: 'Underline',
"line-through": 'Line-Through'
}, 'none');
const customStyle = object('Style', {
fontFamily: 'Arial',
padding: 20,
});
const style = Object.assign({}, customStyle, {
fontWeight: bold ? 800: 400,
color: selectedColor,
textDecoration
});
return (
<div style={style}>
I'm {name} and I was born on "{moment(dob).format("DD MMM YYYY")}"
<p>My favorite number is {favoriteNumber}.</p>
<p>My most comfortable room temperature is {comfortTemp} degrees Fahrenheit.</p>
</div>
);
});
stories.add('dates Knob', () => {
const today = date('today');
const dob = date('DOB', null);
const myDob = date('My DOB', new Date('July 07 1993'));
return (
<ul style={{listStyleType:"none",listStyle:"none",paddingLeft:"15px"}}>
<li>
<p><b>Javascript Date</b> default value, passes date value</p>
<blockquote>
<code>const myDob = date('My DOB', new Date('July 07 1993'));</code>
<pre>// I was born in: "{moment(myDob).format("DD MMM YYYY")}"</pre>
</blockquote>
</li>
<li>
<p><b>undefined</b> default value passes today's date</p>
<blockquote>
<code>const today = date('today');</code>
<pre>// Today's date is: "{moment(today).format("DD MMM YYYY")}"</pre>
</blockquote>
</li>
<li>
<p><b>null</b> default value passes null value</p>
<blockquote>
<code>const dob = date('DOB', null);</code>
<pre>// You were born in: "{dob? moment(dob).format("DD MMM YYYY"): 'Please select date.'}"</pre>
</blockquote>
</li>
</ul>
)
});
stories.add('dynamic knobs', () => {
const showOptional = select('Show optional', ['yes', 'no'], 'yes')
return (
<div>
<div>
{text('compulsary', 'I must be here')}
</div>
{ showOptional==='yes' ? <div>{text('optional', 'I can disapear')}</div> : null }
</div>
)
});
stories.add('without any knob', () => (
<button>This is a button</button>
));

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-knobs",
"version": "4.0.0-alpha.1",
"version": "4.0.0-alpha.4",
"description": "Storybook Addon Prop Editor Component",
"license": "MIT",
"main": "dist/index.js",
@ -10,34 +10,29 @@
"url": "https://github.com/storybooks/storybook.git"
},
"scripts": {
"prepare": "node ../../scripts/prepare.js",
"publish-storybook": "bash .scripts/publish_storybook.sh",
"storybook": "start-storybook -p 9010"
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/components": "4.0.0-alpha.1",
"@storybook/addons": "4.0.0-alpha.4",
"@storybook/components": "4.0.0-alpha.4",
"babel-runtime": "^6.26.0",
"deep-equal": "^1.0.1",
"escape-html": "^1.0.3",
"global": "^4.3.2",
"insert-css": "^2.0.0",
"lodash.debounce": "^4.0.8",
"moment": "^2.22.0",
"moment": "^2.22.1",
"prop-types": "^15.6.1",
"react-color": "^2.14.0",
"react-color": "^2.14.1",
"react-datetime": "^2.14.0",
"react-lifecycles-compat": "^1.1.4",
"react-lifecycles-compat": "^3.0.2",
"react-textarea-autosize": "^6.1.0",
"util-deprecate": "^1.0.2"
},
"devDependencies": {
"@storybook/react": "4.0.0-alpha.1",
"raw-loader": "^0.5.1",
"style-loader": "^0.20.3",
"vue": "^2.5.16"
},
"peerDependencies": {
"@storybook/addons": "^3.3.0",
"react": "*",
"react-dom": "*"
"react": "*"
}
}

View File

@ -1,19 +1,48 @@
/* eslint no-underscore-dangle: 0 */
import deepEqual from 'deep-equal';
import escape from 'escape-html';
import KnobStore from './KnobStore';
// This is used by _mayCallChannel to determine how long to wait to before triggering a panel update
const PANEL_UPDATE_INTERVAL = 400;
const escapeStrings = obj => {
if (typeof obj === 'string') {
return escape(obj);
}
if (obj == null || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
const newArray = obj.map(escapeStrings);
const didChange = newArray.some((newValue, key) => newValue !== obj[key]);
return didChange ? newArray : obj;
}
return Object.entries(obj).reduce((acc, [key, oldValue]) => {
const newValue = escapeStrings(oldValue);
return newValue === oldValue ? acc : { ...acc, [key]: newValue };
}, obj);
};
export default class KnobManager {
constructor() {
this.knobStore = new KnobStore();
this.options = {};
}
setChannel(channel) {
this.channel = channel;
}
setOptions(options) {
this.options = options;
}
getKnobValue({ value }) {
return this.options.escapeHTML ? escapeStrings(value) : value;
}
knob(name, options) {
this._mayCallChannel();
@ -23,7 +52,7 @@ export default class KnobManager {
// But, if the user changes the code for the defaultValue we should set
// that value instead.
if (existingKnob && deepEqual(options.value, existingKnob.defaultValue)) {
return existingKnob.value;
return this.getKnobValue(existingKnob);
}
const defaultValue = options.value;
@ -34,7 +63,7 @@ export default class KnobManager {
};
knobStore.set(name, knobInfo);
return knobStore.get(name).value;
return this.getKnobValue(knobStore.get(name));
}
_mayCallChannel() {

View File

@ -1,5 +1,3 @@
import addons from '@storybook/addons';
import { prepareComponent } from './helpers';
import {
@ -15,7 +13,7 @@ import {
selectV2,
button,
files,
manager,
makeDecorators,
} from '../base';
export { knob, text, boolean, number, color, object, array, date, select, selectV2, button, files };
@ -23,19 +21,4 @@ export { knob, text, boolean, number, color, object, array, date, select, select
export const angularHandler = (channel, knobStore) => getStory => context =>
prepareComponent({ getStory, context, channel, knobStore });
function wrapperKnobs(options) {
const channel = addons.getChannel();
manager.setChannel(channel);
if (options) channel.emit('addon:knobs:setOptions', options);
return angularHandler(channel, manager.knobStore);
}
export function withKnobs(storyFn, context) {
return wrapperKnobs()(storyFn)(context);
}
export function withKnobsOptions(options = {}) {
return (storyFn, context) => wrapperKnobs(options)(storyFn)(context);
}
export const { withKnobs, withKnobsOptions } = makeDecorators(angularHandler, { escapeHTML: true });

View File

@ -1,4 +1,6 @@
import deprecate from 'util-deprecate';
import addons from '@storybook/addons';
import KnobManager from './KnobManager';
export const manager = new KnobManager();
@ -73,3 +75,25 @@ export function button(name, callback, groupId) {
export function files(name, accept, value = []) {
return manager.knob(name, { type: 'files', accept, value });
}
export function makeDecorators(handler, defaultOptions = {}) {
function wrapperKnobs(options) {
const allOptions = { ...defaultOptions, ...options };
manager.setOptions(allOptions);
const channel = addons.getChannel();
manager.setChannel(channel);
channel.emit('addon:knobs:setOptions', allOptions);
return handler(channel, manager.knobStore);
}
return {
withKnobs(storyFn, context) {
return wrapperKnobs()(storyFn)(context);
},
withKnobsOptions(options = {}) {
return (storyFn, context) => wrapperKnobs(options)(storyFn)(context);
},
};
}

View File

@ -155,31 +155,25 @@ export default class Panel extends React.Component {
const groups = {};
const groupIds = [];
Object.keys(knobs)
.filter(key => knobs[key].used && knobs[key].groupId)
.forEach(key => {
const knobKeyGroupId = knobs[key].groupId;
groupIds.push(knobKeyGroupId);
groups[knobKeyGroupId] = {
render: () => <div id={knobKeyGroupId}>{knobKeyGroupId}</div>,
title: knobKeyGroupId,
};
});
let knobsArray = Object.keys(knobs).filter(key => knobs[key].used);
let knobsArray = Object.keys(knobs);
knobsArray.filter(key => knobs[key].groupId).forEach(key => {
const knobKeyGroupId = knobs[key].groupId;
groupIds.push(knobKeyGroupId);
groups[knobKeyGroupId] = {
render: () => <div id={knobKeyGroupId}>{knobKeyGroupId}</div>,
title: knobKeyGroupId,
};
});
if (groupIds.length > 0) {
groups[DEFAULT_GROUP_ID] = {
render: () => <div id={DEFAULT_GROUP_ID}>{DEFAULT_GROUP_ID}</div>,
title: DEFAULT_GROUP_ID,
};
knobsArray = knobsArray.filter(key => {
const filter =
groupId === DEFAULT_GROUP_ID
? knobs[key].used
: knobs[key].used && knobs[key].groupId === groupId;
return filter;
});
if (groupId !== DEFAULT_GROUP_ID) {
knobsArray = knobsArray.filter(key => knobs[key].groupId === groupId);
}
}
knobsArray = knobsArray.map(key => knobs[key]);

View File

@ -2,6 +2,8 @@ import React from 'react';
import { shallow } from 'enzyme';
import ArrayType from '../types/Array';
jest.useFakeTimers();
describe('Array', () => {
it('should subscribe to setKnobs event of channel', () => {
const onChange = jest.fn();
@ -12,8 +14,9 @@ describe('Array', () => {
/>
);
wrapper.simulate('change', { target: { value: 'Fhishing,Skiing,Dancing' } });
expect(onChange).toHaveBeenCalledWith(['Fhishing', 'Skiing', 'Dancing']);
wrapper.simulate('change', { target: { value: 'Fishing,Skiing,Dancing' } });
jest.runAllTimers();
expect(onChange).toHaveBeenCalledWith(['Fishing', 'Skiing', 'Dancing']);
});
it('deserializes an Array to an Array', () => {
@ -41,6 +44,7 @@ describe('Array', () => {
);
wrapper.simulate('change', { target: { value: '' } });
jest.runAllTimers();
expect(onChange).toHaveBeenCalledWith([]);
});
});

Some files were not shown because too many files have changed in this diff Show More