Skip to content

feat(input): add styles for ionic theme for fill=solid #30417

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 2 additions & 138 deletions core/src/components/input/input.ionic.outline.scss
Original file line number Diff line number Diff line change
@@ -1,142 +1,6 @@
@use "../../themes/ionic/ionic.globals.scss" as globals;

// Input Fill: Outline (Ionic Theme)
// ----------------------------------------------------------------

:host(.input-fill-outline) {
--border-radius: #{globals.$ion-border-radius-100};
--padding-start: #{globals.$ion-space-300};
--padding-end: #{globals.$ion-space-300};
}

:host(.input-fill-outline.input-size-large) {
--padding-start: #{globals.$ion-space-400};
--padding-end: #{globals.$ion-space-400};
}

:host(.input-fill-outline.input-size-xlarge) {
--padding-start: #{globals.$ion-space-500};
--padding-end: #{globals.$ion-space-500};
}

/**
* The bottom content should never have
* a border with the outline style.
*/
:host(.input-fill-outline) .input-bottom {
border-top: none;
}

:host(.input-fill-outline) .input-wrapper {
/**
* For the ionic theme, the padding needs to sit on the
* native wrapper instead, so that it sits within the
* outline container but does not always affect the
* label text.
*/
@include globals.padding(0);

/**
* Outline inputs do not have a bottom border.
* Instead, they have a border that wraps the
* input + label.
*/
border-bottom: none;

/**
* Do not show a background on the input wrapper as
* this includes the label, instead we apply the
* background to the native wrapper.
*/
background: transparent;
}

:host(.input-fill-outline.input-label-placement-stacked) .label-text-wrapper {
@include globals.transform-origin(start, top);

/**
* Label text should not extend
* beyond the bounds of the input.
*/
max-width: calc(100% - var(--padding-start) - var(--padding-end));
}

:host(.input-fill-outline) .label-text-wrapper {
/**
* The label should appear on top of an outline
* container that overlaps it so it is always clickable.
*/
position: relative;
}

:host(.input-fill-outline) .native-wrapper {
@include globals.border-radius(inherit);
@include globals.padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));

min-height: globals.$ion-scale-1000;

/**
* Apply the background to the native input
* wrapper to only style the input.
*/
background: var(--background);
}

// Input Fill: Outline, Outline Container
// ----------------------------------------------------------------

:host(.input-fill-outline) .input-outline {
@include globals.position(0, 0, 0, 0);
@include globals.border-radius(var(--border-radius));

position: absolute;

width: 100%;
height: 100%;

pointer-events: none;

border: var(--border-width) var(--border-style) var(--border-color);
}

// Input Fill: Outline, Label Placement: Stacked
// ----------------------------------------------------------------

// This makes the label sit above the input.
:host(.label-floating.input-fill-outline.input-label-placement-stacked) .label-text-wrapper {
@include globals.margin(0);
@include globals.padding(globals.$ion-space-100, null);
}

// Start/End Slots
// ----------------------------------------------------------------

:host(.input-fill-outline) ::slotted([slot="start"]) {
margin-inline-end: globals.$ion-space-200;
}

:host(.input-fill-outline) ::slotted([slot="end"]) {
margin-inline-start: globals.$ion-space-200;
}

// Input Shapes
// --------------------------------------------------

:host(.input-fill-outline.input-shape-soft) {
--border-radius: #{globals.$ion-border-radius-200};
}

:host(.input-fill-outline.input-shape-round) {
--border-radius: #{globals.$ion-border-radius-400};
}

:host(.input-fill-outline.input-shape-rectangular) {
--border-radius: #{globals.$ion-border-radius-0};
}

// Input Focus
// ----------------------------------------------------------------

:host(.input-fill-outline.has-focus) {
--border-width: #{globals.$ion-border-size-050};
--background: #{globals.$ion-primitives-base-white};
--border-color: #{globals.$ion-primitives-neutral-500};
}
160 changes: 136 additions & 24 deletions core/src/components/input/input.ionic.scss
Original file line number Diff line number Diff line change
@@ -1,26 +1,128 @@
@use "../../themes/ionic/ionic.globals.scss" as globals;
@use "./input.common";
@forward "./input.ionic.outline.scss";

@forward "./input.ionic.solid.scss";
// Ionic Input
// --------------------------------------------------

:host {
--color: #{globals.$ion-primitives-neutral-1200};
--border-width: #{globals.$ion-border-size-025};
--border-color: #{globals.$ion-primitives-neutral-500};
--highlight-color-valid: #{globals.$ion-semantics-success-900};
--highlight-color-invalid: #{globals.$ion-semantics-danger-800};
--highlight-color-invalid: #{globals.$ion-border-danger-default};
--placeholder-color: #{globals.$ion-primitives-neutral-800};
--placeholder-opacity: 1;
--background: #{globals.$ion-primitives-base-white};

@include globals.typography(globals.$ion-body-md-regular);
}

// Input Outline Container
// ----------------------------------------------------------------

.input-outline {
@include globals.position(0, 0, 0, 0);
@include globals.border-radius(var(--border-radius));

position: absolute;

width: 100%;
height: 100%;

pointer-events: none;

border: var(--border-width) var(--border-style) var(--border-color);
}

// Input Label Placement: Stacked
// ----------------------------------------------------------------

// This makes the label sit above the input.
:host(.label-floating.input-label-placement-stacked) .label-text-wrapper {
@include globals.margin(0);
@include globals.padding(globals.$ion-space-100, null);
}

.input-wrapper {
/**
* For the ionic theme, the padding needs to sit on the
* native wrapper instead, so that it sits within the
* outline container but does not always affect the
* label text.
*/
@include globals.padding(0);

/**
* Outline inputs do not have a bottom border.
* Instead, they have a border that wraps the
* input + label.
*/
border-bottom: none;

/**
* Do not show a background on the input wrapper as
* this includes the label, instead we apply the
* background to the native wrapper.
*/
background: transparent;
}

.label-text-wrapper {
/**
* The label should appear on top of an outline
* container that overlaps it so it is always clickable.
*/
position: relative;
}

:host(.input-label-placement-stacked) .label-text-wrapper {
@include globals.transform-origin(start, top);

/**
* Label text should not extend
* beyond the bounds of the input.
*/
max-width: calc(100% - var(--padding-start) - var(--padding-end));
}

/**
* The bottom content should never have
* a border with the outline style.
*/
.input-bottom {
border-top: none;
}

.native-wrapper {
@include globals.border-radius(inherit);
@include globals.padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));

min-height: globals.$ion-scale-1000;

/**
* Apply the background to the native input
* wrapper to only style the input.
*/
background: var(--background);
}

// Ionic Input Sizes
// --------------------------------------------------

:host(.input-size-medium) {
--padding-start: #{globals.$ion-space-300};
--padding-end: #{globals.$ion-space-300};
}

:host(.input-size-large) {
--padding-start: #{globals.$ion-space-400};
--padding-end: #{globals.$ion-space-400};
}

:host(.input-size-xlarge) {
--padding-start: #{globals.$ion-space-500};
--padding-end: #{globals.$ion-space-500};
}

:host(.input-size-medium) .native-wrapper {
min-height: globals.$ion-scale-1000;
}
Expand All @@ -33,10 +135,25 @@
min-height: globals.$ion-scale-1400;
}

// Input Shapes
// --------------------------------------------------

:host(.input-shape-soft) {
--border-radius: #{globals.$ion-soft-xl};
}

:host(.input-shape-round) {
--border-radius: #{globals.$ion-round-xl};
}

:host(.input-shape-rectangular) {
--border-radius: #{globals.$ion-rectangular-xl};
}

// Ionic Input Password Toggle Sizes
// --------------------------------------------------

:host ion-input-password-toggle {
:host(.input-size-medium) ion-input-password-toggle {
--size: #{globals.$ion-scale-1000};
}

Expand All @@ -50,7 +167,8 @@

// Target area
// --------------------------------------------------
:host .native-wrapper::after {

.native-wrapper::after {
@include globals.position(50%, 0, null, 0);

position: absolute;
Expand Down Expand Up @@ -78,6 +196,17 @@
z-index: 2;
}

// Start/End Slots
// ----------------------------------------------------------------

::slotted([slot="start"]) {
margin-inline-end: globals.$ion-space-200;
}

::slotted([slot="end"]) {
margin-inline-start: globals.$ion-space-200;
}

// Input Clear Button
// ----------------------------------------------------------------

Expand Down Expand Up @@ -202,29 +331,12 @@
--background: #{globals.$ion-primitives-neutral-100};
}

// Input Highlight
// ----------------------------------------------------------------

.input-highlight {
@include globals.position(null, null, -1px, 0);

position: absolute;

width: 100%;
height: globals.$ion-border-size-050;

transform: scale(0);

transition: transform globals.$ion-transition-time-200;

background: var(--border-color);
}

// Input Focus
// ----------------------------------------------------------------

:host(.has-focus) {
--border-color: #{globals.$ion-border-focus-default};
--border-width: #{globals.$ion-border-size-050};
}

:host(.has-focus) .input-highlight {
Expand Down
Loading
Loading