Files
ionic-framework/core/src/components/toggle/toggle.common.scss
2024-09-06 10:25:27 -04:00

284 lines
6.2 KiB
SCSS

@import "./toggle.vars.scss";
@import "../../themes/mixins.scss";
// Toggle
// --------------------------------------------------
:host {
/**
* @prop --track-background: Background of the toggle track
* @prop --track-background-checked: Background of the toggle track when checked
* @prop --border-radius: Border radius of the toggle track
*
* @prop --handle-background: Background of the toggle handle
* @prop --handle-background-checked: Background of the toggle handle when checked
*
* @prop --handle-border-radius: Border radius of the toggle handle
* @prop --handle-box-shadow: Box shadow of the toggle handle
* @prop --handle-height: Height of the toggle handle
* @prop --handle-max-height: Maximum height of the toggle handle
* @prop --handle-width: Width of the toggle handle
* @prop --handle-spacing: Horizontal spacing around the toggle handle
* @prop --handle-transition: Transition of the toggle handle
*/
/* stylelint-disable-next-line declaration-no-important */
box-sizing: content-box !important;
display: inline-block;
position: relative;
max-width: 100%;
outline: none;
cursor: pointer;
user-select: none;
}
:host(.in-item) {
flex: 1 1 0;
width: 100%;
height: 100%;
}
/**
* Toggle can be slotted
* in components such as item and
* toolbar which is why we do not
* limit the below behavior to just ion-item.
*/
:host([slot="start"]),
:host([slot="end"]) {
// Reset the flex property when the toggle
// is slotted to avoid growing the element larger
// than its content.
flex: initial;
width: auto;
}
:host(.ion-focused) input {
border: 2px solid #5e9ed6;
}
:host(.toggle-disabled) {
pointer-events: none;
}
input {
@include visually-hidden();
}
// Toggle Wrapper
// --------------------------------------------------
.toggle-wrapper {
display: flex;
position: relative;
flex-grow: 1;
align-items: center;
justify-content: space-between;
height: inherit;
transition: background-color 15ms linear;
cursor: inherit;
}
// Input Label
// ----------------------------------------------------------------
/**
* If no label text is placed into the slot
* then the element should be hidden otherwise
* there will be additional margins added.
*/
.label-text-wrapper-hidden {
display: none;
}
// Toggle Native Wrapper
// ----------------------------------------------------------------
.native-wrapper {
display: flex;
align-items: center;
}
// Toggle Justify
// --------------------------------------------------
:host(.toggle-justify-space-between) .toggle-wrapper {
justify-content: space-between;
}
:host(.toggle-justify-start) .toggle-wrapper {
justify-content: start;
}
:host(.toggle-justify-end) .toggle-wrapper {
justify-content: end;
}
// Toggle Align
// --------------------------------------------------
:host(.toggle-alignment-start) .toggle-wrapper {
align-items: start;
}
:host(.toggle-alignment-center) .toggle-wrapper {
align-items: center;
}
// Justify Content & Align Items
// ---------------------------------------------
// The toggle should be displayed as block when either justify
// or alignment is set; otherwise, these properties will have no
// visible effect.
:host(.toggle-justify-space-between),
:host(.toggle-justify-start),
:host(.toggle-justify-end),
:host(.toggle-alignment-start),
:host(.toggle-alignment-center) {
display: block;
}
// Toggle Label Placement - Start
// ----------------------------------------------------------------
/**
* Label is on the left of the input in LTR and
* on the right in RTL.
*/
:host(.toggle-label-placement-start) .toggle-wrapper {
flex-direction: row;
}
// Toggle Label Placement - End
// ----------------------------------------------------------------
/**
* Label is on the right of the input in LTR and
* on the left in RTL.
*/
:host(.toggle-label-placement-end) .toggle-wrapper {
flex-direction: row-reverse;
}
// Toggle Background Track: Unchecked
// --------------------------------------------------
.toggle-icon-wrapper {
display: flex;
position: relative;
align-items: center;
width: 100%;
height: 100%;
transition: var(--handle-transition);
will-change: transform;
}
.toggle-icon {
@include border-radius(var(--border-radius));
display: block;
position: relative;
width: 100%;
height: 100%;
background: var(--track-background);
overflow: inherit;
}
// Toggle Background Track: Checked
// ----------------------------------------------------------
:host(.toggle-checked) .toggle-icon {
background: var(--track-background-checked);
}
// Toggle Inner Knob: Unchecked
// --------------------------------------------------
.toggle-inner {
@include border-radius(var(--handle-border-radius));
position: absolute;
// stylelint-disable-next-line property-disallowed-list
left: var(--handle-spacing);
width: var(--handle-width);
height: var(--handle-height);
max-height: var(--handle-max-height);
transition: var(--handle-transition);
background: var(--handle-background);
box-shadow: var(--handle-box-shadow);
contain: strict;
}
/**
* We do not use the @ltr and @rtl mixins
* here because ion-toggle uses the Shadow DOM
* and WebKit does not support :host-context.
*/
:host(.toggle-ltr) .toggle-inner {
// stylelint-disable-next-line property-disallowed-list
left: var(--handle-spacing);
}
:host(.toggle-rtl) .toggle-inner {
// stylelint-disable-next-line property-disallowed-list
right: var(--handle-spacing);
}
// Toggle Inner Knob: Checked
// ----------------------------------------------------------
:host(.toggle-ltr.toggle-checked) .toggle-icon-wrapper {
// transform by 100% - handle width
transform: translate3d(calc(100% - var(--handle-width)), 0, 0);
}
:host(.toggle-rtl.toggle-checked) .toggle-icon-wrapper {
// transform by -100% + handle width
transform: translate3d(calc(-100% + var(--handle-width)), 0, 0);
}
:host(.toggle-checked) .toggle-inner {
background: var(--handle-background-checked);
}
:host(.toggle-ltr.toggle-checked) .toggle-inner {
// transform by handle spacing amount
transform: translate3d(calc(var(--handle-spacing) * -2), 0, 0);
}
:host(.toggle-rtl.toggle-checked) .toggle-inner {
// transform by handle spacing amount
transform: translate3d(calc(var(--handle-spacing) * 2), 0, 0);
}