Untitled

 avatar
unknown
plain_text
a year ago
3.7 kB
6
Indexable
import * as React from "react";
import { addPropertyControls, ControlType } from "framer";

const FormFieldTypes = {
  Checkbox: "checkbox",
  Email: "email",
  Password: "password",
  Select: "select",
  Phone: "tel",
  Radio: "radio",
};

const Form = ({ fields, labelsStyle, fieldsStyle }) => {
  const renderField = (field, index) => {
    const { type, label, options, style, labelStyle } = field;
    switch (type) {
      case FormFieldTypes.Select:
        return (
          <label key={index} style={{ ...labelsStyle, ...labelStyle }}>
            {label}
            <select style={{ ...fieldsStyle, ...style }}>
              {options.map((option, optionIndex) => (
                <option key={optionIndex} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </label>
        );
      case FormFieldTypes.Radio:
        return options.map((option, optionIndex) => (
          <label key={`${index}-${optionIndex}`} style={{ ...labelsStyle, ...labelStyle }}>
            <input type={type} name={label} value={option.value} style={{ ...fieldsStyle, ...style }} />
            {option.label}
          </label>
        ));
      default:
        return (
          <label key={index} style={{ ...labelsStyle, ...labelStyle }}>
            {label}
            <input type={type} style={{ ...fieldsStyle, ...style }} />
          </label>
        );
    }
  };

  return <form>{fields.map(renderField)}</form>;
};

Form.defaultProps = {
  fields: [],
  labelsStyle: {},
  fieldsStyle: {},
};

addPropertyControls(Form, {
  fields: {
    type: ControlType.Array,
    control: {
      type: ControlType.Object,
      controls: {
        type: {
          type: ControlType.Enum,
          options: Object.values(FormFieldTypes),
          optionTitles: Object.keys(FormFieldTypes),
        },
        label: {
          type: ControlType.String,
        },
        options: {
          type: ControlType.Array,
          control: {
            type: ControlType.Object,
            controls: {
              label: { type: ControlType.String },
              value: { type: ControlType.String },
            },
          },
          hidden: ({ type }) => type !== FormFieldTypes.Select && type !== FormFieldTypes.Radio,
        },
        style: {
          type: ControlType.Object,
          controls: {
            background: { type: ControlType.Color },
            border: { type: ControlType.String },
            borderColor: { type: ControlType.Color },
          },
        },
        labelStyle: {
          type: ControlType.Object,
          controls: {
            color: { type: ControlType.Color },
            fontSize: { type: ControlType.Number },
            fontWeight: { type: ControlType.Enum, options: ["normal", "bold"], optionTitles: ["Normal", "Bold"] },
          },
        },
      },
    },
    defaultValue: [],
  },
  labelsStyle: {
    type: ControlType.Object,
    controls: {
      color: { type: ControlType.Color, defaultValue: "#000" },
      fontSize: { type: ControlType.Number, defaultValue: 14 },
      fontWeight: { type: ControlType.Enum, options: ["normal", "bold"], optionTitles: ["Normal", "Bold"], defaultValue: "normal" },
    },
  },
  fieldsStyle: {
    type: ControlType.Object,
    controls: {
      background: { type: ControlType.Color, defaultValue: "#fff" },
      border: { type: ControlType.String, defaultValue: "1px solid #000" },
      borderColor: { type: ControlType.Color, defaultValue: "#000" },
    },
  },
});

export default Form;
Editor is loading...
Leave a Comment