11import { scopedElementKey } from "../../hooks/gsapKeyframeCacheHelpers" ;
2- import { useEffect , useRef , useState } from "react" ;
2+ import { useEffect , useMemo , useRef , useState } from "react" ;
33import { useShallow } from "zustand/react/shallow" ;
44import { DesignPanelInputProvider } from "../../contexts/DesignPanelInputContext" ;
55import { slugifyDesignInput } from "../../utils/designInputTracking" ;
66import { isTextEditableSelection } from "./domEditing" ;
77import type { PropertyPanelFlatProps } from "./propertyPanelFlatProps" ;
88import { formatPxMetricValue } from "./propertyPanelHelpers" ;
99import { audioFxSummary } from "./audioFxSummary" ;
10- import { HF_AUDIO_GROUP_TAG , resolveAudioGroups } from "@hyperframes/core/audio-groups" ;
10+ import { resolveAudioGroups } from "@hyperframes/core/audio-groups" ;
1111import { PropertyPanelFlatHeader } from "./PropertyPanelFlatHeader" ;
1212import { PropertyPanelFlatFooter } from "./PropertyPanelFlatFooter" ;
1313import { closedGroupHeader , isSelectionHidden } from "./propertyPanelFlatClosedGroup" ;
@@ -43,6 +43,7 @@ import {
4343 EMPTY_GSAP_EFFECT_HANDLERS ,
4444 type FlatGroupDescriptor ,
4545} from "./propertyPanelFlatDescriptors" ;
46+ import { isAudioDomElement } from "../../utils/timelineInspector" ;
4647
4748/** The flat inspector shell with one shared open-group state. */
4849// fallow-ignore-next-line complexity
@@ -170,6 +171,7 @@ export function PropertyPanelFlat({
170171 timelineSessionEpoch : state . timelineSessionEpoch ,
171172 } ) ) ,
172173 ) ;
174+ const storeElements = usePlayerStore ( ( state ) => state . elements ) ;
173175 // Identity of the element THIS panel actually renders (not the store's
174176 // selectedElementId, which flips synchronously on selection while the panel
175177 // still renders the previous element during async DOM-selection resolution):
@@ -282,8 +284,7 @@ export function PropertyPanelFlat({
282284 onSetAllKeyframeEases,
283285 }
284286 : null ;
285- const selectedTag = element . tagName ?. toLowerCase ( ) ;
286- const audioSelection = selectedTag === "audio" || selectedTag === HF_AUDIO_GROUP_TAG ;
287+ const audioSelection = isAudioDomElement ( element . element ) ;
287288 // Handlers being wired is necessary but not sufficient: App.tsx always passes
288289 // them, so this alone showed the tween editor for every selection — including
289290 // an `<audio>` clip and an `<hf-audio-group>` bus, neither of which has a
@@ -300,12 +301,13 @@ export function PropertyPanelFlat({
300301 // "in Voiceover" for a member (see `audioFxSummary`). Resolved from the live
301302 // document because membership lives on the members, so the owning group's
302303 // LABEL is not on the selected element.
303- const audioGroupLabel = ( ( ) : string | undefined => {
304+ const audioGroupLabel = useMemo ( ( ) : string | undefined => {
304305 const doc = element . element ?. ownerDocument ;
305306 const id = element . id ;
306307 if ( ! doc || ! id ) return undefined ;
307- return resolveAudioGroups ( doc ) . find ( ( g ) => g . memberIds . includes ( id ) ) ?. label ;
308- } ) ( ) ;
308+ return resolveAudioGroups ( doc ) . find ( ( group ) => group . memberIds . includes ( id ) ) ?. label ;
309+ // eslint-disable-next-line react-hooks/exhaustive-deps -- store replacement signals live group membership changed
310+ } , [ element , storeElements ] ) ;
309311
310312 const groups : FlatGroupDescriptor [ ] = [ ] ;
311313 if ( isTextEditable ) {
0 commit comments