<script lang="ts" setup>
import { computed } from 'vue'

interface LayoutProrps {
	gap?: number
	h100?: boolean
	columns?: string[]
	mColumns?: string[]
	mRows?: string[]
	rows?: string[]
	mGap?: number
}

const props = withDefaults(defineProps<LayoutProrps>(), {
	gap: 0.5,
	h100: false,
	columns: () => ([]),
	rows: () => ([]),
	mColumns: () => ([]),
	mRows: () => ([]),
	mGap: undefined,

})

// Bare `fr` tracks won't shrink below their content's intrinsic size, which
// causes overflow when a child (table, long text, nested grid) is wider than its
// share. Wrapping in `minmax(0, …)` makes the track shrinkable — the behaviour
// you almost always want. Authors can opt out by passing an explicit minmax().
function normalizeTrack(track: string): string {
	const t = track.trim()
	if (/^\d*\.?\d+fr$/.test(t)) { return `minmax(0, ${t})` }
	return t
}
function buildTemplate(tracks: string[]): string {
	return tracks.length > 0 ? tracks.map(normalizeTrack).join(' ') : 'auto'
}

const gridTemplateRows = computed(() => buildTemplate(props.rows))
const gapSize = computed(() => `${props.gap}rem`)
const mGapSize = computed(() => props.mGap !== undefined ? `${props.mGap}rem` : gapSize.value)

const mGridTemplateRows = computed(() => {
	if (props.mRows?.length) { return buildTemplate(props.mRows) }
	return gridTemplateRows.value
})

const gridTemplateColumns = computed(() => buildTemplate(props.columns))

const mGridTemplateColumns = computed(() => {
	if (props.mColumns?.length) { return buildTemplate(props.mColumns) }
	return gridTemplateColumns.value
})
</script>

<template>
	<div class="layout" :class="{ 'layout-h-100': h100 }">
		<slot />
	</div>
</template>

<style scoped>
.layout {
  min-height: 100px;
  display: grid;
  gap: v-bind(gapSize);
  grid-template-rows: v-bind(gridTemplateRows);
  grid-template-columns: v-bind(gridTemplateColumns);
}

@media screen and (max-width: 910px) {
  .layout {
	gap: v-bind(mGapSize);
    grid-template-rows: v-bind(mGridTemplateRows);
    grid-template-columns: v-bind(mGridTemplateColumns);
  }
}
</style>
