search

Home  >  Q&A  >  body text

How does MaterialUI do this?

<p>If you look at their autocomplete component: https://mui.com/material-ui/react-autocomplete/</p> <p>The input box retains focus after clicking on a suggestion in the dropdown...how do they do that? In every variant in my own vue app (not using material UI) I can't get the click event to prevent the input from losing focus. </p> <p>I've been trying to google this problem for a long time but haven't seen a clear solution. For example, people suggested mousedown/touchstart, but this breaks scrolling (by dragging the dropdown). MaterialUI apparently doesn't have this problem and doesn't seem to use mousedown. </p> <p>I tried analyzing the event using Chrome Dev Tools, but I can only see a single click event, but with the stripped down code it's hard to tell what's going on. </p> <p>Vuetify does this too: https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/components/VAutocomplete/VAutocomplete.ts</p> <p>If anyone has this problem, I also found this helpful https://codepen.io/Pineapple/pen/MWBVqGW</p> <p><strong>Edit</strong>This is what I'm doing: </p> <pre class="brush:html;toolbar:false;"> <app-input-autocomplete @autocomplete-select="onSelect" @autocomplete-close="onClose" :open="open"> <template #default="{ result }"> <div class="input-autocomplete-address"> {{ result.address }} </div> </template> </app-input-autocomplete> </pre> <p>Then in <code>app-input-autocomplete</code>: </p> <pre class="brush:html;toolbar:false;"><template> <app-input @focus="onFocus" @blur="onBlur" v-bind="$attrs"> <template #underInput> <div ref="dropdown" v-show="open" class="input-autocomplete-dropdown"> <div class="input-autocomplete-results"> <div v-for="result in results" :key="result.id" @click="onClick(result)" class="input-autocomplete-result"> <slot :result="result" /> </div> </div> </div> </template> </app-input> </template> <script> import { ref, toRef } from 'vue'; import AppInput from '@/components/AppInput.vue'; import { onClickOutside } from '@vueuse/core'; export default { components: { AppInput, }, inheritAttrs: false, props: { open: { type: Boolean, default: false, }, results: { type: Array, default: () => ([]), }, }, emits: ['autocomplete-close', 'autocomplete-select'], setup(props, { emit }) { const dropdown = ref(null); const open = toRef(props, 'open'); const focused = ref(false); onClickOutside(dropdown, () => { if (!focused.value && open.value) { emit('autocomplete-close'); } }); return { dropdown, focused, }; }, methods: { onFocus() { this.focused = true; }, onBlur() { this.focused = false; }, onClick(result) { this.$emit('autocomplete-select', result); }, }, }; </script> </pre></p>
P粉916760429P粉916760429472 days ago651

reply all(1)I'll reply

  • P粉994092873

    P粉9940928732023-09-05 12:04:13

    I solved this problem by doing the following, thanks to @Claies for the idea and this link:

    https://codepen.io/Pineapple/pen/MWBVqGW

    1. event.preventDefault on mousedown
    2. @click results behave as normal (input closed)
    3. @click/@focus input setopen = true
    4. @blur set open = false

    reply
    0
  • Cancelreply