mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
Merge pull request #41638 from nextcloud/fix/41625-Replace_contacts-menu_search_and_unified-search_with_NcTextField
Replace input form with `NcTextField`
This commit is contained in:
commit
ca91eda240
6 changed files with 76 additions and 70 deletions
|
|
@ -29,13 +29,19 @@
|
|||
<Contacts :size="20" />
|
||||
</template>
|
||||
<div class="contactsmenu__menu">
|
||||
<label for="contactsmenu__menu__search">{{ t('core', 'Search contacts') }}</label>
|
||||
<input id="contactsmenu__menu__search"
|
||||
v-model="searchTerm"
|
||||
class="contactsmenu__menu__search"
|
||||
type="search"
|
||||
:placeholder="t('core', 'Search contacts …')"
|
||||
@input="onInputDebounced">
|
||||
<div class="contactsmenu__menu__input-wrapper">
|
||||
<NcTextField :value.sync="searchTerm"
|
||||
trailing-button-icon="close"
|
||||
ref="contactsMenuInput"
|
||||
:label="t('core', 'Search contacts')"
|
||||
:trailing-button-label="t('core','Reset search')"
|
||||
:show-trailing-button="searchTerm !== ''"
|
||||
:placeholder="t('core', 'Search contacts …')"
|
||||
id="contactsmenu__menu__search"
|
||||
class="contactsmenu__menu__search"
|
||||
@input="onInputDebounced"
|
||||
@trailing-button-click="onReset" />
|
||||
</div>
|
||||
<NcEmptyContent v-if="error" :name="t('core', 'Could not load your contacts')">
|
||||
<template #icon>
|
||||
<Magnify />
|
||||
|
|
@ -88,6 +94,7 @@ import { translate as t } from '@nextcloud/l10n'
|
|||
import Contact from '../components/ContactsMenu/Contact.vue'
|
||||
import logger from '../logger.js'
|
||||
import Nextcloud from '../mixins/Nextcloud.js'
|
||||
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
|
||||
|
||||
export default {
|
||||
name: 'ContactsMenu',
|
||||
|
|
@ -100,6 +107,7 @@ export default {
|
|||
NcEmptyContent,
|
||||
NcHeaderMenu,
|
||||
NcLoadingIcon,
|
||||
NcTextField,
|
||||
},
|
||||
|
||||
mixins: [Nextcloud],
|
||||
|
|
@ -152,17 +160,40 @@ export default {
|
|||
onInputDebounced: debounce(function() {
|
||||
this.getContacts(this.searchTerm)
|
||||
}, 500),
|
||||
|
||||
/**
|
||||
* Reset the search state
|
||||
*/
|
||||
onReset() {
|
||||
this.searchTerm = ''
|
||||
this.contacts = []
|
||||
this.focusInput()
|
||||
},
|
||||
|
||||
/**
|
||||
* Focus the search input on next tick
|
||||
*/
|
||||
focusInput() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.contactsMenuInput.focus()
|
||||
this.$refs.contactsMenuInput.select()
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.contactsmenu {
|
||||
overflow-y: hidden;
|
||||
|
||||
&__menu {
|
||||
/* show 2.5 to 4.5 entries depending on the screen height */
|
||||
height: calc(100vh - 50px * 3);
|
||||
max-height: calc(50px * 6 + 2px + 26px);
|
||||
min-height: calc(50px * 3.5);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: calc(50px * 6 + 2px + 26px);
|
||||
max-height: inherit;
|
||||
|
||||
label[for="contactsmenu__menu__search"] {
|
||||
font-weight: bold;
|
||||
|
|
@ -170,25 +201,22 @@ export default {
|
|||
margin-left: 13px;
|
||||
}
|
||||
|
||||
&__input-wrapper {
|
||||
padding: 10px;
|
||||
z-index: 2;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&__search {
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
margin: 8px 0;
|
||||
|
||||
&:focus,
|
||||
&:focus-visible,
|
||||
&:active {
|
||||
border-color: 2px solid var(--color-main-text) !important;
|
||||
box-shadow: 0 0 0 2px var(--color-main-background) !important;
|
||||
}
|
||||
margin-top: 0!important;
|
||||
}
|
||||
|
||||
&__content {
|
||||
/* fixed max height of the parent container without the search input */
|
||||
height: calc(100vh - 50px * 3 - 60px);
|
||||
max-height: calc(50px * 5);
|
||||
min-height: calc(50px * 3.5 - 50px);
|
||||
overflow-y: auto;
|
||||
margin-top: 10px;
|
||||
flex: 1 1 auto;
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -35,41 +35,22 @@
|
|||
|
||||
<!-- Search form & filters wrapper -->
|
||||
<div class="unified-search__input-wrapper">
|
||||
<label for="unified-search__input">{{ ariaLabel }}</label>
|
||||
<div class="unified-search__input-row">
|
||||
<form class="unified-search__form"
|
||||
role="search"
|
||||
:class="{'icon-loading-small': isLoading}"
|
||||
@submit.prevent.stop="onInputEnter"
|
||||
@reset.prevent.stop="onReset">
|
||||
<!-- Search input -->
|
||||
<input id="unified-search__input"
|
||||
ref="input"
|
||||
v-model="query"
|
||||
class="unified-search__form-input"
|
||||
type="search"
|
||||
:class="{'unified-search__form-input--with-reset': !!query}"
|
||||
:placeholder="t('core', 'Search {types} …', { types: typesNames.join(', ') })"
|
||||
aria-describedby="unified-search-desc"
|
||||
@input="onInputDebounced"
|
||||
@keypress.enter.prevent.stop="onInputEnter">
|
||||
<p id="unified-search-desc" class="hidden-visually">
|
||||
{{ t('core', 'Search starts once you start typing and results may be reached with the arrow keys') }}
|
||||
</p>
|
||||
|
||||
<!-- Reset search button -->
|
||||
<input v-if="!!query && !isLoading"
|
||||
type="reset"
|
||||
class="unified-search__form-reset icon-close"
|
||||
:aria-label="t('core','Reset search')"
|
||||
value="">
|
||||
|
||||
<input v-if="!!query && !isLoading && !enableLiveSearch"
|
||||
type="submit"
|
||||
class="unified-search__form-submit icon-confirm"
|
||||
:aria-label="t('core','Start search')"
|
||||
value="">
|
||||
</form>
|
||||
<NcTextField :value.sync="query"
|
||||
trailing-button-icon="close"
|
||||
:label="ariaLabel"
|
||||
ref="input"
|
||||
:trailing-button-label="t('core','Reset search')"
|
||||
:show-trailing-button="query !== ''"
|
||||
aria-describedby="unified-search-desc"
|
||||
class="unified-search__form-input"
|
||||
:class="{'unified-search__form-input--with-reset': !!query}"
|
||||
:placeholder="t('core', 'Search {types} …', { types: typesNames.join(', ') })"
|
||||
@trailing-button-click="onReset"
|
||||
@input="onInputDebounced" />
|
||||
<p id="unified-search-desc" class="hidden-visually">
|
||||
{{ t('core', 'Search starts once you start typing and results may be reached with the arrow keys') }}
|
||||
</p>
|
||||
|
||||
<!-- Search filters -->
|
||||
<NcActions v-if="availableFilters.length > 1"
|
||||
|
|
@ -152,6 +133,7 @@ import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
|
|||
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
|
||||
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
|
||||
import NcHeaderMenu from '@nextcloud/vue/dist/Components/NcHeaderMenu.js'
|
||||
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
|
||||
|
||||
import Magnify from 'vue-material-design-icons/Magnify.vue'
|
||||
|
||||
|
|
@ -175,6 +157,7 @@ export default {
|
|||
NcHeaderMenu,
|
||||
SearchResult,
|
||||
SearchResultPlaceholders,
|
||||
NcTextField,
|
||||
},
|
||||
|
||||
data() {
|
||||
|
|
@ -738,7 +721,7 @@ export default {
|
|||
|
||||
$margin: 10px;
|
||||
$input-height: 34px;
|
||||
$input-padding: 6px;
|
||||
$input-padding: 10px;
|
||||
|
||||
.unified-search {
|
||||
&__input-wrapper {
|
||||
|
|
@ -778,6 +761,7 @@ $input-padding: 6px;
|
|||
|
||||
&__filters {
|
||||
margin: $margin 0 $margin math.div($margin, 2);
|
||||
padding-top: 5px;
|
||||
ul {
|
||||
display: inline-flex;
|
||||
justify-content: space-between;
|
||||
|
|
@ -820,12 +804,6 @@ $input-padding: 6px;
|
|||
&::-webkit-search-results-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
// Ellipsis earlier if reset button is here
|
||||
.icon-loading-small &,
|
||||
&--with-reset {
|
||||
padding-right: $input-height;
|
||||
}
|
||||
}
|
||||
|
||||
&-reset, &-submit {
|
||||
|
|
|
|||
4
dist/core-main.js
vendored
4
dist/core-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-main.js.map
vendored
2
dist/core-main.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-unified-search.js
vendored
4
dist/core-unified-search.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-unified-search.js.map
vendored
2
dist/core-unified-search.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue