76 lines
1.9 KiB
JavaScript
76 lines
1.9 KiB
JavaScript
import React, { useEffect, useRef } from "react";
|
|
|
|
const OffcanvasComponent = ({
|
|
id = "globalOffcanvas",
|
|
title = "Offcanvas Title",
|
|
placement = "start", // start | end | top | bottom
|
|
children,
|
|
show = false,
|
|
onClose = () => { },
|
|
}) => {
|
|
const offcanvasRef = useRef(null);
|
|
const bsInstance = useRef(null);
|
|
|
|
useEffect(() => {
|
|
if (!offcanvasRef.current) return;
|
|
|
|
// initialize once
|
|
bsInstance.current = bootstrap.Offcanvas.getOrCreateInstance(offcanvasRef.current);
|
|
|
|
const el = offcanvasRef.current;
|
|
const handleHide = () => onClose();
|
|
|
|
el.addEventListener("hidden.bs.offcanvas", handleHide);
|
|
|
|
return () => {
|
|
el.removeEventListener("hidden.bs.offcanvas", handleHide);
|
|
};
|
|
}, [onClose]);
|
|
|
|
// react to `show` changes
|
|
useEffect(() => {
|
|
if (!bsInstance.current) return;
|
|
|
|
if (show) bsInstance.current.show();
|
|
else bsInstance.current.hide();
|
|
}, [show]);
|
|
|
|
return (
|
|
<div >
|
|
<div
|
|
ref={offcanvasRef}
|
|
id={id}
|
|
className={`offcanvas offcanvas offcanvas-${placement} offcanvas-wide`}
|
|
tabIndex="-1"
|
|
aria-labelledby={`${id}-label`}
|
|
>
|
|
<div className="offcanvas-header">
|
|
<div className="d-flex align-items-center gap-3">
|
|
<i
|
|
className="bx bx-lg bx-left-arrow-alt cursor-pointer"
|
|
data-bs-dismiss="offcanvas"
|
|
aria-label="Close"
|
|
></i>
|
|
<i className="bx bx-briefcase text-primary"></i>
|
|
<h5 className="offcanvas-title mb-0" id={`${id}-label`}>
|
|
{title}
|
|
</h5>
|
|
</div>
|
|
|
|
|
|
<button
|
|
type="button"
|
|
className="btn-close"
|
|
data-bs-dismiss="offcanvas"
|
|
aria-label="Close"
|
|
></button>
|
|
</div>
|
|
|
|
<div className="offcanvas-body ">{children}</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default OffcanvasComponent;
|