@xsolla/xui-toast 0.150.0 → 0.152.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.
- package/README.md +185 -405
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,543 +1,323 @@
|
|
|
1
1
|
# Toast
|
|
2
2
|
|
|
3
|
-
A cross-platform
|
|
3
|
+
A cross-platform toast notification system built on a provider/context architecture with a hook-based API. Supports multiple variants, configurable position and alignment, custom durations, custom icons, and programmatic dismiss on both web and React Native.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @xsolla/xui-toast
|
|
9
|
-
# or
|
|
10
|
-
yarn add @xsolla/xui-toast @xsolla/xui-core
|
|
8
|
+
npm install @xsolla/xui-toast
|
|
11
9
|
```
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
## Imports
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
│ │ useToast() │
|
|
30
|
-
│ ┌─────┴──────┐ │
|
|
31
|
-
│ │ Your App │ │
|
|
32
|
-
│ └────────────┘ │
|
|
33
|
-
└─────────────────────────────────────────────────┘
|
|
13
|
+
```tsx
|
|
14
|
+
import {
|
|
15
|
+
Toast,
|
|
16
|
+
ToastProvider,
|
|
17
|
+
ToastGroup,
|
|
18
|
+
ToastContext,
|
|
19
|
+
useToast,
|
|
20
|
+
type ToastProps,
|
|
21
|
+
type ToastOptions,
|
|
22
|
+
type ToastVariant,
|
|
23
|
+
type ToastPosition,
|
|
24
|
+
type ToastAlign,
|
|
25
|
+
type UseToastReturn,
|
|
26
|
+
} from '@xsolla/xui-toast';
|
|
34
27
|
```
|
|
35
28
|
|
|
36
|
-
|
|
37
|
-
2. **`ToastContext`** — React context that exposes `addToast`, `dismissToast`, and `dismissAllToasts` to descendants.
|
|
38
|
-
3. **`useToast`** — Consumer hook that provides convenience methods (`success`, `info`, `warning`, `error`, `dismiss`, `dismissAll`).
|
|
39
|
-
4. **`ToastGroup`** — Renders the stack of visible toasts. On web, uses `ReactDOM.createPortal` to escape z-index stacking contexts. On React Native, uses absolute positioning.
|
|
40
|
-
5. **`Toast`** — The individual notification component with icon, message, and optional close button.
|
|
41
|
-
|
|
42
|
-
## Quick Start
|
|
43
|
-
|
|
44
|
-
### 1. Wrap your app with `ToastProvider`
|
|
29
|
+
## Quick start
|
|
45
30
|
|
|
46
|
-
|
|
31
|
+
Wrap your app with `ToastProvider`, then call `useToast` from any descendant.
|
|
47
32
|
|
|
48
33
|
```tsx
|
|
34
|
+
import * as React from 'react';
|
|
49
35
|
import { XUIProvider } from '@xsolla/xui-core';
|
|
50
|
-
import { ToastProvider } from '@xsolla/xui-toast';
|
|
36
|
+
import { ToastProvider, useToast } from '@xsolla/xui-toast';
|
|
51
37
|
|
|
52
|
-
|
|
38
|
+
function SaveButton() {
|
|
39
|
+
const toast = useToast();
|
|
53
40
|
return (
|
|
54
|
-
<
|
|
55
|
-
<ToastProvider>
|
|
56
|
-
<YourApp />
|
|
57
|
-
</ToastProvider>
|
|
58
|
-
</XUIProvider>
|
|
41
|
+
<button onClick={() => toast.success('Saved successfully')}>Save</button>
|
|
59
42
|
);
|
|
60
43
|
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
**React Native:**
|
|
64
|
-
|
|
65
|
-
```tsx
|
|
66
|
-
import React from 'react';
|
|
67
|
-
import { View } from 'react-native';
|
|
68
|
-
import { XUIProvider } from '@xsolla/xui-core';
|
|
69
|
-
import { ToastProvider } from '@xsolla/xui-toast';
|
|
70
|
-
import { MainNavigator } from './navigation';
|
|
71
44
|
|
|
72
45
|
export default function App() {
|
|
73
46
|
return (
|
|
74
|
-
<XUIProvider
|
|
75
|
-
<ToastProvider
|
|
76
|
-
<
|
|
77
|
-
<MainNavigator />
|
|
78
|
-
</View>
|
|
47
|
+
<XUIProvider initialMode="dark">
|
|
48
|
+
<ToastProvider>
|
|
49
|
+
<SaveButton />
|
|
79
50
|
</ToastProvider>
|
|
80
51
|
</XUIProvider>
|
|
81
52
|
);
|
|
82
53
|
}
|
|
83
54
|
```
|
|
84
55
|
|
|
85
|
-
> **
|
|
56
|
+
> **React Native:** ensure the root container under `ToastProvider` has `flex: 1` so absolute-positioned toasts have a reference height.
|
|
86
57
|
|
|
87
|
-
|
|
58
|
+
## API Reference
|
|
88
59
|
|
|
89
|
-
|
|
90
|
-
import { useToast } from '@xsolla/xui-toast';
|
|
60
|
+
### `<ToastProvider>`
|
|
91
61
|
|
|
92
|
-
|
|
93
|
-
const toast = useToast();
|
|
62
|
+
Root provider. Manages toast state, auto-dismiss timers, and renders the `ToastGroup`.
|
|
94
63
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
};
|
|
64
|
+
| Prop | Type | Default | Description |
|
|
65
|
+
| --- | --- | --- | --- |
|
|
66
|
+
| `children` | `ReactNode` | — | Application content. |
|
|
67
|
+
| `position` | `"top" \| "bottom"` | `"top"` | Vertical anchor of the toast container. |
|
|
68
|
+
| `align` | `"left" \| "center" \| "right"` | `"center"` | Horizontal alignment of toasts within the container. |
|
|
69
|
+
| `defaultDuration` | `number` | `5000` | Default auto-dismiss duration in ms. Set `0` to disable auto-dismiss globally. |
|
|
70
|
+
| `maxWidth` | `number` | — | Maximum width (px) of the toast stack. When unset, toasts stretch to the container width. |
|
|
103
71
|
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
```
|
|
72
|
+
### `<Toast>`
|
|
107
73
|
|
|
108
|
-
|
|
74
|
+
The individual toast cell. Used internally by `ToastGroup`, but can be rendered standalone for static display.
|
|
109
75
|
|
|
110
|
-
|
|
76
|
+
| Prop | Type | Default | Description |
|
|
77
|
+
| --- | --- | --- | --- |
|
|
78
|
+
| `id` | `string` | — | Required unique identifier. |
|
|
79
|
+
| `message` | `string` | — | Required message text. |
|
|
80
|
+
| `variant` | `"success" \| "info" \| "warning" \| "error"` | `"info"` | Visual variant; determines the default icon and accent colour. |
|
|
81
|
+
| `icon` | `ReactNode` | — | Custom icon. Overrides the default. |
|
|
82
|
+
| `duration` | `number` | — | Auto-dismiss duration in ms. `0` or omitted = no auto-dismiss. |
|
|
83
|
+
| `onClose` | `() => void` | — | Close handler. Required for the close button to render. |
|
|
111
84
|
|
|
112
|
-
|
|
85
|
+
Inherits `ThemeOverrideProps` (`themeMode`, `themeProductContext`).
|
|
113
86
|
|
|
114
|
-
|
|
115
|
-
import { useToast } from '@xsolla/xui-toast';
|
|
87
|
+
### `<ToastGroup>`
|
|
116
88
|
|
|
117
|
-
|
|
118
|
-
const toast = useToast();
|
|
89
|
+
Renders the stack of visible toasts. On web uses `ReactDOM.createPortal` to escape stacking contexts; on React Native uses absolute positioning.
|
|
119
90
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
91
|
+
| Prop | Type | Default | Description |
|
|
92
|
+
| --- | --- | --- | --- |
|
|
93
|
+
| `toasts` | `ToastData[]` | — | Toasts to render. |
|
|
94
|
+
| `position` | `"top" \| "bottom"` | `"top"` | Vertical anchor. |
|
|
95
|
+
| `align` | `"left" \| "center" \| "right"` | `"center"` | Horizontal alignment. |
|
|
96
|
+
| `maxWidth` | `number` | — | Maximum width (px). |
|
|
97
|
+
| `onDismiss` | `(id: string) => void` | — | Dismiss callback per toast. |
|
|
98
|
+
|
|
99
|
+
Inherits `ThemeOverrideProps`.
|
|
100
|
+
|
|
101
|
+
### `useToast()`
|
|
102
|
+
|
|
103
|
+
Hook that returns toast helpers. Throws if called outside a `ToastProvider`.
|
|
104
|
+
|
|
105
|
+
| Method | Signature | Description |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| `toast` | `(options: ToastOptions) => string` | Show a toast with full options. Returns the toast ID. |
|
|
108
|
+
| `success` | `(message: string, options?) => string` | Show a success toast. |
|
|
109
|
+
| `info` | `(message: string, options?) => string` | Show an info toast. |
|
|
110
|
+
| `warning` | `(message: string, options?) => string` | Show a warning toast. |
|
|
111
|
+
| `error` | `(message: string, options?) => string` | Show an error toast. |
|
|
112
|
+
| `dismiss` | `(id: string) => void` | Dismiss a specific toast by ID. |
|
|
113
|
+
| `dismissAll` | `() => void` | Dismiss all visible toasts. |
|
|
114
|
+
|
|
115
|
+
### `ToastOptions`
|
|
116
|
+
|
|
117
|
+
| Property | Type | Default | Description |
|
|
118
|
+
| --- | --- | --- | --- |
|
|
119
|
+
| `message` | `string` | — | Required message text. |
|
|
120
|
+
| `variant` | `"success" \| "info" \| "warning" \| "error"` | `"info"` | Visual variant. |
|
|
121
|
+
| `icon` | `ReactNode` | — | Custom icon. |
|
|
122
|
+
| `duration` | `number` | provider's `defaultDuration` | Auto-dismiss duration. `0` keeps the toast until dismissed manually. |
|
|
123
|
+
|
|
124
|
+
### `ToastData`
|
|
125
|
+
|
|
126
|
+
Internal shape exposed via `ToastContext.toasts`.
|
|
127
|
+
|
|
128
|
+
| Property | Type | Description |
|
|
129
|
+
| --- | --- | --- |
|
|
130
|
+
| `id` | `string` | Unique identifier generated by the provider. |
|
|
131
|
+
| `variant` | `ToastVariant` | Toast variant. |
|
|
132
|
+
| `message` | `string` | Message text. |
|
|
133
|
+
| `icon` | `ReactNode \| undefined` | Custom icon, if any. |
|
|
134
|
+
| `duration` | `number \| undefined` | Auto-dismiss duration. |
|
|
135
|
+
|
|
136
|
+
### `ToastContext`
|
|
137
|
+
|
|
138
|
+
React context with `{ toasts, addToast, dismissToast, dismissAllToasts }`. Typically consumed via `useToast`; available for advanced use cases:
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
import { useContext } from 'react';
|
|
142
|
+
import { ToastContext } from '@xsolla/xui-toast';
|
|
143
|
+
|
|
144
|
+
function ActiveCount() {
|
|
145
|
+
const ctx = useContext(ToastContext);
|
|
146
|
+
if (!ctx) throw new Error('Must be within ToastProvider');
|
|
147
|
+
return <span>Active toasts: {ctx.toasts.length}</span>;
|
|
136
148
|
}
|
|
137
149
|
```
|
|
138
150
|
|
|
139
|
-
|
|
151
|
+
## Examples
|
|
140
152
|
|
|
141
|
-
|
|
153
|
+
### Variants
|
|
142
154
|
|
|
143
155
|
```tsx
|
|
144
|
-
import React from 'react';
|
|
145
|
-
import { View } from 'react-native';
|
|
146
|
-
import { Button } from '@xsolla/xui-button';
|
|
156
|
+
import * as React from 'react';
|
|
147
157
|
import { useToast } from '@xsolla/xui-toast';
|
|
148
158
|
|
|
149
|
-
export default function
|
|
159
|
+
export default function Variants() {
|
|
150
160
|
const toast = useToast();
|
|
151
|
-
|
|
152
161
|
return (
|
|
153
|
-
<
|
|
154
|
-
<
|
|
155
|
-
|
|
156
|
-
</
|
|
157
|
-
<
|
|
158
|
-
|
|
159
|
-
</Button>
|
|
160
|
-
<Button onPress={() => toast.warning('Your session is about to expire')}>
|
|
161
|
-
Warning
|
|
162
|
-
</Button>
|
|
163
|
-
<Button onPress={() => toast.error('Failed to save changes')}>
|
|
164
|
-
Error
|
|
165
|
-
</Button>
|
|
166
|
-
</View>
|
|
162
|
+
<div style={{ display: 'flex', gap: 8 }}>
|
|
163
|
+
<button onClick={() => toast.success('Quest activated')}>Success</button>
|
|
164
|
+
<button onClick={() => toast.info('You received 50 points')}>Info</button>
|
|
165
|
+
<button onClick={() => toast.warning('Session about to expire')}>Warning</button>
|
|
166
|
+
<button onClick={() => toast.error('Failed to save')}>Error</button>
|
|
167
|
+
</div>
|
|
167
168
|
);
|
|
168
169
|
}
|
|
169
170
|
```
|
|
170
171
|
|
|
171
|
-
### Toast
|
|
172
|
-
|
|
173
|
-
The `Toast` component can be used standalone outside the provider for static display or custom layouts:
|
|
172
|
+
### Standalone Toast (no provider)
|
|
174
173
|
|
|
175
174
|
```tsx
|
|
175
|
+
import * as React from 'react';
|
|
176
176
|
import { Toast } from '@xsolla/xui-toast';
|
|
177
177
|
|
|
178
|
-
export default function
|
|
178
|
+
export default function Standalone() {
|
|
179
179
|
return (
|
|
180
180
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 8, maxWidth: 400 }}>
|
|
181
|
-
<Toast id="1" variant="success" message="Quest
|
|
182
|
-
<Toast id="2" variant="info" message="You received 50
|
|
183
|
-
<Toast id="3" variant="warning" message="
|
|
184
|
-
<Toast id="4" variant="error" message="Failed to save
|
|
181
|
+
<Toast id="1" variant="success" message="Quest activated" onClose={() => {}} />
|
|
182
|
+
<Toast id="2" variant="info" message="You received 50 points" onClose={() => {}} />
|
|
183
|
+
<Toast id="3" variant="warning" message="Session about to expire" onClose={() => {}} />
|
|
184
|
+
<Toast id="4" variant="error" message="Failed to save" onClose={() => {}} />
|
|
185
185
|
</div>
|
|
186
186
|
);
|
|
187
187
|
}
|
|
188
188
|
```
|
|
189
189
|
|
|
190
|
-
### Custom
|
|
191
|
-
|
|
192
|
-
Control how long toasts remain visible. The default is 5000ms. Set `duration: 0` to disable auto-dismiss entirely:
|
|
190
|
+
### Custom duration
|
|
193
191
|
|
|
194
192
|
```tsx
|
|
193
|
+
import * as React from 'react';
|
|
195
194
|
import { useToast } from '@xsolla/xui-toast';
|
|
196
195
|
|
|
197
|
-
export default function
|
|
196
|
+
export default function Duration() {
|
|
198
197
|
const toast = useToast();
|
|
199
|
-
|
|
200
198
|
return (
|
|
201
|
-
<div style={{ display: 'flex',
|
|
202
|
-
<button onClick={() => toast.toast({ message: 'Stays
|
|
203
|
-
|
|
204
|
-
</button>
|
|
205
|
-
<button onClick={() => toast.toast({ message: 'Stays for 2 seconds', duration: 2000 })}>
|
|
206
|
-
Short Duration (2s)
|
|
207
|
-
</button>
|
|
208
|
-
<button onClick={() => toast.toast({ message: 'Dismiss me manually', duration: 0 })}>
|
|
209
|
-
No Auto-Dismiss
|
|
210
|
-
</button>
|
|
199
|
+
<div style={{ display: 'flex', gap: 8 }}>
|
|
200
|
+
<button onClick={() => toast.toast({ message: 'Stays 10s', duration: 10000 })}>10s</button>
|
|
201
|
+
<button onClick={() => toast.toast({ message: 'Stays 2s', duration: 2000 })}>2s</button>
|
|
202
|
+
<button onClick={() => toast.toast({ message: 'Manual dismiss', duration: 0 })}>No auto-dismiss</button>
|
|
211
203
|
</div>
|
|
212
204
|
);
|
|
213
205
|
}
|
|
214
206
|
```
|
|
215
207
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
```tsx
|
|
219
|
-
<ToastProvider defaultDuration={3000}>
|
|
220
|
-
<App />
|
|
221
|
-
</ToastProvider>
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### Custom Icons
|
|
225
|
-
|
|
226
|
-
Override the default variant icon by passing a `ReactNode` via the `icon` option:
|
|
208
|
+
### Custom icon
|
|
227
209
|
|
|
228
210
|
```tsx
|
|
211
|
+
import * as React from 'react';
|
|
229
212
|
import { useToast } from '@xsolla/xui-toast';
|
|
230
|
-
import { Star } from '@xsolla/xui-icons';
|
|
213
|
+
import { Star } from '@xsolla/xui-icons-base';
|
|
231
214
|
|
|
232
|
-
function
|
|
215
|
+
export default function CustomIcon() {
|
|
233
216
|
const toast = useToast();
|
|
234
|
-
|
|
235
217
|
return (
|
|
236
218
|
<button
|
|
237
219
|
onClick={() =>
|
|
238
|
-
toast.toast({
|
|
239
|
-
message: 'You earned a gold star!',
|
|
240
|
-
variant: 'success',
|
|
241
|
-
icon: <Star />,
|
|
242
|
-
})
|
|
220
|
+
toast.toast({ message: 'You earned a gold star', variant: 'success', icon: <Star /> })
|
|
243
221
|
}
|
|
244
222
|
>
|
|
245
|
-
Show
|
|
223
|
+
Show
|
|
246
224
|
</button>
|
|
247
225
|
);
|
|
248
226
|
}
|
|
249
227
|
```
|
|
250
228
|
|
|
251
|
-
###
|
|
252
|
-
|
|
253
|
-
Every `toast.*()` call returns a unique ID. Use it to dismiss a specific toast:
|
|
229
|
+
### Programmatic dismiss
|
|
254
230
|
|
|
255
231
|
```tsx
|
|
256
232
|
import * as React from 'react';
|
|
257
233
|
import { useToast } from '@xsolla/xui-toast';
|
|
258
234
|
|
|
259
|
-
export default function
|
|
235
|
+
export default function Dismiss() {
|
|
260
236
|
const toast = useToast();
|
|
261
|
-
const [
|
|
262
|
-
|
|
263
|
-
const showToast = () => {
|
|
264
|
-
const id = toast.info('New notification');
|
|
265
|
-
setLastToastId(id);
|
|
266
|
-
};
|
|
237
|
+
const [lastId, setLastId] = React.useState<string | null>(null);
|
|
267
238
|
|
|
268
239
|
return (
|
|
269
240
|
<div style={{ display: 'flex', gap: 8 }}>
|
|
270
|
-
<button onClick={
|
|
271
|
-
<button onClick={() =>
|
|
272
|
-
|
|
273
|
-
</button>
|
|
274
|
-
<button onClick={() => toast.dismissAll()}>Dismiss All</button>
|
|
241
|
+
<button onClick={() => setLastId(toast.info('New notification'))}>Show</button>
|
|
242
|
+
<button onClick={() => lastId && toast.dismiss(lastId)}>Dismiss last</button>
|
|
243
|
+
<button onClick={() => toast.dismissAll()}>Dismiss all</button>
|
|
275
244
|
</div>
|
|
276
245
|
);
|
|
277
246
|
}
|
|
278
247
|
```
|
|
279
248
|
|
|
280
|
-
### Position
|
|
281
|
-
|
|
282
|
-
Toasts can be anchored to the top or bottom of the viewport:
|
|
249
|
+
### Position and alignment
|
|
283
250
|
|
|
284
251
|
```tsx
|
|
252
|
+
import * as React from 'react';
|
|
285
253
|
import { ToastProvider, useToast } from '@xsolla/xui-toast';
|
|
286
254
|
|
|
287
|
-
function
|
|
255
|
+
function Trigger() {
|
|
288
256
|
const toast = useToast();
|
|
289
|
-
return <button onClick={() => toast.info('
|
|
257
|
+
return <button onClick={() => toast.info('Bottom-right toast')}>Show</button>;
|
|
290
258
|
}
|
|
291
259
|
|
|
292
|
-
export default function
|
|
260
|
+
export default function BottomRight() {
|
|
293
261
|
return (
|
|
294
|
-
<ToastProvider position="bottom">
|
|
295
|
-
<
|
|
262
|
+
<ToastProvider position="bottom" align="right" maxWidth={400}>
|
|
263
|
+
<Trigger />
|
|
296
264
|
</ToastProvider>
|
|
297
265
|
);
|
|
298
266
|
}
|
|
299
267
|
```
|
|
300
268
|
|
|
301
|
-
###
|
|
269
|
+
### React Native
|
|
302
270
|
|
|
303
|
-
|
|
271
|
+
The `useToast` hook is identical on React Native; use `onPress` instead of `onClick`.
|
|
304
272
|
|
|
305
273
|
```tsx
|
|
306
|
-
import
|
|
274
|
+
import * as React from 'react';
|
|
275
|
+
import { View } from 'react-native';
|
|
276
|
+
import { Button } from '@xsolla/xui-button';
|
|
277
|
+
import { XUIProvider } from '@xsolla/xui-core';
|
|
278
|
+
import { ToastProvider, useToast } from '@xsolla/xui-toast';
|
|
307
279
|
|
|
308
|
-
function
|
|
280
|
+
function Trigger() {
|
|
309
281
|
const toast = useToast();
|
|
310
|
-
|
|
311
|
-
const showMultiple = () => {
|
|
312
|
-
toast.success('First toast - Success');
|
|
313
|
-
setTimeout(() => toast.info('Second toast - Info'), 200);
|
|
314
|
-
setTimeout(() => toast.warning('Third toast - Warning'), 400);
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
return <button onClick={showMultiple}>Show Multiple Toasts</button>;
|
|
282
|
+
return <Button onPress={() => toast.success('Saved')}>Save</Button>;
|
|
318
283
|
}
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
## API Reference
|
|
322
|
-
|
|
323
|
-
### ToastProvider
|
|
324
|
-
|
|
325
|
-
The root provider component that manages toast state and renders the toast container.
|
|
326
|
-
|
|
327
|
-
| Prop | Type | Default | Description |
|
|
328
|
-
| :--- | :--- | :------ | :---------- |
|
|
329
|
-
| `children` | `ReactNode` | — | Application content. |
|
|
330
|
-
| `position` | `"top" \| "bottom"` | `"top"` | Position of the toast container on screen. |
|
|
331
|
-
| `defaultDuration` | `number` | `5000` | Default auto-dismiss duration in milliseconds. Set to `0` to disable auto-dismiss globally. |
|
|
332
|
-
| `maxWidth` | `number` | `100%` | Maximum width of the toast container in pixels. If not set, toasts stretch to full viewport width. |
|
|
333
|
-
|
|
334
|
-
### useToast
|
|
335
|
-
|
|
336
|
-
A hook that returns methods to show and dismiss toasts. Must be called within a `ToastProvider` — throws an error otherwise.
|
|
337
|
-
|
|
338
|
-
**Return type: `UseToastReturn`**
|
|
339
|
-
|
|
340
|
-
| Method | Signature | Description |
|
|
341
|
-
| :----- | :-------- | :---------- |
|
|
342
|
-
| `toast` | `(options: ToastOptions) => string` | Show a toast with full control over options. Returns the toast ID. |
|
|
343
|
-
| `success` | `(message: string, options?) => string` | Show a success toast with a check icon. |
|
|
344
|
-
| `info` | `(message: string, options?) => string` | Show an info toast with an info icon. |
|
|
345
|
-
| `warning` | `(message: string, options?) => string` | Show a warning toast with an alert icon. |
|
|
346
|
-
| `error` | `(message: string, options?) => string` | Show an error toast with an alert icon. |
|
|
347
|
-
| `dismiss` | `(id: string) => void` | Dismiss a specific toast by its ID. |
|
|
348
|
-
| `dismissAll` | `() => void` | Dismiss all visible toasts at once. |
|
|
349
|
-
|
|
350
|
-
### Toast
|
|
351
|
-
|
|
352
|
-
The individual toast notification component. Used internally by `ToastGroup`, but can be rendered standalone for static display.
|
|
353
|
-
|
|
354
|
-
| Prop | Type | Default | Description |
|
|
355
|
-
| :--- | :--- | :------ | :---------- |
|
|
356
|
-
| `id` | `string` | — | Unique identifier for the toast (required). |
|
|
357
|
-
| `message` | `string` | — | Toast message text (required). |
|
|
358
|
-
| `variant` | `"success" \| "info" \| "warning" \| "error"` | `"info"` | Visual variant that determines the icon color. |
|
|
359
|
-
| `icon` | `ReactNode` | — | Custom icon element. When omitted, a default icon for the variant is used. |
|
|
360
|
-
| `onClose` | `() => void` | — | Callback fired when the close button is clicked. If omitted, the close button is hidden. |
|
|
361
|
-
|
|
362
|
-
### ToastOptions
|
|
363
|
-
|
|
364
|
-
Options object passed to the `toast()` method or as the second argument to shorthand methods.
|
|
365
|
-
|
|
366
|
-
| Property | Type | Default | Description |
|
|
367
|
-
| :------- | :--- | :------ | :---------- |
|
|
368
|
-
| `message` | `string` | — | Toast message text (required). |
|
|
369
|
-
| `variant` | `"success" \| "info" \| "warning" \| "error"` | `"info"` | Toast variant. |
|
|
370
|
-
| `icon` | `ReactNode` | — | Custom icon element. |
|
|
371
|
-
| `duration` | `number` | Provider's `defaultDuration` | Auto-dismiss duration in ms. Use `0` to keep the toast until manually dismissed. |
|
|
372
|
-
|
|
373
|
-
### ToastData
|
|
374
|
-
|
|
375
|
-
Internal data structure for a toast instance (available via `ToastContext`).
|
|
376
|
-
|
|
377
|
-
| Property | Type | Description |
|
|
378
|
-
| :------- | :--- | :---------- |
|
|
379
|
-
| `id` | `string` | Unique identifier generated by the provider. |
|
|
380
|
-
| `variant` | `ToastVariant` | The toast variant. |
|
|
381
|
-
| `message` | `string` | Toast message text. |
|
|
382
|
-
| `icon` | `ReactNode \| undefined` | Custom icon, if provided. |
|
|
383
|
-
| `duration` | `number \| undefined` | Auto-dismiss duration. |
|
|
384
|
-
|
|
385
|
-
### ToastContext
|
|
386
284
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
return <span>Active toasts: {ctx.toasts.length}</span>;
|
|
285
|
+
export default function App() {
|
|
286
|
+
return (
|
|
287
|
+
<XUIProvider initialMode="dark">
|
|
288
|
+
<ToastProvider position="top">
|
|
289
|
+
<View style={{ flex: 1 }}>
|
|
290
|
+
<Trigger />
|
|
291
|
+
</View>
|
|
292
|
+
</ToastProvider>
|
|
293
|
+
</XUIProvider>
|
|
294
|
+
);
|
|
398
295
|
}
|
|
399
296
|
```
|
|
400
297
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
| Variant | Use Case | Default Icon | Icon Color Theme Path |
|
|
404
|
-
| :------ | :------- | :----------- | :-------------------- |
|
|
405
|
-
| `success` | Positive outcomes, confirmations | `<Check />` | `theme.colors.content.success.primary` |
|
|
406
|
-
| `info` | General information, neutral messages | `<AlertCircle />` | `theme.colors.content.inverse` |
|
|
407
|
-
| `warning` | Caution, requires user attention | `<AlertCircle />` | `theme.colors.content.warning.primary` |
|
|
408
|
-
| `error` | Errors, failures, critical issues | `<AlertCircle />` | `theme.colors.content.alert.primary` |
|
|
409
|
-
|
|
410
|
-
## Theming
|
|
411
|
-
|
|
412
|
-
Toast uses the **inverse** color scheme (dark background with light text) to stand out from the application content:
|
|
413
|
-
|
|
414
|
-
### Colors
|
|
415
|
-
|
|
416
|
-
```typescript
|
|
417
|
-
theme.colors.background.inverse // Toast background
|
|
418
|
-
theme.colors.content.inverse // Toast text and info icon color
|
|
419
|
-
|
|
420
|
-
theme.colors.content.success.primary // Success icon color
|
|
421
|
-
theme.colors.content.warning.primary // Warning icon color
|
|
422
|
-
theme.colors.content.alert.primary // Error icon color
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
### Sizing
|
|
426
|
-
|
|
427
|
-
Toast dimensions come from `theme.sizing.toast()`:
|
|
428
|
-
|
|
429
|
-
| Token | Value | Description |
|
|
430
|
-
| :---- | :---- | :---------- |
|
|
431
|
-
| `minHeight` | `64` | Minimum toast height |
|
|
432
|
-
| `paddingHorizontal` | `12` | Left/right padding |
|
|
433
|
-
| `paddingVertical` | `8` | Top/bottom padding |
|
|
434
|
-
| `borderRadius` | `4` | Corner radius |
|
|
435
|
-
| `gap` | `12` | Space between icon, text, and close button |
|
|
436
|
-
| `iconSize` | `24` | Icon dimensions |
|
|
437
|
-
| `closeButtonSize` | `24` | Close button tap target |
|
|
438
|
-
| `closeIconSize` | `20` | Close icon dimensions |
|
|
439
|
-
| `fontSize` | `16` | Message text size |
|
|
440
|
-
| `lineHeight` | `20` | Message line height |
|
|
441
|
-
| `maxWidth` | `400` | Maximum toast width (theme default; overridden by `ToastProvider maxWidth` prop) |
|
|
442
|
-
| `containerPadding` | `12` | Padding between toast container and screen edges |
|
|
443
|
-
| `groupGap` | `4` | Vertical gap between stacked toasts |
|
|
444
|
-
|
|
445
|
-
## Platform Support
|
|
446
|
-
|
|
447
|
-
This package supports both React (web) and React Native with an identical API.
|
|
448
|
-
|
|
449
|
-
### React (Web)
|
|
450
|
-
|
|
451
|
-
- Uses `ReactDOM.createPortal` to render toasts at the document body level
|
|
452
|
-
- Toasts appear above all other content regardless of z-index stacking contexts
|
|
453
|
-
- Works with any React web framework (Next.js, Vite, Create React App, Remix, etc.)
|
|
454
|
-
|
|
455
|
-
### React Native
|
|
456
|
-
|
|
457
|
-
- Uses absolute positioning within the app container
|
|
458
|
-
- Toasts render within the component tree (no portal equivalent in RN)
|
|
459
|
-
- Works with React Navigation, Expo, and bare React Native projects
|
|
298
|
+
## Platform support
|
|
460
299
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
|
464
|
-
| :------ | :-- | :----------- |
|
|
465
|
-
| Provider setup | `ToastProvider` | `XUIProvider` + `ToastProvider` |
|
|
466
|
-
| Hook API | `useToast()` | `useToast()` (identical) |
|
|
300
|
+
| Aspect | Web | React Native |
|
|
301
|
+
| --- | --- | --- |
|
|
302
|
+
| Rendering | `ReactDOM.createPortal` to `document.body` | Absolute-positioned `Box` in tree |
|
|
467
303
|
| Event handlers | `onClick` | `onPress` |
|
|
468
304
|
| Root container | Any element | Must have `flex: 1` |
|
|
469
|
-
| Position: top | Fixed to viewport top | Absolute to container top |
|
|
470
|
-
| Position: bottom | Fixed to viewport bottom | Absolute to container bottom |
|
|
471
|
-
| Rendering | `ReactDOM.createPortal` into `document.body` | Absolute-positioned `Box` in tree |
|
|
472
|
-
|
|
473
|
-
### React Native Example with Navigation
|
|
474
|
-
|
|
475
|
-
```tsx
|
|
476
|
-
import React from 'react';
|
|
477
|
-
import { NavigationContainer } from '@react-navigation/native';
|
|
478
|
-
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
479
|
-
import { XUIProvider } from '@xsolla/xui-core';
|
|
480
|
-
import { ToastProvider } from '@xsolla/xui-toast';
|
|
481
|
-
import { RootNavigator } from './navigation';
|
|
482
|
-
|
|
483
|
-
export default function App() {
|
|
484
|
-
return (
|
|
485
|
-
<SafeAreaProvider>
|
|
486
|
-
<XUIProvider mode="dark">
|
|
487
|
-
<ToastProvider position="top">
|
|
488
|
-
<NavigationContainer>
|
|
489
|
-
<RootNavigator />
|
|
490
|
-
</NavigationContainer>
|
|
491
|
-
</ToastProvider>
|
|
492
|
-
</XUIProvider>
|
|
493
|
-
</SafeAreaProvider>
|
|
494
|
-
);
|
|
495
|
-
}
|
|
496
|
-
```
|
|
497
305
|
|
|
498
306
|
## Accessibility
|
|
499
307
|
|
|
500
|
-
- Each toast renders with `role="alert"` and `aria-live="polite"` for
|
|
501
|
-
- The close button
|
|
502
|
-
-
|
|
503
|
-
-
|
|
504
|
-
- Toast messages are limited to 2 lines (`numberOfLines={2}`) for readability
|
|
308
|
+
- Each toast renders with `role="alert"` and `aria-live="polite"` for assistive technology.
|
|
309
|
+
- The close button has `aria-label="Dismiss toast"` and is keyboard-focusable.
|
|
310
|
+
- Default icons are decorative.
|
|
311
|
+
- Messages clamp to 2 lines for readability.
|
|
505
312
|
|
|
506
313
|
## Troubleshooting
|
|
507
314
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
```tsx
|
|
513
|
-
// Correct — hook is inside the provider tree
|
|
514
|
-
<ToastProvider>
|
|
515
|
-
<ComponentThatCallsUseToast />
|
|
516
|
-
</ToastProvider>
|
|
517
|
-
|
|
518
|
-
// Wrong — hook is outside the provider
|
|
519
|
-
<ComponentThatCallsUseToast />
|
|
520
|
-
<ToastProvider>
|
|
521
|
-
<OtherContent />
|
|
522
|
-
</ToastProvider>
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
### Toasts not visible on React Native
|
|
526
|
-
|
|
527
|
-
Make sure the container inside `ToastProvider` has `flex: 1`. Without this, the absolute-positioned toast group has no reference height:
|
|
528
|
-
|
|
529
|
-
```tsx
|
|
530
|
-
<ToastProvider>
|
|
531
|
-
<View style={{ flex: 1 }}> {/* Required */}
|
|
532
|
-
<App />
|
|
533
|
-
</View>
|
|
534
|
-
</ToastProvider>
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
### Toasts appear behind a modal or overlay
|
|
538
|
-
|
|
539
|
-
On web, `ToastGroup` uses `z-index: 9999`. If your modal or overlay uses a higher z-index, the toasts may be hidden. Consider placing the `ToastProvider` above your modal provider in the tree, or adjusting z-index values.
|
|
315
|
+
- **"useToast must be used within a ToastProvider"** — ensure the calling component is a descendant of `ToastProvider`.
|
|
316
|
+
- **Toasts hidden on React Native** — wrap content in `<View style={{ flex: 1 }}>` inside `ToastProvider`.
|
|
317
|
+
- **Toasts appear behind a modal (web)** — `ToastGroup` uses `z-index: 9999`. Place `ToastProvider` above the modal in the tree, or adjust z-index.
|
|
318
|
+
- **Auto-dismiss not working** — `duration: 0` disables auto-dismiss; check both per-toast and provider defaults.
|
|
540
319
|
|
|
541
|
-
|
|
320
|
+
## Related
|
|
542
321
|
|
|
543
|
-
|
|
322
|
+
- [Notification](./notification.md) — declarative toast/inline notification.
|
|
323
|
+
- [NotificationPanel](./notification-panel.md) — full-width inline banner.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsolla/xui-toast",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.152.0",
|
|
4
4
|
"main": "./web/index.js",
|
|
5
5
|
"module": "./web/index.mjs",
|
|
6
6
|
"types": "./web/index.d.ts",
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"test:coverage": "vitest run --coverage"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@xsolla/xui-core": "0.
|
|
18
|
-
"@xsolla/xui-icons": "0.
|
|
19
|
-
"@xsolla/xui-primitives-core": "0.
|
|
17
|
+
"@xsolla/xui-core": "0.152.0",
|
|
18
|
+
"@xsolla/xui-icons": "0.152.0",
|
|
19
|
+
"@xsolla/xui-primitives-core": "0.152.0"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"react": ">=16.8.0",
|