Skip to content

Commit

Permalink
feat(icons): make decorative required + icon docs (#165)
Browse files Browse the repository at this point in the history
* feat(icons): make decorative required

* feat(website): add icons docs

* fix(spinner): fix story derp

* fix(website): icon docs fixes

* fix(website): update icon docs with pr comments

* fix: more review notes

* fix: add link to storybook icon list

* fix(website): icon docs refactored

* fix(website): add sidebar submenu indentation

* fix(spinner): forgot to pass 'title' prop to icon

* fix(website): add aria-expanded to new sidebar item

* fix: minor nits

* fix: checkpoint major changes

* chore: adding some image assets for docs

* docs: how to add an icon page + nav fixes

* fix: pr feedback

* fix: build issue

* fix: remove sub styles for tsc

* test(buttons): update snapshot

* chore: rebuild

* fix: many cr fixes

* fix: jin comments

* fix(button): story fixes for decorative icons

* fix: eslint

* fix: fancy quotes
  • Loading branch information
TheSisb committed Nov 20, 2019
1 parent 81fa3b2 commit 15ccbc2
Show file tree
Hide file tree
Showing 23 changed files with 516 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ exports[`Button States Has a loading state 1`] = `
<title
id="1"
>
Loading Icon
Loading, please wait.
</title>
<path
d="M20.085 13.123a1 1 0 01.71 1.224A9.103 9.103 0 014.717 17.46l-.15 1.756a1 1 0 11-1.992-.17l.407-4.773a1 1 0 011.357-.848l4.47 1.728a1 1 0 11-.72 1.865l-1.691-.652a7.103 7.103 0 0012.463-2.533 1 1 0 011.223-.71zM12.008 2.892a9.1 9.1 0 017.283 3.64l.148-1.756a1 1 0 011.993.17l-.407 4.773a1 1 0 01-1.357.847l-4.47-1.727a1 1 0 01.72-1.866l1.691.653a7.103 7.103 0 00-12.463 2.533 1 1 0 01-1.932-.514 9.103 9.103 0 018.794-6.753z"
Expand Down Expand Up @@ -634,7 +634,7 @@ exports[`Button States Has a loading state 1`] = `
<title
id="2"
>
Loading Icon
Loading, please wait.
</title>
<path
d="M20.085 13.123a1 1 0 01.71 1.224A9.103 9.103 0 014.717 17.46l-.15 1.756a1 1 0 11-1.992-.17l.407-4.773a1 1 0 011.357-.848l4.47 1.728a1 1 0 11-.72 1.865l-1.691-.652a7.103 7.103 0 0012.463-2.533 1 1 0 011.223-.71zM12.008 2.892a9.1 9.1 0 017.283 3.64l.148-1.756a1 1 0 011.993.17l-.407 4.773a1 1 0 01-1.357.847l-4.47-1.727a1 1 0 01.72-1.866l1.691.653a7.103 7.103 0 00-12.463 2.533 1 1 0 01-1.932-.514 9.103 9.103 0 018.794-6.753z"
Expand Down Expand Up @@ -680,7 +680,7 @@ exports[`Button States Has a loading state 1`] = `
<title
id="3"
>
Loading Icon
Loading, please wait.
</title>
<path
d="M20.085 13.123a1 1 0 01.71 1.224A9.103 9.103 0 014.717 17.46l-.15 1.756a1 1 0 11-1.992-.17l.407-4.773a1 1 0 011.357-.848l4.47 1.728a1 1 0 11-.72 1.865l-1.691-.652a7.103 7.103 0 0012.463-2.533 1 1 0 011.223-.71zM12.008 2.892a9.1 9.1 0 017.283 3.64l.148-1.756a1 1 0 011.993.17l-.407 4.773a1 1 0 01-1.357.847l-4.47-1.727a1 1 0 01.72-1.866l1.691.653a7.103 7.103 0 00-12.463 2.533 1 1 0 01-1.932-.514 9.103 9.103 0 018.794-6.753z"
Expand Down Expand Up @@ -726,7 +726,7 @@ exports[`Button States Has a loading state 1`] = `
<title
id="4"
>
Loading Icon
Loading, please wait.
</title>
<path
d="M20.085 13.123a1 1 0 01.71 1.224A9.103 9.103 0 014.717 17.46l-.15 1.756a1 1 0 11-1.992-.17l.407-4.773a1 1 0 011.357-.848l4.47 1.728a1 1 0 11-.72 1.865l-1.691-.652a7.103 7.103 0 0012.463-2.533 1 1 0 011.223-.71zM12.008 2.892a9.1 9.1 0 017.283 3.64l.148-1.756a1 1 0 011.993.17l-.407 4.773a1 1 0 01-1.357.847l-4.47-1.727a1 1 0 01.72-1.866l1.691.653a7.103 7.103 0 00-12.463 2.533 1 1 0 01-1.932-.514 9.103 9.103 0 018.794-6.753z"
Expand Down Expand Up @@ -772,7 +772,7 @@ exports[`Button States Has a loading state 1`] = `
<title
id="5"
>
Loading Icon
Loading, please wait.
</title>
<path
d="M20.085 13.123a1 1 0 01.71 1.224A9.103 9.103 0 014.717 17.46l-.15 1.756a1 1 0 11-1.992-.17l.407-4.773a1 1 0 011.357-.848l4.47 1.728a1 1 0 11-.72 1.865l-1.691-.652a7.103 7.103 0 0012.463-2.533 1 1 0 011.223-.71zM12.008 2.892a9.1 9.1 0 017.283 3.64l.148-1.756a1 1 0 011.993.17l-.407 4.773a1 1 0 01-1.357.847l-4.47-1.727a1 1 0 01.72-1.866l1.691.653a7.103 7.103 0 00-12.463 2.533 1 1 0 01-1.932-.514 9.103 9.103 0 018.794-6.753z"
Expand Down Expand Up @@ -818,7 +818,7 @@ exports[`Button States Has a loading state 1`] = `
<title
id="6"
>
Loading Icon
Loading, please wait.
</title>
<path
d="M20.085 13.123a1 1 0 01.71 1.224A9.103 9.103 0 014.717 17.46l-.15 1.756a1 1 0 11-1.992-.17l.407-4.773a1 1 0 011.357-.848l4.47 1.728a1 1 0 11-.72 1.865l-1.691-.652a7.103 7.103 0 0012.463-2.533 1 1 0 011.223-.71zM12.008 2.892a9.1 9.1 0 017.283 3.64l.148-1.756a1 1 0 011.993.17l-.407 4.773a1 1 0 01-1.357.847l-4.47-1.727a1 1 0 01.72-1.866l1.691.653a7.103 7.103 0 00-12.463 2.533 1 1 0 01-1.932-.514 9.103 9.103 0 018.794-6.753z"
Expand Down
2 changes: 1 addition & 1 deletion packages/paste-core/components/button/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const Button: React.FC<ButtonProps> = props => {
<ButtonChildren buttonState={buttonState}>{props.children}</ButtonChildren>
{showLoading ? (
<SpinnerWrapper as="span">
<Spinner title=". Loading, please wait." />
<Spinner decorative={false} title="Loading, please wait." />
</SpinnerWrapper>
) : null}
</ButtonWrapper>
Expand Down
34 changes: 17 additions & 17 deletions packages/paste-core/components/button/stories/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ storiesOf('Components|Button', module)
onFocus={action('handleFocus')}
onBlur={action('handleBlur')}
>
<PlusIcon />
<PlusIcon decorative />
<span>Activate</span>
</Button>
);
Expand All @@ -71,7 +71,7 @@ storiesOf('Components|Button', module)
onFocus={action('handleFocus')}
onBlur={action('handleBlur')}
>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
);
})
Expand Down Expand Up @@ -105,13 +105,13 @@ storiesOf('Components|Button', module)
<br />
<section>
<Button variant="primary" size="icon">
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="primary" size="icon" loading>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="primary" size="icon" disabled>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
</section>
<br />
Expand Down Expand Up @@ -153,13 +153,13 @@ storiesOf('Components|Button', module)
<br />
<section>
<Button variant="secondary" size="icon">
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="secondary" size="icon" loading>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="secondary" size="icon" disabled>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
</section>
<br />
Expand Down Expand Up @@ -201,13 +201,13 @@ storiesOf('Components|Button', module)
<br />
<section>
<Button variant="destructive" size="icon">
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="destructive" size="icon" loading>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="destructive" size="icon" disabled>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
</section>
<br />
Expand Down Expand Up @@ -249,13 +249,13 @@ storiesOf('Components|Button', module)
<br />
<section>
<Button variant="link" size="icon">
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="link" size="icon" loading>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="link" size="icon" disabled>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
</section>
<br />
Expand Down Expand Up @@ -297,13 +297,13 @@ storiesOf('Components|Button', module)
<br />
<section>
<Button variant="destructive_link" size="icon">
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="destructive_link" size="icon" loading>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
<Button variant="destructive_link" size="icon" disabled>
<PlusIcon />
<PlusIcon decorative={false} title="Add to cart" />
</Button>
</section>
<br />
Expand Down
5 changes: 2 additions & 3 deletions packages/paste-core/components/spinner/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@ interface SpinnerProps extends LoadingIconProps {
size?: IconSize;
}

const Spinner: React.FC<SpinnerProps> = ({as, size, iconColor, decorative}) => (
const Spinner: React.FC<SpinnerProps> = ({as, size, iconColor, decorative, title}) => (
<SpinningWrapper size={size}>
<LoadingIcon as={as} size={size} iconColor={iconColor} decorative={decorative} />
<LoadingIcon as={as} size={size} iconColor={iconColor} decorative={decorative} title={title} />
</SpinningWrapper>
);

Spinner.defaultProps = {
size: 'sizeIcon20',
decorative: false,
};

Spinner.displayName = 'Spinner';
Expand Down
13 changes: 11 additions & 2 deletions packages/paste-core/components/spinner/stories/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import {storiesOf} from '@storybook/react';
import {withKnobs, text, select} from '@storybook/addon-knobs';
import {withKnobs, text, select, boolean} from '@storybook/addon-knobs';
import {TextColor, IconSize} from '@twilio-paste/types';
import {DefaultTheme} from '@twilio-paste/theme-tokens';
import {Spinner} from '../src';
Expand All @@ -13,15 +13,24 @@ storiesOf('Components|Spinner', module)
.add('Default', () => {
const iconColorValue = select('iconColor', IconColorOptions, 'currentColor') as TextColor;
const sizeValue = select('size', SizeOptions, 'sizeIcon20') as IconSize;
const decorativeValue = boolean('decorative', false);

return <Spinner iconColor={iconColorValue} size={sizeValue} title={text('title', 'Now loading')} />;
return (
<Spinner
iconColor={iconColorValue}
size={sizeValue}
title={text('title', 'Now loading')}
decorative={decorativeValue}
/>
);
})
.add('Responsive', () => {
return (
<Spinner
iconColor={['colorText', 'colorTextError']}
size={['sizeIcon10', 'sizeIcon20', 'sizeIcon30', 'sizeIcon40']}
title={text('title', 'Now loading')}
decorative={false}
/>
);
});
12 changes: 6 additions & 6 deletions packages/paste-icons/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import AssetsIcon from '@twilio-paste/icons/react/AssetsIcon';

### Standard Props

| Prop | Type | Description | Default |
| ----------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| decorative? | boolean | Whether or not the SVG is just visual flair or adds meaning to the page. Specifically for screenreaders to know whether to read out the title or not. | true |
| title? | string | The accesibility text that is read when screenreaders get to this component | Component name |
| size? | number | The width and height value (all icons are square) in pixels | 24 |
| color? | string | The color of your icon | currentColor - whatever is the font-color inherited from up the DOM tree |
| Prop | Type | Description | Default |
| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| decorative | boolean | Whether or not the SVG is just visual flair or adds meaning to the page. Specifically for screenreaders to know whether to read out the title or not. | true |
| title? | string | The accesibility text that is read when screenreaders get to this component | Component name |
| size? | number | The width and height value (all icons are square) in pixels | 24 |
| color? | string | The color of your icon | currentColor - whatever is the font-color inherited from up the DOM tree |

Keep in mind these props are the **Base Guarantee** for icon components. Some icons may have additional functionality as needed (a way to style two color options for example).

Expand Down
41 changes: 21 additions & 20 deletions packages/paste-icons/src/LoadingIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,30 @@ import {IconWrapper, IconWrapperProps} from './helpers/IconWrapper';

export interface LoadingIconProps extends IconWrapperProps {
title?: string;
decorative?: boolean;
decorative: boolean;
}

const LoadingIcon: React.FC<LoadingIconProps> = ({title, decorative, ...props}) => (
<IconWrapper {...props}>
<UID>
{uid => (
<svg role="img" aria-hidden={decorative} aria-labelledby={uid} width="100%" height="100%" viewBox="0 0 24 24">
{title ? <title id={uid}>{title}</title> : null}
<path
fill="currentColor"
fillRule="evenodd"
d="M20.085 13.123a1 1 0 01.71 1.224A9.103 9.103 0 014.717 17.46l-.15 1.756a1 1 0 11-1.992-.17l.407-4.773a1 1 0 011.357-.848l4.47 1.728a1 1 0 11-.72 1.865l-1.691-.652a7.103 7.103 0 0012.463-2.533 1 1 0 011.223-.71zM12.008 2.892a9.1 9.1 0 017.283 3.64l.148-1.756a1 1 0 011.993.17l-.407 4.773a1 1 0 01-1.357.847l-4.47-1.727a1 1 0 01.72-1.866l1.691.653a7.103 7.103 0 00-12.463 2.533 1 1 0 01-1.932-.514 9.103 9.103 0 018.794-6.753z"
/>
</svg>
)}
</UID>
</IconWrapper>
);
const LoadingIcon: React.FC<LoadingIconProps> = ({as, size, iconColor, title, decorative}) => {
if (!decorative && title == null) {
throw new Error('[LoadingIcon]: Missing a title for non-decorative icon.');
}

LoadingIcon.defaultProps = {
title: 'Loading Icon',
decorative: true,
return (
<IconWrapper as={as} size={size} iconColor={iconColor}>
<UID>
{uid => (
<svg role="img" aria-hidden={decorative} aria-labelledby={uid} width="100%" height="100%" viewBox="0 0 24 24">
{title ? <title id={uid}>{title}</title> : null}
<path
fill="currentColor"
fillRule="evenodd"
d="M20.085 13.123a1 1 0 01.71 1.224A9.103 9.103 0 014.717 17.46l-.15 1.756a1 1 0 11-1.992-.17l.407-4.773a1 1 0 011.357-.848l4.47 1.728a1 1 0 11-.72 1.865l-1.691-.652a7.103 7.103 0 0012.463-2.533 1 1 0 011.223-.71zM12.008 2.892a9.1 9.1 0 017.283 3.64l.148-1.756a1 1 0 011.993.17l-.407 4.773a1 1 0 01-1.357.847l-4.47-1.727a1 1 0 01.72-1.866l1.691.653a7.103 7.103 0 00-12.463 2.533 1 1 0 01-1.932-.514 9.103 9.103 0 018.794-6.753z"
/>
</svg>
)}
</UID>
</IconWrapper>
);
};

LoadingIcon.displayName = 'LoadingIcon';
Expand Down
41 changes: 21 additions & 20 deletions packages/paste-icons/src/PlusIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,30 @@ import {IconWrapper, IconWrapperProps} from './helpers/IconWrapper';

export interface PlusIconProps extends IconWrapperProps {
title?: string;
decorative?: boolean;
decorative: boolean;
}

const PlusIcon: React.FC<PlusIconProps> = ({title, decorative, ...props}) => (
<IconWrapper {...props}>
<UID>
{uid => (
<svg role="img" aria-hidden={decorative} aria-labelledby={uid} width="100%" height="100%" viewBox="0 0 24 24">
{title ? <title id={uid}>{title}</title> : null}
<path
fill="currentColor"
fillRule="evenodd"
d="M12 3.348a1 1 0 011 1V11h6.652a1 1 0 01.993.883l.007.117a1 1 0 01-1 1H13v6.652a1 1 0 01-.883.993l-.117.007a1 1 0 01-1-1V13H4.348a1 1 0 01-.993-.883L3.348 12a1 1 0 011-1H11V4.348a1 1 0 01.883-.993z"
/>
</svg>
)}
</UID>
</IconWrapper>
);
const PlusIcon: React.FC<PlusIconProps> = ({as, size, iconColor, title, decorative}) => {
if (!decorative && title == null) {
throw new Error('[PlusIcon]: Missing a title for non-decorative icon.');
}

PlusIcon.defaultProps = {
title: 'Plus Icon',
decorative: true,
return (
<IconWrapper as={as} size={size} iconColor={iconColor}>
<UID>
{uid => (
<svg role="img" aria-hidden={decorative} aria-labelledby={uid} width="100%" height="100%" viewBox="0 0 24 24">
{title ? <title id={uid}>{title}</title> : null}
<path
fill="currentColor"
fillRule="evenodd"
d="M12 3.348a1 1 0 011 1V11h6.652a1 1 0 01.993.883l.007.117a1 1 0 01-1 1H13v6.652a1 1 0 01-.883.993l-.117.007a1 1 0 01-1-1V13H4.348a1 1 0 01-.993-.883L3.348 12a1 1 0 011-1H11V4.348a1 1 0 01.883-.993z"
/>
</svg>
)}
</UID>
</IconWrapper>
);
};

PlusIcon.displayName = 'PlusIcon';
Expand Down
30 changes: 15 additions & 15 deletions packages/paste-icons/tools/templates/reactIconTemplate.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// Note on a11y: https://css-tricks.com/can-make-icon-system-accessible/
const {pascalCaseWordSplitter} = require('../utils');

const reactIconTemplate = ({componentName, svg}) => `
/**
* This file was automatically generated with @twilio-labs/svg-to-react
Expand All @@ -11,23 +9,25 @@ import {IconWrapper, IconWrapperProps} from './helpers/IconWrapper';
export interface ${componentName}Props extends IconWrapperProps {
title?: string;
decorative?: boolean;
decorative: boolean;
}
const ${componentName}: React.FC<${componentName}Props> = ({title, decorative, ...props}) => (
<IconWrapper {...props}>
<UID>
{uid => (
${svg}
)}
</UID>
</IconWrapper>
);
const ${componentName}: React.FC<${componentName}Props> = ({as, size, iconColor, title, decorative}) => {
if (!decorative && title == null) {
throw new Error('[${componentName}]: Missing a title for non-decorative icon.');
}
${componentName}.defaultProps = {
title: '${pascalCaseWordSplitter(componentName)}',
decorative: true,
return (
<IconWrapper as={as} size={size} iconColor={iconColor}>
<UID>
{uid => (
${svg}
)}
</UID>
</IconWrapper>
);
}
${componentName}.displayName = '${componentName}';
export {${componentName}};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ ${importIconList}
interface IconProps {
title?: string;
decorative?: boolean;
decorative: boolean;
size?: number;
color?: string;
}
Expand Down
Loading

1 comment on commit 15ccbc2

@vercel
Copy link

@vercel vercel bot commented on 15ccbc2 Nov 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.