Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message component #62

Merged
merged 9 commits into from
Oct 19, 2015
147 changes: 91 additions & 56 deletions docs/app/Component Guidelines.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
# Stardust Component Guidelines
Copy link
Member Author

Choose a reason for hiding this comment

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


Every component in Stardust must conform to these guidelines. They ensure consistency and optimal development experience for Stardust users.
Every component in Stardust must conform to these guidelines.
They ensure consistency and optimal development experience for Stardust users.

This document will be minimally maintained. See [`\test`](https://github.com/TechnologyAdvice/stardust/tree/master/test) for the current conformance tests.
1. [Classes](#Classes)
- [Extend React.Component](#Extend React.Component)
- [Identical class and component names](#Identical class and component names)
- [No wrapping elements](#No wrapping elements)
1. [Events](#Events)
1. [Props](#Props)
- [className](#className)
Copy link
Member Author

Choose a reason for hiding this comment

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

Added a TOC to the guidelines.


## Extends React.Component
## Classes

**Valid**
### Extend React.Component

**Always**

```jsx
import React, {Component} from 'react';

export default class MyComponent extends Component {...}
```

**Invalid**
**Never**

```jsx
import React, {Component} from 'react';
Expand All @@ -23,17 +32,17 @@ export default class MyComponent {...}
```
>This is a new class, does not extend React.Component.

## Constructor name matches component name
### Identical class and component names

Give `MyComponent.js` is a component attached to `stardust.MyComponent`:
Given `MyComponent.js` is a component attached to `stardust.MyComponent`:

**Valid**
**Always**

```jsx
export default class MyComponent extends Component {...}
```

**Invalid**
**Never**

```jsx
export default class extends Component {...}
Expand All @@ -43,47 +52,101 @@ export default class extends Component {...}
```jsx
export default class YourComponent extends Component {...}
```
>This class has the wrong name, it should be .
>This class has the wrong name, it should be `MyComponent`.

### No wrapping elements

## Has the `sd-<component>` element as its first child (no wrapper elements)
The element with the `sd-*` className is the first child (no wrapper elements).

**Valid**
**Always**

```jsx
export default class Input extends Component {
render() {
return (
<Input />
<input className='sd-input' />
);
}
}
```

**Invalid**
**Never**

```jsx
export default class Input extends Component {
render() {
return (
<Field
<Input />
<input className='sd-input' />
</Field>
);
}
}
```
>Never wrap the component with other components, whether DOM or Composite.

## Has props.className after `sd-<component>`
## Events

Stardust manages Semantic UI's jQuery via React events and lifecycle methods.

Example, the Message component can be dismissed on click of the close icon. Per
the Semantic UI docs, this is done by calling Semantic UI's `transition()`
jQuery plugin on the message via a jQuery click event handler. Instead,
Stardust uses React's `onClick` listener to trigger the `transition()`.
Copy link
Member Author

Choose a reason for hiding this comment

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

This "Events" section is the new content. All other changes were clarifications, typo fixes, and reordering.

EDIT
Please read at least this section of the document. Here is the rendered doc, again.


## Props

### Spread props

Stardust components [spread](https://facebook.github.io/react/docs/jsx-spread.html)
props onto the internal Semantic UI element of concern. This allows access to the
underlying element.

**Always**

**Valid**
```jsx
<Input onFocus={this.handleFocus} />
// => <input type='text' className='sd-input ui input' onFocus={this.handleFocus} />
```

```jsx
<Input data-my-plugin='do-magic' />
// => <input type='text' className='sd-input ui input' data-my-plugin='do-magic' />
```

**Never**

```jsx
<Input onFocus={this.handleFocus} />
// => <input type='text' className='sd-input ui input' />
```
>`onFocus` prop was lost.

```jsx
<Input data-my-plugin='do-magic' />
// => <input type='text' className='sd-input ui input' />
```
>`data-my-plugin` prop was lost.

### className

Stardust components construct the `className` prop in this order.

1. `sd-<component>`
1. `ui` (Semantic UI class, if required)
1. `this.props.className`
1. `<component>` (Semantic UI class)

#### Inherits `props.className` after `sd-<component>`

**Always**

```jsx
<Field className='inherit-this' />
// => <div className='sd-field inherit-this field>...
```

**Invalid**
**Never**

```jsx
<Field className='inherit-this' />
Expand All @@ -103,16 +166,16 @@ export default class Input extends Component {
```
>className was not inherited before sd-field

## Has `sd-<component>` as the first class
#### Has `sd-<component>` as the first class

**Valid**
**Always**

```jsx
<Divider />
// => <div className='sd-divider ui divider' />
```

**Invalid**
**Never**

```jsx
<Divider />
Expand All @@ -126,36 +189,37 @@ export default class Input extends Component {
```
>`sd-divider` className does not come first.

## Has `ui` class immediately after `sd-<component>`
#### Has `ui` immediately after `sd-<component>`

Only for components that utilize the `ui` class (i.e `ui grid` but not `column`).

**Valid**
**Always**

```jsx
<Grid />
// => <div className='sd-grid ui grid' />
```

**Invalid**
**Never**

```jsx
<Grid />
// => <div className='sd-grid grid ui' />
```
>`grid` is immediately after `sd-grid`.

## Has props.className immediately after `ui`
#### Has `props.className` immediately after `ui`

Only for components that utilize the `ui` class (i.e `ui form` but not `field`).

**Valid**
**Always**

```jsx
<Form />
// => <div className='sd-form ui form' />
```

**Invalid**
**Never**

```jsx
<Form className='loading' />
Expand All @@ -168,32 +232,3 @@ Only for components that utilize the `ui` class (i.e `ui form` but not `field`).
// => <div className='sd-form ui form loading' />
```
>Inherited `loading` className comes after `form`.

## Spreads props
Allows access to the underlying element of concern.

**Valid**

```jsx
<Input onFocus={this.handleFocus} />
// => <input type='text' className='sd-input ui input' onFocus={this.handleFocus} />
```

```jsx
<Input data-my-plugin='do-magic' />
// => <input type='text' className='sd-input ui input' data-my-plugin='do-magic' />
```

**Invalid**

```jsx
<Input onFocus={this.handleFocus} />
// => <input type='text' className='sd-input ui input' />
```
>`onFocus` prop was lost.

```jsx
<Input data-my-plugin='do-magic' />
// => <input type='text' className='sd-input ui input' />
```
>`data-my-plugin` prop was lost.
2 changes: 1 addition & 1 deletion docs/app/Components/ComponentDoc/ComponentExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default class ComponentExample extends Component {
);

return (
<Grid className='one column' style={{marginBottom: '4em', marginTop: '4em'}}>
<Grid className='one column' style={{marginBottom: '4em'}}>
Copy link
Member Author

Choose a reason for hiding this comment

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

This style was pushing the first example very far away from the dividing header. Now the first example is place near the dividing header it is under (shown here in orange):

image

<Column>
<Grid>
<Column width={12}>
Expand Down
14 changes: 14 additions & 0 deletions docs/app/Examples/collections/Message/MessageExamples.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React, {Component} from 'react';
import Variations from './Variations/Variations';
import Types from './Types/Types';

export default class MessageExamples extends Component {
render() {
return (
<div>
<Types />
<Variations />
</div>
);
}
}
12 changes: 12 additions & 0 deletions docs/app/Examples/collections/Message/Types/DismissableBlock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, {Component} from 'react';
import {Message} from 'stardust';

export default class MessageDismissableBlockExample extends Component {
render() {
return (
<Message dismissable heading='Welcome back!'>
This is a special notification which you can dismiss if you're bored with it.
</Message>
);
}
}
18 changes: 18 additions & 0 deletions docs/app/Examples/collections/Message/Types/Icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React, {Component} from 'react';
import {Message} from 'stardust';

export default class MessageIconExample extends Component {
render() {
return (
<div>
<Message icon='inbox' heading='Have you heard about our mailing list?'>
Get the best news in your e-mail every day.
</Message>

<Message icon='notched circle loading' heading='Just one second'>
We're fetching that content for you.
</Message>
</div>
);
}
}
22 changes: 22 additions & 0 deletions docs/app/Examples/collections/Message/Types/Types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, {Component} from 'react';
import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection';
import ComponentExample from 'docs/app/Components/ComponentDoc/ComponentExample';

export default class MessageTypesExamples extends Component {
render() {
return (
<ExampleSection title='Types'>
<ComponentExample
title='Dismissable Block'
description='A message that the can choose to hide.'
examplePath='collections/Message/Types/DismissableBlock'
/>
<ComponentExample
title='Icon Message'
description='A message can contain an icon.'
examplePath='collections/Message/Types/Icon'
/>
</ExampleSection>
);
}
}
12 changes: 12 additions & 0 deletions docs/app/Examples/collections/Message/Variations/Info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, {Component} from 'react';
import {Message} from 'stardust';

export default class MessageInfoExample extends Component {
render() {
return (
<Message className='info' heading='Was this what you wanted?'>
Did you know it's been a while?
</Message>
);
}
}
22 changes: 22 additions & 0 deletions docs/app/Examples/collections/Message/Variations/Variations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, {Component} from 'react';
import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection';
import ComponentExample from 'docs/app/Components/ComponentDoc/ComponentExample';

export default class MessageVariationsExamples extends Component {
render() {
return (
<ExampleSection title='Variations'>
<ComponentExample
title='Info'
description='A message may be formatted to display information.'
examplePath='collections/Message/Variations/Info'
/>
<ComponentExample
title='Warning'
description='A message may be formatted to display warning message.'
examplePath='collections/Message/Variations/Warning'
/>
</ExampleSection>
);
}
}
12 changes: 12 additions & 0 deletions docs/app/Examples/collections/Message/Variations/Warning.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, {Component} from 'react';
import {Message} from 'stardust';

export default class MessageWarningExample extends Component {
render() {
return (
<Message className='warning' heading='You must register before you can do that!'>
Visit our registration page, then try again.
</Message>
);
}
}
Loading