aboutsummaryrefslogtreecommitdiffstats
path: root/packages/ui
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2019-01-28 11:35:25 +0100
committerLibravatar Stefan Malzner <stefan@adlk.io>2019-01-28 11:35:25 +0100
commit9a5b313ea12bdb9dc3e3873ca3a2639bd7483e46 (patch)
tree038dc5e0a209d06e1c15c1e3c4740d5bdda96f8a /packages/ui
parentAdd href and type to button component (diff)
downloadferdium-app-9a5b313ea12bdb9dc3e3873ca3a2639bd7483e46.tar.gz
ferdium-app-9a5b313ea12bdb9dc3e3873ca3a2639bd7483e46.tar.zst
ferdium-app-9a5b313ea12bdb9dc3e3873ca3a2639bd7483e46.zip
Update packages
Diffstat (limited to 'packages/ui')
-rw-r--r--packages/ui/.gitignore2
-rw-r--r--packages/ui/package-lock.json207
-rw-r--r--packages/ui/package.json41
-rw-r--r--packages/ui/src/badge/index.tsx75
-rw-r--r--packages/ui/src/headline/index.tsx71
-rw-r--r--packages/ui/src/icon/index.tsx55
-rw-r--r--packages/ui/src/index.ts5
-rw-r--r--packages/ui/src/infobox/index.tsx194
-rw-r--r--packages/ui/src/loader/index.tsx45
-rw-r--r--packages/ui/src/typings/generic.ts10
-rw-r--r--packages/ui/tsconfig.json12
-rw-r--r--packages/ui/tslint.json3
-rw-r--r--packages/ui/webpack.config.js19
13 files changed, 739 insertions, 0 deletions
diff --git a/packages/ui/.gitignore b/packages/ui/.gitignore
new file mode 100644
index 000000000..d01826a6b
--- /dev/null
+++ b/packages/ui/.gitignore
@@ -0,0 +1,2 @@
1node_modules/
2lib
diff --git a/packages/ui/package-lock.json b/packages/ui/package-lock.json
new file mode 100644
index 000000000..8fa68a29b
--- /dev/null
+++ b/packages/ui/package-lock.json
@@ -0,0 +1,207 @@
1{
2 "name": "@meetfranz/ui",
3 "version": "0.0.0",
4 "lockfileVersion": 1,
5 "requires": true,
6 "dependencies": {
7 "@mdi/js": {
8 "version": "3.3.92",
9 "resolved": "https://registry.npmjs.org/@mdi/js/-/js-3.3.92.tgz",
10 "integrity": "sha512-l+12IwTycHlijWMiRWBAssm0RSgkQiwMthIy/EcBAdSqtnsHnFjHq+aI2MBZ8/AYX0QBxNUv4+EN0SXZgNkWDg=="
11 },
12 "@mdi/react": {
13 "version": "1.1.0",
14 "resolved": "https://registry.npmjs.org/@mdi/react/-/react-1.1.0.tgz",
15 "integrity": "sha512-c0+avMYEZ6i7Pg1ULLFs+p7k8bDPiie9rrgGYs8VWQhw2tUUYz7r0lIPVzD3bzMghWfyhfkArj88K5Of0WTMNw=="
16 },
17 "@meetfranz/theme": {
18 "version": "file:../theme",
19 "requires": {
20 "color": "^3.1.0"
21 },
22 "dependencies": {
23 "color": {
24 "version": "3.1.0",
25 "bundled": true,
26 "requires": {
27 "color-convert": "^1.9.1",
28 "color-string": "^1.5.2"
29 }
30 },
31 "color-convert": {
32 "version": "1.9.3",
33 "bundled": true,
34 "requires": {
35 "color-name": "1.1.3"
36 }
37 },
38 "color-name": {
39 "version": "1.1.3",
40 "bundled": true
41 },
42 "color-string": {
43 "version": "1.5.3",
44 "bundled": true,
45 "requires": {
46 "color-name": "^1.0.0",
47 "simple-swizzle": "^0.2.2"
48 }
49 },
50 "is-arrayish": {
51 "version": "0.3.2",
52 "bundled": true
53 },
54 "simple-swizzle": {
55 "version": "0.2.2",
56 "bundled": true,
57 "requires": {
58 "is-arrayish": "^0.3.1"
59 }
60 }
61 }
62 },
63 "asap": {
64 "version": "2.0.6",
65 "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
66 "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
67 },
68 "core-js": {
69 "version": "1.2.7",
70 "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
71 "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
72 },
73 "create-react-class": {
74 "version": "15.6.3",
75 "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz",
76 "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==",
77 "requires": {
78 "fbjs": "^0.8.9",
79 "loose-envify": "^1.3.1",
80 "object-assign": "^4.1.1"
81 }
82 },
83 "encoding": {
84 "version": "0.1.12",
85 "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
86 "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
87 "requires": {
88 "iconv-lite": "~0.4.13"
89 }
90 },
91 "fbjs": {
92 "version": "0.8.17",
93 "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
94 "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
95 "requires": {
96 "core-js": "^1.0.0",
97 "isomorphic-fetch": "^2.1.1",
98 "loose-envify": "^1.0.0",
99 "object-assign": "^4.1.0",
100 "promise": "^7.1.1",
101 "setimmediate": "^1.0.5",
102 "ua-parser-js": "^0.7.18"
103 }
104 },
105 "iconv-lite": {
106 "version": "0.4.24",
107 "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
108 "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
109 "requires": {
110 "safer-buffer": ">= 2.1.2 < 3"
111 }
112 },
113 "is-stream": {
114 "version": "1.1.0",
115 "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
116 "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
117 },
118 "isomorphic-fetch": {
119 "version": "2.2.1",
120 "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
121 "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
122 "requires": {
123 "node-fetch": "^1.0.1",
124 "whatwg-fetch": ">=0.10.0"
125 }
126 },
127 "js-tokens": {
128 "version": "4.0.0",
129 "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
130 "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
131 },
132 "loose-envify": {
133 "version": "1.4.0",
134 "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
135 "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
136 "requires": {
137 "js-tokens": "^3.0.0 || ^4.0.0"
138 }
139 },
140 "node-fetch": {
141 "version": "1.7.3",
142 "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
143 "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
144 "requires": {
145 "encoding": "^0.1.11",
146 "is-stream": "^1.0.1"
147 }
148 },
149 "object-assign": {
150 "version": "4.1.1",
151 "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
152 "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
153 },
154 "promise": {
155 "version": "7.3.1",
156 "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
157 "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
158 "requires": {
159 "asap": "~2.0.3"
160 }
161 },
162 "prop-types": {
163 "version": "15.6.2",
164 "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz",
165 "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==",
166 "requires": {
167 "loose-envify": "^1.3.1",
168 "object-assign": "^4.1.1"
169 }
170 },
171 "react-loader": {
172 "version": "2.4.5",
173 "resolved": "https://registry.npmjs.org/react-loader/-/react-loader-2.4.5.tgz",
174 "integrity": "sha1-zT5VHGzQc4wcDxPwc2VPk4KL5ak=",
175 "requires": {
176 "create-react-class": "^15.5.2",
177 "prop-types": "^15.5.8",
178 "spin.js": "2.x"
179 }
180 },
181 "safer-buffer": {
182 "version": "2.1.2",
183 "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
184 "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
185 },
186 "setimmediate": {
187 "version": "1.0.5",
188 "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
189 "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
190 },
191 "spin.js": {
192 "version": "2.3.2",
193 "resolved": "https://registry.npmjs.org/spin.js/-/spin.js-2.3.2.tgz",
194 "integrity": "sha1-bKpW1SBnNFD9XPvGlx5tB3LDeho="
195 },
196 "ua-parser-js": {
197 "version": "0.7.19",
198 "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz",
199 "integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ=="
200 },
201 "whatwg-fetch": {
202 "version": "3.0.0",
203 "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
204 "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
205 }
206 }
207}
diff --git a/packages/ui/package.json b/packages/ui/package.json
new file mode 100644
index 000000000..cd7252850
--- /dev/null
+++ b/packages/ui/package.json
@@ -0,0 +1,41 @@
1{
2 "name": "@meetfranz/ui",
3 "version": "0.0.0",
4 "description": "React UI components for Franz",
5 "main": "lib/index.js",
6 "scripts": {
7 "dev": "NODE_ENV=development ../../node_modules/.bin/webpack -w",
8 "prepare": "../../node_modules/.bin/webpack"
9 },
10 "publishConfig": {
11 "access": "public"
12 },
13 "repository": {
14 "type": "git",
15 "url": "git+https://github.com/meetfranz/franz.git"
16 },
17 "keywords": [
18 "Franz",
19 "Forms",
20 "React",
21 "UI"
22 ],
23 "author": "Stefan Malzner <stefan@adlk.io>",
24 "license": "Apache-2.0",
25 "dependencies": {
26 "@mdi/js": "^3.3.92",
27 "@mdi/react": "^1.1.0",
28 "@meetfranz/theme": "file:../theme",
29 "react-loader": "^2.4.5"
30 },
31 "peerDependencies": {
32 "classnames": "^2.2.6",
33 "lodash": "^4.17.11",
34 "mobx": "^5.8.0",
35 "mobx-react": "^5.4.3",
36 "react": "^16.7.0",
37 "react-dom": "16.7.0",
38 "react-jss": "^8.6.1"
39 },
40 "gitHead": "e31248830eb63c8bff3d9add3baa4ca8916b74e1"
41}
diff --git a/packages/ui/src/badge/index.tsx b/packages/ui/src/badge/index.tsx
new file mode 100644
index 000000000..241e778e7
--- /dev/null
+++ b/packages/ui/src/badge/index.tsx
@@ -0,0 +1,75 @@
1import { Theme } from '@meetfranz/theme';
2import classnames from 'classnames';
3import React, { Component } from 'react';
4import injectStyle from 'react-jss';
5
6import { IWithStyle } from '../typings/generic';
7
8interface IProps extends IWithStyle {
9 type: string;
10 className?: string;
11 children: React.ReactNode;
12}
13
14const badgeStyles = (theme: Theme) => {
15 const styles = {};
16 Object.keys(theme.styleTypes).map((style) => {
17 Object.assign(styles, {
18 [style]: {
19 background: theme.styleTypes[style].accent,
20 color: theme.styleTypes[style].contrast,
21 border: theme.styleTypes[style].border,
22 },
23 });
24 });
25
26 return styles;
27};
28
29const styles = (theme: Theme) => ({
30 badge: {
31 display: 'inline-block',
32 padding: [3, 8, 4],
33 fontSize: theme.badgeFontSize,
34 borderRadius: theme.badgeBorderRadius,
35 margin: [0, 4],
36
37 '&:first-child': {
38 marginLeft: 0,
39 },
40
41 '&:last-child': {
42 marginRight: 0,
43 },
44 },
45 ...badgeStyles(theme),
46});
47
48class BadgeComponent extends Component<IProps> {
49 public static defaultProps = {
50 type: 'primary',
51 };
52
53 render() {
54 const {
55 classes,
56 children,
57 type,
58 className,
59 } = this.props;
60
61 return (
62 <div
63 className={classnames({
64 [classes.badge]: true,
65 [classes[type]]: true,
66 [`${className}`]: className,
67 })}
68 >
69 {children}
70 </div>
71 );
72 }
73}
74
75export const Badge = injectStyle(styles)(BadgeComponent);
diff --git a/packages/ui/src/headline/index.tsx b/packages/ui/src/headline/index.tsx
new file mode 100644
index 000000000..3458a40ad
--- /dev/null
+++ b/packages/ui/src/headline/index.tsx
@@ -0,0 +1,71 @@
1import { Theme } from '@meetfranz/theme';
2import classnames from 'classnames';
3import React, { Component } from 'react';
4import injectStyle from 'react-jss';
5
6import { uiFontSize } from '@meetfranz/theme/lib/themes/default';
7import { IWithStyle, Omit } from '../typings/generic';
8
9interface IProps extends IWithStyle {
10 level?: number;
11 className?: string;
12 children: string | React.ReactNode;
13 id?: string;
14}
15
16const styles = (theme: Theme) => ({
17 headline: {
18 fontWeight: 'lighter',
19 color: theme.colorText,
20 marginTop: 0,
21 marginBottom: 10,
22 textAlign: 'left',
23 },
24 h1: {
25 fontSize: 30,
26 marginTop: 0,
27 },
28 h2: {
29 fontSize: 20,
30 },
31 h3: {
32 fontSize: 18,
33 },
34 h4: {
35 fontSize: theme.uiFontSize,
36 },
37});
38
39class HeadlineComponent extends Component<IProps> {
40 render() {
41 const {
42 classes,
43 level,
44 className,
45 children,
46 id,
47 } = this.props;
48
49 return React.createElement(
50 `h${level}`,
51 {
52 id,
53 className: classnames({
54 [classes.headline]: true,
55 [classes[level ? `h${level}` : 'h1']]: true,
56 [`${className}`]: className,
57 }),
58 },
59 children,
60 );
61 }
62}
63
64const Headline = injectStyle(styles)(HeadlineComponent);
65
66const createH = (level: number) => (props: Omit<IProps, 'classes' | 'theme'>) => <Headline level={level} {...props}>{props.children}</Headline>;
67
68export const H1 = createH(1);
69export const H2 = createH(2);
70export const H3 = createH(3);
71export const H4 = createH(4);
diff --git a/packages/ui/src/icon/index.tsx b/packages/ui/src/icon/index.tsx
new file mode 100644
index 000000000..e30d3396d
--- /dev/null
+++ b/packages/ui/src/icon/index.tsx
@@ -0,0 +1,55 @@
1import * as mdiIcons from '@mdi/js';
2import MdiIcon from '@mdi/react';
3import { Theme } from '@meetfranz/theme';
4import classnames from 'classnames';
5import React, { Component } from 'react';
6import injectStyle from 'react-jss';
7
8import { IWithStyle } from '../typings/generic';
9
10interface IProps extends IWithStyle {
11 icon: keyof typeof mdiIcons;
12 size?: number;
13 className?: string;
14}
15
16const styles = (theme: Theme) => ({
17 icon: {
18 fill: theme.colorText,
19 },
20});
21
22class IconComponent extends Component<IProps> {
23 public static defaultProps = {
24 size: 1,
25 };
26
27 render() {
28 const {
29 classes,
30 icon: iconName,
31 size,
32 className,
33 } = this.props;
34
35 let icon = '';
36 if (iconName && mdiIcons[iconName]) {
37 icon = mdiIcons[iconName];
38 } else if (iconName && !mdiIcons[iconName]) {
39 console.warn(`Icon '${iconName}' was not found`);
40 }
41
42 return (
43 <MdiIcon
44 path={icon}
45 size={size}
46 className={classnames({
47 [classes.icon]: true,
48 [`${className}`]: className,
49 })}
50 />
51 );
52 }
53}
54
55export const Icon = injectStyle(styles)(IconComponent);
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts
new file mode 100644
index 000000000..1eeec5144
--- /dev/null
+++ b/packages/ui/src/index.ts
@@ -0,0 +1,5 @@
1export { Icon } from './icon';
2export { Infobox } from './infobox';
3export * from './headline';
4export { Loader } from './loader';
5export { Badge } from './badge';
diff --git a/packages/ui/src/infobox/index.tsx b/packages/ui/src/infobox/index.tsx
new file mode 100644
index 000000000..bf985ea9c
--- /dev/null
+++ b/packages/ui/src/infobox/index.tsx
@@ -0,0 +1,194 @@
1import { Theme } from '@meetfranz/theme';
2import classnames from 'classnames';
3import { observer } from 'mobx-react';
4import React, { Component } from 'react';
5import injectStyle from 'react-jss';
6// import Loader from 'react-loader';
7
8import { Icon } from '../';
9import { IWithStyle } from '../typings/generic';
10
11interface IProps extends IWithStyle {
12 icon?: string;
13 type?: string;
14 dismissable?: boolean;
15 onDismiss?: () => void;
16 ctaOnClick?: () => void;
17 ctaLabel?: string;
18 ctaLoading?: boolean;
19 children: React.ReactNode;
20}
21
22interface IState {
23 isDismissing: boolean;
24 dismissed: boolean;
25}
26
27const buttonStyles = (theme: Theme) => {
28 const styles = {};
29 Object.keys(theme.styleTypes).map((style) => {
30 Object.assign(styles, {
31 [style]: {
32 background: theme.styleTypes[style].accent,
33 color: theme.styleTypes[style].contrast,
34 border: theme.styleTypes[style].border,
35
36 '& svg': {
37 fill: theme.styleTypes[style].contrast,
38 },
39 },
40 });
41 });
42
43 return styles;
44};
45
46const styles = (theme: Theme) => ({
47 wrapper: {
48 position: 'relative',
49 overflow: 'hidden',
50 },
51 infobox: {
52 alignItems: 'center',
53 borderRadius: theme.borderRadiusSmall,
54 display: 'flex',
55 height: 'auto',
56 marginBottom: 30,
57 padding: '15px 20px',
58 top: 0,
59 transition: 'all 0.5s',
60 opacity: 1,
61 },
62 dismissing: {
63 // position: 'absolute',
64 marginTop: -100,
65 opacity: 0,
66 },
67 content: {
68 flex: 1,
69 },
70 icon: {
71 marginRight: 10,
72 },
73 close: {
74 color: (props: IProps) => theme.styleTypes[props.type ? props.type : 'primary'].contrast,
75 marginRight: -5,
76 border: 0,
77 background: 'none',
78 },
79 cta: {
80 borderColor: (props: IProps) => theme.styleTypes[props.type ? props.type : 'primary'].contrast,
81 borderRadius: theme.borderRadiusSmall,
82 borderStyle: 'solid',
83 borderWidth: 1,
84 background: 'none',
85 color: (props: IProps) => theme.styleTypes[props.type ? props.type : 'primary'].contrast,
86 marginLeft: 15,
87 padding: [4, 10],
88 fontSize: theme.uiFontSize,
89 transition: 'opacity 0.3s',
90
91 '&:hover': {
92 opacity: 0.6,
93 },
94 },
95 ...buttonStyles(theme),
96});
97
98@observer
99class InfoboxComponent extends Component<IProps, IState> {
100 public static defaultProps = {
101 type: 'primary',
102 dismissable: false,
103 ctaOnClick: () => {},
104 onDismiss: () => {},
105 ctaLabel: '',
106 ctaLoading: false,
107 };
108
109 state = {
110 isDismissing: false,
111 dismissed: false,
112 };
113
114 dismiss() {
115 const {
116 onDismiss,
117 } = this.props;
118
119 this.setState({
120 isDismissing: true,
121 });
122
123 if (onDismiss) {
124 onDismiss();
125 }
126
127 setTimeout(() => {
128 this.setState({
129 dismissed: true,
130 });
131 }, 3000);
132 }
133
134 render() {
135 const {
136 classes,
137 children,
138 icon,
139 type,
140 ctaLabel,
141 ctaLoading,
142 ctaOnClick,
143 dismissable,
144 } = this.props;
145
146 const {
147 isDismissing,
148 dismissed,
149 } = this.state;
150
151 if (dismissed) {
152 return null;
153 }
154
155 return (
156 <div className={classes.wrapper}>
157 <div
158 className={classnames({
159 [classes.infobox]: true,
160 [classes[`${type}`]]: type,
161 [classes.dismissing]: isDismissing,
162 })}
163 >
164 {icon && (
165 <Icon icon={icon} className={classes.icon} />
166 )}
167 <div className={classes.content}>
168 {children}
169 </div>
170 {ctaLabel && (
171 <button
172 className={classes.cta}
173 onClick={ctaOnClick}
174 type="button"
175 >
176 {ctaLabel}
177 </button>
178 )}
179 {dismissable && (
180 <button
181 type="button"
182 onClick={this.dismiss.bind(this)}
183 className={classes.close}
184 >
185 <Icon icon="mdiClose" />
186 </button>
187 )}
188 </div>
189 </div>
190 );
191 }
192}
193
194export const Infobox = injectStyle(styles)(InfoboxComponent);
diff --git a/packages/ui/src/loader/index.tsx b/packages/ui/src/loader/index.tsx
new file mode 100644
index 000000000..799caf195
--- /dev/null
+++ b/packages/ui/src/loader/index.tsx
@@ -0,0 +1,45 @@
1import { Theme } from '@meetfranz/theme';
2import classnames from 'classnames';
3import React, { Component } from 'react';
4import injectStyle from 'react-jss';
5import ReactLoader from 'react-loader';
6
7import { IWithStyle } from '../typings/generic';
8
9interface IProps extends IWithStyle {
10 className?: string;
11}
12
13const styles = (theme: Theme) => ({
14 container: {
15 position: 'relative',
16 height: 60,
17 },
18});
19
20class LoaderComponent extends Component<IProps> {
21 render() {
22 const {
23 classes,
24 className,
25 theme,
26 } = this.props;
27
28 return (
29 <div className={classnames({
30 [classes.container]: true,
31 [`${className}`]: className,
32 })}>
33 <ReactLoader
34 loaded={false}
35 width={4}
36 scale={0.75}
37 color={theme.colorText}
38 parentClassName={classes.loader}
39 />
40 </div>
41 );
42 }
43}
44
45export const Loader = injectStyle(styles)(LoaderComponent);
diff --git a/packages/ui/src/typings/generic.ts b/packages/ui/src/typings/generic.ts
new file mode 100644
index 000000000..d5f953b9f
--- /dev/null
+++ b/packages/ui/src/typings/generic.ts
@@ -0,0 +1,10 @@
1import { Theme } from '@meetfranz/theme/lib';
2import { Classes } from 'jss';
3
4export interface IWithStyle {
5 classes: Classes;
6 theme: Theme;
7}
8
9export type Merge<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;
10export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json
new file mode 100644
index 000000000..8b9507eac
--- /dev/null
+++ b/packages/ui/tsconfig.json
@@ -0,0 +1,12 @@
1{
2 "extends": "../../tsconfig.settings.json",
3 "compilerOptions": {
4 "outDir": "lib",
5 "rootDir": "src"
6 },
7 "references": [
8 {
9 "path": "../theme"
10 }
11 ]
12}
diff --git a/packages/ui/tslint.json b/packages/ui/tslint.json
new file mode 100644
index 000000000..0946f2096
--- /dev/null
+++ b/packages/ui/tslint.json
@@ -0,0 +1,3 @@
1{
2 "extends": "../../tslint.json"
3}
diff --git a/packages/ui/webpack.config.js b/packages/ui/webpack.config.js
new file mode 100644
index 000000000..cc3370359
--- /dev/null
+++ b/packages/ui/webpack.config.js
@@ -0,0 +1,19 @@
1const path = require('path');
2const baseConfig = require('../../webpack.config.base')(__dirname);
3
4module.exports = Object.assign({}, baseConfig, {
5 output: {
6 filename: 'index.js',
7 path: path.join(__dirname, 'lib'),
8 libraryTarget: 'commonjs2',
9 },
10 externals: {
11 react: 'react',
12 reactDom: 'react-dom',
13 classnames: 'classnames',
14 lodash: 'lodash',
15 mobx: 'mobx',
16 mobxReact: 'mobx-react',
17 reactJss: 'react-jss',
18 },
19});