diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..129fbaba56
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,447 @@
+CONTRIBUTING
+============
+
+
+
+
+
+- [Getting Started](#getting-started)
+ - [Clone & Install](#clone-&-install)
+ - [Commit Messages](#commit-messages)
+ - [Commands](#commands)
+- [Workflow](#workflow)
+ - [Create a Component](#create-a-component)
+ - [Define _meta](#define-_meta)
+ - [Conformance Test](#conformance-test)
+ - [Open A PR](#open-a-pr)
+ - [Spec out the API](#spec-out-the-api)
+- [API](#api)
+ - [SUI HTML Classes](#sui-html-classes)
+ - [API Patterns](#api-patterns)
+ - [Prop Utils](#prop-utils)
+ - [Testing className](#testing-classname)
+ - [SUI HTML Markup](#sui-html-markup)
+- [Testing](#testing)
+ - [Common Tests](#common-tests)
+ - [Usage](#usage)
+ - [isConformant (required)](#isconformant-required)
+- [State](#state)
+ - [AutoControlledComponent](#autocontrolledcomponent)
+- [Documentation](#documentation)
+ - [Website](#website)
+ - [Components](#components)
+ - [Props](#props)
+ - [Examples](#examples)
+
+
+
+## Getting Started
+
+### Clone & Install
+
+Start by cloning this repo and installing dependencies:
+
+```sh
+git clone git@github.com:TechnologyAdvice/stardust.git
+cd stardust
+npm install
+```
+
+### Commit Messages
+
+Please follow the [Angular Git Commit Guidelines][8] format.
+
+### Commands
+
+>This list is not updated, you should run `npm run` to see all scripts.
+
+```sh
+npm start // run doc site
+npm run start:local-modules // run offline (slower builds)
+
+npm test // test once
+npm run test:watch // test on file change
+
+npm run build // build everything
+npm run build:dist // build dist
+npm run build:docs // build docs
+npm run build:docs-toc // build toc for markdown files
+
+npm run deploy:docs // deploy gh-pages doc site
+
+npm run lint // lint once
+npm run lint:fix // lint and attempt to fix
+npm run lint:watch // lint on file change
+```
+
+## Workflow
+
+- [Create a Component](#create-a-component)
+- [Define _meta](#define-_meta)
+- [Conformance Test](#conformance-test)
+- [Open A PR](#open-a-pr)
+- [Spec out the API](#spec-out-the-api)
+
+### Create a Component
+
+Create components in `src`. The directory structure follows SUI naming conventions. If you're updating a component, push a small change so you can open a PR early.
+
+Stateless components should be written as a `function`:
+
+```js
+function Button(props) {
+ // ...
+}
+```
+
+Stateful components should be classes:
+
+```js
+import AutoControlledComponent from 'src/utils/AutoControlledComponent'
+
+class Dropdown extends AutoControlledComponent {
+ // ...
+}
+```
+
+>You probably need to extend our [`AutoControlledComponent`](#autocontrolledcomponent) to support both [controlled][2] and [uncontrolled][3] component patterns.
+
+### Define _meta
+
+Every component has a static property called `_meta`. This object defines the component. The values here are used in `propTypes`, generated documentation, generated test cases, and some utilities.
+
+Here's an example `_meta` object:
+
+```js
+import META from 'src/utils/Meta'
+
+const _meta = {
+ library: META.library.semanticUI,
+ name: 'MyComponent',
+ type: META.type.module,
+ props: {
+ pointing: ['bottom left', 'bottom right'],
+ },
+}
+```
+
+Assuming the above `_meta` is in scope, here's how you should expose it:
+
+```js
+function MyComponent() {
+ return
+ }
+}
+```
+
+### Conformance Test
+
+Review [common tests](#common-tests) below. You should now add the [`isConformant()`](#isconformant-required) common test and get it to pass. This will validate the `_meta` and help you get your component off the ground.
+
+### Open A PR
+
+This is a good time to open your PR. The component has been created, but the API and internals are not yet coded. We prefer to collaborate on these things to minimize rework.
+
+This will also with getting early feedback and smaller faster iterations on your component.
+
+### Spec out the API
+
+Review the SUI documentation for the component. Spec out the component's proposed API. The spec should demonstrate how your component's API will support all the native SUI features. You can reference this [API proposal][7] for the Input.
+
+Once we have solidified the component spec, it's time to write some code. The following sections cover everything you'll need to spec and build your awesome component.
+
+## API
+
+The primary areas of focus when designing a component API are:
+
+1. [SUI HTML Classes](#sui-html-classes)
+1. [SUI HTML Markup](#sui-html-markup)
+
+Our goal is to map these to a declarative component API. We map HTML classes to component props. We map markup to sub components (and sometimes props).
+
+### SUI HTML Classes
+
+SUI component definitions (style and behavior) are defined by HTML classes. These classes can be split into 4 groups:
+
+1. Standalone — `basic` `compact` `fluid`
+1. Pairs — `left floated` `right floated`
+1. Mixed — `corner` `top corner`, `padded` `very padded`
+1. Groups — sizes: `tiny` `small` `big`, colors: `red` `green` `blue`
+
+Each group has an API pattern and prop util for building up the `className` and a [Common test](#commont-tests).
+
+#### API Patterns
+
+```js
+ // standalone
+ // pairs
+ // mixed
+
+ // groups
+```
+
+```html
+
+
+
+
+
+```
+
+#### Prop Utils
+
+Use [`propUtils`][4] to extract the prop values and build up the `className`. Grouped classes like `color` and `size` simply use the prop value as the `className`.
+
+```js
+import cx from 'classnames'
+import { useKeyOnly, useValueAndKey, useKeyOrValueAndKey } from 'src/utils/propUtils'
+
+function Segment({ size, color, basic, floated, padded }) {
+ const classes = cx(
+ 'ui',
+ size,
+ color,
+ useKeyOnly(basic, 'basic'),
+ useValueAndKey(floated, 'floated'),
+ useKeyOrValueAndKey(padded, 'padded'),
+ 'segment'
+ )
+
+ return
+}
+```
+
+#### Testing className
+
+Use [`commonTests`](#common-tests) to test the `className` build up for each prop. These tests will run your component through all the possible usage permutations:
+
+```js
+import * as common from 'test/specs/commonTests'
+import Segment from 'src/elements/Segment/Segment'
+
+describe('Segment', () => {
+ common.propValueOnlyToClassName(Segment, 'size')
+ common.propValueOnlyToClassName(Segment, 'color')
+ common.propKeyOnlyToClassName(Segment, 'basic')
+ common.propKeyAndValueToClassName(Segment, 'floated')
+ common.propKeyOrValueToClassName(Segment, 'padded')
+})
+````
+
+### SUI HTML Markup
+
+SUI components can be nested. When nested, the supported features and markup usually change.
+
+Example, a [`header` element][5] accepts a size. It can be nested in a `list`, `modal`, `menu`, etc. The `header` size class is not valid when nested in these components. You size the parent component instead.
+
+Though these headers share the class `header`, they are entirely different components. In order to preserve accurate `propTypes` validation and separate concerns, use sub components to design component markup. This allows each sub component to have its own props and markup:
+
+```js
+
+ Apples
+ Oranges
+ Pears
+
+```
+
+Create the sub component as a separate component in the parent component's directory:
+
+```js
+function ListItem() {
+ // ...
+}
+```
+
+Attach it to the parent via static properties:
+
+```js
+import ListItem from './ListItem'
+
+function List() {
+ // ...
+}
+
+List.Item = ListItem
+```
+
+```js
+import ListItem from './ListItem'
+
+class List {
+ static Item = ListItem
+}
+````
+
+## Testing
+
+Run tests during development with `npm run test:watch` to re-run tests on file changes.
+
+### Common Tests
+
+There are many common things to test for. Because of this, we have [`test/specs/commonTests.js`][1].
+
+>This list is not updated, check the [source][1] for current tests and inline documentation.
+
+```js
+common.isConformant()
+common.hasUIClassName()
+common.hasSubComponents()
+common.isTabbable()
+common.rendersChildren()
+common.implementsAlignedProp()
+common.implementsIconProp()
+common.implementsImageProp()
+common.propKeyOnlyToClassName()
+common.propValueOnlyToClassName()
+common.propKeyAndValueToClassName()
+common.propKeyOrValueToClassName()
+````
+
+#### Usage
+
+Every common test receives your component as its first argument.
+
+```js
+import React from 'react'
+import * as common from 'test/specs/commonTests'
+import Menu from 'src/collections/Menu/Menu'
+import MenuItem from 'src/collections/Menu/MenuItem'
+
+describe('Menu', () => {
+ common.isConformant(Menu)
+ common.hasUIClassName(Menu)
+ common.rendersChildren(Menu)
+ common.hasSubComponents(Menu, [MenuItem]) // some take additional arguments
+})
+```
+
+The last argument to a common test is always `requiredProps`. If your component requires certain props to render, you can pass those last:
+
+```js
+import * as common from 'test/specs/commonTests'
+import Select from 'src/addons/Select/Select'
+
+const requiredProps = {
+ options: [],
+}
+
+describe('Select', () => {
+ common.isConformant(Select, requiredProps)
+})
+```
+
+#### isConformant (required)
+
+This is the only required test. It ensures a consistent baseline for the framework. It also helps you get your component off the ground. You should add this test to new components right away.
+
+>This list is not updated, check the [source][1] for the latest assertions.
+
+1. The [static `_meta`](#_meta) object is valid
+1. Component and filename are correct
+1. Events are properly handled
+1. Extra `props` are spread
+1. Base `className`s are applied
+1. Component is exported if public / hidden if private
+
+## State
+
+TODO
+
+### AutoControlledComponent
+
+TODO
+
+>For now, you should reference Dropdown as an example implementation. You can also consult the comments in AutoControlledComponent.js for more background.
+
+## Documentation
+
+- [Website](#website)
+- [Components](#components)
+- [Props](#props)
+- [Examples](#examples)
+
+Our docs are generated from doc block comments, `propTypes`, and hand written examples.
+
+### Website
+
+Developing against the doc site is a good way to try your component as you build it. Run the doc site with:
+
+```sh
+npm start
+```
+
+### Components
+
+A doc block should appear above a component class or function to describe it:
+
+```js
+/**
+ * A is sugar for .
+ * @see Dropdown
+ */
+function Select(props) {
+ return
+}
+```
+
+### Props
+
+A doc block should appear above each prop in `propTypes` to describe them:
+
+>Limited props shown for brevity.
+
+```js
+Label.propTypes = {
+ /** A label can reduce its complexity. */
+ basic: PropTypes.bool,
+
+ /** Primary content of the label, same as text. */
+ children: PropTypes.node,
+
+ /** Classes to add to the label className. */
+ className: PropTypes.string,
+
+ /** Color of the label. */
+ color: PropTypes.oneOf(Label._meta.props.colors),
+
+ /** Place the label in one of the upper corners . */
+ corner: PropTypes.oneOfType([
+ PropTypes.bool,
+ PropTypes.oneOf(Label._meta.props.corner),
+ ]),
+
+ /** Add an icon by icon className or pass an */
+ icon: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.element,
+ ]),
+}
+```
+
+### Examples
+
+>This section is lacking in instruction as the the docs are set to be overhauled (PRs welcome!).
+
+Usage examples for a component live in `docs/app/Examples`. The examples follow the SUI doc site examples.
+
+Adding documentation for new components is a bit tedious. The best way to do this (for now) is to copy an existing component's and update them.
+
+[1]: https://github.com/TechnologyAdvice/stardust/blob/master/test/specs/commonTests.js
+[2]: https://facebook.github.io/react/docs/forms.html#controlled-components
+[3]: https://facebook.github.io/react/docs/forms.html#uncontrolled-components
+[4]: https://github.com/TechnologyAdvice/stardust/blob/master/src/utils/propUtils.js
+[5]: http://semantic-ui.com/elements/header
+[6]: http://semantic-ui.com/views/item
+[7]: https://github.com/TechnologyAdvice/stardust/pull/281#issuecomment-228663527
+[8]: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit
diff --git a/README.md b/README.md
index 016090dd66..ec246728e9 100644
--- a/README.md
+++ b/README.md
@@ -6,16 +6,30 @@
The [official][8] integration between [Semantic UI][5] and [React][3].
-## Getting Started
-Hey, we're in development. Minor versions may introduce **breaking changes until the [v1.0][6] release**.
+>Hey, we're in development. There are [big changes](#how-can-i-help) taking place while we [migrate to SUI-Org][12]. Minor versions may introduce **breaking changes until the [v1.0][6] release**.
->There are [big changes](#how-can-i-help) taking place while we [migrate to SUI-Org][12].
+
+
-### Installation
+
+- [Install](#install)
+- [Usage](#usage)
+- [Debugger](#debugger)
+- [How Can I Help?](#how-can-i-help)
+ - [v1.0 Migrations](#v10-migrations)
+ - [New Components](#new-components)
+- [Our Principles](#our-principles)
+- [Support](#support)
+- [Releasing](#releasing)
+- [Credit](#credit)
+
+
+
+## Install
npm i stardust -S
-### Usage
+## Usage
**App.js**
@@ -56,8 +70,22 @@ We then use [Webpack][13] to create `bundle.js` from `App.js` and include it in
For more complete examples, check out the [Doc Site][2].
+## Debugger
+
+We use the [debug](https://www.npmjs.com/package/debug) module for debugging. You can turn debugging on and off via the `localStorage.debug` flag from the browser console. See the [debug docs](https://www.npmjs.com/package/debug) for more.
+
+```js
+localStorage.debug = 'stardust:*' // default, debug all components
+localStorage.debug = 'stardust:dropdown' // debug only the dropdown
+localStorage.debug = null // turn debug off
+```
+
+Once you change the flag, you need to refresh your browser to see the changes in debug output.
+
## How Can I Help?
+First, get setup and acquainted with development by reading the [contributing guidelines][1].
+
### v1.0 Migrations
We're making two migrations right now:
@@ -88,121 +116,38 @@ Be sure to check out the above migrations before embarking on a new component.
## Support
-### Elements
-
-- [x] Button
-- [x] Container
-- [x] Divider
-- [ ] Flag
-- [x] Header
-- [x] Icon
-- [x] Image
-- [x] Input
-- [x] Label
-- [x] List
-- [ ] Loader
-- [ ] Rail
-- [ ] Reveal
-- [x] Segment
-- [ ] Step
-
-### Collections
-
-- [ ] Breadcrumb
-- [x] Form
-- [x] Grid
-- [x] Menu
-- [x] Message
-- [x] Table
-
-### Views
-
-- [ ] Advertisement
-- [ ] Card
-- [ ] Comment
-- [ ] Feed
-- [x] Item
-- [x] Statistic
-
-### Modules
-
-- [ ] Accordion
-- [x] Checkbox
-- [ ] Dimmer
-- [x] Dropdown
-- [ ] Embed
-- [x] Modal
-- [ ] Nag
-- [ ] Popup
-- [x] Progress
-- [ ] Rating
-- [ ] Search
-- [ ] Shape
-- [ ] Sidebar
-- [ ] Sticky
-- [ ] Tab
-- [ ] Transition
-
-### Behaviors
-
-- API (not supported)
-- [x] Form Validation
-- Visibility (not supported)
-
-## Development
-
-Start by cloning this repo and installing dependencies:
-
- git clone git@github.com:TechnologyAdvice/stardust.git
- cd stardust
- npm install
-
-### Doc Site
-
-Once dependencies are installed, start the application with:
-
- npm start
-
-This launches the doc site for development. [Webpack Dev Server][7] will watch your JS files for changes and automatically transpile, lint and provide source maps.
-
-### Tests
-
-It is also helpful to develop against tests:
-
- npm test
-
-This will run PhantomJS with Karma on the command line. Just as before, JS files are watched and re-tested on change.
-
-### Debugger
-
-We use the [debug](https://www.npmjs.com/package/debug) module for debugging. You can turn debugging on and off via the `localStorage.debug` flag from the browser console. See the [debug docs](https://www.npmjs.com/package/debug) for more.
-
-```js
-localStorage.debug = 'stardust:*' // default, debug all components
-localStorage.debug = 'stardust:dropdown' // debug only the dropdown
-localStorage.debug = null // turn debug off
-```
-
-Once you change the flag, you need to refresh your browser to see the changes in debug output.
-
-### Commands
-
-List all scripts:
-
- npm run
-
-### Releasing
+| Elements | Collections | Views | Modules | Behaviors |
+|-----------------|-----------------|-----------------|-----------------|--------------------|
+| x Button | _ Breadcrumb | _ Advertisement | _ Accordion | x Form Validation |
+| x Container | x Form | _ Card | x Checkbox | *API (NA)* |
+| x Divider | x Grid | _ Comment | _ Dimmer | *Visibility (NA)* |
+| _ Flag | x Menu | _ Feed | x Dropdown | |
+| x Header | x Message | x Item | _ Embed | |
+| x Icon | x Table | x Statistic | x Modal | |
+| x Image | | | _ Nag | |
+| x Input | | | _ Popup | |
+| x Label | | | x Progress | |
+| x List | | | _ Rating | |
+| _ Loader | | | _ Search | |
+| _ Rail | | | _ Shape | |
+| _ Reveal | | | _ Sidebar | |
+| x Segment | | | _ Sticky | |
+| _ Step | | | _ Tab | |
+| | | | _ Transition | |
+
+## Releasing
On the latest clean `master`:
- npm run release:major
- npm run release:minor
- npm run release:patch
+```sh
+npm run release:major
+npm run release:minor
+npm run release:patch
+```
## Credit
-Originally created with :heart: at [TechnologyAdvice][9].
-
+Originally created with :heart: at [TechnologyAdvice][9]. A ridiculous [place to work][15].
[1]: https://github.com/TechnologyAdvice/stardust/blob/master/docs/app/ComponentGuidelines.md
[2]: https://technologyadvice.github.io/stardust/
@@ -219,3 +164,4 @@ Originally created with :heart: at [TechnologyAdvice][9].
[13]: https://webpack.github.io
[14]: https://github.com/TechnologyAdvice/stardust/issues
[15]: https://github.com/TechnologyAdvice/stardust/issues/269
+[16]: https://github.com/TechnologyAdvice/careers
diff --git a/build/webpack.config.js b/build/webpack.config.js
index 908c75eb3d..11162b2895 100644
--- a/build/webpack.config.js
+++ b/build/webpack.config.js
@@ -183,9 +183,7 @@ if (argv.localModules) {
} else {
webpackConfig.module.noParse = [
...webpackConfig.module.noParse,
- // /faker/,
/jquery/,
- // /lodash/,
/semantic-ui-css\/semantic\.js/,
/semantic-ui-css\/semantic\.css/,
]
diff --git a/package.json b/package.json
index 6d2c877785..1b5b291808 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,9 @@
"build": "npm run build:dist && npm run build:docs",
"prebuild:dist": "rimraf dist",
"build:dist": "babel src -d dist",
+ "prebuild:docs": "build:docs-toc",
"build:docs": "gulp docs",
+ "build:docs-toc": "doctoc README.md CONTRIBUTING.md --github --maxlevel 4",
"predeploy:docs": "NODE_ENV=production npm run build:docs",
"deploy:docs": "gh-pages -d docs/build -m 'deploy docs [ci skip]'",
"lint": "eslint .",
@@ -66,6 +68,7 @@
"css-loader": "^0.23.1",
"del": "^2.0.2",
"dirty-chai": "^1.2.2",
+ "doctoc": "^1.2.0",
"doctrine": "^1.2.1",
"empty": "^0.10.1",
"enzyme": "^2.2.0",
diff --git a/src/elements/Label/Label.js b/src/elements/Label/Label.js
index a6dc429dea..6af7df05eb 100644
--- a/src/elements/Label/Label.js
+++ b/src/elements/Label/Label.js
@@ -85,7 +85,7 @@ Label.propTypes = {
/** Attach to a . */
attached: PropTypes.oneOf(Label._meta.props.attached),
- /** A label can reduce its complexity */
+ /** A label can reduce its complexity. */
basic: PropTypes.bool,
/** Primary content of the label, same as text. */
@@ -97,7 +97,7 @@ Label.propTypes = {
/** Color of the label. */
color: PropTypes.oneOf(Label._meta.props.colors),
- /** Place the label in one of the upper corners . */
+ /** Place the label in one of the upper corners. */
corner: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.oneOf(Label._meta.props.corner),
@@ -118,7 +118,7 @@ Label.propTypes = {
/** Make the label circular, or a dot if it is empty. */
circular: PropTypes.bool,
- /** Add an icon by icon className or pass an */
+ /** Add an icon by icon className or pass an */
icon: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,