@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 +279 -0
- package/native/index.d.mts +47 -0
- package/native/index.d.ts +47 -0
- package/native/index.js +5571 -0
- package/native/index.js.map +1 -0
- package/native/index.mjs +5566 -0
- package/native/index.mjs.map +1 -0
- package/package.json +56 -0
- package/web/index.d.mts +47 -0
- package/web/index.d.ts +47 -0
- package/web/index.js +4056 -0
- package/web/index.js.map +1 -0
- package/web/index.mjs +4042 -0
- package/web/index.mjs.map +1 -0
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 };
|