surf-uiby COLDSURF
Components

ReactionBar

하나 또는 여러 개를 켜는 반응 버튼 줄.

import { ReactionBar } from '@coldsurfers/surf-ui/primitives'
import { ReactionBar } from '@coldsurfers/surf-ui/primitives'import { useState } from 'react'const BASE = [  { id: 'go', label: '🔥 갈래', count: 22 },  { id: 'hmm', label: '🤔 고민', count: 9 },  { id: 'pricey', label: '💸 비싸', count: 4 },]export default function Example() {  const [mine, setMine] = useState<string | null>('go')  const items = BASE.map((r) => ({ ...r, count: r.count + (r.id === mine ? 1 : 0) }))  return (    <ReactionBar      aria-label="이 공연 어때요"      items={items}      value={mine}      onChange={setMine}      style={{ width: '100%', maxWidth: 360 }}    />  )}

같은 폭 버튼 N개에 라벨과 개수를 붙입니다(Figma 1028:400). 기본은 하나만 켜지고, 켠 것을 다시 누르면 onChange(null) 입니다.

여러 개

multiple 이면 칸마다 따로 켜고 끕니다(🔥 갈래 + 💸 비싸 = 가고 싶은데 비싸). value 는 켠 id 배열, onChange(id, on) 은 누른 칸과 켜질지를 넘깁니다 — 서버에 칸 하나씩 켜고 끄는 요청을 보내기 좋은 모양입니다.

import { ReactionBar } from '@coldsurfers/surf-ui/primitives'import { useState } from 'react'const BASE = [  { id: 'go', label: '🔥 갈래', count: 22 },  { id: 'hmm', label: '🤔 고민', count: 9 },  { id: 'pricey', label: '💸 비싸', count: 4 },]export default function Example() {  const [mine, setMine] = useState<string[]>(['go', 'pricey'])  const items = BASE.map((r) => ({ ...r, count: r.count + (mine.includes(r.id) ? 1 : 0) }))  return (    <ReactionBar      multiple      aria-label="이 공연 어때요"      items={items}      value={mine}      onChange={(id, on) => setMine((prev) => (on ? [...prev, id] : prev.filter((k) => k !== id)))}      style={{ width: '100%', maxWidth: 360 }}    />  )}

숫자를 올리는 일(낙관적 갱신)은 소비처가 items 로 넘깁니다. fieldset 이라 disabled 하나로 안의 버튼이 함께 꺼지고, 이름은 aria-label 로 붙입니다.

Props

Prop

Type

On this page