New Componet Panel Added

This commit is contained in:
2025-10-01 13:23:33 +05:30
parent eb1473d4b1
commit 1d571516c8
5 changed files with 175 additions and 0 deletions
+131
View File
@@ -0,0 +1,131 @@
---
import type { HTMLAttributes } from "astro/types";
interface Props extends HTMLAttributes<"div"> {
id: string;
wrapperId: string;
isOpen?: boolean;
width?: number;
position?: "left" | "right";
class?: string;
}
const {
id,
wrapperId,
isOpen = false,
width = 360,
position = "right",
class: className,
}: Props = Astro.props;
---
<div
id={`panel-${id}`}
data-panel
data-open="false"
class={`panel ${position} ${className ?? ""}`}
>
<slot />
</div>
<style>
[data-panel] {
position: absolute;
top: 0;
bottom: 0;
width: 0;
height: 100%;
display: none;
box-sizing: border-box;
overflow: hidden;
transition:
width 300ms ease,
transform 300ms ease,
opacity 300ms ease;
opacity: 0;
z-index: 50;
}
[data-panel].left {
left: 0;
transform: translateX(-100%);
}
[data-panel].right {
right: 0;
transform: translateX(100%);
}
[data-panel][data-open="true"] {
opacity: 1;
transform: translateX(0);
}
</style>
<script
type="module"
is:inline
define:vars={{ id, isOpen, wrapperId, width, position }}
>
const panel = document.getElementById(`panel-${id}`);
const closePanelBtn = document.getElementById(`close-panel-${id}`);
const panelWrapper = document.getElementById(wrapperId);
function openPanel() {
if (!panel || panel.dataset.open === "true") return;
panel.dataset.open = "true";
panel.style.display = "block";
requestAnimationFrame(() => {
panel.style.width = `${width}px`;
if (position === "left") {
panelWrapper.style.transition = "padding-left 300ms ease";
panelWrapper.style.paddingLeft = `${width}px`;
} else {
panelWrapper.style.transition = "padding-right 300ms ease";
panelWrapper.style.paddingRight = `${width}px`;
}
});
}
function closePanel() {
if (!panel || panel.dataset.open === "false") return;
panel.dataset.open = "false";
panel.style.width = "0";
panel.style.display = "none";
if (position === "left") {
panelWrapper.style.paddingLeft = "0px";
} else {
panelWrapper.style.paddingRight = "0px";
}
panel.addEventListener(
"transitionend",
(e) => {
if (
e.propertyName === "width" &&
panel.dataset.open === "false"
) {
panel.style.display = "none";
}
},
{ once: true },
);
}
// Auto-open if isOpen is passed
if (isOpen) {
openPanel();
}
// Global triggers
window.addEventListener(`open-panel-${id}`, openPanel);
window.addEventListener(`close-panel-${id}`, closePanel);
closePanelBtn?.addEventListener("click", closePanel);
</script>