Skip to content
Open
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions core/src/components/textarea/textarea.common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,17 @@
opacity: 1;
}

/**
* When the rows attribute is set, the textarea should not force a min-height,
* but rather respect the natural height of the textarea, especially when
* rows is set to 1.
*/
:host(.textarea-fill-outline.sc-ion-textarea-md-h[rows]),
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Selector uses generated scope class .sc-ion-textarea-md-h, which is brittle and atypical compared to other styles that key off the stable .md / .ios host classes. Prefer targeting the mode via .md (or another stable mode indicator) instead of the generated scope class so the rule does not depend on Stencil scoping internals.

Suggested change
:host(.textarea-fill-outline.sc-ion-textarea-md-h[rows]),
:host(.textarea-fill-outline.md[rows]),

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@thetaPC thetaPC Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As Copolit mentioned, we shouldn't be targeting generated classes. This should be moved into the textarea.md.outline.scss file since it's for the md styles.

:host(.textarea-label-placement-stacked[rows]),
:host(.textarea-label-placement-floating[rows]) {
min-height: auto;
}

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

Expand Down
7 changes: 0 additions & 7 deletions core/src/components/textarea/textarea.ionic.outline.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,6 @@
border-top: none;
}

// Textarea Fill: Outline, Native Textarea
// ----------------------------------------------------------------

:host(.textarea-fill-outline) textarea {
margin-top: globals.$ion-space-100;
}

// Focus
// ----------------------------------------------------------------

Expand Down
46 changes: 39 additions & 7 deletions core/src/components/textarea/textarea.ionic.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,45 @@
--padding-end: #{globals.$ion-space-300};
--padding-bottom: #{globals.$ion-space-200};
--padding-start: #{globals.$ion-space-300};

min-height: globals.$ion-scale-2800;
}

:host(.textarea-size-medium) .textarea-wrapper-inner {
--padding-top: #{globals.$ion-space-300};
--padding-end: #{globals.$ion-space-400};
--padding-bottom: #{globals.$ion-space-300};
--padding-start: #{globals.$ion-space-400};

min-height: globals.$ion-scale-3400;
}

:host(.textarea-size-large) .textarea-wrapper-inner {
--padding-top: #{globals.$ion-space-400};
--padding-end: #{globals.$ion-space-500};
--padding-bottom: #{globals.$ion-space-400};
--padding-start: #{globals.$ion-space-500};
}

// When the rows attribute is set, the container of the textarea should
// increase in height to accommodate the number of rows.
:host([rows]) .textarea-wrapper-inner {
/**
* Clamp the minimum value to 1 to prevent 0 or negative heights.
* Add 0.5 to show a half-line peek at the next row.
*/
--number-rows: calc(max(var(--host-rows, 1), 1) + 0.5);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to accomplish the styling without creating new CSS variables?


min-height: globals.$ion-scale-3600;
/**
* Calculate the minimum height for the textarea container based on the number of rows.
* - $textarea-row-line-height: Approximate height of a single line based on
* the browser's default line-height: normal (~1.2 × font-size).
* - (var(--number-rows) + 0.5): Show the requested rows plus a half-line peek
* at the next row, hinting that the textarea is scrollable.
* - var(--padding-top), var(--padding-bottom), var(--border-width): Account for
* box-sizing: border-box, which includes padding and border in min-height.
*/
$textarea-row-line-height: 1.2em;

min-height: calc(
var(--number-rows) * #{$textarea-row-line-height} + var(--padding-top, 0px) + var(--padding-bottom, 0px) + var(--border-width, 0px)
);
}

// Ionic Textarea Shapes
Expand Down Expand Up @@ -90,13 +109,17 @@
// ----------------------------------------------------------------

// The height should be auto only when auto-grow is enabled.
:host([auto-grow]) .textarea-wrapper-inner {
// If rows is not set, the height should be auto.
:host(:not([rows])) .textarea-wrapper-inner,
:host([auto-grow]:not([auto-grow="false"])) .textarea-wrapper-inner {
height: auto;
Comment on lines 111 to 115
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description says the :host([auto-grow]) .textarea-wrapper-inner selector should apply only when auto-grow = false, but the updated selector applies when auto-grow is enabled ([auto-grow] and not [auto-grow="false"]). If the description is meant to say “only when auto-grow is enabled”, consider correcting the PR description to avoid confusion.

Copilot uses AI. Check for mistakes.
}

// The min and max height should be inherited if auto-grow is enabled.
// This allows the textarea to grow and shrink as needed.
:host([auto-grow]) .native-wrapper {
// If rows is not set, the height should be auto.
:host(:not([rows])) .native-wrapper,
:host([auto-grow]:not([auto-grow="false"])) .native-wrapper {
min-height: inherit;
Comment on lines 111 to 123
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ionic theme selectors were updated to exclude auto-grow="false", but textarea.common.scss still has multiple :host([auto-grow]) ... rules. If the Stencil boolean prop parses auto-grow="false" as false, those common styles will still apply because the attribute is present, causing inconsistencies across themes. Consider updating the common auto-grow selectors to also exclude [auto-grow="false"] for consistent behavior.

Copilot uses AI. Check for mistakes.
max-height: inherit;
}
Expand Down Expand Up @@ -276,3 +299,12 @@ ion-icon {
min-width: $text-wrapper-width;
max-width: globals.$ion-scale-5000;
}

/*
* As the ionic theme introduces padding in the textarea,
* there is no need to add margin-top to the textarea.
*/
:host(.textarea-label-placement-stacked) textarea,
:host(.textarea-label-placement-floating) textarea {
margin-top: 0;
Comment on lines +305 to +309
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Ionic theme you reset margin-top on the textarea for stacked/floating labels, but the auto-grow sizing uses .native-wrapper::after (in textarea.common.scss) to mirror textarea spacing. If the pseudo-element keeps the old top margin while the textarea margin is zero, auto-grow height calculations can become inconsistent. Consider overriding the corresponding .native-wrapper::after margin for these label placements in the Ionic theme too (or otherwise keeping textarea and pseudo-element spacing in sync).

Suggested change
* there is no need to add margin-top to the textarea.
*/
:host(.textarea-label-placement-stacked) textarea,
:host(.textarea-label-placement-floating) textarea {
margin-top: 0;
* there is no need to add margin-top to the textarea.
* We also need to keep the auto-grow pseudo-element spacing
* in sync with the textarea spacing.
*/
:host(.textarea-label-placement-stacked) textarea,
:host(.textarea-label-placement-floating) textarea {
margin-top: 0;
}
:host(.textarea-label-placement-stacked) .native-wrapper::after,
:host(.textarea-label-placement-floating) .native-wrapper::after {
margin-top: 0;

Copilot uses AI. Check for mistakes.
}
4 changes: 4 additions & 0 deletions core/src/components/textarea/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,10 @@ export class Textarea implements ComponentInterface {
'textarea-disabled': disabled,
'textarea-readonly': readonly,
})}
// For ionic theme, we need to define this css variable
style={
theme === 'ionic' ? { '--host-rows': this.rows !== undefined ? this.rows.toString() : undefined } : undefined
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to accomplish the styling without creating new CSS variables?

}
>
{/**
* htmlFor is needed so that clicking the label always focuses
Expand Down
Loading