StarRating | CoUI
LogoCoUI

StarRating

별점으로 평가를 입력하거나 표시하는 컴포넌트

StarRating#

별 아이콘을 사용하여 평점을 입력하거나 표시하는 컴포넌트입니다. 반별(half-star), 커스텀 별 모양, 드래그 인터랙션을 지원합니다.

Live Preview#

사용 시기 (When to Use)#

이 컴포넌트를 사용하세요:

  • 상품, 서비스, 콘텐츠에 대한 사용자 만족도를 수집하는 경우
  • 리뷰 섹션에서 평균 평점을 시각적으로 표시하는 경우

대신 다른 컴포넌트를 사용하세요:

  • Slider: 세밀한 수치 입력이 필요한 경우
  • TextField: 정확한 숫자 값을 직접 입력받아야 하는 경우

기본 사용법 (Basic Usage)#

// 기본 별점 (읽기 전용)
StarRating(value: 3.5)

// 인터랙티브 별점
StarRating(
  value: rating,
  onChanged: (v) => setState(() => rating = v),
)

// 커스텀 별 모양 + 색 (색은 starRatingStyle 로)
StarRating(
  value: 4,
  starPoints: 6,
  starInnerRadiusRatio: 0.5,
  starRatingStyle: CoreStarRatingStyle(
    activeColor: CoreColor.token(CoreColors.warning),
  ),
)
// 기본 별점 (읽기 전용)
StarRating(value: 3.5)

// 인터랙티브 별점
StarRating(
  value: rating,
  onChanged: (v) => setState(() => rating = v),
)

// 커스텀 별 모양 + 색 (색은 starRatingStyle 로)
StarRating(
  value: 4,
  starPoints: 6,
  starInnerRadiusRatio: 0.5,
  starRatingStyle: CoreStarRatingStyle(
    activeColor: CoreColor.token(CoreColors.warning),
  ),
)

빠른 오버라이드 (Chain)#

이미 만든 StarRating 인스턴스에 스타일을 빠르게 덧붙이고 싶다면 withStyle 체인을 쓸 수 있습니다. 생성자의 style 슬롯 인자와 동일하게 동작하지만, 이미 구성된 위젯 위에서 바로 이어 쓸 수 있습니다. .primary처럼 Core 토큰 상수 이름과 똑같은 이름의 getter도 있습니다 — withStyle을 한 번 더 줄인 sugar로, 이름이 곧 값이라(primary == CoreColors.primary) 어느 컴포넌트에서 써도 뜻이 갈리지 않으며, 위 예시처럼 withStyle 뒤에 이어붙일 수도 있습니다.

class StarRatingChainExample extends StatefulWidget {
  const StarRatingChainExample({super.key});

  @override
  State<StarRatingChainExample> createState() => _StarRatingChainExampleState();
}

class _StarRatingChainExampleState extends State<StarRatingChainExample> {
  double _value = 3;

  @override
  Widget build(BuildContext context) {
    return StarRating(
          value: _value,
          onChanged: (v) => setState(() => _value = v),
        )
        .withStyle(
          const CoreStarRatingStyle(
            starSize: CoreSpace.space32,
            starSpacing: CoreSpace.space12,
            activeColor: CoreColor.token(CoreColors.warning),
          ),
        )
        .primary;
  }
}
class StarRatingChainExample extends StatefulComponent {
  const StarRatingChainExample({super.key});

  @override
  State<StarRatingChainExample> createState() => _StarRatingChainExampleState();
}

class _StarRatingChainExampleState extends State<StarRatingChainExample> {
  double _value = 3;

  @override
  Component build(BuildContext context) {
    return StarRating(
          value: _value,
          onChanged: (v) => setState(() => _value = v),
        )
        .withStyle(
          const CoreStarRatingStyle(
            starSize: CoreSpace.space32,
            starSpacing: CoreSpace.space12,
            activeColor: CoreColor.token(CoreColors.warning),
          ),
        )
        .primary;
  }
}

Props / Parameters#

속성타입기본값설명
valuedouble필수현재 별점 값
maxdouble5.0최대 별점
stepdouble0.5별점 증가 단위
enabledbooltrue인터랙션 가능 여부
onChanged ValueChanged<double>? null 별점 변경 콜백
starPoints double? null (→ 5) 별 꼭짓점 수
starPointRounding double? null (→ 0.15) 꼭짓점 둥글기
starValleyRounding double? null (→ 0) 골짜기 둥글기
starSquash double? null (→ 0) 수직 압축
starInnerRadiusRatio double? null (→ 0.4) 안쪽/바깥 반지름 비율
starRotation double? null (→ 0) 회전 (라디안)
starRatingStyle CoreStarRatingStyle? null 색 / 크기 / 간격 / 애니메이션 chrome 단일 진입점
direction CoreAxis CoreAxis.horizontal 별이 놓이는 축. 별 하나가 채워지는 방향도 같이 결정합니다 — 가로는 왼쪽→오른쪽, 세로는 아래→위
name String? null 숨은 native input 의 form 필드 이름 — Web 전용

Web 은 위 파라미터에 더해 id / classes / css / attributes 와 DOM 이벤트 슬롯(onClick / onKeyDown 등)을 받아 루트 요소로 통과시킵니다.

CoreStarRatingStyle 필드#

필드타입설명
animationDuration Duration? Size of each star icon (logical px). Fill-transition duration — how long the star fill sweeps when the rating value changes (Flutter value lerp / Web CSS width transition, same token on both platforms).
starSizedouble?Star icon size (logical px).
starSpacing double? Horizontal spacing between stars (logical px).
activeColor CoreColor? Active (filled) star colour override.
backgroundColor CoreColor? Inactive (empty) star background colour override.
disabledActiveColor CoreColor? Active star colour override when disabled. null defers to [defaultDisabledActiveColor].
focusBorderColor CoreColor? Keyboard focus border colour override. null defers to [defaultFocusBorderColor].
focusBorderWidth double? Keyboard focus border width override (logical px, pre-scaling). null defers to [defaultFocusBorderWidth].

동작 스펙 (Behavior)#

인터랙션#

  • 클릭/탭: 클릭한 위치의 별점으로 설정 (양 플랫폼)
  • 호버: 마우스 위치에 따라 별점 미리보기 (양 플랫폼)
  • 드래그 (Flutter): 드래그하면서 별점 실시간 변경
  • 키보드 (Flutter): ← → 방향키로 step 단위 증감
  • onChangednull 이거나 enabled: false 면 표시 전용이 되고, 포커스도 받지 않습니다.

반별 지원#

  • step: 0.5일 때 반별(half-star) 표시
  • 채워진 부분과 빈 부분의 경계를 clip으로 처리

축 (direction)#

direction 은 별이 놓이는 축과 별 하나가 채워지는 방향을 함께 정합니다.

  • CoreAxis.horizontal (기본): 별이 가로로 놓이고, 각 별은 왼쪽→오른쪽으로 채워집니다.
  • CoreAxis.vertical: 별이 세로로 쌓이고, 각 별은 아래→위로 채워집니다 — 부분 채움이 옆으로 쓸리는 게 아니라 수위처럼 읽히도록.

포인터 진행 방향은 두 축 · 두 플랫폼 모두 가로 입니다. 세로 별점도 좌우로 드래그해 값을 바꿉니다.

사용 가이드라인 (Usage Guidelines)#

✅ Do#

색/크기/애니메이션은 starRatingStyle 하나로

StarRating(
  value: rating,
  onChanged: (v) => setState(() => rating = v),
  starRatingStyle: CoreStarRatingStyle(
    activeColor: CoreColor.token(CoreColors.warning),
  ),
)

색상·크기·간격·애니메이션은 전부 starRatingStyle 단일 슬롯으로 흐릅니다. 이 슬롯으로 override해야 프로젝트 테마와 같은 merge chain을 타 Flutter/Web 양쪽에서 일관되게 반영됩니다.


❌ Don't#

키보드만으로 값 조정이 가능하다고 가정하지 않기

// ❌ Web에서도 방향키로 값이 바뀔 거라 가정
StarRating(
  value: rating,
  onChanged: (v) => setState(() => rating = v),
)

Flutter는 포커스 상태에서 /step 만큼 증감하지만, Web은 아직 화살표 키를 처리하지 않아 값 변경은 포인터로만 가능합니다. 키보드로도 조작 가능해야 한다면 별도의 대체 입력 수단을 함께 제공하세요.

접근성 (Accessibility)#

역할 / 시맨틱#

  • Web: 루트에 role="slider" + aria-label(활성 로케일의 별점 문구) + aria-valuenow / aria-valuemin(0) / aria-valuemax(max).
  • Flutter: Semantics(slider: true, label: <로케일 별점 문구>, value: '값 / max').

키보드#

  • Flutter: FocusableActionDetector / 를 받아 step 만큼 값을 증감하고 0..max 로 clamp 합니다.
  • Web: 인터랙티브할 때만 tabindex="0" 이 붙어 포커스를 받고 focus-visible: 표시가 나타납니다. 화살표 키 처리는 아직 없습니다 — 값 변경은 포인터로만 가능합니다.

크로스 플랫폼 차이점 (Platform Differences)#

항목FlutterWeb
별 렌더링 StarBorder shape + ShaderMask 부분 채움 SVG path (CoreStarPath)
포인터클릭 + 호버 미리보기 + 드래그클릭 + 호버 미리보기
키보드 / step 증감포커스만 (키 처리 없음)
세로 축 채움 LinearGradientbottomCenter → topCenter clip <rect> 를 아래 기준 scaleY
form 연동없음name 으로 숨은 native input 필드명 지정