Skip to content

Commit

Permalink
LabeledTextField: Adjust styling for light prop for improved color co…
Browse files Browse the repository at this point in the history
…ntrast (#2300)

## Summary:
- Use the `LabeledTextField`'s `light` prop in `FieldHeading` to apply light styling for the label, required indicator, description, and the error message. This improves the color contrast of the elements in `LabelledTextField` when used on a dark background. This aligns with the specs in [Figma](https://www.figma.com/design/VbVu3h2BpBhH80niq101MHHE/%F0%9F%92%A0-Main-Components?node-id=13840-8635&t=sq9ZCuTcvzXGme48-4)
- Updated documentation for the `Light` and `Error Light` stories

Issue: WB-1744

## Test plan:
1. Review the LabelledTextField Light and ErrorLight documentation (`?path=/docs/packages-form-labeledtextfield--docs`)
2. Review the Light and ErrorLight stories
- `?path=/story/packages-form-labeledtextfield--light` 
- `?path=/story/packages-form-labeledtextfield--error-light`

<img width="1720" alt="Screenshot 2024-08-22 at 3 17 58 PM" src="https://github.com/user-attachments/assets/5cdba942-d2d0-4822-9e46-554bfd1ec3c4">

<img width="1719" alt="Screenshot 2024-08-22 at 3 16 40 PM" src="https://github.com/user-attachments/assets/ce1ec255-35cd-4337-92c6-cfa753bf19e9">

Author: beaesguerra

Reviewers: beaesguerra, jandrade

Required Reviewers:

Approved By: jandrade

Checks: ✅ Chromatic - Get results on regular PRs (ubuntu-latest, 20.x), ✅ codecov/project, ✅ Test (ubuntu-latest, 20.x, 2/2), ✅ Test (ubuntu-latest, 20.x, 1/2), ✅ Check build sizes (ubuntu-latest, 20.x), ✅ Lint (ubuntu-latest, 20.x), ✅ Chromatic - Build on regular PRs / chromatic (ubuntu-latest, 20.x), ⏭️  Chromatic - Skip on Release PR (changesets), ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ Prime node_modules cache for primary configuration (ubuntu-latest, 20.x), ✅ gerald, ⏭️  dependabot

Pull Request URL: #2300
  • Loading branch information
beaesguerra authored Aug 26, 2024
1 parent 688c65d commit 17f9a33
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 70 deletions.
5 changes: 5 additions & 0 deletions .changeset/sharp-maps-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@khanacademy/wonder-blocks-form": patch
---

Improve `LabeledTextField` styling when the `light` prop is `true`. This improves the color contrast of the label, required indicator, description, and error message when the component is used on dark backgrounds.
105 changes: 42 additions & 63 deletions __docs__/wonder-blocks-form/labeled-text-field.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import {StyleSheet} from "aphrodite";
import type {Meta, StoryObj} from "@storybook/react";

import {View} from "@khanacademy/wonder-blocks-core";
import {LabelMedium, LabelSmall} from "@khanacademy/wonder-blocks-typography";
import {color, spacing} from "@khanacademy/wonder-blocks-tokens";
import {spacing} from "@khanacademy/wonder-blocks-tokens";
import {Strut} from "@khanacademy/wonder-blocks-layout";
import Button from "@khanacademy/wonder-blocks-button";
import Link from "@khanacademy/wonder-blocks-link";
Expand Down Expand Up @@ -436,6 +435,15 @@ export const Error: StoryComponentType = {
render: ErrorRender,
};

/**
* The `light` prop is intended to be used on a dark background. When the
* `light` prop is set to `true`:
* - the underlying `TextField` will have a light border when focused
* - a specific light styling is used for the error state, as seen in the
* `ErrorLight` story
* - the text in the component (label, required indicator, description, and
* error message) are modified to work on the dark background
*/
export const Light: StoryComponentType = (args: any) => {
const [value, setValue] = React.useState("");

Expand All @@ -446,24 +454,17 @@ export const Light: StoryComponentType = (args: any) => {
};

return (
<View style={styles.darkBackground}>
<LabeledTextField
{...args}
label={
<LabelMedium style={styles.whiteColor}>Name</LabelMedium>
}
description={
<LabelSmall style={styles.offWhiteColor}>
Please enter your name
</LabelSmall>
}
value={value}
onChange={setValue}
placeholder="Name"
light={true}
onKeyDown={handleKeyDown}
/>
</View>
<LabeledTextField
{...args}
label="Name"
description="Please enter your name"
value={value}
onChange={setValue}
placeholder="Name"
light={true}
onKeyDown={handleKeyDown}
required={true}
/>
);
};

Expand All @@ -472,17 +473,15 @@ Light.args = {
};

Light.parameters = {
docs: {
description: {
story: `If the \`light\` prop is set to true, the
underlying \`TextField\` will have a light border when focused.
This is intended to be used on a dark background. There is also a
specific light styling for the error state, as seen in the
\`ErrorLight\` story.`,
},
backgrounds: {
default: "darkBlue",
},
};

/**
* If an input value fails validation and the `light` prop is true,
* `TextField` will have light error styling.
*/
export const ErrorLight: StoryComponentType = (args: any) => {
const [value, setValue] = React.useState("khan");

Expand All @@ -500,26 +499,19 @@ export const ErrorLight: StoryComponentType = (args: any) => {
};

return (
<View style={styles.darkBackground}>
<LabeledTextField
{...args}
label={
<LabelMedium style={styles.whiteColor}>Email</LabelMedium>
}
description={
<LabelSmall style={styles.offWhiteColor}>
Please provide your personal email
</LabelSmall>
}
type="email"
value={value}
light={true}
onChange={setValue}
placeholder="Email"
validate={validate}
onKeyDown={handleKeyDown}
/>
</View>
<LabeledTextField
{...args}
label="Email"
description="Please provide your personal email"
type="email"
value={value}
light={true}
onChange={setValue}
placeholder="Email"
validate={validate}
onKeyDown={handleKeyDown}
required={true}
/>
);
};

Expand All @@ -528,11 +520,8 @@ ErrorLight.args = {
};

ErrorLight.parameters = {
docs: {
description: {
story: `If an input value fails validation and the
\`light\` prop is true, \`TextField\` will have light error styling.`,
},
backgrounds: {
default: "darkBlue",
},
};

Expand Down Expand Up @@ -766,16 +755,6 @@ AutoComplete.parameters = {
};

const styles = StyleSheet.create({
darkBackground: {
background: color.darkBlue,
padding: `${spacing.medium_16}px`,
},
whiteColor: {
color: color.white,
},
offWhiteColor: {
color: color.white64,
},
button: {
maxWidth: 150,
},
Expand Down
33 changes: 26 additions & 7 deletions packages/wonder-blocks-form/src/components/field-heading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ type Props = {
* Optional test ID for e2e testing.
*/
testId?: string;
/**
* Change the field’s sub-components to fit a dark background.
*/
light?: boolean;
};

const StyledSpan = addStyle("span");
Expand All @@ -52,10 +56,13 @@ const StyledSpan = addStyle("span");
*/
export default class FieldHeading extends React.Component<Props> {
renderLabel(): React.ReactNode {
const {label, id, required, testId} = this.props;
const {label, id, required, testId, light} = this.props;

const requiredIcon = (
<StyledSpan style={styles.required} aria-hidden={true}>
<StyledSpan
style={light ? styles.lightRequired : styles.required}
aria-hidden={true}
>
{" "}
*
</StyledSpan>
Expand All @@ -64,7 +71,7 @@ export default class FieldHeading extends React.Component<Props> {
return (
<React.Fragment>
<LabelMedium
style={styles.label}
style={light ? styles.lightLabel : styles.label}
tag="label"
htmlFor={id && `${id}-field`}
testId={testId && `${testId}-label`}
Expand All @@ -78,7 +85,7 @@ export default class FieldHeading extends React.Component<Props> {
}

maybeRenderDescription(): React.ReactNode | null | undefined {
const {description, testId} = this.props;
const {description, testId, light} = this.props;

if (!description) {
return null;
Expand All @@ -87,7 +94,7 @@ export default class FieldHeading extends React.Component<Props> {
return (
<React.Fragment>
<LabelSmall
style={styles.description}
style={light ? styles.lightDescription : styles.description}
testId={testId && `${testId}-description`}
>
{description}
Expand All @@ -98,7 +105,7 @@ export default class FieldHeading extends React.Component<Props> {
}

maybeRenderError(): React.ReactNode | null | undefined {
const {error, id, testId} = this.props;
const {error, id, testId, light} = this.props;

if (!error) {
return null;
Expand All @@ -108,7 +115,7 @@ export default class FieldHeading extends React.Component<Props> {
<React.Fragment>
<Strut size={spacing.small_12} />
<LabelSmall
style={styles.error}
style={light ? styles.lightError : styles.error}
role="alert"
id={id && `${id}-error`}
testId={testId && `${testId}-error`}
Expand Down Expand Up @@ -138,13 +145,25 @@ const styles = StyleSheet.create({
label: {
color: color.offBlack,
},
lightLabel: {
color: color.white,
},
description: {
color: color.offBlack64,
},
lightDescription: {
color: color.white64,
},
error: {
color: color.red,
},
lightError: {
color: color.fadedRed,
},
required: {
color: color.red,
},
lightRequired: {
color: color.fadedRed,
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ class LabeledTextField extends React.Component<PropsWithForwardRef, State> {
id={uniqueId}
testId={testId}
style={style}
light={light}
field={
<TextField
id={`${uniqueId}-field`}
Expand Down

0 comments on commit 17f9a33

Please sign in to comment.