@widgetic/creator 0.3.53 → 0.3.55
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/dist/CreatorApp.svelte +1465 -980
- package/dist/components/EditableName.svelte +149 -36
- package/dist/components/EditableName.svelte.d.ts +0 -1
- package/dist/components/HoverTooltip.svelte +60 -0
- package/dist/components/HoverTooltip.svelte.d.ts +31 -0
- package/dist/components/WidgetDetails.svelte +485 -225
- package/dist/components/WidgetDetails.svelte.d.ts +7 -1
- package/dist/pageHelpers.d.ts +2 -0
- package/dist/pageHelpers.js +40 -6
- package/dist/stores/userSession.d.ts +1 -1
- package/dist/stores/userSession.js +19 -4
- package/dist/stores/websocketStore.js +2 -1
- package/dist/syncSiteAuth.js +1 -1
- package/dist/utils/embedCode.d.ts +3 -27
- package/dist/utils/embedCode.js +5 -34
- package/dist/utils/nativeScrollbarPadding.d.ts +5 -0
- package/dist/utils/nativeScrollbarPadding.js +27 -0
- package/dist/utils/widgeticChatUpload.js +2 -2
- package/package.json +13 -19
- package/dist/utils/models.d.ts +0 -4
- package/dist/utils/models.js +0 -94
- package/dist/utils/prototypes.d.ts +0 -0
- package/dist/utils/prototypes.js +0 -20
|
@@ -1,45 +1,119 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { createEventDispatcher } from 'svelte';
|
|
3
|
-
import
|
|
3
|
+
import HoverTooltip from './HoverTooltip.svelte';
|
|
4
4
|
|
|
5
5
|
export let name: string = '';
|
|
6
6
|
export let placeholder: string = 'Unnamed';
|
|
7
7
|
export let tooltipText: string = 'Double-click to rename';
|
|
8
|
-
export let tooltipPosition: 'above' | 'below' | 'left' | 'right' = 'above';
|
|
9
8
|
let className = '';
|
|
10
9
|
export { className as class };
|
|
11
10
|
export let style = '';
|
|
12
11
|
|
|
13
12
|
const dispatch = createEventDispatcher();
|
|
14
13
|
|
|
14
|
+
const NAME_DRAG_SLOP_PX = 5;
|
|
15
|
+
const NAME_DBLCLICK_MS = 450;
|
|
16
|
+
|
|
15
17
|
let isEditing = false;
|
|
16
18
|
let inputValue = '';
|
|
19
|
+
let nameInputEl: HTMLInputElement | null = null;
|
|
20
|
+
let namePointerStartX = 0;
|
|
21
|
+
let namePointerStartY = 0;
|
|
22
|
+
let namePointerMoved = false;
|
|
23
|
+
let lastNameClickAt = 0;
|
|
24
|
+
let lastNameClickX = 0;
|
|
25
|
+
let lastNameClickY = 0;
|
|
26
|
+
|
|
27
|
+
$: nameDisplayText = isEditing ? inputValue : (name || placeholder);
|
|
17
28
|
|
|
18
|
-
function
|
|
29
|
+
function openEditMode() {
|
|
19
30
|
isEditing = true;
|
|
20
31
|
inputValue = name || '';
|
|
21
32
|
}
|
|
22
33
|
|
|
23
|
-
function
|
|
34
|
+
function clearNameSelection() {
|
|
35
|
+
requestAnimationFrame(() => {
|
|
36
|
+
if (nameInputEl) {
|
|
37
|
+
const caret = nameInputEl.value.length;
|
|
38
|
+
try {
|
|
39
|
+
nameInputEl.setSelectionRange(caret, caret);
|
|
40
|
+
} catch {
|
|
41
|
+
/* ignore */
|
|
42
|
+
}
|
|
43
|
+
nameInputEl.blur();
|
|
44
|
+
}
|
|
45
|
+
window.getSelection()?.removeAllRanges();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function closeEditMode() {
|
|
50
|
+
if (!isEditing) {
|
|
51
|
+
clearNameSelection();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const trimmed = inputValue.trim();
|
|
24
55
|
isEditing = false;
|
|
56
|
+
|
|
57
|
+
if (trimmed && trimmed !== name) {
|
|
58
|
+
dispatch('rename', { newName: trimmed });
|
|
59
|
+
}
|
|
25
60
|
inputValue = '';
|
|
61
|
+
clearNameSelection();
|
|
26
62
|
}
|
|
27
63
|
|
|
28
|
-
function
|
|
64
|
+
function cancelEditing() {
|
|
29
65
|
if (!isEditing) return;
|
|
30
|
-
const trimmed = inputValue.trim();
|
|
31
66
|
isEditing = false;
|
|
67
|
+
inputValue = '';
|
|
68
|
+
clearNameSelection();
|
|
69
|
+
}
|
|
32
70
|
|
|
33
|
-
|
|
34
|
-
|
|
71
|
+
function toggleEditing(e: MouseEvent) {
|
|
72
|
+
e.stopPropagation();
|
|
73
|
+
if (isEditing) {
|
|
74
|
+
closeEditMode();
|
|
35
75
|
return;
|
|
36
76
|
}
|
|
77
|
+
openEditMode();
|
|
78
|
+
}
|
|
37
79
|
|
|
38
|
-
|
|
39
|
-
|
|
80
|
+
function onNamePointerDown(e: PointerEvent) {
|
|
81
|
+
if (isEditing) {
|
|
82
|
+
e.stopPropagation();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
namePointerMoved = false;
|
|
86
|
+
namePointerStartX = e.clientX;
|
|
87
|
+
namePointerStartY = e.clientY;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function onNamePointerMove(e: PointerEvent) {
|
|
91
|
+
if (isEditing || namePointerMoved) return;
|
|
92
|
+
if (Math.hypot(e.clientX - namePointerStartX, e.clientY - namePointerStartY) > NAME_DRAG_SLOP_PX) {
|
|
93
|
+
namePointerMoved = true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function onNamePointerUp(e: PointerEvent) {
|
|
98
|
+
if (isEditing) return;
|
|
99
|
+
if (namePointerMoved) {
|
|
100
|
+
lastNameClickAt = 0;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const now = Date.now();
|
|
104
|
+
const dist = Math.hypot(e.clientX - lastNameClickX, e.clientY - lastNameClickY);
|
|
105
|
+
if (now - lastNameClickAt <= NAME_DBLCLICK_MS && dist <= 10) {
|
|
106
|
+
lastNameClickAt = 0;
|
|
107
|
+
openEditMode();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
lastNameClickAt = now;
|
|
111
|
+
lastNameClickX = e.clientX;
|
|
112
|
+
lastNameClickY = e.clientY;
|
|
40
113
|
}
|
|
41
114
|
|
|
42
115
|
function focusAndSelect(node: HTMLInputElement, editing: boolean) {
|
|
116
|
+
nameInputEl = node;
|
|
43
117
|
function apply(shouldEdit: boolean) {
|
|
44
118
|
if (shouldEdit) {
|
|
45
119
|
requestAnimationFrame(() => {
|
|
@@ -58,37 +132,76 @@
|
|
|
58
132
|
</script>
|
|
59
133
|
|
|
60
134
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
61
|
-
<
|
|
135
|
+
<HoverTooltip text={isEditing ? '' : tooltipText} class="min-w-0 w-max max-w-full" {style}>
|
|
62
136
|
<div
|
|
63
|
-
class="editable-name-ct flex items-center
|
|
64
|
-
{
|
|
65
|
-
|
|
137
|
+
class="editable-name-ct flex items-center w-max max-w-full min-w-0 {isEditing ? 'gap-0.5' : 'gap-0'} {className}"
|
|
138
|
+
onpointerdown={onNamePointerDown}
|
|
139
|
+
onpointermove={onNamePointerMove}
|
|
140
|
+
onpointerup={onNamePointerUp}
|
|
141
|
+
onpointercancel={() => { namePointerMoved = true; }}
|
|
66
142
|
>
|
|
67
|
-
<input
|
|
68
|
-
class="editable-name-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
e
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
143
|
+
<div class="editable-name-input-wrap relative min-w-0 max-w-full">
|
|
144
|
+
<span class="editable-name-sizer" aria-hidden="true">{nameDisplayText}</span>
|
|
145
|
+
<input
|
|
146
|
+
class="editable-name-input absolute inset-0 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap font-semibold rounded text-sm outline-none transition-colors {isEditing ? 'editable-name-input-editing border border-blue-400 bg-white focus:ring-1 focus:ring-blue-500' : 'editable-name-input-idle border border-transparent bg-transparent cursor-grab'}"
|
|
147
|
+
style="{!isEditing ? 'pointer-events: none;' : ''}"
|
|
148
|
+
type="text"
|
|
149
|
+
value={nameDisplayText}
|
|
150
|
+
readonly={!isEditing}
|
|
151
|
+
tabindex={isEditing ? 0 : -1}
|
|
152
|
+
use:focusAndSelect={isEditing}
|
|
153
|
+
oninput={(e) => { if (isEditing) inputValue = e.currentTarget.value; }}
|
|
154
|
+
onkeydown={(e) => {
|
|
155
|
+
if (!isEditing) return;
|
|
156
|
+
e.stopPropagation();
|
|
157
|
+
if (e.key === 'Enter') closeEditMode();
|
|
158
|
+
if (e.key === 'Escape') cancelEditing();
|
|
159
|
+
}}
|
|
160
|
+
onblur={() => { if (isEditing) closeEditMode(); }}
|
|
161
|
+
/>
|
|
162
|
+
</div>
|
|
163
|
+
<button
|
|
164
|
+
type="button"
|
|
165
|
+
class="editable-name-pencil w-4 h-4 shrink-0 text-gray-400 text-[16px] leading-none cursor-pointer transition-opacity flex items-center justify-center p-0 bg-transparent border-0 {isEditing ? 'opacity-100' : 'opacity-0'}"
|
|
166
|
+
aria-label={isEditing ? 'Save name' : 'Rename widget'}
|
|
167
|
+
onmousedown={(e) => { e.preventDefault(); e.stopPropagation(); }}
|
|
168
|
+
onpointerdown={(e) => e.stopPropagation()}
|
|
169
|
+
onclick={toggleEditing}
|
|
170
|
+
>✏️</button>
|
|
87
171
|
</div>
|
|
88
|
-
</
|
|
172
|
+
</HoverTooltip>
|
|
89
173
|
|
|
90
174
|
<style>
|
|
91
|
-
.editable-name-
|
|
175
|
+
.editable-name-sizer {
|
|
176
|
+
display: block;
|
|
177
|
+
visibility: hidden;
|
|
178
|
+
white-space: nowrap;
|
|
179
|
+
font: inherit;
|
|
180
|
+
padding: 2px 0 2px 2px;
|
|
181
|
+
}
|
|
182
|
+
.editable-name-ct:focus-within .editable-name-sizer {
|
|
183
|
+
padding-right: 2px;
|
|
184
|
+
}
|
|
185
|
+
.editable-name-input {
|
|
186
|
+
width: 100%;
|
|
187
|
+
height: 100%;
|
|
188
|
+
padding: 2px 0 2px 2px;
|
|
189
|
+
margin: 0;
|
|
190
|
+
border-width: 1px;
|
|
191
|
+
box-sizing: border-box;
|
|
192
|
+
}
|
|
193
|
+
.editable-name-ct:hover .editable-name-pencil,
|
|
194
|
+
.editable-name-ct:focus-within .editable-name-pencil {
|
|
92
195
|
opacity: 1;
|
|
93
196
|
}
|
|
197
|
+
.editable-name-ct:hover .editable-name-input-idle {
|
|
198
|
+
text-decoration: underline;
|
|
199
|
+
text-decoration-style: dotted;
|
|
200
|
+
text-underline-offset: 3px;
|
|
201
|
+
}
|
|
202
|
+
.editable-name-pencil:focus,
|
|
203
|
+
.editable-name-pencil:focus-visible {
|
|
204
|
+
outline: none;
|
|
205
|
+
box-shadow: none;
|
|
206
|
+
}
|
|
94
207
|
</style>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Portal } from '@widgetic/design-system/components';
|
|
3
|
+
|
|
4
|
+
export let text: string = '';
|
|
5
|
+
let className = '';
|
|
6
|
+
export { className as class };
|
|
7
|
+
export let style = '';
|
|
8
|
+
|
|
9
|
+
let triggerEl: HTMLElement | null = null;
|
|
10
|
+
let open = false;
|
|
11
|
+
let tipTop = 0;
|
|
12
|
+
let tipLeft = 0;
|
|
13
|
+
const portalTarget = `wc-hover-tooltip-${Math.random().toString(36).slice(2, 10)}`;
|
|
14
|
+
|
|
15
|
+
function place() {
|
|
16
|
+
if (!triggerEl) return;
|
|
17
|
+
const rect = triggerEl.getBoundingClientRect();
|
|
18
|
+
tipTop = rect.top - 8;
|
|
19
|
+
tipLeft = rect.left + rect.width / 2;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function show() {
|
|
23
|
+
if (!text) return;
|
|
24
|
+
place();
|
|
25
|
+
open = true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function hide() {
|
|
29
|
+
open = false;
|
|
30
|
+
}
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
34
|
+
<div
|
|
35
|
+
bind:this={triggerEl}
|
|
36
|
+
class="wc-hover-tooltip-trigger {className}"
|
|
37
|
+
{style}
|
|
38
|
+
onmouseenter={show}
|
|
39
|
+
onmouseleave={hide}
|
|
40
|
+
onfocusin={show}
|
|
41
|
+
onfocusout={hide}
|
|
42
|
+
>
|
|
43
|
+
<slot />
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
{#if open && text}
|
|
47
|
+
<Portal target={portalTarget}>
|
|
48
|
+
<div
|
|
49
|
+
class="wc-hover-tooltip-bubble pointer-events-none fixed z-[99999] -translate-x-1/2 -translate-y-full rounded-md bg-[#1f2937] px-2.5 py-1 text-xs leading-snug text-[#f9fafb] whitespace-nowrap shadow-md"
|
|
50
|
+
style="top: {tipTop}px; left: {tipLeft}px;"
|
|
51
|
+
role="tooltip"
|
|
52
|
+
>
|
|
53
|
+
{text}
|
|
54
|
+
<span
|
|
55
|
+
class="wc-hover-tooltip-arrow absolute left-1/2 top-full h-0 w-0 -translate-x-1/2 border-x-[5px] border-t-[5px] border-x-transparent border-t-[#1f2937]"
|
|
56
|
+
aria-hidden="true"
|
|
57
|
+
></span>
|
|
58
|
+
</div>
|
|
59
|
+
</Portal>
|
|
60
|
+
{/if}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: Props & {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
|
|
15
|
+
default: any;
|
|
16
|
+
} ? Props extends Record<string, never> ? any : {
|
|
17
|
+
children?: any;
|
|
18
|
+
} : {});
|
|
19
|
+
declare const HoverTooltip: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
|
|
20
|
+
text?: string;
|
|
21
|
+
class?: string;
|
|
22
|
+
style?: string;
|
|
23
|
+
}, {
|
|
24
|
+
default: {};
|
|
25
|
+
}>, {
|
|
26
|
+
[evt: string]: CustomEvent<any>;
|
|
27
|
+
}, {
|
|
28
|
+
default: {};
|
|
29
|
+
}, {}, string>;
|
|
30
|
+
type HoverTooltip = InstanceType<typeof HoverTooltip>;
|
|
31
|
+
export default HoverTooltip;
|