@use "sass:map"; @use "../settings" as *; @if map.get($modules, "components/modal") { /** * Modal () */ :root, :host { #{$css-var-prefix}scrollbar-width: 0px; } #{$parent-selector} dialog { display: grid; z-index: 999; position: fixed; top: 0; right: 0; bottom: 0; left: 0; align-items: center; justify-content: center; width: inherit; min-width: 100%; height: inherit; min-height: 100%; padding: var(#{$css-var-prefix}spacing); border: 0; backdrop-filter: var(#{$css-var-prefix}modal-overlay-backdrop-filter); background-color: var(#{$css-var-prefix}modal-overlay-background-color); color: var(#{$css-var-prefix}color); @if $enable-transitions { transform: scale(1); transition: transform var(#{$css-var-prefix}transition); } // Content > article:not(:has(> form)), > article > form { $close-selector: if( $enable-classes, ".close, :is(a, button)[rel=prev]", ":is(a, button)[rel=prev]" ); width: 100%; @if map.get($breakpoints, "sm") { @media (min-width: map.get(map.get($breakpoints, "sm"), "breakpoint")) { max-width: map.get(map.get($breakpoints, "sm"), "viewport"); } } @if map.get($breakpoints, "md") { @media (min-width: map.get(map.get($breakpoints, "md"), "breakpoint")) { max-width: map.get(map.get($breakpoints, "md"), "viewport"); } } > header { > * { margin-bottom: 0; } #{$close-selector} { margin: 0; margin-left: var(#{$css-var-prefix}spacing); padding: 0; float: right; } } > footer { text-align: right; button, [role="button"] { margin-bottom: 0; &:not(:first-of-type) { margin-left: calc(var(#{$css-var-prefix}spacing) * 0.5); } } } // Close icon #{$close-selector} { display: block; width: 1rem; height: 1rem; margin-top: calc(var(#{$css-var-prefix}spacing) * -1); margin-bottom: var(#{$css-var-prefix}spacing); margin-left: auto; border: none; background-image: var(#{$css-var-prefix}icon-close); background-position: center; background-size: auto 1rem; background-repeat: no-repeat; background-color: transparent; opacity: 0.5; @if $enable-transitions { transition: opacity var(#{$css-var-prefix}transition); } &:is([aria-current]:not([aria-current="false"]), :hover, :active, :focus) { opacity: 1; } } } // Closed state &:not([open]), &[open="false"] { visibility: hidden; opacity: 0; & article { transform: scale(0.7); } } } // Utilities @if $enable-classes { .modal-is-open { padding-right: var(#{$css-var-prefix}scrollbar-width, 0px); overflow: hidden; pointer-events: none; touch-action: none; dialog { pointer-events: auto; touch-action: auto; } } dialog { // Small modal &.modal-sm { > article { width: 90vw; max-width: 400px; } } // Medium modal (default) &.modal-md { > article { width: 90vw; max-width: 600px; } } // Large modal &.modal-lg { > article { width: 90vw; max-width: 800px; } } // Extra large modal &.modal-xlg { > article { width: 95vw; max-width: 1000px; } } // Fullscreen modal &.modal-fs { padding: 0; > article { display: flex; flex-direction: column; justify-content: space-between; width: 100vw; max-width: 100vw; height: 100vh; max-height: 100vh; //border-radius: 0; margin: 0; //padding: var(--spacing); overflow-y: auto; > footer { display: flex; justify-content: flex-end; margin-top: auto; } } } // Handle mobile responsiveness @media (max-width: 576px) { &:not(.modal-fs) { > article { width: 95vw; } } } } } // Prevent scrolling body when modal is open body:has(dialog[open]) { overflow: hidden; } // Animations @if $enable-classes and $enable-transitions { $animation-duration: 0.2s; :where(.modal-is-opening, .modal-is-closing) { dialog, dialog > article { animation-duration: $animation-duration; animation-timing-function: ease-in-out; animation-fill-mode: both; } dialog { animation-duration: ($animation-duration * 4); animation-name: modal-overlay; > article { animation-delay: $animation-duration; animation-name: modal; } } } .modal-is-closing { dialog, dialog > article { animation-delay: 0s; animation-direction: reverse; } } @keyframes modal-overlay { from { backdrop-filter: none; background-color: transparent; } } @keyframes modal { from { transform: translateY(-100%); opacity: 0; } } } }