Skip to main content

Rate

Overview

The Rate component provides a star/icon-based rating system. It supports custom icons, sizes, and display options for building rating interfaces.


Import

import { Rate } from '@allxsmith/bestax-bulma';

Props

PropTypeDefaultDescription
valuenumberControlled value (0 to max).
defaultValuenumber0Default value for uncontrolled usage.
maxnumber5Maximum rating value.
size'small' | 'medium' | 'large'Size variant.
disabledbooleanfalseWhether the rating is disabled.
showScorebooleanfalseShow the numeric score next to stars.
showTextbooleanfalseShow custom text based on value.
textsstring[]Array of text labels for each rating value.
onChange(value: number) => voidCallback when rating changes.
customIcon(props: RateIconProps) => React.ReactNodeCustom icon renderer.
iconNamestringCustom icon name for the rating stars.
iconLibrary'fa' | 'mdi' | 'ion' | 'material-icons' | 'material-symbols'Icon library to use.
iconVariantstringIcon style variant.
iconFeaturesstring | string[]Additional icon modifiers.
color'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger'Color of the active rating icons.
precisionnumber1Rating precision (e.g., 0.5 for half stars).
customTextstringCustom text displayed next to the rating.
spacedbooleanfalseAdd spacing between icons.
rtlbooleanfalseRight-to-left direction.
classNamestringAdditional CSS classes.
refReact.Ref<HTMLElement>Ref forwarded to the container element.
...All standard HTML and Bulma helper props(See Helper Props)

RateIconProps

PropTypeDescription
indexnumberThe index of this icon (0-based).
isActivebooleanWhether this icon is currently active (filled).
isHoveredbooleanWhether this icon is currently hovered.
valuenumberThe current value.

Usage

Basic Rating

A simple 5-star rating.

function example() {
  const [rating, setRating] = useState(3);
  return (
    <Block>
      <Rate value={rating} onChange={setRating} />
      <Paragraph mt="2">Rating: {rating} stars</Paragraph>
    </Block>
  );
}


With Score Display

Rating showing the numeric score.

function example() {
  const [rating, setRating] = useState(4);
  return <Rate value={rating} onChange={setRating} showScore />;
}


With Text Labels

Rating with descriptive text for each level.

function example() {
  const [rating, setRating] = useState(3);
  return (
    <Rate
      value={rating}
      onChange={setRating}
      showText
      texts={['Poor', 'Fair', 'Average', 'Good', 'Excellent']}
    />
  );
}


With Score and Text

Both score and text displayed together.

function example() {
  const [rating, setRating] = useState(4);
  return (
    <Rate
      value={rating}
      onChange={setRating}
      showScore
      showText
      texts={['Terrible', 'Bad', 'OK', 'Good', 'Great']}
    />
  );
}


Size Variants

Ratings in different sizes.

<Block display="flex" flexDirection="column" gap="4">
  <Rate defaultValue={3} size="small" />
  <Rate defaultValue={3} />
  <Rate defaultValue={3} size="medium" />
  <Rate defaultValue={3} size="large" />
</Block>


Custom Max Value

Rating with more than 5 stars.

function example() {
  const [rating, setRating] = useState(7);
  return (
    <Block>
      <Rate value={rating} onChange={setRating} max={10} showScore />
      <Paragraph mt="2">Rating: {rating} out of 10</Paragraph>
    </Block>
  );
}


Spaced Icons

Rating with spacing between stars.

<Rate defaultValue={3} spaced />


Disabled Rating

A read-only rating display.

<Rate value={4} disabled showScore />


Custom Icons

Rating with custom heart icons.

function example() {
  const [rating, setRating] = useState(3);

  const HeartIcon = ({ isActive }) => (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 24 24"
      fill={isActive ? 'currentColor' : 'none'}
      stroke="currentColor"
      strokeWidth={isActive ? 0 : 2}
      style={{ color: '#f14668' }}
    >
      <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
    </svg>
  );

  return (
    <Rate
      value={rating}
      onChange={setRating}
      customIcon={({ isActive }) => <HeartIcon isActive={isActive} />}
      showScore
    />
  );
}


Context-Aware Rendering

The Rate component is context-aware: it detects whether it is already inside a Field and adjusts its rendering accordingly. This means you can use it standalone with a label prop (it wraps itself in a Field), or inside a Field (it skips rendering its own).

Default (with label)

The simplest usage — the component automatically renders its own Field wrapper.

<Rate label="Rating" defaultValue={3} />


With Field Wrapper

When you need manual control over the Field layout (e.g., horizontal forms), wrap the component in Field. The component detects it's inside a Field and skips rendering its own.

function example() {
  return (
    <Field horizontal label="Rating">
      <Field.Body>
        <Field>
          <Rate defaultValue={3} />
        </Field>
      </Field.Body>
    </Field>
  );
}


With Field and Control Wrappers

For full manual composition, wrap in both Field and Control. The component detects the Field context and renders only the rating element.

function example() {
  return (
    <Field horizontal label="Rating">
      <Field.Body>
        <Field>
          <Control iconLeftName="star">
            <Rate defaultValue={3} />
          </Control>
        </Field>
      </Field.Body>
    </Field>
  );
}


Controlled vs Uncontrolled

Controlled Mode

Use value and onChange to manage state externally:

const [rating, setRating] = useState(3);
<Rate value={rating} onChange={setRating} />;

Uncontrolled Mode

Use defaultValue for internal state management:

<Rate defaultValue={3} />

Click Behavior

Clicking the same star twice will deselect it (set value to 0). This allows users to clear their rating if needed.


Form Submission

Rate is an HTML form element. Pass a name prop and the current rating value is rendered as a hidden <input type="hidden"> inside the component, so it's included in FormData on submit and posts to the server like any native input.

PropDescription
nameForm field name. When set, a hidden input is rendered.
formOptional id of the form this hidden input belongs to (use when the input lives outside the form element).

Submit the form below and inspect the resulting FormData entries:

function RateFormDemo() {
  const [submitted, setSubmitted] = React.useState('');
  return (
    <form
      onSubmit={e => {
        e.preventDefault();
        const fd = new FormData(e.currentTarget);
        setSubmitted(JSON.stringify(Array.from(fd.entries()), null, 2));
      }}
    >
      <Rate name="rating" defaultValue={3} showScore />
      <div style={{ marginTop: '1rem' }}>
        <button type="submit" className="button is-primary">
          Submit
        </button>
      </div>
      {submitted && <pre style={{ marginTop: '1rem' }}>{submitted}</pre>}
    </form>
  );
}


Accessibility

  • Uses role="radiogroup" for the container
  • Each star has role="radio" with aria-checked
  • Has aria-valuenow, aria-valuemin, and aria-valuemax
  • Full keyboard navigation with arrow keys
  • Home/End keys jump to 0/max values

  • Slider - For selecting numeric values with a range
  • Input - For text input

Additional Resources

Pro Tip

Use the texts prop to provide context for each rating level, helping users understand what each star value means.