UNPKG

@anoki/fse-ui

Version:

FSE UI components library

185 lines (184 loc) • 5.99 kB
import * as s from "react"; import { composeEventHandlers as p } from "./index.es479.js"; import { createCollection as H } from "./index.es569.js"; import { useComposedRefs as V } from "./index.es478.js"; import { createContextScope as z } from "./index.es477.js"; import { useId as q } from "./index.es481.js"; import { Primitive as G } from "./index.es487.js"; import { useCallbackRef as J } from "./index.es565.js"; import { useControllableState as Q } from "./index.es482.js"; import { useDirection as W } from "./index.es570.js"; import { j as d } from "./index.es237.js"; var _ = "rovingFocusGroup.onEntryFocus", X = { bubbles: !1, cancelable: !0 }, I = "RovingFocusGroup", [y, N, Z] = H(I), [$, Fe] = z( I, [Z] ), [ee, oe] = $(I), O = s.forwardRef( (e, r) => /* @__PURE__ */ d.jsx(y.Provider, { scope: e.__scopeRovingFocusGroup, children: /* @__PURE__ */ d.jsx(y.Slot, { scope: e.__scopeRovingFocusGroup, children: /* @__PURE__ */ d.jsx(te, { ...e, ref: r }) }) }) ); O.displayName = I; var te = s.forwardRef((e, r) => { const { __scopeRovingFocusGroup: c, orientation: o, loop: T = !1, dir: w, currentTabStopId: v, defaultCurrentTabStopId: C, onCurrentTabStopIdChange: S, onEntryFocus: m, preventScrollOnEntryFocus: u = !1, ...b } = e, F = s.useRef(null), g = V(r, F), R = W(w), [E, t] = Q({ prop: v, defaultProp: C ?? null, onChange: S, caller: I }), [i, h] = s.useState(!1), a = J(m), l = N(c), x = s.useRef(!1), [k, D] = s.useState(0); return s.useEffect(() => { const n = F.current; if (n) return n.addEventListener(_, a), () => n.removeEventListener(_, a); }, [a]), /* @__PURE__ */ d.jsx( ee, { scope: c, orientation: o, dir: R, loop: T, currentTabStopId: E, onItemFocus: s.useCallback( (n) => t(n), [t] ), onItemShiftTab: s.useCallback(() => h(!0), []), onFocusableItemAdd: s.useCallback( () => D((n) => n + 1), [] ), onFocusableItemRemove: s.useCallback( () => D((n) => n - 1), [] ), children: /* @__PURE__ */ d.jsx( G.div, { tabIndex: i || k === 0 ? -1 : 0, "data-orientation": o, ...b, ref: g, style: { outline: "none", ...e.style }, onMouseDown: p(e.onMouseDown, () => { x.current = !0; }), onFocus: p(e.onFocus, (n) => { const L = !x.current; if (n.target === n.currentTarget && L && !i) { const P = new CustomEvent(_, X); if (n.currentTarget.dispatchEvent(P), !P.defaultPrevented) { const A = l().filter((f) => f.focusable), U = A.find((f) => f.active), B = A.find((f) => f.id === E), Y = [U, B, ...A].filter( Boolean ).map((f) => f.ref.current); M(Y, u); } } x.current = !1; }), onBlur: p(e.onBlur, () => h(!1)) } ) } ); }), K = "RovingFocusGroupItem", j = s.forwardRef( (e, r) => { const { __scopeRovingFocusGroup: c, focusable: o = !0, active: T = !1, tabStopId: w, children: v, ...C } = e, S = q(), m = w || S, u = oe(K, c), b = u.currentTabStopId === m, F = N(c), { onFocusableItemAdd: g, onFocusableItemRemove: R, currentTabStopId: E } = u; return s.useEffect(() => { if (o) return g(), () => R(); }, [o, g, R]), /* @__PURE__ */ d.jsx( y.ItemSlot, { scope: c, id: m, focusable: o, active: T, children: /* @__PURE__ */ d.jsx( G.span, { tabIndex: b ? 0 : -1, "data-orientation": u.orientation, ...C, ref: r, onMouseDown: p(e.onMouseDown, (t) => { o ? u.onItemFocus(m) : t.preventDefault(); }), onFocus: p(e.onFocus, () => u.onItemFocus(m)), onKeyDown: p(e.onKeyDown, (t) => { if (t.key === "Tab" && t.shiftKey) { u.onItemShiftTab(); return; } if (t.target !== t.currentTarget) return; const i = se(t, u.orientation, u.dir); if (i !== void 0) { if (t.metaKey || t.ctrlKey || t.altKey || t.shiftKey) return; t.preventDefault(); let a = F().filter((l) => l.focusable).map((l) => l.ref.current); if (i === "last") a.reverse(); else if (i === "prev" || i === "next") { i === "prev" && a.reverse(); const l = a.indexOf(t.currentTarget); a = u.loop ? ce(a, l + 1) : a.slice(l + 1); } setTimeout(() => M(a)); } }), children: typeof v == "function" ? v({ isCurrentTabStop: b, hasTabStop: E != null }) : v } ) } ); } ); j.displayName = K; var re = { ArrowLeft: "prev", ArrowUp: "prev", ArrowRight: "next", ArrowDown: "next", PageUp: "first", Home: "first", PageDown: "last", End: "last" }; function ne(e, r) { return r !== "rtl" ? e : e === "ArrowLeft" ? "ArrowRight" : e === "ArrowRight" ? "ArrowLeft" : e; } function se(e, r, c) { const o = ne(e.key, c); if (!(r === "vertical" && ["ArrowLeft", "ArrowRight"].includes(o)) && !(r === "horizontal" && ["ArrowUp", "ArrowDown"].includes(o))) return re[o]; } function M(e, r = !1) { const c = document.activeElement; for (const o of e) if (o === c || (o.focus({ preventScroll: r }), document.activeElement !== c)) return; } function ce(e, r) { return e.map((c, o) => e[(r + o) % e.length]); } var ge = O, Re = j; export { Re as Item, ge as Root, O as RovingFocusGroup, j as RovingFocusGroupItem, Fe as createRovingFocusGroupScope }; //# sourceMappingURL=index.es572.js.map