Skip to content

Commit

Permalink
docs: validate values in ascending order
Browse files Browse the repository at this point in the history
  • Loading branch information
MiroslavPetrik committed Mar 22, 2024
1 parent e15140b commit 1e7bc95
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 1 deletion.
78 changes: 78 additions & 0 deletions src/components/list/Docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -451,3 +451,81 @@ const RemoveButton = ({ remove }: RemoveButtonProps) => (
```

</Example>

<Example of={ListStories.ValidateAscendingValues} >

```tsx
import { fieldAtom, InputField } from "form-atoms";
import { List, listAtom } from "@form-atoms/list-atom";

const levels = listAtom({
value: [],
name: "levels",
fields: ({ level }) => ({ level: fieldAtom<number>({ value: level }) }),
validate: ({ value }) => {
const errors: string[] = [];

if (1 < value.length) {
let [current] = value;

value.forEach((value, index) => {
if (index === 0) {
return;
}

if (value.level <= current!.level) {
errors.push(
`Level at index ${index} must greater than the previous.`,
);
}

current = value;
});
}

return errors;
},
});

const Example = () => (
<>
<List atom={levels} initialValue={[10, 30, 20].map((level) => ({ level }))}>
{({ fields, moveUp, moveDown, RemoveButton }) => (
<div
style={{
display: "grid",
gridGap: 16,
gridTemplateColumns: "auto min-content min-content min-content",
}}
>
<InputField atom={fields.level} component="input" />
<button type="button" className="outline" onClick={moveUp}>
Up
</button>
<button type="button" className="outline" onClick={moveDown}>
Down
</button>
<RemoveButton />
</div>
)}
</List>
<FieldErrors atom={levels} />
</>
);

const FieldErrors = ({ atom }: { atom: FieldAtom<any> }) => {
const errors = useFieldErrors(atom);

return (
<>
{errors.map((error, index) => (
<p key={index} style={{ color: "var(--pico-color-red-550)" }}>
{error}
</p>
))}
</>
);
};
```

</Example>
64 changes: 63 additions & 1 deletion src/components/list/List.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { StoryObj } from "@storybook/react";
import {
FieldAtom,
type FieldAtom,
type FormFieldValues,
type FormFields,
InputField,
Expand All @@ -10,6 +10,7 @@ import {

import { AddButtonProps, List, ListProps, RemoveButtonProps } from "./List";
import { listAtom } from "../../atoms";
import { PicoFieldErrors } from "../../story/PicoFieldErrors";
import { PicoFieldName } from "../../story/PicoFieldName";
import { StoryForm } from "../../story/StoryForm";

Expand Down Expand Up @@ -447,3 +448,64 @@ export const ProgrammaticallySetValue = listStory({
);
},
});

export const ValidateAscendingValues = listStory({
parameters: {
docs: {
description: {
story: "",
},
},
},
args: {
initialValue: [{ level: 10 }, { level: 30 }, { level: 20 }],
atom: listAtom({
name: "levels",
value: [{ level: 0 }],
fields: ({ level }) => ({ level: fieldAtom<number>({ value: level }) }),
validate: ({ value }) => {
const errors: string[] = [];

if (1 < value.length) {
let [current] = value;

value.forEach((value, index) => {
if (index === 0) {
return;
}

if (value.level <= current!.level) {
errors.push(
`Level at index ${index} must greater than the previous.`,
);
}

current = value;
});
}

return errors;
},
}),
children: ({ fields, moveUp, moveDown, RemoveButton }) => (
<fieldset role="group">
<InputField atom={fields.level} component="input" type="number" />
<button type="button" className="outline" onClick={moveUp}>
Up
</button>
<button type="button" className="outline" onClick={moveDown}>
Down
</button>
<RemoveButton />
</fieldset>
),
},
render: (props) => {
return (
<>
<List {...props} />
<PicoFieldErrors atom={props.atom} />
</>
);
},
});
17 changes: 17 additions & 0 deletions src/story/PicoFieldErrors.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FieldAtom, useFieldErrors } from "form-atoms";

const style = { color: "var(--pico-color-red-550)" };

export const PicoFieldErrors = ({ atom }: { atom: FieldAtom<any> }) => {
const errors = useFieldErrors(atom);

return (
<>
{errors.map((error, index) => (
<p key={index} style={style}>
{error}
</p>
))}
</>
);
};

0 comments on commit 1e7bc95

Please sign in to comment.