zhuguifei
2025-06-17 c1cc49dd93d38f51790558541d6835d1598ecccf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<script setup lang="ts">
import { useId } from "@/composables/useId";
 
defineOptions({
  name: "GridPattern"
});
 
interface GridPatternProps {
  width?: number;
  height?: number;
  x?: number;
  y?: number;
  squares?: Array<[x: number, y: number]> | null;
  strokeDasharray?: string;
}
const props = withDefaults(defineProps<GridPatternProps>(), {
  width: 40,
  height: 40,
  x: -1,
  y: -1,
  squares: null,
  strokeDasharray: "0"
});
 
const id = `pattern-${useId()}`;
</script>
 
<template>
  <svg
    aria-hidden="true"
    class="pointer-events-none absolute inset-0 h-full w-full fill-gray-400/30 stroke-gray-400/30"
    v-bind="$attrs"
  >
    <defs>
      <pattern
        :id="id"
        :width="props.width"
        :height="props.height"
        patternUnits="userSpaceOnUse"
        :x="props.x"
        :y="props.y"
      >
        <path
          :d="`M.5 ${props.height}V.5H${props.width}`"
          fill="none"
          :stroke-dasharray="props.strokeDasharray"
        />
      </pattern>
    </defs>
    <rect width="100%" height="100%" :stroke-width="0" :fill="`url(#${id})`" />
    <svg
      v-if="props.squares"
      :x="props.x"
      :y="props.y"
      class="overflow-visible"
    >
      <rect
        v-for="[squareX, squareY] in props.squares"
        :key="`${squareX}-${squareY}`"
        :stroke-width="0"
        :width="props.width - 1"
        :height="props.height - 1"
        :x="squareX * props.width + 1"
        :y="squareY * props.height + 1"
      />
    </svg>
  </svg>
</template>