Files
2022-12-14 16:49:32 -05:00

357 lines
9.8 KiB
SCSS

@import "../themes/ionic.globals";
@import "../components/menu/menu.ios.vars";
@import "../components/menu/menu.md.vars";
// Ionic Font Family
// --------------------------------------------------
html.ios {
--ion-default-font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Roboto", sans-serif;
}
html.md {
--ion-default-font: "Roboto", "Helvetica Neue", sans-serif;
}
html {
--ion-font-family: var(--ion-default-font);
}
body {
background: var(--ion-background-color);
}
body.backdrop-no-scroll {
overflow: hidden;
}
// Modal - Card Style
// --------------------------------------------------
/**
* Card style modal needs additional padding on the
* top of the header. We accomplish this by targeting
* the first toolbar in the header.
* Footer also needs this. We do not adjust the bottom
* padding though because of the safe area.
*/
html.ios ion-modal.modal-card ion-header ion-toolbar:first-of-type,
html.ios ion-modal.modal-sheet ion-header ion-toolbar:first-of-type,
html.ios ion-modal ion-footer ion-toolbar:first-of-type {
padding-top: 6px;
}
/**
* Card style modal needs additional padding on the
* bottom of the header. We accomplish this by targeting
* the last toolbar in the header.
*/
html.ios ion-modal.modal-card ion-header ion-toolbar:last-of-type,
html.ios ion-modal.modal-sheet ion-header ion-toolbar:last-of-type {
padding-bottom: 6px;
}
/**
* Add padding on the left and right
* of toolbars while accounting for
* safe area values when in landscape.
*/
html.ios ion-modal ion-toolbar {
padding-right: calc(var(--ion-safe-area-right) + 8px);
padding-left: calc(var(--ion-safe-area-left) + 8px);
}
/**
* Card style modal on iPadOS
* should only have backdrop on first instance.
*/
@media screen and (min-width: 768px) {
html.ios ion-modal.modal-card:first-of-type {
--backdrop-opacity: 0.18;
}
}
/**
* Subsequent modals should not have a backdrop/box shadow
* as it will cause the screen to appear to get progressively
* darker. With Ionic 6, declarative modals made it
* possible to have multiple non-presented modals in the DOM,
* so we could no longer rely on ion-modal:first-of-type.
* Here we disable the opacity/box-shadow for every modal
* that comes after the first presented modal.
*
* Note: ion-modal:not(.overlay-hidden):first-of-type
* does not match the first modal to not have
* the .overlay-hidden class, it will match the
* first modal in general only if it does not
* have the .overlay-hidden class.
* The :nth-child() pseudo-class has support
* for selectors which would help us here. At the
* time of writing it does not have great cross browser
* support.
*
* Note 2: This should only apply to non-card and
* non-sheet modals. Card and sheet modals have their
* own criteria for displaying backdrops/box shadows.
*/
ion-modal.modal-default:not(.overlay-hidden) ~ ion-modal.modal-default {
--backdrop-opacity: 0;
--box-shadow: none;
}
/**
* This works around a bug in WebKit where the
* content will overflow outside of the bottom border
* radius when re-painting. As long as a single
* border radius value is set on .ion-page, this
* issue does not happen. We set the top left radius
* here because the top left corner will always have a
* radius no matter the platform.
* This behavior only applies to card modals.
*/
html.ios ion-modal.modal-card .ion-page {
border-top-left-radius: var(--border-radius);
}
// Ionic Colors
// --------------------------------------------------
// Generates the color classes and variables based on the
// colors map
@mixin generate-color($color-name) {
$value: map-get($colors, $color-name);
$base: map-get($value, base);
$contrast: map-get($value, contrast);
$shade: map-get($value, shade);
$tint: map-get($value, tint);
--ion-color-base: var(--ion-color-#{$color-name}, #{$base}) !important;
--ion-color-base-rgb: var(--ion-color-#{$color-name}-rgb, #{color-to-rgb-list($base)}) !important;
--ion-color-contrast: var(--ion-color-#{$color-name}-contrast, #{$contrast}) !important;
--ion-color-contrast-rgb: var(--ion-color-#{$color-name}-contrast-rgb, #{color-to-rgb-list($contrast)}) !important;
--ion-color-shade: var(--ion-color-#{$color-name}-shade, #{$shade}) !important;
--ion-color-tint: var(--ion-color-#{$color-name}-tint, #{$tint}) !important;
}
@each $color-name, $value in $colors {
.ion-color-#{$color-name} {
@include generate-color($color-name);
}
}
// Page Container Structure
// --------------------------------------------------
.ion-page {
@include position(0, 0, 0, 0);
display: flex;
position: absolute;
flex-direction: column;
justify-content: space-between;
contain: layout size style;
overflow: hidden;
z-index: $z-index-page-container;
}
/**
* When making custom dialogs, using
* ion-content is not required. As a result,
* some developers may wish to have dialogs
* that are automatically sized by the browser.
* These changes allow certain dimension values
* such as fit-content to work correctly.
*/
ion-modal .ion-page:not(ion-nav .ion-page) {
position: relative;
contain: layout style;
height: 100%;
}
.split-pane-visible > .ion-page.split-pane-main {
position: relative;
}
ion-route,
ion-route-redirect,
ion-router,
ion-select-option,
ion-nav-controller,
ion-menu-controller,
ion-action-sheet-controller,
ion-alert-controller,
ion-loading-controller,
ion-modal-controller,
ion-picker-controller,
ion-popover-controller,
ion-toast-controller,
.ion-page-hidden {
/* stylelint-disable-next-line declaration-no-important */
display: none !important;
}
.ion-page-invisible {
opacity: 0;
}
.can-go-back > ion-header ion-back-button {
display: block;
}
// Ionic Safe Margins
// --------------------------------------------------
html.plt-ios.plt-hybrid, html.plt-ios.plt-pwa {
--ion-statusbar-padding: 20px;
}
@supports (padding-top: 20px) {
html {
--ion-safe-area-top: var(--ion-statusbar-padding);
}
}
// TODO: remove once Safari 11.2 is no longer supported
@supports (padding-top: constant(safe-area-inset-top)) {
html {
--ion-safe-area-top: constant(safe-area-inset-top);
--ion-safe-area-bottom: constant(safe-area-inset-bottom);
--ion-safe-area-left: constant(safe-area-inset-left);
--ion-safe-area-right: constant(safe-area-inset-right);
}
}
@supports (padding-top: env(safe-area-inset-top)) {
html {
--ion-safe-area-top: env(safe-area-inset-top);
--ion-safe-area-bottom: env(safe-area-inset-bottom);
--ion-safe-area-left: env(safe-area-inset-left);
--ion-safe-area-right: env(safe-area-inset-right);
}
}
// Global Card Styles
// --------------------------------------------------
ion-card.ion-color .ion-inherit-color,
ion-card-header.ion-color .ion-inherit-color {
color: inherit;
}
// Menu Styles
// --------------------------------------------------
.menu-content {
@include transform(translate3d(0, 0, 0));
}
.menu-content-open {
cursor: pointer;
touch-action: manipulation;
// the containing element itself should be clickable but
// everything inside of it should not clickable when menu is open
pointer-events: none;
}
.ios .menu-content-reveal {
box-shadow: $menu-ios-box-shadow-reveal;
}
[dir=rtl].ios .menu-content-reveal {
box-shadow: $menu-ios-box-shadow-reveal-rtl;
}
.ios .menu-content-push {
box-shadow: $menu-ios-box-shadow-push;
}
.md .menu-content-reveal {
box-shadow: $menu-md-box-shadow;
}
.md .menu-content-push {
box-shadow: $menu-md-box-shadow;
}
// Accordion Styles
ion-accordion-group.accordion-group-expand-inset > ion-accordion:first-of-type {
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
ion-accordion-group.accordion-group-expand-inset > ion-accordion:last-of-type {
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
ion-accordion-group > ion-accordion:last-of-type ion-item[slot="header"] {
--border-width: 0px;
}
ion-accordion.accordion-animated > [slot="header"] .ion-accordion-toggle-icon {
transition: 300ms transform cubic-bezier(0.25, 0.8, 0.5, 1);
}
@media (prefers-reduced-motion: reduce) {
ion-accordion .ion-accordion-toggle-icon {
/* stylelint-disable declaration-no-important */
transition: none !important;
}
}
/**
* The > [slot="header"] selector ensures that we do
* not modify toggle icons for any nested accordions. The state
* of one accordion should not affect any accordions inside
* of a nested accordion group.
*/
ion-accordion.accordion-expanding > [slot="header"] .ion-accordion-toggle-icon,
ion-accordion.accordion-expanded > [slot="header"] .ion-accordion-toggle-icon {
transform: rotate(180deg);
}
ion-accordion-group.accordion-group-expand-inset.md > ion-accordion.accordion-previous ion-item[slot="header"] {
--border-width: 0px;
--inner-border-width: 0px;
}
ion-accordion-group.accordion-group-expand-inset.md > ion-accordion.accordion-expanding:first-of-type,
ion-accordion-group.accordion-group-expand-inset.md > ion-accordion.accordion-expanded:first-of-type {
margin-top: 0;
}
// Safari/iOS 15 changes the appearance of input[type="date"].
// For backwards compatibility from Ionic 5/Safari 14 designs,
// we override the appearance only when using within an ion-input.
ion-input input::-webkit-date-and-time-value {
text-align: start;
}
/**
* The .ion-datetime-button-overlay class contains
* styles that allow any modal/popover to be
* sized according to the dimensions of the datetime
* when used with ion-datetime-button.
*/
.ion-datetime-button-overlay {
--width: fit-content;
--height: fit-content;
}
/**
* The grid variant can scale down when inline.
* When used in a `fit-content` overlay, this causes
* the overlay to shrink when the month/year picker is open.
* Explicitly setting the dimensions lets us have a consistently
* sized grid interface.
*/
.ion-datetime-button-overlay ion-datetime.datetime-grid {
width: 320px;
min-height: 320px;
}