Context
๋ฒํผ์ ๋๋ฅด๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅํ ๋ ๋ณด์กฐ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์ถ์ ๋๊ฐ ์๋ค. ์ด ๋ Popover ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ณด์กฐ ์ ๋ณด๋ฅผ ํ์ํ๋๋ฐ, shadcn/ui์ Popover๋ฅผ ์ฌ์ฉํด๋ณด๊ธฐ ์ํด ์ด ๊ธ์ ์์ฑํ๋ค.
Agenda
โข
shadcn/ui์ Popover ์ปดํฌ๋ํธ๋ฅผ ๋ถ์ํ๊ณ ์ดํดํ๋ ๊ฒ์ ๋ชฉํ๋ก ํจ
Contents
๋ฒํผ์ ๋๋ ์ ๋๋ ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅํ ๋ ๋ณด์กฐ ์ ๋ณด๋ฅผ ํ๋ฉด์ ํ์ํ๊ณ ์ถ์ ๋๊ฐ ์๋ค. Overlay๋ฅผ ๋๋ฐํ์ฌ ํ๋ฉด ์ ์ฒด๋ฅผ ๋๋ฌ์ธ๋ ๊ฒ์ด ์๋ ๊ฐ๋ฒผ์ด ๋ ์ด์ด๋ก ๋ณด์ฌ์ฃผ๋ ๊ฒ ๋ง์ด๋ค. shadcn/ui๋ ์ด๋ฐ ์ํฉ์ ์ํด Popover ์ปดํฌ๋ํธ๋ฅผ ์ ๊ณตํ๋ค.
Popover
const Popover = ({
...props
}: React.ComponentProps<typeof PopoverPrimitive.Root>) => {
return <PopoverPrimitive.Root data-slot='popover' {...props} />;
};
TypeScript
๋ณต์ฌ
Popover ์ปดํฌ๋ํธ์ด๋ค. radix-ui์ Popover - Root ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ธ๋ Wrapper ํํ๋ก ๋ง๋ค์ด์ก๋ค.
PopoverTrigger
const PopoverTrigger = ({
...props
}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) => {
return <PopoverPrimitive.Trigger data-slot='popover-trigger' {...props} />;
};
TypeScript
๋ณต์ฌ
PopoverTrigger ์ปดํฌ๋ํธ๋ Popover์ ์ด๋ฆผ / ๋ซํ ์ํ๋ฅผ ํ ๊ธํ๋ ์ปดํฌ๋ํธ์ด๋ค.
PopoverContent
const PopoverContent = ({
className,
align = 'center',
sideOffset = 4,
...props
}: React.ComponentProps<typeof PopoverPrimitive.Content>) => {
return (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
data-slot='popover-content'
align={align}
sideOffset={sideOffset}
className={cn(
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden',
className,
)}
{...props}
/>
</PopoverPrimitive.Portal>
);
};
TypeScript
๋ณต์ฌ
Popover์ ์ปจํ
์ธ ๊ฐ ํ์ ๋๋ ์ปดํฌ๋ํธ์ด๋ค. align์ center, start, end ๊ฐ ์ค ํ๋๋ฅผ ๋ถ์ฌํ ์ ์๋ค. className์ ๋ค์ด์๋ ์คํ์ผ๋ง ๊ฐ์ ๋งค์ฐ ๊ธด๋ฐ, ๊ฑฐ์ ์ ๋๋ฉ์ด์
๊ณผ ๊ด๋ จ ๋ ๊ฐ๋ค์ด๋ค.
PopoverAnchor
const PopoverAnchor = ({
...props
}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) => {
return <PopoverPrimitive.Anchor data-slot='popover-anchor' {...props} />;
};
TypeScript
๋ณต์ฌ
pnpm dlx shadcn@latest add popover๋ฅผ ํตํด popover๋ฅผ ์ถ๊ฐํ์ ๋ ๊ฐ์ด ์์ฑ ๋๋ ์ปดํฌ๋ํธ์ด๋ค. ์ด๋ ๊ธฐ๋ฅ์ ํ๋ ์ปดํฌ๋ํธ์ธ์ง ๊ถ๊ธํ์ฌ ๊ณต์ ์ฌ์ดํธ์์ ๋ ํผ๋ฐ์ค๋ฅผ ์ฐพ์๋ณด๋ ค๊ณ ํ๋๋ฐ ๋์ค์ง ์๋๋ค.
๋๋์ Trigger๋ฅผ ์ ํํ๋ฉด Trigger ๊ธฐ์ค์ผ๋ก Popover๊ฐ ํ์๋๋๋ฐ Anchor๋ฅผ ์ฌ์ฉํ๋ฉด ๊ทธ Anchor๋ฅผ ๊ธฐ์ค์ผ๋ก ๋์ค๋ ๊ฒ ๊ฐ์ ์คํ์ ํด๋ณด์๋ค.
<Popover>
<PopoverTrigger asChild>
<Button>Trigger</Button>
</PopoverTrigger>
<PopoverAnchor>
<div className='relative border-4'>
<span>Anchor</span>
</div>
</PopoverAnchor>
<PopoverContent align='start'>Description</PopoverContent>
</Popover>
TypeScript
๋ณต์ฌ
Trigger๋ฅผ ํด๋ฆญํ๋ฉด Anchor๊ฐ ์์์ ๋ Trigger ๋ฐ๋ก ์๋์ Popover๊ฐ ๋์ค์ง๋ง, Anchor๋ฅผ ์์ฑํ๋ฉด ๊ทธ Anchor๋ฅผ ๊ธฐ์ค์ผ๋ก Popover๊ฐ ํ์๋๋ ๊ฒ์ ์ ์ ์์๋ค.
