Speed Dial
Speed Dial (스피드 다이얼)
플로팅 액션 버튼을 눌렀을 때 3~6개의 관련 동작을 Speed Dial 형태로 표시하는 컴포넌트에 대해 알아봅니다.
출처: 문서
본문
플로팅 액션 버튼이 눌리면 3~6개의 관련 동작을 Speed Dial 형태로 표시할 수 있어요.
6개 이상의 동작이 필요하다면, FAB가 아닌 다른 것을 사용해 그것들을 제시해야 합니다.
기본 speed dial (Basic speed dial)
플로팅 액션 버튼은 관련 동작들을 표시할 수 있어요.
import Box from '@mui/material/Box';
import SpeedDial from '@mui/material/SpeedDial';
import SpeedDialIcon from '@mui/material/SpeedDialIcon';
import SpeedDialAction from '@mui/material/SpeedDialAction';
import FileCopyIcon from '@mui/icons-material/FileCopyOutlined';
import SaveIcon from '@mui/icons-material/Save';
import PrintIcon from '@mui/icons-material/Print';
import ShareIcon from '@mui/icons-material/Share';
const actions = [
{ icon: <FileCopyIcon />, name: 'Copy' },
{ icon: <SaveIcon />, name: 'Save' },
{ icon: <PrintIcon />, name: 'Print' },
{ icon: <ShareIcon />, name: 'Share' },
];
export default function BasicSpeedDial() {
return (
<Box sx={{ height: 320, transform: 'translateZ(0px)', flexGrow: 1 }}>
<SpeedDial
ariaLabel="SpeedDial basic example"
sx={{ position: 'absolute', bottom: 16, right: 16 }}
icon={<SpeedDialIcon />}
>
{actions.map((action) => (
<SpeedDialAction
key={action.name}
icon={action.icon}
slotProps={{
tooltip: {
title: action.name,
},
}}
/>
))}
</SpeedDial>
</Box>
);
}
플레이그라운드 (Playground)
import * as React from 'react';
import { styled } from '@mui/material/styles';
import Box from '@mui/material/Box';
import FormControl from '@mui/material/FormControl';
import FormControlLabel from '@mui/material/FormControlLabel';
import FormLabel from '@mui/material/FormLabel';
import Radio from '@mui/material/Radio';
import RadioGroup from '@mui/material/RadioGroup';
import Switch from '@mui/material/Switch';
import SpeedDial, { SpeedDialProps } from '@mui/material/SpeedDial';
import SpeedDialIcon from '@mui/material/SpeedDialIcon';
import SpeedDialAction from '@mui/material/SpeedDialAction';
import FileCopyIcon from '@mui/icons-material/FileCopyOutlined';
import SaveIcon from '@mui/icons-material/Save';
import PrintIcon from '@mui/icons-material/Print';
import ShareIcon from '@mui/icons-material/Share';
const StyledSpeedDial = styled(SpeedDial)(({ theme }) => ({
position: 'absolute',
'&.MuiSpeedDial-directionUp, &.MuiSpeedDial-directionLeft': {
bottom: theme.spacing(2),
right: theme.spacing(2),
},
'&.MuiSpeedDial-directionDown, &.MuiSpeedDial-directionRight': {
top: theme.spacing(2),
left: theme.spacing(2),
},
}));
const actions = [
{ icon: <FileCopyIcon />, name: 'Copy' },
{ icon: <SaveIcon />, name: 'Save' },
{ icon: <PrintIcon />, name: 'Print' },
{ icon: <ShareIcon />, name: 'Share' },
];
export default function PlaygroundSpeedDial() {
const [direction, setDirection] =
React.useState<SpeedDialProps['direction']>('up');
const [hidden, setHidden] = React.useState(false);
const handleDirectionChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setDirection(
(event.target as HTMLInputElement).value as SpeedDialProps['direction'],
);
};
const handleHiddenChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setHidden(event.target.checked);
};
return (
<Box sx={{ transform: 'translateZ(0px)', flexGrow: 1 }}>
<FormControlLabel
control={
<Switch checked={hidden} onChange={handleHiddenChange} color="primary" />
}
label="Hidden"
/>
<FormControl component="fieldset" sx={{ mt: 1, display: 'flex' }}>
<FormLabel component="legend">Direction</FormLabel>
<RadioGroup
aria-label="direction"
name="direction"
value={direction}
onChange={handleDirectionChange}
row
>
<FormControlLabel value="up" control={<Radio />} label="Up" />
<FormControlLabel value="right" control={<Radio />} label="Right" />
<FormControlLabel value="down" control={<Radio />} label="Down" />
<FormControlLabel value="left" control={<Radio />} label="Left" />
</RadioGroup>
</FormControl>
<Box sx={{ position: 'relative', mt: 3, height: 320 }}>
<StyledSpeedDial
ariaLabel="SpeedDial playground example"
hidden={hidden}
icon={<SpeedDialIcon />}
direction={direction}
>
{actions.map((action) => (
<SpeedDialAction
key={action.name}
icon={action.icon}
slotProps={{
tooltip: {
title: action.name,
},
}}
/>
))}
</StyledSpeedDial>
</Box>
</Box>
);
}
제어되는 speed dial (Controlled speed dial)
컴포넌트의 열림 상태는 open/onOpen/onClose props로 제어할 수 있어요.
import * as React from 'react';
import Box from '@mui/material/Box';
import SpeedDial from '@mui/material/SpeedDial';
import SpeedDialIcon from '@mui/material/SpeedDialIcon';
import SpeedDialAction from '@mui/material/SpeedDialAction';
import FileCopyIcon from '@mui/icons-material/FileCopyOutlined';
import SaveIcon from '@mui/icons-material/Save';
import PrintIcon from '@mui/icons-material/Print';
import ShareIcon from '@mui/icons-material/Share';
const actions = [
{ icon: <FileCopyIcon />, name: 'Copy' },
{ icon: <SaveIcon />, name: 'Save' },
{ icon: <PrintIcon />, name: 'Print' },
{ icon: <ShareIcon />, name: 'Share' },
];
export default function ControlledOpenSpeedDial() {
const [open, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
return (
<Box sx={{ height: 320, transform: 'translateZ(0px)', flexGrow: 1 }}>
<SpeedDial
ariaLabel="SpeedDial controlled open example"
sx={{ position: 'absolute', bottom: 16, right: 16 }}
icon={<SpeedDialIcon />}
onClose={handleClose}
onOpen={handleOpen}
open={open}
>
{actions.map((action) => (
<SpeedDialAction
key={action.name}
icon={action.icon}
slotProps={{
tooltip: {
title: action.name,
},
}}
onClick={handleClose}
/>
))}
</SpeedDial>
</Box>
);
}
커스텀 닫기 아이콘 (Custom close icon)
SpeedDialIcon 컴포넌트의 icon과 openIcon props로 닫힘/열림 상태에 대한 대체 아이콘을 제공할 수 있어요.
import Box from '@mui/material/Box';
import SpeedDial from '@mui/material/SpeedDial';
import SpeedDialIcon from '@mui/material/SpeedDialIcon';
import SpeedDialAction from '@mui/material/SpeedDialAction';
import FileCopyIcon from '@mui/icons-material/FileCopyOutlined';
import SaveIcon from '@mui/icons-material/Save';
import PrintIcon from '@mui/icons-material/Print';
import ShareIcon from '@mui/icons-material/Share';
import EditIcon from '@mui/icons-material/Edit';
const actions = [
{ icon: <FileCopyIcon />, name: 'Copy' },
{ icon: <SaveIcon />, name: 'Save' },
{ icon: <PrintIcon />, name: 'Print' },
{ icon: <ShareIcon />, name: 'Share' },
];
export default function OpenIconSpeedDial() {
return (
<Box sx={{ height: 320, transform: 'translateZ(0px)', flexGrow: 1 }}>
<SpeedDial
ariaLabel="SpeedDial openIcon example"
sx={{ position: 'absolute', bottom: 16, right: 16 }}
icon={<SpeedDialIcon openIcon={<EditIcon />} />}
>
{actions.map((action) => (
<SpeedDialAction
key={action.name}
icon={action.icon}
slotProps={{
tooltip: {
title: action.name,
},
}}
/>
))}
</SpeedDial>
</Box>
);
}
상시 표시 동작 툴팁 (Persistent action tooltips)
SpeedDialAction의 툴팁은 상시 표시되도록 할 수 있어, 터치 기기에서 툴팁을 보기 위해 길게 누를 필요가 없게 해 줍니다.
데모 목적으로 여기서는 모든 기기에서 활성화했지만, 프로덕션에서는 isTouch 로직을 사용해 조건부로 prop을 설정할 수 있을 거예요.
import * as React from 'react';
import Box from '@mui/material/Box';
import Backdrop from '@mui/material/Backdrop';
import SpeedDial from '@mui/material/SpeedDial';
import SpeedDialIcon from '@mui/material/SpeedDialIcon';
import SpeedDialAction from '@mui/material/SpeedDialAction';
import FileCopyIcon from '@mui/icons-material/FileCopyOutlined';
import SaveIcon from '@mui/icons-material/Save';
import PrintIcon from '@mui/icons-material/Print';
import ShareIcon from '@mui/icons-material/Share';
const actions = [
{ icon: <FileCopyIcon />, name: 'Copy' },
{ icon: <SaveIcon />, name: 'Save' },
{ icon: <PrintIcon />, name: 'Print' },
{ icon: <ShareIcon />, name: 'Share' },
];
export default function SpeedDialTooltipOpen() {
const [open, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
return (
<Box sx={{ height: 330, transform: 'translateZ(0px)', flexGrow: 1 }}>
<Backdrop open={open} />
<SpeedDial
ariaLabel="SpeedDial tooltip example"
sx={{ position: 'absolute', bottom: 16, right: 16 }}
icon={<SpeedDialIcon />}
onClose={handleClose}
onOpen={handleOpen}
open={open}
>
{actions.map((action) => (
<SpeedDialAction
key={action.name}
icon={action.icon}
slotProps={{
tooltip: {
open: true,
title: action.name,
},
}}
onClick={handleClose}
/>
))}
</SpeedDial>
</Box>
);
}
전환 (Transitions)
Speed Dial은 기본적으로 Zoom을 사용합니다. 다른 전환 효과로 바꾸거나 전환 관련 props를 넘기고 싶다면 slots.transition과 slotProps.transition을 쓰면 돼요. 타이밍을 제어하려면 transitionDuration을 사용하세요.
접근성 (Accessibility)
ARIA
필수 (Required)
- speed dial 컴포넌트에
ariaLabel을 제공해야 합니다. - 각 speed dial 동작에
slotProps.tooltip.title을 사용해 툴팁 제목을 제공해야 합니다.
제공됨 (Provided)
- Fab은
aria-haspopup,aria-expanded,aria-controls속성을 가집니다. - speed dial 동작 컨테이너는 direction에 따라 설정된
role="menu"와aria-orientation을 가집니다. - speed dial 동작은
role="menuitem"과, 관련 툴팁을 참조하는aria-describedby속성을 가집니다.
키보드 (Keyboard)
- speed dial은 포커스를 받으면 열립니다.
- Space와 Enter 키는 선택된 speed dial 동작을 트리거하고, speed dial의 열림 상태를 토글합니다.
- 커서 키는 포커스를 다음 또는 이전 speed dial 동작으로 이동시킵니다. (어떤 커서 방향이든 speed dial을 여는 데 처음에 사용될 수 있습니다. 이는 speed dial의 실제 또는 지각된 방향에 대한 기대 동작을 가능하게 해 줍니다. 예를 들어 드롭다운 메뉴로 인식하는 스크린 리더 사용자의 경우가 그렇죠.)
- Escape 키는 speed dial을 닫고, speed dial 동작이 포커스되어 있었다면 포커스를 Fab으로 되돌립니다.
SpeedDial API
Demos
이 React 컴포넌트의 사용 예시와 자세한 내용은 컴포넌트 데모 페이지에서 확인할 수 있어요.
Import
import SpeedDial from '@mui/material/SpeedDial';
// or
import { SpeedDial } from '@mui/material';
Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
| ariaLabel | string |
- | Yes | |
| children | node |
- | No | |
| classes | object |
- | No | Override or extend the styles applied to the component. |
| direction | 'down' | 'left' | 'right' | 'up' |
'up' |
No | |
| FabProps | object |
{} |
No | |
| hidden | bool |
false |
No | |
| icon | node |
- | No | |
| onClose | function(event: object, reason: string) => void |
- | No | |
| onOpen | function(event: object, reason: string) => void |
- | No | |
| open | bool |
- | No | |
| openIcon | node |
- | No | |
| slotProps | { root?: func | object, transition?: func | object } |
{} |
No | |
| slots | { root?: elementType, transition?: elementType } |
{} |
No | |
| sx | Array<func | object | bool> | func | object |
- | No | The system prop that allows defining system overrides as well as additional CSS styles. |
| transitionDuration | number | { appear?: number, enter?: number, exit?: number } |
`{ | ||
| enter: theme.transitions.duration.enteringScreen, | ||||
| exit: theme.transitions.duration.leavingScreen, | ||||
| }` | No |
참고:
ref는 루트 요소 (HTMLDivElement).
그 외에 제공된 props는 루트 요소 (native element).
Theme default props
MuiSpeedDial을 사용하면 테마에서 이 컴포넌트의 기본 props를 바꿀 수 있어요.
Slots
| Name | Default | Class | Description |
|---|---|---|---|
| root | 'div' |
.MuiSpeedDial-root |
The component that renders the root slot. |
| transition | Zoom |
- | The component that renders the transition. |
| Follow this guide to learn more about the requirements for this component. |
CSS
Rule name
| Global class | Rule name | Description |
|---|---|---|
| - | actions | Styles applied to the actions (children wrapper) element. |
| - | actionsClosed | Styles applied to the actions (children wrapper) element if open={false}. |
| - | directionDown | Styles applied to the root element if direction="down" |
| - | directionLeft | Styles applied to the root element if direction="left" |
| - | directionRight | Styles applied to the root element if direction="right" |
| - | directionUp | Styles applied to the root element if direction="up" |
| - | fab | Styles applied to the Fab component. |
Source code
이 페이지에서 원하는 정보를 찾지 못했다면, 더 자세한 내용은 컴포넌트 구현을 살펴보는 것도 좋아요.
SpeedDialAction API
Demos
이 React 컴포넌트의 사용 예시와 자세한 내용은 컴포넌트 데모 페이지에서 확인할 수 있어요.
Import
import SpeedDialAction from '@mui/material/SpeedDialAction';
// or
import { SpeedDialAction } from '@mui/material';
Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
| classes | object |
- | No | Override or extend the styles applied to the component. |
| delay | number |
0 |
No | |
| icon | node |
- | No | |
| id | string |
- | No | |
| open | bool |
- | No | |
| slotProps | { fab?: func | object, staticTooltip?: func | object, staticTooltipLabel?: func | object, tooltip?: func | object } |
{} |
No | |
| slots | { fab?: elementType, staticTooltip?: elementType, staticTooltipLabel?: elementType, tooltip?: elementType } |
{} |
No | |
| sx | Array<func | object | bool> | func | object |
- | No | The system prop that allows defining system overrides as well as additional CSS styles. |
참고:
ref는 루트 요소 (HTMLButtonElement).
그 외에 제공된 props는 루트 요소 (Tooltip).
Inheritance
위에서 명시적으로 다루진 않았지만, Tooltip 컴포넌트의 props도 SpeedDialAction에서 사용할 수 있어요.
Theme default props
MuiSpeedDialAction을 사용하면 테마에서 이 컴포넌트의 기본 props를 바꿀 수 있어요.
Slots
| Name | Default | Class | Description |
|---|---|---|---|
| fab | Fab |
.MuiSpeedDialAction-fab |
The component that renders the fab. |
| tooltip | Tooltip |
- | The component that renders the tooltip. |
| staticTooltip | 'span' |
.MuiSpeedDialAction-staticTooltip |
The component that renders the static tooltip. |
| staticTooltipLabel | 'span' |
.MuiSpeedDialAction-staticTooltipLabel |
The component that renders the static tooltip label. |
CSS
Rule name
| Global class | Rule name | Description |
|---|---|---|
| - | fabClosed | Styles applied to the Fab component if open={false}. |
| - | staticTooltipClosed | Styles applied to the root element if tooltipOpen={true} and open={false}. |
| - | tooltipPlacementLeft | Styles applied to the root element if tooltipOpen={true} and `tooltipPlacement="left"`` |
| - | tooltipPlacementRight | Styles applied to the root element if tooltipOpen={true} and `tooltipPlacement="right"`` |
Source code
이 페이지에서 원하는 정보를 찾지 못했다면, 더 자세한 내용은 컴포넌트 구현을 살펴보는 것도 좋아요.
SpeedDialIcon API
Demos
이 React 컴포넌트의 사용 예시와 자세한 내용은 컴포넌트 데모 페이지에서 확인할 수 있어요.
Import
import SpeedDialIcon from '@mui/material/SpeedDialIcon';
// or
import { SpeedDialIcon } from '@mui/material';
Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
| classes | object |
- | No | Override or extend the styles applied to the component. |
| icon | node |
- | No | |
| openIcon | node |
- | No | |
| sx | Array<func | object | bool> | func | object |
- | No | The system prop that allows defining system overrides as well as additional CSS styles. |
참고:
ref는 루트 요소 (HTMLSpanElement).
그 외에 제공된 props는 루트 요소 (native element).
Theme default props
MuiSpeedDialIcon을 사용하면 테마에서 이 컴포넌트의 기본 props를 바꿀 수 있어요.
CSS
Rule name
| Global class | Rule name | Description |
|---|---|---|
| - | icon | Styles applied to the icon component. |
| - | iconOpen | Styles applied to the icon component if open={true}. |
| - | iconWithOpenIconOpen | Styles applied to the icon when an openIcon is provided and if open={true}. |
| - | openIcon | Styles applied to the openIcon if provided. |
| - | openIconOpen | Styles applied to the openIcon if provided and if open={true}. |
| - | root | Styles applied to the root element. |
Source code
이 페이지에서 원하는 정보를 찾지 못했다면, 더 자세한 내용은 컴포넌트 구현을 살펴보는 것도 좋아요.