Skip to content

Commit ad27378

Browse files
fix: collapsible renders correctly on CSR
1 parent 05c1c9f commit ad27378

File tree

5 files changed

+84
-1
lines changed

5 files changed

+84
-1
lines changed

.changeset/lucky-carrots-pay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik-ui/headless': patch
3+
---
4+
5+
fix: collapsible renders correctly on CSR
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { component$, useStyles$, useSignal } from '@builder.io/qwik';
2+
import styles from '../snippets/collapsible.css?inline';
3+
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@qwik-ui/headless';
4+
import SVG from './svg';
5+
6+
export default component$(() => {
7+
useStyles$(styles);
8+
const isCollapsibleRendered = useSignal(false);
9+
10+
return (
11+
<>
12+
<button onClick$={() => (isCollapsibleRendered.value = true)}>
13+
Render Collapsible
14+
</button>
15+
{isCollapsibleRendered.value && (
16+
<Collapsible class="collapsible">
17+
<CollapsibleTrigger class="collapsible-trigger">
18+
<span>Trigger</span>
19+
<SVG />
20+
</CollapsibleTrigger>
21+
<CollapsibleContent class="collapsible-content collapsible-content-outline ">
22+
Content
23+
</CollapsibleContent>
24+
</Collapsible>
25+
)}
26+
</>
27+
);
28+
});

apps/website/src/routes/docs/headless/collapsible/index.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ To fix this, add a child element to the content, and set the padding or border o
136136

137137
> Rather than dealing with this under the hood, we thought it'd be appropriate to keep style management as simple as possible. Let us know if you have a better solution!
138138
139+
## CSR
140+
141+
The collapsible can be rendered both server-side or client-side, same with the rest of the components.
142+
143+
<Showcase name="csr" />
144+
145+
The main difference, is there is no server to client handoff. This can be useful if you're navigating via SPA.
146+
139147
## Example CSS
140148

141149
<CodeSnippet name="collapsible.css" />

packages/kit-headless/src/components/collapsible/collapsible-content.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ export const CollapsibleContent = component$((props: CollapsibleContentProps) =>
3535
return;
3636
}
3737

38-
await context.getContentDimensions$();
38+
if (context.isOpenSig.value) {
39+
await context.getContentDimensions$();
40+
}
3941

4042
/* check if there's a transition or animation, we set a timeout for the initial render */
4143
setTimeout(() => {

packages/kit-headless/src/components/collapsible/collapsible.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,43 @@ test.describe('Disabled', () => {
189189
await expect(d.getContent()).toBeHidden();
190190
});
191191
});
192+
193+
test.describe('CSR', () => {
194+
test(`GIVEN a collapsible
195+
WHEN it is client-side rendered
196+
THEN the collapsible trigger should be visible
197+
`, async ({ page }) => {
198+
const { driver: d } = await setup(page, 'csr');
199+
200+
await d.locator.getByRole('button', { name: 'Render Collapsible' }).click();
201+
await expect(d.getTrigger()).toBeVisible();
202+
});
203+
204+
test(`GIVEN a CSR collapsible
205+
WHEN the trigger is clicked
206+
THEN the collapsible should be opened
207+
`, async ({ page }) => {
208+
const { driver: d } = await setup(page, 'csr');
209+
210+
await d.locator.getByRole('button', { name: 'Render Collapsible' }).click();
211+
await expect(d.getTrigger()).toBeVisible();
212+
213+
await d.getTrigger().click();
214+
await expect(d.getContent()).toBeVisible();
215+
});
216+
217+
test(`GIVEN an open CSR collapsible
218+
WHEN the trigger is clicked
219+
THEN the collapsible should be closed
220+
`, async ({ page }) => {
221+
const { driver: d } = await setup(page, 'csr');
222+
223+
await d.locator.getByRole('button', { name: 'Render Collapsible' }).click();
224+
await expect(d.getTrigger()).toBeVisible();
225+
226+
await d.openCollapsible('click');
227+
await d.getTrigger().click();
228+
229+
await expect(d.getContent()).toBeHidden();
230+
});
231+
});

0 commit comments

Comments
 (0)