@clubmed/trident-ui 2.0.0-beta.63 → 2.0.0-beta.65

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 (86) hide show
  1. package/chunks/Backdrop.js +1 -1
  2. package/chunks/Backdrop.js.map +1 -1
  3. package/chunks/DateField.js +2 -2
  4. package/chunks/DateField.js.map +1 -1
  5. package/examples/journey-card-compact-demo.d.ts +1 -0
  6. package/examples/journey-card-compact-demo.js +71 -0
  7. package/examples/journey-card-compact-demo.js.map +1 -0
  8. package/examples/journey-card-demo.d.ts +1 -0
  9. package/examples/journey-card-demo.js +123 -0
  10. package/examples/journey-card-demo.js.map +1 -0
  11. package/examples/tabs-notification-demo.d.ts +1 -0
  12. package/examples/tabs-notification-demo.js +64 -0
  13. package/examples/tabs-notification-demo.js.map +1 -0
  14. package/package.json +1 -1
  15. package/styles/ui/controls.css +3 -6
  16. package/styles/ui/range.css +5 -0
  17. package/ui/AdvancedToast.js +2 -2
  18. package/ui/AdvancedToast.js.map +1 -1
  19. package/ui/Avatar.js +1 -1
  20. package/ui/Avatar.js.map +1 -1
  21. package/ui/BasicToast.js +2 -2
  22. package/ui/BasicToast.js.map +1 -1
  23. package/ui/Breadcrumb.js +1 -0
  24. package/ui/Breadcrumb.js.map +1 -1
  25. package/ui/ChatButton.js +1 -1
  26. package/ui/ChatButton.js.map +1 -1
  27. package/ui/ChatInput.js +1 -1
  28. package/ui/ChatInput.js.map +1 -1
  29. package/ui/ChatWindow.js +2 -2
  30. package/ui/ChatWindow.js.map +1 -1
  31. package/ui/ChatWindowCsatPrompt.js +1 -1
  32. package/ui/ChatWindowCsatPrompt.js.map +1 -1
  33. package/ui/ChoiceExpander.js +1 -1
  34. package/ui/ChoiceExpander.js.map +1 -1
  35. package/ui/ExpandableText.js +1 -1
  36. package/ui/ExpandableText.js.map +1 -1
  37. package/ui/HamburgerIcon.js +1 -1
  38. package/ui/HamburgerIcon.js.map +1 -1
  39. package/ui/Link.js +1 -1
  40. package/ui/Link.js.map +1 -1
  41. package/ui/PageNavigation.js +1 -1
  42. package/ui/PageNavigation.js.map +1 -1
  43. package/ui/Pagination.js +2 -2
  44. package/ui/Pagination.js.map +1 -1
  45. package/ui/SidebarLayout.js +4 -4
  46. package/ui/SidebarLayout.js.map +1 -1
  47. package/ui/Toggle.js +1 -1
  48. package/ui/Toggle.js.map +1 -1
  49. package/ui/buttons/Button.type.js +1 -1
  50. package/ui/buttons/Button.type.js.map +1 -1
  51. package/ui/forms/CheckboxSelect.js +1 -1
  52. package/ui/forms/CheckboxSelect.js.map +1 -1
  53. package/ui/forms/FloatingLabelTextField.js +2 -2
  54. package/ui/forms/FloatingLabelTextField.js.map +1 -1
  55. package/ui/forms/NumberField.js +1 -1
  56. package/ui/forms/NumberField.js.map +1 -1
  57. package/ui/forms/PhoneFieldFullInput.js +1 -1
  58. package/ui/forms/PhoneFieldFullInput.js.map +1 -1
  59. package/ui/forms/PhoneFieldSplitInput.js +2 -2
  60. package/ui/forms/PhoneFieldSplitInput.js.map +1 -1
  61. package/ui/forms/Select.js +1 -1
  62. package/ui/forms/Select.js.map +1 -1
  63. package/ui/forms/TextField.js +3 -3
  64. package/ui/forms/TextField.js.map +1 -1
  65. package/ui/forms/checkboxes/Checkbox.js +1 -1
  66. package/ui/forms/checkboxes/Checkbox.js.map +1 -1
  67. package/ui/forms/password/Password.js +2 -2
  68. package/ui/forms/password/Password.js.map +1 -1
  69. package/ui/journey-card/FlightSegmentCard.d.ts +15 -0
  70. package/ui/journey-card/FlightSegmentCard.js +73 -0
  71. package/ui/journey-card/FlightSegmentCard.js.map +1 -0
  72. package/ui/journey-card/FlightTimeline.d.ts +5 -0
  73. package/ui/journey-card/FlightTimeline.js +27 -0
  74. package/ui/journey-card/FlightTimeline.js.map +1 -0
  75. package/ui/journey-card/ItineraryDetails.d.ts +9 -0
  76. package/ui/journey-card/ItineraryDetails.js +40 -0
  77. package/ui/journey-card/ItineraryDetails.js.map +1 -0
  78. package/ui/journey-card/JourneyCard.d.ts +17 -0
  79. package/ui/journey-card/JourneyCard.js +34 -0
  80. package/ui/journey-card/JourneyCard.js.map +1 -0
  81. package/ui/journey-card/JourneyDetails.d.ts +47 -0
  82. package/ui/journey-card/JourneyDetails.js +183 -0
  83. package/ui/journey-card/JourneyDetails.js.map +1 -0
  84. package/ui/tabs/Tabs.d.ts +5 -1
  85. package/ui/tabs/Tabs.js +49 -43
  86. package/ui/tabs/Tabs.js.map +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JourneyDetails.js","names":[],"sources":["../../../lib/ui/journey-card/JourneyDetails.tsx"],"sourcesContent":["'use client';\n\nimport clsx from 'clsx';\nimport type { ComponentPropsWithoutRef } from 'react';\nimport { useState } from 'react';\nimport { Icon } from '@clubmed/trident-icons';\nimport { Tag } from '../Tag';\nimport { ElasticHeight } from '../ElasticHeight';\nimport { FlightTimeline } from './FlightTimeline';\nimport { ItineraryDetails } from './ItineraryDetails';\nimport type { ItineraryDetailsProps } from './ItineraryDetails';\n\nexport interface AirportInfo {\n name: string;\n terminal?: string;\n}\n\nexport interface JourneyDetailsProps extends ComponentPropsWithoutRef<'div'> {\n /** Human-readable leg label, e.g. \"Outbound\" or \"Inbound\" */\n direction: string;\n /** Controls which plane icon is rendered; falls back to `direction` when omitted */\n directionType?: 'Inbound' | 'Outbound';\n departureDate: string;\n departureTime: string;\n arrivalDate: string;\n arrivalTime: string;\n /** Total flight duration, e.g. \"9h30mn\" */\n duration: string;\n departureAirport: AirportInfo;\n arrivalAirport: AirportInfo;\n /** Connection label shown on the timeline, e.g. \"Direct\" or \"1 Stop over\" */\n stopLabel: string;\n /** Number of stopover dots on the timeline */\n nbStopovers?: number;\n airlineLogoSrc: string;\n airlineLogoAlt: string;\n /** Primary operator name */\n operatedBy: string;\n /** Secondary operator line, e.g. \"Operated by Hop\" */\n companyName?: string;\n /** Cabin / luggage summary text */\n characteristics: string;\n /** Carbon footprint text */\n carbonEmission: string;\n carbonEmissionLearnMoreUrl?: string;\n carbonEmissionLearnMoreLabel: string;\n /** How many calendar days after departure the arrival falls */\n plusDays?: number;\n /** Label appended to plusDays value, e.g. \"day\" */\n plusDaysLabel: string;\n /** Local time qualifier shown near arrival time, e.g. \"(local time)\" */\n localTimeLabel: string;\n /** Optional expanded itinerary with per-segment flight cards */\n itinerary?: ItineraryDetailsProps;\n /** When true, the component is displayed in a vertical layout for side-by-side JourneyCards */\n vertical?: boolean;\n}\n\nexport function JourneyDetails({\n itinerary,\n direction,\n directionType,\n departureDate,\n departureTime,\n arrivalDate,\n arrivalTime,\n duration,\n departureAirport,\n arrivalAirport,\n stopLabel,\n nbStopovers,\n airlineLogoSrc,\n airlineLogoAlt,\n operatedBy,\n companyName,\n characteristics,\n carbonEmission,\n carbonEmissionLearnMoreUrl,\n carbonEmissionLearnMoreLabel,\n plusDays,\n plusDaysLabel,\n localTimeLabel,\n className,\n vertical = false,\n ...props\n}: JourneyDetailsProps) {\n const [isOpen, setIsOpen] = useState(false);\n const isOutbound = (directionType ?? direction) === 'Outbound';\n\n return (\n <div\n data-name=\"JourneyDetails\"\n {...props}\n className={clsx('flex h-fit w-full flex-col gap-8', className)}\n >\n {/* Row 1 — direction label + airline logo */}\n <div className=\"flex h-48 w-full flex-row items-center justify-between\">\n <div className=\"flex h-fit flex-row items-center gap-12\">\n <Icon\n name={isOutbound ? 'PlaneOutbound' : 'PlaneInBound'}\n width=\"24px\"\n className=\"text-black\"\n />\n <span className=\"font-sans text-b3 font-semibold\">{direction}</span>\n </div>\n <img\n src={airlineLogoSrc}\n alt={airlineLogoAlt}\n width={100}\n height={28}\n className=\"object-contain\"\n />\n </div>\n\n {/* Row 2 — schedule */}\n <div className=\"flex h-fit w-full flex-col gap-4\">\n <div className=\"flex w-full flex-row items-end justify-between\">\n <div className=\"flex flex-1 flex-col\">\n <span className=\"font-sans text-b4\">{departureDate}</span>\n <span className=\"font-sans text-b1 font-semibold\">{departureTime}</span>\n </div>\n\n <div className=\"flex flex-1 justify-center\">\n <span className=\"text-center font-sans text-b4\">{duration}</span>\n </div>\n\n <div className=\"flex flex-1 flex-col items-end\">\n <div\n className={clsx(\n 'flex',\n !vertical && 'flex-row items-center justify-end gap-4',\n vertical && 'flex-col items-end justify-start gap-0',\n )}\n >\n <span className=\"font-sans text-b4\">{arrivalDate}</span>\n {plusDays && plusDays > 0 && (\n <Tag\n label={`+${plusDays} ${plusDaysLabel}`}\n theme=\"label\"\n backgroundColor=\"black\"\n color=\"white\"\n className=\"rounded-full\"\n />\n )}\n </div>\n <span className=\"text-right font-sans text-b4\">{localTimeLabel}</span>\n <span className=\"text-right font-sans text-b1 font-semibold\">{arrivalTime}</span>\n </div>\n </div>\n\n <FlightTimeline nbStopovers={nbStopovers} />\n\n <div className=\"flex w-full flex-row items-start justify-between\">\n <div className=\"flex flex-1 flex-col\">\n <span className=\"font-sans text-b4 font-semibold\">{departureAirport.name}</span>\n {departureAirport.terminal && (\n <span className=\"font-sans text-b4\">{departureAirport.terminal}</span>\n )}\n </div>\n <span className=\"flex-1 text-center font-sans text-b4\">{stopLabel}</span>\n <div className=\"flex flex-1 flex-col items-end\">\n <span className=\"font-sans text-b4 font-semibold\">{arrivalAirport.name}</span>\n {arrivalAirport.terminal && (\n <span className=\"text-right font-sans text-b4\">{arrivalAirport.terminal}</span>\n )}\n </div>\n </div>\n </div>\n\n {/* Row 3 — operator toggle */}\n <button\n type=\"button\"\n onClick={() => setIsOpen((v) => !v)}\n aria-expanded={isOpen}\n className=\"flex w-full cursor-pointer flex-row items-end justify-between border-none bg-transparent p-0 outline-none focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2\"\n >\n <div className=\"flex flex-col text-left\">\n <span className=\"font-sans text-b4 font-semibold\">{operatedBy}</span>\n {companyName && <span className=\"font-sans text-b4\">{companyName}</span>}\n </div>\n <Icon\n name=\"ArrowOutlinedUp\"\n width=\"24px\"\n className={clsx('text-black transition-transform duration-200', {\n 'rotate-180': !isOpen,\n })}\n />\n </button>\n\n {/* Rows 4 & 5 — accordion */}\n <ElasticHeight isExpanded={isOpen} innerClassName=\"flex flex-col gap-8\">\n <div className=\"flex h-fit w-full flex-row items-start gap-8\">\n <Icon name=\"Luggage\" width=\"24px\" className=\"shrink-0 text-black\" />\n <span className=\"font-sans text-b4\">{characteristics}</span>\n </div>\n <div className=\"flex h-fit w-full flex-row items-start gap-8\">\n <Icon name=\"HappyToCare\" width=\"24px\" className=\"shrink-0 text-black\" />\n <div className=\"flex flex-col\">\n <span className=\"font-sans text-b4\">{carbonEmission}</span>\n {carbonEmissionLearnMoreUrl && (\n <a\n href={carbonEmissionLearnMoreUrl}\n className=\"font-sans text-b4 underline outline-none focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2 rounded-pill\"\n >\n {carbonEmissionLearnMoreLabel}\n </a>\n )}\n </div>\n </div>\n {itinerary && <ItineraryDetails {...itinerary} />}\n </ElasticHeight>\n </div>\n );\n}\n"],"mappings":"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"}
package/ui/tabs/Tabs.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ComponentProps, ComponentPropsWithoutRef, FunctionComponent, PropsWithChildren } from 'react';
1
+ import { ComponentProps, ComponentPropsWithoutRef, FunctionComponent, PropsWithChildren, ReactNode } from 'react';
2
2
  import { TabsProvider } from '../contexts/TabControl';
3
3
  type ProviderProps = ComponentProps<typeof TabsProvider>;
4
4
  interface Props extends ProviderProps {
@@ -46,6 +46,10 @@ export interface TabSelectProps {
46
46
  }
47
47
  export declare const TabSelect: FunctionComponent<TabSelectProps>;
48
48
  interface TabProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onSelect'> {
49
+ /**
50
+ * Notification content
51
+ */
52
+ notification?: ReactNode;
49
53
  /**
50
54
  * Tab Heading text
51
55
  */
package/ui/tabs/Tabs.js CHANGED
@@ -156,79 +156,85 @@ var g = ({ className: e, compacted: t = !1, selected: r, children: i }) => /* @_
156
156
  children: e.label
157
157
  }, e.value))
158
158
  });
159
- }, x = ({ as: e = "h2", label: t, children: n, value: i, onSelect: o, className: p, ...g }) => {
160
- let _ = f(null), v = r(), y = s(), b = a({
159
+ }, x = ({ as: e = "h2", label: t, children: n, value: i, onSelect: o, className: p, notification: g, ..._ }) => {
160
+ let v = f(null), y = r(), b = s(), x = a({
161
161
  value: i,
162
- ref: _
163
- }), x = f(v), S = f(v === i);
164
- S.current = v === i;
165
- let C = { "--tab-index": i };
162
+ ref: v
163
+ }), S = f(y), C = f(y === i);
164
+ C.current = y === i;
165
+ let w = { "--tab-index": i };
166
166
  d(() => {
167
- x.current !== v && i === v && (_.current?.focus(), o?.({
167
+ S.current !== y && i === y && (v.current?.focus(), o?.({
168
168
  value: i,
169
169
  label: t
170
- })), x.current !== v && (x.current = v);
170
+ })), S.current !== y && (S.current = y);
171
171
  }, [
172
172
  t,
173
173
  i,
174
174
  o,
175
- v
175
+ y
176
176
  ]);
177
- let w = c({
177
+ let T = c({
178
178
  start: u(() => {
179
- b({ type: "start" });
180
- }, [b]),
179
+ x({ type: "start" });
180
+ }, [x]),
181
181
  end: u(() => {
182
- b({ type: "end" });
183
- }, [b]),
182
+ x({ type: "end" });
183
+ }, [x]),
184
184
  up: u(() => {
185
- b({ type: "previous" });
186
- }, [b]),
185
+ x({ type: "previous" });
186
+ }, [x]),
187
187
  down: u(() => {
188
- b({ type: "next" });
189
- }, [b]),
188
+ x({ type: "next" });
189
+ }, [x]),
190
190
  left: u(() => {
191
- b({ type: document.documentElement.dir === "rtl" ? "next" : "previous" });
192
- }, [b]),
191
+ x({ type: document.documentElement.dir === "rtl" ? "next" : "previous" });
192
+ }, [x]),
193
193
  right: u(() => {
194
- b({ type: document.documentElement.dir === "rtl" ? "previous" : "next" });
195
- }, [b])
196
- }), T = u((e) => {
194
+ x({ type: document.documentElement.dir === "rtl" ? "previous" : "next" });
195
+ }, [x])
196
+ }), E = u((e) => {
197
197
  let t = e.key === " " || e.key === "Spacebar" || e.code === "Space", n = e.key === "Enter" || e.code === "Enter";
198
- if (S.current && (t || n)) {
198
+ if (C.current && (t || n)) {
199
199
  e.preventDefault();
200
200
  return;
201
201
  }
202
- w(e);
203
- }, [w]), E = () => {
204
- S.current || b({
202
+ T(e);
203
+ }, [T]), D = () => {
204
+ C.current || x({
205
205
  type: "update",
206
206
  payload: i
207
207
  });
208
208
  };
209
209
  return /* @__PURE__ */ m("div", {
210
- ...g,
211
- id: g.id || `Tab_${i}_${y}`,
210
+ ..._,
211
+ id: _.id || `Tab_${i}_${b}`,
212
212
  "data-name": "Tab",
213
- ref: _,
213
+ ref: v,
214
214
  role: "tab",
215
- "aria-selected": S.current,
216
- "aria-controls": `TabPanel_${i}_${y}`,
217
- tabIndex: S.current ? 0 : -1,
218
- className: l("group text-b3 inline-block cursor-pointer overflow-hidden bg-transparent pe-4 align-middle font-semibold whitespace-nowrap outline-none", {
219
- "text-white": S.current,
220
- "text-black": !S.current,
221
- "transition-transform active:scale-[1.03]": S.current
215
+ "aria-selected": C.current,
216
+ "aria-controls": `TabPanel_${i}_${b}`,
217
+ tabIndex: C.current ? 0 : -1,
218
+ className: l("group/tab text-b3 inline-block cursor-pointer overflow-hidden bg-transparent pe-4 align-middle font-semibold whitespace-nowrap outline-none", {
219
+ "text-white": C.current,
220
+ "text-black": !C.current,
221
+ "transition-transform active:scale-[1.03]": C.current
222
222
  }),
223
- onKeyDown: T,
224
- onClick: E,
223
+ onKeyDown: E,
224
+ onClick: D,
225
225
  children: /* @__PURE__ */ h(e, {
226
- className: l("relative inline-block px-20 py-12", "before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within:before:bg-(--color-pearl) group-hover:before:bg-(--color-pearl) group-focus:before:bg-(--color-pearl)", p),
227
- ...S ? {} : { role: "presentation" },
226
+ className: l("relative inline-block px-20 py-12", "before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within/tab:before:bg-(--color-pearl) group-hover/tab:before:bg-(--color-pearl) group/tab-focus:before:bg-(--color-pearl)", p),
227
+ ...C ? {} : { role: "presentation" },
228
228
  children: [/* @__PURE__ */ m("span", {
229
229
  className: l("tab-focus-pill ease transition-transform/colors", "rounded-pill absolute inset-0 -z-1 duration-300", "bg-black"),
230
- style: C
231
- }), n ?? t]
230
+ style: w
231
+ }), /* @__PURE__ */ h("span", {
232
+ className: "flex items-center gap-8",
233
+ children: [n ?? t, g && /* @__PURE__ */ m("div", {
234
+ className: l("size-18 flex items-center justify-center text-b5 rounded-full bg-saffron text-black transition-colors duration-300", { "group-focus-within/tab:bg-darkGrey group-hover/tab:bg-darkGrey group-focus-within/tab:text-pearl group-hover/tab:text-pearl": !C.current }),
235
+ children: g
236
+ })]
237
+ })]
232
238
  })
233
239
  });
234
240
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.js","names":[],"sources":["../../../lib/ui/tabs/Tabs.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type CSSProperties,\n type FunctionComponent,\n type PropsWithChildren,\n type RefObject,\n type KeyboardEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { TabsProvider } from '../contexts/TabControl';\nimport {\n useActiveTab,\n useActiveTabControl,\n useRegisterTabControl,\n useTabDispatch,\n useTabsUid,\n} from '../hooks/tabControl';\nimport { useKeyboardControls } from '../hooks/useKeyboardControls';\nimport { Select } from '../forms/Select';\nimport { cn } from '../helpers/cn';\nimport { ArrowButton } from '../buttons/ArrowButton';\n\ntype ProviderProps = ComponentProps<typeof TabsProvider>;\n\ninterface Props extends ProviderProps {\n className?: string;\n /**\n * Shrink the spacing between tabs and panels\n */\n compacted?: boolean;\n}\n\nexport const Tabs: FunctionComponent<PropsWithChildren<Props>> = ({\n className,\n compacted = false,\n selected,\n children,\n}) => {\n return (\n <div\n className={cn(\n 'flex flex-col',\n {\n 'sm:gap-y-20': !compacted,\n },\n className,\n )}\n data-name=\"Tabs\"\n >\n <TabsProvider selected={selected}>{children}</TabsProvider>\n </div>\n );\n};\n\ninterface TabsBodyProps {\n className?: string;\n}\n\nexport const TabsBody: FunctionComponent<PropsWithChildren<TabsBodyProps>> = ({\n className,\n children,\n}) => {\n return (\n <div data-name=\"TabsBody\" className={cn('grid grid-rows-1 overflow-hidden', className)}>\n {children}\n </div>\n );\n};\n\ninterface TabPanelProps {\n className?: string;\n /**\n * Tab panel index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on panel select handler\n */\n onSelect?: (context: { value: TabPanelProps['value'] }) => void;\n}\n\nexport const TabPanel: FunctionComponent<PropsWithChildren<TabPanelProps>> = ({\n value,\n className,\n onSelect,\n children,\n ...attrs\n}) => {\n const uid = useTabsUid();\n const mounted = useRef(false);\n const tabSelected = useActiveTab();\n const isActive = tabSelected === value;\n\n useEffect(() => {\n if (!mounted.current) {\n mounted.current = true;\n return;\n }\n\n if (isActive) {\n onSelect?.({ value });\n }\n }, [isActive, value, onSelect]);\n\n return (\n <div\n {...attrs}\n aria-hidden={!isActive}\n className={cn(\n 'relative col-start-1 row-start-1 transition-opacity duration-500',\n {\n 'pointer-events-none z-0 h-0 opacity-0': !isActive,\n 'pointer-events-auto z-1 h-auto opacity-100': isActive,\n },\n className,\n )}\n inert={isActive ? undefined : true}\n tabIndex={isActive ? 0 : -1}\n id={`TabPanel_${value}_${uid}`}\n data-name={`TabPanel_${value}`}\n role=\"tabpanel\"\n aria-labelledby={`Tab_${value}_${uid}`}\n >\n {children}\n </div>\n );\n};\n\ninterface TabListProps {\n className?: string;\n /**\n * Remove filler placeholders\n */\n constrained?: boolean;\n}\n\nexport const TabList: FunctionComponent<PropsWithChildren<TabListProps>> = ({\n className,\n constrained = false,\n children,\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const spacerRef = useRef<HTMLDivElement>(null);\n const [currentTab, currentControl] = useActiveTabControl();\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const updateScrollState = useCallback(() => {\n const el = ref.current;\n if (!el) return;\n setCanScrollLeft(el.scrollLeft > 0);\n setCanScrollRight(Math.ceil(el.scrollLeft) < el.scrollWidth - el.clientWidth);\n }, []);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n updateScrollState();\n\n const observer = new ResizeObserver(updateScrollState);\n observer.observe(el);\n el.addEventListener('scroll', updateScrollState, { passive: true });\n\n return () => {\n observer.disconnect();\n el.removeEventListener('scroll', updateScrollState);\n };\n }, [updateScrollState]);\n\n useEffect(() => {\n if (!currentControl?.current || !ref.current) {\n return;\n }\n\n const spacerWidth = spacerRef.current!.offsetWidth ?? 0;\n const currentRect = currentControl.current.getBoundingClientRect();\n const containerRect = ref.current!.getBoundingClientRect();\n\n ref.current.scrollBy({\n left: currentRect.left - containerRect.left - spacerWidth,\n behavior: 'smooth',\n });\n }, [currentControl]);\n\n const scrollRafRef = useRef<number | null>(null);\n\n const stopScroll = useCallback(() => {\n if (scrollRafRef.current !== null) {\n cancelAnimationFrame(scrollRafRef.current);\n scrollRafRef.current = null;\n }\n }, []);\n\n const startScroll = useCallback((direction: -1 | 1) => {\n if (scrollRafRef.current !== null) return;\n const step = () => {\n ref.current?.scrollBy({ left: direction * 6 });\n scrollRafRef.current = requestAnimationFrame(step);\n };\n scrollRafRef.current = requestAnimationFrame(step);\n }, []);\n\n const handleScrollKeyUp = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') stopScroll();\n },\n [stopScroll],\n );\n\n const handleScrollLeftKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(-1);\n }\n },\n [startScroll],\n );\n\n const handleScrollRightKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(1);\n }\n },\n [startScroll],\n );\n\n useEffect(() => stopScroll, [stopScroll]);\n\n const style = { '--active-tab': currentTab } as CSSProperties;\n const isScrollable = canScrollLeft || canScrollRight;\n\n return (\n <div className=\"relative\" data-name=\"TabsHeader\">\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultLeft\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-8 focus-visible:ring-lavender/20',\n canScrollLeft ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(-1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollLeftKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollLeft}\n tabIndex={canScrollLeft ? 0 : -1}\n >\n Scroll tabs left\n </ArrowButton>\n </div>\n )}\n <div\n className={cn(\n 'scrollbar-hidden relative isolate flex max-w-full overflow-x-auto py-20',\n className,\n )}\n ref={ref}\n >\n <div role=\"tablist\" className=\"flex flex-row\" style={style}>\n <div\n ref={spacerRef}\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n {children}\n <div\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n </div>\n </div>\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 right-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultRight\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-8 focus-visible:ring-lavender/20',\n canScrollRight ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollRightKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollRight}\n tabIndex={canScrollRight ? 0 : -1}\n >\n Scroll tabs right\n </ArrowButton>\n </div>\n )}\n </div>\n );\n};\n\nexport interface TabSelectProps {\n items: { label: string; value: number }[];\n className?: string;\n 'aria-label'?: string;\n}\n\nexport const TabSelect: FunctionComponent<TabSelectProps> = ({\n items,\n className,\n 'aria-label': ariaLabel = 'Select tab',\n}) => {\n const activeTab = useActiveTab();\n const dispatch = useTabDispatch();\n\n const handleChange = (_event: Event, value: string) => {\n dispatch({ type: 'update', payload: Number(value) });\n };\n\n const selectValue = activeTab === -1 ? undefined : activeTab;\n\n return (\n <Select\n value={selectValue?.toString()}\n onChange={handleChange}\n name={ariaLabel}\n className={cn(className)}\n >\n {items.map((item) => (\n <option key={item.value} value={item.value}>\n {item.label}\n </option>\n ))}\n </Select>\n );\n};\n\ninterface TabProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n /**\n * Tab Heading text\n */\n label?: string;\n /**\n * Tab heading index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on tab select handler\n */\n onSelect?: (context: { value: TabProps['value']; label: TabProps['label'] }) => void;\n /**\n * Heading type\n * _default: **h2**_\n */\n as?: 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5';\n}\n\nexport const Tab: FunctionComponent<PropsWithChildren<TabProps>> = ({\n as: TagName = 'h2',\n label,\n children,\n value,\n onSelect,\n className,\n ...attr\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const activeTab = useActiveTab();\n const uid = useTabsUid();\n const dispatch = useRegisterTabControl({ value, ref: ref as RefObject<HTMLDivElement> });\n const previousActiveTab = useRef(activeTab);\n\n const isActive = useRef(activeTab === value);\n isActive.current = activeTab === value;\n\n const pillStyle = { '--tab-index': value } as CSSProperties;\n\n useEffect(() => {\n if (previousActiveTab.current !== activeTab && value === activeTab) {\n ref.current?.focus();\n onSelect?.({ value, label });\n }\n if (previousActiveTab.current !== activeTab) {\n previousActiveTab.current = activeTab;\n }\n }, [label, value, onSelect, activeTab]);\n\n const start = useCallback(() => {\n dispatch({ type: 'start' });\n }, [dispatch]);\n\n const end = useCallback(() => {\n dispatch({ type: 'end' });\n }, [dispatch]);\n\n const up = useCallback(() => {\n dispatch({ type: 'previous' });\n }, [dispatch]);\n\n const down = useCallback(() => {\n dispatch({ type: 'next' });\n }, [dispatch]);\n\n const left = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'next' : 'previous' });\n }, [dispatch]);\n\n const right = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'previous' : 'next' });\n }, [dispatch]);\n\n const keyboardHandler = useKeyboardControls({\n start,\n end,\n up,\n down,\n left,\n right,\n });\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.code === 'Space';\n const isEnter = e.key === 'Enter' || e.code === 'Enter';\n\n if (isActive.current && (isSpace || isEnter)) {\n e.preventDefault();\n return;\n }\n\n keyboardHandler(e);\n },\n [keyboardHandler],\n );\n\n const handleClick = () => {\n if (isActive.current) {\n return;\n }\n\n dispatch({ type: 'update', payload: value });\n };\n\n return (\n <div\n {...attr}\n id={attr.id || `Tab_${value}_${uid}`}\n data-name=\"Tab\"\n ref={ref}\n role=\"tab\"\n aria-selected={isActive.current}\n aria-controls={`TabPanel_${value}_${uid}`}\n tabIndex={isActive.current ? 0 : -1}\n className={cn(\n 'group text-b3 inline-block cursor-pointer overflow-hidden bg-transparent pe-4 align-middle font-semibold whitespace-nowrap outline-none',\n {\n 'text-white': isActive.current,\n 'text-black': !isActive.current,\n 'transition-transform active:scale-[1.03]': isActive.current,\n },\n )}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n >\n <TagName\n className={cn(\n 'relative inline-block px-20 py-12',\n 'before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within:before:bg-(--color-pearl) group-hover:before:bg-(--color-pearl) group-focus:before:bg-(--color-pearl)',\n className,\n )}\n {...(!isActive ? { role: 'presentation' } : {})}\n >\n <span\n className={cn(\n 'tab-focus-pill ease transition-transform/colors',\n 'rounded-pill absolute inset-0 -z-1 duration-300',\n 'bg-black',\n )}\n style={pillStyle}\n />\n {children ?? label}\n </TagName>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"Tabs.js","names":[],"sources":["../../../lib/ui/tabs/Tabs.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type CSSProperties,\n type FunctionComponent,\n type PropsWithChildren,\n type RefObject,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { TabsProvider } from '../contexts/TabControl';\nimport {\n useActiveTab,\n useActiveTabControl,\n useRegisterTabControl,\n useTabDispatch,\n useTabsUid,\n} from '../hooks/tabControl';\nimport { useKeyboardControls } from '../hooks/useKeyboardControls';\nimport { Select } from '../forms/Select';\nimport { cn } from '../helpers/cn';\nimport { ArrowButton } from '../buttons/ArrowButton';\n\ntype ProviderProps = ComponentProps<typeof TabsProvider>;\n\ninterface Props extends ProviderProps {\n className?: string;\n /**\n * Shrink the spacing between tabs and panels\n */\n compacted?: boolean;\n}\n\nexport const Tabs: FunctionComponent<PropsWithChildren<Props>> = ({\n className,\n compacted = false,\n selected,\n children,\n}) => {\n return (\n <div\n className={cn(\n 'flex flex-col',\n {\n 'sm:gap-y-20': !compacted,\n },\n className,\n )}\n data-name=\"Tabs\"\n >\n <TabsProvider selected={selected}>{children}</TabsProvider>\n </div>\n );\n};\n\ninterface TabsBodyProps {\n className?: string;\n}\n\nexport const TabsBody: FunctionComponent<PropsWithChildren<TabsBodyProps>> = ({\n className,\n children,\n}) => {\n return (\n <div data-name=\"TabsBody\" className={cn('grid grid-rows-1 overflow-hidden', className)}>\n {children}\n </div>\n );\n};\n\ninterface TabPanelProps {\n className?: string;\n /**\n * Tab panel index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on panel select handler\n */\n onSelect?: (context: { value: TabPanelProps['value'] }) => void;\n}\n\nexport const TabPanel: FunctionComponent<PropsWithChildren<TabPanelProps>> = ({\n value,\n className,\n onSelect,\n children,\n ...attrs\n}) => {\n const uid = useTabsUid();\n const mounted = useRef(false);\n const tabSelected = useActiveTab();\n const isActive = tabSelected === value;\n\n useEffect(() => {\n if (!mounted.current) {\n mounted.current = true;\n return;\n }\n\n if (isActive) {\n onSelect?.({ value });\n }\n }, [isActive, value, onSelect]);\n\n return (\n <div\n {...attrs}\n aria-hidden={!isActive}\n className={cn(\n 'relative col-start-1 row-start-1 transition-opacity duration-500',\n {\n 'pointer-events-none z-0 h-0 opacity-0': !isActive,\n 'pointer-events-auto z-1 h-auto opacity-100': isActive,\n },\n className,\n )}\n inert={isActive ? undefined : true}\n tabIndex={isActive ? 0 : -1}\n id={`TabPanel_${value}_${uid}`}\n data-name={`TabPanel_${value}`}\n role=\"tabpanel\"\n aria-labelledby={`Tab_${value}_${uid}`}\n >\n {children}\n </div>\n );\n};\n\ninterface TabListProps {\n className?: string;\n /**\n * Remove filler placeholders\n */\n constrained?: boolean;\n}\n\nexport const TabList: FunctionComponent<PropsWithChildren<TabListProps>> = ({\n className,\n constrained = false,\n children,\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const spacerRef = useRef<HTMLDivElement>(null);\n const [currentTab, currentControl] = useActiveTabControl();\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const updateScrollState = useCallback(() => {\n const el = ref.current;\n if (!el) return;\n setCanScrollLeft(el.scrollLeft > 0);\n setCanScrollRight(Math.ceil(el.scrollLeft) < el.scrollWidth - el.clientWidth);\n }, []);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n updateScrollState();\n\n const observer = new ResizeObserver(updateScrollState);\n observer.observe(el);\n el.addEventListener('scroll', updateScrollState, { passive: true });\n\n return () => {\n observer.disconnect();\n el.removeEventListener('scroll', updateScrollState);\n };\n }, [updateScrollState]);\n\n useEffect(() => {\n if (!currentControl?.current || !ref.current) {\n return;\n }\n\n const spacerWidth = spacerRef.current!.offsetWidth ?? 0;\n const currentRect = currentControl.current.getBoundingClientRect();\n const containerRect = ref.current!.getBoundingClientRect();\n\n ref.current.scrollBy({\n left: currentRect.left - containerRect.left - spacerWidth,\n behavior: 'smooth',\n });\n }, [currentControl]);\n\n const scrollRafRef = useRef<number | null>(null);\n\n const stopScroll = useCallback(() => {\n if (scrollRafRef.current !== null) {\n cancelAnimationFrame(scrollRafRef.current);\n scrollRafRef.current = null;\n }\n }, []);\n\n const startScroll = useCallback((direction: -1 | 1) => {\n if (scrollRafRef.current !== null) return;\n const step = () => {\n ref.current?.scrollBy({ left: direction * 6 });\n scrollRafRef.current = requestAnimationFrame(step);\n };\n scrollRafRef.current = requestAnimationFrame(step);\n }, []);\n\n const handleScrollKeyUp = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') stopScroll();\n },\n [stopScroll],\n );\n\n const handleScrollLeftKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(-1);\n }\n },\n [startScroll],\n );\n\n const handleScrollRightKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(1);\n }\n },\n [startScroll],\n );\n\n useEffect(() => stopScroll, [stopScroll]);\n\n const style = { '--active-tab': currentTab } as CSSProperties;\n const isScrollable = canScrollLeft || canScrollRight;\n\n return (\n <div className=\"relative\" data-name=\"TabsHeader\">\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultLeft\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-8 focus-visible:ring-lavender/20',\n canScrollLeft ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(-1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollLeftKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollLeft}\n tabIndex={canScrollLeft ? 0 : -1}\n >\n Scroll tabs left\n </ArrowButton>\n </div>\n )}\n <div\n className={cn(\n 'scrollbar-hidden relative isolate flex max-w-full overflow-x-auto py-20',\n className,\n )}\n ref={ref}\n >\n <div role=\"tablist\" className=\"flex flex-row\" style={style}>\n <div\n ref={spacerRef}\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n {children}\n <div\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n </div>\n </div>\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 right-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultRight\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-8 focus-visible:ring-lavender/20',\n canScrollRight ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollRightKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollRight}\n tabIndex={canScrollRight ? 0 : -1}\n >\n Scroll tabs right\n </ArrowButton>\n </div>\n )}\n </div>\n );\n};\n\nexport interface TabSelectProps {\n items: { label: string; value: number }[];\n className?: string;\n 'aria-label'?: string;\n}\n\nexport const TabSelect: FunctionComponent<TabSelectProps> = ({\n items,\n className,\n 'aria-label': ariaLabel = 'Select tab',\n}) => {\n const activeTab = useActiveTab();\n const dispatch = useTabDispatch();\n\n const handleChange = (_event: Event, value: string) => {\n dispatch({ type: 'update', payload: Number(value) });\n };\n\n const selectValue = activeTab === -1 ? undefined : activeTab;\n\n return (\n <Select\n value={selectValue?.toString()}\n onChange={handleChange}\n name={ariaLabel}\n className={cn(className)}\n >\n {items.map((item) => (\n <option key={item.value} value={item.value}>\n {item.label}\n </option>\n ))}\n </Select>\n );\n};\n\ninterface TabProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n /**\n * Notification content\n */\n notification?: ReactNode;\n /**\n * Tab Heading text\n */\n label?: string;\n /**\n * Tab heading index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on tab select handler\n */\n onSelect?: (context: { value: TabProps['value']; label: TabProps['label'] }) => void;\n /**\n * Heading type\n * _default: **h2**_\n */\n as?: 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5';\n}\n\nexport const Tab: FunctionComponent<PropsWithChildren<TabProps>> = ({\n as: TagName = 'h2',\n label,\n children,\n value,\n onSelect,\n className,\n notification,\n ...attr\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const activeTab = useActiveTab();\n const uid = useTabsUid();\n const dispatch = useRegisterTabControl({ value, ref: ref as RefObject<HTMLDivElement> });\n const previousActiveTab = useRef(activeTab);\n\n const isActive = useRef(activeTab === value);\n isActive.current = activeTab === value;\n\n const pillStyle = { '--tab-index': value } as CSSProperties;\n\n useEffect(() => {\n if (previousActiveTab.current !== activeTab && value === activeTab) {\n ref.current?.focus();\n onSelect?.({ value, label });\n }\n if (previousActiveTab.current !== activeTab) {\n previousActiveTab.current = activeTab;\n }\n }, [label, value, onSelect, activeTab]);\n\n const start = useCallback(() => {\n dispatch({ type: 'start' });\n }, [dispatch]);\n\n const end = useCallback(() => {\n dispatch({ type: 'end' });\n }, [dispatch]);\n\n const up = useCallback(() => {\n dispatch({ type: 'previous' });\n }, [dispatch]);\n\n const down = useCallback(() => {\n dispatch({ type: 'next' });\n }, [dispatch]);\n\n const left = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'next' : 'previous' });\n }, [dispatch]);\n\n const right = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'previous' : 'next' });\n }, [dispatch]);\n\n const keyboardHandler = useKeyboardControls({\n start,\n end,\n up,\n down,\n left,\n right,\n });\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.code === 'Space';\n const isEnter = e.key === 'Enter' || e.code === 'Enter';\n\n if (isActive.current && (isSpace || isEnter)) {\n e.preventDefault();\n return;\n }\n\n keyboardHandler(e);\n },\n [keyboardHandler],\n );\n\n const handleClick = () => {\n if (isActive.current) {\n return;\n }\n\n dispatch({ type: 'update', payload: value });\n };\n\n return (\n <div\n {...attr}\n id={attr.id || `Tab_${value}_${uid}`}\n data-name=\"Tab\"\n ref={ref}\n role=\"tab\"\n aria-selected={isActive.current}\n aria-controls={`TabPanel_${value}_${uid}`}\n tabIndex={isActive.current ? 0 : -1}\n className={cn(\n 'group/tab text-b3 inline-block cursor-pointer overflow-hidden bg-transparent pe-4 align-middle font-semibold whitespace-nowrap outline-none',\n {\n 'text-white': isActive.current,\n 'text-black': !isActive.current,\n 'transition-transform active:scale-[1.03]': isActive.current,\n },\n )}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n >\n <TagName\n className={cn(\n 'relative inline-block px-20 py-12',\n 'before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within/tab:before:bg-(--color-pearl) group-hover/tab:before:bg-(--color-pearl) group/tab-focus:before:bg-(--color-pearl)',\n className,\n )}\n {...(!isActive ? { role: 'presentation' } : {})}\n >\n <span\n className={cn(\n 'tab-focus-pill ease transition-transform/colors',\n 'rounded-pill absolute inset-0 -z-1 duration-300',\n 'bg-black',\n )}\n style={pillStyle}\n />\n <span className=\"flex items-center gap-8\">\n {children ?? label}\n {notification && (\n <div\n className={cn(\n 'size-18 flex items-center justify-center text-b5 rounded-full bg-saffron text-black transition-colors duration-300',\n {\n 'group-focus-within/tab:bg-darkGrey group-hover/tab:bg-darkGrey group-focus-within/tab:text-pearl group-hover/tab:text-pearl':\n !isActive.current,\n },\n )}\n >\n {notification}\n </div>\n )}\n </span>\n </TagName>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AAwCA,IAAa,KAAqD,EAChE,cACA,eAAY,IACZ,aACA,kBAGE,kBAAC,OAAD;CACE,WAAW,EACT,iBACA,EACE,eAAe,CAAC,GACjB,EACD,EACD;CACD,aAAU;WAEV,kBAAC,GAAD;EAAwB;EAAW;EAAwB,CAAA;CACvD,CAAA,EAQG,KAAiE,EAC5E,cACA,kBAGE,kBAAC,OAAD;CAAK,aAAU;CAAW,WAAW,EAAG,oCAAoC,EAAU;CACnF;CACG,CAAA,EAiBG,KAAiE,EAC5E,UACA,cACA,aACA,aACA,GAAG,QACC;CACJ,IAAM,IAAM,GAAY,EAClB,IAAU,EAAO,GAAM,EAEvB,IADc,GAAc,KACD;AAajC,QAXA,QAAgB;AACd,MAAI,CAAC,EAAQ,SAAS;AACpB,KAAQ,UAAU;AAClB;;AAGF,EAAI,KACF,IAAW,EAAE,UAAO,CAAC;IAEtB;EAAC;EAAU;EAAO;EAAS,CAAC,EAG7B,kBAAC,OAAD;EACE,GAAI;EACJ,eAAa,CAAC;EACd,WAAW,EACT,oEACA;GACE,yCAAyC,CAAC;GAC1C,8CAA8C;GAC/C,EACD,EACD;EACD,OAAO,IAAW,KAAA,IAAY;EAC9B,UAAU,IAAW,IAAI;EACzB,IAAI,YAAY,EAAM,GAAG;EACzB,aAAW,YAAY;EACvB,MAAK;EACL,mBAAiB,OAAO,EAAM,GAAG;EAEhC;EACG,CAAA;GAYG,KAA+D,EAC1E,cACA,iBAAc,IACd,kBACI;CACJ,IAAM,IAAM,EAAuB,KAAK,EAClC,IAAY,EAAuB,KAAK,EACxC,CAAC,GAAY,KAAkB,GAAqB,EACpD,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAgB,KAAqB,EAAS,GAAM,EAErD,IAAoB,QAAkB;EAC1C,IAAM,IAAK,EAAI;AACV,QACL,EAAiB,EAAG,aAAa,EAAE,EACnC,EAAkB,KAAK,KAAK,EAAG,WAAW,GAAG,EAAG,cAAc,EAAG,YAAY;IAC5E,EAAE,CAAC;AAkBN,CAhBA,QAAgB;EACd,IAAM,IAAK,EAAI;AACf,MAAI,CAAC,EAAI;AAET,KAAmB;EAEnB,IAAM,IAAW,IAAI,eAAe,EAAkB;AAItD,SAHA,EAAS,QAAQ,EAAG,EACpB,EAAG,iBAAiB,UAAU,GAAmB,EAAE,SAAS,IAAM,CAAC,QAEtD;AAEX,GADA,EAAS,YAAY,EACrB,EAAG,oBAAoB,UAAU,EAAkB;;IAEpD,CAAC,EAAkB,CAAC,EAEvB,QAAgB;AACd,MAAI,CAAC,GAAgB,WAAW,CAAC,EAAI,QACnC;EAGF,IAAM,IAAc,EAAU,QAAS,eAAe,GAChD,IAAc,EAAe,QAAQ,uBAAuB,EAC5D,IAAgB,EAAI,QAAS,uBAAuB;AAE1D,IAAI,QAAQ,SAAS;GACnB,MAAM,EAAY,OAAO,EAAc,OAAO;GAC9C,UAAU;GACX,CAAC;IACD,CAAC,EAAe,CAAC;CAEpB,IAAM,IAAe,EAAsB,KAAK,EAE1C,IAAa,QAAkB;AACnC,EAAI,EAAa,YAAY,SAC3B,qBAAqB,EAAa,QAAQ,EAC1C,EAAa,UAAU;IAExB,EAAE,CAAC,EAEA,IAAc,GAAa,MAAsB;AACrD,MAAI,EAAa,YAAY,KAAM;EACnC,IAAM,UAAa;AAEjB,GADA,EAAI,SAAS,SAAS,EAAE,MAAM,IAAY,GAAG,CAAC,EAC9C,EAAa,UAAU,sBAAsB,EAAK;;AAEpD,IAAa,UAAU,sBAAsB,EAAK;IACjD,EAAE,CAAC,EAEA,IAAoB,GACvB,MAAwC;AACvC,GAAI,EAAE,QAAQ,OAAO,EAAE,QAAQ,YAAS,GAAY;IAEtD,CAAC,EAAW,CACb,EAEK,IAA0B,GAC7B,MAAwC;AACvC,GAAI,EAAE,QAAQ,OAAO,EAAE,QAAQ,aAC7B,EAAE,gBAAgB,EAClB,EAAY,GAAG;IAGnB,CAAC,EAAY,CACd,EAEK,IAA2B,GAC9B,MAAwC;AACvC,GAAI,EAAE,QAAQ,OAAO,EAAE,QAAQ,aAC7B,EAAE,gBAAgB,EAClB,EAAY,EAAE;IAGlB,CAAC,EAAY,CACd;AAED,SAAgB,GAAY,CAAC,EAAW,CAAC;CAEzC,IAAM,IAAQ,EAAE,gBAAgB,GAAY,EACtC,IAAe,KAAiB;AAEtC,QACE,kBAAC,OAAD;EAAK,WAAU;EAAW,aAAU;YAApC;GACG,KACC,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KACE,MAAK;KACL,MAAK;KACL,WAAW,EACT,2GACA,IAAgB,gBAAgB,gCACjC;KACD,mBAAmB,EAAY,GAAG;KAClC,WAAW;KACX,cAAc;KACd,WAAW;KACX,SAAS;KACT,OAAO,CAAC;KACR,UAAU,IAAgB,IAAI;eAC/B;KAEa,CAAA;IACV,CAAA;GAER,kBAAC,OAAD;IACE,WAAW,EACT,2EACA,EACD;IACI;cAEL,kBAAC,OAAD;KAAK,MAAK;KAAU,WAAU;KAAuB;eAArD;MACE,kBAAC,OAAD;OACE,KAAK;OACL,WAAW,EAAG,YAAY,EACxB,0FACE,CAAC,GACJ,CAAA;OACD,CAAA;MACD;MACD,kBAAC,OAAD,EACE,WAAW,EAAG,YAAY,EACxB,0FACE,CAAC,GACJ,CAAC,EACF,CAAA;;;IAEA,CAAA;GACL,KACC,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KACE,MAAK;KACL,MAAK;KACL,WAAW,EACT,2GACA,IAAiB,gBAAgB,gCAClC;KACD,mBAAmB,EAAY,EAAE;KACjC,WAAW;KACX,cAAc;KACd,WAAW;KACX,SAAS;KACT,OAAO,CAAC;KACR,UAAU,IAAiB,IAAI;eAChC;KAEa,CAAA;IACV,CAAA;;;GAYD,KAAgD,EAC3D,UACA,cACA,cAAc,IAAY,mBACtB;CACJ,IAAM,IAAY,GAAc,EAC1B,IAAW,GAAgB;AAQjC,QACE,kBAAC,GAAD;EACE,QAJgB,MAAc,KAAK,KAAA,IAAY,IAI3B,UAAU;EAC9B,WATkB,GAAe,MAAkB;AACrD,KAAS;IAAE,MAAM;IAAU,SAAS,OAAO,EAAA;IAAQ,CAAC;;EASlD,MAAM;EACN,WAAW,EAAG,EAAU;YAEvB,EAAM,KAAK,MACV,kBAAC,UAAD;GAAyB,OAAO,EAAK;aAClC,EAAK;GACC,EAFI,EAAK,MAET,CAAA;EAEJ,CAAA;GA6BA,KAAuD,EAClE,IAAI,IAAU,MACd,UACA,aACA,UACA,aACA,cACA,iBACA,GAAG,QACC;CACJ,IAAM,IAAM,EAAuB,KAAK,EAClC,IAAY,GAAc,EAC1B,IAAM,GAAY,EAClB,IAAW,EAAsB;EAAE;EAAY;EAAkC,CAAC,EAClF,IAAoB,EAAO,EAAU,EAErC,IAAW,EAAO,MAAc,EAAM;AAC5C,GAAS,UAAU,MAAc;CAEjC,IAAM,IAAY,EAAE,eAAe,GAAO;AAE1C,SAAgB;AAKd,EAJI,EAAkB,YAAY,KAAa,MAAU,MACvD,EAAI,SAAS,OAAO,EACpB,IAAW;GAAE;GAAO;GAAO,CAAC,GAE1B,EAAkB,YAAY,MAChC,EAAkB,UAAU;IAE7B;EAAC;EAAO;EAAO;EAAU;EAAU,CAAC;CA8BvC,IAAM,IAAkB,EAAoB;EAC1C,OA7BY,QAAkB;AAC9B,KAAS,EAAE,MAAM,SAAS,CAAC;KAC1B,CAAC,EAAS,CAAC;EA4BZ,KA1BU,QAAkB;AAC5B,KAAS,EAAE,MAAM,OAAO,CAAC;KACxB,CAAC,EAAS,CAAC;EAyBZ,IAvBS,QAAkB;AAC3B,KAAS,EAAE,MAAM,YAAY,CAAC;KAC7B,CAAC,EAAS,CAAC;EAsBZ,MApBW,QAAkB;AAC7B,KAAS,EAAE,MAAM,QAAQ,CAAC;KACzB,CAAC,EAAS,CAAC;EAmBZ,MAjBW,QAAkB;AAG7B,KAAS,EAAE,MAFG,SAAS,gBAAgB,QAAQ,QAEtB,SAAS,YAAY,CAAC;KAC9C,CAAC,EAAS,CAAC;EAcZ,OAZY,QAAkB;AAG9B,KAAS,EAAE,MAFG,SAAS,gBAAgB,QAAQ,QAEtB,aAAa,QAAQ,CAAC;KAC9C,CAAC,EAAS,CAAA;EASZ,CAAC,EAEI,IAAgB,GACnB,MAAqC;EACpC,IAAM,IAAU,EAAE,QAAQ,OAAO,EAAE,QAAQ,cAAc,EAAE,SAAS,SAC9D,IAAU,EAAE,QAAQ,WAAW,EAAE,SAAS;AAEhD,MAAI,EAAS,YAAY,KAAW,IAAU;AAC5C,KAAE,gBAAgB;AAClB;;AAGF,IAAgB,EAAE;IAEpB,CAAC,EAAgB,CAClB,EAEK,UAAoB;AACpB,IAAS,WAIb,EAAS;GAAE,MAAM;GAAU,SAAS;GAAO,CAAC;;AAG9C,QACE,kBAAC,OAAD;EACE,GAAI;EACJ,IAAI,EAAK,MAAM,OAAO,EAAM,GAAG;EAC/B,aAAU;EACL;EACL,MAAK;EACL,iBAAe,EAAS;EACxB,iBAAe,YAAY,EAAM,GAAG;EACpC,UAAU,EAAS,UAAU,IAAI;EACjC,WAAW,EACT,+IACA;GACE,cAAc,EAAS;GACvB,cAAc,CAAC,EAAS;GACxB,4CAA4C,EAAS;GACtD,CACF;EACD,WAAW;EACX,SAAS;YAET,kBAAC,GAAD;GACE,WAAW,EACT,qCACA,4PACA,EACD;GACD,GAAM,IAAsC,EAAE,GAA7B,EAAE,MAAM,gBAAgB;aAN3C,CAQE,kBAAC,QAAD;IACE,WAAW,EACT,mDACA,mDACA,WACD;IACD,OAAO;IACP,CAAA,EACF,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACG,KAAY,GACZ,KACC,kBAAC,OAAD;KACE,WAAW,EACT,sHACA,EACE,+HACE,CAAC,EAAS,SACb,CACF;eAEA;KACG,CAAA,CAAA;;;EAIR,CAAA"}