@blakesteve/roster 5.0.0 → 5.1.0

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.
Files changed (110) hide show
  1. package/README.md +55 -8
  2. package/dist/components/atoms/Chip/Chip.cjs +1 -1
  3. package/dist/components/atoms/Chip/Chip.js +27 -27
  4. package/dist/components/atoms/Disclosure/Disclosure.cjs +1 -1
  5. package/dist/components/atoms/Disclosure/Disclosure.js +42 -44
  6. package/dist/components/atoms/Stat/Stat.cjs +1 -1
  7. package/dist/components/atoms/Stat/Stat.d.ts +27 -2
  8. package/dist/components/atoms/Stat/Stat.js +38 -13
  9. package/dist/components/atoms/Switch/Switch.cjs +1 -1
  10. package/dist/components/atoms/Switch/Switch.d.ts +11 -1
  11. package/dist/components/atoms/Switch/Switch.js +38 -36
  12. package/dist/components/atoms/Switch/switch-variants.cjs +1 -1
  13. package/dist/components/atoms/Switch/switch-variants.js +1 -1
  14. package/dist/components/molecules/LiquidTabs/LiquidNav.cjs +1 -0
  15. package/dist/components/molecules/LiquidTabs/LiquidNav.d.ts +62 -0
  16. package/dist/components/molecules/LiquidTabs/LiquidNav.js +78 -0
  17. package/dist/components/molecules/LiquidTabs/LiquidTabs.cjs +1 -0
  18. package/dist/components/molecules/LiquidTabs/LiquidTabs.d.ts +69 -0
  19. package/dist/components/molecules/LiquidTabs/LiquidTabs.js +92 -0
  20. package/dist/components/molecules/LiquidTabs/liquid-pill.cjs +1 -0
  21. package/dist/components/molecules/LiquidTabs/liquid-pill.d.ts +56 -0
  22. package/dist/components/molecules/LiquidTabs/liquid-pill.js +129 -0
  23. package/dist/components/molecules/LiquidTabs/liquid-tab-id.cjs +1 -0
  24. package/dist/components/molecules/LiquidTabs/liquid-tab-id.d.ts +12 -0
  25. package/dist/components/molecules/LiquidTabs/liquid-tab-id.js +6 -0
  26. package/dist/components/molecules/Toast/Toaster.cjs +1 -1
  27. package/dist/components/molecules/Toast/Toaster.d.ts +7 -0
  28. package/dist/components/molecules/Toast/Toaster.js +67 -45
  29. package/dist/components/organisms/Dialog/Dialog.cjs +1 -1
  30. package/dist/components/organisms/Dialog/Dialog.js +102 -79
  31. package/dist/components/organisms/Navbar/Navbar.cjs +1 -1
  32. package/dist/components/organisms/Navbar/Navbar.js +157 -157
  33. package/dist/components/organisms/Sheet/Sheet.cjs +1 -0
  34. package/dist/components/organisms/Sheet/Sheet.d.ts +82 -0
  35. package/dist/components/organisms/Sheet/Sheet.js +303 -0
  36. package/dist/components/organisms/Sheet/sheet-drag.cjs +1 -0
  37. package/dist/components/organisms/Sheet/sheet-drag.d.ts +40 -0
  38. package/dist/components/organisms/Sheet/sheet-drag.js +22 -0
  39. package/dist/hooks/useCountdown.cjs +1 -1
  40. package/dist/hooks/useCountdown.d.ts +9 -0
  41. package/dist/hooks/useCountdown.js +20 -23
  42. package/dist/index.d.ts +4 -1
  43. package/dist/internal/motion.cjs +1 -0
  44. package/dist/internal/motion.d.ts +12 -0
  45. package/dist/internal/motion.js +21 -0
  46. package/dist/internal/page-inert.cjs +1 -0
  47. package/dist/internal/page-inert.d.ts +51 -0
  48. package/dist/internal/page-inert.js +36 -0
  49. package/dist/meta.json +3 -3
  50. package/dist/roster.cjs +1 -1
  51. package/dist/roster.css +1 -1
  52. package/dist/roster.js +128 -122
  53. package/package.json +3 -4
  54. package/dist/components/atoms/LiquidTabs/LiquidTabs.cjs +0 -1
  55. package/dist/components/atoms/LiquidTabs/LiquidTabs.d.ts +0 -39
  56. package/dist/components/atoms/LiquidTabs/LiquidTabs.js +0 -120
  57. package/dist/node_modules/date-fns/_lib/getRoundingMethod.cjs +0 -1
  58. package/dist/node_modules/date-fns/_lib/getRoundingMethod.js +0 -9
  59. package/dist/node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.cjs +0 -1
  60. package/dist/node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js +0 -18
  61. package/dist/node_modules/date-fns/_lib/normalizeDates.cjs +0 -1
  62. package/dist/node_modules/date-fns/_lib/normalizeDates.js +0 -11
  63. package/dist/node_modules/date-fns/_lib/normalizeInterval.cjs +0 -1
  64. package/dist/node_modules/date-fns/_lib/normalizeInterval.js +0 -8
  65. package/dist/node_modules/date-fns/add.cjs +0 -1
  66. package/dist/node_modules/date-fns/add.js +0 -19
  67. package/dist/node_modules/date-fns/addDays.cjs +0 -1
  68. package/dist/node_modules/date-fns/addDays.js +0 -9
  69. package/dist/node_modules/date-fns/addMonths.cjs +0 -1
  70. package/dist/node_modules/date-fns/addMonths.js +0 -19
  71. package/dist/node_modules/date-fns/compareAsc.cjs +0 -1
  72. package/dist/node_modules/date-fns/compareAsc.js +0 -8
  73. package/dist/node_modules/date-fns/constants.cjs +0 -1
  74. package/dist/node_modules/date-fns/constants.js +0 -7
  75. package/dist/node_modules/date-fns/constructFrom.cjs +0 -1
  76. package/dist/node_modules/date-fns/constructFrom.js +0 -7
  77. package/dist/node_modules/date-fns/differenceInCalendarDays.cjs +0 -1
  78. package/dist/node_modules/date-fns/differenceInCalendarDays.js +0 -15
  79. package/dist/node_modules/date-fns/differenceInCalendarMonths.cjs +0 -1
  80. package/dist/node_modules/date-fns/differenceInCalendarMonths.js +0 -12
  81. package/dist/node_modules/date-fns/differenceInCalendarYears.cjs +0 -1
  82. package/dist/node_modules/date-fns/differenceInCalendarYears.js +0 -12
  83. package/dist/node_modules/date-fns/differenceInDays.cjs +0 -1
  84. package/dist/node_modules/date-fns/differenceInDays.js +0 -21
  85. package/dist/node_modules/date-fns/differenceInHours.cjs +0 -1
  86. package/dist/node_modules/date-fns/differenceInHours.js +0 -14
  87. package/dist/node_modules/date-fns/differenceInMilliseconds.cjs +0 -1
  88. package/dist/node_modules/date-fns/differenceInMilliseconds.js +0 -7
  89. package/dist/node_modules/date-fns/differenceInMinutes.cjs +0 -1
  90. package/dist/node_modules/date-fns/differenceInMinutes.js +0 -10
  91. package/dist/node_modules/date-fns/differenceInMonths.cjs +0 -1
  92. package/dist/node_modules/date-fns/differenceInMonths.js +0 -23
  93. package/dist/node_modules/date-fns/differenceInSeconds.cjs +0 -1
  94. package/dist/node_modules/date-fns/differenceInSeconds.js +0 -9
  95. package/dist/node_modules/date-fns/differenceInYears.cjs +0 -1
  96. package/dist/node_modules/date-fns/differenceInYears.js +0 -16
  97. package/dist/node_modules/date-fns/endOfDay.cjs +0 -1
  98. package/dist/node_modules/date-fns/endOfDay.js +0 -8
  99. package/dist/node_modules/date-fns/endOfMonth.cjs +0 -1
  100. package/dist/node_modules/date-fns/endOfMonth.js +0 -8
  101. package/dist/node_modules/date-fns/intervalToDuration.cjs +0 -1
  102. package/dist/node_modules/date-fns/intervalToDuration.js +0 -25
  103. package/dist/node_modules/date-fns/isAfter.cjs +0 -1
  104. package/dist/node_modules/date-fns/isAfter.js +0 -7
  105. package/dist/node_modules/date-fns/isLastDayOfMonth.cjs +0 -1
  106. package/dist/node_modules/date-fns/isLastDayOfMonth.js +0 -10
  107. package/dist/node_modules/date-fns/startOfDay.cjs +0 -1
  108. package/dist/node_modules/date-fns/startOfDay.js +0 -8
  109. package/dist/node_modules/date-fns/toDate.cjs +0 -1
  110. package/dist/node_modules/date-fns/toDate.js +0 -7
@@ -1,65 +1,67 @@
1
1
  "use client";
2
- import { jsxs as m, jsx as s } from "react/jsx-runtime";
3
- import { Description as x } from "../../../node_modules/@headlessui/react/dist/components/description/description.js";
4
- import { Field as h } from "../../../node_modules/@headlessui/react/dist/components/field/field.js";
5
- import { Label as d } from "../../../node_modules/@headlessui/react/dist/components/label/label.js";
6
- import { Switch as g } from "../../../node_modules/@headlessui/react/dist/components/switch/switch.js";
2
+ import { jsxs as o, jsx as a } from "react/jsx-runtime";
3
+ import { Description as l } from "../../../node_modules/@headlessui/react/dist/components/description/description.js";
4
+ import { Field as u } from "../../../node_modules/@headlessui/react/dist/components/field/field.js";
5
+ import { Label as g } from "../../../node_modules/@headlessui/react/dist/components/label/label.js";
6
+ import { Switch as y } from "../../../node_modules/@headlessui/react/dist/components/switch/switch.js";
7
7
  import { cn as t } from "../../../lib/utils.js";
8
- import { switchThumbVariants as u, switchTrackVariants as y } from "./switch-variants.js";
9
- const S = ({
8
+ import { switchThumbVariants as d, switchTrackVariants as N } from "./switch-variants.js";
9
+ const V = ({
10
10
  checked: c,
11
- onChange: o,
11
+ onChange: n,
12
12
  label: r,
13
- description: a,
14
- disabled: e = !1,
15
- size: i,
16
- variant: n,
17
- className: l,
18
- ariaLabel: p
13
+ description: e,
14
+ disabled: s = !1,
15
+ labelClickable: i = !0,
16
+ size: m,
17
+ variant: p,
18
+ className: f,
19
+ ariaLabel: x
19
20
  }) => {
20
- const f = r ? void 0 : p || "Toggle setting";
21
- return /* @__PURE__ */ m(
22
- h,
21
+ const h = r ? void 0 : x || "Toggle setting";
22
+ return /* @__PURE__ */ o(
23
+ u,
23
24
  {
24
25
  as: "div",
25
- className: t("rst:flex rst:items-center rst:justify-between rst:gap-4", l),
26
+ className: t("rst:flex rst:items-center rst:justify-between rst:gap-4", f),
26
27
  children: [
27
- (r || a) && /* @__PURE__ */ m("span", { className: "rst:flex rst:flex-col", children: [
28
- r && /* @__PURE__ */ s(
29
- d,
28
+ (r || e) && /* @__PURE__ */ o("span", { className: "rst:flex rst:flex-col", children: [
29
+ r && /* @__PURE__ */ a(
30
+ g,
30
31
  {
31
- passive: !0,
32
+ passive: !i,
32
33
  className: t(
33
34
  "rst:text-sm rst:font-medium rst:text-gray-900 rst:dark:text-gray-100",
34
- e && "rst:opacity-50"
35
+ i && !s && "rst:cursor-pointer",
36
+ s && "rst:opacity-50"
35
37
  ),
36
38
  children: r
37
39
  }
38
40
  ),
39
- a && /* @__PURE__ */ s(
40
- x,
41
+ e && /* @__PURE__ */ a(
42
+ l,
41
43
  {
42
44
  className: t(
43
45
  "rst:text-xs rst:text-gray-500 rst:dark:text-gray-400",
44
- e && "rst:opacity-50"
46
+ s && "rst:opacity-50"
45
47
  ),
46
- children: a
48
+ children: e
47
49
  }
48
50
  )
49
51
  ] }),
50
- /* @__PURE__ */ s(
51
- g,
52
+ /* @__PURE__ */ a(
53
+ y,
52
54
  {
53
55
  checked: c,
54
- onChange: o,
55
- disabled: e,
56
- "aria-label": f,
57
- className: t(y({ variant: n, size: i })),
58
- children: /* @__PURE__ */ s(
56
+ onChange: n,
57
+ disabled: s,
58
+ "aria-label": h,
59
+ className: t(N({ variant: p, size: m })),
60
+ children: /* @__PURE__ */ a(
59
61
  "span",
60
62
  {
61
63
  "aria-hidden": "true",
62
- className: t(u({ size: i }))
64
+ className: t(d({ size: m }))
63
65
  }
64
66
  )
65
67
  }
@@ -69,5 +71,5 @@ const S = ({
69
71
  );
70
72
  };
71
73
  export {
72
- S as Switch
74
+ V as Switch
73
75
  };
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../../../node_modules/class-variance-authority/dist/index.cjs"),t=r.cva("rst:font-ui rst:group rst:relative rst:inline-flex rst:shrink-0 rst:cursor-pointer rst:rounded-full rst:border-2 rst:border-transparent rst:transition-colors rst:duration-200 rst:ease-in-out rst:focus:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-offset-2 rst:ring-offset-background rst:disabled:cursor-not-allowed rst:disabled:opacity-50",{variants:{variant:{primary:"rst:bg-gray-200 rst:dark:bg-gray-700 rst:data-[checked]:bg-primary-500 rst:focus-visible:ring-ring",success:"rst:bg-gray-200 rst:dark:bg-gray-700 rst:data-[checked]:bg-green-500 rst:focus-visible:ring-ring",danger:"rst:bg-gray-200 rst:dark:bg-gray-700 rst:data-[checked]:bg-error-500 rst:focus-visible:ring-ring",neutral:"rst:bg-gray-200 rst:dark:bg-gray-700 rst:data-[checked]:bg-gray-600 rst:dark:data-[checked]:bg-gray-500 rst:focus-visible:ring-ring"},size:{xs:"rst:h-4 rst:w-7",sm:"rst:h-5 rst:w-9",md:"rst:h-6 rst:w-11",lg:"rst:h-7 rst:w-14"}},defaultVariants:{variant:"primary",size:"md"}}),s=r.cva("rst:pointer-events-none rst:inline-block rst:rounded-full rst:bg-white rst:shadow rst:ring-0 rst:transition rst:duration-200 rst:ease-in-out rst:transform",{variants:{size:{xs:"rst:h-3 rst:w-3 rst:translate-x-0 rst:group-data-[checked]:translate-x-3",sm:"rst:h-4 rst:w-4 rst:translate-x-0 rst:group-data-[checked]:translate-x-4",md:"rst:h-5 rst:w-5 rst:translate-x-0 rst:group-data-[checked]:translate-x-5",lg:"rst:h-6 rst:w-6 rst:translate-x-0 rst:group-data-[checked]:translate-x-7"}},defaultVariants:{size:"md"}});exports.switchThumbVariants=s;exports.switchTrackVariants=t;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../../../node_modules/class-variance-authority/dist/index.cjs"),t=r.cva("rst:before:absolute rst:before:top-1/2 rst:before:left-1/2 rst:before:size-11 rst:before:-translate-x-1/2 rst:before:-translate-y-1/2 rst:before:content-[''] rst:font-ui rst:group rst:relative rst:inline-flex rst:shrink-0 rst:cursor-pointer rst:rounded-full rst:border-2 rst:border-transparent rst:transition-colors rst:duration-200 rst:ease-in-out rst:focus:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-offset-2 rst:ring-offset-background rst:disabled:cursor-not-allowed rst:disabled:opacity-50",{variants:{variant:{primary:"rst:bg-gray-200 rst:dark:bg-gray-700 rst:data-[checked]:bg-primary-500 rst:focus-visible:ring-ring",success:"rst:bg-gray-200 rst:dark:bg-gray-700 rst:data-[checked]:bg-green-500 rst:focus-visible:ring-ring",danger:"rst:bg-gray-200 rst:dark:bg-gray-700 rst:data-[checked]:bg-error-500 rst:focus-visible:ring-ring",neutral:"rst:bg-gray-200 rst:dark:bg-gray-700 rst:data-[checked]:bg-gray-600 rst:dark:data-[checked]:bg-gray-500 rst:focus-visible:ring-ring"},size:{xs:"rst:h-4 rst:w-7",sm:"rst:h-5 rst:w-9",md:"rst:h-6 rst:w-11",lg:"rst:h-7 rst:w-14"}},defaultVariants:{variant:"primary",size:"md"}}),s=r.cva("rst:pointer-events-none rst:inline-block rst:rounded-full rst:bg-white rst:shadow rst:ring-0 rst:transition rst:duration-200 rst:ease-in-out rst:transform",{variants:{size:{xs:"rst:h-3 rst:w-3 rst:translate-x-0 rst:group-data-[checked]:translate-x-3",sm:"rst:h-4 rst:w-4 rst:translate-x-0 rst:group-data-[checked]:translate-x-4",md:"rst:h-5 rst:w-5 rst:translate-x-0 rst:group-data-[checked]:translate-x-5",lg:"rst:h-6 rst:w-6 rst:translate-x-0 rst:group-data-[checked]:translate-x-7"}},defaultVariants:{size:"md"}});exports.switchThumbVariants=s;exports.switchTrackVariants=t;
@@ -1,6 +1,6 @@
1
1
  import { cva as r } from "../../../node_modules/class-variance-authority/dist/index.js";
2
2
  const s = /* @__PURE__ */ r(
3
- "rst:font-ui rst:group rst:relative rst:inline-flex rst:shrink-0 rst:cursor-pointer rst:rounded-full rst:border-2 rst:border-transparent rst:transition-colors rst:duration-200 rst:ease-in-out rst:focus:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-offset-2 rst:ring-offset-background rst:disabled:cursor-not-allowed rst:disabled:opacity-50",
3
+ "rst:before:absolute rst:before:top-1/2 rst:before:left-1/2 rst:before:size-11 rst:before:-translate-x-1/2 rst:before:-translate-y-1/2 rst:before:content-[''] rst:font-ui rst:group rst:relative rst:inline-flex rst:shrink-0 rst:cursor-pointer rst:rounded-full rst:border-2 rst:border-transparent rst:transition-colors rst:duration-200 rst:ease-in-out rst:focus:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-offset-2 rst:ring-offset-background rst:disabled:cursor-not-allowed rst:disabled:opacity-50",
4
4
  {
5
5
  variants: {
6
6
  variant: {
@@ -0,0 +1 @@
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react/jsx-runtime"),b=require("react"),a=require("./liquid-pill.cjs"),N=require("../../../lib/utils.cjs");function I({href:r,className:t,children:d,onClick:c,"aria-current":l,"data-tab-id":s}){return u.jsx("a",{href:r,className:t,onClick:c,"aria-current":l,"data-tab-id":s,children:d})}function P({items:r,activeTab:t,onChange:d,linkComponent:c,variant:l="pill",fullWidth:s=!1,size:q="md","aria-label":y,"aria-labelledby":L,className:p}){const o=b.useRef(null),f=b.useRef(null),j=c??I;return a.useLiquidPill(o,f,t,r.map(e=>e.id).join("\0")),u.jsxs("nav",{ref:o,"aria-label":y,"aria-labelledby":L,"data-testid":"liquid-nav",style:a.LIQUID_STRIP_STYLE,className:a.liquidStripClassName(l,s,p),children:[u.jsx("div",{ref:f,"aria-hidden":!0,"data-testid":"liquid-tabs-pill",className:a.liquidPillClassName(l),style:a.LIQUID_PILL_STYLE}),r.map(e=>{const n=e.id===t;return u.jsx(j,{href:e.href,to:e.href,"aria-current":n?"page":void 0,"data-tab-id":e.id,onClick:i=>{i.defaultPrevented||i.button!==0||i.metaKey||i.ctrlKey||i.shiftKey||i.altKey||n||d?.(e.id)},className:N.cn(a.liquidItemClassName({variant:l,fullWidth:s,size:q,isActive:n}),"rst:inline-flex rst:items-center rst:justify-center rst:no-underline"),children:typeof e.label=="function"?e.label(n):e.label},e.id)})]})}exports.LiquidNav=P;
@@ -0,0 +1,62 @@
1
+ import { ComponentType, MouseEvent, ReactNode } from 'react';
2
+ import { LiquidSize, LiquidVariant } from './liquid-pill';
3
+ import { TabItem } from './LiquidTabs';
4
+ export interface LiquidNavItem extends Omit<TabItem, "panelId"> {
5
+ href: string;
6
+ }
7
+ /**
8
+ * The props every link is rendered with.
9
+ *
10
+ * `href` and `to` carry the same value, so `next/link`, React Router's `Link`
11
+ * and a plain `<a>` all work without a wrapper. `next/link` passes props it
12
+ * does not know through to its `<a>`, so the rendered link carries a `to`
13
+ * attribute too; harmless, and a wrapper can drop it. Forward `data-tab-id`
14
+ * to the DOM: the pill finds its item by it.
15
+ */
16
+ export interface LiquidNavLinkProps {
17
+ href: string;
18
+ to: string;
19
+ className: string;
20
+ children: ReactNode;
21
+ "aria-current"?: "page";
22
+ onClick: (event: MouseEvent<HTMLAnchorElement>) => void;
23
+ "data-tab-id": string;
24
+ }
25
+ export interface LiquidNavProps {
26
+ items: LiquidNavItem[];
27
+ /** The `id` of the current item. Gets `aria-current="page"` and the pill. */
28
+ activeTab: string;
29
+ /**
30
+ * Called on a plain left click, before navigation. Optional, because the
31
+ * route usually decides `activeTab`. Modified and middle clicks open
32
+ * elsewhere and do not call it.
33
+ */
34
+ onChange?: (id: string) => void;
35
+ /**
36
+ * Renders each link. Defaults to a plain `<a>`, which is right for a static
37
+ * site and wrong inside a router, where it makes every hop a full page load.
38
+ *
39
+ * **Pass it from a client component.** Functions can not cross the React
40
+ * Server Component boundary, so handing `next/link` over from a server
41
+ * layout fails the render with "Functions cannot be passed directly to
42
+ * Client Components". Bind it in a small `"use client"` wrapper.
43
+ */
44
+ linkComponent?: ComponentType<LiquidNavLinkProps>;
45
+ variant?: LiquidVariant;
46
+ fullWidth?: boolean;
47
+ size?: LiquidSize;
48
+ /** Name the navigation; a page with two `nav`s needs both named. */
49
+ "aria-label"?: string;
50
+ "aria-labelledby"?: string;
51
+ className?: string;
52
+ }
53
+ /**
54
+ * `LiquidTabs`' look, for navigation between routes: a `nav` of links rather
55
+ * than a tablist of buttons.
56
+ *
57
+ * It is a separate component, not a mode, because the two are different
58
+ * things to assistive technology. Tabs switch panels on the same page and take
59
+ * one tab stop with arrow keys between them; links go somewhere, and each is
60
+ * its own tab stop, as in any nav.
61
+ */
62
+ export declare function LiquidNav({ items, activeTab, onChange, linkComponent, variant, fullWidth, size, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, className, }: LiquidNavProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,78 @@
1
+ "use client";
2
+ import { jsxs as q, jsx as u } from "react/jsx-runtime";
3
+ import { useRef as c } from "react";
4
+ import { useLiquidPill as I, LIQUID_STRIP_STYLE as N, LIQUID_PILL_STYLE as h, liquidPillClassName as P, liquidItemClassName as j, liquidStripClassName as x } from "./liquid-pill.js";
5
+ import { cn as C } from "../../../lib/utils.js";
6
+ function K({
7
+ href: e,
8
+ className: r,
9
+ children: n,
10
+ onClick: d,
11
+ "aria-current": l,
12
+ "data-tab-id": t
13
+ }) {
14
+ return /* @__PURE__ */ u("a", { href: e, className: r, onClick: d, "aria-current": l, "data-tab-id": t, children: n });
15
+ }
16
+ function D({
17
+ items: e,
18
+ activeTab: r,
19
+ onChange: n,
20
+ linkComponent: d,
21
+ variant: l = "pill",
22
+ fullWidth: t = !1,
23
+ size: b = "md",
24
+ "aria-label": p,
25
+ "aria-labelledby": m,
26
+ className: y
27
+ }) {
28
+ const o = c(null), f = c(null), L = d ?? K;
29
+ return I(o, f, r, e.map((a) => a.id).join("\0")), /* @__PURE__ */ q(
30
+ "nav",
31
+ {
32
+ ref: o,
33
+ "aria-label": p,
34
+ "aria-labelledby": m,
35
+ "data-testid": "liquid-nav",
36
+ style: N,
37
+ className: x(l, t, y),
38
+ children: [
39
+ /* @__PURE__ */ u(
40
+ "div",
41
+ {
42
+ ref: f,
43
+ "aria-hidden": !0,
44
+ "data-testid": "liquid-tabs-pill",
45
+ className: P(l),
46
+ style: h
47
+ }
48
+ ),
49
+ e.map((a) => {
50
+ const s = a.id === r;
51
+ return /* @__PURE__ */ u(
52
+ L,
53
+ {
54
+ href: a.href,
55
+ to: a.href,
56
+ "aria-current": s ? "page" : void 0,
57
+ "data-tab-id": a.id,
58
+ onClick: (i) => {
59
+ i.defaultPrevented || i.button !== 0 || i.metaKey || i.ctrlKey || i.shiftKey || i.altKey || s || n?.(a.id);
60
+ },
61
+ className: C(
62
+ j({ variant: l, fullWidth: t, size: b, isActive: s }),
63
+ /* A button centers its label and draws no underline on its own;
64
+ a link does neither, and a host stylesheet may underline it. */
65
+ "rst:inline-flex rst:items-center rst:justify-center rst:no-underline"
66
+ ),
67
+ children: typeof a.label == "function" ? a.label(s) : a.label
68
+ },
69
+ a.id
70
+ );
71
+ })
72
+ ]
73
+ }
74
+ );
75
+ }
76
+ export {
77
+ D as LiquidNav
78
+ };
@@ -0,0 +1 @@
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("react/jsx-runtime"),d=require("react"),s=require("./liquid-pill.cjs"),_=require("./liquid-tab-id.cjs");function E({tabs:l,activeTab:r,onChange:S,variant:n="pill",fullWidth:q=!1,size:R="md",activation:b="automatic",id:A,"aria-label":h,"aria-labelledby":j,className:k}){const u=d.useRef(null),y=d.useRef(null),w=d.useId(),I=A??w;s.useLiquidPill(u,y,r,l.map(e=>e.id).join("\0"));const p=e=>{e!==r&&S(e)},[a,L]=d.useState(null),x=l.some(e=>e.id===r),N=a!==null&&l.some(e=>e.id===a)?a:x?r:l[0]?.id,P=e=>{e.currentTarget.contains(e.relatedTarget)||L(null)},T=e=>{const i=u.current;if(!i)return;const c=Array.from(i.querySelectorAll('[role="tab"]')),o=c.indexOf(e.target);if(o===-1)return;const f=c.length-1,g=getComputedStyle(i).direction==="rtl",C=g?"ArrowLeft":"ArrowRight",D=g?"ArrowRight":"ArrowLeft";let t;if(e.key===C)t=o===f?0:o+1;else if(e.key===D)t=o===0?f:o-1;else if(e.key==="Home")t=0;else if(e.key==="End")t=f;else return;e.preventDefault(),c[t].focus(),b==="automatic"&&p(l[t].id)};return m.jsxs("div",{ref:u,id:I,role:"tablist","aria-label":h,"aria-labelledby":j,"data-testid":"liquid-tabs",style:s.LIQUID_STRIP_STYLE,className:s.liquidStripClassName(n,q,k),onKeyDown:T,onBlur:P,children:[m.jsx("div",{ref:y,"aria-hidden":!0,"data-testid":"liquid-tabs-pill",className:s.liquidPillClassName(n),style:s.LIQUID_PILL_STYLE}),l.map(e=>{const i=e.id===r;return m.jsx("button",{type:"button",role:"tab",id:_.liquidTabId(I,e.id),"aria-selected":i,"aria-controls":e.panelId,tabIndex:e.id===N?0:-1,"data-tab-id":e.id,"data-testid":`liquid-tab-${e.id}`,onClick:()=>p(e.id),onFocus:()=>L(e.id),className:s.liquidItemClassName({variant:n,fullWidth:q,size:R,isActive:i}),children:typeof e.label=="function"?e.label(i):e.label},e.id)})]})}exports.LiquidTabs=E;
@@ -0,0 +1,69 @@
1
+ import { ReactNode } from 'react';
2
+ import { LiquidSize, LiquidVariant } from './liquid-pill';
3
+ export interface TabItem {
4
+ id: string;
5
+ /** Static label, or a render function that receives whether this tab is active. */
6
+ label: ReactNode | ((isActive: boolean) => ReactNode);
7
+ /**
8
+ * The `id` of the panel this tab controls, which sets `aria-controls`. Give
9
+ * every tab the same id when one panel swaps its content.
10
+ */
11
+ panelId?: string;
12
+ }
13
+ export interface LiquidTabsProps {
14
+ tabs: TabItem[];
15
+ /** The `id` of the currently active tab. */
16
+ activeTab: string;
17
+ /** Called with the new tab `id` when the user selects a different tab. */
18
+ onChange: (id: string) => void;
19
+ /**
20
+ * `"pill"` (default): a floating pill inside a padded container, `w-fit`
21
+ * unless `fullWidth` is set.
22
+ *
23
+ * `"filled"`: the active tab fills its whole cell, and the container is
24
+ * always `w-full`.
25
+ *
26
+ * Both squash the pill vertically (`scaleY`) while it stretches between tabs.
27
+ */
28
+ variant?: LiquidVariant;
29
+ /** Stretch the `pill` variant container to full width with `flex-1` buttons. */
30
+ fullWidth?: boolean;
31
+ /**
32
+ * `"md"` (default) keeps the heights this component has always had. `"lg"`
33
+ * makes every tab at least 44px tall, the WCAG 2.5.5 target size.
34
+ */
35
+ size?: LiquidSize;
36
+ /**
37
+ * `"automatic"` (default): arrowing onto a tab selects it.
38
+ * `"manual"`: arrows move focus only, and Enter or Space selects. Use it when
39
+ * selecting a tab is expensive, like swapping a whole form.
40
+ */
41
+ activation?: "automatic" | "manual";
42
+ /**
43
+ * The tablist's `id`, and the base of every tab's id: see `liquidTabId`.
44
+ * Generated when omitted, which is fine unless a panel needs to point back at
45
+ * its tab with `aria-labelledby`.
46
+ */
47
+ id?: string;
48
+ "aria-label"?: string;
49
+ "aria-labelledby"?: string;
50
+ /** Extra classes applied to the outer container. */
51
+ className?: string;
52
+ }
53
+ /**
54
+ * A controlled tab strip with a liquid sliding indicator.
55
+ *
56
+ * Follows the WAI tabs pattern: only the selected tab is in the tab order,
57
+ * Left and Right move between tabs and wrap, Home and End go to the ends. If
58
+ * `activeTab` matches no tab, the first tab takes the tab stop and no pill
59
+ * shows.
60
+ *
61
+ * Until script has measured the pill, the active tab paints the pill's color
62
+ * itself, so server-rendered HTML shows the selection too.
63
+ *
64
+ * The pill follows `activeTab`, never the click, so a change the consumer
65
+ * vetoes, or one that waits on navigation, never leaves it on the wrong tab.
66
+ *
67
+ * For navigation between routes, use `LiquidNav`, which renders links.
68
+ */
69
+ export declare function LiquidTabs({ tabs, activeTab, onChange, variant, fullWidth, size, activation, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, className, }: LiquidTabsProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,92 @@
1
+ "use client";
2
+ import { jsxs as j, jsx as q } from "react/jsx-runtime";
3
+ import { useRef as L, useId as E, useState as T } from "react";
4
+ import { useLiquidPill as F, LIQUID_STRIP_STYLE as Q, LIQUID_PILL_STYLE as U, liquidPillClassName as Y, liquidItemClassName as B, liquidStripClassName as H } from "./liquid-pill.js";
5
+ import { liquidTabId as K } from "./liquid-tab-id.js";
6
+ function J({
7
+ tabs: l,
8
+ activeTab: r,
9
+ onChange: g,
10
+ variant: s = "pill",
11
+ fullWidth: u = !1,
12
+ size: A = "md",
13
+ activation: S = "automatic",
14
+ id: h,
15
+ "aria-label": k,
16
+ "aria-labelledby": w,
17
+ className: N
18
+ }) {
19
+ const d = L(null), f = L(null), R = E(), m = h ?? R;
20
+ F(d, f, r, l.map((e) => e.id).join("\0"));
21
+ const p = (e) => {
22
+ e !== r && g(e);
23
+ }, [n, y] = T(null), x = l.some((e) => e.id === r), C = n !== null && l.some((e) => e.id === n) ? n : x ? r : l[0]?.id, b = (e) => {
24
+ e.currentTarget.contains(e.relatedTarget) || y(null);
25
+ }, D = (e) => {
26
+ const i = d.current;
27
+ if (!i) return;
28
+ const a = Array.from(
29
+ i.querySelectorAll('[role="tab"]')
30
+ ), o = a.indexOf(e.target);
31
+ if (o === -1) return;
32
+ const c = a.length - 1, I = getComputedStyle(i).direction === "rtl", P = I ? "ArrowLeft" : "ArrowRight", _ = I ? "ArrowRight" : "ArrowLeft";
33
+ let t;
34
+ if (e.key === P) t = o === c ? 0 : o + 1;
35
+ else if (e.key === _) t = o === 0 ? c : o - 1;
36
+ else if (e.key === "Home") t = 0;
37
+ else if (e.key === "End") t = c;
38
+ else return;
39
+ e.preventDefault(), a[t].focus(), S === "automatic" && p(l[t].id);
40
+ };
41
+ return /* @__PURE__ */ j(
42
+ "div",
43
+ {
44
+ ref: d,
45
+ id: m,
46
+ role: "tablist",
47
+ "aria-label": k,
48
+ "aria-labelledby": w,
49
+ "data-testid": "liquid-tabs",
50
+ style: Q,
51
+ className: H(s, u, N),
52
+ onKeyDown: D,
53
+ onBlur: b,
54
+ children: [
55
+ /* @__PURE__ */ q(
56
+ "div",
57
+ {
58
+ ref: f,
59
+ "aria-hidden": !0,
60
+ "data-testid": "liquid-tabs-pill",
61
+ className: Y(s),
62
+ style: U
63
+ }
64
+ ),
65
+ l.map((e) => {
66
+ const i = e.id === r;
67
+ return /* @__PURE__ */ q(
68
+ "button",
69
+ {
70
+ type: "button",
71
+ role: "tab",
72
+ id: K(m, e.id),
73
+ "aria-selected": i,
74
+ "aria-controls": e.panelId,
75
+ tabIndex: e.id === C ? 0 : -1,
76
+ "data-tab-id": e.id,
77
+ "data-testid": `liquid-tab-${e.id}`,
78
+ onClick: () => p(e.id),
79
+ onFocus: () => y(e.id),
80
+ className: B({ variant: s, fullWidth: u, size: A, isActive: i }),
81
+ children: typeof e.label == "function" ? e.label(i) : e.label
82
+ },
83
+ e.id
84
+ );
85
+ })
86
+ ]
87
+ }
88
+ );
89
+ }
90
+ export {
91
+ J as LiquidTabs
92
+ };
@@ -0,0 +1 @@
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react"),d=require("../../../lib/utils.cjs"),L=require("../../../internal/motion.cjs");function v(s,i,n){return d.cn("rst:font-ui rst:relative rst:flex rst:border",s==="filled"?"rst:w-full rst:overflow-hidden rst:rounded-lg":d.cn("rst:gap-1 rst:rounded-xl rst:p-1",i?"rst:w-full":"rst:w-fit"),n)}const w={background:"var(--roster-lt-bg)",borderColor:"var(--roster-lt-border)"};function x(s){return d.cn("rst:absolute rst:rounded-lg",s==="filled"?"rst:top-0 rst:bottom-0":"rst:top-1 rst:bottom-1")}const q={opacity:0,left:0,width:0,background:"var(--roster-lt-pill)"};function C({variant:s,fullWidth:i,size:n,isActive:p}){return d.cn("rst:relative rst:z-10 rst:text-sm rst:font-medium rst:transition-colors rst:cursor-pointer","rst:focus-visible:outline-2 rst:focus-visible:-outline-offset-4 rst:focus-visible:outline-current",n==="lg"&&"rst:min-h-11",s==="filled"?"rst:flex-1 rst:py-2":d.cn("rst:rounded-lg rst:py-1.5",i?"rst:flex-1":"rst:px-4"),p?"rst:text-(--roster-lt-text-active) rst:bg-(--roster-lt-pill) rst:in-data-[pill-ready]:bg-transparent":"rst:text-(--roster-lt-text-inactive) rst:hover:text-(--roster-lt-text-hover)")}function S(s,i,n,p){const y=o.useRef(null),u=o.useRef(null),g=o.useRef(n),h=o.useRef(null),a=o.useCallback(e=>{const t=s.current;if(!t)return null;const l=Array.from(t.querySelectorAll("[data-tab-id]")).find(b=>b.dataset.tabId===e);if(!l)return null;const r=t.getBoundingClientRect(),c=l.getBoundingClientRect();return{left:c.left-r.left-t.clientLeft+t.scrollLeft,width:c.width}},[s]),f=o.useCallback((e,t,l)=>{const r=i.current;r&&(r.style.transition=t,r.style.left=`${e.left}px`,r.style.width=`${e.width}px`,r.style.transform=`scaleY(${l})`)},[i]),m=o.useCallback(()=>{const e=i.current,t=a(g.current);if(y.current=t,!!e){if(!t){e.style.opacity="0";return}f(t,"none",1),e.style.opacity="1",s.current?.setAttribute("data-pill-ready","")}},[f,s,a,i]);o.useLayoutEffect(()=>{g.current=n;const e=y.current,t=a(n),l=h.current!==null&&h.current!==n;if(h.current=n,u.current&&(clearTimeout(u.current),u.current=null),!e||!t||!l||L.prefersReducedMotion()){m();return}const r=Math.min(e.left,t.left),c=Math.max(e.left+e.width,t.left+t.width);f({left:r,width:c-r},"left 130ms ease-out, width 130ms ease-out, transform 130ms ease-out",.55),u.current=setTimeout(()=>{u.current=null;const b=a(n)??t;y.current=b,f(b,"left 160ms ease-in, width 160ms ease-in, transform 160ms ease-in",1)},130)},[n,f,a,m]),o.useEffect(()=>{const e=s.current;if(!e)return;const t=()=>{u.current||m()};let l;typeof ResizeObserver<"u"&&(l=new ResizeObserver(t),l.observe(e),e.querySelectorAll("[data-tab-id]").forEach(c=>l.observe(c)));let r=!0;return document.fonts?.ready.then(()=>{r&&t()}),()=>{r=!1,l?.disconnect()}},[s,p,m]),o.useEffect(()=>()=>{u.current&&clearTimeout(u.current)},[])}exports.LIQUID_PILL_STYLE=q;exports.LIQUID_STRIP_STYLE=w;exports.liquidItemClassName=C;exports.liquidPillClassName=x;exports.liquidStripClassName=v;exports.useLiquidPill=S;
@@ -0,0 +1,56 @@
1
+ import { RefObject } from 'react';
2
+ /**
3
+ * What `LiquidTabs` and `LiquidNav` share: the strip, the pill, and the motion.
4
+ *
5
+ * Internal. The two components differ in semantics only (a tablist of buttons,
6
+ * or a `nav` of links), so everything here is about how they look and move.
7
+ */
8
+ export type LiquidVariant = "pill" | "filled";
9
+ export type LiquidSize = "md" | "lg";
10
+ export declare function liquidStripClassName(variant: LiquidVariant, fullWidth: boolean, className?: string): string;
11
+ export declare const LIQUID_STRIP_STYLE: {
12
+ readonly background: "var(--roster-lt-bg)";
13
+ readonly borderColor: "var(--roster-lt-border)";
14
+ };
15
+ export declare function liquidPillClassName(variant: LiquidVariant): string;
16
+ export declare const LIQUID_PILL_STYLE: {
17
+ readonly opacity: 0;
18
+ readonly left: 0;
19
+ readonly width: 0;
20
+ readonly background: "var(--roster-lt-pill)";
21
+ };
22
+ /**
23
+ * One tab or link.
24
+ *
25
+ * The focus indicator is an outline drawn inside the item, in its own text
26
+ * color. Inside, because the `filled` strip clips its overflow and an outer
27
+ * ring would lose its sides. The text color, because it is the one color
28
+ * guaranteed to read against whatever is behind the item: the pill under the
29
+ * active one, the strip under the rest. The library's `--roster-ring` would sit
30
+ * on a pill painted `primary-500` by default, which is the ring's own color.
31
+ * An outline rather than a box-shadow ring, because forced-colors mode drops
32
+ * box-shadows and keeps outlines.
33
+ */
34
+ export declare function liquidItemClassName({ variant, fullWidth, size, isActive, }: {
35
+ variant: LiquidVariant;
36
+ fullWidth: boolean;
37
+ size: LiquidSize;
38
+ isActive: boolean;
39
+ }): string;
40
+ /**
41
+ * Drives the pill from `activeId`, and only from `activeId`.
42
+ *
43
+ * Earlier versions moved the pill on click, before the consumer had decided
44
+ * anything, so a vetoed change or a slow navigation left it on the wrong item.
45
+ * It now follows the controlled value, so it is wherever the consumer says the
46
+ * selection is.
47
+ *
48
+ * Positions are written straight to the DOM, so the animation itself never
49
+ * renders: only the change of `activeId` does. Two phases:
50
+ * 1. Stretch: the pill spans old and new item (130ms ease-out, `scaleY(0.55)`).
51
+ * 2. Contract: it settles on the new one (160ms ease-in).
52
+ * Under `prefers-reduced-motion` it moves without either.
53
+ */
54
+ export declare function useLiquidPill(containerRef: RefObject<HTMLElement | null>, pillRef: RefObject<HTMLDivElement | null>, activeId: string,
55
+ /** Changes whenever the set of items does, so new items get observed. */
56
+ itemsKey: string): void;
@@ -0,0 +1,129 @@
1
+ "use client";
2
+ import { useRef as p, useCallback as g, useLayoutEffect as w, useEffect as v } from "react";
3
+ import { cn as a } from "../../../lib/utils.js";
4
+ import { prefersReducedMotion as L } from "../../../internal/motion.js";
5
+ function S(s, o, n) {
6
+ return a(
7
+ "rst:font-ui rst:relative rst:flex rst:border",
8
+ s === "filled" ? "rst:w-full rst:overflow-hidden rst:rounded-lg" : a("rst:gap-1 rst:rounded-xl rst:p-1", o ? "rst:w-full" : "rst:w-fit"),
9
+ n
10
+ );
11
+ }
12
+ const E = {
13
+ background: "var(--roster-lt-bg)",
14
+ borderColor: "var(--roster-lt-border)"
15
+ };
16
+ function A(s) {
17
+ return a(
18
+ "rst:absolute rst:rounded-lg",
19
+ s === "filled" ? "rst:top-0 rst:bottom-0" : "rst:top-1 rst:bottom-1"
20
+ );
21
+ }
22
+ const P = {
23
+ opacity: 0,
24
+ left: 0,
25
+ width: 0,
26
+ background: "var(--roster-lt-pill)"
27
+ };
28
+ function _({
29
+ variant: s,
30
+ fullWidth: o,
31
+ size: n,
32
+ isActive: b
33
+ }) {
34
+ return a(
35
+ "rst:relative rst:z-10 rst:text-sm rst:font-medium rst:transition-colors rst:cursor-pointer",
36
+ "rst:focus-visible:outline-2 rst:focus-visible:-outline-offset-4 rst:focus-visible:outline-current",
37
+ /* `lg` is the 44px target (WCAG 2.5.5). `md` keeps the heights every
38
+ existing consumer laid out against. */
39
+ n === "lg" && "rst:min-h-11",
40
+ s === "filled" ? "rst:flex-1 rst:py-2" : a("rst:rounded-lg rst:py-1.5", o ? "rst:flex-1" : "rst:px-4"),
41
+ /* Until the pill has been measured, which needs script, the active item
42
+ paints the pill's color itself. Without it, server-rendered HTML shows
43
+ the active label in the pill's ink on the strip's background, which by
44
+ default is white on white. */
45
+ b ? "rst:text-(--roster-lt-text-active) rst:bg-(--roster-lt-pill) rst:in-data-[pill-ready]:bg-transparent" : "rst:text-(--roster-lt-text-inactive) rst:hover:text-(--roster-lt-text-hover)"
46
+ );
47
+ }
48
+ function k(s, o, n, b) {
49
+ const y = p(null), i = p(null), x = p(n), h = p(null), c = g(
50
+ (r) => {
51
+ const t = s.current;
52
+ if (!t) return null;
53
+ const l = Array.from(
54
+ t.querySelectorAll("[data-tab-id]")
55
+ ).find((m) => m.dataset.tabId === r);
56
+ if (!l) return null;
57
+ const e = t.getBoundingClientRect(), u = l.getBoundingClientRect();
58
+ return {
59
+ left: u.left - e.left - t.clientLeft + t.scrollLeft,
60
+ width: u.width
61
+ };
62
+ },
63
+ [s]
64
+ ), f = g(
65
+ (r, t, l) => {
66
+ const e = o.current;
67
+ e && (e.style.transition = t, e.style.left = `${r.left}px`, e.style.width = `${r.width}px`, e.style.transform = `scaleY(${l})`);
68
+ },
69
+ [o]
70
+ ), d = g(() => {
71
+ const r = o.current, t = c(x.current);
72
+ if (y.current = t, !!r) {
73
+ if (!t) {
74
+ r.style.opacity = "0";
75
+ return;
76
+ }
77
+ f(t, "none", 1), r.style.opacity = "1", s.current?.setAttribute("data-pill-ready", "");
78
+ }
79
+ }, [f, s, c, o]);
80
+ w(() => {
81
+ x.current = n;
82
+ const r = y.current, t = c(n), l = h.current !== null && h.current !== n;
83
+ if (h.current = n, i.current && (clearTimeout(i.current), i.current = null), !r || !t || !l || L()) {
84
+ d();
85
+ return;
86
+ }
87
+ const e = Math.min(r.left, t.left), u = Math.max(r.left + r.width, t.left + t.width);
88
+ f(
89
+ { left: e, width: u - e },
90
+ "left 130ms ease-out, width 130ms ease-out, transform 130ms ease-out",
91
+ 0.55
92
+ ), i.current = setTimeout(() => {
93
+ i.current = null;
94
+ const m = c(n) ?? t;
95
+ y.current = m, f(
96
+ m,
97
+ "left 160ms ease-in, width 160ms ease-in, transform 160ms ease-in",
98
+ 1
99
+ );
100
+ }, 130);
101
+ }, [n, f, c, d]), v(() => {
102
+ const r = s.current;
103
+ if (!r) return;
104
+ const t = () => {
105
+ i.current || d();
106
+ };
107
+ let l;
108
+ typeof ResizeObserver < "u" && (l = new ResizeObserver(t), l.observe(r), r.querySelectorAll("[data-tab-id]").forEach((u) => l.observe(u)));
109
+ let e = !0;
110
+ return document.fonts?.ready.then(() => {
111
+ e && t();
112
+ }), () => {
113
+ e = !1, l?.disconnect();
114
+ };
115
+ }, [s, b, d]), v(
116
+ () => () => {
117
+ i.current && clearTimeout(i.current);
118
+ },
119
+ []
120
+ );
121
+ }
122
+ export {
123
+ P as LIQUID_PILL_STYLE,
124
+ E as LIQUID_STRIP_STYLE,
125
+ _ as liquidItemClassName,
126
+ A as liquidPillClassName,
127
+ S as liquidStripClassName,
128
+ k as useLiquidPill
129
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function i(t,e){return`${t}-tab-${e}`}exports.liquidTabId=i;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The `id` a `LiquidTabs` tab renders with, for a panel's `aria-labelledby`.
3
+ *
4
+ * ```tsx
5
+ * <LiquidTabs id="views" tabs={tabs} activeTab={view} onChange={setView} />
6
+ * <div role="tabpanel" id="views-panel" aria-labelledby={liquidTabId("views", view)}>
7
+ * ```
8
+ *
9
+ * The tab's own `id` is used verbatim, so keep it free of whitespace. A module
10
+ * of its own, with no React in it, so a server component can call it too.
11
+ */
12
+ export declare function liquidTabId(listId: string, tabId: string): string;