Motile UI

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

속성타입기본값설명
openboolean-SpeedDial 열림/닫힘 상태
onOpenChange(open: boolean) => void-SpeedDial 상태 변경 핸들러
direction"up" | "down" | "left" | "right""up"Actions가 나타나는 방향
colorstring-Trigger 버튼 배경 색상
closeOnClickOutsidebooleantrue외부 클릭 시 자동으로 닫기
closeOnEscapeKeybooleantrueESC 키로 닫기

SpeedDial.Trigger

속성타입기본값설명
asChildbooleanfalse래퍼 없이 자식 요소만 렌더링

SpeedDial.Action

속성타입기본값설명
asChildbooleanfalse래퍼 없이 자식 요소만 렌더링

예제

방향: 위로

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}
SpeedDial | Motile UI