1
- import { getContext , setContext } from "svelte" ;
1
+ import { getContext , setContext , untrack } from "svelte" ;
2
2
3
3
/**
4
4
* @template T
5
5
* @typedef {Object } SingleSelectionContext
6
- * @property {T= } value
6
+ * @property {T|null } value
7
7
*/
8
8
9
9
/** @type {symbol } */
@@ -12,11 +12,16 @@ const SINGLE_SELECTION_KEY = Symbol("singleton");
12
12
/**
13
13
* @template T
14
14
* @param {boolean } [nonReactive=false] - use a non-reactive placeholder to allow multiple selection and keep context shallow
15
- * @returns {SingleSelectionContext<T>|null }
15
+ * @returns {SingleSelectionContext<T> }
16
16
*/
17
17
export function createSingleSelectionContext ( nonReactive = false ) {
18
- const context = $state ( { value : undefined } ) ;
19
- return setContext ( SINGLE_SELECTION_KEY , nonReactive ? null : context ) ;
18
+ if ( nonReactive ) {
19
+ const context = { value : null } ;
20
+ return setContext ( SINGLE_SELECTION_KEY , context ) ;
21
+ } else {
22
+ const context = $state ( { value : null } ) ;
23
+ return setContext ( SINGLE_SELECTION_KEY , context ) ;
24
+ }
20
25
}
21
26
22
27
/**
@@ -27,22 +32,27 @@ export function createSingleSelectionContext(nonReactive = false) {
27
32
* @returns {SingleSelectionContext<T> }
28
33
*/
29
34
function setSelected ( context , open , value ) {
30
- if ( open ) context . value = value ;
31
- else if ( context . value === value ) context . value = undefined ;
35
+ if ( open ) context . value = value ?? null ;
36
+ else if ( context . value === value ) context . value = null ;
32
37
33
38
return context ;
34
39
}
35
40
36
41
/**
37
42
* @template T
38
- * @param {(value: T) => void } callback
43
+ * @param {(value: T|null ) => void } callback
39
44
* @returns {(open: boolean, v?: T) => SingleSelectionContext<T> }
40
45
*/
41
46
export function useSingleSelection ( callback ) {
42
47
const context = getContext ( SINGLE_SELECTION_KEY ) ?? createSingleSelectionContext ( false ) ;
43
48
49
+ let initialized = $state ( false ) ;
44
50
$effect ( ( ) => {
45
- if ( context . value !== undefined ) callback ( context . value ) ;
51
+ if ( initialized )
52
+ // if (context.value !== null)
53
+ callback ( context . value ) ;
54
+ initialized = true ;
46
55
} ) ;
47
- return ( open , v ) => setSelected ( context , open , v ) ;
56
+
57
+ return ( open , v ) => untrack ( ( ) => setSelected ( context , open , v ) ) ;
48
58
}
0 commit comments