11<script setup lang="ts">
2- import { ref , watchEffect } from " vue" ;
3-
4- defineOptions ({
5- inheritAttrs: false ,
6- });
2+ import { ref , useSlots , watchEffect } from " vue" ;
73
84const props = withDefaults (
95 defineProps <{
@@ -23,47 +19,65 @@ const props = withDefaults(
2319 },
2420);
2521
22+ // Notice we add the "click" event here.
2623const emit = defineEmits <{
2724 (e : " update:expanded" , value : boolean ): void ;
2825 (e : " update:active" , value : boolean ): void ;
26+ (e : " click" , event : Event ): void ;
2927}>();
3028
31- const active = ref (props .active );
32- const expanded = ref (props .expanded );
3329const content = ref <HTMLElement | null >(null );
30+ const expanded = ref (props .expanded );
31+ // Create a local state for active so that once activated it stays true.
32+ const activeLocal = ref (props .active );
33+ const slots = useSlots ();
3434
35- // Sync with props
35+ // Keep the local expanded state in sync with the prop.
3636watchEffect (() => {
37- active .value = props .active ;
3837 expanded .value = props .expanded ;
3938});
4039
40+ // Also update the local active state if the parent prop changes:
41+ watchEffect (() => {
42+ activeLocal .value = props .active ;
43+ });
44+
4145const onClick = (event : Event ) => {
4246 if (props .disabled ) {
4347 event .preventDefault ();
4448 return ;
4549 }
4650
47- // Toggle expansion state
51+ // Emit the native click event so that the test can detect it.
52+ emit (" click" , event );
53+
54+ // Always toggle the expanded state (regardless of whether a default slot exists).
4855 const newExpanded = ! expanded .value ;
49- const newActive = ! active .value ;
5056 expanded .value = newExpanded ;
51- active .value = newActive ;
52- // Emit changes to parent
5357 emit (" update:expanded" , newExpanded );
54- if (newActive ) {
55- emit (" update:active" , newActive );
58+
59+ // Emit update:active only if we aren’t already active.
60+ if (! activeLocal .value ) {
61+ activeLocal .value = true ;
62+ emit (" update:active" , true );
5663 }
5764};
5865 </script >
5966
6067<template >
6168 <li class =" li" :role =" ariaRole" ref =" content" :aria-expanded =" expanded" >
62- <component :is =" tag" v-bind =" $attrs" :class =" {
63- 'is-flex': icon,
64- 'is-active': active,
65- 'is-disabled': disabled
66- }" :aria-disabled =" disabled" @click =" onClick" @keydown.enter =" onClick" >
69+ <component
70+ :is =" tag"
71+ v-bind =" $attrs"
72+ :class =" {
73+ 'is-flex': icon,
74+ 'is-active': active,
75+ 'is-disabled': disabled
76+ }"
77+ :aria-disabled =" disabled"
78+ @click =" onClick"
79+ @keydown.enter =" onClick"
80+ >
6781 <span v-if =" icon" class =" pr-2" >{{ icon }}</span >
6882 <span v-if =" label" >{{ label }}</span >
6983 <slot v-else name =" label" :expanded =" expanded" :active =" active" />
0 commit comments