braindrops.nicwands.com/shared/ControlPanel.vue
2026-08-11 10:24:27 -04:00

125 lines
2.9 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="shared-control-panel" :class="{ 'is-open': open }">
<btn
class="toggle-btn"
@click="open = !open"
:aria-expanded="open"
aria-label="Toggle control panel"
>
<!-- <span class="toggle-btn-inner"> -->
<span class="toggle-icon">{{ open ? '×' : '⊞' }}</span>
<!-- <span class="toggle-label">{{ title }}</span> -->
<!-- </span> -->
</btn>
<div class="panel-body">
<div class="panel-inner">
<slot />
</div>
</div>
</div>
</template>
<script setup>
import Btn from './Btn.vue'
import { ref } from 'vue'
const props = defineProps({
title: {
type: String,
default: 'Controls',
},
defaultOpen: {
type: Boolean,
default: true,
},
})
const open = ref(props.defaultOpen)
</script>
<style lang="scss">
.shared-control-panel {
--t-duration: 400ms;
--t-ease: var(--ease-out-quart);
--panel-width: #{columns(4)};
position: fixed;
top: 0;
right: 0;
padding: var(--layout-margin) 0;
display: flex;
align-items: center;
gap: rs(8px);
height: 100dvh;
pointer-events: none;
.toggle-btn {
pointer-events: all;
position: absolute;
top: var(--layout-margin);
right: 0;
z-index: 5;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
cursor: pointer;
.toggle-btn-inner {
display: flex;
align-items: center;
gap: rs(8px);
}
.toggle-icon {
@include label;
}
.toggle-label {
white-space: nowrap;
@include label;
}
}
.panel-body {
pointer-events: all;
width: var(--panel-width);
height: 100%;
background: var(--theme-bg);
border: 1px solid var(--grey-400);
border-radius: rs(10px);
overflow: hidden;
transform: translateX(100%);
transition: transform var(--t-duration) var(--t-ease);
display: flex;
flex-direction: column;
padding-top: rs(50px);
}
.panel-inner {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding: rs(24px) rs(20px);
display: flex;
flex-direction: column;
align-items: flex-start;
gap: rs(20px);
scrollbar-width: thin;
scrollbar-color: var(--grey-400) transparent;
&::-webkit-scrollbar {
width: rs(4px);
}
&::-webkit-scrollbar-track {
background: transparent;
}
&::-webkit-scrollbar-thumb {
background: var(--grey-400);
border-radius: rs(2px);
}
}
&.is-open {
.panel-body {
transform: translateX(0);
}
}
}
</style>