@woosmap/ui 2.45.0 → 2.49.0
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/package.json +1 -1
- package/src/components/Button/Button.js +7 -2
- package/src/components/Button/Button.stories.js +2 -2
- package/src/components/Dropdown/Dropdown.js +77 -3
- package/src/components/Dropdown/Dropdown.stories.js +29 -0
- package/src/components/Dropdown/Dropdown.styl +3 -0
- package/src/components/Icon/Icon.js +2 -0
- package/src/components/Modal/Modal.js +24 -0
- package/src/components/Modal/Modal.stories.js +12 -0
- package/src/components/Modal/Modal.test.js +18 -2
- package/src/icons/arrow-link.svg +1 -0
- package/src/styles/console/button.styl +29 -9
package/package.json
CHANGED
|
@@ -25,12 +25,14 @@ export default class Button extends Component {
|
|
|
25
25
|
active,
|
|
26
26
|
children,
|
|
27
27
|
testId,
|
|
28
|
+
iconRight,
|
|
28
29
|
...rest
|
|
29
30
|
} = this.props;
|
|
30
31
|
const classes = cl(
|
|
31
32
|
'btn',
|
|
32
33
|
{ 'btn--has-icon': icon || isLoading },
|
|
33
34
|
{ 'btn--icon': isBtnIcon || (icon && !label) },
|
|
35
|
+
{ 'btn--icon-right': iconRight },
|
|
34
36
|
size ? `btn--${size}` : null,
|
|
35
37
|
type ? `btn--${type}` : null,
|
|
36
38
|
{ active },
|
|
@@ -54,8 +56,9 @@ export default class Button extends Component {
|
|
|
54
56
|
className={classes}
|
|
55
57
|
data-testid={testId}
|
|
56
58
|
>
|
|
57
|
-
{iconComponent}
|
|
59
|
+
{!iconRight ? iconComponent : null}
|
|
58
60
|
{label && <span className="btn__label">{isLoading ? tr('Loading...') : label}</span>}
|
|
61
|
+
{iconRight ? iconComponent : null}
|
|
59
62
|
{children}
|
|
60
63
|
</button>
|
|
61
64
|
);
|
|
@@ -76,6 +79,7 @@ Button.defaultProps = {
|
|
|
76
79
|
isLoading: false,
|
|
77
80
|
active: false,
|
|
78
81
|
onClick: null,
|
|
82
|
+
iconRight: false,
|
|
79
83
|
};
|
|
80
84
|
|
|
81
85
|
Button.propTypes = {
|
|
@@ -104,10 +108,11 @@ Button.propTypes = {
|
|
|
104
108
|
]),
|
|
105
109
|
isLoading: PropTypes.bool,
|
|
106
110
|
active: PropTypes.bool,
|
|
107
|
-
label: PropTypes.string,
|
|
111
|
+
label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
108
112
|
icon: PropTypes.string,
|
|
109
113
|
iconSize: PropTypes.number,
|
|
110
114
|
className: PropTypes.string,
|
|
111
115
|
onClick: PropTypes.func,
|
|
112
116
|
children: PropTypes.node,
|
|
117
|
+
iconRight: PropTypes.bool,
|
|
113
118
|
};
|
|
@@ -23,7 +23,7 @@ const Template = (args) => {
|
|
|
23
23
|
<div className="flex mbi">
|
|
24
24
|
<Button icon="add" />
|
|
25
25
|
<Button label={label} />
|
|
26
|
-
<Button label={label} icon="marker" />
|
|
26
|
+
<Button label={label} icon="marker" iconRight />
|
|
27
27
|
<Button label={label} isLoading />
|
|
28
28
|
<Button label={label} disabled />
|
|
29
29
|
</div>
|
|
@@ -82,7 +82,7 @@ const Template = (args) => {
|
|
|
82
82
|
</span>
|
|
83
83
|
<span>
|
|
84
84
|
There is a labeled and iconed button link here :
|
|
85
|
-
<Button label={label} icon="marker" type="link" />
|
|
85
|
+
<Button label={label} icon="marker" iconRight type="link" />
|
|
86
86
|
</span>
|
|
87
87
|
<span>
|
|
88
88
|
There is a iconed button link here : <Button label={label} icon="clock" type="link" />
|
|
@@ -45,9 +45,20 @@ class DropdownMenu extends Component {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
render() {
|
|
48
|
-
const { direction, children, closeCb, testId, ...rest } = this.props;
|
|
48
|
+
const { direction, children, closeCb, testId, isSection, ...rest } = this.props;
|
|
49
49
|
const childrenWithProps = mapChildrenWithProps(children, this.childrenRefs, closeCb);
|
|
50
|
-
|
|
50
|
+
if (isSection) {
|
|
51
|
+
return (
|
|
52
|
+
<div
|
|
53
|
+
role="menu"
|
|
54
|
+
className={cl('dropdown__menu', direction, 'dropdown__menu--section')}
|
|
55
|
+
data-testid={testId}
|
|
56
|
+
{...rest}
|
|
57
|
+
>
|
|
58
|
+
{childrenWithProps}
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
51
62
|
return (
|
|
52
63
|
<ul role="menu" className={cl('dropdown__menu', direction)} data-testid={testId} {...rest}>
|
|
53
64
|
{childrenWithProps}
|
|
@@ -60,15 +71,50 @@ DropdownMenu.defaultProps = {
|
|
|
60
71
|
direction: 'sw',
|
|
61
72
|
closeCb: null,
|
|
62
73
|
testId: 'dropdown-menu',
|
|
74
|
+
isSection: false,
|
|
63
75
|
};
|
|
64
76
|
|
|
65
77
|
DropdownMenu.propTypes = {
|
|
66
78
|
children: PropTypes.node.isRequired,
|
|
67
79
|
closeCb: PropTypes.func,
|
|
68
80
|
testId: PropTypes.string,
|
|
81
|
+
isSection: PropTypes.bool,
|
|
69
82
|
direction: PropTypes.oneOf(['ne', 'e', 'se', 's', 'sw', 'w']),
|
|
70
83
|
};
|
|
71
84
|
|
|
85
|
+
class DropdownMenuSection extends Component {
|
|
86
|
+
constructor(props) {
|
|
87
|
+
super(props);
|
|
88
|
+
this.childrenRefs = {};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
close = () => {
|
|
92
|
+
closeChildren(this.childrenRefs);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
render() {
|
|
96
|
+
const { title, children, closeCb, ...rest } = this.props;
|
|
97
|
+
const childrenWithProps = mapChildrenWithProps(children, this.childrenRefs, closeCb);
|
|
98
|
+
return (
|
|
99
|
+
<div className="dropdown__menu__section">
|
|
100
|
+
{title && <div className="dropdown__menu__section__title">{title}</div>}
|
|
101
|
+
<ul {...rest}>{childrenWithProps}</ul>
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
DropdownMenuSection.defaultProps = {
|
|
108
|
+
title: null,
|
|
109
|
+
closeCb: null,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
DropdownMenuSection.propTypes = {
|
|
113
|
+
children: PropTypes.node.isRequired,
|
|
114
|
+
title: PropTypes.string,
|
|
115
|
+
closeCb: PropTypes.func,
|
|
116
|
+
};
|
|
117
|
+
|
|
72
118
|
class DropdownSeparator extends Component {
|
|
73
119
|
render() {
|
|
74
120
|
const { testId } = this.props;
|
|
@@ -243,6 +289,28 @@ class Dropdown extends Component {
|
|
|
243
289
|
this.setOpen(false);
|
|
244
290
|
};
|
|
245
291
|
|
|
292
|
+
onMouseEnter = () => {
|
|
293
|
+
const { openOnMouseEnter } = this.props;
|
|
294
|
+
if (openOnMouseEnter) {
|
|
295
|
+
if (this.mouseLeaveTimeout) {
|
|
296
|
+
clearTimeout(this.mouseLeaveTimeout);
|
|
297
|
+
}
|
|
298
|
+
this.setOpen(true);
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
onMouseLeave = () => {
|
|
303
|
+
const { openOnMouseEnter } = this.props;
|
|
304
|
+
if (openOnMouseEnter) {
|
|
305
|
+
if (this.mouseLeaveTimeout) {
|
|
306
|
+
clearTimeout(this.mouseLeaveTimeout);
|
|
307
|
+
}
|
|
308
|
+
this.mouseLeaveTimeout = setTimeout(() => {
|
|
309
|
+
this.setOpen(false);
|
|
310
|
+
}, 500);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
|
|
246
314
|
onClick = (e) => {
|
|
247
315
|
const { onClick } = this.props;
|
|
248
316
|
const { open } = this.state;
|
|
@@ -273,6 +341,7 @@ class Dropdown extends Component {
|
|
|
273
341
|
closeCb,
|
|
274
342
|
disableCloseOutside,
|
|
275
343
|
testId,
|
|
344
|
+
openOnMouseEnter,
|
|
276
345
|
...rest
|
|
277
346
|
} = this.props;
|
|
278
347
|
const { open } = this.state;
|
|
@@ -283,6 +352,8 @@ class Dropdown extends Component {
|
|
|
283
352
|
ref={this.clickOutsideRef}
|
|
284
353
|
className={cl('dropdown', { open }, `dropdown--${size}`, className)}
|
|
285
354
|
{...rest}
|
|
355
|
+
onMouseEnter={this.onMouseEnter}
|
|
356
|
+
onMouseLeave={this.onMouseLeave}
|
|
286
357
|
>
|
|
287
358
|
<Button
|
|
288
359
|
disabled={disabled}
|
|
@@ -311,6 +382,7 @@ Dropdown.defaultProps = {
|
|
|
311
382
|
label: null,
|
|
312
383
|
className: null,
|
|
313
384
|
closeCb: null,
|
|
385
|
+
openOnMouseEnter: false,
|
|
314
386
|
btnFace: 'link-flex',
|
|
315
387
|
btnFaceIcon: 'caret-bottom',
|
|
316
388
|
btnFaceIconSize: 24,
|
|
@@ -323,7 +395,8 @@ Dropdown.propTypes = {
|
|
|
323
395
|
onDoubleClick: PropTypes.func,
|
|
324
396
|
disabled: PropTypes.bool,
|
|
325
397
|
disableCloseOutside: PropTypes.bool,
|
|
326
|
-
|
|
398
|
+
openOnMouseEnter: PropTypes.bool,
|
|
399
|
+
label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
327
400
|
testId: PropTypes.string,
|
|
328
401
|
children: PropTypes.node.isRequired,
|
|
329
402
|
className: PropTypes.string,
|
|
@@ -336,6 +409,7 @@ Dropdown.propTypes = {
|
|
|
336
409
|
|
|
337
410
|
export default Object.assign(withClickOutside(Dropdown, '.popover__content'), {
|
|
338
411
|
Menu: DropdownMenu,
|
|
412
|
+
MenuSection: DropdownMenuSection,
|
|
339
413
|
Item: DropdownItem,
|
|
340
414
|
ButtonItem: DropdownButtonItem,
|
|
341
415
|
ConfirmButtonItem: DropdownConfirmButtonItem,
|
|
@@ -52,3 +52,32 @@ const Template = () => (
|
|
|
52
52
|
);
|
|
53
53
|
export const Default = Template.bind({});
|
|
54
54
|
Default.args = {};
|
|
55
|
+
|
|
56
|
+
const MultiMenuTemplate = () => (
|
|
57
|
+
<div className="mbi" id="menuid">
|
|
58
|
+
<Dropdown btnFace="link" btnFaceIcon="clock" label="My dropdown" openOnMouseEnter>
|
|
59
|
+
<Dropdown.Menu isSection direction="se">
|
|
60
|
+
<Dropdown.MenuSection title="Section title">
|
|
61
|
+
<Dropdown.ButtonItem btnIcon="delete" isImportant btnLabel="Delete" />
|
|
62
|
+
<Dropdown.ConfirmButtonItem
|
|
63
|
+
btnIcon="delete"
|
|
64
|
+
isImportant
|
|
65
|
+
btnLabel="Delete confirm"
|
|
66
|
+
onConfirm={() => null}
|
|
67
|
+
/>
|
|
68
|
+
</Dropdown.MenuSection>
|
|
69
|
+
<Dropdown.MenuSection title="Section title 2">
|
|
70
|
+
<Dropdown.ButtonItem btnIcon="delete" isImportant btnLabel="Delete" />
|
|
71
|
+
<Dropdown.ConfirmButtonItem
|
|
72
|
+
btnIcon="delete"
|
|
73
|
+
isImportant
|
|
74
|
+
btnLabel="Delete confirm"
|
|
75
|
+
onConfirm={() => null}
|
|
76
|
+
/>
|
|
77
|
+
</Dropdown.MenuSection>
|
|
78
|
+
</Dropdown.Menu>
|
|
79
|
+
</Dropdown>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
export const MultiMenuTemplateDropdown = MultiMenuTemplate.bind({});
|
|
83
|
+
MultiMenuTemplateDropdown.args = {};
|
|
@@ -16,6 +16,7 @@ import { ReactComponent as ArrowBotton } from '../../icons/arrow-bottom.svg';
|
|
|
16
16
|
import { ReactComponent as ArrowLeft } from '../../icons/arrow-left.svg';
|
|
17
17
|
import { ReactComponent as ArrowRight } from '../../icons/arrow-right.svg';
|
|
18
18
|
import { ReactComponent as ArrowTop } from '../../icons/arrow-top.svg';
|
|
19
|
+
import { ReactComponent as ArrowLink } from '../../icons/arrow-link.svg';
|
|
19
20
|
import { ReactComponent as Asset } from '../../icons/asset.svg';
|
|
20
21
|
import { ReactComponent as AssetAddFile } from '../../icons/asset-add-file.svg';
|
|
21
22
|
import { ReactComponent as AssetAdd } from '../../icons/asset-add.svg';
|
|
@@ -134,6 +135,7 @@ const Icons = {
|
|
|
134
135
|
'arrow-left': ArrowLeft,
|
|
135
136
|
'arrow-right': ArrowRight,
|
|
136
137
|
'arrow-top': ArrowTop,
|
|
138
|
+
'arrow-link': ArrowLink,
|
|
137
139
|
asset: Asset,
|
|
138
140
|
'asset-add-file': AssetAddFile,
|
|
139
141
|
'asset-add': AssetAdd,
|
|
@@ -15,6 +15,10 @@ class Modal extends Component {
|
|
|
15
15
|
this.modalRef = React.createRef();
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
componentDidMount() {
|
|
19
|
+
this.handleEscFunction('add');
|
|
20
|
+
}
|
|
21
|
+
|
|
18
22
|
componentDidUpdate() {
|
|
19
23
|
const { isLoading } = this.state;
|
|
20
24
|
const { hasErrors } = this.props;
|
|
@@ -23,6 +27,10 @@ class Modal extends Component {
|
|
|
23
27
|
}
|
|
24
28
|
}
|
|
25
29
|
|
|
30
|
+
componentWillUnmount() {
|
|
31
|
+
this.handleEscFunction();
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
handleClickOutside = () => {
|
|
27
35
|
this.close();
|
|
28
36
|
};
|
|
@@ -31,6 +39,20 @@ class Modal extends Component {
|
|
|
31
39
|
this.setState({ isLoading: loading });
|
|
32
40
|
}
|
|
33
41
|
|
|
42
|
+
handleEscFunction = (key) => {
|
|
43
|
+
const { closesWithEscape } = this.props;
|
|
44
|
+
if (closesWithEscape) {
|
|
45
|
+
if (key === 'add') document.addEventListener('keydown', this.escFunction, false);
|
|
46
|
+
else document.removeEventListener('keydown', this.escFunction, false);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
escFunction = (event) => {
|
|
51
|
+
if (event.keyCode === 27) {
|
|
52
|
+
this.close();
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
34
56
|
open = () => {
|
|
35
57
|
this.setState({ open: true });
|
|
36
58
|
};
|
|
@@ -141,6 +163,7 @@ Modal.defaultProps = {
|
|
|
141
163
|
validateBtnProps: {},
|
|
142
164
|
mainButtonType: 'primary',
|
|
143
165
|
testId: 'modal',
|
|
166
|
+
closesWithEscape: false,
|
|
144
167
|
};
|
|
145
168
|
|
|
146
169
|
Modal.propTypes = {
|
|
@@ -160,6 +183,7 @@ Modal.propTypes = {
|
|
|
160
183
|
validateBtnProps: PropTypes.object,
|
|
161
184
|
mainButtonType: PropTypes.string,
|
|
162
185
|
testId: PropTypes.string,
|
|
186
|
+
closesWithEscape: PropTypes.bool,
|
|
163
187
|
};
|
|
164
188
|
|
|
165
189
|
export default withClickOutside(Modal, '.ignore-click-outside-modal');
|
|
@@ -78,3 +78,15 @@ const TemplateConfirmationModal = () => {
|
|
|
78
78
|
};
|
|
79
79
|
export const ModalConfirmation = TemplateConfirmationModal.bind({});
|
|
80
80
|
Default.args = {};
|
|
81
|
+
|
|
82
|
+
const TemplateEscapeModal = () => {
|
|
83
|
+
const modalRef = React.createRef();
|
|
84
|
+
return (
|
|
85
|
+
<div style={{ paddingLeft: '50px' }}>
|
|
86
|
+
<Button onClick={() => modalRef.current.open()} label="Open modal" />
|
|
87
|
+
<Modal ref={modalRef} closesWithEscape title="My modal" />
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
export const ModalEscape = TemplateEscapeModal.bind({});
|
|
92
|
+
Default.args = {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
3
3
|
import '@testing-library/jest-dom/extend-expect';
|
|
4
4
|
import { act } from 'react-dom/test-utils';
|
|
5
5
|
import userEvent from '@testing-library/user-event';
|
|
@@ -56,7 +56,7 @@ it('is hidden after clicking cancel', () => {
|
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
it('is hidden after clicking
|
|
59
|
+
it('is hidden after clicking validate', () => {
|
|
60
60
|
const modalRef = React.createRef();
|
|
61
61
|
const validateCb = jest.fn();
|
|
62
62
|
render(
|
|
@@ -72,3 +72,19 @@ it('is hidden after clicking cancel', () => {
|
|
|
72
72
|
userEvent.click(validate);
|
|
73
73
|
expect(validateCb.mock.calls.length).toBe(1);
|
|
74
74
|
});
|
|
75
|
+
|
|
76
|
+
it('is closing after escaping if it is set to be closed with it', () => {
|
|
77
|
+
const modalRef = React.createRef();
|
|
78
|
+
const closeCb = jest.fn();
|
|
79
|
+
render(
|
|
80
|
+
<Modal ref={modalRef} closesWithEscape closeCb={closeCb}>
|
|
81
|
+
content
|
|
82
|
+
</Modal>
|
|
83
|
+
);
|
|
84
|
+
act(() => {
|
|
85
|
+
modalRef.current.open();
|
|
86
|
+
});
|
|
87
|
+
expect(closeCb).not.toHaveBeenCalled();
|
|
88
|
+
fireEvent.keyDown(document, { keyCode: 27 });
|
|
89
|
+
expect(closeCb).toHaveBeenCalled();
|
|
90
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m20.217 11.6-4.708-4.7a.56.56 0 1 0-.792.792l3.753 3.748H4.179a.56.56 0 1 0 0 1.12H18.47l-3.753 3.752a.56.56 0 0 0 .792.792l4.708-4.704a.559.559 0 0 0 0-.8Z"/></svg>
|
|
@@ -256,8 +256,12 @@
|
|
|
256
256
|
padding 0
|
|
257
257
|
text-decoration none
|
|
258
258
|
&.btn--has-icon
|
|
259
|
-
.icon
|
|
260
|
-
|
|
259
|
+
&:not(.btn--icon-right)
|
|
260
|
+
.icon
|
|
261
|
+
margin-right .3rem
|
|
262
|
+
&.btn--icon-right
|
|
263
|
+
.icon
|
|
264
|
+
margin-left .3rem
|
|
261
265
|
&--link
|
|
262
266
|
&--link-primary
|
|
263
267
|
&--link-info
|
|
@@ -265,15 +269,28 @@
|
|
|
265
269
|
trans()
|
|
266
270
|
position relative
|
|
267
271
|
top .7rem
|
|
268
|
-
|
|
269
|
-
&.btn--small
|
|
272
|
+
&:not(.btn--icon-right)
|
|
270
273
|
.icon
|
|
271
|
-
top .5rem
|
|
272
274
|
left -.3rem
|
|
273
|
-
|
|
275
|
+
&.btn--small
|
|
276
|
+
.icon
|
|
277
|
+
top .5rem
|
|
278
|
+
left -.3rem
|
|
279
|
+
&.btn--large
|
|
280
|
+
.icon
|
|
281
|
+
top 1.2rem
|
|
282
|
+
left -.3rem
|
|
283
|
+
&.btn--icon-right
|
|
274
284
|
.icon
|
|
275
|
-
|
|
276
|
-
|
|
285
|
+
right -.3rem
|
|
286
|
+
&.btn--small
|
|
287
|
+
.icon
|
|
288
|
+
top .5rem
|
|
289
|
+
rigth -.3rem
|
|
290
|
+
&.btn--large
|
|
291
|
+
.icon
|
|
292
|
+
top 1.2rem
|
|
293
|
+
rigth -.3rem
|
|
277
294
|
&--link-flex
|
|
278
295
|
&--link-flex-info
|
|
279
296
|
display flex
|
|
@@ -340,8 +357,11 @@
|
|
|
340
357
|
trans()
|
|
341
358
|
|
|
342
359
|
&--has-icon
|
|
343
|
-
&:not(.btn--icon):not(.btn--link):not(.btn--link-primary):not(.btn--link-info):not(.btn--link-flex):not(.btn--link-flex-info):not(.btn--loading):not(.btn--mini):not(.btn--small):not(.btn--large):not(.btn--dropdown-item):not(.btn--tab):not(.btn--sidebar-link)
|
|
360
|
+
&:not(.btn--icon):not(.btn--link):not(.btn--link-primary):not(.btn--link-info):not(.btn--link-flex):not(.btn--link-flex-info):not(.btn--loading):not(.btn--mini):not(.btn--small):not(.btn--large):not(.btn--dropdown-item):not(.btn--tab):not(.btn--sidebar-link):not(.btn--icon-right)
|
|
344
361
|
padding 0 $padding 0 $padding - .6
|
|
362
|
+
&:not(.btn--icon):not(.btn--link):not(.btn--link-primary):not(.btn--link-info):not(.btn--link-flex):not(.btn--link-flex-info):not(.btn--loading):not(.btn--mini):not(.btn--small):not(.btn--large):not(.btn--dropdown-item):not(.btn--tab):not(.btn--sidebar-link)
|
|
363
|
+
&.btn--icon-right
|
|
364
|
+
padding 0 $padding - .6 0 $padding
|
|
345
365
|
&--loading
|
|
346
366
|
&:not(.btn--icon):not(.btn--mini):not(.btn--small):not(.btn--large):not(.btn--sidebar-link)
|
|
347
367
|
padding-left $padding - .4
|