This repository has been archived by the owner on May 25, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcontent.json
1 lines (1 loc) · 673 KB
/
content.json
1
[{"title":"","updated":"2018-05-09T14:34:08.328Z","permalink":"https://v0-16.quasar-framework.org/index.html","text":""},{"title":"","updated":"2018-05-09T14:34:08.328Z","permalink":"https://v0-16.quasar-framework.org/quasar-play-privacy-policy.html","text":""},{"title":"","updated":"2018-05-09T14:34:08.328Z","permalink":"https://v0-16.quasar-framework.org/support-quasar-framework.html","text":""},{"title":"Action Sheet","updated":"2018-05-18T22:01:01.000Z","permalink":"https://v0-16.quasar-framework.org/components/action-sheet.html","text":"Action Sheets slide up from the bottom edge of the device screen, and display a set of options with the ability to confirm or cancel an action. Action Sheets can sometimes be used as an alternative to menus, however, they should not be used for navigation. The Action Sheet always appears above any other components on the page, and must be dismissed in order to interact with the underlying content. When it is triggered, the rest of the page darkens to give more focus to the Action Sheet options. Action Sheets can be displayed as a list or as a grid, with icons or with avatars. They can be used either as a component in your Vue file templates, or as a globally available method. Basic Usage as a MethodFirst, we install it: Edit /quasar.conf.js:framework: { plugins: ['ActionSheet']} Now let’s see how we can use it:// outside of a Vue fileimport { ActionSheet } from 'quasar'(Promise) ActionSheet.create(configObj)// inside of a Vue file(Promise) this.$q.actionSheet(configObj) Basic syntax for the config object:this.$q.actionSheet({ title: 'Article Actions', // specify ONLY IF you want grid mode: grid: true, // optional; change dismiss label (only for iOS theme) dismissLabel: 'Quit', actions: [ { label: 'Delete', // Optional color: 'negative', // Choose one of the following two: icon: 'delete', // specify ONLY IF using icon avatar: 'assets/some-avatar.png', // specify ONLY IF using avatar // optional; what to do when user chooses this action; // Can also be handled later by using the returned Promise // and identifying the action from \"action\" param handler () { console.log('Deleted Article') } }, {}, // optional separator ... ]}) IMPORTANTWhen user hits the phone/tablet back button (only for Cordova apps), the Action Sheet will get closed automatically.Also, when on a desktop browser, hitting the <ESCAPE> key also closes the Action Sheet. Handling OutcomeThe returning object when creating an ActionSheet is a Promise, so you can leverage the Promise API to handle the outcome: this.$q.actionSheet({...}) .then(action => { // user picked an action console.log(action) // { label: 'Joe', ... } }) .catch(() => { // user dismissed Action Sheet })// OR with async/await:async showActionSheet () { try { const action = await this.$q.actionSheet({...}) // user picked an action at this point console.log(action) // { label: 'Joe', ... } } catch () { // user dismissed Action Sheet }} Basic Usage As a ComponentFirst, we install it: Edit /quasar.conf.js:framework: { components: ['QActionSheet']} Now let’s see how we can use it:<template> <q-action-sheet v-model=\"actionSheet\" title=\"Action Sheet\" @ok=\"onOk\" @cancel=\"onCancel\" @show=\"onShow\" @hide=\"onHide\" :actions=\"[ { label: 'Delete', icon: 'delete', color: 'red', handler: deleteAction }, { label: 'Share', icon: 'share', color: 'primary' }, // optional separator {}, // continuing with other actions { label: 'Play', icon: 'gamepad' }, { label: 'Favorite', icon: 'favorite' } ]\" /> <!-- there's an optional \"title\" slot if you have something very specific for the ActionSheet title (it replaces \"title\" prop) --></template><script>export default { data () { // model for QActionSheet example return { actionSheet: false } }, methods: { // custom handler for one of the actions deleteAction () { // @ok event will still be triggered this.$q.notify('Deleting...') }, // user picked one of the actions onOk (item) { if (item.handler) { // if we've already triggered a handler return } this.$q.notify({ color: 'secondary', message: `Clicked on \"${item.label}\"` }) }, // user dismissed ActionSheet onCancel () { this.$q.notify({ color: 'tertiary', icon: 'done', message: 'Action Sheet was dismissed' }) }, // when we show it to the user onShow () { }, // when it gets hidden onHide () { } }}</script> QActionSheet Vue Properties Vue Property Type Required Description actions Array of Objects yes Defining ActionSheet actions title String Title of Action Sheet. grid Boolean Makes it a “tag” type. dismiss-label String Override default i18n “Cancel” label (for iOS theme only) QActionSheet Vue Events Vue Property Description @ok(action) User picked an action. @cancel User dismissed ActionSheet. @show ActionSheet has just been showed to the user. @hide ActionSheet has been hidden (regardless of outcome). @escape-key ActionSheet dismissed with ESCAPE key."},{"title":"Ajax Bar","updated":"2018-07-23T16:37:49.828Z","permalink":"https://v0-16.quasar-framework.org/components/ajax-bar.html","text":"Ajax Bar is a component which displays a loading bar (like Youtube) whenever an Ajax call (regardless of Ajax library used) is in progress. It can be manually triggered as well. InstallationEdit /quasar.conf.js:framework: { components: ['QAjaxBar']} Basic UsageAs long as this component is rendered by Vue it will capture all Ajax calls.<q-ajax-bar /> Best way is to place it in your App root component (App.vue if you are using the default Quasar template):<template> <div id=\"q-app\"> <router-view></router-view> <q-ajax-bar /> </div></template> IMPORTANTDo not simultaneously use more than one Ajax Bar component in your App. Vue Properties Vue Property Type Default Value Description position String ‘top’ Where to place the loading bar: ‘top’, ‘bottom’, ‘left’ or ‘right’. size String ‘4px’ Thickness of loading bar. color String ‘red’ One from Quasar Color Palette. speed Number 250 How fast should loading bar update its value (in milliseconds). delay Number 1000 How much should loading bar wait before showing loading bar after it’s triggered (in milliseconds). reverse Boolean false Reverse direction of loading bar. Vue MethodsOnly if you want to also trigger it manually. Ajax calls trigger these methods automatically. Vue Method Description start() Trigger loading bar. stop() Notify one event has finished. Vue Events Vue Event Description @start Triggered when loading bar has been triggered to be displayed. @stop Triggered when loading bar finished its work and goes hidden. If multiple events are captured by Ajax Bar simultaneously, @start and @stop will still be triggered only once: when loading bar starts showing up and when it goes hidden. How start/stop worksEach Ajax call makes a start() call when it is triggered. When it ends, it calls stop(). So yes, if you also manually trigger Ajax Bar you must call start() each time a new event is starting and stop() each time an event finished. Ajax Bar knows to handle multiple events simultaneously."},{"title":"Mobile Addressbar Coloring","updated":"2018-05-18T22:01:01.000Z","permalink":"https://v0-16.quasar-framework.org/components/addressbar-color.html","text":"Newer mobile browsers have the ability to specify a color for the addressbar, like in the example below. Note 1. There isn’t yet a Web standard for this so it won’t work for all mobile browsers.Note 2. This applies when building a website only. For coloring top bar on a mobile app (built with Cordova wrapper), please refer to Cordova plugins. Basic UsageFirst, we need to indicate that we want the AddressbarColor Quasar plugin embedded into our website/app: // file: /quasar.conf.jsframework: { plugins: ['AddressbarColor']} Then we create an app plugin to initialize its usage: quasar new plugin addressbar-color. A file is created (/src/plugins/addressbar-color.js). We edit it: import { AddressbarColor } from 'quasar'export default () => { AddressbarColor.set('#a2e3fa')} What this does is that it injects some <meta> tags into your index.html at runtime. This means, as an example, that you can dynamically change this color during runtime multiple times, based on the page the user is on (by calling set method on created() lifecycle hook on the respective pages): // a .vue file representing a pageexport default { // ..., created () { this.$q.addressbarColor.set('#a2e3fa') }} Calling set() with no parameters will use the primary color."},{"title":"","updated":"2018-05-09T14:34:08.654Z","permalink":"https://v0-16.quasar-framework.org/blog/index.html","text":""},{"title":"Animation CSS Helper Classes","updated":"2018-05-18T22:01:01.001Z","permalink":"https://v0-16.quasar-framework.org/components/animation-css-helper-classes.html","text":"Add these CSS classes to the DOM element / component you want the effect on.These are very basic effects so for advanced ones check Transition, Slide Transition or use JS Animations. Class Name Description animate-pop Apply a pop-in effect to the DOM element animate-scale Apply a scale-in effect to the DOM element animate-fade Apply a fade-in effect to the DOM element animate-spin Apply a continuous spin/rotation to the DOM element animate-spin-reverse Apply a continuous spin/rotation (opposite direction to animate-spin) to the DOM element animate-blink Apply a continuous blinking effect to the DOM element animate-bounce Apply a continuous bouncing effect to the DOM element"},{"title":"Fullscreen","updated":"2018-05-18T22:01:01.001Z","permalink":"https://v0-16.quasar-framework.org/components/app-fullscreen.html","text":"There are times when you want your website or App to run in fullscreen.Quasar makes it easy by wrapping the Web Fullscreen API. Please note that the behavior is different depending on the platform the code is running on, due to the fact that there isn’t a fixed Web standard for Web Fullscreen API yet. InstallationEdit /quasar.conf.js:framework: { plugins: ['AppFullscreen']} Basic Usage// outside of a Vue fileimport { AppFullscreen } from 'quasar'// determine if platform has Fullscreen capability:(Boolean) AppFullscreen.isCapable// Determining if website is in fullscreen mode:(Boolean) AppFullscreen.isActive// Requesting fullscreen mode:AppFullscreen.request()// Exiting fullscreen mode:AppFullscreen.exit()// Toggle fullscreen mode:AppFullscreen.toggle() // inside of a Vue file// determine if platform has Fullscreen capability:(Boolean) this.$q.fullscreen.isCapable// Determining if website is in fullscreen mode:(Boolean) this.$q.fullscreen.isActive// Requesting fullscreen mode:this.$q.fullscreen.request()// Exiting fullscreen mode:this.$q.fullscreen.exit()// Toggle fullscreen mode:this.$q.fullscreen.toggle() ExampleWatching for fullscreen changes: // vue file<template>...</template><script>export default { watch: { '$q.fullscreen.isActive' (val) { console.log(val ? 'In fullscreen now' : 'Exited fullscreen') } }}</script>"},{"title":"Autocomplete","updated":"2018-07-23T16:37:49.828Z","permalink":"https://v0-16.quasar-framework.org/components/autocomplete.html","text":"The Quasar Autocomplete component binds to the parent textfield (eg. QInput, QSearch, QChipsInput) and offers suggestions to the user, while the user is typing. The suggestions offered to the user are based on either a static list of results or on an asynchronous function call (eg. containing an Ajax request). InstallationEdit /quasar.conf.js:framework: { components: ['QAutocomplete']} Basic UsageAs long as this component is rendered by Vue, it will capture all Ajax calls.<!-- Binds to parent QInput --><q-input color=\"amber\" v-model=\"terms\" placeholder=\"Type 'fre'\"> <q-autocomplete @search=\"search\" :min-characters=\"3\" @selected=\"selected\" /></q-input><!-- Binds to parent QSearch --><q-search v-model=\"terms\" placeholder=\"Start typing a country name\"> <q-autocomplete @search=\"search\" @selected=\"selected\" /></q-search><!-- Adds a separator between results --><q-search v-model=\"terms\"> <q-autocomplete separator @search=\"search\" @selected=\"selected\" /></q-search><!-- Binds to parent QChipsInput --><q-chips-input v-model=\"terms\" placeholder=\"Start typing a country name\"> <q-autocomplete @search=\"search\" @selected=\"selected\" /></q-chips-input> Vue Properties Vue Property Type Default Value Description min-characters Number 1 How many minimum characters can trigger component to suggest something? max-results Number 6 How many results can we display at a time? static-data Object None Use static suggestions. No need to do an Ajax call. Filtering is provided by Autocomplete component. filter Function Internal implementation If provided, autocomplete will perform custom filtering. debounce Number 500 Time in milliseconds, between key presses and finding new results. Good for delay, if using AJAX requests. separator Boolean false If set to true, it ads a delimeter between the values to select from. Vue MethodsNo need to trigger these methods manually as they are invoked automatically. Only use them when your use-case is something very specific. Vue Method Description trigger() Trigger suggestions (parent textfield must be focused). hide() Hide suggestions Popover. setValue() Set textfield string to the value supplied. Vue Events Vue Event Description @search(terms, Function done) Triggered by the component when a search should start and offer some results. @selected(item) Triggered when user has selected a suggestion. @show Triggered when the selections popup opens. @hide Triggered when selections popup closes. Example for search event: function search (terms, done) { // do something with terms, like an Ajax call for example // then call done(Array results) // DO NOT forget to call done! When no results or an error occured, // just call with empty array as param. Example: done([])} Using Static DataWhen using static data, specify an Object (notice that it uses some properties from List and List Items components:// static-data{ // Property name that will be used by filter() to filter the array of objects below. field: 'value', list: [ { value: 'Romania', // The value given, when selected label: 'Romania', // The value displayed as main label for this suggested selection sublabel: 'Continent: Europe', // optional icon: 'location_city', // optional stamp: '18 mil', // optional ... }, ... ]} Here is the full list of properties that can be used: Property Type Description leftColor String Color for left side from Quasar Color Palette. icon String Icon on the left to use. avatar String URL pointing to statics for an avatar. letter String One character String. leftInverted Boolean Invert mode, but only for icon and letter. leftTextColor String Override default “white” text-color when using an icon or letter only. image String URL pointing to statics for an image. label String Main label of the selection. sublabel String Sub-label of the selection. labelLines String/Number Number of lines that label can expand to. sublabelLines String/Number Number of lines that the sublabel can expand to. inset Boolean Inset Label if no left-side is specified (no icon, avatar, letter or image). rightColor String Color for right side from Quasar Color Palette. rightIcon String Icon on the right to use. rightAvatar String URL pointing to statics for an avatar on right side. rightLetter String One character String for right side. rightImage String URL pointing to statics for an image on right side. rightInverted Boolean Invert mode, but only for icon and letter. rightTextColor String Override default “white” text-color when using an icon or letter only. stamp String Stamp to use for right side. Example: ‘10 min ago’. <template> <q-search inverted color=\"secondary\" v-model=\"terms\" placeholder=\"Featuring static data\"> <q-autocomplete :static-data=\"{field: 'value', list: countries}\" @selected=\"selected\" /> </q-search></template><script>import countries from 'countries.json'// See above for the data format for the array of objects with required and optional dataexport default { data () { return { terms: '', countries } }}</script> Custom FilterTo perform custom filtering like fuzzy search, provide an optional function with following signature: <template> <q-search v-model=\"terms\"> <!-- Provide custom filter function --> <q-autocomplete :filter=\"myFilter\" @search=\"search\" @selected=\"selected\" /> </q-search></template><script>// fuzzysearch (needle, haystack) { return true|false }export default { ..., methods: { myFilter(terms, { field, list }) { const token = terms.toLowerCase(); return list.filter(item => fuzzysearch(token, item[field].toLowerCase())); } }}</script> Using Asynchronous Method (Ajax call?)If you’d like to call up data from the server, you may also do so with the following usage of search() method. <template> <q-search v-model=\"terms\" placeholder=\"Start typing a country name\"> <q-autocomplete @search=\"search\" @selected=\"selected\" /> </q-search></template><script>export default { ... methods: { search (terms, done) { // make an AJAX call // then call done(Array results) // DO NOT forget to call done! When no results or an error occurred, // just call with empty array as param. Example: done([]) } }, ...}</script>"},{"title":"Back to Top","updated":"2018-05-18T22:01:01.002Z","permalink":"https://v0-16.quasar-framework.org/components/back-to-top.html","text":"This is actually a directive and not a component. It allows to make visible any DOM elements (like buttons) which appear after a certain scroll offset. When clicked/tapped they take the user to the top of the page. InstallationEdit /quasar.conf.js:framework: { directives: ['BackToTop']} Basic Usage<!-- Bare bones example --><q-btn v-back-to-top round color=\"teal-5\" class=\"fixed-bottom-right\" style=\"margin: 0 15px 15px 0\"> <q-icon name=\"keyboard_arrow_up\" /></q-btn><!-- With animation, custom scroll offset (after which button is visible) and animation duration. Use \"animate-*\" CSS classes for effects when buttons/elements become visible. In this case, we'll use \"animate-pop\":--><q-btn v-back-to-top.animate=\"{offset: 500, duration: 200}\" round color=\"primary\" class=\"fixed-bottom-right animate-pop\" style=\"margin: 0 15px 15px 0\"> <q-icon name=\"keyboard_arrow_up\" /></q-btn> When using a Layout then you can take advantage of the Fixed Positioning on Layout component too and wrap your element with it, like this: <q-page-sticky position=\"top-right\" :offset=\"[18, 18]\"> <q-btn v-back-to-top round color=\"primary\" @click=\"alert\" icon=\"keyboard_arrow_up\" /></q-page-sticky> Vue Modifiers Vue Modifier Description animate Adds scrolling animation Vue Binding ValueYou can use the binding value in 3 forms: No value. Defaults will apply. As a Number. This will be the scroll offset after which DOM element will be made visible. As an Object with offset and/or duration as props. Duration is ignored if animate modifier is not used. Determining Scrolling ContainerPlease read here about how Quasar determines the container to attach scrolling events to."},{"title":"Alert","updated":"2018-05-18T22:01:01.001Z","permalink":"https://v0-16.quasar-framework.org/components/alert.html","text":"QAlert is a component that allows you to display an informational message to the users, with optional action buttons. InstallationEdit /quasar.conf.js:framework: { components: ['QAlert']} Basic Usage<q-alert color=\"primary\"> Some cool message</q-alert><q-alert type=\"positive\" icon=\"cloud\" :actions=\"[{label: 'Snooze', handler () {}}]\"> Some cool message for your users.</q-alert> As a tip, you can also add an animation to it. Make sure you specify the animation in /quasar.conf.js.<transition enter-active-class=\"animated bounceInLeft\" leave-active-class=\"animated bounceOutRight\" appear> <q-alert v-if=\"visible\" color=\"secondary\" icon=\"cloud\" appear :actions=\"[{ label: 'Dismiss', handler: () => { visible = false } }]\" class=\"q-mb-sm\" > Lorem ipsum dolor sit amet. </q-alert></transition> Vue PropertiesHere are the available properties, when using Alert as a component: Property Type Description type String One of ‘positive’, ‘negative’, ‘warning’, ‘info’. Applies the respective color and icon, so you can skip specifying those props too. color String This can be any color set up under the Quasar Color Palette. text-color String This can be any color (for the text) set up under the Quasar Color Palette. message String Alert’s content message, if you don’t add it as a children of QAlert. detail String Alert’s sub-message, as a detail. icon String Icon to use. See Icons. avatar String Image file (use statics folder for it). actions Array of Objects Place one or more buttons within the alert, like “Snooze” or “Abort”. Each Object from Array must have label (String) and handler (Function) props."},{"title":"Button Group","updated":"2018-07-23T16:37:49.829Z","permalink":"https://v0-16.quasar-framework.org/components/button-group.html","text":"You can conveniently group QBtn and QBtnDropdown using QBtnGroup. Be sure to check those component’s respective pages to see their props and methods. InstallationEdit /quasar.conf.js:framework: { components: [ 'QBtnGroup', 'QBtn', // if using QBtn 'QBtnDropdown' // if using QBtnDropdown ]} Basic usageSimple group of three buttons:<q-btn-group> <q-btn label=\"One\" @click=\"clickHandler1\"/> <q-btn label=\"Two\" @click=\"clickHandler2\"/> <q-btn label=\"Three\" @click=\"clickHandler3\"/></q-btn-group> Simple group of three push buttons:<q-btn-group push> <q-btn push label=\"One\" @click=\"clickHandler1\" /> <q-btn push label=\"Two\" @click=\"clickHandler2\" /> <q-btn push label=\"Three\" @click=\"clickHandler3\" /></q-btn-group> Simple group of three outlined buttons:<q-btn-group outline> <q-btn outline label=\"One\" @click=\"clicHandler1\" /> <q-btn outline label=\"Two\" @click=\"clicHandler2\" /> <q-btn outline label=\"Three\" @click=\"clicHandler3\" /></q-btn-group> Vue Properties Vue Property Type Description outline Boolean Set true, if you want an outlined button. flat Boolean Set true, if you want a flat button. push Boolean Set true, if the button should have a push effect. rounded Boolean Set true, if the square button should have rounded corners. You must use these props on both the parent QBtnGroup and the children QBtn/QBtnDropdown. More examplesSimple group of three rounded buttons<q-btn-group rounded> <q-btn rounded label=\"One\" @click=\"clickHandler1\" /> <q-btn rounded label=\"Two\" @click=\"clickHandler2\" /> <q-btn rounded label=\"Three\" @click=\"clickHandler3\" /></q-btn-group> Simple group of three flat buttons<q-btn-group flat> <q-btn flat label=\"One\" @click=\"clickHandler1\" /> <q-btn flat label=\"Two\" @click=\"clickHandler2\" /> <q-btn flat label=\"Three\" @click=\"clickHandler3\" /></q-btn-group> Simple group of two rounded buttons and one rounded dropdown button:<q-btn-group rounded> <q-btn rounded color=\"primary\" label=\"One\" /> <q-btn rounded color=\"primary\" label=\"Two\" /> <q-btn-dropdown rounded color=\"primary\" label=\"Three\" split> <!-- dropdown content goes here --> <q-list link> <q-item v-close-overlay> <q-item-side icon=\"folder\" inverted color=\"primary\" /> <q-item-main> <q-item-tile label>Photos</q-item-tile> <q-item-tile sublabel>February 22, 2016</q-item-tile> </q-item-main> <q-item-side right icon=\"info\" color=\"amber\" /> </q-item> <q-item-separator inset /> <q-list-header inset>Files</q-list-header> <q-item v-close-overlay> <q-item-side icon=\"assignment\" inverted /> <q-item-main> <q-item-tile label>Vacation</q-item-tile> <q-item-tile sublabel>February 22, 2016</q-item-tile> </q-item-main> <q-item-side right icon=\"info\" color=\"amber\" /> </q-item> </q-list> </q-btn-dropdown></q-btn-group>"},{"title":"Button Toggle","updated":"2018-07-23T16:37:49.829Z","permalink":"https://v0-16.quasar-framework.org/components/button-toggle.html","text":"The QBtnToggle component is another basic element for user input, similar to QRadio but with buttons. You can use this to supply a way for the user to pick an option from multiple choices. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QBtnToggle']} Basic Usage<!-- Three choices for the user --><q-btn-toggle v-model=\"model\" toggle-color=\"primary\" :options=\"[ {label: 'One', value: 'one'}, {label: 'Two', value: 'two'}, {label: 'Three', value: 'three'} ]\"/> Vue PropertiesSupports v-model which should be binded to a String in your scope. Choosing one option (clicking/tapping on a radio) makes your v-model change to Radio’s val. Vue Property Type Description options Array An array of objects with value and label properties. The binary components will be created according to this array. readonly Boolean Set to true, to make the radio read-only. disable Boolean Set to true, to disable the radio. dense Boolean Dense Buttons. outline Boolean Set true, if you want an outlined button. flat Boolean Set true, if you want a flat button. push Boolean Set true, if the button should have a push effect. rounded Boolean Set true, if the square button should have rounded corners. glossy Boolean Set true, if the button should be glossy. no-wrap Boolean Prevent text wrapping no-caps Boolean Set true, if you don’t want button content/label to be transformed to uppercase letter on Material Theme. no-ripple Boolean Disable Material Ripple. Mat theme only. wait-for-ripple Boolean Wait for ripple then before emitting @click event. Mat theme only. Color PropertiesAll can take values from Quasar Color Palette. Vue Property Type Description color String Color of buttons. text-color String Optional color of buttons label/icon. toggle-color String Color for button representing the current selection. toggle-text-color String Optional color for button label/icon representing the current selection. Options ConfigurationThe options property must be an Array of Objects with this structure:{ // required; the model gets this value when button is selected: value: ..., // include at least one of the following three props: label: '...', // Label for button icon: '...', // Icon for button iconRight: '...', // Icon for button on right side // Optional properties that override the QBtnToggle props: disable, color, textColor, toggleColor, toggleTextColor, noCaps, noWrap, noRipple, waitForRipple, tabindex} Vue Events Vue Event Description @input Triggered when it gets selected."},{"title":"Button","updated":"2018-07-23T16:37:49.829Z","permalink":"https://v0-16.quasar-framework.org/components/button.html","text":"Quasar has a component called QBtn which is a button with a few extra useful features. For instance, it comes in two shapes: rectangle (default) and round. It also has the material ripple effect by default when building with Material theme. The button component also comes with a spinner or loading effect. You would use this for times when app execution may cause a delay and you want to give the user some feedback about that delay. When used, the button will display a spinning animation as soon as the user clicks the button. When not disabled or spinning, QBtn emits a @click event, as soon as it is clicked or tapped. InstallationEdit /quasar.conf.js:framework: { components: ['QBtn']} Basic Usage<!-- Just label --><q-btn label=\"New item\" /><!-- Just icon --><q-btn icon=\"map\" /><!-- Icon & Label --><q-btn icon=\"create\" label=\"New item\" /> A standard round button.<!-- Notice \"round\" specified and self-closing tag (as we don't need to specify any content for button -- the icon fills all available space anyway). The label is discarded.--><q-btn round color=\"secondary\" icon=\"card_giftcard\" /><!-- Next is perfectly equivalent, but use \"icon\" property whenever you can.--><q-btn round color=\"secondary\"> <q-icon name=\"card_giftcard\" /></q-btn> IMPORTANTFor round buttons, only use an icon as content, through “icon” property or QIcon component as the only child. Do not add anything else besides the icon, unless you want a Popover or Tooltip. Primary colored button of small size: <q-btn color=\"primary\" size=\"sm\" label=\"Edit\"/> Button with “loading” state (we’ll go over these in more detail in its own section later): <!-- Regular shaped --><q-btn loading color=\"primary\" @click=\"clickMethod\" label=\"Button Label\"/> <template> <!-- Round shaped (only use icon or spinner as content!) with loading state --> <q-btn :loading=\"loading\" round icon=\"map\" color=\"primary\" @click=\"handler\" > <q-spinner-oval slot=\"loading\" /> </q-btn></template><script>export default { data () { return { loading: false } }, methods: { handler () { this.loading = true // we simulate a delay here: setTimeout(() => { this.loading = false }, 3000) } }}</script> Vue Properties Vue Property Type Description icon String Name of the icon to use. icon-right String Name of the icon to place on right side of button. loading Boolean Display a spinner, if true. Check Button with Progress. percentage Number Optional property for displaying a determinate progress. Use along loading. dark-percentage Boolean Optional property for displaying a determinate progress on a light button color. Use along loading and percentage. disable Boolean The button is disabled, if true. @click event won’t be triggered while in this state. label String/Number Button label. tabindex Number Set explicit tab index. repeat-timeout Number/Function Enables multiple @click events on click/tap and hold. Function gets a Number (timesTriggered) as parameter. wait-for-ripple Boolean Wait for ripple then before emitting @click event. Mat theme only. Router syntax sugar Vue Property Type Description to String/Object Makes button go to the indicated route when clicked. replace Boolean Replaces current route instead of pushing to window history. The properties above are just syntactic sugar and work similar to <router-link> Vue component. <q-btn label=\"Home\" to=\"/\" /><!-- equivalent to: --><q-btn label=\"Home\" @click=\"$router.push('/')\" /> Appearance Vue Property Type Description size String Button size. One of xs, sm, md, lg, xl, or a css string size eg. 25px, 2rem, 3vw. More info below this table. color String A color from Quasar Color Palette. text-color String A color from Quasar Color Palette. align String Label/Content alignment. One of left, center, right, around, between. dense Boolean Dense Button. round Boolean Set true, if you want a round button. outline Boolean Set true, if you want an outlined button. flat Boolean Set true, if you want a flat button. push Boolean Set true, if the button should have a push effect. rounded Boolean Set true, if the square button should have rounded corners. glossy Boolean Set true, if the button should be glossy. fab Boolean Floating Action Button. See fab-mini Boolean Smaller Floating Action Button. no-wrap Boolean Prevent text wrapping no-caps Boolean Set true, if you don’t want button content/label to be transformed to uppercase letter on Material Theme. no-ripple Boolean Disable Material Ripple. Mat theme only. Size property values: Size value Description xs, …, xl Predefined sizes form Same size as an input form component form-label Same size as an input form component with stack/float label form-hide-underline Same size as an input form component with no bottom border form-label-hide-underline Same size as an input form component with stack/float label and no bottom border form-inverted Same size as an inverted input form component form-label-inverted Same size as an inverted input form component with stack/float label Vue Events Vue Event Description @click Triggered on button click/tap, if button is not disabled. More examplesWhen adding an icon to a regular button, there are two possibilities for its position. The default position is left. Use icon-right property instead to position the icon to the right: <!-- icon will be placed on the left --><q-btn icon=\"mail\" color=\"primary\" label=\"Button Label\" /><!-- icon will be placed on the right --><q-btn icon-right=\"mail\" color=\"teal\" label=\"Button Label\" /><!-- icons will be placed on both sides --><q-btn icon=\"mail\" icon-right=\"mail\" color=\"teal\" label=\"Button Label\" /> Button SizesUse size attribute with one of the following values: xs, sm, md, lg, xl. You don’t need to specify md, because that’s the default size.<q-btn color=\"primary\" size=\"xs\" label=\"Extra Small Button\" /><q-btn color=\"primary\" size=\"sm\" label=\"Small Button\" /><q-btn color=\"primary\" size=\"md\" label=\"Medium Button\" /><q-btn color=\"primary\" size=\"lg\" label=\"Large Button\" /><q-btn color=\"primary\" size=\"xl\" label=\"Extra Large Button\" /> You can also use a CSS unit as size:<q-btn color=\"primary\" size=\"25px\" label=\"25 Pixels\" /><q-btn color=\"primary\" size=\"2rem\" label=\"2 Rem\" /><q-btn color=\"primary\" size=\"3vh\" label=\"3 View Height\" /> You can also make use of globally available CSS helper class block (sets CSS display property to block) or full-width to expand the button. Button ColorsUse any color from the Quasar Color Palette. Examples: primary, orange, lime, ‘amber-8’. <q-btn color=\"primary\" label=\"Primary Button\"/><q-btn color=\"amber\" label=\"Amber Button\"/><q-btn color=\"primary\" text-color=\"amber\" label=\"Primary Button with Amber text\" /> Button Style TypesThere are also the outline, push, round, flat, rounded and glossy props for you to use to control some design aspects of the button. <!-- an outlined button --><q-btn outline color=\"teal\" label=\"Outlined Button\" /><!-- a rounded push button --><q-btn rounded push color=\"secondary\" label=\"Rounded Push Button\"/><!-- a glossy button --><q-btn glossy color=\"primary\" label=\"Glossy\" /><!-- a flat dense round button --><q-btn flat dense round icon=\"menu\" color=\"primary\" /> Button with ProgressSome button actions involve contacting a server, so an asynchronous response. It’s best that you inform the user about a background process taking place until the asynchronous response is ready. QBtn offers this possibility through the loading prop. This property will display a QSpinner (by default) instead of the icon and/or label of the button. Custom loading content can also be used. Here is a full example highlighting what you can do with the loading property.<template> <!-- Notice `loading` prop --> <q-btn :loading=\"loading\" @click=\"simulateProgress\" label=\"Button Label\"> <!-- Notice slot=\"loading\". This is optional. If missing, the default theme spinner will be used. --> <span slot=\"loading\">Loading...</span> </q-btn></template><script>export default { data () { return { loading: false } }, methods: { simulateProgress () { // we set loading state this.loading = true // simulate a delay, like in // waiting for an Ajax call setTimeout(() => { // delay is over, now we reset loading state this.loading = false // DON't forget to reset loading state // otherwise the button will keep on // being in \"loading\" state }, 3000) } }}</script> If you’d like to add a different spinner than the default one of the theme you are building your website/app with, you can do so by slotting in the Spinner component that you’d like. <q-btn icon=\"mail\" label=\"Get Mail\" color=\"orange\" @click=\"simulateProgress\"> <q-spinner-facebook slot=\"loading\" size=\"20px\" /></q-btn> The “loading” slot can contain anything. It’s not limited to text or spinners only. You can use whatever DOM elements or components you want. The end result is that while in “loading” state, the Button content will be replaced by whatever the “loading” slot contains. Also, while in this state, the button gets disabled so no further click events are unnecessarily triggered. Handling Deterministic ProgressShould you wish, you can also display a deterministic progress within the button by using the additional “percentage” property along with what you’ve already learned about buttons with progress:<template> <q-btn :percentage=\"percentage\" :loading=\"loading\" label=\"Compute PI\" color=\"primary\" @click=\"startComputing\" > <span slot=\"loading\"> <q-spinner-gears class=\"on-left\" /> Computing... </span> </q-btn></template><script>// remember to also register necessary components in quasar.conf.jsexport default { data () { return { loading: false percentage: 0 } }, methods: { startComputing () { this.loading = true this.percentage = 0 // we simulate progress here this.interval = setInterval(() => { // adding a random amount of percentage this.percentage += Math.floor(Math.random() * 8 + 10) // and when we are done... if (this.percentage >= 100) { clearInterval(this.interval) // DON'T forget to reset loading state: this.loading = false } }, 700) } }, beforeDestroy () { // we also take care of clearing interval // should the user navigate away before the progress has ended clearInterval(this.interval) }}</script> You can also use the dark-percentage prop if your button has a light color. Controlling the Button for Form SubmissionWhen you have a button to submit a form’s input to the server, like a “Save” button, more often than not you will also want to give the user the ability to submit the form with a press of the enter key. If you would also like to give the user feedback of the saving process being in progress, and to prevent the user repeatedly pressing the button, you would need the button to show a loading spinner and be disabled from click events. QBtn allows this behavior if configured so. To control this loading feature, all you need is logic in your form which sets the v-model of the button to true. Once it is set to true, the button displays the spinner. To stop the process, set the v-model value back to false. The example below demonstrates this button control with the Enter key. <template> <div> <!-- a simple text field watching for the enter key release --> <q-input v-model=\"test\" @keyup.enter=\"simulateSubmit\" /> <!-- A button with v-model set to submit. v-model scope variable must be a strict Boolean --> <q-btn :loading=\"submitting\" @click=\"simulateSubmit\" label=\"Save\"> <q-spinner-facebook slot=\"loading\" /> </q-btn> </div></template><script>export default { data () { return { test: '', submitting: false } }, methods: { simulateSubmit () { this.submitting = true // Simulating a delay here. // When we are done, we reset \"submitting\" // Boolean to false to restore the // initial state. setTimeout(() => { // delay simulated, we are done, // now restoring submit to its initial state this.submitting = false }, 3000) } }}</script> Disabling a ButtonTo disable the button, use the disable prop. Along with a small fade applied to the Button, the @click event will no longer be triggered. <q-btn color=\"primary\" disable label=\"Primary Button\" /><q-btn color=\"amber\" :disable=\"booleanVar\" label=\"Amber Button\" /> Dealing with formsRequires Quasar v0.15.11+ Should you wish to use QBtn inside of a <form> tag, you should know about the difference between (type=”button”, which is implicit, and type=”submit”): <form> ... <q-btn label=\"I do not submit form\" /> <q-btn type=\"submit\" label=\"I do submit the form\" /> ...</form> Using a Button with Vue RouterIf you want to use a button to navigate to a new page you don’t need to use a wrapping <router-link> tag. Instead, you can use the @click event to handle the route change. <q-btn @click=\"$router.push('/path/to/new/page')\" color=\"primary\" label=\"navigate\"/> Delaying button click eventOn Material theme you can delay a button’s @click until the material ripple has reached the edge of the button using the wait-for-ripple prop. Useful from a UI perspective as an example when you want a button to dismiss a Modal. <q-btn wait-for-ripple @click=\"clickHandler\" label=\"Click Me\"/> Using a click and hold buttonIf you want to trigger a button’s @click event multiple times on click and hold use the repeat-timeout prop. Accepts either a Number or a Function (returning a Number). The Number represents the time amount to wait until triggering @click event again. <template> <!-- Click and hold to trigger every second --> <q-btn @click=\"clickHandler\" :repeat-timeout=\"1000\" label=\"Click Me\" /> <!-- Click and hold to trigger faster over time --> <q-btn @click=\"clickHandler\" :repeat-timeout=\"repeatFunction\" label=\"Click Me\" /></template><script> export default { methods: { clickHandler () { console.log('Handler Triggered') }, repeatFunction (timesTriggered) { // first time timesTriggered is 0, so we add 1 // to be sure we don't divide by 0 return 1000 / (timesTriggered + 1) } } }</script>"},{"title":"Cards","updated":"2018-07-23T16:37:49.830Z","permalink":"https://v0-16.quasar-framework.org/components/card.html","text":"Quasar Cards are a great way to display important pieces of content, and are quickly emerging as a core design pattern for Apps. They’re a great way to contain and organize information, while also setting up predictable expectations for the user. With so much content to display at once, and often so little screen real-estate, Cards have fast become the design pattern of choice for many companies, including the likes of Google and Twitter. Quasar Cards are a collection of components that you can use, based on the needs. It’s all about being creative. Experiment with different Web Components by embedding them in Card components to create awesome results. InstallationEdit /quasar.conf.js:framework: { components: [ 'QCard', 'QCardTitle', 'QCardMain', 'QCardMedia', 'QCardSeparator', 'QCardActions' ]} Basic UsageFamiliarize yourself with Card components with the examples below. The only requirement is that QCard needs to wrap all the other ones. Everything else is optional and can be inserted into your template anywhere as long as they are direct children of QCard. Following are Vue properties of QCard component: Vue Property Type Description square Boolean Squared borders instead of round ones. flat Boolean Remove shadow. inline Boolean Make it inline. Also set a CSS width to work. Take a look at Grid example on the “More Examples” section. color String One color from Quasar Color Palette. text-color String Override color of text, one from Quasar Color Palette. <!-- An basic example --><q-card> <q-card-title> Card Title </q-card-title> <q-card-separator /> <q-card-main> Card Content </q-card-main></q-card> A more complex example:<q-card inline style=\"width: 500px\"> <q-card-media> <img src=\"~assets/donuts.png\"> </q-card-media> <q-card-title> Cafe Basilico <q-rating slot=\"subtitle\" v-model=\"stars\" :max=\"5\" /> <div slot=\"right\" class=\"row items-center\"> <q-icon name=\"place\" /> 250 ft </div> </q-card-title> <q-card-main> <p>$・Italian, Cafe</p> <p class=\"text-faded\">Small plates, salads & sandwiches in an intimate setting.</p> </q-card-main> <q-card-separator /> <q-card-actions> <q-btn flat round dense icon=\"event\" /> <q-btn flat label=\"5:30PM\" /> <q-btn flat label=\"7:30PM\" /> <q-btn flat label=\"9:00PM\" /> <q-btn flat color=\"primary\" label=\"Reserve\" /> </q-card-actions></q-card> Card Title (QCardTitle)QCardTitle has three main areas (all are optional): title, subtitle (“subtitle” slot) and right side (“right” slot). Note that you can set title and subtitle as overlay on an image or video through a QCardMedia component too (see QCardMedia section). <q-card-title> <!-- Optional. Anything that goes here without specifying \"slot\" is considered the main title --> Title <!-- Optional. Adding the subtitle. Notice slot=\"subtitle\" --> <span slot=\"subtitle\">Subtitle</span> <!-- Optional. Adding something on the right side, like an icon triggering a Popover with a menu. Notice the slot=\"right\" --> <q-icon slot=\"right\" name=\"more_vert\"> <q-popover> <q-list link class=\"no-border\"> <q-item v-close-overlay> <q-item-main label=\"Remove Card\" /> </q-item> <q-item v-close-overlay> <q-item-main label=\"Send Feedback\" /> </q-item> <q-item v-close-overlay> <q-item-main label=\"Share\" /> </q-item> </q-list> </q-popover> </q-icon></q-card-title> Card Main Content (QCardMain)QCardMain defines an area containing the main Card content, like description, details or anything you need outside of the other Card component’s purpose. <q-card-main> Card main content.</q-card-main><q-card-main> <p>$・Italian, Cafe</p> <p class=\"text-faded\"> Small plates, salads & sandwiches in an intimate setting. </p></q-card-main> Card Actions (QCardActions)Cards can have some actions (buttons) attached to them. Vue Property Type Description vertical Boolean Stack actions vertically align String One of ‘start’, ‘center’, ‘end’, ‘around’, ‘between’ which aligns buttons in respect to the actions container <!-- Horizontal actions --><q-card-actions> <!-- Define the buttons to your liking, these are just examples --> <q-btn flat round dense icon=\"event\" /> <q-btn flat label=\"5:30PM\" /> <q-btn flat label=\"7:30PM\" /> <q-btn flat label=\"9:00PM\" /> <q-btn flat color=\"primary\" label=\"Reserve\" /></q-card-actions><!-- Vertical actions --><q-card-actions vertical> <q-btn flat label=\"Action 1\" /> <q-btn flat label=\"Action 2\" /></q-card-actions> Card Media (QCardMedia)Cards can also contain media elements: images, videos (through QVideo) or a parallax (through QParallax). This can be done through QCardMedia component, which supports an optional overlay too (for things like title and/or subtitle). Vue Property Type Description overlay-position String One of ‘top’, ‘bottom’ or ‘full’ which sets the position of overlay on top of media element. <!-- Displaying an image --><q-card-media> <img src=\"~assets/some-image.jpg\"></q-card-media><!-- Display a video (with help of QVideo component) --><q-card-media> <q-video src=\"https://www.youtube.com/embed/k3_tw44QsZQ?rel=0\" /></q-card-media><!-- Displaying a Parallax (with help of QParallax) --><q-card-media> <q-parallax :src=\"'statics/parallax1.jpg'\" :height=\"150\"> <div slot=\"loading\">Loading...</div> </q-parallax></q-card-media> Now let’s see how we can add overlays too (through “overlay” slot):<q-card-media> <img src=\"~assets/mountains.jpg\"> <!-- Notice the slot=\"overlay\" --> <q-card-title slot=\"overlay\"> Title <span slot=\"subtitle\">Subtitle</span> </q-card-title></q-card-media><!-- Overlay at top of media elements. Notice overlay-position=\"top\"--><q-card-media overlay-position=\"top\"> <img src=\"~assets/mountains.jpg\"> <!-- Notice the slot=\"overlay\" --> <q-card-title slot=\"overlay\"> Title <span slot=\"subtitle\">Subtitle</span> </q-card-title></q-card-media><!-- Overlay on full area of media elements Notice overlay-position=\"full\"--><q-card-media overlay-position=\"full\"> <img src=\"~assets/mountains.jpg\"> <!-- Notice the slot=\"overlay\" --> <q-card-title slot=\"overlay\"> Title <span slot=\"subtitle\">Subtitle</span> </q-card-title></q-card-media> Card Inner SeparatorYou can choose to add a separator between Card components, which is basically a horizontal thin line, by adding QCardSeparator: <q-card> <q-card-title> ... </q-card-title> <!-- Here is the separator --> <q-card-separator /> <q-card-actions> ... </q-card-actions></q-card> Some More ExamplesColoring CardsUse colors from Quasar Color Palette to set a color for your Cards. <q-card color=\"primary\"> ...</q-card><q-card color=\"amber-8\" text-color=\"black\"> ...</q-card> Lists on CardsPlace a QList with its QItems at root of your QCard, like this: <q-card> ... <q-list> <q-item> <q-item-side> <q-item-tile color=\"primary\" icon=\"local bar\" /> </q-item-side> <q-item-main> <q-item-tile label>Bar XYZ</q-item-tile> <q-item-tile sublabel>Have a drink.</q-item-tile> </q-item-main> </q-item> <q-item> <q-item-side> <q-item-tile color=\"red\" icon=\"local gas station\" /> </q-item-side> <q-item-main> <q-item-tile label>Gas Station</q-item-tile> <q-item-tile sublabel>Fill your gas tank.</q-item-tile> </q-item-main> </q-item> <q-item> <q-item-side> <q-item-tile color=\"amber\" icon=\"local movies\" /> </q-item-side> <q-item-main> <q-item-tile label>Cinema XYZ</q-item-tile> <q-item-tile sublabel>Watch a movie.</q-item-tile> </q-item-main> </q-item> </q-list> ...</q-card> There’s also the possibility to create a nice header for your Cards with an image / avatar, a person name and some quick details. In this example, we skip using QCardList: <q-card> <q-item> <q-item-side avatar=\"/statics/boy-avatar.png\" /> <q-item-main> <q-item-tile label>Title</q-item-tile> <q-item-tile sublabel>Subhead</q-item-tile> </q-item-main> </q-item></q-card> Making a Grid of CardsIn order to make a grid of Cards you need to use the inline property of QCard component and set a width for your Cards. <div> <!-- In this example every card has a \"style\" tag with a width. Consider defining a CSS class instead to ease the template syntax. --> <q-card inline style=\"width: 300px\">...</q-card> <q-card inline style=\"width: 300px\">...</q-card> <q-card inline style=\"width: 300px\">...</q-card> ... <q-card inline style=\"width: 300px\">...</q-card></div> Card with CollapsiblesSince Collapsibles are List items too, it makes sense to use a QList component to encapsulate them. Also, imagine a Card with Collapsibles containing Cards. Inception :) <q-card> <q-card-title> Card with Collapsible List </q-card-title> <q-card-separator /> <q-list> <q-collapsible icon=\"explore\" label=\"First\"> <div> Lorem ipsum dolor sit amet... </div> </q-collapsible> <q-collapsible icon=\"perm_identity\" label=\"Second\"> <div> Lorem ipsum dolor sit amet... </div> </q-collapsible> <q-collapsible icon=\"shopping_cart\" label=\"Third\"> <div> Lorem ipsum dolor sit amet... </div> </q-collapsible> </q-list></q-card>"},{"title":"App Visibility","updated":"2018-05-18T22:01:01.002Z","permalink":"https://v0-16.quasar-framework.org/components/app-visibility.html","text":"Quasar makes use of the Web Page Visibility API which lets you know when a website/app is visible or in focus. InstallationEdit /quasar.conf.js:framework: { plugins: ['AppVisibility']} Basic Usage// outside of a Vue fileimport { AppVisibility } from 'quasar'(Boolean) AppVisibility.appVisible// inside of a Vue file(Boolean) this.$q.appVisible ExampleWatching for browser tab / app visibility changes: // vue file<template>...</template><script>export default { watch: { '$q.appVisible' (val) { console.log(val ? 'App has focus now' : 'App lost focus (was minimized') } }}</script>"},{"title":"Carousel","updated":"2018-07-23T16:37:49.831Z","permalink":"https://v0-16.quasar-framework.org/components/carousel.html","text":"Quasar Carousel is a Vue Component which you can use to display more information with less real estate, using slides. Useful for creating Wizards too. The Carousel height is determined by the slide with biggest height, unless the height prop is used. InstallationEdit /quasar.conf.js:framework: { components: [ 'QCarousel', 'QCarouselSlide', 'QCarouselControl' ],} Basic UsageHere is a very basic example:<q-carousel class=\"text-white\"> <q-carousel-slide class=\"bg-primary\"> Slide 1 </q-carousel-slide> <q-carousel-slide class=\"bg-secondary\"> Slide 2 </q-carousel-slide> <q-carousel-slide class=\"bg-tertiary\"> Slide 3 </q-carousel-slide></q-carousel> QCarousel (Parent)QCarousel Vue PropertiesSupports v-model which determines the slide number. Vue Property Type Description color String One from Quasar Color Palette. It determines the color of the out of the box Carousel controls (arrows, quick nav). arrows Boolean Show navigation arrows. infinite Boolean Infinite slides scrolling. autoplay Boolean/Number Auto scrolls between slides. Works great along infinite prop (but infinite is not required). If used as a number, it represents the number of milliseconds between scrolls. quick-nav Boolean Shows navigational dots at bottom. quick-nav-icon String Icon to use instead of the navigational dots at bottom. no-swipe Boolean Disable navigation by touch/mouse actions. handle-arrow-keys Boolean Allow navigation with left and right arrow key. In this case, it’s best to render only one such Carousel at a time. easing Function Easing function used when changing slide from autoplay or button press. swipe-easing Function Easing function used when changing slide with a swipe. thumbnails Array (v0.15.11+) Array of thumbnails pointing to “statics” folder. Check examples. thumbnails-horizontal Boolean (v0.15.11+) Thumbnails get displayed horizontally. QCarousel Vue Methods Vue Method Description next() Goes to next slide. previous() Goes to previous slide. goToSlide(slideNumber) Go to the desired slide. slideNumber is 0-based. QCarousel Vue Events Vue Event Description @input(index) Emits the index of the current slide. @slide-trigger(oldIndex, newIndex, direction) Emitted before animating to the new slide. @slide(index, direction) Emits the index of the current slide and the direction of the slide after the transition animation finishes. Emits even if navigating to the same slide. @slide-direction('next'/'previous') Emitted when navigating to a slide, describing direction (next / previous). QCarouselSlide (Child) Vue Property Type Description img-src String An image from statics folder. Example: ‘statics/mountaings.png’. QCarouselControl (Child) Vue Property Type Description position String Position of the control: ‘top’, ‘top-right’, ‘top-left’, ‘bottom-right’, etc offset Array of 2 Numbers Offset on horizontal and vertical (in pixels). Example (default value): [18, 18]. ExamplesCarousel with a base color, Arrows, Quick Navigation, and slides with images<template> <q-carousel color=\"white\" arrows height=\"400px\" > <q-carousel-slide img-src=\"statics/mountains.jpg\"> <div class=\"absolute-bottom custom-caption\"> <div class=\"q-display-1\">First stop</div> <div class=\"q-headline\">Mountains</div> </div> </q-carousel-slide> <q-carousel-slide img-src=\"statics/parallax1.jpg\"> <div class=\"absolute-bottom custom-caption\"> <div class=\"q-display-1\">Second stop</div> <div class=\"q-headline\">Famous City</div> </div> </q-carousel-slide> <q-carousel-slide img-src=\"statics/parallax2.jpg\"> <div class=\"absolute-bottom custom-caption\"> <div class=\"q-display-1\">Third stop</div> <div class=\"q-headline\">Famous Bridge</div> </div> </q-carousel-slide> </q-carousel></template><style>.custom-caption { text-align: center; padding: 12px; color: $grey-4; background: rgba(0, 0, 0, 0.5);}</style> Carousel with image slides and thumbnails Requires Quasar v0.15.11+ <q-carousel color=\"white\" arrows quick-nav height=\"300px\" :thumbnails=\"[ 'statics/mountains.jpg', 'statics/parallax1.jpg', 'statics/parallax2.jpg' ]\"> <q-carousel-slide img-src=\"statics/mountains.jpg\" /> <q-carousel-slide img-src=\"statics/parallax1.jpg\" /> <q-carousel-slide img-src=\"statics/parallax2.jpg\" /></q-carousel> Horizontal thumbnails:<q-carousel :thumbnails=\"....\" thumbnails-horizontal> ...</q-carousel>### Infinite scroll, auto-play and custom Quick Navigation icon. Second slide has a Youtube video.Use `infinite` Vue prop.``` html<q-carousel color=\"white\" arrows quick-nav quick-nav-icon=\"favorite\" infinite autoplay height=\"300px\"> <q-carousel-slide img-src=\"statics/mountains.jpg\" /> <q-carousel-slide> <q-video class=\"absolute-full\" src=\"https://www.youtube.com/embed/k3_tw44QsZQ?rel=0\" /> </q-carousel-slide> <q-carousel-slide img-src=\"statics/parallax1.jpg\" /> <q-carousel-slide img-src=\"statics/parallax2.jpg\" /></q-carousel> Custom Quick Navigation and different type of slides contentThird slide has a Youtube video.<q-carousel color=\"white\" quick-nav height=\"300px\"> <q-carousel-slide class=\"text-white bg-primary row flex-center\"> <div class=\"q-display-2\">First Slide</div> </q-carousel-slide> <q-carousel-slide class=\"text-white bg-secondary row flex-center\"> <div class=\"q-display-2\">Second Slide</div> </q-carousel-slide> <q-carousel-slide class=\"text-white bg-primary\"> <div v-for=\"n in 7\" :key=\"`custom-${n}`\" class=\"q-ma-sm\"> {{ lorem }} </div> </q-carousel-slide> <q-carousel-slide img-src=\"statics/mountains.jpg\" /> <q-carousel-slide> <q-video class=\"absolute-full\" src=\"https://www.youtube.com/embed/k3_tw44QsZQ?rel=0\" /> </q-carousel-slide> <q-carousel-slide img-src=\"statics/parallax1.jpg\" /> <q-carousel-slide img-src=\"statics/parallax2.jpg\" /> <q-carousel-control slot=\"control-nav\" slot-scope=\"carousel\" :offset=\"[18, 52]\"> <q-btn @click=\"carousel.previous\" :disable=\"!carousel.canGoToPrevious\" color=\"amber\" text-color=\"black\" icon=\"keyboard_arrow_left\" round dense class=\"q-mr-small\" /> <q-btn @click=\"carousel.next\" :disable=\"!carousel.canGoToNext\" color=\"amber\" text-color=\"black\" icon=\"keyboard_arrow_right\" round dense /> </q-carousel-control> <q-btn slot=\"quick-nav\" slot-scope=\"props\" color=\"white\" flat dense :label=\"`${props.slide + 1}`\" @click=\"props.goToSlide()\" :class=\"{inactive: !props.current}\" /></q-carousel> Using v-model & some custom controls: autoplay button, progressbar, fullscreen toggleControlling from outside of Carousel:<q-btn rounded color=\"primary\" @click=\"slide = 1\" icon=\"arrow_downward\" label=\"Navigate to second slide\" class=\"q-ml-sm\"/><q-carousel v-model=\"slide\" color=\"amber\" quick-nav infinite :autoplay=\"autoplay\" height=\"400px\"> <q-carousel-slide v-for=\"n in 7\" :key=\"`car-${n}`\" class=\"flex flex-center\" :class=\"`bg-${colors[n % 5]}`\" > <div class=\"text-center\"> <div class=\"q-display-3\">Slide {{ n }}</div> <div>Slides can contain any content.</div> </div> </q-carousel-slide> <q-carousel-control slot=\"control\" position=\"top-right\" :offset=\"[18, 18]\" class=\"text-white\" style=\"background: rgba(0, 0, 0, .3); padding: 4px; border-radius: 4px\" > <q-toggle dark color=\"amber\" v-model=\"autoplay\" label=\"Auto Play\" /> </q-carousel-control> <q-carousel-control slot=\"control-button\" slot-scope=\"carousel\" position=\"bottom-right\" :offset=\"[18, 22]\" > <q-btn round dense push color=\"amber\" :icon=\"carousel.inFullscreen ? 'fullscreen_exit' : 'fullscreen'\" @click=\"carousel.toggleFullscreen()\" /> </q-carousel-control> <q-carousel-control slot=\"control-progress\" slot-scope=\"carousel\" position=\"bottom\" :offset=\"[42, 100]\"> <q-progress :percentage=\"carousel.percentage\" stripe color=\"amber\" :animate=\"autoplay\" /> </q-carousel-control></q-carousel> Custom easing animation.<template> <q-carousel class=\"text-white\" :easing=\"overshoot\" infinite autoplay arrows color=\"white\" height=\"250px\" > <q-carousel-slide v-for=\"n in 7\" :key=\"`anim-${n}`\" class=\"flex flex-center\" :class=\"`bg-${colors[n % 5]}`\" > <div class=\"q-display-3\">Slide {{ n }}</div> </q-carousel-slide> </q-carouse></template><script>import { easing } from 'quasar'// easing is a collection;// we're picking \"overshoot\" from itexport default { data () { return { overshoot: easing.overshoot } }}</script> Launching on FullscreenUseful for creating Wizards. <template> <div> <q-btn color=\"primary\" class=\"glossy\" @click=\"modal = true\"> Launch </q-btn> <q-modal v-model=\"modal\" maximized> <q-carousel color=\"white\" arrows quick-nav class=\"text-white full-height\" > <q-carousel-slide v-for=\"n in 7\" :key=\"`full-${n}`\" class=\"flex flex-center\" :class=\"`bg-${colors[n % 5]}`\" > <div class=\"q-display-3\">Step {{ n }}</div> </q-carousel-slide> <q-carousel-control slot=\"control-full\" slot-scope=\"carousel\" position=\"bottom-right\" :offset=\"[18, 22]\" > <q-btn rounded push color=\"amber\" icon=\"close\" label=\"Close me\" @click=\"modal = false\" /> </q-carousel-control> </q-carousel> </q-modal> </div></template><script>export default { data () { return { modal: false } }}</script>"},{"title":"Checkbox","updated":"2018-07-23T16:37:49.831Z","permalink":"https://v0-16.quasar-framework.org/components/checkbox.html","text":"The Quasar Checkbox component is a basic element to be used for selection or toggling by the user. It has a number of features, as described below. Please also refer to the Option Group documentation on other possibilities for creating groups of Toggles. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QCheckbox']} Basic Usage<!-- No label: --><q-checkbox v-model=\"checked\" /><!-- With a label --><q-checkbox v-model=\"checked\" label=\"Checkbox Label\" /><!-- Disabled: --><q-checkbox v-model=\"checked\" disable /> Vue PropertiesSupports v-model which should be binded to a Boolean or Array in your scope. Vue Property Type Description val Object Used to modify the v-model of the Checkbox when using an Array as v-model. true-value Any Gets into “true” state when model has this value. false-value Any Gets into “false” state when model has this value. indeterminate-value Any Gets into “indeterminate” state when model has this value. Default is null. toggle-indeterminate Boolean Toggle between 3 states, including “indeterminate”. label String The text label for the Checkbox. left-label Boolean Set to true, if the label should be placed to the left of the Checkbox. checked-icon String Optional icon to use, when the Checkbox is checked. unchecked-icon String Optional icon to use, when the Checkbox is not checked. indeterminate-icon String Optional icon to use, when the Checkbox is in indeterminate state. color String Color from Quasar Color Palette. keep-color Boolean Keep color when not truthy too. readonly Boolean Set to true, to make the checkbox read-only. disable Boolean Set to true, to disable the checkbox. dark Boolean Set to true when background is dark. Vue Events Vue Event Description @input Triggered when it changes model. @blur Triggered, when Checkbox loses focus. @focus Triggered, when Checkbox gains focus. Array as ModelIf you have a number of checkboxes for a selection, use an array as the model object and specify val property. <q-checkbox v-model=\"selection\" val=\"one\" label=\"One\" /><br><br><q-checkbox v-model=\"selection\" val=\"two\" label=\"Two\" /><br><br><q-checkbox v-model=\"selection\" val=\"three\" label=\"Three\" /> <script>export default { data () { return { selection: ['one', 'two', 'three'] } }}</script> Ticking all Checkboxes will make selection scope variable to be ['one', 'two', 'three']. Unticking all Checkboxes will result in selection being an empty array []. More ExamplesThere are a number of props, which are available to help quickly format a Checkbox. An interesting feature of Checkbox is the ripple effect that user gets when clicking/tapping on it to change its state. Custom Model ValuesInstead of the default true/false values, you can use custom ones:<q-checkbox v-model=\"customModel\" color=\"secondary\" label=\"Do you agree with the terms & conditions?\" true-value=\"yes\" false-value=\"no\"/> Specific IconsSometimes, you might need a checkbox simply as a type of button, to maybe turn something on or off. You can do this with the checked-icon and unchecked-icon props. <!-- a happy and unhappy smiley, maybe for a one-touch satisfaction feedback --><q-checkbox v-model=\"checked\" checked-icon=\"sentiment very satisfied\" unchecked-icon=\"sentiment very dissatisfied\"/><!-- an eye and a crossed out eye to indicate visibility --><q-checkbox v-model=\"checked\" checked-icon=\"visibility\" unchecked-icon=\"visibility_off\"/> ColoringUse the color prop to control the Checkbox color. <q-checkbox v-model=\"checked\" color=\"teal\" /><q-checkbox v-model=\"checked\" color=\"orange\" /><q-checkbox v-model=\"checked\" color=\"dark\" /> Label PositionUse the left-label prop, to move the label to the left of Checkbox. <q-checkbox v-model=\"checked\" color=\"teal\" left-label label=\"Checkbox Label\"/> Usage Inside of a ListIn the following example we use the Right side of QItems to insert Checkbox, but it works anywhere. <q-list link> <!-- Rendering a <label> tag (notice tag=\"label\") so the whole QItem will respond to clicks to change Checkbox state. --> <q-item tag=\"label\"> <q-item-side> <q-checkbox v-model=\"checked\" /> </q-item-side> <q-item-main> <q-item-tile label>Events and reminders</q-item-tile> </q-item-main> </q-item> <q-item tag=\"label\"> <q-item-side> <q-checkbox v-model=\"checked\" /> </q-item-side> <q-item-main> <q-item-tile label>Events and reminders</q-item-tile> <q-item-tile sublabel>Lorem ipsum</q-item-tile> </q-item-main> </q-item> <q-item tag=\"label\" multiline> <q-item-side> <q-checkbox v-model=\"checked\" /> </q-item-side> <q-item-main> <q-item-tile label>Events and reminders</q-item-tile> <q-item-tile sublabel>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</q-item-tile> </q-item-main> </q-item></q-list>"},{"title":"Chips Input","updated":"2018-07-23T16:37:49.833Z","permalink":"https://v0-16.quasar-framework.org/components/chips-input.html","text":"The Quasar Chips Input allows user to enter a group of text items, which is also editable in the form of quick deletion of the Chips in the list. For more details on Chips used within Chips Input, please refer to its documentation. For autocomplete functionality, also refer to QAutocomplete documentation. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QChipsInput']} Basic Usage<q-chips-input v-model=\"model\" /><!-- Disabled --><q-chips-input v-model=\"model\" disable /><!-- With floating label --><q-chips-input v-model=\"model\" float-label=\"Floating Label\" /><!-- With custom placeholder --><q-chips-input v-model=\"model\" placeholder=\"Type some names\" /><!-- On error state --><q-chips-input v-model=\"model\" error /> The model variable must be an Array. The user can remove a Chip by clicking/tapping on the close icon. Adding a Chip is done by clicking/tapping on the component, typing and then hitting the send icon or <ENTER> key. Pressing Backspace key either removes content of the textfield or if that is empty then the last Chip. Vue PropertiesSupports v-model which should be binded to an Array of Strings in your scope. Vue Property Type Description chips-color String Override default children chips text color. chips-bg-color String Override default children chips background color. add-icon String Override add icon (the one on the right side) to another one. readonly Boolean If readonly user can not add or remove chips. Also note you can use the native DOM attributes of an input: “max-length”, “autocomplete” and so on. Common input field properties: Property Type Description autofocus Boolean Focus input field after rendering component. placeholder String A text to be shown on textfield, mainly to explain what should be entered. loading Boolean Place the default spinner of the theme after textfield to highlight some process takes place in the background. Also note you can use the native DOM attributes of an input: “name”, “max-length”, “autocomplete” and so on. They are applied to the native <input> contained by QChipsInput. Common input frame properties: Property Type Description prefix String A text that should be shown before the textfield. suffix String A text that should be shown after the textfield. float-label String A text label that will “float” up above the input field, once the input field gets focus. stack-label String A text label that will be shown above the input field and is static. color String One from Quasar Color Palette. inverted Boolean Inverted mode. Color is applied to background instead. inverted-light Boolean Inverted mode with a light color. Color is applied to background instead. hide-underline Boolean Hides the bottom border. dark Boolean Is QChipsInput rendered on a dark background? align String One of ‘left’, ‘center’ or ‘right’ which determines the text align within textfield. disable Boolean If set to true, textfield is disabled and the user cannot type anything. warning Boolean If set to true, the component colors are changed to show there is a warning. error Boolean If set to true, the input fields colors are changed to show there is an error. before Array of Objects Icon buttons on left side of input frame. Read below more details. after Array of Objects Icon buttons on right side of input frame. Read below more details. Icon buttonsThis section refers to before and after properties which can add additional buttons as icons to the textfield. Here is the structure of the two properties: { // required icon icon: String, // required function to call when // icon is clicked/tapped handler: Function, // Optional. Show icon button // if model has a value content: Boolean, // Optional. Show icon button // if textfield is marked with error error: Boolean} Examples:<q-chips-input v-model=\"model\" color=\"secondary\" :after=\"[ { icon: 'warning', error: true, handler () { // do something... } } ]\"/> ColoringAs you may have noticed above, there’s a “color”, “chips-color” and “chips-bg-color” along with “inverted”/“inverted-light” and “dark” properties.By default, if you only use “color” then the input frame and Chips will share the color. If there’s also a “chips-color” or “chips-bg-color” specified then the encapsulated chips’ colors will be overwritten.When you want the frame inverted (color is applied to background), then specify “inverted” property. Use “inverted-light” when the color is light.When used on a dark background, specify “dark” property. <!-- Use a color. --><q-chips-input color=\"secondary\" v-model=\"model\" /><!-- Use a color on inverted mode (background gets colored). --><q-chips-input color=\"secondary\" v-model=\"model\" /><!-- Coloring the encapsulated Chips.--><q-chips-input color=\"amber\" chips-color=\"yellow\" chips-bg-color=\"black\" inverted-light v-model=\"model\"/><!-- When we use the component on a dark background, so we specify \"dark\" property.--><div class=\"bg-grey-9\" style=\"padding: 15px\"> <q-chips-input dark color=\"amber\" v-model=\"model\" /></div> Lazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-chips-input :value=\"model\" @change=\"val => { model = val }\"/> AutocompleteYou can use QAutocomplete to provide the user a list of values to select from.While the list of found values is open <ENTER> key will select a value from it and add it to the list.If you want to add a value not found in the list either hit the send icon or press <ESC> key to hide the list and then the <ENTER> key.<q-chips-input v-model=\"model\" placeholder=\"Add from list or new ones\"> <q-autocomplete @search=\"search\" @selected=\"selected\" /></q-chips-input> Vue Methods Vue Method Description add(value) Adds value to the model. remove(index) Removes value at index in model. focus() Focuses the input text field within Chips Input. select() Selects all textfield text and focuses. clear() Resets the model to an empty string. Vue Events Vue Event Description @input(newVal) Triggered immediately on model value change. @change(newVal) Triggered on lazy model value change. @clear(clearVal) Triggered when the model is cleared. @duplicate(val) Triggered when user tries to add a duplicate value. More ExamplesWrapped with QField<q-field icon=\"account_box\" label=\"Birthday\" :count=\"10\" helper=\"Some helper here\"> <q-chips-input float-label=\"Float Label\" v-model=\"model\" /></q-field> Usage Inside of a List<q-list> <q-item multiline> <q-item-side icon=\"edit\" /> <q-item-main> <q-chips-input v-model=\"model\" placeholder=\"Type names\"/> </q-item-main> </q-item></q-list>"},{"title":"Breadcrumbs","updated":"2018-05-18T22:01:01.003Z","permalink":"https://v0-16.quasar-framework.org/components/breadcrumbs.html","text":"Quasar Breadcrumbs is a component used as a navigational aid in UI. It allows users to keep track of their location within programs, documents, or websites. InstallationEdit /quasar.conf.js:framework: { components: [ 'QBreadcrumbs', 'QBreadcrumbsEl' ]} Basic Usage<q-breadcrumbs> <q-breadcrumbs-el label=\"Home\" icon=\"home\" /> <q-breadcrumbs-el label=\"Components\" icon=\"widgets\" /> <q-breadcrumbs-el label=\"Breadcrumbs\" icon=\"navigation\" /></q-breadcrumbs> With route links and custom separator:<q-breadcrumbs separator=\"->\" active-color=\"secondary\" color=\"light\"> <q-breadcrumbs-el label=\"Home\" to=\"/\" /> <q-breadcrumbs-el label=\"Components\" to=\"/components\" /> <q-breadcrumbs-el label=\"Breadcrumbs\" to=\"/components/breadcrums\" /> <q-breadcrumbs-el label=\"Bogus\" to=\"/components/breadcrums/bogus\" /></q-breadcrumbs> With separator as scoped slot (in this case an icon, but can be anything):<q-breadcrumbs> <q-icon name=\"trending_flat\" slot=\"separator\" slot-scope=\"props\" /> <q-breadcrumbs-el active>Home</q-breadcrumbs-el> <q-breadcrumbs-el>Components</q-breadcrumbs-el> <q-breadcrumbs-el>Breadcrumbs</q-breadcrumbs-el></q-breadcrumbs> With different alignment:<q-breadcrumbs align=\"center\"> <q-icon name=\"arrow_forward\" slot=\"separator\" slot-scope=\"props\" /> <q-breadcrumbs-el>Home</q-breadcrumbs-el> <q-breadcrumbs-el>Components</q-breadcrumbs-el> <q-breadcrumbs-el>Breadcrumbs</q-breadcrumbs-el></q-breadcrumbs> QBreadcrumbs Vue Properties Vue Property Type Description color String A color from Quasar Color Palette active-color String Active color, one from Quasar Color Palette separator String Separator text between breadcrumb elements align String One of ‘left’, ‘right’, ‘center’, ‘between’, ‘around’. QBreadcrumbsEl Vue Properties Vue Property Type Description label String Label of element icon String Icon for element color String A color from Quasar Color Palette Using QBreadcrumbsEl as a Router LinkIf you want your QBreadcrumbsEl to act the same as Vue’s <router-link>, then you can use these additional properties (which work exactly the same as <router-link>): Property Type Description to String / Object Route to navigate to exact Boolean Match the exact route specified (and not also its children) when adding router-link-active CSS class. append Boolean Append route definition to current route when navigating. replace Boolean Replaces current route with the new one instead of adding it to the window history queue. For more details on these properties, please refer to the Vue Router documentation."},{"title":"Color Input","updated":"2018-07-23T16:37:49.835Z","permalink":"https://v0-16.quasar-framework.org/components/color-input.html","text":"The Color component provides a method to input colors. There is also one more version available: Color Picker. Works well with QField for additional functionality such as a helper, error message placeholder and many others.You might also want to check Color Utils. InstallationEdit /quasar.conf.js:framework: { components: ['QColor']} Basic Usage<template> <q-color v-model=\"modelHex\" /></template><script>export default { data: () => ({ modelHex: '#C7044B', // and the other types of models: modelHexa: '#F0FF1CBF', modelRgb: { r: 112, g: 204, b: 55 }, modelRgba: { r: 138, g: 36, b: 138, a: 64 } })} Vue PropertiesSupports v-model which must be a String, Number or Date Object. Vue Property Type Description clearable Boolean If set to true, the component offers the user an actionable icon to remove the current selection. readonly Boolean If set to true, component is displayed as read-only. default-value String/Number/Date Default date/time for picker when model is not yet set. display-value String Text to display on input frame. Supersedes ‘placeholder’. hide-underline Boolean Hides the bottom border. popover Boolean Always display with a Popover, regardless of Platform. modal Boolean Always display with a Modal, regardless of Platform. format-model String Data type of model (useful especially when starting out with undefined or null). One of ‘auto’, ‘hex’, ‘rgb’, ‘hexa’, ‘rgba’. placeholder String Placeholder text for input frame to use when model is not set (empty). ok-label String Text for the button to accept the input (when using Modal). cancel-label String Text for the button to cancel input with no change (when using Modal). Common input frame properties: Property Type Description prefix String A text that should be shown before the value of model. suffix String A text that should be shown after the value of model. float-label String A text label that will “float” up above the input field, once the input field gets focus. stack-label String A text label that will be shown above the input field and is static. color String One from Quasar Color Palette. inverted Boolean Inverted mode. Color is applied to background instead. inverted-light Boolean Inverted mode with a light color. Color is applied to background instead. dark Boolean Is component rendered on a dark background? align String One of ‘left’, ‘center’ or ‘right’ which determines the text align. disable Boolean If set to true, component is disabled and the user cannot change model. warning Boolean If set to true, the input fields colors are changed to show there is a warning. error Boolean If set to true, the input fields colors are changed to show there is an error. before Array of Objects Icon buttons on left side of input frame. Read below more details. after Array of Objects Icon buttons on right side of input frame. Read below more details. Lazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-color :value=\"model\" @change=\"val => { model = val }\"/> Icon buttonsThis section refers to before and after properties which can add additional buttons as icons to the component. Here is the structure of the two properties: { // required icon icon: String, // required function to call when // icon is clicked/tapped handler: Function, // Optional. Show icon button // if model has a value content: Boolean, // Optional. Show icon button // if model is marked with error error: Boolean} Examples:<!-- Show an icon button (with 'warning' as icon) when there is an error on component (through \"error\" prop)--><q-color v-model=\"color\" :error=\"error\" :after=\"[ { icon: 'warning', error: true, handler () { // do something... } } ]\"/><!-- Show an icon button (with 'arrow_forward' as icon) when the model has a non empty value--><q-color v-model=\"color\" :after=\"[ { icon: 'arrow_forward', content: true, handler () { // do something... } } ]\"/> Vue Methods Vue Method Description show() Show Popover (on desktop) and Dialog (on mobile) to select date and/or time. Returns a Promise. hide() Hide Popover (on desktop) and Dialog (on mobile) to select date and/or time and execute Function after it’s been hidden. Returns a Promise. toggle() Toggle the Popover or Modal. clear() Sets model to empty string (removes current value). Vue Events Vue Event Description @input(newVal) Triggered on immediate model value change. @change(newVal) Triggered on lazy model value change. @clear(clearVal) Triggered when the model is cleared. @blur Triggered when the modal/ popup is closed. @focus Triggered when the modal/ popup is opened. More ExamplesColoringUse the color and inverted/inverted-light props to control the color.<q-color color=\"amber-7\" float-label=\"Float Label\" v-model=\"model\"/><q-color inverted color=\"primary\" float-label=\"Float Label\" v-model=\"model\"/> Also, if QColor is displayed on a dark background, add the dark property.<q-color dark color=\"secondary\" />"},{"title":"Collapsible (+ Accordion)","updated":"2018-07-23T16:37:49.834Z","permalink":"https://v0-16.quasar-framework.org/components/collapsible.html","text":"Quasar Collapsibles allow the hiding of content that is not immediately relevant to the user. Think of them as accordion elements that expand when clicked on. They are basically QItem components wrapped with additional functionality. So they can be included in QLists and inherit QItem component properties. InstallationEdit /quasar.conf.js:framework: { components: ['QCollapsible']} Basic Usage<q-list> <q-collapsible icon=\"explore\" label=\"First\"> <div> Content </div> </q-collapsible> <q-collapsible icon=\"perm_identity\" label=\"Second\"> <div> Content </div> </q-collapsible> <q-collapsible icon=\"shopping_cart\" label=\"Third\"> <div> Content </div> </q-collapsible></q-list> AccordionYou can group multiple Collapsibles to act as an Accordion, which is to open only one Collapsible at a time while closing the others automatically. For this, use group Vue property and specify a unique name within the Vue parent container of the Collapsibles.<q-list> <q-collapsible group=\"somegroup\" icon=\"explore\" label=\"First\"> <div> Content </div> </q-collapsible> <q-collapsible group=\"somegroup\" icon=\"perm_identity\" label=\"Second\"> <div> Content </div> </q-collapsible> <q-collapsible group=\"somegroup\" icon=\"shopping_cart\" label=\"Third\"> <div> Content </div> </q-collapsible></q-list> Vue PropertiesSince QCollapsible is a wrapper over QItem components, it inherits some of their properties as you can see below. Supports v-model to control the state (open/close). Own Property Type Description opened Boolean Control if Collapsible is opened or not when first rendered. group String Unique name which allows to group multiple Collapsible so they work as an Accordion. popup Boolean “Popup” mode instead of default behavior. indent Boolean Indent Collapsible content. Useful when building a menu with it. icon-toggle Boolean Expand/Contract only by clicking/tapping on the arrow on the right. collapse-icon String Icon used instead of default arrow on the right side. header-style Array/String/Object Vue style binding for header. header-class Array/String/Object Vue class binding for header. disable Boolean Disable current Collapsible. QItem & QItem related components inherited properties: Inherited Property Type Description icon, right-icon String Icon to use. Either use an icon, image, avatar or letter. image, right-image String URL to image to use (point to statics). Either use an icon, image, avatar or letter. avatar, right-avatar String URL to avatar to use (point to statics). Either use an icon, image, avatar or letter. letter, right-letter String One character String to define a letter. Either use an icon, image, avatar or letter. label String Label to use as title. sublabel String Label to use as subtitle. label-lines String / Number Number of lines the label can span to. Ellipsis are used when overflowing. sublabel-lines String / Number Number of lines the sublabel can span to. Ellipsis are used when overflowing. dense Boolean Use a dense QItem. sparse Boolean Use a sparse QItem. multiline Boolean Use a multiline QItem. Useful in cases where you use label and sublabel that spans multiple lines, but even then it’s optional. separator Boolean Use a separator from other QItems or QCollapsibles, just like on QItem. inset-separator Boolean Inset separator, same behavior as separator. Vue Methods Vue Methods Description toggle() Toggle open/close state. show() Open it. hide() Close it. Vue Events Vue Method Description @show Triggered after opening Collapsible. @hide Triggered after closing Collapsible. ExamplesUsing a v-model<template> <q-collapsible v-model=\"open\" icon=\"perm_identity\" label=\"With a model and events\" > <div>...content...</div> </q-collapsible></template><script>export default { data () { return { open: true } }, methods: { toggle () { this.open = !this.open } }}</script> Custom Header<q-collapsible> <template slot=\"header\"> <q-chip color=\"primary\" small class=\"q-mr-sm\"> Custom header </q-chip> <q-item-main label=\"using slot\" /> <q-item-side right> <q-icon name=\"star\" color=\"red\" size=\"24px\" /> </q-item-side> </template> <div>Collapsible content</div></q-collapsible> Popup Mode<q-collapsible popup icon=\"mail\" label=\"Inbox\" sublabel=\"5 unread emails\"> <div>...content...</div></q-collapsible><q-collapsible popup icon=\"send\" label=\"Outbox\" sublabel=\"Empty\"> <div>...content...</div></q-collapsible> Creating a Menu<q-list separator> <q-collapsible indent icon=\"mail\" label=\"Inbox\" sublabel=\"5 unread emails\" opened> <q-collapsible indent icon=\"receipt\" label=\"Receipts\"> <q-collapsible label=\"Today\"> <div>...content...</div> </q-collapsible> <q-collapsible label=\"Yesterday\"> <div>...content...</div> </q-collapsible> </q-collapsible> <q-collapsible indent icon=\"schedule\" label=\"Postponed\"> <div>...content...</div> </q-collapsible> </q-collapsible> <q-collapsible indent icon=\"send\" label=\"Outbox\" sublabel=\"Empty\"> <q-collapsible label=\"Today\"> <div>...content...</div> </q-collapsible> <q-collapsible label=\"Yesterday\"> <div>...content...</div> </q-collapsible> </q-collapsible> <q-collapsible indent icon=\"drafts\" label=\"Draft\" sublabel=\"Draft a new email\"> <div>...content...</div> </q-collapsible></q-list> Preselecting ItemsCollapsible items can be opened by default: <q-collapsible opened icon=\"explore\" label=\"First\"> <div> Content </div></q-collapsible><!-- or --><q-collapsible :opened=\"boolean_variable\" icon=\"explore\" label=\"First\"> <div> Content </div></q-collapsible> Indenting ContentWhen you are building a complex menu (with sub-menus), like for example on a Left or Right side of QLayout, it’s useful to also have some kind of left-side indentation on the Collapsible content: <q-collapsible indent icon=\"explore\" label=\"First\"> <q-item link ...>...</q-item> <q-item link ...>...</q-item> <q-item link ...>...</q-item></q-collapsible> Making Use of Events<template> <q-collapsible indent icon=\"explore\" label=\"Counter\" @show=\"startCounting\" @hide=\"stopCounting\" > <div> <q-chip color=\"secondary\"> Counting: {{ counter }} </q-chip> </div> <div class=\"q-mt-md\"> Will only count when opened, using the show/hide events to control count timer. </div> </q-collapsible></template><script>export default { data () { return { counter: 0 } }, methods: { startCounting () { this.hndl = setInterval(() => { this.counter++ }, 1000) }, stopCounting () { clearInterval(this.hndl) } }}</script> UbiquityBe creative. In the example below we’re using a Card as Collapsible content. <q-collapsible icon=\"explore\" label=\"First Card\" sublabel=\"Contains a Card\"> <q-card> <q-card-title> Card Title </q-card-title> <q-card-main> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </q-card-main> </q-card></q-collapsible>"},{"title":"Color Palette","updated":"2018-07-23T16:37:49.835Z","permalink":"https://v0-16.quasar-framework.org/components/color-palette.html","text":"Quasar Framework offers a wide selection of colors out of the box. You can use them both as Stylus variables in your CSS code or directly as CSS classes in your HTML templates. This page comes really handy after reading Quasar Theming. You might also want to check Color Utils. Brand ColorsThere can be three main colors used throughout your App, called primary, secondary and tertiary. Most of the colors that Quasar Components use are strongly linked with these three colors that you can change. Choosing these colors is the first step one should take when differentiating the design of its own App. You’ll notice immediately on changing their default values that Quasar Components follow these colors as a guideline. Color ListHere’s the list of colors provided out of the box. Use them as CSS classes (in HTML templates) or as Stylus variables (in <style lang="stylus"> tags) within your app’s *.vue files. primary, secondary, tertiarypositive, negative, info, warning, white, light, dark, faded On the following colors there are variations available:red, pink, purple, deep-purple, indigo, blue, light-blue, cyan, teal, green, light-green, lime, yellow, amber, orange, deep-orange, brown, grey, blue-grey Example of color variation: red, red-1, red-2, …, red-14. See the demo to make a good picture of what variations are. Variation 11 to 14 are color accents. Using as CSS ClassesUse text- or bg- prefixes as class names to change the color of text or the color of the background. <!-- changing text color --><p class=\"text-primary\">....</p><!-- changing background color --><p class=\"bg-positive\">...</p> Using Stylus VariablesIn your app’s *.vue files you can use the colors as $primary, $red-1, and so on. <!-- Notice lang=\"stylus\" --><style lang=\"stylus\">// \"variables\" is a Webpack alias injected by Quasar CLI@import '~variables'div color $red-1 background-color $grey-5</style> Adding Your Own ColorsIf you want to use colors of your own for components, let’s say we are adding a color named “brand”, all you need to do is add the following CSS into your app: .text-brand { color: #a2aa33;}.bg-brand { background: #a2aa33;} Now we can use this color for Quasar components:<q-input color=\"brand\" ... /> Dynamic Change of Brand Colors (Dynamic Theme Colors) WARNINGThis is only supported on browsers that support CSS Variables (Custom Properties).It is not going to work on IE11, but it will fall back to the brand colors from the CSS theme. This feature requires Quasar v0.15.7+ You can dynamically customize the brand colors during run-time: primary, secondary, tertiary, positive, negative, info, warning, light, dark, faded. That means you can have one build of your application with a default color theme but show it with a runtime selected one. The main color configuration is done using CSS custom properties, stored on the root element (:root). Each property has a name of --q-color-${name} (example: --q-color-primary, --q-color-secondary) and should have a valid CSS color as value. The CSS Custom properties use the same inheritance rules as normal CSS, so you can only redefine your desired colors and the rest will be inherited from the parent elements. The recommended workflow is to set your customized color properties on the html (document.documentElement) or body (document.body) elements. This will allow you to revert to the default color by just deleting your custom one. More info on CSS custom properties (variables): https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables Helper - setBrandQuasar offers a helper function for setting custom colors in the colors utils: setBrand(colorName, colorValue[, element]) Parameter Type Required Description colorName String Yes One of primary, secondary, tertiary, positive, negative, info, warning, light, dark, faded colorValue String Yes Valid CSS color value element Element - (Default: document.body) Element where the custom property will be set. Example of setting brand colors using the helper: import { colors } from 'quasar'colors.setBrand('light', '#DDD')colors.setBrand('primary', '#33F')colors.setBrand('primary', '#F33', document.getElementById('rebranded-section-id')) The helper function will also take care of setting dependent custom properties for some colors (positive, negative, light), so this is the recommended way of usage instead of the raw Javascript setProperty(). Helper - getBrandQuasar offers a helper function for setting custom colors in the colors utils: getBrand(colorName[, element]) Parameter Type Required Description colorName String Yes One of primary, secondary, tertiary, positive, negative, info, warning, light, dark, faded element Element - (Default: document.body) Element where the custom property will be read. Example of getting brand colors using the helper: import { colors } from 'quasar'colors.getBrand('primary') // '#33F'colors.getBrand('primary', document.getElementById('rebranded-section-id')) What this helper does is wrap the raw Javascript getPropertyValue() and it’s available for convenience. Example of equivalent raw Javascript: // equivalent of colors.getBrand('primary') in raw Javascript:getComputedStyle(document.documentElement) .getPropertyValue('--q-color-primary') // #0273d4"},{"title":"Color Picker","updated":"2018-07-23T16:37:49.836Z","permalink":"https://v0-16.quasar-framework.org/components/color-picker.html","text":"The ColorPicker component provides a method to input colors. There is also one more version available: Color Input. Works well with QField for additional functionality such as a helper, error message placeholder and many others.You might also want to check Color Utils. InstallationEdit /quasar.conf.js:framework: { components: ['QColorPicker']} Basic Usage<template> <q-color-picker v-model=\"modelHex\" /></template><script>export default { data: () => ({ modelHex: '#C7044B', // and the other types of models: modelHexa: '#F0FF1CBF', modelRgb: { r: 112, g: 204, b: 55 }, modelRgba: { r: 138, g: 36, b: 138, a: 64 } })} Vue PropertiesSupports v-model which must be a String, Number or Date Object. Vue Property Type Description dark Boolean Is component rendered on a dark background? default-value String/Object Default color hex/rgb for picker when model is not yet set. format-model String Data type of model (useful especially when starting out with undefined or null). One of ‘auto’, ‘hex’, ‘rgb’, ‘hexa’, ‘rgba’. readonly Boolean If set to true, component is displayed as read-only. disable Boolean If set to true, component is disabled and the user cannot change model. Lazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-color-picker :value=\"model\" @change=\"val => { model = val }\"/> Vue Methods Vue Method Description clear() Sets model to empty string (removes current value). Vue Events Vue Event Description @input(newVal) Triggered on immediate model value change. @change(newVal) Triggered on lazy model value change. More ExamplesColoringUse the color and inverted/inverted-light props to control the color.<q-color-picker color=\"amber-7\" float-label=\"Float Label\" v-model=\"model\"/><q-color-picker inverted color=\"primary\" float-label=\"Float Label\" v-model=\"model\"/> Also, if QColor is displayed on a dark background, add the dark property.<q-color-picker dark color=\"secondary\" />"},{"title":"Building Reusable Components with Quasar","updated":"2018-05-18T22:01:01.003Z","permalink":"https://v0-16.quasar-framework.org/components/building-reusable-components.html","text":"Vue greatly encourages the use of components to encapsulate reusable code and therefore DRY up your code. Quasar also follows this practice and distributes all its components encapsulated. This guide should help you to build new components by either using existing Quasar components or starting from scratch. Before you read this guide, please make sure you understand the concepts behind Vue components and also read up on Single File Components. Using existing componentsQuasar is a framework and therefore provides building blocks to build your own apps on top of it. But often the question arises how one could use the already existing Quasar components to build own components. The first thing to notice is that Vue favors composition over inheritance. Inheritance is a concept know from object oriented programming, where classes are able to extend another class to reuse its methods and attributes to build a new but similar class. Composition, on the other hand, is also known from object oriented programming, but instead of extending or overwriting an existing class, the class uses other classes to provide some common services. Compose components to build a new oneMost of the times you want to take existing Quasar components and build new components on top of them.You can refer to this as the Decorator pattern / Wrapper known from object oriented programming. This pattern allows to create new versions of an object and altering/extending its behavior by wrapping the existing object and giving it a new name, therefore not affecting the base object. Let’s take a look at a simple example: Custom select componentLet’s assume we want to build a component that hides some of the props passed to QSelect. Specifically, we want to build a select component which always has the filter prop set to true and always apply a default filter-placeholder. A simple implementation of this component could look like this: <template> <q-select :value="value" :options="options" @change="handleChange" filter filter-placeholder="select"/></template><script> import { QSelect } from 'quasar' export default { props: ['value', 'options'], methods: { handleChange (newVal) { this.$emit('input', newVal) } }, components: { QSelect } }</script> Because v-model="foo" is just syntactic sugar for :value="foo" @input="foo = $event.target.the value" we can define a property value on our new component, which is then passed as value to the inner QSelect. Then we can listen to the change event on the QSelect to trigger a method when the input has changed. If we receive such an event, we are emitting an input event from our new component and pass the new value as a parameter, so it can again be used with vmodel. Now we can use the component like this: <template> <my-select v-model="selected" :options="myOptions" /></template><script> import MySelect from './MySelect' export default { data () { return { selected: null, myOptions: [] } }, components: { MySelect } }</script> This would render a QSelect with filter set to true and filter-placeholder set to “select”. A great way to inspect this is by using vue-devtools Note that we now can not use all the standard QSelect properties. If we wanted to set other properties on the internal QSelect we would have to define all of them on our own component and pass them to QSelect. Pinpad componentNow let’s assume we do not want to wrap an existing component to simply it, but instead, we want to build an entirely new component which is not included with Quasar. This example is taken from a forum post, where a user wanted to build a pin pad component. If you think about pin pads for a minute, you will quickly come to the conclusion that pin pads most of the time are made up of a matrix of buttons. That’s great, we already have the existing QBtn component included with Quasar, so these could be used to build our pin pad component. Next thing we need for a pin pad is to order a set of buttons in a matrix. For this the CSS flexbox layout is great. Gladly Quasar also has you covered here and already includes a flexbox grid. If we throw this two thing together, building our pin pad is easy. <template> <div> <div v-for="row in 3" class="row justify-center"> <div v-for="col in 3" class="col-auto"> <q-btn @click="handleClick((row-1)*3 + col)"> {{ (row-1)*3 + col }} </q-btn> </div> </div> </div></template><script> import { QBtn } from 'quasar' export default { data () { return { pin: '' } }, methods: { handleClick (digit) { this.pin += digit } }, components: { QBtn } }</script> This gives us a whole new component by using existing components. We could now even extend this component with other Quasar components like a QInput to allow for manually entered pins. Of course, this is just a minimal example, we miss styling of the buttons and all the logic that goes behind a pin pad. MixinsMixins allow re-using certain features that you need in a set of components to not repeat yourself writing that code over and over. To define a mixin one has to export an object that looks similar to a normal component. Other components now can use this mixin to implement the mixin functionality. For example, lets we need to call a register method on a lot of different components. This method calls an API and returns some identifier that should be stored in the data object of the component. First, let us define the RegisterMixin: export const RegisterMixin = { data () { return { id: '' } }, methods: { register () { // Lets assume we extracted the AJAX call to the Registration class new Registration() .register() .then(response => { this.id = response.id }) } }, created () { this.register() }} Now that we have defined the mixin, we can use it on any other component and it will be mixed in the component attributes. import { RegisterMixin } from './registerMixin'export default { mixins: [RegisterMixin]} A component can use as many mixins as it likes.But be aware how Vue merges the options. You can read more about mixins in the Vue docs. Quasar uses mixins for some of its internal functionality. For example, the RouterLinkMixin which allows adding link functionality to different components. But as great as mixins are, you can not really use another single file component as mixin because only the JavaScript parts are mixed into your component and not the template or style definition. Let’s assume we want to build the MySelect component from above, using mixins. If we would write the following code import { QSelect } from 'quasar'export default { mixin: [QSelect]} we would end up with a component that has all the internal methods and data from QSelect but no template at all. So we would have to get to the source of QSelect and copy the whole template definition. This would work as long as QSelect gets updated and you forget to update the template as well. Even if you only update minor versions it could break, because you are not relying on the external interface of QSelect which is described in the docs, but also on the internal code, which normally one shouldn’t have to care about. So mixins are great to simplify your own components and if you want to build an entirely new component on top of existing Quasar logic. How to style custom componentsStyling custom components is easy, just declare your styles in the <style> section of your single file component or import a external style definition by using <style src="/path/to/your/stlye"></style> But what if we want our styles to be consistent and be able to change them in a single place? Quasar uses Stylus variables for that purpose.If you want to use some of the variables in your own components you can just import them like so: <template> ...</template><script> ...</script><style lang="stylus"> @import '~variables'</style> Now you can use all the Stylus variables like colors or breakpoints in your own component. @import '~variables'h1 color $primary Inter-component communicationVue provides various ways to allow two or more components to communicate with each other. PropsProps are used to pass data from a parent component to a child component. Almost all Quasar components use props to allow you to pass data or set options on them. EventsFor more complex communication events are used. One particulary interesting thing about events is that v-model="foo" is just syntactic sugar for :value="foo" @input="foo = $event.target.the value". If you want to build a custom component you can use v-model on, just emit an input event with the payload somewhere in your code. DirectivesAnother form of reusable code in Vue are directives. Quasar provides a set of directives out of the box you can use. Swiping, Panning and HoldThe v-touch-pan, v-touch-swipe and v-touch-hold directives allow you to add gesture and touch interactions to your custom components. RippleThe Material Ripple directive allows you add the well know ripple effect to your custom components. UtilsIn addition to components and directives Quasar also offers a set of JavaScript Utils to simplify your component development, check them out in the Utils section."},{"title":"Color Utils","updated":"2018-07-09T22:30:23.744Z","permalink":"https://v0-16.quasar-framework.org/components/color-utils.html","text":"Quasar provides a set of useful functions to manipulate colors easily in most use cases, without the high additional cost of integrating dedicated libraries. Helping Tree-ShakeYou will notice all examples import colors Object from Quasar. However, if you need only one method from it, then you can use ES6 destructuring to help Tree Shaking embed only that method and not all of colors. Example with setBrand():// we import all of `colors`import { colors } from 'quasar'// destructuring to keep only what is neededconst { setBrand } = colorssetBrand('primary', '#f33') Color ConversionThese functions take a color as string or Object and convert it to another format. Function Source format Destination format Description rgbToHex Object String Converts a RGB/A color Object ({ r: [0-255], g: [0-255], b: [0-255}<, a: [0-100]>}) to it’s HEX/A representation as a String (#RRGGBB<AA>). If Alpha channel is present in the original object it will be present also in the output. rgbToHsv Object Object Converts a RGB/A color Object ({ r: [0-255], g: [0-255], b: [0-255}<, a: [0-100]>}) to it’s HSV/A representation as an Object ({ h: [0-360], s: [0-100], v: [0-100}, a: [0-100]}). If Alpha channel is present in the original object it will be present also in the output. hexToRgb String Object Converts a HEX/A color String (#RRGGBB<AA>) to it’s RGB/A representation as an Object ({ r: [0-255], g: [0-255], b: [0-255}<, a: [0-100]>}) to it’s . If Alpha channel is present in the original object it will be present also in the output. textToRgb String Object Converts a HEX/A color String (#RRGGBB<AA>) or a RGB/A color String(rgb(R, G, B<, A>)) to it’s RGB/A representation as an Object ({ r: [0-255], g: [0-255], b: [0-255}<, a: [0-100]>}) to it’s . If Alpha channel is present in the original object it will be present also in the output. hsvToRgb String Object Converts a HSV/A color Object ({ h: [0-360], s: [0-100], v: [0-100}, a: [0-100]}) to it’s RGB/A representation as an Object ({ r: [0-255], g: [0-255], b: [0-255}<, a: [0-100]>}) to it’s . If Alpha channel is present in the original object it will be present also in the output. Color ProcessingThese functions perform changes on the color or extract specific information. lighten (color, percent)Lighten the color (if percent is positive) or darken it (if percent is negative). Accepts a HEX/A String or a RGB/A String as color and a percent (0 to 100 or -100 to 0) of lighten/darken to be applied to the color.Returns a HEX String representation of the calculated color. luminosity (color)Calculates the relative luminance of the color. Accepts a HEX/A String, a RGB/A String or a RGB/A Object as color.Returns a value between 0 and 1. Dynamic Change of Brand Colors (Dynamic Theme Colors) WARNINGThis is only supported on browsers that support CSS Variables (Custom Properties).It is not going to work on IE11, but it will fall back to the brand colors from the CSS theme. This feature requires Quasar v0.15.7+ You can dynamically customize the brand colors during run-time: primary, secondary, tertiary, positive, negative, info, warning, light, dark, faded. That means you can have one build of your application with a default color theme but show it with a runtime selected one. The main color configuration is done using CSS custom properties, stored on the root element (:root). Each property has a name of --q-color-${name} (example: --q-color-primary, --q-color-secondary) and should have a valid CSS color as value. The CSS Custom properties use the same inheritance rules as normal CSS, so you can only redefine your desired colors and the rest will be inherited from the parent elements. The recommended workflow is to set your customized color properties on the html (document.documentElement) or body (document.body) elements. This will allow you to revert to the default color by just deleting your custom one. More info on CSS custom properties (variables): https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables Helper - setBrandQuasar offers a helper function for setting custom colors in the colors utils: setBrand(colorName, colorValue[, element]) Parameter Type Required Description colorName String Yes One of primary, secondary, tertiary, positive, negative, info, warning, light, dark, faded colorValue String Yes Valid CSS color value element Element - (Default: document.body) Element where the custom property will be set. Example of setting brand colors using the helper: import { colors } from 'quasar'colors.setBrand('light', '#DDD')colors.setBrand('primary', '#33F')colors.setBrand('primary', '#F33', document.getElementById('rebranded-section-id')) The helper function will also take care of setting dependent custom properties for some colors (positive, negative, light), so this is the recommended way of usage instead of the raw Javascript setProperty(). Helper - getBrandQuasar offers a helper function for getting custom colors in the colors utils: getBrand(colorName[, element]) Parameter Type Required Description colorName String Yes One of primary, secondary, tertiary, positive, negative, info, warning, light, dark, faded element Element - (Default: document.body) Element where the custom property will be read. Example of getting brand colors using the helper: import { colors } from 'quasar'colors.getBrand('primary') // '#33F'colors.getBrand('primary', document.getElementById('rebranded-section-id')) What this helper does is wrap the raw Javascript getPropertyValue() and it’s available for convenience. Example of equivalent raw Javascript: // equivalent of colors.getBrand('primary') in raw Javascript:getComputedStyle(document.documentElement) .getPropertyValue('--q-color-primary') // #0273d4 Create Dynamic Custom ColorsYou can use setBrand and getBrand to define custom brand colors to use in your application.An example of such a new custom color usage: $primary-darkened = darken($primary, 10%):root --q-color-primary-darkened $primary-darkened.text-primary-darkened color $primary-darkened !important color var(--q-color-primary-darkened) !important.bg-primary-darkened background $primary-darkened !important background var(--q-color-primary-darkened) !important import { colors } from 'quasar'const { lighten, setBrand } = colorsconst newPrimaryColor = '#933'setBrand('primary', newPrimaryColor)setBrand('primary-darkened', lighten(newPrimaryColor, -10))"},{"title":"Chat","updated":"2018-05-18T22:01:01.005Z","permalink":"https://v0-16.quasar-framework.org/components/chat.html","text":"Quasar supplies a chat component called QChatMessage which is really a chat entry that renders the data given by the props. InstallationEdit /quasar.conf.js:framework: { components: ['QChatMessage']} Basic UsageThis show a simple chat between two parties. <q-chat-message label='Sunday, 19th'/><q-chat-message name=\"me\" avatar=\"statics/boy-avatar.png\" :text=\"['hunter2']\" stamp=\"4 minutes ago\" sent/><q-chat-message name=\"Jane\" avatar=\"statics/linux-avatar.png\" :text=\"['hey, if you type in your pw', 'it will show as stars']\" stamp=\"7 minutes ago\"/> Vue Properties Vue Property Type Description sent Boolean Render as a sent message (so from current user) label String Label of message name String Name of the message creator avatar String URL to the avatar image of the creator (use a static resource) text Array Array of strings that are the message body stamp String Creation timestamp string text-color String Color of the text bg-color String Color of the chat message bubble size Number 1-12 out of 12 (same as col-*). Note that text property is an Array of Strings. This is useful when two or more messages share the same (or very close) timestamp. They will be displayed on separate bubbles, but grouped together more closely so that the name of the creator and timestamp are displayed only once for this kind of group. Please refer to the demo source for a more complete set of examples."},{"title":"Context Menu","updated":"2018-05-18T22:01:01.009Z","permalink":"https://v0-16.quasar-framework.org/components/context-menu.html","text":"This component allows you to display a context menu (popup) instead of the default browser one when user performs a right-click (or long tap on touch capable devices). InstallationEdit /quasar.conf.js:framework: { components: ['QContextMenu'], directives: ['CloseOverlay']} Basic UsageContext menus can contain anything. In the example below, we display a menu. <q-context-menu> <q-list link separator style=\"min-width: 150px; max-height: 300px;\"> <q-item v-close-overlay @click.native=\"showToast()\"> <q-item-main label=\"Label\" sublabel=\"Value\" /> </q-item> <q-item v-close-overlay @click.native=\"showOtherToast()\"> <q-item-main label=\"Other Label\" sublabel=\"Other Value\" /> </q-item> </q-list></q-context-menu> The position of the popup is calculated so that it will be displayed on the available screen real estate, switching sides (right/left and/or top/bottom) when necessary.Clicking/Tapping outside of the popup will close the Context Menu. Notice the “v-close-overlay” directive. When applied to any element within a popup (Popover, Modal) like in this case, it closes it. IMPORTANTWhen on a mobile app and user hits the phone/tablet back button, the Context Menu will get closed automatically.When on a desktop browser and user hits the <ESCAPE> key, the Context Menu will get close automatically. Vue Properties Vue Property Type Description disable Boolean Disabled or not QContextMenu also supports a Boolean ‘v-model’ which controls the open/close state. Vue Methods Vue Method Description show() Open Context Menu hide() Close Context Menu Vue Events Vue Method Description @show Triggered when showing up. @hide Triggered when closing/hiding."},{"title":"Data Table","updated":"2018-07-23T16:37:49.837Z","permalink":"https://v0-16.quasar-framework.org/components/datatable.html","text":"QTable is a Component which allows you to display data in a tabular manner. Features: Filtering Sorting Single / Multiple rows selection with custom selection actions Pagination (including server-side if required) Total customization of rows and cells through scoped slots Ability to add additional row(s) at top or bottom of data rows Columns picker (through QTableColumns component described in one of the sections) Custom top and/or bottom Table controls Responsive design (“dense” mode for narrow windows) InstallationEdit /quasar.conf.js:framework: { components: [ 'QTable', // pick only what you are using from: 'QTh', 'QTr', 'QTd', 'QTableColumns' ]} Basic UsageThis is the most basic QTable:<template> <q-table title=\"Table Title\" :data=\"tableData\" :columns=\"columns\" row-key=\"name\" /></template><script>export default { data: () => ({ columns: [ { name: 'desc', required: true, label: 'Dessert (100g serving)', align: 'left', field: 'name', sortable: true }, ... ], tableData: [ { name: 'Frozen Yogurt', calories: 159, fat: 6.0, carbs: 24, protein: 4.0, sodium: 87, calcium: '14%', iron: '1%' }, ... ] })}</script> InternationalizationThe default values of the different QTable labels are taken care of by default through Quasar I18n. If your desired language pack is missing, please provide a PR for it. QTable Vue Properties Vue Property Type Description data Array of Objects Data containing Array of rows to display. columns Array of Objects (Required) Defining each column’s properties. row-key String (Required) Property name of each row defining a unique data key for the respective rows. pagination Object Use with .sync. Control of the pagination and sorting. Can enable Table “server-mode” by containing rowsNumber property. See next sections for details. rows-per-page-options Array Array of Numbers representing options for user to select how many rows per page should be shown. Example: ‘[3, 5, 7, 0]’. Notice value 0 means “All”. selection String Set selection mode. One of ‘single’, ‘multiple’ or (default) ‘none’. selected Array Use with .sync. Array of unique keys for selected row(s). visible-columns Array Array of Strings containing the ‘name’ column property value of the visible columns. loading Boolean Show a background process is in progress (like fetching data and so on). color String Color of the default Table controls (pagination, checkboxes, …). dark Boolean When using Table on a dark background. dense Boolean Dense Table, when you want to display more data using the same real estate on window. Gets activated by default on narrow windows. title String Title of Table. hide-header Boolean Hide Table header. hide-bottom Boolean Hide Table bottom (usually containing pagination controls). separator String Sets separator for rows/columns/cell. One of ‘horizontal’, ‘vertical’, ‘cell’, ‘none’. table-style String/Array/Object Style for the <table> tag itself. table-class String/Array/Object Classes for the <table> tag itself. filter String Filter String for Table used by filter-method(). filter-method Function When you want a custom filtering method. See next sections for details. Label properties are by default defined in Quasar’s i18n, but you can override them: Vue Property Type Description no-data-label String Message to display when no rows are available. no-results-label String Message to display when no rows match the filter. loading-label String Message to display when Table currently has no rows but is in the process of fetching them. selected-rows-label(rowsNumber) Function Function that returns a message (String) to display how many rows are selected. Takes a Number parameter which is the actual rows number that are selected. rows-per-page-label String Override ‘Rows per page:’ message. pagination-label(start,end,total) Function Override default ‘x-y of z’ pagination label. IMPORTANTInitial sorted column, sorting direction & page is configured through the pagination prop. Check the Pagination section below. Columns DefinitionLet’s take an example of configuring columns property. Let’s assume we are telling QTable that row-key is ‘name’.columns: /* array of Objects */ [ // column Object definition { // unique id (used by row-key, pagination.sortBy, ...) name: 'desc', // label for header label: 'Dessert (100g serving)', // row Object property to determine value for this column field: 'name', // OR field: row => row.some.nested.prop // (optional) if we use visible-columns, this col will always be visible required: true, // (optional) alignment align: 'left', // (optional) tell QTable you want this column sortable sortable: true // (optional) compare function if you have // some custom data or want a specific way to compare two rows sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) // function return value: // * is less than 0 then sort a to an index lower than b, i.e. a comes first // * is 0 then leave a and b unchanged with respect to each other, but sorted with respect to all different elements // * is greater than 0 then sort b to an index lower than a, i.e. b comes first }, { name: 'calories', label: 'Calories', field: 'calories', sortable: true }, { name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true }, { name: 'carbs', label: 'Carbs (g)', field: 'carbs' }, { name: 'protein', label: 'Protein (g)', field: 'protein' }, { name: 'sodium', label: 'Sodium (mg)', field: 'sodium' }, { name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, { name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }] PaginationWhen you want to control Table’s pagination, use pagination prop, but don’t forget to add the .sync modifier: <template> <div> <q-table :pagination.sync=\"pagination\" ... /> <q-btn @click=\"pagination.page++\" label=\"Next page\" ... /> </div></template><script>export default { data: () => ({ pagination: { sortBy: null, // String, column \"name\" property value descending: false, page: 1, rowsPerPage: 5 // current rows per page being displayed } })} When pagination has a property named rowsNumber, then this means that you’ll be configuring Table for server-side pagination (& sorting & filtering). Custom Filter Method<template> <q-table :filter=\"terms\" :filter-method=\"myFilter\" ...</template><script>export default { data: () => ({ filter: '' }), methods: { // this is actually the default filtering method: myFilter (rows, terms, cols, cellValue) { const lowerTerms = terms ? terms.toLowerCase() : '' return rows.filter( row => cols.some(col => (cellValue(col, row) + '').toLowerCase().indexOf(lowerTerms) !== -1) ) } }}</script> QTable Vue Events Vue Event Parameters Description @request Object { pagination, filter, getCellValue } Gets triggered when using server-side pagination (pagination property Object contains rowsNumber) Server-side Pagination, Filtering, SortingWhen your database contains a big number of rows for a Table, obviously it’s not feasible to load them all for multiple reasons (memory, UI rendering performance, …). Instead, you can load only a Table page. Whenever the user wants to navigate to another Table page, or wants to sort by a column or wants to filter the Table, a request is sent to the server to fetch the partial data. First step to enable this behavior is to specify pagination prop, which MUST contain rowsNumber. QTable needs to know the total number of rows available in order to correctly render the pagination links. Second step is to listen for @request event on QTable. This event is triggered when data needs to be fetched from the server because either page number or sorting or filtering changed. It’s best that you also specify the loading prop in order to notify the user that a background process is in progress. <template> <q-table ref=\"table\" :data=\"serverData\" :columns=\"columns\" :filter=\"filter\" row-key=\"name\" :pagination.sync=\"serverPagination\" :loading=\"loading\" @request=\"request\" > <template slot=\"top-right\" slot-scope=\"props\"> <q-search hide-underline v-model=\"filter\" /> </template> </q-table></template><script>import tableData from 'assets/table-data'export default { data () { return { filter: '', loading: false, serverPagination: { page: 1, rowsNumber: 10 // specifying this determines pagination is server-side }, serverData: [], columns: [ { name: 'desc', required: true, label: 'Dessert (100g serving)', align: 'left', field: 'name', sortable: true }, { name: 'calories', label: 'Calories', field: 'calories', sortable: true }, { name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true }, { name: 'carbs', label: 'Carbs (g)', field: 'carbs' }, { name: 'protein', label: 'Protein (g)', field: 'protein' }, { name: 'sodium', label: 'Sodium (mg)', field: 'sodium' }, { name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, { name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) } ] } }, methods: { request ({ pagination, filter }) { // we set QTable to \"loading\" state this.loading = true // we do the server data fetch, based on pagination and filter received // (using Axios here, but can be anything; parameters vary based on backend implementation) axios .get(`/data/${pagination.page}?sortBy=${pagination.sortBy}&descending=${pagination.descending}&filter=${filter}`) .then(({ data }) => { // updating pagination to reflect in the UI this.serverPagination = pagination // we also set (or update) rowsNumber this.serverPagination.rowsNumber = data.rowsNumber // then we update the rows with the fetched ones this.serverData = data.rows // finally we tell QTable to exit the \"loading\" state this.loading = false }) .catch(error => { // there's an error... do SOMETHING // we tell QTable to exit the \"loading\" state this.loading = false }) } }, mounted () { // once mounted, we need to trigger the initial server data fetch this.request({ pagination: this.serverPagination, filter: this.filter }) }}</script> Examples - FeaturesFilter, Column selection, Separators, Toggle Fullscreen<template> <q-table :data=\"tableData\" :columns=\"columns\" :filter=\"filter\" :visible-columns=\"visibleColumns\" :separator=\"separator\" row-key=\"name\" color=\"secondary\" > <template slot=\"top-left\" slot-scope=\"props\"> <q-search hide-underline color=\"secondary\" v-model=\"filter\" class=\"col-6\" /> </template> <template slot=\"top-right\" slot-scope=\"props\"> <q-table-columns color=\"secondary\" class=\"q-mr-sm\" v-model=\"visibleColumns\" :columns=\"columns\" /> <q-select color=\"secondary\" v-model=\"separator\" :options=\"[ { label: 'Horizontal', value: 'horizontal' }, { label: 'Vertical', value: 'vertical' }, { label: 'Cell', value: 'cell' }, { label: 'None', value: 'none' } ]\" hide-underline /> <q-btn flat round dense :icon=\"props.inFullscreen ? 'fullscreen_exit' : 'fullscreen'\" @click=\"props.toggleFullscreen\" /> </template> </q-table></template><script>export default { data: () => ({ tableData: [ ... ], columns: [ ... ], visibleColumns: ['desc', 'fat', 'carbs', 'protein', 'sodium', 'calcium', 'iron'], separator: 'horizontal', filter: '' })}</script> Row selection, Extra top/bottom rows, Loading state<template> <q-table :data=\"tableData\" :columns=\"columns\" :selection=\"selection\" :selected.sync=\"selected\" :loading=\"loading\" row-key=\"name\" color=\"secondary\" :class=\"tableClass\" > <q-tr slot=\"top-row\" slot-scope=\"props\"> <q-td colspan=\"100%\"> <strong>Extra top row</strong> </q-td> </q-tr> <q-tr slot=\"bottom-row\" slot-scope=\"props\"> <q-td colspan=\"100%\"> <strong>Extra bottom row</strong> </q-td> </q-tr> <template slot=\"top-left\" slot-scope=\"props\"> <q-select v-model=\"selection\" stack-label=\"Selection\" hide-underline :options=\"[ { label: 'Single', value: 'single' }, { label: 'Multiple', value: 'multiple' }, { label: 'None', value: 'none' } ]\" color=\"secondary\" style=\"min-width: 100px\" /> </template> <div slot=\"top-right\" slot-scope=\"props\" class=\"column\"> <q-toggle v-model=\"loading\" label=\"Loading state\" color=\"secondary\" class=\"q-mb-sm\" /> <q-toggle v-model=\"dark\" label=\"On dark background\" color=\"secondary\" /> </div> </q-table></template><script>export default { data: () => ({ tableData: [ ... ], columns: [ ... ], loading: false, dark: true, selection: 'multiple', selected: [ // initial selection; notice we specify the // row-key prop of the selected row { name: 'Ice cream sandwich' } ] })}</script> Controlling pagination, custom controls & watching for page navigation<template> <q-table :data=\"tableData\" :columns=\"columns\" :pagination.sync=\"paginationControl\" row-key=\"name\" color=\"primary\" > <div slot=\"pagination\" slot-scope=\"props\" class=\"row flex-center q-py-sm\"> <q-btn round dense size=\"sm\" icon=\"undo\" color=\"secondary\" class=\"q-mr-sm\" :disable=\"props.isFirstPage\" @click=\"props.prevPage\" /> <div class=\"q-mr-sm\" style=\"font-size: small\"> Page {{ props.pagination.page }} / {{ props.pagesNumber }} </div> <q-btn round dense size=\"sm\" icon=\"redo\" color=\"secondary\" :disable=\"props.isLastPage\" @click=\"props.nextPage\" /> </div> </q-table></template><script>export default { data: () => ({ tableData: [ ... ], columns: [ ... ], paginationControl: { rowsPerPage: 3, page: 1 }, }), watch: { 'paginationControl.page' (page) { this.$q.notify({ color: 'secondary', message: `Navigated to page ${page}`, actions: page < 4 ? [{ label: 'Go to last page', handler: () => { this.paginationControl.page = 4 } }] : null }) } }}</script> Row selection actions<q-table :data=\"tableData\" :columns=\"columns\" selection=\"multiple\" :selected.sync=\"selectedSecond\" row-key=\"name\" color=\"secondary\" title=\"Select some rows\"> <!-- gets displayed only when there's at least one row selected --> <template slot=\"top-selection\" slot-scope=\"props\"> <q-btn color=\"secondary\" flat label=\"Action 1\" class=\"q-mr-sm\" /> <q-btn color=\"secondary\" flat label=\"Action 2\" /> <div class=\"col\" /> <q-btn color=\"negative\" flat round delete icon=\"delete\" @click=\"deleteRow\" /> </template></q-table> Hide header & bottom<q-table :data=\"tableData\" :columns=\"columns\" row-key=\"name\" color=\"primary\" hide-header hide-bottom/> Display a nested property or format a columnYou can display the value of a nested property. For example:columns: [ { name: 'author', label: 'Author', field: row => row.author.name }] Then you can go even further and format the value for a specific column in your column definition. Example:columns: [ { name: 'author', label: 'Author', field: row => row.author.name, format: val => `${val}%` }] The value returned by field is used for sorting rows, while the format value is specifically meant for displaying a value to the user. This is very useful for cases where you need to sort by the initial value of your data. You can (if you want to), however, avoid the format and use custom scoped slots (row, column cell) for defining how Quasar should format the cell(s). Examples - CustomizationCustom table top & bottom<q-table :data=\"tableData\" :columns=\"columns\" row-key=\"name\" color=\"primary\"> <div slot=\"top\" slot-scope=\"props\" class=\"row flex-center fit\"> <img src=\"~assets/quasar-logo-full.svg\"> </div> <div slot=\"bottom\" slot-scope=\"props\" class=\"row flex-center fit\"> <q-btn round dense icon=\"chevron_left\" color=\"primary\" class=\"q-mr-md\" :disable=\"props.isFirstPage\" @click=\"props.prevPage\" /> <q-btn round dense icon=\"chevron_right\" color=\"primary\" :disable=\"props.isLastPage\" @click=\"props.nextPage\" /> </div></q-table> Custom column cell<q-table :data=\"tableData\" :columns=\"columns\" row-key=\"name\" color=\"secondary\"> <!-- slot name syntax: body-cell-<column_name> --> <q-td slot=\"body-cell-desc\" slot-scope=\"props\" :props=\"props\"> <q-chip small color=\"secondary\">{{ props.value }}</q-chip> </q-td></q-table> Custom rows<q-table :data=\"tableData\" :columns=\"columns\" row-key=\"name\"> <q-tr slot=\"body\" slot-scope=\"props\" :props=\"props\"> <q-td key=\"desc\" :props=\"props\"> <span class=\"text-italic\">{{ props.row.name }}</span> <q-tooltip>I'd like to eat \"{{ props.row.name }}\"</q-tooltip> </q-td> <q-td key=\"calories\" :props=\"props\"> <div class=\"row items-center justify-between no-wrap\"> <q-btn size=\"sm\" round dense color=\"secondary\" icon=\"remove\" @click=\"props.row.calories--\" class=\"q-mr-xs\" /> <q-btn size=\"sm\" round dense color=\"tertiary\" icon=\"add\" @click=\"props.row.calories++\" class=\"q-mr-sm\" /> <div>{{ props.row.calories }}</div> </div> </q-td> <q-td key=\"fat\" :props=\"props\">{{ props.row.fat }}</q-td> <q-td key=\"carbs\" :props=\"props\"> <q-chip small square color=\"amber\">{{ props.row.carbs }}</q-chip> </q-td> <q-td key=\"protein\" :props=\"props\">{{ props.row.protein }}</q-td> <q-td key=\"sodium\" :props=\"props\">{{ props.row.sodium }}</q-td> <q-td key=\"calcium\" :props=\"props\">{{ props.row.calcium }}</q-td> <q-td key=\"iron\" :props=\"props\"> {{ props.row.iron }} </q-td> </q-tr></q-table> Alternative custom rows<q-table :data=\"tableData\" :columns=\"columns\" title=\"Click on a row\" dark class=\"bg-black\" color=\"amber\" row-key=\"name\"> <q-tr slot=\"body\" slot-scope=\"props\" :props=\"props\" @click.native=\"rowClick(props.row)\" class=\"cursor-pointer\"> <q-td v-for=\"col in props.cols\" :key=\"col.name\" :props=\"props\"> # {{ col.value }} # </q-td> </q-tr></q-table> Custom header (has tooltips)<q-table :data=\"tableData\" :columns=\"columns\" row-key=\"name\"> <tr slot=\"header\" slot-scope=\"props\"> <q-th key=\"desc\" :props=\"props\"> Dessert <q-tooltip>Pick a desert</q-tooltip> </q-th> <q-th key=\"calories\" :props=\"props\"> Calories <q-tooltip>These are the calories</q-tooltip> </q-th> <q-th key=\"fat\" :props=\"props\"> Fat <q-tooltip>This is the fat</q-tooltip> </q-th> <q-th key=\"carbs\" :props=\"props\"> Carbs <q-tooltip>These are the carbohydrates</q-tooltip> </q-th> <q-th key=\"protein\" :props=\"props\"> Protein <q-tooltip>These are the proteins</q-tooltip> </q-th> <q-th key=\"sodium\" :props=\"props\"> Sodium <q-tooltip>This is the sodium</q-tooltip> </q-th> <q-th key=\"calcium\" :props=\"props\"> Calcium <q-tooltip>This is the calcium</q-tooltip> </q-th> <q-th key=\"iron\" :props=\"props\"> Iron <q-tooltip>This is the iron</q-tooltip> </q-th> </tr></q-table> Alternative custom header<q-table :data=\"tableData\" :columns=\"columns\" row-key=\"name\"> <q-tr slot=\"header\" slot-scope=\"props\" :props=\"props\"> <q-th v-for=\"col in props.cols\" :key=\"col.name\" :props=\"props\"> # {{ col.label }} # </q-th> </q-tr></q-table> Custom header & rows with selection & expandable rows<q-table :data=\"tableData\" :columns=\"columns\" selection=\"multiple\" :selected.sync=\"selected\" row-key=\"name\"> <q-tr slot=\"header\" slot-scope=\"props\"> <q-th auto-width> <q-checkbox v-if=\"props.multipleSelect\" v-model=\"props.selected\" indeterminate-value=\"some\" /> </q-th> <q-th v-for=\"col in props.cols\" :key=\"col.name\" :props=\"props\"> {{ col.label }} </q-th> </q-tr> <template slot=\"body\" slot-scope=\"props\"> <q-tr :props=\"props\"> <q-td auto-width> <q-checkbox color=\"primary\" v-model=\"props.selected\" /> </q-td> <q-td key=\"desc\" :props=\"props\"> <q-checkbox color=\"primary\" v-model=\"props.expand\" checked-icon=\"remove\" unchecked-icon=\"add\" class=\"q-mr-md\" /> {{ props.row.name }} </q-td> <q-td key=\"calories\" :props=\"props\">{{ props.row.calories }}</q-td> <q-td key=\"fat\" :props=\"props\">{{ props.row.fat }}</q-td> <q-td key=\"carbs\" :props=\"props\">{{ props.row.carbs }}</q-td> <q-td key=\"protein\" :props=\"props\">{{ props.row.protein }}</q-td> <q-td key=\"sodium\" :props=\"props\">{{ props.row.sodium }}</q-td> <q-td key=\"calcium\" :props=\"props\">{{ props.row.calcium }}</q-td> <q-td key=\"iron\" :props=\"props\"> <q-chip small square color=\"amber\">{{ props.row.iron }}</q-chip> </q-td> </q-tr> <q-tr v-show=\"props.expand\" :props=\"props\"> <q-td colspan=\"100%\"> <div class=\"text-left\">This is expand slot for row above: {{ props.row.name }}.</div> </q-td> </q-tr> </template></q-table>"},{"title":"Datetime Picker","updated":"2018-07-23T16:37:49.839Z","permalink":"https://v0-16.quasar-framework.org/components/datetime-picker.html","text":"The DatetimePicker component provides a method to input dates and time or both. There is also one more version available: Datetime Input. You’ll notice in the demos that the iOS and Material Datetime pickers look and act totally different, just like their native counterparts. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QDatetimePicker']} Basic Usage<!-- Only Date --><q-datetime-picker v-model=\"model\" type=\"date\" /><!-- Only Time --><q-datetime-picker v-model=\"model\" type=\"time\" /><!-- Date & Time --><q-datetime-picker v-model=\"model\" type=\"datetime\" /> InternationalizationThe day and month names are taken care of by default through Quasar I18n. If your desired language pack is missing, please provide a PR for it. Vue PropertiesSupports v-model which must be a String, Number or Date Object. Vue Property Type Description type String One of date, time or datetime. Default is date. readonly Boolean If set to true, component is displayed as read-only. disable Boolean If set to true, component is disabled and the user cannot change model. minimal Boolean (v0.15.9+) Don’t display header. min String Optional minimum value it can take. Has same format as Datetime model. max String Optional maximum value it can take. Has same format as Datetime model. default-view String One of ‘year’, ‘month’, ‘day’, ‘hour’, ‘minute’. default-value String/Number/Date Default date/time for picker when model is not yet set. display-value String Text to display on input frame. Supersedes ‘placeholder’. first-day-of-week Number 0-6, 0 - Sunday, 1 Monday, …. format-model String Data type of model (useful especially when starting out with undefined or null). One of ‘auto’, ‘date’, ‘number’, ‘string’. color String One from Quasar Color Palette. dark Boolean Is component rendered on a dark background? format24h Boolean Override default i18n setting. Use 24 hour time for Material picker instead of AM/PM system which is default. Lazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-datetime-picker type=\"date\" :value=\"model\" @change=\"val => { model = val }\"/> Vue Methods Vue Method Description setYear(val) Sets year. setMonth(val) Sets month. setDay(val) Sets day. setHour(val) Sets hour. setMinute(val) Sets minute. setView(val) Sets view. One of ‘year’, ‘month’, ‘day’, ‘hour’, ‘minute’. Notice that depending of type prop, some may not be available. clear() Sets model to empty string (removes current value). Vue Events Vue Event Description @input(newVal) Triggered on immediate model value change. @change(newVal) Triggered on lazy model value change. The ModelQuasar uses its own date utility to work with date values within the model of the component. IMPORTANTThe model (variable binded to v-model) must either be empty (undefined) or a string in the form of a valid ISO 8601 datetime value, like 2016-10-24T10:40:14.674Z. It can also be a shorter derivative of this string, like 2016-10-24 or 2016-10-24T10:40. The value can also be a Unix Timestamp (including milliseconds), like 1477298414674. Last but not least, it can also be an instance of the Javascript Date Object, like new Date(). For more information about how Quasar works with dates, please refer to the Handling JS Date documentation page. Here are a few examples of setting up the value prop: <template> <q-datetime-picker v-model=\"model\" type=\"datetime\" /></template><script>// ....export default { data () { return { model: undefined // empty value // OR model: new Date() // as in \"right this moment\" // OR model: 1477298414674 // Unix Timestamp with milliseconds // OR model: '2016-10-24T10:40:14.674Z' // full ISO 8601 compliant value // OR model: `2016-10-24` // Any dirivative of a valid ISO 8601 datetime value will // also work, like '2016-10-24T10:40:14' // OR model: `2016-10-24T10:40`, // For an ISO 8601 value, the time must be included // A Unix Timestamp will also work. } }, // ...}</script> More ExamplesColoringUse the color and inverted/inverted-light props to control the color.<q-datetime color=\"amber-7\" float-label=\"Float Label\" v-model=\"model\" type=\"date\"/><q-datetime inverted color=\"primary\" float-label=\"Float Label\" v-model=\"model\" type=\"date\"/> Also, if QDatetime is displayed on a dark background, add the dark property.<q-datetime-picker dark color=\"secondary\" /> Usage Inside of a List<q-list> <q-list-header>Date or Time</q-list-header> <q-item> <q-item-side icon=\"access_time\" /> <q-item-main> <q-datetime-picker v-model=\"model\" type=\"time\" /> </q-item-main> </q-item> <q-item> <q-item-side icon=\"update\" /> <q-item-main> <q-datetime-picker v-model=\"model\" type=\"date\" /> </q-item-main> </q-item> <q-item-separator /> <q-list-header>Date & Time</q-list-header> <q-item> <q-item-side icon=\"notifications\" /> <q-item-main> <q-datetime-picker v-model=\"model\" type=\"datetime\" /> </q-item-main> </q-item></q-list>"},{"title":"Chip","updated":"2018-05-18T22:01:01.006Z","permalink":"https://v0-16.quasar-framework.org/components/chip.html","text":"The Chip component is basically a simple UI block entity, representing for example more advanced underlying data, such as a contact, in a compact way. Chips can contain entities such as an avatar, text or an icon, optionally having a pointer too. They can also be closed or removed if configured so. InstallationEdit /quasar.conf.js:framework: { components: ['QChip']} Basic UsageSome basic examples: <!-- icon on left side --><q-chip icon=\"alarm\" color=\"primary\"> q-chip</q-chip><!-- icon on right side --><q-chip icon-right=\"alarm\" color=\"primary\"> q-chip</q-chip><!-- avatar on left side --><q-chip avatar=\"/statics/some.png\" color=\"primary\"> q-chip</q-chip><!-- floating chip applied to a button (v0.15.7+) --><q-btn round dense color=\"dark\" icon=\"announcement\"> <q-chip floating color=\"red\">1</q-chip></q-btn> Vue PropertiesThere are a number of properties available: Vue Property Type Description floating Boolean Allows the chip to float over other elements on top-right side of them. tag Boolean Makes it a “tag” type. detail Boolean Highlights the area on the right (icon or avatar), should there be one. icon String Icon for left side. icon-right String Icon for right side. avatar String URL pointing to statics folder for an image which gets placed on left side. small Boolean Reduces the size of the chip. Makes it compact. Use this or “dense”, but not both. dense Boolean (Quasar v0.15.7+) Makes chip small, with minimum padding. Use this or “small”, but not both. square Boolean Gives the chip right-angled corners. Rounded corners are default. pointing String Adds a carat to the chip, pointing either up, right, down or left. color String The color the chip should be. text-color String Override the text color of the chip. closable Boolean Adds a close button to the right of the chip, which when clicked, will emit @hide event. Vue Events Vue Property Description @hide The close button has been clicked/tapped. @focus The chip has been focused. @click Chip has been clicked/tapped outside of close button. When using closable property a close button will be displayed on the right side. When clicking/tapping on the button the @hide event will be triggered. This does not removes the chip by itself. You will have to handle it yourself. The two events fire independently but not both simultaneously, depending on where the user has clicked/tapped (on close button or anywhere else within the Chip). More ExamplesYou can add the ability to hide the chip too.<q-chip closable color=\"red\"> Joe</q-chip> You can also use a chip to label a button.<q-btn color=\"light\" label=\"Inbox\"> <q-chip floating color=\"primary\">22</q-chip></q-btn> Or to label anything you want, as long as the container has position: relative (hint: use relative-position Quasar CSS helper class):<div class=\"relative-position\"> ....content... <q-chip floating color=\"primary\">22</q-chip></div> You can also use chips as pointing labels.<q-chip pointing=\"up\" color=\"primary\"> Pointing Up</q-chip> You can create advanced label chips, with an avatar/image and a closeable button to delete the chip.<q-chip closable avatar=\"statics/some.png\" color=\"red\"> Joe</q-chip> You can also create chips that look like tags. <q-chip tag color=\"secondary\" icon-right=\"mail\"> New</q-chip> This chip highlights the icon by using the detail property. <q-chip tag color=\"secondary\" detail icon=\"mail\"> 10 emails</q-chip> One more example where we add a shadow to a chip:<q-chip class=\"shadow-1\" square color=\"primary\">10k</q-chip>"},{"title":"Datetime Input","updated":"2018-07-23T16:37:49.838Z","permalink":"https://v0-16.quasar-framework.org/components/datetime-input.html","text":"The Datetime component provides a method to input dates and time or both. There is also one more version available: Datetime Picker. You’ll notice in the demos that the iOS and Material Datetime pickers look and act totally different, just like their native counterparts. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QDatetime']} Basic Usage<!-- Only Date --><q-datetime v-model=\"model\" type=\"date\" /><!-- Only Time --><q-datetime v-model=\"model\" type=\"time\" /><!-- Date & Time --><q-datetime v-model=\"model\" type=\"datetime\" /> InternationalizationThe day and month names are taken care of by default through Quasar I18n. If your desired language pack is missing, please provide a PR for it. Vue PropertiesSupports v-model which must be a String, Number or Date Object. Vue Property Type Description type String One of date, time or datetime. Default is date. clearable Boolean If set to true, the component offers the user an actionable icon to remove the current selection. minimal Boolean (v0.15.9+) Don’t display header. readonly Boolean If set to true, component is displayed as read-only. min String Optional minimum value it can take. Has same format as Datetime model. max String Optional maximum value it can take. Has same format as Datetime model. default-view String One of ‘year’, ‘month’, ‘day’, ‘hour’, ‘minute’. default-value String/Number/Date Default date/time for picker when model is not yet set. display-value String Text to display on input frame. Supersedes ‘placeholder’. first-day-of-week Number 0-6, 0 - Sunday, 1 Monday, …. hide-underline Boolean Hides the bottom border. popover Boolean Always display with a Popover, regardless of Platform. modal Boolean Always display with a Modal, regardless of Platform. format String Format as described on Handling JS Date page under Format for display section. format-model String Data type of model (useful especially when starting out with undefined or null). One of ‘auto’, ‘date’, ‘number’, ‘string’. format24h Boolean Override default i18n setting. Use 24 hour time for Material picker instead of AM/PM system which is default. placeholder String Placeholder text for input frame to use when model is not set (empty). ok-label String Text for the button to accept the input (when using Modal). cancel-label String Text for the button to cancel input with no change (when using Modal). Common input frame properties: Property Type Description prefix String A text that should be shown before the value of model. suffix String A text that should be shown after the value of model. float-label String A text label that will “float” up above the input field, once the input field gets focus. stack-label String A text label that will be shown above the input field and is static. color String One from Quasar Color Palette. inverted Boolean Inverted mode. Color is applied to background instead. inverted-light Boolean Inverted mode with a light color. Color is applied to background instead. dark Boolean Is component rendered on a dark background? align String One of ‘left’, ‘center’ or ‘right’ which determines the text align. disable Boolean If set to true, component is disabled and the user cannot change model. warning Boolean If set to true, the input fields colors are changed to show there is a warning. error Boolean If set to true, the input fields colors are changed to show there is an error. before Array of Objects Icon buttons on left side of input frame. Read below more details. after Array of Objects Icon buttons on right side of input frame. Read below more details. Lazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-datetime type=\"date\" :value=\"model\" @change=\"val => { model = val }\"/> Icon buttonsThis section refers to before and after properties which can add additional buttons as icons to the component. Here is the structure of the two properties: { // required icon icon: String, // required function to call when // icon is clicked/tapped handler: Function, // Optional. Show icon button // if model has a value content: Boolean, // Optional. Show icon button // if model is marked with error error: Boolean} Examples:<!-- Show an icon button (with 'warning' as icon) when there is an error on component (through \"error\" prop)--><q-datetime v-model=\"date\" :error=\"error\" :after=\"[ { icon: 'warning', error: true, handler () { // do something... } } ]\"/><!-- Show an icon button (with 'arrow_forward' as icon) when the model has a non empty value--><q-datetime v-model=\"date\" :after=\"[ { icon: 'arrow_forward', content: true, handler () { // do something... } } ]\"/> Vue Methods Vue Method Description show() Show Popover (on desktop) and Dialog (on mobile) to select date and/or time. Returns a Promise. hide() Hide Popover (on desktop) and Dialog (on mobile) to select date and/or time and execute Function after it’s been hidden. Returns a Promise. toggle() Toggle the Popover or Modal. clear() Sets model to empty string (removes current value). Vue Events Vue Event Description @input(newVal) Triggered on immediate model value change. @change(newVal) Triggered on lazy model value change. @clear(clearVal) Triggered when the model is cleared. @blur Triggered when the modal/ popup is closed. @focus Triggered when the modal/ popup is opened. The ModelQuasar uses its own date utility to work with date values within the model of the component. IMPORTANTThe model (variable binded to v-model) must either be empty (undefined) or a string in the form of a valid ISO 8601 datetime value, like 2016-10-24T10:40:14.674Z. It can also be a shorter derivative of this string, like 2016-10-24 or 2016-10-24T10:40. The value can also be a Unix Timestamp (including milliseconds), like 1477298414674. Last but not least, it can also be an instance of the Javascript Date Object, like new Date(). For more information about how Quasar works with dates, please refer to the Handling JS Date documentation page. Here are a few examples of setting up the value prop: <template> <q-datetime v-model=\"model\" type=\"datetime\" /></template><script>// ....export default { data () { return { model: undefined // empty value // OR model: new Date() // as in \"right this moment\" // OR model: 1477298414674 // Unix Timestamp with milliseconds // OR model: '2016-10-24T10:40:14.674Z' // full ISO 8601 compliant value // OR model: `2016-10-24` // Any dirivative of a valid ISO 8601 datetime value will // also work, like '2016-10-24T10:40:14' // OR model: `2016-10-24T10:40`, // For an ISO 8601 value, the time must be included // A Unix Timestamp will also work. } }, // ...}</script> More ExamplesColoringUse the color and inverted/inverted-light props to control the color.<q-datetime color=\"amber-7\" float-label=\"Float Label\" v-model=\"model\" type=\"date\"/><q-datetime inverted color=\"primary\" float-label=\"Float Label\" v-model=\"model\" type=\"date\"/> Also, if QDatetime is displayed on a dark background, add the dark property.<q-datetime dark color=\"secondary\" /> Usage Inside of a List<q-list> <q-list-header>Date or Time</q-list-header> <q-item> <q-item-side icon=\"access_time\" /> <q-item-main> <q-datetime v-model=\"model\" type=\"time\" /> </q-item-main> </q-item> <q-item> <q-item-side icon=\"update\" /> <q-item-main> <q-datetime v-model=\"model\" type=\"date\" /> </q-item-main> </q-item> <q-item-separator /> <q-list-header>Date & Time</q-list-header> <q-item> <q-item-side icon=\"notifications\" /> <q-item-main> <q-datetime v-model=\"model\" type=\"datetime\" /> </q-item-main> </q-item></q-list>"},{"title":"Dialog","updated":"2018-07-23T16:37:49.840Z","permalink":"https://v0-16.quasar-framework.org/components/dialog.html","text":"Quasar Dialogs are a great way to offer the user the ability to choose a specific action or list of actions. They also can provide the user with important information, or require them to make a decision (or multiple decisions). From a UI perspective, you can think of Dialogs as a type of “floating” modal, which covers only a portion of the screen. This means Dialogs should only be used for quick actions, like password verification, small App notifications or quick options. More in depth user flows should be reserved for Modals. Dialogs can be used either as a component in your Vue file templates (for complex use-cases, like specific form components with validation etc), or as a globally available method (for some basic use cases, equivalent to native JS alert(), prompt(), …). Basic Usage as a MethodFirst, we install it: Edit /quasar.conf.js:framework: { plugins: ['Dialog']} Now let’s see how we can use it:// outside of a Vue fileimport { Dialog } from 'quasar'(Promise) Dialog.create(configObj)// inside of a Vue file(Promise) this.$q.dialog(configObj) Basic syntax for the config object:this.$q.dialog({ title: 'Warning', message: 'You are about to run out of disk space.', // optional color: 'primary', // optional; we want an \"OK\" button ok: true, // takes i18n value, or String for \"OK\" button label // optional; we want a \"Cancel\" button cancel: true, // takes i18n value, or String for \"Cancel\" button label // optional; prevent user dismissal when not clicking on a Dialog button preventClose: true, noBackdropDismiss: false, // gets set to \"true\" automatically if preventClose is \"true\" noEscDismiss: false, // gets set to \"true\" automatically if preventClose is \"true\" // optional; stacks button vertically instead of horizontally (default) stackButtons: true, // optional; a position of the Dialog (top, bottom, left, right) position: 'top', // optional; show an input box (make Dialog similar to a JS prompt) prompt: { model: '', type: 'text' // optional }, // optional; show a radio, checkbox or toggle options: { type: 'radio', // or 'checkbox' / 'toggle' model: 'opt2', // Array when checkbox/toggle! (like '[]') items: [ {label: 'Option 1', value: 'opt1', color: 'secondary'}, {label: 'Option 2', value: 'opt2'}, {label: 'Option 3', value: 'opt3'} ] }}) IMPORTANTWhen user hits the phone/tablet back button (only for Cordova apps), the Action Sheet will get closed automatically.Also, when on a desktop browser, hitting the <ESCAPE> key also closes the Action Sheet. Handling OutcomeThe returning object when creating an ActionSheet is a Promise, so you can leverage the Promise API to handle the outcome: this.$q.dialog({...}) .then(() => { // Picked \"OK\" }) .catch(() => { // Picked \"Cancel\" or dismissed })// OR with async/await:async showActionSheet () { try { await this.$q.dialog({...}) // user picked \"OK\" } catch () { // Picked \"Cancel\" or dismissed }} ExamplesAlertthis.$q.dialog({ title: 'Alert', message: 'Modern HTML5 front-end framework on steroids.'}) Confirmthis.$q.dialog({ title: 'Confirm', message: 'Modern HTML5 front-end framework on steroids.', ok: 'Agree', cancel: 'Disagree'}).then(() => { this.$q.notify('Agreed!')}).catch(() => { this.$q.notify('Disagreed...')}) Promptthis.$q.dialog({ title: 'Prompt', message: 'Modern front-end framework on steroids.', prompt: { model: '', type: 'text' // optional }, cancel: true, color: 'secondary'}).then(data => { this.$q.notify(`You typed: \"${data}\"`)}).catch(() => { this.$q.notify('Ok, no mood for talking, right?')}) Single Choice Selectionthis.$q.dialog({ title: 'Options', message: 'Modern front-end framework on steroids.', options: { type: 'radio', model: 'opt2', items: [ {label: 'Option 1', value: 'opt1', color: 'secondary'}, {label: 'Option 2', value: 'opt2'}, {label: 'Option 3', value: 'opt3'} ] }, cancel: true, preventClose: true, color: 'secondary'}).then(data => { this.$q.notify(`You selected: ${data}`)}) Multiple Choice Selectionthis.$q.dialog({ title: 'Options', message: 'Modern front-end framework on steroids.', options: { type: 'checkbox', model: [], items: [ {label: 'Option 1', value: 'opt1', color: 'secondary'}, {label: 'Option 2', value: 'opt2'}, {label: 'Option 3', value: 'opt3'} ] }, cancel: true, preventClose: true, color: 'secondary'}).then(data => { this.$q.notify(`You selected: ${JSON.stringify(data)}`)}) Stacked Buttonsthis.$q.dialog({ title: 'Stacked buttons', message: 'Go to a movie.', ok: 'Yes, please!', cancel: 'Uhm, nope', stackButtons: true}).then(() => { this.$q.notify('Agreed!')}).catch(() => { this.$q.notify('Disagreed...')}) Custom Buttonsthis.$q.dialog({ title: 'Custom buttons', message: 'Go to a movie.', ok: { push: true, label: 'Yes, please!' }, cancel: { push: true, color: 'negative', label: 'Uhm, nope' }}).then(() => { this.$q.notify('Agreed!')}).catch(() => { this.$q.notify('Disagreed...')}) Prevent accidental closethis.$q.dialog({ title: 'Prevent close', message: 'This dialog cannot be dismissed by clicking/tapping on the background overlay.', ok: true, cancel: true, preventClose: true}).then(() => { this.$q.notify('You said OK!')}).catch(() => { this.$q.notify(`You didn't agree`)}) Basic Usage As a ComponentFirst, we install it: Edit /quasar.conf.js:framework: { components: ['QDialog']} Now let’s see how we can use it:<template> <q-dialog v-model=\"customDialogModel\" stack-buttons prevent-close @ok=\"onOk\" @cancel=\"onCancel\" @show=\"onShow\" @hide=\"onHide\" > <!-- This or use \"title\" prop on <q-dialog> --> <span slot=\"title\">Favorite Superhero</span> <!-- This or use \"message\" prop on <q-dialog> --> <span slot=\"message\">What is your superhero of choice?</span> <div slot=\"body\"> <q-field icon=\"account_circle\" helper=\"We need your name so we can send you to the movies.\" label=\"Your name\" :label-width=\"3\" > <q-input v-model=\"name\" /> </q-field> </div> <template slot=\"buttons\" slot-scope=\"props\"> <q-btn color=\"primary\" label=\"Choose Superman\" @click=\"choose(props.ok, 'Superman')\" /> <q-btn color=\"black\" label=\"Choose Batman\" @click=\"choose(props.ok, 'Batman')\" /> <q-btn color=\"negative\" label=\"Choose Spiderman\" @click=\"choose(props.ok, 'Spiderman')\" /> <q-btn flat label=\"No thanks\" @click=\"props.cancel\" /> </template> </q-dialog></template><script>export default { data () { return { // model for Dialog example customDialogModel: false, name: '' } }, methods: { // when props.ok() gets called onOk (data) { }, // when props.cancel() gets called onCancel () { }, // when we show it to the user onShow () { }, // when it gets hidden onHide () { }, // custom handler async choose (okFn, hero) { if (this.name.length === 0) { this.$q.dialog({ title: 'Please specify your name!', message: `Can't buy tickets without knowing your name.` }) } else { await okFn() this.$q.notify(`Ok ${this.name}, going with ${hero}`) } } }}</script> QDialog Vue Properties Vue Property Type Description title String Title of Dialog. message String Message of Dialog. prompt Object Check below table for details. options Object Check below table for details. ok Boolean/String/Object Do we have an OK button? Optionally specify which label to use for it OR the button props in an Object. cancel Boolean/String/Object Do we have a Cancel button? Optionally specify which label to use for it OR the button props in an Object. stack-buttons Boolean Stack buttons vertically instead of default horizontally. prevent-close Boolean Dialog can be dismissed only by clicking/tapping on OK/Cancel buttons. no-esc-dismiss Boolean “ESC” key won’t dismiss the Dialog. Overriden to “true” if “prevent-close” is “true”. no-backdrop-dismiss Boolean Click/Tap on backdrop won’t dismiss Dialog. Overriden to “true” if “prevent-close” is “true”. position String Position of Dialog (top, bottom, left, right). color String A color from Quasar Color Palette. Prompt Object:{ model: '..' // String, type: 'text' // optional} Options Object:{ type: 'radio', // or 'checkbox', 'toggle' model: 'opt2', // Array when checkbox / toggle (like '[]') items: [ {label: 'Option 1', value: 'opt1', color: 'secondary'}, {label: 'Option 2', value: 'opt2'}, {label: 'Option 3', value: 'opt3'} ]} QDialog Vue Events Vue Property Description @ok When “props.ok()” got called. @cancel When “props.cancel()” got called. @show Dialog has just been showed to the user. @hide Dialog has been hidden (regardless of outcome). @escape-key Dialog dismissed with ESCAPE key."},{"title":"Dropdown Button","updated":"2018-07-23T16:37:49.841Z","permalink":"https://v0-16.quasar-framework.org/components/dropdown-button.html","text":"QBtnDropdown is a very convenient dropdown button. Goes very well with QList as dropdown content, but it’s by no means limited to it. InstallationEdit /quasar.conf.js:framework: { components: ['QBtnDropdown']} Basic usageSimple dropdown menu<q-btn-dropdown label=\"Button\"> <!-- dropdown content --> <q-list link> <q-item> <q-item-main> <q-item-tile label>Item</q-item-tile> </q-item-main> </q-item> </q-list></q-btn-dropdown> Use the split prop to separate target areas for opening dropdown and triggering @click event <q-btn-dropdown split label=\"Button\" @click=\"handlerFunction\"> <!-- dropdown content --> <q-list link> <q-item> <q-item-main> <q-item-tile label>Item</q-item-tile> </q-item-main> </q-item> </q-list></q-btn-dropdown> Vue PropertiesAll props except split are shared with QBtn. Vue Property Type Description split Boolean Use a split QBtnDropdown icon String Name of the icon to use. icon-right String Name of the icon to place on right side of button. (only usable with split set to true) loading Boolean Display a spinner, if true. Can be optionally used along v-model. Check Button with Progress section. percentage Number Optional property for displaying a determinate progress. Use along loading. dark-percentage Boolean Optional property for displaying a determinate progress on a light button color. Use along loading and percentage. disable Boolean The button is disabled, if true. @click event won’t be triggered while in this state. label String/Number Button label. tabindex Number Set explicit tab index. repeat-timeout Number/Function Enables multiple @click events on click/tap and hold. Function gets a Number (timesTriggered) as parameter. wait-for-ripple Boolean Wait for ripple then before emitting @click event. Mat theme only. content-class String/Array/Object Classes applied to the Popover container. content-style String/Array/Object Style applied to the Popover container. Apearance Vue Property Type Description size String Button size. One of xs, sm, md, lg, xl, or a css string size eg. 25px, 2rem, 3vw. color String A color from Quasar Color Palette. text-color String A color from Quasar Color Palette. align String Label/Content alignment. One of left, center, right, around, between. dense Boolean Dense Button. round Boolean Set true, if you want a round button. outline Boolean Set true, if you want an outlined button. flat Boolean Set true, if you want a flat button. push Boolean Set true, if the button should have a push effect. rounded Boolean Set true, if the square button should have rounded corners. glossy Boolean Set true, if the button should be glossy. fab Boolean Floating Action Button. See fab-mini Boolean Smaller Floating Action Button. no-wrap Boolean Prevent text wrapping no-caps Boolean Set true, if you don’t want button content/label to be transformed to uppercase letter on Material Theme. no-ripple Boolean Disable Material Ripple. Mat theme only. Vue Events Vue Event Description @click Triggered on button click/tap, if button is not disabled. More examplesComplete example with QList: Note the use of the v-close-overlay directive to close the dropdown on click. Don’t forget to register it in quasar.conf.js <q-btn-dropdown color=\"primary\" label=\"Dropdown\"> <q-list link> <q-item v-for=\"n in 2\" :key=\"`1.${n}`\" v-close-overlay @click.native=\"handlerFunction\"> <q-item-side icon=\"folder\" inverted color=\"primary\" /> <q-item-main> <q-item-tile label>Photos</q-item-tile> <q-item-tile sublabel>February 22, 2016</q-item-tile> </q-item-main> <q-item-side right icon=\"info\" color=\"amber\" /> </q-item> <q-item-separator inset /> <q-list-header inset>Files</q-list-header> <q-item v-close-overlay @click.native=\"handlerFunction\"> <q-item-side icon=\"assignment\" inverted color=\"secondary\" /> <q-item-main> <q-item-tile label>Vacation</q-item-tile> <q-item-tile sublabel>February 22, 2016</q-item-tile> </q-item-main> <q-item-side right icon=\"info\" color=\"amber\" /> </q-item> </q-list></q-btn-dropdown>"},{"title":"Cookies","updated":"2018-05-18T22:01:01.010Z","permalink":"https://v0-16.quasar-framework.org/components/cookies.html","text":"This is a wrapper over the standardized document.cookie. NOTEIn addition, you can read and write cookies using JSON objects. InstallationEdit /quasar.conf.js:framework: { plugins: ['Cookies']} Read a Cookie// outside of a Vue fileimport { Cookies } from 'quasar'var value = Cookies.get('cookie_name') When cookie is not set, the return value is undefined. // inside of a Vue filethis.$q.cookies.get('cookie_name') Read All Cookies// outside of a Vue fileimport { Cookies } from 'quasar'var cookies = Cookies.all() cookies variable will be an object with key-value pairs (cookie_name : cookie_value). // inside of a Vue filethis.$q.cookies.all() Verify if Cookie is Set// outside of a Vue fileimport { Cookies } from 'quasar'(Boolean) Cookies.has('cookie_name') // inside of a Vue filethis.$q.cookies.has('cookie_name') Write a Cookie// outside of a Vue fileimport { Cookies } from 'quasar'Cookies.set('cookie_name', cookie_value, options) options is an Object which can have the following properties: expire, path, domain, secure. They are explained below. // outside of a Vue fileimport { Cookies } from 'quasar'Cookies.set('quasar', 'framework', { secure: true}) // inside of a Vue filethis.$q.cookies.set('cookie_name', cookie_value, options) Option expiresexpires: 10 Define lifetime of the cookie. Value can be a Number which will be interpreted as days from time of creation or a Date object. If omitted, the cookie becomes a session cookie. Option pathpath: '/' Define the path where the cookie is valid. By default the path of the cookie is the path of the page where the cookie was created (standard browser behavior). If you want to make it available for instance across the entire domain use path: ‘/‘. Default: path of page where the cookie was created. Option domaindomain: 'quasar-framework.org' Define the domain where the cookie is valid. Default: domain of page where the cookie was created. Option securesecure: true If true, the cookie transmission requires a secure protocol (HTTPS) and will NOT be sent over HTTP. Default value is false. Remove a Cookie// outside of a Vue fileimport { Cookies } from 'quasar'Cookies.remove('cookie_name') // inside of a Vue filethis.$q.cookies.remove('cookie_name')"},{"title":"Editor (WYSIWYG)","updated":"2018-07-23T16:37:49.842Z","permalink":"https://v0-16.quasar-framework.org/components/editor---wysiwyg.html","text":"QEditor is a WYSIWYG (“what you see is what you get”) editor component. WARNINGUsing v-html on the resulting v-model renders you vulnerable to Cross Site Scripting attacks.If the content is user generated, be sure to sanitize it either on render or server side. InstallationEdit /quasar.conf.js:framework: { components: ['QEditor']} Basic Usage<q-editor v-model=\"model\" /> InternationalizationThe tooltips content of QEditor are part of Quasar I18n. If your desired language pack is missing, please provide a PR for it. Vue PropertiesSupports v-model which should be binded to a String in your scope, which is essentially HTML code. Vue Property Type Description readonly Boolean Sets editor in readonly mode. disable Boolean Sets editor in disable mode. min-height String CSS unit for minimum height of the input area. max-height String CSS unit for maximum height of the input area. definitions Object Object with definitions (see next sections). fonts Object Object with fonts definitions (see next sections). toolbar Array Array of Arrays of Objects/Strings with toolbar commands (see next sections). toolbar-color String Color (from Quasar Palette) of toolbar commands. toolbar-text-color String Text color (from Quasar Palette) of toolbar commands. toolbar-toggle-color String Color (from Quasar Palette) of toolbar commands when in “active” state. toolbar-bg String Toolbar background color (from Quasar Palette). toolbar-flat Boolean Toolbar buttons become of “flat” type. toolbar-outline Boolean Toolbar buttons become of “outline” type. toolbar-push Boolean Toolbar buttons become of “push” type. toolbar-rounded Boolean Toolbar buttons become of “rounded” type. content-style Object CSS Style in Object format for the input area. content-class Object/Array/String CSS classes for the input area. DefinitionsBy default, QEditor offers most if not all the commands you’d need in a WYSIWYG editor: bold, italic, strike, underline, unordered (list), ordered (list), subscript, superscript, link, fullscreen, quote, left (align), center (align), right (align), justify (align), print, outdent, indent, removeFormat, hr, undo, redo, h1 to h6, p (paragraph), code (code paragraph), size-1 to size-7. Each of these commands are pre-configured with icons with tooltips. However, if you want to override some of their settings you can do so with the help of definitions Object property. <!-- overriding \"bold\" command to include a label instead of an icon and also changing its tooltip-->:definitions=\"{ bold: {label: 'Bold', icon: null, tip: 'My bold tooltip'}}\" Example adding your own definition. In this case make sure you don’t overlap the default commands:<!-- we can later use \"save\" and \"upload\" in \"toolbar\" prop -->:definitions=\"{ save: { tip: 'Save your work', icon: 'save', label: 'Save', handler: saveWork }, upload: { tip: 'Upload to cloud', icon: 'cloud_upload', label: 'Upload', handler: uploadIt }}\"<!-- Notice the handlers. It references methods in your Vue scope for when toolbar commands using these definitions are clicked/tapped.--> Command definitions properties: Property Name Type Description label String Label of button icon String Icon of button tip String Tooltip of button cmd String Either this or “handler” is required. One of the commands described at the beginning of this section. handler Function Either this or “cmd” is required. Function for when button gets clicked/tapped. disable Boolean/Function Is button disabled? If specifying a function, return a Boolean value. Another example of adding a definition using a QEditor command::definitions=\"{ customItalic: { cmd: 'italic', icon: 'camera_enhance', tip: 'Italic' }}\" FontsExample of specifying fonts so that you can later use them as options in the toolbar. These become “commands” themselves, so make sure you don’t overlap any of the default commands.:fonts=\"{ arial: 'Arial', arial_black: 'Arial Black', comic_sans: 'Comic Sans MS'}\" Then in toolbar, you can reference them. The example below creates a dropdown.:toolbar=\"[ ..., [{ label: $q.i18n.editor.defaultFont, icon: $q.icon.editor.font, fixedIcon: true, list: 'no-icons', options: ['default_font', 'arial', 'arial_black', 'comic_sans'] }]]\" ToolbarThe toolbar property is the place where you configure how your toolbar looks like, based on your own commands and the default ones. It’s an Array of Arrays of Object/Strings. Each sub-array represents a Button Group. [ // array of button groups [ ... ], // button group [ ... ], // button group ...] :toolbar=\"[ ['bold', 'italic', 'strike', 'underline'], ['token', 'hr', 'link', 'custom_btn'], ['print', 'fullscreen']]\" Take a look at the demo and the examples below to see how you can also specify dropdowns. You can make dropdowns as single selection, meaning only one command from its list can get into “active” state.<!-- Example of a dropdown with text alignment commands -->:toolbar=\"[ [ { label: $q.i18n.editor.align, icon: $q.icon.editor.align, fixedLabel: true, list: 'only-icons', options: ['left', 'center', 'right', 'justify'] } ]]\" Vue Events Vue Event Description @input Triggered when input area content changes. ExamplesComplex Example<q-editor v-model=\"model\" :toolbar=\"[ ['bold', 'italic', 'strike', 'underline', 'subscript', 'superscript'], ['token', 'hr', 'link', 'custom_btn'], ['print', 'fullscreen'], [ { label: $q.i18n.editor.formatting, icon: $q.icon.editor.formatting, list: 'no-icons', options: ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'code'] }, { label: $q.i18n.editor.fontSize, icon: $q.icon.editor.fontSize, fixedLabel: true, fixedIcon: true, list: 'no-icons', options: ['size-1', 'size-2', 'size-3', 'size-4', 'size-5', 'size-6', 'size-7'] }, { label: $q.i18n.editor.defaultFont, icon: $q.icon.editor.font, fixedIcon: true, list: 'no-icons', options: ['default_font', 'arial', 'arial_black', 'comic_sans', 'courier_new', 'impact', 'lucida_grande', 'times_new_roman', 'verdana'] }, 'removeFormat' ], ['quote', 'unordered', 'ordered', 'outdent', 'indent'], [ { label: $q.i18n.editor.align, icon: $q.icon.editor.align, fixedLabel: true, list: 'only-icons', options: ['left', 'center', 'right', 'justify'] }, { label: $q.i18n.editor.align, icon: $q.icon.editor.align, fixedLabel: true, options: ['left', 'center', 'right', 'justify'] } ], ['undo', 'redo'] ]\" :fonts=\"{ arial: 'Arial', arial_black: 'Arial Black', comic_sans: 'Comic Sans MS', courier_new: 'Courier New', impact: 'Impact', lucida_grande: 'Lucida Grande', times_new_roman: 'Times New Roman', verdana: 'Verdana' }\"/> Overriding & extending default toolbar buttons definitionsThis particular case: overrides bold & italic default definitions (label, icon, their tooltips) adds a new custom command which basically is same as “italic” adds “save”, “upload” & “spellcheck” commands adds a disabled button adds a custom “Import” button <q-editor v-model=\"model\" :toolbar=\"[ ['bold', 'italic'], ['customItalic'], ['save', 'upload'], ['spellcheck'], ['disabledButton'], ['custom_btn'] ]\" :definitions=\"{ bold: {cmd: 'bold', label: 'Bold', icon: null, tip: 'My bold tooltip'}, italic: {cmd: 'italic', icon: 'border_color', tip: 'My italic tooltip'}, customItalic: {cmd: 'italic', icon: 'camera_enhance', tip: 'Italic'}, save: {tip: 'Save your work', icon: 'save', label: 'Save', handler: saveWork}, upload: {tip: 'Upload to cloud', icon: 'cloud_upload', label: 'Upload', handler: upload}, spellcheck: {tip: 'Run spell-check', icon: 'spellcheck', handler: spellCheck}, disabledButton: {tip: 'I am disabled...', disable: true, icon: 'cloud_off'} }\"> <q-btn slot=\"custom_btn\" dense color=\"secondary\" icon=\"import_contacts\" label=\"Import\" @click=\"importSomething\" /></q-editor> Custom Style<q-editor v-model=\"model\" toolbar-text-color=\"white\" toolbar-toggle-color=\"yellow-8\" toolbar-flat toolbar-bg=\"primary\" :toolbar=\"[ ['bold', 'italic', 'underline'], [{ label: $q.i18n.editor.formatting, icon: $q.icon.editor.formatting, list: 'no-icons', options: ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'code'] }] ]\"/> Types of dropdowns<q-editor v-model=\"model\" :toolbar=\"[ [ { label: 'Icons & Label', icon: 'filter_1', fixedLabel: true, fixedIcon: true, options: ['bold', 'italic', 'strike', 'underline'] } ], [ { label: 'Only label', icon: 'filter_2', fixedLabel: true, fixedIcon: true, list: 'no-icons', options: ['bold', 'italic', 'strike', 'underline'] } ], [ { label: 'Only icons', icon: 'filter_3', fixedLabel: true, fixedIcon: true, list: 'only-icons', options: ['bold', 'italic', 'strike', 'underline'] } ] ]\"/> Dropdowns with exclusive optionsUser can pick only one option from each dropdown. First has icon and label changing based on current selection Second has fixed label but dynamic icon Third has fixed icon but dynamic label <q-editor v-model=\"model\" :toolbar=\"[ [ { label: 'Dynamic label', icon: 'help_outline', options: ['left', 'center', 'right', 'justify'] } ], [ { label: 'Static label', fixedLabel: true, options: ['left', 'center', 'right', 'justify'] } ], [ { label: 'Some label', icon: 'account_balance', fixedIcon: true, options: ['left', 'center', 'right', 'justify'] } ] ]\"/>"},{"title":"Date Utils","updated":"2018-07-09T22:30:23.746Z","permalink":"https://v0-16.quasar-framework.org/components/date-utils.html","text":"Quasar provides a set of useful functions to manipulate JS Date easily in most use cases, without the high additional cost of integrating dedicated libraries like moment. Most Quasar date functions take as parameter either a Unix timestamp or a String representing a date which needs to be parsable by the native JS Date constructor. Some examples: 1497159857411, Sun Jun 11 2017 08:44:42 GMT+0300, 2017-06-16. Returned values are all JS Dates. Get familiar with JS native Date class, which is very powerful, and remember that you don’t need solutions like Momentjs which add hundreds of minified KB to your bundle. Helping Tree-ShakeYou will notice all examples import date Object from Quasar. However, if you need only one method from it, then you can use ES6 destructuring to help Tree Shaking embed only that method and not all of date. Example with addToDate():// we import all of `date`import { date } from 'quasar'// destructuring to keep only what is neededconst { addToDate } = datelet newDate = addToDate(new Date(), { days: 7, months: 1 }) Format for displayIt takes a string of tokens and replaces them with their corresponding date values:import { date } from 'quasar'let timeStamp = Date.now()let formattedString = date.formatDate(timeStamp, 'YYYY-MM-DDTHH:mm:ss.SSSZ') For i18n, you can use a third parameter:let formattedString = date.formatDate(timesStamp, 'MMMM - dddd', { dayNames: ['Duminica', 'Luni', /* and all the rest of days - remember starting with Sunday */], monthNames: ['Ianuarie', 'Februarie', /* and all the rest of months */]}) Available format tokens: Unit Formats available Year YY: 70 71 … 29 30YYYY: 1970 1971 … 2029 2030 Month M: 1 2 … 11 12MM: 01 02 … 11 12MMM: Jan Feb … Nov DecMMMM: January February … November December Quarter Q: Quarter number 1 2 3 4Qo: Quarter number 1st 2nd 3rd 4th Day of Month D: 1 2 … 30 31Do: 1st 2nd … 30th 31stDD: 01 02 … 30 31 Day of Year DDD: 1 2 … 364 365DDDD: 001 002 … 364 365 Day of Week d: 0 1 … 5 6dd: Su Mo … Fr Saddd: Sun Mon … Fri Satdddd: Sunday Monday … Friday Saturday Day of Week (ISO) E: 1 2 … 6 7 Week of Year w: 1 2 … 52 53ww: 01 02 … 52 53 Hour H: 0 1 … 22 23HH: 00 01 … 22 23h: 0 … 11 12hh: 01 02 … 11 12 Minute m: 0 1 … 58 59mm: 00 01 … 58 59 Second s: 0 1 … 58 59ss: 00 01 … 58 59 Fractional Second S: 0 1 … 8 9SS: 00 01 … 98 99SSS: 000 001 … 998 999 Timezone offset Z: -07:00 -06:00 … +06:00 +07:00ZZ: -0700 -0600 … +0600 +0700 AM/PM A: AM, PMa: am, pmaa: a.m, p.m Unix Timestamp X: 1360013296x (ms): 1360013296123 Manipulate datesCreateTry to create dates with native JS Date class like so:let date = new Date(); The following method is just a wrapper to help you in cases where you just need current time but with a different year, or month, or second etc. import { date } from 'quasar'let newDate = date.buildDate({ year:2010, day:5, hours:15, milliseconds:123}) You can pass a third argument (a boolean) for setting UTC time (true) instead of local time. The object literal provided can contain the following keys (all are optional): Key Description milliseconds for the milliseconds component of the date/time seconds for the seconds component of the date/time minutes for the minutes component of the date/time hours for the hours component of the date/time day for the day component of the date/time month for the month component of the date/time year for the year component of the date/time ValidateTo check if a date string is valid use:import { date } from 'quasar'let dateString = 'Wed, 09 Aug 1995 00:00:00 GMT'if (date.isValid(dateString)) { // Do something with date string} Add/SubtractTo add/subtract some duration to/from a date use:import { date } from 'quasar'let newDate = new Date(2017, 2, 7)newDate = date.addToDate(newDate, { days: 7, month: 1 })// `newDate` is now 2017-3-14 00:00:00newDate = date.subtractFromDate(newDate, { hours: 24, milliseconds: 10000 })// `newDate` is now 2017-3-12 23:59:50 The object literal provided can contain the following keys (all are optional): Key Description milliseconds for a duration in milliseconds seconds for a duration in seconds minutes for a duration in minutes hours for a duration in hours days for a duration in days month for a duration in months year for a duration in years Set date/timeTo set a specified unit(s) of date/time:import { date } from 'quasar'let newDate = new Date(2017, 10, 2)let adjustedDate = date.adjustDate(newDate, { year: 2010, month: 2 })// `adjustedDate` is 2010-2-2 You can pass a third argument (a Boolean) for setting UTC time (true) instead of local time. The object literal provided can contain the following keys (all are optional): Key Description milliseconds for the milliseconds component of the date/time seconds for the seconds component of the date/time minutes for the minutes component of the date/time hours for the hours component of the date/time day for the day component of the date/time month for the month component of the date/time year for the year component of the date/time Query datesMinimum/MaximumTo get the minimum/maximum date of a date set (i.e. array) use:import { date } from 'quasar'let dates = [ new Date(2017, 6, 24), new Date(2017, 5, 20), new Date(2017, 6, 26) ]let min = date.getMinDate(dates) // `min` is 2017-5-20let max = date.getMaxDate(dates) // `max` is 2017-6-26// Or simply use multiple parameters:let min = date.getMinDate(new Date(2017, 6, 24), new Date(2017, 5, 20), new Date(2017, 6, 26))// `min` is 2017-5-20let max = date.getMaxDate(new Date(2017, 6, 24), new Date(2017, 5, 20), new Date(2017, 6, 26))// `max` is 2017-6-26 Time rangeTo check if a date is in a given date/time range use:import { date } from 'quasar'let dateTarget = new Date()let dateFrom = new Date()let dateTo = new Date()// **strictly** (i.e. exclusive range)if (date.isBetweenDates(dateTarget, dateFrom, dateTo)) { // Do something with dateTarget}// including which margin you wantif (date.isBetweenDates(dateTarget, dateFrom, dateTo, { inclusiveFrom: true, inclusiveTo: true })) { // Do something with dateTarget} To normalize a date in a given date/time range use:import { date } from 'quasar'let newDate = new Date()let dateMin = new Date(2010, 2, 23)let dateMax = new Date(2012, 4, 12)let dateNormalized = date.getDateBetween(newDate, dateMin, dateMax)// Returns `newDate` if it's between 2010-2-23 and 2012-4-12; `dateMin` if it's lower; `dateMax` if it's greater EqualityTo check if two dates’ unit are equal use:import { date } from 'quasar'let date1 = new Date(2017, 2, 5)let date2 = new Date(2017, 3, 8)let unit = 'year'if (date.isSameDate(date1, date2, /* optional */ unit)) { // true because date1 and date2's year is the same} Unit parameter can be omitted, in which case a full date/time comparison will occur, otherwise it allows to perform partial comparison: Unit Description second test if same second only minute test if same minute only hour test if same hour only day test if same day only month test if same month only year test if same year only DifferenceTo compute the difference between two dates use:import { date } from 'quasar'let date1 = new Date(2017, 4, 12)let date2 = new Date(2017, 3, 8)let unit = 'days'let diff = date.getDateDiff(date1, date2, unit)// `diff` is 34 (days) The unit parameter indicates the unit of measurement, if not specified then it is days by default: Unit Description seconds distance in seconds minutes distance in minutes hours distance in hours days distance in days months distance in months years distance in years CalendarTo get the week number in year for a given date object use:import { date } from 'quasar'let newDate = new Date(2017, 0, 4)let week = date.getWeekOfYear(newDate) // `week` is 1 To get the day number in year for a given date object use:import { date } from 'quasar'let newDate = new Date(2017, 1, 4)let day = date.getDayOfYear(newDate) // `day` is 35 To get the day number in week for a given date object use:import { date } from 'quasar'let newDate = new Date(2017, 1, 9)let day = date.getDayOfWeek(newDate) // `day` is 4 To get the number of days in the month for the specified date:import { date } from 'quasar'let newDate = new Date()let days = date.daysInMonth(newDate) // e.g. 30 Start/End of timeTo mutate the original date object by setting it to the start of a unit of time use:import { date } from 'quasar'let newDate = new Date(2000)// set to beginning of year 2000 (January 1st, 2000, 00:00:00.000)newDate = date.startOfDate(newDate, 'year')// set to end of year 2000 (December 31st, 2000, 23:59:59.999)newDate = date.endOfDate(newDate, 'year') The second parameter indicates a unit to reset to (beginning of it or end of it): Unit Description second reset seconds minute reset minutes hour reset hours day reset days month reset months year reset years Get Formatimport { date } from 'quasar'date.inferDateFormat(new Date()) // 'date'date.inferDateFormat(35346363) // 'number'date.inferDateFormat('Mon Feb 05 2018 23:05:29') // string Cloning Dateimport { date } from 'quasar'const newDate = new Date()const clonedDate = date.clone(newDate)date.addToDate(newDate, { days: 1 })console.log(newDate.getDate() === clonedDate.getDate()) // false"},{"title":"Element Resize Observable","updated":"2018-05-18T22:01:01.013Z","permalink":"https://v0-16.quasar-framework.org/components/element-resize-observable.html","text":"QResizeObservable is a Quasar component that emits a resize event whenever the wrapping DOM element / component (defined as direct parent of QResizeObservable) changes its size. Note that no polling is involved, but overusing it is costly too. InstallationEdit /quasar.conf.js:framework: { components: [ 'QResizeObservable' ]} Basic Usage<template> <!-- we listen for size changes on this next <div>, so we place the observer as direct child: --> <div> <q-resize-observable @resize=\"onResize\" /> </div></template><script>export default { ..., methods: { ..., onResize (size) { console.log(size) // { // width: 20 // width of container (in px) // height: 50 // height of container (in px) // } } }}</script> Please note that QResizeObservable will issue an event as soon as it gets rendered and attached to DOM, so you can have the initial size of the container. Vue Properties Property Type Description debounce Number (Quasar v0.15.7+, default: 100) Debounce time in milliseconds"},{"title":"Field","updated":"2018-05-18T22:01:01.014Z","permalink":"https://v0-16.quasar-framework.org/components/field.html","text":"Field component allows you to easily build your responsive Forms UI by wrapping each Form component (QInput, QSelect, QDatetime, QChipsInput and so on) to enrich it with a main label, an icon, error placeholder and error state, helper placeholder and/or item/character counter. On small windows, label and content will stack vertically, while on bigger windows label will be placed on the left of QField content. Icons are always placed at the left of label and content, regardless of window width. Works with ANY component, not only Form ones. InstallationEdit /quasar.conf.js:framework: { components: ['QField']} Basic Usage<q-field icon=\"cloud\" label=\"Your Gmail\" helper=\"Helper\" :error=\"mailHasError\" error-label=\"We need a valid email\" :count=\"10\"> <q-input suffix=\"@gmail.com\" v-model=\"model\" /></q-field> Vue Properties Vue Property Type Description label String Main label to use. icon String An icon to use on left of label. icon-color String Optional color of icon. helper String Helper text which gets placed below your wrapped form component. error Boolean Highlight field and wrapped form component has an error. error-label String If error is specified and true, then field helper is replaced by this prop. Doesn’t depend on field helper existance. warning Boolean Highlight field and wrapped form component has a warning. warning-label String If warning is specified and true, then field helper is replaced by this prop. Doesn’t depend on field helper existance. count Number/Boolean Add a counter of characters or items (like Chips) in your wrapped form component. If Boolean, it just counts them. If Number, it also adds a maximum number to it, but doesn’t acts as a restraint. inset String Inset you field to align with other fields when current one is missing an icon and/or label. One of ‘icon’, ‘label’ or ‘full’ (inset for both icon and label). orientation String Overrides the responsive orientation. One of ‘vertical’ or ‘horizontal’. label-width Number Out of 12 grid points, how much should the label take? Default is 5. Minimum is 1 and maximum is 12. dark Boolean Is your field used on a dark background? ExamplesThe following are just a glimpse of what QField can do for you. Using Counter<!-- 16 characters max. Notice \"count\" property (and optional max-length to enforce max number of characters)--><q-field :count=\"16\"> <q-input type=\"password\" max-length=\"16\" v-model=\"model\" /></q-field><!-- Counting Chips. Notice \"count\" property --><q-field count icon=\"account_box\" helper=\"Some helper here\" :label-width=\"3\"> <q-chips-input float-label=\"Float Label\" v-model=\"model\" /></q-field><!-- Counting selected options --><q-field count> <q-select v-model=\"select\" :options=\"[ { label: 'Google', icon: 'email', value: 'goog' }, { label: 'Facebook', description: 'Enables communication', value: 'fb' }, { label: 'Twitter', secondIcon: 'alarm', value: 'twtr' } ]\" /></q-field> Validations with VuelidateQuasar’s recommendation for doing form components validations is Vuelidate as it fits great with the overall architecture. It’s simple, lightweight and model-based. You need to have Vuelidate added to your project first. See here. <template> <q-field icon=\"mail\" label=\"Email\" helper=\"Type the email we can use to contact you\" :error=\"$v.email.$error\" error-label=\"Please type a valid email\" count > <q-input type=\"email\" v-model=\"email\" @blur=\"$v.email.$touch\" /> </q-field></template><script>import { required, email } from 'vuelidate/lib/validators'export default { data () { return { email: '' } }, validations: { email: { required, email } }}</script> Float Label QInput<q-field icon=\"cloud\" helper=\"Helper\"> <q-input v-model=\"model\" float-label=\"Float Label\" /></q-field> Custom Label WidthIf you customize label width for one QField then it’s best to apply it to all its sibling QFields for UI consistency.Since Quasar is using a 12 point grid system, assign a number >= 1 and < 12 for the label width. Default is 5. <q-field helper=\"Helper\" :label-width=\"3\" label=\"Label\"> <q-input v-model=\"model\" /></q-field> Using InsetInset is useful to perfectly align all QFields when some have icons and labels and some are missing either or both of them. If, for example, no QField uses icon, then it makes sense to not add inset for any of the QFields. Same goes for label. <!-- This example has icon and label. Since having both of them, it gets set as reference for the other QFields when adding inset to them.--><q-field icon=\"cloud\" helper=\"Helper\" label=\"Horizontal\"> <q-input v-model=\"model\" /></q-field><!-- This example has only label, so we inset for the icon (because there is at least one QField having icon too)--><q-field helper=\"Helper\" label=\"Label\" inset=\"icon\"> <q-input v-model=\"model\" /></q-field><!-- This example has no icon or label, so we inset for them both (as there is a sibling QField with both icon and label).--><q-field helper=\"Helper\" inset=\"full\"> <q-input v-model=\"model\" /></q-field> Wrapping Side by Side QInputsWe use Quasar CSS Flex to create a non wrappable row where we place two QInputs. When more than one Form component is wrapped by QField, avoid adding a counter to QField because only one will end up synching its length to it. Each Form component has its own length and there’s only one placeholder for the counter, so in the end you will only confuse the user. <!-- Example featuring stacked labels --><q-field icon=\"security\" helper=\"Helper\" label=\"Label\"> <!-- We create a row --> <div class=\"row no-wrap\"> <q-input class=\"col\" v-model=\"model\" stack-label=\"Input 1\" /> <q-input class=\"col\" v-model=\"model\" stack-label=\"Input 2\" /> </div></q-field> Dark BackgroundWhen placing a QField on a dark background, use dark property to inform QField it needs to adjust colors. <!-- This example has a wrapping <div> with a dark background associated with it.--><div class=\"bg-grey-9\" style=\"padding: 10px\"> <!-- Notice \"dark\" property --> <q-field dark label=\"Knob\" helper=\"Touch to change\" icon=\"cake\" :error=\"error\" > <q-knob v-model=\"knob\" :min=\"knobMin\" :max=\"knobMax\" > <q-icon class=\"on-left\" name=\"volume_up\" /> {{knob}} </q-knob> </q-field></div> Option GroupHere’s an example with an Option Group component. <q-field icon=\"flight_takeoff\" label=\"Flight\" helper=\"Pick the day when you want to go\"> <q-option-group type=\"radio\" v-model=\"option\" :options=\"[ { label: 'Monday', value: 'monday' }, { label: 'Tuesday', value: 'tuesday' }, { label: 'Friday', value: 'friday' } ]\" /></q-field>"},{"title":"Floating Action Buttons","updated":"2018-06-20T12:44:57.532Z","permalink":"https://v0-16.quasar-framework.org/components/floating-action-button.html","text":"A Floating Action Button (FAB) represents the primary action in an App Page. But, it’s not limited to only a single action. It can contain any number of sub-actions too. And more importantly, it can also be used inline in your Pages or Layouts. Note that you don’t need a QLayout to use FABs. InstallationEdit /quasar.conf.js:framework: { components: [ 'QFab', 'QFabAction' ]} Basic UsageThere are two types of FABs: expandable (has sub-actions) and non-expandable. Non-ExpandableIf you want a non-expandable FAB, all you need is a round button – wrapped in QPageSticky if used on a QLayout. <!-- Non-expandable without being on a QLayout --><q-btn round color=\"primary\" @click=\"method\" class=\"fixed\" icon=\"mail\" style=\"right: 18px; bottom: 18px\"/><!-- Non-expandable on a QLayout --><q-page-sticky position=\"bottom-right\" :offset=\"[18, 18]\"> <q-btn round color=\"primary\" @click=\"method\" icon=\"mail\" /></q-page-sticky> ExpandableExpandable FABs are defined by two components: QFab (parent) and QFabAction (children).<!-- Expandable --><q-fab color=\"purple\" icon=\"keyboard_arrow_up\" direction=\"up\"> <q-fab-action color=\"primary\" @click=\"someMethod\" icon=\"mail\" /> <q-fab-action color=\"secondary\" @click=\"someMethod\" icon=\"alarm\" /></q-fab><!-- Expandable, fixed position without a QLayout --><q-fab class=\"fixed\" style=\"right: 18px; bottom: 18px\" color=\"primary\" icon=\"wifi\">....</q-fab><!-- Expandable, fixed position on a QLayout --><q-page-sticky position=\"bottom-right\" :offset=\"[18, 18]\"> <q-fab color=\"primary\" icon=\"wifi\" >....</q-fab></q-page-sticky> We’ll continue describing only the expandable FAB, as the non-expandable FAB is, as mentioned above, a simple round button. Toggle through v-model<template> <div> <q-fab v-model=\"open\" color=\"primary\" icon=\"wifi\" >....</q-fab> </div></template><script>export default { data () { return { open: false } }, methods: { toggleFab () { this.open = !this.open } }}</script> Labeling with TooltipsNotice slot="tooltip" for the Tooltip on main button and where are the Tooltips placed for the Fab action buttons.<q-fab color=\"primary\" active-icon=\"alarm\" direction=\"up\"> <q-tooltip slot=\"tooltip\" anchor=\"center left\" self=\"center right\" :offset=\"[20, 0]\" > Tooltip in FAB </q-tooltip> <q-fab-action color=\"purple\" @click=\"toast('mail')\" icon=\"mail\"> <q-tooltip anchor=\"center left\" self=\"center right\" :offset=\"[20, 0]\">Mail</q-tooltip> </q-fab-action> <q-fab-action color=\"secondary\" @click=\"toast('alarm')\" icon=\"alarm\"> <q-tooltip anchor=\"center left\" self=\"center right\" :offset=\"[20, 0]\">Alarm</q-tooltip> </q-fab-action></q-fab> For more information about Tooltips, please refer to the Tooltip documentation. QFab (Parent)QFab Vue Properties Vue Property Type Default Value Description color String n/a The color of the button, from Quasar Color Palette. text-color String n/a The color of the button icon, from Quasar Color Palette. direction String “right” The direction in which to expand; one of the following values: “up”, “down”, “left”, “right”. icon String “add” Icon to use when not expanded active-icon String “close” The icon to change to when expanded. outline Boolean n/a Set true, for an outlined button. push Boolean n/a Set true, for a push styled button. flat Boolean n/a Set true, for a flat styled button. glossy Boolean n/a Make button “glossy”. QFab Vue Methods Vue Method Description toggle() Toggle open/close state. show() Open FAB. hide() Close FAB. QFab Vue Events Vue Method Description @show Triggered when clicking/tapping on main FAB to open it. @hide Triggered when clicking/tapping on main FAB to close it. QFabAction (Child)The cool bit about FABs is, they give the user the ability to select from a number of actions. These actions can be offered through a list of QFabAction components witin the QFab. Basic Usage<!-- a q-fab with two actions --><q-fab color=\"purple\" icon=\"keyboard_arrow_up\" direction=\"up\"> <q-fab-action class=\"white\" @click=\"someMethod()\" icon=\"mail\" /> <q-fab-action class=\"white\" @click=\"someMethod()\" icon=\"alarm\" /></q-fab> QFabAction Vue Properties Vue Property Type Description color String The color of the button. text-color String n/a The color of the button icon. icon String The icon of the button. outline Boolean Set true, for an outlined button. push Boolean Set true, for a push styled button. flat Boolean Set true, for a flat styled button. glossy Boolean Make button “glossy”. QFabAction Vue Events Vue Method Description @click Triggered when clicking/tapping on the small fab. NoteClicking on a QFabAction will automatically close the list of sub-actions and return the FAB to its original state."},{"title":"Flex CSS","updated":"2018-05-18T22:01:01.015Z","permalink":"https://v0-16.quasar-framework.org/components/flex-css.html","text":"Quasar provides lots of CSS classes to help you build your UI easily with the help of Flexbox. Think of it like operating with rows and columns with many options at hand. The final section of this page will show you how to create responsive UIs. Also take a look at the demo (best viewed by clicking “Desktop View” when on a desktop, because that’s where you can resize the window width to see helper classes in action). Click on “View Source” too to see the demo’s source code. Background on FlexboxThe Flexbox Layout (Flexible Box) module (currently a W3C Last Call Working Draft) aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word “flex”). The main idea behind the flex layout is to give the container the ability to alter its items’ width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes). A flex container expands items to fill available free space, or shrinks them to prevent overflow. Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts (block which is vertically-based and inline which is horizontally-based). While those work well for pages, they lack flexibility (no pun intended) to support large or complex applications (especially when it comes to orientation changing, resizing, stretching, shrinking, etc.). Getting StartedQuasar Flex CSS classes apply to either the Container (Parent) or the Container’s items (Children). Parent ClassesSetting DirectionOne of the following CSS classes is mandatory for the parent in order for the children ones (described in next sections) to have any effect. Class Name Description row Flex row row inline Inline Flex row column Flex column column inline Inline Flex column row reverse Flex row with flex-direction set to row-reverse column reverse Flex column with flex-direction set to column-reverse Example:<div class=\"row\"> <div>First column</div> <div>Second column</div> <div>Third column</div></div> Wrapping by defaultBy default, all rows and columns are wrapping content. However if you explicitly do not want to wrap and by so doing you want to fit all content into one line, then add no-wrap CSS helper class. Also, if you want to wrap in reverse order, then reverse-wrap is available. Class Name Description wrap Wrap if necessary (“on” by default, no need to specify it) no-wrap Do NOT wrap even if necessary reverse-wrap Wrap backwards if necessary AlignmentFor alignment along the main axis, use classes below. It helps distribute extra free space left over when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size. It also exerts some control over the alignment of items when they overflow the line. For alignment perpendicular to the main axis, use classes below. This defines the default behavior for how flex items are laid out along the cross axis on the current line. Think of it as the horizontal-* version for the cross-axis (perpendicular to the main-axis). The next classes align a flex container’s lines within when there is extra space in the cross-axis, similar to how horizontal-* aligns individual items within the main-axis. Children ClassesDistribution of SizeQuasar uses a 12 point column system for distributing size of row children. Here are some examples of the CSS helper classes available: <div class=\"row\"> <div class=\"col-8\">two thirds</div> <div class=\"col-2\">one sixth</div> <div class=\"col-auto\">auto size based on content and available space</div> <div class=\"col\">fills remaining available space</div></div> In the example above, col-8 fills two thirds (2/3) of the row width, because 8/12 = 2/3 = 66%, while col-2 occupies one sixth (2/12 = 1/6 ~ 16.67%). CSS helper class col-auto makes the cell fill only the space it needs to be rendered, with the possibility to shrink when not enough space is available. col, on the other hand, tries to fill all space available while also shrinking if needed. Another example with a visual representation below it:<div class=\"row\"> <div class=\"col\">1</div> <div class=\"col\">1</div> <div class=\"col\">1</div> <!-- we have 3 children, so equivalent to above would be to use `col-4` on each of the children --></div><div class=\"row\"> <div class=\"col-3\">1</div> <div class=\"col-6\">2</div> <div class=\"col-3\">1</div></div> There’s also the possible to offset a cell. Example: offset-4 which offsets a third of space (4/12 = 1/3 = 33%). WrappingWrapping is a key feature in understanding Flex CSS classes. You are not bound to use exactly 12 points per row. You can use less or even more. This allows you, among other things, to dynamically stack rows vertically on smaller screens while displaying them on a single line on bigger screens. Read “Responsive Design” section. <div class=\"row\"> <div class=\"col-2\">...</div> <!-- 2 + 6 < 12, so next element is placed on same line --> <div class=\"col-6\">...</div> <!-- 2 + 6 + 10 > 12, so next element wraps to next line --> <div class=\"col-10\">...</div> <!-- 10 + 3 > 12, so next element wraps to next line. Note that we take into consideration the current line only (with col-10 only, since it was wrapped to its own line). --> <div class=\"col-3\">...</div></div> Note that rows are wrappable by default. Should you wish to disable this, use no-wrap CSS helper class. Self AlignmentAn item can override the aligned specified on parent. This allows alignment to be overridden for individual flex items. Please see the Alignment explanation from Parent Classes to understand the available values (self-start, self-center, self-baseline, self-end, self-stretch). OrderYou can set the order of children elements by using order-first and order-last CSS helper classes. By default, flex items are laid out in the source order. However, the order property controls the order in which they appear in the flex container. If you need more granularity, use order CSS property and assign the desired value. Example:<div class=\"row\"> <div style=\"order: 2\">Second column</div> <div class=\"order-last\">Third column</div> <div class=\"order-first\">First column</div></div> Here is how the CSS order property works: Responsive DesignFlex CSS Helper classes can be applied based on the width of the screen, to help you in making a responsive UI. The 12 points grid is inspired by Bootstrap’s, so there are a lot of similarities. What we’ve learned so far is that, for example, we can size the columns regardless of window width. If we are to create a response UI, we need to dynamically change the sizing while taking into account how wide the window is. First, let’s learn about some tokens that you can inject at middle of col-*, offset-* and col-auto helper classes (look at table below for tokens). Token Max window width Description / When it applies xs 576px Extra small sized window sm 768px Small sized window md 992px Medium-sized window lg 1200px Large sized window xl Infinite Extra large sized window Example: col-md-7, offset-lg-3, col-xs-auto. Before diving into examples, make sure you read and understood Children Classes > Wrapping because it is key to understanding how you can build a responsive design. A full example: let’s say we have a row with three children. On extra small windows, we need to stack the children vertically, on small windows we need to display them side by side (each having equal width), and starting with medium windows we should display them all on same line: <div class=\"row\"> <div class=\"col-xs-12 col-sm-6 col-md-4\"> col </div> <div class=\"col-xs-12 col-sm-6 col-md-4\"> col </div> <div class=\"col-xs-12 col-sm-6 col-md-4\"> col </div></div> Notice in the above example that we used col-xs-12 (12/12 = 100% of row, so each child will take full width of the container making all children stack vertically, since rows are wrapping content by default), col-sm-6 (6/12 = 50% of row) and col-md-4 (4/12 = 33% of row). Like previously mentioned, rows wrap content by default, so when 12 (or more) grid points are used for a row, content is wrapped to the next line. If we have two <div>s and we use col-8 on both, they will also stack, since 8 + 8 = 16 and we can only display 12 points on a single line. <div class=\"row\"> <!-- more than 12 grid points together, so second <div> will wrap on next line --> <div class=\"col-8\">col</div> <div class=\"col-8\">col</div></div> Also check CSS Helpers > Visibility page to see thresholds on window width and these tokens (xs, sm, md, lg, xl) used on their own to hide or show DOM elements. Customize breakpointsIf you want to customize existing responsive breakpoints or add new ones, you can edit the $size Stylus variable: $sizes = { xs: 0, sm: 575px md: 767px lg: 991px xl: 1199px} Using GuttersThere are 5 types of gutter, depending on the amount of space that you want between your elements: Class Name Size Description gutter-xs 8px extra small gutter gutter-sm 16px small gutter gutter-md 32px medium gutter gutter-lg 48px large gutter gutter-xl 64px extra large gutter Let’s look at a basic example. Please take note of the structure. You need a wrapping <div> and your content must be inside the <div> which has col-* CSS helper classes. The gutter classes make use of negative margins, so if your flex grid content is contained within, for example, a q-collapsible with a clickable area immediately above the flex grid, you must specify class="overflow-hidden" to avoid the contents overlapping the active area of the parent component. <!-- Example with extra small gutter and two equal width cols --><!-- wrapping <div> required --><div class=\"overflow-hidden\"> <!-- the row with a type of gutter --> <div class=\"row gutter-xs\"> <div class=\"col-6\"> <!-- Your content here --> </div> <div class=\"col-6\"> <!-- Your content here --> </div> </div></div> IMPORTANTSome components have default margins, like the form components. This will add to the gutter, which is probably not what you want. For such cases, use no-margin class on those components, like in the example below: <div class=\"overflow-hidden\"> <div class=\"row gutter-xs\"> <div class=\"col-6\"> <q-input v-model=\"model\" class=\"no-margin\" /> </div> <div class=\"col-6\"> <q-input v-model=\"model\" class=\"no-margin\" /> </div> </div></div> By default, the gutter applies both horizontally and vertically. If for example you different levels of gutter only horizontally or only vertically, use gutter-x-* and gutter-y-* CSS classes:<!-- small gutter horizontally, large gutter vertically --><div class=\"overflow-hidden\"> <div class=\"row gutter-x-sm gutter-y-lg\"> <div class=\"col-6\"> <q-input v-model=\"model\" class=\"no-margin\" /> </div> <div class=\"col-6\"> <q-input v-model=\"model\" class=\"no-margin\" /> </div> </div></div> QInput ExampleLet’s say we want to build something depicted in the two picture below.… which becomes like below on xs windows: The template for this would look like below. Note we are using no-margin CSS helper class for QInputs to not add additional space to gutter.<div> <div class=\"row gutter-sm\"> <div class=\"col-12\"> <q-input inverted v-model=\"model\" class=\"no-margin\" float-label=\"col-12\" /> </div> <div class=\"col-xs-12 col-sm-6\"> <q-input inverted v-model=\"model\" class=\"no-margin\" float-label=\"col-xs-12 col-sm-6 TOP LEFT\" /> </div> <div class=\"col-xs-12 col-sm-6\"> <q-input inverted v-model=\"model\" class=\"no-margin\" float-label=\"col-xs-12 col-sm-6 TOP RIGHT\" /> </div> <div class=\"col-xs-12 col-sm-6\"> <q-input inverted v-model=\"model\" class=\"no-margin\" float-label=\"col-xs-12 col-sm-6 BOTTOM LEFT\" /> </div> <div class=\"col-xs-12 col-sm-6\"> <q-input inverted v-model=\"model\" class=\"no-margin\" float-label=\"col-xs-12 col-sm-6 BOTTOM RIGHT\" /> </div> <div class=\"col-12\"> <q-input inverted v-model=\"model\" class=\"no-margin\" float-label=\"col-12\" /> </div> </div></div>"},{"title":"DOM Utils","updated":"2018-06-07T11:37:46.877Z","permalink":"https://v0-16.quasar-framework.org/components/dom-utils.html","text":"Helping Tree-ShakeYou will notice all examples import different parts of Quasar. However, if you need only one specific util method, then you can use ES6 destructuring to help Tree Shaking embed only that method and not all around it. Example with dom utils:import { dom } from 'quasar'const { offset } = dom// Offset on screenconsole.log(offset(DomElement))// { top: 10, left: 100 } You can also import all of dom utils and use whatever you need like this (but note that your bundle will contain unused methods too):import { dom } from 'quasar'// Offset on screenconsole.log(dom.offset(DomElement))// { top: 10, left: 100 } Offset on screen viewportimport { dom } from 'quasar'const { offset } = dom// Offset on screenconsole.log(offset(DomElement))// { top: 10, left: 100 } Get Computed StyleThis applies only when DomElement is visible! It returns the computed browser style, so the property you are asking for doesn’t necessary has to be applied within a style attribute. import { dom } from 'quasar'const { style } = dom// Get COMPUTED style (when DomElement is visible!)// Computed means a DomElement might not have \"height\" CSS property set,// but that does not mean it doesn't have a height when it's displayed.// The following method accesses the computed CSS provided by the browser:console.log(style(DomElement, 'height'))// '10px' <<< notice it returns a String ending in 'px' Get Height / Widthimport { dom } from 'quasar'const { height, width } = dom// Some aliases of the previous method for \"width\" and \"height\" which// returns Numbers instead of Strings:console.log( height(DomElement), width(DomElement))// 10 100 Apply CSS Properties in Batchimport { dom } from 'quasar'const { css } = dom// Apply a list of CSS properties to a DomNodecss(DomElement, { height: '10px', display: 'flex'}) Execute when DOM is readyimport { dom } from 'quasar'const { ready } = dom// Execute a Function when DOM is ready:ready(function () { // ....}) Get Crossbrowser CSS Transform Propertyimport { dom } from 'quasar'const { cssTransform } = domlet props = cssTransform('rotateX(30deg)')// props = {// transform: 'rotateX(30deg)',// '-webkit-transform': 'rotateX(30deg)',// '-ms-transform': 'rotateX(30deg)',// '-o-transform': 'rotateX(30deg)',// '-moz-transform': 'rotateX(30deg)'// }// Then you can apply it with css(el, props)"},{"title":"Handling Back Button","updated":"2018-07-23T16:37:49.843Z","permalink":"https://v0-16.quasar-framework.org/components/handling-back-button.html","text":"When writing reusable code for building a mobile App and a website, it’s important to know how to handle the “Back” button. More specifically, how to manage buttons on your layout/page that should make your App “go back” to the previous screen. If you have no knowledge of Vue Router, we highly recommend you read and understand how it works first. Navigation ScenarioConsider this situation: We have an App with two pages (so two routes): a login page (route “/“) and another page with a list of items on multiple layout tabs- Let’s call this page “List page” from now on, where each tab has a route like “/list/shoes”, “/list/hats”. The Login page redirects to List page and List page has a “Logout” button, which redirects the user to the Login page. How would you handle this situation? Normally, you’d write code like below for the Login and Logout button (we won’t go into details of handling the login information and communicating with a server as this is outside of our point here): <!-- Login button --><q-btn @click=\"$router.push('/list')\">Login</q-btn><!-- Logout button --><q-btn @click=\"$router.push('/login')\">Logout</q-btn> Now you build your App and install it on a phone. You open up the App, hit login then logout, then the phone’s back button. What you most likely want is for your App to exit at this point… but it doesn’t! It goes to the “/list” route instead. It’s kind of obvious why. Web history builds up as you hit the buttons:# Start App--> window.history.length is 1# Hit Login button--> window.history.length is 2# Hit Logout button--> window.history.length is 3! What you’d like instead, is when you hit the Logout button, the window.history.length to be 1 again. Quasar can handle this automatically for you. Read about the v-go-back Vue directive. Directive “v-go-back”Let’s rewrite the Logout button to act as we would actually want it to work, which is to make window.history.length be 1 again. First, we install the directive. Edit /quasar.conf.js:framework: { directives: ['GoBack']} Then we use it:<!-- Logout button --><q-btn v-go-back=\" '/' \" color=\"primary\" label=\"Logout\"/> This directive determines if the Platform is Cordova, and if so, it performs a window.history.back() call instead of a $router.push('/'). QuirksNow you may think everything will work smoothly, but you must be careful about how your app is stacking up the window history. Remember, we started out by saying that the List page has a layout with multiple tabs, each one with its own route (“/list/shoes”, “/list/hats”). If we’d use to="/list/shoes" and to="/list/hats'" on your Tabs (read more about Tabs here), then window history will build up when switching between the tabs. This incorrect behavior for apps is due to Vue Router pushing routes to the history by default. What you’d like instead, is for your window history length to stay the same, even if routes change. Fortunately, Vue Router comes to the rescue with the replace property, which essentially replaces current route instead of pushing it as a new route. So, besides to=" '...route...' " you should add the replace attribute (becoming to=" '...route...' " replace). This will replace the current route in the window history rather than pushing it. The same applies to <router-link>s. Always think about how you redirect your App to a new route, depending on what you want to achieve. Think if you really want to push a new route to window history or if you want to “replace” the current route. Otherwise the phone/tablet/browser “Back” button won’t work quite as expected. Instead of finally exiting the App, it will make you go through all the routes in the reverse order they were visited. So when you hit back and go to the Login page, you’d expect another back to make the App exit, but it might make your App go to one of the List tabs, depending on the user’s navigation history."},{"title":"Formatter Utils","updated":"2018-05-18T22:01:01.017Z","permalink":"https://v0-16.quasar-framework.org/components/formatter-utils.html","text":"Helping Tree-ShakeYou will notice all examples import format Object from Quasar. However, if you need only one formatter method from it, then you can use ES6 destructuring to help Tree Shaking embed only that method and not all of format. Example:// we import all of `date`import { format } from 'quasar'// destructuring to keep only what is neededconst { capitalize, humanStorageSize } = formatconsole.log( capitalize('some text') )// Some textconsole.log( humanStorageSize(13087) )// 12.78 kB You can also import all formatters and use whatever you need like this (but note that your bundle will probably contain unused methods too):import { format } from 'quasar'console.log( format.capitalize('some text') )console.log( format.humanStorageSize(13087) ) Capitalizeimport { format } from 'quasar'const { capitalize } = formatconsole.log( capitalize('some text') )// Some text Format to Human Readable Sizeimport { format } from 'quasar'const { humanStorageSize } = formatconsole.log( humanStorageSize(13087) )// 12.78 kB Normalize Number to Intervalimport { format } from 'quasar'const { between } = format// (Number) between(Number, Number min, Number max)console.log( between(50, 10, 20) )// 20 Pad Stringimport { format } from 'quasar'const { pad } = format// (String) pad(String toPad, Number length, String paddingCharacter)// length is default 2// paddingCharacter is default '0'console.log( pad('2', 4) )// '0002'"},{"title":"Form Validation","updated":"2018-05-20T16:04:39.313Z","permalink":"https://v0-16.quasar-framework.org/components/form-validation.html","text":"Recommended package for Form Validations is Vuelidate.Get started with the documentation. Installation of Vuelidate$ yarn add vuelidate# or:$ npm install --save vuelidate$ quasar new plugin vuelidate An app plugin file got created: /src/plugins/vuelidate.js. We edit it:import Vuelidate from 'vuelidate'export default ({ Vue }) => { Vue.use(Vuelidate)} We then edit /quasar.conf.js to add the app plugin file to the build:plugins: ['vuelidate'] Note: ensure you add this to the main plugins at the top of the file, not in the framework plugins section. Example<template> <div> <q-input v-model=\"form.email\" @blur=\"$v.form.email.$touch\" @keyup.enter=\"submit\" :error=\"$v.form.email.$error\" /> <q-btn color=\"primary\" @click=\"submit\">Submit</q-btn> </div></template><script>import { required, email } from 'vuelidate/lib/validators'export default { data () { return { form: { email: '' } } }, validations: { form: { email: { required, email } } }, methods: { submit () { this.$v.form.$touch() if (this.$v.form.$error) { this.$q.notify('Please review fields again.') return } // ... } }}</script>"},{"title":"Global Event Bus","updated":"2018-05-18T22:01:01.017Z","permalink":"https://v0-16.quasar-framework.org/components/global-event-bus.html","text":"Events are important for the inner workings of your App.Sometimes you need an event bus or a publish/subscribe channel. Vue already has an event bus for each component. For convenience, you can use the root Vue component for this through this.$root to register and listen for events. IMPORTANT!Not to be confused with events supported by Quasar Components. Those are Vue events emitted by the respective components and don’t interfere with the global event bus. Please check the Vue Instance Methods / Events page for the API. Then let’s see how, for example, to register an event on the root Vue component of your app: // callbackfunction cb (msg) { console.log(msg)}// listen for an eventthis.$root.$on('event_name', cb)// listen once (only) for an eventthis.$root.$once('event_name', cb)// Make sure you stop listening for an event// when your respective component gets destroyedthis.$root.$off('event_name', cb)// Emitting an event:this.$root.$emit('event_name', 'some message')"},{"title":"Overview","updated":"2018-05-18T22:01:01.018Z","permalink":"https://v0-16.quasar-framework.org/components/index.html","text":"Quasar Apps are made of high-level building blocks called components. Components allow you to quickly construct an interface for your App. Quasar comes with a number of components, including modals, action sheets, collapsibles, cards, dialogs, FAB, lists and many more. Quasar Components are written as Web Components, so they embed HTML, CSS and Javascript code that you can use by just including an HTML tag in your Page and Layout templates. IMPORTANTFor Vue & Quasar developers (beginners or not), read Introduction for Beginners first. It’s mandatory in order to understand how you can use Vue properties, methods and so on. Check out the live demos for each Quasar theme to see what each component looks like and to learn how to use each one. If you widen your browser window enough then you’ll see a live demo on the right side of each component page. Live Component Demo: Material Theme iOS Theme"},{"title":"Input (Textfield)","updated":"2018-07-23T16:37:49.843Z","permalink":"https://v0-16.quasar-framework.org/components/input-textfield.html","text":"Quasar’s Input component is the basis for text (we’ll call it “Singe Line Input”) and textarea (we’ll call it “Multiple Line Input”) form input. It can be used for regular text input, passwords, email addresses, numbers, telephone numbers, urls and auto-growing text areas. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QInput']} Basic Usage<!-- Single Line Input --><q-input v-model=\"text\" /><q-input v-model=\"text\" stack-label=\"Stack Label\" /><q-input v-model=\"text\" float-label=\"Float Label\" placeholder=\"Gigi\" /><!-- Multiple Line Input --><q-input v-model=\"area\" type=\"textarea\" float-label=\"Textarea\" :max-height=\"100\" rows=\"7\"/><!-- max-height refers to pixels --> Vue PropertiesSupports v-model which should be bound to a String or Number (depending on type property used) in your scope. Property Type Description type String Must be one of the following: text (default), textarea, email, tel, number, password and url. This is important as it determines the keyboard type popping up on mobile devices. readonly Boolean If set to true, textfield is readonly and the user cannot change value. clearable Boolean If set to true, the component offers the user an actionable icon to remove the entered text. no-pass-toggle Boolean If type is ‘password’ and set to true, then password toggle is not shown. upper-case Boolean Transform input to upper case. lower-case Boolean Transform input to lower case. When you set type to “number”, there are some additional properties that you can use: Property Type Description decimals Number Maximum number of decimals that should be displayed. numeric-keyboard-toggle Boolean Some mobile keyboards do not allow to type the dot to compose a floating number, so this property adds an icon that when clicked/tapped it toggles the keyboard to/from an alphanumeric one. Also note you can use the native DOM attributes of an input: “min”, “max”, “step”. When you set type to “textarea”, these is an additional property that you can use: Property Type Description max-height Number Number in pixels that determines the maximum height of textarea which auto-grows. There’s also the native DOM attribute of a textarea: ‘rows’. Common input field properties: Property Type Description autofocus Boolean Focus input field after rendering component. placeholder String A text to be shown on textfield, mainly to explain what should be entered. loading Boolean Place the default spinner of the theme after textfield to highlight some process takes place in the background. clearable Boolean If set to true, the component offers the user an actionable icon to remove the current selection. Common input frame properties: Property Type Description prefix String A text that should be shown before the textfield. suffix String A text that should be shown after the textfield. float-label String A text label that will “float” up above the input field, once the input field gets focus. stack-label String A text label that will be shown above the input field and is static. color String One from Quasar Color Palette. inverted Boolean Inverted mode. Color is applied to background instead. inverted-light Boolean Inverted mode with a light color. Color is applied to background instead. dark Boolean Is QInput rendered on a dark background? align String One of ‘left’, ‘center’ or ‘right’ which determines the text align within textfield. disable Boolean If set to true, textfield is disabled and the user cannot type anything. hide-underline Boolean Hides the bottom border. error Boolean If set to true, the input fields colors are changed to show there is an error. warning Boolean Same as error, the input field color is changed to show there is a warning. before Array of Objects Icon buttons on left side of textfield. Read below more details. after Array of Objects Icon buttons on right side of textfield. Read below more details. IMPORTANTAll DOM attributes that apply to a native <input> or <textarea> can be used. Example: maxlength, rows, min/max/step, autocomplete and so on. Icon buttonsThis section refers to before and after properties which can add additional buttons as icons to the textfield. Here is the structure of the two properties: { // required icon icon: String, // required function to call when // icon is clicked/tapped handler: Function, // Optional. Show icon button // if model has a value content: Boolean, // Optional. Show icon button // if textfield is marked with error error: Boolean} Examples:<!-- Show an icon button (with 'warning' as icon) when there is an error on QInput (through \"error\" prop)--><q-input v-model=\"text\" :error=\"error\" type=\"password\" :after=\"[ { icon: 'warning', error: true, handler () { // do something... } } ]\"/><!-- Show an icon button (with 'arrow_forward' as icon) when the model has a non empty value--><q-input v-model=\"text\" :after=\"[ { icon: 'arrow_forward', content: true, handler () { // do something... } } ]\"/> LabelingQInput comes with two built-in labeling possibilities. You can use the float-label or the stack-label properties to add text for the labeling of the field. A stack-label is static in its position above the field, whereas the fload-label is more dynamic. Check the examples to the right to see the difference. <q-input v-model=\"text\" stack-label=\"Stack Label\" placeholder=\"Add some text...\" /><q-input v-model=\"text\" float-label=\"Float Label\"/> As shown above, you can also add a placeholder to help explain to the user what type of input should be entered. Password InputIf you use the input type password, the component will hide the characters entered by the user, but it will also offer the user a clickable icon to toggle the input, to make the input legible. <q-input v-model=\"text\" type=\"password\" float-label=\"Password\" /> Number InputThe below example shows a number input type.<q-input v-model=\"number\" type=\"number\" float-label=\"Number\" /> Prefixes and SuffixesYou can add a text before or after the field as part of an input mask, for instance, for showing Euro or US Dollar currency. <!-- Notice prefix property --><q-input v-model=\"number\" type=\"number\" prefix=\"$US\" stack-label=\"Number\" /><!-- Notice suffix property --><q-input v-model=\"number\" type=\"number\" suffix=\"€\" stack-label=\"Number\" /><!-- Notice suffix property --><q-input v-model=\"email\" type=\"email\" suffix=\"@gmail.com\" stack-label=\"Type Google Email\" /> Error StateYou can control the color to show a mistake in user input or some other systematic error. To do this set the error prop to true. <q-input :error=\"error\" v-model=\"text\" float-label=\"Colored Black\" color=\"black\" /> If you’d like to show the user an explanatory text about the error condition, you can wrap the QInput in a QField component. <!-- Notice error prop is now used on wrapper QField instead of on QInput now--><q-field :error=\"error\" error-label=\"Oh buggers! You made a boo boo.\"> <q-input v-model=\"text\" float-label=\"Colored with Error\" color=\"amber\" /></q-field> Please refer to the QField documentation for more info about its usage. Loading StateIf, for some reason, the input requires some longer term background action or process, you can add a spinner to indicate progress by setting the loading prop to true. <q-input :loading=\"loading\" v-model=\"text\" placeholder=\"Add some text...\" /> Vue Methods Vue Method Description clear() Clear the model. Sets it to empty String ''. togglePass() Applies to type “password” only. Toggles between showing legible password or not. focus() Focused the textfield. blur() Makes textfield lose focus. select() Selects all textfield text and focuses. Vue Events Vue Event Description @input(newVal) Triggered on immediate model value change. @change(newVal) Triggered on lazy model value change. @clear(clearVal) Triggered when the model is cleared. @focus Triggered on focus. @blur Triggered a blur. @keydown Triggered by keydown event on textfield. @keyup Triggered by keyup event on textfield. @click Triggered by a native click event on textfield. FormattingIt is possible to add formatting to a QInput in two ways. One is for the basic component. The other is with the QField component. Both methods offer “inverted” coloring. Additional Vue Properties Property Type Description color String The color the QInput should have. The default is primary. inverted Boolean Set to true, to color field’s background set by the color prop. inverted-light Boolean Set to true, to color field’s background set by the color prop (when that color is light). dark Boolean Set to true, if the field is on a dark background. It will invert the text color to make it light. align Text Controls the ‘right’, ‘center’ or ‘left’ alignment of the input. The default is ‘left’. Basic Formatting ExamplesThis will color the field black. <q-input v-model=\"text\" float-label=\"Colored\" color=\"black\" /> This will show an inverted colored input field in amber. Here, the text is automatically inverted to a lighter color. <q-input v-model=\"text\" inverted-light color=\"amber\" stack-label=\"Amber Colored Background\" /> AlignmentYou can also align the input to the right, center or left. The default is left. The below example will show a field for Euro currency input. <!-- Align textfield content to the right --><q-input v-model=\"number\" align=\"right\" type=\"number\" suffix=\"€\" stack-label=\"Number\" /> Basic Usage with QFieldIt is also possible to further enhance a QInput by wrapping it in a QField component. <div class=\"bg-grey-9\" style=\"width: 500px; padding: 25px\"> <q-field icon=\"wifi\" label=\"Some Label\" :count=\"10\" helper=\"Some helper\" :error=\"error\" error-label=\"Some error\" > <q-input v-model=\"text\" dark color=\"yellow\" float-label=\"Textfield\" /> </q-field></div> The above usage of QField will show the input field within a dark grey background with an inverse white text. Notice the usage of the dark prop for QInput. This controls the inversion of the text color. Please refer to the QField documentation for more info about its usage. Validations with VuelidateQuasar’s recommendation for doing form components validations is Vuelidate as it fits great with the overall architecture. It’s simple, lightweight and model-based. You need to have Vuelidate added to your project first. See here. <template> <q-input type=\"email\" :error=\"$v.email.$error\" v-model=\"email\" @blur=\"$v.email.$touch\" /></template><script>import { required, email } from 'vuelidate/lib/validators'export default { data () { return { email: '' } }, validations: { email: { required, email } }}</script> For more options like displaying an error label, a helper or character counter, wrap QInput with a QField. Here is a more involved example. Directive Modifiers for v-modelVue comes with standard modifiers on v-model, which can be useful in conjunction with QInput. They are .lazy and .trim. .lazyVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-input :value=\"model\" @change=\"val => { model = val }\"/> .trimIf you want the user’s input to be trimmed automatically, you can add the trim modifier to your v-model managed inputs: <q-input v-model.trim=\"msg\" />"},{"title":"Infinite Scroll","updated":"2018-05-20T16:04:39.315Z","permalink":"https://v0-16.quasar-framework.org/components/infinite-scroll.html","text":"When you want to progressively load new content as the user scrolls down your Page, use QInfiniteScroll component. InstallationEdit /quasar.conf.js:framework: { components: ['QInfiniteScroll']} Basic Usage<q-infinite-scroll :handler=\"loadMore\"> <!-- Content, in this case some <p> tags --> <p v-for=\"item in items\" class=\"caption\"> Lorem ipsum dolor sit amet... </p> <!-- slot=\"message\" for DOM element to display (in this example a dots spinner) when loading additional content --> <q-spinner-dots slot=\"message\" :size=\"40\"></q-spinner-dots></q-infinite-scroll> IMPORTANTInfinite Scroll loads items in advance when less than one screen height is left to be seen. If the content you fetch has height less than the container’s height on screen then Infinite Scroll will continue loading more content. So make sure you load enough content. IMPORTANTThis works best when placed as direct child of the Vue component rendering your Page. If you place it under an overflowed DOM element or component, don’t forget to set the inline prop. Vue Properties Vue Property Required Type Description handler Yes Function Method from VM to be called to load more content inline Empty Use it when you place your infinite scroll within an overflowed DOM element offset Number Offset (pixels) to bottom of Infinite Scroll container from which the component should start loading more content in advance. Default it’s one container height. Vue Methods Vue Method Description loadMore() Tells Infinite Scroll to load more content, regardless of the scroll position. reset() Resets calling index to 0. stop() Stops working, regardless of scroll position. resume() Starts working. Checks scroll position upon call and if trigger is hit, it loads more content. poll() Checks scroll position and loads more content if necessary. HandlerThe handler Function takes two parameters:loadMore: function(index, done) { // index - called for nth time // done - Function to call when you made all necessary updates. // DO NOT forget to call it otherwise your loading message // will continue to be displayed. Has optional boolean // parameter that invokes stop() when true // make some Ajax call then call done()} The index parameter can be used to make some sort of pagination on the content you load. It takes numeric values starting with 1 and incrementing with each call. Inline UsageUse it when you place your infinite scroll within an overflowed DOM element. <q-infinite-scroll :handler=\"loadMore\" inline style=\"height: 400px; overflow: auto;\"> ...</q-infinite-scroll> Controlling Infinite ScrollIf for some reason you need to control the working state of Infinite Scroll component, use a Vue reference and call methods from above. <q-infinite-scroll :handler=\"loadMore\" ref=\"infiniteScroll\"> ... <button @click=\"$refs.infiniteScroll.stop()\"> Stop Loading More </button> ...</q-infinite-scroll>"},{"title":"Integrating Layout with Router","updated":"2018-05-18T22:01:01.021Z","permalink":"https://v0-16.quasar-framework.org/components/integrating-layout-with-router.html","text":"You can benefit from Vue Router’s capabilities while structuring your routes with a Quasar Layout. The information below is just a recommendation and not mandatory to follow. Quasar allows you full freedom. Take the lines below only as an example. Layout is the component used to encapsulate pages, so that multiple pages will share the same header, left / right side and so on. However, you can also configure per page header/footer/left or right side, but they all must be children of QLayout component. In order to understand how this works, you need a little bit of reading on Vue Router nested routes. ExampleTo make it more clear, let’s take an example. We have one layout (‘user’) and two pages (‘user-feed’ and ‘user-profile’). We want to configure the website/app routes like this: /user/feed and /user/profile. First, we create the layout and its pages:$ quasar new layout user app:new Generated layout: src/layouts/user.vue +0ms app:new Make sure to reference it in src/router/routes.js +2ms$ quasar new page user-feed user-profile app:new Generated page: src/pages/user-feed.vue +0ms app:new Make sure to reference it in src/router/routes.js +2ms app:new Generated page: src/pages/user-profile.vue +1ms app:new Make sure to reference it in src/router/routes.js +0ms The commands above create the following folder structure:src/├── layouts│ └── user.vue # our QLayout definition└── pages ├── user-feed.vue # page for /user/feed route └── user-profile.vue # page for /user/profile route Our routes configuration (/src/router/routes.js) should look like this:export default [ { path: '/user', // We point it to our component // where we defined our QLayout component: () => import('layouts/user'), // Now we define the sub-routes. // These are getting injected into // layout (from above) automatically // by using <router-view> placeholder // (need to specify it in layout) children: [ { path: 'feed', component: () => import('pages/user-feed') }, { path: 'profile', component: () => import('pages/user-profile') } ] }] Please notice a few things: We are using lazy loading of layouts and pages (() => import(<path>)). If your website/app is small, then you can skip the lazy loading benefits as they could add more overhead than what it’s worth: import UserLayout from 'layouts/user'import UserFeed from 'pages/user-feed'import UserProfile from 'pages/user-profile'export default [ path: '/user', component: UserLayout, children: [ { path: 'feed', component: UserFeed }, { path: 'profile', component: UserProfile } ]] Quasar provides some out of the box Webpack aliases (‘layouts’ & ‘pages’), which are used in the above examples. Pages of a Layout are declared as children of it in the Vue Router configuration so that <router-view/> will know what page component to inject. Remember to always use this Vue component whenever your Layout has pages attached to it. <q-layout> ... <q-page-container> <!-- This is where your pages will get injected into your Layout --> <router-view /> </q-page-container> ...</q-layout> Read all Vue Router documentation to fully understand the example above and how to configure the router and its routes for your app."},{"title":"Inner Loading","updated":"2018-05-18T22:01:01.020Z","permalink":"https://v0-16.quasar-framework.org/components/inner-loading.html","text":"The QInnerLoading component allows you to add a progress animation within a component. Much like the Loading feature, it’s purpose is to offer visual confirmation to the user that some process is happening in the background, which takes an excessive amount of time. QInnerLoading will add an opaque overlay over the delayed element along with a Spinner. NoteIn order for the spinner to be properly placed in the center of the element you want the loading display to show over, that element must have the relative-position CSS class declared. NoteQInnerLoading must be the last element inside it’s parent so it can appear on top of the other content InstallationEdit /quasar.conf.js:framework: { components: [ 'QInnerLoading', //... if using custom spinner, add it too //whatever that is 'QSpinnerGears' ]} Basic Usage<div class=\"row justify-center\" style=\"margin-top: 40px\"> <q-card style=\"width: 288px; height: 262px;\" color=\"grey-2\" class=\"text-dark relative-position\"> <q-card-title> Lorem Ipsum </q-card-title> <q-card-main> <q-transition appear enter=\"fadeIn\" leave=\"fadeOut\" > <div v-show=\"showSimulatedReturnData\"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vel magna eu risus laoreet tristique. Nulla ut fermentum elit, nec consequat augue. Morbi et dolor nec metus tincidunt pellentesque. Nullam non semper ante. Fusce pellentesque sagittis felis quis porta. Aenean condimentum neque sed erat suscipit malesuada. Nulla eget rhoncus enim. Duis dictum interdum eros. </div> </q-transition> </q-card-main> <!-- Place QInnerLoading as the last child element. This is important for it to be displayed on top of the other content. --> <q-inner-loading :visible=\"visible\"> <q-spinner-gears size=\"50px\" color=\"primary\"></q-spinner-gears> </q-inner-loading> </q-card></div> View the source of the demo for the full example. Use v-show or v-if and the Inner Loading component’s :visible prop to toggle between the animation and your content. Vue Properties Vue Property Type Description dark Boolean Darkens the color of the opaque overlay for darker designs visible Boolean The loading effect becomes visible when true size Number, String Changes the default size of the default spinner. The default is 42 pixels. color String Specify color of the default spinner. NoteIf you add your own spinner, use the spinner’s own size and color prop to change the size and color. To change the spinner, you can add your own as a child of QInnerLoading component. The below code would add a teal-variation gear spinner with the size of 50 pixels. <q-inner-loading :visible=\"visible\"> <q-spinner-gears size=\"50px\" color=\"teal-4\" /></q-inner-loading> In most cases, you’ll probably want to add your own spinner, color and size. For more information on spinner control, please refer to the Spinner section of the docs."},{"title":"Icons","updated":"2018-06-14T17:09:40.307Z","permalink":"https://v0-16.quasar-framework.org/components/icons.html","text":"The Quasar Icon component allows you to easily insert icons within other components or any other area of your pages, as you’d like.Quasar currently supports: Material Icons , Font Awesome, Ionicons, MDI and IcoMoon. Except for IcoMoon (which has a license), you can either choose to use only one of them or use multiple. Quasar just needs to know which icon set to use for its components. We’ll see how we can install an icon set in the following section.Please submit a request if your favorite font icon is not listed here. InstallingIf you are building a website only, then using a CDN (Content Delivery Network) approach can be an option you can follow. However, when building a mobile or Electron app, you most likely do not want to depend on an Internet connection, so it’s best that you follow the next steps. IMPORTANTDue to the license of IcoMoon and its custom build option, this icon font is not provided by out of the box. You will need to use their website to create your custom icon font files and then copy them to your app’s folder and import them in an app plugin ($ quasar new plugin icomoon). Adding an Icon SetFirst step is to make an icon set available in your website/app. For this, edit /quasar.conf.js: extras: [ 'material-icons'] Icon sets are available through quasar-extras package. You don’t need to import it in your app, just configure /quasar.conf.js as indicated. Adding more than one set (showing all options):extras: [ 'material-icons', 'mdi', 'ionicons', 'fontawesome'] Quasar Using an Icon SetUnless configured otherwise, Quasar uses Material Icons as its icon set for its components. You can however tell Quasar to use some other icon set, but be sure to include that set in your website/app (see step above: Adding an Icon Set). So let’s say we included Ionicons and we want Quasar to use it for its components. We edit /quasar.conf.js again: framework: { iconSet: 'ionicons'} Full ExampleHere is an example of including Ionicons & Fontawesome and telling Quasar to use Fontawesome for its components. extras: [ 'ionicons', 'fontawesome'],framework: { iconSet: 'fontawesome'} This will enable you to use both Ionicons & Fontawesome in your app, and all Quasar components will display Fontawesome icons. Including from CDNIf you want to make use of CDNs (Content Delivery Network), all you need is to include style tags in your index.template.html which point to the CDN URL. In case you follow this path, do not also add the icon sets that you want in /quasar.conf.js > extras. Simply edit index.template.html as follows. The example link tag below would include Font Awesome v4.7.0 icons. Do a Google search for CDNs to make sure you include the latest version. Following are just examples. <!-- in `/src/index.template.html` --><head> ... <!-- CDN example for Material Icons --> <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/icon?family=Material+Icons\" > <!-- CDN example for Fontawesome 5.0.13 --> <link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.0.13/css/all.css\" integrity=\"sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp\" crossorigin=\"anonymous\" > <!-- CDN example for Ionicons --> <link rel=\"stylesheet\" href=\"https://unpkg.com/[email protected]/dist/css/ionicons.min.css\" ></head> Using Fontawesome-ProIf you have a Fontawesome 5 Pro license and want to use it instead Fontawesome Free version. Following this instructions. Open Linked Accounts section in Fontawesome’s user account page to grab npm TOKENID (login if necessary). Create or append TOKENID into file .npmrc (file path same as package.json): @fortawesome:registry=https://npm.fontawesome.com/TOKENID Install Fontawesome webfonts: $ yarn add @fortawesome/fontawesome-pro-webfonts# or:$ npm install @fortawesome/fontawesome-pro-webfonts Create new App plugin: $ quasar new plugin fontawesome-pro Edit /quasar.conf.js: plugins: [ ... 'fontawesome-pro' // Add app plugin],extras: [ // 'fontawesome' // Disable free version!],framework: { // if you want Quasar to use Fontawesome for its icons iconSet: 'fontawesome-pro' // requires Quasar v0.15.6+} Edit /src/plugins/fontawesome-pro.js: // requiredimport '@fortawesome/fontawesome-pro-webfonts/css/fontawesome.css'import '@fortawesome/fontawesome-pro-webfonts/css/fa-light.css'// do you want these too?// import '@fortawesome/fontawesome-pro-webfonts/css/fa-brands.css'// import '@fortawesome/fontawesome-pro-webfonts/css/fa-solid.css'// import '@fortawesome/fontawesome-pro-webfonts/css/fa-regular.css'export default () => { // Leave blank or make something cool.} (Optional) Override default icons: Since the default font-weight for fontawesome-pro is light or fal, some icons used by the framework components may not be desirable. The best way to handle this is to override it in the plugin you created. For instance, to override the fal version of the close icon for chips, do this: First, find the icon used for chip close in Quasar’s quasar/icons/fontawesome-pro.js (Alternatively, you can check inside the render function of the component you are overriding.) chip: { close: 'fal fa-times-circle'}, Then, override it in your /src/plugins/fontawesome-pro.jsimport '@fortawesome/fontawesome-pro-webfonts/css/fontawesome.css'import '@fortawesome/fontawesome-pro-webfonts/css/fa-solid.css'import '@fortawesome/fontawesome-pro-webfonts/css/fa-light.css'export default ({ Vue }) => { Vue.prototype.$q.icon.chip.close = 'fas fa-times-circle'} Basic UsageLet’s take a look at how we can use QIcon component. Do not forget to check above how to Install Icon Sets, otherwise they won’t show up! <!-- Material icons have no prefix --><q-icon name=\"thumb_up\" /><!-- Ionicons have \"ion-\", \"ion-logo\", \"ion-md-\" or \"ion-ios-\" as prefix --><q-icon name=\"ion-heart\" /><!-- Fontawesome icons have \"fa[s|r|l|b] fa-\" prefix --><q-icon name=\"fas fa-id-card\" /><!-- MDI icons have \"mdi-\" prefix --><q-icon name=\"mdi-account-card-details\" /><!-- IcoMoon icons have \"icon-\" prefix --><q-icon name=\"icon-chrome\" /><!-- or if you prefer the non self-closing tag version which allows to add a QPopover or QTooltip:--><q-icon name=\"thumb_up\"> <q-tooltip>Some tooltip</q-tooltip></q-icon> For “icon” properties on different Quasar components you won’t have the means to specify an icon for each platform, but you can achieve the same effect with: <q-item-side :icon=\"$q.theme === 'mat' ? 'settings' : 'ion-ios-gear-outline'\"/> Vue Properties Vue Property Type Description name String The name of the icon to be used (for both Quasar themes). color String One color from the Quasar Color Palette. size String Example: ‘12px’, ‘3.2rem’, ‘14pt’. Size & ColorsAll icons are font icons. This means that you can change size by manipulating font-size CSS property. And also, they inherit the current CSS color used. <q-icon name=\"mail\" style=\"font-size: 25px\" /><div style=\"color: #a2e2e3\"> ... <!-- inheriting color #a2e2e3: --> <q-icon name=\"alarm\" /></div> Colors from the Quasar Color Palette can be specified in two ways:<q-icon name=\"mail\" class=\"text-red\" /><!-- or by using `color` prop: --><q-icon name=\"alarm\" color=\"red\" /><q-icon name=\"alarm\" color=\"green-2\" /> There’s also a “size” property:<q-icon name=\"wifi\" size=\"2rem\" /><q-icon name=\"delete\" size=\"24px\" /> Cheatsheet Name Prefix Examples Notes material-icons None thumb_up Notice the underline character instead of dash or space ionicons ion-, ion-md-, ion-ios-, ion-logo- ion-heart, ion-logo-npm, ion-md-airplane Use QIcon instead of <ion-icon> component; Logo icons require ‘ion-logo-‘ prefix fontawesome fa[s,r,l,b] fa- “fas fa-ambulance” QIcon “name” property is same as “class” attribute value in Fontawesome docs examples (where they show <i> tags) mdi mdi- mdi-alert-circle-outline Notice the use of dash characters More ExamplesWith HTML native style attribute: <q-icon name=\"thumb_up\" style=\"font-size: 5rem;\" /> With HTML native class attribute: <q-icon name=\"thumb_up\" class=\"big-icon\" /> NoteTo create the necessary CSS class, you would need to define the class within your component’s style section as below. Watch for CSS class clashes though. <style lang=\"stylus\">.big-icon font-size: 5rem</style> Adding a click event handle. Remember we want to capture a native DOM event and this is a Vue component, so we use the ‘.native’ modifier:<q-icon name=\"map\" @click.native=\"handle\"/>"},{"title":"Knob","updated":"2018-07-23T16:37:49.845Z","permalink":"https://v0-16.quasar-framework.org/components/knob.html","text":"Quasar Knob is another way of making the user select a Number value from a predefined range. With optional steps included. See demo. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QKnob']} Basic Usage<q-knob v-model=\"model\" :min=\"min\" :max=\"max\"/><!-- With custom placeholder --><q-knob v-model=\"model\" :min=\"min\" :max=\"max\" :placeholder=\"'$ ' + model\"/><!-- Disabled state --><q-knob disable v-model=\"model\" :min=\"min\" :max=\"max\"/> Vue PropertiesSupports v-model which should be a Number. Vue Property Type Description size String CSS String determining the width and height of the Knob. Examples: “120px”, “12rem”. step Number Number representing difference between two values that the model can take. Default: 1. min Number Minimum value that the model can take. max Number Maximum value that the model can take. color String One from Quasar Color Palette. trackColor String One from Quasar Color Palette. lineWidth String Line width of Knob. Default is ‘6px’. readonly Boolean Sort of a “display” only mode. Model cannot be altered. disable Boolean When set to true the model cannot be altered. Vue Events Vue Event Description @input(newVal) Triggered immediately on model value change. @change(newVal) Triggered on lazy model value change. @drag-value(val) (v0.15.11+) Triggered while dragging (or clicking) on Knob. More ExamplesLazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-knob :value=\"model\" @change=\"val => { model = val }\" :min=\"min\" :max=\"max\"/> We can go a step further and display the current value while dragging:<!-- v0.15.11+ --><q-knob :value=\"model\" @change=\"val => { model = val }\" @drag-value=\"val => { currentValue = val }\" :min=\"min\" :max=\"max\"> {{ currentValue }}</q-knob> Multi-colored with a Euro icon. <q-knob v-model=\"model\" size=\"120px\" style=\"font-size: 1.5rem\" color=\"secondary\" track-color=\"yellow-3\" line-width=\"5px\" :min=\"min\" :max=\"max\" :step=\"5\"> <q-icon class=\"on-left\" name=\"euro_symbol\" /> {{model}}</q-knob> Read-only state (different than disabled, as the mouse pointer doesn’t change).<q-knob v-model=\"model\" :min=\"min\" :max=\"max\" color=\"primary\" readonly> <q-icon class=\"on-left\" name=\"volume_up\" /> {{model}}</q-knob> Using a QField to highlight error state.<q-field label=\"Knob\" icon=\"cake\" helper=\"Touch to change\" :error=\"knobHasError\" error-label=\"Invalid value selected.\"> <q-knob v-model=\"model\" :min=\"min\" :max=\"max\" > <q-icon class=\"on-left\" name=\"volume_up\" /> {{model}} </q-knob></q-field>"},{"title":"Layout Drawer","updated":"2018-07-23T16:37:49.846Z","permalink":"https://v0-16.quasar-framework.org/components/layout-drawer.html","text":"QLayout allows you to configure your views as a 3x3 matrix, containing an optional Header and/or Footer. If you haven’t already, please read QLayout documentation page first. InstallationEdit /quasar.conf.js:framework: { components: [ 'QLayoutDrawer' ]} Basic Usage<q-layout> ... <q-layout-drawer side=\"left\"> <!-- drawer content --> </q-layout-drawer> ...</q-layout> QLayoutDrawer Vue Properties Vue Property Type Description side String One of ‘left’ or ‘right’, depending on the Drawer position on Layout. overlay Boolean Overlay mode breakpoint Number Breakpoint (in pixels, defining window width) at which point the Drawer will be placed directly over the layout and won’t act as a mobile drawer anymore. Default is 992 (up to “sm”, including). behavior String One of ‘default’, ‘desktop’, ‘mobile’. The last two override the breakpoint and makes Drawer act only as on desktop or only as on mobile modes, regardless of window width. no-hide-on-route-change Boolean (Quasar v0.15.7+) Disable hiding of Drawer during route changes. no-swipe-open Boolean Disable ability to open Drawer by touch actions. no-swipe-close Boolean Disable ability to close Drawer by touch actions. Useful if you have components in your Drawer which require touch actions. The backdrop will still work with touch actions. content-style Object CSS Style in Object format for the Drawer container element. content-class String/Object/Array CSS classes for the Drawer container element. mini Boolean (v0.15.11+) If drawer is in mini mode or not. mini-width String (v0.15.11+) CSS unit for drawer width when in mini mode. Default: ‘60px’ Styling Examples<q-layout-drawer content-class=\"bg-grey-3\" :content-style=\"{padding: '20px'}\" side=\"left\"> ...</q-layout-drawer> The Vue Object notation for content-style is mandatory. <q-layout-drawer :content-class=\"['bg-grey-3', 'q-pa-sm']\" side=\"left\"> ...</q-layout-drawer> The BreakpointIf you’ve played with the layout in desktop mode, you might notice how the left and right sides / drawers magically hide, as you decrease the screen width. This is part of the smart responsiveness designed into Quasar’s layout component. If you’d like to control how the left and right side / drawers work, you have a prop called breakpoint on each QLayoutDrawer. This value represents the minimum size of the screen in pixels, before the Drawer is forced to float above the Layout. This is a fantastic and important function in maximizing screen real estate for smaller devices. TipAlso take a look at the behavior property if you want the Drawer to act only as on a narrow screen or only as on a wide screen, effectively disable the breakpoint. Using v-modelThere’s the possibility to use v-model to control the state of Drawer (opened/showing and closed/hidden). <template> ... <q-layout-drawer v-model=\"drawer\"> ... </q-layout-drawer> ... <q-btn @click=\"drawer = !drawer\" flat round dense icon=\"menu\" /> ...</template><script>export default { data () { return { // \"false\" means hidden // \"true\" means visible drawer: true } }}</script> Please note that the model can instantly get changed upon Drawer being rendered if the breakpoint requires it. Mini modeRequires Quasar v0.15.11+ Drawer can operate in two modes: ‘normal’ and ‘mini’, and you can switch between them by using the Boolean mini property on QLayoutDrawer. Please note that “mini” mode does not apply when in “mobile” behavior. CSS classesThere are some CSS classes that will help you customize the drawer when dealing with “mini” mode. These are very useful especially when using the “click” trigger: CSS Class Description q-mini-drawer-hide Hide when drawer is in “mini” mode. q-mini-drawer-only Show only when drawer is in “mini” mode. You can also write your own CSS classes based on the fact that QLayoutDrawer has q-layout-drawer-normal CSS class when in “normal” mode and q-layout-drawer-mini when in “mini” mode. Also, when drawer is in “mobile” behavior, it gets q-layout-drawer-mobile CSS class. SlotsBy default, when in “mini” mode, Quasar CSS hides a few DOM elements to provide a neat narrow drawer. But there may certainly be use-cases where you need a deep tweak. You can use the “mini” Vue slot of QLayoutDrawer just for that. The content of this slot will replace your drawer’s default content when in “mini” mode. <template> ... <q-layout-drawer :mini=\"miniState\" > <!-- drawer content when not \"mini\" --> <div slot=\"mini\"> <!-- drawer content when in \"mini\" mode --> </div> </q-layout-drawer> ...</template><script>export default { data () { return { miniState: false } }}</script> Example with mouseover/mouseout trigger<template> ... <q-layout-drawer :mini=\"miniState\" @mouseover=\"miniState = false\" @mouseout=\"miniState = true\" > <!-- drawer content --> </q-layout-drawer> ...</template><script>export default { data () { return { miniState: false } }}</script> Example with click triggerWhen in “mini” mode, if user clicks on Drawer then we switch to normal mode. <template> ... <q-layout-drawer :mini=\"miniState\" @click.capture=\"drawerClick\" > <!-- drawer content --> <!-- we also need a way for user to be able to switch back to \"mini\" mode, so here's an example with a button which gets hidden when on \"mini\" mode: --> <q-btn class=\"q-mini-drawer-hide\" label=\"Go to mini state\" @click=\"miniState = true\" /> </q-layout-drawer> ...</template><script>export default { data () { return { miniState: false } }, methods: { drawerClick (e) { // if in \"mini\" state and user // click on drawer, we switch it to \"normal\" mode if (this.miniState) { this.miniState = false // notice we have registered an event with capture flag; // we need to stop further propagation as this click is // intended for switching drawer to \"normal\" mode only e.stopPropagation() } } }}</script>"},{"title":"JS Animations","updated":"2018-05-18T22:01:01.022Z","permalink":"https://v0-16.quasar-framework.org/components/js-animations.html","text":"You can create animations through Javascript (using RAF - requestAnimationFrame()) with Quasar. import { animate } from 'quasar'let id = animate.start({ name: 'unique-animation-name', // optional, if none is supplied a unique one is created and returned from: '0', // current position to: '100', // final position duration: 300, // duration of the animation done (finalPosition) {...}, // function to call when animation is done cancel (currentPosition) {...}, // function to call when animation is aborted apply (currentPosition) {...}, // function called on each step so you can apply changes easing (currentPosition) { // custom easing function, see below // ...return transformation of currentPosition... }})// Starting an animation with same name will abort the previous one// Stop an animation using its nameanimate.stop('unique-animation-name')// oranimate.stop(id) // id returned from above Example:import { animate } from 'quasar'animate.start({ from: 6, to: 158, apply (pos) { el.style.maxHeight = `${pos}px` }, done () { console.log(`we're done!`) }}) Easing FunctionsEasing functions take the current percent progress of the animation (a float between 0 and 1) and return a position multiplier (0 being initial position and 1 being final position). The following easing functions are included: ease[In|Out|InOut][Quad|Cubic|Quart|Quint|Circ] For example, easeInCubic. Quad through Quint get progressively more exaggerated. Circ is slightly different (the graph is a quarter circle), it accelerates much faster at the end. overshoot Shoots past the end position and returns slowly Material Design Curves: standard Use for on-screen movement. Accelerates quickly, decelerates slowly decelerate Use for elements entering the screen. Flies in and slowly decelerates (easeOutCubic). accelerate Use for elements leaving the screen. Accelerates and then leaves at full velocity (easeInCubic). sharp Use for elements leaving the screen that may return (e.g. navigation bar). Accelerates and decelerates (easeInOutQuad) Example:import { animate, easing } from 'quasar'animate.start({ from: 0, to: 100, easing: easing.standard ...}) Or with the carousel:<template> <q-carousel :swipe-easing=\"overshoot\"> Slides... </q-carousel></template><script>import { easing, QCarousel } from 'quasar'export default { components: { QCarousel }, data: () => ({ overshoot: easing.overshoot })}</script>"},{"title":"Introduction for Beginners","updated":"2018-05-20T16:04:39.316Z","permalink":"https://v0-16.quasar-framework.org/components/introduction-for-beginners.html","text":"Before you begin with Quasar, it is a good idea to get acquainted with ES6 and have a fairly good knowledge about how Vue works. (quick overview of ES6 and full description – don’t worry, you don’t need to understand ALL of ES6). For devs experienced with reactive UIs, the Vue documentation itself takes half a day at most to read top-to-bottom and will help you understand how Quasar components can be used and configured. If you are a total beginner to Vue and reactive UI libraries and want a good tutorial, we recommend you take a look at the Udemy Course - Vue JS 2 - The Complete Guide. After reading the Vue documentation, let’s clear up some of the most frequently asked questions, like “How can I use Quasar components, Vue properties, methods and events”. Single File Vue ComponentsYou’ll be building your Quasar app using *.vue files which contain multiple sections: ‘template’ (HTML), ‘script’ (Javascript) and ‘style’ (CSS). <template> <!-- you define your Vue template here --></template><script>// This is where your Javascript goes// to define your Vue component, which// can be a Layout, a Page or your own// component used throughout the app.export default { //}</script><style>/* This is where your CSS goes */</style> CSS preprocessorsFor the <style> tag, you can also use whatever CSS preprocessor you want. Stylus is available out of the box. For SCSS/SASS or LESS, you’ll need to install their Webpack loaders (example: yarn add --dev less-loader or npm install --save-dev less-loader). After installing the loader you need (remember Stylus is already installed for you), you can specify you want your chosen preprocessor to handle the CSS code you’re writing: <!-- notice lang=\"stylus\" --><style lang=\"stylus\">.some-div font-size 15px</style> In the above example, you would replace stylus with the preprocessor you’ve chosen. Using Quasar DirectiveQuasar comes with a few custom Vue Directives. These directives can be applied on almost any DOM element or Component. Example of a Quasar directive:<div v-ripple>Click Me</div> Notice how Ripple is used in the HTML template as v-ripple. Vue directives are prefixed with v-. In order for you to use any of the directives that Quasar supplies, you first need to tell Quasar you want it embedded. Open /quasar.conf.js file and add the following reference: framework: { directives: ['Ripple']} Let’s take another example. We now also want TouchPan and TouchSwipe directives, so we add them too in /quasar.conf.js:framework: { directives: ['Ripple', 'TouchPan', 'TouchSwipe']} Now we can write in your Vue files template: <div v-touch-pan=\"handler\">...</div><div v-touch-swipe=\"handler\">...</div><div v-ripple>Click me. I got ripples.</div> Using Quasar ComponentsQuasar components have names beginning with “Q” like “QBtn” or “QElementResizeObservable”. In order to use them, you need to add a reference to them in /quasar.conf.js. Let’s take the following example with a QBtn and QIcon and then we’ll see how to embed these components in our app:<div> <q-btn @click=\"doSomething\">Do something</q-btn> <q-icon name=\"alarm\" /></div> Notice how QBtn is used in the Vue HTML template as <q-btn>. If we’d import QElementResizeObservable, then we’d use it in template as <q-element-resize-observable>. Now on /quasar.conf.js, you would add:framework: { components: ['QBtn', 'QIcon']} Using Quasar PluginsQuasar Plugins are features that you can use both in your Vue files as well as outside of them, like Notify, ActionSheet, AppVisibility and so on. In order to use them, you need to add a reference to them in /quasar.conf.js:framework: { plugins: ['Notify', 'ActionSheet']} Let’s take Notify as an example and see how we can then use it. In a Vue file, you’d write something like this:<template> <div> <q-btn @click=\"$q.notify('My message')\" color=\"primary\" label=\"Show a notification\" /> <q-btn @click=\"showNotification\" color=\"primary\" label=\"Show another notification\" /> </div></template><script>export default { methods: { showNotification () { this.$q.notify('Some other message') } }}</script> Notice that in the template area we’re using $q.<plugin-name> and in our script we say this.$q.<plugin-name>. Now let’s see an example of Notify being used outside of a Vue file:import { Notify } from 'quasar'// ...Notify.create('My message') Importing All Components and Directives for Quick TestReferencing all Quasar Components, Directives and Plugins can be tiresome when you just want to do a quick test. In this case, you can tell Quasar to import them all by editing /quasar.conf.js like this: framework: 'all' IMPORTANTThis will not take advantage of tree shaking, causing your bundle to become bloated with unnescesary/unused code. Not recommended for production. Use this only for quick testing purposes. Self Closing TagsSome Quasar components do not need you to include HTML content inside of them. In this case, you can use them as self closing tags. One example with QIcon below: <q-icon name=\"cloud\" /> Self-closing means the above template is the equivalent to: <q-icon name=\"cloud\"></q-icon> Both forms are valid and can be used. It works the same with regular DOM elements: <div class=\"col\" /><!-- equivalent to: --><div class=\"col\"></div> Some eslint-plugin-vue linting rules actually enforce using the self-closing syntax. Handling Vue PropertiesYou will notice throughout the documentation that Quasar components have a section called “Vue Properties”. These are often called Props in Vue documentation. Example: Vue Property Type Description infinite Boolean Infinite slides scrolling size String Thickness of loading bar. speed Number How fast should loading bar update its value (in milliseconds). columns Object Object defining columns (see “Columns Definition” below). offset Array Array with two numbers. Offset on horizontal and vertical (in pixels). Let’s take some examples with a bogus Quasar component (we will call it QBogus) that supports the properties above. We will discuss each of the types of Vue properties in the below sections. Boolean PropertyA boolean property means it only accepts a strictly Boolean value. The values will not be cast to Boolean, so you must ensure you are using a true Boolean. If you are trying to control that property and change it dynamically at runtime, then bind it to a variable in your scope:<template> <q-bogus :infinite=\"myInfiniteVariable\" /></template><script>export default { data () { return { myInfiniteVariable: false } }}</script> If, on the other hand, you know this Boolean value is not going to change, you can use the shorthand version of the variable like a component attribute and just specify it. In other words, if you don’t bind the variable to a variable in the component’s scope as it will always be true:<template> <q-bogus infinite /> <!-- the following is perfectly valid, but it's a longer version --> <q-bogus :infinite="true" /></template> String PropertyAs you can imagine, Strings are required as a value for this type of property.<template> <!-- direct assignment, no need for a variable in our scope --> <q-bogus size=\"24px\" /> <!-- we can also bind it to a variable in our scope so we can dynamically change it --> <q-bogus :size=\"mySize\" /></template><script>export default { data () { return { // notice String as value mySize: '16px' } }}</script> Number Property<template> <!-- Case 1. Direct assignment. Notice the colon (\":\") before property name. --> <q-bogus :speed=\"50\" /> <!-- Case 2. Assignment through a scope variable --> <q-bogus :speed=\"myNumber\" /></template><script>export default { data () { return { // notice Number as value myNumber: 50 } }}</script> Object Property<template> <!-- Case 1. Direct assignment. --> <q-bogus :columns=\"{key: 'value', anotherKey: 'another value'}\" /> <!-- or a more elegant way for Case 1: --> <q-bogus :columns=\"{ key: 'value', anotherKey: 'another value' }\" /> <!-- Case 2. Assignment through a scope variable --> <q-bogus :columns=\"myColumns\" /></template><script>export default { data () { return { myColumns: { key: 'value', anotherKey: 'another value' } } }}</script> Array Property<template> <!-- Case 1. Direct assignment. --> <q-bogus :offset=\"[10, 20]\" /> <!-- Case 2. Assignment through a scope variable --> <q-bogus :offset=\"myOffset\" /></template><script>export default { data () { return { myOffset: [10, 20] } }}</script> Handling Vue MethodsYou will notice throughout the documentation that some Quasar components have a section called “Vue Methods”. Example: Vue Method Description next() Goes to next slide. previous(doneFn) Goes to previous slide. toggleFullscreen() Toggles fullscreen mode. In order for you to access these methods, you will need to set a Vue reference on the component first. Here’s an example: <template> <!-- Notice ref=\"myRef\". We will use the name assigned to \"ref\" in the script part below --> <q-bogus ref=\"myRef\" /></template><script>export default { // we can now access `this.$refs.myRef` // an example on the mounted() Vue component hook mounted () { // calling \"next()\" method: this.$refs.myRef.next() } // calling before mount point might result in errors // as Vue hasn't yet prepared the Vue references}</script> Handling Vue EventsYou will notice throughout the documentation that some Quasar components have a section called “Vue Events”. Do not confuse these Vue events with the Global Event Bus as these two have nothing in common. Example of “Vue Events” section in docs: Event Name Description @open Triggered right after the Modal is opened. @close Triggered right after the Modal is closed. In order for you to catch these events, when they are triggered, you will need to add listeners for them on the component itself in the HTML template. Here’s an example: <template> <q-bogus @open=\"doSomething\" @close=\"doSomethingElse\" /></template><script>export default { methods: { doSomething () { // this method has been called (in this case) // because @open event was triggered by QBogus component }, doSomethingElse () { // this method has been called (in this case) // because @close event was triggered by QBogus component } }}</script> There are times when you need to access native DOM events on a Quasar component too, like the native @click. Do not confuse native events with the Vue events emitted by the component. They are different things. Let’s take an example: let’s say we have a component (QBogus) that emits @open and @close, but doesn’t emit a @click event. @click being a native DOM event, we can still catch it with the .native modifier: <!-- Notice \"@click.native\" --><q-bogus @click.native=\"myMethod\" />"},{"title":"Layout Page","updated":"2018-07-23T16:37:49.847Z","permalink":"https://v0-16.quasar-framework.org/components/layout-page.html","text":"QLayout must contain page content. If you haven’t already, please read QLayout documentation page first. InstallationEdit /quasar.conf.js:framework: { components: [ 'QPageContainer', 'QPage' ]} Basic UsageA QPage must be encapsulated by QPageContainer, which in turn must be a child of QLayout. <q-layout> ... <q-page-container> <q-page> <!-- page content --> </q-page> </q-page-container></q-layout> Usually, the QPageContainer is part of the Layout template (where it contains a <router-view /> child only), and its content goes into separate vue files under /src/pages. If you haven’t already, please read Integrating Layout with Router. <!-- vue file for Layout: --><q-layout> ... <q-page-container> <router-view /> </q-page-container></q-layout><!-- vue file for a Page: --><q-page padding> <!-- page content --></q-page> QPage Vue Properties Vue Property Type Description padding Boolean Adds a default dynamic padding to the page."},{"title":"Internationalization (I18n)","updated":"2018-05-28T18:14:34.613Z","permalink":"https://v0-16.quasar-framework.org/components/internationalization.html","text":"Internationalization is a design process that ensures a product (a website or application) can be adapted to various languages and regions without requiring engineering changes to the source code. Think of internationalization as readiness for localization. The recommended package for handling website/app is vue-i18n. It should be noted that what is described below is the internationalization of quasar-framework components. If you need to internationalize your own components, read the documentation indicated above and configure the project by editing the files located in <project>/src/i18n The following is an example recipe for using vue-i18n embedded <i18n> template components in your vue files with vue-i18n-loader, which you have to add in your quasar.conf.js. In this case the translations are stored in yaml format in the block. // quasar.confbuild: { // OR use the equivalent chainWebpack() // with its own chain statements (CLI v0.16.2+) extendWebpack (cfg) { cfg.module.rules.push({ resourceQuery: /blockType=i18n/, use: [ {loader: '@kazupon/vue-i18n-loader'}, {loader: 'yaml-loader'} ] }) ... }} However, handling i18n in app-space is not enough. Quasar components have their own labels too. One option is to configure labels through label properties on each instance of Quasar components like QTable or QDatetime. This takes time and adds unnecessary complexity to your website/app. Instead, use the Quasar I18n (applies to Quasar components only!) system. For a complete list of available languages, check Quasar I18n on Github.If your desired language is not on that list, then feel free to submit a PR to add it. It takes from 5 to 10 minutes at most. We kindly welcome any language! Configuring the Default LanguageEdit /quasar.conf.js:framework: { i18n: 'de'} Dynamically Changing LanguageExample with a QSelect to dynamically change the Quasar components language:<template> <q-select stack-label=\"I18n\" :options=\"[ { label: 'English (US)', value: 'en-us' }, { label: 'English (UK)', value: 'en-uk' }, { label: 'Romanian', value: 'ro' }, { label: 'Chinese (Simplified)', value: 'zh-hans' }, { label: 'Italian', value: 'it' } { label: 'Spanish', value: 'es' } { label: 'French', value: 'fr' } { label: 'German', value: 'de' }, { label: 'Russian', value: 'ru' }, ....... ]\" v-model=\"lang\" /></template><script>export default { data () { return { lang: this.$q.i18n.lang } }, watch: { lang (lang) { // dynamic import, so loading on demand only import(`quasar-framework/i18n/${lang}`).then(lang => { this.$q.i18n.set(lang.default) }) } }}</script> Using Quasar I18n in App SpaceAlthough the Quasar I18n is designed only for Quasar components, you can still use it for your own website/app components too. \"Close\" label in current Quasar I18n language is:{{ $q.i18n.label.close }} Detecting LocaleThere’s also a method to determine user locale which is supplied by Quasar out of the box:// outside of a Vue fileimport Quasar from 'quasar'Quasar.i18n.getLocale() // returns a string// inside of a Vue filethis.$q.i18n.getLocale() // returns a string Handling Quasar UMDTo add a Quasar language pack you need to include the language pack JS tag for your Quasar version and also tell Quasar to use it. Example: <!-- include this after Quasar JS tag --><script src=\"https://cdn.jsdelivr.net/npm/quasar-framework@latest/dist/umd/i18n.pt-br.umd.min.js\"></script><script> Quasar.i18n.set(Quasar.i18n.ptBr)</script> Check what tags you need to include in your HTML files by generating a sample with $ vue init quasarframework/quasar-starter-kit-umd <folder> and specifying a language code for Quasar I18n (other than default “en-us”)."},{"title":"Layout Header & Footer","updated":"2018-05-18T22:01:01.024Z","permalink":"https://v0-16.quasar-framework.org/components/layout-header-and-footer.html","text":"QLayout allows you to configure your views as a 3x3 matrix, containing an optional Header and/or Footer. If you haven’t already, please read QLayout documentation page first. InstallationEdit /quasar.conf.js:framework: { components: [ 'QLayoutHeader', 'QLayoutFooter' ]} Basic Usage<q-layout> ... <q-layout-header v-model=\"header\"> <!-- header content --> </q-layout-header> ... <q-layout-footer v-model=\"footer\"> <!-- footer content --> </q-layout-footer> ...</q-layout> QLayoutHeader/QLayoutFooter Vue Properties Vue Property Type Description reveal Boolean Scrolling hides header/footer. reveal-offset Number (Default: 250) Scrolling distance in pixels that triggers the hide. Reveal PropertyYou’ll notice in playing with the QLayout view configuration that if you set the header to “hhh” (all small letters), the header will be set to a static position at the top of the page. This in turn means, the header will move off the screen as the user scrolls down the page. If the user then needs to use the navigation in the header, he/she must scroll completely up to top of the page to get to it and this is bad UX. One way to help the user is to add a back-to-top button on the page. Another way is to use the reveal prop. The reveal prop overrides “H” in QLayout view prop, by fixing the header to the top of the screen. As the user scrolls down more than reveal-offset pixels, the header rolls up it’s own height above the top of the screen. As soon as the user scrolls back up (just 1 pixel), the header comes into view again immediately. Same goes for QLayoutFooter. Hiding Header/Footer CompletelyQLayoutHeader and QLayoutFooter support a Boolean v-model which determines if they take up space on screen or not. This does not interferes with the reveal property, which works only if the v-model is set to true. <template> ... <q-layout-header v-model=\"state\"> ... </q-layout-header> ...</template><script>export default { data () { return { state: true } }, methods: { toggleHeader () { this.state = !this.state } }}</script> QLayoutHeader/QLayoutFooter Vue Events Vue Event Description @reveal(state) Emitted when reveal state changes. Handling Quasar ThemesYou can make some tweaks to distinguish between Material and iOS themes. You’ll notice in the demo that header and footer has different looks based on Quasar theme. Here’s an example how to do it below. Notice that in this example we also place navigational tabs in header (for Material) or footer (for iOS): <!-- layout.vue --><q-layout-header reveal> <q-toolbar :inverted=\"$q.theme === 'ios'\"> .... </q-toolbar> <nav-tabs v-if=\"$q.theme === 'mat'\" /></q-layout-header><q-layout-footer reveal v-if=\"$q.theme === 'ios'\"> <nav-tabs /></q-layout-footer><!-- nav-tabs.vue --><q-tabs :inverted=\"$q.theme === 'ios'\"> <q-route-tab......</q-tabs>"},{"title":"Loading","updated":"2018-07-23T16:37:49.850Z","permalink":"https://v0-16.quasar-framework.org/components/loading.html","text":"Loading is a feature that you can use to display an overlay with a spinner on top of your App’s content to inform the user that a background operation is taking place. No need to add complex logic within your Pages for global background operations. InstallationEdit /quasar.conf.js:framework: { plugins: ['Loading']} Basic UsageLoading uses a delay (500ms) to display itself so that quick operations won’t make the screen flicker. This happens by showing and then quickly hiding the progress spinner without the user having a chance to see what happens. The delay before showing it eliminates confusion. Show LoadingInside a Vue component:this.$q.loading.show({ delay: 400 // ms}) Outside of a Vue component:import { Loading, // optional!, for example below // with custom spinner QSpinnerGears} from 'quasar'// default optionsLoading.show()// with a custom delayLoading.show({ delay: 300 // milliseconds})// customizable (all props available)Loading.show({ spinner: QSpinnerGears, message: 'Some message', messageColor: 'blue', spinnerSize: 250, // in pixels spinnerColor: 'white', customClass : 'bg-primary'}) Hide LoadingInside a Vue component:this.$q.loading.hide() Outside of a Vue component:import { Loading } from 'quasar'Loading.hide() Check StatusChecking whether the Loading is active is easy. Inside a Vue component:this.$q.loading.isActive Outside of a Vue component:import { Loading } from 'quasar'(Boolean) Loading.isActive"},{"title":"Lists and List Items","updated":"2018-07-23T16:37:49.849Z","permalink":"https://v0-16.quasar-framework.org/components/lists-and-list-items.html","text":"Quasar Lists and List Items are a group of components which can work together to present multiple line items vertically as a single continuous element. They are best suited for displaying similar data types as rows of information, such as a contact list, a playlist, or menu. Each row is called an Item. Items can also be used outside of a List. Lists can encapsulate Items or Item-like components, for example QCollapsible. List Items have following content areas: left side and right side (usually equipped for supplemental actions represented by icons, avatars, images or letters, but not limited to only these) main content which usually is filled with a label (title) and sublabel (subtitle), form components, or anything else for that matter. InstallationEdit /quasar.conf.js:framework: { components: [ 'QList', 'QListHeader', 'QItem', 'QItemMain', 'QItemSeparator', 'QItemSide', 'QItemTile' ], // if you use v-close-overlay: directives: ['CloseOverlay']} Basic UsageWe’ll cover each component on its own section later on, but for now, take a look to get a glimpse of how to structure your templates when using Lists. <q-list highlight> <q-list-header>Recent chats</q-list-header> <q-item> <q-item-side> <q-item-tile avatar> <img src=\"statics/boy-avatar.png\"> </q-item-tile> </q-item-side> <q-item-main label=\"John Doe\" /> <q-item-side right> <q-item-tile icon=\"chat_bubble\" color=\"green\" /> </q-item-side> </q-item> <q-item> <q-item-side avatar=\"statics/linux-avatar.png\" /> <q-item-main label=\"Jim Doe\" /> <q-item-side right icon=\"chat_bubble\" /> </q-item> <q-item-separator /> <q-list-header>Previous chats</q-list-header> <q-item> <q-item-side avatar=\"statics/guy-avatar.png\" /> <q-item-main label=\"Jack Doe\" /> </q-item></q-list> Notice that QItemMain and QItemSide can contain QItemTiles, or for convenience, you can use their own properties to define the content. Due to how Webpack works in creating the bundle for your App, in some cases you may need to use QItemTile, like for avatars or images. The reason is simple: if you use QItemSide avatar property, you must supply the path to the statics folder and cannot use the assets folder or relative paths. Instead, the latter two can be used with a QItemTile wrapping an <img> HTML tag. Look closely at image paths in the example above (statics/guy-avatar.png vs ~assets/boy-avatar.png). Also read about App Handling Static Assets to understand how Webpack includes assets into the bundle. ComponentsBelow is a list of Quasar components that you can use to define lists and list items: QList (encapsulating QItems and all other List related components) QListHeader (header of a section in QList) QItemSeparator (external Item separator/separator) QItem (encapsulating everything an Item contains) QItemSide (left or right side) QItemMain (for main content of an Item) QItemTile (for individual parts of QItemSide and QItemMain, like label, icon, avatar, image, …) QListQList encapsulates all other components mentioned. It’s not mandatory, but does help with maintaining a good design and can also define some properties that will be applied to all QItems (or QItem-like components) like multiline, separator, link, highlight and so on. Vue Property Type Description striped Boolean Apply highlight to QItems intermittently, starting with second QItem. striped-odd Boolean Apply highlight to QItems intermittently, starting with first QItem. highlight Boolean Apply highlight to all QItems. This works only on desktop when user hovers QItems. link Boolean Apply highlight and a pointer cursor to all QItems. dense Boolean Make QItems dense. sparse Boolean Make QItems sparse. multiline Boolean Make QItems multiline. separator Boolean Make QItems have a separator between them. inset-separator Boolean Make QItems have an inset separator between them. dark Boolean When you component is rendered on a dark background no-border Boolean Remove the default border around QList. QListHeaderWithin QList, you can display a section header / title. Vue Property Type Description inset Boolean Place an inset separator. <q-list> <q-list-header>Folders</q-list-header> <!-- insert QItems... --> <q-list-header>Files</q-list-header> <!-- insert QItems... --></q-list> QItemSeparatorIf you want QItem external separators (there are internal ones too as you can see on QItem’s description later on this page), use the QItemSeparator component. It’s useful also to separate different sections of your QList, like for example, before a QListHeader. Vue Property Type Description inset Boolean Place an inset separator. <q-list> <q-list-header>Folders</q-list-header> <!-- insert QItems... --> <q-item-separator /> <q-list-header>Files</q-list-header> <!-- insert QItems... --></q-list><!-- and/or --><q-list> <q-item ...>...</q-item> <!-- Inset separator example --> <q-item-separator inset /> <q-item ...>...</q-item> <q-item-separator /> <q-item ...>...</q-item> <q-item-separator /> <q-list-header>Files</q-list-header> <q-item ...>...</q-item></q-list> QItem Vue Property Type Description dense Boolean Make QItem dense (narrow paddings). sparse Boolean Make QItem sparse (large paddings). separator Boolean Make QItem have a separator between it and previous QItem. inset-separator Boolean Make QItem have an inset separator between it and previous QItem. multiline Boolean Make QItem multiline. Vertically aligns QItem sides to top. Useful for more than 2-3 lines QItem content. highlight Boolean Apply highlight to QItem. Works only on desktop when user hovers it. link Boolean Apply highlight and a pointer cursor to QItem. tag String Default HTML tag used is ‘div’, but this can be any HTML tag if you need to. Read below for more information. dark Boolean When rendered on a dark background Also check the next section for more properties and to learn about how you can use your QItem as a Router Link. Using QItem as a Router LinkIf you want your QItem to act the same as Vue’s <router-link>, then you can use these additional properties (which work exactly the same as <router-link>): Property Type Description to String / Object Route to navigate to exact Boolean Match the exact route specified (and not also its children) when adding router-link-active CSS class. append Boolean Append route definition to current route when navigating. replace Boolean Replaces current route with the new one instead of adding it to the window history queue. For more details on these properties, please refer to the Vue Router documentation. Render with specific HTML tagPlease refer to the example on how to use the tag property shown below. In this example, we take advantage of the <label> tag that browsers automatically connect to checkboxes (QCheckbox, QToggle) or radio inputs (QRadio). When a <label> is clicked/tapped, then the wrapped checkboxes toggle their state (check / uncheck) and wrapped radios are being selected.<!-- We want a click/tap on the whole QItem to toggle the checkbox, so we use tag=\"label\" to make QItem render with <label> tag.--><q-item tag=\"label\"> <q-item-side> <q-checkbox v-model=\"checkboxModel\" /> </q-item-side> <q-item-main> <q-item-tile label>Notifications</q-item-tile> <q-item-tile sublabel>Notify me about updates to apps or games that I downloaded</q-item-tile> </q-item-main></q-item> QItemSide Vue Property Type Description color String Use a color from Quasar Color Palette. text-color String Override text color, one from Quasar Color Palette. inverted Boolean Invert colors. right Boolean Applies necessary design tweaks for right side of QItem. icon String Icon to use. Either use an icon, image, avatar or letter. image String URL to image to use (point to statics). Either use an icon, image, avatar or letter. avatar String URL to avatar to use (point to statics). Either use an icon, image, avatar or letter. letter String One character String to define a letter. Either use an icon, image, avatar or letter. stamp String For right side only. One character String to define a letter. Either use an icon, image, avatar or letter. tag String Default HTML tag that QItemTile gets rendered with is ‘div’, but this can be any HTML tag if you need to. Use the icon, image, avatar, letter or stamp properties or, for more control, insert QItemTiles instead. Use only one method or the other. QItemMain Vue Property Type Description label String Label to use as title. sublabel String Label to use as subtitle. label-lines String / Number Number of lines the label can span to. sublabel-lines String / Number Number of lines the sublabel can span to. inset Boolean Useful when QItem has no left side, but you want to align your content as if it had a left side. tag String Default HTML tag that QItemTile gets rendered with is ‘div’, but this can be any HTML tag if you need to. Use the label properties or, for more control, insert QItemTiles to define the label and sublabel. Use only one method or the other. QItemTileQItemTile can be used for more control over the content of the left, right side or main content of QItem. Vue Property Type Description color String Use a color from Quasar Color Palette. text-color String Override text color, one from Quasar Color Palette. inverted Boolean Invert colors. icon String Icon to use. Either use an icon, image, avatar or letter as props. image Boolean Encapsulates an image. Its content must be an <img> with src attribute pointing to statics. Either use an icon, image, avatar or letter as props. avatar Boolean Encapsulates an avatar image. Its content must be an <img> with src attribute pointing to statics. Either use an icon, image, avatar or letter as props. letter String One character String to define a letter. Either use an icon, image, avatar or letter as props. tag String Default HTML tag that QItemTile gets rendered with is ‘div’, but this can be any HTML tag if you need to. There are more props available for QItemTile, but only use the following when QItemTile is wrapped with QItemMain: Vue Property Type Description label Boolean Encapsulates the label / title of QItem. sublabel Boolean Encapsulates the sub-label / sub-title of QItem. lines String / Number Number of lines the label/sublabel can span to. Ellipsis are used when overflowing. Use only in conjunction with label and sublabel. Using QCollapsible with QItemsQCollapsible is a QItem wrapper, so you can use them as (and along) QItems within a QList. Here are two examples: <!-- Notice we use QCollapsibles and QItems as direct children of QList. We are basically building a menu.--><q-list separator> <!-- collapsible to hide sub-level menu entries --> <q-collapsible icon=\"inbox\" label=\"Inbox\" sublabel=\"Where your email is\"> <q-item link to=\"/inbox/1\"> <q-item-side icon=\"mail\" /> <q-item-main label=\"Email 1\" /> </q-item> <q-item link to=\"/inbox/2\"> <q-item-side icon=\"mail\" /> <q-item-main label=\"Email 2\" /> </q-item> <q-collapsible icon=\"favorite\" label=\"Favorites\"> <q-item link to=\"/inbox/favorites/1\"> <q-item-side icon=\"mail\" /> <q-item-main label=\"Favorite 1\" /> </q-item> <q-item to=\"/inbox/favorites/2\"> <q-item-side icon=\"mail\" /> <q-item-main label=\"Favorite 2\" /> </q-item> </q-collapsible> <q-item to=\"/inbox/3\"> <q-item-side icon=\"mail\" /> <q-item-main label=\"Email 3\" /> </q-item> </q-collapsible> <!-- menu link --> <q-item link to=\"/snoozed\"> <q-item-side icon=\"schedule\" /> <q-item-main> <q-item-tile label>Snoozed</q-item-tile> </q-item-main> </q-item> <!-- collapsible to hide sub-level menu entries --> <q-collapsible icon=\"send\" label=\"Sent\"> <q-item to=\"/sent/1\"> <q-item-side icon=\"mail\" /> <q-item-main label=\"Email 1\" /> </q-item> </q-collapsible> <!-- menu link --> <q-item link to=\"/trash\"> <q-item-side icon=\"delete\" /> <q-item-main> <q-item-tile label>Trash</q-item-tile> </q-item-main> </q-item></q-list> More ExamplesEmail list<q-list highlight inset-separator> <q-item> <q-item-side avatar=\"statics/boy-avatar.png\" /> <q-item-main label=\"Brunch this weekend? Brunch this weekend? Brunch this weekend?\" label-lines=\"1\" /> <q-item-side right stamp=\"1 min\" /> </q-item> <q-item multiline> <q-item-side avatar=\"statics/boy-avatar.png\" /> <q-item-main label=\"Brunch this weekend? Brunch this weekend? Brunch this weekend?\" label-lines=\"1\" sublabel=\"John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe\" sublabel-lines=\"2\" /> <q-item-side right> <q-item-tile stamp>1 week ago</q-item-tile> </q-item-side> </q-item> <q-item multiline> <q-item-side avatar=\"statics/boy-avatar.png\" /> <q-item-main label=\"Brunch this weekend? Brunch this weekend? Brunch this weekend?\" label-lines=\"2\" sublabel=\"John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe\" /> <q-item-side right stamp=\"10 min\" /> </q-item> <q-item multiline> <q-item-side> <q-item-tile avatar> <img src=\"statics/boy-avatar.png\"> </q-item-tile> </q-item-side> <q-item-main> <q-item-tile label>Brunch <span>5</span></q-item-tile> <q-item-tile sublabel lines=\"2\"> John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe John Doe </q-item-tile> </q-item-main> <q-item-side right> <q-item-tile stamp>10 min</q-item-tile> <q-item-tile icon=\"star\" color=\"yellow\" /> </q-item-side> </q-item> <q-item multiline> <q-item-side avatar=\"statics/boy-avatar.png\" /> <q-item-main> <q-item-tile label lines=\"1\">Brunch this weekend? Yeah, this weekend. Really. This one.</q-item-tile> <q-item-tile sublabel lines=\"2\"> <span>John Doe</span> -- I'll be in your neighborhood doing errands this weekend. Do you want to grab brunch? </q-item-tile> </q-item-main> <q-item-side right> <q-item-tile stamp>2 years</q-item-tile> <q-item-tile icon=\"mail\" color=\"primary\" /> </q-item-side> </q-item></q-list><q-list inset-separator class=\"q-mt-md\"> <q-item> <q-item-side avatar=\"statics/boy-avatar.png\" /> <q-item-main label=\"Brunch this weekend?\" /> <q-item-side right> <q-btn flat round dense icon=\"more_vert\"> <q-popover> <q-list link> <q-item v-close-overlay> <q-item-main label=\"Reply\" /> </q-item> <q-item v-close-overlay> <q-item-main label=\"Forward\" /> </q-item> <q-item v-close-overlay> <q-item-main label=\"Delete\" /> </q-item> </q-list> </q-popover> </q-btn> </q-item-side> </q-item> <q-item> <q-item-side avatar=\"statics/boy-avatar.png\" /> <q-item-main label=\"Brunch this weekend?\" /> <q-item-side right> <q-chip square color=\"primary\" class=\"shadow-2\">10k</q-chip> </q-item-side> </q-item> <q-item> <q-item-side avatar=\"statics/boy-avatar.png\" /> <q-item-main label=\"Brunch this weekend?\" /> <q-item-side right> <q-item-tile stamp>10 min ago</q-item-tile> <span class=\"text-amber\"> <q-item-tile icon=\"star\" v-for=\"n in 2\" :key=\"n\" /> </span> </q-item-side> </q-item></q-list> Chat List<q-list highlight> <q-list-header>Recent chats</q-list-header> <q-item> <q-item-side> <q-item-tile avatar> <img src=\"statics/boy-avatar.png\"> </q-item-tile> </q-item-side> <q-item-main label=\"John Doe\" /> <q-item-side right> <q-item-tile icon=\"chat_bubble\" color=\"green\" /> </q-item-side> </q-item> <q-item> <q-item-side avatar=\"statics/linux-avatar.png\" /> <q-item-main label=\"Jim Doe\" /> <q-item-side right icon=\"chat_bubble\" /> </q-item> <q-item-separator /> <q-list-header>Previous chats</q-list-header> <q-item> <q-item-side avatar=\"statics/guy-avatar.png\" /> <q-item-main label=\"Jack Doe\" /> </q-item></q-list> One more example:<q-list inset-separator> <q-item> <q-item-side icon=\"voice_chat\" color=\"secondary\" /> <q-item-main label=\"Voice Chat with Joe\" /> <q-item-side right icon=\"voice_chat\" color=\"secondary\" /> </q-item> <q-item> <q-item-side inverted icon=\"voice_chat\" color=\"secondary\" /> <q-item-main label=\"Voice Chat with Joe\" /> <q-item-side right inverted icon=\"voice_chat\" color=\"secondary\" /> </q-item> <q-item> <q-item-side inverted icon=\"voice_chat\" color=\"amber\" text-color=\"black\" /> <q-item-main label=\"Voice Chat with Joe\" /> <q-item-side right inverted icon=\"voice_chat\" color=\"amber\" text-color=\"black\" /> </q-item> <q-item> <q-item-side letter=\"J\" color=\"secondary\" /> <q-item-main label=\"John Doe\" /> <q-item-side right letter=\"J\" color=\"secondary\" /> </q-item> <q-item> <q-item-side inverted letter=\"J\" color=\"secondary\" /> <q-item-main label=\"John Doe\" /> <q-item-side right inverted letter=\"J\" color=\"secondary\" /> </q-item> <q-item> <q-item-side inverted letter=\"J\" color=\"amber\" text-color=\"black\" /> <q-item-main label=\"John Doe\" /> <q-item-side right inverted letter=\"J\" color=\"amber\" text-color=\"black\" /> </q-item></q-list> Folders and Files<q-list> <q-list-header inset>Folders</q-list-header> <q-item> <q-item-side icon=\"folder\" inverted color=\"primary\" /> <q-item-main> <q-item-tile label>Photos</q-item-tile> <q-item-tile sublabel>February 22, 2016</q-item-tile> </q-item-main> <q-item-side right icon=\"info\" color=\"green\" /> </q-item> <q-item-separator inset /> <q-list-header inset>Files</q-list-header> <q-item> <q-item-side icon=\"assignment\" inverted color=\"grey-6\" /> <q-item-main> <q-item-tile label>Expenses spreadsheet</q-item-tile> <q-item-tile sublabel>March 2nd, 2016</q-item-tile> </q-item-main> <q-item-side right icon=\"info\" /> </q-item></q-list> Settings (Embedding Form Components)<q-list link> <q-list-header>User controls</q-list-header> <q-item> <q-item-main> <q-item-tile label>Content filtering</q-item-tile> <q-item-tile sublabel>Set the content filtering level to restrict apps that can be downloaded</q-item-tile> </q-item-main> </q-item> <q-item> <q-item-main> <q-item-tile label>Password</q-item-tile> <q-item-tile sublabel>Require password for purchase or use password to restrict purchase</q-item-tile> </q-item-main> </q-item> <q-item-separator /> <q-list-header>General</q-list-header> <q-item tag=\"label\"> <q-item-side> <q-checkbox v-model=\"checked_one\" /> </q-item-side> <q-item-main> <q-item-tile label>Notifications</q-item-tile> <q-item-tile sublabel>Notify me about updates to apps or games that I downloaded</q-item-tile> </q-item-main> </q-item> <q-item tag=\"label\"> <q-item-side> <q-checkbox v-model=\"checked_two\" color=\"secondary\" /> </q-item-side> <q-item-main> <q-item-tile label>Sound</q-item-tile> <q-item-tile sublabel>Auto-update apps at anytime. Data charges may apply</q-item-tile> </q-item-main> </q-item> <q-item tag=\"label\"> <q-item-side> <q-checkbox v-model=\"checked_three\" color=\"red\" /> </q-item-side> <q-item-main> <q-item-tile label>Auto-add widgets</q-item-tile> <q-item-tile sublabel>Automatically add home screen widgets</q-item-tile> </q-item-main> </q-item></q-list><q-list class=\"q-mt-md\"> <q-list-header>Radios</q-list-header> <q-item link tag=\"label\"> <q-item-side> <q-radio v-model=\"option\" val=\"opt1\" /> </q-item-side> <q-item-main label=\"Option 1\" /> </q-item> <q-item link tag=\"label\"> <q-item-side> <q-radio color=\"secondary\" v-model=\"option\" val=\"opt2\" /> </q-item-side> <q-item-main> <q-item-tile label>Option 2</q-item-tile> <q-item-tile sublabel>Allows notifications</q-item-tile> </q-item-main> </q-item> <q-item link tag=\"label\"> <q-item-side> <q-radio color=\"amber\" v-model=\"option\" val=\"opt3\" /> </q-item-side> <q-item-main> <q-item-tile label>Option 3</q-item-tile> <q-item-tile sublabel lines=\"3\">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</q-item-tile> </q-item-main> </q-item> <q-item-separator /> <q-list-header>Toggles</q-list-header> <q-item link tag=\"label\"> <q-item-main label=\"Events and reminders\" /> <q-item-side right> <q-toggle v-model=\"checked_one\" /> </q-item-side> </q-item> <q-item link tag=\"label\" multiline> <q-item-main> <q-item-tile label>Events and reminders</q-item-tile> <q-item-tile sublabel>Lorem ipsum</q-item-tile> </q-item-main> <q-item-side right> <q-toggle v-model=\"checked_two\" color=\"secondary\" /> </q-item-side> </q-item> <q-item link tag=\"label\" multiline> <q-item-main> <q-item-tile label>Events and reminders</q-item-tile> <q-item-tile sublabel lines=\"3\"> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute </q-item-tile> </q-item-main> <q-item-side right> <q-toggle v-model=\"checked_three\" color=\"amber\" /> </q-item-side> </q-item> <q-item-separator /> <q-list-header>Selects</q-list-header> <q-item> <q-item-side icon=\"supervisor_account\" /> <q-item-main> <q-select hide-underline class=\"q-ma-none full-width\" v-model=\"select\" :options=\"selectOptions\" /> </q-item-main> </q-item> <q-item> <q-item-side icon=\"supervisor_account\" /> <q-item-main> <q-select hide-underline class=\"q-ma-none full-width\" multiple toggle v-model=\"multipleSelect\" :options=\"selectOptions\" /> </q-item-main> </q-item> <q-item-separator /> <q-list-header>Ranges</q-list-header> <q-item> <q-item-side icon=\"volume_down\" /> <q-item-main> <q-slider v-model=\"range\" :min=\"0\" :max=\"50\" label /> </q-item-main> <q-item-side right icon=\"volume_up\" /> </q-item> <q-item> <q-item-side icon=\"volume_down\" /> <q-item-main> <q-slider v-model=\"range\" :min=\"0\" :max=\"50\" label color=\"amber\" /> </q-item-main> <q-item-side right icon=\"volume_up\" /> </q-item> <q-item> <q-item-side icon=\"monetization_on\" /> <q-item-main> <q-range v-model=\"doubleRange\" :min=\"0\" :max=\"50\" label color=\"secondary\" /> </q-item-main> </q-item></q-list> Movies List<q-list> <q-list-header>Documentaries</q-list-header> <q-item> <q-item-side image=\"statics/mountains.jpg\" /> <q-item-main label=\"Mountains Documentary\" /> <q-item-side right icon=\"movie\" /> </q-item> <q-item> <q-item-side image=\"statics/quasar-logo.png\" /> <q-item-main> <q-item-tile label>Quasar</q-item-tile> <q-item-tile sublabel>Empower your development skills</q-item-tile> </q-item-main> <q-item-side right icon=\"movie\" /> </q-item> <q-item-separator /> <q-list-header>Movies</q-list-header> <q-item multiline> <q-item-side image=\"statics/parallax1.jpg\" /> <q-item-main> <q-item-tile label>Must-see places</q-item-tile> <q-item-tile sublabel lines=\"3\"> The world in which we live is full of wonderful places that most of us do not know they really exist. Here you can see some of those breathtaking places around the world. Enjoy! </q-item-tile> </q-item-main> <q-item-side right icon=\"movie\" /> </q-item> <q-item multiline> <q-item-side image=\"statics/parallax2.jpg\" /> <q-item-main> <q-item-tile label>Building a Bridge</q-item-tile> <q-item-tile sublabel lines=\"5\"> A bridge is one of those things that are often taken for granted until you don’t have one, especially if you live on a rural property and there’s a creek between your house and the county road. John Doe had plans to build a new bridge along with building a new house on his property, but plans for the bridge were made top priority when a wayward truck carried too much weight over the old bridge and it collapsed. </q-item-tile> </q-item-main> <q-item-side right icon=\"movie\" /> </q-item></q-list> Phonebook List<q-list> <q-item> <q-item-side icon=\"phone\" color=\"primary\" /> <q-item-main> <q-item-tile label>(650) 555 - 1234</q-item-tile> <q-item-tile sublabel>Mobile</q-item-tile> </q-item-main> <q-item-side right icon=\"chat_bubble\" color=\"green\" /> </q-item> <q-item> <q-item-main inset> <q-item-tile label>(650) 555 - 2345</q-item-tile> <q-item-tile sublabel>Office</q-item-tile> </q-item-main> <q-item-side right icon=\"chat_bubble\" /> </q-item> <q-item> <q-item-main inset> <q-item-tile label>(650) 555 - 3456</q-item-tile> <q-item-tile sublabel>Home</q-item-tile> </q-item-main> <q-item-side right icon=\"chat_bubble\" /> </q-item> <q-item-separator inset /> <q-item> <q-item-side icon=\"mail\" color=\"primary\" /> <q-item-main> <q-item-tile label>[email protected]</q-item-tile> <q-item-tile sublabel>Personal</q-item-tile> </q-item-main> </q-item> <q-item> <q-item-main inset> <q-item-tile label>[email protected]</q-item-tile> <q-item-tile sublabel>Office</q-item-tile> </q-item-main> </q-item></q-list>"},{"title":"Modal","updated":"2018-07-23T16:37:49.851Z","permalink":"https://v0-16.quasar-framework.org/components/modal.html","text":"The Quasar Modal component is a UI overlay, which offers extended screen space to allow the user to get more work done. Modals are used for such things as login or signup dialogs, for message composition windows or extended option selections, like offering a list of users to be friends with. InstallationEdit /quasar.conf.js:framework: { components: ['QModal'], // optional if you want to use // directive `v-close-overlay` directives: ['CloseOverlay']} Basic UsageBelow you’ll find the code to a very basic modal: <template> <q-modal v-model=\"opened\"> <h4>Basic Modal</h4> <q-btn color=\"primary\" @click=\"opened = false\" label=\"Close\" /> </q-modal></template><script>export default { data () { return { opened: false } }}</script> Modals are responsive to the width of the window (see demo on a desktop and resize browser window). Sometimes you need to always have a Modal maximized or minimized regardless of window width, so to do this, Quasar offers the minimized and maximized props: <q-modal maximized> ...</q-modal> Vue Properties Property Type Description minimized Boolean Always minimized regardless of screen width. maximized Boolean Always maximized regardless of screen width. no-route-dismiss Boolean By default, when route changes, the modal gets closed. This prop inhibits the behavior. no-esc-dismiss Boolean Disable Modal dismissal by hitting Escape key. no-backdrop-dismiss Boolean Disable Modal dismissal by clicking/tapping on backdrop. content-css Object/Array/String Applies CSS style to Modal container. Use Object or Array of Object when also specifying position prop. content-classes Object/Array/String Classes to apply to Modal inner content. position String Stick Modal to one of the screen edges (top, right, bottom, left). position-classes String Space delimited CSS classes that overwrite the default ‘items-center justify-center’ classes. Gets overridden by position if present. transition String Vue transition to use. Quasar comes with a q-modal transition out of the box. But you can write your own Vue transitions using CSS and use them. enter-class String enter transition class name leave-class String leave transition class name Vue Methods Method Description show Open Modal. Takes one optional Function parameter to trigger after Modal is opened. hide Close Modal. Takes one optional Function parameter to trigger after Modal is closed. toggle Toggle open/close Modal state. Takes one optional Function parameter to trigger after Modal is toggled. Vue Events Event Name Description @show Triggered right after Modal is opened. @hide Triggered right after Modal is closed. @escape-key Triggered if the Modal is dismissed with the Escape key on desktops. ExamplesStyling Modal<q-modal content-css=\"padding: 50px\"> ...</q-modal> Sticking Modal to an Edge<q-modal position=\"left\"> ...</q-modal> Modal with LayoutWhen making layout inside a modal, Quasar has a special component called QModalLayout (described in next section), which takes care of any needed structure. Do NOT use QLayout inside a QModal. Instead, use the simplified QModalLayout. <q-modal v-model=\"opened\" :content-css=\"{minWidth: '80vw', minHeight: '80vh'}\"> <q-modal-layout> <q-toolbar slot=\"header\"> <q-btn flat round dense v-close-overlay icon=\"keyboard_arrow_left\" /> <q-toolbar-title> Header </q-toolbar-title> </q-toolbar> <q-toolbar slot=\"header\"> <q-search inverted v-model=\"search\" color=\"none\" /> </q-toolbar> <q-toolbar slot=\"footer\"> <q-toolbar-title> Footer </q-toolbar-title> </q-toolbar> <div class=\"layout-padding\"> <h1>Modal</h1> <q-btn color=\"primary\" v-close-overlay label=\"Close\" /> <p>This is a Modal presenting a Layout.</p> </div> </q-modal-layout></q-modal> QModalLayoutQModalLayout has two slots (header and footer) and the following properties which can be either String, Object or Array: Property Type Description header-style String/Object/Array Style applied to header. header-class String/Object/Array CSS classes applied to header. content-style String/Object/Array Style applied to content (between header and footer). content-class String/Object/Array CSS classes applied to content (between header and footer). footer-style String/Object/Array Style applied to footer. footer-class String/Object/Array CSS classes applied to footer. Example: <q-modal .....> <q-modal-layout header-style=\"min-height: 100px\" content-class=\"{'bg-primary': isPrimary, 'some-class': someBoolean}\" footer-class=\"bg-primary some-class\" footer-style=\"{fontSize: '24px', fontWeight: 'bold'}\" > <!-- inject header and/or footer slots here examples: 1. <div slot=\"header\">...</div> 2. <q-toolbar slot=\"header\">...</q-toolbar> --> ... <!-- all other elements not using header or footer slot is considered content --> .... </q-modal-layout></q-modal>"},{"title":"Notify","updated":"2018-07-23T16:37:49.851Z","permalink":"https://v0-16.quasar-framework.org/components/notify.html","text":"Notify is a Quasar plugin that can display animated QAlerts (floating above everything in your pages) to users under the form of a notification. They are useful for alerting the user of an event and can even engage the user through actions. InstallationEdit /quasar.conf.js:framework: { plugins: ['Notify']} Basic Usage// outside of a Vue fileimport { Notify } from 'quasar'Notify.create('Warning, warning, Will Robinson!')// or with a config object:Notify.create({ message: 'Warning, warning, Will Robinson!'})// inside of a Vue filethis.$q.notify('Message')// or with a config object:this.$q.notify({...}) You can see this notification at the bottom of the demo page screen. Please notice the defaults: The notification is red. It has a timeout of 5000ms. It appears floating at the bottom of the screen. The animation is determined by the position of the notification on screen. Config ObjectLet’s go deeper and analyze the different optional properties available for a notification. this.$q.notify({ // only required parameter is the message: message: `A text with your alert's awesome message`, /* * All parameters below are optional: */ timeout: 3000, // in milliseconds; 0 means no timeout // \"type\" adds a color and icon, // so you don't need to specify them. // Available values: 'positive', 'negative', 'warning', 'info' type: 'positive', color: 'positive', textColor: 'black', // if default 'white' doesn't fits icon: 'wifi', // or avatar: 'statics/boy-avatar.png', detail: 'Optional detail message.', position: 'top-right', // 'top', 'left', 'bottom-left' etc actions: [ { label: 'Snooze', icon: 'timer', // optional noDismiss: true, // optional, v0.15.11+ handler: () => { console.log('acting') } }, { label: 'Dismiss', handler: () => { console.log('dismissed') } } ], onDismiss () { // v0.15.11+ //... }}) NoteIf you define any actions, the notification will automatically be dismissed when user picks it. Programmatically Closing AlertNotifications are meant to be dismissed only by the user, however for exceptional cases you can do it programmatically. Especially useful when you set indefinite timeout (0). const dismiss = this.$q.notify({...})...dismiss() Types of NotificationsQuasar offers the possibility to create out of the box notifications for different types of success or failure messages. The Notify types have specific icons and colors. The types of Notify we are talking about are: positive (for success), negative (for errors), warning and info. Here’s how to create them: this.$q.notify({ type: 'positive', ...})"},{"title":"Option Group","updated":"2018-07-23T16:37:49.853Z","permalink":"https://v0-16.quasar-framework.org/components/option-group.html","text":"The Quasar Option Group component is a helper component, which allows you to better control the grouping of binary (as in on or off, true or false, 1 or 0) form input components like checkboxes, radios or toggles. A good usage for this component is for offering the user a set of options or settings to turn on and off, and thus the name of the component. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QOptionGroup']} Basic UsageExample on a group of checkboxes: <template> <q-option-group color=\"secondary\" type=\"checkbox\" v-model=\"group\" :options=\"[ { label: 'Option 1', value: 'op1' }, { label: 'Option 2', value: 'op2' }, { label: 'Option 3', value: 'op3' } ]\" /></template><script>export default { data () { return { // `v-model` binded to `group`, // which must be an array for checkboxes and toggles group: ['opt1'] } }}</script> Example on a group of radios: <template> <q-option-group color=\"secondary\" type=\"radio\" v-model=\"group\" :options=\"[ { label: 'Option 1', value: 'op1' }, { label: 'Option 2', value: 'op2' }, { label: 'Option 3', value: 'op3' } ]\" /></template><script>export default { data () { return { // `v-model` binded to `group`, // which must be a String when using radios group: 'opt1' } }}</script> Vue PropertiesSupports v-model, which is required. For “radio” type it must be a String, otherwise (“checkbox” or “toggle” type) your scope variable binded to v-model must be an Array. Vue Property Type Description type String The type of input component to be used. The default is radio. The other choices are checkbox and toggle. options Array An array of objects with value and label properties. The binary components will be created according to this array. left-label Boolean When set to true, the labels will be put on the left side. inline Boolean Adjusts the display of the binary components fill out the row, instead of being stacked vertically. color String Color from Quasar Color Palette. keep-color Boolean Keep color when not selected/truthy too. readonly Boolean Set to true, to make the binary components read-only. disable Boolean When set to true, the binary components are not selectable thus cannot change your v-model. dark Boolean Set to true when background is dark. Vue Events Vue Event Description @input Triggered immediately when model changes. @change Fired when the component model changes. @focus Fired when the component gets focus. @blur Fired when the component loses focus. Lazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-option-group type=\"radio\" :value=\"model\" @change=\"val => { model = val }\" :options=\"[ { label: 'Option 1', value: 'op1' }, { label: 'Option 2', value: 'op2' }, { label: 'Option 3', value: 'op3' } ]\"/> Other ExamplesA group of radios with different colors.<q-option-group type=\"radio\" v-model=\"group\" :options=\"[ { label: 'Option 1', value: 'op1' }, { label: 'Option 2', value: 'op2', color: 'secondary' }, { label: 'Option 3', value: 'op3', color: 'amber' } ]\"/> And a group of toggles, but not stacked vertically when possible. We add inline Boolean property. <q-option-group inline type=\"toggle\" v-model=\"group\" :options=\"[ { label: 'Option 1', value: 'op1' }, { label: 'Option 2', value: 'op2' }, { label: 'Option 3', value: 'op3' } ]\"/> You would normally also add this component inside a QField component as shown below. <q-field icon=\"cloud\" helper=\"Choose your option\" label=\"Pick something\" :error=\"hasError\" error-label=\"Select at least one option\"> <q-option-group type=\"radio\" v-model=\"group\" :options=\"[ { label: 'Option 1', value: 'op1' }, { label: 'Option 2', value: 'op2' }, { label: 'Option 3', value: 'op3' } ]\" /></q-field>"},{"title":"Layout","updated":"2018-05-18T22:01:01.026Z","permalink":"https://v0-16.quasar-framework.org/components/layout.html","text":"Layouts are the elements that wrap page content, like a navigational bar or drawer. Multiple pages can share the same Layout, so the code is reusable, which is one of their key points. Quasar Layouts are NOT mandatory, but they do help you better structure your website/app. They have a number of features which offer you major benefits in simplifying your app’s layout design, right out of the box. InstallationEdit /quasar.conf.js to embed the components (only add what you need from below):framework: { components: [ 'QLayout', 'QPageContainer', 'QPage', 'QLayoutHeader', 'QLayoutFooter', 'QLayoutDrawer', 'QPageSticky' ]} Basic UsageBelow is a scaffolding of a Layout so you can understand the structure. We’ll discuss about properties later<!-- main wrapping component --><q-layout> <!-- optional --> <q-layout-header> <!-- content; any --> </q-layout-header> <!-- optional --> <q-layout-drawer side=\"left\"> <!-- content; any --> </q-layout-drawer> <!-- optional --> <q-layout-drawer side=\"right\"> <!-- content; any --> </q-layout-drawer> <!-- REQUIRED --> <q-page-container> <!-- Here it's where Vue Router injects children Page components. <router-view/> tag below can be replaced by an actual page content should you wish to do so. --> <router-view /> <!-- First child of QPageContainer must be a QPage, so make sure that your layout route children components encapsulate a QPage. --> </q-page-container> <!-- optional --> <q-layout-footer> <!-- content; any --> </q-layout-footer></q-layout> Below is another example of a Layout, which contains some useful elements: a QToolbar (used for both header and footer, you can specify as many as you want) a navigation with QTabs a left side drawer panel (which is shown alongside page content on wide screens) and a right side drawer panel <q-layout view=\"hHr LpR lFf\"> <!-- Header --> <q-layout-header> <!-- First row of header is a QToolbar --> <q-toolbar> <!-- showLeft is a model attached to left side drawer below --> <q-btn flat round dense @click=\"showLeft = !showLeft\" icon=\"menu\" /> <q-toolbar-title> Layout Header <span slot=\"subtitle\">Optional subtitle</span> </q-toolbar-title> <!-- showRight is a model attached to right side drawer below --> <q-btn flat round dense @click=\"showRight = !showRight\" icon=\"menu\" /> </q-toolbar> <!-- Second row of header is a QTabs --> <q-tabs> <q-route-tab slot=\"title\" icon=\"view_quilt\" to=\"/test-layout/about\" replace hide=\"icon\" label=\"About\" /> <q-route-tab slot=\"title\" icon=\"view_day\" to=\"/test-layout/toolbar\" replace hide=\"icon\" label=\"Toolbar\" /> <q-route-tab slot=\"title\" icon=\"view_day\" to=\"/test-layout/tabs\" replace label=\"Tabs\" /> <q-route-tab slot=\"title\" icon=\"input\" to=\"/test-layout/drawer\" replace label=\"Drawer\" /> </q-tabs> </q-layout-header> <!-- Left Side Drawer --> <q-layout-drawer side=\"left\" v-model=\"showLeft\"> <q-list no-border link inset-separator> <q-list-header>Essential Links</q-list-header> <q-item to=\"/docs\"> <q-item-side icon=\"school\" /> <q-item-main label=\"Docs\" sublabel=\"quasar-framework.org\" /> </q-item> <q-item to=\"/forum\"> <q-item-side icon=\"record_voice_over\" /> <q-item-main label=\"Forum\" sublabel=\"forum.quasar-framework.org\" /> </q-item> <q-item to=\"/chat\"> <q-item-side icon=\"chat\" /> <q-item-main label=\"Discord Chat Channel\" sublabel=\"https://discord.gg/5TDhbDg\" /> </q-item> <q-item to=\"/twitter\"> <q-item-side icon=\"rss feed\" /> <q-item-main label=\"Twitter\" sublabel=\"@quasarframework\" /> </q-item> </q-list> </q-layout-drawer> <!-- Right Side Panel --> <q-layout-drawer side=\"right\" v-model=\"showRight\"> Right Side of Layout </q-layout-drawer> <!-- sub-routes get injected here: --> <q-page-container> <router-view /> </q-page-container> <!-- Footer --> <q-layout-footer> <q-toolbar-title> Layout Footer </q-toolbar-title> </q-layout-footer></q-layout> You can also use QScrollArea for the left or right sides of the layout, if you want to control the scrollbar (but it’s not mandatory):<!-- notice style tag --><q-layout-drawer side=\"left\"> <q-scroll-area class=\"fit\"> <q-item to=\"/test-layout/toolbar\">Toolbar</q-item> <q-item to=\"/test-layout/tabs\">Tabs</q-item> <q-item to=\"/test-layout/drawer\">Drawer</q-item> </q-scroll-area></q-layout-drawer> Tips to Understanding QLayout Using margin CSS will break the layoutQLayout depends on taking up the whole screen and so QPageContainer, QLayoutHeader, QLayoutFooter and QLayoutDrawer positions are managed by it (through view prop). You cannot use CSS margins as a style neither on QLayout itself nor on any of the components mentioned above. However use can safely use CSS padding. RoutingIf your layout uses Vue Router sub-routes (recommended), then it makes sense to use Vue’s <router-view /> component, which is just a placeholder where sub-routes are injected. Toolbar PlacementA great place to use the Toolbars component is within the QLayoutHeader and QLayoutFooter. <q-layout-header> <q-toolbar color=\"green\"> ... toolbar content ... </q-toolbar></q-layout-header> Search exampleBelow is an example of placing a Search bar in the header:<q-layout> ... <!-- We place it on header --> <q-layout-header> <q-toolbar color=\"primary\"> <q-search inverted v-model=\"search\" color=\"none\" /> </q-toolbar> </q-layout-header> ...</q-layout> Fixed Positioning & FABsAlso, read about the smart Page Sticky which helps you fix position DOM elements or components on a Layout page and learn how you can use it to also place a Floating Action Button. QLayout Vue Properties Vue Property Type Description view String Configuration string which defines how different parts of the layout get displayed on screen. Configuring the “view” propQuasar introduces a unique and excellent layout concept, which allows you to easily structure layouts to work in certain ways, by simply changing a short string notation. To explain how this works, imagine your Layout is a 3x3 matrix of containers. The first row of containers would be the header and the last row would be the footer. The first column of containers would be the “left” and last column would be the “right”. The center of the matrix, below the header and above the footer, would be the page or main content container. Now think about this. This matrix of containers or “QLayout View” can be represented by a string. This string contains only 11 characters: 3 defining the header row then a space 3 defining the middle row a space then 3 defining the footer The picture below offers a visual representation of the QLayout View, to help you understand how to configure its 3x3 matrix. The letters shown above are also case sensitive. For example, using at least one “L” (uppercase character instead of lowercase) will make your layout left side (drawer) be in a fixed position. Same applies for “H” (header), “F” (footer) and finally “R” (right side / drawer). For example, if you want your layout’s right side / drawer to be placed on the right of the header, page and footer, you’d use hhr lpr ffr. If you’d like to also make it fixed, just transform one r character to uppercase, like this: hhR lpr ffr, or hhr lpR ffr or hhr lpr ffR. These settings are completely up to you to use as you’d like. You could even go wild with a setup like this: Lhh lpR ffr. Try it out! Make sure you also go to the desktop view, to see it work properly. NOTEIt is important that you specify all sections of a layout, even if you don’t use them. For example, even if you don’t use footer or right side drawer, specify them within your layout’s view prop. QLayout Vue Events Event Name Description @resize Event emitted on window resize. @scroll Event emitted on page scroll. @scrollHeight Event emitted on page scroll height change."},{"title":"Material Ripples","updated":"2018-05-18T22:01:01.028Z","permalink":"https://v0-16.quasar-framework.org/components/material-ripples.html","text":"Material Ripple effect can easily be added to any DOM element (or component) through the v-ripple Quasar directive. Following these steps: Make sure your DOM element or component has CSS position: relative or Quasar CSS helper class relative-position attached to it. Add v-ripple directive to it. The color of the ripples are determined by the text color (CSS ‘color’ prop) of the DOM element. InstallingEdit /quasar.conf.js:framework: { directives: ['Ripple']} Basic Usage<div class=\"relative-position\" v-ripple> ....</div> Trigger only for one Quasar themeFor this you need to specify mat or ios directive modifiers like this: <!-- Only for Quasar Material theme --><div v-ripple.mat class=\"relative-position\">...</div><!-- Only for Quasar iOS theme --><div v-ripple.ios class=\"relative-position\">...</div> Dynamic DisableIf for some reason you have a scenario where the ripples need to be disabled, then you can assign a Boolean as value for the directive. <template> <div v-ripple=\"rippleEnabled\" class=\"relative-position\" > <q-checkbox v-model=\"rippleEnabled\" label=\"Enable Ripples\" /> ..... </div></template><script>export default { data () { return { rippleEnabled: true } }}</script> When your Vue scope variable rippleEnabled becomes Boolean false then the ripple will be disabled.You can also combine this with the mat and ios modifiers."},{"title":"Other CSS Helper Classes","updated":"2018-05-18T22:01:01.030Z","permalink":"https://v0-16.quasar-framework.org/components/other-helper-classes.html","text":"There are a lot of CSS classes that you can use while writing your Vue templates. Very handy to ease the complexity of your VueModels and templates. The list below is not complete. Also check the other CSS documentation pages like Typography, Visibility, Shadows, Positioning. Mouse Related Class Name Description non-selectable User won’t be able to select DOM node along with its text scroll Applies CSS tweaks to make scroll work at its best on ALL platforms no-scroll Hides scrollbars on the DOM node no-pointer-events DOM element does not become a target of mouse events - clicks, hover and so on all-pointer-events The opposite of no-pointer-events cursor-pointer Change mouse pointer on DOM element to look as if on a clickable link Size Related Class Name Description fit Width and Height is set to 100% full-height Height is set to 100% full-width Width is set to 100% window-height Height is set to 100vh with top and bottom margins 0 window-width Width is set to 100vw with left and right margins 0 block Sets display property set to block Orientation Related Class Name Description rotate-45 Rotate by 45 degrees rotate-90 Rotate by 90 degrees rotate-135 Rotate by 135 degrees rotate-180 Rotate by 180 degrees rotate-205 Rotate by 205 degrees rotate-270 Rotate by 270 degrees rotate-315 Rotate by 315 degrees flip-horizontal Flip DOM element horizontally flip-vertical Flip DOM element vertically Border Related Class Name Description no-border Removes any border round-borders Applies a generic border radius based on theme GroupsThere are two special CSS class named group and generic-margin. group applies a small margin to all children DOM elements, while generic-margin applies same margin to the respective DOM element (this varies with each theme). The recommended way to go is by using CSS Flex Gutter though."},{"title":"Other Utils","updated":"2018-06-07T11:37:46.879Z","permalink":"https://v0-16.quasar-framework.org/components/other-utils.html","text":"Open External URLimport { openURL } from 'quasar'openURL('http://...') It will take care of the quirks involved when running under Cordova or on a browser, including notifying the user he/she has to acknowledge opening popups. Debounce FunctionIf your App uses JavaScript to accomplish taxing tasks, a debounce function is essential to ensuring a given task doesn’t fire so often that it bricks browser performance. Debouncing a function limits the rate at which the function can fire. Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in “execute this function only if 100 milliseconds have passed without it being called.” A quick example: you have a resize listener on the window which does some element dimension calculations and (possibly) repositions a few elements. That isn’t a heavy task in itself but being repeatedly fired after numerous resizes will really slow your App down. So why not limit the rate at which the function can fire? // Returns a function, that, as long as it continues to be invoked, will not// be triggered. The function will be called after it stops being called for// N milliseconds. If `immediate` is passed, trigger the function on the// leading edge, instead of the trailing.import { debounce } from 'quasar'(Debounced Function) debounce(Function fn, Number milliseconds_to_wait, Boolean immediate)// Example:window.addEventListener( 'resize', debounce(function() { .... things to do ... }, 300 /*ms to wait*/)) There’s also a frameDebounce available which delays calling your function until next browser frame is scheduled to run (read about requestAnimationFrame). import { frameDebounce } from 'quasar'(Debounced Function) frameDebounce(Function fn)// Example:window.addEventListener( 'resize', frameDebounce(function() { .... things to do ... })) Throttle FunctionThrottling enforces a maximum number of times a function can be called over time. As in “execute this function at most once every X milliseconds.” import { throttle } from 'quasar'(Throttled Function) throttle(Function fn, Number limit_in_milliseconds)// Example:window.addEventListener( 'resize', throttle(function() { .... things to do ... }, 300 /* execute at most once every 0.3s */)) (Deep) Copy ObjectsA basic respawn of jQuery.extend(). Takes same parameters:import { extend } from 'quasar'let newObject = extend([Boolean deepCopy], targetObj, obj, ...) Watch out for methods within objects. Generate UIDGenerate unique identifiers:import { uid } from 'quasar'let uid = uid()// Example: 501e7ae1-7e6f-b923-3e84-4e946bff31a8 Handling event on a DOM event handlerIt’s cross-browser. import { event } from 'quasar'node.addEventListener('click', evt => { // left clicked? (Boolean) event.leftClick(evt) // middle clicked? (Boolean) event.middleClick(evt) // right clicked? (Boolean) event.rightClick(evt) // key in number format (Number) event.getEventKey(evt) // Mouse wheel distance (in pixels) (Number) event.getMouseWheelDistance(evt) // position on viewport // works both for mouse and touch events! (Object {top, left}) event.position(evt) // get target DOM Element on which mouse or touch // event has fired upon (DOM Element) event.targetElement(evt) // call stopPropagation and preventDefault event.stopAndPrevent(evt)}) FilterFilter out an array of Objects based on a certain field: import { filter } from 'quasar'let data = [{fee: 5, desc: 'Bla bla'}, {fee: 10, desc: 'Bla bla'}, {fee: 1, desc: 'Bla bla'}]console.log(filter('5', {field: 'fee', list: data}))// [{fee: 5, desc: 'Bla bla'}]"},{"title":"Page Sticky","updated":"2018-05-18T22:01:01.031Z","permalink":"https://v0-16.quasar-framework.org/components/page-sticky.html","text":"The PageSticky component helps in placing DOM elements / components wrapped by it into a static position within the content area of your Layout, no matter where the user scrolls. A good example of this would be a “Back to top” button, which would first appear at the bottom of the screen, once the user scrolls down to a certain level on the screen. The great advantage of this is that the elements wrapped by this component will never overlap the layout header, footer or left/right sides, even if those are not configured to be fixed. In the latter case, the position will be offsetted so that the overlap won’t occur.Try it out with a non fixed footer for example. When user reaches bottom of screen and footer comes into view, the component will shift up so it won’t overlap with the footer. Important!In order for QPageSticky to work, it must be placed within a QLayout component NoteQPageSticky must be the last child element within it’s parent, so it can display on top of other content InstallationEdit /quasar.conf.js:framework: { components: ['QPageSticky']} Basic Usage<q-layout> ... <!-- Place QPageSticky as the last child element of your page. This is important for it to be displayed on top of the other page content. --> <q-page-sticky position=\"top-right\" :offset=\"[18, 18]\"> <q-btn round color=\"primary\" @click=\"alert\" icon=\"alarm\" /> </q-page-sticky></q-layout> The above would position a circular button at the top right corner of the content area of a layout. It would also pad the button with 18 pixels from the top and right edges of the layout. Expand mode Needs Quasar v0.15.4+Beware that you need to manually set the according padding to your QPage element so that your sticky elements won’t overlap page content. By default, QPageSticky shrinks to the size of its content. In case you want to place something like a QToolbar (works with any element/component) in a QPageSticky with position set to “top” (works for top/right/bottom/left), you can use the expand Boolean property: <!-- Example of a toolbar placed at top of the page --><q-page-sticky expand position=\"top\"> <q-toolbar> <q-btn flat round dense icon=\"menu\" /> <q-toolbar-title>Title</q-toolbar-title> </q-toolbar></q-page-sticky><!-- Example of placing something on the right side of the page --><q-page-sticky expand position=\"left\"> <div class=\"fit bg-tertiary\"> ....content... </div></q-page-sticky> Tip: For left/right positions you can use the Quasar Flex CSS classes to center content. Vue Properties Vue Property Type Description position String Check below for valid values. expand Boolean (v0.15.4+) Expand mode. Overrides default “shrinking” mode where Page Sticky shrinks to the size of content. offset Array (2 integers) Optional. The offset of the content, relative to the corner. First is offset on X axis, then on Y axis.Example: [0, 18] (offset 0 on X axis and 18px on Y axis). Valid values for “position” property: top-right, top-left, bottom-right, bottom-left, top, right, bottom, left."},{"title":"Popover","updated":"2018-07-23T16:37:49.855Z","permalink":"https://v0-16.quasar-framework.org/components/popover.html","text":"QPopover should be used when you want a menu (or any content) to be displayed on a popup as a result of user clicking/tapping on a DOM element / component. InstallationEdit /quasar.conf.js:framework: { components: ['QPopover'], // optional if you want to use // directive `v-close-overlay` directives: ['CloseOverlay']} Basic UsageIn the example below we use a Button (as a target) and when clicking/tapping on it Quasar will display a List. You can replace the QBtn and the List with any DOM elements or components you like. <!-- The target button (can be anything else) must be direct parent of QPopover on the DOM hierarchy.--><q-btn label=\"Email\"> <!-- Direct child of target --> <q-popover> <!-- The DOM element(s) that make up the popup, in this case a list: --> <q-list separator link> <!-- notice `v-close-overlay` which closes popover --> <q-item v-close-overlay @click.native=\"doSomething\"> ... </q-item> </q-list> </q-popover></q-btn> The idea is to place QPopover inside your DOM element / component that you want to be the trigger as direct child. Don’t worry about QPopover content inheriting CSS from the container as the QPopover will be injected as a direct child of <body>. IMPORTANTWhen on a browser, hitting the <ESCAPE> key also closes the QPopover. Toggle through v-model<template> <div> <q-btn color=\"primary\" @click=\"showing = true\" label=\"Show\" /> <q-btn color=\"primary\" @click=\"showing = false\" label=\"Hide\" /> <div> ... <q-popover v-model=\"showing\">...</q-popover> </div> </div></template><script>export default { data () { return { showing: false } }}</script> Vue Properties Vue Property Type Description anchor Object String of form bottom left (vertical horizontal) self Object String of form top left (vertical horizontal) max-height String Optional maximum height of Popover content. Example: 500px touch-position Boolean Open Popover from the position where user clicked/tapped on anchor. fit Boolean Popover has min-width set as same as the width of the container. disable Boolean When set to true, Popover won’t be triggered. offset Array of 2 Numbers Offset on horizontal and vertical (in pixels). Example: [18, 18]. disable Boolean Disable Popover Vue Methods Method Description show Open Popover. Takes one optional Function parameter to trigger after Popover is opened. hide Close Popover. Takes one optional Function parameter to trigger after Popover is closed. toggle Toggle open/close Popover state. Takes one optional Function parameter to trigger after Popover is toggled. Vue Events Vue Method Description @show Triggered after opening Popover. @hide Triggered after closing Popover. Handling Popover DismissalBy default, clicking/tapping outside the QPopover content will close it. But if you’d like elements from the QPopover content to close it, then use the v-close-overlay Quasar directive. Handling PositioningPosition of the QPopover can be customized. It keeps account of the anchor and self optional Vue properties. See demo and play with them. The final position of the QPopover popup is calculated so that it will be displayed on the available screen real estate, switching to right-side and/or top-side when necessary. If you would like the QPopover to appear from the touch/click point triggering the QPopover open, then use the Boolean touch-position Vue property:<q-popover touch-position> ...</q-popover> The demo has touch-position specified for the big image on the center of the page."},{"title":"Platform Detection","updated":"2018-05-18T22:01:01.032Z","permalink":"https://v0-16.quasar-framework.org/components/platform-detection.html","text":"Helpers are built-in to detect the Platform (and its capabilities) in which the code is running: // For usage inside a Vue component JS:this.$q.platform.is.mobile// or usage inside a Vue component template:$q.platform.is.cordova// Only for usage outside a Vue component you need to import it:import { Platform } from 'quasar' Property Type Meaning Platform.is.mobile boolean Is the code running on a mobile device? Platform.is.cordova boolean Is the code running within Cordova? Platform.is.electron boolean Is the code running within Electron? Platform.is.desktop boolean Is the code running on a desktop browser? Platform.is.chromeExt boolean Is the code running is a Chrome extension environment? Platform.has.touch boolean Is the code running on a touch capable screen? Platform.within.iframe boolean Is the App running within an IFRAME? NOTERunning on mobile means you can have this code running on a mobile device (phone or tablet) but with a browser, not within a Cordova wrapper. Other Platform.is specific properties:android, blackberry, cros, ios, ipad, iphone, ipod, kindle, linux, mac, playbook, silk, chrome, opera, safari, win (Windows), winphone (Windows Phone) and more… Example when running Chrome on a Linux desktop machine:// Describing Platform.is{ chrome: true, desktop: true, linux: true, name: \"chrome\", platform: \"linux\", version: \"47.0.2526.80\", versionNumber: 47, webkit: true} UsageLet’s say we want to render different components or DOM elements, based on the platform that the code is running under. We want to show something on desktop and something else on mobile. We would proceed like this: <div v-if=\"$q.platform.is.desktop\"> I'm only rendered on desktop!</div><div v-if=\"$q.platform.is.mobile\"> I'm only rendered on mobile!</div><div v-if=\"$q.platform.is.electron\"> I'm only rendered on Electron!</div> NOTEBased on your needs, you might want to also check Design Helpers > Visibility page to see how you can achieve the same effect using CSS alone. This latter method will render your DOM elements or components regardless of platform though, so choose wisely on how you want to handle the performance of your app."},{"title":"Parallax","updated":"2018-05-18T22:01:01.032Z","permalink":"https://v0-16.quasar-framework.org/components/parallax.html","text":"Parallax scrolling is a technique in computer graphics and web design, where background images move by the camera slower than foreground images, creating an illusion of depth in a 2D scene and adding to the immersion. Quasar provides an out of the box Vue Component you can use. It takes care of a lot of quirks, including image size which can actually be smaller than the window width/height. InstallationEdit /quasar.conf.js:framework: { components: ['QParallax']} Basic Usage<q-parallax src=\"assets/mountains.jpg\"> <!-- Dom elements to display while loading image --> <div slot=\"loading\">Loading...</div> <!-- The rest of Dom elements get displayed on top of the Parallax image after it's loaded --> <h1>Parallax</h1></q-parallax> While the underlying image is being loaded you can display a specific message through <div slot="loading">...</div>. After image has loaded, you can also display some content on top of the Parallax image (in the example above an <h1> tag). Vue Properties Param Attributes Type Description src String Source for the image. height Number Height of Parallax in pixels. Default value is 500. speed Number Float between 0 and 1. Example:<!-- VueModel contains data property \"imageURL\" --><q-parallax :src=\"imageURL\" :height=\"300\"> <div slot=\"loading\">Loading...</div> <h1>Parallax</h1></q-parallax>"},{"title":"CSS Positioning Classes","updated":"2018-05-18T22:01:01.033Z","permalink":"https://v0-16.quasar-framework.org/components/positioning.html","text":"There are CSS classes supplied by Quasar to help you position a DOM element easily: Class Name Description fullscreen Fix position covering all window real-estate fixed Set position to fixed without specifying top, left, right or bottom properties fixed-center Set position to fixed but in the middle of window. absolute Set position to absolute without specifying top, left, right or bottom properties absolute-center Set position to absolute but in the middle of the container (container needs relative position). fixed-top, absolute-top Fixed or absolute position to top of screen fixed-right, absolute-right Fixed or absolute position to the right edge of screen fixed-bottom, absolute-bottom Fixed or absolute position to bottom of screen fixed-left, absolute-left Fixed or absolute position to the left edge of screen fixed-top-left, absolute-top-left Fixed or absolute position to top left of screen fixed-top-right, absolute-top-right Fixed or absolute position to top right of screen fixed-bottom-left, absolute-bottom-left Fixed or absolute position to bottom left of screen fixed-bottom-right, absolute-bottom-right Fixed or absolute position to bottom right of screen relative-position Set position to relative Alignment Class Name Description float-left Float to the left float-right Float to the right on-left Sets a small margin to the right; commonly used for icon elements with other siblings on-right Sets a small margin to the left; commonly used for icon elements with other siblings Vertical alignment: Class Name Description vertical-top Set CSS vertical alignment to top vertical-middle Set CSS vertical alignment to middle vertical-bottom Set CSS vertical alignment to bottom"},{"title":"Pull Down to Refresh","updated":"2018-07-23T16:37:49.856Z","permalink":"https://v0-16.quasar-framework.org/components/pull-to-refresh.html","text":"When you want to allow the user to refresh the content or add newest content. InstallationEdit /quasar.conf.js:framework: { components: ['QPullToRefresh']} Basic UsageUse QPullToRefresh component as direct child of your page component, to encapsulate all its content. Refer to the source on the demo for a more detailed example. <q-pull-to-refresh :handler=\"refresher\"> <!-- Content, whatever you like --> <p v-for=\"item in items\"> Lorem ipsum dolor sit amet... </p></q-pull-to-refresh> IMPORTANTDo not wrap <q-pull-to-refresh> by a <div class="layout-padding">. If you must, place that <div> as direct child of <q-pull-to-refresh>. Vue Properties Vue Property Type Default Value Description handler Function Required Method from VM to be called to load more content distance Number 35 Minimum threshold distance in pixels to determine if releasing will determine a refresh pull-message String ‘Pull down to refresh’ Message to display before hitting the threshold above release-message String ‘Release to refresh’ Message to display after hitting the threshold above and before releasing refresh-message String ‘Refreshing…’ Message to display when refreshing content refresh-icon String ‘refresh’ Icon to display when refreshing the content, besides the text above inline Boolean false If the component is not direct child of QPage, set this to “true”. disable Boolean false When set to true it disables its functionality. If no value is provided (empty attribute), then it’s considered as set to true. Vue Methods Vue Method Description @trigger Triggers a refresh, calling your handler. HandlerThe handler Function (specified as DOM element property) takes one parameter:{ methods: { refresher (done) { // done - Function to call when you made all necessary updates. // DO NOT forget to call it otherwise the refresh message // will continue to be displayed // make some Ajax call then call done() } }}"},{"title":"Pagination","updated":"2018-07-19T13:04:56.787Z","permalink":"https://v0-16.quasar-framework.org/components/pagination.html","text":"The Quasar Pagination component is available for whenever a pagination system is required. It offers the user a simple UI to help you in moving between pages/items. There are two modes in which QPagination operates: with buttons only or with an inputbox. The latter mode allows the user to go to a specific page by clicking/tapping on the inputbox, typing the page number then hitting Enter key and if the new page number is within valid limits, the model will be changed accordingly. InstallationEdit /quasar.conf.js:framework: { components: ['QPagination']} Basic Usage<q-pagination v-model=\"page\" :max=\"17\" /> Vue PropertiesSupports v-model. Vue Property Type Description min Number Number of the first page; Default: 1 max Number (Required) Number of last page color String One from Quasar Color Palette text-color String Text color of current selection button, one from Quasar Color Palette size String Button size (check “size” prop from Buttons) input Boolean Use inputbox mode instead of buttons boundary-links Boolean Show boundary button links boundary-numbers Boolean Show boundary number buttons direction-links Boolean Show direction buttons ellipses Boolean Show ellipses when pages available > “max-pages” prop. max-pages Number Maximum number of page links to display at a time. disable Boolean If no value is provided (empty attribute), then it’s considered as set to true. If you’d like to set the minimum starting page or the max number of pages, you can do so, as in the example below. <template> <q-pagination v-model=\"page\" :min=\"minPages\" :max=\"maxPages\" /></template><script>export default { data () { return { page: 4, minPages: 4, maxPages: 27 } }}</script> This will cause the pagination to initially render to page 4 and not allow the user to go below page 4. Vue Events Vue Event Description @input(newVal) Triggered immediately on model value change. @change(newVal) Triggered on lazy model value change. ExamplesWith buttons<q-pagination v-model=\"page\" :min=\"1\" :max=\"6\"/> With inputbox<q-pagination input v-model=\"page\" :min=\"1\" :max=\"6\"/> With maximum number of links & custom color<q-pagination v-model=\"page2\" color=\"secondary\" :min=\"1\" :max=\"15\" :max-pages=\"6\"/> With no ellipses<q-pagination v-model=\"page2\" color=\"amber\" text-color=\"black\" :min=\"1\" :max=\"15\" :max-pages=\"6\" :ellipses=\"false\"/> With boundary links<q-pagination v-model=\"page2\" color=\"purple\" :min=\"1\" :max=\"15\" :max-pages=\"6\" boundary-links/> With direction links<q-pagination v-model=\"page2\" color=\"teal\" :min=\"1\" :max=\"15\" :max-pages=\"6\" direction-links/> With custom interval<q-pagination v-model=\"page3\" :min=\"5\" :max=\"10\"/> Mix and match<q-pagination v-model=\"page4\" color=\"tertiary\" :min=\"7\" :max=\"18\" :max-pages=\"8\" boundary-links direction-links/>"},{"title":"Radio","updated":"2018-07-23T16:37:49.858Z","permalink":"https://v0-16.quasar-framework.org/components/radio.html","text":"The Quasar Radio component is another basic element for user input. You can use this to supply a way for the user to pick an option from multiple choices. Please also refer to the Option Group documentation on other possibilities for creating groups of Toggles. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QRadio']} Basic Usage<!-- Three choices for the user --><q-radio v-model=\"option\" val=\"opt1\" label=\"Option 1\" /><q-radio v-model=\"option\" val=\"opt2\" label=\"Option 2\" /><q-radio v-model=\"option\" val=\"opt3\" label=\"Option 3\" /> Vue PropertiesSupports v-model which should be binded to a String in your scope. Choosing one option (clicking/tapping on a radio) makes your v-model change to Radio’s val. Vue Property Type Description val Object Used to modify the v-model of the Radio with. label String The text label for the Radio. left-label Boolean Set to true, if the label should be placed to the left of the radio. checked-icon String The icon to use, when the radio is checked. Default is a simple radio icon. uncheck-icon String The icon to use, when the radio is not checked. Default is simple unchecked radio icon. color String Color from Quasar Color Palette of the Radio. keep-color Boolean Keep color when not selected too. readonly Boolean Set to true, to make the radio read-only. disable Boolean Set to true, to disable the radio. dark Boolean Set to true when background is dark. Vue Events Vue Event Description @input Triggered when it gets selected. @blur Triggered, when Radio loses focus. @focus Triggered, when Radio gains focus. More ExamplesThere are a number of props, which are available to help quickly format a Radio. An interesting feature of Radio is the ripple effect that user gets when clicking/tapping on it to change its state. Specific State IconsInstead of the default radio icon, you can also use the checked-icon and unchecked-icon props to display a different icon. <q-radio v-model=\"option\" val=\"opt1\" unchecked-icon=\"visibility_off\" checked-icon=\"visibility\" label=\"Show only Area 1\"/><q-radio v-model=\"option\" val=\"opt2\" unchecked-icon=\"visibility_off\" checked-icon=\"visibility\" label=\"Show only Area 2\"/><q-radio v-model=\"option\" val=\"opt3\" unchecked-icon=\"visibility_off\" checked-icon=\"visibility\" label=\"Show only Area 3\"/> ColoringUse the color prop to control the Radio color. <!-- Default color, which is \"primary\" --><q-radio v-model=\"option\" val=\"opt2\" /><!-- Teal --><q-radio v-model=\"option\" val=\"opt3\" color=\"teal\" /><!-- Orange-7 --><q-radio v-model=\"option\" val=\"opt4\" color=\"orange-7\" /> Label PositionUse the left-label prop, to move the label to the left of the radio. <q-radio v-model=\"option\" val=\"opt2\" left-label label=\"Option 2\"/> Usage Inside of a List<q-list link> <!-- Rendering a <label> tag (notice tag=\"label\") so the whole QItem will respond to clicks to change Toggle state. --> <q-item tag=\"label\"> <q-item-side> <q-radio v-model=\"option\" val=\"opt1\" /> </q-item-side> <q-item-main> <q-item-tile label>Option 1</q-item-tile> </q-item-main> </q-item> <q-item tag=\"label\"> <q-item-side> <q-radio v-model=\"option\" val=\"opt2\" /> </q-item-side> <q-item-main> <q-item-tile label>Option 2</q-item-tile> <q-item-tile sublabel>Allows notifications</q-item-tile> </q-item-main> </q-item> <q-item tag=\"label\"> <q-item-side> <q-radio v-model=\"option\" val=\"opt3\" /> </q-item-side> <q-item-main> <q-item-tile label>Option 3</q-item-tile> <q-item-tile sublabel> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </q-item-tile> </q-item-main> </q-item></q-list>"},{"title":"Progress Bar (QProgress)","updated":"2018-05-18T22:01:01.034Z","permalink":"https://v0-16.quasar-framework.org/components/progress-bar.html","text":"A Progress bar is used to show a process is being worked on, so the user isn’t staring at a static page, even though the system is working in the background. It is a good visual indicator (i.e. good UX) for the user, when waiting for longer term operations to be accomplished. InstallationEdit /quasar.conf.js:framework: { components: ['QProgress']} Basic usage<q-progress :percentage=\"progressModel\" /><!-- with buffering; 4px height looks best --><q-progress :percentage=\"progressBuffer\" :buffer=\"buffer\" style=\"height: 4px\"/> Vue Properties Property Type Description percentage Number Progress (in percentage). buffer Number Buffer (in percentage). color String The Quasar CSS color value the bar should be. stripe Boolen If set to true, the progress bar will be striped. animate Boolean If set to true, the progress bar will be animated. indeterminate Boolean If set to true, the state is indeterminate, meaning it is unknown when the progress will stop. height String CSS unit for height of QProgress. Percentage and buffer, being percentage values, must be between 0 and 100, and percentage + buffer must be lower or equal to 100. If percentage is outside this interval the component will parse it and make it be within the interval. For color, use one from the Quasar Color Palette. Examples:<q-progress :percentage=\"progress\" color=\"teal-4\" /><q-progress :percentage=\"progress\" color=\"positive\" /><q-progress :percentage=\"progress\" color=\"info\" /><q-progress :percentage=\"progress\" color=\"warning\" /> For stripes, just add the stripe prop. Examples:<q-progress :percentage=\"progress\" color=\"positive\" stripe /><q-progress :percentage=\"progress\" color=\"info\" stripe /><q-progress :percentage=\"progress\" color=\"warning\" stripe /> For buffering, use the buffer prop. <q-progress :percentage=\"progress\" color=\"positive\" stripe :buffer=\"buffer\" /><q-progress :percentage=\"progress\" color=\"info\" stripe :buffer=\"buffer\" /><q-progress :percentage=\"progress\" color=\"warning\" stripe :buffer=\"buffer\" /> If you cannot calculate the progress in percent, use the indeterminate prop. <q-progress indeterminate /><q-progress indeterminate color=\"positive\" /><q-progress indeterminate color=\"warning\" /><q-progress indeterminate color=\"negative\" /> If you’d like to set a specific height of the progress bar, add inline styling to the component:<q-progress :percentage=\"progress\" stripe animate height=\"45px\"/>"},{"title":"Rating","updated":"2018-05-18T22:01:01.036Z","permalink":"https://v0-16.quasar-framework.org/components/rating.html","text":"Quasar Rating is a Component which allows users to rate items, usually known as “Star Rating”. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QRating']} Basic Usage<q-rating v-model=\"ratingModel\" :max=\"3\" /><!-- Disabled State --><q-rating disable v-model=\"ratingModel\" :max=\"3\"/> Vue PropertiesSupports v-model which should be binded to a Number in your scope. Vue Property Type Description max Number Number of icons to display. icon String Icon to use as grade. Default value: grade. color String One of Quasar Color Palette. size String CSS size String. Examples: ‘12px’, ‘2rem’. readonly Boolean Display as readonly. disable Boolean When set to true user can not change model value and Rating is faded. Vue Methods Vue Method Description set(value) Parses and sets that value. Vue Events Vue Event Description @input(newVal) Triggered on model value change. @change(newVal) Triggered on model value change. ColoringUse one of the Quasar colors from the Color Palette, like primary, secondary, orange-7, teal-2 as CSS class: <q-rating class=\"orange\" v-model=\"ratingModel\" :max=\"5\"/>"},{"title":"Range","updated":"2018-05-18T22:01:01.036Z","permalink":"https://v0-16.quasar-framework.org/components/range.html","text":"The Quasar Range component is a great way to offer the user the selection of a sub-range of values between a minimum and maximum value, with optional steps to select those values. An example use case for the Range component would be to offer a price range selection. Also check out its “sibling”, the Slider component.Remember you can use QRange wrapped by a QField too. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QRange']} Basic UsageNotice we are using an object for the selection, which holds values for both the lower value of the selected range - rangeValues.min and the higher value - rangeValues.max. <template> <q-range v-model=\"rangeValues\" :min=\"0\" :max=\"10\" :step=\"1\" /></template><script>export default { data () { return { // our model here rangeValues: { min: 2, max: 4 } } }}</script> Example with step, label and snap:<q-range v-model=\"rangeValues\" :min=\"0\" :max=\"10\" :step=\"2\" label snap/> Vue PropertiesSupports v-model which should be binded to an Object in your scope with “min” and “max” properties. Vue Property Type Description min Number (Required) Minimum value for beginning of interval. max Number (Required) Maximum value for end of interval. label Boolean Popup a label when user clicks/taps on the Range. label-always Boolean Always display the label. left-label-value String Override default left label value. right-label-value String Override default right label value. left-label-color String Color from Quasar Palette for left label background. right-label-color String Color from Quasar Palette for right label background. fill-handle-always Boolean Fill handle even if at minimum value. step Number Specify step amount between valid values. decimals Number Specify maximum number of decimals. snap Boolean Range handler will snap on values, rather than walking freely; good to use along step; also displays step markers on the Range. markers Boolean Display markers on background, one for each possible value for the model. square Boolean When true. the slider buttons are square instead of round. color String One of Quasar Color Palette. error Boolean If set to true, the range is turned red. warning Boolean If set to true, the slider is turned yellowish. readonly Boolean If set to true, the user cannot change model value. disable Boolean If set to true, the user cannot change model value. drag-range Boolean User can also drag the range (while maintaining interval in this case). drag-only-range Boolean When true, the user can only drag a predetermined range. Range limit values cannot be changed independently. IMPORTANTMake sure you choose the min, max and step values correctly. step must be a divisor of max - min, of v-model.min and of v-model.max, otherwise the component won’t work right. This is because all valid steps must be able to hold an equal position within the min-max values. ColoringUse one of the Quasar colors from the Color Palette, like primary, secondary, orange-9, teal-4 within the color prop: <q-range color=\"teal\" v-model=\"rangeValues\" :min=\"0\" :max=\"50\" label/> Lazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-range :value=\"model\" @change=\"val => { model = val }\" :min=\"0\" :max=\"20\"/> Draging the RangeUse the drag-range or drag-only-range props, to allow the user to move the selected range or only a predetermined range as a whole. <q-range drag-range v-model=\"rangeValues\" :min=\"0\" :max=\"100\" label /><q-range drag-only-range v-model=\"rangeValues\" :min=\"0\" :max=\"100\" label /> Adding MarkersUse the markers prop, to show the steps available for the range selection.<q-range markers v-model=\"rangeValues\" :min=\"-6\" :max=\"10\" :step=\"2\" label snap /> Overriding LabelsIn the example below we add a “px” suffix to labels.<q-range v-model=\"model\" :min=\"-20\" :max=\"20\" :left-label-value=\"`${model.min}px`\" :right-label-value=\"`${model.max}px`\"/> Vue Events Vue Event Description @input(newVal) Triggered immediately on model value change. @change(newVal) Triggered on lazy model value change. Usage Inside of a List<q-list> <q-item> <q-item-side icon=\"local_atm\" /> <q-item-main> <q-range v-model=\"standalone\" :min=\"0\" :max=\"50\" label /> </q-item-main> </q-item> <q-item> <q-item-side icon=\"euro symbol\" /> <q-item-main> <q-range v-model=\"standalone\" :min=\"0\" :max=\"50\" label /> </q-item-main> </q-item></q-list>"},{"title":"RTL Support","updated":"2018-05-18T22:01:01.037Z","permalink":"https://v0-16.quasar-framework.org/components/rtl-support.html","text":"RTL is referring to “right to left” UI for languages that need it. You need Quasar v0.15.5+. Enabling RTL supportTo enable it, you need to edit /quasar.conf.js:build: { rtl: true} How it worksRTL is tightly coupled to Quasar I18n. When Quasar is set to use an RTL language (language pack has “rtl” prop set to “true”) and RTL support is enabled (check step above for quasar.conf.js), then the UI will dynamically transform Quasar & your website/app code for RTL. Let’s discuss about each of these two requirements: Quasar needs to be set to use an RTL languageSee Internationalization on how you can set a language. You can set a language as default or dynamically set one. RTL support needs to be enabledYou need to set “rtl” to “true” under quasar.conf.js > “build”. What this does is it compiles CSS for both your website/app code and for Quasar components and add corresponding RTL CSS rules automatically. Your CSS bundle will slightly increase in size due to the addition of these CSS rules. Things to keep in mind Both RTL and non-RTL Quasar language packs will work together and dynamically switch to/from RTL. So only choosing an RTL Quasar language pack will trigger the RTL UI for you. You don’t need separate builds of your app (one for non-RTL and one for RTL-only). The RTL is dynamical. You can dynamically detect if you are on RTL mode by taking a look at Boolean this.$q.i18n.rtl. More info on Vue Prototype Injections. You need to be careful when writing your own CSS. Like mentioned above, Quasar will automatically add RTL rules based on your CSS code. So writing: .my-class { margin-left: 10px; right: 5px;} …will add this rule for RTL: [dir=rtl] .my-class { margin-right: 10px; left: 5px;} Any CSS rule that refers to “left” or “right” is automatically triggering an equivalent RTL CSS rule to be added. Marking CSS rules as exceptionsIf you need an exception so your CSS code will not add a corresponding RTL rule, then add this comment:.my-class { margin-left: 10px /* rtl:ignore */;} Now both RTL and non-RTL UI mode will have margin-left prop. Sometimes you’ll need to make exceptions for whole DOM elements / components. In this case, add dir="ltr" or dir="rtl" HTML attribute to the outermost DOM element / component template: <div dir=\"ltr\"> <!-- this DIV and all its content will use RTL mode regardless of Quasar language pack RTL settings --></div> Or, if you need your RTL UI to use left-to-right (ltr) mode for a DOM element / component:<div dir=\"ltr\"> <!-- this DIV and all its content will use non-RTL mode regardless of Quasar language pack RTL settings --></div> Handling Quasar UMDTo enable RTL UIs in UMD you need to include the RTL equivalent CSS tag for your Quasar version and also pack in a Quasar RTL language pack (like Hebrew or Farsi). Example: <html> <head> ... <link href=\"https://cdn.jsdelivr.net/npm/quasar-framework@latest/dist/umd/quasar.mat.rtl.min.css\" rel=\"stylesheet\" type=\"text/css\"> </head> <body> ... <!-- we also need an RTL Quasar language pack; let's take Hebrew as example; include this after Quasar JS tag --> <script src=\"https://cdn.jsdelivr.net/npm/quasar-framework@latest/dist/umd/i18n.he.umd.min.js\"></script> <script> Quasar.i18n.set(Quasar.i18n.he) </script> </body></html> Check what tags you need to include in your HTML files by generating a sample with $ vue init quasarframework/quasar-starter-kit-umd <folder> and answering with “Yes” to the RTL question and specifying an RTL language for Quasar I18n.Also notice the <html dir="rtl"> tag at the beginning of the generated html file – you’ll need that too. CaveatQuasar CLI automatically adds equivalent RTL CSS rules for your website/app code, but this is not the case for UMD where Quasar CLI is not being used. You’ll have to manage writing the RTL equivalent of your website/app CSS code by yourself. It’s only Quasar components that will have this handled automatically."},{"title":"Screen Plugin","updated":"2018-05-20T16:04:39.318Z","permalink":"https://v0-16.quasar-framework.org/components/screen-plugin.html","text":"The Quasar Screen plugin allows you to have a dynamic and responsive UI when dealing with your Javascript code. When possible, it is recommended to use the responsive CSS classes instead, for performance reasons. Installation// quasar.conf.jsframework: { plugins: ['Screen']} Basic UsageNotice $q.screen below. This is just a simple usage example. <q-list :dense=\"$q.screen.lt.md\" :sparse=\"$q.screen.gt.lg\"> <q-item> <q-item-main label=\"John Doe\" /> </q-item> <q-item> <q-item-main label=\"Jim Doe\" /> </q-item></q-list> // script part of a Vue componentexport default { computed: { buttonColor () { return this.$q.screen.lt.md ? 'primary' : 'secondary' } }} We can also use Screen plugin outside of a Vue component:import { Screen } from 'quasar'// Screen.gt.md// Screen.md ConfigurationThere are a few methods that can be used to tweak how Screen plugin works: Method Description Example setSizes(Object) Change window breakpoints; does NOT also changes CSS breakpoints. setSizes({ lg: 1024, xl: 2000 }) setDebounce(Number) Change the default 100ms debounce to some other value. setDebounce(500) // 500ms Examples:// inside a Vue component:this.$q.screen.setSizes({ sm: 300, md: 500, lg: 1000, xl: 2000 })// outside of a Vue component:import { Screen } from 'quasar'Screen.setSizes({ sm: 300, md: 500, lg: 1000, xl: 2000 })"},{"title":"Scroll Area","updated":"2018-05-18T22:01:01.038Z","permalink":"https://v0-16.quasar-framework.org/components/scroll-area.html","text":"Quasar offers a neat way of customizing the scrollbars with the help of QScrollArea component which can encapsulate your content. Think of it as a DOM element which has overflow: auto, but with your own custom styled scrollbar instead of browser’s default one and a few nice features on top. This is especially useful for desktop as scrollbars are hidden on a mobile device. When on a mobile device, QScrollArea simply wraps the content in a <div> configured for default browser scrolling. InstallationEdit /quasar.conf.js:framework: { components: ['QScrollArea']} Basic UsageQScrollArea supports scrolling by user dragging the custom scrollbars or by using the mousewheel. If on a desktop that has a touch screen then scrolling will work with touch actions too. <!-- In this example we set a height to force custom scrollbars to appear--><q-scroll-area style=\"width: 400px; height: 100px;\"> <div v-for=\"n in 10\"> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </div></q-scroll-area> Vue Properties Property Description thumb-style Object with CSS properties and values for styling the thumb of custom scrollbar. content-style Object with CSS properties and values for styling the container of QScrollArea. content-active-style Object with CSS properties and values for styling the container of QScrollArea when scroll area becomes active (is mouse hovered). delay Number (in milliseconds, default is 1000) defining a delay before custom scrollbars become visible after mouse is hovering the container. Custom Scrollbar Example<!-- Custom scrollbar thumb with a delay of 1.5 seconds before appearing after hovering the mouse over the scrollable content--><q-scroll-area style=\"height: 200px\" :thumb-style=\"{ right: '4px', borderRadius: '5px', background: 'red', width: '10px', opacity: 1 }\" :delay=\"1500\"> ...Scrollable.Content...</q-scroll-area> Vue Methods Method Description setScrollPosition(offset[, duration]) Set scroll position to an offset. If a duration (in milliseconds) is specified then the scroll is animated."},{"title":"Scroll Observable","updated":"2018-07-23T16:37:49.859Z","permalink":"https://v0-16.quasar-framework.org/components/scroll-observable.html","text":"QScrollObservable is a Quasar component that emits a scroll event whenever the user scrolls the page or overflowed container with .scroll CSS class applied to it. InstallationEdit /quasar.conf.js:framework: { components: ['QScrollObservable']} Basic Usage<template> ... <q-scroll-observable @scroll=\"userHasScrolled\" /> ...</template><script>export default { ..., methods: { ..., userHasScrolled (scroll) { console.log(scroll) // { // position: 56, // pixels from top // direction: 'down', // 'down' or 'up' // directionChanged: false, // has direction changed since this handler was called? // inflexionPosition: 56 // last scroll position where user changed scroll direction // } } }}</script> Determining Scrolling ContainerAll components or directives in Quasar have a simple algorithm to determine which is the container that supports the scroll: it searches for a parent DOM element which has the scroll Quasar CSS Helper class attached to it. If none is found, then it considers that the scrolling takes place on the document itself. Components like QScrollArea, for example, respect this design and have the scroll class embedded into it, so that QScrollObservable (or any other scrolling component or directive) can succesfully detect it and attach the necessary event handlers to it. Please note that simply attaching scroll CSS class to a DOM element or on a Vue component will have no effect if the respective element is not overflowed (example, with: CSS overflow: hidden and a height smaller than its inner content height). Example of good container:<!-- Quasar CSS helper 'overflow-hidden' is equivalent to style=\"overflow: hidden\"--><div class=\"scroll overflow-hidden\" style=\"height: 100px\"> ...content expanding over the 100px height from container... <q-scroll-observable @scroll=\"scrollHandler\" /> <!-- example with `v-scroll` directive --> <div v-scroll=\"scrollHandler\">...</div></div> One more example with QScrollArea:<q-scroll-area style=\"width: 400px; height: 500px;\" class=\"bg-yellow\"> ...content expanding over the 500px height from container... <q-scroll-observable @scroll=\"scrollHandler\" /></q-scroll-area> Layout ScrollingWhen scrolling on a Layout with a Page, rather than injecting a QScrollObservable (and by so doing registering additional scroll events) you can take advantage of QLayout´s @scroll event directly on your component defining the Layout. <q-layout @scroll=\"scrollHandler\">...</q-layout>"},{"title":"Scrolling Utils","updated":"2018-05-18T22:01:01.039Z","permalink":"https://v0-16.quasar-framework.org/components/scrolling-utils.html","text":"Determine Scrolling ContainerMight be worthwhile to read how this is done hereimport { scroll } from 'quasar'const { getScrollTarget } = scroll// Get parent DomNode that handles page scrolling// Usually this is element with classname \".layout-view\" or \"window\"(DOM Element) getScrollTarget(DomElement) Get/Set Scroll Positionimport { scroll } from 'quasar'const { getScrollPosition, setScrollPosition } = scroll// Get scroll position of a element or page. Use it in conjunction with `getScrollTarget()`(Number pixels) getScrollPosition(scrollTargetDomElement)// Setting scroll position of an element or page:setScrollPosition (scrollTargetElement, offset[, duration])// if \"duration\" is specified then it will animate the scrolling Scrolling to an elementA full example using the scroll utils to scroll to an element: import { scroll } from 'quasar'const { getScrollTarget, setScrollPosition } = scroll// takes an element objectfunction scrollToElement (el) { let target = getScrollTarget(el) let offset = el.offsetTop - el.scrollHeight let duration = 1000 setScrollPosition(target, offset, duration)} Determine Scroll Heightimport { scroll } from 'quasar'const { getScrollHeight } = scroll// get scrolling container inner height(Number) getScrollHeight(scrollTargetDomElement)console.log( getScrollHeight(el) )// 824 (it's in pixels always) Determining Scrollbar WidthComputes the width of scrollbar in pixels. import { scroll } from 'quasar'const { getScrollbarWidth } = scrollconsole.log(getScrollbarWidth()) // 16 (it's in pixels)"},{"title":"Directive \"v-scroll\"","updated":"2018-05-18T22:01:01.038Z","permalink":"https://v0-16.quasar-framework.org/components/scroll-directive.html","text":"This is a Vue directive which takes one parameter (a Function) and fires when user scrolls the page containing that DOM node. One alternative to using this directive is to place a QScrollObservable component on your page. InstallationEdit /quasar.conf.js:framework: { directives: ['Scroll']} Basic Usage<!-- Template for VueModel below -->...<div v-scroll=\"scrolled\">...</div>... // VueModel for template above{ ..., methods: { ..., scrolled (position) { // when this method is invoked then it means user // has scrolled the page to `position` // // `position` is an Integer designating the current // scroll position in pixels. } }} IMPORTANTPlease note that by default the method called is not debounced. For that you have to do it yourself, by wrapping your method with Quasar’s debouncer (as an example) like in example below.Read more about debouncing here. import { debounce } from 'quasar'export default { ..., methods: { ..., scrolled: debounce(position => { // when this method is invoked then it means user // has scrolled the Page to `position` // // `position` is an Integer designating the current // scroll position in pixels. }, 200) // debounce for 200ms }} NOTEThere is one more scrolling-related directive available called “Scroll Fire” described on its own documentation page. Read more here. Determining Scrolling ContainerPlease read here about how Quasar determines the container to attach scrolling events to."},{"title":"Search (Textfield)","updated":"2018-07-23T16:37:49.860Z","permalink":"https://v0-16.quasar-framework.org/components/search.html","text":"The Search component offers the users an input field with additional features for searching purposes. For autocomplete functionality, also refer to QAutocomplete documentation. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QSearch']} Basic Usage<q-search v-model=\"search\" /> Vue PropertiesSupports v-model which should be binded to a String or Number (depending on type property used) in your scope. Vue Property Type Description icon String Icon to use. no-icon Boolean Hide the icon type String Must be one of the following: text (default), email, tel, number and url. This is important as it determines the keyboard type popping up on mobile devices. debounce Number Number of ms to debounce input. Default is 300. readonly Boolean If set to true, textfield is readonly and the user cannot change value. A more involved example:<q-search v-model=\"searchModel\" :debounce=\"600\" placeholder=\"Hotels\" icon=\"local_hotel\" float-label=\"What is your hotel?\"/> Common input field properties: Property Type Description autofocus Boolean Focus input field after rendering component. placeholder String A text to be shown on textfield, mainly to explain what should be entered. clearable Boolean If set to true, the component offers the user an actionable icon to remove the entered text. Also note you can use the native DOM attributes of an input: “name”, “max-length”, “autocomplete” and so on. Common input frame properties: Property Type Description prefix String A text that should be shown before the textfield. suffix String A text that should be shown after the textfield. float-label String A text label that will “float” up above the input field, once the input field gets focus. stack-label String A text label that will be shown above the input field and is static. color String One from Quasar Color Palette. inverted Boolean Inverted mode. Color is applied to background instead. inverted-light Boolean Inverted mode with a light color. Color is applied to background instead. hide-underline Boolean Hides the bottom border. dark Boolean Is QSearch rendered on a dark background? align String One of ‘left’, ‘center’ or ‘right’ which determines the text align within textfield. disable Boolean If set to true, textfield is disabled and the user cannot type anything. warning Boolean If set to true, the input fields colors are changed to show there is a warning. error Boolean If set to true, the input fields colors are changed to show there is an error. before Array of Objects Icon buttons on left side of input frame. Read below more details. after Array of Objects Icon buttons on right side of input frame. Read below more details. Icon buttonsThis section refers to before and after properties which can add additional buttons as icons to the textfield. Here is the structure of the two properties: { // required icon icon: String, // required function to call when // icon is clicked/tapped handler: Function, // Optional. Show icon button // if model has a value content: Boolean, // Optional. Show icon button // if textfield is marked with error error: Boolean} Examples:<!-- Show an icon button (with 'warning' as icon) when there is an error on QInput (through \"error\" prop)--><q-search v-model=\"text\" :after=\"[ { icon: 'warning', error: true, handler () { // do something... } } ]\"/><!-- Show an icon button (with 'attach_file' as icon) when the model has a non empty value--><q-search v-model=\"text\" :after=\"[ { icon: 'attach_file', content: true, handler () { // do something... } } ]\"/> Lazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-search :value=\"model\" @change=\"val => { model = val }\"/> Vue Methods Vue Method Description clear() Resets the model to an empty string. clearAndFocus() Resets the model to an empty string and gives the input focus. focus() Focused the textfield. blur() Makes textfield lose focus. select() Selects all textfield text and focuses. Vue Events Vue Event Description @input(newVal) Triggered immediately on model value change. @change(newVal) Triggered on lazy model value change. @clear(clearVal) Triggered when the model is cleared. @focus Triggered on focus. @blur Triggered a blur. @keydown Triggered by keydown event on textfield. @keyup Triggered by keyup event on textfield. @click Triggered by a native click event on textfield. ColoringUse the color prop with one of the Quasar colors from the Color Palette, like primary, secondary, orange-7, teal-2: <q-search color=\"orange\" v-model=\"search\" /> Use the inverted prop, to change the background of the input to the color. <q-search inverted color=\"orange\" v-model=\"search\" /> Error StateUse the error prop to show there has been an error. This will turn the component color to red.<q-search error v-model=\"search\" /><q-search :error=\"hasError\" inverted v-model=\"search\" /> DisableUse the disable prop to stop user input.<q-search disable v-model=\"search\" color=\"primary\" /> Usage with LayoutIf you’d like to set search within a QToolbar on QLayout:<q-layout> ... <!-- Notice we set a color for QToolbar and QSearch has \"inverted\" and color=\"none\" specified. This makes QSearch use background color set by QToolbar. --> <q-toolbar slot=\"header\" color=\"primary\"> <q-search inverted color=\"none\" v-model=\"search\" /> </q-toolbar> ...</q-layout> FormattingIt is possible to add formatting to a QSearch in two ways. One is for the basic component. The other is with the QField component. Both methods offer “inverted” coloring. Additional Vue Properties Property Type Description color String The color the QInput should have. The default is primary. inverted Boolean Set to true, to color field’s background set by the color prop. dark Boolean Set to true, if the field is on a dark background. It will invert the text color to make it light. align Text Controls the ‘right’, ‘center’ or ‘left’ alignment of the input. The default is ‘left’. Basic Formatting ExamplesThis will color the field black. <q-search v-model=\"text\" float-label=\"Colored\" color=\"black\" /> This will show an inverted colored input field in amber. Here, the text is automatically inverted to a lighter color. <q-search v-model=\"text\" inverted color=\"amber\" stack-label=\"Amber Colored Background\" /> AlignmentYou can also align the input to the right, center or left. The default is left. The below example will show a field for Euro currency input. <!-- Align textfield content to the right --><q-search v-model=\"text\" align=\"right\" /> Basic Usage with QFieldIt is also possible to further enhance a QInput by wrapping it in a QField component. <div class=\"bg-grey-9\" style=\"width: 500px; padding: 25px\"> <q-field icon=\"wifi\" label=\"Some Label\" :count=\"10\" helper=\"Some helper\" :error=\"error\" error-label=\"Some error\" > <q-search v-model=\"text\" dark inverted color=\"black\" float-label=\"Textfield\" /> </q-field></div> The above usage of QField will show the input field within a dark grey background with an inverse white text. Notice the usage of the dark prop for QInput. This controls the inversion of the text color. Please refer to the QField documentation for more info about its usage."},{"title":"Select","updated":"2018-07-23T16:37:49.861Z","permalink":"https://v0-16.quasar-framework.org/components/select.html","text":"Select component has two types of selection: single selection (using Radios or Lists) or multiple selection (using Checkboxes or Toggles). This component opens up a Popover for the selection list and action. A filter can also be used for longer lists. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QSelect']} Basic Usage<template> <div> <!-- Single Selection using Radios --> <q-select v-model=\"select\" float-label=\"Is Quasar Awesome?\" radio :options=\"selectOptions\" /> <!-- Single Selection as a simple List --> <q-select v-model=\"select\" :options=\"selectOptions\" /> <!-- Multiple Selection using Checkboxes by default --> <q-select multiple v-model=\"multipleSelect\" :options=\"selectOptions\" /> <!-- Multiple Selection using Toggles --> <q-select multiple toggle v-model=\"multipleSelect\" :options=\"selectOptions\" @change=\"inputChange\" /> </div></template><script>export default { data () { return { selectOptions: [ { label: 'Google', value: 'goog' }, { label: 'Facebook', value: 'fb' } ] } }}</script> Vue PropertiesSupports v-model which should be the String for single selection and Array for multiple selection. Vue Property Type Description options Array (Required) A list of objects to present as the selection’s options. See below for the data format for the array. multiple Boolean If set to true, multiple selections will be allowed. radio Boolean If set to true, the selection will be through radios. For single selection only. toggle Boolean If set to true, the selection options will offer a toggle to select them. chips Boolean If set to true, the selections will appear as chips (instead of comma separated strings) on the input frame (works for multiple selection only). chips-color String Override default children chips text color. chips-bg-color String Override default children chips background color. readonly Boolean If set to true, select is readonly and the user cannot change model. filter Boolean If set to true, the selections will offer an input to filter the selection options. autofocus-filter Boolean Auto-focus on the filter input field (if available) when opening selection. filter-placeholder String A text to show in the filter input field. Default is “Filter”. separator Boolean If set to true, the selection options will be separated by a line. display-value String Overrides text displayed in input frame. See “Working with Display Value” section below. placeholder String Placeholder text. clearable Boolean If set to true, the component offers the user an actionable icon to remove the current selection. no-icon Boolean Use no icon on left side Common input frame properties: Property Type Description prefix String A text that should be shown before the textfield. suffix String A text that should be shown after the textfield. float-label String A text label that will “float” up above the input field, once the input field gets focus. stack-label String A text label that will be shown above the input field and is static. color String One from Quasar Color Palette. inverted Boolean Inverted mode. Color is applied to background instead. inverted-light Boolean Inverted mode with a light color. Color is applied to background instead. hide-underline Boolean Hides the bottom border. dark Boolean Is it rendered on a dark background? align String One of ‘left’, ‘center’ or ‘right’ which determines the text align within the textfield. disable Boolean If set to true, the field is disabled and the user cannot select anything. warning Boolean If set to true, the component colors are changed to show there is a warning. error Boolean If set to true, the input field’s colors are changed to show there is an error. before Array of Objects Icon buttons positioned on the left side of field. after Array of Objects Icon buttons on the right side of the field. Icon buttonsThis section refers to before and after properties which can add additional buttons as icons to the textfield. Here is the structure of the two properties: { // required icon icon: String, // required function to call when // icon is clicked/tapped handler: Function, // Optional. Show icon button // if model has a value content: Boolean, // Optional. Show icon button // if textfield is marked with error error: Boolean} Examples:<!-- Show an icon button (with 'warning' as icon)--><q-select v-model=\"selection\" :options=\"selectListOptions\" :after=\"[ { icon: 'warning', handler () { // do something... } } ]\"/><!-- Show an icon button (with 'arrow_forward' as icon) when the model has a non empty value (like something has been selected).--><q-select v-model=\"selection\" :options=\"selectListOptions\" :after=\"[ { icon: 'arrow_forward', content: true, handler () { // do something... } } ]\"/> Selection TypesYou have a number of possible selection types to choose from. They are straight text with optional icons and stamp values, radios, checkboxes, and toggles. Text is default for single selections and checkboxes are default for multiple selections. Use the radio prop for single selections. These checkboxes are inserted where the icons would be, so you cannot have icons and checkboxes for multiple selections. If you still want icons with your multiple selections, use the toggle prop. This would, however, replace the stamp option. <!-- Radios for single selections --><q-select radio v-model=\"select\" float-label=\"Gogu\" :options=\"selectListOptions\"/><!-- Toggles for Multiple Selection --><q-select toggle multiple v-model=\"multipleSelect\" :options=\"selectListOptions\"/> The Options Array FormatBelow are examples of the array of options you must use to create the selection options: Select options object:selectOptions: [ { label: 'Google', value: 'goog' }, { label: 'Facebook', value: 'fb' }, ...] More advanced select list object example: selectListOptions: [ { label: 'Google', icon: 'search', value: 'goog' }, { label: 'Facebook', inset: true, sublabel: 'Enables communication', value: 'fb' }, { label: 'Oracle', sublabel: 'Some Java for today?', icon: 'mail', leftColor: 'secondary', // color for left side, whatever it is (icon, letter, ...) rightIcon: 'alarm', rightColor: 'negative', // color for right side, whatever it is (icon, letter, ...) value: 'ora' }, { label: 'Apple Inc.', inset: true, stamp: '10 min', value: 'appl' }, ...] NoteSet “inset” to true, instead of an icon, so the label text is properly aligned with the other options that use icons or avatars. Use an Object for each option like above (notice that it uses some properties from List and List Items components, like “label”, “sublabel”, “stamp”, “icon”, “rightIcon” and so on. Here is the full list of properties that can be used for each option: Property Type Description leftColor String Color for left side from Quasar Color Palette. icon String Icon on the left to use. avatar String URL pointing to statics for an avatar. letter String One character String. leftInverted Boolean Invert mode, but only for icon and letter. leftTextColor String Override default “white” text-color when using an icon or letter only. image String URL pointing to statics for an image. label String Main label of the selection. sublabel String Sub-label of the selection. labelLines String/Number Number of lines that label can expand to. sublabelLines String/Number Number of lines that the sublabel can expand to. inset Boolean Inset Label if no left-side is specified (no icon, avatar, letter or image). rightColor String Color for right side from Quasar Color Palette. rightIcon String Icon on the right to use. rightAvatar String URL pointing to statics for an avatar on right side. rightLetter String One character String for right side. rightImage String URL pointing to statics for an image on right side. rightInverted Boolean Invert mode, but only for icon and letter. rightTextColor String Override default “white” text-color when using an icon or letter only. stamp String Stamp to use for right side. Example: ‘10 min ago’. Working with Display ValueIf for some reason you want to have total control over the text in the input frame (replacing the comma delimited option strings), then use display-value property: <q-select :display-value=\"`${ multipleSelect.length } item${ multipleSelect.length !== 1 ? 's' : '' } selected`\" multiple v-model=\"multipleSelect\" float-label=\"Select a company\" :options=\"selectLongListOptions\"/> For a more elegant solution (and more efficient too), use a computed property:<template> <!-- Notice \"display-value\" is binded to \"text\" variable --> <q-select :display-value=\"text\" multiple v-model=\"multipleSelect\" float-label=\"Select a company\" :options=\"selectLongListOptions\" /></template><script>export default { data () { return { multipleSelect: /* value */, selectOptions: /* options */ } }, computed: { text () { // in this example we want to show how many items are selected, // so we need to check model (multipleSelect) length return `${this.multipleSelect.length} item${this.multipleSelect.length > 1 ? 's' : ''} selected` } }}</script> Lazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-select :value=\"model\" @change=\"val => { model = val }\" :options=\"selectOptions\"/> Vue Methods Vue Method Description show() Opens the Popover hide() Closes the Popover clear() Resets the model to an empty string. Vue Events Vue Event Description @input(newVal) Triggered immediately on model value change. @change(newVal) Triggered on lazy model value change. @clear(clearVal) Triggered when the model is cleared. @focus Triggered when the field gets focus. @blur Triggered when the field loses focus. More ExamplesError StateUse the error prop, to change the color of the component to red:<q-select error multiple v-model=\"multipleSelect\" :options=\"selectOptions\"/> DisableUse the disable prop, to stop access to the field.<!-- Disabled state --> <q-select disable float-label=\"Disabled Select\" multiple v-model=\"multipleSelect\" :options=\"selectOptions\"/> LabelingAs with any input, you have two options for labels. Stack and Floating. Unless you wrap it with a QField which has its own label.<!-- Floating Label --><q-select float-label=\"This Label Floats\" multiple v-model=\"multipleSelect\" :options=\"selectOptions\"/><!-- Stack Label --><q-select static-label=\"Company\" multiple v-model=\"multipleSelect\" :options=\"selectOptions\"/> ColoringUse the color, inverted and frame-color props to control the coloring of the component.<!-- Color --><q-select color=\"amber\" v-model=\"select\" :options=\"selectListOptions\"/><!-- Inverted Color --><q-select inverted color=\"secondary\" v-model=\"select\" :options=\"selectListOptions\"/><!-- With custom colors for Chips.--><q-select color=\"amber\" chips-color=\"yellow\" chips-bg-color=\"black\" inverted-light multiple chips v-model=\"multipleSelect\" :options=\"selectListOptions\" float-label=\"Some label\"/> NoteThe optional frame-color prop is useful when using chips as selected values, so the chips stand out from the background color. Usage Inside of a List<q-list> <q-list-header>Single Selection</q-list-header> <q-item> <q-item-side icon=\"supervisor_account\" /> <q-item-main> <q-select class=\"no-margin\" v-model=\"select\" :options=\"selectOptions\" /> </q-item-main> </q-item> <q-item-separator /> <q-list-header>Multiple Selection</q-list-header> <q-item> <q-item-side icon=\"supervisor_account\" /> <q-item-main> <q-select multiple class=\"no-margin\" v-model=\"multipleSelect\" :options=\"selectOptions\" /> </q-item-main> </q-item></q-list>"},{"title":"Scroll Fire","updated":"2018-05-18T22:01:01.038Z","permalink":"https://v0-16.quasar-framework.org/components/scroll-fire.html","text":"“Scroll Fire” is a feature that enables a method to be called (once and only once) when user scrolls current page and the DOM element (or component) that it is applied to comes into the viewport. For ease of use, its implementation is through a Vue Directive called v-scroll-fire. NOTEThere is also a v-scroll directive which fires whenever user scrolls the page, available to read here.. InstallationEdit /quasar.conf.js:framework: { directives: ['ScrollFire']} Basic Usage<!-- Template for VueModel below -->....<div v-scroll-fire=\"bounceImage\">...</div> // VueModel for template above{ ..., methods: { bounceImage (element) { // in this example, when the `<div>` comes into view, // we bounce it for 2 seconds // we add helper `nimate-bounce` Quasar CSS class element.classList.add('animate-bounce') setTimeout(() => { // we make sure the node is still in DOM // (user hasn't navigated away from the Vue component // rendering our `<div>`) // so we don't generate an error if (document.body.contains(element)) { // then remove the helper class to // stop bouncing element.classList.remove('animate-bounce') } }, 2000) } }} IMPORTANTFor performance purposes, the scroll listener function injected is by default debounced by 50ms. Read more about debouncing here. Determining Scrolling ContainerPlease read here about how Quasar determines the container to attach scrolling events to."},{"title":"CSS Shadows (Elevation)","updated":"2018-05-18T22:01:01.041Z","permalink":"https://v0-16.quasar-framework.org/components/shadows.html","text":"Simple yet effective way to add shadows to create a depth/elevation effect.The shadows are in accordance to Material Design specifications (24 levels of depth). Don’t forget to check the demo. CSS Class Name Description no-shadow Remove any shadow inset-shadow Set an inset shadow shadow-1 Set a depth of 1 shadow-2 Set a depth of 2 shadow-N Where N is an integer from 1 to 24. shadow-transition Apply a CSS transition on the shadow; best use in conjunction with hoverable classes Example:<div class=\"shadow-1\">...</div> The shadows above point towards the bottom of the element. If you want them to point towards the top of the element, add up before the number: CSS Class Name Description shadow-up-1 Set a depth of 1 shadow-up-2 Set a depth of 2 shadow-up-N Where N is an integer from 1 to 24."},{"title":"Slider","updated":"2018-05-18T22:01:01.042Z","permalink":"https://v0-16.quasar-framework.org/components/slider.html","text":"Quasar Slider is a great way to make the user specify a number value between a minimum and maximum value, with optional steps between valid values. Also check its “sibling”, the Range component.Remember you can use QSlider wrapped by a QField too. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QSlider']} Basic Usage<q-slider v-model=\"selectedValue\" :min=\"1\" :max=\"7\" /> Example with step, label and snap:<q-slider v-model=\"selectedValue\" :min=\"0\" :max=\"10\" :step=\"2\" label snap/> Example with square slider button:<q-slider v-model=\"selectedValue\" :min=\"0\" :max=\"10\" square/> Vue PropertiesSupports v-model which should be binded to a Number in your scope. Vue Property Type Description min Number Minimum value of the model. Default is 1. max Number Maximum value of the model. Default is 5. label Boolean Popup a label when user clicks/taps on the Range and moves it. label-always Boolean Always display the label. label-value String Override default label value. fill-handle-always Boolean Fill handle even if at minimum value. step Number Specify step amount between valid values. decimals Number Specify maximum number of decimals. snap Boolean Range handler will snap on values, rather than sliding freely; good to use along step; also displays step markers on the Range. markers Boolean Display markers on background, one for each possible value for the model. square Boolean When true. the slider button is square instead of round. color String One of Quasar Color Palette. error Boolean If set to true, the slider is turned red. warning Boolean If set to true, the slider is turned yellowish. readonly Boolean If set to true, the user cannot change model value. disable Boolean If set to true, the user cannot change model value. IMPORTANTMake sure you choose the min, max and step value correctly. step must be a divisor of max - min, otherwise the component won’t work right. This is because all valid steps must be able to hold an equal position within the min and max values. Overriding LabelIn the example below we add a “px” suffix to the label.<q-slider v-model=\"model\" label-always :min=\"-20\" :max=\"20\" :label-value=\"`${model}px`\"/> Lazy InputVue will soon supply the .lazy modifier for v-model on components too, but until then, you can use the longer equivalent form:<q-slider :value=\"model\" @change=\"val => { model = val }\" :min=\"0\" :max=\"20\"/> ColoringUse one of the Quasar colors from the Color Palette with the color prop, like primary, secondary, orange-8, teal-4: <q-slider color=\"orange\" v-model=\"standalone\" :min=\"0\" :max=\"50\" label/> Vue Events Vue Event Description @input(newVal) Triggered immediately on model value change. @change(newVal) Triggered on lazy model value change. Usage Inside of a List<q-list> <q-item> <q-item-side icon=\"volume_up\" /> <q-item-main> <q-slider v-model=\"standalone\" :min=\"0\" :max=\"50\" label /> </q-item-main> </q-item> <q-item> <q-item-side icon=\"brightness_medium\" /> <q-item-main> <q-slider v-model=\"standalone\" :min=\"0\" :max=\"50\" label /> </q-item-main> </q-item> <q-item> <q-item-side icon=\"mic\" /> <q-item-main> <q-slider v-model=\"standalone\" :min=\"0\" :max=\"50\" label /> </q-item-main> </q-item></q-list>"},{"title":"Slide Transition","updated":"2018-05-18T22:01:01.041Z","permalink":"https://v0-16.quasar-framework.org/components/slide-transition.html","text":"QSlideTransitions slides the DOM element (or component) up or down, based on its visibility: works alongside v-show and v-if on a single element, similar to Vue’s Transition component with the only difference being that it’s not a group transition too (it only applies to one DOM element or component). InstallationEdit /quasar.conf.js:framework: { components: ['QSlideTransition']} Basic Usage<template> <div> <q-slide-transition> <img v-show=\"visible\" src=\"~assets/quasar.jpg\" > </q-slide-transition> <q-btn @click=\"toggleVisibility\"> Toggle </q-btn> </div></template><script>export default { ..., data: { ..., visible: true }, methods: { ..., toggleVisibility () { this.visible = !this.visible } }}</script> You can also trigger the animation when rendering the component for first time (on appearance) too, by specifying the appear Boolean prop:<q-slide-transition appear> ...</q-slide-transition> (v0.15.13+) You can also use @show and @hide Vue events if you want to trigger something after animation is over."},{"title":"Quasar Stepper","updated":"2018-07-23T16:37:49.862Z","permalink":"https://v0-16.quasar-framework.org/components/stepper.html","text":"Quasar Stepper conveys progress through numbered steps. Steppers display progress through a sequence of logical and numbered steps. They may also be used for navigation. It’s usually useful when the user has to follow steps to complete a process, like in a wizard. The stepper component is built from three different child components: QStepper - main Stepper encapsulating component QStep - individual steps QStepperNavigation - helper for encapsulating Stepper navigation buttons (within QStep or globally for the stepper as direct child of QStepper) InstallationEdit /quasar.conf.js:framework: { components: [ 'QStepper', 'QStep', 'QStepperNavigation' ]} Basic UsageHere’s a small example showcasing a very basic Stepper to understand how components fit together.<q-stepper ref=\"stepper\"> <!-- Step: --> <q-step default title=\"First Step\" subtitle=\"Here we go\"> ...Step content, components, ... </q-step> <!-- Step: --> <q-step title=\"Step 2\">...</q-step> <!-- Step: --> <q-step title=\"Step 3\" subtitle=\"Review and submit\">...</q-step> <!-- Optional. \"Globally\" available Stepper navigation which means that it will be visible regardless of the current step. If we'd put QStepperNavigation under a QStep then we'd be using it for that step only. --> <q-stepper-navigation> <q-btn flat @click=\"$refs.stepper.previous()\" label=\"Back\" /> <q-btn @click=\"$refs.stepper.next()\" label=\"Next\" /> </q-stepper-navigation></q-stepper> A more involved example. This one doesn’t uses QStepperNavigation as direct child of QStepper because each step has navigation configured. Notice the additional attributes on each component below. They will be detailed in next sections.<q-stepper color=\"secondary\" ref=\"stepper\" alternative-labels> <q-step default name=\"first\" title=\"Ad style\"> <div v-for=\"n in 10\">Step 1</div> <!-- Navigation for this step at the end of QStep--> <q-stepper-navigation> <q-btn color=\"secondary\" @click=\"$refs.stepper.next()\" label=\"Continue\" /> </q-stepper-navigation> </q-step> <q-step error name=\"second\" title=\"Custom channels\" subtitle=\"Alert message\"> <div v-for=\"n in 10\">Step 2</div> <q-stepper-navigation> <q-btn color=\"secondary\" @click=\"$refs.stepper.next()\" label=\"Next\" /> <q-btn color=\"secondary\" flat @click=\"$refs.stepper.previous()\" label=\"Back\" /> </q-stepper-navigation> </q-step> <q-step name=\"third\" title=\"Get code\"> <div v-for=\"n in 3\">Step 3</div> <q-stepper-navigation> <q-btn color=\"secondary\" @click=\"$refs.stepper.next()\" label=\"Next\" /> <q-btn color=\"secondary\" flat @click=\"$refs.stepper.previous()\" label=\"Back\" /> </q-stepper-navigation> </q-step> <q-step name=\"fifth\" disable title=\"Disabled\"> <div v-for=\"n in 3\">Step 4</div> <q-stepper-navigation> <q-btn color=\"secondary\" @click=\"$refs.stepper.next()\" label=\"Next\" /> <q-btn color=\"secondary\" flat @click=\"$refs.stepper.previous()\" label=\"Back\" /> </q-stepper-navigation> </q-step> <q-step name=\"fourth\" title=\"Review and Finalize\"> <div v-for=\"n in 3\">Step 5</div> <q-stepper-navigation> <q-btn color=\"secondary\" @click=\"$refs.stepper.next()\" label=\"Next\" /> <q-btn color=\"secondary\" flat @click=\"$refs.stepper.previous()\" label=\"Back\" /> </q-stepper-navigation> </q-step></q-stepper> QStepper (Parent) Vue Property Type Description color String Main color of Stepper, from Quasar Color Palette. vertical Boolean Set Stepper as vertical instead of default horizontal. alternative-labels Boolean Use alternative labels (applies only to horizontal Stepper). contractable Boolean Labels are hidden on narrow windows. no-header-navigation Boolean (Quasar v0.15.7+) Disable ability to navigate to previous steps through header. order Number / String If you add/remove Steps dynamically, it’s good to use this prop to specify the order in which Steps should be displayed. done-icon String, Boolean Used to change the display of the Step icon, when the step is finished. Default is the “check” icon. active-icon String, Boolean Used to change the icon, when a Step is selected. Default is the “edit” icon. error-icon String / Boolean Used to change the icon, when there is an error in a Step. Default is the “warning” icon. You can also control the current step by using v-model on QStep. More details in next section. Vue Method Description goToStep(String) Moves the user to the given Step, defined by Step’s “name” property. next() Stepper goes to the next step. previous() Stepper goes to the previous step. reset() Returns the stepper back to the first step. Component events: Vue Event Description @step Emitted when navigating to another step. Using v-modelEach QStep has a name prop (which is optional). Use this prop along with v-model to control the current step. The example below shows how you can use v-model alone to control navigation. Notice the @click events. If you dynamically insert/remove Steps it’s better to use a Vue reference on QStepper and call next() or previous() methods since these methods are not binded to specific Step names. <template> <q-stepper v-model=\"currentStep\"> <q-step name=\"first\"> ... <q-stepper-navigation> <q-btn color=\"primary\" @click=\"currentStep = 'second'\" label=\"Go to Step 2\" /> </q-stepper-navigation> </q-step> <q-step name=\"second\"> ... <q-stepper-navigation> <q-btn color=\"primary\" @click=\"currentStep = 'first'\" label=\"Go Back\" /> </q-stepper-navigation> </q-step> </q-stepper></template><script>export default { data () { return { // we initialize it with first step's name currentStep: 'first' } }}</script> QStep (Child) Vue Property Type Description name Number, String Step name, used by QStepper’s v-model or goToStep() method. default Boolean (Optional) Use it on only one Step. Becomes default selected one. error Boolean Mark Step as having an error. default Boolean Use on only one Step to make it be the active one by default. Previous steps will be marked as done. Useful when refreshing page. title String Step title. subtitle String Step’s additional information along the title. icon String Step’s icon when Step isn’t finished yet. If no active-icon is specified, then this icon will be used when Step is currently active too. active-icon String The icon used for the Step when it’s currently active. Defaults to icon prop value when active-icon isn’t specified. done-icon String The icon to use for Step when it’s finished. error-icon String The icon to use for Step when it’s marked as having an error. disable Boolean Step is disabled. Methods for this component: Vue Method Description select() Stepper selects this step as current one. QStepperNavigation (Child of QStepper or QStep)This component allows you to place buttons within QStepper or QStep to navigate through the steps. It is up to you to add whatever buttons you require. <q-stepper ref=\"myStepper\"> ... <q-stepper-navigation> <q-btn color=\"secondary\" @click=\"$refs.myStepper.next()\" label=\"Next\" /> <q-btn color=\"secondary\" @click=\"$refs.myStepper.previous()\" label=\"Back\" /> </q-stepper-navigation></q-stepper> More ExamplesVertical StepperIt is also possible to build a stepper, which presents itself in a vertical fashion. To do this, simply use vertical property on QStepper: <q-stepper vertical> <q-step>..</q-step> <q-step>..</q-step> ...</q-stepper> When using a vertical Stepper, it doesn’t really make sense to use a “global” QStepper navigation. Instead, use navigation within each QStep. Displaying ProgressA common case is where you need to take an asynchronouse action (like an Ajax call) before going to next step. Make use of QInnerLoading component for this: <q-stepper> <!-- Steps... --> ........ <!-- Create a Boolean scope variable (here it's \"inProgress\") and binded to \"visible\" prop. Then toggle it whenever you need to display that the Stepper has a background process going. --> <q-inner-loading :visible=\"inProgress\" /></q-stepper> Specific Steps OrderIf you dynamically add/remove Steps, then you need to specify the order property (for ALL QSteps) so that the Stepper will know the actual order of Steps. By using v-if or v-for directives, Vue & Quasar can’t ensure Steps will be registered in the order they are placed in DOM. IMPORTANTJust make sure that when you use order you apply it to all QSteps and don’t leave out any step without it. Either use order for all QSteps or don’t use it at all. <q-stepper> <!-- Will come as second step --> <q-step :order=\"2\">..</q-step> <!-- Will come as first step --> <q-step :order=\"1\">..</q-step> <!-- Will come as third step --> <q-step :order=\"3\">..</q-step></q-stepper> The order property applied to all QStep doesn’t has to be strictly growing consecutively. Setting order as 10, 100 and 52 will work too."},{"title":"CSS Spacing Classes","updated":"2018-05-18T22:01:01.042Z","permalink":"https://v0-16.quasar-framework.org/components/spacing.html","text":"There are CSS classes supplied by Quasar to help you with spacing for DOM elements or components. Syntaxq-[p|m][t|r|b|l|a|x|y]-[none|xs|sm|md|lg|xl] T D ST - type - values: p (padding), m (margin)D - direction - values: t (top), r (right), b (bottom), l (left), a (all), x (both left & right), y (both top & bottom)S - size - values: none, xs (extra small), sm (small), md (medium), lg (large), xl (extra large) Examples<!-- small padding in all directions --><div class=\"q-pa-sm\">...</div><!-- medium margin to top, small margin to right --><q-card class=\"q-mt-md q-mr-sm\">...</q-card>"},{"title":"Tabs","updated":"2018-07-23T16:37:49.863Z","permalink":"https://v0-16.quasar-framework.org/components/tabs.html","text":"Quasar Tabs are a way of displaying more information using less window real estate.One common use case for this component is in Layout’s header/footer in a QToolbar. Please refer to Layouts and Toolbar for references. InstallationEdit /quasar.conf.js:framework: { components: [ 'QTabs', 'QTab', 'QTabPane', 'QRouteTab' ]} Basic UsageBelow is a basic example of the Tabs component using many of its features. <q-tabs> <!-- Tabs - notice slot=\"title\" --> <q-tab default count=\"5\" slot=\"title\" name=\"tab-1\" icon=\"message\" /> <q-tab disable slot=\"title\" name=\"tab-2\" icon=\"fingerprint\" /> <q-tab alert slot=\"title\" name=\"tab-3\" icon=\"account_box\" /> <q-tab slot=\"title\" name=\"tab-4\" icon=\"accessibility\" /> <q-tab slot=\"title\" name=\"tab-5\" icon=\"build\" /> <!-- Targets --> <q-tab-pane name=\"tab-1\">Tab One</q-tab-pane> <q-tab-pane name=\"tab-2\">Tab Two</q-tab-pane> <q-tab-pane name=\"tab-3\">Tab Three</q-tab-pane> <q-tab-pane name=\"tab-4\">Tab Four</q-tab-pane> <q-tab-pane name=\"tab-5\">Tab Five</q-tab-pane></q-tabs> The above example is using QTabPane component as the content container (or target container) for the tabs. There is also the ability to use Vue Router for each tab instead of targeting a QTabPane. Also, QTabPanes are optional and you can use v-model on QTabs. We’ll cover those features later. The name prop on QTab and QTabPane links the tab to the targets (panes). As you can see from the example, we have a main Tab container with (QTabs) and singular Tabs themselves with (QTab). Let’s look at the Tabs container first: QTabs (Container Component)Use the QTabs component to wrap your Tabs. Vue Properties Vue Property Type Description align String The type of the alignment for the tabs within the tabs container. The allowed values are left (default), center, right or justify. position String The screen position of the tabs. The allowed values are top or bottom. color String A Quasar standard CSS color. text-color String (Quasar v0.15.7+) One from Quasar Palette to override color of text inverted Boolean Set to true, to invert the tab color. two-lines Boolean Set to true, should a tab’s label wrap to a second line. no-pane-border Boolean Avoid drawing a border around QTabPanes. glossy Boolean Apply a glossy effect There is support for v-model (which is optional). In this case, you need a Vue variable in your scope which will contain the name of the current selected tab (through name prop on QTab). Changing the value will also make QTabs select the according QTab. Basic usage with v-model:<template> <div> <q-tabs v-model=\"selectedTab\"> <q-tab slot=\"title\" name=\"tab-1\" icon=\"message\" /> <q-tab slot=\"title\" name=\"tab-2\" icon=\"fingerprint\" /> <q-tab slot=\"title\" name=\"tab-3\" icon=\"account_box\" /> ...optional `QTabPane`s... </q-tabs> <q-btn @click=\"selectThirdTab\">Select Third Tab</q-btn> </div></template><script>import { QTabs, QTab, QBtn } from 'quasar'export default { components: { QTabs, QTab, QBtn }, data () { return { // initializing for second tab to be selected by default selectedTab: 'tab-2' } }, methods: { selectThirdTab () { // we select third tab which has `name` set to 'tab-3' this.selectedTab = 'tab-3' } }}</script> Vue Methods Vue Method Description selectTab(name) Set the active Tab using its name. Vue Events Event Description @select Triggered when selected Tab changes. Overflow BehaviorOn a desktop, if the Tabs cannot be dispalayed completely, the user will be offered a scroll action in the form of an opaque gradient fill. When hovered over, it turns to an arrow button. The user can press continually on the button, and the unseen Tabs will scroll by. If the user is on a device with a small screen (like a phone) and all Tabs can fit on the screen, they will be automatically justify aligned and share the complete screen width. If the Tabs do not fit, then the user will also see the arrow to indicate the user can swipe through the Tabs. QTab (Child Component)QTab component is used to define a title for your Tab. Can be linked to a QTabPane through name prop.If you want to use Vue Router with a Tab (clicking on a Tab triggers a route change in your app), then please refer to QRouteTab component in next section. IMPORTANT. Do not forget to specify slot="title" on QTab. Vue Properties Vue Property Type Description default Boolean Set to true on the tab which you want to be selected by default. label String Label to use for the tab. icon String Icon to use for the tab. disable Boolean If disabled, the user won’t be able to select the tab. hidden Boolean If set to true, it hides the tab. hide String Possible values: icon or label. On narrow screens one of the two will be hidden. name String The id of the tab. Default is a uid added by Quasar. alert Boolean When true, the tab has a red dot, which is meant to get the user’s attention. count Number, String A number to indicate there is a list of unread or unseen items in the tab’s content. color String The color of the tab’s icon or text, should it be different than the default. Vue Methods Vue Method Description select() Make this Tab the selected one. Vue Events Event Description @select Triggered when QTab gets selected. @click Triggered when user clicks/taps on Tab. Usage with “v-model”Best way to programmatically switch between Tabs is by using a v-model. Here’s another example, a little bit more complex which includes a QSelect to explain the effects of using a v-model. <q-select type=\"radio\" v-model=\"tabsModel\" :options=\"tabsOptions\"></q-select><q-tabs v-model=\"tabsModel\"> <q-tab name=\"xtab-1\" icon=\"message\" slot=\"title\" /> <q-tab name=\"xtab-2\" icon=\"account_box\" slot=\"title\" /> <q-tab name=\"xtab-3\" icon=\"mail\" slot=\"title\" /> <q-tab-pane name=\"xtab-1\">Tab One</q-tab-pane> <q-tab-pane name=\"xtab-2\">Tab Two</q-tab-pane> <q-tab-pane name=\"xtab-3\">Tab Three</q-tab-pane></q-tabs> // Data for template abovedata () { return { tabsModel: 'xtab-2', tabsOptions: [ {label: 'Tab 1', value: 'xtab-1'}, {label: 'Tab 2', value: 'xtab-2'}, {label: 'Tab 3', value: 'xtab-3'} ] }} NoteWhen the tabs are initially rendered, the value stored in the v-model used by your component, as with tabsModel above, will also indicate to the user a selected tab. If you aren’t using v-model, you can set the initially active tab with the default prop. QTabPane (Child Component)The Tabs Pane component is useful, when the content of each tab is relatively small or simple. If you have complex content, you’ll propably want to use the Tabs Router Component below. Vue Properties Vue Property Type Description name String Required The name of the tab and also the target id. keep-alive Boolean Keeps components alive even if current selected Tab changes. In order to show the proper content for each tab in each pane, the names of the tabs and panes should match. QRouteTab (Child Component)The Tabs Router component is just like the QTab component and shares the same properties, however it also has Vue Router properties bound to it. These allow the triggering of your specific routing. Additional Vue Router Properties. Vue Property Type Description to String, Object The literal path or vue-router object the tab should route to. exact Boolean If true, the router will be forced into “exact match mode” append Boolean If true, the to path will be appended to the current path. replace Boolean If true, there will be no history of the used route. Please refer to Vue-Router Link documentation to get a feeling how to use these props. Usage<!-- Tabs --><q-tabs> <q-route-tab icon=\"mail\" to=\"/mails\" exact slot=\"title\" /> <q-route-tab icon=\"alarm\" to=\"/alarms\" exact slot=\"title\" /></q-tabs> Your Tabs will be auto-selected when user navigates to the specified routes. DO NOT use v-model or selectTab() method on QTabs if using QRouteTab. Tabs in a LayoutYou will, in most cases, want to use tabs within a layout component. Below is an example of how this would be done. <q-layout> ... <q-layout-header> <q-tabs> <q-route-tab icon=\"mail\" to=\"/mails\" exact slot=\"title\" /> <q-route-tab icon=\"alarm\" to=\"/alarms\" exact slot=\"title\" /> </q-tabs> </q-layout-header> ...</q-layout> Please refer to the following documentation for more information: Quasar Layout Component ColoringUse one of the Quasar colors from the Color Palette, like “primary”, “secondary”, “orange”, “teal” or variants (“teal-4”, “orange-10”) for color/text-color properties: <!-- Applied to all tabs: --><q-tabs color=\"orange\">...</q-tabs><!-- Applied only to a specific tab. In this case you can color Tabs differently:--><q-tab slot=\"title\" color=\"orange\" /> You can also invert the colors (see demo for example) by adding the Boolean inverted prop (works only on QTabs and NOT on QTab or QRouteTab): <!-- default color, on `inverted` color mode --><q-tabs color=\"orange\" inverted>...</q-tabs> Example of transparent background with green text color (v0.15.7+):<q-tabs color=\"transparent\" text-color=\"green\">...</q-tabs> Example of light color with custom text color (v0.15.7+):<q-tabs color=\"amber\" text-color=\"dark\">...</q-tabs> Alignment of Tabs in the HeaderBy default, on large width windows the Tabs are aligned to the left. If you wish to maintain a justify alignment (filling all available space on the width), then add justify to the align prop: <q-tabs align=\"justify\">...</q-tabs> To align center or to the right, use align="center" or align="right"."},{"title":"Toggle","updated":"2018-07-23T16:37:49.864Z","permalink":"https://v0-16.quasar-framework.org/components/toggle.html","text":"The Quasar Toggle component is another basic element for user input. You can use this for turning settings, features or true/ false inputs on and off. Please also refer to the Option Group documentation on other possibilities for creating groups of Toggles. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QToggle']} Basic Usage<q-toggle v-model=\"checked\" label=\"Toggle Label\" /><!-- With no label --><q-toggle v-model=\"checked\" /><!-- With a specific color --><q-toggle v-model=\"checked\" color=\"teal-8\" /><!-- With icon --><q-toggle v-model=\"checked\" icon=\"alarm\" label=\"Toggle Label\" /><!-- Disabled state --><q-toggle v-model=\"checked\" disable label=\"Toggle Label\" /> Check “Vue Properties” for even more options. Vue PropertiesSupports v-model which should be binded to a Boolean or Array in your scope. Vue Property Type Description val Object Used to modify the v-model of the Toggle when using an Array as v-model. true-value Any Gets into “true” state when model has this value. false-value Any Gets into “false” state when model has this value. label String The text label for the Toggle. left-label Boolean Set to true, if the label should be placed to the left of the Toggle. icon String Optional icon to use. Overriden by checked-icon and unchecked-icon if the latter are used. checked-icon String The icon to use, when the Toggle is checked. unchecked-icon String The icon to use, when the Toggle is not checked. color String Color from Quasar Color Palette. keep-color Boolean Keep color when not truthy too. readonly Boolean Set to true, to make the toggle read-only. disable Boolean Set to true, to disable the toggle. dark Boolean Set to true when background is dark. Vue Events Vue Event Description @input(newVal) Triggered immediately on model value change. @change(newVal) Triggered on lazy model value change. @blur Triggered, when Toggle loses focus. @focus Triggered, when Toggle gains focus. Array as ModelIf you have a number of toggles for a selection, use can also use an Array as the model object and the val prop for the inserted value into the Array. <template> <div> <q-toggle v-model=\"selection\" val=\"one\" label=\"One\" /> <q-toggle v-model=\"selection\" val=\"two\" label=\"Two\" /> <q-toggle v-model=\"selection\" val=\"three\" label=\"Three\" /> </div></template><script>export default { data () { return { selection: ['two'] } }}</script> Ticking all toggles will make selection scope variable to be ['one', 'two', 'three']. Unticking all toggles will result in selection being an empty array []. More ExamplesThere are a number of props, which are available to help quickly format a Toggle. An interesting feature of Toggle is the ripple effect that user gets when clicking/tapping on it to change its state. Custom Model ValuesInstead of the default true/false values, you can use custom ones:<q-toggle v-model=\"customModel\" color=\"secondary\" label=\"Do you agree with the terms & conditions?\" true-value=\"yes\" false-value=\"no\"/> Specific State IconsFor a more informational Toggle, you can also use the checked-icon and unchecked-icon props to display an inset icon in the toggle. <q-toggle v-model=\"checked\" unchecked-icon=\"visibility_off\" checked-icon=\"visibility\" label=\"Toggle Label\"/> Specifying checked-icon and unchecked-icon overrides icon property if you’ve also used it. ColoringUse the color prop to control the toggle’s color. <q-toggle v-model=\"checked\" color=\"orange\" /><q-toggle v-model=\"checked\" color=\"teal\" /><q-toggle v-model=\"checked\" color=\"dark\" /> Label PositionUse the left-label prop, to move the label to the left of Toggle. <q-toggle v-model=\"checked\" left-label label=\"Checkbox Label\"/> Usage Inside of a ListIn the following example we use the right side of QItems to insert Toggle, but it works anywhere. <q-list link> <!-- Rendering a <label> tag (notice tag=\"label\") so the whole QItem will respond to clicks to change Toggle state. --> <q-item tag=\"label\"> <q-item-main> <q-item-tile label>Events and reminders</q-item-tile> </q-item-main> <q-item-side right> <q-toggle v-model=\"checked\" /> </q-item-side> </q-item> <q-item tag=\"label\" multiline> <q-item-main> <q-item-tile label>Events and reminders</q-item-tile> <q-item-tile sublabel>Lorem ipsum</q-item-tile> </q-item-main> <q-item-side right> <q-toggle v-model=\"checked\" class=\"purple\" /> </q-item-side> </q-item> <q-item tag=\"label\" multiline> <q-item-main> <q-item-tile label>Events and reminders</q-item-tile> <q-item-tile sublabel>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</q-item-tile> </q-item-main> <q-item-side right> <q-toggle v-model=\"checked\" class=\"red\" /> </q-item-side> </q-item></q-list>"},{"title":"Spinners","updated":"2018-05-18T22:01:01.042Z","permalink":"https://v0-16.quasar-framework.org/components/spinner.html","text":"A Spinner is used to show the user a timely process is currently taking place. It is an important UX feature, which gives the user the feeling the system is continuing to work for longer term activities, like grabbing data from the server or some heavy calculations. InstallationEdit /quasar.conf.js:framework: { components: [ 'QSpinner', 'QSpinnerAudio', ... ]} Basic Usage<!-- Default platform spinner--><q-spinner /><!-- Spinner with options --><q-spinner color=\"secondary\" :size=\"30\" /><q-spinner color=\"teal-4\" size=\"40px\" /><!-- Alternatively, you can set CSS colo prop on a container or directly with `style` attribute on spinner--><q-spinner style=\"color: #e2aa6f\" /> Vue Properties Vue Property Type Description size Number / String Number (defining the size in pixels) or String (CSS size with unit). color String CSS color from Quasar Color Palette. You can change the spinner’s size without a loss of quality, because SVGs are used. Using Specific SpinnersIf you’d like to use a different spinner than the default, use a specific spinner component, which inherits the same props as specified above. The following specific spinners components are available. The name of these components is q-spinner-*name*, where name is one of ‘audio’, ‘ball’, ‘bars’, ‘circles’, ‘comment’, ‘cube’, ‘dots’, ‘grid’, ‘hearts’, ‘ios’, ‘mat’, ‘oval’, ‘puff’, ‘rings’, ‘tail’, ‘facebook’, ‘gears’, ‘hourglass’, ‘infinity’, ‘pie’, ‘radio’. Example: <!-- Specific spinner icon --><q-spinner-audio /><!-- Specific spinner icon with options --><q-spinner-audio color=\"primary\" :size=\"30\" /> NoteHaving to use an extra component to identify specific spinners might seem like extra work, however, the goal is to be able to remove all other spinner components in your final build, in order to keep the overall package size of your application down to a minimum. The spinners are used in components such as the QInnerLoading and QBtn components or within the Loading feature, just to name a few examples."},{"title":"Timeline","updated":"2018-07-09T22:30:23.752Z","permalink":"https://v0-16.quasar-framework.org/components/timeline.html","text":"A Timeline is a display of a list of events in chronological order. It is typically a graphic design showing a long bar labelled with dates alongside itself and usually events. Timelines can use any time scale, depending on the subject and data. QTimelines have 3 media breakpoints. View on a desktop and click the “View Desktop” link on the right side, then resize the browser window to see the media breakpoints in action. InstallationEdit /quasar.conf.js:framework: { components: [ 'QTimeline', 'QTimelineEntry' ]} Basic Usage<q-timeline color=\"secondary\"> <q-timeline-entry heading> Timeline Subject </q-timeline-entry> <q-timeline-entry title=\"Event Title\" subtitle=\"February 22, 1986\" side=\"left\" > <div> Lorem ipsum dolor sit amet. </div> </q-timeline-entry></q-timeline> QTimeline (Parent) Vue Properties Vue Property Type Description color String Color of the timeline element dark Boolean When rendering on a dark background. QTimelineEntry (Child) Vue Properties Vue Property Type Description heading Boolean Display a timeline subject which helps group timeline entries into separate chunks. tag String HTML tag to use to render the timeline entry DOM element. side Boolean On wider windows, you can choose on which side to display this entry. Default is on the right side. icon String Icon to use. color String Color to use for this entry. title String Title of the entry. subtitle String Addition to title of the entry."},{"title":"Stylus Variables","updated":"2018-05-18T22:01:01.043Z","permalink":"https://v0-16.quasar-framework.org/components/stylus-variables.html","text":"Quasar CSS is a blank slate that you can easily customize and modify to fit your brand, while still following the standards of each platform. The best apps in the app stores are fully customized and Quasar makes it easy to do the same with your App. Quasar is built on top of Stylus, which allows it to set some default styles for your App but makes it extremely easy for you to change the defaults in your App code. Customizing a theme means overriding Stylus variables which can hold colors, sizes, border types and so on. To understand how and where to make use of the full list of variables below, read Guide > Theming. Variables List"},{"title":"Toolbar","updated":"2018-05-18T22:01:01.045Z","permalink":"https://v0-16.quasar-framework.org/components/toolbar.html","text":"A Quasar Layout can have headers and/or footers (also called “marginals”) and this is a great place to use Toolbars, but note that you can also place Toolbars anywhere else you want. One QToolbar will represent a row in your marginals, usually used for navigation buttons and a title (but not limited to only this). InstallationEdit /quasar.conf.js:framework: { components: [ 'QToolbar', 'QToolbarTitle' ]} Basic Usage<q-toolbar color=\"primary\"> <!-- For Toolbar title, we use QToolbarTitle component --> <q-toolbar-title> Title </q-toolbar-title> <!-- In a Toolbar, buttons are best configured as \"flat, round, dense\" and with an icon, but any button will do --> <q-btn flat round dense icon=\"mail\" /></q-toolbar><!-- A color \"inverted\" Toolbar --><q-toolbar color=\"primary\" inverted> ...</q-toolbar><!-- A color \"inverted\" Toolbar with custom text color --><q-toolbar color=\"amber\" text-color=\"dark\" inverted> ...</q-toolbar><!-- A Toolbar with a title and subtitle --><q-toolbar color=\"primary\" inverted> <q-toolbar-title> Title <span slot=\"subtitle\"> Subtitle </span> </q-toolbar-title></q-toolbar><!-- A Toolbar with light color and overriden text color --><q-toolbar color=\"amber\" text-color=\"black\">...</q-toolbar><!-- A Toolbar with transparent background and green text color --><q-toolbar color=\"transparent\" text-color=\"green\">...</q-toolbar> Example on using a Toolbar on Layout header: <q-layout> ... <q-layout-header> <q-toolbar color=\"secondary\"> <!-- Toggles QLayout left side (Assuming the Drawer has a model bound to \"leftSide\") --> <q-btn flat round dense icon=\"menu\" @click=\"leftSide = !leftSide\" /> <q-toolbar-title> Title </q-toolbar-title> <q-btn flat round dense icon=\"mail\" /> <q-btn flat round dense icon=\"alarm\" /> </q-toolbar> </q-layout-header> ...</q-layout> QToolbar Vue Props Property Type Description color String A color from Quasar Color Palette text-color String One from Quasar Palette to override color of text inverted Boolean Invert color: background becomes “white” while text has color glossy Boolean Apply a glossy effect shrink Boolean Check Shrink section QToolbarTitleQToolbarTitle is a component used to wrap the “title” of your Toolbar. It spreads horizontally to the full real estate space it can get. If not enough space to cover the full extent of the content then ending ellipsis are used. <!-- A Toolbar with a title and subtitle --><q-toolbar color=\"primary\" inverted> ... <q-toolbar-title> Title <span slot=\"subtitle\"> Subtitle </span> </q-toolbar-title></q-toolbar> ShrinkBy default, QToolbarTitle is set to grow to the available space. However, you can change that with the shrink Boolean prop:<q-toolbar-title shrink> Title</q-toolbar-title>"},{"title":"Tooltip","updated":"2018-05-18T22:01:01.046Z","permalink":"https://v0-16.quasar-framework.org/components/tooltip.html","text":"QTooltip should be used when you want to offer the user more information about a certain area in your App. When hovering the mouse over the target element (or quickly tapping on mobile platforms), the Tooltip will appear. InstallationEdit /quasar.conf.js:framework: { components: ['QTooltip']} Basic UsageIn the example below we use a QBtn (as a target) and when hovering over it, Quasar will display some text. You can replace QBtn and the QPopover content with any DOM elements or components you like. <!-- The target button (can be anything else) must be direct parent of QTooltip on the DOM hierarchy.--><q-btn label=\"Email\"> <!-- Direct child of target --> <q-tooltip> <!-- The DOM element(s) that make up the tooltip, in this case a simple text: --> Some text as content of Tooltip </q-tooltip></q-btn> The idea is to place QTooltip inside your DOM element / component (as direct child in DOM hierarchy), when you want it to be the trigger for the QTooltip. Don’t worry about QTooltip content inheriting CSS from the container. This won’t occur, since QTooltip will be injected as a direct child of <body>. Toggle through v-model<template> <div> <q-btn color=\"primary\" @click=\"showing = true\" label=\"Show\" /> <q-btn color=\"primary\" @close=\"showing = false\" label=\"Hide\" /> <div> ... <q-tooltip v-model=\"showing\">...</q-tooltip> </div> </div></template><script>export default { data () { return { showing: false } }}</script> Vue Properties Vue Property Type Description anchor Object String of form bottom left (vertical horizontal). self Object String of form top left (vertical horizontal). offset Array of 2 Numbers Offset on horizontal and vertical (in pixels). Example: [18, 18]. max-height String Optional maximum height of Tooltip content. Example: 500px delay Number Set the delay, when tooltip should appear. disable Boolean When set to true, Tooltip won’t be triggered. Vue Methods Vue Method Description show() Open Tooltip. hide() Close Tooltip. toggle() Toggle open/close state. Handling PositioningThe position of QTooltip can be customized. It keeps account of the anchor and self optional Vue properties. Check out the demo and play with them. The final position of QTooltip popup is calculated so that it will be displayed on the available screen real estate, switching to the right-side and/or top-side when necessary."},{"title":"Touch/Mouse Hold Action","updated":"2018-05-18T22:01:01.046Z","permalink":"https://v0-16.quasar-framework.org/components/touch-hold.html","text":"Quasar offers full-featured Vue directives that can totally replace libraries like Hammerjs: v-touch-pan, v-touch-swipe and v-touch-hold. These directives also work with mouse events, not only touch events, so you are able to build cool functionality for your App on desktops too. We will be describing v-touch-hold on the lines below. InstallationEdit /quasar.conf.js:framework: { directives: ['TouchHold']} Basic Usage<div v-touch-hold=\"handler\">...</div> “handler“ is a Function which receives an Object as parameter.Please note that the default “hold” duration is 600ms. This means that your handler function will run after 600ms. Handler ParameterThe handler function/method is called by the directive when user taps/clicks and holds on the DOM element and it receives the following parameter:{ evt, // JS Native Event position: // {x, y} offset on screen duration // Number in ms}// example:handler (obj) { console.log(obj.position) // {x: 22, y: 451} console.log(obj.duration) // 600} Modifiers Property Description noMouse Avoid capturing mouse events too. stop Stop event propagation once holding has been detected. prevent Prevent default browser behavior of the event once holding has been detected. Avoid Capturing Mouse EventsWhen you don’t want to capture mouse actions too, use the noMouse modifier:<!-- directive won't be triggered by mouse actions; it's exclusively triggered by touch actions now:--><div v-touch-hold.noMouse=\"userHasHold\">...</div> Preventing Scroll (on touch capable devices)By default, the directive does not block page scrolling. If you want to prevent scrolling, then use the prevent modifier.<div v-touch-hold.prevent=\"userHasHold\">...</div> Custom Duration<div v-touch-hold:1000=\"userHasHold\">...</div>"},{"title":"CSS Transitions","updated":"2018-05-18T22:01:01.047Z","permalink":"https://v0-16.quasar-framework.org/components/transition.html","text":"CSS Transitions can be handled by the Vue Transition Component. The transitions are used for entering (appearing) or leaving (disappearing) animations. However, Quasar can supply a big list of ready to use CSS animations. The animation effects are borrowed from Animate.css. So there are 12 general, 32 entering (In) and 32 leaving (Out) animation types currently available for you to use out of the box. Check the list either on Animate.css website or on the demo available for this page. Please refer to Vue Documentation Website for learning on how to use the Vue supplied <transition> component. InstallationEdit /quasar.conf.js.// embedding all animationsanimations: 'all'// or embedding only specific animationsanimations: [ 'bounceInLeft', 'bounceOutRight'] If you are building a website, you can also skip configuring quasar.conf.js and use a CDN link which points to Animate.css like this (following is just an example, Google for latest link). Remember this will require an Internet connection for your user, as opposed to bundling from within quasar.conf.js. <!-- index.template.html --><head> ... <!-- CDN example for Animate.css --> <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css\" ></head> Basic UsageNotice the string “animated” in front of the actual animation name.<!-- Example with wrapping only one DOM element / component --><transition appear enter-active-class=\"animated fadeIn\" leave-active-class=\"animated fadeOut\"> <!-- Wrapping only one DOM element, defined by QBtn --> <q-btn color=\"secondary\" icon=\"mail\" label=\"Email\" /></transition> Wrapping Multiple ElementsYou can also group components or DOM elements in a transition so that the same effects are applied to all of them simultaneously. <!-- Example with wrapping multiple DOM elements / components --><transition-group enter-active-class=\"animated fadeIn\" leave-active-class=\"animated fadeOut\"> <!-- We wrap a \"p\" tag and a QBtn --> <p key=\"text\"> Lorum Ipsum </p> <q-btn key=\"email-button\" color=\"secondary\" icon=\"mail\" label=\"Email\" /></transition-group> Please note some things in the above example: Note <transition-group> instead of <transition>. The components and DOM elements must be keyed, like key="text" or key="email-button" in the example above. Both examples above have the Boolean property appear specified, which makes the entering animation kick in right after component(s) have been rendered. This property is optional."},{"title":"Panning Touch/Mouse Action","updated":"2018-05-18T22:01:01.047Z","permalink":"https://v0-16.quasar-framework.org/components/touch-pan.html","text":"Quasar offers full-featured Vue directives that can totally replace libraries like Hammerjs: v-touch-pan, v-touch-swipe and v-touch-hold. These directives also work with mouse events, not only touch events, so you are able to build cool functionality for your App on desktops too. We will be describing v-touch-pan on the lines below. InstallationEdit /quasar.conf.js:framework: { directives: ['TouchPan']} Basic Usage<div v-touch-pan=\"handler\">...</div>// \"handler\" is a Function which receives an Object as parameter Handler ParameterThe handler function/method will be called by the directive when a pan touch (or with mouse) action is taking place (any change in touch position triggers a call) on the DOM element and it receives the following parameter: { evt, // JS Native Event position, // {top, left} Position in pixels // where the user's finger is currently at direction, // \"left\", \"right\", \"up\" or \"down\" duration, // Number in ms since \"pan\" started distance, // {x, y} Distance in pixels covered by panning // on horizontal and vertical delta, // {x, y} Distance in pixels since last called handler isFirst, // Boolean; Has panning just been started? isFinal // Boolean; Is panning over?}// example:handler (obj) { console.log(obj.direction) // \"right\" console.log(obj.duration) // 78 console.log(obj.distance.x) // 273} Modifiers Property Description horizontal Capture only horizontal panning. vertical Capture only vertical panning. noMouse Avoid capturing mouse events too. stop Stop event propagation once panning has been detected. prevent Prevent default browser behavior of the event once panning has been detected. mightPrevent If not using prevent prop, but you might call event.preventDefault(), specify this modifier otherwise you’ll get console warnings. Use horizontal or vertical when you only want to capture horizontal or vertical swipes.<div v-touch-pan.horizontal=\"userHasPanned\">...</div> Avoid Capturing Mouse EventsWhen you don’t want to capture mouse actions too, use the noMouse modifier:<!-- directive won't be triggered by mouse actions; it's exclusively triggered by touch actions now:--><div v-touch-pan.noMouse=\"userHasPanned\">...</div> Preventing Scroll (on touch capable devices)By default, the directive does not block page scrolling. If you want to prevent scrolling, then use the prevent modifier.<div v-touch-pan.prevent=\"userHasPanned\">...</div>"},{"title":"Uploader","updated":"2018-07-23T16:37:49.865Z","permalink":"https://v0-16.quasar-framework.org/components/uploader.html","text":"Quasar supplies a way for you to upload files through QUploader component. Works well with QField for additional functionality such as a helper, error message placeholder and many others. InstallationEdit /quasar.conf.js:framework: { components: ['QUploader']} Basic Usage<q-uploader :url=\"url\" /> Vue Properties Vue Property Type Description url String (Required) URL or path to the server which handles the upload name String Name of the file, if it should be different than the file’s name. headers Object Specify what headers need to be added to the XHR request url-factory Function Function (with file object received as parameter) which returns a Promise that resolves to a URL. method String HTTP method to use (POST/PUT). Defaults to POST. extensions String Extensions to allow for uploading. Example: '.gif,.jpg,.jpeg,.png' multiple Boolean Allow multiple file uploads hide-upload-button Boolean Hides the Upload button. You can then trigger it manually by calling upload() on the Vue ref hide-upload-progress Boolean Hides the upload progress. Useful when you want some other means of signaling upload progress to the user. additional-fields Array Additional fields to send along the upload request. Useful for authentication and so on. Array of Objects containing name and value props. no-thumbnails Boolean Don’t display thumbnails when files are images. auto-expand Boolean Auto-expand the list of files when some are added to the queue. expand-style String/Array/Object Style of the expanded file list container. expand-class String/Array/Object Classes of the expanded file list container. send-raw Boolean Don’t use multipart/form-data and send the file content inside the request body. If using this approach you will need to specify the correct Content-Type header. Defaults to false. readonly Boolean If set to true, Uploader is displayed as read-only. clearable Boolean If set to true, the component offers the user an actionable icon to remove the current selection. Common input frame properties: Property Type Description prefix String A text that should be shown before the textfield. suffix String A text that should be shown after the textfield. float-label String A text label that will “float” up above the input field, once the input field gets focus. stack-label String A text label that will be shown above the input field and is static. color String One from Quasar Color Palette. inverted Boolean Inverted mode. Color is applied to background instead. inverted-light Boolean Inverted mode with a light color. Color is applied to background instead. dark Boolean Is QUploader rendered on a dark background? hide-underline Boolean Hides the bottom border. align String One of ‘left’, ‘center’ or ‘right’ which determines the text align within textfield. disable Boolean If set to true, Uploader is disabled and the user cannot change anything. error Boolean If set to true, the input fields colors are changed to show there is an error. before Array of Objects Icon buttons on left side of input frame. Read below more details. after Array of Objects Icon buttons on right side of input frame. Read below more details. Icon buttonsThis section refers to before and after properties which can add additional buttons as icons to the textfield. Here is the structure of the two properties: { // required icon icon: String, // required function to call when // icon is clicked/tapped handler: Function, // Optional. Show icon button // if model has a value content: Boolean, // Optional. Show icon button // if textfield is marked with error error: Boolean} Examples:<!-- Show an icon button (with 'warning' as icon)--><q-uploader :url=\"url\" :after=\"[ { icon: 'warning', handler () { // do something... } } ]\"/> Vue Methods Vue Method Description upload() Start file(s) upload. abort() Abort uploading file(s). reset() Reset uploader state. Vue Events Vue Event Description @add(files) Triggered when file is picked for upload @remove:abort(file) Triggered when file is removed from upload queue while uploading. @remove:cancel(file) Triggered when file is removed from upload queue before uploading. @remove:done(file) Triggered when file is removed from upload list after it has been uploaded. @uploaded(file, xhr) Triggered individually for each file that has just been uploaded @fail(file, xhr) Triggered individually for each file that has encountered error while uploading @start Triggered when upload has started @finish Triggered when upload of file(s) has ended (with success or failure) ExamplesAWS S3 - Uploading Using Pre-Signed URLs<!-- x-amz-acl and content-type headers must match the ACL and ContentType specified when generating the signed url.--><q-uploader url=\"\" method=\"PUT\" :headers=\"{ 'x-amz-acl': <acl>, 'content-type': <file-type> }\" :url-factory=\"getSignedUrl\" :send-raw=\"true\"/> async getSignedUrl (file) { const contentType = file.type // To send the correct Content-Type const fileName = file.name // If you want to use this value to calculate the S3 Key. const response = await api.getSignedUrl({ fileName, contentType }) // Your api call to a sever that calculates the signed url. return response.data.url}"},{"title":"Video Embedding","updated":"2018-05-18T22:01:01.049Z","permalink":"https://v0-16.quasar-framework.org/components/video-embedding.html","text":"Embedding a video like Youtube is easy. It also resizes to fit the container by default. InstallationEdit /quasar.conf.js:framework: { components: ['QVideo']} Using QVideo<q-video src=\"https://www.youtube.com/embed/k3_tw44QsZQ?rel=0\" style=\"width: 853px; height: 480px\"/> Or, if you prefer the “raw” version for more control:<div class=\"q-video\"> <iframe width=\"853\" height=\"480\" src=\"https://www.youtube.com/embed/k3_tw44QsZQ?rel=0\" frameborder=\"0\" allowfullscreen ></iframe></div>"},{"title":"Quasar Typography","updated":"2018-05-18T22:01:01.048Z","permalink":"https://v0-16.quasar-framework.org/components/typography.html","text":"See how headings, blockquotes, definitions lists and more are displayed in the demo. At the end of this page you can read about CSS helper classes. Headings<h1>Light 112sp</h1><!-- or: --><div class=\"q-display-4\">Light 112sp</div><h2>Regular 56sp</h2><!-- or: --><div class=\"q-display-3\">Regular 56sp</div><h3>Regular 45sp</h3><!-- or: --><div class=\"q-display-2\">Regular 45sp</div><h4>Regular 34sp</h4><!-- or: --><div class=\"q-display-1\">Regular 34sp</div><h5>Regular 24sp</h5><!-- or: --><div class=\"q-headline\">Regular 24sp</div><h6>Medium 20sp</h6><!-- or: --><div class=\"q-title\">Medium 20sp</div><div class=\"q-subheading\">Regular 16sp</div><div class=\"q-body-2\">Medium 14sp</div><div class=\"q-body-1\">Regular 14sp</div><div class=\"q-caption\">Regular 12sp</div> Weights Class Name text-weight-thin text-weight-light text-weight-regular text-weight-medium text-weight-bold text-weight-bolder Text TypesYou can display text in a variety of ways. <!-- Small and Big text --><small>Text</small><big>Text</big><!-- sub and sup --><sub>Subtext</sub><sup>Supertext</sup><!-- Bold or italic --><p class=\"text-bold\">Bold text</p><!-- or: --><strong>Bold text</strong><p class=\"text-italic\">Italic text</p><!-- or: --><em>Italic text</em><!-- Quotes --><div class=\"quote\"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</div><div class=\"quote text-right\"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</div><!-- Blockquotes --><blockquote> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p> <small>Someone famous for <cite title=\"Quasar Framework\">Quasar Framework</cite></small></blockquote><blockquote class=\"text-right\"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p> <small>Someone famous for <cite title=\"Quasar Framework\">Quasar Framework</cite></small></blockquote><!-- Definition Lists --><dl> <dt>Description lists</dt> <dd>A description list is perfect for defining terms.</dd> <dt>Euismod</dt> <dd>Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.</dd></dl><dl class=\"horizontal\"> <dt>Description lists</dt> <dd>A description list is perfect for defining terms.</dd> <dt>Euismod</dt> <dd>Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.</dd></dl> CSS Helper Classes Class Name Description text-right Align text to the right text-left Align text to the left text-center Align text to the center text-justify Text will be justified text-truncate Applies all CSS tweaks to truncate text when container is too small text-bold Text will be in bold text-italic Text will be in italic text-no-wrap Non wrapable text (applies white-space: nowrap) uppercase Transform text to uppercase lowercase Transform text to lowercase capitalize Capitalize first letter of the text round-borders Every Quasar Theme has a generic border radius. This radius is applied to the DOM node block display property set to block no-margin Margins are set to 0 no-padding Padding is set to 0 no-outline Outline is set to 0 Default MD FontThe default font embedded in Quasar App when built with Material Design Theme is Roboto. But it is not required. You can use whatever font(s) you like. Roboto comes with 5 different font weights you can use: 100, 300, 400, 500, 700. Below is an image from Google’s Roboto Specimen document displaying the different font weights: This is where Roboto font comes embedded by default, if you are looking to remove it: // file: /quasar.conf.jsextras: [ ctx.theme.mat ? 'roboto-font' : null] Notice that the font is only included when developing/building with Material Theme."},{"title":"Swipe Touch/Mouse Action","updated":"2018-06-07T17:23:32.797Z","permalink":"https://v0-16.quasar-framework.org/components/touch-swipe.html","text":"Quasar offers full-featured Vue directives that can totally replace libraries like Hammerjs: v-touch-pan, v-touch-swipe and v-touch-hold. These directives also work with mouse events, not only touch events, so you are able to build cool functionality for your App on desktops too. We will be describing v-touch-swipe on the lines below. InstallationEdit /quasar.conf.js:framework: { directives: ['TouchSwipe']} Basic Usage<div v-touch-swipe=\"handler\">...</div>// \"handler\" is a Function which receives an Object as parameter Handler ParameterThe handler function/method is called by the directive when a swipe touch action took place on the DOM element and it receives the following parameter:{ evt, // JS Native Event direction, // \"left\", \"right\", \"up\" or \"down\" duration, // Number in ms distance // {x, y} Distance in pixels covered by swipe on horizontal and vertical}// example:handler (obj) { console.log(obj.direction) // \"right\" console.log(obj.duration) // 78 console.log(obj.distance.x) // 273} Modifiers Property Description horizontal Capture only horizontal swipe. vertical Capture only vertical swipe. up, right, down, left Capture swipe on the respective direction. noMouse Avoid capturing mouse events too. Use horizontal or vertical when you only want to capture horizontal or vertical swipes, or specify which directions are of interest:<div v-touch-swipe.horizontal=\"userHasSwiped\"> Capturing only horizontal swipes.</div><div v-touch-swipe.up.right=\"userHasSwiped\"> Capturing only swipes to \"up\" or \"right\".</div> Avoid Capturing Mouse EventsWhen you don’t want to capture mouse actions too, use the noMouse modifier:<!-- directive won't be triggered by mouse actions; it's exclusively triggered by touch actions now:--><div v-touch-swipe.noMouse=\"userHasSwiped\">...</div>"},{"title":"Tree","updated":"2018-05-18T22:01:01.048Z","permalink":"https://v0-16.quasar-framework.org/components/tree.html","text":"Quasar Tree represents a highly configurable component that displays hierarchical data, such as a table of contents in a tree structure. InstallationEdit /quasar.conf.js:framework: { components: ['QTree']} Basic UsageThis is the simplest Tree that you can write:<template> <q-tree :nodes=\"simple\" node-key=\"label\" /></template><script>export default { data: () => ({ simple: [ { label: 'Satisfied customers', children: [ { label: 'Good food', children: [ { label: 'Quality ingredients' }, { label: 'Good recipe' } ] }, { label: 'Good service (disabled node)', disabled: true, children: [ { label: 'Prompt attention' }, { label: 'Professional waiter' } ] }, { label: 'Pleasant surroundings', children: [ { label: 'Happy atmosphere' }, { label: 'Good table presentation' }, { label: 'Pleasing decor' } ] } ] } ] })}</script> Notice that nodes must have a unique key defined by a property of each key. In the example above, labels are unique so we’re using label prop to define these keys. However, you can add any property to the nodes (like ‘id’ or anything you want) and then use that property (like node-key="id"). Vue Properties Vue Property Type Description nodes Array Vue model for the Tree node-key String Property of node to use as unique key. color String Color of the connector lines. control-color String Color of checkboxes. text-color String Color of text. dark Boolean When rendering on a dark background. icon String Connector icon for each node. selected Any Use .sync. The unique key value of the selected node. tick-strategy String One of ‘leaf’, ‘leaf-filtered’, ‘strict’, ‘none’. ticked Array Use .sync. Node unique keys of ticked nodes. expanded Array Use .sync. Node unique keys of expanded nodes. default-expand-all Boolean Expan all nodes on first render. accordion Boolean Expanding a node closes its siblings. filter String String to be used when filtering nodes. filter-method Function Custom filtering method. no-nodes-label String Override default i18n of message when no nodes are available. no-results-label String Override default i18n of message when no nodes are available after filtering. Nodes model structureThe following describes a node’s properties that are taken into account by QTree’s v-model. Node Property Type Description label String Node’s label icon String Node’s icon img String Node’s image. Use statics folder. Example: ‘statics/mountains.png’ avatar String Node’s avatar. Use statics folder. Example: ‘statics/boy-avatar.png’ children Array Array of nodes as children. disabled Boolean Is node disabled? expandable Boolean Is node expandable? tickable Boolean When using a tick strategy, each node shows a checkbox. Should a node’s checkbox be disabled? noTick Boolean When using a tick strategy, should node display a checkbox? tickStrategy String Override global tick strategy for this node only. One of ‘leaf’, ‘leaf-filtered’, ‘strict’, ‘none’. lazy Boolean Should children be lazy loaded? In this case also don’t specify ‘children’ prop. header String Node header scoped slot name, without the required ‘header-‘ prefix. Example: ‘story’ refers to ‘header-story’ scoped slot. body String Node body scoped slot name, without the required ‘body-‘ prefix. Example: ‘story’ refers to ‘body-story’ scoped slot. Selection vs Ticking, Expansion Selection (through QTree selected prop) refers to the currently selected node (gets highlighted with different background). Ticking (through QTree ticked prop) refers to the checkbox associated with each node. Expansion (through QTree expanded prop) refers to the nodes that are expanded. All properties above require the .sync modifier in order for them to work correctly. Example:<!-- DO NOT forget about adding \".sync\" --><q-tree selected.sync=\"selection\" ... Tick StrategyThere are three ticking strategy: ‘leaf’, ‘leaf-filtered’, ‘strict’ with an additional (and default) ‘none’ which disables ticking. Strategy Description leaf Ticked nodes are only the leaves. Ticking a node influences the parent’s ticked state too (parent becomes partially ticked or ticked), as well as its children (all tickable children become ticked). leaf-filtered Same concept as leaf, only that this strategy applies only to filtered nodes (the nodes that remain visible after filtering). strict Ticked nodes are independent of parent or children tick state. You can apply a global tick strategy for a QTree and locally change the ticking strategy for a certain node by specifying the tickStrategy in the nodes model. Custom Filter MethodYou can customize the filtering method by specifying the filter-method prop. The method below is actually the default filtering strategy:<template> <q-tree :filter-method=\"myFilterMethod\" ...></template><script>export default { methods: { myFilterMethod (node, filter) { const filt = filter.toLowerCase() return node.label && node.label.toLowerCase().indexOf(filt) > -1 } }}</script> ExamplesNode icon/avatar/image, controlling expansion and colored<template> <div> <q-btn color=\"secondary\" @click=\"togglePropsGoodServiceExpand\" label=\"Toggle 'Good service' expansion\" /> <q-tree :nodes=\"props\" :expanded.sync=\"propsExpanded\" color=\"red\" node-key=\"label\" /> </div></template><script>export default { data: () => ({ propsExpanded: ['Satisfied customers', 'Pleasant surroundings'], props: [ { label: 'Satisfied customers', avatar: 'statics/boy-avatar.png', children: [ { label: 'Good food', icon: 'restaurant_menu', children: [ { label: 'Quality ingredients' }, { label: 'Good recipe' } ] }, { label: 'Good service', icon: 'room_service', children: [ { label: 'Prompt attention' }, { label: 'Professional waiter' } ] }, { label: 'Pleasant surroundings', icon: 'photo', children: [ { label: 'Happy atmosphere', img: 'statics/parallax1.jpg' }, { label: 'Good table presentation', img: 'statics/parallax2.jpg' }, { label: 'Pleasing decor', img: 'statics/mountains.jpg' } ] } ] } ] }), methods: { togglePropsGoodServiceExpand () { const index = this.propsExpanded.indexOf('Good service') if (index > -1) { this.propsExpanded.splice(index, 1) } else { this.propsExpanded.push('Good service') } } }}</script> Customizing nodes (header and body slots)<template> <q-tree :nodes=\"customize\" node-key=\"label\" default-expand-all > <div slot=\"header-root\" slot-scope=\"prop\" class=\"row items-center\"> <img src=\"~assets/quasar-logo.svg\" class=\"avatar q-mr-sm\"> <div> {{ prop.node.label }} <q-chip color=\"orange\" small>New!</q-chip> </div> </div> <div slot=\"header-generic\" slot-scope=\"prop\" class=\"row items-center\"> <q-icon :name=\"prop.node.icon || 'star'\" color=\"orange\" size=\"28px\" class=\"q-mr-sm\" /> <div class=\"text-weight-bold text-primary\">{{ prop.node.label }}</div> </div> <div slot=\"body-story\" slot-scope=\"prop\"> <span class=\"text-weight-thin\">The story is:</span> {{ prop.node.story }} </div> <div slot=\"body-toggle\" slot-scope=\"prop\"> <p class=\"caption\">{{ prop.node.caption }}</p> <q-toggle v-model=\"prop.node.enabled\" label=\"I agree to the terms and conditions\" /> </div> </q-tree></template><script>export default { data: () => ({ customize: [ { label: 'Satisfied customers', header: 'root', children: [ { label: 'Good food', icon: 'restaurant_menu', header: 'generic', children: [ { label: 'Quality ingredients', header: 'generic', body: 'story', story: 'Lorem ipsum dolor sit amet.' }, { label: 'Good recipe', body: 'story', story: 'A Congressman works with his equally conniving wife to exact revenge on the people who betrayed him.' } ] }, { label: 'Good service', header: 'generic', body: 'toggle', caption: 'Why are we as consumers so captivated by stories of great customer service? Perhaps it is because...', enabled: false, children: [ { label: 'Prompt attention' }, { label: 'Professional waiter' } ] }, { label: 'Pleasant surroundings', children: [ { label: 'Happy atmosphere' }, { label: 'Good table presentation', header: 'generic' }, { label: 'Pleasing decor' } ] } ] } ] })}</script> Applying a default header and body slot<template> <q-tree :nodes=\"customize\" node-key=\"label\" default-expand-all > <div slot=\"default-header\" slot-scope=\"prop\" class=\"row items-center\"> <q-icon :name=\"prop.node.icon || 'share'\" color=\"orange\" size=\"28px\" class=\"q-mr-sm\" /> <div class=\"text-weight-bold text-primary\">{{ prop.node.label }}</div> </div> <div slot=\"default-body\" slot-scope=\"prop\"> <div v-if=\"prop.node.story\"> <span class=\"text-weight-thin\">This node has a story</span>: {{ prop.node.story }} </div> <span v-else class=\"text-weight-thin\">This is some default content.</span> </div> </q-tree></template><script>export default { data: () => ({ customize: [ { label: 'Satisfied customers', header: 'root', children: [ { label: 'Good food', icon: 'restaurant_menu', header: 'generic', children: [ { label: 'Quality ingredients', header: 'generic', body: 'story', story: 'Lorem ipsum dolor sit amet.' }, { label: 'Good recipe', body: 'story', story: 'A Congressman works with his equally conniving wife to exact revenge on the people who betrayed him.' } ] }, { label: 'Good service', header: 'generic', body: 'toggle', caption: 'Why are we as consumers so captivated by stories of great customer service? Perhaps it is because...', enabled: false, children: [ { label: 'Prompt attention' }, { label: 'Professional waiter' } ] }, { label: 'Pleasant surroundings', children: [ { label: 'Happy atmosphere' }, { label: 'Good table presentation', header: 'generic' }, { label: 'Pleasing decor' } ] } ] } ] })}</script> Filtering nodes<template> <div> <q-input v-model=\"filter\" stack-label=\"Filter\" clearable class=\"q-mb-sm\" /> <q-tree :nodes=\"simple\" :filter=\"filter\" default-expand-all node-key=\"label\" /> </div></template><script>export default { data: () => ({ filter: '', simple: [ { label: 'Satisfied customers', children: [ { label: 'Good food', children: [ { label: 'Quality ingredients' }, { label: 'Good recipe' } ] }, { label: 'Good service (disabled node)', disabled: true, children: [ { label: 'Prompt attention' }, { label: 'Professional waiter' } ] }, { label: 'Pleasant surroundings', children: [ { label: 'Happy atmosphere' }, { label: 'Good table presentation' }, { label: 'Pleasing decor' } ] } ] } ] })}</script> Accordion mode (sibling nodes get contracted when one gets expanded)<q-tree :nodes=\"simple\" accordion node-key=\"label\"/> Selectable nodes<template> <div> <div class=\"q-mb-sm\"> <q-btn size=\"sm\" color=\"primary\" @click=\"selectGoodService\" label=\"Select 'Good service'\" /> <q-btn v-if=\"selected\" size=\"sm\" color=\"red\" @click=\"unselectNode\" label=\"Unselect node\" /> </div> <q-tree :nodes=\"props\" default-expand-all :selected.sync=\"selected\" node-key=\"label\" /> </div></template><script>export default { data: () => ({ selected: null, props: [ { label: 'Satisfied customers', avatar: 'statics/boy-avatar.png', children: [ { label: 'Good food', icon: 'restaurant_menu', children: [ { label: 'Quality ingredients' }, { label: 'Good recipe' } ] }, { label: 'Good service', icon: 'room_service', children: [ { label: 'Prompt attention' }, { label: 'Professional waiter' } ] }, { label: 'Pleasant surroundings', icon: 'photo', children: [ { label: 'Happy atmosphere', img: 'statics/parallax1.jpg' }, { label: 'Good table presentation', img: 'statics/parallax2.jpg' }, { label: 'Pleasing decor', img: 'statics/mountains.jpg' } ] } ] } ] }), methods: { selectGoodService () { if (this.selected !== 'Good service') { this.selected = 'Good service' } }, unselectNode () { this.selected = null }, }}</script> Tickable nodes & strategies<template> <div> <div class=\"q-mb-sm row no-wrap items-center\"> <q-select v-model=\"tickStrategy\" color=\"secondary\" stack-label=\"Tick Strategy\" :options=\"[ {label: 'None', value: 'none'}, {label: 'Leaf', value: 'leaf'}, {label: 'Leaf Filtered', value: 'leaf-filtered'}, {label: 'Strict', value: 'strict'} ]\" class=\"q-ma-none q-mr-sm\" style=\"width: 150px\" /> <q-input v-if=\"tickStrategy === 'leaf-filtered'\" color=\"secondary\" stack-label=\"Filter\" v-model=\"tickFilter\" class=\"q-ma-none\" clearable /> </div> <q-tree :nodes=\"tickable\" color=\"secondary\" default-expand-all :ticked.sync=\"ticked\" :tick-strategy=\"tickStrategy\" :filter=\"tickFilter\" node-key=\"label\" /> </div></template><script>export default { data: () => ({ ticked: [], tickStrategy: 'leaf', tickFilter: null, tickable: [ { label: 'Satisfied customers', avatar: 'statics/boy-avatar.png', children: [ { label: 'Good food', icon: 'restaurant_menu', children: [ { label: 'Quality ingredients' }, { label: 'Good recipe' } ] }, { label: 'Good service', icon: 'room_service', children: [ { label: 'Prompt attention' }, { label: 'Professional waiter' } ] }, { label: 'Pleasant surroundings', icon: 'photo', children: [ { label: 'Happy atmosphere (not tickable)', tickable: false, img: 'statics/parallax1.jpg' }, { label: 'Good table presentation (disabled node)', disabled: true, img: 'statics/parallax2.jpg' }, { label: 'Pleasing decor', img: 'statics/mountains.jpg' } ] }, { label: 'Extra information (has no tick)', noTick: true, icon: 'photo' }, { label: 'Forced tick strategy (to \"strict\" in this case)', tickStrategy: 'strict', icon: 'school', children: [ { label: 'Happy atmosphere', img: 'statics/parallax1.jpg' }, { label: 'Good table presentation', img: 'statics/parallax2.jpg' }, { label: 'Very pleasing decor', img: 'statics/mountains.jpg' } ] } ] } ] })}</script> Lazy loading nodes<template> <q-tree :nodes=\"lazy\" default-expand-all node-key=\"label\" @lazy-load=\"onLazyLoad\" /></template><script>export default { data: () => ({ lazy: [ { label: 'Node 1', children: [ { label: 'Node 1.1', lazy: true }, { label: 'Node 1.2', lazy: true } ] }, { label: 'Node 2', lazy: true }, { label: 'Lazy load empty', lazy: true }, { label: 'Node is not expandable', expandable: false, children: [ { label: 'Some node' } ] } ] }), methods: { onLazyLoad ({ node, key, done, fail }) { // call fail() if any error occurs setTimeout(() => { // simulate loading and setting an empty node if (key.indexOf('Lazy load empty') > -1) { done([]) return } const label = node.label done([ { label: `${label}.1` }, { label: `${label}.2`, lazy: true }, { label: `${label}.3`, children: [ { label: `${label}.3.1`, lazy: true }, { label: `${label}.3.2`, lazy: true } ] } ]) }, 1000) } }}</script>"},{"title":"Window Resize Observable","updated":"2018-07-23T16:37:49.866Z","permalink":"https://v0-16.quasar-framework.org/components/window-resize-observable.html","text":"QWindowResizeObservable is a Quasar component that emits a resize event whenever the document viewport (window) changes its size, with no polling involved. InstallationEdit /quasar.conf.js:framework: { components: [ 'QWindowResizeObservable' ]} Basic Usage<template> ... <!--can be placed anywhere within your template --> <q-window-resize-observable @resize=\"onResize\" /> ...</template><script>export default { ..., methods: { ..., onResize (size) { console.log(size) // { // width: 1200 // width of viewport (in px) // height: 920 // height of viewport (in px) // } } }}</script> Please note that QWindowResizeObservable will issue an event as soon as it gets rendered and attached to DOM, so you can have the initial size of the window."},{"title":"CSS Visibility","updated":"2018-05-18T22:01:01.049Z","permalink":"https://v0-16.quasar-framework.org/components/visibility.html","text":"There are some CSS classes that you can use out of the box for common functionality. Class Name Description disabled Cursor is changed to notify a ‘disable’ and opacity is set to a lower value. hidden Set display to none. Compare with below - the class hidden means the element will not show and will not take up space in the layout. invisible Set visibility to hidden. Compare with above - the class invisible means the element will not show, but it will still take up space in the layout. transparent Background color is transparent. dimmed Apply dark transparent overlay on top of your element. Do not use on elements which already have :after pseudoelement. light-dimmed Apply white transparent overlay on top of your element. Do not use on elements which already have :after pseudoelement. highlight-and-fade Adds a yellow background color and fades it away upon element is displayed. ellipsis Truncates text and shows ellipsis when not enough space available. ellipsis-2-lines Truncates text and shows ellipsis when not enough space available on two lines (works only on Webkit browsers). ellipsis-3-lines Truncates text and shows ellipsis when not enough space available on three lines (works only on Webkit browsers). z-top Positions your element on top of any other component, but behind Popovers, Tooltips, Notifications. z-max Positions your element on top of any other component (including Drawer, Modals, Notifications, Layout header/footer, …) Window Width RelatedFirst of all, let’s define what does a small, medium, big or large window means: Window Size Prefix Width threshold in pixels Extra Small xs Up to 576px Small sm Up to 768px Medium md Up to 992px Large lg Up to 1200px Extra Large xl Bigger than 1200px Now on to the window width related CSS classes. Class Name Description xs Display only on extra small windows sm Display only on small windows md Display only on medium-sized windows lg Display only on large windows xl Display only on extra large windows You can also show some DOM element or component if it’s lower than one of the sizes. Same for greater than one of the sizes. Just attach lt- or gt- prefixes, which come from “lower than” and “greater than”. Example: lt-md (display on xs and sm only), lt-xl (display on xs, sm, md and lg windows only), gt-md (display on greater than medium windows: lg and xl). NOTEYou can combine the visibility classes with the inline class for inline-blocks.Example : <span class="gt-sm inline">&nbsp;and here is the end of this long sentence.</span> Platform RelatedVisible only on: Class Name Description desktop-only Visible only on desktop mobile-only Visible only on mobile cordova-only Visible only on Cordova wrapped Apps electron-only Visible only on Electron wrapped Apps touch-only Visible only on touch capable platforms mat-only Visible only for Material Quasar Theme ios-only Visible only for iOS Quasar Theme platform-ios-only Visible only on an iOS platform platform-android-only Visible only on an Android platform within-iframe-only Visible only when entire website is under an IFRAME tag Hide on: Class Name Description desktop-hide Hide on desktop mobile-hide Hide on mobile cordova-hide Hide on Cordova wrapped Apps electron-hide Hide on Electron wrapped Apps touch-hide Hide on touch capable platforms mat-hide Hide for Material Quasar Theme ios-hide Hide for iOS Quasar Theme platform-ios-hide Hide on iOS platform platform-android-hide Hide on Android platform within-iframe-hide Hide only when entire website is under an IFRAME tag Also check Quasar Theming > Platform Specific Styles. NOTEBased on your needs, you might want to also check Javascript > Environment page to see how you can achieve the same effect using Javascript. This latter method allows you to not even render a DOM element or component. It is useful when the rendering process is expensive. Orientation Related Class Name Description orientation-portrait Visible only when screen orientation is Portrait orientation-landscape Visible only when screen orientation is Landscape Printing Related Class Name Description print-only Visible only on print media - hidden on screen media print-hide Visible on screen media - hidden on print media"},{"title":"Vue Prototype Injections","updated":"2018-05-18T22:01:01.050Z","permalink":"https://v0-16.quasar-framework.org/components/vue-prototype-injections.html","text":"Quasar injects Vue prototype with $q object: Injection Type Description $q.version String Quasar version. $q.theme String Theme being used. Examples: mat, ios $q.platform Object Same object as Platform import from Quasar. $q.i18n Object Internationalisation for Quasar, containing labels etc (one of i18n files). Designed for Quasar components, but you can use in your app components too. $q.cordova Object Reference to Cordova global object. Available only when running under a Cordova app. $q.electron Object Reference to Electron global object. Available only when running under an Electron app. You can use it globally inside a Vue context (component script or template) like this: <!-- inside a Vue template --><template> <div> <div v-if=\"$q.platform.is.ios\"> Gets rendered only on iOS platform. </div> </div></template><script>// not available here outside// of the exportexport default { // inside a Vue component script ..., // showing an example on a method, but // can be any part of Vue script methods: { show () { // prints out Quasar version console.log(this.$q.version) } }}</script>"},{"title":"Quasar Web Storage","updated":"2018-05-18T22:01:01.050Z","permalink":"https://v0-16.quasar-framework.org/components/web-storage.html","text":"Quasar provides a wrapper over Web Storage API. NOTEWeb Storage API only retrieves strings. Quasar retrieves data with its original data type. You tell it to store a Number then to retrieve it and it will still be a Number, not a string representation of the number as with Web Storage API. Same for JSON, Regular Expressions, Dates, Booleans and so on. Read below. InstallationEdit /quasar.conf.js:framework: { plugins: [ 'LocalStorage', 'SessionStorage' ]} Getting StartedQuasar supports both Local and Session Storage. // outside of a Vue fileimport { LocalStorage, SessionStorage } from 'quasar'LocalStorage.set(key, value)let value = LocalStorage.get.item(key)SessionStorage.set(key, value)let value = SessionStorage.get.item(key) // inside of a Vue filethis.$q.localStorage.set(key, value)let value = this.$q.localStorage.get.item(key)this.$q.sessionStorage.set(key, value)let value = this.$q.sessionStorage.get.item(key) Before we jump to discuss on the API, let’s see what data types are supported out of the box. Data TypesQuasar Storage supports (but not limited to) the following data types out of the box. If you store one of these types, the retrieved data will have the same data type. Dates Regular Expressions Numbers Booleans Strings Plain Javascript Objects If you store any other data type, the returned value will be a String. So you can even store functions, but be careful that you need to eval() the returned value (which is a String representation of the function). MethodsStoring Data// outside of a Vue fileimport { LocalStorage, SessionStorage } from 'quasar'LocalStorage.set(key, value)SessionStorage.set(key, value) // inside of a Vue filethis.$q.localStorage.set(key, value)this.$q.sessionStorage.set(key, value) Retrieving DataOne item:// outside of a Vue fileimport { LocalStorage, SessionStorage } from 'quasar'let item = LocalStorage.get.item(key)let item = SessionStorage.get.item(key)// inside of a Vue filelet item = this.$q.localStorage.get.item(key)let item = this.$q.sessionStorage.get.item(key) All items:// outside of a Vue fileimport { LocalStorage, SessionStorage } from 'quasar'let item = LocalStorage.get.all()let item = SessionStorage.get.all()// inside of a Vue filelet item = this.$q.localStorage.get.all()let item = this.$q.sessionStorage.get.all() Iterating through StoreGetting length of store:// outside of a Vue fileimport { LocalStorage, SessionStorage } from 'quasar'let length = LocalStorage.get.length()let length = SessionStorage.get.length()// inside of a Vue filelet length = this.$q.localStorage.get.length()let length = this.$q.sessionStorage.get.length() Getting item at index:// outside of a Vue fileimport { LocalStorage, SessionStorage } from 'quasar'let item = LocalStorage.get.index(index)let item = SessionStorage.get.index(index)// inside of a Vue filelet item = this.$q.localStorage.get.index(index)let item = this.$q.sessionStorage.get.index(index) Now you know how to loop through the store. Removing DataOne item:// outside of a Vue fileimport { LocalStorage, SessionStorage } from 'quasar'LocalStorage.remove(key)SessionStorage.remove(key)// inside of a Vue filethis.$q.localStorage.remove(key)this.$q.sessionStorage.remove(key) All items (clear the store):// outside of a Vue fileimport { LocalStorage, SessionStorage } from 'quasar'LocalStorage.clear()SessionStorage.clear()// inside of a Vue filethis.$q.localStorage.clear()this.$q.sessionStorage.clear() Is Store Empty?// outside of a Vue fileimport { LocalStorage, SessionStorage } from 'quasar'(boolean) LocalStorage.isEmpty()(boolean) SessionStorage.isEmpty()// inside of a Vue file(boolean) this.$q.localStorage.isEmpty()(boolean) this.$q.sessionStorage.isEmpty() Is Key in Store?// outside of a Vue fileimport { LocalStorage, SessionStorage } from 'quasar'(boolean) LocalStorage.has(key)(boolean) SessionStorage.has(key)// inside of a Vue file(boolean) this.$q.localStorage.has(key)(boolean) this.$q.sessionStorage.has(key)"},{"title":"Build Commands","updated":"2018-07-23T16:37:49.866Z","permalink":"https://v0-16.quasar-framework.org/guide/app-build-commands.html","text":"We will be covering Development and Production build commands. For a full list of Quasar CLI commands, make sure to read its documentation page. Development Starts a Node.js local development server. # run development server (with default theme)$ quasar dev# run development server with specific theme$ quasar dev -t mat$ quasar dev -t ios# on specific port$ quasar dev -p 9090# PWA$ quasar dev -m pwa# Mobile App$ quasar dev -m cordova -T [android|ios] -t [mat|ios]# Electron App$ quasar dev -m electron# with iOS theme...$ quasar dev -m electron -t ios For a complete list, please read Quasar CLI Development Server section. While developing with the Dev Server you will have: Babel, so you can write ES6 code Webpack + vue-loader for Vue SFC (single file components) State preserving hot-reload State preserving compilation error overlay Lint-on-save with ESLint Source maps Develop right on a device emulator (or a real phone connected to your machine) if you target a Mobile App Develop right on an Electron window with Developer Tools included if you target an Electron App Production Build assets for production. # build for production$ quasar build# build for production with specific theme$ quasar build -t mat$ quasar build -t ios# PWA$ quasar build -m pwa# Mobile App$ quasar build -m cordova -T [android|ios] -t [mat|ios]# Electron App$ quasar build -m electron# with iOS theme...$ quasar build -m electron -t ios For a complete list, please read Quasar CLI Build App for Production section. In addition to what you get while developing your website/app, for production builds you also take advantage of: Javascript minified with UglifyJS HTML minified with html-minifier CSS across all components extracted (and auto-prefixed) into a single file and minified with cssnano All static assets are compiled with version hashes for efficient long-term caching, and a production index.html is auto-generated with proper URLs to these generated assets."},{"title":"Adding Pages and Layouts","updated":"2018-05-18T22:01:01.051Z","permalink":"https://v0-16.quasar-framework.org/guide/app-adding-pages-and-layouts.html","text":"Your Pages (/src/pages) and Layouts (/src/layouts) are injected into your website/app (and also managed) through Vue Router in /src/router/routes.js. Each Page and Layout needs to be referenced there. You may want to read Routing first and also understand Lazy Loading / Code Splitting. Example of routes.js:// we define our routes in this fileimport LandingPage from 'pages/Landing'const routes = [ { path: '/', component: LandingPage }]export default routes Example of routes.js using lazy-loading / on-demand loading:// we define our routes in this fileconst routes = [ { path: '/', component: () => import('pages/Landing') }]export default routes Configuring routes to use Layouts and Pages basically consists of correctly nesting routes, as we’ll see in the next section. Nested RoutesReal app UIs are usually composed of components that are nested multiple levels deep. It is also very common that the segments of a URL corresponds to a certain structure of nested components, for example: /user/profile /user/posts+------------------+ +-----------------+| User | | User || +--------------+ | | +-------------+ || | Profile | | +------> | | Posts | || | | | | | | || +--------------+ | | +-------------+ |+------------------+ +-----------------+ With Vue Router, it is very simple to express this relationship using nested route configurations. We notice some things: both pages need to be wrapped by a User component. Hey, User component is then a Layout! Let’s create these files:$ quasar new layout User app:new Generated layout: src/layouts/User.vue +0ms app:new Make sure to reference it in src/router/routes.js +2ms$ quasar new page Profile Posts app:new Generated page: src/pages/Profile.vue +0ms app:new Make sure to reference it in src/router/routes.js +2ms app:new Generated page: src/pages/Posts.vue +1ms app:new Make sure to reference it in src/router/routes.js +0ms Since User layout wraps inner pages, they need an injection point. This is supplied by the <router-view> component:<!-- /src/layouts/User.vue --><template> <q-layout> ... <!-- this is where the Pages are injected --> <q-page-container> <router-view></router-view> </q-page-container> ... </q-layout></template> <!-- /src/pages/Profile.vue or Posts.vue --><template> <q-page> ...page content... </q-page></template>` Our example has some routes specified (/user/profile and /user/posts). So how can we put everything together now? We edit the routes file. That’s where we will configure routes, tell which components are Layouts and which are Pages and also reference/import them into our app: // src/router/routes.jsimport User from 'layouts/User'import Profile from 'pages/Profile'import Posts from 'pages/Posts'const routes = [ { path: '/user', // we use /src/layouts/User component which is imported above component: User, // hey, it has children routes and User has <router-view> in it; // It is really a Layout then! children: [ // Profile page { path: 'profile', // here it is, route /user/profile component: Profile // we reference /src/pages/Profile.vue imported above }, // Posts page { path: 'posts', // here it is, route /user/posts component: Posts // we reference /src/pages/Posts.vue imported above } ] }]export default routes Note that nested paths that start with / will be treated as a root path. This allows you to leverage component nesting without having to use a nested URL. For further in-detail reading please take a look on Vue Router documentation."},{"title":"Ajax Requests","updated":"2018-05-18T22:01:01.051Z","permalink":"https://v0-16.quasar-framework.org/guide/ajax-requests.html","text":"Quasar recommends Axios during project initialization: Use Axios for Ajax calls? (Y/n) Then you should create a new plugin axios.js that looks like this:(Here you can also specify additional settings for your axios instance)import axios from 'axios'export default ({app, router, Vue}) => { Vue.prototype.$axios = axios // ^ ^ ^ this will allow you to use this.$axios // so you won't necessarily have to import axios in each vue file} Usage in your single file components methods will be like:methods: { loadData () { this.$axios.get('/api/backend') .then((response) => { this.data = response.data }) .catch(() => { this.$q.notify({ color: 'negative', position: 'top', message: 'Loading failed', icon: 'report_problem' }) }) }, Usage in Vuex Actions for globally adding headers to axios (such as during authentication):import axios from 'axios'export function register ({commit}, form) { return axios.post('api/auth/register', form) .then(response => { commit('login', {token: response.data.token, user: response.data.user}) setAxiosHeaders(response.data.token) })}function setAxiosHeaders (token) { axios.defaults.headers.common['Authorization'] = 'Bearer ' + token} Also look at Axios docs for more information."},{"title":"Directory Structure","updated":"2018-07-23T16:37:49.866Z","permalink":"https://v0-16.quasar-framework.org/guide/app-directory-structure.html","text":"This is the structure of a project with all modes installed. There’s no reason to be intimidated though! If you are a beginner, all you’ll need to care about is /quasar.conf.js (Quasar App Config file), /src/router, /src/layouts, /src/pages and optionally /src/assets..├── src/│ ├── assets/ # dynamic assets (processed by webpack)│ ├── statics/ # pure static assets (directly copied)│ ├── components/ # .vue components used in pages & layouts│ ├── css/ # CSS/Stylus/Sass/... files for your app| | ├── app.styl| │ └── themes/ # Quasar themes entry points for you to tweak| │ ├── common.variables.styl # Common Stylus variables for all Quasar themes| │ ├── variables.mat.styl # Variables for Material Design theme| │ └── variables.ios.styl # Variables for iOS theme│ ├── layouts/ # layout .vue files│ ├── pages/ # page .vue files│ ├── plugins/ # app plugins (app initialization code)│ ├── router/ # Vue Router| | ├── index.js # Vue Router definition| │ └── routes.js # App Routes definitions│ ├── store/ # Vuex Store| | ├── index.js # Vuex Store definition| │ ├── <folder> # Vuex Store Module...| │ └── <folder> # Vuex Store Module...│ ├── App.vue # root Vue component of your App│ └── index.template.html # Template for index.html├── src-pwa/ # PWA specific code (like Service Worker)├── src-cordova/ # Cordova generated folder used to create Mobile Apps├── src-electron/ # Electron specific code (like \"main\" thread)├── dist/ # where production builds go│ ├── spa-mat/ # example when building SPA with MAT theme│ ├── spa-ios/ # example when building SPA with IOS theme│ ├── electron-mat/ # example when building Electron with MAT theme│ └── ....├── quasar.conf.js # Quasar App Config file├── .babelrc # babel config├── .editorconfig # editor config├── .eslintignore # ESlint ignore paths├── .eslintrc.js # ESlint config├── .postcssrc.js # PostCSS config├── .stylintrc # Stylus lint config├── .gitignore # GIT ignore paths├── package.json # npm scripts and dependencies└── README.md # readme for your website/App"},{"title":"Main Starter Kit Installation","updated":"2018-07-23T16:37:49.867Z","permalink":"https://v0-16.quasar-framework.org/guide/app-installation.html","text":"Using the Main Starter Kit is the recommended way to go in order to benefit from all Quasar can do for it. You’ll be able to build: a SPA (Single Page Application/Website), a PWA (Progressive Web App), a Mobile App (through Cordova), an Electron App,…sharing the same base-code. First, we install Quasar CLI. Make sure you have Node >=8 and NPM >=5 installed on your machine. # Node.js >= 8.9.0 is required.$ yarn global add quasar-cli# or:$ npm install -g quasar-cli Then we create a project folder with Quasar CLI:$ quasar init <folder_name> Note that you don’t need separate starter kits if you want to build any of the options described above. This one can seamlessly handle all of them. Make sure you familiarize yourself with the Quasar CLI because you will be using it a lot. What’s IncludedWhile developing with Dev Server ($ quasar dev): Babel, so you can write ES6 code Webpack + vue-loader for Vue SFC (single file components) State preserving hot-reload State preserving compilation error overlay Lint-on-save with ESLint Source maps Develop right on a device emulator (or a real phone connected to your machine) if you target a Mobile App Develop right on an Electron window with Developer Tools included if you target an Electron App Developing for production ($ quasar build): Javascript minified with UglifyJS HTML minified with html-minifier CSS across all components extracted (and auto-prefixed) into a single file and minified with cssnano All static assets are compiled with version hashes for efficient long-term caching, and a production index.html is auto-generated with proper URLs to these generated assets. Take note of the ‘/quasar.conf.js’ file in the root of your project folder. This file helps you quickly configure the way your website/App works. We’ll go over it in the Configuration section."},{"title":"Deployment of SPA","updated":"2018-05-20T16:04:39.318Z","permalink":"https://v0-16.quasar-framework.org/guide/app-deploying-spa.html","text":"There exist many services that allow deploying applications with ease.To list all of them would not be possible so we will focus on the general deployment process and some specifics for common services. If your favorite deployment tool is missing feel free to create a pull request on GitHub to add it to the list. General deploymentThe first step in deploying you Quasar SPA is always to build a production-ready bundle of your files, which gets rid of development statements and minifies your source. To produce such a build use Quasar CLI with the following command$ quasar build For possible build options please refer to the Quasar CLI docs. This command will build your project in SPA mode and output your production ready bundle to a newly created folder /dist/spa-<theme> were <theme> is replaced by the theme you chose to build with. To serve your production files it is required to use a web server, so to serve over http:// protocol. Simply opening the index.html file from within your browser will not work, since this uses the file:// protocol instead. Common choices for web servers are nginx, Caddy, Apache, Express; but you should be able to use whatever web server you want. The web server requires no special setup (unless you built with Vue Router in “history” mode). The main requirement is to be able to serve static files from a directory, so consult the documentation of your web server on how to set up static file serving. An example config for nginx may look like this:server { listen 80 http2; server_name quasar.myapp.com; root /home/user/quasar.myapp.com/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; index index.html; charset utf-8; location / { try_files $uri $uri/ /index.html; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } access_log off; error_log /var/log/nginx/quasar.myapp.com-error.log error; location ~ /\\.(?!well-known).* { deny all; }} Deploying with NowDeploying your Quasar application with now is really easy. All you have to do is to download the now-cli and log in by running:$ now login Then proceed to build your Quasar application using the steps described in General deployment. After the build is finished, change directory into your deploy root (example: /dist/spa-mat) and run:$ now The Now CLI should now display information regarding your deployment, like the URL. That’s it. You’re done. Deploying with HerokuUnfortunately, Heroku does not support static sites out of the box. But don’t worry, we just need to add an HTTP server to our project so Heroku can serve our Quasar application. In this example, we will use Express to create a minimal server which Heroku can use. First, we need to install the required dependencies to our project:$ npm install express serve-static connect-history-api-fallback Now that we have installed the required dependencies, we can add our server. Create a file called server.js in the root directory of your project.const express = require('express'), serveStatic = require('serve-static'), history = require('connect-history-api-fallback'), port = process.env.PORT || 5000const app = express()app.use(history())app.use(serveStatic(__dirname + '/dist/spa-<theme>'))app.listen(port) Make sure to exchange <theme> to the theme you use. Heroku assumes a set of npm scripts to be available, so we have to alter our package.json and add the following under the script section:\"build\": \"quasar build\",\"start\": \"node server.js\",\"heroku-postbuild\": \"npm install --only=dev --no-shrinkwrap && npm run build\" Now it is time to create an app on Heroku by running:$ heroku create and deploy to Heroku using:$ heroku deploy Deploying with SurgeSurge is a popular tool to host and deploy static sites. If you want to deploy your application with Surge you first need to install the Surge CLI tool:$ npm install -g surge Next, we will use Quasar CLI to build our app:$ quasar build Now we can deploy our application using Surge by calling:# make sure to replace <theme> with your actual theme$ surge dist/spa-<theme> Now your application should be successfully deployed using Surge. You should be able to adapt this guide to any other static site deployment tool. Deploying on GitHub PagesTo deploy your Quasar application to GitHub pages the first step is to create a special repository on GitHub which is named <username>.github.io. Clone this repository to your local machine. Next, you need to build your Quasar application like it is described in the general deployment section. This will result in a spa-<theme> directory inside the dist directory. Copy the content of this folder to your cloned repository. The last step is to add a commit in your repository an push to GitHub. After a short time, you should be able to visit your Quasar application at https://.github.io/. Adding a custom domain to GitHub pagesPlease see the GitHub pages guides for an in-depth explanation on how to set up a custom domain. Automated deployment to GitHub pages with push-dirManual copying all your files to your GitHub Pages repository can be a cumbersome task to do. This step can be automated by using the push-dir package. First, install the package with:$ npm install push-dir --save-dev Then add a deploy script command to your package.json:// replace <theme> with your actual theme (mat, ios)\"scripts\": { \"deploy\": \"push-dir --dir=dist/spa-<theme> --remote=gh-pages --branch=master\"} Add your GitHub Pages repository as a remote named gh-pages:$ git remote add gh-pages [email protected]:<username>/<username>.github.io.git Now you can build and deploy your application using:$ quasar build$ npm run deploy which will push the content of your build directory to your master branch on your Github Pages repository."},{"title":"API Proxying for Dev","updated":"2018-05-18T22:01:01.052Z","permalink":"https://v0-16.quasar-framework.org/guide/app-api-proxying.html","text":"When integrating a project folder with Quasar CLI and the Main Starter Kit with an existing backend, a common need is to access the backend API when using the dev server. To achieve this, we can run the dev server and the API backend side-by-side (or remotely), and let the dev server proxy all API requests to the actual backend. This is useful if you access relative paths in your API requests. Obviously, these relative paths will probably not work while you are developing. In order to create an environment similar to the one used by your deployed website/app, you can proxy your API requests. To configure the proxy rules, edit /quasar.conf.js in devServer.proxy. You should refer to Webpack Dev Server Proxy docs for detailed usage. But here’s a simple example: // quasar.conf.jsdevServer: { proxy: { // proxy all requests starting with /api to jsonplaceholder '/api': { target: 'http://some.api.target.com:7070', changeOrigin: true, pathRewrite: { '^/api': '' } } }} The above example will proxy the request /api/posts/1 to http://some.api.target.com:7070/posts/1."},{"title":"App Plugins","updated":"2018-07-23T16:37:49.867Z","permalink":"https://v0-16.quasar-framework.org/guide/app-plugins.html","text":"A common use case for Quasar applications is to run code before the root Vue instance is instantiated.Quasar provides an elegant solution to that problem by allowing users to define so-called app plugins. IMPORTANTDo not confuse app plugins with Quasar plugins, like ActionSheet, Dialog, Notify. Quasar plugins are something else entirely and will be covered in the Components section. In earlier Quasar versions, to run code before the root Vue instance was instantiated, you could alter the /src/main.js file and add any code you needed to execute. There is a major problem with this approach: With a growing project, your main.js file was very likely to get cluttered and challenging to maintain, which breaks with Quasar’s concept of encouraging developers to write maintainable and elegant cross-platform applications. With app plugins, it is possible to split each of your dependencies into a self-contained, easy to maintain file. It is also trivial to disable any of the app plugins or even contextually determine which of the app plugins get into the build through quasar.conf.js configuration. Anatomy of an app pluginAn app plugin is a simple JavaScript file which needs to export a function. Quasar will then call the exported function when it boots the application and additionally pass an object with the following properties to the function: Prop name Description app Object with which the root component gets instantiated by Vue router Instance of Vue Router from ‘src/router/index.js’ store Instance of Vuex from ‘src/store/index.js’ - store only will be passed if your project uses Vuex (you have src/store) Vue Is same as if we do import Vue from 'vue' and it’s there for convenience export default ({ app, router, store, Vue }) => { // something to do} Notice we are using the ES6 destructuring assignment. Only assign what you actually need/use. When to use app plugins IMPORTANTPlease make sure you understand what problem app plugins solve and when it is appropriate to use them, to avoid applying them in cases where they are not needed. App plugins fulfill one special purpose: they run code before the App’s Vue root component is instantiated while giving you access to certain variables, which is required if you need to initialize a library, interfere with Vue Router, inject Vue prototype or inject the root instance of the Vue app. Examples of appropriate usage of app plugins Your Vue plugin has installation instructions, like needing to call Vue.use() on it. Your Vue plugin requires instantiation of data that is added to the root instance - An example would be vue-i18n. You want to add something to the Vue prototype for convenient access - An example would be to conveniently use this.$axios inside your Vue files instead of importing Axios in each such file. You want to interfere with the router - An example would be to use router.beforeEach for authentication You want to interfere with the Vuex store instance - An example would be to use vuex-router-sync package Configure aspects of libraries - An example would be to create an instance of Axios with a base URL; you can then inject it into Vue prototype and/or export it (so you can import the instance from anywhere else in your app) Examples of unneeded usage of app plugins For plain JavaScript libraries like Lodash, which don’t need any initialization prior to their usage. Lodash, for example, might make sense to use as an app plugin only if you want to inject Vue prototype with it, like being able to use this.$_ inside your Vue files. Make API requests - You probably want to do this inside your pages Vue component Usage of app pluginsThe first step is always to generate a new plugin using Quasar CLI: $ quasar new plugin <name> Where <name> should be exchanged by a suitable name for your plugin. This command creates a new file: /src/plugins/<name>.js with the following content: // import something here// leave the export, even if you don't use itexport default ({ app, router, store, Vue }) => { // something to do} You can now add content to that file depending on the intended use of your plugin. Do not forget that your default export needs to be a function.However, you can have as many named exports as you want, should the plugin expose something for later usage. In this case, you can import any of these named exports anywhere in your app. The last step is to tell Quasar to use your new plugin. For this to happen you need to add the plugin in /quasar.conf.js plugins: [ '<name>' // references /src/plugins/<name>.js] Quasar App FlowIn order to better understand how and what a plugin does, you need to understand how your website/app is booted up: Quasar gets initialized (components, directives, plugins, Quasar i18n, Quasar icon sets) Quasar Extras get imported (Roboto font – if used, icons, animations, …) Quasar CSS & your app’s global CSS is imported App.vue is loaded up (not yet being used) Store is imported (if using Vuex Store in src/store) App plugins are imported App plugins get their default export function executed, except for App Boot plugin (if on Electron mode) Electron is imported and injected into Vue prototype (if on Cordova mode) Listening for “deviceready” event and only then continuing with following steps (if App Boot plugin exists) Executing App Boot plugin (if no App Boot plugin exists) Instantiating Vue with root component and attaching to DOM Examples of app pluginsAxiosimport axios from 'axios'export default ({ Vue }) => { // we add it to Vue prototype // so we can reference it in Vue files // without the need to import axios Vue.prototype.$axios = axios // Example: this.$axios will reference Axios now so you don't need stuff like vue-axios} vue-i18n// we import the external packageimport VueI18n from 'vue-i18n'// let's say we have a file in /src/i18n containing the language packimport messages from 'src/i18n'export default ({ app, Vue }) => { // we tell Vue to use our Vue package: Vue.use(VueI18n) // Set i18n instance on app; // We inject it into root component by doing so; // new Vue({..., i18n: ... }).$mount(...) app.i18n = new VueI18n({ locale: 'en', fallbackLocale: 'en', messages })} Router authenticationSome plugins might need to interfere with Vue Router configuration:export default ({ router, store, Vue }) => { router.beforeEach((to, from, next) => { // Now you need to add your authentication logic here, like calling an API endpoint })} Accessing data from pluginsSometimes you want to access data that you configure in your app plugin in files where you don’t have access to the root Vue instance. Fortunately, because app plugins are just normal JavaScript files you can add as many named exports to your app plugin as you want. Let’s take the example of Axios. Sometimes you want to access your Axios instance inside your JavaScript files, but you can not access the root Vue instance. To solve this you can export the Axios instance in your plugin and import it elsewhere. Consider the following plugin file for axios: // axios app plugin file (src/plugins/axios.js)import axios from 'axios'// We create our own axios instance and set a custom base URL.// Note that if we wouldn't set any config here we do not need// a named export, as we could just `import axios from 'axios'`const axiosInstance = axios.create({ baseURL: 'https://api.example.com'})export default ({ Vue }) => { // for use inside Vue files through this.$axios Vue.prototype.$axios = axiosInstance}// Here we define a named export// that we can later use inside .js files:export { axiosInstance } In any JavaScript file, you’ll be able to import the axios instance like this. // we import one of the named exports from src/plugins/axios.jsimport { axiosInstance } from 'plugins/axios' Further reading on syntax: ES6 import, ES6 export. Special App Plugin: BootEvery Quasar website/app is booted up after plugins have been loaded and executed. The last step is to call new Vue() and attach it to the DOM. If, for whatever reason, you need to control this final step and decide the specific moment when Vue kicks in, you can create a special Quasar plugin named “boot” (requires Quasar v0.15.6+). Remember to only use this plugin for eventually calling new Vue(app). Don’t use this for initializing any library you may have – for that, use a regular app plugin. # we create the boot plugin$ quasar new plugin boot app:new Generated plugin: src/plugins/boot.js +0ms app:new Make sure to reference it in quasar.conf.js > plugins +2ms We then add this plugin to app plugins list in /quasar.conf.js:module.export = function (ctx) { return { plugins: [ 'boot' ], ... }} IMPORTANTThe name “boot” for your plugin has a special meaning to Quasar CLI. It runs this plugin after all other app initialization has been executed and right before kicking off Vue with new Vue(). By adding this plugin you are responsible for kicking off Vue yourself, as we’ll see next. We edit our new plugin (/src/plugins/boot.js):export default ({ app, Vue }) => { // do some logic here... // ... then, kick off our Quasar website/app: /* eslint-disable-next-line no-new */ new Vue(app) // \"app\" has everything cooked in by Quasar CLI, // you don't need to inject it with anything at this point} IMPORTANTDo not forget to have at least one decisional branch where you call new Vue(app) otherwise your app won’t boot and you’ll only see a blank page!"},{"title":"App Handling Assets","updated":"2018-05-18T22:01:01.053Z","permalink":"https://v0-16.quasar-framework.org/guide/app-handling-assets.html","text":"You will notice in the project structure we have two directories for assets: /src/statics/ and /src/assets/. What is the difference between them? Some are static assets while the others are processed and embedded by the build system. Type of AssetsSo let’s try to answer the question above. We’ll first talk about using regular assets then we’ll see what static assets are. Regular assets - /src/assetsIn *.vue components, all your templates and CSS are parsed by vue-html-loader and css-loader to look for asset URLs. For example, in <img src="./logo.png"> and background: url(./logo.png), "./logo.png" is a relative asset path and will be resolved by Webpack as a module dependency. Because logo.png is not JavaScript, when treated as a module dependency, we need to use url-loader and file-loader to process it. Quasar CLI has already configured these webpack loaders for you, so you basically get features such as filename fingerprinting and conditional base64 inlining for free, while being able to use relative/module paths without worrying about deployment. Since these assets may be inlined/copied/renamed during build, they are essentially part of your source code. This is why it is recommended to place Webpack-processed assets inside /src/assets, along side other source files. In fact, you don’t even have to put them all in /src/assets: you can organize them based on the module/component using them. For example, you can put each component in its own directory, with its static assets right next to it. Asset Resolving RulesRelative URLs, e.g. ./assets/logo.png will be interpreted as a module dependency. They will be replaced with a auto-generated URL based on your Webpack output configuration. URLs prefixed with ~ are treated as a module request, similar to require('some-module/image.png'). You need to use this prefix if you want to leverage Webpack’s module resolving configurations. Quasar provides assets Webpack alias out of the box, so it is recommended that you use it like this: <img src="~assets/logo.png">. Notice ~ in front of ‘assets’. Static Assets - /src/staticsRoot-relative URLs, e.g. /statics/logo.png or statics/logo.png are not processed at all. This should be placed in src/statics/. These won’t be processed by Webpack at all. The statics folder is simply copied over to the distributable folder as-is. Quasar has some smart algorithms behind the curtains which ensure that no matter what you build (SPA, PWA, Cordova, Electron), your statics are correctly referenced if and only if all your statics start with statics/ string. For this reason, do not use /statics as URL. <!-- Good! --><img src=\"statics/logo.png\"><!-- BAD! Don't! --><img src=\"/statics/logo.png\"> Vue Binding Requires Statics OnlyPlease note that whenever you bind “src” to a variable in your Vue scope, it must be one from the statics folder. The reason is simple: the URL is dynamic, so Webpack (which packs up assets at compile time) doesn’t know which file you’ll be referencing at runtime, so it won’t process the URL. <template> <!-- imageSrc MUST reference a file from /src/statics --> <img :src=\"imageSrc\"></template><script>export default { data () { return { <!-- Referencing /src/statics. Notice string doesn't start with a slash. (/) --> imageSrc: 'statics/logo.png' } }}</script> IMPORTANTYou can force serving static assets by using src as a Vue property. Instead of src="statics/path/to/image" use :src="'statics/path/to/image'". Please note the usage of single and double quotes. Getting Asset Paths in JavaScriptIn order for Webpack to return the correct asset paths, you need to use require('./relative/path/to/file.jpg'), which will get processed by file-loader and returns the resolved URL. For example: computed: { background () { return require('./bgs/' + this.id + '.jpg') }} Note the above example will include every image under ./bgs/ in the final build. This is because Webpack cannot guess which of them will be used at runtime, so it includes them all."},{"title":"Configuring quasar.conf.js","updated":"2018-07-23T16:37:49.867Z","permalink":"https://v0-16.quasar-framework.org/guide/app-quasar.conf.js.html","text":"Quasar Starter Kit makes use of some awesome tools under the cover, like Webpack. Fortunately, the complexity of configuring the underlying tools is managed by Quasar CLI which does the heavy lifting for you. As a result, you don’t even need to know Webpack in order to use Quasar. So what can you configure through /quasar.conf.js? Quasar components, directives and plugins that you’ll be using in your website/app. Default Quasar I18n language pack Icon pack(s) that you wish to use Default icon set for Quasar components Development server port, HTTPS mode, hostname and so on CSS animations that you wish to use App Plugins list (that determines order of execution too) – which are files in /src/plugins that tell how your app is initialized before mounting the root Vue component Global CSS/Stylus/… files to be included in the bundle PWA manifest and Workbox options Electron Packager and/or Electron Builder IE11+ support Extend Webpack config Object You’ll notice that changing any of these settings does not require you to manually reload the dev server. Quasar detects if the changes can be injected through Hot Module Reload and in case it can’t, it will reload the dev server for you. You won’t lose your development flow as you will just sit back while Quasar CLI quickly takes care of it. /quasar.conf.js is run by the Quasar CLI build system, so this code runs under Node directly, not in the context of your app. So you can require modules like ‘fs’, ‘path’, ‘webpack’ and so on. Make sure the ES6 features that you want to write this file with are supported by the installed version of your Node (which should be >= 8.9.0). StructureYou’ll notice that /quasar.conf.js exports a function that takes a ctx (context) parameter and returns an Object. This allows you to dynamically change your website/app config based on this context: module.exports = function (ctx) { console.log(ctx) // Example output on console: { dev: true, prod: false, theme: { mat: true }, themeName: 'mat', mode: { spa: true }, modeName: 'spa', target: {}, targetName: undefined, arch: {}, archName: undefined, debug: undefined } // context gets generated based on the parameters // with which you run \"quasar dev\" or \"quasar build\"} What this means is that, as an example, you can load a font when building with Quasar Material theme, and pick another one for Quasar iOS theme.module.exports = function (ctx) { extras: [ ctx.theme.mat ? 'roboto-font' // we're building with Material theme : null // we're not building with Material theme, so it's iOS theme ]} Or you can use a global CSS file for SPA mode and another one for Cordova mode while avoiding loading any such file for the other modes.module.exports = function (ctx) { css: [ ctx.mode.spa ? 'app-spa.styl' : null, // looks for /src/css/app-spa.styl ctx.mode.cordova ? 'app-cordova.styl' : null // looks for /src/css/app-cordova.styl ]} Or you can configure the dev server to run on port 8000 for SPA mode, on port 9000 for PWA mode or on port 9090 for the other modes:module.exports = function (ctx) { devServer: { port: ctx.mode.spa ? 8000 : (ctx.mode.pwa ? 9000 : 9090) }} The possibilities are endless. Options to ConfigureLet’s take each option one by one: Property Type Description css Array Global CSS/Stylus/… files from /src/css/, except for theme files, which are included by default. Example: [‘app.styl’] (referring /src/css/app.styl) extras Array What to import from quasar-extras package. Example: [‘material-icons’, ‘roboto-font’, ‘ionicons’] supportIE Boolean Add support for IE11+. framework Object/String What Quasar components/directives/plugins to import, what Quasar I18n language pack to use, what icon set to use for Quasar components. Example: { components: [‘QBtn’, ‘QIcon’], directives: [‘TouchSwipe’], plugins: [‘Notify’], iconSet: ‘fontawesome’, i18n: ‘de’ }. Note that for iconSet to work, you also need to tell Quasar to embed that icon pack through extras prop. animations Object/String What CSS animations to import. Example: [‘bounceInLeft’, ‘bounceOutRight’] devServer Object Dev server options. Some properties are overwritten based on the Quasar mode you’re using in order to ensure a correct config. build Object Build configuration options. See section below. sourceFiles Object (v0.16+) Change the default name of parts of your app. More info cordova Object Cordova specific config. pwa Object PWA specific config. electron Object Electron specific config. devServer PropertyTake a look at the full list of options. Some are overwritten by Quasar CLI based on “quasar dev” parameters and Quasar mode in order to ensure that everything is setup correctly. Most used properties are: Property Type Description port Number Port of dev server host String Local IP/Host to use for dev server open Boolean Open up browser pointing to dev server address automatically. Applies to SPA and PWA modes. build Property Property Type Description extendWebpack(cfg) Function Extend Webpack config generated by Quasar CLI. Equivalent to chainWebpack(), but you have direct access to the Webpack config object. chainWebpack(chain) Function (CLI v0.16.2+) Extend Webpack config generated by Quasar CLI. Equivalent to extendWebpack(), but using webpack-chain instead. publicPath String Public path of your app. By default, it uses the root. Use it when your public path is something else, like “<protocol>://<domain>/some/nested/folder” – in this case, it means the distributables are in “some/nested/folder” on your webserver. vueRouterMode String Sets Vue Router mode: ‘hash’ or ‘history’. Pick wisely. History mode requires configuration on your deployment web server too. htmlFilename String Default is ‘index.html’. productName String Default value is taken from package.json > productName field. distDir String Folder where Quasar CLI should generate the distributables. Relative path to project root directory. Default is ‘dist/{ctx.modeName}-{ctx.themeName}’. Applies to all Modes except for Cordova (which is forced to src-cordova/www). devtool String Source map strategy to use. env Object Add properties to process.env that you can use in your website/app JS code. Each property needs to be JSON encoded. Example: { SOMETHING: JSON.stringify(‘someValue’) }. gzip Boolean Gzip the distributables. Useful when the web server with which you are serving the content does not have gzip. scopeHoisting Boolean Default: true. Use Webpack scope hoisting for slightly better runtime performance. analyze Boolean/Object Show analysis of build bundle with webpack-bundle-analyzer. If using as Object, it represents the webpack-bundle-analyzer config Object. vueCompiler Boolean (v0.15.7+) Include vue runtime + compiler version, instead of default Vue runtime-only uglifyOptions Object (v0.16+) Minification options. Full list. preloadChunks Boolean (v0.16+) Default is “true”. Preload chunks when browser is idle to improve user’s later navigation to the other pages. The following properties of build are automatically configured by Quasar CLI depending on dev/build commands and Quasar mode. But if you like to override some (make sure you know what you are doing), you can do so: Property Type Description extractCSS Boolean Extract CSS from Vue files sourceMap Boolean Use source maps minify Boolean Minify code (html, js, css) webpackManifest Boolean Improves caching strategy. Use a webpack manifest (runtime) file to avoid cache bust on vendor chunk changing hash on each build. If, for example, you run “quasar build –debug”, sourceMap and extractCSS will be set to “true” regardless of what you configure. sourceFiles PropertyQuasar v0.16+ Use this property to change the default names of some files of your website/app if you have to. All paths must be relative to the root folder of your project. // default values:sourceFiles: { rootComponent: 'src/App.vue', router: 'src/router', store: 'src/store', indexHtmlTemplate: 'src/index.template.html', registerServiceWorker: 'src-pwa/register-service-worker.js', serviceWorker: 'src-pwa/custom-service-worker.js', electronMainDev: 'src-electron/main-process/electron-main.dev.js', electronMainProd: 'src-electron/main-process/electron-main.js'} Example setting env for dev/buildbuild: { env: ctx.dev ? { // so on dev we'll have API: JSON.stringify('https://dev.api.com') } : { // and on build (production): API: JSON.stringify('https://prod.api.com') }} Then in your website/app you can access process.env.API and it’s gonna point to one of those two links above, based on dev or production build type. You can even go one step further. Supply it with values taken from the quasar dev/build env variables:# we set an env variable in terminal$ MY_API=api.com quasar build# then we pick it up in /quasar.conf.jsbuild: { env: ctx.dev ? { // so on dev we'll have API: JSON.stringify('https://dev.'+ process.env.MY_API) } : { // and on build (production): API: JSON.stringify('https://prod.'+ process.env.MY_API) }} Extending Webpack Config ObjectThis is achieved through build > extendWebpack() Function. Example adding a Webpack loader. // quasar.conf.jsbuild: { extendWebpack (cfg) { // we make in-place changes cfg.module.rules.push({ test: /\\.json$/, loader: 'json-loader' }) // no need to return anything }} If you are using Quasar CLI v0.16.2+, then you have another method to tamper with the generated Webpack config, through build > chainWebpack(chain). The difference is that it is easier because you’ll be using webpack-chain to do it. Equivalent with chainWebpack(chain):// quasar.conf.jsbuild: { chainWebpack (chain) { chain.module.rule('json') .test(/\\.json$/) .use('json-loader') .loader('json-loader') // no need to return anything }} NOTE chainWebpack() gets executed BEFORE extendWebpack() The two examples above are equivalent. Do NOT use both methods to tamper for the same thing! Adding your own alias to WebpackTo add your own alias you can extend the webpack config and merge it with the existing alias.Use the path.resolve helper to resolve the path to your intended alias. // quasar.conf.jsbuild: { extendWebpack (cfg) { cfg.resolve.alias = { ...cfg.resolve.alias, // This adds the existing alias // Add your own alias like this myalias: path.resolve(__dirname, './src/somefolder'), }} Equivalent with chainWebpack():// quasar.conf.jsbuild: { chainWebpack (chain) { chain.resolve.alias .set('myalias', path.resolve(__dirname, './src/somefolder')) }}"},{"title":"Lazy Loading / Code Splitting","updated":"2018-05-18T22:01:01.054Z","permalink":"https://v0-16.quasar-framework.org/guide/app-lazy-loading---code-splitting.html","text":"When your website/app is small, you can load all layouts/pages/components into the initial bundle and serve everything at startup. But when your code gets complex and has many layouts/pages/components, it won’t be optimal to do this as it will massively impact loading time. Fortunately, there is a way to solve this. We’ll cover how you can lazy load / code split parts of your app so that they are automatically requested only on demand. This is done through dynamic imports. Let’s start with an example and then convert it so that we use lazy loading – we’ll focus this example on loading a page, but the same principle can be applied to load anything (assets, JSONs, …): import SomePage from 'pages/SomePage'const routes = [ { path: '/some-page', component: SomePage }] Now let’s change this and make the page be loaded on demand only, using dynamic imports:const routes = [ { path: '/some-page', component: () => import('pages/SomePage') }] Easy, right? What this does is that it creates a separate chunk for /src/pages/SomePage.vue which is then loaded only when it is needed. In this case, when a user visits the ‘/same-page’ route. As you noticed above, we’re using dynamic imports (import('..resource..')) instead of regular imports (import Resource from './path/to/resource'). Dynamic imports are essentially returning a Promise that you can use: import('./categories.json') .then(categories => { // hey, we have lazy loaded the file // and we have its content in \"categories\" }) .catch(() => { // oops, something went wrong... // couldn't load the resource }) One advantage of using dynamic imports as opposed to regular imports is that the import path can be determined at runtime: import('pages/' + pageName + '/' + 'id') Caveat for Dynamic ImportsThere’s one caveat when using dynamic imports with variable parts like in the previous example. When the website/app is bundled, so at compile time, we have no way of telling what the exact import path will be at runtime. As a result, chunks will be created for each file that could match the variable path. You might see un-necessary files in the build log. So how can we limit the number of chunks created in this case? The idea is to limit the variable part as much as you can so the matched paths are as few as possible. Add file extension, even if it works without it too. This will create chunks only for that file types. Useful when that folder contains many file types. // badimport('./folder/' + pageName)// much betterimport('./folder/' + pageName + '.vue') Try to create a folder structure that will limit the files available in that variable path. Make it as specific as possible: // bad -- makes chunks for any JSON inside ./folder (recursive search)const asset = 'my/jsons/categories.json'import('./folder/' + asset)// good -- makes chunks only for JSONs inside ./folder/my/jsonsconst asset = 'categories.json'import('./folder/my/jsons/' + asset) Try to import from folders containing only files. Take the previous example and imagine ./folder/my/jsons further contains sub-folders. We made the dynamic import better by specifying a more specific path, but it’s still not optimal in this case. Best is to use terminal folders that only contain files, so we limit the number of matched paths. Remember that the number of matched paths equals to the number of chunks being generated."},{"title":"App Linter","updated":"2018-05-28T17:24:35.869Z","permalink":"https://v0-16.quasar-framework.org/guide/app-linter.html","text":"Having a code linter in place is highly recommended and ensures your code looks legible. It also helps you capture some errors before even running the code. When you create a Quasar project folder with Quasar CLI it will ask you if you want a linter and which setup you want for ESLint: Standard - https://github.com/standard/standard Airbnb - https://github.com/airbnb/javascript .. or you can configure one yourself Two dot files will be created: .eslintrc.js – ESLint configuration, including rules .eslintignore – what ESLint should ignore when linting Further extension of one of the Eslint setups above can be made. Your project will by default use eslint-plugin-vue to handle your Vue files. Take a quick look at .eslintrc.js and notice it: extends: [ // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 'plugin:vue/strongly-recommended'] If you chose ESLint when creating your project folder, you’ll also notice that /quasar.conf.js adds the eslint-loader to Webpack configuration for you: build: { extendWebpack (cfg) { cfg.module.rules.push({ enforce: 'pre', test: /\\.(js|vue)$/, loader: 'eslint-loader', exclude: /(node_modules|quasar)/ }) }} Lint RulesThe linting rules can be removed, changed, or added. Notice some things: Some rules are for the Standard or Airbnb standards (whichever you chose when project was created). Example: ‘brace-style’. Some rules are for eslint-plugin-vue. Example: ‘vue/max-attributes-per-line’. You can add/remove/change rules by first visiting https://eslint.org/docs/rules/ or https://github.com/vuejs/eslint-plugin-vue. Example of ESLint rules below:// .eslintrc.js'rules': { 'brace-style': [2, 'stroustrup', { 'allowSingleLine': true }], 'vue/max-attributes-per-line': 0, 'vue/valid-v-for': 0, // allow async-await 'generator-star-spacing': 'off', // allow paren-less arrow functions 'arrow-parens': 0, 'one-var': 0, 'import/first': 0, 'import/named': 2, 'import/namespace': 2, 'import/default': 2, 'import/export': 2, 'import/extensions': 0, 'import/no-unresolved': 0, 'import/no-extraneous-dependencies': 0, // allow debugger during development 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0} Disabling LinterIn order for you to disable ESLint, all you need to do is comment out (or remove) the following code from /quasar.conf.js: build: { extendWebpack (cfg) { /* * we comment out this block * cfg.module.rules.push({ enforce: 'pre', test: /\\.(js|vue)$/, loader: 'eslint-loader', exclude: /(node_modules|quasar)/ }) */ }}"},{"title":"App Vuex Store","updated":"2018-07-23T16:37:49.868Z","permalink":"https://v0-16.quasar-framework.org/guide/app-vuex-store.html","text":"In large applications, state management often becomes complex due to multiple pieces of state scattered across many components and the interactions between them. It is often overlooked that the source of truth in Vue instances is the raw data object - a Vue instance simply proxies access to it. Therefore, if you have a piece of state that should be shared by multiple instances, you should avoid duplicating it and share it by identity. The recommended way to go if you want components sharing state is Vuex. Take a look at its documentation before diving in. It has a great feature when used along the Vue dev-tools browser extension like Time Travel debugging. We won’t go into details on how to configure or use Vuex since it has great docs. Instead we’ll just show you what the folder structure looks like when using it on a Quasar project. .└── src/ └── store/ # Vuex Store ├── index.js # Vuex Store definition ├── <folder> # Vuex Store Module... └── <folder> # Vuex Store Module... By default, if you choose to use Vuex when you create a project folder with Quasar CLI, it will set you up on using Vuex modules. Each sub-folder of /src/store represents a Vuex Module. If Vuex Modules is too much for your website app, you can change /src/store/index.js and avoid importing any module. Adding a Vuex Module.Adding a Vuex Module is made easy by Quasar CLI through the $ quasar new command.$ quasar new store <store_name> It will create a folder in /src/store named by “store_name” from the command above. It will contain all the boilerplate that you need. Let’s say that you want to create a “showcase” Vuex Module. You issue $ quasar new store showcase. You then notice the newly created /src/store/showcase folder, which holds the following files: .└── src/ └── store/ ├── index.js # Vuex Store definition └── showcase # Module \"showcase\" ├── index.js # Gluing the module together ├── actions.js # Module actions ├── getters.js # Module getters ├── mutations.js # Module mutations └── state.js # Module state We’ve created the new Vuex Module, but we haven’t yet informed Vuex to use it. So we edit /src/store/index.js and add a reference to it: import Vue from 'vue'import Vuex from 'vuex'// we first import the moduleimport showcase from './showcase'Vue.use(Vuex)const store = new Vuex.Store({ modules: { // then we reference it showcase }})// if we want some HMR magic for it, we handle// the hot update like below. Notice we guard this// code with \"process.env.DEV\" -- so this doesn't// get into our production build (and it shouldn't).if (process.env.DEV && module.hot) { module.hot.accept(['./showcase'], () => { const newShowcase = require('./showcase').default store.hotUpdate({ modules: { showcase: newShowcase } }) })}export default store Now we can use this Vuex Module in our Vue files. Quick example. Assume we configured “drawerState” into the state and added updateDrawerState mutation. // src/store/showcase/mutations.jsexport const updateDrawerState = (state, opened) => { state.drawerState = opened}// src/store/showcase/state.jsexport default { drawerState: true} In a Vue file:<template> <div> <q-toggle v-model=\"drawerState\" /> </div></template><script>export default { computed: { drawerState: { get () { return this.$store.state.showcase.drawerState }, set (val) { this.$store.commit('showcase/updateDrawerState', val) } } }}</script>"},{"title":"App Routing","updated":"2018-05-18T22:01:01.055Z","permalink":"https://v0-16.quasar-framework.org/guide/app-routing.html","text":"You’ll notice that your Quasar project contains a /src/router folder. This holds the routing configuration of your website/app: “/src/router/index.js” holds the Vue Router initialization code “/src/router/routes.js” holds the routes of your website/app Make sure to read Vue Router documentation to understand how it works. The /src/router/routes.js needs to import your website/app’s Pages and Layouts. Read more on Adding Pages and Layouts documentation page."},{"title":"Configuring Cordova","updated":"2018-07-23T16:37:49.868Z","permalink":"https://v0-16.quasar-framework.org/guide/cordova-configuring-cordova.html","text":"We’ll be using Quasar CLI (and Cordova CLI) to develop and build a Mobile App. The difference between building a SPA, PWA, Electron App or a Mobile App is simply determined by the “mode” parameter in “quasar dev” and “quasar build” commands. There are two configuration files of great importance to your mobile apps. We’ll go over each one. Config.xmlThe most important config file for your mobile app is /src-cordova/config.xml. Like mentioned above, /src-cordova is a Cordova project folder, so please refer to Cordova documentation in order to understand what each file from there does. But for now, have a few moments to read about config.xml. Some properties from this file will get overwritten as we’ll see in next section. Quasar.conf.jsQuasar CLI helps you in setting some properties of the mobile Apps automatically (from config.xml): the Cordova “id”, app version and description. This is for convenience so you’ll be able to have a single point where, for example, you change the version of your app, not multiple files that you need to simultaneously touch which is error prone. For determining the values for each of the properties mentioned above, Quasar CLI: Looks in /quasar.conf.js for a “cordova” Object. Does it have “id”, “version” and/or “description”? If yes, it will use it/them. If not, then it looks into your /package.json for “cordovaId”, “version” and “description” fields."},{"title":"Supporting IE","updated":"2018-05-20T16:04:39.322Z","permalink":"https://v0-16.quasar-framework.org/guide/app-supporting-ie.html","text":"If you are building a website, you might want to support IE 11+. This support is not added by default to your website. Quasar CLI provides it on demand only. It is strongly recommended to use Yarn instead of NPM when developing on a Windows machine, to avoid many problems. Installation of IE SupportIn order to support IE, you’ll need to edit /quasar.conf.js:module.exports = function (ctx) { return { supportIE: true, .... }} That’s it. This will inject the Promise polyfill, along with some other smaller polyfills, adding an extra ~6k worth of code (minified) to your bundle. NOTEQuasar CLI is smart enough to include the IE polyfills only if it is really needed. An Electron app for example doesn’t need it and as a result, even if you leave supportIE set to “true” in quasar.conf.js it won’t be bundled. WARNINGRunning dev server on a Windows machine and consuming the output in IE11 will result in an error (ansi-strip package related used by webpack-dev-server). This is only an issue during development, and if you run the dev server on a Linux or MAC machine you can consume it safely in IE11.The fix is to use “yarn” instead of “npm” as node packager. If you have used npm until now, then delete /node_modules folder and /package-lock.json then run “yarn”."},{"title":"Mobile App Build Commands","updated":"2018-05-20T16:04:39.323Z","permalink":"https://v0-16.quasar-framework.org/guide/cordova-build-commands.html","text":"Quasar CLI makes it incredibly simple to develop or build the final distributables from your source code. Before we dive in, make sure you got the Cordova CLI installed.$ yarn global add cordova# or:$ npm install -g cordova Developing$ quasar dev -m cordova -T [ios|android]# ..or the longer form:$ quasar dev --mode cordova -T [ios|android]# with a specific Quasar theme, for iOS platform:$ quasar dev -m cordova -T ios -t ios# with a specific Quasar theme, for Android platform:$ quasar dev -m cordova -T android -t mat# using a specific emulator (--emulator, -e)$ quasar dev -m cordova -T android -e iPhone-7 IMPORTANTYou can develop with any Quasar theme, regardless of the platform you are building on (Android, IOS, …). In order for you to be able to develop on a device emulator or directly on a phone (with Hot Module Reload included), Quasar CLI follows these steps: Detects your machine’s external IP address. If there are multiple such IPs detected, then it asks you to choose one. If you’ll be using a mobile phone to develop then choose the IP address of your machine that’s pingable from the phone/tablet. It starts up a development server on your machine. It temporarily changes the <content/> tag in /src-cordova/config.xml to point to the IP previously detected. This allows the app to connect to the development server. It defers to Cordova CLI to build a native app with the temporarily changed config.xml. Cordova CLI checks if a mobile phone / tablet is connected to your development machine. If it is, it installs the development app on it. If none is found, then it boots up an emulator and runs the development app. Finally, it reverts the temporary changes made to /src-cordova/config.xml. IMPORTANTIf developing on a mobile phone/tablet, it is very important that the external IP address of your build machine is accessible from the phone/tablet, otherwise you’ll get a development app with white screen only. Also check your machine’s firewall to allow connections to the development chosen port. Building for Production$ quasar build -m cordova -T [ios|android]# ..or the longer form:$ quasar build --mode cordova -T [ios|android]# with a specific Quasar theme, for iOS platform:$ quasar build -m cordova -T ios -t ios# with a specific Quasar theme, for Android platform:$ quasar build -m cordova -T android -t mat IMPORTANTYou can build with any Quasar theme, regardless of the platform you are targeting (Android, IOS, …). These commands parse and build your /src folder then overwrite /src-cordova/www then defer to Cordova CLI to trigger the actual native app creation. You may ask yourself. So where’s the .apk or .app? Watch the terminal console to see where it puts it."},{"title":"App Pre-Processors & Webpack","updated":"2018-05-28T17:33:06.389Z","permalink":"https://v0-16.quasar-framework.org/guide/app-pre-processors-and-webpack.html","text":"The build system uses Webpack to create your website/app. Don’t worry if you aren’t acquainted with Webpack. Out of the box, you won’t need to configure it because it already has everything set up. However, for cases where you need to tweak the default Webpack config you can do so by editing /quasar.conf.js and configuring build > extendWebpack (cfg) method or (CLI v0.16.2+) build > chainWebpack (chain). Example of adding ESLint loader to it (assuming you’ve installed it):build: { extendWebpack (cfg) { cfg.module.rules.push({ enforce: 'pre', test: /\\.(js|vue)$/, loader: 'eslint-loader', exclude: /(node_modules|quasar)/ }) }} Notice that you don’t need to return anything. The parameter of extendWebpack(cfg) is the Webpack configuration Object generated by Quasar for you. You can add/remove/replace anything from it, assuming you really know what you are doing. Equivalent quasar.conf for chainWebpack():build: { chainWebpack (chain) { chain.module.rule('eslint') .test(/\\.(js|vue)$/) .enforce('pre') .exclude(/(node_modules|quasar)/) .use('eslint-loader') .loader('eslint-loader') }} Let’s discuss about Webpack loaders now. It’s probably where you’ll make the most additions. Webpack AliasesQuasar comes with a bunch of useful Webpack aliases preconfigured.You can use them anywhere in your project and webpack will resolve the correct path. If you want to add you own alias, se the section about adding your own alias to Webpack. Alias Resolves to quasar node_modules/quasar-framework/dist/quasar.<configured-theme>.esm.js src /src components /src/components layouts /src/layouts pages /src/pages assets /src/assets plugins /src/plugins variables /.quasar/variables.styl Also if you configure to build with the Vue compiler version (build > vueCompiler: true), vue$ resolves to vue/dist/vue.esm.js. Webpack LoadersThe build system uses Webpack, so it relies on using webpack loaders to handle different types of files (js, css, styl, scss, json, and so on). By default, the most used loaders are provided by default. Installing loaders:Let’s take an example. You want to be able to import .json files. Out of the box, Quasar supplies json support so you don’t actually need to follow these steps, but for the sake of demonstrating how to add a loader, we’ll pretend Quasar doesn’t offer it. So, you need a loader for it. You search Google to see what webpack loader you need. In this case, it’s “json-loader”. We first install it:$ yarn add --dev json-loader# or:$ npm install --save-dev json-loader After installing your new loader, we want to tell Webpack to use it. So we edit /quasar.conf.js and change build.extendWebpack() to add entries to module/rules for this new loader: // quasar.confbuild: { extendWebpack (cfg) { cfg.module.rules.push({ test: /\\.json$/, loader: 'json-loader' }) }} Equivalent with chainWebpack():// quasar.confbuild: { chainWebpack (chain) { chain.module.rule('json') .test(/\\.json$/) .use('json-loader') .loader('json-loader') }} And you’re done. SASS/SCSS supportSo you want to be able to write SASS/SCSS CSS code. You need a loader for it. We first install it. Note that for this particular case you also need to install node-sass because sass-loader depends on it as a peer dependency. $ yarn add --dev sass-loader node-sass# or:$ npm install --save-dev sass-loader node-sass And you’re done. For SCSS/SASS it’s all it takes. You don’t need to further configure /quasar.conf.js. Once installed, you can use this pre-processor inside your *.vue components using the lang attribute on <style> tags: <style lang=\"scss\">/* We can write SASS now! */</style> A note on SASS syntax: lang=”scss” corresponds to the CSS-superset syntax (with curly braces and semicolons). lang=”sass” corresponds to the indentation-based syntax. PostCSSStyles in *.vue files (and all other style files) are piped through PostCSS by default, so you don’t need to use a specific loader for it. By default, PostCSS is configured to use Autoprefixer. Take a look at `/.postcssrc.js where you can tweak it if you need to. PugFirst, you need to install some dependencies: $ yarn add --dev pug pug-plain-loader# or:$ npm install --save-dev pug pug-plain-loader Then you need to extend the webpack configuration through quasar.conf.js:// quasar.conf.jsbuild: { extendWebpack (cfg) { cfg.module.rules.push({ test: /\\.pug$/, loader: 'pug-plain-loader' }) }} Equivalent with chainWebpack():// quasar.conf.jsbuild: { chainWebpack (chain) { chain.module.rule('pug') .test(/\\.pug$/) .use('pug-plain-loader') .loader('pug-plain-loader') }} CoffeescriptIf you are using Coffeescript then you need to EITHER disable ESLint OR tell ESLint which Vue components are using Coffeescript. Note that vue-loader uses lang="coffee" to identify components which are using Coffeescript, but lang="coffee" is not recognizable for ESLint. Fortunately, ESLint (following traditional HTML) uses type="xxx" to identify the type of scripts. As long as a <script> tag has any type other than javascript, ESLint would mark the script as non-javascript, and skips linting it. Coffeescript’s convention is to use type="text/coffeescript" to identify itself. Therefore, in your Vue components which are using Coffeescript, using both lang and type to avoid ESLint warnings: <template> ...</template><script lang=\"coffee\" type=\"text/coffeescript\"> ...</script>"},{"title":"What is Cordova","updated":"2018-05-18T22:01:01.057Z","permalink":"https://v0-16.quasar-framework.org/guide/cordova-introduction.html","text":"Apache Cordova is a mobile application development framework originally created by Nitobi. Adobe Systems purchased Nitobi in 2011, rebranded it as PhoneGap, and later released an open source version of the software called Apache Cordova. Apache Cordova enables software programmers to build applications for mobile devices using CSS3, HTML5, and JavaScript instead of relying on platform-specific APIs like those in Android, iOS, or Windows Phone. It enables wrapping up of CSS, HTML, and JavaScript code depending upon the platform of the device. It extends the features of HTML and JavaScript to work with the device. The resulting applications are hybrid, meaning that they are neither truly native mobile application (because all layout rendering is done via Web views instead of the platform’s native UI framework) nor purely Web-based (because they are not just Web apps, but are packaged as apps for distribution and have access to native device APIs). You can hook into the native device APIs by using Cordova Plugins."},{"title":"Cordova Plugins","updated":"2018-07-09T22:30:23.754Z","permalink":"https://v0-16.quasar-framework.org/guide/cordova-plugins.html","text":"You can hook into the native device APIs by using Cordova Plugins. Cordova PluginsA few examples of such plugins: Battery Status Camera Contacts Device Device Motion Geolocation Media Media Capture Network Information Splashscreen Vibration Statusbar Deviceready EventYou’ll notice that some Cordova plugins are usable only after the deviceready event has been triggered. We don’t need to worry about it too much. Quasar listens to this event and takes care of our root Vue component to be mounted after this event has been triggered. But if you need some plugin’s own variable and that is initialized after deviceready you can follow the example of using the plugin device below CaveatLet’s take a vue file for example:<template> ... we are sure 'deviceready' has been triggered here ...</template><script>// outside of the default export,// we need to listen to the event for ourselves:document.addEventListener('deviceready', () => { // it's only now that we are sure // the event has triggered}, false)export default { // we are sure 'deviceready' has been triggered here}</script> The reason is simple. Quasar listens for the event then mounts the root Vue component. But before this, the Vue files are imported into the /src/router/routes.js file, so the code outside of the default export gets executed. Using a Cordova PluginLet’s learn by taking some examples, assuming you’ve added Cordova mode to your Quasar project and installed a platform (android, ios, …) already. Example: Battery StatusFirst step is to read the documentation of the Cordova plugin that we want to use. We look at Cordova Plugins list and click on Battery Status doc page. We see instructions on how to install this plugin. It’s always a Cordova command. So we “cd” into /src-cordova (which is a Cordova generated folder) and issue the install command form there:# from /src-cordova:$ cordova plugin add cordova-plugin-battery-status Now let’s put this plugin to some good use. In one of your Quasar project’s pages/layouts/components Vue file, we write: // some Vue file// remember this is simply an example;// only look at how we use the API described in the plugin's page;// the rest of things here are of no importance<template> <div> Battery status is: <strong>{{ batteryStatus }}</strong> </div></template><script>export default { data () { return { batteryStatus: 'determining...' } }, methods: { updateBatteryStatus (status) { this.batteryStatus = `Level: ${status.level}, plugged: ${status.isPlugged}` } } created () { // we register the event like on plugin's doc page window.addEventListener('batterystatus', this.updateBatteryStatus, false) }, beforeDestroy () { // we do some cleanup; // we need to remove the event listener window.removeEventListener('batterystatus', this.updateBatteryStatus, false) }}</script> Example: CameraFirst step is to read the documentation of the Cordova plugin that we want to use. We look at Cordova Plugins list and click on Camera doc page. There’s a mention of the deviceready event. But we already know how to handle it from the previous sections. We read the instructions on how to install this plugin. It’s always a Cordova command. So we “cd” into /src-cordova (which is a Cordova generated folder) and issue the install command form there:# from /src-cordova:$ cordova plugin add cordova-plugin-camera Now let’s put this plugin to some good use. In one of your Quasar project’s pages/layouts/components Vue file, we write: // some Vue file// remember this is simply an example;// only look at how we use the API described in the plugin's page;// the rest of things here are of no importance<template> <div> <q-btn color=\"primary\" label=\"Get Picture\" @click=\"captureImage\" /> <img :src=\"imageSrc\"> </div></template><script>export default { data () { return { imageSrc: '' } }, methods: { captureImage () { navigator.camera.getPicture( data => { // on success this.imageSrc = `data:image/jpeg;base64,${data}` }, () => { // on fail this.$q.notify('Could not access device camera.') }, { // camera options } ) } }}</script> Example: DeviceFirst step is to read the documentation of the Cordova plugin that we want to use. Look at the Cordova Plugins list and click on Device doc page. This plugin initializes a global variable called device which describes the device’s hardware and software. So it can be accessed with window.device. Read the instructions on how to install this plugin on its cordova doc page. It’s always a Cordova command. So we “cd” into /src-cordova (which is a Cordova generated folder) and issue the install command from there:# from /src-cordova:$ cordova plugin add cordova-plugin-device Now let’s put this plugin to some good use. If you need the information of your device when starting the application, you will have to capture the created event. In one of your Quasar project’s pages/layouts/components Vue file, we write: // some Vue file// remember this is simply an example;// only look at how we use the API described in the plugin's page;// the rest of things here are of no importance<template> <div> <q-page class=\"flex flex-center\"> <div>IMEI {{IMEI}}</div> </q-page> </div></template><script>export default { data () { return { IMEI: window.device === void 0 ? 'Run this on a mobile/tablet device' : window.device } }}</script>"},{"title":"Managing Google Analytics","updated":"2018-05-18T22:01:01.057Z","permalink":"https://v0-16.quasar-framework.org/guide/cordova-managing-google-analytics.html","text":"Getting to know your users and measuring user behavior is an important step in App Development. Unfortunately, it takes a bit of non-standard work to get Google Analytics to work after wrapping your mobile app with Cordova. Setting up Google Analytics in a pure web application is quite easy, but Cordova somehow prevents pageviews and events from being sent to Google Analytics. Follow this guide to implement Google Analytics into your Cordova powered Quasar App. IMPORTANTYou’ll need to include a <script> tag provided by Google in /src/index.template.html, which will make your App depend on an Internet connection! Prerequisites Make sure all your routes have a name and path parameter specified. Otherwise, they cannot be posted to the ga.logPage function. Please refer to Routing for more info on routing. Have Basic knowledge of Google Analytics PreparationBefore we can start implementing Google Analytics into your application, you’ll need an account for Google Analytics and Google Tagmanager. So let’s do that first. When you have these accounts, it’s time to configure Tag manager. Follow the steps in this Multiminds article to do so. Implementing this into application For this guide, we’ll assume you have a fixed sessionId that you send to Google Analytics. Google Analytics uses a sessionId to distinguish different users from each other. If you want to create an anonymous sessionId, see Analytics Documentation on user id. Place the Tag Manager snippet into head of your index.html file (if you’ve followed the Multiminds article, you already have this.) Create a new file in your codebase called analytics.js with the following contents: export default { logEvent(category, action, label, sessionId = null) { dataLayer.push({ 'appEventCategory': category, 'appEventAction': action, 'appEventLabel': label, 'sessionId': sessionId }) dataLayer.push({ 'event': 'appEvent' }) }, logPage(path, name, sessionId = null) { dataLayer.push({ 'screenPath': path, 'screenName': name, 'sessionId': sessionId }) dataLayer.push({ 'event': 'appScreenView' }) }} To make sure all the pages in your application are automatically posted to Google Analytics, we create an app plugin:$ quasar new plugin google-analytics Then we edit the newly created file: /src/plugins/google-analytics:import ga from 'analytics.js'export default ({ router }) => { router.afterEach((to, from) => { ga.logPage(to.path, to.name, sessionId) })} Finally we register the app plugin in /quasar.conf.js. We can do so only for Cordova wrapped apps if we want:plugins: [ ctx.mode.cordova ? 'google-analytics' : ''] More information about events can be found in the Analytics documentation on events. You’ll see the events and pageviews coming in when you run your app. It usually takes around 5 to 10 seconds for a pageview to be registered in the realtime view."},{"title":"Cordova Troubleshooting and Tips","updated":"2018-05-18T22:01:01.058Z","permalink":"https://v0-16.quasar-framework.org/guide/cordova-troubleshooting-and-tips.html","text":"Browser SimulatorUse Google Chrome’s emulator from Developer Tools. It’s a fantastic tool. You can select which device to emulate, but keep in mind that it’s an emulator and not the real deal. IMPORTANTAlso, if you change from desktop to mobile emulator or backwards, hit the refresh button as Quasar Platform detection is not dynamic (nor it should be). Disabling iOS rubber band effectWhen building an iOS app with Cordova and you want to disable the rubber band effect (https://www.youtube.com/watch?v=UjuNGpU29Mk), add this to your /src-cordova/config.xml: <preference name = \"DisallowOverscroll\" value = \"true\" /> Remote DebuggingIf you are debugging Android Apps, you can use Google Chrome Remote Debugging through a USB cable attached to your Android phone/tablet. It can be used for emulator too. This way you have Chrome Dev Tools directly for your App running on the emulator/phone/table. Inspect elements, check console output, and so on and so forth. Android SDK not found after installation of the SDKSome newer Debian-based OS (e.g. ubuntu, elementary OS) might leave you with a Android SDK not found. after you installed and (correctly) configured the environment. The output might look similar to this: $ cordova requirementsRequirements check results for android:Java JDK: installed 1.8.0Android SDK: installed trueAndroid target: not installedAndroid SDK not found. Make sure that it is installed. If it is not at the default location, set the ANDROID_HOME environment variable.Gradle: not installedCould not find gradle wrapper within Android SDK. Might need to update your Android SDK.Looked here: /home/your_user/Android/Sdk/tools/templates/gradle/wrapperError: Some of requirements check failed This could have two different reasons: Usually the paths aren’t configured correctly. The first step is to verify if your paths are set correctly. This can be done by running the following commands: $ echo $ANDROID_HOME The expected output should be a path similar to this $HOME/Android/Sdk. After this run: $ ls -la $ANDROID_HOME To ensure the folder contains the SDK. The expected output should contain folders like ‘tools’, ‘sources’, ‘platform-tools’, etc. $ echo $PATH The output should contain each one entry for the Android SDK ‘tools’-folder and ‘platform-tools’-tools. This could look like this: /home/your_user/bin:/home/your_user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/your_user/Android/Sdk/tools:/home/your_user/Android/Sdk/platform-tools If you ensured your paths are set correctly and still get the error on cordova requirements you can try the following fix: Replacing the Android Studio ‘tools’ folder manually Setting Up Device on LinuxYou may bump into ?????? no permissions problem when trying to run your App directly on an Android phone/tablet. Here’s how you fix this: # create the .rules file and insert the content# from below this examplesudo vim /etc/udev/rules.d/51-android.rulessudo chmod 644 /etc/udev/rules.d/51-android.rulessudo chown root. /etc/udev/rules.d/51-android.rulessudo service udev restartsudo killall adb The content for 51-android.rules:SUBSYSTEM=="usb", ATTRS{idVendor}=="0bb4", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0e79", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0502", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0b05", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="413c", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0489", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="091e", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="18d1", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0bb4", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="12d1", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="24e3", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="2116", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0482", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="17ef", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="1004", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="22b8", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0409", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="2080", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0955", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="2257", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="10a9", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="1d4d", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0471", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="04da", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="05c6", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="1f53", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="04e8", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="04dd", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0fce", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="0930", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="19d2", MODE="0666"SUBSYSTEM=="usb", ATTRS{idVendor}=="1bbb", MODE="0666" Now running adb devices should discover your device."},{"title":"Mobile App Preparation","updated":"2018-05-28T18:15:22.603Z","permalink":"https://v0-16.quasar-framework.org/guide/cordova-preparation.html","text":"Before we dive in to the actual development, we need to do some preparation work. 1. InstallationFirst step is to make sure you got the Cordova CLI installed and the necessary SDKs.$ yarn global add cordova# or:$ npm install -g cordova After this step you will need to install the Android platform SDK on your machine. You can download the Android Studio here and follow these installation steps afterwards. Update your ~/.bashrc file to contain the correct paths to your installation of Android Studio: export ANDROID_HOME=\"$HOME/Android/Sdk\"PATH=$PATH:$ANDROID_HOME/tools; PATH=$PATH:$ANDROID_HOME/platform-tools Start Android studio by changing into the folder you installed it in and run ./studio.sh. Next step is to install the individual SDKs: Open the “Configure” menu at the bottom of the window: Select the desired SDKs. As per May 2017 Cordova supports 4.4 and up and click on “Apply” to install the SDKs. 2. Add Cordova Quasar ModeIn order to develop/build a Mobile app, we need to add the Cordova mode to our Quasar project. What this does is that it uses Cordova CLI to generate a Cordova project in /src-cordova folder. /src-cordova/www folder will be overwritten each time you build.$ quasar mode -a cordova You can now verify if everything is in order. “cd” into /src-cordova and type:$ cordova requirements On some newer Debian-based operating systems you might face a very persistent problem when running cordova requirements. Please see the “Android SDK not found” after installation section for assistance. 3. Start DevelopingIf you want to jump right in and start developing, you can skip the previous step with “quasar mode” command and issue:$ quasar dev -m cordova -T [android|ios] This will add Cordova mode automatically, if it is missing."},{"title":"Electron Build Commands","updated":"2018-05-18T22:01:01.059Z","permalink":"https://v0-16.quasar-framework.org/guide/electron-build-commands.html","text":"Quasar CLI makes it incredibly simple to develop or build the final distributables from your source code. Developing$ quasar dev -m electron# ..or the longer form:$ quasar dev --mode electron# with a specific Quasar theme, for iOS platform:$ quasar dev -m electron -t ios# with a specific Quasar theme, for Android platform:$ quasar dev -m electron -t mat It opens up an Electron window with dev-tools included. You have HMR for the renderer process and changes to main process are also picked up (but the latter restarts the Electron window on each change). Check how you can tweak Webpack config Object for the Main Process on Configuring Electron page. Building for Production$ quasar build -m electron# ..or the longer form:$ quasar build --mode electron# with a specific Quasar theme, for iOS platform:$ quasar build -m electron -t ios# with a specific Quasar theme, for Android platform:$ quasar build -m electron -t mat It builds your app for production and then uses electron-packager to pack it into an executable. Check how to configure this on Configuring Electron page. A note for non-Windows usersIf you want to build for Windows with a custom icon using a non-Windows platform, you must have wine installed. More Info."},{"title":"Configuring Electron","updated":"2018-05-28T18:00:18.503Z","permalink":"https://v0-16.quasar-framework.org/guide/electron-configuring-electron.html","text":"We’ll be using Quasar CLI to develop and build an Electron App. The difference between building a SPA, PWA, Mobile App or an Electron App is simply determined by the “mode” parameter in “quasar dev” and “quasar build” commands. But first, let’s learn how we can configure the Electron build. Quasar.conf.jsYou may notice that /quasar.conf.js contains a property called electron.electron: { // optional; webpack config Object for // the Main Process ONLY (/src-electron/main-process/) extendWebpack (cfg) { // directly change props of cfg; // no need to return anything }, // optional; EQUIVALENT to extendWebpack() but uses webpack-chain; // for the Main Process ONLY (/src-electron/main-process/) chainWebpack (chain) { // chain is an webpack-chain instance // of the Webpack configuration }, bundler: 'packager', // or 'builder' // electron-packager options packager: { //... }, // electron-builder options builder: { //... }} The “packager” prop refers to electron-packager options. The dir and out properties are overwritten by Quasar CLI to ensure the best results. The “builder” prop refers to electron-builder options."},{"title":"Electron Packages","updated":"2018-05-20T16:04:39.326Z","permalink":"https://v0-16.quasar-framework.org/guide/electron-packages.html","text":"You can npm/yarn install and use Electron specific packages in your app. Take a look at the link and choose wisely if you need to."},{"title":"What is Electron","updated":"2018-05-18T22:01:01.059Z","permalink":"https://v0-16.quasar-framework.org/guide/electron-introduction.html","text":"Electron (formerly known as Atom Shell) is an open-source framework created by Cheng Zhao, and now developed by GitHub. It allows for the development of desktop GUI applications using front and back end components originally developed for web applications: Node.js runtime for the backend and Chromium for the frontend. Electron is the main GUI framework behind several notable open-source projects including GitHub’s Atom and Microsoft’s Visual Studio Code source code editors, the Tidal music streaming service desktop application and the Light Table IDE, in addition to the freeware desktop client for the Discord chat service. Each Electron app has two threads: one is the main thread (dealing with the App window and bootup), and one is the renderer thread (which is basically your web code UI). Renderer ThreadElectron uses Chromium for displaying web pages in a separate process called the render process. This thread deals with your UI code in /src folder. In normal browsers, web pages usually run in a sand-boxed environment and are not allowed access to native resources. For Electron users, however, you got the power to use Node.js APIs in web pages allowing lower level operating system interactions. Main ThreadIn Electron, the process that runs package.json’s main script is called the main process. The script that runs in the main process and can display a GUI by initializing the renderer thread."},{"title":"Publishing to Store","updated":"2018-05-18T22:01:01.058Z","permalink":"https://v0-16.quasar-framework.org/guide/cordova-publishing-to-store.html","text":"So you’ve finished working on your Mobile App. Now it’s time to deploy it. Let’s learn how. Android PublishingTo generate a release build for Android, we can use the following Quasar CLI command:$ quasar build -m cordova -T android# optionally picking a Quasar theme too$ quasar build -m cordova -T android -t mat This will generate a release build based on the settings in your /src-cordova/config.xml. Next, we can find our unsigned APK file in /src-cordova/platforms/android/build/outputs/apk. Filename usually ends with “-release-unsigned.apk”. Now, we need to sign the unsigned APK and run an alignment utility on it to optimize it and prepare it for the app store. If you already have a signing key, skip these steps and use that one instead. Let’s generate our private key using the keytool command that comes with the JDK. If this tool isn’t found, refer to the installation guide: $ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 20000 You’ll first be prompted to create a password for the keystore. Then, answer the rest of the nice tools’s questions and when it’s all done, you should have a file called my-release-key.keystore created in the current directory. NoteMake sure to save this file somewhere safe, if you lose it you won’t be able to submit updates to your app! To sign the unsigned APK, run the jarsigner tool which is also included in the JDK: $ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore <path-to-unsigned-apk-file> alias_name This signs the apk in place. Finally, we need to run the zip align tool to optimize the APK. The zipalign tool can be found in /path/to/Android/sdk/build-tools/VERSION/zipalign. For example, on OS X with Android Studio installed, zipalign is in ~/Library/Android/sdk/build-tools/VERSION/zipalign: $ zipalign -v 4 <path-to-same-apk-file> HelloWorld.apk Now we have our final release binary called HelloWorld.apk and we can release this on the Google Play Store for all the world to enjoy! (There are a few other ways to sign APKs. Refer to the official Android App Signing documentation for more information.) Google Play StoreNow that we have our release APK ready for the Google Play Store, we can create a Play Store listing and upload our APK. To start, you’ll need to visit the Google Play Store Developer Console and create a new developer account. Unfortunately, this is not free. However, the cost is only $25 compared to Apple’s $99. Once you have a developer account, you can go ahead and click “Publish an Android App on Google Play”. Then, you can go ahead and click the button to edit the store listing (We will upload an APK later). You’ll want to fill out the description for the app. When you are ready, upload the APK for the release build and publish the listing. Be patient and your hard work should be live in the wild! Updating your AppAs you develop your app, you’ll want to update it periodically. In order for the Google Play Store to accept updated APKs, you’ll need to bump the app version (from /package.json or from /quasar.conf.js > cordova > version, then rebuild the app for release. iOS PublishingFirst, you need to enroll in Apple Developer Program. As with Google, if you have a personal account with Apple, you can create an additional one for your applications. Connecting Xcode with your developer accountAfter you receive your developer status, open Xcode on your Mac and go to Preferences > Accounts and add your account to Xcode by clicking the + button on the lower left hand side, and follow the instructions. SigningNow that you linked Xcode with your developer account, go to Preferences > Accounts, select your Apple Id on the left hand side and then click the View Details button shown on the previous image. Click the Create button next to the iOS Distribution option. You can learn more about maintaining your signing identities and certificates from the official documentation. Setting up the app identifierNext, through the Apple Developer Member Center we’ll set up the app ID identifier details. Identifiers are used to allow an app to have access to certain app services like for example Apple Pay. You can login to Apple Developer Member Center with your Apple ID and password. Once you’re logged in you should choose Certificates, Identifiers, and Profiles option. Also select the Identifiers option under the iOS Apps. Then select the + button in order to add a new iOS App ID. Then you’ll have to set the name of your app, and use the Explicit App ID option and set the Bundle ID to the value of the id in your Cordova config.xml tag. Additionally, you’ll have to choose any of the services that need to be enabled. For example, if you use Apple Pay or Wallet in your app, you need to choose those option. You can learn more about registering app identifiers from the official documentation. Creating the app listingApple uses iTunes Connect to manage app submissions. After you login, you should select the My Apps button, and on the next screen select the + button, just below the iTunes Connect My Apps header. This will show three options in a dropdown, and you should select the New App. After this the popup appears where you have to choose the name of the application, platform, primary language, bundle ID and SKU. Once you’re done, click on the Create button and you’ll be presented with a screen where you’ll have to set some basic options like Privacy Policy URL, category and sub category. Now, before we fill out everything in the listing, we’ll build our app and get it uploaded with Xcode. Then you’ll come back to finish the listing. You can learn more about managing your app in iTunes Connect from the official documentation. Building the app for production$ quasar build -m cordova -T [android|ios] -t [mat|ios] If everything went well you’ll see the BUILD SUCCEEDED output in the console. Opening the project in XcodeNow, open the /src-cordova/platforms/ios/<name>.xcodeproj file in Xcode. Once the Xcode opens up the project, you should see the details about your app in the general view. You should just check that the bundle identifier is set up correctly, so that it’s the same as the value you specified earlier in the app ID. Also, make sure that the version and build numbers are correct. Team option should be set to your Apple developer account. Under the deployment target you can choose which devices your application will support. Creating an archive of the applicationIn Xcode, select Product > Scheme > Edit Scheme to open the scheme editor. Next, select the Archive from the list on the left hand side. Make sure that the Build configuration is set to Release. To create an archive choose a Generic iOS Device, or your device if it’s connected to your Mac (you can’t create an archive if simulator is selected), from the Scheme toolbar menu in the project editor. Next, select Product > Archive, and the Archive organizer appears and displays the new archive. At this point you can click the Upload to App Store... button, and if everything goes fine you’ll have an uploaded app, and the only thing that’s left to do is to complete the iTunes Connect listing and submit it for review! At this point you should get an email from iTunes Connect shortly after you uploaded the archive with the content. Finishing the app list processNow you should head back to the iTunes Connect portal and login. Next, click on the Pricing and Availability on the left hand side under APP STORE INFORMATION. You don’t have to worry about forgetting to insert any crucial and required information about your application, since you’ll be notified about what’s missing and what needs to be added/changed if you try to submit the app for review before all details are filled in. Next, click on the 1.0 Prepare for Submission button on the left hand side, as shown on the image below. When we uploaded our archive, iTunes Connect automatically determined which device sizes are supported. You’ll need to upload at least one screenshot image for each of the various app sizes that were detected by iTunes Connect. Next you’ll have to insert Description, Keywords, Support URL and Marketing URL (optionally). In the Build section you have to click on the + button and select the build that was uploaded through Xcode in the previous steps. Next you’ll have to upload the icon, edit the rating, and set some additional info like copyright and your information. Note that the size of the icon that you’ll have to upload here will have to be 1024 by 1024 pixels. Thankfully, you can use the splash.png from the second tutorial. If you’re the sole developer then the data in the App Review Information should be your own. Finally, as the last option, you can leave the default checked option that once your app is approved that it is automatically released to the App Store. Now that we’re finished with adding all of the details to the app listing, we can press Save and then Submit for Review. Finally, you’ll be presented with the last form that you’ll have to fill out. After you submit your app for review you’ll see the status of it in the My Apps as Waiting for review, as shown on the image below. Also, shortly after you submit your app for review you’ll get a confirmation email from iTunes Connect that your app is in review. Apple prides itself with a manual review process, which basically means it can take several days for your app to be reviewed. You’ll be notified of any issues or updates to your app status. Updating the appSince you’ll probably want to update your app at some point you’ll you’ll first need to bump the app version (from /package.json or from /quasar.conf.js > cordova > version, then rebuild the app for release. Finally, you’ll have to open it up from the Xcode and follow the same steps all over again. Once you submit for the review, you’ll have to wait for the review process again."},{"title":"UMD Starter Kit - CDN install","updated":"2018-07-23T16:37:49.868Z","permalink":"https://v0-16.quasar-framework.org/guide/embedding-quasar.html","text":"If you want to embed Quasar into your existing website project, integrating it in a progressive manner, then go for the UMD/Standalone (Unified Module Definition) version. The UMD starter kit will ask you some questions and will generate a simple HTML file that will show you how to use CDN to add Quasar: $ vue init quasarframework/quasar-starter-kit-umd <folder_name> And you’re done. Inspect index.html file that was created in the new folder and learn how you can embed Quasar. Notice the <style> and <script> tags and their order. Notice that as opposed to the Main Starter Kit, you don’t need to import anything. All components, directives and Quasar plugins are ready to be used out of the box. However, the disadvantage is that you won’t benefit from the top notch development experience provided by Quasar CLI – which allows you to simultaneously develop and build SPA, PWA, Mobile and Electron Apps. JsFiddle / CodepenYou can fork and use these links for reporting issues on Github too: Material Theme iOS Theme jsFiddle https://jsfiddle.net/rstoenescu/waugrryy/ https://jsfiddle.net/rstoenescu/7gu065yg/ Codepen https://codepen.io/rstoenescu/pen/KQRZJg https://codepen.io/rstoenescu/pen/paVpBN These links (obviously) use the Quasar UMD version. Quasar Global ObjectWhen you embed Quasar UMD into a webpage you’ll get a Quasar global Object injected: Quasar = { version, theme: 'mat', // or 'ios', based on the theme you are using from CDN // -- must match both .js and .css CDN links to point to same theme plugins, utils, // if you want to extend Quasar's components or directives components, directives, // if you want to change current icon set or Quasar I18n language // (must include CDN links so they are available first!) i18n, icons} UsageSo, after you figured out the CDN links that you need to embed into your webpages (hopefully you’ve inspected the project folder created by UMD Starter Kit), now it’s time to use Quasar. You’ll notice that all the Quasar Components, Quasar Directives and Quasar Plugins have an installation section at the top of their pages. When using UMD, you can skip this section, as it is intended only for when your project is generated from the Main Starter Kit. By using the UMD version, you’ll have all of the components, directives and Quasar plugins already installed for you. You just need to start using them. Do not use self-closing tags with the UMD version:You will notice that you won’t be able to use the self-closing tag form of any of the components. You must close all components tags. <!-- In docs, but for Main Starter Kit usage --><q-btn label=\"My Button\" /><!-- ^^^ can't use it like this on UMD --><!-- Instead, include a self-closing tag too: --><q-btn label=\"My Button\"></q-btn> Quasar ComponentsAn example. No need to install any component in UMD version. <q-btn label=\"My Button\"></q-btn> Quasar DirectivesAn example. No need to install any directives in UMD version.<div v-ripple>...</div> Quasar PluginsAn example. No need to install any plugins in UMD version. Quasar.plugins.actionSheet.create({...}) Quasar UtilsAn example. Quasar.utils.event.getEventKey(evt) Changing Quasar Icon SetAssuming you have already included the CDN link to your favorite Quasar Icon Set (unless you’re using Material Icons which is used by default), you can then tell Quasar to use it: Quasar.icons.set(Quasar.icons.fontawesome) Changing Quasar I18n LanguageAssuming you have already included the CDN link to your desired Quasar I18n Language (unless you want “en-us” language pack which is used by default), you can then tell Quasar to use it: // example setting German language,// using ISO 2 letter code:Quasar.i18n.set(Quasar.i18n.de)// example setting Portuguese (Brazil) language:Quasar.i18n.set(Quasar.i18n.ptBr) The list of available languages can be found on Github. If your desired language pack is not available yet, you can help by providing a PR. We welcome any languages!"},{"title":"Getting Started - Installation","updated":"2018-07-23T16:37:49.869Z","permalink":"https://v0-16.quasar-framework.org/guide/index.html","text":"If you want to learn what Quasar is and what it can do for you, read the Introduction to Quasar. Otherwise, let’s get started and choose how you want to use Quasar: UMD/Standalone (embed into an existing project through CDN, progressive integration) Starter Kit handled by Quasar CLI (the premium experience, recommended) Vue CLI 3 plugin Here’s a comparison: Feature UMD Starter Kit Vue CLI 3 Plugin Ability to embed into an existing project Yes - Yes, if it is Vue CLI app Progressive integration of Quasar Yes - - Ability to serve Quasar from CDN Yes - - Build SPA, PWA Yes Yes Yes Build Mobile Apps, Electron Apps Yes Yes - Dynamic RTL support for Quasar components Yes Yes Yes Generating your own website/app RTL equivalent CSS rules automatically by Quasar - Yes Yes Take advantage of Quasar CLI for a stellar developer experience - Yes - Tree Shaking - Yes Yes SFC (Single File Component - for Vue) - Yes Yes Advanced configuration through dynamic quasar.conf.js - Yes - Unit & end to end testing - Not yet Yes If you are upgrading from previous Quasar versions, check Upgrade Guide. UMD / Standalone (uses CDN)If you want to embed Quasar into your existing website project, integrating it in a progressive manner, then go for the UMD/Standalone (Unified Module Definition) version. There a helper UMD starter kit which will show you how to get started and what CSS and JS tags to include into your project. It will ask you some questions (what Quasar theme will you be using, what Quasar I18n to include, …) and it will generate a simple HTML file that will demo on how to use CDN to add Quasar: # make sure you have vue-cli globally installed# Node.js >= 8.9.0 is required.$ yarn global add vue-cli# or:$ npm install -g vue-cli# then...$ vue init quasarframework/quasar-starter-kit-umd <folder_name> And you’re done. Inspect index.html file that was created in the new folder and learn how you can embed Quasar. You may want to repeat the step above to experiment with different setups based on the answers you give out. Now head on to read about UMD/Standalone. Starter Kit (Recommended)If you want to be able to build: a SPA (Single Page Application/Website), a PWA (Progressive Web App), a Mobile App (through Cordova), an Electron App,…and benefit from a stellar experience provided by Quasar CLI, with HMR (Hot Module Reload) share the same base-code for all those modes benefit from the latest web recommended practices out of the box ability to write ES6 code benefit from Tree Shaking get your code optimized, minified, bundled in the best possible way ability to write SFC (Single File Component - for Vue)…then go for the Starter Kit way: First, we install Quasar CLI. Make sure you have Node >=8 and NPM >=5 installed on your machine. # make sure you have vue-cli globally installed$ yarn global add vue-cli# or:$ npm install -g vue-cli# Node.js >= 8.9.0 is required.$ yarn global add quasar-cli# or:$ npm install -g quasar-cli Then we create a project folder with Quasar CLI:$ quasar init <folder_name> Note that you don’t need separate starter kits if you want to build any of the options described above. This one can seamlessly handle all of them. Now head on to read about Main Starter Kit and also familiarize yourself with the Quasar CLI. Vue CLI 3 pluginMake sure you have vue-cli 3.x.x: vue --version If you don’t have a project created with vue-cli 3.x yet: vue create my-app Navigate to the newly created project folder and add the cli plugin. Before installing it, make sure to commit your current changes should you wish to revert them later. cd my-appvue add quasar It will ask you if you want the plugin to replace some existing files. It is recommended that you do it if you wish to have an example so you can quickly develop your app. Your Vue config (in package.json or vue.config.js file, depending on what you chose when you created your vue app) will also contain a quasar Object. Most important property is theme (with possible values “mat” or “ios”), which you can later change should you want."},{"title":"Introduction to the Quasar Framework","updated":"2018-07-23T16:37:49.869Z","permalink":"https://v0-16.quasar-framework.org/guide/introduction-to-quasar.html","text":"What is Quasar?Quasar (pronounced /ˈkweɪ.zɑɹ/) is an MIT licensed open-source framework (powered with Vue) that helps web developers create: Responsive Websites PWAs (Progressive Web App) Mobile Apps (Android, iOS, …) through Apache Cordova Multi-platform Desktop Apps (using Electron) Quasar allows developers to write code once and simultaneously deploy as website, PWA, Mobile App and/or Electron App using the same codebase. Design an app in record time, using a state of the art CLI and backed by well-written, very fast Quasar web components. When using Quasar, you won’t need additional heavy libraries like Hammerjs, Momentjs or Bootstrap. It’s got that covered too, and with a small footprint! Why Quasar?Because of what is offered out of the box. Follow our Twitter account for testimonials. All Platforms in One GoOne authoritative source of code for all platforms, simultaneously: responsive desktop/mobile website, PWAs (Progressive Web Apps), mobile apps (that look native) and multi-platform desktop apps (through Electron). Top class, fast web responsive componentsThere’s a component for almost every web development need out there. Each of these components is carefully crafted to offer the best possible experience to users. Quasar is designed with performance & responsiveness in mind – so the overhead of using Quasar is barely noticeable. This is an area we take special pride in. Best practices integrated by defaultDevelopers using Quasar are encouraged to follow web development best practices, and it comes embedded with many such features out of the box. HTML/CSS/JS minification, cache busting, tree shaking, sourcemapping, code-splitting & lazy loading, ES6 transpiling, linting code, accessibility features. Quasar takes care of all these and more - no configuration needed. Full RTL SupportRTL (right to left) support for both Quasar components & the developer’s own code. Developer-written website/app CSS code gets automatically converted to RTL if an RTL language pack is used. Two Themes (more to come)The framework supports two of the most commonly used themes out of the box – Material theme and iOS theme. Progressively migrate your existing projectQuasar offers a UMD (Unified Module Definition) version, which means developers can add a CSS and JS HTML tag into their existing project and they’re ready to use it. No build step is required. Unparalleled developer experience through Quasar CLIWhen using Quasar’s CLI, developers benefit from: State preserving hot-reload when making changes to app source code, no matter if it’s a website, PWA, a Mobile App (directly on a phone or on an emulator) or an Electron app. Developers simply change their code and they can watch it get updated on the fly, without the need of any page refresh. State preserving compilation error overlay. Lint-on-save with ESLint – if developers like linting their code only ES6 code transpiling Sourcemaps Changing build options doesn’t require a manual reload of the dev server Many more leading-edge developer tools and techniques Get up to speed fastThe top-class starter kit makes it easy for developers to bring an idea to reality in record time. The heavy lifting is done for the developer, not by the developer. You are free to focus on your features instead and let the boilerplate be done by Quasar. Awesome ever-growing communityWhen developers encounter a problem they can’t solve, they can visit the Quasar forum or Discord chat server. The community is there to help you. Wide platform supportGoogle Chrome, Firefox, IE11/Edge, Safari, Opera, iOS, Android, Windows Phone, Blackberry. Quasar components Internationalization (I18n)I18n is provided by default for Quasar components. If your language pack is missing it takes just 5 minutes to add it. Great documentationFinally, it’s worth mentioning the significant amount of time that is spent on writing great, bloat-free, focused, complete documentation pages so that developers can quickly pick up Quasar. There will be no room for confusion. Underlying technologiesVue, Babel, Webpack, Cordova, Electron. Except for Vue, which takes half a day to pick up and will change you forever, you are not really required to know the other technologies. Most of them are integrated and already configured for you. Get started in under a minuteHaving said this, let’s get started! You’ll be running a website or app in under a minute."},{"title":"Electron Preparation","updated":"2018-05-18T22:01:01.060Z","permalink":"https://v0-16.quasar-framework.org/guide/electron-preparation.html","text":"Before we dive in to the actual development, we need to do some preparation work. 1. Add Quasar Electron ModeIn order to develop/build a Quasar Electron app, we need to add the Electron mode to our Quasar project. What this does is that it npm installs some Electron packages and creates /src-electron folder.$ quasar mode -a electron Every Electron app has two threads: the main thread (deals with the window and initialization code – from the newly created folder /src-electron) and the renderer thread (which deals with the actual content of your app from /src). The new folder has the following structure:.└── src-electron/ ├── icons/ # Icons of your app for all platforms | ├── icon.icns # Icon file for Darwin (MacOS) platform | ├── icon.ico # Icon file for win32 (Windows) platform | └── linux-256x256.png # Icon file for Linux platform └── main-process/ # Main thread source code ├── electron-main.dev.js # Main thread code while developing; read below └── electron-main.js # Main thread code for production When you add the Quasar Electron mode, you’ll notice that a few npm packages are installed. These are Electron specific and since Electron doesn’t follow the semver notation, it’s best that you lock the installed versions. Otherwise, other developers working on the same project may end up using on different Electron version – room for trouble. Electron makes releases quite often so features are always subject to change. Electron-main.dev.jsThis file (/src-electron/main-process/electron-main.dev.js) is used specifically for development and is used to install dev-tools. Usually it should not have to be modified, but can be used to extend your development needs. After it sets up dev-tools it imports the electron-main.js which is the place you’ll make most (if not all) of your changes. A note for Windows UsersIf you run into errors during npm install about node-gyp, then you most likely do not have the proper build tools installed on your system. Build tools include items like Python and Visual Studio. Fortunately, there are a few packages to help simplify this process. The first item we need to check is our npm version and ensure that it is not outdated. This is accomplished using npm-windows-upgrade. If you are using yarn, then you can skip this check. Once that is complete, we can then continue to setup the needed build tools. Using windows-build-tools, most of the dirty work is done for us. Installing this globally will in turn setup Visual C++ packages, Python, and more. At this point things should successfully install, but if not then you will need a clean installation of Visual Studio. Please note that these are not problems with Quasar, but they are related to NPM and Windows. 2. Start DevelopingIf you want to jump right in and start developing, you can skip the previous step with “quasar mode” command and issue:$ quasar dev -m electron -t [mat|ios] This will add Electron mode automatically, if it is missing.It will open up an Electron window which will render your app along with Developer Tools opened side by side."},{"title":"Electron Static Assets","updated":"2018-05-18T22:01:01.060Z","permalink":"https://v0-16.quasar-framework.org/guide/electron-static-assets.html","text":"Please read about Handling Assets first, which applies to the renderer process. However, when we deal with Electron then Quasar CLI offers a handy __static variable in addition. Statics can be consumed by both the main process and renderer process, but since the paths change when building for production (due to packaging), then usage with fs and other modules that need a full path can be a little tricky. So __statics can come into play. On the subject of using dirname & filenameSince the main process is bundled using webpack, the use of __dirname and __filename will not provide an expected value in production. Referring to the File Tree, you’ll notice that in production the electron-main.js is placed inside the dist/electron-* folder. Based on this knowledge, use __dirname & __filename accordingly. app.asar└─ dist └─ electron-* ├─ statics/ ├─ js/... ├─ node_modules/ ├─ index.html ├─ package.json └─ electron-main.js Static assets with fs, path and __staticsLet’s say we have a static asset that we need to read into our application using fs, but how do we get a reliable path, in both development and production, to the statics/ folder? Quasar provides a global variable named __statics that will yield a proper path to it. Here’s how we can use it to read a simple text file in both development and production. Let’s assume we have a file called someFile.txt in /src/statics. Now, in main or renderer process, we can access it like this:// main or renderer processimport fs from 'fs'import path from 'path'let fileContents = fs.readFileSync(path.join(__statics, '/someFile.txt'), 'utf8')"},{"title":"Configuring PWA","updated":"2018-07-23T16:37:49.870Z","permalink":"https://v0-16.quasar-framework.org/guide/pwa-configuring-pwa.html","text":"We’ll be using Quasar CLI to develop and build a PWA. The difference between building a SPA, Mobile App, Electron App or a PWA is simply determined by the “mode” parameter in “quasar dev” and “quasar build” commands. InstallationIn order to build a PWA, we first need to add the PWA mode to our Quasar project:$ quasar mode -a pwa If you want to jump right in and start developing, you can skip the “quasar mode” command and issue:$ quasar dev -m pwa This will add PWA mode automatically, if it is missing. Service WorkerAdding PWA mode to a Quasar project means a new folder will be created: /src-pwa, which contains PWA specific files:.└── src-pwa/ ├── register-service-worker.js # App-code *managing* service worker └── custom-service-worker.js # Optional custom service worker file You can freely edit these files. Notice a few things: Both files are embedded ONLY for production builds, while the development build skips them. “register-service-worker.js” is automatically imported into your app (like any other /src file). It registers the service worker (created by Workbox or your custom one, depending on workbox plugin mode – quasar.conf.js > pwa > workboxPluginMode) and you can listen for Service Worker’s events. You can use ES6 code. “custom-service-worker.js” will be your service worker file ONLY if workbox plugin mode is set to “InjectManifest” (quasar.conf.js > pwa > workboxPluginMode: ‘InjectManifest’). Otherwise, Workbox will create a service-worker file for you. During development, a no-op service worker will be created which plays nicely with HMR (Hot Module Reload). Its sole purpose is to override any possible previous registered service worker. It makes sense to run Lighthouse tests on production builds only. Quasar.conf.jsThis is the place where you can configure Workbox’s behavior and also tweak your manifest.json. pwa: { // workboxPluginMode: 'InjectManifest', // workboxOptions: {}, manifest: { // ... }} More information: Workbox Webpack Plugin, Workbox. Configuring Manifest FileThe Manifest file is generated by Quasar CLI with a default configuration for it. You can however tweak this configuration from /quasar.conf.js. Example taken from Quasar Play’s quasar.conf.js:pwa: { // workboxPluginMode: 'InjectManifest', // workboxOptions: {}, manifest: { name: 'Quasar Play', short_name: 'Quasar-Play', description: 'Quasar Framework Showcase', icons: [ { 'src': 'statics/icons/icon-128x128.png', 'sizes': '128x128', 'type': 'image/png' }, { 'src': 'statics/icons/icon-192x192.png', 'sizes': '192x192', 'type': 'image/png' }, { 'src': 'statics/icons/icon-256x256.png', 'sizes': '256x256', 'type': 'image/png' }, { 'src': 'statics/icons/icon-384x384.png', 'sizes': '384x384', 'type': 'image/png' }, { 'src': 'statics/icons/icon-512x512.png', 'sizes': '512x512', 'type': 'image/png' } ], display: 'standalone', orientation: 'portrait', background_color: '#ffffff', theme_color: '#027be3' }} Please read about the manifest config before diving in. IMPORTANTNote that you don’t need to edit your index.html file (generated from /src/index.template.html) to link to the manifest file. Quasar CLI takes care of embedding the right things for you. PWA Checklisthttps://developers.google.com/web/progressive-web-apps/checklist IMPORTANTDo not run Lighthouse on your development build. It is not optimized and does not contain a true Service Worker."},{"title":"What is a PWA","updated":"2018-07-23T16:37:49.870Z","permalink":"https://v0-16.quasar-framework.org/guide/pwa-introduction.html","text":"A Progressive Web App (PWA) is a web app that uses modern web capabilities to deliver an app-like experience to users. These apps meet certain requirements (see below), are deployed to web servers and accessible through URLs (on HTTPS protocol). This can work in conjunction with Cordova to provide a multiple deploy targets for all your users. Quasar CLI allows you to deploy your app as a PWA as well as a Mobile app and take advantage of both channels. What is RequiredTo be considered a Progressive Web App, your app must be: Progressive - Work for every user, regardless of browser choice, because they are built with progressive enhancement as a core tenet. Responsive - Fit any form factor, desktop, mobile, tablet, or whatever is next. Connectivity independent - Enhanced with service workers to work offline or on low quality networks. App-like - Use the app-shell model to provide app-style navigation and interactions. Fresh - Always up-to-date thanks to the service worker update process. Safe - Served via HTTPS to prevent snooping and ensure content has not been tampered with. Discoverable - Are identifiable as “applications” thanks to W3C manifests and service worker registration scope allowing search engines to find them. Re-engageable - Make re-engagement easy through features like push notifications. Installable - Allow users to “keep” apps they find most useful on their home screen without the hassle of an app store. Linkable - Easily share via URL and not require complex installation. More information available on Addy Osmani’s article about PWA. Manifest FileAn app manifest file describes the resources your app will need. This includes your app’s displayed name, icons, as well as splash screen. Quasar CLI configures this for you, but you can override any property from within /quasar.conf.js. Learn how by visiting the Configure PWA documentation page. More information on the Manifest file can be read by accessing:https://developer.mozilla.org/en-US/docs/Web/Manifest Service WorkerThe Service worker provides a programmatic way to cache app resources. Be it JavaScript files or JSON data from a HTTPS request. The programmatic API allows developers to decide how to handle caching and provides a much more flexible experience than other options. More information on the Service Worker API can be read by accessing:https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API NOTEA full-blown Service Worker is not available during development due to the fact that it is not compatible with HMR (Hot Module Reload). So, as opposed to production code, development has a very simple Service Worker that just invalidates cache. Take a look at /src-pwa for the two service workers used. You can change these files to meet your needs."},{"title":"Quasar CLI","updated":"2018-07-23T16:37:49.871Z","permalink":"https://v0-16.quasar-framework.org/guide/quasar-cli.html","text":"The Quasar CLI allows you to create new projects in no time, by generating a base application, filled with everything you need to begin working on your application. It does most of the heavy-lifting, so you need not concern yourself with the redundant tasks of building the application. You only need Quasar CLI if using the Main Starter Kit. If you want the UMD version, you won’t be using it. # Node.js >= 8.9.0 is required.$ yarn global add quasar-cli# or:$ npm install -g quasar-cli Familiarize yourself with the list of commands:$ quasar ... Commands init Create a project folder dev Start a dev server for your App build Build your app for production clean Clean all build artifacts new Quickly scaffold page/layout/component/... vue file mode Add/remove Quasar Modes for your App info Display info about your machine and your App serve Create an ad-hoc server on App distributables help Displays this message See help for any command:$ quasar [command name] --help init (Create Project Folder)Initializes an App folder with a starter boilerplate.$ quasar init <folder-name> You’ll need @vue/cli and @vue/cli-init globally installed, or just vue-cli. info (Package Versions)The Quasar CLI is equipped with a stable combination of multiple NPM build packages (Webpack, Vue, etc) which gets updated frequently after heavy testing. In order for you to see what versions of Node, NPM, Quasar CLI, Quasar, Vue, Webpack, Cordova, Babel and many more, issue this command in a Quasar project folder:$ quasar info dev (Development Server)$ quasar dev -h Description Starts the app in development mode (hot-code reloading, error reporting, etc) Usage $ quasar dev -p <port number> Options --theme, -t App theme (default: mat) --mode, -m App mode [spa|pwa|cordova|electron] (default: spa) --port, -p A port number on which to start the application --hostname, -H A hostname to use for serving the application --help, -h Displays this message Only for Cordova mode: --target, -T (required) App target [android|ios|blackberry10|browser|osx|ubuntu|webos|windows] --emulator, -e (optional) Emulator name Example: iPhone-7, iPhone-X The Quasar development server allows you to develop your App by compiling and maintaining code in-memory. A web server will serve your App while offering hot-reload out of the box. Running in-memory offers faster rebuilds when you change your code. Hot Reload is much more than just refreshing your browser when code changes. It skips the refresh and updates your code on the fly, while maintaining your App’s state (like your Vue’s model data). Please note that there are cases when this is impossible, so the dev webserver will simply refresh your browser. (Always ensure you are running only one instance of Quasar CLI at a time, otherwise Hot-Reload and other stuff will break!) Based on what you want to develop, you can start the development server by using “quasar dev” command as follows: # Developing a SPA$ quasar dev# ...or$ quasar dev -m spa# Developing a PWA$ quasar dev -m pwa# Developing a Mobile App (through Cordova)$ quasar dev -m cordova -T [android|ios]# Developing an Electron App$ quasar dev -m electron However, there are two themes available: Material Design (‘mat’) and iOS (‘ios’). In order for specifying a specific theme, add the ‘-t’ parameter to the above commands: # Material Design$ quasar dev -t mat# iOS theme$ quasar dev -t ios If you wish to change the hostname or port serving your App you have 3 options: Edit ‘/quasar.conf.js’: devServer: { host: '...', port: ...} Through ‘-H’ (hostname) and ‘-p’ (port) command options. If this is a one time thing, specify the hostname and/or port as an environment variable:$ PORT=3000 quasar dev$ HOSTNAME=1.1.1.14 quasar dev If there appears to be an issue with hot reload, you can try two fixes: Change the permissions for the project folder with sudo chown -R username: . or run the dev server with root privileges sudo quasar dev build / clean (Build App for Production)$ quasar build -h Description Builds distributables of your app. Usage $ quasar build -p <port number> Options --theme, -t App theme (default: mat) --mode, -m App mode [spa|pwa|cordova|electron] (default: spa) --target, -T App target - Cordova (default: all installed) [android|ios|blackberry10|browser|osx|ubuntu|webos|windows] - Electron with default \"electron-packager\" bundler (default: yours) [darwin|win32|linux|mas|all] - Electron with \"electron-builder\" bundler (default: yours) [darwin|mac|win32|win|linux|all] --debug, -d Build for debugging purposes --help, -h Displays this message ONLY for Electron mode: --bundler, -b Bundler (electron-packager or electron-builder) [packager|builder] --arch, -A App architecture (default: yours) - with default \"electron-packager\" bundler: [ia32|x64|armv7l|arm64|mips64el|all] - with \"electron-builder\" bundler: [ia32|x64|armv7l|arm64|all] The Quasar CLI can pack everything together and optimize your App for production. It minifies source code, extracts vendor components, leverages browser cache and much more. # build for production$ quasar build# build for production with specific theme$ quasar build -t mat$ quasar build -t ios$ quasar build -m pwa -t mat You can also clean up the build assets:$ quasar clean new (Generating Components, Pages, Layouts, Vuex Store)$ quasar new -h Description Quickly scaffold a page/layout/component/store module. Usage $ quasar new [p|page] <page_file_name> $ quasar new [l|layout] <layout_file_name> $ quasar new [c|component] <component_file_name> $ quasar new plugin <plugin_name> $ quasar new [s|store] <store_module_name> # Examples: # Create src/pages/MyNewPage.vue: $ quasar new p MyNewPage # Create src/pages/MyNewPage.vue and src/pages/OtherPage.vue: $ quasar new p MyNewPage OtherPage # Create src/layouts/shop/Checkout.vue $ quasar new layout shop/Checkout.vue Options --help, -h Displays this message This command is simply a helper in order to quickly scaffold a page/layout/component/vuex store module. You are not required to use it, but can help you when you don’t know how to start. mode (PWA, Cordova, Electron)$ quasar mode -h Description Add/Remove support for PWA / Cordova / Electron modes. Usage $ quasar mode -r|-a pwa|cordova|electron Options --add, -a Add support for mode [pwa|cordova|electron] --remove, -r Remove support for mode [pwa|cordova|electron] --help, -h Displays this message When you use the Main Starter Kit, you can build SPA (Single Page Website/Application), PWA (Progressive Web App), Mobile App (through Cordova), and/or Electron Apps. When you develop for PWA, Cordova or Electron, you need these modes installed. If you issue “quasar dev” or “quasar build” they will automatically be installed. These modes will add a “src-*” folder into your project with very specific code for it: Folder Mode Description src-pwa pwa Contains the Service Worker file that you can tweak. src-cordova cordova Is a Cordova project folder that will be using your ‘src’ as content. Tweak Cordova config, add/remove platforms, splash screens, Cordova plugins and so on from this folder. Do NOT touch “src-cordova/www” folder though as it will get overwritten at every build. src-electron electron Has code for the main Electron thread. The renderer thread will be your app in ‘src’. If for some reason you decide you don’t need a mode, you can remove it. This will permanently delete the respective “src-*” folder.$ quasar mode --remove pwa serve (Serve Static-Content Folder)$ quasar serve -h Description Create an ad-hoc http(s) server on a specified folder. This command has been deprecated in favor of using the \"http-server\" NPM package: https://www.npmjs.com/package/http-server Install it by typing: \"yarn global add http-server\" or \"npm install -g http-server\" Check its usage by visiting the link above. Basic usage is: $ http-server [path] [options] When building a SPA or PWA, the distributable folder can be served by any static webserver. To test it out (assuming you don’t have a specific publicPath or not using Vue Router “history” mode), you can use the “http-server” npm package. Or you can build your own server. Here are some examples:// when using default Vue Router \"hash\" modeconst express = require('express'), serveStatic = require('serve-static'), port = process.env.PORT || 5000const app = express()app.use(serveStatic(...path-to-dist...))app.listen(port) // when using Vue Router \"history\" modeconst express = require('express'), serveStatic = require('serve-static'), history = require('connect-history-api-fallback'), port = process.env.PORT || 5000const app = express()app.use(history())app.use(serveStatic(...path-to-dist...))app.listen(port) If you need URL rewrites of API, or simply put you want to proxy your API requests, then you can use “http-proxy-middleware” package:// add this to one of the two previous examples:const proxy = require('http-proxy-middleware')// ...app.use('/api', proxy({ '/api': { target: `http://my-api.com:5050`, pathRewrite: {\"^/api\" : \"\"} }}))// then app.listen(...) Finally, run one of these files:$ node my-server.js"},{"title":"Troubleshooting and Tips","updated":"2018-05-18T22:01:01.060Z","permalink":"https://v0-16.quasar-framework.org/guide/electron-troubleshooting-and-tips.html","text":"Read & Write Local FilesOne great benefit of using Electron is the ability to access the user’s file system. This enables you to read and write files on the local system. To help avoid Chromium restrictions and writing to your application’s internal files, make sure to take use of electron’s APIs, specifically the app.getPath(name) function. This helper method can get you file paths to system directories such as the user’s desktop, system temporary files, etc. We can use the userData directory, which is reserved specifically for our application, so we can have confidence other programs or other user interactions should not tamper with this file space. import path from 'path'import { remote } from 'electron'const filePath = path.join(remote.app.getPath('userData'), '/some.file') Debugging Main ProcessWhen running your application in development you may have noticed a message from the main process mentioning a remote debugger. Ever since the release of electron@^1.7.2, remote debugging over the Inspect API was introduced and can be easily accessed by opening the provided link with Google Chrome or through another debugger that can remotely attach to the process using the default port of 5858, such as Visual Studio Code. ┏ Electron ------------------- Debugger listening on port 5858. Warning: This is an experimental feature and could change at any time. To start debugging, open the following URL in Chrome: chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:5858/22271e96-df65-4bab-9207-da8c71117641┗ ----------------------------"},{"title":"Opening Your Dev Server to the Public","updated":"2018-05-18T22:01:01.062Z","permalink":"https://v0-16.quasar-framework.org/guide/opening-dev-server-to-public.html","text":"At some point you may want to show someone else the project you’ve been working on. Fortunately, there is a simple CLI tool to accomplish this. Ngrok creates a tunnel to your dev server and (by default) generates a hexadecimal internet address on the ngrok server to offer to your clients or anyone special you’d like to show your work to. IMPORTANTOpening a dev server to the public constitutes security risks. Be absolutely cautious when using tools like this. This tip is not intended for the general public. When you’ve finished with your demonstration or testing, make sure to stop ngrok. This will prevent any unwanted access of your computer through ngrok. Getting started Download and install ngrok here.(Please note that the ngrok executable file does not need to be placed in or run from inside your cordova folder. When on a mac it’s best to place the ngrok executable file inside /usr/local/bin to be able to run it globally.) Start your Dev server $ quasar dev Create your ngrok connection $ ngrok http 8080# In case your development server doesn't run on port 8080 you need to change the number to the correct port ngrok shows the url in the command line when it started. Tunnel Status onlineVersion 2.0/2.0Web Interface http://127.0.0.1:4040Forwarding http://92832de0.ngrok.io -> localhost:8080Forwarding https://92832de0.ngrok.io -> localhost:8080Connnections ttl opn rt1 rt5 p50 p90 0 0 0.00 0.00 0.00 0.00 Please be careful as the ‘Forwarding’ URL will be accessible to anyone until this connection is closed again. Inspecting trafficWhen running ngrok, visit http://localhost:4040 to inspect the traffic. This tool allows for custom domains, password protection and a lot more. If you require further assistance, please refer to the ngrok docs for more information."},{"title":"PWA Build Commands","updated":"2018-05-18T22:01:01.062Z","permalink":"https://v0-16.quasar-framework.org/guide/pwa-build-commands.html","text":"Quasar CLI makes it incredibly simple to develop or build the final distributables from your source code. Developing$ quasar dev -m pwa# ..or the longer form:$ quasar dev --mode pwa# with a specific Quasar theme:$ quasar dev -m pwa -t ios IMPORTANTDo not run Lighthouse on your development build. It is not optimized and does not contain a true Service Worker. Building for Production$ quasar build -m pwa# ..or the longer form:$ quasar build --mode pwa# with a specific Quasar theme:$ quasar build -m pwa -t ios PWA Checklisthttps://developers.google.com/web/progressive-web-apps/checklist IMPORTANTDo not run Lighthouse on your development build. It is not optimized and does not contain a true Service Worker."},{"title":"Quasar Roadmap","updated":"2018-07-23T16:37:49.871Z","permalink":"https://v0-16.quasar-framework.org/guide/quasar-roadmap.html","text":"Next version is v1.0, with four main focus points: SSR (Server Side Rendering) Quasar Mode Quasar + Nuxt starter kit Notable improvements to the form components Total documentation website revamp, using Quasar SSR. Better “view source” functionality, with ability to fork and play each example on JsFiddle. Out of the box Typescript support (can be added now too) Notable features on the roadmap for longer term (some might end up in v1.0): Chrome (+ Firefox) extension support Tipster component List Item Sliding with Actions component Virtual Lists component Quasar needs your backing in order to speed up development and offer even better support. Please take a look on the Patreon Campaign. If invoices are needed for bigger amounts, please contact us by email ([email protected]). Every cent really counts and helps us spend more time on Quasar."},{"title":"Quasar Framework Contributing Guide","updated":"2018-05-18T22:01:01.064Z","permalink":"https://v0-16.quasar-framework.org/guide/quasar-contribution-guide.html","text":"The Quasar team is really excited when people help by contributing to Quasar Framework. It’s what the FLOSS community is all about! There are lots of features waiting for someone to write them and make the Quasar experience even better. Check Github or contact Razvan Stoenescu through Discord chat/email. Before submitting your contribution though, please make sure to take a moment and read through the contributing guidelines and also the code of conduct. You can also help with the documentation. If you catch a mistake or want to add a few lines to a page or write new pages, use the link at the end of each page of this website (specifically the Suggest an edit on Github link). Finally, if you want, you can leave a buck for coffee from time to time. Quasar needs some financial backing to evolve. Read more here. Github Repositories Quasar Framework Quasar CLI Quasar Starter Kit Quasar Play Documentation Website Please use the appropriate Github repo to report issues. See “Github Repositories” above. For example, a bug related to CLI should be reported to the CLI repo, one related to build issues to Quasar Starter Kit repo and so on."},{"title":"Upgrade Guide","updated":"2018-07-23T16:37:49.872Z","permalink":"https://v0-16.quasar-framework.org/guide/quasar-upgrade-guide.html","text":"We’ll cover how to upgrade to a new Quasar version in your project, both for UMD and using the Starter Kit. Then we’ll go on to discuss how you can migrate v0.15 to v0.16 and your pre v0.15 project to v0.15+. Upgrading to a newer Quasar versionThis applies when upgrading from v0.15+ to a newer Quasar version, including v0.16. IMPORTANTQuasar v0.15+ requires Node.js version 8.9.0 or greater UMDSimply replace the version string in all the CSS and JS tags that refer to Quasar to the newer version. Starter KitAs you may have noticed, the only dependency in your project (unless you’ve also installed a linter or your own deps) is quasar-cli. All you need is to update this dependency. $ yarn add --dev quasar-cli@latest# or:$ npm install --save-dev quasar-cli@latest Quasar CLI is installed both globally and locally. When you issue a Quasar command, the global installation defers to the project locally installed Quasar CLI. This allows you to skip writing npm scripts in your package.json (for Quasar commands), and also it allows you to run different Quasar versions in multiple projects. Watch for Quasar CLI version. It’s not the same thing as Quasar version. Type $ quasar info. All you need to know is that the major and minor part of Quasar CLI version matches Quasar version. So for example installing latest Quasar CLI v0.15.x will ensure you are using latest Quasar v0.15.x. While working on v0.15.x, no breaking changes will occur, so you are safe (& recommended) to upgrade to latest Quasar CLI as it’s released. CaveatSometimes after you npm install a package, or even update current packages, might screw things up. You’ll get errors that some packages are missing and you need to install them. In such cases, delete node_modules and package-lock.json and npm install again.Same goes for Yarn. In case you get errors, delete node_modules and yarn.lock then install again. Upgrading v0.15 to v0.16The difference between Quasar v0.15.x and v0.16 is minimal. No big breaking changes as you can see below. The only reason for bumping Quasar’s version is to maintain consistency (same major + minor version) with Quasar CLI (which got an important update: webpack 4, babel 7, Workbox, electron-builder support, ionicons v4 and many more). Upgrading from v0.15.x should be seamless if you are using Quasar CLI – which will guide you to do some minor changes to your project folder. Note that Ionicons v4 has breaking changes, so if you are using it in your project, then you need to update each such icon to its new name. If you face any problems, there is probably something conflicting in your npm modules. It is either babel, webpack or eslint. The console messages will tell you more about what is wrong. Remember you’ll be using Webpack 4, so all your webpack plugins must be compatible with it. For example, you need to upgrade to a newer eslint-loader, babel-eslint etc package if you already have it in your package.json as dev dependency. If you’re using ESLint, make sure you have these in your package.json (minimum version required):\"babel-eslint\": \"^8.2.1\",\"eslint\": \"^4.18.2\",\"eslint-config-standard\": \"^11.0.0\",\"eslint-friendly-formatter\": \"^4.0.1\",\"eslint-loader\": \"^2.0.0\",\"eslint-plugin-import\": \"^2.9.0\",\"eslint-plugin-node\": \"^6.0.1\",\"eslint-plugin-promise\": \"^3.7.0\",\"eslint-plugin-standard\": \"^3.0.1\",\"eslint-plugin-vue\": \"^4.3.0\", If you are seeing babel issues when you run quasar dev, then you have probably installed a package that is using babel-core instead of @babel/core - such as cypress-vue-unit-test. To find out which one it is, run: npm ls babel-core and then remove the offending source. # cd into project folder$ rm yarn.lock # or: package-lock.json (if installed through npm)$ rm -rf node_modules/$ yarn global add quasar-cli@latest # or: npm install --global quasar-cli@latest$ yarn add --dev quasar-cli@latest # or: npm install --save-dev quasar-cli@latest$ yarn # or: npm install Breaking Changes: QIcon: removed “mat” & “ios” props for performance reasons (use :name="$q.theme === 'mat' ? val : otherVal" instead) Removed utils > dom > viewport() method (use window.innerHeight/innerWidth instead) Updated Quasar ionicons set to Ionicons v4 – compatible with [email protected] Upgrading pre v0.15 to Quasar v0.15+There’s been A LOT of work done for v0.15. The Quasar CLI has been rewritten from scratch to allow for a stellar development experience (Mobile App developers and Electron will fall in love with it!). Only one starter kit is required in order to handle websites, PWAs, Mobile Apps and Electron Apps. Building any of those is a matter of just adding a parameter to the dev/build command. Furthermore, you can now use an UMD/standalone version of Quasar to embed in an existing project. No build step is required. Take some time to read all “Guide” pages once again. It will help you understand the true power of Quasar v0.15+ and what you can do with it. So, what is new and what has changed? Everything has been polished. The full list of enhancements and new features is exhausting. We’ll try to cover the major parts only. This is just a guide to get you started so that you know where to look in docs for things that have changed. First step - when using starter kitFirst we make sure we update the globally installed Quasar version (needs to be at least v0.15). Then we create a new project folder:# Node.js >= 8.9.0 is required.$ yarn global add quasar-cli@latest# or:$ npm install -g quasar-cli@latest# Then we create a project folder with Quasar CLI:$ quasar init <folder_name> Observe the new project structure. Start to port out files to the new project folder, taking into account the far superior structure. Using the new starter kit will allow you to take advantage of future seamless upgrades! In any case, do not simply copy your /src folder over to the new starter kit. Build configuration no longer requiredYou’ll notice the new starter kit doesn’t provide a /build or /config folders. They are no longer required. Everything can be easily configured from /quasar.conf.js now. You don’t need to know Webpack. More Info. No main.js?Yes. It’s no longer there because you don’t need it anymore. For initialization code and importing libraries into your website/app, read about App Plugins. Importing Components/Directives/etcYou’re no longer required to import Quasar components and directives anywhere in your app. Simply configuring /quasar.conf.js in framework Object will suffice. More Info. Quasar Plugins?Yes, this refers to Action Sheet, Notify (replacement of Toast and Alert), LocalStorage/SessionStorage and so on. They are available globally or under the Vue $q Object injection, and need to be specified in /quasar.conf.js > framework > plugins in order for them to be available. Revamps Typography Flex CSS gutter classes QLayout & co. You’ll love the new features! Be sure to check this out. Major improvements in syntax and flexibility. Some breaking changes, like slots no longer being used. QBtn (new features!) QToolbar (small update regarding buttons) QBreadcrumbs (powerful component instead of just CSS) QPagination (major improvements) QCollapsible (new powerful features!) QTable (replacing QDataTable – full customization now!) Lists & List Items – more options, better control, “dark” theme QTree (the most advanced you’ll ever see and need!) ActionSheet (now as a Quasar Plugin & QActionSheet component too! – has new features too) Dialog (now as a Quasar Plugin & QDialog component too for unlimited flexibility! – has new features too) QModal - Easier to use than ever! Now with full v-model support. QPopover & QTooltip - new animation, ability to close it without the need of a Vue reference (through v-close-overlay directive), full support for v-model now Loading (now as a Quasar Plugin) QCarousel - Easier to use. Fully customizable! Transitions - No need for QTransition anymore! Minimum overhead, better performance. QAlert - new features QChat - new features TouchSwipe, TouchHold and TouchPan - Much better implementation, more control. Read about these directive’s modifiers. AppFullscreen & AppVisibility - Now as Quasar Plugins, with reactive state properties that can be used in Vue watchers QUploader - new features & design Also notice QInlineDatetime has been renamed to QDatetimePicker. New Components or Features Spacing CSS classes QTable - It’s on the Revamps list too, but it sure deserves a place here too. Prepare for next level Data Tables, now fully customizable! Check out the demo too. QEditor - Quasar’s own WYSIWYG approach! This alone would deserve its own section. Notify - A merge between Toast and Alert, with flexible positioning and awesome animations. QColor - Color Picker! New button types: QBtnGroup and QBtnDropdown QBtnToggle - A radio-like component, but with buttons I18n for Quasar ComponentsBe sure to check out the Internationalization for Quasar Components. Icon PacksYou can now tell Quasar to use one of Fontawesome, Ionicons, MDI or Material Icons for its components. You are no longer required to include Material Icons. You can use any of these packs as default. Also, small change for Fontawesome icons:<!-- pre v0.15 --><q-icon name=\"fa-paypal fab\" /><!-- v0.15+ --><!-- Copy paste fontawesome icon class as it's in fontawesome docs now --><q-icon name=\"fab fa-paypal\" /> Vue Prototype InjectionsYou can use $q injection for convenience, accessing Quasar Theme, Quasar I18n, Quasar Platform, and many more. Quasar Plugins add functionality to it. Read doc page, especially if you build Cordova or Electron apps. What has been dropped? Global Event Bus (Events) – no longer needed. Use Vue root component events instead. More Info QFixedPosition – now replaced by a more powerful QPageSticky QSideLink – no longer required! Simply use a QItem or whatever component you want and bind an @click="$router.push(...)" to it. Alert and Toast as methods. They’ve been merged into Notify. HTML Table. You can however check code from v0.14 and embed it yourself into your app. Image Gallery - no longer needed. The new QCarousel is so powerful that you’ll immediately see the benefit of switching to it. QTransition - no longer required. Simply use Vue’s <transition> (or <transition-group>) instead. More Info QDatetimeRange - it’s so easy to simply write two QDatetime side by side that this component is simply not required anymore; this allows you full flexibility too. New LayoutThe following upgrade guide for QLayout barely scratches the surface, but it’s a starting point. <!-- v0.14 --><q-layout ref=\"layout\" view=\"hHr LpR lFf\" :right-breakpoint=\"1100\"> <!-- Header --> <q-toolbar slot=\"header\"> <q-btn flat @click=\"$refs.layout.toggleLeft()\"> <q-icon name=\"menu\" /> </q-btn> <q-toolbar-title> Layout Header <span slot=\"subtitle\">Optional subtitle</span> </q-toolbar-title> <q-btn flat @click=\"$refs.layout.toggleRight()\"> <q-icon name=\"menu\" /> </q-btn> </q-toolbar> <!-- Navigation --> <q-tabs slot=\"navigation\"> <q-route-tab slot=\"title\" icon=\"view_quilt\" to=\"/test-layout/about\" replace hide=\"icon\" label=\"About\" /> <q-route-tab slot=\"title\" icon=\"view_day\" to=\"/test-layout/toolbar\" replace hide=\"icon\" label=\"Toolbar\" /> <q-route-tab slot=\"title\" icon=\"view_day\" to=\"/test-layout/tabs\" replace label=\"Tabs\" /> <q-route-tab slot=\"title\" icon=\"input\" to=\"/test-layout/drawer\" replace label=\"Drawer\" /> </q-tabs> <!-- Left Side Panel --> <div slot=\"left\"> <q-list no-border link inset-separator> <q-list-header>Essential Links</q-list-header> <q-side-link item to=\"/docs\"> <q-item-side icon=\"school\" /> <q-item-main label=\"Docs\" sublabel=\"quasar-framework.org\" /> </q-side-link> </q-list> </div> <!-- Right Side Panel --> <div slot=\"right\"> Right Side of Layout </div> <!-- sub-routes get injected here: --> <router-view /> <!-- Footer --> <q-toolbar slot=\"footer\"> <q-toolbar-title> Layout Footer </q-toolbar-title> </q-toolbar></q-layout> We upgrade it to v0.15+. Notice that in order for us to place navigation tabs on header (for Material) and on Footer (for iOS), we also write a NavTabs component. Notice no slots, no QSideLink, “flat round dense” buttons, v-model on left/right drawers, QLayout* components:<!-- layout component --><q-layout ref=\"layout\" view=\"hHr LpR lFf\"> <!-- Header --> <q-layout-header> <q-toolbar> <q-btn flat round dense icon=\"menu\" @click=\"leftSide = !leftSide\" /> <q-toolbar-title> Layout Header <span slot=\"subtitle\">Optional subtitle</span> </q-toolbar-title> <q-btn flat round dense icon=\"menu\" @click=\"rightSide = !rightSide\" /> </q-toolbar> <!-- Navigation for Material theme --> <nav-tabs v-if=\"$q.theme === 'mat'\" /> </q-layout-header> <!-- Left Side Panel --> <q-layout-drawer v-model=\"leftSide\" side=\"left\"> <q-list no-border link inset-separator> <q-list-header>Essential Links</q-list-header> <q-item to=\"/docs\"> <q-item-side icon=\"school\" /> <q-item-main label=\"Docs\" sublabel=\"quasar-framework.org\" /> </q-item> </q-list> </q-layout-drawer> <!-- Right Side Panel --> <q-layout-drawer v-model=\"rightSide\" side=\"right\" :breakpoint=\"1100\"> Right Side of Layout </q-layout-drawer> <!-- sub-routes get injected here: --> <q-page-container> <router-view /> </q-page-container> <!-- Footer --> <q-layout-footer> <!-- Navigation for iOS theme --> <nav-tabs v-if=\"$q.theme === 'ios'\" /> ... </q-layout-footer></q-layout><!-- nav-tabs component --><q-tabs> <q-route-tab slot=\"title\" icon=\"view_quilt\" to=\"/test-layout/about\" replace hide=\"icon\" label=\"About\" /> <q-route-tab slot=\"title\" icon=\"view_day\" to=\"/test-layout/toolbar\" replace hide=\"icon\" label=\"Toolbar\" /> <q-route-tab slot=\"title\" icon=\"view_day\" to=\"/test-layout/tabs\" replace label=\"Tabs\" /> <q-route-tab slot=\"title\" icon=\"input\" to=\"/test-layout/drawer\" replace label=\"Drawer\" /></q-tabs> Form ComponentsIn previous versions you would listen for @change event to detect changes. Now you can listen to @input for immediate changes or @change for lazy update. Vue v-model.lazy support is a pending change, so until then you can use the equivalent form (details below). <!-- QInput example --><!-- same as listening for @input --><q-input v-model=\"myModel\" /><!-- listening for lazy update --><q-input :value=\"myModel\" @change=\"val => { myModel = val }\" /> You’ll notice all form components have been polished. Also, you’ll be pleasantly surprised by new properties. To name just a few: “hide-underline”, “inverted-light”, “dark” or “warning” (for highlighting a warning state). Prior to v0.15, form components had a default margin. This was removed to allow easier customization. You can now use the new Spacing CSS classes to do it. QCheckbox now supports an indeterminate state as well. You can specify a value for “true”/“false”/“indeterminate” states, so it no longer operates with Booleans (or Arrays) only. QDatetime now doesn’t require the “Set” button when using Popovers. Clicking on a date will simply select it and close the popover. QChipsInput (& QChips) have new props that allow for better customization now. Using PromisesModals, Popovers, Tooltips, Layout Drawer, Dialog, Notify (just to name a few) now use Promises instead of taking a callback parameter. This allows you to take advantage of async/await and simplifies your code. methods: { async showNotify () { await this.$q.dialog('Some dialog...') console.log('Dialog has been closed') }} Vue refs no longer necessary for a lot of componentsYou were also used to using Vue refs for a few components (Layout left/right drawer, Modals, …). This is no longer necessary. You can use a “v-model” instead to show (open) / hide (close) them. This wasn’t quite possible pre v0.15 because you needed for them to close in order to, as an example, navigate away. Now it’s no longer needed, so a Boolean scoped variable will suffice. Some components need .native modifier for events nowSome components, like QItem or QCard & co now need the .native modifier for binding to native DOM events like click. A general rule is: if @click is not mentioned in the component’s docs Vue Events section, then you need to use the native modifier. <!-- prior to v0.15 --><q-item @click=\"...\">....</q-item><!-- v0.15+ way: --><q-item @click.native=\"...\">...</q-item> A few Quasar components were of functional type. These pass native events right through, so there’s no need to add the native modifier. But during a thorough benchmarking session it turned out having these as regular components meant better performance due to a number of reasons. Switching these components from functional to regular adds this small breaking change where you need to use the native modifier. We were using different env for dev and productionYou still can! Only now it’s even better, due to /quasar.conf.js features. More Info New directive: v-close-overlayAll components using popups, like Modal, Dialog, Popover, Context Menu, now support a much simplified way of closing them. Instead of using a Vue reference, which is troublesome for some use cases, you can simply add v-close-overlay to the element/component that you wish to close the popup. This directive listens for the @click event, determines the first parent popup component and closes it. <q-btn label=\"I got a Popover\"> <q-popover> ... <q-icon v-close-overlay name=\"close\" /> ... </q-popover></q-btn> Handling Back ButtonUnfortunately, the automatic handling of back button was a one of the features that was the hardest to comprehend. It required you to handle Vue references (which beginners on Vue were struggling with) and didn’t fully allow you to connect components like Drawers & Modals to Vuex in an easy way. Now it only works on Mobile Apps (for example Android has a back button that is handled by Quasar). The removal of this feature for websites greatly simplify your code: <q-modal v-model=\"modal\">...</q-modal><q-btn label=\"Open modal\" @click=\"modal = true\" /> ButtonsWhile QBtn still allows you to specify icon and label as children nodes, it is now recommended that you use the “icon” and “label” props instead: <q-btn icon=\"map\" label=\"See map\" /><!-- instead of old: --><q-btn> <q-icon class=\"on-left\" name=\"map\" /> See map</q-btn> Be sure to check out the new button types and props too. Quasar CLI and Pre-0.15 AppsThe Quasar CLI v0.15+ is not compatible with pre-0.15 apps. You can install the latest CLI globally while still supporting quasar commands in legacy apps by adding quasar-cli as a development dependency. To support 0.14 and earlier you need quasar-cli v0.6.5. $ yarn add --dev [email protected]# or:$ npm install --save-dev [email protected] This will add the legacy quasar CLI tool to your projects ./node_modules/.bin/ directory. Use the npx tool (automatically installed alongside npm) to run quasar from your local node modules. For example: $ npx quasar dev"},{"title":"Quasar Release Notes","updated":"2018-05-18T22:01:01.064Z","permalink":"https://v0-16.quasar-framework.org/guide/quasar-release-notes.html","text":"Release Notes are available on Github."},{"title":"Quasar Playground","updated":"2018-05-18T22:01:01.064Z","permalink":"https://v0-16.quasar-framework.org/guide/quasar-playground.html","text":"jsFiddle / Codepen Material Theme iOS Theme jsFiddle https://jsfiddle.net/rstoenescu/waugrryy/ https://jsfiddle.net/rstoenescu/7gu065yg/ Codepen https://codepen.io/rstoenescu/pen/KQRZJg https://codepen.io/rstoenescu/pen/paVpBN You can fork and use these links for reporting issues on Github too. These links (obviously) use the Quasar UMD version. Make sure to read about it before diving in. When you use jsFiddle/Codepen you can skip the Installation section. Quasar PlayLive Demo: Material Theme iOS Theme Google Play Store (currently it’s outdated, using a very old Quasar version) Quasar Play is used for these documentation pages too, on the right side, on the mobile frame.You can clone it and play with it by visiting its Github page."},{"title":"","updated":"2018-05-09T14:34:08.654Z","permalink":"https://v0-16.quasar-framework.org/search/index.html","text":""},{"title":"Quasar Theming","updated":"2018-05-18T22:01:01.066Z","permalink":"https://v0-16.quasar-framework.org/guide/quasar-theming.html","text":"Every website/app needs a specific design to differentiate from the competition. This is where Quasar Framework excels, because: It offers two themes out of the box: Material and iOS The two themes can be customized/extended easily from the App code. You can change the primary color, the secondary color, and most of the CSS. Customizing does not mean having multiple CSS files, one overriding properties from the other. No. You’ll have one stylesheet with each CSS property declared only once. All themes include a CSS reset (following latest standards) to eliminate quirks between platforms. Quasar CSS is a blank slate that you can easily customize and modify to fit your brand, while still following the standards of each platform. The best apps in the app stores are fully customized and Quasar makes it easy to do the same with your App. Quasar is built on top of Stylus, which allows it to set some default styles for your App but makes it extremely easy for you to change the defaults in your App code. Customizing a theme means overriding Stylus variables which can hold colors, sizes, border types and so on. After reading this intro you can go to Components > Stylus Variables for a list of all Stylus variables that you can override so you can theme your App. Please note the following: When building your App or starting the dev server you can only use one theme at a time. Quasar themes can be configured in /src/css/themes folder, which contains three files, as you’ll see in the next section. Structuresrc/css/themes folder from a Quasar App will contain the following files: src└── css └── themes ├── common.variables.styl # Theme Shared Quasar Variables ├── variables.mat.styl # Quasar Variables that apply to Material only └── variables.ios.styl # Quasar Variables that apply to iOS only You will find more documentation and steps in these files. Using Stylus variables in Vue filesIn your app’s *.vue files you can use the core Quasar Stylus variables (examples - colors: $primary, $red-1, media breakpoints: $breakpoint-md, $breakpoint-md-min and so on). <!-- Notice lang=\"stylus\" --><style lang=\"stylus\">// \"variables\" is a Webpack alias (provided out of the box by Quasar CLI)@import '~variables'div color $red-1 background-color $grey-5</style> NOTE: You must add @import '~variables' within your <style> tags, in order for Quasar to parse any Stylus variables you may add. If you don’t, Quasar will literally pass the variables as text and any theming changes using Stylus variables won’t work. NOTE: The <style> tag uses Stylus code. You can’t use any other CSS pre-processor. Theming Your AppYou can easily theme your App by adding Stylus variable declarations in src/css/themes/common.variables.styl or the other two files (in the latter case if you want different looks for each Quasar theme). To customize the look and feel of this app, you can override the Stylus variables found in Quasar’s source Stylus files. Setting variables before Quasar’s Stylus will use these variables rather than Quasar’s default Stylus variable values. Stylus variables specific to the themes belong in either the variables.ios.styl or variables.mat.styl files. For example, change the primary color of your App: $primary = #00ffff Platform Specific StylesThe platform in which your App runs is automatically detected and the <body> tag gets following classes: Body Class Name Description mat Default style; Material Design theme; Android platform ios Apple platform; iOS theme desktop App runs on a desktop browser mobile App runs on a mobile browser cordova Standalone Mobile App wrapped with Apache Cordova electron App runs under Electron touch Touch capable platform no-touch Touch capability not present within-iframe For when entire website is under an IFRAME tag So you can write specific Stylus code for your App like this: body &.cordova .tag color $primary &.desktop .tag color $secondary &.mobile .tag color $tertiary Stylus VariablesRead a complete list of all Stylus variables that you can override."}]