Skip to content

Commit

Permalink
Add addon implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Cody Price authored and Cody Price committed Dec 14, 2018
1 parent 9a9ff7b commit 0358b57
Show file tree
Hide file tree
Showing 16 changed files with 3,438 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-proposal-class-properties"
]
}
1 change: 1 addition & 0 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
> 0.25%
8 changes: 8 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
build
builds
scripts
config
lib
dist
*.config.*
20 changes: 20 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"extends": "airbnb",
"parser": "babel-eslint",
"plugins": [
"import",
"compat"
],
"env": {
"browser": true,
"jest": true
},
"rules": {
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["**/test/*", "**/*.jest.*", "**/*.test.*"]}],
"compat/compat": "error",
"max-len": ["error", { "code": 120 }]
},
"settings": {
"polyfills": ["promises"]
}
}
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
node_modules
dist
lib
yarn-error*
.DS_Store

# Logs
logs
*.log
Expand Down
5 changes: 5 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.log
node_modules
target
reports
tests/**/__snapshots__/
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lts/*
51 changes: 51 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "storybook-addon-goto-iframe",
"version": "1.1.0",
"main": "dist/register.js",
"author": "Cody Price <[email protected]>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/dev-cprice/storybook-addon-goto-iframe.git"
},
"homepage": "https://github.com/dev-cprice/storybook-addon-goto-iframe",
"keywords": [
"addon",
"storybook"
],
"files": [
"dist",
"src",
"register.js"
],
"publishConfig": {
"registry": "https://registry.npmjs.org"
},
"dependencies": {
"@storybook/addons": "^3.4.11"
},
"devDependencies": {
"@babel/cli": "^7.2.0",
"@babel/core": "^7.2.0",
"@babel/plugin-proposal-class-properties": "^7.2.1",
"@babel/preset-env": "^7.2.0",
"@babel/preset-react": "^7.0.0",
"babel-eslint": "^10.0.1",
"eslint": "^5.10.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-compat": "^2.6.3",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^6.1.2",
"eslint-plugin-react": "^7.11.1",
"react": "^16.6.3"
},
"peerDependencies": {
"react": "^16"
},
"scripts": {
"compile": "babel src --out-dir dist --copy-files",
"precompile": "rm -rf dist",
"lint": "eslint src",
"prepublishOnly": "yarn run lint && yarn run compile"
}
}
1 change: 1 addition & 0 deletions register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('./dist/register.js');
42 changes: 42 additions & 0 deletions src/components/button/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import buttonStyle, { hoverButtonStyle } from './ButtonStyles';

const propTypes = {
href: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
};

class Button extends Component {
static propTypes = propTypes;

constructor(props) {
super(props);
this.state = {
isHovered: false,
}
}

toggleHover = () => {
this.setState(({ isHovered }) => ({ isHovered: !isHovered }));
}

render() {
const { href, children } = this.props;

const hoveredStyle = this.state.isHovered ? hoverButtonStyle : {};

const style = {
...buttonStyle,
...hoveredStyle,
};

return (
<a href={href} style={style} onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover}>
{children}
</a>
);
}
}

export default Button;
29 changes: 29 additions & 0 deletions src/components/button/ButtonStyles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export default {
backgroundColor: '#0c5fd0',
color: '#fff',
borderClip: 'border-box',
borderRadius: '0.1875rem',
borderStyle: 'none',
boxShadow: [
'0px 3px 1px -2px rgba(0, 0, 0, 0.2)',
'0px 2px 2px 0px rgba(0, 0, 0, 0.14)',
'0px 1px 5px 0px rgba(0, 0, 0, 0.12)',
].join(', '),
cursor: 'pointer',
display: 'inline-block',
fontFamily: 'sans-serif',
fontSize: '14px',
outline: 'none',
padding: '8px',
textAlign: 'center',
textDecoration: 'none',
textTransform: 'uppercase',
};

export const hoverButtonStyle = {
boxShadow: [
'0px 5px 5px -3px rgba(0, 0, 0, 0.2)',
'0px 8px 10px 1px rgba(0, 0, 0, 0.14)',
'0px 3px 14px 2px rgba(0, 0, 0, 0.12)',
].join(', '),
};
54 changes: 54 additions & 0 deletions src/components/panel/Panel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Button from '../button/Button';
import panelStyle, { centeredStyle, descriptionStyle } from './PanelStyles';

const propTypes = {
api: PropTypes.shape({
onStory: PropTypes.func,
}).isRequired,
};

class Panel extends Component {
static propTypes = propTypes;

constructor(props) {
super(props);
this.state = {
url: '',
};
}

componentDidMount() {
const { api: { onStory } } = this.props;
onStory((kind, story) => this.updateUrl(kind, story));
}

componentWillUnmount() {
this.setState({ url: '' });
}

updateUrl = (storyPath, storyName) => {
const selectedKind = storyPath.replace(/\//g, '%2F');
const selectedStory = storyName.replace(/ /g, '%20');
const url = `iframe.html?selectedKind=${selectedKind}&selectedStory=${selectedStory}`

this.setState({ url });
}

render() {
const { url } = this.state;

return (
<div style={panelStyle}>
<p>Use this addon to navigate to the selected story's iframe.</p>
<p style={descriptionStyle}>This is useful for testing accessibility (the Storybook UI has WCAG/508 violations) or when you need a larger window size than Storybook allows for.</p>
<div style={centeredStyle}>
<Button href={url}>Go to Story Iframe</Button>
</div>
</div>
);
}
}

export default Panel;
13 changes: 13 additions & 0 deletions src/components/panel/PanelStyles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const centeredStyle = {
textAlign: 'center',
};

export const descriptionStyle = {
color: 'rgba(0, 0, 0, 0.54)',
};

export default {
color: 'rgba(0, 0, 0, 0.87)',
fontFamily: 'sans-serif',
margin: '16px',
};
5 changes: 5 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const ADDON_TITLE = 'Go To Story Iframe';

export const ADDON_ID = 'dev-cprice/story-iframe';

export const PANEL_ID = `${ADDON_ID}/panel`;
11 changes: 11 additions & 0 deletions src/register.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import addons from '@storybook/addons';
import Panel from './components/panel/Panel';
import { ADDON_ID, ADDON_TITLE, PANEL_ID } from './constants';

addons.register(ADDON_ID, api => {
addons.addPanel(PANEL_ID, {
title: ADDON_TITLE,
render: () => <Panel api={api} />,
});
});
Loading

0 comments on commit 0358b57

Please sign in to comment.