@jobber/components 8.18.1 → 8.20.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.
@@ -245,7 +245,7 @@ function useFocus(context, props = {}) {
245
245
  // return to the tab/window.
246
246
  function onBlur() {
247
247
  const currentDomReference = store.select('domReferenceElement');
248
- if (!store.select('open') && floatingUi_utils_dom.isHTMLElement(currentDomReference) && currentDomReference === ScrollAreaViewport.activeElement(clamp.ownerDocument(currentDomReference))) {
248
+ if (!store.select('open') && floatingUi_utils_dom.isHTMLElement(currentDomReference) && currentDomReference === clamp.activeElement(clamp.ownerDocument(currentDomReference))) {
249
249
  blockFocusRef.current = true;
250
250
  }
251
251
  }
@@ -300,19 +300,19 @@ function useFocus(context, props = {}) {
300
300
  blockFocusRef.current = false;
301
301
  blockedReferenceRef.current = null;
302
302
  }
303
- const target = ScrollAreaViewport.getTarget(event.nativeEvent);
303
+ const target = clamp.getTarget(event.nativeEvent);
304
304
  if (floatingUi_utils_dom.isElement(target)) {
305
305
  // Safari fails to match `:focus-visible` if focus was initially
306
306
  // outside the document.
307
307
  if (isMacSafari && !event.relatedTarget) {
308
- if (!keyboardModalityRef.current && !ScrollAreaViewport.isTypeableElement(target)) {
308
+ if (!keyboardModalityRef.current && !clamp.isTypeableElement(target)) {
309
309
  return;
310
310
  }
311
- } else if (!ScrollAreaViewport.matchesFocusVisible(target)) {
311
+ } else if (!clamp.matchesFocusVisible(target)) {
312
312
  return;
313
313
  }
314
314
  }
315
- const movedFromOtherEnabledTrigger = ScrollAreaViewport.isTargetInsideEnabledTrigger(event.relatedTarget, store.context.triggerElements);
315
+ const movedFromOtherEnabledTrigger = clamp.isTargetInsideEnabledTrigger(event.relatedTarget, store.context.triggerElements);
316
316
  const {
317
317
  nativeEvent,
318
318
  currentTarget
@@ -342,7 +342,7 @@ function useFocus(context, props = {}) {
342
342
  // Wait for the window blur listener to fire.
343
343
  timeout.start(0, () => {
344
344
  const domReference = store.select('domReferenceElement');
345
- const activeEl = ScrollAreaViewport.activeElement(domReference ? domReference.ownerDocument : document);
345
+ const activeEl = clamp.activeElement(domReference ? domReference.ownerDocument : document);
346
346
 
347
347
  // Focus left the page, keep it open.
348
348
  if (!relatedTarget && activeEl === domReference) {
@@ -356,7 +356,7 @@ function useFocus(context, props = {}) {
356
356
  // as it will only point to the shadow host of the newly focused element
357
357
  // and not the element that actually has received focus if it is located
358
358
  // inside a shadow root.
359
- if (ScrollAreaViewport.contains(dataRef.current.floatingContext?.refs.floating.current, activeEl) || ScrollAreaViewport.contains(domReference, activeEl) || movedToFocusGuard) {
359
+ if (clamp.contains(dataRef.current.floatingContext?.refs.floating.current, activeEl) || clamp.contains(domReference, activeEl) || movedToFocusGuard) {
360
360
  return;
361
361
  }
362
362
 
@@ -364,7 +364,7 @@ function useFocus(context, props = {}) {
364
364
  // the floating element. The focus handler of that trigger will
365
365
  // handle the open state.
366
366
  const nextFocusedElement = relatedTarget ?? activeEl;
367
- if (ScrollAreaViewport.isTargetInsideEnabledTrigger(nextFocusedElement, store.context.triggerElements)) {
367
+ if (clamp.isTargetInsideEnabledTrigger(nextFocusedElement, store.context.triggerElements)) {
368
368
  return;
369
369
  }
370
370
  store.setOpen(false, clamp.createChangeEventDetails(clamp.triggerFocus, nativeEvent));
@@ -377,7 +377,7 @@ function useFocus(context, props = {}) {
377
377
  } : {}, [enabled, reference]);
378
378
  }
379
379
 
380
- const interactiveSelector = `button,a,[role="button"],select,[tabindex]:not([tabindex="-1"]),${ScrollAreaViewport.TYPEABLE_SELECTOR}`;
380
+ const interactiveSelector = `button,a,[role="button"],select,[tabindex]:not([tabindex="-1"]),${clamp.TYPEABLE_SELECTOR}`;
381
381
  function isInteractiveElement(element) {
382
382
  return element ? Boolean(element.closest(interactiveSelector)) : false;
383
383
  }
@@ -470,7 +470,7 @@ function useHoverFloatingInteraction(context, parameters = {}) {
470
470
  return type?.includes('mouse') && type !== 'mousedown';
471
471
  });
472
472
  const isRelatedTargetInsideEnabledTrigger = clamp.useStableCallback(target => {
473
- return ScrollAreaViewport.isTargetInsideEnabledTrigger(target, store.context.triggerElements);
473
+ return clamp.isTargetInsideEnabledTrigger(target, store.context.triggerElements);
474
474
  });
475
475
  const closeWithDelay = React__namespace.useCallback(event => {
476
476
  const closeDelay = getDelay(closeDelayProp, 'close', instance.pointerType);
@@ -489,7 +489,7 @@ function useHoverFloatingInteraction(context, parameters = {}) {
489
489
  clearSafePolygonPointerEventsMutation(instance);
490
490
  });
491
491
  const handleInteractInside = clamp.useStableCallback(event => {
492
- const target = ScrollAreaViewport.getTarget(event);
492
+ const target = clamp.getTarget(event);
493
493
  if (!isInteractiveElement(target)) {
494
494
  instance.interactedInside = false;
495
495
  return;
@@ -631,14 +631,14 @@ function useHoverReferenceInteraction(context, props = {}) {
631
631
  return isClickLikeOpenEvent(dataRef.current.openEvent?.type, instance.interactedInside);
632
632
  });
633
633
  const isRelatedTargetInsideEnabledTrigger = clamp.useStableCallback(target => {
634
- return ScrollAreaViewport.isTargetInsideEnabledTrigger(target, store.context.triggerElements);
634
+ return clamp.isTargetInsideEnabledTrigger(target, store.context.triggerElements);
635
635
  });
636
636
  const isOverInactiveTrigger = clamp.useStableCallback((currentDomReference, currentTarget, target) => {
637
637
  const allTriggers = store.context.triggerElements;
638
638
 
639
639
  // Fast path for normal usage where handlers are attached directly to triggers.
640
640
  if (allTriggers.hasElement(currentTarget)) {
641
- return !currentDomReference || !ScrollAreaViewport.contains(currentDomReference, currentTarget);
641
+ return !currentDomReference || !clamp.contains(currentDomReference, currentTarget);
642
642
  }
643
643
 
644
644
  // Fallback for delegated/wrapper usage where currentTarget may be outside the trigger map.
@@ -646,7 +646,7 @@ function useHoverReferenceInteraction(context, props = {}) {
646
646
  return false;
647
647
  }
648
648
  const targetElement = target;
649
- return allTriggers.hasMatchingElement(trigger => ScrollAreaViewport.contains(trigger, targetElement)) && (!currentDomReference || !ScrollAreaViewport.contains(currentDomReference, targetElement));
649
+ return allTriggers.hasMatchingElement(trigger => clamp.contains(trigger, targetElement)) && (!currentDomReference || !clamp.contains(currentDomReference, targetElement));
650
650
  });
651
651
  const closeWithDelay = React__namespace.useCallback((event, runElseBranch = true) => {
652
652
  const closeDelay = getDelay(delayRef.current, 'close', instance.pointerType);
@@ -772,7 +772,7 @@ function useHoverReferenceInteraction(context, props = {}) {
772
772
  instance.handler(event);
773
773
  return;
774
774
  }
775
- const shouldClose = instance.pointerType === 'touch' ? !ScrollAreaViewport.contains(store.select('floatingElement'), event.relatedTarget) : true;
775
+ const shouldClose = instance.pointerType === 'touch' ? !clamp.contains(store.select('floatingElement'), event.relatedTarget) : true;
776
776
  if (shouldClose) {
777
777
  closeWithDelay(event);
778
778
  }
@@ -861,23 +861,23 @@ function doSwitch(orientation, vertical, horizontal) {
861
861
  }
862
862
  }
863
863
  function isMainOrientationKey(key, orientation) {
864
- const vertical = key === ScrollAreaViewport.ARROW_UP || key === ScrollAreaViewport.ARROW_DOWN;
865
- const horizontal = key === ScrollAreaViewport.ARROW_LEFT || key === ScrollAreaViewport.ARROW_RIGHT;
864
+ const vertical = key === clamp.ARROW_UP || key === clamp.ARROW_DOWN;
865
+ const horizontal = key === clamp.ARROW_LEFT || key === clamp.ARROW_RIGHT;
866
866
  return doSwitch(orientation, vertical, horizontal);
867
867
  }
868
868
  function isMainOrientationToEndKey(key, orientation, rtl) {
869
- const vertical = key === ScrollAreaViewport.ARROW_DOWN;
870
- const horizontal = rtl ? key === ScrollAreaViewport.ARROW_LEFT : key === ScrollAreaViewport.ARROW_RIGHT;
869
+ const vertical = key === clamp.ARROW_DOWN;
870
+ const horizontal = rtl ? key === clamp.ARROW_LEFT : key === clamp.ARROW_RIGHT;
871
871
  return doSwitch(orientation, vertical, horizontal) || key === 'Enter' || key === ' ' || key === '';
872
872
  }
873
873
  function isCrossOrientationOpenKey(key, orientation, rtl) {
874
- const vertical = rtl ? key === ScrollAreaViewport.ARROW_LEFT : key === ScrollAreaViewport.ARROW_RIGHT;
875
- const horizontal = key === ScrollAreaViewport.ARROW_DOWN;
874
+ const vertical = rtl ? key === clamp.ARROW_LEFT : key === clamp.ARROW_RIGHT;
875
+ const horizontal = key === clamp.ARROW_DOWN;
876
876
  return doSwitch(orientation, vertical, horizontal);
877
877
  }
878
878
  function isCrossOrientationCloseKey(key, orientation, rtl, cols) {
879
- const vertical = rtl ? key === ScrollAreaViewport.ARROW_RIGHT : key === ScrollAreaViewport.ARROW_LEFT;
880
- const horizontal = key === ScrollAreaViewport.ARROW_UP;
879
+ const vertical = rtl ? key === clamp.ARROW_RIGHT : key === clamp.ARROW_LEFT;
880
+ const horizontal = key === clamp.ARROW_UP;
881
881
  if (orientation === 'both' || orientation === 'horizontal' && cols && cols > 1) {
882
882
  return key === ESCAPE;
883
883
  }
@@ -929,14 +929,14 @@ function useListNavigation(context, props) {
929
929
  console.warn('In grid list navigation mode (`cols` > 1), the `orientation` should', 'be either "horizontal" or "both".');
930
930
  }
931
931
  }
932
- const floatingFocusElement = ScrollAreaViewport.getFloatingFocusElement(floatingElement);
932
+ const floatingFocusElement = clamp.getFloatingFocusElement(floatingElement);
933
933
  const floatingFocusElementRef = clamp.useValueAsRef(floatingFocusElement);
934
934
  const parentId = ScrollAreaViewport.useFloatingParentNodeId();
935
935
  const tree = ScrollAreaViewport.useFloatingTree(externalTree);
936
936
  clamp.useIsoLayoutEffect(() => {
937
937
  dataRef.current.orientation = orientation;
938
938
  }, [dataRef, orientation]);
939
- const typeableComboboxReference = ScrollAreaViewport.isTypeableCombobox(domReferenceElement);
939
+ const typeableComboboxReference = clamp.isTypeableCombobox(domReferenceElement);
940
940
  const focusItemOnOpenRef = React__namespace.useRef(focusItemOnOpen);
941
941
  const indexRef = React__namespace.useRef(selectedIndex ?? -1);
942
942
  const keyRef = React__namespace.useRef(null);
@@ -1077,8 +1077,8 @@ function useListNavigation(context, props) {
1077
1077
  }
1078
1078
  const nodes = tree.nodesRef.current;
1079
1079
  const parent = nodes.find(node => node.id === parentId)?.context?.elements.floating;
1080
- const activeEl = ScrollAreaViewport.activeElement(clamp.ownerDocument(floatingElement));
1081
- const treeContainsActiveEl = nodes.some(node => node.context && ScrollAreaViewport.contains(node.context.elements.floating, activeEl));
1080
+ const activeEl = clamp.activeElement(clamp.ownerDocument(floatingElement));
1081
+ const treeContainsActiveEl = nodes.some(node => node.context && clamp.contains(node.context.elements.floating, activeEl));
1082
1082
  if (parent && !treeContainsActiveEl && isPointerModalityRef.current) {
1083
1083
  parent.focus({
1084
1084
  preventScroll: true
@@ -1145,8 +1145,8 @@ function useListNavigation(context, props) {
1145
1145
  onNavigate(event);
1146
1146
  if (!virtual) {
1147
1147
  const floatingFocusEl = floatingFocusElementRef.current;
1148
- const activeEl = ScrollAreaViewport.activeElement(clamp.ownerDocument(floatingFocusEl));
1149
- if (floatingFocusEl && ScrollAreaViewport.contains(floatingFocusEl, activeEl)) {
1148
+ const activeEl = clamp.activeElement(clamp.ownerDocument(floatingFocusEl));
1149
+ if (floatingFocusEl && clamp.contains(floatingFocusEl, activeEl)) {
1150
1150
  floatingFocusEl.focus({
1151
1151
  preventScroll: true
1152
1152
  });
@@ -1241,7 +1241,7 @@ function useListNavigation(context, props) {
1241
1241
  // we're moving in so we don't end up in the same item. Prefer
1242
1242
  // top/left over bottom/right.
1243
1243
  // eslint-disable-next-line no-nested-ternary
1244
- event.key === ScrollAreaViewport.ARROW_DOWN ? 'bl' : event.key === (rtl ? ScrollAreaViewport.ARROW_LEFT : ScrollAreaViewport.ARROW_RIGHT) ? 'tr' : 'tl'),
1244
+ event.key === clamp.ARROW_DOWN ? 'bl' : event.key === (rtl ? clamp.ARROW_LEFT : clamp.ARROW_RIGHT) ? 'tr' : 'tl'),
1245
1245
  stopEvent: true
1246
1246
  })];
1247
1247
  if (index != null) {
@@ -1256,7 +1256,7 @@ function useListNavigation(context, props) {
1256
1256
  clamp.stopEvent(event);
1257
1257
 
1258
1258
  // Reset the index if no item is focused.
1259
- if (open && !virtual && ScrollAreaViewport.activeElement(event.currentTarget.ownerDocument) === event.currentTarget) {
1259
+ if (open && !virtual && clamp.activeElement(event.currentTarget.ownerDocument) === event.currentTarget) {
1260
1260
  indexRef.current = isMainOrientationToEndKey(event.key, orientation, rtl) ? minIndex : maxIndex;
1261
1261
  onNavigate(event);
1262
1262
  return;
@@ -1327,8 +1327,8 @@ function useListNavigation(context, props) {
1327
1327
  // If the event originated from within a nested element (e.g., a Dialog opened from
1328
1328
  // within the menu), don't close the menu. The nested element has its own focus
1329
1329
  // management and should handle the Tab key.
1330
- const target = ScrollAreaViewport.getTarget(event.nativeEvent);
1331
- if (target && !ScrollAreaViewport.contains(floatingFocusElementRef.current, target)) {
1330
+ const target = clamp.getTarget(event.nativeEvent);
1331
+ if (target && !clamp.contains(floatingFocusElementRef.current, target)) {
1332
1332
  return;
1333
1333
  }
1334
1334
  clamp.stopEvent(event);
@@ -1569,8 +1569,8 @@ function useTypeahead(context, props) {
1569
1569
  const next = event.relatedTarget;
1570
1570
  const currentDomReferenceElement = store.select('domReferenceElement');
1571
1571
  const currentFloatingElement = store.select('floatingElement');
1572
- const withinReference = ScrollAreaViewport.contains(currentDomReferenceElement, next);
1573
- const withinFloating = ScrollAreaViewport.contains(currentFloatingElement, next);
1572
+ const withinReference = clamp.contains(currentDomReferenceElement, next);
1573
+ const withinFloating = clamp.contains(currentFloatingElement, next);
1574
1574
 
1575
1575
  // Keep the session if focus moves within the composite (reference <-> floating).
1576
1576
  if (withinReference || withinFloating) {
@@ -1690,10 +1690,10 @@ function safePolygon(options = {}) {
1690
1690
  clientX,
1691
1691
  clientY
1692
1692
  } = event;
1693
- const target = ScrollAreaViewport.getTarget(event);
1693
+ const target = clamp.getTarget(event);
1694
1694
  const isLeave = event.type === 'mouseleave';
1695
- const isOverFloatingEl = ScrollAreaViewport.contains(floating, target);
1696
- const isOverReferenceEl = ScrollAreaViewport.contains(domReference, target);
1695
+ const isOverFloatingEl = clamp.contains(floating, target);
1696
+ const isOverReferenceEl = clamp.contains(domReference, target);
1697
1697
  if (isOverFloatingEl) {
1698
1698
  hasLanded = true;
1699
1699
  if (!isLeave) {
@@ -1710,7 +1710,7 @@ function safePolygon(options = {}) {
1710
1710
 
1711
1711
  // Prevent overlapping floating element from being stuck in an open-close
1712
1712
  // loop: https://github.com/floating-ui/floating-ui/issues/1910
1713
- if (isLeave && floatingUi_utils_dom.isElement(event.relatedTarget) && ScrollAreaViewport.contains(floating, event.relatedTarget)) {
1713
+ if (isLeave && floatingUi_utils_dom.isElement(event.relatedTarget) && clamp.contains(floating, event.relatedTarget)) {
1714
1714
  return undefined;
1715
1715
  }
1716
1716
  function hasOpenChildNode() {
@@ -4492,7 +4492,7 @@ const MenuTrigger = ScrollAreaViewport.fastComponentRef(function MenuTrigger(com
4492
4492
  allowMouseUpTriggerTimeout.clear();
4493
4493
  store.context.allowMouseUpTriggerRef.current = false;
4494
4494
  const mouseUpTarget = mouseEvent.target;
4495
- if (ScrollAreaViewport.contains(triggerRef.current, mouseUpTarget) || ScrollAreaViewport.contains(store.select('positionerElement'), mouseUpTarget) || mouseUpTarget === triggerRef.current) {
4495
+ if (clamp.contains(triggerRef.current, mouseUpTarget) || clamp.contains(store.select('positionerElement'), mouseUpTarget) || mouseUpTarget === triggerRef.current) {
4496
4496
  return;
4497
4497
  }
4498
4498
  if (mouseUpTarget != null && findRootOwnerId(mouseUpTarget) === store.select('rootId')) {
@@ -4596,7 +4596,7 @@ const MenuTrigger = ScrollAreaViewport.fastComponentRef(function MenuTrigger(com
4596
4596
  store.setOpen(false, clamp.createChangeEventDetails(clamp.focusOut, event.nativeEvent, event.currentTarget));
4597
4597
  });
4598
4598
  let nextTabbable = ScrollAreaViewport.getTabbableAfterElement(store.context.triggerFocusTargetRef.current || triggerElementRef.current);
4599
- while (nextTabbable !== null && ScrollAreaViewport.contains(currentPositionerElement, nextTabbable)) {
4599
+ while (nextTabbable !== null && clamp.contains(currentPositionerElement, nextTabbable)) {
4600
4600
  const prevTabbable = nextTabbable;
4601
4601
  nextTabbable = ScrollAreaViewport.getNextTabbable(nextTabbable);
4602
4602
  if (nextTabbable === prevTabbable) {
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
- import { u as useFloatingParentNodeId, F as FloatingRootStore, P as PopupTriggerMap, g as useFloatingTree, h as getTarget, i as isTypeableElement, m as matchesFocusVisible, j as isTargetInsideEnabledTrigger, k as createAttribute, l as activeElement, n as contains, T as TYPEABLE_SELECTOR, o as getNodeChildren, p as getFloatingFocusElement, q as isTypeableCombobox, r as isIndexOutOfListBounds, s as getMinListIndex, t as getMaxListIndex, v as createGridCellMap, w as isListIndexDisabled, x as getGridNavigatedIndex, y as getGridCellIndices, z as getGridCellIndexOfCorner, A as ARROW_DOWN, B as ARROW_LEFT, C as ARROW_RIGHT, E as findNonDisabledListIndex, G as enqueueFocus, H as ARROW_UP, I as isElementVisible, J as useDirection, K as DISABLED_TRANSITIONS_STYLE, L as useDialogRootContext, M as popupStateMapping, N as COMPOSITE_KEYS, O as FloatingFocusManager, Q as FloatingPortal, R as POPUP_COLLISION_AVOIDANCE, U as InternalBackdrop, V as inertValue, W as FloatingNode, X as DROPDOWN_COLLISION_AVOIDANCE, Y as popupStoreSelectors, Z as createSelector, _ as ReactStore, $ as createInitialPopupStoreState, a0 as FloatingTreeStore, a1 as fastComponent, a2 as useOnFirstRender, a3 as useFloatingNodeId, a4 as useOpenInteractionType, a5 as useImplicitActiveTrigger, a6 as useOpenStateTransitions, a7 as useScrollLock, a8 as useSyncedFloatingRootContext, a9 as useDismiss, aa as useRole, ab as TYPEAHEAD_RESET_MS, ac as useInteractions, ad as FloatingTree, ae as fastComponentRef, af as useTriggerDataForwarding, ag as useClick, ah as getTabbableBeforeElement, ai as isOutsideEvent, aj as getTabbableAfterElement, ak as getNextTabbable, al as pressableTriggerOpenStateMapping, am as FocusGuard, an as PATIENT_CLICK_THRESHOLD, ao as useTriggerRegistration, ap as triggerOpenStateMapping } from './ScrollAreaViewport-es.js';
2
+ import { u as useFloatingParentNodeId, F as FloatingRootStore, P as PopupTriggerMap, g as useFloatingTree, h as createAttribute, i as getNodeChildren, j as isIndexOutOfListBounds, k as getMinListIndex, l as getMaxListIndex, m as createGridCellMap, n as isListIndexDisabled, o as getGridNavigatedIndex, p as getGridCellIndices, q as getGridCellIndexOfCorner, r as findNonDisabledListIndex, s as enqueueFocus, t as isElementVisible, v as useDirection, w as DISABLED_TRANSITIONS_STYLE, x as useDialogRootContext, y as popupStateMapping, C as COMPOSITE_KEYS, z as FloatingFocusManager, A as FloatingPortal, B as POPUP_COLLISION_AVOIDANCE, I as InternalBackdrop, E as inertValue, G as FloatingNode, H as DROPDOWN_COLLISION_AVOIDANCE, J as popupStoreSelectors, K as createSelector, R as ReactStore, L as createInitialPopupStoreState, M as FloatingTreeStore, N as fastComponent, O as useOnFirstRender, Q as useFloatingNodeId, T as useOpenInteractionType, U as useImplicitActiveTrigger, V as useOpenStateTransitions, W as useScrollLock, X as useSyncedFloatingRootContext, Y as useDismiss, Z as useRole, _ as TYPEAHEAD_RESET_MS, $ as useInteractions, a0 as FloatingTree, a1 as fastComponentRef, a2 as useTriggerDataForwarding, a3 as useClick, a4 as getTabbableBeforeElement, a5 as isOutsideEvent, a6 as getTabbableAfterElement, a7 as getNextTabbable, a8 as pressableTriggerOpenStateMapping, a9 as FocusGuard, aa as PATIENT_CLICK_THRESHOLD, ab as useTriggerRegistration, ac as triggerOpenStateMapping } from './ScrollAreaViewport-es.js';
3
3
  import { a as useRefWithInit, E as EMPTY_OBJECT, u as useRenderElement, f as formatErrorMessage, m as mergeProps, b as useMergedRefs, d as EMPTY_ARRAY } from './useRenderElement-es.js';
4
- import { C as isMouseLikePointerType, D as useId, d as useIsoLayoutEffect, b as useTimeout, k as createChangeEventDetails, E as triggerFocus, F as isMac, G as isSafari, s as ownerDocument, H as triggerPress, I as escapeKey, f as useOnMount, T as Timeout, a as useStableCallback, J as triggerHover, i as useValueAsRef, A as stopEvent, K as listNavigation, L as focusOut, M as isVirtualClick, N as isVirtualPointerEvent, y as useButton, O as closePress, u as useBaseUiId, P as itemPress, t as transitionStatusMapping, e as useOpenChangeComplete, Q as outsidePress, R as useAnimationsFinished, S as siblingOpen, h as useControlled, c as useTransitionStatus, U as imperativeAction, V as useCompositeRootContext, W as cancelOpen } from './clamp-es.js';
4
+ import { E as isMouseLikePointerType, F as useId, d as useIsoLayoutEffect, b as useTimeout, g as getTarget, G as isTypeableElement, H as matchesFocusVisible, I as isTargetInsideEnabledTrigger, m as createChangeEventDetails, J as triggerFocus, K as activeElement, L as contains, M as isMac, N as isSafari, o as ownerDocument, O as triggerPress, P as escapeKey, h as useOnMount, Q as TYPEABLE_SELECTOR, T as Timeout, a as useStableCallback, R as triggerHover, k as useValueAsRef, U as getFloatingFocusElement, V as isTypeableCombobox, C as stopEvent, W as listNavigation, X as ARROW_DOWN, Y as ARROW_LEFT, Z as ARROW_RIGHT, _ as focusOut, $ as isVirtualClick, a0 as isVirtualPointerEvent, a1 as ARROW_UP, A as useButton, a2 as closePress, u as useBaseUiId, a3 as itemPress, t as transitionStatusMapping, f as useOpenChangeComplete, a4 as outsidePress, a5 as useAnimationsFinished, a6 as siblingOpen, j as useControlled, c as useTransitionStatus, a7 as imperativeAction, a8 as useCompositeRootContext, a9 as cancelOpen } from './clamp-es.js';
5
5
  import { jsx, jsxs } from 'react/jsx-runtime';
6
6
  import { b as isElement, k as getWindow, a as isHTMLElement, d as isLastTraversableNode, e as getParentNode } from './floating-ui.utils.dom-es.js';
7
7
  import { e as evaluate, h as getPaddingObject, b as getAlignmentAxis, d as getAlignment, q as getAxisLength, n as clamp, c as getSide, g as getSideAxis } from './index.esm-es.js';
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var React = require('react');
3
+ var floatingUi_utils_dom = require('./floating-ui.utils.dom-cjs.js');
4
4
  var clamp = require('./clamp-cjs.js');
5
+ var React = require('react');
5
6
  var useRenderElement = require('./useRenderElement-cjs.js');
6
- var floatingUi_utils_dom = require('./floating-ui.utils.dom-cjs.js');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
  var ReactDOM = require('react-dom');
9
9
 
@@ -330,6 +330,84 @@ function useLabelableId(params = {}) {
330
330
  return controlId ?? defaultId;
331
331
  }
332
332
 
333
+ function useRegisteredLabelId(idProp, setLabelId) {
334
+ const id = clamp.useBaseUiId(idProp);
335
+ clamp.useIsoLayoutEffect(() => {
336
+ setLabelId(id);
337
+ return () => {
338
+ setLabelId(undefined);
339
+ };
340
+ }, [id, setLabelId]);
341
+ return id;
342
+ }
343
+
344
+ function useLabel(params = {}) {
345
+ const {
346
+ id: idProp,
347
+ fallbackControlId,
348
+ native = false,
349
+ setLabelId: setLabelIdProp,
350
+ focusControl: focusControlProp
351
+ } = params;
352
+ const {
353
+ controlId: contextControlId,
354
+ setLabelId: setContextLabelId
355
+ } = useLabelableContext();
356
+ const syncLabelId = clamp.useStableCallback(nextLabelId => {
357
+ setContextLabelId(nextLabelId);
358
+ setLabelIdProp?.(nextLabelId);
359
+ });
360
+ const id = useRegisteredLabelId(idProp, syncLabelId);
361
+ const resolvedControlId = contextControlId ?? fallbackControlId;
362
+ function focusControl(event) {
363
+ if (focusControlProp) {
364
+ focusControlProp(event, resolvedControlId);
365
+ return;
366
+ }
367
+ if (!resolvedControlId) {
368
+ return;
369
+ }
370
+ const controlElement = clamp.ownerDocument(event.currentTarget).getElementById(resolvedControlId);
371
+ if (floatingUi_utils_dom.isHTMLElement(controlElement)) {
372
+ focusElementWithVisible(controlElement);
373
+ }
374
+ }
375
+ function handleInteraction(event) {
376
+ const target = clamp.getTarget(event.nativeEvent);
377
+ if (target?.closest('button,input,select,textarea')) {
378
+ return;
379
+ }
380
+
381
+ // Prevent text selection when double clicking label.
382
+ if (!event.defaultPrevented && event.detail > 1) {
383
+ event.preventDefault();
384
+ }
385
+ if (native) {
386
+ return;
387
+ }
388
+ focusControl(event);
389
+ }
390
+ return native ? {
391
+ id,
392
+ htmlFor: resolvedControlId ?? undefined,
393
+ onMouseDown: handleInteraction
394
+ } : {
395
+ id,
396
+ onClick: handleInteraction,
397
+ onPointerDown(event) {
398
+ event.preventDefault();
399
+ }
400
+ };
401
+ }
402
+ function focusElementWithVisible(element) {
403
+ element.focus({
404
+ // Available from Chrome 144+ (January 2026).
405
+ // Safari and Firefox already support it.
406
+ // @ts-expect-error not available in types yet
407
+ focusVisible: true
408
+ });
409
+ }
410
+
333
411
  const cache = new Map();
334
412
  function getFormatter(locale, options) {
335
413
  const optionsString = JSON.stringify({
@@ -1822,6 +1900,7 @@ exports.stateAttributesMapping = stateAttributesMapping$1;
1822
1900
  exports.useField = useField;
1823
1901
  exports.useFieldRootContext = useFieldRootContext;
1824
1902
  exports.useFormContext = useFormContext;
1903
+ exports.useLabel = useLabel;
1825
1904
  exports.useLabelableContext = useLabelableContext;
1826
1905
  exports.useLabelableId = useLabelableId;
1827
1906
  exports.useNumberFieldRootContext = useNumberFieldRootContext;
@@ -1,7 +1,7 @@
1
+ import { b as isElement, a as isHTMLElement, k as getWindow } from './floating-ui.utils.dom-es.js';
2
+ import { a as useStableCallback, d as useIsoLayoutEffect, u as useBaseUiId, g as getTarget, o as ownerDocument, h as useOnMount, T as Timeout, i as clamp, j as useControlled, k as useValueAsRef, b as useTimeout, l as isIOS, m as createChangeEventDetails, n as none, v as visuallyHiddenInput, p as visuallyHidden, q as inputChange, r as inputClear, s as inputBlur, w as inputPaste, x as createGenericEventDetails, y as incrementPress, z as decrementPress, A as useButton, B as useValueChanged, C as stopEvent, D as keyboard } from './clamp-es.js';
1
3
  import * as React from 'react';
2
- import { a as useStableCallback, d as useIsoLayoutEffect, u as useBaseUiId, f as useOnMount, T as Timeout, g as clamp, h as useControlled, i as useValueAsRef, b as useTimeout, j as isIOS, k as createChangeEventDetails, n as none, v as visuallyHiddenInput, l as visuallyHidden, m as inputChange, o as inputClear, p as inputBlur, q as inputPaste, r as createGenericEventDetails, s as ownerDocument, w as incrementPress, x as decrementPress, y as useButton, z as useValueChanged, A as stopEvent, B as keyboard } from './clamp-es.js';
3
4
  import { N as NOOP, f as formatErrorMessage, E as EMPTY_OBJECT, a as useRefWithInit, b as useMergedRefs, u as useRenderElement } from './useRenderElement-es.js';
4
- import { b as isElement, k as getWindow } from './floating-ui.utils.dom-es.js';
5
5
  import { jsxs, jsx } from 'react/jsx-runtime';
6
6
  import * as ReactDOM from 'react-dom';
7
7
 
@@ -308,6 +308,84 @@ function useLabelableId(params = {}) {
308
308
  return controlId ?? defaultId;
309
309
  }
310
310
 
311
+ function useRegisteredLabelId(idProp, setLabelId) {
312
+ const id = useBaseUiId(idProp);
313
+ useIsoLayoutEffect(() => {
314
+ setLabelId(id);
315
+ return () => {
316
+ setLabelId(undefined);
317
+ };
318
+ }, [id, setLabelId]);
319
+ return id;
320
+ }
321
+
322
+ function useLabel(params = {}) {
323
+ const {
324
+ id: idProp,
325
+ fallbackControlId,
326
+ native = false,
327
+ setLabelId: setLabelIdProp,
328
+ focusControl: focusControlProp
329
+ } = params;
330
+ const {
331
+ controlId: contextControlId,
332
+ setLabelId: setContextLabelId
333
+ } = useLabelableContext();
334
+ const syncLabelId = useStableCallback(nextLabelId => {
335
+ setContextLabelId(nextLabelId);
336
+ setLabelIdProp?.(nextLabelId);
337
+ });
338
+ const id = useRegisteredLabelId(idProp, syncLabelId);
339
+ const resolvedControlId = contextControlId ?? fallbackControlId;
340
+ function focusControl(event) {
341
+ if (focusControlProp) {
342
+ focusControlProp(event, resolvedControlId);
343
+ return;
344
+ }
345
+ if (!resolvedControlId) {
346
+ return;
347
+ }
348
+ const controlElement = ownerDocument(event.currentTarget).getElementById(resolvedControlId);
349
+ if (isHTMLElement(controlElement)) {
350
+ focusElementWithVisible(controlElement);
351
+ }
352
+ }
353
+ function handleInteraction(event) {
354
+ const target = getTarget(event.nativeEvent);
355
+ if (target?.closest('button,input,select,textarea')) {
356
+ return;
357
+ }
358
+
359
+ // Prevent text selection when double clicking label.
360
+ if (!event.defaultPrevented && event.detail > 1) {
361
+ event.preventDefault();
362
+ }
363
+ if (native) {
364
+ return;
365
+ }
366
+ focusControl(event);
367
+ }
368
+ return native ? {
369
+ id,
370
+ htmlFor: resolvedControlId ?? undefined,
371
+ onMouseDown: handleInteraction
372
+ } : {
373
+ id,
374
+ onClick: handleInteraction,
375
+ onPointerDown(event) {
376
+ event.preventDefault();
377
+ }
378
+ };
379
+ }
380
+ function focusElementWithVisible(element) {
381
+ element.focus({
382
+ // Available from Chrome 144+ (January 2026).
383
+ // Safari and Firefox already support it.
384
+ // @ts-expect-error not available in types yet
385
+ focusVisible: true
386
+ });
387
+ }
388
+
311
389
  const cache = new Map();
312
390
  function getFormatter(locale, options) {
313
391
  const optionsString = JSON.stringify({
@@ -1784,4 +1862,4 @@ const NumberFieldInput = /*#__PURE__*/React.forwardRef(function NumberFieldInput
1784
1862
  });
1785
1863
  if (process.env.NODE_ENV !== "production") NumberFieldInput.displayName = "NumberFieldInput";
1786
1864
 
1787
- export { DEFAULT_VALIDITY_STATE as D, FieldRootContext as F, LabelableContext as L, NumberFieldRoot as N, useFormContext as a, useFieldRootContext as b, NumberFieldGroup as c, NumberFieldInput as d, NumberFieldIncrement as e, fieldValidityMapping as f, getCombinedFieldValidityData as g, NumberFieldDecrement as h, useLabelableId as i, useField as j, DEFAULT_FIELD_STATE_ATTRIBUTES as k, useNumberFieldRootContext as l, DEFAULT_STEP as m, stateAttributesMapping$1 as s, useLabelableContext as u };
1865
+ export { DEFAULT_VALIDITY_STATE as D, FieldRootContext as F, LabelableContext as L, NumberFieldRoot as N, useFormContext as a, useFieldRootContext as b, useLabel as c, NumberFieldGroup as d, NumberFieldInput as e, fieldValidityMapping as f, getCombinedFieldValidityData as g, NumberFieldIncrement as h, NumberFieldDecrement as i, useLabelableId as j, useField as k, DEFAULT_FIELD_STATE_ATTRIBUTES as l, useNumberFieldRootContext as m, DEFAULT_STEP as n, stateAttributesMapping$1 as s, useLabelableContext as u };