Files
ionic-framework/core/src/components/input/input.md.outline.scss
Liam DeBeasi f14c440d63 fix(input, textarea): input does not block floating label (#27870)
Issue number: resolves #27812

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

We currently have CSS to ensure the floating/stacked label is not
obscured by the input/textarea when using the outline styles. However,
it was discovered that this scenario can happen with any
floating/stacked label not just when the input/textarea is using the
outline style.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Floating/stacked labels appear on top of the input/textarea regardless
of fill mode.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->


Dev build: `7.2.1-dev.11690464203.1b2b4419`

---------

Co-authored-by: ionitron <hi@ionicframework.com>
2023-08-01 15:48:55 +00:00

222 lines
6.3 KiB
SCSS

@import "./input.vars";
// Input Fill: Outline
// ----------------------------------------------------------------
:host(.input-fill-outline) {
--border-color: #{$background-color-step-300};
--border-radius: 4px;
--padding-start: 16px;
--padding-end: 16px;
}
:host(.input-fill-outline.input-shape-round) {
--border-radius: 28px;
--padding-start: 32px;
--padding-end: 32px;
}
/**
* If the input has a validity state, the
* border should reflect that as a color.
*/
:host(.has-focus.input-fill-outline.ion-valid),
:host(.input-fill-outline.ion-touched.ion-invalid) {
--border-color: var(--highlight-color);
}
/**
* Border should be
* slightly darker on hover.
*/
@media (any-hover: hover) {
:host(.input-fill-outline:hover) {
--border-color: #{$background-color-step-750};
}
}
/**
* The border should get thicker
* and take on component color when
* the input is focused.
*/
:host(.input-fill-outline.has-focus) {
--border-width: 2px;
--border-color: var(--highlight-color);
}
/**
* The bottom content should never have
* a border with the outline style.
*/
:host(.input-fill-outline) .input-bottom {
border-top: none;
}
/**
* Outline inputs do not have a bottom border.
* Instead, they have a border that wraps the
* input + label.
*/
:host(.input-fill-outline) .input-wrapper {
border-bottom: none;
}
:host(.input-fill-outline.input-label-placement-stacked) .label-text-wrapper,
:host(.input-fill-outline.input-label-placement-floating) .label-text-wrapper {
@include transform-origin(start, top);
position: absolute;
/**
* Label text should not extend
* beyond the bounds of the input.
*/
max-width: calc(100% - var(--padding-start) - var(--padding-end));
}
/**
* The label should appear on top of an outline
* container that overlaps it so it is always clickable.
*/
:host(.input-fill-outline) .label-text-wrapper,
:host(.input-fill-outline) .label-text-wrapper {
position: relative;
}
/**
* This makes the label sit above the input.
*/
:host(.has-focus.input-fill-outline.input-label-placement-floating) .label-text-wrapper,
:host(.has-value.input-fill-outline.input-label-placement-floating) .label-text-wrapper,
:host(.input-fill-outline.input-label-placement-stacked) .label-text-wrapper {
@include transform(translateY(-32%), scale(#{$input-floating-label-scale}));
@include margin(0);
/**
* Label text should not extend
* beyond the bounds of the input.
*/
max-width: calc((100% - var(--padding-start) - var(--padding-end) - #{$input-md-floating-label-padding * 2}) / #{$input-floating-label-scale});
}
/**
* This ensures that the input does not
* overlap the floating label while still
* remaining visually centered.
*/
:host(.input-fill-outline.input-label-placement-stacked) input,
:host(.input-fill-outline.input-label-placement-floating) input {
@include margin(6px, 0, 6px, 0);
}
// Input Fill: Outline Outline Container
// ----------------------------------------------------------------
:host(.input-fill-outline) .input-outline-container {
@include position(0, 0, 0, 0);
display: flex;
position: absolute;
width: 100%;
height: 100%;
}
:host(.input-fill-outline) .input-outline-start,
:host(.input-fill-outline) .input-outline-end {
pointer-events: none;
}
/**
* By default, each piece of the container should have
* a top and bottom border. This gives the appearance
* of a unified container with a border.
*/
:host(.input-fill-outline) .input-outline-start,
:host(.input-fill-outline) .input-outline-notch,
:host(.input-fill-outline) .input-outline-end {
border-top: var(--border-width) var(--border-style) var(--border-color);
border-bottom: var(--border-width) var(--border-style) var(--border-color);
}
/**
* Ensures long labels do not cause the notch to flow
* out of bounds.
*/
:host(.input-fill-outline) .input-outline-notch {
max-width: calc(100% - var(--padding-start) - var(--padding-end));
}
/**
* This element ensures that the notch used
* the size of the scaled text so that the
* border cut out is the correct width.
* The text in this element should not
* be interactive.
*/
:host(.input-fill-outline) .notch-spacer {
/**
* We need $input-md-floating-label-padding of padding on the right.
* However, we also subtracted $input-md-floating-label-padding from
* the width of .input-outline-start
* to create space, so we need to take
* that into consideration here.
*/
@include padding(null, #{$input-md-floating-label-padding * 2}, null, null);
font-size: calc(1em * #{$input-floating-label-scale});
opacity: 0;
pointer-events: none;
/**
* The spacer currently inherits
* border-box sizing from the Ionic reset styles.
* However, we do not want to include padding in
* the calculation of the element dimensions.
* This code can be removed if input is updated
* to use the Shadow DOM.
*/
box-sizing: content-box;
}
:host(.input-fill-outline) .input-outline-start {
@include border-radius(var(--border-radius), 0px, 0px, var(--border-radius));
@include border(null, null, null, var(--border-width) var(--border-style) var(--border-color));
/**
* There should be spacing between the translated text
* and .input-outline-start. However, we can't add this
* spacing onto the notch because it would cause the
* label to look like it is not aligned with the
* text input. Instead, we subtract a few pixels from
* this element.
*/
width: calc(var(--padding-start) - #{$input-md-floating-label-padding});
}
:host(.input-fill-outline) .input-outline-end {
@include border(null, var(--border-width) var(--border-style) var(--border-color), null, null);
@include border-radius(0px, var(--border-radius), var(--border-radius), 0px);
/**
* The ending outline fragment
* should take up the remaining free space.
*/
flex-grow: 1;
}
/**
* When the input either has focus or a value,
* there should be a "cut out" at the top for
* the floating/stacked label. We simulate this "cut out"
* by removing the top border from the notch fragment.
*/
:host(.has-focus.input-fill-outline.input-label-placement-floating) .input-outline-notch,
:host(.has-value.input-fill-outline.input-label-placement-floating) .input-outline-notch,
:host(.input-fill-outline.input-label-placement-stacked) .input-outline-notch {
border-top: none;
}