Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

docs(Examples): allow to use TS in examples #617

Merged
merged 13 commits into from
Dec 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ docs/src/componentInfo
docs/src/componentMenu.json
docs/src/behaviorMenu.json
docs/src/exampleMenus
docs/src/exampleSources
docs/dist/
dll/
node_modules/
Expand Down
36 changes: 36 additions & 0 deletions build/babel/transform-star-import-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as T from '@babel/types'
import { BabelPlugin } from './types'

/**
* Creates an default import:
* - import React from 'react'
*/
const createDefaultImportDeclaration = (
t: typeof T,
declaration: T.ImportDeclaration,
specifier: T.ImportNamespaceSpecifier,
): T.ImportDeclaration =>
t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(specifier.local.name))],
t.stringLiteral(declaration.source.value),
)

/**
* A plugin for Babel that performs AST transform:
* - from: import * as _ from 'lodash'
* - to: import _ from 'lodash'
*/
const starImportToDefaultPlugin: BabelPlugin = ({ types: t }) => ({
visitor: {
ImportDeclaration: path => {
const { specifiers } = path.node
const specifier = specifiers[0]

if (specifiers.length === 1 && t.isImportNamespaceSpecifier(specifier)) {
path.replaceWith(createDefaultImportDeclaration(t, path.node, specifier))
}
},
},
})

export default starImportToDefaultPlugin
22 changes: 22 additions & 0 deletions build/babel/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as T from '@babel/types'
import { NodePath } from '@babel/traverse'

export type BabelPluginArguments = {
types: typeof T
}

type BabelPluginVisitorFunction<T> = (path: NodePath<T>) => void
type BabelPluginVisitor<T> =
| BabelPluginVisitorFunction<T>
| {
exit: BabelPluginVisitorFunction<T>
}

export type BabelPlugin = (
options: BabelPluginArguments,
) => {
visitor: {
// This type is extendable, feel to add own visitor types.
ImportDeclaration: BabelPluginVisitor<T.ImportDeclaration>
}
}
55 changes: 55 additions & 0 deletions build/gulp/plugins/gulp-example-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as Babel from '@babel/core'
import * as gutil from 'gulp-util'
import * as prettier from 'prettier'
import * as through from 'through2'
import * as Vinyl from 'vinyl'

import * as prettierConfig from '../../../.prettierrc.json'
import { ExampleSource } from '../../../docs/src/types'
import transformStarImportPlugin from '../../babel/transform-star-import-plugin'
import { getRelativePathToSourceFile } from './util'

const pluginName = 'gulp-example-source'

const createExampleSourceCode = (file: Vinyl): ExampleSource => {
const tsSource = file.contents.toString()

const transformResult = Babel.transform(tsSource, {
plugins: [transformStarImportPlugin],
presets: [['@babel/preset-typescript', { allExtensions: true, isTSX: true }]],
sourceType: 'module',
})
const jsSource = prettier.format(transformResult.code, {
...prettierConfig,
parser: 'babylon',
})

return {
js: jsSource,
ts: tsSource,
}
}

export default () =>
through.obj((file: Vinyl, enc, cb) => {
if (file.isNull()) {
cb(null, file)
return
}

if (file.isStream()) {
cb(new gutil.PluginError(pluginName, 'Streaming is not supported'))
return
}

const sourcePath = getRelativePathToSourceFile(file.path)
const source = createExampleSourceCode(file)

cb(
null,
new Vinyl({
path: sourcePath,
contents: Buffer.from(JSON.stringify(source, null, 2)),
}),
)
})
13 changes: 13 additions & 0 deletions build/gulp/plugins/util/getRelativePathToSourceFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as path from 'path'
import config from '../../../../config'

const examplesPath = config.paths.docsSrc('examples', 'components')

/**
* Generates a relative path to a source file, outputs:
* Chat/Types/ChatExample.shorthand.source.json
*/
const getRelativePathToSourceFile = (filePath: string): string =>
`${path.relative(examplesPath, filePath).replace(/\.tsx$/, '')}.source.json`

export default getRelativePathToSourceFile
1 change: 1 addition & 0 deletions build/gulp/plugins/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './checksumUtils'
export { default as getComponentInfo } from './getComponentInfo'
export { default as getRelativePathToSourceFile } from './getRelativePathToSourceFile'
export { default as parseDefaultValue } from './parseDefaultValue'
export { default as parseDocblock } from './parseDocblock'
export { default as parseDocSection } from './parseDocSection'
Expand Down
33 changes: 30 additions & 3 deletions build/gulp/tasks/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as historyApiFallback from 'connect-history-api-fallback'
import * as express from 'express'
import { task, src, dest, lastRun, parallel, series, watch } from 'gulp'
import * as remember from 'gulp-remember'
import * as fs from 'fs'
import * as path from 'path'
import * as rimraf from 'rimraf'
import * as through2 from 'through2'
Expand All @@ -14,7 +15,9 @@ import config from '../../../config'
import gulpComponentMenu from '../plugins/gulp-component-menu'
import gulpComponentMenuBehaviors from '../plugins/gulp-component-menu-behaviors'
import gulpExampleMenu from '../plugins/gulp-example-menu'
import gulpExampleSource from '../plugins/gulp-example-source'
import gulpReactDocgen from '../plugins/gulp-react-docgen'
import { getRelativePathToSourceFile } from '../plugins/util'

const { paths } = config
const g = require('gulp-load-plugins')()
Expand Down Expand Up @@ -46,13 +49,18 @@ task('clean:docs:example-menus', cb => {
rimraf(paths.docsSrc('exampleMenus'), cb)
})

task('clean:docs:example-sources', cb => {
rimraf(paths.docsSrc('exampleSources'), cb)
})

task(
'clean:docs',
parallel(
'clean:docs:component-menu',
'clean:docs:component-menu-behaviors',
'clean:docs:dist',
'clean:docs:example-menus',
'clean:docs:example-sources',
),
)

Expand All @@ -62,7 +70,8 @@ task(

const componentsSrc = [`${paths.posix.src()}/components/*/[A-Z]*.tsx`, '!**/Slot.tsx']
const behaviorSrc = [`${paths.posix.src()}/lib/accessibility/Behaviors/*/[a-z]*.ts`]
const examplesSrc = `${paths.posix.docsSrc()}/examples/*/*/*/index.tsx`
const examplesIndexSrc = `${paths.posix.docsSrc()}/examples/*/*/*/index.tsx`
const examplesSrc = `${paths.posix.docsSrc()}/examples/*/*/*/!(*index|.knobs).tsx`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 for filtering out index files

const markdownSrc = [
'.github/CONTRIBUTING.md',
'.github/setup-local-development.md',
Expand Down Expand Up @@ -92,18 +101,25 @@ task('build:docs:component-menu-behaviors', () =>
)

task('build:docs:example-menu', () =>
src(examplesSrc, { since: lastRun('build:docs:example-menu') })
src(examplesIndexSrc, { since: lastRun('build:docs:example-menu') })
.pipe(remember('example-menu')) // FIXME: with watch this unnecessarily processes index files for all examples
.pipe(gulpExampleMenu())
.pipe(dest(paths.docsSrc('exampleMenus'))),
)

task('build:docs:example-sources', () =>
src(examplesSrc, { since: lastRun('build:docs:example-sources') })
.pipe(gulpExampleSource())
.pipe(dest(paths.docsSrc('exampleSources'))),
)

task(
'build:docs:json',
parallel(
series('build:docs:docgen', 'build:docs:component-menu'),
'build:docs:component-menu-behaviors',
'build:docs:example-menu',
'build:docs:example-sources',
),
)

Expand Down Expand Up @@ -218,10 +234,21 @@ task('watch:docs', cb => {
watch(componentsSrc, series('build:docs:docgen')).on('change', handleWatchChange)

// rebuild example menus
watch(examplesSrc, series('build:docs:example-menu'))
watch(examplesIndexSrc, series('build:docs:example-menu'))
.on('change', handleWatchChange)
.on('unlink', path => handleWatchUnlink('example-menu', path))

watch(examplesSrc, series('build:docs:example-sources'))
.on('change', handleWatchChange)
.on('unlink', filePath => {
log(`File ${filePath} was deleted, running tasks...`)

const sourceFilename = getRelativePathToSourceFile(filePath)
const sourcePath = config.paths.docsSrc('exampleSources', sourceFilename)

fs.unlinkSync(sourcePath)
})

watch(behaviorSrc, series('build:docs:component-menu-behaviors'))
.on('change', handleWatchChange)
.on('unlink', path => handleWatchUnlink('component-menu-behaviors', path))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ class SourceCodeManager {

private safeRequire = (path: string): string | undefined => {
try {
return require(`!raw-loader!../../../examples/${path}`)
const filename = `${path.replace(/^components\//, '')}.source.json`

return require(`!docs/src/exampleSources/${filename}`).js
} catch (e) {
return undefined
}
Expand Down
10 changes: 7 additions & 3 deletions docs/src/examples/components/Ref/Types/RefExample.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import React from 'react'
import * as React from 'react'
import { Button, Grid, Ref, Segment } from '@stardust-ui/react'

class RefExample extends React.Component {
type RefExampleState = {
isMounted: boolean
}

class RefExample extends React.Component<{}, RefExampleState> {
state = { isMounted: false }

createdRef = React.createRef<HTMLButtonElement>()
functionalRef = null

handleRef = node => (this.functionalRef = node)
handleRef = (node: HTMLButtonElement) => (this.functionalRef = node)

componentDidMount() {
this.setState({ isMounted: true })
Expand Down
20 changes: 13 additions & 7 deletions docs/src/examples/components/Ref/Types/RefForwardingExample.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import React from 'react'
import * as React from 'react'
import { Grid, Ref, Segment } from '@stardust-ui/react'

const ExampleButton = React.forwardRef<HTMLButtonElement>((props, ref) => (
<div>
<button {...props} ref={ref} />
</div>
))
type RefForwardingExampleState = {
isMounted: boolean
}

const ExampleButton = React.forwardRef<HTMLButtonElement, { children: React.ReactNode }>(
(props, ref) => (
<div>
<button {...props} ref={ref} />
</div>
),
)

class RefForwardingExample extends React.Component {
class RefForwardingExample extends React.Component<{}, RefForwardingExampleState> {
forwardedRef = React.createRef<HTMLButtonElement>()
state = { isMounted: false }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const TextExampleDisabledShorthand = () => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const TextExampleDisabled = () => <Text disabled>This feature has been disabled.</Text>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const TextExampleErrorShorthand = () => <Text error content="There has been an error." />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const TextExampleError = () => <Text error>There has been an error.</Text>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const TextExampleSuccessShorthand = () => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const TextExampleSuccess = () => <Text success>Your action has completed successfully.</Text>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const TextExampleTemporaryShorthand = () => <Text temporary content="Lorem ipsum dolor" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const TextExampleTemporary = () => <Text temporary>Lorem ipsum dolor</Text>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const [notTruncatedText, truncatedText] = [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const [notTruncatedText, truncatedText] = [
Expand Down
2 changes: 1 addition & 1 deletion docs/src/examples/components/Text/States/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import * as _ from 'lodash'
import { Provider, Text } from '@stardust-ui/react'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import * as _ from 'lodash'
import { Provider, Text } from '@stardust-ui/react'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const TextWeightsExampleShorthand = () => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { Text } from '@stardust-ui/react'

const TextWeightsExample = () => (
Expand Down
2 changes: 1 addition & 1 deletion docs/src/examples/components/Text/Types/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

Expand Down
Loading