bits-ui 2.16.4 → 2.16.5

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.
@@ -135,6 +135,7 @@ export declare class DateFieldRootState {
135
135
  style: {
136
136
  caretColor: string;
137
137
  };
138
+ onbeforeinput: (e: InputEvent) => void;
138
139
  };
139
140
  updateSegment<T extends keyof DateAndTimeSegmentObj>(part: T, cb: T extends DateSegmentPart ? Updater<DateSegmentObj[T]> : T extends EditableTimeSegmentPart ? Updater<TimeSegmentObj[T]> : Updater<DateAndTimeSegmentObj[T]>): void;
140
141
  handleSegmentClick(e: BitsMouseEvent): void;
@@ -256,6 +257,7 @@ declare abstract class BaseNumericSegmentState {
256
257
  style: {
257
258
  caretColor: string;
258
259
  };
260
+ onbeforeinput: (e: InputEvent) => void;
259
261
  } | {
260
262
  "aria-labelledby": string;
261
263
  contenteditable: string | undefined;
@@ -285,6 +287,7 @@ declare abstract class BaseNumericSegmentState {
285
287
  style: {
286
288
  caretColor: string;
287
289
  };
290
+ onbeforeinput: (e: InputEvent) => void;
288
291
  };
289
292
  }
290
293
  declare class DateFieldYearSegmentState extends BaseNumericSegmentState {
@@ -345,6 +348,7 @@ export declare class DateFieldDayPeriodSegmentState {
345
348
  style: {
346
349
  caretColor: string;
347
350
  };
351
+ onbeforeinput: (e: InputEvent) => void;
348
352
  } | {
349
353
  "aria-labelledby": string;
350
354
  contenteditable: string | undefined;
@@ -373,6 +377,7 @@ export declare class DateFieldDayPeriodSegmentState {
373
377
  style: {
374
378
  caretColor: string;
375
379
  };
380
+ onbeforeinput: (e: InputEvent) => void;
376
381
  } | undefined;
377
382
  }
378
383
  interface DateFieldLiteralSegmentStateOpts extends WithRefOpts {
@@ -414,6 +414,11 @@ export class DateFieldRootState {
414
414
  style: {
415
415
  caretColor: "transparent",
416
416
  },
417
+ onbeforeinput: (e) => {
418
+ if (!e.data || e.data.length <= 1) {
419
+ e.preventDefault();
420
+ }
421
+ },
417
422
  };
418
423
  #getLabelledBy(segmentId) {
419
424
  return `${segmentId} ${this.getLabelNode()?.id ?? ""}`;
@@ -80,7 +80,7 @@ export class NavigationMenuRootState {
80
80
  const isOpen = this.opts?.value?.current !== "";
81
81
  if (isOpen || this.isDelaySkipped.current) {
82
82
  // 150 for user to switch trigger or move into content view
83
- return 100;
83
+ return 150;
84
84
  }
85
85
  else {
86
86
  return this.opts.delayDuration.current;
@@ -41,11 +41,13 @@ declare abstract class SelectBaseRootState {
41
41
  readonly highlightedValue: string | null;
42
42
  readonly highlightedId: string | undefined;
43
43
  readonly highlightedLabel: string | null;
44
+ contentIsPositioned: boolean;
44
45
  isUsingKeyboard: boolean;
45
46
  isCombobox: boolean;
46
47
  domContext: DOMContext;
47
48
  constructor(opts: SelectBaseRootStateOpts);
48
49
  setHighlightedNode(node: HTMLElement | null, initial?: boolean): void;
50
+ scrollHighlightedNodeIntoView(node: HTMLElement): void;
49
51
  getCandidateNodes(): HTMLElement[];
50
52
  setHighlightedToFirstCandidate(initial?: boolean): void;
51
53
  getNodeByValue(value: string): HTMLElement | null;
@@ -65,6 +65,7 @@ class SelectBaseRootState {
65
65
  return null;
66
66
  return this.highlightedNode.getAttribute("data-label");
67
67
  });
68
+ contentIsPositioned = $state(false);
68
69
  isUsingKeyboard = false;
69
70
  isCombobox = false;
70
71
  domContext = new DOMContext(() => null);
@@ -87,9 +88,14 @@ class SelectBaseRootState {
87
88
  setHighlightedNode(node, initial = false) {
88
89
  this.highlightedNode = node;
89
90
  if (node && (this.isUsingKeyboard || initial)) {
90
- node.scrollIntoView({ block: this.opts.scrollAlignment.current });
91
+ this.scrollHighlightedNodeIntoView(node);
91
92
  }
92
93
  }
94
+ scrollHighlightedNodeIntoView(node) {
95
+ if (!this.viewportNode || !this.contentIsPositioned)
96
+ return;
97
+ node.scrollIntoView({ block: this.opts.scrollAlignment.current });
98
+ }
93
99
  getCandidateNodes() {
94
100
  const node = this.contentNode;
95
101
  if (!node)
@@ -713,13 +719,20 @@ export class SelectContentState {
713
719
  }
714
720
  onDestroyEffect(() => {
715
721
  this.root.contentNode = null;
722
+ this.root.contentIsPositioned = false;
716
723
  this.isPositioned = false;
717
724
  });
718
725
  watch(() => this.root.opts.open.current, () => {
719
726
  if (this.root.opts.open.current)
720
727
  return;
728
+ this.root.contentIsPositioned = false;
721
729
  this.isPositioned = false;
722
730
  });
731
+ watch([() => this.isPositioned, () => this.root.highlightedNode], () => {
732
+ if (!this.isPositioned || !this.root.highlightedNode)
733
+ return;
734
+ this.root.scrollHighlightedNodeIntoView(this.root.highlightedNode);
735
+ });
723
736
  this.onpointermove = this.onpointermove.bind(this);
724
737
  }
725
738
  onpointermove(_) {
@@ -782,6 +795,7 @@ export class SelectContentState {
782
795
  // onPlaced is also called when the menu is closed, so we need to check if the menu
783
796
  // is actually open to avoid setting positioning to true when the menu is closed
784
797
  if (this.root.opts.open.current) {
798
+ this.root.contentIsPositioned = true;
785
799
  this.isPositioned = true;
786
800
  }
787
801
  },
@@ -1120,7 +1134,9 @@ export class SelectScrollDownButtonState {
1120
1134
  }
1121
1135
  this.scrollIntoViewTimer = afterSleep(5, () => {
1122
1136
  const activeItem = this.root.highlightedNode;
1123
- activeItem?.scrollIntoView({ block: this.root.opts.scrollAlignment.current });
1137
+ if (!activeItem)
1138
+ return;
1139
+ this.root.scrollHighlightedNodeIntoView(activeItem);
1124
1140
  });
1125
1141
  });
1126
1142
  }
@@ -163,8 +163,8 @@ export class TooltipProviderState {
163
163
  onClose = (tooltip) => {
164
164
  if (this.#openTooltip === tooltip) {
165
165
  this.#openTooltip = null;
166
+ this.#startTimer();
166
167
  }
167
- this.#startTimer();
168
168
  };
169
169
  isTooltipOpen = (tooltip) => {
170
170
  return this.#openTooltip === tooltip;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bits-ui",
3
- "version": "2.16.4",
3
+ "version": "2.16.5",
4
4
  "license": "MIT",
5
5
  "repository": "github:huntabyte/bits-ui",
6
6
  "funding": "https://github.com/sponsors/huntabyte",