hyperclayjs 1.3.1 → 1.4.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 +77 -45
- package/communication/behaviorCollector.js +7 -4
- package/communication/sendMessage.js +7 -4
- package/communication/uploadFile.js +8 -5
- package/core/autosave.js +5 -47
- package/core/editmodeSystem.js +8 -5
- package/core/enablePersistentFormInputValues.js +7 -4
- package/core/exportToWindow.js +14 -0
- package/core/optionVisibilityRuleGenerator.js +8 -5
- package/core/savePage.js +47 -14
- package/core/savePageCore.js +10 -7
- package/custom-attributes/domHelpers.js +7 -4
- package/custom-attributes/sortable.js +23 -16
- package/dom-utilities/All.js +9 -6
- package/dom-utilities/getDataFromForm.js +8 -5
- package/dom-utilities/insertStyleTag.js +8 -5
- package/dom-utilities/onDomReady.js +7 -4
- package/dom-utilities/onLoad.js +7 -4
- package/hyperclay.js +90 -31
- package/module-dependency-graph.json +103 -135
- package/package.json +1 -1
- package/string-utilities/copy-to-clipboard.js +7 -4
- package/string-utilities/query.js +8 -5
- package/string-utilities/slugify.js +8 -5
- package/ui/prompts.js +49 -31
- package/ui/theModal.js +50 -6
- package/ui/toast-hyperclay.js +27 -11
- package/ui/toast.js +82 -92
- package/utilities/cookie.js +8 -5
- package/utilities/debounce.js +7 -4
- package/utilities/loadVendorScript.js +57 -0
- package/utilities/mutation.js +9 -6
- package/utilities/nearest.js +7 -4
- package/utilities/throttle.js +7 -4
- package/vendor/Sortable.vendor.js +2 -0
- package/vendor/idiomorph.min.js +8 -5
- package/vendor/tailwind-play.js +16 -162
- package/vendor/tailwind-play.vendor.js +169 -0
- package/string-utilities/emmet-html.js +0 -60
- package/ui/info.js +0 -47
- package/vendor/Sortable.js +0 -3351
package/ui/prompts.js
CHANGED
|
@@ -2,13 +2,12 @@ import themodal from "./theModal.js";
|
|
|
2
2
|
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
|
-
import { info } from "./info.js";
|
|
6
5
|
|
|
7
6
|
const CLOSE_BUTTON_SVG = `<svg class="group" viewBox="0 0 134 134" fill="none" xmlns="http://www.w3.org/2000/svg"><path class="fill-[#1D2032] group-hover:fill-[#212543]" d="M132 132.5 1 1.5h131v131Z" /><path 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" fill="#fff"/></svg>`;
|
|
8
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>`;
|
|
9
8
|
|
|
10
9
|
function createModal(promptText, yesCallback, extraContent = "", includeInput = false, defaultValue = "") {
|
|
11
|
-
const inputHtml = includeInput
|
|
10
|
+
const inputHtml = includeInput
|
|
12
11
|
? `<div><input class="micromodal__input" type="text" value="${defaultValue}" required></div>`
|
|
13
12
|
: "";
|
|
14
13
|
|
|
@@ -43,14 +42,14 @@ function createModal(promptText, yesCallback, extraContent = "", includeInput =
|
|
|
43
42
|
return false; // Prevent modal from closing
|
|
44
43
|
}
|
|
45
44
|
});
|
|
46
|
-
|
|
45
|
+
|
|
47
46
|
themodal.onNo = () => {
|
|
48
47
|
reject();
|
|
49
48
|
};
|
|
50
49
|
});
|
|
51
50
|
|
|
52
51
|
themodal.open();
|
|
53
|
-
|
|
52
|
+
|
|
54
53
|
return promise;
|
|
55
54
|
}
|
|
56
55
|
|
|
@@ -63,8 +62,38 @@ export function consent(promptText, yesCallback, extraContent = "") {
|
|
|
63
62
|
return createModal(promptText, yesCallback, extraContent, false);
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Display an informational modal with a title and optional content paragraphs
|
|
67
|
+
* @param {string} promptText - The title/heading text
|
|
68
|
+
* @param {...string} content - Additional content paragraphs (variadic)
|
|
69
|
+
* @returns {Promise} Resolves when user confirms, rejects on close
|
|
70
|
+
*/
|
|
71
|
+
export function tell(promptText, ...content) {
|
|
72
|
+
const contentHtml = content.length > 0
|
|
73
|
+
? content.map(c => `<div class="text-[16px] sm:text-[18px] font-normal">${c}</div>`).join("")
|
|
74
|
+
: "";
|
|
75
|
+
|
|
76
|
+
themodal.html = `<div class="max-w-[440px] space-y-5 mb-7">
|
|
77
|
+
<div class="text-[20px] sm:text-[22px] font-bold">${promptText}</div>
|
|
78
|
+
${contentHtml}
|
|
79
|
+
</div>`;
|
|
80
|
+
themodal.closeHtml = CLOSE_BUTTON_SVG;
|
|
81
|
+
themodal.yes = CONFIRM_BUTTON_SVG;
|
|
82
|
+
|
|
83
|
+
const promise = new Promise((resolve, reject) => {
|
|
84
|
+
themodal.onYes(() => {
|
|
85
|
+
resolve();
|
|
86
|
+
return true;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
themodal.onNo = () => {
|
|
90
|
+
reject();
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
themodal.open();
|
|
95
|
+
|
|
96
|
+
return promise;
|
|
68
97
|
}
|
|
69
98
|
|
|
70
99
|
/**
|
|
@@ -146,15 +175,6 @@ export function snippet(title, content, options = {}) {
|
|
|
146
175
|
return promise;
|
|
147
176
|
}
|
|
148
177
|
|
|
149
|
-
/**
|
|
150
|
-
* Show API key with standard warning
|
|
151
|
-
*/
|
|
152
|
-
export function showApiKey(apiKey, username, expiresAt) {
|
|
153
|
-
return snippet('Sync API Key', apiKey, {
|
|
154
|
-
extraContent: `This key won't be shown again. Save it. Expires in 1 year.`
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
|
|
158
178
|
// Auto-initialize - cleanup any leftover modal elements
|
|
159
179
|
export function init() {
|
|
160
180
|
onDomReady(() => {
|
|
@@ -166,21 +186,19 @@ export function init() {
|
|
|
166
186
|
});
|
|
167
187
|
}
|
|
168
188
|
|
|
169
|
-
//
|
|
170
|
-
window.
|
|
171
|
-
window.
|
|
172
|
-
window.
|
|
173
|
-
window.
|
|
174
|
-
window.
|
|
175
|
-
window.hyperclay
|
|
176
|
-
window.hyperclay.
|
|
177
|
-
window.hyperclay.
|
|
178
|
-
window.hyperclay.
|
|
179
|
-
window.hyperclay.snippet = snippet;
|
|
180
|
-
window.
|
|
181
|
-
|
|
182
|
-
// Re-export info
|
|
183
|
-
export { info };
|
|
189
|
+
// Auto-export to window unless suppressed by loader
|
|
190
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
191
|
+
window.ask = ask;
|
|
192
|
+
window.consent = consent;
|
|
193
|
+
window.tell = tell;
|
|
194
|
+
window.snippet = snippet;
|
|
195
|
+
window.hyperclay = window.hyperclay || {};
|
|
196
|
+
window.hyperclay.ask = ask;
|
|
197
|
+
window.hyperclay.consent = consent;
|
|
198
|
+
window.hyperclay.tell = tell;
|
|
199
|
+
window.hyperclay.snippet = snippet;
|
|
200
|
+
window.h = window.hyperclay;
|
|
201
|
+
}
|
|
184
202
|
|
|
185
203
|
// Auto-init when module is imported
|
|
186
|
-
init();
|
|
204
|
+
init();
|
package/ui/theModal.js
CHANGED
|
@@ -318,6 +318,8 @@ const modalCss = `<style class="micromodal-css">
|
|
|
318
318
|
.micromodal {
|
|
319
319
|
display: none;
|
|
320
320
|
color: #fff;
|
|
321
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
322
|
+
font-size: 18px;
|
|
321
323
|
}
|
|
322
324
|
|
|
323
325
|
.micromodal button:not(.custom-button) {
|
|
@@ -413,7 +415,7 @@ const modalCss = `<style class="micromodal-css">
|
|
|
413
415
|
.micromodal .micromodal__input {
|
|
414
416
|
width: clamp(300px, calc(100vw - 100px), 420px);
|
|
415
417
|
padding: 6px 6px 7px;
|
|
416
|
-
font-size:
|
|
418
|
+
font-size: 16px;
|
|
417
419
|
color: #000;
|
|
418
420
|
}
|
|
419
421
|
|
|
@@ -469,12 +471,19 @@ const modalHtml = `<div class="micromodal" id="micromodal" aria-hidden="true">
|
|
|
469
471
|
</div>
|
|
470
472
|
</div>`;
|
|
471
473
|
|
|
474
|
+
const DEFAULT_FONT_FAMILY = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace";
|
|
475
|
+
const DEFAULT_FONT_SIZE = "18px";
|
|
476
|
+
const DEFAULT_INPUT_FONT_SIZE = "16px";
|
|
477
|
+
|
|
472
478
|
const themodal = (() => {
|
|
473
479
|
let html = "";
|
|
474
480
|
let yes = "";
|
|
475
481
|
let no = "";
|
|
476
482
|
let zIndex = "100";
|
|
477
483
|
let closeHtml = "";
|
|
484
|
+
let fontFamily = DEFAULT_FONT_FAMILY;
|
|
485
|
+
let fontSize = DEFAULT_FONT_SIZE;
|
|
486
|
+
let inputFontSize = DEFAULT_INPUT_FONT_SIZE;
|
|
478
487
|
|
|
479
488
|
let enableClickOutsideCloses = true;
|
|
480
489
|
let disableScroll = true;
|
|
@@ -502,6 +511,17 @@ const themodal = (() => {
|
|
|
502
511
|
modalOverlayElem.style.zIndex = zIndex;
|
|
503
512
|
modalCloseElem.innerHTML = closeHtml;
|
|
504
513
|
|
|
514
|
+
// Apply font styles to the modal
|
|
515
|
+
const modalElem = document.querySelector("#micromodal");
|
|
516
|
+
modalElem.style.fontFamily = fontFamily;
|
|
517
|
+
modalElem.style.fontSize = fontSize;
|
|
518
|
+
|
|
519
|
+
// Apply input font size
|
|
520
|
+
const modalInputElem = document.querySelector(".micromodal__input");
|
|
521
|
+
if (modalInputElem) {
|
|
522
|
+
modalInputElem.style.fontSize = inputFontSize;
|
|
523
|
+
}
|
|
524
|
+
|
|
505
525
|
// MODIFIED so modal doesn't close if mousedown happened inside the modal
|
|
506
526
|
let mousedownOnBackdrop = false;
|
|
507
527
|
|
|
@@ -581,6 +601,9 @@ const themodal = (() => {
|
|
|
581
601
|
no = "";
|
|
582
602
|
zIndex = "100";
|
|
583
603
|
closeHtml = "";
|
|
604
|
+
fontFamily = DEFAULT_FONT_FAMILY;
|
|
605
|
+
fontSize = DEFAULT_FONT_SIZE;
|
|
606
|
+
inputFontSize = DEFAULT_INPUT_FONT_SIZE;
|
|
584
607
|
|
|
585
608
|
// reset to defaults
|
|
586
609
|
enableClickOutsideCloses = true;
|
|
@@ -642,6 +665,24 @@ const themodal = (() => {
|
|
|
642
665
|
set zIndex(newVal) {
|
|
643
666
|
zIndex = newVal;
|
|
644
667
|
},
|
|
668
|
+
get fontFamily() {
|
|
669
|
+
return fontFamily;
|
|
670
|
+
},
|
|
671
|
+
set fontFamily(newVal) {
|
|
672
|
+
fontFamily = newVal;
|
|
673
|
+
},
|
|
674
|
+
get fontSize() {
|
|
675
|
+
return fontSize;
|
|
676
|
+
},
|
|
677
|
+
set fontSize(newVal) {
|
|
678
|
+
fontSize = newVal;
|
|
679
|
+
},
|
|
680
|
+
get inputFontSize() {
|
|
681
|
+
return inputFontSize;
|
|
682
|
+
},
|
|
683
|
+
set inputFontSize(newVal) {
|
|
684
|
+
inputFontSize = newVal;
|
|
685
|
+
},
|
|
645
686
|
get disableFocus() {
|
|
646
687
|
return disableFocus;
|
|
647
688
|
},
|
|
@@ -669,9 +710,12 @@ const themodal = (() => {
|
|
|
669
710
|
return themodalMain;
|
|
670
711
|
})();
|
|
671
712
|
|
|
672
|
-
//
|
|
673
|
-
window.
|
|
674
|
-
window.
|
|
675
|
-
window.hyperclay
|
|
713
|
+
// Auto-export to window unless suppressed by loader
|
|
714
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
715
|
+
window.themodal = themodal;
|
|
716
|
+
window.hyperclay = window.hyperclay || {};
|
|
717
|
+
window.hyperclay.themodal = themodal;
|
|
718
|
+
window.h = window.hyperclay;
|
|
719
|
+
}
|
|
676
720
|
|
|
677
|
-
export default themodal;
|
|
721
|
+
export default themodal;
|
package/ui/toast-hyperclay.js
CHANGED
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Toast Hyperclay -
|
|
2
|
+
* Toast Hyperclay - Toast with Hyperclay platform styling
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Provides toastHyperclay() function with Hyperclay platform styling.
|
|
5
|
+
* Use this alongside toast() if you need both styles in the same project.
|
|
6
6
|
*
|
|
7
7
|
* This is a hidden feature not exposed in the UI - used internally by
|
|
8
8
|
* the Hyperclay platform for backward compatibility.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import
|
|
11
|
+
import {
|
|
12
|
+
toastCore,
|
|
13
|
+
injectToastStyles,
|
|
14
|
+
hyperclayStyles,
|
|
15
|
+
hyperclayTemplates,
|
|
16
|
+
hyperclayIcons
|
|
17
|
+
} from './toast.js';
|
|
12
18
|
|
|
13
|
-
//
|
|
14
|
-
|
|
19
|
+
// Toast function with Hyperclay styling
|
|
20
|
+
function toastHyperclay(message, messageType = "success") {
|
|
21
|
+
injectToastStyles(hyperclayStyles, 'hyperclay');
|
|
22
|
+
toastCore(message, messageType, {
|
|
23
|
+
templates: hyperclayTemplates,
|
|
24
|
+
icons: hyperclayIcons,
|
|
25
|
+
theme: 'hyperclay'
|
|
26
|
+
});
|
|
27
|
+
}
|
|
15
28
|
|
|
16
|
-
//
|
|
17
|
-
window.
|
|
18
|
-
window.
|
|
19
|
-
window.hyperclay
|
|
29
|
+
// Auto-export to window unless suppressed by loader
|
|
30
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
31
|
+
window.toastHyperclay = toastHyperclay;
|
|
32
|
+
window.hyperclay = window.hyperclay || {};
|
|
33
|
+
window.hyperclay.toastHyperclay = toastHyperclay;
|
|
34
|
+
window.h = window.hyperclay;
|
|
35
|
+
}
|
|
20
36
|
|
|
21
|
-
export default
|
|
37
|
+
export default toastHyperclay;
|
package/ui/toast.js
CHANGED
|
@@ -7,24 +7,23 @@ const defaultIcons = {
|
|
|
7
7
|
error: `<svg viewBox="0 0 46 44" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M31.7383 12.4045L13 31.1429M31.7451 31.1429L13.0068 12.4046M2.00977 2H43.9902V41.809H2.00977V2Z" stroke="#FF4450" stroke-width="4"/></svg>`
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
//
|
|
11
|
-
const
|
|
10
|
+
// Hyperclay icons
|
|
11
|
+
export const hyperclayIcons = {
|
|
12
12
|
success: `<svg viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M32 1h-5v3.5h-2.5V8h-2v3.5H20V15h-2.5v3.5h-2V22H13v3.5H9V22H7v-3.5H6V15H1v3.5h1V22h2v3.5h1.5V29H7v3.5h5V29h3.5v-3.5H18V22h2.5v-3.5h2V15H25v-3.5h2.5V8h2V4.5H32V1Z" fill="#76C824"/></svg>`,
|
|
13
13
|
error: `<svg viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M33 1h-5v3.5h-3.5V8H21v3.5h-3.5V15h-2v-3.5H12V8H8.5V4.5H5V1H0v3.5h3.5V8H7v3.5h3.5V15H14v3.5h-3.5V22H7v3.5H3.5V29H0v3.5h5V29h3.5v-3.5H12V22h3.5v-3.5h2V22H21v3.5h3.5V29H28v3.5h5V29h-3.5v-3.5H26V22h-3.5v-3.5H19V15h3.5v-3.5H26V8h3.5V4.5H33V1Z" fill="#DD304F"/></svg>`
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
// Default templates
|
|
17
17
|
const defaultTemplates = {
|
|
18
|
-
container: `<div class="toast-container" save-ignore></div>`,
|
|
19
18
|
toast: {
|
|
20
19
|
success: `
|
|
21
|
-
<div class="toast
|
|
20
|
+
<div class="toast hide success noise-texture">
|
|
22
21
|
<div class="toast-icon">{icon}</div>
|
|
23
22
|
<div class="toast-message">{message}</div>
|
|
24
23
|
</div>
|
|
25
24
|
`,
|
|
26
25
|
error: `
|
|
27
|
-
<div class="toast
|
|
26
|
+
<div class="toast hide error noise-texture">
|
|
28
27
|
<div class="toast-icon">{icon}</div>
|
|
29
28
|
<div class="toast-message">{message}</div>
|
|
30
29
|
</div>
|
|
@@ -32,9 +31,8 @@ const defaultTemplates = {
|
|
|
32
31
|
}
|
|
33
32
|
};
|
|
34
33
|
|
|
35
|
-
//
|
|
36
|
-
const
|
|
37
|
-
container: `<div class="toast-container" save-ignore></div>`,
|
|
34
|
+
// Hyperclay templates
|
|
35
|
+
export const hyperclayTemplates = {
|
|
38
36
|
toast: {
|
|
39
37
|
success: `
|
|
40
38
|
<div class="toast hide success">
|
|
@@ -51,9 +49,9 @@ const legacyTemplates = {
|
|
|
51
49
|
}
|
|
52
50
|
};
|
|
53
51
|
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
.toast-container {
|
|
52
|
+
// Modern styles (scoped by data-toast-theme="modern")
|
|
53
|
+
const modernStyles = `
|
|
54
|
+
[data-toast-theme="modern"].toast-container {
|
|
57
55
|
z-index: 9999;
|
|
58
56
|
position: fixed;
|
|
59
57
|
top: 20px;
|
|
@@ -63,20 +61,12 @@ const defaultStyles = `
|
|
|
63
61
|
align-items: end;
|
|
64
62
|
gap: 18px;
|
|
65
63
|
}
|
|
66
|
-
|
|
67
|
-
.toast {
|
|
64
|
+
|
|
65
|
+
[data-toast-theme="modern"] .toast {
|
|
68
66
|
position: relative;
|
|
69
67
|
right: 0;
|
|
70
68
|
cursor: pointer;
|
|
71
69
|
transition: right 0.5s ease-in-out, opacity 0.5s ease-in-out;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
.toast.hide {
|
|
75
|
-
right: -400px;
|
|
76
|
-
opacity: 0;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
.toast-modern {
|
|
80
70
|
display: flex;
|
|
81
71
|
align-items: center;
|
|
82
72
|
gap: 12px;
|
|
@@ -88,37 +78,42 @@ const defaultStyles = `
|
|
|
88
78
|
border-width: 1px;
|
|
89
79
|
border-style: solid;
|
|
90
80
|
}
|
|
91
|
-
|
|
92
|
-
|
|
81
|
+
|
|
82
|
+
[data-toast-theme="modern"] .toast.hide {
|
|
83
|
+
right: -400px;
|
|
84
|
+
opacity: 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[data-toast-theme="modern"] .toast.success {
|
|
93
88
|
border-color: #358234;
|
|
94
89
|
background: radial-gradient(85.86% 68.42% at 50% 68.42%, #142419 0%, #1D3927 100%);
|
|
95
90
|
}
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
|
|
92
|
+
[data-toast-theme="modern"] .toast.error {
|
|
98
93
|
border-color: #992930;
|
|
99
94
|
background: radial-gradient(85.86% 68.42% at 50% 68.42%, #240A13 0%, #481826 100%);
|
|
100
95
|
}
|
|
101
|
-
|
|
102
|
-
.toast-icon {
|
|
96
|
+
|
|
97
|
+
[data-toast-theme="modern"] .toast-icon {
|
|
103
98
|
position: relative;
|
|
104
99
|
top: -1px;
|
|
105
100
|
}
|
|
106
|
-
|
|
107
|
-
.toast-icon svg {
|
|
101
|
+
|
|
102
|
+
[data-toast-theme="modern"] .toast-icon svg {
|
|
108
103
|
width: 22px;
|
|
109
104
|
height: 22px;
|
|
110
105
|
}
|
|
111
|
-
|
|
112
|
-
.toast-message {
|
|
106
|
+
|
|
107
|
+
[data-toast-theme="modern"] .toast-message {
|
|
113
108
|
position: relative;
|
|
114
109
|
top: -1px;
|
|
115
110
|
}
|
|
116
|
-
|
|
117
|
-
.noise-texture {
|
|
111
|
+
|
|
112
|
+
[data-toast-theme="modern"] .noise-texture {
|
|
118
113
|
position: relative;
|
|
119
114
|
}
|
|
120
|
-
|
|
121
|
-
.noise-texture::before {
|
|
115
|
+
|
|
116
|
+
[data-toast-theme="modern"] .noise-texture::before {
|
|
122
117
|
content: "";
|
|
123
118
|
position: absolute;
|
|
124
119
|
top: 0;
|
|
@@ -132,8 +127,9 @@ const defaultStyles = `
|
|
|
132
127
|
}
|
|
133
128
|
`;
|
|
134
129
|
|
|
135
|
-
|
|
136
|
-
|
|
130
|
+
// Hyperclay styles (scoped by data-toast-theme="hyperclay")
|
|
131
|
+
export const hyperclayStyles = `
|
|
132
|
+
[data-toast-theme="hyperclay"].toast-container {
|
|
137
133
|
z-index: 9999;
|
|
138
134
|
position: fixed;
|
|
139
135
|
top: 20px;
|
|
@@ -142,12 +138,12 @@ const legacyStyles = `
|
|
|
142
138
|
flex-direction: column;
|
|
143
139
|
align-items: end;
|
|
144
140
|
}
|
|
145
|
-
|
|
146
|
-
.toast-container > * + * {
|
|
141
|
+
|
|
142
|
+
[data-toast-theme="hyperclay"].toast-container > * + * {
|
|
147
143
|
margin-top: 18px;
|
|
148
144
|
}
|
|
149
|
-
|
|
150
|
-
.toast {
|
|
145
|
+
|
|
146
|
+
[data-toast-theme="hyperclay"] .toast {
|
|
151
147
|
position: relative;
|
|
152
148
|
right: 0;
|
|
153
149
|
display: flex;
|
|
@@ -159,59 +155,59 @@ const legacyStyles = `
|
|
|
159
155
|
border: 2px dashed rgba(255,255,255,.6);
|
|
160
156
|
transition: right 0.5s ease-in-out;
|
|
161
157
|
}
|
|
162
|
-
|
|
163
|
-
.toast svg {
|
|
158
|
+
|
|
159
|
+
[data-toast-theme="hyperclay"] .toast svg {
|
|
164
160
|
position: relative;
|
|
165
161
|
top: -1px;
|
|
166
162
|
width: 17px;
|
|
167
163
|
height: 17px;
|
|
168
164
|
margin-right: 13px;
|
|
169
165
|
}
|
|
170
|
-
|
|
171
|
-
.toast.hide {
|
|
166
|
+
|
|
167
|
+
[data-toast-theme="hyperclay"] .toast.hide {
|
|
172
168
|
right: -300px;
|
|
173
169
|
}
|
|
174
|
-
|
|
175
|
-
.toast.success {
|
|
170
|
+
|
|
171
|
+
[data-toast-theme="hyperclay"] .toast.success {
|
|
176
172
|
color: #76C824;
|
|
177
173
|
border: 2px dashed #589E11;
|
|
178
174
|
}
|
|
179
|
-
|
|
180
|
-
.toast.error {
|
|
175
|
+
|
|
176
|
+
[data-toast-theme="hyperclay"] .toast.error {
|
|
181
177
|
color: #DD304F;
|
|
182
178
|
border: 2px dashed #CD2140;
|
|
183
179
|
}
|
|
184
180
|
`;
|
|
185
181
|
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
182
|
+
// Track which theme styles have been injected
|
|
183
|
+
const injectedThemes = new Set();
|
|
184
|
+
|
|
185
|
+
// Helper function to inject styles for a theme (additive, not replacing)
|
|
186
|
+
export function injectToastStyles(styles, theme) {
|
|
187
|
+
if (injectedThemes.has(theme)) return;
|
|
188
|
+
|
|
193
189
|
const styleSheet = document.createElement('style');
|
|
194
|
-
styleSheet.className =
|
|
190
|
+
styleSheet.className = `toast-styles-${theme}`;
|
|
195
191
|
styleSheet.setAttribute('save-ignore', '');
|
|
196
192
|
styleSheet.textContent = styles;
|
|
197
193
|
document.head.appendChild(styleSheet);
|
|
194
|
+
|
|
195
|
+
injectedThemes.add(theme);
|
|
198
196
|
}
|
|
199
197
|
|
|
200
|
-
//
|
|
201
|
-
function
|
|
202
|
-
messageType = messageType || "success";
|
|
203
|
-
|
|
204
|
-
// Get configuration
|
|
205
|
-
const config = toast.config || {};
|
|
198
|
+
// Core toast function (used by both toast and toastHyperclay)
|
|
199
|
+
export function toastCore(message, messageType = "success", config = {}) {
|
|
206
200
|
const templates = config.templates || defaultTemplates;
|
|
207
201
|
const icons = config.icons || defaultIcons;
|
|
202
|
+
const theme = config.theme || 'modern';
|
|
208
203
|
|
|
209
|
-
// Get or create container
|
|
210
|
-
let toastContainer = document.querySelector(
|
|
204
|
+
// Get or create container for this theme
|
|
205
|
+
let toastContainer = document.querySelector(`.toast-container[data-toast-theme="${theme}"]`);
|
|
211
206
|
if (!toastContainer) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
toastContainer
|
|
207
|
+
toastContainer = document.createElement('div');
|
|
208
|
+
toastContainer.className = 'toast-container';
|
|
209
|
+
toastContainer.setAttribute('data-toast-theme', theme);
|
|
210
|
+
toastContainer.setAttribute('save-ignore', '');
|
|
215
211
|
document.body.append(toastContainer);
|
|
216
212
|
}
|
|
217
213
|
|
|
@@ -221,7 +217,7 @@ function toast(message, messageType = "success") {
|
|
|
221
217
|
const toastHtml = template
|
|
222
218
|
.replace('{icon}', icon)
|
|
223
219
|
.replace('{message}', message);
|
|
224
|
-
|
|
220
|
+
|
|
225
221
|
const tempDiv = document.createElement('div');
|
|
226
222
|
tempDiv.innerHTML = toastHtml.trim();
|
|
227
223
|
const toastElement = tempDiv.firstElementChild;
|
|
@@ -243,28 +239,22 @@ function toast(message, messageType = "success") {
|
|
|
243
239
|
}, 6600);
|
|
244
240
|
}
|
|
245
241
|
|
|
246
|
-
//
|
|
247
|
-
toast
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
toast.config = toast.legacyConfig;
|
|
256
|
-
// Replace styles with legacy styles
|
|
257
|
-
injectStyles(legacyStyles);
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
// Initialize with default styles when script loads
|
|
261
|
-
injectStyles(defaultStyles);
|
|
242
|
+
// Main toast function - uses modern styles
|
|
243
|
+
function toast(message, messageType = "success") {
|
|
244
|
+
injectToastStyles(modernStyles, 'modern');
|
|
245
|
+
toastCore(message, messageType, {
|
|
246
|
+
templates: defaultTemplates,
|
|
247
|
+
icons: defaultIcons,
|
|
248
|
+
theme: 'modern'
|
|
249
|
+
});
|
|
250
|
+
}
|
|
262
251
|
|
|
263
|
-
//
|
|
264
|
-
window.
|
|
265
|
-
window.
|
|
266
|
-
window.hyperclay
|
|
252
|
+
// Auto-export to window unless suppressed by loader
|
|
253
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
254
|
+
window.toast = toast;
|
|
255
|
+
window.hyperclay = window.hyperclay || {};
|
|
256
|
+
window.hyperclay.toast = toast;
|
|
257
|
+
window.h = window.hyperclay;
|
|
258
|
+
}
|
|
267
259
|
|
|
268
|
-
|
|
269
|
-
// toast("Site name taken", "error");
|
|
270
|
-
export default toast;
|
|
260
|
+
export default toast;
|
package/utilities/cookie.js
CHANGED
|
@@ -34,9 +34,12 @@ const cookie = {
|
|
|
34
34
|
remove
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
//
|
|
38
|
-
window.
|
|
39
|
-
window.
|
|
40
|
-
window.hyperclay
|
|
37
|
+
// Auto-export to window unless suppressed by loader
|
|
38
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
39
|
+
window.cookie = cookie;
|
|
40
|
+
window.hyperclay = window.hyperclay || {};
|
|
41
|
+
window.hyperclay.cookie = cookie;
|
|
42
|
+
window.h = window.hyperclay;
|
|
43
|
+
}
|
|
41
44
|
|
|
42
|
-
export default cookie;
|
|
45
|
+
export default cookie;
|
package/utilities/debounce.js
CHANGED
|
@@ -11,8 +11,11 @@ function debounce(callback, delay) {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
window.hyperclay
|
|
14
|
+
// Auto-export to window unless suppressed by loader
|
|
15
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
16
|
+
window.hyperclay = window.hyperclay || {};
|
|
17
|
+
window.hyperclay.debounce = debounce;
|
|
18
|
+
window.h = window.hyperclay;
|
|
19
|
+
}
|
|
17
20
|
|
|
18
|
-
export default debounce;
|
|
21
|
+
export default debounce;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Lazy-load vendor scripts in edit mode only
|
|
3
|
+
|
|
4
|
+
Injects a <script save-ignore> tag that loads the vendor script.
|
|
5
|
+
The save-ignore attribute ensures it's stripped when the page is saved.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
import { loadVendorScript } from '../utilities/loadVendorScript.js';
|
|
9
|
+
|
|
10
|
+
// Load and get global
|
|
11
|
+
const Sortable = await loadVendorScript(url, 'Sortable');
|
|
12
|
+
|
|
13
|
+
// Just load (no return value needed)
|
|
14
|
+
loadVendorScript(url);
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Load a vendor script via script tag with save-ignore
|
|
19
|
+
* @param {string} url - URL to the vendor script
|
|
20
|
+
* @param {Object} [options] - Options
|
|
21
|
+
* @param {string} [options.globalName] - Window property to return when loaded (for classic scripts)
|
|
22
|
+
* @param {boolean} [options.module] - Set true for ES modules (type="module")
|
|
23
|
+
* @returns {Promise<any>} Resolves with window[globalName] or undefined
|
|
24
|
+
*/
|
|
25
|
+
export function loadVendorScript(url, options = {}) {
|
|
26
|
+
// Support legacy signature: loadVendorScript(url, globalName)
|
|
27
|
+
if (typeof options === 'string') {
|
|
28
|
+
options = { globalName: options };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const { globalName, module: isModule } = options;
|
|
32
|
+
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
const script = document.createElement('script');
|
|
35
|
+
script.src = url;
|
|
36
|
+
script.setAttribute('save-ignore', '');
|
|
37
|
+
if (isModule) {
|
|
38
|
+
script.type = 'module';
|
|
39
|
+
}
|
|
40
|
+
script.onload = () => resolve(globalName ? window[globalName] : undefined);
|
|
41
|
+
script.onerror = () => reject(new Error(`Failed to load vendor script: ${url}`));
|
|
42
|
+
document.head.appendChild(script);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get vendor URL relative to a module's location
|
|
48
|
+
* @param {string} importMetaUrl - import.meta.url of the calling module
|
|
49
|
+
* @param {string} vendorFile - Filename of the vendor script
|
|
50
|
+
* @returns {string} Full URL to vendor script
|
|
51
|
+
*/
|
|
52
|
+
export function getVendorUrl(importMetaUrl, vendorFile) {
|
|
53
|
+
const baseUrl = importMetaUrl.substring(0, importMetaUrl.lastIndexOf('/'));
|
|
54
|
+
return `${baseUrl}/${vendorFile}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default loadVendorScript;
|