hyperclayjs 1.6.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/package.json +17 -25
- package/src/core/adminContenteditable.js +51 -0
- package/{core → src/core}/adminInputs.js +29 -8
- package/src/core/adminOnClick.js +54 -0
- package/{core → src/core}/adminResources.js +25 -5
- package/src/core/optionVisibility.js +216 -0
- package/{core → src/core}/savePage.js +1 -1
- package/{core → src/core}/savePageCore.js +13 -3
- package/{custom-attributes → src/custom-attributes}/domHelpers.js +17 -4
- package/{custom-attributes → src/custom-attributes}/events.js +2 -0
- package/src/custom-attributes/onmutation.js +90 -0
- package/src/custom-attributes/onpagemutation.js +32 -0
- package/{custom-attributes → src/custom-attributes}/sortable.js +16 -1
- package/{dom-utilities → src/dom-utilities}/All.js +22 -0
- package/{hyperclay.js → src/hyperclay.js} +4 -4
- package/{module-dependency-graph.json → src/module-dependency-graph.json} +16 -26
- package/{ui → src/ui}/prompts.js +13 -18
- package/{ui → src/ui}/theModal.js +101 -0
- package/{ui → src/ui}/toast.js +4 -3
- package/core/adminContenteditable.js +0 -36
- package/core/adminOnClick.js +0 -31
- package/core/optionVisibilityRuleGenerator.js +0 -171
- package/custom-attributes/onpagemutation.js +0 -20
- /package/{communication → src/communication}/behaviorCollector.js +0 -0
- /package/{communication → src/communication}/sendMessage.js +0 -0
- /package/{communication → src/communication}/uploadFile.js +0 -0
- /package/{core → src/core}/adminSystem.js +0 -0
- /package/{core → src/core}/autosave.js +0 -0
- /package/{core → src/core}/editmode.js +0 -0
- /package/{core → src/core}/editmodeSystem.js +0 -0
- /package/{core → src/core}/enablePersistentFormInputValues.js +0 -0
- /package/{core → src/core}/exportToWindow.js +0 -0
- /package/{core → src/core}/isAdminOfCurrentResource.js +0 -0
- /package/{core → src/core}/saveToast.js +0 -0
- /package/{core → src/core}/setPageTypeOnDocumentElement.js +0 -0
- /package/{custom-attributes → src/custom-attributes}/ajaxElements.js +0 -0
- /package/{custom-attributes → src/custom-attributes}/autosize.js +0 -0
- /package/{custom-attributes → src/custom-attributes}/inputHelpers.js +0 -0
- /package/{custom-attributes → src/custom-attributes}/onaftersave.js +0 -0
- /package/{custom-attributes → src/custom-attributes}/onclickaway.js +0 -0
- /package/{custom-attributes → src/custom-attributes}/onclone.js +0 -0
- /package/{custom-attributes → src/custom-attributes}/onrender.js +0 -0
- /package/{custom-attributes → src/custom-attributes}/preventEnter.js +0 -0
- /package/{dom-utilities → src/dom-utilities}/getDataFromForm.js +0 -0
- /package/{dom-utilities → src/dom-utilities}/insertStyleTag.js +0 -0
- /package/{dom-utilities → src/dom-utilities}/onDomReady.js +0 -0
- /package/{dom-utilities → src/dom-utilities}/onLoad.js +0 -0
- /package/{string-utilities → src/string-utilities}/copy-to-clipboard.js +0 -0
- /package/{string-utilities → src/string-utilities}/query.js +0 -0
- /package/{string-utilities → src/string-utilities}/slugify.js +0 -0
- /package/{ui → src/ui}/toast-hyperclay.js +0 -0
- /package/{utilities → src/utilities}/cookie.js +0 -0
- /package/{utilities → src/utilities}/debounce.js +0 -0
- /package/{utilities → src/utilities}/loadVendorScript.js +0 -0
- /package/{utilities → src/utilities}/mutation.js +0 -0
- /package/{utilities → src/utilities}/nearest.js +0 -0
- /package/{utilities → src/utilities}/pipe.js +0 -0
- /package/{utilities → src/utilities}/throttle.js +0 -0
- /package/{vendor → src/vendor}/Sortable.vendor.js +0 -0
- /package/{vendor → src/vendor}/idiomorph.min.js +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/*
|
|
2
|
+
[onmutation] - Trigger code when this element or its children change
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
<div onmutation="console.log('My content changed')">
|
|
6
|
+
<span contenteditable>Edit me</span>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
Unlike [onglobalmutation]/[onpagemutation] which fires on ANY DOM change,
|
|
10
|
+
[onmutation] only fires when the element itself or its descendants mutate.
|
|
11
|
+
*/
|
|
12
|
+
import Mutation from "../utilities/mutation.js";
|
|
13
|
+
|
|
14
|
+
const observers = new WeakMap();
|
|
15
|
+
|
|
16
|
+
function setupMutationObserver(element) {
|
|
17
|
+
if (observers.has(element)) return;
|
|
18
|
+
|
|
19
|
+
const executeMutation = async () => {
|
|
20
|
+
try {
|
|
21
|
+
const code = element.getAttribute('onmutation');
|
|
22
|
+
if (!code) return;
|
|
23
|
+
const asyncFn = new Function(`return (async function() { ${code} })`)();
|
|
24
|
+
await asyncFn.call(element);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error('Error in onmutation execution:', error);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const observer = new MutationObserver(() => {
|
|
31
|
+
executeMutation();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
observer.observe(element, {
|
|
35
|
+
childList: true,
|
|
36
|
+
subtree: true,
|
|
37
|
+
characterData: true,
|
|
38
|
+
attributes: true
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
observers.set(element, observer);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function teardownMutationObserver(element) {
|
|
45
|
+
const observer = observers.get(element);
|
|
46
|
+
if (observer) {
|
|
47
|
+
observer.disconnect();
|
|
48
|
+
observers.delete(element);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function init() {
|
|
53
|
+
// Set up existing elements
|
|
54
|
+
document.querySelectorAll('[onmutation]').forEach(setupMutationObserver);
|
|
55
|
+
|
|
56
|
+
// Watch for dynamically added elements with onmutation
|
|
57
|
+
Mutation.onAddElement({
|
|
58
|
+
selectorFilter: '[onmutation]',
|
|
59
|
+
debounce: 200
|
|
60
|
+
}, (changes) => {
|
|
61
|
+
changes.forEach(({ element }) => {
|
|
62
|
+
setupMutationObserver(element);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Clean up when elements are removed
|
|
67
|
+
Mutation.onRemoveElement({
|
|
68
|
+
selectorFilter: '[onmutation]',
|
|
69
|
+
debounce: 200
|
|
70
|
+
}, (changes) => {
|
|
71
|
+
changes.forEach(({ element }) => {
|
|
72
|
+
teardownMutationObserver(element);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Watch for attribute removal
|
|
77
|
+
Mutation.onAttribute({
|
|
78
|
+
selectorFilter: '[onmutation]',
|
|
79
|
+
debounce: 200
|
|
80
|
+
}, (changes) => {
|
|
81
|
+
changes.forEach(({ element, attribute, newValue }) => {
|
|
82
|
+
if (attribute === 'onmutation' && newValue === null) {
|
|
83
|
+
teardownMutationObserver(element);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { init };
|
|
90
|
+
export default init;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
[onpagemutation] / [onglobalmutation] - Trigger code when ANY element on the page changes
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
<span onglobalmutation="this.textContent = All('li').length">0</span>
|
|
6
|
+
<span onpagemutation="this.textContent = All('li').length">0</span>
|
|
7
|
+
|
|
8
|
+
Both attributes are equivalent - onglobalmutation is the preferred name for clarity.
|
|
9
|
+
*/
|
|
10
|
+
import Mutation from "../utilities/mutation.js";
|
|
11
|
+
|
|
12
|
+
function init() {
|
|
13
|
+
const executeGlobalMutation = async element => {
|
|
14
|
+
try {
|
|
15
|
+
// Support both onglobalmutation and onpagemutation (legacy)
|
|
16
|
+
const code = element.getAttribute('onglobalmutation') || element.getAttribute('onpagemutation');
|
|
17
|
+
const asyncFn = new Function(`return (async function() { ${code} })`)();
|
|
18
|
+
await asyncFn.call(element);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error('Error in onglobalmutation/onpagemutation execution:', error);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
Mutation.onAnyChange({
|
|
25
|
+
debounce: 200,
|
|
26
|
+
omitChangeDetails: true
|
|
27
|
+
}, () => {
|
|
28
|
+
document.querySelectorAll('[onglobalmutation], [onpagemutation]').forEach(executeGlobalMutation);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export { init };
|
|
32
|
+
export default init;
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
How to use:
|
|
6
6
|
- add `sortable` attribute to an element to make children sortable
|
|
7
7
|
- e.g. <div sortable></div>
|
|
8
|
+
- add `onsorting` attribute to execute code during drag
|
|
9
|
+
- e.g. <ul sortable onsorting="console.log('Dragging!')"></ul>
|
|
8
10
|
- add `onsorted` attribute to execute code when items are sorted
|
|
9
11
|
- e.g. <ul sortable onsorted="console.log('Items reordered!')"></ul>
|
|
10
12
|
|
|
@@ -39,7 +41,20 @@ function makeSortable(sortableElem, Sortable) {
|
|
|
39
41
|
options.handle = '[sortable-handle]';
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
// Add
|
|
44
|
+
// Add onsorting callback if attribute exists (fires during drag)
|
|
45
|
+
const onsortingCode = sortableElem.getAttribute('onsorting');
|
|
46
|
+
if (onsortingCode) {
|
|
47
|
+
options.onMove = function(evt) {
|
|
48
|
+
try {
|
|
49
|
+
const asyncFn = new Function(`return (async function(evt) { ${onsortingCode} })`)();
|
|
50
|
+
asyncFn.call(sortableElem, evt);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error('Error in onsorting execution:', error);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Add onsorted callback if attribute exists (fires after drop)
|
|
43
58
|
const onsortedCode = sortableElem.getAttribute('onsorted');
|
|
44
59
|
if (onsortedCode) {
|
|
45
60
|
options.onEnd = function(evt) {
|
|
@@ -336,6 +336,28 @@ const defaultPlugins = {
|
|
|
336
336
|
});
|
|
337
337
|
|
|
338
338
|
return this;
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
pluck(attr) {
|
|
342
|
+
return this.map(el => el.getAttribute(attr));
|
|
343
|
+
},
|
|
344
|
+
|
|
345
|
+
unique() {
|
|
346
|
+
return [...new Set(this)];
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
sortBy(fn) {
|
|
350
|
+
if (typeof fn === 'string') {
|
|
351
|
+
const attr = fn;
|
|
352
|
+
fn = el => el.getAttribute(attr);
|
|
353
|
+
}
|
|
354
|
+
return [...this].sort((a, b) => {
|
|
355
|
+
const aVal = fn(a);
|
|
356
|
+
const bVal = fn(b);
|
|
357
|
+
if (aVal < bVal) return -1;
|
|
358
|
+
if (aVal > bVal) return 1;
|
|
359
|
+
return 0;
|
|
360
|
+
});
|
|
339
361
|
}
|
|
340
362
|
}
|
|
341
363
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HyperclayJS v1.
|
|
2
|
+
* HyperclayJS v1.8.0 - Minimal Browser-Native Loader
|
|
3
3
|
*
|
|
4
4
|
* Modules auto-init when imported (no separate init call needed).
|
|
5
5
|
* Include `export-to-window` feature to export to window.hyperclay.
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
*
|
|
9
9
|
* <script type="module">
|
|
10
10
|
* // With window.hyperclay (default presets include export-to-window):
|
|
11
|
-
* await import('https://cdn.jsdelivr.net/npm/hyperclayjs@1/hyperclay.js?preset=minimal');
|
|
11
|
+
* await import('https://cdn.jsdelivr.net/npm/hyperclayjs@1/src/hyperclay.js?preset=minimal');
|
|
12
12
|
* const { toast, savePage } = window.hyperclay;
|
|
13
13
|
*
|
|
14
14
|
* // ES modules only (exclude export-to-window):
|
|
15
|
-
* const hyperclay = await import('https://cdn.jsdelivr.net/npm/hyperclayjs@1/hyperclay.js?preset=minimal&exclude=export-to-window');
|
|
15
|
+
* const hyperclay = await import('https://cdn.jsdelivr.net/npm/hyperclayjs@1/src/hyperclay.js?preset=minimal&exclude=export-to-window');
|
|
16
16
|
* const modules = window.hyperclayModules;
|
|
17
17
|
* </script>
|
|
18
18
|
*
|
|
@@ -31,7 +31,7 @@ const MODULE_PATHS = {
|
|
|
31
31
|
"save-toast": "./core/saveToast.js",
|
|
32
32
|
"edit-mode-helpers": "./core/adminSystem.js",
|
|
33
33
|
"persist": "./core/enablePersistentFormInputValues.js",
|
|
34
|
-
"option-visibility": "./core/
|
|
34
|
+
"option-visibility": "./core/optionVisibility.js",
|
|
35
35
|
"edit-mode": "./core/editmodeSystem.js",
|
|
36
36
|
"event-attrs": "./custom-attributes/events.js",
|
|
37
37
|
"ajax-elements": "./custom-attributes/ajaxElements.js",
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"rawDependencies": {
|
|
3
|
-
"__tests__/All.test.js": [
|
|
4
|
-
"dom-utilities/All.js"
|
|
5
|
-
],
|
|
6
|
-
"babel.config.js": [],
|
|
7
|
-
"build/build-loader.js": [],
|
|
8
|
-
"build/generate-dependency-graph.js": [],
|
|
9
|
-
"build/generate-load-jsdelivr.js": [],
|
|
10
|
-
"build/generate-readme.js": [],
|
|
11
|
-
"build/hyperclay.template.js": [],
|
|
12
|
-
"build/update-index-url.js": [],
|
|
13
3
|
"communication/behaviorCollector.js": [],
|
|
14
4
|
"communication/sendMessage.js": [
|
|
15
5
|
"communication/behaviorCollector.js",
|
|
@@ -68,7 +58,7 @@
|
|
|
68
58
|
"string-utilities/query.js",
|
|
69
59
|
"utilities/cookie.js"
|
|
70
60
|
],
|
|
71
|
-
"core/
|
|
61
|
+
"core/optionVisibility.js": [
|
|
72
62
|
"utilities/mutation.js"
|
|
73
63
|
],
|
|
74
64
|
"core/savePage.js": [
|
|
@@ -89,9 +79,6 @@
|
|
|
89
79
|
"core/savePage.js",
|
|
90
80
|
"dom-utilities/onDomReady.js"
|
|
91
81
|
],
|
|
92
|
-
"coverage/lcov-report/block-navigation.js": [],
|
|
93
|
-
"coverage/lcov-report/prettify.js": [],
|
|
94
|
-
"coverage/lcov-report/sorter.js": [],
|
|
95
82
|
"custom-attributes/ajaxElements.js": [
|
|
96
83
|
"dom-utilities/getDataFromForm.js"
|
|
97
84
|
],
|
|
@@ -103,6 +90,7 @@
|
|
|
103
90
|
"custom-attributes/events.js": [
|
|
104
91
|
"custom-attributes/onclickaway.js",
|
|
105
92
|
"custom-attributes/onclone.js",
|
|
93
|
+
"custom-attributes/onmutation.js",
|
|
106
94
|
"custom-attributes/onpagemutation.js",
|
|
107
95
|
"custom-attributes/onrender.js"
|
|
108
96
|
],
|
|
@@ -113,6 +101,9 @@
|
|
|
113
101
|
"custom-attributes/onaftersave.js": [],
|
|
114
102
|
"custom-attributes/onclickaway.js": [],
|
|
115
103
|
"custom-attributes/onclone.js": [],
|
|
104
|
+
"custom-attributes/onmutation.js": [
|
|
105
|
+
"utilities/mutation.js"
|
|
106
|
+
],
|
|
116
107
|
"custom-attributes/onpagemutation.js": [
|
|
117
108
|
"utilities/mutation.js"
|
|
118
109
|
],
|
|
@@ -132,7 +123,6 @@
|
|
|
132
123
|
"dom-utilities/onDomReady.js": [],
|
|
133
124
|
"dom-utilities/onLoad.js": [],
|
|
134
125
|
"hyperclay.js": [],
|
|
135
|
-
"jest.config.js": [],
|
|
136
126
|
"string-utilities/copy-to-clipboard.js": [],
|
|
137
127
|
"string-utilities/query.js": [],
|
|
138
128
|
"string-utilities/slugify.js": [],
|
|
@@ -161,7 +151,7 @@
|
|
|
161
151
|
"save-core": {
|
|
162
152
|
"name": "save-core",
|
|
163
153
|
"category": "core",
|
|
164
|
-
"size": 6.
|
|
154
|
+
"size": 6.5,
|
|
165
155
|
"files": [
|
|
166
156
|
"core/savePageCore.js"
|
|
167
157
|
],
|
|
@@ -218,7 +208,7 @@
|
|
|
218
208
|
"edit-mode-helpers": {
|
|
219
209
|
"name": "edit-mode-helpers",
|
|
220
210
|
"category": "core",
|
|
221
|
-
"size":
|
|
211
|
+
"size": 7.500000000000001,
|
|
222
212
|
"files": [
|
|
223
213
|
"core/adminSystem.js",
|
|
224
214
|
"core/adminContenteditable.js",
|
|
@@ -242,9 +232,9 @@
|
|
|
242
232
|
"option-visibility": {
|
|
243
233
|
"name": "option-visibility",
|
|
244
234
|
"category": "core",
|
|
245
|
-
"size":
|
|
235
|
+
"size": 5.9,
|
|
246
236
|
"files": [
|
|
247
|
-
"core/
|
|
237
|
+
"core/optionVisibility.js"
|
|
248
238
|
],
|
|
249
239
|
"description": "Dynamic show/hide based on ancestor state with option:attribute=\"value\"",
|
|
250
240
|
"exports": {}
|
|
@@ -274,7 +264,7 @@
|
|
|
274
264
|
"event-attrs": {
|
|
275
265
|
"name": "event-attrs",
|
|
276
266
|
"category": "custom-attributes",
|
|
277
|
-
"size":
|
|
267
|
+
"size": 4.1000000000000005,
|
|
278
268
|
"files": [
|
|
279
269
|
"custom-attributes/events.js",
|
|
280
270
|
"custom-attributes/onclickaway.js",
|
|
@@ -298,7 +288,7 @@
|
|
|
298
288
|
"sortable": {
|
|
299
289
|
"name": "sortable",
|
|
300
290
|
"category": "custom-attributes",
|
|
301
|
-
"size":
|
|
291
|
+
"size": 3.4,
|
|
302
292
|
"files": [
|
|
303
293
|
"custom-attributes/sortable.js"
|
|
304
294
|
],
|
|
@@ -308,7 +298,7 @@
|
|
|
308
298
|
"dom-helpers": {
|
|
309
299
|
"name": "dom-helpers",
|
|
310
300
|
"category": "custom-attributes",
|
|
311
|
-
"size":
|
|
301
|
+
"size": 6.2,
|
|
312
302
|
"files": [
|
|
313
303
|
"custom-attributes/domHelpers.js"
|
|
314
304
|
],
|
|
@@ -340,7 +330,7 @@
|
|
|
340
330
|
"dialogs": {
|
|
341
331
|
"name": "dialogs",
|
|
342
332
|
"category": "ui",
|
|
343
|
-
"size":
|
|
333
|
+
"size": 7.7,
|
|
344
334
|
"files": [
|
|
345
335
|
"ui/prompts.js"
|
|
346
336
|
],
|
|
@@ -396,7 +386,7 @@
|
|
|
396
386
|
"the-modal": {
|
|
397
387
|
"name": "the-modal",
|
|
398
388
|
"category": "ui",
|
|
399
|
-
"size":
|
|
389
|
+
"size": 21.8,
|
|
400
390
|
"files": [
|
|
401
391
|
"ui/theModal.js"
|
|
402
392
|
],
|
|
@@ -512,7 +502,7 @@
|
|
|
512
502
|
"all-js": {
|
|
513
503
|
"name": "all-js",
|
|
514
504
|
"category": "dom-utilities",
|
|
515
|
-
"size": 14,
|
|
505
|
+
"size": 14.4,
|
|
516
506
|
"files": [
|
|
517
507
|
"dom-utilities/All.js"
|
|
518
508
|
],
|
|
@@ -678,7 +668,7 @@
|
|
|
678
668
|
"save-toast": "./core/saveToast.js",
|
|
679
669
|
"edit-mode-helpers": "./core/adminSystem.js",
|
|
680
670
|
"persist": "./core/enablePersistentFormInputValues.js",
|
|
681
|
-
"option-visibility": "./core/
|
|
671
|
+
"option-visibility": "./core/optionVisibility.js",
|
|
682
672
|
"edit-mode": "./core/editmodeSystem.js",
|
|
683
673
|
"event-attrs": "./custom-attributes/events.js",
|
|
684
674
|
"ajax-elements": "./custom-attributes/ajaxElements.js",
|
package/{ui → src/ui}/prompts.js
RENAMED
|
@@ -3,7 +3,7 @@ import onDomReady from "../dom-utilities/onDomReady.js";
|
|
|
3
3
|
import toast from "./toast.js";
|
|
4
4
|
import copyToClipboard from "../string-utilities/copy-to-clipboard.js";
|
|
5
5
|
|
|
6
|
-
const CLOSE_BUTTON_SVG = `<svg
|
|
6
|
+
const CLOSE_BUTTON_SVG = `<svg viewBox="0 0 134 134" fill="none" xmlns="http://www.w3.org/2000/svg"><path class="micromodal__close-bg" d="M132 132.5 1 1.5h131v131Z" /><path class="micromodal__close-x" fill-rule="evenodd" clip-rule="evenodd" d="M0 0h3v1.5h1.5V3H6v1.5h1.5V6H9v1.5h1.5V9H12v1.5h1.5V12H15v1.5h1.5V15H18v1.5h1.5V18H21v1.5h1.5V21H24v1.5h1.5V24H27v1.5h1.5V27H30v1.5h1.5V30H33v1.5h1.5V33H36v1.5h1.5V36H39v1.5h1.5V39H42v1.5h1.5V42H45v1.5h1.5V45H48v1.5h1.5V48H51v1.5h1.5V51H54v1.5h1.5V54H57v1.5h1.5V57H60v1.5h1.5V60H63v1.5h1.5V63H66v1.5h1.5V66H69v1.5h1.5V69H72v1.5h1.5V72H75v1.5h1.5V75H78v1.5h1.5V78H81v1.5h1.5V81H84v1.5h1.5V84H87v1.5h1.5V87H90v1.5h1.5V90H93v1.5h1.5V93H96v1.5h1.5V96H99v1.5h1.5V99h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v1.5h1.5v3h-3V132H129v-1.5h-1.5V129H126v-1.5h-1.5V126H123v-1.5h-1.5V123H120v-1.5h-1.5V120H117v-1.5h-1.5V117H114v-1.5h-1.5V114H111v-1.5h-1.5V111H108v-1.5h-1.5V108H105v-1.5h-1.5V105H102v-1.5h-1.5V102H99v-1.5h-1.5V99H96v-1.5h-1.5V96H93v-1.5h-1.5V93H90v-1.5h-1.5V90H87v-1.5h-1.5V87H84v-1.5h-1.5V84H81v-1.5h-1.5V81H78v-1.5h-1.5V78H75v-1.5h-1.5V75H72v-1.5h-1.5V72H69v-1.5h-1.5V69H66v-1.5h-1.5V66H63v-1.5h-1.5V63H60v-1.5h-1.5V60H57v-1.5h-1.5V57H54v-1.5h-1.5V54H51v-1.5h-1.5V51H48v-1.5h-1.5V48H45v-1.5h-1.5V45H42v-1.5h-1.5V42H39v-1.5h-1.5V39H36v-1.5h-1.5V36H33v-1.5h-1.5V33H30v-1.5h-1.5V30H27v-1.5h-1.5V27H24v-1.5h-1.5V24H21v-1.5h-1.5V21H18v-1.5h-1.5V18H15v-1.5h-1.5V15H12v-1.5h-1.5V12H9v-1.5H7.5V9H6V7.5H4.5V6H3V4.5H1.5V3H0V0ZM108.8 22h5.2v5.1h-2.6v2.6H109v2.6h-2.6v2.6h-2.6v2.5h-2.6v5.2h2.6V45h2.6v2.6h2.6v2.6h2.5v2.6h2.6V58h-5.1v-2.6h-2.6V53h-2.6v-2.6h-2.6v-2.6h-2.5v-2.6h-5.2v2.6H91v2.6h-2.6v2.6h-2.6v2.5h-2.6V58H78v-5.1h2.6v-2.6H83v-2.6h2.6v-2.6h2.6v-2.5h2.6v-5.2h-2.6V35h-2.6v-2.6h-2.6v-2.6h-2.5v-2.6H78V22h5.2v2.6h2.5V27h2.6v2.6h2.6v2.6h2.5v2.6h5.2v-2.6h2.5v-2.6h2.6v-2.6h2.6v-2.5h2.5V22Z" /></svg>`;
|
|
7
7
|
const CONFIRM_BUTTON_SVG = `<div style="width: 28px;"><svg viewBox="0 0 60 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M34.5 0.75H43.5V5.25H49V9.75H54.5V14.25H60V18.75H54.5V23.25H49V27.75H43.5V32.25H34.5V27.75H40V23.25H45.5V18.75H0V14.25H45.5V9.75H40V5.25H34.5V0.75Z" fill="white"/></svg></div>`;
|
|
8
8
|
|
|
9
9
|
function createModal(promptText, yesCallback, extraContent = "", includeInput = false, defaultValue = "") {
|
|
@@ -70,11 +70,11 @@ export function consent(promptText, yesCallback, extraContent = "") {
|
|
|
70
70
|
*/
|
|
71
71
|
export function tell(promptText, ...content) {
|
|
72
72
|
const contentHtml = content.length > 0
|
|
73
|
-
? content.map(c => `<div class="
|
|
73
|
+
? content.map(c => `<div class="micromodal__tell-content">${c}</div>`).join("")
|
|
74
74
|
: "";
|
|
75
75
|
|
|
76
|
-
themodal.html = `<div class="
|
|
77
|
-
<div class="
|
|
76
|
+
themodal.html = `<div class="micromodal__tell">
|
|
77
|
+
<div class="micromodal__tell-title">${promptText}</div>
|
|
78
78
|
${contentHtml}
|
|
79
79
|
</div>`;
|
|
80
80
|
themodal.closeHtml = CLOSE_BUTTON_SVG;
|
|
@@ -98,27 +98,22 @@ export function tell(promptText, ...content) {
|
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
100
|
* Display a modal with a code snippet and copy functionality
|
|
101
|
-
*
|
|
101
|
+
* @param {string} title - The modal heading
|
|
102
|
+
* @param {string} content - The code to display
|
|
103
|
+
* @param {string} extraContent - Optional warning/info text below the copy button
|
|
102
104
|
*/
|
|
103
|
-
export function snippet(title, content,
|
|
104
|
-
const {
|
|
105
|
-
extraContent = 'Save this, it won\'t be shown again. Expires in 1 year.'
|
|
106
|
-
} = options;
|
|
105
|
+
export function snippet(title, content, extraContent = '') {
|
|
107
106
|
|
|
108
107
|
// Create the modal content with copy button
|
|
109
108
|
const modalContent = `
|
|
110
|
-
<div class="
|
|
111
|
-
<
|
|
112
|
-
<pre class="text-white font-mono text-sm whitespace-nowrap">${content}</pre>
|
|
113
|
-
</div>
|
|
109
|
+
<div class="snippet-code-block">
|
|
110
|
+
<pre>${content}</pre>
|
|
114
111
|
</div>
|
|
115
112
|
|
|
116
|
-
<button type="button" class="
|
|
117
|
-
<span class="whitespace-nowrap select-none inline-block group-active:translate-x-[1.5px] group-active:translate-y-[1.5px]">copy</span>
|
|
118
|
-
</button>
|
|
113
|
+
<button type="button" class="micromodal__secondary-btn copy-snippet-btn" style="margin-bottom: 14px;">copy</button>
|
|
119
114
|
|
|
120
115
|
${extraContent ? `
|
|
121
|
-
<div class="
|
|
116
|
+
<div class="snippet-warning">
|
|
122
117
|
${extraContent}
|
|
123
118
|
</div>
|
|
124
119
|
` : ''}
|
|
@@ -131,7 +126,7 @@ export function snippet(title, content, options = {}) {
|
|
|
131
126
|
</div>`;
|
|
132
127
|
|
|
133
128
|
themodal.closeHtml = CLOSE_BUTTON_SVG;
|
|
134
|
-
themodal.yes =
|
|
129
|
+
themodal.yes = '';
|
|
135
130
|
|
|
136
131
|
const promise = new Promise((resolve) => {
|
|
137
132
|
// Local copy function
|
|
@@ -429,6 +429,7 @@ const modalCss = `<style class="micromodal-css">
|
|
|
429
429
|
align-items: center;
|
|
430
430
|
width: 100%;
|
|
431
431
|
height: 39px;
|
|
432
|
+
line-height: 0;
|
|
432
433
|
border: 3px solid;
|
|
433
434
|
border-top-color: #94BA6F;
|
|
434
435
|
border-left-color: #94BA6F;
|
|
@@ -449,6 +450,66 @@ const modalCss = `<style class="micromodal-css">
|
|
|
449
450
|
border-right-color: #94BA6F;
|
|
450
451
|
}
|
|
451
452
|
|
|
453
|
+
.micromodal button.micromodal__secondary-btn {
|
|
454
|
+
display: flex;
|
|
455
|
+
justify-content: center;
|
|
456
|
+
align-items: center;
|
|
457
|
+
width: 100%;
|
|
458
|
+
height: 39px;
|
|
459
|
+
line-height: 0;
|
|
460
|
+
border: 3px solid;
|
|
461
|
+
border-top-color: #474C65;
|
|
462
|
+
border-left-color: #474C65;
|
|
463
|
+
border-bottom-color: #131725;
|
|
464
|
+
border-right-color: #131725;
|
|
465
|
+
background-color: #1D1F2F;
|
|
466
|
+
color: #E5E7EB;
|
|
467
|
+
font-family: inherit;
|
|
468
|
+
font-size: 16px;
|
|
469
|
+
font-weight: bold;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.micromodal button.micromodal__secondary-btn:focus,
|
|
473
|
+
.micromodal button.micromodal__secondary-btn:hover {
|
|
474
|
+
background-color: #232639;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.micromodal button.micromodal__secondary-btn:active {
|
|
478
|
+
border-top-color: #131725;
|
|
479
|
+
border-left-color: #131725;
|
|
480
|
+
border-bottom-color: #474C65;
|
|
481
|
+
border-right-color: #474C65;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
.micromodal:has(.snippet-code-block) .micromodal__content {
|
|
485
|
+
margin-bottom: 0;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.micromodal .snippet-code-block {
|
|
489
|
+
background-color: #292E54;
|
|
490
|
+
padding: 1rem;
|
|
491
|
+
margin-bottom: 14px;
|
|
492
|
+
max-width: 420px;
|
|
493
|
+
overflow-x: auto;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.micromodal .snippet-code-block pre {
|
|
497
|
+
color: white;
|
|
498
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
499
|
+
font-size: 0.875rem;
|
|
500
|
+
white-space: nowrap;
|
|
501
|
+
margin: 0;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.micromodal .snippet-warning {
|
|
505
|
+
padding: 0.75rem;
|
|
506
|
+
border: 2px solid #989742;
|
|
507
|
+
background-color: #1E1E11;
|
|
508
|
+
font-size: 0.875rem;
|
|
509
|
+
color: #FBF7B7;
|
|
510
|
+
max-width: 420px;
|
|
511
|
+
}
|
|
512
|
+
|
|
452
513
|
.micromodal button.micromodal__close {
|
|
453
514
|
clip-path: polygon(0% 4%, 0% 0%, 100% 0%, 100% 100%, 94% 100%);
|
|
454
515
|
position: absolute;
|
|
@@ -456,6 +517,46 @@ const modalCss = `<style class="micromodal-css">
|
|
|
456
517
|
right: -1px;
|
|
457
518
|
width: 68px;
|
|
458
519
|
}
|
|
520
|
+
|
|
521
|
+
.micromodal .micromodal__close-bg {
|
|
522
|
+
fill: #1D2032;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.micromodal .micromodal__close:hover .micromodal__close-bg {
|
|
526
|
+
fill: #212543;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.micromodal .micromodal__close-x {
|
|
530
|
+
fill: #fff;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.micromodal .micromodal__tell {
|
|
534
|
+
max-width: 440px;
|
|
535
|
+
margin-bottom: 28px;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.micromodal .micromodal__tell > * + * {
|
|
539
|
+
margin-top: 20px;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
.micromodal .micromodal__tell-title {
|
|
543
|
+
font-size: 20px;
|
|
544
|
+
font-weight: bold;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
.micromodal .micromodal__tell-content {
|
|
548
|
+
font-size: 16px;
|
|
549
|
+
font-weight: normal;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
@media (min-width: 640px) {
|
|
553
|
+
.micromodal .micromodal__tell-title {
|
|
554
|
+
font-size: 22px;
|
|
555
|
+
}
|
|
556
|
+
.micromodal .micromodal__tell-content {
|
|
557
|
+
font-size: 18px;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
459
560
|
</style>`;
|
|
460
561
|
|
|
461
562
|
const modalHtml = `<div class="micromodal" id="micromodal" aria-hidden="true">
|
package/{ui → src/ui}/toast.js
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// a nice, simple alert
|
|
2
2
|
// ❗️ don't use too much text!
|
|
3
3
|
|
|
4
|
-
// Default modern icons
|
|
4
|
+
// Default modern icons (normalized to 48x48 viewBox)
|
|
5
5
|
const defaultIcons = {
|
|
6
|
-
success: `<svg viewBox="0 0 48
|
|
7
|
-
error: `<svg viewBox="0 0
|
|
6
|
+
success: `<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M13.9404 23.9475L21.9099 31.224L35.1906 15.9045M3 4.5H44.9804V44.309H3V4.5Z" stroke="#33D131" stroke-width="4.3"/></svg>`,
|
|
7
|
+
error: `<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M32.7383 14.4045L14 33.1429M32.7451 33.1429L14.0068 14.4046M3.01 4H44.99V43.809H3.01V4Z" stroke="#FF4450" stroke-width="4"/></svg>`
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
// Hyperclay icons
|
|
@@ -100,6 +100,7 @@ const modernStyles = `
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
[data-toast-theme="modern"] .toast-icon svg {
|
|
103
|
+
display: block;
|
|
103
104
|
width: 22px;
|
|
104
105
|
height: 22px;
|
|
105
106
|
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { isEditMode, isOwner } from "./isAdminOfCurrentResource.js";
|
|
2
|
-
import onDomReady from "../dom-utilities/onDomReady.js";
|
|
3
|
-
import {beforeSave} from "./savePage.js";
|
|
4
|
-
|
|
5
|
-
export function disableContentEditableBeforeSave () {
|
|
6
|
-
beforeSave(docElem => {
|
|
7
|
-
docElem.querySelectorAll('[edit-mode-contenteditable]').forEach(resource => {
|
|
8
|
-
const originalValue = resource.getAttribute("contenteditable");
|
|
9
|
-
resource.setAttribute("inert-contenteditable", originalValue);
|
|
10
|
-
resource.removeAttribute("contenteditable");
|
|
11
|
-
});
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function enableContentEditableForAdminOnPageLoad () {
|
|
16
|
-
if (!isEditMode) return;
|
|
17
|
-
|
|
18
|
-
onDomReady(() => {
|
|
19
|
-
document.querySelectorAll('[edit-mode-contenteditable]').forEach(resource => {
|
|
20
|
-
let originalValue = resource.getAttribute("inert-contenteditable");
|
|
21
|
-
|
|
22
|
-
if (!["false", "plaintext-only"].includes(originalValue)) {
|
|
23
|
-
originalValue = "true";
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
resource.setAttribute("contenteditable", originalValue);
|
|
27
|
-
resource.removeAttribute("inert-contenteditable");
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Auto-initialize
|
|
33
|
-
export function init() {
|
|
34
|
-
disableContentEditableBeforeSave();
|
|
35
|
-
enableContentEditableForAdminOnPageLoad();
|
|
36
|
-
}
|
package/core/adminOnClick.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { isEditMode, isOwner } from "./isAdminOfCurrentResource.js";
|
|
2
|
-
import onDomReady from "../dom-utilities/onDomReady.js";
|
|
3
|
-
import {beforeSave} from "./savePage.js";
|
|
4
|
-
|
|
5
|
-
export function disableOnClickBeforeSave () {
|
|
6
|
-
beforeSave(docElem => {
|
|
7
|
-
docElem.querySelectorAll('[edit-mode-onclick]').forEach(resource => {
|
|
8
|
-
const originalValue = resource.getAttribute("onclick");
|
|
9
|
-
resource.setAttribute("inert-onclick", originalValue);
|
|
10
|
-
resource.removeAttribute("onclick");
|
|
11
|
-
});
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function enableOnClickForAdminOnPageLoad () {
|
|
16
|
-
if (!isEditMode) return;
|
|
17
|
-
|
|
18
|
-
onDomReady(() => {
|
|
19
|
-
document.querySelectorAll('[edit-mode-onclick]').forEach(resource => {
|
|
20
|
-
const originalValue = resource.getAttribute("inert-onclick");
|
|
21
|
-
resource.setAttribute("onclick", originalValue);
|
|
22
|
-
resource.removeAttribute("inert-onclick");
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Auto-initialize
|
|
28
|
-
export function init() {
|
|
29
|
-
disableOnClickBeforeSave();
|
|
30
|
-
enableOnClickForAdminOnPageLoad();
|
|
31
|
-
}
|