Skip to content

Commit

Permalink
WC-22 page head actions (#64)
Browse files Browse the repository at this point in the history
* setting up basic flex component

* adding direction props

* wip flex

* adding flex tests

* adding flexitem tests and some flex comments

* adding comments

* swapping out template quotes for regular quotes

* adding basic page actions files

* adding swarm icons library

* adding raw loader and swarm componets to storybook

* cleaning out old icon sprite setup, add in swarm icons to decorator

* removing webpacksvgicons dependency

* migrating pagetitle to page head

* cr: handling @nlax nitpick, adding visualization for justify

* cr: spaces

* adding style for page head

* adding some spacing improvements for info wrapper

* reducing down pageHead and pageActionButton down into 2 components, cleaning up styles for info container

* linting

* cr: adjusting flex component based on comments, adjusting tests to not check for flex and p, cleaning up css

* cr: linting

* removing icon dependency

* updating icon test

* updating story with icons

* adjusting button tests, and fixing descriptions

* updating tests, renaming some of the prop types

* cleaning up button a bit more

* linting

* beforeAll -> beforeEach
  • Loading branch information
Lori Hutchek authored Feb 12, 2017
1 parent d4fb5f2 commit b2179d9
Show file tree
Hide file tree
Showing 18 changed files with 694 additions and 92 deletions.
12 changes: 12 additions & 0 deletions assets/scss/_pageActionButton.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.pageActionButton {
border: none;
border-radius: 0;
width: 100%;
}

@include responsiveBase() {
.pageActionButton {
min-height: $base*$line-height-largeText*2; // text--display height * line-height
justify-content: center;
}
}
5 changes: 5 additions & 0 deletions assets/scss/_pageHead.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@include responsiveBase() {
.pageHead {
padding-bottom: $base;
}
}
2 changes: 2 additions & 0 deletions assets/scss/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
@import "bounds";
@import "chunk";
@import "flex";
@import "pageActionButton";
@import "pageHead";
@import "stripe";
@import "section";

Expand Down
7 changes: 6 additions & 1 deletion assets/scss/storybook.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ html, body, #root {
align-items: center;
justify-content: center;
}

div[data-reactroot] {
width: 100%;
div {
width: 100%;
}
}
//
// SASS BASE FILE
//
Expand Down
35 changes: 23 additions & 12 deletions src/Button.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import React from 'react';
import cx from 'classnames';
import Flex from './Flex';
import FlexItem from './FlexItem';

export const BUTTON_CLASS = 'button';

/**
* SQ2 Button component
Expand All @@ -24,7 +28,7 @@ class Button extends React.Component {
} = this.props;

const classNames = cx(
'button',
BUTTON_CLASS,
{
'button--contrast': contrast,
'button--fullWidth': fullWidth,
Expand All @@ -33,22 +37,30 @@ class Button extends React.Component {
},
className
);
const opts = right ? { rowReverse: 'all' } : {};

const iconChildren = [
<span className='button--icon' key={0}>{icon}</span>,
'\u00a0', // non-breaking space
<span className='button--label' key={2}>{children}</span>
];
if (right) {
iconChildren.reverse();
}
const iconChildren = (
<Flex className='button--icon-wrapper' {...opts}>
{icon &&
<FlexItem shrink className='button--icon valign--middle'>
{icon}
</FlexItem>
}
{children &&
<FlexItem className='button--label valign--middle align--center atMedium_align--left'>
{children}
</FlexItem>
}
</Flex>
);

return (
<button
className={classNames}
onClick={onClick}
role='button'
{...other}>
{...other}
>
{ icon ? iconChildren : children }
</button>
);
Expand All @@ -65,7 +77,6 @@ Button.propTypes = {
primary: React.PropTypes.bool,
small: React.PropTypes.bool,
icon: React.PropTypes.any,
right: React.PropTypes.bool
right: React.PropTypes.bool,
};

export default Button;
6 changes: 3 additions & 3 deletions src/Flex.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export const VALID_BREAKPOINTS = {

export const VALID_SPACE = {
center: 'center',
around: 'spaceAround',
between: 'spaceBetween',
end: 'flexEnd'
spaceAround: 'spaceAround',
spaceBetween: 'spaceBetween',
flexEnd: 'flexEnd'
};

export const DIRECTION_ROW = 'row';
Expand Down
82 changes: 82 additions & 0 deletions src/PageActionButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React from 'react';
import Button from './Button';
import Flex from './Flex';
import FlexItem from './FlexItem';

export const PAGE_ACTION_BUTTON_CLASS = 'pageActionButton';

/**
* @description Design System Component: Provides `PageActionButtion` button which offers a larger button
* with stacked icon/label or side by side view options. It differs from `Button` in that there
* is now visible button border and offers more enhanced stacking options. Common usage would be
* with `PageHead` component
* @module PageActionButton
*/
class PageActionButton extends React.Component {
render() {
const {
children,
className,
icon,
label,
stackVertical,
stackVerticalAtMedium,
onClick,
...other
} = this.props;

let direction,
switchDirection,
justify;

// if (direction is column)
// icons and labels in stacked rows,
// Otherwise, always labels and icons
// are side by side in a row
if (stackVertical || stackVerticalAtMedium) {
direction = 'column';
justify = 'center';
switchDirection = stackVerticalAtMedium ? 'medium' : '';
}

return (
<Button
className={PAGE_ACTION_BUTTON_CLASS}
onClick={onClick}
>
<Flex
direction={direction}
switchDirection={switchDirection}
justify={justify}
className={className}
{...other}
>
{icon &&
<FlexItem shrink className='valign--middle'>
{icon}
</FlexItem>
}
{label &&
<FlexItem shrink className='valign--middle align--center atMedium_align--left'>
<div className='text--small text--hint'>{label}</div>
</FlexItem>
}
{children}
</Flex>
</Button>
);
}
}

PageActionButton.propTypes = {
icon: React.PropTypes.element.isRequired,
label: React.PropTypes.oneOfType([
React.PropTypes.element,
React.PropTypes.string
]).isRequired,
stackVertical: React.PropTypes.bool,
stackVerticalAtMedium: React.PropTypes.bool,
onClick: React.PropTypes.func,
};

export default PageActionButton;
90 changes: 90 additions & 0 deletions src/PageHead.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from 'react';
import cx from 'classnames';
import Chunk from './Chunk';
import Flex from './Flex';
import FlexItem from './FlexItem';
import Section from './Section';

export const PAGE_HEAD_CLASS = 'pageHead';
export const PAGE_TITLE_CLASS = 'pageTitle';
export const PAGE_SUBTITLE_CLASS = 'pageSubtitle';
export const PAGE_ACTIONS_CLASS = 'pageActions';
export const PAGE_ACTION_CLASS = 'pageAction';

/**
* @description Design System Component: `PageHead` creates a
* header, and subtitle container for pages, and provides an optional Flex
* side menu. The side menu can contain any number of items which
* appropriately adjusts to stacked or column view.
* @module PageHead
*/
class PageHead extends React.Component {
render() {
const {
children,
className,
subtitle,
title,
menuItems,
...other
} = this.props;

const classNames = cx(
PAGE_HEAD_CLASS,
className
);

const menuRender = menuItems.map((menuItem, i) => (
<FlexItem className={PAGE_ACTION_CLASS} key={i} shrink>
{menuItem}
</FlexItem>
));

return (
<Section
className={classNames}
{...other}
>
<Flex
className={PAGE_TITLE_CLASS}
direction='column'
switchDirection='large'
>
<FlexItem>
<Chunk className='align--center atMedium_align--left'>
<h1 className='text--display1'>{title}</h1>
{subtitle &&
<p className={`${PAGE_SUBTITLE_CLASS} text--secondary`}>{subtitle}</p>
}
</Chunk>
</FlexItem>
{menuItems.length > 0 &&
<FlexItem shrink>
<Flex justify='center' className={PAGE_ACTIONS_CLASS}>
{menuRender}
</Flex>
</FlexItem>
}
</Flex>
{children}
</Section>
);
}
}

PageHead.propTypes = {
title: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.element
]).isRequired,
subtitle: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.element
]),
menuItems: React.PropTypes.array,
};
PageHead.defaultProps = {
menuItems: []
};

export default PageHead;
6 changes: 4 additions & 2 deletions src/button.story.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from 'react';
import { storiesOf, action } from '@kadira/storybook';
import { decorateWithLocale } from './utils/decorators';
import { InfoWrapper } from './utils/storyComponents';
import { Inverted } from './utils/storyComponents';
import Button from './Button';
import Icon from './Icon';

storiesOf('Button', module)
.addDecorator(decorateWithLocale)
.addWithInfo(
'default',
'This is the basic usage with the component.',
Expand Down Expand Up @@ -46,10 +48,10 @@ storiesOf('Button', module)
<Button onClick={action('clicked')} small>Button Label</Button>
))
.add('Icon', () => (
<Button onClick={action('clicked')} icon={<Icon shape='chevron-left' size='s' />}>Button Label</Button>
<Button onClick={action('clicked')} icon={<Icon shape='search' size='s' />}>Button Label</Button>
))
.add('Icon Right', () => (
<Button onClick={action('clicked')} icon={<Icon shape='chevron-right' size='s' />} right>Button Label</Button>
<Button onClick={action('clicked')} icon={<Icon shape='search' size='s' />} right>Button Label</Button>
))
.add('No Label', () => (
<Button></Button>
Expand Down
Loading

0 comments on commit b2179d9

Please sign in to comment.