refactor: modal component
This commit is contained in:
parent
8e6ffdccf6
commit
4e60aefc9d
2 changed files with 85 additions and 28 deletions
|
|
@ -41,6 +41,7 @@ interface FormValidation {
|
|||
export function NewClusterCreate() {
|
||||
const queryClient = useQueryClient();
|
||||
const [currentStepIndex, setCurrentStepIndex] = useState(0);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [formData, setFormData] = useState<ClusterFormData>({
|
||||
loader: 'vanilla',
|
||||
clusterName: '',
|
||||
|
|
@ -63,6 +64,15 @@ export function NewClusterCreate() {
|
|||
}), {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['getClusters'] });
|
||||
// Modal'ı kapat ve formu sıfırla
|
||||
setIsModalOpen(false);
|
||||
setCurrentStepIndex(0);
|
||||
setFormData({
|
||||
loader: 'vanilla',
|
||||
clusterName: '',
|
||||
clusterVersion: '',
|
||||
clusterProvider: '',
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -154,32 +164,30 @@ export function NewClusterCreate() {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<Modal.Trigger>
|
||||
<Button>
|
||||
<PlusIcon className="stroke-width-[2.2] size-5" />
|
||||
New cluster
|
||||
</Button>
|
||||
<Button onPress={() => setIsModalOpen(true)}>
|
||||
<PlusIcon className="stroke-width-[2.2] size-5" />
|
||||
New cluster
|
||||
</Button>
|
||||
|
||||
<Modal>
|
||||
<div className="min-w-sm flex flex-col rounded-lg bg-page text-center">
|
||||
<ModalHeader currentStep={currentStepConfig} />
|
||||
<Modal isDismissable isOpen={isModalOpen} onOpenChange={setIsModalOpen}>
|
||||
<div className="min-w-sm flex flex-col rounded-lg bg-page text-center">
|
||||
<ModalHeader currentStep={currentStepConfig} />
|
||||
|
||||
<div className="flex flex-col rounded-b-lg border border-white/5">
|
||||
<div className="p-3">
|
||||
{stepContent}
|
||||
</div>
|
||||
|
||||
<ModalFooter
|
||||
isFirstStep={isFirstStep}
|
||||
isNextDisabled={isNextDisabled}
|
||||
nextButtonText={nextButtonText}
|
||||
onBack={handleBack}
|
||||
onNext={handleNext}
|
||||
/>
|
||||
<div className="flex flex-col rounded-b-lg border border-white/5">
|
||||
<div className="p-3">
|
||||
{stepContent}
|
||||
</div>
|
||||
|
||||
<ModalFooter
|
||||
isFirstStep={isFirstStep}
|
||||
isNextDisabled={isNextDisabled}
|
||||
nextButtonText={nextButtonText}
|
||||
onBack={handleBack}
|
||||
onNext={handleNext}
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
</Modal.Trigger>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,68 @@
|
|||
import type { DialogProps } from 'react-aria-components';
|
||||
import type { VariantProps } from 'tailwind-variants';
|
||||
import {
|
||||
Dialog as AriaDialog,
|
||||
Modal as AriaModal,
|
||||
DialogTrigger,
|
||||
ModalOverlay,
|
||||
} from 'react-aria-components';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { tv } from 'tailwind-variants';
|
||||
|
||||
interface ModalProps extends DialogProps { }
|
||||
const modalVariants = tv({
|
||||
slots: {
|
||||
overlay: [
|
||||
'fixed inset-0 z-50',
|
||||
'flex items-center justify-center',
|
||||
'bg-black/50 p-4',
|
||||
|
||||
'data-[entering]:animate-in data-[entering]:fade-in data-[entering]:duration-200',
|
||||
'data-[exiting]:animate-out data-[exiting]:fade-out data-[exiting]:duration-150',
|
||||
],
|
||||
modal: [
|
||||
'data-[entering]:animate-in data-[entering]:zoom-in-95 data-[entering]:duration-200',
|
||||
'data-[exiting]:animate-out data-[exiting]:zoom-out-95 data-[exiting]:duration-150',
|
||||
],
|
||||
dialog: [
|
||||
'outline-none',
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
export interface ModalProps extends DialogProps, VariantProps<typeof modalVariants> {
|
||||
isOpen?: boolean;
|
||||
onOpenChange?: (isOpen: boolean) => void;
|
||||
isDismissable?: boolean;
|
||||
overlayClassName?: string;
|
||||
modalClassName?: string;
|
||||
}
|
||||
|
||||
function Modal({
|
||||
className,
|
||||
isOpen,
|
||||
onOpenChange,
|
||||
isDismissable = true,
|
||||
overlayClassName,
|
||||
modalClassName,
|
||||
...props
|
||||
}: ModalProps) {
|
||||
const { overlay, modal, dialog } = modalVariants();
|
||||
|
||||
const isControlled = isOpen !== undefined || onOpenChange !== undefined;
|
||||
|
||||
const overlayProps = {
|
||||
className: twMerge(overlay(), overlayClassName),
|
||||
isDismissable,
|
||||
...(isControlled && { isOpen, onOpenChange }),
|
||||
};
|
||||
|
||||
function Modal({ className, ...props }: ModalProps) {
|
||||
return (
|
||||
<ModalOverlay className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4" isDismissable>
|
||||
<AriaModal>
|
||||
<AriaDialog className="" {...props} />
|
||||
|
||||
<ModalOverlay {...overlayProps}>
|
||||
<AriaModal className={twMerge(modal(), modalClassName)}>
|
||||
<AriaDialog
|
||||
className={twMerge(dialog(), className)}
|
||||
{...props}
|
||||
/>
|
||||
</AriaModal>
|
||||
</ModalOverlay>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue