Convert <Avatar /> component to Storybook

Co-authored-by: Chris Svenningsen <chris@carbonfive.com>
Co-authored-by: Sidney Keese <me@sidke.com>
This commit is contained in:
Chris Svenningsen 2020-08-13 13:53:45 -07:00 committed by GitHub
parent 4169c120fc
commit d3d3c41f94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 183 additions and 540 deletions

View file

@ -1,468 +0,0 @@
### With avatar
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={112}
color="blue"
avatarPath={util.gifObjectUrl}
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={80}
color="blue"
avatarPath={util.gifObjectUrl}
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={52}
color="blue"
avatarPath={util.gifObjectUrl}
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="blue"
avatarPath={util.gifObjectUrl}
conversationType="direct"
i18n={util.i18n}
/>
<hr />
<Avatar
size={80}
color="blue"
avatarPath={util.gifObjectUrl}
conversationType="direct"
onClick={() => console.log('onClick')}
i18n={util.i18n}
/>
<Avatar
size={52}
color="blue"
avatarPath={util.gifObjectUrl}
conversationType="direct"
onClick={() => console.log('onClick')}
i18n={util.i18n}
/>
<Avatar
size={28}
color="blue"
avatarPath={util.gifObjectUrl}
conversationType="direct"
onClick={() => console.log('onClick')}
i18n={util.i18n}
/>
</util.ConversationContext>
```
### With only name
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={28}
color="blue"
name="John"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="green"
name="John Smith"
conversationType="direct"
i18n={util.i18n}
/>
</util.ConversationContext>
```
### Just phone number
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={28}
color="pink"
phoneNumber="(555) 353-3433"
conversationType="direct"
i18n={util.i18n}
/>
</util.ConversationContext>
```
### Letters
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={112}
color="blue"
name="One"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={80}
color="blue"
name="One"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={52}
color="blue"
name="One"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="blue"
name="One"
conversationType="direct"
i18n={util.i18n}
/>
<hr />
<Avatar
size={80}
color="blue"
name="One"
conversationType="direct"
onClick={() => console.log('onClick')}
i18n={util.i18n}
/>
<Avatar
size={52}
color="blue"
name="One"
conversationType="direct"
onClick={() => console.log('onClick')}
i18n={util.i18n}
/>
<Avatar
size={28}
color="blue"
name="One"
conversationType="direct"
onClick={() => console.log('onClick')}
i18n={util.i18n}
/>
</util.ConversationContext>
```
### Note to self
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={112}
color="pink"
noteToSelf={true}
phoneNumber="(555) 353-3433"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={80}
color="pink"
noteToSelf={true}
phoneNumber="(555) 353-3433"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={52}
color="pink"
noteToSelf={true}
phoneNumber="(555) 353-3433"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="pink"
noteToSelf={true}
phoneNumber="(555) 353-3433"
conversationType="direct"
i18n={util.i18n}
/>
</util.ConversationContext>
```
### Group Icon
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar size={112} color="blue" conversationType="group" i18n={util.i18n} />
<Avatar size={80} color="blue" conversationType="group" i18n={util.i18n} />
<Avatar size={52} color="blue" conversationType="group" i18n={util.i18n} />
<Avatar size={28} color="blue" conversationType="group" i18n={util.i18n} />
</util.ConversationContext>
```
### Contact Icon
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar size={112} color="blue" conversationType="direct" i18n={util.i18n} />
<Avatar size={80} color="blue" conversationType="direct" i18n={util.i18n} />
<Avatar size={52} color="blue" conversationType="direct" i18n={util.i18n} />
<Avatar size={28} color="blue" conversationType="direct" i18n={util.i18n} />
</util.ConversationContext>
```
### All colors, 28px
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={28}
color="signal-blue"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="signal-blue"
name="Group"
conversationType="group"
i18n={util.i18n}
/>
<Avatar
size={28}
color="red"
name="Red"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="deep_orange"
name="Deep Orange"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="brown"
name="Broen"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="pink"
name="Pink"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="purple"
name="Purple"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="indigo"
name="Indigo"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="blue"
name="Blue"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="teal"
name="Teal"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="green"
name="Green"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="light_green"
name="Light Green"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={28}
color="blue_grey"
name="Blue Grey"
conversationType="direct"
i18n={util.i18n}
/>
</util.ConversationContext>
```
### 52px
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={52}
color="teal"
name="John Smith"
avatarPath={util.gifObjectUrl}
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={52}
color="teal"
name="John"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={52}
color="teal"
name="John Smith"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar size={52} color="teal" conversationType="direct" i18n={util.i18n} />
<Avatar
size={52}
color="teal"
name="Pupplies"
conversationType="group"
i18n={util.i18n}
/>
</util.ConversationContext>
```
### 80px
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={80}
color="teal"
name="John Smith"
avatarPath={util.gifObjectUrl}
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={80}
color="teal"
name="John"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={80}
color="teal"
name="John Smith"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar size={80} color="teal" conversationType="direct" i18n={util.i18n} />
<Avatar
size={80}
color="teal"
name="Pupplies"
conversationType="group"
i18n={util.i18n}
/>
</util.ConversationContext>
```
### 112px
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={112}
color="teal"
name="John Smith"
avatarPath={util.gifObjectUrl}
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={112}
color="teal"
name="John"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar
size={112}
color="teal"
name="John Smith"
conversationType="direct"
i18n={util.i18n}
/>
<Avatar size={112} color="teal" conversationType="direct" i18n={util.i18n} />
<Avatar
size={112}
color="teal"
name="Pupplies"
conversationType="group"
i18n={util.i18n}
/>
</util.ConversationContext>
```
### Broken color
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={28}
color="fake"
name="F"
conversationType="direct"
i18n={util.i18n}
/>
</util.ConversationContext>
```
### Broken image
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={28}
color="pink"
name="John Smith"
avatarPath="nonexistent"
conversationType="direct"
i18n={util.i18n}
/>
</util.ConversationContext>
```
### Broken image for group
```jsx
<util.ConversationContext theme={util.theme} ios={util.ios}>
<Avatar
size={28}
avatarPath="nonexistent"
color="pink"
name="Puppies"
avatarPath="nonexistent"
conversationType="group"
i18n={util.i18n}
/>
</util.ConversationContext>
```

View file

@ -0,0 +1,126 @@
import * as React from 'react';
import { Avatar, Props } from './Avatar';
import { storiesOf } from '@storybook/react';
import { boolean, select, text } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';
// @ts-ignore
import { setup as setupI18n } from '../../js/modules/i18n';
// @ts-ignore
import enMessages from '../../_locales/en/messages.json';
import { Colors, ColorType } from '../types/Colors';
const i18n = setupI18n('en', enMessages);
const story = storiesOf('Components/Avatar', module);
const colorMap: Record<string, ColorType> = Colors.reduce(
(m, color) => ({
...m,
[color]: color,
}),
{}
);
const conversationTypeMap: Record<string, Props['conversationType']> = {
direct: 'direct',
group: 'group',
};
const createProps = (overrideProps: Partial<Props> = {}): Props => ({
avatarPath: text('avatarPath', overrideProps.avatarPath || ''),
color: select('color', colorMap, overrideProps.color || 'blue'),
conversationType: select(
'conversationType',
conversationTypeMap,
overrideProps.conversationType || 'direct'
),
i18n,
name: text('name', overrideProps.name || ''),
noteToSelf: boolean('noteToSelf', overrideProps.noteToSelf || false),
onClick: action('onClick'),
phoneNumber: text('phoneNumber', overrideProps.phoneNumber || ''),
size: 80,
title: '',
});
const sizes: Array<Props['size']> = [112, 80, 52, 32, 28];
story.add('Avatar', () => {
const props = createProps({
avatarPath: '/fixtures/giphy-GVNvOUpeYmI7e.gif',
});
return sizes.map(size => <Avatar key={size} {...props} size={size} />);
});
story.add('One-word Name', () => {
const props = createProps({
name: 'John',
});
return sizes.map(size => <Avatar key={size} {...props} size={size} />);
});
story.add('Multi-word Name', () => {
const props = createProps({
name: 'John Smith',
});
return sizes.map(size => <Avatar key={size} {...props} size={size} />);
});
story.add('Note to Self', () => {
const props = createProps({
noteToSelf: true,
});
return sizes.map(size => <Avatar key={size} {...props} size={size} />);
});
story.add('Contact Icon', () => {
const props = createProps();
return sizes.map(size => <Avatar key={size} {...props} size={size} />);
});
story.add('Group Icon', () => {
const props = createProps({
conversationType: 'group',
});
return sizes.map(size => <Avatar key={size} {...props} size={size} />);
});
story.add('Colors', () => {
const props = createProps();
return Colors.map(color => <Avatar key={color} {...props} color={color} />);
});
story.add('Broken Color', () => {
const props = createProps({
color: 'nope' as ColorType,
});
return sizes.map(size => <Avatar key={size} {...props} size={size} />);
});
story.add('Broken Avatar', () => {
const props = createProps({
avatarPath: 'badimage.png',
});
return sizes.map(size => <Avatar key={size} {...props} size={size} />);
});
story.add('Broken Avatar for Group', () => {
const props = createProps({
avatarPath: 'badimage.png',
conversationType: 'group',
});
return sizes.map(size => <Avatar key={size} {...props} size={size} />);
});

View file

@ -2,7 +2,8 @@ import * as React from 'react';
import classNames from 'classnames';
import { getInitials } from '../util/getInitials';
import { ColorType, LocalizerType } from '../types/Util';
import { LocalizerType } from '../types/Util';
import { ColorType } from '../types/Colors';
export type Props = {
avatarPath?: string;

View file

@ -1,7 +1,7 @@
import * as React from 'react';
import { CallManager } from './CallManager';
import { CallState } from '../types/Calling';
import { ColorType } from '../types/Util';
import { ColorType } from '../types/Colors';
// @ts-ignore
import { setup as setupI18n } from '../../js/modules/i18n';

View file

@ -1,6 +1,6 @@
import * as React from 'react';
import { CallState } from '../types/Calling';
import { ColorType } from '../types/Util';
import { ColorType } from '../types/Colors';
import { CallScreen } from './CallScreen';
// @ts-ignore

View file

@ -5,7 +5,8 @@ import { Avatar } from './Avatar';
import { Emojify } from './conversation/Emojify';
import { InContactsIcon } from './InContactsIcon';
import { ColorType, LocalizerType } from '../types/Util';
import { LocalizerType } from '../types/Util';
import { ColorType } from '../types/Colors';
interface Props {
title: string;

View file

@ -9,7 +9,8 @@ import { ContactName } from './conversation/ContactName';
import { TypingAnimation } from './conversation/TypingAnimation';
import { cleanId } from './_util';
import { ColorType, LocalizerType } from '../types/Util';
import { LocalizerType } from '../types/Util';
import { ColorType } from '../types/Colors';
export type PropsData = {
id: string;

View file

@ -1,6 +1,6 @@
import * as React from 'react';
import { IncomingCallBar } from './IncomingCallBar';
import { ColorType } from '../types/Util';
import { Colors, ColorType } from '../types/Colors';
// @ts-ignore
import { setup as setupI18n } from '../../js/modules/i18n';
@ -31,22 +31,6 @@ const defaultProps = {
i18n,
};
const colors: Array<ColorType> = [
'blue',
'blue_grey',
'brown',
'deep_orange',
'green',
'grey',
'indigo',
'light_green',
'pink',
'purple',
'red',
'teal',
'ultramarine',
];
const permutations = [
{
title: 'Incoming Call Bar (no call details)',
@ -74,7 +58,7 @@ const permutations = [
storiesOf('Components/IncomingCallBar', module)
.add('Knobs Playground', () => {
const color = select('color', colors, 'ultramarine');
const color = select('color', Colors, 'ultramarine');
const isVideoCall = boolean('isVideoCall', false);
const name = text(
'name',

View file

@ -7,7 +7,8 @@ import { createPortal } from 'react-dom';
import { showSettings } from '../shims/Whisper';
import { Avatar } from './Avatar';
import { AvatarPopup } from './AvatarPopup';
import { ColorType, LocalizerType } from '../types/Util';
import { LocalizerType } from '../types/Util';
import { ColorType } from '../types/Colors';
export interface PropsType {
searchTerm: string;

View file

@ -6,7 +6,8 @@ import { MessageBodyHighlight } from './MessageBodyHighlight';
import { Timestamp } from './conversation/Timestamp';
import { ContactName } from './conversation/ContactName';
import { ColorType, LocalizerType } from '../types/Util';
import { LocalizerType } from '../types/Util';
import { ColorType } from '../types/Colors';
export type PropsDataType = {
isSelected?: boolean;

View file

@ -11,7 +11,8 @@ import { Emojify } from './Emojify';
import { Avatar } from '../Avatar';
import { InContactsIcon } from '../InContactsIcon';
import { ColorType, LocalizerType } from '../../types/Util';
import { LocalizerType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
interface TimerOption {
name: string;

View file

@ -39,7 +39,8 @@ import { ContactType } from '../../types/Contact';
import { getIncrement } from '../../util/timer';
import { isFileDangerous } from '../../util/isFileDangerous';
import { ColorType, LocalizerType } from '../../types/Util';
import { LocalizerType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
import { createRefMerger } from '../_util';
import { ContextMenu, ContextMenuTrigger, MenuItem } from 'react-contextmenu';

View file

@ -5,7 +5,8 @@ import moment from 'moment';
import { Avatar } from '../Avatar';
import { ContactName } from './ContactName';
import { Message, Props as MessageProps } from './Message';
import { ColorType, LocalizerType } from '../../types/Util';
import { LocalizerType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
interface Contact {
status: string;

View file

@ -7,7 +7,8 @@ import * as MIME from '../../../ts/types/MIME';
import * as GoogleChrome from '../../../ts/util/GoogleChrome';
import { MessageBody } from './MessageBody';
import { ColorType, LocalizerType } from '../../types/Util';
import { LocalizerType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
import { ContactName } from './ContactName';
interface Props {

View file

@ -5,7 +5,7 @@ import { ContactName } from './ContactName';
import { Avatar, Props as AvatarProps } from '../Avatar';
import { Emoji } from '../emoji/Emoji';
import { useRestoreFocus } from '../../util/hooks';
import { ColorType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
export type Reaction = {
emoji: string;

View file

@ -4,7 +4,8 @@ import classNames from 'classnames';
import { TypingAnimation } from './TypingAnimation';
import { Avatar } from '../Avatar';
import { ColorType, LocalizerType } from '../../types/Util';
import { LocalizerType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
interface Props {
avatarPath?: string;