Skip to content

Commit

Permalink
feat: aded tabs component
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Feb 10, 2020
1 parent 5558d98 commit 6191630
Show file tree
Hide file tree
Showing 9 changed files with 291 additions and 15 deletions.
3 changes: 2 additions & 1 deletion .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import { addDecorator, addParameters } from '@storybook/react';
import { polaris as theme} from '@theme-ui/presets';
import { ThemeProvider } from 'theme-ui';
import { lighten, darken } from 'polished';
import { lighten } from 'polished';


addDecorator((story) => {
Expand Down Expand Up @@ -43,6 +43,7 @@ addDecorator((story) => {
},
colors: {
...theme.colors,
accent: '#1EA7FD',
fadedText: lighten(0.25, theme.colors.text),
lightenPrimary: lighten(0.4, theme.colors.primary),

Expand Down
69 changes: 69 additions & 0 deletions core/editors/src/components/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { FC } from 'react';
import styled from '@emotion/styled';
import { Theme } from 'theme-ui';
import {
Tab,
Tabs as OriginalTabs,
TabsProps,
TabList,
TabPanel,
} from 'react-tabs';

const TabsContainer = styled.div`
${({ theme }: { theme: Theme }) => `
.react-tabs {
-webkit-tap-highlight-color: transparent;
}
.react-tabs__tab-list {
margin: 0 0 10px;
padding: 0;
}
.react-tabs__tab {
font-size: 13px;
font-weight: bold;
display: inline-block;
border-bottom: none;
bottom: -1px;
position: relative;
list-style: none;
padding: 4px 15px;
cursor: pointer;
color: ${theme?.colors?.fadedText};
}
.react-tabs__tab--selected {
border-bottom: 3px solid ${theme?.colors?.accent};
color: ${theme?.colors?.accent};
}
.react-tabs__tab--disabled {
color: GrayText;
cursor: default;
}
.react-tabs__tab:focus {
box-shadow: 0 0 5px hsl(208, 99%, 50%);
border-color: hsl(208, 99%, 50%);
outline: none;
}
.react-tabs__tab:focus:after {
content: "";
position: absolute;
height: 5px;
left: -4px;
right: -4px;
bottom: -5px;
background: #fff;
}
.react-tabs__tab-panel {
display: none;
}
.react-tabs__tab-panel.react-tabs__tab-panel--selected {
display: block;
}
`}
`;

const Tabs: FC<TabsProps> = (props: TabsProps) => (
<TabsContainer>
<OriginalTabs {...props} />
</TabsContainer>
);
export { Tab, Tabs, TabList, TabPanel };
203 changes: 203 additions & 0 deletions core/editors/src/forms/ControlsTable/ControlEditorsTable.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ControlTypes } from '@component-controls/specification';
import {
LoadedComponentControls,
mergeControlValues,
getControlValues,
loadControls,
} from '@component-controls/core';

import { ControlsEditorsTable } from './ControlEditorsTable';
Expand Down Expand Up @@ -58,3 +60,204 @@ export const simple = () => {
</>
);
};

const arrayOfObjects = [
{
label: 'Sparky',
dogParent: 'Matthew',
location: 'Austin',
},
{
label: 'Juniper',
dogParent: 'Joshua',
location: 'Austin',
},
];
const GROUP_IDS = {
DISPLAY: 'Display',
GENERAL: 'General',
FAVORITES: 'Favorites',
};

const advancedControls: LoadedComponentControls = loadControls({
userName: {
type: ControlTypes.TEXT,
label: 'Name',
value: 'Storyteller',
groupId: GROUP_IDS.GENERAL,
},
age: {
type: ControlTypes.NUMBER,
label: 'Age',
value: 78,
range: true,
min: 0,
max: 90,
step: 5,
groupId: GROUP_IDS.GENERAL,
},
birthday: {
type: ControlTypes.DATE,
label: 'Birthday',
value: new Date(),
groupId: GROUP_IDS.GENERAL,
},
dollars: {
type: ControlTypes.NUMBER,
label: 'Dollars',
value: 12.5,
min: 0,
max: 100,
step: 0.01,
groupId: GROUP_IDS.GENERAL,
},
years: {
type: ControlTypes.NUMBER,
label: 'Years in NY',
value: 9,
groupId: GROUP_IDS.GENERAL,
},
nice: {
type: ControlTypes.BOOLEAN,
label: 'Nice',
value: true,
groupId: GROUP_IDS.FAVORITES,
},
items: {
type: ControlTypes.ARRAY,
label: 'Items',
value: ['Laptop', 'Book', 'Whiskey'],
groupId: GROUP_IDS.FAVORITES,
},

fruit: {
type: ControlTypes.OPTIONS,
label: 'Fruit',
value: 'apple',
options: {
Apple: 'apple',
Banana: 'banana',
Cherry: 'cherry',
},
groupId: GROUP_IDS.FAVORITES,
},
otherFruit: {
type: ControlTypes.OPTIONS,
label: 'Other Fruit',
value: 'watermelon',
options: {
Kiwi: 'kiwi',
Guava: 'guava',
Watermelon: 'watermelon',
},
display: 'radio',
groupId: GROUP_IDS.FAVORITES,
},
dog: {
type: ControlTypes.OPTIONS,
options: arrayOfObjects,
value: arrayOfObjects[0],
groupId: GROUP_IDS.FAVORITES,
},
backgroundColor: {
type: ControlTypes.COLOR,
value: '#dedede',
groupId: GROUP_IDS.DISPLAY,
},

color: {
type: ControlTypes.COLOR,
value: '#000000',
groupId: GROUP_IDS.DISPLAY,
},
otherStyles: {
type: ControlTypes.OBJECT,
label: 'Styles',
value: {
// do not randomize the border style
border: {
type: ControlTypes.TEXT,
value: '2px dashed silver',
data: null,
},
borderRadius: { type: ControlTypes.NUMBER, value: 10 },
padding: { type: ControlTypes.NUMBER, value: 10 },
},
groupId: GROUP_IDS.DISPLAY,
},
images: {
type: ControlTypes.FILES,
label: 'Happy Picture',
accept: 'image/*',
value: [
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiARwMCyEWcOFPAAAAP0lEQVQoz8WQMQoAIAwDL/7/z3GwghSp4KDZyiUpBMCYUgd8rehtH16/l3XewgU2KAzapjXBbNFaPS6lDMlKB6OiDv3iAH1OAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTAxLTI4VDEyOjExOjMzLTA3OjAwlAHQBgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wMS0yOFQxMjoxMTozMy0wNzowMOVcaLoAAAAASUVORK5CYII=',
],
groupId: GROUP_IDS.DISPLAY,
},
});

export const advanced = () => {
const [controls, setControls] = React.useState<LoadedComponentControls>(
advancedControls,
);
const {
userName,
age,
fruit,
otherFruit,
dollars,
years,
backgroundColor,
color,
items,
otherStyles,
nice,
images,
dog,
birthday,
} = getControlValues(controls);
const intro = `My name is ${userName}, I'm ${age} years old, and my favorite fruit is ${fruit}. I also enjoy ${otherFruit}, and hanging out with my dog ${dog}`;
const style = {
backgroundColor,
color,
...otherStyles,
};
const salutation = nice ? 'Nice to meet you!' : 'Leave me alone!';
const dateOptions = {
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'UTC',
};

return (
<>
<div style={style}>
<p>{intro}</p>
<p>
My birthday is:{' '}
{new Date(birthday).toLocaleDateString('en-US', dateOptions)} at:
{new Date(birthday).toLocaleTimeString()}
</p>
<p>I live in NY for {years} years.</p>
<p>My wallet contains: ${dollars.toFixed(2)}</p>
<p>In my backpack, I have:</p>
<ul>
{items && items.map((item: string) => <li key={item}>{item}</li>)}
</ul>
<p>{salutation}</p>
<p>
When I am happy I look like this: <img src={images[0]} alt="happy" />
</p>
</div>
<ControlsEditorsTable
controls={controls as LoadedComponentControls}
title="Complex controls"
storyId="1-12"
setControlValue={(storyId, name, value) =>
setControls(mergeControlValues(controls, name, value))
}
/>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
LoadedComponentControl,
} from '@component-controls/core';

import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import { Tab, Tabs, TabList, TabPanel } from '../../components/Tabs/Tabs';
import { ControlsEditorsTableProps } from '../../types';
import { ActionBar } from '../../components/ActionBar/ActionBar';

Expand Down
2 changes: 1 addition & 1 deletion core/specification/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export interface ComponentControlBase<T> {
* helper information to generate random data
* can be used in conjunction with faker.js
*/
data?: ComponentControlData;
data?: ComponentControlData | null;
}

export interface ComponentControlText extends ComponentControlBase<string> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { ControlTypes } from '@component-controls/specification';
import { Title, Subtitle, Description, Story, Props, Stories } from '@storybook/addon-docs/blocks';
import { ControlsEditorsTable } from '../../dist/preview/blocks';
import { ControlsEditorsTable } from '../../dist/blocks';

export default {
title: 'Docs/PropEditors/ControlsEditorsTable',
Expand Down
1 change: 0 additions & 1 deletion integrations/storybook/src/blocks/ControlsEditorsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export const ControlsEditorsTable: React.FC<ControlsEditorsTableProps> = ({
controls={controls}
storyId={id}
setControlValue={api.setControlValue}
resetControlValue={api.resetControlValue}
clickControl={api.clickControl}
/>
) : null;
Expand Down
14 changes: 9 additions & 5 deletions integrations/storybook/src/manager/Panel.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import React from 'react';
import { styled } from '@storybook/theming';
import { LoadedComponentControls } from '@component-controls/specification';
import { Combo, Consumer, API, StoryInput } from '@storybook/api';
import { LoadedComponentControls } from '@component-controls/core';
import { Combo, Consumer, API } from '@storybook/api';
import { ControlsTable } from '../shared/ControlsTable';
import { NoControls } from './NoControls';

interface StoryInput {
id: string;
controls: LoadedComponentControls;
}

const Wrapper = styled.div(() => ({
display: 'flex',
alignItems: 'start',
Expand All @@ -30,8 +35,8 @@ const mapper = ({ state }: Combo): MapperReturnProps => {
if (!state.storiesHash[storyId]) {
return {};
}
const { controls } = state.storiesHash[state.storyId] as StoryInput;
return { story: state.storiesHash[storyId] as StoryInput, controls };
const { controls } = (state.storiesHash[state.storyId] as any) as StoryInput;
return { story: (state.storiesHash[storyId] as any) as StoryInput, controls };
};

export const PropsPanel: React.FC<PropsPanelProps> = ({
Expand All @@ -52,7 +57,6 @@ export const PropsPanel: React.FC<PropsPanelProps> = ({
controls={controls}
storyId={story.id}
setControlValue={api.setControlValue}
resetControlValue={api.resetControlValue}
clickControl={api.clickControl}
/>
</Container>
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
"clean": "lerna clean",
"bootstrap": "lerna bootstrap",
"dev": "cd dev-env/basic && yarn && yarn dev",
"packages": "run-s packages:*",
"packages:fix": "lerna run --parallel fix && echo",
"packages:lint": "lerna run --parallel lint",
"packages:build": "lerna run build",
"packages:test": "lerna run test --stream",
"packages": "yarn fix && yarn lint && yarn build && yarn test",
"fix": "lerna run --parallel fix && echo",
"lint": "lerna run --parallel lint",
"build": "lerna run build",
"test": "lerna run test --stream",
"prerelease": "yarn run packages",
"release": "lerna publish --conventional-commits",
"release:next": "yarn run packages && lerna publish --conventional-commits --conventional-prerelease --dist-tag=next --exact",
Expand Down

0 comments on commit 6191630

Please sign in to comment.