diff --git a/ts/components/conversation/TypingAnimation.md b/ts/components/conversation/TypingAnimation.md
deleted file mode 100644
index 537c6c7a9..000000000
--- a/ts/components/conversation/TypingAnimation.md
+++ /dev/null
@@ -1,22 +0,0 @@
-### Conversation List
-
-```jsx
-
-
-
-```
-
-### Dark background
-
-Note: background color is 'steel'
-
-```jsx
-
-
-
-```
diff --git a/ts/components/conversation/TypingAnimation.stories.tsx b/ts/components/conversation/TypingAnimation.stories.tsx
new file mode 100644
index 000000000..a577df28b
--- /dev/null
+++ b/ts/components/conversation/TypingAnimation.stories.tsx
@@ -0,0 +1,37 @@
+import * as React from 'react';
+import { storiesOf } from '@storybook/react';
+
+// @ts-ignore
+import { setup as setupI18n } from '../../../js/modules/i18n';
+
+// @ts-ignore
+import enMessages from '../../../_locales/en/messages.json';
+
+import { Props, TypingAnimation } from './TypingAnimation';
+
+const i18n = setupI18n('en', enMessages);
+
+const story = storiesOf('Components/Conversation/TypingAnimation', module);
+
+const createProps = (overrideProps: Partial = {}): Props => ({
+ i18n,
+ color: overrideProps.color || '',
+});
+
+story.add('Default', () => {
+ const props = createProps();
+
+ return ;
+});
+
+story.add('Light', () => {
+ const props = createProps({
+ color: 'light',
+ });
+
+ return (
+
+
+
+ );
+});
diff --git a/ts/components/conversation/TypingAnimation.tsx b/ts/components/conversation/TypingAnimation.tsx
index 744a4f387..06852717a 100644
--- a/ts/components/conversation/TypingAnimation.tsx
+++ b/ts/components/conversation/TypingAnimation.tsx
@@ -3,7 +3,7 @@ import classNames from 'classnames';
import { LocalizerType } from '../../types/Util';
-interface Props {
+export interface Props {
i18n: LocalizerType;
color?: string;
}
diff --git a/ts/components/conversation/TypingBubble.md b/ts/components/conversation/TypingBubble.md
deleted file mode 100644
index 297cd9034..000000000
--- a/ts/components/conversation/TypingBubble.md
+++ /dev/null
@@ -1,38 +0,0 @@
-### In message bubble
-
-```jsx
-
-
-
-
-
-
-
-
-```
-
-### In message bubble, group conversation
-
-```jsx
-
-
-
-
-
-
-
-
-
-
-
-```
diff --git a/ts/components/conversation/TypingBubble.stories.tsx b/ts/components/conversation/TypingBubble.stories.tsx
new file mode 100644
index 000000000..0ba000471
--- /dev/null
+++ b/ts/components/conversation/TypingBubble.stories.tsx
@@ -0,0 +1,45 @@
+import * as React from 'react';
+import { storiesOf } from '@storybook/react';
+import { select, text } from '@storybook/addon-knobs';
+
+// @ts-ignore
+import { setup as setupI18n } from '../../../js/modules/i18n';
+
+// @ts-ignore
+import enMessages from '../../../_locales/en/messages.json';
+
+import { Props, TypingBubble } from './TypingBubble';
+import { Colors } from '../../types/Colors';
+
+const i18n = setupI18n('en', enMessages);
+
+const story = storiesOf('Components/Conversation/TypingBubble', module);
+
+const createProps = (overrideProps: Partial = {}): Props => ({
+ i18n,
+ color: select(
+ 'color',
+ Colors.reduce((m, c) => ({ ...m, [c]: c }), {}),
+ overrideProps.color || 'red'
+ ),
+ avatarPath: text('avatarPath', overrideProps.avatarPath || ''),
+ title: '',
+ profileName: text('profileName', overrideProps.profileName || ''),
+ conversationType: select(
+ 'conversationType',
+ { group: 'group', direct: 'direct' },
+ overrideProps.conversationType || 'direct'
+ ),
+});
+
+story.add('Direct', () => {
+ const props = createProps();
+
+ return ;
+});
+
+story.add('Group', () => {
+ const props = createProps({ conversationType: 'group' });
+
+ return ;
+});
diff --git a/ts/components/conversation/TypingBubble.tsx b/ts/components/conversation/TypingBubble.tsx
index 5988afeec..70919eef6 100644
--- a/ts/components/conversation/TypingBubble.tsx
+++ b/ts/components/conversation/TypingBubble.tsx
@@ -7,7 +7,7 @@ import { Avatar } from '../Avatar';
import { LocalizerType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
-interface Props {
+export interface Props {
avatarPath?: string;
color: ColorType;
name?: string;
diff --git a/ts/components/conversation/UnsupportedMessage.md b/ts/components/conversation/UnsupportedMessage.md
deleted file mode 100644
index 2d7bac27a..000000000
--- a/ts/components/conversation/UnsupportedMessage.md
+++ /dev/null
@@ -1,69 +0,0 @@
-### From someone in your contacts
-
-```jsx
-
- console.log('downloadNewVersion')}
- />
-
-```
-
-### After you upgrade
-
-```jsx
-
- console.log('downloadNewVersion')}
- />
-
-```
-
-### No name, just profile
-
-```jsx
-
- console.log('downloadNewVersion')}
- />
-
-```
-
-### From yourself
-
-```jsx
-
- console.log('downloadNewVersion')}
- />
-
-```
-
-### From yourself, after you upgrade
-
-```jsx
-
- console.log('downloadNewVersion')}
- />
-
-```
diff --git a/ts/components/conversation/UnsupportedMessage.stories.tsx b/ts/components/conversation/UnsupportedMessage.stories.tsx
new file mode 100644
index 000000000..493bfb312
--- /dev/null
+++ b/ts/components/conversation/UnsupportedMessage.stories.tsx
@@ -0,0 +1,75 @@
+import * as React from 'react';
+import { storiesOf } from '@storybook/react';
+import { boolean, 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 { ContactType, Props, UnsupportedMessage } from './UnsupportedMessage';
+
+const i18n = setupI18n('en', enMessages);
+
+const story = storiesOf('Components/Conversation/UnsupportedMessage', module);
+
+const createContact = (props: Partial = {}): ContactType => ({
+ id: '',
+ title: text('contact title', props.title || ''),
+ isMe: boolean('contact isMe', props.isMe || false),
+});
+
+const createProps = (overrideProps: Partial = {}): Props => ({
+ i18n,
+ canProcessNow: boolean('canProcessNow', overrideProps.canProcessNow || false),
+ contact: overrideProps.contact || ({} as ContactType),
+ downloadNewVersion: action('downloadNewVersion'),
+});
+
+story.add('From Someone', () => {
+ const contact = createContact({
+ title: 'Alice',
+ name: 'Alice',
+ });
+
+ const props = createProps({ contact });
+
+ return ;
+});
+
+story.add('After Upgrade', () => {
+ const contact = createContact({
+ title: 'Alice',
+ name: 'Alice',
+ });
+
+ const props = createProps({ contact, canProcessNow: true });
+
+ return ;
+});
+
+story.add('From Yourself', () => {
+ const contact = createContact({
+ title: 'Alice',
+ name: 'Alice',
+ isMe: true,
+ });
+
+ const props = createProps({ contact });
+
+ return ;
+});
+
+story.add('From Yourself After Upgrade', () => {
+ const contact = createContact({
+ title: 'Alice',
+ name: 'Alice',
+ isMe: true,
+ });
+
+ const props = createProps({ contact, canProcessNow: true });
+
+ return ;
+});
diff --git a/ts/components/conversation/UnsupportedMessage.tsx b/ts/components/conversation/UnsupportedMessage.tsx
index 15f4d9fb5..72f0c3fe5 100644
--- a/ts/components/conversation/UnsupportedMessage.tsx
+++ b/ts/components/conversation/UnsupportedMessage.tsx
@@ -5,7 +5,7 @@ import { ContactName } from './ContactName';
import { Intl } from '../Intl';
import { LocalizerType } from '../../types/Util';
-interface ContactType {
+export interface ContactType {
id: string;
phoneNumber?: string;
profileName?: string;
@@ -27,7 +27,7 @@ type PropsHousekeeping = {
i18n: LocalizerType;
};
-type Props = PropsData & PropsHousekeeping & PropsActions;
+export type Props = PropsData & PropsHousekeeping & PropsActions;
export class UnsupportedMessage extends React.Component {
public render() {
diff --git a/ts/components/conversation/VerificationNotification.md b/ts/components/conversation/VerificationNotification.md
deleted file mode 100644
index 82818f0ee..000000000
--- a/ts/components/conversation/VerificationNotification.md
+++ /dev/null
@@ -1,49 +0,0 @@
-### Marking as verified
-
-```js
-
-
-
-
-```
-
-### Marking as not verified
-
-```js
-
-
-
-
-```
diff --git a/ts/components/conversation/VerificationNotification.stories.tsx b/ts/components/conversation/VerificationNotification.stories.tsx
new file mode 100644
index 000000000..d62ff43d6
--- /dev/null
+++ b/ts/components/conversation/VerificationNotification.stories.tsx
@@ -0,0 +1,55 @@
+import * as React from 'react';
+import { storiesOf } from '@storybook/react';
+
+// @ts-ignore
+import { setup as setupI18n } from '../../../js/modules/i18n';
+
+// @ts-ignore
+import enMessages from '../../../_locales/en/messages.json';
+
+import { Props, VerificationNotification } from './VerificationNotification';
+import { boolean } from '@storybook/addon-knobs';
+
+const i18n = setupI18n('en', enMessages);
+
+const story = storiesOf(
+ 'Components/Conversation/VerificationNotification',
+ module
+);
+
+const contact = {
+ title: 'Mr. Fire',
+ phoneNumber: '(202) 555-0003',
+ profileName: 'Mr. Fire',
+};
+
+const createProps = (overrideProps: Partial = {}): Props => ({
+ i18n,
+ type: overrideProps.type || 'markVerified',
+ isLocal: boolean('isLocal', overrideProps.isLocal !== false),
+ contact,
+});
+
+story.add('Mark as Verified', () => {
+ const props = createProps({ type: 'markVerified' });
+
+ return ;
+});
+
+story.add('Mark as Not Verified', () => {
+ const props = createProps({ type: 'markNotVerified' });
+
+ return ;
+});
+
+story.add('Mark as Verified Remotely', () => {
+ const props = createProps({ type: 'markVerified', isLocal: false });
+
+ return ;
+});
+
+story.add('Mark as Not Verified Remotely', () => {
+ const props = createProps({ type: 'markNotVerified', isLocal: false });
+
+ return ;
+});
diff --git a/ts/components/conversation/VerificationNotification.tsx b/ts/components/conversation/VerificationNotification.tsx
index ab4081433..f04a1e8df 100644
--- a/ts/components/conversation/VerificationNotification.tsx
+++ b/ts/components/conversation/VerificationNotification.tsx
@@ -24,7 +24,7 @@ type PropsHousekeeping = {
i18n: LocalizerType;
};
-type Props = PropsData & PropsHousekeeping;
+export type Props = PropsData & PropsHousekeeping;
export class VerificationNotification extends React.Component {
public getStringId() {