Skip to content

Commit

Permalink
BREAKING CHANGE(web): Turn off scrolling inside ModalDialog by defa…
Browse files Browse the repository at this point in the history
…ult #DS-1184
  • Loading branch information
adamkudrna committed May 18, 2024
1 parent 52cad76 commit e568cd2
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 306 deletions.
3 changes: 3 additions & 0 deletions docs/migrations/web/MIGRATION-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ The `.ModalDialog--nonScrollable` modifier was removed and the ModalDialog is ma

In the new version, use the `.ModalDialog--scrollable` modifier class to make the ModalDialog scrollable.

If you use `ScrollView` for scrolling the content of your modal, you must also add the `.ModalDialog--scrollable` class
to the `.ModalDialog` element.

- `.ModalDialog``.ModalDialog .ModalDialog--scrollable`

### Modal: Uniform Variant Feature Flag
Expand Down
18 changes: 4 additions & 14 deletions packages/web/DEPRECATIONS-v2.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
# Deprecations List

Following deprecations will be removed in version 2 of the _spirit-web_ package.
This document lists all deprecations that will be removed in the next major version of the _spirit-web_ package.

> Please follow these steps to safely upgrade your design system to Spirit Design System v2 components.
[What are deprecations?][readme-deprecations]
> Please follow the migration guides to safely upgrade your design system components.
## Deprecations

### Modal (Non)Scrollable

The `.ModalDialog--nonScrollable` modifier will be removed and the ModalDialog will be made non-scrollable by default.

#### Migration Guide

In the new version, use the `.ModalDialog--scrollable` modifier class to make the ModalDialog scrollable.
Nothing here right now! 🎉

- `.ModalDialog``.ModalDialog .ModalDialog--scrollable`
👉 [What are deprecations?][readme-deprecations]

[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
[dictionary-placement]: https://github.com/lmc-eu/spirit-design-system/blob/main/docs/DICTIONARIES.md#placement
132 changes: 61 additions & 71 deletions packages/web/src/scss/components/Modal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,56 +39,6 @@ Example:
</dialog>
```

### Custom Height

By default, Modal expands to fit the height of its content, as long as it fits the viewport (see [more below](#custom-max-height)).
You can override this behavior by setting a custom preferred height using a custom property:

- `--modal-preferred-height-mobile` for mobile screens, and
- `--modal-preferred-height-tablet` for tablet screens and up.

This is useful for Modals with dynamic content, e.g. a list of items that can be added or removed, or a multistep wizard.

```html
<dialog
id="modal-example"
class="Modal Modal--center"
aria-labelledby="modal-example-title"
style="--modal-preferred-height-mobile: 400px; --modal-preferred-height-tablet: 500px;"
>
<!-- ModalDialog -->
</dialog>
```

👉 Please note the preferred height options are ignored when scrolling inside ModalDialog is
[turned off](#disable-scrolling-inside-modaldialog).

👉 Please note the custom height values are considered **preferred:** Modal will not expand beyond the viewport height.

### Custom Max Height

The default maximum height of Modal is:

- viewport height minus 1100 spacing on mobile screens, and
- 600 px on tablet screens and up (shrunk if necessary).

You can use the custom property `--modal-max-height-tablet` to override the max height on tablet screens and up:

```html
<dialog
id="modal-example"
class="Modal Modal--center"
aria-labelledby="modal-example-title"
style="--modal-max-height-tablet: 700px"
>
<!-- ModalDialog -->
</dialog>
```

👉 Please note the max height is ignored when scrolling inside ModalDialog is [turned off](#disable-scrolling-inside-modaldialog).

👉 Please note the max height on mobile screens is currently not customizable. Let us know if you need this feature! 🙏

## ModalDialog

ModalDialog is the actual dialog window, a place for the header, body, and footer of the dialog.
Expand Down Expand Up @@ -134,7 +84,7 @@ class.

#### Expanded Variant

By default the docked dialog on mobile screens shrinks to fit the height of its content
By default, the docked dialog on mobile screens shrinks to fit the height of its content
(if smaller than the viewport). Use the `ModalDialog--expandOnMobile` class to expand the dialog on mobile.

```html
Expand Down Expand Up @@ -282,47 +232,87 @@ You can still close modal with close buttons or ESC key.

## Scrolling Long Content

When Modals become too long for the user's viewport or device, they scroll independently of the page itself. By default,
ModalBody has `overflow-y: auto` applied to it, so it scrolls vertically.
In case the content is longer than user's viewport or device, the ModalBody will expand to fit the height of its content
and the whole ModalDialog will scroll.

### Enable Scrolling Inside ModalDialog

Scrolling inside ModalDialog can be turned on by adding the `ModalDialog--scrollable` modifier class:

```html
<article class="ModalDialog ModalDialog--scrollable">
<!---->
</article>
```

### Scrolling with ScrollView

Alternatively, you can wrap the ModalBody content in a [ScrollView][scroll-view] to take over the responsibility for
Additionally, you can wrap the ModalBody content in a [ScrollView][scroll-view] to take over the responsibility for
scrolling, e.g.:

```html
<div class="ScrollView ScrollView--vertical" data-spirit-toggle="scrollView">
<div class="ScrollView__viewport" data-spirit-element="viewport">
<div class="ScrollView__content" data-spirit-element="content">
<div class="ModalBody">
<!---->
<article class="ModalDialog ModalDialog--scrollable">
<!-- ModalHeader -->
<div class="ScrollView ScrollView--vertical" data-spirit-toggle="scrollView">
<div class="ScrollView__viewport" data-spirit-element="viewport">
<div class="ScrollView__content" data-spirit-element="content">
<div class="ModalBody">
<!---->
</div>
</div>
</div>
<div class="ScrollView__overflowDecorators ScrollView__overflowDecorators--borders" aria-hidden="true"></div>
</div>
<div class="ScrollView__overflowDecorators ScrollView__overflowDecorators--borders" aria-hidden="true"></div>
</div>
<!-- ModalFooter -->
</article>
```

### Disable Scrolling Inside ModalDialog
### Custom Height

By default, ModalDialog grows to the height of its content until it reaches the [maximum height](#custom-max-height)
limit.

You can set a custom preferred height of ModalDialog using a custom property:

- `--modal-preferred-height-mobile` for mobile screens, and
- `--modal-preferred-height-tablet` for tablet screens and up.

Scrolling inside ModalDialog can be turned off by adding the `ModalDialog--nonScrollable` modifier class:
This is useful for Modals with dynamic content, e.g. a list of items that can be added or removed, or a multistep wizard.

```html
<article class="ModalDialog ModalDialog--nonScrollable">
<article
class="ModalDialog ModalDialog--scrollable"
style="--modal-preferred-height-mobile: 400px; --modal-preferred-height-tablet: 500px;"
>
<!---->
</article>
```

This way, the ModalBody will expand to fit the height of its content and the whole ModalDialog will scroll in case the
content is longer than user's viewport.
⚠️ This feature is only available for ModalDialogs with the `ModalDialog--scrollable` modifier class.

👉 Please note the custom height values are considered **preferred**. Scrollable ModalDialog will never expand beyond
the viewport height. See the [Custom Max Height](#custom-max-height) section for more information.

### Custom Max Height

👉 Please note that this modifier class can produce unexpected results when used in combination with ScrollView.
The default maximum height of a scrollable ModalDialog is **600 px**, as long as it can fit the viewport.

If the viewport is smaller, scrollable ModalDialog will shrink to fit the viewport. In such case, the ModalDialog height
will calculate as "viewport height (`100dvh`) minus 1100 spacing".

You can use the custom property `--modal-max-height-tablet` to override the default maximum height limit on tablet
screens and up:

```html
<article class="ModalDialog ModalDialog--scrollable" style="--modal-max-height-tablet: 400px">
<!---->
</article>
```

#### ⚠️ DEPRECATION NOTICE
⚠️ This feature is only available for ModalDialogs with the `ModalDialog--scrollable` modifier class.

The `.ModalDialog--nonScrollable` modifier will be removed in the next major release and the ModalDialog will be made
non-scrollable by default. It will be possible to re-enable the inside scrolling by adding the
`.ModalDialog--scrollable` modifier class (which will remain the recommended default usage).
👉 If a [custom height](#custom-height) is set, the custom max height is only applied if it's smaller than the custom
height.

## Stacking Modals

Expand Down
8 changes: 3 additions & 5 deletions packages/web/src/scss/components/Modal/_Modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
// 5. Allow scrolling through the modal. Has no effect unless the modal is taller than the viewport.
// 6. Restore text selection after `all: unset`.

@use 'sass:map';
@use '../../tools/breakpoint';
@use 'theme';

.Modal {
Expand All @@ -20,7 +18,7 @@
z-index: 1;
display: flex; // 1.
padding-block: theme.$padding-y;
overflow: hidden; // 4.
overflow-y: auto; // 5.
background: linear-gradient(#{theme.$backdrop-background-color}, #{theme.$backdrop-background-color}); // 2., 3.
visibility: hidden; // 1.
opacity: 0; // 1.
Expand All @@ -38,8 +36,8 @@
}
}

.Modal:has(.ModalDialog--nonScrollable) {
overflow-y: auto; // 5.
.Modal:has(.ModalDialog--scrollable) {
overflow: hidden; // 4.
}

.Modal--center,
Expand Down
4 changes: 2 additions & 2 deletions packages/web/src/scss/components/Modal/_ModalBody.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
min-height: map.get(theme.$typography, mobile, font-size) * map.get(theme.$typography, mobile, line-height); // 1.
padding-inline: theme.$common-padding-x;
padding-block: theme.$body-padding-y;
overflow-x: var(--modal-body-overflow-x, hidden);
overflow-y: var(--modal-body-overflow-y, auto);
overflow-x: var(--modal-body-overflow-x, visible);
overflow-y: var(--modal-body-overflow-y, visible);
overscroll-behavior: contain;

@include breakpoint.up(map.get(theme.$breakpoints, tablet)) {
Expand Down
43 changes: 23 additions & 20 deletions packages/web/src/scss/components/Modal/_ModalDialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
margin-inline: auto;
margin-top: var(--modal-top);
margin-bottom: var(--modal-bottom);
overflow-x: var(--modal-body-overflow-x, hidden);
overflow-y: var(--modal-body-overflow-y, auto);
overflow-x: var(--modal-body-overflow-x, visible);
overflow-y: var(--modal-body-overflow-y, visible);
color: theme.$dialog-text-color;
border-radius: theme.$dialog-border-radius;
background-color: theme.$dialog-background-color;
Expand All @@ -34,11 +34,6 @@
transform-origin: var(--modal-transform-origin);
overscroll-behavior: contain;

@include breakpoint.up(map.get(theme.$breakpoints, tablet)) {
height: theme.$dialog-height-tablet;
max-height: theme.$dialog-max-height-tablet;
}

@include breakpoint.up(map.get(theme.$breakpoints, desktop)) {
width: theme.$dialog-width-desktop;
}
Expand All @@ -49,6 +44,19 @@
}
}

.ModalDialog--scrollable {
--modal-body-overflow-x: hidden;
--modal-body-overflow-y: auto;

height: theme.$dialog-scrollable-height;
max-height: theme.$dialog-scrollable-max-height;

@include breakpoint.up(map.get(theme.$breakpoints, tablet)) {
height: theme.$dialog-scrollable-height-tablet;
max-height: theme.$dialog-scrollable-max-height-tablet;
}
}

.ModalDialog--dockOnMobile {
@include breakpoint.down(map.get(theme.$breakpoints, tablet)) {
--modal-top: auto;
Expand All @@ -58,12 +66,17 @@

width: theme.$dialog-docked-width;
max-width: none;
height: theme.$dialog-docked-height;
max-height: theme.$dialog-docked-expanded-height;
border-radius: theme.$dialog-border-radius theme.$dialog-border-radius 0 0;
}
}

.ModalDialog--dockOnMobile.ModalDialog--scrollable {
@include breakpoint.down(map.get(theme.$breakpoints, tablet)) {
height: theme.$dialog-docked-scrollable-height;
max-height: theme.$dialog-docked-scrollable-max-height;
}
}

[open] > .ModalDialog--dockOnMobile {
@include breakpoint.down(map.get(theme.$breakpoints, tablet)) {
--modal-translate-y: 0;
Expand All @@ -72,16 +85,6 @@

.ModalDialog--dockOnMobile.ModalDialog--expandOnMobile {
@include breakpoint.down(map.get(theme.$breakpoints, tablet)) {
min-height: theme.$dialog-docked-expanded-height;
min-height: theme.$dialog-docked-expanded-min-height;
}
}

// @deprecated The non-scrollable modal dialog is deprecated and will be removed in the next major release.
// Migration: In CSS, make the modal dialog non-scrollable by default so scrolling inside is turned on by a modifier class.
.ModalDialog--nonScrollable {
--modal-body-overflow-x: visible;
--modal-body-overflow-y: visible;

height: auto;
max-height: none;
}
24 changes: 18 additions & 6 deletions packages/web/src/scss/components/Modal/_theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,31 @@ $common-padding-x-tablet: tokens.$space-800;
// ModalDialog
$dialog-width: 640px;
$dialog-width-desktop: 680px;
$dialog-height: var(--modal-preferred-height-mobile, min-content);
$dialog-height-tablet: var(--modal-preferred-height-tablet, min-content);
$dialog-max-height: min(var(--modal-max-height-mobile, 600px), calc(100dvh - #{2 * $padding-y}));
$dialog-max-height-tablet: min(var(--modal-max-height-tablet, 600px), calc(100dvh - #{2 * $padding-y}));
$dialog-height: auto;
$dialog-max-height: none;
$dialog-text-color: tokens.$text-primary-default;
$dialog-border-radius: tokens.$radius-200;
$dialog-background-color: tokens.$background-basic;
$dialog-shadow: tokens.$shadow-300;

$dialog-scrollable-height: var(--modal-preferred-height-mobile, min-content);
$dialog-scrollable-height-tablet: var(
--modal-preferred-height-tablet,
var(--modal-preferred-height-mobile, min-content)
);
$dialog-scrollable-max-height: min(var(--modal-max-height-mobile, 600px), calc(100dvh - #{2 * $padding-y}));
$dialog-scrollable-max-height-tablet: min(
var(--modal-max-height-tablet, var(--modal-max-height-mobile, 600px)),
calc(100dvh - #{2 * $padding-y})
);

$dialog-docked-width: 100%;
$dialog-docked-height: var(--modal-preferred-height-mobile, min-content);
$dialog-docked-margin-top: tokens.$space-1100;
$dialog-docked-expanded-height: calc(100dvh - #{$dialog-docked-margin-top});

$dialog-docked-expanded-min-height: calc(100dvh - #{$dialog-docked-margin-top});

$dialog-docked-scrollable-height: var(--modal-preferred-height-mobile, min-content);
$dialog-docked-scrollable-max-height: $dialog-docked-expanded-min-height;

// ModalHeader
$header-gap: tokens.$space-400;
Expand Down
Loading

0 comments on commit e568cd2

Please sign in to comment.