Socket
Socket
Sign inDemoInstall

@radix-ui/react-roving-focus

Package Overview
Dependencies
Maintainers
6
Versions
192
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@radix-ui/react-roving-focus - npm Package Compare versions

Comparing version 0.1.6-rc.5 to 0.1.6-rc.6

266

dist/index.js

@@ -1,2 +0,266 @@

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;
var $9QJ9Y$babelruntimehelpersextends = require("@babel/runtime/helpers/extends");
var $9QJ9Y$react = require("react");
var $9QJ9Y$radixuiprimitive = require("@radix-ui/primitive");
var $9QJ9Y$radixuireactcollection = require("@radix-ui/react-collection");
var $9QJ9Y$radixuireactcomposerefs = require("@radix-ui/react-compose-refs");
var $9QJ9Y$radixuireactcontext = require("@radix-ui/react-context");
var $9QJ9Y$radixuireactid = require("@radix-ui/react-id");
var $9QJ9Y$radixuireactprimitive = require("@radix-ui/react-primitive");
var $9QJ9Y$radixuireactusecallbackref = require("@radix-ui/react-use-callback-ref");
var $9QJ9Y$radixuireactusecontrollablestate = require("@radix-ui/react-use-controllable-state");
var $9QJ9Y$radixuireactdirection = require("@radix-ui/react-direction");
function $parcel$exportWildcard(dest, source) {
Object.keys(source).forEach(function(key) {
if (key === 'default' || key === '__esModule' || dest.hasOwnProperty(key)) {
return;
}
Object.defineProperty(dest, key, {
enumerable: true,
get: function get() {
return source[key];
}
});
});
return dest;
}
function $parcel$interopDefault(a) {
return a && a.__esModule ? a.default : a;
}
function $parcel$export(e, n, v, s) {
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
}
var $0063afae63b3fa70$exports = {};
$parcel$export($0063afae63b3fa70$exports, "createRovingFocusGroupScope", () => $0063afae63b3fa70$export$c7109489551a4f4);
$parcel$export($0063afae63b3fa70$exports, "RovingFocusGroup", () => $0063afae63b3fa70$export$8699f7c8af148338);
$parcel$export($0063afae63b3fa70$exports, "RovingFocusGroupItem", () => $0063afae63b3fa70$export$ab9df7c53fe8454);
$parcel$export($0063afae63b3fa70$exports, "Root", () => $0063afae63b3fa70$export$be92b6f5f03c0fe9);
$parcel$export($0063afae63b3fa70$exports, "Item", () => $0063afae63b3fa70$export$6d08773d2e66f8f2);
const $0063afae63b3fa70$var$ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';
const $0063afae63b3fa70$var$EVENT_OPTIONS = {
bubbles: false,
cancelable: true
};
/* -------------------------------------------------------------------------------------------------
* RovingFocusGroup
* -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$GROUP_NAME = 'RovingFocusGroup';
const [$0063afae63b3fa70$var$Collection, $0063afae63b3fa70$var$useCollection, $0063afae63b3fa70$var$createCollectionScope] = $9QJ9Y$radixuireactcollection.createCollection($0063afae63b3fa70$var$GROUP_NAME);
const [$0063afae63b3fa70$var$createRovingFocusGroupContext, $0063afae63b3fa70$export$c7109489551a4f4] = $9QJ9Y$radixuireactcontext.createContextScope($0063afae63b3fa70$var$GROUP_NAME, [
$0063afae63b3fa70$var$createCollectionScope
]);
const [$0063afae63b3fa70$var$RovingFocusProvider, $0063afae63b3fa70$var$useRovingFocusContext] = $0063afae63b3fa70$var$createRovingFocusGroupContext($0063afae63b3fa70$var$GROUP_NAME);
const $0063afae63b3fa70$export$8699f7c8af148338 = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{
return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.Provider, {
scope: props.__scopeRovingFocusGroup
}, /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.Slot, {
scope: props.__scopeRovingFocusGroup
}, /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$RovingFocusGroupImpl, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({}, props, {
ref: forwardedRef
}))));
});
/*#__PURE__*/ Object.assign($0063afae63b3fa70$export$8699f7c8af148338, {
displayName: $0063afae63b3fa70$var$GROUP_NAME
});
/* -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$RovingFocusGroupImpl = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{
const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , orientation: orientation , loop: loop = false , dir: dir , currentTabStopId: currentTabStopIdProp , defaultCurrentTabStopId: defaultCurrentTabStopId , onCurrentTabStopIdChange: onCurrentTabStopIdChange , onEntryFocus: onEntryFocus , ...groupProps } = props;
const ref = $9QJ9Y$react.useRef(null);
const composedRefs = $9QJ9Y$radixuireactcomposerefs.useComposedRefs(forwardedRef, ref);
const direction = $9QJ9Y$radixuireactdirection.useDirection(dir);
const [currentTabStopId = null, setCurrentTabStopId] = $9QJ9Y$radixuireactusecontrollablestate.useControllableState({
prop: currentTabStopIdProp,
defaultProp: defaultCurrentTabStopId,
onChange: onCurrentTabStopIdChange
});
const [isTabbingBackOut, setIsTabbingBackOut] = $9QJ9Y$react.useState(false);
const handleEntryFocus = $9QJ9Y$radixuireactusecallbackref.useCallbackRef(onEntryFocus);
const getItems = $0063afae63b3fa70$var$useCollection(__scopeRovingFocusGroup);
const isClickFocusRef = $9QJ9Y$react.useRef(false);
$9QJ9Y$react.useEffect(()=>{
const node = ref.current;
if (node) {
node.addEventListener($0063afae63b3fa70$var$ENTRY_FOCUS, handleEntryFocus);
return ()=>node.removeEventListener($0063afae63b3fa70$var$ENTRY_FOCUS, handleEntryFocus)
;
}
}, [
handleEntryFocus
]);
return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$RovingFocusProvider, {
scope: __scopeRovingFocusGroup,
orientation: orientation,
dir: direction,
loop: loop,
currentTabStopId: currentTabStopId,
onItemFocus: $9QJ9Y$react.useCallback((tabStopId)=>setCurrentTabStopId(tabStopId)
, [
setCurrentTabStopId
]),
onItemShiftTab: $9QJ9Y$react.useCallback(()=>setIsTabbingBackOut(true)
, [])
}, /*#__PURE__*/ $9QJ9Y$react.createElement($9QJ9Y$radixuireactprimitive.Primitive.div, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({
tabIndex: isTabbingBackOut ? -1 : 0,
"data-orientation": orientation
}, groupProps, {
ref: composedRefs,
style: {
outline: 'none',
...props.style
},
onMouseDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onMouseDown, ()=>{
isClickFocusRef.current = true;
}),
onFocus: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onFocus, (event)=>{
// We normally wouldn't need this check, because we already check
// that the focus is on the current target and not bubbling to it.
// We do this because Safari doesn't focus buttons when clicked, and
// instead, the wrapper will get focused and not through a bubbling event.
const isKeyboardFocus = !isClickFocusRef.current;
if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
const entryFocusEvent = new Event($0063afae63b3fa70$var$ENTRY_FOCUS, $0063afae63b3fa70$var$EVENT_OPTIONS);
event.currentTarget.dispatchEvent(entryFocusEvent);
if (!entryFocusEvent.defaultPrevented) {
const items = getItems().filter((item)=>item.focusable
);
const activeItem = items.find((item)=>item.active
);
const currentItem = items.find((item)=>item.id === currentTabStopId
);
const candidateItems = [
activeItem,
currentItem,
...items
].filter(Boolean);
const candidateNodes = candidateItems.map((item)=>item.ref.current
);
$0063afae63b3fa70$var$focusFirst(candidateNodes);
}
}
isClickFocusRef.current = false;
}),
onBlur: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onBlur, ()=>setIsTabbingBackOut(false)
)
})));
});
/* -------------------------------------------------------------------------------------------------
* RovingFocusGroupItem
* -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$ITEM_NAME = 'RovingFocusGroupItem';
const $0063afae63b3fa70$export$ab9df7c53fe8454 = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{
const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , focusable: focusable = true , active: active = false , ...itemProps } = props;
const id = $9QJ9Y$radixuireactid.useId();
const context = $0063afae63b3fa70$var$useRovingFocusContext($0063afae63b3fa70$var$ITEM_NAME, __scopeRovingFocusGroup);
const isCurrentTabStop = context.currentTabStopId === id;
const getItems = $0063afae63b3fa70$var$useCollection(__scopeRovingFocusGroup);
return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.ItemSlot, {
scope: __scopeRovingFocusGroup,
id: id,
focusable: focusable,
active: active
}, /*#__PURE__*/ $9QJ9Y$react.createElement($9QJ9Y$radixuireactprimitive.Primitive.span, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({
tabIndex: isCurrentTabStop ? 0 : -1,
"data-orientation": context.orientation
}, itemProps, {
ref: forwardedRef,
onMouseDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onMouseDown, (event)=>{
// We prevent focusing non-focusable items on `mousedown`.
// Even though the item has tabIndex={-1}, that only means take it out of the tab order.
if (!focusable) event.preventDefault(); // Safari doesn't focus a button when clicked so we run our logic on mousedown also
else context.onItemFocus(id);
}),
onFocus: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onFocus, ()=>context.onItemFocus(id)
),
onKeyDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onKeyDown, (event)=>{
if (event.key === 'Tab' && event.shiftKey) {
context.onItemShiftTab();
return;
}
if (event.target !== event.currentTarget) return;
const focusIntent = $0063afae63b3fa70$var$getFocusIntent(event, context.orientation, context.dir);
if (focusIntent !== undefined) {
event.preventDefault();
const items = getItems().filter((item)=>item.focusable
);
let candidateNodes = items.map((item)=>item.ref.current
);
if (focusIntent === 'last') candidateNodes.reverse();
else if (focusIntent === 'prev' || focusIntent === 'next') {
if (focusIntent === 'prev') candidateNodes.reverse();
const currentIndex = candidateNodes.indexOf(event.currentTarget);
candidateNodes = context.loop ? $0063afae63b3fa70$var$wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
}
/**
* Imperative focus during keydown is risky so we prevent React's batching updates
* to avoid potential bugs. See: https://github.com/facebook/react/issues/20332
*/ setTimeout(()=>$0063afae63b3fa70$var$focusFirst(candidateNodes)
);
}
})
})));
});
/*#__PURE__*/ Object.assign($0063afae63b3fa70$export$ab9df7c53fe8454, {
displayName: $0063afae63b3fa70$var$ITEM_NAME
});
/* -----------------------------------------------------------------------------------------------*/ // prettier-ignore
const $0063afae63b3fa70$var$MAP_KEY_TO_FOCUS_INTENT = {
ArrowLeft: 'prev',
ArrowUp: 'prev',
ArrowRight: 'next',
ArrowDown: 'next',
PageUp: 'first',
Home: 'first',
PageDown: 'last',
End: 'last'
};
function $0063afae63b3fa70$var$getDirectionAwareKey(key, dir) {
if (dir !== 'rtl') return key;
return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;
}
function $0063afae63b3fa70$var$getFocusIntent(event, orientation, dir) {
const key = $0063afae63b3fa70$var$getDirectionAwareKey(event.key, dir);
if (orientation === 'vertical' && [
'ArrowLeft',
'ArrowRight'
].includes(key)) return undefined;
if (orientation === 'horizontal' && [
'ArrowUp',
'ArrowDown'
].includes(key)) return undefined;
return $0063afae63b3fa70$var$MAP_KEY_TO_FOCUS_INTENT[key];
}
function $0063afae63b3fa70$var$focusFirst(candidates) {
const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
for (const candidate of candidates){
// if focus is already where we want to go, we don't want to keep going through the candidates
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
candidate.focus();
if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
}
}
/**
* Wraps an array around itself at a given start index
* Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
*/ function $0063afae63b3fa70$var$wrapArray(array, startIndex) {
return array.map((_, index)=>array[(startIndex + index) % array.length]
);
}
const $0063afae63b3fa70$export$be92b6f5f03c0fe9 = $0063afae63b3fa70$export$8699f7c8af148338;
const $0063afae63b3fa70$export$6d08773d2e66f8f2 = $0063afae63b3fa70$export$ab9df7c53fe8454;
$parcel$exportWildcard(module.exports, $0063afae63b3fa70$exports);
//# sourceMappingURL=index.js.map

@@ -1,2 +0,247 @@

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;
import $98Iye$babelruntimehelpersesmextends from "@babel/runtime/helpers/esm/extends";
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";
import {composeEventHandlers as $98Iye$composeEventHandlers} from "@radix-ui/primitive";
import {createCollection as $98Iye$createCollection} from "@radix-ui/react-collection";
import {useComposedRefs as $98Iye$useComposedRefs} from "@radix-ui/react-compose-refs";
import {createContextScope as $98Iye$createContextScope} from "@radix-ui/react-context";
import {useId as $98Iye$useId} from "@radix-ui/react-id";
import {Primitive as $98Iye$Primitive} from "@radix-ui/react-primitive";
import {useCallbackRef as $98Iye$useCallbackRef} from "@radix-ui/react-use-callback-ref";
import {useControllableState as $98Iye$useControllableState} from "@radix-ui/react-use-controllable-state";
import {useDirection as $98Iye$useDirection} from "@radix-ui/react-direction";
function $parcel$export(e, n, v, s) {
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
}
var $d7bdfb9eb0fdf311$exports = {};
$parcel$export($d7bdfb9eb0fdf311$exports, "createRovingFocusGroupScope", () => $d7bdfb9eb0fdf311$export$c7109489551a4f4);
$parcel$export($d7bdfb9eb0fdf311$exports, "RovingFocusGroup", () => $d7bdfb9eb0fdf311$export$8699f7c8af148338);
$parcel$export($d7bdfb9eb0fdf311$exports, "RovingFocusGroupItem", () => $d7bdfb9eb0fdf311$export$ab9df7c53fe8454);
$parcel$export($d7bdfb9eb0fdf311$exports, "Root", () => $d7bdfb9eb0fdf311$export$be92b6f5f03c0fe9);
$parcel$export($d7bdfb9eb0fdf311$exports, "Item", () => $d7bdfb9eb0fdf311$export$6d08773d2e66f8f2);
const $d7bdfb9eb0fdf311$var$ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';
const $d7bdfb9eb0fdf311$var$EVENT_OPTIONS = {
bubbles: false,
cancelable: true
};
/* -------------------------------------------------------------------------------------------------
* RovingFocusGroup
* -----------------------------------------------------------------------------------------------*/ const $d7bdfb9eb0fdf311$var$GROUP_NAME = 'RovingFocusGroup';
const [$d7bdfb9eb0fdf311$var$Collection, $d7bdfb9eb0fdf311$var$useCollection, $d7bdfb9eb0fdf311$var$createCollectionScope] = $98Iye$createCollection($d7bdfb9eb0fdf311$var$GROUP_NAME);
const [$d7bdfb9eb0fdf311$var$createRovingFocusGroupContext, $d7bdfb9eb0fdf311$export$c7109489551a4f4] = $98Iye$createContextScope($d7bdfb9eb0fdf311$var$GROUP_NAME, [
$d7bdfb9eb0fdf311$var$createCollectionScope
]);
const [$d7bdfb9eb0fdf311$var$RovingFocusProvider, $d7bdfb9eb0fdf311$var$useRovingFocusContext] = $d7bdfb9eb0fdf311$var$createRovingFocusGroupContext($d7bdfb9eb0fdf311$var$GROUP_NAME);
const $d7bdfb9eb0fdf311$export$8699f7c8af148338 = /*#__PURE__*/ $98Iye$forwardRef((props, forwardedRef)=>{
return /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$Collection.Provider, {
scope: props.__scopeRovingFocusGroup
}, /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$Collection.Slot, {
scope: props.__scopeRovingFocusGroup
}, /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$RovingFocusGroupImpl, $98Iye$babelruntimehelpersesmextends({}, props, {
ref: forwardedRef
}))));
});
/*#__PURE__*/ Object.assign($d7bdfb9eb0fdf311$export$8699f7c8af148338, {
displayName: $d7bdfb9eb0fdf311$var$GROUP_NAME
});
/* -----------------------------------------------------------------------------------------------*/ const $d7bdfb9eb0fdf311$var$RovingFocusGroupImpl = /*#__PURE__*/ $98Iye$forwardRef((props, forwardedRef)=>{
const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , orientation: orientation , loop: loop = false , dir: dir , currentTabStopId: currentTabStopIdProp , defaultCurrentTabStopId: defaultCurrentTabStopId , onCurrentTabStopIdChange: onCurrentTabStopIdChange , onEntryFocus: onEntryFocus , ...groupProps } = props;
const ref = $98Iye$useRef(null);
const composedRefs = $98Iye$useComposedRefs(forwardedRef, ref);
const direction = $98Iye$useDirection(dir);
const [currentTabStopId = null, setCurrentTabStopId] = $98Iye$useControllableState({
prop: currentTabStopIdProp,
defaultProp: defaultCurrentTabStopId,
onChange: onCurrentTabStopIdChange
});
const [isTabbingBackOut, setIsTabbingBackOut] = $98Iye$useState(false);
const handleEntryFocus = $98Iye$useCallbackRef(onEntryFocus);
const getItems = $d7bdfb9eb0fdf311$var$useCollection(__scopeRovingFocusGroup);
const isClickFocusRef = $98Iye$useRef(false);
$98Iye$useEffect(()=>{
const node = ref.current;
if (node) {
node.addEventListener($d7bdfb9eb0fdf311$var$ENTRY_FOCUS, handleEntryFocus);
return ()=>node.removeEventListener($d7bdfb9eb0fdf311$var$ENTRY_FOCUS, handleEntryFocus)
;
}
}, [
handleEntryFocus
]);
return /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$RovingFocusProvider, {
scope: __scopeRovingFocusGroup,
orientation: orientation,
dir: direction,
loop: loop,
currentTabStopId: currentTabStopId,
onItemFocus: $98Iye$useCallback((tabStopId)=>setCurrentTabStopId(tabStopId)
, [
setCurrentTabStopId
]),
onItemShiftTab: $98Iye$useCallback(()=>setIsTabbingBackOut(true)
, [])
}, /*#__PURE__*/ $98Iye$createElement($98Iye$Primitive.div, $98Iye$babelruntimehelpersesmextends({
tabIndex: isTabbingBackOut ? -1 : 0,
"data-orientation": orientation
}, groupProps, {
ref: composedRefs,
style: {
outline: 'none',
...props.style
},
onMouseDown: $98Iye$composeEventHandlers(props.onMouseDown, ()=>{
isClickFocusRef.current = true;
}),
onFocus: $98Iye$composeEventHandlers(props.onFocus, (event)=>{
// We normally wouldn't need this check, because we already check
// that the focus is on the current target and not bubbling to it.
// We do this because Safari doesn't focus buttons when clicked, and
// instead, the wrapper will get focused and not through a bubbling event.
const isKeyboardFocus = !isClickFocusRef.current;
if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
const entryFocusEvent = new Event($d7bdfb9eb0fdf311$var$ENTRY_FOCUS, $d7bdfb9eb0fdf311$var$EVENT_OPTIONS);
event.currentTarget.dispatchEvent(entryFocusEvent);
if (!entryFocusEvent.defaultPrevented) {
const items = getItems().filter((item)=>item.focusable
);
const activeItem = items.find((item)=>item.active
);
const currentItem = items.find((item)=>item.id === currentTabStopId
);
const candidateItems = [
activeItem,
currentItem,
...items
].filter(Boolean);
const candidateNodes = candidateItems.map((item)=>item.ref.current
);
$d7bdfb9eb0fdf311$var$focusFirst(candidateNodes);
}
}
isClickFocusRef.current = false;
}),
onBlur: $98Iye$composeEventHandlers(props.onBlur, ()=>setIsTabbingBackOut(false)
)
})));
});
/* -------------------------------------------------------------------------------------------------
* RovingFocusGroupItem
* -----------------------------------------------------------------------------------------------*/ const $d7bdfb9eb0fdf311$var$ITEM_NAME = 'RovingFocusGroupItem';
const $d7bdfb9eb0fdf311$export$ab9df7c53fe8454 = /*#__PURE__*/ $98Iye$forwardRef((props, forwardedRef)=>{
const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , focusable: focusable = true , active: active = false , ...itemProps } = props;
const id = $98Iye$useId();
const context = $d7bdfb9eb0fdf311$var$useRovingFocusContext($d7bdfb9eb0fdf311$var$ITEM_NAME, __scopeRovingFocusGroup);
const isCurrentTabStop = context.currentTabStopId === id;
const getItems = $d7bdfb9eb0fdf311$var$useCollection(__scopeRovingFocusGroup);
return /*#__PURE__*/ $98Iye$createElement($d7bdfb9eb0fdf311$var$Collection.ItemSlot, {
scope: __scopeRovingFocusGroup,
id: id,
focusable: focusable,
active: active
}, /*#__PURE__*/ $98Iye$createElement($98Iye$Primitive.span, $98Iye$babelruntimehelpersesmextends({
tabIndex: isCurrentTabStop ? 0 : -1,
"data-orientation": context.orientation
}, itemProps, {
ref: forwardedRef,
onMouseDown: $98Iye$composeEventHandlers(props.onMouseDown, (event)=>{
// We prevent focusing non-focusable items on `mousedown`.
// Even though the item has tabIndex={-1}, that only means take it out of the tab order.
if (!focusable) event.preventDefault(); // Safari doesn't focus a button when clicked so we run our logic on mousedown also
else context.onItemFocus(id);
}),
onFocus: $98Iye$composeEventHandlers(props.onFocus, ()=>context.onItemFocus(id)
),
onKeyDown: $98Iye$composeEventHandlers(props.onKeyDown, (event)=>{
if (event.key === 'Tab' && event.shiftKey) {
context.onItemShiftTab();
return;
}
if (event.target !== event.currentTarget) return;
const focusIntent = $d7bdfb9eb0fdf311$var$getFocusIntent(event, context.orientation, context.dir);
if (focusIntent !== undefined) {
event.preventDefault();
const items = getItems().filter((item)=>item.focusable
);
let candidateNodes = items.map((item)=>item.ref.current
);
if (focusIntent === 'last') candidateNodes.reverse();
else if (focusIntent === 'prev' || focusIntent === 'next') {
if (focusIntent === 'prev') candidateNodes.reverse();
const currentIndex = candidateNodes.indexOf(event.currentTarget);
candidateNodes = context.loop ? $d7bdfb9eb0fdf311$var$wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
}
/**
* Imperative focus during keydown is risky so we prevent React's batching updates
* to avoid potential bugs. See: https://github.com/facebook/react/issues/20332
*/ setTimeout(()=>$d7bdfb9eb0fdf311$var$focusFirst(candidateNodes)
);
}
})
})));
});
/*#__PURE__*/ Object.assign($d7bdfb9eb0fdf311$export$ab9df7c53fe8454, {
displayName: $d7bdfb9eb0fdf311$var$ITEM_NAME
});
/* -----------------------------------------------------------------------------------------------*/ // prettier-ignore
const $d7bdfb9eb0fdf311$var$MAP_KEY_TO_FOCUS_INTENT = {
ArrowLeft: 'prev',
ArrowUp: 'prev',
ArrowRight: 'next',
ArrowDown: 'next',
PageUp: 'first',
Home: 'first',
PageDown: 'last',
End: 'last'
};
function $d7bdfb9eb0fdf311$var$getDirectionAwareKey(key, dir) {
if (dir !== 'rtl') return key;
return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;
}
function $d7bdfb9eb0fdf311$var$getFocusIntent(event, orientation, dir) {
const key = $d7bdfb9eb0fdf311$var$getDirectionAwareKey(event.key, dir);
if (orientation === 'vertical' && [
'ArrowLeft',
'ArrowRight'
].includes(key)) return undefined;
if (orientation === 'horizontal' && [
'ArrowUp',
'ArrowDown'
].includes(key)) return undefined;
return $d7bdfb9eb0fdf311$var$MAP_KEY_TO_FOCUS_INTENT[key];
}
function $d7bdfb9eb0fdf311$var$focusFirst(candidates) {
const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
for (const candidate of candidates){
// if focus is already where we want to go, we don't want to keep going through the candidates
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
candidate.focus();
if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
}
}
/**
* Wraps an array around itself at a given start index
* Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
*/ function $d7bdfb9eb0fdf311$var$wrapArray(array, startIndex) {
return array.map((_, index)=>array[(startIndex + index) % array.length]
);
}
const $d7bdfb9eb0fdf311$export$be92b6f5f03c0fe9 = $d7bdfb9eb0fdf311$export$8699f7c8af148338;
const $d7bdfb9eb0fdf311$export$6d08773d2e66f8f2 = $d7bdfb9eb0fdf311$export$ab9df7c53fe8454;
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};
//# sourceMappingURL=index.module.js.map

18

package.json
{
"name": "@radix-ui/react-roving-focus",
"version": "0.1.6-rc.5",
"version": "0.1.6-rc.6",
"license": "MIT",

@@ -21,10 +21,10 @@ "source": "src/index.ts",

"@radix-ui/primitive": "0.1.0",
"@radix-ui/react-collection": "0.1.5-rc.2",
"@radix-ui/react-compose-refs": "0.1.1-rc.2",
"@radix-ui/react-context": "0.1.2-rc.2",
"@radix-ui/react-direction": "0.1.0-rc.5",
"@radix-ui/react-id": "0.1.6-rc.2",
"@radix-ui/react-primitive": "0.1.5-rc.2",
"@radix-ui/react-use-callback-ref": "0.1.1-rc.2",
"@radix-ui/react-use-controllable-state": "0.1.1-rc.2"
"@radix-ui/react-collection": "0.1.5-rc.3",
"@radix-ui/react-compose-refs": "0.1.1-rc.3",
"@radix-ui/react-context": "0.1.2-rc.3",
"@radix-ui/react-direction": "0.1.0-rc.6",
"@radix-ui/react-id": "0.1.6-rc.3",
"@radix-ui/react-primitive": "0.1.5-rc.3",
"@radix-ui/react-use-callback-ref": "0.1.1-rc.3",
"@radix-ui/react-use-controllable-state": "0.1.1-rc.3"
},

@@ -31,0 +31,0 @@ "peerDependencies": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc