mirror of
https://github.com/discourse/discourse.git
synced 2025-06-08 00:27:32 +08:00
UX: header search mobile support - follow up (#32306)
### Changes made #### Styling 1. added `4px` spacing between search input and cancel button 2. increased cancel button size (with padding) to match input height 3. decreased search panel padding by 1/2 from 16px to 8px 4. animation show/hide changed (from vertical to horizontal) and made it quicker (300ms->200ms) 5. set html unscrollable when search panel is open #### Dev 1. changed `data-test-` value to be consistent with other element's attrs values 2. clear search action tag changed from `<a>` to `<DButton>`
This commit is contained in:
@ -116,6 +116,7 @@ export default class GlimmerHeader extends Component {
|
|||||||
handleAnimationComplete() {
|
handleAnimationComplete() {
|
||||||
this.hasClosingAnimation = false;
|
this.hasClosingAnimation = false;
|
||||||
this.search.visible = false;
|
this.search.visible = false;
|
||||||
|
this.toggleBodyScrolling(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -169,9 +170,11 @@ export default class GlimmerHeader extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.site.mobileView && this.search.visible) {
|
if (this.site.mobileView && this.search.visible) {
|
||||||
|
// hide is delayed for the duration of `search-slide-out` animation
|
||||||
this.hasClosingAnimation = true;
|
this.hasClosingAnimation = true;
|
||||||
} else {
|
} else {
|
||||||
this.search.visible = !this.search.visible;
|
this.search.visible = !this.search.visible;
|
||||||
|
this.toggleBodyScrolling(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.search.visible) {
|
if (!this.search.visible) {
|
||||||
|
@ -188,9 +188,7 @@ export default class SearchMenu extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@bind
|
@bind
|
||||||
clearSearch(e) {
|
clearSearch() {
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
this.search.activeGlobalSearchTerm = "";
|
this.search.activeGlobalSearchTerm = "";
|
||||||
this.search.focusSearchInput();
|
this.search.focusSearchInput();
|
||||||
this.triggerSearch();
|
this.triggerSearch();
|
||||||
@ -471,8 +469,8 @@ export default class SearchMenu extends Component {
|
|||||||
<DButton
|
<DButton
|
||||||
@action={{this.cancelMobileSearch}}
|
@action={{this.cancelMobileSearch}}
|
||||||
@translatedLabel={{i18n "cancel_value"}}
|
@translatedLabel={{i18n "cancel_value"}}
|
||||||
class="btn-flat"
|
class="btn-flat btn-cancel-mobile-search"
|
||||||
data-test-button="cancel-search-mobile"
|
data-test-button="cancel-mobile-search"
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,7 +3,7 @@ import { i18n } from "discourse-i18n";
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DButton
|
<DButton
|
||||||
class="show-advanced-search btn-transparent"
|
class="btn-transparent show-advanced-search"
|
||||||
data-test-button="show-advanced-search"
|
data-test-button="show-advanced-search"
|
||||||
title={{i18n "search.open_advanced"}}
|
title={{i18n "search.open_advanced"}}
|
||||||
@action={{@openAdvancedSearch}}
|
@action={{@openAdvancedSearch}}
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
import { on } from "@ember/modifier";
|
import DButton from "discourse/components/d-button";
|
||||||
import icon from "discourse/helpers/d-icon";
|
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a
|
<DButton
|
||||||
class="clear-search"
|
class="btn-transparent clear-search"
|
||||||
data-test-anchor="clear-search-input"
|
data-test-button="clear-search-input"
|
||||||
aria-label="clear_input"
|
aria-label="clear_input"
|
||||||
title={{i18n "search.clear_search"}}
|
title={{i18n "search.clear_search"}}
|
||||||
href
|
@action={{@clearSearch}}
|
||||||
{{on "click" @clearSearch}}
|
@icon="xmark"
|
||||||
>
|
/>
|
||||||
{{icon "xmark"}}
|
|
||||||
</a>
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -15,7 +15,7 @@ export default modifier(
|
|||||||
(
|
(
|
||||||
element,
|
element,
|
||||||
posArgs,
|
posArgs,
|
||||||
{ animate = false, onComplete = () => {}, elementSelector, delay = 300 }
|
{ animate = false, onComplete = () => {}, elementSelector, delay = 200 }
|
||||||
) => {
|
) => {
|
||||||
if (animate) {
|
if (animate) {
|
||||||
const targetEl = elementSelector
|
const targetEl = elementSelector
|
||||||
|
@ -52,7 +52,7 @@ acceptance("Search - Mobile", function (needs) {
|
|||||||
"search results are listed on search value present"
|
"search results are listed on search value present"
|
||||||
);
|
);
|
||||||
|
|
||||||
await click('[data-test-anchor="clear-search-input"]');
|
await click('[data-test-button="clear-search-input"]');
|
||||||
|
|
||||||
assert
|
assert
|
||||||
.dom('[data-test-selector="search-menu-results"]')
|
.dom('[data-test-selector="search-menu-results"]')
|
||||||
@ -64,7 +64,7 @@ acceptance("Search - Mobile", function (needs) {
|
|||||||
test("with empty input search", async function (assert) {
|
test("with empty input search", async function (assert) {
|
||||||
await visit("/");
|
await visit("/");
|
||||||
await click("#search-button");
|
await click("#search-button");
|
||||||
await click('[data-test-button="cancel-search-mobile"]');
|
await click('[data-test-button="cancel-mobile-search"]');
|
||||||
|
|
||||||
assert
|
assert
|
||||||
.dom('[data-test-selector="menu-panel"]')
|
.dom('[data-test-selector="menu-panel"]')
|
||||||
@ -82,7 +82,7 @@ acceptance("Search - Mobile", function (needs) {
|
|||||||
"search results are listed on search value present"
|
"search results are listed on search value present"
|
||||||
);
|
);
|
||||||
|
|
||||||
await click('[data-test-button="cancel-search-mobile"]');
|
await click('[data-test-button="cancel-mobile-search"]');
|
||||||
await click("#search-button");
|
await click("#search-button");
|
||||||
|
|
||||||
assert.dom('[data-test-input="search-term"]').hasNoValue();
|
assert.dom('[data-test-input="search-term"]').hasNoValue();
|
||||||
|
@ -242,36 +242,44 @@
|
|||||||
&.search-menu-panel {
|
&.search-menu-panel {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
|
padding: 0.5rem 0.5rem 0;
|
||||||
|
transform-origin: 66%;
|
||||||
|
transition: height 0.2s ease-in;
|
||||||
|
|
||||||
&.empty-panel {
|
&.empty-panel {
|
||||||
height: auto;
|
height: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.slide-in {
|
&.slide-in {
|
||||||
animation: search-slidein 0.3s ease-out forwards;
|
animation: search-slide-in 0.2s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-destroying {
|
&.is-destroying {
|
||||||
animation: search-slideout 0.3s ease-in forwards;
|
animation: search-slide-out 0.2s ease-in forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes search-slidein {
|
@keyframes search-slide-in {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-100%);
|
transform: scaleX(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes search-slideout {
|
@keyframes search-slide-out {
|
||||||
80% {
|
from {
|
||||||
|
transform: scaleX(1);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-100%);
|
transform: scaleX(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-cancel-mobile-search {
|
||||||
|
padding: 1rem 0.625rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,19 @@ $search-pad-horizontal: 0.5em;
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
gap: 0.25rem;
|
||||||
|
|
||||||
|
@include breakpoint("mobile-extra-large") {
|
||||||
|
--search-input-wrapper-padding: 0.5rem;
|
||||||
|
position: fixed;
|
||||||
|
left: var(--search-input-wrapper-padding);
|
||||||
|
right: var(--search-input-wrapper-padding);
|
||||||
|
top: var(--search-input-wrapper-padding);
|
||||||
|
width: calc(100dvw - calc(var(--search-input-wrapper-padding) * 2));
|
||||||
|
padding-bottom: var(--search-input-wrapper-padding);
|
||||||
|
background-color: var(--secondary);
|
||||||
|
z-index: z("base");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
@ -113,6 +126,13 @@ $search-pad-horizontal: 0.5em;
|
|||||||
padding-top: $search-pad-vertical;
|
padding-top: $search-pad-vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include breakpoint("mobile-extra-large") {
|
||||||
|
&,
|
||||||
|
&.with-search-term {
|
||||||
|
padding-top: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
|
|
||||||
@ -403,18 +423,14 @@ $search-pad-horizontal: 0.5em;
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.spinner {
|
.spinner {
|
||||||
width: 12px;
|
width: 0.75rem; // 12px
|
||||||
height: 12px;
|
height: 0.75rem; // 12px
|
||||||
border-width: 2px;
|
border-width: 0.125rem; // 2px
|
||||||
margin: 0 0.5em 0.25em 0;
|
margin: 0 $hpad 0 0;
|
||||||
margin-top: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.show-advanced-search,
|
.show-advanced-search,
|
||||||
a.clear-search {
|
.clear-search {
|
||||||
display: inline-block;
|
|
||||||
background-color: transparent;
|
|
||||||
|
|
||||||
.d-icon {
|
.d-icon {
|
||||||
color: var(--primary-medium);
|
color: var(--primary-medium);
|
||||||
}
|
}
|
||||||
@ -427,8 +443,12 @@ $search-pad-horizontal: 0.5em;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a.clear-search {
|
.clear-search {
|
||||||
margin-right: 3px;
|
padding-right: 0.25rem; // 4px
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-advanced-search {
|
||||||
|
padding-left: 0.375rem; // 6px
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
|
||||||
.show-advanced-search,
|
.show-advanced-search,
|
||||||
a.clear-search {
|
.clear-search {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user