ui-ingredients 0.0.41 → 0.0.42

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. package/dist/accordion/item-content.svelte +17 -6
  2. package/dist/accordion/root.svelte +18 -6
  3. package/dist/color-picker/root.svelte +1 -1
  4. package/dist/combobox/content.svelte +8 -6
  5. package/dist/combobox/positioner.svelte +8 -6
  6. package/dist/combobox/root.svelte +21 -6
  7. package/dist/date-picker/content.svelte +8 -6
  8. package/dist/date-picker/positioner.svelte +8 -6
  9. package/dist/date-picker/root.svelte +21 -6
  10. package/dist/dialog/backdrop.svelte +17 -6
  11. package/dist/dialog/content.svelte +8 -6
  12. package/dist/dialog/positioner.svelte +8 -6
  13. package/dist/dialog/root.svelte +25 -3
  14. package/dist/hover-card/content.svelte +8 -6
  15. package/dist/hover-card/positioner.svelte +8 -6
  16. package/dist/hover-card/root.svelte +27 -2
  17. package/dist/menu/content.svelte +8 -6
  18. package/dist/menu/positioner.svelte +8 -6
  19. package/dist/menu/root.svelte +38 -2
  20. package/dist/popover/content.svelte +8 -6
  21. package/dist/popover/positioner.svelte +8 -6
  22. package/dist/popover/root.svelte +35 -2
  23. package/dist/portal/root.svelte +5 -1
  24. package/dist/presence/context.svelte.d.ts +2 -1
  25. package/dist/presence/context.svelte.js +1 -0
  26. package/dist/presence/create-presence.svelte.d.ts +9 -2
  27. package/dist/presence/create-presence.svelte.js +25 -5
  28. package/dist/presence/root.svelte +16 -6
  29. package/dist/select/content.svelte +8 -6
  30. package/dist/select/positioner.svelte +8 -6
  31. package/dist/select/root.svelte +19 -4
  32. package/dist/time-picker/content.svelte +14 -4
  33. package/dist/time-picker/positioner.svelte +7 -1
  34. package/dist/time-picker/root.svelte +29 -4
  35. package/dist/tooltip/content.svelte +8 -6
  36. package/dist/tooltip/positioner.svelte +8 -6
  37. package/dist/tooltip/root.svelte +20 -2
  38. package/package.json +1 -1
@@ -8,6 +8,7 @@
8
8
 
9
9
  <script lang="ts">
10
10
  import {mergeProps} from '../merge-props.js';
11
+ import {getPresenceStrategyPropsContext} from '../presence/context.svelte.js';
11
12
  import {createPresence} from '../presence/create-presence.svelte.js';
12
13
  import {
13
14
  getAccordionContext,
@@ -19,10 +20,18 @@
19
20
  let accordion = getAccordionContext();
20
21
  let itemProps = getAccordionItemPropsContext();
21
22
  let itemsState = $derived(accordion.getItemState(itemProps));
23
+
24
+ let presenceStrategyProps = getPresenceStrategyPropsContext();
22
25
  let presence = createPresence({
23
26
  get present() {
24
27
  return itemsState.expanded;
25
28
  },
29
+ get lazyMount() {
30
+ return presenceStrategyProps.lazyMount;
31
+ },
32
+ get keepMounted() {
33
+ return presenceStrategyProps.keepMounted;
34
+ },
26
35
  });
27
36
 
28
37
  let mergedProps = $derived(
@@ -34,10 +43,12 @@
34
43
  );
35
44
  </script>
36
45
 
37
- {#if asChild}
38
- {@render asChild(presence.ref, mergedProps)}
39
- {:else}
40
- <div use:presence.ref {...mergedProps}>
41
- {@render children?.()}
42
- </div>
46
+ {#if presence.mounted}
47
+ {#if asChild}
48
+ {@render asChild(presence.ref, mergedProps)}
49
+ {:else}
50
+ <div use:presence.ref {...mergedProps}>
51
+ {@render children?.()}
52
+ </div>
53
+ {/if}
43
54
  {/if}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts" module>
2
+ import type {PresenceStrategyProps} from '../presence/create-presence.svelte.js';
2
3
  import type {Assign, HtmlIngredientProps} from '../types.js';
3
4
  import type {
4
5
  CreateAccordionProps,
@@ -7,13 +8,15 @@
7
8
 
8
9
  export interface AccordionProps
9
10
  extends Assign<
10
- HtmlIngredientProps<'div', CreateAccordionReturn>,
11
- CreateAccordionProps
12
- > {}
11
+ HtmlIngredientProps<'div', CreateAccordionReturn>,
12
+ CreateAccordionProps
13
+ >,
14
+ PresenceStrategyProps {}
13
15
  </script>
14
16
 
15
17
  <script lang="ts">
16
18
  import {mergeProps} from '../merge-props.js';
19
+ import {setPresenceStrategyPropsContext} from '../presence/context.svelte.js';
17
20
  import {reflect} from '@zag-js/svelte';
18
21
  import {createSplitProps} from '@zag-js/utils';
19
22
  import {setAccordionContext} from './context.svelte.js';
@@ -21,7 +24,13 @@
21
24
 
22
25
  let {asChild, children, ...props}: AccordionProps = $props();
23
26
 
24
- let [accordionProps, otherProps] = $derived(
27
+ let [presenceStrategyProps, otherProps] = $derived(
28
+ createSplitProps<PresenceStrategyProps>(['lazyMount', 'keepMounted'])(
29
+ props,
30
+ ),
31
+ );
32
+
33
+ let [accordionProps, elementProps] = $derived(
25
34
  createSplitProps<CreateAccordionProps>([
26
35
  'id',
27
36
  'ids',
@@ -32,14 +41,17 @@
32
41
  'collapsible',
33
42
  'onFocusChange',
34
43
  'onValueChange',
35
- ])(props),
44
+ ])(otherProps),
36
45
  );
37
46
 
38
47
  let accordion = createAccordion(reflect(() => accordionProps));
39
48
 
40
- let mergedProps = $derived(mergeProps(otherProps, accordion.getRootProps()));
49
+ let mergedProps = $derived(
50
+ mergeProps(elementProps, accordion.getRootProps()),
51
+ );
41
52
 
42
53
  setAccordionContext(accordion);
54
+ setPresenceStrategyPropsContext(() => presenceStrategyProps);
43
55
  </script>
44
56
 
45
57
  {#if asChild}
@@ -51,7 +51,7 @@
51
51
  let colorPicker = createColorPicker(reflect(() => colorPickerProps));
52
52
  let presence = createPresence({
53
53
  get present() {
54
- return colorPickerProps.open;
54
+ return colorPicker.open;
55
55
  },
56
56
  });
57
57
 
@@ -21,10 +21,12 @@
21
21
  );
22
22
  </script>
23
23
 
24
- {#if asChild}
25
- {@render asChild(presence.ref, mergedProps)}
26
- {:else}
27
- <div use:presence.ref {...mergedProps}>
28
- {@render children?.()}
29
- </div>
24
+ {#if presence.mounted}
25
+ {#if asChild}
26
+ {@render asChild(presence.ref, mergedProps)}
27
+ {:else}
28
+ <div use:presence.ref {...mergedProps}>
29
+ {@render children?.()}
30
+ </div>
31
+ {/if}
30
32
  {/if}
@@ -23,10 +23,12 @@
23
23
  );
24
24
  </script>
25
25
 
26
- {#if asChild}
27
- {@render asChild(mergedProps)}
28
- {:else}
29
- <div {...mergedProps}>
30
- {@render children?.()}
31
- </div>
26
+ {#if presence.mounted}
27
+ {#if asChild}
28
+ {@render asChild(mergedProps)}
29
+ {:else}
30
+ <div {...mergedProps}>
31
+ {@render children?.()}
32
+ </div>
33
+ {/if}
32
34
  {/if}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts" module>
2
+ import type {PresenceStrategyProps} from '../presence/create-presence.svelte.js';
2
3
  import type {Assign, HtmlIngredientProps} from '../types.js';
3
4
  import type {
4
5
  CreateComboboxProps,
@@ -7,9 +8,10 @@
7
8
 
8
9
  export interface ComboboxProps<T>
9
10
  extends Assign<
10
- HtmlIngredientProps<'div', CreateComboboxReturn>,
11
- CreateComboboxProps<T>
12
- > {}
11
+ HtmlIngredientProps<'div', CreateComboboxReturn>,
12
+ CreateComboboxProps<T>
13
+ >,
14
+ PresenceStrategyProps {}
13
15
  </script>
14
16
 
15
17
  <script lang="ts" generics="T">
@@ -23,7 +25,13 @@
23
25
 
24
26
  let {asChild, children, ...props}: ComboboxProps<T> = $props();
25
27
 
26
- let [comboboxProps, otherProps] = $derived(
28
+ let [presenceStrategyProps, otherProps] = $derived(
29
+ createSplitProps<PresenceStrategyProps>(['lazyMount', 'keepMounted'])(
30
+ props,
31
+ ),
32
+ );
33
+
34
+ let [comboboxProps, elementProps] = $derived(
27
35
  createSplitProps<CreateComboboxProps<T>>([
28
36
  'id',
29
37
  'ids',
@@ -66,17 +74,24 @@
66
74
  'onPointerDownOutside',
67
75
  'getSelectionValue',
68
76
  'scrollToIndexFn',
69
- ])(props),
77
+ ])(otherProps),
70
78
  );
71
79
 
72
80
  let combobox = createCombobox(reflect(() => comboboxProps));
81
+
73
82
  let presence = createPresence({
74
83
  get present() {
75
84
  return combobox.open;
76
85
  },
86
+ get lazyMount() {
87
+ return presenceStrategyProps.lazyMount;
88
+ },
89
+ get keepMounted() {
90
+ return presenceStrategyProps.keepMounted;
91
+ },
77
92
  });
78
93
 
79
- let mergedProps = $derived(mergeProps(otherProps, combobox.getRootProps()));
94
+ let mergedProps = $derived(mergeProps(elementProps, combobox.getRootProps()));
80
95
 
81
96
  setComboboxContext(combobox);
82
97
  setPresenceContext(presence);
@@ -25,10 +25,12 @@
25
25
  );
26
26
  </script>
27
27
 
28
- {#if asChild}
29
- {@render asChild(presence.ref, mergedProps)}
30
- {:else}
31
- <div use:presence.ref {...mergedProps}>
32
- {@render children?.()}
33
- </div>
28
+ {#if presence.mounted}
29
+ {#if asChild}
30
+ {@render asChild(presence.ref, mergedProps)}
31
+ {:else}
32
+ <div use:presence.ref {...mergedProps}>
33
+ {@render children?.()}
34
+ </div>
35
+ {/if}
34
36
  {/if}
@@ -24,10 +24,12 @@
24
24
  );
25
25
  </script>
26
26
 
27
- {#if asChild}
28
- {@render asChild(mergedProps)}
29
- {:else}
30
- <div {...mergedProps}>
31
- {@render children?.()}
32
- </div>
27
+ {#if presence.mounted}
28
+ {#if asChild}
29
+ {@render asChild(mergedProps)}
30
+ {:else}
31
+ <div {...mergedProps}>
32
+ {@render children?.()}
33
+ </div>
34
+ {/if}
33
35
  {/if}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts" module>
2
+ import type {PresenceStrategyProps} from '../presence/create-presence.svelte.js';
2
3
  import type {Assign, HtmlIngredientProps} from '../types.js';
3
4
  import type {
4
5
  CreateDatePickerProps,
@@ -7,9 +8,10 @@
7
8
 
8
9
  export interface DatePickerProps
9
10
  extends Assign<
10
- HtmlIngredientProps<'div', CreateDatePickerReturn>,
11
- CreateDatePickerProps
12
- > {}
11
+ HtmlIngredientProps<'div', CreateDatePickerReturn>,
12
+ CreateDatePickerProps
13
+ >,
14
+ PresenceStrategyProps {}
13
15
  </script>
14
16
 
15
17
  <script lang="ts">
@@ -23,7 +25,11 @@
23
25
 
24
26
  let {asChild, children, ...props}: DatePickerProps = $props();
25
27
 
26
- let [datePickerProps, otherProps] = $derived(
28
+ let [presenceStrategyProps, otherProps] = $derived(
29
+ createSplitProps<PresenceStrategyProps>([])(props),
30
+ );
31
+
32
+ let [datePickerProps, elementProps] = $derived(
27
33
  createSplitProps<CreateDatePickerProps>([
28
34
  'id',
29
35
  'ids',
@@ -53,17 +59,26 @@
53
59
  'onValueChange',
54
60
  'onFocusChange',
55
61
  'isDateUnavailable',
56
- ])(props),
62
+ ])(otherProps),
57
63
  );
58
64
 
59
65
  let datePicker = createDatePicker(reflect(() => datePickerProps));
66
+
60
67
  let presence = createPresence({
61
68
  get present() {
62
69
  return datePicker.open;
63
70
  },
71
+ get lazyMount() {
72
+ return presenceStrategyProps.lazyMount;
73
+ },
74
+ get keepMounted() {
75
+ return presenceStrategyProps.keepMounted;
76
+ },
64
77
  });
65
78
 
66
- let mergedProps = $derived(mergeProps(otherProps, datePicker.getRootProps()));
79
+ let mergedProps = $derived(
80
+ mergeProps(elementProps, datePicker.getRootProps()),
81
+ );
67
82
 
68
83
  setDatePickerContext(datePicker);
69
84
  setPresenceContext(presence);
@@ -8,16 +8,25 @@
8
8
 
9
9
  <script lang="ts">
10
10
  import {mergeProps} from '../merge-props.js';
11
+ import {getPresenceStrategyPropsContext} from '../presence/context.svelte.js';
11
12
  import {createPresence} from '../presence/create-presence.svelte.js';
12
13
  import {getDialogContext} from './context.svelte.js';
13
14
 
14
15
  let {asChild, children, ...props}: DialogBackdropProps = $props();
15
16
 
16
17
  let dialog = getDialogContext();
18
+
19
+ let presenceStrategyProps = getPresenceStrategyPropsContext();
17
20
  let presence = createPresence({
18
21
  get present() {
19
22
  return dialog.open;
20
23
  },
24
+ get lazyMount() {
25
+ return presenceStrategyProps.lazyMount;
26
+ },
27
+ get keepMounted() {
28
+ return presenceStrategyProps.keepMounted;
29
+ },
21
30
  });
22
31
 
23
32
  let mergedProps = $derived(
@@ -25,10 +34,12 @@
25
34
  );
26
35
  </script>
27
36
 
28
- {#if asChild}
29
- {@render asChild(presence.ref, mergedProps)}
30
- {:else}
31
- <div use:presence.ref {...mergedProps}>
32
- {@render children?.()}
33
- </div>
37
+ {#if presence.mounted}
38
+ {#if asChild}
39
+ {@render asChild(presence.ref, mergedProps)}
40
+ {:else}
41
+ <div use:presence.ref {...mergedProps}>
42
+ {@render children?.()}
43
+ </div>
44
+ {/if}
34
45
  {/if}
@@ -21,10 +21,12 @@
21
21
  );
22
22
  </script>
23
23
 
24
- {#if asChild}
25
- {@render asChild(presence.ref, mergedProps)}
26
- {:else}
27
- <div use:presence.ref {...mergedProps}>
28
- {@render children?.()}
29
- </div>
24
+ {#if presence.mounted}
25
+ {#if asChild}
26
+ {@render asChild(presence.ref, mergedProps)}
27
+ {:else}
28
+ <div use:presence.ref {...mergedProps}>
29
+ {@render children?.()}
30
+ </div>
31
+ {/if}
30
32
  {/if}
@@ -19,10 +19,12 @@
19
19
  );
20
20
  </script>
21
21
 
22
- {#if asChild}
23
- {@render asChild(mergedProps)}
24
- {:else}
25
- <div {...mergedProps}>
26
- {@render children?.()}
27
- </div>
22
+ {#if presence.mounted}
23
+ {#if asChild}
24
+ {@render asChild(mergedProps)}
25
+ {:else}
26
+ <div {...mergedProps}>
27
+ {@render children?.()}
28
+ </div>
29
+ {/if}
28
30
  {/if}
@@ -1,32 +1,54 @@
1
1
  <script lang="ts" module>
2
+ import type {PresenceStrategyProps} from '../presence/create-presence.svelte.js';
2
3
  import type {Snippet} from 'svelte';
3
4
  import type {
4
5
  CreateDialogProps,
5
6
  CreateDialogReturn,
6
7
  } from './create-dialog.svelte.js';
7
8
 
8
- export interface DialogProps extends CreateDialogProps {
9
+ export interface DialogProps
10
+ extends CreateDialogProps,
11
+ PresenceStrategyProps {
9
12
  children?: Snippet<[CreateDialogReturn]>;
10
13
  }
11
14
  </script>
12
15
 
13
16
  <script lang="ts">
14
- import {setPresenceContext} from '../presence/context.svelte.js';
17
+ import {
18
+ setPresenceContext,
19
+ setPresenceStrategyPropsContext,
20
+ } from '../presence/context.svelte.js';
15
21
  import {createPresence} from '../presence/create-presence.svelte.js';
22
+ import {reflect} from '@zag-js/svelte';
23
+ import {createSplitProps} from '@zag-js/utils';
16
24
  import {setDialogContext} from './context.svelte.js';
17
25
  import {createDialog} from './create-dialog.svelte.js';
18
26
 
19
27
  let {children, ...props}: DialogProps = $props();
20
28
 
21
- let dialog = createDialog(props);
29
+ let [presenceStrategyProps, dialogProps] = $derived(
30
+ createSplitProps<PresenceStrategyProps>(['lazyMount', 'keepMounted'])(
31
+ props,
32
+ ),
33
+ );
34
+
35
+ let dialog = createDialog(reflect(() => dialogProps));
36
+
22
37
  let presence = createPresence({
23
38
  get present() {
24
39
  return dialog.open;
25
40
  },
41
+ get lazyMount() {
42
+ return presenceStrategyProps.lazyMount;
43
+ },
44
+ get keepMounted() {
45
+ return presenceStrategyProps.keepMounted;
46
+ },
26
47
  });
27
48
 
28
49
  setDialogContext(dialog);
29
50
  setPresenceContext(presence);
51
+ setPresenceStrategyPropsContext(() => presenceStrategyProps);
30
52
  </script>
31
53
 
32
54
  {@render children?.(dialog)}
@@ -21,10 +21,12 @@
21
21
  );
22
22
  </script>
23
23
 
24
- {#if asChild}
25
- {@render asChild(presence.ref, mergedProps)}
26
- {:else}
27
- <div use:presence.ref {...mergedProps}>
28
- {@render children?.()}
29
- </div>
24
+ {#if presence.mounted}
25
+ {#if asChild}
26
+ {@render asChild(presence.ref, mergedProps)}
27
+ {:else}
28
+ <div use:presence.ref {...mergedProps}>
29
+ {@render children?.()}
30
+ </div>
31
+ {/if}
30
32
  {/if}
@@ -24,10 +24,12 @@
24
24
  );
25
25
  </script>
26
26
 
27
- {#if asChild}
28
- {@render asChild(mergedProps)}
29
- {:else}
30
- <div {...mergedProps}>
31
- {@render children?.()}
32
- </div>
27
+ {#if presence.mounted}
28
+ {#if asChild}
29
+ {@render asChild(mergedProps)}
30
+ {:else}
31
+ <div {...mergedProps}>
32
+ {@render children?.()}
33
+ </div>
34
+ {/if}
33
35
  {/if}
@@ -1,11 +1,14 @@
1
1
  <script lang="ts" module>
2
+ import type {PresenceStrategyProps} from '../presence/create-presence.svelte.js';
2
3
  import type {Snippet} from 'svelte';
3
4
  import type {
4
5
  CreateHoverCardProps,
5
6
  CreateHoverCardReturn,
6
7
  } from './create-hover-card.svelte.js';
7
8
 
8
- export interface HoverCardProps extends CreateHoverCardProps {
9
+ export interface HoverCardProps
10
+ extends CreateHoverCardProps,
11
+ PresenceStrategyProps {
9
12
  children?: Snippet<[CreateHoverCardReturn]>;
10
13
  }
11
14
  </script>
@@ -13,16 +16,38 @@
13
16
  <script lang="ts">
14
17
  import {setPresenceContext} from '../presence/context.svelte.js';
15
18
  import {createPresence} from '../presence/create-presence.svelte.js';
19
+ import {reflect} from '@zag-js/svelte';
20
+ import {createSplitProps} from '@zag-js/utils';
16
21
  import {setHoverCardContext} from './context.svelte.js';
17
22
  import {createHoverCard} from './create-hover-card.svelte.js';
18
23
 
19
24
  let {children, ...props}: HoverCardProps = $props();
20
25
 
21
- let hoverCard = createHoverCard(props);
26
+ let [hoverCardProps, presenceStrategyProps] = $derived(
27
+ createSplitProps<CreateHoverCardProps>([
28
+ 'id',
29
+ 'ids',
30
+ 'open',
31
+ 'openDelay',
32
+ 'closeDelay',
33
+ 'defaultOpen',
34
+ 'positioning',
35
+ 'onOpenChange',
36
+ ])(props),
37
+ );
38
+
39
+ let hoverCard = createHoverCard(reflect(() => hoverCardProps));
40
+
22
41
  let presence = createPresence({
23
42
  get present() {
24
43
  return hoverCard.open;
25
44
  },
45
+ get lazyMount() {
46
+ return presenceStrategyProps.lazyMount;
47
+ },
48
+ get keepMounted() {
49
+ return presenceStrategyProps.keepMounted;
50
+ },
26
51
  });
27
52
 
28
53
  setHoverCardContext(hoverCard);
@@ -21,10 +21,12 @@
21
21
  );
22
22
  </script>
23
23
 
24
- {#if asChild}
25
- {@render asChild(presence.ref, mergedProps)}
26
- {:else}
27
- <div use:presence.ref {...mergedProps}>
28
- {@render children?.()}
29
- </div>
24
+ {#if presence.mounted}
25
+ {#if asChild}
26
+ {@render asChild(presence.ref, mergedProps)}
27
+ {:else}
28
+ <div use:presence.ref {...mergedProps}>
29
+ {@render children?.()}
30
+ </div>
31
+ {/if}
30
32
  {/if}
@@ -19,10 +19,12 @@
19
19
  );
20
20
  </script>
21
21
 
22
- {#if asChild}
23
- {@render asChild(mergedProps)}
24
- {:else}
25
- <div {...mergedProps}>
26
- {@render children?.()}
27
- </div>
22
+ {#if presence.mounted}
23
+ {#if asChild}
24
+ {@render asChild(mergedProps)}
25
+ {:else}
26
+ <div {...mergedProps}>
27
+ {@render children?.()}
28
+ </div>
29
+ {/if}
28
30
  {/if}
@@ -1,11 +1,14 @@
1
1
  <script lang="ts" module>
2
+ import type {PresenceStrategyProps} from '../presence/create-presence.svelte.js';
2
3
  import type {Snippet} from 'svelte';
3
4
  import {
4
5
  type CreateMenuProps,
5
6
  type CreateMenuReturn,
6
7
  } from './create-menu.svelte.js';
7
8
 
8
- export interface MenuRootProps extends CreateMenuProps {
9
+ export interface MenuRootProps
10
+ extends CreateMenuProps,
11
+ PresenceStrategyProps {
9
12
  children?: Snippet<[CreateMenuReturn]>;
10
13
  }
11
14
  </script>
@@ -13,16 +16,49 @@
13
16
  <script lang="ts">
14
17
  import {setPresenceContext} from '../presence/context.svelte.js';
15
18
  import {createPresence} from '../presence/create-presence.svelte.js';
19
+ import {reflect} from '@zag-js/svelte';
20
+ import {createSplitProps} from '@zag-js/utils';
16
21
  import {setMenuContext} from './context.svelte.js';
17
22
  import {createMenu} from './create-menu.svelte.js';
18
23
 
19
24
  let {children, ...props}: MenuRootProps = $props();
20
25
 
21
- let menu = createMenu(props);
26
+ let [menuProps, presenceStrategyProps] = $derived(
27
+ createSplitProps<CreateMenuProps>([
28
+ 'anchorPoint',
29
+ 'aria-label',
30
+ 'closeOnSelect',
31
+ 'composite',
32
+ 'defaultOpen',
33
+ 'highlightedValue',
34
+ 'id',
35
+ 'ids',
36
+ 'loopFocus',
37
+ 'onEscapeKeyDown',
38
+ 'onFocusOutside',
39
+ 'onHighlightChange',
40
+ 'onInteractOutside',
41
+ 'onOpenChange',
42
+ 'onPointerDownOutside',
43
+ 'onSelect',
44
+ 'open',
45
+ 'positioning',
46
+ 'typeahead',
47
+ ])(props),
48
+ );
49
+
50
+ let menu = createMenu(reflect(() => menuProps));
51
+
22
52
  let presence = createPresence({
23
53
  get present() {
24
54
  return menu.open;
25
55
  },
56
+ get lazyMount() {
57
+ return presenceStrategyProps.lazyMount;
58
+ },
59
+ get keepMounted() {
60
+ return presenceStrategyProps.keepMounted;
61
+ },
26
62
  });
27
63
 
28
64
  setMenuContext(menu);
@@ -21,10 +21,12 @@
21
21
  );
22
22
  </script>
23
23
 
24
- {#if asChild}
25
- {@render asChild(presence.ref, mergedProps)}
26
- {:else}
27
- <div use:presence.ref {...mergedProps}>
28
- {@render children?.()}
29
- </div>
24
+ {#if presence.mounted}
25
+ {#if asChild}
26
+ {@render asChild(presence.ref, mergedProps)}
27
+ {:else}
28
+ <div use:presence.ref {...mergedProps}>
29
+ {@render children?.()}
30
+ </div>
31
+ {/if}
30
32
  {/if}
@@ -23,10 +23,12 @@
23
23
  );
24
24
  </script>
25
25
 
26
- {#if asChild}
27
- {@render asChild(mergedProps)}
28
- {:else}
29
- <div {...mergedProps}>
30
- {@render children?.()}
31
- </div>
26
+ {#if presence.mounted}
27
+ {#if asChild}
28
+ {@render asChild(mergedProps)}
29
+ {:else}
30
+ <div {...mergedProps}>
31
+ {@render children?.()}
32
+ </div>
33
+ {/if}
32
34
  {/if}
@@ -1,11 +1,14 @@
1
1
  <script lang="ts" module>
2
+ import type {PresenceStrategyProps} from '../presence/create-presence.svelte.js';
2
3
  import type {Snippet} from 'svelte';
3
4
  import type {
4
5
  CreatePopoverProps,
5
6
  CreatePopoverReturn,
6
7
  } from './create-popover.svelte.js';
7
8
 
8
- export interface PopoverProps extends CreatePopoverProps {
9
+ export interface PopoverProps
10
+ extends CreatePopoverProps,
11
+ PresenceStrategyProps {
9
12
  children?: Snippet<[CreatePopoverReturn]>;
10
13
  }
11
14
  </script>
@@ -13,16 +16,46 @@
13
16
  <script lang="ts">
14
17
  import {setPresenceContext} from '../presence/context.svelte.js';
15
18
  import {createPresence} from '../presence/create-presence.svelte.js';
19
+ import {reflect} from '@zag-js/svelte';
20
+ import {createSplitProps} from '@zag-js/utils';
16
21
  import {setPopoverContext} from './context.svelte.js';
17
22
  import {createPopover} from './create-popover.svelte.js';
18
23
 
19
24
  let {children, ...props}: PopoverProps = $props();
20
25
 
21
- let popover = createPopover(props);
26
+ let [popoverProps, presenceStrategyProps] = $derived(
27
+ createSplitProps<CreatePopoverProps>([
28
+ 'autoFocus',
29
+ 'closeOnEscape',
30
+ 'closeOnInteractOutside',
31
+ 'defaultOpen',
32
+ 'id',
33
+ 'ids',
34
+ 'initialFocusEl',
35
+ 'modal',
36
+ 'onEscapeKeyDown',
37
+ 'onFocusOutside',
38
+ 'onInteractOutside',
39
+ 'onOpenChange',
40
+ 'onPointerDownOutside',
41
+ 'open',
42
+ 'persistentElements',
43
+ 'portalled',
44
+ 'positioning',
45
+ ])(props),
46
+ );
47
+
48
+ let popover = createPopover(reflect(() => popoverProps));
22
49
  let presence = createPresence({
23
50
  get present() {
24
51
  return popover.open;
25
52
  },
53
+ get lazyMount() {
54
+ return presenceStrategyProps.lazyMount;
55
+ },
56
+ get keepMounted() {
57
+ return presenceStrategyProps.keepMounted;
58
+ },
26
59
  });
27
60
 
28
61
  setPopoverContext(popover);
@@ -5,6 +5,7 @@
5
5
  container?: HTMLElement;
6
6
  disabled?: boolean;
7
7
  children: Snippet;
8
+ [x: `data-${string}`]: string | number | boolean | null | undefined;
8
9
  }
9
10
  </script>
10
11
 
@@ -12,7 +13,7 @@
12
13
  import {getEnvironmentContext} from '../environment-provider/index.js';
13
14
  import {portal} from '@zag-js/svelte';
14
15
 
15
- let {container, disabled, children}: PortalProps = $props();
16
+ let {container, disabled, children, ...props}: PortalProps = $props();
16
17
 
17
18
  let environment = getEnvironmentContext();
18
19
  </script>
@@ -23,6 +24,9 @@
23
24
  container,
24
25
  getRootNode: environment?.getRootNode,
25
26
  }}
27
+ data-scope="portal"
28
+ data-part="root"
29
+ {...props}
26
30
  >
27
31
  {@render children?.()}
28
32
  </div>
@@ -1,2 +1,3 @@
1
- import type { CreatePresenceReturn } from './create-presence.svelte.js';
1
+ import type { CreatePresenceReturn, PresenceStrategyProps } from './create-presence.svelte.js';
2
2
  export declare const getPresenceContext: () => CreatePresenceReturn, setPresenceContext: (context: CreatePresenceReturn | (() => CreatePresenceReturn)) => void;
3
+ export declare const getPresenceStrategyPropsContext: () => PresenceStrategyProps, setPresenceStrategyPropsContext: (context: PresenceStrategyProps | (() => PresenceStrategyProps)) => void;
@@ -1,2 +1,3 @@
1
1
  import { createContext } from '../create-context.svelte.js';
2
2
  export const [getPresenceContext, setPresenceContext] = createContext('Presence');
3
+ export const [getPresenceStrategyPropsContext, setPresenceStrategyPropsContext,] = createContext('PresenceStrategyProps');
@@ -1,10 +1,17 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
- export interface CreatePresenceProps {
3
- present?: boolean;
2
+ export interface PresenceStrategyProps {
3
+ /** @default false */
4
+ lazyMount?: boolean;
5
+ /** @default true */
6
+ keepMounted?: boolean;
7
+ }
8
+ export interface CreatePresenceProps extends PresenceStrategyProps {
9
+ present: boolean;
4
10
  }
5
11
  export interface CreatePresenceReturn extends ReturnType<typeof createPresence> {
6
12
  }
7
13
  export declare function createPresence(props: CreatePresenceProps): {
8
14
  ref: (node: HTMLElement) => void;
9
15
  getPresenceProps: () => HTMLAttributes<HTMLElement>;
16
+ readonly mounted: boolean;
10
17
  };
@@ -1,10 +1,12 @@
1
1
  import * as presence from '@zag-js/presence';
2
2
  import { normalizeProps, useMachine } from '@zag-js/svelte';
3
- import { tick } from 'svelte';
4
3
  export function createPresence(props) {
4
+ const present = $derived(props.present);
5
+ const lazyMount = $derived(props.lazyMount ?? false);
6
+ const keepMounted = $derived(props.keepMounted ?? true);
5
7
  const context = $derived({
6
8
  get present() {
7
- return props.present;
9
+ return present;
8
10
  },
9
11
  });
10
12
  const [state, send] = useMachine(presence.machine(context), { context });
@@ -15,13 +17,31 @@ export function createPresence(props) {
15
17
  'data-state': context.present ? 'open' : 'closed',
16
18
  };
17
19
  }
20
+ let wasPresent = $state(false);
21
+ $effect(() => {
22
+ if (!api.present)
23
+ return;
24
+ if (wasPresent)
25
+ return;
26
+ wasPresent = true;
27
+ });
28
+ const unmounted = $derived.by(() => {
29
+ if (api.present)
30
+ return false;
31
+ if (!wasPresent && lazyMount)
32
+ return true;
33
+ if (wasPresent && !keepMounted)
34
+ return true;
35
+ return false;
36
+ });
18
37
  function ref(node) {
19
- tick().then(() => {
20
- api.setNode(node);
21
- });
38
+ api.setNode(node);
22
39
  }
23
40
  return {
24
41
  ref,
25
42
  getPresenceProps,
43
+ get mounted() {
44
+ return !unmounted;
45
+ },
26
46
  };
27
47
  }
@@ -1,18 +1,22 @@
1
1
  <script lang="ts" module>
2
- import type {Assign, HtmlProps} from '../types.js';
2
+ import type {Assign, HtmlIngredientProps} from '../types.js';
3
3
  import type {CreatePresenceProps} from './create-presence.svelte.js';
4
4
 
5
5
  export interface PresenceProps
6
- extends Assign<HtmlProps<'div'>, CreatePresenceProps> {}
6
+ extends Assign<
7
+ HtmlIngredientProps<'div', never, Action>,
8
+ CreatePresenceProps
9
+ > {}
7
10
  </script>
8
11
 
9
12
  <script lang="ts">
10
13
  import {mergeProps} from '../merge-props.js';
11
14
  import {reflect} from '@zag-js/svelte';
12
15
  import {createSplitProps} from '@zag-js/utils';
16
+ import type {Action} from 'svelte/action';
13
17
  import {createPresence} from './create-presence.svelte.js';
14
18
 
15
- let {children, ...props}: PresenceProps = $props();
19
+ let {asChild, children, ...props}: PresenceProps = $props();
16
20
 
17
21
  let [presenceProps, otherProps] = $derived(
18
22
  createSplitProps<CreatePresenceProps>(['present'])(props),
@@ -25,6 +29,12 @@
25
29
  );
26
30
  </script>
27
31
 
28
- <div use:presence.ref {...mergedProps}>
29
- {@render children?.()}
30
- </div>
32
+ {#if presence.mounted}
33
+ {#if asChild}
34
+ {@render asChild(presence.ref, mergedProps)}
35
+ {:else}
36
+ <div use:presence.ref {...mergedProps}>
37
+ {@render children?.()}
38
+ </div>
39
+ {/if}
40
+ {/if}
@@ -21,10 +21,12 @@
21
21
  );
22
22
  </script>
23
23
 
24
- {#if asChild}
25
- {@render asChild(presence.ref, mergedProps)}
26
- {:else}
27
- <div use:presence.ref {...mergedProps}>
28
- {@render children?.()}
29
- </div>
24
+ {#if presence.mounted}
25
+ {#if asChild}
26
+ {@render asChild(presence.ref, mergedProps)}
27
+ {:else}
28
+ <div use:presence.ref {...mergedProps}>
29
+ {@render children?.()}
30
+ </div>
31
+ {/if}
30
32
  {/if}
@@ -19,10 +19,12 @@
19
19
  );
20
20
  </script>
21
21
 
22
- {#if asChild}
23
- {@render asChild(mergedProps)}
24
- {:else}
25
- <div {...mergedProps}>
26
- {@render children?.()}
27
- </div>
22
+ {#if presence.mounted}
23
+ {#if asChild}
24
+ {@render asChild(mergedProps)}
25
+ {:else}
26
+ <div {...mergedProps}>
27
+ {@render children?.()}
28
+ </div>
29
+ {/if}
28
30
  {/if}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts" module>
2
+ import type {PresenceStrategyProps} from '../presence/create-presence.svelte.js';
2
3
  import type {Assign, HtmlIngredientProps} from '../types.js';
3
4
  import type {
4
5
  CreateSelectProps,
@@ -7,9 +8,10 @@
7
8
 
8
9
  export interface SelectProps<T>
9
10
  extends Assign<
10
- HtmlIngredientProps<'div', CreateSelectReturn>,
11
- CreateSelectProps<T>
12
- > {}
11
+ HtmlIngredientProps<'div', CreateSelectReturn>,
12
+ CreateSelectProps<T>
13
+ >,
14
+ PresenceStrategyProps {}
13
15
  </script>
14
16
 
15
17
  <script lang="ts" generics="T">
@@ -57,13 +59,26 @@
57
59
  );
58
60
 
59
61
  let select = createSelect(reflect(() => selectProps));
62
+
63
+ let [presenceStrategyProps, elementProps] = $derived(
64
+ createSplitProps<PresenceStrategyProps>(['lazyMount', 'keepMounted'])(
65
+ otherProps,
66
+ ),
67
+ );
68
+
60
69
  let presence = createPresence({
61
70
  get present() {
62
71
  return select.open;
63
72
  },
73
+ get lazyMount() {
74
+ return presenceStrategyProps.lazyMount;
75
+ },
76
+ get keepMounted() {
77
+ return presenceStrategyProps.keepMounted;
78
+ },
64
79
  });
65
80
 
66
- let mergedProps = $derived(mergeProps(otherProps, select.getRootProps()));
81
+ let mergedProps = $derived(mergeProps(elementProps, select.getRootProps()));
67
82
 
68
83
  setSelectContext(select);
69
84
  setPresenceContext(presence);
@@ -1,24 +1,34 @@
1
1
  <script lang="ts" module>
2
2
  import type {HtmlIngredientProps} from '../types.js';
3
3
 
4
- export interface TimePickerContentProps extends HtmlIngredientProps<'div'> {}
4
+ export interface TimePickerContentProps
5
+ extends HtmlIngredientProps<'div', never, Action> {}
5
6
  </script>
6
7
 
7
8
  <script lang="ts">
8
9
  import {mergeProps} from '../merge-props.js';
10
+ import {getPresenceContext} from '../presence/context.svelte.js';
11
+ import type {Action} from 'svelte/action';
9
12
  import {getTimePickerContext} from './context.svelte.js';
10
13
 
11
14
  let {asChild, children, ...props}: TimePickerContentProps = $props();
12
15
 
13
16
  let timePicker = getTimePickerContext();
17
+ let presence = getPresenceContext();
14
18
 
15
- let mergedProps = $derived(mergeProps(props, timePicker.getContentProps()));
19
+ let mergedProps = $derived(
20
+ mergeProps(
21
+ props,
22
+ timePicker.getContentProps(),
23
+ presence.getPresenceProps(),
24
+ ),
25
+ );
16
26
  </script>
17
27
 
18
28
  {#if asChild}
19
- {@render asChild(mergedProps)}
29
+ {@render asChild(presence.ref, mergedProps)}
20
30
  {:else}
21
- <div {...mergedProps}>
31
+ <div use:presence.ref {...mergedProps}>
22
32
  {@render children?.()}
23
33
  </div>
24
34
  {/if}
@@ -7,14 +7,20 @@
7
7
 
8
8
  <script lang="ts">
9
9
  import {mergeProps} from '../merge-props.js';
10
+ import {getPresenceContext} from '../presence/context.svelte.js';
10
11
  import {getTimePickerContext} from './context.svelte.js';
11
12
 
12
13
  let {asChild, children, ...props}: TimePickerPositionerProps = $props();
13
14
 
14
15
  let timePicker = getTimePickerContext();
16
+ let presence = getPresenceContext();
15
17
 
16
18
  let mergedProps = $derived(
17
- mergeProps(props, timePicker.getPositionerProps()),
19
+ mergeProps(
20
+ props,
21
+ timePicker.getPositionerProps(),
22
+ presence.getPresenceProps(),
23
+ ),
18
24
  );
19
25
  </script>
20
26
 
@@ -1,4 +1,5 @@
1
1
  <script lang="ts" module>
2
+ import type {PresenceStrategyProps} from '../presence/create-presence.svelte.js';
2
3
  import type {Assign, HtmlIngredientProps} from '../types.js';
3
4
  import type {
4
5
  CreateTimePickerProps,
@@ -7,13 +8,16 @@
7
8
 
8
9
  export interface TimePickerProps
9
10
  extends Assign<
10
- HtmlIngredientProps<'div', CreateTimePickerReturn>,
11
- CreateTimePickerProps
12
- > {}
11
+ HtmlIngredientProps<'div', CreateTimePickerReturn>,
12
+ CreateTimePickerProps
13
+ >,
14
+ PresenceStrategyProps {}
13
15
  </script>
14
16
 
15
17
  <script lang="ts">
16
18
  import {mergeProps} from '../merge-props.js';
19
+ import {setPresenceContext} from '../presence/context.svelte.js';
20
+ import {createPresence} from '../presence/create-presence.svelte.js';
17
21
  import {reflect} from '@zag-js/svelte';
18
22
  import {createSplitProps} from '@zag-js/utils';
19
23
  import {setTimePickerContext} from './context.svelte.js';
@@ -47,9 +51,30 @@
47
51
 
48
52
  let timePicker = createTimePicker(reflect(() => timePickerProps));
49
53
 
50
- let mergedProps = $derived(mergeProps(otherProps, timePicker.getRootProps()));
54
+ let [presenceStrategyProps, elementProps] = $derived(
55
+ createSplitProps<PresenceStrategyProps>(['lazyMount', 'keepMounted'])(
56
+ otherProps,
57
+ ),
58
+ );
59
+
60
+ let presence = createPresence({
61
+ get present() {
62
+ return timePicker.open;
63
+ },
64
+ get lazyMount() {
65
+ return presenceStrategyProps.lazyMount;
66
+ },
67
+ get keepMounted() {
68
+ return presenceStrategyProps.keepMounted;
69
+ },
70
+ });
71
+
72
+ let mergedProps = $derived(
73
+ mergeProps(elementProps, timePicker.getRootProps()),
74
+ );
51
75
 
52
76
  setTimePickerContext(timePicker);
77
+ setPresenceContext(presence);
53
78
  </script>
54
79
 
55
80
  {#if asChild}
@@ -21,10 +21,12 @@
21
21
  );
22
22
  </script>
23
23
 
24
- {#if asChild}
25
- {@render asChild(presence.ref, mergedProps)}
26
- {:else}
27
- <div use:presence.ref {...mergedProps}>
28
- {@render children?.()}
29
- </div>
24
+ {#if presence.mounted}
25
+ {#if asChild}
26
+ {@render asChild(presence.ref, mergedProps)}
27
+ {:else}
28
+ <div use:presence.ref {...mergedProps}>
29
+ {@render children?.()}
30
+ </div>
31
+ {/if}
30
32
  {/if}
@@ -23,10 +23,12 @@
23
23
  );
24
24
  </script>
25
25
 
26
- {#if asChild}
27
- {@render asChild(mergedProps)}
28
- {:else}
29
- <div {...mergedProps}>
30
- {@render children?.()}
31
- </div>
26
+ {#if presence.mounted}
27
+ {#if asChild}
28
+ {@render asChild(mergedProps)}
29
+ {:else}
30
+ <div {...mergedProps}>
31
+ {@render children?.()}
32
+ </div>
33
+ {/if}
32
34
  {/if}
@@ -1,11 +1,14 @@
1
1
  <script lang="ts" module>
2
+ import type {PresenceStrategyProps} from '../presence/create-presence.svelte.js';
2
3
  import type {Snippet} from 'svelte';
3
4
  import type {
4
5
  CreateTooltipProps,
5
6
  CreateTooltipReturn,
6
7
  } from './create-tooltip.svelte.js';
7
8
 
8
- export interface TooltipProps extends CreateTooltipProps {
9
+ export interface TooltipProps
10
+ extends CreateTooltipProps,
11
+ PresenceStrategyProps {
9
12
  children?: Snippet<[CreateTooltipReturn]>;
10
13
  }
11
14
  </script>
@@ -13,16 +16,31 @@
13
16
  <script lang="ts">
14
17
  import {setPresenceContext} from '../presence/context.svelte.js';
15
18
  import {createPresence} from '../presence/create-presence.svelte.js';
19
+ import {reflect} from '@zag-js/svelte';
20
+ import {createSplitProps} from '@zag-js/utils';
16
21
  import {setTooltipContext} from './context.svelte.js';
17
22
  import {createTooltip} from './create-tooltip.svelte.js';
18
23
 
19
24
  let {children, ...props}: TooltipProps = $props();
20
25
 
21
- let tooltip = createTooltip(props);
26
+ let [presenceStrategyProps, tooltipProps] = $derived(
27
+ createSplitProps<PresenceStrategyProps>(['lazyMount', 'keepMounted'])(
28
+ props,
29
+ ),
30
+ );
31
+
32
+ let tooltip = createTooltip(reflect(() => tooltipProps));
33
+
22
34
  let presence = createPresence({
23
35
  get present() {
24
36
  return tooltip.open;
25
37
  },
38
+ get lazyMount() {
39
+ return presenceStrategyProps.lazyMount;
40
+ },
41
+ get keepMounted() {
42
+ return presenceStrategyProps.keepMounted;
43
+ },
26
44
  });
27
45
 
28
46
  setTooltipContext(tooltip);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ui-ingredients",
3
3
  "type": "module",
4
- "version": "0.0.41",
4
+ "version": "0.0.42",
5
5
  "packageManager": "pnpm@9.7.0",
6
6
  "svelte": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",