modifying super menu template and css to handle new filter input

This commit is contained in:
Jamie V 2025-01-06 10:57:02 -08:00
parent cded8fc4d0
commit 2b78e7ce04
3 changed files with 115 additions and 49 deletions

View File

@ -26,53 +26,65 @@
:class="[options.menuClass, 'c-super-menu']"
:style="styleObject"
>
<ul
v-if="options.actions.length && options.actions[0].length"
role="menu"
class="c-super-menu__menu"
>
<template v-for="(actionGroups, index) in options.actions" :key="index">
<div role="group">
<li
v-for="action in actionGroups"
:key="action.name"
role="menuitem"
:aria-disabled="action.isDisabled"
aria-describedby="item-description"
:class="action.cssClass"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()"
>
{{ action.name }}
</li>
<div
v-if="index !== options.actions.length - 1"
:key="index"
role="separator"
class="c-menu__section-separator"
></div>
<li v-if="actionGroups.length === 0" :key="index">No actions defined.</li>
</div></template
<div class="c-super-menu__left-col">
<div v-if="options.filterable" class="c-menu__search">
<input
v-model="searchTerm"
type="text"
placeholder="Filter..."
class="c-menu__search-input"
@input="filterItems"
@click.stop
/>
</div>
<ul
v-if="filteredActions.length && filteredActions[0].length"
role="menu"
class="c-super-menu__menu"
>
</ul>
<template v-for="(actionGroups, index) in filteredActions" :key="index">
<div role="group">
<li
v-for="action in actionGroups"
:key="action.name"
role="menuitem"
:aria-disabled="action.isDisabled"
aria-describedby="item-description"
:class="action.cssClass"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()"
>
{{ action.name }}
</li>
<div
v-if="index !== filteredActions.length - 1"
:key="index"
role="separator"
class="c-menu__section-separator"
></div>
<li v-if="actionGroups.length === 0" :key="index">No actions defined.</li>
</div></template
>
</ul>
<ul v-else class="c-super-menu__menu" role="menu">
<li
v-for="action in options.actions"
:key="action.name"
role="menuitem"
:class="action.cssClass"
:aria-label="action.name"
aria-describedby="item-description"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()"
>
{{ action.name }}
</li>
<li v-if="options.actions.length === 0">No actions defined.</li>
</ul>
<ul v-else class="c-super-menu__menu" role="menu">
<li
v-for="action in filteredActions"
:key="action.name"
role="menuitem"
:class="action.cssClass"
:aria-label="action.name"
aria-describedby="item-description"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()"
>
{{ action.name }}
</li>
<li v-if="filteredActions.length === 0">No actions defined.</li>
</ul>
</div>
<div aria-live="polite" class="c-super-menu__item-description">
<div :class="itemDescriptionIconClass"></div>
@ -92,7 +104,9 @@ export default {
inject: ['options'],
data() {
return {
hoveredItem: null
hoveredItem: null,
filteredActions: [],
searchTerm: ''
};
},
computed: {
@ -114,6 +128,9 @@ export default {
return this.hoveredItem?.description ?? '';
}
},
created() {
this.filteredActions = this.options.actions;
},
methods: {
toggleItemDescription(action = null) {
const hoveredItem = {
@ -123,6 +140,33 @@ export default {
};
this.hoveredItem = hoveredItem;
},
filterItems() {
const term = this.searchTerm.toLowerCase();
if (!term) {
this.filteredActions = this.options.actions;
return;
}
if (Array.isArray(this.options.actions[0])) {
// Handle grouped actions
this.filteredActions = this.options.actions
.map((group) =>
group.filter(
(action) =>
action.name.toLowerCase().includes(term) ||
(action.description && action.description.toLowerCase().includes(term))
)
)
.filter((group) => group.length > 0);
} else {
// Handle flat actions list
this.filteredActions = this.options.actions.filter(
(action) =>
action.name.toLowerCase().includes(term) ||
(action.description && action.description.toLowerCase().includes(term))
);
}
}
}
};

View File

@ -663,10 +663,31 @@ select {
}
}
&__menu {
@include menuInner();
&__left-col {
display: flex;
flex-direction: column;
flex: 1 1 50%;
margin-right: $m;
}
&__search {
flex: 0 0 auto;
width: 100%;
margin-bottom: $interiorMarginLg;
.c-menu__search-input {
@include nice-input();
width: 100%;
padding: $interiorMargin;
&:focus {
background: $colorInputBg;
}
}
}
&__menu {
@include menuInner();
flex: 1 1 auto;
overflow: auto;
ul {

View File

@ -92,7 +92,8 @@ export default {
const y = elementBoundingClientRect.y + elementBoundingClientRect.height;
const menuOptions = {
menuClass: 'c-create-menu'
menuClass: 'c-create-menu',
filterable: true
};
this.openmct.menus.showSuperMenu(x, y, this.sortedItems, menuOptions);