aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/ui/infobox/index.tsx
diff options
context:
space:
mode:
authorLibravatar Vijay Aravamudhan <vraravam@users.noreply.github.com>2021-10-15 15:25:41 +0530
committerLibravatar GitHub <noreply@github.com>2021-10-15 15:25:41 +0530
commit0ad7444fb1dc2cdb82830df4ef241d75a6bfd82d (patch)
tree5a994fb8e0620aa5d2542ddd9c8561ef9861a9b5 /src/components/ui/infobox/index.tsx
parentchore: refresh lock file to fix vulnerabilities (#2075) (diff)
downloadferdium-app-0ad7444fb1dc2cdb82830df4ef241d75a6bfd82d.tar.gz
ferdium-app-0ad7444fb1dc2cdb82830df4ef241d75a6bfd82d.tar.zst
ferdium-app-0ad7444fb1dc2cdb82830df4ef241d75a6bfd82d.zip
chore: move 'packages/ui' into 'src' (no longer an injected package) (#2077)
Diffstat (limited to 'src/components/ui/infobox/index.tsx')
-rw-r--r--src/components/ui/infobox/index.tsx205
1 files changed, 205 insertions, 0 deletions
diff --git a/src/components/ui/infobox/index.tsx b/src/components/ui/infobox/index.tsx
new file mode 100644
index 000000000..e6be83556
--- /dev/null
+++ b/src/components/ui/infobox/index.tsx
@@ -0,0 +1,205 @@
1import { mdiClose } from '@mdi/js';
2import classnames from 'classnames';
3import { Component, ReactNode } from 'react';
4import injectStyle from 'react-jss';
5
6import { Theme } from '@meetfranz/theme';
7import { Icon } from '../icon';
8import { IWithStyle } from '../typings/generic';
9
10interface IProps extends IWithStyle {
11 icon?: string;
12 type?: string;
13 dismissable?: boolean;
14 onDismiss?: () => void;
15 onUnmount?: () => void;
16 ctaOnClick?: () => void;
17 ctaLabel?: string;
18 ctaLoading?: boolean;
19 children: ReactNode;
20 className: string;
21}
22
23interface IState {
24 isDismissing: boolean;
25 dismissed: boolean;
26}
27
28const buttonStyles = (theme: Theme) => {
29 const styles = {};
30 Object.keys(theme.styleTypes).map(style => {
31 Object.assign(styles, {
32 [style]: {
33 background: theme.styleTypes[style].accent,
34 color: theme.styleTypes[style].contrast,
35 border: theme.styleTypes[style].border,
36
37 '& svg': {
38 fill: theme.styleTypes[style].contrast,
39 },
40 },
41 });
42 });
43
44 return styles;
45};
46
47const infoBoxTransition: string = 'none';
48const ctaTransition: string = 'none';
49
50// TODO: Not sure why, but this location alone, the `dinwo` is not defined - and it throws an error thus aborting the startup sequence of ferdi
51// if (window && window.matchMedia('(prefers-reduced-motion: no-preference)')) {
52// infoBoxTransition = 'all 0.5s';
53// ctaTransition = 'opacity 0.3s';
54// }
55
56const styles = (theme: Theme) => ({
57 wrapper: {
58 position: 'relative',
59 overflow: 'hidden',
60 height: 'auto',
61 marginBottom: 30,
62 },
63 infobox: {
64 alignItems: 'center',
65 borderRadius: theme.borderRadiusSmall,
66 display: 'flex',
67 height: 'auto',
68 padding: '15px 20px',
69 top: 0,
70 transition: infoBoxTransition,
71 opacity: 1,
72 },
73 dismissing: {
74 // position: 'absolute',
75 marginTop: -100,
76 opacity: 0,
77 },
78 content: {
79 flex: 1,
80 },
81 icon: {
82 marginRight: 10,
83 },
84 close: {
85 color: (props: IProps) =>
86 theme.styleTypes[props.type ? props.type : 'primary'].contrast,
87 marginRight: -5,
88 border: 0,
89 background: 'none',
90 },
91 cta: {
92 borderColor: (props: IProps) =>
93 theme.styleTypes[props.type ? props.type : 'primary'].contrast,
94 borderRadius: theme.borderRadiusSmall,
95 borderStyle: 'solid',
96 borderWidth: 1,
97 background: 'none',
98 color: (props: IProps) =>
99 theme.styleTypes[props.type ? props.type : 'primary'].contrast,
100 marginLeft: 15,
101 padding: [4, 10],
102 fontSize: theme.uiFontSize,
103 transition: ctaTransition,
104
105 '&:hover': {
106 opacity: 0.6,
107 },
108 },
109 ...buttonStyles(theme),
110});
111
112class InfoboxComponent extends Component<IProps, IState> {
113 public static defaultProps = {
114 type: 'primary',
115 dismissable: false,
116 ctaOnClick: () => {},
117 onDismiss: () => {},
118 ctaLabel: '',
119 ctaLoading: false,
120 };
121
122 state = {
123 isDismissing: false,
124 dismissed: false,
125 };
126
127 dismiss() {
128 const { onDismiss } = this.props;
129
130 this.setState({
131 isDismissing: true,
132 });
133
134 if (onDismiss) {
135 onDismiss();
136 }
137
138 setTimeout(() => {
139 this.setState({
140 dismissed: true,
141 });
142 }, 3000);
143 }
144
145 componentWillUnmount(): void {
146 const { onUnmount } = this.props;
147 if (onUnmount) onUnmount();
148 }
149
150 render() {
151 const {
152 classes,
153 children,
154 icon,
155 type,
156 ctaLabel,
157 ctaOnClick,
158 dismissable,
159 className,
160 } = this.props;
161
162 const { isDismissing, dismissed } = this.state;
163
164 if (dismissed) {
165 return null;
166 }
167
168 return (
169 <div
170 className={classnames({
171 [classes.wrapper]: true,
172 [`${className}`]: className,
173 })}
174 >
175 <div
176 className={classnames({
177 [classes.infobox]: true,
178 [classes[`${type}`]]: type,
179 [classes.dismissing]: isDismissing,
180 })}
181 data-type="franz-infobox"
182 >
183 {icon && <Icon icon={icon} className={classes.icon} />}
184 <div className={classes.content}>{children}</div>
185 {ctaLabel && (
186 <button className={classes.cta} onClick={ctaOnClick} type="button">
187 {ctaLabel}
188 </button>
189 )}
190 {dismissable && (
191 <button
192 type="button"
193 onClick={this.dismiss.bind(this)}
194 className={classes.close}
195 >
196 <Icon icon={mdiClose} />
197 </button>
198 )}
199 </div>
200 </div>
201 );
202 }
203}
204
205export const Infobox = injectStyle(styles)(InfoboxComponent);