-
Notifications
You must be signed in to change notification settings - Fork 0
πͺλͺ¨λ¬μ κ΄νμ¬β¦
λͺ¨λ¬μ μ΄λͺ©μ μ§μ€μν€κΈ° μν΄ μ¬μ©νλ νλ©΄ μ ν κΈ°λ²μ΄λ€.
νλ‘ νΈμλμμλ λ°λμ ꡬννκ² λλ κ·Έκ²μ΄λ€.
μ°λ¦¬ μλΉμ€λ λͺ¨λ¬μ΄ κ΅μ₯ν λ§λ€.
λͺ¨λ¬μ΄ νλλΏμ΄λΌλ©΄ λ±ν κ³ λ―Όνμ§ μκ² μ§λ§, μ°λ¦¬ μλΉμ€λ κ΅μ₯ν λͺ¨λ¬μ΄ λ§λ€.
λ°λ³΅ν΄μ μ¬μ©λκΈ°μ κ³΅ν΅ μ»΄ν¬λνΈλ‘ λ§λ€μ΄μ€ νμκ° μμλ€.
λͺ¨λ¬μ ꡬμ±νλ λ°©λ²μ μ°Ύμ보λ μ¬λ¬ λ°©λ²μ΄ μμ§λ§ ν¬κ² λ κ°μ§λ‘ λΆλ₯λλ κ² κ°μλ€.
β κ° μ»΄ν¬λνΈμμ λͺ¨λ¬μ μ μ μνλ₯Ό λ³κ²½νμ¬ λ΄μ©μ λ°κΎΈλ λ±μ μμ μ μν
μ₯μ
- root μμ μΈμ DOMμμλ₯Ό μΆκ°νμ¬(usePortal νμ©) λ 립μ μΈ modalκ΅¬μ± κ°λ₯
- Modalμμλ typeμ λ°λΌ λͺ¨λ¬ λ΄μ©μ λ°κΏμ£Όκ³ , modal μ λμμ£Όλ μ»΄ν¬λνΈλ μ μ λͺ¨λ¬μ typeκ³Ό propsλ§μ μ€μ νλ―λ‘ μ»΄ν¬λνΈκ°μ μν κ³Ό μ± μμ΄ λͺ νν΄μ§
λ¨μ
- λͺ¨λ¬μ΄ νλ μΆκ°λ λλ§λ€ Modalμ»΄ν¬λνΈμμ λͺ¨λ¬ typeμ μΆκ°ν΄μ£Όμ΄μΌν¨
- ꡬνμ΄ μ½μ§μμ
β λͺ¨λ¬ μ»΄ν¬λνΈλ ν νλ¦Ώλ§μ μ 곡νκ³ , μ΄λ₯Ό μ¬μ©νλ μ»΄ν¬λνΈμμ μ λμ μΌλ‘ μμ±νλ ννλ‘ μ¬μ¬μ© ν μ μλλ‘ κ΅¬μ±
μ₯μ
- modalμ rootλ΄λΆμ λ λλ§λλ , useModalμ ν΅ν΄ Modal ν νλ¦Ώμ κΊΌλ΄κ³ , Modal μ λ΄λΆ μμλ modalμ λμ°λ μ»΄ν¬λνΈμμ κ²°μ ν΄μ£ΌκΈ°μ μ‘°κΈ λ μ μ°νκ³ , μ¬μ©νκΈ° μ¬μ
λ¨μ
- μ 체μ λͺ¨λ¬μ΄ μ΄λ€ κ²λ€μ΄ μλμ§ νμ νκΈ° λͺ¨νΈν΄μ§
- μ»΄ν¬λνΈμ μν κ³Ό μ± μμ΄ λͺ¨νΈν΄μ§
- rootλ΄λΆμ λͺ¨λ¬μ΄ λ λλ§λ¨
μ΄λ κ² κ³ λ―Όνλ μ€ λ¦¬λ·°μ΄λκ» μ‘°μΈμ ꡬνκ³ , λͺ¨λ¬μ΄ μ¬λ¬κ° λ¨λ κ²½μ°κΉμ§ κ³ λ €ν΄λ³Όλ§νλ€λ μ견과 ν¨κ» μ’μ λΌμ΄λΈλ¬λ¦¬ μ½λ(https://github.com/eBay/nice-modal-react)λ₯Ό νλ μ£Όμ ¨λ€.
ν΄λΉ λΌμ΄λΈλ¬λ¦¬μ μ½λλ₯Ό μ°Έκ³ νμ¬ ν΄κ²°ν μ μμλ€. useModalμ λͺ¨λ¬ λ΄λΆμ λ³΄μΌ μ»΄ν¬λνΈλ₯Ό μΈμλ‘ μ£Όκ³ , show, hideν¨μλ₯Ό μ»μ΄μ€λ ννλ‘ κ΅¬νν΄μ£Όμλ€.
μ΄ λΌμ΄λΈλ¬λ¦¬λ κΈ°λ³Έμ μΌλ‘ useContextλ₯Ό ν΅ν΄μ μ²λ¦¬νκ³ μμΌλ, μ°λ¦¬λ Zustandλ₯Ό ν΅ν΄ μ²λ¦¬ν΄μ€ κ²μ΄λ€. ν΅μ¬ μμ΄λμ΄λ λ°°μ΄ ννλ‘ modalμ μνλ₯Ό κ΄λ¦¬νκ³ μ΄κ±Έ νν°λ§νμ¬ λ λλ§νλ κ²μ΄λ€.
λν, λͺ¨λ¬λ΄λΆμ λ€μ΄κ° μ»΄ν¬λνΈλ₯Ό stateλ‘ κ΄λ¦¬νλ©΄ 무거μ°λ―λ‘, λͺ¨λ¬ μ»΄ν¬λνΈμ 본체λ λ°λ‘ κ°μ²΄λ‘ κ΄λ¦¬νλ€.
export const MODAL_COMPONENTS: { [id: string]: { Comp: React.ComponentType<any>; props?: Record<string, unknown> } } = {};
type Modal = {
id: string;
visible: boolean;
props: Record<string, unknown>;
};
type ModalState = {
modals: Modal[];
addModal: (id: string) => void;
removeModal: (id: string) => void;
showModal: (id: string) => void;
hideModal: (id: string) => void;
};
κ·Έλ¦¬κ³ μ΄λ₯Ό modals μν λ°°μ΄μ κ΄λ¦¬νλ actionν¨μ 4κ°λ₯Ό λ§λ€μ΄μ£Όμλ€.
μ΄λ₯Ό ν΅ν΄ μ΄μ modalsμ μν λ°°μ΄μ κ΄λ¦¬ν μ μκ² λμλ€. μ΄λ€μ€ visibleμΈ μ»΄ν¬λνΈλ€λ§ μ°μ΄μ£Όλ©΄λλ€.
export default function Modals() {
const { modals } = useModalState((state) => state);
const { hideModal } = useModalState((state) => state);
const modalComponents = modals
.filter((modal) => modal.visible) //visibleμΈκ² νν°λ§
.filter((modal) => MODAL_COMPONENTS[modal.id]) //modal λ°°μ΄μ체μλ μ»΄ν¬λνΈκ° μμΌλ―λ‘, MODAL_COMPONENTSμμ κ°μ Έμ΄
.map((modal) => ({
id: modal.id,
Modal: MODAL_COMPONENTS[modal.id],
}));
return (
<>
{modalComponents.map(({ Modal, id }) => (
<ModalWrapper cancel={() => hideModal(id)} key={id}>
<Modal.Comp {...Modal.props} /> //κ°μ Έμ¨ Modalλ°°μ΄μ λ λλ§ μ΄λ κ² ν¨μΌλ‘μ¨ λͺ¨λ¬ μ¬λ¬κ°λ₯Ό νλ²μ λμΈ μ μκ²λλ€.
</ModalWrapper>
))}
</>
);
}
μ΄μ μ΄λ κ² μ¬μ©ν΄μ£Όλ©΄ λλ€.
export default function ControllSection({ mediaObject }: { mediaObject: MediaObject }) {
const { stream } = mediaObject;
const { show } = useModal(SettingModal); //SettingModalμ Propsλ showλ₯Ό ν΅ν΄ λ겨μ€λ€.
return (
...
<button ... onClick={() => show({ mediaObject })}> //showμμ propsλ₯Ό λ°μμ€λ€.
...
</button>
</div>
);
}
μ΄λ κ² νλ λͺ¨λ¬μ΄ μκΈ°μμ μ μ°Ύμ μ μλβ¦λ¬Έμ κ° μκ²Όλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ hideν¨μλ₯Ό λ°μ쀬λ€.
export default function ControllSection({ mediaObject }: { mediaObject: MediaObject }) {
const { stream } = mediaObject;
const { show, hide } = useModal(SettingModal);
return (
...
<button
type="button"
className="w-[3vw] p-[1vw] hover:opacity-50 rounded-[15px] border-white"
onClick={() => show({ mediaObject, hide })} //μ¬κΈ°μ λ°μμ£Όμλ€.
>
...
λͺ¨λ¬μ μ΄κ³ λ«μ λ μ λλ©μ΄μ μ μ£Όκ³ μΆμλ€.
μ΄λ»κ² μ€κΉ νλ€κ° μ΄λ°μμΌλ‘ ν΄κ²°νλ€.
const ANIMATION_RENDER = 'relative p-4 bg-white rounded-2xl animate-render';
const ANIMATION_REMOVE = 'relative p-4 bg-white rounded-2xl animate-remove';
export default function Modal({ ... }: {
Component: React.ComponentType<any>;
modalProps?: Record<string, unknown>;
hide: () => void;
}) {
const [className, setClassName] = useState(ANIMATION_RENDER);
//μ λλ©μ΄μ
μ classμ΄λ¦μ λ³κ²½νλ ννλ‘ κ΅¬ν
...
const handleCancel = () => setClassName(ANIMATION_REMOVE);
//μ λλ©μ΄μ
μ μΌμΌν΄
const handleAnimationEnd = () => className === ANIMATION_REMOVE && hide();
//μ λλ©μ΄μ
μ΄ λλλ©΄ λͺ¨λ¬ μν λ³κ²½
const handleKeyDown = (e: React.KeyboardEvent) => e.key === 'Escape' && handleCancel(); //ESCλ₯Ό λλ₯΄λ©΄ λͺ¨λ¬ λ«κΈ°
return (
<div className="..." onClick={handleCancel}>
<div
...
className={className}
onAnimationEnd={handleAnimationEnd}
onKeyDown={handleKeyDown}
>
...
<div className="py-8 reative">
<Component {...{ ...modalProps, hide: handleCancel }} />
//handleCancelμ hideν¨μλ‘ μ£Όμ
νλ€.
</div>
...
</div>
);
}
μ΄λ κ² μ£Όμ λ hideν¨μλ Modalλ‘ μ°μΌ μ»΄ν¬λνΈμ hideλ‘ μ£Όμ λμ΄, ν΄λΉ μ»΄ν¬λνΈμμ hideν¨μλ₯Ό νΈμΆνλ©΄ μ λλ©μ΄μ μ νΈλ¦¬κ±°νκ³ , μ΄λ₯Ό ν΅ν΄ λͺ¨λ¬μ μνκ° λ³κ²½λλ€.
π ν
π λ
Έμ
보λ¬κ°κΈ°
π μ£Όμ κΈ°λ₯
π» λ©€λ²
π» κ·ΈλΌμ΄λ λ£°
π» 컨벀μ
π» κΈ°μ μ 리
π» μ ν λ°±λ‘κ·Έ 보λ¬κ°κΈ°
π week1
π week2
π week3
π week4
π week5
π week6
ποΈ week1
ποΈ week2
ποΈ week3
ποΈ week4
ποΈ week5
ποΈ week6