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

Commit 2cc9dad

Browse files
committed
feat: navbar icons to add popper later
1 parent 1e15631 commit 2cc9dad

File tree

2 files changed

+172
-6
lines changed

2 files changed

+172
-6
lines changed

website/src/components/Navbar.vue

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
border-top="6px solid"
1313
border-color="vue.500"
1414
>
15-
<CFlex align-items="center" flex="1" />
15+
<CFlex align-items="center" :flex="{ base: 0, sm: 1 }" />
1616
<CFlex flex="1" justify-content="center">
1717
<CIcon name="search" mt="8px" />
1818
</CFlex>
@@ -25,7 +25,19 @@
2525
pt="8px"
2626
justify-content="flex-end"
2727
>
28-
<CBox as="li" mr="2">
28+
<CBox as="li" mr="2" :d="{ base: 'none', sm: 'block' }">
29+
<CIconButton
30+
as="a"
31+
variant="ghost"
32+
variant-color="gray"
33+
aria-label="View GitHub"
34+
target="_blank"
35+
rel="noopener noreferrer"
36+
href="https://github.com/chakra-ui/chakra-ui-vue"
37+
icon="github"
38+
/>
39+
</CBox>
40+
<CBox as="li" mr="2" :d="{ base: 'none', sm: 'block' }">
2941
<CIconButton
3042
as="a"
3143
variant="ghost"
@@ -37,19 +49,19 @@
3749
icon="book"
3850
/>
3951
</CBox>
40-
<CBox as="li" mr="2">
52+
<CBox as="li" mr="2" :d="{ base: 'none', sm: 'block' }">
4153
<CIconButton
4254
as="a"
4355
variant="ghost"
4456
variant-color="gray"
4557
aria-label="Join Discord channel"
46-
rel="noopener noreferrer"
4758
target="_blank"
48-
href="https://discord.gg/sq2Kp6x"
59+
rel="noopener noreferrer"
60+
href="https://github.com/chakra-ui/chakra-ui-vue"
4961
icon="message-circle"
5062
/>
5163
</CBox>
52-
<CBox as="li" mr="2">
64+
<CBox as="li">
5365
<CIconButton
5466
as="a"
5567
variant="ghost"
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<template>
2+
<chakra.div h="100%" d="flex" mr="2">
3+
<c-portal>
4+
<transition
5+
:css="false"
6+
@leave="
7+
(el, done) => {
8+
motionInstance.leave(done)
9+
innerMotionInstance.leave?.(() => null)
10+
}
11+
"
12+
>
13+
<chakra.span :ref="popper" v-if="isOpen">
14+
<chakra.div
15+
ref="innerPopperElement"
16+
d="inline-flex"
17+
flex-direction="column"
18+
align-items="center"
19+
min-w="100px"
20+
shadow="lg"
21+
rounded="lg"
22+
transform-origin="top left"
23+
bg="gray.50"
24+
border-width="1px"
25+
border-color="gray.300"
26+
color="gray.600"
27+
cursor="pointer"
28+
overflow="hidden"
29+
p="2"
30+
>
31+
<slot></slot>
32+
</chakra.div>
33+
</chakra.span>
34+
</transition>
35+
</c-portal>
36+
37+
<CIconButton
38+
:ref="reference"
39+
id="referenceElement"
40+
@mouseover="toggleIsOpen"
41+
@mouseleave="toggleIsOpen"
42+
variant="ghost"
43+
variant-color="gray"
44+
:aria-label="ariaLabel"
45+
target="_blank"
46+
rel="noopener noreferrer"
47+
:href="link"
48+
:icon="icon"
49+
/>
50+
</chakra.div>
51+
</template>
52+
53+
<script lang="ts">
54+
import { computed, defineComponent, nextTick, ref, watch } from 'vue'
55+
import { usePopper } from '@chakra-ui/c-popper'
56+
import { CIconButton, CPortal } from '@chakra-ui/vue-next'
57+
import { useToggle } from '@vueuse/core'
58+
import { useMotion } from '@vueuse/motion'
59+
60+
export default defineComponent({
61+
name: 'NavbarPopper',
62+
components: { CIconButton, CPortal },
63+
props: {
64+
icon: {
65+
type: String,
66+
default: '',
67+
},
68+
link: {
69+
type: String,
70+
default: '',
71+
},
72+
ariaLabel: {
73+
type: String,
74+
default: '',
75+
},
76+
},
77+
setup(props) {
78+
const [isOpen, toggleIsOpen] = useToggle(false)
79+
const motionInstance = ref()
80+
const innerMotionInstance = ref()
81+
const innerPopperElement = ref()
82+
const { reference, popper, popperEl } = usePopper({
83+
gutter: 16,
84+
placement: 'bottom-end',
85+
})
86+
87+
const _innerPopperElement = computed(
88+
() => innerPopperElement.value?.$el || innerPopperElement.value
89+
)
90+
91+
const variants = {
92+
initial: {
93+
opacity: 0,
94+
},
95+
enter: {
96+
opacity: 1,
97+
},
98+
leave: {
99+
opacity: 0,
100+
},
101+
}
102+
103+
const innerVariants = {
104+
initial: {
105+
scale: 0.9,
106+
opacity: 0,
107+
},
108+
enter: {
109+
scale: 1,
110+
opacity: 1,
111+
transition: {
112+
scale: {
113+
type: 'spring',
114+
damping: 5,
115+
stiffness: 550,
116+
},
117+
},
118+
},
119+
leave: {
120+
scale: 0.9,
121+
opacity: 0,
122+
},
123+
}
124+
125+
watch(
126+
isOpen,
127+
async (newVal) => {
128+
await nextTick()
129+
if (newVal) {
130+
motionInstance.value = useMotion(popperEl, variants)
131+
innerMotionInstance.value = useMotion(
132+
_innerPopperElement.value,
133+
innerVariants
134+
)
135+
}
136+
},
137+
{
138+
immediate: true,
139+
}
140+
)
141+
142+
return {
143+
isOpen,
144+
toggleIsOpen,
145+
reference,
146+
popper,
147+
innerPopperElement,
148+
motionInstance,
149+
innerMotionInstance,
150+
...props,
151+
}
152+
},
153+
})
154+
</script>

0 commit comments

Comments
 (0)