feat: 去掉antd

This commit is contained in:
2025-03-20 21:47:50 +08:00
parent c206add7eb
commit cfd263a1e7
36 changed files with 1369 additions and 769 deletions

View File

@@ -1,13 +1,13 @@
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Button } from '@mui/material';
import { useRef, useState } from 'react';
import type { ModalFuncProps } from 'antd';
export const Confirm = ({
open,
onClose,
title,
content,
onConfirm,
confirmText = '确认',
okText = '确认',
cancelText = '取消',
}: {
open: boolean;
@@ -15,11 +15,15 @@ export const Confirm = ({
title: string;
content: string;
onConfirm?: () => void;
confirmText?: string;
okText?: string;
cancelText?: string;
}) => {
return (
<Dialog open={open} onClose={onClose} aria-labelledby='alert-dialog-title' aria-describedby='alert-dialog-description'>
<Dialog
open={open}
onClose={onClose}
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'>
<DialogTitle id='alert-dialog-title' className='text-secondary min-w-[300px]'>
{title}
</DialogTitle>
@@ -31,7 +35,7 @@ export const Confirm = ({
{cancelText || '取消'}
</Button>
<Button onClick={onConfirm} variant='contained' color='primary' autoFocus>
{confirmText || '确认'}
{okText || '确认'}
</Button>
</DialogActions>
</Dialog>
@@ -39,53 +43,57 @@ export const Confirm = ({
};
type Fn = () => void;
export const useConfirm = () => {
export const useModal = () => {
const [open, setOpen] = useState(false);
const [title, setTitle] = useState('');
const [content, setContent] = useState('');
const fns = useRef<{
onConfirm: Fn;
onCancel: Fn;
confirmText: string;
okText: string;
cancelText: string;
}>({
onConfirm: () => {},
onCancel: () => {},
confirmText: '确认',
okText: '确认',
cancelText: '取消',
});
return {
contextHolder: (
<Confirm
open={open}
confirmText={fns.current.confirmText}
cancelText={fns.current.cancelText}
onClose={() => {
setOpen(false);
fns.current.onCancel();
}}
title={title}
content={content}
onConfirm={fns.current.onConfirm}
/>
),
confirm: (
title: string,
content: string,
opts?: {
onConfirm: () => void;
confirmText?: string;
cancelText?: string;
onCancel?: () => void;
},
) => {
const modal = {
confirm: (props: ModalFuncProps) => {
setOpen(true);
setTitle(title);
setContent(content);
fns.current.onConfirm = opts?.onConfirm || (() => {});
fns.current.onCancel = opts?.onCancel || (() => {});
fns.current.confirmText = opts?.confirmText || '确认';
fns.current.cancelText = opts?.cancelText || '取消';
setTitle(props.title as string);
setContent(props.content as string);
fns.current.onConfirm = async () => {
const isClose = await props.onOk?.();
if (!isClose) {
setOpen(false);
}
};
fns.current.onCancel = async () => {
await props.onCancel?.();
setOpen(false);
};
fns.current.okText = props.okText as string;
fns.current.cancelText = props.cancelText as string;
},
cancel: () => {
setOpen(false);
fns.current.onCancel();
},
};
const contextHolder = (
<Confirm
open={open}
okText={fns.current.okText}
cancelText={fns.current.cancelText}
onClose={() => {
setOpen(false);
fns.current.onCancel();
}}
title={title}
content={content}
onConfirm={fns.current.onConfirm}
/>
);
return [modal, contextHolder] as [typeof modal, React.ReactNode];
};

View File

@@ -0,0 +1,47 @@
import { Fragment, useEffect, useState } from 'react';
import Autocomplete from '@mui/material/Autocomplete';
import { TextField, Chip } from '@mui/material';
type TagsInputProps = {
value: string[];
onChange: (value: string[]) => void;
placeholder?: string;
label?: string;
};
export const TagsInput = ({ value, onChange, placeholder = 'Add a tag', label = 'Tags' }: TagsInputProps) => {
const [tags, setTags] = useState<string[]>(value);
useEffect(() => {
setTags(value);
}, [value]);
const randomid = () => {
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
};
return (
<Autocomplete
multiple
freeSolo
options={[]}
value={tags}
onChange={(event, newValue) => {
// setTags(newValue as string[]);
onChange(newValue as string[]);
}}
renderTags={(value: string[], getTagProps) => {
const id = randomid();
const com = value.map((option: string, index: number) => (
<Chip
variant='outlined'
sx={{
borderColor: 'primary.main',
}}
label={option}
{...getTagProps({ index })}
key={`${id}-${index}`}
/>
));
return <Fragment key={id}>{com}</Fragment>;
}}
renderInput={(params) => <TextField {...params} variant='outlined' label={label} placeholder={placeholder} />}
/>
);
};

View File

@@ -0,0 +1,18 @@
import { MenuItem, Select as MuiSelect, SelectProps as MuiSelectProps } from '@mui/material';
type SelectProps = {
options?: { label: string; value: string }[];
} & MuiSelectProps;
export const Select = (props: SelectProps) => {
const { options, ...rest } = props;
return (
<MuiSelect {...rest}>
{options?.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</MuiSelect>
);
};

View File

@@ -58,7 +58,7 @@ export const themeOptions: ThemeOptions = {
// paper: '#f5f5f5', // 设置纸张背景颜色
},
error: {
main: red[500],
main: red[500], // 设置错误颜色 "#f44336"
},
},
shadows: generateShadows('rgba(255, 193, 7, 0.2)'),
@@ -94,6 +94,14 @@ export const themeOptions: ThemeOptions = {
},
},
MuiTextField: {
defaultProps: {
fullWidth: true,
slotProps: {
inputLabel: {
shrink: true,
},
},
},
styleOverrides: {
root: {
'& .MuiOutlinedInput-root': {
@@ -145,6 +153,29 @@ export const themeOptions: ThemeOptions = {
},
},
},
MuiFormControlLabel: {
defaultProps: {
labelPlacement: 'top',
sx: {
alignItems: 'flex-start',
'& .MuiFormControlLabel-label': {
textAlign: 'left',
width: '100%',
},
'& .MuiFormControlLabel-root': {
width: '100%',
},
'& .MuiInputBase-root': {
width: '100%',
},
},
},
styleOverrides: {
root: {
color: amber[600],
},
},
},
},
};