Skip to content

Commit ae5ff8f

Browse files
committed
新增 FaHoverCard 组件
1 parent 34c7e41 commit ae5ff8f

File tree

8 files changed

+150
-0
lines changed

8 files changed

+150
-0
lines changed

src/router/modules/component.example.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ const routes: RouteRecordRaw = {
102102
copyright: false,
103103
},
104104
},
105+
{
106+
path: 'hovercard',
107+
name: 'componentExampleBuiltInHoverCard',
108+
component: () => import('@/views/component_built_in_example/hovercard.vue'),
109+
meta: {
110+
title: '悬浮卡片',
111+
},
112+
},
105113
{
106114
path: 'input',
107115
name: 'componentExampleBuiltInInput',

src/types/components.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ declare module 'vue' {
2121
FaDrawer: typeof import('./../ui/components/FaDrawer/index.vue')['default']
2222
FaDropdown: typeof import('./../ui/components/FaDropdown/index.vue')['default']
2323
FaFixedActionBar: typeof import('./../ui/components/FaFixedActionBar/index.vue')['default']
24+
FaHoverCard: typeof import('./../ui/components/FaHoverCard/index.vue')['default']
2425
FaIcon: typeof import('./../ui/components/FaIcon/index.vue')['default']
2526
FaInput: typeof import('./../ui/components/FaInput/index.vue')['default']
2627
FaKbd: typeof import('./../ui/components/FaKbd/index.vue')['default']
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script setup lang="ts">
2+
import type { HoverCardRootEmits, HoverCardRootProps } from 'reka-ui'
3+
import { HoverCardRoot, useForwardPropsEmits } from 'reka-ui'
4+
5+
const props = defineProps<HoverCardRootProps>()
6+
const emits = defineEmits<HoverCardRootEmits>()
7+
8+
const forwarded = useForwardPropsEmits(props, emits)
9+
</script>
10+
11+
<template>
12+
<HoverCardRoot v-bind="forwarded">
13+
<slot />
14+
</HoverCardRoot>
15+
</template>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<script setup lang="ts">
2+
import type { HoverCardContentProps } from 'reka-ui'
3+
import type { HTMLAttributes } from 'vue'
4+
import { cn } from '@/utils'
5+
import {
6+
HoverCardContent,
7+
HoverCardPortal,
8+
useForwardProps,
9+
} from 'reka-ui'
10+
import { computed } from 'vue'
11+
12+
const props = withDefaults(
13+
defineProps<HoverCardContentProps & { class?: HTMLAttributes['class'] }>(),
14+
{
15+
sideOffset: 4,
16+
},
17+
)
18+
19+
const delegatedProps = computed(() => {
20+
const { class: _, ...delegated } = props
21+
22+
return delegated
23+
})
24+
25+
const forwardedProps = useForwardProps(delegatedProps)
26+
</script>
27+
28+
<template>
29+
<HoverCardPortal>
30+
<HoverCardContent
31+
v-bind="forwardedProps"
32+
:class="
33+
cn(
34+
'z-2000 min-w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
35+
props.class,
36+
)
37+
"
38+
>
39+
<slot />
40+
</HoverCardContent>
41+
</HoverCardPortal>
42+
</template>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script setup lang="ts">
2+
import type { HoverCardTriggerProps } from 'reka-ui'
3+
import { HoverCardTrigger } from 'reka-ui'
4+
5+
const props = defineProps<HoverCardTriggerProps>()
6+
</script>
7+
8+
<template>
9+
<HoverCardTrigger v-bind="props">
10+
<slot />
11+
</HoverCardTrigger>
12+
</template>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { default as HoverCard } from './HoverCard.vue'
2+
export { default as HoverCardContent } from './HoverCardContent.vue'
3+
export { default as HoverCardTrigger } from './HoverCardTrigger.vue'
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<script setup lang="ts">
2+
import type { HoverCardContentProps } from 'reka-ui'
3+
import type { HTMLAttributes } from 'vue'
4+
import {
5+
HoverCard,
6+
HoverCardContent,
7+
HoverCardTrigger,
8+
} from './hover-card'
9+
10+
defineOptions({
11+
name: 'FaHoverCard',
12+
})
13+
14+
const props = defineProps<{
15+
align?: HoverCardContentProps['align']
16+
alignOffset?: HoverCardContentProps['alignOffset']
17+
side?: HoverCardContentProps['side']
18+
sideOffset?: HoverCardContentProps['sideOffset']
19+
collisionPadding?: HoverCardContentProps['collisionPadding']
20+
class?: HTMLAttributes['class']
21+
}>()
22+
</script>
23+
24+
<template>
25+
<HoverCard>
26+
<HoverCardTrigger as-child>
27+
<slot />
28+
</HoverCardTrigger>
29+
<HoverCardContent :align :align-offset :side :side-offset :collision-padding :class="props.class">
30+
<slot name="card" />
31+
</HoverCardContent>
32+
</HoverCard>
33+
</template>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<route lang="yaml">
2+
meta:
3+
enabled: false
4+
</route>
5+
6+
<template>
7+
<div>
8+
<FaPageHeader title="悬浮卡片" description="FaHoverCard" />
9+
<FaPageMain>
10+
<FaHoverCard class="min-w-auto">
11+
<FaButton variant="link">
12+
@hooray
13+
</FaButton>
14+
<template #card>
15+
<div class="flex space-x-4">
16+
<FaAvatar shape="circle" src="https://github.com/vuejs.png" />
17+
<div class="space-y-1">
18+
<h4 class="text-sm font-semibold">
19+
@hooray
20+
</h4>
21+
<p class="text-sm">
22+
一个前端开发工程师
23+
</p>
24+
<div class="flex items-center pt-2">
25+
<FaIcon name="i-ci:calendar-days" class="mr-2 h-4 w-4 opacity-70" />
26+
<span class="text-xs text-muted-foreground">
27+
2020 年注册
28+
</span>
29+
</div>
30+
</div>
31+
</div>
32+
</template>
33+
</FaHoverCard>
34+
</FaPageMain>
35+
</div>
36+
</template>

0 commit comments

Comments
 (0)