Skip to content

Commit

Permalink
docs: programmatic value control of the list atom
Browse files Browse the repository at this point in the history
fixes #4
  • Loading branch information
MiroslavPetrik committed Mar 11, 2024
1 parent 0438674 commit 50a0895
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 2 deletions.
105 changes: 103 additions & 2 deletions src/components/list/Docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ const users = listAtom({
const NestedListExample = () => {
return (
<List
field={users}
atom={users}
AddButton={({ add }) => (
<button type="button" className="outline" onClick={add}>
Add Person
Expand Down Expand Up @@ -309,7 +309,7 @@ const NestedListExample = () => {
</div>
</div>
<List
field={fields.accounts}
atom={fields.accounts}
AddButton={({ add }) => (
<button type="button" className="outline" onClick={add}>
Add Bank Account
Expand Down Expand Up @@ -350,3 +350,104 @@ const RemoveButton = ({ remove }: RemoveButtonProps) => (
```

</Example>

<Example of={ListStories.ProgrammaticallySetValue} >

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

const environmentListAtom = listAtom({
name: "environment",
value: [
{ variable: "GITHUB_TOKEN", value: "<secret>" },
{ variable: "NPM_TOKEN", value: "<secret>" },
],
fields: ({ variable, value }) => ({
variable: fieldAtom({ name: "variable", value: variable }),
value: fieldAtom({ name: "value", value: value }),
}),
});

const ProgrammaticControls = ({ add }: AddButtonProps) => {
/**
* listAtom is fieldAtom, so any useField* hooks work:
*/
const actions = useFieldActions(environmentListAtom);

return (
<section className="grid">
<button type="button" className="outline" onClick={() => add()}>
New variable
</button>
<button
type="button"
className="outline secondary"
onClick={() =>
// clear the field - remove all items
actions.setValue([])
}
>
Clear
</button>
<button
type="button"
className="outline contrast"
onClick={() =>
// set multiple values
actions.setValue([
{ variable: "NPM_TOKEN", value: "secrettoken" },
{ variable: "NODE_ENV", value: "production" },
])
}
>
Set values from .env file
</button>
</section>
);
};

const ProgrammaticallySetValueExample = () => {
return (
<List atom={environmentListAtom} AddButton={ProgrammaticControls}>
{({ fields, RemoveButton }) => (
<div
style={{
display: "grid",
gridGap: 16,
gridTemplateColumns: "auto auto min-content",
}}
>
<div>
<InputField
atom={fields.variable}
render={(props) => (
<input {...props} placeholder="Variable Name" />
)}
/>
</div>
<div>
<InputField
atom={fields.value}
render={(props) => (
<input {...props} placeholder="Variable Value" />
)}
/>
</div>
<div>
<RemoveButton />
</div>
</div>
)}
</List>
);
};

const RemoveButton = ({ remove }: RemoveButtonProps) => (
<button type="button" className="outline secondary" onClick={remove}>
Remove
</button>
);
```

</Example>
91 changes: 91 additions & 0 deletions src/components/list/List.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
type FormFields,
InputField,
fieldAtom,
useFieldActions,
} from "form-atoms";

import { AddButtonProps, List, ListProps, RemoveButtonProps } from "./List";
Expand Down Expand Up @@ -356,3 +357,93 @@ export const NestedList = listStory({
),
},
});

export const ProgrammaticallySetValue = listStory({
parameters: {
docs: {
description: {
story:
"The `listAtom` is a regular `fieldAtom`, so it works with the form-atoms field hooks. " +
"Here we use the `setValue` action from the `useFieldActions()` hook to clear or initialize the list programmatically.",
},
},
},
args: {
atom: listAtom({
name: "environment",
value: [
{ variable: "GITHUB_TOKEN", value: "<secret>" },
{ variable: "NPM_TOKEN", value: "<secret>" },
],
fields: ({ variable, value }) => ({
variable: fieldAtom({ name: "variable", value: variable }),
value: fieldAtom({ name: "value", value: value }),
}),
}),
children: ({ fields, RemoveButton }) => (
<div
style={{
display: "grid",
gridGap: 16,
gridTemplateColumns: "auto auto min-content",
}}
>
<div>
<InputField
atom={fields.variable}
render={(props) => <input {...props} placeholder="Variable Name" />}
/>
</div>
<div>
<InputField
atom={fields.value}
render={(props) => (
<input {...props} placeholder="Variable Value" />
)}
/>
</div>
<div>
<RemoveButton />
</div>
</div>
),
},
render: (props) => {
const actions = useFieldActions(props.atom);

return (
<>
<List
{...props}
AddButton={({ add }) => (
<section className="grid">
<button type="button" className="outline" onClick={() => add()}>
New variable
</button>
<div />
<button
type="button"
className="outline secondary"
onClick={() => actions.setValue([])}
>
Clear
</button>
<button
type="button"
className="outline contrast"
onClick={() =>
actions.setValue([
{ variable: "NPM_TOKEN", value: "secrettoken" },
{ variable: "NODE_ENV", value: "production" },
])
}
>
Set values from .env file
</button>
</section>
)}
/>
</>
);
},
});

0 comments on commit 50a0895

Please sign in to comment.