Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
66f7231
feat(textarea): add default textarea styles
brandyscarney Aug 16, 2024
98bdc88
fix(textarea): add proper structure, padding and spacing
brandyscarney Aug 16, 2024
e55e4e2
style: lint
brandyscarney Aug 16, 2024
66f4adb
feat(textarea): add size property with default set to medium
brandyscarney Aug 16, 2024
25ae1a1
test(textarea): add test for sizes
brandyscarney Aug 16, 2024
ab46a02
fix(textarea): move padding and spacing to all fills
brandyscarney Aug 16, 2024
91a5823
chore(): add updated snapshots
brandyscarney Aug 16, 2024
ee00a2d
chore: build
brandyscarney Aug 16, 2024
2f7e2a7
Merge branch 'next' into ROU-10916
brandyscarney Aug 16, 2024
1db5bbc
docs(textarea): improve size description
brandyscarney Aug 19, 2024
e54fb4d
fix(textarea): separate common and native styles
brandyscarney Aug 19, 2024
74d9fb9
chore(): add updated snapshots
Ionitron Aug 19, 2024
f4b7bc3
refactor(textarea): more cleanup between common and native
brandyscarney Aug 19, 2024
4947747
style: remove escapes
brandyscarney Aug 19, 2024
9a46466
style: lint
brandyscarney Aug 19, 2024
694242b
fix(textarea): use min height to autogrow
brandyscarney Aug 19, 2024
2273735
feat(textarea): add sm and lg sizes for ionic theme
brandyscarney Aug 19, 2024
f852a85
test(textarea): update size test to include sm and lg
brandyscarney Aug 19, 2024
630c12f
chore(): add updated snapshots
brandyscarney Aug 19, 2024
f82126a
style: lint
brandyscarney Aug 19, 2024
cff97fa
test(textarea): update basic test
brandyscarney Aug 19, 2024
1b3fc07
fix(textarea): allow height to collapse to use the true min height
brandyscarney Aug 19, 2024
6df45be
Merge branch 'ROU-10916' into ROU-10917
brandyscarney Aug 19, 2024
9fe763a
chore(): add updated snapshots
brandyscarney Aug 19, 2024
ea98cf3
style(textarea): remove unused files, fix imports
brandyscarney Aug 20, 2024
9e3ff8b
test(textarea): remove round shape
brandyscarney Aug 20, 2024
559a6f3
fix(textarea): use space var for textarea margin
brandyscarney Aug 20, 2024
e6d53fb
fix(textarea): use tokens and properly position slotted content
brandyscarney Aug 20, 2024
56b58ee
style: lint
brandyscarney Aug 20, 2024
f5d0725
chore(): add updated snapshots
brandyscarney Aug 20, 2024
303c134
fix(textarea): properly grow and shrink based on auto-grow
brandyscarney Aug 20, 2024
aceb60b
Merge branch 'ROU-10916' into ROU-10917
brandyscarney Aug 21, 2024
06abd94
test(textarea): remove round shape from size test
brandyscarney Aug 21, 2024
548d51b
docs(textarea): improve size description
brandyscarney Aug 21, 2024
e9da9ba
Merge branch 'next' into ROU-10917
brandyscarney Aug 21, 2024
1e2d23b
chore(): add updated snapshots
Ionitron Aug 21, 2024
445d6f1
feat(textarea): add support for soft and rectangular shapes
brandyscarney Aug 21, 2024
f50285e
test(textarea): add test for different shapes
brandyscarney Aug 21, 2024
0866be7
chore(): add updated snapshots
brandyscarney Aug 21, 2024
58b5cce
chore(): add updated snapshots
Ionitron Aug 21, 2024
8181c3e
Merge branch 'next' into ROU-10918
brandyscarney Aug 21, 2024
20a3b00
fix(textarea): account for the round shape being defined in md
brandyscarney Aug 21, 2024
47e3497
chore(): add updated snapshots
brandyscarney Aug 21, 2024
9d5838a
Merge branch 'next' into ROU-10918
brandyscarney Aug 22, 2024
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
2 changes: 1 addition & 1 deletion core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2279,7 +2279,7 @@ ion-textarea,prop,placeholder,string | undefined,undefined,false,false
ion-textarea,prop,readonly,boolean,false,false,false
ion-textarea,prop,required,boolean,false,false,false
ion-textarea,prop,rows,number | undefined,undefined,false,false
ion-textarea,prop,shape,"round" | undefined,undefined,false,false
ion-textarea,prop,shape,"rectangular" | "round" | "soft" | undefined,undefined,false,false
ion-textarea,prop,size,"large" | "medium" | "small" | undefined,'medium',false,false
ion-textarea,prop,spellcheck,boolean,false,false,false
ion-textarea,prop,theme,"ios" | "md" | "ionic",undefined,false,false
Expand Down
8 changes: 4 additions & 4 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3617,9 +3617,9 @@ export namespace Components {
*/
"setFocus": () => Promise<void>;
/**
* The shape of the textarea. If "round" it will have an increased border radius.
* Set to `"soft"` for a textarea with slightly rounded corners, `"round"` for a textarea with fully rounded corners, or `"rectangular"` for a textarea without rounded corners. Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
*/
"shape"?: 'round';
"shape"?: 'soft' | 'round' | 'rectangular';
/**
* 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.
*/
Expand Down Expand Up @@ -8977,9 +8977,9 @@ declare namespace LocalJSX {
*/
"rows"?: number;
/**
* The shape of the textarea. If "round" it will have an increased border radius.
* Set to `"soft"` for a textarea with slightly rounded corners, `"round"` for a textarea with fully rounded corners, or `"rectangular"` for a textarea without rounded corners. Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
*/
"shape"?: 'round';
"shape"?: 'soft' | 'round' | 'rectangular';
/**
* 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.
*/
Expand Down
97 changes: 97 additions & 0 deletions core/src/components/textarea/test/shape/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Textarea - Shape</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<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(2, 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 - Shape</ion-title>
</ion-toolbar>
</ion-header>

<ion-content id="content" class="ion-padding">
<div class="grid">
<div class="grid-item">
<h2>Default</h2>
<ion-textarea
fill="outline"
label="Label"
label-placement="stacked"
placeholder="Placeholder"
></ion-textarea>
</div>

<div class="grid-item">
<h2>Round</h2>
<ion-textarea
shape="round"
fill="outline"
label="Label"
label-placement="stacked"
placeholder="Placeholder"
></ion-textarea>
</div>

<div class="grid-item">
<h2>Soft</h2>
<ion-textarea
shape="soft"
fill="outline"
label="Label"
label-placement="stacked"
placeholder="Placeholder"
></ion-textarea>
</div>

<div class="grid-item">
<h2>Rectangular</h2>
<ion-textarea
shape="rectangular"
fill="outline"
label="Label"
label-placement="stacked"
placeholder="Placeholder"
></ion-textarea>
</div>
</div>
</ion-content>
</ion-app>
</body>
</html>
100 changes: 100 additions & 0 deletions core/src/components/textarea/test/shape/textarea.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';

/**
* This behavior does not vary across directions
* The round shape is only available in the Ionic and Material Design themes
*/
configs({ modes: ['md', 'ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('textarea: shape'), () => {
test.describe('default', () => {
test('should not have visual regressions', async ({ page }) => {
await page.setContent(
`
<ion-textarea
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-default`));
});
});

test.describe('round', () => {
test('should not have visual regressions', async ({ page }) => {
await page.setContent(
`
<ion-textarea
shape="round"
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-round`));
});
});
});
});

/**
* The soft and rectangular shapes are only available in the Ionic theme
*/
configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('textarea: shape'), () => {
test.describe('soft', () => {
test('should not have visual regressions', async ({ page }) => {
await page.setContent(
`
<ion-textarea
shape="soft"
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-soft`));
});
});

test.describe('rectangular', () => {
test('should not have visual regressions', async ({ page }) => {
await page.setContent(
`
<ion-textarea
shape="rectangular"
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-rectangular`));
});
});
});
});
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.
38 changes: 1 addition & 37 deletions core/src/components/textarea/test/size/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<style>
.grid {
display: grid;
grid-template-columns: repeat(2, minmax(250px, 1fr));
grid-template-columns: repeat(3, minmax(250px, 1fr));
grid-row-gap: 20px;
grid-column-gap: 20px;
}
Expand All @@ -27,7 +27,6 @@
color: #6f7378;

margin-top: 10px;
padding-left: 16px;
}

@media screen and (max-width: 800px) {
Expand Down Expand Up @@ -60,18 +59,6 @@ <h2>Outline: Small Size</h2>
></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
Expand All @@ -82,17 +69,6 @@ <h2>Outline: No Size</h2>
></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"
placeholder="Placeholder"
></ion-textarea>
</div>

<div class="grid-item">
<h2>Outline: Large Size</h2>
<ion-textarea
Expand All @@ -103,18 +79,6 @@ <h2>Outline: Large Size</h2>
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>
</ion-app>
Expand Down
16 changes: 15 additions & 1 deletion core/src/components/textarea/textarea.ionic.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
// --------------------------------------------------

:host {
--border-radius: #{globals.$ionic-border-radius-400};
--color: #{globals.$ionic-color-neutral-1200};
--highlight-color-valid: #{globals.$ionic-color-success-base};
--highlight-color-invalid: #{globals.$ionic-color-danger-base};
Expand Down Expand Up @@ -53,6 +52,21 @@
min-height: globals.$ionic-scale-3600;
}

// Ionic Textarea Shapes
// --------------------------------------------------

:host(.textarea-shape-soft) {
--border-radius: #{globals.$ionic-border-radius-200};
}

:host(.textarea-shape-round) {
--border-radius: #{globals.$ionic-border-radius-400};
}

:host(.textarea-shape-rectangular) {
--border-radius: #{globals.$ionic-border-radius-0};
}

// Textarea Wrapper
// ----------------------------------------------------------------

Expand Down
23 changes: 20 additions & 3 deletions core/src/components/textarea/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,13 @@ export class Textarea implements ComponentInterface {
@Prop() labelPlacement: 'start' | 'end' | 'floating' | 'stacked' | 'fixed' = 'start';

/**
* The shape of the textarea. If "round" it will have an increased border radius.
* Set to `"soft"` for a textarea with slightly rounded corners,
* `"round"` for a textarea with fully rounded corners, or `"rectangular"`
* for a textarea without rounded corners.
*
* Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
*/
@Prop() shape?: 'round';
@Prop() shape?: 'soft' | 'round' | 'rectangular';

/**
* The size of the textarea. If "large" it will increase the height of the textarea, while
Expand Down Expand Up @@ -541,6 +545,18 @@ export class Textarea implements ComponentInterface {
return this.label !== undefined || this.labelSlot !== null;
}

private getShape(): string | undefined {
const theme = getIonTheme(this);
const { shape } = this;

// TODO(ROU-11050): Update theme check when shapes are defined for all themes.
if (theme === 'ionic' && shape === undefined) {
return 'round';
}

return shape;
}

/**
* Renders the border container when fill="outline".
*/
Expand Down Expand Up @@ -626,8 +642,9 @@ export class Textarea implements ComponentInterface {
}

render() {
const { inputId, disabled, fill, shape, size, labelPlacement, el, hasFocus } = this;
const { inputId, disabled, fill, size, labelPlacement, el, hasFocus } = this;
const theme = getIonTheme(this);
const shape = this.getShape();
const value = this.getValue();
const inItem = hostContext('ion-item', this.el);
const shouldRenderHighlight = theme === 'md' && fill !== 'outline' && !inItem;
Expand Down