Skip to content

Commit 8d99647

Browse files
feat(popover): add icon only popover variant, rounded style, disallowing children
1 parent c46b673 commit 8d99647

File tree

4 files changed

+102
-15
lines changed

4 files changed

+102
-15
lines changed

lib/interactive/popover/CorvuPopover.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { buttonCva2 } from "~ui/interactive/button/buttonCva"
55
import type { ButtonIcon1Props } from "~ui/interactive/button/ButtonIcon1"
66
import { buttonIconCva } from "~ui/interactive/button/buttonIconCva"
77
import { classesButtonClickAnimation } from "~ui/interactive/button/classesButtonClickAnimation"
8+
import { classesPopoverContentMerge } from "~ui/interactive/popover/classesPopoverContent"
89
import { Icon1 } from "~ui/static/icon/Icon1"
9-
import { classArr } from "~ui/utils/classArr"
1010
import type { MayHaveChildren } from "~ui/utils/MayHaveChildren"
1111
import type { MayHaveClass } from "~ui/utils/MayHaveClass"
1212
import type { MayHaveInnerClass } from "~ui/utils/MayHaveInnerClass"
@@ -42,20 +42,7 @@ export function CorvuPopover(p: CorvuPopoverProps) {
4242
)}
4343
</Popover.Trigger>
4444
<Popover.Portal>
45-
<Popover.Content
46-
class={classArr(
47-
"z-50", // positioning
48-
"px-3 py-3", // spacing
49-
"rounded-lg", // border
50-
"dark:border", // border
51-
"bg-white dark:bg-black", // background
52-
"shadow-md", // shadow
53-
"data-open:animate-in data-open:fade-in-50% data-open:slide-in-from-top-1 data-closed:animate-out data-closed:fade-out-50% data-closed:slide-out-to-top-1", // animations
54-
p.innerClass,
55-
)}
56-
>
57-
{p.children}
58-
</Popover.Content>
45+
<Popover.Content class={classesPopoverContentMerge(p.innerClass)}>{p.children}</Popover.Content>
5946
</Popover.Portal>
6047
</Popover>
6148
)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import Popover from "@corvu/popover"
2+
import { type Component, type ComponentProps, splitProps } from "solid-js"
3+
import { classesDisabledDirectly } from "~ui/classes/classesDisabledDirectly"
4+
import { buttonCvaIconOnly, type ButtonCvaProps } from "~ui/interactive/button/buttonCva"
5+
import { buttonIconCva } from "~ui/interactive/button/buttonIconCva"
6+
import { classesButtonClickAnimation } from "~ui/interactive/button/classesButtonClickAnimation"
7+
import { classesPopoverContentMerge } from "~ui/interactive/popover/classesPopoverContent"
8+
import { Icon0 } from "~ui/static/icon/Icon0"
9+
import type { MayHaveChildren } from "~ui/utils/MayHaveChildren"
10+
import type { MayHaveClass } from "~ui/utils/MayHaveClass"
11+
import type { MayHaveInnerClass } from "~ui/utils/MayHaveInnerClass"
12+
import { isLoading, type MayHaveIsLoading } from "~ui/utils/MayHaveIsLoading"
13+
14+
export interface CorvuPopoverIconProps
15+
extends ComponentProps<"button">,
16+
ButtonCvaProps,
17+
MayHaveClass,
18+
MayHaveInnerClass,
19+
MayHaveChildren,
20+
MayHaveIsLoading {
21+
title: string
22+
icon: string
23+
iconClass?: string
24+
}
25+
26+
export const CorvuPopoverIcon: Component<CorvuPopoverIconProps> = (p) => {
27+
const [s, rest] = splitProps(p, [
28+
// button
29+
"variant",
30+
"size",
31+
"class",
32+
// state
33+
"isLoading",
34+
"disabled",
35+
// icons
36+
"title",
37+
"icon",
38+
"iconClass",
39+
// popover
40+
"innerClass",
41+
"children",
42+
])
43+
44+
return (
45+
<Popover
46+
floatingOptions={{
47+
offset: 8,
48+
flip: true,
49+
shift: true,
50+
}}
51+
>
52+
<Popover.Trigger
53+
class={buttonCvaIconOnly(s.variant, isLoading(p), s.disabled, classesButtonClickAnimation, s.class)}
54+
title={s.title}
55+
{...rest}
56+
>
57+
<Icon0
58+
path={s.icon}
59+
class={buttonIconCva(
60+
s.variant,
61+
isLoading(p) && "animate-spin-faster",
62+
s.disabled && classesDisabledDirectly,
63+
s.iconClass,
64+
)}
65+
/>
66+
</Popover.Trigger>
67+
<Popover.Portal>
68+
<Popover.Content class={classesPopoverContentMerge(s.innerClass)}>{s.children}</Popover.Content>
69+
</Popover.Portal>
70+
</Popover>
71+
)
72+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { classMerge } from "~ui/utils/classMerge"
2+
3+
export const classesPopoverContent = [
4+
"z-50", // positioning
5+
"px-3 py-3", // spacing
6+
"rounded-lg", // border
7+
"dark:border", // border
8+
"bg-white dark:bg-black", // background
9+
"shadow-md", // shadow
10+
"data-open:animate-in data-open:fade-in-50% data-open:slide-in-from-top-1 data-closed:animate-out data-closed:fade-out-50% data-closed:slide-out-to-top-1", // animations
11+
]
12+
13+
export function classesPopoverContentMerge(innerClass?: string) {
14+
return classMerge(classesPopoverContent, innerClass)
15+
}

src/demos/interactive/DemoPopover.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { mdiDotsVertical } from "@mdi/js"
22
import { buttonVariant } from "~ui/interactive/button/buttonCva"
33
import { CorvuPopover } from "~ui/interactive/popover/CorvuPopover"
4+
import { CorvuPopoverIcon } from "~ui/interactive/popover/CorvuPopoverIcon"
45
import { classesGridCols3xl } from "~ui/static/container/classesGridCols"
56
import { classArr } from "~ui/utils/classArr"
67
import type { MayHaveClass } from "~ui/utils/MayHaveClass"
@@ -13,6 +14,7 @@ export function DemoPopover() {
1314
<BasicPopoverDemo title="Start" class="justify-start items-start" />
1415
<BasicPopoverDemo title="Center" class="justify-center items-center" />
1516
<BasicPopoverDemo title="End" class="justify-end items-end" />
17+
<IconPopoverDemo title="Icon" class="justify-center items-center" />
1618
</div>
1719
</div>
1820
)
@@ -33,6 +35,17 @@ function BasicPopoverDemo(p: BasicPopoverDemo) {
3335
)
3436
}
3537

38+
function IconPopoverDemo(p: BasicPopoverDemo) {
39+
return (
40+
<div class={classArr("flex flex-col", p.class)}>
41+
<h2 class="text-2xl font-bold mb-4">{p.title + " Popover"}</h2>
42+
<CorvuPopoverIcon icon={mdiDotsVertical} variant={buttonVariant.outline} title="Open popover">
43+
<Content />
44+
</CorvuPopoverIcon>
45+
</div>
46+
)
47+
}
48+
3649
function Content() {
3750
return (
3851
<div class="p-4 min-w-48">

0 commit comments

Comments
 (0)