sass-references/angular-material/material/select/select.scss

248 lines
7.6 KiB
SCSS
Raw Permalink Normal View History

2024-12-06 10:42:08 +08:00
@use 'sass:math';
@use '@angular/cdk';
@use '../core/style/vendor-prefixes';
@use '../core/style/variables';
@use '../core/tokens/token-utils';
@use '../core/tokens/m2/mat/select' as tokens-mat-select;
$mat-select-arrow-size: 5px !default;
$mat-select-arrow-margin: 4px !default;
$mat-select-panel-max-height: 275px !default;
$mat-select-placeholder-arrow-space: 2 *
($mat-select-arrow-size + $mat-select-arrow-margin);
$leading-width: 12px !default;
$scale: 0.75 !default;
.mat-mdc-select {
display: inline-block;
width: 100%;
outline: none;
@include token-utils.use-tokens(
tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
@include vendor-prefixes.smooth-font();
@include token-utils.create-token-slot(color, enabled-trigger-text-color);
@include token-utils.create-token-slot(font-family, trigger-text-font);
@include token-utils.create-token-slot(line-height, trigger-text-line-height);
@include token-utils.create-token-slot(font-size, trigger-text-size);
@include token-utils.create-token-slot(font-weight, trigger-text-weight);
@include token-utils.create-token-slot(letter-spacing, trigger-text-tracking);
}
}
@include token-utils.use-tokens(tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
div.mat-mdc-select-panel {
@include token-utils.create-token-slot(box-shadow, container-elevation-shadow);
}
}
.mat-mdc-select-disabled {
@include token-utils.use-tokens(
tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
@include token-utils.create-token-slot(color, disabled-trigger-text-color);
}
}
.mat-mdc-select-trigger {
display: inline-flex;
align-items: center;
cursor: pointer;
position: relative;
box-sizing: border-box;
width: 100%;
.mat-mdc-select-disabled & {
@include vendor-prefixes.user-select(none);
cursor: default;
}
}
.mat-mdc-select-value {
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.mat-mdc-select-value-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.mat-mdc-select-arrow-wrapper {
height: 24px;
flex-shrink: 0;
display: inline-flex;
align-items: center;
.mat-form-field-appearance-fill .mdc-text-field--no-label & {
transform: none;
}
}
.mat-mdc-form-field .mat-mdc-select.mat-mdc-select-invalid .mat-mdc-select-arrow,
.mat-form-field-invalid:not(.mat-form-field-disabled) .mat-mdc-form-field-infix::after {
@include token-utils.use-tokens(tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
@include token-utils.create-token-slot(color, invalid-arrow-color);
}
}
.mat-mdc-select-arrow {
width: $mat-select-arrow-size * 2;
height: $mat-select-arrow-size;
position: relative;
@include token-utils.use-tokens(
tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
@include token-utils.create-token-slot(color, enabled-arrow-color);
.mat-mdc-form-field.mat-focused & {
@include token-utils.create-token-slot(color, focused-arrow-color);
}
.mat-mdc-form-field .mat-mdc-select.mat-mdc-select-disabled & {
@include token-utils.create-token-slot(color, disabled-arrow-color);
}
}
svg {
fill: currentColor;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
@include cdk.high-contrast {
// On Chromium browsers the `currentColor` blends in with the
// background for SVGs so we have to fall back to `CanvasText`.
fill: CanvasText;
.mat-mdc-select-disabled & {
fill: GrayText;
}
}
}
}
// Even though we don't use the MDC styles, we need to keep the classes in the
// DOM for the Gmat versions to work. We need to bump up the specificity here
// so that it's higher than MDC's styles.
div.mat-mdc-select-panel {
width: 100%; // Ensures that the panel matches the overlay width.
max-height: $mat-select-panel-max-height;
outline: 0;
overflow: auto;
padding: 8px 0;
border-radius: 4px;
box-sizing: border-box;
// Workaround in case other MDC menu surface styles bleed in.
position: static;
@include token-utils.use-tokens(
tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
@include token-utils.create-token-slot(background-color, panel-background-color);
}
@include cdk.high-contrast {
outline: solid 1px;
}
.cdk-overlay-pane:not(.mat-mdc-select-panel-above) & {
border-top-left-radius: 0;
border-top-right-radius: 0;
transform-origin: top center;
}
.mat-mdc-select-panel-above & {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
transform-origin: bottom center;
}
.mat-mdc-option {
--mdc-list-list-item-container-color: var(--mat-select-panel-background-color);
}
}
.mat-mdc-select-placeholder {
// Delay the transition until the label has animated about a third of the way through, in
// order to prevent the placeholder from overlapping for a split second.
transition: color variables.$swift-ease-out-duration
math.div(variables.$swift-ease-out-duration, 3)
variables.$swift-ease-out-timing-function;
@include token-utils.use-tokens(
tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
@include token-utils.create-token-slot(color, placeholder-text-color);
}
._mat-animation-noopable & {
transition: none;
}
.mat-form-field-hide-placeholder & {
color: transparent;
// Overwrite browser specific CSS properties that can overwrite the `color` property.
// Some developers seem to use this approach to easily overwrite the placeholder / label color.
-webkit-text-fill-color: transparent;
// Remove the transition to prevent the placeholder
// from overlapping when the label comes back down.
transition: none;
// Prevents the '...' from showing on the parent element.
display: block;
}
}
// Our MDC form field implementation is based on the MDC text field which doesn't include styles
// for select. The select specific styles are not present as they don't use their text field as a
// container. Below are the styles to account for the select arrow icon at the end.
.mat-mdc-form-field-type-mat-select {
&:not(.mat-form-field-disabled) .mat-mdc-text-field-wrapper {
cursor: pointer;
}
&.mat-form-field-appearance-fill {
.mat-mdc-floating-label {
max-width: calc(100% - #{$mat-select-placeholder-arrow-space});
}
.mdc-floating-label--float-above {
$arrow-scale: math.div($mat-select-placeholder-arrow-space, $scale);
max-width: calc(100% / #{$scale} - #{$arrow-scale});
}
}
&.mat-form-field-appearance-outline {
.mdc-notched-outline__notch {
max-width: calc(100% - #{2 * ($mat-select-placeholder-arrow-space + $leading-width)});
}
.mdc-text-field--label-floating .mdc-notched-outline__notch {
max-width: calc(100% - #{$leading-width * 2});
}
}
}
// Used to prevent inline elements from collapsing if their text bindings
// become empty. This is preferrable to inserting a blank space, because the
// space can be read out by screen readers (see #21725).
.mat-mdc-select-min-line:empty::before {
content: ' ';
white-space: pre;
width: 1px;
display: inline-block;
// Prevents some browsers from rendering the element in high contrast mode. Use `visibility`
// instead of `opacity` since VoiceOver + Chrome still reads out the space with the latter.
visibility: hidden;
}
@include token-utils.use-tokens(tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
.mat-form-field-appearance-fill .mat-mdc-select-arrow-wrapper {
@include token-utils.create-token-slot(transform, arrow-transform);
}
}