@radix-ui/react-roving-focus 0.1.6-rc.5 → 0.1.6-rc.50

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 {\n createRovingFocusGroupScope,\n //\n RovingFocusGroup,\n RovingFocusGroupItem,\n //\n Root,\n Item,\n} from './RovingFocusGroup';\nexport type { RovingFocusGroupProps, RovingFocusItemProps } from './RovingFocusGroup';\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/dist/index.js CHANGED
@@ -1,2 +1,248 @@
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$export(e, n, v, s) {
14
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
15
+ }
16
+ function $parcel$interopDefault(a) {
17
+ return a && a.__esModule ? a.default : a;
18
+ }
19
+
20
+ $parcel$export(module.exports, "createRovingFocusGroupScope", () => $0063afae63b3fa70$export$c7109489551a4f4);
21
+ $parcel$export(module.exports, "RovingFocusGroup", () => $0063afae63b3fa70$export$8699f7c8af148338);
22
+ $parcel$export(module.exports, "RovingFocusGroupItem", () => $0063afae63b3fa70$export$ab9df7c53fe8454);
23
+ $parcel$export(module.exports, "Root", () => $0063afae63b3fa70$export$be92b6f5f03c0fe9);
24
+ $parcel$export(module.exports, "Item", () => $0063afae63b3fa70$export$6d08773d2e66f8f2);
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+ const $0063afae63b3fa70$var$ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';
37
+ const $0063afae63b3fa70$var$EVENT_OPTIONS = {
38
+ bubbles: false,
39
+ cancelable: true
40
+ };
41
+ /* -------------------------------------------------------------------------------------------------
42
+ * RovingFocusGroup
43
+ * -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$GROUP_NAME = 'RovingFocusGroup';
44
+ const [$0063afae63b3fa70$var$Collection, $0063afae63b3fa70$var$useCollection, $0063afae63b3fa70$var$createCollectionScope] = $9QJ9Y$radixuireactcollection.createCollection($0063afae63b3fa70$var$GROUP_NAME);
45
+ const [$0063afae63b3fa70$var$createRovingFocusGroupContext, $0063afae63b3fa70$export$c7109489551a4f4] = $9QJ9Y$radixuireactcontext.createContextScope($0063afae63b3fa70$var$GROUP_NAME, [
46
+ $0063afae63b3fa70$var$createCollectionScope
47
+ ]);
48
+ const [$0063afae63b3fa70$var$RovingFocusProvider, $0063afae63b3fa70$var$useRovingFocusContext] = $0063afae63b3fa70$var$createRovingFocusGroupContext($0063afae63b3fa70$var$GROUP_NAME);
49
+ const $0063afae63b3fa70$export$8699f7c8af148338 = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{
50
+ return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.Provider, {
51
+ scope: props.__scopeRovingFocusGroup
52
+ }, /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.Slot, {
53
+ scope: props.__scopeRovingFocusGroup
54
+ }, /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$RovingFocusGroupImpl, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({}, props, {
55
+ ref: forwardedRef
56
+ }))));
57
+ });
58
+ /*#__PURE__*/ Object.assign($0063afae63b3fa70$export$8699f7c8af148338, {
59
+ displayName: $0063afae63b3fa70$var$GROUP_NAME
60
+ });
61
+ /* -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$RovingFocusGroupImpl = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{
62
+ const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , orientation: orientation , loop: loop = false , dir: dir , currentTabStopId: currentTabStopIdProp , defaultCurrentTabStopId: defaultCurrentTabStopId , onCurrentTabStopIdChange: onCurrentTabStopIdChange , onEntryFocus: onEntryFocus , ...groupProps } = props;
63
+ const ref = $9QJ9Y$react.useRef(null);
64
+ const composedRefs = $9QJ9Y$radixuireactcomposerefs.useComposedRefs(forwardedRef, ref);
65
+ const direction = $9QJ9Y$radixuireactdirection.useDirection(dir);
66
+ const [currentTabStopId = null, setCurrentTabStopId] = $9QJ9Y$radixuireactusecontrollablestate.useControllableState({
67
+ prop: currentTabStopIdProp,
68
+ defaultProp: defaultCurrentTabStopId,
69
+ onChange: onCurrentTabStopIdChange
70
+ });
71
+ const [isTabbingBackOut, setIsTabbingBackOut] = $9QJ9Y$react.useState(false);
72
+ const handleEntryFocus = $9QJ9Y$radixuireactusecallbackref.useCallbackRef(onEntryFocus);
73
+ const getItems = $0063afae63b3fa70$var$useCollection(__scopeRovingFocusGroup);
74
+ const isClickFocusRef = $9QJ9Y$react.useRef(false);
75
+ $9QJ9Y$react.useEffect(()=>{
76
+ const node = ref.current;
77
+ if (node) {
78
+ node.addEventListener($0063afae63b3fa70$var$ENTRY_FOCUS, handleEntryFocus);
79
+ return ()=>node.removeEventListener($0063afae63b3fa70$var$ENTRY_FOCUS, handleEntryFocus)
80
+ ;
81
+ }
82
+ }, [
83
+ handleEntryFocus
84
+ ]);
85
+ return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$RovingFocusProvider, {
86
+ scope: __scopeRovingFocusGroup,
87
+ orientation: orientation,
88
+ dir: direction,
89
+ loop: loop,
90
+ currentTabStopId: currentTabStopId,
91
+ onItemFocus: $9QJ9Y$react.useCallback((tabStopId)=>setCurrentTabStopId(tabStopId)
92
+ , [
93
+ setCurrentTabStopId
94
+ ]),
95
+ onItemShiftTab: $9QJ9Y$react.useCallback(()=>setIsTabbingBackOut(true)
96
+ , [])
97
+ }, /*#__PURE__*/ $9QJ9Y$react.createElement($9QJ9Y$radixuireactprimitive.Primitive.div, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({
98
+ tabIndex: isTabbingBackOut ? -1 : 0,
99
+ "data-orientation": orientation
100
+ }, groupProps, {
101
+ ref: composedRefs,
102
+ style: {
103
+ outline: 'none',
104
+ ...props.style
105
+ },
106
+ onMouseDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onMouseDown, ()=>{
107
+ isClickFocusRef.current = true;
108
+ }),
109
+ onFocus: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onFocus, (event)=>{
110
+ // We normally wouldn't need this check, because we already check
111
+ // that the focus is on the current target and not bubbling to it.
112
+ // We do this because Safari doesn't focus buttons when clicked, and
113
+ // instead, the wrapper will get focused and not through a bubbling event.
114
+ const isKeyboardFocus = !isClickFocusRef.current;
115
+ if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
116
+ const entryFocusEvent = new CustomEvent($0063afae63b3fa70$var$ENTRY_FOCUS, $0063afae63b3fa70$var$EVENT_OPTIONS);
117
+ event.currentTarget.dispatchEvent(entryFocusEvent);
118
+ if (!entryFocusEvent.defaultPrevented) {
119
+ const items = getItems().filter((item)=>item.focusable
120
+ );
121
+ const activeItem = items.find((item)=>item.active
122
+ );
123
+ const currentItem = items.find((item)=>item.id === currentTabStopId
124
+ );
125
+ const candidateItems = [
126
+ activeItem,
127
+ currentItem,
128
+ ...items
129
+ ].filter(Boolean);
130
+ const candidateNodes = candidateItems.map((item)=>item.ref.current
131
+ );
132
+ $0063afae63b3fa70$var$focusFirst(candidateNodes);
133
+ }
134
+ }
135
+ isClickFocusRef.current = false;
136
+ }),
137
+ onBlur: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onBlur, ()=>setIsTabbingBackOut(false)
138
+ )
139
+ })));
140
+ });
141
+ /* -------------------------------------------------------------------------------------------------
142
+ * RovingFocusGroupItem
143
+ * -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$ITEM_NAME = 'RovingFocusGroupItem';
144
+ const $0063afae63b3fa70$export$ab9df7c53fe8454 = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{
145
+ const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , focusable: focusable = true , active: active = false , ...itemProps } = props;
146
+ const id = $9QJ9Y$radixuireactid.useId();
147
+ const context = $0063afae63b3fa70$var$useRovingFocusContext($0063afae63b3fa70$var$ITEM_NAME, __scopeRovingFocusGroup);
148
+ const isCurrentTabStop = context.currentTabStopId === id;
149
+ const getItems = $0063afae63b3fa70$var$useCollection(__scopeRovingFocusGroup);
150
+ return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.ItemSlot, {
151
+ scope: __scopeRovingFocusGroup,
152
+ id: id,
153
+ focusable: focusable,
154
+ active: active
155
+ }, /*#__PURE__*/ $9QJ9Y$react.createElement($9QJ9Y$radixuireactprimitive.Primitive.span, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({
156
+ tabIndex: isCurrentTabStop ? 0 : -1,
157
+ "data-orientation": context.orientation
158
+ }, itemProps, {
159
+ ref: forwardedRef,
160
+ onMouseDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onMouseDown, (event)=>{
161
+ // We prevent focusing non-focusable items on `mousedown`.
162
+ // Even though the item has tabIndex={-1}, that only means take it out of the tab order.
163
+ if (!focusable) event.preventDefault(); // Safari doesn't focus a button when clicked so we run our logic on mousedown also
164
+ else context.onItemFocus(id);
165
+ }),
166
+ onFocus: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onFocus, ()=>context.onItemFocus(id)
167
+ ),
168
+ onKeyDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onKeyDown, (event)=>{
169
+ if (event.key === 'Tab' && event.shiftKey) {
170
+ context.onItemShiftTab();
171
+ return;
172
+ }
173
+ if (event.target !== event.currentTarget) return;
174
+ const focusIntent = $0063afae63b3fa70$var$getFocusIntent(event, context.orientation, context.dir);
175
+ if (focusIntent !== undefined) {
176
+ event.preventDefault();
177
+ const items = getItems().filter((item)=>item.focusable
178
+ );
179
+ let candidateNodes = items.map((item)=>item.ref.current
180
+ );
181
+ if (focusIntent === 'last') candidateNodes.reverse();
182
+ else if (focusIntent === 'prev' || focusIntent === 'next') {
183
+ if (focusIntent === 'prev') candidateNodes.reverse();
184
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
185
+ candidateNodes = context.loop ? $0063afae63b3fa70$var$wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
186
+ }
187
+ /**
188
+ * Imperative focus during keydown is risky so we prevent React's batching updates
189
+ * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332
190
+ */ setTimeout(()=>$0063afae63b3fa70$var$focusFirst(candidateNodes)
191
+ );
192
+ }
193
+ })
194
+ })));
195
+ });
196
+ /*#__PURE__*/ Object.assign($0063afae63b3fa70$export$ab9df7c53fe8454, {
197
+ displayName: $0063afae63b3fa70$var$ITEM_NAME
198
+ });
199
+ /* -----------------------------------------------------------------------------------------------*/ // prettier-ignore
200
+ const $0063afae63b3fa70$var$MAP_KEY_TO_FOCUS_INTENT = {
201
+ ArrowLeft: 'prev',
202
+ ArrowUp: 'prev',
203
+ ArrowRight: 'next',
204
+ ArrowDown: 'next',
205
+ PageUp: 'first',
206
+ Home: 'first',
207
+ PageDown: 'last',
208
+ End: 'last'
209
+ };
210
+ function $0063afae63b3fa70$var$getDirectionAwareKey(key, dir) {
211
+ if (dir !== 'rtl') return key;
212
+ return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;
213
+ }
214
+ function $0063afae63b3fa70$var$getFocusIntent(event, orientation, dir) {
215
+ const key = $0063afae63b3fa70$var$getDirectionAwareKey(event.key, dir);
216
+ if (orientation === 'vertical' && [
217
+ 'ArrowLeft',
218
+ 'ArrowRight'
219
+ ].includes(key)) return undefined;
220
+ if (orientation === 'horizontal' && [
221
+ 'ArrowUp',
222
+ 'ArrowDown'
223
+ ].includes(key)) return undefined;
224
+ return $0063afae63b3fa70$var$MAP_KEY_TO_FOCUS_INTENT[key];
225
+ }
226
+ function $0063afae63b3fa70$var$focusFirst(candidates) {
227
+ const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
228
+ for (const candidate of candidates){
229
+ // if focus is already where we want to go, we don't want to keep going through the candidates
230
+ if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
231
+ candidate.focus();
232
+ if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
233
+ }
234
+ }
235
+ /**
236
+ * Wraps an array around itself at a given start index
237
+ * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
238
+ */ function $0063afae63b3fa70$var$wrapArray(array, startIndex) {
239
+ return array.map((_, index)=>array[(startIndex + index) % array.length]
240
+ );
241
+ }
242
+ const $0063afae63b3fa70$export$be92b6f5f03c0fe9 = $0063afae63b3fa70$export$8699f7c8af148338;
243
+ const $0063afae63b3fa70$export$6d08773d2e66f8f2 = $0063afae63b3fa70$export$ab9df7c53fe8454;
244
+
245
+
246
+
247
+
2
248
  //# 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 {\n createRovingFocusGroupScope,\n //\n RovingFocusGroup,\n RovingFocusGroupItem,\n //\n Root,\n Item,\n} from './RovingFocusGroup';\nexport type { RovingFocusGroupProps, RovingFocusItemProps } from './RovingFocusGroup';\n","import * as React from 'react';\nimport { composeEventHandlers } from '@radix-ui/primitive';\nimport { createCollection } from '@radix-ui/react-collection';\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useId } from '@radix-ui/react-id';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { useCallbackRef } from '@radix-ui/react-use-callback-ref';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport { useDirection } from '@radix-ui/react-direction';\n\nimport type * 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 CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);\n event.currentTarget.dispatchEvent(entryFocusEvent);\n\n if (!entryFocusEvent.defaultPrevented) {\n const items = getItems().filter((item) => item.focusable);\n const activeItem = items.find((item) => item.active);\n const currentItem = items.find((item) => item.id === currentTabStopId);\n const candidateItems = [activeItem, currentItem, ...items].filter(\n Boolean\n ) as typeof items;\n const candidateNodes = candidateItems.map((item) => item.ref.current!);\n focusFirst(candidateNodes);\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":["createRovingFocusGroupScope","RovingFocusGroup","RovingFocusGroupItem","Root","Item","React","composeEventHandlers","createCollection","useComposedRefs","createContextScope","useId","Primitive","useCallbackRef","useControllableState","useDirection","ENTRY_FOCUS","EVENT_OPTIONS","bubbles","cancelable","GROUP_NAME","Collection","useCollection","createCollectionScope","createRovingFocusGroupContext","RovingFocusProvider","useRovingFocusContext","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","CustomEvent","dispatchEvent","defaultPrevented","items","filter","item","focusable","activeItem","find","active","currentItem","id","candidateItems","Boolean","candidateNodes","map","focusFirst","onBlur","ITEM_NAME","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"],"version":3,"file":"index.js.map"}
@@ -1,2 +1,237 @@
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
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+ const $d7bdfb9eb0fdf311$var$ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';
25
+ const $d7bdfb9eb0fdf311$var$EVENT_OPTIONS = {
26
+ bubbles: false,
27
+ cancelable: true
28
+ };
29
+ /* -------------------------------------------------------------------------------------------------
30
+ * RovingFocusGroup
31
+ * -----------------------------------------------------------------------------------------------*/ const $d7bdfb9eb0fdf311$var$GROUP_NAME = 'RovingFocusGroup';
32
+ const [$d7bdfb9eb0fdf311$var$Collection, $d7bdfb9eb0fdf311$var$useCollection, $d7bdfb9eb0fdf311$var$createCollectionScope] = $98Iye$createCollection($d7bdfb9eb0fdf311$var$GROUP_NAME);
33
+ const [$d7bdfb9eb0fdf311$var$createRovingFocusGroupContext, $d7bdfb9eb0fdf311$export$c7109489551a4f4] = $98Iye$createContextScope($d7bdfb9eb0fdf311$var$GROUP_NAME, [
34
+ $d7bdfb9eb0fdf311$var$createCollectionScope
35
+ ]);
36
+ const [$d7bdfb9eb0fdf311$var$RovingFocusProvider, $d7bdfb9eb0fdf311$var$useRovingFocusContext] = $d7bdfb9eb0fdf311$var$createRovingFocusGroupContext($d7bdfb9eb0fdf311$var$GROUP_NAME);
37
+ const $d7bdfb9eb0fdf311$export$8699f7c8af148338 = /*#__PURE__*/ $98Iye$forwardRef((props, forwardedRef)=>{
38
+ return /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$Collection.Provider, {
39
+ scope: props.__scopeRovingFocusGroup
40
+ }, /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$Collection.Slot, {
41
+ scope: props.__scopeRovingFocusGroup
42
+ }, /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$RovingFocusGroupImpl, $98Iye$babelruntimehelpersesmextends({}, props, {
43
+ ref: forwardedRef
44
+ }))));
45
+ });
46
+ /*#__PURE__*/ Object.assign($d7bdfb9eb0fdf311$export$8699f7c8af148338, {
47
+ displayName: $d7bdfb9eb0fdf311$var$GROUP_NAME
48
+ });
49
+ /* -----------------------------------------------------------------------------------------------*/ const $d7bdfb9eb0fdf311$var$RovingFocusGroupImpl = /*#__PURE__*/ $98Iye$forwardRef((props, forwardedRef)=>{
50
+ const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , orientation: orientation , loop: loop = false , dir: dir , currentTabStopId: currentTabStopIdProp , defaultCurrentTabStopId: defaultCurrentTabStopId , onCurrentTabStopIdChange: onCurrentTabStopIdChange , onEntryFocus: onEntryFocus , ...groupProps } = props;
51
+ const ref = $98Iye$useRef(null);
52
+ const composedRefs = $98Iye$useComposedRefs(forwardedRef, ref);
53
+ const direction = $98Iye$useDirection(dir);
54
+ const [currentTabStopId = null, setCurrentTabStopId] = $98Iye$useControllableState({
55
+ prop: currentTabStopIdProp,
56
+ defaultProp: defaultCurrentTabStopId,
57
+ onChange: onCurrentTabStopIdChange
58
+ });
59
+ const [isTabbingBackOut, setIsTabbingBackOut] = $98Iye$useState(false);
60
+ const handleEntryFocus = $98Iye$useCallbackRef(onEntryFocus);
61
+ const getItems = $d7bdfb9eb0fdf311$var$useCollection(__scopeRovingFocusGroup);
62
+ const isClickFocusRef = $98Iye$useRef(false);
63
+ $98Iye$useEffect(()=>{
64
+ const node = ref.current;
65
+ if (node) {
66
+ node.addEventListener($d7bdfb9eb0fdf311$var$ENTRY_FOCUS, handleEntryFocus);
67
+ return ()=>node.removeEventListener($d7bdfb9eb0fdf311$var$ENTRY_FOCUS, handleEntryFocus)
68
+ ;
69
+ }
70
+ }, [
71
+ handleEntryFocus
72
+ ]);
73
+ return /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$RovingFocusProvider, {
74
+ scope: __scopeRovingFocusGroup,
75
+ orientation: orientation,
76
+ dir: direction,
77
+ loop: loop,
78
+ currentTabStopId: currentTabStopId,
79
+ onItemFocus: $98Iye$useCallback((tabStopId)=>setCurrentTabStopId(tabStopId)
80
+ , [
81
+ setCurrentTabStopId
82
+ ]),
83
+ onItemShiftTab: $98Iye$useCallback(()=>setIsTabbingBackOut(true)
84
+ , [])
85
+ }, /*#__PURE__*/ $98Iye$createElement($98Iye$Primitive.div, $98Iye$babelruntimehelpersesmextends({
86
+ tabIndex: isTabbingBackOut ? -1 : 0,
87
+ "data-orientation": orientation
88
+ }, groupProps, {
89
+ ref: composedRefs,
90
+ style: {
91
+ outline: 'none',
92
+ ...props.style
93
+ },
94
+ onMouseDown: $98Iye$composeEventHandlers(props.onMouseDown, ()=>{
95
+ isClickFocusRef.current = true;
96
+ }),
97
+ onFocus: $98Iye$composeEventHandlers(props.onFocus, (event)=>{
98
+ // We normally wouldn't need this check, because we already check
99
+ // that the focus is on the current target and not bubbling to it.
100
+ // We do this because Safari doesn't focus buttons when clicked, and
101
+ // instead, the wrapper will get focused and not through a bubbling event.
102
+ const isKeyboardFocus = !isClickFocusRef.current;
103
+ if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
104
+ const entryFocusEvent = new CustomEvent($d7bdfb9eb0fdf311$var$ENTRY_FOCUS, $d7bdfb9eb0fdf311$var$EVENT_OPTIONS);
105
+ event.currentTarget.dispatchEvent(entryFocusEvent);
106
+ if (!entryFocusEvent.defaultPrevented) {
107
+ const items = getItems().filter((item)=>item.focusable
108
+ );
109
+ const activeItem = items.find((item)=>item.active
110
+ );
111
+ const currentItem = items.find((item)=>item.id === currentTabStopId
112
+ );
113
+ const candidateItems = [
114
+ activeItem,
115
+ currentItem,
116
+ ...items
117
+ ].filter(Boolean);
118
+ const candidateNodes = candidateItems.map((item)=>item.ref.current
119
+ );
120
+ $d7bdfb9eb0fdf311$var$focusFirst(candidateNodes);
121
+ }
122
+ }
123
+ isClickFocusRef.current = false;
124
+ }),
125
+ onBlur: $98Iye$composeEventHandlers(props.onBlur, ()=>setIsTabbingBackOut(false)
126
+ )
127
+ })));
128
+ });
129
+ /* -------------------------------------------------------------------------------------------------
130
+ * RovingFocusGroupItem
131
+ * -----------------------------------------------------------------------------------------------*/ const $d7bdfb9eb0fdf311$var$ITEM_NAME = 'RovingFocusGroupItem';
132
+ const $d7bdfb9eb0fdf311$export$ab9df7c53fe8454 = /*#__PURE__*/ $98Iye$forwardRef((props, forwardedRef)=>{
133
+ const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , focusable: focusable = true , active: active = false , ...itemProps } = props;
134
+ const id = $98Iye$useId();
135
+ const context = $d7bdfb9eb0fdf311$var$useRovingFocusContext($d7bdfb9eb0fdf311$var$ITEM_NAME, __scopeRovingFocusGroup);
136
+ const isCurrentTabStop = context.currentTabStopId === id;
137
+ const getItems = $d7bdfb9eb0fdf311$var$useCollection(__scopeRovingFocusGroup);
138
+ return /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$Collection.ItemSlot, {
139
+ scope: __scopeRovingFocusGroup,
140
+ id: id,
141
+ focusable: focusable,
142
+ active: active
143
+ }, /*#__PURE__*/ $98Iye$createElement($98Iye$Primitive.span, $98Iye$babelruntimehelpersesmextends({
144
+ tabIndex: isCurrentTabStop ? 0 : -1,
145
+ "data-orientation": context.orientation
146
+ }, itemProps, {
147
+ ref: forwardedRef,
148
+ onMouseDown: $98Iye$composeEventHandlers(props.onMouseDown, (event)=>{
149
+ // We prevent focusing non-focusable items on `mousedown`.
150
+ // Even though the item has tabIndex={-1}, that only means take it out of the tab order.
151
+ if (!focusable) event.preventDefault(); // Safari doesn't focus a button when clicked so we run our logic on mousedown also
152
+ else context.onItemFocus(id);
153
+ }),
154
+ onFocus: $98Iye$composeEventHandlers(props.onFocus, ()=>context.onItemFocus(id)
155
+ ),
156
+ onKeyDown: $98Iye$composeEventHandlers(props.onKeyDown, (event)=>{
157
+ if (event.key === 'Tab' && event.shiftKey) {
158
+ context.onItemShiftTab();
159
+ return;
160
+ }
161
+ if (event.target !== event.currentTarget) return;
162
+ const focusIntent = $d7bdfb9eb0fdf311$var$getFocusIntent(event, context.orientation, context.dir);
163
+ if (focusIntent !== undefined) {
164
+ event.preventDefault();
165
+ const items = getItems().filter((item)=>item.focusable
166
+ );
167
+ let candidateNodes = items.map((item)=>item.ref.current
168
+ );
169
+ if (focusIntent === 'last') candidateNodes.reverse();
170
+ else if (focusIntent === 'prev' || focusIntent === 'next') {
171
+ if (focusIntent === 'prev') candidateNodes.reverse();
172
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
173
+ candidateNodes = context.loop ? $d7bdfb9eb0fdf311$var$wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
174
+ }
175
+ /**
176
+ * Imperative focus during keydown is risky so we prevent React's batching updates
177
+ * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332
178
+ */ setTimeout(()=>$d7bdfb9eb0fdf311$var$focusFirst(candidateNodes)
179
+ );
180
+ }
181
+ })
182
+ })));
183
+ });
184
+ /*#__PURE__*/ Object.assign($d7bdfb9eb0fdf311$export$ab9df7c53fe8454, {
185
+ displayName: $d7bdfb9eb0fdf311$var$ITEM_NAME
186
+ });
187
+ /* -----------------------------------------------------------------------------------------------*/ // prettier-ignore
188
+ const $d7bdfb9eb0fdf311$var$MAP_KEY_TO_FOCUS_INTENT = {
189
+ ArrowLeft: 'prev',
190
+ ArrowUp: 'prev',
191
+ ArrowRight: 'next',
192
+ ArrowDown: 'next',
193
+ PageUp: 'first',
194
+ Home: 'first',
195
+ PageDown: 'last',
196
+ End: 'last'
197
+ };
198
+ function $d7bdfb9eb0fdf311$var$getDirectionAwareKey(key, dir) {
199
+ if (dir !== 'rtl') return key;
200
+ return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;
201
+ }
202
+ function $d7bdfb9eb0fdf311$var$getFocusIntent(event, orientation, dir) {
203
+ const key = $d7bdfb9eb0fdf311$var$getDirectionAwareKey(event.key, dir);
204
+ if (orientation === 'vertical' && [
205
+ 'ArrowLeft',
206
+ 'ArrowRight'
207
+ ].includes(key)) return undefined;
208
+ if (orientation === 'horizontal' && [
209
+ 'ArrowUp',
210
+ 'ArrowDown'
211
+ ].includes(key)) return undefined;
212
+ return $d7bdfb9eb0fdf311$var$MAP_KEY_TO_FOCUS_INTENT[key];
213
+ }
214
+ function $d7bdfb9eb0fdf311$var$focusFirst(candidates) {
215
+ const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
216
+ for (const candidate of candidates){
217
+ // if focus is already where we want to go, we don't want to keep going through the candidates
218
+ if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
219
+ candidate.focus();
220
+ if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
221
+ }
222
+ }
223
+ /**
224
+ * Wraps an array around itself at a given start index
225
+ * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
226
+ */ function $d7bdfb9eb0fdf311$var$wrapArray(array, startIndex) {
227
+ return array.map((_, index)=>array[(startIndex + index) % array.length]
228
+ );
229
+ }
230
+ const $d7bdfb9eb0fdf311$export$be92b6f5f03c0fe9 = $d7bdfb9eb0fdf311$export$8699f7c8af148338;
231
+ const $d7bdfb9eb0fdf311$export$6d08773d2e66f8f2 = $d7bdfb9eb0fdf311$export$ab9df7c53fe8454;
232
+
233
+
234
+
235
+
236
+ 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
237
  //# 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 {\n createRovingFocusGroupScope,\n //\n RovingFocusGroup,\n RovingFocusGroupItem,\n //\n Root,\n Item,\n} from './RovingFocusGroup';\nexport type { RovingFocusGroupProps, RovingFocusItemProps } from './RovingFocusGroup';\n","import * as React from 'react';\nimport { composeEventHandlers } from '@radix-ui/primitive';\nimport { createCollection } from '@radix-ui/react-collection';\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useId } from '@radix-ui/react-id';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { useCallbackRef } from '@radix-ui/react-use-callback-ref';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport { useDirection } from '@radix-ui/react-direction';\n\nimport type * 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 CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);\n event.currentTarget.dispatchEvent(entryFocusEvent);\n\n if (!entryFocusEvent.defaultPrevented) {\n const items = getItems().filter((item) => item.focusable);\n const activeItem = items.find((item) => item.active);\n const currentItem = items.find((item) => item.id === currentTabStopId);\n const candidateItems = [activeItem, currentItem, ...items].filter(\n Boolean\n ) as typeof items;\n const candidateNodes = candidateItems.map((item) => item.ref.current!);\n focusFirst(candidateNodes);\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":["createRovingFocusGroupScope","RovingFocusGroup","RovingFocusGroupItem","Root","Item","React","composeEventHandlers","createCollection","useComposedRefs","createContextScope","useId","Primitive","useCallbackRef","useControllableState","useDirection","ENTRY_FOCUS","EVENT_OPTIONS","bubbles","cancelable","GROUP_NAME","Collection","useCollection","createCollectionScope","createRovingFocusGroupContext","RovingFocusProvider","useRovingFocusContext","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","CustomEvent","dispatchEvent","defaultPrevented","items","filter","item","focusable","activeItem","find","active","currentItem","id","candidateItems","Boolean","candidateNodes","map","focusFirst","onBlur","ITEM_NAME","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"],"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.5",
3
+ "version": "0.1.6-rc.50",
4
4
  "license": "MIT",
5
5
  "source": "src/index.ts",
6
6
  "main": "dist/index.js",
@@ -17,18 +17,19 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@babel/runtime": "^7.13.10",
20
- "@radix-ui/primitive": "0.1.0",
21
- "@radix-ui/react-collection": "0.1.5-rc.2",
22
- "@radix-ui/react-compose-refs": "0.1.1-rc.2",
23
- "@radix-ui/react-context": "0.1.2-rc.2",
24
- "@radix-ui/react-direction": "0.1.0-rc.5",
25
- "@radix-ui/react-id": "0.1.6-rc.2",
26
- "@radix-ui/react-primitive": "0.1.5-rc.2",
27
- "@radix-ui/react-use-callback-ref": "0.1.1-rc.2",
28
- "@radix-ui/react-use-controllable-state": "0.1.1-rc.2"
20
+ "@radix-ui/primitive": "0.1.1-rc.7",
21
+ "@radix-ui/react-collection": "0.1.5-rc.47",
22
+ "@radix-ui/react-compose-refs": "0.1.1-rc.47",
23
+ "@radix-ui/react-context": "0.1.2-rc.47",
24
+ "@radix-ui/react-direction": "0.1.0-rc.50",
25
+ "@radix-ui/react-id": "0.1.6-rc.47",
26
+ "@radix-ui/react-primitive": "0.1.5-rc.47",
27
+ "@radix-ui/react-use-callback-ref": "0.1.1-rc.47",
28
+ "@radix-ui/react-use-controllable-state": "0.1.1-rc.47"
29
29
  },
30
30
  "peerDependencies": {
31
- "react": "^16.8 || ^17.0 || ^18.0"
31
+ "react": "^16.8 || ^17.0 || ^18.0",
32
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
32
33
  },
33
34
  "homepage": "https://radix-ui.com/primitives",
34
35
  "repository": {