mirror of
https://github.com/Kong/insomnia.git
synced 2026-10-23 15:19:04 -04:00
Add Storybook with basic components (#1807)
* Gruvbox theme * Added Storybook for all components that don't fail in browser
This commit is contained in:
1 parent
bb0b5df096
commit
42e198bf75
18 files changed
+9323
-3
No files matched your search
Generated
+1527
File diff suppressed because it is too large.
Load diff
@@ -17,6 +17,7 @@
|
||||
"app-build": "lerna run build --stream --parallel --bail",
|
||||
"app-package": "lerna run package --stream --parallel --bail",
|
||||
"app-release": "lerna run release --stream --parallel --bail",
|
||||
"app-storybook": "lerna run storybook --stream --parallel --bail",
|
||||
"format-code": "prettier --write \"**/*.js\""
|
||||
},
|
||||
"husky": {
|
||||
@@ -31,6 +32,7 @@
|
||||
"@babel/preset-env": "^7.4.3",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@storybook/addon-info": "^5.2.6",
|
||||
"babel-eslint": "^8.2.3",
|
||||
"babel-jest": "^24.7.1",
|
||||
"babel-loader": "^8.0.5",
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { configure, addDecorator } from '@storybook/react';
|
||||
import { withInfo } from '@storybook/addon-info';
|
||||
|
||||
addDecorator(
|
||||
withInfo({
|
||||
inline: true,
|
||||
}),
|
||||
);
|
||||
|
||||
configure(require.context('../app/ui', true, /\.stories\.js$/), module);
|
||||
@@ -0,0 +1,32 @@
|
||||
@import '../app/ui/css/index.less';
|
||||
|
||||
body {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#root {
|
||||
max-width: 70rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#story-root {
|
||||
padding-left: 40px;
|
||||
padding-right: 40px;
|
||||
background: var(--color-bg);
|
||||
}
|
||||
|
||||
.storybook-skinny {
|
||||
max-width: 40rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
// Fix for Insomnia style clashing
|
||||
.hljs .tag {
|
||||
background: none;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: auto;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.body.setAttribute('theme', 'default');
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,12 @@
|
||||
module.exports = async function({ config, mode }) {
|
||||
config.module.rules.push({
|
||||
test: /\.less$/,
|
||||
use: [
|
||||
'style-loader',
|
||||
{ loader: 'css-loader', options: { importLoaders: 1 } },
|
||||
{ loader: 'less-loader', options: { noIeCompat: true } },
|
||||
],
|
||||
});
|
||||
|
||||
return config;
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { clipboard } from 'electron';
|
||||
import PropTypes from 'prop-types';
|
||||
import autobind from 'autobind-decorator';
|
||||
const { clipboard } = require('electron');
|
||||
|
||||
@autobind
|
||||
class CopyButton extends PureComponent {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import '../../../../.storybook/index.less';
|
||||
import Editable from './editable';
|
||||
|
||||
export default { title: 'Editable' };
|
||||
|
||||
export const input = () => (
|
||||
<Editable value="Double-click to edit me" onSubmit={v => console.log('New value', v)} />
|
||||
);
|
||||
@@ -4,6 +4,7 @@ import autobind from 'autobind-decorator';
|
||||
|
||||
type Props = {
|
||||
indeterminate: boolean,
|
||||
checked: boolean,
|
||||
};
|
||||
|
||||
@autobind
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
import '../../../../.storybook/index.less';
|
||||
import PromptButton from './prompt-button';
|
||||
|
||||
export default { title: 'Prompt Button' };
|
||||
|
||||
export const _default = () => <PromptButton className="btn btn--clicky">Do Something</PromptButton>;
|
||||
@@ -0,0 +1,123 @@
|
||||
import React from 'react';
|
||||
import '../../../.storybook/index.less';
|
||||
import IndeterminateCheckbox from './base/indeterminate-checkbox';
|
||||
|
||||
export default { title: 'Forms' };
|
||||
|
||||
export const input = () => (
|
||||
<form>
|
||||
<div className="form-control form-control--outlined">
|
||||
<input type="text" placeholder="text input" />
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
||||
export const inputWithLabel = () => (
|
||||
<form>
|
||||
<div className="form-control form-control--outlined">
|
||||
<label>
|
||||
Text Input
|
||||
<input type="text" placeholder="text input" />
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
||||
export const selectWithLabel = () => (
|
||||
<form>
|
||||
<div className="form-control form-control--outlined">
|
||||
<label>
|
||||
Select One
|
||||
<select>
|
||||
<option>Option 1</option>
|
||||
<option>Option 2</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
||||
export const checkboxWithLabel = () => (
|
||||
<form>
|
||||
<div className="form-control form-control--thin">
|
||||
<label className="inline-block">
|
||||
Check Me
|
||||
<input type="checkbox" />
|
||||
</label>
|
||||
</div>
|
||||
<div className="form-control form-control--thin">
|
||||
<label className="inline-block">
|
||||
Check Me Too!
|
||||
<input type="checkbox" />
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
||||
export const intermediaryCheckbox = () => (
|
||||
<form>
|
||||
<div className="form-control form-control--thin">
|
||||
<label className="inline-block">
|
||||
Check me, maybe
|
||||
<IndeterminateCheckbox indeterminate={true} checked={false} />
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
||||
export const exampleForm = () => (
|
||||
<form className="storybook-skinny">
|
||||
<div className="form-row">
|
||||
<div className="form-control form-control--outlined">
|
||||
<label>
|
||||
First Name
|
||||
<input type="text" required placeholder="Jane" />
|
||||
</label>
|
||||
</div>
|
||||
<div className="form-control form-control--outlined">
|
||||
<label>
|
||||
Last Name
|
||||
<input type="text" placeholder="Strong" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-control form-control--outlined">
|
||||
<label>
|
||||
Email
|
||||
<input type="email" placeholder="text input" required />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="form-control form-control--outlined">
|
||||
<label>
|
||||
Favorite Color
|
||||
<select>
|
||||
<option>Blue</option>
|
||||
<option>Pink</option>
|
||||
<option>Yellow</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="form-control form-control--thin">
|
||||
<label className="inline-block">
|
||||
Check me
|
||||
<input type="checkbox" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="form-control form-control--thin">
|
||||
<label className="inline-block">
|
||||
Check me too, maybe
|
||||
<IndeterminateCheckbox indeterminate={true} checked={false} />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="form-control margin-top">
|
||||
<button type="submit" className="btn btn--clicky">
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
import '../../../.storybook/index.less';
|
||||
import GravatarImg from './gravatar-img';
|
||||
|
||||
export default { title: 'Gravatar Image' };
|
||||
|
||||
export const _default = () => <GravatarImg email="support@insomnia.rest" size={200} />;
|
||||
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import '../../../.storybook/index.less';
|
||||
import HelpTooltip from './help-tooltip';
|
||||
|
||||
export default { title: 'Help Tooltip' };
|
||||
|
||||
export const _default = () => (
|
||||
<p>
|
||||
Hover over the question mark to view <HelpTooltip>This is the help message</HelpTooltip>
|
||||
</p>
|
||||
);
|
||||
@@ -0,0 +1,72 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import autobind from 'autobind-decorator';
|
||||
import classnames from 'classnames';
|
||||
|
||||
const DISMISSED_VALUE = 'dismissed';
|
||||
|
||||
type Props = {|
|
||||
dismissKey?: string,
|
||||
color?: 'surprise' | 'success' | 'warning' | 'info' | 'error' | 'subtle',
|
||||
children: React.Node,
|
||||
className?: string,
|
||||
|};
|
||||
|
||||
type State = {
|
||||
visible: boolean,
|
||||
localStorageKey: string | null,
|
||||
};
|
||||
|
||||
@autobind
|
||||
class Notice extends React.PureComponent<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
const { dismissKey } = props;
|
||||
const localStorageKey = dismissKey ? 'insomnia::notice::' + dismissKey : null;
|
||||
|
||||
// It's visible if it's not dismissible
|
||||
let visible = false;
|
||||
if (localStorageKey) {
|
||||
visible = window.localStorage.getItem(localStorageKey) !== DISMISSED_VALUE;
|
||||
} else {
|
||||
visible = true;
|
||||
}
|
||||
|
||||
this.state = {
|
||||
visible,
|
||||
localStorageKey,
|
||||
};
|
||||
}
|
||||
|
||||
_dismissNotification() {
|
||||
const { localStorageKey } = this.state;
|
||||
|
||||
// Hide the currently showing notification
|
||||
this.setState({ visible: false });
|
||||
|
||||
window.localStorage.setItem(localStorageKey, DISMISSED_VALUE);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, color, className } = this.props;
|
||||
const { visible, localStorageKey } = this.state;
|
||||
|
||||
if (!visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<p className={classnames('notice', color, className)}>
|
||||
{localStorageKey && (
|
||||
<button className="icon pull-right" onClick={this._dismissNotification}>
|
||||
<i className="fa fa-times" />
|
||||
</button>
|
||||
)}
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Notice;
|
||||
@@ -0,0 +1,37 @@
|
||||
import React from 'react';
|
||||
import '../../../.storybook/index.less';
|
||||
import Notice from './notice';
|
||||
|
||||
export default { title: 'Notice' };
|
||||
|
||||
export const _default = () => (
|
||||
<Notice>This is a notice. It is a bright block of text, meant to stand out from the rest!</Notice>
|
||||
);
|
||||
|
||||
export const colors = () => (
|
||||
<div>
|
||||
<Notice color="surprise">
|
||||
This is a <strong>surprise</strong> notice
|
||||
</Notice>
|
||||
|
||||
<Notice color="info">
|
||||
This is a <strong>info</strong> notice
|
||||
</Notice>
|
||||
|
||||
<Notice color="warning">
|
||||
This is a <strong>warning</strong> notice
|
||||
</Notice>
|
||||
|
||||
<Notice color="error">
|
||||
This is a <strong>error</strong> notice
|
||||
</Notice>
|
||||
|
||||
<Notice color="subtle">
|
||||
This is a <strong>subtle</strong> notice
|
||||
</Notice>
|
||||
|
||||
<Notice color="success">
|
||||
This is a <strong>success</strong> notice
|
||||
</Notice>
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1,57 @@
|
||||
import React from 'react';
|
||||
import Tooltip from './tooltip';
|
||||
import '../../../.storybook/index.less';
|
||||
|
||||
export default { title: 'Tooltip' };
|
||||
|
||||
export const onTop = () => (
|
||||
<p className="text-center">
|
||||
<Tooltip message="Here is some extra info on top" position="top">
|
||||
<button className="btn btn--clicky">Hover Me</button>
|
||||
</Tooltip>
|
||||
</p>
|
||||
);
|
||||
|
||||
export const onRight = () => (
|
||||
<p className="text-center">
|
||||
<Tooltip message="Here is some extra info on the right" position="right">
|
||||
<button className="btn btn--clicky">Hover Me</button>
|
||||
</Tooltip>
|
||||
</p>
|
||||
);
|
||||
|
||||
export const onLeft = () => (
|
||||
<p className="text-center">
|
||||
<Tooltip message="Here is some extra info on the left" position="left">
|
||||
<button className="btn btn--clicky">Hover Me</button>
|
||||
</Tooltip>
|
||||
</p>
|
||||
);
|
||||
|
||||
export const withDelay = () => (
|
||||
<p className="text-center">
|
||||
<Tooltip message="This tooltip had a 900ms delay" delay={900}>
|
||||
<button className="btn btn--clicky">Hover Me</button>
|
||||
</Tooltip>
|
||||
</p>
|
||||
);
|
||||
|
||||
export const withChildren = () => {
|
||||
const message = (
|
||||
<React.Fragment>
|
||||
This is a{' '}
|
||||
<a href="#" onClick={e => e.preventDefault()}>
|
||||
Link
|
||||
</a>
|
||||
.
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
return (
|
||||
<p className="text-center">
|
||||
<Tooltip message={message}>
|
||||
<button className="btn btn--clicky">Hover Me</button>
|
||||
</Tooltip>
|
||||
</p>
|
||||
);
|
||||
};
|
||||
Generated
+7408
-2
File diff suppressed because it is too large.
Load diff
@@ -44,6 +44,7 @@
|
||||
"start:electron": "cross-env NODE_ENV=development webpack --config ./webpack/webpack.config.electron.babel.js && electron .",
|
||||
"start:dev-server": "webpack-dev-server --config ./webpack/webpack.config.development.babel.js",
|
||||
"start": "concurrently --kill-others \"npm run start:dev-server\" \"npm run start:electron\"",
|
||||
"storybook": "start-storybook --port 3222",
|
||||
"build": "node ./scripts/build.js",
|
||||
"package": "node ./scripts/package.js",
|
||||
"release": "node ./scripts/release.js",
|
||||
@@ -188,6 +189,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.4.0",
|
||||
"@octokit/rest": "^16.33.0",
|
||||
"@storybook/react": "^5.2.6",
|
||||
"concurrently": "^3.5.0",
|
||||
"cross-env": "^2.0.0",
|
||||
"css-loader": "^2.1.1",
|
||||
|
||||
Reference in new issue
Block a user