bits-ui 1.1.0 → 1.2.1

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 (38) 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/date-range-field/date-range-field.svelte.d.ts +0 -7
  4. package/dist/bits/date-range-field/date-range-field.svelte.js +58 -52
  5. package/dist/bits/dialog/dialog.svelte.d.ts +1 -3
  6. package/dist/bits/dialog/dialog.svelte.js +0 -14
  7. package/dist/bits/dropdown-menu/components/dropdown-menu-content-static.svelte +2 -0
  8. package/dist/bits/dropdown-menu/components/dropdown-menu-content.svelte +2 -0
  9. package/dist/bits/link-preview/components/link-preview-content-static.svelte +7 -22
  10. package/dist/bits/link-preview/components/link-preview-content.svelte +7 -22
  11. package/dist/bits/link-preview/link-preview.svelte.d.ts +14 -1
  12. package/dist/bits/link-preview/link-preview.svelte.js +24 -0
  13. package/dist/bits/menu/components/menu-content-static.svelte +2 -0
  14. package/dist/bits/menu/components/menu-content.svelte +2 -0
  15. package/dist/bits/menu/menu.svelte.d.ts +3 -1
  16. package/dist/bits/menu/menu.svelte.js +3 -1
  17. package/dist/bits/menubar/components/menubar-content-static.svelte +1 -9
  18. package/dist/bits/menubar/components/menubar-content.svelte +1 -9
  19. package/dist/bits/menubar/menubar.svelte.d.ts +10 -4
  20. package/dist/bits/menubar/menubar.svelte.js +14 -12
  21. package/dist/bits/popover/components/popover-content-static.svelte +2 -7
  22. package/dist/bits/popover/components/popover-content.svelte +2 -6
  23. package/dist/bits/popover/popover.svelte.d.ts +8 -3
  24. package/dist/bits/popover/popover.svelte.js +11 -9
  25. package/dist/bits/progress/components/progress.svelte +2 -0
  26. package/dist/bits/progress/progress.svelte.d.ts +7 -5
  27. package/dist/bits/progress/progress.svelte.js +6 -5
  28. package/dist/bits/progress/types.d.ts +11 -2
  29. package/dist/bits/select/components/select-content-static.svelte +7 -30
  30. package/dist/bits/select/components/select-content.svelte +4 -27
  31. package/dist/bits/select/select.svelte.d.ts +17 -2
  32. package/dist/bits/select/select.svelte.js +30 -3
  33. package/dist/bits/select/types.d.ts +2 -2
  34. package/dist/bits/tooltip/components/tooltip-content-static.svelte +7 -23
  35. package/dist/bits/tooltip/components/tooltip-content.svelte +7 -22
  36. package/dist/bits/tooltip/tooltip.svelte.d.ts +14 -1
  37. package/dist/bits/tooltip/tooltip.svelte.js +31 -1
  38. 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"
@@ -41,13 +41,6 @@ export declare class DateRangeFieldRootState {
41
41
  startValueComplete: boolean;
42
42
  endValueComplete: boolean;
43
43
  rangeComplete: boolean;
44
- mergedValues: {
45
- start: undefined;
46
- end: undefined;
47
- } | {
48
- start: DateValue;
49
- end: DateValue;
50
- };
51
44
  constructor(opts: DateRangeFieldRootStateProps);
52
45
  validationStatus: false | {
53
46
  readonly reason: "custom";
@@ -1,6 +1,5 @@
1
- import { untrack } from "svelte";
2
1
  import { box, onDestroyEffect, useRefById } from "svelte-toolbelt";
3
- import { Context } from "runed";
2
+ import { Context, watch } from "runed";
4
3
  import { DateFieldInputState, useDateFieldRoot } from "../date-field/date-field.svelte.js";
5
4
  import { useId } from "../../internal/use-id.js";
6
5
  import { getDataDisabled, getDataInvalid } from "../../internal/attrs.js";
@@ -22,21 +21,6 @@ export class DateRangeFieldRootState {
22
21
  startValueComplete = $derived.by(() => this.opts.startValue.current !== undefined);
23
22
  endValueComplete = $derived.by(() => this.opts.endValue.current !== undefined);
24
23
  rangeComplete = $derived(this.startValueComplete && this.endValueComplete);
25
- mergedValues = $derived.by(() => {
26
- if (this.opts.startValue.current === undefined ||
27
- this.opts.endValue.current === undefined) {
28
- return {
29
- start: undefined,
30
- end: undefined,
31
- };
32
- }
33
- else {
34
- return {
35
- start: this.opts.startValue.current,
36
- end: this.opts.endValue.current,
37
- };
38
- }
39
- });
40
24
  constructor(opts) {
41
25
  this.opts = opts;
42
26
  this.formatter = createFormatter(this.opts.locale.current);
@@ -54,48 +38,65 @@ export class DateRangeFieldRootState {
54
38
  return;
55
39
  this.formatter.setLocale(this.opts.locale.current);
56
40
  });
57
- $effect(() => {
58
- const startValue = this.opts.value.current.start;
59
- untrack(() => {
60
- if (startValue)
61
- this.opts.placeholder.current = startValue;
62
- });
63
- });
64
- $effect(() => {
65
- const endValue = this.opts.value.current.end;
66
- untrack(() => {
67
- if (endValue)
68
- this.opts.placeholder.current = endValue;
69
- });
41
+ /**
42
+ * Synchronize the start and end values with the `value` in case
43
+ * it is updated externally.
44
+ */
45
+ watch(() => this.opts.value.current, (value) => {
46
+ if (value.start && value.end) {
47
+ this.opts.startValue.current = value.start;
48
+ this.opts.endValue.current = value.end;
49
+ }
50
+ else if (value.start) {
51
+ this.opts.startValue.current = value.start;
52
+ this.opts.endValue.current = undefined;
53
+ }
54
+ else if (value.start === undefined && value.end === undefined) {
55
+ this.opts.startValue.current = undefined;
56
+ this.opts.endValue.current = undefined;
57
+ }
70
58
  });
71
59
  /**
72
- * Sync values set programatically with the `startValue` and `endValue`
60
+ * Synchronize the placeholder value with the current start value
73
61
  */
74
- $effect(() => {
75
- const value = this.opts.value.current;
76
- untrack(() => {
77
- if (value.start !== undefined && value.start !== this.opts.startValue.current) {
78
- this.#setStartValue(value.start);
79
- }
80
- if (value.end !== undefined && value.end !== this.opts.endValue.current) {
81
- this.#setEndValue(value.end);
82
- }
83
- });
62
+ watch(() => this.opts.value.current, (value) => {
63
+ const startValue = value.start;
64
+ if (startValue && this.opts.placeholder.current !== startValue) {
65
+ this.opts.placeholder.current = startValue;
66
+ }
84
67
  });
85
- // TODO: Handle description element
86
- $effect(() => {
87
- const placeholder = untrack(() => this.opts.placeholder.current);
88
- const startValue = untrack(() => this.opts.startValue.current);
89
- if (this.startValueComplete && placeholder !== startValue) {
90
- untrack(() => {
91
- if (startValue) {
92
- this.opts.placeholder.current = startValue;
68
+ watch([() => this.opts.startValue.current, () => this.opts.endValue.current], ([startValue, endValue]) => {
69
+ if (this.opts.value.current &&
70
+ this.opts.value.current.start === startValue &&
71
+ this.opts.value.current.end === endValue) {
72
+ return;
73
+ }
74
+ if (startValue && endValue) {
75
+ this.#updateValue((prev) => {
76
+ if (prev.start === startValue && prev.end === endValue) {
77
+ return prev;
78
+ }
79
+ if (isBefore(endValue, startValue)) {
80
+ const start = startValue;
81
+ const end = endValue;
82
+ this.#setStartValue(end);
83
+ this.#setEndValue(start);
84
+ return { start: endValue, end: startValue };
85
+ }
86
+ else {
87
+ return {
88
+ start: startValue,
89
+ end: endValue,
90
+ };
93
91
  }
94
92
  });
95
93
  }
96
- });
97
- $effect(() => {
98
- this.opts.value.current = this.mergedValues;
94
+ else if (this.opts.value.current &&
95
+ this.opts.value.current.start &&
96
+ this.opts.value.current.end) {
97
+ this.opts.value.current.start = undefined;
98
+ this.opts.value.current.end = undefined;
99
+ }
99
100
  });
100
101
  }
101
102
  validationStatus = $derived.by(() => {
@@ -134,6 +135,11 @@ export class DateRangeFieldRootState {
134
135
  return false;
135
136
  return true;
136
137
  });
138
+ #updateValue(cb) {
139
+ const value = this.opts.value.current;
140
+ const newValue = cb(value);
141
+ this.opts.value.current = newValue;
142
+ }
137
143
  #setStartValue(value) {
138
144
  this.opts.startValue.current = value;
139
145
  }
@@ -1,5 +1,5 @@
1
1
  import type { ReadableBoxedValues, WritableBoxedValues } from "../../internal/box.svelte.js";
2
- import type { BitsKeyboardEvent, BitsMouseEvent, BitsPointerEvent, WithRefProps } from "../../internal/types.js";
2
+ import type { BitsKeyboardEvent, BitsMouseEvent, WithRefProps } from "../../internal/types.js";
3
3
  type DialogVariant = "alert-dialog" | "dialog";
4
4
  type DialogRootStateProps = WritableBoxedValues<{
5
5
  open: boolean;
@@ -42,7 +42,6 @@ declare class DialogTriggerState {
42
42
  readonly root: DialogRootState;
43
43
  constructor(opts: DialogTriggerStateProps, root: DialogRootState);
44
44
  onclick(e: BitsMouseEvent): void;
45
- onpointerdown(e: BitsPointerEvent): void;
46
45
  onkeydown(e: BitsKeyboardEvent): void;
47
46
  props: {
48
47
  readonly "data-state": "open" | "closed";
@@ -50,7 +49,6 @@ declare class DialogTriggerState {
50
49
  readonly "aria-haspopup": "dialog";
51
50
  readonly "aria-expanded": "true" | "false";
52
51
  readonly "aria-controls": string | undefined;
53
- readonly onpointerdown: (e: BitsPointerEvent) => void;
54
52
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
55
53
  readonly onclick: (e: BitsMouseEvent) => void;
56
54
  readonly disabled: true | undefined;
@@ -51,9 +51,6 @@ class DialogTriggerState {
51
51
  constructor(opts, root) {
52
52
  this.opts = opts;
53
53
  this.root = root;
54
- this.onclick = this.onclick.bind(this);
55
- this.onpointerdown = this.onpointerdown.bind(this);
56
- this.onkeydown = this.onkeydown.bind(this);
57
54
  useRefById({
58
55
  ...opts,
59
56
  onRefChange: (node) => {
@@ -62,7 +59,6 @@ class DialogTriggerState {
62
59
  },
63
60
  });
64
61
  this.onclick = this.onclick.bind(this);
65
- this.onpointerdown = this.onpointerdown.bind(this);
66
62
  this.onkeydown = this.onkeydown.bind(this);
67
63
  }
68
64
  onclick(e) {
@@ -72,15 +68,6 @@ class DialogTriggerState {
72
68
  return;
73
69
  this.root.handleOpen();
74
70
  }
75
- onpointerdown(e) {
76
- if (this.opts.disabled.current)
77
- return;
78
- if (e.button > 0)
79
- return;
80
- // by default, it will attempt to focus this trigger on pointerdown
81
- // since this also opens the dialog we want to prevent that behavior
82
- e.preventDefault();
83
- }
84
71
  onkeydown(e) {
85
72
  if (this.opts.disabled.current)
86
73
  return;
@@ -95,7 +82,6 @@ class DialogTriggerState {
95
82
  "aria-expanded": getAriaExpanded(this.root.opts.open.current),
96
83
  "aria-controls": this.root.contentId,
97
84
  [this.root.attrs.trigger]: "",
98
- onpointerdown: this.onpointerdown,
99
85
  onkeydown: this.onkeydown,
100
86
  onclick: this.onclick,
101
87
  disabled: this.opts.disabled.current ? true : undefined,
@@ -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;