@muraldevkit/ui-toolkit 1.9.1 → 1.10.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/dist/components/button/helpers.d.ts +2 -1
- package/dist/components/focus-trap/MrlFocusTrap.d.ts +26 -0
- package/dist/components/modal/MrlModal/index.d.ts +34 -0
- package/dist/components/modal/MrlModalContent/index.d.ts +16 -0
- package/dist/components/modal/MrlModalFooter/index.d.ts +28 -0
- package/dist/components/modal/MrlModalHeader/index.d.ts +23 -0
- package/dist/components/modal/constants.d.ts +18 -0
- package/dist/components/modal/demo/ModalWithTriggerDemo.d.ts +14 -0
- package/dist/components/modal/index.d.ts +5 -0
- package/dist/components/tooltip/MrlTooltip/MrlTooltip.d.ts +12 -10
- package/dist/index.js +1 -1
- package/dist/styles/MrlModal/mixins.scss +46 -0
- package/dist/styles/MrlModal/module.scss +81 -0
- package/dist/styles/MrlModal/variables.scss +28 -0
- package/dist/styles/MrlModalContent/module.scss +13 -0
- package/dist/styles/MrlModalFooter/module.scss +49 -0
- package/dist/styles/MrlModalFooter/variables.scss +10 -0
- package/dist/styles/MrlModalHeader/module.scss +21 -0
- package/dist/styles/button/global.scss +2 -2
- package/dist/styles/modal/variables.scss +37 -0
- package/dist/utils/isElementScrollable/index.d.ts +7 -0
- package/dist/utils/trapFocus/index.d.ts +16 -0
- package/package.json +2 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
////
|
|
2
|
+
/// Modal component mixins
|
|
3
|
+
/// @group modal
|
|
4
|
+
////
|
|
5
|
+
|
|
6
|
+
/// CSS transition setup for modal backdrop/scrim animating in
|
|
7
|
+
/// There are no configurations for this mixin
|
|
8
|
+
///
|
|
9
|
+
/// @example @include mrl-modal-scrim-in;
|
|
10
|
+
@mixin mrl-modal-scrim-in() {
|
|
11
|
+
opacity: 1;
|
|
12
|
+
transition-duration: var(--mrl-duration-04);
|
|
13
|
+
transition-property: opacity;
|
|
14
|
+
transition-timing-function: var(--mrl-timing-m1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/// CSS transition setup for modal backdrop/scrim animating out
|
|
18
|
+
/// There are no configurations for this mixin
|
|
19
|
+
///
|
|
20
|
+
/// @example @include mrl-modal-scrim-out;
|
|
21
|
+
@mixin mrl-modal-scrim-out() {
|
|
22
|
+
opacity: 0;
|
|
23
|
+
transition-duration: var(--mrl-duration-03);
|
|
24
|
+
transition-timing-function: var(--mrl-timing-m3);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/// CSS transition setup for modal dialog animating in
|
|
28
|
+
/// There are no configurations for this mixin
|
|
29
|
+
///
|
|
30
|
+
/// @example @include mrl-modal-dialog-in;
|
|
31
|
+
@mixin mrl-modal-dialog-in() {
|
|
32
|
+
transform: translate(0, 0);
|
|
33
|
+
transition-duration: var(--mrl-duration-04);
|
|
34
|
+
transition-property: transform;
|
|
35
|
+
transition-timing-function: var(--mrl-timing-m1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/// CSS transition setup for modal dialog animating out
|
|
39
|
+
/// There are no configurations for this mixin
|
|
40
|
+
///
|
|
41
|
+
/// @example @include mrl-modal-dialog-out;
|
|
42
|
+
@mixin mrl-modal-dialog-out() {
|
|
43
|
+
transform: translate(0, var(--mrl-distance-02));
|
|
44
|
+
transition-duration: var(--mrl-duration-03);
|
|
45
|
+
transition-timing-function: var(--mrl-timing-m3);
|
|
46
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
////
|
|
2
|
+
/// Modal component styles
|
|
3
|
+
/// @group modal
|
|
4
|
+
////
|
|
5
|
+
|
|
6
|
+
@use '~@muraldevkit/ds-foundation/src/styles/global-variables/breakpoints' as *;
|
|
7
|
+
|
|
8
|
+
@use '~@muraldevkit/ds-foundation/src/styles/_mixins' as *;
|
|
9
|
+
@use './styles.variables.scss';
|
|
10
|
+
@use './styles.mixins.scss' as *;
|
|
11
|
+
@use '~@muraldevkit/ds-foundation/src/styles/contextual-variables/z-index' as *;
|
|
12
|
+
@use './styles.mixins.scss' as *;
|
|
13
|
+
|
|
14
|
+
.mrl-modal-backdrop {
|
|
15
|
+
align-items: center;
|
|
16
|
+
background: var(--mrl-modal-backdrop-background);
|
|
17
|
+
display: flex;
|
|
18
|
+
inset: 0;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
opacity: 0;
|
|
21
|
+
position: fixed;
|
|
22
|
+
transition: opacity 300ms ease-in-out;
|
|
23
|
+
z-index: $mrl-zIndex-overlays;
|
|
24
|
+
|
|
25
|
+
&.fade-in {
|
|
26
|
+
@include mrl-modal-scrim-in;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&.fade-out {
|
|
30
|
+
@include mrl-modal-scrim-out;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&.display {
|
|
34
|
+
display: fixed;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&.hide {
|
|
38
|
+
display: none;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.mrl-modal {
|
|
43
|
+
background: var(--mrl-modal-background);
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
flex-grow: 1;
|
|
47
|
+
height: 100vh;
|
|
48
|
+
overflow: auto;
|
|
49
|
+
position: relative;
|
|
50
|
+
width: 100vw;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.mrl-modal-close {
|
|
54
|
+
position: absolute;
|
|
55
|
+
|
|
56
|
+
// The close button is in the same location for all modal sizes
|
|
57
|
+
right: var(--mrl-modal-close-offset);
|
|
58
|
+
top: var(--mrl-modal-close-offset);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
62
|
+
.mrl-modal-backdrop.fade-in .mrl-modal {
|
|
63
|
+
@include mrl-modal-dialog-in;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.mrl-modal-backdrop.fade-out .mrl-modal {
|
|
67
|
+
@include mrl-modal-dialog-out;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Modifiers: Sizes
|
|
72
|
+
@media screen and (min-width: $mrl-breakpoint-01) {
|
|
73
|
+
.mrl-modal {
|
|
74
|
+
border-radius: var(--mrl-modal-border-radius);
|
|
75
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 8%), var(--mrl-shadow-03);
|
|
76
|
+
height: auto;
|
|
77
|
+
margin: var(--mrl-spacing-08);
|
|
78
|
+
max-height: 95vh;
|
|
79
|
+
max-width: var(--mrl-modal-size);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
////
|
|
2
|
+
/// Modal component styles
|
|
3
|
+
/// @group modal
|
|
4
|
+
////
|
|
5
|
+
|
|
6
|
+
@use '~@muraldevkit/ds-foundation/src/styles/global-variables/breakpoints' as *;
|
|
7
|
+
@use '../styles.variables.scss';
|
|
8
|
+
|
|
9
|
+
.mrl-modal-backdrop {
|
|
10
|
+
--mrl-modal-backdrop-background: var(--mrl-black-opacity-06);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.mrl-modal {
|
|
14
|
+
--mrl-modal-size: 600px;
|
|
15
|
+
--mrl-modal-border-radius: var(--mrl-radii-05);
|
|
16
|
+
--mrl-modal-background: var(--mrl-color-background);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/// Media queries' styles for desktop
|
|
20
|
+
@media screen and (min-width: $mrl-breakpoint-01) {
|
|
21
|
+
.mrl-modal--small {
|
|
22
|
+
--mrl-modal-size: 400px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.mrl-modal--large {
|
|
26
|
+
--mrl-modal-size: 800px;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@use '~@muraldevkit/ds-foundation/src/styles/_mixins' as *;
|
|
2
|
+
|
|
3
|
+
.mrl-modal-content {
|
|
4
|
+
// Because this is a non-standard tab-able element, we may have limitations with
|
|
5
|
+
// styling options of the focus ring.
|
|
6
|
+
@include mrl-focus($style: 'outline');
|
|
7
|
+
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
flex-grow: 1;
|
|
11
|
+
overflow: auto;
|
|
12
|
+
padding: 0 var(--mrl-modal-padding-horizontal);
|
|
13
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
////
|
|
2
|
+
/// Modal footer component styles
|
|
3
|
+
/// @group modal
|
|
4
|
+
////
|
|
5
|
+
|
|
6
|
+
@use '~@muraldevkit/ds-foundation/src/styles/global-variables/breakpoints' as *;
|
|
7
|
+
@use '~@muraldevkit/ds-foundation/src/styles/skeletons/button' as *;
|
|
8
|
+
@use './styles.variables.scss';
|
|
9
|
+
|
|
10
|
+
.mrl-modal-footer {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: row;
|
|
13
|
+
gap: var(--mrl-modal-footer-inline-margin);
|
|
14
|
+
padding: var(--mrl-modal-padding-vertical) var(--mrl-modal-padding-horizontal);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.mrl-modal-footer-wrapper {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
gap: var(--mrl-modal-footer-inline-margin);
|
|
21
|
+
width: 100%;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.slotted :global(.mrlButton) {
|
|
25
|
+
display: block;
|
|
26
|
+
width: 100%;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/// Media queries' styles for desktop
|
|
30
|
+
@media screen and (min-width: $mrl-breakpoint-01) {
|
|
31
|
+
.mrl-modal-footer {
|
|
32
|
+
flex-direction: row;
|
|
33
|
+
justify-content: space-between;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.mrl-modal-footer-wrapper {
|
|
37
|
+
flex-direction: row;
|
|
38
|
+
justify-content: right;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.mrl-modal-footer-wrapper .slotted {
|
|
42
|
+
display: inline-flex;
|
|
43
|
+
width: auto;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.tertiary.slotted {
|
|
47
|
+
margin-right: auto;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
////
|
|
2
|
+
/// Modal header component styles
|
|
3
|
+
/// @group modal
|
|
4
|
+
////
|
|
5
|
+
|
|
6
|
+
@use '../styles.variables.scss' as *;
|
|
7
|
+
|
|
8
|
+
.mrl-modal-header {
|
|
9
|
+
color: var(--mrl-modal-header-text-color);
|
|
10
|
+
display: flex;
|
|
11
|
+
min-height: calc(
|
|
12
|
+
var(--mrl-type-size-headline-large) * var(--mrl-type-line-height-headline-large)
|
|
13
|
+
);
|
|
14
|
+
padding: var(--mrl-modal-padding-vertical)
|
|
15
|
+
// We calculate padding based on the position of the close button
|
|
16
|
+
// that is added to the modal container
|
|
17
|
+
calc(
|
|
18
|
+
#{$mrl-modal-close-size} + var(--mrl-modal-close-offset) + var(--mrl-modal-close-inline-margin)
|
|
19
|
+
)
|
|
20
|
+
var(--mrl-modal-padding-vertical) var(--mrl-modal-padding-horizontal);
|
|
21
|
+
}
|
|
@@ -59,9 +59,9 @@ $mrl-interaction-scope: ':not(#{$mrl-button-toggle-selector}):not([aria-disabled
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// Developer-initiated skeleton state
|
|
62
|
-
// Requires additional weight to overwrite other
|
|
62
|
+
// Requires additional weight to overwrite other versions of the component
|
|
63
63
|
&--skeleton,
|
|
64
|
-
&--skeleton[aria-disabled=
|
|
64
|
+
&--skeleton[aria-disabled='true'] {
|
|
65
65
|
@include mrl-button-skeleton;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
////
|
|
2
|
+
/// Modal shared variables
|
|
3
|
+
/// @group modal
|
|
4
|
+
////
|
|
5
|
+
|
|
6
|
+
@use '~@muraldevkit/ds-foundation/src/styles/global-variables/breakpoints' as *;
|
|
7
|
+
@use '~@muraldevkit/ds-foundation/src/styles/skeletons/button' as *;
|
|
8
|
+
|
|
9
|
+
// @use '~@muraldevkit/ds-component-button/dist/scss/variables' as *;
|
|
10
|
+
|
|
11
|
+
// import button.variables.scss from button component in this repositories button component
|
|
12
|
+
@use '../button/button.variables.scss' as *;
|
|
13
|
+
|
|
14
|
+
$mrl-modal-close-size: $mrl-button-height--default;
|
|
15
|
+
|
|
16
|
+
.mrl-modal {
|
|
17
|
+
--mrl-modal-header-text-color: rgba(var(--mrl-gray-100), 1);
|
|
18
|
+
--mrl-modal-padding-vertical: var(--mrl-spacing-07);
|
|
19
|
+
--mrl-modal-padding-horizontal: var(--mrl-spacing-07);
|
|
20
|
+
--mrl-modal-close-inline-margin: var(--mrl-space-inline-related);
|
|
21
|
+
--mrl-modal-close-offset: var(--mrl-spacing-06);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/// Media queries' styles for desktop
|
|
25
|
+
@media screen and (min-width: $mrl-breakpoint-01) {
|
|
26
|
+
.mrl-modal,
|
|
27
|
+
.mrl-modal .footer.slotted .mrl-modal-footer,
|
|
28
|
+
.mrl-modal .header.slotted .mrl-modal-header {
|
|
29
|
+
--mrl-modal-padding-horizontal: var(--mrl-spacing-08);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.mrl-modal--large,
|
|
33
|
+
.mrl-modal--large .footer.slotted .mrl-modal-footer,
|
|
34
|
+
.mrl-modal--large .header.slotted .mrl-modal-header {
|
|
35
|
+
--mrl-modal-padding-horizontal: var(--mrl-spacing-09);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test if an element is scrollable
|
|
3
|
+
*
|
|
4
|
+
* @param {HTMLElement} element - the element you want to test
|
|
5
|
+
* @returns {boolean} - true if the element is scrollable, false if it is not scrollable
|
|
6
|
+
*/
|
|
7
|
+
export declare const isElementScrollable: (element: HTMLElement) => boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Focus trap logic
|
|
3
|
+
*
|
|
4
|
+
* @param {HTMLElement} element - The component props.
|
|
5
|
+
* @returns {HTMLElement[]} - The focusable elements inside the element.
|
|
6
|
+
*/
|
|
7
|
+
export declare const getFocusableElementsInsideElement: (element: HTMLElement) => HTMLElement[];
|
|
8
|
+
/**
|
|
9
|
+
* Traps focus inside of an element.
|
|
10
|
+
* Adapted from https://hidde.blog/using-javascript-to-trap-focus-in-an-element/
|
|
11
|
+
*
|
|
12
|
+
* @param {HTMLElement} element // Element to trap focus in
|
|
13
|
+
* @returns {Function} // Cleanup function to be run when component is
|
|
14
|
+
* // removed from the DOM
|
|
15
|
+
*/
|
|
16
|
+
export declare const trapFocus: (element: HTMLElement) => (() => void);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muraldevkit/ui-toolkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Mural's UI Toolkit",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
"jest-environment-jsdom": "29.5.0",
|
|
94
94
|
"jest-matchmedia-mock": "1.1.0",
|
|
95
95
|
"lint-staged": "13.2.2",
|
|
96
|
+
"null-loader": "4.0.1",
|
|
96
97
|
"prettier": "2.8.8",
|
|
97
98
|
"rimraf": "5.0.0",
|
|
98
99
|
"sass": "1.62.1",
|