@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 CHANGED
@@ -1,8 +1,9 @@
1
+
1
2
  ## @samline/notify
2
3
 
3
- A Sileo-inspired notifications engine providing a framework-agnostic core and lightweight adapters for Vanilla JS, React, Vue and Svelte.
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
- Inspired by Sileo — see the original project: https://github.com/hiaaryan/sileo
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
- Common `options` across entrypoints:
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 | — | Optional body text |
111
- | `type` | `info\|success\|error\|warning` | `info` | Visual intent |
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 | `4000` | Auto-dismiss timeout in ms (0 = persistent) |
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 = { id, options: { ...opts }, createdAt: Date.now() };
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 = { id, options: { ...opts }, createdAt: Date.now() };
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];
@@ -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 = { id, options: { ...opts }, createdAt: Date.now() };
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 | — | Optional body text |
59
- | `type` | `info\|success\|error\|warning` | `info` | Visual intent |
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 | — | Optional body text |
60
- | `type` | `info\|success\|error\|warning` | `info` | Visual intent |
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
- Use the vanilla adapter for plain JavaScript projects, either with modules or directly via CDN.
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
- ```ts
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', type: 'success' });
11
+ notify.success({ title: 'Saved', description: 'Your changes have been saved' });
11
12
  ```
12
13
 
13
- ## Quick start (CDN / UMD)
14
+ ## Methods: Full Examples
14
15
 
15
- ```html
16
- <link rel="stylesheet" href="https://unpkg.com/@samline/notify@0.1.15/dist/styles.css">
17
- <script src="https://unpkg.com/@samline/notify@0.1.15/dist/notify.umd.js"></script>
18
- <script>
19
- document.addEventListener('DOMContentLoaded', () => {
20
- const api = window.notify;
21
- api.initToasters(document.body, ['top-right']);
22
- api.notify({ title: 'Saved', description: 'Your changes have been saved', type: 'success' });
23
- });
24
- </script>
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
- ```ts
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
- ### Parameters
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
- | Parameter | Type | Description |
45
- | --- | --- | --- |
46
- | `options` | object | Toast creation options (see Options below) |
160
+ ---
47
161
 
48
- ### Returns
162
+ # Browser / CDN (No Bundler)
49
163
 
50
- `string | void` `show` returns a toast id when created.
164
+ If you are not using a bundler, use the [Browser guide](./browser.md) for CDN usage. Example:
51
165
 
52
- ## Options
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
- | Property | Type | Default | Description |
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samline/notify",
3
- "version": "0.1.15",
3
+ "version": "0.2.0",
4
4
  "description": "Notifications engine inspired by Sileo, with adapters for vanilla, React, Vue and Svelte.",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",