@tamagui/roving-focus 2.7.7 → 3.0.0-beta.643.1

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.
@@ -1,23 +1,23 @@
1
1
  "use strict";
2
2
 
3
+
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
8
  var __copyProps = (to, from, except, desc) => {
8
- if (from && typeof from === "object" || typeof from === "function") {
9
- for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
10
- get: () => from[key],
11
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
12
- });
13
- }
14
- return to;
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
11
+ get: () => from[key],
12
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
13
+ });
14
+ }
15
+ return to;
15
16
  };
16
17
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
17
- var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
18
- value: true
19
- }), mod);
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
19
  var index_exports = {};
21
20
  module.exports = __toCommonJS(index_exports);
22
21
  __reExport(index_exports, require("./RovingFocusGroup.native.js"), module.exports);
22
+
23
23
  //# sourceMappingURL=index.native.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["__toCommonJS","mod","__copyProps","__defProp","value","index_exports","module","exports"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":";;;;;;;;;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,GAAA,IAAAC,WAAA,CAAAC,SAAA;EAAAC,KAAA;AAAA,IAAAH,GAAA;AAAA,IAAAI,aAAA;AAAAC,MAAA,CAAAC,OAAA,GAAAP,YAAc,CAAAK,aAAA","ignoreList":[]}
1
+ {"version":3,"file":"index.native.js","names":[],"sources":["cjs/index.native.js"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, \"default\"), secondTarget && __copyProps(secondTarget, mod, \"default\"));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar index_exports = {};\nmodule.exports = __toCommonJS(index_exports);\n__reExport(index_exports, require(\"./RovingFocusGroup\"), module.exports);\n//# sourceMappingURL=index.js.map\n"],"mappings":";;;;AACA,IAAI,YAAY,OAAO;AACvB,IAAI,mBAAmB,OAAO;AAC9B,IAAI,oBAAoB,OAAO;AAC/B,IAAI,eAAe,OAAO,UAAU;AACpC,IAAI,eAAe,IAAI,MAAM,QAAQ,SAAS;CAC5C,IAAI,QAAQ,OAAO,SAAS,YAAY,OAAO,SAAS,YAAY;EAClE,KAAK,IAAI,OAAO,kBAAkB,IAAI,GACpC,IAAI,CAAC,aAAa,KAAK,IAAI,GAAG,KAAK,QAAQ,QACzC,UAAU,IAAI,KAAK;GAAE,WAAW,KAAK;GAAM,YAAY,EAAE,OAAO,iBAAiB,MAAM,GAAG,MAAM,KAAK;EAAW,CAAC;CACvH;CACA,OAAO;AACT;AACA,IAAI,cAAc,QAAQ,KAAK,kBAAkB,YAAY,QAAQ,KAAK,SAAS,GAAG,gBAAgB,YAAY,cAAc,KAAK,SAAS;AAC9I,IAAI,gBAAgB,QAAQ,YAAY,UAAU,CAAC,GAAG,cAAc,EAAE,OAAO,KAAK,CAAC,GAAG,GAAG;AACzF,IAAI,gBAAgB,CAAC;AACrB,OAAO,UAAU,aAAa,aAAa;AAC3C,WAAW,eAAe,QAAQ,8BAAoB,GAAG,OAAO,OAAO"}
@@ -1,204 +1,209 @@
1
1
  import { createCollection } from "@tamagui/collection";
2
2
  import { useComposedRefs } from "@tamagui/compose-refs";
3
3
  import { isWeb } from "@tamagui/constants";
4
- import { Slot, View, createStyledContext, useEvent } from "@tamagui/core";
4
+ import { Slot, View, createChangeEventDetails, createRefComponent, createStyledContext, useEvent } from "@tamagui/core";
5
5
  import { composeEventHandlers, withStaticProperties } from "@tamagui/helpers";
6
6
  import { useControllableState } from "@tamagui/use-controllable-state";
7
7
  import { useDirection } from "@tamagui/use-direction";
8
8
  import * as React from "react";
9
9
  import { jsx } from "react/jsx-runtime";
10
- const ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
11
- const EVENT_OPTIONS = {
12
- bubbles: false,
13
- cancelable: true
14
- };
15
- const RovingFocusGroupImpl = React.forwardRef((props, forwardedRef) => {
16
- const {
17
- __scopeRovingFocusGroup,
18
- orientation,
19
- loop = false,
20
- dir,
21
- currentTabStopId: currentTabStopIdProp,
22
- defaultCurrentTabStopId,
23
- onCurrentTabStopIdChange,
24
- onEntryFocus,
25
- asChild,
26
- ...groupProps
27
- } = props;
28
- const ref = React.useRef(null);
29
- const composedRefs = useComposedRefs(forwardedRef, ref);
30
- const direction = useDirection(dir);
31
- const [currentTabStopId = null, setCurrentTabStopId] = useControllableState({
32
- prop: currentTabStopIdProp,
33
- defaultProp: defaultCurrentTabStopId ?? null,
34
- onChange: onCurrentTabStopIdChange
35
- });
36
- const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);
37
- const handleEntryFocus = useEvent(onEntryFocus);
38
- const getItems = useCollection(__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT);
39
- const isClickFocusRef = React.useRef(false);
40
- const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);
41
- const Comp = asChild ? Slot : View;
42
- return /* @__PURE__ */jsx(RovingFocusProvider, {
43
- scope: __scopeRovingFocusGroup,
44
- orientation,
45
- dir: direction,
46
- loop,
47
- currentTabStopId,
48
- onItemFocus: React.useCallback(tabStopId => setCurrentTabStopId(tabStopId), [setCurrentTabStopId]),
49
- onItemShiftTab: React.useCallback(() => setIsTabbingBackOut(true), []),
50
- onFocusableItemAdd: React.useCallback(() => setFocusableItemsCount(prevCount => prevCount + 1), []),
51
- onFocusableItemRemove: React.useCallback(() => setFocusableItemsCount(prevCount => prevCount - 1), []),
52
- children: /* @__PURE__ */jsx(Comp, {
53
- tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
54
- "data-orientation": orientation,
55
- ...groupProps,
56
- ref: composedRefs,
57
- outlineStyle: "none",
58
- onMouseDown: composeEventHandlers(props.onMouseDown, () => {
59
- isClickFocusRef.current = true;
60
- }),
61
- onFocus: composeEventHandlers(props.onFocus, event => {
62
- const isKeyboardFocus = !isClickFocusRef.current;
63
- if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
64
- const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
65
- handleEntryFocus(entryFocusEvent);
66
- if (!entryFocusEvent.defaultPrevented) {
67
- const items = getItems().filter(item => item.focusable);
68
- const activeItem = items.find(item => item.active);
69
- const currentItem = items.find(item => item.id === currentTabStopId);
70
- const candidateItems = [activeItem, currentItem, ...items].filter(Boolean);
71
- const candidateNodes = candidateItems.map(item => item.ref.current);
72
- focusFirst(candidateNodes, {
73
- focusVisible: false
74
- });
75
- }
76
- }
77
- isClickFocusRef.current = false;
78
- }),
79
- onBlur: composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))
80
- })
81
- });
10
+
11
+ const RovingFocusGroupImpl = createRefComponent((props, forwardedRef) => {
12
+ const { __scopeRovingFocusGroup, orientation, loop = false, dir, currentTabStopId: currentTabStopIdProp, defaultCurrentTabStopId, onCurrentTabStopIdChange, onEntryFocus, asChild, ...groupProps } = props;
13
+ const ref = React.useRef(null);
14
+ const composedRefs = useComposedRefs(forwardedRef, ref);
15
+ const direction = useDirection(dir);
16
+ const [currentTabStopId = null, setCurrentTabStopId] = useControllableState({
17
+ prop: currentTabStopIdProp,
18
+ defaultProp: defaultCurrentTabStopId ?? null,
19
+ onChange: (tabStopId, details) => {
20
+ if (details) onCurrentTabStopIdChange?.(tabStopId, details);
21
+ }
22
+ });
23
+ const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);
24
+ const handleEntryFocus = useEvent(onEntryFocus);
25
+ const getItems = useCollection(__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT);
26
+ const isClickFocusRef = React.useRef(false);
27
+ const pendingFocusDetailsRef = React.useRef(null);
28
+ const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);
29
+ const Comp = asChild ? Slot : View;
30
+ return /* @__PURE__ */ jsx(RovingFocusProvider, {
31
+ scope: __scopeRovingFocusGroup,
32
+ orientation,
33
+ dir: direction,
34
+ loop,
35
+ currentTabStopId,
36
+ onItemFocus: React.useCallback((tabStopId, event) => {
37
+ if (tabStopId === currentTabStopId) return;
38
+ const details = pendingFocusDetailsRef.current ?? createChangeEventDetails("trigger-focus", event, event.currentTarget);
39
+ pendingFocusDetailsRef.current = null;
40
+ setCurrentTabStopId(tabStopId, details);
41
+ }, [currentTabStopId, setCurrentTabStopId]),
42
+ setPendingFocusDetails: React.useCallback((details) => {
43
+ pendingFocusDetailsRef.current = details;
44
+ }, []),
45
+ onItemShiftTab: React.useCallback(() => setIsTabbingBackOut(true), []),
46
+ onFocusableItemAdd: React.useCallback(() => setFocusableItemsCount((prevCount) => prevCount + 1), []),
47
+ onFocusableItemRemove: React.useCallback(() => setFocusableItemsCount((prevCount) => prevCount - 1), []),
48
+ children: /* @__PURE__ */ jsx(Comp, {
49
+ tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
50
+ "data-orientation": orientation,
51
+ ...groupProps,
52
+ ref: composedRefs,
53
+ outlineStyle: "none",
54
+ onMouseDown: composeEventHandlers(props.onMouseDown, () => {
55
+ isClickFocusRef.current = true;
56
+ }),
57
+ onFocus: composeEventHandlers(props.onFocus, (event) => {
58
+ const isKeyboardFocus = !isClickFocusRef.current;
59
+ if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
60
+ const details = createChangeEventDetails("trigger-focus", event, event.currentTarget);
61
+ handleEntryFocus(details);
62
+ if (!details.isCanceled) {
63
+ const items = getItems().filter((item) => item.focusable);
64
+ const activeItem = items.find((item) => item.active);
65
+ const currentItem = items.find((item) => item.id === currentTabStopId);
66
+ const candidateItems = [
67
+ activeItem,
68
+ currentItem,
69
+ ...items
70
+ ].filter(Boolean);
71
+ const candidateNodes = candidateItems.map((item) => item.ref.current);
72
+ focusFirst(candidateNodes, { focusVisible: false });
73
+ }
74
+ }
75
+ isClickFocusRef.current = false;
76
+ }),
77
+ onBlur: composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))
78
+ })
79
+ });
82
80
  });
83
81
  const ITEM_NAME = "RovingFocusGroupItem";
84
- const RovingFocusGroupItem = React.forwardRef((props, forwardedRef) => {
85
- const {
86
- __scopeRovingFocusGroup,
87
- focusable = true,
88
- active = false,
89
- tabStopId,
90
- ...itemProps
91
- } = props;
92
- const autoId = React.useId();
93
- const id = tabStopId || autoId;
94
- const context = useRovingFocusContext(__scopeRovingFocusGroup);
95
- const isCurrentTabStop = context.currentTabStopId === id;
96
- const getItems = useCollection(__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT);
97
- const {
98
- onFocusableItemAdd,
99
- onFocusableItemRemove
100
- } = context;
101
- React.useEffect(() => {
102
- if (focusable) {
103
- onFocusableItemAdd();
104
- return () => onFocusableItemRemove();
105
- }
106
- }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);
107
- return /* @__PURE__ */jsx(Collection.ItemSlot, {
108
- scope: __scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT,
109
- id,
110
- focusable,
111
- active,
112
- children: /* @__PURE__ */jsx(View, {
113
- tabIndex: focusable ? 0 : -1,
114
- "data-orientation": context.orientation,
115
- ...itemProps,
116
- ref: forwardedRef,
117
- onMouseDown: composeEventHandlers(props.onMouseDown, event => {
118
- if (!focusable) event.preventDefault();else context.onItemFocus(id);
119
- }),
120
- onFocus: composeEventHandlers(props.onFocus, () => context.onItemFocus(id)),
121
- ...(isWeb && {
122
- onKeyDown: composeEventHandlers(props.onKeyDown, event => {
123
- if (event.key === "Tab" && event.shiftKey) {
124
- context.onItemShiftTab();
125
- return;
126
- }
127
- if (event.target !== event.currentTarget) return;
128
- const focusIntent = getFocusIntent(event, context.orientation, context.dir);
129
- if (focusIntent !== void 0) {
130
- event.preventDefault();
131
- const items = getItems().filter(item => item.focusable);
132
- let candidateNodes = items.map(item => item.ref.current);
133
- if (focusIntent === "last") candidateNodes.reverse();else if (focusIntent === "prev" || focusIntent === "next") {
134
- if (focusIntent === "prev") candidateNodes.reverse();
135
- const currentIndex = candidateNodes.indexOf(event.currentTarget);
136
- candidateNodes = context.loop ? wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
137
- }
138
- setTimeout(() => focusFirst(candidateNodes, {
139
- focusVisible: true
140
- }));
141
- }
142
- })
143
- })
144
- })
145
- });
82
+ const RovingFocusGroupItem = createRefComponent((props, forwardedRef) => {
83
+ const { __scopeRovingFocusGroup, active = false, tabStopId, tabIndex: tabIndexProp, ...itemProps } = props;
84
+ const tabIndex = tabIndexProp ?? 0;
85
+ const focusable = Number(tabIndex) >= 0;
86
+ const autoId = React.useId();
87
+ const id = tabStopId || autoId;
88
+ const context = useRovingFocusContext(__scopeRovingFocusGroup);
89
+ const isCurrentTabStop = context.currentTabStopId === id;
90
+ const getItems = useCollection(__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT);
91
+ const skipNextFocusRequestRef = React.useRef(false);
92
+ const { onFocusableItemAdd, onFocusableItemRemove } = context;
93
+ React.useEffect(() => {
94
+ if (focusable) {
95
+ onFocusableItemAdd();
96
+ return () => onFocusableItemRemove();
97
+ }
98
+ }, [
99
+ focusable,
100
+ onFocusableItemAdd,
101
+ onFocusableItemRemove
102
+ ]);
103
+ return /* @__PURE__ */ jsx(Collection.ItemSlot, {
104
+ scope: __scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT,
105
+ id,
106
+ focusable,
107
+ active,
108
+ children: /* @__PURE__ */ jsx(View, {
109
+ tabIndex,
110
+ "data-orientation": context.orientation,
111
+ ...itemProps,
112
+ ref: forwardedRef,
113
+ onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {
114
+ if (!focusable) event.preventDefault();
115
+ else {
116
+ skipNextFocusRequestRef.current = true;
117
+ queueMicrotask(() => {
118
+ skipNextFocusRequestRef.current = false;
119
+ });
120
+ context.onItemFocus(id, event);
121
+ }
122
+ }),
123
+ onFocus: composeEventHandlers(props.onFocus, (event) => {
124
+ if (skipNextFocusRequestRef.current) {
125
+ skipNextFocusRequestRef.current = false;
126
+ return;
127
+ }
128
+ context.onItemFocus(id, event);
129
+ }),
130
+ ...isWeb && { onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
131
+ if (event.key === "Tab" && event.shiftKey) {
132
+ context.onItemShiftTab();
133
+ return;
134
+ }
135
+ if (event.target !== event.currentTarget) return;
136
+ const focusIntent = getFocusIntent(event, context.orientation, context.dir);
137
+ if (focusIntent !== void 0) {
138
+ event.preventDefault();
139
+ const items = getItems().filter((item) => item.focusable);
140
+ let candidateNodes = items.map((item) => item.ref.current);
141
+ if (focusIntent === "last") candidateNodes.reverse();
142
+ else if (focusIntent === "prev" || focusIntent === "next") {
143
+ if (focusIntent === "prev") candidateNodes.reverse();
144
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
145
+ candidateNodes = context.loop ? wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
146
+ }
147
+ const details = createChangeEventDetails("keyboard", event, event.currentTarget);
148
+ setTimeout(() => {
149
+ context.setPendingFocusDetails(details);
150
+ focusFirst(candidateNodes, { focusVisible: true });
151
+ context.setPendingFocusDetails(null);
152
+ });
153
+ }
154
+ }) }
155
+ })
156
+ });
146
157
  });
147
158
  RovingFocusGroupItem.displayName = ITEM_NAME;
148
159
  const GROUP_NAME = "RovingFocusGroup";
149
160
  const [Collection, useCollection] = createCollection(GROUP_NAME);
150
- const {
151
- Provider: RovingFocusProvider,
152
- useStyledContext: useRovingFocusContext
153
- } = createStyledContext();
161
+ const { Provider: RovingFocusProvider, useStyledContext: useRovingFocusContext } = createStyledContext();
154
162
  const ROVING_FOCUS_GROUP_CONTEXT = "RovingFocusGroupContext";
155
- const RovingFocusGroup = withStaticProperties(React.forwardRef((props, forwardedRef) => {
156
- return /* @__PURE__ */jsx(Collection.Provider, {
157
- scope: props.__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT,
158
- children: /* @__PURE__ */jsx(Collection.Slot, {
159
- scope: props.__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT,
160
- children: /* @__PURE__ */jsx(RovingFocusGroupImpl, {
161
- ...props,
162
- ref: forwardedRef
163
- })
164
- })
165
- });
166
- }), {
167
- Item: RovingFocusGroupItem
168
- });
163
+ const RovingFocusGroup = withStaticProperties(createRefComponent((props, forwardedRef) => {
164
+ return /* @__PURE__ */ jsx(Collection.Provider, {
165
+ scope: props.__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT,
166
+ children: /* @__PURE__ */ jsx(Collection.Slot, {
167
+ scope: props.__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT,
168
+ children: /* @__PURE__ */ jsx(RovingFocusGroupImpl, {
169
+ ...props,
170
+ ref: forwardedRef
171
+ })
172
+ })
173
+ });
174
+ }), { Item: RovingFocusGroupItem });
169
175
  RovingFocusGroup.displayName = GROUP_NAME;
170
176
  const MAP_KEY_TO_FOCUS_INTENT = {
171
- ArrowLeft: "prev",
172
- ArrowUp: "prev",
173
- ArrowRight: "next",
174
- ArrowDown: "next",
175
- PageUp: "first",
176
- Home: "first",
177
- PageDown: "last",
178
- End: "last"
177
+ ArrowLeft: "prev",
178
+ ArrowUp: "prev",
179
+ ArrowRight: "next",
180
+ ArrowDown: "next",
181
+ PageUp: "first",
182
+ Home: "first",
183
+ PageDown: "last",
184
+ End: "last"
179
185
  };
180
186
  function getDirectionAwareKey(key, dir) {
181
- if (dir !== "rtl") return key;
182
- return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
187
+ if (dir !== "rtl") return key;
188
+ return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
183
189
  }
184
190
  function getFocusIntent(event, orientation, dir) {
185
- const key = getDirectionAwareKey(event.key, dir);
186
- if (orientation === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
187
- if (orientation === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
188
- return MAP_KEY_TO_FOCUS_INTENT[key];
191
+ const key = getDirectionAwareKey(event.key, dir);
192
+ if (orientation === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
193
+ if (orientation === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
194
+ return MAP_KEY_TO_FOCUS_INTENT[key];
189
195
  }
190
196
  function focusFirst(candidates, options) {
191
- const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
192
- for (const candidate of candidates) {
193
- if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
194
- candidate.focus({
195
- focusVisible: options?.focusVisible
196
- });
197
- if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
198
- }
197
+ const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
198
+ for (const candidate of candidates) {
199
+ if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
200
+ candidate.focus({ focusVisible: options?.focusVisible });
201
+ if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
202
+ }
199
203
  }
200
204
  function wrapArray(array, startIndex) {
201
- return array.map((_, index) => array[(startIndex + index) % array.length]);
205
+ return array.map((_, index) => array[(startIndex + index) % array.length]);
202
206
  }
207
+
203
208
  export { RovingFocusGroup, RovingFocusGroupItem };
204
209
  //# sourceMappingURL=RovingFocusGroup.mjs.map
@@ -1 +1 @@
1
- {"version":3,"names":["createCollection","useComposedRefs","isWeb","Slot","View","createStyledContext","useEvent","composeEventHandlers","withStaticProperties","useControllableState","useDirection","React","jsx","ENTRY_FOCUS","EVENT_OPTIONS","bubbles","cancelable","RovingFocusGroupImpl","forwardRef","props","forwardedRef","__scopeRovingFocusGroup","orientation","loop","dir","currentTabStopId","currentTabStopIdProp","defaultCurrentTabStopId","onCurrentTabStopIdChange","onEntryFocus","asChild","groupProps","ref","useRef","composedRefs","direction","setCurrentTabStopId","prop","defaultProp","onChange","isTabbingBackOut","setIsTabbingBackOut","useState","handleEntryFocus","getItems","useCollection","ROVING_FOCUS_GROUP_CONTEXT","isClickFocusRef","focusableItemsCount","setFocusableItemsCount","Comp","RovingFocusProvider","scope","onItemFocus","useCallback","tabStopId","onItemShiftTab","onFocusableItemAdd","prevCount","onFocusableItemRemove","children","tabIndex","outlineStyle","onMouseDown","current","onFocus","event","isKeyboardFocus","target","currentTarget","entryFocusEvent","CustomEvent","defaultPrevented","items","filter","item","focusable","activeItem","find","active","currentItem","id","candidateItems","Boolean","candidateNodes","map","focusFirst","focusVisible","onBlur","ITEM_NAME","RovingFocusGroupItem","itemProps","autoId","useId","context","useRovingFocusContext","isCurrentTabStop","useEffect","Collection","ItemSlot","preventDefault","onKeyDown","key","shiftKey","focusIntent","getFocusIntent","reverse","currentIndex","indexOf","wrapArray","slice","setTimeout","displayName","GROUP_NAME","Provider","useStyledContext","RovingFocusGroup","Item","MAP_KEY_TO_FOCUS_INTENT","ArrowLeft","ArrowUp","ArrowRight","ArrowDown","PageUp","Home","PageDown","End","getDirectionAwareKey","includes","candidates","options","PREVIOUSLY_FOCUSED_ELEMENT","document","activeElement","candidate","focus","array","startIndex","_","index","length"],"sources":["../../src/RovingFocusGroup.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"RovingFocusGroup.js","names":[],"sources":["esm/RovingFocusGroup.js"],"sourcesContent":["import { createCollection } from \"@tamagui/collection\";\nimport { useComposedRefs } from \"@tamagui/compose-refs\";\nimport { isWeb } from \"@tamagui/constants\";\nimport {\n Slot,\n View,\n createChangeEventDetails,\n createStyledContext,\n useEvent,\n createRefComponent\n} from \"@tamagui/core\";\nimport { composeEventHandlers, withStaticProperties } from \"@tamagui/helpers\";\nimport { useControllableState } from \"@tamagui/use-controllable-state\";\nimport { useDirection } from \"@tamagui/use-direction\";\nimport * as React from \"react\";\nimport { jsx } from \"react/jsx-runtime\";\nconst RovingFocusGroupImpl = createRefComponent((props, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n orientation,\n loop = false,\n dir,\n currentTabStopId: currentTabStopIdProp,\n defaultCurrentTabStopId,\n onCurrentTabStopIdChange,\n onEntryFocus,\n asChild,\n ...groupProps\n } = props;\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const direction = useDirection(dir);\n const [currentTabStopId = null, setCurrentTabStopId] = useControllableState({\n prop: currentTabStopIdProp,\n defaultProp: defaultCurrentTabStopId ?? null,\n onChange: (tabStopId, details) => {\n if (details) onCurrentTabStopIdChange?.(tabStopId, details);\n }\n });\n const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);\n const handleEntryFocus = useEvent(onEntryFocus);\n const getItems = useCollection(__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT);\n const isClickFocusRef = React.useRef(false);\n const pendingFocusDetailsRef = React.useRef(null);\n const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);\n const Comp = asChild ? Slot : View;\n return /* @__PURE__ */ jsx(\n RovingFocusProvider,\n {\n scope: __scopeRovingFocusGroup,\n orientation,\n dir: direction,\n loop,\n currentTabStopId,\n onItemFocus: React.useCallback(\n (tabStopId, event) => {\n if (tabStopId === currentTabStopId) return;\n const details = pendingFocusDetailsRef.current ?? createChangeEventDetails(\"trigger-focus\", event, event.currentTarget);\n pendingFocusDetailsRef.current = null;\n setCurrentTabStopId(tabStopId, details);\n },\n [currentTabStopId, setCurrentTabStopId]\n ),\n setPendingFocusDetails: React.useCallback((details) => {\n pendingFocusDetailsRef.current = details;\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 children: /* @__PURE__ */ jsx(\n Comp,\n {\n tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,\n \"data-orientation\": orientation,\n ...groupProps,\n ref: composedRefs,\n outlineStyle: \"none\",\n onMouseDown: composeEventHandlers(props.onMouseDown, () => {\n isClickFocusRef.current = true;\n }),\n onFocus: composeEventHandlers(props.onFocus, (event) => {\n const isKeyboardFocus = !isClickFocusRef.current;\n if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {\n const details = createChangeEventDetails(\n \"trigger-focus\",\n event,\n event.currentTarget\n );\n handleEntryFocus(details);\n if (!details.isCanceled) {\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 );\n const candidateNodes = candidateItems.map((item) => item.ref.current);\n focusFirst(candidateNodes, { focusVisible: false });\n }\n }\n isClickFocusRef.current = false;\n }),\n onBlur: composeEventHandlers(\n props.onBlur,\n () => setIsTabbingBackOut(false)\n )\n }\n )\n }\n );\n});\nconst ITEM_NAME = \"RovingFocusGroupItem\";\nconst RovingFocusGroupItem = createRefComponent((props, forwardedRef) => {\n const {\n __scopeRovingFocusGroup,\n active = false,\n tabStopId,\n tabIndex: tabIndexProp,\n ...itemProps\n } = props;\n const tabIndex = tabIndexProp ?? 0;\n const focusable = Number(tabIndex) >= 0;\n const autoId = React.useId();\n const id = tabStopId || autoId;\n const context = useRovingFocusContext(__scopeRovingFocusGroup);\n const isCurrentTabStop = context.currentTabStopId === id;\n const getItems = useCollection(__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT);\n const skipNextFocusRequestRef = React.useRef(false);\n const { onFocusableItemAdd, onFocusableItemRemove } = context;\n React.useEffect(() => {\n if (focusable) {\n onFocusableItemAdd();\n return () => onFocusableItemRemove();\n }\n }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);\n return /* @__PURE__ */ jsx(\n Collection.ItemSlot,\n {\n scope: __scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT,\n id,\n focusable,\n active,\n children: /* @__PURE__ */ jsx(\n View,\n {\n tabIndex,\n \"data-orientation\": context.orientation,\n ...itemProps,\n ref: forwardedRef,\n onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {\n if (!focusable) event.preventDefault();\n else {\n skipNextFocusRequestRef.current = true;\n queueMicrotask(() => {\n skipNextFocusRequestRef.current = false;\n });\n context.onItemFocus(id, event);\n }\n }),\n onFocus: composeEventHandlers(props.onFocus, (event) => {\n if (skipNextFocusRequestRef.current) {\n skipNextFocusRequestRef.current = false;\n return;\n }\n context.onItemFocus(id, event);\n }),\n ...isWeb && {\n onKeyDown: composeEventHandlers(\n props.onKeyDown,\n (event) => {\n if (event.key === \"Tab\" && event.shiftKey) {\n context.onItemShiftTab();\n return;\n }\n if (event.target !== event.currentTarget) return;\n const focusIntent = getFocusIntent(event, context.orientation, context.dir);\n if (focusIntent !== void 0) {\n event.preventDefault();\n const items = getItems().filter((item) => item.focusable);\n let candidateNodes = items.map((item) => item.ref.current);\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 ? wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);\n }\n const details = createChangeEventDetails(\n \"keyboard\",\n event,\n event.currentTarget\n );\n setTimeout(() => {\n context.setPendingFocusDetails(details);\n focusFirst(candidateNodes, { focusVisible: true });\n context.setPendingFocusDetails(null);\n });\n }\n }\n )\n }\n }\n )\n }\n );\n});\nRovingFocusGroupItem.displayName = ITEM_NAME;\nconst GROUP_NAME = \"RovingFocusGroup\";\nconst [Collection, useCollection] = createCollection(GROUP_NAME);\nconst { Provider: RovingFocusProvider, useStyledContext: useRovingFocusContext } = createStyledContext();\nconst ROVING_FOCUS_GROUP_CONTEXT = \"RovingFocusGroupContext\";\nconst RovingFocusGroup = withStaticProperties(\n createRefComponent(\n (props, forwardedRef) => {\n return /* @__PURE__ */ jsx(\n Collection.Provider,\n {\n scope: props.__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT,\n children: /* @__PURE__ */ jsx(\n Collection.Slot,\n {\n scope: props.__scopeRovingFocusGroup || ROVING_FOCUS_GROUP_CONTEXT,\n children: /* @__PURE__ */ jsx(RovingFocusGroupImpl, { ...props, ref: forwardedRef })\n }\n )\n }\n );\n }\n ),\n {\n Item: RovingFocusGroupItem\n }\n);\nRovingFocusGroup.displayName = GROUP_NAME;\nconst MAP_KEY_TO_FOCUS_INTENT = {\n ArrowLeft: \"prev\",\n ArrowUp: \"prev\",\n ArrowRight: \"next\",\n ArrowDown: \"next\",\n PageUp: \"first\",\n Home: \"first\",\n PageDown: \"last\",\n End: \"last\"\n};\nfunction getDirectionAwareKey(key, dir) {\n if (dir !== \"rtl\") return key;\n return key === \"ArrowLeft\" ? \"ArrowRight\" : key === \"ArrowRight\" ? \"ArrowLeft\" : key;\n}\nfunction getFocusIntent(event, orientation, dir) {\n const key = getDirectionAwareKey(event.key, dir);\n if (orientation === \"vertical\" && [\"ArrowLeft\", \"ArrowRight\"].includes(key))\n return void 0;\n if (orientation === \"horizontal\" && [\"ArrowUp\", \"ArrowDown\"].includes(key))\n return void 0;\n return MAP_KEY_TO_FOCUS_INTENT[key];\n}\nfunction focusFirst(candidates, options) {\n const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;\n for (const candidate of candidates) {\n if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;\n candidate.focus({ focusVisible: options?.focusVisible });\n if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;\n }\n}\nfunction wrapArray(array, startIndex) {\n return array.map((_, index) => array[(startIndex + index) % array.length]);\n}\nexport {\n RovingFocusGroup,\n RovingFocusGroupItem\n};\n//# sourceMappingURL=RovingFocusGroup.js.map\n"],"mappings":"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"}
@@ -1,21 +1,17 @@
1
- import { styled, View } from "@tamagui/core";
1
+ import { View, styled } from "@tamagui/core";
2
2
  import { withStaticProperties } from "@tamagui/helpers";
3
+
3
4
  var ITEM_NAME = "RovingFocusGroupItem";
4
- var RovingFocusGroupItem = styled(View, {
5
- name: ITEM_NAME
6
- });
5
+ var RovingFocusGroupItem = styled(View, { displayName: ITEM_NAME });
7
6
  var GROUP_NAME = "RovingFocusGroup";
8
- var RovingFocusGroupFrame = styled(View, {
9
- name: GROUP_NAME
10
- });
11
- var RovingFocusGroup = withStaticProperties(RovingFocusGroupFrame, {
12
- Item: RovingFocusGroupItem
13
- });
7
+ var RovingFocusGroupFrame = styled(View, { displayName: GROUP_NAME });
8
+ var RovingFocusGroup = withStaticProperties(RovingFocusGroupFrame, { Item: RovingFocusGroupItem });
14
9
  RovingFocusGroup.displayName = GROUP_NAME;
15
- var createRovingFocusGroupScope = function () {
16
- return function () {
17
- return {};
18
- };
10
+ var createRovingFocusGroupScope = function() {
11
+ return function() {
12
+ return {};
13
+ };
19
14
  };
15
+
20
16
  export { RovingFocusGroup, createRovingFocusGroupScope };
21
17
  //# sourceMappingURL=RovingFocusGroup.native.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["styled","View","withStaticProperties","ITEM_NAME","RovingFocusGroupItem","name","GROUP_NAME","RovingFocusGroupFrame","RovingFocusGroup","Item","displayName","createRovingFocusGroupScope"],"sources":["../../src/RovingFocusGroup.native.tsx"],"sourcesContent":[null],"mappings":"AAAA,SAASA,MAAA,EAAQC,IAAA,QAAY;AAC7B,SAASC,oBAAA,QAA4B;AAErC,IAAIC,SAAA,GAAY;AAChB,IAAIC,oBAAA,GAAuBJ,MAAA,CAAOC,IAAA,EAAM;EACpCI,IAAA,EAAMF;AACV,CAAC;AACD,IAAIG,UAAA,GAAa;AACjB,IAAIC,qBAAA,GAAwBP,MAAA,CAAOC,IAAA,EAAM;EACrCI,IAAA,EAAMC;AACV,CAAC;AACD,IAAIE,gBAAA,GAAmBN,oBAAA,CAAqBK,qBAAA,EAAuB;EAC/DE,IAAA,EAAML;AACV,CAAC;AACDI,gBAAA,CAAiBE,WAAA,GAAcJ,UAAA;AAC/B,IAAIK,2BAAA,GAA8B,SAAAA,CAAA,EAAW;EACzC,OAAO,YAAW;IACd,OAAO,CAAC;EACZ;AACJ","ignoreList":[]}
1
+ {"version":3,"file":"RovingFocusGroup.native.js","names":[],"sources":["esm/RovingFocusGroup.native.js"],"sourcesContent":["import { styled, View } from \"@tamagui/core\";\nimport { withStaticProperties } from \"@tamagui/helpers\";\nvar ITEM_NAME = \"RovingFocusGroupItem\";\nvar RovingFocusGroupItem = styled(View, {\n displayName: ITEM_NAME\n});\nvar GROUP_NAME = \"RovingFocusGroup\";\nvar RovingFocusGroupFrame = styled(View, {\n displayName: GROUP_NAME\n});\nvar RovingFocusGroup = withStaticProperties(RovingFocusGroupFrame, {\n Item: RovingFocusGroupItem\n});\nRovingFocusGroup.displayName = GROUP_NAME;\nvar createRovingFocusGroupScope = function() {\n return function() {\n return {};\n };\n};\nexport {\n RovingFocusGroup,\n createRovingFocusGroupScope\n};\n//# sourceMappingURL=RovingFocusGroup.native.js.map\n"],"mappings":";;;;AAEA,IAAI,YAAY;AAChB,IAAI,uBAAuB,OAAO,MAAM,EACtC,aAAa,UACf,CAAC;AACD,IAAI,aAAa;AACjB,IAAI,wBAAwB,OAAO,MAAM,EACvC,aAAa,WACf,CAAC;AACD,IAAI,mBAAmB,qBAAqB,uBAAuB,EACjE,MAAM,qBACR,CAAC;AACD,iBAAiB,cAAc;AAC/B,IAAI,8BAA8B,WAAW;CAC3C,OAAO,WAAW;EAChB,OAAO,CAAC;CACV;AACF"}
package/dist/esm/index.js CHANGED
@@ -1,2 +1 @@
1
- export * from "./RovingFocusGroup.mjs";
2
- //# sourceMappingURL=index.js.map
1
+ export * from "./RovingFocusGroup.mjs"
@@ -1,2 +1 @@
1
- export * from "./RovingFocusGroup.mjs";
2
- //# sourceMappingURL=index.mjs.map
1
+ export * from "./RovingFocusGroup.mjs"
@@ -1,2 +1 @@
1
- export * from "./RovingFocusGroup.native.js";
2
- //# sourceMappingURL=index.native.js.map
1
+ export * from "./RovingFocusGroup.native.js"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/roving-focus",
3
- "version": "2.7.7",
3
+ "version": "3.0.0-beta.643.1",
4
4
  "gitHead": "a49cc7ea6b93ba384e77a4880ae48ac4a5635c14",
5
5
  "source": "src/index.ts",
6
6
  "files": [
@@ -35,18 +35,18 @@
35
35
  "clean:build": "tamagui-build clean:build"
36
36
  },
37
37
  "dependencies": {
38
- "@tamagui/collection": "2.7.7",
39
- "@tamagui/compose-refs": "2.7.7",
40
- "@tamagui/constants": "2.7.7",
41
- "@tamagui/core": "2.7.7",
42
- "@tamagui/create-context": "2.7.7",
43
- "@tamagui/helpers": "2.7.7",
44
- "@tamagui/use-controllable-state": "2.7.7",
45
- "@tamagui/use-direction": "2.7.7",
46
- "@tamagui/use-event": "2.7.7"
38
+ "@tamagui/collection": "3.0.0-beta.643.1",
39
+ "@tamagui/compose-refs": "3.0.0-beta.643.1",
40
+ "@tamagui/constants": "3.0.0-beta.643.1",
41
+ "@tamagui/core": "3.0.0-beta.643.1",
42
+ "@tamagui/create-context": "3.0.0-beta.643.1",
43
+ "@tamagui/helpers": "3.0.0-beta.643.1",
44
+ "@tamagui/use-controllable-state": "3.0.0-beta.643.1",
45
+ "@tamagui/use-direction": "3.0.0-beta.643.1",
46
+ "@tamagui/use-event": "3.0.0-beta.643.1"
47
47
  },
48
48
  "devDependencies": {
49
- "@tamagui/build": "2.7.7",
49
+ "@tamagui/build": "3.0.0-beta.643.1",
50
50
  "react": ">=19"
51
51
  },
52
52
  "peerDependencies": {
@@ -7,12 +7,12 @@ import type { RovingFocusGroupProps, RovingFocusItemProps } from './RovingFocusG
7
7
 
8
8
  const ITEM_NAME = 'RovingFocusGroupItem'
9
9
  const RovingFocusGroupItem = styled(View, {
10
- name: ITEM_NAME,
10
+ displayName: ITEM_NAME,
11
11
  })
12
12
 
13
13
  const GROUP_NAME = 'RovingFocusGroup'
14
14
  const RovingFocusGroupFrame = styled(View, {
15
- name: GROUP_NAME,
15
+ displayName: GROUP_NAME,
16
16
  })
17
17
 
18
18
  const RovingFocusGroup = withStaticProperties(