Focus trap contacts menu with NcHeaderMenu port

Signed-off-by: Christopher Ng <chrng8@gmail.com>
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
Signed-off-by: Christopher Ng <chrng8@gmail.com>
pull/35637/head
Christopher Ng 1 year ago
parent f7ff54860b
commit f6aa5224c4

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["styles.scss"],"names":[],"mappings":"AAkBA,yQACC,SACA,UACA,SACA,oBACA,eACA,oBACA,wBACA,eACA,uDACA,qBAGD,6CACC,aAID,kGAEC,gDACA,aAGD,UACC,YAGD,6DACC,cAGD,KACC,gBAGD,MACC,yBACA,iBACA,mBAGD,cACC,gBACA,mBAGD,YACC,sBAGD,EACC,SACA,6BACA,qBACA,eACA,IACC,eAIF,WACC,aACA,0BAGD,MACC,eACA,QACC,eAIF,0BACC,eAGD,GACC,gBAGD,KACC,mBAEA,mCACA,uCACA,6BACA,6BAGD,mBACC,kBAGD,qBACC,kBACA,uBACA,qBACA,2BACA,2DACA,uBAGD,iBACC,qBACA,aACA,gCAGD,eACC,YACA,aAGD,cACC,eACA,MACA,SACA,OACA,YACA,WACA,aACA,kBACA,gDACA,gCACA,iBACA,eACA,kBACC,cACA,kBACA,UACA,QACA,gBAED,gBACC,gCACA,sDACA,4CACC,qCAOH,oBACC,WACA,YAGD,gCACC,+BAGD,0BACC,kCACA,yCACA,+BACA,4BAMD,YACC,8CACA,gCAMD,kBACC,sBAKD,4BAEC,oCACA,kBACA,gBACA,WACA,sDACC,gBAED,sEACC,gBAED,kCACC,mBAED,oHAEC,qBACA,YACA,WACA,mBACA,gcAEC,WAOH,sBACC,WASD,oCACC,kBACA,yBACA,sBACA,qBACA,iBAKD,kBACC,kBACA,UACA,SACA,YAGD,8BACC,WACA,oBACA,wBACA,wBAGD,2EACC,WAED,oGACC,0CACA,UACA,qBAGD,mDACC,6BACA,YACA,WACA,yCACA,4BACA,2BACA,WAOA,qEACC,UAED,qEACC,UAIF,wEACC,aAGD,2CACC,mBAGD,yBACC,kBACA,qBACA,iBAED,qBACC,cACA,QACA,iBACA,kBACA,aAKD,4CACC,eACA,YACA,mCACA,6BACA,qDAIA,2BACC,4BAKD,wBACC,sBACA,4BACA,+BACC,2CACA,qBACA,kBAGF,0BACC,qBACA,gBAIF,YACC,YACA,8BACA,oBACC,sBAIF,eACC,2CAUD,mBACC,kBACA,cACA,2BACC,kBACA,cAIF,UACC,gBAGD,8CACC,UAIA,oGAGC,WAIF,mBACC,WACA,kBACA,QAEA,kDACC,UAIF,WACC,WACA,YAGD,eACC,WAIA,8CACC,UAKD,kDACC,UAKD,0CACC,UAKD,8CACC,8CAIF,KACC,mFAGD,OACC,gBACA,YACA,eACA,qBACA,UACC,qBAIF,2FACC,gBACA,uBAGD,2BACC,yDAGD,2BACC,6DAID,yBACC,gBACA,gBACA,WACA,mCACA,YACA,wBAEA,sKAGC,+BACA,mBAED,2CACC,YACA,eACA,YACA,8CACA,6BAEA,gEACC,cACA,mBAED,oDACC,WAEA,8EACC,yEAED,8EACC,wEAGF,oEACC,UAID,oDACC,mBACA,gCACA,WACA,WACA,YAED,0DACC,yBAGA,+FACC,gDAGD,wOAGC,sCACA,gCACA,iBAGD,yNAEC,gCACA,WAMJ,wCACC,gCACA,wCAKD,yBACC,2BACA,sBACA,mCACA,wBAEA,4CACC,uBAGD,sKAGC,+BACA,mBAED,2CACC,YACA,eACA,YACA,8CACA,6BAEA,gEACC,cACA,mBAIF,qFACC,iBAGA,iDACC,mBACA,gCACA,WACA,yDACC,UACA,WACA,iBAGF,uDACC,yBAGA,0TAIC,sCACA,gCACA,iBAGD,4FACC,gCAGD,qEACC,2CASH,oGACC,aACA,iBACA,8BACA,0GACC,cACA,SACA,YACA,YACA,WACA,aACA,mBACA,uBACA,8GACC,kBACA,kBACA,mBACA,6BACA,cACA,iBACA,WACA,YACA,YACA,eAOJ,8BACC,kBACA,aACA,sBAEA,uCACC,eACA,sBACA,oBAEA,yDACC,uCACA,4BACA,gCAGA,6DACC,eAED,uDACC,iBAED,oEACC,YACA,YAKH,mDACC,kBACA,+BACA,YACA,SACA,aACA,WACA,QACA,MAEA,4KAGC,0CACA,UAIF,iDACC,eACA,YACA,sBACA,oBACA,WACA,gBACA,eACA,8CACA,0CACA,wCACA,kBACA,UACA,QACA,QAEA,gEACC,sCACA,0BACA,WACA,YACA,WACA,WAGD,mDACC,WACA,YACA,gBAGD,uDACC,SACA,gBACA,4DACC,aACA,YAMH,kDACC,sBACA,qBACA,gBACA,OAGA,WACA,kBAED,4CACC,oCACA,kBACA,gBACA,WACA,aAED,wCACC,8CACA,WAED,0DAEC,kBACA,mBAEC,mEACC,4CACA,8CACA,sEACC,UACA,YAIH,0EACC,cACA,aACA,YACA,sBACA,2BACA,sBAED,+EACC,iBACA,iBAGD,6EACC,WACA,WACA,gBACA,qBACA,2BACA,WAED,qQAGC,kBAED,oLAEC,mBAGD,6DACC,aACA,4CAED,2EACC,mBAED,oEACC,gBACA,mBACA,uBACA,qBACA,4BACA,kBACA,4BACA,eAEA,YACA,oFACC,aACA,2FACC,gBACA,gBACA,uBAED,0FACC,gBAIH,oIACC,WAED,oEACC,iBAED,oEAIC,aACA,sBAEA,0EACC,aACA,+CACA,6BACA,aACA,cAEA,6EACC,cACA,kBACA,mCACA,QAhBS,KAiBT,aACA,sBACA,YAGA,gFACC,YACA,UACA,kBACA,mCAEA,yFACC,oBACA,+BACA,wBACA,YA/BU,KAgCV,eACA,yGACC,uBAGF,yFACC,iBACA,WAED,qFACC,aAON,2DACC,gDAIF,WACC,0BAGD,aACC,WACA,sBAMA,0BACC,eACA,iCACC,0BACA,4BACA,0BACA,0BACA,aACA,YAEA,qDACA,gDAGD,iGAGC,qBAKD,mCACC,YAEA,iDACC,6DAMJ,6CAEC,2BACA,iBACA,iBACA,YAEA,2DACC,0BACA,kBACA,iJAEC,qBAIF,sDAEC,kCACA,iBACA,iBACA,gBAEA,8DACC,kBAEA,gEACC,cACA,WACA,eACA,WAKH,sDACC,aACA,kBACA,mBACA,yBAEA,8DACC,YACA,WACA,qBAGD,4DACC,YACA,iBAEA,gEACC,kBACA,WAGD,iJAEC,gBACA,gBACA,mBACA,uBAED,qJACC,oCAIF,4MACC,WACA,YACA,WACA,eAEA,gPACC,aAED,wNACC,wCAGD,6pBAGC,UAIF,2EACC,WAEA,iFACC,2BACA,4CAGD,yFACC,wCAKF,4DACC,SACA,kBAED,0EACC,UAMH,qBACC,wBACA,WACA,YAKD,YACC,6BAMA,qBACC,WACA,aAED,wBACC,cACA,gDACA,WACA,aAED,2BACC,WACA,YACA,6BACC,WAGF,wBACC,wCACA,kBACA,mBACA,gBACA,uBACA,0CACA,kCACA,6DACC,0CAGF,sBACC,UACA,WAKF,YACC,oBAED,UACC,oBACA,kDACA,4BACA,iCACA,YACA,0BACA,cACA,QACA,kBACA,oBACC,QACA,kBACA,sBACC,WAIA,0FACC,cAIF,iCACC,SACA,iBACA,oCACC,iBACA,gBACA,kBACA,kBACA,gEACC,+EAGF,gDACC,aAIH,iBACC,aACA,wBACC,QAGF,2BAEC,kBACA,aACA,WACA,uBACA,mBACA,gBACA,cAEA,gBAEA,kGAGC,oBAGF,0BACC,UACA,WAID,qBACC,iBACA,kBAEA,4BACC,eAGF,mEACC,UAEA,kKAEC,WAOH,QACC,UACA,yCACA,sCACA,qCACA,oCACA,iCACA,oBACC,UAOD,+CACC,SACA,kBAED,mDACC,gBAKF,cACC,mBAMD,mBACC,aACA,QACA,SACA","file":"styles.css"}
{"version":3,"sourceRoot":"","sources":["styles.scss"],"names":[],"mappings":"AAkBA,yQACC,SACA,UACA,SACA,oBACA,eACA,oBACA,wBACA,eACA,uDACA,qBAGD,6CACC,aAID,kGAEC,gDACA,aAGD,UACC,YAGD,6DACC,cAGD,KACC,gBAGD,MACC,yBACA,iBACA,mBAGD,cACC,gBACA,mBAGD,YACC,sBAGD,EACC,SACA,6BACA,qBACA,eACA,IACC,eAIF,WACC,aACA,0BAGD,MACC,eACA,QACC,eAIF,0BACC,eAGD,GACC,gBAGD,KACC,mBAEA,mCACA,uCACA,6BACA,6BAGD,mBACC,kBAGD,qBACC,kBACA,uBACA,qBACA,2BACA,2DACA,uBAGD,iBACC,qBACA,aACA,gCAGD,eACC,YACA,aAGD,cACC,eACA,MACA,SACA,OACA,YACA,WACA,aACA,kBACA,gDACA,gCACA,iBACA,eACA,kBACC,cACA,kBACA,UACA,QACA,gBAED,gBACC,gCACA,sDACA,4CACC,qCAOH,oBACC,WACA,YAGD,gCACC,+BAGD,0BACC,kCACA,yCACA,+BACA,4BAMD,YACC,8CACA,gCAMD,kBACC,sBAKD,4BAEC,oCACA,kBACA,gBACA,WACA,sDACC,gBAED,sEACC,gBAED,kCACC,mBAED,oHAEC,qBACA,YACA,WACA,mBACA,gcAEC,WAOH,sBACC,WASD,oCACC,kBACA,yBACA,sBACA,qBACA,iBAKD,kBACC,kBACA,UACA,SACA,YAGD,8BACC,WACA,oBACA,wBACA,wBAGD,2EACC,WAED,oGACC,0CACA,UACA,qBAGD,mDACC,6BACA,YACA,WACA,yCACA,4BACA,2BACA,WAOA,qEACC,UAED,qEACC,UAIF,wEACC,aAGD,2CACC,mBAGD,yBACC,kBACA,qBACA,iBAED,qBACC,cACA,QACA,iBACA,kBACA,aAKD,4CACC,eACA,YACA,mCACA,6BACA,qDAIA,2BACC,4BAKD,wBACC,sBACA,4BACA,+BACC,2CACA,qBACA,kBAGF,0BACC,qBACA,gBAIF,YACC,YACA,8BACA,oBACC,sBAIF,eACC,2CAUD,mBACC,kBACA,cACA,2BACC,kBACA,cAIF,UACC,gBAGD,8CACC,UAIA,oGAGC,WAIF,mBACC,WACA,kBACA,QAEA,kDACC,UAIF,WACC,WACA,YAGD,eACC,WAIA,8CACC,UAKD,kDACC,UAKD,0CACC,UAKD,8CACC,8CAIF,KACC,mFAGD,OACC,gBACA,YACA,eACA,qBACA,UACC,qBAIF,2FACC,gBACA,uBAGD,2BACC,yDAGD,2BACC,6DAID,yBACC,gBACA,gBACA,WACA,mCACA,YACA,wBAEA,sKAGC,+BACA,mBAED,2CACC,YACA,eACA,YACA,8CACA,6BAEA,gEACC,cACA,mBAED,oDACC,WAEA,8EACC,yEAED,8EACC,wEAGF,oEACC,UAID,oDACC,mBACA,gCACA,WACA,WACA,YAED,0DACC,yBAGA,+FACC,gDAGD,wOAGC,sCACA,gCACA,iBAGD,yNAEC,gCACA,WAMJ,wCACC,gCACA,wCAKD,yBACC,2BACA,sBACA,mCACA,wBAEA,4CACC,uBAGD,sKAGC,+BACA,mBAED,2CACC,YACA,eACA,YACA,8CACA,6BAEA,gEACC,cACA,mBAIF,qFACC,iBAGA,iDACC,mBACA,gCACA,WACA,yDACC,UACA,WACA,iBAGF,uDACC,yBAGA,0TAIC,sCACA,gCACA,iBAGD,4FACC,gCAGD,qEACC,2CASH,oGACC,aACA,iBACA,8BACA,0GACC,cACA,SACA,YACA,YACA,WACA,aACA,mBACA,uBACA,8GACC,kBACA,kBACA,mBACA,6BACA,cACA,iBACA,WACA,YACA,YACA,eAOJ,8BACC,kBACA,aACA,sBAEA,uCACC,eACA,sBACA,oBAEA,yDACC,uCACA,4BACA,gCAGA,6DACC,eAED,uDACC,iBAED,oEACC,YACA,YAKH,mDACC,kBACA,+BACA,YACA,SACA,aACA,WACA,QACA,MAEA,4KAGC,0CACA,UAIF,iDACC,eACA,YACA,sBACA,oBACA,WACA,gBACA,eACA,8CACA,0CACA,wCACA,kBACA,UACA,QACA,QAEA,gEACC,sCACA,0BACA,WACA,YACA,WACA,WAGD,mDACC,WACA,YACA,gBAGD,uDACC,SACA,gBACA,4DACC,aACA,YAMH,kDACC,sBACA,qBACA,gBACA,OAGA,WACA,kBAED,4CACC,oCACA,kBACA,gBACA,WACA,aAED,wCACC,8CACA,WAED,0DAEC,kBACA,mBAEC,mEACC,4CACA,8CACA,sEACC,UACA,YAIH,0EACC,cACA,aACA,YACA,sBACA,2BACA,sBAED,+EACC,iBACA,iBAGD,6EACC,WACA,WACA,gBACA,qBACA,2BACA,WAED,qQAGC,kBAED,oLAEC,mBAGD,6DACC,aACA,4CAED,2EACC,mBAED,oEACC,gBACA,mBACA,uBACA,qBACA,4BACA,kBACA,4BACA,eAEA,YACA,oFACC,aACA,2FACC,gBACA,gBACA,uBAED,0FACC,gBAIH,oIACC,WAED,oEACC,iBAED,oEAIC,aACA,sBAEA,0EACC,aACA,+CACA,6BACA,aACA,cAEA,6EACC,cACA,kBACA,mCACA,QAhBS,KAiBT,aACA,sBACA,YAGA,gFACC,YACA,UACA,kBACA,mCAEA,yFACC,oBACA,+BACA,wBACA,YA/BU,KAgCV,eACA,yGACC,uBAGF,yFACC,iBACA,WAED,qFACC,aAON,2DACC,gDAIF,WACC,0BAGD,aACC,WACA,sBAKD,YACC,6BAMA,qBACC,WACA,aAED,wBACC,cACA,gDACA,WACA,aAED,2BACC,WACA,YACA,6BACC,WAGF,wBACC,wCACA,kBACA,mBACA,gBACA,uBACA,0CACA,kCACA,6DACC,0CAGF,sBACC,UACA,WAKF,YACC,oBAED,UACC,oBACA,kDACA,4BACA,iCACA,YACA,0BACA,cACA,QACA,kBACA,oBACC,QACA,kBACA,sBACC,WAIA,0FACC,cAIF,iCACC,SACA,iBACA,oCACC,iBACA,gBACA,kBACA,kBACA,gEACC,+EAGF,gDACC,aAIH,iBACC,aACA,wBACC,QAGF,2BAEC,kBACA,aACA,WACA,uBACA,mBACA,gBACA,cAEA,gBAEA,kGAGC,oBAGF,0BACC,UACA,WAID,qBACC,iBACA,kBAEA,4BACC,eAGF,mEACC,UAEA,kKAEC,WAOH,QACC,UACA,yCACA,sCACA,qCACA,oCACA,iCACA,oBACC,UAOD,+CACC,SACA,kBAED,mDACC,gBAKF,cACC,mBAMD,mBACC,aACA,QACA,SACA","file":"styles.css"}

@ -893,160 +893,6 @@ span.ui-icon {
margin: 3px 7px 30px 0;
}
/* ---- CONTACTS MENU ---- */
#contactsmenu {
.menutoggle {
cursor: pointer;
&:before {
background-size: 20px 20px;
background-repeat: no-repeat;
background-position-x: 3px;
background-position-y: 4px;
padding: 14px;
content: ' ';
// Force white
background-image: var(--original-icon-contacts-white);
filter: var(--background-image-invert-if-bright);
}
&:hover,
&:focus,
&:active {
opacity: 1 !important;
}
}
#contactsmenu-menu {
a {
padding: 2px;
&:focus-visible {
box-shadow: inset 0 0 0 2px var(--color-main-text) !important; // override rule in core/css/headers.scss #header a:focus-visible
}
}
}
}
#header .header-right > div#contactsmenu > .menu {
/* show 2.5 to 4.5 entries depending on the screen height */
height: calc(100vh - 50px * 3);
max-height: calc(50px * 6 + 2px);
min-height: calc(50px * 3.5);
width: 350px;
.emptycontent {
margin-top: 5vh !important;
margin-bottom: 2vh;
.icon-loading,
.icon-search {
display: inline-block;
}
}
.content {
/* fixed max height of the parent container without the search input */
height: calc(100vh - 50px * 3 - 50px);
max-height: calc(50px * 5);
min-height: calc(50px * 3.5 - 50px);
overflow-y: auto;
.footer {
text-align: center;
a {
display: block;
width: 100%;
padding: 12px 0;
opacity: .5;
}
}
}
.contact {
display: flex;
position: relative;
align-items: center;
padding: 3px 3px 3px 10px;
.avatar {
height: 32px;
width: 32px;
display: inline-block;
}
.body {
flex-grow: 1;
padding-left: 8px;
div {
position: relative;
width: 100%;
}
.full-name, .last-message {
/* TODO: don't use fixed width */
max-width: 204px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.last-message, .email-address {
color: var(--color-text-maxcontrast);
}
}
.top-action, .second-action, .other-actions {
width: 16px;
height: 16px;
opacity: .5;
cursor: pointer;
&:not(button) {
padding: 14px;
}
img {
filter: var(--background-invert-if-dark);
}
&:hover,
&:active,
&:focus {
opacity: 1;
}
}
button.other-actions {
width: 44px;
&:focus {
border-color: transparent;
box-shadow: 0 0 0 2px var(--color-main-text);
}
&:focus-visible {
border-radius: var(--border-radius-pill);
}
}
/* actions menu */
.menu {
top: 47px;
margin-right: 13px;
}
.popovermenu::after {
right: 2px;
}
}
}
#contactsmenu-search {
width: calc(100% - 16px);
margin: 8px;
height: 34px;
}
/* ---- TOOLTIPS ---- */
.extra-data {

@ -32,7 +32,7 @@ describe('Contacts menu', function() {
* @returns {Promise}
*/
function openMenu() {
return menu._toggleVisibility(true);
return menu.loadContacts();
}
beforeEach(function(done) {

@ -381,8 +381,7 @@ const ContactsMenuView = View.extend({
/**
* @param {Object} options
* @param {jQuery} options.el
* @param {jQuery} options.trigger
* @param {string} options.el
* @class ContactsMenu
* @memberOf OC
*/
@ -391,12 +390,9 @@ const ContactsMenu = function(options) {
}
ContactsMenu.prototype = {
/** @type {jQuery} */
/** @type {string} */
$el: undefined,
/** @type {jQuery} */
_$trigger: undefined,
/** @type {ContactsMenuView} */
_view: undefined,
@ -405,41 +401,19 @@ ContactsMenu.prototype = {
/**
* @param {Object} options
* @param {jQuery} options.el - the element to render the menu in
* @param {jQuery} options.trigger - the element to click on to open the menu
* @param {string} options.el - the selector of the element to render the menu in
* @returns {undefined}
*/
initialize: function(options) {
this.$el = options.el
this._$trigger = options.trigger
this.$el = $(options.el)
this._view = new ContactsMenuView({
el: this.$el
el: this.$el,
})
this._view.on('search', function(searchTerm) {
this._loadContacts(searchTerm)
this.loadContacts(searchTerm)
}, this)
OC.registerMenu(this._$trigger, this.$el, function() {
this._toggleVisibility(true)
}.bind(this), true)
this.$el.on('beforeHide', function() {
this._toggleVisibility(false)
}.bind(this))
},
/**
* @private
* @param {boolean} show
* @returns {Promise}
*/
_toggleVisibility: function(show) {
if (show) {
return this._loadContacts()
} else {
this.$el.html('')
return Promise.resolve()
}
},
/**
@ -461,7 +435,7 @@ ContactsMenu.prototype = {
* @param {string|undefined} searchTerm
* @returns {undefined}
*/
_loadContacts: function(searchTerm) {
loadContacts: function(searchTerm) {
var self = this
if (!self._contactsPromise) {

@ -2,6 +2,7 @@
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Christopher Ng <chrng8@gmail.com>
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0-or-later
@ -21,16 +22,20 @@
*
*/
import $ from 'jquery'
import OC from '../OC'
import Vue from 'vue'
import ContactsMenu from '../views/ContactsMenu.vue'
/**
* @todo move to contacts menu code https://github.com/orgs/nextcloud/projects/31#card-21213129
*/
export const setUp = () => {
// eslint-disable-next-line no-new
new OC.ContactsMenu({
el: $('#contactsmenu .menu'),
trigger: $('#contactsmenu .menutoggle'),
})
const mountPoint = document.getElementById('contactsmenu')
if (mountPoint) {
// eslint-disable-next-line no-new
new Vue({
el: mountPoint,
render: h => h(ContactsMenu),
})
}
}

@ -0,0 +1,198 @@
<!--
- @copyright 2023 Christopher Ng <chrng8@gmail.com>
-
- @author Christopher Ng <chrng8@gmail.com>
-
- @license AGPL-3.0-or-later
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->
<template>
<NcHeaderMenu id="contactsmenu"
:aria-label="t('core', 'Search contacts')"
@open="handleOpen">
<template #trigger>
<Contacts :size="20" />
</template>
<div id="contactsmenu-menu" />
</NcHeaderMenu>
</template>
<script>
import NcHeaderMenu from '@nextcloud/vue/dist/Components/NcHeaderMenu.js'
import Contacts from 'vue-material-design-icons/Contacts.vue'
import OC from '../OC/index.js'
export default {
name: 'ContactsMenu',
components: {
Contacts,
NcHeaderMenu,
},
data() {
return {
contactsMenu: null,
}
},
mounted() {
// eslint-disable-next-line no-new
this.contactsMenu = new OC.ContactsMenu({
el: '#contactsmenu-menu',
})
},
methods: {
handleOpen() {
this.contactsMenu?.loadContacts()
},
},
}
</script>
<style lang="scss" scoped>
#contactsmenu-menu {
/* show 2.5 to 4.5 entries depending on the screen height */
height: calc(100vh - 50px * 3);
max-height: calc(50px * 6 + 2px);
min-height: calc(50px * 3.5);
width: 350px;
&:deep {
.emptycontent {
margin-top: 5vh !important;
margin-bottom: 1.5vh;
.icon-loading,
.icon-search {
display: inline-block;
}
}
#contactsmenu-search {
width: calc(100% - 16px);
margin: 8px;
height: 34px;
}
.content {
/* fixed max height of the parent container without the search input */
height: calc(100vh - 50px * 3 - 50px);
max-height: calc(50px * 5);
min-height: calc(50px * 3.5 - 50px);
overflow-y: auto;
.footer {
text-align: center;
a {
display: block;
width: 100%;
padding: 12px 0;
opacity: .5;
}
}
}
a {
padding: 2px;
&:focus-visible {
box-shadow: inset 0 0 0 2px var(--color-main-text) !important; // override rule in core/css/headers.scss #header a:focus-visible
}
}
.contact {
display: flex;
position: relative;
align-items: center;
padding: 3px 3px 3px 10px;
.avatar {
height: 32px;
width: 32px;
display: inline-block;
}
.body {
flex-grow: 1;
padding-left: 8px;
div {
position: relative;
width: 100%;
}
.full-name, .last-message {
/* TODO: don't use fixed width */
max-width: 204px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.last-message, .email-address {
color: var(--color-text-maxcontrast);
}
}
.top-action, .second-action, .other-actions {
width: 16px;
height: 16px;
opacity: .5;
cursor: pointer;
&:not(button) {
padding: 14px;
}
img {
filter: var(--background-invert-if-dark);
}
&:hover,
&:active,
&:focus {
opacity: 1;
}
}
button.other-actions {
width: 44px;
&:focus {
border-color: transparent;
box-shadow: 0 0 0 2px var(--color-main-text);
}
&:focus-visible {
border-radius: var(--border-radius-pill);
}
}
/* actions menu */
.menu {
top: 47px;
margin-right: 13px;
}
.popovermenu::after {
right: 2px;
}
}
}
}
</style>

@ -69,14 +69,7 @@ $getUserAvatar = static function (int $size) use ($_): string {
<div class="header-right">
<div id="unified-search"></div>
<div id="notifications"></div>
<div id="contactsmenu">
<div class="menutoggle" tabindex="0" role="button"
aria-haspopup="true" aria-controls="contactsmenu-menu" aria-expanded="false">
<span class="hidden-visually"><?php p($l->t('Contacts'));?></span>
</div>
<div id="contactsmenu-menu" class="menu"
aria-label="<?php p($l->t('Contacts menu'));?>"></div>
</div>
<div id="contactsmenu"></div>
<div id="settings">
<div id="expand" tabindex="0" role="button" class="menutoggle"
aria-label="<?php p($l->t('Open settings menu'));?>"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/core-main.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -31,7 +31,7 @@ class ContactsMenuContext implements Context, ActorAwareInterface {
* @return Locator
*/
public static function contactsMenuButton() {
return Locator::forThe()->xpath("//*[@id = 'header']//*[@id = 'contactsmenu']")->
return Locator::forThe()->xpath("//*[@id = 'header']//*[@id = 'contactsmenu']//*[@class = 'header-menu__trigger']")->
describedAs("Contacts menu button");
}
@ -39,8 +39,7 @@ class ContactsMenuContext implements Context, ActorAwareInterface {
* @return Locator
*/
public static function contactsMenu() {
return Locator::forThe()->css(".menu")->
descendantOf(self::contactsMenuButton())->
return Locator::forThe()->xpath("//*[@id = 'header']//*[@id = 'contactsmenu']//*[@id = 'contactsmenu-menu']")->
describedAs("Contacts menu");
}

Loading…
Cancel
Save