comand-component-library 3.3.84 → 3.3.86

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.
Files changed (38) hide show
  1. package/dist/comand-component-library.js +5623 -3929
  2. package/dist/comand-component-library.umd.cjs +4 -4
  3. package/dist/style.css +1 -1
  4. package/package.json +2 -2
  5. package/src/App.vue +215 -112
  6. package/src/assets/data/component-structure.json +228 -0
  7. package/src/assets/data/form-elements.json +156 -0
  8. package/src/assets/data/opening-hours.json +79 -37
  9. package/src/components/CmdAddressData.vue +187 -201
  10. package/src/components/CmdAddressDataItem.vue +306 -0
  11. package/src/components/CmdBox.vue +1 -0
  12. package/src/components/CmdBoxWrapper.vue +53 -5
  13. package/src/components/CmdFancyBox.vue +31 -4
  14. package/src/components/CmdForm.vue +98 -4
  15. package/src/components/CmdFormElement.vue +5 -1
  16. package/src/components/CmdHeadline.vue +179 -52
  17. package/src/components/CmdImage.vue +205 -76
  18. package/src/components/CmdImageGallery.vue +88 -85
  19. package/src/components/CmdListOfLinks.vue +63 -43
  20. package/src/components/CmdListOfLinksItem.vue +97 -0
  21. package/src/components/CmdLoginForm.vue +3 -6
  22. package/src/components/CmdMultistepFormProgressBar.vue +37 -8
  23. package/src/components/CmdOpeningHours.vue +280 -63
  24. package/src/components/CmdOpeningHoursItem.vue +264 -0
  25. package/src/components/{CmdPager.vue → CmdPagination.vue} +2 -2
  26. package/src/components/CmdSlideshow.vue +137 -10
  27. package/src/components/CmdSocialNetworks.vue +115 -28
  28. package/src/components/CmdSocialNetworksItem.vue +184 -0
  29. package/src/components/CmdTable.vue +0 -1
  30. package/src/components/CmdTextImageBlock.vue +158 -0
  31. package/src/components/CmdThumbnailScroller.vue +132 -12
  32. package/src/components/CmdToggleDarkMode.vue +58 -1
  33. package/src/components/EditComponentWrapper.vue +553 -0
  34. package/src/index.js +2 -2
  35. package/src/mixins/EditMode.vue +28 -9
  36. package/src/utils/editmode.js +30 -5
  37. package/src/components/CmdTextBlock.vue +0 -73
  38. package/src/editmode/editModeContext.js +0 -50
@@ -0,0 +1,553 @@
1
+ <template>
2
+ <component
3
+ :is="componentTag || 'div'"
4
+ :class="['edit-component-wrapper', {active}]"
5
+ tabindex="0"
6
+ @click.stop="showActionButtons"
7
+ ref="editComponent"
8
+ :title="!active ? 'Click to select this element' : 'Select an action from the buttons in the top-left corner'"
9
+ :data-identifier="componentIdentifier">
10
+ <li v-if="componentTag === 'ul'" class="action-buttons-wrapper">
11
+ <!-- begin action-buttons -->
12
+ <ul v-show="active" class="flex-container no-flex action-buttons" :data-component="componentName">
13
+ <!-- begin add -->
14
+ <li>
15
+ <a :class="['icon-hexagon button confirm', {disabled: !addHandlerProvider && !itemProvider && !allowAddComponent}]"
16
+ href="#"
17
+ @click.prevent="addEntry($event)"
18
+ :title="!isOuterComponent ? 'Add new item/entry' : 'Add new component'">
19
+ <CmdIcon :iconClass="!isOuterComponent ? 'icon-plus' : 'icon-plus'"/>
20
+ </a>
21
+ </li>
22
+ <!-- end add -->
23
+
24
+ <!-- begin settings -->
25
+ <li>
26
+ <a :class="['icon-hexagon button primary', {disabled: editing || !hasSettings}]"
27
+ :href="editing ? null : '#'"
28
+ @click.prevent="editSettings"
29
+ title="Edit settings of this component">
30
+ <CmdIcon :iconClass="!isOuterComponent ? 'icon-cog' : 'icon-cogs'"/>
31
+ </a>
32
+ </li>
33
+ <!-- end settings -->
34
+
35
+ <!-- begin delete -->
36
+ <li>
37
+ <a class="icon-hexagon button-delete"
38
+ href="#"
39
+ @click.prevent="deleteComponent"
40
+ title="Delete this component (and its content)">
41
+ <CmdIcon iconClass="icon-trash"/>
42
+ </a>
43
+ </li>
44
+ <!-- end delete -->
45
+
46
+ <!-- begin cancel -->
47
+ <li v-if="!isOuterComponent">
48
+ <a :class="['icon-hexagon button-cancel', {disabled: !editing}]"
49
+ href="#"
50
+ @click.prevent="cancelComponent"
51
+ title="Cancel editing (changes will not be saved)">
52
+ <CmdIcon iconClass="icon-cancel"/>
53
+ </a>
54
+ </li>
55
+ <!-- end cancel -->
56
+
57
+ <!-- begin edit/save -->
58
+ <li v-if="!isOuterComponent">
59
+ <a v-if="editing"
60
+ class="icon-hexagon button-save"
61
+ href="#"
62
+ @click.prevent="saveComponent"
63
+ title="Save changes of this component">
64
+ <CmdIcon iconClass="icon-check"/>
65
+ </a>
66
+ <a v-else
67
+ :class="['icon-hexagon button', {disabled: editModeContext.settings.isEditing(componentIdentifier)}]"
68
+ href="#"
69
+ @click.prevent="editComponent"
70
+ title="Edit content of this component">
71
+ <CmdIcon iconClass="icon-edit"/>
72
+ </a>
73
+ </li>
74
+ <!-- end edit/save -->
75
+ </ul>
76
+ <!-- end action buttons -->
77
+ </li>
78
+ <template v-else>
79
+ <!-- begin action-buttons -->
80
+ <p v-if="isOuterComponent" class="component-name">{{ componentName }}</p>
81
+ <ul v-show="active"
82
+ class="flex-container no-flex action-buttons"
83
+ :data-component="componentName"
84
+ @mouseenter="addHighlightRelatedComponent"
85
+ @mouseleave="removeHighlightRelatedComponent">
86
+ <!-- begin add -->
87
+ <li>
88
+ <a :class="['icon-hexagon use-icon-as-background button confirm', {disabled: !addHandlerProvider && !itemProvider && !allowAddComponent}]"
89
+ href="#"
90
+ @click.prevent="addEntry"
91
+ :title="!isOuterComponent ? 'Add new item/entry' : 'Add new component'">
92
+ <CmdIcon :iconClass="!isOuterComponent ? 'icon-plus' : 'icon-plus'"/>
93
+ </a>
94
+ </li>
95
+ <!-- end add -->
96
+
97
+ <!-- begin settings -->
98
+ <li>
99
+ <a :class="['icon-hexagon use-icon-as-background button primary', {disabled: editing || !hasSettings}]"
100
+ :href="editing ? null : '#'"
101
+ @click.prevent="editSettings"
102
+ :title="'Edit settings for ' + componentName">
103
+ <CmdIcon :iconClass="!isOuterComponent ? 'icon-cog' : 'icon-cogs'"/>
104
+ </a>
105
+ </li>
106
+ <!-- end settings -->
107
+
108
+ <!-- begin delete -->
109
+ <li>
110
+ <a :class="['icon-hexagon use-icon-as-background button button-delete', {disabled: editing || !allowDeleteComponent}]"
111
+ href="#"
112
+ @click.prevent="deleteComponent"
113
+ :title="'Delete ' + componentName + ' (and its content)'">
114
+ <CmdIcon iconClass="icon-trash"/>
115
+ </a>
116
+ </li>
117
+ <!-- end delete -->
118
+
119
+ <!-- begin edit/save -->
120
+ <li v-if="!isOuterComponent">
121
+ <a :class="['icon-hexagon use-icon-as-background button cancel', {disabled: !editing}]"
122
+ href="#"
123
+ @click.prevent="cancelComponent"
124
+ title="Cancel editing (changes will not be saved)">
125
+ <CmdIcon iconClass="icon-cancel"/>
126
+ </a>
127
+ </li>
128
+ <li v-if="!isOuterComponent">
129
+ <a v-if="editing"
130
+ class="icon-hexagon use-icon-as-background button confirm" href="#"
131
+ @click.prevent="saveComponent"
132
+ :title="'Save changes of ' + componentName">
133
+ <CmdIcon iconClass="icon-check"/>
134
+ </a>
135
+ <a v-else
136
+ :class="['icon-hexagon use-icon-as-background button confirm', {disabled: editModeContext.settings.isEditing(componentIdentifier)}]"
137
+ href="#"
138
+ @click.prevent="editComponent"
139
+ :title="'Edit content for ' + componentName">
140
+ <CmdIcon iconClass="icon-edit"/>
141
+ </a>
142
+ </li>
143
+ <!-- end edit/save -->
144
+ </ul>
145
+ <!-- end action buttons -->
146
+ </template>
147
+ <!-- begin slot -->
148
+ <slot :editing="editing"></slot>
149
+ <!-- end slot -->
150
+ </component>
151
+ </template>
152
+
153
+ <script>
154
+ import componentStructure from "../assets/data/component-structure.json"
155
+
156
+ import {componentPathAsString, findEditComponentWrapper} from "../utils/editmode.js"
157
+ import {getCurrentInstance} from "vue"
158
+
159
+ export default {
160
+ name: "EditComponentWrapper",
161
+ inject: {
162
+ editModeContext: {
163
+ default: null
164
+ }
165
+ },
166
+ props: {
167
+ allowedComponentTypes: {
168
+ type: Array
169
+ },
170
+ componentName: {
171
+ type: String
172
+ },
173
+ componentProps: {
174
+ type: Object
175
+ },
176
+ componentPath: {
177
+ type: Array,
178
+ required: true
179
+ },
180
+ allowAddComponent: {
181
+ type: Boolean
182
+ },
183
+ allowDeleteComponent: {
184
+ type: Boolean,
185
+ default: true
186
+ },
187
+ showComponentName: {
188
+ type: Boolean,
189
+ default: true
190
+ },
191
+ componentTag: {
192
+ type: String
193
+ },
194
+ itemProvider: {
195
+ type: Function
196
+ }
197
+ },
198
+ data() {
199
+ return {
200
+ componentIdentifier: "",
201
+ editStateListeners: [],
202
+ updateHandlerProviders: [],
203
+ addHandlerProvider: null,
204
+ showComponentSelection: false,
205
+ showAddComponentButtons: false,
206
+ addComponentLevel: ""
207
+ }
208
+ },
209
+ computed: {
210
+ isOuterComponent() {
211
+ return !findEditComponentWrapper(this.$parent, component => component?.componentName !== "CmdContainer")
212
+ },
213
+ active() {
214
+ if (!this.editModeContext) {
215
+ return false
216
+ }
217
+ const parentEditComponentWrapper = findEditComponentWrapper(this.$parent, component => component?.componentName !== "CmdContainer");
218
+ if (parentEditComponentWrapper) {
219
+ return !!this.editModeContext.system.isActiveChildComponent(buildComponentPath(this))
220
+ }
221
+ return !!this.editModeContext.system.isActiveComponent(buildComponentPath(this))
222
+ },
223
+ editing() {
224
+ return this.editModeContext?.content.isEditing(this.componentIdentifier)
225
+ },
226
+ hasSettings() {
227
+ const settingsComponentName = `${this.componentName}Settings`
228
+ return !!getCurrentInstance().appContext.components[settingsComponentName]
229
+ }
230
+ },
231
+ methods: {
232
+ addHighlightRelatedComponent(event) {
233
+ const currentElement = event.target
234
+ currentElement.parentNode.classList.add("highlight")
235
+ },
236
+ removeHighlightRelatedComponent(event) {
237
+ const currentElement = event.target
238
+ currentElement.parentNode.classList.remove("highlight")
239
+ },
240
+ // provide actions from store as methods inside this component
241
+ showActionButtons() {
242
+ const parentEditComponentWrapper = findEditComponentWrapper(this.$parent, component => component?.componentName !== "CmdContainer")
243
+ this.editModeContext.system.setActiveComponent(buildComponentPath(parentEditComponentWrapper), buildComponentPath(this))
244
+ },
245
+ deleteComponent() {
246
+ if (!this.editing && this.allowDeleteComponent && confirm("Delete this component and its content?")) {
247
+ this.editModeContext?.store.deleteContent(buildComponentPath(this))
248
+ // close settings sidebar if component is deleted
249
+ this.editModeContext.settings.stopEditing()
250
+ }
251
+ },
252
+ deleteInnerComponent() {
253
+ this.editModeContext.store.deleteContent(buildComponentPath(this))
254
+ // stop editing to close settings-sidebar
255
+ this.editModeContext.settings.stopEditing()
256
+ },
257
+ cancelComponent(event) {
258
+ if (this.editing) {
259
+ event.stopPropagation()
260
+ this.editModeContext.content.stopEditing()
261
+ }
262
+ },
263
+ editComponent(event) {
264
+ event?.stopPropagation()
265
+
266
+ // avoid component from resetting editing-flag
267
+ if (!event) {
268
+ this.showActionButtons()
269
+ }
270
+
271
+ const component = this.$refs.editComponent;
272
+ this.editModeContext.content.startEditing(this.componentIdentifier)
273
+ // wait until input in inserted into DOM on next tick
274
+ this.$nextTick(() => component.querySelector("input")?.focus())
275
+ },
276
+ saveComponent() {
277
+ this.editModeContext.store.updateContent(
278
+ buildComponentPath(this),
279
+ this.updateHandlerProviders.map(provider => provider()))
280
+ this.editModeContext.content.stopEditing()
281
+ },
282
+ editSettings(event, action) {
283
+ event.stopPropagation()
284
+
285
+ if (!this.editing && this.hasSettings) {
286
+ this.editModeContext.settings.startEditing(
287
+ this.componentIdentifier,
288
+ this.componentName,
289
+ this.componentProps,
290
+ this.allowedComponentTypes,
291
+ buildComponentPath(this),
292
+ this.saveSettings,
293
+ this.deleteInnerComponent,
294
+ action || 'edit'
295
+ )
296
+ }
297
+ },
298
+ addEntry(event) {
299
+ if (this.itemProvider) {
300
+ // if related element is inner component (add item/entry)
301
+ this.editModeContext.content.addContent(buildComponentPath(this), this.itemProvider)
302
+ } else {
303
+ // if related element is outer component (open settings)
304
+ this.editSettings(event, 'add')
305
+ }
306
+ },
307
+ saveSettings(updateCallback) {
308
+ this.editModeContext.store.updateSettings(
309
+ buildComponentPath(this),
310
+ updateCallback)
311
+ this.editModeContext.settings.stopEditing()
312
+ },
313
+ addEditStateListener(listener) {
314
+ this.editStateListeners.push(listener)
315
+ listener(this.editing)
316
+ },
317
+ addUpdateHandlerProvider(updateHandlerProvider) {
318
+ this.updateHandlerProviders.push(updateHandlerProvider)
319
+ },
320
+ setAddHandlerProvider(addHandlerProvider) {
321
+ // assign given function to data-property
322
+ if (addHandlerProvider) {
323
+ this.addHandlerProvider = addHandlerProvider
324
+ }
325
+ }
326
+ },
327
+ watch: {
328
+ componentPath: {
329
+ handler() {
330
+ this.componentIdentifier = componentPathAsString(buildComponentPath(this))
331
+ },
332
+ immediate: true,
333
+ deep: true
334
+ },
335
+ editing(value) {
336
+ this.editStateListeners.forEach(listener => listener(value))
337
+ }
338
+ }
339
+ }
340
+
341
+ function buildComponentPath(component) {
342
+ const path = []
343
+ for (let parent = component; parent; parent = findEditComponentWrapper(parent.$parent)) {
344
+ if (parent.componentPath) {
345
+ path.unshift(...parent.componentPath)
346
+ }
347
+ }
348
+ return path
349
+ }
350
+ </script>
351
+
352
+ <style lang="scss">
353
+ @mixin edit-border {
354
+ border: .1rem dashed transparent;
355
+ transition: var(--default-transition);
356
+
357
+ &:hover, &:active, &:focus {
358
+ border-color: var(--primary-color);
359
+ background: hsla(0, 0%, 100%, 0.1);
360
+ transition: var(--default-transition);
361
+ }
362
+
363
+ &:focus, &.active {
364
+ border-style: solid;
365
+ border-color: var(--primary-color);
366
+
367
+ .action-buttons {
368
+ opacity: 1;
369
+ transition: var(--default-transition);
370
+ }
371
+ }
372
+ }
373
+
374
+ .edit-component-wrapper {
375
+ @include edit-border;
376
+
377
+ display: block;
378
+
379
+ &.highlight {
380
+ border-color: var(--hyperlink-color-highlighted);
381
+ border-style: dotted;
382
+ }
383
+
384
+ .cmd-headline {
385
+ margin: 0;
386
+ }
387
+
388
+ .component-name {
389
+ display: none;
390
+ position: absolute;
391
+ left: auto;
392
+ right: 10rem;
393
+ font-style: italic;
394
+ z-index: 10;
395
+ padding: .2rem;
396
+ background: var(--primary-color);
397
+ }
398
+
399
+ &.active {
400
+ .component-name {
401
+ display: block;
402
+ }
403
+ }
404
+
405
+ .action-buttons {
406
+ --action-buttons-size: 3.6rem;
407
+
408
+ transition: var(--default-transition);
409
+ gap: 0;
410
+ position: absolute;
411
+ top: -1.8rem;
412
+ right: 0.8rem;
413
+ z-index: 1;
414
+ margin: 0;
415
+
416
+ li {
417
+ &:nth-child(odd) {
418
+ top: 0;
419
+ }
420
+
421
+ &:nth-child(even) {
422
+ top: -1.6rem;
423
+ }
424
+
425
+ &:nth-child(5) {
426
+ right: 0;
427
+ }
428
+
429
+ &:nth-child(4) {
430
+ right: calc(var(--action-buttons-size) * -0.25);
431
+ }
432
+
433
+ &:nth-child(3) {
434
+ right: calc(var(--action-buttons-size) * -0.5);
435
+ }
436
+
437
+ &:nth-child(2) {
438
+ right: calc(var(--action-buttons-size) * -0.75);
439
+ }
440
+
441
+ &:nth-child(1) {
442
+ right: calc(var(--action-buttons-size) * -1);
443
+ }
444
+ }
445
+ }
446
+
447
+ .edit-items {
448
+ .action-buttons {
449
+ gap: var(--default-gap-third);
450
+ top: -2.3rem;
451
+ left: 0;
452
+ right: auto; /* avoids container to be stretched */
453
+ flex-wrap: nowrap;
454
+ border-bottom: 0;
455
+ backdrop-filter: grayscale(1) brightness(1.5) blur(2rem) opacity(85%);
456
+ border-radius: .5rem;
457
+
458
+ li {
459
+ top: 0;
460
+ right: 0;
461
+ left: auto;
462
+
463
+ &:nth-child(5) {
464
+ right: 0;
465
+ }
466
+
467
+ &:nth-child(4) {
468
+ right: var(--icon-font-size);
469
+ }
470
+
471
+ &:nth-child(3) {
472
+ right: calc(var(--icon-font-size) * 2);
473
+ }
474
+
475
+ &:nth-child(2) {
476
+ right: calc(var(--icon-font-size) * 3);
477
+ }
478
+
479
+ &:nth-child(1) {
480
+ right: calc(var(--icon-font-size) * 4);
481
+ }
482
+
483
+ a.button {
484
+ border-radius: var(--full-circle);
485
+ font-size: 1rem;
486
+ display: block;
487
+ padding: 0.5rem;
488
+ background: var(--button-background-color);
489
+
490
+ &:before {
491
+ content: "";
492
+ font-size: 1rem;
493
+
494
+ }
495
+
496
+ span[class*="icon-"] {
497
+ font-size: var(--icon-size-small);
498
+ position: relative;
499
+ top: 0;
500
+ left: 0;
501
+ transform: none;
502
+ }
503
+
504
+ &.primary {
505
+ background: var(--primary-color);
506
+ }
507
+ }
508
+ }
509
+ }
510
+
511
+ &.active {
512
+ //width: 100%; /* stretch inside flex-container */
513
+ background: var(--pure-white);
514
+ }
515
+ }
516
+
517
+ // begin component-level only
518
+ &:not(.edit-items) {
519
+ > ul {
520
+ > li {
521
+ a.button {
522
+ background: none !important;
523
+ }
524
+ }
525
+ }
526
+ }
527
+ // end component-level only
528
+ }
529
+
530
+ ul.edit-component-wrapper {
531
+ border: 0;
532
+
533
+ > li {
534
+ list-style-type: none;
535
+ margin: 0;
536
+
537
+ &.action-buttons-wrapper {
538
+ display: flex;
539
+ justify-content: flex-end;
540
+ padding-top: .1rem;
541
+
542
+ .action-buttons {
543
+ position: relative;
544
+ top: auto;
545
+ }
546
+ }
547
+
548
+ &.item-wrapper {
549
+ @include edit-border;
550
+ }
551
+ }
552
+ }
553
+ </style>
package/src/index.js CHANGED
@@ -25,7 +25,7 @@ export { default as CmdLoginForm } from '@/components/CmdLoginForm.vue'
25
25
  export { default as CmdMainNavigation } from '@/components/CmdMainNavigation.vue'
26
26
  export { default as CmdMultistepFormProgressBar } from '@/components/CmdMultistepFormProgressBar.vue'
27
27
  export { default as CmdOpeningHours } from '@/components/CmdOpeningHours.vue'
28
- export { default as CmdPager } from '@/components/CmdPager.vue'
28
+ export { default as CmdPager } from '@/components/CmdPagination.vue'
29
29
  export { default as CmdProgressBar } from '@/components/CmdProgressBar.vue'
30
30
  export { default as CmdSidebar } from '@/components/CmdSidebar.vue'
31
31
  export { default as CmdSiteFooter } from '@/components/CmdSiteFooter.vue'
@@ -38,7 +38,7 @@ export { default as CmdSwitchLanguage } from '@/components/CmdSwitchLanguage.vue
38
38
  export { default as CmdSystemMessage } from '@/components/CmdSystemMessage.vue'
39
39
  export { default as CmdTable } from '@/components/CmdTable.vue'
40
40
  export { default as CmdTabs } from '@/components/CmdTabs.vue'
41
- export { default as CmdTextBlock } from '@/components/CmdTextBlock.vue'
41
+ export { default as CmdTextImageBlock } from '@/components/CmdTextImageBlock.vue'
42
42
  export { default as CmdThumbnailScroller } from '@/components/CmdThumbnailScroller.vue'
43
43
  export { default as CmdToggleDarkMode } from '@/components/CmdToggleDarkMode.vue'
44
44
  export { default as CmdTooltip } from '@/components/CmdTooltip.vue'
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import {findEditComponentWrapper} from "../utils/editmode.js"
2
+ import {findEditComponentWrapper, findEditSettingsComponentWrapper, findMainSidebar} from "../utils/editmode.js"
3
3
 
4
4
  export default {
5
5
  inject: {
@@ -7,20 +7,39 @@ export default {
7
7
  default: null
8
8
  }
9
9
  },
10
+ props: {
11
+ componentPath: {
12
+ type: Array
13
+ },
14
+ editModeConfig: {
15
+ type: Object
16
+ }
17
+ },
10
18
  data() {
11
19
  return {
12
- editing: false
20
+ editing: false,
21
+ settingsContext: false,
22
+ mainSidebarContext: false
13
23
  }
14
24
  },
15
- created() {
16
- const editComponentWrapper = findEditComponentWrapper(this.$parent)
17
- if (editComponentWrapper) {
18
- editComponentWrapper.addEditStateListener(editing => this.editing = editing)
19
- editComponentWrapper.addUpdateHandlerProvider(this.updateHandlerProvider)
20
- editComponentWrapper.setAddHandlerProvider(this.addHandlerProvider)
21
- }
25
+ mounted() {
26
+ this.initializeEditMode()
22
27
  },
23
28
  methods: {
29
+ initializeEditMode() {
30
+ if (this.$refs.editComponentWrapper) {
31
+ this.$refs.editComponentWrapper?.addUpdateHandlerProvider(this.updateHandlerProvider)
32
+ } else {
33
+ const editComponentWrapper = findEditComponentWrapper(this.$parent);
34
+ if (editComponentWrapper) {
35
+ editComponentWrapper.addEditStateListener(editing => this.editing = editing)
36
+ editComponentWrapper.addUpdateHandlerProvider(this.updateHandlerProvider)
37
+ editComponentWrapper.setAddHandlerProvider(this.addHandlerProvider)
38
+ }
39
+ }
40
+ this.mainSidebarContext = !!findMainSidebar(this)
41
+ this.settingsContext = !!findEditSettingsComponentWrapper(this)
42
+ },
24
43
  updateHandlerProvider() {
25
44
  return {}
26
45
  }
@@ -1,9 +1,21 @@
1
- function findEditComponentWrapper(component) {
2
- if (component?.$options?.name === "EditComponentWrapper") {
1
+ function findEditComponentWrapper(component, filter) {
2
+ return findParentComponent(component, "EditComponentWrapper", filter)
3
+ }
4
+
5
+ function findEditSettingsComponentWrapper(component) {
6
+ return findParentComponent(component, "EditModeSettingsSidebar")
7
+ }
8
+
9
+ function findMainSidebar(component) {
10
+ return findParentComponent(component, "EditModeMainSidebar")
11
+ }
12
+
13
+ function findParentComponent(component, parentComponentName, filter) {
14
+ if (component?.$options?.name === parentComponentName && (filter == null || filter(component))) {
3
15
  return component
4
16
  }
5
17
  if (component?.$parent) {
6
- return findEditComponentWrapper(component.$parent)
18
+ return findParentComponent(component.$parent, parentComponentName, filter)
7
19
  }
8
20
  return null
9
21
  }
@@ -11,7 +23,9 @@ function findEditComponentWrapper(component) {
11
23
  function buildComponentPath(component, ...extraPathElements) {
12
24
  const path = []
13
25
  for (let parent = findEditComponentWrapper(component); parent; parent = findEditComponentWrapper(parent.$parent)) {
14
- path.unshift(...parent.componentPath)
26
+ if (parent.componentPath) {
27
+ path.unshift(...parent.componentPath);
28
+ }
15
29
  }
16
30
  path.push(...extraPathElements)
17
31
  return path
@@ -34,9 +48,20 @@ function updateHandlerProvider(component, options) {
34
48
  return options
35
49
  }
36
50
 
51
+ function highlightSection(sectionId) {
52
+ document.querySelectorAll(".section-wrapper.active").forEach((section) => section.classList.remove("active"))
53
+ // get the edit-mode-wrapper of a section
54
+ const element = document.getElementById("edit-mode-" + sectionId)
55
+ element.scrollIntoView()
56
+ element.classList.add("active")
57
+ }
58
+
37
59
  export {
38
60
  findEditComponentWrapper,
61
+ findEditSettingsComponentWrapper,
62
+ findMainSidebar,
39
63
  buildComponentPath,
40
64
  componentPathAsString,
41
- updateHandlerProvider
65
+ updateHandlerProvider,
66
+ highlightSection
42
67
  }