New Componet Panel Added
This commit is contained in:
@@ -21,6 +21,7 @@ export { default as Link } from "../src/components/Link.astro";
|
|||||||
export { default as Modal } from "../src/components/Modal.astro";
|
export { default as Modal } from "../src/components/Modal.astro";
|
||||||
export { default as MultiSelect } from "../src/components/MultiSelect.astro";
|
export { default as MultiSelect } from "../src/components/MultiSelect.astro";
|
||||||
export { default as OtpField } from "../src/components/OtpField.astro";
|
export { default as OtpField } from "../src/components/OtpField.astro";
|
||||||
|
export { default as Panel } from "../src/components/Panel.astro";
|
||||||
export { default as PasswordField } from "../src/components/PasswordField.astro";
|
export { default as PasswordField } from "../src/components/PasswordField.astro";
|
||||||
export { default as ThemeSwitcher } from "../src/components/ThemeSwitcher.astro";
|
export { default as ThemeSwitcher } from "../src/components/ThemeSwitcher.astro";
|
||||||
export { default as TimePicker } from "../src/components/TimePicker.astro";
|
export { default as TimePicker } from "../src/components/TimePicker.astro";
|
||||||
@@ -45,6 +46,7 @@ export const Link: any;
|
|||||||
export const Modal: any;
|
export const Modal: any;
|
||||||
export const MultiSelect: any;
|
export const MultiSelect: any;
|
||||||
export const OtpField: any;
|
export const OtpField: any;
|
||||||
|
export const Panel: any;
|
||||||
export const PasswordField: any;
|
export const PasswordField: any;
|
||||||
export const ThemeSwitcher: any;
|
export const ThemeSwitcher: any;
|
||||||
export const TimePicker: any;
|
export const TimePicker: any;
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -13,6 +13,7 @@ export { default as Link } from "./components/Link.astro";
|
|||||||
export { default as Modal } from "./components/Modal.astro";
|
export { default as Modal } from "./components/Modal.astro";
|
||||||
export { default as MultiSelect } from "./components/MultiSelect.astro";
|
export { default as MultiSelect } from "./components/MultiSelect.astro";
|
||||||
export { default as OtpField } from "./components/OtpField.astro";
|
export { default as OtpField } from "./components/OtpField.astro";
|
||||||
|
export { default as Panel } from "./components/Panel.astro";
|
||||||
export { default as PasswordField } from "./components/PasswordField.astro";
|
export { default as PasswordField } from "./components/PasswordField.astro";
|
||||||
export { default as ThemeSwitcher } from "./components/ThemeSwitcher.astro";
|
export { default as ThemeSwitcher } from "./components/ThemeSwitcher.astro";
|
||||||
export { default as TimePicker } from "./components/TimePicker.astro";
|
export { default as TimePicker } from "./components/TimePicker.astro";
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ import Base from "./Base.astro";
|
|||||||
<li class="list-item">
|
<li class="list-item">
|
||||||
<a href="/dashboard">Dashboard</a>
|
<a href="/dashboard">Dashboard</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="list-item">
|
||||||
|
<a href="/panel">Panel</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
import ComponentLayout from "../layouts/ComponentLayout.astro";
|
||||||
|
import Panel from "../components/Panel.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
<ComponentLayout class="wr:p-4">
|
||||||
|
<div class="wr:h-full wr:w-full wr:relative wr:bg-yellow-200">
|
||||||
|
<div id="panel-wrapper">
|
||||||
|
<button id="openPanelBtn"> Open Panel </button>
|
||||||
|
|
||||||
|
<div class="wr:grid wr:grid-cols-2">
|
||||||
|
<h1>Data 1</h1>
|
||||||
|
<h1>Data 2</h1>
|
||||||
|
<h1>Data 3</h1>
|
||||||
|
<h1>Data 4</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Panel
|
||||||
|
wrapperId="panel-wrapper"
|
||||||
|
id="settings"
|
||||||
|
isOpen={true}
|
||||||
|
width={400}
|
||||||
|
position="left"
|
||||||
|
class="wr:bg-neutral-700 wr:p-4"
|
||||||
|
>
|
||||||
|
<button id=`close-panel-settings`> Close </button>
|
||||||
|
<h2>Settings Panel</h2>
|
||||||
|
<p>This is a settings panel with a width of 400px.</p>
|
||||||
|
</Panel>
|
||||||
|
</div>
|
||||||
|
</ComponentLayout>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const openPanelBtn = document.getElementById("openPanelBtn");
|
||||||
|
openPanelBtn?.addEventListener("click", () => {
|
||||||
|
window.dispatchEvent(new Event("open-panel-settings"));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user