summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components/popover.tsx
blob: 6db44f5f9b5b5b49438028b13bd99157fff3d872 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import { Popover as Kobalte } from "@kobalte/core/popover"
import { ComponentProps, JSXElement, ParentProps, Show, splitProps, ValidComponent } from "solid-js"
import { useI18n } from "../context/i18n"
import { IconButton } from "./icon-button"

export interface PopoverProps<T extends ValidComponent = "div">
  extends ParentProps,
    Omit<ComponentProps<typeof Kobalte>, "children"> {
  trigger?: JSXElement
  triggerAs?: T
  triggerProps?: ComponentProps<T>
  title?: JSXElement
  description?: JSXElement
  class?: ComponentProps<"div">["class"]
  classList?: ComponentProps<"div">["classList"]
}

export function Popover<T extends ValidComponent = "div">(props: PopoverProps<T>) {
  const i18n = useI18n()
  const [local, rest] = splitProps(props, [
    "trigger",
    "triggerAs",
    "triggerProps",
    "title",
    "description",
    "class",
    "classList",
    "children",
  ])

  return (
    <Kobalte gutter={4} {...rest}>
      <Kobalte.Trigger as={local.triggerAs ?? "div"} data-slot="popover-trigger" {...(local.triggerProps as any)}>
        {local.trigger}
      </Kobalte.Trigger>
      <Kobalte.Portal>
        <Kobalte.Content
          data-component="popover-content"
          classList={{
            ...(local.classList ?? {}),
            [local.class ?? ""]: !!local.class,
          }}
        >
          {/* <Kobalte.Arrow data-slot="popover-arrow" /> */}
          <Show when={local.title}>
            <div data-slot="popover-header">
              <Kobalte.Title data-slot="popover-title">{local.title}</Kobalte.Title>
              <Kobalte.CloseButton
                data-slot="popover-close-button"
                as={IconButton}
                icon="close"
                variant="ghost"
                aria-label={i18n.t("ui.common.close")}
              />
            </div>
          </Show>
          <Show when={local.description}>
            <Kobalte.Description data-slot="popover-description">{local.description}</Kobalte.Description>
          </Show>
          <div data-slot="popover-body">{local.children}</div>
        </Kobalte.Content>
      </Kobalte.Portal>
    </Kobalte>
  )
}