Skip to content

Commit

Permalink
fix(textarea, textbox): remove enforceCharacterLimit from textbox b…
Browse files Browse the repository at this point in the history
…ased inputs and textarea

due to accessibility concerns the `enforceCharacterLimit` prop has been removed and is no longer
supported. By enforcing a character limit and limiting an input users may not recieve appropriate
feedback of the limit. This can be especially problematic for individuals who rely on assistive
technologies or alternative communication methods

BREAKING CHANGE: The `enforceCharacterLimit` prop has been completely removed and is no longer
supported. We recommend providing adequate feedback to users when they have exceeded the set
`characterLimit` instead
  • Loading branch information
tomdavies73 authored and robinzigmond committed Oct 19, 2023
1 parent a814e14 commit b49f757
Show file tree
Hide file tree
Showing 16 changed files with 23 additions and 283 deletions.
36 changes: 1 addition & 35 deletions cypress/components/number/number.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,37 +81,6 @@ context("Tests for Number component", () => {
}
);

it.each([
[11, 11],
[10, 10],
])(
"should input %s characters and enforce character limit of %s in Number",
(charactersUsed, limit) => {
const inputValue = "12345678901";
const underCharacters =
limit - charactersUsed === 1 ? "character" : "characters";
const overCharacters =
charactersUsed - limit === 1 ? "character" : "characters";

CypressMountWithProviders(
<NumberInputComponent enforceCharacterLimit characterLimit={limit} />
);

commonDataElementInputPreview()
.type(inputValue)
.then(() => {
characterCount().should(
"have.text",
`${
charactersUsed - limit
? `${limit - charactersUsed} ${overCharacters} too many`
: `${charactersUsed - limit} ${underCharacters} left`
}`
);
});
}
);

it.each([
[11, 11, "rgba(0, 0, 0, 0.55)"],
[11, 10, "rgb(203, 55, 74)"],
Expand All @@ -125,10 +94,7 @@ context("Tests for Number component", () => {
charactersUsed - limit === 1 ? "character" : "characters";

CypressMountWithProviders(
<NumberInputComponent
enforceCharacterLimit={false}
characterLimit={limit}
/>
<NumberInputComponent characterLimit={limit} />
);

commonDataElementInputPreview()
Expand Down
66 changes: 5 additions & 61 deletions cypress/components/textarea/textarea.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,7 @@ context("Tests for Textarea component", () => {
const overCharacters =
charactersUsed - limit === 1 ? "character" : "characters";

CypressMountWithProviders(
<TextareaComponent
enforceCharacterLimit={false}
characterLimit={limit}
/>
);
CypressMountWithProviders(<TextareaComponent characterLimit={limit} />);

textareaChildren()
.type(inputValue)
Expand Down Expand Up @@ -229,12 +224,7 @@ context("Tests for Textarea component", () => {
])(
"input hint should be conditionally rendered",
(inputHint, renderStatus) => {
CypressMountWithProviders(
<TextareaComponent
enforceCharacterLimit={false}
inputHint={inputHint}
/>
);
CypressMountWithProviders(<TextareaComponent inputHint={inputHint} />);

getDataElementByValue("input-hint").should(renderStatus);
}
Expand All @@ -247,10 +237,7 @@ context("Tests for Textarea component", () => {
"character counter should be conditionally rendered",
(characterLimit, renderStatus) => {
CypressMountWithProviders(
<TextareaComponent
enforceCharacterLimit={false}
characterLimit={characterLimit}
/>
<TextareaComponent characterLimit={characterLimit} />
);

characterCount().should(renderStatus);
Expand All @@ -264,10 +251,7 @@ context("Tests for Textarea component", () => {
"visually hidden character count should be conditionally rendered",
(characterLimit, renderStatus) => {
CypressMountWithProviders(
<TextareaComponent
enforceCharacterLimit={false}
characterLimit={characterLimit}
/>
<TextareaComponent characterLimit={characterLimit} />
);

visuallyHiddenCharacterCount().should(renderStatus);
Expand All @@ -281,10 +265,7 @@ context("Tests for Textarea component", () => {
"visually hidden hint should be conditionally rendered",
(characterLimit, renderStatus) => {
CypressMountWithProviders(
<TextareaComponent
enforceCharacterLimit={false}
characterLimit={characterLimit}
/>
<TextareaComponent characterLimit={characterLimit} />
);

visuallyHiddenHint().should(renderStatus);
Expand Down Expand Up @@ -312,37 +293,6 @@ context("Tests for Textarea component", () => {
.should("have.css", "max-width", "100%");
});

it.each([
[11, 11],
[10, 10],
])(
"should input %s characters and enforce character limit of %s in Textarea",
(charactersUsed, limit) => {
const inputValue = "12345678901";
const underCharacters =
limit - charactersUsed === 1 ? "character" : "characters";
const overCharacters =
charactersUsed - limit === 1 ? "character" : "characters";

CypressMountWithProviders(
<TextareaComponent enforceCharacterLimit characterLimit={limit} />
);

textareaChildren()
.type(inputValue)
.then(() => {
characterCount().should(
"have.text",
`${
charactersUsed - limit
? `${limit - charactersUsed} ${underCharacters} too many`
: `${charactersUsed - limit} ${overCharacters} left`
}`
);
});
}
);

it("should render Textarea with name prop", () => {
CypressMountWithProviders(
<TextareaComponent name={CHARACTERS.STANDARD} />
Expand Down Expand Up @@ -793,12 +743,6 @@ context("Tests for Textarea component", () => {
cy.checkAccessibility();
});

it("should pass accessibility tests for Textarea UnenforcedCharacterLimitStory", () => {
CypressMountWithProviders(<stories.UnenforcedCharacterLimitStory />);

cy.checkAccessibility();
});

it("should pass accessibility tests for Textarea ValidationBooleanStory", () => {
CypressMountWithProviders(<stories.ValidationBooleanStory />);

Expand Down
59 changes: 5 additions & 54 deletions cypress/components/textbox/textbox.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,7 @@ context("Tests for Textbox component", () => {
"input hint should be conditionally rendered",
(inputHint, renderStatus) => {
CypressMountWithProviders(
<stories.TextboxComponent
enforceCharacterLimit={false}
inputHint={inputHint}
/>
<stories.TextboxComponent inputHint={inputHint} />
);

getDataElementByValue("input-hint").should(renderStatus);
Expand All @@ -246,10 +243,7 @@ context("Tests for Textbox component", () => {
"character counter should be conditionally rendered",
(characterLimit, renderStatus) => {
CypressMountWithProviders(
<stories.TextboxComponent
enforceCharacterLimit={false}
characterLimit={characterLimit}
/>
<stories.TextboxComponent characterLimit={characterLimit} />
);

characterCount().should(renderStatus);
Expand All @@ -263,10 +257,7 @@ context("Tests for Textbox component", () => {
"visually hidden character count should be conditionally rendered",
(characterLimit, renderStatus) => {
CypressMountWithProviders(
<stories.TextboxComponent
enforceCharacterLimit={false}
characterLimit={characterLimit}
/>
<stories.TextboxComponent characterLimit={characterLimit} />
);

visuallyHiddenCharacterCount().should(renderStatus);
Expand All @@ -280,10 +271,7 @@ context("Tests for Textbox component", () => {
"visually hidden hint should be conditionally rendered",
(characterLimit, renderStatus) => {
CypressMountWithProviders(
<stories.TextboxComponent
enforceCharacterLimit={false}
characterLimit={characterLimit}
/>
<stories.TextboxComponent characterLimit={characterLimit} />
);

visuallyHiddenHint().should(renderStatus);
Expand Down Expand Up @@ -332,10 +320,7 @@ context("Tests for Textbox component", () => {
charactersUsed - limit === 1 ? "character" : "characters";

CypressMountWithProviders(
<stories.TextboxComponent
enforceCharacterLimit={false}
characterLimit={limit}
/>
<stories.TextboxComponent characterLimit={limit} />
);

textboxInput()
Expand Down Expand Up @@ -364,40 +349,6 @@ context("Tests for Textbox component", () => {
}
);

it.each([
[11, 11],
[10, 10],
])(
"should input %s characters and enforce character limit of %s in Textbox",
(charactersUsed, limit) => {
const inputValue = "12345678901";
const underCharacters =
limit - charactersUsed === 1 ? "character" : "characters";
const overCharacters =
charactersUsed - limit === 1 ? "character" : "characters";

CypressMountWithProviders(
<stories.TextboxComponent
enforceCharacterLimit
characterLimit={limit}
/>
);

textboxInput()
.type(inputValue)
.then(() => {
characterCount().should(
"have.text",
`${
charactersUsed - limit
? `${limit - charactersUsed} ${overCharacters} too many`
: `${charactersUsed - limit} ${underCharacters} left`
}`
);
});
}
);

it("should render Textbox with name prop", () => {
CypressMountWithProviders(
<stories.TextboxComponent name={CHARACTERS.STANDARD} />
Expand Down
1 change: 0 additions & 1 deletion src/components/date/date.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export interface DateInputProps
| "placeholder"
| "iconOnClick"
| "iconOnMouseDown"
| "enforceCharacterLimit"
| "characterLimit"
| "warnOverLimit"
| "iconTabIndex"
Expand Down
1 change: 0 additions & 1 deletion src/components/date/date.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ the German (`de`) locale whilst the second is for a Chinese (`zh-CN`) locale. Re
"placeholder",
"iconOnClick",
"iconOnMouseDown",
"enforceCharacterLimit",
"characterLimit",
"prefix",
"inputIcon",
Expand Down
1 change: 0 additions & 1 deletion src/components/password/password.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ export const CharacterCounter = () => {
value={state}
characterLimit={10}
onChange={setValue}
enforceCharacterLimit={false}
/>
);
};
Expand Down
1 change: 0 additions & 1 deletion src/components/textarea/textarea-test.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ export default {
fieldHelp: "",
characterLimit: undefined,
inputWidth: 100,
enforceCharacterLimit: true,
label: "Textarea",
labelHelp: "",
labelInline: false,
Expand Down
9 changes: 2 additions & 7 deletions src/components/textarea/textarea.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ export interface TextareaProps
cols?: number;
/** If true, the component will be disabled */
disabled?: boolean;
/** Stop the user typing over the characterLimit */
enforceCharacterLimit?: boolean;
/** Indicate that error has occurred
Pass string to display icon, tooltip and red border
Pass true boolean to only display red border */
Expand Down Expand Up @@ -136,7 +134,6 @@ export const Textarea = React.forwardRef(
size,
children,
characterLimit,
enforceCharacterLimit = true,
onChange,
disabled = false,
labelInline,
Expand Down Expand Up @@ -254,10 +251,9 @@ export const Textarea = React.forwardRef(
fieldHelp,
});

const [maxLength, characterCount, visuallyHiddenHintId] = useCharacterCount(
const [characterCount, visuallyHiddenHintId] = useCharacterCount(
value,
characterLimit,
enforceCharacterLimit
characterLimit
);

useEffect(() => {
Expand Down Expand Up @@ -323,7 +319,6 @@ export const Textarea = React.forwardRef(
name={name}
value={value}
ref={callbackRef}
maxLength={maxLength}
onChange={onChange}
disabled={disabled}
readOnly={readOnly}
Expand Down
8 changes: 0 additions & 8 deletions src/components/textarea/textarea.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,6 @@ as it forces a pause before any other announcements, this well help screen reade
<Story name="with characterLimit" story={stories.CharacterLimitStory} />
</Canvas>

### With characterLimit - not enforced

<Canvas>
<Story
name="with characterLimit - not enforced"
story={stories.UnenforcedCharacterLimitStory}
/>
</Canvas>

### with characterLimit - with translations

Expand Down
21 changes: 0 additions & 21 deletions src/components/textarea/textarea.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,26 +70,6 @@ export const CharacterLimitStory: ComponentStory<typeof Textarea> = () => {
);
};

export const UnenforcedCharacterLimitStory: ComponentStory<
typeof Textarea
> = () => {
const [value, setValue] = useState("");
return (
<Textarea
label="Textarea"
inputHint="Hint text (optional)."
expandable
value={value}
onChange={({ target }) => setValue(target.value)}
characterLimit={50}
enforceCharacterLimit={false}
/>
);
};
UnenforcedCharacterLimitStory.parameters = {
chromatic: { disableSnapshot: true },
};

export const TranslationsCharacterLimitStory: ComponentStory<
typeof Textarea
> = () => {
Expand Down Expand Up @@ -119,7 +99,6 @@ export const TranslationsCharacterLimitStory: ComponentStory<
value={value}
onChange={({ target }) => setValue(target.value)}
characterLimit={50}
enforceCharacterLimit={false}
/>
</I18nProvider>
);
Expand Down
1 change: 0 additions & 1 deletion src/components/textbox/textbox-test.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export const getCommonTextboxArgs = (
size: "medium",
inputIcon: undefined,
required: false,
enforceCharacterLimit: false,
characterLimit: undefined,
error: "",
warning: "",
Expand Down
Loading

0 comments on commit b49f757

Please sign in to comment.