feat: 去掉antd
This commit is contained in:
@@ -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];
|
||||
};
|
||||
|
||||
47
packages/components/src/select/TagsInput.tsx
Normal file
47
packages/components/src/select/TagsInput.tsx
Normal 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} />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
18
packages/components/src/select/index.tsx
Normal file
18
packages/components/src/select/index.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
@@ -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],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user