컴포넌트
Popover
기준 요소 옆에 내용이나 작업을 표시합니다.
설치
pnpm dlx ply-ui add popover공통 설치 설정을 먼저 적용합니다.
사용법
Positioner의 side/align/sideOffset으로 위치를 조절합니다.
Title/Description을 넣고, 사용자가 작업을 마치면 Close로 닫을 수 있습니다.
구성
| 구성 요소 | 역할 |
|---|---|
Root | 열림 상태를 관리합니다. |
Trigger | 클릭해서 내용을 여는 버튼입니다. |
Portal / Positioner | 팝오버를 버튼 기준으로 배치합니다. |
Popup | 내용을 담는 표면입니다. variant로 색상을 바꿉니다. |
Title / Description | 제목과 설명입니다. |
Arrow | 버튼 방향을 가리키는 표시입니다. |
Close | 팝오버를 닫습니다. |
Standard
Popup variant="standard"는 기본 표면 색상입니다.
Inverse
Popup variant="inverse"는 반전된 표면과 글자 색상입니다.
속성
이 프로젝트에서 추가하거나 제한한 속성입니다.
Popup
속성
타입
구현 코드
components/ui/popover.tsx
"use client";
import type { ComponentProps } from "react";
import { Popover as Primitive } from "@base-ui/react/popover";
import { withClassName } from "../../lib/cx";
import "./popover.css";
// 동작과 접근성은 Base UI가 담당합니다. 이 파일은 스타일 연결만 담당합니다.
function PopoverTrigger({
className,
...props
}: ComponentProps<typeof Primitive.Trigger>) {
return (
<Primitive.Trigger
{...props}
className={withClassName("rbx-button", className)}
/>
);
}
export type PopoverPopupProps = ComponentProps<typeof Primitive.Popup> & {
/** 표면과 글자 색상입니다. @defaultValue "standard" */
variant?: "standard" | "inverse";
};
function PopoverPopup({
variant = "standard",
className,
...props
}: PopoverPopupProps) {
return (
<Primitive.Popup
{...props}
data-variant={variant}
className={withClassName("rbx-popup rbx-padded", className)}
/>
);
}
function PopoverPositioner({
className,
...props
}: ComponentProps<typeof Primitive.Positioner>) {
return (
<Primitive.Positioner
{...props}
className={withClassName("rbx-positioner", className)}
/>
);
}
function PopoverTitle({
className,
...props
}: ComponentProps<typeof Primitive.Title>) {
return (
<Primitive.Title
{...props}
className={withClassName("rbx-dialog-title", className)}
/>
);
}
function PopoverDescription({
className,
...props
}: ComponentProps<typeof Primitive.Description>) {
return (
<Primitive.Description
{...props}
className={withClassName("rbx-description", className)}
/>
);
}
function PopoverClose({
className,
...props
}: ComponentProps<typeof Primitive.Close>) {
return (
<Primitive.Close
{...props}
className={withClassName("rbx-button", className)}
/>
);
}
function PopoverArrow({
className,
...props
}: ComponentProps<typeof Primitive.Arrow>) {
return (
<Primitive.Arrow
{...props}
className={withClassName("rbx-popup-arrow", className)}
/>
);
}
// Root/Portal 등 스타일 없는 파트와 제네릭 API는 원본을 그대로 보존합니다.
export const Popover = {
...Primitive,
Trigger: PopoverTrigger,
Popup: PopoverPopup,
Positioner: PopoverPositioner,
Title: PopoverTitle,
Description: PopoverDescription,
Close: PopoverClose,
Arrow: PopoverArrow,
};
components/ui/popover.css
@import "./button.css";
/* Community educational tooltip variant. Standard popovers retain the shared surface. */
.rbx-popup[data-variant="inverse"] {
padding: 12px;
border: 0;
border-radius: 8px;
background: var(--rbx-inverse-surface-0);
color: var(--rbx-inverse-content-emphasis);
box-shadow: none;
}
.rbx-popup[data-variant="inverse"] .rbx-description {
color: var(--rbx-inverse-content-default);
}
.rbx-popup[data-variant="inverse"] .rbx-popup-arrow {
fill: var(--rbx-inverse-surface-0);
}