Skip to content

Commit

Permalink
LabeledField (part 1): Initial set up for LabeledField component base…
Browse files Browse the repository at this point in the history
…d on FieldHeading (#2322)

## Summary:
- The `FieldHeading` component internal to the `wonder-blocks-form package` was copied to `wonder-blocks-labeled-field` package and renamed to the `LabeledField` component
- Export `LabeledField` as a named export
- Added base stories for `LabeledField` and updated docs

Issue: WB-1503

## Test plan:
- `LabeledField` component is reviewed (`?path=/docs/packages-labeledfield-labeledfield--docs`)

Note: Minimal changes have been made to the FieldHeading implementation and tests (just renaming). Next, I will be working on updating the component so it follows the implementation spec and exploring validation more, so the api may change! I'll be merging PRs to the `feature/labeled-field` branch until it's all ready 😄

Author: beaesguerra

Reviewers: beaesguerra, jandrade

Required Reviewers:

Approved By: jandrade

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

Pull Request URL: #2322
  • Loading branch information
beaesguerra authored Oct 3, 2024
1 parent f451591 commit daf459a
Show file tree
Hide file tree
Showing 7 changed files with 621 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/two-pens-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@khanacademy/wonder-blocks-labeled-field": patch
---

Sets up the initial implementation for LabeledField based on the internal FieldHeading component in the form package
49 changes: 49 additions & 0 deletions __docs__/wonder-blocks-labeled-field/labeled-field.argtypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export default {
label: {
table: {
type: {
summary: "string | ReactNode",
},
},
},
description: {
table: {
type: {
summary: "string | ReactNode",
},
},
},
error: {
table: {
type: {
summary: "string | ReactNode",
},
},
},
field: {
table: {
type: {
summary: "ReactNode",
},
},
},
/**
* Visual Style
*/
style: {
table: {
type: {
summary: "StyleType",
},
category: "Visual style",
},
control: {
type: "null",
},
},
light: {
table: {
category: "Visual style",
},
},
};
171 changes: 171 additions & 0 deletions __docs__/wonder-blocks-labeled-field/labeled-field.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import * as React from "react";
import type {Meta, StoryObj} from "@storybook/react";
import ComponentInfo from "../../.storybook/components/component-info";
import packageConfig from "../../packages/wonder-blocks-labeled-field/package.json";
import {LabeledField} from "@khanacademy/wonder-blocks-labeled-field";
import {TextArea, TextField} from "@khanacademy/wonder-blocks-form";
import LabeledFieldArgTypes from "./labeled-field.argtypes";
import {PropsFor, View} from "@khanacademy/wonder-blocks-core";
import {spacing} from "@khanacademy/wonder-blocks-tokens";
import {
MultiSelect,
OptionItem,
SingleSelect,
} from "@khanacademy/wonder-blocks-dropdown";
import SearchField from "@khanacademy/wonder-blocks-search-field";

/**
* The `LabeledField` component provides common elements for a form field such
* as the label, required indicator, description, and error message.
*
* It is highly recommended that all form fields should be used with the
* `LabeledField` component so that our form fields are consistent and accessible.
*/
export default {
title: "Packages / LabeledField / LabeledField",
component: LabeledField,
parameters: {
componentSubtitle: (
<ComponentInfo
name={packageConfig.name}
version={packageConfig.version}
/>
),
},
argTypes: LabeledFieldArgTypes,
} as Meta<typeof LabeledField>;

type StoryComponentType = StoryObj<typeof LabeledField>;

export const Default: StoryComponentType = {
args: {
field: <TextField value="" onChange={() => {}} />,
label: "Name",
description: "Helpful description text",
error: "Error message",
required: true,
},
};

const AllFields = (args: PropsFor<typeof LabeledField>) => {
const [textFieldValue, setTextFieldValue] = React.useState("");
const [textAreaValue, setTextAreaValue] = React.useState("");
const [singleSelectValue, setSingleSelectValue] = React.useState("");
const [multiSelectValue, setMultiSelectValue] = React.useState<string[]>(
[],
);
const [searchValue, setSearchValue] = React.useState("");

return (
<View style={{gap: spacing.large_24}}>
<LabeledField
{...args}
label="Text Field"
field={
<TextField
value={textFieldValue}
onChange={setTextFieldValue}
/>
}
/>
<LabeledField
{...args}
label="Text Area"
field={
<TextArea
value={textAreaValue}
onChange={setTextAreaValue}
/>
}
/>

<LabeledField
{...args}
label="Single Select"
field={
<SingleSelect
placeholder="Choose a fruit"
selectedValue={singleSelectValue}
onChange={setSingleSelectValue}
error={!!args.error}
>
<OptionItem label="Mango" value="mango" />
<OptionItem label="Strawberry" value="strawberry" />
<OptionItem label="Banana" value="banana" />
</SingleSelect>
}
/>

<LabeledField
{...args}
label="Multi Select"
field={
<MultiSelect
selectedValues={multiSelectValue}
onChange={setMultiSelectValue}
error={!!args.error}
>
<OptionItem label="Mango" value="mango" />
<OptionItem label="Strawberry" value="strawberry" />
<OptionItem label="Banana" value="banana" />
</MultiSelect>
}
/>

<LabeledField
{...args}
label="Search"
field={
<SearchField
value={searchValue}
onChange={setSearchValue}
/>
}
/>
</View>
);
};

/**
* The `LabeledField` component can be used with form field components such as:
* - `TextField`
* - `TextArea`
* - `SingleSelect`
* - `MultiSelect`
* - `SearchField`
*/
export const Fields: StoryComponentType = {
args: {
description: "Helpful description text",
required: true,
},
render: AllFields,
};

export const Error: StoryComponentType = {
args: {
description: "Helpful description text",
error: "Error message",
required: true,
},
render: AllFields,
};

/**
* If the labeled field is used on a dark background, the `light` prop can be
* set to `true`. When abled, the text in the component (label, required
* indicator, description, and error message) are modified to work on a dark
* background.
*/
export const Light: StoryComponentType = {
args: {
description: "Helpful description text",
error: "Error message",
required: true,
light: true,
},
parameters: {
backgrounds: {default: "darkBlue"},
},
render: AllFields,
};
Loading

0 comments on commit daf459a

Please sign in to comment.