Files
ionic-framework/core/src/components/input/input.md.outline.scss
Amanda Johnston 357b8b2beb feat(input, textarea, select): add start and end slots (#28583)
Issue number: Resolves #26297

---------

<!-- 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. -->

With the modern form control syntax, it is not possible to add icon
buttons or other decorators to the sides of `ion-input`, `ion-textarea`,
or `ion-select`, as you can with `ion-item`.

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

`start` and `end` slots added to each component.

This PR is a combination of several others that were already approved.
If needed, it might be easiest to review the PRs individually by looking
at the commit history here.

## 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. -->

Docs PR: https://github.com/ionic-team/ionic-docs/pull/3271

Dev build: `7.5.4-dev.11701112913.1ea61220`

---------

Co-authored-by: ionitron <hi@ionicframework.com>
Co-authored-by: Maria Hutt <thetaPC@users.noreply.github.com>
Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
2023-12-01 14:54:10 -06:00

220 lines
5.9 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;
min-height: 56px;
}
: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(.label-floating.input-fill-outline) .label-text-wrapper {
@include transform(translateY(-32%), scale(#{$form-control-label-stacked-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}) / #{$form-control-label-stacked-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 * #{$form-control-label-stacked-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(.label-floating.input-fill-outline) .input-outline-notch {
border-top: none;
}