apostrophe 3.63.1 → 4.0.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.
Files changed (150) hide show
  1. package/.eslintrc +13 -4
  2. package/CHANGELOG.md +35 -0
  3. package/defaults.js +1 -0
  4. package/modules/@apostrophecms/admin-bar/ui/apos/apps/AposAdminBar.js +7 -17
  5. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBar.vue +14 -16
  6. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBarLocale.vue +1 -1
  7. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBarMenu.vue +22 -15
  8. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBarUser.vue +2 -2
  9. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +13 -8
  10. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextModeAndSettings.vue +18 -10
  11. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextTitle.vue +4 -4
  12. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextUndoRedo.vue +14 -8
  13. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposSavingIndicator.vue +2 -1
  14. package/modules/@apostrophecms/area/ui/apos/apps/AposAreas.js +36 -54
  15. package/modules/@apostrophecms/area/ui/apos/components/AposAreaContextualMenu.vue +20 -25
  16. package/modules/@apostrophecms/area/ui/apos/components/AposAreaEditor.vue +5 -12
  17. package/modules/@apostrophecms/area/ui/apos/components/AposAreaExpandedMenu.vue +11 -3
  18. package/modules/@apostrophecms/area/ui/apos/components/AposAreaMenu.vue +6 -6
  19. package/modules/@apostrophecms/area/ui/apos/components/AposAreaMenuItem.vue +3 -2
  20. package/modules/@apostrophecms/area/ui/apos/components/AposAreaWidget.vue +31 -44
  21. package/modules/@apostrophecms/area/ui/apos/components/AposWidgetControls.vue +6 -6
  22. package/modules/@apostrophecms/asset/index.js +25 -12
  23. package/modules/@apostrophecms/asset/lib/webpack/apos/webpack.config.js +3 -3
  24. package/modules/@apostrophecms/asset/lib/webpack/apos/webpack.vue.js +7 -1
  25. package/modules/@apostrophecms/busy/ui/apos/apps/AposBusy.js +8 -7
  26. package/modules/@apostrophecms/busy/ui/apos/components/TheAposBusy.vue +1 -1
  27. package/modules/@apostrophecms/command-menu/ui/apos/apps/AposCommandMenu.js +11 -29
  28. package/modules/@apostrophecms/command-menu/ui/apos/components/AposCommandMenuShortcut.vue +6 -6
  29. package/modules/@apostrophecms/command-menu/ui/apos/components/TheAposCommandMenu.vue +10 -7
  30. package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocEditor.vue +20 -15
  31. package/modules/@apostrophecms/doc-type/ui/apos/logic/AposDocContextMenu.js +1 -1
  32. package/modules/@apostrophecms/i18n/ui/apos/components/AposI18nLocalize.vue +36 -27
  33. package/modules/@apostrophecms/i18n/ui/apos/components/AposI18nLocalizeErrors.vue +3 -3
  34. package/modules/@apostrophecms/image/ui/apos/components/AposImageCropper.vue +5 -5
  35. package/modules/@apostrophecms/image/ui/apos/components/AposImageRelationshipEditor.vue +6 -6
  36. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManager.vue +23 -16
  37. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerDisplay.vue +11 -11
  38. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue +28 -21
  39. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerSelections.vue +1 -1
  40. package/modules/@apostrophecms/image/ui/apos/components/AposMediaUploader.vue +5 -4
  41. package/modules/@apostrophecms/login/ui/apos/apps/AposLogin.js +6 -7
  42. package/modules/@apostrophecms/login/ui/apos/components/AposForgotPasswordForm.vue +3 -3
  43. package/modules/@apostrophecms/login/ui/apos/components/AposLoginForm.vue +10 -10
  44. package/modules/@apostrophecms/login/ui/apos/components/AposResetPasswordForm.vue +1 -1
  45. package/modules/@apostrophecms/login/ui/apos/components/TheAposLogin.vue +2 -2
  46. package/modules/@apostrophecms/modal/ui/apos/apps/AposModals.js +60 -87
  47. package/modules/@apostrophecms/modal/ui/apos/components/AposDocsManagerToolbar.vue +15 -11
  48. package/modules/@apostrophecms/modal/ui/apos/components/AposModal.vue +8 -2
  49. package/modules/@apostrophecms/modal/ui/apos/components/AposModalBreadcrumbs.vue +7 -4
  50. package/modules/@apostrophecms/modal/ui/apos/components/AposModalConfirm.vue +5 -5
  51. package/modules/@apostrophecms/modal/ui/apos/components/AposModalShareDraft.vue +8 -8
  52. package/modules/@apostrophecms/modal/ui/apos/components/AposModalToolbar.vue +7 -7
  53. package/modules/@apostrophecms/modal/ui/apos/components/TheAposModals.vue +22 -4
  54. package/modules/@apostrophecms/modal/ui/apos/composables/AposFocus.js +95 -0
  55. package/modules/@apostrophecms/modal/ui/apos/mixins/AposDocsManagerMixin.js +2 -3
  56. package/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js +6 -0
  57. package/modules/@apostrophecms/multisite-i18n/i18n/aposMultisite/en.json +48 -0
  58. package/modules/@apostrophecms/multisite-i18n/index.js +7 -0
  59. package/modules/@apostrophecms/notification/index.js +4 -4
  60. package/modules/@apostrophecms/notification/ui/apos/apps/AposNotification.js +6 -9
  61. package/modules/@apostrophecms/notification/ui/apos/components/AposNotification.vue +12 -8
  62. package/modules/@apostrophecms/oembed/index.js +10 -3
  63. package/modules/@apostrophecms/oembed-field/ui/apos/components/AposInputOembed.vue +4 -4
  64. package/modules/@apostrophecms/page/ui/apos/components/AposPagesManager.vue +15 -11
  65. package/modules/@apostrophecms/page/ui/apos/logic/AposPagesManager.js +1 -1
  66. package/modules/@apostrophecms/permission/ui/apos/components/AposInputRole.vue +3 -3
  67. package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +25 -17
  68. package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManagerDisplay.vue +24 -20
  69. package/modules/@apostrophecms/piece-type/ui/apos/components/AposRelationshipEditor.vue +15 -11
  70. package/modules/@apostrophecms/polymorphic-type/index.js +0 -19
  71. package/modules/@apostrophecms/rich-text-widget/index.js +1 -0
  72. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposImageControlDialog.vue +7 -6
  73. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +31 -30
  74. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapAnchor.vue +12 -10
  75. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapLink.vue +9 -8
  76. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapStyles.vue +3 -3
  77. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapTable.vue +3 -3
  78. package/modules/@apostrophecms/schema/index.js +30 -1
  79. package/modules/@apostrophecms/schema/ui/apos/components/AposArrayEditor.vue +10 -8
  80. package/modules/@apostrophecms/schema/ui/apos/components/AposInputArea.vue +5 -3
  81. package/modules/@apostrophecms/schema/ui/apos/components/AposInputArray.vue +81 -277
  82. package/modules/@apostrophecms/schema/ui/apos/components/AposInputAttachment.vue +4 -2
  83. package/modules/@apostrophecms/schema/ui/apos/components/AposInputBoolean.vue +24 -14
  84. package/modules/@apostrophecms/schema/ui/apos/components/AposInputCheckboxes.vue +7 -6
  85. package/modules/@apostrophecms/schema/ui/apos/components/AposInputColor.vue +10 -7
  86. package/modules/@apostrophecms/schema/ui/apos/components/AposInputObject.vue +3 -3
  87. package/modules/@apostrophecms/schema/ui/apos/components/AposInputRadio.vue +5 -4
  88. package/modules/@apostrophecms/schema/ui/apos/components/AposInputRelationship.vue +15 -12
  89. package/modules/@apostrophecms/schema/ui/apos/components/AposInputSelect.vue +1 -1
  90. package/modules/@apostrophecms/schema/ui/apos/components/AposInputSlug.vue +16 -12
  91. package/modules/@apostrophecms/schema/ui/apos/components/AposInputString.vue +19 -11
  92. package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +1 -1
  93. package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +65 -21
  94. package/modules/@apostrophecms/schema/ui/apos/components/AposSubform.vue +2 -2
  95. package/modules/@apostrophecms/schema/ui/apos/logic/AposArrayEditor.js +0 -4
  96. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArea.js +3 -3
  97. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArray.js +15 -4
  98. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputAttachment.js +3 -3
  99. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputCheckboxes.js +7 -7
  100. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputColor.js +5 -8
  101. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputDateAndTime.js +1 -1
  102. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputObject.js +1 -1
  103. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRadio.js +1 -1
  104. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRelationship.js +12 -9
  105. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputSelect.js +2 -2
  106. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputString.js +6 -8
  107. package/modules/@apostrophecms/schema/ui/apos/logic/AposSchema.js +39 -13
  108. package/modules/@apostrophecms/schema/ui/apos/logic/AposSubform.js +1 -1
  109. package/modules/@apostrophecms/schema/ui/apos/mixins/AposInputMixin.js +9 -9
  110. package/modules/@apostrophecms/schema/ui/apos/scss/AposInputArray.scss +205 -0
  111. package/modules/@apostrophecms/settings/ui/apos/components/AposSettingsManager.vue +4 -4
  112. package/modules/@apostrophecms/settings/ui/apos/logic/AposSettingsManager.js +4 -4
  113. package/modules/@apostrophecms/submitted-draft/ui/apos/components/AposSubmittedDraftIcon.vue +5 -4
  114. package/modules/@apostrophecms/ui/ui/apos/components/AposButton.vue +4 -4
  115. package/modules/@apostrophecms/ui/ui/apos/components/AposButtonGroup.vue +6 -6
  116. package/modules/@apostrophecms/ui/ui/apos/components/AposButtonSplit.vue +120 -113
  117. package/modules/@apostrophecms/ui/ui/apos/components/AposCheckbox.vue +19 -19
  118. package/modules/@apostrophecms/ui/ui/apos/components/AposCombo.vue +15 -15
  119. package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenu.vue +216 -191
  120. package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenuDialog.vue +77 -65
  121. package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenuItem.vue +1 -1
  122. package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenuTip.vue +28 -50
  123. package/modules/@apostrophecms/ui/ui/apos/components/AposFile.vue +5 -5
  124. package/modules/@apostrophecms/ui/ui/apos/components/AposFilterMenu.vue +4 -4
  125. package/modules/@apostrophecms/ui/ui/apos/components/AposMinMaxCount.vue +5 -5
  126. package/modules/@apostrophecms/ui/ui/apos/components/AposPager.vue +14 -8
  127. package/modules/@apostrophecms/ui/ui/apos/components/AposSlat.vue +2 -2
  128. package/modules/@apostrophecms/ui/ui/apos/components/AposSlatList.vue +53 -59
  129. package/modules/@apostrophecms/ui/ui/apos/components/AposSubformPreview.vue +2 -2
  130. package/modules/@apostrophecms/ui/ui/apos/components/AposTagApply.vue +40 -35
  131. package/modules/@apostrophecms/ui/ui/apos/components/AposToggle.vue +2 -2
  132. package/modules/@apostrophecms/ui/ui/apos/components/AposTree.vue +9 -11
  133. package/modules/@apostrophecms/ui/ui/apos/components/AposTreeHeader.vue +5 -3
  134. package/modules/@apostrophecms/ui/ui/apos/components/AposTreeRows.vue +129 -129
  135. package/modules/@apostrophecms/ui/ui/apos/composables/AposTheme.js +11 -0
  136. package/modules/@apostrophecms/ui/ui/apos/lib/click-outside-element.js +4 -4
  137. package/modules/@apostrophecms/ui/ui/apos/lib/i18next.js +56 -50
  138. package/modules/@apostrophecms/ui/ui/apos/lib/tooltip.js +191 -0
  139. package/modules/@apostrophecms/ui/ui/apos/lib/vue.js +19 -10
  140. package/modules/@apostrophecms/ui/ui/apos/mixins/AposAdvisoryLockMixin.js +1 -1
  141. package/modules/@apostrophecms/ui/ui/apos/scss/global/_tables.scss +1 -1
  142. package/modules/@apostrophecms/ui/ui/apos/scss/global/_tooltips.scss +6 -22
  143. package/modules/@apostrophecms/ui/ui/apos/scss/shared/_table-rows.scss +1 -1
  144. package/modules/@apostrophecms/widget-type/index.js +8 -2
  145. package/modules/@apostrophecms/widget-type/ui/apos/components/AposWidgetEditor.vue +26 -22
  146. package/modules/@apostrophecms/widget-type/ui/apos/mixins/AposWidgetMixin.js +4 -4
  147. package/package.json +31 -44
  148. package/test/schemas.js +10 -4
  149. package/modules/@apostrophecms/ui/ui/apos/lib/localized-v-tooltip.js +0 -63
  150. package/modules/@apostrophecms/ui/ui/apos/lib/tooltip-options.js +0 -13
@@ -1,28 +1,29 @@
1
1
  <template>
2
2
  <div class="apos-area-menu" :class="{'apos-is-focused': groupIsFocused}">
3
3
  <AposContextMenu
4
- :disabled="isDisabled"
5
- :button="buttonOptions"
6
4
  v-bind="extendedContextMenuOptions"
7
- @open="menuOpen"
8
- @close="menuClose"
9
5
  ref="contextMenu"
6
+ :disabled="isDisabled"
7
+ :button="buttonOptions"
10
8
  :popover-modifiers="inContext ? ['z-index-in-context'] : []"
11
9
  >
12
10
  <ul class="apos-area-menu__wrapper">
13
11
  <li
14
- class="apos-area-menu__item"
15
12
  v-for="(item, itemIndex) in myMenu"
16
13
  :key="item.type ? `${item.type}_${item.label}` : item.label"
17
- :class="{'apos-has-group': item.items}"
18
14
  :ref="`item-${itemIndex}`"
15
+ class="apos-area-menu__item"
16
+ :class="{'apos-has-group': item.items}"
19
17
  >
20
18
  <dl v-if="item.items" class="apos-area-menu__group">
21
19
  <dt>
22
20
  <button
23
- :for="item.label" class="apos-area-menu__group-label"
24
- v-if="item.items" tabindex="0"
21
+ v-if="item.items"
25
22
  :id="`${menuId}-trigger-${itemIndex}`"
23
+ ref="groupButton"
24
+ :for="item.label"
25
+ class="apos-area-menu__group-label"
26
+ tabindex="0"
26
27
  :aria-controls="`${menuId}-group-${itemIndex}`"
27
28
  @focus="groupFocused"
28
29
  @blur="groupBlurred"
@@ -33,33 +34,33 @@
33
34
  @keydown.prevent.arrow-up="switchGroup(itemIndex, -1)"
34
35
  @keydown.prevent.home="switchGroup(itemIndex, 0)"
35
36
  @keydown.prevent.end="switchGroup(itemIndex, null)"
36
- ref="groupButton"
37
37
  >
38
38
  <span>{{ item.label }}</span>
39
39
  <chevron-up-icon
40
40
  class="apos-area-menu__group-chevron"
41
- :class="{'apos-is-active': itemIndex === active}" :size="13"
41
+ :class="{'apos-is-active': itemIndex === active}"
42
+ :size="13"
42
43
  />
43
44
  </button>
44
45
  </dt>
45
46
  <dd class="apos-area-menu__group-list" role="region">
46
47
  <ul
48
+ :id="`${menuId}-group-${itemIndex}`"
47
49
  class="apos-area-menu__items apos-area-menu__items--accordion"
48
50
  :class="{'apos-is-active': active === itemIndex}"
49
- :id="`${menuId}-group-${itemIndex}`"
50
51
  :aria-labelledby="`${menuId}-trigger-${itemIndex}`"
51
52
  :aria-expanded="active === itemIndex ? 'true' : 'false'"
52
53
  >
53
54
  <li
54
- class="apos-area-menu__item"
55
55
  v-for="(child, childIndex) in item.items"
56
56
  :key="child.name"
57
57
  :ref="`child-${index}-${childIndex}`"
58
+ class="apos-area-menu__item"
58
59
  >
59
60
  <AposAreaMenuItem
60
- @click="add(child)"
61
61
  :item="child"
62
62
  :tabbable="itemIndex === active"
63
+ @click="add(child)"
63
64
  @up="switchItem(`child-${itemIndex}-${childIndex - 1}`, -1)"
64
65
  @down="switchItem(`child-${itemIndex}-${childIndex + 1}`, 1)"
65
66
  />
@@ -69,8 +70,8 @@
69
70
  </dl>
70
71
  <AposAreaMenuItem
71
72
  v-else
72
- @click="add(item)"
73
73
  :item="item"
74
+ @click="add(item)"
74
75
  @up="switchItem(`item-${itemIndex - 1}`, -1)"
75
76
  @down="switchItem(`item-${itemIndex + 1}`, 1)"
76
77
  />
@@ -118,7 +119,7 @@ export default {
118
119
  }
119
120
  }
120
121
  },
121
- emits: [ 'menu-close', 'menu-open', 'add' ],
122
+ emits: [ 'add' ],
122
123
  data() {
123
124
  return {
124
125
  active: 0,
@@ -192,17 +193,11 @@ export default {
192
193
  this.inContext = !apos.util.closest(this.$el, '[data-apos-schema-area]');
193
194
  },
194
195
  methods: {
195
- menuClose(e) {
196
- this.$emit('menu-close', e);
197
- },
198
- menuOpen(e) {
199
- this.$emit('menu-open', e);
200
- },
201
196
  async add(item) {
202
197
  // Potential TODO: If we find ourselves manually flipping these bits in other AposContextMenu overrides
203
198
  // we should consider refactoring contextmenus to be able to self close when any click takes place within their el
204
199
  // as it is often the logical experience (not always, see tag menus and filters)
205
- this.$refs.contextMenu.isOpen = false;
200
+ this.$refs.contextMenu.hide();
206
201
  this.$emit('add', {
207
202
  ...item,
208
203
  index: this.index
@@ -278,11 +273,11 @@ export default {
278
273
 
279
274
  <style lang="scss" scoped>
280
275
 
281
- .apos-area-menu.apos-is-focused ::v-deep .apos-context-menu__inner {
276
+ .apos-area-menu.apos-is-focused :deep(.apos-context-menu__inner) {
282
277
  border: 1px solid var(--a-base-4);
283
278
  }
284
279
 
285
- .apos-area-menu.apos-is-focused ::v-deep .apos-context-menu__tip-outline {
280
+ .apos-area-menu.apos-is-focused :deep(.apos-context-menu__tip-outline) {
286
281
  stroke: var(--a-base-4);
287
282
  }
288
283
 
@@ -306,7 +301,7 @@ export default {
306
301
 
307
302
  &:hover,
308
303
  &:focus {
309
- & ::v-deep .apos-area-menu__item-icon {
304
+ &:deep(.apos-area-menu__item-icon) {
310
305
  color: var(--a-primary);
311
306
  }
312
307
  }
@@ -22,7 +22,6 @@
22
22
  </template>
23
23
  <template v-else>
24
24
  <AposAreaMenu
25
- @add="add"
26
25
  :context-menu-options="contextMenuOptions"
27
26
  :empty="true"
28
27
  :index="0"
@@ -30,14 +29,15 @@
30
29
  :max-reached="maxReached"
31
30
  :disabled="field && field.readOnly"
32
31
  :widget-options="options.widgets"
32
+ @add="add"
33
33
  />
34
34
  </template>
35
35
  </div>
36
36
  <div class="apos-areas-widgets-list">
37
37
  <AposAreaWidget
38
38
  v-for="(widget, i) in next"
39
- :area-id="areaId"
40
39
  :key="widget._id"
40
+ :area-id="areaId"
41
41
  :widget="widget"
42
42
  :meta="meta[widget._id]"
43
43
  :generation="generation"
@@ -227,7 +227,7 @@ export default {
227
227
  mounted() {
228
228
  this.bindEventListeners();
229
229
  },
230
- beforeDestroy() {
230
+ beforeUnmount() {
231
231
  this.unbindEventListeners();
232
232
  },
233
233
  methods: {
@@ -235,14 +235,12 @@ export default {
235
235
  apos.bus.$on('area-updated', this.areaUpdatedHandler);
236
236
  apos.bus.$on('widget-hover', this.updateWidgetHovered);
237
237
  apos.bus.$on('widget-focus', this.updateWidgetFocused);
238
- apos.bus.$on('refreshed', this.destroyParentComponent);
239
238
  window.addEventListener('keydown', this.focusParentEvent);
240
239
  },
241
240
  unbindEventListeners() {
242
241
  apos.bus.$off('area-updated', this.areaUpdatedHandler);
243
242
  apos.bus.$off('widget-hover', this.updateWidgetHovered);
244
243
  apos.bus.$off('widget-focus', this.updateWidgetFocused);
245
- apos.bus.$off('refreshed', this.destroyParentComponent);
246
244
  window.removeEventListener('keydown', this.focusParentEvent);
247
245
  },
248
246
  areaUpdatedHandler(area) {
@@ -382,7 +380,7 @@ export default {
382
380
  apos.area.activeEditor = this;
383
381
  apos.bus.$on('apos-refreshing', cancelRefresh);
384
382
  const result = await apos.modal.execute(componentName, {
385
- value: widget,
383
+ modelValue: widget,
386
384
  options: this.widgetOptionsByType(widget.type),
387
385
  type: widget.type,
388
386
  docId: this.docId,
@@ -481,7 +479,7 @@ export default {
481
479
  const componentName = this.widgetEditorComponent(name);
482
480
  apos.area.activeEditor = this;
483
481
  const widget = await apos.modal.execute(componentName, {
484
- value: null,
482
+ modelValue: null,
485
483
  options: this.widgetOptionsByType(name),
486
484
  type: name,
487
485
  docId: this.docId,
@@ -606,11 +604,6 @@ export default {
606
604
  }
607
605
  });
608
606
  return widget;
609
- },
610
- destroyParentComponent() {
611
- if (!document.body.contains(this.$parent.$el)) {
612
- this.$parent.$destroy();
613
- }
614
607
  }
615
608
  }
616
609
  };
@@ -16,7 +16,7 @@
16
16
  :key="groupIndex"
17
17
  class="apos-widget-group"
18
18
  >
19
- <h2 class="apos-widget-group__label" v-if="group.label">{{ $t(group.label) }}</h2>
19
+ <h2 v-if="group.label" class="apos-widget-group__label">{{ $t(group.label) }}</h2>
20
20
  <div
21
21
  :class="[
22
22
  `apos-widget-group--${group.columns}-column${
@@ -42,10 +42,11 @@
42
42
  class="apos-widget__preview-image"
43
43
  >
44
44
  <component
45
+ :is="getIcon(item)"
45
46
  v-else-if="hasIcon(item)"
47
+ :title="getTitle(item)"
46
48
  :size="25"
47
49
  class="apos-widget__preview--icon"
48
- :is="item.previewIcon || item.icon"
49
50
  />
50
51
  </div>
51
52
  <p class="apos-widget__label">
@@ -173,9 +174,16 @@ export default {
173
174
 
174
175
  return group;
175
176
  },
176
- hasIcon(widget) {
177
+ getIcon(widget) {
177
178
  return widget.previewIcon || widget.icon;
178
179
  },
180
+ hasIcon(widget) {
181
+ return Boolean(widget.previewIcon || widget.icon);
182
+ },
183
+ getTitle(widget) {
184
+ const icon = this.getIcon(widget);
185
+ return icon.replaceAll('-', ' ');
186
+ },
179
187
  close() {
180
188
  this.modal.showModal = false;
181
189
  },
@@ -1,14 +1,13 @@
1
1
  <template>
2
2
  <AposButton
3
3
  v-if="options.expanded"
4
- :disabled="disabled"
5
4
  v-bind="buttonOptions"
6
- @click="openExpandedMenu(index)"
5
+ :disabled="disabled"
7
6
  role="button"
7
+ @click="openExpandedMenu(index)"
8
8
  />
9
9
  <AposAreaContextualMenu
10
10
  v-else
11
- @add="$emit('add', $event);"
12
11
  :button-options="buttonOptions"
13
12
  :context-menu-options="contextMenuOptions"
14
13
  :empty="true"
@@ -17,6 +16,7 @@
17
16
  :options="options"
18
17
  :max-reached="maxReached"
19
18
  :disabled="disabled"
19
+ @add="$emit('add', $event);"
20
20
  />
21
21
  </template>
22
22
 
@@ -86,11 +86,11 @@ export default {
86
86
 
87
87
  <style lang="scss" scoped>
88
88
 
89
- .apos-area-menu.apos-is-focused ::v-deep .apos-context-menu__inner {
89
+ .apos-area-menu.apos-is-focused :deep(.apos-context-menu__inner) {
90
90
  border: 1px solid var(--a-base-4);
91
91
  }
92
92
 
93
- .apos-area-menu.apos-is-focused ::v-deep .apos-context-menu__tip-outline {
93
+ .apos-area-menu.apos-is-focused :deep(.apos-context-menu__tip-outline) {
94
94
  stroke: var(--a-base-4);
95
95
  }
96
96
 
@@ -114,7 +114,7 @@ export default {
114
114
 
115
115
  &:hover,
116
116
  &:focus {
117
- & ::v-deep .apos-area-menu__item-icon {
117
+ &:deep(.apos-area-menu__item-icon) {
118
118
  color: var(--a-primary);
119
119
  }
120
120
  }
@@ -1,9 +1,10 @@
1
1
  <template>
2
2
  <button
3
- @click="click" class="apos-area-menu__button"
3
+ class="apos-area-menu__button"
4
4
  :class="{ 'apos-area-menu__button--separated': item.type }"
5
5
  :data-action="item.name"
6
6
  :tabindex="String(tabindex)"
7
+ @click="click"
7
8
  @keydown.prevent.arrow-down="$emit('down')"
8
9
  @keydown.prevent.arrow-up="$emit('up')"
9
10
  >
@@ -15,10 +16,10 @@
15
16
  </div>
16
17
  <div class="apos-area-menu__item-content">
17
18
  <component
19
+ :is="item.icon"
18
20
  v-if="item.icon"
19
21
  :size="15"
20
22
  class="apos-area-menu__item-icon"
21
- :is="item.icon"
22
23
  />
23
24
  {{ $t(item.label) }}
24
25
  </div>
@@ -1,13 +1,13 @@
1
1
 
2
2
  <template>
3
3
  <div
4
+ ref="widget"
4
5
  class="apos-area-widget-wrapper"
5
6
  :class="{'apos-area-widget-wrapper--foreign': foreign}"
6
7
  :data-area-widget="widget._id"
7
8
  :data-area-label="widgetLabel"
8
9
  :data-apos-widget-foreign="foreign ? 1 : 0"
9
10
  :data-apos-widget-id="widget._id"
10
- ref="widget"
11
11
  >
12
12
  <div
13
13
  class="apos-area-widget-inner"
@@ -17,8 +17,8 @@
17
17
  @click="getFocus($event, widget._id)"
18
18
  >
19
19
  <div
20
- class="apos-area-widget-controls apos-area-widget__label"
21
20
  ref="label"
21
+ class="apos-area-widget-controls apos-area-widget__label"
22
22
  :class="labelsClasses"
23
23
  >
24
24
  <ol class="apos-area-widget__breadcrumbs">
@@ -33,18 +33,16 @@
33
33
  >
34
34
  <AposButton
35
35
  type="quiet"
36
- @click="getFocus($event, item.id)"
37
36
  :label="item.label"
38
37
  icon="chevron-right-icon"
39
38
  :icon-size="9"
40
39
  :modifiers="['icon-right', 'no-motion']"
40
+ @click="getFocus($event, item.id)"
41
41
  />
42
42
  </li>
43
43
  <li class="apos-area-widget__breadcrumb" data-apos-widget-breadcrumb="0">
44
44
  <AposButton
45
45
  type="quiet"
46
- @click="foreign ? $emit('edit', i) : null"
47
- @dblclick.native="(!foreign && !isContextual) ? $emit('edit', i) : null"
48
46
  :label="foreign ? {
49
47
  key: 'apostrophe:editWidgetType',
50
48
  label: $t(widgetLabel)
@@ -52,6 +50,8 @@
52
50
  :tooltip="!isContextual && 'apostrophe:editWidgetForeignTooltip'"
53
51
  :icon-size="11"
54
52
  :modifiers="['no-motion']"
53
+ @click="foreign ? $emit('edit', i) : null"
54
+ @dblclick="(!foreign && !isContextual) ? $emit('edit', i) : null"
55
55
  />
56
56
  </li>
57
57
  </ol>
@@ -63,14 +63,12 @@
63
63
  <AposAreaMenu
64
64
  v-if="!foreign"
65
65
  :max-reached="maxReached"
66
- @add="$emit('add', $event);"
67
- @menu-open="toggleMenuFocus($event, 'top', true)"
68
- @menu-close="toggleMenuFocus($event, 'top', false)"
69
66
  :context-menu-options="contextMenuOptions"
70
67
  :index="i"
71
68
  :widget-options="widgets"
72
69
  :options="options"
73
70
  :disabled="disabled"
71
+ @add="$emit('add', $event);"
74
72
  />
75
73
  </div>
76
74
  <div
@@ -104,33 +102,34 @@
104
102
  />
105
103
  <!-- Still used for contextual editing components -->
106
104
  <component
107
- v-if="isContextual && !foreign"
108
105
  :is="widgetEditorComponent(widget.type)"
106
+ v-if="isContextual && !foreign"
107
+ :key="generation"
109
108
  :options="widgetOptions"
110
109
  :type="widget.type"
111
- :value="widget"
110
+ :model-value="widget"
112
111
  :meta="meta"
113
- @update="$emit('update', $event)"
114
112
  :doc-id="docId"
115
113
  :focused="isFocused"
116
- :key="generation"
114
+ @update="$emit('update', $event)"
117
115
  />
118
116
  <component
119
- v-else
120
117
  :is="widgetComponent(widget.type)"
118
+ v-else
119
+ :id="widget._id"
120
+ :key="`${generation}-preview`"
121
121
  :options="widgetOptions"
122
122
  :type="widget.type"
123
- :id="widget._id"
124
123
  :area-field-id="fieldId"
125
124
  :area-field="field"
126
125
  :following-values="followingValuesWithParent"
126
+ :model-value="widget"
127
127
  :value="widget"
128
128
  :meta="meta"
129
129
  :foreign="foreign"
130
- @edit="$emit('edit', i);"
131
130
  :doc-id="docId"
132
131
  :rendering="rendering"
133
- :key="`${generation}-preview`"
132
+ @edit="$emit('edit', i);"
134
133
  />
135
134
  <div
136
135
  class="apos-area-widget-controls apos-area-widget-controls--add apos-area-widget-controls--add--bottom"
@@ -139,14 +138,12 @@
139
138
  <AposAreaMenu
140
139
  v-if="!foreign"
141
140
  :max-reached="maxReached"
142
- @add="$emit('add', $event)"
143
141
  :context-menu-options="bottomContextMenuOptions"
144
142
  :index="i + 1"
145
143
  :widget-options="widgets"
146
144
  :options="options"
147
145
  :disabled="disabled"
148
- @menu-open="toggleMenuFocus($event, 'bottom', true)"
149
- @menu-close="toggleMenuFocus($event, 'bottom', false)"
146
+ @add="$emit('add', $event)"
150
147
  />
151
148
  </div>
152
149
  </div>
@@ -279,7 +276,8 @@ export default {
279
276
  };
280
277
  },
281
278
  widgetIcon() {
282
- const natural = this.contextMenuOptions.menu.filter(item => item.name === this.widget.type)[0]?.icon || 'shape-icon';
279
+ const natural = this.contextMenuOptions.menu
280
+ .filter(item => item.name === this.widget.type)[0]?.icon || 'shape-icon';
283
281
  return this.foreign ? 'earth-icon' : natural;
284
282
  },
285
283
  widgetLabel() {
@@ -377,7 +375,7 @@ export default {
377
375
  apos.bus.$emit('widget-focus', this.widget._id);
378
376
  }
379
377
  },
380
- destroyed() {
378
+ unmounted() {
381
379
  // Remove the focus parent listener when unmounted
382
380
  apos.bus.$off('widget-focus-parent', this.focusParent);
383
381
  },
@@ -441,17 +439,6 @@ export default {
441
439
  }
442
440
  },
443
441
 
444
- toggleMenuFocus(event, name, value) {
445
- if (event) {
446
- event.cancelBubble = true;
447
- }
448
- this.state.add[name].focus = value;
449
-
450
- if (value) {
451
- this.focus();
452
- }
453
- },
454
-
455
442
  getParent() {
456
443
  if (!this.mounted) {
457
444
  return false;
@@ -517,7 +504,7 @@ export default {
517
504
  }
518
505
  &.apos-is-focused {
519
506
  outline: 1px dashed var(--a-primary);
520
- &::v-deep .apos-rich-text-editor__editor.apos-is-visually-empty {
507
+ &:deep(.apos-rich-text-editor__editor.apos-is-visually-empty) {
521
508
  box-shadow: none;
522
509
  }
523
510
  }
@@ -577,11 +564,11 @@ export default {
577
564
  .apos-area-widget-controls--modify {
578
565
  right: 0;
579
566
  transform: translate3d(-10px, 30px, 0);
580
- ::v-deep .apos-button-group__inner {
567
+ :deep(.apos-button-group__inner) {
581
568
  border: 1px solid var(--a-primary-transparent-25);
582
569
  box-shadow: var(--a-box-shadow);
583
570
  }
584
- ::v-deep .apos-button-group .apos-button {
571
+ :deep(.apos-button-group) .apos-button {
585
572
  width: 32px;
586
573
  height: 32px;
587
574
  padding: 0;
@@ -608,9 +595,9 @@ export default {
608
595
  transform: translate(-50%, -50%);
609
596
  }
610
597
 
611
- .apos-area-widget-controls--add ::v-deep {
598
+ .apos-area-widget-controls--add {
612
599
 
613
- .apos-button__wrapper {
600
+ :deep(.apos-button__wrapper) {
614
601
  padding: 8px;
615
602
 
616
603
  &:hover .apos-button:not([disabled]) {
@@ -634,11 +621,11 @@ export default {
634
621
  }
635
622
  }
636
623
 
637
- .apos-button__icon {
624
+ :deep(.apos-button__icon) {
638
625
  margin-right: 0;
639
626
  }
640
627
 
641
- .apos-button__label {
628
+ :deep(.apos-button__label) {
642
629
  display: inline-block;
643
630
  overflow: hidden;
644
631
  max-width: 0;
@@ -648,7 +635,7 @@ export default {
648
635
  font-size: var(--a-type-small);
649
636
  }
650
637
 
651
- .apos-button {
638
+ :deep(.apos-button) {
652
639
  display: flex;
653
640
  align-items: center;
654
641
  justify-content: center;
@@ -666,7 +653,7 @@ export default {
666
653
  transform: translate(-50%, 50%);
667
654
  }
668
655
 
669
- .apos-area-widget-inner ::v-deep .apos-context-menu__popup.apos-is-visible {
656
+ .apos-area-widget-inner :deep(.apos-context-menu__popup.apos-is-visible) {
670
657
  top: calc(100% + 20px);
671
658
  left: 50%;
672
659
  transform: translate(-50%, 0);
@@ -698,7 +685,7 @@ export default {
698
685
  }
699
686
 
700
687
  .apos-area-widget__breadcrumb,
701
- .apos-area-widget__breadcrumb ::v-deep .apos-button__content {
688
+ .apos-area-widget__breadcrumb :deep(.apos-button__content) {
702
689
  @include type-help;
703
690
  padding: 2px;
704
691
  white-space: nowrap;
@@ -707,7 +694,7 @@ export default {
707
694
  }
708
695
 
709
696
  .apos-area-widget__breadcrumbs:hover .apos-area-widget__breadcrumb,
710
- .apos-area-widget__breadcrumbs:hover .apos-area-widget__breadcrumb ::v-deep .apos-button__content {
697
+ .apos-area-widget__breadcrumbs:hover .apos-area-widget__breadcrumb :deep(.apos-button__content) {
711
698
  color: var(--a-text-primary);
712
699
  }
713
700
 
@@ -729,7 +716,7 @@ export default {
729
716
  color: var(--a-text-primary);
730
717
  }
731
718
 
732
- .apos-area-widget__breadcrumb ::v-deep .apos-button {
719
+ .apos-area-widget__breadcrumb :deep(.apos-button) {
733
720
  color: var(--a-primary-dark-10);
734
721
  &:hover, &:active, &:focus {
735
722
  text-decoration: none;
@@ -46,8 +46,8 @@
46
46
  />
47
47
  <AposButton
48
48
  v-if="!foreign"
49
- :disabled="disabled || maxReached"
50
49
  v-bind="cloneButton"
50
+ :disabled="disabled || maxReached"
51
51
  @click="$emit('clone')"
52
52
  :tooltip="{
53
53
  content: 'apostrophe:duplicate',
@@ -57,8 +57,8 @@
57
57
  />
58
58
  <AposButton
59
59
  v-if="!foreign"
60
- :disabled="disabled"
61
60
  v-bind="removeButton"
61
+ :disabled="disabled"
62
62
  @click="$emit('remove')"
63
63
  :tooltip="{
64
64
  content: 'apostrophe:delete',
@@ -184,15 +184,15 @@ export default {
184
184
  $z-index-button-background: 1;
185
185
  $z-index-button-foreground: 2;
186
186
 
187
- .apos-area-modify-controls ::v-deep {
188
- .apos-button__content {
187
+ .apos-area-modify-controls {
188
+ :deep(.apos-button__content) {
189
189
  z-index: $z-index-button-foreground;
190
190
  position: relative;
191
191
  }
192
- .apos-button__icon {
192
+ :deep(.apos-button__icon) {
193
193
  transition: all 0.3s var(--a-transition-timing-bounce);
194
194
  }
195
- .apos-button {
195
+ :deep(.apos-button) {
196
196
  background-color: transparent;
197
197
 
198
198
  &:not([disabled]):hover:after {