diff --git a/core/tests/Unit/Manager/ActionButtonsStyleTest.php b/core/tests/Unit/Manager/ActionButtonsStyleTest.php new file mode 100644 index 0000000000..22dcd87c1e --- /dev/null +++ b/core/tests/Unit/Manager/ActionButtonsStyleTest.php @@ -0,0 +1,28 @@ +not->toMatch('/#actions[^{]*\.btn-success[^{]*\{[^}]*box-shadow/'); +}); + +test('action button text sits 1px higher than the forms.css padding puts it', function () { + $css = actionButtonsCss(); + + expect($css)->toContain('#actions .btn-group .btn { padding-top: calc(.46153846em - 1px) }') + // the chevron toggle keeps the full padding, so it does not move with the text + ->and($css)->toMatch('/#actions \.btn-group \.plus \{[^}]*padding: \.46153846em 0;/'); +}); + +test('the stay toggle chevron is drawn 1px taller and 1px higher, and keeps that while the menu is open', function () { + $css = actionButtonsCss(); + + expect($css)->toMatch('/#actions \.btn-group \.plus::before \{[^}]*width:1\.25em;height:1\.25em;margin-bottom:\.08em;position:relative;top:-1px;/') + // the open state swaps only the icon, a size of its own would shrink it back + ->and($css)->toMatch('/#actions \.btn-group \.show \.plus::before \{ -webkit-mask-image:var\(--evo-icon-chevron-up\); mask-image:var\(--evo-icon-chevron-up\) \}/'); +}); diff --git a/core/tests/Unit/Manager/MenuItemGroupStyleTest.php b/core/tests/Unit/Manager/MenuItemGroupStyleTest.php new file mode 100644 index 0000000000..193d3aba81 --- /dev/null +++ b/core/tests/Unit/Manager/MenuItemGroupStyleTest.php @@ -0,0 +1,26 @@ +toMatch('/#mainMenu \.nav li\.item-group > \*:not\(:first-child\) svg \{\s*margin-right: 0;/') + ->and($css)->toMatch('/#mainMenu \.nav li\.item-group > \*:not\(:first-child\) \{\s*vertical-align: middle;/'); +}); + +test('top menu dropdowns end at their last item, which takes the rounded corners', function () { + $css = file_get_contents(dirname(__DIR__, 4) . '/manager/media/style/default/css/mainmenu.css'); + preg_match('/#mainMenu \.nav > li > ul \{([^}]*)\}/', $css, $rule); + + // bottom padding under the last item showed as a white strip below its hover background + expect($rule[1] ?? '')->toMatch('/\bpadding: 0;/') + ->and($rule[1] ?? '')->toContain('border-radius: 0 0 0.25rem 0.25rem;') + ->and($rule[1] ?? '')->toContain('overflow: auto;'); +}); + +test('the last top menu item is as tall as the others, which carry a 1px separator', function () { + $css = file_get_contents(dirname(__DIR__, 4) . '/manager/media/style/default/css/mainmenu.css'); + + expect($css)->toMatch('/#mainMenu \.nav > li > ul > li \{\s*border-bottom: 1px solid[^}]*margin-bottom: -1px;/') + ->and($css)->toMatch('/#mainMenu \.nav > li > ul > li:last-child > a:first-child,\s*#mainMenu \.nav > li > ul > li:last-child > span:first-child \{\s*padding-bottom: 1px;/'); +}); diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index e729a4864d..b9b1697f01 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -46,10 +46,10 @@ select[name=context] + input[type=submit] { float: none; margin: 0; } #actions .btn-group > .btn-group { display: block } #actions .btn-group .btn, #actions .btn-group .form-control { font-size: .6772rem; height: 2.4em; line-height: 1.4 } +/* the forms.css padding sets the text 1px below the middle of these fixed-height buttons */ +#actions .btn-group .btn { padding-top: calc(.46153846em - 1px) } #actions .btn-group .btn .evo-icon, #_actions .btn-group .btn .evo-icon { display: none; width: 1em; font-size: 1em; text-align: center } #actions .btn-group .btn-group #Button1 { min-width: 100%; text-align: left; float: right; } -#actions .btn-group .btn-success { box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .07); } -#actions .btn-group .btn-success:hover { box-shadow: none } /* the in-place save: the join box between "Save" and the stay option shows +, a spinner, then a check mark, at one width */ #actions .btn-group #Button1 .save-join { display: inline-block; position: relative; width: 1.4em; margin: 0 .25em; text-align: center } #actions .btn-group #Button1.saving { pointer-events: none; opacity: .75 } @@ -57,9 +57,10 @@ select[name=context] + input[type=submit] { float: none; margin: 0; } #actions .btn-group #Button1.saving .save-join::before { content: ''; position: absolute; left: 50%; top: 50%; width: .8em; height: .8em; margin: -.45em 0 0 -.45em; border: 2px solid rgba(255, 255, 255, .45); border-top-color: #fff; border-radius: 50%; animation: evo-save-spin .7s linear infinite } #actions .btn-group #Button1.saved .save-join::before { content: '\2713'; position: absolute; left: 0; right: 0; top: 0; color: #fff } @keyframes evo-save-spin { to { transform: rotate(360deg) } } -#actions .btn-group .plus { z-index: 2; float: right; margin: -2.4em 0 0 0; width: 2rem; padding-left: 0; padding-right: 0; text-align: center; cursor: pointer; } -#actions .btn-group .plus::before { content:"";display:inline-block;width:1em;height:1em;vertical-align:middle;background-color:currentColor;-webkit-mask:var(--evo-icon-chevron-down) center/contain no-repeat;mask:var(--evo-icon-chevron-down) center/contain no-repeat; font-weight: 900; } -#actions .btn-group .show .plus::before { content:"";display:inline-block;width:1em;height:1em;vertical-align:middle;background-color:currentColor;-webkit-mask:var(--evo-icon-chevron-up) center/contain no-repeat;mask:var(--evo-icon-chevron-up) center/contain no-repeat; } +#actions .btn-group .plus { z-index: 2; float: right; margin: -2.4em 0 0 0; width: 2rem; padding: .46153846em 0; text-align: center; cursor: pointer; } +/* the chevron fills only the middle of its box: 1.25em draws it 1px taller, the bottom margin keeps its lower edge in place, top lifts it 1px */ +#actions .btn-group .plus::before { content:"";display:inline-block;width:1.25em;height:1.25em;margin-bottom:.08em;position:relative;top:-1px;vertical-align:middle;background-color:currentColor;-webkit-mask:var(--evo-icon-chevron-down) center/contain no-repeat;mask:var(--evo-icon-chevron-down) center/contain no-repeat; } +#actions .btn-group .show .plus::before { -webkit-mask-image:var(--evo-icon-chevron-up); mask-image:var(--evo-icon-chevron-up) } #actions .btn-group select#stay { display: block; position: relative; z-index: -1; clear: both; width: auto; height: 0; margin: -100% 0 -2rem 0; font-size: 0.675rem; opacity: 0; visibility: hidden; } #actions .btn-group .dropdown-menu { display: none; position: absolute; z-index: -1; left: auto; right: 0; top: 100%; width: 100%; min-width: 2rem; margin: 0; padding: 0; text-align: left; font-size: .6772rem; border-top: none; border-radius: 0 0 0.1em 0.1em; overflow: hidden; } diff --git a/manager/media/style/default/css/forms.css b/manager/media/style/default/css/forms.css index a1b5cbde82..ea8e6b2fa2 100644 --- a/manager/media/style/default/css/forms.css +++ b/manager/media/style/default/css/forms.css @@ -78,7 +78,6 @@ select:not([size]):not([multiple]) { text-indent: -2px } .darkness .btn-default { color: #bbb; background-color: #202329; border-color: #202329 } .darkness .btn-default:hover { color: #fff; background-color: #1a1c21; border-color: #1a1c21 } .darkness #actions { right: 0; background-color: #212328 } -.darkness #actions .btn-group .btn-success { box-shadow: none } .darkness #actions .dropdown-menu .btn { background-color: #343942; border-radius: 0; color: #fff; } .darkness #actions .dropdown-menu .btn:hover { background-color: #3c424e; color: #fff } .darkness optgroup { background-color: #202329 } diff --git a/manager/media/style/default/css/mainmenu.css b/manager/media/style/default/css/mainmenu.css index e550bf8c03..b7cfd79d0c 100755 --- a/manager/media/style/default/css/mainmenu.css +++ b/manager/media/style/default/css/mainmenu.css @@ -266,7 +266,8 @@ body.sidebar-closed #bars .icon-collapse { display: none !important; } top: 100%; left: 0; margin: 0; - padding: 0 0 0.25rem; + /* no bottom padding: the last item reaches the rounded edge (overflow clips it), so its hover leaves no strip */ + padding: 0; min-width: 15rem; max-height: -webkit-calc(100vh - var(--manager-menu-height, 2.2rem)); max-height: calc(100vh - var(--manager-menu-height, 2.2rem)); @@ -303,6 +304,11 @@ body.sidebar-closed #bars .icon-collapse { display: none !important; } border: none; margin-bottom: 0; } +/* no separator below the last item: one more pixel keeps it as tall as the others, in its own hover colour */ +#mainMenu .nav > li > ul > li:last-child > a:first-child, +#mainMenu .nav > li > ul > li:last-child > span:first-child { + padding-bottom: 1px; +} #mainMenu .nav > li > ul > li.item-input { padding: 0.375em 0.5em; } @@ -434,7 +440,12 @@ body.sidebar-closed #bars .icon-collapse { display: none !important; } #mainMenu .nav li.item-group > *:first-child { width: 100%; } -#mainMenu .nav li.item-group > *:not(:first-child) .evo-icon { +/* an icon-only button beside the item: centred, without the gap menu icons keep before their label */ +#mainMenu .nav li.item-group > *:not(:first-child) { + vertical-align: middle; +} +#mainMenu .nav li.item-group > *:not(:first-child) .evo-icon, +#mainMenu .nav li.item-group > *:not(:first-child) svg { margin-right: 0; } /* statusbar */