fix(textarea): respect rows prop by adjusting min-height in the ionic theme (#30957)
Issue number: resolves internal --------- ## What is the current behavior? - The `rows` attribute is not respected in `ion-textarea` when lower than 3. Some paddings and margins were applied in incorrect places in the `ionic` theme. ## What is the new behavior? - The ionic theme has the following changes: - `.textarea-size-*` classes stopped forcing the `min-height` allowing `rows` to adjust the height - Added an end-to-end test file `textarea.e2e.ts` to verify that the `rows` attribute is respected across different values, sizes, and with auto-grow enabled. - Introduced a new HTML test page (`index.html`) for visual/manual testing of `ion-textarea` with different `rows` and `size` combinations, and with auto-grow enabled. ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information - [Textarea: Autogrow](https://ionic-framework-git-rou-12443-v4-ionic1.vercel.app/src/components/textarea/test/autogrow?ionic:theme=ionic) - [Textarea: Basic](https://ionic-framework-git-rou-12443-v4-ionic1.vercel.app/src/components/textarea/test/basic?ionic:theme=ionic) - [Textarea: Rows](https://ionic-framework-git-rou-12443-v4-ionic1.vercel.app/src/components/textarea/test/rows?ionic:theme=ionic) - [Textarea: Size](https://ionic-framework-git-rou-12443-v4-ionic1.vercel.app/src/components/textarea/test/size?ionic:theme=ionic) - [Textarea: Shape](https://ionic-framework-git-rou-12443-v4-ionic1.vercel.app/src/components/textarea/test/shape?ionic:theme=ionic) --------- Co-authored-by: ionitron <hi@ionicframework.com> Co-authored-by: Maria Hutt <thetaPC@users.noreply.github.com>
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.5 KiB |
119
core/src/components/textarea/test/rows/index.html
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Textarea - Rows</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
<style>
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(250px, 1fr));
|
||||
grid-row-gap: 20px;
|
||||
grid-column-gap: 20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
color: #6f7378;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.grid {
|
||||
grid-template-columns: 1fr;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Textarea - Rows</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content id="content" class="ion-padding">
|
||||
<div class="grid">
|
||||
<!-- Different row values -->
|
||||
<div class="grid-item">
|
||||
<h2>Rows: 1</h2>
|
||||
<ion-textarea
|
||||
rows="1"
|
||||
label="Small"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Rows: 3</h2>
|
||||
<ion-textarea
|
||||
rows="3"
|
||||
label="Medium"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Rows: 8</h2>
|
||||
<ion-textarea
|
||||
rows="8"
|
||||
label="Large"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<!-- Different sizes -->
|
||||
<div class="grid-item">
|
||||
<h2>Rows: 3, Size Small</h2>
|
||||
<ion-textarea
|
||||
rows="3"
|
||||
size="small"
|
||||
label="Small Size"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Rows: 3, Size Medium</h2>
|
||||
<ion-textarea
|
||||
rows="3"
|
||||
size="medium"
|
||||
label="Medium Size"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Rows: 3, Size Large</h2>
|
||||
<ion-textarea
|
||||
rows="3"
|
||||
size="large"
|
||||
label="Large Size"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<!-- Auto-grow -->
|
||||
<div class="grid-item">
|
||||
<h2>Rows: 3, Auto-grow</h2>
|
||||
<ion-textarea
|
||||
rows="3"
|
||||
auto-grow="true"
|
||||
label="Comments"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
</body>
|
||||
</html>
|
||||
88
core/src/components/textarea/test/rows/textarea.e2e.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
/**
|
||||
* This behavior does not vary across directions
|
||||
* This behavior only applies to the `ionic` theme.
|
||||
*/
|
||||
configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('textarea: rows'), () => {
|
||||
test('should respect rows attribute', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<div id="container" style="display: flex; flex-direction: column; gap: 20px;">
|
||||
<ion-textarea
|
||||
rows="1"
|
||||
label="Comments"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
<ion-textarea
|
||||
rows="3"
|
||||
label="Comments"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
<ion-textarea
|
||||
rows="8"
|
||||
label="Comments"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const container = page.locator('#container');
|
||||
await expect(container).toHaveScreenshot(screenshot(`textarea-rows`));
|
||||
});
|
||||
|
||||
test('should respect rows attribute with different sizes', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<div id="container" style="display: flex; flex-direction: column; gap: 20px;">
|
||||
<ion-textarea
|
||||
rows="3"
|
||||
size="small"
|
||||
label="Small Size"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
<ion-textarea
|
||||
rows="3"
|
||||
size="medium"
|
||||
label="Medium Size"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
<ion-textarea
|
||||
rows="3"
|
||||
size="large"
|
||||
label="Large Size"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const container = page.locator('#container');
|
||||
await expect(container).toHaveScreenshot(screenshot(`textarea-rows-sizes`));
|
||||
});
|
||||
|
||||
test('should respect rows when auto-grow is enabled', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<div id="container" style="display: flex; flex-direction: column; gap: 20px;">
|
||||
<ion-textarea
|
||||
rows="3"
|
||||
auto-grow="true"
|
||||
label="Comments"
|
||||
value="1 2 3 4 5 6 7 8 9 0"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const container = page.locator('#container');
|
||||
await expect(container).toHaveScreenshot(screenshot(`textarea-rows-autogrow`));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.2 KiB |
@@ -53,13 +53,6 @@
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
// Textarea Fill: Outline, Native Textarea
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.textarea-fill-outline) textarea {
|
||||
margin-top: globals.$ion-space-100;
|
||||
}
|
||||
|
||||
// Focus
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -27,19 +27,11 @@
|
||||
// Ionic Textarea Sizes
|
||||
// --------------------------------------------------
|
||||
|
||||
// Setting height to 0 allows it to collapse in height
|
||||
// instead of growing above the min height by default.
|
||||
.textarea-wrapper-inner {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
:host(.textarea-size-small) .textarea-wrapper-inner {
|
||||
--padding-top: #{globals.$ion-space-200};
|
||||
--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 {
|
||||
@@ -47,8 +39,6 @@
|
||||
--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 {
|
||||
@@ -56,8 +46,13 @@
|
||||
--padding-end: #{globals.$ion-space-500};
|
||||
--padding-bottom: #{globals.$ion-space-400};
|
||||
--padding-start: #{globals.$ion-space-500};
|
||||
}
|
||||
|
||||
min-height: globals.$ion-scale-3600;
|
||||
// Native Textarea
|
||||
// --------------------------------------------------
|
||||
|
||||
:host .native-wrapper::after {
|
||||
@include globals.padding(0);
|
||||
}
|
||||
|
||||
// Ionic Textarea Shapes
|
||||
@@ -75,17 +70,6 @@
|
||||
--border-radius: #{globals.$ion-rectangular-xl};
|
||||
}
|
||||
|
||||
// Textarea Wrapper
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
.textarea-wrapper {
|
||||
gap: globals.$ion-space-100;
|
||||
}
|
||||
|
||||
.textarea-wrapper-inner {
|
||||
@include globals.padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
|
||||
}
|
||||
|
||||
// Textarea Auto Grow
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
@@ -101,36 +85,54 @@
|
||||
max-height: inherit;
|
||||
}
|
||||
|
||||
// Textarea Label
|
||||
// Textarea Wrapper
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
.label-text-wrapper {
|
||||
@include globals.typography(globals.$ion-body-sm-medium);
|
||||
|
||||
max-width: globals.$ion-scale-5000;
|
||||
|
||||
transition: color globals.$ion-transition-time-150 globals.$ion-transition-curve-expressive,
|
||||
transform globals.$ion-transition-time-150 globals.$ion-transition-curve-expressive;
|
||||
|
||||
color: globals.$ion-text-subtle;
|
||||
.textarea-wrapper {
|
||||
gap: globals.$ion-space-100;
|
||||
}
|
||||
|
||||
:host(.label-floating) .label-text-wrapper {
|
||||
@include globals.transform(none);
|
||||
.textarea-wrapper-inner {
|
||||
@include globals.padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
|
||||
}
|
||||
|
||||
// Textarea Slotted Content
|
||||
:host([rows]:not([auto-grow])) .textarea-wrapper-inner {
|
||||
@include globals.padding(0, var(--padding-end), 0, var(--padding-start));
|
||||
}
|
||||
|
||||
/**
|
||||
* Top and bottom padding are applied to ensure that text remains visible
|
||||
* as it scrolls past the container boundaries. This provides a "sneak peek"
|
||||
* of the content transitioning off-screen, mirroring native textarea behavior
|
||||
* where text isn't immediately clipped or "glued" to the border at the
|
||||
* scroll limits.
|
||||
*/
|
||||
:host([rows]:not([auto-grow])) .textarea-wrapper-inner .native-textarea {
|
||||
padding-top: var(--padding-top);
|
||||
padding-bottom: var(--padding-bottom);
|
||||
}
|
||||
|
||||
// Textarea Highlight
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
ion-icon {
|
||||
--color: globals.$ion-icon-subtlest;
|
||||
|
||||
font-size: globals.$ion-scale-400;
|
||||
:host(.has-focus.ion-valid),
|
||||
:host(.ion-touched.ion-invalid) {
|
||||
--border-width: #{globals.$ion-border-size-025};
|
||||
}
|
||||
|
||||
.start-slot-wrapper,
|
||||
.end-slot-wrapper {
|
||||
margin-top: globals.$ion-space-050;
|
||||
.textarea-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);
|
||||
}
|
||||
|
||||
// Textarea Bottom Content
|
||||
@@ -154,27 +156,83 @@ ion-icon {
|
||||
color: var(--highlight-color-valid);
|
||||
}
|
||||
|
||||
:host(.has-focus.ion-valid),
|
||||
:host(.ion-touched.ion-invalid) {
|
||||
--border-width: #{globals.$ion-border-size-025};
|
||||
}
|
||||
|
||||
// Textarea Highlight
|
||||
// Textarea Label
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
.textarea-highlight {
|
||||
@include globals.position(null, null, -1px, 0);
|
||||
.label-text-wrapper {
|
||||
@include globals.typography(globals.$ion-body-sm-medium);
|
||||
|
||||
position: absolute;
|
||||
max-width: globals.$ion-scale-5000;
|
||||
|
||||
width: 100%;
|
||||
height: globals.$ion-border-size-050;
|
||||
transition: color globals.$ion-transition-time-150 globals.$ion-transition-curve-expressive,
|
||||
transform globals.$ion-transition-time-150 globals.$ion-transition-curve-expressive;
|
||||
|
||||
transform: scale(0);
|
||||
color: globals.$ion-text-subtle;
|
||||
}
|
||||
|
||||
transition: transform globals.$ion-transition-time-200;
|
||||
:host(.label-floating) .label-text-wrapper {
|
||||
@include globals.transform(none);
|
||||
}
|
||||
|
||||
background: var(--border-color);
|
||||
/**
|
||||
* This makes the label sit above the textarea.
|
||||
*/
|
||||
:host(.label-floating) .label-text-wrapper {
|
||||
$form-control-label-stacked-scale: 0.75;
|
||||
|
||||
/**
|
||||
* Label text should not extend
|
||||
* beyond the bounds of the textarea.
|
||||
*/
|
||||
max-width: calc(100% / #{$form-control-label-stacked-scale});
|
||||
}
|
||||
|
||||
.textarea-wrapper textarea {
|
||||
/**
|
||||
* When the floating label appears on top of the
|
||||
* textarea, we need to fade the textarea out so that the
|
||||
* label does not overlap with the placeholder.
|
||||
*/
|
||||
transition: opacity globals.$ion-transition-time-150 globals.$ion-transition-curve-expressive;
|
||||
}
|
||||
|
||||
// Textarea Label Placement - Fixed
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Label is on the left of the textarea in LTR and
|
||||
* on the right in RTL. Label also has a fixed width.
|
||||
*/
|
||||
:host(.textarea-label-placement-fixed) .label-text {
|
||||
$text-wrapper-width: calc(globals.$ion-scale-2400 + globals.$ion-space-100);
|
||||
|
||||
flex: 0 0 $text-wrapper-width;
|
||||
|
||||
width: $text-wrapper-width;
|
||||
min-width: $text-wrapper-width;
|
||||
max-width: globals.$ion-scale-5000;
|
||||
}
|
||||
|
||||
// Textarea Slotted Content
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
ion-icon {
|
||||
--color: globals.$ion-icon-subtlest;
|
||||
|
||||
font-size: globals.$ion-scale-400;
|
||||
}
|
||||
|
||||
// Start / End Slots
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
.start-slot-wrapper,
|
||||
.end-slot-wrapper {
|
||||
margin-top: globals.$ion-space-050;
|
||||
}
|
||||
|
||||
:host([rows]:not([auto-grow])) .start-slot-wrapper,
|
||||
:host([rows]:not([auto-grow])) .end-slot-wrapper {
|
||||
@include globals.padding(var(--padding-top), 0, var(--padding-bottom), 0);
|
||||
}
|
||||
|
||||
// Textarea Focus
|
||||
@@ -237,42 +295,3 @@ ion-icon {
|
||||
:host(.textarea-readonly) {
|
||||
--background: #{globals.$ion-bg-input-read-only};
|
||||
}
|
||||
|
||||
/**
|
||||
* This makes the label sit above the textarea.
|
||||
*/
|
||||
:host(.label-floating) .label-text-wrapper {
|
||||
$form-control-label-stacked-scale: 0.75;
|
||||
|
||||
/**
|
||||
* Label text should not extend
|
||||
* beyond the bounds of the textarea.
|
||||
*/
|
||||
max-width: calc(100% / #{$form-control-label-stacked-scale});
|
||||
}
|
||||
|
||||
.textarea-wrapper textarea {
|
||||
/**
|
||||
* When the floating label appears on top of the
|
||||
* textarea, we need to fade the textarea out so that the
|
||||
* label does not overlap with the placeholder.
|
||||
*/
|
||||
transition: opacity globals.$ion-transition-time-150 globals.$ion-transition-curve-expressive;
|
||||
}
|
||||
|
||||
// Textarea Label Placement - Fixed
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Label is on the left of the textarea in LTR and
|
||||
* on the right in RTL. Label also has a fixed width.
|
||||
*/
|
||||
:host(.textarea-label-placement-fixed) .label-text {
|
||||
$text-wrapper-width: calc(globals.$ion-scale-2400 + globals.$ion-space-100);
|
||||
|
||||
flex: 0 0 $text-wrapper-width;
|
||||
|
||||
width: $text-wrapper-width;
|
||||
min-width: $text-wrapper-width;
|
||||
max-width: globals.$ion-scale-5000;
|
||||
}
|
||||
|
||||