import { FieldArray } from "formik"; import { Fragment, useEffect, useState } from "react"; import { Card, Flex, Label } from "theme-ui"; import * as yup from "yup"; import { Col, Flex as FlexGrid } from "@/legacy/components/Flex"; import WidgetFormField from "@/legacy/lib/builders/common/EditModal/Field"; import { createFieldNameFromKey } from "@/legacy/lib/forms"; import { DefaultFields } from "@/legacy/lib/forms/defaults"; import { TabFields } from "@/legacy/lib/models/common/CustomType"; import { AddThumbnailButton, ConstraintForm, ThumbnailButton, } from "./components"; const nullableNumberSchema = () => { return yup .number() .nullable() .transform((value: string | number, originalValue: string | number) => // When the user empties the field, it should convert it to null so that "auto" dimensions are set originalValue === "" ? null : value, ); }; const FormFields = { label: DefaultFields.label, id: DefaultFields.id, constraint: { validate: () => yup.object().defined().shape({ width: nullableNumberSchema(), height: nullableNumberSchema(), }), }, thumbnails: { validate: () => yup.array().of( yup.object().test({ name: "Thumbnails", message: "Must set name and width or height at minimum", test: function (value) { if (!value.name) { return false; } const hasWidth = typeof value.width === "number" && value.width; const hasHeight = typeof value.height === "number" && value.height; const hasWidthOrHeight = hasWidth || hasHeight; return value.name && hasWidthOrHeight; }, }), ), }, }; type Thumbnail = { name: string; width: string; height: string; }; const EMPTY_THUMBNAIL: Thumbnail = { name: "", width: "", height: "", }; const thumbText = ( { width, height, }: { width?: number | string; height?: number | string; } = {}, allowAuto = false, ) => { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (allowAuto && !width && !height) { return "auto"; } // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (width || height) { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions return `${width ? width : "auto"}x${height ? height : "auto"}`; } return "..."; }; type FieldValues = { id: string; config: { label: string; constraint: { width?: number; height?: number; }; thumbnails?: Array; }; }; type FormProps = { // actually some of formik props are passed down to values: FieldValues; initialValues: FieldValues; errors: Partial; touched: Partial; fields: TabFields; }; const Form: React.FC = (props) => { const { initialValues, values: formValues, errors, fields, touched } = props; const [thumbI, setThumbI] = useState(0); const { config: { thumbnails = [], constraint }, } = formValues; useEffect(() => { setThumbI(thumbnails.length); }, [thumbnails.length]); return ( {Object.entries(FormFields).map(([key, field]) => ( ))} ( setThumbI(0)} /> {thumbnails.map((e, i) => ( remove(i)} onClick={() => setThumbI(+i + 1)} /> ))} { push(EMPTY_THUMBNAIL); }} /> {thumbnails.map((_, i) => ( ))} )} /> ); }; export { FormFields }; export default Form;