@radix-ui/react-roving-focus 0.1.6-rc.4 → 0.1.6-rc.7

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 +1 @@
1
- {"mappings":"A;A;A;AA8BA,OAAA,kGAGC,CAAC;AAEF,mBAAmB,MAAM,cAAc,CAAC,kBAAkB,CAAC,CAAC;AAC5D,iBAAiB,KAAK,GAAG,KAAK,CAAC;AAE/B;IACE;A;A;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;A;OAEG;IACH,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB;A;A;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAYD,sCAAgC,SAAQ,yBAAyB;CAAG;AAEpE,OAAA,MAAM,8GAUL,CAAC;AAOF,yBAAyB,MAAM,wBAAwB,CAAC,OAAO,UAAU,GAAG,CAAC,CAAC;AAC9E,mCACE,SAAQ,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,EACpC,uBAAuB;IACzB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,wBAAwB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACvC;AAkGD,0BAA0B,MAAM,wBAAwB,CAAC,OAAO,UAAU,IAAI,CAAC,CAAC;AAChF,qCAA+B,SAAQ,kBAAkB;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,OAAA,MAAM,kHA+DL,CAAC;AA8CF,OAAA,MAAM,kGAAuB,CAAC;AAC9B,OAAA,MAAM,kGAA2B,CAAC","sources":["./packages/react/roving-focus/src/packages/react/roving-focus/src/RovingFocusGroup.tsx","./packages/react/roving-focus/src/packages/react/roving-focus/src/index.ts"],"sourcesContent":[null,null],"names":[],"version":3,"file":"index.d.ts.map"}
1
+ {"mappings":";;;AA8BA,OAAA,kGAGC,CAAC;AAEF,mBAAmB,MAAM,cAAc,CAAC,kBAAkB,CAAC,CAAC;AAC5D,iBAAiB,KAAK,GAAG,KAAK,CAAC;AAE/B;IACE;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;OAEG;IACH,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAYD,sCAAgC,SAAQ,yBAAyB;CAAG;AAEpE,OAAA,MAAM,8GAUL,CAAC;AAOF,yBAAyB,MAAM,wBAAwB,CAAC,OAAO,UAAU,GAAG,CAAC,CAAC;AAC9E,mCACE,SAAQ,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,EACpC,uBAAuB;IACzB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,wBAAwB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACvC;AAkGD,0BAA0B,MAAM,wBAAwB,CAAC,OAAO,UAAU,IAAI,CAAC,CAAC;AAChF,qCAA+B,SAAQ,kBAAkB;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,OAAA,MAAM,kHA+DL,CAAC;AA8CF,OAAA,MAAM,kGAAuB,CAAC;AAC9B,OAAA,MAAM,kGAA2B,CAAC","sources":["packages/react/roving-focus/src/packages/react/roving-focus/src/RovingFocusGroup.tsx","packages/react/roving-focus/src/packages/react/roving-focus/src/index.ts","packages/react/roving-focus/src/index.ts"],"sourcesContent":[null,null,"export * from './RovingFocusGroup';\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/dist/index.js CHANGED
@@ -1,2 +1,266 @@
1
- var e,r,o,t=require("@radix-ui/react-direction").useDirection,n=require("@radix-ui/react-use-controllable-state").useControllableState,u=require("@radix-ui/react-use-callback-ref").useCallbackRef,i=require("@radix-ui/react-primitive").Primitive,c=require("@radix-ui/react-id").useId,a=require("@radix-ui/react-context").createContextScope,s=require("@radix-ui/react-compose-refs").useComposedRefs,l=require("@radix-ui/react-collection").createCollection,f=require("@radix-ui/primitive").composeEventHandlers,p=(e={},r=require("react"),Object.keys(r).forEach((function(o){"default"!==o&&"__esModule"!==o&&Object.defineProperty(e,o,{enumerable:!0,get:function(){return r[o]}})})),e),d=(o=require("@babel/runtime/helpers/extends"))&&o.__esModule?o.default:o;const v={bubbles:!1,cancelable:!0},[m,g,b]=l("RovingFocusGroup"),[w,F]=a("RovingFocusGroup",[b]);exports.createRovingFocusGroupScope=F;const[x,R]=w("RovingFocusGroup"),E=/*#__PURE__*/p.forwardRef(((e,r)=>/*#__PURE__*/p.createElement(m.Provider,{scope:e.__scopeRovingFocusGroup},/*#__PURE__*/p.createElement(m.Slot,{scope:e.__scopeRovingFocusGroup},/*#__PURE__*/p.createElement(I,d({},e,{ref:r}))))));exports.RovingFocusGroup=E;const I=/*#__PURE__*/p.forwardRef(((e,r)=>{const{__scopeRovingFocusGroup:o,orientation:c,loop:a=!1,dir:l,currentTabStopId:m,defaultCurrentTabStopId:b,onCurrentTabStopIdChange:w,onEntryFocus:F,...R}=e,E=p.useRef(null),I=s(r,E),h=t(l),[G=null,S]=n({prop:m,defaultProp:b,onChange:w}),[T,A]=p.useState(!1),D=u(F),_=g(o),q=p.useRef(!1);return p.useEffect((()=>{const e=E.current;if(e)return e.addEventListener("rovingFocusGroup.onEntryFocus",D),()=>e.removeEventListener("rovingFocusGroup.onEntryFocus",D)}),[D]),/*#__PURE__*/p.createElement(x,{scope:o,orientation:c,dir:h,loop:a,currentTabStopId:G,onItemFocus:p.useCallback((e=>S(e)),[S]),onItemShiftTab:p.useCallback((()=>A(!0)),[])},/*#__PURE__*/p.createElement(i.div,d({tabIndex:T?-1:0,"data-orientation":c},R,{ref:I,style:{outline:"none",...e.style},onMouseDown:f(e.onMouseDown,(()=>{q.current=!0})),onFocus:f(e.onFocus,(e=>{const r=!q.current;if(e.target===e.currentTarget&&r&&!T){const r=new Event("rovingFocusGroup.onEntryFocus",v);if(e.currentTarget.dispatchEvent(r),!r.defaultPrevented){const e=_().filter((e=>e.focusable));y([e.find((e=>e.active)),e.find((e=>e.id===G)),...e].filter(Boolean).map((e=>e.ref.current)))}}q.current=!1})),onBlur:f(e.onBlur,(()=>A(!1)))})))})),h=/*#__PURE__*/p.forwardRef(((e,r)=>{const{__scopeRovingFocusGroup:o,focusable:t=!0,active:n=!1,...u}=e,a=c(),s=R("RovingFocusGroupItem",o),l=s.currentTabStopId===a,v=g(o);/*#__PURE__*/return p.createElement(m.ItemSlot,{scope:o,id:a,focusable:t,active:n},/*#__PURE__*/p.createElement(i.span,d({tabIndex:l?0:-1,"data-orientation":s.orientation},u,{ref:r,onMouseDown:f(e.onMouseDown,(e=>{t?s.onItemFocus(a):e.preventDefault()})),onFocus:f(e.onFocus,(()=>s.onItemFocus(a))),onKeyDown:f(e.onKeyDown,(e=>{if("Tab"===e.key&&e.shiftKey)return void s.onItemShiftTab();if(e.target!==e.currentTarget)return;const r=function(e,r,o){const t=function(e,r){return"rtl"!==r?e:"ArrowLeft"===e?"ArrowRight":"ArrowRight"===e?"ArrowLeft":e}(e.key,o);return"vertical"===r&&["ArrowLeft","ArrowRight"].includes(t)||"horizontal"===r&&["ArrowUp","ArrowDown"].includes(t)?void 0:G[t]}(e,s.orientation,s.dir);if(void 0!==r){e.preventDefault();let n=v().filter((e=>e.focusable)).map((e=>e.ref.current));if("last"===r)n.reverse();else if("prev"===r||"next"===r){"prev"===r&&n.reverse();const u=n.indexOf(e.currentTarget);n=s.loop?(t=u+1,(o=n).map(((e,r)=>o[(t+r)%o.length]))):n.slice(u+1)}setTimeout((()=>y(n)))}var o,t}))})))}));exports.RovingFocusGroupItem=h;const G={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function y(e){const r=document.activeElement;for(const o of e){if(o===r)return;if(o.focus(),document.activeElement!==r)return}}const S=E;exports.Root=S;const T=h;exports.Item=T;
1
+ var $9QJ9Y$babelruntimehelpersextends = require("@babel/runtime/helpers/extends");
2
+ var $9QJ9Y$react = require("react");
3
+ var $9QJ9Y$radixuiprimitive = require("@radix-ui/primitive");
4
+ var $9QJ9Y$radixuireactcollection = require("@radix-ui/react-collection");
5
+ var $9QJ9Y$radixuireactcomposerefs = require("@radix-ui/react-compose-refs");
6
+ var $9QJ9Y$radixuireactcontext = require("@radix-ui/react-context");
7
+ var $9QJ9Y$radixuireactid = require("@radix-ui/react-id");
8
+ var $9QJ9Y$radixuireactprimitive = require("@radix-ui/react-primitive");
9
+ var $9QJ9Y$radixuireactusecallbackref = require("@radix-ui/react-use-callback-ref");
10
+ var $9QJ9Y$radixuireactusecontrollablestate = require("@radix-ui/react-use-controllable-state");
11
+ var $9QJ9Y$radixuireactdirection = require("@radix-ui/react-direction");
12
+
13
+ function $parcel$exportWildcard(dest, source) {
14
+ Object.keys(source).forEach(function(key) {
15
+ if (key === 'default' || key === '__esModule' || dest.hasOwnProperty(key)) {
16
+ return;
17
+ }
18
+
19
+ Object.defineProperty(dest, key, {
20
+ enumerable: true,
21
+ get: function get() {
22
+ return source[key];
23
+ }
24
+ });
25
+ });
26
+
27
+ return dest;
28
+ }
29
+ function $parcel$interopDefault(a) {
30
+ return a && a.__esModule ? a.default : a;
31
+ }
32
+ function $parcel$export(e, n, v, s) {
33
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
34
+ }
35
+ var $0063afae63b3fa70$exports = {};
36
+
37
+ $parcel$export($0063afae63b3fa70$exports, "createRovingFocusGroupScope", () => $0063afae63b3fa70$export$c7109489551a4f4);
38
+ $parcel$export($0063afae63b3fa70$exports, "RovingFocusGroup", () => $0063afae63b3fa70$export$8699f7c8af148338);
39
+ $parcel$export($0063afae63b3fa70$exports, "RovingFocusGroupItem", () => $0063afae63b3fa70$export$ab9df7c53fe8454);
40
+ $parcel$export($0063afae63b3fa70$exports, "Root", () => $0063afae63b3fa70$export$be92b6f5f03c0fe9);
41
+ $parcel$export($0063afae63b3fa70$exports, "Item", () => $0063afae63b3fa70$export$6d08773d2e66f8f2);
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+ const $0063afae63b3fa70$var$ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';
54
+ const $0063afae63b3fa70$var$EVENT_OPTIONS = {
55
+ bubbles: false,
56
+ cancelable: true
57
+ };
58
+ /* -------------------------------------------------------------------------------------------------
59
+ * RovingFocusGroup
60
+ * -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$GROUP_NAME = 'RovingFocusGroup';
61
+ const [$0063afae63b3fa70$var$Collection, $0063afae63b3fa70$var$useCollection, $0063afae63b3fa70$var$createCollectionScope] = $9QJ9Y$radixuireactcollection.createCollection($0063afae63b3fa70$var$GROUP_NAME);
62
+ const [$0063afae63b3fa70$var$createRovingFocusGroupContext, $0063afae63b3fa70$export$c7109489551a4f4] = $9QJ9Y$radixuireactcontext.createContextScope($0063afae63b3fa70$var$GROUP_NAME, [
63
+ $0063afae63b3fa70$var$createCollectionScope
64
+ ]);
65
+ const [$0063afae63b3fa70$var$RovingFocusProvider, $0063afae63b3fa70$var$useRovingFocusContext] = $0063afae63b3fa70$var$createRovingFocusGroupContext($0063afae63b3fa70$var$GROUP_NAME);
66
+ const $0063afae63b3fa70$export$8699f7c8af148338 = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{
67
+ return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.Provider, {
68
+ scope: props.__scopeRovingFocusGroup
69
+ }, /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.Slot, {
70
+ scope: props.__scopeRovingFocusGroup
71
+ }, /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$RovingFocusGroupImpl, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({}, props, {
72
+ ref: forwardedRef
73
+ }))));
74
+ });
75
+ /*#__PURE__*/ Object.assign($0063afae63b3fa70$export$8699f7c8af148338, {
76
+ displayName: $0063afae63b3fa70$var$GROUP_NAME
77
+ });
78
+ /* -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$RovingFocusGroupImpl = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{
79
+ const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , orientation: orientation , loop: loop = false , dir: dir , currentTabStopId: currentTabStopIdProp , defaultCurrentTabStopId: defaultCurrentTabStopId , onCurrentTabStopIdChange: onCurrentTabStopIdChange , onEntryFocus: onEntryFocus , ...groupProps } = props;
80
+ const ref = $9QJ9Y$react.useRef(null);
81
+ const composedRefs = $9QJ9Y$radixuireactcomposerefs.useComposedRefs(forwardedRef, ref);
82
+ const direction = $9QJ9Y$radixuireactdirection.useDirection(dir);
83
+ const [currentTabStopId = null, setCurrentTabStopId] = $9QJ9Y$radixuireactusecontrollablestate.useControllableState({
84
+ prop: currentTabStopIdProp,
85
+ defaultProp: defaultCurrentTabStopId,
86
+ onChange: onCurrentTabStopIdChange
87
+ });
88
+ const [isTabbingBackOut, setIsTabbingBackOut] = $9QJ9Y$react.useState(false);
89
+ const handleEntryFocus = $9QJ9Y$radixuireactusecallbackref.useCallbackRef(onEntryFocus);
90
+ const getItems = $0063afae63b3fa70$var$useCollection(__scopeRovingFocusGroup);
91
+ const isClickFocusRef = $9QJ9Y$react.useRef(false);
92
+ $9QJ9Y$react.useEffect(()=>{
93
+ const node = ref.current;
94
+ if (node) {
95
+ node.addEventListener($0063afae63b3fa70$var$ENTRY_FOCUS, handleEntryFocus);
96
+ return ()=>node.removeEventListener($0063afae63b3fa70$var$ENTRY_FOCUS, handleEntryFocus)
97
+ ;
98
+ }
99
+ }, [
100
+ handleEntryFocus
101
+ ]);
102
+ return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$RovingFocusProvider, {
103
+ scope: __scopeRovingFocusGroup,
104
+ orientation: orientation,
105
+ dir: direction,
106
+ loop: loop,
107
+ currentTabStopId: currentTabStopId,
108
+ onItemFocus: $9QJ9Y$react.useCallback((tabStopId)=>setCurrentTabStopId(tabStopId)
109
+ , [
110
+ setCurrentTabStopId
111
+ ]),
112
+ onItemShiftTab: $9QJ9Y$react.useCallback(()=>setIsTabbingBackOut(true)
113
+ , [])
114
+ }, /*#__PURE__*/ $9QJ9Y$react.createElement($9QJ9Y$radixuireactprimitive.Primitive.div, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({
115
+ tabIndex: isTabbingBackOut ? -1 : 0,
116
+ "data-orientation": orientation
117
+ }, groupProps, {
118
+ ref: composedRefs,
119
+ style: {
120
+ outline: 'none',
121
+ ...props.style
122
+ },
123
+ onMouseDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onMouseDown, ()=>{
124
+ isClickFocusRef.current = true;
125
+ }),
126
+ onFocus: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onFocus, (event)=>{
127
+ // We normally wouldn't need this check, because we already check
128
+ // that the focus is on the current target and not bubbling to it.
129
+ // We do this because Safari doesn't focus buttons when clicked, and
130
+ // instead, the wrapper will get focused and not through a bubbling event.
131
+ const isKeyboardFocus = !isClickFocusRef.current;
132
+ if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
133
+ const entryFocusEvent = new Event($0063afae63b3fa70$var$ENTRY_FOCUS, $0063afae63b3fa70$var$EVENT_OPTIONS);
134
+ event.currentTarget.dispatchEvent(entryFocusEvent);
135
+ if (!entryFocusEvent.defaultPrevented) {
136
+ const items = getItems().filter((item)=>item.focusable
137
+ );
138
+ const activeItem = items.find((item)=>item.active
139
+ );
140
+ const currentItem = items.find((item)=>item.id === currentTabStopId
141
+ );
142
+ const candidateItems = [
143
+ activeItem,
144
+ currentItem,
145
+ ...items
146
+ ].filter(Boolean);
147
+ const candidateNodes = candidateItems.map((item)=>item.ref.current
148
+ );
149
+ $0063afae63b3fa70$var$focusFirst(candidateNodes);
150
+ }
151
+ }
152
+ isClickFocusRef.current = false;
153
+ }),
154
+ onBlur: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onBlur, ()=>setIsTabbingBackOut(false)
155
+ )
156
+ })));
157
+ });
158
+ /* -------------------------------------------------------------------------------------------------
159
+ * RovingFocusGroupItem
160
+ * -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$ITEM_NAME = 'RovingFocusGroupItem';
161
+ const $0063afae63b3fa70$export$ab9df7c53fe8454 = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{
162
+ const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , focusable: focusable = true , active: active = false , ...itemProps } = props;
163
+ const id = $9QJ9Y$radixuireactid.useId();
164
+ const context = $0063afae63b3fa70$var$useRovingFocusContext($0063afae63b3fa70$var$ITEM_NAME, __scopeRovingFocusGroup);
165
+ const isCurrentTabStop = context.currentTabStopId === id;
166
+ const getItems = $0063afae63b3fa70$var$useCollection(__scopeRovingFocusGroup);
167
+ return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.ItemSlot, {
168
+ scope: __scopeRovingFocusGroup,
169
+ id: id,
170
+ focusable: focusable,
171
+ active: active
172
+ }, /*#__PURE__*/ $9QJ9Y$react.createElement($9QJ9Y$radixuireactprimitive.Primitive.span, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({
173
+ tabIndex: isCurrentTabStop ? 0 : -1,
174
+ "data-orientation": context.orientation
175
+ }, itemProps, {
176
+ ref: forwardedRef,
177
+ onMouseDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onMouseDown, (event)=>{
178
+ // We prevent focusing non-focusable items on `mousedown`.
179
+ // Even though the item has tabIndex={-1}, that only means take it out of the tab order.
180
+ if (!focusable) event.preventDefault(); // Safari doesn't focus a button when clicked so we run our logic on mousedown also
181
+ else context.onItemFocus(id);
182
+ }),
183
+ onFocus: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onFocus, ()=>context.onItemFocus(id)
184
+ ),
185
+ onKeyDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onKeyDown, (event)=>{
186
+ if (event.key === 'Tab' && event.shiftKey) {
187
+ context.onItemShiftTab();
188
+ return;
189
+ }
190
+ if (event.target !== event.currentTarget) return;
191
+ const focusIntent = $0063afae63b3fa70$var$getFocusIntent(event, context.orientation, context.dir);
192
+ if (focusIntent !== undefined) {
193
+ event.preventDefault();
194
+ const items = getItems().filter((item)=>item.focusable
195
+ );
196
+ let candidateNodes = items.map((item)=>item.ref.current
197
+ );
198
+ if (focusIntent === 'last') candidateNodes.reverse();
199
+ else if (focusIntent === 'prev' || focusIntent === 'next') {
200
+ if (focusIntent === 'prev') candidateNodes.reverse();
201
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
202
+ candidateNodes = context.loop ? $0063afae63b3fa70$var$wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
203
+ }
204
+ /**
205
+ * Imperative focus during keydown is risky so we prevent React's batching updates
206
+ * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332
207
+ */ setTimeout(()=>$0063afae63b3fa70$var$focusFirst(candidateNodes)
208
+ );
209
+ }
210
+ })
211
+ })));
212
+ });
213
+ /*#__PURE__*/ Object.assign($0063afae63b3fa70$export$ab9df7c53fe8454, {
214
+ displayName: $0063afae63b3fa70$var$ITEM_NAME
215
+ });
216
+ /* -----------------------------------------------------------------------------------------------*/ // prettier-ignore
217
+ const $0063afae63b3fa70$var$MAP_KEY_TO_FOCUS_INTENT = {
218
+ ArrowLeft: 'prev',
219
+ ArrowUp: 'prev',
220
+ ArrowRight: 'next',
221
+ ArrowDown: 'next',
222
+ PageUp: 'first',
223
+ Home: 'first',
224
+ PageDown: 'last',
225
+ End: 'last'
226
+ };
227
+ function $0063afae63b3fa70$var$getDirectionAwareKey(key, dir) {
228
+ if (dir !== 'rtl') return key;
229
+ return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;
230
+ }
231
+ function $0063afae63b3fa70$var$getFocusIntent(event, orientation, dir) {
232
+ const key = $0063afae63b3fa70$var$getDirectionAwareKey(event.key, dir);
233
+ if (orientation === 'vertical' && [
234
+ 'ArrowLeft',
235
+ 'ArrowRight'
236
+ ].includes(key)) return undefined;
237
+ if (orientation === 'horizontal' && [
238
+ 'ArrowUp',
239
+ 'ArrowDown'
240
+ ].includes(key)) return undefined;
241
+ return $0063afae63b3fa70$var$MAP_KEY_TO_FOCUS_INTENT[key];
242
+ }
243
+ function $0063afae63b3fa70$var$focusFirst(candidates) {
244
+ const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
245
+ for (const candidate of candidates){
246
+ // if focus is already where we want to go, we don't want to keep going through the candidates
247
+ if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
248
+ candidate.focus();
249
+ if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
250
+ }
251
+ }
252
+ /**
253
+ * Wraps an array around itself at a given start index
254
+ * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
255
+ */ function $0063afae63b3fa70$var$wrapArray(array, startIndex) {
256
+ return array.map((_, index)=>array[(startIndex + index) % array.length]
257
+ );
258
+ }
259
+ const $0063afae63b3fa70$export$be92b6f5f03c0fe9 = $0063afae63b3fa70$export$8699f7c8af148338;
260
+ const $0063afae63b3fa70$export$6d08773d2e66f8f2 = $0063afae63b3fa70$export$ab9df7c53fe8454;
261
+
262
+
263
+ $parcel$exportWildcard(module.exports, $0063afae63b3fa70$exports);
264
+
265
+
2
266
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"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","sources":["./node_modules/@parcel/scope-hoisting/lib/helpers.js","./packages/react/roving-focus/src/RovingFocusGroup.tsx"],"sourcesContent":["function $parcel$interopDefault(a) {\n return a && a.__esModule ? a.default : a;\n}\n\nfunction $parcel$defineInteropFlag(a) {\n Object.defineProperty(a, '__esModule', {value: true});\n}\n\nfunction $parcel$reexport(e, n, v) {\n Object.defineProperty(e, n, {get: v, enumerable: true});\n}\n\nfunction $parcel$exportWildcard(dest, source) {\n Object.keys(source).forEach(function(key) {\n if (key === 'default' || key === '__esModule') {\n return;\n }\n\n Object.defineProperty(dest, key, {\n enumerable: true,\n get: function get() {\n return source[key];\n },\n });\n });\n\n return dest;\n}\n\nfunction $parcel$missingModule(name) {\n var err = new Error(\"Cannot find module '\" + name + \"'\");\n err.code = 'MODULE_NOT_FOUND';\n throw err;\n}\n\nvar $parcel$global =\n typeof globalThis !== 'undefined'\n ? globalThis\n : typeof self !== 'undefined'\n ? self\n : typeof window !== 'undefined'\n ? window\n : typeof global !== 'undefined'\n ? global\n : {};\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 * 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};\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}\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 ...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\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 >\n <Primitive.div\n tabIndex={isTabbingBackOut ? -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 Event(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);\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 focusable?: boolean;\n active?: boolean;\n}\n\nconst RovingFocusGroupItem = React.forwardRef<RovingFocusItemElement, RovingFocusItemProps>(\n (props: ScopedProps<RovingFocusItemProps>, forwardedRef) => {\n const { __scopeRovingFocusGroup, focusable = true, active = false, ...itemProps } = props;\n const id = useId();\n const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);\n const isCurrentTabStop = context.currentTabStopId === id;\n const getItems = useCollection(__scopeRovingFocusGroup);\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 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[]) {\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();\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"],"names":["dest","source","a","Object","keys","forEach","key","defineProperty","enumerable","get","__esModule","default","EVENT_OPTIONS","bubbles","cancelable","Collection","useCollection","createCollectionScope","createCollection","createRovingFocusGroupContext","createRovingFocusGroupScope","createContextScope","RovingFocusProvider","useRovingFocusContext","RovingFocusGroup","React","forwardRef","props","forwardedRef","_react","createElement","$e775be37c80f9cb18a9ef43638f10ed0$var$Collection","Provider","scope","__scopeRovingFocusGroup","Slot","$e775be37c80f9cb18a9ef43638f10ed0$var$RovingFocusGroupImpl","_babelRuntimeHelpersExtends","ref","RovingFocusGroupImpl","orientation","loop","dir","currentTabStopId","currentTabStopIdProp","defaultCurrentTabStopId","onCurrentTabStopIdChange","onEntryFocus","groupProps","useRef","composedRefs","useComposedRefs","direction","useDirection","setCurrentTabStopId","useControllableState","prop","defaultProp","onChange","isTabbingBackOut","setIsTabbingBackOut","useState","handleEntryFocus","useCallbackRef","getItems","isClickFocusRef","useEffect","node","current","addEventListener","removeEventListener","$e775be37c80f9cb18a9ef43638f10ed0$var$RovingFocusProvider","onItemFocus","useCallback","tabStopId","onItemShiftTab","Primitive","div","tabIndex","style","outline","onMouseDown","composeEventHandlers","onFocus","event","isKeyboardFocus","target","currentTarget","entryFocusEvent","Event","dispatchEvent","defaultPrevented","items","filter","item","focusable","focusFirst","find","active","id","Boolean","map","onBlur","RovingFocusGroupItem","itemProps","useId","context","isCurrentTabStop","ItemSlot","span","preventDefault","onKeyDown","shiftKey","focusIntent","getDirectionAwareKey","includes","MAP_KEY_TO_FOCUS_INTENT","getFocusIntent","undefined","candidateNodes","reverse","currentIndex","indexOf","startIndex","array","_","index","length","slice","setTimeout","ArrowLeft","ArrowUp","ArrowRight","ArrowDown","PageUp","Home","PageDown","End","candidates","PREVIOUSLY_FOCUSED_ELEMENT","document","activeElement","candidate","focus","Root","Item"],"version":3,"file":"index.js.map"}
1
+ {"mappings":"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","sources":["packages/react/roving-focus/src/index.ts","packages/react/roving-focus/src/RovingFocusGroup.tsx"],"sourcesContent":["export * 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 * 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};\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}\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 ...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\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 >\n <Primitive.div\n tabIndex={isTabbingBackOut ? -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 Event(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);\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 focusable?: boolean;\n active?: boolean;\n}\n\nconst RovingFocusGroupItem = React.forwardRef<RovingFocusItemElement, RovingFocusItemProps>(\n (props: ScopedProps<RovingFocusItemProps>, forwardedRef) => {\n const { __scopeRovingFocusGroup, focusable = true, active = false, ...itemProps } = props;\n const id = useId();\n const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);\n const isCurrentTabStop = context.currentTabStopId === id;\n const getItems = useCollection(__scopeRovingFocusGroup);\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 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[]) {\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();\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"],"names":["React","composeEventHandlers","createCollection","useComposedRefs","createContextScope","useId","Primitive","useCallbackRef","useControllableState","useDirection","ENTRY_FOCUS","EVENT_OPTIONS","bubbles","cancelable","GROUP_NAME","Collection","useCollection","createCollectionScope","createRovingFocusGroupContext","createRovingFocusGroupScope","RovingFocusProvider","useRovingFocusContext","RovingFocusGroup","forwardRef","props","forwardedRef","__scopeRovingFocusGroup","RovingFocusGroupImpl","orientation","loop","dir","currentTabStopId","currentTabStopIdProp","defaultCurrentTabStopId","onCurrentTabStopIdChange","onEntryFocus","groupProps","ref","useRef","composedRefs","direction","setCurrentTabStopId","prop","defaultProp","onChange","isTabbingBackOut","setIsTabbingBackOut","useState","handleEntryFocus","getItems","isClickFocusRef","useEffect","node","current","addEventListener","removeEventListener","useCallback","tabStopId","outline","style","onMouseDown","onFocus","event","isKeyboardFocus","target","currentTarget","entryFocusEvent","Event","dispatchEvent","defaultPrevented","items","filter","item","focusable","activeItem","find","active","currentItem","id","candidateItems","Boolean","candidateNodes","map","focusFirst","onBlur","ITEM_NAME","RovingFocusGroupItem","itemProps","context","isCurrentTabStop","preventDefault","onItemFocus","onKeyDown","key","shiftKey","onItemShiftTab","focusIntent","getFocusIntent","undefined","reverse","currentIndex","indexOf","wrapArray","slice","setTimeout","MAP_KEY_TO_FOCUS_INTENT","ArrowLeft","ArrowUp","ArrowRight","ArrowDown","PageUp","Home","PageDown","End","getDirectionAwareKey","includes","candidates","PREVIOUSLY_FOCUSED_ELEMENT","document","activeElement","candidate","focus","array","startIndex","_","index","length","Root","Item"],"version":3,"file":"index.js.map"}
@@ -1,2 +1,247 @@
1
- import{useDirection as e}from"@radix-ui/react-direction";import{useControllableState as o}from"@radix-ui/react-use-controllable-state";import{useCallbackRef as r}from"@radix-ui/react-use-callback-ref";import{Primitive as t}from"@radix-ui/react-primitive";import{useId as n}from"@radix-ui/react-id";import{createContextScope as i}from"@radix-ui/react-context";import{useComposedRefs as c}from"@radix-ui/react-compose-refs";import{createCollection as u}from"@radix-ui/react-collection";import{composeEventHandlers as a}from"@radix-ui/primitive";import*as s from"react";import f from"@babel/runtime/helpers/esm/extends";const p={bubbles:!1,cancelable:!0},[l,m,d]=u("RovingFocusGroup"),[v,g]=i("RovingFocusGroup",[d]);export{g as createRovingFocusGroupScope};const[F,w]=v("RovingFocusGroup");export const RovingFocusGroup=/*#__PURE__*/s.forwardRef(((e,o)=>/*#__PURE__*/s.createElement(l.Provider,{scope:e.__scopeRovingFocusGroup},/*#__PURE__*/s.createElement(l.Slot,{scope:e.__scopeRovingFocusGroup},/*#__PURE__*/s.createElement(b,f({},e,{ref:o}))))));/*#__PURE__*/const b=/*#__PURE__*/s.forwardRef(((n,i)=>{const{__scopeRovingFocusGroup:u,orientation:l,loop:d=!1,dir:v,currentTabStopId:g,defaultCurrentTabStopId:w,onCurrentTabStopIdChange:b,onEntryFocus:x,...E}=n,I=s.useRef(null),G=c(i,I),h=e(v),[T=null,A]=o({prop:g,defaultProp:w,onChange:b}),[y,D]=s.useState(!1),S=r(x),_=m(u),C=s.useRef(!1);return s.useEffect((()=>{const e=I.current;if(e)return e.addEventListener("rovingFocusGroup.onEntryFocus",S),()=>e.removeEventListener("rovingFocusGroup.onEntryFocus",S)}),[S]),/*#__PURE__*/s.createElement(F,{scope:u,orientation:l,dir:h,loop:d,currentTabStopId:T,onItemFocus:s.useCallback((e=>A(e)),[A]),onItemShiftTab:s.useCallback((()=>D(!0)),[])},/*#__PURE__*/s.createElement(t.div,f({tabIndex:y?-1:0,"data-orientation":l},E,{ref:G,style:{outline:"none",...n.style},onMouseDown:a(n.onMouseDown,(()=>{C.current=!0})),onFocus:a(n.onFocus,(e=>{const o=!C.current;if(e.target===e.currentTarget&&o&&!y){const o=new Event("rovingFocusGroup.onEntryFocus",p);if(e.currentTarget.dispatchEvent(o),!o.defaultPrevented){const e=_().filter((e=>e.focusable));R([e.find((e=>e.active)),e.find((e=>e.id===T)),...e].filter(Boolean).map((e=>e.ref.current)))}}C.current=!1})),onBlur:a(n.onBlur,(()=>D(!1)))})))}));export const RovingFocusGroupItem=/*#__PURE__*/s.forwardRef(((e,o)=>{const{__scopeRovingFocusGroup:r,focusable:i=!0,active:c=!1,...u}=e,p=n(),d=w("RovingFocusGroupItem",r),v=d.currentTabStopId===p,g=m(r);/*#__PURE__*/return s.createElement(l.ItemSlot,{scope:r,id:p,focusable:i,active:c},/*#__PURE__*/s.createElement(t.span,f({tabIndex:v?0:-1,"data-orientation":d.orientation},u,{ref:o,onMouseDown:a(e.onMouseDown,(e=>{i?d.onItemFocus(p):e.preventDefault()})),onFocus:a(e.onFocus,(()=>d.onItemFocus(p))),onKeyDown:a(e.onKeyDown,(e=>{if("Tab"===e.key&&e.shiftKey)return void d.onItemShiftTab();if(e.target!==e.currentTarget)return;const o=function(e,o,r){const t=function(e,o){return"rtl"!==o?e:"ArrowLeft"===e?"ArrowRight":"ArrowRight"===e?"ArrowLeft":e}(e.key,r);return"vertical"===o&&["ArrowLeft","ArrowRight"].includes(t)||"horizontal"===o&&["ArrowUp","ArrowDown"].includes(t)?void 0:x[t]}(e,d.orientation,d.dir);if(void 0!==o){e.preventDefault();let n=g().filter((e=>e.focusable)).map((e=>e.ref.current));if("last"===o)n.reverse();else if("prev"===o||"next"===o){"prev"===o&&n.reverse();const i=n.indexOf(e.currentTarget);n=d.loop?(t=i+1,(r=n).map(((e,o)=>r[(t+o)%r.length]))):n.slice(i+1)}setTimeout((()=>R(n)))}var r,t}))})))}));/*#__PURE__*/const x={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function R(e){const o=document.activeElement;for(const r of e){if(r===o)return;if(r.focus(),document.activeElement!==o)return}}export const Root=RovingFocusGroup;export const Item=RovingFocusGroupItem;
1
+ import $98Iye$babelruntimehelpersesmextends from "@babel/runtime/helpers/esm/extends";
2
+ import {forwardRef as $98Iye$forwardRef, createElement as $98Iye$createElement, useRef as $98Iye$useRef, useState as $98Iye$useState, useEffect as $98Iye$useEffect, useCallback as $98Iye$useCallback} from "react";
3
+ import {composeEventHandlers as $98Iye$composeEventHandlers} from "@radix-ui/primitive";
4
+ import {createCollection as $98Iye$createCollection} from "@radix-ui/react-collection";
5
+ import {useComposedRefs as $98Iye$useComposedRefs} from "@radix-ui/react-compose-refs";
6
+ import {createContextScope as $98Iye$createContextScope} from "@radix-ui/react-context";
7
+ import {useId as $98Iye$useId} from "@radix-ui/react-id";
8
+ import {Primitive as $98Iye$Primitive} from "@radix-ui/react-primitive";
9
+ import {useCallbackRef as $98Iye$useCallbackRef} from "@radix-ui/react-use-callback-ref";
10
+ import {useControllableState as $98Iye$useControllableState} from "@radix-ui/react-use-controllable-state";
11
+ import {useDirection as $98Iye$useDirection} from "@radix-ui/react-direction";
12
+
13
+ function $parcel$export(e, n, v, s) {
14
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
15
+ }
16
+ var $d7bdfb9eb0fdf311$exports = {};
17
+
18
+ $parcel$export($d7bdfb9eb0fdf311$exports, "createRovingFocusGroupScope", () => $d7bdfb9eb0fdf311$export$c7109489551a4f4);
19
+ $parcel$export($d7bdfb9eb0fdf311$exports, "RovingFocusGroup", () => $d7bdfb9eb0fdf311$export$8699f7c8af148338);
20
+ $parcel$export($d7bdfb9eb0fdf311$exports, "RovingFocusGroupItem", () => $d7bdfb9eb0fdf311$export$ab9df7c53fe8454);
21
+ $parcel$export($d7bdfb9eb0fdf311$exports, "Root", () => $d7bdfb9eb0fdf311$export$be92b6f5f03c0fe9);
22
+ $parcel$export($d7bdfb9eb0fdf311$exports, "Item", () => $d7bdfb9eb0fdf311$export$6d08773d2e66f8f2);
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+ const $d7bdfb9eb0fdf311$var$ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';
35
+ const $d7bdfb9eb0fdf311$var$EVENT_OPTIONS = {
36
+ bubbles: false,
37
+ cancelable: true
38
+ };
39
+ /* -------------------------------------------------------------------------------------------------
40
+ * RovingFocusGroup
41
+ * -----------------------------------------------------------------------------------------------*/ const $d7bdfb9eb0fdf311$var$GROUP_NAME = 'RovingFocusGroup';
42
+ const [$d7bdfb9eb0fdf311$var$Collection, $d7bdfb9eb0fdf311$var$useCollection, $d7bdfb9eb0fdf311$var$createCollectionScope] = $98Iye$createCollection($d7bdfb9eb0fdf311$var$GROUP_NAME);
43
+ const [$d7bdfb9eb0fdf311$var$createRovingFocusGroupContext, $d7bdfb9eb0fdf311$export$c7109489551a4f4] = $98Iye$createContextScope($d7bdfb9eb0fdf311$var$GROUP_NAME, [
44
+ $d7bdfb9eb0fdf311$var$createCollectionScope
45
+ ]);
46
+ const [$d7bdfb9eb0fdf311$var$RovingFocusProvider, $d7bdfb9eb0fdf311$var$useRovingFocusContext] = $d7bdfb9eb0fdf311$var$createRovingFocusGroupContext($d7bdfb9eb0fdf311$var$GROUP_NAME);
47
+ const $d7bdfb9eb0fdf311$export$8699f7c8af148338 = /*#__PURE__*/ $98Iye$forwardRef((props, forwardedRef)=>{
48
+ return /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$Collection.Provider, {
49
+ scope: props.__scopeRovingFocusGroup
50
+ }, /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$Collection.Slot, {
51
+ scope: props.__scopeRovingFocusGroup
52
+ }, /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$RovingFocusGroupImpl, $98Iye$babelruntimehelpersesmextends({}, props, {
53
+ ref: forwardedRef
54
+ }))));
55
+ });
56
+ /*#__PURE__*/ Object.assign($d7bdfb9eb0fdf311$export$8699f7c8af148338, {
57
+ displayName: $d7bdfb9eb0fdf311$var$GROUP_NAME
58
+ });
59
+ /* -----------------------------------------------------------------------------------------------*/ const $d7bdfb9eb0fdf311$var$RovingFocusGroupImpl = /*#__PURE__*/ $98Iye$forwardRef((props, forwardedRef)=>{
60
+ const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , orientation: orientation , loop: loop = false , dir: dir , currentTabStopId: currentTabStopIdProp , defaultCurrentTabStopId: defaultCurrentTabStopId , onCurrentTabStopIdChange: onCurrentTabStopIdChange , onEntryFocus: onEntryFocus , ...groupProps } = props;
61
+ const ref = $98Iye$useRef(null);
62
+ const composedRefs = $98Iye$useComposedRefs(forwardedRef, ref);
63
+ const direction = $98Iye$useDirection(dir);
64
+ const [currentTabStopId = null, setCurrentTabStopId] = $98Iye$useControllableState({
65
+ prop: currentTabStopIdProp,
66
+ defaultProp: defaultCurrentTabStopId,
67
+ onChange: onCurrentTabStopIdChange
68
+ });
69
+ const [isTabbingBackOut, setIsTabbingBackOut] = $98Iye$useState(false);
70
+ const handleEntryFocus = $98Iye$useCallbackRef(onEntryFocus);
71
+ const getItems = $d7bdfb9eb0fdf311$var$useCollection(__scopeRovingFocusGroup);
72
+ const isClickFocusRef = $98Iye$useRef(false);
73
+ $98Iye$useEffect(()=>{
74
+ const node = ref.current;
75
+ if (node) {
76
+ node.addEventListener($d7bdfb9eb0fdf311$var$ENTRY_FOCUS, handleEntryFocus);
77
+ return ()=>node.removeEventListener($d7bdfb9eb0fdf311$var$ENTRY_FOCUS, handleEntryFocus)
78
+ ;
79
+ }
80
+ }, [
81
+ handleEntryFocus
82
+ ]);
83
+ return /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$RovingFocusProvider, {
84
+ scope: __scopeRovingFocusGroup,
85
+ orientation: orientation,
86
+ dir: direction,
87
+ loop: loop,
88
+ currentTabStopId: currentTabStopId,
89
+ onItemFocus: $98Iye$useCallback((tabStopId)=>setCurrentTabStopId(tabStopId)
90
+ , [
91
+ setCurrentTabStopId
92
+ ]),
93
+ onItemShiftTab: $98Iye$useCallback(()=>setIsTabbingBackOut(true)
94
+ , [])
95
+ }, /*#__PURE__*/ $98Iye$createElement($98Iye$Primitive.div, $98Iye$babelruntimehelpersesmextends({
96
+ tabIndex: isTabbingBackOut ? -1 : 0,
97
+ "data-orientation": orientation
98
+ }, groupProps, {
99
+ ref: composedRefs,
100
+ style: {
101
+ outline: 'none',
102
+ ...props.style
103
+ },
104
+ onMouseDown: $98Iye$composeEventHandlers(props.onMouseDown, ()=>{
105
+ isClickFocusRef.current = true;
106
+ }),
107
+ onFocus: $98Iye$composeEventHandlers(props.onFocus, (event)=>{
108
+ // We normally wouldn't need this check, because we already check
109
+ // that the focus is on the current target and not bubbling to it.
110
+ // We do this because Safari doesn't focus buttons when clicked, and
111
+ // instead, the wrapper will get focused and not through a bubbling event.
112
+ const isKeyboardFocus = !isClickFocusRef.current;
113
+ if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
114
+ const entryFocusEvent = new Event($d7bdfb9eb0fdf311$var$ENTRY_FOCUS, $d7bdfb9eb0fdf311$var$EVENT_OPTIONS);
115
+ event.currentTarget.dispatchEvent(entryFocusEvent);
116
+ if (!entryFocusEvent.defaultPrevented) {
117
+ const items = getItems().filter((item)=>item.focusable
118
+ );
119
+ const activeItem = items.find((item)=>item.active
120
+ );
121
+ const currentItem = items.find((item)=>item.id === currentTabStopId
122
+ );
123
+ const candidateItems = [
124
+ activeItem,
125
+ currentItem,
126
+ ...items
127
+ ].filter(Boolean);
128
+ const candidateNodes = candidateItems.map((item)=>item.ref.current
129
+ );
130
+ $d7bdfb9eb0fdf311$var$focusFirst(candidateNodes);
131
+ }
132
+ }
133
+ isClickFocusRef.current = false;
134
+ }),
135
+ onBlur: $98Iye$composeEventHandlers(props.onBlur, ()=>setIsTabbingBackOut(false)
136
+ )
137
+ })));
138
+ });
139
+ /* -------------------------------------------------------------------------------------------------
140
+ * RovingFocusGroupItem
141
+ * -----------------------------------------------------------------------------------------------*/ const $d7bdfb9eb0fdf311$var$ITEM_NAME = 'RovingFocusGroupItem';
142
+ const $d7bdfb9eb0fdf311$export$ab9df7c53fe8454 = /*#__PURE__*/ $98Iye$forwardRef((props, forwardedRef)=>{
143
+ const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , focusable: focusable = true , active: active = false , ...itemProps } = props;
144
+ const id = $98Iye$useId();
145
+ const context = $d7bdfb9eb0fdf311$var$useRovingFocusContext($d7bdfb9eb0fdf311$var$ITEM_NAME, __scopeRovingFocusGroup);
146
+ const isCurrentTabStop = context.currentTabStopId === id;
147
+ const getItems = $d7bdfb9eb0fdf311$var$useCollection(__scopeRovingFocusGroup);
148
+ return /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$Collection.ItemSlot, {
149
+ scope: __scopeRovingFocusGroup,
150
+ id: id,
151
+ focusable: focusable,
152
+ active: active
153
+ }, /*#__PURE__*/ $98Iye$createElement($98Iye$Primitive.span, $98Iye$babelruntimehelpersesmextends({
154
+ tabIndex: isCurrentTabStop ? 0 : -1,
155
+ "data-orientation": context.orientation
156
+ }, itemProps, {
157
+ ref: forwardedRef,
158
+ onMouseDown: $98Iye$composeEventHandlers(props.onMouseDown, (event)=>{
159
+ // We prevent focusing non-focusable items on `mousedown`.
160
+ // Even though the item has tabIndex={-1}, that only means take it out of the tab order.
161
+ if (!focusable) event.preventDefault(); // Safari doesn't focus a button when clicked so we run our logic on mousedown also
162
+ else context.onItemFocus(id);
163
+ }),
164
+ onFocus: $98Iye$composeEventHandlers(props.onFocus, ()=>context.onItemFocus(id)
165
+ ),
166
+ onKeyDown: $98Iye$composeEventHandlers(props.onKeyDown, (event)=>{
167
+ if (event.key === 'Tab' && event.shiftKey) {
168
+ context.onItemShiftTab();
169
+ return;
170
+ }
171
+ if (event.target !== event.currentTarget) return;
172
+ const focusIntent = $d7bdfb9eb0fdf311$var$getFocusIntent(event, context.orientation, context.dir);
173
+ if (focusIntent !== undefined) {
174
+ event.preventDefault();
175
+ const items = getItems().filter((item)=>item.focusable
176
+ );
177
+ let candidateNodes = items.map((item)=>item.ref.current
178
+ );
179
+ if (focusIntent === 'last') candidateNodes.reverse();
180
+ else if (focusIntent === 'prev' || focusIntent === 'next') {
181
+ if (focusIntent === 'prev') candidateNodes.reverse();
182
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
183
+ candidateNodes = context.loop ? $d7bdfb9eb0fdf311$var$wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
184
+ }
185
+ /**
186
+ * Imperative focus during keydown is risky so we prevent React's batching updates
187
+ * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332
188
+ */ setTimeout(()=>$d7bdfb9eb0fdf311$var$focusFirst(candidateNodes)
189
+ );
190
+ }
191
+ })
192
+ })));
193
+ });
194
+ /*#__PURE__*/ Object.assign($d7bdfb9eb0fdf311$export$ab9df7c53fe8454, {
195
+ displayName: $d7bdfb9eb0fdf311$var$ITEM_NAME
196
+ });
197
+ /* -----------------------------------------------------------------------------------------------*/ // prettier-ignore
198
+ const $d7bdfb9eb0fdf311$var$MAP_KEY_TO_FOCUS_INTENT = {
199
+ ArrowLeft: 'prev',
200
+ ArrowUp: 'prev',
201
+ ArrowRight: 'next',
202
+ ArrowDown: 'next',
203
+ PageUp: 'first',
204
+ Home: 'first',
205
+ PageDown: 'last',
206
+ End: 'last'
207
+ };
208
+ function $d7bdfb9eb0fdf311$var$getDirectionAwareKey(key, dir) {
209
+ if (dir !== 'rtl') return key;
210
+ return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;
211
+ }
212
+ function $d7bdfb9eb0fdf311$var$getFocusIntent(event, orientation, dir) {
213
+ const key = $d7bdfb9eb0fdf311$var$getDirectionAwareKey(event.key, dir);
214
+ if (orientation === 'vertical' && [
215
+ 'ArrowLeft',
216
+ 'ArrowRight'
217
+ ].includes(key)) return undefined;
218
+ if (orientation === 'horizontal' && [
219
+ 'ArrowUp',
220
+ 'ArrowDown'
221
+ ].includes(key)) return undefined;
222
+ return $d7bdfb9eb0fdf311$var$MAP_KEY_TO_FOCUS_INTENT[key];
223
+ }
224
+ function $d7bdfb9eb0fdf311$var$focusFirst(candidates) {
225
+ const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
226
+ for (const candidate of candidates){
227
+ // if focus is already where we want to go, we don't want to keep going through the candidates
228
+ if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
229
+ candidate.focus();
230
+ if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
231
+ }
232
+ }
233
+ /**
234
+ * Wraps an array around itself at a given start index
235
+ * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
236
+ */ function $d7bdfb9eb0fdf311$var$wrapArray(array, startIndex) {
237
+ return array.map((_, index)=>array[(startIndex + index) % array.length]
238
+ );
239
+ }
240
+ const $d7bdfb9eb0fdf311$export$be92b6f5f03c0fe9 = $d7bdfb9eb0fdf311$export$8699f7c8af148338;
241
+ const $d7bdfb9eb0fdf311$export$6d08773d2e66f8f2 = $d7bdfb9eb0fdf311$export$ab9df7c53fe8454;
242
+
243
+
244
+
245
+
246
+ export {$d7bdfb9eb0fdf311$export$c7109489551a4f4 as createRovingFocusGroupScope, $d7bdfb9eb0fdf311$export$8699f7c8af148338 as RovingFocusGroup, $d7bdfb9eb0fdf311$export$ab9df7c53fe8454 as RovingFocusGroupItem, $d7bdfb9eb0fdf311$export$be92b6f5f03c0fe9 as Root, $d7bdfb9eb0fdf311$export$6d08773d2e66f8f2 as Item};
2
247
  //# sourceMappingURL=index.module.js.map
@@ -1 +1 @@
1
- {"mappings":"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","sources":["./packages/react/roving-focus/src/RovingFocusGroup.tsx"],"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};\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}\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 ...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\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 >\n <Primitive.div\n tabIndex={isTabbingBackOut ? -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 Event(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);\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 focusable?: boolean;\n active?: boolean;\n}\n\nconst RovingFocusGroupItem = React.forwardRef<RovingFocusItemElement, RovingFocusItemProps>(\n (props: ScopedProps<RovingFocusItemProps>, forwardedRef) => {\n const { __scopeRovingFocusGroup, focusable = true, active = false, ...itemProps } = props;\n const id = useId();\n const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);\n const isCurrentTabStop = context.currentTabStopId === id;\n const getItems = useCollection(__scopeRovingFocusGroup);\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 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[]) {\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();\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"],"names":["EVENT_OPTIONS","bubbles","cancelable","Collection","useCollection","createCollectionScope","createCollection","createRovingFocusGroupContext","createRovingFocusGroupScope","createContextScope","RovingFocusProvider","useRovingFocusContext","RovingFocusGroup","React","forwardRef","props","forwardedRef","_react","createElement","$aa7392b6d04813384a511e60e09$var$Collection","Provider","scope","__scopeRovingFocusGroup","Slot","$aa7392b6d04813384a511e60e09$var$RovingFocusGroupImpl","_babelRuntimeHelpersEsmExtends","ref","RovingFocusGroupImpl","orientation","loop","dir","currentTabStopId","currentTabStopIdProp","defaultCurrentTabStopId","onCurrentTabStopIdChange","onEntryFocus","groupProps","useRef","composedRefs","useComposedRefs","direction","useDirection","setCurrentTabStopId","useControllableState","prop","defaultProp","onChange","isTabbingBackOut","setIsTabbingBackOut","useState","handleEntryFocus","useCallbackRef","getItems","isClickFocusRef","useEffect","node","current","addEventListener","removeEventListener","$aa7392b6d04813384a511e60e09$var$RovingFocusProvider","onItemFocus","useCallback","tabStopId","onItemShiftTab","Primitive","div","tabIndex","style","outline","onMouseDown","composeEventHandlers","onFocus","event","isKeyboardFocus","target","currentTarget","entryFocusEvent","Event","dispatchEvent","defaultPrevented","items","filter","item","focusable","focusFirst","find","active","id","Boolean","map","onBlur","RovingFocusGroupItem","itemProps","useId","context","isCurrentTabStop","ItemSlot","span","preventDefault","onKeyDown","key","shiftKey","focusIntent","getDirectionAwareKey","includes","MAP_KEY_TO_FOCUS_INTENT","getFocusIntent","undefined","candidateNodes","reverse","currentIndex","indexOf","startIndex","array","_","index","length","slice","setTimeout","ArrowLeft","ArrowUp","ArrowRight","ArrowDown","PageUp","Home","PageDown","End","candidates","PREVIOUSLY_FOCUSED_ELEMENT","document","activeElement","candidate","focus","Root","Item"],"version":3,"file":"index.module.js.map"}
1
+ {"mappings":"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","sources":["packages/react/roving-focus/src/index.ts","packages/react/roving-focus/src/RovingFocusGroup.tsx"],"sourcesContent":["export * 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 * 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};\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}\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 ...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\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 >\n <Primitive.div\n tabIndex={isTabbingBackOut ? -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 Event(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);\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 focusable?: boolean;\n active?: boolean;\n}\n\nconst RovingFocusGroupItem = React.forwardRef<RovingFocusItemElement, RovingFocusItemProps>(\n (props: ScopedProps<RovingFocusItemProps>, forwardedRef) => {\n const { __scopeRovingFocusGroup, focusable = true, active = false, ...itemProps } = props;\n const id = useId();\n const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);\n const isCurrentTabStop = context.currentTabStopId === id;\n const getItems = useCollection(__scopeRovingFocusGroup);\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 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[]) {\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();\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"],"names":["React","composeEventHandlers","createCollection","useComposedRefs","createContextScope","useId","Primitive","useCallbackRef","useControllableState","useDirection","ENTRY_FOCUS","EVENT_OPTIONS","bubbles","cancelable","GROUP_NAME","Collection","useCollection","createCollectionScope","createRovingFocusGroupContext","createRovingFocusGroupScope","RovingFocusProvider","useRovingFocusContext","RovingFocusGroup","forwardRef","props","forwardedRef","__scopeRovingFocusGroup","RovingFocusGroupImpl","orientation","loop","dir","currentTabStopId","currentTabStopIdProp","defaultCurrentTabStopId","onCurrentTabStopIdChange","onEntryFocus","groupProps","ref","useRef","composedRefs","direction","setCurrentTabStopId","prop","defaultProp","onChange","isTabbingBackOut","setIsTabbingBackOut","useState","handleEntryFocus","getItems","isClickFocusRef","useEffect","node","current","addEventListener","removeEventListener","useCallback","tabStopId","outline","style","onMouseDown","onFocus","event","isKeyboardFocus","target","currentTarget","entryFocusEvent","Event","dispatchEvent","defaultPrevented","items","filter","item","focusable","activeItem","find","active","currentItem","id","candidateItems","Boolean","candidateNodes","map","focusFirst","onBlur","ITEM_NAME","RovingFocusGroupItem","itemProps","context","isCurrentTabStop","preventDefault","onItemFocus","onKeyDown","key","shiftKey","onItemShiftTab","focusIntent","getFocusIntent","undefined","reverse","currentIndex","indexOf","wrapArray","slice","setTimeout","MAP_KEY_TO_FOCUS_INTENT","ArrowLeft","ArrowUp","ArrowRight","ArrowDown","PageUp","Home","PageDown","End","getDirectionAwareKey","includes","candidates","PREVIOUSLY_FOCUSED_ELEMENT","document","activeElement","candidate","focus","array","startIndex","_","index","length","Root","Item"],"version":3,"file":"index.module.js.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radix-ui/react-roving-focus",
3
- "version": "0.1.6-rc.4",
3
+ "version": "0.1.6-rc.7",
4
4
  "license": "MIT",
5
5
  "source": "src/index.ts",
6
6
  "main": "dist/index.js",
@@ -18,14 +18,14 @@
18
18
  "dependencies": {
19
19
  "@babel/runtime": "^7.13.10",
20
20
  "@radix-ui/primitive": "0.1.0",
21
- "@radix-ui/react-collection": "0.1.5-rc.1",
22
- "@radix-ui/react-compose-refs": "0.1.1-rc.1",
23
- "@radix-ui/react-context": "0.1.2-rc.1",
24
- "@radix-ui/react-direction": "0.1.0-rc.4",
25
- "@radix-ui/react-id": "0.1.6-rc.1",
26
- "@radix-ui/react-primitive": "0.1.5-rc.1",
27
- "@radix-ui/react-use-callback-ref": "0.1.1-rc.1",
28
- "@radix-ui/react-use-controllable-state": "0.1.1-rc.1"
21
+ "@radix-ui/react-collection": "0.1.5-rc.4",
22
+ "@radix-ui/react-compose-refs": "0.1.1-rc.4",
23
+ "@radix-ui/react-context": "0.1.2-rc.4",
24
+ "@radix-ui/react-direction": "0.1.0-rc.7",
25
+ "@radix-ui/react-id": "0.1.6-rc.4",
26
+ "@radix-ui/react-primitive": "0.1.5-rc.4",
27
+ "@radix-ui/react-use-callback-ref": "0.1.1-rc.4",
28
+ "@radix-ui/react-use-controllable-state": "0.1.1-rc.4"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "react": "^16.8 || ^17.0 || ^18.0"