Elastic: Toolbar variations

pull/5578/merge
Aleksander Machniak 6 years ago
parent da5080a980
commit f0cf4e3f2e

@ -136,6 +136,7 @@ body > #layout {
margin: 0 -20rem;
}
a.toolbar-list-button,
a.toolbar-menu-button {
order: 99; // always the last button
}
@ -216,6 +217,10 @@ html.iframe {
}
}
}
a.toolbar-list-button {
display: none;
}
}
@media screen and (max-width: @screen-width-xs) {

@ -36,11 +36,11 @@ button.btn {
&:before {
&:extend(.font-icon-class);
}
&.toolbar-menu-button:before {
content: @fa-var-ellipsis-v;
}
&.sidebar-menu:before,
&.toolbar-menu-button:before,
&.toolbar-list-button:before {
content: @fa-var-cog;
content: @fa-var-ellipsis-v;
width: 1em;
}
&.menu-button:before {
content: @fa-var-bars;
@ -50,6 +50,9 @@ button.btn {
&.back-list-button:before {
content: @fa-var-chevron-left;
}
&.refresh:before {
content: @fa-var-sync;
}
&.generate:before,
&.yes:before,
&.submit:before,
@ -116,9 +119,6 @@ button.btn {
&.help:before {
.font-icon-regular(@fa-var-life-ring);
}
&.toggleselect:before {
.font-icon-regular(@fa-var-check-square);
}
&.folders:before {
content: @fa-var-folder-open;
}
@ -126,10 +126,12 @@ button.btn {
&.settings:before {
content: @fa-var-wrench;
}
&.properties:before {
content: @fa-var-info-circle;
}
&.select:before {
.font-icon-regular(@fa-var-check-circle);
}
}
a.btn,

@ -272,6 +272,7 @@ fieldset.image-attachment {
.quota-widget {
width: 100%;
max-width: 15em;
padding: .5rem 1rem;
display: flex;
align-items: center;

@ -113,23 +113,23 @@
&.encrypt:before {
content: @fa-var-lock;
}
&.firstpage:before {
content: @fa-var-fast-backward;
}
&.prev:before {
content: @fa-var-arrow-left;
}
&.next:before {
content: @fa-var-arrow-right;
}
&.firstpage:before {
content: @fa-var-angle-double-left;
}
&.prevpage:before {
content: @fa-var-backward;
content: @fa-var-angle-left;
}
&.nextpage:before {
content: @fa-var-forward;
content: @fa-var-angle-right;
}
&.lastpage:before {
content: @fa-var-fast-forward;
content: @fa-var-angle-double-right;
}
&.send:before {
content: @fa-var-paper-plane;
@ -157,7 +157,7 @@
content: @fa-var-comment;
}
&.select:before {
.font-icon-regular(@fa-var-check-square);
.font-icon-regular(@fa-var-check-circle);
}
&.threads:before {
content: @fa-var-comments;
@ -239,16 +239,11 @@
a.button {
flex-grow: 1;
font-size: 80%;
min-width: 2rem !important;
height: @layout-footer-small-height;
&:before {
line-height: 1.5 !important;
}
&.toggleselect {
flex-grow: unset !important;
line-height: 1.25;
}
}
@ -517,6 +512,15 @@
a.export.all:before {
content: @fa-var-download;
}
a.select:before {
content: @fa-var-check-circle;
}
a.threads:before {
content: @fa-var-comments;
}
a.selection:before {
content: @fa-var-mouse-pointer;
}
a.select.all:before {
.font-icon-regular(@fa-var-check-square);
}
@ -639,10 +643,6 @@ html.ie11 .toolbar .dropbutton a.dropdown:before {
}
@media screen and (min-width: (@screen-width-small + 1px)) {
ul.toolbar {
flex: 1;
}
.toolbar {
a.button {
&:not(.disabled):focus,
@ -728,6 +728,30 @@ html.ie11 .toolbar .dropbutton a.dropdown:before {
}
}
a.button.icon.toolbar-button {
order: 8;
@media screen and (min-width: (@screen-width-large + 1px)) {
height: @layout-header-height;
line-height: 1.5;
padding: .5rem;
&:before {
float: none;
height: 1.75rem;
line-height: 1.75;
width: auto;
}
span.inner {
display: inline;
font-weight: normal;
font-size: 90%;
}
}
}
/*** Searchbar and searchoptions widgets ***/
.searchbar {

@ -8,18 +8,14 @@
<div class="header">
<a class="button icon back-list-button" href="#back"><span class="inner"><roundcube:label name="back" /></span></a>
<span id="directorylist-header" class="header-title"><roundcube:label name="groups" /></span>
<roundcube:button name="groupoptions" type="link" title="arialabelabookgroupoptions" label="actions"
class="button icon sidebar-menu" innerClass="inner" data-popup="groupoptions-menu" />
</div>
<div class="scroller">
<roundcube:object name="directorylist" id="directorylist" class="treelist listing iconized" />
<h3 class="voice"><roundcube:label name="savedsearches" /></h3>
<roundcube:object name="savedsearchlist" id="savedsearchlist" class="treelist listing iconized" />
</div>
<div class="footer toolbar" role="toolbar">
<roundcube:button command="group-create" type="link" title="newgroup" label="addgroup"
class="button create disabled" classAct="button create" innerClass="inner" />
<roundcube:button name="groupoptions" type="link" title="arialabelabookgroupoptions" label="actions"
class="button actions" innerClass="inner" data-popup="groupoptions-menu" />
</div>
</div>
<!-- contacts list -->
@ -113,6 +109,7 @@
<div id="groupoptions-menu" class="popupmenu">
<h3 id="aria-label-groupoptions-menu" class="voice"><roundcube:label name="arialabelabookgroupoptions" /></h3>
<ul class="toolbarmenu listing" role="menu" aria-labelledby="aria-label-groupoptions-menu">
<roundcube:button type="link-menuitem" command="group-create" title="newgroup" label="addgroup" class="create" classAct="create active" />
<roundcube:button type="link-menuitem" command="group-rename" label="grouprename" class="group rename" classAct="group rename active" />
<roundcube:button type="link-menuitem" command="group-delete" label="groupdelete" class="group delete" classAct="group delete active" />
<roundcube:button type="link-menuitem" command="search-create" label="searchsave" class="search" classAct="search active" />

@ -5,6 +5,7 @@
<roundcube:add_label name="htmltoggle" />
<roundcube:add_label name="previous" />
<roundcube:add_label name="next" />
<roundcube:add_label name="select" />
<roundcube:object name="doctype" value="html5" />
<roundcube:if condition="!env:framed || env:extwin" />
<html>

@ -1,5 +1,7 @@
<roundcube:add_label name="viewsource" />
<div id="mailtoolbar" class="toolbar" role="toolbar">
<roundcube:button command="compose" type="link" class="button compose hidden"
label="compose" title="writenewmessage" innerclass="inner" />
<roundcube:button command="reply" type="link"
class="button reply disabled" classAct="button reply"
label="reply" title="replytomessage" innerclass="inner" data-content-button="true" />

@ -8,15 +8,13 @@
<div class="header">
<a class="button icon back-list-button" href="#back"><span class="inner"><roundcube:label name="back" /></span></a>
<span class="header-title username"><roundcube:object name="username" /></span>
<roundcube:button name="folderactions" type="link" title="folderactions" label="actions"
class="button icon sidebar-menu" innerclass="inner" data-popup="mailboxoptions-menu" />
</div>
<h2 id="aria-label-folderlist" class="voice"><roundcube:label name="arialabelfolderlist" /></h2>
<div id="folderlist-content" class="scroller">
<roundcube:object name="mailboxlist" id="mailboxlist" class="treelist listing folderlist" folder_filter="mail" unreadwrap="%s" />
</div>
<div id="folderlist-footer" class="footer toolbar">
<roundcube:button name="folderactions" type="link" title="folderactions" label="actions"
class="button actions" innerclass="inner" data-popup="mailboxoptions-menu" />
</div>
<div class="footer toolbar small">
<roundcube:if condition="env:quota" />
<div id="quotadisplay" class="quota-widget">
@ -34,16 +32,15 @@
<a class="button icon back-sidebar-button folders" href="#sidebar"><span class="inner"><roundcube:label name="mailboxlist" /></span></a>
<span class="header-title"></span>
<div class="toolbar" role="toolbar">
<!--
<a href="#select" class="button select" data-popup="listselect-menu" title="<roundcube:label name="select" />"><span class="inner"><roundcube:label name="select" /></span></a>
-->
<a href="#select" class="button select active" data-popup="listselect-menu" data-toggle-button="list-toggle-button" title="<roundcube:label name="select" />"><span class="inner"><roundcube:label name="select" /></span></a>
<roundcube:if condition="env:threads" />
<a href="#threads" class="button threads" data-popup="threadselect-menu" title="<roundcube:label name="threads" />"><span class="inner"><roundcube:label name="threads" /></span></a>
<a href="#threads" class="button threads active" data-popup="threadselect-menu" title="<roundcube:label name="threads" />"><span class="inner"><roundcube:label name="threads" /></span></a>
<roundcube:endif />
<roundcube:object name="listmenulink" class="button settings" label="options" innerclass="inner" />
<roundcube:button command="checkmail" type="link" class="button refresh" label="refresh" title="checkmail" innerclass="inner" />
<roundcube:object name="listmenulink" class="button settings active" label="options" innerclass="inner" />
<roundcube:container name="listcontrols" id="listcontrols" />
</div>
<roundcube:button command="checkmail" type="link" class="button icon toolbar-button refresh"
label="refresh" title="checkmail" innerclass="inner" />
<a class="button icon toolbar-menu-button" href="#list-menu"><span class="inner"><roundcube:label name="menu" /></span></a>
</div>
<roundcube:object name="searchform" id="mailsearchform" wrapper="searchbar toolbar"
@ -141,6 +138,9 @@
<div id="listselect-menu" class="popupmenu">
<h3 id="aria-label-listselect-menu" class="voice"><roundcube:label name="arialabellistselectmenu" /></h3>
<ul class="toolbarmenu listing" role="menu" aria-labelledby="aria-label-listselect-menu">
<roundcube:button type="link-menuitem" label="selection" class="selection" classAct="selection active"
name="list-toggle-button" id="list-toggle-button"
onclick="if ($(this).is('.active')) $('#messagelist').toggleClass('withselection');" />
<roundcube:button command="select-all" type="link-menuitem" label="all" class="select all" classAct="select all active" />
<roundcube:button command="select-all" type="link-menuitem" prop="page" label="currpage" class="select page" classAct="select page active" />
<roundcube:button command="select-all" type="link-menuitem" prop="unread" label="unread" class="select unread" classAct="select unread active" />

@ -77,6 +77,9 @@ function rcube_elastic_ui()
this.pretty_select = pretty_select;
// Detect screen size/mode
screen_mode();
// Initialize layout
layout_init();
@ -354,21 +357,23 @@ function rcube_elastic_ui()
/**
* Create a button clone for use in toolbar
*/
function create_cloned_button(target)
function create_cloned_button(target, menu_button, add_class)
{
var button = $('<a>'),
target_id = target.attr('id'),
button_id = target_id + '-clone',
btn_class = target[0].className;
btn_class = target[0].className + (add_class ? ' ' + add_class : '');
btn_class = $.trim(btn_class.replace('btn-primary', 'primary').replace(/(btn[a-z-]*|button|disabled)/g, ''))
btn_class += ' button disabled';
if (!menu_button) {
btn_class = $.trim(btn_class.replace('btn-primary', 'primary').replace(/(btn[a-z-]*|button|disabled)/g, ''))
btn_class += ' button disabled';
}
button.attr({'onclick': '', id: button_id, href: '#', 'class': btn_class})
.append($('<span class="inner">').text(target.text()))
.on('click', function(e) { target.click(); });
if (is_framed) {
if (is_framed && !menu_button) {
button.data('target', target);
frame_buttons.push($.extend({button_id: button_id}, find_button(target[0].id)));
}
@ -452,21 +457,33 @@ function rcube_elastic_ui()
list = table.data('list');
if (rcmail[list] && rcmail[list].multiselect) {
var parent = table.parents('.sidebar,.list,.content').last(),
toolbar = parent.find('.pagenav');
var button, parent = table.parents('.sidebar,.list,.content').last(),
header = parent.find('.header'),
toolbar = header.find('ul');
if (!toolbar.length) {
toolbar = $('<div class="pagenav toolbar footer small">').appendTo(parent);
toolbar = header;
}
else if (button = toolbar.find('a.button.select').data('toggle-button')) {
button = $('#' + button);
}
// Enable checkbox selection on list widgets
rcmail[list].enable_checkbox_selection();
// Add Select button to the list navigation bar
button = $('<a>').attr({'class': 'button icon toggleselect disabled', role: 'button'})
.on('click', function() { if ($(this).is('.active')) table.toggleClass('withselection'); })
.append($('<span class="inner">').text(rcmail.gettext('select')))
.prependTo(toolbar);
if (!button) {
button = $('<a>').attr({'class': 'button select disabled', role: 'button', title: rcmail.gettext('select')})
.on('click', function() { if ($(this).is('.active')) table.toggleClass('withselection'); })
.append($('<span class="inner">').text(rcmail.gettext('select')));
if (toolbar.is('.toolbar')) {
button.prependTo(toolbar).wrap('<li role="menuitem">');
}
else {
button.appendTo(toolbar).addClass('icon toolbar-button');
}
}
// Update Select button state on list update
rcmail.addEventListener('listupdate', function(prop) {
@ -1211,12 +1228,11 @@ function rcube_elastic_ui()
};
/**
* Window resize handler
* Does layout reflows e.g. on screen orientation change
* screen mode
*/
function resize()
function screen_mode()
{
var size, mobile, width = $(window).width();
var size, width = $(window).width();
if (width <= 480)
size = 'phone';
@ -1229,6 +1245,17 @@ function rcube_elastic_ui()
touch = width <= 1024;
mode = size;
};
/**
* Window resize handler
* Does layout reflows e.g. on screen orientation change
*/
function resize()
{
var mobile;
screen_mode();
screen_resize();
screen_resize_html();
@ -1366,7 +1393,10 @@ function rcube_elastic_ui()
layout.content.removeClass('hidden');
app_menu(true);
screen_resize_small_none();
$('.header > ul.toolbar', layout.list).addClass('popupmenu');
if (layout.list) {
$('.header > ul.toolbar', layout.list).addClass('popupmenu toolbarmenu').removeClass('toolbar');
}
};
function screen_resize_large()
@ -1374,6 +1404,10 @@ function rcube_elastic_ui()
$.each(layout, function(name, item) { item.removeClass('hidden'); });
screen_resize_small_none();
if (layout.list) {
$('.header > ul.toolbarmenu.popupmenu', layout.list).removeClass('popupmenu toolbarmenu').addClass('toolbar');
}
};
function screen_resize_small_all()
@ -1383,11 +1417,13 @@ function rcube_elastic_ui()
if (layout.content.length) {
show = got_content = layout.content.is(env.last_selected);
layout.content[show ? 'removeClass' : 'addClass']('hidden');
$('.header > ul.toolbar', layout.content).addClass('popupmenu');
}
if (layout.list.length) {
show = !got_content && layout.list.is(env.last_selected);
layout.list[show ? 'removeClass' : 'addClass']('hidden');
$('.header > ul.toolbar', layout.list).addClass('popupmenu');
}
if (layout.sidebar.length) {
@ -1398,9 +1434,6 @@ function rcube_elastic_ui()
if (got_content) {
buttons.back_list.show();
}
$('.header > ul.toolbar', layout.content).addClass('popupmenu');
$('.header > ul.toolbar', layout.list).addClass('popupmenu');
};
function screen_resize_small_none()
@ -1585,6 +1618,9 @@ function rcube_elastic_ui()
}
}
// Close all popovers
$(document).click();
// Display loader when the dialog has an iframe
iframe_loader($('div.popup > iframe', me));
@ -1599,6 +1635,7 @@ function rcube_elastic_ui()
{
var options_button = $('a.button.options', bar),
input = $('input:not([type=hidden])', bar),
placeholder = input.attr('placeholder'),
form = $('form', bar),
is_search_pending = function() {
if (input.val()) {
@ -1643,7 +1680,9 @@ function rcube_elastic_ui()
}
});
input.on('input change', update_func);
input.on('input change', update_func)
.on('focus', function() { input.attr('placeholder', ''); })
.on('blur', function() { input.attr('placeholder', placeholder); });
// Search reset action
$('a.reset', bar).on('click', function(e) {
@ -1687,11 +1726,12 @@ function rcube_elastic_ui()
env.got_smart_toolbar = true;
var items = [],
var list_mark, items = [],
list_items = [],
button_func = function(button, items) {
meta = layout_metadata(),
button_func = function(button, items, cloned) {
var item = $('<li role="menuitem">'),
button = $(button).detach();
button = cloned ? create_cloned_button($(button), true, 'hidden-big hidden-large') : $(button).detach();
// Remove empty text nodes that break alignment of text of the menu item
button.contents().filter(function() { if (this.nodeType == 3 && !$.trim(this.nodeValue).length) $(this).remove(); });
@ -1706,22 +1746,35 @@ function rcube_elastic_ui()
items.push(item);
};
// convert toolbar to a popup list
if (layout.list) {
$('.header > .toolbar', layout.list).each(function() {
// convert content toolbar to a popup list
if (layout.content) {
$('.header > .toolbar', layout.content).each(function() {
var toolbar = $(this);
toolbar.children().each(function() { button_func(this, list_items); });
toolbar.children().each(function() { button_func(this, items); });
toolbar.remove();
});
}
// convert toolbar to a popup list
if (layout.content) {
$('.header > .toolbar', layout.content).each(function() {
// convert list toolbar to a popup list
if (layout.list) {
$('.header > .toolbar', layout.list).each(function() {
var toolbar = $(this);
toolbar.children().each(function() { button_func(this, items); });
list_mark = toolbar.next();
toolbar.children().each(function() {
if (meta.mode != 'large') {
// TODO: Would be better to set this automatically on submenu display
// i.e. in show/shown event (see popup_init()), if possible
$(this).data('popup-pos', 'right');
}
// add items to the content menu too
button_func(this, items, true);
button_func(this, list_items);
});
toolbar.remove();
});
}
@ -1742,12 +1795,17 @@ function rcube_elastic_ui()
var container = layout.list.children('.header'),
menu_attrs = {'class': 'toolbar popupmenu listing iconized', id: 'toolbar-list-menu'},
menu_button = $('<a class="button icon toolbar-list-button" href="#list-menu">')
.attr({'data-popup': 'toolbar-list-menu'});
container
.attr({'data-popup': 'toolbar-list-menu'}),
// TODO: copy original toolbar attributes (class, role, aria-*)
.append($('<ul>').attr(menu_attrs).data('popup-parent', container).append(list_items))
.append(menu_button);
toolbar = $('<ul>').attr(menu_attrs).data('popup-parent', container).append(list_items);
if (list_mark.length) {
toolbar.insertBefore(list_mark);
}
else {
container.append(toolbar);
}
container.append(menu_button);
}
// append the new toolbar and menu button
@ -1783,7 +1841,6 @@ function rcube_elastic_ui()
}
if (!win) win = window;
var level,
popup_id = $(item).data('popup'),
popup = $(win.$('#' + popup_id).get(0)), // a "hack" to support elements in frames

Loading…
Cancel
Save