The behavior of Quasar's q-drawer is quite unpredictable

Having made the transition from Vue.js 2 with Vuetify to Vue.js 3 with Quasar due to Vuetify not officially supporting Vue.js 3 yet, I am utilizing q-drawer and its mini property. This allows me to toggle between the mini state and the normal expanded state by clicking a button. However, I am encountering two issues:

  1. Starting in the mini state, expanding and returning back to the mini state causes the layout inside the q-drawer to change, resulting in a horizontal scrollbar being displayed even though there wasn't one initially. You can see an illustration of this behavior in the images below:

    No horizontal scrollbar prior to the first expansion: https://i.sstatic.net/eNN8p.png

    A horizontal scrollbar appears after expanding and switching back to the mini state: https://i.sstatic.net/4zBtH.png

    I attempted using the q-mini-drawer-hide class on the q-item-section intended to not be visible in the mini mode, but the content still ends up with a different width after expanding and minimizing again compared to the original width.

    Question:

    Is there a way to prevent the horizontal scrollbar from appearing while retaining the vertical scrolling functionality provided by q-scroll-area? Could there be an issue in my code that is causing the content to behave unexpectedly?

  2. The second issue pertains to the behavior of long texts within the q-drawer. Upon reloading the page with the drawer in its expanded state, the long text breaks into multiple lines, which is the desired outcome. However, when I minimize and expand the drawer again, the text reverts to a single line extending beyond the width of the q-drawer, despite the set width. The illustrations below demonstrate this:

    Long text displayed across multiple lines upon reloading with an expanded q-drawer: https://i.sstatic.net/Egke9.png

    After minifying and then expanding the q-drawer, the long text returns to a single line exceeding the set width of the component: https://i.sstatic.net/iarAC.png

    Question:

    How can I instruct the q-drawer component or a child component to consistently break the text into multiple lines? Or apply ellipsis to the text?

Sample code for replicating the issue:

<template>
  <q-layout view="hHh Lpr fff">
    <q-header elevated class="bg-primary text-white">
      <q-toolbar class="bg-black">
        <q-btn flat @click="toggleSidebar" round dense icon="mdi-menu" />
        <q-toolbar-title>
          A title
        </q-toolbar-title>
        <q-space></q-space>
        <q-btn flat round dense icon="mdi-dots-vertical"></q-btn>
      </q-toolbar>
    </q-header>

    <q-drawer show-if-above v-model="sidebar_open" side="left" elevated
      :mini="!sidebar_expanded"
      bordered
      :width="240"
      class="bg-grey-3">
      <q-scroll-area class="fit">
        <q-list>
          <q-item clickable v-ripple>
            <q-item-section avatar>
              <q-icon name="mdi-view-dashboard" />
            </q-item-section>
            <q-item-section class="q-mini-drawer-hide">Some text</q-item-section>
          </q-item>
          <q-item clickable v-ripple>
            <q-item-section avatar>
              <q-icon name="mdi-cube" />
            </q-item-section>
            <q-item-section class="q-mini-drawer-hide">Some other text</q-item-section>
          </q-item>
          <q-item clickable v-ripple>
            <q-item-section avatar>
              <q-icon name="mdi-clipboard-text" />
            </q-item-section>
            <q-item-section class="q-mini-drawer-hide">Some other other text</q-item-section>
          </q-item>
          <q-item clickable v-ripple>
            <q-item-section avatar>
              <q-icon name="mdi-cog" />
            </q-item-section>
            <q-item-section class="q-mini-drawer-hide">Some very very very very long text that should break</q-item-section>
          </q-item>
        </q-list>
      </q-scroll-area>
    </q-drawer>

    <q-page-container>
      <router-view />
    </q-page-container>

  </q-layout>
</template>

<script>
import { useStore } from 'vuex'
import { defineComponent, ref, computed } from 'vue'

export default defineComponent({

  setup() {
    //------------------------------------------------------------------------------------------------------------------
    // Basic setup
    //------------------------------------------------------------------------------------------------------------------
    const $store = useStore()

    const sidebar_open = ref(true)

    //------------------------------------------------------------------------------------------------------------------
    // Sidebar expansion functionality
    //------------------------------------------------------------------------------------------------------------------
    /**
     * The expansion state of the sidebar (true = expanded, false = mini)
     */
    const sidebar_expanded = computed({
      // For some reason, this needs to use the name of the store ('global' in this case) even with the namespacing disabled
      get() { return $store.state.global.sidebar_expanded },
      /** @param { boolean } value */
      set(value) { $store.dispatch('changeSidebarState', { expanded: value }) }
    })

    /**
     * Sets the sidebar expansion state to mini
     */
    const collapseSidebar = () => {
      sidebar_expanded.value = false
    }

    /**
     * Sets the sidebar expansion state to expanded
     */
    const expandSidebar = () => {
      sidebar_expanded.value = true
    }

    /**
     * Toggles the sidebar expansion state
     */
    const toggleSidebar = () => {
      if (sidebar_expanded.value) {
        collapseSidebar()
      } else {
        expandSidebar()
      }
    }

    return {
      sidebar_open,

      // Sidebar expansion functionality
      sidebar_expanded,
      toggleSidebar,
    }
  }
})
</script>

<style scoped>

</style>

Note: I have opted for the mdi-v5 icons as the default Quasar icons were exhibiting abnormal behavior.

Answer №1

Solving this problem is as simple as adjusting the CSS to control line breaks.

.content__section  { white-space: break-spaces; }

Alternatively, you can opt to maintain text on a single line with:

.content__section  { white-space: nowrap; }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dealing with AngularJS memory leaks caused by jQuery

How can I showcase a custom HTML on an AngularJS page using the given service? app.service('automaticFunctions', function ($timeout) { this.init = function initAutomaticFunctions(scope, $elem, attrs) { switch (scope.content.type) { ...

Steering clear of inserting 'Array' into a database through autocomplete using Js, Ajax, and Json

I'm currently working on a script that auto-populates input fields based on the autocomplete feature of the first input field. Although the script works fine and everything looks good when I hit submit, the problem arises when I check the database. A ...

vee-validate: Personalized Validation Messages

I am currently working with Laravel 5.8 and Vue.js. My query pertains to displaying a custom error message for a specific rule in the Vee-Validate library. I have set a custom message for the "required" rule, but it is not showing up correctly. Instead of ...

Error 403 occurs after submitting the form

Recently, I encountered a 403 error when attempting to submit the form on this page. Interestingly, when I directly accessed the new page by typing the URL into my browser, it loaded without any issues. The PHP code in the initial page looks like this: & ...

Show the output of a MySQL query on a modal, alert, or popup box within a webpage initiated by a search box, with the option to close the

Having worked in IT for 16 years, I am new to coding and seeking help on displaying search results from an input HTML box. I want the data from a MySQL database to be displayed in a modal, alert, or popup box with a closing "X" button. This database only c ...

Only when the user has successfully completed the reCAPTCHA and checked the checkbox, Vue will be able to

For my new project developed with VueJs, I am implementing a Single Page Application (SPA). The objective is to incorporate a simple if statement functionality. When the user checks a checkbox and successfully solves the reCaptcha, Vue should send an email ...

Stepping up Your Next.js Game with the Razorpay Payment Button Integration

When using the Razorpay payment button on a website, it provides a code snippet like this: <form> <script src = "https://cdn.razorpay.com/static/widget/payment-button.js" data-payment_button_id = "pl_FNmjTJSGXBYIfp" data ...

What naming convention do you recommend for mixin functions to ensure clarity and consistency?

In the past, I've struggled with locating where methods, computed values, and other components are defined when using multiple mixins. Is there a recommended standard practice for resolving this issue? One way to approach this problem is as follows: ...

Exploring Vuetify: Navigating Through Sub-Menus on a Drawer

My goal is to create a navigation drawer with expandable sub-menus for specific options. For example, the main menu option "User Profile" may have sub-menus like "Update Contact Details" and "Review Registration". I've experimented with different app ...

Transfer text from one form to a text field on a different website

I've created a form that allows users to input numbers in a field and then directs the page to a specific URL. Here's the code snippet: <html> <head> <meta charset="utf-8"> <title>Tracking</title> </head& ...

Asynchronous operations and recursive functions in the world of Node.js

When working with express and mongoose, I frequently find myself needing to perform batch operations on collections. However, the typical approach involves callbacks in nodejs concurrency coding, which can be cumbersome. // given a collection C var i = 0 ...

Unveiling the solution: Hide selected options in the input field of Material UI Autocomplete in React

I need help with not displaying the labels of selected options in the input field. I think it might be possible to do this using the renderInput property, but I'm not sure how. Even with the limitTags prop, the options still show up in the input field ...

Display or conceal a div depending on the selected radio button

I am attempting to display a hidden div based on the input of a radio button. If the "yes" option is checked, the hidden div should be shown. Conversely, if the "no" option is checked, the div should be hidden. I'm not sure why this code isn't w ...

Watch the video and follow along with your mouse using jQuery

Wouldn't it be cool to have a video play and follow your mouse pointer when you hover over the red box? And then once you move away, the video stops and disappears. Check out my progress so far: jsfiddle Here's the jQuery code I've used: $ ...

Utilize JavaScript to randomly choose images as background tiles in HTML

Currently, I am in the process of developing a game using HTML/CSS/JavaScript. My background is currently set to a single image (100px / 100px) being repeated vertically and horizontally to tile across the entire page body; CSS: body { background-ima ...

Notification system for managing recurring tasks

Situation I am currently working on an application where users are assigned daily tasks such as "wash the window, clean the floor," and so on. Each task has a specific recurrence interval and must be completed at least once within that time frame. For e ...

The role of providers in Angular applications

After creating a component and service in my project, I followed the documentation's instruction to include the service in the providers metadata of the component for injection. However, I found that it still works fine even without mentioning it in t ...

Is it better to utilize a sizable JavaScript file or opt for a compact one?

I recently created a JavaScript file with over 6000 lines of code for various sections of my website. I'm debating whether to keep it as one large file or break it up into smaller parts and call them in their respective sections. What do you think? ...

Error in Laravel: The source map for js/app.js could not be located, request failed with a status code 404

I recently started using laravel and keep encountering the following error message in the browser console: Source-Map-Error: request failed with status 404 Resource-Address: Source-Map-Address: popper.js.map I'm struggling to pinpoint the ...

Testing Vue components within a Rails application is a crucial step to ensuring

I have been working on creating Vue components using a different structure. Vue.component('my-component', { template: '<div>A totally unique component!</div>' }) Now, I am looking to test this with karma and jasmine or j ...