UNPKG

tailwind-header-tabs

Version:

`HeaderTabs` is a customizable and accessible React component for displaying tabbed navigation with optional icons, count badges, and multi-tab selection via an auto-complete input.

153 lines (152 loc) 4.93 kB
import { jsxs as p, jsx as l } from "react/jsx-runtime"; import j, { useState as y, useRef as k, useEffect as L, useMemo as N } from "react"; const V = ({ data: c, selectedData: s, onCountrySelect: m }) => { const [a, f] = y(""), [h, i] = y(!1), u = k(null), o = c.filter( (t) => t.toLowerCase().includes(a.toLowerCase()) && !s.find((d) => d.label === t) ); L(() => { const t = (d) => { u.current && !u.current.contains(d.target) && i(!1); }; return document.addEventListener("mousedown", t), () => document.removeEventListener("mousedown", t); }, []); const b = (t) => { m(t), f(""), i(!1); }; return o.length ? /* @__PURE__ */ p( "li", { className: `relative ${s.length ? "bottom-[-3px]" : "mb-1 w-full"}`, ref: u, children: [ /* @__PURE__ */ l( "input", { type: "text", value: a, onFocus: () => i(!0), onChange: (t) => f(t.target.value), className: "border border-slate-200 rounded-lg p-2 w-full", placeholder: "Select country..." } ), h && o.length > 0 && /* @__PURE__ */ l("ul", { className: "absolute z-10 w-full mt-1 max-h-60 overflow-y-auto bg-white border border-gray-200 rounded-md shadow-lg", children: o.map((t) => /* @__PURE__ */ l( "li", { className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-start", onClick: () => b(t), children: t }, t )) }) ] } ) : null; }, x = { active: "#2563eb", inactive: "#6b7280" }, z = ({ tabs: c, activeTab: s, showCountBadges: m, icons: a, onClickTab: f, activeIconColor: h = x.active, inactiveIconColor: i = x.inactive, countLabel: u = {}, selectable: o = !1, containerClasses: b = "" }) => { const [t, d] = j.useState([]), v = k({}), I = N(() => (e, r) => typeof a == "function" ? a(r)[e] : null, [a]), S = N(() => (e) => /* @__PURE__ */ l("span", { className: "inline-flex items-center capitalize text-xs font-semibold bg-gray-100 text-gray-600 px-2 py-[1px] rounded-md ms-2", children: e }), []), R = (e) => { const r = v.current[e.id]; r && r.scrollIntoView({ behavior: "smooth", block: "center", inline: "center" }), f(e); }, $ = (e) => { d( (r) => r.filter((n) => n.id !== e) ); }; return /* @__PURE__ */ l("div", { className: "border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ p( "ul", { className: `flex flex-none -mb-px text-sm font-medium text-gray-500 dark:text-gray-400 overflow-hidden gap-x-2 ${b}`, children: [ (o ? t : c).map((e) => { const r = (s == null ? void 0 : s.id) === e.id, n = r ? h : i, w = I(e.label, n); let g = 0; m && (g = u[e.label] || 0); const E = `inline-flex items-center justify-center border-b-2 rounded-t-lg group ${r ? "text-blue-600 border-blue-600 dark:text-blue-500 dark:border-blue-500" : "border-transparent hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300"}`; return /* @__PURE__ */ l( "li", { ref: (C) => { C && (v.current[e.id] = C); }, children: /* @__PURE__ */ p("button", { "data-id": e.id, className: E, children: [ /* @__PURE__ */ p( "span", { onClick: () => R(e), className: "flex items-center p-2 md:p-3 w-max", children: [ w, /* @__PURE__ */ l( "span", { className: `${w && "ps-2"} text-[${n}] md:text-base text-[13px]`, children: e.label } ), m && g > 0 && S(g) ] } ), o && /* @__PURE__ */ l( "span", { onClick: () => $(e.id), className: "px-2", children: "×" } ) ] }) }, e.id ); }), o && /* @__PURE__ */ l( V, { data: c.map((e) => e.label), selectedData: t, onCountrySelect: (e) => { if (t.some((n) => n.label === e)) return; const r = c.find( (n) => n.label === e ); r && d((n) => [ ...n, r ]); } } ) ] } ) }); }; z.defaultProps = { activeIconColor: x.active, inactiveIconColor: x.inactive }; export { z as default };