@einblick/sdk 0.6.3 → 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 +275 -100
- 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;
|
|
@@ -1281,11 +1387,6 @@ class EinblickEditRuntime {
|
|
|
1281
1387
|
outline-offset: 2px;
|
|
1282
1388
|
}
|
|
1283
1389
|
|
|
1284
|
-
.secondary {
|
|
1285
|
-
border-color: transparent;
|
|
1286
|
-
background: transparent;
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
1390
|
.menu {
|
|
1290
1391
|
position: absolute;
|
|
1291
1392
|
right: 0.5rem;
|
|
@@ -1299,7 +1400,6 @@ class EinblickEditRuntime {
|
|
|
1299
1400
|
border-radius: 0.75rem;
|
|
1300
1401
|
background: rgb(255, 255, 255);
|
|
1301
1402
|
color: rgb(15, 23, 42);
|
|
1302
|
-
box-shadow: 0 14px 32px rgba(15, 23, 42, 0.16);
|
|
1303
1403
|
overflow: hidden;
|
|
1304
1404
|
}
|
|
1305
1405
|
|
|
@@ -1367,7 +1467,7 @@ class EinblickEditRuntime {
|
|
|
1367
1467
|
resourceList.className = 'resources';
|
|
1368
1468
|
const moreButton = document.createElement('button');
|
|
1369
1469
|
moreButton.type = 'button';
|
|
1370
|
-
moreButton.className = '
|
|
1470
|
+
moreButton.className = 'icon-button';
|
|
1371
1471
|
moreButton.setAttribute('aria-haspopup', 'menu');
|
|
1372
1472
|
moreButton.title = this.messages.actions.moreActions;
|
|
1373
1473
|
moreButton.innerHTML = getMoreActionsSvg(20);
|
|
@@ -1741,9 +1841,6 @@ class EinblickEditRuntime {
|
|
|
1741
1841
|
if (this.hoverButton) {
|
|
1742
1842
|
this.hoverButton.hidden = true;
|
|
1743
1843
|
}
|
|
1744
|
-
if (this.hoverCreateButton) {
|
|
1745
|
-
this.hoverCreateButton.hidden = true;
|
|
1746
|
-
}
|
|
1747
1844
|
return;
|
|
1748
1845
|
}
|
|
1749
1846
|
element.dataset.einblickHoverActive = 'true';
|
|
@@ -1779,6 +1876,10 @@ class EinblickEditRuntime {
|
|
|
1779
1876
|
}
|
|
1780
1877
|
this.updateHoverButtonLabel();
|
|
1781
1878
|
this.updateHoverButtonVisibility(this.activeElement);
|
|
1879
|
+
if (this.hoverButtonContainer?.hidden) {
|
|
1880
|
+
this.updateQuickFieldOverlayPositions();
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1782
1883
|
this.positionHoverControls(rect);
|
|
1783
1884
|
this.updateQuickFieldOverlayPositions();
|
|
1784
1885
|
}
|
|
@@ -1827,10 +1928,9 @@ class EinblickEditRuntime {
|
|
|
1827
1928
|
const button = document.createElement('button');
|
|
1828
1929
|
button.type = 'button';
|
|
1829
1930
|
button.setAttribute('data-einblick-field-button', isMediaBinding ? 'media' : 'text');
|
|
1830
|
-
button
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
: this.messages.actions.editText;
|
|
1931
|
+
setOverlayButtonContent(button, isMediaBinding
|
|
1932
|
+
? getMediaActionLabel(binding, this.messages)
|
|
1933
|
+
: this.messages.actions.editText);
|
|
1834
1934
|
button.addEventListener('pointerdown', (event) => {
|
|
1835
1935
|
event.stopPropagation();
|
|
1836
1936
|
});
|
|
@@ -1872,8 +1972,37 @@ class EinblickEditRuntime {
|
|
|
1872
1972
|
const height = overlay.button.offsetHeight || 26;
|
|
1873
1973
|
const scrollX = window.scrollX || document.documentElement.scrollLeft;
|
|
1874
1974
|
const scrollY = window.scrollY || document.documentElement.scrollTop;
|
|
1875
|
-
|
|
1876
|
-
|
|
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
|
+
}
|
|
1877
2006
|
overlay.button.style.left = `${Math.round(left)}px`;
|
|
1878
2007
|
overlay.button.style.top = `${Math.round(top)}px`;
|
|
1879
2008
|
}
|
|
@@ -1884,14 +2013,19 @@ class EinblickEditRuntime {
|
|
|
1884
2013
|
}
|
|
1885
2014
|
const binding = readBindingFromElement(this.activeElement);
|
|
1886
2015
|
if (!binding?.fieldKey) {
|
|
1887
|
-
this.hoverButton
|
|
2016
|
+
setOverlayButtonContent(this.hoverButton, this.messages.actions.editElement, { databaseIcon: true });
|
|
1888
2017
|
return;
|
|
1889
2018
|
}
|
|
1890
|
-
|
|
2019
|
+
const opensDrawer = isMultiMediaBinding(binding) ||
|
|
2020
|
+
(!isMediaEditableBinding(binding) && !shouldUseInlineEditor(binding));
|
|
2021
|
+
const label = isMediaEditableBinding(binding)
|
|
1891
2022
|
? getMediaActionLabel(binding, this.messages)
|
|
1892
2023
|
: shouldUseInlineEditor(binding)
|
|
1893
2024
|
? this.messages.actions.editText
|
|
1894
|
-
: this.messages.actions.
|
|
2025
|
+
: this.messages.actions.editElement;
|
|
2026
|
+
setOverlayButtonContent(this.hoverButton, label, {
|
|
2027
|
+
databaseIcon: opensDrawer,
|
|
2028
|
+
});
|
|
1895
2029
|
}
|
|
1896
2030
|
reloadBridge() {
|
|
1897
2031
|
this.clearBridgePing();
|
|
@@ -2013,16 +2147,51 @@ class EinblickEditRuntime {
|
|
|
2013
2147
|
return url.toString();
|
|
2014
2148
|
}
|
|
2015
2149
|
updateHoverButtonVisibility(element) {
|
|
2016
|
-
if (!this.hoverButton
|
|
2150
|
+
if (!this.hoverButton) {
|
|
2017
2151
|
return;
|
|
2018
2152
|
}
|
|
2019
2153
|
const binding = element ? readBindingFromElement(element) : null;
|
|
2020
|
-
const canCreate = this.shouldShowCreateButton(element, binding);
|
|
2021
2154
|
const canEdit = this.shouldShowEditButton(element, binding);
|
|
2022
2155
|
this.hoverButton.hidden = !canEdit;
|
|
2023
|
-
this.hoverCreateButton.hidden = !canCreate;
|
|
2024
2156
|
if (this.hoverButtonContainer) {
|
|
2025
|
-
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
|
+
}
|
|
2026
2195
|
}
|
|
2027
2196
|
}
|
|
2028
2197
|
shouldShowEditButton(element, binding) {
|
|
@@ -2038,7 +2207,10 @@ class EinblickEditRuntime {
|
|
|
2038
2207
|
if (binding.fieldKey) {
|
|
2039
2208
|
return false;
|
|
2040
2209
|
}
|
|
2041
|
-
|
|
2210
|
+
if (element.dataset.einblickKind !== 'collection') {
|
|
2211
|
+
return false;
|
|
2212
|
+
}
|
|
2213
|
+
return true;
|
|
2042
2214
|
}
|
|
2043
2215
|
findEditableTarget(target) {
|
|
2044
2216
|
if (!(target instanceof Element)) {
|
|
@@ -2076,9 +2248,7 @@ class EinblickEditRuntime {
|
|
|
2076
2248
|
return [];
|
|
2077
2249
|
}
|
|
2078
2250
|
if (binding.fieldKey) {
|
|
2079
|
-
return
|
|
2080
|
-
? [element]
|
|
2081
|
-
: [];
|
|
2251
|
+
return [];
|
|
2082
2252
|
}
|
|
2083
2253
|
if (!binding.recordId) {
|
|
2084
2254
|
return [];
|
|
@@ -2109,7 +2279,8 @@ class EinblickEditRuntime {
|
|
|
2109
2279
|
!!this.brandBadge?.contains(target) ||
|
|
2110
2280
|
!!this.brandPopover?.contains(target) ||
|
|
2111
2281
|
!!this.bottomBarHost?.contains(target) ||
|
|
2112
|
-
!!this.bottomBarMoreMenu?.contains(target)
|
|
2282
|
+
!!this.bottomBarMoreMenu?.contains(target) ||
|
|
2283
|
+
!!this.findCollectionCreateButton(target));
|
|
2113
2284
|
}
|
|
2114
2285
|
findElementForBinding(binding) {
|
|
2115
2286
|
const selector = [
|
|
@@ -2361,18 +2532,21 @@ class EinblickEditRuntime {
|
|
|
2361
2532
|
this.callbacks.onError?.(this.messages.errors.fieldBindingRequired);
|
|
2362
2533
|
return;
|
|
2363
2534
|
}
|
|
2535
|
+
if (isMultiMediaBinding(binding)) {
|
|
2536
|
+
this.openDrawer(target, binding);
|
|
2537
|
+
return;
|
|
2538
|
+
}
|
|
2364
2539
|
const input = document.createElement('input');
|
|
2365
2540
|
input.type = 'file';
|
|
2366
2541
|
input.accept = getMediaAcceptValue(binding);
|
|
2367
2542
|
input.style.position = 'fixed';
|
|
2368
2543
|
input.style.left = '-9999px';
|
|
2369
2544
|
input.style.top = '0';
|
|
2370
|
-
const
|
|
2545
|
+
const buttonLabel = getMediaActionLabel(binding, this.messages);
|
|
2371
2546
|
const resetButton = () => {
|
|
2372
2547
|
if (button) {
|
|
2373
2548
|
button.disabled = false;
|
|
2374
|
-
button
|
|
2375
|
-
previousText || getMediaActionLabel(binding, this.messages);
|
|
2549
|
+
setOverlayButtonContent(button, buttonLabel);
|
|
2376
2550
|
}
|
|
2377
2551
|
};
|
|
2378
2552
|
input.addEventListener('change', () => {
|
|
@@ -2383,7 +2557,7 @@ class EinblickEditRuntime {
|
|
|
2383
2557
|
}
|
|
2384
2558
|
if (button) {
|
|
2385
2559
|
button.disabled = true;
|
|
2386
|
-
button
|
|
2560
|
+
setOverlayButtonContent(button, this.messages.actions.uploading);
|
|
2387
2561
|
}
|
|
2388
2562
|
void (async () => {
|
|
2389
2563
|
try {
|
|
@@ -2648,6 +2822,7 @@ export function createEinblickEditRuntime(options) {
|
|
|
2648
2822
|
login: (loginOptions) => runtime.login(loginOptions),
|
|
2649
2823
|
openEditor: (binding, element) => runtime.openEditor(binding, element),
|
|
2650
2824
|
setLocale: (locale) => runtime.setLocale(locale),
|
|
2825
|
+
setAccentColor: (accentColor) => runtime.setAccentColor(accentColor),
|
|
2651
2826
|
};
|
|
2652
2827
|
}
|
|
2653
2828
|
//# sourceMappingURL=runtime.js.map
|