import { computed, type Ref, type ComputedRef } from 'vue' import { useElementSize } from '@vueuse/core' /** * ============================================================ * useResponsiveCols - 容器宽度驱动的列数 * ============================================================ * * 用 `@vueuse/core` 的 `useElementSize` 观察容器宽度, * 按 `minItemWidth` 算出能塞下几列。 * * 适用:嵌在窄/可变宽容器里的网格 —— dashboard 卡片、对话框等 * 「视口断点表达不了」的场景。 * * 典型用法(配合 AutoSizer): * * * * * 或直接传一个外层容器 ref: * const wrapperRef = ref(null) * const cols = useResponsiveCols(wrapperRef, { minItemWidth: 240 }) */ export function useResponsiveCols( containerRef: Ref, opts: { /** 单项最小宽度(含 gap 估算更稳,但不强求) */ minItemWidth: number /** 最少列数(默认 1,避免 width=0 时返回 0) */ min?: number /** 最多列数(可选上限) */ max?: number }, ): ComputedRef { const { width } = useElementSize(containerRef) return computed(() => { const w = width.value const minCols = opts.min ?? 1 if (!w || opts.minItemWidth <= 0) return minCols const raw = Math.floor(w / opts.minItemWidth) let n = Math.max(minCols, raw) if (opts.max !== undefined) n = Math.min(opts.max, n) return n }) }