@bethinkpl/design-system 37.1.0 → 38.0.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/dist/design-system.css +1 -1
- package/dist/design-system.js +6422 -6340
- package/dist/design-system.js.map +1 -1
- package/dist/lib/js/components/Buttons/Button/Button.consts.d.ts +1 -0
- package/dist/lib/js/components/Buttons/Button/useMagicGradient.d.ts +5 -0
- package/dist/lib/js/components/Buttons/IconButton/IconButton.consts.d.ts +1 -0
- package/dist/lib/js/components/Buttons/IconButton/IconButton.vue.d.ts +7 -2
- package/dist/lib/js/components/Cards/CardExpandable/CardExpandable.vue.d.ts +2 -0
- package/dist/lib/js/components/DatePickers/DateBox/DateBox.vue.d.ts +2 -0
- package/dist/lib/js/components/DatePickers/DatePicker/DatePicker.vue.d.ts +2 -0
- package/dist/lib/js/components/DatePickers/DateRangePicker/DateRangePicker.vue.d.ts +2 -0
- package/dist/lib/js/components/Drawer/DrawerHeader/DrawerHeader.vue.d.ts +7 -0
- package/dist/lib/js/components/Drawer/DrawerListItem/DrawerListItem.vue.d.ts +2 -0
- package/dist/lib/js/components/Drawer/DrawerSection/DrawerSection.vue.d.ts +11 -0
- package/dist/lib/js/components/Form/RadioButton/RadioButton.vue.d.ts +2 -0
- package/dist/lib/js/components/Headers/OverlayHeader/OverlayHeader.vue.d.ts +8 -0
- package/dist/lib/js/components/Headers/SectionHeader/SectionHeader.vue.d.ts +8 -0
- package/dist/lib/js/components/Icons/Icon/Icon.consts.d.ts +2 -0
- package/dist/lib/js/components/Modal/Modal.vue.d.ts +2 -0
- package/dist/lib/js/components/Modals/Modal/Modal.vue.d.ts +9 -0
- package/dist/lib/js/components/Modals/ModalDialog/ModalDialog.vue.d.ts +9 -0
- package/dist/lib/js/components/Pagination/Pagination.vue.d.ts +8 -0
- package/dist/lib/js/components/ProgressBar/ProgressBar.vue.d.ts +2 -0
- package/dist/lib/js/components/ProgressDonutChart/ProgressDonutChart.vue.d.ts +2 -0
- package/dist/lib/js/components/RichList/BasicRichListItem/BasicRichListItem.vue.d.ts +2 -0
- package/dist/lib/js/components/RichList/RichListItem/RichListItem.vue.d.ts +2 -0
- package/dist/lib/js/components/Statuses/AccessStatus/AccessStatus.vue.d.ts +2 -0
- package/dist/lib/js/components/Statuses/BlockadeStatus/BlockadeStatus.vue.d.ts +2 -0
- package/dist/lib/js/components/SurveyQuestions/SurveyQuestionOpenEnded/SurveyQuestionOpenEnded.vue.d.ts +10 -0
- package/dist/lib/js/components/SurveyQuestions/SurveyQuestionScale/SurveyQuestionScale.vue.d.ts +10 -0
- package/dist/lib/js/components/Switch/Switch.vue.d.ts +2 -0
- package/dist/lib/js/components/Tile/Tile.sb.shared.d.ts +2 -0
- package/dist/lib/js/components/Toast/Toast.vue.d.ts +1 -0
- package/dist/lib/js/components/Toggles/ToggleButton/ToggleButton.vue.d.ts +2 -0
- package/dist/lib/js/icons/fontawesome.d.ts +2 -0
- package/lib/js/components/Buttons/Button/Button.consts.ts +1 -0
- package/lib/js/components/Buttons/Button/Button.spec.ts +35 -0
- package/lib/js/components/Buttons/Button/Button.vue +19 -0
- package/lib/js/components/Buttons/Button/useMagicGradient.spec.ts +47 -0
- package/lib/js/components/Buttons/Button/useMagicGradient.ts +50 -0
- package/lib/js/components/Buttons/IconButton/IconButton.consts.ts +1 -0
- package/lib/js/components/Buttons/IconButton/IconButton.spec.ts +107 -0
- package/lib/js/components/Buttons/IconButton/IconButton.stories.ts +5 -1
- package/lib/js/components/Buttons/IconButton/IconButton.vue +45 -5
- package/lib/js/components/DatePickers/DatePicker/DatePicker.vue +5 -0
- package/lib/js/components/DatePickers/DateRangePicker/DateRangePicker.vue +5 -0
- package/lib/js/icons/fontawesome.ts +4 -0
- package/lib/styles/components/_buttons.scss +96 -1
- package/lib/styles/design-system.scss +9 -3
- package/lib/styles/mixins/_scrollbars.scss +6 -2
- package/lib/styles/settings/_gradients-variables.scss +34 -0
- package/lib/styles/settings/_gradients.scss +4 -0
- package/lib/styles/settings/colors/_magic-variables.scss +10 -0
- package/lib/styles/settings/colors/_magic.scss +9 -0
- package/lib/styles/settings/colors/_raw-bodywork-dark.scss +22 -0
- package/lib/styles/settings/colors/_raw-mc-dark.scss +22 -0
- package/lib/styles/settings/colors/_raw-wnl-dark.scss +22 -0
- package/lib/styles/settings/colors/_raw.json +1 -1
- package/lib/styles/settings/colors/_raw.scss +26 -0
- package/lib/styles/settings/colors/_tokens-variables-dark.scss +513 -0
- package/package.json +1 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { toValue, watch, type MaybeRefOrGetter } from 'vue';
|
|
2
|
+
|
|
3
|
+
export const GRADIENT_MAGIC_ICON_ID = 'ds-gradient-magic-icon';
|
|
4
|
+
export const GRADIENT_MAGIC_ICON_DISABLED_ID = 'ds-gradient-magic-icon-disabled';
|
|
5
|
+
|
|
6
|
+
// SVG icons (the loading spinner) fill with the magic gradient via `fill: url(#...)`, which
|
|
7
|
+
// CSS gradients can't do. The gradient is identical for every magic button, so a single
|
|
8
|
+
// shared def is injected into <body> once and left for the page lifetime (invisible, 0×0).
|
|
9
|
+
function ensureMagicGradientDef(): void {
|
|
10
|
+
if (typeof document === 'undefined') {
|
|
11
|
+
return; // SSR guard
|
|
12
|
+
}
|
|
13
|
+
if (document.getElementById(GRADIENT_MAGIC_ICON_ID)) {
|
|
14
|
+
return; // already injected
|
|
15
|
+
}
|
|
16
|
+
// `var()` works in the `style` property but not in the `stop-color` presentation
|
|
17
|
+
// attribute, so stop colors are set inline.
|
|
18
|
+
document.body.insertAdjacentHTML(
|
|
19
|
+
'beforeend',
|
|
20
|
+
`<svg aria-hidden="true" width="0" height="0" style="position:absolute">
|
|
21
|
+
<defs>
|
|
22
|
+
<linearGradient id="${GRADIENT_MAGIC_ICON_ID}" x1="0" y1="0" x2="1" y2="0.17">
|
|
23
|
+
<stop offset="7%" style="stop-color:var(--gradient-magic-color-1)"/>
|
|
24
|
+
<stop offset="36%" style="stop-color:var(--gradient-magic-color-2)"/>
|
|
25
|
+
<stop offset="65%" style="stop-color:var(--gradient-magic-color-3)"/>
|
|
26
|
+
<stop offset="95%" style="stop-color:var(--gradient-magic-color-4)"/>
|
|
27
|
+
</linearGradient>
|
|
28
|
+
<linearGradient id="${GRADIENT_MAGIC_ICON_DISABLED_ID}" x1="0" y1="0" x2="1" y2="0.17">
|
|
29
|
+
<stop offset="7.16%" style="stop-color:rgba(var(--gradient-magic-color-1-rgb), 0.3)"/>
|
|
30
|
+
<stop offset="36.18%" style="stop-color:rgba(var(--gradient-magic-color-2-rgb), 0.3)"/>
|
|
31
|
+
<stop offset="65.19%" style="stop-color:rgba(var(--gradient-magic-color-3-rgb), 0.3)"/>
|
|
32
|
+
<stop offset="95.08%" style="stop-color:rgba(var(--gradient-magic-color-4-rgb), 0.3)"/>
|
|
33
|
+
</linearGradient>
|
|
34
|
+
</defs>
|
|
35
|
+
</svg>`,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Injects the shared magic-gradient def once `enabled` becomes truthy (immediate + reactive).
|
|
40
|
+
export function useMagicGradient(enabled: MaybeRefOrGetter<boolean>): void {
|
|
41
|
+
watch(
|
|
42
|
+
() => toValue(enabled),
|
|
43
|
+
(isEnabled) => {
|
|
44
|
+
if (isEnabled) {
|
|
45
|
+
ensureMagicGradientDef();
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{ immediate: true },
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, test } from 'vitest';
|
|
2
|
+
import { mount } from '@vue/test-utils';
|
|
3
|
+
|
|
4
|
+
import IconButton from './IconButton.vue';
|
|
5
|
+
import {
|
|
6
|
+
ICON_BUTTON_COLORS,
|
|
7
|
+
ICON_BUTTON_SIZES,
|
|
8
|
+
ICON_BUTTON_STATES,
|
|
9
|
+
ICON_BUTTON_TYPES,
|
|
10
|
+
} from './IconButton.consts';
|
|
11
|
+
import Button, { BUTTON_TYPES } from '../Button';
|
|
12
|
+
import Icon, { ICONS } from '../../Icons/Icon';
|
|
13
|
+
import { GRADIENT_MAGIC_ICON_ID } from '../Button/useMagicGradient';
|
|
14
|
+
|
|
15
|
+
describe('IconButton', () => {
|
|
16
|
+
const createComponent = (props = {} as any) => {
|
|
17
|
+
return mount(IconButton, {
|
|
18
|
+
props: {
|
|
19
|
+
icon: ICONS.FA_XMARK,
|
|
20
|
+
...props,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
it('should create', () => {
|
|
26
|
+
const component = createComponent();
|
|
27
|
+
|
|
28
|
+
expect(component.exists()).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test.each([
|
|
32
|
+
[{ props: { size: ICON_BUTTON_SIZES.X_SMALL }, expectedClass: '-ds-x-small' }],
|
|
33
|
+
[{ props: { size: ICON_BUTTON_SIZES.SMALL }, expectedClass: '-ds-small' }],
|
|
34
|
+
[{ props: { size: ICON_BUTTON_SIZES.LARGE }, expectedClass: '-ds-large' }],
|
|
35
|
+
[{ props: { state: ICON_BUTTON_STATES.HOVERED }, expectedClass: '-ds-hovered' }],
|
|
36
|
+
[{ props: { state: ICON_BUTTON_STATES.FOCUSED }, expectedClass: '-ds-focused' }],
|
|
37
|
+
[{ props: { state: ICON_BUTTON_STATES.DISABLED }, expectedClass: '-ds-disabled' }],
|
|
38
|
+
[{ props: { state: ICON_BUTTON_STATES.LOADING }, expectedClass: '-ds-loading' }],
|
|
39
|
+
[{ props: { color: ICON_BUTTON_COLORS.PRIMARY }, expectedClass: '-ds-color-primary' }],
|
|
40
|
+
[{ props: { color: ICON_BUTTON_COLORS.MAGIC }, expectedClass: '-ds-color-magic' }],
|
|
41
|
+
])('correct class for props', ({ props, expectedClass }) => {
|
|
42
|
+
const component = createComponent(props);
|
|
43
|
+
expect(component.classes()).toContain(expectedClass);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('renders the icon', () => {
|
|
47
|
+
const component = createComponent({ icon: ICONS.FA_CLOCK });
|
|
48
|
+
|
|
49
|
+
const icon = component.findComponent<typeof Icon>('.ds-iconButton__icon');
|
|
50
|
+
expect(icon.exists()).toBe(true);
|
|
51
|
+
expect(icon.props().icon).toEqual(ICONS.FA_CLOCK);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('renders the spinner icon when loading', () => {
|
|
55
|
+
const component = createComponent({ state: ICON_BUTTON_STATES.LOADING });
|
|
56
|
+
|
|
57
|
+
const icon = component.findComponent<typeof Icon>('.ds-iconButton__icon');
|
|
58
|
+
expect(icon.props().icon).toEqual(ICONS.FAD_SPINNER_THIRD);
|
|
59
|
+
expect(icon.props().spinning).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test.each([
|
|
63
|
+
[{ type: ICON_BUTTON_TYPES.ICON_ONLY, expectedButtonType: BUTTON_TYPES.OUTLINED }],
|
|
64
|
+
[{ type: ICON_BUTTON_TYPES.OUTLINED, expectedButtonType: BUTTON_TYPES.OUTLINED }],
|
|
65
|
+
[{ type: ICON_BUTTON_TYPES.FILLED, expectedButtonType: BUTTON_TYPES.FILLED }],
|
|
66
|
+
])('maps type to inner button type', ({ type, expectedButtonType }) => {
|
|
67
|
+
const component = createComponent({ type });
|
|
68
|
+
|
|
69
|
+
const button = component.findComponent<typeof Button>('.ds-iconButton__button');
|
|
70
|
+
expect(button.props().type).toBe(expectedButtonType);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('marks the inner button as icon-only for the icon-only type', () => {
|
|
74
|
+
const component = createComponent({ type: ICON_BUTTON_TYPES.ICON_ONLY });
|
|
75
|
+
|
|
76
|
+
const button = component.findComponent<typeof Button>('.ds-iconButton__button');
|
|
77
|
+
expect(button.classes()).toContain('-ds-iconOnly');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe('magic color', () => {
|
|
81
|
+
afterEach(() => {
|
|
82
|
+
document.getElementById(GRADIENT_MAGIC_ICON_ID)?.remove();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('passes the magic color through to the inner button', () => {
|
|
86
|
+
const component = createComponent({
|
|
87
|
+
color: ICON_BUTTON_COLORS.MAGIC,
|
|
88
|
+
type: ICON_BUTTON_TYPES.OUTLINED,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const button = component.findComponent<typeof Button>('.ds-iconButton__button');
|
|
92
|
+
expect(button.props().color).toBe(ICON_BUTTON_COLORS.MAGIC);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('injects the shared gradient paint server into the document when color is magic', () => {
|
|
96
|
+
createComponent({ color: ICON_BUTTON_COLORS.MAGIC });
|
|
97
|
+
|
|
98
|
+
expect(document.getElementById(GRADIENT_MAGIC_ICON_ID)).not.toBeNull();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('does not inject the gradient paint server for non-magic colors', () => {
|
|
102
|
+
createComponent({ color: ICON_BUTTON_COLORS.PRIMARY });
|
|
103
|
+
|
|
104
|
+
expect(document.getElementById(GRADIENT_MAGIC_ICON_ID)).toBeNull();
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -45,7 +45,11 @@ const StoryTemplate: StoryFn<typeof IconButton> = (args) => ({
|
|
|
45
45
|
:elevation="elevation"
|
|
46
46
|
:color="color"
|
|
47
47
|
:state="state"
|
|
48
|
-
|
|
48
|
+
>
|
|
49
|
+
<template v-if="label !== ''" #default>
|
|
50
|
+
<span>{{label}}</span>
|
|
51
|
+
</template>
|
|
52
|
+
</icon-button>
|
|
49
53
|
</div>`,
|
|
50
54
|
});
|
|
51
55
|
|
|
@@ -36,13 +36,10 @@
|
|
|
36
36
|
class="ds-iconButton__button"
|
|
37
37
|
:class="{
|
|
38
38
|
'-ds-iconOnly': type === ICON_BUTTON_TYPES.ICON_ONLY,
|
|
39
|
-
'-ds-hovered': state === ICON_BUTTON_STATES.HOVERED,
|
|
40
|
-
'-ds-focused': state === ICON_BUTTON_STATES.FOCUSED,
|
|
41
|
-
'-ds-disabled': state === ICON_BUTTON_STATES.DISABLED,
|
|
42
39
|
}"
|
|
43
40
|
:radius="radius"
|
|
44
41
|
:type="buttonType"
|
|
45
|
-
:state="
|
|
42
|
+
:state="ICON_BUTTON_STATE_MAP[state]"
|
|
46
43
|
:elevation="elevation"
|
|
47
44
|
:color="isButtonColor ? color : null"
|
|
48
45
|
>
|
|
@@ -61,6 +58,7 @@
|
|
|
61
58
|
<style lang="scss" scoped>
|
|
62
59
|
@import '../../../../styles/settings/animations';
|
|
63
60
|
@import '../../../../styles/settings/buttons';
|
|
61
|
+
@import '../../../../styles/settings/gradients';
|
|
64
62
|
@import '../../../../styles/settings/icons';
|
|
65
63
|
@import '../../../../styles/settings/media-queries';
|
|
66
64
|
@import '../../../../styles/settings/spacings';
|
|
@@ -140,7 +138,8 @@
|
|
|
140
138
|
transition: color ease-in-out $default-transition-time;
|
|
141
139
|
|
|
142
140
|
&:disabled,
|
|
143
|
-
&.-ds-disabled
|
|
141
|
+
&.-ds-disabled,
|
|
142
|
+
&.-ds-loading {
|
|
144
143
|
pointer-events: none;
|
|
145
144
|
}
|
|
146
145
|
|
|
@@ -148,6 +147,14 @@
|
|
|
148
147
|
color: map-get($icon-button-colors, 'theme', 'hovered');
|
|
149
148
|
}
|
|
150
149
|
|
|
150
|
+
&.-ds-color-magic {
|
|
151
|
+
#{$self}__icon {
|
|
152
|
+
:deep(svg path) {
|
|
153
|
+
fill: var(--ds-magic-fill, currentColor);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
151
158
|
// Doubled class selector increases specificity to ensure icon button styles never get overridden by .ds-button base styles
|
|
152
159
|
#{$self}__button#{$self}__button {
|
|
153
160
|
height: $icon-button-medium-size;
|
|
@@ -158,6 +165,27 @@
|
|
|
158
165
|
|
|
159
166
|
&.-ds-iconOnly.-ds-outlined {
|
|
160
167
|
border: none;
|
|
168
|
+
|
|
169
|
+
&.-ds-color-magic {
|
|
170
|
+
background: none;
|
|
171
|
+
|
|
172
|
+
&.-ds-hovered,
|
|
173
|
+
&:hover,
|
|
174
|
+
&.-ds-active,
|
|
175
|
+
&:active {
|
|
176
|
+
background: $gradient-magic-background-ghost-hovered;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
&.-ds-focused,
|
|
180
|
+
&:focus {
|
|
181
|
+
background: $gradient-magic-background-ghost-focused;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// no glow (blurred gradient shadow) in iconOnly magic IconButton
|
|
185
|
+
&::after {
|
|
186
|
+
display: none;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
161
189
|
}
|
|
162
190
|
}
|
|
163
191
|
|
|
@@ -266,9 +294,11 @@ import WnlButton, {
|
|
|
266
294
|
BUTTON_COLORS,
|
|
267
295
|
BUTTON_ELEVATIONS,
|
|
268
296
|
BUTTON_RADIUSES,
|
|
297
|
+
BUTTON_STATES,
|
|
269
298
|
BUTTON_TYPES,
|
|
270
299
|
ButtonElevation,
|
|
271
300
|
ButtonRadius,
|
|
301
|
+
ButtonState,
|
|
272
302
|
} from '../Button';
|
|
273
303
|
import {
|
|
274
304
|
ICON_BUTTON_COLOR_SCHEMES,
|
|
@@ -279,6 +309,7 @@ import {
|
|
|
279
309
|
IconButtonColor,
|
|
280
310
|
IconButtonColorScheme,
|
|
281
311
|
IconButtonSize,
|
|
312
|
+
IconButtonState,
|
|
282
313
|
IconButtonType,
|
|
283
314
|
} from './IconButton.consts';
|
|
284
315
|
import { Value } from '../../../utils/type.utils';
|
|
@@ -293,6 +324,14 @@ const ICON_ONLY_ICON_SIZES_MAP = {
|
|
|
293
324
|
[ICON_BUTTON_SIZES.LARGE]: ICON_SIZES.MEDIUM,
|
|
294
325
|
} as const;
|
|
295
326
|
|
|
327
|
+
const ICON_BUTTON_STATE_MAP: Record<IconButtonState, ButtonState> = {
|
|
328
|
+
[ICON_BUTTON_STATES.DEFAULT]: BUTTON_STATES.DEFAULT,
|
|
329
|
+
[ICON_BUTTON_STATES.HOVERED]: BUTTON_STATES.HOVERED,
|
|
330
|
+
[ICON_BUTTON_STATES.FOCUSED]: BUTTON_STATES.FOCUSED,
|
|
331
|
+
[ICON_BUTTON_STATES.LOADING]: BUTTON_STATES.LOADING,
|
|
332
|
+
[ICON_BUTTON_STATES.DISABLED]: BUTTON_STATES.DISABLED,
|
|
333
|
+
};
|
|
334
|
+
|
|
296
335
|
export default defineComponent({
|
|
297
336
|
name: 'IconButton',
|
|
298
337
|
components: {
|
|
@@ -364,6 +403,7 @@ export default defineComponent({
|
|
|
364
403
|
setup() {
|
|
365
404
|
return {
|
|
366
405
|
...useHoverState(),
|
|
406
|
+
ICON_BUTTON_STATE_MAP,
|
|
367
407
|
};
|
|
368
408
|
},
|
|
369
409
|
data() {
|
|
@@ -64,6 +64,11 @@
|
|
|
64
64
|
|
|
65
65
|
<style lang="scss">
|
|
66
66
|
@import 'flatpickr/dist/flatpickr';
|
|
67
|
+
|
|
68
|
+
.-ds-dark {
|
|
69
|
+
// stylelint-disable-next-line no-invalid-position-at-import-rule -- nested import scopes flatpickr's dark theme under `.-ds-dark`
|
|
70
|
+
@import 'flatpickr/dist/themes/dark';
|
|
71
|
+
}
|
|
67
72
|
</style>
|
|
68
73
|
|
|
69
74
|
<style lang="scss" scoped>
|
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
|
|
24
24
|
<style lang="scss">
|
|
25
25
|
@import 'flatpickr/dist/flatpickr';
|
|
26
|
+
|
|
27
|
+
.-ds-dark {
|
|
28
|
+
// stylelint-disable-next-line no-invalid-position-at-import-rule -- nested import scopes flatpickr's dark theme under `.-ds-dark`
|
|
29
|
+
@import 'flatpickr/dist/themes/dark';
|
|
30
|
+
}
|
|
26
31
|
</style>
|
|
27
32
|
|
|
28
33
|
<style scoped lang="scss">
|
|
@@ -126,6 +126,7 @@ import { faLocationDot } from '@fortawesome/pro-regular-svg-icons/faLocationDot'
|
|
|
126
126
|
import { faLockKeyhole } from '@fortawesome/pro-regular-svg-icons/faLockKeyhole';
|
|
127
127
|
import { faMap } from '@fortawesome/pro-regular-svg-icons/faMap';
|
|
128
128
|
import { faMagnifyingGlass } from '@fortawesome/pro-regular-svg-icons/faMagnifyingGlass';
|
|
129
|
+
import { faMarker } from '@fortawesome/pro-regular-svg-icons/faMarker';
|
|
129
130
|
import { faMedal } from '@fortawesome/pro-regular-svg-icons/faMedal';
|
|
130
131
|
import { faMemo } from '@fortawesome/pro-regular-svg-icons/faMemo';
|
|
131
132
|
import { faMemoCircleInfo } from '@fortawesome/pro-regular-svg-icons/faMemoCircleInfo';
|
|
@@ -158,6 +159,7 @@ import { faShieldHalved } from '@fortawesome/pro-regular-svg-icons/faShieldHalve
|
|
|
158
159
|
import { faSidebarFlip } from '@fortawesome/pro-regular-svg-icons/faSidebarFlip';
|
|
159
160
|
import { faSignal } from '@fortawesome/pro-regular-svg-icons/faSignal';
|
|
160
161
|
import { faSitemap } from '@fortawesome/pro-regular-svg-icons/faSitemap';
|
|
162
|
+
import { faSignPost } from '@fortawesome/pro-regular-svg-icons/faSignPost';
|
|
161
163
|
import { faSliders } from '@fortawesome/pro-regular-svg-icons/faSliders';
|
|
162
164
|
import { faSpellCheck } from '@fortawesome/pro-regular-svg-icons/faSpellCheck';
|
|
163
165
|
import { faSquare } from '@fortawesome/pro-regular-svg-icons/faSquare';
|
|
@@ -441,6 +443,7 @@ export const FONTAWESOME_ICONS = {
|
|
|
441
443
|
FA_LOCATION_DOT: faLocationDot,
|
|
442
444
|
FA_LOCK_KEYHOLE: faLockKeyhole,
|
|
443
445
|
FA_MAP: faMap,
|
|
446
|
+
FA_MARKER: faMarker,
|
|
444
447
|
FA_MAGNIFYING_GLASS: faMagnifyingGlass,
|
|
445
448
|
FA_MEDAL: faMedal,
|
|
446
449
|
FA_MEMO_SOLID: fasMemo,
|
|
@@ -481,6 +484,7 @@ export const FONTAWESOME_ICONS = {
|
|
|
481
484
|
FA_SHIELD_HALVED: faShieldHalved,
|
|
482
485
|
FA_SIDEBAR_FLIP: faSidebarFlip,
|
|
483
486
|
FA_SIGNAL: faSignal,
|
|
487
|
+
FA_SIGN_POST: faSignPost,
|
|
484
488
|
FA_SITEMAP_SOLID: fasSitemap,
|
|
485
489
|
FA_SITEMAP: faSitemap,
|
|
486
490
|
FA_SLIDERS: faSliders,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
@import '../settings/spacings';
|
|
3
3
|
@import '../settings/radiuses';
|
|
4
4
|
@import '../settings/buttons';
|
|
5
|
+
@import '../settings/gradients';
|
|
5
6
|
@import '../settings/shadows';
|
|
6
7
|
@import '../settings/icons';
|
|
7
8
|
@import '../settings/typography/tokens';
|
|
@@ -122,6 +123,25 @@
|
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
125
|
|
|
126
|
+
// The magic outlined background stack: a solid white fill clipped to `padding-box` over a
|
|
127
|
+
// gradient ring clipped to `border-box`, showing through only in the 1px transparent border.
|
|
128
|
+
// `$tint` adds a faint gradient over the white pill (hover / focus states); `$border` swaps the
|
|
129
|
+
// gradient ring (e.g. the faded disabled variant).
|
|
130
|
+
@mixin setMagicOutlinedBackground($tint: null, $border: $gradient-magic-border-angular) {
|
|
131
|
+
$fill: linear-gradient($color-default-background, $color-default-background) padding-box;
|
|
132
|
+
|
|
133
|
+
@if $tint {
|
|
134
|
+
background:
|
|
135
|
+
$tint padding-box,
|
|
136
|
+
$fill,
|
|
137
|
+
$border border-box;
|
|
138
|
+
} @else {
|
|
139
|
+
background:
|
|
140
|
+
$fill,
|
|
141
|
+
$border border-box;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
125
145
|
$button-small-min-height: 28px;
|
|
126
146
|
$button-medium-min-height: 32px;
|
|
127
147
|
$button-large-min-height: 48px;
|
|
@@ -201,6 +221,81 @@ $button-disabled-alpha: 0.6;
|
|
|
201
221
|
}
|
|
202
222
|
}
|
|
203
223
|
|
|
224
|
+
// `magic` is a gradient color that doesn't fit the flat color maps. Outlined only:
|
|
225
|
+
// a white fill over a blurred gradient glow.
|
|
226
|
+
&.-ds-color-magic.-ds-outlined {
|
|
227
|
+
$magic-glow-spread: 1px;
|
|
228
|
+
|
|
229
|
+
// `border-image` can't follow `border-radius`, so the gradient ring is a transparent
|
|
230
|
+
// border with two background layers: a solid fill clipped to `padding-box` over the
|
|
231
|
+
// gradient clipped to `border-box`, showing through only in the 1px border gap. The
|
|
232
|
+
// conic gradient starts and ends on the same color so its wrap-around has no seam.
|
|
233
|
+
@include setMagicOutlinedBackground;
|
|
234
|
+
|
|
235
|
+
border: 1px solid transparent;
|
|
236
|
+
color: $color-neutral-text;
|
|
237
|
+
|
|
238
|
+
#{$self}__icon {
|
|
239
|
+
color: $color-neutral-icon;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
#{$self}__loadingIcon {
|
|
243
|
+
svg path {
|
|
244
|
+
fill: var(--ds-magic-fill, currentColor);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Blurred conic gradient creating the glow.
|
|
249
|
+
&::after {
|
|
250
|
+
background: $gradient-magic-border-angular;
|
|
251
|
+
border-radius: inherit;
|
|
252
|
+
bottom: -$magic-glow-spread;
|
|
253
|
+
content: '';
|
|
254
|
+
display: block;
|
|
255
|
+
filter: blur(4px);
|
|
256
|
+
left: -$magic-glow-spread;
|
|
257
|
+
position: absolute;
|
|
258
|
+
right: -$magic-glow-spread;
|
|
259
|
+
top: -$magic-glow-spread;
|
|
260
|
+
transform: translateZ(-1px);
|
|
261
|
+
z-index: -1;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Hover / pressed add a faint gradient tint over the white pill.
|
|
265
|
+
&:hover,
|
|
266
|
+
&.-ds-hovered,
|
|
267
|
+
&:active,
|
|
268
|
+
&.-ds-active {
|
|
269
|
+
// Re-declare the full stack so the gradient ring survives, with the ghost tint
|
|
270
|
+
// layered on top.
|
|
271
|
+
@include setMagicOutlinedBackground($tint: $gradient-magic-background-ghost-hovered);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Focused uses its own ghost tint.
|
|
275
|
+
&:focus,
|
|
276
|
+
&.-ds-focused {
|
|
277
|
+
@include setMagicOutlinedBackground($tint: $gradient-magic-background-ghost-focused);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Disabled drops the glow entirely and fades text/icon.
|
|
281
|
+
&.-ds-disabled,
|
|
282
|
+
&:disabled {
|
|
283
|
+
// Keep the gradient ring but drop the hover tint; the glow is removed below.
|
|
284
|
+
@include setMagicOutlinedBackground($border: $gradient-magic-border-angular-disabled);
|
|
285
|
+
|
|
286
|
+
color: $color-neutral-text-disabled;
|
|
287
|
+
|
|
288
|
+
#{$self}__icon,
|
|
289
|
+
#{$self}__loadingIcon {
|
|
290
|
+
color: $color-neutral-icon-disabled;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
&::after {
|
|
294
|
+
display: none;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
204
299
|
&.-ds-large {
|
|
205
300
|
@include button-l-default-bold-uppercase;
|
|
206
301
|
|
|
@@ -240,7 +335,7 @@ $button-disabled-alpha: 0.6;
|
|
|
240
335
|
}
|
|
241
336
|
|
|
242
337
|
&:not(.-ds-text) {
|
|
243
|
-
min-width:
|
|
338
|
+
min-width: 80px;
|
|
244
339
|
|
|
245
340
|
&.-ds-rounded {
|
|
246
341
|
border-radius: $radius-s;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Settings
|
|
2
2
|
@import 'settings/animations';
|
|
3
3
|
@import 'settings/buttons';
|
|
4
|
+
@import 'settings/gradients';
|
|
4
5
|
@import 'settings/fonts';
|
|
5
6
|
@import 'settings/icons';
|
|
6
7
|
@import 'settings/media-queries';
|
|
@@ -12,6 +13,9 @@
|
|
|
12
13
|
@import 'settings/colors/raw-wnl';
|
|
13
14
|
@import 'settings/colors/raw-bodywork';
|
|
14
15
|
@import 'settings/colors/raw-mc';
|
|
16
|
+
@import 'settings/colors/raw-wnl-dark';
|
|
17
|
+
@import 'settings/colors/raw-bodywork-dark';
|
|
18
|
+
@import 'settings/colors/raw-mc-dark';
|
|
15
19
|
@import 'settings/typography/variables-css';
|
|
16
20
|
|
|
17
21
|
// Mixins
|
|
@@ -32,6 +36,9 @@
|
|
|
32
36
|
@import 'settings/colors/tokens-wnl-variables';
|
|
33
37
|
@import 'settings/colors/tokens-bodywork-variables';
|
|
34
38
|
@import 'settings/colors/tokens-mc-variables';
|
|
39
|
+
@import 'settings/colors/tokens-variables-dark';
|
|
40
|
+
@import 'settings/colors/magic-variables';
|
|
41
|
+
@import 'settings/gradients-variables';
|
|
35
42
|
|
|
36
43
|
html,
|
|
37
44
|
body {
|
|
@@ -50,13 +57,12 @@ textarea {
|
|
|
50
57
|
|
|
51
58
|
html.-ds-thick-scrollbar {
|
|
52
59
|
@media #{breakpoint-m()} {
|
|
53
|
-
@include scrollbar(15px, var(--
|
|
60
|
+
@include scrollbar(15px, var(--color-neutral-background-hovered));
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
html {
|
|
58
|
-
|
|
59
|
-
@include scrollbar(2px, var(--raw-gray-100));
|
|
65
|
+
@include scrollbar(2px, var(--color-neutral-background-hovered));
|
|
60
66
|
|
|
61
67
|
box-sizing: border-box;
|
|
62
68
|
overflow-y: auto; // Without this style, we always display a scrollbar that covers the scrollbar in a container that is full-width. eg. scrollable-main-container
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@mixin scrollbar($size, $foreground-color, $background-color:
|
|
1
|
+
@mixin scrollbar($size, $foreground-color, $background-color: var(--color-default-background)) {
|
|
2
2
|
::-webkit-scrollbar {
|
|
3
3
|
height: $size;
|
|
4
4
|
width: $size;
|
|
@@ -13,7 +13,11 @@
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
@mixin scrollbar-on-self(
|
|
16
|
+
@mixin scrollbar-on-self(
|
|
17
|
+
$size,
|
|
18
|
+
$foreground-color,
|
|
19
|
+
$background-color: var(--color-default-background)
|
|
20
|
+
) {
|
|
17
21
|
&::-webkit-scrollbar {
|
|
18
22
|
height: $size;
|
|
19
23
|
width: $size;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
@import 'colors/magic';
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
--gradient-magic-background-ghost-hovered: linear-gradient(
|
|
5
|
+
100deg,
|
|
6
|
+
rgba(#{$gradient-magic-color-1-rgb}, 0.12) 7.16%,
|
|
7
|
+
rgba(#{$gradient-magic-color-2-rgb}, 0.12) 36.18%,
|
|
8
|
+
rgba(#{$gradient-magic-color-3-rgb}, 0.12) 65.19%,
|
|
9
|
+
rgba(#{$gradient-magic-color-4-rgb}, 0.12) 95.08%
|
|
10
|
+
);
|
|
11
|
+
--gradient-magic-background-ghost-focused: linear-gradient(
|
|
12
|
+
100deg,
|
|
13
|
+
rgba(#{$gradient-magic-color-1-rgb}, 0.12) 7.16%,
|
|
14
|
+
rgba(#{$gradient-magic-color-2-rgb}, 0.12) 36.18%,
|
|
15
|
+
rgba(#{$gradient-magic-color-3-rgb}, 0.12) 65.19%,
|
|
16
|
+
rgba(#{$gradient-magic-color-4-rgb}, 0.12) 95.08%
|
|
17
|
+
);
|
|
18
|
+
--gradient-magic-border-angular: conic-gradient(
|
|
19
|
+
from 90deg,
|
|
20
|
+
#{$gradient-magic-color-4} 0%,
|
|
21
|
+
#{$gradient-magic-color-1} 25%,
|
|
22
|
+
#{$gradient-magic-color-2} 50%,
|
|
23
|
+
#{$gradient-magic-color-3} 75%,
|
|
24
|
+
#{$gradient-magic-color-4} 100%
|
|
25
|
+
);
|
|
26
|
+
--gradient-magic-border-angular-disabled: conic-gradient(
|
|
27
|
+
from 90deg,
|
|
28
|
+
rgba(#{$gradient-magic-color-4-rgb}, 0.4) 0%,
|
|
29
|
+
rgba(#{$gradient-magic-color-1-rgb}, 0.4) 25%,
|
|
30
|
+
rgba(#{$gradient-magic-color-2-rgb}, 0.4) 50%,
|
|
31
|
+
rgba(#{$gradient-magic-color-3-rgb}, 0.4) 75%,
|
|
32
|
+
rgba(#{$gradient-magic-color-4-rgb}, 0.4) 100%
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
$gradient-magic-background-ghost-hovered: var(--gradient-magic-background-ghost-hovered);
|
|
2
|
+
$gradient-magic-background-ghost-focused: var(--gradient-magic-background-ghost-focused);
|
|
3
|
+
$gradient-magic-border-angular: var(--gradient-magic-border-angular);
|
|
4
|
+
$gradient-magic-border-angular-disabled: var(--gradient-magic-border-angular-disabled);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--gradient-magic-color-1: var(--raw-teal-500);
|
|
3
|
+
--gradient-magic-color-2: var(--raw-indigo-500);
|
|
4
|
+
--gradient-magic-color-3: var(--raw-violet-500);
|
|
5
|
+
--gradient-magic-color-4: var(--raw-gold-500);
|
|
6
|
+
--gradient-magic-color-1-rgb: var(--raw-teal-500-rgb);
|
|
7
|
+
--gradient-magic-color-2-rgb: var(--raw-indigo-500-rgb);
|
|
8
|
+
--gradient-magic-color-3-rgb: var(--raw-violet-500-rgb);
|
|
9
|
+
--gradient-magic-color-4-rgb: var(--raw-gold-500-rgb);
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
$gradient-magic-color-1: var(--gradient-magic-color-1);
|
|
2
|
+
$gradient-magic-color-2: var(--gradient-magic-color-2);
|
|
3
|
+
$gradient-magic-color-3: var(--gradient-magic-color-3);
|
|
4
|
+
$gradient-magic-color-4: var(--gradient-magic-color-4);
|
|
5
|
+
|
|
6
|
+
$gradient-magic-color-1-rgb: var(--gradient-magic-color-1-rgb);
|
|
7
|
+
$gradient-magic-color-2-rgb: var(--gradient-magic-color-2-rgb);
|
|
8
|
+
$gradient-magic-color-3-rgb: var(--gradient-magic-color-3-rgb);
|
|
9
|
+
$gradient-magic-color-4-rgb: var(--gradient-magic-color-4-rgb);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.-ds-theme-bodywork.-ds-dark {
|
|
2
|
+
--theme-50: #183340;
|
|
3
|
+
--theme-50-rgb: 24, 51, 64;
|
|
4
|
+
--theme-100: #0a425b;
|
|
5
|
+
--theme-100-rgb: 10, 66, 91;
|
|
6
|
+
--theme-200: #004c6e;
|
|
7
|
+
--theme-200-rgb: 0, 76, 110;
|
|
8
|
+
--theme-300: #0e5d81;
|
|
9
|
+
--theme-300-rgb: 14, 93, 129;
|
|
10
|
+
--theme-400: #1f7095;
|
|
11
|
+
--theme-400-rgb: 31, 112, 149;
|
|
12
|
+
--theme-500: #3d8baf;
|
|
13
|
+
--theme-500-rgb: 61, 139, 175;
|
|
14
|
+
--theme-600: #81b2c8;
|
|
15
|
+
--theme-600-rgb: 129, 178, 200;
|
|
16
|
+
--theme-700: #b6cdd7;
|
|
17
|
+
--theme-700-rgb: 182, 205, 215;
|
|
18
|
+
--theme-800: #dce7ed;
|
|
19
|
+
--theme-800-rgb: 220, 231, 237;
|
|
20
|
+
--theme-900: #ecf2f5;
|
|
21
|
+
--theme-900-rgb: 236, 242, 245;
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.-ds-theme-mc.-ds-dark {
|
|
2
|
+
--theme-50: #081d44;
|
|
3
|
+
--theme-50-rgb: 8, 29, 68;
|
|
4
|
+
--theme-100: #0b265b;
|
|
5
|
+
--theme-100-rgb: 11, 38, 91;
|
|
6
|
+
--theme-200: #0e3277;
|
|
7
|
+
--theme-200-rgb: 14, 50, 119;
|
|
8
|
+
--theme-300: #123d94;
|
|
9
|
+
--theme-300-rgb: 18, 61, 148;
|
|
10
|
+
--theme-400: #164bb6;
|
|
11
|
+
--theme-400-rgb: 22, 75, 182;
|
|
12
|
+
--theme-500: #2664e0;
|
|
13
|
+
--theme-500-rgb: 38, 100, 224;
|
|
14
|
+
--theme-600: #6399f0;
|
|
15
|
+
--theme-600-rgb: 99, 153, 240;
|
|
16
|
+
--theme-700: #aec6f5;
|
|
17
|
+
--theme-700-rgb: 174, 198, 245;
|
|
18
|
+
--theme-800: #d8e4fb;
|
|
19
|
+
--theme-800-rgb: 216, 228, 251;
|
|
20
|
+
--theme-900: #e8effc;
|
|
21
|
+
--theme-900-rgb: 232, 239, 252;
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.-ds-theme-wnl.-ds-dark {
|
|
2
|
+
--theme-50: #0a4c58;
|
|
3
|
+
--theme-50-rgb: 10, 76, 88;
|
|
4
|
+
--theme-100: #095d68;
|
|
5
|
+
--theme-100-rgb: 9, 93, 104;
|
|
6
|
+
--theme-200: #096b75;
|
|
7
|
+
--theme-200-rgb: 9, 107, 117;
|
|
8
|
+
--theme-300: #087e85;
|
|
9
|
+
--theme-300-rgb: 8, 126, 133;
|
|
10
|
+
--theme-400: #078f96;
|
|
11
|
+
--theme-400-rgb: 7, 143, 150;
|
|
12
|
+
--theme-500: #0d9ea4;
|
|
13
|
+
--theme-500-rgb: 13, 158, 164;
|
|
14
|
+
--theme-600: #5bbdc1;
|
|
15
|
+
--theme-600-rgb: 91, 189, 193;
|
|
16
|
+
--theme-700: #a6dcde;
|
|
17
|
+
--theme-700-rgb: 166, 220, 222;
|
|
18
|
+
--theme-800: #d5eeef;
|
|
19
|
+
--theme-800-rgb: 213, 238, 239;
|
|
20
|
+
--theme-900: #e8f6f6;
|
|
21
|
+
--theme-900-rgb: 232, 246, 246;
|
|
22
|
+
}
|