mantine: 自定义Form控件

自定义CustomizeInput
更新于: 2024-05-07 13:25:08

定义一个复合类型的控件

一般这种类型的数据 value 是一个 object

/**
 * @email: aric.zheng@alo7.com
 * @description: A React component.
 * @created_at: 2024-04-25 11:17:16
 */
import React from 'react';
import { Fieldset, NumberInput, Select } from '@mantine/core';

interface InputProps {
  value?: Record<string, any>;
  onChange?: (event: any) => void;
}

const Anonymous = (props: InputProps) => {
  const configs = nx.$use('v2App.configs');
  const undergraduate_colleges = nx.get(configs, 'undergraduate_colleges', []);
  const undergraduate_majors = nx.get(configs, 'undergraduate_majors', []);
  const { value, onChange, ...rest } = props;
  const handleInputChange = (field: string, event: any) => {
    onChange?.({ ...value, [field]: event });
  };
  return (
    <Fieldset legend={<label className="font-bold">学术背景</label>}>
      <div className="grid grid-cols-2 gap-5">
        <Select
          data={undergraduate_colleges}
          withAsterisk
          label="学校"
          searchable
          limit={20}
          placeholder="请选择本科院校"
          className="col-span-2"
          value={value?.school_name}
          onChange={(event) => handleInputChange('school_name', event)}
          {...rest}
        />
        <Select
          label="年级"
          placeholder="年级"
          withAsterisk
          data={['大一', '大二', '大三', '大四']}
          value={value?.grade_level}
          onChange={(event) => handleInputChange('grade_level', event)}
          {...rest}
        />
        <Select
          withAsterisk
          data={undergraduate_majors}
          label="专业"
          searchable
          limit={20}
          placeholder="请选择本科专业"
          value={value?.undergraduate_major}
          onChange={(event) => handleInputChange('undergraduate_major', event)}
          {...rest}
        />
        <NumberInput
          label="GPA"
          placeholder="GPA"
          withAsterisk
          value={value?.gpa || 0}
          onChange={(event) => handleInputChange('gpa', event)}
          {...rest}
        />
        <Select
          data={['Top 1%', 'Top 5%', 'Top 10%', 'Top 25%', 'Top 50%', 'Top 75%', 'Top 100%']}
          label="排名"
          placeholder="请输入排名"
          value={value?.class_rank}
          onChange={(event) => handleInputChange('class_rank', event)}
          {...rest}
        />
      </div>
    </Fieldset>
  );
};

export default Anonymous;

值类型的

这个是官方文档提供的示例。

interface CustomInputProps {
  value?: string;
  defaultValue?: string;
  onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
  onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
  onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
  error?: string;
}

export function CustomInput({
  value,
  defaultValue,
  onChange,
  onFocus,
  onBlur,
  error,
}: CustomInputProps) {
  return (
    <div>
      <input
        value={value}
        defaultValue={defaultValue}
        onChange={onChange}
        onFocus={onFocus}
        onBlur={onBlur}
      />
      {error && <div>{error}</div>}
    </div>
  );
}

值类型项目实战

/**
 * @email: aric.zheng@alo7.com
 * @description: A React component.
 * @created_at: 2024-05-07 11:00:10
 */

import { Select } from '@mantine/core';
import RadioGroup from '@/shared/components/radio-group';

export default (props: StdCustomInputProps<string>) => {
  const { value, onChange, ...rest } = props;
  const configs = nx.$use('v2App.configs');
  const undergraduate_colleges = nx.get(configs, 'undergraduate_colleges', []);
  const hot_universities = undergraduate_colleges.slice(0, 10);

  return (
    <div className="debug-red y relative gap-5">
      <h1 className="text-center text-xl">请选择你的本科学校?</h1>
      <RadioGroup value={value} items={hot_universities} onChange={onChange} />
      <Select
        data={undergraduate_colleges}
        placeholder="请输入本科学校"
        searchable
        limit={20}
        value={value}
        onChange={onChange}
        {...rest}
      />
    </div>
  );
};

参考