Skip to content

Latest commit

 

History

History
173 lines (154 loc) · 3.45 KB

field-examples.md

File metadata and controls

173 lines (154 loc) · 3.45 KB

Example Fields

These can be a good starting points for your fields with @ts-react/form

  1. Select
  2. Text Field
  3. Number Field
  4. Checkbox
  5. Multi Checkbox

Select

function Select({ options }: { options: string[] }) {
  const { field, error } = useTsController<string>();
  return (
    <>
      <select
        value={field.value ? field.value : "none"}
        onChange={(e) => {
          field.onChange(e.target.value);
        }}
      >
        {!field.value && <option value="none">Please select...</option>}
        {options.map((e) => (
          <option key={e} value={e}>
            {e}
          </option>
        ))}
      </select>
      <span>{error?.errorMessage && error.errorMessage}</span>
    </>
  );
}

const mapping = [
  // z.number() is also viable. You'll probably have to use "createUniqueFieldSchema" (since you probably already have a Text Field)
  [z.string(), DropDownSelect],
] as const;

const MyForm = z.object({
  eyeColor: z.string(),
  favoritePants: z.string(),
});

function MyPage() {
  return (
    <Form
      schema={MyForm}
      onSubmit={() => {}}
      renderAfter={() => <button>Submit</button>}
      props={{
        eyeColor: {
          options: ["blue", "red", "green"],
        },
        favoritePants: {
          options: ["khakis", "blue jeans"],
        },
      }}
    />
  );
}

Text Field

function TextField() {
  const {
    field: { onChange, value },
    error,
  } = useTsController<string>();

  return (
    <>
      <input
        onChange={(e) => onChange(e.target.value)}
        value={value ? value : ""}
      />
      {error && error.errorMessage}
    </>
  );
}

Number Field

function NumberField({ req }: { req: number }) {
  const {
    field: { onChange, value },
    error,
  } = useTsController<number>();
  return (
    <>
      <span>
        <span>{`req is ${req}`}</span>
        <input
          value={value !== undefined ? value + "" : ""}
          onChange={(e) => {
            const value = parseInt(e.target.value);
            if (isNaN(value)) onChange(undefined);
            else onChange(value);
          }}
        />
        {error && error.errorMessage}
      </span>
    </>
  );
}

Checkbox

function Checkbox({ name }: { name: string }) {
  const {
    field: { onChange, value },
  } = useTsController<boolean>();

  return (
    <label>
      {name}
      <input
        onChange={(e) => onChange(e.target.checked)}
        checked={value ? value : false}
        type="checkbox"
      />
    </label>
  );
}

Multi Checkbox

function MultiCheckbox({ options }: { options: string[] }) {
  const {
    field: { onChange, value },
  } = useTsController<string[]>();

  function toggleField(option: string) {
    if (!value) onChange([option]);
    else {
      onChange(
        value.includes(option)
          ? value.filter((e) => e !== option)
          : [...value, option]
      );
    }
  }

  return (
    <>
      {options.map((optionValue) => (
        <label
          htmlFor={optionValue}
          style={{ display: "flex", flexDirection: "row" }}
          key={optionValue}
        >
          {optionValue}
          <input
            name={optionValue}
            type="checkbox"
            onChange={() => toggleField(optionValue)}
            checked={value?.includes(optionValue) ? true : false}
          />
        </label>
      ))}
    </>
  );
}