@lilaquadrat/design-core 0.1.0 → 0.2.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/package.json +10 -9
- package/src/components/partials/error.partial.vue +1 -1
- package/src/components/partials/main-components.partial.vue +1 -1
- package/src/libs/Models.class.ts +1 -1
- package/src/main.ts +5 -2
- package/src/plugins/inview.ts +6 -348
- package/src/plugins/resize.ts +7 -128
- package/src/stores/main.store.ts +1 -1
- package/src/views/content.view.vue +1 -1
- package/src/views/editor.view.vue +1 -1
- package/src/views/signup-account.view.vue +1 -1
- package/tooling/vite.ts +19 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lilaquadrat/design-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "framework layer shared by every lilaquadrat STUDIO design: app bootstrap, router, stores, plugins and build tooling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
"url": "https://lilaquadrat.de"
|
|
11
11
|
},
|
|
12
12
|
"homepage": "https://lilaquadrat.de",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+ssh://git@ssh.dev.azure.com/v3/lilaquadrat/studio-packages/studio-design-core"
|
|
16
|
+
},
|
|
13
17
|
"engines": {
|
|
14
18
|
"node": ">=18"
|
|
15
19
|
},
|
|
@@ -53,13 +57,14 @@
|
|
|
53
57
|
"scripts": {
|
|
54
58
|
"type-check": "vue-tsc --noEmit",
|
|
55
59
|
"lint": "eslint . --fix",
|
|
60
|
+
"commit": "cz",
|
|
56
61
|
"release": "standard-version"
|
|
57
62
|
},
|
|
58
63
|
"peerDependencies": {
|
|
59
64
|
"@auth0/auth0-spa-js": "^2.1.3",
|
|
60
|
-
"@lilaquadrat/
|
|
65
|
+
"@lilaquadrat/frontend": ">=0.2.0",
|
|
66
|
+
"@lilaquadrat/interfaces": ">=1.48.0",
|
|
61
67
|
"@lilaquadrat/sdk": "^0.1.2",
|
|
62
|
-
"@lilaquadrat/studio": "^9.14.3",
|
|
63
68
|
"axios": "^1.9.0",
|
|
64
69
|
"cypress": "^15.0.0",
|
|
65
70
|
"dayjs": "^1.11.13",
|
|
@@ -99,9 +104,9 @@
|
|
|
99
104
|
"devDependencies": {
|
|
100
105
|
"@auth0/auth0-spa-js": "2.1.3",
|
|
101
106
|
"@eslint/js": "^9.25.1",
|
|
102
|
-
"@lilaquadrat/
|
|
107
|
+
"@lilaquadrat/frontend": "^0.2.0",
|
|
108
|
+
"@lilaquadrat/interfaces": "1.48.0",
|
|
103
109
|
"@lilaquadrat/sdk": "^0.1.2",
|
|
104
|
-
"@lilaquadrat/studio": "9.15.4",
|
|
105
110
|
"@types/node": "^22.15.3",
|
|
106
111
|
"@types/object-path": "^0.11.4",
|
|
107
112
|
"@types/qrcode": "^1.5.5",
|
|
@@ -140,9 +145,5 @@
|
|
|
140
145
|
"commitizen": {
|
|
141
146
|
"path": "./node_modules/cz-conventional-changelog"
|
|
142
147
|
}
|
|
143
|
-
},
|
|
144
|
-
"resolutions": {
|
|
145
|
-
"@lilaquadrat/sdk/@lilaquadrat/interfaces": "1.31.0",
|
|
146
|
-
"@lilaquadrat/studio/@lilaquadrat/interfaces": "1.31.0"
|
|
147
148
|
}
|
|
148
149
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import useMainStore from '../../stores/main.store';
|
|
3
3
|
import type { BasicData, Content } from '@lilaquadrat/interfaces';
|
|
4
4
|
import type { SDKResponse } from '@lilaquadrat/sdk';
|
|
5
|
-
import { prepareContent } from '@lilaquadrat/
|
|
5
|
+
import { prepareContent } from '@lilaquadrat/frontend/content';
|
|
6
6
|
import { watch } from 'vue';
|
|
7
7
|
import { onBeforeMount } from 'vue';
|
|
8
8
|
import { ref, computed } from 'vue';
|
|
@@ -5,7 +5,7 @@ import useMainStore from '../../stores/main.store';
|
|
|
5
5
|
import useUserStore from '../../stores/user.store';
|
|
6
6
|
import type { BasicData, Content, ContentWithPositions, GenericData } from '@lilaquadrat/interfaces';
|
|
7
7
|
import type { SDKResponse } from '@lilaquadrat/sdk';
|
|
8
|
-
import { distributeGenericData, generateDataWithContent, hardCopy, prepareContent } from '@lilaquadrat/
|
|
8
|
+
import { distributeGenericData, generateDataWithContent, hardCopy, prepareContent } from '@lilaquadrat/frontend/content';
|
|
9
9
|
import { ref, computed, watch, onServerPrefetch, onBeforeMount } from 'vue';
|
|
10
10
|
import { useRoute } from 'vue-router';
|
|
11
11
|
|
package/src/libs/Models.class.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { v4 as uuid } from 'uuid';
|
|
2
|
-
import { hardCopy } from '@lilaquadrat/
|
|
2
|
+
import { hardCopy } from '@lilaquadrat/frontend/content';
|
|
3
3
|
|
|
4
4
|
type DeclarationTypes = 'string' | 'number' | 'boolean' | 'object';
|
|
5
5
|
type SingleDeclaration = { type: 'string', default?: string } |
|
package/src/main.ts
CHANGED
|
@@ -3,7 +3,11 @@ import { createPinia, type StateTree } from 'pinia';
|
|
|
3
3
|
import createRouter from './mixins/createRouter';
|
|
4
4
|
import { loadViaDeclarationSync } from './mixins/loadComponents';
|
|
5
5
|
import i18n from './plugins/translations';
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* side effect import: the resize singleton in @lilaquadrat/frontend attaches its
|
|
8
|
+
* listeners on import, there is no plugin to install
|
|
9
|
+
*/
|
|
10
|
+
import './plugins/resize';
|
|
7
11
|
import HelpersPlugin from './plugins/filters';
|
|
8
12
|
import youtubePlugin from './plugins/youtube';
|
|
9
13
|
import traceablePlugin from './plugins/traceable';
|
|
@@ -70,7 +74,6 @@ export function getAppInstance (context: any, routes: readonly RouteRecordRaw[],
|
|
|
70
74
|
|
|
71
75
|
app.use(i18n);
|
|
72
76
|
app.use(HelpersPlugin);
|
|
73
|
-
app.use(resizePlugin);
|
|
74
77
|
app.use(youtubePlugin);
|
|
75
78
|
app.use(traceablePlugin);
|
|
76
79
|
app.use(authPlugin);
|
package/src/plugins/inview.ts
CHANGED
|
@@ -1,351 +1,9 @@
|
|
|
1
|
-
import { computed, watch } from 'vue';
|
|
2
|
-
import { ref } from 'vue';
|
|
3
|
-
import { type Ref } from 'vue';
|
|
4
|
-
|
|
5
|
-
class Inview {
|
|
6
|
-
|
|
7
|
-
timeout!: NodeJS.Timeout | undefined;
|
|
8
|
-
|
|
9
|
-
lastScrollingAdjustment = 0;
|
|
10
|
-
|
|
11
|
-
debounceTime: number = 50;
|
|
12
|
-
|
|
13
|
-
isTop = ref<boolean>(false);
|
|
14
|
-
|
|
15
|
-
scrolledEvent: Event;
|
|
16
|
-
|
|
17
|
-
scrolled = ref<number>(0);
|
|
18
|
-
|
|
19
|
-
moduleAdded = ref<number>(0);
|
|
20
|
-
|
|
21
|
-
scrollDirection = ref<'up' | 'down'>();
|
|
22
|
-
|
|
23
|
-
parentElement = ref<HTMLElement>();
|
|
24
|
-
|
|
25
|
-
lastScrollY = 0;
|
|
26
|
-
lastTimestamp = 0;
|
|
27
|
-
scrollVelocity = 0;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* if true we fire an inital scroll event to indicate that scrolling has started without waiting for the debounce
|
|
31
|
-
*/
|
|
32
|
-
triggerStart = ref<boolean>(true);
|
|
33
|
-
|
|
34
|
-
safeWindow = computed(() => {
|
|
35
|
-
|
|
36
|
-
if (typeof window === 'undefined') return null;
|
|
37
|
-
if (this.parentElement.value) return this.parentElement.value;
|
|
38
|
-
return window;
|
|
39
|
-
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
scrollY () {
|
|
43
|
-
|
|
44
|
-
if (this.safeWindow.value instanceof Window) {
|
|
45
|
-
|
|
46
|
-
return this.safeWindow.value.scrollY;
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (this.parentElement.value) {
|
|
51
|
-
|
|
52
|
-
return this.parentElement.value.scrollTop;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return 0
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
height () {
|
|
60
|
-
|
|
61
|
-
if (this.safeWindow.value instanceof Window) {
|
|
62
|
-
|
|
63
|
-
return this.safeWindow.value.outerHeight;
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (this.parentElement.value) {
|
|
68
|
-
|
|
69
|
-
return this.parentElement.value.offsetHeight;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return 0
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
constructor () {
|
|
77
|
-
|
|
78
|
-
this.scrolledEvent = new Event('scrolled');
|
|
79
|
-
this.checkIsTop();
|
|
80
|
-
|
|
81
|
-
if (this.safeWindow.value) {
|
|
82
|
-
|
|
83
|
-
this.safeWindow.value?.addEventListener('scroll', () => {
|
|
84
|
-
|
|
85
|
-
this.debounce();
|
|
86
|
-
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
setParentElement (element: HTMLElement) {
|
|
94
|
-
|
|
95
|
-
this.parentElement.value = element;
|
|
96
|
-
this.addScrollListener(element);
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
addScrollListener (element: Element) {
|
|
101
|
-
|
|
102
|
-
element.addEventListener('scroll', () => {
|
|
103
|
-
|
|
104
|
-
const currentTimestamp = performance.now();
|
|
105
|
-
const deltaY = this.scrollY() - this.lastScrollY;
|
|
106
|
-
const deltaTime = currentTimestamp - this.lastTimestamp;
|
|
107
|
-
|
|
108
|
-
// Calculate velocity (pixels per millisecond)
|
|
109
|
-
this.scrollVelocity = Math.abs(deltaY / deltaTime);
|
|
110
|
-
|
|
111
|
-
this.lastScrollY = this.scrollY();
|
|
112
|
-
this.lastTimestamp = currentTimestamp;
|
|
113
|
-
|
|
114
|
-
// console.log(`Scroll Velocity: ${this.scrollVelocity.toFixed(2)} pixels/ms`);
|
|
115
|
-
|
|
116
|
-
this.debounce();
|
|
117
|
-
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
trigger (isStart?: boolean) {
|
|
123
|
-
|
|
124
|
-
if (!this.safeWindow.value) return;
|
|
125
|
-
|
|
126
|
-
this.checkIsTop();
|
|
127
|
-
this.scrollDirection.value = this.scrolled.value > this.scrollY()
|
|
128
|
-
? 'down'
|
|
129
|
-
: 'up'
|
|
130
|
-
this.scrolled.value = this.scrollY();
|
|
131
|
-
|
|
132
|
-
this.safeWindow.value?.dispatchEvent(this.scrolledEvent);
|
|
133
|
-
if (!isStart) this.triggerStart.value = true;
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
checkIsTop () {
|
|
138
|
-
|
|
139
|
-
if (!this.safeWindow.value) return;
|
|
140
|
-
|
|
141
|
-
this.isTop.value = this.scrollY() <= 0
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
debounce () {
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* indicates that the scrolling has begun and fire an inital scrolling event without waiting for the debounce
|
|
149
|
-
*/
|
|
150
|
-
if (this.triggerStart.value) {
|
|
151
|
-
|
|
152
|
-
this.triggerStart.value = false;
|
|
153
|
-
this.trigger(true);
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
clearTimeout(this.timeout);
|
|
158
|
-
this.timeout = setTimeout(() => {
|
|
159
|
-
|
|
160
|
-
this.trigger();
|
|
161
|
-
|
|
162
|
-
}, this.debounceTime);
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
check (component: HTMLElement, state: Ref<string[]>, options?: { align?: boolean }) {
|
|
167
|
-
const element = component;
|
|
168
|
-
const newState: string[] = [];
|
|
169
|
-
|
|
170
|
-
if (typeof element?.getBoundingClientRect !== 'function') return;
|
|
171
|
-
if (!this.safeWindow.value) return;
|
|
172
|
-
|
|
173
|
-
const viewportHeight = this.height();
|
|
174
|
-
const height = viewportHeight / 2;
|
|
175
|
-
const rect = element.getBoundingClientRect();
|
|
176
|
-
let top = rect.top - height + 10;
|
|
177
|
-
let bottom = rect.bottom - height + 10;
|
|
178
|
-
let visibleHeight = 0;
|
|
179
|
-
let marginToTop = 0;
|
|
180
|
-
|
|
181
|
-
if (this.parentElement.value) {
|
|
182
|
-
|
|
183
|
-
const parentRect = this.parentElement.value.getBoundingClientRect();
|
|
184
|
-
// Adjust top and bottom based on parent element's top and bottom
|
|
185
|
-
const parentTop = parentRect.top;
|
|
186
|
-
const parentBottom = parentRect.bottom;
|
|
187
|
-
|
|
188
|
-
top = rect.top - parentTop - height + 10;
|
|
189
|
-
bottom = rect.bottom - parentTop - height + 10;
|
|
190
|
-
|
|
191
|
-
marginToTop = Math.abs(rect.top - parentTop);
|
|
192
|
-
|
|
193
|
-
// Adjust visibleTop and visibleBottom for parent element
|
|
194
|
-
const visibleTop = Math.max(parentTop, rect.top);
|
|
195
|
-
const visibleBottom = Math.min(parentBottom, rect.bottom);
|
|
196
|
-
|
|
197
|
-
visibleHeight = Math.max(0, visibleBottom - visibleTop);
|
|
198
|
-
|
|
199
|
-
} else {
|
|
200
|
-
|
|
201
|
-
// Original calculations if no parent element is provided
|
|
202
|
-
const visibleTop = Math.max(0, rect.top);
|
|
203
|
-
const visibleBottom = Math.min(rect.bottom, viewportHeight);
|
|
204
|
-
|
|
205
|
-
marginToTop = Math.abs(rect.top);
|
|
206
|
-
|
|
207
|
-
visibleHeight = Math.max(0, visibleBottom - visibleTop);
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (top > 0) {
|
|
212
|
-
newState.push('inview-after');
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (top <= 0 && bottom >= 0) {
|
|
216
|
-
newState.push('inview-current');
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (bottom < 0) {
|
|
220
|
-
newState.push('inview-before');
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Check if more than 30% of the element is visible
|
|
224
|
-
if (visibleHeight / rect.height >= 0.3) {
|
|
225
|
-
newState.push('inview-visible');
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
if (newState.includes('inview-current') && options?.align) {
|
|
229
|
-
|
|
230
|
-
if(!this.lastScrollingAdjustment || Date.now() - this.lastScrollingAdjustment > 1500) {
|
|
231
|
-
|
|
232
|
-
requestAnimationFrame(() => this.adjustScrolling(element, marginToTop));
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
state.value.length = 0;
|
|
239
|
-
state.value.push(...newState);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
checkPreload (component: HTMLElement, state: Ref<boolean>) {
|
|
243
|
-
|
|
244
|
-
const preloadRange = window?.outerHeight * 2;
|
|
245
|
-
const rect = component.getBoundingClientRect();
|
|
246
|
-
|
|
247
|
-
if (rect.bottom > -preloadRange && rect.top < preloadRange) {
|
|
248
|
-
|
|
249
|
-
state.value = true;
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
adjustScrolling (component: HTMLElement, top: number) {
|
|
256
|
-
|
|
257
|
-
const offset = this.height() / 10;
|
|
258
|
-
|
|
259
|
-
if (top < offset && top > (offset * -1)) {
|
|
260
|
-
|
|
261
|
-
this.lastScrollingAdjustment = Date.now();
|
|
262
|
-
|
|
263
|
-
component.scrollIntoView({
|
|
264
|
-
behavior: 'smooth',
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
moduleRendered () {
|
|
272
|
-
|
|
273
|
-
this.moduleAdded.value++;
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const inview = new Inview();
|
|
280
|
-
|
|
281
1
|
/**
|
|
282
|
-
*
|
|
2
|
+
* Inview lives in @lilaquadrat/frontend - it is shared with the internal apps,
|
|
3
|
+
* and that copy is the truth. This path stays so a design keeps importing
|
|
4
|
+
* '@/plugins/inview'.
|
|
283
5
|
*
|
|
284
|
-
*
|
|
285
|
-
** inview-before - the element is before the viewport
|
|
286
|
-
** inview-current - the element is centered in the viewport
|
|
287
|
-
** inview-after - the element is after the viewport
|
|
288
|
-
** inview-visible - more than 30% of the element are visible in the current viewport, regardless if it is centered or nor
|
|
6
|
+
* Importing the module starts the scroll listener.
|
|
289
7
|
*/
|
|
290
|
-
|
|
291
|
-
export
|
|
292
|
-
|
|
293
|
-
const state = ref<string[]>([]);
|
|
294
|
-
const preload = ref<boolean>(false);
|
|
295
|
-
|
|
296
|
-
if (element) {
|
|
297
|
-
|
|
298
|
-
watch(element, () => {
|
|
299
|
-
|
|
300
|
-
if (element.value) {
|
|
301
|
-
|
|
302
|
-
inview.moduleRendered();
|
|
303
|
-
|
|
304
|
-
if (options?.preload) {
|
|
305
|
-
|
|
306
|
-
inview.checkPreload(element.value, preload);
|
|
307
|
-
|
|
308
|
-
const unwatchPreload = watch(inview.scrolled, () => {
|
|
309
|
-
|
|
310
|
-
if (!element.value) return;
|
|
311
|
-
|
|
312
|
-
inview.checkPreload(element.value as HTMLElement, preload);
|
|
313
|
-
|
|
314
|
-
//unwatch when the preload value is true
|
|
315
|
-
if (preload.value) unwatchPreload();
|
|
316
|
-
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
} else {
|
|
320
|
-
|
|
321
|
-
inview.check(element.value, state, options);
|
|
322
|
-
|
|
323
|
-
watch(inview.scrolled, () => {
|
|
324
|
-
|
|
325
|
-
inview.check(element.value as HTMLElement, state, options)
|
|
326
|
-
|
|
327
|
-
})
|
|
328
|
-
|
|
329
|
-
watch(inview.moduleAdded, () => {
|
|
330
|
-
|
|
331
|
-
requestAnimationFrame(() => {
|
|
332
|
-
|
|
333
|
-
inview.check(element.value as HTMLElement, state, options);
|
|
334
|
-
|
|
335
|
-
})
|
|
336
|
-
|
|
337
|
-
})
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
})
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
return { inviewState: state, scrolled: inview.scrolled, scrollDirection: inview.scrollDirection, preload };
|
|
348
|
-
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
export default inview;
|
|
8
|
+
export * from '@lilaquadrat/frontend/inview';
|
|
9
|
+
export { default } from '@lilaquadrat/frontend/inview';
|
package/src/plugins/resize.ts
CHANGED
|
@@ -1,128 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
debounceTime: number = 50;
|
|
9
|
-
|
|
10
|
-
resizedEvent: Event;
|
|
11
|
-
|
|
12
|
-
mediaEvent: Event;
|
|
13
|
-
|
|
14
|
-
media = ref<string>('mobile');
|
|
15
|
-
|
|
16
|
-
resized = ref<number>(Date.now());
|
|
17
|
-
|
|
18
|
-
realHeight = ref<number>(0);
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* if true we fire an inital resized event to indicate that resizing has started without waiting for the debounce
|
|
22
|
-
*/
|
|
23
|
-
triggerStart = ref<boolean>(true);
|
|
24
|
-
|
|
25
|
-
safeWindow = computed(() => {
|
|
26
|
-
|
|
27
|
-
if(typeof window === 'undefined') return null;
|
|
28
|
-
return window;
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
constructor () {
|
|
33
|
-
|
|
34
|
-
this.resizedEvent = new Event('resized');
|
|
35
|
-
this.mediaEvent = new Event('media');
|
|
36
|
-
this.realHeight.value = this.safeWindow.value?.innerHeight || 0;
|
|
37
|
-
|
|
38
|
-
this.getMediaQuery();
|
|
39
|
-
|
|
40
|
-
this.safeWindow.value?.addEventListener('resize', () => this.debounce());
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
trigger (isStart?: boolean) {
|
|
45
|
-
|
|
46
|
-
this.getMediaQuery();
|
|
47
|
-
|
|
48
|
-
if(this.safeWindow.value) {
|
|
49
|
-
|
|
50
|
-
this.realHeight.value = this.safeWindow.value?.innerHeight;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
this.resized.value = Date.now();
|
|
54
|
-
this.safeWindow.value?.dispatchEvent(this.resizedEvent);
|
|
55
|
-
|
|
56
|
-
if(!isStart) this.triggerStart.value = true;
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
getMediaQuery (): void {
|
|
61
|
-
|
|
62
|
-
if(typeof document === 'undefined') return;
|
|
63
|
-
|
|
64
|
-
const element = document.getElementById('mediadetection');
|
|
65
|
-
|
|
66
|
-
if (!element) return;
|
|
67
|
-
|
|
68
|
-
const child = Array.from(element.children).find(child => this.safeWindow.value?.getComputedStyle(child).display === 'block');
|
|
69
|
-
|
|
70
|
-
if (child) {
|
|
71
|
-
const childClass = child.getAttribute('class') as string;
|
|
72
|
-
|
|
73
|
-
if (this.media.value !== childClass) {
|
|
74
|
-
|
|
75
|
-
this.media.value = childClass;
|
|
76
|
-
this.safeWindow.value?.dispatchEvent(this.mediaEvent);
|
|
77
|
-
|
|
78
|
-
} else {
|
|
79
|
-
|
|
80
|
-
this.media.value = childClass;
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
debounce () {
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* indicates that the scrolling has begun and fire an inital scrolling event without waiting for the debounce
|
|
90
|
-
*/
|
|
91
|
-
if(this.triggerStart.value) {
|
|
92
|
-
|
|
93
|
-
this.triggerStart.value = false;
|
|
94
|
-
this.trigger(true);
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
clearTimeout(this.timeout);
|
|
99
|
-
this.timeout = setTimeout(() => {
|
|
100
|
-
|
|
101
|
-
this.trigger();
|
|
102
|
-
|
|
103
|
-
}, this.debounceTime);
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const resize = new Resize();
|
|
110
|
-
const plugin = {
|
|
111
|
-
install: (): void => {
|
|
112
|
-
// this exists only for initialization purposes
|
|
113
|
-
logger.plugins('resize installed');
|
|
114
|
-
},
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
function useResize () {
|
|
118
|
-
|
|
119
|
-
return {realHeight: resize.realHeight, media: resize.media, resized: resize.resized, plugin: resize};
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export default plugin;
|
|
124
|
-
|
|
125
|
-
export {
|
|
126
|
-
useResize,
|
|
127
|
-
resize
|
|
128
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Resize lives in @lilaquadrat/frontend - it is shared with the internal apps,
|
|
3
|
+
* and that copy is the truth. This path stays so a design keeps importing
|
|
4
|
+
* '@/plugins/resize'.
|
|
5
|
+
*/
|
|
6
|
+
export * from '@lilaquadrat/frontend/resize';
|
|
7
|
+
export { default } from '@lilaquadrat/frontend/resize';
|
package/src/stores/main.store.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { useAuth } from '../plugins/auth';
|
|
|
7
7
|
import type FrontendConfig from '../interfaces/FrontendConfig.interface';
|
|
8
8
|
import type { AxiosError } from 'axios';
|
|
9
9
|
import { computed } from 'vue';
|
|
10
|
-
import { hardCopy } from '@lilaquadrat/
|
|
10
|
+
import { hardCopy } from '@lilaquadrat/frontend/content';
|
|
11
11
|
|
|
12
12
|
export const useMainStore = defineStore('main', () => {
|
|
13
13
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, ref, watch } from 'vue';
|
|
3
|
-
import { distributeGenericData, generateDataWithContent, hardCopy, prepareContent } from '@lilaquadrat/
|
|
3
|
+
import { distributeGenericData, generateDataWithContent, hardCopy, prepareContent } from '@lilaquadrat/frontend/content';
|
|
4
4
|
import type { BasicData, Content, ContentWithPositions, GenericData } from '@lilaquadrat/interfaces';
|
|
5
5
|
import useMainStore from '../stores/main.store';
|
|
6
6
|
import { useRoute } from 'vue-router';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import useEditorStore from '../stores/editor.store';
|
|
3
|
-
import { hardCopy, prepareContent } from '@lilaquadrat/
|
|
3
|
+
import { hardCopy, prepareContent } from '@lilaquadrat/frontend/content';
|
|
4
4
|
import { getCurrentInstance, nextTick, onMounted, ref } from 'vue';
|
|
5
5
|
import { type Content, type ContentWithPositions, type EditorActiveModule, type StudioIframeMessage } from '@lilaquadrat/interfaces';
|
|
6
6
|
import { onBeforeUnmount } from 'vue';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { auth } from '../plugins/auth';
|
|
3
3
|
import useMainStore from '../stores/main.store';
|
|
4
4
|
import useUserStore from '../stores/user.store';
|
|
5
|
-
import { prepareContent } from '@lilaquadrat/
|
|
5
|
+
import { prepareContent } from '@lilaquadrat/frontend/content';
|
|
6
6
|
import type { ContentWithPositions } from '@lilaquadrat/interfaces';
|
|
7
7
|
import { computed, onBeforeMount } from 'vue';
|
|
8
8
|
import { useRoute, useRouter } from 'vue-router';
|
package/tooling/vite.ts
CHANGED
|
@@ -110,9 +110,14 @@ export function createViteConfig (options: ViteFactoryOptions) {
|
|
|
110
110
|
host: '0.0.0.0',
|
|
111
111
|
},
|
|
112
112
|
optimizeDeps: {
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
113
|
+
// design-core ships source, and its less needs the project variables
|
|
114
|
+
// injected below - a prebundle would not see them.
|
|
115
|
+
//
|
|
116
|
+
// @lilaquadrat/frontend rides along because design-core imports it:
|
|
117
|
+
// prebundling it there and serving it raw here would give the resize and
|
|
118
|
+
// inview singletons two module identities, and a second scroll listener
|
|
119
|
+
// with it
|
|
120
|
+
exclude: ['@lilaquadrat/design-core', '@lilaquadrat/frontend']
|
|
116
121
|
},
|
|
117
122
|
build: {
|
|
118
123
|
cssCodeSplit : false,
|
|
@@ -173,13 +178,22 @@ export function createViteConfig (options: ViteFactoryOptions) {
|
|
|
173
178
|
'vue-router',
|
|
174
179
|
'vue-i18n',
|
|
175
180
|
'pinia',
|
|
176
|
-
|
|
181
|
+
// holds a static request cache, so a second copy would cache twice
|
|
177
182
|
'@lilaquadrat/sdk',
|
|
178
|
-
|
|
183
|
+
// resize and inview are singletons: a second copy means a second
|
|
184
|
+
// scroll listener and a second set of refs nobody reads
|
|
185
|
+
'@lilaquadrat/frontend',
|
|
179
186
|
'@auth0/auth0-spa-js',
|
|
180
187
|
'axios',
|
|
181
188
|
'dayjs',
|
|
182
189
|
],
|
|
190
|
+
/**
|
|
191
|
+
* @lilaquadrat/studio is deliberately NOT deduped: it is the backend
|
|
192
|
+
* package and a project may still hold a copy for other reasons, while
|
|
193
|
+
* a second one costs nothing here.
|
|
194
|
+
*
|
|
195
|
+
* @lilaquadrat/interfaces is types only, so it has nothing to dedupe.
|
|
196
|
+
*/
|
|
183
197
|
},
|
|
184
198
|
define: {
|
|
185
199
|
'__FRONTEND_CONFIG__' : JSON.stringify(config),
|