@octanejs/aria 0.0.46 → 0.0.48
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.
- package/README.md +7 -6
- package/UPSTREAM.md +58 -69
- package/package.json +11 -11
- package/src/calendar/useCalendarGrid.tsx +64 -62
- package/src/collections/Document.ts +3 -0
- package/src/color/useColorArea.tsx +95 -69
- package/src/color/useColorWheel.tsx +38 -37
- package/src/combobox/{useComboBox.ts → useComboBox.tsx} +243 -258
- package/src/components/ComboBox.ts +35 -2
- package/src/components/Dialog.ts +12 -1
- package/src/components/DropZone.tsx +3 -2
- package/src/components/FileTrigger.tsx +1 -0
- package/src/components/GridList.ts +11 -2
- package/src/components/ListBox.ts +1 -1
- package/src/components/Menu.ts +1 -0
- package/src/components/Meter.ts +3 -1
- package/src/components/Popover.ts +20 -8
- package/src/components/PreviewTrigger.tsx +101 -0
- package/src/components/ProgressBar.ts +10 -2
- package/src/components/Select.ts +1 -1
- package/src/components/Table.ts +26 -15
- package/src/components/TokenField.tsx +395 -0
- package/src/components/Tooltip.ts +4 -6
- package/src/components/Tree.ts +14 -7
- package/src/components/Virtualizer.tsx +30 -14
- package/src/components/index.ts +22 -0
- package/src/components/utils.ts +1 -1
- package/src/datepicker/useDateField.tsx +2 -11
- package/src/datepicker/useDatePickerGroup.tsx +44 -33
- package/src/datepicker/useDateSegment.tsx +31 -30
- package/src/dialog/useDialog.ts +8 -1
- package/src/dnd/DragManager.tsx +5 -1
- package/src/dnd/useDrag.tsx +2 -1
- package/src/focus/FocusScope.ts +2 -2
- package/src/grid/useGrid.ts +3 -0
- package/src/grid/{useGridCell.ts → useGridCell.tsx} +128 -66
- package/src/grid/utils.ts +1 -0
- package/src/gridlist/{useGridListItem.ts → useGridListItem.tsx} +154 -112
- package/src/index.ts +22 -0
- package/src/interactions/createEventHandler.ts +11 -8
- package/src/interactions/createKeyboardShortcutHandler.tsx +218 -0
- package/src/interactions/textSelection.ts +3 -3
- package/src/interactions/useContextMenu.tsx +125 -0
- package/src/interactions/useFocusVisible.ts +4 -4
- package/src/interactions/useKeyboard.ts +50 -2
- package/src/interactions/useLongPress.ts +33 -22
- package/src/interactions/useMove.ts +6 -6
- package/src/interactions/usePress.ts +8 -0
- package/src/interactions/utils.ts +10 -10
- package/src/intl/combobox/fi-FI.json +2 -2
- package/src/intl/previewtrigger/ar-AE.json +3 -0
- package/src/intl/previewtrigger/bg-BG.json +3 -0
- package/src/intl/previewtrigger/cs-CZ.json +3 -0
- package/src/intl/previewtrigger/da-DK.json +3 -0
- package/src/intl/previewtrigger/de-DE.json +3 -0
- package/src/intl/previewtrigger/el-GR.json +3 -0
- package/src/intl/previewtrigger/en-US.json +3 -0
- package/src/intl/previewtrigger/es-ES.json +3 -0
- package/src/intl/previewtrigger/et-EE.json +3 -0
- package/src/intl/previewtrigger/fi-FI.json +3 -0
- package/src/intl/previewtrigger/fr-FR.json +3 -0
- package/src/intl/previewtrigger/he-IL.json +3 -0
- package/src/intl/previewtrigger/hr-HR.json +3 -0
- package/src/intl/previewtrigger/hu-HU.json +3 -0
- package/src/intl/previewtrigger/index.ts +73 -0
- package/src/intl/previewtrigger/it-IT.json +3 -0
- package/src/intl/previewtrigger/ja-JP.json +3 -0
- package/src/intl/previewtrigger/ko-KR.json +3 -0
- package/src/intl/previewtrigger/lt-LT.json +3 -0
- package/src/intl/previewtrigger/lv-LV.json +3 -0
- package/src/intl/previewtrigger/nb-NO.json +3 -0
- package/src/intl/previewtrigger/nl-NL.json +3 -0
- package/src/intl/previewtrigger/pl-PL.json +3 -0
- package/src/intl/previewtrigger/pt-BR.json +3 -0
- package/src/intl/previewtrigger/pt-PT.json +3 -0
- package/src/intl/previewtrigger/ro-RO.json +3 -0
- package/src/intl/previewtrigger/ru-RU.json +3 -0
- package/src/intl/previewtrigger/sk-SK.json +3 -0
- package/src/intl/previewtrigger/sl-SI.json +3 -0
- package/src/intl/previewtrigger/sr-SP.json +3 -0
- package/src/intl/previewtrigger/sv-SE.json +3 -0
- package/src/intl/previewtrigger/tr-TR.json +3 -0
- package/src/intl/previewtrigger/uk-UA.json +3 -0
- package/src/intl/previewtrigger/zh-CN.json +3 -0
- package/src/intl/previewtrigger/zh-TW.json +3 -0
- package/src/intl/table/ar-AE.json +3 -3
- package/src/intl/table/bg-BG.json +3 -3
- package/src/intl/table/cs-CZ.json +3 -3
- package/src/intl/table/da-DK.json +3 -3
- package/src/intl/table/de-DE.json +3 -3
- package/src/intl/table/el-GR.json +3 -3
- package/src/intl/table/es-ES.json +3 -3
- package/src/intl/table/et-EE.json +3 -3
- package/src/intl/table/fi-FI.json +3 -3
- package/src/intl/table/fr-FR.json +3 -3
- package/src/intl/table/he-IL.json +3 -3
- package/src/intl/table/hr-HR.json +3 -3
- package/src/intl/table/hu-HU.json +3 -3
- package/src/intl/table/it-IT.json +3 -3
- package/src/intl/table/ja-JP.json +3 -3
- package/src/intl/table/ko-KR.json +3 -3
- package/src/intl/table/lt-LT.json +3 -3
- package/src/intl/table/lv-LV.json +3 -3
- package/src/intl/table/nb-NO.json +3 -3
- package/src/intl/table/nl-NL.json +3 -3
- package/src/intl/table/pl-PL.json +3 -3
- package/src/intl/table/pt-BR.json +3 -3
- package/src/intl/table/pt-PT.json +3 -3
- package/src/intl/table/ro-RO.json +3 -3
- package/src/intl/table/ru-RU.json +3 -3
- package/src/intl/table/sk-SK.json +3 -3
- package/src/intl/table/sl-SI.json +3 -3
- package/src/intl/table/sr-SP.json +3 -3
- package/src/intl/table/sv-SE.json +3 -3
- package/src/intl/table/tr-TR.json +3 -3
- package/src/intl/table/uk-UA.json +3 -3
- package/src/intl/table/zh-CN.json +4 -4
- package/src/intl/table/zh-TW.json +3 -3
- package/src/intl/tree/es-ES.json +1 -1
- package/src/link/useLink.ts +2 -0
- package/src/menu/useMenuItem.ts +33 -36
- package/src/menu/useMenuTrigger.tsx +222 -0
- package/src/menu/{useSubmenuTrigger.ts → useSubmenuTrigger.tsx} +116 -151
- package/src/numberfield/{useNumberField.ts → useNumberField.tsx} +188 -238
- package/src/overlays/Overlay.ts +5 -1
- package/src/overlays/ariaHideOutside.ts +6 -8
- package/src/overlays/useCloseOnScroll.ts +7 -5
- package/src/overlays/{useOverlay.ts → useOverlay.tsx} +76 -83
- package/src/overlays/usePopover.ts +10 -5
- package/src/overlays/usePreventScroll.ts +4 -4
- package/src/progress/useProgressBar.ts +2 -1
- package/src/radio/{useRadioGroup.ts → useRadioGroup.tsx} +87 -79
- package/src/searchfield/useSearchField.tsx +152 -0
- package/src/select/useSelect.ts +20 -20
- package/src/selection/useSelectableCollection.tsx +755 -0
- package/src/selection/useSelectableItem.ts +48 -11
- package/src/slider/{useSliderThumb.ts → useSliderThumb.tsx} +120 -158
- package/src/spinbutton/useSpinButton.tsx +335 -0
- package/src/stately/combobox/useComboBoxState.ts +1 -1
- package/src/stately/grid/useGridState.ts +9 -10
- package/src/stately/index.ts +11 -0
- package/src/stately/menu/useMenuTriggerState.ts +1 -1
- package/src/stately/menu/useSubmenuTriggerState.ts +2 -0
- package/src/stately/overlays/useOverlayTriggerState.ts +12 -1
- package/src/stately/radio/useRadioGroupState.ts +5 -1
- package/src/stately/table/TableUtils.ts +15 -1
- package/src/stately/table/useTableState.ts +7 -0
- package/src/stately/tokenfield/TokenFieldValue.tsx +440 -0
- package/src/stately/tokenfield/useTokenFieldState.tsx +57 -0
- package/src/stately/tooltip/useTooltipTriggerState.ts +16 -7
- package/src/stately/virtualizer/Layout.tsx +2 -0
- package/src/stately/virtualizer/ScrollAnchor.tsx +338 -0
- package/src/stately/virtualizer/Virtualizer.tsx +52 -1
- package/src/stately/virtualizer/types.tsx +2 -0
- package/src/table/useTableCell.ts +12 -0
- package/src/table/useTableColumnHeader.ts +8 -1
- package/src/table/useTableColumnResize.tsx +359 -0
- package/src/tag/useTag.ts +22 -15
- package/src/textfield/useTextField.ts +2 -0
- package/src/tokenfield/useToken.tsx +64 -0
- package/src/tokenfield/useTokenField.tsx +849 -0
- package/src/tooltip/usePreviewTrigger.tsx +266 -0
- package/src/tooltip/useSafeArea.tsx +171 -0
- package/src/upstream-exports/react-aria/mergeRefs.tsx +3 -0
- package/src/upstream-exports/react-aria/usePreviewTrigger.tsx +18 -0
- package/src/upstream-exports/react-aria/useTokenField.tsx +22 -0
- package/src/upstream-exports/react-stately/private/collections/getChildNodes.tsx +8 -0
- package/src/upstream-exports/react-stately/private/collections/getItemCount.tsx +2 -0
- package/src/upstream-exports/react-stately/private/grid/GridCollection.tsx +7 -0
- package/src/upstream-exports/react-stately/private/grid/useGridState.tsx +6 -0
- package/src/upstream-exports/react-stately/private/utils/number.tsx +2 -0
- package/src/upstream-exports/react-stately/useComboBoxState.tsx +23 -0
- package/src/upstream-exports/react-stately/useListState.tsx +15 -0
- package/src/upstream-exports/react-stately/useMenuTriggerState.tsx +26 -0
- package/src/upstream-exports/react-stately/useMultipleSelectionState.tsx +21 -0
- package/src/upstream-exports/react-stately/useNumberFieldState.tsx +20 -0
- package/src/upstream-exports/react-stately/useOverlayTriggerState.tsx +20 -0
- package/src/upstream-exports/react-stately/useRadioGroupState.tsx +16 -0
- package/src/upstream-exports/react-stately/useSearchFieldState.tsx +19 -0
- package/src/upstream-exports/react-stately/useSliderState.tsx +20 -0
- package/src/upstream-exports/react-stately/useTableState.tsx +45 -0
- package/src/upstream-exports/react-stately/useTokenFieldState.tsx +25 -0
- package/src/upstream-exports/react-stately/useTooltipTriggerState.tsx +20 -0
- package/src/upstream-exports/react-stately/useTreeState.tsx +14 -0
- package/src/utils/domHelpers.ts +74 -17
- package/src/utils/isVirtualEvent.ts +2 -1
- package/src/utils/openLink.ts +8 -3
- package/src/utils/platform.ts +7 -3
- package/src/utils/scrollIntoView.ts +4 -4
- package/src/utils/shadowdom/DOMFunctions.ts +42 -2
- package/src/utils/useId.ts +11 -2
- package/src/utils/useLoadMoreSentinel.ts +8 -3
- package/src/utils/useViewportSize.ts +3 -3
- package/src/virtualizer/ScrollView.tsx +13 -4
- package/src/virtualizer/VirtualizerItem.tsx +4 -1
- package/src/virtualizer/useVirtualizerItem.tsx +43 -3
- package/src/menu/useMenuTrigger.ts +0 -189
- package/src/searchfield/useSearchField.ts +0 -156
- package/src/selection/useSelectableCollection.ts +0 -750
- package/src/spinbutton/useSpinButton.ts +0 -380
- package/src/table/useTableColumnResize.ts +0 -374
|
@@ -24,6 +24,7 @@ import { focusSafely } from '../interactions/focusSafely';
|
|
|
24
24
|
import { getActiveElement, getEventTarget } from '../utils/shadowdom/DOMFunctions';
|
|
25
25
|
import { getCollectionId, isNonContiguousSelectionModifier } from './utils';
|
|
26
26
|
import { isCtrlKeyPressed } from '../utils/keyboard';
|
|
27
|
+
import { isTabbable } from '../utils/isFocusable';
|
|
27
28
|
import { mergeProps } from '../utils/mergeProps';
|
|
28
29
|
import { moveVirtualFocus } from '../focus/virtualFocus';
|
|
29
30
|
import type { MultipleSelectionManager } from '../stately/selection/types';
|
|
@@ -380,7 +381,8 @@ export function useSelectableItem(...args: any[]): SelectableItemAria {
|
|
|
380
381
|
};
|
|
381
382
|
}
|
|
382
383
|
|
|
383
|
-
|
|
384
|
+
let collectionId = getCollectionId(manager.collection);
|
|
385
|
+
itemProps['data-collection'] = collectionId;
|
|
384
386
|
itemProps['data-key'] = key;
|
|
385
387
|
itemPressProps.preventFocusOnPress = shouldUseVirtualFocus;
|
|
386
388
|
|
|
@@ -470,17 +472,52 @@ export function useSelectableItem(...args: any[]): SelectableItemAria {
|
|
|
470
472
|
}
|
|
471
473
|
: undefined;
|
|
472
474
|
|
|
475
|
+
let mergedItemProps = mergeProps(
|
|
476
|
+
itemProps,
|
|
477
|
+
allowsSelection || hasPrimaryAction || (shouldUseVirtualFocus && !isDisabled) ? pressProps : {},
|
|
478
|
+
longPressEnabled ? longPressProps : {},
|
|
479
|
+
{ onDoubleClick, onDragStartCapture, onClick, id },
|
|
480
|
+
// Prevent DOM focus from moving on mouse down when using virtual focus
|
|
481
|
+
shouldUseVirtualFocus ? { onMouseDown: (e: MouseEvent) => e.preventDefault() } : undefined,
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
// Guard against presses triggering selection when they happen on interactive children or collection items from different collections
|
|
485
|
+
// will need to trigger selection if the target is itself a collection item belonging to the same collection parent (aka a cell in a row) but
|
|
486
|
+
// not if the target is a child of a different collections aka taggroup in table cell.
|
|
487
|
+
let isChildInteraction = (target: Element) => {
|
|
488
|
+
let el: Element | null = target;
|
|
489
|
+
while (el && el !== ref.current) {
|
|
490
|
+
let elCollection = el.getAttribute('data-collection');
|
|
491
|
+
if (elCollection != null) {
|
|
492
|
+
return elCollection !== collectionId;
|
|
493
|
+
}
|
|
494
|
+
el = el.parentElement;
|
|
495
|
+
}
|
|
496
|
+
return isTabbable(target);
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
let baseOnPointerDown = mergedItemProps.onPointerDown;
|
|
500
|
+
mergedItemProps.onPointerDown = (e: PointerEvent) => {
|
|
501
|
+
let target = getEventTarget(e) as Element | null;
|
|
502
|
+
if (target && target !== ref.current && isChildInteraction(target)) {
|
|
503
|
+
e.stopPropagation();
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
baseOnPointerDown?.(e);
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
let baseOnMouseDown = mergedItemProps.onMouseDown;
|
|
510
|
+
mergedItemProps.onMouseDown = (e) => {
|
|
511
|
+
let target = getEventTarget(e) as Element | null;
|
|
512
|
+
if (target && target !== ref.current && isChildInteraction(target)) {
|
|
513
|
+
e.stopPropagation();
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
baseOnMouseDown?.(e);
|
|
517
|
+
};
|
|
518
|
+
|
|
473
519
|
return {
|
|
474
|
-
itemProps:
|
|
475
|
-
itemProps,
|
|
476
|
-
allowsSelection || hasPrimaryAction || (shouldUseVirtualFocus && !isDisabled)
|
|
477
|
-
? pressProps
|
|
478
|
-
: {},
|
|
479
|
-
longPressEnabled ? longPressProps : {},
|
|
480
|
-
{ onDoubleClick, onDragStartCapture, onClick, id },
|
|
481
|
-
// Prevent DOM focus from moving on mouse down when using virtual focus
|
|
482
|
-
shouldUseVirtualFocus ? { onMouseDown: (e: MouseEvent) => e.preventDefault() } : undefined,
|
|
483
|
-
),
|
|
520
|
+
itemProps: mergedItemProps,
|
|
484
521
|
isPressed,
|
|
485
522
|
isSelected: manager.isSelected(key),
|
|
486
523
|
isFocused: manager.isFocused && manager.focusedKey === key,
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
// on the native `input` event, so the timing is identical — this mirrors how the browser
|
|
6
|
-
// reports native keyboard/drag stepping of a range input).
|
|
7
|
-
// - React's InputHTMLAttributes/LabelHTMLAttributes element types collapse to the local
|
|
8
|
-
// structural `DOMAttributes` prop bag; mouse/pointer/touch handler params are native.
|
|
9
|
-
// - `clamp` comes from the ported stately number utils; `SliderState` from the ported
|
|
10
|
-
// stately slider hook.
|
|
11
|
-
// - Public-hook slot threading (splitSlot/subSlot); explicit dependency arrays are kept
|
|
12
|
-
// verbatim.
|
|
13
|
-
import type {
|
|
1
|
+
/** @jsxImportSource octane */
|
|
2
|
+
type DOMAttributes = Record<string, any>;
|
|
3
|
+
// Ported from adobe/react-spectrum@5ecb3333001313e83898cd07644227897e3bae1f (packages/react-aria/src/slider/useSliderThumb.ts).
|
|
4
|
+
import {
|
|
14
5
|
AriaLabelingProps,
|
|
15
6
|
AriaValidationProps,
|
|
16
7
|
DOMProps,
|
|
@@ -21,15 +12,22 @@ import type {
|
|
|
21
12
|
RefObject,
|
|
22
13
|
ValidationState,
|
|
23
14
|
} from '@react-types/shared';
|
|
24
|
-
// octane adaptation: FocusableProps is the ported native-event version.
|
|
25
15
|
import type { FocusableProps } from '../interactions/useFocusable';
|
|
26
|
-
import { clamp } from '../stately/utils/number';
|
|
16
|
+
import { clamp } from '../upstream-exports/react-stately/private/utils/number';
|
|
27
17
|
import { focusWithoutScrolling } from '../utils/focusWithoutScrolling';
|
|
28
18
|
import { getEventTarget } from '../utils/shadowdom/DOMFunctions';
|
|
29
19
|
import { getSliderThumbId, sliderData } from './utils';
|
|
30
20
|
import { mergeProps } from '../utils/mergeProps';
|
|
31
|
-
import {
|
|
32
|
-
import
|
|
21
|
+
import { withSlot } from 'octane';
|
|
22
|
+
import React, {
|
|
23
|
+
ChangeEvent,
|
|
24
|
+
InputHTMLAttributes,
|
|
25
|
+
LabelHTMLAttributes,
|
|
26
|
+
useCallback,
|
|
27
|
+
useEffect,
|
|
28
|
+
useRef,
|
|
29
|
+
} from '../compat/react';
|
|
30
|
+
import { SliderState } from '../upstream-exports/react-stately/useSliderState';
|
|
33
31
|
import { useFocusable } from '../interactions/useFocusable';
|
|
34
32
|
import { useFormReset } from '../utils/useFormReset';
|
|
35
33
|
import { useGlobalListeners } from '../utils/useGlobalListeners';
|
|
@@ -38,12 +36,6 @@ import { useLabel } from '../label/useLabel';
|
|
|
38
36
|
import { useLocale } from '../i18n/I18nProvider';
|
|
39
37
|
import { useMove } from '../interactions/useMove';
|
|
40
38
|
|
|
41
|
-
import { S, splitSlot, subSlot } from '../internal';
|
|
42
|
-
|
|
43
|
-
// octane adaptation: minimal structural DOMAttributes (upstream's drags React's synthetic
|
|
44
|
-
// handler types along).
|
|
45
|
-
type DOMAttributes = Record<string, any>;
|
|
46
|
-
|
|
47
39
|
export interface SliderThumbProps extends FocusableProps, LabelableProps {
|
|
48
40
|
/**
|
|
49
41
|
* The orientation of the Slider.
|
|
@@ -82,10 +74,10 @@ export interface SliderThumbAria {
|
|
|
82
74
|
thumbProps: DOMAttributes;
|
|
83
75
|
|
|
84
76
|
/** Props for the visually hidden range input element. */
|
|
85
|
-
inputProps:
|
|
77
|
+
inputProps: InputHTMLAttributes<HTMLInputElement>;
|
|
86
78
|
|
|
87
79
|
/** Props for the label element for this thumb (optional). */
|
|
88
|
-
labelProps:
|
|
80
|
+
labelProps: LabelHTMLAttributes<HTMLLabelElement>;
|
|
89
81
|
|
|
90
82
|
/** Whether this thumb is currently being dragged. */
|
|
91
83
|
isDragging: boolean;
|
|
@@ -108,18 +100,14 @@ export interface AriaSliderThumbOptions extends AriaSliderThumbProps {
|
|
|
108
100
|
* @param opts Options for this Slider thumb.
|
|
109
101
|
* @param state Slider state, created via `useSliderState`.
|
|
110
102
|
*/
|
|
111
|
-
export function useSliderThumb(opts: AriaSliderThumbOptions, state: SliderState): SliderThumbAria;
|
|
112
|
-
// Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
|
|
113
103
|
export function useSliderThumb(
|
|
114
104
|
opts: AriaSliderThumbOptions,
|
|
115
105
|
state: SliderState,
|
|
116
|
-
|
|
117
|
-
): SliderThumbAria
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const opts = user[0] as AriaSliderThumbOptions;
|
|
122
|
-
const state = user[1] as SliderState;
|
|
106
|
+
_slot?: symbol,
|
|
107
|
+
): SliderThumbAria {
|
|
108
|
+
if (_slot !== undefined) {
|
|
109
|
+
return withSlot(_slot, useSliderThumb, opts, state);
|
|
110
|
+
}
|
|
123
111
|
|
|
124
112
|
let {
|
|
125
113
|
index = 0,
|
|
@@ -136,129 +124,105 @@ export function useSliderThumb(...args: any[]): SliderThumbAria {
|
|
|
136
124
|
let isDisabled = opts.isDisabled || state.isDisabled;
|
|
137
125
|
let isVertical = orientation === 'vertical';
|
|
138
126
|
|
|
139
|
-
let { direction } = useLocale(
|
|
140
|
-
let { addGlobalListener, removeGlobalListener } = useGlobalListeners(
|
|
141
|
-
subSlot(slot, 'globalListeners'),
|
|
142
|
-
);
|
|
127
|
+
let { direction } = useLocale();
|
|
128
|
+
let { addGlobalListener, removeGlobalListener } = useGlobalListeners();
|
|
143
129
|
|
|
144
130
|
let data = sliderData.get(state)!;
|
|
145
|
-
const { labelProps, fieldProps } = useLabel(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
},
|
|
151
|
-
subSlot(slot, 'label'),
|
|
152
|
-
);
|
|
131
|
+
const { labelProps, fieldProps } = useLabel({
|
|
132
|
+
...opts,
|
|
133
|
+
id: getSliderThumbId(state, index),
|
|
134
|
+
'aria-labelledby': `${data.id} ${opts['aria-labelledby'] ?? ''}`.trim(),
|
|
135
|
+
});
|
|
153
136
|
|
|
154
137
|
const value = state.values[index];
|
|
155
138
|
|
|
156
|
-
const focusInput = useCallback(
|
|
157
|
-
()
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
},
|
|
162
|
-
[inputRef],
|
|
163
|
-
subSlot(slot, 'focusInput'),
|
|
164
|
-
);
|
|
139
|
+
const focusInput = useCallback(() => {
|
|
140
|
+
if (inputRef.current) {
|
|
141
|
+
focusWithoutScrolling(inputRef.current);
|
|
142
|
+
}
|
|
143
|
+
}, [inputRef]);
|
|
165
144
|
|
|
166
145
|
const isFocused = state.focusedThumb === index;
|
|
167
146
|
|
|
168
|
-
useEffect(
|
|
169
|
-
()
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
},
|
|
174
|
-
[isFocused, focusInput],
|
|
175
|
-
subSlot(slot, 'focusFx'),
|
|
176
|
-
);
|
|
147
|
+
useEffect(() => {
|
|
148
|
+
if (isFocused) {
|
|
149
|
+
focusInput();
|
|
150
|
+
}
|
|
151
|
+
}, [isFocused, focusInput]);
|
|
177
152
|
|
|
178
153
|
let reverseX = direction === 'rtl';
|
|
179
|
-
let currentPosition = useRef<number | null>(null
|
|
154
|
+
let currentPosition = useRef<number | null>(null);
|
|
180
155
|
|
|
181
|
-
let
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
case 'Home':
|
|
210
|
-
setThumbValue(index, getThumbMinValue(index));
|
|
211
|
-
break;
|
|
212
|
-
case 'End':
|
|
213
|
-
setThumbValue(index, getThumbMaxValue(index));
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
setThumbDragging(index, false);
|
|
156
|
+
let keyboardUpdate = (cb: () => void) => {
|
|
157
|
+
// remember to set this so that onChangeEnd is fired
|
|
158
|
+
state.setThumbDragging(index, true);
|
|
159
|
+
cb();
|
|
160
|
+
state.setThumbDragging(index, false);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
let { keyboardProps } = useKeyboard({
|
|
164
|
+
shortcuts: {
|
|
165
|
+
PageUp: () => {
|
|
166
|
+
return keyboardUpdate(() => {
|
|
167
|
+
state.incrementThumb(index, state.pageSize);
|
|
168
|
+
});
|
|
169
|
+
},
|
|
170
|
+
PageDown: () => {
|
|
171
|
+
return keyboardUpdate(() => {
|
|
172
|
+
state.decrementThumb(index, state.pageSize);
|
|
173
|
+
});
|
|
174
|
+
},
|
|
175
|
+
Home: () => {
|
|
176
|
+
return keyboardUpdate(() => {
|
|
177
|
+
state.setThumbValue(index, state.getThumbMinValue(index));
|
|
178
|
+
});
|
|
179
|
+
},
|
|
180
|
+
End: () => {
|
|
181
|
+
return keyboardUpdate(() => {
|
|
182
|
+
state.setThumbValue(index, state.getThumbMaxValue(index));
|
|
183
|
+
});
|
|
217
184
|
},
|
|
218
185
|
},
|
|
219
|
-
|
|
220
|
-
);
|
|
186
|
+
allowRepeats: true,
|
|
187
|
+
});
|
|
221
188
|
|
|
222
|
-
let { moveProps } = useMove(
|
|
223
|
-
{
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
let size = isVertical ? height : width;
|
|
189
|
+
let { moveProps } = useMove({
|
|
190
|
+
onMoveStart() {
|
|
191
|
+
currentPosition.current = null;
|
|
192
|
+
state.setThumbDragging(index, true);
|
|
193
|
+
},
|
|
194
|
+
onMove({ deltaX, deltaY, pointerType, shiftKey }: import('@react-types/shared').MoveMoveEvent) {
|
|
195
|
+
const { getThumbPercent, setThumbPercent, decrementThumb, incrementThumb, step, pageSize } =
|
|
196
|
+
state;
|
|
197
|
+
if (!trackRef.current) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
let { width, height } = trackRef.current.getBoundingClientRect();
|
|
201
|
+
let size = isVertical ? height : width;
|
|
236
202
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
} else {
|
|
244
|
-
incrementThumb(index, shiftKey ? pageSize : step);
|
|
245
|
-
}
|
|
203
|
+
if (currentPosition.current == null) {
|
|
204
|
+
currentPosition.current = getThumbPercent(index) * size;
|
|
205
|
+
}
|
|
206
|
+
if (pointerType === 'keyboard') {
|
|
207
|
+
if ((deltaX > 0 && reverseX) || (deltaX < 0 && !reverseX) || deltaY > 0) {
|
|
208
|
+
decrementThumb(index, shiftKey ? pageSize : step);
|
|
246
209
|
} else {
|
|
247
|
-
|
|
248
|
-
if (isVertical || reverseX) {
|
|
249
|
-
delta = -delta;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
currentPosition.current += delta;
|
|
253
|
-
setThumbPercent(index, clamp(currentPosition.current / size, 0, 1));
|
|
210
|
+
incrementThumb(index, shiftKey ? pageSize : step);
|
|
254
211
|
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
212
|
+
} else {
|
|
213
|
+
let delta = isVertical ? deltaY : deltaX;
|
|
214
|
+
if (isVertical || reverseX) {
|
|
215
|
+
delta = -delta;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
currentPosition.current += delta;
|
|
219
|
+
setThumbPercent(index, clamp(currentPosition.current / size, 0, 1));
|
|
220
|
+
}
|
|
259
221
|
},
|
|
260
|
-
|
|
261
|
-
|
|
222
|
+
onMoveEnd() {
|
|
223
|
+
state.setThumbDragging(index, false);
|
|
224
|
+
},
|
|
225
|
+
});
|
|
262
226
|
|
|
263
227
|
// Immediately register editability with the state
|
|
264
228
|
state.setThumbEditable(index, !isDisabled);
|
|
@@ -269,10 +233,9 @@ export function useSliderThumb(...args: any[]): SliderThumbAria {
|
|
|
269
233
|
onBlur: () => state.setFocusedThumb(undefined),
|
|
270
234
|
}),
|
|
271
235
|
inputRef,
|
|
272
|
-
subSlot(slot, 'focusable'),
|
|
273
236
|
);
|
|
274
237
|
|
|
275
|
-
let currentPointer = useRef<number | undefined>(undefined
|
|
238
|
+
let currentPointer = useRef<number | undefined>(undefined);
|
|
276
239
|
let onDown = (id?: number) => {
|
|
277
240
|
focusInput();
|
|
278
241
|
currentPointer.current = id;
|
|
@@ -283,8 +246,13 @@ export function useSliderThumb(...args: any[]): SliderThumbAria {
|
|
|
283
246
|
addGlobalListener(window, 'pointerup', onUp, false);
|
|
284
247
|
};
|
|
285
248
|
|
|
286
|
-
let onUp = (e:
|
|
287
|
-
let id =
|
|
249
|
+
let onUp = (e: globalThis.PointerEvent | globalThis.TouchEvent | globalThis.MouseEvent) => {
|
|
250
|
+
let id =
|
|
251
|
+
'pointerId' in e
|
|
252
|
+
? e.pointerId
|
|
253
|
+
: 'changedTouches' in e
|
|
254
|
+
? e.changedTouches[0]?.identifier
|
|
255
|
+
: undefined;
|
|
288
256
|
if (id === currentPointer.current) {
|
|
289
257
|
focusInput();
|
|
290
258
|
state.setThumbDragging(index, false);
|
|
@@ -300,38 +268,34 @@ export function useSliderThumb(...args: any[]): SliderThumbAria {
|
|
|
300
268
|
}
|
|
301
269
|
|
|
302
270
|
let interactions = !isDisabled
|
|
303
|
-
?
|
|
304
|
-
|
|
271
|
+
? // oxlint-disable-next-line react/react-compiler
|
|
272
|
+
mergeProps(keyboardProps, moveProps, {
|
|
273
|
+
onMouseDown: (e: React.MouseEvent) => {
|
|
305
274
|
if (e.button !== 0 || e.altKey || e.ctrlKey || e.metaKey) {
|
|
306
275
|
return;
|
|
307
276
|
}
|
|
308
277
|
onDown();
|
|
309
278
|
},
|
|
310
|
-
onPointerDown: (e: PointerEvent) => {
|
|
279
|
+
onPointerDown: (e: React.PointerEvent) => {
|
|
311
280
|
if (e.button !== 0 || e.altKey || e.ctrlKey || e.metaKey) {
|
|
312
281
|
return;
|
|
313
282
|
}
|
|
314
283
|
onDown(e.pointerId);
|
|
315
284
|
},
|
|
316
|
-
onTouchStart: (e: TouchEvent) => {
|
|
285
|
+
onTouchStart: (e: React.TouchEvent) => {
|
|
317
286
|
onDown(e.changedTouches[0].identifier);
|
|
318
287
|
},
|
|
319
288
|
})
|
|
320
289
|
: {};
|
|
321
290
|
|
|
322
|
-
useFormReset(
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
(v) => {
|
|
326
|
-
state.setThumbValue(index, v);
|
|
327
|
-
},
|
|
328
|
-
subSlot(slot, 'reset'),
|
|
329
|
-
);
|
|
291
|
+
useFormReset(inputRef, state.defaultValues[index], (v) => {
|
|
292
|
+
state.setThumbValue(index, v);
|
|
293
|
+
});
|
|
330
294
|
|
|
331
295
|
// We install mouse handlers for the drag motion on the thumb div, but
|
|
332
296
|
// not the key handler for moving the thumb with the slider. Instead,
|
|
333
297
|
// we focus the range input, and let the browser handle the keyboard
|
|
334
|
-
// interactions; we then listen to input's
|
|
298
|
+
// interactions; we then listen to input's onChange to update state.
|
|
335
299
|
return {
|
|
336
300
|
inputProps: mergeProps(focusableProps, fieldProps, {
|
|
337
301
|
type: 'range',
|
|
@@ -352,8 +316,6 @@ export function useSliderThumb(...args: any[]): SliderThumbAria {
|
|
|
352
316
|
.filter(Boolean)
|
|
353
317
|
.join(' '),
|
|
354
318
|
'aria-details': [data['aria-details'], opts['aria-details']].filter(Boolean).join(' '),
|
|
355
|
-
// octane adaptation: React's synthetic onChange for range inputs rides the
|
|
356
|
-
// native `input` event — onInput is the direct equivalent.
|
|
357
319
|
onInput: (e: Event) => {
|
|
358
320
|
state.setThumbValue(index, parseFloat((getEventTarget(e) as HTMLInputElement).value));
|
|
359
321
|
},
|