@panphora/clayjs 1.6.1 → 1.7.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 +5 -4
- package/dist/clay.standalone.js +8452 -5819
- package/entries/clay-data.js +8 -6
- package/package.json +1 -1
- package/src/core/conflict-notice.js +2 -4
- package/src/core/page-data.js +321 -0
- package/src/core/save.js +19 -11
- package/src/lib/content-dom.js +3 -3
- package/src/loader-logic.js +2 -0
- package/src/loader.js +7 -2
- package/src/plugins/wire.js +4 -4
- package/src/sync/conflict-footprints.js +41 -0
- package/src/sync/conflict-revert.js +3 -0
- package/src/sync/conflicts.js +28 -1
- package/src/sync/live-sync.js +5 -3
- package/src/ui/bevel-controls.js +8 -2
- package/src/ui/bevel-dialog.js +2 -4
- package/src/ui/bevel.js +22 -2
- package/src/ui/dialogs.js +1 -1
- package/src/ui/skins/cms.js +1 -1
- package/src/ui/skins/quickcrop.js +1 -1
- package/src/ui/skins/richclay.js +2 -2
- package/src/ui/toast.js +7 -15
- package/src/vendor/hyper-morph.vendor.js +4 -4
- package/src/vendor/hypercms.vendor.js +12 -12
- package/src/vendor/quickcrop.vendor.js +1 -1
- package/src/vendor/richclay.vendor.js +27 -19
package/src/loader.js
CHANGED
|
@@ -50,7 +50,7 @@ export async function boot(base, params, readyResolve) {
|
|
|
50
50
|
continue;
|
|
51
51
|
}
|
|
52
52
|
loaded[path] = mod;
|
|
53
|
-
attachPluginMember(path, mod);
|
|
53
|
+
attachPluginMember(path, mod, loaded); // immediately, not after the loop: hypercms's ?cms=true
|
|
54
54
|
// auto-open runs as a microtask queued during ITS evaluation
|
|
55
55
|
// (before boot resumes) and reads clay.RichClay and clay.undo,
|
|
56
56
|
// which earlier plugins must have attached by then
|
|
@@ -83,6 +83,10 @@ function assembleCore(loaded, { isEditMode, isOwner }, regionPolicy) {
|
|
|
83
83
|
const save = loaded["core/save.js"];
|
|
84
84
|
const cacheBustMod = loaded["lib/cache-bust.js"];
|
|
85
85
|
const hyperMorph = loaded["vendor/hyper-morph.vendor.js"];
|
|
86
|
+
const pageData = loaded["core/page-data.js"];
|
|
87
|
+
|
|
88
|
+
clay.readData = pageData.readData;
|
|
89
|
+
clay.writeData = pageData.writeData;
|
|
86
90
|
|
|
87
91
|
if (save) {
|
|
88
92
|
const saveFn = save.savePage || save.default;
|
|
@@ -107,7 +111,7 @@ function assembleCore(loaded, { isEditMode, isOwner }, regionPolicy) {
|
|
|
107
111
|
if (hyperMorph) clay.morph = hyperMorph.morph;
|
|
108
112
|
}
|
|
109
113
|
|
|
110
|
-
function attachPluginMember(path, mod) {
|
|
114
|
+
function attachPluginMember(path, mod, loaded) {
|
|
111
115
|
const clay = window.clay;
|
|
112
116
|
|
|
113
117
|
if (path === "plugins/undo.js") {
|
|
@@ -115,6 +119,7 @@ function attachPluginMember(path, mod) {
|
|
|
115
119
|
} else if (path === "sync/live-sync.js") {
|
|
116
120
|
clay.morph = mod.morph;
|
|
117
121
|
clay.conflicts = mod.conflicts;
|
|
122
|
+
loaded["core/page-data.js"].setPageDataLiveSync(mod.liveSync);
|
|
118
123
|
} else if (path === "plugins/cms.js") {
|
|
119
124
|
clay.cms = mod.cms || mod.default;
|
|
120
125
|
} else if (path === "plugins/upload.js") {
|
package/src/plugins/wire.js
CHANGED
|
@@ -506,10 +506,10 @@ async function flushSave() {
|
|
|
506
506
|
// surface is an opt-in satellite script, absent on every page the loader
|
|
507
507
|
// builds, so reading it here made "is a save on the wire" permanently false.
|
|
508
508
|
const { isSaveInProgress } = await import("../core/save-core.js");
|
|
509
|
-
// A held save
|
|
510
|
-
// nothing to save: posting now
|
|
511
|
-
const { savesHeld } = await import("../core/save.js");
|
|
512
|
-
if (savesHeld()) throw new Error(
|
|
509
|
+
// A held save means another operation owns the page's persisted state, not a
|
|
510
|
+
// page with nothing to save: posting now could hand the agent stale bytes.
|
|
511
|
+
const { savesHeld, saveHoldReason } = await import("../core/save.js");
|
|
512
|
+
if (savesHeld()) throw new Error(saveHoldReason());
|
|
513
513
|
const deadline = Date.now() + SAVE_FLUSH_TIMEOUT_MS;
|
|
514
514
|
|
|
515
515
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { conflicts } from './conflicts.js';
|
|
2
|
+
|
|
3
|
+
const replacements = new WeakMap();
|
|
4
|
+
|
|
5
|
+
export const replacementFootprint = (rec) => replacements.get(rec) || null;
|
|
6
|
+
|
|
7
|
+
export function trackConflictFootprints(merge) {
|
|
8
|
+
const watched = new Map();
|
|
9
|
+
for (const rec of conflicts.list()) {
|
|
10
|
+
if (!rec.recovery?.text) continue;
|
|
11
|
+
const live = rec.recovery.subject.live;
|
|
12
|
+
const node = replacements.get(rec) || (live.length === 1 ? live[0] : null);
|
|
13
|
+
if (node?.nodeType === 1 && node.ownerDocument === document && node.isConnected) watched.set(rec, node);
|
|
14
|
+
}
|
|
15
|
+
if (!watched.size) return merge();
|
|
16
|
+
const observer = new MutationObserver(() => {});
|
|
17
|
+
observer.observe(document, { subtree: true, childList: true, attributes: true, characterData: true });
|
|
18
|
+
try {
|
|
19
|
+
const pending = merge();
|
|
20
|
+
const changes = observer.takeRecords();
|
|
21
|
+
if (changes.length !== 2) return pending;
|
|
22
|
+
const [insert, remove] = changes;
|
|
23
|
+
if (insert.type !== 'childList' || remove.type !== 'childList' || insert.target !== remove.target ||
|
|
24
|
+
insert.addedNodes.length !== 1 || insert.removedNodes.length ||
|
|
25
|
+
remove.removedNodes.length !== 1 || remove.addedNodes.length) return pending;
|
|
26
|
+
const old = remove.removedNodes[0];
|
|
27
|
+
const fresh = insert.addedNodes[0];
|
|
28
|
+
if (old.nodeType !== 1 || fresh.nodeType !== 1 || old.isConnected || !fresh.isConnected ||
|
|
29
|
+
old.namespaceURI !== fresh.namespaceURI || old.tagName === fresh.tagName ||
|
|
30
|
+
insert.nextSibling !== old || remove.previousSibling !== fresh ||
|
|
31
|
+
fresh.parentNode !== insert.target || fresh.previousSibling !== insert.previousSibling ||
|
|
32
|
+
fresh.nextSibling !== remove.nextSibling) return pending;
|
|
33
|
+
if (old.childNodes.length !== 1 || fresh.childNodes.length !== 1 || old.firstChild.nodeType !== 3 ||
|
|
34
|
+
!old.firstChild.isEqualNode(fresh.firstChild) || old.attributes.length !== fresh.attributes.length ||
|
|
35
|
+
[...old.attributes].some((a) => fresh.getAttributeNS(a.namespaceURI, a.localName) !== a.value)) return pending;
|
|
36
|
+
for (const [rec, node] of watched) if (node === old) replacements.set(rec, fresh);
|
|
37
|
+
return pending;
|
|
38
|
+
} finally {
|
|
39
|
+
observer.disconnect();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { HyperMorph } from "../vendor/hyper-morph.vendor.js";
|
|
2
2
|
import { conflicts } from "./conflicts.js";
|
|
3
|
+
import { replacementFootprint } from "./conflict-footprints.js";
|
|
3
4
|
import { SYNC_IGNORE_SELECTOR, REMOTE_WINS_SELECTOR } from "./live-sync.js";
|
|
4
5
|
import { savePage } from "../core/save.js";
|
|
5
6
|
import { gateMarkDirty } from "../lib/dirty-gate.js";
|
|
@@ -802,6 +803,8 @@ function footprintOf(rec, apply) {
|
|
|
802
803
|
}
|
|
803
804
|
const live = subject ? liveOf(subject, apply, subject.nodeType) : null;
|
|
804
805
|
if (live) return live;
|
|
806
|
+
const replacement = replacementFootprint(rec);
|
|
807
|
+
if (replacement && onPage(replacement)) return replacement;
|
|
805
808
|
const parent = r.structure && r.structure.localPlacement ? liveOf(r.structure.localPlacement.parent, apply, 1) : null;
|
|
806
809
|
if (parent) return parent;
|
|
807
810
|
const path = subject && subject.local.length ? subject.local[0] : [];
|
package/src/sync/conflicts.js
CHANGED
|
@@ -63,6 +63,33 @@ export function beginApply({ source, seq = null, etag = null, domain, root }) {
|
|
|
63
63
|
return id;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
function insertionProof(raw) {
|
|
67
|
+
if (!raw.every((c) => c.kind === 'structure' && c.detail === 'insert-collision' && c.recovery?.applied === true && !c.recovery.unavailable && c.recovery.structure?.localAction === 'inserted' && c.recovery.structure.fragmentKind === 'element')) return null;
|
|
68
|
+
const subject = raw[0].recovery.subject;
|
|
69
|
+
if (subject?.local?.length !== 1 || subject.merged?.length !== 1 || subject.live?.length !== 1) return null;
|
|
70
|
+
return { local: subject.local[0], merged: subject.merged[0], live: subject.live[0] };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function foldInsertions(groups) {
|
|
74
|
+
const proofs = new Map(groups.map((raw) => [raw, insertionProof(raw)]));
|
|
75
|
+
const below = (parent, child) => parent.length < child.length && parent.every((step, i) => step === child[i]);
|
|
76
|
+
const at = (root, path) => path.reduce((node, step) => step === 'content' ? node?.content : node?.childNodes[step], root);
|
|
77
|
+
const folded = new Map();
|
|
78
|
+
for (const raw of groups) {
|
|
79
|
+
const child = proofs.get(raw);
|
|
80
|
+
let owner = raw;
|
|
81
|
+
if (child) {
|
|
82
|
+
for (const candidate of groups) {
|
|
83
|
+
const parent = proofs.get(candidate);
|
|
84
|
+
if (parent && parent.local.length < proofs.get(owner).local.length && below(parent.local, child.local) && below(parent.merged, child.merged) && (parent.live.contains(child.live) || at(parent.live, child.merged.slice(parent.merged.length)) === child.live)) owner = candidate;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!folded.has(owner)) folded.set(owner, [...owner]);
|
|
88
|
+
if (raw !== owner) folded.get(owner).push(...raw);
|
|
89
|
+
}
|
|
90
|
+
return [...folded.values()];
|
|
91
|
+
}
|
|
92
|
+
|
|
66
93
|
export function completeApply(applyId, conflicts, { ticket }) {
|
|
67
94
|
const apply = applies.get(applyId);
|
|
68
95
|
if (!apply) return [];
|
|
@@ -74,7 +101,7 @@ export function completeApply(applyId, conflicts, { ticket }) {
|
|
|
74
101
|
if (!groups.has(key)) groups.set(key, []);
|
|
75
102
|
groups.get(key).push(c);
|
|
76
103
|
}
|
|
77
|
-
const ids = [...groups.values()].map((raw) => install(apply, raw));
|
|
104
|
+
const ids = foldInsertions([...groups.values()]).map((raw) => install(apply, raw));
|
|
78
105
|
pending.delete(applyId);
|
|
79
106
|
if (!ids.length) applies.delete(applyId);
|
|
80
107
|
if (ids.length) changed({ added: ids.map((id) => records.get(id)) });
|
package/src/sync/live-sync.js
CHANGED
|
@@ -60,6 +60,7 @@ import { pageMaybeDirty, pauseGate, resumeGate, gateCaptureToken, gateClearIfUnc
|
|
|
60
60
|
import { gestureSeen } from '../lib/user-gesture.js';
|
|
61
61
|
import { SyncStream } from './stream.js';
|
|
62
62
|
import { conflicts, beginApply, completeApply, failApply } from './conflicts.js';
|
|
63
|
+
import { trackConflictFootprints } from './conflict-footprints.js';
|
|
63
64
|
|
|
64
65
|
// What a live-sync merge never reads or touches on any side: editor chrome,
|
|
65
66
|
// content kept out of the save or the snapshot, frozen regions, and nodes
|
|
@@ -1339,6 +1340,7 @@ class LiveSync {
|
|
|
1339
1340
|
* @param {object} [lane.extra] - extra mergeDocument options (the disk lane's beforeApply)
|
|
1340
1341
|
*/
|
|
1341
1342
|
async _mergeIncoming(html, identityMap, { base, baseIdentityMap = null, captureLocal, synthetic, source = 'peer', seq = null, etag = null, extra = {} }) {
|
|
1343
|
+
const mergeDocument = (options) => trackConflictFootprints(() => HyperMorph.mergeDocument(options));
|
|
1342
1344
|
const store = this.identity;
|
|
1343
1345
|
// A frame may neither write these onto our root nor, by not carrying them,
|
|
1344
1346
|
// take ours away. Returning false is hyper-morph's veto for both directions.
|
|
@@ -1396,7 +1398,7 @@ class LiveSync {
|
|
|
1396
1398
|
let localRoot = null;
|
|
1397
1399
|
let applyId = null;
|
|
1398
1400
|
if (base == null) {
|
|
1399
|
-
pending =
|
|
1401
|
+
pending = mergeDocument({
|
|
1400
1402
|
...common,
|
|
1401
1403
|
base: null,
|
|
1402
1404
|
local: { root: captureLocal(), toLive: originalSnapshotNode },
|
|
@@ -1414,7 +1416,7 @@ class LiveSync {
|
|
|
1414
1416
|
const localRoot = captureLocal();
|
|
1415
1417
|
const baseDoc = localRoot.ownerDocument;
|
|
1416
1418
|
if (baseDoc.documentElement !== localRoot) baseDoc.replaceChild(localRoot, baseDoc.documentElement);
|
|
1417
|
-
pending =
|
|
1419
|
+
pending = mergeDocument({
|
|
1418
1420
|
...common,
|
|
1419
1421
|
base: baseDoc,
|
|
1420
1422
|
local: { root: localRoot, toLive: originalSnapshotNode },
|
|
@@ -1432,7 +1434,7 @@ class LiveSync {
|
|
|
1432
1434
|
domain: source === 'disk' ? 'save' : 'sync',
|
|
1433
1435
|
});
|
|
1434
1436
|
try {
|
|
1435
|
-
pending =
|
|
1437
|
+
pending = mergeDocument({
|
|
1436
1438
|
...common,
|
|
1437
1439
|
base,
|
|
1438
1440
|
local: { root: localRoot, toLive: originalSnapshotNode },
|
package/src/ui/bevel-controls.js
CHANGED
|
@@ -72,8 +72,10 @@ function protectIcon(svg, size) {
|
|
|
72
72
|
`fill:${attr('fill', svg.getAttribute('fill') ?? 'currentColor')}`,
|
|
73
73
|
`stroke:${attr('stroke', svg.getAttribute('stroke') ?? 'none')}`,
|
|
74
74
|
];
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
for (const prop of ['stroke-width', 'stroke-linecap', 'stroke-linejoin']) {
|
|
76
|
+
const value = el.getAttribute(prop) ?? svg.getAttribute(prop);
|
|
77
|
+
if (value !== null) rules.push(`${prop}:${value}`);
|
|
78
|
+
}
|
|
77
79
|
if (el.localName === 'path' && el.hasAttribute('d')) rules.push(`d:path("${el.getAttribute('d')}")`);
|
|
78
80
|
style(el, rules);
|
|
79
81
|
}
|
|
@@ -84,6 +86,7 @@ export function bevelButton(label, { variant = 'default', small = false, onClick
|
|
|
84
86
|
const size = small ? SIZE.small : SIZE.normal;
|
|
85
87
|
const reducedMotion = media('(prefers-reduced-motion: reduce)');
|
|
86
88
|
const forced = media('(forced-colors: active)');
|
|
89
|
+
const coarse = media('(pointer: coarse)');
|
|
87
90
|
const flags = { hovered: false, pressed: false, focusVisible: false, disabled: false };
|
|
88
91
|
const pinned = new Map();
|
|
89
92
|
|
|
@@ -103,6 +106,7 @@ export function bevelButton(label, { variant = 'default', small = false, onClick
|
|
|
103
106
|
}
|
|
104
107
|
if (flags.focusVisible) rules.push(...RULES.focus);
|
|
105
108
|
if (forced) rules.push(...MEDIA.forcedColors);
|
|
109
|
+
if (coarse) rules.push(...MEDIA.coarseButton);
|
|
106
110
|
rules.push(...extra);
|
|
107
111
|
for (const [prop, value] of pinned) rules.push(`${prop}:${value}`);
|
|
108
112
|
restyle(b, rules);
|
|
@@ -234,6 +238,7 @@ export function bevelText(tag, rules = [], text) {
|
|
|
234
238
|
export function paintInput(el, { rules = [] } = {}) {
|
|
235
239
|
const flags = { hovered: false, focused: false };
|
|
236
240
|
const forced = media('(forced-colors: active)');
|
|
241
|
+
const coarse = media('(pointer: coarse)');
|
|
237
242
|
runtime(el);
|
|
238
243
|
function applyState() {
|
|
239
244
|
const height = el.localName === 'textarea' ? el.style.getPropertyValue('height') : '';
|
|
@@ -242,6 +247,7 @@ export function paintInput(el, { rules = [] } = {}) {
|
|
|
242
247
|
if (flags.focused) list.push(...RULES.inputFocus);
|
|
243
248
|
if (forced) list.push(...MEDIA.forcedColors);
|
|
244
249
|
list.push(...rules);
|
|
250
|
+
if (coarse) list.push(...MEDIA.coarseInput);
|
|
245
251
|
if (height) list.push(`height:${height}`);
|
|
246
252
|
restyle(el, list);
|
|
247
253
|
}
|
package/src/ui/bevel-dialog.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// backdrop clicks and settling, so each keeps the rules it already had.
|
|
4
4
|
import { set } from "../lib/hostile-css.js";
|
|
5
5
|
import { bevelBox, bevelSurface, bevelText, pageScheme, protectIcon } from "./bevel-controls.js";
|
|
6
|
-
import { TOKENS, FONT_SANS, RULES } from "./bevel.js";
|
|
6
|
+
import { TOKENS, FONT_SANS, RULES, GLYPHS } from "./bevel.js";
|
|
7
7
|
|
|
8
8
|
// A frame's own way to settle itself. The modal is a singleton and clears every frame
|
|
9
9
|
// when it opens; a frame it does not own (the crop dialog) registers here, so it is
|
|
@@ -32,8 +32,6 @@ export function keepFocusIn(container, event) {
|
|
|
32
32
|
// The dashboard's dialog (Bevel's React dialog with the dashboard's overrides), drawn
|
|
33
33
|
// inline. ClayJS loads no webfonts, so the title's Newsreader falls back to Georgia.
|
|
34
34
|
const LINE = `1px solid ${TOKENS["line-2"]}`;
|
|
35
|
-
const CLOSE_X =
|
|
36
|
-
'<svg viewBox="0 0 256 256" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"/></svg>';
|
|
37
35
|
|
|
38
36
|
// The close: a column at the header's right edge in the button face, or a 62px square
|
|
39
37
|
// at the panel's corner when there is no header.
|
|
@@ -48,7 +46,7 @@ function dialogClose(label, inHeader) {
|
|
|
48
46
|
b.type = "button";
|
|
49
47
|
b.setAttribute("aria-label", label);
|
|
50
48
|
b.title = label;
|
|
51
|
-
b.innerHTML =
|
|
49
|
+
b.innerHTML = GLYPHS.dialogClose;
|
|
52
50
|
protectIcon(b.firstElementChild, 16);
|
|
53
51
|
b.addEventListener("pointerenter", () => set(b, "background", hover));
|
|
54
52
|
b.addEventListener("pointerleave", () => set(b, "background", TOKENS.face));
|
package/src/ui/bevel.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// GENERATED from bevel/bevel.css by scripts/build-bevel-subset.mjs. Run `npm run build:bevel`.
|
|
2
|
-
export const SOURCE_SHA256 = "
|
|
1
|
+
// GENERATED from bevel/bevel.css and bevel/icons by scripts/build-bevel-subset.mjs. Run `npm run build:bevel`.
|
|
2
|
+
export const SOURCE_SHA256 = "775cf730e10d88d8b13440ba83e039a907ffb70bffe88d13c3bee8681af2e131";
|
|
3
3
|
export const FONT_SANS = "system-ui,-apple-system,\"Segoe UI\",sans-serif";
|
|
4
4
|
export const FONT_MONO = "ui-monospace,SFMono-Regular,Menlo,Consolas,monospace";
|
|
5
5
|
export const SHADOW = "0 1px 2px rgba(0,0,0,.12),0 10px 28px -12px rgba(0,0,0,.35)";
|
|
@@ -33,6 +33,14 @@ export const TOKENS = {
|
|
|
33
33
|
"ox-edge-lo": "light-dark(#451510, #3E1410)",
|
|
34
34
|
"ox-ink": "light-dark(#FBEEE8, #FBEEE8)",
|
|
35
35
|
};
|
|
36
|
+
export const GLYPHS = {
|
|
37
|
+
"toastSuccess": "<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"square\" stroke-linejoin=\"miter\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m5 12 4 4L19 6\"/></svg>",
|
|
38
|
+
"toastWarning": "<svg width=\"16\" height=\"16\" viewBox=\"0 0 256 256\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1-7.48,4.2H40.55a8.5,8.5,0,0,1-7.48-4.2,7.59,7.59,0,0,1,0-7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,180Z\"/></svg>",
|
|
39
|
+
"toastInfo": "<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"square\" stroke-linejoin=\"miter\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0M12 7.75v.85M10.3 11.15H12v5.1M10.3 16.25h3.4\"/></svg>",
|
|
40
|
+
"toastClose": "<svg width=\"14\" height=\"14\" viewBox=\"0 0 256 256\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z\"/></svg>",
|
|
41
|
+
"dialogClose": "<svg width=\"16\" height=\"16\" viewBox=\"0 0 256 256\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z\"/></svg>",
|
|
42
|
+
"conflictEye": "<svg width=\"16\" height=\"16\" viewBox=\"0 0 256 256\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M247.31,124.76c-.35-.79-8.82-19.58-27.65-38.41C194.57,61.26,162.88,48,128,48S61.43,61.26,36.34,86.35C17.51,105.18,9,124,8.69,124.76a8,8,0,0,0,0,6.5c.35.79,8.82,19.57,27.65,38.4C61.43,194.74,93.12,208,128,208s66.57-13.26,91.66-38.34c18.83-18.83,27.3-37.61,27.65-38.4A8,8,0,0,0,247.31,124.76ZM128,192c-30.78,0-57.67-11.19-79.93-33.25A133.47,133.47,0,0,1,25,128,133.33,133.33,0,0,1,48.07,97.25C70.33,75.19,97.22,64,128,64s57.67,11.19,79.93,33.25A133.46,133.46,0,0,1,231.05,128C223.84,141.46,192.43,192,128,192Zm0-112a48,48,0,1,0,48,48A48.05,48.05,0,0,0,128,80Zm0,80a32,32,0,1,1,32-32A32,32,0,0,1,128,160Z\"/></svg>",
|
|
43
|
+
};
|
|
36
44
|
export const RULES = {
|
|
37
45
|
"button": [
|
|
38
46
|
"display:inline-flex",
|
|
@@ -244,4 +252,16 @@ export const MEDIA = {
|
|
|
244
252
|
"forcedColors": [
|
|
245
253
|
"border:1px solid ButtonText",
|
|
246
254
|
],
|
|
255
|
+
"coarseInput": [
|
|
256
|
+
"font-size:16px",
|
|
257
|
+
"block-size:40px",
|
|
258
|
+
"min-block-size:40px",
|
|
259
|
+
"padding-inline:12px",
|
|
260
|
+
],
|
|
261
|
+
"coarseButton": [
|
|
262
|
+
"block-size:40px",
|
|
263
|
+
"min-block-size:40px",
|
|
264
|
+
"padding-inline:14px",
|
|
265
|
+
"font-size:15px",
|
|
266
|
+
],
|
|
247
267
|
};
|
package/src/ui/dialogs.js
CHANGED
|
@@ -9,7 +9,7 @@ import { TOKENS, FONT_SANS, FONT_MONO } from "./bevel.js";
|
|
|
9
9
|
// are markup by design, and callers pass elements through them. Only the frame around
|
|
10
10
|
// it is ClayJS's to style. The prompt is the dialog's title, as in the dashboard.
|
|
11
11
|
function createModal(promptText, yesCallback, extraContent = "", includeInput = false, defaultValue = "", yesLabel = "OK") {
|
|
12
|
-
const content = bevelBox("div", ["display:flex", "flex-direction:column", "gap:14px"]);
|
|
12
|
+
const content = bevelBox("div", ["display:flex", "flex-direction:column", "gap:14px", `font:14.5px/1.55 ${FONT_SANS}`, `color:${TOKENS["ink-2"]}`]);
|
|
13
13
|
let input = null;
|
|
14
14
|
if (includeInput) {
|
|
15
15
|
input = bevelInput("input", { rules: ["display:block", "width:100%", "margin:0"] });
|
package/src/ui/skins/cms.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// GENERATED from src/vendor/hypercms.vendor.js by scripts/build-vendor-skins.mjs. Run `npm run build:skins`.
|
|
2
|
-
export const SOURCE_SHA256 = "
|
|
2
|
+
export const SOURCE_SHA256 = "a1757cdc7333f40185cb497dd0a7db863289aac55e96c9d9f24239d56ceeacc2";
|
|
3
3
|
export const ROOTS = [".hcms-shell"];
|
|
4
4
|
export const CSS = "@layer clay-skin{\n:is(.hcms-shell):not([data-theme]),:is(.hcms-shell):not([data-theme]) *{--mirk-canvas:light-dark(#FDF8F0, #0B0C13) !important;--mirk-bg:light-dark(#FFFCF6, #11131E) !important;--mirk-fg:light-dark(#2B241B, #ECEAF2) !important;--mirk-accent:light-dark(#F4ECDF, #1A1D2C) !important;--mirk-destructive:light-dark(#A83A2C, #FF5566) !important;--mirk-focus-color:light-dark(#8F6310, #D9A445) !important;--mirk-bevel-bg:light-dark(#F1E7D4, #22273E) !important;--mirk-bevel-fg:light-dark(#2B241B, #ECEAF2) !important;--mirk-bevel-tl:light-dark(#FFF9ED, #3C4260) !important;--mirk-bevel-br:light-dark(#D6C3A5, #1B2033) !important;--mirk-bevel-hover-bg:color-mix(in srgb, light-dark(#F1E7D4, #22273E), light-dark(#FFF9ED, #3C4260) 45%) !important;--mirk-pill-inner-top:light-dark(#FFF9ED, #3C4260) !important;--mirk-input-border:light-dark(#D8C8AF, #353B52) !important;--mirk-placeholder-color:light-dark(#9A8A70, #6A7090) !important;--mirk-ctrl-bg:light-dark(#6B5942, #8A90AB) !important;--mirk-toggle-bg:light-dark(#FCF8F1, #4A5275) !important;--mirk-toggle-hi:light-dark(#FFF9ED, #6C759A) !important;--mirk-toggle-lo:light-dark(#D6C3A5, #1B2033) !important;--mirk-mark-fg:light-dark(#2B241B, #ECEAF2) !important;--mirk-sortable-dot:light-dark(#D8C8AF, #353B52) !important;--mirk-sortable-shadow:light-dark(#D6C3A5, #1B2033) !important;--mirk-sortable-label:light-dark(#6B5942, #8A90AB) !important;--mirk-sortable-placeholder:light-dark(#9A8A70, #6A7090) !important;--mirk-slider-fill:light-dark(#F0E4CC, #3A2F17) !important;--mirk-slider-nub-bg:light-dark(#FCF8F1, #4A5275) !important;--mirk-slider-nub-hi:light-dark(#FFF9ED, #6C759A) !important;--mirk-slider-nub-lo:light-dark(#D6C3A5, #1B2033) !important;--mirk-chip-surface:light-dark(#FFFCF6, #11131E) !important;--mirk-chip-edge:light-dark(#D8C8AF, #353B52) !important;--mirk-chip-primary-bg:light-dark(#2B241B, #ECEAF2) !important;--mirk-chip-primary-fg:light-dark(#FDF8F0, #0B0C13) !important;--mirk-chip-alert:light-dark(#A83A2C, #FF5566) !important;--mirk-radius:0px !important;--mirk-focus-offset:2px !important}\n:is(.hcms-shell){font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace !important}\n.hcms-shell .mirk-chip__actions .mirk-chip__action--primary{--mirk-bevel-bg:var(--mirk-chip-primary-bg) !important;--mirk-bevel-fg:var(--mirk-chip-primary-fg) !important;--mirk-bevel-tl:color-mix(in srgb, var(--mirk-chip-primary-bg), white 24%) !important;--mirk-bevel-br:color-mix(in srgb, var(--mirk-chip-primary-bg), black 32%) !important;--mirk-bevel-hover-bg:color-mix(in srgb, var(--mirk-chip-primary-bg), white 10%) !important}\n}";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// GENERATED from src/vendor/quickcrop.vendor.js and bevel/integrations/quickcrop.css by scripts/build-vendor-skins.mjs. Run `npm run build:skins`.
|
|
2
|
-
export const SOURCE_SHA256 = "
|
|
2
|
+
export const SOURCE_SHA256 = "eadbbf799e0954f11ff553c5a37a759ceb42c6bb1698a0e46b1f273458acf8ed";
|
|
3
3
|
export const ROOTS = [".qc-stage",".qc-backdrop"];
|
|
4
4
|
export const CSS = "@layer clay-skin{\n:is(.qc-stage, .qc-backdrop),:is(.qc-stage, .qc-backdrop) *{--qc-surface:light-dark(#FFFCF6, #11131E) !important;--qc-text:light-dark(#2B241B, #ECEAF2) !important;--qc-border:light-dark(#D8C8AF, #353B52) !important;--qc-radius:0px !important;--qc-font:system-ui,-apple-system,\"Segoe UI\",sans-serif !important;--qc-surface-hover:light-dark(#F4ECDF, #1A1D2C) !important;--qc-text-hover:color-mix(in srgb, light-dark(#2B241B, #ECEAF2), light-dark(#FDF8F0, #0B0C13) 12%) !important;--qc-on-dark:light-dark(#FDF8F0, #0B0C13) !important;--qc-overlay:color-mix(in srgb, light-dark(#FDF8F0, #0B0C13) 70%, transparent) !important;--qc-dim:rgba(0,0,0,.55) !important;--qc-crop-line:#fff !important}\n.qc-stage{margin-inline:auto !important;inline-size:fit-content !important;background:light-dark(#F4ECDF, #1A1D2C) !important}\n.qc-stage img{display:block !important;max-inline-size:100% !important}\n.qc-backdrop{position:fixed !important;inset:0 !important;background:var(--qc-overlay) !important;display:grid !important;place-items:center !important;z-index:1000 !important;animation:qc-fade .15s ease !important}\n.qc-modal{background:var(--qc-surface) !important;border:1px solid var(--qc-border) !important;border-radius:var(--qc-radius) !important;padding:16px !important;max-width:92vw !important;font-family:var(--qc-font) !important}\n.qc-bar{display:flex !important;justify-content:flex-end !important;gap:10px !important;margin-top:12px !important}\n.qc-btn{font:inherit !important;font-family:var(--qc-font) !important;font-size:.85rem !important;padding:.3rem .75rem !important;border:1px solid var(--qc-border) !important;border-radius:6px !important;background:var(--qc-surface) !important;color:var(--qc-text) !important;cursor:pointer !important}\n.qc-btn:hover{background:var(--qc-surface-hover) !important}\n.qc-btn-primary{background:var(--qc-text) !important;border-color:var(--qc-text) !important;color:var(--qc-on-dark) !important;font-weight:600 !important}\n.qc-btn-primary:hover{background:var(--qc-text-hover) !important;border-color:var(--qc-text-hover) !important}\n.qc-stage{position:relative !important;line-height:0 !important;user-select:none !important;-webkit-user-select:none !important;touch-action:none !important}\n.qc-stage img{display:block !important;max-width:100% !important;pointer-events:none !important}\n.qc-dim{position:absolute !important;inset:0 !important;background:var(--qc-dim) !important;pointer-events:none !important}\n.qc-box{position:absolute !important;cursor:move !important;outline:1px solid var(--qc-crop-line) !important;background:linear-gradient(var(--qc-crop-line),var(--qc-crop-line)) 0 33.33%/100% 1px no-repeat,linear-gradient(var(--qc-crop-line),var(--qc-crop-line)) 0 66.66%/100% 1px no-repeat,linear-gradient(var(--qc-crop-line),var(--qc-crop-line)) 33.33% 0/1px 100% no-repeat,linear-gradient(var(--qc-crop-line),var(--qc-crop-line)) 66.66% 0/1px 100% no-repeat !important;background-blend-mode:overlay !important}\n.qc-handle{position:absolute !important;box-sizing:border-box !important;width:28px !important;height:28px !important;border:7px solid transparent !important;background:var(--qc-crop-line) !important;background-clip:padding-box !important;border-radius:9px !important}\n.qc-nw{left:-14px !important;top:-14px !important;cursor:nwse-resize !important}\n.qc-ne{right:-14px !important;top:-14px !important;cursor:nesw-resize !important}\n.qc-sw{left:-14px !important;bottom:-14px !important;cursor:nesw-resize !important}\n.qc-se{right:-14px !important;bottom:-14px !important;cursor:nwse-resize !important}\n.qc-mount{line-height:0 !important}\n.qc-stage img[hidden]{display:none !important}\n.qc-backdrop[hidden]{display:none !important}\n.qc-bar[hidden]{display:none !important}\n}";
|
package/src/ui/skins/richclay.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// GENERATED from src/vendor/richclay.vendor.js and bevel/integrations/richclay.css by scripts/build-vendor-skins.mjs. Run `npm run build:skins`.
|
|
2
|
-
export const SOURCE_SHA256 = "
|
|
2
|
+
export const SOURCE_SHA256 = "69e3bc73ddf6654bb6245485dbad2a54956b8abd621889807b2de80875927982";
|
|
3
3
|
export const ROOTS = [".richclay-toolbar",".richclay-float",".richclay-dialog"];
|
|
4
|
-
export const CSS = "@layer clay-skin{\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog),:is(.richclay-toolbar, .richclay-float, .richclay-dialog) *{--richclay-surface:light-dark(#FFFCF6, #11131E) !important;--richclay-surface-alt:light-dark(#F4ECDF, #1A1D2C) !important;--richclay-text:light-dark(#2B241B, #ECEAF2) !important;--richclay-muted:light-dark(#6B5942, #8A90AB) !important;--richclay-border:light-dark(#D8C8AF, #353B52) !important;--richclay-accent:light-dark(#8F6310, #D9A445) !important;--richclay-accent-ink:light-dark(#FDF8F0, #0B0C13) !important;--richclay-focus:light-dark(#8F6310, #D9A445) !important;--richclay-danger:light-dark(#A83A2C, #FF5566) !important;--richclay-radius:0px !important;--richclay-control-size:32px !important;--richclay-shadow:0 1px 2px rgba(0,0,0,.12),0 10px 28px -12px rgba(0,0,0,.35) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog){font-family:system-ui,-apple-system,\"Segoe UI\",sans-serif !important}\n:where(.richclay-float, .richclay-dialog):is(.richclay-toolbar, .richclay-float, .richclay-dialog){color:light-dark(#2B241B, #ECEAF2) !important;background:light-dark(#FFFCF6, #11131E) !important;border:1px solid light-dark(#D8C8AF, #353B52) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-toolbar{gap:3px !important;margin:0 !important;padding:8px !important;border:1px solid light-dark(#D8C8AF, #353B52) !important;border-radius:0 !important;background:light-dark(#F4ECDF, #1A1D2C) !important;color:light-dark(#2B241B, #ECEAF2) !important}\n.richclay-toolbar:is(.richclay-toolbar, .richclay-float, .richclay-dialog){gap:3px !important;padding:8px !important;border:1px solid light-dark(#D8C8AF, #353B52) !important;border-radius:0 !important;background:light-dark(#F4ECDF, #1A1D2C) !important;color:light-dark(#2B241B, #ECEAF2) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-button{min-width:32px !important;height:32px !important;padding:0 7px !important;gap:6px !important;border:2px solid !important;border-color:light-dark(#FFF9ED, #3C4260) light-dark(#D6C3A5, #1B2033) light-dark(#D6C3A5, #1B2033) light-dark(#FFF9ED, #3C4260) !important;border-radius:0 !important;background:light-dark(#F1E7D4, #22273E) !important;font:14px system-ui,-apple-system,\"Segoe UI\",sans-serif !important;cursor:pointer !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-button:is([aria-pressed=\"true\"], [aria-expanded=\"true\"]){background:light-dark(#E3D0B3, #28304D) !important;border-color:light-dark(#B89F7B, #1F2339) light-dark(#F0E1C9, #4D587A) light-dark(#F0E1C9, #4D587A) light-dark(#B89F7B, #1F2339) !important;box-shadow:none !important;color:light-dark(#2B241B, #ECEAF2) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-button[aria-pressed=\"true\"] > svg{translate:1px 1px !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-button:disabled{opacity:.45 !important;cursor:not-allowed !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-button:hover:not([aria-pressed=\"true\"], [aria-expanded=\"true\"], :disabled){border-color:light-dark(#FFF9ED, #3C4260) light-dark(#D6C3A5, #1B2033) light-dark(#D6C3A5, #1B2033) light-dark(#FFF9ED, #3C4260) !important;background:color-mix(in srgb, light-dark(#F1E7D4, #22273E), light-dark(#FFF9ED, #3C4260) 45%) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-separator{align-self:center !important;height:22px !important;margin:0 5px !important;background:light-dark(#D8C8AF, #353B52) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-menu{inset-block-start:38px !important;min-width:210px !important;padding:5px !important;border-radius:0 !important;box-shadow:0 1px 2px rgba(0,0,0,.12),0 10px 28px -12px rgba(0,0,0,.35) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-menu-item{padding:8px 10px !important;border:0 !important;border-radius:0 !important;font:14px system-ui,-apple-system,\"Segoe UI\",sans-serif !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-menu-item[aria-checked=\"true\"]{background:light-dark(#F4ECDF, #1A1D2C) !important;box-shadow:inset 2px 0 light-dark(#8F6310, #D9A445) !important}\n.richclay-dialog:is(.richclay-toolbar, .richclay-float, .richclay-dialog){width:min(100%, 360px) !important;padding:14px 16px 12px !important;border:1px solid light-dark(#D8C8AF, #353B52) !important;border-radius:0 !important;background:light-dark(#FFFCF6, #11131E) !important;color:light-dark(#2B241B, #ECEAF2) !important;box-shadow:0 1px 2px rgba(0,0,0,.12),0 10px 28px -12px rgba(0,0,0,.35) !important}\n.richclay-dialog:is(.richclay-toolbar, .richclay-float, .richclay-dialog)::before{content:\"\" !important;position:absolute !important;left:calc(var(--richclay-dialog-arrow, 28px) - 6px) !important;top:-7px !important;width:12px !important;height:12px !important;background:light-dark(#FFFCF6, #11131E) !important;border-top:1px solid light-dark(#D8C8AF, #353B52) !important;border-left:1px solid light-dark(#D8C8AF, #353B52) !important;transform:rotate(45deg) !important}\n.richclay-dialog:is(.richclay-toolbar, .richclay-float, .richclay-dialog)[data-richclay-side=\"above\"]::before{top:auto !important;bottom:-7px !important;border:0 !important;border-right:1px solid light-dark(#D8C8AF, #353B52) !important;border-bottom:1px solid light-dark(#D8C8AF, #353B52) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-dialog-title{margin-bottom:2px !important;font:500 10px ui-monospace,SFMono-Regular,Menlo,Consolas,monospace !important;text-transform:uppercase !important;letter-spacing:.12em !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-field{gap:5px !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-field > span{color:light-dark(#4A4033, #C9CDE0) !important;font-size:12px !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-input{min-height:30px !important;padding:4px 8px !important;border:2px solid !important;border-color:light-dark(#B89F7B, #1F2339) light-dark(#F0E1C9, #4D587A) light-dark(#F0E1C9, #4D587A) light-dark(#B89F7B, #1F2339) !important;border-radius:0 !important;background:light-dark(#F4ECDF, #1A1D2C) !important;color:light-dark(#2B241B, #ECEAF2) !important;font:13px system-ui,-apple-system,\"Segoe UI\",sans-serif !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-dialog-actions{margin-top:4px !important;padding-top:12px !important;border-top:1px solid light-dark(#E8DCC6, #262B42) !important;flex-wrap:wrap !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) :is(.richclay-primary, .richclay-secondary){min-height:30px !important;padding:4px 10px !important;border:2px solid !important;border-color:light-dark(#FFF9ED, #3C4260) light-dark(#D6C3A5, #1B2033) light-dark(#D6C3A5, #1B2033) light-dark(#FFF9ED, #3C4260) !important;border-radius:0 !important;background:light-dark(#F1E7D4, #22273E) !important;color:light-dark(#2B241B, #ECEAF2) !important;font:13px system-ui,-apple-system,\"Segoe UI\",sans-serif !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-primary{background:light-dark(#2B241B, #ECEAF2) !important;color:light-dark(#FDF8F0, #0B0C13) !important;border-color:color-mix(in srgb, light-dark(#2B241B, #ECEAF2), white 24%) color-mix(in srgb, light-dark(#2B241B, #ECEAF2), black 32%) color-mix(in srgb, light-dark(#2B241B, #ECEAF2), black 32%) color-mix(in srgb, light-dark(#2B241B, #ECEAF2), white 24%) !important}\n.richclay-float:is(.richclay-toolbar, .richclay-float, .richclay-dialog){border-radius:0 !important;box-shadow:0 1px 2px rgba(0,0,0,.12),0 10px 28px -12px rgba(0,0,0,.35) !important}\n.richclay-float:is(.richclay-toolbar, .richclay-float, .richclay-dialog) > .richclay-toolbar{padding:5px !important}\n.richclay-toolbar{align-items:center !important;background:var(--richclay-surface-alt) !important;border:1px solid var(--richclay-border) !important;border-radius:var(--richclay-radius) !important;color:var(--richclay-text) !important;display:flex !important;flex-wrap:wrap !important;gap:2px !important;margin-block:0 6px !important;padding:4px !important}\n.richclay-toolbar:has(+ .richclay-editor){margin-block-end:0 !important;border-bottom-left-radius:0 !important;border-bottom-right-radius:0 !important}\n.richclay-button{align-items:center !important;appearance:none !important;background:transparent !important;border:1px solid transparent !important;border-radius:5px !important;color:currentColor !important;display:inline-flex !important;height:var(--richclay-control-size) !important;justify-content:center !important;margin:0 !important;min-width:var(--richclay-control-size) !important;padding:0 !important;position:relative !important}\n.richclay-button:hover,.richclay-button[aria-expanded=\"true\"],.richclay-menu-item:hover{background:var(--richclay-surface) !important;border-color:var(--richclay-border) !important}\n.richclay-button.is-active,.richclay-button[aria-pressed=\"true\"],.richclay-menu-item.is-active{background:rgb(0 0 0 / 0.13) !important;border-color:rgb(0 0 0 / 0.22) !important;color:var(--richclay-text) !important;box-shadow:inset 0 1px 3px rgb(0 0 0 / 0.26) !important}\n.richclay-button:focus-visible,.richclay-menu-item:focus-visible,.richclay-input:focus-visible,.richclay-primary:focus-visible,.richclay-secondary:focus-visible{outline:3px solid var(--richclay-focus) !important;outline-offset:2px !important}\n.richclay-button:disabled{color:var(--richclay-muted) !important;cursor:not-allowed !important;opacity:0.55 !important}\n.richclay-separator{align-self:stretch !important;background:var(--richclay-border) !important;display:inline-block !important;margin:5px 4px !important;width:1px !important}\n.richclay-menu-wrap{display:inline-flex !important;position:relative !important}\n.richclay-menu{background:var(--richclay-surface) !important;border:1px solid var(--richclay-border) !important;border-radius:var(--richclay-radius) !important;box-shadow:var(--richclay-shadow) !important;color:var(--richclay-text) !important;display:grid !important;gap:2px !important;inset-block-start:calc(100% + 4px) !important;inset-inline-start:0 !important;min-width:160px !important;padding:4px !important;position:absolute !important;z-index:1000 !important}\n.richclay-menu[hidden]{display:none !important}\n.richclay-menu-item{appearance:none !important;background:transparent !important;border:1px solid transparent !important;border-radius:4px !important;color:inherit !important;font:inherit !important;min-height:32px !important;padding:5px 9px !important;text-align:start !important}\n.richclay-float{left:0 !important;position:fixed !important;top:0 !important;will-change:transform !important;z-index:99999 !important}\n.richclay-float .richclay-toolbar{box-shadow:var(--richclay-shadow) !important;margin-block:0 !important}\n.richclay-float-rail .richclay-toolbar{--richclay-control-size:28px !important;flex-direction:column !important;flex-wrap:nowrap !important}\n.richclay-float-rail .richclay-toolbar svg{height:15px !important;width:15px !important}\n.richclay-float-rail .richclay-separator{align-self:stretch !important;height:1px !important;margin:4px 5px !important;width:auto !important}\n.richclay-float-rail .richclay-menu{inset-block-start:0 !important;inset-inline-start:calc(100% + 4px) !important}\n.richclay-dialog{background:var(--richclay-surface) !important;border:1px solid var(--richclay-border) !important;border-radius:var(--richclay-radius) !important;box-shadow:var(--richclay-shadow) !important;color:var(--richclay-text) !important;display:grid !important;gap:10px !important;box-sizing:border-box !important;width:min(420px, calc(100vw - 16px)) !important;z-index:99999 !important;padding:12px !important}\n.richclay-dialog-title{font-weight:650 !important}\n.richclay-field{display:grid !important;gap:4px !important}\n.richclay-field span{color:var(--richclay-muted) !important;font-size:0.875rem !important}\n.richclay-input{background:var(--richclay-surface) !important;border:1px solid var(--richclay-border) !important;border-radius:4px !important;color:var(--richclay-text) !important;font:inherit !important;min-height:36px !important;padding:6px 8px !important}\n.richclay-dialog-actions{display:flex !important;gap:8px !important;justify-content:flex-end !important}\n.richclay-primary,.richclay-secondary{appearance:none !important;border:1px solid var(--richclay-border) !important;border-radius:4px !important;font:inherit !important;min-height:34px !important;padding:5px 10px !important}\n.richclay-primary{background:var(--richclay-accent) !important;border-color:var(--richclay-accent) !important;color:var(--richclay-accent-ink) !important}\n.richclay-secondary{background:var(--richclay-surface-alt) !important;color:var(--richclay-text) !important}\n.richclay-sr-only{border:0 !important;clip:rect(0 0 0 0) !important;clip-path:inset(50%) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:1px !important}\n@media (forced-colors: active){\n.richclay-toolbar,.richclay-menu,.richclay-input{border-color:CanvasText !important}\n.richclay-dialog{border-color:CanvasText !important}\n.richclay-button.is-active,.richclay-button[aria-pressed=\"true\"],.richclay-menu-item.is-active,.richclay-primary{background:Highlight !important;color:HighlightText !important}\n.richclay-button:focus-visible,.richclay-menu-item:focus-visible,.richclay-input:focus-visible{outline-color:Highlight !important}\n}\n.richclay-toolbar[hidden]{display:none !important}\n.richclay-button[hidden]{display:none !important}\n.richclay-separator[hidden]{display:none !important}\n.richclay-menu-wrap[hidden]{display:none !important}\n.richclay-menu[hidden]{display:none !important}\n.richclay-dialog[hidden]{display:none !important}\n.richclay-field[hidden]{display:none !important}\n.richclay-dialog-actions[hidden]{display:none !important}\n}";
|
|
4
|
+
export const CSS = "@layer clay-skin{\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog),:is(.richclay-toolbar, .richclay-float, .richclay-dialog) *{--richclay-surface:light-dark(#FFFCF6, #11131E) !important;--richclay-surface-alt:light-dark(#F4ECDF, #1A1D2C) !important;--richclay-text:light-dark(#2B241B, #ECEAF2) !important;--richclay-muted:light-dark(#6B5942, #8A90AB) !important;--richclay-border:light-dark(#D8C8AF, #353B52) !important;--richclay-accent:light-dark(#8F6310, #D9A445) !important;--richclay-accent-ink:light-dark(#FDF8F0, #0B0C13) !important;--richclay-focus:light-dark(#8F6310, #D9A445) !important;--richclay-danger:light-dark(#A83A2C, #FF5566) !important;--richclay-radius:0px !important;--richclay-control-size:32px !important;--richclay-shadow:0 1px 2px rgba(0,0,0,.12),0 10px 28px -12px rgba(0,0,0,.35) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog){font-family:system-ui,-apple-system,\"Segoe UI\",sans-serif !important}\n:where(.richclay-float, .richclay-dialog):is(.richclay-toolbar, .richclay-float, .richclay-dialog){color:light-dark(#2B241B, #ECEAF2) !important;background:light-dark(#FFFCF6, #11131E) !important;border:1px solid light-dark(#D8C8AF, #353B52) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-toolbar{gap:3px !important;margin:0 !important;padding:8px !important;border:1px solid light-dark(#D8C8AF, #353B52) !important;border-radius:0 !important;background:light-dark(#F4ECDF, #1A1D2C) !important;color:light-dark(#2B241B, #ECEAF2) !important}\n.richclay-toolbar:is(.richclay-toolbar, .richclay-float, .richclay-dialog){gap:3px !important;padding:8px !important;border:1px solid light-dark(#D8C8AF, #353B52) !important;border-radius:0 !important;background:light-dark(#F4ECDF, #1A1D2C) !important;color:light-dark(#2B241B, #ECEAF2) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-button{min-width:32px !important;height:32px !important;padding:0 7px !important;gap:6px !important;border:2px solid !important;border-color:light-dark(#FFF9ED, #3C4260) light-dark(#D6C3A5, #1B2033) light-dark(#D6C3A5, #1B2033) light-dark(#FFF9ED, #3C4260) !important;border-radius:0 !important;background:light-dark(#F1E7D4, #22273E) !important;font:14px system-ui,-apple-system,\"Segoe UI\",sans-serif !important;cursor:pointer !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-button:is([aria-pressed=\"true\"], [aria-expanded=\"true\"]){background:light-dark(#E3D0B3, #28304D) !important;border-color:light-dark(#B89F7B, #1F2339) light-dark(#F0E1C9, #4D587A) light-dark(#F0E1C9, #4D587A) light-dark(#B89F7B, #1F2339) !important;box-shadow:none !important;color:light-dark(#2B241B, #ECEAF2) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-button[aria-pressed=\"true\"] > svg{translate:1px 1px !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-button:disabled{opacity:.45 !important;cursor:not-allowed !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-button:hover:not([aria-pressed=\"true\"], [aria-expanded=\"true\"], :disabled){border-color:light-dark(#FFF9ED, #3C4260) light-dark(#D6C3A5, #1B2033) light-dark(#D6C3A5, #1B2033) light-dark(#FFF9ED, #3C4260) !important;background:color-mix(in srgb, light-dark(#F1E7D4, #22273E), light-dark(#FFF9ED, #3C4260) 45%) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-separator{align-self:center !important;height:22px !important;margin:0 5px !important;background:light-dark(#D8C8AF, #353B52) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-menu{inset-block-start:38px !important;min-width:210px !important;padding:5px !important;border-radius:0 !important;box-shadow:0 1px 2px rgba(0,0,0,.12),0 10px 28px -12px rgba(0,0,0,.35) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-menu-item{padding:8px 10px !important;border:0 !important;border-radius:0 !important;font:14px system-ui,-apple-system,\"Segoe UI\",sans-serif !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-menu-item[aria-checked=\"true\"]{background:light-dark(#F4ECDF, #1A1D2C) !important;box-shadow:inset 2px 0 light-dark(#8F6310, #D9A445) !important}\n.richclay-dialog:is(.richclay-toolbar, .richclay-float, .richclay-dialog){width:min(100%, 360px) !important;padding:14px 16px 12px !important;border:1px solid light-dark(#D8C8AF, #353B52) !important;border-radius:0 !important;background:light-dark(#FFFCF6, #11131E) !important;color:light-dark(#2B241B, #ECEAF2) !important;box-shadow:0 1px 2px rgba(0,0,0,.12),0 10px 28px -12px rgba(0,0,0,.35) !important}\n.richclay-dialog:is(.richclay-toolbar, .richclay-float, .richclay-dialog)::before{content:\"\" !important;position:absolute !important;left:calc(var(--richclay-dialog-arrow, 28px) - 6px) !important;top:-7px !important;width:12px !important;height:12px !important;background:light-dark(#FFFCF6, #11131E) !important;border-top:1px solid light-dark(#D8C8AF, #353B52) !important;border-left:1px solid light-dark(#D8C8AF, #353B52) !important;transform:rotate(45deg) !important}\n.richclay-dialog:is(.richclay-toolbar, .richclay-float, .richclay-dialog)[data-richclay-side=\"above\"]::before{top:auto !important;bottom:-7px !important;border:0 !important;border-right:1px solid light-dark(#D8C8AF, #353B52) !important;border-bottom:1px solid light-dark(#D8C8AF, #353B52) !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-dialog-title{margin-bottom:2px !important;font:500 10px ui-monospace,SFMono-Regular,Menlo,Consolas,monospace !important;text-transform:uppercase !important;letter-spacing:.12em !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-field{gap:5px !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-field > span{color:light-dark(#4A4033, #C9CDE0) !important;font-size:12px !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-input{min-height:30px !important;padding:4px 8px !important;border:2px solid !important;border-color:light-dark(#B89F7B, #1F2339) light-dark(#F0E1C9, #4D587A) light-dark(#F0E1C9, #4D587A) light-dark(#B89F7B, #1F2339) !important;border-radius:0 !important;background:light-dark(#F4ECDF, #1A1D2C) !important;color:light-dark(#2B241B, #ECEAF2) !important;font:13px system-ui,-apple-system,\"Segoe UI\",sans-serif !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-dialog-actions{margin-top:4px !important;padding-top:12px !important;border-top:1px solid light-dark(#E8DCC6, #262B42) !important;flex-wrap:wrap !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) :is(.richclay-primary, .richclay-secondary){min-height:30px !important;padding:4px 10px !important;border:2px solid !important;border-color:light-dark(#FFF9ED, #3C4260) light-dark(#D6C3A5, #1B2033) light-dark(#D6C3A5, #1B2033) light-dark(#FFF9ED, #3C4260) !important;border-radius:0 !important;background:light-dark(#F1E7D4, #22273E) !important;color:light-dark(#2B241B, #ECEAF2) !important;font:13px system-ui,-apple-system,\"Segoe UI\",sans-serif !important}\n:is(.richclay-toolbar, .richclay-float, .richclay-dialog) .richclay-primary{background:light-dark(#2B241B, #ECEAF2) !important;color:light-dark(#FDF8F0, #0B0C13) !important;border-color:color-mix(in srgb, light-dark(#2B241B, #ECEAF2), white 24%) color-mix(in srgb, light-dark(#2B241B, #ECEAF2), black 32%) color-mix(in srgb, light-dark(#2B241B, #ECEAF2), black 32%) color-mix(in srgb, light-dark(#2B241B, #ECEAF2), white 24%) !important}\n.richclay-float:is(.richclay-toolbar, .richclay-float, .richclay-dialog){border-radius:0 !important;box-shadow:0 1px 2px rgba(0,0,0,.12),0 10px 28px -12px rgba(0,0,0,.35) !important}\n.richclay-float:is(.richclay-toolbar, .richclay-float, .richclay-dialog) > .richclay-toolbar{padding:5px !important}\n.richclay-toolbar{align-items:center !important;background:var(--richclay-surface-alt) !important;border:1px solid var(--richclay-border) !important;border-radius:var(--richclay-radius) !important;color:var(--richclay-text) !important;display:flex !important;flex-wrap:wrap !important;gap:2px !important;margin-block:0 6px !important;padding:4px !important}\n.richclay-toolbar:has(+ .richclay-editor){margin-block-end:0 !important;border-bottom-left-radius:0 !important;border-bottom-right-radius:0 !important}\n.richclay-button{align-items:center !important;appearance:none !important;background:transparent !important;border:1px solid transparent !important;border-radius:5px !important;color:currentColor !important;display:inline-flex !important;height:var(--richclay-control-size) !important;justify-content:center !important;margin:0 !important;min-width:var(--richclay-control-size) !important;padding:0 !important;position:relative !important}\n.richclay-button:hover,.richclay-button[aria-expanded=\"true\"],.richclay-menu-item:hover{background:var(--richclay-surface) !important;border-color:var(--richclay-border) !important}\n.richclay-button.is-active,.richclay-button[aria-pressed=\"true\"],.richclay-menu-item.is-active{background:rgb(0 0 0 / 0.13) !important;border-color:rgb(0 0 0 / 0.22) !important;color:var(--richclay-text) !important;box-shadow:inset 0 1px 3px rgb(0 0 0 / 0.26) !important}\n.richclay-button:focus-visible,.richclay-menu-item:focus-visible,.richclay-input:focus-visible,.richclay-primary:focus-visible,.richclay-secondary:focus-visible{outline:3px solid var(--richclay-focus) !important;outline-offset:2px !important}\n.richclay-button:disabled{color:var(--richclay-muted) !important;cursor:not-allowed !important;opacity:0.55 !important}\n.richclay-separator{align-self:stretch !important;background:var(--richclay-border) !important;display:inline-block !important;margin:5px 4px !important;width:1px !important}\n.richclay-menu-wrap{display:inline-flex !important;position:relative !important}\n.richclay-menu{background:var(--richclay-surface) !important;border:1px solid var(--richclay-border) !important;border-radius:var(--richclay-radius) !important;box-shadow:var(--richclay-shadow) !important;color:var(--richclay-text) !important;display:grid !important;gap:2px !important;inset-block-start:calc(100% + 4px) !important;inset-inline-start:0 !important;min-width:160px !important;padding:4px !important;position:absolute !important;z-index:1000 !important}\n.richclay-menu[hidden]{display:none !important}\n.richclay-menu-item{align-items:center !important;appearance:none !important;background:transparent !important;border:1px solid transparent !important;border-radius:4px !important;color:inherit !important;display:flex !important;font:inherit !important;gap:8px !important;min-height:32px !important;padding:5px 9px !important;text-align:start !important}\n.richclay-float{left:0 !important;position:fixed !important;top:0 !important;will-change:transform !important;z-index:99999 !important}\n.richclay-float .richclay-toolbar{box-shadow:var(--richclay-shadow) !important;margin-block:0 !important}\n.richclay-float-rail .richclay-toolbar{--richclay-control-size:28px !important;flex-direction:column !important;flex-wrap:nowrap !important}\n.richclay-float-rail .richclay-toolbar svg{height:15px !important;width:15px !important}\n.richclay-float-rail .richclay-separator{align-self:stretch !important;height:1px !important;margin:4px 5px !important;width:auto !important}\n.richclay-float-rail .richclay-menu{inset-block-start:0 !important;inset-inline-start:calc(100% + 4px) !important}\n.richclay-dialog{background:var(--richclay-surface) !important;border:1px solid var(--richclay-border) !important;border-radius:var(--richclay-radius) !important;box-shadow:var(--richclay-shadow) !important;color:var(--richclay-text) !important;display:grid !important;gap:10px !important;box-sizing:border-box !important;width:min(420px, calc(100vw - 16px)) !important;z-index:99999 !important;padding:12px !important}\n.richclay-dialog-title{font-weight:650 !important}\n.richclay-field{display:grid !important;gap:4px !important}\n.richclay-field span{color:var(--richclay-muted) !important;font-size:0.875rem !important}\n.richclay-input{background:var(--richclay-surface) !important;border:1px solid var(--richclay-border) !important;border-radius:4px !important;color:var(--richclay-text) !important;font:inherit !important;min-height:36px !important;padding:6px 8px !important}\n.richclay-dialog-actions{display:flex !important;gap:8px !important;justify-content:flex-end !important}\n.richclay-dialog-actions [data-richclay-remove-link]{margin-inline-end:auto !important}\n.richclay-primary,.richclay-secondary{appearance:none !important;border:1px solid var(--richclay-border) !important;border-radius:4px !important;font:inherit !important;min-height:34px !important;padding:5px 10px !important}\n.richclay-primary{background:var(--richclay-accent) !important;border-color:var(--richclay-accent) !important;color:var(--richclay-accent-ink) !important}\n.richclay-secondary{background:var(--richclay-surface-alt) !important;color:var(--richclay-text) !important}\n.richclay-sr-only{border:0 !important;clip:rect(0 0 0 0) !important;clip-path:inset(50%) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:1px !important}\n@media (forced-colors: active){\n.richclay-toolbar,.richclay-menu,.richclay-input{border-color:CanvasText !important}\n.richclay-dialog{border-color:CanvasText !important}\n.richclay-button.is-active,.richclay-button[aria-pressed=\"true\"],.richclay-menu-item.is-active,.richclay-primary{background:Highlight !important;color:HighlightText !important}\n.richclay-button:focus-visible,.richclay-menu-item:focus-visible,.richclay-input:focus-visible{outline-color:Highlight !important}\n}\n.richclay-toolbar[hidden]{display:none !important}\n.richclay-button[hidden]{display:none !important}\n.richclay-separator[hidden]{display:none !important}\n.richclay-menu-wrap[hidden]{display:none !important}\n.richclay-menu[hidden]{display:none !important}\n.richclay-menu-item[hidden]{display:none !important}\n.richclay-dialog[hidden]{display:none !important}\n.richclay-field[hidden]{display:none !important}\n.richclay-dialog-actions[hidden]{display:none !important}\n}";
|
package/src/ui/toast.js
CHANGED
|
@@ -2,27 +2,19 @@
|
|
|
2
2
|
// ❗️ don't use too much text!
|
|
3
3
|
//
|
|
4
4
|
// The Hyperclay dashboard's toast (Bevel's React toast with the dashboard's overrides),
|
|
5
|
-
// drawn inline: a 3px tone edge, a 16px
|
|
5
|
+
// drawn inline: a 3px tone edge, a 16px Bevel glyph, 13.5px semibold text, a quiet close.
|
|
6
6
|
import { set } from "../lib/hostile-css.js";
|
|
7
7
|
import { bevelBox, bevelSurface, bevelText, pageScheme, protectIcon } from "./bevel-controls.js";
|
|
8
|
-
import { TOKENS, RULES } from "./bevel.js";
|
|
9
|
-
|
|
10
|
-
const icon = (d) =>
|
|
11
|
-
`<svg viewBox="0 0 256 256" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="${d}"/></svg>`;
|
|
12
|
-
|
|
13
|
-
const CHECK = "M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z";
|
|
14
|
-
const WARNING = "M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1-7.48,4.2H40.55a8.5,8.5,0,0,1-7.48-4.2,7.59,7.59,0,0,1,0-7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,180Z";
|
|
15
|
-
const INFO = "M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z";
|
|
16
|
-
const X = "M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z";
|
|
8
|
+
import { TOKENS, RULES, GLYPHS } from "./bevel.js";
|
|
17
9
|
|
|
18
10
|
const TONES = {
|
|
19
|
-
success: { edge: TOKENS.teal, icon:
|
|
20
|
-
error: { edge: TOKENS.ox, icon:
|
|
21
|
-
warning: { edge: TOKENS.brass, icon:
|
|
22
|
-
info: { edge: TOKENS.brass, icon:
|
|
11
|
+
success: { edge: TOKENS.teal, icon: GLYPHS.toastSuccess },
|
|
12
|
+
error: { edge: TOKENS.ox, icon: GLYPHS.toastWarning },
|
|
13
|
+
warning: { edge: TOKENS.brass, icon: GLYPHS.toastWarning },
|
|
14
|
+
info: { edge: TOKENS.brass, icon: GLYPHS.toastInfo },
|
|
23
15
|
};
|
|
24
16
|
|
|
25
|
-
const CLOSE_ICON =
|
|
17
|
+
const CLOSE_ICON = GLYPHS.toastClose;
|
|
26
18
|
|
|
27
19
|
const HIDDEN = ["opacity:0", "transform:translateX(24px)"];
|
|
28
20
|
|