comand-component-library 3.3.83 → 3.3.85

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. package/dist/comand-component-library.js +5630 -3936
  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 +150 -21
  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
  }