Popover
An overlay that displays additional information or options when triggered.
Usage
Favorite Framework
Tell us what is your favorite framework and why you love to use it.
import { XIcon } from 'lucide-react'
import { Box, Stack } from 'styled-system/jsx'
import { Button, IconButton, Popover } from '~/components/ui'
export const Demo = (props: Popover.RootProps) => {
  return (
    <Popover.Root {...props}>
      <Popover.Trigger asChild>
        <Button>Open Popover</Button>
      </Popover.Trigger>
      <Popover.Positioner>
        <Popover.Content>
          <Popover.Arrow>
            <Popover.ArrowTip />
          </Popover.Arrow>
          <Stack gap="1">
            <Popover.Title>Favorite Framework</Popover.Title>
            <Popover.Description>
              Tell us what is your favorite framework and why you love to use it.
            </Popover.Description>
          </Stack>
          <Box position="absolute" top="1" right="1">
            <Popover.CloseTrigger asChild>
              <IconButton aria-label="Close Popover" variant="ghost" size="sm">
                <XIcon />
              </IconButton>
            </Popover.CloseTrigger>
          </Box>
        </Popover.Content>
      </Popover.Positioner>
    </Popover.Root>
  )
}
Installation
npx @park-ui/cli components add popover1
Styled Primitive
Copy the code snippet below into ~/components/ui/primitives/popover.tsx
'use client'
import type { Assign } from '@ark-ui/react'
import { Popover } from '@ark-ui/react/popover'
import { type PopoverVariantProps, popover } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withRootProvider, withContext } = createStyleContext(popover)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withRootProvider<
  Assign<Popover.RootProviderProps, PopoverVariantProps>
>(Popover.RootProvider)
export type RootProps = ComponentProps<typeof Root>
export const Root = withRootProvider<Assign<Popover.RootProps, PopoverVariantProps>>(Popover.Root)
export const Anchor = withContext<
  HTMLDivElement,
  Assign<HTMLStyledProps<'div'>, Popover.AnchorBaseProps>
>(Popover.Anchor, 'anchor')
export const Arrow = withContext<
  HTMLDivElement,
  Assign<HTMLStyledProps<'div'>, Popover.ArrowBaseProps>
>(Popover.Arrow, 'arrow')
export const ArrowTip = withContext<
  HTMLDivElement,
  Assign<HTMLStyledProps<'div'>, Popover.ArrowTipBaseProps>
>(Popover.ArrowTip, 'arrowTip')
export const CloseTrigger = withContext<
  HTMLButtonElement,
  Assign<HTMLStyledProps<'button'>, Popover.CloseTriggerBaseProps>
>(Popover.CloseTrigger, 'closeTrigger')
export const Content = withContext<
  HTMLDivElement,
  Assign<HTMLStyledProps<'div'>, Popover.ContentBaseProps>
>(Popover.Content, 'content')
export const Description = withContext<
  HTMLDivElement,
  Assign<HTMLStyledProps<'div'>, Popover.DescriptionBaseProps>
>(Popover.Description, 'description')
export const Indicator = withContext<
  HTMLDivElement,
  Assign<HTMLStyledProps<'div'>, Popover.IndicatorBaseProps>
>(Popover.Indicator, 'indicator')
export const Positioner = withContext<
  HTMLDivElement,
  Assign<HTMLStyledProps<'div'>, Popover.PositionerBaseProps>
>(Popover.Positioner, 'positioner')
export const Title = withContext<
  HTMLDivElement,
  Assign<HTMLStyledProps<'div'>, Popover.TitleBaseProps>
>(Popover.Title, 'title')
export const Trigger = withContext<
  HTMLButtonElement,
  Assign<HTMLStyledProps<'button'>, Popover.TriggerBaseProps>
>(Popover.Trigger, 'trigger')
export { PopoverContext as Context } from '@ark-ui/react/popover'
import { type Assign, Popover } from '@ark-ui/solid'
import type { ComponentProps } from 'solid-js'
import { type PopoverVariantProps, popover } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withRootProvider, withContext } = createStyleContext(popover)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withRootProvider<
  Assign<Popover.RootProviderProps, PopoverVariantProps>
>(Popover.RootProvider)
export type RootProps = ComponentProps<typeof Root>
export const Root = withRootProvider<Assign<Popover.RootProps, PopoverVariantProps>>(Popover.Root)
export const Anchor = withContext<Assign<HTMLStyledProps<'div'>, Popover.AnchorBaseProps>>(
  Popover.Anchor,
  'anchor',
)
export const Arrow = withContext<Assign<HTMLStyledProps<'div'>, Popover.ArrowBaseProps>>(
  Popover.Arrow,
  'arrow',
)
export const ArrowTip = withContext<Assign<HTMLStyledProps<'div'>, Popover.ArrowTipBaseProps>>(
  Popover.ArrowTip,
  'arrowTip',
)
export const CloseTrigger = withContext<
  Assign<HTMLStyledProps<'button'>, Popover.CloseTriggerBaseProps>
>(Popover.CloseTrigger, 'closeTrigger')
export const Content = withContext<Assign<HTMLStyledProps<'div'>, Popover.ContentBaseProps>>(
  Popover.Content,
  'content',
)
export const Description = withContext<
  Assign<HTMLStyledProps<'div'>, Popover.DescriptionBaseProps>
>(Popover.Description, 'description')
export const Indicator = withContext<Assign<HTMLStyledProps<'div'>, Popover.IndicatorBaseProps>>(
  Popover.Indicator,
  'indicator',
)
export const Positioner = withContext<Assign<HTMLStyledProps<'div'>, Popover.PositionerBaseProps>>(
  Popover.Positioner,
  'positioner',
)
export const Title = withContext<Assign<HTMLStyledProps<'div'>, Popover.TitleBaseProps>>(
  Popover.Title,
  'title',
)
export const Trigger = withContext<Assign<HTMLStyledProps<'button'>, Popover.TriggerBaseProps>>(
  Popover.Trigger,
  'trigger',
)
export { PopoverContext as Context } from '@ark-ui/solid'
No snippet foundExtend ~/components/ui/primitives/index.ts with the following line:
export * as Popover from './popover'2
Integrate Recipe
If you're not using @park-ui/preset, add the following recipe to yourpanda.config.ts:
import { popoverAnatomy } from '@ark-ui/anatomy'
import { defineSlotRecipe } from '@pandacss/dev'
export const popover = defineSlotRecipe({
  className: 'popover',
  slots: popoverAnatomy.keys(),
  base: {
    positioner: {
      position: 'relative',
    },
    content: {
      background: 'bg.default',
      borderRadius: 'l3',
      boxShadow: 'lg',
      display: 'flex',
      flexDirection: 'column',
      maxWidth: 'sm',
      zIndex: 'popover',
      p: '4',
      _open: {
        animation: 'fadeIn 0.25s ease-out',
      },
      _closed: {
        animation: 'fadeOut 0.2s ease-out',
      },
      _hidden: {
        display: 'none',
      },
    },
    title: {
      fontWeight: 'medium',
      textStyle: 'sm',
    },
    description: {
      color: 'fg.muted',
      textStyle: 'sm',
    },
    closeTrigger: {
      color: 'fg.muted',
    },
    arrow: {
      '--arrow-size': 'var(--sizes-3)',
      '--arrow-background': 'var(--colors-bg-default)',
    },
    arrowTip: {
      borderTopWidth: '1px',
      borderLeftWidth: '1px',
    },
  },
})