- vừa được xem lúc

Tạo modal với Nextjs 14

0 0 6

Người đăng: Huy Đỗ Hửu

Theo Viblo Asia

  1. Tạo context API: xử lý kèm logic:
"use client";
import { $ModalKeys } from "@/collects/modals";
import { Dispatch, PropsWithChildren, SetStateAction, createContext, useState,
} from "react"; type $ToggleFn = { key: $ModalKeys; data?: any }; type $Show = { [T in $ModalKeys]: { open: boolean; data?: any; };
}; type $_Modal = { onToggle: (props: $ToggleFn) => void; show: $Show; setShow: Dispatch<SetStateAction<$Show>>;
}; export let _$modal = {} as $_Modal; const useLogic = () => { const [show, setShow] = useState({} as $Show); const onToggle = (props: $ToggleFn) => { const { key, data } = props; setShow((prev) => ({ ...prev, [key]: { ...prev[key], open: !prev[key]?.open, data }, })); }; _$modal = { onToggle, show, setShow, }; return { onToggle, show, setShow };
}; type ValueCtx = ReturnType<typeof useLogic>; export const ModalCtx = createContext({} as ValueCtx); export const ModalProvider = ({ children }: PropsWithChildren) => { const valueCtx = useLogic(); return ( <ModalCtx.Provider value={{ ...valueCtx }}> <>{children}</> </ModalCtx.Provider> );
}; 
  1. Tạo Component Modal :
"use client";
import cx from "classnames";
import React, { useContext } from "react";
import ReactDOM from "react-dom";
import styles from "./styles.module.scss";
import { ModalCtx } from "./context"; export type $Modal = { open?: boolean; onToggle: () => void; data?: any;
}; type $Props = { set?: { open?: $Modal["open"]; isCloseOutside?: boolean; clsOverlay?: string; clsModal?: string; content?: (props: $Modal) => JSX.Element; header?: (props: $Modal) => JSX.Element; }; action: { onToggle: () => void; };
}; export default function Modal(props: $Props) { const { set, action } = props; const {} = useContext(ModalCtx); if (!set?.open) { return null; } return ReactDOM.createPortal( <div className={cx(styles.overlay, set?.clsOverlay)} onClick={set?.isCloseOutside ? action?.onToggle : undefined} > <div className={cx(styles.modal, set?.clsModal)} onClick={onStopPrpg}> {set?.header?.({ onToggle: action.onToggle })} {set.content?.({ onToggle: action.onToggle })} </div> </div>, document.body );
} const onStopPrpg = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => { event.stopPropagation(); event.preventDefault();
}; 
  1. Tạo SCSS : file styles.module.scss
.overlay { position: fixed; width: 100vw; height: 100vh; top: 0; display: flex; align-items: center; justify-content: center; .modal { background-color: lightblue; display: flex; flex-direction: column; width: fit-content; border-radius: 0.5rem; padding: 1rem; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); .header { display: flex; } }
} 

Đơn giản đúng hông, có thể tuỳ chỉnh styles tuỳ thích. Phần tiếp theo là Dropbox

Bình luận

Bài viết tương tự

- vừa được xem lúc

Một số thủ thuật hay ho với Linux (1).

1. Ctrl + x + e. Giữ CTRL, nhấn phím x rồi nhấn phím e. Thao tác này sẽ mở ra editor mặc định (echo $EDITOR | $VISUAL để kiểm tra) chứa sẵn.

0 0 34

- vừa được xem lúc

How to deploy Amplication app to DigitalOcean

This article shows you the way to deploy an app generated by Amplication to DigitalOcean. Amplication provides the dockerfile to use containers for deployment, but this blog explains how to do it manu

0 0 39

- vừa được xem lúc

Có gì mới trong Laravel 9.0?

Laravel v9 là phiên bản LTS tiếp theo của Laravel và ra mắt vào tháng 2 năm 2022. Trong bài viết này, mình xin giới thiệu một vài tính năng mới trong Laravel trong Laravel 9.

0 0 65

- vừa được xem lúc

Xây dựng trang web tra cứu ảnh sử dụng phân cụm Spectral Clustering

1. Tổng quan tra cứu ảnh. 1.1.

0 0 32

- vừa được xem lúc

Scanning network 1 - quét mạng như một hacker

Chào mọi người mình là Tuntun. Một năm qua là một năm khá bận rộn nhỉ.

0 0 34

- vừa được xem lúc

Interpreter Design Pattern - Trợ thủ đắc lực của Developers

1. Giới thiệu. . Interpreter là một mẫu thiết kế thuộc nhóm hành vi (Behavioral Pattern).

0 0 32