aboutsummaryrefslogtreecommitdiffstats
path: root/uidev
diff options
context:
space:
mode:
Diffstat (limited to 'uidev')
-rw-r--r--uidev/src/app.html12
-rw-r--r--uidev/src/app.tsx125
-rw-r--r--uidev/src/index.tsx9
-rw-r--r--uidev/src/stores/index.ts5
-rw-r--r--uidev/src/stores/stories.ts43
-rw-r--r--uidev/src/stories/badge.stories.tsx21
-rw-r--r--uidev/src/stories/button.stories.tsx97
-rw-r--r--uidev/src/stories/headline.stories.tsx54
-rw-r--r--uidev/src/stories/icon.stories.tsx53
-rw-r--r--uidev/src/stories/infobox.stories.tsx126
-rw-r--r--uidev/src/stories/input.stories.tsx97
-rw-r--r--uidev/src/stories/loader.stories.tsx14
-rw-r--r--uidev/src/stories/select.stories.tsx320
-rw-r--r--uidev/src/stories/toggle.stories.tsx70
-rw-r--r--uidev/src/withTheme/index.tsx50
-rw-r--r--uidev/tsconfig.json14
-rw-r--r--uidev/tslint.json3
-rw-r--r--uidev/webpack.config.js29
18 files changed, 1142 insertions, 0 deletions
diff --git a/uidev/src/app.html b/uidev/src/app.html
new file mode 100644
index 000000000..2557bf25e
--- /dev/null
+++ b/uidev/src/app.html
@@ -0,0 +1,12 @@
1<!DOCTYPE html>
2<html>
3
4<head>
5 <title>UIDev</title>
6 <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,800" rel="stylesheet">
7</head>
8
9<body>
10 <div id="root"></div>
11</body>
12</html>
diff --git a/uidev/src/app.tsx b/uidev/src/app.tsx
new file mode 100644
index 000000000..870911c2f
--- /dev/null
+++ b/uidev/src/app.tsx
@@ -0,0 +1,125 @@
1import CSS from 'csstype';
2import { Classes } from 'jss';
3import { observer } from 'mobx-react';
4import DevTools from 'mobx-react-devtools';
5import React, { Component } from 'react';
6import injectSheet from 'react-jss';
7
8import { WithTheme } from './withTheme';
9
10import './stories/badge.stories';
11import './stories/button.stories';
12import './stories/headline.stories';
13import './stories/icon.stories';
14import './stories/infobox.stories';
15import './stories/input.stories';
16import './stories/loader.stories';
17import './stories/select.stories';
18import './stories/toggle.stories';
19
20import { store } from './stores';
21
22import { theme, ThemeType } from '@meetfranz/theme';
23const defaultTheme = theme(ThemeType.default);
24
25const styles = {
26 '@global body': {
27 margin: 0,
28 fontSize: defaultTheme.uiFontSize,
29 fontFamily: '\'Open Sans\', sans-serif',
30 },
31 container: {
32 display: 'flex',
33 width: '100%',
34 },
35 menu: {
36 width: 300,
37 position: 'fixed' as CSS.PositionProperty,
38 listStyleType: 'none',
39 fontSize: 14,
40 overflow: 'scroll',
41 height: '100%',
42 },
43 storyList: {
44 paddingLeft: 18,
45 marginTop: 5,
46 marginBottom: 20,
47 },
48 stories: {
49 width: '100%',
50 marginLeft: 320,
51 paddingLeft: 40,
52 paddingRight: 40,
53 borderLeft: '1px solid #CFCFCF',
54 background: '#f7f7f7',
55 },
56 sectionHeadline: {
57 fontSize: 30,
58 },
59 storyHeadline: {
60 fontSize: 24,
61 },
62 story: {
63 paddingBottom: 40,
64 marginBottom: 40,
65 borderBottom: '1px solid #CFCFCF',
66 },
67 sectionLink: {
68 fontWeight: 'bold' as CSS.FontWeightProperty,
69 color: '#000',
70 textDecoration: 'none',
71 },
72 storyLink: {
73 color: '#000',
74 textDecoration: 'none',
75 },
76};
77
78export const App = injectSheet(styles)(observer(({ classes }: { classes: Classes }) => (
79 <div className={classes.container}>
80 <ul className={classes.menu}>
81 {store.stories.sections.map((section, key) => (
82 <li key={key}>
83 <a href={`#section-${key}`} className={classes.sectionLink}>{
84 section.name}
85 </a>
86 <ul className={classes.storyList}>
87 {section.stories.map((story, storyKey) => (
88 <li key={storyKey}>
89 <a href={`#section-${key}-story-${storyKey}`} className={classes.storyLink}>
90 {story.name}
91 </a>
92 </li>
93 ))}
94 </ul>
95 </li>
96 ))}
97 </ul>
98 <div className={classes.stories}>
99 {store.stories.sections.map((section, key) => (
100 <div key={key}>
101 <h1
102 id={`section-${key}`}
103 className={classes.sectionHeadline}
104 >
105 {section.name}
106 </h1>
107 {section.stories.map((story, storyKey) => (
108 <div className={classes.story} key={storyKey}>
109 <h2
110 id={`section-${key}-story-${storyKey}`}
111 className={classes.storyHeadline}
112 >
113 {story.name}
114 </h2>
115 <WithTheme>
116 <story.component />
117 </WithTheme>
118 </div>
119 ))}
120 </div>
121 ))}
122 </div>
123 <DevTools />
124 </div>
125)));
diff --git a/uidev/src/index.tsx b/uidev/src/index.tsx
new file mode 100644
index 000000000..99658b184
--- /dev/null
+++ b/uidev/src/index.tsx
@@ -0,0 +1,9 @@
1import React from 'react';
2import { render } from 'react-dom';
3import { App } from './app';
4
5const app = () => (
6 <App />
7);
8
9render(app(), document.getElementById('root'));
diff --git a/uidev/src/stores/index.ts b/uidev/src/stores/index.ts
new file mode 100644
index 000000000..276058ec4
--- /dev/null
+++ b/uidev/src/stores/index.ts
@@ -0,0 +1,5 @@
1import { storyStore } from './stories';
2
3export const store = {
4 stories: storyStore,
5};
diff --git a/uidev/src/stores/stories.ts b/uidev/src/stores/stories.ts
new file mode 100644
index 000000000..6a98c9fd3
--- /dev/null
+++ b/uidev/src/stores/stories.ts
@@ -0,0 +1,43 @@
1import { store } from './index';
2
3export type StorySectionName = string;
4export type StoryName = string;
5export type StoryComponent = () => JSX.Element;
6
7export interface IStories {
8 name: string;
9 component: StoryComponent;
10}
11
12export interface ISections {
13 name: StorySectionName;
14 stories: IStories[];
15}
16
17export interface IStoryStore {
18 sections: ISections[];
19}
20
21export const storyStore: IStoryStore = {
22 sections: [],
23};
24
25export const storiesOf = (name: StorySectionName) => {
26 const length = storyStore.sections.push({
27 name,
28 stories: [],
29 });
30
31 const actions = {
32 add: (name: StoryName, component: StoryComponent) => {
33 storyStore.sections[length - 1].stories.push({
34 name,
35 component,
36 });
37
38 return actions;
39 },
40 };
41
42 return actions;
43};
diff --git a/uidev/src/stories/badge.stories.tsx b/uidev/src/stories/badge.stories.tsx
new file mode 100644
index 000000000..6de2034bf
--- /dev/null
+++ b/uidev/src/stories/badge.stories.tsx
@@ -0,0 +1,21 @@
1import React from 'react';
2
3import { Badge } from '@meetfranz/ui';
4import { storiesOf } from '../stores/stories';
5
6storiesOf('Badge')
7 .add('Basic', () => (
8 <>
9 <Badge>New</Badge>
10 </>
11 ))
12 .add('Styles', () => (
13 <>
14 <Badge type="primary">Primary</Badge>
15 <Badge type="secondary">secondary</Badge>
16 <Badge type="success">success</Badge>
17 <Badge type="warning">warning</Badge>
18 <Badge type="danger">danger</Badge>
19 <Badge type="inverted">inverted</Badge>
20 </>
21 ));
diff --git a/uidev/src/stories/button.stories.tsx b/uidev/src/stories/button.stories.tsx
new file mode 100644
index 000000000..d81808530
--- /dev/null
+++ b/uidev/src/stories/button.stories.tsx
@@ -0,0 +1,97 @@
1import { observable } from 'mobx';
2import { observer } from 'mobx-react';
3import React from 'react';
4
5import { Button } from '@meetfranz/forms';
6import { storiesOf } from '../stores/stories';
7
8const defaultProps = {
9 label: 'Button',
10 id: 'test1',
11 name: 'test1',
12 type: 'button',
13 disabled: false,
14};
15
16const createStore = (args?: any) => {
17 return observable(Object.assign({}, defaultProps, args));
18};
19
20const WithStoreButton = observer(({ store }: { store: any }) => (
21 <>
22 <Button
23 {...Object.assign({}, defaultProps, store)}
24 onClick={!store.onClick ? () => {
25 store.busy = !store.busy;
26
27 window.setTimeout(() => {
28 store.busy = !store.busy;
29 }, 1000);
30 } : store.onClick}
31 />
32 </>
33));
34
35storiesOf('Button')
36 .add('Basic', () => (
37 <WithStoreButton store={createStore()} />
38 ))
39 .add('Secondary', () => (
40 <WithStoreButton store={createStore({
41 buttonType: 'secondary',
42 })} />
43 ))
44 .add('Success', () => (
45 <WithStoreButton store={createStore({
46 buttonType: 'success',
47 })} />
48 ))
49 .add('Warning', () => (
50 <WithStoreButton store={createStore({
51 buttonType: 'warning',
52 })} />
53 ))
54 .add('Danger', () => (
55 <WithStoreButton store={createStore({
56 buttonType: 'danger',
57 })} />
58 ))
59 .add('Inverted', () => (
60 <WithStoreButton store={createStore({
61 buttonType: 'inverted',
62 })} />
63 ))
64 .add('Full width', () => (
65 <WithStoreButton store={createStore({
66 stretch: true,
67 })} />
68 ))
69 .add('Disabled', () => (
70 <WithStoreButton store={createStore({
71 disabled: true,
72 })} />
73 ))
74 .add('With loader', () => (
75 <WithStoreButton store={createStore({
76 busy: true,
77 })} />
78 ))
79 .add('As link', () => (
80 <WithStoreButton store={createStore({
81 href: 'https://meetfranz.com',
82 })} />
83 ))
84 .add('As link (target=_blank)', () => (
85 <WithStoreButton store={createStore({
86 href: 'https://meetfranz.com',
87 target: '_blank',
88 })} />
89 ))
90 .add('As link (with onClick)', () => (
91 <WithStoreButton store={createStore({
92 href: 'https://meetfranz.com',
93 onClick: (e: React.MouseEvent<HTMLAnchorElement>) => {
94 e.preventDefault();
95 alert('Click event');
96 },
97 })} />));
diff --git a/uidev/src/stories/headline.stories.tsx b/uidev/src/stories/headline.stories.tsx
new file mode 100644
index 000000000..f42771cae
--- /dev/null
+++ b/uidev/src/stories/headline.stories.tsx
@@ -0,0 +1,54 @@
1import { observable } from 'mobx';
2import { observer } from 'mobx-react';
3import React from 'react';
4import uuid from 'uuid/v4';
5
6import { H1, H2, H3, H4 } from '@meetfranz/ui';
7import { storiesOf } from '../stores/stories';
8
9// interface IStoreArgs {
10// value?: boolean;
11// checked?: boolean;
12// label?: string;
13// id?: string;
14// name?: string;
15// disabled?: boolean;
16// error?: string;
17// }
18
19// const createStore = (args?: IStoreArgs) => {
20// return observable(Object.assign({
21// id: `element-${uuid()}`,
22// name: 'toggle',
23// label: 'Label',
24// value: true,
25// checked: false,
26// disabled: false,
27// error: '',
28// }, args));
29// };
30
31// const WithStoreToggle = observer(({ store }: { store: any }) => (
32// <>
33// <Toggle
34// value={store.value}
35// checked={store.checked}
36// label={store.label}
37// id={store.id}
38// name={store.name}
39// disabled={store.disabled}
40// error={store.error}
41// onChange={() => store.checked = !store.checked}
42// />
43// </>
44// ));
45
46storiesOf('Typo')
47 .add('Headlines', () => (
48 <>
49 <H1>Welcome to the world of tomorrow</H1>
50 <H2>Welcome to the world of tomorrow</H2>
51 <H3>Welcome to the world of tomorrow</H3>
52 <H4>Welcome to the world of tomorrow</H4>
53 </>
54 ));
diff --git a/uidev/src/stories/icon.stories.tsx b/uidev/src/stories/icon.stories.tsx
new file mode 100644
index 000000000..c8e7f8ced
--- /dev/null
+++ b/uidev/src/stories/icon.stories.tsx
@@ -0,0 +1,53 @@
1import { observable } from 'mobx';
2import { observer } from 'mobx-react';
3import React from 'react';
4import uuid from 'uuid/v4';
5
6import { Icon } from '@meetfranz/ui';
7import { storiesOf } from '../stores/stories';
8
9// interface IStoreArgs {
10// value?: boolean;
11// checked?: boolean;
12// label?: string;
13// id?: string;
14// name?: string;
15// disabled?: boolean;
16// error?: string;
17// }
18
19// const createStore = (args?: IStoreArgs) => {
20// return observable(Object.assign({
21// id: `element-${uuid()}`,
22// name: 'toggle',
23// label: 'Label',
24// value: true,
25// checked: false,
26// disabled: false,
27// error: '',
28// }, args));
29// };
30
31// const WithStoreToggle = observer(({ store }: { store: any }) => (
32// <>
33// <Toggle
34// value={store.value}
35// checked={store.checked}
36// label={store.label}
37// id={store.id}
38// name={store.name}
39// disabled={store.disabled}
40// error={store.error}
41// onChange={() => store.checked = !store.checked}
42// />
43// </>
44// ));
45
46storiesOf('Icon')
47 .add('Basic', () => (
48 <>
49 <Icon icon="mdiAccountCircle" />
50 <Icon icon="mdiAccountCircle" size={2} />
51 <Icon icon="mdiAccountCircle" size={3} />
52 </>
53 ));
diff --git a/uidev/src/stories/infobox.stories.tsx b/uidev/src/stories/infobox.stories.tsx
new file mode 100644
index 000000000..2a5e8b0d5
--- /dev/null
+++ b/uidev/src/stories/infobox.stories.tsx
@@ -0,0 +1,126 @@
1import { observable } from 'mobx';
2import { observer } from 'mobx-react';
3import React from 'react';
4
5import { Infobox } from '@meetfranz/ui';
6import { storiesOf } from '../stores/stories';
7
8interface IStoreArgs {
9 icon?: string;
10 ctaLabel?: string;
11 type?: string;
12 dismissable?: boolean;
13}
14
15const createStore = (args?: IStoreArgs) => {
16 return observable(Object.assign({
17 type: 'primary',
18 ctaOnClick: () => {
19 alert('on click handler');
20 },
21 }, args));
22};
23
24const WithStoreInfobox = observer(({ store, children }: { store: any, children: string | React.ReactNode }) => (
25 <>
26 <Infobox
27 icon={store.icon}
28 ctaLabel={store.ctaLabel}
29 type={store.type}
30 ctaOnClick={store.ctaOnClick}
31 dismissable={store.dismissable}
32 >
33 {children}
34 </Infobox>
35 </>
36));
37
38storiesOf('Infobox')
39 .add('Basic', () => (
40 <WithStoreInfobox store={createStore()}>Welcome to the world of tomorrow</WithStoreInfobox>
41 ))
42 .add('Icon + Dismissable', () => (
43 <WithStoreInfobox
44 store={createStore({
45 icon: 'mdiEarth',
46 dismissable: true,
47 })}
48 >
49 Welcome to the world of tomorrow
50 </WithStoreInfobox>
51 ))
52 .add('With CTA', () => (
53 <WithStoreInfobox
54 store={createStore({
55 icon: 'mdiEarth',
56 ctaLabel: 'Ok, hi!',
57 })}
58 >
59 Welcome to the world of tomorrow
60 </WithStoreInfobox>
61 ))
62 .add('With long text', () => (
63 <WithStoreInfobox
64 store={createStore({
65 icon: 'mdiEarth',
66 ctaLabel: 'Ok, hi!',
67 })}
68 >
69 Franz is your messaging app / former Emperor of Austria and combines chat & messaging services into one application. Franz currently supports Slack, WhatsApp, WeChat, HipChat, Facebook Messenger, Telegram, Google Hangouts,GroupMe, Skype and many more.
70 </WithStoreInfobox>
71 ))
72 .add('Secondary', () => (
73 <WithStoreInfobox
74 store={createStore({
75 icon: 'mdiEarth',
76 ctaLabel: 'Ok, hi!',
77 type: 'secondary',
78 })}
79 >
80 Welcome to the world of tomorrow
81 </WithStoreInfobox>
82 ))
83 .add('Success', () => (
84 <WithStoreInfobox
85 store={createStore({
86 icon: 'mdiEarth',
87 ctaLabel: 'Ok, hi!',
88 type: 'success',
89 })}
90 >
91 Welcome to the world of tomorrow
92 </WithStoreInfobox>
93 ))
94 .add('Warning', () => (
95 <WithStoreInfobox
96 store={createStore({
97 icon: 'mdiEarth',
98 ctaLabel: 'Ok, hi!',
99 type: 'warning',
100 })}
101 >
102 Welcome to the world of tomorrow
103 </WithStoreInfobox>
104 ))
105 .add('Danger', () => (
106 <WithStoreInfobox
107 store={createStore({
108 icon: 'mdiEarth',
109 ctaLabel: 'Ok, hi!',
110 type: 'danger',
111 })}
112 >
113 Welcome to the world of tomorrow
114 </WithStoreInfobox>
115 ))
116 .add('Inverted', () => (
117 <WithStoreInfobox
118 store={createStore({
119 icon: 'mdiEarth',
120 ctaLabel: 'Ok, hi!',
121 type: 'inverted',
122 })}
123 >
124 Welcome to the world of tomorrow
125 </WithStoreInfobox>
126 ));
diff --git a/uidev/src/stories/input.stories.tsx b/uidev/src/stories/input.stories.tsx
new file mode 100644
index 000000000..c522a10c7
--- /dev/null
+++ b/uidev/src/stories/input.stories.tsx
@@ -0,0 +1,97 @@
1import React from 'react';
2import uuid from 'uuid/v4';
3
4import { Input } from '@meetfranz/forms';
5import { storiesOf } from '../stores/stories';
6
7const defaultProps = () => {
8 const id = uuid();
9 return {
10 label: 'Label',
11 id: `test-${id}`,
12 name: `test-${id}`,
13 onChange: (e: React.ChangeEvent<HTMLInputElement>) => console.log('changed event', e),
14 };
15};
16
17const defaultPasswordProps = () => {
18 const id = uuid();
19 return {
20 label: 'Password',
21 id: `test-${id}`,
22 name: `test-${id}`,
23 type: 'password',
24 onChange: (e: React.ChangeEvent<HTMLInputElement>) => console.log('changed event', e),
25 };
26};
27
28storiesOf('Input')
29 .add('Basic', () => (
30 <Input
31 {...defaultProps()}
32 placeholder="Placeholder text"
33 />
34 ))
35 .add('Without Label', () => (
36 <Input
37 {...defaultProps()}
38 showLabel={false}
39 />
40 ))
41 .add('Disabled', () => (
42 <Input {...defaultProps()} disabled />
43 ))
44 .add('With prefix', () => (
45 <Input
46 {...defaultProps()}
47 prefix="https://"
48 />
49 ))
50 .add('With suffix', () => (
51 <Input
52 {...defaultProps()}
53 suffix=".meetfranz.com"
54 />
55 ))
56 .add('With pre-suffix', () => (
57 <Input
58 {...defaultProps()}
59 prefix="https://"
60 suffix=".meetfranz.com"
61 />
62 ))
63 .add('With error', () => (
64 <Input
65 {...defaultProps()}
66 value="faulty input"
67 error="This is a generic error message."
68 />
69 ));
70
71storiesOf('Password')
72 .add('Basic', () => (
73 <Input
74 {...defaultPasswordProps()}
75 />
76 ))
77 .add('Show password toggle', () => (
78 <Input
79 {...defaultPasswordProps()}
80 showPasswordToggle
81 />
82 ))
83 .add('Score password', () => (
84 <Input
85 {...defaultPasswordProps()}
86 showPasswordToggle
87 scorePassword
88 />
89 ))
90 .add('Score password with error', () => (
91 <Input
92 {...defaultPasswordProps()}
93 error="Password is too short"
94 showPasswordToggle
95 scorePassword
96 />
97 ));
diff --git a/uidev/src/stories/loader.stories.tsx b/uidev/src/stories/loader.stories.tsx
new file mode 100644
index 000000000..84e813c04
--- /dev/null
+++ b/uidev/src/stories/loader.stories.tsx
@@ -0,0 +1,14 @@
1import { observable } from 'mobx';
2import { observer } from 'mobx-react';
3import React from 'react';
4import uuid from 'uuid/v4';
5
6import { Loader } from '@meetfranz/ui';
7import { storiesOf } from '../stores/stories';
8
9storiesOf('Loader')
10 .add('Basic', () => (
11 <>
12 <Loader />
13 </>
14 ));
diff --git a/uidev/src/stories/select.stories.tsx b/uidev/src/stories/select.stories.tsx
new file mode 100644
index 000000000..81f7f08a6
--- /dev/null
+++ b/uidev/src/stories/select.stories.tsx
@@ -0,0 +1,320 @@
1import React from 'react';
2import uuid from 'uuid/v4';
3
4import { Select } from '@meetfranz/forms';
5import { storiesOf } from '../stores/stories';
6
7const defaultProps = () => {
8 const id = uuid();
9 return {
10 label: 'Label',
11 id: `test-${id}`,
12 name: `test-${id}`,
13 options: {
14 AF: 'Afghanistan',
15 AL: 'Albania',
16 DZ: 'Algeria',
17 AS: 'American Samoa',
18 AD: 'Andorra',
19 AO: 'Angola',
20 AI: 'Anguilla',
21 AQ: 'Antarctica',
22 AG: 'Antigua and Barbuda',
23 AR: 'Argentina',
24 AM: 'Armenia',
25 AW: 'Aruba',
26 AC: 'Ascension Island',
27 AU: 'Australia',
28 AT: 'Austria',
29 AZ: 'Azerbaijan',
30 BS: 'Bahamas',
31 BH: 'Bahrain',
32 BD: 'Bangladesh',
33 BB: 'Barbados',
34 BY: 'Belarus',
35 BE: 'Belgium',
36 BZ: 'Belize',
37 BJ: 'Benin',
38 BM: 'Bermuda',
39 BT: 'Bhutan',
40 BO: 'Bolivia',
41 BA: 'Bosnia and Herzegovina',
42 BW: 'Botswana',
43 BV: 'Bouvet Island',
44 BR: 'Brazil',
45 BQ: 'British Antarctic Territory',
46 IO: 'British Indian Ocean Territory',
47 VG: 'British Virgin Islands',
48 BN: 'Brunei',
49 BG: 'Bulgaria',
50 BF: 'Burkina Faso',
51 BI: 'Burundi',
52 KH: 'Cambodia',
53 CM: 'Cameroon',
54 CA: 'Canada',
55 IC: 'Canary Islands',
56 CT: 'Canton and Enderbury Islands',
57 CV: 'Cape Verde',
58 KY: 'Cayman Islands',
59 CF: 'Central African Republic',
60 EA: 'Ceuta and Melilla',
61 TD: 'Chad',
62 CL: 'Chile',
63 CN: 'China',
64 CX: 'Christmas Island',
65 CP: 'Clipperton Island',
66 CC: 'Cocos [Keeling] Islands',
67 CO: 'Colombia',
68 KM: 'Comoros',
69 CD: 'Congo - Kinshasa',
70 CG: 'Congo [Republic]',
71 CK: 'Cook Islands',
72 CR: 'Costa Rica',
73 HR: 'Croatia',
74 CU: 'Cuba',
75 CY: 'Cyprus',
76 CZ: 'Czech Republic',
77 CI: 'Côte d’Ivoire',
78 DK: 'Denmark',
79 DG: 'Diego Garcia',
80 DJ: 'Djibouti',
81 DM: 'Dominica',
82 DO: 'Dominican Republic',
83 NQ: 'Dronning Maud Land',
84 TL: 'East Timor',
85 EC: 'Ecuador',
86 EG: 'Egypt',
87 SV: 'El Salvador',
88 GQ: 'Equatorial Guinea',
89 ER: 'Eritrea',
90 EE: 'Estonia',
91 ET: 'Ethiopia',
92 FK: 'Falkland Islands',
93 FO: 'Faroe Islands',
94 FJ: 'Fiji',
95 FI: 'Finland',
96 FR: 'France',
97 GF: 'French Guiana',
98 PF: 'French Polynesia',
99 TF: 'French Southern Territories',
100 FQ: 'French Southern and Antarctic Territories',
101 GA: 'Gabon',
102 GM: 'Gambia',
103 GE: 'Georgia',
104 DE: 'Germany',
105 GH: 'Ghana',
106 GI: 'Gibraltar',
107 GR: 'Greece',
108 GL: 'Greenland',
109 GD: 'Grenada',
110 GP: 'Guadeloupe',
111 GU: 'Guam',
112 GT: 'Guatemala',
113 GG: 'Guernsey',
114 GN: 'Guinea',
115 GW: 'Guinea-Bissau',
116 GY: 'Guyana',
117 HT: 'Haiti',
118 HM: 'Heard Island and McDonald Islands',
119 HN: 'Honduras',
120 HK: 'Hong Kong',
121 HU: 'Hungary',
122 IS: 'Iceland',
123 IN: 'India',
124 ID: 'Indonesia',
125 IR: 'Iran',
126 IQ: 'Iraq',
127 IE: 'Ireland',
128 IM: 'Isle of Man',
129 IL: 'Israel',
130 IT: 'Italy',
131 JM: 'Jamaica',
132 JP: 'Japan',
133 JE: 'Jersey',
134 JT: 'Johnston Island',
135 JO: 'Jordan',
136 KZ: 'Kazakhstan',
137 KE: 'Kenya',
138 KI: 'Kiribati',
139 XK: 'Kosovo',
140 KW: 'Kuwait',
141 KG: 'Kyrgyzstan',
142 LA: 'Laos',
143 LV: 'Latvia',
144 LB: 'Lebanon',
145 LS: 'Lesotho',
146 LR: 'Liberia',
147 LY: 'Libya',
148 LI: 'Liechtenstein',
149 LT: 'Lithuania',
150 LU: 'Luxembourg',
151 MO: 'Macau',
152 MK: 'Macedonia',
153 MG: 'Madagascar',
154 MW: 'Malawi',
155 MY: 'Malaysia',
156 MV: 'Maldives',
157 ML: 'Mali',
158 MT: 'Malta',
159 MH: 'Marshall Islands',
160 MQ: 'Martinique',
161 MR: 'Mauritania',
162 MU: 'Mauritius',
163 YT: 'Mayotte',
164 FX: 'Metropolitan France',
165 MX: 'Mexico',
166 FM: 'Micronesia',
167 MI: 'Midway Islands',
168 MD: 'Moldova',
169 MC: 'Monaco',
170 MN: 'Mongolia',
171 ME: 'Montenegro',
172 MS: 'Montserrat',
173 MA: 'Morocco',
174 MZ: 'Mozambique',
175 MM: 'Myanmar [Burma]',
176 NA: 'Namibia',
177 NR: 'Nauru',
178 NP: 'Nepal',
179 NL: 'Netherlands',
180 AN: 'Netherlands Antilles',
181 NC: 'New Caledonia',
182 NZ: 'New Zealand',
183 NI: 'Nicaragua',
184 NE: 'Niger',
185 NG: 'Nigeria',
186 NU: 'Niue',
187 NF: 'Norfolk Island',
188 KP: 'North Korea',
189 VD: 'North Vietnam',
190 MP: 'Northern Mariana Islands',
191 NO: 'Norway',
192 OM: 'Oman',
193 QO: 'Outlying Oceania',
194 PC: 'Pacific Islands Trust Territory',
195 PK: 'Pakistan',
196 PW: 'Palau',
197 PS: 'Palestinian Territories',
198 PA: 'Panama',
199 PZ: 'Panama Canal Zone',
200 PG: 'Papua New Guinea',
201 PY: 'Paraguay',
202 YD: 'Peoples Democratic Republic of Yemen',
203 PE: 'Peru',
204 PH: 'Philippines',
205 PN: 'Pitcairn Islands',
206 PL: 'Poland',
207 PT: 'Portugal',
208 PR: 'Puerto Rico',
209 QA: 'Qatar',
210 RO: 'Romania',
211 RU: 'Russia',
212 RW: 'Rwanda',
213 RE: 'Réunion',
214 BL: 'Saint Barthélemy',
215 SH: 'Saint Helena',
216 KN: 'Saint Kitts and Nevis',
217 LC: 'Saint Lucia',
218 MF: 'Saint Martin',
219 PM: 'Saint Pierre and Miquelon',
220 VC: 'Saint Vincent and the Grenadines',
221 WS: 'Samoa',
222 SM: 'San Marino',
223 SA: 'Saudi Arabia',
224 SN: 'Senegal',
225 RS: 'Serbia',
226 CS: 'Serbia and Montenegro',
227 SC: 'Seychelles',
228 SL: 'Sierra Leone',
229 SG: 'Singapore',
230 SK: 'Slovakia',
231 SI: 'Slovenia',
232 SB: 'Solomon Islands',
233 SO: 'Somalia',
234 ZA: 'South Africa',
235 GS: 'South Georgia and the South Sandwich Islands',
236 KR: 'South Korea',
237 ES: 'Spain',
238 LK: 'Sri Lanka',
239 SD: 'Sudan',
240 SR: 'Suriname',
241 SJ: 'Svalbard and Jan Mayen',
242 SZ: 'Swaziland',
243 SE: 'Sweden',
244 CH: 'Switzerland',
245 SY: 'Syria',
246 ST: 'São Tomé and Príncipe',
247 TW: 'Taiwan',
248 TJ: 'Tajikistan',
249 TZ: 'Tanzania',
250 TH: 'Thailand',
251 TG: 'Togo',
252 TK: 'Tokelau',
253 TO: 'Tonga',
254 TT: 'Trinidad and Tobago',
255 TA: 'Tristan da Cunha',
256 TN: 'Tunisia',
257 TR: 'Turkey',
258 TM: 'Turkmenistan',
259 TC: 'Turks and Caicos Islands',
260 TV: 'Tuvalu',
261 UM: 'U.S. Minor Outlying Islands',
262 PU: 'U.S. Miscellaneous Pacific Islands',
263 VI: 'U.S. Virgin Islands',
264 UG: 'Uganda',
265 UA: 'Ukraine',
266 AE: 'United Arab Emirates',
267 GB: 'United Kingdom',
268 US: 'United States',
269 UY: 'Uruguay',
270 UZ: 'Uzbekistan',
271 VU: 'Vanuatu',
272 VA: 'Vatican City',
273 VE: 'Venezuela',
274 VN: 'Vietnam',
275 WK: 'Wake Island',
276 WF: 'Wallis and Futuna',
277 EH: 'Western Sahara',
278 YE: 'Yemen',
279 ZM: 'Zambia',
280 ZW: 'Zimbabwe',
281 AX: 'Åland Islands',
282 },
283 actionText: 'Select country',
284 // defaultValue: 'AT',
285 onChange: (e: React.ChangeEvent<HTMLInputElement>) => console.log('changed event', e),
286 };
287};
288
289storiesOf('Select')
290 .add('Basic', () => (
291 <Select
292 {...defaultProps()}
293 />
294 ))
295 .add('With preselection', () => (
296 <Select
297 {...defaultProps()}
298 defaultValue="AT"
299 />
300 ))
301 .add('With search', () => (
302 <Select
303 {...defaultProps()}
304 showSearch
305 />
306 ))
307 .add('Disabled', () => (
308 <Select
309 {...defaultProps()}
310 showSearch
311 disabled
312 />
313 ))
314 .add('With error', () => (
315 <Select
316 {...defaultProps()}
317 showSearch
318 error="Your selection was a bit too funky for my taste"
319 />
320 ));
diff --git a/uidev/src/stories/toggle.stories.tsx b/uidev/src/stories/toggle.stories.tsx
new file mode 100644
index 000000000..091342496
--- /dev/null
+++ b/uidev/src/stories/toggle.stories.tsx
@@ -0,0 +1,70 @@
1import { observable } from 'mobx';
2import { observer } from 'mobx-react';
3import React from 'react';
4import uuid from 'uuid/v4';
5
6import { Toggle } from '@meetfranz/forms';
7import { storiesOf } from '../stores/stories';
8
9interface IStoreArgs {
10 value?: boolean;
11 checked?: boolean;
12 label?: string;
13 id?: string;
14 name?: string;
15 disabled?: boolean;
16 error?: string;
17}
18
19const createStore = (args?: IStoreArgs) => {
20 return observable(Object.assign({
21 id: `element-${uuid()}`,
22 name: 'toggle',
23 label: 'Label',
24 value: true,
25 checked: false,
26 disabled: false,
27 error: '',
28 }, args));
29};
30
31const WithStoreToggle = observer(({ store }: { store: any }) => (
32 <>
33 <Toggle
34 value={store.value}
35 checked={store.checked}
36 label={store.label}
37 id={store.id}
38 name={store.name}
39 disabled={store.disabled}
40 error={store.error}
41 onChange={() => store.checked = !store.checked}
42 />
43 </>
44));
45
46storiesOf('Toggle')
47 .add('Basic', () => (
48 <WithStoreToggle store={createStore()} />
49 ))
50 .add('Checked', () => (
51 <WithStoreToggle store={createStore({
52 checked: true,
53 })} />
54 ))
55 .add('Disabled', () => (
56 <WithStoreToggle store={createStore({
57 checked: true,
58 disabled: true,
59 })} />
60 ))
61 .add('Long label', () => (
62 <WithStoreToggle store={createStore({
63 label: 'Hello world, this is an insanely long label for this toggle. We need to make sure that it will be displayed correctly.',
64 })} />
65 ))
66 .add('With error', () => (
67 <WithStoreToggle store={createStore({
68 error: 'Something went wrong',
69 })} />
70 ));
diff --git a/uidev/src/withTheme/index.tsx b/uidev/src/withTheme/index.tsx
new file mode 100644
index 000000000..17a1074d3
--- /dev/null
+++ b/uidev/src/withTheme/index.tsx
@@ -0,0 +1,50 @@
1import { theme, Theme, ThemeType } from '@meetfranz/theme';
2import { Classes } from 'jss';
3import React from 'react';
4import injectSheet, { ThemeProvider } from 'react-jss';
5
6const defaultTheme = {
7 name: 'Default',
8 variables: theme(ThemeType.default),
9};
10
11const darkTheme = {
12 name: 'Dark Mode',
13 variables: theme(ThemeType.dark),
14};
15
16const themes = [defaultTheme, darkTheme];
17
18const styles = (theme: Theme) => ({
19 title: {
20 fontSize: 14,
21 },
22 container: {
23 border: theme.inputBorder,
24 borderRadius: theme.borderRadiusSmall,
25 marginBottom: 20,
26 padding: 20,
27 background: theme.colorContentBackground,
28 },
29});
30
31const Container = injectSheet(styles)(({ name, classes, story }: { name: string, classes: Classes, story: React.ReactNode }) => (
32 <article>
33 <h1 className={classes.title}>{name}</h1>
34 <div className={classes.container}>
35 {story}
36 </div>
37 </article>
38));
39
40export const WithTheme = ({ children }: {children: React.ReactChild}) => {
41 return (
42 <>
43 {themes.map((theme, key) => (
44 <ThemeProvider key={key} theme={theme.variables}>
45 <Container story={children} name={theme.name} />
46 </ThemeProvider>
47 ))}
48 </>
49 );
50};
diff --git a/uidev/tsconfig.json b/uidev/tsconfig.json
new file mode 100644
index 000000000..fb57639c8
--- /dev/null
+++ b/uidev/tsconfig.json
@@ -0,0 +1,14 @@
1{
2 "extends": "../tsconfig.settings.json",
3 "compilerOptions": {
4 "baseUrl": "..",
5 "outDir": "lib",
6 "rootDir": "src",
7 },
8 "references": [{
9 "path": "../packages/theme"
10 },
11 {
12 "path": "../packages/forms"
13 }]
14}
diff --git a/uidev/tslint.json b/uidev/tslint.json
new file mode 100644
index 000000000..ec365f164
--- /dev/null
+++ b/uidev/tslint.json
@@ -0,0 +1,3 @@
1{
2 "extends": "../tslint.json"
3}
diff --git a/uidev/webpack.config.js b/uidev/webpack.config.js
new file mode 100644
index 000000000..74ea870ef
--- /dev/null
+++ b/uidev/webpack.config.js
@@ -0,0 +1,29 @@
1const path = require('path');
2const HtmlWebpackPlugin = require('html-webpack-plugin');
3
4module.exports = {
5 entry: './src/index.tsx',
6 module: {
7 rules: [{
8 test: /\.tsx?$/,
9 use: 'ts-loader',
10 exclude: /node_modules/,
11 }],
12 },
13 resolve: {
14 extensions: ['.tsx', '.ts', '.js'],
15 alias: {
16 react: path.resolve('../node_modules/react'),
17 },
18 },
19 mode: 'none',
20 plugins: [
21 new HtmlWebpackPlugin({
22 template: path.join('src', 'app.html'),
23 }),
24 ],
25 devServer: {
26 inline: true,
27 port: 8008,
28 },
29};