@einblick/sdk 0.6.4 → 0.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/AGENTS.md +1 -1
- package/README.md +48 -2
- package/dist/next/edit-boot.d.ts +6 -3
- package/dist/next/edit-boot.d.ts.map +1 -1
- package/dist/next/edit-boot.js +10 -4
- package/dist/next/edit-boot.js.map +1 -1
- package/dist/react/markers.d.ts +5 -1
- package/dist/react/markers.d.ts.map +1 -1
- package/dist/react/markers.js +23 -6
- package/dist/react/markers.js.map +1 -1
- package/dist/react/provider.d.ts +1 -1
- package/dist/react/provider.d.ts.map +1 -1
- package/dist/react/provider.js +6 -1
- package/dist/react/provider.js.map +1 -1
- package/dist/react/runtime.d.ts +2 -0
- package/dist/react/runtime.d.ts.map +1 -1
- package/dist/react/runtime.js +273 -91
- package/dist/react/runtime.js.map +1 -1
- package/dist/react/shared.d.ts.map +1 -1
- package/dist/react/shared.js +0 -2
- package/dist/react/shared.js.map +1 -1
- package/dist/react/types.d.ts +1 -0
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/types.js.map +1 -1
- package/package.json +8 -8
package/dist/react/runtime.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { EINBLICK_AUTH_SOURCE, EINBLICK_BRIDGE_SOURCE, EINBLICK_EDITOR_SOURCE, EINBLICK_PARENT_SOURCE, formatValueForText, isMediaEditableBinding, isEditSessionExpired, readBindingFromElement, resolveAppOrigin, serializeBindingValue, shouldUseInlineEditor, } from './shared.js';
|
|
2
2
|
import { getEinblickSdkMessages, resolveEinblickSdkLocale, } from './i18n.js';
|
|
3
3
|
const RUNTIME_STYLE_ID = 'einblick-edit-runtime-styles';
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
4
|
+
const DEFAULT_EINBLICK_ACCENT_COLOR = 'rgb(250, 105, 62)';
|
|
5
|
+
const EINBLICK_ACCENT_COLOR_VAR = '--einblick-editor-accent-color';
|
|
6
|
+
const EINBLICK_ACCENT_COLOR = `var(${EINBLICK_ACCENT_COLOR_VAR}, ${DEFAULT_EINBLICK_ACCENT_COLOR})`;
|
|
7
|
+
const EINBLICK_ACCENT_TINT = `color-mix(in srgb, ${EINBLICK_ACCENT_COLOR} 12%, transparent)`;
|
|
8
|
+
const EINBLICK_ACCENT_HOVER_COLOR = `color-mix(in srgb, ${EINBLICK_ACCENT_COLOR} 92%, black)`;
|
|
7
9
|
const CONTROL_BAR_HEIGHT = 44;
|
|
8
10
|
function getBrandBadgeSvg(size) {
|
|
9
11
|
return `
|
|
@@ -40,6 +42,30 @@ function getMoreActionsSvg(size) {
|
|
|
40
42
|
</svg>
|
|
41
43
|
`;
|
|
42
44
|
}
|
|
45
|
+
function createDatabaseIconElement(size) {
|
|
46
|
+
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
47
|
+
svg.setAttribute('viewBox', '0 0 24 24');
|
|
48
|
+
svg.setAttribute('width', String(size));
|
|
49
|
+
svg.setAttribute('height', String(size));
|
|
50
|
+
svg.setAttribute('fill', 'none');
|
|
51
|
+
svg.setAttribute('stroke', 'currentColor');
|
|
52
|
+
svg.setAttribute('stroke-width', '2');
|
|
53
|
+
svg.setAttribute('stroke-linecap', 'round');
|
|
54
|
+
svg.setAttribute('stroke-linejoin', 'round');
|
|
55
|
+
svg.setAttribute('aria-hidden', 'true');
|
|
56
|
+
svg.setAttribute('focusable', 'false');
|
|
57
|
+
const ellipse = document.createElementNS('http://www.w3.org/2000/svg', 'ellipse');
|
|
58
|
+
ellipse.setAttribute('cx', '12');
|
|
59
|
+
ellipse.setAttribute('cy', '5');
|
|
60
|
+
ellipse.setAttribute('rx', '9');
|
|
61
|
+
ellipse.setAttribute('ry', '3');
|
|
62
|
+
const sidePath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
63
|
+
sidePath.setAttribute('d', 'M3 5V19A9 3 0 0 0 21 19V5');
|
|
64
|
+
const middlePath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
65
|
+
middlePath.setAttribute('d', 'M3 12A9 3 0 0 0 21 12');
|
|
66
|
+
svg.append(ellipse, sidePath, middlePath);
|
|
67
|
+
return svg;
|
|
68
|
+
}
|
|
43
69
|
function createRandomId() {
|
|
44
70
|
if (typeof crypto !== 'undefined' &&
|
|
45
71
|
typeof crypto.randomUUID === 'function') {
|
|
@@ -54,6 +80,24 @@ function stopEvent(event) {
|
|
|
54
80
|
function clamp(value, min, max) {
|
|
55
81
|
return Math.min(Math.max(value, min), max);
|
|
56
82
|
}
|
|
83
|
+
function rectsOverlap(first, second, padding = 0) {
|
|
84
|
+
return (first.left < second.right + padding &&
|
|
85
|
+
first.right > second.left - padding &&
|
|
86
|
+
first.top < second.bottom + padding &&
|
|
87
|
+
first.bottom > second.top - padding);
|
|
88
|
+
}
|
|
89
|
+
function normalizeAccentColor(accentColor) {
|
|
90
|
+
const normalized = accentColor?.trim();
|
|
91
|
+
if (!normalized) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
if (typeof CSS !== 'undefined' &&
|
|
95
|
+
typeof CSS.supports === 'function' &&
|
|
96
|
+
!CSS.supports('color', normalized)) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return normalized;
|
|
100
|
+
}
|
|
57
101
|
function isTextInputEvent(event) {
|
|
58
102
|
return (event.key.length === 1 ||
|
|
59
103
|
event.key === 'Enter' ||
|
|
@@ -67,15 +111,37 @@ function fieldTypeAllowsMultiline(binding) {
|
|
|
67
111
|
return binding.fieldType === 'text' || binding.fieldType === 'markdown';
|
|
68
112
|
}
|
|
69
113
|
function getMediaAcceptValue(binding) {
|
|
70
|
-
return binding.fieldType === 'image'
|
|
71
|
-
? 'image/*'
|
|
72
|
-
: '';
|
|
114
|
+
return binding.fieldType === 'image' ? 'image/*' : '';
|
|
73
115
|
}
|
|
74
116
|
function getMediaActionLabel(binding, messages) {
|
|
75
|
-
return binding.fieldType === 'image'
|
|
117
|
+
return binding.fieldType === 'image'
|
|
76
118
|
? messages.actions.replaceImage
|
|
77
119
|
: messages.actions.replaceFile;
|
|
78
120
|
}
|
|
121
|
+
function isMultiMediaBinding(binding) {
|
|
122
|
+
return binding?.fieldType === 'images' || binding?.fieldType === 'files';
|
|
123
|
+
}
|
|
124
|
+
function setOverlayButtonContent(button, label, options) {
|
|
125
|
+
const hasDatabaseIcon = options?.databaseIcon === true;
|
|
126
|
+
if (button.dataset.einblickOverlayButtonLabel === label &&
|
|
127
|
+
button.dataset.einblickOverlayButtonDatabaseIcon ===
|
|
128
|
+
(hasDatabaseIcon ? 'true' : 'false')) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const text = document.createElement('span');
|
|
132
|
+
text.setAttribute('data-einblick-overlay-button-label', 'true');
|
|
133
|
+
text.textContent = label;
|
|
134
|
+
button.replaceChildren();
|
|
135
|
+
if (hasDatabaseIcon) {
|
|
136
|
+
button.append(createDatabaseIconElement(14));
|
|
137
|
+
}
|
|
138
|
+
button.append(text);
|
|
139
|
+
button.title = label;
|
|
140
|
+
button.dataset.einblickOverlayButtonLabel = label;
|
|
141
|
+
button.dataset.einblickOverlayButtonDatabaseIcon = hasDatabaseIcon
|
|
142
|
+
? 'true'
|
|
143
|
+
: 'false';
|
|
144
|
+
}
|
|
79
145
|
function injectRuntimeStyles() {
|
|
80
146
|
if (typeof document === 'undefined') {
|
|
81
147
|
return;
|
|
@@ -91,13 +157,12 @@ function injectRuntimeStyles() {
|
|
|
91
157
|
}
|
|
92
158
|
|
|
93
159
|
[data-einblick-editable="true"][data-einblick-hover-active="true"] {
|
|
94
|
-
outline: 1px solid ${
|
|
160
|
+
outline: 1px solid ${EINBLICK_ACCENT_COLOR};
|
|
95
161
|
outline-offset: -1px;
|
|
96
|
-
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.72);
|
|
97
162
|
}
|
|
98
163
|
|
|
99
164
|
[data-einblick-editable="true"][data-einblick-field-hover-active="true"] {
|
|
100
|
-
outline: 1px dashed
|
|
165
|
+
outline: 1px dashed ${EINBLICK_ACCENT_COLOR};
|
|
101
166
|
outline-offset: -1px;
|
|
102
167
|
}
|
|
103
168
|
|
|
@@ -111,43 +176,46 @@ function injectRuntimeStyles() {
|
|
|
111
176
|
z-index: 2147483644;
|
|
112
177
|
display: inline-flex;
|
|
113
178
|
align-items: center;
|
|
114
|
-
gap: 0;
|
|
179
|
+
gap: 0.25rem;
|
|
115
180
|
}
|
|
116
181
|
|
|
117
182
|
[data-einblick-edit-button],
|
|
118
|
-
[data-einblick-create-button],
|
|
183
|
+
[data-einblick-collection-create-button],
|
|
119
184
|
[data-einblick-field-button] {
|
|
185
|
+
display: inline-flex;
|
|
186
|
+
align-items: center;
|
|
187
|
+
justify-content: center;
|
|
188
|
+
gap: 0.35rem;
|
|
120
189
|
border: 1px solid ${EINBLICK_ACCENT_COLOR};
|
|
121
190
|
border-radius: 0;
|
|
122
|
-
min-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
box-shadow: 0 8px 18px rgba(15, 23, 42, 0.16);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
[data-einblick-edit-button],
|
|
131
|
-
[data-einblick-field-button="media"] {
|
|
191
|
+
min-width: max-content;
|
|
192
|
+
min-height: 2.05rem;
|
|
193
|
+
max-width: calc(100vw - 0.5rem);
|
|
194
|
+
padding: 0 0.74rem;
|
|
195
|
+
overflow: hidden;
|
|
132
196
|
background: ${EINBLICK_ACCENT_COLOR};
|
|
133
197
|
color: rgb(255, 255, 255);
|
|
198
|
+
font: 700 13px/1 system-ui, sans-serif;
|
|
199
|
+
letter-spacing: 0;
|
|
200
|
+
white-space: nowrap;
|
|
201
|
+
text-overflow: ellipsis;
|
|
202
|
+
cursor: pointer;
|
|
134
203
|
}
|
|
135
204
|
|
|
136
|
-
[data-einblick-edit-button]
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
background: rgb(255, 255, 255);
|
|
143
|
-
color: ${EINBLICK_ACCENT_COLOR};
|
|
205
|
+
[data-einblick-edit-button] svg,
|
|
206
|
+
[data-einblick-collection-create-button] svg,
|
|
207
|
+
[data-einblick-field-button] svg {
|
|
208
|
+
flex: none;
|
|
209
|
+
width: 0.95rem;
|
|
210
|
+
height: 0.95rem;
|
|
144
211
|
}
|
|
145
212
|
|
|
146
213
|
[data-einblick-edit-button]:hover,
|
|
147
|
-
[data-einblick-create-button]:hover,
|
|
214
|
+
[data-einblick-collection-create-button]:hover,
|
|
148
215
|
[data-einblick-field-button]:hover {
|
|
149
|
-
background:
|
|
150
|
-
|
|
216
|
+
background: ${EINBLICK_ACCENT_COLOR};
|
|
217
|
+
background: ${EINBLICK_ACCENT_HOVER_COLOR};
|
|
218
|
+
color: rgb(255, 255, 255);
|
|
151
219
|
}
|
|
152
220
|
|
|
153
221
|
[data-einblick-field-overlays] {
|
|
@@ -162,8 +230,6 @@ function injectRuntimeStyles() {
|
|
|
162
230
|
position: absolute;
|
|
163
231
|
z-index: 2147483644;
|
|
164
232
|
pointer-events: auto;
|
|
165
|
-
font-size: 11px;
|
|
166
|
-
min-height: 1.65rem;
|
|
167
233
|
}
|
|
168
234
|
|
|
169
235
|
[data-einblick-brand-badge] {
|
|
@@ -182,17 +248,15 @@ function injectRuntimeStyles() {
|
|
|
182
248
|
background: transparent;
|
|
183
249
|
color: ${EINBLICK_ACCENT_COLOR};
|
|
184
250
|
cursor: pointer;
|
|
185
|
-
|
|
186
|
-
transition: transform 120ms ease, filter 120ms ease;
|
|
251
|
+
transition: transform 120ms ease;
|
|
187
252
|
}
|
|
188
253
|
|
|
189
254
|
[data-einblick-brand-badge]:hover {
|
|
190
255
|
transform: translateY(-1px) scale(1.04);
|
|
191
|
-
filter: drop-shadow(0 12px 28px rgba(15, 23, 42, 0.28));
|
|
192
256
|
}
|
|
193
257
|
|
|
194
258
|
[data-einblick-brand-badge]:focus-visible {
|
|
195
|
-
outline: 2px solid ${
|
|
259
|
+
outline: 2px solid ${EINBLICK_ACCENT_COLOR};
|
|
196
260
|
outline-offset: 4px;
|
|
197
261
|
border-radius: 999px;
|
|
198
262
|
}
|
|
@@ -212,7 +276,6 @@ function injectRuntimeStyles() {
|
|
|
212
276
|
color: rgb(15, 23, 42);
|
|
213
277
|
border-radius: 1.25rem;
|
|
214
278
|
padding: 1rem;
|
|
215
|
-
box-shadow: 0 22px 56px rgba(15, 23, 42, 0.2);
|
|
216
279
|
backdrop-filter: blur(18px);
|
|
217
280
|
box-sizing: border-box;
|
|
218
281
|
}
|
|
@@ -262,7 +325,8 @@ function injectRuntimeStyles() {
|
|
|
262
325
|
display: inline-flex;
|
|
263
326
|
align-items: center;
|
|
264
327
|
border-radius: 999px;
|
|
265
|
-
background:
|
|
328
|
+
background: transparent;
|
|
329
|
+
background: ${EINBLICK_ACCENT_TINT};
|
|
266
330
|
color: ${EINBLICK_ACCENT_COLOR};
|
|
267
331
|
padding: 0.32rem 0.58rem;
|
|
268
332
|
font: 600 0.74rem/1 system-ui, sans-serif;
|
|
@@ -311,7 +375,8 @@ function injectRuntimeStyles() {
|
|
|
311
375
|
|
|
312
376
|
[data-einblick-brand-popover-action="primary"]:hover {
|
|
313
377
|
border-color: ${EINBLICK_ACCENT_COLOR};
|
|
314
|
-
background:
|
|
378
|
+
background: ${EINBLICK_ACCENT_COLOR};
|
|
379
|
+
background: ${EINBLICK_ACCENT_HOVER_COLOR};
|
|
315
380
|
}
|
|
316
381
|
|
|
317
382
|
[data-einblick-inline-editing="true"] {
|
|
@@ -337,7 +402,6 @@ function injectRuntimeStyles() {
|
|
|
337
402
|
width: min(46rem, 100vw);
|
|
338
403
|
background: rgb(255, 255, 255);
|
|
339
404
|
border-left: 1px solid rgba(148, 163, 184, 0.35);
|
|
340
|
-
box-shadow: 0 24px 64px rgba(15, 23, 42, 0.26);
|
|
341
405
|
overflow: hidden;
|
|
342
406
|
}
|
|
343
407
|
|
|
@@ -359,7 +423,6 @@ function injectRuntimeStyles() {
|
|
|
359
423
|
border-top: 1px solid rgba(148, 163, 184, 0.36);
|
|
360
424
|
overflow: hidden;
|
|
361
425
|
background: rgb(255, 255, 255);
|
|
362
|
-
box-shadow: 0 -12px 28px rgba(15, 23, 42, 0.12);
|
|
363
426
|
pointer-events: none;
|
|
364
427
|
transform: translateY(100%);
|
|
365
428
|
transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
|
|
@@ -396,6 +459,8 @@ class EinblickEditRuntime {
|
|
|
396
459
|
reserveBottomSpace;
|
|
397
460
|
locale;
|
|
398
461
|
messages;
|
|
462
|
+
accentColor;
|
|
463
|
+
originalRootAccentColor;
|
|
399
464
|
bridgeNonce = createRandomId();
|
|
400
465
|
session;
|
|
401
466
|
state = {
|
|
@@ -409,7 +474,6 @@ class EinblickEditRuntime {
|
|
|
409
474
|
activeElement = null;
|
|
410
475
|
hoverButtonContainer = null;
|
|
411
476
|
hoverButton = null;
|
|
412
|
-
hoverCreateButton = null;
|
|
413
477
|
quickFieldOverlayContainer = null;
|
|
414
478
|
quickFieldOverlays = [];
|
|
415
479
|
brandBadge = null;
|
|
@@ -455,6 +519,7 @@ class EinblickEditRuntime {
|
|
|
455
519
|
options.reserveBottomSpace ?? this.chrome === 'bar';
|
|
456
520
|
this.locale = resolveEinblickSdkLocale(options.locale);
|
|
457
521
|
this.messages = getEinblickSdkMessages(this.locale);
|
|
522
|
+
this.accentColor = normalizeAccentColor(options.accentColor);
|
|
458
523
|
this.session =
|
|
459
524
|
options.initialSession && !isEditSessionExpired(options.initialSession)
|
|
460
525
|
? options.initialSession
|
|
@@ -475,6 +540,43 @@ class EinblickEditRuntime {
|
|
|
475
540
|
this.messages = getEinblickSdkMessages(nextLocale);
|
|
476
541
|
this.refreshLocalizedUi();
|
|
477
542
|
}
|
|
543
|
+
setAccentColor(accentColor) {
|
|
544
|
+
const nextAccentColor = normalizeAccentColor(accentColor);
|
|
545
|
+
if (nextAccentColor === this.accentColor) {
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
this.accentColor = nextAccentColor;
|
|
549
|
+
this.applyAccentColor();
|
|
550
|
+
}
|
|
551
|
+
applyAccentColor() {
|
|
552
|
+
if (typeof document === 'undefined') {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
if (!this.accentColor) {
|
|
556
|
+
this.restoreAccentColor();
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
const root = document.documentElement;
|
|
560
|
+
if (this.originalRootAccentColor === undefined) {
|
|
561
|
+
this.originalRootAccentColor =
|
|
562
|
+
root.style.getPropertyValue(EINBLICK_ACCENT_COLOR_VAR) || null;
|
|
563
|
+
}
|
|
564
|
+
root.style.setProperty(EINBLICK_ACCENT_COLOR_VAR, this.accentColor);
|
|
565
|
+
}
|
|
566
|
+
restoreAccentColor() {
|
|
567
|
+
if (typeof document === 'undefined' ||
|
|
568
|
+
this.originalRootAccentColor === undefined) {
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
const root = document.documentElement;
|
|
572
|
+
if (this.originalRootAccentColor) {
|
|
573
|
+
root.style.setProperty(EINBLICK_ACCENT_COLOR_VAR, this.originalRootAccentColor);
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
root.style.removeProperty(EINBLICK_ACCENT_COLOR_VAR);
|
|
577
|
+
}
|
|
578
|
+
this.originalRootAccentColor = undefined;
|
|
579
|
+
}
|
|
478
580
|
start() {
|
|
479
581
|
if (this.started ||
|
|
480
582
|
typeof window === 'undefined' ||
|
|
@@ -482,6 +584,7 @@ class EinblickEditRuntime {
|
|
|
482
584
|
return;
|
|
483
585
|
}
|
|
484
586
|
this.started = true;
|
|
587
|
+
this.applyAccentColor();
|
|
485
588
|
injectRuntimeStyles();
|
|
486
589
|
this.ensureHoverButton();
|
|
487
590
|
if (this.chrome === 'badge') {
|
|
@@ -493,6 +596,7 @@ class EinblickEditRuntime {
|
|
|
493
596
|
window.addEventListener('message', this.handleMessage);
|
|
494
597
|
window.addEventListener('pointerdown', this.handleGlobalPointerDown, true);
|
|
495
598
|
window.addEventListener('pointermove', this.handlePointerMove, true);
|
|
599
|
+
window.addEventListener('click', this.handleCollectionCreateButtonClick, true);
|
|
496
600
|
window.addEventListener('scroll', this.handleViewportChange, true);
|
|
497
601
|
window.addEventListener('resize', this.handleViewportChange);
|
|
498
602
|
window.addEventListener('blur', this.handleWindowBlur);
|
|
@@ -508,12 +612,14 @@ class EinblickEditRuntime {
|
|
|
508
612
|
this.closeInlineEditor();
|
|
509
613
|
}
|
|
510
614
|
this.updateBottomBarResources();
|
|
615
|
+
this.updateCollectionCreateButtons();
|
|
511
616
|
});
|
|
512
617
|
this.mutationObserver.observe(document.body, {
|
|
513
618
|
childList: true,
|
|
514
619
|
subtree: true,
|
|
515
620
|
});
|
|
516
621
|
this.reloadBridge();
|
|
622
|
+
this.updateCollectionCreateButtons();
|
|
517
623
|
}
|
|
518
624
|
destroy() {
|
|
519
625
|
if (this.destroyed) {
|
|
@@ -524,6 +630,7 @@ class EinblickEditRuntime {
|
|
|
524
630
|
window.removeEventListener('message', this.handleMessage);
|
|
525
631
|
window.removeEventListener('pointerdown', this.handleGlobalPointerDown, true);
|
|
526
632
|
window.removeEventListener('pointermove', this.handlePointerMove, true);
|
|
633
|
+
window.removeEventListener('click', this.handleCollectionCreateButtonClick, true);
|
|
527
634
|
window.removeEventListener('scroll', this.handleViewportChange, true);
|
|
528
635
|
window.removeEventListener('resize', this.handleViewportChange);
|
|
529
636
|
window.removeEventListener('blur', this.handleWindowBlur);
|
|
@@ -543,8 +650,6 @@ class EinblickEditRuntime {
|
|
|
543
650
|
this.hoverButtonContainer = null;
|
|
544
651
|
this.hoverButton?.remove();
|
|
545
652
|
this.hoverButton = null;
|
|
546
|
-
this.hoverCreateButton?.remove();
|
|
547
|
-
this.hoverCreateButton = null;
|
|
548
653
|
this.clearQuickFieldOverlays();
|
|
549
654
|
this.brandBadge?.remove();
|
|
550
655
|
this.brandBadge = null;
|
|
@@ -567,6 +672,7 @@ class EinblickEditRuntime {
|
|
|
567
672
|
this.closeInlineEditor();
|
|
568
673
|
this.removeNavigatorPanel(false);
|
|
569
674
|
this.closeDrawer();
|
|
675
|
+
this.restoreAccentColor();
|
|
570
676
|
if (this.pendingLogin) {
|
|
571
677
|
if (this.pendingLogin.closePollId !== null) {
|
|
572
678
|
window.clearInterval(this.pendingLogin.closePollId);
|
|
@@ -597,9 +703,6 @@ class EinblickEditRuntime {
|
|
|
597
703
|
if (this.hoverButton) {
|
|
598
704
|
this.updateHoverButtonLabel();
|
|
599
705
|
}
|
|
600
|
-
if (this.hoverCreateButton) {
|
|
601
|
-
this.hoverCreateButton.textContent = this.messages.actions.addRecord;
|
|
602
|
-
}
|
|
603
706
|
if (this.brandBadge) {
|
|
604
707
|
this.brandBadge.setAttribute('aria-label', this.messages.brand.quickActionsLabel);
|
|
605
708
|
this.brandBadge.title = this.messages.brand.quickActionsLabel;
|
|
@@ -616,6 +719,7 @@ class EinblickEditRuntime {
|
|
|
616
719
|
}
|
|
617
720
|
this.updateBrandPopover();
|
|
618
721
|
this.updateBottomBar();
|
|
722
|
+
this.updateCollectionCreateButtons();
|
|
619
723
|
this.updateHoverChrome();
|
|
620
724
|
}
|
|
621
725
|
async login(options) {
|
|
@@ -743,22 +847,31 @@ class EinblickEditRuntime {
|
|
|
743
847
|
!this.shouldShowEditButton(this.activeElement, binding)) {
|
|
744
848
|
return;
|
|
745
849
|
}
|
|
850
|
+
if (binding.fieldKey && isMultiMediaBinding(binding)) {
|
|
851
|
+
this.openDrawer(this.activeElement, binding);
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
746
854
|
if (binding.fieldKey && isMediaEditableBinding(binding)) {
|
|
747
855
|
this.openMediaPicker(this.activeElement, binding, this.hoverButton);
|
|
748
856
|
return;
|
|
749
857
|
}
|
|
750
858
|
this.openEditor(binding, this.activeElement);
|
|
751
859
|
};
|
|
752
|
-
|
|
860
|
+
handleCollectionCreateButtonClick = (event) => {
|
|
861
|
+
const button = this.findCollectionCreateButton(event.target);
|
|
862
|
+
if (!button) {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
753
865
|
stopEvent(event);
|
|
754
|
-
|
|
866
|
+
const collection = this.findCollectionForCreateButton(button);
|
|
867
|
+
if (!collection) {
|
|
755
868
|
return;
|
|
756
869
|
}
|
|
757
|
-
const binding = readBindingFromElement(
|
|
758
|
-
if (!binding || !this.shouldShowCreateButton(
|
|
870
|
+
const binding = readBindingFromElement(collection);
|
|
871
|
+
if (!binding || !this.shouldShowCreateButton(collection, binding)) {
|
|
759
872
|
return;
|
|
760
873
|
}
|
|
761
|
-
this.openDrawer(
|
|
874
|
+
this.openDrawer(collection, binding, 'create');
|
|
762
875
|
};
|
|
763
876
|
handleGlobalPointerDown = (event) => {
|
|
764
877
|
const target = event.target;
|
|
@@ -1044,6 +1157,7 @@ class EinblickEditRuntime {
|
|
|
1044
1157
|
this.updateBrandBadge();
|
|
1045
1158
|
this.updateBrandPopover();
|
|
1046
1159
|
this.updateBottomBar();
|
|
1160
|
+
this.updateCollectionCreateButtons();
|
|
1047
1161
|
if (!nextState.isAuthenticated) {
|
|
1048
1162
|
this.setActiveElement(null);
|
|
1049
1163
|
this.removeNavigatorPanel();
|
|
@@ -1058,26 +1172,18 @@ class EinblickEditRuntime {
|
|
|
1058
1172
|
container.hidden = true;
|
|
1059
1173
|
const editButton = document.createElement('button');
|
|
1060
1174
|
editButton.type = 'button';
|
|
1061
|
-
editButton
|
|
1175
|
+
setOverlayButtonContent(editButton, this.messages.actions.editElement, {
|
|
1176
|
+
databaseIcon: true,
|
|
1177
|
+
});
|
|
1062
1178
|
editButton.setAttribute('data-einblick-edit-button', 'true');
|
|
1063
1179
|
editButton.addEventListener('pointerdown', (event) => {
|
|
1064
1180
|
event.stopPropagation();
|
|
1065
1181
|
});
|
|
1066
1182
|
editButton.addEventListener('click', this.handleHoverButtonClick);
|
|
1067
|
-
|
|
1068
|
-
createButton.type = 'button';
|
|
1069
|
-
createButton.textContent = this.messages.actions.addRecord;
|
|
1070
|
-
createButton.hidden = true;
|
|
1071
|
-
createButton.setAttribute('data-einblick-create-button', 'true');
|
|
1072
|
-
createButton.addEventListener('pointerdown', (event) => {
|
|
1073
|
-
event.stopPropagation();
|
|
1074
|
-
});
|
|
1075
|
-
createButton.addEventListener('click', this.handleCreateButtonClick);
|
|
1076
|
-
container.append(editButton, createButton);
|
|
1183
|
+
container.append(editButton);
|
|
1077
1184
|
document.body.append(container);
|
|
1078
1185
|
this.hoverButtonContainer = container;
|
|
1079
1186
|
this.hoverButton = editButton;
|
|
1080
|
-
this.hoverCreateButton = createButton;
|
|
1081
1187
|
}
|
|
1082
1188
|
ensureBrandBadge() {
|
|
1083
1189
|
if ((this.brandBadge && this.brandPopover) ||
|
|
@@ -1254,7 +1360,7 @@ class EinblickEditRuntime {
|
|
|
1254
1360
|
border: 0;
|
|
1255
1361
|
border-radius: 0.35rem;
|
|
1256
1362
|
background: #ffffff;
|
|
1257
|
-
color:
|
|
1363
|
+
color: ${EINBLICK_ACCENT_COLOR};
|
|
1258
1364
|
padding: 0 0.7rem;
|
|
1259
1365
|
font: 700 0.78rem/1 system-ui, sans-serif;
|
|
1260
1366
|
letter-spacing: 0;
|
|
@@ -1294,7 +1400,6 @@ class EinblickEditRuntime {
|
|
|
1294
1400
|
border-radius: 0.75rem;
|
|
1295
1401
|
background: rgb(255, 255, 255);
|
|
1296
1402
|
color: rgb(15, 23, 42);
|
|
1297
|
-
box-shadow: 0 14px 32px rgba(15, 23, 42, 0.16);
|
|
1298
1403
|
overflow: hidden;
|
|
1299
1404
|
}
|
|
1300
1405
|
|
|
@@ -1736,9 +1841,6 @@ class EinblickEditRuntime {
|
|
|
1736
1841
|
if (this.hoverButton) {
|
|
1737
1842
|
this.hoverButton.hidden = true;
|
|
1738
1843
|
}
|
|
1739
|
-
if (this.hoverCreateButton) {
|
|
1740
|
-
this.hoverCreateButton.hidden = true;
|
|
1741
|
-
}
|
|
1742
1844
|
return;
|
|
1743
1845
|
}
|
|
1744
1846
|
element.dataset.einblickHoverActive = 'true';
|
|
@@ -1774,6 +1876,10 @@ class EinblickEditRuntime {
|
|
|
1774
1876
|
}
|
|
1775
1877
|
this.updateHoverButtonLabel();
|
|
1776
1878
|
this.updateHoverButtonVisibility(this.activeElement);
|
|
1879
|
+
if (this.hoverButtonContainer?.hidden) {
|
|
1880
|
+
this.updateQuickFieldOverlayPositions();
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1777
1883
|
this.positionHoverControls(rect);
|
|
1778
1884
|
this.updateQuickFieldOverlayPositions();
|
|
1779
1885
|
}
|
|
@@ -1822,10 +1928,9 @@ class EinblickEditRuntime {
|
|
|
1822
1928
|
const button = document.createElement('button');
|
|
1823
1929
|
button.type = 'button';
|
|
1824
1930
|
button.setAttribute('data-einblick-field-button', isMediaBinding ? 'media' : 'text');
|
|
1825
|
-
button
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
: this.messages.actions.editText;
|
|
1931
|
+
setOverlayButtonContent(button, isMediaBinding
|
|
1932
|
+
? getMediaActionLabel(binding, this.messages)
|
|
1933
|
+
: this.messages.actions.editText);
|
|
1829
1934
|
button.addEventListener('pointerdown', (event) => {
|
|
1830
1935
|
event.stopPropagation();
|
|
1831
1936
|
});
|
|
@@ -1867,8 +1972,37 @@ class EinblickEditRuntime {
|
|
|
1867
1972
|
const height = overlay.button.offsetHeight || 26;
|
|
1868
1973
|
const scrollX = window.scrollX || document.documentElement.scrollLeft;
|
|
1869
1974
|
const scrollY = window.scrollY || document.documentElement.scrollTop;
|
|
1870
|
-
|
|
1871
|
-
|
|
1975
|
+
let left = clamp(rect.right + scrollX - width, scrollX, Math.max(scrollX, scrollX + window.innerWidth - width));
|
|
1976
|
+
let top = clamp(rect.top + scrollY, scrollY, Math.max(scrollY, scrollY + window.innerHeight - height));
|
|
1977
|
+
const hoverControlsRect = this.hoverButtonContainer && !this.hoverButtonContainer.hidden
|
|
1978
|
+
? this.hoverButtonContainer.getBoundingClientRect()
|
|
1979
|
+
: null;
|
|
1980
|
+
if (hoverControlsRect) {
|
|
1981
|
+
const candidateRect = {
|
|
1982
|
+
left: left - scrollX,
|
|
1983
|
+
top: top - scrollY,
|
|
1984
|
+
right: left - scrollX + width,
|
|
1985
|
+
bottom: top - scrollY + height,
|
|
1986
|
+
};
|
|
1987
|
+
if (rectsOverlap(candidateRect, hoverControlsRect, 6)) {
|
|
1988
|
+
const minTop = scrollY;
|
|
1989
|
+
const maxTop = Math.max(scrollY, scrollY + window.innerHeight - height);
|
|
1990
|
+
const belowTop = hoverControlsRect.bottom + scrollY + 6;
|
|
1991
|
+
const aboveTop = hoverControlsRect.top + scrollY - height - 6;
|
|
1992
|
+
if (belowTop <= maxTop) {
|
|
1993
|
+
top = clamp(belowTop, minTop, maxTop);
|
|
1994
|
+
}
|
|
1995
|
+
else if (aboveTop >= minTop) {
|
|
1996
|
+
top = clamp(aboveTop, minTop, maxTop);
|
|
1997
|
+
}
|
|
1998
|
+
else {
|
|
1999
|
+
const maxLeft = Math.max(scrollX, scrollX + window.innerWidth - width);
|
|
2000
|
+
const leftOfControls = hoverControlsRect.left + scrollX - width - 6;
|
|
2001
|
+
const rightOfControls = hoverControlsRect.right + scrollX + 6;
|
|
2002
|
+
left = clamp(leftOfControls >= scrollX ? leftOfControls : rightOfControls, scrollX, maxLeft);
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
1872
2006
|
overlay.button.style.left = `${Math.round(left)}px`;
|
|
1873
2007
|
overlay.button.style.top = `${Math.round(top)}px`;
|
|
1874
2008
|
}
|
|
@@ -1879,14 +2013,19 @@ class EinblickEditRuntime {
|
|
|
1879
2013
|
}
|
|
1880
2014
|
const binding = readBindingFromElement(this.activeElement);
|
|
1881
2015
|
if (!binding?.fieldKey) {
|
|
1882
|
-
this.hoverButton
|
|
2016
|
+
setOverlayButtonContent(this.hoverButton, this.messages.actions.editElement, { databaseIcon: true });
|
|
1883
2017
|
return;
|
|
1884
2018
|
}
|
|
1885
|
-
|
|
2019
|
+
const opensDrawer = isMultiMediaBinding(binding) ||
|
|
2020
|
+
(!isMediaEditableBinding(binding) && !shouldUseInlineEditor(binding));
|
|
2021
|
+
const label = isMediaEditableBinding(binding)
|
|
1886
2022
|
? getMediaActionLabel(binding, this.messages)
|
|
1887
2023
|
: shouldUseInlineEditor(binding)
|
|
1888
2024
|
? this.messages.actions.editText
|
|
1889
|
-
: this.messages.actions.
|
|
2025
|
+
: this.messages.actions.editElement;
|
|
2026
|
+
setOverlayButtonContent(this.hoverButton, label, {
|
|
2027
|
+
databaseIcon: opensDrawer,
|
|
2028
|
+
});
|
|
1890
2029
|
}
|
|
1891
2030
|
reloadBridge() {
|
|
1892
2031
|
this.clearBridgePing();
|
|
@@ -2008,16 +2147,51 @@ class EinblickEditRuntime {
|
|
|
2008
2147
|
return url.toString();
|
|
2009
2148
|
}
|
|
2010
2149
|
updateHoverButtonVisibility(element) {
|
|
2011
|
-
if (!this.hoverButton
|
|
2150
|
+
if (!this.hoverButton) {
|
|
2012
2151
|
return;
|
|
2013
2152
|
}
|
|
2014
2153
|
const binding = element ? readBindingFromElement(element) : null;
|
|
2015
|
-
const canCreate = this.shouldShowCreateButton(element, binding);
|
|
2016
2154
|
const canEdit = this.shouldShowEditButton(element, binding);
|
|
2017
2155
|
this.hoverButton.hidden = !canEdit;
|
|
2018
|
-
this.hoverCreateButton.hidden = !canCreate;
|
|
2019
2156
|
if (this.hoverButtonContainer) {
|
|
2020
|
-
this.hoverButtonContainer.hidden = !canEdit
|
|
2157
|
+
this.hoverButtonContainer.hidden = !canEdit;
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
findCollectionCreateButton(target) {
|
|
2161
|
+
const element = target instanceof Element
|
|
2162
|
+
? target
|
|
2163
|
+
: target instanceof Node
|
|
2164
|
+
? target.parentElement
|
|
2165
|
+
: null;
|
|
2166
|
+
if (!element) {
|
|
2167
|
+
return null;
|
|
2168
|
+
}
|
|
2169
|
+
return element.closest('[data-einblick-collection-create-button="true"]');
|
|
2170
|
+
}
|
|
2171
|
+
findCollectionForCreateButton(button) {
|
|
2172
|
+
return button.closest('[data-einblick-editable="true"][data-einblick-kind="collection"]');
|
|
2173
|
+
}
|
|
2174
|
+
updateCollectionCreateButtons() {
|
|
2175
|
+
if (typeof document === 'undefined') {
|
|
2176
|
+
return;
|
|
2177
|
+
}
|
|
2178
|
+
const buttons = Array.from(document.querySelectorAll('[data-einblick-collection-create-button="true"]'));
|
|
2179
|
+
for (const button of buttons) {
|
|
2180
|
+
const label = button.dataset.einblickCollectionCreateLabel?.trim() ||
|
|
2181
|
+
this.messages.actions.addRecord;
|
|
2182
|
+
setOverlayButtonContent(button, label, { databaseIcon: true });
|
|
2183
|
+
button.type = 'button';
|
|
2184
|
+
const collection = this.findCollectionForCreateButton(button);
|
|
2185
|
+
const binding = collection ? readBindingFromElement(collection) : null;
|
|
2186
|
+
const isVisible = !!collection &&
|
|
2187
|
+
!!binding &&
|
|
2188
|
+
this.shouldShowCreateButton(collection, binding);
|
|
2189
|
+
button.hidden = !isVisible;
|
|
2190
|
+
button.disabled = !isVisible;
|
|
2191
|
+
const wrapper = button.closest('[data-einblick-collection-create-wrapper="true"]');
|
|
2192
|
+
if (wrapper) {
|
|
2193
|
+
wrapper.hidden = !isVisible;
|
|
2194
|
+
}
|
|
2021
2195
|
}
|
|
2022
2196
|
}
|
|
2023
2197
|
shouldShowEditButton(element, binding) {
|
|
@@ -2033,7 +2207,10 @@ class EinblickEditRuntime {
|
|
|
2033
2207
|
if (binding.fieldKey) {
|
|
2034
2208
|
return false;
|
|
2035
2209
|
}
|
|
2036
|
-
|
|
2210
|
+
if (element.dataset.einblickKind !== 'collection') {
|
|
2211
|
+
return false;
|
|
2212
|
+
}
|
|
2213
|
+
return true;
|
|
2037
2214
|
}
|
|
2038
2215
|
findEditableTarget(target) {
|
|
2039
2216
|
if (!(target instanceof Element)) {
|
|
@@ -2102,7 +2279,8 @@ class EinblickEditRuntime {
|
|
|
2102
2279
|
!!this.brandBadge?.contains(target) ||
|
|
2103
2280
|
!!this.brandPopover?.contains(target) ||
|
|
2104
2281
|
!!this.bottomBarHost?.contains(target) ||
|
|
2105
|
-
!!this.bottomBarMoreMenu?.contains(target)
|
|
2282
|
+
!!this.bottomBarMoreMenu?.contains(target) ||
|
|
2283
|
+
!!this.findCollectionCreateButton(target));
|
|
2106
2284
|
}
|
|
2107
2285
|
findElementForBinding(binding) {
|
|
2108
2286
|
const selector = [
|
|
@@ -2354,18 +2532,21 @@ class EinblickEditRuntime {
|
|
|
2354
2532
|
this.callbacks.onError?.(this.messages.errors.fieldBindingRequired);
|
|
2355
2533
|
return;
|
|
2356
2534
|
}
|
|
2535
|
+
if (isMultiMediaBinding(binding)) {
|
|
2536
|
+
this.openDrawer(target, binding);
|
|
2537
|
+
return;
|
|
2538
|
+
}
|
|
2357
2539
|
const input = document.createElement('input');
|
|
2358
2540
|
input.type = 'file';
|
|
2359
2541
|
input.accept = getMediaAcceptValue(binding);
|
|
2360
2542
|
input.style.position = 'fixed';
|
|
2361
2543
|
input.style.left = '-9999px';
|
|
2362
2544
|
input.style.top = '0';
|
|
2363
|
-
const
|
|
2545
|
+
const buttonLabel = getMediaActionLabel(binding, this.messages);
|
|
2364
2546
|
const resetButton = () => {
|
|
2365
2547
|
if (button) {
|
|
2366
2548
|
button.disabled = false;
|
|
2367
|
-
button
|
|
2368
|
-
previousText || getMediaActionLabel(binding, this.messages);
|
|
2549
|
+
setOverlayButtonContent(button, buttonLabel);
|
|
2369
2550
|
}
|
|
2370
2551
|
};
|
|
2371
2552
|
input.addEventListener('change', () => {
|
|
@@ -2376,7 +2557,7 @@ class EinblickEditRuntime {
|
|
|
2376
2557
|
}
|
|
2377
2558
|
if (button) {
|
|
2378
2559
|
button.disabled = true;
|
|
2379
|
-
button
|
|
2560
|
+
setOverlayButtonContent(button, this.messages.actions.uploading);
|
|
2380
2561
|
}
|
|
2381
2562
|
void (async () => {
|
|
2382
2563
|
try {
|
|
@@ -2641,6 +2822,7 @@ export function createEinblickEditRuntime(options) {
|
|
|
2641
2822
|
login: (loginOptions) => runtime.login(loginOptions),
|
|
2642
2823
|
openEditor: (binding, element) => runtime.openEditor(binding, element),
|
|
2643
2824
|
setLocale: (locale) => runtime.setLocale(locale),
|
|
2825
|
+
setAccentColor: (accentColor) => runtime.setAccentColor(accentColor),
|
|
2644
2826
|
};
|
|
2645
2827
|
}
|
|
2646
2828
|
//# sourceMappingURL=runtime.js.map
|