@rabbitio/ui-kit 1.0.0-alpha.8 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/index.js +1 -0
- package/package.json +6 -16
- package/stories/atoms/LoadingDots/LoadingDots.jsx +57 -0
- package/stories/atoms/LoadingDots/LoadingDots.module.scss +83 -0
- package/stories/atoms/buttons/Button/Button.jsx +235 -0
- package/stories/atoms/buttons/Button/Button.module.scss +212 -0
- package/stories/index.js +2 -0
package/README.md
CHANGED
|
@@ -4,11 +4,19 @@ npm install --save @rabbitio/ui-kit
|
|
|
4
4
|
~~~
|
|
5
5
|
|
|
6
6
|
# Using library
|
|
7
|
-
1. To use components
|
|
7
|
+
1. To use components for web import the following way:
|
|
8
|
+
~~~
|
|
9
|
+
import { Button } from "@rabbitio/ui-kit/web";
|
|
10
|
+
~~~
|
|
11
|
+
2. To use components for node import the following way:
|
|
12
|
+
~~~
|
|
13
|
+
import { Button } from "@rabbitio/ui-kit/node";
|
|
14
|
+
~~~
|
|
15
|
+
3. To use components for next.js import the following way and add "@rabbitio/ui-kit" to transpilePackages inside your next.config.js:
|
|
8
16
|
~~~
|
|
9
17
|
import { Button } from "@rabbitio/ui-kit";
|
|
10
18
|
~~~
|
|
11
|
-
|
|
19
|
+
4. [In progress] Also, you can import base styles into your scss index file:
|
|
12
20
|
~~~
|
|
13
21
|
@import "@rabbitio/ui-kit/styles/index";
|
|
14
22
|
~~~
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./stories/index.js";
|
package/package.json
CHANGED
|
@@ -1,24 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rabbitio/ui-kit",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
4
|
"description": "Rabbit.io react.js components kit",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"files": [
|
|
7
|
-
"dist",
|
|
8
|
-
"styles",
|
|
9
|
-
"README.md"
|
|
10
|
-
],
|
|
11
6
|
"exports": {
|
|
12
|
-
".": "./
|
|
7
|
+
".": "./index.js",
|
|
13
8
|
"./node": "./dist/node/index.js",
|
|
14
|
-
"./dist/node": "./dist/node/index.js",
|
|
15
9
|
"./web": "./dist/web/index.js",
|
|
16
|
-
"./
|
|
17
|
-
"./node1": "./dist/node",
|
|
18
|
-
"./dist/node1": "./dist/node",
|
|
19
|
-
"./web1": "./dist/web",
|
|
20
|
-
"./dist/web1": "./dist/web"
|
|
21
|
-
|
|
10
|
+
"./package.json": "./package.json"
|
|
22
11
|
},
|
|
23
12
|
"scripts": {
|
|
24
13
|
"build-dev": "rm -rf dist && NODE_ENV=production webpack --mode development",
|
|
@@ -42,12 +31,13 @@
|
|
|
42
31
|
"license": "MIT",
|
|
43
32
|
"peerDependencies": {
|
|
44
33
|
"react": ">=16.0.0",
|
|
45
|
-
"react-dom": ">=16.0.0"
|
|
34
|
+
"react-dom": ">=16.0.0",
|
|
35
|
+
"react-router-dom": ">=6.21.1"
|
|
46
36
|
},
|
|
47
37
|
"dependencies": {
|
|
48
38
|
"react": ">=16.0.0",
|
|
49
39
|
"react-dom": ">=16.0.0",
|
|
50
|
-
"react-router-dom": "6.21.1"
|
|
40
|
+
"react-router-dom": ">=6.21.1"
|
|
51
41
|
},
|
|
52
42
|
"devDependencies": {
|
|
53
43
|
"@babel/core": "^7.23.7",
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
|
|
4
|
+
import styles from "./LoadingDots.module.scss";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* LoadingDots Component - Displays a loading animation with dots.
|
|
8
|
+
* This component allows customization of size, color, margins, and alignment.
|
|
9
|
+
*
|
|
10
|
+
* @component
|
|
11
|
+
* @param {Object} props - The props of the component.
|
|
12
|
+
* @param {('big'|'small'|'extra-small')} [props.size='small'] - Sets the size of the loading dots.
|
|
13
|
+
* @param {boolean} [props.isColored=false] - If true, the dots will be colored, otherwise they will be monochrome.
|
|
14
|
+
* @param {boolean} [props.noMargins=false] - If true, removes the margins around the loading dots.
|
|
15
|
+
* @param {(boolean|'left'|'right')} [props.align=false] - Aligns the loading dots to the left or right if specified, otherwise centered.
|
|
16
|
+
* @returns {React.ReactElement} A React component that renders the loading dots animation.
|
|
17
|
+
*/
|
|
18
|
+
export const LoadingDots = ({
|
|
19
|
+
size = "small",
|
|
20
|
+
isColored = false,
|
|
21
|
+
noMargins = false,
|
|
22
|
+
align = false,
|
|
23
|
+
}) => {
|
|
24
|
+
return (
|
|
25
|
+
<div
|
|
26
|
+
className={`${styles["loading-dots"]} ${styles[size]} ${
|
|
27
|
+
noMargins ? ` ${styles["no-margins"]}` : ""
|
|
28
|
+
} ${align ? styles["align-" + align] : ""}`}
|
|
29
|
+
>
|
|
30
|
+
<div
|
|
31
|
+
className={`${styles.dot} ${
|
|
32
|
+
isColored ? ` ${styles.colored}` : ""
|
|
33
|
+
}`}
|
|
34
|
+
/>
|
|
35
|
+
<div
|
|
36
|
+
className={`${styles.dot} ${
|
|
37
|
+
isColored ? ` ${styles.colored}` : ""
|
|
38
|
+
}`}
|
|
39
|
+
/>
|
|
40
|
+
<div
|
|
41
|
+
className={`${styles.dot} ${
|
|
42
|
+
isColored ? ` ${styles.colored}` : ""
|
|
43
|
+
}`}
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
LoadingDots.propTypes = {
|
|
50
|
+
size: PropTypes.oneOf(["big", "small", "extra-small"]),
|
|
51
|
+
isColored: PropTypes.bool,
|
|
52
|
+
noMargins: PropTypes.bool,
|
|
53
|
+
align: PropTypes.oneOfType([
|
|
54
|
+
PropTypes.oneOf(["left", "right"]),
|
|
55
|
+
PropTypes.bool,
|
|
56
|
+
]),
|
|
57
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
@import "../../../styles/index";
|
|
2
|
+
|
|
3
|
+
.loading-dots {
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
margin: 0 auto;
|
|
8
|
+
|
|
9
|
+
&.no-margins {
|
|
10
|
+
margin: 0 !important;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.dot {
|
|
14
|
+
border-radius: 50%;
|
|
15
|
+
background: $white;
|
|
16
|
+
|
|
17
|
+
&.colored {
|
|
18
|
+
background: SolidColor(tosca);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
animation: 0.5s ease-in-out 0s alternate infinite dots;
|
|
22
|
+
|
|
23
|
+
&:nth-child(2) {
|
|
24
|
+
animation-delay: 0.2s;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&:nth-child(3) {
|
|
28
|
+
animation-delay: 0.4s;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&.big {
|
|
33
|
+
.dot {
|
|
34
|
+
width: 24px;
|
|
35
|
+
height: 24px;
|
|
36
|
+
|
|
37
|
+
@media (max-width: $phone-width) {
|
|
38
|
+
width: 14px;
|
|
39
|
+
height: 14px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&:nth-child(2) {
|
|
43
|
+
@extend .mx-3;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&.small {
|
|
49
|
+
.dot {
|
|
50
|
+
width: 14px;
|
|
51
|
+
height: 14px;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&.extra-small {
|
|
56
|
+
.dot {
|
|
57
|
+
width: 8px;
|
|
58
|
+
height: 8px;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&.align-left {
|
|
63
|
+
justify-content: flex-start;
|
|
64
|
+
margin: 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&.align-right {
|
|
68
|
+
justify-content: flex-end;
|
|
69
|
+
margin: 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@keyframes dots {
|
|
74
|
+
0% {
|
|
75
|
+
transform: scale(1);
|
|
76
|
+
opacity: 1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
100% {
|
|
80
|
+
transform: scale(0.45);
|
|
81
|
+
opacity: 0.6;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { Link } from "react-router-dom";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
|
|
5
|
+
import styles from "./Button.module.scss";
|
|
6
|
+
|
|
7
|
+
import { LoadingDots } from "../../LoadingDots/LoadingDots.jsx";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Button component - A versatile and customizable button for React applications.
|
|
11
|
+
* It supports various sizes, styles, and functionalities, including loaders, icons, and handling of click events.
|
|
12
|
+
* This component can also be used as a link when integrated with `react-router-dom`.
|
|
13
|
+
*
|
|
14
|
+
* @component
|
|
15
|
+
* @param {Object} props
|
|
16
|
+
* @param {('xl'|'lg'|'md'|'sm')} [props.size='xl'] - Sets the size of the button.
|
|
17
|
+
* @param {string} [props.className=''] - An optional custom CSS class name for additional styling.
|
|
18
|
+
* @param {string} [props.mode='transparent'] - Determines the button's visual style.
|
|
19
|
+
* @param {Function} [props.onClick=(resetButtonLoader, event) => {}] - Callback function that triggers on button click.
|
|
20
|
+
* @param {boolean} [props.loader=true] - If true, displays a loader animation on the button when clicked.
|
|
21
|
+
* @param {boolean} [props.loading=false] - Controls the actual display of the loader if `loader` is true.
|
|
22
|
+
* @param {string} [props.to=''] - The path for the button to act as a link.
|
|
23
|
+
* @param {boolean} [props.fullWidthOnMobiles=false] - Expands the button to full width on mobiles.
|
|
24
|
+
* @param {boolean} [props.fullWidthOnTablets=false] - Expands the button to full width on tablets.
|
|
25
|
+
* @param {string} [props.icon=''] - The path to the button's icon.
|
|
26
|
+
* @param {React.ReactNode} [props.content=''] - The text or content displayed inside the button.
|
|
27
|
+
* @param {boolean} [props.isDisabled=false] - Disables the button if true.
|
|
28
|
+
* @param {Function} [props.setClickTrigger=(p) => {}] - Function to programmatically trigger a button click.
|
|
29
|
+
* @param {boolean} [props.isFormSubmittingButton=false] - If true, adds a hidden `<input type="submit">`.
|
|
30
|
+
* @param {boolean} [props.bigIcon=false] - If true, displays a larger icon on the button.
|
|
31
|
+
* @param {boolean} [props.checkmarkOnClick=false] - Shows a checkmark instead of content for a few seconds after click.
|
|
32
|
+
* @param {boolean} [props.propagatePrimaryButtonClick=true] - Propagates the primary button click event if true.
|
|
33
|
+
* @param {boolean} [props.smallPaddingOnSmallMobiles=false] - Enables smaller paddings for extra-small screen sizes.
|
|
34
|
+
* @param {Function} [props.handleError=(func) => func()] - Function to handle errors during button click events.
|
|
35
|
+
* @returns {React.ReactElement}
|
|
36
|
+
*/
|
|
37
|
+
export const Button = ({
|
|
38
|
+
size = "xl",
|
|
39
|
+
className = "",
|
|
40
|
+
mode = "transparent",
|
|
41
|
+
onClick = (resetButtonLoader, event) => {},
|
|
42
|
+
loader = true,
|
|
43
|
+
loading = false,
|
|
44
|
+
to = "",
|
|
45
|
+
fullWidthOnMobiles = false,
|
|
46
|
+
fullWidthOnTablets = false,
|
|
47
|
+
icon = "",
|
|
48
|
+
content = "",
|
|
49
|
+
isDisabled = false,
|
|
50
|
+
setClickTrigger = (p) => {},
|
|
51
|
+
isFormSubmittingButton = false,
|
|
52
|
+
bigIcon = false,
|
|
53
|
+
checkmarkOnClick = false,
|
|
54
|
+
propagatePrimaryButtonClick = true,
|
|
55
|
+
smallPaddingOnSmallMobiles = false,
|
|
56
|
+
handleError = (func, event) => func(event),
|
|
57
|
+
}) => {
|
|
58
|
+
const [isLoading, setIsLoading] = useState(loading);
|
|
59
|
+
const [isCheckShown, setIsCheckShown] = useState(false);
|
|
60
|
+
const [event, setEvent] = useState(null);
|
|
61
|
+
|
|
62
|
+
const buttonRef = useRef();
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
setClickTrigger(() => buttonRef.current.click());
|
|
66
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
67
|
+
}, [buttonRef]);
|
|
68
|
+
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (isLoading) {
|
|
71
|
+
onClick(() => setIsLoading(false), event);
|
|
72
|
+
}
|
|
73
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
74
|
+
}, [isLoading]);
|
|
75
|
+
|
|
76
|
+
const buttonClick = (e) => {
|
|
77
|
+
if (isLoading || isDisabled) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (checkmarkOnClick && !isCheckShown && !loader && !loading) {
|
|
82
|
+
setIsCheckShown(true);
|
|
83
|
+
setTimeout(() => {
|
|
84
|
+
setIsCheckShown(false);
|
|
85
|
+
}, 2000);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
e.persist(); // Persisting React's SyntheticEvent to be able to use it in any async context
|
|
89
|
+
!propagatePrimaryButtonClick && e.stopPropagation();
|
|
90
|
+
if (loader) {
|
|
91
|
+
setIsLoading(true);
|
|
92
|
+
setEvent(e);
|
|
93
|
+
} else {
|
|
94
|
+
onClick(() => setIsLoading(false), e);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const classNames =
|
|
99
|
+
`${styles.button} ${styles[size]} ${styles[className]} ${styles[mode]}` +
|
|
100
|
+
(fullWidthOnMobiles ? ` ${styles["full-width-on-mobiles"]}` : "") +
|
|
101
|
+
(fullWidthOnTablets ? ` ${styles["full-width-on-tablets"]}` : "") +
|
|
102
|
+
(isDisabled ? ` ${styles.disable}` : "") +
|
|
103
|
+
(smallPaddingOnSmallMobiles
|
|
104
|
+
? ` ${styles["small-padding-on-small-mobiles"]}`
|
|
105
|
+
: "");
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<>
|
|
109
|
+
{isFormSubmittingButton ? <input type="submit" hidden /> : null}
|
|
110
|
+
{to ? (
|
|
111
|
+
<Link
|
|
112
|
+
className={classNames}
|
|
113
|
+
onClick={(e) => handleError(buttonClick, e)}
|
|
114
|
+
to={to}
|
|
115
|
+
innerRef={buttonRef}
|
|
116
|
+
>
|
|
117
|
+
{icon ? (
|
|
118
|
+
<div
|
|
119
|
+
className={
|
|
120
|
+
styles["button-with-icon"] +
|
|
121
|
+
(bigIcon ? ` ${styles["big-icon"]}` : "")
|
|
122
|
+
}
|
|
123
|
+
>
|
|
124
|
+
<img src={icon} alt="button icon" />
|
|
125
|
+
<span className={styles["button-with-icon-text"]}>
|
|
126
|
+
{content}
|
|
127
|
+
</span>
|
|
128
|
+
</div>
|
|
129
|
+
) : (
|
|
130
|
+
content
|
|
131
|
+
)}
|
|
132
|
+
</Link>
|
|
133
|
+
) : (
|
|
134
|
+
<div
|
|
135
|
+
className={classNames}
|
|
136
|
+
onClick={(e) => handleError(buttonClick, e)}
|
|
137
|
+
ref={buttonRef}
|
|
138
|
+
>
|
|
139
|
+
<div
|
|
140
|
+
className={`${styles["button-primary-dots-wrapper"]} ${
|
|
141
|
+
isLoading && loader ? styles.show : ""
|
|
142
|
+
}`}
|
|
143
|
+
>
|
|
144
|
+
{loader && isLoading ? (
|
|
145
|
+
<LoadingDots isColored={mode === "white"} />
|
|
146
|
+
) : null}
|
|
147
|
+
</div>
|
|
148
|
+
<div
|
|
149
|
+
className={`${styles["button-success-icon"]} ${
|
|
150
|
+
styles[mode]
|
|
151
|
+
} ${isCheckShown ? styles["show"] : ""}`}
|
|
152
|
+
></div>
|
|
153
|
+
{icon ? (
|
|
154
|
+
<div
|
|
155
|
+
className={`${styles["button-with-icon"]} ${
|
|
156
|
+
(isLoading && loader) ||
|
|
157
|
+
(checkmarkOnClick && isCheckShown)
|
|
158
|
+
? styles["hide"]
|
|
159
|
+
: ""
|
|
160
|
+
} ${bigIcon ? styles["big-icon"] : ""}`}
|
|
161
|
+
>
|
|
162
|
+
<img src={icon} alt="button icon" />
|
|
163
|
+
<span className={styles["button-with-icon-text"]}>
|
|
164
|
+
{content}
|
|
165
|
+
</span>
|
|
166
|
+
</div>
|
|
167
|
+
) : (
|
|
168
|
+
<span
|
|
169
|
+
className={`${styles["button-text"]} ${
|
|
170
|
+
(isLoading && loader) ||
|
|
171
|
+
(checkmarkOnClick && isCheckShown)
|
|
172
|
+
? styles["hide"]
|
|
173
|
+
: ""
|
|
174
|
+
}`}
|
|
175
|
+
>
|
|
176
|
+
{content}
|
|
177
|
+
</span>
|
|
178
|
+
)}
|
|
179
|
+
</div>
|
|
180
|
+
)}
|
|
181
|
+
</>
|
|
182
|
+
);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
Button.propTypes = {
|
|
186
|
+
size: PropTypes.oneOf(["xl", "lg", "md", "sm"]),
|
|
187
|
+
className: PropTypes.string,
|
|
188
|
+
mode: PropTypes.oneOf([
|
|
189
|
+
"transparent",
|
|
190
|
+
"white",
|
|
191
|
+
"primary",
|
|
192
|
+
"primary-bordered",
|
|
193
|
+
"primary-transparent",
|
|
194
|
+
"transparent-bordered",
|
|
195
|
+
"transparent-without-shadow",
|
|
196
|
+
]),
|
|
197
|
+
onClick: PropTypes.func,
|
|
198
|
+
loader: PropTypes.bool,
|
|
199
|
+
loading: PropTypes.bool,
|
|
200
|
+
to: PropTypes.string,
|
|
201
|
+
fullWidthOnMobiles: PropTypes.bool,
|
|
202
|
+
fullWidthOnTablets: PropTypes.bool,
|
|
203
|
+
icon: PropTypes.string,
|
|
204
|
+
content: PropTypes.node,
|
|
205
|
+
isDisabled: PropTypes.bool,
|
|
206
|
+
setClickTrigger: PropTypes.func,
|
|
207
|
+
isFormSubmittingButton: PropTypes.bool,
|
|
208
|
+
bigIcon: PropTypes.bool,
|
|
209
|
+
checkmarkOnClick: PropTypes.bool,
|
|
210
|
+
propagatePrimaryButtonClick: PropTypes.bool,
|
|
211
|
+
smallPaddingOnSmallMobiles: PropTypes.bool,
|
|
212
|
+
handleError: PropTypes.func,
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
Button.defaultProps = {
|
|
216
|
+
size: "xl",
|
|
217
|
+
className: "",
|
|
218
|
+
mode: "transparent",
|
|
219
|
+
onClick: (resetButtonLoader, event) => {},
|
|
220
|
+
loader: true,
|
|
221
|
+
loading: false,
|
|
222
|
+
to: "",
|
|
223
|
+
fullWidthOnMobiles: false,
|
|
224
|
+
fullWidthOnTablets: false,
|
|
225
|
+
icon: "",
|
|
226
|
+
content: "",
|
|
227
|
+
isDisabled: false,
|
|
228
|
+
setClickTrigger: (p) => {},
|
|
229
|
+
isFormSubmittingButton: false,
|
|
230
|
+
bigIcon: false,
|
|
231
|
+
checkmarkOnClick: false,
|
|
232
|
+
propagatePrimaryButtonClick: true,
|
|
233
|
+
smallPaddingOnSmallMobiles: false,
|
|
234
|
+
handleError: (func) => func(),
|
|
235
|
+
};
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
@import "../../../../styles/index";
|
|
2
|
+
|
|
3
|
+
.button {
|
|
4
|
+
@extend %text-very-bold;
|
|
5
|
+
@extend %hover-state;
|
|
6
|
+
transition-property: all;
|
|
7
|
+
transition-duration: 0.1s;
|
|
8
|
+
font-size: 16px;
|
|
9
|
+
-webkit-border-radius: 200px;
|
|
10
|
+
-moz-border-radius: 200px;
|
|
11
|
+
border-radius: 200px;
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
text-decoration: none;
|
|
16
|
+
white-space: nowrap;
|
|
17
|
+
position: relative;
|
|
18
|
+
user-select: none;
|
|
19
|
+
|
|
20
|
+
&.disable {
|
|
21
|
+
&,
|
|
22
|
+
&:hover,
|
|
23
|
+
&:active {
|
|
24
|
+
background-color: LightColor("grey-20") !important;
|
|
25
|
+
color: SolidColor("grey") !important;
|
|
26
|
+
cursor: default !important;
|
|
27
|
+
box-shadow: none !important;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@media (max-width: $tablet-width) {
|
|
32
|
+
&.full-width-on-tablets {
|
|
33
|
+
max-width: 100%;
|
|
34
|
+
width: 100%;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@media (max-width: $phone-width) {
|
|
39
|
+
font-size: 14px;
|
|
40
|
+
&.full-width-on-mobiles {
|
|
41
|
+
max-width: 100%;
|
|
42
|
+
width: 100%;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&.xl {
|
|
47
|
+
height: 66px;
|
|
48
|
+
padding: 0 64px;
|
|
49
|
+
@media (max-width: $phone-width) {
|
|
50
|
+
height: 48px;
|
|
51
|
+
padding: 0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&.lg {
|
|
56
|
+
font-size: 14px;
|
|
57
|
+
height: 48px;
|
|
58
|
+
padding: 0 48px;
|
|
59
|
+
@media (max-width: $phone-width) {
|
|
60
|
+
height: 40px;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
&.md {
|
|
64
|
+
height: 40px;
|
|
65
|
+
font-size: 14px;
|
|
66
|
+
padding: 0 32px;
|
|
67
|
+
}
|
|
68
|
+
&.sm {
|
|
69
|
+
height: 35px;
|
|
70
|
+
font-size: 12px;
|
|
71
|
+
padding: 0 24px;
|
|
72
|
+
|
|
73
|
+
// This is somewhat of a hack, which should absolutely be refactored with a better layout
|
|
74
|
+
&.small-padding-on-small-mobiles {
|
|
75
|
+
@media (max-width: 415px) {
|
|
76
|
+
padding: 0 18px;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
&.primary {
|
|
82
|
+
box-shadow: 0 20px 40px 0 rgba(11, 137, 143, 0.39);
|
|
83
|
+
background: SolidColor(tosca);
|
|
84
|
+
color: $white;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&.primary-bordered {
|
|
88
|
+
border: $buttonBorder;
|
|
89
|
+
color: SolidColor(tosca);
|
|
90
|
+
&:hover {
|
|
91
|
+
background-color: LightColor("tosca-20");
|
|
92
|
+
transition-duration: 0.02s;
|
|
93
|
+
opacity: 1;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
&.primary-transparent {
|
|
98
|
+
background: LightColor(army-20);
|
|
99
|
+
color: SolidColor(tosca);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&.transparent {
|
|
103
|
+
background: LightColor(white-20);
|
|
104
|
+
color: $white;
|
|
105
|
+
box-shadow: 0 23px 30px 0 rgba(0, 102, 107, 0.39);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&.transparent-bordered {
|
|
109
|
+
border: $buttonBorderWhite;
|
|
110
|
+
color: $white;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
&.transparent-without-shadow {
|
|
114
|
+
background: transparent;
|
|
115
|
+
border-color: transparent;
|
|
116
|
+
color: SolidColor(tosca);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
&.white {
|
|
120
|
+
background: $white;
|
|
121
|
+
color: #39448e;
|
|
122
|
+
box-shadow: 0 20px 20px rgba(15, 24, 75, 0.2);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
&-primary-dots-wrapper {
|
|
126
|
+
position: absolute;
|
|
127
|
+
top: 50%;
|
|
128
|
+
left: 50%;
|
|
129
|
+
transform: translate(-50%, -50%) scale(1.15);
|
|
130
|
+
transition: all 0.1s $transitionEaseOut;
|
|
131
|
+
opacity: 0;
|
|
132
|
+
|
|
133
|
+
&.show {
|
|
134
|
+
opacity: 1;
|
|
135
|
+
transform: translate(-50%, -50%) scale(1);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
&-success-icon {
|
|
140
|
+
position: absolute;
|
|
141
|
+
top: 50%;
|
|
142
|
+
left: 50%;
|
|
143
|
+
opacity: 0;
|
|
144
|
+
width: 20px;
|
|
145
|
+
height: 20px;
|
|
146
|
+
transform: translate(-50%, -50%) scale(1.4);
|
|
147
|
+
transition: all 0.1s $transitionEaseOut;
|
|
148
|
+
display: flex;
|
|
149
|
+
justify-content: center;
|
|
150
|
+
align-items: center;
|
|
151
|
+
|
|
152
|
+
&.show {
|
|
153
|
+
opacity: 1;
|
|
154
|
+
transform: translate(-50%, -50%) scale(1);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
&::after {
|
|
158
|
+
content: " ";
|
|
159
|
+
display: inline-block;
|
|
160
|
+
transform: rotate(45deg);
|
|
161
|
+
height: 10px;
|
|
162
|
+
width: 5px;
|
|
163
|
+
border-bottom: 3px solid SolidColor(tosca);
|
|
164
|
+
border-right: 3px solid SolidColor(tosca);
|
|
165
|
+
margin-top: -4px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
&.transparent-bordered::after,
|
|
169
|
+
&.transparent::after,
|
|
170
|
+
&.primary::after {
|
|
171
|
+
border-color: $white;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
&.primary-bordered::after,
|
|
175
|
+
&.primary-transparent::after,
|
|
176
|
+
&.transparent-without-shadow::after {
|
|
177
|
+
border-color: SolidColor(tosca);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
&-text {
|
|
182
|
+
user-select: none;
|
|
183
|
+
transform: scale(1);
|
|
184
|
+
transition: all 0.1s $transitionEaseOut;
|
|
185
|
+
&.hide {
|
|
186
|
+
opacity: 0;
|
|
187
|
+
transform: scale(0.9);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.button-with-icon {
|
|
192
|
+
display: flex;
|
|
193
|
+
align-items: center;
|
|
194
|
+
transform: scale(1);
|
|
195
|
+
transition: all 0.1s $transitionEaseOut;
|
|
196
|
+
|
|
197
|
+
&.hide {
|
|
198
|
+
opacity: 0;
|
|
199
|
+
transform: scale(0.9);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
&-text {
|
|
203
|
+
margin-left: Margin("3");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
&.big-icon {
|
|
207
|
+
img {
|
|
208
|
+
height: 24px;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
package/stories/index.js
ADDED