monacousa-portal/components/dashboard/BentoGrid.vue

164 lines
2.5 KiB
Vue

<template>
<div class="bento-grid" :class="gridClass">
<slot></slot>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue';
interface Props {
columns?: number;
gap?: 'sm' | 'md' | 'lg' | 'xl';
responsive?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
columns: 12,
gap: 'md',
responsive: true
});
const gridClass = computed(() => {
return {
[`bento-grid--cols-${props.columns}`]: true,
[`bento-grid--gap-${props.gap}`]: true,
'bento-grid--responsive': props.responsive
};
});
</script>
<style scoped lang="scss">
.bento-grid {
display: grid;
width: 100%;
// Column configurations
&--cols-12 {
grid-template-columns: repeat(12, 1fr);
}
&--cols-6 {
grid-template-columns: repeat(6, 1fr);
}
&--cols-4 {
grid-template-columns: repeat(4, 1fr);
}
&--cols-3 {
grid-template-columns: repeat(3, 1fr);
}
// Gap sizes
&--gap-sm {
gap: 0.75rem;
}
&--gap-md {
gap: 1.25rem;
}
&--gap-lg {
gap: 1.75rem;
}
&--gap-xl {
gap: 2.25rem;
}
// Responsive behavior
&--responsive {
@media (max-width: 640px) {
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 641px) and (max-width: 768px) {
grid-template-columns: repeat(6, 1fr);
}
@media (min-width: 769px) and (max-width: 1024px) {
grid-template-columns: repeat(8, 1fr);
}
}
}
// Global Bento Item Classes
:deep(.bento-item) {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
// Size variants
&--small {
grid-column: span 3;
}
&--medium {
grid-column: span 4;
}
&--large {
grid-column: span 6;
}
&--xlarge {
grid-column: span 8;
}
&--full {
grid-column: span 12;
}
// Height variants
&--tall {
grid-row: span 2;
}
&--xtall {
grid-row: span 3;
}
// Responsive overrides
@media (max-width: 640px) {
&--small,
&--medium,
&--large,
&--xlarge {
grid-column: span 12;
}
}
@media (min-width: 641px) and (max-width: 768px) {
&--small {
grid-column: span 3;
}
&--medium,
&--large {
grid-column: span 6;
}
&--xlarge {
grid-column: span 6;
}
}
@media (min-width: 769px) and (max-width: 1024px) {
&--small {
grid-column: span 3;
}
&--medium {
grid-column: span 4;
}
&--large {
grid-column: span 6;
}
&--xlarge {
grid-column: span 8;
}
}
}
</style>