mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
377 lines
8.5 KiB
SCSS
377 lines
8.5 KiB
SCSS
@import "../../themes/ionic.globals";
|
|
@import "./toggle.vars.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;
|
|
z-index: $z-index-item-input;
|
|
}
|
|
|
|
:host(.in-item:not(.legacy-toggle)) {
|
|
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"]:not(.legacy-toggle)),
|
|
:host([slot="end"]:not(.legacy-toggle)) {
|
|
width: auto;
|
|
}
|
|
|
|
:host(.legacy-toggle) {
|
|
contain: content;
|
|
|
|
touch-action: none;
|
|
}
|
|
|
|
:host(.ion-focused) input {
|
|
border: 2px solid #5e9ed6;
|
|
}
|
|
|
|
:host(.toggle-disabled) {
|
|
pointer-events: none;
|
|
}
|
|
|
|
:host(.legacy-toggle) label {
|
|
@include input-cover();
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
opacity: 0;
|
|
|
|
pointer-events: none;
|
|
}
|
|
|
|
input {
|
|
@include visually-hidden();
|
|
}
|
|
|
|
// Toggle Wrapper
|
|
// --------------------------------------------------
|
|
|
|
.toggle-wrapper {
|
|
display: flex;
|
|
|
|
position: relative;
|
|
|
|
flex-grow: 1;
|
|
|
|
height: inherit;
|
|
|
|
transition: background-color 15ms linear;
|
|
|
|
cursor: inherit;
|
|
}
|
|
|
|
// Input Label
|
|
// ----------------------------------------------------------------
|
|
|
|
.label-text-wrapper {
|
|
text-overflow: ellipsis;
|
|
|
|
white-space: nowrap;
|
|
|
|
overflow: hidden;
|
|
}
|
|
|
|
:host(.in-item:not(.legacy-toggle)) .label-text-wrapper {
|
|
@include margin($toggle-item-label-margin-top, null, $toggle-item-label-margin-bottom, null);
|
|
}
|
|
|
|
:host(.in-item.toggle-label-placement-stacked) .label-text-wrapper {
|
|
@include margin($toggle-item-label-margin-top, null, $form-control-label-margin, null);
|
|
}
|
|
|
|
:host(.in-item.toggle-label-placement-stacked) .native-wrapper {
|
|
@include margin(null, null, $toggle-item-label-margin-bottom, null);
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
:host(.toggle-label-placement-start) .label-text-wrapper {
|
|
/**
|
|
* The margin between the label and
|
|
* the input should be on the end
|
|
* when the label sits at the start.
|
|
*/
|
|
@include margin(null, $form-control-label-margin, null, 0);
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
/**
|
|
* The margin between the label and
|
|
* the input should be on the start
|
|
* when the label sits at the end.
|
|
*/
|
|
:host(.toggle-label-placement-end) .label-text-wrapper {
|
|
@include margin(null, 0, null, $form-control-label-margin);
|
|
}
|
|
|
|
// Input Label Placement - Fixed
|
|
// ----------------------------------------------------------------
|
|
|
|
:host(.toggle-label-placement-fixed) .label-text-wrapper {
|
|
/**
|
|
* The margin between the label and
|
|
* the input should be on the end
|
|
* when the label sits at the start.
|
|
*/
|
|
@include margin(null, $form-control-label-margin, null, 0);
|
|
}
|
|
|
|
/**
|
|
* Label is on the left of the input in LTR and
|
|
* on the right in RTL. Label also has a fixed width.
|
|
*/
|
|
:host(.toggle-label-placement-fixed) .label-text-wrapper {
|
|
flex: 0 0 100px;
|
|
|
|
width: 100px;
|
|
min-width: 100px;
|
|
max-width: 200px;
|
|
}
|
|
|
|
// Toggle Label Placement - Stacked
|
|
// ----------------------------------------------------------------
|
|
|
|
/**
|
|
* Label is on top of the toggle.
|
|
*/
|
|
:host(.toggle-label-placement-stacked) .toggle-wrapper {
|
|
flex-direction: column;
|
|
}
|
|
|
|
:host(.toggle-label-placement-stacked) .label-text-wrapper {
|
|
@include transform(scale(#{$form-control-label-stacked-scale}));
|
|
|
|
/**
|
|
* The margin between the label and
|
|
* the toggle should be on the bottom
|
|
* when the label sits on top.
|
|
*/
|
|
@include margin(null, 0, $form-control-label-margin, 0);
|
|
|
|
/**
|
|
* Label text should not extend
|
|
* beyond the bounds of the toggle.
|
|
*/
|
|
max-width: calc(100% / #{$form-control-label-stacked-scale});
|
|
}
|
|
|
|
:host(.toggle-label-placement-stacked.toggle-alignment-start) .label-text-wrapper {
|
|
@include transform-origin(start, top);
|
|
}
|
|
|
|
:host(.toggle-label-placement-stacked.toggle-alignment-center) .label-text-wrapper {
|
|
@include transform-origin(center, top);
|
|
}
|
|
|
|
// 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);
|
|
}
|