import { useState } from 'react' import { Alert, Button, Checkbox, Cascader, Code, ColorInput, Container, FileInput, Group, MultiSelect, NumberInput, Paper, PasswordInput, Radio, Select, SimpleGrid, Stack, Switch, TagsInput, Text, Textarea, TextInput, Title, useMatches, } from '@mantine/core' import { isEmail, useForm } from '@mantine/form' import { UploadSimpleIcon } from '@phosphor-icons/react' import classes from './page-form.module.css' // 仅用于演示联动,不是完整行政区划数据。 const regions = [ { name: '浙江省', cities: [ { name: '杭州市', districts: ['西湖区', '拱墅区'] }, { name: '宁波市', districts: ['海曙区', '鄞州区'] }, ], }, { name: '江苏省', cities: [ { name: '南京市', districts: ['鼓楼区', '玄武区'] }, { name: '苏州市', districts: ['姑苏区', '吴中区'] }, ], }, ] const regionOptions = regions.map((province) => ({ value: province.name, children: province.cities.map((city) => ({ value: city.name, children: city.districts.map((district) => ({ value: district })), })), })) type FormValues = { name: string email: string role: string | null region: string[] | null contact: string interests: string[] technologies: string[] tags: string[] color: string files: File[] quantity: number | string password: string description: string notifications: boolean acceptedTerms: boolean } const exampleErrors = { email: '邮箱格式不正确,例如 name@example.com' } export default function FormExample() { const [submitted, setSubmitted] = useState(null) const withColumns = useMatches({ base: false, sm: true }) const form = useForm({ mode: 'controlled', validateInputOnBlur: true, initialErrors: exampleErrors, initialValues: { name: '', email: 'invalid-email', role: null, region: null, contact: 'email', interests: [], technologies: [], tags: [], color: '#228be6', files: [], quantity: 1, password: '', description: '', notifications: false, acceptedTerms: false, }, validate: { name: (value) => value.trim() ? null : '请输入名称', email: (value) => !value.trim() ? '请输入邮箱' : isEmail(exampleErrors.email)(value.trim()), role: (value) => value ? null : '请选择角色', quantity: (value) => typeof value === 'number' && Number.isInteger(value) && value >= 0 && value <= 100 ? null : '请输入 0–100 之间的整数', password: (value) => value && value.length < 8 ? '密码至少需要 8 位' : null, color: (value) => /^#[\da-f]{6}$/i.test(value) ? null : '请输入有效的六位 HEX 颜色', acceptedTerms: (value) => value ? null : '请先阅读并同意示例协议', }, }) function submit(values: FormValues) { setSubmitted(JSON.stringify({ ...values, password: values.password ? '已填写(不展示密码)' : '未填写', files: values.files.map((file) => ({ name: file.name, size: file.size, type: file.type || '未知类型', })), }, null, 2)) } return (
表单示例 体验常用表单控件。提交后在本页预览结果,数据和文件不会发送到服务器。
setSubmitted(null))} onReset={(event) => { event.preventDefault() form.reset() form.setErrors(exampleErrors) setSubmitted(null) }} noValidate > 带 * 的项目为必填项;离开输入框或提交时会校验。邮箱预填了错误值,用于演示错误提示。