bits-ui 2.9.8 → 2.10.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.
@@ -4,7 +4,7 @@ import { CustomEventDispatcher } from "../../internal/events.js";
4
4
  import type { AnyFn, BitsFocusEvent, BitsKeyboardEvent, BitsMouseEvent, BitsPointerEvent, OnChangeFn, RefAttachment, WithRefOpts } from "../../internal/types.js";
5
5
  import type { Direction } from "../../shared/index.js";
6
6
  import { IsUsingKeyboard } from "../../index.js";
7
- import type { KeyboardEventHandler, PointerEventHandler } from "svelte/elements";
7
+ import type { KeyboardEventHandler, PointerEventHandler, MouseEventHandler } from "svelte/elements";
8
8
  import { RovingFocusGroup } from "../../internal/roving-focus-group.js";
9
9
  export declare const CONTEXT_MENU_TRIGGER_ATTR = "data-context-menu-trigger";
10
10
  export declare const MenuCheckboxGroupContext: Context<MenuCheckboxGroupState>;
@@ -346,6 +346,7 @@ export declare class DropdownMenuTriggerState {
346
346
  readonly parentMenu: MenuMenuState;
347
347
  readonly attachment: RefAttachment;
348
348
  constructor(opts: DropdownMenuTriggerStateOpts, parentMenu: MenuMenuState);
349
+ onclick: MouseEventHandler<HTMLElement>;
349
350
  onpointerdown: PointerEventHandler<HTMLElement>;
350
351
  onpointerup: PointerEventHandler<HTMLElement>;
351
352
  onkeydown: KeyboardEventHandler<HTMLElement>;
@@ -357,6 +358,7 @@ export declare class DropdownMenuTriggerState {
357
358
  readonly "aria-controls": string | undefined;
358
359
  readonly "data-disabled": "" | undefined;
359
360
  readonly "data-state": "open" | "closed";
361
+ readonly onclick: MouseEventHandler<HTMLElement>;
360
362
  readonly onpointerdown: PointerEventHandler<HTMLElement>;
361
363
  readonly onpointerup: PointerEventHandler<HTMLElement>;
362
364
  readonly onkeydown: KeyboardEventHandler<HTMLElement>;
@@ -768,6 +768,17 @@ export class DropdownMenuTriggerState {
768
768
  this.parentMenu = parentMenu;
769
769
  this.attachment = attachRef(this.opts.ref, (v) => (this.parentMenu.triggerNode = v));
770
770
  }
771
+ onclick = (e) => {
772
+ /**
773
+ * MacOS VoiceOver sends a click in Safari/Firefox bypassing the keydown event
774
+ * when V0+Space is pressed. Since we already handle the keydown event and the
775
+ * pointerdown events separately, we ignore it if the detail is not 0.
776
+ */
777
+ if (this.opts.disabled.current || e.detail !== 0)
778
+ return;
779
+ this.parentMenu.toggleOpen();
780
+ e.preventDefault();
781
+ };
771
782
  onpointerdown = (e) => {
772
783
  if (this.opts.disabled.current)
773
784
  return;
@@ -817,6 +828,7 @@ export class DropdownMenuTriggerState {
817
828
  "data-state": getDataOpenClosed(this.parentMenu.opts.open.current),
818
829
  [this.parentMenu.root.getBitsAttr("trigger")]: "",
819
830
  //
831
+ onclick: this.onclick,
820
832
  onpointerdown: this.onpointerdown,
821
833
  onpointerup: this.onpointerup,
822
834
  onkeydown: this.onkeydown,
@@ -28,7 +28,6 @@ interface SelectBaseRootStateOpts extends ReadableBoxedValues<{
28
28
  isCombobox: boolean;
29
29
  }
30
30
  declare abstract class SelectBaseRootState {
31
- #private;
32
31
  readonly opts: SelectBaseRootStateOpts;
33
32
  touchedInput: boolean;
34
33
  inputNode: HTMLElement | null;
@@ -45,9 +44,7 @@ declare abstract class SelectBaseRootState {
45
44
  constructor(opts: SelectBaseRootStateOpts);
46
45
  setHighlightedNode(node: HTMLElement | null, initial?: boolean): void;
47
46
  getCandidateNodes(): HTMLElement[];
48
- setHighlightedToFirstCandidate(options?: {
49
- debounced: boolean;
50
- }): void;
47
+ setHighlightedToFirstCandidate(): void;
51
48
  getNodeByValue(value: string): HTMLElement | null;
52
49
  setOpen(open: boolean): void;
53
50
  toggleOpen(): void;
@@ -1,5 +1,5 @@
1
1
  import { Context, Previous, watch } from "runed";
2
- import { afterSleep, afterTick, onDestroyEffect, onMountEffect, attachRef, DOMContext, box, } from "svelte-toolbelt";
2
+ import { afterSleep, afterTick, onDestroyEffect, attachRef, DOMContext, box, } from "svelte-toolbelt";
3
3
  import { on } from "svelte/events";
4
4
  import { backward, forward, next, prev } from "../../internal/arrays.js";
5
5
  import { getAriaExpanded, getAriaHidden, getDataDisabled, getDataOpenClosed, getDisabled, getRequired, } from "../../internal/attrs.js";
@@ -11,7 +11,6 @@ import { getFloatingContentCSSVars } from "../../internal/floating-svelte/floati
11
11
  import { DataTypeahead } from "../../internal/data-typeahead.svelte.js";
12
12
  import { DOMTypeahead } from "../../internal/dom-typeahead.svelte.js";
13
13
  import { OpenChangeComplete } from "../../internal/open-change-complete.js";
14
- import { debounce } from "../../internal/debounce.js";
15
14
  // prettier-ignore
16
15
  export const INTERACTION_KEYS = [kbd.ARROW_LEFT, kbd.ESCAPE, kbd.ARROW_RIGHT, kbd.SHIFT, kbd.CAPS_LOCK, kbd.CONTROL, kbd.ALT, kbd.META, kbd.ENTER, kbd.F1, kbd.F2, kbd.F3, kbd.F4, kbd.F5, kbd.F6, kbd.F7, kbd.F8, kbd.F9, kbd.F10, kbd.F11, kbd.F12];
17
16
  export const FIRST_KEYS = [kbd.ARROW_DOWN, kbd.PAGE_UP, kbd.HOME];
@@ -83,7 +82,6 @@ class SelectBaseRootState {
83
82
  }
84
83
  });
85
84
  }
86
- #debouncedSetHighlightedToFirstCandidate = debounce(this.setHighlightedToFirstCandidate.bind(this), 20);
87
85
  setHighlightedNode(node, initial = false) {
88
86
  this.highlightedNode = node;
89
87
  if (node && (this.isUsingKeyboard || initial)) {
@@ -96,11 +94,7 @@ class SelectBaseRootState {
96
94
  return [];
97
95
  return Array.from(node.querySelectorAll(`[${this.getBitsAttr("item")}]:not([data-disabled])`));
98
96
  }
99
- setHighlightedToFirstCandidate(options = { debounced: false }) {
100
- if (options.debounced) {
101
- this.#debouncedSetHighlightedToFirstCandidate();
102
- return;
103
- }
97
+ setHighlightedToFirstCandidate() {
104
98
  this.setHighlightedNode(null);
105
99
  const candidateNodes = this.getCandidateNodes();
106
100
  if (!candidateNodes.length)
@@ -328,7 +322,9 @@ export class SelectInputState {
328
322
  this.root.handleClose();
329
323
  return;
330
324
  }
331
- if (this.root.highlightedValue) {
325
+ if (this.root.highlightedValue &&
326
+ this.root.highlightedNode &&
327
+ this.root.highlightedNode.isConnected) {
332
328
  this.root.toggleItem(this.root.highlightedValue, this.root.highlightedLabel ?? undefined);
333
329
  }
334
330
  if (!this.root.isMulti && !isCurrentSelectedValue) {
@@ -378,6 +374,7 @@ export class SelectInputState {
378
374
  }
379
375
  oninput(e) {
380
376
  this.root.opts.inputValue.current = e.currentTarget.value;
377
+ this.root.setHighlightedToFirstCandidate();
381
378
  }
382
379
  props = $derived.by(() => ({
383
380
  id: this.opts.id.current,
@@ -790,12 +787,6 @@ export class SelectItemState {
790
787
  this.opts = opts;
791
788
  this.root = root;
792
789
  this.attachment = attachRef(opts.ref);
793
- onMountEffect(() => {
794
- this.root.setHighlightedToFirstCandidate({ debounced: true });
795
- });
796
- onDestroyEffect(() => {
797
- this.root.setHighlightedToFirstCandidate({ debounced: true });
798
- });
799
790
  watch([() => this.isHighlighted, () => this.prevHighlighted.current], () => {
800
791
  if (this.isHighlighted) {
801
792
  this.opts.onHighlight.current();
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { Accordion, AlertDialog, AspectRatio, Avatar, BitsConfig, Button, Calendar, Checkbox, Collapsible, Combobox, Command, ContextMenu, DateField, DatePicker, DateRangeField, DateRangePicker, Dialog, DropdownMenu, Label, LinkPreview, Menubar, Meter, NavigationMenu, Pagination, PinInput, Popover, Progress, RadioGroup, RangeCalendar, RatingGroup as unstable_RatingGroup, ScrollArea, Select, Separator, Slider, Switch, Tabs, TimeField, TimeRangeField, Toggle, ToggleGroup, Toolbar, Tooltip, Portal, IsUsingKeyboard, computeCommandScore, getBitsConfig, } from "./bits/index.js";
1
+ export { Accordion, AlertDialog, AspectRatio, Avatar, BitsConfig, Button, Calendar, Checkbox, Collapsible, Combobox, Command, ContextMenu, DateField, DatePicker, DateRangeField, DateRangePicker, Dialog, DropdownMenu, Label, LinkPreview, Menubar, Meter, NavigationMenu, Pagination, PinInput, Popover, Progress, RadioGroup, RangeCalendar, RatingGroup, ScrollArea, Select, Separator, Slider, Switch, Tabs, TimeField, TimeRangeField, Toggle, ToggleGroup, Toolbar, Tooltip, Portal, IsUsingKeyboard, computeCommandScore, getBitsConfig, } from "./bits/index.js";
2
2
  export * from "./shared/index.js";
3
3
  export type * from "./shared/index.js";
4
4
  export * from "./types.js";
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { Accordion, AlertDialog, AspectRatio, Avatar, BitsConfig, Button, Calendar, Checkbox, Collapsible, Combobox, Command, ContextMenu, DateField, DatePicker, DateRangeField, DateRangePicker, Dialog, DropdownMenu, Label, LinkPreview, Menubar, Meter, NavigationMenu, Pagination, PinInput, Popover, Progress, RadioGroup, RangeCalendar, RatingGroup as unstable_RatingGroup, ScrollArea, Select, Separator, Slider, Switch, Tabs, TimeField, TimeRangeField, Toggle, ToggleGroup, Toolbar, Tooltip, Portal, IsUsingKeyboard, computeCommandScore, getBitsConfig, } from "./bits/index.js";
1
+ export { Accordion, AlertDialog, AspectRatio, Avatar, BitsConfig, Button, Calendar, Checkbox, Collapsible, Combobox, Command, ContextMenu, DateField, DatePicker, DateRangeField, DateRangePicker, Dialog, DropdownMenu, Label, LinkPreview, Menubar, Meter, NavigationMenu, Pagination, PinInput, Popover, Progress, RadioGroup, RangeCalendar, RatingGroup, ScrollArea, Select, Separator, Slider, Switch, Tabs, TimeField, TimeRangeField, Toggle, ToggleGroup, Toolbar, Tooltip, Portal, IsUsingKeyboard, computeCommandScore, getBitsConfig, } from "./bits/index.js";
2
2
  export * from "./shared/index.js";
3
3
  export * from "./types.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bits-ui",
3
- "version": "2.9.8",
3
+ "version": "2.10.0",
4
4
  "license": "MIT",
5
5
  "repository": "github:huntabyte/bits-ui",
6
6
  "funding": "https://github.com/sponsors/huntabyte",
@@ -20,10 +20,10 @@
20
20
  ],
21
21
  "devDependencies": {
22
22
  "@internationalized/date": "^3.8.2",
23
- "@sveltejs/kit": "^2.31.0",
23
+ "@sveltejs/kit": "^2.42.0",
24
24
  "@sveltejs/package": "2.5.0",
25
25
  "@sveltejs/vite-plugin-svelte": "^6.2.0",
26
- "@types/node": "^20.19.0",
26
+ "@types/node": "^20.19.16",
27
27
  "@types/resize-observer-browser": "^0.1.11",
28
28
  "csstype": "^3.1.3",
29
29
  "jsdom": "^24.1.3",
@@ -41,7 +41,7 @@
41
41
  "@floating-ui/core": "^1.7.1",
42
42
  "@floating-ui/dom": "^1.7.1",
43
43
  "esm-env": "^1.1.2",
44
- "runed": "^0.29.1",
44
+ "runed": "^0.31.1",
45
45
  "svelte-toolbelt": "^0.9.3",
46
46
  "tabbable": "^6.2.0"
47
47
  },