Skip to content

Commit

Permalink
feat: actionbar ui improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Mar 8, 2020
1 parent c88b281 commit aa0c212
Show file tree
Hide file tree
Showing 18 changed files with 173 additions and 96 deletions.
2 changes: 1 addition & 1 deletion integrations/storybook/src/shared/ThemeProvider.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { getLuminance } from 'polished';
import { ThemeContext, Theme } from '@storybook/theming';
import { ThemeProvider as ThemeUIProvider } from '@component-controls/blocks';
import { ThemeProvider as ThemeUIProvider } from '@component-controls/components';

export const ThemeProvider: React.FC = ({ children }) => {
const { background: { content = '#ffffff' } = {} } = React.useContext<Theme>(
Expand Down
10 changes: 7 additions & 3 deletions ui/block-components/src/BlockContainer/BlockContainer.tsx
@@ -1,4 +1,6 @@
import React, { FC } from 'react';
/** @jsx jsx */
import { FC } from 'react';
import { jsx, Box } from 'theme-ui';
import styled from '@emotion/styled';
import { Subtitle } from '../Subtitle';
import { ActionBar, ActionItem } from '@component-controls/components';
Expand Down Expand Up @@ -31,7 +33,9 @@ export const BlockContainer: FC<BlockContainerProps> = ({
}) => (
<SpacedBlockContainer>
{title && <Subtitle>{title}</Subtitle>}
{actions && <ActionBar actionItems={actions} />}
<FramedBlockContainer>{children}</FramedBlockContainer>
<Box>
{actions && <ActionBar actionItems={actions} />}
<FramedBlockContainer>{children}</FramedBlockContainer>
</Box>
</SpacedBlockContainer>
);
36 changes: 22 additions & 14 deletions ui/block-components/src/ControlsTable/ControlsTable.tsx
@@ -1,3 +1,5 @@
/** @jsx jsx */
import { jsx, Box } from 'theme-ui';
import React, { FC, MouseEvent } from 'react';
import { window, document } from 'global';
import styled from '@emotion/styled';
Expand Down Expand Up @@ -159,22 +161,28 @@ export const ControlsTable: FC<ControlsTableProps & {
];
return (
<BlockContainer actions={actionItems} title={title}>
{groupedItems.length === 1 ? (
<PropGroupTable {...props} controls={groupedItems[0].controls} />
) : (
<Tabs>
<TabList>
<Box
sx={{
pt: 4,
}}
>
{groupedItems.length === 1 ? (
<PropGroupTable {...props} controls={groupedItems[0].controls} />
) : (
<Tabs>
<TabList>
{groupedItems.map(item => (
<Tab key={`tab_${item.label}`}>{item.label}</Tab>
))}
</TabList>
{groupedItems.map(item => (
<Tab key={`tab_${item.label}`}>{item.label}</Tab>
<TabPanel key={`tab_panel_${item.label}`}>
<PropGroupTable {...props} controls={item.controls} />
</TabPanel>
))}
</TabList>
{groupedItems.map(item => (
<TabPanel key={`tab_panel_${item.label}`}>
<PropGroupTable {...props} controls={item.controls} />
</TabPanel>
))}
</Tabs>
)}
</Tabs>
)}
</Box>
</BlockContainer>
);
}
Expand Down
2 changes: 1 addition & 1 deletion ui/block-components/src/Source/Source.tsx
Expand Up @@ -74,7 +74,7 @@ export const Source: FC<SourceProps> = ({
: ({ className, style, tokens, getLineProps, getTokenProps }: any) => (
<Styled.pre
className={`${className}`}
style={{ ...style, padding: '10px 10px', margin: 0 }}
style={{ ...style, padding: '26px 10px 10px', margin: 0 }}
>
{tokens.map((line: string[], i: number) => (
<div {...getLineProps({ line, key: i })}>
Expand Down
2 changes: 1 addition & 1 deletion ui/block-components/src/StorySource/TaggedSource.tsx
Expand Up @@ -73,7 +73,7 @@ export const TaggedSource: React.FC<TaggedSourceProps> = ({
return (
<Styled.pre
className={`${className}`}
style={{ ...style, padding: '10px 10px', margin: 0 }}
style={{ ...style, padding: '26px 10px 10px', margin: 0 }}
>
{tokens.map((line, i: number) => (
<div {...getLineProps({ line, key: i })}>
Expand Down
1 change: 0 additions & 1 deletion ui/blocks/package.json
Expand Up @@ -39,7 +39,6 @@
"react": "^16.8.3",
"react-dom": "^16.8.3",
"theme-ui": "^0.3.1",
"@theme-ui/presets": "^0.3.0",
"@theme-ui/prism": "^0.3.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion ui/blocks/src/ComponentSource/ComponentSource.tsx
Expand Up @@ -5,7 +5,7 @@ import {
SourceProps,
} from '@component-controls/block-components';
import { useControlsContext, StoryInputProps } from '../BlocksContext';
import { ThemeContext } from '../ThemeContext';
import { ThemeContext } from '@component-controls/components';
import { repositoryActions } from '../utils/repositoryActions';

export type ComponentSourceProps = StoryInputProps & SourceProps;
Expand Down
2 changes: 1 addition & 1 deletion ui/blocks/src/StorySource/StorySource.tsx
Expand Up @@ -4,7 +4,7 @@ import {
StorySourceProps as BaseStorySourceProps,
} from '@component-controls/block-components';
import { useControlsContext, StoryInputProps } from '../BlocksContext';
import { ThemeContext } from '../ThemeContext';
import { ThemeContext } from '@component-controls/components';
import { repositoryActions } from '../utils/repositoryActions';

export type StorySourceProps = StoryInputProps & BaseStorySourceProps;
Expand Down
1 change: 0 additions & 1 deletion ui/blocks/src/index.ts
Expand Up @@ -4,5 +4,4 @@ export * from './Description';
export * from './StorySource';
export * from './ComponentSource';
export * from './Subtitle';
export * from './ThemeContext';
export * from './Title';
1 change: 0 additions & 1 deletion ui/blocks/src/typings.d.ts
@@ -1,2 +1 @@
declare module '@component-controls/loader/story-store-data';
declare module '@theme-ui/presets';
3 changes: 2 additions & 1 deletion ui/components/package.json
Expand Up @@ -34,7 +34,8 @@
"react-dom": "^16.8.3",
"react-popper-tooltip": "^2.10.1",
"react-tabs": "^3.1.0",
"theme-ui": "^0.3.1"
"theme-ui": "^0.3.1",
"@theme-ui/presets": "^0.3.0"
},
"devDependencies": {
"@types/jest": "^25.1.2",
Expand Down
65 changes: 65 additions & 0 deletions ui/components/src/ActionBar/ActionBar.stories.tsx
@@ -0,0 +1,65 @@
import React from 'react';
import { Box } from 'theme-ui';
import { ActionBar } from './ActionBar';
import { ThemeProvider } from '../ThemeContext';
import { ExternalLink } from '../ExternalLink';

export default {
title: 'Components/ActionBar',
component: ActionBar,
};

const Container: React.FC = ({ children }) => (
<ThemeProvider>
<Box
style={{
height: 100,
backgroundColor: 'red',
}}
>
{children}
</Box>
</ThemeProvider>
);
export const simple = () => (
<Container>
<ActionBar
actionItems={[
{
title: 'action 1',
onClick: () => console.log('clicked'),
},
{
title: 'action 2',
onClick: () => console.log('clicked'),
},
]}
/>
</Container>
);

export const disabled = () => (
<Container>
<ActionBar
actionItems={[
{
title: 'click action',
onClick: () => console.log('clicked'),
disabled: true,
},
]}
/>
</Container>
);

export const link = () => (
<Container>
<ActionBar
actionItems={[
{
title: <ExternalLink href="https://google.com">google</ExternalLink>,
},
]}
/>
</Container>
);
115 changes: 49 additions & 66 deletions ui/components/src/ActionBar/ActionBar.tsx
@@ -1,83 +1,66 @@
/** @jsx jsx */
import React, { FunctionComponent, MouseEvent } from 'react';
import styled from '@emotion/styled';
import { Theme } from 'theme-ui';

const Container = styled.div(({ theme }: { theme?: Theme }) => ({
bottom: 0,
right: 0,
maxWidth: '100%',
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-end',
background: theme?.colors?.background,
}));

interface ActionButtonProps {
disabled?: boolean;
}
export const ActionButton = styled.button<ActionButtonProps>(
({ theme }: { theme: Theme } & ActionButtonProps) => ({
border: '0 none',
padding: '4px 10px',
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
color: theme?.colors?.text,
background: theme?.colors?.background,

fontSize: 12,
lineHeight: '16px',
fontWeight: 'bold',

borderBottom: `1px solid ${theme?.colors?.muted}`,
borderLeft: `1px solid ${theme?.colors?.muted}`,
borderRight: `1px solid ${theme?.colors?.muted}`,
marginLeft: -1,

borderRadius: `4px 0 0 0`,

'&:not(:last-child)': { borderRight: `1px solid ${theme?.colors?.muted}` },
'& + *': {
borderLeft: `1px solid ${theme?.colors?.muted}`,
borderRadius: 0,
},

'&:focus': {
boxShadow: `${theme?.colors?.secondary} 0 -3px 0 0 inset`,
outline: '0 none',
},
}),
({ disabled }) =>
disabled && {
cursor: 'not-allowed',
opacity: 0.5,
},
);
ActionButton.displayName = 'ActionButton';
import { Box, Button, jsx } from 'theme-ui';

export interface ActionItem {
title: React.ReactNode;
onClick?: (e: MouseEvent<HTMLButtonElement>) => void;
disabled?: boolean;
hidden?: boolean;
}

export interface ActionBarProps {
actionItems: ActionItem[];
}

const StyledContainer = styled.div`
position: relative;
`;

const StyledFlex = styled.div`
display: flex;
position: absolute;
flex-direction: row-reverse;
width: 100%;
`;

const ActionColors = (disabled: boolean | undefined) => ({
backgroundColor: 'highlight',
color: disabled ? '#ddd' : 'background',
cursor: disabled ? 'not-allowed' : undefined,
px: 2,
py: 1,
lineHeight: 1,
borderRadius: 0,
border: 'none',
});
export const ActionBar: FunctionComponent<ActionBarProps> = ({
actionItems,
...props
}) => (
<Container {...props}>
{actionItems.map(({ title, onClick, disabled }, index: number) => (
<ActionButton
key={`${typeof title === 'string' ? title : 'item'}_${index}`}
onClick={onClick}
disabled={disabled}
>
{title}
</ActionButton>
))}
</Container>
<StyledContainer>
<StyledFlex>
{actionItems
.filter(({ hidden }) => !hidden)
.map(({ title, onClick, disabled }, index: number) => (
<Box
key={`${typeof title === 'string' ? title : 'item'}_${index}`}
sx={{
ml: 1,
fontSize: 1,
a: ActionColors(disabled),
button: ActionColors(disabled),
}}
>
{typeof title === 'string' ? (
<Button onClick={onClick} disabled={disabled}>
{title}
</Button>
) : (
title
)}
</Box>
))}
</StyledFlex>
</StyledContainer>
);
22 changes: 19 additions & 3 deletions ui/components/src/Collapsible/Collapsible.stories.tsx
@@ -1,20 +1,36 @@
import React from 'react';
import { Box, Button } from 'theme-ui';
import { Collapsible } from './Collapsible';
import { Collapsible, CollapsibleProps } from './Collapsible';

export default {
title: 'Components/Collapsible',
component: Collapsible,
};

export const simple = () => {
export const simple = ({ easing }: CollapsibleProps) => {
const [isOpen, setIsOpen] = React.useState(false);
return (
<Box>
<Button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? 'close' : 'open'}
</Button>
<Collapsible isOpen={isOpen}>content</Collapsible>
<Collapsible isOpen={isOpen} easing={easing}>
content
</Collapsible>
</Box>
);
};

simple.story = {
parameters: {
addonControls: {
smart: false,
},
controls: {
easing: {
type: 'options',
options: ['ease', 'linear', 'ease-in', 'ease-out', 'ease-in-out'],
},
},
},
};
Expand Up @@ -32,7 +32,7 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
padding: '16px 20px',
},
tr: {
borderTop: '1px solid rgba(0, 0, 0, 0.1)',
borderBottom: '1px solid rgba(0, 0, 0, 0.1)',
},
},
buttons: {
Expand All @@ -48,6 +48,7 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
},
colors: {
...polaris.colors,
highlight: '#339793',
accent: '#1EA7FD',
fadedText: lighten(0.25, polaris.colors.text),
lightenPrimary: '#F6F9FC',
Expand Down
File renamed without changes.

0 comments on commit aa0c212

Please sign in to comment.