gaoluyang
2026-06-24 c0cb161bb52ce0fbdce5c66ec391d107c75e2452
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<script setup lang="ts">
import type { CollapsibleRootEmits, CollapsibleRootProps } from 'reka-ui';
 
import type { ClassType } from '..\..\..\..\..\base\typings\src';
 
import { computed } from 'vue';
 
import { ChevronsDown } from '@lucide/vue';
import {
  CollapsibleContent,
  CollapsibleRoot,
  CollapsibleTrigger,
  useForwardPropsEmits,
} from 'reka-ui';
 
const props = defineProps<
  CollapsibleRootProps & {
    class?: ClassType;
    showTrigger?: boolean;
  }
>();
 
const emits = defineEmits<CollapsibleRootEmits>();
 
const delegatedProps = computed(() => {
  const { class: _cls, ...delegated } = props;
 
  return delegated;
});
 
const forwarded = useForwardPropsEmits(delegatedProps, emits);
 
const open = defineModel('open', { default: true });
 
function toggle() {
  open.value = !open.value;
}
 
defineExpose({
  toggle,
});
</script>
 
<template>
  <CollapsibleRoot
    v-bind="forwarded"
    v-model:open="open"
    class="flex flex-col"
    :unmount-on-hide="false"
  >
    <div
      class="flex items-center justify-between"
      v-if="$slots.label || showTrigger"
    >
      <slot name="label" v-if="$slots.label"> </slot>
      <CollapsibleTrigger
        v-if="showTrigger"
        class="cursor-pointer rounded-full h-[25px] w-[25px] inline-flex items-center justify-center outline-none data-[state=closed]:bg-white data-[state=open]:bg-primary/20 hover:bg-primary/20 text-primary"
      >
        <slot name="trigger" :open>
          <ChevronsDown
            class="h-3.5 w-3.5 transition-transform"
            :class="{
              'rotate-180': open,
            }"
          />
        </slot>
      </CollapsibleTrigger>
    </div>
 
    <slot name="visibleContent" :open></slot>
 
    <CollapsibleContent
      class="data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up overflow-hidden justify-start"
    >
      <slot name="collapsibleContent" :open></slot>
    </CollapsibleContent>
  </CollapsibleRoot>
</template>