Skip to content
This repository was archived by the owner on Sep 20, 2024. It is now read-only.

Commit 3de8c75

Browse files
committed
fix: popover initial transition state
1 parent 280455c commit 3de8c75

12 files changed

+131
-82
lines changed

packages/c-popover/examples/simple-popover.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ import { CButton } from "../../c-button/src"
1313
</script>
1414

1515
<template>
16-
<c-popover>
16+
<c-popover
17+
:positioning="{
18+
placement: 'bottom-start',
19+
}"
20+
>
1721
<c-popover-trigger>
18-
<c-button> Click me </c-button>
22+
<c-button> Trigger </c-button>
1923
</c-popover-trigger>
2024
<c-popover-content>
2125
<c-popover-arrow />
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<script setup lang="ts">
2+
import { Teleport } from "vue"
3+
import {
4+
CPopover,
5+
CPopoverTrigger,
6+
CPopoverContent,
7+
CPopoverArrow,
8+
CPopoverHeader,
9+
CPopoverBody,
10+
CPopoverFooter,
11+
CPopoverCloseButton,
12+
} from "../src"
13+
import { CButton } from "../../c-button/src"
14+
</script>
15+
16+
<template>
17+
<c-popover
18+
:positioning="{
19+
placement: 'bottom-start',
20+
}"
21+
>
22+
<c-popover-trigger>
23+
<c-button> Portal Popover </c-button>
24+
</c-popover-trigger>
25+
<Teleport to="body">
26+
<c-popover-content>
27+
<c-popover-arrow />
28+
<c-popover-header>Look! I'm portalled</c-popover-header>
29+
<c-popover-body>
30+
Inspect me in the DOM and you'll see that I'm portalled to the end of
31+
the body
32+
</c-popover-body>
33+
<c-popover-footer>
34+
<c-button size="sm">Okay</c-button>
35+
</c-popover-footer>
36+
<c-popover-close-button />
37+
</c-popover-content>
38+
</Teleport>
39+
</c-popover>
40+
</template>

packages/c-popover/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
"dev": "tsup --watch"
3535
},
3636
"dependencies": {
37+
"@chakra-ui/c-close-button": "workspace:*",
3738
"@chakra-ui/c-motion": "workspace:*",
39+
"@chakra-ui/styled-system": "2.6.1",
3840
"@chakra-ui/vue-composables": "workspace:*",
3941
"@chakra-ui/vue-system": "workspace:*",
4042
"@chakra-ui/vue-utils": "workspace:*",
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { computed, defineComponent } from "vue"
2+
import { usePopoverContext, useStyles } from "./popover.context"
3+
import { CCloseButton, type CloseButtonProps } from "@chakra-ui/c-close-button"
4+
import { match } from "@chakra-ui/vue-utils"
5+
6+
export interface CPopoverCloseButtonProps extends CloseButtonProps {}
7+
export const CPopoverCloseButton = defineComponent({
8+
name: "CPopoverCloseButton",
9+
setup(_, { attrs }) {
10+
const api = usePopoverContext()
11+
const styles = useStyles()
12+
13+
const popoverTriggerProps = computed(() => {
14+
const { onClick, ...rest } = api.value.triggerProps
15+
return {
16+
...rest,
17+
async onClick(e: MouseEvent) {
18+
requestAnimationFrame(() => {
19+
api.value.leaveTransition(() => onClick(e))
20+
})
21+
},
22+
}
23+
})
24+
25+
return () => (
26+
<CCloseButton
27+
size="sm"
28+
__label="popover__close-button"
29+
__css={styles.value.closeButton}
30+
{...popoverTriggerProps.value}
31+
{...attrs}
32+
/>
33+
)
34+
},
35+
})

packages/c-popover/src/c-popover-content.tsx

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,15 @@ import {
66
chakra,
77
} from "@chakra-ui/vue-system"
88
import { CPopoverPositioner } from "./c-popover-positioner"
9-
import { TransitionDefaults } from "@chakra-ui/c-motion"
109
import { MotionDirective, useMotions } from "@vueuse/motion"
1110
import { withDirectives } from "vue"
1211
import { match } from "@chakra-ui/vue-utils"
12+
import { PopoverVariants } from "./popover.transitions"
1313

14-
const variants = {
15-
backdrop: {
16-
initial: {
17-
opacity: 0,
18-
scale: 1.1,
19-
},
20-
animate: { opacity: 0.5, scale: 1 },
21-
exit: { opacity: 0, scale: 1.1 },
22-
},
23-
content: {
24-
initial: {
25-
opacity: 0,
26-
scale: 1.005,
27-
y: 10,
28-
},
29-
animate: { opacity: 1, scale: 1, y: 0 },
30-
exit: { opacity: 0, scale: 1.005, y: 10 },
31-
},
32-
}
14+
const toVar = (value: string, fallback?: string) => ({
15+
var: value,
16+
varRef: fallback ? `var(${value}, ${fallback})` : `var(${value})`,
17+
})
3318

3419
export interface CPopoverContentProps extends HTMLChakraProps<"div"> {}
3520
export const CPopoverContent = defineComponent({
@@ -44,6 +29,10 @@ export const CPopoverContent = defineComponent({
4429
display: "flex",
4530
flexDirection: "column",
4631
...styles.value.content,
32+
transformOrigin: toVar(
33+
"--transform-origin",
34+
api.value.positionerProps.style.transformOrigin
35+
).varRef,
4736
}))
4837

4938
const popoverContentProps = computed(() => {
@@ -82,24 +71,7 @@ export const CPopoverContent = defineComponent({
8271
>
8372
{slots.default?.()}
8473
</chakra.div>,
85-
[
86-
[
87-
MotionDirective({
88-
initial: { scale: 0.95, opacity: 0 },
89-
enter: {
90-
scale: 1,
91-
transition: TransitionDefaults.enter,
92-
opacity: 1,
93-
},
94-
leave: {
95-
scale: 0.95,
96-
transition: TransitionDefaults.leave,
97-
opacity: 0,
98-
},
99-
}),
100-
api.value.transitionId,
101-
],
102-
]
74+
[[MotionDirective(PopoverVariants), api.value.transitionId]]
10375
)}
10476
</CPopoverPositioner>
10577
)

packages/c-popover/src/c-popover-trigger.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export const CPopoverTrigger = defineComponent({
3535
})
3636
},
3737
async onPointerleave(e: MouseEvent) {
38-
requestAnimationFrame(() => {
38+
requestAnimationFrame(async () => {
3939
api.value.leaveTransition(() => api.value.close())
4040
})
4141
},

packages/c-popover/src/c-popover.tsx

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@
1010

1111
import { computed, defineComponent, mergeProps, PropType } from "vue"
1212
import { PopoverProvider, PopoverStylesProvider } from "./popover.context"
13-
import {
14-
useDeferredDisclosure,
15-
usePopover,
16-
UsePopoverProps,
17-
} from "./use-popover"
13+
import { usePopover, UsePopoverProps } from "./use-popover"
14+
import { wait } from "./popover.utils"
1815
import type * as ZP from "@zag-js/popper"
1916
import type * as ZT from "@zag-js/types"
2017
import { useId } from "@chakra-ui/vue-composables"
@@ -70,10 +67,6 @@ const VuePopoverProps = {
7067
},
7168
}
7269

73-
function wait(delay: number) {
74-
return new Promise((resolve) => setTimeout(resolve, delay))
75-
}
76-
7770
export const CPopover = defineComponent({
7871
name: "CPopover",
7972
props: VuePopoverProps,
@@ -110,26 +103,24 @@ export const CPopover = defineComponent({
110103

111104
const enterTransition = (done: VoidFunction) => {
112105
const motions = useMotions()
113-
console.log("motions", motions)
114106
const instance = motions[transitionId.value]
115107
requestAnimationFrame(async () => {
108+
instance.set("initial")
116109
await instance.apply("enter")
117110
done()
118111
})
119112
}
120113

121114
const api = usePopover(popoverProps.value)
122-
const nativeIsOpen = computed(() => api.value.isOpen)
123115

124-
const { isOpenDeferred } = useDeferredDisclosure(nativeIsOpen)
125116
const popoverApi = computed(() => ({
126117
...api.value,
127-
deferredIsOpen: isOpenDeferred.value,
128118
leaveTransition,
129119
enterTransition,
130120
wait,
131121
transitionId: transitionId.value,
132122
trigger: props.trigger,
123+
close: () => leaveTransition(() => api.value.close()),
133124
}))
134125

135126
PopoverProvider(popoverApi)

packages/c-popover/src/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ export { CPopoverHeader, type CPopoverHeaderProps } from "./c-popover-header"
1616
export { CPopoverFooter, type CPopoverFooterProps } from "./c-popover-footer"
1717
export { CPopoverBody, type CPopoverBodyProps } from "./c-popover-body"
1818
export { CPopoverAnchor, type CPopoverAnchorProps } from "./c-popover-anchor"
19+
export {
20+
CPopoverCloseButton,
21+
type CPopoverCloseButtonProps,
22+
} from "./c-popover-close-button"
1923
export { usePopover } from "./use-popover"
2024

2125
export type { CPopoverProps } from "./c-popover"

packages/c-popover/src/popover.context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import type { connect } from "@zag-js/popover"
22
import type { ComputedRef } from "vue"
33
import { AnyFn, createContext } from "@chakra-ui/vue-utils"
44
import { createStylesContext } from "@chakra-ui/vue-system"
5+
import type * as S from "@chakra-ui/styled-system"
56
import type { UsePopoverReturn } from "./use-popover"
67

78
export const [PopoverProvider, usePopoverContext] = createContext<
89
ComputedRef<
910
ReturnType<typeof connect> & {
10-
deferredIsOpen: boolean
1111
leaveTransition: AnyFn
1212
enterTransition: AnyFn
1313
wait: AnyFn
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { TransitionDefaults } from "@chakra-ui/c-motion"
2+
import { MotionVariants } from "@vueuse/motion"
3+
4+
export const PopoverVariants: MotionVariants = {
5+
initial: { scale: 0.95, opacity: 0 },
6+
enter: {
7+
scale: 1,
8+
transition: TransitionDefaults.enter,
9+
opacity: 1,
10+
},
11+
leave: {
12+
scale: 0.95,
13+
transition: TransitionDefaults.leave,
14+
opacity: 0,
15+
},
16+
}

0 commit comments

Comments
 (0)