SpeedDial
빠른 액션을 위한 플로팅 버튼 컴포넌트입니다. Root, Trigger, Actions, Action으로 구성된 Compound 패턴으로 유연한 커스터마이징이 가능합니다. 메인 버튼을 클릭하면 여러 액션 버튼이 up, down, left, right 4가지 방향으로 시차 애니메이션과 함께 펼쳐집니다. ESC 키 및 외부 클릭으로 닫기 제어, asChild 패턴을 통한 커스텀 렌더링, ARIA 속성을 통한 접근성 지원, color 속성으로 테마 색상 커스터마이징을 제공합니다.
미리보기
사용법
TSX
1"use client";
2
3import { useState } from "react";
4import { SpeedDial } from "motile-ui";
5
6export default function PreviewExample() {
7 const [open, setOpen] = useState(false);
8
9 return (
10 <div style={{ display: "flex", alignItems: "center", justifyContent: "center", minHeight: "300px" }}>
11 <SpeedDial.Root open={open} onOpenChange={setOpen} direction="up">
12 <SpeedDial.Trigger>+</SpeedDial.Trigger>
13 <SpeedDial.Actions>
14 <SpeedDial.Action onClick={() => alert("Action 1")}>1</SpeedDial.Action>
15 <SpeedDial.Action onClick={() => alert("Action 2")}>2</SpeedDial.Action>
16 <SpeedDial.Action onClick={() => alert("Action 3")}>3</SpeedDial.Action>
17 </SpeedDial.Actions>
18 </SpeedDial.Root>
19 </div>
20 );
21}API 레퍼런스
SpeedDial.Root
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
open | boolean | - | SpeedDial 열림/닫힘 상태 |
onOpenChange | (open: boolean) => void | - | SpeedDial 상태 변경 핸들러 |
direction | "up" | "down" | "left" | "right" | "up" | Actions가 나타나는 방향 |
color | string | - | Trigger 버튼 배경 색상 |
closeOnClickOutside | boolean | true | 외부 클릭 시 자동으로 닫기 |
closeOnEscapeKey | boolean | true | ESC 키로 닫기 |
SpeedDial.Trigger
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
asChild | boolean | false | 래퍼 없이 자식 요소만 렌더링 |
SpeedDial.Action
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
asChild | boolean | false | 래퍼 없이 자식 요소만 렌더링 |
예제
방향: 위로
TSX
1"use client";
2
3import { useState } from "react";
4import { SpeedDial } from "motile-ui";
5
6export default function DirectionUpExample() {
7 const [open, setOpen] = useState(false);
8
9 return (
10 <div style={{ display: "flex", alignItems: "center", justifyContent: "center", minHeight: "300px" }}>
11 <SpeedDial.Root open={open} onOpenChange={setOpen} direction="up">
12 <SpeedDial.Trigger>↑</SpeedDial.Trigger>
13 <SpeedDial.Actions>
14 {[1, 2, 3].map((num) => (
15 <SpeedDial.Action key={num} onClick={() => alert(`Action ${num}`)}>
16 {num}
17 </SpeedDial.Action>
18 ))}
19 </SpeedDial.Actions>
20 </SpeedDial.Root>
21 </div>
22 );
23}방향: 아래로
TSX
1"use client";
2
3import { useState } from "react";
4import { SpeedDial } from "motile-ui";
5
6export default function DirectionDownExample() {
7 const [open, setOpen] = useState(false);
8
9 return (
10 <div style={{ display: "flex", alignItems: "center", justifyContent: "center", minHeight: "300px" }}>
11 <SpeedDial.Root open={open} onOpenChange={setOpen} direction="down">
12 <SpeedDial.Trigger>↓</SpeedDial.Trigger>
13 <SpeedDial.Actions>
14 {[1, 2, 3].map((num) => (
15 <SpeedDial.Action key={num} onClick={() => alert(`Action ${num}`)}>
16 {num}
17 </SpeedDial.Action>
18 ))}
19 </SpeedDial.Actions>
20 </SpeedDial.Root>
21 </div>
22 );
23}방향: 왼쪽으로
TSX
1"use client";
2
3import { useState } from "react";
4import { SpeedDial } from "motile-ui";
5
6export default function DirectionLeftExample() {
7 const [open, setOpen] = useState(false);
8
9 return (
10 <div style={{ display: "flex", alignItems: "center", justifyContent: "center", minHeight: "300px" }}>
11 <SpeedDial.Root open={open} onOpenChange={setOpen} direction="left">
12 <SpeedDial.Trigger>←</SpeedDial.Trigger>
13 <SpeedDial.Actions>
14 {[1, 2, 3].map((num) => (
15 <SpeedDial.Action key={num} onClick={() => alert(`Action ${num}`)}>
16 {num}
17 </SpeedDial.Action>
18 ))}
19 </SpeedDial.Actions>
20 </SpeedDial.Root>
21 </div>
22 );
23}방향: 오른쪽으로
TSX
1"use client";
2
3import { useState } from "react";
4import { SpeedDial } from "motile-ui";
5
6export default function DirectionRightExample() {
7 const [open, setOpen] = useState(false);
8
9 return (
10 <div style={{ display: "flex", alignItems: "center", justifyContent: "center", minHeight: "300px" }}>
11 <SpeedDial.Root open={open} onOpenChange={setOpen} direction="right">
12 <SpeedDial.Trigger>→</SpeedDial.Trigger>
13 <SpeedDial.Actions>
14 {[1, 2, 3].map((num) => (
15 <SpeedDial.Action key={num} onClick={() => alert(`Action ${num}`)}>
16 {num}
17 </SpeedDial.Action>
18 ))}
19 </SpeedDial.Actions>
20 </SpeedDial.Root>
21 </div>
22 );
23}아이콘 사용
TSX
1"use client";
2
3import { useState } from "react";
4import { SpeedDial } from "motile-ui";
5import ShareIcon from "@/app/_components/icons/ShareIcon";
6import CopyIcon from "@/app/_components/icons/CopyIcon";
7import TwitterIcon from "@/app/_components/icons/TwitterIcon";
8import FacebookIcon from "@/app/_components/icons/FacebookIcon";
9import LinkIcon from "@/app/_components/icons/LinkIcon";
10
11export default function WithIconsExample() {
12 const [open, setOpen] = useState(false);
13
14 return (
15 <div style={{ display: "flex", alignItems: "center", justifyContent: "center", minHeight: "300px" }}>
16 <SpeedDial.Root open={open} onOpenChange={setOpen} direction="up">
17 <SpeedDial.Trigger>
18 <ShareIcon />
19 </SpeedDial.Trigger>
20 <SpeedDial.Actions>
21 <SpeedDial.Action aria-label="Copy Link" onClick={() => alert("Copy Link")}>
22 <CopyIcon />
23 </SpeedDial.Action>
24 <SpeedDial.Action aria-label="Share on Twitter" onClick={() => alert("Share on Twitter")}>
25 <TwitterIcon />
26 </SpeedDial.Action>
27 <SpeedDial.Action aria-label="Share on Facebook" onClick={() => alert("Share on Facebook")}>
28 <FacebookIcon />
29 </SpeedDial.Action>
30 <SpeedDial.Action aria-label="Get Link" onClick={() => alert("Get Link")}>
31 <LinkIcon />
32 </SpeedDial.Action>
33 </SpeedDial.Actions>
34 </SpeedDial.Root>
35 </div>
36 );
37}