@xsolla/xui-image-thumbnail 0.99.0 → 0.100.0

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