Skip to content

Commit

Permalink
fix: selectField w/ required error message
Browse files Browse the repository at this point in the history
  • Loading branch information
MiroslavPetrik committed Feb 27, 2023
1 parent eda10d6 commit e7e2e71
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 13 deletions.
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ Most UI libraries provide styled primitive `<Input>` components, form `<Label>`

## Contents

| Field | About |
| ------------------------------- | --------------------------------------- |
| [`textField()`](#textfield) | A fieldAtom to capture `string` values. |
| [`selectField()`](#selectfield) | A fieldAtom to capture enum values. |

| Hooks | About |
| ------------------------------------------------------- | ----------------------------- |
| [`useClearFileFieldEffect()`](#useclearfilefieldeffect) | A hook to control file input. |
Expand Down
1 change: 1 addition & 0 deletions src/Intro.contents.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
| [fileField()](?path=/docs/fields-filefield--docs) | A field to hold a `FileList` value. |
| [numberField()](?path=/docs/fields-numberfield--docs) | A field to hold a `number` type. |
| [textField()](?path=/docs/fields-textfield--docs) | A field to hold a `string` type. |
| [selectField()](?path=/docs/fields-selectfield--docs) | A generic field to hold one of radio or select options. |

### Components

Expand Down
43 changes: 43 additions & 0 deletions src/fields/select-field/Docs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Meta, Markdown } from "@storybook/blocks";

import Config from "./config.md?raw";

<Meta title="fields/selectField" />

# `selectField<Value = string>(): ValidatedFieldAtom<Value | undefined>`

A generic choice field to hold a key of some options e.g. in `<input type="radio" />` or `<select />` elements.
The `undefined` empty value means that no option is selected.

```ts
import { selectField } from "@form-atoms/field";

// required string, must be filled to submit
const favoriteCategory = selectField();

// optional string, can be empty to submit
const companySize = selectField({ optional: true });
```

## Initial Config

<Markdown>{Config}</Markdown>

## Examples

### Number select

By default the select field works with `string` values. You can specify your own type. For example to make a rating field with choices 1-5
you will need a `numericSelectField`:

```ts
import { selectField } from "@form-atoms/field";
import { useFieldActions } from "form-atoms";

const rating = selectField<number>({ schema: z.number() });

const actions = useFieldActions(rating);

actions.setValue("4"); // ERR!
actions.setValue(4); // OK
```
5 changes: 5 additions & 0 deletions src/fields/select-field/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
| Param | Value |
| ---------------- | ------------------- |
| `value` | `undefined` |
| `schema` | `z.string()` |
| `optionalSchema` | `schema.optional()` |
12 changes: 6 additions & 6 deletions src/fields/select-field/selectField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ import {
ValidatedFieldAtomConfig,
validatedFieldAtom,
} from "..";
import { ZodParams, defaultParams } from "../zodParams";

export type SelectFieldAtom<Value = string> = ValidatedFieldAtom<
Value | undefined
>;

// possibly validate option literals, or union of literals
// https://zod.dev/?id=unions
export const selectField = <Value = string>(
config: Partial<ValidatedFieldAtomConfig<Value | undefined>> = {}
) =>
export const selectField = <Value = string>({
required_error = defaultParams.required_error,
...config
}: Partial<ValidatedFieldAtomConfig<Value | undefined>> & ZodParams = {}) =>
validatedFieldAtom({
value: undefined,
schema: z.string({ required_error: "This field is required" }),
schema: z.string({ required_error }),
...config,
});
4 changes: 2 additions & 2 deletions src/fields/text-field/useTextFieldProps.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChangeEvent } from "react";

import { TextFieldAtom, TextValue } from "./textField";
import { TextFieldAtom, TextFieldValue } from "./textField";
import { FieldProps, useFieldProps } from "..";

export type TextFieldProps = FieldProps<TextFieldAtom>;
Expand All @@ -10,7 +10,7 @@ const getEventValue = (
) => event.target.value;

export const useTextFieldProps = <F extends TextFieldAtom>(field: F) =>
useFieldProps<TextValue, HTMLInputElement | HTMLTextAreaElement>(
useFieldProps<TextFieldValue, HTMLInputElement | HTMLTextAreaElement>(
field,
getEventValue
);

0 comments on commit e7e2e71

Please sign in to comment.