본문으로 건너뛰기

Spoiler

누군가 요청하기 전까지 내용을 덮어 두는 상자입니다. 덮개는 숨겨진 박스가 아니라 blur이므로, 독자는 거기에 무언가가 있다는 것과 그 분량을 알 수 있으면서도 실수로 읽게 되지는 않습니다.

tsx
import { Spoiler } from 'neba';

<Spoiler locale="ko">
  <p>로즈버드는 썰매의 이름이었습니다.</p>
</Spoiler>;

Props

Prop타입기본값설명
revealedboolean내용이 열려 있는지. 직접 제어할 때 씁니다
defaultRevealedbooleanfalse제어하지 않을 때의 시작 상태
onRevealedChange(revealed: boolean) => void열기 또는 닫기 버튼을 눌렀을 때
localestring'en'기본 라벨과 안내 문구의 언어. BCP 47 태그(ko, pt-BR, zh-Hant). 모르는 태그는 영어로 돌아갑니다
labelReactNode열기 버튼의 라벨. 기본값은 locale이 정합니다
hideLabelReactNodereversible일 때 닫기 버튼의 라벨
descriptionReactNode | false버튼 위의 안내 문구. 기본값은 locale이 정하고, false면 아무것도 쓰지 않습니다
actionReactNode기본 열기 버튼을 통째로 바꿉니다. 이 경우 revealed와 onRevealedChange로 직접 제어해야 합니다
reversiblebooleanfalse열고 난 뒤 다시 닫을 수 있게 아래에 닫기 버튼을 둡니다. 그 줄은 덮인 동안에도 자리를 지켜 상자 높이가 변하지 않습니다
maxHeightnumber | string가려진 상자의 높이를 제한합니다. CSS 길이 또는 픽셀 수. 열면 풀립니다
blurnumber10흐림의 세기(px)
paddedbooleantrue내용 주변의 여백. 사진이나 영상처럼 가장자리까지 채워야 할 때 끕니다
variant공통'solid' | 'outline' | 'text''outline'상자 표면의 무게. text는 상자를 그리지 않습니다
size공통'xs' | 'sm' | 'md' | 'lg' | 'xl''md'시트의 반경과 그 위 버튼의 크기
color공통'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info''primary'의미론적 색 역할. 임의 색상값은 받지 않습니다
density공통'default' | 'compact''default'덮개의 문구와 버튼 주위 여백만 바꿉니다
elevation공통0 | 1 | 2 | 30그림자 깊이. 0은 그림자 없음
childrenReactNode가려지는 내용

나머지 <div> 속성은 모두 루트로 전달됩니다. 예외는 onChange 하나로, 여기서 들을 만한 변화는 onRevealedChange입니다.

공통 축(variant size color density elevation)의 의미는 Prop 규약에 있습니다.

예시

maxHeight

지정하지 않으면 상자는 담고 있는 것의 높이 그대로입니다. 문단이나 사진에는 그쪽이 맞습니다. 덮개는 내용이 드러난 뒤에도 자리를 지키므로, 덮고 있던 줄보다 안내문과 버튼이 더 높더라도 누르는 순간 상자가 줄어들지 않고 아래 내용도 밀리지 않습니다.

높이를 바꾸는 것은 maxHeight 하나뿐입니다. 덮여 있는 동안의 높이를 제한하고, 열면 그 제한이 풀려 내용이 필요한 높이를 그대로 차지합니다. 제한이 남아 있으면 읽는 사람에게는 스크롤바만 남습니다. CSS 길이 또는 픽셀 수를 받습니다.

reversible은 열고 난 뒤 다시 덮을 수 있게 내용 아래에 닫기 버튼을 둡니다. 그 줄은 아직 덮여 있는 동안에도 자리를 지키므로 돌아가는 길 역시 상자 높이를 늘리지 않습니다.

locale

이 컴포넌트가 스스로 지어내는 말은 버튼과 그 위의 한 줄뿐이고, locale은 그 말들의 언어를 정합니다. ko, pt-BR, zh-Hant 같은 BCP 47 태그를 받습니다. 번역이 없는 태그는 영어로 돌아가고, 지역 태그는 언어로 해석됩니다. ko-KRko, zh-TW는 번체입니다.

label, description, action

label은 버튼의 말을, description은 그 위의 줄을 바꿉니다. description={false}면 덮개에 아무것도 쓰지 않습니다. blur는 흐림의 세기를 픽셀로 정합니다.

action은 버튼을 통째로 갈아 끼웁니다. 이때 버튼의 동작은 직접 연결해야 하며, revealedonRevealedChange를 씁니다.

padded

상자는 Box와 같은 스케일로 내용에 여백을 둡니다. 가장자리까지 채워야 하는 것에는 이것을 끄면 됩니다. 그러면 다른 시트에서와 마찬가지로 모서리가 그림을 잘라 냅니다.

variant

text는 상자를 아예 그리지 않습니다. 글 한가운데 놓이는 spoiler가 대개 원하는 모습입니다. solid는 채워진 시트로, 독자를 멈춰 세워야 할 때 씁니다.

제어하기

revealed를 넘기면 Spoiler는 자체 상태를 갖지 않습니다. 여러 개를 한 번에 열거나, 독자가 이미 연 것을 기억하거나, 컨트롤을 페이지의 다른 자리에 두고 싶을 때 씁니다.

tsx
const [revealed, setRevealed] = useState(false);

<Spoiler revealed={revealed} onRevealedChange={setRevealed}>
  <p>범인은 집사였습니다.</p>
</Spoiler>;

접근성

  • 덮여 있는 동안 내용은 inert입니다. tab 순서에서 빠지고, 접근성 트리에서 사라지며, 전체 선택에도 걸리지 않습니다. 전체 선택으로 뚫리는 spoiler는 spoiler가 아닙니다.
  • 열기 버튼은 자신이 여는 내용을 가리키는 aria-expandedaria-controls를 갖습니다.
  • 버튼과 안내 문구가 페이지의 언어로 읽히도록 locale을 지정하거나, labeldescription에 직접 쓰세요.

Released under the MIT License