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

Commit a26e33b

Browse files
authored
feat(docs): adding 'behaviors' section to menu (#119)
* editing,adding behaviours and adding acc. description for components * removing divider role as it was not correctly implemented * returning back divider file, which deleted by mistake * adding tests * adding test, modify tests, change format of description * another changes in descriptions * draft adding acc behaviours to sidebar menu * first raw version of behaviours in menu * adding parsing, UI improvement * adding link to component * another polish, moving comments, adding extract-comment package * removing not used commented code * adding comments to particular behavior files * adding another doc for particular behaviors * cleaning PR * toggleButton Behavior updated coresponding master * removing type from constants, taking from JSON or changed to hardcoded string * improving showing behaviors in menu * removing behavior description changes, it will be moved to new PR * removing description changes in component, it will be moved to new PR * removing changes in componentDocTag, it will go in next PR * removing unused imports * changes after review * fix after PR * - add behaviors menu to gulp watch * adding changelog * another fixes after json file was renamed
1 parent ca435ed commit a26e33b

File tree

10 files changed

+247
-6
lines changed

10 files changed

+247
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ coverage/
1010
dist/
1111
docs/src/componentInfo
1212
docs/src/componentMenu.json
13+
docs/src/behaviorMenu.json
1314
docs/src/exampleMenus
1415
docs/dist/
1516
dll/

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
2222

2323
### Features
2424
- Add `state` to `props` in component styling functions @Bugaa92 ([#173](https://github.com/stardust-ui/react/pull/173))
25+
- Adding 'behaviors' section to the menu, under the components @kolaps33 ([#119] (https://github.com/stardust-ui/react/pull/119)
2526

2627
<!--------------------------------[ v0.5.0 ]------------------------------- -->
2728
## [v0.5.0](https://github.com/stardust-ui/react/tree/v0.5.0) (2018-08-30)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import * as gutil from 'gulp-util'
2+
import * as path from 'path'
3+
import * as through2 from 'through2'
4+
import * as Vinyl from 'vinyl'
5+
import * as _ from 'lodash'
6+
import * as fs from 'fs'
7+
8+
const pluginName = 'gulp-component-menu-behaviors'
9+
const extract = require('extract-comments')
10+
const doctrine = require('doctrine')
11+
12+
type BehaviorMenuItem = {
13+
displayName: string
14+
type: string
15+
variations: {
16+
name: string
17+
text: string
18+
}
19+
}
20+
21+
export default () => {
22+
const result: BehaviorMenuItem[] = []
23+
function bufferContents(file, enc, cb) {
24+
if (file.isNull()) {
25+
cb(null, file)
26+
return
27+
}
28+
29+
if (file.isStream()) {
30+
cb(new gutil.PluginError(pluginName, 'Streaming is not supported'))
31+
return
32+
}
33+
34+
try {
35+
const absPath = path.resolve(process.cwd(), file.path)
36+
const dir = path.dirname(absPath)
37+
const componentType = _.lowerFirst(path.basename(path.dirname(dir)).replace(/s$/, ''))
38+
const behaviorVariantName = file.basename
39+
const behaviorName = path.basename(dir)
40+
41+
let description
42+
const fileContent = fs.readFileSync(file.path).toString()
43+
const blockComments = extract(fileContent).filter(comment => comment.type === 'BlockComment') // filtering only block comments
44+
const emptyDescriptionText = 'Behavior file has no description.'
45+
46+
// getting object that describes '@description' part of the comment's text
47+
if (!_.isEmpty(blockComments)) {
48+
const commentTokens = doctrine.parse(blockComments[0].raw, { unwrap: true }).tags
49+
const descriptionToken = commentTokens.find(token => token.title === 'description')
50+
description = descriptionToken ? descriptionToken.description : emptyDescriptionText
51+
} else {
52+
description = emptyDescriptionText
53+
}
54+
55+
result.push({
56+
displayName: behaviorName,
57+
type: componentType,
58+
variations: {
59+
name: behaviorVariantName,
60+
text: description,
61+
},
62+
})
63+
cb()
64+
} catch (err) {
65+
const pluginError = new gutil.PluginError(pluginName, err)
66+
const relativePath = path.relative(process.cwd(), file.path)
67+
pluginError.message = [
68+
gutil.colors.magenta(`Error in file: ${relativePath}`),
69+
gutil.colors.red(err.message),
70+
gutil.colors.gray(err.stack),
71+
].join('\n\n')
72+
this.emit('error', pluginError)
73+
}
74+
}
75+
76+
function getParsedResults() {
77+
return _(result)
78+
.groupBy('displayName')
79+
.map((behaviors, displayName) => ({
80+
displayName,
81+
type: behaviors[0].type,
82+
variations: _.map(behaviors, 'variations'),
83+
}))
84+
.value()
85+
}
86+
87+
function endStream(cb) {
88+
const file = new Vinyl({
89+
path: './behaviorMenu.json',
90+
contents: Buffer.from(JSON.stringify(getParsedResults(), null, 2)),
91+
})
92+
93+
this.push(file)
94+
cb()
95+
}
96+
97+
return through2.obj(bufferContents, endStream)
98+
}

build/gulp/tasks/docs.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as historyApiFallback from 'connect-history-api-fallback'
22
import * as express from 'express'
33
import { task, src, dest, lastRun, parallel, series, watch } from 'gulp'
4+
import * as remember from 'gulp-remember'
45
import * as path from 'path'
56
import * as rimraf from 'rimraf'
67
import * as through2 from 'through2'
@@ -11,14 +12,15 @@ import * as WebpackHotMiddleware from 'webpack-hot-middleware'
1112
import sh from '../sh'
1213
import config from '../../../config'
1314
import gulpComponentMenu from '../plugins/gulp-component-menu'
15+
import gulpComponentMenuBehaviors from '../plugins/gulp-component-menu-behaviors'
1416
import gulpExampleMenu from '../plugins/gulp-example-menu'
1517
import gulpReactDocgen from '../plugins/gulp-react-docgen'
1618

1719
const { paths } = config
1820
const g = require('gulp-load-plugins')()
1921
const { colors, log, PluginError } = g.util
2022

21-
const handleWatchChange = e => log(`File ${e.path} was ${e.type}, running tasks...`)
23+
const handleWatchChange = (path, stats) => log(`File ${path} was changed, running tasks...`)
2224

2325
// ----------------------------------------
2426
// Clean
@@ -32,6 +34,10 @@ task('clean:docs:component-menu', cb => {
3234
rimraf(paths.docsSrc('componentMenu.json'), cb)
3335
})
3436

37+
task('clean:docs:component-menu-behaviors', cb => {
38+
rimraf(paths.docsSrc('behaviorMenu.json'), cb)
39+
})
40+
3541
task('clean:docs:dist', cb => {
3642
rimraf(paths.docsDist(), cb)
3743
})
@@ -45,6 +51,7 @@ task(
4551
parallel(
4652
'clean:docs:component-info',
4753
'clean:docs:component-menu',
54+
'clean:docs:component-menu-behaviors',
4855
'clean:docs:dist',
4956
'clean:docs:example-menus',
5057
),
@@ -55,6 +62,7 @@ task(
5562
// ----------------------------------------
5663

5764
const componentsSrc = [`${config.paths.src()}/components/*/[A-Z]*.tsx`]
65+
const behaviorSrc = [`${config.paths.src()}/lib/accessibility/Behaviors/*/[A-Z]*.ts`]
5866
const examplesSrc = `${paths.docsSrc()}/examples/*/*/*/index.tsx`
5967
const markdownSrc = ['.github/CONTRIBUTING.md', 'specifications/*.md']
6068

@@ -70,6 +78,13 @@ task('build:docs:component-menu', () =>
7078
.pipe(dest(paths.docsSrc())),
7179
)
7280

81+
task('build:docs:component-menu-behaviors', () =>
82+
src(behaviorSrc, { since: lastRun('build:docs:component-menu-behaviors') })
83+
.pipe(remember('component-menu-behaviors'))
84+
.pipe(gulpComponentMenuBehaviors())
85+
.pipe(dest(paths.docsSrc())),
86+
)
87+
7388
task('build:docs:example-menu', () =>
7489
src(examplesSrc, { since: lastRun('build:docs:example-menu') })
7590
.pipe(gulpExampleMenu())
@@ -78,7 +93,12 @@ task('build:docs:example-menu', () =>
7893

7994
task(
8095
'build:docs:json',
81-
parallel('build:docs:docgen', 'build:docs:component-menu', 'build:docs:example-menu'),
96+
parallel(
97+
'build:docs:docgen',
98+
'build:docs:component-menu',
99+
'build:docs:component-menu-behaviors',
100+
'build:docs:example-menu',
101+
),
82102
)
83103

84104
task('build:docs:html', () => src(paths.docsSrc('404.html')).pipe(dest(paths.docsDist())))
@@ -193,6 +213,13 @@ task('watch:docs', cb => {
193213
// rebuild example menus
194214
watch(examplesSrc, series('build:docs:example-menu')).on('change', handleWatchChange)
195215

216+
watch(behaviorSrc, series('build:docs:component-menu-behaviors'))
217+
.on('change', handleWatchChange)
218+
.on('unlink', path => {
219+
log(`File ${path} was deleted, running tasks...`)
220+
remember.forget('component-menu-behaviors', path)
221+
})
222+
196223
// rebuild images
197224
watch(`${config.paths.src()}/**/*.{png,jpg,gif}`, series('build:docs:images')).on(
198225
'change',
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import * as _ from 'lodash'
2+
import PropTypes from 'prop-types'
3+
import * as React from 'react'
4+
const behaviorMenuItems = require('docs/src/behaviorMenu')
5+
import { Grid } from 'semantic-ui-react'
6+
import ComponentExampleTitle from './ComponentDoc/ComponentExample/ComponentExampleTitle'
7+
class DocsBehaviorRoot extends React.Component<any, any> {
8+
static propTypes = {
9+
children: PropTypes.node,
10+
match: PropTypes.shape({
11+
params: PropTypes.shape({
12+
name: PropTypes.string.isRequired,
13+
}),
14+
}),
15+
}
16+
17+
baseName(fileName: string) {
18+
const divided = _.startCase(fileName.replace('ts', ''))
19+
return _.upperFirst(_.lowerCase(divided))
20+
}
21+
22+
render() {
23+
const exampleStyle: React.CSSProperties = {
24+
position: 'relative',
25+
transition: 'box-shadow 200ms, background 200ms',
26+
background: '#fff',
27+
boxShadow: '0 1px 2px #ccc',
28+
margin: '10px',
29+
}
30+
31+
const commentBox: React.CSSProperties = {
32+
padding: 5,
33+
}
34+
const { match } = this.props
35+
return (
36+
<div style={commentBox}>
37+
{behaviorMenuItems
38+
.find(behavior => behavior.displayName === _.capitalize(match.params.name))
39+
.variations.map((variation, keyValue) => (
40+
<Grid key={keyValue} className="docs-example" style={exampleStyle}>
41+
<Grid.Column width={16} style={{ borderBottom: '1px solid #ddd' }}>
42+
<div style={{ display: 'flex' }}>
43+
<div style={{ flex: '1' }}>
44+
<ComponentExampleTitle
45+
id={_.kebabCase(variation.name)}
46+
title={this.baseName(variation.name)}
47+
description={`Behavior name: ${variation.name.replace('.ts', '')}`}
48+
/>
49+
</div>
50+
<div style={{ flex: '0 0 auto' }} />
51+
</div>
52+
</Grid.Column>
53+
<div style={{ paddingTop: '1rem', paddingBottom: '1rem' }}>
54+
<span> Description: </span>
55+
<br />
56+
{variation.text.split('\n').map((splittedText, keyValue) => {
57+
return (
58+
<span key={keyValue}>
59+
{splittedText}
60+
<br />
61+
</span>
62+
)
63+
})}
64+
</div>
65+
</Grid>
66+
))}
67+
</div>
68+
)
69+
}
70+
}
71+
72+
export default DocsBehaviorRoot

docs/src/components/DocsRoot.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as React from 'react'
55
import ComponentDoc from '../components/ComponentDoc'
66
import PageNotFound from '../views/PageNotFound'
77
import componentInfoContext from '../utils/componentInfoContext'
8+
import DocsBehaviorRoot from './DocsBehaviorRoot'
89

910
class DocsRoot extends React.Component<any, any> {
1011
static propTypes = {
@@ -22,6 +23,9 @@ class DocsRoot extends React.Component<any, any> {
2223
render() {
2324
const { match } = this.props
2425
const displayName = _.startCase(match.params.name).replace(/ /g, '')
26+
if (match.params.type === 'behaviors') {
27+
return <DocsBehaviorRoot {...this.props} />
28+
}
2529
const info = componentInfoContext.byDisplayName[displayName]
2630

2731
if (info) return <ComponentDoc info={info} />

docs/src/components/Sidebar/Sidebar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import { getComponentPathname, typeOrder, repoURL } from 'docs/src/utils'
1212

1313
const pkg = require('../../../../package.json')
1414
const componentMenu = require('docs/src/componentMenu')
15+
const behaviorMenu = require('docs/src/behaviorMenu')
1516

1617
const selectedItemLabelStyle: any = { color: '#35bdb2', float: 'right' }
1718
const selectedItemLabel = <span style={selectedItemLabelStyle}>Press Enter</span>
18-
1919
type ComponentMenuItem = { displayName: string; type: string }
2020

2121
class Sidebar extends React.Component<any, any> {
@@ -111,7 +111,7 @@ class Sidebar extends React.Component<any, any> {
111111
activeClassName="active"
112112
/>
113113
)),
114-
)(componentMenu)
114+
)([...componentMenu, ...behaviorMenu])
115115

116116
return (
117117
<Menu.Item key={nextType}>

docs/src/utils/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export const repoURL = 'https://github.com/stardust-ui/react'
2-
export const typeOrder = ['component']
2+
export const typeOrder = ['component', 'behavior']

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,15 @@
107107
"enzyme": "^3.1.0",
108108
"enzyme-adapter-react-16": "^1.0.1",
109109
"express": "^4.15.4",
110+
"extract-comments": "^1.0.0",
110111
"fbjs": "^0.8.17",
111112
"gh-pages": "^1.0.0",
112113
"glob": "^7.1.2",
113114
"gulp": "^4.0.0",
114115
"gulp-debug": "^4.0.0",
115116
"gulp-load-plugins": "^1.5.0",
116117
"gulp-plumber": "^1.2.0",
118+
"gulp-remember": "^1.0.1",
117119
"gulp-rename": "^1.3.0",
118120
"gulp-replace": "^1.0.0",
119121
"gulp-transform": "^3.0.5",

0 commit comments

Comments
 (0)