Popover
Playground
TSX
'use client';
import { useState } from 'react';
import {
Popover,
PopoverTrigger,
PopoverContent,
Button,
Input,
type PopoverSize,
} from '@mbsw/ui';
import { Check, Copy } from 'lucide-react';
export default function Demo() {
const settings = {
"align": "center",
"label": "open",
"title": "link",
"content": "https://example.com/document",
"size": "md",
"side": "top"
};
const [copyState, setCopyState] = useState<'idle' | 'copied' | 'error'>(
'idle',
);
const link = settings.content;
return (
<div
style={{
display: 'flex',
width: '100%',
justifyContent:
settings.side === 'right'
? 'flex-start'
: settings.side === 'left'
? 'flex-end'
: 'center',
}}
>
<Popover onOpenChange={() => setCopyState('idle')}>
<PopoverTrigger asChild>
<Button variant="solid" tone="secondary">
{settings.label}
</Button>
</PopoverTrigger>
<PopoverContent
size={settings.size as PopoverSize}
side={settings.side as 'top' | 'right' | 'bottom' | 'left'}
align={settings.align as 'start' | 'center' | 'end'}
sideOffset={8}
aria-label={settings.title || 'Popover'}
collisionPadding={16}
style={{
maxWidth:
'min(calc(100vw - 32px), var(--radix-popover-content-available-width))',
}}
>
<div style={{ display: 'grid', gap: 12 }}>
<label htmlFor="link" style={{ fontWeight: 600 }}>
{settings.title}
</label>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Input
id="link"
size="md"
readOnly
value={link}
style={{ minWidth: 0, flex: 1 }}
/>
<Button
iconOnly
icon={copyState === 'copied' ? Check : Copy}
size="lg"
variant="outline"
tone="secondary"
aria-label={
copyState === 'copied' ? "링크 복사됨" : "링크 복사"
}
style={{ flexShrink: 0 }}
onClick={async () => {
try {
await navigator.clipboard.writeText(link);
setCopyState('copied');
} catch {
setCopyState('error');
}
}}
/>
</div>
{copyState === 'error' && (
<span role="alert">{"링크를 선택해 직접 복사해주세요."}</span>
)}
</div>
</PopoverContent>
</Popover>
</div>
);
}
Properties
Size
Side
Align
Content
Trigger
Title
Link
Usage
PopoverContent는 portal로 표시됩니다. actions에는 Button을 전달합니다. HoverCard는 보충 정보에 사용하며 필수 작업을 hover에만 숨기지 않습니다.
TSX
'use client';
import { Popover, PopoverTrigger, PopoverContent, Button } from '@mbsw/ui';
export default function Example() {
return (
<Popover>
<PopoverTrigger asChild>
<Button>open</Button>
</PopoverTrigger>
<PopoverContent aria-label="link">
https://example.com/document
</PopoverContent>
</Popover>
);
}
Playground의 Code 탭에서 현재 설정과 동작이 포함된 예제 전체를 복사할 수 있습니다. 공통 CSS 설치는 설치하기를 확인하세요.
Composition
HoverCard
TSX
'use client';
import { HoverCard, HoverCardTrigger, HoverCardContent } from '@mbsw/ui';
export default function Demo() {
const settings = {
"title": "MBSW",
"description": "React 컴포넌트와 디자인 토큰"
};
return (
<HoverCard>
<HoverCardTrigger asChild>
<a
href="https://www.npmjs.com/package/@mbsw/ui"
target="_blank"
rel="noreferrer"
>
{"MBSW 프로젝트"}
</a>
</HoverCardTrigger>
<HoverCardContent>
<strong>{settings.title}</strong>
<p style={{ whiteSpace: 'pre-wrap' }}>{settings.description}</p>
</HoverCardContent>
</HoverCard>
);
}
Content
Title
Description