diff --git a/packages/web/src/scss/components/Modal/README.md b/packages/web/src/scss/components/Modal/README.md index ad576a2afe..7337a829ba 100644 --- a/packages/web/src/scss/components/Modal/README.md +++ b/packages/web/src/scss/components/Modal/README.md @@ -14,7 +14,7 @@ Modal establishes the top layer with a backdrop. Under the hood it uses the [` + ``` @@ -34,9 +34,9 @@ This is useful for Modals with dynamic content, e.g. a list of items that can be ```html @@ -55,7 +55,7 @@ The default maximum height of Modal is: You can use the custom property `--modal-max-height-tablet` to override the max height on tablet screens and up: ```html - + ``` @@ -107,13 +107,13 @@ and allows users to easily close it. ```html
-

Modal Title

+ @@ -176,7 +176,7 @@ to compensate for the lost spacing by applying utility spacing classes to the Mo type="button" class="Button Button--secondary Button--medium" data-spirit-dismiss="modal" - data-spirit-target="#example_1" + data-spirit-target="#modal-example" > Secondary action @@ -215,8 +215,8 @@ Use our JavaScript plugin to open your Modal, e.g.: type="button" class="Button Button--primary Button--medium" data-spirit-toggle="modal" - data-spirit-target="#example_1" - aria-controls="example_1" + data-spirit-target="#modal-example" + aria-controls="modal-example" aria-expanded="false" > Open Modal @@ -229,7 +229,7 @@ Disable modal close when clicking on the backdrop. You can still close modal with close buttons or ESC key. ```html - + ``` @@ -267,8 +267,8 @@ When you put it all together: type="button" class="Button Button--primary Button--medium" data-spirit-toggle="modal" - data-spirit-target="#example_1" - aria-controls="example_1" + data-spirit-target="#modal-example" + aria-controls="modal-example" aria-expanded="false" > Open Modal @@ -276,18 +276,18 @@ When you put it all together: - +
-

Modal Title

+ @@ -326,7 +326,7 @@ When you put it all together: type="button" class="Button Button--secondary Button--medium" data-spirit-dismiss="modal" - data-spirit-target="#example_1" + data-spirit-target="#modal-example" > Secondary action @@ -352,6 +352,21 @@ Both trigger and close buttons use `data` attributes to open and close the Modal | `data-spirit-target` | `string` | — | ✔ | Target selector | | `data-spirit-toggle` | `string` | `modal` | ✕ | Iterable selector | +## Feature Flag: Uniform Appearance on All Breakpoints + +The uniform appearance of modal dialog on all breakpoints is disabled by default. To enable it, either set the +`$modal-enable-uniform-dialog` feature flag to `true` or use the `spirit-modal-enable-uniform-dialog` CSS class on any +parent of the modal. + +For more info, see main [README][readme-feature-flags]. + +### ⚠️ DEPRECATION NOTICE + +The uniform dialog appearance will replace current behavior in the next major release. Current mobile appearance will +remain accessible via the `.ModalDialog--dockOnMobile` modifier class. + +[What are deprecations?][readme-deprecations] + ## JavaScript Plugin For full functionality you need to provide JavaScript which will handle the toggling of the Modal dialog component. @@ -369,3 +384,5 @@ Or feel free to write controlling scripts yourself. [scroll-view]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/src/scss/components/ScrollView/README.md [web-readme]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/README.md [dictionary-alignment]: https://github.com/lmc-eu/spirit-design-system/blob/main/docs/DICTIONARIES.md#alignment +[readme-deprecations]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/README.md#deprecations +[readme-feature-flags]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/README.md#feature-flags diff --git a/packages/web/src/scss/components/Modal/_Modal.scss b/packages/web/src/scss/components/Modal/_Modal.scss index 769a891703..a509b25de0 100644 --- a/packages/web/src/scss/components/Modal/_Modal.scss +++ b/packages/web/src/scss/components/Modal/_Modal.scss @@ -46,7 +46,6 @@ @media (prefers-reduced-motion: no-preference) { transition-property: visibility, opacity; transition-duration: theme.$transition-duration; - will-change: visibility, opacity; // 2. &::before { diff --git a/packages/web/src/scss/components/Modal/_ModalDialog.scss b/packages/web/src/scss/components/Modal/_ModalDialog.scss index f9fb2787b4..125a4ee2b1 100644 --- a/packages/web/src/scss/components/Modal/_ModalDialog.scss +++ b/packages/web/src/scss/components/Modal/_ModalDialog.scss @@ -4,10 +4,52 @@ // 3. We need to set the box-sizing again because the parent element unsets styles using `all: unset`. @use 'sass:map'; +@use '../../settings/feature-flags'; @use '../../tools/breakpoint'; @use '../../tools/typography'; @use 'theme'; +@mixin -uniform-modal-dialog() { + --modal-translate-y: 50%; + + bottom: 50%; + width: theme.$dialog-uniform-width; + max-width: calc(100% - #{theme.$padding-x}); + height: theme.$dialog-uniform-height; + max-height: theme.$dialog-uniform-max-height; + border-radius: theme.$dialog-border-radius; + transform-origin: center center; + + @include breakpoint.up(map.get(theme.$breakpoints, tablet)) { + height: theme.$dialog-height-tablet; + max-height: theme.$dialog-uniform-max-height-tablet; + } + + @include breakpoint.up(map.get(theme.$breakpoints, desktop)) { + width: theme.$dialog-width-desktop; + } +} + +@mixin -docked-modal-dialog() { + @include breakpoint.down(map.get(theme.$breakpoints, tablet)) { + --modal-translate-y: 0; + + bottom: 0; + width: theme.$dialog-width; + max-width: none; + height: theme.$dialog-height; + max-height: theme.$dialog-max-height; + border-radius: theme.$dialog-border-radius theme.$dialog-border-radius 0 0; + transform-origin: bottom center; + } +} + +@mixin -expand-docked-modal-dialog() { + @include breakpoint.down(map.get(theme.$breakpoints, tablet)) { + height: theme.$dialog-max-height; + } +} + .ModalDialog { @include typography.generate(theme.$typography); @@ -46,14 +88,42 @@ width: theme.$dialog-width-desktop; } + // @deprecated The "uniform" dialog variant is deprecated and will be removed in the next major release. + // Migration: + // 1. Remove the feature flag and make the uniform dialog the default. + // 2. Adjust transitions below. + @if feature-flags.$modal-enable-uniform-dialog { + @include -uniform-modal-dialog(); + } + @media (prefers-reduced-motion: no-preference) { transition-property: bottom, width, border-radius, transform; // 1. transition-duration: inherit; } } -.ModalDialog--expandOnMobile { - @include breakpoint.down(map.get(theme.$breakpoints, tablet)) { - height: theme.$dialog-max-height; +// @deprecated The "uniform" dialog variant is deprecated and will be removed in the next major release. +// Migration: Remove the feature flag and make the uniform dialog the default. +@if feature-flags.$modal-enable-uniform-dialog { + .ModalDialog--dockOnMobile { + @include -docked-modal-dialog(); + } + + .ModalDialog--dockOnMobile.ModalDialog--expandOnMobile { + @include -expand-docked-modal-dialog(); + } +} @else { + .spirit-feature-modal-enable-uniform-dialog .ModalDialog { + @include -uniform-modal-dialog(); + } + + .spirit-feature-modal-enable-uniform-dialog .ModalDialog--dockOnMobile { + @include -docked-modal-dialog(); + } + + // stylelint-disable-next-line selector-max-class -- Only target the docked variant. + .ModalDialog--expandOnMobile, + .spirit-feature-modal-enable-uniform-dialog .ModalDialog--dockOnMobile.ModalDialog--expandOnMobile { + @include -expand-docked-modal-dialog(); } } diff --git a/packages/web/src/scss/components/Modal/_ModalHeader.scss b/packages/web/src/scss/components/Modal/_ModalHeader.scss index dc70d60c89..355fe27001 100644 --- a/packages/web/src/scss/components/Modal/_ModalHeader.scss +++ b/packages/web/src/scss/components/Modal/_ModalHeader.scss @@ -32,3 +32,17 @@ padding-top: 0.25em; // 1. } } + +// stylelint-disable selector-max-class -- We need high specificity for the feature flag. +.spirit-feature-modal-enable-uniform-dialog .ModalHeader { + padding-top: theme.$header-uniform-padding-top; + + @include breakpoint.up(map.get(theme.$breakpoints, tablet)) { + padding-top: theme.$header-uniform-padding-top-tablet; + } +} + +.spirit-feature-modal-enable-uniform-dialog .ModalDialog--dockOnMobile .ModalHeader { + padding-top: theme.$header-docked-padding-top; +} +// stylelint-enable selector-max-class diff --git a/packages/web/src/scss/components/Modal/_theme.scss b/packages/web/src/scss/components/Modal/_theme.scss index bdb4129cf3..e20fb18e15 100644 --- a/packages/web/src/scss/components/Modal/_theme.scss +++ b/packages/web/src/scss/components/Modal/_theme.scss @@ -3,6 +3,7 @@ $breakpoints: tokens.$breakpoints; $padding: tokens.$space-600; +$padding-x: tokens.$space-700; $padding-x-tablet: tokens.$space-1100; $typography: tokens.$body-medium-text-regular; $transition-duration: transitions.$duration-medium; @@ -27,12 +28,25 @@ $dialog-border-radius: tokens.$radius-200; $dialog-background-color: tokens.$background-basic; $dialog-shadow: tokens.$shadow-300; +// @deprecated The "uniform" Header padding is deprecated and will be removed in the next major release. +// Migration: Rename the variables containing the `uniform` keyword to remove it. +$dialog-uniform-width: 640px; +$dialog-uniform-height: var(--modal-preferred-height-mobile, min-content); +$dialog-uniform-max-height: min(var(--modal-max-height-mobile, 600px), calc(100dvh - #{2 * tokens.$space-600})); +$dialog-uniform-max-height-tablet: min(var(--modal-max-height-tablet, 600px), calc(100dvh - #{2 * tokens.$space-600})); + // ModalHeader $header-gap: tokens.$space-400; $header-padding-top: tokens.$space-800; $header-padding-bottom: tokens.$space-600; $header-title-typography: tokens.$heading-small-text; +// @deprecated The "uniform" Header padding is deprecated and will be removed in the next major release. +// Migration: Rename the variables containing the `uniform` keyword to remove it. +$header-uniform-padding-top: tokens.$space-700; +$header-uniform-padding-top-tablet: tokens.$space-800; +$header-docked-padding-top: tokens.$space-800; + // ModalBody $body-padding-y: tokens.$space-600; diff --git a/packages/web/src/scss/components/Modal/index.html b/packages/web/src/scss/components/Modal/index.html index b27e2ffbb9..d55782cbbf 100644 --- a/packages/web/src/scss/components/Modal/index.html +++ b/packages/web/src/scss/components/Modal/index.html @@ -10,28 +10,28 @@

Modal

type="button" class="Button Button--primary Button--medium" data-spirit-toggle="modal" - data-spirit-target="#example_basic" - aria-controls="example_basic" + data-spirit-target="#example-basic" + aria-controls="example-basic" aria-expanded="false" > Open Modal - +
-

Modal Title

+

Modal Title

@@ -109,7 +109,7 @@

Modal Title

type="button" class="Button Button--secondary Button--medium" data-spirit-dismiss="modal" - data-spirit-target="#example_basic" + data-spirit-target="#example-basic" > Secondary action @@ -127,28 +127,28 @@

Modal Title

type="button" class="Button Button--primary Button--medium" data-spirit-toggle="modal" - data-spirit-target="#example_form" - aria-controls="example_form" + data-spirit-target="#example-form" + aria-controls="example-form" aria-expanded="false" > Open Modal with a Form - +
-

Modal with a Form

+

Modal with a Form

@@ -201,8 +201,8 @@

Modal with a Form

type="button" class="Button Button--primary Button--medium" data-spirit-toggle="modal" - data-spirit-target="#example_custom_height" - aria-controls="example_custom_height" + data-spirit-target="#example-custom-height" + aria-controls="example-custom-height" aria-expanded="false" > Open Modal with Custom Height @@ -210,9 +210,9 @@

Modal with a Form

@@ -221,13 +221,13 @@

Modal with a Form

-

Modal with Custom Height

+

Modal with Custom Height

@@ -273,7 +273,7 @@

Modal with Custo type="button" class="Button Button--secondary Button--medium" data-spirit-dismiss="modal" - data-spirit-target="#example_custom_height" + data-spirit-target="#example-custom-height" > Secondary action @@ -299,30 +299,30 @@

Scrolling Long Content

type="button" class="Button Button--primary Button--medium" data-spirit-toggle="modal" - data-spirit-target="#example_long_content" - aria-controls="example_long_content" + data-spirit-target="#example-long-content" + aria-controls="example-long-content" aria-expanded="false" > Open Modal with Long Content - +
-

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam at excepturi laudantium magnam mollitia perferendis reprehenderit, voluptate. Cum delectus dicta

@@ -395,7 +395,7 @@

type="button" class="Button Button--secondary Button--medium" data-spirit-dismiss="modal" - data-spirit-target="#example_long_content" + data-spirit-target="#example-long-content" > Secondary action @@ -413,30 +413,30 @@

type="button" class="Button Button--primary Button--medium" data-spirit-toggle="modal" - data-spirit-target="#example_scroll_view" - aria-controls="example_scroll_view" + data-spirit-target="#example-scroll-view" + aria-controls="example-scroll-view" aria-expanded="false" > Open Modal with ScrollView - +
-

+

Modal with ScrollView

@@ -520,7 +520,7 @@

type="button" class="Button Button--secondary Button--medium" data-spirit-dismiss="modal" - data-spirit-target="#example_scroll_view" + data-spirit-target="#example-scroll-view" > Secondary action @@ -547,28 +547,28 @@

Stacking Modals

type="button" class="Button Button--primary Button--medium" data-spirit-toggle="modal" - data-spirit-target="#example_stacking_parent" - aria-controls="example_stacking_parent" + data-spirit-target="#example-stacking-parent" + aria-controls="example-stacking-parent" aria-expanded="false" > Open Modal - +
-

Modal Title

+

Modal Title

@@ -696,25 +696,25 @@

Disabled Backdrop Click

type="button" class="Button Button--primary Button--medium" data-spirit-toggle="modal" - data-spirit-target="#example_disabled_backdrop_click" - aria-controls="example_disabled_backdrop_click" + data-spirit-target="#example-disabled-backdrop-click" + aria-controls="example-disabled-backdrop-click" aria-expanded="false" > Open Modal - +
-

Modal Title

+

Modal Title

@@ -746,7 +746,7 @@

Modal type="button" class="Button Button--secondary Button--medium" data-spirit-dismiss="modal" - data-spirit-target="#example_disabled_backdrop_click" + data-spirit-target="#example-disabled-backdrop-click" > Secondary action @@ -761,4 +761,172 @@

Modal +
+

Feature Flag: Uniform Modal on Mobile

+ +
+ + + + + + + + + +
+ + +
+

Modal Title

+ +
+ + + +
+ +

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam at excepturi laudantium magnam mollitia + perferendis reprehenderit, voluptate. Cum delectus dicta ducimus eligendi excepturi natus perferendis + provident unde. Eveniet, iste, molestiae? +

+ +
+ + + +
+
+ Optional description +
+
+ + +
+
+ + +
+ + +
+ + + + + + +
+ + +
+

Modal Title

+ +
+ + + +
+ +

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam at excepturi laudantium magnam mollitia + perferendis reprehenderit, voluptate. Cum delectus dicta ducimus eligendi excepturi natus perferendis + provident unde. Eveniet, iste, molestiae? +

+ +
+ + + +
+
+ Optional description +
+
+ + +
+
+ + +
+ + +
+ + +
+
+ {{/layout/plain }} diff --git a/packages/web/src/scss/settings/_feature-flags.scss b/packages/web/src/scss/settings/_feature-flags.scss index 4c7a10a2fe..25c69b50e2 100644 --- a/packages/web/src/scss/settings/_feature-flags.scss +++ b/packages/web/src/scss/settings/_feature-flags.scss @@ -1,2 +1,3 @@ $dropdown-enable-enhanced-shadow: false !default; +$modal-enable-uniform-dialog: false !default; $tooltip-enable-data-placement: false !default;