@hoangyell/gallery 1.0.3 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -1
- package/package.json +2 -2
- package/src/Gallery.astro +45 -0
package/README.md
CHANGED
|
@@ -2,9 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
[Astro](https://astro.build/) image gallery component with lightbox, pyramid multi-row layout, and accessible controls.
|
|
4
4
|
|
|
5
|
+
**Live demo → [gallery.hoangyell.com](https://gallery.hoangyell.com)**
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://gallery.hoangyell.com">
|
|
9
|
+
<img
|
|
10
|
+
src="https://raw.githubusercontent.com/HoangYell/hoangyell-gallery/main/packages/astro/docs/site-hero.jpg"
|
|
11
|
+
alt="@hoangyell/gallery landing page hero — The friendly Astro image gallery"
|
|
12
|
+
width="720"
|
|
13
|
+
/>
|
|
14
|
+
</a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<p align="center">
|
|
18
|
+
<em>Click any image to open the lightbox — keyboard arrows, swipe, ESC to close.</em>
|
|
19
|
+
<br />
|
|
20
|
+
<img
|
|
21
|
+
src="https://raw.githubusercontent.com/HoangYell/hoangyell-gallery/main/packages/astro/docs/gallery-lightbox.jpg"
|
|
22
|
+
alt="Lightbox view with page indicator, close button, and next-image arrow"
|
|
23
|
+
width="640"
|
|
24
|
+
/>
|
|
25
|
+
</p>
|
|
26
|
+
|
|
5
27
|
## Features
|
|
6
28
|
|
|
7
29
|
- **Pyramid layout** — distribute images across rows with `rows` prop
|
|
30
|
+
- **Two fit modes** — `cover` (default, uniform photo grid) or `contain` (natural aspect, for diagrams and tall portraits)
|
|
8
31
|
- **Lightbox** — click to open, keyboard arrows, swipe, ESC to close
|
|
9
32
|
- **Corner rounding** — only the four outer corners of each group are rounded
|
|
10
33
|
- **Hover zoom** — image scales inside its cell without changing layout
|
|
@@ -57,9 +80,46 @@ import { Gallery } from "@hoangyell/gallery";
|
|
|
57
80
|
| `rows` | `number` | auto (~3 per row) | Number of visual rows |
|
|
58
81
|
| `orientation` | `"landscape" \| "portrait"` | `"landscape"` | Item aspect ratio hint |
|
|
59
82
|
| `scale` | `number` | `1` | Gallery width scale (0–1) |
|
|
60
|
-
| `fit` | `ObjectFit` | `"cover"` | Default CSS object-fit |
|
|
83
|
+
| `fit` | `ObjectFit` | `"cover"` | Default CSS object-fit — see Fit modes below |
|
|
61
84
|
| `class` | `string` | — | Extra wrapper class |
|
|
62
85
|
|
|
86
|
+
## Fit modes
|
|
87
|
+
|
|
88
|
+
The `fit` prop controls **both** the image's `object-fit` **and** the
|
|
89
|
+
container's aspect ratio. Pick the right one for your content:
|
|
90
|
+
|
|
91
|
+
| Mode | What you get | When to use |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| `"cover"` (default) | Uniform 4:3 grid (1:1 on mobile). Images are cropped to fill. | Photo galleries — travel, products, faces. The Pinterest aesthetic. |
|
|
94
|
+
| `"contain"` | Container hugs each image's natural aspect ratio. No cropping. | Diagrams, charts, screenshots, comics, tall portraits. |
|
|
95
|
+
|
|
96
|
+
Set it at the gallery level:
|
|
97
|
+
|
|
98
|
+
```mdx
|
|
99
|
+
<Gallery items={["/diagram.png"]} rows={1} fit="contain" />
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Or per-item (mix and match in the same gallery):
|
|
103
|
+
|
|
104
|
+
```mdx
|
|
105
|
+
<Gallery
|
|
106
|
+
items={[
|
|
107
|
+
"/cover-photo.jpg",
|
|
108
|
+
{ src: "/architecture-diagram.png", fit: "contain" },
|
|
109
|
+
]}
|
|
110
|
+
/>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Dark mode
|
|
114
|
+
|
|
115
|
+
The component auto-themes via three mechanisms (last one wins):
|
|
116
|
+
|
|
117
|
+
1. `prefers-color-scheme: dark` — OS preference (default).
|
|
118
|
+
2. `<html class="dark">` or `<html data-theme="dark">` — Tailwind-style class toggle.
|
|
119
|
+
3. `<html class="light">` or `<html data-theme="light">` — explicit light theme override.
|
|
120
|
+
|
|
121
|
+
This means it Just Works™ with manual theme toggles **and** OS preference.
|
|
122
|
+
|
|
63
123
|
## Customization
|
|
64
124
|
|
|
65
125
|
Override CSS custom properties on `.hy-gallery`:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hoangyell/gallery",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Astro image gallery with lightbox, pyramid multi-row layout, and accessible controls.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"photo-gallery"
|
|
24
24
|
],
|
|
25
25
|
"author": "Hoang Yell <hoangyell@gmail.com> (https://hoangyell.com)",
|
|
26
|
-
"homepage": "https://
|
|
26
|
+
"homepage": "https://gallery.hoangyell.com",
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|
|
29
29
|
"url": "https://github.com/HoangYell/hoangyell-gallery.git",
|
package/src/Gallery.astro
CHANGED
|
@@ -100,6 +100,7 @@ if (resolvedRows <= 1 || galleryItems.length <= 1) {
|
|
|
100
100
|
class={`hy-gallery ${className}`}
|
|
101
101
|
data-hy-gallery
|
|
102
102
|
data-orientation={orientation}
|
|
103
|
+
data-fit={fit}
|
|
103
104
|
style={scale !== 1 ? `width: ${scale * 100}%; margin: 2rem auto;` : undefined}
|
|
104
105
|
>
|
|
105
106
|
{groupedItems.map((group, rowIdx) => {
|
|
@@ -124,6 +125,7 @@ if (resolvedRows <= 1 || galleryItems.length <= 1) {
|
|
|
124
125
|
class={`hy-gallery-item ${cornerClasses}`}
|
|
125
126
|
data-zoom-src={item.src}
|
|
126
127
|
data-alt={item.alt}
|
|
128
|
+
data-fit={item.fit}
|
|
127
129
|
aria-label={
|
|
128
130
|
item.alt ? `View full size: ${item.alt}` : "View full size image"
|
|
129
131
|
}
|
|
@@ -159,6 +161,7 @@ if (resolvedRows <= 1 || galleryItems.length <= 1) {
|
|
|
159
161
|
--hy-gallery-control-bg: rgba(255, 255, 255, 0.95);
|
|
160
162
|
}
|
|
161
163
|
|
|
164
|
+
/* OS-level dark preference. */
|
|
162
165
|
@media (prefers-color-scheme: dark) {
|
|
163
166
|
.hy-gallery {
|
|
164
167
|
--hy-gallery-bg: #0f172a;
|
|
@@ -170,6 +173,28 @@ if (resolvedRows <= 1 || galleryItems.length <= 1) {
|
|
|
170
173
|
}
|
|
171
174
|
}
|
|
172
175
|
|
|
176
|
+
/* Explicit light theme on any ancestor wins over OS preference.
|
|
177
|
+
Supports Tailwind-style `.light` class and `[data-theme="light"]`. */
|
|
178
|
+
:where(.light, [data-theme="light"]) .hy-gallery {
|
|
179
|
+
--hy-gallery-bg: #f8fafc;
|
|
180
|
+
--hy-gallery-overlay-bg: rgba(255, 255, 255, 0.7);
|
|
181
|
+
--hy-gallery-accent: #2563eb;
|
|
182
|
+
--hy-gallery-border: #e2e8f0;
|
|
183
|
+
--hy-gallery-text: #334155;
|
|
184
|
+
--hy-gallery-control-bg: rgba(255, 255, 255, 0.95);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Explicit dark theme on any ancestor wins over OS preference.
|
|
188
|
+
Supports Tailwind-style `.dark` class and `[data-theme="dark"]`. */
|
|
189
|
+
:where(.dark, [data-theme="dark"]) .hy-gallery {
|
|
190
|
+
--hy-gallery-bg: #0f172a;
|
|
191
|
+
--hy-gallery-overlay-bg: rgba(2, 6, 23, 0.8);
|
|
192
|
+
--hy-gallery-accent: #60a5fa;
|
|
193
|
+
--hy-gallery-border: #334155;
|
|
194
|
+
--hy-gallery-text: #e2e8f0;
|
|
195
|
+
--hy-gallery-control-bg: rgba(30, 41, 59, 0.95);
|
|
196
|
+
}
|
|
197
|
+
|
|
173
198
|
.hy-gallery {
|
|
174
199
|
display: flex;
|
|
175
200
|
flex-direction: column;
|
|
@@ -240,6 +265,16 @@ if (resolvedRows <= 1 || galleryItems.length <= 1) {
|
|
|
240
265
|
}
|
|
241
266
|
}
|
|
242
267
|
|
|
268
|
+
/* fit="contain" — show the whole image at its natural aspect ratio.
|
|
269
|
+
Drops the forced 4:3 / 1:1 container so diagrams, charts, screenshots,
|
|
270
|
+
and tall portraits render fully without cropping or letterboxing.
|
|
271
|
+
Applied either at the wrapper (global) or per-item via data-fit. */
|
|
272
|
+
.hy-gallery[data-fit="contain"] .hy-gallery-item,
|
|
273
|
+
.hy-gallery .hy-gallery-item[data-fit="contain"] {
|
|
274
|
+
aspect-ratio: auto;
|
|
275
|
+
background: transparent;
|
|
276
|
+
}
|
|
277
|
+
|
|
243
278
|
.hy-gallery-img {
|
|
244
279
|
position: absolute;
|
|
245
280
|
inset: 0;
|
|
@@ -256,6 +291,16 @@ if (resolvedRows <= 1 || galleryItems.length <= 1) {
|
|
|
256
291
|
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
257
292
|
}
|
|
258
293
|
|
|
294
|
+
/* In contain mode the image is the primary content — let it drive height
|
|
295
|
+
instead of being absolutely positioned inside a fixed-aspect box. */
|
|
296
|
+
.hy-gallery[data-fit="contain"] .hy-gallery-img,
|
|
297
|
+
.hy-gallery .hy-gallery-item[data-fit="contain"] .hy-gallery-img {
|
|
298
|
+
position: static;
|
|
299
|
+
width: 100%;
|
|
300
|
+
height: auto;
|
|
301
|
+
inset: auto;
|
|
302
|
+
}
|
|
303
|
+
|
|
259
304
|
.hy-gallery-item:hover .hy-gallery-img,
|
|
260
305
|
.hy-gallery-item:focus-visible .hy-gallery-img {
|
|
261
306
|
will-change: transform;
|