I'm using PrimeVue v3 and I have multiple Panels generated in a for loop. I also have buttons for Expand/Collapse All, which work until I manually expand or collapse one of the panels.
const panelCollapsed = ref(true);
function expandAll() {
panelCollapsed.value = false;
}
function collapseAll() {
panelCollapsed.value = true;
}
<Button aria-label="Expand All" @click="expandAll">Expand All</Button>
<Button aria-label="Collapse All" @click="collapseAll">Collapse All</Button>
<div v-for="myPanel in myPanelList">
<Panel toggleable :collapsed="panelCollapsed"
:pt="{ content: { style: 'padding: 0' }, root: { style: 'margin-bottom: 1rem;' } }" >
</Panel>
</div>
How can I hook into the expanded/collapsed state of PrimeVue Panels?
I found something called PanelState in their documentation but there is no explanation on how to use it. To be honest I don't understand what PanelPassThroughMethodOptions are either, and I can't find anything related to it. I tried adding state
to :pt
like this: :pt="{ state: { d_collapsed: panelCollapsed }
but that doesn't work.
There should be per component instance collapse states, not a single state. Expand/Collapse All
won't work if they set panelCollapsed
to the same value it currently has.
Despite what the documentation states about collapsed
prop:
Defines the initial state of panel content
The prop is reactive and updates the component state at any time. That the component also has update:collapsed
means that it's intended to be used with v-model
.
const myPanelStates = ref([...]);
function expandAll() {
myPanelStates.value.fill(false);
}
function collapseAll() {
myPanelStates.value.fill(true);
}
function updatePanel(value, index) {
myPanelStates.value[index] = value
}
<Button @click="expandAll">Expand All</Button>
<Button @click="collapseAll">Collapse All</Button>
<div v-for="(myPanel, index) in myPanelList">
<Panel
:collapsed="myPanelStates[index]"
@update:collapsed="updatePanel($event, index)"
myPanelStates
should have the same length as myPanelList
and potentially be stored inside of it, this would allow to use v-model:collapsed="myPanel.state"
instead of a prop and event handler.
state
refers to this kind of use, as it follows from TypeScript types in the documentation:
<Panel
:pt="{
content: { style: 'padding: 0' },
root(options) {
options.state.d_collapsed = myPanelStates[index];
return { style: 'margin-bottom: 1rem;' }
}
}"
>
The documentation doesn't state that state
is intended for mutation, but at least it's possible because it's reactive. This would be helpful to extend the component if it didn't have collapsed
property. In the current implementation of Panel
the use of pt
to access state
serves the same purpose as accessing component instance directly like panelRef.value.d_collapsed
, but this may change in future.