Menu Sheet
사용자의 작업과 관련된 선택지를 제공하는 시트 형태의 컴포넌트입니다.
import { IconEyeSlashLine } from "@karrotmarket/react-monochrome-icon";
import { ActionButton } from "seed-design/ui/action-button";
import {
MenuSheetContent,
MenuSheetGroup,
MenuSheetItem,
MenuSheetRoot,
MenuSheetTrigger,
} from "seed-design/ui/menu-sheet";
const MenuSheetPreview = () => {
return (
<MenuSheetRoot>
<MenuSheetTrigger asChild>
<ActionButton variant="neutralSolid">Open</ActionButton>
</MenuSheetTrigger>
<MenuSheetContent
title="proident irure"
description="Aliqua fugiat adipisicing magna dolor laborum."
aria-label="Menu Sheet"
>
<MenuSheetGroup>
<MenuSheetItem
label="Action 1"
description="Est commodo veniam magna officia ad dolor esse aliquip laboris nisi do."
prefixIcon={<IconEyeSlashLine />}
/>
<MenuSheetItem label="Action 2" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 3" prefixIcon={<IconEyeSlashLine />} />
</MenuSheetGroup>
<MenuSheetGroup>
<MenuSheetItem label="Action 4" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 5" prefixIcon={<IconEyeSlashLine />} tone="critical" />
</MenuSheetGroup>
</MenuSheetContent>
</MenuSheetRoot>
);
};
export default MenuSheetPreview;Stackflow
Stackflow와 Menu Sheet를 함께 사용하는 방법에 대해 알아보세요.
Installation
npx @seed-design/cli@latest add ui:menu-sheetProps
MenuSheetRoot
Prop
Type
MenuSheetTrigger
Prop
Type
MenuSheetContent
Prop
Type
MenuSheetGroup
Prop
Type
MenuSheetItem
Prop
Type
Examples
With Title
MenuSheetContent의 title prop을 사용하여 시트 헤더에 제목을 표시합니다.
import { IconEyeSlashLine } from "@karrotmarket/react-monochrome-icon";
import { ActionButton } from "seed-design/ui/action-button";
import {
MenuSheetContent,
MenuSheetGroup,
MenuSheetItem,
MenuSheetRoot,
MenuSheetTrigger,
} from "seed-design/ui/menu-sheet";
const MenuSheetWithTitle = () => {
return (
<MenuSheetRoot>
<MenuSheetTrigger asChild>
<ActionButton variant="neutralSolid">Open</ActionButton>
</MenuSheetTrigger>
<MenuSheetContent title="Menu Sheet">
<MenuSheetGroup>
<MenuSheetItem label="Action 1" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem
label="Action 2"
prefixIcon={<IconEyeSlashLine />}
description="Ut nulla et id dolor labore ullamco irure est id occaecat."
/>
<MenuSheetItem
label="Action 3"
prefixIcon={<IconEyeSlashLine />}
description="Ut nulla et id dolor labore ullamco irure est id occaecat."
/>
</MenuSheetGroup>
<MenuSheetGroup>
<MenuSheetItem label="Action 4" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 5" prefixIcon={<IconEyeSlashLine />} tone="critical" />
</MenuSheetGroup>
</MenuSheetContent>
</MenuSheetRoot>
);
};
export default MenuSheetWithTitle;With Title and Description
MenuSheetContent의 description prop을 사용하여 제목 아래에 부가 설명을 추가합니다.
import { IconEyeSlashLine } from "@karrotmarket/react-monochrome-icon";
import { ActionButton } from "seed-design/ui/action-button";
import {
MenuSheetContent,
MenuSheetGroup,
MenuSheetItem,
MenuSheetRoot,
MenuSheetTrigger,
} from "seed-design/ui/menu-sheet";
export default function MenuSheetWithTitleAndDescription() {
return (
<MenuSheetRoot>
<MenuSheetTrigger asChild>
<ActionButton variant="neutralSolid">Open</ActionButton>
</MenuSheetTrigger>
<MenuSheetContent title="Menu Sheet" description="부가적인 설명이 여기에 표시됩니다.">
<MenuSheetGroup>
<MenuSheetItem label="Action 1" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem
label="Action 2"
prefixIcon={<IconEyeSlashLine />}
description="Ut nulla et id dolor labore ullamco irure est id occaecat."
/>
<MenuSheetItem
label="Action 3"
prefixIcon={<IconEyeSlashLine />}
description="Ut nulla et id dolor labore ullamco irure est id occaecat."
/>
</MenuSheetGroup>
<MenuSheetGroup>
<MenuSheetItem label="Action 4" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 5" prefixIcon={<IconEyeSlashLine />} tone="critical" />
</MenuSheetGroup>
</MenuSheetContent>
</MenuSheetRoot>
);
}Label Align
MenuSheetContent의 labelAlign prop으로 메뉴 항목의 레이블 정렬을 설정합니다.
labelAlign="left" (with PrefixIcon)
레이블을 왼쪽 정렬합니다.
import { IconEyeSlashLine } from "@karrotmarket/react-monochrome-icon";
import { ActionButton } from "seed-design/ui/action-button";
import {
MenuSheetContent,
MenuSheetGroup,
MenuSheetItem,
MenuSheetRoot,
MenuSheetTrigger,
} from "seed-design/ui/menu-sheet";
const MenuSheetWithPrefixIcon = () => {
return (
<MenuSheetRoot>
<MenuSheetTrigger asChild>
<ActionButton variant="neutralSolid">Open</ActionButton>
</MenuSheetTrigger>
<MenuSheetContent aria-label="Menu Sheet">
<MenuSheetGroup>
<MenuSheetItem label="Action 1" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 2" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 3" prefixIcon={<IconEyeSlashLine />} />
</MenuSheetGroup>
<MenuSheetGroup>
<MenuSheetItem label="Action 4" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 5" prefixIcon={<IconEyeSlashLine />} tone="critical" />
</MenuSheetGroup>
</MenuSheetContent>
</MenuSheetRoot>
);
};
export default MenuSheetWithPrefixIcon;labelAlign="center" (without PrefixIcon)
레이블을 중앙 정렬합니다. (일반적으로, prefixIcon 없는 경우)
import { ActionButton } from "seed-design/ui/action-button";
import {
MenuSheetContent,
MenuSheetGroup,
MenuSheetItem,
MenuSheetRoot,
MenuSheetTrigger,
} from "seed-design/ui/menu-sheet";
const MenuSheetWithoutPrefixIcon = () => {
return (
<MenuSheetRoot>
<MenuSheetTrigger asChild>
<ActionButton variant="neutralSolid">Open</ActionButton>
</MenuSheetTrigger>
<MenuSheetContent aria-label="Menu Sheet" labelAlign="center">
<MenuSheetGroup>
<MenuSheetItem label="Action 1" />
<MenuSheetItem label="Action 2" />
<MenuSheetItem label="Action 3" />
</MenuSheetGroup>
<MenuSheetGroup>
<MenuSheetItem label="Action 4" />
<MenuSheetItem label="Action 5" tone="critical" />
</MenuSheetGroup>
</MenuSheetContent>
</MenuSheetRoot>
);
};
export default MenuSheetWithoutPrefixIcon;Overriding labelAlign
필요한 경우 MenuSheetContent에 지정한 labelAlign을 MenuSheetGroup 또는 MenuSheetItem에 지정한 labelAlign으로 덮어쓸 수 있습니다.
import { ActionButton } from "seed-design/ui/action-button";
import {
MenuSheetContent,
MenuSheetGroup,
MenuSheetItem,
MenuSheetRoot,
MenuSheetTrigger,
} from "seed-design/ui/menu-sheet";
const MenuSheetOverridingLabelAlign = () => {
return (
<MenuSheetRoot>
<MenuSheetTrigger asChild>
<ActionButton variant="neutralSolid">Open</ActionButton>
</MenuSheetTrigger>
<MenuSheetContent aria-label="Menu Sheet" labelAlign="center">
<MenuSheetGroup labelAlign="left">
<MenuSheetItem label="Action 1" />
<MenuSheetItem label="Action 2" labelAlign="center" />
<MenuSheetItem label="Action 3" />
</MenuSheetGroup>
<MenuSheetGroup>
<MenuSheetItem label="Action 4" />
<MenuSheetItem label="Action 5" tone="critical" labelAlign="left" />
</MenuSheetGroup>
</MenuSheetContent>
</MenuSheetRoot>
);
};
export default MenuSheetOverridingLabelAlign;onOpenChange Details
onOpenChange 두 번째 인자로 details가 제공됩니다.
reason
열릴 때 (open: true)
"trigger":MenuSheetTrigger(MenuSheet.Trigger)로 열림
닫힐 때 (open: false)
"closeButton":MenuSheet.CloseButton으로 닫힘"escapeKeyDown": ESC 키 사용"interactOutside": 외부 영역 클릭
import { IconEyeSlashLine } from "@karrotmarket/react-monochrome-icon";
import { HStack, Text, VStack } from "@seed-design/react";
import { useState } from "react";
import { ActionButton } from "seed-design/ui/action-button";
import {
MenuSheetContent,
MenuSheetGroup,
MenuSheetItem,
MenuSheetRoot,
MenuSheetTrigger,
} from "seed-design/ui/menu-sheet";
export default function MenuSheetOnOpenChangeReason() {
const [open, setOpen] = useState(false);
const [openReason, setOpenReason] = useState<string | null>(null);
const [closeReason, setCloseReason] = useState<string | null>(null);
return (
<VStack gap="x4" align="center">
<MenuSheetRoot
open={open}
onOpenChange={(open, meta) => {
setOpen(open);
(open ? setOpenReason : setCloseReason)(meta?.reason ?? null);
}}
>
<MenuSheetTrigger asChild>
<ActionButton variant="neutralSolid">열기</ActionButton>
</MenuSheetTrigger>
<MenuSheetContent title="메뉴" aria-label="Menu Sheet">
<MenuSheetGroup>
<MenuSheetItem label="Action 1" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 2" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 3" prefixIcon={<IconEyeSlashLine />} />
</MenuSheetGroup>
</MenuSheetContent>
</MenuSheetRoot>
<HStack gap="x4">
<Text fontSize="t3" color="fg.neutralMuted">
마지막 열림 이유: {openReason ?? "-"}
</Text>
<Text fontSize="t3" color="fg.neutralMuted">
마지막 닫힘 이유: {closeReason ?? "-"}
</Text>
</HStack>
</VStack>
);
}Skip Animation
skipAnimation prop을 사용하여 MenuSheet의 enter/exit 애니메이션을 건너뛸 수 있습니다.
import { IconEyeSlashLine } from "@karrotmarket/react-monochrome-icon";
import { ActionButton } from "seed-design/ui/action-button";
import {
MenuSheetContent,
MenuSheetGroup,
MenuSheetItem,
MenuSheetRoot,
MenuSheetTrigger,
} from "seed-design/ui/menu-sheet";
const MenuSheetSkipAnimation = () => {
return (
<MenuSheetRoot skipAnimation>
<MenuSheetTrigger asChild>
<ActionButton variant="neutralSolid">Open</ActionButton>
</MenuSheetTrigger>
<MenuSheetContent aria-label="Menu Sheet">
<MenuSheetGroup>
<MenuSheetItem label="Action 1" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 2" prefixIcon={<IconEyeSlashLine />} />
<MenuSheetItem label="Action 3" prefixIcon={<IconEyeSlashLine />} />
</MenuSheetGroup>
</MenuSheetContent>
</MenuSheetRoot>
);
};
export default MenuSheetSkipAnimation;Last updated on