@radix-ui/react-roving-focus 1.1.0-rc.2 → 1.1.0-rc.4

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/dist/index.d.mts CHANGED
@@ -1,11 +1,10 @@
1
1
  import * as React from 'react';
2
- import * as Radix from '@radix-ui/react-primitive';
3
2
  import { Primitive } from '@radix-ui/react-primitive';
4
3
 
5
- declare type Scope<C = any> = {
4
+ type Scope<C = any> = {
6
5
  [scopeName: string]: React.Context<C>[];
7
6
  } | undefined;
8
- declare type ScopeHook = (scope: Scope) => {
7
+ type ScopeHook = (scope: Scope) => {
9
8
  [__scopeProp: string]: Scope;
10
9
  };
11
10
  interface CreateScope {
@@ -14,8 +13,8 @@ interface CreateScope {
14
13
  }
15
14
 
16
15
  declare const createRovingFocusGroupScope: CreateScope;
17
- declare type Orientation = React.AriaAttributes['aria-orientation'];
18
- declare type Direction = 'ltr' | 'rtl';
16
+ type Orientation = React.AriaAttributes['aria-orientation'];
17
+ type Direction = 'ltr' | 'rtl';
19
18
  interface RovingFocusGroupOptions {
20
19
  /**
21
20
  * The orientation of the group.
@@ -35,7 +34,7 @@ interface RovingFocusGroupOptions {
35
34
  interface RovingFocusGroupProps extends RovingFocusGroupImplProps {
36
35
  }
37
36
  declare const RovingFocusGroup: React.ForwardRefExoticComponent<RovingFocusGroupProps & React.RefAttributes<HTMLDivElement>>;
38
- declare type PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;
37
+ type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
39
38
  interface RovingFocusGroupImplProps extends Omit<PrimitiveDivProps, 'dir'>, RovingFocusGroupOptions {
40
39
  currentTabStopId?: string | null;
41
40
  defaultCurrentTabStopId?: string;
@@ -43,7 +42,7 @@ interface RovingFocusGroupImplProps extends Omit<PrimitiveDivProps, 'dir'>, Rovi
43
42
  onEntryFocus?: (event: Event) => void;
44
43
  preventScrollOnEntryFocus?: boolean;
45
44
  }
46
- declare type PrimitiveSpanProps = Radix.ComponentPropsWithoutRef<typeof Primitive.span>;
45
+ type PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;
47
46
  interface RovingFocusItemProps extends PrimitiveSpanProps {
48
47
  tabStopId?: string;
49
48
  focusable?: boolean;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  import * as React from 'react';
2
- import * as Radix from '@radix-ui/react-primitive';
3
2
  import { Primitive } from '@radix-ui/react-primitive';
4
3
 
5
- declare type Scope<C = any> = {
4
+ type Scope<C = any> = {
6
5
  [scopeName: string]: React.Context<C>[];
7
6
  } | undefined;
8
- declare type ScopeHook = (scope: Scope) => {
7
+ type ScopeHook = (scope: Scope) => {
9
8
  [__scopeProp: string]: Scope;
10
9
  };
11
10
  interface CreateScope {
@@ -14,8 +13,8 @@ interface CreateScope {
14
13
  }
15
14
 
16
15
  declare const createRovingFocusGroupScope: CreateScope;
17
- declare type Orientation = React.AriaAttributes['aria-orientation'];
18
- declare type Direction = 'ltr' | 'rtl';
16
+ type Orientation = React.AriaAttributes['aria-orientation'];
17
+ type Direction = 'ltr' | 'rtl';
19
18
  interface RovingFocusGroupOptions {
20
19
  /**
21
20
  * The orientation of the group.
@@ -35,7 +34,7 @@ interface RovingFocusGroupOptions {
35
34
  interface RovingFocusGroupProps extends RovingFocusGroupImplProps {
36
35
  }
37
36
  declare const RovingFocusGroup: React.ForwardRefExoticComponent<RovingFocusGroupProps & React.RefAttributes<HTMLDivElement>>;
38
- declare type PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;
37
+ type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
39
38
  interface RovingFocusGroupImplProps extends Omit<PrimitiveDivProps, 'dir'>, RovingFocusGroupOptions {
40
39
  currentTabStopId?: string | null;
41
40
  defaultCurrentTabStopId?: string;
@@ -43,7 +42,7 @@ interface RovingFocusGroupImplProps extends Omit<PrimitiveDivProps, 'dir'>, Rovi
43
42
  onEntryFocus?: (event: Event) => void;
44
43
  preventScrollOnEntryFocus?: boolean;
45
44
  }
46
- declare type PrimitiveSpanProps = Radix.ComponentPropsWithoutRef<typeof Primitive.span>;
45
+ type PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;
47
46
  interface RovingFocusItemProps extends PrimitiveSpanProps {
48
47
  tabStopId?: string;
49
48
  focusable?: boolean;
package/dist/index.js CHANGED
@@ -1,252 +1,260 @@
1
1
  "use strict";
2
2
  "use client";
3
- (() => {
4
- var __create = Object.create;
5
- var __defProp = Object.defineProperty;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __getOwnPropNames = Object.getOwnPropertyNames;
8
- var __getProtoOf = Object.getPrototypeOf;
9
- var __hasOwnProp = Object.prototype.hasOwnProperty;
10
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
12
- }) : x)(function(x) {
13
- if (typeof require !== "undefined") return require.apply(this, arguments);
14
- throw Error('Dynamic require of "' + x + '" is not supported');
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // packages/react/roving-focus/src/index.ts
32
+ var src_exports = {};
33
+ __export(src_exports, {
34
+ Item: () => Item,
35
+ Root: () => Root,
36
+ RovingFocusGroup: () => RovingFocusGroup,
37
+ RovingFocusGroupItem: () => RovingFocusGroupItem,
38
+ createRovingFocusGroupScope: () => createRovingFocusGroupScope
39
+ });
40
+ module.exports = __toCommonJS(src_exports);
41
+
42
+ // packages/react/roving-focus/src/RovingFocusGroup.tsx
43
+ var React = __toESM(require("react"));
44
+ var import_primitive = require("@radix-ui/primitive");
45
+ var import_react_collection = require("@radix-ui/react-collection");
46
+ var import_react_compose_refs = require("@radix-ui/react-compose-refs");
47
+ var import_react_context = require("@radix-ui/react-context");
48
+ var import_react_id = require("@radix-ui/react-id");
49
+ var import_react_primitive = require("@radix-ui/react-primitive");
50
+ var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
51
+ var import_react_use_controllable_state = require("@radix-ui/react-use-controllable-state");
52
+ var import_react_direction = require("@radix-ui/react-direction");
53
+ var import_jsx_runtime = require("react/jsx-runtime");
54
+ var ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
55
+ var EVENT_OPTIONS = { bubbles: false, cancelable: true };
56
+ var GROUP_NAME = "RovingFocusGroup";
57
+ var [Collection, useCollection, createCollectionScope] = (0, import_react_collection.createCollection)(GROUP_NAME);
58
+ var [createRovingFocusGroupContext, createRovingFocusGroupScope] = (0, import_react_context.createContextScope)(
59
+ GROUP_NAME,
60
+ [createCollectionScope]
61
+ );
62
+ var [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext(GROUP_NAME);
63
+ var RovingFocusGroup = React.forwardRef(
64
+ (props, forwardedRef) => {
65
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
66
+ }
67
+ );
68
+ RovingFocusGroup.displayName = GROUP_NAME;
69
+ var RovingFocusGroupImpl = React.forwardRef((props, forwardedRef) => {
70
+ const {
71
+ __scopeRovingFocusGroup,
72
+ orientation,
73
+ loop = false,
74
+ dir,
75
+ currentTabStopId: currentTabStopIdProp,
76
+ defaultCurrentTabStopId,
77
+ onCurrentTabStopIdChange,
78
+ onEntryFocus,
79
+ preventScrollOnEntryFocus = false,
80
+ ...groupProps
81
+ } = props;
82
+ const ref = React.useRef(null);
83
+ const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref);
84
+ const direction = (0, import_react_direction.useDirection)(dir);
85
+ const [currentTabStopId = null, setCurrentTabStopId] = (0, import_react_use_controllable_state.useControllableState)({
86
+ prop: currentTabStopIdProp,
87
+ defaultProp: defaultCurrentTabStopId,
88
+ onChange: onCurrentTabStopIdChange
15
89
  });
16
- var __copyProps = (to, from, except, desc) => {
17
- if (from && typeof from === "object" || typeof from === "function") {
18
- for (let key of __getOwnPropNames(from))
19
- if (!__hasOwnProp.call(to, key) && key !== except)
20
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
90
+ const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);
91
+ const handleEntryFocus = (0, import_react_use_callback_ref.useCallbackRef)(onEntryFocus);
92
+ const getItems = useCollection(__scopeRovingFocusGroup);
93
+ const isClickFocusRef = React.useRef(false);
94
+ const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);
95
+ React.useEffect(() => {
96
+ const node = ref.current;
97
+ if (node) {
98
+ node.addEventListener(ENTRY_FOCUS, handleEntryFocus);
99
+ return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
21
100
  }
22
- return to;
23
- };
24
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
- // If the importer is in node compatibility mode or this is not an ESM
26
- // file that has been converted to a CommonJS file using a Babel-
27
- // compatible transform (i.e. "__esModule" has not been set), then set
28
- // "default" to the CommonJS "module.exports" for node compatibility.
29
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
- mod
31
- ));
32
-
33
- // packages/react/roving-focus/src/RovingFocusGroup.tsx
34
- var React = __toESM(__require("react"));
35
- var import_primitive = __require("@radix-ui/primitive");
36
- var import_react_collection = __require("@radix-ui/react-collection");
37
- var import_react_compose_refs = __require("@radix-ui/react-compose-refs");
38
- var import_react_context = __require("@radix-ui/react-context");
39
- var import_react_id = __require("@radix-ui/react-id");
40
- var import_react_primitive = __require("@radix-ui/react-primitive");
41
- var import_react_use_callback_ref = __require("@radix-ui/react-use-callback-ref");
42
- var import_react_use_controllable_state = __require("@radix-ui/react-use-controllable-state");
43
- var import_react_direction = __require("@radix-ui/react-direction");
44
- var import_jsx_runtime = __require("react/jsx-runtime");
45
- var ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
46
- var EVENT_OPTIONS = { bubbles: false, cancelable: true };
47
- var GROUP_NAME = "RovingFocusGroup";
48
- var [Collection, useCollection, createCollectionScope] = (0, import_react_collection.createCollection)(GROUP_NAME);
49
- var [createRovingFocusGroupContext, createRovingFocusGroupScope] = (0, import_react_context.createContextScope)(
50
- GROUP_NAME,
51
- [createCollectionScope]
52
- );
53
- var [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext(GROUP_NAME);
54
- var RovingFocusGroup = React.forwardRef(
55
- (props, forwardedRef) => {
56
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
101
+ }, [handleEntryFocus]);
102
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
103
+ RovingFocusProvider,
104
+ {
105
+ scope: __scopeRovingFocusGroup,
106
+ orientation,
107
+ dir: direction,
108
+ loop,
109
+ currentTabStopId,
110
+ onItemFocus: React.useCallback(
111
+ (tabStopId) => setCurrentTabStopId(tabStopId),
112
+ [setCurrentTabStopId]
113
+ ),
114
+ onItemShiftTab: React.useCallback(() => setIsTabbingBackOut(true), []),
115
+ onFocusableItemAdd: React.useCallback(
116
+ () => setFocusableItemsCount((prevCount) => prevCount + 1),
117
+ []
118
+ ),
119
+ onFocusableItemRemove: React.useCallback(
120
+ () => setFocusableItemsCount((prevCount) => prevCount - 1),
121
+ []
122
+ ),
123
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
124
+ import_react_primitive.Primitive.div,
125
+ {
126
+ tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
127
+ "data-orientation": orientation,
128
+ ...groupProps,
129
+ ref: composedRefs,
130
+ style: { outline: "none", ...props.style },
131
+ onMouseDown: (0, import_primitive.composeEventHandlers)(props.onMouseDown, () => {
132
+ isClickFocusRef.current = true;
133
+ }),
134
+ onFocus: (0, import_primitive.composeEventHandlers)(props.onFocus, (event) => {
135
+ const isKeyboardFocus = !isClickFocusRef.current;
136
+ if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
137
+ const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
138
+ event.currentTarget.dispatchEvent(entryFocusEvent);
139
+ if (!entryFocusEvent.defaultPrevented) {
140
+ const items = getItems().filter((item) => item.focusable);
141
+ const activeItem = items.find((item) => item.active);
142
+ const currentItem = items.find((item) => item.id === currentTabStopId);
143
+ const candidateItems = [activeItem, currentItem, ...items].filter(
144
+ Boolean
145
+ );
146
+ const candidateNodes = candidateItems.map((item) => item.ref.current);
147
+ focusFirst(candidateNodes, preventScrollOnEntryFocus);
148
+ }
149
+ }
150
+ isClickFocusRef.current = false;
151
+ }),
152
+ onBlur: (0, import_primitive.composeEventHandlers)(props.onBlur, () => setIsTabbingBackOut(false))
153
+ }
154
+ )
57
155
  }
58
156
  );
59
- RovingFocusGroup.displayName = GROUP_NAME;
60
- var RovingFocusGroupImpl = React.forwardRef((props, forwardedRef) => {
157
+ });
158
+ var ITEM_NAME = "RovingFocusGroupItem";
159
+ var RovingFocusGroupItem = React.forwardRef(
160
+ (props, forwardedRef) => {
61
161
  const {
62
162
  __scopeRovingFocusGroup,
63
- orientation,
64
- loop = false,
65
- dir,
66
- currentTabStopId: currentTabStopIdProp,
67
- defaultCurrentTabStopId,
68
- onCurrentTabStopIdChange,
69
- onEntryFocus,
70
- preventScrollOnEntryFocus = false,
71
- ...groupProps
163
+ focusable = true,
164
+ active = false,
165
+ tabStopId,
166
+ ...itemProps
72
167
  } = props;
73
- const ref = React.useRef(null);
74
- const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref);
75
- const direction = (0, import_react_direction.useDirection)(dir);
76
- const [currentTabStopId = null, setCurrentTabStopId] = (0, import_react_use_controllable_state.useControllableState)({
77
- prop: currentTabStopIdProp,
78
- defaultProp: defaultCurrentTabStopId,
79
- onChange: onCurrentTabStopIdChange
80
- });
81
- const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);
82
- const handleEntryFocus = (0, import_react_use_callback_ref.useCallbackRef)(onEntryFocus);
168
+ const autoId = (0, import_react_id.useId)();
169
+ const id = tabStopId || autoId;
170
+ const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);
171
+ const isCurrentTabStop = context.currentTabStopId === id;
83
172
  const getItems = useCollection(__scopeRovingFocusGroup);
84
- const isClickFocusRef = React.useRef(false);
85
- const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);
173
+ const { onFocusableItemAdd, onFocusableItemRemove } = context;
86
174
  React.useEffect(() => {
87
- const node = ref.current;
88
- if (node) {
89
- node.addEventListener(ENTRY_FOCUS, handleEntryFocus);
90
- return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
175
+ if (focusable) {
176
+ onFocusableItemAdd();
177
+ return () => onFocusableItemRemove();
91
178
  }
92
- }, [handleEntryFocus]);
179
+ }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);
93
180
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
94
- RovingFocusProvider,
181
+ Collection.ItemSlot,
95
182
  {
96
183
  scope: __scopeRovingFocusGroup,
97
- orientation,
98
- dir: direction,
99
- loop,
100
- currentTabStopId,
101
- onItemFocus: React.useCallback(
102
- (tabStopId) => setCurrentTabStopId(tabStopId),
103
- [setCurrentTabStopId]
104
- ),
105
- onItemShiftTab: React.useCallback(() => setIsTabbingBackOut(true), []),
106
- onFocusableItemAdd: React.useCallback(
107
- () => setFocusableItemsCount((prevCount) => prevCount + 1),
108
- []
109
- ),
110
- onFocusableItemRemove: React.useCallback(
111
- () => setFocusableItemsCount((prevCount) => prevCount - 1),
112
- []
113
- ),
184
+ id,
185
+ focusable,
186
+ active,
114
187
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
115
- import_react_primitive.Primitive.div,
188
+ import_react_primitive.Primitive.span,
116
189
  {
117
- tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
118
- "data-orientation": orientation,
119
- ...groupProps,
120
- ref: composedRefs,
121
- style: { outline: "none", ...props.style },
122
- onMouseDown: (0, import_primitive.composeEventHandlers)(props.onMouseDown, () => {
123
- isClickFocusRef.current = true;
190
+ tabIndex: isCurrentTabStop ? 0 : -1,
191
+ "data-orientation": context.orientation,
192
+ ...itemProps,
193
+ ref: forwardedRef,
194
+ onMouseDown: (0, import_primitive.composeEventHandlers)(props.onMouseDown, (event) => {
195
+ if (!focusable) event.preventDefault();
196
+ else context.onItemFocus(id);
124
197
  }),
125
- onFocus: (0, import_primitive.composeEventHandlers)(props.onFocus, (event) => {
126
- const isKeyboardFocus = !isClickFocusRef.current;
127
- if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
128
- const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
129
- event.currentTarget.dispatchEvent(entryFocusEvent);
130
- if (!entryFocusEvent.defaultPrevented) {
131
- const items = getItems().filter((item) => item.focusable);
132
- const activeItem = items.find((item) => item.active);
133
- const currentItem = items.find((item) => item.id === currentTabStopId);
134
- const candidateItems = [activeItem, currentItem, ...items].filter(
135
- Boolean
136
- );
137
- const candidateNodes = candidateItems.map((item) => item.ref.current);
138
- focusFirst(candidateNodes, preventScrollOnEntryFocus);
198
+ onFocus: (0, import_primitive.composeEventHandlers)(props.onFocus, () => context.onItemFocus(id)),
199
+ onKeyDown: (0, import_primitive.composeEventHandlers)(props.onKeyDown, (event) => {
200
+ if (event.key === "Tab" && event.shiftKey) {
201
+ context.onItemShiftTab();
202
+ return;
203
+ }
204
+ if (event.target !== event.currentTarget) return;
205
+ const focusIntent = getFocusIntent(event, context.orientation, context.dir);
206
+ if (focusIntent !== void 0) {
207
+ if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
208
+ event.preventDefault();
209
+ const items = getItems().filter((item) => item.focusable);
210
+ let candidateNodes = items.map((item) => item.ref.current);
211
+ if (focusIntent === "last") candidateNodes.reverse();
212
+ else if (focusIntent === "prev" || focusIntent === "next") {
213
+ if (focusIntent === "prev") candidateNodes.reverse();
214
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
215
+ candidateNodes = context.loop ? wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
139
216
  }
217
+ setTimeout(() => focusFirst(candidateNodes));
140
218
  }
141
- isClickFocusRef.current = false;
142
- }),
143
- onBlur: (0, import_primitive.composeEventHandlers)(props.onBlur, () => setIsTabbingBackOut(false))
219
+ })
144
220
  }
145
221
  )
146
222
  }
147
223
  );
148
- });
149
- var ITEM_NAME = "RovingFocusGroupItem";
150
- var RovingFocusGroupItem = React.forwardRef(
151
- (props, forwardedRef) => {
152
- const {
153
- __scopeRovingFocusGroup,
154
- focusable = true,
155
- active = false,
156
- tabStopId,
157
- ...itemProps
158
- } = props;
159
- const autoId = (0, import_react_id.useId)();
160
- const id = tabStopId || autoId;
161
- const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);
162
- const isCurrentTabStop = context.currentTabStopId === id;
163
- const getItems = useCollection(__scopeRovingFocusGroup);
164
- const { onFocusableItemAdd, onFocusableItemRemove } = context;
165
- React.useEffect(() => {
166
- if (focusable) {
167
- onFocusableItemAdd();
168
- return () => onFocusableItemRemove();
169
- }
170
- }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);
171
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
172
- Collection.ItemSlot,
173
- {
174
- scope: __scopeRovingFocusGroup,
175
- id,
176
- focusable,
177
- active,
178
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
179
- import_react_primitive.Primitive.span,
180
- {
181
- tabIndex: isCurrentTabStop ? 0 : -1,
182
- "data-orientation": context.orientation,
183
- ...itemProps,
184
- ref: forwardedRef,
185
- onMouseDown: (0, import_primitive.composeEventHandlers)(props.onMouseDown, (event) => {
186
- if (!focusable) event.preventDefault();
187
- else context.onItemFocus(id);
188
- }),
189
- onFocus: (0, import_primitive.composeEventHandlers)(props.onFocus, () => context.onItemFocus(id)),
190
- onKeyDown: (0, import_primitive.composeEventHandlers)(props.onKeyDown, (event) => {
191
- if (event.key === "Tab" && event.shiftKey) {
192
- context.onItemShiftTab();
193
- return;
194
- }
195
- if (event.target !== event.currentTarget) return;
196
- const focusIntent = getFocusIntent(event, context.orientation, context.dir);
197
- if (focusIntent !== void 0) {
198
- if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
199
- event.preventDefault();
200
- const items = getItems().filter((item) => item.focusable);
201
- let candidateNodes = items.map((item) => item.ref.current);
202
- if (focusIntent === "last") candidateNodes.reverse();
203
- else if (focusIntent === "prev" || focusIntent === "next") {
204
- if (focusIntent === "prev") candidateNodes.reverse();
205
- const currentIndex = candidateNodes.indexOf(event.currentTarget);
206
- candidateNodes = context.loop ? wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
207
- }
208
- setTimeout(() => focusFirst(candidateNodes));
209
- }
210
- })
211
- }
212
- )
213
- }
214
- );
215
- }
216
- );
217
- RovingFocusGroupItem.displayName = ITEM_NAME;
218
- var MAP_KEY_TO_FOCUS_INTENT = {
219
- ArrowLeft: "prev",
220
- ArrowUp: "prev",
221
- ArrowRight: "next",
222
- ArrowDown: "next",
223
- PageUp: "first",
224
- Home: "first",
225
- PageDown: "last",
226
- End: "last"
227
- };
228
- function getDirectionAwareKey(key, dir) {
229
- if (dir !== "rtl") return key;
230
- return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
231
- }
232
- function getFocusIntent(event, orientation, dir) {
233
- const key = getDirectionAwareKey(event.key, dir);
234
- if (orientation === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
235
- if (orientation === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
236
- return MAP_KEY_TO_FOCUS_INTENT[key];
237
- }
238
- function focusFirst(candidates, preventScroll = false) {
239
- const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
240
- for (const candidate of candidates) {
241
- if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
242
- candidate.focus({ preventScroll });
243
- if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
244
- }
245
224
  }
246
- function wrapArray(array, startIndex) {
247
- return array.map((_, index) => array[(startIndex + index) % array.length]);
225
+ );
226
+ RovingFocusGroupItem.displayName = ITEM_NAME;
227
+ var MAP_KEY_TO_FOCUS_INTENT = {
228
+ ArrowLeft: "prev",
229
+ ArrowUp: "prev",
230
+ ArrowRight: "next",
231
+ ArrowDown: "next",
232
+ PageUp: "first",
233
+ Home: "first",
234
+ PageDown: "last",
235
+ End: "last"
236
+ };
237
+ function getDirectionAwareKey(key, dir) {
238
+ if (dir !== "rtl") return key;
239
+ return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
240
+ }
241
+ function getFocusIntent(event, orientation, dir) {
242
+ const key = getDirectionAwareKey(event.key, dir);
243
+ if (orientation === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
244
+ if (orientation === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
245
+ return MAP_KEY_TO_FOCUS_INTENT[key];
246
+ }
247
+ function focusFirst(candidates, preventScroll = false) {
248
+ const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
249
+ for (const candidate of candidates) {
250
+ if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
251
+ candidate.focus({ preventScroll });
252
+ if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
248
253
  }
249
- var Root = RovingFocusGroup;
250
- var Item = RovingFocusGroupItem;
251
- })();
254
+ }
255
+ function wrapArray(array, startIndex) {
256
+ return array.map((_, index) => array[(startIndex + index) % array.length]);
257
+ }
258
+ var Root = RovingFocusGroup;
259
+ var Item = RovingFocusGroupItem;
252
260
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/RovingFocusGroup.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nimport { composeEventHandlers } from '@radix-ui/primitive';\nimport { createCollection } from '@radix-ui/react-collection';\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useId } from '@radix-ui/react-id';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { useCallbackRef } from '@radix-ui/react-use-callback-ref';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport { useDirection } from '@radix-ui/react-direction';\n\nimport type * as Radix from '@radix-ui/react-primitive';\nimport type { Scope } from '@radix-ui/react-context';\n\nconst ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';\nconst EVENT_OPTIONS = { bubbles: false, cancelable: true };\n\n/* -------------------------------------------------------------------------------------------------\n * RovingFocusGroup\n * -----------------------------------------------------------------------------------------------*/\n\nconst GROUP_NAME = 'RovingFocusGroup';\n\ntype ItemData = { id: string; focusable: boolean; active: boolean };\nconst [Collection, useCollection, createCollectionScope] = createCollection<\n HTMLSpanElement,\n ItemData\n>(GROUP_NAME);\n\ntype ScopedProps<P> = P & { __scopeRovingFocusGroup?: Scope };\nconst [createRovingFocusGroupContext, createRovingFocusGroupScope] = createContextScope(\n GROUP_NAME,\n [createCollectionScope]\n);\n\ntype Orientation = React.AriaAttributes['aria-orientation'];\ntype Direction = 'ltr' | 'rtl';\n\ninterface RovingFocusGroupOptions {\n /**\n * The orientation of the group.\n * Mainly so arrow navigation is done accordingly (left & right vs. up & down)\n */\n orientation?: Orientation;\n /**\n * The direction of navigation between items.\n */\n dir?: Direction;\n /**\n * Whether keyboard navigation should loop around\n * @defaultValue false\n */\n loop?: boolean;\n}\n\ntype RovingContextValue = RovingFocusGroupOptions & {\n currentTabStopId: string | null;\n onItemFocus(tabStopId: string): void;\n onItemShiftTab(): void;\n onFocusableItemAdd(): void;\n onFocusableItemRemove(): void;\n};\n\nconst [RovingFocusProvider, useRovingFocusContext] =\n createRovingFocusGroupContext<RovingContextValue>(GROUP_NAME);\n\ntype RovingFocusGroupElement = RovingFocusGroupImplElement;\ninterface RovingFocusGroupProps extends RovingFocusGroupImplProps {}\n\nconst RovingFocusGroup = React.forwardRef<RovingFocusGroupElement, RovingFocusGroupProps>(\n (props: ScopedProps<RovingFocusGroupProps>, forwardedRef) => {\n return (\n <Collection.Provider scope={props.__scopeRovingFocusGroup}>\n <Collection.Slot scope={props.__scopeRovingFocusGroup}>\n <RovingFocusGroupImpl {...props} ref={forwardedRef} />\n </Collection.Slot>\n </Collection.Provider>\n );\n }\n);\n\nRovingFocusGroup.displayName = GROUP_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\ntype RovingFocusGroupImplElement = React.ElementRef<typeof Primitive.div>;\ntype PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface RovingFocusGroupImplProps\n extends Omit<PrimitiveDivProps, 'dir'>,\n RovingFocusGroupOptions {\n currentTabStopId?: string | null;\n defaultCurrentTabStopId?: string;\n onCurrentTabStopIdChange?: (tabStopId: string | null) => void;\n onEntryFocus?: (event: Event) => void;\n preventScrollOnEntryFocus?: boolean;\n}\n\nconst RovingFocusGroupImpl = React.forwardRef<\n RovingFocusGroupImplElement,\n RovingFocusGroupImplProps\n>((props: ScopedProps<RovingFocusGroupImplProps>, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n orientation,\n loop = false,\n dir,\n currentTabStopId: currentTabStopIdProp,\n defaultCurrentTabStopId,\n onCurrentTabStopIdChange,\n onEntryFocus,\n preventScrollOnEntryFocus = false,\n ...groupProps\n } = props;\n const ref = React.useRef<RovingFocusGroupImplElement>(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const direction = useDirection(dir);\n const [currentTabStopId = null, setCurrentTabStopId] = useControllableState({\n prop: currentTabStopIdProp,\n defaultProp: defaultCurrentTabStopId,\n onChange: onCurrentTabStopIdChange,\n });\n const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);\n const handleEntryFocus = useCallbackRef(onEntryFocus);\n const getItems = useCollection(__scopeRovingFocusGroup);\n const isClickFocusRef = React.useRef(false);\n const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);\n\n React.useEffect(() => {\n const node = ref.current;\n if (node) {\n node.addEventListener(ENTRY_FOCUS, handleEntryFocus);\n return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);\n }\n }, [handleEntryFocus]);\n\n return (\n <RovingFocusProvider\n scope={__scopeRovingFocusGroup}\n orientation={orientation}\n dir={direction}\n loop={loop}\n currentTabStopId={currentTabStopId}\n onItemFocus={React.useCallback(\n (tabStopId) => setCurrentTabStopId(tabStopId),\n [setCurrentTabStopId]\n )}\n onItemShiftTab={React.useCallback(() => setIsTabbingBackOut(true), [])}\n onFocusableItemAdd={React.useCallback(\n () => setFocusableItemsCount((prevCount) => prevCount + 1),\n []\n )}\n onFocusableItemRemove={React.useCallback(\n () => setFocusableItemsCount((prevCount) => prevCount - 1),\n []\n )}\n >\n <Primitive.div\n tabIndex={isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0}\n data-orientation={orientation}\n {...groupProps}\n ref={composedRefs}\n style={{ outline: 'none', ...props.style }}\n onMouseDown={composeEventHandlers(props.onMouseDown, () => {\n isClickFocusRef.current = true;\n })}\n onFocus={composeEventHandlers(props.onFocus, (event) => {\n // We normally wouldn't need this check, because we already check\n // that the focus is on the current target and not bubbling to it.\n // We do this because Safari doesn't focus buttons when clicked, and\n // instead, the wrapper will get focused and not through a bubbling event.\n const isKeyboardFocus = !isClickFocusRef.current;\n\n if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {\n const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);\n event.currentTarget.dispatchEvent(entryFocusEvent);\n\n if (!entryFocusEvent.defaultPrevented) {\n const items = getItems().filter((item) => item.focusable);\n const activeItem = items.find((item) => item.active);\n const currentItem = items.find((item) => item.id === currentTabStopId);\n const candidateItems = [activeItem, currentItem, ...items].filter(\n Boolean\n ) as typeof items;\n const candidateNodes = candidateItems.map((item) => item.ref.current!);\n focusFirst(candidateNodes, preventScrollOnEntryFocus);\n }\n }\n\n isClickFocusRef.current = false;\n })}\n onBlur={composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))}\n />\n </RovingFocusProvider>\n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * RovingFocusGroupItem\n * -----------------------------------------------------------------------------------------------*/\n\nconst ITEM_NAME = 'RovingFocusGroupItem';\n\ntype RovingFocusItemElement = React.ElementRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = Radix.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface RovingFocusItemProps extends PrimitiveSpanProps {\n tabStopId?: string;\n focusable?: boolean;\n active?: boolean;\n}\n\nconst RovingFocusGroupItem = React.forwardRef<RovingFocusItemElement, RovingFocusItemProps>(\n (props: ScopedProps<RovingFocusItemProps>, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n focusable = true,\n active = false,\n tabStopId,\n ...itemProps\n } = props;\n const autoId = useId();\n const id = tabStopId || autoId;\n const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);\n const isCurrentTabStop = context.currentTabStopId === id;\n const getItems = useCollection(__scopeRovingFocusGroup);\n\n const { onFocusableItemAdd, onFocusableItemRemove } = context;\n\n React.useEffect(() => {\n if (focusable) {\n onFocusableItemAdd();\n return () => onFocusableItemRemove();\n }\n }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);\n\n return (\n <Collection.ItemSlot\n scope={__scopeRovingFocusGroup}\n id={id}\n focusable={focusable}\n active={active}\n >\n <Primitive.span\n tabIndex={isCurrentTabStop ? 0 : -1}\n data-orientation={context.orientation}\n {...itemProps}\n ref={forwardedRef}\n onMouseDown={composeEventHandlers(props.onMouseDown, (event) => {\n // We prevent focusing non-focusable items on `mousedown`.\n // Even though the item has tabIndex={-1}, that only means take it out of the tab order.\n if (!focusable) event.preventDefault();\n // Safari doesn't focus a button when clicked so we run our logic on mousedown also\n else context.onItemFocus(id);\n })}\n onFocus={composeEventHandlers(props.onFocus, () => context.onItemFocus(id))}\n onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {\n if (event.key === 'Tab' && event.shiftKey) {\n context.onItemShiftTab();\n return;\n }\n\n if (event.target !== event.currentTarget) return;\n\n const focusIntent = getFocusIntent(event, context.orientation, context.dir);\n\n if (focusIntent !== undefined) {\n if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;\n event.preventDefault();\n const items = getItems().filter((item) => item.focusable);\n let candidateNodes = items.map((item) => item.ref.current!);\n\n if (focusIntent === 'last') candidateNodes.reverse();\n else if (focusIntent === 'prev' || focusIntent === 'next') {\n if (focusIntent === 'prev') candidateNodes.reverse();\n const currentIndex = candidateNodes.indexOf(event.currentTarget);\n candidateNodes = context.loop\n ? wrapArray(candidateNodes, currentIndex + 1)\n : candidateNodes.slice(currentIndex + 1);\n }\n\n /**\n * Imperative focus during keydown is risky so we prevent React's batching updates\n * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332\n */\n setTimeout(() => focusFirst(candidateNodes));\n }\n })}\n />\n </Collection.ItemSlot>\n );\n }\n);\n\nRovingFocusGroupItem.displayName = ITEM_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\n// prettier-ignore\nconst MAP_KEY_TO_FOCUS_INTENT: Record<string, FocusIntent> = {\n ArrowLeft: 'prev', ArrowUp: 'prev',\n ArrowRight: 'next', ArrowDown: 'next',\n PageUp: 'first', Home: 'first',\n PageDown: 'last', End: 'last',\n};\n\nfunction getDirectionAwareKey(key: string, dir?: Direction) {\n if (dir !== 'rtl') return key;\n return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;\n}\n\ntype FocusIntent = 'first' | 'last' | 'prev' | 'next';\n\nfunction getFocusIntent(event: React.KeyboardEvent, orientation?: Orientation, dir?: Direction) {\n const key = getDirectionAwareKey(event.key, dir);\n if (orientation === 'vertical' && ['ArrowLeft', 'ArrowRight'].includes(key)) return undefined;\n if (orientation === 'horizontal' && ['ArrowUp', 'ArrowDown'].includes(key)) return undefined;\n return MAP_KEY_TO_FOCUS_INTENT[key];\n}\n\nfunction focusFirst(candidates: HTMLElement[], preventScroll = false) {\n const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;\n for (const candidate of candidates) {\n // if focus is already where we want to go, we don't want to keep going through the candidates\n if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;\n candidate.focus({ preventScroll });\n if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;\n }\n}\n\n/**\n * Wraps an array around itself at a given start index\n * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`\n */\nfunction wrapArray<T>(array: T[], startIndex: number) {\n return array.map((_, index) => array[(startIndex + index) % array.length]);\n}\n\nconst Root = RovingFocusGroup;\nconst Item = RovingFocusGroupItem;\n\nexport {\n createRovingFocusGroupScope,\n //\n RovingFocusGroup,\n RovingFocusGroupItem,\n //\n Root,\n Item,\n};\nexport type { RovingFocusGroupProps, RovingFocusItemProps };\n"],
5
- "mappings": "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",
3
+ "sources": ["../src/index.ts", "../src/RovingFocusGroup.tsx"],
4
+ "sourcesContent": ["'use client';\nexport {\n createRovingFocusGroupScope,\n //\n RovingFocusGroup,\n RovingFocusGroupItem,\n //\n Root,\n Item,\n} from './RovingFocusGroup';\nexport type { RovingFocusGroupProps, RovingFocusItemProps } from './RovingFocusGroup';\n", "import * as React from 'react';\nimport { composeEventHandlers } from '@radix-ui/primitive';\nimport { createCollection } from '@radix-ui/react-collection';\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useId } from '@radix-ui/react-id';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { useCallbackRef } from '@radix-ui/react-use-callback-ref';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport { useDirection } from '@radix-ui/react-direction';\n\nimport type { Scope } from '@radix-ui/react-context';\n\nconst ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';\nconst EVENT_OPTIONS = { bubbles: false, cancelable: true };\n\n/* -------------------------------------------------------------------------------------------------\n * RovingFocusGroup\n * -----------------------------------------------------------------------------------------------*/\n\nconst GROUP_NAME = 'RovingFocusGroup';\n\ntype ItemData = { id: string; focusable: boolean; active: boolean };\nconst [Collection, useCollection, createCollectionScope] = createCollection<\n HTMLSpanElement,\n ItemData\n>(GROUP_NAME);\n\ntype ScopedProps<P> = P & { __scopeRovingFocusGroup?: Scope };\nconst [createRovingFocusGroupContext, createRovingFocusGroupScope] = createContextScope(\n GROUP_NAME,\n [createCollectionScope]\n);\n\ntype Orientation = React.AriaAttributes['aria-orientation'];\ntype Direction = 'ltr' | 'rtl';\n\ninterface RovingFocusGroupOptions {\n /**\n * The orientation of the group.\n * Mainly so arrow navigation is done accordingly (left & right vs. up & down)\n */\n orientation?: Orientation;\n /**\n * The direction of navigation between items.\n */\n dir?: Direction;\n /**\n * Whether keyboard navigation should loop around\n * @defaultValue false\n */\n loop?: boolean;\n}\n\ntype RovingContextValue = RovingFocusGroupOptions & {\n currentTabStopId: string | null;\n onItemFocus(tabStopId: string): void;\n onItemShiftTab(): void;\n onFocusableItemAdd(): void;\n onFocusableItemRemove(): void;\n};\n\nconst [RovingFocusProvider, useRovingFocusContext] =\n createRovingFocusGroupContext<RovingContextValue>(GROUP_NAME);\n\ntype RovingFocusGroupElement = RovingFocusGroupImplElement;\ninterface RovingFocusGroupProps extends RovingFocusGroupImplProps {}\n\nconst RovingFocusGroup = React.forwardRef<RovingFocusGroupElement, RovingFocusGroupProps>(\n (props: ScopedProps<RovingFocusGroupProps>, forwardedRef) => {\n return (\n <Collection.Provider scope={props.__scopeRovingFocusGroup}>\n <Collection.Slot scope={props.__scopeRovingFocusGroup}>\n <RovingFocusGroupImpl {...props} ref={forwardedRef} />\n </Collection.Slot>\n </Collection.Provider>\n );\n }\n);\n\nRovingFocusGroup.displayName = GROUP_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\ntype RovingFocusGroupImplElement = React.ElementRef<typeof Primitive.div>;\ntype PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface RovingFocusGroupImplProps\n extends Omit<PrimitiveDivProps, 'dir'>,\n RovingFocusGroupOptions {\n currentTabStopId?: string | null;\n defaultCurrentTabStopId?: string;\n onCurrentTabStopIdChange?: (tabStopId: string | null) => void;\n onEntryFocus?: (event: Event) => void;\n preventScrollOnEntryFocus?: boolean;\n}\n\nconst RovingFocusGroupImpl = React.forwardRef<\n RovingFocusGroupImplElement,\n RovingFocusGroupImplProps\n>((props: ScopedProps<RovingFocusGroupImplProps>, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n orientation,\n loop = false,\n dir,\n currentTabStopId: currentTabStopIdProp,\n defaultCurrentTabStopId,\n onCurrentTabStopIdChange,\n onEntryFocus,\n preventScrollOnEntryFocus = false,\n ...groupProps\n } = props;\n const ref = React.useRef<RovingFocusGroupImplElement>(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const direction = useDirection(dir);\n const [currentTabStopId = null, setCurrentTabStopId] = useControllableState({\n prop: currentTabStopIdProp,\n defaultProp: defaultCurrentTabStopId,\n onChange: onCurrentTabStopIdChange,\n });\n const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);\n const handleEntryFocus = useCallbackRef(onEntryFocus);\n const getItems = useCollection(__scopeRovingFocusGroup);\n const isClickFocusRef = React.useRef(false);\n const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);\n\n React.useEffect(() => {\n const node = ref.current;\n if (node) {\n node.addEventListener(ENTRY_FOCUS, handleEntryFocus);\n return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);\n }\n }, [handleEntryFocus]);\n\n return (\n <RovingFocusProvider\n scope={__scopeRovingFocusGroup}\n orientation={orientation}\n dir={direction}\n loop={loop}\n currentTabStopId={currentTabStopId}\n onItemFocus={React.useCallback(\n (tabStopId) => setCurrentTabStopId(tabStopId),\n [setCurrentTabStopId]\n )}\n onItemShiftTab={React.useCallback(() => setIsTabbingBackOut(true), [])}\n onFocusableItemAdd={React.useCallback(\n () => setFocusableItemsCount((prevCount) => prevCount + 1),\n []\n )}\n onFocusableItemRemove={React.useCallback(\n () => setFocusableItemsCount((prevCount) => prevCount - 1),\n []\n )}\n >\n <Primitive.div\n tabIndex={isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0}\n data-orientation={orientation}\n {...groupProps}\n ref={composedRefs}\n style={{ outline: 'none', ...props.style }}\n onMouseDown={composeEventHandlers(props.onMouseDown, () => {\n isClickFocusRef.current = true;\n })}\n onFocus={composeEventHandlers(props.onFocus, (event) => {\n // We normally wouldn't need this check, because we already check\n // that the focus is on the current target and not bubbling to it.\n // We do this because Safari doesn't focus buttons when clicked, and\n // instead, the wrapper will get focused and not through a bubbling event.\n const isKeyboardFocus = !isClickFocusRef.current;\n\n if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {\n const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);\n event.currentTarget.dispatchEvent(entryFocusEvent);\n\n if (!entryFocusEvent.defaultPrevented) {\n const items = getItems().filter((item) => item.focusable);\n const activeItem = items.find((item) => item.active);\n const currentItem = items.find((item) => item.id === currentTabStopId);\n const candidateItems = [activeItem, currentItem, ...items].filter(\n Boolean\n ) as typeof items;\n const candidateNodes = candidateItems.map((item) => item.ref.current!);\n focusFirst(candidateNodes, preventScrollOnEntryFocus);\n }\n }\n\n isClickFocusRef.current = false;\n })}\n onBlur={composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))}\n />\n </RovingFocusProvider>\n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * RovingFocusGroupItem\n * -----------------------------------------------------------------------------------------------*/\n\nconst ITEM_NAME = 'RovingFocusGroupItem';\n\ntype RovingFocusItemElement = React.ElementRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface RovingFocusItemProps extends PrimitiveSpanProps {\n tabStopId?: string;\n focusable?: boolean;\n active?: boolean;\n}\n\nconst RovingFocusGroupItem = React.forwardRef<RovingFocusItemElement, RovingFocusItemProps>(\n (props: ScopedProps<RovingFocusItemProps>, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n focusable = true,\n active = false,\n tabStopId,\n ...itemProps\n } = props;\n const autoId = useId();\n const id = tabStopId || autoId;\n const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);\n const isCurrentTabStop = context.currentTabStopId === id;\n const getItems = useCollection(__scopeRovingFocusGroup);\n\n const { onFocusableItemAdd, onFocusableItemRemove } = context;\n\n React.useEffect(() => {\n if (focusable) {\n onFocusableItemAdd();\n return () => onFocusableItemRemove();\n }\n }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);\n\n return (\n <Collection.ItemSlot\n scope={__scopeRovingFocusGroup}\n id={id}\n focusable={focusable}\n active={active}\n >\n <Primitive.span\n tabIndex={isCurrentTabStop ? 0 : -1}\n data-orientation={context.orientation}\n {...itemProps}\n ref={forwardedRef}\n onMouseDown={composeEventHandlers(props.onMouseDown, (event) => {\n // We prevent focusing non-focusable items on `mousedown`.\n // Even though the item has tabIndex={-1}, that only means take it out of the tab order.\n if (!focusable) event.preventDefault();\n // Safari doesn't focus a button when clicked so we run our logic on mousedown also\n else context.onItemFocus(id);\n })}\n onFocus={composeEventHandlers(props.onFocus, () => context.onItemFocus(id))}\n onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {\n if (event.key === 'Tab' && event.shiftKey) {\n context.onItemShiftTab();\n return;\n }\n\n if (event.target !== event.currentTarget) return;\n\n const focusIntent = getFocusIntent(event, context.orientation, context.dir);\n\n if (focusIntent !== undefined) {\n if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;\n event.preventDefault();\n const items = getItems().filter((item) => item.focusable);\n let candidateNodes = items.map((item) => item.ref.current!);\n\n if (focusIntent === 'last') candidateNodes.reverse();\n else if (focusIntent === 'prev' || focusIntent === 'next') {\n if (focusIntent === 'prev') candidateNodes.reverse();\n const currentIndex = candidateNodes.indexOf(event.currentTarget);\n candidateNodes = context.loop\n ? wrapArray(candidateNodes, currentIndex + 1)\n : candidateNodes.slice(currentIndex + 1);\n }\n\n /**\n * Imperative focus during keydown is risky so we prevent React's batching updates\n * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332\n */\n setTimeout(() => focusFirst(candidateNodes));\n }\n })}\n />\n </Collection.ItemSlot>\n );\n }\n);\n\nRovingFocusGroupItem.displayName = ITEM_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\n// prettier-ignore\nconst MAP_KEY_TO_FOCUS_INTENT: Record<string, FocusIntent> = {\n ArrowLeft: 'prev', ArrowUp: 'prev',\n ArrowRight: 'next', ArrowDown: 'next',\n PageUp: 'first', Home: 'first',\n PageDown: 'last', End: 'last',\n};\n\nfunction getDirectionAwareKey(key: string, dir?: Direction) {\n if (dir !== 'rtl') return key;\n return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;\n}\n\ntype FocusIntent = 'first' | 'last' | 'prev' | 'next';\n\nfunction getFocusIntent(event: React.KeyboardEvent, orientation?: Orientation, dir?: Direction) {\n const key = getDirectionAwareKey(event.key, dir);\n if (orientation === 'vertical' && ['ArrowLeft', 'ArrowRight'].includes(key)) return undefined;\n if (orientation === 'horizontal' && ['ArrowUp', 'ArrowDown'].includes(key)) return undefined;\n return MAP_KEY_TO_FOCUS_INTENT[key];\n}\n\nfunction focusFirst(candidates: HTMLElement[], preventScroll = false) {\n const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;\n for (const candidate of candidates) {\n // if focus is already where we want to go, we don't want to keep going through the candidates\n if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;\n candidate.focus({ preventScroll });\n if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;\n }\n}\n\n/**\n * Wraps an array around itself at a given start index\n * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`\n */\nfunction wrapArray<T>(array: T[], startIndex: number) {\n return array.map((_, index) => array[(startIndex + index) % array.length]);\n}\n\nconst Root = RovingFocusGroup;\nconst Item = RovingFocusGroupItem;\n\nexport {\n createRovingFocusGroupScope,\n //\n RovingFocusGroup,\n RovingFocusGroupItem,\n //\n Root,\n Item,\n};\nexport type { RovingFocusGroupProps, RovingFocusItemProps };\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/RovingFocusGroup.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nimport { composeEventHandlers } from '@radix-ui/primitive';\nimport { createCollection } from '@radix-ui/react-collection';\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useId } from '@radix-ui/react-id';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { useCallbackRef } from '@radix-ui/react-use-callback-ref';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport { useDirection } from '@radix-ui/react-direction';\n\nimport type * as Radix from '@radix-ui/react-primitive';\nimport type { Scope } from '@radix-ui/react-context';\n\nconst ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';\nconst EVENT_OPTIONS = { bubbles: false, cancelable: true };\n\n/* -------------------------------------------------------------------------------------------------\n * RovingFocusGroup\n * -----------------------------------------------------------------------------------------------*/\n\nconst GROUP_NAME = 'RovingFocusGroup';\n\ntype ItemData = { id: string; focusable: boolean; active: boolean };\nconst [Collection, useCollection, createCollectionScope] = createCollection<\n HTMLSpanElement,\n ItemData\n>(GROUP_NAME);\n\ntype ScopedProps<P> = P & { __scopeRovingFocusGroup?: Scope };\nconst [createRovingFocusGroupContext, createRovingFocusGroupScope] = createContextScope(\n GROUP_NAME,\n [createCollectionScope]\n);\n\ntype Orientation = React.AriaAttributes['aria-orientation'];\ntype Direction = 'ltr' | 'rtl';\n\ninterface RovingFocusGroupOptions {\n /**\n * The orientation of the group.\n * Mainly so arrow navigation is done accordingly (left & right vs. up & down)\n */\n orientation?: Orientation;\n /**\n * The direction of navigation between items.\n */\n dir?: Direction;\n /**\n * Whether keyboard navigation should loop around\n * @defaultValue false\n */\n loop?: boolean;\n}\n\ntype RovingContextValue = RovingFocusGroupOptions & {\n currentTabStopId: string | null;\n onItemFocus(tabStopId: string): void;\n onItemShiftTab(): void;\n onFocusableItemAdd(): void;\n onFocusableItemRemove(): void;\n};\n\nconst [RovingFocusProvider, useRovingFocusContext] =\n createRovingFocusGroupContext<RovingContextValue>(GROUP_NAME);\n\ntype RovingFocusGroupElement = RovingFocusGroupImplElement;\ninterface RovingFocusGroupProps extends RovingFocusGroupImplProps {}\n\nconst RovingFocusGroup = React.forwardRef<RovingFocusGroupElement, RovingFocusGroupProps>(\n (props: ScopedProps<RovingFocusGroupProps>, forwardedRef) => {\n return (\n <Collection.Provider scope={props.__scopeRovingFocusGroup}>\n <Collection.Slot scope={props.__scopeRovingFocusGroup}>\n <RovingFocusGroupImpl {...props} ref={forwardedRef} />\n </Collection.Slot>\n </Collection.Provider>\n );\n }\n);\n\nRovingFocusGroup.displayName = GROUP_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\ntype RovingFocusGroupImplElement = React.ElementRef<typeof Primitive.div>;\ntype PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface RovingFocusGroupImplProps\n extends Omit<PrimitiveDivProps, 'dir'>,\n RovingFocusGroupOptions {\n currentTabStopId?: string | null;\n defaultCurrentTabStopId?: string;\n onCurrentTabStopIdChange?: (tabStopId: string | null) => void;\n onEntryFocus?: (event: Event) => void;\n preventScrollOnEntryFocus?: boolean;\n}\n\nconst RovingFocusGroupImpl = React.forwardRef<\n RovingFocusGroupImplElement,\n RovingFocusGroupImplProps\n>((props: ScopedProps<RovingFocusGroupImplProps>, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n orientation,\n loop = false,\n dir,\n currentTabStopId: currentTabStopIdProp,\n defaultCurrentTabStopId,\n onCurrentTabStopIdChange,\n onEntryFocus,\n preventScrollOnEntryFocus = false,\n ...groupProps\n } = props;\n const ref = React.useRef<RovingFocusGroupImplElement>(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const direction = useDirection(dir);\n const [currentTabStopId = null, setCurrentTabStopId] = useControllableState({\n prop: currentTabStopIdProp,\n defaultProp: defaultCurrentTabStopId,\n onChange: onCurrentTabStopIdChange,\n });\n const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);\n const handleEntryFocus = useCallbackRef(onEntryFocus);\n const getItems = useCollection(__scopeRovingFocusGroup);\n const isClickFocusRef = React.useRef(false);\n const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);\n\n React.useEffect(() => {\n const node = ref.current;\n if (node) {\n node.addEventListener(ENTRY_FOCUS, handleEntryFocus);\n return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);\n }\n }, [handleEntryFocus]);\n\n return (\n <RovingFocusProvider\n scope={__scopeRovingFocusGroup}\n orientation={orientation}\n dir={direction}\n loop={loop}\n currentTabStopId={currentTabStopId}\n onItemFocus={React.useCallback(\n (tabStopId) => setCurrentTabStopId(tabStopId),\n [setCurrentTabStopId]\n )}\n onItemShiftTab={React.useCallback(() => setIsTabbingBackOut(true), [])}\n onFocusableItemAdd={React.useCallback(\n () => setFocusableItemsCount((prevCount) => prevCount + 1),\n []\n )}\n onFocusableItemRemove={React.useCallback(\n () => setFocusableItemsCount((prevCount) => prevCount - 1),\n []\n )}\n >\n <Primitive.div\n tabIndex={isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0}\n data-orientation={orientation}\n {...groupProps}\n ref={composedRefs}\n style={{ outline: 'none', ...props.style }}\n onMouseDown={composeEventHandlers(props.onMouseDown, () => {\n isClickFocusRef.current = true;\n })}\n onFocus={composeEventHandlers(props.onFocus, (event) => {\n // We normally wouldn't need this check, because we already check\n // that the focus is on the current target and not bubbling to it.\n // We do this because Safari doesn't focus buttons when clicked, and\n // instead, the wrapper will get focused and not through a bubbling event.\n const isKeyboardFocus = !isClickFocusRef.current;\n\n if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {\n const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);\n event.currentTarget.dispatchEvent(entryFocusEvent);\n\n if (!entryFocusEvent.defaultPrevented) {\n const items = getItems().filter((item) => item.focusable);\n const activeItem = items.find((item) => item.active);\n const currentItem = items.find((item) => item.id === currentTabStopId);\n const candidateItems = [activeItem, currentItem, ...items].filter(\n Boolean\n ) as typeof items;\n const candidateNodes = candidateItems.map((item) => item.ref.current!);\n focusFirst(candidateNodes, preventScrollOnEntryFocus);\n }\n }\n\n isClickFocusRef.current = false;\n })}\n onBlur={composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))}\n />\n </RovingFocusProvider>\n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * RovingFocusGroupItem\n * -----------------------------------------------------------------------------------------------*/\n\nconst ITEM_NAME = 'RovingFocusGroupItem';\n\ntype RovingFocusItemElement = React.ElementRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = Radix.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface RovingFocusItemProps extends PrimitiveSpanProps {\n tabStopId?: string;\n focusable?: boolean;\n active?: boolean;\n}\n\nconst RovingFocusGroupItem = React.forwardRef<RovingFocusItemElement, RovingFocusItemProps>(\n (props: ScopedProps<RovingFocusItemProps>, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n focusable = true,\n active = false,\n tabStopId,\n ...itemProps\n } = props;\n const autoId = useId();\n const id = tabStopId || autoId;\n const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);\n const isCurrentTabStop = context.currentTabStopId === id;\n const getItems = useCollection(__scopeRovingFocusGroup);\n\n const { onFocusableItemAdd, onFocusableItemRemove } = context;\n\n React.useEffect(() => {\n if (focusable) {\n onFocusableItemAdd();\n return () => onFocusableItemRemove();\n }\n }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);\n\n return (\n <Collection.ItemSlot\n scope={__scopeRovingFocusGroup}\n id={id}\n focusable={focusable}\n active={active}\n >\n <Primitive.span\n tabIndex={isCurrentTabStop ? 0 : -1}\n data-orientation={context.orientation}\n {...itemProps}\n ref={forwardedRef}\n onMouseDown={composeEventHandlers(props.onMouseDown, (event) => {\n // We prevent focusing non-focusable items on `mousedown`.\n // Even though the item has tabIndex={-1}, that only means take it out of the tab order.\n if (!focusable) event.preventDefault();\n // Safari doesn't focus a button when clicked so we run our logic on mousedown also\n else context.onItemFocus(id);\n })}\n onFocus={composeEventHandlers(props.onFocus, () => context.onItemFocus(id))}\n onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {\n if (event.key === 'Tab' && event.shiftKey) {\n context.onItemShiftTab();\n return;\n }\n\n if (event.target !== event.currentTarget) return;\n\n const focusIntent = getFocusIntent(event, context.orientation, context.dir);\n\n if (focusIntent !== undefined) {\n if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;\n event.preventDefault();\n const items = getItems().filter((item) => item.focusable);\n let candidateNodes = items.map((item) => item.ref.current!);\n\n if (focusIntent === 'last') candidateNodes.reverse();\n else if (focusIntent === 'prev' || focusIntent === 'next') {\n if (focusIntent === 'prev') candidateNodes.reverse();\n const currentIndex = candidateNodes.indexOf(event.currentTarget);\n candidateNodes = context.loop\n ? wrapArray(candidateNodes, currentIndex + 1)\n : candidateNodes.slice(currentIndex + 1);\n }\n\n /**\n * Imperative focus during keydown is risky so we prevent React's batching updates\n * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332\n */\n setTimeout(() => focusFirst(candidateNodes));\n }\n })}\n />\n </Collection.ItemSlot>\n );\n }\n);\n\nRovingFocusGroupItem.displayName = ITEM_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\n// prettier-ignore\nconst MAP_KEY_TO_FOCUS_INTENT: Record<string, FocusIntent> = {\n ArrowLeft: 'prev', ArrowUp: 'prev',\n ArrowRight: 'next', ArrowDown: 'next',\n PageUp: 'first', Home: 'first',\n PageDown: 'last', End: 'last',\n};\n\nfunction getDirectionAwareKey(key: string, dir?: Direction) {\n if (dir !== 'rtl') return key;\n return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;\n}\n\ntype FocusIntent = 'first' | 'last' | 'prev' | 'next';\n\nfunction getFocusIntent(event: React.KeyboardEvent, orientation?: Orientation, dir?: Direction) {\n const key = getDirectionAwareKey(event.key, dir);\n if (orientation === 'vertical' && ['ArrowLeft', 'ArrowRight'].includes(key)) return undefined;\n if (orientation === 'horizontal' && ['ArrowUp', 'ArrowDown'].includes(key)) return undefined;\n return MAP_KEY_TO_FOCUS_INTENT[key];\n}\n\nfunction focusFirst(candidates: HTMLElement[], preventScroll = false) {\n const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;\n for (const candidate of candidates) {\n // if focus is already where we want to go, we don't want to keep going through the candidates\n if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;\n candidate.focus({ preventScroll });\n if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;\n }\n}\n\n/**\n * Wraps an array around itself at a given start index\n * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`\n */\nfunction wrapArray<T>(array: T[], startIndex: number) {\n return array.map((_, index) => array[(startIndex + index) % array.length]);\n}\n\nconst Root = RovingFocusGroup;\nconst Item = RovingFocusGroupItem;\n\nexport {\n createRovingFocusGroupScope,\n //\n RovingFocusGroup,\n RovingFocusGroupItem,\n //\n Root,\n Item,\n};\nexport type { RovingFocusGroupProps, RovingFocusItemProps };\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nimport { composeEventHandlers } from '@radix-ui/primitive';\nimport { createCollection } from '@radix-ui/react-collection';\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useId } from '@radix-ui/react-id';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { useCallbackRef } from '@radix-ui/react-use-callback-ref';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport { useDirection } from '@radix-ui/react-direction';\n\nimport type { Scope } from '@radix-ui/react-context';\n\nconst ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';\nconst EVENT_OPTIONS = { bubbles: false, cancelable: true };\n\n/* -------------------------------------------------------------------------------------------------\n * RovingFocusGroup\n * -----------------------------------------------------------------------------------------------*/\n\nconst GROUP_NAME = 'RovingFocusGroup';\n\ntype ItemData = { id: string; focusable: boolean; active: boolean };\nconst [Collection, useCollection, createCollectionScope] = createCollection<\n HTMLSpanElement,\n ItemData\n>(GROUP_NAME);\n\ntype ScopedProps<P> = P & { __scopeRovingFocusGroup?: Scope };\nconst [createRovingFocusGroupContext, createRovingFocusGroupScope] = createContextScope(\n GROUP_NAME,\n [createCollectionScope]\n);\n\ntype Orientation = React.AriaAttributes['aria-orientation'];\ntype Direction = 'ltr' | 'rtl';\n\ninterface RovingFocusGroupOptions {\n /**\n * The orientation of the group.\n * Mainly so arrow navigation is done accordingly (left & right vs. up & down)\n */\n orientation?: Orientation;\n /**\n * The direction of navigation between items.\n */\n dir?: Direction;\n /**\n * Whether keyboard navigation should loop around\n * @defaultValue false\n */\n loop?: boolean;\n}\n\ntype RovingContextValue = RovingFocusGroupOptions & {\n currentTabStopId: string | null;\n onItemFocus(tabStopId: string): void;\n onItemShiftTab(): void;\n onFocusableItemAdd(): void;\n onFocusableItemRemove(): void;\n};\n\nconst [RovingFocusProvider, useRovingFocusContext] =\n createRovingFocusGroupContext<RovingContextValue>(GROUP_NAME);\n\ntype RovingFocusGroupElement = RovingFocusGroupImplElement;\ninterface RovingFocusGroupProps extends RovingFocusGroupImplProps {}\n\nconst RovingFocusGroup = React.forwardRef<RovingFocusGroupElement, RovingFocusGroupProps>(\n (props: ScopedProps<RovingFocusGroupProps>, forwardedRef) => {\n return (\n <Collection.Provider scope={props.__scopeRovingFocusGroup}>\n <Collection.Slot scope={props.__scopeRovingFocusGroup}>\n <RovingFocusGroupImpl {...props} ref={forwardedRef} />\n </Collection.Slot>\n </Collection.Provider>\n );\n }\n);\n\nRovingFocusGroup.displayName = GROUP_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\ntype RovingFocusGroupImplElement = React.ElementRef<typeof Primitive.div>;\ntype PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface RovingFocusGroupImplProps\n extends Omit<PrimitiveDivProps, 'dir'>,\n RovingFocusGroupOptions {\n currentTabStopId?: string | null;\n defaultCurrentTabStopId?: string;\n onCurrentTabStopIdChange?: (tabStopId: string | null) => void;\n onEntryFocus?: (event: Event) => void;\n preventScrollOnEntryFocus?: boolean;\n}\n\nconst RovingFocusGroupImpl = React.forwardRef<\n RovingFocusGroupImplElement,\n RovingFocusGroupImplProps\n>((props: ScopedProps<RovingFocusGroupImplProps>, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n orientation,\n loop = false,\n dir,\n currentTabStopId: currentTabStopIdProp,\n defaultCurrentTabStopId,\n onCurrentTabStopIdChange,\n onEntryFocus,\n preventScrollOnEntryFocus = false,\n ...groupProps\n } = props;\n const ref = React.useRef<RovingFocusGroupImplElement>(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const direction = useDirection(dir);\n const [currentTabStopId = null, setCurrentTabStopId] = useControllableState({\n prop: currentTabStopIdProp,\n defaultProp: defaultCurrentTabStopId,\n onChange: onCurrentTabStopIdChange,\n });\n const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);\n const handleEntryFocus = useCallbackRef(onEntryFocus);\n const getItems = useCollection(__scopeRovingFocusGroup);\n const isClickFocusRef = React.useRef(false);\n const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);\n\n React.useEffect(() => {\n const node = ref.current;\n if (node) {\n node.addEventListener(ENTRY_FOCUS, handleEntryFocus);\n return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);\n }\n }, [handleEntryFocus]);\n\n return (\n <RovingFocusProvider\n scope={__scopeRovingFocusGroup}\n orientation={orientation}\n dir={direction}\n loop={loop}\n currentTabStopId={currentTabStopId}\n onItemFocus={React.useCallback(\n (tabStopId) => setCurrentTabStopId(tabStopId),\n [setCurrentTabStopId]\n )}\n onItemShiftTab={React.useCallback(() => setIsTabbingBackOut(true), [])}\n onFocusableItemAdd={React.useCallback(\n () => setFocusableItemsCount((prevCount) => prevCount + 1),\n []\n )}\n onFocusableItemRemove={React.useCallback(\n () => setFocusableItemsCount((prevCount) => prevCount - 1),\n []\n )}\n >\n <Primitive.div\n tabIndex={isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0}\n data-orientation={orientation}\n {...groupProps}\n ref={composedRefs}\n style={{ outline: 'none', ...props.style }}\n onMouseDown={composeEventHandlers(props.onMouseDown, () => {\n isClickFocusRef.current = true;\n })}\n onFocus={composeEventHandlers(props.onFocus, (event) => {\n // We normally wouldn't need this check, because we already check\n // that the focus is on the current target and not bubbling to it.\n // We do this because Safari doesn't focus buttons when clicked, and\n // instead, the wrapper will get focused and not through a bubbling event.\n const isKeyboardFocus = !isClickFocusRef.current;\n\n if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {\n const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);\n event.currentTarget.dispatchEvent(entryFocusEvent);\n\n if (!entryFocusEvent.defaultPrevented) {\n const items = getItems().filter((item) => item.focusable);\n const activeItem = items.find((item) => item.active);\n const currentItem = items.find((item) => item.id === currentTabStopId);\n const candidateItems = [activeItem, currentItem, ...items].filter(\n Boolean\n ) as typeof items;\n const candidateNodes = candidateItems.map((item) => item.ref.current!);\n focusFirst(candidateNodes, preventScrollOnEntryFocus);\n }\n }\n\n isClickFocusRef.current = false;\n })}\n onBlur={composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))}\n />\n </RovingFocusProvider>\n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * RovingFocusGroupItem\n * -----------------------------------------------------------------------------------------------*/\n\nconst ITEM_NAME = 'RovingFocusGroupItem';\n\ntype RovingFocusItemElement = React.ElementRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface RovingFocusItemProps extends PrimitiveSpanProps {\n tabStopId?: string;\n focusable?: boolean;\n active?: boolean;\n}\n\nconst RovingFocusGroupItem = React.forwardRef<RovingFocusItemElement, RovingFocusItemProps>(\n (props: ScopedProps<RovingFocusItemProps>, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n focusable = true,\n active = false,\n tabStopId,\n ...itemProps\n } = props;\n const autoId = useId();\n const id = tabStopId || autoId;\n const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);\n const isCurrentTabStop = context.currentTabStopId === id;\n const getItems = useCollection(__scopeRovingFocusGroup);\n\n const { onFocusableItemAdd, onFocusableItemRemove } = context;\n\n React.useEffect(() => {\n if (focusable) {\n onFocusableItemAdd();\n return () => onFocusableItemRemove();\n }\n }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);\n\n return (\n <Collection.ItemSlot\n scope={__scopeRovingFocusGroup}\n id={id}\n focusable={focusable}\n active={active}\n >\n <Primitive.span\n tabIndex={isCurrentTabStop ? 0 : -1}\n data-orientation={context.orientation}\n {...itemProps}\n ref={forwardedRef}\n onMouseDown={composeEventHandlers(props.onMouseDown, (event) => {\n // We prevent focusing non-focusable items on `mousedown`.\n // Even though the item has tabIndex={-1}, that only means take it out of the tab order.\n if (!focusable) event.preventDefault();\n // Safari doesn't focus a button when clicked so we run our logic on mousedown also\n else context.onItemFocus(id);\n })}\n onFocus={composeEventHandlers(props.onFocus, () => context.onItemFocus(id))}\n onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {\n if (event.key === 'Tab' && event.shiftKey) {\n context.onItemShiftTab();\n return;\n }\n\n if (event.target !== event.currentTarget) return;\n\n const focusIntent = getFocusIntent(event, context.orientation, context.dir);\n\n if (focusIntent !== undefined) {\n if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;\n event.preventDefault();\n const items = getItems().filter((item) => item.focusable);\n let candidateNodes = items.map((item) => item.ref.current!);\n\n if (focusIntent === 'last') candidateNodes.reverse();\n else if (focusIntent === 'prev' || focusIntent === 'next') {\n if (focusIntent === 'prev') candidateNodes.reverse();\n const currentIndex = candidateNodes.indexOf(event.currentTarget);\n candidateNodes = context.loop\n ? wrapArray(candidateNodes, currentIndex + 1)\n : candidateNodes.slice(currentIndex + 1);\n }\n\n /**\n * Imperative focus during keydown is risky so we prevent React's batching updates\n * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332\n */\n setTimeout(() => focusFirst(candidateNodes));\n }\n })}\n />\n </Collection.ItemSlot>\n );\n }\n);\n\nRovingFocusGroupItem.displayName = ITEM_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\n// prettier-ignore\nconst MAP_KEY_TO_FOCUS_INTENT: Record<string, FocusIntent> = {\n ArrowLeft: 'prev', ArrowUp: 'prev',\n ArrowRight: 'next', ArrowDown: 'next',\n PageUp: 'first', Home: 'first',\n PageDown: 'last', End: 'last',\n};\n\nfunction getDirectionAwareKey(key: string, dir?: Direction) {\n if (dir !== 'rtl') return key;\n return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;\n}\n\ntype FocusIntent = 'first' | 'last' | 'prev' | 'next';\n\nfunction getFocusIntent(event: React.KeyboardEvent, orientation?: Orientation, dir?: Direction) {\n const key = getDirectionAwareKey(event.key, dir);\n if (orientation === 'vertical' && ['ArrowLeft', 'ArrowRight'].includes(key)) return undefined;\n if (orientation === 'horizontal' && ['ArrowUp', 'ArrowDown'].includes(key)) return undefined;\n return MAP_KEY_TO_FOCUS_INTENT[key];\n}\n\nfunction focusFirst(candidates: HTMLElement[], preventScroll = false) {\n const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;\n for (const candidate of candidates) {\n // if focus is already where we want to go, we don't want to keep going through the candidates\n if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;\n candidate.focus({ preventScroll });\n if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;\n }\n}\n\n/**\n * Wraps an array around itself at a given start index\n * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`\n */\nfunction wrapArray<T>(array: T[], startIndex: number) {\n return array.map((_, index) => array[(startIndex + index) % array.length]);\n}\n\nconst Root = RovingFocusGroup;\nconst Item = RovingFocusGroupItem;\n\nexport {\n createRovingFocusGroupScope,\n //\n RovingFocusGroup,\n RovingFocusGroupItem,\n //\n Root,\n Item,\n};\nexport type { RovingFocusGroupProps, RovingFocusItemProps };\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radix-ui/react-roving-focus",
3
- "version": "1.1.0-rc.2",
3
+ "version": "1.1.0-rc.4",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": {
@@ -28,21 +28,21 @@
28
28
  "version": "yarn version"
29
29
  },
30
30
  "dependencies": {
31
- "@radix-ui/primitive": "1.1.0-rc.2",
32
- "@radix-ui/react-collection": "1.1.0-rc.2",
33
- "@radix-ui/react-compose-refs": "1.1.0-rc.2",
34
- "@radix-ui/react-context": "1.1.0-rc.2",
35
- "@radix-ui/react-direction": "1.1.0-rc.2",
36
- "@radix-ui/react-id": "1.1.0-rc.2",
37
- "@radix-ui/react-primitive": "1.1.0-rc.2",
38
- "@radix-ui/react-use-callback-ref": "1.1.0-rc.2",
39
- "@radix-ui/react-use-controllable-state": "1.1.0-rc.2"
31
+ "@radix-ui/primitive": "1.1.0-rc.4",
32
+ "@radix-ui/react-collection": "1.1.0-rc.4",
33
+ "@radix-ui/react-compose-refs": "1.1.0-rc.4",
34
+ "@radix-ui/react-context": "1.1.0-rc.4",
35
+ "@radix-ui/react-direction": "1.1.0-rc.4",
36
+ "@radix-ui/react-id": "1.1.0-rc.4",
37
+ "@radix-ui/react-primitive": "2.0.0-rc.1",
38
+ "@radix-ui/react-use-callback-ref": "1.1.0-rc.4",
39
+ "@radix-ui/react-use-controllable-state": "1.1.0-rc.4"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@types/react": "*",
43
43
  "@types/react-dom": "*",
44
- "react": "^16.8 || ^17.0 || ^18.0",
45
- "react-dom": "^16.8 || ^17.0 || ^18.0"
44
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0",
45
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
46
46
  },
47
47
  "peerDependenciesMeta": {
48
48
  "@types/react": {