@octanejs/aria 0.0.47 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octanejs/aria",
3
- "version": "0.0.47",
3
+ "version": "0.0.48",
4
4
  "license": "MIT AND Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -56,7 +56,7 @@
56
56
  "octane": "^0.1.51 || ^0.2.0"
57
57
  },
58
58
  "devDependencies": {
59
- "@tsrx/react": "^0.2.69",
59
+ "@tsrx/react": "^0.2.71",
60
60
  "esbuild": "^0.28.1",
61
61
  "react": "19.2.7",
62
62
  "react-aria": "3.51.0",
@@ -65,7 +65,7 @@
65
65
  "react-stately": "3.49.0",
66
66
  "typescript": "^5.9.3",
67
67
  "vitest": "^4.1.10",
68
- "octane": "0.2.7"
68
+ "octane": "0.2.8"
69
69
  },
70
70
  "scripts": {
71
71
  "exports:check": "node scripts/check-react-aria-components-exports.mjs",
@@ -47,6 +47,7 @@ import {
47
47
  import { getActiveElement, getEventTarget, nodeContains } from '../utils/shadowdom/DOMFunctions';
48
48
  import { getChildNodes } from '../upstream-exports/react-stately/private/collections/getChildNodes';
49
49
  import { getItemCount } from '../upstream-exports/react-stately/private/collections/getItemCount';
50
+ import { withSlot } from 'octane';
50
51
  import { getItemId, listData } from '../listbox/utils';
51
52
  import { getOwnerDocument } from '../utils/domHelpers';
52
53
  import intlMessages from '../intl/combobox/index';
@@ -131,6 +132,10 @@ export function useComboBox<T, M extends SelectionMode = 'single'>(
131
132
  state: ComboBoxState<T, M>,
132
133
  _slot?: symbol,
133
134
  ): ComboBoxAria<T> {
135
+ if (_slot !== undefined) {
136
+ return withSlot(_slot, useComboBox<T, M>, props, state);
137
+ }
138
+
134
139
  let {
135
140
  buttonRef,
136
141
  popoverRef,
@@ -1386,7 +1386,7 @@ export interface TreeSectionProps<T> extends SectionProps<T>, DOMRenderProps<'di
1386
1386
  * A TreeSection represents a section within a Tree.
1387
1387
  */
1388
1388
  export const TreeSection: <T extends object = object>(
1389
- props: GridListHeaderProps & { ref?: any },
1389
+ props: TreeSectionProps<T> & { ref?: any },
1390
1390
  ) => any = /*#__PURE__*/ createBranchComponent(SectionNode, function TreeSection<
1391
1391
  T,
1392
1392
  >(props: TreeSectionProps<T>, forwardedRef: any, item?: Node<T>): any {
@@ -61,7 +61,7 @@ export function useDialog(...args: any[]): DialogAria {
61
61
  let titleId: string | undefined = useSlotId(undefined, subSlot(slot, 'title'));
62
62
  titleId = props['aria-label'] ? undefined : titleId;
63
63
 
64
- let contentId: string | undefined = useSlotId();
64
+ let contentId: string | undefined = useSlotId(undefined, subSlot(slot, 'content'));
65
65
  contentId = role === 'alertdialog' && !props['aria-describedby'] ? contentId : undefined;
66
66
 
67
67
  let isRefocusing = useRef(false, subSlot(slot, 'refocusing'));
@@ -14,6 +14,7 @@ type DOMAttributes = Record<string, any>;
14
14
  */
15
15
 
16
16
  import { FocusableElement, Key, RefObject } from '@react-types/shared';
17
+ import { withSlot } from 'octane';
17
18
  import { focusSafely } from '../interactions/focusSafely';
18
19
  import {
19
20
  getActiveElement,
@@ -89,6 +90,10 @@ export function useGridCell<T, C extends GridCollection<T>>(
89
90
  ref: RefObject<FocusableElement | null>,
90
91
  _slot?: symbol,
91
92
  ): GridCellAria {
93
+ if (_slot !== undefined) {
94
+ return withSlot(_slot, useGridCell<T, C>, props, state, ref);
95
+ }
96
+
92
97
  let {
93
98
  node,
94
99
  isVirtualized,
@@ -27,6 +27,7 @@ import { getOwnerDocument } from '../utils/domHelpers';
27
27
  import { getRowId, listMap } from './utils';
28
28
  import { getScrollParent } from '../utils/getScrollParent';
29
29
  import { HTMLAttributes, KeyboardEvent as ReactKeyboardEvent, useRef } from '../compat/react';
30
+ import { withSlot } from 'octane';
30
31
  import { isFocusVisible } from '../interactions/useFocusVisible';
31
32
  import type { ListState } from '../upstream-exports/react-stately/useListState';
32
33
  import { mergeProps } from '../utils/mergeProps';
@@ -97,6 +98,10 @@ export function useGridListItem<T>(
97
98
  ref: RefObject<FocusableElement | null>,
98
99
  _slot?: symbol,
99
100
  ): GridListItemAria {
101
+ if (_slot !== undefined) {
102
+ return withSlot(_slot, useGridListItem<T>, props, state, ref);
103
+ }
104
+
100
105
  // Copied from useGridCell + some modifications to make it not so grid specific
101
106
  let { node, isVirtualized, focusMode = 'row', allowsArrowNavigation } = props;
102
107
 
@@ -438,16 +443,12 @@ export function useGridListItem<T>(
438
443
  rowProps.tabIndex = -1;
439
444
  }
440
445
 
441
- // we need to guard against space/enter triggering selection/row link via usePress (from itemProps) so check if propagation
442
- // is stopped. this also fixes space not working in a textfield in a tree parent row
446
+ // Keep Space/Enter on a child control from reaching the row's usePress handler. With native
447
+ // events, stopPropagation() marks cancelBubble rather than exposing isPropagationStopped().
443
448
  let baseOnKeyDown = rowProps.onKeyDown;
444
449
  rowProps.onKeyDown = (e: ReactKeyboardEvent<FocusableElement>) => {
445
450
  onKeyDown(e as ReactKeyboardEvent);
446
- if (!(
447
- 'isPropagationStopped' in e &&
448
- typeof e.isPropagationStopped === 'function' &&
449
- e.isPropagationStopped()
450
- )) {
451
+ if (!e.cancelBubble) {
451
452
  baseOnKeyDown?.(e);
452
453
  }
453
454
  };
@@ -1,4 +1,3 @@
1
- import { chain } from '../utils/chain';
2
1
  import {
3
2
  createKeyboardShortcutHandler,
4
3
  type KeyboardShortcutBindings,
@@ -8,6 +7,7 @@ import { getEventTarget, nodeContains } from '../utils/shadowdom/DOMFunctions';
8
7
  // octane adaptations:
9
8
  // - `KeyboardEvents` / `DOMAttributes` from '@react-types/shared' are typed over React's
10
9
  // synthetic events; local structural aliases over native KeyboardEvent replace them.
10
+ // - Shortcut and user callbacks share the BaseEvent wrapper so both have propagation controls.
11
11
  // - Public-hook slot threading (splitSlot) per the binding convention; no octane base hooks
12
12
  // are composed here, so the slot is absorbed and unused.
13
13
  import type { BaseEvent } from './createEventHandler';
@@ -53,7 +53,8 @@ export function useKeyboard(...args: any[]): KeyboardResult {
53
53
  let onKeyUp;
54
54
  if (shortcuts) {
55
55
  let shortcutHandler = createKeyboardShortcutHandler(shortcuts);
56
- let shortcutOnKeyDown = createEventHandler<KeyboardEvent>((e) => {
56
+ onKeyDown = createEventHandler<KeyboardEvent>((e) => {
57
+ props.onKeyDown?.(e);
57
58
  // If keyboard event didn't originate from a child of the current target,
58
59
  // then it's a React event coming through a portal. We should ignore it.
59
60
  if (!nodeContains(e.currentTarget as Node, getEventTarget(e) as Element)) {
@@ -67,7 +68,8 @@ export function useKeyboard(...args: any[]): KeyboardResult {
67
68
 
68
69
  shortcutHandler(e);
69
70
  });
70
- let shortcutOnKeyUp = createEventHandler<KeyboardEvent>((e) => {
71
+ onKeyUp = createEventHandler<KeyboardEvent>((e) => {
72
+ props.onKeyUp?.(e);
71
73
  // If keyboard event didn't originate from a child of the current target,
72
74
  // then it's a React event coming through a portal. We should ignore it.
73
75
  if (!nodeContains(e.currentTarget as Node, getEventTarget(e) as Element)) {
@@ -81,8 +83,6 @@ export function useKeyboard(...args: any[]): KeyboardResult {
81
83
  // implement shortcut handler on keyup, what should the map be called? or should it be another syntax on shortcuts?
82
84
  e.continuePropagation();
83
85
  });
84
- onKeyDown = props.onKeyDown ? chain(props.onKeyDown, shortcutOnKeyDown) : shortcutOnKeyDown;
85
- onKeyUp = props.onKeyUp ? chain(props.onKeyUp, shortcutOnKeyUp) : shortcutOnKeyUp;
86
86
  } else {
87
87
  onKeyDown = createEventHandler(props.onKeyDown);
88
88
  onKeyUp = createEventHandler(props.onKeyUp);
@@ -15,6 +15,7 @@ type KeyboardEvent = BaseEvent<globalThis.KeyboardEvent>;
15
15
  */
16
16
 
17
17
  import { AriaButtonProps } from '../button/useButton';
18
+ import { withSlot } from 'octane';
18
19
  import { AriaMenuOptions } from './useMenu';
19
20
  import { FocusableElement, FocusStrategy, RefObject } from '@react-types/shared';
20
21
  import { focusWithoutScrolling } from '../utils/focusWithoutScrolling';
@@ -63,6 +64,10 @@ export function useMenuTrigger<T>(
63
64
  ref: RefObject<Element | null>,
64
65
  _slot?: symbol,
65
66
  ): MenuTriggerAria<T> {
67
+ if (_slot !== undefined) {
68
+ return withSlot(_slot, useMenuTrigger<T>, props, state, ref);
69
+ }
70
+
66
71
  let { type = 'menu', isDisabled, trigger = 'press' } = props;
67
72
 
68
73
  let menuTriggerId = useId();
@@ -13,6 +13,7 @@
13
13
  */
14
14
 
15
15
  import { AriaMenuItemProps } from './useMenuItem';
16
+ import { withSlot } from 'octane';
16
17
  import { AriaMenuOptions } from './useMenu';
17
18
  import type { AriaPopoverProps } from '../overlays/usePopover';
18
19
  import { FocusableElement, FocusStrategy, Node, PressEvent, RefObject } from '@react-types/shared';
@@ -93,6 +94,10 @@ export function useSubmenuTrigger<T>(
93
94
  ref: RefObject<FocusableElement | null>,
94
95
  _slot?: symbol,
95
96
  ): SubmenuTriggerAria<T> {
97
+ if (_slot !== undefined) {
98
+ return withSlot(_slot, useSubmenuTrigger<T>, props, state, ref);
99
+ }
100
+
96
101
  let {
97
102
  parentMenuRef,
98
103
  submenuRef,
@@ -42,7 +42,7 @@ import {
42
42
  useState,
43
43
  } from '../compat/react';
44
44
  import { filterDOMProps } from '../utils/filterDOMProps';
45
- import { flushSync } from 'octane';
45
+ import { flushSync, withSlot } from 'octane';
46
46
  import { getActiveElement, getEventTarget } from '../utils/shadowdom/DOMFunctions';
47
47
  import intlMessages from '../intl/numberfield/index';
48
48
  import { isAndroid, isIOS, isIPhone } from '../utils/platform';
@@ -110,6 +110,10 @@ export function useNumberField(
110
110
  inputRef: RefObject<HTMLInputElement | null>,
111
111
  _slot?: symbol,
112
112
  ): NumberFieldAria {
113
+ if (_slot !== undefined) {
114
+ return withSlot(_slot, useNumberField, props, state, inputRef);
115
+ }
116
+
113
117
  let {
114
118
  id,
115
119
  decrementAriaLabel,
@@ -14,6 +14,7 @@ type DOMAttributes = Record<string, any>;
14
14
  */
15
15
 
16
16
  import { RefObject } from '@react-types/shared';
17
+ import { withSlot } from 'octane';
17
18
  import { getEventTarget } from '../utils/shadowdom/DOMFunctions';
18
19
  import { isElementInChildOfActiveScope } from '../focus/FocusScope';
19
20
  import { useEffect, useRef } from '../compat/react';
@@ -73,6 +74,10 @@ export function useOverlay(
73
74
  ref: RefObject<Element | null>,
74
75
  _slot?: symbol,
75
76
  ): OverlayAria {
77
+ if (_slot !== undefined) {
78
+ return withSlot(_slot, useOverlay, props, ref);
79
+ }
80
+
76
81
  let {
77
82
  onClose,
78
83
  shouldCloseOnBlur,
@@ -20,6 +20,7 @@ import {
20
20
  InputDOMProps,
21
21
  ValidationResult,
22
22
  } from '@react-types/shared';
23
+ import { withSlot } from 'octane';
23
24
  import { filterDOMProps } from '../utils/filterDOMProps';
24
25
  import { getEventTarget } from '../utils/shadowdom/DOMFunctions';
25
26
  import { getFocusableTreeWalker } from '../focus/FocusScope';
@@ -62,6 +63,10 @@ export function useRadioGroup(
62
63
  state: RadioGroupState,
63
64
  _slot?: symbol,
64
65
  ): RadioGroupAria {
66
+ if (_slot !== undefined) {
67
+ return withSlot(_slot, useRadioGroup, props, state);
68
+ }
69
+
65
70
  let {
66
71
  name,
67
72
  form,
@@ -14,6 +14,7 @@ type DOMAttributes = Record<string, any>;
14
14
  */
15
15
 
16
16
  import { AriaButtonProps } from '../button/useButton';
17
+ import { withSlot } from 'octane';
17
18
  import { AriaTextFieldProps, useTextField } from '../textfield/useTextField';
18
19
  import { RefObject, ValidationResult } from '@react-types/shared';
19
20
  import { InputHTMLAttributes, LabelHTMLAttributes } from '../compat/react';
@@ -69,6 +70,10 @@ export function useSearchField(
69
70
  inputRef: RefObject<HTMLInputElement | null>,
70
71
  _slot?: symbol,
71
72
  ): SearchFieldAria {
73
+ if (_slot !== undefined) {
74
+ return withSlot(_slot, useSearchField, props, state, inputRef);
75
+ }
76
+
72
77
  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/searchfield');
73
78
  let { isDisabled, isReadOnly, onSubmit, onClear, type = 'search' } = props;
74
79
 
@@ -25,7 +25,7 @@ import {
25
25
  KeyboardDelegate,
26
26
  RefObject,
27
27
  } from '@react-types/shared';
28
- import { flushSync } from 'octane';
28
+ import { flushSync, withSlot } from 'octane';
29
29
  import { FocusEvent, useEffect, useRef } from '../compat/react';
30
30
  import { focusSafely } from '../interactions/focusSafely';
31
31
  import { focusWithoutScrolling } from '../utils/focusWithoutScrolling';
@@ -153,6 +153,10 @@ export function useSelectableCollection(
153
153
  options: AriaSelectableCollectionOptions,
154
154
  _slot?: symbol,
155
155
  ): SelectableCollectionAria {
156
+ if (_slot !== undefined) {
157
+ return withSlot(_slot, useSelectableCollection, options);
158
+ }
159
+
156
160
  let {
157
161
  selectionManager: manager,
158
162
  keyboardDelegate: delegate,
@@ -18,6 +18,7 @@ import { focusWithoutScrolling } from '../utils/focusWithoutScrolling';
18
18
  import { getEventTarget } from '../utils/shadowdom/DOMFunctions';
19
19
  import { getSliderThumbId, sliderData } from './utils';
20
20
  import { mergeProps } from '../utils/mergeProps';
21
+ import { withSlot } from 'octane';
21
22
  import React, {
22
23
  ChangeEvent,
23
24
  InputHTMLAttributes,
@@ -104,6 +105,10 @@ export function useSliderThumb(
104
105
  state: SliderState,
105
106
  _slot?: symbol,
106
107
  ): SliderThumbAria {
108
+ if (_slot !== undefined) {
109
+ return withSlot(_slot, useSliderThumb, opts, state);
110
+ }
111
+
107
112
  let {
108
113
  index = 0,
109
114
  isRequired,
@@ -14,6 +14,7 @@ type DOMAttributes = Record<string, any>;
14
14
  */
15
15
 
16
16
  import { announce, clearAnnouncer } from '../live-announcer/LiveAnnouncer';
17
+ import { withSlot } from 'octane';
17
18
 
18
19
  import { AriaButtonProps } from '../button/useButton';
19
20
  import { InputBase, RangeInputBase, Validation, ValueBase } from '@react-types/shared';
@@ -44,6 +45,10 @@ export interface SpinbuttonAria {
44
45
  }
45
46
 
46
47
  export function useSpinButton(props: SpinButtonProps, _slot?: symbol): SpinbuttonAria {
48
+ if (_slot !== undefined) {
49
+ return withSlot(_slot, useSpinButton, props);
50
+ }
51
+
47
52
  const _async = useRef<number | undefined>(undefined);
48
53
  let {
49
54
  value,
@@ -23,6 +23,7 @@ import { GridNode } from '../upstream-exports/react-stately/private/grid/GridCol
23
23
  import intlMessages from '../intl/table/index';
24
24
  import { mergeProps } from '../utils/mergeProps';
25
25
  import { TableColumnResizeState } from '../upstream-exports/react-stately/useTableState';
26
+ import { withSlot } from 'octane';
26
27
  import { useDescription } from '../utils/useDescription';
27
28
  import { useEffectEvent } from '../utils/useEffectEvent';
28
29
  import { useId } from '../utils/useId';
@@ -87,6 +88,10 @@ export function useTableColumnResize<T>(
87
88
  ref: RefObject<HTMLInputElement | null>,
88
89
  _slot?: symbol,
89
90
  ): TableColumnResizeAria {
91
+ if (_slot !== undefined) {
92
+ return withSlot(_slot, useTableColumnResize<T>, props, state, ref);
93
+ }
94
+
90
95
  let {
91
96
  column: item,
92
97
  triggerRef,
@@ -43,7 +43,7 @@ import { useLayoutEffect } from '../utils/useLayoutEffect';
43
43
  import { useLocale } from '../i18n/I18nProvider';
44
44
 
45
45
  export interface AriaTokenFieldProps<T extends TokenFieldValue = TokenFieldValue>
46
- extends TokenFieldProps<T>, AriaLabelingProps {
46
+ extends TokenFieldProps<T>, AriaLabelingProps, FocusableProps {
47
47
  /**
48
48
  * The accessibility role of the token field.
49
49
  *
@@ -36,6 +36,7 @@ export function VirtualizerItem(props: VirtualizerItemProps): JSX.Element {
36
36
  layoutInfo,
37
37
  virtualizer,
38
38
  ref,
39
+ shouldObserveItemSize,
39
40
  });
40
41
 
41
42
  return (