feat: 新增 FaCollapsible 组件

This commit is contained in:
Hooray
2025-09-05 16:25:44 +08:00
parent 632a2d389f
commit aa5de0ebf0
6 changed files with 101 additions and 0 deletions
+1
View File
@@ -16,6 +16,7 @@ declare module 'vue' {
FaButtonGroup: typeof import('./../ui/components/FaButtonGroup/index.vue')['default']
FaCard: typeof import('./../ui/components/FaCard/index.vue')['default']
FaCheckbox: typeof import('./../ui/components/FaCheckbox/index.vue')['default']
FaCollapsible: typeof import('./../ui/components/FaCollapsible/index.vue')['default']
FaContextMenu: typeof import('./../ui/components/FaContextMenu/index.vue')['default']
FaCopyright: typeof import('./../ui/components/FaCopyright/index.vue')['default']
FaDivider: typeof import('./../ui/components/FaDivider/index.vue')['default']
@@ -0,0 +1,15 @@
<script setup lang="ts">
import type { CollapsibleRootEmits, CollapsibleRootProps } from 'reka-ui'
import { CollapsibleRoot, useForwardPropsEmits } from 'reka-ui'
const props = defineProps<CollapsibleRootProps>()
const emits = defineEmits<CollapsibleRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script>
<template>
<CollapsibleRoot v-slot="{ open }" v-bind="forwarded">
<slot :open="open" />
</CollapsibleRoot>
</template>
@@ -0,0 +1,46 @@
<script setup lang="ts">
import type { CollapsibleContentProps } from 'reka-ui'
import { CollapsibleContent } from 'reka-ui'
const props = defineProps<CollapsibleContentProps>()
</script>
<template>
<CollapsibleContent v-bind="props" class="CollapsibleContent">
<slot />
</CollapsibleContent>
</template>
<style scoped>
.CollapsibleContent {
overflow: hidden;
}
.CollapsibleContent[data-state="open"] {
animation: collapsible-down 300ms ease-out;
}
.CollapsibleContent[data-state="closed"] {
animation: collapsible-up 300ms ease-out;
}
@keyframes collapsible-down {
from {
height: 0;
}
to {
height: var(--reka-collapsible-content-height);
}
}
@keyframes collapsible-up {
from {
height: var(--reka-collapsible-content-height);
}
to {
height: 0;
}
}
</style>
@@ -0,0 +1,12 @@
<script setup lang="ts">
import type { CollapsibleTriggerProps } from 'reka-ui'
import { CollapsibleTrigger } from 'reka-ui'
const props = defineProps<CollapsibleTriggerProps>()
</script>
<template>
<CollapsibleTrigger v-bind="props">
<slot />
</CollapsibleTrigger>
</template>
@@ -0,0 +1,3 @@
export { default as Collapsible } from './Collapsible.vue'
export { default as CollapsibleContent } from './CollapsibleContent.vue'
export { default as CollapsibleTrigger } from './CollapsibleTrigger.vue'
+24
View File
@@ -0,0 +1,24 @@
<script setup lang="ts">
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './collapsible'
defineOptions({
name: 'FaCollapsible',
})
const open = defineModel<boolean>('modelValue', {
default: false,
})
const slots = useSlots()
</script>
<template>
<Collapsible v-model:open="open">
<CollapsibleTrigger v-if="!!slots.trigger">
<slot name="trigger" :open />
</CollapsibleTrigger>
<CollapsibleContent>
<slot />
</CollapsibleContent>
</Collapsible>
</template>