UNPKG

@primer/react-brand

Version:

Primer Brand is a GitHub's design system for creating React-based marketing websites and digital experiences.

129 lines (128 loc) 3.01 kB
import { useId as e } from "./useId.js"; import { useCallback as t, useRef as n, useState as r } from "react"; //#region src/hooks/useTabs.ts var i = ({ defaultTab: i, autoActivate: a = !0, orientation: o = "horizontal", onTabActivate: s } = {}) => { let c = e(), [l, u] = r({ activeTab: i || null, focusedTab: null, tabs: /* @__PURE__ */ new Set() }), d = t((e) => { u((t) => { let n = e(t); return n.activeTab && n.activeTab !== t.activeTab && t.activeTab !== null && s?.(n.activeTab, f.current.get(n.activeTab)), n; }); }, [s]), f = n(/* @__PURE__ */ new Map()), p = t((e) => `tabs-${c}-tab-${e}`, [c]), m = t((e) => `tabs-${c}-panel-${e}`, [c]), h = t((e, t) => { f.current.has(e) || (f.current.set(e, t), d((t) => ({ ...t, tabs: new Set([...t.tabs, e]), activeTab: t.activeTab || e }))); }, [d]), g = t((e) => { f.current.get(e)?.focus(); }, []), _ = t((e) => { d((t) => ({ ...t, activeTab: e, focusedTab: e })); }, [d]), v = t((e, t) => (e + 1) % t.length, []), y = t((e, t) => (e - 1 + t.length) % t.length, []), b = t((e, t) => { let n = [...l.tabs], r = n.indexOf(t); switch (!0) { case e.key === "ArrowLeft" && o === "horizontal": case e.key === "ArrowUp" && o === "vertical": { e.preventDefault(); let t = n[y(r, n)]; g(t), a && _(t); break; } case e.key === "ArrowRight" && o === "horizontal": case e.key === "ArrowDown" && o === "vertical": { e.preventDefault(); let t = n[v(r, n)]; g(t), a && _(t); break; } case e.key === "Home": e.preventDefault(), g(n[0]), a && _(n[0]); break; case e.key === "End": e.preventDefault(), g(n[n.length - 1]), a && _(n[n.length - 1]); break; case e.key === " ": case e.key === "Enter": e.preventDefault(), a || _(t); break; } }, [ l.tabs, o, y, g, a, _, v ]), x = t((e) => { _(e); }, [_]), S = t((e) => { d((t) => t.focusedTab === e ? t : { ...t, focusedTab: e }); }, [d]), C = t(({ label: e, labelledBy: t }) => ({ role: "tablist", "aria-orientation": o, ...e && { "aria-label": e }, ...t && { "aria-labelledby": t } }), [o]), w = t((e, t) => ({ role: "tab", id: p(e), "aria-controls": m(e), "aria-selected": e === l.activeTab, tabIndex: e === l.activeTab ? 0 : -1, onClick: () => x(e), onKeyDown: (t) => b(t, e), onFocus: () => S(e), ref: (n) => { if (n && h(e, n), t) { if (typeof t == "function") { t(n); return; } if ("current" in t) { t.current = n; return; } } } }), [ l.activeTab, p, m, x, b, S, h ]), T = t((e) => ({ role: "tabpanel", id: m(e), "aria-labelledby": p(e), hidden: e !== l.activeTab, tabIndex: 0 }), [ l.activeTab, m, p ]); return { activeTab: l.activeTab, focusedTab: l.focusedTab, activateTab: _, focusTab: g, getTabListProps: C, getTabProps: w, getTabPanelProps: T }; }; //#endregion export { i as useTabs }; //# sourceMappingURL=useTabs.js.map