164 lines
2.5 KiB
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> |