Skip to content

Commit f23da69

Browse files
MDL-89010 theme_boost: apply inline search design to mobile navbar
1 parent 572b629 commit f23da69

6 files changed

Lines changed: 253 additions & 39 deletions

File tree

public/lib/templates/search_input_navbar_inline.mustache

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
{{!
1818
@template core/search_input_navbar_inline
1919
20-
Inline navbar search input for desktop. Always visible, no collapse or toggle.
20+
Navbar search input using the inline field design. The field is always
21+
visible on desktop. On small screens only a toggle button is shown and
22+
the field expands across the navbar, with a close button inside the field.
2123
2224
Example context (json):
2325
{
@@ -34,7 +36,17 @@
3436
}
3537
}}
3638
<div id="searchinput-navbar" class="search-input-inline">
39+
<button type="button"
40+
class="nav-link icon-no-margin search-toggle"
41+
data-action="opensearch"
42+
aria-expanded="false"
43+
aria-controls="searchform-navbar-inline"
44+
title="{{#str}} togglesearch {{/str}}">
45+
{{#pix}} a/search, core {{/pix}}
46+
<span class="visually-hidden">{{#str}} togglesearch {{/str}}</span>
47+
</button>
3748
<form role="search"
49+
id="searchform-navbar-inline"
3850
{{#grouplabel}}aria-label="{{{ grouplabel }}}"{{/grouplabel}}
3951
autocomplete="off"
4052
action="{{{ action }}}"
@@ -57,6 +69,12 @@
5769
name="{{{ inputname }}}"
5870
data-region="input"
5971
autocomplete="off">
72+
<button type="button"
73+
class="search-close d-md-none"
74+
data-action="closesearch">
75+
{{#pix}} e/cancel, core {{/pix}}
76+
<span class="visually-hidden">{{#str}} closebuttontitle {{/str}}</span>
77+
</button>
6078
</div>
6179
</form>
6280
</div>
@@ -66,11 +84,26 @@ require([], function() {
6684
const wrapper = document.getElementById('searchinput-navbar');
6785
const form = wrapper.querySelector('.searchform-navbar');
6886
const input = wrapper.querySelector('[data-region="input"]');
87+
const opensearch = wrapper.querySelector('[data-action="opensearch"]');
88+
const closesearch = wrapper.querySelector('[data-action="closesearch"]');
6989
7090
form.addEventListener('submit', (e) => {
7191
if (input.value.trim() === '') {
7292
e.preventDefault();
7393
}
7494
});
95+
96+
opensearch.addEventListener('click', () => {
97+
wrapper.classList.add('expanded');
98+
opensearch.setAttribute('aria-expanded', 'true');
99+
input.focus();
100+
});
101+
102+
closesearch.addEventListener('click', () => {
103+
wrapper.classList.remove('expanded');
104+
opensearch.setAttribute('aria-expanded', 'false');
105+
input.value = '';
106+
opensearch.focus();
107+
});
75108
});
76109
{{/js}}

public/search/tests/behat/behat_search.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class behat_search extends behat_base {
4545
* @param string $query Query to search for
4646
*/
4747
public function i_search_for_using_the_header_global_search_box($query) {
48-
// In boost the toggle button lives inside the mobile-only wrapper and is hidden on desktop.
49-
// Classic always shows it. Check visibility before clicking to handle both cases.
48+
// In boost the toggle button is only visible on small screens, where it expands the
49+
// inline search field. Check visibility before clicking.
5050
$togglelabel = get_string('togglesearch', 'core');
5151
$toggle = $this->getSession()->getPage()->find('named', ['button', $togglelabel]);
5252
if ($toggle && $toggle->isVisible()) {

public/theme/boost/classes/output/core_renderer.php

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@
3333
*/
3434
class core_renderer extends \core_renderer {
3535
/**
36-
* Returns an inline search box permanently visible in the top navigation.
36+
* Returns the navbar search box using the inline field design.
3737
*
38-
* @param string $id Passed to parent::search_box() for the mobile fallback.
39-
* @return string HTML for the inline and mobile search forms, or empty string.
38+
* The field is always visible on md+ viewports and collapses behind a
39+
* toggle button on smaller screens.
40+
*
41+
* @param string $id Unused, kept for compatibility with the parent signature.
42+
* @return string HTML for the navbar search form, or empty string.
4043
*/
4144
public function search_box($id = false) {
4245
global $CFG;
@@ -53,13 +56,7 @@ public function search_box($id = false) {
5356
'grouplabel' => get_string('sitewidesearch', 'search'),
5457
];
5558

56-
// Desktop (md+): new inline, always-visible form.
57-
$desktop = $this->render_from_template('core/search_input_navbar_inline', $data);
58-
59-
// Mobile (< md): keep the original toggle + collapse pattern.
60-
$mobile = html_writer::div(parent::search_box($id), 'd-flex d-md-none');
61-
62-
return $desktop . $mobile;
59+
return $this->render_from_template('core/search_input_navbar_inline', $data);
6360
}
6461

6562
/**

public/theme/boost/scss/moodle/navbar.scss

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,19 +190,19 @@
190190

191191
// Inline search form.
192192
.navbar.fixed-top #usernavigation .search-input-inline {
193-
display: none;
193+
display: flex;
194+
align-items: center;
195+
height: 100%;
194196

195-
@include media-breakpoint-up(md) {
197+
.search-toggle {
196198
display: flex;
197199
align-items: center;
198200
height: 100%;
199-
padding: 0 $primary-nav-padding-x;
200201
}
201202

202203
.searchform-navbar {
203-
.input-group {
204-
width: 256px;
205-
}
204+
display: none;
205+
206206
.input-group-text,
207207
.form-control {
208208
background-color: $gray-200;
@@ -211,5 +211,73 @@
211211
.form-control::placeholder {
212212
color: $gray-700;
213213
}
214+
.input-group > .form-control {
215+
@include border-end-radius($input-border-radius);
216+
}
217+
// Close button floats inside the field, over its end padding.
218+
.search-close {
219+
position: absolute;
220+
top: 0;
221+
right: 0;
222+
height: 100%;
223+
padding: 0 0.5rem;
224+
background: none;
225+
border: 0;
226+
color: $gray-700;
227+
z-index: 6;
228+
229+
.icon {
230+
margin: 0;
231+
}
232+
}
233+
}
234+
235+
@include media-breakpoint-up(md) {
236+
padding: 0 $primary-nav-padding-x;
237+
238+
.search-toggle {
239+
display: none;
240+
}
241+
242+
.searchform-navbar {
243+
display: block;
244+
245+
.input-group {
246+
width: 256px;
247+
}
248+
}
249+
}
250+
251+
// On small screens the field expands across the whole navbar.
252+
@include media-breakpoint-down(md) {
253+
&.expanded {
254+
position: absolute;
255+
top: 0;
256+
left: 0;
257+
width: 100%;
258+
height: $navbar-height;
259+
padding: 0 $primary-nav-padding-x;
260+
background-color: $white;
261+
z-index: $zindex-popover;
262+
263+
.search-toggle {
264+
display: none;
265+
}
266+
267+
.searchform-navbar {
268+
display: flex;
269+
align-items: center;
270+
width: 100%;
271+
272+
.input-group {
273+
width: 100%;
274+
flex-wrap: nowrap;
275+
}
276+
277+
.form-control {
278+
padding-right: 2rem;
279+
}
280+
}
281+
}
214282
}
215283
}

public/theme/boost/style/moodle.css

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42841,18 +42841,17 @@ div.editor_atto_toolbar button .icon {
4284142841
}
4284242842

4284342843
.navbar.fixed-top #usernavigation .search-input-inline {
42844-
display: none;
42844+
display: flex;
42845+
align-items: center;
42846+
height: 100%;
4284542847
}
42846-
@media (min-width: 768px) {
42847-
.navbar.fixed-top #usernavigation .search-input-inline {
42848-
display: flex;
42849-
align-items: center;
42850-
height: 100%;
42851-
padding: 0 0.5rem;
42852-
}
42848+
.navbar.fixed-top #usernavigation .search-input-inline .search-toggle {
42849+
display: flex;
42850+
align-items: center;
42851+
height: 100%;
4285342852
}
42854-
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .input-group {
42855-
width: 256px;
42853+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar {
42854+
display: none;
4285642855
}
4285742856
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .input-group-text,
4285842857
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .form-control {
@@ -42862,6 +42861,65 @@ div.editor_atto_toolbar button .icon {
4286242861
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .form-control::placeholder {
4286342862
color: #495057;
4286442863
}
42864+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .input-group > .form-control {
42865+
border-top-right-radius: var(--bs-border-radius);
42866+
border-bottom-right-radius: var(--bs-border-radius);
42867+
}
42868+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .search-close {
42869+
position: absolute;
42870+
top: 0;
42871+
right: 0;
42872+
height: 100%;
42873+
padding: 0 0.5rem;
42874+
background: none;
42875+
border: 0;
42876+
color: #495057;
42877+
z-index: 6;
42878+
}
42879+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .search-close .icon {
42880+
margin: 0;
42881+
}
42882+
@media (min-width: 768px) {
42883+
.navbar.fixed-top #usernavigation .search-input-inline {
42884+
padding: 0 0.5rem;
42885+
}
42886+
.navbar.fixed-top #usernavigation .search-input-inline .search-toggle {
42887+
display: none;
42888+
}
42889+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar {
42890+
display: block;
42891+
}
42892+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .input-group {
42893+
width: 256px;
42894+
}
42895+
}
42896+
@media (max-width: 767.98px) {
42897+
.navbar.fixed-top #usernavigation .search-input-inline.expanded {
42898+
position: absolute;
42899+
top: 0;
42900+
left: 0;
42901+
width: 100%;
42902+
height: 60px;
42903+
padding: 0 0.5rem;
42904+
background-color: #ffffff;
42905+
z-index: 1070;
42906+
}
42907+
.navbar.fixed-top #usernavigation .search-input-inline.expanded .search-toggle {
42908+
display: none;
42909+
}
42910+
.navbar.fixed-top #usernavigation .search-input-inline.expanded .searchform-navbar {
42911+
display: flex;
42912+
align-items: center;
42913+
width: 100%;
42914+
}
42915+
.navbar.fixed-top #usernavigation .search-input-inline.expanded .searchform-navbar .input-group {
42916+
width: 100%;
42917+
flex-wrap: nowrap;
42918+
}
42919+
.navbar.fixed-top #usernavigation .search-input-inline.expanded .searchform-navbar .form-control {
42920+
padding-right: 2rem;
42921+
}
42922+
}
4286542923

4286642924
/**
4286742925
* Reportbuilder styles.

public/theme/classic/style/moodle.css

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40576,18 +40576,17 @@ div.editor_atto_toolbar button .icon {
4057640576
}
4057740577

4057840578
.navbar.fixed-top #usernavigation .search-input-inline {
40579-
display: none;
40579+
display: flex;
40580+
align-items: center;
40581+
height: 100%;
4058040582
}
40581-
@media (min-width: 768px) {
40582-
.navbar.fixed-top #usernavigation .search-input-inline {
40583-
display: flex;
40584-
align-items: center;
40585-
height: 100%;
40586-
padding: 0 0.5rem;
40587-
}
40583+
.navbar.fixed-top #usernavigation .search-input-inline .search-toggle {
40584+
display: flex;
40585+
align-items: center;
40586+
height: 100%;
4058840587
}
40589-
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .input-group {
40590-
width: 256px;
40588+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar {
40589+
display: none;
4059140590
}
4059240591
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .input-group-text,
4059340592
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .form-control {
@@ -40597,6 +40596,65 @@ div.editor_atto_toolbar button .icon {
4059740596
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .form-control::placeholder {
4059840597
color: #495057;
4059940598
}
40599+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .input-group > .form-control {
40600+
border-top-right-radius: var(--bs-border-radius);
40601+
border-bottom-right-radius: var(--bs-border-radius);
40602+
}
40603+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .search-close {
40604+
position: absolute;
40605+
top: 0;
40606+
right: 0;
40607+
height: 100%;
40608+
padding: 0 0.5rem;
40609+
background: none;
40610+
border: 0;
40611+
color: #495057;
40612+
z-index: 6;
40613+
}
40614+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .search-close .icon {
40615+
margin: 0;
40616+
}
40617+
@media (min-width: 768px) {
40618+
.navbar.fixed-top #usernavigation .search-input-inline {
40619+
padding: 0 0.5rem;
40620+
}
40621+
.navbar.fixed-top #usernavigation .search-input-inline .search-toggle {
40622+
display: none;
40623+
}
40624+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar {
40625+
display: block;
40626+
}
40627+
.navbar.fixed-top #usernavigation .search-input-inline .searchform-navbar .input-group {
40628+
width: 256px;
40629+
}
40630+
}
40631+
@media (max-width: 767.98px) {
40632+
.navbar.fixed-top #usernavigation .search-input-inline.expanded {
40633+
position: absolute;
40634+
top: 0;
40635+
left: 0;
40636+
width: 100%;
40637+
height: 50px;
40638+
padding: 0 0.5rem;
40639+
background-color: #fff;
40640+
z-index: 1070;
40641+
}
40642+
.navbar.fixed-top #usernavigation .search-input-inline.expanded .search-toggle {
40643+
display: none;
40644+
}
40645+
.navbar.fixed-top #usernavigation .search-input-inline.expanded .searchform-navbar {
40646+
display: flex;
40647+
align-items: center;
40648+
width: 100%;
40649+
}
40650+
.navbar.fixed-top #usernavigation .search-input-inline.expanded .searchform-navbar .input-group {
40651+
width: 100%;
40652+
flex-wrap: nowrap;
40653+
}
40654+
.navbar.fixed-top #usernavigation .search-input-inline.expanded .searchform-navbar .form-control {
40655+
padding-right: 2rem;
40656+
}
40657+
}
4060040658

4060140659
/**
4060240660
* Reportbuilder styles.

0 commit comments

Comments
 (0)