Skip to content

Commit

Permalink
docs(Select): normalize component story
Browse files Browse the repository at this point in the history
  • Loading branch information
MiroslavPetrik committed Feb 27, 2024
1 parent 0d8b283 commit a5b744d
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 97 deletions.
178 changes: 81 additions & 97 deletions src/components/select/Select.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,54 @@
import { StoryObj } from "@storybook/react";
import { z } from "zod";

import { SelectField } from "./SelectField.mock";
import { Select, SelectProps } from "./Select";
import { booleanField, numberField, stringField, zodField } from "../../fields";
import { countryOptions } from "../../scenarios/mocks";
import { formStory, meta } from "../../scenarios/StoryForm";
import { type SelectField as TSelectField } from "../../hooks";
import {
type Language,
addresses,
languageOptions,
} from "../../scenarios/mocks";
import { StoryForm, meta } from "../../scenarios/StoryForm";

export default {
...meta,
component: Select,
title: "components/Select",
args: {
options: languageOptions,
getValue: ({ key }: Language) => key,
getLabel: ({ name }: Language) => name,
},
};

export const RequiredString = formStory({
args: {
fields: {
country: stringField(),
},
children: ({ fields }) => (
<SelectField
field={fields.country}
label="Country of Origin"
options={countryOptions}
getValue={({ key }) => key}
getLabel={({ name }) => name}
/>
const selectStory = <Option, Field extends TSelectField>(
storyObj: {
args: Pick<SelectProps<Option, Field>, "field"> &
Omit<Partial<SelectProps<Option, Field>>, "field">;
} & Omit<StoryObj<typeof meta>, "args">,
) => ({
...storyObj,
decorators: [
(Story: () => JSX.Element) => (
<StoryForm fields={{ field: storyObj.args.field }}>
{() => (
<p>
<Story />
</p>
)}
</StoryForm>
),
],
});

export const RequiredString = selectStory({
args: {
field: stringField(),
},
});

export const OptionalString = formStory({
export const OptionalString = selectStory({
parameters: {
docs: {
description: {
Expand All @@ -37,62 +58,42 @@ export const OptionalString = formStory({
},
},
args: {
fields: {
country: stringField().optional(),
},
children: ({ fields }) => (
<SelectField
field={fields.country}
label="Country of Origin"
options={countryOptions}
getValue={({ key }) => key}
getLabel={({ name }) => name}
/>
),
field: stringField().optional(),
},
});

export const InitializedString = formStory({
export const Initialized = selectStory({
parameters: {
docs: {
description: {
story: "Field is initialized via the `initialValue` prop.",
story:
"Field is initialized via the `initialValue` prop. It must be one of the values returned by the `getValue`",
},
},
},
args: {
fields: {
country: stringField(),
},
children: ({ fields }) => (
<SelectField
field={fields.country}
initialValue={countryOptions[2]?.key}
label="Country of Origin"
options={countryOptions}
getValue={({ key }) => key}
getLabel={({ name }) => name}
/>
),
field: stringField(),
initialValue: languageOptions[2]!.key,
},
});

const ratingOptions = [5, 4, 3, 2, 1];

export const RequiredNumber = formStory({
args: {
fields: {
rating: numberField(),
export const RequiredNumber = selectStory({
parameters: {
docs: {
description: {
story:
"Here, options `[5, 4, 3, 2, 1]` set the value in `numberField()`.",
},
},
children: ({ fields }) => (
<SelectField
field={fields.rating}
label="How do you rate this docs?"
options={ratingOptions}
getValue={(value) => value}
getLabel={(value) => Array(value + 1).join("🌟")}
/>
),
},
args: {
placeholder: "How is the weather today?",
field: numberField(),
options: ratingOptions,
getValue: (value) => value,
getLabel: (value) => Array(value + 1).join("🌟"),
},
});

Expand All @@ -101,57 +102,40 @@ const approvalOptions = [
{ label: "I have some comments", key: false },
];

export const RequiredBoolean = formStory({
export const RequiredBoolean = selectStory({
args: {
fields: {
approved: booleanField(),
},
children: ({ fields }) => (
<SelectField
field={fields.approved}
label="Do you approve this message?"
options={approvalOptions}
getValue={({ key }) => key}
getLabel={({ label }) => label}
/>
),
field: booleanField(),
options: approvalOptions,
getValue: ({ key }) => key,
getLabel: ({ label }) => label,
},
});

const customers = [
{ name: "Github", city: "San Francisco" },
{ name: "Microsoft", city: "Seattle" },
{ name: "basic IT", city: "Bratislava" },
];

export const RequiredCustomer = formStory({
name: "Required custom type (Customer)",
export const RequiredAddress = selectStory({
name: "Required custom type (Address)",
parameters: {
docs: {
description: {
story:
"For custom type, here `{name: string, city: string}`, pass a custom zodField",
"For custom type, here `{street: string, city: string, zip: string}`, pass a custom `zodField`",
},
},
},
args: {
fields: {
names: zodField({
value: undefined,
schema: z.object(
{ name: z.string(), city: z.string() },
{ required_error: "Please select a customer." },
),
}),
},
children: ({ fields }) => (
<SelectField
field={fields.names}
label="Pick a customer"
options={customers}
getValue={(addr) => addr}
getLabel={({ name, city }) => `${name} in ${city}`}
/>
),
placeholder: "Select delivery address",
field: zodField({
value: undefined,
schema: z.object(
{
street: z.string(),
city: z.string(),
zip: z.string(),
},
{ required_error: "Please select address." },
),
}),
options: addresses,
getValue: (addr) => addr,
getLabel: ({ street, city, zip }) => `${street}, ${city}, ${zip}`,
},
});
17 changes: 17 additions & 0 deletions src/scenarios/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,20 @@ export const countryOptions = [
{ name: "Poland", key: "PL", flag: "🇵🇱" },
{ name: "Hungary", key: "HU", flag: "🇭🇺" },
];

export type Language = (typeof languageOptions)[number];

export const languageOptions = [
{ name: "Pascal", key: "pascal" },
{ name: "Typescript", key: "ts" },
{ name: "React", key: "react" },
{ name: "English", key: "en" },
{ name: "Holy C", key: "hc" },
{ name: "Tensorflow", key: "tf" },
{ name: "Na'vi", key: "navi" },
];

export const addresses = [
{ street: "Hrad", city: "Bratislava", zip: "81101" },
{ street: "Hlavná", city: "Košice", zip: "04001" },
];

0 comments on commit a5b744d

Please sign in to comment.