Skip to content

Commit

Permalink
fix: better error styles for TextInput and TextArea (#527)
Browse files Browse the repository at this point in the history
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Refactor**
- Improved readability and simplified logic in handling focus, border,
label, and helper text for text input components.
- **Style**
- Adjusted label and helper text positioning for better visual alignment
in text input areas.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
aversini authored Apr 23, 2024
1 parent f1e66a8 commit d0952ab
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,20 @@ describe("TextArea modifiers", () => {
expect(screen.queryByText("helper text")).not.toBeInTheDocument();
});
});

it("should render a disabled text area", async () => {
render(<TextArea label="hello world" name="toto" disabled />);
const label = await screen.findAllByText("hello world");

expect(label[0].className).toContain("sr-only");
expectToHaveClasses(label[1], [
"px-2",
"absolute",
"cursor-not-allowed",
"font-medium",
"opacity-50",
]);
});
});

describe("TextArea methods", () => {
Expand Down
93 changes: 59 additions & 34 deletions packages/ui-form/src/components/TextArea/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,17 @@ const getTextAreaColorClasses = ({

const getTextAreaFocusClasses = ({
focusMode,
error,
}: {
error: boolean;
focusMode: "dark" | "light" | "system" | "alt-system";
}) => {
if (error) {
return "focus:outline focus:outline-2 focus:outline-focus-error-dark";
} else {
return clsx("focus:outline focus:outline-2 focus:outline-offset-2", {
"focus:outline-focus-dark": focusMode === "dark",
"focus:outline-focus-light": focusMode === "light",
"focus:outline-focus-light dark:focus:outline-focus-dark":
focusMode === "alt-system",
"focus:outline-focus-dark dark:focus:outline-focus-light":
focusMode === "system",
});
}
return clsx("focus:outline focus:outline-2 focus:outline-offset-2", {
"focus:outline-focus-dark": focusMode === "dark",
"focus:outline-focus-light": focusMode === "light",
"focus:outline-focus-light dark:focus:outline-focus-dark":
focusMode === "alt-system",
"focus:outline-focus-dark dark:focus:outline-focus-light":
focusMode === "system",
});
};

const getTextAreaBorderClasses = ({
Expand All @@ -75,9 +69,10 @@ const getTextAreaBorderClasses = ({
noBorder: boolean;
}) => {
return clsx("border-2", {
"border-border-dark": !noBorder,
"border-border-dark": !noBorder && !error,
"focus:border-border-dark": !noBorder && error,
"border-border-error-dark": !noBorder && error,
"border-transparent": noBorder,
"border-border-error-dark": error,
});
};

Expand All @@ -95,34 +90,63 @@ const getTextAreaLabelClasses = ({
if (raw) {
return "";
}
return clsx("absolute cursor-text font-medium", {
"text-copy-lighter": !error && mode === "dark",
"text-copy-dark": !error && mode === "light",
"text-copy-dark dark:text-copy-lighter": !error && mode === "system",
"text-copy-lighter dark:text-copy-dark": !error && mode === "alt-system",
"cursor-not-allowed opacity-50": disabled,
});
if (disabled) {
return clsx("absolute px-2 cursor-not-allowed opacity-50 font-medium");
}
if (!error) {
return clsx("absolute px-2 cursor-text font-medium", {
"text-copy-lighter": mode === "dark",
"text-copy-dark": mode === "light",
"text-copy-dark dark:text-copy-lighter": mode === "system",
"text-copy-lighter dark:text-copy-dark": mode === "alt-system",
});
}
if (error) {
return clsx("absolute px-2 cursor-text font-medium", {
"text-copy-lighter": mode === "dark",
"text-copy-error-dark": mode === "light",
"text-copy-error-dark dark:text-copy-error-light": mode === "system",
"text-copy-lighter dark:text-copy-error-dark": mode === "alt-system",
});
}
};

const getTextAreaHelperTextClasses = ({
error,
raw,
mode,
disabled,
}: {
disabled: boolean;
error: boolean;
mode: "dark" | "light" | "system" | "alt-system";
raw: boolean;
}) => {
return raw
? undefined
: clsx(TEXT_AREA_HELPER_TEXT_CLASSNAME, "absolute px-2 font-medium", {
"rounded-md bg-surface-darker text-copy-error-light": error,
"text-copy-lighter": !error && mode === "dark",
"text-copy-dark": !error && mode === "light",
"text-copy-dark dark:text-copy-lighter": !error && mode === "system",
"text-copy-lighter dark:text-copy-dark":
!error && mode === "alt-system",
});
if (raw) {
return "";
}
if (disabled) {
return clsx(
TEXT_AREA_HELPER_TEXT_CLASSNAME,
"absolute px-2 cursor-not-allowed opacity-50 font-medium",
);
}
if (!error) {
return clsx(TEXT_AREA_HELPER_TEXT_CLASSNAME, "absolute px-2 font-medium", {
"text-copy-lighter": mode === "dark",
"text-copy-dark": mode === "light",
"text-copy-dark dark:text-copy-lighter": mode === "system",
"text-copy-lighter dark:text-copy-dark": mode === "alt-system",
});
}
if (error) {
return clsx(TEXT_AREA_HELPER_TEXT_CLASSNAME, "absolute px-2 font-medium", {
"text-copy-error-light": mode === "dark",
"text-copy-error-dark": mode === "light",
"text-copy-error-dark dark:text-copy-error-light": mode === "system",
"dark:text-copy-error-dark text-copy-error-light": mode === "alt-system",
});
}
};

export const getTextAreaClasses = ({
Expand Down Expand Up @@ -152,7 +176,7 @@ export const getTextAreaClasses = ({
textAreaClassName,
getTextAreaBaseClasses(),
getTextAreaColorClasses({ mode }),
getTextAreaFocusClasses({ focusMode, error }),
getTextAreaFocusClasses({ focusMode }),
getTextAreaBorderClasses({
noBorder,
error,
Expand All @@ -175,6 +199,7 @@ export const getTextAreaClasses = ({
error,
raw,
mode,
disabled,
});

const rightElement = raw
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,20 @@ describe("TextInput modifiers", () => {
);
await screen.findByText("right element");
});

it("should render a disabled text input", async () => {
render(<TextInput label="hello world" name="toto" disabled />);
const label = await screen.findAllByText("hello world");

expect(label[0].className).toContain("sr-only");
expectToHaveClasses(label[1], [
"px-2",
"absolute",
"cursor-not-allowed",
"font-medium",
"opacity-50",
]);
});
});

describe("TextInput methods", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ describe("TextInputMask modifiers", () => {
/>,
);
const label = await screen.findAllByText("hello world");
// const input = await screen.findByRole("textbox");

expectToHaveClasses(label[1], [
"absolute",
Expand All @@ -42,26 +41,6 @@ describe("TextInputMask modifiers", () => {
"font-medium",
"text-copy-dark",
]);
// expectToHaveClasses(input, [
// TEXT_INPUT_CLASSNAME,
// "bg-surface-lighter",
// "border-2",
// "border-border-dark",
// "caret-copy-dark",
// "dark:bg-surface-darker",
// "dark:caret-copy-light",
// "dark:focus:outline-focus-light",
// "dark:text-copy-lighter",
// "focus:outline-2",
// "focus:outline-focus-dark",
// "focus:outline-offset-2",
// "focus:outline",
// "h-12",
// "px-4",
// "rounded-md",
// "text-base",
// "text-copy-dark",
// ]);
});

it("should render a text input with an error message", async () => {
Expand Down Expand Up @@ -162,7 +141,7 @@ describe("TextInputMask modifiers", () => {
}
});

it("should render a text input with an input class", async () => {
it("should render a text input with a custom class", async () => {
render(
<TextInputMask
label="toto"
Expand All @@ -180,6 +159,30 @@ describe("TextInputMask modifiers", () => {
expect(input.className).toContain("toto");
expect(input.parentElement?.className).not.toContain("toto");
});

it("should render a disabled text input", async () => {
render(
<TextInputMask
disabled
label="hello world"
name="toto"
rightElement={
<ButtonIcon>
<IconHide />
</ButtonIcon>
}
/>,
);
const label = await screen.findAllByText("hello world");

expectToHaveClasses(label[1], [
"px-2",
"absolute",
"cursor-not-allowed",
"font-medium",
"opacity-50",
]);
});
});

describe("TextInputMask methods", () => {
Expand Down
Loading

0 comments on commit d0952ab

Please sign in to comment.