Vela UI Docsvenizia.ai

Popover

Floating content anchored to a trigger and opened on click.

npx shadcn@latest add @velaui/popover
npx shadcn@latest add @velaui/popover

Examples

  • Default

View code

Popover · Default

Installation

pnpm dlx velaui add @velaui/popover
pnpm dlx velaui add @velaui/popover

Code

popover-default.tsx
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";

export default function Example() {
  return (
    <Popover>
      <PopoverTrigger asChild>
        <Button variant="outline">Set dimensions</Button>
      </PopoverTrigger>
      <PopoverContent className="flex flex-col gap-3">
        <div className="flex flex-col gap-1">
          <p className="text-sm font-medium">Dimensions</p>
          <p className="text-sm text-text-muted">Set the size of the layer.</p>
        </div>
        <div className="grid grid-cols-[4rem_1fr] items-center gap-2">
          <Label htmlFor="width">Width</Label>
          <Input id="width" defaultValue="320px" />
          <Label htmlFor="height">Height</Label>
          <Input id="height" defaultValue="240px" />
        </div>
      </PopoverContent>
    </Popover>
  );
}
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";

export default function Example() {
  return (
    <Popover>
      <PopoverTrigger render={<Button variant="outline" />}>
        Set dimensions
      </PopoverTrigger>
      <PopoverContent className="flex flex-col gap-3">
        <div className="flex flex-col gap-1">
          <p className="text-sm font-medium">Dimensions</p>
          <p className="text-sm text-text-muted">Set the size of the layer.</p>
        </div>
        <div className="grid grid-cols-[4rem_1fr] items-center gap-2">
          <Label htmlFor="width">Width</Label>
          <Input id="width" defaultValue="320px" />
          <Label htmlFor="height">Height</Label>
          <Input id="height" defaultValue="240px" />
        </div>
      </PopoverContent>
    </Popover>
  );
}

Usage

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";

export default function Example() {
  return (
    <Popover>
      <PopoverTrigger asChild>
        <Button variant="outline">Set dimensions</Button>
      </PopoverTrigger>
      <PopoverContent className="flex flex-col gap-3">
        <div className="flex flex-col gap-1">
          <p className="text-sm font-medium">Dimensions</p>
          <p className="text-sm text-text-muted">Set the size of the layer.</p>
        </div>
        <div className="grid grid-cols-[4rem_1fr] items-center gap-2">
          <Label htmlFor="width">Width</Label>
          <Input id="width" defaultValue="320px" />
          <Label htmlFor="height">Height</Label>
          <Input id="height" defaultValue="240px" />
        </div>
      </PopoverContent>
    </Popover>
  );
}
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";

export default function Example() {
  return (
    <Popover>
      <PopoverTrigger render={<Button variant="outline" />}>
        Set dimensions
      </PopoverTrigger>
      <PopoverContent className="flex flex-col gap-3">
        <div className="flex flex-col gap-1">
          <p className="text-sm font-medium">Dimensions</p>
          <p className="text-sm text-text-muted">Set the size of the layer.</p>
        </div>
        <div className="grid grid-cols-[4rem_1fr] items-center gap-2">
          <Label htmlFor="width">Width</Label>
          <Input id="width" defaultValue="320px" />
          <Label htmlFor="height">Height</Label>
          <Input id="height" defaultValue="240px" />
        </div>
      </PopoverContent>
    </Popover>
  );
}

Props

Popover

Takes every prop of PopoverProps.

PopoverTrigger

Takes every prop of PopoverTriggerProps.

PopoverAnchor

Takes every prop of PopoverAnchorProps.

PopoverContent

PropTypeDefault
align"center" | "start" | "end""center"
sideOffsetnumber8

Takes these and every prop of PopoverContentProps.

Popover

Takes every prop of PopoverProps.

PopoverContent

PropTypeDefault
alignimport("/app/node_modules/.bun/@base-ui+react@1.6.0+df7f6a806acd27ca/node_modules/@base-ui/react/utils/useAnchorPositioning").Align"center"
alignOffsetnumber | import("/app/node_modules/.bun/@base-ui+react@1.6.0+df7f6a806acd27ca/node_modules/@base-ui/react/utils/useAnchorPositioning").OffsetFunction0
sideimport("/app/node_modules/.bun/@base-ui+react@1.6.0+df7f6a806acd27ca/node_modules/@base-ui/react/utils/useAnchorPositioning").Side"bottom"
sideOffsetnumber | import("/app/node_modules/.bun/@base-ui+react@1.6.0+df7f6a806acd27ca/node_modules/@base-ui/react/utils/useAnchorPositioning").OffsetFunction8

Takes these and every prop of PopoverContentProps.

PopoverTrigger

Takes every prop of PopoverTriggerProps.

Dependencies

npm
radix-ui@1.6.0
Installs with it
nothing else
npm
@base-ui/react@1.6.0
Installs with it
nothing else

Source

components/ui/popover.tsx
import * as React from "react";
import { Popover as PopoverPrimitive } from "radix-ui";

import { cn } from "@/lib/utils";

export type PopoverProps = React.ComponentProps<typeof PopoverPrimitive.Root>;

function Popover({
  ...props
}: PopoverProps) {
  return <PopoverPrimitive.Root data-slot="popover" {...props} />;
}

export type PopoverTriggerProps = React.ComponentProps<typeof PopoverPrimitive.Trigger>;

function PopoverTrigger({
  ...props
}: PopoverTriggerProps) {
  return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
}

export type PopoverAnchorProps = React.ComponentProps<typeof PopoverPrimitive.Anchor>;

function PopoverAnchor({
  ...props
}: PopoverAnchorProps) {
  return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />;
}

export type PopoverContentProps = React.ComponentProps<typeof PopoverPrimitive.Content>;

function PopoverContent({
  className,
  align = "center",
  sideOffset = 8,
  ...props
}: PopoverContentProps) {
  return (
    <PopoverPrimitive.Portal>
      <PopoverPrimitive.Content
        data-slot="popover-content"
        align={align}
        sideOffset={sideOffset}
        className={cn(
          "z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-xl border border-border-default bg-bg-main p-4 text-text-strong shadow-md outline-hidden duration-100 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
          className,
        )}
        {...props}
      />
    </PopoverPrimitive.Portal>
  );
}

export { Popover, PopoverTrigger, PopoverAnchor, PopoverContent };
components/ui/popover.tsx
import { Popover as PopoverPrimitive } from "@base-ui/react/popover";

import { cn } from "@/lib/utils";

export type PopoverProps = PopoverPrimitive.Root.Props;

function Popover({ ...props }: PopoverProps) {
  return <PopoverPrimitive.Root data-slot="popover" {...props} />;
}

export type PopoverTriggerProps = PopoverPrimitive.Trigger.Props;

function PopoverTrigger({ ...props }: PopoverTriggerProps) {
  return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
}

export type PopoverContentProps = PopoverPrimitive.Popup.Props &
  Pick<
    PopoverPrimitive.Positioner.Props,
    "align" | "alignOffset" | "side" | "sideOffset"
  >;

function PopoverContent({
  className,
  align = "center",
  alignOffset = 0,
  side = "bottom",
  sideOffset = 8,
  ...props
}: PopoverContentProps) {
  return (
    <PopoverPrimitive.Portal>
      <PopoverPrimitive.Positioner
        align={align}
        alignOffset={alignOffset}
        side={side}
        sideOffset={sideOffset}
        className="isolate z-50"
      >
        <PopoverPrimitive.Popup
          data-slot="popover-content"
          className={cn(
            "z-50 w-72 origin-(--transform-origin) rounded-xl border border-border-default bg-bg-main p-4 text-text-strong shadow-md outline-hidden duration-100 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
            className,
          )}
          {...props}
        />
      </PopoverPrimitive.Positioner>
    </PopoverPrimitive.Portal>
  );
}

export { Popover, PopoverContent, PopoverTrigger };