feat(textarea): add small and large sizes for the ionic theme (#29781)
- Adds the `small` and `large` sizes for the `ionic` theme - Adds tests for the sizes to the existing `size` test
4
core/src/components.d.ts
vendored
@@ -3621,7 +3621,7 @@ export namespace Components {
|
||||
*/
|
||||
"shape"?: 'round';
|
||||
/**
|
||||
* The size of the textarea. If "large", it will have an increased height. By default the size is "medium". This property only applies to the `"ionic"` theme.
|
||||
* The size of the textarea. If "large" it will increase the height of the textarea, while "small" and "medium" provide progressively smaller heights. The default size is "medium". This property only applies to the `"ionic"` theme.
|
||||
*/
|
||||
"size"?: 'small' | 'medium' | 'large';
|
||||
/**
|
||||
@@ -8981,7 +8981,7 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"shape"?: 'round';
|
||||
/**
|
||||
* The size of the textarea. If "large", it will have an increased height. By default the size is "medium". This property only applies to the `"ionic"` theme.
|
||||
* The size of the textarea. If "large" it will increase the height of the textarea, while "small" and "medium" provide progressively smaller heights. The default size is "medium". This property only applies to the `"ionic"` theme.
|
||||
*/
|
||||
"size"?: 'small' | 'medium' | 'large';
|
||||
/**
|
||||
|
||||
@@ -50,23 +50,70 @@
|
||||
<ion-content id="content" class="ion-padding">
|
||||
<div class="grid">
|
||||
<div class="grid-item">
|
||||
<h2>No Fill: No Size</h2>
|
||||
<ion-textarea label="Label" label-placement="stacked" placeholder="Placeholder"></ion-textarea>
|
||||
<h2>Outline: Small Size</h2>
|
||||
<ion-textarea
|
||||
size="small"
|
||||
fill="outline"
|
||||
label="Label"
|
||||
label-placement="stacked"
|
||||
placeholder="Placeholder"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Outline: Small Size, Round Shape</h2>
|
||||
<ion-textarea
|
||||
size="small"
|
||||
fill="outline"
|
||||
shape="round"
|
||||
label="Label"
|
||||
label-placement="stacked"
|
||||
placeholder="Placeholder"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Outline: No Size</h2>
|
||||
<ion-textarea fill="outline" label="Label" label-placement="stacked"></ion-textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>No Fill: No Size, Round Shape</h2>
|
||||
<ion-textarea shape="round" label="Label" label-placement="stacked"></ion-textarea>
|
||||
<ion-textarea
|
||||
fill="outline"
|
||||
label="Label"
|
||||
label-placement="stacked"
|
||||
placeholder="Placeholder"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Outline: No Size, Round Shape</h2>
|
||||
<ion-textarea fill="outline" shape="round" label="Label" label-placement="stacked"></ion-textarea>
|
||||
<ion-textarea
|
||||
fill="outline"
|
||||
shape="round"
|
||||
label="Label"
|
||||
label-placement="stacked"
|
||||
placeholder="Placeholder"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Outline: Large Size</h2>
|
||||
<ion-textarea
|
||||
size="large"
|
||||
fill="outline"
|
||||
label="Label"
|
||||
label-placement="stacked"
|
||||
placeholder="Placeholder"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Outline: Large Size, Round Shape</h2>
|
||||
<ion-textarea
|
||||
size="large"
|
||||
fill="outline"
|
||||
shape="round"
|
||||
label="Label"
|
||||
label-placement="stacked"
|
||||
placeholder="Placeholder"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
|
||||
@@ -6,6 +6,57 @@ import { configs, test } from '@utils/test/playwright';
|
||||
*/
|
||||
configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('textarea: size'), () => {
|
||||
test.describe('textarea: size small', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-textarea
|
||||
size="small"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
></ion-textarea>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const textarea = page.locator('ion-textarea');
|
||||
await expect(textarea).toHaveScreenshot(screenshot(`textarea-size-small`));
|
||||
});
|
||||
test('should render correctly with stacked label', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-textarea
|
||||
size="small"
|
||||
label="Email"
|
||||
label-placement="stacked"
|
||||
value="hi@ionic.io"
|
||||
></ion-textarea>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const textarea = page.locator('ion-textarea');
|
||||
await expect(textarea).toHaveScreenshot(screenshot(`textarea-size-small-label-stacked`));
|
||||
});
|
||||
test('should not have visual regressions with fill outline', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-textarea
|
||||
size="small"
|
||||
fill="outline"
|
||||
label="Email"
|
||||
label-placement="stacked"
|
||||
value="hi@ionic.io"
|
||||
></ion-textarea>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const textarea = page.locator('ion-textarea');
|
||||
await expect(textarea).toHaveScreenshot(screenshot(`textarea-size-small-outline`));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('textarea: size medium', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(
|
||||
@@ -53,5 +104,56 @@ configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screensh
|
||||
await expect(textarea).toHaveScreenshot(screenshot(`textarea-size-medium-outline`));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('textarea: size large', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-textarea
|
||||
size="large"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
></ion-textarea>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const textarea = page.locator('ion-textarea');
|
||||
await expect(textarea).toHaveScreenshot(screenshot(`textarea-size-large`));
|
||||
});
|
||||
test('should render correctly with stacked label', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-textarea
|
||||
size="large"
|
||||
label="Email"
|
||||
label-placement="stacked"
|
||||
value="hi@ionic.io"
|
||||
></ion-textarea>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const textarea = page.locator('ion-textarea');
|
||||
await expect(textarea).toHaveScreenshot(screenshot(`textarea-size-large-label-stacked`));
|
||||
});
|
||||
test('should not have visual regressions with fill outline', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-textarea
|
||||
size="large"
|
||||
fill="outline"
|
||||
label="Email"
|
||||
label-placement="stacked"
|
||||
value="hi@ionic.io"
|
||||
></ion-textarea>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const textarea = page.locator('ion-textarea');
|
||||
await expect(textarea).toHaveScreenshot(screenshot(`textarea-size-large-outline`));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
@@ -13,10 +13,6 @@
|
||||
--placeholder-color: #{globals.$ionic-color-neutral-800};
|
||||
--placeholder-opacity: 1;
|
||||
--background: #{globals.$ionic-color-base-white};
|
||||
--padding-top: #{globals.$ionic-space-300};
|
||||
--padding-end: #{globals.$ionic-space-400};
|
||||
--padding-bottom: #{globals.$ionic-space-300};
|
||||
--padding-start: #{globals.$ionic-space-400};
|
||||
|
||||
@include globals.typography(globals.$ionic-body-md-regular);
|
||||
}
|
||||
@@ -30,10 +26,33 @@
|
||||
height: 0;
|
||||
}
|
||||
|
||||
:host(.textarea-size-small) .textarea-wrapper-inner {
|
||||
--padding-top: #{globals.$ionic-space-200};
|
||||
--padding-end: #{globals.$ionic-space-300};
|
||||
--padding-bottom: #{globals.$ionic-space-200};
|
||||
--padding-start: #{globals.$ionic-space-300};
|
||||
|
||||
min-height: globals.$ionic-scale-2800;
|
||||
}
|
||||
|
||||
:host(.textarea-size-medium) .textarea-wrapper-inner {
|
||||
--padding-top: #{globals.$ionic-space-300};
|
||||
--padding-end: #{globals.$ionic-space-400};
|
||||
--padding-bottom: #{globals.$ionic-space-300};
|
||||
--padding-start: #{globals.$ionic-space-400};
|
||||
|
||||
min-height: globals.$ionic-scale-3400;
|
||||
}
|
||||
|
||||
:host(.textarea-size-large) .textarea-wrapper-inner {
|
||||
--padding-top: #{globals.$ionic-space-400};
|
||||
--padding-end: #{globals.$ionic-space-500};
|
||||
--padding-bottom: #{globals.$ionic-space-400};
|
||||
--padding-start: #{globals.$ionic-space-500};
|
||||
|
||||
min-height: globals.$ionic-scale-3600;
|
||||
}
|
||||
|
||||
// Textarea Wrapper
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -249,8 +249,9 @@ export class Textarea implements ComponentInterface {
|
||||
@Prop() shape?: 'round';
|
||||
|
||||
/**
|
||||
* The size of the textarea. If "large", it will have an increased height. By default the
|
||||
* size is "medium". This property only applies to the `"ionic"` theme.
|
||||
* The size of the textarea. If "large" it will increase the height of the textarea, while
|
||||
* "small" and "medium" provide progressively smaller heights. The default size is "medium".
|
||||
* This property only applies to the `"ionic"` theme.
|
||||
*/
|
||||
@Prop() size?: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
|
||||