Skip to content

Commit

Permalink
[full-ci] Fix search bar display on small screens (#7675)
Browse files Browse the repository at this point in the history
Fix search bar display on small screens
  • Loading branch information
JammingBen authored Oct 5, 2022
1 parent b7debe7 commit 468abaf
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 53 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/bugfix-search-bar-on-small-screens
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Bugfix: Search bar on small screens

We've fixed the display of the search bar on small screens.

https://github.com/owncloud/web/pull/7675
https://github.com/owncloud/web/issues/7617
113 changes: 83 additions & 30 deletions packages/web-app-search/src/portals/SearchBar.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
<template>
<div v-if="availableProviders.length" id="files-global-search" data-custom-key-bindings="true">
<div
v-if="availableProviders.length"
id="files-global-search"
ref="searchBar"
class="oc-flex"
data-custom-key-bindings="true"
>
<oc-search-bar
id="files-global-search-bar"
ref="search"
:label="searchLabel"
:type-ahead="true"
:placeholder="searchLabel"
:button-hidden="true"
:show-cancel-button="showCancelButton"
cancel-button-variation="inverse"
:cancel-handler="cancelSearch"
@input="updateTerm"
@clear="onClear"
@click.native="term && $refs.optionsDrop.show()"
Expand All @@ -15,6 +24,16 @@
@keyup.native.down="onKeyUpDown"
@keyup.native.enter="onKeyUpEnter"
/>
<oc-button
v-oc-tooltip="$gettext('Display search bar')"
:aria-label="$gettext('Click to display and focus the search bar')"
class="mobile-search-btn oc-mr-s"
appearance="raw"
variation="inverse"
@click="showSearchBar"
>
<oc-icon name="search" fill-type="line"></oc-icon>
</oc-button>
<oc-drop
id="files-global-search-options"
ref="optionsDrop"
Expand Down Expand Up @@ -86,6 +105,8 @@ export default {
data() {
return {
resizeObserver: new ResizeObserver(this.onResize),
showCancelButton: false,
term: '',
activeProvider: undefined,
optionsVisible: false,
Expand Down Expand Up @@ -167,6 +188,14 @@ export default {
})
},
mounted() {
this.resizeObserver.observe(this.$refs.searchBar)
},
beforeDestroy() {
this.resizeObserver.unobserve(this.$refs.searchBar)
},
methods: {
async search() {
this.searchResults = []
Expand Down Expand Up @@ -290,18 +319,51 @@ export default {
isPreviewElementActive(searchId) {
const previewElements = this.$refs.optionsDrop.$el.querySelectorAll('.preview')
return previewElements[this.activePreviewIndex]?.dataset?.searchId === searchId
},
showSearchBar() {
document.getElementById('files-global-search-bar').style.visibility = 'visible'
document.getElementsByClassName('oc-search-input')[0].focus()
this.showCancelButton = true
},
cancelSearch() {
document.getElementById('files-global-search-bar').style.visibility = 'hidden'
this.showCancelButton = false
},
onResize() {
const searchBarEl = document.getElementById('files-global-search-bar')
const optionDropVisible = !!document.querySelector('.tippy-box[data-state="visible"]')
if (window.innerWidth > 639) {
searchBarEl.style.visibility = 'visible'
this.showCancelButton = false
} else {
if (optionDropVisible) {
searchBarEl.style.visibility = 'visible'
this.showCancelButton = true
} else {
searchBarEl.style.visibility = 'hidden'
this.showCancelButton = false
}
}
}
}
}
</script>
<style lang="scss">
#files-global-search {
.mobile-search-btn {
display: none;
@media (max-width: 639px) {
display: inline-flex;
}
}
.oc-search-input {
background-color: var(--oc-color-input-bg);
transition: 0s;
@media (max-width: 959px) {
@media (max-width: 639px) {
border: none;
display: inline;
}
Expand All @@ -310,42 +372,29 @@ export default {
#files-global-search-bar {
width: 452px;
@media (max-width: 959px) {
min-width: 2.5rem;
width: 2.5rem;
background-color: var(--oc-color-swatch-brand-default);
width: 300px;
}
input,
.oc-width-expand {
width: 2.5rem;
}
@media (max-width: 639px) {
visibility: hidden;
background-color: var(--oc-color-swatch-brand-default);
position: absolute;
height: 48px;
left: 0;
right: 0;
margin: 0 auto;
top: 0;
width: 95vw !important;
.oc-search-input-icon {
padding: 0 var(--oc-space-large);
}
.oc-search-clear {
right: var(--oc-space-medium);
}
&:focus-within {
position: absolute;
height: 60px;
left: var(--oc-space-medium);
margin: 0 auto;
top: 0;
width: 100vw !important;
.oc-search-input-icon {
padding: 0 var(--oc-space-xlarge);
}
padding: 0 var(--oc-space-xlarge);
}
&:focus-within input,
input,
input:not(:placeholder-shown) {
background-color: var(--oc-color-input-bg);
border: 1px solid var(--oc-color-input-border);
z-index: var(--oc-z-index-modal);
width: 95%;
margin: 0 auto;
}
}
Expand All @@ -365,7 +414,11 @@ export default {
font-weight: 600;
}
@media (max-width: 959px) {
@media (max-width: 969px) {
width: 300px;
}
@media (max-width: 639px) {
width: 93vw !important;
}
Expand Down
6 changes: 6 additions & 0 deletions packages/web-app-search/tests/unit/portals/SearchBar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ jest.mock('lodash-es/debounce', () => (fn) => fn)
beforeEach(() => {
jest.resetAllMocks()

window.ResizeObserver = jest.fn().mockImplementation(() => ({
disconnect: jest.fn(),
observe: jest.fn(),
unobserve: jest.fn()
}))

providerFiles.previewSearch.search.mockImplementation(() => {
return {
values: [
Expand Down
5 changes: 1 addition & 4 deletions packages/web-runtime/src/components/Topbar/ThemeSwitcher.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
variation="inverse"
@click="toggleTheme"
>
<span class="oc-visible@s" :aria-label="switchLabel" v-text="switchText" />
<span class="oc-visible@s" :aria-label="switchLabel" />
<oc-icon :name="switchIcon" fill-type="line" />
</oc-button>
</template>
Expand Down Expand Up @@ -50,9 +50,6 @@ export default {
},
switchLabel() {
return this.$gettext('Currently used theme')
},
switchText() {
return this.isLightTheme ? this.$gettext('Light mode') : this.$gettext('Dark mode')
}
},
methods: {
Expand Down
6 changes: 6 additions & 0 deletions packages/web-runtime/src/components/Topbar/TopBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ export default {
position: sticky;
z-index: 5;
.portal-wrapper {
@media (max-width: 639px) {
margin-left: auto;
}
}
img {
max-height: 38px;
image-rendering: auto;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ThemeSwitcher component restores dark theme if dark theme is saved in localstorage 1`] = `
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s">Dark mode</span>
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s"></span>
<oc-icon-stub name="moon-clear" filltype="line" accessiblelabel="" type="span" size="medium" variation="passive" color=""></oc-icon-stub>
</button>
`;

exports[`ThemeSwitcher component restores light theme if light theme is saved in localstorage 1`] = `
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s">Light mode</span>
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s"></span>
<oc-icon-stub name="sun" filltype="line" accessiblelabel="" type="span" size="medium" variation="passive" color=""></oc-icon-stub>
</button>
`;

exports[`ThemeSwitcher component visually renders a button, initially in dark mode if user prefers dark color scheme 1`] = `
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s">Dark mode</span>
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s"></span>
<oc-icon-stub name="moon-clear" filltype="line" accessiblelabel="" type="span" size="medium" variation="passive" color=""></oc-icon-stub>
</button>
`;

exports[`ThemeSwitcher component visually renders a button, initially in light mode per default 1`] = `
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s">Light mode</span>
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s"></span>
<oc-icon-stub name="sun" filltype="line" accessiblelabel="" type="span" size="medium" variation="passive" color=""></oc-icon-stub>
</button>
`;

exports[`ThemeSwitcher component visually toggles between themes upon click 1`] = `
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s">Dark mode</span>
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s"></span>
<oc-icon-stub name="moon-clear" filltype="line" accessiblelabel="" type="span" size="medium" variation="passive" color=""></oc-icon-stub>
</button>
`;

exports[`ThemeSwitcher component visually toggles between themes upon click 2`] = `
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s">Light mode</span>
<button aria-label="Click to switch theme" type="button" class="themeswitcher-btn oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw"><span aria-label="Currently used theme" class="oc-visible@s"></span>
<oc-icon-stub name="sun" filltype="line" accessiblelabel="" type="span" size="medium" variation="passive" color=""></oc-icon-stub>
</button>
`;
24 changes: 11 additions & 13 deletions tests/acceptance/pageObjects/webPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ module.exports = {
*
* @param {string} searchTerm
*/
search: function (searchTerm) {
search: async function (searchTerm) {
// wait for search indexing to be finished
await this.pause(1000)
return this.initAjaxCounters()
.isVisible(
{
Expand All @@ -22,13 +24,13 @@ module.exports = {
(result) => {
if (result.value === true) {
this.click('@openSearchButton')
.waitForElementVisible('@searchInputFieldLowResolution')
.setValue('@searchInputFieldLowResolution', [searchTerm, this.api.Keys.ENTER])
.waitForElementVisible('@searchInputField')
.setValue('@searchInputField', [searchTerm, this.api.Keys.ENTER])
} else {
this.waitForElementVisible('@searchInputFieldHighResolution').setValue(
'@searchInputFieldHighResolution',
[searchTerm, this.api.Keys.ENTER]
)
this.waitForElementVisible('@searchInputField').setValue('@searchInputField', [
searchTerm,
this.api.Keys.ENTER
])
}
}
)
Expand Down Expand Up @@ -287,14 +289,10 @@ module.exports = {
ocDialogPromptAlert: {
selector: '.oc-modal .oc-text-input-message'
},
searchInputFieldHighResolution: {
searchInputField: {
selector: '(//input[contains(@class, "oc-search-input")])[1]',
locateStrategy: 'xpath'
},
searchInputFieldLowResolution: {
selector: '(//input[contains(@class, "oc-search-input")])[2]',
locateStrategy: 'xpath'
},
searchLoadingIndicator: {
selector: '#files-global-search-bar .oc-spinner'
},
Expand All @@ -303,7 +301,7 @@ module.exports = {
locateStrategy: 'xpath'
},
openSearchButton: {
selector: '#files-open-search-btn'
selector: '.mobile-search-btn'
},
userMenuButton: {
selector: '#_userMenuButton'
Expand Down

0 comments on commit 468abaf

Please sign in to comment.