Skip to content

Commit

Permalink
feat(QRating): improve kbd navigation; add vertical mode
Browse files Browse the repository at this point in the history
  • Loading branch information
pdanpdan committed Jan 29, 2022
1 parent 0b71921 commit 59b1991
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 28 deletions.
6 changes: 5 additions & 1 deletion docs/src/examples/KeyGroupNavigation/FormControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
<!-- QDate already uses the keyboard navigation inside -->
<q-date v-model="date" />

<!-- QRating already uses the keyboard navigation inside -->
<q-rating class="self-start" v-model="rating" size="3rem" :max="6" icon="img:https://cdn.quasar.dev/logo/svg/quasar-logo.svg" />

<q-btn color="black" label="Last focusable element" />
</div>
</template>
Expand All @@ -17,7 +20,8 @@ export default {
data () {
return {
editor: 'What you see is <b>what</b> you get.',
date: '2019/02/01'
date: '2019/02/01',
rating: 3
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion docs/src/examples/QRating/Basic.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column">
<div class="column q-gutter-y-md">
<q-rating
v-model="ratingModel"
size="1.5em"
Expand Down
50 changes: 50 additions & 0 deletions docs/src/examples/QRating/Vertical.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<template>
<div class="q-pa-md">
<div class="row items-start q-gutter-md">
<q-rating
v-model="ratingModel"
vertical
size="1.5em"
icon="thumb_up"
/>
<q-rating
v-model="ratingModel"
vertical
size="2em"
color="red-7"
icon="favorite_border"
/>
<q-rating
v-model="ratingModel"
vertical
size="2.5em"
color="purple-4"
icon="create"
/>
<q-rating
v-model="ratingModel"
vertical
size="3em"
color="brown-5"
icon="pets"
/>
<q-rating
v-model="ratingModel"
vertical
size="3.5em"
color="green-5"
icon="star_border"
/>
</div>
</div>
</template>

<script>
export default {
data () {
return {
ratingModel: 3
}
}
}
</script>
4 changes: 4 additions & 0 deletions docs/src/pages/vue-components/rating.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Quasar Rating is a Component which allows users to rate items, usually known as

<doc-example title="Custom number of choices" file="QRating/Max" />

### Vertical <q-badge align="top" color="brand-primary" label="v1.16+" />

<doc-example title="Vertical" file="QRating/Vertical" />

### Icons

<doc-example title="Image icons" file="QRating/Images" />
Expand Down
15 changes: 10 additions & 5 deletions ui/dev/src/pages/form/rating.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@
Model <span class="right-detail"><em>{{ ratingModel }}</em></span>
</div>

<div class="column q-gutter-md" style="font-size: 2rem; margin-top: 20px;">
<q-rating v-model="ratingModel" max="3" @change="onChange" @input="onInput" />
<q-rating v-model="ratingModel" color="primary" max="5" icon="pets" @input="onInput" />
<div class="column items-start q-gutter-y-md" style="font-size: 2rem; margin-top: 20px;">
<div class="row items-center">
<q-rating v-model="ratingModel" vertical max="3" @change="onChange" @input="onInput" />
<q-separator vertical spaced />
<q-rating v-model="ratingModel" color="primary" max="5" icon="pets" @input="onInput" />
</div>
<q-rating color="teal" v-model="ratingModel" max="9" icon="thumb_up" />
<q-rating size="3rem" color="red" v-model="ratingModel" :max="6" icon="favorite_border" />
<q-rating size="3rem" color="red" v-model="ratingModel" :max="6" icon="img:https://cdn.quasar.dev/logo/svg/quasar-logo.svg" />
<q-rating size="3rem" color="red" v-model="ratingModel" :max="6" icon="star_border" icon-selected="star" />
<q-rating size="3rem" color="red" v-model="moodModel" :max="4" :icon="ratingIcons" />
<q-rating size="3rem" :color="ratingColors" v-model="moodModel" :max="4" :icon="ratingIcons" />
<div>
<q-rating vertical size="3rem" color="red" v-model="moodModel" :max="4" :icon="ratingIcons" />
<q-rating vertical size="3rem" :color="ratingColors" v-model="moodModel" :max="4" :icon="ratingIcons" />
</div>
<q-rating size="3rem" :color="ratingColors" v-model="moodModel" :max="5" icon="star" :icon-selected="ratingIcons" />
<q-rating
v-model="ratingModel"
Expand Down
48 changes: 27 additions & 21 deletions ui/src/components/rating/QRating.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Vue from 'vue'

import KeyGroupNavigation from '../../directives/KeyGroupNavigation.js'

import { stopAndPrevent } from '../../utils/event.js'
import { between } from '../../utils/format.js'
import QIcon from '../icon/QIcon.js'
Expand All @@ -16,6 +18,10 @@ export default Vue.extend({

mixins: [ SizeMixin, FormMixin, ListenersMixin ],

directives: {
KeyGroupNavigation
},

props: {
value: {
type: Number,
Expand All @@ -35,6 +41,8 @@ export default Vue.extend({
colorHalf: [String, Array],
colorSelected: [String, Array],

vertical: Boolean,

noReset: Boolean,
noDimming: Boolean,

Expand All @@ -55,6 +63,7 @@ export default Vue.extend({

classes () {
return `q-rating--${this.editable === true ? '' : 'non-'}editable` +
(this.vertical === true ? ' column justify-center' : ' row items-center') +
(this.noDimming === true ? ' q-rating--no-dimming' : '') +
(this.disable === true ? ' disabled' : '') +
(this.color !== void 0 && Array.isArray(this.color) === false ? ` text-${this.color}` : '')
Expand Down Expand Up @@ -97,7 +106,7 @@ export default Vue.extend({

for (let i = 1; i <= this.max; i++) {
const
active = (this.mouseModel === 0 && this.value >= i) || (this.mouseModel > 0 && this.mouseModel >= i),
active = this.mouseModel >= i || (this.mouseModel === 0 && this.value >= i),
half = halfIndex === i && this.mouseModel < i,
exSelected = this.mouseModel > 0 && (half === true ? ceil : this.value) >= i && this.mouseModel < i,
color = half === true
Expand All @@ -123,6 +132,7 @@ export default Vue.extend({
(active === true || half === true ? ' q-rating__icon--active' : '') +
(exSelected === true ? ' q-rating__icon--exselected' : '') +
(this.mouseModel === i ? ' q-rating__icon--hovered' : '') +
(ceil === i ? ' q-key-group-navigation__refocus' : '') +
(color !== void 0 ? ` text-${color}` : '')
})
}
Expand All @@ -137,6 +147,15 @@ export default Vue.extend({
if (this.readonly === true) {
return { 'aria-readonly': 'true' }
}
},

directives () {
return [{
name: 'key-group-navigation',
modifiers: {
[this.vertical === true ? 'vertical' : 'horizontal']: true
}
}]
}
},

Expand All @@ -159,23 +178,9 @@ export default Vue.extend({
},

__keyup (e, i) {
switch (e.keyCode) {
case 13:
case 32:
this.__set(i)
return stopAndPrevent(e)
case 37: // LEFT ARROW
case 40: // DOWN ARROW
if (this.$refs[`rt${i - 1}`]) {
this.$refs[`rt${i - 1}`].focus()
}
return stopAndPrevent(e)
case 39: // RIGHT ARROW
case 38: // UP ARROW
if (this.$refs[`rt${i + 1}`]) {
this.$refs[`rt${i + 1}`].focus()
}
return stopAndPrevent(e)
if ([13, 32].indexOf(e.keyCode) > -1) {
this.__set(i)
stopAndPrevent(e)
}
}
},
Expand All @@ -185,14 +190,14 @@ export default Vue.extend({
child = [],
tabindex = this.editable === true ? 0 : null

this.stars.forEach(({ classes, name }, index) => {
this.stars.forEach(({ classes, name, active }, index) => {
const i = index + 1

child.push(
h('div', {
key: i,
ref: `rt${i}`,
class: 'q-rating__icon-container flex flex-center',
staticClass: 'q-rating__icon-container flex flex-center',
attrs: { tabindex },
on: cache(this, 'i#' + i, {
click: () => { this.__set(i) },
Expand All @@ -214,10 +219,11 @@ export default Vue.extend({
}

return h('div', {
staticClass: 'q-rating row inline items-center q-key-group-navigation--ignore-key',
staticClass: 'q-rating inline',
class: this.classes,
style: this.sizeStyle,
attrs: this.attrs,
directives: this.directives,
on: { ...this.qListeners }
}, child)
}
Expand Down
7 changes: 7 additions & 0 deletions ui/src/components/rating/QRating.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@
"category": "model"
},

"vertical": {
"type": "Boolean",
"desc": "Vertical display",
"category": "style",
"addedIn": "v1.16.0"
},

"readonly": {
"extends": "readonly"
},
Expand Down

0 comments on commit 59b1991

Please sign in to comment.