@samline/notify 1.0.2 → 2.0.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.
Files changed (84) hide show
  1. package/{LICENSE → LICENSE.md} +2 -2
  2. package/README.md +27 -163
  3. package/dist/_runtime.d.mts +87 -0
  4. package/dist/_runtime.d.ts +87 -0
  5. package/dist/_runtime.js +97 -0
  6. package/dist/_runtime.mjs +83 -0
  7. package/dist/browser/assets-client-B-VVPPYQ.js +114 -0
  8. package/dist/browser/assets-client-CUzxHubR.mjs +108 -0
  9. package/dist/browser/index-client-BBOQyMFk.mjs +173 -0
  10. package/dist/browser/index-client-Czb7hTpD.js +181 -0
  11. package/dist/browser/index.d.mts +134 -0
  12. package/dist/browser/index.d.ts +134 -0
  13. package/dist/browser/index.js +34 -0
  14. package/dist/browser/index.mjs +26 -0
  15. package/dist/browser/render-client-CjcQoukB.js +981 -0
  16. package/dist/browser/render-client-bGRSTd-L.mjs +974 -0
  17. package/dist/core/index.d.mts +68 -0
  18. package/dist/core/index.d.ts +68 -0
  19. package/dist/core/index.js +1 -0
  20. package/dist/core/index.mjs +1 -0
  21. package/dist/index.d.mts +131 -0
  22. package/dist/index.d.ts +131 -0
  23. package/dist/index.js +1240 -0
  24. package/dist/index.mjs +1228 -0
  25. package/dist/react/index.d.mts +158 -0
  26. package/dist/react/index.d.ts +158 -0
  27. package/dist/react/index.js +1116 -0
  28. package/dist/react/index.mjs +1107 -0
  29. package/dist/styles.css +589 -422
  30. package/dist/svelte/assets-client-B-VVPPYQ.js +114 -0
  31. package/dist/svelte/assets-client-CUzxHubR.mjs +108 -0
  32. package/dist/svelte/index-client-DbXbWMIe.js +177 -0
  33. package/dist/svelte/index-client-Dj_WfPK9.mjs +170 -0
  34. package/dist/svelte/index.d.mts +14 -0
  35. package/dist/svelte/index.d.ts +14 -0
  36. package/dist/svelte/index.js +43 -0
  37. package/dist/svelte/index.mjs +36 -0
  38. package/dist/svelte/render-client-CjcQoukB.js +981 -0
  39. package/dist/svelte/render-client-bGRSTd-L.mjs +974 -0
  40. package/dist/vue/assets-client-B-VVPPYQ.js +114 -0
  41. package/dist/vue/assets-client-CUzxHubR.mjs +108 -0
  42. package/dist/vue/index-client-DbXbWMIe.js +177 -0
  43. package/dist/vue/index-client-Dj_WfPK9.mjs +170 -0
  44. package/dist/vue/index.d.mts +50 -0
  45. package/dist/vue/index.d.ts +50 -0
  46. package/dist/vue/index.js +110 -0
  47. package/dist/vue/index.mjs +104 -0
  48. package/dist/vue/render-client-CjcQoukB.js +981 -0
  49. package/dist/vue/render-client-bGRSTd-L.mjs +974 -0
  50. package/package.json +140 -95
  51. package/dist/browser-notify.js +0 -68
  52. package/dist/cc-2Yt7NqMX.mjs +0 -21
  53. package/dist/cc-B6peeNak.mjs +0 -33
  54. package/dist/cc-BWuAzFJ6.js +0 -12
  55. package/dist/cc-CaBHsjUt.js +0 -34
  56. package/dist/cc-DGff5sSY.js +0 -21
  57. package/dist/cc-he3fHS3P.mjs +0 -12
  58. package/dist/notify.d.mts +0 -48
  59. package/dist/notify.d.mts.map +0 -1
  60. package/dist/notify.d.ts +0 -48
  61. package/dist/notify.d.ts.map +0 -1
  62. package/dist/notify.js +0 -206
  63. package/dist/notify.mjs +0 -202
  64. package/dist/react-notify-12s--2JK5UjB.mjs +0 -1244
  65. package/dist/react-notify-12s-Kv2M6zlv.js +0 -1247
  66. package/dist/react.d.mts +0 -70
  67. package/dist/react.d.mts.map +0 -1
  68. package/dist/react.d.ts +0 -70
  69. package/dist/react.d.ts.map +0 -1
  70. package/dist/react.js +0 -19
  71. package/dist/react.mjs +0 -10
  72. package/dist/render-notify-toasts.js +0 -213
  73. package/dist/svelte.d.mts +0 -49
  74. package/dist/svelte.d.mts.map +0 -1
  75. package/dist/svelte.d.ts +0 -49
  76. package/dist/svelte.d.ts.map +0 -1
  77. package/dist/svelte.js +0 -284
  78. package/dist/svelte.mjs +0 -280
  79. package/dist/vue.d.mts +0 -107
  80. package/dist/vue.d.mts.map +0 -1
  81. package/dist/vue.d.ts +0 -107
  82. package/dist/vue.d.ts.map +0 -1
  83. package/dist/vue.js +0 -2215
  84. package/dist/vue.mjs +0 -2211
@@ -1,7 +1,7 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Samuel Olvera (samline)
4
- Copyright (c) 2023 Aaryan Arora (hiaaryan)
3
+ Copyright (c) 2026 Samuel Olvera (Samline)
4
+ Copyright (c) 2023 Emil Kowalski
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,196 +1,60 @@
1
1
  # Notify
2
2
 
3
- A toast notification library designed to bring a beautiful animated experience to React, Vue, Svelte, and Vanilla JS.
3
+ A universal toast notification library. Built for teams who need Sonner quality and API, but require seamless integration across multiple frameworks.
4
4
 
5
- ---
6
-
7
- Inspired by Sileo: [https://github.com/hiaaryan/sileo](https://github.com/hiaaryan/sileo)
8
-
9
- ---
5
+ Notify is a toast package inspired by [Sonner](https://github.com/emilkowalski/sonner). The intention is to complement that work and experiment with a shared runtime for React, Vue, Svelte, vanilla JS, and browser/CDN usage.
10
6
 
11
7
  ## Table of Contents
12
8
 
13
9
  - [Installation](#installation)
14
- - [CDN / Browser](#cdn--browser)
15
10
  - [Entrypoints](#entrypoints)
16
11
  - [Quick Start](#quick-start)
17
- - [What can you do?](#what-can-you-do)
18
- - [General API](#general-api)
19
- - [Minimal Example](#minimal-example)
20
- - [Framework Documentation](#framework-documentation)
12
+ - [Documentation](#documentation)
13
+ - [Scripts](#scripts)
21
14
  - [License](#license)
22
15
 
23
- ---
24
-
25
16
  ## Installation
26
17
 
27
18
  ```bash
28
19
  npm install @samline/notify
29
20
  ```
30
21
 
31
- ---
32
-
33
- ## CDN / Browser
34
-
35
- Include the CSS and UMD bundle via unpkg or jsDelivr:
36
-
37
- ```html
38
- <!-- unpkg -->
39
- <link rel="stylesheet" href="https://unpkg.com/@samline/notify@1.0.2/dist/styles.css" />
40
- <script src="https://unpkg.com/@samline/notify@1.0.2/dist/browser-notify.js"></script>
41
- <script src="https://unpkg.com/@samline/notify@1.0.2/dist/render-notify-toasts.js"></script>
42
- ```
43
-
44
- ```html
45
- <!-- jsDelivr -->
46
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@samline/notify@1.0.2/dist/styles.css" />
47
- <script src="https://cdn.jsdelivr.net/npm/@samline/notify@1.0.2/dist/browser-notify.js"></script>
48
- <script src="https://cdn.jsdelivr.net/npm/@samline/notify@1.0.2/dist/render-notify-toasts.js"></script>
49
- ```
50
-
51
- ```html
52
- <script>
53
- renderNotifyToasts({ position: 'top-right' })
54
- window.notify.show({
55
- title: 'Hello from the browser',
56
- type: 'success',
57
- duration: 2000,
58
- })
59
- </script>
22
+ ```bash
23
+ bun add @samline/notify
60
24
  ```
61
25
 
62
- ---
63
-
64
26
  ## Entrypoints
65
27
 
66
- | Entrypoint | Description |
67
- | ---------------------------------- | ----------------------------- |
68
- | @samline/notify | VanillaJS API |
69
- | @samline/notify/react | React API (hooks and helpers) |
70
- | @samline/notify/vue | Vue API (composable) |
71
- | @samline/notify/svelte | Svelte API (store) |
72
- | @samline/notify/dist/browser-notify | Global for Browser/CDN |
73
-
74
- ---
28
+ | Entrypoint | Use |
29
+ | ---------------------------- | --------------------- |
30
+ | `@samline/notify` | Main vanilla API |
31
+ | `@samline/notify/browser` | Browser global bundle |
32
+ | `@samline/notify/react` | React adapter |
33
+ | `@samline/notify/vue` | Vue adapter |
34
+ | `@samline/notify/svelte` | Svelte adapter |
35
+ | `@samline/notify/styles.css` | Shared styles export |
75
36
 
76
37
  ## Quick Start
77
38
 
78
- ### Import by framework
39
+ ```ts
40
+ import { createToaster, toast } from '@samline/notify';
79
41
 
80
- **VanillaJS (default):**
81
-
82
- ```js
83
- import { showNotifyToast, onNotifyToastsChange } from '@samline/notify'
84
-
85
- // Subscribe first — the library manages state, rendering is up to you
86
- onNotifyToastsChange((toasts) => { /* render toasts in your DOM */ })
87
-
88
- showNotifyToast({ title: 'Hello world!', type: 'success' })
89
- ```
90
-
91
- **React:**
92
-
93
- ```js
94
- import { showNotifyToast } from '@samline/notify/react'
95
- showNotifyToast({ title: 'Hello from React!', type: 'success' })
96
- ```
97
-
98
- **Vue:**
99
-
100
- ```js
101
- import { showNotifyToast, useNotifyToasts } from '@samline/notify/vue'
102
- showNotifyToast({ title: 'Hello from Vue!', type: 'success' })
103
- ```
104
-
105
- **Svelte:**
106
-
107
- ```js
108
- import { showNotifyToast, notifyToasts } from '@samline/notify/svelte'
109
- showNotifyToast({ title: 'Hello from Svelte!', type: 'success' })
110
- ```
42
+ createToaster({ position: 'bottom-right', richColors: true });
111
43
 
112
- Each framework imports from its own context, ensuring optimal integration and correct types. See the specific documentation for advanced examples.
113
-
114
- For complete examples and plug-and-play UI, see your framework's documentation:
115
-
116
- - [React](docs/react.md)
117
- - [Vue 3](docs/vue.md)
118
- - [Svelte](docs/svelte.md)
119
- - [VanillaJS](docs/vanillajs.md)
120
- - [Browser / CDN](docs/browser.md)
121
-
122
- ---
123
-
124
- ## What can you do?
125
-
126
- - Show toasts with physics-based, customizable animations
127
- - Use the same API in React, Vue, Svelte, VanillaJS, and Browser
128
- - Customize position, duration, styles, icons, and buttons
129
- - Integrate plug-and-play UI or create your own rendering
130
- - Subscribe to toast changes (store/composable/callback)
131
- - Use from bundlers or directly in HTML
132
-
133
- ---
134
-
135
- ## General API
136
-
137
- Notify exposes a unified API for all environments. All options and methods are available in each integration.
138
-
139
- ### Toast Options
140
-
141
- | Option | Type | Description |
142
- | ----------- | ------------------------------------------------------------------------------------- | ---------------------------- |
143
- | title | string | Toast title |
144
- | description | string | Optional description |
145
- | type | 'success'\|'loading'\|'error'\|'warning'\|'info'\|'action' | Toast type |
146
- | duration | number | Duration in milliseconds |
147
- | position | 'top-left'\|'top-center'\|'top-right'\|'bottom-left'\|'bottom-center'\|'bottom-right' | Screen position |
148
- | styles | { title, description, badge, button } | Custom CSS classes |
149
- | fill | string | Background color |
150
- | roundness | number | Border radius |
151
- | autopilot | boolean\|{ expand, collapse } | Auto expand/collapse control |
152
- | button | { title: string, onClick: () => void } | Action button |
153
-
154
- ### Main Methods
155
-
156
- - `showNotifyToast(options)` — Show a toast (in all environments)
157
- - `onNotifyToastsChange(fn)` — Subscribe to changes (VanillaJS)
158
- - `useNotifyToasts()` — Vue composable
159
- - `notifyToasts` — Svelte store
160
-
161
- ---
162
-
163
- ## Minimal Example
164
-
165
- ```js
166
- showNotifyToast({
167
- title: 'Action required',
168
- description: 'Click the button to continue',
169
- type: 'action',
170
- button: {
171
- title: 'Continue',
172
- onClick: () => alert('You continued!'),
173
- },
174
- styles: {
175
- title: 'my-title',
176
- button: 'my-button',
177
- },
178
- fill: '#fffae0',
179
- roundness: 24,
180
- duration: 5000,
181
- })
44
+ toast.success('Saved');
182
45
  ```
183
46
 
184
- ## Framework Documentation
47
+ ## Documentation
185
48
 
186
- - [React](docs/react.md)
187
- - [Vue 3](docs/vue.md)
188
- - [Svelte](docs/svelte.md)
189
- - [VanillaJS](docs/vanillajs.md)
190
- - [Browser / CDN](docs/browser.md)
191
- - [General API](docs/api.md)
49
+ Use the dedicated docs when you want the full API or a framework-specific guide.
192
50
 
193
- ---
51
+ - [docs/README.md](docs/README.md)
52
+ - [docs/api.md](docs/api.md)
53
+ - [docs/vanilla.md](docs/vanilla.md)
54
+ - [docs/browser.md](docs/browser.md)
55
+ - [docs/react.md](docs/react.md)
56
+ - [docs/vue.md](docs/vue.md)
57
+ - [docs/svelte.md](docs/svelte.md)
194
58
 
195
59
  ## License
196
60
 
@@ -0,0 +1,87 @@
1
+ import React from 'react';
2
+
3
+ interface ToastClassnames {
4
+ toast?: string;
5
+ title?: string;
6
+ description?: string;
7
+ loader?: string;
8
+ closeButton?: string;
9
+ cancelButton?: string;
10
+ actionButton?: string;
11
+ success?: string;
12
+ error?: string;
13
+ info?: string;
14
+ warning?: string;
15
+ loading?: string;
16
+ default?: string;
17
+ content?: string;
18
+ icon?: string;
19
+ }
20
+ interface ToastIcons {
21
+ success?: React.ReactNode;
22
+ info?: React.ReactNode;
23
+ warning?: React.ReactNode;
24
+ error?: React.ReactNode;
25
+ loading?: React.ReactNode;
26
+ close?: React.ReactNode;
27
+ }
28
+ type Position = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center';
29
+ interface ToastOptions {
30
+ className?: string;
31
+ closeButton?: boolean;
32
+ descriptionClassName?: string;
33
+ style?: React.CSSProperties;
34
+ cancelButtonStyle?: React.CSSProperties;
35
+ actionButtonStyle?: React.CSSProperties;
36
+ duration?: number;
37
+ unstyled?: boolean;
38
+ classNames?: ToastClassnames;
39
+ closeButtonAriaLabel?: string;
40
+ toasterId?: string;
41
+ }
42
+ type Offset = {
43
+ top?: string | number;
44
+ right?: string | number;
45
+ bottom?: string | number;
46
+ left?: string | number;
47
+ } | string | number;
48
+ interface ToasterProps {
49
+ id?: string;
50
+ invert?: boolean;
51
+ theme?: 'light' | 'dark' | 'system';
52
+ position?: Position;
53
+ hotkey?: string[];
54
+ richColors?: boolean;
55
+ expand?: boolean;
56
+ duration?: number;
57
+ gap?: number;
58
+ visibleToasts?: number;
59
+ closeButton?: boolean;
60
+ toastOptions?: ToastOptions;
61
+ className?: string;
62
+ style?: React.CSSProperties;
63
+ offset?: Offset;
64
+ mobileOffset?: Offset;
65
+ dir?: 'rtl' | 'ltr' | 'auto';
66
+ swipeDirections?: SwipeDirection[];
67
+ icons?: ToastIcons;
68
+ customAriaLabel?: string;
69
+ containerAriaLabel?: string;
70
+ }
71
+ type SwipeDirection = 'top' | 'right' | 'bottom' | 'left';
72
+
73
+ declare const VISIBLE_TOASTS_AMOUNT = 3;
74
+ declare const VIEWPORT_OFFSET = "24px";
75
+ declare const MOBILE_VIEWPORT_OFFSET = "16px";
76
+ declare const TOAST_LIFETIME = 4000;
77
+ declare const TOAST_WIDTH = 356;
78
+ declare const GAP = 14;
79
+ declare const SWIPE_THRESHOLD = 45;
80
+ declare const TIME_BEFORE_UNMOUNT = 200;
81
+ declare function cn(...classes: Array<string | undefined>): string;
82
+ declare function canUseDOM(): boolean;
83
+ declare function getDefaultSwipeDirections(position: string): Array<SwipeDirection>;
84
+ declare function getDocumentDirection(): ToasterProps['dir'];
85
+ declare function assignOffset(defaultOffset: ToasterProps['offset'], mobileOffset: ToasterProps['mobileOffset']): React.CSSProperties;
86
+
87
+ export { GAP, MOBILE_VIEWPORT_OFFSET, SWIPE_THRESHOLD, TIME_BEFORE_UNMOUNT, TOAST_LIFETIME, TOAST_WIDTH, VIEWPORT_OFFSET, VISIBLE_TOASTS_AMOUNT, assignOffset, canUseDOM, cn, getDefaultSwipeDirections, getDocumentDirection };
@@ -0,0 +1,87 @@
1
+ import React from 'react';
2
+
3
+ interface ToastClassnames {
4
+ toast?: string;
5
+ title?: string;
6
+ description?: string;
7
+ loader?: string;
8
+ closeButton?: string;
9
+ cancelButton?: string;
10
+ actionButton?: string;
11
+ success?: string;
12
+ error?: string;
13
+ info?: string;
14
+ warning?: string;
15
+ loading?: string;
16
+ default?: string;
17
+ content?: string;
18
+ icon?: string;
19
+ }
20
+ interface ToastIcons {
21
+ success?: React.ReactNode;
22
+ info?: React.ReactNode;
23
+ warning?: React.ReactNode;
24
+ error?: React.ReactNode;
25
+ loading?: React.ReactNode;
26
+ close?: React.ReactNode;
27
+ }
28
+ type Position = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center';
29
+ interface ToastOptions {
30
+ className?: string;
31
+ closeButton?: boolean;
32
+ descriptionClassName?: string;
33
+ style?: React.CSSProperties;
34
+ cancelButtonStyle?: React.CSSProperties;
35
+ actionButtonStyle?: React.CSSProperties;
36
+ duration?: number;
37
+ unstyled?: boolean;
38
+ classNames?: ToastClassnames;
39
+ closeButtonAriaLabel?: string;
40
+ toasterId?: string;
41
+ }
42
+ type Offset = {
43
+ top?: string | number;
44
+ right?: string | number;
45
+ bottom?: string | number;
46
+ left?: string | number;
47
+ } | string | number;
48
+ interface ToasterProps {
49
+ id?: string;
50
+ invert?: boolean;
51
+ theme?: 'light' | 'dark' | 'system';
52
+ position?: Position;
53
+ hotkey?: string[];
54
+ richColors?: boolean;
55
+ expand?: boolean;
56
+ duration?: number;
57
+ gap?: number;
58
+ visibleToasts?: number;
59
+ closeButton?: boolean;
60
+ toastOptions?: ToastOptions;
61
+ className?: string;
62
+ style?: React.CSSProperties;
63
+ offset?: Offset;
64
+ mobileOffset?: Offset;
65
+ dir?: 'rtl' | 'ltr' | 'auto';
66
+ swipeDirections?: SwipeDirection[];
67
+ icons?: ToastIcons;
68
+ customAriaLabel?: string;
69
+ containerAriaLabel?: string;
70
+ }
71
+ type SwipeDirection = 'top' | 'right' | 'bottom' | 'left';
72
+
73
+ declare const VISIBLE_TOASTS_AMOUNT = 3;
74
+ declare const VIEWPORT_OFFSET = "24px";
75
+ declare const MOBILE_VIEWPORT_OFFSET = "16px";
76
+ declare const TOAST_LIFETIME = 4000;
77
+ declare const TOAST_WIDTH = 356;
78
+ declare const GAP = 14;
79
+ declare const SWIPE_THRESHOLD = 45;
80
+ declare const TIME_BEFORE_UNMOUNT = 200;
81
+ declare function cn(...classes: Array<string | undefined>): string;
82
+ declare function canUseDOM(): boolean;
83
+ declare function getDefaultSwipeDirections(position: string): Array<SwipeDirection>;
84
+ declare function getDocumentDirection(): ToasterProps['dir'];
85
+ declare function assignOffset(defaultOffset: ToasterProps['offset'], mobileOffset: ToasterProps['mobileOffset']): React.CSSProperties;
86
+
87
+ export { GAP, MOBILE_VIEWPORT_OFFSET, SWIPE_THRESHOLD, TIME_BEFORE_UNMOUNT, TOAST_LIFETIME, TOAST_WIDTH, VIEWPORT_OFFSET, VISIBLE_TOASTS_AMOUNT, assignOffset, canUseDOM, cn, getDefaultSwipeDirections, getDocumentDirection };
@@ -0,0 +1,97 @@
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+
3
+ // Visible toasts amount
4
+ const VISIBLE_TOASTS_AMOUNT = 3;
5
+ // Viewport padding
6
+ const VIEWPORT_OFFSET = '24px';
7
+ // Mobile viewport padding
8
+ const MOBILE_VIEWPORT_OFFSET = '16px';
9
+ // Default lifetime of a toasts (in ms)
10
+ const TOAST_LIFETIME = 4000;
11
+ // Default toast width
12
+ const TOAST_WIDTH = 356;
13
+ // Default gap between toasts
14
+ const GAP = 14;
15
+ // Threshold to dismiss a toast
16
+ const SWIPE_THRESHOLD = 45;
17
+ // Equal to exit animation duration
18
+ const TIME_BEFORE_UNMOUNT = 200;
19
+ function cn(...classes) {
20
+ return classes.filter(Boolean).join(' ');
21
+ }
22
+ function canUseDOM() {
23
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
24
+ }
25
+ function getDefaultSwipeDirections(position) {
26
+ const [y, x] = position.split('-');
27
+ const directions = [];
28
+ if (y) {
29
+ directions.push(y);
30
+ }
31
+ if (x) {
32
+ directions.push(x);
33
+ }
34
+ return directions;
35
+ }
36
+ function getDocumentDirection() {
37
+ if (!canUseDOM()) return 'ltr';
38
+ const dirAttribute = document.documentElement.getAttribute('dir');
39
+ if (dirAttribute === 'auto' || !dirAttribute) {
40
+ return window.getComputedStyle(document.documentElement).direction;
41
+ }
42
+ return dirAttribute;
43
+ }
44
+ function assignOffset(defaultOffset, mobileOffset) {
45
+ const styles = {};
46
+ [
47
+ defaultOffset,
48
+ mobileOffset
49
+ ].forEach((offset, index)=>{
50
+ const isMobile = index === 1;
51
+ const prefix = isMobile ? '--mobile-offset' : '--offset';
52
+ const defaultValue = isMobile ? MOBILE_VIEWPORT_OFFSET : VIEWPORT_OFFSET;
53
+ function assignAll(value) {
54
+ [
55
+ 'top',
56
+ 'right',
57
+ 'bottom',
58
+ 'left'
59
+ ].forEach((key)=>{
60
+ styles[`${prefix}-${key}`] = typeof value === 'number' ? `${value}px` : value;
61
+ });
62
+ }
63
+ if (typeof offset === 'number' || typeof offset === 'string') {
64
+ assignAll(offset);
65
+ } else if (typeof offset === 'object') {
66
+ [
67
+ 'top',
68
+ 'right',
69
+ 'bottom',
70
+ 'left'
71
+ ].forEach((key)=>{
72
+ if (offset[key] === undefined) {
73
+ styles[`${prefix}-${key}`] = defaultValue;
74
+ } else {
75
+ styles[`${prefix}-${key}`] = typeof offset[key] === 'number' ? `${offset[key]}px` : offset[key];
76
+ }
77
+ });
78
+ } else {
79
+ assignAll(defaultValue);
80
+ }
81
+ });
82
+ return styles;
83
+ }
84
+
85
+ exports.GAP = GAP;
86
+ exports.MOBILE_VIEWPORT_OFFSET = MOBILE_VIEWPORT_OFFSET;
87
+ exports.SWIPE_THRESHOLD = SWIPE_THRESHOLD;
88
+ exports.TIME_BEFORE_UNMOUNT = TIME_BEFORE_UNMOUNT;
89
+ exports.TOAST_LIFETIME = TOAST_LIFETIME;
90
+ exports.TOAST_WIDTH = TOAST_WIDTH;
91
+ exports.VIEWPORT_OFFSET = VIEWPORT_OFFSET;
92
+ exports.VISIBLE_TOASTS_AMOUNT = VISIBLE_TOASTS_AMOUNT;
93
+ exports.assignOffset = assignOffset;
94
+ exports.canUseDOM = canUseDOM;
95
+ exports.cn = cn;
96
+ exports.getDefaultSwipeDirections = getDefaultSwipeDirections;
97
+ exports.getDocumentDirection = getDocumentDirection;
@@ -0,0 +1,83 @@
1
+ // Visible toasts amount
2
+ const VISIBLE_TOASTS_AMOUNT = 3;
3
+ // Viewport padding
4
+ const VIEWPORT_OFFSET = '24px';
5
+ // Mobile viewport padding
6
+ const MOBILE_VIEWPORT_OFFSET = '16px';
7
+ // Default lifetime of a toasts (in ms)
8
+ const TOAST_LIFETIME = 4000;
9
+ // Default toast width
10
+ const TOAST_WIDTH = 356;
11
+ // Default gap between toasts
12
+ const GAP = 14;
13
+ // Threshold to dismiss a toast
14
+ const SWIPE_THRESHOLD = 45;
15
+ // Equal to exit animation duration
16
+ const TIME_BEFORE_UNMOUNT = 200;
17
+ function cn(...classes) {
18
+ return classes.filter(Boolean).join(' ');
19
+ }
20
+ function canUseDOM() {
21
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
22
+ }
23
+ function getDefaultSwipeDirections(position) {
24
+ const [y, x] = position.split('-');
25
+ const directions = [];
26
+ if (y) {
27
+ directions.push(y);
28
+ }
29
+ if (x) {
30
+ directions.push(x);
31
+ }
32
+ return directions;
33
+ }
34
+ function getDocumentDirection() {
35
+ if (!canUseDOM()) return 'ltr';
36
+ const dirAttribute = document.documentElement.getAttribute('dir');
37
+ if (dirAttribute === 'auto' || !dirAttribute) {
38
+ return window.getComputedStyle(document.documentElement).direction;
39
+ }
40
+ return dirAttribute;
41
+ }
42
+ function assignOffset(defaultOffset, mobileOffset) {
43
+ const styles = {};
44
+ [
45
+ defaultOffset,
46
+ mobileOffset
47
+ ].forEach((offset, index)=>{
48
+ const isMobile = index === 1;
49
+ const prefix = isMobile ? '--mobile-offset' : '--offset';
50
+ const defaultValue = isMobile ? MOBILE_VIEWPORT_OFFSET : VIEWPORT_OFFSET;
51
+ function assignAll(value) {
52
+ [
53
+ 'top',
54
+ 'right',
55
+ 'bottom',
56
+ 'left'
57
+ ].forEach((key)=>{
58
+ styles[`${prefix}-${key}`] = typeof value === 'number' ? `${value}px` : value;
59
+ });
60
+ }
61
+ if (typeof offset === 'number' || typeof offset === 'string') {
62
+ assignAll(offset);
63
+ } else if (typeof offset === 'object') {
64
+ [
65
+ 'top',
66
+ 'right',
67
+ 'bottom',
68
+ 'left'
69
+ ].forEach((key)=>{
70
+ if (offset[key] === undefined) {
71
+ styles[`${prefix}-${key}`] = defaultValue;
72
+ } else {
73
+ styles[`${prefix}-${key}`] = typeof offset[key] === 'number' ? `${offset[key]}px` : offset[key];
74
+ }
75
+ });
76
+ } else {
77
+ assignAll(defaultValue);
78
+ }
79
+ });
80
+ return styles;
81
+ }
82
+
83
+ export { GAP, MOBILE_VIEWPORT_OFFSET, SWIPE_THRESHOLD, TIME_BEFORE_UNMOUNT, TOAST_LIFETIME, TOAST_WIDTH, VIEWPORT_OFFSET, VISIBLE_TOASTS_AMOUNT, assignOffset, canUseDOM, cn, getDefaultSwipeDirections, getDocumentDirection };