@samline/notify 0.1.15 → 0.2.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 +57 -7
- package/dist/index.cjs.js +46 -4
- package/dist/index.esm.js +46 -4
- package/dist/notify.umd.js +46 -4
- package/docs/browser.md +49 -1
- package/docs/react.md +194 -2
- package/docs/svelte.md +194 -2
- package/docs/vanilla.md +189 -32
- package/docs/vue.md +201 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
|
|
1
2
|
## @samline/notify
|
|
2
3
|
|
|
3
|
-
A
|
|
4
|
+
A universal toast notification library powered by Sileo, designed to bring the same beautiful, animated experience to React, Vue, Svelte, and Vanilla JS. Built for teams who need Sileo’s quality and API, but require seamless integration across multiple frameworks.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Powered by Sileo — see the original project: https://github.com/hiaaryan/sileo
|
|
6
7
|
|
|
7
8
|
Table of Contents
|
|
8
9
|
|
|
@@ -100,18 +101,67 @@ notify.clear()
|
|
|
100
101
|
|
|
101
102
|
When using the UMD/browser bundle the global is exposed as `window.notify` (preferred). For compatibility the API object also exposes `window.notifications` which maintains the previous shape.
|
|
102
103
|
|
|
103
|
-
Shared Options
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
Shared Options (All Entrypoints)
|
|
106
|
+
|
|
107
|
+
All notification methods accept a rich set of options for full customization:
|
|
106
108
|
|
|
107
109
|
| Property | Type | Default | Description |
|
|
108
110
|
| ------------- | -------------------------------------- | ----------- | ------------------------------------------- |
|
|
109
111
|
| `title` | string | — | Toast title |
|
|
110
|
-
| `description` | string
|
|
111
|
-
| `type` | `info\|success\|error\|warning
|
|
112
|
+
| `description` | string \| ReactNode \| SvelteNode | — | Optional body text (JSX, HTML, or string) |
|
|
113
|
+
| `type` | `info\|success\|error\|warning\|action`| `info` | Visual intent |
|
|
112
114
|
| `position` | string | `top-right` | One of toast positions |
|
|
113
|
-
| `duration` | number
|
|
115
|
+
| `duration` | number \| null | `4000` | Auto-dismiss timeout in ms (null = sticky) |
|
|
114
116
|
| `button` | { title: string, onClick: () => void } | — | Optional action button |
|
|
117
|
+
| `icon` | string \| ReactNode \| SvelteNode | — | Custom icon (SVG, JSX, or node) |
|
|
118
|
+
| `fill` | string | — | Custom background color (SVG or badge) |
|
|
119
|
+
| `styles` | { title, description, badge, button } | — | Custom class overrides for sub-elements |
|
|
120
|
+
| `roundness` | number | 16 | Border radius in pixels |
|
|
121
|
+
| `autopilot` | boolean \| object | true | Auto expand/collapse timing |
|
|
122
|
+
|
|
123
|
+
#### Example: Advanced Toast
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
notify.success({
|
|
127
|
+
title: "Styled!",
|
|
128
|
+
fill: "#222",
|
|
129
|
+
icon: '<svg>...</svg>',
|
|
130
|
+
styles: {
|
|
131
|
+
title: "text-white!",
|
|
132
|
+
badge: "bg-white/20!",
|
|
133
|
+
button: "bg-white/10!"
|
|
134
|
+
},
|
|
135
|
+
roundness: 24,
|
|
136
|
+
autopilot: false
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### SileoPromiseOptions
|
|
141
|
+
|
|
142
|
+
The `promise` method supports advanced flows:
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
notify.promise(fetchData(), {
|
|
146
|
+
loading: { title: "Loading..." },
|
|
147
|
+
success: (data) => ({ title: `Loaded ${data.name}` }),
|
|
148
|
+
error: (err) => ({ title: "Error", description: err.message }),
|
|
149
|
+
action: (data) => ({ title: "Action required", button: { title: "Retry", onClick: () => retry() } })
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### Toaster Component Props (React, Svelte, Vue, Vanilla)
|
|
154
|
+
|
|
155
|
+
All Toaster components accept the following props for global control:
|
|
156
|
+
|
|
157
|
+
| Prop | Type | Default | Description |
|
|
158
|
+
| --------- | ----------------------------------------- | ------------ | ------------------------------------------- |
|
|
159
|
+
| `position`| string | top-right | Default toast position |
|
|
160
|
+
| `offset` | number \| string \| {top,right,bottom,left}| 0 | Distance from viewport edges |
|
|
161
|
+
| `options` | Partial<Options> | — | Default options for all toasts |
|
|
162
|
+
| `theme` | "light" \| "dark" \| "system" | system | Color scheme (auto, light, dark) |
|
|
163
|
+
|
|
164
|
+
See framework-specific guides for more examples.
|
|
115
165
|
|
|
116
166
|
Notes
|
|
117
167
|
|
package/dist/index.cjs.js
CHANGED
|
@@ -24,8 +24,21 @@ class NotifyController {
|
|
|
24
24
|
return this.toasts.slice();
|
|
25
25
|
}
|
|
26
26
|
show(opts) {
|
|
27
|
+
// Normalizar props avanzadas
|
|
28
|
+
const { icon, fill, styles, roundness, autopilot, ...rest } = opts;
|
|
27
29
|
const id = this.nextId();
|
|
28
|
-
const item = {
|
|
30
|
+
const item = {
|
|
31
|
+
id,
|
|
32
|
+
options: {
|
|
33
|
+
...rest,
|
|
34
|
+
...(icon !== undefined ? { icon } : {}),
|
|
35
|
+
...(fill !== undefined ? { fill } : {}),
|
|
36
|
+
...(styles !== undefined ? { styles } : {}),
|
|
37
|
+
...(roundness !== undefined ? { roundness } : {}),
|
|
38
|
+
...(autopilot !== undefined ? { autopilot } : {}),
|
|
39
|
+
},
|
|
40
|
+
createdAt: Date.now(),
|
|
41
|
+
};
|
|
29
42
|
this.toasts.push(item);
|
|
30
43
|
this.notify();
|
|
31
44
|
return id;
|
|
@@ -65,6 +78,13 @@ class NotifyController {
|
|
|
65
78
|
const loadingId = this.show({ ...(opts.loading || {}), type: 'loading', position: opts.position });
|
|
66
79
|
p.then((res) => {
|
|
67
80
|
this.dismiss(loadingId);
|
|
81
|
+
if (opts.action) {
|
|
82
|
+
const actionOpt = typeof opts.action === 'function' ? opts.action(res) : opts.action;
|
|
83
|
+
if (actionOpt) {
|
|
84
|
+
this.show({ ...(actionOpt || {}), type: 'action', position: opts.position });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
68
88
|
const successOpt = typeof opts.success === 'function' ? opts.success(res) : opts.success;
|
|
69
89
|
if (successOpt)
|
|
70
90
|
this.show({ ...(successOpt || {}), type: 'success', position: opts.position });
|
|
@@ -1006,12 +1026,30 @@ const POSITIONS = [
|
|
|
1006
1026
|
'bottom-center',
|
|
1007
1027
|
'bottom-right'
|
|
1008
1028
|
];
|
|
1009
|
-
function createContainer(position, root) {
|
|
1029
|
+
function createContainer(position, root, opts) {
|
|
1010
1030
|
const c = document.createElement('div');
|
|
1011
1031
|
c.className = 'sileo-toaster';
|
|
1012
1032
|
c.setAttribute('data-position', position);
|
|
1013
1033
|
c.setAttribute('role', 'status');
|
|
1014
1034
|
c.setAttribute('aria-live', 'polite');
|
|
1035
|
+
if (opts === null || opts === void 0 ? void 0 : opts.theme)
|
|
1036
|
+
c.setAttribute('data-theme', opts.theme);
|
|
1037
|
+
// offset
|
|
1038
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.offset) !== undefined) {
|
|
1039
|
+
if (typeof opts.offset === 'number' || typeof opts.offset === 'string') {
|
|
1040
|
+
c.style.margin = typeof opts.offset === 'number' ? `${opts.offset}px` : opts.offset;
|
|
1041
|
+
}
|
|
1042
|
+
else if (typeof opts.offset === 'object') {
|
|
1043
|
+
if (opts.offset.top !== undefined)
|
|
1044
|
+
c.style.marginTop = `${opts.offset.top}px`;
|
|
1045
|
+
if (opts.offset.right !== undefined)
|
|
1046
|
+
c.style.marginRight = `${opts.offset.right}px`;
|
|
1047
|
+
if (opts.offset.bottom !== undefined)
|
|
1048
|
+
c.style.marginBottom = `${opts.offset.bottom}px`;
|
|
1049
|
+
if (opts.offset.left !== undefined)
|
|
1050
|
+
c.style.marginLeft = `${opts.offset.left}px`;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1015
1053
|
return c;
|
|
1016
1054
|
}
|
|
1017
1055
|
function renderToast(item) {
|
|
@@ -1065,13 +1103,17 @@ function renderToast(item) {
|
|
|
1065
1103
|
}
|
|
1066
1104
|
return el;
|
|
1067
1105
|
}
|
|
1068
|
-
function initToasters(root = document.body, positions = ['top-right']) {
|
|
1106
|
+
function initToasters(root = document.body, positions = ['top-right'], opts) {
|
|
1069
1107
|
const containers = {};
|
|
1070
1108
|
positions.forEach((pos) => {
|
|
1071
|
-
const c = createContainer(pos);
|
|
1109
|
+
const c = createContainer(pos, root, opts);
|
|
1072
1110
|
root.appendChild(c);
|
|
1073
1111
|
containers[pos] = c;
|
|
1074
1112
|
});
|
|
1113
|
+
if (opts === null || opts === void 0 ? void 0 : opts.options)
|
|
1114
|
+
window.sileo._globalOptions = opts.options;
|
|
1115
|
+
if (opts === null || opts === void 0 ? void 0 : opts.theme)
|
|
1116
|
+
window.sileo._theme = opts.theme;
|
|
1075
1117
|
function rerender(items) {
|
|
1076
1118
|
positions.forEach((pos) => {
|
|
1077
1119
|
const container = containers[pos];
|
package/dist/index.esm.js
CHANGED
|
@@ -20,8 +20,21 @@ class NotifyController {
|
|
|
20
20
|
return this.toasts.slice();
|
|
21
21
|
}
|
|
22
22
|
show(opts) {
|
|
23
|
+
// Normalizar props avanzadas
|
|
24
|
+
const { icon, fill, styles, roundness, autopilot, ...rest } = opts;
|
|
23
25
|
const id = this.nextId();
|
|
24
|
-
const item = {
|
|
26
|
+
const item = {
|
|
27
|
+
id,
|
|
28
|
+
options: {
|
|
29
|
+
...rest,
|
|
30
|
+
...(icon !== undefined ? { icon } : {}),
|
|
31
|
+
...(fill !== undefined ? { fill } : {}),
|
|
32
|
+
...(styles !== undefined ? { styles } : {}),
|
|
33
|
+
...(roundness !== undefined ? { roundness } : {}),
|
|
34
|
+
...(autopilot !== undefined ? { autopilot } : {}),
|
|
35
|
+
},
|
|
36
|
+
createdAt: Date.now(),
|
|
37
|
+
};
|
|
25
38
|
this.toasts.push(item);
|
|
26
39
|
this.notify();
|
|
27
40
|
return id;
|
|
@@ -61,6 +74,13 @@ class NotifyController {
|
|
|
61
74
|
const loadingId = this.show({ ...(opts.loading || {}), type: 'loading', position: opts.position });
|
|
62
75
|
p.then((res) => {
|
|
63
76
|
this.dismiss(loadingId);
|
|
77
|
+
if (opts.action) {
|
|
78
|
+
const actionOpt = typeof opts.action === 'function' ? opts.action(res) : opts.action;
|
|
79
|
+
if (actionOpt) {
|
|
80
|
+
this.show({ ...(actionOpt || {}), type: 'action', position: opts.position });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
64
84
|
const successOpt = typeof opts.success === 'function' ? opts.success(res) : opts.success;
|
|
65
85
|
if (successOpt)
|
|
66
86
|
this.show({ ...(successOpt || {}), type: 'success', position: opts.position });
|
|
@@ -1002,12 +1022,30 @@ const POSITIONS = [
|
|
|
1002
1022
|
'bottom-center',
|
|
1003
1023
|
'bottom-right'
|
|
1004
1024
|
];
|
|
1005
|
-
function createContainer(position, root) {
|
|
1025
|
+
function createContainer(position, root, opts) {
|
|
1006
1026
|
const c = document.createElement('div');
|
|
1007
1027
|
c.className = 'sileo-toaster';
|
|
1008
1028
|
c.setAttribute('data-position', position);
|
|
1009
1029
|
c.setAttribute('role', 'status');
|
|
1010
1030
|
c.setAttribute('aria-live', 'polite');
|
|
1031
|
+
if (opts === null || opts === void 0 ? void 0 : opts.theme)
|
|
1032
|
+
c.setAttribute('data-theme', opts.theme);
|
|
1033
|
+
// offset
|
|
1034
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.offset) !== undefined) {
|
|
1035
|
+
if (typeof opts.offset === 'number' || typeof opts.offset === 'string') {
|
|
1036
|
+
c.style.margin = typeof opts.offset === 'number' ? `${opts.offset}px` : opts.offset;
|
|
1037
|
+
}
|
|
1038
|
+
else if (typeof opts.offset === 'object') {
|
|
1039
|
+
if (opts.offset.top !== undefined)
|
|
1040
|
+
c.style.marginTop = `${opts.offset.top}px`;
|
|
1041
|
+
if (opts.offset.right !== undefined)
|
|
1042
|
+
c.style.marginRight = `${opts.offset.right}px`;
|
|
1043
|
+
if (opts.offset.bottom !== undefined)
|
|
1044
|
+
c.style.marginBottom = `${opts.offset.bottom}px`;
|
|
1045
|
+
if (opts.offset.left !== undefined)
|
|
1046
|
+
c.style.marginLeft = `${opts.offset.left}px`;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1011
1049
|
return c;
|
|
1012
1050
|
}
|
|
1013
1051
|
function renderToast(item) {
|
|
@@ -1061,13 +1099,17 @@ function renderToast(item) {
|
|
|
1061
1099
|
}
|
|
1062
1100
|
return el;
|
|
1063
1101
|
}
|
|
1064
|
-
function initToasters(root = document.body, positions = ['top-right']) {
|
|
1102
|
+
function initToasters(root = document.body, positions = ['top-right'], opts) {
|
|
1065
1103
|
const containers = {};
|
|
1066
1104
|
positions.forEach((pos) => {
|
|
1067
|
-
const c = createContainer(pos);
|
|
1105
|
+
const c = createContainer(pos, root, opts);
|
|
1068
1106
|
root.appendChild(c);
|
|
1069
1107
|
containers[pos] = c;
|
|
1070
1108
|
});
|
|
1109
|
+
if (opts === null || opts === void 0 ? void 0 : opts.options)
|
|
1110
|
+
window.sileo._globalOptions = opts.options;
|
|
1111
|
+
if (opts === null || opts === void 0 ? void 0 : opts.theme)
|
|
1112
|
+
window.sileo._theme = opts.theme;
|
|
1071
1113
|
function rerender(items) {
|
|
1072
1114
|
positions.forEach((pos) => {
|
|
1073
1115
|
const container = containers[pos];
|
package/dist/notify.umd.js
CHANGED
|
@@ -26,8 +26,21 @@
|
|
|
26
26
|
return this.toasts.slice();
|
|
27
27
|
}
|
|
28
28
|
show(opts) {
|
|
29
|
+
// Normalizar props avanzadas
|
|
30
|
+
const { icon, fill, styles, roundness, autopilot, ...rest } = opts;
|
|
29
31
|
const id = this.nextId();
|
|
30
|
-
const item = {
|
|
32
|
+
const item = {
|
|
33
|
+
id,
|
|
34
|
+
options: {
|
|
35
|
+
...rest,
|
|
36
|
+
...(icon !== undefined ? { icon } : {}),
|
|
37
|
+
...(fill !== undefined ? { fill } : {}),
|
|
38
|
+
...(styles !== undefined ? { styles } : {}),
|
|
39
|
+
...(roundness !== undefined ? { roundness } : {}),
|
|
40
|
+
...(autopilot !== undefined ? { autopilot } : {}),
|
|
41
|
+
},
|
|
42
|
+
createdAt: Date.now(),
|
|
43
|
+
};
|
|
31
44
|
this.toasts.push(item);
|
|
32
45
|
this.notify();
|
|
33
46
|
return id;
|
|
@@ -67,6 +80,13 @@
|
|
|
67
80
|
const loadingId = this.show({ ...(opts.loading || {}), type: 'loading', position: opts.position });
|
|
68
81
|
p.then((res) => {
|
|
69
82
|
this.dismiss(loadingId);
|
|
83
|
+
if (opts.action) {
|
|
84
|
+
const actionOpt = typeof opts.action === 'function' ? opts.action(res) : opts.action;
|
|
85
|
+
if (actionOpt) {
|
|
86
|
+
this.show({ ...(actionOpt || {}), type: 'action', position: opts.position });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
70
90
|
const successOpt = typeof opts.success === 'function' ? opts.success(res) : opts.success;
|
|
71
91
|
if (successOpt)
|
|
72
92
|
this.show({ ...(successOpt || {}), type: 'success', position: opts.position });
|
|
@@ -1008,12 +1028,30 @@
|
|
|
1008
1028
|
'bottom-center',
|
|
1009
1029
|
'bottom-right'
|
|
1010
1030
|
];
|
|
1011
|
-
function createContainer(position, root) {
|
|
1031
|
+
function createContainer(position, root, opts) {
|
|
1012
1032
|
const c = document.createElement('div');
|
|
1013
1033
|
c.className = 'sileo-toaster';
|
|
1014
1034
|
c.setAttribute('data-position', position);
|
|
1015
1035
|
c.setAttribute('role', 'status');
|
|
1016
1036
|
c.setAttribute('aria-live', 'polite');
|
|
1037
|
+
if (opts === null || opts === void 0 ? void 0 : opts.theme)
|
|
1038
|
+
c.setAttribute('data-theme', opts.theme);
|
|
1039
|
+
// offset
|
|
1040
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.offset) !== undefined) {
|
|
1041
|
+
if (typeof opts.offset === 'number' || typeof opts.offset === 'string') {
|
|
1042
|
+
c.style.margin = typeof opts.offset === 'number' ? `${opts.offset}px` : opts.offset;
|
|
1043
|
+
}
|
|
1044
|
+
else if (typeof opts.offset === 'object') {
|
|
1045
|
+
if (opts.offset.top !== undefined)
|
|
1046
|
+
c.style.marginTop = `${opts.offset.top}px`;
|
|
1047
|
+
if (opts.offset.right !== undefined)
|
|
1048
|
+
c.style.marginRight = `${opts.offset.right}px`;
|
|
1049
|
+
if (opts.offset.bottom !== undefined)
|
|
1050
|
+
c.style.marginBottom = `${opts.offset.bottom}px`;
|
|
1051
|
+
if (opts.offset.left !== undefined)
|
|
1052
|
+
c.style.marginLeft = `${opts.offset.left}px`;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1017
1055
|
return c;
|
|
1018
1056
|
}
|
|
1019
1057
|
function renderToast(item) {
|
|
@@ -1067,13 +1105,17 @@
|
|
|
1067
1105
|
}
|
|
1068
1106
|
return el;
|
|
1069
1107
|
}
|
|
1070
|
-
function initToasters(root = document.body, positions = ['top-right']) {
|
|
1108
|
+
function initToasters(root = document.body, positions = ['top-right'], opts) {
|
|
1071
1109
|
const containers = {};
|
|
1072
1110
|
positions.forEach((pos) => {
|
|
1073
|
-
const c = createContainer(pos);
|
|
1111
|
+
const c = createContainer(pos, root, opts);
|
|
1074
1112
|
root.appendChild(c);
|
|
1075
1113
|
containers[pos] = c;
|
|
1076
1114
|
});
|
|
1115
|
+
if (opts === null || opts === void 0 ? void 0 : opts.options)
|
|
1116
|
+
window.sileo._globalOptions = opts.options;
|
|
1117
|
+
if (opts === null || opts === void 0 ? void 0 : opts.theme)
|
|
1118
|
+
window.sileo._theme = opts.theme;
|
|
1077
1119
|
function rerender(items) {
|
|
1078
1120
|
positions.forEach((pos) => {
|
|
1079
1121
|
const container = containers[pos];
|
package/docs/browser.md
CHANGED
|
@@ -19,13 +19,61 @@ Add the stylesheet and UMD bundle to your HTML:
|
|
|
19
19
|
</script>
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
|
|
22
23
|
## API
|
|
23
24
|
|
|
24
25
|
- The UMD bundle exposes `window.notify` (recommended) and `window.notifications` (legacy/compatibility).
|
|
25
26
|
- Always include `dist/styles.css` for correct appearance and animations.
|
|
26
|
-
- Use `api.initToasters(container, positions)` to mount containers (usually `document.body`).
|
|
27
|
+
- Use `api.initToasters(container, positions, { offset, options, theme })` to mount containers (usually `document.body`).
|
|
27
28
|
- Use `api.notify({...})` to show a notification.
|
|
28
29
|
|
|
30
|
+
### Advanced Options
|
|
31
|
+
|
|
32
|
+
All notification methods accept advanced options:
|
|
33
|
+
|
|
34
|
+
| Property | Type | Default | Description |
|
|
35
|
+
| ------------- | -------------------------------------- | ----------- | ------------------------------------------- |
|
|
36
|
+
| `title` | string | — | Toast title |
|
|
37
|
+
| `description` | string | — | Optional body text (HTML or string) |
|
|
38
|
+
| `type` | `info\|success\|error\|warning\|action`| `info` | Visual intent |
|
|
39
|
+
| `position` | string | `top-right` | One of toast positions |
|
|
40
|
+
| `duration` | number \| null | `4000` | Auto-dismiss timeout in ms (null = sticky) |
|
|
41
|
+
| `button` | { title: string, onClick: () => void } | — | Optional action button |
|
|
42
|
+
| `icon` | string | — | Custom icon (SVG or HTML) |
|
|
43
|
+
| `fill` | string | — | Custom background color (SVG or badge) |
|
|
44
|
+
| `styles` | { title, description, badge, button } | — | Custom class overrides for sub-elements |
|
|
45
|
+
| `roundness` | number | 16 | Border radius in pixels |
|
|
46
|
+
| `autopilot` | boolean \| object | true | Auto expand/collapse timing |
|
|
47
|
+
|
|
48
|
+
#### Example: Advanced Toast
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
api.success({
|
|
52
|
+
title: "Styled!",
|
|
53
|
+
fill: "#222",
|
|
54
|
+
icon: '<svg>...</svg>',
|
|
55
|
+
styles: {
|
|
56
|
+
title: "text-white!",
|
|
57
|
+
badge: "bg-white/20!",
|
|
58
|
+
button: "bg-white/10!"
|
|
59
|
+
},
|
|
60
|
+
roundness: 24,
|
|
61
|
+
autopilot: false
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Toaster Options
|
|
66
|
+
|
|
67
|
+
You can pass advanced options to `initToasters`:
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
api.initToasters(document.body, ['top-right'], {
|
|
71
|
+
offset: { top: 32, right: 16 },
|
|
72
|
+
options: { fill: '#222', roundness: 20 },
|
|
73
|
+
theme: 'dark'
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
29
77
|
## Notes
|
|
30
78
|
|
|
31
79
|
- If you need more control or want to avoid global variables, use the ESM/CJS builds with a bundler.
|
package/docs/react.md
CHANGED
|
@@ -26,6 +26,50 @@ export function App() {
|
|
|
26
26
|
}
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
## Methods: Full Examples
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
// Show a generic toast
|
|
33
|
+
notify.show({ title: 'Hello', description: 'Generic toast', type: 'info' });
|
|
34
|
+
|
|
35
|
+
// Success toast
|
|
36
|
+
notify.success({ title: 'Success!', description: 'Operation completed.' });
|
|
37
|
+
|
|
38
|
+
// Error toast
|
|
39
|
+
notify.error({ title: 'Error', description: 'Something went wrong.' });
|
|
40
|
+
|
|
41
|
+
// Info toast
|
|
42
|
+
notify.info({ title: 'Heads up!', description: 'This is an info toast.' });
|
|
43
|
+
|
|
44
|
+
// Warning toast
|
|
45
|
+
notify.warning({ title: 'Warning!', description: 'Be careful.' });
|
|
46
|
+
|
|
47
|
+
// Action toast with button
|
|
48
|
+
notify.action({
|
|
49
|
+
title: 'Action required',
|
|
50
|
+
description: 'Click the button to proceed.',
|
|
51
|
+
button: { title: 'Proceed', onClick: () => alert('Action!') }
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Promise toast (loading, success, error, action)
|
|
55
|
+
notify.promise(fetch('/api/save'), {
|
|
56
|
+
loading: { title: 'Saving...' },
|
|
57
|
+
success: { title: 'Saved!', description: 'Your data was saved.' },
|
|
58
|
+
error: { title: 'Failed', description: 'Could not save.' },
|
|
59
|
+
action: { title: 'Retry?', button: { title: 'Retry', onClick: () => {/* retry logic */} } }
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Dismiss a toast by id
|
|
63
|
+
const id = notify.success({ title: 'Dismiss me' });
|
|
64
|
+
notify.dismiss(id);
|
|
65
|
+
|
|
66
|
+
// Clear all toasts
|
|
67
|
+
notify.clear();
|
|
68
|
+
|
|
69
|
+
// Clear only a position
|
|
70
|
+
notify.clear('top-right');
|
|
71
|
+
```
|
|
72
|
+
|
|
29
73
|
> **Note:**
|
|
30
74
|
> Import `@samline/notify/dist/styles.css` in your main entrypoint or include it in your HTML for correct appearance.
|
|
31
75
|
> CDN: `<link rel="stylesheet" href="https://unpkg.com/@samline/notify@0.1.15/dist/styles.css">`
|
|
@@ -52,12 +96,160 @@ notify.clear()
|
|
|
52
96
|
|
|
53
97
|
### Options
|
|
54
98
|
|
|
99
|
+
All notification methods accept advanced options:
|
|
100
|
+
|
|
55
101
|
| Property | Type | Default | Description |
|
|
56
102
|
| ------------- | -------------------------------------- | ----------- | ------------------------------------------- |
|
|
57
103
|
| `title` | string | — | Toast title |
|
|
58
|
-
| `description` | string
|
|
59
|
-
| `type` | `info\|success\|error\|warning
|
|
104
|
+
| `description` | string \| ReactNode | — | Optional body text (JSX or string) |
|
|
105
|
+
| `type` | `info\|success\|error\|warning\|action`| `info` | Visual intent |
|
|
60
106
|
| `position` | string | `top-right` | One of toast positions |
|
|
107
|
+
| `duration` | number \| null | `4000` | Auto-dismiss timeout in ms (null = sticky) |
|
|
108
|
+
| `button` | { title: string, onClick: () => void } | — | Optional action button |
|
|
109
|
+
| `icon` | string \| ReactNode | — | Custom icon (SVG or JSX) |
|
|
110
|
+
| `fill` | string | — | Custom background color (SVG or badge) |
|
|
111
|
+
| `styles` | { title, description, badge, button } | — | Custom class overrides for sub-elements |
|
|
112
|
+
| `roundness` | number | 16 | Border radius in pixels |
|
|
113
|
+
| `autopilot` | boolean \| object | true | Auto expand/collapse timing |
|
|
114
|
+
|
|
115
|
+
#### Example: Advanced Toasts
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
// Custom icon (SVG string or JSX)
|
|
119
|
+
notify.success({
|
|
120
|
+
title: 'With Icon',
|
|
121
|
+
icon: <svg width="16" height="16" ...>...</svg>
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Custom fill color
|
|
125
|
+
notify.info({
|
|
126
|
+
title: 'Colored',
|
|
127
|
+
fill: '#2563eb'
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Custom styles for sub-elements
|
|
131
|
+
notify.success({
|
|
132
|
+
title: 'Styled',
|
|
133
|
+
styles: {
|
|
134
|
+
title: 'my-title-class',
|
|
135
|
+
badge: 'my-badge-class',
|
|
136
|
+
button: 'my-btn-class'
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Custom roundness
|
|
141
|
+
notify.success({
|
|
142
|
+
title: 'Rounded',
|
|
143
|
+
roundness: 32
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Autopilot off (manual expand/collapse)
|
|
147
|
+
notify.success({
|
|
148
|
+
title: 'Manual',
|
|
149
|
+
autopilot: false
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Custom duration (sticky)
|
|
153
|
+
notify.info({
|
|
154
|
+
title: 'Sticky',
|
|
155
|
+
duration: null
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Custom position
|
|
159
|
+
notify.success({
|
|
160
|
+
title: 'Bottom left',
|
|
161
|
+
position: 'bottom-left'
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Description as ReactNode
|
|
165
|
+
notify.info({
|
|
166
|
+
title: 'JSX Description',
|
|
167
|
+
description: <span style={{ color: 'red' }}>Custom JSX content</span>
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### Example: Advanced Toast
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
notify.success({
|
|
175
|
+
title: "Styled!",
|
|
176
|
+
fill: "#222",
|
|
177
|
+
icon: '<svg>...</svg>',
|
|
178
|
+
styles: {
|
|
179
|
+
title: "text-white!",
|
|
180
|
+
badge: "bg-white/20!",
|
|
181
|
+
button: "bg-white/10!"
|
|
182
|
+
},
|
|
183
|
+
roundness: 24,
|
|
184
|
+
autopilot: false
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Promise Toasts
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
notify.promise(fetchData(), {
|
|
192
|
+
loading: { title: "Loading..." },
|
|
193
|
+
success: (data) => ({ title: `Loaded ${data.name}` }),
|
|
194
|
+
error: (err) => ({ title: "Error", description: err.message }),
|
|
195
|
+
action: (data) => ({ title: "Action required", button: { title: "Retry", onClick: () => retry() } })
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Toaster Component Props
|
|
200
|
+
|
|
201
|
+
The `<Toaster />` component accepts the following props:
|
|
202
|
+
|
|
203
|
+
| Prop | Type | Default | Description |
|
|
204
|
+
| --------- | ----------------------------------------- | ------------ | ------------------------------------------- |
|
|
205
|
+
| `position`| string | top-right | Default toast position |
|
|
206
|
+
| `offset` | number \| string \| {top,right,bottom,left}| 0 | Distance from viewport edges |
|
|
207
|
+
| `options` | Partial<Options> | — | Default options for all toasts |
|
|
208
|
+
| `theme` | "light" \| "dark" \| "system" | system | Color scheme (auto, light, dark) |
|
|
209
|
+
|
|
210
|
+
#### Example: Custom Toaster
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
<Toaster position="bottom-center" offset={24} theme="dark" options={{ fill: '#222', roundness: 20 }} />
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Customizing Styles
|
|
217
|
+
|
|
218
|
+
- Override CSS variables in your stylesheet or inline:
|
|
219
|
+
|
|
220
|
+
```css
|
|
221
|
+
:root {
|
|
222
|
+
--sileo-bg: #18181b;
|
|
223
|
+
--sileo-success: #22c55e;
|
|
224
|
+
--sileo-error: #ef4444;
|
|
225
|
+
--sileo-info: #2563eb;
|
|
226
|
+
--sileo-warning: #f59e0b;
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
- Add custom classes via the `styles` option for title, badge, button, description.
|
|
231
|
+
|
|
232
|
+
## Accessibility
|
|
233
|
+
|
|
234
|
+
- Toast containers use `role="status"` and `aria-live="polite"`.
|
|
235
|
+
- Respects `prefers-reduced-motion` for users with motion sensitivity.
|
|
236
|
+
|
|
237
|
+
## Common Errors & Troubleshooting
|
|
238
|
+
|
|
239
|
+
- **No styles?** Make sure to import or link `dist/styles.css`.
|
|
240
|
+
- **No animation?** Check that the `motion` dependency is installed for ESM/bundler usage.
|
|
241
|
+
- **Button not working?** Ensure your `onClick` is a function and not a string.
|
|
242
|
+
- **Nothing appears?** Confirm you rendered `<Toaster />` and are using the correct import.
|
|
243
|
+
|
|
244
|
+
## Migration & Best Practices
|
|
245
|
+
|
|
246
|
+
- If migrating from Sileo, all options and methods are compatible.
|
|
247
|
+
- Prefer using `notify.success`, `notify.error`, etc. for intent clarity.
|
|
248
|
+
- Use `notify.clear()` to remove all toasts, or pass a position to clear only one area.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
For other frameworks, see the Vue, Svelte, and Vanilla guides.
|
|
61
253
|
| `duration` | number | `4000` | Auto-dismiss timeout in ms (0 = persistent) |
|
|
62
254
|
| `button` | { title: string, onClick: () => void } | — | Optional action button |
|
|
63
255
|
|
package/docs/svelte.md
CHANGED
|
@@ -26,6 +26,50 @@ Import and initialize in your root component:
|
|
|
26
26
|
<button on:click={show}>Show</button>
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
## Methods: Full Examples
|
|
30
|
+
|
|
31
|
+
```svelte
|
|
32
|
+
// Show a generic toast
|
|
33
|
+
notify.show({ title: 'Hello', description: 'Generic toast', type: 'info' });
|
|
34
|
+
|
|
35
|
+
// Success toast
|
|
36
|
+
notify.success({ title: 'Success!', description: 'Operation completed.' });
|
|
37
|
+
|
|
38
|
+
// Error toast
|
|
39
|
+
notify.error({ title: 'Error', description: 'Something went wrong.' });
|
|
40
|
+
|
|
41
|
+
// Info toast
|
|
42
|
+
notify.info({ title: 'Heads up!', description: 'This is an info toast.' });
|
|
43
|
+
|
|
44
|
+
// Warning toast
|
|
45
|
+
notify.warning({ title: 'Warning!', description: 'Be careful.' });
|
|
46
|
+
|
|
47
|
+
// Action toast with button
|
|
48
|
+
notify.action({
|
|
49
|
+
title: 'Action required',
|
|
50
|
+
description: 'Click the button to proceed.',
|
|
51
|
+
button: { title: 'Proceed', onClick: () => alert('Action!') }
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Promise toast (loading, success, error, action)
|
|
55
|
+
notify.promise(fetch('/api/save'), {
|
|
56
|
+
loading: { title: 'Saving...' },
|
|
57
|
+
success: { title: 'Saved!', description: 'Your data was saved.' },
|
|
58
|
+
error: { title: 'Failed', description: 'Could not save.' },
|
|
59
|
+
action: { title: 'Retry?', button: { title: 'Retry', onClick: () => {/* retry logic */} } }
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Dismiss a toast by id
|
|
63
|
+
const id = notify.success({ title: 'Dismiss me' });
|
|
64
|
+
notify.dismiss(id);
|
|
65
|
+
|
|
66
|
+
// Clear all toasts
|
|
67
|
+
notify.clear();
|
|
68
|
+
|
|
69
|
+
// Clear only a position
|
|
70
|
+
notify.clear('top-right');
|
|
71
|
+
```
|
|
72
|
+
|
|
29
73
|
> **Note:**
|
|
30
74
|
> Import `@samline/notify/dist/styles.css` in your main entrypoint or HTML for correct appearance.
|
|
31
75
|
> CDN: `<link rel="stylesheet" href="https://unpkg.com/@samline/notify@0.1.15/dist/styles.css">`
|
|
@@ -53,12 +97,160 @@ notify.clear()
|
|
|
53
97
|
|
|
54
98
|
### Options
|
|
55
99
|
|
|
100
|
+
All notification methods accept advanced options:
|
|
101
|
+
|
|
56
102
|
| Property | Type | Default | Description |
|
|
57
103
|
| ------------- | -------------------------------------- | ----------- | ------------------------------------------- |
|
|
58
104
|
| `title` | string | — | Toast title |
|
|
59
|
-
| `description` | string
|
|
60
|
-
| `type` | `info\|success\|error\|warning
|
|
105
|
+
| `description` | string \| SvelteNode | — | Optional body text (HTML or string) |
|
|
106
|
+
| `type` | `info\|success\|error\|warning\|action`| `info` | Visual intent |
|
|
61
107
|
| `position` | string | `top-right` | One of toast positions |
|
|
108
|
+
| `duration` | number \| null | `4000` | Auto-dismiss timeout in ms (null = sticky) |
|
|
109
|
+
| `button` | { title: string, onClick: () => void } | — | Optional action button |
|
|
110
|
+
| `icon` | string \| SvelteNode | — | Custom icon (SVG or node) |
|
|
111
|
+
| `fill` | string | — | Custom background color (SVG or badge) |
|
|
112
|
+
| `styles` | { title, description, badge, button } | — | Custom class overrides for sub-elements |
|
|
113
|
+
| `roundness` | number | 16 | Border radius in pixels |
|
|
114
|
+
| `autopilot` | boolean \| object | true | Auto expand/collapse timing |
|
|
115
|
+
|
|
116
|
+
#### Example: Advanced Toasts
|
|
117
|
+
|
|
118
|
+
```svelte
|
|
119
|
+
// Custom icon (SVG string or SvelteNode)
|
|
120
|
+
notify.success({
|
|
121
|
+
title: 'With Icon',
|
|
122
|
+
icon: '<svg width="16" height="16" ...>...</svg>'
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Custom fill color
|
|
126
|
+
notify.info({
|
|
127
|
+
title: 'Colored',
|
|
128
|
+
fill: '#2563eb'
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Custom styles for sub-elements
|
|
132
|
+
notify.success({
|
|
133
|
+
title: 'Styled',
|
|
134
|
+
styles: {
|
|
135
|
+
title: 'my-title-class',
|
|
136
|
+
badge: 'my-badge-class',
|
|
137
|
+
button: 'my-btn-class'
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Custom roundness
|
|
142
|
+
notify.success({
|
|
143
|
+
title: 'Rounded',
|
|
144
|
+
roundness: 32
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Autopilot off (manual expand/collapse)
|
|
148
|
+
notify.success({
|
|
149
|
+
title: 'Manual',
|
|
150
|
+
autopilot: false
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Custom duration (sticky)
|
|
154
|
+
notify.info({
|
|
155
|
+
title: 'Sticky',
|
|
156
|
+
duration: null
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Custom position
|
|
160
|
+
notify.success({
|
|
161
|
+
title: 'Bottom left',
|
|
162
|
+
position: 'bottom-left'
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Description as SvelteNode
|
|
166
|
+
notify.info({
|
|
167
|
+
title: 'Node Description',
|
|
168
|
+
description: '<span style="color: red">Custom HTML content</span>'
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Example: Advanced Toast
|
|
173
|
+
|
|
174
|
+
```svelte
|
|
175
|
+
notify.success({
|
|
176
|
+
title: "Styled!",
|
|
177
|
+
fill: "#222",
|
|
178
|
+
icon: '<svg>...</svg>',
|
|
179
|
+
styles: {
|
|
180
|
+
title: "text-white!",
|
|
181
|
+
badge: "bg-white/20!",
|
|
182
|
+
button: "bg-white/10!"
|
|
183
|
+
},
|
|
184
|
+
roundness: 24,
|
|
185
|
+
autopilot: false
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Promise Toasts
|
|
190
|
+
|
|
191
|
+
```svelte
|
|
192
|
+
notify.promise(fetchData(), {
|
|
193
|
+
loading: { title: "Loading..." },
|
|
194
|
+
success: (data) => ({ title: `Loaded ${data.name}` }),
|
|
195
|
+
error: (err) => ({ title: "Error", description: err.message }),
|
|
196
|
+
action: (data) => ({ title: "Action required", button: { title: "Retry", onClick: () => retry() } })
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Toaster Component Props
|
|
201
|
+
|
|
202
|
+
The `<Toaster />` component accepts the following props:
|
|
203
|
+
|
|
204
|
+
| Prop | Type | Default | Description |
|
|
205
|
+
| --------- | ----------------------------------------- | ------------ | ------------------------------------------- |
|
|
206
|
+
| `position`| string | top-right | Default toast position |
|
|
207
|
+
| `offset` | number \| string \| {top,right,bottom,left}| 0 | Distance from viewport edges |
|
|
208
|
+
| `options` | Partial<Options> | — | Default options for all toasts |
|
|
209
|
+
| `theme` | "light" \| "dark" \| "system" | system | Color scheme (auto, light, dark) |
|
|
210
|
+
|
|
211
|
+
#### Example: Custom Toaster
|
|
212
|
+
|
|
213
|
+
```svelte
|
|
214
|
+
<Toaster position="bottom-center" offset={24} theme="dark" options={{ fill: '#222', roundness: 20 }} />
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Customizing Styles
|
|
218
|
+
|
|
219
|
+
- Override CSS variables in your stylesheet or inline:
|
|
220
|
+
|
|
221
|
+
```css
|
|
222
|
+
:root {
|
|
223
|
+
--sileo-bg: #18181b;
|
|
224
|
+
--sileo-success: #22c55e;
|
|
225
|
+
--sileo-error: #ef4444;
|
|
226
|
+
--sileo-info: #2563eb;
|
|
227
|
+
--sileo-warning: #f59e0b;
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
- Add custom classes via the `styles` option for title, badge, button, description.
|
|
232
|
+
|
|
233
|
+
## Accessibility
|
|
234
|
+
|
|
235
|
+
- Toast containers use `role="status"` and `aria-live="polite"`.
|
|
236
|
+
- Respects `prefers-reduced-motion` for users with motion sensitivity.
|
|
237
|
+
|
|
238
|
+
## Common Errors & Troubleshooting
|
|
239
|
+
|
|
240
|
+
- **No styles?** Make sure to import or link `dist/styles.css`.
|
|
241
|
+
- **No animation?** Check that the `motion` dependency is installed for ESM/bundler usage.
|
|
242
|
+
- **Button not working?** Ensure your `onClick` is a function and not a string.
|
|
243
|
+
- **Nothing appears?** Confirm you rendered `<Toaster />` and are using the correct import.
|
|
244
|
+
|
|
245
|
+
## Migration & Best Practices
|
|
246
|
+
|
|
247
|
+
- If migrating from Sileo, all options and methods are compatible.
|
|
248
|
+
- Prefer using `notify.success`, `notify.error`, etc. for intent clarity.
|
|
249
|
+
- Use `notify.clear()` to remove all toasts, o pasar una posición para limpiar solo un área.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
For other frameworks, see the React, Vue, and Vanilla guides.
|
|
62
254
|
| `duration` | number | `4000` | Auto-dismiss timeout in ms (0 = persistent) |
|
|
63
255
|
| `button` | { title: string, onClick: () => void } | — | Optional action button |
|
|
64
256
|
|
package/docs/vanilla.md
CHANGED
|
@@ -1,69 +1,226 @@
|
|
|
1
|
-
# Vanilla JS
|
|
2
1
|
|
|
3
|
-
|
|
2
|
+
# Vanilla JS (Bundler/Import)
|
|
3
|
+
|
|
4
|
+
Use the vanilla adapter for plain JavaScript projects with a bundler (Vite, Webpack, etc) or Node.js ESM/CJS. This entrypoint provides full API and advanced options.
|
|
4
5
|
|
|
5
6
|
## Quick start (ESM / npm)
|
|
6
7
|
|
|
7
|
-
```
|
|
8
|
+
```js
|
|
8
9
|
import { notify, initToasters } from '@samline/notify/vanilla';
|
|
9
10
|
initToasters(document.body, ['top-right']);
|
|
10
|
-
notify({ title: 'Saved', description: 'Your changes have been saved'
|
|
11
|
+
notify.success({ title: 'Saved', description: 'Your changes have been saved' });
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
##
|
|
14
|
+
## Methods: Full Examples
|
|
14
15
|
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
```js
|
|
17
|
+
// Show a generic toast
|
|
18
|
+
notify.show({ title: 'Hello', description: 'Generic toast', type: 'info' });
|
|
19
|
+
|
|
20
|
+
// Success toast
|
|
21
|
+
notify.success({ title: 'Success!', description: 'Operation completed.' });
|
|
22
|
+
|
|
23
|
+
// Error toast
|
|
24
|
+
notify.error({ title: 'Error', description: 'Something went wrong.' });
|
|
25
|
+
|
|
26
|
+
// Info toast
|
|
27
|
+
notify.info({ title: 'Heads up!', description: 'This is an info toast.' });
|
|
28
|
+
|
|
29
|
+
// Warning toast
|
|
30
|
+
notify.warning({ title: 'Warning!', description: 'Be careful.' });
|
|
31
|
+
|
|
32
|
+
// Action toast with button
|
|
33
|
+
notify.action({
|
|
34
|
+
title: 'Action required',
|
|
35
|
+
description: 'Click the button to proceed.',
|
|
36
|
+
button: { title: 'Proceed', onClick: () => alert('Action!') }
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Promise toast (loading, success, error, action)
|
|
40
|
+
notify.promise(fetch('/api/save'), {
|
|
41
|
+
loading: { title: 'Saving...' },
|
|
42
|
+
success: { title: 'Saved!', description: 'Your data was saved.' },
|
|
43
|
+
error: { title: 'Failed', description: 'Could not save.' },
|
|
44
|
+
action: { title: 'Retry?', button: { title: 'Retry', onClick: () => {/* retry logic */} } }
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Dismiss a toast by id
|
|
48
|
+
const id = notify.success({ title: 'Dismiss me' });
|
|
49
|
+
notify.dismiss(id);
|
|
50
|
+
|
|
51
|
+
// Clear all toasts
|
|
52
|
+
notify.clear();
|
|
53
|
+
|
|
54
|
+
// Clear only a position
|
|
55
|
+
notify.clear('top-right');
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Advanced Toaster Options
|
|
59
|
+
|
|
60
|
+
You can pass advanced options to `initToasters`:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
initToasters(document.body, ['top-right'], {
|
|
64
|
+
offset: { top: 32, right: 16 },
|
|
65
|
+
options: { fill: '#222', roundness: 20 },
|
|
66
|
+
theme: 'dark'
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Example: Multiple positions and custom offset
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
initToasters(document.body, ['top-right', 'bottom-left'], {
|
|
74
|
+
offset: { top: 24, right: 24, bottom: 24, left: 24 },
|
|
75
|
+
theme: 'light',
|
|
76
|
+
options: { fill: '#0f1724', roundness: 18 }
|
|
77
|
+
});
|
|
25
78
|
```
|
|
26
79
|
|
|
27
80
|
## API
|
|
28
81
|
|
|
29
|
-
```
|
|
30
|
-
// Core controller (primary: `notify`, compatibility alias: `sileo`)
|
|
82
|
+
```js
|
|
31
83
|
notify.show(options)
|
|
32
84
|
notify.success(options)
|
|
33
85
|
notify.error(options)
|
|
34
86
|
notify.info(options)
|
|
35
87
|
notify.warning(options)
|
|
36
88
|
notify.action(options)
|
|
37
|
-
notify.promise(promise, { loading, success, error })
|
|
89
|
+
notify.promise(promise, { loading, success, error, action })
|
|
38
90
|
notify.dismiss(id)
|
|
39
91
|
notify.clear()
|
|
40
92
|
```
|
|
41
93
|
|
|
42
|
-
|
|
94
|
+
## Options: Full Examples
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
// Custom icon (SVG string)
|
|
98
|
+
notify.success({
|
|
99
|
+
title: 'With Icon',
|
|
100
|
+
icon: '<svg width="16" height="16" ...>...</svg>'
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Custom fill color
|
|
104
|
+
notify.info({
|
|
105
|
+
title: 'Colored',
|
|
106
|
+
fill: '#2563eb'
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Custom styles for sub-elements
|
|
110
|
+
notify.success({
|
|
111
|
+
title: 'Styled',
|
|
112
|
+
styles: {
|
|
113
|
+
title: 'my-title-class',
|
|
114
|
+
badge: 'my-badge-class',
|
|
115
|
+
button: 'my-btn-class'
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Custom roundness
|
|
120
|
+
notify.success({
|
|
121
|
+
title: 'Rounded',
|
|
122
|
+
roundness: 32
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Autopilot off (manual expand/collapse)
|
|
126
|
+
notify.success({
|
|
127
|
+
title: 'Manual',
|
|
128
|
+
autopilot: false
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Custom duration (sticky)
|
|
132
|
+
notify.info({
|
|
133
|
+
title: 'Sticky',
|
|
134
|
+
duration: null
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Custom position
|
|
138
|
+
notify.success({
|
|
139
|
+
title: 'Bottom left',
|
|
140
|
+
position: 'bottom-left'
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Options
|
|
145
|
+
|
|
146
|
+
| Property | Type | Default | Description |
|
|
147
|
+
| ------------- | -------------------------------------- | ----------- | ------------------------------------------- |
|
|
148
|
+
| `title` | string | — | Toast title |
|
|
149
|
+
| `description` | string | — | Optional body text |
|
|
150
|
+
| `type` | `info\|success\|error\|warning\|action`| `info` | Visual intent |
|
|
151
|
+
| `position` | string | `top-right` | Container position |
|
|
152
|
+
| `duration` | number \| null | `4000` | Auto-dismiss timeout in ms (`null` = sticky)|
|
|
153
|
+
| `button` | { title: string, onClick: () => void } | — | Optional action button |
|
|
154
|
+
| `icon` | string | — | Custom icon (SVG or HTML) |
|
|
155
|
+
| `fill` | string | — | Custom background color (SVG or badge) |
|
|
156
|
+
| `styles` | { title, description, badge, button } | — | Custom class overrides for sub-elements |
|
|
157
|
+
| `roundness` | number | 16 | Border radius in pixels |
|
|
158
|
+
| `autopilot` | boolean \| object | true | Auto expand/collapse timing |
|
|
43
159
|
|
|
44
|
-
|
|
45
|
-
| --- | --- | --- |
|
|
46
|
-
| `options` | object | Toast creation options (see Options below) |
|
|
160
|
+
---
|
|
47
161
|
|
|
48
|
-
|
|
162
|
+
# Browser / CDN (No Bundler)
|
|
49
163
|
|
|
50
|
-
|
|
164
|
+
If you are not using a bundler, use the [Browser guide](./browser.md) for CDN usage. Example:
|
|
51
165
|
|
|
52
|
-
|
|
166
|
+
```html
|
|
167
|
+
<link rel="stylesheet" href="https://unpkg.com/@samline/notify@0.1.15/dist/styles.css">
|
|
168
|
+
<script src="https://unpkg.com/@samline/notify@0.1.15/dist/notify.umd.js"></script>
|
|
169
|
+
<script>
|
|
170
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
171
|
+
const api = window.notify;
|
|
172
|
+
api.initToasters(document.body, ['top-right']);
|
|
173
|
+
api.notify({ title: 'Saved', description: 'Your changes have been saved', type: 'success' });
|
|
174
|
+
});
|
|
175
|
+
</script>
|
|
176
|
+
```
|
|
53
177
|
|
|
54
|
-
|
|
55
|
-
| --- | --- | --- | --- |
|
|
56
|
-
| `title` | `string` | — | Toast title |
|
|
57
|
-
| `description` | `string` | — | Optional body text |
|
|
58
|
-
| `type` | `info\|success\|error\|warning` | `info` | Visual intent |
|
|
59
|
-
| `position` | `string` | `top-right` | Container position |
|
|
60
|
-
| `duration` | `number` | `4000` | Auto-dismiss timeout in ms (`null` = sticky) |
|
|
178
|
+
> The CDN/UMD build exposes `window.notify` and only supports string/HTML for icons and content. For advanced options, use the import/bundler version.
|
|
61
179
|
| `button` | `{ title, onClick }` | — | Optional action button |
|
|
62
180
|
|
|
63
181
|
## Tips
|
|
64
182
|
|
|
65
183
|
- Always include the stylesheet for correct appearance.
|
|
66
184
|
- Use the ESM build for modern projects, or the UMD build for legacy/static sites.
|
|
185
|
+
|
|
186
|
+
## Customizing Styles
|
|
187
|
+
|
|
188
|
+
- Override CSS variables in your stylesheet or inline:
|
|
189
|
+
|
|
190
|
+
```css
|
|
191
|
+
:root {
|
|
192
|
+
--sileo-bg: #18181b;
|
|
193
|
+
--sileo-success: #22c55e;
|
|
194
|
+
--sileo-error: #ef4444;
|
|
195
|
+
--sileo-info: #2563eb;
|
|
196
|
+
--sileo-warning: #f59e0b;
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
- Add custom classes via the `styles` option for title, badge, button, description.
|
|
201
|
+
|
|
202
|
+
## Accessibility
|
|
203
|
+
|
|
204
|
+
- Toast containers use `role="status"` and `aria-live="polite"`.
|
|
205
|
+
- Respects `prefers-reduced-motion` for users with motion sensitivity.
|
|
206
|
+
|
|
207
|
+
## Common Errors & Troubleshooting
|
|
208
|
+
|
|
209
|
+
- **No styles?** Make sure to import or link `dist/styles.css`.
|
|
210
|
+
- **No animation?** Check that the `motion` dependency is installed for ESM/bundler usage.
|
|
211
|
+
- **Button not working?** Ensure your `onClick` is a function and not a string.
|
|
212
|
+
- **Nothing appears?** Confirm you called `initToasters` and are using the correct container.
|
|
213
|
+
|
|
214
|
+
## Migration & Best Practices
|
|
215
|
+
|
|
216
|
+
- If migrating from Sileo, all options and methods are compatible.
|
|
217
|
+
- Use the ESM/bundler version for full feature support.
|
|
218
|
+
- Prefer using `notify.success`, `notify.error`, etc. for intent clarity.
|
|
219
|
+
- Use `notify.clear()` to remove all toasts, or pass a position to clear only one area.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
For framework-specific usage, see the React, Vue, and Svelte guides.
|
|
67
224
|
```
|
|
68
225
|
|
|
69
226
|
### Promise flow
|
package/docs/vue.md
CHANGED
|
@@ -20,6 +20,50 @@ app.component('Toaster', Toaster);
|
|
|
20
20
|
app.mount('#app');
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
## Methods: Full Examples
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
// Show a generic toast
|
|
27
|
+
notify.show({ title: 'Hello', description: 'Generic toast', type: 'info' });
|
|
28
|
+
|
|
29
|
+
// Success toast
|
|
30
|
+
notify.success({ title: 'Success!', description: 'Operation completed.' });
|
|
31
|
+
|
|
32
|
+
// Error toast
|
|
33
|
+
notify.error({ title: 'Error', description: 'Something went wrong.' });
|
|
34
|
+
|
|
35
|
+
// Info toast
|
|
36
|
+
notify.info({ title: 'Heads up!', description: 'This is an info toast.' });
|
|
37
|
+
|
|
38
|
+
// Warning toast
|
|
39
|
+
notify.warning({ title: 'Warning!', description: 'Be careful.' });
|
|
40
|
+
|
|
41
|
+
// Action toast with button
|
|
42
|
+
notify.action({
|
|
43
|
+
title: 'Action required',
|
|
44
|
+
description: 'Click the button to proceed.',
|
|
45
|
+
button: { title: 'Proceed', onClick: () => alert('Action!') }
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Promise toast (loading, success, error, action)
|
|
49
|
+
notify.promise(fetch('/api/save'), {
|
|
50
|
+
loading: { title: 'Saving...' },
|
|
51
|
+
success: { title: 'Saved!', description: 'Your data was saved.' },
|
|
52
|
+
error: { title: 'Failed', description: 'Could not save.' },
|
|
53
|
+
action: { title: 'Retry?', button: { title: 'Retry', onClick: () => {/* retry logic */} } }
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Dismiss a toast by id
|
|
57
|
+
const id = notify.success({ title: 'Dismiss me' });
|
|
58
|
+
notify.dismiss(id);
|
|
59
|
+
|
|
60
|
+
// Clear all toasts
|
|
61
|
+
notify.clear();
|
|
62
|
+
|
|
63
|
+
// Clear only a position
|
|
64
|
+
notify.clear('top-right');
|
|
65
|
+
```
|
|
66
|
+
|
|
23
67
|
|
|
24
68
|
|
|
25
69
|
Use the `notify` controller to show notifications:
|
|
@@ -58,6 +102,163 @@ function show(){ notify.show({ title: 'Hello from Vue' }); }
|
|
|
58
102
|
|
|
59
103
|
- `Toaster`: Main visual component (same as in React and Svelte).
|
|
60
104
|
- `notify`: Programmatic controller for showing notifications. Import from `@samline/notify/vue` or use `this.$notify` if using the plugin.
|
|
105
|
+
|
|
106
|
+
### Options
|
|
107
|
+
|
|
108
|
+
All notification methods accept advanced options:
|
|
109
|
+
|
|
110
|
+
| Property | Type | Default | Description |
|
|
111
|
+
| ------------- | -------------------------------------- | ----------- | ------------------------------------------- |
|
|
112
|
+
| `title` | string | — | Toast title |
|
|
113
|
+
| `description` | string \| VNode | — | Optional body text (HTML or string) |
|
|
114
|
+
| `type` | `info\|success\|error\|warning\|action`| `info` | Visual intent |
|
|
115
|
+
| `position` | string | `top-right` | One of toast positions |
|
|
116
|
+
| `duration` | number \| null | `4000` | Auto-dismiss timeout in ms (null = sticky) |
|
|
117
|
+
| `button` | { title: string, onClick: () => void } | — | Optional action button |
|
|
118
|
+
| `icon` | string \| VNode | — | Custom icon (SVG or node) |
|
|
119
|
+
| `fill` | string | — | Custom background color (SVG or badge) |
|
|
120
|
+
| `styles` | { title, description, badge, button } | — | Custom class overrides for sub-elements |
|
|
121
|
+
| `roundness` | number | 16 | Border radius in pixels |
|
|
122
|
+
| `autopilot` | boolean \| object | true | Auto expand/collapse timing |
|
|
123
|
+
|
|
124
|
+
#### Example: Advanced Toasts
|
|
125
|
+
|
|
126
|
+
```js
|
|
127
|
+
// Custom icon (SVG string or VNode)
|
|
128
|
+
notify.success({
|
|
129
|
+
title: 'With Icon',
|
|
130
|
+
icon: '<svg width="16" height="16" ...>...</svg>'
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Custom fill color
|
|
134
|
+
notify.info({
|
|
135
|
+
title: 'Colored',
|
|
136
|
+
fill: '#2563eb'
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Custom styles for sub-elements
|
|
140
|
+
notify.success({
|
|
141
|
+
title: 'Styled',
|
|
142
|
+
styles: {
|
|
143
|
+
title: 'my-title-class',
|
|
144
|
+
badge: 'my-badge-class',
|
|
145
|
+
button: 'my-btn-class'
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Custom roundness
|
|
150
|
+
notify.success({
|
|
151
|
+
title: 'Rounded',
|
|
152
|
+
roundness: 32
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Autopilot off (manual expand/collapse)
|
|
156
|
+
notify.success({
|
|
157
|
+
title: 'Manual',
|
|
158
|
+
autopilot: false
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Custom duration (sticky)
|
|
162
|
+
notify.info({
|
|
163
|
+
title: 'Sticky',
|
|
164
|
+
duration: null
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Custom position
|
|
168
|
+
notify.success({
|
|
169
|
+
title: 'Bottom left',
|
|
170
|
+
position: 'bottom-left'
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Description as VNode
|
|
174
|
+
notify.info({
|
|
175
|
+
title: 'VNode Description',
|
|
176
|
+
description: h('span', { style: 'color: red' }, 'Custom VNode content')
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
#### Example: Advanced Toast
|
|
181
|
+
|
|
182
|
+
```js
|
|
183
|
+
notify.success({
|
|
184
|
+
title: "Styled!",
|
|
185
|
+
fill: "#222",
|
|
186
|
+
icon: '<svg>...</svg>',
|
|
187
|
+
styles: {
|
|
188
|
+
title: "text-white!",
|
|
189
|
+
badge: "bg-white/20!",
|
|
190
|
+
button: "bg-white/10!"
|
|
191
|
+
},
|
|
192
|
+
roundness: 24,
|
|
193
|
+
autopilot: false
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
#### Promise Toasts
|
|
198
|
+
|
|
199
|
+
```js
|
|
200
|
+
notify.promise(fetchData(), {
|
|
201
|
+
loading: { title: "Loading..." },
|
|
202
|
+
success: (data) => ({ title: `Loaded ${data.name}` }),
|
|
203
|
+
error: (err) => ({ title: "Error", description: err.message }),
|
|
204
|
+
action: (data) => ({ title: "Action required", button: { title: "Retry", onClick: () => retry() } })
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Toaster Component Props
|
|
209
|
+
|
|
210
|
+
The `<Toaster />` component accepts the following props:
|
|
211
|
+
|
|
212
|
+
| Prop | Type | Default | Description |
|
|
213
|
+
| --------- | ----------------------------------------- | ------------ | ------------------------------------------- |
|
|
214
|
+
| `position`| string | top-right | Default toast position |
|
|
215
|
+
| `offset` | number \| string \| {top,right,bottom,left}| 0 | Distance from viewport edges |
|
|
216
|
+
| `options` | Partial<Options> | — | Default options for all toasts |
|
|
217
|
+
| `theme` | "light" \| "dark" \| "system" | system | Color scheme (auto, light, dark) |
|
|
218
|
+
|
|
219
|
+
#### Example: Custom Toaster
|
|
220
|
+
|
|
221
|
+
```vue
|
|
222
|
+
<Toaster position="bottom-center" :offset="24" theme="dark" :options="{ fill: '#222', roundness: 20 }" />
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Customizing Styles
|
|
226
|
+
|
|
227
|
+
- Override CSS variables in your stylesheet or inline:
|
|
228
|
+
|
|
229
|
+
```css
|
|
230
|
+
:root {
|
|
231
|
+
--sileo-bg: #18181b;
|
|
232
|
+
--sileo-success: #22c55e;
|
|
233
|
+
--sileo-error: #ef4444;
|
|
234
|
+
--sileo-info: #2563eb;
|
|
235
|
+
--sileo-warning: #f59e0b;
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
- Add custom classes via the `styles` option for title, badge, button, description.
|
|
240
|
+
|
|
241
|
+
## Accessibility
|
|
242
|
+
|
|
243
|
+
- Toast containers use `role="status"` and `aria-live="polite"`.
|
|
244
|
+
- Respects `prefers-reduced-motion` for users with motion sensitivity.
|
|
245
|
+
|
|
246
|
+
## Common Errors & Troubleshooting
|
|
247
|
+
|
|
248
|
+
- **No styles?** Make sure to import or link `dist/styles.css`.
|
|
249
|
+
- **No animation?** Check that the `motion` dependency is installed for ESM/bundler usage.
|
|
250
|
+
- **Button not working?** Ensure your `onClick` is a function and not a string.
|
|
251
|
+
- **Nothing appears?** Confirm you rendered `<Toaster />` and are using the correct import.
|
|
252
|
+
|
|
253
|
+
## Migration & Best Practices
|
|
254
|
+
|
|
255
|
+
- If migrating from Sileo, all options and methods are compatible.
|
|
256
|
+
- Prefer using `notify.success`, `notify.error`, etc. for intent clarity.
|
|
257
|
+
- Use `notify.clear()` to remove all toasts, o pasar una posición para limpiar solo un área.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
For other frameworks, see the React, Svelte, and Vanilla guides.
|
|
61
262
|
- Advanced: The `Notifications` plugin is available for global/legacy registration, but direct use of `Toaster` is recommended for most apps.
|
|
62
263
|
- `useSileo()`: Composable that returns the `sileo` controller if you prefer.
|
|
63
264
|
|
package/package.json
CHANGED