From 898c1f4de9bb83901d404f6a2a42763fa0b5c2c2 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Sat, 19 May 2018 13:53:25 +0200 Subject: [PATCH 001/104] WIP --- .../tabs/__snapshots__/tabs.stories.storyshot | 237 ++++++++++++++++++ lib/components/src/tabs/tabs.js | 189 ++++++++++++++ lib/components/src/tabs/tabs.stories.js | 89 +++++++ 3 files changed, 515 insertions(+) create mode 100644 lib/components/src/tabs/__snapshots__/tabs.stories.storyshot create mode 100644 lib/components/src/tabs/tabs.js create mode 100644 lib/components/src/tabs/tabs.stories.js diff --git a/lib/components/src/tabs/__snapshots__/tabs.stories.storyshot b/lib/components/src/tabs/__snapshots__/tabs.stories.storyshot new file mode 100644 index 000000000000..37b3e7401706 --- /dev/null +++ b/lib/components/src/tabs/__snapshots__/tabs.stories.storyshot @@ -0,0 +1,237 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Components|Tabs no panels 1`] = ` +
+

+ no panels available +

+
+`; + +exports[`Storyshots Components|Tabs stateless - default 1`] = ` +
+
+
+ + +
+
+ +
+
+ TEST 2 +
+
+
+
+
+`; + +exports[`Storyshots Components|Tabs stateless 1`] = ` +
+
+
+ + +
+
+ +
+
+ TEST 2 +
+
+
+
+
+`; + +exports[`Storyshots Components|Tabs with State - no initial 1`] = ` +
+
+
+ + +
+
+ +
+
+ TEST 2 +
+
+
+
+
+`; + +exports[`Storyshots Components|Tabs with State - with initial 1`] = ` +
+
+
+ + +
+
+ +
+
+ TEST 2 +
+
+
+
+
+`; diff --git a/lib/components/src/tabs/tabs.js b/lib/components/src/tabs/tabs.js new file mode 100644 index 000000000000..bb91978a1d12 --- /dev/null +++ b/lib/components/src/tabs/tabs.js @@ -0,0 +1,189 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import styled from 'react-emotion'; + +import { Placeholder } from '../'; + +const Wrapper = styled('div')( + ({ theme }) => ({ + background: theme.mainFill, + borderRadius: 4, + border: theme.mainBorder, + }), + ({ absolute }) => + absolute + ? { + overflow: 'hidden', + width: '100%', + height: '100%', + boxSizing: 'border-box', + display: 'flex', + flexDirection: 'column', + } + : { + display: 'block', + } +); + +export const TabBar = styled('div')({ + // display: 'flex', + // flexDirection: 'row', + // justifyContent: 'flex-start', + // alignItems: 'center', + // flexWrap: 'wrap', + borderBottom: 'solid 1px #eaeaea', + overflow: 'auto', + padding: '0 7.5px', + whiteSpace: 'nowrap', + height: 40, +}); + +const TabButton = styled('div')( + { + whiteSpace: 'normal', + display: 'inline-flex', + overflow: 'hidden', + verticalAlign: 'top', + justifyContent: 'center', + alignItems: 'center', + textAlign: 'center', + }, + { + fontSize: 11, + letterSpacing: '1px', + padding: '0 7.5px', + textTransform: 'uppercase', + transition: 'opacity 0.3s', + height: 40, + lineHeight: '10px', + boxSizing: 'border-box', + cursor: 'pointer', + background: 'transparent', + border: 'none', + }, + ({ selected }) => + selected + ? { + opacity: 1, + } + : { + opacity: 0.5, + } +); + +const Content = styled('div')( + { + display: 'block', + }, + ({ absolute }) => + absolute + ? { + overflow: 'auto', + flex: 1, + width: '100%', + } + : {} +); + +export const Tab = ({ selected, name, title, onSelect }) => { + const onClick = e => { + e.preventDefault(); + onSelect(name); + }; + + return ( + + {typeof title === 'function' ? title() : title} + + ); +}; + +Tab.propTypes = { + selected: PropTypes.bool.isRequired, + name: PropTypes.string.isRequired, + title: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired, + onSelect: PropTypes.func.isRequired, +}; + +const Tabs = ({ panels, selectedPanel, onPanelSelect, absolute }) => { + const list = panels ? Object.entries(panels) : []; + + return list.length ? ( + + + {list.map(([name, data]) => ( + + ))} + + + {list.map(([name, { render: Panel }]) => ( + + + ) : ( + no panels available + ); +}; + +Tabs.defaultProps = { + panels: {}, + onPanelSelect: () => {}, + selectedPanel: null, + absolute: false, +}; + +Tabs.propTypes = { + panels: PropTypes.shape({ + title: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), + render: PropTypes.func, + }).isRequired, + onPanelSelect: PropTypes.func, + selectedPanel: PropTypes.string, + absolute: PropTypes.bool, +}; + +export default Tabs; + +export class TabsState extends Component { + static propTypes = { + panels: PropTypes.shape({ + title: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), + render: PropTypes.func, + }).isRequired, + initial: PropTypes.string, + absolute: PropTypes.bool, + }; + static defaultProps = { + initial: undefined, + absolute: false, + }; + + constructor(props) { + super(props); + + this.state = { + selected: props.initial || Object.keys(props.panels)[0], + }; + } + render() { + return ( + this.setState({ selected: id })} + /> + ); + } +} + +export const panelProps = { + hidden: PropTypes.bool, +}; diff --git a/lib/components/src/tabs/tabs.stories.js b/lib/components/src/tabs/tabs.stories.js new file mode 100644 index 000000000000..a82f92120443 --- /dev/null +++ b/lib/components/src/tabs/tabs.stories.js @@ -0,0 +1,89 @@ +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; + +import Tabs, { TabsState, panelProps } from './tabs'; + +const colours = [...new Array(15)].map((_, i) => + Math.floor(1 / 15 * i * 16777215) + .toString(16) + .padStart(6, '0') +); + +function fibonacci(num, memo = {}) { + if (memo[num]) return memo[num]; + if (num <= 1) return 1; + + // eslint-disable-next-line no-param-reassign + memo[num] = fibonacci(num - 1, memo) + fibonacci(num - 2, memo); + return memo[num]; +} + +const panels = { + test1: { + title: 'Tab title #1', + // eslint-disable-next-line react/prop-types + render: ({ hidden }) => (hidden ? null :
CONTENT 1
), + }, + test2: { + title: 'Tab title #2', + // eslint-disable-next-line react/prop-types + render: ({ hidden }) => ( + + ), + }, + test3: { + title: 'Tab with scroll', + // eslint-disable-next-line react/prop-types + render: ({ hidden }) => + hidden ? null : ( +
+ {colours.map((colour, i) => ( +
+ ))} +
+ ), + }, + test4: { + title: 'Tab title #4', + // eslint-disable-next-line react/prop-types + render: ({ hidden }) => (hidden ? null :
CONTENT 4
), + }, + test5: { + title: 'Tab title #5', + // eslint-disable-next-line react/prop-types + render: ({ hidden }) => (hidden ? null :
CONTENT 5
), + }, + test6: { + title: 'Tab title #6', + // eslint-disable-next-line react/prop-types + render: ({ hidden }) => (hidden ? null :
CONTENT 6
), + }, +}; +panels.test1.propTypes = panelProps; +panels.test2.propTypes = panelProps; +panels.test3.propTypes = panelProps; +panels.test4.propTypes = panelProps; +panels.test5.propTypes = panelProps; +panels.test6.propTypes = panelProps; + +const onPanelSelect = action('onPanelSelect'); + +storiesOf('Components|Tabs', module) + .addDecorator(s =>
{s()}
) + .add('statefull - no initial', () => ) + .add('statefull - with initial', () => ) + .add('statefull - absolute', () => ) + .add('stateless - default', () => ) + .add('stateless - empty', () => ); From f54648187e7d9e97b5fe31ca08e5e90471be8833 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Sun, 20 May 2018 23:56:50 +0200 Subject: [PATCH 002/104] FIX drag blocker --- lib/components/src/layout/desktop.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/components/src/layout/desktop.js b/lib/components/src/layout/desktop.js index 65fa70fadc1d..a3f5a9af10f7 100644 --- a/lib/components/src/layout/desktop.js +++ b/lib/components/src/layout/desktop.js @@ -107,6 +107,7 @@ const PreviewWrapper = styled('div')( ); const DragBlockOverlay = styled('div')(({ isDragging }) => ({ + zIndex: isDragging ? 2 : 0, display: isDragging ? 'block' : 'none', position: 'absolute', top: '0px', From ee4a416422cff458a6a7215897d4619229a8a56b Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 22 May 2018 22:26:39 +0200 Subject: [PATCH 003/104] REFACTOR consolidate Tabs component && CHANGE registerAddon api to include a `active` prop --- addons/a11y/src/components/Panel.js | 36 ++--- addons/a11y/src/components/Tabs.js | 1 + addons/a11y/src/register.js | 8 +- .../src/components/ActionLogger/style.js | 1 + .../src/containers/ActionLogger/index.js | 18 ++- addons/actions/src/manager.js | 3 +- addons/backgrounds/src/BackgroundPanel.js | 6 +- addons/backgrounds/src/register.js | 3 +- addons/events/src/components/Panel.js | 7 +- addons/events/src/manager.js | 4 +- addons/jest/src/register.js | 6 +- addons/knobs/src/components/Panel.js | 8 +- addons/knobs/src/register.js | 4 +- addons/notes/src/register.js | 6 +- addons/storysource/src/StoryPanel.js | 6 +- addons/storysource/src/manager.js | 3 +- addons/viewport/src/manager/index.js | 6 +- lib/addons/package.json | 1 + lib/addons/src/index.js | 12 +- lib/components/src/addon_panel/index.js | 132 +----------------- .../src/addon_panel/index.stories.js | 10 +- lib/components/src/index.js | 1 + lib/components/src/layout/mobile.js | 4 +- lib/components/src/tabs/tabs.js | 24 ++-- lib/components/src/tabs/tabs.stories.js | 24 ++-- 25 files changed, 125 insertions(+), 209 deletions(-) diff --git a/addons/a11y/src/components/Panel.js b/addons/a11y/src/components/Panel.js index 8e3617c81b18..d4c118dea037 100644 --- a/addons/a11y/src/components/Panel.js +++ b/addons/a11y/src/components/Panel.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import addons from '@storybook/addons'; +import PropTypes from 'prop-types'; import styled from 'react-emotion'; @@ -17,36 +17,40 @@ const Violations = styled('span')({ }); class Panel extends Component { - constructor(props, ...args) { - super(props, ...args); - this.state = { - passes: [], - violations: [], - }; - this.channel = addons.getChannel(); + static propTypes = { + active: PropTypes.bool.isRequired, + channel: PropTypes.shape({ + on: PropTypes.func, + emit: PropTypes.func, + removeListener: PropTypes.func, + }).isRequired, + }; - this.onUpdate = this.onUpdate.bind(this); - } + state = { + passes: [], + violations: [], + }; componentDidMount() { - this.channel.on(CHECK_EVENT_ID, this.onUpdate); + this.props.channel.on(CHECK_EVENT_ID, this.onUpdate); } componentWillUnmount() { - this.channel.removeListener(CHECK_EVENT_ID, this.onUpdate); + this.props.channel.removeListener(CHECK_EVENT_ID, this.onUpdate); } - onUpdate({ passes, violations }) { + onUpdate = ({ passes, violations }) => { this.setState({ passes, violations, }); - } + }; render() { const { passes, violations } = this.state; + const { active } = this.props; - return ( + return active ? ( - ); + ) : null; } } diff --git a/addons/a11y/src/components/Tabs.js b/addons/a11y/src/components/Tabs.js index 2bdd3efcfff2..81e428b81dae 100644 --- a/addons/a11y/src/components/Tabs.js +++ b/addons/a11y/src/components/Tabs.js @@ -6,6 +6,7 @@ import styled from 'react-emotion'; const Container = styled('div')({ width: '100%', position: 'relative', + minHeight: '100%', }); const List = styled('div')({ diff --git a/addons/a11y/src/register.js b/addons/a11y/src/register.js index 043797800f68..7074287dc6fb 100644 --- a/addons/a11y/src/register.js +++ b/addons/a11y/src/register.js @@ -5,12 +5,12 @@ import Panel from './components/Panel'; import { ADDON_ID, PANEL_ID } from './shared'; function init() { - addons.register(ADDON_ID, () => { + addons.register(ADDON_ID, api => { + const channel = addons.getChannel(); addons.addPanel(PANEL_ID, { title: 'Accessibility', - render() { - return ; - }, + // eslint-disable-next-line react/prop-types + render: ({ active }) => , }); }); } diff --git a/addons/actions/src/components/ActionLogger/style.js b/addons/actions/src/components/ActionLogger/style.js index e2d4b67081f6..c5b18e6ec014 100644 --- a/addons/actions/src/components/ActionLogger/style.js +++ b/addons/actions/src/components/ActionLogger/style.js @@ -51,4 +51,5 @@ export const Wrapper = styled('div')({ flex: 1, display: 'flex', position: 'relative', + minHeight: '100%', }); diff --git a/addons/actions/src/containers/ActionLogger/index.js b/addons/actions/src/containers/ActionLogger/index.js index df814b21ad87..6d78106dfb9d 100644 --- a/addons/actions/src/containers/ActionLogger/index.js +++ b/addons/actions/src/containers/ActionLogger/index.js @@ -56,21 +56,25 @@ export default class ActionLogger extends React.Component { } render() { + const { active } = this.props; const props = { actions: this.state.actions, onClear: () => this.clearActions(), }; - return ; + return active ? : null; } } ActionLogger.propTypes = { - // eslint-disable-next-line react/forbid-prop-types - channel: PropTypes.object, + active: PropTypes.bool.isRequired, + channel: PropTypes.shape({ + emit: PropTypes.func, + on: PropTypes.func, + removeListener: PropTypes.func, + }).isRequired, api: PropTypes.shape({ - onStory: PropTypes.func.isRequired, + onStory: PropTypes.func, + getQueryParam: PropTypes.func, + setQueryParams: PropTypes.func, }).isRequired, }; -ActionLogger.defaultProps = { - channel: {}, -}; diff --git a/addons/actions/src/manager.js b/addons/actions/src/manager.js index 0fc82a627c7b..43eea1709d91 100644 --- a/addons/actions/src/manager.js +++ b/addons/actions/src/manager.js @@ -8,7 +8,8 @@ export function register() { const channel = addons.getChannel(); addons.addPanel(PANEL_ID, { title: 'Action Logger', - render: () => , + // eslint-disable-next-line react/prop-types + render: ({ active }) => , }); }); } diff --git a/addons/backgrounds/src/BackgroundPanel.js b/addons/backgrounds/src/BackgroundPanel.js index a20d7c8737bb..7ad1fbe8b569 100644 --- a/addons/backgrounds/src/BackgroundPanel.js +++ b/addons/backgrounds/src/BackgroundPanel.js @@ -130,8 +130,11 @@ export default class BackgroundPanel extends Component { } render() { + const { active } = this.props; const backgrounds = [...this.state.backgrounds]; - + if (!active) { + return null; + } if (!backgrounds.length) return ; const hasDefault = backgrounds.filter(x => x.default).length; @@ -149,6 +152,7 @@ export default class BackgroundPanel extends Component { } } BackgroundPanel.propTypes = { + active: PropTypes.bool.isRequired, api: PropTypes.shape({ getQueryParam: PropTypes.func, setQueryParams: PropTypes.func, diff --git a/addons/backgrounds/src/register.js b/addons/backgrounds/src/register.js index 50d22ddbba67..c1a380e25443 100644 --- a/addons/backgrounds/src/register.js +++ b/addons/backgrounds/src/register.js @@ -10,6 +10,7 @@ addons.register(ADDON_ID, api => { const channel = addons.getChannel(); addons.addPanel(PANEL_ID, { title: 'Backgrounds', - render: () => , + // eslint-disable-next-line react/prop-types + render: ({ active }) => , }); }); diff --git a/addons/events/src/components/Panel.js b/addons/events/src/components/Panel.js index adcab42e4b0b..7061171ac8d8 100644 --- a/addons/events/src/components/Panel.js +++ b/addons/events/src/components/Panel.js @@ -10,10 +10,12 @@ const Wrapper = styled('div')({ width: '100%', boxSizing: 'border-box', padding: '10px', + minHeight: '100%', }); export default class Events extends Component { static propTypes = { + active: PropTypes.bool.isRequired, channel: PropTypes.shape({ on: PropTypes.func, emit: PropTypes.func, @@ -43,10 +45,11 @@ export default class Events extends Component { render() { const { events } = this.state; - return ( + const { active } = this.props; + return active ? ( {events.map(event => )} - ); + ) : null; } } diff --git a/addons/events/src/manager.js b/addons/events/src/manager.js index c5929d7d525e..842bf3177d1b 100644 --- a/addons/events/src/manager.js +++ b/addons/events/src/manager.js @@ -6,9 +6,11 @@ import { ADDON_ID, PANEL_ID } from './constants'; export function register() { addons.register(ADDON_ID, () => { + const channel = addons.getChannel(); addons.addPanel(PANEL_ID, { title: 'Events', - render: () => , + // eslint-disable-next-line react/prop-types + render: ({ active }) => , }); }); } diff --git a/addons/jest/src/register.js b/addons/jest/src/register.js index 66639bb3b402..ddd802dfe4d0 100644 --- a/addons/jest/src/register.js +++ b/addons/jest/src/register.js @@ -4,11 +4,11 @@ import addons from '@storybook/addons'; import PanelTitle from './components/PanelTitle'; import Panel from './components/Panel'; -// Register the addon with a unique name. addons.register('storybook/tests', api => { - // Also need to set a unique name to the panel. + const channel = addons.getChannel(); addons.addPanel('storybook/tests/panel', { title: , - render: () => , + // eslint-disable-next-line react/prop-types + render: ({ active }) => (active ? : null), }); }); diff --git a/addons/knobs/src/components/Panel.js b/addons/knobs/src/components/Panel.js index 509a250849f3..e8a10575fc7b 100644 --- a/addons/knobs/src/components/Panel.js +++ b/addons/knobs/src/components/Panel.js @@ -136,6 +136,11 @@ export default class Panel extends React.Component { render() { const { knobs, groupId } = this.state; + const { active } = this.props; + + if (!active) { + return null; + } const groups = {}; const groupIds = []; @@ -190,12 +195,13 @@ export default class Panel extends React.Component { } Panel.propTypes = { + active: PropTypes.bool.isRequired, + onReset: PropTypes.object, // eslint-disable-line channel: PropTypes.shape({ emit: PropTypes.func, on: PropTypes.func, removeListener: PropTypes.func, }).isRequired, - onReset: PropTypes.object, // eslint-disable-line api: PropTypes.shape({ onStory: PropTypes.func, getQueryParam: PropTypes.func, diff --git a/addons/knobs/src/register.js b/addons/knobs/src/register.js index b208cef4109d..838fbc062024 100644 --- a/addons/knobs/src/register.js +++ b/addons/knobs/src/register.js @@ -4,9 +4,9 @@ import Panel from './components/Panel'; addons.register('storybooks/storybook-addon-knobs', api => { const channel = addons.getChannel(); - addons.addPanel('storybooks/storybook-addon-knobs', { title: 'Knobs', - render: () => , + // eslint-disable-next-line react/prop-types + render: ({ active }) => , }); }); diff --git a/addons/notes/src/register.js b/addons/notes/src/register.js index 39df9f8c9b18..230c4cc12854 100644 --- a/addons/notes/src/register.js +++ b/addons/notes/src/register.js @@ -62,11 +62,11 @@ Notes.defaultProps = { api: {}, }; -// Register the addon with a unique name. addons.register('storybook/notes', api => { - // Also need to set a unique name to the panel. + const channel = addons.getChannel(); addons.addPanel('storybook/notes/panel', { title: 'Notes', - render: () => , + // eslint-disable-next-line react/prop-types + render: ({ active }) => (active ? : null), }); }); diff --git a/addons/storysource/src/StoryPanel.js b/addons/storysource/src/StoryPanel.js index 97023d1e6109..513d6d281e39 100644 --- a/addons/storysource/src/StoryPanel.js +++ b/addons/storysource/src/StoryPanel.js @@ -179,7 +179,8 @@ export default class StoryPanel extends Component { }; render() { - return ( + const { active } = this.props; + return active ? ( {this.state.source} - ); + ) : null; } } StoryPanel.propTypes = { + active: PropTypes.bool.isRequired, api: PropTypes.shape({ selectStory: PropTypes.func.isRequired, }).isRequired, diff --git a/addons/storysource/src/manager.js b/addons/storysource/src/manager.js index 1523fefcea22..810da1c70f94 100644 --- a/addons/storysource/src/manager.js +++ b/addons/storysource/src/manager.js @@ -8,7 +8,8 @@ export function register() { const channel = addons.getChannel(); addons.addPanel(PANEL_ID, { title: 'Story', - render: () => , + // eslint-disable-next-line react/prop-types + render: ({ active }) => , }); }); } diff --git a/addons/viewport/src/manager/index.js b/addons/viewport/src/manager/index.js index 77cc056e1b6e..9a561ba5c4e6 100644 --- a/addons/viewport/src/manager/index.js +++ b/addons/viewport/src/manager/index.js @@ -7,12 +7,10 @@ import { ADDON_ID, PANEL_ID } from '../shared'; const addChannel = api => { const channel = addons.getChannel(); - addons.addPanel(PANEL_ID, { title: 'Viewport', - render() { - return ; - }, + // eslint-disable-next-line react/prop-types + render: ({ active }) => (active ? : null), }); }; diff --git a/lib/addons/package.json b/lib/addons/package.json index e6f02348e202..23def0a4652d 100644 --- a/lib/addons/package.json +++ b/lib/addons/package.json @@ -21,6 +21,7 @@ }, "dependencies": { "@storybook/channels": "4.0.0-alpha.7", + "@storybook/components": "4.0.0-alpha.7", "global": "^4.3.2", "util-deprecate": "^1.0.2" } diff --git a/lib/addons/src/index.js b/lib/addons/src/index.js index 960ace6fb015..dbb90befe71e 100644 --- a/lib/addons/src/index.js +++ b/lib/addons/src/index.js @@ -1,5 +1,6 @@ // Resolves to window in browser and to global in node import global from 'global'; +import { TabWrapper } from '@storybook/components'; export mockChannel from './storybook-channel-mock'; export { makeDecorator } from './make-decorator'; @@ -52,7 +53,16 @@ export class AddonStore { } addPanel(name, panel) { - this.panels[name] = panel; + // supporting legacy addons, which have not migrated to the active-prop + const original = panel.render; + if (original && original.toString() && !original.toString().match(/active/)) { + this.panels[name] = { + ...panel, + render: ({ active }) => TabWrapper({ active, render: original }), + }; + } else { + this.panels[name] = panel; + } } register(name, loader) { diff --git a/lib/components/src/addon_panel/index.js b/lib/components/src/addon_panel/index.js index c5ec62175e64..3d4a046e15b1 100644 --- a/lib/components/src/addon_panel/index.js +++ b/lib/components/src/addon_panel/index.js @@ -1,133 +1,5 @@ import React from 'react'; -import PropTypes from 'prop-types'; -import styled from 'react-emotion'; -import { baseFonts, Placeholder } from '../'; +import { Tabs } from '../'; -const Wrapper = styled('div')(({ theme }) => ({ - flex: '1 1 auto', - display: 'flex', - flexDirection: 'column', - background: theme.mainFill, - borderRadius: 4, - border: theme.mainBorder, - overflow: 'hidden', - width: '100%', - height: '100%', - boxSizing: 'border-box', -})); - -export const TabBar = styled('div')({ - display: 'flex', - flexWrap: 'wrap', - flexDirection: 'row', - justifyContent: 'flex-start', - alignItems: 'center', - borderBottom: 'solid 1px #eaeaea', -}); - -const Content = styled('div')({ - flex: '1 1 0', - display: 'flex', - overflow: 'auto', - height: '100%', - width: '100%', -}); - -const TabButton = styled('div')( - baseFonts, - { - fontSize: 11, - letterSpacing: '1px', - padding: '10px 15px', - textTransform: 'uppercase', - transition: 'opacity 0.3s', - maxHeight: 60, - overflow: 'hidden', - cursor: 'pointer', - background: 'transparent', - border: 'none', - }, - ({ selected }) => - selected - ? { - opacity: 1, - } - : { - opacity: 0.5, - } -); - -const Panel = styled('div')( - ({ hidden }) => (hidden ? { display: 'none' } : { display: 'flex', flex: 1 }) -); - -export const Tab = ({ selected, name, title, onSelect }) => { - const onClick = e => { - e.preventDefault(); - onSelect(name); - }; - - return ( - - {typeof title === 'function' ? title() : title} - - ); -}; - -Tab.propTypes = { - selected: PropTypes.bool.isRequired, - name: PropTypes.string.isRequired, - title: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired, - onSelect: PropTypes.func.isRequired, -}; - -const AddonPanel = ({ panels, selectedPanel, onPanelSelect }) => { - const hasPanels = panels && Object.keys(panels).length; - - return hasPanels ? ( - - - {Object.entries(panels).map(([name, data]) => ( - - ))} - - - {Object.keys(panels) - .sort() - .map(name => { - const panel = panels[name]; - - return ( - - ); - })} - - - ) : ( - no panels available - ); -}; - -AddonPanel.defaultProps = { - panels: {}, - onPanelSelect: () => {}, - selectedPanel: null, -}; - -AddonPanel.propTypes = { - // eslint-disable-next-line react/forbid-prop-types - panels: PropTypes.object, - onPanelSelect: PropTypes.func, - selectedPanel: PropTypes.string, -}; - -export default AddonPanel; +export default props => ; diff --git a/lib/components/src/addon_panel/index.stories.js b/lib/components/src/addon_panel/index.stories.js index 7a3dbfb0f623..fd95f2404112 100644 --- a/lib/components/src/addon_panel/index.stories.js +++ b/lib/components/src/addon_panel/index.stories.js @@ -7,15 +7,13 @@ import AddonPanel from './index'; const panels = { test1: { title: 'Test 1', - render() { - return
TEST 1
; - }, + // eslint-disable-next-line react/prop-types + render: ({ active }) => (active ?
TEST 1
: null), }, test2: { title: 'Test 2', - render() { - return
TEST 2
; - }, + // eslint-disable-next-line react/prop-types + render: ({ active }) => (active ?
TEST 2
: null), }, }; diff --git a/lib/components/src/index.js b/lib/components/src/index.js index b3497661f4e0..6fcfe2cf607a 100644 --- a/lib/components/src/index.js +++ b/lib/components/src/index.js @@ -8,6 +8,7 @@ export { default as MenuLink } from './navigation/MenuLink'; export { default as HighlightButton } from './highlight_button'; export { default as Table } from './table/table'; export { Td, Th } from './table/cell'; +export { Tabs, TabsState, TabWrapper } from './tabs/tabs'; export { default as Button } from './form/button'; export { default as Placeholder } from './placeholder/placeholder'; diff --git a/lib/components/src/layout/mobile.js b/lib/components/src/layout/mobile.js index 3e8391c0b310..938276f6b280 100644 --- a/lib/components/src/layout/mobile.js +++ b/lib/components/src/layout/mobile.js @@ -2,7 +2,7 @@ import React, { Component, Children } from 'react'; import PropTypes from 'prop-types'; import styled from 'react-emotion'; -import { TabBar, Tab } from '../addon_panel/index'; +import { Tab, TabBar } from '../tabs/tabs'; const MobilePanel = styled('div')( ({ selected }) => @@ -12,7 +12,7 @@ const MobilePanel = styled('div')( position: 'fixed', top: 0, left: 0, - height: 'calc(100vh - 34px)', + height: 'calc(100vh - 40px)', width: '100vw', overflow: 'auto', WebkitOverflowScrolling: 'touch', diff --git a/lib/components/src/tabs/tabs.js b/lib/components/src/tabs/tabs.js index bb91978a1d12..608026196caf 100644 --- a/lib/components/src/tabs/tabs.js +++ b/lib/components/src/tabs/tabs.js @@ -26,11 +26,6 @@ const Wrapper = styled('div')( ); export const TabBar = styled('div')({ - // display: 'flex', - // flexDirection: 'row', - // justifyContent: 'flex-start', - // alignItems: 'center', - // flexWrap: 'wrap', borderBottom: 'solid 1px #eaeaea', overflow: 'auto', padding: '0 7.5px', @@ -105,7 +100,7 @@ Tab.propTypes = { onSelect: PropTypes.func.isRequired, }; -const Tabs = ({ panels, selectedPanel, onPanelSelect, absolute }) => { +export const Tabs = ({ panels, selectedPanel, onPanelSelect, absolute }) => { const list = panels ? Object.entries(panels) : []; return list.length ? ( @@ -123,7 +118,7 @@ const Tabs = ({ panels, selectedPanel, onPanelSelect, absolute }) => { {list.map(([name, { render: Panel }]) => ( - @@ -132,6 +127,17 @@ const Tabs = ({ panels, selectedPanel, onPanelSelect, absolute }) => { ); }; +const VisuallyHidden = styled('div')( + ({ active }) => (active ? { display: 'block' } : { display: 'none' }) +); +export const TabWrapper = ({ active, render }) => ( + {render()} +); +TabWrapper.propTypes = { + active: PropTypes.bool.isRequired, + render: PropTypes.func.isRequired, +}; + Tabs.defaultProps = { panels: {}, onPanelSelect: () => {}, @@ -149,8 +155,6 @@ Tabs.propTypes = { absolute: PropTypes.bool, }; -export default Tabs; - export class TabsState extends Component { static propTypes = { panels: PropTypes.shape({ @@ -185,5 +189,5 @@ export class TabsState extends Component { } export const panelProps = { - hidden: PropTypes.bool, + active: PropTypes.bool, }; diff --git a/lib/components/src/tabs/tabs.stories.js b/lib/components/src/tabs/tabs.stories.js index a82f92120443..8e12324498c1 100644 --- a/lib/components/src/tabs/tabs.stories.js +++ b/lib/components/src/tabs/tabs.stories.js @@ -2,7 +2,7 @@ import React from 'react'; import { storiesOf } from '@storybook/react'; import { action } from '@storybook/addon-actions'; -import Tabs, { TabsState, panelProps } from './tabs'; +import { Tabs, TabsState, panelProps, TabWrapper } from './tabs'; const colours = [...new Array(15)].map((_, i) => Math.floor(1 / 15 * i * 16777215) @@ -23,15 +23,15 @@ const panels = { test1: { title: 'Tab title #1', // eslint-disable-next-line react/prop-types - render: ({ hidden }) => (hidden ? null :
CONTENT 1
), + render: ({ active }) => (active ?
CONTENT 1
: null), }, test2: { title: 'Tab title #2', // eslint-disable-next-line react/prop-types - render: ({ hidden }) => ( + render: ({ active }) => ( @@ -40,8 +40,8 @@ const panels = { test3: { title: 'Tab with scroll', // eslint-disable-next-line react/prop-types - render: ({ hidden }) => - hidden ? null : ( + render: ({ active }) => + active ? (
{colours.map((colour, i) => (
))}
- ), + ) : null, }, test4: { title: 'Tab title #4', // eslint-disable-next-line react/prop-types - render: ({ hidden }) => (hidden ? null :
CONTENT 4
), + render: ({ active }) => (active ?
CONTENT 4
: null), }, test5: { title: 'Tab title #5', // eslint-disable-next-line react/prop-types - render: ({ hidden }) => (hidden ? null :
CONTENT 5
), + render: ({ active }) => (active ?
CONTENT 5
: null), }, test6: { title: 'Tab title #6', // eslint-disable-next-line react/prop-types - render: ({ hidden }) => (hidden ? null :
CONTENT 6
), + render: ({ active }) =>
CONTENT 6
} />, }, }; panels.test1.propTypes = panelProps; @@ -85,5 +85,7 @@ storiesOf('Components|Tabs', module) .add('statefull - no initial', () => ) .add('statefull - with initial', () => ) .add('statefull - absolute', () => ) - .add('stateless - default', () => ) + .add('stateless - default', () => ( + + )) .add('stateless - empty', () => ); From c6e704c415f74c8e4eba72b9612be54f985d44f7 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 22 May 2018 22:27:20 +0200 Subject: [PATCH 004/104] DOCUMENT new api for registering addon panels --- docs/src/pages/addons/writing-addons/index.md | 59 +++++++++---------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/docs/src/pages/addons/writing-addons/index.md b/docs/src/pages/addons/writing-addons/index.md index 61dba335768e..6a48b429399b 100644 --- a/docs/src/pages/addons/writing-addons/index.md +++ b/docs/src/pages/addons/writing-addons/index.md @@ -91,7 +91,7 @@ export class WithNotes extends React.Component { const channel = addons.getChannel(); // send the notes to the channel. - channel.emit('kadira/notes/add_notes', notes); + channel.emit('MYADDON/add_notes', notes); // return children elements. return children; } @@ -107,33 +107,27 @@ Then add the following code to the register.js. ```js import React from 'react'; import addons from '@storybook/addons'; +import styled from 'emotion'; -const styles = { - notesPanel: { - margin: 10, - fontFamily: 'Arial', - fontSize: 14, - color: '#444', - width: '100%', - overflow: 'auto', - } -}; +const NotesPanel = styled('div')({ + margin: 10, + width: '100%', + overflow: 'auto', +}); class Notes extends React.Component { - constructor(...args) { - super(...args); - this.state = {text: ''}; - this.onAddNotes = this.onAddNotes.bind(this); - } + state = { + text: '', + }; - onAddNotes(text) { - this.setState({text}); + onAddNotes = text => { + this.setState({ text }); } componentDidMount() { const { channel, api } = this.props; // Listen to the notes and render it. - channel.on('kadira/notes/add_notes', this.onAddNotes); + channel.on('MYADDON/add_notes', this.onAddNotes); // Clear the current notes on every story change. this.stopListeningOnStory = api.onStory(() => { @@ -143,34 +137,33 @@ class Notes extends React.Component { render() { const { text } = this.state; + const { active } = this.props; const textAfterFormatted = text? text.trim().replace(/\n/g, '
') : ""; - return ( -
-
-
- ); + return active ? + : + null; } // This is some cleanup tasks when the Notes panel is unmounting. componentWillUnmount() { - if(this.stopListeningOnStory) { + if (this.stopListeningOnStory) { this.stopListeningOnStory(); } this.unmounted = true; const { channel, api } = this.props; - channel.removeListener('kadira/notes/add_notes', this.onAddNotes); + channel.removeListener('MYADDON/add_notes', this.onAddNotes); } } // Register the addon with a unique name. -addons.register('kadira/notes', (api) => { +addons.register('MYADDON', (api) => { // Also need to set a unique name to the panel. - addons.addPanel('kadira/notes/panel', { + addons.addPanel('MYADDON/panel', { title: 'Notes', - render: () => ( - + render: ({ active }) => ( + ), }) }) @@ -184,6 +177,8 @@ Then it will listen to the channel and render the notes text on the panel. Have It also listens to another event, called onStory, in the storybook API, which fires when the user selects a story. We use that event to clear the previous notes when selecting a story. +Multiple addons can be loaded, but only a single panel can be shown, the render function will receive an `active` prop, which is true if the addon is shown. It is up to you to decide if this mean your component must be unmounted, or just visually hidden. This allows you to keep state but unmount expensive renderings. + ### Register the addon Now, finally, we need to register the addon by importing it to the `.storybook/addons.js` file. @@ -193,7 +188,7 @@ Now, finally, we need to register the addon by importing it to the `.storybook/a import '@storybook/addon-actions/register'; // Our addon -import '../src/notes-addon/register'; +import '../src/MYADDON/register'; ``` > Above code runs in the Manager App but not in the preview area. @@ -247,4 +242,4 @@ When you are developing your addon as a package, you can't use `npm link` to add ### Package Maintenance Your packaged Storybook addon needs to be written in ES5. If you are using ES6, then you need to transpile it. -In that case, we recommend to use [React CDK](https://github.com/kadirahq/react-cdk) for that. +In that case, we recommend to use [React CDK](https://github.com/myhq/react-cdk) for that. From 4c39c8b55d08aa27c01d3c93f1eba1272486fde1 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 22 May 2018 22:28:14 +0200 Subject: [PATCH 005/104] CHANGE location and styling of Dimensions component --- lib/components/src/layout/desktop.js | 2 +- lib/components/src/layout/dimensions.js | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/components/src/layout/desktop.js b/lib/components/src/layout/desktop.js index a3f5a9af10f7..61947bf25124 100644 --- a/lib/components/src/layout/desktop.js +++ b/lib/components/src/layout/desktop.js @@ -277,8 +277,8 @@ class Layout extends Component { }} > + - diff --git a/lib/components/src/layout/dimensions.js b/lib/components/src/layout/dimensions.js index 444d99135608..689b2ec06217 100644 --- a/lib/components/src/layout/dimensions.js +++ b/lib/components/src/layout/dimensions.js @@ -9,10 +9,11 @@ const DISPLAY_TIMEOUT = 1000; const Container = styled('div')({ position: 'absolute', - padding: 5, - bottom: 10, - right: 10, + padding: '5px 8px', + bottom: 0, + right: 0, backgroundColor: 'rgba(255, 255, 255, 0.5)', + borderRadius: '5px 0 0 0', }); const Section = styled('span')(baseFonts, { fontSize: 12 }); From 313486ffe3e9669916a7a2cd5a237322647221bd Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 22 May 2018 22:58:07 +0200 Subject: [PATCH 006/104] FIX tests --- .../src/__tests__/BackgroundPanel.js | 30 +- .../knobs/src/components/__tests__/Panel.js | 10 +- .../__snapshots__/index.stories.storyshot | 30 +- lib/components/src/addon_panel/index.test.js | 21 +- .../__snapshots__/index.stories.storyshot | 20 +- .../tabs/__snapshots__/tabs.stories.storyshot | 295 ++++++++++++------ 6 files changed, 245 insertions(+), 161 deletions(-) diff --git a/addons/backgrounds/src/__tests__/BackgroundPanel.js b/addons/backgrounds/src/__tests__/BackgroundPanel.js index 59eb89db51ff..8c9f59aac76c 100644 --- a/addons/backgrounds/src/__tests__/BackgroundPanel.js +++ b/addons/backgrounds/src/__tests__/BackgroundPanel.js @@ -30,26 +30,26 @@ jest.mock('global', () => ({ describe('Background Panel', () => { it('should exist', () => { - const backgroundPanel = shallow(); + const backgroundPanel = shallow(); expect(backgroundPanel).toBeDefined(); }); it('should have a default background value of transparent', () => { - const backgroundPanel = shallow(); + const backgroundPanel = shallow(); expect(backgroundPanel.state().backgrounds).toHaveLength(0); }); it('should show setup instructions if no colors provided', () => { - const backgroundPanel = shallow(); + const backgroundPanel = shallow(); expect(backgroundPanel.html().match(/Setup Instructions/gim).length).toBeGreaterThan(0); }); it('should set the query string', () => { const SpiedChannel = new EventEmitter(); - mount(); + mount(); SpiedChannel.emit(Events.SET, backgrounds); expect(mockedApi.getQueryParam).toBeCalledWith('background'); @@ -57,7 +57,7 @@ describe('Background Panel', () => { it('should not unset the query string', () => { const SpiedChannel = new EventEmitter(); - mount(); + mount(); SpiedChannel.emit(Events.UNSET, []); expect(mockedApi.setQueryParams).not.toHaveBeenCalled(); @@ -65,7 +65,9 @@ describe('Background Panel', () => { it('should accept colors through channel and render the correct swatches with a default swatch', () => { const SpiedChannel = new EventEmitter(); - const backgroundPanel = mount(); + const backgroundPanel = mount( + + ); SpiedChannel.emit(Events.SET, backgrounds); expect(backgroundPanel.state('backgrounds')).toEqual(backgrounds); @@ -73,7 +75,9 @@ describe('Background Panel', () => { it('should allow setting a default swatch', () => { const SpiedChannel = new EventEmitter(); - const backgroundPanel = mount(); + const backgroundPanel = mount( + + ); const [head, ...tail] = backgrounds; const localBgs = [{ ...head, default: true }, ...tail]; SpiedChannel.emit(Events.SET, localBgs); @@ -88,7 +92,9 @@ describe('Background Panel', () => { it('should allow the default swatch become the background color', () => { const SpiedChannel = new EventEmitter(); - const backgroundPanel = mount(); + const backgroundPanel = mount( + + ); const [head, second, ...tail] = backgrounds; const localBgs = [head, { ...second, default: true }, ...tail]; SpiedChannel.on('background', bg => { @@ -106,7 +112,9 @@ describe('Background Panel', () => { it('should unset all swatches on receiving the background-unset message', () => { const SpiedChannel = new EventEmitter(); - const backgroundPanel = mount(); + const backgroundPanel = mount( + + ); SpiedChannel.emit(Events.SET, backgrounds); expect(backgroundPanel.state('backgrounds')).toEqual(backgrounds); @@ -118,7 +126,9 @@ describe('Background Panel', () => { it('should set iframe background', () => { const SpiedChannel = new EventEmitter(); - const backgroundPanel = mount(); + const backgroundPanel = mount( + + ); backgroundPanel.setState({ backgrounds }); // force re-render backgroundPanel diff --git a/addons/knobs/src/components/__tests__/Panel.js b/addons/knobs/src/components/__tests__/Panel.js index ef0389705b6f..474bd9250a9b 100644 --- a/addons/knobs/src/components/__tests__/Panel.js +++ b/addons/knobs/src/components/__tests__/Panel.js @@ -6,14 +6,14 @@ describe('Panel', () => { it('should subscribe to setKnobs event of channel', () => { const testChannel = { on: jest.fn() }; const testApi = { onStory: jest.fn() }; - shallow(); + shallow(); expect(testChannel.on).toHaveBeenCalledWith('addon:knobs:setKnobs', jasmine.any(Function)); }); it('should subscribe to onStory event', () => { const testChannel = { on: jest.fn() }; const testApi = { onStory: jest.fn() }; - shallow(); + shallow(); expect(testApi.onStory).toHaveBeenCalled(); expect(testChannel.on).toHaveBeenCalledWith('addon:knobs:setKnobs', jasmine.any(Function)); @@ -41,7 +41,7 @@ describe('Panel', () => { onStory: jest.fn(), }; - shallow(); + shallow(); const setKnobsHandler = handlers['addon:knobs:setKnobs']; const knobs = { @@ -88,7 +88,7 @@ describe('Panel', () => { onStory: jest.fn(), }; - const wrapper = shallow(); + const wrapper = shallow(); const setKnobsHandler = handlers['addon:knobs:setKnobs']; const knobs = { @@ -130,7 +130,7 @@ describe('Panel', () => { onStory: jest.fn(), }; - const wrapper = shallow(); + const wrapper = shallow(); const testChangedKnob = { name: 'foo', diff --git a/lib/components/src/addon_panel/__snapshots__/index.stories.storyshot b/lib/components/src/addon_panel/__snapshots__/index.stories.storyshot index 58a348c13363..51b7473de2b1 100644 --- a/lib/components/src/addon_panel/__snapshots__/index.stories.storyshot +++ b/lib/components/src/addon_panel/__snapshots__/index.stories.storyshot @@ -5,21 +5,21 @@ exports[`Storyshots Components|AddonPanel default 1`] = ` style="height:calc(100vh - 20px)" >
-
-
- TEST 2 -
+ TEST 2
diff --git a/lib/components/src/addon_panel/index.test.js b/lib/components/src/addon_panel/index.test.js index 125384ecdcf0..a970e23b19fe 100644 --- a/lib/components/src/addon_panel/index.test.js +++ b/lib/components/src/addon_panel/index.test.js @@ -7,15 +7,13 @@ describe('manager.ui.components.addon_panel.index', () => { const panels = { test1: { title: 'TEST 1', - render() { - return
TEST 1
; - }, + // eslint-disable-next-line react/prop-types + render: ({ active }) => (active ?
TEST 1
: null), }, test2: { title: 'TEST 2', - render() { - return
TEST 2
; - }, + // eslint-disable-next-line react/prop-types + render: ({ active }) => (active ?
TEST 2
: null), }, }; @@ -23,10 +21,12 @@ describe('manager.ui.components.addon_panel.index', () => { const wrapper = shallow( - ); + ).dive(); - expect(wrapper.find('#test1').parent()).toHaveProp('hidden', true); - expect(wrapper.find('#test2').parent()).not.toHaveProp('hidden', true); + expect(wrapper.find('Tab').at(0)).toHaveProp({ selected: false }); + expect(wrapper.find('Tab').at(1)).toHaveProp('selected', true); + expect(wrapper.find('render').at(0)).toHaveProp('active', false); + expect(wrapper.find('render').at(1)).toHaveProp('active', true); }); test('should set onPanelSelected as onClick handlers of tabs', () => { @@ -45,6 +45,7 @@ describe('manager.ui.components.addon_panel.index', () => { ); wrapper + .dive() .find('Tab') .dive() .simulate('click', { preventDefault }); @@ -57,7 +58,7 @@ describe('manager.ui.components.addon_panel.index', () => { test('should render "no panels available"', () => { const panels = {}; const onPanelSelect = () => 'onPanelSelect'; - const wrapper = shallow(); + const wrapper = shallow().dive(); expect(wrapper.contains('no panels available')).toBe(true); }); diff --git a/lib/components/src/layout/__snapshots__/index.stories.storyshot b/lib/components/src/layout/__snapshots__/index.stories.storyshot index fe146494708e..65a34d65006f 100644 --- a/lib/components/src/layout/__snapshots__/index.stories.storyshot +++ b/lib/components/src/layout/__snapshots__/index.stories.storyshot @@ -55,7 +55,7 @@ exports[`Storyshots Components|Layout addon panel in right 1`] = ` class="css-1e1vreg" >
-

- no panels available -

-
-`; - -exports[`Storyshots Components|Tabs stateless - default 1`] = ` +exports[`Storyshots Components|Tabs statefull - absolute 1`] = `
+ + + +
+
-
- TEST 2 +
+ CONTENT 6
@@ -68,55 +81,80 @@ exports[`Storyshots Components|Tabs stateless - default 1`] = `
`; -exports[`Storyshots Components|Tabs stateless 1`] = ` +exports[`Storyshots Components|Tabs statefull - no initial 1`] = `
+ + + +
@@ -124,55 +162,75 @@ exports[`Storyshots Components|Tabs stateless 1`] = `
`; -exports[`Storyshots Components|Tabs with State - no initial 1`] = ` +exports[`Storyshots Components|Tabs statefull - with initial 1`] = `
+ + + +
-
- TEST 2 +
+ CONTENT 6
@@ -180,58 +238,89 @@ exports[`Storyshots Components|Tabs with State - no initial 1`] = `
`; -exports[`Storyshots Components|Tabs with State - with initial 1`] = ` +exports[`Storyshots Components|Tabs stateless - default 1`] = `
+ + + +
-
- TEST 2 +
+ CONTENT 6
`; + +exports[`Storyshots Components|Tabs stateless - empty 1`] = ` +
+

+ no panels available +

+
+`; From 4ea75bbc23bcd3825fc57501dd49072d88f1e27d Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 24 May 2018 00:50:24 +0200 Subject: [PATCH 007/104] REMOVE mobile header --- lib/components/src/header/header.js | 49 +++++---------------- lib/components/src/header/header.stories.js | 16 ++----- 2 files changed, 15 insertions(+), 50 deletions(-) diff --git a/lib/components/src/header/header.js b/lib/components/src/header/header.js index 70c02bed4ef9..b673c426fbf8 100755 --- a/lib/components/src/header/header.js +++ b/lib/components/src/header/header.js @@ -2,22 +2,19 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'react-emotion'; -const Wrapper = styled('div')(({ isMobileDevice }) => ({ - margin: isMobileDevice ? '10px 0' : '0 0 10px', +const Wrapper = styled('div')({ + margin: '0 0 10px', display: 'flex', -})); +}); -const HeadingLink = styled('a')(({ isMobileDevice }) => ({ +const HeadingLink = styled('a')({ textDecoration: 'none', flexGrow: 1, display: 'flex', alignItems: 'center', - color: 'currentColor', justifyContent: 'center', - border: isMobileDevice ? 'none' : '1px solid rgba(0, 0, 0, 0.1)', + border: '1px solid rgba(0, 0, 0, 0.1)', borderRadius: 2, -})); -const Heading = styled('h3')({ textTransform: 'uppercase', letterSpacing: '1.5px', fontSize: '12px', @@ -30,7 +27,7 @@ const Heading = styled('h3')({ overflow: 'hidden', }); -const iconStyle = ({ isMobileDevice }) => ({ +const ShortHelpButton = styled('button')({ textTransform: 'uppercase', fontSize: 12, fontWeight: 'bolder', @@ -41,47 +38,24 @@ const iconStyle = ({ isMobileDevice }) => ({ cursor: 'pointer', display: 'inlineBlock', padding: 0, - margin: isMobileDevice ? '0 15px' : '0 0 0 5px', + margin: '0 0 0 5px', backgroundColor: 'inherit', outline: 0, width: 30, flexShrink: 0, }); -const BurgerButton = styled('button')(iconStyle({ isMobileDevice: true }), { - paddingBottom: 2, -}); -const ShortHelpButton = styled('button')(iconStyle); - -const Header = ({ - openShortcutsHelp, - onBurgerButtonClick, - name, - url, - enableShortcutsHelp, - isMobileDevice, -}) => ( +const Header = ({ openShortcutsHelp, name, url, enableShortcutsHelp, isMobileDevice }) => ( - {isMobileDevice && ☰} - - {name} + + {name} - {enableShortcutsHelp && ( - - ⌘ - - )} + {enableShortcutsHelp && ⌘} ); Header.defaultProps = { openShortcutsHelp: null, - onBurgerButtonClick: null, enableShortcutsHelp: true, name: '', url: '', @@ -90,7 +64,6 @@ Header.defaultProps = { Header.propTypes = { openShortcutsHelp: PropTypes.func, - onBurgerButtonClick: PropTypes.func, name: PropTypes.string, url: PropTypes.string, isMobileDevice: PropTypes.bool, diff --git a/lib/components/src/header/header.stories.js b/lib/components/src/header/header.stories.js index a6af9614d980..f9e1767e9b2d 100644 --- a/lib/components/src/header/header.stories.js +++ b/lib/components/src/header/header.stories.js @@ -5,15 +5,7 @@ import { action } from '@storybook/addon-actions'; import Header from './header'; const openShortcutsHelp = action('openShortcutsHelp'); -storiesOf('Components|Header', module) - .add('simple', () => ( -
- )) - .add('mobile-view', () => ( -
- )); + +storiesOf('Components|Header', module).add('simple', () => ( +
+)); From b668f5a30505a82b03f9edb2938becfdc5aae11b Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 24 May 2018 00:52:42 +0200 Subject: [PATCH 008/104] ADD theme variables for Tabs --- lib/components/src/tabs/tabs.js | 9 +++++---- lib/components/src/theme.js | 7 ++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/components/src/tabs/tabs.js b/lib/components/src/tabs/tabs.js index 608026196caf..f6597096aa77 100644 --- a/lib/components/src/tabs/tabs.js +++ b/lib/components/src/tabs/tabs.js @@ -25,13 +25,14 @@ const Wrapper = styled('div')( } ); -export const TabBar = styled('div')({ - borderBottom: 'solid 1px #eaeaea', +export const TabBar = styled('div')(({ theme }) => ({ + background: theme.barFill, + borderBottom: theme.mainBorder, overflow: 'auto', padding: '0 7.5px', whiteSpace: 'nowrap', height: 40, -}); +})); const TabButton = styled('div')( { @@ -48,7 +49,7 @@ const TabButton = styled('div')( letterSpacing: '1px', padding: '0 7.5px', textTransform: 'uppercase', - transition: 'opacity 0.3s', + transition: 'opacity 0.2s', height: 40, lineHeight: '10px', boxSizing: 'border-box', diff --git a/lib/components/src/theme.js b/lib/components/src/theme.js index fd0de1dfeeb2..7c30cd579c60 100644 --- a/lib/components/src/theme.js +++ b/lib/components/src/theme.js @@ -16,10 +16,15 @@ export const normal = { mainBackground: '#F7F7F7', mainBorder: '1px solid rgba(0,0,0,0.1)', mainBorderRadius: 4, - mainFill: 'rgba(255,255,255,0.99)', + mainFill: 'rgba(255,255,255,0.89)', + barFill: 'rgba(255,255,255,1)', mainTextFace: baseFonts.fontFamily, mainTextColor: baseFonts.color, mainTextSize: 13, monoTextFace: monoFonts.color, layoutMargin: '10px', + + brand: { + border: '1px solid rgba(0,0,0,0.1)', + }, }; From af097bcb939f3d95a1d5876d94e35c83d9aeda4c Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 24 May 2018 07:42:19 +0200 Subject: [PATCH 009/104] FIX snapshots --- .../__snapshots__/index.stories.storyshot | 8 +-- .../__snapshots__/header.stories.storyshot | 39 +---------- .../__snapshots__/index.stories.storyshot | 18 +++--- .../tabs/__snapshots__/tabs.stories.storyshot | 64 +++++++++---------- .../__snapshots__/index.stories.storyshot | 40 ++++-------- .../text_filter.stories.storyshot | 4 +- 6 files changed, 62 insertions(+), 111 deletions(-) diff --git a/lib/components/src/addon_panel/__snapshots__/index.stories.storyshot b/lib/components/src/addon_panel/__snapshots__/index.stories.storyshot index 51b7473de2b1..94712334935b 100644 --- a/lib/components/src/addon_panel/__snapshots__/index.stories.storyshot +++ b/lib/components/src/addon_panel/__snapshots__/index.stories.storyshot @@ -5,21 +5,21 @@ exports[`Storyshots Components|AddonPanel default 1`] = ` style="height:calc(100vh - 20px)" >
-`; - exports[`Storyshots Components|Header simple 1`] = `
-

- name -

+ name
`; -exports[`Storyshots Button with some info 1`] = ` -
-
-
- click the - - Show Info - - label in top right for info about "with some info" -
-
- -
- -
-
-
-

- Button -

-

- with some info -

-
-
-
- Use the - - info addon - - with its painful API. -
-
-
-

- Story Source -

-
-            
-
-
- - <Container - - - - > - -
-
- - click the - -
-
- - <InfoButton - - - - /> - -
-
- - label in top right for info about " - -
-
- - with some info - -
-
- - " - -
-
- - </Container> - -
-
-
- -
-
-
-

- Prop Types -

-
-

- "Container" Component -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- property - - propType - - required - - default - - description -
- children - - - - yes - - - - -
- isAmazing - - - - - - - - false - - -
- age - - - - - - - - { - - - isOld - - - : - - false - - , - - - value - - - : - - 0 - - } - - -
- title - - - - - - - - the best container ever - - -
-
-
-

- "InfoButton" Component -

- - No propTypes defined! - -
-
-
-
-
-
-`; - exports[`Storyshots Button with text 1`] = `
@@ -10,7 +10,7 @@ exports[`Storyshots Addons|Viewport default 1`] = ` exports[`Storyshots Addons|Viewport.Custom Default (Kindle Fire 2) Inherited 1`] = `
I've inherited @@ -22,7 +22,7 @@ exports[`Storyshots Addons|Viewport.Custom Default (Kindle Fire 2) Inherited 1`] exports[`Storyshots Addons|Viewport.Custom Default (Kindle Fire 2) Overridden via "Viewport" component (deprecated) 1`] = `
I respect my parents but I should be looking good on @@ -34,7 +34,7 @@ exports[`Storyshots Addons|Viewport.Custom Default (Kindle Fire 2) Overridden vi exports[`Storyshots Addons|Viewport.Custom Default (Kindle Fire 2) Overridden via "withViewport" decorator (deprecated) 1`] = `
I respect my parents but I should be looking good on @@ -46,7 +46,7 @@ exports[`Storyshots Addons|Viewport.Custom Default (Kindle Fire 2) Overridden vi exports[`Storyshots Addons|Viewport.Custom Default (Kindle Fire 2) Overridden via "withViewport" parameterized decorator 1`] = `
I respect my parents but I should be looking good on diff --git a/examples/official-storybook/stories/__snapshots__/core.stories.storyshot b/examples/official-storybook/stories/__snapshots__/core.stories.storyshot index 05dfd93da384..def6fee010ce 100644 --- a/examples/official-storybook/stories/__snapshots__/core.stories.storyshot +++ b/examples/official-storybook/stories/__snapshots__/core.stories.storyshot @@ -2,7 +2,7 @@ exports[`Storyshots Core|Events Force re-render 1`] = ` diff --git a/lib/cli/test/snapshots/meteor/package.json b/lib/cli/test/snapshots/meteor/package.json index 2d2a0395ba5a..a69b527d3d8a 100644 --- a/lib/cli/test/snapshots/meteor/package.json +++ b/lib/cli/test/snapshots/meteor/package.json @@ -10,8 +10,8 @@ "dependencies": { "babel-runtime": "^6.20.0", "meteor-node-stubs": "~0.2.4", - "react": "^16.3.2", - "react-dom": "^16.3.2" + "react": "^16.4.0", + "react-dom": "^16.4.0" }, "devDependencies": { "babel-core": "^6.26.3", diff --git a/lib/components/src/form/__snapshots__/button.stories.storyshot b/lib/components/src/form/__snapshots__/button.stories.storyshot index 82eaa081b751..7d9432bda01c 100644 --- a/lib/components/src/form/__snapshots__/button.stories.storyshot +++ b/lib/components/src/form/__snapshots__/button.stories.storyshot @@ -2,7 +2,7 @@ exports[`Storyshots Components|Form/Button with onclick 1`] = ` diff --git a/lib/components/src/layout/__snapshots__/index.stories.storyshot b/lib/components/src/layout/__snapshots__/index.stories.storyshot index 8e81ee145b53..b6c6b3d835bd 100644 --- a/lib/components/src/layout/__snapshots__/index.stories.storyshot +++ b/lib/components/src/layout/__snapshots__/index.stories.storyshot @@ -2,7 +2,7 @@ exports[`Storyshots Components|Layout addon panel in right 1`] = `
Link @@ -11,7 +11,7 @@ exports[`Storyshots Components|Navigation/MenuLink active 1`] = ` exports[`Storyshots Components|Navigation/MenuLink default 1`] = ` Link @@ -23,7 +23,7 @@ exports[`Storyshots Components|Navigation/MenuLink with knobs 1`] = ` style="width:90px" > Menu link item diff --git a/lib/components/src/tabs/__snapshots__/tabs.stories.storyshot b/lib/components/src/tabs/__snapshots__/tabs.stories.storyshot index 3ea0dbd54954..2c12ce7ce3da 100644 --- a/lib/components/src/tabs/__snapshots__/tabs.stories.storyshot +++ b/lib/components/src/tabs/__snapshots__/tabs.stories.storyshot @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Storyshots Components|Tabs statefull - absolute 1`] = ` +exports[`Storyshots Components|Tabs stateful - absolute 1`] = `
@@ -81,7 +81,7 @@ exports[`Storyshots Components|Tabs statefull - absolute 1`] = `
`; -exports[`Storyshots Components|Tabs statefull - no initial 1`] = ` +exports[`Storyshots Components|Tabs stateful - no initial 1`] = `
@@ -162,7 +162,7 @@ exports[`Storyshots Components|Tabs statefull - no initial 1`] = `
`; -exports[`Storyshots Components|Tabs statefull - with initial 1`] = ` +exports[`Storyshots Components|Tabs stateful - with initial 1`] = `
diff --git a/lib/ui/src/modules/ui/components/stories_panel/__snapshots__/index.stories.storyshot b/lib/ui/src/modules/ui/components/stories_panel/__snapshots__/index.stories.storyshot index 230f1e175c06..da14a789cdf7 100644 --- a/lib/ui/src/modules/ui/components/stories_panel/__snapshots__/index.stories.storyshot +++ b/lib/ui/src/modules/ui/components/stories_panel/__snapshots__/index.stories.storyshot @@ -133,17 +133,17 @@ exports[`Storyshots ui/stories/StoriesPanel with storiesHierarchies prop 1`] = ` class="css-7w6khc" >