-
Notifications
You must be signed in to change notification settings - Fork 79
feat(text-area): add calcite-text-area component #5644
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
anveshmekala
merged 111 commits into
master
from
anveshmekala/836-add-texarea-component
Mar 23, 2023
Merged
Changes from 106 commits
Commits
Show all changes
111 commits
Select commit
Hold shift + click to select a range
4693a44
feat(textarea): add textareacomponent
anveshmekala a66a339
implement label & form components
anveshmekala fe688cf
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 18a54d6
allow user to type beyond maxlength limit
anveshmekala 03b5287
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 1f07b3a
fix e2e
anveshmekala a7c4c8d
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 345e57d
add public methods
anveshmekala 0bc2598
add validation
anveshmekala 31d6547
add custom error handling and tests
anveshmekala d7b1d7b
add more tests
anveshmekala 9af159d
add more tests
anveshmekala edd920f
add form handling when character length is under limit
anveshmekala 431f2bf
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 5da7a90
prettify
anveshmekala cbd3e42
add wrapper and include footer on initial tab
anveshmekala 410ecc0
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala b571ee1
more cleanup
anveshmekala b2cce37
add resize observer
anveshmekala 422d756
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 935c6ba
fix build error
anveshmekala 53db818
change focus order and remove tab index
anveshmekala 80278c7
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala d60cb78
add demos
anveshmekala 52a6170
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala dee0454
fix positioning overlap
anveshmekala 84968b1
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 99b3f80
add read me
anveshmekala b6f0128
add storybook
anveshmekala d67b401
remove minlenth and refactor
anveshmekala 3a49121
fix test error
anveshmekala d3ea364
increase inline-size when slotted
anveshmekala a0cedc2
add more test
anveshmekala 0b2da56
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 9321d32
add missing jsdoc for events
anveshmekala e5522a6
more doc updates
anveshmekala d9ae7ae
feeback changes
anveshmekala 4d39f8d
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 131395e
use slotted content when value is null
anveshmekala c5978be
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala a501272
restore footer-slotted css class
anveshmekala f8a010f
add back test
anveshmekala cbd6c31
make footer conditional
anveshmekala 705084d
revert package-lock changes
anveshmekala 9d3b200
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala a3b6755
fix resize disabled y
anveshmekala 621ed17
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 16e6d94
set height and width to auto on resize
anveshmekala db7aa4d
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 7fa99cc
disable pointer events
anveshmekala df3bb75
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 0e23d8b
fix tests
anveshmekala 0e7226d
implement t9ncomponent
anveshmekala 1bf35a1
refactor
anveshmekala 01e761d
restore spacing.11 in tailwind
anveshmekala 60319ef
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala a09790f
fix resizing issue
anveshmekala 6c91c9e
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 1e0e522
remove return on resize
anveshmekala 4594bea
refactor
anveshmekala 820b557
add setTimeout
anveshmekala b3bf3d0
set timeout to 150ms
anveshmekala d68983f
set auto height on vertical resize
anveshmekala 9ff4471
fix build errors
anveshmekala b0cdc21
decrease timeout
anveshmekala 5e27fd6
fix footer enabled dragging issue
anveshmekala ae2065e
refactor
anveshmekala f01dff5
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 10cac6d
remove flex and add block containers
anveshmekala c92f5bc
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 3205cd7
refactor
anveshmekala b21e10f
feedback changes
anveshmekala b140bfc
fix textarea shrinking on focus
anveshmekala df78452
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 6a4d256
move maxlength to the right
anveshmekala 3456770
feedback changes
anveshmekala 99e8f2c
add disabled e2e
anveshmekala 3d1ccff
cleanup
anveshmekala fdbb886
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala e40a14f
remove irrelavent tests
anveshmekala 6a612a1
fix textarea height issue
anveshmekala 3a9764e
feedback changes
anveshmekala f853bd9
rename private properties
anveshmekala b500bad
fix positioning and characterlength issue
anveshmekala 1ffe8d8
refactor
anveshmekala b457901
rename maxlength to maxLength
anveshmekala 7e1cd51
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala d2ac102
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 34b29d4
add demo for debugging
anveshmekala 81b6f7a
feedback changes
anveshmekala 13a126d
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 4c4f6a3
change textarea to texta-area
anveshmekala 6e423ff
fix tests
anveshmekala 8c491ec
update stories and remove unwanted e2e tests
anveshmekala 0f303d8
rename resize props
anveshmekala 942c502
fix resizing behavior
anveshmekala 7824722
Merge branch 'master' into anveshmekala/836-add-texarea-component
anveshmekala 0093eb7
change events names to camelcase
anveshmekala 526c6a1
update usage files
anveshmekala 3a7c4d8
update demo page and font weight for character limit
anveshmekala ee48026
fix resizing error
anveshmekala 04ac12c
disable resize on mobile devices
anveshmekala dfc1ea1
update readme typo
anveshmekala 149157b
fix alignment for footer-end slot only use case & text whitespace for…
anveshmekala 696f6de
fix slottedElementsDarkModeRTL screenshot test
anveshmekala c7d5644
remove text-area issue demo page
anveshmekala 1782a90
more feedback changes
anveshmekala 0be6dc2
rename overLimit to tooLong
anveshmekala b2d9e7e
fix displaying form handling error & editorial feedback changes
anveshmekala 6dfbd7f
add jsdoc description to autofocus prop
anveshmekala f6b9697
selectText method wait for component to load
anveshmekala File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions
4
src/components/text-area/assets/text-area/t9n/messages_en.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"invalid": "Invalid", | ||
"overLimit": "Character limit exceeded" | ||
anveshmekala marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# calcite-text-area | ||
|
||
<!-- Auto Generated Below --> | ||
|
||
## Usage | ||
|
||
### Basic | ||
|
||
```html | ||
<calcite-text-area placeholder="Add Notes"></calcite-text-area> | ||
``` | ||
|
||
### Exceeding-max-length | ||
|
||
Renders text-area with | ||
|
||
```html | ||
<calcite-text-area placeholder="Add Notes" value="Rocky Mountains National Park" max-length="20"></calcite-text-area> | ||
``` | ||
|
||
## Properties | ||
|
||
| Property | Attribute | Description | Type | Default | | ||
| ------------------ | ------------------ | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | ||
| `autofocus` | `autofocus` | When `true`, the component is focused on page load. | `boolean` | `false` | | ||
| `columns` | `columns` | Specifies the number or columns allowed. | `number` | `undefined` | | ||
| `disabled` | `disabled` | When `true`, interaction is prevented and the component is displayed with lower opacity. | `boolean` | `false` | | ||
| `groupSeparator` | `group-separator` | When `true`, number values are displayed with a group separator corresponding to the language and country format. | `boolean` | `false` | | ||
| `label` | `label` | Accessible name for the component. | `string` | `undefined` | | ||
| `maxLength` | `max-length` | Specifies the maximum number of characters allowed. | `number` | `undefined` | | ||
| `messageOverrides` | -- | Use this property to override individual strings used by the component. | `{ invalid?: string; overLimit?: string; }` | `undefined` | | ||
| `name` | `name` | Specifies the name of the component | `string` | `undefined` | | ||
| `numberingSystem` | `numbering-system` | Specifies the Unicode numeral system used by the component for localization. | `"arab" \| "arabext" \| "bali" \| "beng" \| "deva" \| "fullwide" \| "gujr" \| "guru" \| "hanidec" \| "khmr" \| "knda" \| "laoo" \| "latn" \| "limb" \| "mlym" \| "mong" \| "mymr" \| "orya" \| "tamldec" \| "telu" \| "thai" \| "tibt"` | `undefined` | | ||
| `placeholder` | `placeholder` | Specifies the placeholder text for the component. | `string` | `undefined` | | ||
| `readonly` | `readonly` | When `true`, the component's value can be read, but cannot be modified. | `boolean` | `false` | | ||
| `required` | `required` | When `true`, the component must have a value in order for the form to submit. | `boolean` | `false` | | ||
| `resize` | `resize` | When `true`, disables horizontally and vertically resizing the component. | `"both" \| "horizontal" \| "none" \| "vertical"` | `"both"` | | ||
| `rows` | `rows` | Specifies the number or rows allowed. | `number` | `undefined` | | ||
| `scale` | `scale` | Specifies the size of the component. | `"l" \| "m" \| "s"` | `"m"` | | ||
| `value` | `value` | The component's value. | `string` | `undefined` | | ||
| `wrap` | `wrap` | Specifies the wrapping mechanism for the text. | `"hard" \| "soft"` | `"soft"` | | ||
|
||
## Events | ||
|
||
| Event | Description | Type | | ||
| ----------------------- | ----------------------------------------------------- | ------------------- | | ||
| `calciteTextAreaChange` | Fires each time a new `value` is typed and committed. | `CustomEvent<void>` | | ||
| `calciteTextAreaInput` | Fires each time a new `value` is typed. | `CustomEvent<void>` | | ||
|
||
## Methods | ||
|
||
### `selectText() => Promise<void>` | ||
|
||
Selects all text of the component's `value`. | ||
|
||
#### Returns | ||
|
||
Type: `Promise<void>` | ||
|
||
### `setFocus() => Promise<void>` | ||
|
||
Sets focus on the component. | ||
|
||
#### Returns | ||
|
||
Type: `Promise<void>` | ||
|
||
## Slots | ||
|
||
| Slot | Description | | ||
| ---------------- | ------------------------------------ | | ||
| | A slot for adding text. | | ||
| `"footer-end"` | A slot for adding a trailing footer. | | ||
| `"footer-start"` | A slot for adding a leading footer. | | ||
|
||
--- | ||
|
||
_Built with [StencilJS](https://stenciljs.com/)_ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
export const CSS = { | ||
characterLimit: "character-limit", | ||
content: "content", | ||
container: "container", | ||
footer: "footer", | ||
resizeDisabled: "resize--disabled", | ||
resizeDisabledX: "resize--disabled-x", | ||
resizeDisabledY: "resize--disabled-y", | ||
characterOverlimit: "character--over-limit", | ||
readonly: "readonly", | ||
textAreaInvalid: "text-area--invalid", | ||
footerSlotted: "footer--slotted", | ||
borderColor: "border--color", | ||
hide: "hide", | ||
blocksizeFull: "block-size--full", | ||
anveshmekala marked this conversation as resolved.
Show resolved
Hide resolved
|
||
footerEndSlotOnly: "footer--end-only" | ||
}; | ||
|
||
export const SLOTS = { | ||
footerStart: "footer-start", | ||
footerEnd: "footer-end" | ||
}; | ||
|
||
export const RESIZE_TIMEOUT = 100; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
import { newE2EPage } from "@stencil/core/testing"; | ||
import { | ||
accessible, | ||
defaults, | ||
disabled, | ||
focusable, | ||
formAssociated, | ||
hidden, | ||
labelable, | ||
reflects, | ||
renders, | ||
t9n | ||
} from "../../tests/commonTests"; | ||
import { CSS } from "./resources"; | ||
|
||
describe("calcite-text-area", () => { | ||
it("renders", async () => { | ||
renders("calcite-text-area", { display: "inline-block" }); | ||
}); | ||
|
||
it("defaults", async () => { | ||
defaults("calcite-text-area", [ | ||
{ | ||
propertyName: "wrap", | ||
defaultValue: "soft" | ||
}, | ||
{ | ||
propertyName: "scale", | ||
defaultValue: "m" | ||
} | ||
]); | ||
}); | ||
|
||
it("honors hidden attribute", () => hidden("calcite-text-area")); | ||
|
||
it("is labelable", () => labelable("calcite-text-area")); | ||
|
||
it("can be disabled", () => disabled("calcite-text-area")); | ||
|
||
it("reflects", async () => | ||
reflects("calcite-text-area", [ | ||
{ | ||
propertyName: "columns", | ||
value: "10" | ||
}, | ||
{ | ||
propertyName: "rows", | ||
value: "50" | ||
}, | ||
{ | ||
propertyName: "scale", | ||
value: "s" | ||
} | ||
])); | ||
|
||
it("is accessible", async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent( | ||
`<calcite-label>add notes<calcite-text-area max-length="50" required name="something" > </calcite-text-area></calcite-label>` | ||
); | ||
await accessible("calcite-text-area", page); | ||
}); | ||
|
||
it("is focusable", () => focusable("calcite-text-area")); | ||
|
||
it("is form associated", () => | ||
formAssociated("calcite-text-area", { | ||
testValue: "zion national park", | ||
expectedSubmitValue: "zion national park", | ||
submitsOnEnter: false | ||
})); | ||
|
||
it("should emit calciteTextareaInput event when user type in the textarea and emit calciteTextareaChange when users tabs out", async () => { | ||
anveshmekala marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const page = await newE2EPage(); | ||
await page.setContent("<calcite-text-area></calcite-text-area>"); | ||
|
||
const element = await page.find("calcite-text-area"); | ||
const inputEventSpy = await element.spyOnEvent("calciteTextAreaInput"); | ||
const changeEventSpy = await element.spyOnEvent("calciteTextAreaChange"); | ||
await page.waitForChanges(); | ||
|
||
await page.keyboard.press("Tab"); | ||
await page.waitForChanges(); | ||
|
||
await page.keyboard.type("rocky"); | ||
await page.waitForChanges(); | ||
|
||
expect(inputEventSpy).toHaveReceivedEventTimes(5); | ||
|
||
await page.keyboard.press("Tab"); | ||
await page.waitForChanges(); | ||
|
||
expect(changeEventSpy).toHaveReceivedEventTimes(1); | ||
}); | ||
|
||
it("should not emit calciteTextareaChange & calciteTextareaInput event when user tabs out of the textarea without typing", async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent("<calcite-text-area></calcite-text-area>"); | ||
|
||
const element = await page.find("calcite-text-area"); | ||
const changeEventSpy = await element.spyOnEvent("calciteTextAreaChange"); | ||
const inputEventSpy = await element.spyOnEvent("calciteTextAreaInput"); | ||
await page.waitForChanges(); | ||
|
||
await page.keyboard.press("Tab"); | ||
await page.waitForChanges(); | ||
|
||
await page.keyboard.press("Tab"); | ||
await page.waitForChanges(); | ||
|
||
expect(changeEventSpy).not.toHaveReceivedEvent(); | ||
expect(inputEventSpy).not.toHaveReceivedEvent(); | ||
}); | ||
|
||
it("should be able to enter characters beyond max-length", async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent("<calcite-text-area></calcite-text-area>"); | ||
|
||
const element = await page.find("calcite-text-area"); | ||
element.setAttribute("max-length", 5); | ||
await page.waitForChanges(); | ||
|
||
await page.keyboard.press("Tab"); | ||
await page.waitForChanges(); | ||
|
||
await page.keyboard.type("rocky mountains"); | ||
await page.waitForChanges(); | ||
|
||
expect(await element.getProperty("value")).toBe("rocky mountains"); | ||
}); | ||
|
||
it("should have footer--slotted class when slotted at both start and end", async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent(`<calcite-text-area > | ||
<calcite-button slot="footer-start">CLEAR</calcite-button> | ||
<calcite-button slot="footer-end">RESET</calcite-button></calcite-text-area>`); | ||
|
||
const element = await page.find("calcite-text-area >>> textarea"); | ||
await page.waitForChanges(); | ||
|
||
expect(element).toHaveClass(CSS.footerSlotted); | ||
}); | ||
|
||
describe("resize", () => { | ||
it("should set CSS resize property to horizontal", async () => { | ||
anveshmekala marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const page = await newE2EPage(); | ||
await page.setContent(`<calcite-text-area resize="horizontal"></calcite-text-area>`); | ||
|
||
const element = await page.find("calcite-text-area >>> textarea"); | ||
await page.waitForChanges(); | ||
|
||
expect((await element.getComputedStyle()).resize).toBe("horizontal"); | ||
}); | ||
|
||
it("should set CSS resize property to vertical", async () => { | ||
const page = await newE2EPage(); | ||
await page.setContent(`<calcite-text-area resize="vertical"></calcite-text-area>`); | ||
|
||
const element = await page.find("calcite-text-area >>> textarea"); | ||
await page.waitForChanges(); | ||
|
||
expect((await element.getComputedStyle()).resize).toBe("vertical"); | ||
}); | ||
}); | ||
|
||
it("supports translations", () => t9n("calcite-text-area")); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.