apostrophe 4.6.0 → 4.6.1
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/CHANGELOG.md +8 -0
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaContextualMenu.vue +7 -3
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaMenu.vue +5 -0
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaWidget.vue +65 -19
- package/modules/@apostrophecms/asset/index.js +8 -4
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +2 -0
- package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenu.vue +16 -8
- package/modules/@apostrophecms/ui/ui/apos/scss/mixins/_zindex.scss +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.6.1 (2024-08-26)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
|
|
7
|
+
* Registering duplicate icon is no longer breaking the build.
|
|
8
|
+
* Fix widget focus state so that the in-context Add Content menu stays visible during animation.
|
|
9
|
+
* Fix UI of areas in schemas so that their context menus are layered overtop sibling schema fields UI.
|
|
10
|
+
|
|
3
11
|
## 4.6.0 (2024-08-08)
|
|
4
12
|
|
|
5
13
|
### Adds
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
:disabled="isDisabled"
|
|
7
7
|
:button="buttonOptions"
|
|
8
8
|
:popover-modifiers="inContext ? ['z-index-in-context'] : []"
|
|
9
|
+
:menu-id="menuId"
|
|
9
10
|
>
|
|
10
11
|
<ul class="apos-area-menu__wrapper">
|
|
11
12
|
<li
|
|
@@ -117,6 +118,12 @@ export default {
|
|
|
117
118
|
default: function() {
|
|
118
119
|
return {};
|
|
119
120
|
}
|
|
121
|
+
},
|
|
122
|
+
menuId: {
|
|
123
|
+
type: String,
|
|
124
|
+
default() {
|
|
125
|
+
return `areaMenu-${createId()}`;
|
|
126
|
+
}
|
|
120
127
|
}
|
|
121
128
|
},
|
|
122
129
|
emits: [ 'add' ],
|
|
@@ -182,9 +189,6 @@ export default {
|
|
|
182
189
|
} else {
|
|
183
190
|
return menu;
|
|
184
191
|
}
|
|
185
|
-
},
|
|
186
|
-
menuId() {
|
|
187
|
-
return `areaMenu-${createId()}`;
|
|
188
192
|
}
|
|
189
193
|
},
|
|
190
194
|
mounted() {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
:options="options"
|
|
17
17
|
:max-reached="maxReached"
|
|
18
18
|
:disabled="disabled"
|
|
19
|
+
:menu-id="menuId"
|
|
19
20
|
@add="$emit('add', $event);"
|
|
20
21
|
/>
|
|
21
22
|
</template>
|
|
@@ -58,6 +59,10 @@ export default {
|
|
|
58
59
|
tabbable: {
|
|
59
60
|
type: Boolean,
|
|
60
61
|
default: false
|
|
62
|
+
},
|
|
63
|
+
menuId: {
|
|
64
|
+
type: String,
|
|
65
|
+
default: null
|
|
61
66
|
}
|
|
62
67
|
},
|
|
63
68
|
emits: [ 'add' ],
|
|
@@ -75,6 +75,8 @@
|
|
|
75
75
|
:options="options"
|
|
76
76
|
:disabled="disabled"
|
|
77
77
|
:tabbable="isHovered || isFocused"
|
|
78
|
+
:menu-id="`${widget._id}-widget-menu-top`"
|
|
79
|
+
:class="{[classes.open]: menuOpen === 'top'}"
|
|
78
80
|
@add="$emit('add', $event);"
|
|
79
81
|
/>
|
|
80
82
|
</div>
|
|
@@ -148,6 +150,8 @@
|
|
|
148
150
|
:options="options"
|
|
149
151
|
:disabled="disabled"
|
|
150
152
|
:tabbable="isHovered || isFocused"
|
|
153
|
+
:menu-id="`${widget._id}-widget-menu-bottom`"
|
|
154
|
+
:class="{[classes.open]: menuOpen === 'bottom'}"
|
|
151
155
|
@add="$emit('add', $event)"
|
|
152
156
|
/>
|
|
153
157
|
</div>
|
|
@@ -251,6 +255,7 @@ export default {
|
|
|
251
255
|
return {
|
|
252
256
|
mounted: false, // hack around needing DOM to be rendered for computed classes
|
|
253
257
|
isSuppressed: false,
|
|
258
|
+
menuOpen: null,
|
|
254
259
|
classes: {
|
|
255
260
|
show: 'apos-is-visible',
|
|
256
261
|
open: 'apos-is-open',
|
|
@@ -345,7 +350,8 @@ export default {
|
|
|
345
350
|
},
|
|
346
351
|
addClasses() {
|
|
347
352
|
return {
|
|
348
|
-
[this.classes.show]: this.isHovered || this.isFocused
|
|
353
|
+
[this.classes.show]: this.isHovered || this.isFocused,
|
|
354
|
+
[`${this.classes.open}--menu-${this.menuOpen}`]: !!this.menuOpen
|
|
349
355
|
};
|
|
350
356
|
},
|
|
351
357
|
foreign() {
|
|
@@ -358,6 +364,7 @@ export default {
|
|
|
358
364
|
if (newVal) {
|
|
359
365
|
this.$refs.wrapper.addEventListener('keydown', this.handleKeyboardUnfocus);
|
|
360
366
|
} else {
|
|
367
|
+
this.menuOpen = null;
|
|
361
368
|
this.$refs.wrapper.removeEventListener('keydown', this.handleKeyboardUnfocus);
|
|
362
369
|
}
|
|
363
370
|
}
|
|
@@ -377,6 +384,7 @@ export default {
|
|
|
377
384
|
// AposAreaEditor is listening for keyboard input that triggers
|
|
378
385
|
// a 'focus my parent' plea
|
|
379
386
|
apos.bus.$on('widget-focus-parent', this.focusParent);
|
|
387
|
+
apos.bus.$on('context-menu-toggled', this.getFocusForMenu);
|
|
380
388
|
|
|
381
389
|
this.breadcrumbs.$lastEl = this.$el;
|
|
382
390
|
|
|
@@ -395,6 +403,22 @@ export default {
|
|
|
395
403
|
},
|
|
396
404
|
methods: {
|
|
397
405
|
|
|
406
|
+
getFocusForMenu({ menuId, isOpen }) {
|
|
407
|
+
if (
|
|
408
|
+
(
|
|
409
|
+
menuId === `${this.widget._id}-widget-menu-top` ||
|
|
410
|
+
menuId === `${this.widget._id}-widget-menu-bottom`
|
|
411
|
+
) &&
|
|
412
|
+
isOpen
|
|
413
|
+
) {
|
|
414
|
+
const whichMenu = menuId.split('-')[menuId.split('-').length - 1];
|
|
415
|
+
this.menuOpen = whichMenu;
|
|
416
|
+
this.getFocus(null, this.widget._id);
|
|
417
|
+
} else {
|
|
418
|
+
this.menuOpen = null;
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
|
|
398
422
|
// Determine whether or not we should adjust the label based on its position to the admin bar
|
|
399
423
|
adjustUi() {
|
|
400
424
|
const { height: labelHeight } = this.$refs.label.getBoundingClientRect();
|
|
@@ -427,7 +451,9 @@ export default {
|
|
|
427
451
|
|
|
428
452
|
// Ask the parent AposAreaEditor to make us focused
|
|
429
453
|
getFocus(e, id) {
|
|
430
|
-
e
|
|
454
|
+
if (e) {
|
|
455
|
+
e.stopPropagation();
|
|
456
|
+
}
|
|
431
457
|
this.isSuppressed = false;
|
|
432
458
|
apos.bus.$emit('widget-focus', id);
|
|
433
459
|
},
|
|
@@ -515,6 +541,26 @@ export default {
|
|
|
515
541
|
</script>
|
|
516
542
|
|
|
517
543
|
<style lang="scss" scoped>
|
|
544
|
+
@mixin showButton() {
|
|
545
|
+
transform: scale(1.15);
|
|
546
|
+
background-size: 150% 100%;
|
|
547
|
+
border-radius: 10px;
|
|
548
|
+
transition-duration: 500ms;
|
|
549
|
+
|
|
550
|
+
/* stylelint-disable-next-line max-nesting-depth */
|
|
551
|
+
.apos-button__label {
|
|
552
|
+
max-width: 100px;
|
|
553
|
+
max-height: 100px;
|
|
554
|
+
transition-duration: 500ms;
|
|
555
|
+
padding: 0 5px 0 0;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/* stylelint-disable-next-line max-nesting-depth */
|
|
559
|
+
.apos-button__icon {
|
|
560
|
+
margin-right: 5px;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
518
564
|
.apos-area-widget-guard {
|
|
519
565
|
position: absolute;
|
|
520
566
|
top: 0;
|
|
@@ -657,6 +703,22 @@ export default {
|
|
|
657
703
|
top: 0;
|
|
658
704
|
left: 50%;
|
|
659
705
|
transform: translate(-50%, -50%);
|
|
706
|
+
|
|
707
|
+
&.apos-area-widget-controls--add--top.apos-is-open--menu-top,
|
|
708
|
+
&.apos-area-widget-controls--add--bottom.apos-is-open--menu-bottom {
|
|
709
|
+
z-index: $z-index-area-schema-ui;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.apos-area-widget-controls--add {
|
|
714
|
+
&.apos-area-widget-controls--add--top.apos-is-open--menu-top,
|
|
715
|
+
&.apos-area-widget-controls--add--bottom.apos-is-open--menu-bottom {
|
|
716
|
+
|
|
717
|
+
/* stylelint-disable-next-line max-nesting-depth */
|
|
718
|
+
:deep(.apos-button__wrapper .apos-button:not([disabled])) {
|
|
719
|
+
@include showButton;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
660
722
|
}
|
|
661
723
|
|
|
662
724
|
.apos-area-widget-controls--add {
|
|
@@ -664,23 +726,7 @@ export default {
|
|
|
664
726
|
padding: 8px;
|
|
665
727
|
|
|
666
728
|
&:hover .apos-button:not([disabled]) {
|
|
667
|
-
|
|
668
|
-
background-size: 150% 100%;
|
|
669
|
-
border-radius: 10px;
|
|
670
|
-
transition-duration: 500ms;
|
|
671
|
-
|
|
672
|
-
/* stylelint-disable-next-line max-nesting-depth */
|
|
673
|
-
.apos-button__label {
|
|
674
|
-
max-width: 100px;
|
|
675
|
-
max-height: 100px;
|
|
676
|
-
transition-duration: 500ms;
|
|
677
|
-
padding: 0 5px 0 0;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
/* stylelint-disable-next-line max-nesting-depth */
|
|
681
|
-
.apos-button__icon {
|
|
682
|
-
margin-right: 5px;
|
|
683
|
-
}
|
|
729
|
+
@include showButton;
|
|
684
730
|
}
|
|
685
731
|
}
|
|
686
732
|
|
|
@@ -572,11 +572,15 @@ module.exports = {
|
|
|
572
572
|
registerCode: 'window.apos.iconComponents = window.apos.iconComponents || {};\n'
|
|
573
573
|
};
|
|
574
574
|
|
|
575
|
+
const importIndex = [];
|
|
575
576
|
for (const [ registerAs, importFrom ] of Object.entries(self.iconMap)) {
|
|
576
|
-
if (
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
577
|
+
if (!importIndex.includes(importFrom)) {
|
|
578
|
+
if (importFrom.substring(0, 1) === '~') {
|
|
579
|
+
output.importCode += `import ${importFrom}Icon from '${importFrom.substring(1)}';\n`;
|
|
580
|
+
} else {
|
|
581
|
+
output.importCode += `import ${importFrom}Icon from '@apostrophecms/vue-material-design-icons/${importFrom}.vue';\n`;
|
|
582
|
+
}
|
|
583
|
+
importIndex.push(importFrom);
|
|
580
584
|
}
|
|
581
585
|
output.registerCode += `window.apos.iconComponents['${registerAs}'] = ${importFrom}Icon;\n`;
|
|
582
586
|
}
|
|
@@ -106,12 +106,17 @@ const props = defineProps({
|
|
|
106
106
|
default() {
|
|
107
107
|
return [];
|
|
108
108
|
}
|
|
109
|
+
},
|
|
110
|
+
menuId: {
|
|
111
|
+
type: String,
|
|
112
|
+
default() {
|
|
113
|
+
return createId();
|
|
114
|
+
}
|
|
109
115
|
}
|
|
110
116
|
});
|
|
111
117
|
|
|
112
118
|
const emit = defineEmits([ 'open', 'close', 'item-clicked' ]);
|
|
113
119
|
|
|
114
|
-
const menuId = ref(createId());
|
|
115
120
|
const isOpen = ref(false);
|
|
116
121
|
const placement = ref(props.menuPlacement);
|
|
117
122
|
const event = ref(null);
|
|
@@ -172,13 +177,13 @@ watch(isOpen, (newVal) => {
|
|
|
172
177
|
const { themeClass } = useAposTheme();
|
|
173
178
|
|
|
174
179
|
onMounted(() => {
|
|
175
|
-
apos.bus.$on('context-menu-
|
|
176
|
-
apos.bus.$on('
|
|
180
|
+
apos.bus.$on('context-menu-toggled', hideWhenOtherOpen);
|
|
181
|
+
apos.bus.$on('close-context-menus', hide);
|
|
177
182
|
});
|
|
178
183
|
|
|
179
184
|
onBeforeUnmount(() => {
|
|
180
|
-
apos.bus.$off('context-menu-
|
|
181
|
-
apos.bus.$off('
|
|
185
|
+
apos.bus.$off('context-menu-toggled', hideWhenOtherOpen);
|
|
186
|
+
apos.bus.$off('close-context-menus', hide);
|
|
182
187
|
});
|
|
183
188
|
|
|
184
189
|
function getMenuOffset() {
|
|
@@ -188,8 +193,8 @@ function getMenuOffset() {
|
|
|
188
193
|
};
|
|
189
194
|
}
|
|
190
195
|
|
|
191
|
-
function hideWhenOtherOpen(
|
|
192
|
-
if (menuId
|
|
196
|
+
function hideWhenOtherOpen({ menuId }) {
|
|
197
|
+
if (props.menuId !== menuId) {
|
|
193
198
|
hide();
|
|
194
199
|
}
|
|
195
200
|
}
|
|
@@ -199,8 +204,11 @@ function hide() {
|
|
|
199
204
|
}
|
|
200
205
|
|
|
201
206
|
function buttonClicked(e) {
|
|
202
|
-
apos.bus.$emit('context-menu-opened', menuId.value);
|
|
203
207
|
isOpen.value = !isOpen.value;
|
|
208
|
+
apos.bus.$emit('context-menu-toggled', {
|
|
209
|
+
menuId: props.menuId,
|
|
210
|
+
isOpen: isOpen.value
|
|
211
|
+
});
|
|
204
212
|
event.value = e;
|
|
205
213
|
}
|
|
206
214
|
|