@xsolla/xui-tag 0.148.0 → 0.148.2
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 +319 -0
- package/package.json +4 -4
package/README.md
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# Tag
|
|
2
|
+
|
|
3
|
+
A cross-platform React tag component for displaying labels, categories, and removable chips. Supports multiple tones, solid/outlined types, and optional left/right icons.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @xsolla/xui-tag
|
|
9
|
+
# or
|
|
10
|
+
yarn add @xsolla/xui-tag
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Demo
|
|
14
|
+
|
|
15
|
+
### Basic Tag
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import * as React from 'react';
|
|
19
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
20
|
+
|
|
21
|
+
export default function BasicTag() {
|
|
22
|
+
return (
|
|
23
|
+
<div style={{ display: 'flex', gap: 8 }}>
|
|
24
|
+
<Tag>Default</Tag>
|
|
25
|
+
<Tag tone="brand">Brand</Tag>
|
|
26
|
+
<Tag tone="success">Success</Tag>
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Tag Tones
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import * as React from 'react';
|
|
36
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
37
|
+
|
|
38
|
+
export default function TagTones() {
|
|
39
|
+
return (
|
|
40
|
+
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
|
|
41
|
+
<Tag tone="primary">Primary</Tag>
|
|
42
|
+
<Tag tone="brand">Brand</Tag>
|
|
43
|
+
<Tag tone="brandExtra">Brand Extra</Tag>
|
|
44
|
+
<Tag tone="success">Success</Tag>
|
|
45
|
+
<Tag tone="warning">Warning</Tag>
|
|
46
|
+
<Tag tone="alert">Alert</Tag>
|
|
47
|
+
<Tag tone="neutral">Neutral</Tag>
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Tag Sizes
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import * as React from 'react';
|
|
57
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
58
|
+
|
|
59
|
+
export default function TagSizes() {
|
|
60
|
+
return (
|
|
61
|
+
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
|
|
62
|
+
<Tag size="xs">Extra Small</Tag>
|
|
63
|
+
<Tag size="sm">Small</Tag>
|
|
64
|
+
<Tag size="md">Medium</Tag>
|
|
65
|
+
<Tag size="lg">Large</Tag>
|
|
66
|
+
<Tag size="xl">Extra Large</Tag>
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Solid vs Outlined
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import * as React from 'react';
|
|
76
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
77
|
+
|
|
78
|
+
export default function TagTypes() {
|
|
79
|
+
return (
|
|
80
|
+
<div style={{ display: 'flex', gap: 8 }}>
|
|
81
|
+
<Tag tone="brand" type="solid">Solid</Tag>
|
|
82
|
+
<Tag tone="brand" type="outlined">Outlined</Tag>
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Tag with Icons
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import * as React from 'react';
|
|
92
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
93
|
+
import { Check } from '@xsolla/xui-icons';
|
|
94
|
+
import { Star, Clock } from '@xsolla/xui-icons-base';
|
|
95
|
+
|
|
96
|
+
export default function TagWithIcon() {
|
|
97
|
+
return (
|
|
98
|
+
<div style={{ display: 'flex', gap: 8 }}>
|
|
99
|
+
<Tag iconLeft={<Star size={12} />} tone="warning">Featured</Tag>
|
|
100
|
+
<Tag iconLeft={<Check size={12} />} tone="success">Verified</Tag>
|
|
101
|
+
<Tag iconLeft={<Clock size={12} />} iconRight={<Star size={12} />} tone="neutral">Pending</Tag>
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Icon-Only Tag
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
import * as React from 'react';
|
|
111
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
112
|
+
import { Check } from '@xsolla/xui-icons';
|
|
113
|
+
|
|
114
|
+
export default function IconOnlyTag() {
|
|
115
|
+
return <Tag iconLeft={<Check size={12} />} tone="success" />;
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Removable Tag
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import * as React from 'react';
|
|
123
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
124
|
+
|
|
125
|
+
export default function RemovableTag() {
|
|
126
|
+
const [tags, setTags] = React.useState(['React', 'TypeScript', 'Node.js', 'GraphQL']);
|
|
127
|
+
|
|
128
|
+
const removeTag = (tagToRemove: string) => {
|
|
129
|
+
setTags(tags.filter(tag => tag !== tagToRemove));
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
|
|
134
|
+
{tags.map(tag => (
|
|
135
|
+
<Tag key={tag} tone="brand" onRemove={() => removeTag(tag)}>
|
|
136
|
+
{tag}
|
|
137
|
+
</Tag>
|
|
138
|
+
))}
|
|
139
|
+
</div>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Anatomy
|
|
145
|
+
|
|
146
|
+
Import the component and use it directly:
|
|
147
|
+
|
|
148
|
+
```jsx
|
|
149
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
150
|
+
|
|
151
|
+
<Tag
|
|
152
|
+
size="md" // Size variant
|
|
153
|
+
tone="brand" // Color tone
|
|
154
|
+
type="solid" // Solid or outlined
|
|
155
|
+
iconLeft={<Icon />} // Optional leading icon
|
|
156
|
+
iconRight={<Icon />} // Optional trailing icon
|
|
157
|
+
onRemove={handleRemove} // Makes tag removable (renders X icon)
|
|
158
|
+
>
|
|
159
|
+
Tag Label
|
|
160
|
+
</Tag>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Examples
|
|
164
|
+
|
|
165
|
+
### Category Tags
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
import * as React from 'react';
|
|
169
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
170
|
+
|
|
171
|
+
export default function CategoryTags() {
|
|
172
|
+
const categories = [
|
|
173
|
+
{ name: 'Technology', tone: 'brand' as const },
|
|
174
|
+
{ name: 'Design', tone: 'brandExtra' as const },
|
|
175
|
+
{ name: 'Marketing', tone: 'success' as const },
|
|
176
|
+
{ name: 'Sales', tone: 'warning' as const },
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<div style={{ display: 'flex', gap: 8 }}>
|
|
181
|
+
{categories.map(cat => (
|
|
182
|
+
<Tag key={cat.name} tone={cat.tone} size="sm">
|
|
183
|
+
{cat.name}
|
|
184
|
+
</Tag>
|
|
185
|
+
))}
|
|
186
|
+
</div>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Status Tags
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
import * as React from 'react';
|
|
195
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
196
|
+
import { CheckCircle, Clock, XCircle } from '@xsolla/xui-icons-base';
|
|
197
|
+
|
|
198
|
+
export default function StatusTags() {
|
|
199
|
+
return (
|
|
200
|
+
<div style={{ display: 'flex', gap: 8 }}>
|
|
201
|
+
<Tag iconLeft={<CheckCircle size={12} />} tone="success">
|
|
202
|
+
Completed
|
|
203
|
+
</Tag>
|
|
204
|
+
<Tag iconLeft={<Clock size={12} />} tone="warning">
|
|
205
|
+
In Progress
|
|
206
|
+
</Tag>
|
|
207
|
+
<Tag iconLeft={<XCircle size={12} />} tone="alert">
|
|
208
|
+
Failed
|
|
209
|
+
</Tag>
|
|
210
|
+
</div>
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Tag Input
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
import * as React from 'react';
|
|
219
|
+
import { Tag } from '@xsolla/xui-tag';
|
|
220
|
+
import { Input } from '@xsolla/xui-input';
|
|
221
|
+
|
|
222
|
+
export default function TagInput() {
|
|
223
|
+
const [tags, setTags] = React.useState(['react', 'typescript']);
|
|
224
|
+
const [inputValue, setInputValue] = React.useState('');
|
|
225
|
+
|
|
226
|
+
const addTag = () => {
|
|
227
|
+
if (inputValue.trim() && !tags.includes(inputValue.trim())) {
|
|
228
|
+
setTags([...tags, inputValue.trim()]);
|
|
229
|
+
setInputValue('');
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
return (
|
|
234
|
+
<div>
|
|
235
|
+
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 8 }}>
|
|
236
|
+
{tags.map(tag => (
|
|
237
|
+
<Tag
|
|
238
|
+
key={tag}
|
|
239
|
+
tone="primary"
|
|
240
|
+
onRemove={() => setTags(tags.filter(t => t !== tag))}
|
|
241
|
+
>
|
|
242
|
+
{tag}
|
|
243
|
+
</Tag>
|
|
244
|
+
))}
|
|
245
|
+
</div>
|
|
246
|
+
<Input
|
|
247
|
+
value={inputValue}
|
|
248
|
+
onChangeText={setInputValue}
|
|
249
|
+
placeholder="Add a tag..."
|
|
250
|
+
onKeyDown={(e) => e.key === 'Enter' && addTag()}
|
|
251
|
+
/>
|
|
252
|
+
</div>
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## API Reference
|
|
258
|
+
|
|
259
|
+
### Tag
|
|
260
|
+
|
|
261
|
+
A tag/chip component.
|
|
262
|
+
|
|
263
|
+
**Tag Props:**
|
|
264
|
+
|
|
265
|
+
| Prop | Type | Default | Description |
|
|
266
|
+
| :--- | :--- | :------ | :---------- |
|
|
267
|
+
| children | `ReactNode` | - | Tag content. Optional for icon-only tags. |
|
|
268
|
+
| size | `"xl" \| "lg" \| "md" \| "sm" \| "xs"` | `"md"` | Size of the tag. |
|
|
269
|
+
| tone | `"primary" \| "brand" \| "brandExtra" \| "success" \| "warning" \| "alert" \| "neutral"` | `"primary"` | Color tone. |
|
|
270
|
+
| type | `"solid" \| "outlined"` | `"solid"` | Visual type. Solid fills background; outlined uses a border with lighter background. |
|
|
271
|
+
| iconLeft | `ReactNode` | - | Leading icon. |
|
|
272
|
+
| iconRight | `ReactNode` | - | Trailing icon. |
|
|
273
|
+
| onRemove | `() => void` | - | Callback for remove button. Renders an X icon in the trailing position. |
|
|
274
|
+
|
|
275
|
+
**Solid Tone Color Mapping:**
|
|
276
|
+
|
|
277
|
+
| Tone | Background | Text |
|
|
278
|
+
| :--- | :--------- | :--- |
|
|
279
|
+
| primary | Background primary | Content primary |
|
|
280
|
+
| brand | Brand primary | On brand |
|
|
281
|
+
| brandExtra | BrandExtra primary | On brandExtra |
|
|
282
|
+
| success | Success primary | On success |
|
|
283
|
+
| warning | Warning primary | On warning |
|
|
284
|
+
| alert | Alert primary | On alert |
|
|
285
|
+
| neutral | Neutral primary | On neutral |
|
|
286
|
+
|
|
287
|
+
**Outlined Tone Color Mapping:**
|
|
288
|
+
|
|
289
|
+
| Tone | Background | Border | Text |
|
|
290
|
+
| :--- | :--------- | :----- | :--- |
|
|
291
|
+
| primary | Background primary | Border secondary | Content primary |
|
|
292
|
+
| brand | Brand secondary | Border brand | Content brand primary |
|
|
293
|
+
| brandExtra | BrandExtra secondary | Border brandExtra | Content brandExtra primary |
|
|
294
|
+
| success | Success secondary | Border success | Content success primary |
|
|
295
|
+
| warning | Warning secondary | Border warning | Content warning primary |
|
|
296
|
+
| alert | Alert secondary | Border alert | Content alert primary |
|
|
297
|
+
| neutral | Neutral secondary | Border neutral | Content neutral primary |
|
|
298
|
+
|
|
299
|
+
## Theming
|
|
300
|
+
|
|
301
|
+
Tag uses the design system theme for colors:
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
// Solid colors (example for "brand" tone)
|
|
305
|
+
theme.colors.background.brand.primary // Background
|
|
306
|
+
theme.colors.content.on.brand // Text color
|
|
307
|
+
|
|
308
|
+
// Outlined colors (example for "brand" tone)
|
|
309
|
+
theme.colors.background.brand.secondary // Background
|
|
310
|
+
theme.colors.border.brand // Border color
|
|
311
|
+
theme.colors.content.brand.primary // Text color
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Accessibility
|
|
315
|
+
|
|
316
|
+
- Uses semantic elements for proper structure
|
|
317
|
+
- Remove button includes accessible label
|
|
318
|
+
- Keyboard accessible remove action
|
|
319
|
+
- Focus indicator on interactive elements
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsolla/xui-tag",
|
|
3
|
-
"version": "0.148.
|
|
3
|
+
"version": "0.148.2",
|
|
4
4
|
"main": "./web/index.js",
|
|
5
5
|
"module": "./web/index.mjs",
|
|
6
6
|
"types": "./web/index.d.ts",
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
"build:native": "PLATFORM=native tsup"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@xsolla/xui-core": "0.148.
|
|
14
|
-
"@xsolla/xui-icons": "0.148.
|
|
15
|
-
"@xsolla/xui-primitives-core": "0.148.
|
|
13
|
+
"@xsolla/xui-core": "0.148.2",
|
|
14
|
+
"@xsolla/xui-icons": "0.148.2",
|
|
15
|
+
"@xsolla/xui-primitives-core": "0.148.2"
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
|
18
18
|
"react": ">=16.8.0",
|