Use the v-model directive to control the rating value of the StarRating component.
<script setup lang="ts">
const value = ref(3)
</script>
<template>
<UStarRating v-model="value" />
</template>
Use the default-value prop to set the initial value when you do not need to control its state.
<template>
<UStarRating :default-value="3" />
</template>
Use the allow-half prop to enable half-star ratings. When enabled, clicking on the left half of a star will set a half-star value.
<script setup lang="ts">
const value = ref(3.5)
</script>
<template>
<UStarRating allow-half v-model="value" />
</template>
Use the readonly prop to display a rating without allowing user interaction. This is useful for displaying existing ratings.
<template>
<UStarRating readonly v-model="value" />
</template>
Use the icon prop to customize the icon used for stars. Defaults to i-lucide-star.
<script setup lang="ts">
const value = ref(4)
</script>
<template>
<UStarRating icon="i-lucide-heart" v-model="value" />
</template>
Use the empty-icon prop to customize the icon used for empty stars. If not provided, uses the same icon as icon.
<script setup lang="ts">
const value = ref(3)
</script>
<template>
<UStarRating icon="i-lucide-star" empty-icon="i-lucide-star-off" v-model="value" />
</template>
Use the max prop to set the maximum number of stars. Defaults to 5.
<script setup lang="ts">
const value = ref(7.5)
</script>
<template>
<UStarRating :max="10" v-model="value" allow-half />
</template>
Use the color prop to change the color of the filled stars.
<script setup lang="ts">
const value = ref(4)
</script>
<template>
<UStarRating color="primary" v-model="value" />
</template>
<script setup lang="ts">
const value = ref(4)
</script>
<template>
<UStarRating color="success" v-model="value" />
</template>
<script setup lang="ts">
const value = ref(4)
</script>
<template>
<UStarRating color="warning" v-model="value" />
</template>
<script setup lang="ts">
const value = ref(4)
</script>
<template>
<UStarRating color="error" v-model="value" />
</template>
Use the size prop to change the size of the stars.
<script setup lang="ts">
const value = ref(4)
</script>
<template>
<UStarRating size="xs" v-model="value" />
</template>
<script setup lang="ts">
const value = ref(4)
</script>
<template>
<UStarRating size="sm" v-model="value" />
</template>
<script setup lang="ts">
const value = ref(4)
</script>
<template>
<UStarRating size="md" v-model="value" />
</template>
<script setup lang="ts">
const value = ref(4)
</script>
<template>
<UStarRating size="lg" v-model="value" />
</template>
<script setup lang="ts">
const value = ref(4)
</script>
<template>
<UStarRating size="xl" v-model="value" />
</template>
Use the disabled prop to disable the StarRating component.
<script setup lang="ts">
const value = ref(3)
</script>
<template>
<UStarRating disabled v-model="value" />
</template>
The StarRating component integrates seamlessly with forms and supports form validation.
<script setup lang="ts">
const value = ref(0)
</script>
<template>
<UStarRating name="rating" required v-model="value" />
</template>
You can read the modelValue externally to use it in your application logic.
<script setup lang="ts">
const rating = ref(0)
watch(rating, (value) => {
console.log('Rating changed:', value)
// Save to database, update state, etc.
})
</script>
<template>
<UStarRating v-model="rating" />
<p>Current rating: {{ rating }}</p>
</template>
| Prop | Default | Type |
|---|---|---|
as | 'div' | anyThe element or component this component should render as. |
modelValue | 0 | numberThe rating value (0 to max). |
defaultValue | 0 | numberThe default rating value. |
max | 5 | numberMaximum rating value. |
allowHalf | false | boolean Allow half star ratings. |
readonly | false | boolean Make the rating readonly (non-interactive). |
disabled | false | boolean Disable the rating. |
icon | appConfig.ui.icons.star | anyThe icon to use for stars. |
emptyIcon | anyThe icon to use for empty stars (outline version).
If not provided, uses the same icon as | |
color | 'primary' | "primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral" |
size | 'md' | "xs" | "sm" | "md" | "lg" | "xl" |
name | stringForm field name. | |
id | stringForm field id. | |
required | boolean Form field required. | |
ui | { root?: ClassNameValue; star?: ClassNameValue; starFilled?: ClassNameValue; starHalf?: ClassNameValue; } |
| Slot | Type |
|---|---|
star | { index: number; value: number; filled: boolean; half: boolean; } |
| Event | Type |
|---|---|
change | [event: Event] |
update:modelValue | [value: number] |
export default defineAppConfig({
ui: {
starRating: {
slots: {
root: 'inline-flex items-center gap-0.5',
star: 'relative inline-block cursor-pointer transition-colors select-none',
starFilled: 'absolute inset-0 pointer-events-none',
starHalf: 'absolute inset-0 pointer-events-none overflow-hidden'
},
variants: {
size: {
xs: {
star: 'size-3'
},
sm: {
star: 'size-4'
},
md: {
star: 'size-5'
},
lg: {
star: 'size-6'
},
xl: {
star: 'size-7'
}
},
color: {
primary: {
starFilled: 'text-primary-500 dark:text-primary-400',
starHalf: 'text-primary-500 dark:text-primary-400'
},
secondary: {
starFilled: 'text-secondary-500 dark:text-secondary-400',
starHalf: 'text-secondary-500 dark:text-secondary-400'
},
success: {
starFilled: 'text-success-500 dark:text-success-400',
starHalf: 'text-success-500 dark:text-success-400'
},
info: {
starFilled: 'text-info-500 dark:text-info-400',
starHalf: 'text-info-500 dark:text-info-400'
},
warning: {
starFilled: 'text-warning-500 dark:text-warning-400',
starHalf: 'text-warning-500 dark:text-warning-400'
},
error: {
starFilled: 'text-error-500 dark:text-error-400',
starHalf: 'text-error-500 dark:text-error-400'
},
neutral: {
starFilled: 'text-gray-500 dark:text-gray-400',
starHalf: 'text-gray-500 dark:text-gray-400'
}
},
readonly: {
true: {
root: 'cursor-default',
star: 'cursor-default'
},
false: {
star: 'hover:scale-110'
}
},
disabled: {
true: {
root: 'opacity-75 cursor-not-allowed',
star: 'cursor-not-allowed'
}
}
},
defaultVariants: {
size: 'md',
color: 'primary'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
starRating: {
slots: {
root: 'inline-flex items-center gap-0.5',
star: 'relative inline-block cursor-pointer transition-colors select-none',
starFilled: 'absolute inset-0 pointer-events-none',
starHalf: 'absolute inset-0 pointer-events-none overflow-hidden'
},
variants: {
size: {
xs: {
star: 'size-3'
},
sm: {
star: 'size-4'
},
md: {
star: 'size-5'
},
lg: {
star: 'size-6'
},
xl: {
star: 'size-7'
}
},
color: {
primary: {
starFilled: 'text-primary-500 dark:text-primary-400',
starHalf: 'text-primary-500 dark:text-primary-400'
},
secondary: {
starFilled: 'text-secondary-500 dark:text-secondary-400',
starHalf: 'text-secondary-500 dark:text-secondary-400'
},
success: {
starFilled: 'text-success-500 dark:text-success-400',
starHalf: 'text-success-500 dark:text-success-400'
},
info: {
starFilled: 'text-info-500 dark:text-info-400',
starHalf: 'text-info-500 dark:text-info-400'
},
warning: {
starFilled: 'text-warning-500 dark:text-warning-400',
starHalf: 'text-warning-500 dark:text-warning-400'
},
error: {
starFilled: 'text-error-500 dark:text-error-400',
starHalf: 'text-error-500 dark:text-error-400'
},
neutral: {
starFilled: 'text-gray-500 dark:text-gray-400',
starHalf: 'text-gray-500 dark:text-gray-400'
}
},
readonly: {
true: {
root: 'cursor-default',
star: 'cursor-default'
},
false: {
star: 'hover:scale-110'
}
},
disabled: {
true: {
root: 'opacity-75 cursor-not-allowed',
star: 'cursor-not-allowed'
}
}
},
defaultVariants: {
size: 'md',
color: 'primary'
}
}
}
})
]
})