alert90s 1.0.8 → 1.0.10

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,209 +1,220 @@
1
- # Alert90s
2
-
3
- A "Neo Brutalism 90s" style JavaScript alert library. Completely standalone and dependency-free (CSS is injected automatically).
4
-
5
- Heavily inspired by **SweetAlert2**. It supports many of the same API signatures (Promises, Inputs, PreConfirm, Timers, RTL), making it practically a drop-in UI replacement for existing projects that want a brutalist 90s makeover, just using the `Alert90s` object instead!
6
-
7
- ## Installation
8
-
9
- You can install it via npm:
10
-
11
- ```bash
12
- npm install alert90s
13
- ```
14
-
15
- Or just include the built file in your project:
16
-
17
- ```html
18
- <script src="path/to/alert90s.min.js"></script>
19
- ```
20
-
21
- ## Usage
22
-
23
- If using a bundler (Webpack, Vite, Rollup):
24
-
25
- ```javascript
26
- import Alert90s from "alert90s";
27
-
28
- // Basic Message
29
- Alert90s.show("Any fool can use a computer");
30
- ```
31
-
32
- If using via `<script>` tag, the library automatically registered on the global `window` object as `Alert90s` and `Swal`.
33
-
34
- ## Examples
35
-
36
- ### 1. Promises & Deny Buttons
37
-
38
- ```javascript
39
- Alert90s.fire({
40
- title: "Do you want to save the changes?",
41
- showDenyButton: true,
42
- showCancelButton: true,
43
- confirmButtonText: "Save",
44
- denyButtonText: `Don't save`,
45
- }).then((result) => {
46
- if (result.isConfirmed) {
47
- Alert90s.fire("Saved!", "", "success");
48
- } else if (result.isDenied) {
49
- Alert90s.fire("Changes are not saved", "", "info");
50
- }
51
- });
52
- ```
53
-
54
- ### 2. AJAX Requests & Inputs
55
-
56
- ```javascript
57
- Alert90s.fire({
58
- title: "Submit your Github username",
59
- input: "text",
60
- inputAttributes: {
61
- autocapitalize: "off",
62
- },
63
- showCancelButton: true,
64
- confirmButtonText: "Look up",
65
- showLoaderOnConfirm: true,
66
- preConfirm: async (login) => {
67
- try {
68
- const response = await fetch(`https://api.github.com/users/${login}`);
69
- if (!response.ok) {
70
- return Alert90s.showValidationMessage(
71
- `${JSON.stringify(await response.json())}`,
72
- );
73
- }
74
- return response.json();
75
- } catch (error) {
76
- Alert90s.showValidationMessage(`Request failed: ${error}`);
77
- }
78
- },
79
- allowOutsideClick: () => !Alert90s.isLoading(),
80
- }).then((result) => {
81
- if (result.isConfirmed) {
82
- Alert90s.fire({ title: `Avatar`, imageUrl: result.value.avatar_url });
83
- }
84
- });
85
- ```
86
-
87
- ### 3. RTL Support
88
-
89
- ```javascript
90
- Alert90s.fire({
91
- title: "هل تريد الاستمرار؟",
92
- icon: "question",
93
- iconHtml: "؟",
94
- confirmButtonText: "نعم",
95
- cancelButtonText: "لا",
96
- showCancelButton: true,
97
- showCloseButton: true,
98
- dir: "rtl",
99
- });
100
- ```
101
-
102
- ### 4. Custom Animate.css Animations
103
-
104
- ```javascript
105
- Alert90s.fire({
106
- title: "Custom animation with Animate.css",
107
- showClass: { popup: "animate__animated animate__fadeInUp" },
108
- hideClass: { popup: "animate__animated animate__fadeOutDown" },
109
- });
110
- ```
111
-
112
- ### 5. Toast Notification
113
-
114
- ```javascript
115
- Alert90s.fire({
116
- toast: true,
117
- position: "top-end",
118
- icon: "success",
119
- title: "Saved successfully",
120
- showConfirmButton: false,
121
- timer: 3000,
122
- });
123
- ```
124
-
125
- ## CSS-only Buttons
126
-
127
- Alert90s also ships with a standalone CSS button library. Just add the classes to your own `<button>` or `<a>` elements for an instant neo-brutalist feel!
128
-
129
- ```html
130
- <!-- Base Button -->
131
- <button class="btn90s">Base Button</button>
132
-
133
- <!-- Color Variants -->
134
- <button class="btn90s primary">Primary</button>
135
- <button class="btn90s success">Success</button>
136
- <button class="btn90s warning">Warning</button>
137
- <button class="btn90s danger">Danger</button>
138
- <button class="btn90s dark">Dark</button>
139
-
140
- <!-- Sizes -->
141
- <button class="btn90s sm primary">Small</button>
142
- <button class="btn90s lg danger">Large</button>
143
- ```
144
-
145
- ## Tooltips / Popovers
146
-
147
- Alert90s includes a lightweight, built-in tooltip library that styles any element with a `data-alert90s-tooltip` attribute.
148
-
149
- ```html
150
- <!-- Basic (Top default) -->
151
- <button data-alert90s-tooltip="I appear on top!">Hover Me</button>
152
-
153
- <!-- Positions (top, bottom, left, right) -->
154
- <button data-alert90s-tooltip="Bottom side!" data-alert90s-position="bottom">
155
- Hover
156
- </button>
157
-
158
- <!-- Colors (yellow, cyan, pink, base, dark) -->
159
- <button data-alert90s-tooltip="Cyan Tooltip" data-alert90s-color="cyan">
160
- Hover
161
- </button>
162
- ```
163
-
164
- **Note:** Tooltips initialize automatically on `DOMContentLoaded`. If you load dynamic content later, call `Alert90s.initTooltips()` to initialize them.
165
-
166
- ## Support
167
-
168
- If you find this project useful, you can support its development:
169
-
170
- - [Saweria](https://saweria.co/adewanggar)
171
- - [Ko-fi](https://ko-fi.com/adewanggar)
172
-
173
- ## Advanced Options
174
-
175
- | Option | Type | Default | Description |
176
- | ---------------- | -------- | ----------- | ----------------------------------------------------------------- |
177
- | background | String | '' | Custom background color for the modal. |
178
- | color | String | '' | Custom text color for the modal body. |
179
- | titleColor | String | '' | Custom title color. |
180
- | iconColor | String | '' | Custom icon color (including SVG stroke). |
181
- | title | String | '' | The title of the alert. Supports HTML. |
182
- | text/message | String | '' | The message body of the alert. |
183
- | html | String | '' | A custom HTML description for the alert. |
184
- | icon | String | '' | Standard icons: `warning`, `error`, `info`, `success`, `question` |
185
- | iconHtml | String | '' | Custom HTML string for the icon. |
186
- | footer | String | '' | Custom HTML for the footer section. |
187
- | imageUrl | String | '' | URL for an image to display. |
188
- | input | String | null | Type of input: `text`, `password`, `email`, `textarea`, etc. |
189
- | dir | String | 'auto' | Text direction. Set `rtl` for Arabic/Hebrew. |
190
- | position | String | 'center' | `top`, `top-end`, `bottom-start`, etc. |
191
- | timer | Number | null | Auto close timer in milliseconds. |
192
- | timerProgressBar | Boolean | false | Display progress bar at the bottom. |
193
- | toast | Boolean | false | Display the alert as a non-blocking toast notification. |
194
- | loaderType | String | 'hourglass' | Type of loader: `hourglass`, `ascii`, `blinking`, `progress`. |
195
- | draggable | Boolean | false | Allow moving the modal dragging its header. |
196
- | showDenyButton | Boolean | false | Show the third middle deny button. |
197
- | preConfirm | Function | null | Async function executed before confirm executes. |
198
-
199
- ## Methods
200
-
201
- - `Alert90s.fire(options)` or `Alert90s.show(options)`
202
- - `Alert90s.showLoading()` / `Alert90s.hideLoading()`
203
- - `Alert90s.showValidationMessage(message)` / `Alert90s.resetValidationMessage()`
204
- - `Alert90s.getTimerLeft()`
205
- - `Alert90s.getPopup()`
206
-
207
- ## License
208
-
209
- MIT
1
+ # Alert90s
2
+
3
+ A "Neo Brutalism 90s" style JavaScript alert library. Completely standalone and dependency-free (CSS is injected automatically).
4
+
5
+ Heavily inspired by **SweetAlert2**. It supports many of the same API signatures (Promises, Inputs, PreConfirm, Timers, RTL), making it practically a drop-in UI replacement for existing projects that want a brutalist 90s makeover, just using the `Alert90s` object instead!
6
+
7
+ ## Installation
8
+
9
+ You can install it via npm:
10
+
11
+ ```bash
12
+ npm install alert90s
13
+ ```
14
+
15
+ Or just include the built file in your project:
16
+
17
+ ```html
18
+ <script src="path/to/alert90s.min.js"></script>
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ If using a bundler (Webpack, Vite, Rollup):
24
+
25
+ ```javascript
26
+ import Alert90s from "alert90s";
27
+
28
+ // Basic Message
29
+ Alert90s.show("Any fool can use a computer");
30
+ ```
31
+
32
+ If using via `<script>` tag, the library automatically registered on the global `window` object as `Alert90s` and `Swal`.
33
+
34
+ ## Examples
35
+
36
+ ### 1. Promises & Deny Buttons
37
+
38
+ ```javascript
39
+ Alert90s.fire({
40
+ title: "Do you want to save the changes?",
41
+ showDenyButton: true,
42
+ showCancelButton: true,
43
+ confirmButtonText: "Save",
44
+ denyButtonText: `Don't save`,
45
+ }).then((result) => {
46
+ if (result.isConfirmed) {
47
+ Alert90s.fire("Saved!", "", "success");
48
+ } else if (result.isDenied) {
49
+ Alert90s.fire("Changes are not saved", "", "info");
50
+ }
51
+ });
52
+ ```
53
+
54
+ ### 2. AJAX Requests & Inputs
55
+
56
+ ```javascript
57
+ Alert90s.fire({
58
+ title: "Submit your Github username",
59
+ input: "text",
60
+ inputAttributes: {
61
+ autocapitalize: "off",
62
+ },
63
+ showCancelButton: true,
64
+ confirmButtonText: "Look up",
65
+ showLoaderOnConfirm: true,
66
+ preConfirm: async (login) => {
67
+ try {
68
+ const response = await fetch(`https://api.github.com/users/${login}`);
69
+ if (!response.ok) {
70
+ return Alert90s.showValidationMessage(
71
+ `${JSON.stringify(await response.json())}`,
72
+ );
73
+ }
74
+ return response.json();
75
+ } catch (error) {
76
+ Alert90s.showValidationMessage(`Request failed: ${error}`);
77
+ }
78
+ },
79
+ allowOutsideClick: () => !Alert90s.isLoading(),
80
+ }).then((result) => {
81
+ if (result.isConfirmed) {
82
+ Alert90s.fire({ title: `Avatar`, imageUrl: result.value.avatar_url });
83
+ }
84
+ });
85
+ ```
86
+
87
+ ### 3. RTL Support
88
+
89
+ ```javascript
90
+ Alert90s.fire({
91
+ title: "هل تريد الاستمرار؟",
92
+ icon: "question",
93
+ iconHtml: "؟",
94
+ confirmButtonText: "نعم",
95
+ cancelButtonText: "لا",
96
+ showCancelButton: true,
97
+ showCloseButton: true,
98
+ dir: "rtl",
99
+ });
100
+ ```
101
+
102
+ ### 4. Custom Animate.css Animations
103
+
104
+ ```javascript
105
+ Alert90s.fire({
106
+ title: "Custom animation with Animate.css",
107
+ showClass: { popup: "animate__animated animate__fadeInUp" },
108
+ hideClass: { popup: "animate__animated animate__fadeOutDown" },
109
+ });
110
+ ```
111
+
112
+ ### 5. Toast Notification
113
+
114
+ ```javascript
115
+ Alert90s.fire({
116
+ toast: true,
117
+ position: "top-end",
118
+ icon: "success",
119
+ title: "Saved successfully",
120
+ showConfirmButton: false,
121
+ timer: 3000,
122
+ });
123
+ ```
124
+
125
+ ## CSS-only Buttons
126
+
127
+ Alert90s also ships with a standalone CSS button library. Just add the classes to your own `<button>` or `<a>` elements for an instant neo-brutalist feel!
128
+
129
+ ```html
130
+ <!-- Base Button -->
131
+ <button class="btn90s">Base Button</button>
132
+
133
+ <!-- Color Variants -->
134
+ <button class="btn90s primary">Primary</button>
135
+ <button class="btn90s success">Success</button>
136
+ <button class="btn90s warning">Warning</button>
137
+ <button class="btn90s danger">Danger</button>
138
+ <button class="btn90s dark">Dark</button>
139
+
140
+ <!-- Sizes -->
141
+ <button class="btn90s sm primary">Small</button>
142
+ <button class="btn90s lg danger">Large</button>
143
+ ```
144
+
145
+ ## Tooltips / Popovers
146
+
147
+ Alert90s includes a lightweight, built-in tooltip library that styles any element with a `data-alert90s-tooltip` attribute.
148
+
149
+ ```html
150
+ <!-- Basic (Top default) -->
151
+ <button data-alert90s-tooltip="I appear on top!">Hover Me</button>
152
+
153
+ <!-- Positions (top, bottom, left, right) -->
154
+ <button data-alert90s-tooltip="Bottom side!" data-alert90s-position="bottom">
155
+ Hover
156
+ </button>
157
+
158
+ <!-- Colors (yellow, cyan, pink, base, dark) -->
159
+ <button data-alert90s-tooltip="Cyan Tooltip" data-alert90s-color="cyan">
160
+ Hover
161
+ </button>
162
+ ```
163
+
164
+ **Note:** Tooltips initialize automatically on `DOMContentLoaded`. If you load dynamic content later, call `Alert90s.initTooltips()` to initialize them.
165
+
166
+ ## Support
167
+
168
+ If you find this project useful, you can support its development:
169
+
170
+ - [Saweria](https://saweria.co/adewanggar)
171
+ - [Ko-fi](https://ko-fi.com/adewanggar)
172
+
173
+ If you'd like to collaborate or just say hi, visit my [Portfolio Website](https://www.dewangga.site/).
174
+
175
+ ## Advanced Options
176
+
177
+ | Option | Type | Default | Description |
178
+ | ----------------- | -------- | ----------- | --------------------------------------------------------------------------------------------------------- |
179
+ | background | String | '' | Custom background color for the modal. |
180
+ | color | String | '' | Custom text color for the modal body. |
181
+ | titleColor | String | '' | Custom title color. |
182
+ | iconColor | String | '' | Custom icon color (including SVG stroke). |
183
+ | title | String | '' | The title of the alert. Supports HTML. |
184
+ | text/message | String | '' | The message body of the alert. |
185
+ | html | String | '' | A custom HTML description for the alert. |
186
+ | icon | String | '' | Standard icons: `warning`, `error`, `info`, `success`, `question` |
187
+ | iconHtml | String | '' | Custom HTML string for the icon. |
188
+ | footer | String | '' | Custom HTML for the footer section. |
189
+ | imageUrl | String | '' | URL for an image to display. |
190
+ | input | String | null | Generate an input: `'text'`, `'password'`, `'textarea'`, `'select'`, `'radio'`, `'checkbox'`, `'toggle'`. |
191
+ | inputPlaceholder | String | '' | Placeholder text or label for `checkbox`/`toggle`. |
192
+ | inputValue | String | '' | Initial value or checked state (for boolean inputs). |
193
+ | inputOptions | Object | {} | Object mapping `{value: 'Label'}` for `select`/`radio`. |
194
+ | inputAttributes | Object | {} | Custom HTML attributes for the input element. |
195
+ | dir | String | 'auto' | Text direction. Set `rtl` for Arabic/Hebrew. |
196
+ | position | String | 'center' | `top`, `top-end`, `bottom-start`, etc. |
197
+ | timer | Number | null | Auto close timer in milliseconds. |
198
+ | timerProgressBar | Boolean | false | Display progress bar at the bottom. |
199
+ | toast | Boolean | false | Display the alert as a non-blocking toast notification. |
200
+ | loaderType | String | 'hourglass' | Type of loader: `hourglass`, `ascii`, `blinking`, `progress`. |
201
+ | draggable | Boolean | false | Allow moving the modal dragging its header. |
202
+ | showDenyButton | Boolean | false | Show the third middle deny button. |
203
+ | preConfirm | Function | null | Async function executed before confirm executes. |
204
+ | allowOutsideClick | Function | null | Async function executed before confirm executes. |
205
+
206
+ ## Methods
207
+
208
+ - `Alert90s.fire(options)` or `Alert90s.show(options)`
209
+ - `Alert90s.showLoading()` / `Alert90s.hideLoading()`
210
+ - `Alert90s.showValidationMessage(message)` / `Alert90s.resetValidationMessage()`
211
+ - `Alert90s.getTimerLeft()`
212
+ - `Alert90s.getPopup()`
213
+ - `Alert90s.initTooltips()`
214
+ - `Alert90s.destroyTooltips()`
215
+
216
+ ## License
217
+
218
+ MIT
219
+
220
+ # alert90s
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Alert90s=t()}(this,function(){"use strict";!function(e,t){void 0===t&&(t={});var o=t.insertAt;if("undefined"!=typeof document){var r=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.type="text/css","top"===o&&r.firstChild?r.insertBefore(n,r.firstChild):r.appendChild(n),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(document.createTextNode(e))}}('.alert90s-overlay{animation:alert90s-fade-in .2s ease-out forwards;backdrop-filter:blur(4px);background-color:rgba(0,0,0,.6);box-sizing:border-box;display:flex;font-family:inherit;inset:0;padding:1rem;position:fixed;z-index:99999}.alert90s-overlay.alert90s-pos-center{align-items:center;justify-content:center}.alert90s-overlay.alert90s-pos-top{align-items:flex-start;justify-content:center}.alert90s-overlay.alert90s-pos-top-start{align-items:flex-start;justify-content:flex-start}.alert90s-overlay.alert90s-pos-top-end{align-items:flex-start;justify-content:flex-end}.alert90s-overlay.alert90s-pos-bottom{align-items:flex-end;justify-content:center}.alert90s-overlay.alert90s-pos-bottom-start{align-items:flex-end;justify-content:flex-start}.alert90s-overlay.alert90s-pos-bottom-end{align-items:flex-end;justify-content:flex-end}.alert90s-overlay.alert90s-pos-center-start{align-items:center;justify-content:flex-start}.alert90s-overlay.alert90s-pos-center-end{align-items:center;justify-content:flex-end}.alert90s-overlay *{box-sizing:border-box}.alert90s-box{align-items:center;animation:alert90s-pop-in .3s cubic-bezier(.175,.885,.32,1.275) forwards;background-color:#fff;border:4px solid #000;box-shadow:12px 12px 0 0 #000;display:flex;flex-direction:column;max-height:95vh;max-width:28rem;position:relative;text-align:center;width:100%}.alert90s-box[dir=rtl]{text-align:right}.alert90s-box.is-draggable{position:absolute}.alert90s-body{align-items:center;display:flex;flex-direction:column;overflow-y:auto;padding:3rem 2rem 2rem;scrollbar-width:none;width:100%}.alert90s-body::-webkit-scrollbar{display:none}.alert90s-header{align-items:center;background-color:#e2e8f0;border-bottom:4px solid #000;display:flex;height:2rem;justify-content:space-between;left:0;padding:0 .5rem;position:absolute;top:0;width:100%;z-index:10}.alert90s-header.draggable{cursor:grab}.alert90s-header.draggable:active{cursor:grabbing}.alert90s-header-left{display:flex;gap:.25rem}.alert90s-box[dir=rtl] .alert90s-header{flex-direction:row-reverse}.alert90s-header-dot{background-color:#fff;border:2px solid #000;height:.75rem;width:.75rem}.alert90s-header-right{align-items:center;display:flex;gap:.5rem;z-index:11}.alert90s-box[dir=rtl] .alert90s-header-right{flex-direction:row-reverse}.alert90s-header-title{font-size:10px;font-weight:700;letter-spacing:.1em;pointer-events:none;text-transform:uppercase}.alert90s-close-btn{align-items:center;background-color:#ef4444;border:2px solid #000;box-shadow:none;cursor:pointer;display:flex;height:1.25rem;justify-content:center;margin:0;padding:0;transition:transform .1s,background-color .1s;width:1.25rem}.alert90s-close-btn:hover{background-color:#f87171;transform:scale(1.1)}.alert90s-close-btn span{color:#000;font-size:14px;font-weight:700;line-height:1}.alert90s-image-container{align-items:center;background:#fff;border:4px solid #000;box-shadow:4px 4px 0 0 #000;display:flex;justify-content:center;margin-bottom:1rem;overflow:hidden;width:100%}.alert90s-image-container img{display:block;height:auto;max-width:100%}.alert90s-icon{align-items:center;border:4px solid #000;border-radius:9999px;box-shadow:4px 4px 0 0 #000;display:flex;flex-shrink:0;height:4rem;justify-content:center;margin-bottom:1rem;width:4rem}.alert90s-icon img,.alert90s-icon svg{height:2rem;width:2rem}.alert90s-icon-custom{font-size:2.25rem;font-weight:700;line-height:1}.alert90s-icon.warning{background-color:#facc15}.alert90s-icon.danger,.alert90s-icon.error{background-color:#ef4444;color:#fff}.alert90s-icon.info,.alert90s-icon.question{background-color:#60a5fa}.alert90s-icon.success{background-color:#4ade80}.alert90s-title{color:#1a1a1a;font-size:1.5rem;font-weight:900;letter-spacing:.1em;line-height:1.2;margin:0 0 .5rem;text-transform:uppercase}.alert90s-message{color:#475569;font-weight:700}.alert90s-html,.alert90s-message{font-size:.875rem;margin:0 0 1.5rem;max-width:100%}.alert90s-html{color:#1a1a1a;line-height:1.5}.alert90s-box[dir=rtl] .alert90s-html{text-align:right}.alert90s-html a{color:#2563eb;font-weight:700;text-decoration:underline;text-decoration-thickness:2px}.alert90s-html a:hover{background-color:#bfdbfe}.alert90s-html b,.alert90s-html strong{font-weight:900}.alert90s-input-container{margin-bottom:1.5rem;width:100%}.alert90s-input{background-color:#f8fafc;border:4px solid #000;box-shadow:inset 4px 4px 0 0 rgba(0,0,0,.05);font-family:inherit;font-size:1rem;font-weight:700;outline:none;padding:.75rem;transition:background-color .2s;width:100%}.alert90s-input:focus{background-color:#fff;border-color:#2563eb}textarea.alert90s-input{min-height:100px;resize:vertical}.alert90s-validation-message{background-color:#fef2f2;border:4px solid #000;border-left:8px solid #ef4444;color:#ef4444;display:none;font-size:.875rem;font-weight:700;margin-bottom:1.5rem;padding:.75rem;text-align:left;width:100%}.alert90s-box[dir=rtl] .alert90s-validation-message{border-left-color:#000;border-left-width:4px;border-right-color:#ef4444;border-right-width:8px;text-align:right}.alert90s-actions{display:flex;flex-direction:column;gap:1rem;justify-content:center;width:100%}@media (min-width:640px){.alert90s-actions{flex-direction:row}}.alert90s-button{align-items:center;background-color:#fff;border:4px solid #000;box-shadow:4px 4px 0 0 #000;color:#000;cursor:pointer;display:flex;font-family:inherit;font-size:.875rem;font-weight:900;gap:.5rem;justify-content:center;letter-spacing:.1em;margin:0;padding:.75rem 1rem;text-transform:uppercase;transition:background-color .1s;width:100%}@media (min-width:640px){.alert90s-button{flex:1;min-width:100px;width:auto}}.alert90s-button:active{box-shadow:0 0 0 0 #000;transform:translate(4px,4px)}.alert90s-button:focus{outline:2px dashed #000;outline-offset:4px}.alert90s-button.cancel{background-color:#f87171}.alert90s-button.cancel:hover{background-color:#fca5a5}.alert90s-button.deny{background-color:#fb923c}.alert90s-button.deny:hover{background-color:#fdba74}.alert90s-button.confirm{background-color:#4ade80}.alert90s-button.confirm:hover{background-color:#86efac}.alert90s-footer{border-top:4px solid #000;color:#475569;font-size:.75rem;font-weight:700;margin-top:1.5rem;padding-top:1rem;width:100%}.alert90s-footer a{color:#2563eb;text-decoration:underline;text-decoration-thickness:2px}.alert90s-footer a:hover{background-color:#bfdbfe}.alert90s-progress-bar{animation:alert90s-progress linear forwards;background-color:#000;bottom:0;height:6px;left:0;position:absolute;width:100%}.alert90s-loader{display:flex;padding:1rem 0}.alert90s-loader,.alert90s-spinner{align-items:center;justify-content:center}.alert90s-spinner{display:inline-flex}.alert90s-spinner.hourglass{animation:alert90s-hourglass 2s ease-in-out infinite;font-size:2.5rem;line-height:1}.alert90s-spinner.ascii{font-family:monospace;font-size:2rem;font-weight:700}.alert90s-spinner.ascii:after{animation:alert90s-ascii .5s steps(4) infinite;content:"|"}.alert90s-spinner.blinking{font-family:monospace;font-size:1.5rem;font-weight:700;letter-spacing:.1em}.alert90s-spinner.blinking .cursor{animation:alert90s-blink 1s step-end infinite}.alert90s-spinner.progress{background-color:#cbd5e1;border:2px solid #000;box-shadow:inset 2px 2px 0 0 #64748b,inset -2px -2px 0 0 #f8fafc;height:24px;overflow:hidden;padding:2px;position:relative;width:200px}.alert90s-spinner.progress:before{animation:alert90s-marquee 1.5s linear infinite;background-color:#1d4ed8;background-image:repeating-linear-gradient(90deg,#1d4ed8,#1d4ed8 10px,transparent 0,transparent 12px);content:"";height:calc(100% - 4px);left:0;position:absolute;top:2px;width:40%}@keyframes alert90s-hourglass{0%{transform:rotate(0)}25%{transform:rotate(180deg)}50%{transform:rotate(180deg)}75%{transform:rotate(1turn)}to{transform:rotate(1turn)}}@keyframes alert90s-ascii{0%{content:"|"}25%{content:"/"}50%{content:"-"}75%{content:"\\\\"}to{content:"|"}}@keyframes alert90s-blink{50%{opacity:0}}@keyframes alert90s-marquee{0%{transform:translateX(-100%)}to{transform:translateX(250px)}}@keyframes alert90s-progress{0%{width:100%}to{width:0}}@keyframes alert90s-fade-in{0%{opacity:0}to{opacity:1}}@keyframes alert90s-pop-in{0%{opacity:0;transform:scale(.95) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes alert90s-fade-out{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.95) translateY(10px)}}.alert90s-overlay.toast-overlay{backdrop-filter:none!important;background-color:transparent!important;pointer-events:none}.alert90s-box.alert90s-toast{align-items:stretch;box-shadow:6px 6px 0 0 #000;flex-direction:row;max-width:100%;min-width:250px;padding:0;pointer-events:auto;width:auto}.alert90s-toast .alert90s-header{display:none}.alert90s-toast .alert90s-body{align-items:center;flex-direction:row;gap:1rem;padding:1rem 1.5rem}.alert90s-toast .alert90s-icon{height:2.5rem;margin-bottom:0;width:2.5rem}.alert90s-toast .alert90s-icon img,.alert90s-toast .alert90s-icon svg{height:1.25rem;width:1.25rem}.alert90s-content-wrapper{align-items:center;display:flex;flex-direction:column;width:100%}.alert90s-toast .alert90s-content-wrapper{align-items:flex-start;text-align:left}.alert90s-box.alert90s-toast[dir=rtl] .alert90s-content-wrapper{align-items:flex-end;text-align:right}.alert90s-toast .alert90s-title{font-size:1rem;margin-bottom:.25rem}.alert90s-toast .alert90s-html,.alert90s-toast .alert90s-message{font-size:.875rem;margin-bottom:0}.alert90s-toast-close{align-items:center;background-color:#ef4444;border:2px solid #000;box-shadow:none;cursor:pointer;display:flex;height:1.5rem;justify-content:center;margin:0;margin-inline-start:auto;padding:0;transition:transform .1s,background-color .1s;width:1.5rem}.alert90s-toast-close span{color:#000;display:block;font-size:10px;font-weight:700;line-height:1}.alert90s-toast-close:hover{background-color:#f87171;transform:scale(1.1)}.btn90s{align-items:center;background-color:#fff;border:4px solid #000;box-shadow:4px 4px 0 0 #000;color:#000;cursor:pointer;display:inline-flex;font-family:inherit;font-size:1rem;font-weight:900;justify-content:center;letter-spacing:.05em;margin:.25rem;padding:.75rem 1.5rem;text-decoration:none;text-transform:uppercase;transition:transform .1s,box-shadow .1s,background-color .1s}.btn90s:active{box-shadow:0 0 0 0 #000;transform:translate(4px,4px)}.btn90s:focus-visible{outline:2px dashed #000;outline-offset:4px}.btn90s.primary{background-color:#00f0ff}.btn90s.primary:hover{background-color:#66f6ff}.btn90s.success{background-color:#4ade80}.btn90s.success:hover{background-color:#86efac}.btn90s.warning{background-color:#ffc900}.btn90s.warning:hover{background-color:#ffe066}.btn90s.danger{background-color:#ff90e8}.btn90s.danger:hover{background-color:#ffbaf0}.btn90s.dark{background-color:#000;border-color:#000;color:#fff}.btn90s.dark:hover{background-color:#333}.btn90s.sm{border-width:3px;box-shadow:3px 3px 0 0 #000;font-size:.875rem;padding:.5rem 1rem}.btn90s.sm:active{transform:translate(3px,3px)}.btn90s.lg{border-width:5px;box-shadow:6px 6px 0 0 #000;font-size:1.25rem;padding:1rem 2rem}.btn90s.lg:active{transform:translate(6px,6px)}.alert90s-tooltip{animation:tooltip-pop .15s cubic-bezier(.175,.885,.32,1.275) forwards;background-color:#fff;border:3px solid #000;box-shadow:4px 4px 0 0 #000;color:#000;display:none;font-family:inherit;font-size:.875rem;font-weight:700;max-width:300px;padding:.5rem 1rem;pointer-events:none;position:absolute;white-space:pre-wrap;z-index:100000}.alert90s-tooltip.show{display:block}.alert90s-tooltip.c-yellow{background-color:#fef08a}.alert90s-tooltip.c-cyan{background-color:#00f0ff}.alert90s-tooltip.c-pink{background-color:#ff90e8}.alert90s-tooltip.c-base{background-color:#fff}.alert90s-tooltip.c-dark{background-color:#000;color:#fff}.alert90s-tooltip:after{border-style:solid;content:"";height:0;position:absolute;width:0}.alert90s-tooltip.pos-top:after{border-color:#000 transparent transparent;border-width:8px 8px 0;bottom:-8px;left:50%;margin-left:-8px}.alert90s-tooltip.pos-bottom:after{border-color:transparent transparent #000;border-width:0 8px 8px;left:50%;margin-left:-8px;top:-8px}.alert90s-tooltip.pos-left:after{border-color:transparent transparent transparent #000;border-width:8px 0 8px 8px;margin-top:-8px;right:-8px;top:50%}.alert90s-tooltip.pos-right:after{border-color:transparent #000 transparent transparent;border-width:8px 8px 8px 0;left:-8px;margin-top:-8px;top:50%}@keyframes tooltip-pop{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}');class e{static getOptions(){return this.currentOptions||{}}static getPopup(){return this.currentPopup||null}static getTimerLeft(){if(!this.timerEnd)return;const e=this.timerEnd-Date.now();return e>0?e:0}static isLoading(){const e=this.getPopup();if(!e)return!1;const t=e.querySelector(".alert90s-actions"),o=e.querySelector(".alert90s-loader");return t&&"none"===t.style.display||!!o}static showLoading(){const t=this.getPopup();if(t){const o=t.querySelector(".alert90s-actions");o&&(o.style.display="none");let r=t.querySelector(".alert90s-loader");if(!r){r=document.createElement("div"),r.className="alert90s-loader";const n=e.currentOptions&&e.currentOptions.loaderType||"hourglass";r.innerHTML="ascii"===n?'<div class="alert90s-spinner ascii"></div>':"blinking"===n?'<div class="alert90s-spinner blinking">LOADING<span class="cursor">_</span></div>':"progress"===n?'<div class="alert90s-spinner progress"></div>':'<div class="alert90s-spinner hourglass">⏳</div>',o&&o.parentNode?o.parentNode.insertBefore(r,o):t.querySelector(".alert90s-body").appendChild(r)}}}static hideLoading(){const e=this.getPopup();if(e){const t=e.querySelector(".alert90s-actions");t&&(t.style.display="");const o=e.querySelector(".alert90s-loader");o&&o.remove()}}static showValidationMessage(e){const t=this.getPopup();if(t){let o=t.querySelector(".alert90s-validation-message");if(!o){o=document.createElement("div"),o.className="alert90s-validation-message";const e=t.querySelector(".alert90s-actions");e&&e.parentNode?e.parentNode.insertBefore(o,e):t.querySelector(".alert90s-body").appendChild(o)}o.innerHTML=e,o.style.display="block"}}static resetValidationMessage(){const e=this.getPopup();if(e){const t=e.querySelector(".alert90s-validation-message");t&&(t.style.display="none")}}static fire(e={}){return this.show(e)}static show(t={}){return new Promise(o=>{"string"==typeof t&&(t={title:t}),this.currentOptions=t;const r={title:void 0!==t.title?t.title:"",text:t.message||t.text||"",html:t.html||"",icon:t.type||t.icon||"",iconHtml:t.iconHtml||"",showConfirmButton:!1!==t.showConfirmButton,showCancelButton:t.showCancelButton||!1,showDenyButton:t.showDenyButton||!1,showCloseButton:void 0===t.showCloseButton||t.showCloseButton,loaderType:t.loaderType||"hourglass",confirmButtonText:t.confirmText||t.confirmButtonText||"OK",cancelButtonText:t.cancelText||t.cancelButtonText||"Cancel",denyButtonText:t.denyText||t.denyButtonText||"No",confirmButtonColor:t.confirmButtonColor||"",cancelButtonColor:t.cancelButtonColor||"",denyButtonColor:t.denyButtonColor||"",background:t.background||"",color:t.color||"",titleColor:t.titleColor||"",iconColor:t.iconColor||"",confirmButtonAriaLabel:t.confirmButtonAriaLabel||"",cancelButtonAriaLabel:t.cancelButtonAriaLabel||"",denyButtonAriaLabel:t.denyButtonAriaLabel||"",focusConfirm:!1!==t.focusConfirm,footer:t.footer||"",imageUrl:t.imageUrl||"",imageWidth:t.imageWidth||null,imageHeight:t.imageHeight||null,imageAlt:t.imageAlt||"",input:t.input||null,inputAttributes:t.inputAttributes||{},showLoaderOnConfirm:t.showLoaderOnConfirm||!1,preConfirm:t.preConfirm||null,toast:t.toast||!1,draggable:t.draggable||!1,position:t.position||(t.toast?"top-end":"center"),allowOutsideClick:void 0===t.allowOutsideClick||t.allowOutsideClick,dir:t.dir||"auto",showClass:t.showClass||{popup:"alert90s-pop-in"},hideClass:t.hideClass||{popup:"alert90s-fade-out"},timer:t.timer||null,timerProgressBar:t.timerProgressBar||!1,didOpen:t.didOpen||null,willClose:t.willClose||null},n=document.createElement("div");n.className=`alert90s-overlay alert90s-pos-${r.position}`,r.toast&&n.classList.add("toast-overlay"),n.addEventListener("mousedown",e=>{if(e.target===n){("function"==typeof r.allowOutsideClick?r.allowOutsideClick():r.allowOutsideClick)&&h({isConfirmed:!1,isDenied:!1,isDismissed:!0,dismiss:"backdrop"})}});const i=document.createElement("div");i.className="alert90s-box",r.toast&&i.classList.add("alert90s-toast"),"rtl"===document.dir||"rtl"===r.dir||r.position.includes("start")?i.setAttribute("dir","auto"===r.dir?document.dir||"ltr":r.dir):i.setAttribute("dir",r.dir),r.showClass.popup&&"alert90s-pop-in"!==r.showClass.popup&&(i.style.animation="none",i.className=`alert90s-box ${r.showClass.popup}`),r.background&&(i.style.backgroundColor=r.background),r.color&&(i.style.color=r.color),r.draggable&&i.classList.add("is-draggable"),this.currentPopup=i;const s=document.createElement("div");s.className="alert90s-body";const a=document.createElement("div");a.className="alert90s-header",r.draggable&&a.classList.add("draggable");let l="";if(r.showCloseButton&&(l='\n <button class="alert90s-close-btn" id="alert90s-close" aria-label="Close">\n <span>&#10005;</span>\n </button>\n '),a.innerHTML=`\n <div class="alert90s-header-left">\n <div class="alert90s-header-dot"></div>\n <div class="alert90s-header-dot"></div>\n <div class="alert90s-header-dot"></div>\n </div>\n <div class="alert90s-header-right">\n <span class="alert90s-header-title">SYS.REQ</span>\n ${l}\n </div>\n `,r.draggable){let e,t,o,r,n=!1;a.addEventListener("mousedown",s=>{if(s.target.closest("#alert90s-close"))return;n=!0,e=s.clientX,t=s.clientY;const a=i.getBoundingClientRect();i.style.transform="none",i.style.animation="none",o=a.left,r=a.top,i.style.left=o+"px",i.style.top=r+"px",i.style.margin="0",document.body.style.userSelect="none"}),document.addEventListener("mousemove",s=>{n&&(i.style.left=o+(s.clientX-e)+"px",i.style.top=r+(s.clientY-t)+"px")}),document.addEventListener("mouseup",()=>{n&&(n=!1,document.body.style.userSelect="")})}let d=null;if(r.timer&&r.timerProgressBar&&(d=document.createElement("div"),d.className="alert90s-progress-bar",d.style.animationDuration=`${r.timer}ms`,i.appendChild(d)),r.imageUrl){const e=document.createElement("div");e.className="alert90s-image-container";const t=document.createElement("img");t.src=r.imageUrl,r.imageAlt&&(t.alt=r.imageAlt);let o="";r.imageWidth&&(o+=`width: ${r.imageWidth}px; max-width: 100%; `),r.imageHeight&&(o+=`height: ${r.imageHeight}px; `),o&&e.setAttribute("style",o),e.appendChild(t),s.appendChild(e)}if(r.icon){const e=document.createElement("div"),t="error"===r.icon?"danger":r.icon;e.className=`alert90s-icon ${t}`;let o="";if(r.iconHtml?o=`<div class="alert90s-icon-custom">${r.iconHtml}</div>`:"warning"===r.icon?o='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>':"danger"===r.icon||"error"===r.icon?o='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>':"info"===r.icon?o='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>':"success"===r.icon?o='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>':"question"===r.icon&&(o='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>'),e.innerHTML=o,r.iconColor&&(e.style.color=r.iconColor,e.style.borderColor=r.iconColor,!r.iconHtml)){const t=e.querySelector("svg");t&&(t.style.stroke=r.iconColor)}o&&s.appendChild(e)}const c=document.createElement("div");if(c.className="alert90s-content-wrapper",r.title){const e=document.createElement("h2");e.className="alert90s-title",e.innerHTML=r.title,r.titleColor&&(e.style.color=r.titleColor),c.appendChild(e)}if(r.html){const e=document.createElement("div");e.className="alert90s-html",e.innerHTML=r.html,r.color&&(e.style.color=r.color),c.appendChild(e)}else if(r.text){const e=document.createElement("p");e.className="alert90s-message",e.textContent=r.text,r.color&&(e.style.color=r.color),c.appendChild(e)}if((r.title||r.html||r.text)&&s.appendChild(c),r.toast&&r.showCloseButton){const e=document.createElement("button");e.className="alert90s-toast-close",e.innerHTML="<span>&#10005;</span>",e.onclick=()=>h({isConfirmed:!1,isDenied:!1,isDismissed:!0,dismiss:"close"}),s.appendChild(e)}let p=null;if(r.input){const e=document.createElement("div");if(e.className="alert90s-input-container","textarea"===r.input?p=document.createElement("textarea"):(p=document.createElement("input"),p.type=r.input),p.className="alert90s-input",r.inputAttributes)for(const[e,t]of Object.entries(r.inputAttributes))p.setAttribute(e,t);e.appendChild(p),s.appendChild(e)}const m=document.createElement("div");m.className="alert90s-actions";let u=null,f=null;const h=e=>{f&&clearTimeout(f),r.willClose&&r.willClose(),i.style.animation="none","alert90s-fade-out"===r.hideClass.popup?(i.style.animation="alert90s-fade-out 0.2s forwards",n.style.transition="opacity 0.2s",n.style.opacity="0"):i.className=`alert90s-box ${r.hideClass.popup}`,setTimeout(()=>{document.body.contains(n)&&document.body.removeChild(n),o(e)},200)},g=async()=>{let t=!0;if(p&&(t=p.value),r.preConfirm){e.resetValidationMessage(),r.showLoaderOnConfirm&&e.showLoading();try{const o=await Promise.resolve(r.preConfirm(t));if(!1===o)return void e.hideLoading();void 0!==o&&o!==t&&(t=o);const n=i.querySelector(".alert90s-validation-message");if(n&&"block"===n.style.display)return void e.hideLoading()}catch(t){return e.showValidationMessage(`Request failed: ${t}`),void e.hideLoading()}}h({isConfirmed:!0,isDenied:!1,isDismissed:!1,value:t})};if(r.showCancelButton){const e=document.createElement("button");e.className="alert90s-button cancel",e.innerHTML=r.cancelButtonText,r.cancelButtonAriaLabel&&e.setAttribute("aria-label",r.cancelButtonAriaLabel),r.cancelButtonColor&&(e.style.backgroundColor=r.cancelButtonColor),e.onclick=()=>h({isConfirmed:!1,isDenied:!1,isDismissed:!0,dismiss:"cancel"}),m.appendChild(e)}if(r.showDenyButton){const e=document.createElement("button");e.className="alert90s-button deny",e.innerHTML=r.denyButtonText,r.denyButtonAriaLabel&&e.setAttribute("aria-label",r.denyButtonAriaLabel),r.denyButtonColor&&(e.style.backgroundColor=r.denyButtonColor),e.onclick=()=>h({isConfirmed:!1,isDenied:!0,isDismissed:!1}),m.appendChild(e)}if(r.showConfirmButton){const e=document.createElement("button");e.className="alert90s-button confirm",e.innerHTML=r.confirmButtonText,r.confirmButtonAriaLabel&&e.setAttribute("aria-label",r.confirmButtonAriaLabel),r.confirmButtonColor&&(e.style.backgroundColor=r.confirmButtonColor),e.onclick=g,m.appendChild(e),u=e}if((r.showCancelButton||r.showDenyButton||r.showConfirmButton)&&s.appendChild(m),r.footer){const e=document.createElement("div");e.className="alert90s-footer",e.innerHTML=r.footer,s.appendChild(e)}if(i.appendChild(a),i.appendChild(s),n.appendChild(i),r.showCloseButton){const e=a.querySelector("#alert90s-close");e&&(e.onclick=()=>h({isConfirmed:!1,isDenied:!1,isDismissed:!0,dismiss:"close"}))}document.body.appendChild(n),r.focusConfirm&&u&&setTimeout(()=>{p?p.focus():u.focus()},50),r.didOpen&&setTimeout(()=>{r.didOpen()},0),r.timer&&(this.timerEnd=Date.now()+r.timer,f=setTimeout(()=>{h({isConfirmed:!1,isDenied:!1,isDismissed:!0,dismiss:"timer"})},r.timer))})}static initTooltips(){this._tooltipsInitialized||(this._tooltipsInitialized=!0,this._tooltipEl=document.createElement("div"),this._tooltipEl.className="alert90s-tooltip",document.body.appendChild(this._tooltipEl),document.addEventListener("mouseover",this._handleTooltipMouseOver.bind(this)),document.addEventListener("mouseout",this._handleTooltipMouseOut.bind(this)),document.addEventListener("focusin",this._handleTooltipMouseOver.bind(this)),document.addEventListener("focusout",this._handleTooltipMouseOut.bind(this)))}static _handleTooltipMouseOver(e){const t=e.target.closest("[data-alert90s-tooltip]");if(!t)return;const o=t.getAttribute("data-alert90s-tooltip");if(!o)return;const r=t.getAttribute("data-alert90s-position")||"top",n=t.getAttribute("data-alert90s-color")||"yellow";this._tooltipEl.innerHTML=o,this._tooltipEl.className=`alert90s-tooltip pos-${r} c-${n} show`;const i=t.getBoundingClientRect(),s=this._tooltipEl.getBoundingClientRect(),a=10;let l=0,d=0;switch(r){case"top":l=i.top-s.height-a,d=i.left+i.width/2-s.width/2;break;case"bottom":l=i.bottom+a,d=i.left+i.width/2-s.width/2;break;case"left":l=i.top+i.height/2-s.height/2,d=i.left-s.width-a;break;case"right":l=i.top+i.height/2-s.height/2,d=i.right+a}d<a&&(d=a),l<a&&(l=a),d+s.width>window.innerWidth-a&&(d=window.innerWidth-s.width-a),this._tooltipEl.style.top=`${l+window.scrollY}px`,this._tooltipEl.style.left=`${d+window.scrollX}px`}static _handleTooltipMouseOut(e){const t=e.target.closest("[data-alert90s-tooltip]");t&&setTimeout(()=>{this._tooltipEl.matches(":hover")||t.matches(":hover")||t.contains(document.activeElement)||this._tooltipEl.classList.remove("show")},10)}}return"undefined"!=typeof window&&(window.Alert90s=e,document.addEventListener("DOMContentLoaded",()=>{e.initTooltips()})),e});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Alert90s=t()}(this,function(){"use strict";!function(e,t){void 0===t&&(t={});var o=t.insertAt;if("undefined"!=typeof document){var r=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.type="text/css","top"===o&&r.firstChild?r.insertBefore(n,r.firstChild):r.appendChild(n),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(document.createTextNode(e))}}('.alert90s-overlay{animation:alert90s-fade-in .2s ease-out forwards;backdrop-filter:blur(4px);background-color:rgba(0,0,0,.6);box-sizing:border-box;display:flex;font-family:inherit;inset:0;padding:1rem;position:fixed;z-index:99999}.alert90s-overlay.alert90s-pos-center{align-items:center;justify-content:center}.alert90s-overlay.alert90s-pos-top{align-items:flex-start;justify-content:center}.alert90s-overlay.alert90s-pos-top-start{align-items:flex-start;justify-content:flex-start}.alert90s-overlay.alert90s-pos-top-end{align-items:flex-start;justify-content:flex-end}.alert90s-overlay.alert90s-pos-bottom{align-items:flex-end;justify-content:center}.alert90s-overlay.alert90s-pos-bottom-start{align-items:flex-end;justify-content:flex-start}.alert90s-overlay.alert90s-pos-bottom-end{align-items:flex-end;justify-content:flex-end}.alert90s-overlay.alert90s-pos-center-start{align-items:center;justify-content:flex-start}.alert90s-overlay.alert90s-pos-center-end{align-items:center;justify-content:flex-end}.alert90s-overlay *{box-sizing:border-box}.alert90s-box{align-items:center;animation:alert90s-pop-in .3s cubic-bezier(.175,.885,.32,1.275) forwards;background-color:#fff;border:4px solid #000;box-shadow:12px 12px 0 0 #000;display:flex;flex-direction:column;max-height:95vh;max-width:28rem;position:relative;text-align:center;width:100%}.alert90s-box[dir=rtl]{text-align:right}.alert90s-box.is-draggable{position:absolute}.alert90s-body{align-items:center;display:flex;flex-direction:column;overflow-y:auto;padding:3rem 2rem 2rem;scrollbar-width:none;width:100%}.alert90s-body::-webkit-scrollbar{display:none}.alert90s-header{align-items:center;background-color:#e2e8f0;border-bottom:4px solid #000;display:flex;height:2rem;justify-content:space-between;left:0;padding:0 .5rem;position:absolute;top:0;width:100%;z-index:10}.alert90s-header.draggable{cursor:grab}.alert90s-header.draggable:active{cursor:grabbing}.alert90s-header-left{display:flex;gap:.25rem}.alert90s-box[dir=rtl] .alert90s-header{flex-direction:row-reverse}.alert90s-header-dot{background-color:#fff;border:2px solid #000;height:.75rem;width:.75rem}.alert90s-header-right{align-items:center;display:flex;gap:.5rem;z-index:11}.alert90s-box[dir=rtl] .alert90s-header-right{flex-direction:row-reverse}.alert90s-header-title{font-size:10px;font-weight:700;letter-spacing:.1em;pointer-events:none;text-transform:uppercase}.alert90s-close-btn{align-items:center;background-color:#ef4444;border:2px solid #000;box-shadow:none;cursor:pointer;display:flex;height:1.25rem;justify-content:center;margin:0;padding:0;transition:transform .1s,background-color .1s;width:1.25rem}.alert90s-close-btn:hover{background-color:#f87171;transform:scale(1.1)}.alert90s-close-btn span{color:#000;font-size:14px;font-weight:700;line-height:1}.alert90s-image-container{align-items:center;background:#fff;border:4px solid #000;box-shadow:4px 4px 0 0 #000;display:flex;justify-content:center;margin-bottom:1rem;overflow:hidden;width:100%}.alert90s-image-container img{display:block;height:auto;max-width:100%}.alert90s-icon{align-items:center;border:4px solid #000;border-radius:9999px;box-shadow:4px 4px 0 0 #000;display:flex;flex-shrink:0;height:4rem;justify-content:center;margin-bottom:1rem;width:4rem}.alert90s-icon img,.alert90s-icon svg{height:2rem;width:2rem}.alert90s-icon-custom{font-size:2.25rem;font-weight:700;line-height:1}.alert90s-icon.warning{background-color:#facc15}.alert90s-icon.danger,.alert90s-icon.error{background-color:#ef4444;color:#fff}.alert90s-icon.info,.alert90s-icon.question{background-color:#60a5fa}.alert90s-icon.success{background-color:#4ade80}.alert90s-title{color:#1a1a1a;font-size:1.5rem;font-weight:900;letter-spacing:.1em;line-height:1.2;margin:0 0 .5rem;text-transform:uppercase}.alert90s-message{color:#475569;font-weight:700}.alert90s-html,.alert90s-message{font-size:.875rem;margin:0 0 1.5rem;max-width:100%}.alert90s-html{color:#1a1a1a;line-height:1.5}.alert90s-box[dir=rtl] .alert90s-html{text-align:right}.alert90s-html a{color:#2563eb;font-weight:700;text-decoration:underline;text-decoration-thickness:2px}.alert90s-html a:hover{background-color:#bfdbfe}.alert90s-html b,.alert90s-html strong{font-weight:900}.alert90s-input-container{margin-bottom:1.5rem;width:100%}.alert90s-input{background-color:#f8fafc;border:4px solid #000;box-shadow:inset 4px 4px 0 0 rgba(0,0,0,.05);font-family:inherit;font-size:1rem;font-weight:700;outline:none;padding:.75rem;transition:background-color .2s;width:100%}.alert90s-input:focus{background-color:#fff;border-color:#2563eb}textarea.alert90s-input{min-height:100px;resize:vertical}select.alert90s-select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,#000 0),linear-gradient(135deg,#000 50%,transparent 0);background-position:calc(100% - 20px) calc(1em + 2px),calc(100% - 15px) calc(1em + 2px);background-repeat:no-repeat;background-size:5px 5px,5px 5px;cursor:pointer}.alert90s-radio-group{align-items:flex-start;display:flex;flex-direction:column;gap:.5rem;width:100%}.alert90s-radio-label{align-items:center;cursor:pointer;display:flex;font-size:1rem;font-weight:700;gap:.75rem}.alert90s-radio-label input[type=radio]{appearance:none;background-color:#f8fafc;border:4px solid #000;border-radius:50%;cursor:pointer;height:1.25rem;margin:0;position:relative;width:1.25rem}.alert90s-radio-label input[type=radio]:checked{background-color:#000;box-shadow:inset 0 0 0 4px #fff}.alert90s-checkbox-label{align-items:center;cursor:pointer;display:flex;font-size:1rem;font-weight:700;gap:.75rem}.alert90s-checkbox-label input[type=checkbox]{appearance:none;background-color:#f8fafc;border:4px solid #000;cursor:pointer;height:1.25rem;margin:0;position:relative;width:1.25rem}.alert90s-checkbox-label input[type=checkbox]:checked{background-color:#000}.alert90s-checkbox-label input[type=checkbox]:checked:after{color:#fff;content:"✔";font-size:.8rem;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.alert90s-toggle-label{align-items:center;cursor:pointer;display:flex;font-size:1rem;font-weight:700;gap:.75rem}.alert90s-toggle-label input[type=checkbox]{display:none}.alert90s-toggle-slider{background-color:#f87171;border:4px solid #000;box-shadow:inset 3px 3px 0 0 rgba(0,0,0,.1);height:1.5rem;position:relative;transition:background-color .2s;width:3rem}.alert90s-toggle-slider:before{background-color:#fff;border-right:4px solid #000;content:"";height:100%;left:0;position:absolute;top:0;transition:transform .2s;width:1rem}.alert90s-toggle-label input[type=checkbox]:checked+.alert90s-toggle-slider{background-color:#4ade80}.alert90s-toggle-label input[type=checkbox]:checked+.alert90s-toggle-slider:before{border-left:4px solid #000;transform:translateX(1.5rem)}.alert90s-validation-message{background-color:#fef2f2;border:4px solid #000;border-left:8px solid #ef4444;color:#ef4444;display:none;font-size:.875rem;font-weight:700;margin-bottom:1.5rem;padding:.75rem;text-align:left;width:100%}.alert90s-box[dir=rtl] .alert90s-validation-message{border-left-color:#000;border-left-width:4px;border-right-color:#ef4444;border-right-width:8px;text-align:right}.alert90s-actions{display:flex;flex-direction:column;gap:1rem;justify-content:center;width:100%}@media (min-width:640px){.alert90s-actions{flex-direction:row}}.alert90s-button{align-items:center;background-color:#fff;border:4px solid #000;box-shadow:4px 4px 0 0 #000;color:#000;cursor:pointer;display:flex;font-family:inherit;font-size:.875rem;font-weight:900;gap:.5rem;justify-content:center;letter-spacing:.1em;margin:0;padding:.75rem 1rem;text-transform:uppercase;transition:background-color .1s;width:100%}@media (min-width:640px){.alert90s-button{flex:1;min-width:100px;width:auto}}.alert90s-button:active{box-shadow:0 0 0 0 #000;transform:translate(4px,4px)}.alert90s-button:focus{outline:2px dashed #000;outline-offset:4px}.alert90s-button.cancel{background-color:#f87171}.alert90s-button.cancel:hover{background-color:#fca5a5}.alert90s-button.deny{background-color:#fb923c}.alert90s-button.deny:hover{background-color:#fdba74}.alert90s-button.confirm{background-color:#4ade80}.alert90s-button.confirm:hover{background-color:#86efac}.alert90s-footer{border-top:4px solid #000;color:#475569;font-size:.75rem;font-weight:700;margin-top:1.5rem;padding-top:1rem;width:100%}.alert90s-footer a{color:#2563eb;text-decoration:underline;text-decoration-thickness:2px}.alert90s-footer a:hover{background-color:#bfdbfe}.alert90s-progress-bar{animation:alert90s-progress linear forwards;background-color:#000;bottom:0;height:6px;left:0;position:absolute;width:100%}.alert90s-loader{display:flex;padding:1rem 0}.alert90s-loader,.alert90s-spinner{align-items:center;justify-content:center}.alert90s-spinner{display:inline-flex}.alert90s-spinner.hourglass{animation:alert90s-hourglass 2s ease-in-out infinite;font-size:2.5rem;line-height:1}.alert90s-spinner.ascii{font-family:monospace;font-size:2rem;font-weight:700}.alert90s-spinner.ascii:after{animation:alert90s-ascii .5s steps(4) infinite;content:"|"}.alert90s-spinner.blinking{font-family:monospace;font-size:1.5rem;font-weight:700;letter-spacing:.1em}.alert90s-spinner.blinking .cursor{animation:alert90s-blink 1s step-end infinite}.alert90s-spinner.progress{background-color:#cbd5e1;border:2px solid #000;box-shadow:inset 2px 2px 0 0 #64748b,inset -2px -2px 0 0 #f8fafc;height:24px;overflow:hidden;padding:2px;position:relative;width:200px}.alert90s-spinner.progress:before{animation:alert90s-marquee 1.5s linear infinite;background-color:#1d4ed8;background-image:repeating-linear-gradient(90deg,#1d4ed8,#1d4ed8 10px,transparent 0,transparent 12px);content:"";height:calc(100% - 4px);left:0;position:absolute;top:2px;width:40%}@keyframes alert90s-hourglass{0%{transform:rotate(0)}25%{transform:rotate(180deg)}50%{transform:rotate(180deg)}75%{transform:rotate(1turn)}to{transform:rotate(1turn)}}@keyframes alert90s-ascii{0%{content:"|"}25%{content:"/"}50%{content:"-"}75%{content:"\\\\"}to{content:"|"}}@keyframes alert90s-blink{50%{opacity:0}}@keyframes alert90s-marquee{0%{transform:translateX(-100%)}to{transform:translateX(250px)}}@keyframes alert90s-progress{0%{width:100%}to{width:0}}@keyframes alert90s-fade-in{0%{opacity:0}to{opacity:1}}@keyframes alert90s-pop-in{0%{opacity:0;transform:scale(.95) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes alert90s-fade-out{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.95) translateY(10px)}}@keyframes alert90s-toast-slide-in{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}.alert90s-toast-container{display:flex;gap:10px;padding:10px;pointer-events:none;position:fixed;z-index:10000}.alert90s-toast-top-start{flex-direction:column;left:0;top:0}.alert90s-toast-top{flex-direction:column;left:50%;top:0;transform:translateX(-50%)}.alert90s-toast-top-end{flex-direction:column;right:0;top:0}.alert90s-toast-center-start{flex-direction:column;left:0;top:50%;transform:translateY(-50%)}.alert90s-toast-center{flex-direction:column;left:50%;top:50%;transform:translate(-50%,-50%)}.alert90s-toast-center-end{flex-direction:column;right:0;top:50%;transform:translateY(-50%)}.alert90s-toast-bottom-start{bottom:0;flex-direction:column-reverse;left:0}.alert90s-toast-bottom{bottom:0;flex-direction:column-reverse;left:50%;transform:translateX(-50%)}.alert90s-toast-bottom-end{bottom:0;flex-direction:column-reverse;right:0}.alert90s-box.alert90s-toast{align-items:stretch;bottom:auto!important;box-shadow:6px 6px 0 0 #000;flex-direction:row;left:auto!important;margin:0;max-width:100%;min-width:250px;padding:0;pointer-events:auto;position:relative!important;right:auto!important;top:auto!important;transform:none!important;width:auto}.alert90s-toast .alert90s-header{display:none}.alert90s-toast .alert90s-body{align-items:center;flex-direction:row;gap:1rem;padding:1rem 1.5rem}.alert90s-toast .alert90s-icon{height:2.5rem;margin-bottom:0;width:2.5rem}.alert90s-toast .alert90s-icon img,.alert90s-toast .alert90s-icon svg{height:1.25rem;width:1.25rem}.alert90s-content-wrapper{align-items:center;display:flex;flex-direction:column;width:100%}.alert90s-toast .alert90s-content-wrapper{align-items:flex-start;text-align:left}.alert90s-box.alert90s-toast[dir=rtl] .alert90s-content-wrapper{align-items:flex-end;text-align:right}.alert90s-toast .alert90s-title{font-size:1rem;margin-bottom:.25rem}.alert90s-toast .alert90s-html,.alert90s-toast .alert90s-message{font-size:.875rem;margin-bottom:0}.alert90s-toast-close{align-items:center;background-color:#ef4444;border:2px solid #000;box-shadow:none;cursor:pointer;display:flex;height:1.5rem;justify-content:center;margin:0;margin-inline-start:auto;padding:0;transition:transform .1s,background-color .1s;width:1.5rem}.alert90s-toast-close span{color:#000;display:block;font-size:10px;font-weight:700;line-height:1}.alert90s-toast-close:hover{background-color:#f87171;transform:scale(1.1)}.btn90s{align-items:center;background-color:#fff;border:4px solid #000;box-shadow:4px 4px 0 0 #000;color:#000;cursor:pointer;display:inline-flex;font-family:inherit;font-size:1rem;font-weight:900;justify-content:center;letter-spacing:.05em;margin:.25rem;padding:.75rem 1.5rem;text-decoration:none;text-transform:uppercase;transition:transform .1s,box-shadow .1s,background-color .1s}.btn90s:active{box-shadow:0 0 0 0 #000;transform:translate(4px,4px)}.btn90s:focus-visible{outline:2px dashed #000;outline-offset:4px}.btn90s.primary{background-color:#00f0ff}.btn90s.primary:hover{background-color:#66f6ff}.btn90s.success{background-color:#4ade80}.btn90s.success:hover{background-color:#86efac}.btn90s.warning{background-color:#ffc900}.btn90s.warning:hover{background-color:#ffe066}.btn90s.danger{background-color:#ff90e8}.btn90s.danger:hover{background-color:#ffbaf0}.btn90s.dark{background-color:#000;border-color:#000;color:#fff}.btn90s.dark:hover{background-color:#333}.btn90s.sm{border-width:3px;box-shadow:3px 3px 0 0 #000;font-size:.875rem;padding:.5rem 1rem}.btn90s.sm:active{transform:translate(3px,3px)}.btn90s.lg{border-width:5px;box-shadow:6px 6px 0 0 #000;font-size:1.25rem;padding:1rem 2rem}.btn90s.lg:active{transform:translate(6px,6px)}.alert90s-tooltip{animation:tooltip-pop .15s cubic-bezier(.175,.885,.32,1.275) forwards;background-color:#fff;border:3px solid #000;box-shadow:4px 4px 0 0 #000;color:#000;display:none;font-family:inherit;font-size:.875rem;font-weight:700;max-width:300px;padding:.5rem 1rem;pointer-events:none;position:absolute;white-space:pre-wrap;z-index:100000}.alert90s-tooltip.show{display:block}.alert90s-tooltip.c-yellow{background-color:#fef08a}.alert90s-tooltip.c-cyan{background-color:#00f0ff}.alert90s-tooltip.c-pink{background-color:#ff90e8}.alert90s-tooltip.c-base{background-color:#fff}.alert90s-tooltip.c-dark{background-color:#000;color:#fff}.alert90s-tooltip:after{border-style:solid;content:"";height:0;position:absolute;width:0}.alert90s-tooltip.pos-top:after{border-color:#000 transparent transparent;border-width:8px 8px 0;bottom:-8px;left:50%;margin-left:-8px}.alert90s-tooltip.pos-bottom:after{border-color:transparent transparent #000;border-width:0 8px 8px;left:50%;margin-left:-8px;top:-8px}.alert90s-tooltip.pos-left:after{border-color:transparent transparent transparent #000;border-width:8px 0 8px 8px;margin-top:-8px;right:-8px;top:50%}.alert90s-tooltip.pos-right:after{border-color:transparent #000 transparent transparent;border-width:8px 8px 8px 0;left:-8px;margin-top:-8px;top:50%}@keyframes tooltip-pop{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}');class e{static getOptions(){return this.currentOptions||{}}static getPopup(){return this.currentPopup||null}static getTimerLeft(){if(!this.timerEnd)return;const e=this.timerEnd-Date.now();return e>0?e:0}static isLoading(){const e=this.getPopup();if(!e)return!1;const t=e.querySelector(".alert90s-actions"),o=e.querySelector(".alert90s-loader");return t&&"none"===t.style.display||!!o}static showLoading(){const t=this.getPopup();if(t){const o=t.querySelector(".alert90s-actions");o&&(o.style.display="none");let r=t.querySelector(".alert90s-loader");if(!r){r=document.createElement("div"),r.className="alert90s-loader";const n=e.currentOptions&&e.currentOptions.loaderType||"hourglass";r.innerHTML="ascii"===n?'<div class="alert90s-spinner ascii"></div>':"blinking"===n?'<div class="alert90s-spinner blinking">LOADING<span class="cursor">_</span></div>':"progress"===n?'<div class="alert90s-spinner progress"></div>':'<div class="alert90s-spinner hourglass">⏳</div>',o&&o.parentNode?o.parentNode.insertBefore(r,o):t.querySelector(".alert90s-body").appendChild(r)}}}static hideLoading(){const e=this.getPopup();if(e){const t=e.querySelector(".alert90s-actions");t&&(t.style.display="");const o=e.querySelector(".alert90s-loader");o&&o.remove()}}static showValidationMessage(e){const t=this.getPopup();if(t){let o=t.querySelector(".alert90s-validation-message");if(!o){o=document.createElement("div"),o.className="alert90s-validation-message";const e=t.querySelector(".alert90s-actions");e&&e.parentNode?e.parentNode.insertBefore(o,e):t.querySelector(".alert90s-body").appendChild(o)}o.innerHTML=e,o.style.display="block"}}static resetValidationMessage(){const e=this.getPopup();if(e){const t=e.querySelector(".alert90s-validation-message");t&&(t.style.display="none")}}static getToastContainer(e){const t=`alert90s-toast-container alert90s-toast-${e}`;let o=document.querySelector(`.${t.replace(/ /g,".")}`);return o||(o=document.createElement("div"),o.className=t,document.body.appendChild(o)),o}static fire(e={}){return this.show(e)}static show(t={}){return new Promise(o=>{"string"==typeof t&&(t={title:t}),this.currentOptions=t;const r={title:void 0!==t.title?t.title:"",text:t.message||t.text||"",html:t.html||"",icon:t.type||t.icon||"",iconHtml:t.iconHtml||"",showConfirmButton:!1!==t.showConfirmButton,showCancelButton:t.showCancelButton||!1,showDenyButton:t.showDenyButton||!1,showCloseButton:void 0===t.showCloseButton||t.showCloseButton,loaderType:t.loaderType||"hourglass",confirmButtonText:t.confirmText||t.confirmButtonText||"OK",cancelButtonText:t.cancelText||t.cancelButtonText||"Cancel",denyButtonText:t.denyText||t.denyButtonText||"No",confirmButtonColor:t.confirmButtonColor||"",cancelButtonColor:t.cancelButtonColor||"",denyButtonColor:t.denyButtonColor||"",background:t.background||"",color:t.color||"",titleColor:t.titleColor||"",iconColor:t.iconColor||"",confirmButtonAriaLabel:t.confirmButtonAriaLabel||"",cancelButtonAriaLabel:t.cancelButtonAriaLabel||"",denyButtonAriaLabel:t.denyButtonAriaLabel||"",focusConfirm:!1!==t.focusConfirm,footer:t.footer||"",imageUrl:t.imageUrl||"",imageWidth:t.imageWidth||null,imageHeight:t.imageHeight||null,imageAlt:t.imageAlt||"",input:t.input||null,inputPlaceholder:t.inputPlaceholder||"",inputValue:t.inputValue||"",inputOptions:t.inputOptions||{},inputAttributes:t.inputAttributes||{},showLoaderOnConfirm:t.showLoaderOnConfirm||!1,preConfirm:t.preConfirm||null,toast:t.toast||!1,draggable:t.draggable||!1,position:t.position||(t.toast?"top-end":"center"),allowOutsideClick:void 0===t.allowOutsideClick||t.allowOutsideClick,dir:t.dir||"auto",showClass:t.showClass||{popup:"alert90s-pop-in"},hideClass:t.hideClass||{popup:"alert90s-fade-out"},timer:t.timer||null,timerProgressBar:t.timerProgressBar||!1,didOpen:t.didOpen||null,willClose:t.willClose||null};let n=null;r.toast||(n=document.createElement("div"),n.className=`alert90s-overlay alert90s-pos-${r.position}`,n.addEventListener("mousedown",e=>{if(e.target===n){("function"==typeof r.allowOutsideClick?r.allowOutsideClick():r.allowOutsideClick)&&h({isConfirmed:!1,isDenied:!1,isDismissed:!0,dismiss:"backdrop"})}}));const a=document.createElement("div");a.className="alert90s-box",r.toast&&a.classList.add("alert90s-toast"),"rtl"===document.dir||"rtl"===r.dir||r.position.includes("start")?a.setAttribute("dir","auto"===r.dir?document.dir||"ltr":r.dir):a.setAttribute("dir",r.dir),r.showClass.popup&&"alert90s-pop-in"!==r.showClass.popup&&(a.style.animation="none",a.className=`alert90s-box ${r.showClass.popup}`),r.background&&(a.style.backgroundColor=r.background),r.color&&(a.style.color=r.color),r.draggable&&a.classList.add("is-draggable"),r.toast||(this.currentPopup=a);const i=document.createElement("div");i.className="alert90s-body";const s=document.createElement("div");s.className="alert90s-header",r.draggable&&s.classList.add("draggable");let l="";if(r.showCloseButton&&(l='\n <button class="alert90s-close-btn" id="alert90s-close" aria-label="Close">\n <span>&#10005;</span>\n </button>\n '),s.innerHTML=`\n <div class="alert90s-header-left">\n <div class="alert90s-header-dot"></div>\n <div class="alert90s-header-dot"></div>\n <div class="alert90s-header-dot"></div>\n </div>\n <div class="alert90s-header-right">\n <span class="alert90s-header-title">SYS.REQ</span>\n ${l}\n </div>\n `,r.draggable){let e,t,o,r,n=!1;s.addEventListener("mousedown",i=>{if(i.target.closest("#alert90s-close"))return;n=!0,e=i.clientX,t=i.clientY;const s=a.getBoundingClientRect();a.style.transform="none",a.style.animation="none",o=s.left,r=s.top,a.style.left=o+"px",a.style.top=r+"px",a.style.margin="0",document.body.style.userSelect="none"}),document.addEventListener("mousemove",i=>{n&&(a.style.left=o+(i.clientX-e)+"px",a.style.top=r+(i.clientY-t)+"px")}),document.addEventListener("mouseup",()=>{n&&(n=!1,document.body.style.userSelect="")})}let c=null;if(r.timer&&r.timerProgressBar&&(c=document.createElement("div"),c.className="alert90s-progress-bar",c.style.animationDuration=`${r.timer}ms`,a.appendChild(c)),r.imageUrl){const e=document.createElement("div");e.className="alert90s-image-container";const t=document.createElement("img");t.src=r.imageUrl,r.imageAlt&&(t.alt=r.imageAlt);let o="";r.imageWidth&&(o+=`width: ${r.imageWidth}px; max-width: 100%; `),r.imageHeight&&(o+=`height: ${r.imageHeight}px; `),o&&e.setAttribute("style",o),e.appendChild(t),i.appendChild(e)}if(r.icon){const e=document.createElement("div"),t="error"===r.icon?"danger":r.icon;e.className=`alert90s-icon ${t}`;let o="";if(r.iconHtml?o=`<div class="alert90s-icon-custom">${r.iconHtml}</div>`:"warning"===r.icon?o='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>':"danger"===r.icon||"error"===r.icon?o='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>':"info"===r.icon?o='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>':"success"===r.icon?o='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>':"question"===r.icon&&(o='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>'),e.innerHTML=o,r.iconColor&&(e.style.color=r.iconColor,e.style.borderColor=r.iconColor,!r.iconHtml)){const t=e.querySelector("svg");t&&(t.style.stroke=r.iconColor)}o&&i.appendChild(e)}const d=document.createElement("div");if(d.className="alert90s-content-wrapper",r.title){const e=document.createElement("h2");e.className="alert90s-title",e.innerHTML=r.title,r.titleColor&&(e.style.color=r.titleColor),d.appendChild(e)}if(r.html){const e=document.createElement("div");e.className="alert90s-html",e.innerHTML=r.html,r.color&&(e.style.color=r.color),d.appendChild(e)}else if(r.text){const e=document.createElement("p");e.className="alert90s-message",e.textContent=r.text,r.color&&(e.style.color=r.color),d.appendChild(e)}if((r.title||r.html||r.text)&&i.appendChild(d),r.toast&&r.showCloseButton){const e=document.createElement("button");e.className="alert90s-toast-close",e.innerHTML="<span>&#10005;</span>",e.onclick=()=>h({isConfirmed:!1,isDenied:!1,isDismissed:!0,dismiss:"close"}),i.appendChild(e)}let p=null;if(r.input){const e=document.createElement("div");if(e.className="alert90s-input-container","select"===r.input){if(p=document.createElement("select"),p.className="alert90s-input alert90s-select",r.inputPlaceholder){const e=document.createElement("option");e.value="",e.textContent=r.inputPlaceholder,e.disabled=!0,e.selected=!0,p.appendChild(e)}for(const[e,t]of Object.entries(r.inputOptions)){const o=document.createElement("option");o.value=e,o.textContent=t,e===r.inputValue&&(o.selected=!0),p.appendChild(o)}e.appendChild(p)}else if("radio"===r.input){const t=document.createElement("div");t.className="alert90s-radio-group";for(const[e,o]of Object.entries(r.inputOptions)){const n=document.createElement("label");n.className="alert90s-radio-label";const a=document.createElement("input");a.type="radio",a.name="alert90s-radio",a.value=e,e===r.inputValue&&(a.checked=!0);const i=document.createElement("span");i.textContent=o,n.appendChild(a),n.appendChild(i),t.appendChild(n)}p=t,e.appendChild(t)}else if("checkbox"===r.input||"toggle"===r.input){const t=document.createElement("label");if(t.className="toggle"===r.input?"alert90s-toggle-label":"alert90s-checkbox-label",p=document.createElement("input"),p.type="checkbox",p.checked=!!r.inputValue,"toggle"===r.input){const e=document.createElement("div");if(e.className="alert90s-toggle-slider",t.appendChild(p),t.appendChild(e),r.inputPlaceholder){const e=document.createElement("span");e.textContent=r.inputPlaceholder,t.appendChild(e)}}else{const e=document.createElement("span");e.textContent=r.inputPlaceholder||"Check me",t.appendChild(p),t.appendChild(e)}e.appendChild(t)}else"textarea"===r.input?(p=document.createElement("textarea"),p.className="alert90s-input",r.inputPlaceholder&&(p.placeholder=r.inputPlaceholder),r.inputValue&&(p.value=r.inputValue),e.appendChild(p)):(p=document.createElement("input"),p.type=r.input,p.className="alert90s-input",r.inputPlaceholder&&(p.placeholder=r.inputPlaceholder),r.inputValue&&(p.value=r.inputValue),e.appendChild(p));if(r.inputAttributes&&p&&!["radio"].includes(r.input))for(const[e,t]of Object.entries(r.inputAttributes))p.setAttribute(e,t);i.appendChild(e)}const m=document.createElement("div");m.className="alert90s-actions";let u=null,f=null;const h=e=>{f&&clearTimeout(f),r.willClose&&r.willClose(),a.style.animation="none","alert90s-fade-out"===r.hideClass.popup?(a.style.animation="alert90s-fade-out 0.2s forwards",n&&(n.style.transition="opacity 0.2s",n.style.opacity="0")):a.className=`alert90s-box ${r.hideClass.popup}`,setTimeout(()=>{r.toast?a.parentNode&&a.parentNode.removeChild(a):n&&document.body.contains(n)&&document.body.removeChild(n),o(e)},200)},g=async()=>{let t=!0;if("radio"===r.input){const e=p.querySelector('input[type="radio"]:checked');t=e?e.value:null}else"checkbox"===r.input||"toggle"===r.input?t=p.checked:p&&(t=p.value);if(r.preConfirm){e.resetValidationMessage(),r.showLoaderOnConfirm&&e.showLoading();try{const o=await Promise.resolve(r.preConfirm(t));if(!1===o)return void e.hideLoading();void 0!==o&&o!==t&&(t=o);const n=a.querySelector(".alert90s-validation-message");if(n&&"block"===n.style.display)return void e.hideLoading()}catch(t){return e.showValidationMessage(`Request failed: ${t}`),void e.hideLoading()}}h({isConfirmed:!0,isDenied:!1,isDismissed:!1,value:t})};if(r.showCancelButton){const e=document.createElement("button");e.className="alert90s-button cancel",e.innerHTML=r.cancelButtonText,r.cancelButtonAriaLabel&&e.setAttribute("aria-label",r.cancelButtonAriaLabel),r.cancelButtonColor&&(e.style.backgroundColor=r.cancelButtonColor),e.onclick=()=>h({isConfirmed:!1,isDenied:!1,isDismissed:!0,dismiss:"cancel"}),m.appendChild(e)}if(r.showDenyButton){const e=document.createElement("button");e.className="alert90s-button deny",e.innerHTML=r.denyButtonText,r.denyButtonAriaLabel&&e.setAttribute("aria-label",r.denyButtonAriaLabel),r.denyButtonColor&&(e.style.backgroundColor=r.denyButtonColor),e.onclick=()=>h({isConfirmed:!1,isDenied:!0,isDismissed:!1}),m.appendChild(e)}if(r.showConfirmButton){const e=document.createElement("button");e.className="alert90s-button confirm",e.innerHTML=r.confirmButtonText,r.confirmButtonAriaLabel&&e.setAttribute("aria-label",r.confirmButtonAriaLabel),r.confirmButtonColor&&(e.style.backgroundColor=r.confirmButtonColor),e.onclick=g,m.appendChild(e),u=e}if((r.showCancelButton||r.showDenyButton||r.showConfirmButton)&&i.appendChild(m),r.footer){const e=document.createElement("div");e.className="alert90s-footer",e.innerHTML=r.footer,i.appendChild(e)}if(a.appendChild(s),a.appendChild(i),r.toast){const t=e.getToastContainer(r.position);a.style.animation="alert90s-toast-slide-in 0.3s ease-out",t.appendChild(a)}else n.appendChild(a);if(r.showCloseButton&&!r.toast){const e=s.querySelector("#alert90s-close");e&&(e.onclick=()=>h({isConfirmed:!1,isDenied:!1,isDismissed:!0,dismiss:"close"}))}r.toast||document.body.appendChild(n),r.focusConfirm&&u&&setTimeout(()=>{p?p.focus():u.focus()},50),r.didOpen&&setTimeout(()=>{r.didOpen()},0),r.timer&&(this.timerEnd=Date.now()+r.timer,f=setTimeout(()=>{h({isConfirmed:!1,isDenied:!1,isDismissed:!0,dismiss:"timer"})},r.timer))})}static initTooltips(){this._tooltipsInitialized||(this._tooltipsInitialized=!0,this._tooltipEl=document.createElement("div"),this._tooltipEl.className="alert90s-tooltip",document.body.appendChild(this._tooltipEl),document.addEventListener("mouseover",this._handleTooltipMouseOver.bind(this)),document.addEventListener("mouseout",this._handleTooltipMouseOut.bind(this)),document.addEventListener("focusin",this._handleTooltipMouseOver.bind(this)),document.addEventListener("focusout",this._handleTooltipMouseOut.bind(this)))}static _handleTooltipMouseOver(e){const t=e.target.closest("[data-alert90s-tooltip]");if(!t)return;const o=t.getAttribute("data-alert90s-tooltip");if(!o)return;const r=t.getAttribute("data-alert90s-position")||"top",n=t.getAttribute("data-alert90s-color")||"yellow";this._tooltipEl.innerHTML=o,this._tooltipEl.className=`alert90s-tooltip pos-${r} c-${n} show`;const a=t.getBoundingClientRect(),i=this._tooltipEl.getBoundingClientRect(),s=10;let l=0,c=0;switch(r){case"top":l=a.top-i.height-s,c=a.left+a.width/2-i.width/2;break;case"bottom":l=a.bottom+s,c=a.left+a.width/2-i.width/2;break;case"left":l=a.top+a.height/2-i.height/2,c=a.left-i.width-s;break;case"right":l=a.top+a.height/2-i.height/2,c=a.right+s}c<s&&(c=s),l<s&&(l=s),c+i.width>window.innerWidth-s&&(c=window.innerWidth-i.width-s),this._tooltipEl.style.top=`${l+window.scrollY}px`,this._tooltipEl.style.left=`${c+window.scrollX}px`}static _handleTooltipMouseOut(e){const t=e.target.closest("[data-alert90s-tooltip]");t&&setTimeout(()=>{this._tooltipEl.matches(":hover")||t.matches(":hover")||t.contains(document.activeElement)||this._tooltipEl.classList.remove("show")},10)}}return"undefined"!=typeof window&&(window.Alert90s=e,document.addEventListener("DOMContentLoaded",()=>{e.initTooltips()})),e});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alert90s",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Neo Brutalism 90s style JS alert library",
5
5
  "main": "dist/alert90s.min.js",
6
6
  "files": [
package/src/index.js CHANGED
@@ -88,6 +88,17 @@ class Alert90s {
88
88
  }
89
89
  }
90
90
 
91
+ static getToastContainer(position) {
92
+ const containerClass = `alert90s-toast-container alert90s-toast-${position}`;
93
+ let container = document.querySelector(`.${containerClass.replace(/ /g, '.')}`);
94
+ if (!container) {
95
+ container = document.createElement('div');
96
+ container.className = containerClass;
97
+ document.body.appendChild(container);
98
+ }
99
+ return container;
100
+ }
101
+
91
102
  static fire(options = {}) {
92
103
  return this.show(options);
93
104
  }
@@ -141,7 +152,10 @@ class Alert90s {
141
152
  imageAlt: options.imageAlt || '',
142
153
 
143
154
  // Input
144
- input: options.input || null, // 'text', 'email', 'password', 'number', 'tel', 'url', 'textarea'
155
+ input: options.input || null,
156
+ inputPlaceholder: options.inputPlaceholder || '',
157
+ inputValue: options.inputValue || '',
158
+ inputOptions: options.inputOptions || {},
145
159
  inputAttributes: options.inputAttributes || {},
146
160
  showLoaderOnConfirm: options.showLoaderOnConfirm || false,
147
161
  preConfirm: options.preConfirm || null,
@@ -168,22 +182,22 @@ class Alert90s {
168
182
  willClose: options.willClose || null,
169
183
  };
170
184
 
171
- // Create overlay
172
- const overlay = document.createElement('div');
173
- overlay.className = `alert90s-overlay alert90s-pos-${config.position}`;
174
- if (config.toast) {
175
- overlay.classList.add('toast-overlay');
176
- }
177
-
178
- // Handle allowOutsideClick
179
- overlay.addEventListener('mousedown', (e) => {
180
- if (e.target === overlay) {
181
- const allow = typeof config.allowOutsideClick === 'function' ? config.allowOutsideClick() : config.allowOutsideClick;
182
- if (allow) {
183
- finish({ isConfirmed: false, isDenied: false, isDismissed: true, dismiss: 'backdrop' });
185
+ // Create overlay (only for non-toasts)
186
+ let overlay = null;
187
+ if (!config.toast) {
188
+ overlay = document.createElement('div');
189
+ overlay.className = `alert90s-overlay alert90s-pos-${config.position}`;
190
+
191
+ // Handle allowOutsideClick
192
+ overlay.addEventListener('mousedown', (e) => {
193
+ if (e.target === overlay) {
194
+ const allow = typeof config.allowOutsideClick === 'function' ? config.allowOutsideClick() : config.allowOutsideClick;
195
+ if (allow) {
196
+ finish({ isConfirmed: false, isDenied: false, isDismissed: true, dismiss: 'backdrop' });
197
+ }
184
198
  }
185
- }
186
- });
199
+ });
200
+ }
187
201
 
188
202
  // Create Box
189
203
  const box = document.createElement('div');
@@ -213,7 +227,10 @@ class Alert90s {
213
227
  box.classList.add('is-draggable');
214
228
  }
215
229
 
216
- this.currentPopup = box;
230
+ if (!config.toast) {
231
+ // Only assign currentPopup for Modal Alerts (singleton pattern)
232
+ this.currentPopup = box;
233
+ }
217
234
 
218
235
  const bodyContainer = document.createElement('div');
219
236
  bodyContainer.className = 'alert90s-body';
@@ -384,27 +401,95 @@ class Alert90s {
384
401
 
385
402
  // Input form
386
403
  let inputEl = null;
404
+
387
405
  if (config.input) {
388
406
  const inputContainer = document.createElement('div');
389
407
  inputContainer.className = 'alert90s-input-container';
390
-
391
- if (config.input === 'textarea') {
408
+
409
+ if (config.input === 'select') {
410
+ inputEl = document.createElement('select');
411
+ inputEl.className = 'alert90s-input alert90s-select';
412
+ if (config.inputPlaceholder) {
413
+ const defaultOpt = document.createElement('option');
414
+ defaultOpt.value = '';
415
+ defaultOpt.textContent = config.inputPlaceholder;
416
+ defaultOpt.disabled = true;
417
+ defaultOpt.selected = true;
418
+ inputEl.appendChild(defaultOpt);
419
+ }
420
+ for (const [val, text] of Object.entries(config.inputOptions)) {
421
+ const opt = document.createElement('option');
422
+ opt.value = val;
423
+ opt.textContent = text;
424
+ if (val === config.inputValue) opt.selected = true;
425
+ inputEl.appendChild(opt);
426
+ }
427
+ inputContainer.appendChild(inputEl);
428
+ } else if (config.input === 'radio') {
429
+ const radioGroup = document.createElement('div');
430
+ radioGroup.className = 'alert90s-radio-group';
431
+ for (const [val, text] of Object.entries(config.inputOptions)) {
432
+ const label = document.createElement('label');
433
+ label.className = 'alert90s-radio-label';
434
+ const radio = document.createElement('input');
435
+ radio.type = 'radio';
436
+ radio.name = 'alert90s-radio';
437
+ radio.value = val;
438
+ if (val === config.inputValue) radio.checked = true;
439
+ const span = document.createElement('span');
440
+ span.textContent = text;
441
+ label.appendChild(radio);
442
+ label.appendChild(span);
443
+ radioGroup.appendChild(label);
444
+ }
445
+ inputEl = radioGroup; // Parent serves as reference
446
+ inputContainer.appendChild(radioGroup);
447
+ } else if (config.input === 'checkbox' || config.input === 'toggle') {
448
+ const label = document.createElement('label');
449
+ label.className = config.input === 'toggle' ? 'alert90s-toggle-label' : 'alert90s-checkbox-label';
450
+ inputEl = document.createElement('input');
451
+ inputEl.type = 'checkbox';
452
+ inputEl.checked = !!config.inputValue;
453
+
454
+ if (config.input === 'toggle') {
455
+ const slider = document.createElement('div');
456
+ slider.className = 'alert90s-toggle-slider';
457
+ label.appendChild(inputEl);
458
+ label.appendChild(slider);
459
+ if (config.inputPlaceholder) {
460
+ const span = document.createElement('span');
461
+ span.textContent = config.inputPlaceholder;
462
+ label.appendChild(span);
463
+ }
464
+ } else {
465
+ const span = document.createElement('span');
466
+ span.textContent = config.inputPlaceholder || 'Check me';
467
+ label.appendChild(inputEl);
468
+ label.appendChild(span);
469
+ }
470
+ inputContainer.appendChild(label);
471
+ } else if (config.input === 'textarea') {
392
472
  inputEl = document.createElement('textarea');
473
+ inputEl.className = 'alert90s-input';
474
+ if (config.inputPlaceholder) inputEl.placeholder = config.inputPlaceholder;
475
+ if (config.inputValue) inputEl.value = config.inputValue;
476
+ inputContainer.appendChild(inputEl);
393
477
  } else {
394
478
  inputEl = document.createElement('input');
395
479
  inputEl.type = config.input;
480
+ inputEl.className = 'alert90s-input';
481
+ if (config.inputPlaceholder) inputEl.placeholder = config.inputPlaceholder;
482
+ if (config.inputValue) inputEl.value = config.inputValue;
483
+ inputContainer.appendChild(inputEl);
396
484
  }
397
485
 
398
- inputEl.className = 'alert90s-input';
399
-
400
- // Apply custom attributes
401
- if (config.inputAttributes) {
486
+ // Apply custom attributes (for non-grouped inputs)
487
+ if (config.inputAttributes && inputEl && !['radio'].includes(config.input)) {
402
488
  for (const [key, val] of Object.entries(config.inputAttributes)) {
403
489
  inputEl.setAttribute(key, val);
404
490
  }
405
491
  }
406
492
 
407
- inputContainer.appendChild(inputEl);
408
493
  bodyContainer.appendChild(inputContainer);
409
494
  }
410
495
 
@@ -423,15 +508,23 @@ class Alert90s {
423
508
 
424
509
  if (config.hideClass.popup === 'alert90s-fade-out') {
425
510
  box.style.animation = 'alert90s-fade-out 0.2s forwards';
426
- overlay.style.transition = 'opacity 0.2s';
427
- overlay.style.opacity = '0';
511
+ if (overlay) {
512
+ overlay.style.transition = 'opacity 0.2s';
513
+ overlay.style.opacity = '0';
514
+ }
428
515
  } else {
429
516
  box.className = `alert90s-box ${config.hideClass.popup}`;
430
517
  }
431
518
 
432
519
  setTimeout(() => {
433
- if (document.body.contains(overlay)) {
434
- document.body.removeChild(overlay);
520
+ if (config.toast) {
521
+ if (box.parentNode) {
522
+ box.parentNode.removeChild(box);
523
+ }
524
+ } else {
525
+ if (overlay && document.body.contains(overlay)) {
526
+ document.body.removeChild(overlay);
527
+ }
435
528
  }
436
529
  resolve(resultObj);
437
530
  }, 200);
@@ -441,8 +534,13 @@ class Alert90s {
441
534
  const handleConfirm = async () => {
442
535
  let val = true;
443
536
 
444
- if (inputEl) {
445
- val = inputEl.value;
537
+ if (config.input === 'radio') {
538
+ const checked = inputEl.querySelector('input[type="radio"]:checked');
539
+ val = checked ? checked.value : null;
540
+ } else if (config.input === 'checkbox' || config.input === 'toggle') {
541
+ val = inputEl.checked;
542
+ } else if (inputEl) {
543
+ val = inputEl.value;
446
544
  }
447
545
 
448
546
  if (config.preConfirm) {
@@ -521,17 +619,29 @@ class Alert90s {
521
619
  // Assemble
522
620
  box.appendChild(header);
523
621
  box.appendChild(bodyContainer);
524
- overlay.appendChild(box);
622
+
623
+ if (config.toast) {
624
+ const container = Alert90s.getToastContainer(config.position);
625
+
626
+ // Setup initial animation specifically for toast
627
+ box.style.animation = 'alert90s-toast-slide-in 0.3s ease-out';
628
+
629
+ container.appendChild(box);
630
+ } else {
631
+ overlay.appendChild(box);
632
+ }
525
633
 
526
- if (config.showCloseButton) {
634
+ if (config.showCloseButton && !config.toast) {
527
635
  const closeBtn = header.querySelector('#alert90s-close');
528
636
  if (closeBtn) {
529
637
  closeBtn.onclick = () => finish({ isConfirmed: false, isDenied: false, isDismissed: true, dismiss: 'close' });
530
638
  }
531
639
  }
532
640
 
533
- // Append to body
534
- document.body.appendChild(overlay);
641
+ // Append to body (if it's not a toast)
642
+ if (!config.toast) {
643
+ document.body.appendChild(overlay);
644
+ }
535
645
 
536
646
  // Focus
537
647
  if (config.focusConfirm && confirmBtnRef) {
package/src/styles.css CHANGED
@@ -230,6 +230,120 @@ textarea.alert90s-input {
230
230
  resize: vertical;
231
231
  min-height: 100px;
232
232
  }
233
+
234
+ /* Select */
235
+ select.alert90s-select {
236
+ cursor: pointer;
237
+ appearance: none;
238
+ background-image: linear-gradient(45deg, transparent 50%, #000 50%), linear-gradient(135deg, #000 50%, transparent 50%);
239
+ background-position: calc(100% - 20px) calc(1em + 2px), calc(100% - 15px) calc(1em + 2px);
240
+ background-size: 5px 5px, 5px 5px;
241
+ background-repeat: no-repeat;
242
+ }
243
+
244
+ /* Radio Group */
245
+ .alert90s-radio-group {
246
+ display: flex;
247
+ flex-direction: column;
248
+ gap: 0.5rem;
249
+ align-items: flex-start;
250
+ width: 100%;
251
+ }
252
+ .alert90s-radio-label {
253
+ display: flex;
254
+ align-items: center;
255
+ gap: 0.75rem;
256
+ font-weight: bold;
257
+ cursor: pointer;
258
+ font-size: 1rem;
259
+ }
260
+ .alert90s-radio-label input[type="radio"] {
261
+ appearance: none;
262
+ width: 1.25rem;
263
+ height: 1.25rem;
264
+ border: 4px solid #000;
265
+ border-radius: 50%;
266
+ margin: 0;
267
+ cursor: pointer;
268
+ position: relative;
269
+ background-color: #f8fafc;
270
+ }
271
+ .alert90s-radio-label input[type="radio"]:checked {
272
+ background-color: #000;
273
+ box-shadow: inset 0 0 0 4px #fff;
274
+ }
275
+
276
+ /* Checkbox */
277
+ .alert90s-checkbox-label {
278
+ display: flex;
279
+ align-items: center;
280
+ gap: 0.75rem;
281
+ font-weight: bold;
282
+ cursor: pointer;
283
+ font-size: 1rem;
284
+ }
285
+ .alert90s-checkbox-label input[type="checkbox"] {
286
+ appearance: none;
287
+ width: 1.25rem;
288
+ height: 1.25rem;
289
+ border: 4px solid #000;
290
+ margin: 0;
291
+ cursor: pointer;
292
+ position: relative;
293
+ background-color: #f8fafc;
294
+ }
295
+ .alert90s-checkbox-label input[type="checkbox"]:checked {
296
+ background-color: #000;
297
+ }
298
+ .alert90s-checkbox-label input[type="checkbox"]:checked::after {
299
+ content: '✔';
300
+ position: absolute;
301
+ top: 50%;
302
+ left: 50%;
303
+ transform: translate(-50%, -50%);
304
+ color: #fff;
305
+ font-size: 0.8rem;
306
+ }
307
+
308
+ /* Toggle Switch */
309
+ .alert90s-toggle-label {
310
+ display: flex;
311
+ align-items: center;
312
+ gap: 0.75rem;
313
+ font-weight: bold;
314
+ cursor: pointer;
315
+ font-size: 1rem;
316
+ }
317
+ .alert90s-toggle-label input[type="checkbox"] {
318
+ display: none;
319
+ }
320
+ .alert90s-toggle-slider {
321
+ width: 3rem;
322
+ height: 1.5rem;
323
+ background-color: #f87171;
324
+ border: 4px solid #000;
325
+ position: relative;
326
+ transition: background-color 0.2s;
327
+ box-shadow: inset 3px 3px 0 0 rgba(0,0,0,0.1);
328
+ }
329
+ .alert90s-toggle-slider::before {
330
+ content: '';
331
+ position: absolute;
332
+ width: 1rem;
333
+ height: 100%;
334
+ background-color: #fff;
335
+ border-right: 4px solid #000;
336
+ top: 0;
337
+ left: 0;
338
+ transition: transform 0.2s;
339
+ }
340
+ .alert90s-toggle-label input[type="checkbox"]:checked + .alert90s-toggle-slider {
341
+ background-color: #4ade80;
342
+ }
343
+ .alert90s-toggle-label input[type="checkbox"]:checked + .alert90s-toggle-slider::before {
344
+ transform: translateX(1.5rem);
345
+ border-left: 4px solid #000;
346
+ }
233
347
  .alert90s-validation-message {
234
348
  display: none;
235
349
  width: 100%;
@@ -415,16 +529,37 @@ textarea.alert90s-input {
415
529
  @keyframes alert90s-fade-in { from { opacity: 0; } to { opacity: 1; } }
416
530
  @keyframes alert90s-pop-in { 0% { transform: scale(0.95) translateY(10px); opacity: 0; } 100% { transform: scale(1) translateY(0); opacity: 1; } }
417
531
  @keyframes alert90s-fade-out { 0% { transform: scale(1) translateY(0); opacity: 1; } 100% { transform: scale(0.95) translateY(10px); opacity: 0; } }
532
+ @keyframes alert90s-toast-slide-in { 0% { transform: scale(0.9) translateY(20px); opacity: 0; } 100% { transform: scale(1) translateY(0); opacity: 1; } }
418
533
 
419
- /* Toast Styles */
420
- .alert90s-overlay.toast-overlay {
421
- background-color: transparent !important;
422
- backdrop-filter: none !important;
534
+ /* Toast Containers */
535
+ .alert90s-toast-container {
536
+ position: fixed;
537
+ display: flex;
538
+ z-index: 10000;
539
+ padding: 10px;
423
540
  pointer-events: none;
541
+ gap: 10px;
424
542
  }
425
543
 
544
+ .alert90s-toast-top-start { top: 0; left: 0; flex-direction: column; }
545
+ .alert90s-toast-top { top: 0; left: 50%; transform: translateX(-50%); flex-direction: column; }
546
+ .alert90s-toast-top-end { top: 0; right: 0; flex-direction: column; }
547
+ .alert90s-toast-center-start { top: 50%; left: 0; transform: translateY(-50%); flex-direction: column; }
548
+ .alert90s-toast-center { top: 50%; left: 50%; transform: translate(-50%, -50%); flex-direction: column; }
549
+ .alert90s-toast-center-end { top: 50%; right: 0; transform: translateY(-50%); flex-direction: column; }
550
+ .alert90s-toast-bottom-start { bottom: 0; left: 0; flex-direction: column-reverse; }
551
+ .alert90s-toast-bottom { bottom: 0; left: 50%; transform: translateX(-50%); flex-direction: column-reverse; }
552
+ .alert90s-toast-bottom-end { bottom: 0; right: 0; flex-direction: column-reverse; }
553
+
554
+ /* Toast Styles */
426
555
  .alert90s-box.alert90s-toast {
427
556
  pointer-events: auto;
557
+ position: relative !important;
558
+ transform: none !important;
559
+ top: auto !important;
560
+ left: auto !important;
561
+ right: auto !important;
562
+ bottom: auto !important;
428
563
  width: auto;
429
564
  min-width: 250px;
430
565
  max-width: 100%;
@@ -432,6 +567,7 @@ textarea.alert90s-input {
432
567
  align-items: stretch;
433
568
  padding: 0;
434
569
  box-shadow: 6px 6px 0 0 #000;
570
+ margin: 0;
435
571
  }
436
572
 
437
573
  .alert90s-toast .alert90s-header {