aboutsummaryrefslogtreecommitdiffstats
path: root/packages/forms/src/button/index.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/forms/src/button/index.tsx')
-rw-r--r--packages/forms/src/button/index.tsx70
1 files changed, 39 insertions, 31 deletions
diff --git a/packages/forms/src/button/index.tsx b/packages/forms/src/button/index.tsx
index b81154a43..48fb61635 100644
--- a/packages/forms/src/button/index.tsx
+++ b/packages/forms/src/button/index.tsx
@@ -1,21 +1,31 @@
1import Icon from '@mdi/react'; 1import Icon from '@mdi/react';
2import { Theme } from '@meetfranz/theme';
3import classnames from 'classnames'; 2import classnames from 'classnames';
4import CSS from 'csstype'; 3import { Property } from 'csstype';
5import React, { Component } from 'react'; 4import React, { Component } from 'react';
6import injectStyle, { withTheme } from 'react-jss'; 5import injectStyle, { withTheme } from 'react-jss';
7import Loader from 'react-loader'; 6import Loader from 'react-loader';
8 7
9import { IFormField, IWithStyle } from '../typings/generic'; 8import { IFormField, IWithStyle } from '../typings/generic';
9import { Theme } from '../../../theme';
10 10
11type ButtonType = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'inverted'; 11type ButtonType =
12 | 'primary'
13 | 'secondary'
14 | 'success'
15 | 'danger'
16 | 'warning'
17 | 'inverted';
12 18
13interface IProps extends IFormField, IWithStyle { 19interface IProps extends IFormField, IWithStyle {
14 className?: string; 20 className?: string;
15 disabled?: boolean; 21 disabled?: boolean;
16 id?: string; 22 id?: string;
17 type?: "button" | "reset" | "submit" | undefined; 23 type?: 'button' | 'reset' | 'submit' | undefined;
18 onClick: (event: React.MouseEvent<HTMLButtonElement> | React.MouseEvent<HTMLAnchorElement>) => void; 24 onClick: (
25 event:
26 | React.MouseEvent<HTMLButtonElement>
27 | React.MouseEvent<HTMLAnchorElement>,
28 ) => void;
19 buttonType?: ButtonType; 29 buttonType?: ButtonType;
20 stretch?: boolean; 30 stretch?: boolean;
21 loaded?: boolean; 31 loaded?: boolean;
@@ -25,8 +35,12 @@ interface IProps extends IFormField, IWithStyle {
25 target?: string; 35 target?: string;
26} 36}
27 37
28interface IState { 38let buttonTransition: string = 'none';
29 busy: boolean; 39let loaderContainerTransition: string = 'none';
40
41if (window && window.matchMedia('(prefers-reduced-motion: no-preference)')) {
42 buttonTransition = 'background .5s, opacity 0.3s';
43 loaderContainerTransition = 'all 0.3s';
30} 44}
31 45
32const styles = (theme: Theme) => ({ 46const styles = (theme: Theme) => ({
@@ -34,16 +48,16 @@ const styles = (theme: Theme) => ({
34 borderRadius: theme.borderRadiusSmall, 48 borderRadius: theme.borderRadiusSmall,
35 border: 'none', 49 border: 'none',
36 display: 'inline-flex', 50 display: 'inline-flex',
37 position: 'relative' as CSS.PositionProperty, 51 position: 'relative' as Property.Position,
38 transition: 'background .5s, opacity 0.3s', 52 transition: buttonTransition,
39 textAlign: 'center' as CSS.TextAlignProperty, 53 textAlign: 'center' as Property.TextAlign,
40 outline: 'none', 54 outline: 'none',
41 alignItems: 'center', 55 alignItems: 'center',
42 padding: 0, 56 padding: 0,
43 width: (props: IProps) => (props.stretch ? '100%' : 'auto') as CSS.WidthProperty<string>, 57 width: (props: IProps) =>
58 (props.stretch ? '100%' : 'auto') as Property.Width<string>,
44 fontSize: theme.uiFontSize, 59 fontSize: theme.uiFontSize,
45 textDecoration: 'none', 60 textDecoration: 'none',
46 // height: theme.buttonHeight,
47 61
48 '&:hover': { 62 '&:hover': {
49 opacity: 0.8, 63 opacity: 0.8,
@@ -113,7 +127,7 @@ const styles = (theme: Theme) => ({
113 opacity: theme.inputDisabledOpacity, 127 opacity: theme.inputDisabledOpacity,
114 }, 128 },
115 loader: { 129 loader: {
116 position: 'relative' as CSS.PositionProperty, 130 position: 'relative' as Property.Position,
117 width: 20, 131 width: 20,
118 height: 18, 132 height: 18,
119 zIndex: 9999, 133 zIndex: 9999,
@@ -122,10 +136,11 @@ const styles = (theme: Theme) => ({
122 width: (props: IProps): string => (!props.busy ? '0' : '40px'), 136 width: (props: IProps): string => (!props.busy ? '0' : '40px'),
123 height: 20, 137 height: 20,
124 overflow: 'hidden', 138 overflow: 'hidden',
125 transition: 'all 0.3s', 139 transition: loaderContainerTransition,
126 marginLeft: (props: IProps): number => !props.busy ? 10 : 20, 140 marginLeft: (props: IProps): number => (!props.busy ? 10 : 20),
127 marginRight: (props: IProps): number => !props.busy ? -10 : -20, 141 marginRight: (props: IProps): number => (!props.busy ? -10 : -20),
128 position: (props: IProps): CSS.PositionProperty => props.stretch ? 'absolute' : 'inherit', 142 position: (props: IProps): Property.Position =>
143 props.stretch ? 'absolute' : 'inherit',
129 }, 144 },
130 icon: { 145 icon: {
131 margin: [1, 10, 0, -5], 146 margin: [1, 10, 0, -5],
@@ -155,7 +170,7 @@ class ButtonComponent extends Component<IProps> {
155 if (this.props.busy) { 170 if (this.props.busy) {
156 setTimeout(() => { 171 setTimeout(() => {
157 this.setState({ busy: nextProps.busy }); 172 this.setState({ busy: nextProps.busy });
158 }, 300); 173 }, 300);
159 } else { 174 } else {
160 this.setState({ busy: nextProps.busy }); 175 this.setState({ busy: nextProps.busy });
161 } 176 }
@@ -175,19 +190,18 @@ class ButtonComponent extends Component<IProps> {
175 buttonType, 190 buttonType,
176 loaded, 191 loaded,
177 icon, 192 icon,
178 busy: busyProp,
179 href, 193 href,
180 target, 194 target,
181 } = this.props; 195 } = this.props;
182 196
183 const { 197 const { busy } = this.state;
184 busy,
185 } = this.state;
186 198
187 let showLoader = false; 199 let showLoader = false;
188 if (loaded) { 200 if (loaded) {
189 showLoader = !loaded; 201 showLoader = !loaded;
190 console.warn('Ferdi Button prop `loaded` will be deprecated in the future. Please use `busy` instead'); 202 console.warn(
203 'Ferdi Button prop `loaded` will be deprecated in the future. Please use `busy` instead',
204 );
191 } 205 }
192 if (busy) { 206 if (busy) {
193 showLoader = busy; 207 showLoader = busy;
@@ -207,19 +221,13 @@ class ButtonComponent extends Component<IProps> {
207 )} 221 )}
208 </div> 222 </div>
209 <div className={classes.label}> 223 <div className={classes.label}>
210 {icon && ( 224 {icon && <Icon path={icon} size={0.8} className={classes.icon} />}
211 <Icon
212 path={icon}
213 size={0.8}
214 className={classes.icon}
215 />
216 )}
217 {label} 225 {label}
218 </div> 226 </div>
219 </> 227 </>
220 ); 228 );
221 229
222 let wrapperComponent = null; 230 let wrapperComponent: JSX.Element;
223 231
224 if (!href) { 232 if (!href) {
225 wrapperComponent = ( 233 wrapperComponent = (