diff --git a/ts/components/conversation/ExpireTimer.md b/ts/components/conversation/ExpireTimer.md
deleted file mode 100644
index 3ec7a4439..000000000
--- a/ts/components/conversation/ExpireTimer.md
+++ /dev/null
@@ -1,222 +0,0 @@
-### Countdown at different rates
-
-```jsx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### Timer calculations
-
-```jsx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
diff --git a/ts/components/conversation/ExpireTimer.stories.tsx b/ts/components/conversation/ExpireTimer.stories.tsx
new file mode 100644
index 000000000..0a7c478e3
--- /dev/null
+++ b/ts/components/conversation/ExpireTimer.stories.tsx
@@ -0,0 +1,109 @@
+import * as React from 'react';
+
+import { boolean, number } from '@storybook/addon-knobs';
+import { storiesOf } from '@storybook/react';
+
+import { ExpireTimer, Props } from './ExpireTimer';
+
+const story = storiesOf('Components/Conversation/ExpireTimer', module);
+
+const createProps = (overrideProps: Partial = {}): Props => ({
+ direction: overrideProps.direction || 'outgoing',
+ expirationLength: number(
+ 'expirationLength',
+ overrideProps.expirationLength || 30 * 1000
+ ),
+ expirationTimestamp: number(
+ 'expirationTimestamp',
+ overrideProps.expirationTimestamp || Date.now() + 30 * 1000
+ ),
+ withImageNoCaption: boolean(
+ 'withImageNoCaption',
+ overrideProps.withImageNoCaption || false
+ ),
+ withSticker: boolean('withSticker', overrideProps.withSticker || false),
+ withTapToViewExpired: boolean(
+ 'withTapToViewExpired',
+ overrideProps.withTapToViewExpired || false
+ ),
+});
+
+story.add('30 seconds', () => {
+ const props = createProps();
+
+ return ;
+});
+
+story.add('2 minutes', () => {
+ const twoMinutes = 60 * 1000 * 2;
+ const props = createProps({
+ expirationTimestamp: Date.now() + twoMinutes,
+ expirationLength: twoMinutes,
+ });
+
+ return ;
+});
+
+story.add('In Progress', () => {
+ const props = createProps({
+ expirationTimestamp: Date.now() + 15 * 1000,
+ });
+
+ return ;
+});
+
+story.add('Expired', () => {
+ const props = createProps({
+ expirationTimestamp: Date.now() - 30 * 1000,
+ });
+
+ return ;
+});
+
+story.add('Sticker', () => {
+ const props = createProps({
+ withSticker: true,
+ });
+
+ return ;
+});
+
+story.add('Tap To View Expired', () => {
+ const props = createProps({
+ withTapToViewExpired: true,
+ });
+
+ return ;
+});
+
+story.add('Image No Caption', () => {
+ const props = createProps({
+ withImageNoCaption: true,
+ });
+
+ return (
+
+
+
+ );
+});
+
+story.add('Incoming', () => {
+ const props = createProps({
+ direction: 'incoming',
+ });
+
+ return (
+
+
+
+ );
+});
+
+story.add('Expiration Too Far Out', () => {
+ const props = createProps({
+ expirationTimestamp: Date.now() + 150 * 1000,
+ });
+
+ return ;
+});
diff --git a/ts/components/conversation/ExpireTimer.tsx b/ts/components/conversation/ExpireTimer.tsx
index bc75d6671..013445232 100644
--- a/ts/components/conversation/ExpireTimer.tsx
+++ b/ts/components/conversation/ExpireTimer.tsx
@@ -3,7 +3,7 @@ import classNames from 'classnames';
import { getIncrement, getTimerBucket } from '../../util/timer';
-interface Props {
+export interface Props {
withImageNoCaption?: boolean;
withSticker?: boolean;
withTapToViewExpired?: boolean;