File size: 4,193 Bytes
e903a32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
---
interface Props {
    /** Layout mode: number of columns or 'auto' for responsive */
    layout?: "2-column" | "3-column" | "4-column" | "auto";
    /** Gap between items - can be a predefined size or custom value (e.g., "2rem", "20px", "1.5em") */
    gap?: "small" | "medium" | "large" | string;
    /** Optional class to apply on the wrapper */
    class?: string;
    /** Optional ID for the stack */
    id?: string;
}

const {
    layout = "2-column",
    gap = "medium",
    class: className,
    id,
} = Astro.props as Props;

// Generate flex properties based on layout
const getFlexProperties = () => {
    switch (layout) {
        case "2-column":
            return { flexBasis: "50%", maxWidth: "50%" };
        case "3-column":
            return { flexBasis: "33.333%", maxWidth: "33.333%" };
        case "4-column":
            return { flexBasis: "25%", maxWidth: "25%" };
        case "auto":
            return { flexBasis: "auto", maxWidth: "none" };
        default:
            // By default, all children on one line with equal width
            return { flexBasis: "auto", maxWidth: "none" };
    }
};

const getGapSize = () => {
    // If it's a predefined size, return the corresponding value
    switch (gap) {
        case "small":
            return "0.5rem";
        case "medium":
            return "1rem";
        case "large":
            return "1.5rem";
        default:
            // If it's a custom value, return it as-is (e.g., "2rem", "20px", "1.5em")
            return gap;
    }
};

const flexProps = getFlexProperties();
const gapSize = getGapSize();
---

<div
    class={`stack ${className || ""}`}
    data-layout={layout}
    data-gap={gap}
    {id}
    style={`gap: ${gapSize}`}
>
    <slot />
</div>

<style>
    .stack {
        display: grid;
        gap: 1rem;
        margin: var(--block-spacing-y) 0;
        width: 100%;
        max-width: 100%;
        box-sizing: border-box;
    }

    /* Layout configurations */
    .stack[data-layout="2-column"] {
        grid-template-columns: repeat(2, 1fr);
    }

    .stack[data-layout="3-column"] {
        grid-template-columns: repeat(3, 1fr);
    }

    .stack[data-layout="4-column"] {
        grid-template-columns: repeat(4, 1fr);
    }

    .stack[data-layout="auto"] {
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    }

    /* Default layout (2-column) */
    .stack:not([data-layout]) {
        grid-template-columns: repeat(2, 1fr);
    }

    /* Ensure child elements don't overflow */
    .stack :global(> *) {
        min-width: 0 !important;
        max-width: 100% !important;
        box-sizing: border-box !important;
        word-wrap: break-word !important;
        overflow-wrap: break-word !important;
        overflow: hidden !important;
    }

    /* Handle code blocks inside stack */
    .stack pre {
        overflow-x: auto;
        max-width: 100%;
        width: 100%;
        word-wrap: break-word;
        white-space: pre-wrap;
        box-sizing: border-box;
        min-width: 0 !important;
    }

    .stack code {
        word-wrap: break-word;
        white-space: pre-wrap;
        max-width: 100%;
        box-sizing: border-box;
        min-width: 0 !important;
    }

    /* Override the min-width: 100% from _code.css */
    .stack pre code {
        min-width: 0 !important;
    }

    /* Override section.content-grid pre code min-width rule */
    .stack section.content-grid pre code {
        min-width: 0 !important;
    }

    /* Responsive behavior */
    @media (max-width: 768px) {
        .stack[data-layout="3-column"],
        .stack[data-layout="4-column"],
        .stack[data-layout="2-column"],
        .stack:not([data-layout]) {
            grid-template-columns: 1fr !important;
        }
    }

    @media (min-width: 769px) and (max-width: 1100px) {
        .stack[data-layout="3-column"],
        .stack[data-layout="4-column"] {
            grid-template-columns: repeat(2, 1fr) !important;
        }
    }

    @media (min-width: 1101px) and (max-width: 1400px) {
        .stack[data-layout="4-column"] {
            grid-template-columns: repeat(2, 1fr) !important;
        }
    }
</style>