Add form support to `Rating`
parent
2a63b3fdce
commit
97e27ad77a
|
@ -1,19 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
import BaseComponent from '@primevue/core/basecomponent';
|
import BaseEditableHolder from '@primevue/core/baseeditableholder';
|
||||||
import RatingStyle from 'primevue/rating/style';
|
import RatingStyle from 'primevue/rating/style';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'BaseRating',
|
name: 'BaseRating',
|
||||||
extends: BaseComponent,
|
extends: BaseEditableHolder,
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
|
||||||
type: Number,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
readonly: {
|
readonly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="cx('root')" v-bind="ptmi('root')">
|
<div :class="cx('root')" v-bind="ptmi('root')">
|
||||||
<template v-for="value in stars" :key="value">
|
<template v-for="value in stars" :key="value">
|
||||||
<div :class="cx('option', { value })" @click="onOptionClick($event, value)" v-bind="getPTOptions('option', value)" :data-p-active="value <= modelValue" :data-p-focused="value === focusedOptionIndex">
|
<div :class="cx('option', { value })" @click="onOptionClick($event, value)" v-bind="getPTOptions('option', value)" :data-p-active="value <= d_value" :data-p-focused="value === focusedOptionIndex">
|
||||||
<span class="p-hidden-accessible" v-bind="ptm('hiddenOptionInputContainer')" :data-p-hidden-accessible="true">
|
<span class="p-hidden-accessible" v-bind="ptm('hiddenOptionInputContainer')" :data-p-hidden-accessible="true">
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
:value="value"
|
:value="value"
|
||||||
:name="name"
|
:name="d_name"
|
||||||
:checked="modelValue === value"
|
:checked="d_value === value"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:aria-label="starAriaLabel(value)"
|
:aria-label="starAriaLabel(value)"
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
v-bind="ptm('hiddenOptionInput')"
|
v-bind="ptm('hiddenOptionInput')"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<slot v-if="value <= modelValue" name="onicon" :value="value" :class="cx('onIcon')">
|
<slot v-if="value <= d_value" name="onicon" :value="value" :class="cx('onIcon')">
|
||||||
<component :is="onIcon ? 'span' : 'StarFillIcon'" :class="[cx('onIcon'), onIcon]" v-bind="ptm('onIcon')" />
|
<component :is="onIcon ? 'span' : 'StarFillIcon'" :class="[cx('onIcon'), onIcon]" v-bind="ptm('onIcon')" />
|
||||||
</slot>
|
</slot>
|
||||||
<slot v-else name="officon" :value="value" :class="cx('offIcon')">
|
<slot v-else name="officon" :value="value" :class="cx('offIcon')">
|
||||||
|
@ -29,8 +29,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { focus, getFirstFocusableElement } from '@primeuix/utils/dom';
|
||||||
import { UniqueComponentId } from '@primevue/core/utils';
|
import { UniqueComponentId } from '@primevue/core/utils';
|
||||||
import { getFirstFocusableElement, focus } from '@primeuix/utils/dom';
|
|
||||||
import BanIcon from '@primevue/icons/ban';
|
import BanIcon from '@primevue/icons/ban';
|
||||||
import StarIcon from '@primevue/icons/star';
|
import StarIcon from '@primevue/icons/star';
|
||||||
import StarFillIcon from '@primevue/icons/starfill';
|
import StarFillIcon from '@primevue/icons/starfill';
|
||||||
|
@ -40,27 +40,27 @@ export default {
|
||||||
name: 'Rating',
|
name: 'Rating',
|
||||||
extends: BaseRating,
|
extends: BaseRating,
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
emits: ['update:modelValue', 'change', 'focus', 'blur'],
|
emits: ['change', 'focus', 'blur'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
name: this.$attrs.name,
|
d_name: this.name,
|
||||||
focusedOptionIndex: -1,
|
focusedOptionIndex: -1,
|
||||||
isFocusVisibleItem: true
|
isFocusVisibleItem: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$attrs.name': function (newValue) {
|
name: function (newValue) {
|
||||||
this.name = newValue || UniqueComponentId();
|
this.d_name = newValue || UniqueComponentId();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.name = this.name || UniqueComponentId();
|
this.d_name = this.d_name || UniqueComponentId();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getPTOptions(key, value) {
|
getPTOptions(key, value) {
|
||||||
return this.ptm(key, {
|
return this.ptm(key, {
|
||||||
context: {
|
context: {
|
||||||
active: value <= this.modelValue,
|
active: value <= this.d_value,
|
||||||
focused: value === this.focusedOptionIndex
|
focused: value === this.focusedOptionIndex
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -81,13 +81,14 @@ export default {
|
||||||
onBlur(event) {
|
onBlur(event) {
|
||||||
this.focusedOptionIndex = -1;
|
this.focusedOptionIndex = -1;
|
||||||
this.$emit('blur', event);
|
this.$emit('blur', event);
|
||||||
|
this.formField.onBlur?.();
|
||||||
},
|
},
|
||||||
onChange(event, value) {
|
onChange(event, value) {
|
||||||
this.onOptionSelect(event, value);
|
this.onOptionSelect(event, value);
|
||||||
this.isFocusVisibleItem = true;
|
this.isFocusVisibleItem = true;
|
||||||
},
|
},
|
||||||
onOptionSelect(event, value) {
|
onOptionSelect(event, value) {
|
||||||
if (this.focusedOptionIndex === value || this.modelValue === value) {
|
if (this.focusedOptionIndex === value || this.d_value === value) {
|
||||||
this.focusedOptionIndex = -1;
|
this.focusedOptionIndex = -1;
|
||||||
this.updateModel(event, null);
|
this.updateModel(event, null);
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,7 +97,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateModel(event, value) {
|
updateModel(event, value) {
|
||||||
this.$emit('update:modelValue', value);
|
this.updateValue(value, event);
|
||||||
this.$emit('change', { originalEvent: event, value });
|
this.$emit('change', { originalEvent: event, value });
|
||||||
},
|
},
|
||||||
starAriaLabel(value) {
|
starAriaLabel(value) {
|
||||||
|
@ -104,9 +105,9 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
StarFillIcon: StarFillIcon,
|
StarFillIcon,
|
||||||
StarIcon: StarIcon,
|
StarIcon,
|
||||||
BanIcon: BanIcon
|
BanIcon
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -43,6 +43,10 @@ const theme = ({ dt }) => `
|
||||||
.p-rating-option-active .p-rating-icon {
|
.p-rating-option-active .p-rating-icon {
|
||||||
color: ${dt('rating.icon.active.color')};
|
color: ${dt('rating.icon.active.color')};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-rating-icon.p-invalid { /* @todo */
|
||||||
|
stroke: ${dt('rating.invalid.icon.color')};
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const classes = {
|
const classes = {
|
||||||
|
@ -53,15 +57,25 @@ const classes = {
|
||||||
'p-disabled': props.disabled
|
'p-disabled': props.disabled
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
option: ({ instance, props, value }) => [
|
option: ({ instance, value }) => [
|
||||||
'p-rating-option',
|
'p-rating-option',
|
||||||
{
|
{
|
||||||
'p-rating-option-active': value <= props.modelValue,
|
'p-rating-option-active': value <= instance.d_value,
|
||||||
'p-focus-visible': value === instance.focusedOptionIndex && instance.isFocusVisibleItem
|
'p-focus-visible': value === instance.focusedOptionIndex && instance.isFocusVisibleItem
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
onIcon: 'p-rating-icon p-rating-on-icon',
|
onIcon: ({ instance }) => [
|
||||||
offIcon: 'p-rating-icon p-rating-off-icon'
|
'p-rating-icon p-rating-on-icon',
|
||||||
|
{
|
||||||
|
'p-invalid': instance.$invalid
|
||||||
|
}
|
||||||
|
],
|
||||||
|
offIcon: ({ instance }) => [
|
||||||
|
'p-rating-icon p-rating-off-icon',
|
||||||
|
{
|
||||||
|
'p-invalid': instance.$invalid
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BaseStyle.extend({
|
export default BaseStyle.extend({
|
||||||
|
|
Loading…
Reference in New Issue