@xsolla/xui-uploader 0.148.0 → 0.148.1

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 +270 -0
  2. package/package.json +5 -5
package/README.md ADDED
@@ -0,0 +1,270 @@
1
+ # Uploader
2
+
3
+ A cross-platform React file uploader component that provides a button to select files, displays selected files, and allows removing them.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @xsolla/xui-uploader
9
+ # or
10
+ yarn add @xsolla/xui-uploader
11
+ ```
12
+
13
+ ## Demo
14
+
15
+ ### Basic Uploader
16
+
17
+ ```tsx
18
+ import * as React from 'react';
19
+ import { Uploader } from '@xsolla/xui-uploader';
20
+
21
+ export default function BasicUploader() {
22
+ return (
23
+ <Uploader
24
+ label="Upload file"
25
+ onFilesChange={(files) => console.log('Selected:', files)}
26
+ />
27
+ );
28
+ }
29
+ ```
30
+
31
+ ### Multiple Files
32
+
33
+ ```tsx
34
+ import * as React from 'react';
35
+ import { Uploader } from '@xsolla/xui-uploader';
36
+
37
+ export default function MultipleFiles() {
38
+ return (
39
+ <Uploader
40
+ label="Upload documents"
41
+ placeholder="Select multiple files"
42
+ multiple
43
+ onFilesChange={(files) => console.log('Files:', files)}
44
+ />
45
+ );
46
+ }
47
+ ```
48
+
49
+ ### Accept Specific Types
50
+
51
+ ```tsx
52
+ import * as React from 'react';
53
+ import { Uploader } from '@xsolla/xui-uploader';
54
+
55
+ export default function ImageUploader() {
56
+ return (
57
+ <Uploader
58
+ label="Upload image"
59
+ placeholder="Select image file"
60
+ accept=".jpg,.jpeg,.png,.gif"
61
+ onFilesChange={(files) => console.log('Images:', files)}
62
+ />
63
+ );
64
+ }
65
+ ```
66
+
67
+ ## Anatomy
68
+
69
+ ```jsx
70
+ import { Uploader } from '@xsolla/xui-uploader';
71
+
72
+ <Uploader
73
+ label="Label" // Label above button
74
+ placeholder="Select files" // Button text
75
+ accept=".pdf,.doc" // Accepted file types
76
+ multiple={false} // Allow multiple selection
77
+ disabled={false} // Disabled state
78
+ size="md" // Button size
79
+ onFilesChange={handleFiles} // File change callback
80
+ />
81
+ ```
82
+
83
+ ## Examples
84
+
85
+ ### Document Upload
86
+
87
+ ```tsx
88
+ import * as React from 'react';
89
+ import { Uploader } from '@xsolla/xui-uploader';
90
+
91
+ export default function DocumentUpload() {
92
+ const [files, setFiles] = React.useState<File[]>([]);
93
+
94
+ return (
95
+ <div>
96
+ <Uploader
97
+ label="Legal documents"
98
+ placeholder="Upload PDF documents"
99
+ accept=".pdf"
100
+ multiple
101
+ onFilesChange={setFiles}
102
+ />
103
+ {files.length > 0 && (
104
+ <p style={{ marginTop: 8 }}>
105
+ {files.length} file(s) selected
106
+ </p>
107
+ )}
108
+ </div>
109
+ );
110
+ }
111
+ ```
112
+
113
+ ### Profile Image Upload
114
+
115
+ ```tsx
116
+ import * as React from 'react';
117
+ import { Uploader } from '@xsolla/xui-uploader';
118
+
119
+ export default function ProfileImageUpload() {
120
+ const handleImageUpload = (files: File[]) => {
121
+ if (files.length > 0) {
122
+ const file = files[0];
123
+ // Create preview URL
124
+ const previewUrl = URL.createObjectURL(file);
125
+ console.log('Preview:', previewUrl);
126
+ }
127
+ };
128
+
129
+ return (
130
+ <div style={{ maxWidth: 300 }}>
131
+ <Uploader
132
+ label="Profile picture"
133
+ placeholder="Choose image"
134
+ accept="image/*"
135
+ onFilesChange={handleImageUpload}
136
+ size="sm"
137
+ />
138
+ <p style={{ fontSize: 12, color: '#666', marginTop: 4 }}>
139
+ Recommended: Square image, at least 200x200px
140
+ </p>
141
+ </div>
142
+ );
143
+ }
144
+ ```
145
+
146
+ ### Form with File Upload
147
+
148
+ ```tsx
149
+ import * as React from 'react';
150
+ import { Uploader } from '@xsolla/xui-uploader';
151
+ import { Input } from '@xsolla/xui-input';
152
+ import { Textarea } from '@xsolla/xui-textarea';
153
+ import { Button } from '@xsolla/xui-button';
154
+
155
+ export default function FormWithUpload() {
156
+ const [files, setFiles] = React.useState<File[]>([]);
157
+
158
+ const handleSubmit = () => {
159
+ const formData = new FormData();
160
+ files.forEach((file) => formData.append('attachments', file));
161
+ console.log('Submitting with', files.length, 'files');
162
+ };
163
+
164
+ return (
165
+ <form
166
+ style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 400 }}
167
+ onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}
168
+ >
169
+ <Input label="Subject" placeholder="Enter subject" />
170
+ <Textarea label="Message" placeholder="Enter your message" />
171
+ <Uploader
172
+ label="Attachments"
173
+ placeholder="Add attachments"
174
+ multiple
175
+ onFilesChange={setFiles}
176
+ />
177
+ <Button type="submit">Submit</Button>
178
+ </form>
179
+ );
180
+ }
181
+ ```
182
+
183
+ ### Different Sizes
184
+
185
+ ```tsx
186
+ import * as React from 'react';
187
+ import { Uploader } from '@xsolla/xui-uploader';
188
+
189
+ export default function UploaderSizes() {
190
+ return (
191
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
192
+ <Uploader size="xs" placeholder="Extra small" />
193
+ <Uploader size="sm" placeholder="Small" />
194
+ <Uploader size="md" placeholder="Medium" />
195
+ <Uploader size="lg" placeholder="Large" />
196
+ <Uploader size="xl" placeholder="Extra large" />
197
+ </div>
198
+ );
199
+ }
200
+ ```
201
+
202
+ ### Disabled State
203
+
204
+ ```tsx
205
+ import * as React from 'react';
206
+ import { Uploader } from '@xsolla/xui-uploader';
207
+
208
+ export default function DisabledUploader() {
209
+ return (
210
+ <Uploader
211
+ label="Upload (disabled)"
212
+ placeholder="Cannot upload files"
213
+ disabled
214
+ />
215
+ );
216
+ }
217
+ ```
218
+
219
+ ## API Reference
220
+
221
+ ### Uploader
222
+
223
+ **UploaderProps:**
224
+
225
+ | Prop | Type | Default | Description |
226
+ | :--- | :--- | :------ | :---------- |
227
+ | label | `string` | - | Label text above the button. |
228
+ | placeholder | `string` | `"Select files to upload"` | Button text. |
229
+ | accept | `string` | - | Accepted file types (e.g., ".jpg,.png"). |
230
+ | multiple | `boolean` | `false` | Allow multiple file selection. |
231
+ | disabled | `boolean` | `false` | Disabled state. |
232
+ | size | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Button size. |
233
+ | onFilesChange | `(files: File[]) => void` | - | Callback when files change. |
234
+
235
+ ## File List Display
236
+
237
+ When files are selected, they appear below the button with:
238
+
239
+ - File icon
240
+ - File name (truncated if too long)
241
+ - Remove button (X icon)
242
+
243
+ Removing a file updates the list and calls `onFilesChange` with the updated array.
244
+
245
+ ## Accept Patterns
246
+
247
+ | Pattern | Description |
248
+ | :------ | :---------- |
249
+ | `.pdf` | PDF files only |
250
+ | `.jpg,.jpeg,.png` | Specific image formats |
251
+ | `image/*` | All image types |
252
+ | `video/*` | All video types |
253
+ | `.doc,.docx,.pdf` | Multiple document types |
254
+
255
+ ## Behavior
256
+
257
+ - Click button to open native file picker
258
+ - Multiple selection when `multiple` is true
259
+ - Files accumulate when `multiple` is true (new selections add to existing)
260
+ - Files replace when `multiple` is false
261
+ - Each file can be removed individually
262
+ - Hidden native input, styled button
263
+
264
+ ## Accessibility
265
+
266
+ - Button is keyboard accessible
267
+ - File input is properly associated with the button
268
+ - Remove buttons have appropriate labels
269
+ - Disabled state prevents interaction
270
+ - File list is accessible to screen readers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-uploader",
3
- "version": "0.148.0",
3
+ "version": "0.148.1",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -13,10 +13,10 @@
13
13
  "test:coverage": "vitest run --coverage"
14
14
  },
15
15
  "dependencies": {
16
- "@xsolla/xui-button": "0.148.0",
17
- "@xsolla/xui-core": "0.148.0",
18
- "@xsolla/xui-icons": "0.148.0",
19
- "@xsolla/xui-primitives-core": "0.148.0"
16
+ "@xsolla/xui-button": "0.148.1",
17
+ "@xsolla/xui-core": "0.148.1",
18
+ "@xsolla/xui-icons": "0.148.1",
19
+ "@xsolla/xui-primitives-core": "0.148.1"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "react": ">=16.8.0"