bits-ui 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/bits/context-menu/components/context-menu-content-static.svelte +2 -0
  2. package/dist/bits/context-menu/components/context-menu-content.svelte +2 -0
  3. package/dist/bits/dropdown-menu/components/dropdown-menu-content-static.svelte +2 -0
  4. package/dist/bits/dropdown-menu/components/dropdown-menu-content.svelte +2 -0
  5. package/dist/bits/link-preview/components/link-preview-content-static.svelte +7 -22
  6. package/dist/bits/link-preview/components/link-preview-content.svelte +7 -22
  7. package/dist/bits/link-preview/link-preview.svelte.d.ts +14 -1
  8. package/dist/bits/link-preview/link-preview.svelte.js +24 -0
  9. package/dist/bits/menu/components/menu-content-static.svelte +2 -0
  10. package/dist/bits/menu/components/menu-content.svelte +2 -0
  11. package/dist/bits/menu/menu.svelte.d.ts +3 -1
  12. package/dist/bits/menu/menu.svelte.js +3 -1
  13. package/dist/bits/menubar/components/menubar-content-static.svelte +1 -9
  14. package/dist/bits/menubar/components/menubar-content.svelte +1 -9
  15. package/dist/bits/menubar/menubar.svelte.d.ts +10 -4
  16. package/dist/bits/menubar/menubar.svelte.js +14 -12
  17. package/dist/bits/popover/components/popover-content-static.svelte +2 -7
  18. package/dist/bits/popover/components/popover-content.svelte +2 -6
  19. package/dist/bits/popover/popover.svelte.d.ts +8 -3
  20. package/dist/bits/popover/popover.svelte.js +11 -9
  21. package/dist/bits/progress/components/progress.svelte +2 -0
  22. package/dist/bits/progress/progress.svelte.d.ts +7 -5
  23. package/dist/bits/progress/progress.svelte.js +6 -5
  24. package/dist/bits/progress/types.d.ts +11 -2
  25. package/dist/bits/select/components/select-content-static.svelte +7 -30
  26. package/dist/bits/select/components/select-content.svelte +4 -27
  27. package/dist/bits/select/select.svelte.d.ts +17 -2
  28. package/dist/bits/select/select.svelte.js +30 -3
  29. package/dist/bits/select/types.d.ts +2 -2
  30. package/dist/bits/tooltip/components/tooltip-content-static.svelte +7 -23
  31. package/dist/bits/tooltip/components/tooltip-content.svelte +7 -22
  32. package/dist/bits/tooltip/tooltip.svelte.d.ts +14 -1
  33. package/dist/bits/tooltip/tooltip.svelte.js +31 -1
  34. package/package.json +1 -1
@@ -65,6 +65,7 @@
65
65
  {#if forceMount}
66
66
  <PopperLayerForceMount
67
67
  {...mergedProps}
68
+ {...contentState.popperProps}
68
69
  isStatic
69
70
  side="right"
70
71
  sideOffset={2}
@@ -96,6 +97,7 @@
96
97
  {:else if !forceMount}
97
98
  <PopperLayer
98
99
  {...mergedProps}
100
+ {...contentState.popperProps}
99
101
  isStatic
100
102
  side="right"
101
103
  sideOffset={2}
@@ -65,6 +65,7 @@
65
65
  {#if forceMount}
66
66
  <PopperLayerForceMount
67
67
  {...mergedProps}
68
+ {...contentState.popperProps}
68
69
  side="right"
69
70
  sideOffset={2}
70
71
  align="start"
@@ -96,6 +97,7 @@
96
97
  {:else if !forceMount}
97
98
  <PopperLayer
98
99
  {...mergedProps}
100
+ {...contentState.popperProps}
99
101
  side="right"
100
102
  sideOffset={2}
101
103
  align="start"
@@ -51,6 +51,7 @@
51
51
  {#if forceMount}
52
52
  <PopperLayerForceMount
53
53
  {...mergedProps}
54
+ {...contentState.popperProps}
54
55
  enabled={contentState.parentMenu.opts.open.current}
55
56
  onInteractOutside={handleInteractOutside}
56
57
  onEscapeKeydown={handleEscapeKeydown}
@@ -77,6 +78,7 @@
77
78
  {:else if !forceMount}
78
79
  <PopperLayer
79
80
  {...mergedProps}
81
+ {...contentState.popperProps}
80
82
  present={contentState.parentMenu.opts.open.current}
81
83
  onInteractOutside={handleInteractOutside}
82
84
  onEscapeKeydown={handleEscapeKeydown}
@@ -51,6 +51,7 @@
51
51
  {#if forceMount}
52
52
  <PopperLayerForceMount
53
53
  {...mergedProps}
54
+ {...contentState.popperProps}
54
55
  enabled={contentState.parentMenu.opts.open.current}
55
56
  onInteractOutside={handleInteractOutside}
56
57
  onEscapeKeydown={handleEscapeKeydown}
@@ -78,6 +79,7 @@
78
79
  {:else if !forceMount}
79
80
  <PopperLayer
80
81
  {...mergedProps}
82
+ {...contentState.popperProps}
81
83
  present={contentState.parentMenu.opts.open.current}
82
84
  onInteractOutside={handleInteractOutside}
83
85
  onEscapeKeydown={handleEscapeKeydown}
@@ -6,14 +6,15 @@
6
6
  import PopperLayer from "../../utilities/popper-layer/popper-layer.svelte";
7
7
  import { getFloatingContentCSSVars } from "../../../internal/floating-svelte/floating-utils.svelte.js";
8
8
  import PopperLayerForceMount from "../../utilities/popper-layer/popper-layer-force-mount.svelte";
9
+ import { noop } from "../../../internal/noop.js";
9
10
 
10
11
  let {
11
12
  children,
12
13
  child,
13
14
  id = useId(),
14
15
  ref = $bindable(null),
15
- onInteractOutside,
16
- onEscapeKeydown,
16
+ onInteractOutside = noop,
17
+ onEscapeKeydown = noop,
17
18
  forceMount = false,
18
19
  ...restProps
19
20
  }: LinkPreviewContentStaticProps = $props();
@@ -24,33 +25,20 @@
24
25
  () => ref,
25
26
  (v) => (ref = v)
26
27
  ),
28
+ onInteractOutside: box.with(() => onInteractOutside),
29
+ onEscapeKeydown: box.with(() => onEscapeKeydown),
27
30
  });
28
31
 
29
32
  const mergedProps = $derived(mergeProps(restProps, contentState.props));
30
-
31
- function handleInteractOutside(e: PointerEvent) {
32
- onInteractOutside?.(e);
33
- if (e.defaultPrevented) return;
34
- contentState.root.handleClose();
35
- }
36
-
37
- function handleEscapeKeydown(e: KeyboardEvent) {
38
- onEscapeKeydown?.(e);
39
- if (e.defaultPrevented) return;
40
- contentState.root.handleClose();
41
- }
42
33
  </script>
43
34
 
44
35
  {#if forceMount}
45
36
  <PopperLayerForceMount
46
37
  {...mergedProps}
38
+ {...contentState.popperProps}
47
39
  enabled={contentState.root.opts.open.current}
48
40
  isStatic
49
41
  {id}
50
- onInteractOutside={handleInteractOutside}
51
- onEscapeKeydown={handleEscapeKeydown}
52
- onOpenAutoFocus={(e) => e.preventDefault()}
53
- onCloseAutoFocus={(e) => e.preventDefault()}
54
42
  trapFocus={false}
55
43
  loop={false}
56
44
  preventScroll={false}
@@ -72,13 +60,10 @@
72
60
  {:else if !forceMount}
73
61
  <PopperLayer
74
62
  {...mergedProps}
63
+ {...contentState.popperProps}
75
64
  present={contentState.root.opts.open.current}
76
65
  isStatic
77
66
  {id}
78
- onInteractOutside={handleInteractOutside}
79
- onEscapeKeydown={handleEscapeKeydown}
80
- onOpenAutoFocus={(e) => e.preventDefault()}
81
- onCloseAutoFocus={(e) => e.preventDefault()}
82
67
  trapFocus={false}
83
68
  loop={false}
84
69
  preventScroll={false}
@@ -7,6 +7,7 @@
7
7
  import { getFloatingContentCSSVars } from "../../../internal/floating-svelte/floating-utils.svelte.js";
8
8
  import PopperLayerForceMount from "../../utilities/popper-layer/popper-layer-force-mount.svelte";
9
9
  import Mounted from "../../utilities/mounted.svelte";
10
+ import { noop } from "../../../internal/noop.js";
10
11
 
11
12
  let {
12
13
  children,
@@ -21,8 +22,8 @@
21
22
  sticky = "partial",
22
23
  hideWhenDetached = false,
23
24
  collisionPadding = 0,
24
- onInteractOutside,
25
- onEscapeKeydown,
25
+ onInteractOutside = noop,
26
+ onEscapeKeydown = noop,
26
27
  forceMount = false,
27
28
  ...restProps
28
29
  }: LinkPreviewContentProps = $props();
@@ -33,6 +34,8 @@
33
34
  () => ref,
34
35
  (v) => (ref = v)
35
36
  ),
37
+ onInteractOutside: box.with(() => onInteractOutside),
38
+ onEscapeKeydown: box.with(() => onEscapeKeydown),
36
39
  });
37
40
 
38
41
  const floatingProps = $derived({
@@ -47,29 +50,14 @@
47
50
  });
48
51
 
49
52
  const mergedProps = $derived(mergeProps(restProps, floatingProps, contentState.props));
50
-
51
- function handleInteractOutside(e: PointerEvent) {
52
- onInteractOutside?.(e);
53
- if (e.defaultPrevented) return;
54
- contentState.root.handleClose();
55
- }
56
-
57
- function handleEscapeKeydown(e: KeyboardEvent) {
58
- onEscapeKeydown?.(e);
59
- if (e.defaultPrevented) return;
60
- contentState.root.handleClose();
61
- }
62
53
  </script>
63
54
 
64
55
  {#if forceMount}
65
56
  <PopperLayerForceMount
66
57
  {...mergedProps}
58
+ {...contentState.popperProps}
67
59
  enabled={contentState.root.opts.open.current}
68
60
  {id}
69
- onInteractOutside={handleInteractOutside}
70
- onEscapeKeydown={handleEscapeKeydown}
71
- onOpenAutoFocus={(e) => e.preventDefault()}
72
- onCloseAutoFocus={(e) => e.preventDefault()}
73
61
  trapFocus={false}
74
62
  loop={false}
75
63
  preventScroll={false}
@@ -93,12 +81,9 @@
93
81
  {:else if !forceMount}
94
82
  <PopperLayer
95
83
  {...mergedProps}
84
+ {...contentState.popperProps}
96
85
  present={contentState.root.opts.open.current}
97
86
  {id}
98
- onInteractOutside={handleInteractOutside}
99
- onEscapeKeydown={handleEscapeKeydown}
100
- onOpenAutoFocus={(e) => e.preventDefault()}
101
- onCloseAutoFocus={(e) => e.preventDefault()}
102
87
  trapFocus={false}
103
88
  loop={false}
104
89
  preventScroll={false}
@@ -45,7 +45,10 @@ declare class LinkPreviewTriggerState {
45
45
  readonly onpointerleave: (e: BitsPointerEvent) => void;
46
46
  };
47
47
  }
48
- type LinkPreviewContentStateProps = WithRefProps;
48
+ type LinkPreviewContentStateProps = WithRefProps & ReadableBoxedValues<{
49
+ onInteractOutside: (e: PointerEvent) => void;
50
+ onEscapeKeydown: (e: KeyboardEvent) => void;
51
+ }>;
49
52
  declare class LinkPreviewContentState {
50
53
  readonly opts: LinkPreviewContentStateProps;
51
54
  readonly root: LinkPreviewRootState;
@@ -53,6 +56,10 @@ declare class LinkPreviewContentState {
53
56
  onpointerdown(e: BitsPointerEvent): void;
54
57
  onpointerenter(e: BitsPointerEvent): void;
55
58
  onfocusout(e: BitsFocusEvent): void;
59
+ onInteractOutside: (e: PointerEvent) => void;
60
+ onEscapeKeydown: (e: KeyboardEvent) => void;
61
+ onOpenAutoFocus: (e: Event) => void;
62
+ onCloseAutoFocus: (e: Event) => void;
56
63
  snippetProps: {
57
64
  open: boolean;
58
65
  };
@@ -65,6 +72,12 @@ declare class LinkPreviewContentState {
65
72
  readonly onpointerenter: (e: BitsPointerEvent) => void;
66
73
  readonly onfocusout: (e: BitsFocusEvent) => void;
67
74
  };
75
+ popperProps: {
76
+ onInteractOutside: (e: PointerEvent) => void;
77
+ onEscapeKeydown: (e: KeyboardEvent) => void;
78
+ onOpenAutoFocus: (e: Event) => void;
79
+ onCloseAutoFocus: (e: Event) => void;
80
+ };
68
81
  }
69
82
  export declare function useLinkPreviewRoot(props: LinkPreviewRootStateProps): LinkPreviewRootState;
70
83
  export declare function useLinkPreviewTrigger(props: LinkPreviewTriggerStateProps): LinkPreviewTriggerState;
@@ -181,6 +181,24 @@ class LinkPreviewContentState {
181
181
  onfocusout(e) {
182
182
  e.preventDefault();
183
183
  }
184
+ onInteractOutside = (e) => {
185
+ this.opts.onInteractOutside.current(e);
186
+ if (e.defaultPrevented)
187
+ return;
188
+ this.root.handleClose();
189
+ };
190
+ onEscapeKeydown = (e) => {
191
+ this.opts.onEscapeKeydown.current?.(e);
192
+ if (e.defaultPrevented)
193
+ return;
194
+ this.root.handleClose();
195
+ };
196
+ onOpenAutoFocus = (e) => {
197
+ e.preventDefault();
198
+ };
199
+ onCloseAutoFocus = (e) => {
200
+ e.preventDefault();
201
+ };
184
202
  snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
185
203
  props = $derived.by(() => ({
186
204
  id: this.opts.id.current,
@@ -191,6 +209,12 @@ class LinkPreviewContentState {
191
209
  onpointerenter: this.onpointerenter,
192
210
  onfocusout: this.onfocusout,
193
211
  }));
212
+ popperProps = {
213
+ onInteractOutside: this.onInteractOutside,
214
+ onEscapeKeydown: this.onEscapeKeydown,
215
+ onOpenAutoFocus: this.onOpenAutoFocus,
216
+ onCloseAutoFocus: this.onCloseAutoFocus,
217
+ };
194
218
  }
195
219
  const LinkPreviewRootContext = new Context("LinkPreview.Root");
196
220
  export function useLinkPreviewRoot(props) {
@@ -54,6 +54,7 @@
54
54
  {#if forceMount}
55
55
  <PopperLayerForceMount
56
56
  {...mergedProps}
57
+ {...contentState.popperProps}
57
58
  enabled={contentState.parentMenu.opts.open.current}
58
59
  onInteractOutside={handleInteractOutside}
59
60
  onEscapeKeydown={handleEscapeKeydown}
@@ -83,6 +84,7 @@
83
84
  {:else if !forceMount}
84
85
  <PopperLayer
85
86
  {...mergedProps}
87
+ {...contentState.popperProps}
86
88
  present={contentState.parentMenu.opts.open.current}
87
89
  onInteractOutside={handleInteractOutside}
88
90
  onEscapeKeydown={handleEscapeKeydown}
@@ -54,6 +54,7 @@
54
54
  {#if forceMount}
55
55
  <PopperLayerForceMount
56
56
  {...mergedProps}
57
+ {...contentState.popperProps}
57
58
  enabled={contentState.parentMenu.opts.open.current}
58
59
  onInteractOutside={handleInteractOutside}
59
60
  onEscapeKeydown={handleEscapeKeydown}
@@ -84,6 +85,7 @@
84
85
  {:else if !forceMount}
85
86
  <PopperLayer
86
87
  {...mergedProps}
88
+ {...contentState.popperProps}
87
89
  present={contentState.parentMenu.opts.open.current}
88
90
  onInteractOutside={handleInteractOutside}
89
91
  onEscapeKeydown={handleEscapeKeydown}
@@ -74,12 +74,14 @@ declare class MenuContentState {
74
74
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
75
75
  readonly onblur: (e: BitsFocusEvent) => void;
76
76
  readonly onfocus: (_: BitsFocusEvent) => void;
77
- readonly onCloseAutoFocus: (e: Event) => void;
78
77
  readonly dir: Direction;
79
78
  readonly style: {
80
79
  readonly pointerEvents: "auto";
81
80
  };
82
81
  };
82
+ popperProps: {
83
+ onCloseAutoFocus: (e: Event) => void;
84
+ };
83
85
  }
84
86
  type MenuItemSharedStateProps = WithRefProps & ReadableBoxedValues<{
85
87
  disabled: boolean;
@@ -281,12 +281,14 @@ class MenuContentState {
281
281
  onkeydown: this.onkeydown,
282
282
  onblur: this.onblur,
283
283
  onfocus: this.onfocus,
284
- onCloseAutoFocus: (e) => this.onCloseAutoFocus(e),
285
284
  dir: this.parentMenu.root.opts.dir.current,
286
285
  style: {
287
286
  pointerEvents: "auto",
288
287
  },
289
288
  }));
289
+ popperProps = {
290
+ onCloseAutoFocus: (e) => this.onCloseAutoFocus(e),
291
+ };
290
292
  }
291
293
  class MenuItemSharedState {
292
294
  opts;
@@ -33,12 +33,4 @@
33
33
  const mergedProps = $derived(mergeProps(restProps, contentState.props));
34
34
  </script>
35
35
 
36
- <MenuContentStatic
37
- bind:ref
38
- {...mergedProps}
39
- preventScroll={false}
40
- onInteractOutside={contentState.onInteractOutside}
41
- onFocusOutside={contentState.onFocusOutside}
42
- onCloseAutoFocus={contentState.onCloseAutoFocus}
43
- onOpenAutoFocus={contentState.onOpenAutoFocus}
44
- />
36
+ <MenuContentStatic bind:ref {...mergedProps} {...contentState.popperProps} preventScroll={false} />
@@ -33,12 +33,4 @@
33
33
  const mergedProps = $derived(mergeProps(restProps, contentState.props));
34
34
  </script>
35
35
 
36
- <MenuContent
37
- bind:ref
38
- {...mergedProps}
39
- preventScroll={false}
40
- onInteractOutside={contentState.onInteractOutside}
41
- onFocusOutside={contentState.onFocusOutside}
42
- onCloseAutoFocus={contentState.onCloseAutoFocus}
43
- onOpenAutoFocus={contentState.onOpenAutoFocus}
44
- />
36
+ <MenuContent bind:ref {...mergedProps} {...contentState.popperProps} preventScroll={false} />
@@ -103,10 +103,10 @@ declare class MenubarContentState {
103
103
  hasInteractedOutside: boolean;
104
104
  focusScopeContext: FocusScopeContextValue;
105
105
  constructor(opts: MenubarContentStateProps, menu: MenubarMenuState);
106
- onCloseAutoFocus(e: Event): void;
107
- onFocusOutside(e: FocusEvent): void;
108
- onInteractOutside(e: PointerEvent): void;
109
- onOpenAutoFocus(e: Event): void;
106
+ onCloseAutoFocus: (e: Event) => void;
107
+ onFocusOutside: (e: FocusEvent) => void;
108
+ onInteractOutside: (e: PointerEvent) => void;
109
+ onOpenAutoFocus: (e: Event) => void;
110
110
  onkeydown(e: BitsKeyboardEvent): void;
111
111
  props: {
112
112
  readonly id: string;
@@ -121,6 +121,12 @@ declare class MenubarContentState {
121
121
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
122
122
  readonly "data-menu-content": "";
123
123
  };
124
+ popperProps: {
125
+ onCloseAutoFocus: (e: Event) => void;
126
+ onFocusOutside: (e: FocusEvent) => void;
127
+ onInteractOutside: (e: PointerEvent) => void;
128
+ onOpenAutoFocus: (e: Event) => void;
129
+ };
124
130
  }
125
131
  export declare function useMenubarRoot(props: MenubarRootStateProps): MenubarRootState;
126
132
  export declare function useMenubarMenu(props: MenubarMenuStateProps): MenubarMenuState;
@@ -202,10 +202,6 @@ class MenubarContentState {
202
202
  this.menu = menu;
203
203
  this.root = menu.root;
204
204
  this.focusScopeContext = FocusScopeContext.get();
205
- this.onCloseAutoFocus = this.onCloseAutoFocus.bind(this);
206
- this.onFocusOutside = this.onFocusOutside.bind(this);
207
- this.onInteractOutside = this.onInteractOutside.bind(this);
208
- this.onOpenAutoFocus = this.onOpenAutoFocus.bind(this);
209
205
  this.onkeydown = this.onkeydown.bind(this);
210
206
  useRefById({
211
207
  ...opts,
@@ -215,7 +211,7 @@ class MenubarContentState {
215
211
  deps: () => this.menu.open,
216
212
  });
217
213
  }
218
- onCloseAutoFocus(e) {
214
+ onCloseAutoFocus = (e) => {
219
215
  this.opts.onCloseAutoFocus.current(e);
220
216
  if (e.defaultPrevented)
221
217
  return;
@@ -226,8 +222,8 @@ class MenubarContentState {
226
222
  }
227
223
  this.hasInteractedOutside = false;
228
224
  e.preventDefault();
229
- }
230
- onFocusOutside(e) {
225
+ };
226
+ onFocusOutside = (e) => {
231
227
  const target = e.target;
232
228
  const isMenubarTrigger = this.root
233
229
  .getTriggers()
@@ -235,17 +231,17 @@ class MenubarContentState {
235
231
  if (isMenubarTrigger)
236
232
  e.preventDefault();
237
233
  this.opts.onFocusOutside.current(e);
238
- }
239
- onInteractOutside(e) {
234
+ };
235
+ onInteractOutside = (e) => {
240
236
  this.hasInteractedOutside = true;
241
237
  this.opts.onInteractOutside.current(e);
242
- }
243
- onOpenAutoFocus(e) {
238
+ };
239
+ onOpenAutoFocus = (e) => {
244
240
  this.opts.onOpenAutoFocus.current(e);
245
241
  if (e.defaultPrevented)
246
242
  return;
247
243
  afterTick(() => this.opts.ref.current?.focus());
248
- }
244
+ };
249
245
  onkeydown(e) {
250
246
  if (e.key !== kbd.ARROW_LEFT && e.key !== kbd.ARROW_RIGHT)
251
247
  return;
@@ -290,6 +286,12 @@ class MenubarContentState {
290
286
  onkeydown: this.onkeydown,
291
287
  "data-menu-content": "",
292
288
  }));
289
+ popperProps = {
290
+ onCloseAutoFocus: this.onCloseAutoFocus,
291
+ onFocusOutside: this.onFocusOutside,
292
+ onInteractOutside: this.onInteractOutside,
293
+ onOpenAutoFocus: this.onOpenAutoFocus,
294
+ };
293
295
  }
294
296
  const MenubarRootContext = new Context("Menubar.Root");
295
297
  const MenubarMenuContext = new Context("Menubar.Menu");
@@ -19,7 +19,6 @@
19
19
  onInteractOutside = noop,
20
20
  trapFocus = true,
21
21
  preventScroll = false,
22
-
23
22
  ...restProps
24
23
  }: PopoverContentStaticProps = $props();
25
24
 
@@ -40,12 +39,10 @@
40
39
  {#if forceMount}
41
40
  <PopperLayerForceMount
42
41
  {...mergedProps}
42
+ {...contentState.popperProps}
43
43
  isStatic
44
44
  enabled={contentState.root.opts.open.current}
45
45
  {id}
46
- onInteractOutside={contentState.handleInteractOutside}
47
- onEscapeKeydown={contentState.handleEscapeKeydown}
48
- onCloseAutoFocus={contentState.handleCloseAutoFocus}
49
46
  {trapFocus}
50
47
  {preventScroll}
51
48
  loop
@@ -67,12 +64,10 @@
67
64
  {:else if !forceMount}
68
65
  <PopperLayer
69
66
  {...mergedProps}
67
+ {...contentState.popperProps}
70
68
  isStatic
71
69
  present={contentState.root.opts.open.current}
72
70
  {id}
73
- onInteractOutside={contentState.handleInteractOutside}
74
- onEscapeKeydown={contentState.handleEscapeKeydown}
75
- onCloseAutoFocus={contentState.handleCloseAutoFocus}
76
71
  {trapFocus}
77
72
  {preventScroll}
78
73
  loop
@@ -39,11 +39,9 @@
39
39
  {#if forceMount}
40
40
  <PopperLayerForceMount
41
41
  {...mergedProps}
42
+ {...contentState.popperProps}
42
43
  enabled={contentState.root.opts.open.current}
43
44
  {id}
44
- onInteractOutside={contentState.handleInteractOutside}
45
- onEscapeKeydown={contentState.handleEscapeKeydown}
46
- onCloseAutoFocus={contentState.handleCloseAutoFocus}
47
45
  {trapFocus}
48
46
  {preventScroll}
49
47
  loop
@@ -67,11 +65,9 @@
67
65
  {:else if !forceMount}
68
66
  <PopperLayer
69
67
  {...mergedProps}
68
+ {...contentState.popperProps}
70
69
  present={contentState.root.opts.open.current}
71
70
  {id}
72
- onInteractOutside={contentState.handleInteractOutside}
73
- onEscapeKeydown={contentState.handleEscapeKeydown}
74
- onCloseAutoFocus={contentState.handleCloseAutoFocus}
75
71
  {trapFocus}
76
72
  {preventScroll}
77
73
  loop
@@ -45,9 +45,9 @@ declare class PopoverContentState {
45
45
  readonly opts: PopoverContentStateProps;
46
46
  readonly root: PopoverRootState;
47
47
  constructor(opts: PopoverContentStateProps, root: PopoverRootState);
48
- handleInteractOutside(e: PointerEvent): void;
49
- handleEscapeKeydown(e: KeyboardEvent): void;
50
- handleCloseAutoFocus(e: Event): void;
48
+ onInteractOutside: (e: PointerEvent) => void;
49
+ onEscapeKeydown: (e: KeyboardEvent) => void;
50
+ onCloseAutoFocus: (e: Event) => void;
51
51
  snippetProps: {
52
52
  open: boolean;
53
53
  };
@@ -60,6 +60,11 @@ declare class PopoverContentState {
60
60
  readonly pointerEvents: "auto";
61
61
  };
62
62
  };
63
+ popperProps: {
64
+ onInteractOutside: (e: PointerEvent) => void;
65
+ onEscapeKeydown: (e: KeyboardEvent) => void;
66
+ onCloseAutoFocus: (e: Event) => void;
67
+ };
63
68
  }
64
69
  type PopoverCloseStateProps = WithRefProps;
65
70
  declare class PopoverCloseState {
@@ -92,11 +92,8 @@ class PopoverContentState {
92
92
  this.root.contentNode = node;
93
93
  },
94
94
  });
95
- this.handleInteractOutside = this.handleInteractOutside.bind(this);
96
- this.handleEscapeKeydown = this.handleEscapeKeydown.bind(this);
97
- this.handleCloseAutoFocus = this.handleCloseAutoFocus.bind(this);
98
95
  }
99
- handleInteractOutside(e) {
96
+ onInteractOutside = (e) => {
100
97
  this.opts.onInteractOutside.current(e);
101
98
  if (e.defaultPrevented)
102
99
  return;
@@ -106,20 +103,20 @@ class PopoverContentState {
106
103
  if (closestTrigger === this.root.triggerNode)
107
104
  return;
108
105
  this.root.handleClose();
109
- }
110
- handleEscapeKeydown(e) {
106
+ };
107
+ onEscapeKeydown = (e) => {
111
108
  this.opts.onEscapeKeydown.current(e);
112
109
  if (e.defaultPrevented)
113
110
  return;
114
111
  this.root.handleClose();
115
- }
116
- handleCloseAutoFocus(e) {
112
+ };
113
+ onCloseAutoFocus = (e) => {
117
114
  this.opts.onCloseAutoFocus.current(e);
118
115
  if (e.defaultPrevented)
119
116
  return;
120
117
  e.preventDefault();
121
118
  this.root.triggerNode?.focus();
122
- }
119
+ };
123
120
  snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
124
121
  props = $derived.by(() => ({
125
122
  id: this.opts.id.current,
@@ -130,6 +127,11 @@ class PopoverContentState {
130
127
  pointerEvents: "auto",
131
128
  },
132
129
  }));
130
+ popperProps = {
131
+ onInteractOutside: this.onInteractOutside,
132
+ onEscapeKeydown: this.onEscapeKeydown,
133
+ onCloseAutoFocus: this.onCloseAutoFocus,
134
+ };
133
135
  }
134
136
  class PopoverCloseState {
135
137
  opts;
@@ -9,6 +9,7 @@
9
9
  children,
10
10
  value = 0,
11
11
  max = 100,
12
+ min = 0,
12
13
  id = useId(),
13
14
  ref = $bindable(null),
14
15
  ...restProps
@@ -17,6 +18,7 @@
17
18
  const rootState = useProgressRootState({
18
19
  value: box.with(() => value),
19
20
  max: box.with(() => max),
21
+ min: box.with(() => min),
20
22
  id: box.with(() => id),
21
23
  ref: box.with(
22
24
  () => ref,
@@ -3,20 +3,22 @@ import type { WithRefProps } from "../../internal/types.js";
3
3
  type ProgressRootStateProps = WithRefProps<ReadableBoxedValues<{
4
4
  value: number | null;
5
5
  max: number;
6
+ min: number;
6
7
  }>>;
7
8
  declare class ProgressRootState {
8
9
  readonly opts: ProgressRootStateProps;
9
10
  constructor(opts: ProgressRootStateProps);
10
11
  props: {
11
- readonly role: "meter";
12
+ readonly role: "progressbar";
12
13
  readonly value: number | null;
13
- readonly max: number;
14
- readonly "aria-valuemin": 0;
14
+ readonly "aria-valuemin": number;
15
15
  readonly "aria-valuemax": number;
16
- readonly "aria-valuenow": number | null;
17
- readonly "data-value": number | null;
16
+ readonly "aria-valuenow": number | undefined;
17
+ readonly "data-value": number | undefined;
18
18
  readonly "data-state": "indeterminate" | "loading" | "loaded";
19
19
  readonly "data-max": number;
20
+ readonly "data-min": number;
21
+ readonly "data-indeterminate": "" | undefined;
20
22
  readonly "data-progress-root": "";
21
23
  };
22
24
  }
@@ -7,15 +7,16 @@ class ProgressRootState {
7
7
  useRefById(opts);
8
8
  }
9
9
  props = $derived.by(() => ({
10
- role: "meter",
10
+ role: "progressbar",
11
11
  value: this.opts.value.current,
12
- max: this.opts.max.current,
13
- "aria-valuemin": 0,
12
+ "aria-valuemin": this.opts.min.current,
14
13
  "aria-valuemax": this.opts.max.current,
15
- "aria-valuenow": this.opts.value.current,
16
- "data-value": this.opts.value.current,
14
+ "aria-valuenow": this.opts.value.current === null ? undefined : this.opts.value.current,
15
+ "data-value": this.opts.value.current === null ? undefined : this.opts.value.current,
17
16
  "data-state": getProgressDataState(this.opts.value.current, this.opts.max.current),
18
17
  "data-max": this.opts.max.current,
18
+ "data-min": this.opts.min.current,
19
+ "data-indeterminate": this.opts.value.current === null ? "" : undefined,
19
20
  [ROOT_ATTR]: "",
20
21
  }));
21
22
  }
@@ -4,12 +4,21 @@ export type ProgressRootPropsWithoutHTML = WithChild<{
4
4
  /**
5
5
  * The current value of the progress bar.
6
6
  * If `null`, the progress bar will be in an indeterminate state.
7
+ *
8
+ * @default 0
7
9
  */
8
10
  value?: number | null;
9
11
  /**
10
- * The maximum value of the progress bar. Used to calculate the percentage
11
- * of the progress bar along with the `value` prop.
12
+ * The maximum value of the progress bar.
13
+ *
14
+ * @default 100
12
15
  */
13
16
  max?: number;
17
+ /**
18
+ * The minimum value of the progress bar.
19
+ *
20
+ * @default 0
21
+ */
22
+ min?: number;
14
23
  }>;
15
24
  export type ProgressRootProps = ProgressRootPropsWithoutHTML & Without<BitsPrimitiveDivAttributes, ProgressRootPropsWithoutHTML>;
@@ -15,6 +15,7 @@
15
15
  onEscapeKeydown = noop,
16
16
  children,
17
17
  child,
18
+ preventScroll = false,
18
19
  ...restProps
19
20
  }: SelectContentStaticProps = $props();
20
21
 
@@ -24,39 +25,21 @@
24
25
  () => ref,
25
26
  (v) => (ref = v)
26
27
  ),
28
+ onInteractOutside: box.with(() => onInteractOutside),
29
+ onEscapeKeydown: box.with(() => onEscapeKeydown),
27
30
  });
28
31
 
29
32
  const mergedProps = $derived(mergeProps(restProps, contentState.props));
30
-
31
- function handleInteractOutside(e: PointerEvent) {
32
- contentState.handleInteractOutside(e);
33
- if (e.defaultPrevented) return;
34
- onInteractOutside(e);
35
- if (e.defaultPrevented) return;
36
- contentState.root.handleClose();
37
- }
38
-
39
- function handleEscapeKeydown(e: KeyboardEvent) {
40
- onEscapeKeydown(e);
41
- if (e.defaultPrevented) return;
42
- contentState.root.handleClose();
43
- }
44
33
  </script>
45
34
 
46
35
  {#if forceMount}
47
36
  <PopperLayerForceMount
48
37
  {...mergedProps}
38
+ {...contentState.popperProps}
49
39
  isStatic
50
40
  enabled={contentState.root.opts.open.current}
51
41
  {id}
52
- onInteractOutside={handleInteractOutside}
53
- onEscapeKeydown={handleEscapeKeydown}
54
- onOpenAutoFocus={(e) => e.preventDefault()}
55
- onCloseAutoFocus={(e) => e.preventDefault()}
56
- trapFocus={false}
57
- loop={false}
58
- preventScroll={false}
59
- onPlaced={() => (contentState.isPositioned = true)}
42
+ {preventScroll}
60
43
  forceMount={true}
61
44
  >
62
45
  {#snippet popper({ props })}
@@ -73,17 +56,11 @@
73
56
  {:else if !forceMount}
74
57
  <PopperLayer
75
58
  {...mergedProps}
59
+ {...contentState.popperProps}
76
60
  isStatic
77
61
  present={contentState.root.opts.open.current}
78
62
  {id}
79
- onInteractOutside={handleInteractOutside}
80
- onEscapeKeydown={handleEscapeKeydown}
81
- onOpenAutoFocus={(e) => e.preventDefault()}
82
- onCloseAutoFocus={(e) => e.preventDefault()}
83
- trapFocus={false}
84
- loop={false}
85
- preventScroll={false}
86
- onPlaced={() => (contentState.isPositioned = true)}
63
+ {preventScroll}
87
64
  forceMount={false}
88
65
  >
89
66
  {#snippet popper({ props })}
@@ -26,37 +26,20 @@
26
26
  () => ref,
27
27
  (v) => (ref = v)
28
28
  ),
29
+ onInteractOutside: box.with(() => onInteractOutside),
30
+ onEscapeKeydown: box.with(() => onEscapeKeydown),
29
31
  });
30
32
 
31
33
  const mergedProps = $derived(mergeProps(restProps, contentState.props));
32
-
33
- function handleInteractOutside(e: PointerEvent) {
34
- contentState.handleInteractOutside(e);
35
- if (e.defaultPrevented) return;
36
- onInteractOutside(e);
37
- if (e.defaultPrevented) return;
38
- contentState.root.handleClose();
39
- }
40
-
41
- function handleEscapeKeydown(e: KeyboardEvent) {
42
- onEscapeKeydown(e);
43
- if (e.defaultPrevented) return;
44
- contentState.root.handleClose();
45
- }
46
34
  </script>
47
35
 
48
36
  {#if forceMount}
49
37
  <PopperLayerForceMount
50
38
  {...mergedProps}
39
+ {...contentState.popperProps}
51
40
  {side}
52
41
  enabled={contentState.root.opts.open.current}
53
42
  {id}
54
- onInteractOutside={handleInteractOutside}
55
- onEscapeKeydown={handleEscapeKeydown}
56
- onOpenAutoFocus={(e) => e.preventDefault()}
57
- onCloseAutoFocus={(e) => e.preventDefault()}
58
- trapFocus={false}
59
- loop={false}
60
43
  {preventScroll}
61
44
  onPlaced={() => (contentState.isPositioned = true)}
62
45
  forceMount={true}
@@ -77,17 +60,11 @@
77
60
  {:else if !forceMount}
78
61
  <PopperLayer
79
62
  {...mergedProps}
63
+ {...contentState.popperProps}
80
64
  {side}
81
65
  present={contentState.root.opts.open.current}
82
66
  {id}
83
- onInteractOutside={handleInteractOutside}
84
- onEscapeKeydown={handleEscapeKeydown}
85
- onOpenAutoFocus={(e) => e.preventDefault()}
86
- onCloseAutoFocus={(e) => e.preventDefault()}
87
- trapFocus={false}
88
- loop={false}
89
67
  {preventScroll}
90
- onPlaced={() => (contentState.isPositioned = true)}
91
68
  forceMount={false}
92
69
  >
93
70
  {#snippet popper({ props, wrapperProps })}
@@ -151,7 +151,10 @@ declare class SelectTriggerState {
151
151
  readonly onpointerup: (e: BitsPointerEvent) => void;
152
152
  };
153
153
  }
154
- type SelectContentStateProps = WithRefProps;
154
+ type SelectContentStateProps = WithRefProps & ReadableBoxedValues<{
155
+ onInteractOutside: (e: PointerEvent) => void;
156
+ onEscapeKeydown: (e: KeyboardEvent) => void;
157
+ }>;
155
158
  declare class SelectContentState {
156
159
  #private;
157
160
  readonly opts: SelectContentStateProps;
@@ -160,7 +163,10 @@ declare class SelectContentState {
160
163
  isPositioned: boolean;
161
164
  constructor(opts: SelectContentStateProps, root: SelectRootState);
162
165
  onpointermove(_: BitsPointerEvent): void;
163
- handleInteractOutside(e: PointerEvent): void;
166
+ onInteractOutside: (e: PointerEvent) => void;
167
+ onEscapeKeydown: (e: KeyboardEvent) => void;
168
+ onOpenAutoFocus: (e: Event) => void;
169
+ onCloseAutoFocus: (e: Event) => void;
164
170
  snippetProps: {
165
171
  open: boolean;
166
172
  };
@@ -184,6 +190,15 @@ declare class SelectContentState {
184
190
  };
185
191
  readonly onpointermove: (_: BitsPointerEvent) => void;
186
192
  };
193
+ popperProps: {
194
+ onInteractOutside: (e: PointerEvent) => void;
195
+ onEscapeKeydown: (e: KeyboardEvent) => void;
196
+ onOpenAutoFocus: (e: Event) => void;
197
+ onCloseAutoFocus: (e: Event) => void;
198
+ trapFocus: boolean;
199
+ loop: boolean;
200
+ onPlaced: () => void;
201
+ };
187
202
  }
188
203
  type SelectItemStateProps = WithRefProps<ReadableBoxedValues<{
189
204
  value: string;
@@ -618,7 +618,6 @@ class SelectContentState {
618
618
  this.isPositioned = false;
619
619
  });
620
620
  this.onpointermove = this.onpointermove.bind(this);
621
- this.handleInteractOutside = this.handleInteractOutside.bind(this);
622
621
  }
623
622
  onpointermove(_) {
624
623
  this.root.isUsingKeyboard = false;
@@ -633,11 +632,28 @@ class SelectContentState {
633
632
  [`${prefix}-anchor-height`]: "var(--bits-floating-anchor-height)",
634
633
  };
635
634
  });
636
- handleInteractOutside(e) {
635
+ onInteractOutside = (e) => {
637
636
  if (e.target === this.root.triggerNode || e.target === this.root.inputNode) {
638
637
  e.preventDefault();
638
+ return;
639
639
  }
640
- }
640
+ this.opts.onInteractOutside.current(e);
641
+ if (e.defaultPrevented)
642
+ return;
643
+ this.root.handleClose();
644
+ };
645
+ onEscapeKeydown = (e) => {
646
+ this.opts.onEscapeKeydown.current(e);
647
+ if (e.defaultPrevented)
648
+ return;
649
+ this.root.handleClose();
650
+ };
651
+ onOpenAutoFocus = (e) => {
652
+ e.preventDefault();
653
+ };
654
+ onCloseAutoFocus = (e) => {
655
+ e.preventDefault();
656
+ };
641
657
  snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
642
658
  props = $derived.by(() => ({
643
659
  id: this.opts.id.current,
@@ -654,6 +670,17 @@ class SelectContentState {
654
670
  },
655
671
  onpointermove: this.onpointermove,
656
672
  }));
673
+ popperProps = {
674
+ onInteractOutside: this.onInteractOutside,
675
+ onEscapeKeydown: this.onEscapeKeydown,
676
+ onOpenAutoFocus: this.onOpenAutoFocus,
677
+ onCloseAutoFocus: this.onCloseAutoFocus,
678
+ trapFocus: false,
679
+ loop: false,
680
+ onPlaced: () => {
681
+ this.isPositioned = true;
682
+ },
683
+ };
657
684
  }
658
685
  class SelectItemState {
659
686
  opts;
@@ -123,9 +123,9 @@ export type _SharedSelectContentProps = {
123
123
  */
124
124
  loop?: boolean;
125
125
  };
126
- export type SelectContentPropsWithoutHTML = Expand<WithChildNoChildrenSnippetProps<Omit<PopperLayerProps, "content" | "onOpenAutoFocus" | "trapFocus"> & _SharedSelectContentProps, FloatingContentSnippetProps>>;
126
+ export type SelectContentPropsWithoutHTML = Expand<WithChildNoChildrenSnippetProps<Omit<PopperLayerProps, "content" | "onOpenAutoFocus" | "trapFocus" | "onCloseAutoFocus"> & _SharedSelectContentProps, FloatingContentSnippetProps>>;
127
127
  export type SelectContentProps = SelectContentPropsWithoutHTML & Without<BitsPrimitiveDivAttributes, SelectContentPropsWithoutHTML>;
128
- export type SelectContentStaticPropsWithoutHTML = Expand<WithChildNoChildrenSnippetProps<Omit<PopperLayerStaticProps, "content" | "onOpenAutoFocus" | "trapFocus"> & _SharedSelectContentProps, StaticContentSnippetProps>>;
128
+ export type SelectContentStaticPropsWithoutHTML = Expand<WithChildNoChildrenSnippetProps<Omit<PopperLayerStaticProps, "content" | "onOpenAutoFocus" | "onCloseAutoFocus" | "trapFocus"> & _SharedSelectContentProps, StaticContentSnippetProps>>;
129
129
  export type SelectContentStaticProps = SelectContentStaticPropsWithoutHTML & Without<BitsPrimitiveDivAttributes, SelectContentStaticPropsWithoutHTML>;
130
130
  export type SelectTriggerPropsWithoutHTML = WithChild;
131
131
  export type SelectTriggerProps = SelectTriggerPropsWithoutHTML & Without<BitsPrimitiveButtonAttributes, SelectTriggerPropsWithoutHTML>;
@@ -6,15 +6,15 @@
6
6
  import PopperLayer from "../../utilities/popper-layer/popper-layer.svelte";
7
7
  import { getFloatingContentCSSVars } from "../../../internal/floating-svelte/floating-utils.svelte.js";
8
8
  import PopperLayerForceMount from "../../utilities/popper-layer/popper-layer-force-mount.svelte";
9
+ import { noop } from "../../../internal/noop.js";
9
10
 
10
11
  let {
11
12
  children,
12
13
  child,
13
14
  id = useId(),
14
15
  ref = $bindable(null),
15
-
16
- onInteractOutside,
17
- onEscapeKeydown,
16
+ onInteractOutside = noop,
17
+ onEscapeKeydown = noop,
18
18
  forceMount = false,
19
19
  ...restProps
20
20
  }: TooltipContentStaticProps = $props();
@@ -25,33 +25,20 @@
25
25
  () => ref,
26
26
  (v) => (ref = v)
27
27
  ),
28
+ onInteractOutside: box.with(() => onInteractOutside),
29
+ onEscapeKeydown: box.with(() => onEscapeKeydown),
28
30
  });
29
31
 
30
32
  const mergedProps = $derived(mergeProps(restProps, contentState.props));
31
-
32
- function handleInteractOutside(e: PointerEvent) {
33
- onInteractOutside?.(e);
34
- if (e.defaultPrevented) return;
35
- contentState.root.handleClose();
36
- }
37
-
38
- function handleEscapeKeydown(e: KeyboardEvent) {
39
- onEscapeKeydown?.(e);
40
- if (e.defaultPrevented) return;
41
- contentState.root.handleClose();
42
- }
43
33
  </script>
44
34
 
45
35
  {#if forceMount}
46
36
  <PopperLayerForceMount
47
37
  {...mergedProps}
38
+ {...contentState.popperProps}
48
39
  isStatic
49
40
  enabled={contentState.root.opts.open.current}
50
41
  {id}
51
- onInteractOutside={handleInteractOutside}
52
- onEscapeKeydown={handleEscapeKeydown}
53
- onOpenAutoFocus={(e) => e.preventDefault()}
54
- onCloseAutoFocus={(e) => e.preventDefault()}
55
42
  trapFocus={false}
56
43
  loop={false}
57
44
  preventScroll={false}
@@ -73,13 +60,10 @@
73
60
  {:else if !forceMount}
74
61
  <PopperLayer
75
62
  {...mergedProps}
63
+ {...contentState.popperProps}
76
64
  isStatic
77
65
  present={contentState.root.opts.open.current}
78
66
  {id}
79
- onInteractOutside={handleInteractOutside}
80
- onEscapeKeydown={handleEscapeKeydown}
81
- onOpenAutoFocus={(e) => e.preventDefault()}
82
- onCloseAutoFocus={(e) => e.preventDefault()}
83
67
  trapFocus={false}
84
68
  loop={false}
85
69
  preventScroll={false}
@@ -6,6 +6,7 @@
6
6
  import PopperLayer from "../../utilities/popper-layer/popper-layer.svelte";
7
7
  import { getFloatingContentCSSVars } from "../../../internal/floating-svelte/floating-utils.svelte.js";
8
8
  import PopperLayerForceMount from "../../utilities/popper-layer/popper-layer-force-mount.svelte";
9
+ import { noop } from "../../../internal/noop.js";
9
10
 
10
11
  let {
11
12
  children,
@@ -20,8 +21,8 @@
20
21
  sticky = "partial",
21
22
  hideWhenDetached = false,
22
23
  collisionPadding = 0,
23
- onInteractOutside,
24
- onEscapeKeydown,
24
+ onInteractOutside = noop,
25
+ onEscapeKeydown = noop,
25
26
  forceMount = false,
26
27
  ...restProps
27
28
  }: TooltipContentProps = $props();
@@ -32,6 +33,8 @@
32
33
  () => ref,
33
34
  (v) => (ref = v)
34
35
  ),
36
+ onInteractOutside: box.with(() => onInteractOutside),
37
+ onEscapeKeydown: box.with(() => onEscapeKeydown),
35
38
  });
36
39
 
37
40
  const floatingProps = $derived({
@@ -46,29 +49,14 @@
46
49
  });
47
50
 
48
51
  const mergedProps = $derived(mergeProps(restProps, floatingProps, contentState.props));
49
-
50
- function handleInteractOutside(e: PointerEvent) {
51
- onInteractOutside?.(e);
52
- if (e.defaultPrevented) return;
53
- contentState.root.handleClose();
54
- }
55
-
56
- function handleEscapeKeydown(e: KeyboardEvent) {
57
- onEscapeKeydown?.(e);
58
- if (e.defaultPrevented) return;
59
- contentState.root.handleClose();
60
- }
61
52
  </script>
62
53
 
63
54
  {#if forceMount}
64
55
  <PopperLayerForceMount
65
56
  {...mergedProps}
57
+ {...contentState.popperProps}
66
58
  enabled={contentState.root.opts.open.current}
67
59
  {id}
68
- onInteractOutside={handleInteractOutside}
69
- onEscapeKeydown={handleEscapeKeydown}
70
- onOpenAutoFocus={(e) => e.preventDefault()}
71
- onCloseAutoFocus={(e) => e.preventDefault()}
72
60
  trapFocus={false}
73
61
  loop={false}
74
62
  preventScroll={false}
@@ -92,12 +80,9 @@
92
80
  {:else if !forceMount}
93
81
  <PopperLayer
94
82
  {...mergedProps}
83
+ {...contentState.popperProps}
95
84
  present={contentState.root.opts.open.current}
96
85
  {id}
97
- onInteractOutside={handleInteractOutside}
98
- onEscapeKeydown={handleEscapeKeydown}
99
- onOpenAutoFocus={(e) => e.preventDefault()}
100
- onCloseAutoFocus={(e) => e.preventDefault()}
101
86
  trapFocus={false}
102
87
  loop={false}
103
88
  preventScroll={false}
@@ -75,11 +75,18 @@ declare class TooltipTriggerState {
75
75
  onclick: () => void;
76
76
  };
77
77
  }
78
- type TooltipContentStateProps = WithRefProps;
78
+ type TooltipContentStateProps = WithRefProps & ReadableBoxedValues<{
79
+ onInteractOutside: (e: PointerEvent) => void;
80
+ onEscapeKeydown: (e: KeyboardEvent) => void;
81
+ }>;
79
82
  declare class TooltipContentState {
80
83
  readonly opts: TooltipContentStateProps;
81
84
  readonly root: TooltipRootState;
82
85
  constructor(opts: TooltipContentStateProps, root: TooltipRootState);
86
+ onInteractOutside: (e: PointerEvent) => void;
87
+ onEscapeKeydown: (e: KeyboardEvent) => void;
88
+ onOpenAutoFocus: (e: Event) => void;
89
+ onCloseAutoFocus: (e: Event) => void;
83
90
  snippetProps: {
84
91
  open: boolean;
85
92
  };
@@ -93,6 +100,12 @@ declare class TooltipContentState {
93
100
  };
94
101
  readonly "data-tooltip-content": "";
95
102
  };
103
+ popperProps: {
104
+ onInteractOutside: (e: PointerEvent) => void;
105
+ onEscapeKeydown: (e: KeyboardEvent) => void;
106
+ onOpenAutoFocus: (e: Event) => void;
107
+ onCloseAutoFocus: (e: Event) => void;
108
+ };
96
109
  }
97
110
  export declare function useTooltipProvider(props: TooltipProviderStateProps): TooltipProviderState;
98
111
  export declare function useTooltipRoot(props: TooltipRootStateProps): TooltipRootState;
@@ -2,7 +2,7 @@ import { box, executeCallbacks, onMountEffect, useRefById } from "svelte-toolbel
2
2
  import { on } from "svelte/events";
3
3
  import { Context, watch } from "runed";
4
4
  import { useTimeoutFn } from "../../internal/use-timeout-fn.svelte.js";
5
- import { isFocusVisible } from "../../internal/is.js";
5
+ import { isElement, isFocusVisible } from "../../internal/is.js";
6
6
  import { useGraceArea } from "../../internal/use-grace-area.svelte.js";
7
7
  import { getDataDisabled } from "../../internal/attrs.js";
8
8
  import { CustomEventDispatcher } from "../../internal/events.js";
@@ -224,6 +224,30 @@ class TooltipContentState {
224
224
  }
225
225
  }), TooltipOpenEvent.listen(window, this.root.handleClose)));
226
226
  }
227
+ onInteractOutside = (e) => {
228
+ if (isElement(e.target) &&
229
+ this.root.triggerNode?.contains(e.target) &&
230
+ this.root.disableCloseOnTriggerClick) {
231
+ e.preventDefault();
232
+ return;
233
+ }
234
+ this.opts.onInteractOutside.current(e);
235
+ if (e.defaultPrevented)
236
+ return;
237
+ this.root.handleClose();
238
+ };
239
+ onEscapeKeydown = (e) => {
240
+ this.opts.onEscapeKeydown.current?.(e);
241
+ if (e.defaultPrevented)
242
+ return;
243
+ this.root.handleClose();
244
+ };
245
+ onOpenAutoFocus = (e) => {
246
+ e.preventDefault();
247
+ };
248
+ onCloseAutoFocus = (e) => {
249
+ e.preventDefault();
250
+ };
227
251
  snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
228
252
  props = $derived.by(() => ({
229
253
  id: this.opts.id.current,
@@ -235,6 +259,12 @@ class TooltipContentState {
235
259
  },
236
260
  [TOOLTIP_CONTENT_ATTR]: "",
237
261
  }));
262
+ popperProps = {
263
+ onInteractOutside: this.onInteractOutside,
264
+ onEscapeKeydown: this.onEscapeKeydown,
265
+ onOpenAutoFocus: this.onOpenAutoFocus,
266
+ onCloseAutoFocus: this.onCloseAutoFocus,
267
+ };
238
268
  }
239
269
  //
240
270
  // CONTEXT METHODS
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bits-ui",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "license": "MIT",
5
5
  "repository": "github:huntabyte/bits-ui",
6
6
  "funding": "https://github.com/sponsors/huntabyte",