@xsolla/xui-b2c-image-thumbnail 0.157.0-pr299.1779375789

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 ADDED
@@ -0,0 +1,279 @@
1
+ # ImageThumbnail
2
+
3
+ A cross-platform React component for displaying image thumbnails with overlays, tags at all four corners, and center content (like play buttons). Perfect for video thumbnails, screenshot galleries, and media previews.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @xsolla/xui-b2c-image-thumbnail
9
+ ```
10
+
11
+ ## Demo
12
+
13
+ ### Basic ImageThumbnail
14
+
15
+ ```tsx
16
+ import * as React from "react";
17
+ import { ImageThumbnail } from "@xsolla/xui-b2c-image-thumbnail";
18
+
19
+ export default function BasicThumbnail() {
20
+ return (
21
+ <ImageThumbnail
22
+ src="https://example.com/screenshot.jpg"
23
+ alt="Game screenshot"
24
+ ratio="16:9"
25
+ width={320}
26
+ />
27
+ );
28
+ }
29
+ ```
30
+
31
+ ### Video Thumbnail with Play Button
32
+
33
+ ```tsx
34
+ import * as React from "react";
35
+ import { ImageThumbnail } from "@xsolla/xui-b2c-image-thumbnail";
36
+
37
+ const PlayButton = () => (
38
+ <div
39
+ style={{
40
+ width: 48,
41
+ height: 48,
42
+ borderRadius: 24,
43
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
44
+ display: "flex",
45
+ alignItems: "center",
46
+ justifyContent: "center",
47
+ }}
48
+ >
49
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="white">
50
+ <path d="M8 5v14l11-7z" />
51
+ </svg>
52
+ </div>
53
+ );
54
+
55
+ export default function VideoThumbnail() {
56
+ return (
57
+ <ImageThumbnail
58
+ src="https://example.com/video-preview.jpg"
59
+ alt="Video preview"
60
+ ratio="16:9"
61
+ width={320}
62
+ overlay="fade"
63
+ centerContent={<PlayButton />}
64
+ />
65
+ );
66
+ }
67
+ ```
68
+
69
+ ### Thumbnail with Tags
70
+
71
+ ```tsx
72
+ import * as React from "react";
73
+ import { ImageThumbnail } from "@xsolla/xui-b2c-image-thumbnail";
74
+ import { Tag } from "@xsolla/xui-tag";
75
+ import { XsollaTicket } from "@xsolla/xui-icons-currency";
76
+
77
+ export default function ThumbnailWithTags() {
78
+ return (
79
+ <ImageThumbnail
80
+ src="https://example.com/screenshot.jpg"
81
+ alt="Screenshot with reward"
82
+ ratio="16:9"
83
+ width={320}
84
+ overlay="fade"
85
+ tagsBottomLeft={
86
+ <Tag size="sm" tone="secondary" icon={<XsollaTicket />}>
87
+ 5x
88
+ </Tag>
89
+ }
90
+ />
91
+ );
92
+ }
93
+ ```
94
+
95
+ ### All Corner Tags
96
+
97
+ ```tsx
98
+ import * as React from "react";
99
+ import { ImageThumbnail } from "@xsolla/xui-b2c-image-thumbnail";
100
+ import { Tag } from "@xsolla/xui-tag";
101
+ import { Badge } from "@xsolla/xui-badge";
102
+
103
+ export default function AllCornerTags() {
104
+ return (
105
+ <ImageThumbnail
106
+ src="https://example.com/screenshot.jpg"
107
+ alt="Screenshot with all tags"
108
+ ratio="16:9"
109
+ width={400}
110
+ overlay="fade"
111
+ tagsTopLeft={
112
+ <Tag size="sm" tone="brand">
113
+ NEW
114
+ </Tag>
115
+ }
116
+ tagsTopRight={
117
+ <Tag size="sm" tone="secondary">
118
+ 2:30
119
+ </Tag>
120
+ }
121
+ tagsBottomLeft={
122
+ <Tag size="sm" tone="secondary">
123
+ 5x Tickets
124
+ </Tag>
125
+ }
126
+ tagsBottomRight={
127
+ <Badge size="lg" tone="success">
128
+ HD
129
+ </Badge>
130
+ }
131
+ />
132
+ );
133
+ }
134
+ ```
135
+
136
+ ### Overlay Types
137
+
138
+ ```tsx
139
+ import * as React from "react";
140
+ import { ImageThumbnail } from "@xsolla/xui-b2c-image-thumbnail";
141
+
142
+ export default function OverlayTypes() {
143
+ return (
144
+ <div style={{ display: "flex", gap: 16 }}>
145
+ <div>
146
+ <p>No Overlay</p>
147
+ <ImageThumbnail
148
+ src="https://example.com/image.jpg"
149
+ ratio="16:9"
150
+ width={200}
151
+ overlay="none"
152
+ />
153
+ </div>
154
+ <div>
155
+ <p>Fade Overlay</p>
156
+ <ImageThumbnail
157
+ src="https://example.com/image.jpg"
158
+ ratio="16:9"
159
+ width={200}
160
+ overlay="fade"
161
+ />
162
+ </div>
163
+ <div>
164
+ <p>Dark Overlay</p>
165
+ <ImageThumbnail
166
+ src="https://example.com/image.jpg"
167
+ ratio="16:9"
168
+ width={200}
169
+ overlay="dark"
170
+ />
171
+ </div>
172
+ </div>
173
+ );
174
+ }
175
+ ```
176
+
177
+ ### Aspect Ratios
178
+
179
+ ```tsx
180
+ import * as React from "react";
181
+ import { ImageThumbnail } from "@xsolla/xui-b2c-image-thumbnail";
182
+
183
+ export default function AspectRatios() {
184
+ const ratios = ["1:1", "16:9", "4:3", "3:2", "9:16"] as const;
185
+
186
+ return (
187
+ <div style={{ display: "flex", gap: 16, flexWrap: "wrap" }}>
188
+ {ratios.map((ratio) => (
189
+ <div key={ratio}>
190
+ <p>{ratio}</p>
191
+ <ImageThumbnail
192
+ src="https://example.com/image.jpg"
193
+ ratio={ratio}
194
+ width={150}
195
+ overlay="fade"
196
+ />
197
+ </div>
198
+ ))}
199
+ </div>
200
+ );
201
+ }
202
+ ```
203
+
204
+ ## Anatomy
205
+
206
+ Import the component and use it directly:
207
+
208
+ ```jsx
209
+ import { ImageThumbnail } from "@xsolla/xui-b2c-image-thumbnail";
210
+
211
+ <ImageThumbnail
212
+ src="..." // Required: Image URL
213
+ alt="Description" // Alt text
214
+ ratio="16:9" // Aspect ratio
215
+ width={320} // Width
216
+ overlay="fade" // Overlay type
217
+ centerContent={<PlayBtn />} // Center content
218
+ tagsTopLeft={<Tag />} // Top-left tags
219
+ tagsTopRight={<Tag />} // Top-right tags
220
+ tagsBottomLeft={<Tag />} // Bottom-left tags
221
+ tagsBottomRight={<Tag />} // Bottom-right tags
222
+ onPress={() => {}} // Click handler
223
+ />;
224
+ ```
225
+
226
+ ## API Reference
227
+
228
+ ### ImageThumbnail
229
+
230
+ A media thumbnail component with tag support.
231
+
232
+ **ImageThumbnail Props:**
233
+
234
+ | Prop | Type | Default | Description |
235
+ | :-------------- | :----------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------ |
236
+ | `testID` | `string` | — | Test ID for testing frameworks. On web this renders as `data-testid`; on React Native it renders as `testID`. |
237
+ | src | `string` | required | Image source URL. |
238
+ | alt | `string` | `""` | Alt text for the image. |
239
+ | ratio | `"1:1" \| "16:9" \| "4:3" \| "3:2" \| "2:3" \| "9:16" \| "custom"` | `"16:9"` | Aspect ratio. |
240
+ | customRatio | `number` | - | Custom aspect ratio (when ratio is 'custom'). |
241
+ | width | `number \| string` | `"100%"` | Width of the thumbnail. |
242
+ | height | `number \| string` | - | Fixed height (overrides ratio). |
243
+ | borderRadius | `number` | `4` | Border radius in pixels. |
244
+ | overlay | `"none" \| "fade" \| "dark"` | `"fade"` | Overlay type. |
245
+ | centerContent | `ReactNode` | - | Content in the center (e.g., play button). |
246
+ | tagsTopLeft | `ReactNode` | - | Tags in top-left corner. |
247
+ | tagsTopRight | `ReactNode` | - | Tags in top-right corner. |
248
+ | tagsBottomLeft | `ReactNode` | - | Tags in bottom-left corner. |
249
+ | tagsBottomRight | `ReactNode` | - | Tags in bottom-right corner. |
250
+ | onPress | `() => void` | - | Click handler. |
251
+ | tagPadding | `number` | `8` | Padding for tag positions. |
252
+ | tagGap | `number` | `4` | Gap between stacked tags. |
253
+ | className | `string` | - | Custom className for the container. |
254
+
255
+ **Overlay Types:**
256
+
257
+ | Type | Description |
258
+ | :--- | :------------------------------------------- |
259
+ | none | No overlay |
260
+ | fade | Gradient fade from bottom (semi-transparent) |
261
+ | dark | Solid dark overlay |
262
+
263
+ **Aspect Ratio Values:**
264
+
265
+ | Ratio | Numeric Value | Common Use |
266
+ | :---- | :------------ | :---------------- |
267
+ | 1:1 | 1 | Square thumbnails |
268
+ | 16:9 | 1.78 | Video, widescreen |
269
+ | 4:3 | 1.33 | Standard photos |
270
+ | 3:2 | 1.5 | DSLR photos |
271
+ | 2:3 | 0.67 | Portrait |
272
+ | 9:16 | 0.56 | Vertical video |
273
+
274
+ ## Accessibility
275
+
276
+ - Uses semantic `img` element with alt text
277
+ - Interactive when `onPress` is provided
278
+ - Tags and center content can include accessible labels
279
+ - Supports keyboard navigation when interactive
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import { ThemeOverrideProps } from '@xsolla/xui-core';
3
+
4
+ type ImageThumbnailRatio = "1:1" | "16:9" | "4:3" | "3:2" | "2:3" | "9:16" | "custom";
5
+ type ImageThumbnailOverlay = "none" | "fade" | "dark";
6
+ interface ImageThumbnailProps extends ThemeOverrideProps {
7
+ /** Image source URL */
8
+ src: string;
9
+ /** Alt text for the image */
10
+ alt?: string;
11
+ /** Aspect ratio of the thumbnail */
12
+ ratio?: ImageThumbnailRatio;
13
+ /** Custom aspect ratio (only used when ratio is 'custom') */
14
+ customRatio?: number;
15
+ /** Width of the thumbnail */
16
+ width?: number | string;
17
+ /** Height of the thumbnail (overrides ratio if provided) */
18
+ height?: number | string;
19
+ /** Border radius */
20
+ borderRadius?: number;
21
+ /** Overlay type */
22
+ overlay?: ImageThumbnailOverlay;
23
+ /** Content displayed in the center (e.g., play button) */
24
+ centerContent?: React.ReactNode;
25
+ /** Content displayed in top-left corner */
26
+ tagsTopLeft?: React.ReactNode;
27
+ /** Content displayed in top-right corner */
28
+ tagsTopRight?: React.ReactNode;
29
+ /** Content displayed in bottom-left corner */
30
+ tagsBottomLeft?: React.ReactNode;
31
+ /** Content displayed in bottom-right corner */
32
+ tagsBottomRight?: React.ReactNode;
33
+ /** Click handler */
34
+ onPress?: () => void;
35
+ /** Custom className */
36
+ className?: string;
37
+ /** Padding for tag positions */
38
+ tagPadding?: number;
39
+ /** Gap between tags */
40
+ tagGap?: number;
41
+ /** Test ID for testing frameworks */
42
+ testID?: string;
43
+ }
44
+
45
+ declare const ImageThumbnail: React.FC<ImageThumbnailProps>;
46
+
47
+ export { ImageThumbnail, type ImageThumbnailOverlay, type ImageThumbnailProps, type ImageThumbnailRatio };
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import { ThemeOverrideProps } from '@xsolla/xui-core';
3
+
4
+ type ImageThumbnailRatio = "1:1" | "16:9" | "4:3" | "3:2" | "2:3" | "9:16" | "custom";
5
+ type ImageThumbnailOverlay = "none" | "fade" | "dark";
6
+ interface ImageThumbnailProps extends ThemeOverrideProps {
7
+ /** Image source URL */
8
+ src: string;
9
+ /** Alt text for the image */
10
+ alt?: string;
11
+ /** Aspect ratio of the thumbnail */
12
+ ratio?: ImageThumbnailRatio;
13
+ /** Custom aspect ratio (only used when ratio is 'custom') */
14
+ customRatio?: number;
15
+ /** Width of the thumbnail */
16
+ width?: number | string;
17
+ /** Height of the thumbnail (overrides ratio if provided) */
18
+ height?: number | string;
19
+ /** Border radius */
20
+ borderRadius?: number;
21
+ /** Overlay type */
22
+ overlay?: ImageThumbnailOverlay;
23
+ /** Content displayed in the center (e.g., play button) */
24
+ centerContent?: React.ReactNode;
25
+ /** Content displayed in top-left corner */
26
+ tagsTopLeft?: React.ReactNode;
27
+ /** Content displayed in top-right corner */
28
+ tagsTopRight?: React.ReactNode;
29
+ /** Content displayed in bottom-left corner */
30
+ tagsBottomLeft?: React.ReactNode;
31
+ /** Content displayed in bottom-right corner */
32
+ tagsBottomRight?: React.ReactNode;
33
+ /** Click handler */
34
+ onPress?: () => void;
35
+ /** Custom className */
36
+ className?: string;
37
+ /** Padding for tag positions */
38
+ tagPadding?: number;
39
+ /** Gap between tags */
40
+ tagGap?: number;
41
+ /** Test ID for testing frameworks */
42
+ testID?: string;
43
+ }
44
+
45
+ declare const ImageThumbnail: React.FC<ImageThumbnailProps>;
46
+
47
+ export { ImageThumbnail, type ImageThumbnailOverlay, type ImageThumbnailProps, type ImageThumbnailRatio };