HextaUI

BetaVercel UI SDK 0.1.0-beta.1 üzerine kurulu. API’si değişebilir.

Rating

Vercel UI SDK üzerinde tam veya yarım yıldızlı, üzerine gelince önizleme, salt okunur ortalamalar ve form desteği sunan bir yıldız puanlama.

Bağımlılıklar
  • @tabler/icons-react
  • @ui-sdk/core
  • @ui-sdk/react
  • class-variance-authority
"use client"

import * as React from "react"

import { Rating, RatingItem } from "@/components/ui/ui-sdk-rating"

const labels = ["Terrible", "Poor", "Okay", "Good", "Great"]

function UiSdkRatingDemo() {
  const [value, setValue] = React.useState<number | null>(4)

  return (
    <div className="flex flex-col items-center gap-2">
      <Rating
        aria-label="How was your stay?"
        size="lg"
        value={value}
        onValueChange={setValue}
        getValueLabel={(score, max) =>
          labels[score - 1] + ", " + score + " of " + max
        }
      >
        <RatingItem />
      </Rating>
      <p
        aria-hidden="true"
        className="min-h-5 text-sm text-muted-foreground tabular-nums"
      >
        {value ? labels[value - 1] : "Not rated yet"}
      </p>
    </div>
  )
}

export { UiSdkRatingDemo }
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-rating.json

Bileşeni, HextaUI tema token'larını ve bileşenin bağımlı olduğu tüm HextaUI bileşenlerini ekler.

UI SDK, ui-sdk adlı bir cascade katmanında kendi CSS’ini biraz ekler. Sınıflarınızın kazanması için bu katmanı genel stil dosyanızın en üstünde, Tailwind import’unun üzerinde tanımlayın.

@layer ui-sdk;

@import "tailwindcss";
import { Rating, RatingItem } from "@/components/ui/ui-sdk-rating"
<Rating aria-label="Rating" defaultValue={3}>
  <RatingItem />
</Rating>

Rating alt öğesini her yıldız için bir kez çizer; bu yüzden içine bir RatingItem koyun. Her yıldız, --rating-fill ile kırpılmış dolu bir yıldızla boş bir yıldız çizer; böylece yarım yıldızlar ve 4,3 gibi ortalamalar tam görünür.

Rating
└── RatingItem

step={0.5} ile her yıldız yarısı kendi radyosudur ve ok tuşları yarım yıldız ilerler.

import { Rating, RatingItem } from "@/components/ui/ui-sdk-rating"

function UiSdkRatingHalf() {
  return (
    <Rating aria-label="Rating" step={0.5} defaultValue={3.5}>
      <RatingItem />
    </Rating>
  )
}

export { UiSdkRatingHalf }

Salt okunur bir puanlama, getValueLabel ile adlandırılan tek bir görseldir ve ortalama gibi her puanı gösterir.

"use client"

import { Rating, RatingItem } from "@/components/ui/ui-sdk-rating"

function UiSdkRatingReadOnly() {
  return (
    <div className="flex items-center gap-2 text-sm">
      <Rating
        readOnly
        size="sm"
        value={4.3}
        getValueLabel={(value, max) =>
          "Rated " + value + " out of " + max + " stars"
        }
      >
        <RatingItem />
      </Rating>
      <span className="font-medium tabular-nums">4.3</span>
      <span className="text-muted-foreground">(1,284 reviews)</span>
    </div>
  )
}

export { UiSdkRatingReadOnly }

size, sm, default veya lg olur.

import { Rating, RatingItem } from "@/components/ui/ui-sdk-rating"

function UiSdkRatingSizes() {
  return (
    <div className="flex flex-col items-center gap-4">
      <Rating aria-label="Small rating" size="sm" defaultValue={3}>
        <RatingItem />
      </Rating>
      <Rating aria-label="Default rating" defaultValue={3}>
        <RatingItem />
      </Rating>
      <Rating aria-label="Large rating" size="lg" defaultValue={3}>
        <RatingItem />
      </Rating>
    </div>
  )
}

export { UiSdkRatingSizes }

deselectable ile işaretli yıldıza yeniden basmak puanı temizler.

import { Rating, RatingItem } from "@/components/ui/ui-sdk-rating"

function UiSdkRatingDeselectable() {
  return (
    <Rating aria-label="Rating" deselectable defaultValue={2}>
      <RatingItem />
    </Rating>
  )
}

export { UiSdkRatingDeselectable }

value ve onValueChange verin; null henüz puan olmadığı anlamına gelir. createRatingController() ile oluşturulan bir controller puanı her yerden ayarlar.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import {
  createRatingController,
  Rating,
  RatingItem,
} from "@/components/ui/ui-sdk-rating"

function UiSdkRatingControlled() {
  const [rating] = React.useState(createRatingController)
  const [value, setValue] = React.useState<number | null>(null)

  return (
    <div className="flex flex-col items-center gap-3">
      <Rating
        aria-label="Rating"
        controller={rating}
        value={value}
        onValueChange={setValue}
      >
        <RatingItem />
      </Rating>
      <div className="flex gap-2">
        <Button variant="outline" size="sm" onClick={() => rating.setValue(5)}>
          Rate 5
        </Button>
        <Button
          variant="ghost"
          size="sm"
          disabled={value === null}
          onClick={() => setValue(null)}
        >
          Clear
        </Button>
      </div>
      <p className="text-sm text-muted-foreground tabular-nums">
        {value === null ? "No score" : "Score: " + value}
      </p>
    </div>
  )
}

export { UiSdkRatingControlled }

Bir name ile puan formla birlikte gönderilir. required, puan verilene kadar gönderimi tarayıcının kendi mesajıyla engeller.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { Rating, RatingItem } from "@/components/ui/ui-sdk-rating"

function UiSdkRatingForm() {
  const [submitted, setSubmitted] = React.useState<string | null>(null)

  return (
    <form
      className="flex flex-col items-start gap-3"
      onSubmit={(event) => {
        event.preventDefault()
        setSubmitted(String(new FormData(event.currentTarget).get("score")))
      }}
      onReset={() => setSubmitted(null)}
    >
      <div className="flex flex-col gap-1.5">
        <span id="rating-form-label" className="text-sm font-medium">
          Rate this answer
        </span>
        <Rating aria-labelledby="rating-form-label" name="score" required>
          <RatingItem />
        </Rating>
      </div>
      <div className="flex gap-2">
        <Button type="submit" size="sm">
          Submit
        </Button>
        <Button type="reset" variant="outline" size="sm">
          Reset
        </Button>
      </div>
      <p role="status" className="text-sm text-muted-foreground">
        {submitted ? "Submitted score=" + submitted : "Nothing submitted yet."}
      </p>
    </form>
  )
}

export { UiSdkRatingForm }

Kendi simgenizi RatingItem alt öğesi olarak verin ve data-filled ile değiştirin. tone rengi belirler.

import { IconHeart, IconHeartFilled } from "@tabler/icons-react"

import { Rating, RatingItem } from "@/components/ui/ui-sdk-rating"

function UiSdkRatingCustomIcon() {
  return (
    <Rating
      aria-label="How much did you like it?"
      defaultValue={3}
      tone="destructive"
    >
      <RatingItem>
        <IconHeart
          aria-hidden="true"
          className="size-6 group-data-[filled]/rating-item:hidden group-data-[partial]/rating-item:hidden"
        />
        <IconHeartFilled
          aria-hidden="true"
          className="hidden size-6 group-data-[filled]/rating-item:block group-data-[partial]/rating-item:block"
        />
      </RatingItem>
    </Rating>
  )
}

export { UiSdkRatingCustomIcon }

Devre dışı bir puanlama odak almaz, değişmez ve hiçbir şey göndermez.

import { Rating, RatingItem } from "@/components/ui/ui-sdk-rating"

function UiSdkRatingDisabled() {
  return (
    <Rating aria-label="Rating" disabled defaultValue={3}>
      <RatingItem />
    </Rating>
  )
}

export { UiSdkRatingDisabled }

Yıldızlar sağdan başlar ve yarım yıldız sağ kenarından dolar.

import { Rating, RatingItem } from "@/components/ui/ui-sdk-rating"

function UiSdkRatingRtl() {
  return (
    <div dir="rtl">
      <Rating aria-label="التقييم" step={0.5} defaultValue={2.5}>
        <RatingItem />
      </Rating>
    </div>
  )
}

export { UiSdkRatingRtl }
TuşAction
TabPuanlamaya, işaretli yıldıza ya da ilk yıldıza geçer.
←→↑↓Sonraki veya önceki puana geçip işaretler; loop ayarlı değilse uçlarda durur.
SpaceOdaktaki yıldızı işaretler; işaretliyse ve puanlama seçimi kaldırılabilirse temizler.
EnterFormu gönderir.

Puanlama, tek sekme durağı olan bir radyo grubudur. Her yıldız, seçebileceği her puan için getValueLabel ile adlandırılan bir radyo içerir; bu yüzden puanları insanların kullandığı sözcüklerle adlandırın, örneğin “Harika, 5 üzerinden 5”. Yıldız simgeleri ekran okuyuculardan gizlenir. Salt okunur bir puanlama ise tek bir görseldir.

Yıldızlar yalnızca harekete izin verildiğinde üzerine gelince büyür ve basınca küçülür. Dokunmatik ekranlarda her yıldıza ek dolgu eklenir; zorunlu renkler modunda dolu yıldızlar metin rengini, boş olanlar sistemin grisini kullanır.

Her parça aynı adlı UI SDK parçasını sarar ve render ile parçanın durumuna bağlı bir fonksiyon olabilen className dahil tüm prop’larını kabul eder.

PropTürVarsayılan
value
number | null–
defaultValue
number | null–
onValueChange
(value: number | null, details) => void–
max
number5
step
number1
size
"sm" | "default" | "lg""default"
tone
"default" | "neutral" | "destructive""default"
deselectable
booleanfalse
readOnly
booleanfalse
disabled
booleanfalse
required
booleanfalse
name
string–
loop
booleanfalse
getValueLabelHer puanı radyosu ve salt okunur puanlama için adlandırır.
(value: number, max: number) => string–
controllercreateRatingController() ile oluşturulur.
RatingController–
ÖznitelikAçıklama
data-slot="rating"CSS’te puanlamayı hedefler.
data-sizeBoyut: sm, default veya lg.
data-toneTon: default, neutral veya destructive.
data-readonlySalt okunur olduğunda bulunur.
data-disabledDevre dışıyken bulunur.
--rating-colorDolu yıldızların rengi; tone ile ayarlanır.
PropTürVarsayılan
childrenYıldızın simgesi. Varsayılan olarak --rating-fill ile dolan bir Tabler yıldızıdır.
ReactNode–
render
ReactElement | (props, state) => ReactElement–
ÖznitelikAçıklama
data-slot="rating-item"CSS’te bir yıldızı hedefler.
data-filledGösterilen puanın tamamen kapladığı yıldızlarda bulunur.
data-partialGösterilen puanın bir kısmını kapladığı yıldızda bulunur.
data-checkedPuanın bittiği yıldızda bulunur.
data-highlightedİşaretçinin önizlediği puana kadar olan yıldızlarda bulunur.
--rating-fillGösterilen puanın yıldızın ne kadarını kapladığı, 0 ile 1 arasında.