Skip to content

Commit

Permalink
Merge pull request #5441 from mozilla/mntor-3823
Browse files Browse the repository at this point in the history
Add floating labels to InputField
  • Loading branch information
flozia authored Jan 8, 2025
2 parents 780dfd4 + a436d84 commit d91f5a5
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 9 deletions.
47 changes: 44 additions & 3 deletions src/app/components/client/InputField.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,36 @@
flex-direction: column;
position: relative;

.inputFieldWrapper {
position: relative;
}

.floatingLabel {
background: $color-white;
border-radius: $border-radius-sm;
color: $color-black;
display: inline-block;
// Add a bit more space: The next spacing step is too much.
left: calc($spacing-sm * 1.5);
line-height: 1em;
padding: 0 calc($spacing-xs * 0.5);
pointer-events: none;
position: absolute;
top: 50%;
transform-origin: top left;
transform: translate(-0.05em, -50%) scale(1);
transition: transform 0.2s ease-in-out;
user-select: none;
}

.inputField {
border: 1px solid $color-grey-30;
border-radius: $border-radius-sm;
color: $color-black;
// Add a bit more vertical space: The next spacing step is too much.
padding: calc($spacing-sm * 1.5) $spacing-md;
// Add a bit more space: The next spacing step is too much.
padding: calc($spacing-sm * 1.5);
width: 100%;

&::placeholder,
&.noValue {
color: $color-grey-40;
}
Expand All @@ -39,6 +61,25 @@
}
}

&:has(.floatingLabel) {
::placeholder {
@include visually-hidden;
}
.inputField {
// Move the value string off-center.
padding: calc($spacing-md * 1.25) calc($spacing-sm * 1.5) $spacing-xs;
}
}

&:focus-within,
&:not(:has(:placeholder-shown)) {
.floatingLabel {
color: $color-grey-40;
// Make the floating label visually align with the input value.
transform: translate(-0.05em, -115%) scale(0.75);
}
}

.inputLabel {
font-weight: 600;
margin-bottom: $spacing-sm;
Expand Down
27 changes: 27 additions & 0 deletions src/app/components/client/InputField.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { expect } from "@jest/globals";
import { render } from "@testing-library/react";
import { composeStory } from "@storybook/react";
import { axe } from "jest-axe";
import Meta, {
TextInputFieldEmpty,
TextInputFieldEmptyFloatingLabel,
TextInputFieldFilled,
TextInputFieldFilledFloatingLabel,
} from "./stories/InputField.stories";

describe("InputField", () => {
test.each([
TextInputFieldEmpty,
TextInputFieldFilled,
TextInputFieldEmptyFloatingLabel,
TextInputFieldFilledFloatingLabel,
])("passes the axe accessibility test suite for %s", async (component) => {
const ComposedInput = composeStory(component, Meta);
const { container } = render(<ComposedInput hasFloatingLabel />);
expect(await axe(container)).toHaveNoViolations();
});
});
14 changes: 8 additions & 6 deletions src/app/components/client/InputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useL10n } from "../../hooks/l10n";
export const InputField = (
props: AriaTextFieldProps & {
iconButton?: ReactNode;
hasFloatingLabel?: boolean;
},
) => {
const { isRequired, label, isInvalid, value, description } = props;
Expand All @@ -29,13 +30,14 @@ export const InputField = (
return (
<div className={styles.input}>
{label && (
<label {...labelProps} className={styles.inputLabel}>
{label}
{
// TODO: Add unit test when changing this code:
/* c8 ignore next */
isRequired ? <span aria-hidden="true">*</span> : ""
<label
{...labelProps}
className={
props.hasFloatingLabel ? styles.floatingLabel : styles.inputLabel
}
>
{label}
{isRequired ? <span aria-hidden="true">*</span> : ""}
</label>
)}
<input
Expand Down
19 changes: 19 additions & 0 deletions src/app/components/client/stories/InputField.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,22 @@ export const DateInputFieldInvalidWithMessage: Story = {
errorMessage: "Select a date",
},
};

export const TextInputFieldEmptyFloatingLabel: Story = {
args: {
label: "Text input floating label",
placeholder: "Type here",
type: "text",
hasFloatingLabel: true,
},
};

export const TextInputFieldFilledFloatingLabel: Story = {
args: {
label: "Text input floating label",
placeholder: "Type here",
type: "text",
value: "Input is filled",
hasFloatingLabel: true,
},
};

0 comments on commit d91f5a5

Please sign in to comment.