본문으로 건너뛰기

FloatingActionButton

화면이 다루는 단 하나의 행동을, 그 화면 위에 띄워 놓은 둥근 버튼입니다. FAB이라고도 부릅니다. 자식으로 FloatingAction을 넣으면 눌렀을 때 펼쳐지는 작은 액션 묶음이 됩니다.

tsx
import { FloatingActionButton } from 'neba';

<FloatingActionButton icon={<PencilIcon />} label="새 글" onClick={compose} />;

Props

Prop타입기본값설명
variant공통'solid' | 'outline' | 'text''solid'표면의 무게. 채움 / 하이라인 / 없음
size공통'xs' | 'sm' | 'md' | 'lg' | 'xl''lg'높이. 사다리는 Button과 같고 시작점만 한 칸 위입니다. 보지 않고 엄지로 찾아 누르는 유일한 컨트롤이기 때문입니다
color공통'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info''primary'의미론적 색 역할. 임의 색상값은 받지 않습니다
density공통'default' | 'compact''default'여백만 바꿉니다. 높이와 글자 크기는 그대로
elevation공통0 | 1 | 2 | 32그림자 깊이. Pill과 같은 이유로 기본이 2입니다. 이 버튼은 페이지의 일부가 아니라 그 위에 떠 있습니다
iconReactNodea plus버튼의 글리프
label * string버튼이 무엇을 하는지, 말로. 필수입니다. 그림만으로 된 버튼은 접근성 이름이 아예 없습니다. extended일 때는 버튼에 쓰이는 말이기도 합니다
extendedbooleanfalselabel을 글리프 옆에 씁니다. 원이 스타디움이 됩니다
openIconReactNode다이얼이 열려 있는 동안의 글리프. 액션이 있으면 기본이 ×입니다. icon과 같은 노드를 넘기면 바뀌지 않습니다
position'static' | 'sticky' | 'fixed' | 'absolute''fixed'어디에 앉는지. fixed는 창의 모서리에, absolute는 가장 가까운 positioned 조상의 모서리에 고정합니다
corner공통'top-start' | 'top-end' | 'bottom-start' | 'bottom-end''bottom-end'어느 모서리에 붙는지
offsetnumber | string16양쪽 가장자리에서 얼마나 안쪽인지. CSS 길이 또는 픽셀 수
direction'top' | 'bottom'액션이 펼쳐지는 방향. 지정하지 않으면 corner에서 가져옵니다
openboolean다이얼이 열려 있는지. 직접 제어할 때
defaultOpenbooleanfalse제어하지 않을 때의 시작 상태
onOpenChange(open: boolean) => void다이얼이 열리거나 닫혔을 때
openOnHoverbooleantrue마우스가 버튼에 머무르면 다이얼을 엽니다. 터치와 펜은 제외됩니다
closeOnActionbooleantrue액션을 누르면 다이얼을 닫습니다
showLabelsbooleantrue각 액션의 이름을 옆의 로젠지에 그립니다. 꺼도 이름은 그대로 읽힙니다
disabledbooleanfalse버튼과 모든 액션이 응답을 멈춥니다
onClickMouseEventHandler<HTMLButtonElement>버튼을 눌렀을 때. 액션이 있어도 그대로 발생하며, 그때는 누름이 다이얼도 여닫습니다
childrenReactNodeFloatingAction들, 있다면
Prop타입기본값설명
iconReactNode글리프
label * string액션이 무엇을 하는지, 말로. 옆에 그려지고 언제나 읽힙니다
disabledbooleanfalse사용 불가. 다이얼에는 남습니다
onClickMouseEventHandler<HTMLButtonElement>액션을 눌렀을 때

나머지 <div> 속성은 루트로, 나머지 <button> 속성은 각 액션으로 전달됩니다. onClick은 버튼 자신의 것입니다.

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

예시

액션 펼치기

자식으로 FloatingAction을 넣으면 버튼은 다이얼이 됩니다. 누르거나 마우스를 올리면 액션들이 펼쳐지고, 글리프는 ×로 바뀝니다. 각 액션의 이름은 옆의 로젠지에 그려집니다.

closeOnAction은 액션을 누른 뒤 다이얼을 닫을지, showLabels는 이름을 그릴지, openOnHover는 마우스가 머무를 때 열지를 정합니다.

extended

extendedlabel을 글리프 옆에 써서 원을 스타디움으로 바꿉니다. 화면이 다루는 행동이 무엇인지 그림만으로 분명하지 않을 때 쓰는 형태입니다. label은 두 경우 모두 접근성 이름이므로, 그려지는 말과 읽히는 말이 어긋날 수 없습니다.

position, corner, offset

position은 기본이 fixed로 창의 모서리에 고정합니다. absolute는 가장 가까운 positioned 조상의 모서리에 고정하므로 카드나 지도, Mockup의 화면 안에 넣을 때 쓰고, static은 흐름 안으로 되돌립니다.

corner는 네 모서리 중 하나, offset은 양쪽 가장자리에서의 거리입니다. 액션이 펼쳐지는 방향은 corner에서 따라오며 direction으로 뒤집을 수 있습니다.

variant, size, color

버튼 자체는 Button이고, 변형과 elevation 사다리, 포인터 조명, 누름의 거동이 모두 그대로입니다. size만 한 칸 위에서 시작해 lg가 기본입니다. 보지 않고 엄지로 찾아 누르는 유일한 컨트롤이기 때문입니다. 액션들은 다시 한 칸 아래에서 그려집니다.

제어하기

open을 넘기면 다이얼은 자체 상태를 갖지 않습니다.

tsx
const [open, setOpen] = useState(false);

<FloatingActionButton label="공유" open={open} onOpenChange={setOpen}>
  <FloatingAction icon={<LinkIcon />} label="링크 복사" />
</FloatingActionButton>;

접근성

  • label은 필수입니다. 그림만으로 된 버튼은 접근성 이름이 아예 없습니다.
  • 액션이 있으면 버튼에 aria-expanded와, 펼쳐진 묶음을 가리키는 aria-controls가 붙습니다. role="menu"는 아닙니다. 메뉴는 세트 전체에 tab 정지점 하나와 방향키 이동, typeahead를 약속하고, 그것이 필요하면 Menu가 그것입니다.
  • 액션들은 버튼 바로 다음 순서의 평범한 버튼이므로 tab으로 닿습니다.
  • Escape는 다이얼을 닫고 focus를 버튼으로 되돌립니다. 바깥을 누르면 닫힙니다.
  • 액션 옆 로젠지는 aria-hidden입니다. 같은 문자열이 이미 버튼의 이름이므로 두 번 읽히지 않게 합니다.

Released under the MIT License