modern-alert 1.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.
- package/LICENSE +21 -0
- package/README.md +214 -0
- package/package.json +53 -0
- package/src/icons.js +41 -0
- package/src/modern-alert.css +467 -0
- package/src/modern-alert.d.ts +84 -0
- package/src/modern-alert.js +601 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Paul's Digital Studio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# ModernAlert
|
|
2
|
+
|
|
3
|
+
A small dialog library for the browser. No npm dependencies, no framework.
|
|
4
|
+
|
|
5
|
+
Drop in three files. Call `ModernAlert.show()`. Get a promise back.
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
const result = await ModernAlert.confirm(
|
|
9
|
+
'Delete this project?',
|
|
10
|
+
'Files stay in the trash for 30 days.'
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
if (result.isConfirmed) {
|
|
14
|
+
await deleteProject()
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The default card is left-aligned, with the type color as a thin top line. Light, dark, or follow the system. The circular icon is opt-in.
|
|
19
|
+
|
|
20
|
+
## What you get
|
|
21
|
+
|
|
22
|
+
- Dialog first, decoration second (`icon` is off by default)
|
|
23
|
+
- Semantic types: `success`, `error`, `warning`, `info`, `question`, `confirm`, `loading`
|
|
24
|
+
- Backdrop you can keep, drop, or keep invisible while still blocking the page
|
|
25
|
+
- Inputs, HTML, loading, and a timer — still three files, no bundler
|
|
26
|
+
|
|
27
|
+
## Setup
|
|
28
|
+
|
|
29
|
+
Load the three files in this order. `window.ModernAlert` is ready after the last script.
|
|
30
|
+
|
|
31
|
+
### npm
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install modern-alert
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```html
|
|
38
|
+
<link rel="stylesheet" href="node_modules/modern-alert/src/modern-alert.css">
|
|
39
|
+
<script src="node_modules/modern-alert/src/icons.js"></script>
|
|
40
|
+
<script src="node_modules/modern-alert/src/modern-alert.js"></script>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If your bundler can import CSS:
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
import 'modern-alert/src/icons.js'
|
|
47
|
+
import 'modern-alert'
|
|
48
|
+
import 'modern-alert/modern-alert.css'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### CDN
|
|
52
|
+
|
|
53
|
+
After the package is on npm:
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/modern-alert@1.0.0/src/modern-alert.css">
|
|
57
|
+
<script src="https://cdn.jsdelivr.net/npm/modern-alert@1.0.0/src/icons.js"></script>
|
|
58
|
+
<script src="https://cdn.jsdelivr.net/npm/modern-alert@1.0.0/src/modern-alert.js"></script>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Pin a version. `@latest` will follow new releases.
|
|
62
|
+
|
|
63
|
+
TypeScript types ship in the package (`src/modern-alert.d.ts`).
|
|
64
|
+
|
|
65
|
+
### Copy the files
|
|
66
|
+
|
|
67
|
+
Copy `src/modern-alert.css`, `src/icons.js`, and `src/modern-alert.js` into your project:
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<link rel="stylesheet" href="src/modern-alert.css">
|
|
71
|
+
<script src="src/icons.js"></script>
|
|
72
|
+
<script src="src/modern-alert.js"></script>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Usage
|
|
76
|
+
|
|
77
|
+
### A simple message
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
await ModernAlert.success('Saved', 'The file is already in the library.')
|
|
81
|
+
await ModernAlert.error('Could not save', 'Check your connection and try again.')
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Confirm something destructive
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
const { isConfirmed } = await ModernAlert.confirm(
|
|
88
|
+
'Delete this project?',
|
|
89
|
+
'You can restore it from the trash.'
|
|
90
|
+
)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`confirm` shows Cancel and a primary action. Other types show a single button unless you pass `cancelText`.
|
|
94
|
+
|
|
95
|
+
### Ask for a value
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
const result = await ModernAlert.show({
|
|
99
|
+
type: 'question',
|
|
100
|
+
title: 'What should we call it?',
|
|
101
|
+
input: 'text',
|
|
102
|
+
inputPlaceholder: 'Project name',
|
|
103
|
+
inputValidator: (value) => !String(value).trim() && 'Give it a name'
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
if (result.isConfirmed) {
|
|
107
|
+
createProject(result.value)
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`input` can be `text`, `email`, `password`, `textarea`, or `select` (`inputOptions` + `inputValue` for select).
|
|
112
|
+
|
|
113
|
+
### Loading, then done
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
ModernAlert.loading('Saving…')
|
|
117
|
+
|
|
118
|
+
await api.save()
|
|
119
|
+
|
|
120
|
+
await ModernAlert.success('Saved', 'You can keep working.')
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
A loading dialog does not close on backdrop click or Escape. Close it with `ModernAlert.close()`, or replace it with the next `show()` / `success()`.
|
|
124
|
+
|
|
125
|
+
### HTML inside the body
|
|
126
|
+
|
|
127
|
+
```js
|
|
128
|
+
await ModernAlert.show({
|
|
129
|
+
title: "What's new",
|
|
130
|
+
html: '<p>You can pass <strong>your own markup</strong>.</p>'
|
|
131
|
+
})
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Markup is sanitized: scripts, event handlers, and `javascript:` URLs are stripped.
|
|
135
|
+
|
|
136
|
+
## Look
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
await ModernAlert.show({
|
|
140
|
+
title: 'Deployed',
|
|
141
|
+
text: 'v2.4.1 is live.',
|
|
142
|
+
theme: 'dark', // auto | light | dark
|
|
143
|
+
icon: true, // circular SVG mascot
|
|
144
|
+
backdrop: false // no dim; the page still cannot be clicked
|
|
145
|
+
})
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Shorthand helpers take an optional third argument for any option:
|
|
149
|
+
|
|
150
|
+
```js
|
|
151
|
+
ModernAlert.success('Saved', 'All set.', { theme: 'dark', timer: 2000 })
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Options
|
|
155
|
+
|
|
156
|
+
| Option | Default | Meaning |
|
|
157
|
+
| --- | --- | --- |
|
|
158
|
+
| `type` | `'info'` | `success` `error` `warning` `info` `question` `confirm` `loading` |
|
|
159
|
+
| `title` | `''` | Heading |
|
|
160
|
+
| `text` | `''` | Body text. Ignored if `html` is set |
|
|
161
|
+
| `html` | `''` | Sanitized markup for the body |
|
|
162
|
+
| `confirmText` | `'OK'` | Primary button label |
|
|
163
|
+
| `cancelText` | `''` | Secondary button label. Any non-empty value also shows Cancel |
|
|
164
|
+
| `showConfirm` | `true` | Show the primary button |
|
|
165
|
+
| `showCancel` | `false` | Show Cancel. `type: 'confirm'` turns this on |
|
|
166
|
+
| `input` | `''` | `text` `email` `password` `textarea` `select` |
|
|
167
|
+
| `inputPlaceholder` | `''` | Placeholder for text-like inputs |
|
|
168
|
+
| `inputValue` | `''` | Initial value, or the selected key for `select` |
|
|
169
|
+
| `inputLabel` | `''` | Label above the field |
|
|
170
|
+
| `inputOptions` | `null` | `{ value: 'Label' }` map for `select` |
|
|
171
|
+
| `inputValidator` | `null` | `(value) => errorMessage`. Return a string to block confirm |
|
|
172
|
+
| `theme` | `'auto'` | Follows `prefers-color-scheme`, or `'light'` / `'dark'` |
|
|
173
|
+
| `icon` | `false` | `true` shows the animated 72px type icon. Forced on for `loading` |
|
|
174
|
+
| `backdrop` | `true` | `false` removes the dim and blur, not the click shield |
|
|
175
|
+
| `timer` | `0` | Auto-dismiss after N milliseconds. Ignored for `loading` |
|
|
176
|
+
| `allowOutsideClick` | `true` | Click outside the card to dismiss. Off for `loading` |
|
|
177
|
+
| `allowEscapeKey` | `true` | Escape to dismiss. Off for `loading` |
|
|
178
|
+
|
|
179
|
+
## The promise
|
|
180
|
+
|
|
181
|
+
Every call returns:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
{
|
|
185
|
+
isConfirmed: boolean
|
|
186
|
+
isDismissed: boolean
|
|
187
|
+
value: any // true, or the input string
|
|
188
|
+
dismiss: string // 'cancel' | 'esc' | 'backdrop' | 'timer' | 'close' | 'replace'
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`dismiss` is set only when the dialog was not confirmed.
|
|
193
|
+
|
|
194
|
+
```js
|
|
195
|
+
ModernAlert.show({ title: 'Ping' })
|
|
196
|
+
ModernAlert.isVisible() // true
|
|
197
|
+
ModernAlert.close() // dismiss: 'close'
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## API map
|
|
201
|
+
|
|
202
|
+
| Call | What it does |
|
|
203
|
+
| --- | --- |
|
|
204
|
+
| `show(options)` | Full dialog |
|
|
205
|
+
| `show(title, text, type)` | Same, positional |
|
|
206
|
+
| `success` `error` `warning` `info` `question` | Typed helpers |
|
|
207
|
+
| `confirm(title, text, options?)` | Two actions |
|
|
208
|
+
| `loading(title, text?)` | Spinner, no buttons |
|
|
209
|
+
| `close()` | Dismiss the open dialog |
|
|
210
|
+
| `isVisible()` | Whether a dialog is on screen |
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "modern-alert",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Modern modal dialogs for the browser. No dependencies.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Paul's Digital Studio",
|
|
8
|
+
"url": "https://github.com/PaulsDigital"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/PaulsDigital/modern-alert.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/PaulsDigital/modern-alert/issues"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/PaulsDigital/modern-alert#readme",
|
|
18
|
+
"keywords": [
|
|
19
|
+
"alert",
|
|
20
|
+
"dialog",
|
|
21
|
+
"modal",
|
|
22
|
+
"confirm",
|
|
23
|
+
"prompt",
|
|
24
|
+
"popup",
|
|
25
|
+
"vanilla-js"
|
|
26
|
+
],
|
|
27
|
+
"main": "src/modern-alert.js",
|
|
28
|
+
"browser": "src/modern-alert.js",
|
|
29
|
+
"style": "src/modern-alert.css",
|
|
30
|
+
"types": "src/modern-alert.d.ts",
|
|
31
|
+
"unpkg": "src/modern-alert.js",
|
|
32
|
+
"jsdelivr": "src/modern-alert.js",
|
|
33
|
+
"files": [
|
|
34
|
+
"src",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"types": "./src/modern-alert.d.ts",
|
|
40
|
+
"default": "./src/modern-alert.js"
|
|
41
|
+
},
|
|
42
|
+
"./modern-alert.css": "./src/modern-alert.css",
|
|
43
|
+
"./src/modern-alert.css": "./src/modern-alert.css",
|
|
44
|
+
"./src/modern-alert.js": "./src/modern-alert.js",
|
|
45
|
+
"./src/icons.js": "./src/icons.js",
|
|
46
|
+
"./package.json": "./package.json"
|
|
47
|
+
},
|
|
48
|
+
"sideEffects": [
|
|
49
|
+
"./src/modern-alert.js",
|
|
50
|
+
"./src/icons.js",
|
|
51
|
+
"*.css"
|
|
52
|
+
]
|
|
53
|
+
}
|
package/src/icons.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
(function (global) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const stroke =
|
|
5
|
+
'fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" pathLength="1"';
|
|
6
|
+
|
|
7
|
+
global.ModernAlertIcons = {
|
|
8
|
+
success:
|
|
9
|
+
'<svg class="ma-svg" viewBox="0 0 64 64" aria-hidden="true">' +
|
|
10
|
+
'<circle class="ma-stroke ma-stroke--ring" cx="32" cy="32" r="26" ' + stroke + '></circle>' +
|
|
11
|
+
'<path class="ma-stroke ma-stroke--mark" d="M20.5 33.2l8.2 8.3 15.6-18" ' + stroke + '></path>' +
|
|
12
|
+
'</svg>',
|
|
13
|
+
|
|
14
|
+
error:
|
|
15
|
+
'<svg class="ma-svg" viewBox="0 0 64 64" aria-hidden="true">' +
|
|
16
|
+
'<circle class="ma-stroke ma-stroke--ring" cx="32" cy="32" r="26" ' + stroke + '></circle>' +
|
|
17
|
+
'<path class="ma-stroke ma-stroke--mark" d="M24 24l16 16M40 24L24 40" ' + stroke + '></path>' +
|
|
18
|
+
'</svg>',
|
|
19
|
+
|
|
20
|
+
warning:
|
|
21
|
+
'<svg class="ma-svg" viewBox="0 0 64 64" aria-hidden="true">' +
|
|
22
|
+
'<path class="ma-stroke ma-stroke--ring" d="M32 12.5L54 51.5H10z" ' + stroke + '></path>' +
|
|
23
|
+
'<path class="ma-stroke ma-stroke--mark" d="M32 26v12" ' + stroke + '></path>' +
|
|
24
|
+
'<circle class="ma-stroke ma-stroke--dot" cx="32" cy="46" r="1.4" fill="currentColor" stroke="none"></circle>' +
|
|
25
|
+
'</svg>',
|
|
26
|
+
|
|
27
|
+
info:
|
|
28
|
+
'<svg class="ma-svg" viewBox="0 0 64 64" aria-hidden="true">' +
|
|
29
|
+
'<circle class="ma-stroke ma-stroke--ring" cx="32" cy="32" r="26" ' + stroke + '></circle>' +
|
|
30
|
+
'<path class="ma-stroke ma-stroke--mark" d="M32 29.5V42" ' + stroke + '></path>' +
|
|
31
|
+
'<circle class="ma-stroke ma-stroke--dot" cx="32" cy="23" r="1.6" fill="currentColor" stroke="none"></circle>' +
|
|
32
|
+
'</svg>',
|
|
33
|
+
|
|
34
|
+
question:
|
|
35
|
+
'<svg class="ma-svg" viewBox="0 0 64 64" aria-hidden="true">' +
|
|
36
|
+
'<circle class="ma-stroke ma-stroke--ring" cx="32" cy="32" r="26" ' + stroke + '></circle>' +
|
|
37
|
+
'<path class="ma-stroke ma-stroke--mark" d="M26 25.5c1.2-3.6 6.8-5 10.2-2.4 3 2.3 2.6 6.2-.2 8.2-1.8 1.3-4 2.2-4 5.2" ' + stroke + '></path>' +
|
|
38
|
+
'<circle class="ma-stroke ma-stroke--dot" cx="32" cy="44.5" r="1.6" fill="currentColor" stroke="none"></circle>' +
|
|
39
|
+
'</svg>'
|
|
40
|
+
};
|
|
41
|
+
})(typeof window !== 'undefined' ? window : this);
|