Skip to content

Commit 460361d

Browse files
fix: toggle item correctly updates based on each individual toggle
1 parent c25e2d4 commit 460361d

File tree

5 files changed

+20
-32
lines changed

5 files changed

+20
-32
lines changed

apps/website/src/routes/docs/headless/toggle-group/examples/hero.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { component$, useStyles$ } from '@builder.io/qwik';
2-
import styles from '../snippets/toggle.css?inline';
32

43
import { ToggleGroup } from '@qwik-ui/headless';
54

@@ -21,3 +20,6 @@ export default component$(() => {
2120
</div>
2221
);
2322
});
23+
24+
// internal
25+
import styles from '../snippets/toggle.css?inline';

packages/kit-headless/src/components/toggle-group/toggle-group-item.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,25 @@ export const HToggleGroupItem = component$<ToggleGroupItemProps>((props) => {
6969
const valueContext = useContext(toggleGroupValueContextId);
7070
const baseContext = useContext(toggleGroupBaseContextId);
7171
const disabled = baseContext.disabled || itemDisabled;
72+
const isPressedSig = useSignal(false);
7273

7374
const itemId = useId();
7475

75-
const pressed = useComputed$(() => {
76-
const pressedValue = valueContext.pressedValuesSig.value;
77-
if (pressedValue == null) return false;
76+
useTask$(({ track }) => {
77+
const pressedValue = track(() => valueContext.pressedValuesSig.value);
78+
if (pressedValue == null) {
79+
isPressedSig.value = false;
80+
return;
81+
}
7882

7983
if (typeof pressedValue === 'string') {
80-
return pressedValue === value;
84+
isPressedSig.value = pressedValue === value;
85+
} else {
86+
isPressedSig.value = pressedValue.includes(value);
8187
}
82-
return pressedValue.includes(value);
8388
});
8489

85-
// const pressed = useComputed$(() => valueContext.pressedValuesSig.value.includes(value));
86-
87-
const tabIndex = useComputed$(() => (pressed.value ? 0 : -1));
90+
const tabIndex = useComputed$(() => (isPressedSig.value ? 0 : -1));
8891

8992
const itemRef = useSignal<HTMLButtonElement>();
9093

@@ -163,7 +166,7 @@ export const HToggleGroupItem = component$<ToggleGroupItemProps>((props) => {
163166
<Toggle
164167
ref={itemRef}
165168
{...itemProps}
166-
pressed={pressed.value}
169+
bind:pressed={isPressedSig}
167170
disabled={disabled}
168171
onPressedChange$={handlePressed$}
169172
onKeyDown$={[handleKeyDownSync$, handleKeyDown$]}

packages/kit-headless/src/components/toggle-group/use-toggle.tsx

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,6 @@ function useCreateSingleToggleGroup(props: ToggleGroupSingleProps) {
2626
pressedValuesSig.value = value;
2727
});
2828

29-
// const pressedValuesSig = useSignal(givenValueSig?.value ?? value ?? defaultValue ?? '');
30-
31-
// // side effect: update external when internal changed
32-
// useTask$(({ track }) => {
33-
// if (!givenValueSig) return;
34-
// track(() => pressedValuesSig.value); //internal changed
35-
// givenValueSig.value = pressedValuesSig.value; //side effect: update external
36-
// });
37-
38-
// // side effect: update internal when external changed
39-
// useTask$(({ track }) => {
40-
// if (!givenValueSig) return;
41-
// track(() => givenValueSig.value); //external changed
42-
// pressedValuesSig.value = givenValueSig.value; //side effect: update internal
43-
// });
44-
4529
const handleValueChange$ = $((newValue: string) => {
4630
pressedValuesSig.value = newValue;
4731
console.log('newState', newValue);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ test.describe('Mouse Behavior', () => {
8181
await expect(spanElement).toContainText('You unpressed me');
8282
});
8383

84-
//bind:pressed: 2 way binding (writting)
84+
//bind:pressed: 2 way binding (writing)
8585
test(`GIVEN a pressed toggle (with 'bind-pressed')
8686
WHEN the toggle is clicked
8787
AND the external button is clicked

packages/kit-headless/src/components/toggle/toggle.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { PropsOf, QRL, Signal } from '@builder.io/qwik';
2-
import { $, component$, Slot, useSignal, useTask$ } from '@builder.io/qwik';
2+
import { $, component$, Slot, useTask$ } from '@builder.io/qwik';
3+
import { useBoundSignal } from '../../utils/bound-signal';
34

45
export type ToggleProps = PropsOf<'button'> & {
56
/**
@@ -36,13 +37,11 @@ export const HToggle = component$<ToggleProps>((props) => {
3637
pressed: pressedProp,
3738
defaultPressed = false,
3839
onPressedChange$,
39-
// 'bind:pressed': givenValueSig,
40+
'bind:pressed': givenValueSig,
4041
...buttonProps
4142
} = props;
4243

43-
// const pressedSig = useBoundSignal(givenValueSig, defaultPressed);
44-
45-
const pressedSig = useSignal<boolean>(defaultPressed);
44+
const pressedSig = useBoundSignal(givenValueSig, defaultPressed);
4645

4746
useTask$(({ track }) => {
4847
if (pressedProp === undefined) return;

0 commit comments

Comments
 (0)