@loafmarkets/ui 0.1.1 → 0.1.3

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.
package/dist/index.mjs CHANGED
@@ -4275,7 +4275,7 @@ var PriceChange = at.span`
4275
4275
  gap: 0.35rem;
4276
4276
  color: ${(props) => props.$isPositive == null ? "var(--color-text-secondary, rgba(255, 255, 255, 0.6))" : props.$isPositive ? "var(--color-positive, #0ecb81)" : "var(--color-negative, #f6465d)"};
4277
4277
  `;
4278
- var TABS = [
4278
+ var DEFAULT_TABS = [
4279
4279
  { id: "portfolio", label: "Portfolio" },
4280
4280
  { id: "openOrders", label: "Open Orders" },
4281
4281
  { id: "tradeHistory", label: "Trade History" },
@@ -4370,12 +4370,29 @@ var formatPercent = (value, fractionDigits = 2) => {
4370
4370
  return `${value.toFixed(fractionDigits)}%`;
4371
4371
  };
4372
4372
  var YourOrders = o.forwardRef(
4373
- ({ className, title = "Portfolio Holdings (Demo)", orders, renderOrderActions, ...props }, ref) => {
4374
- const [activeTab, setActiveTab] = o.useState("portfolio");
4375
- const hasOrders = Array.isArray(orders) && orders.length > 0;
4376
- const renderPortfolio = () => {
4373
+ ({ className, title, orders, tabs, activeTabId, onTabChange, renderOrderActions, ...props }, ref) => {
4374
+ const [internalActiveTab, setInternalActiveTab] = o.useState(tabs?.[0]?.id ?? "portfolio");
4375
+ const effectiveActiveTabId = activeTabId ?? internalActiveTab;
4376
+ const handleTabChange = (tabId) => {
4377
+ if (onTabChange) {
4378
+ onTabChange(tabId);
4379
+ } else {
4380
+ setInternalActiveTab(tabId);
4381
+ }
4382
+ };
4383
+ const resolvedTabs = tabs ?? DEFAULT_TABS.map((t) => ({ ...t, orders: orders ?? [], emptyState: `No ${t.label.toLowerCase()} data available.` }));
4384
+ const activeTab = resolvedTabs.find((t) => t.id === effectiveActiveTabId) ?? resolvedTabs[0];
4385
+ const activeOrders = activeTab?.orders ?? orders ?? [];
4386
+ const displayTitle = title ?? activeTab?.title ?? activeTab?.label ?? "Portfolio Holdings";
4387
+ console.log("[YourOrders] tabs:", tabs?.map((t) => ({ id: t.id, ordersCount: t.orders?.length })));
4388
+ console.log("[YourOrders] activeTabId prop:", activeTabId);
4389
+ console.log("[YourOrders] effectiveActiveTabId:", effectiveActiveTabId);
4390
+ console.log("[YourOrders] activeTab:", activeTab?.id, "orders count:", activeOrders?.length);
4391
+ const hasOrders = Array.isArray(activeOrders) && activeOrders.length > 0;
4392
+ const emptyMessage = activeTab?.emptyState ?? "No holdings yet. Start trading to build your portfolio.";
4393
+ const renderOrders = () => {
4377
4394
  if (!hasOrders) {
4378
- return /* @__PURE__ */ jsx("div", { style: emptyStateStyle, children: "No holdings yet. Start trading to build your portfolio." });
4395
+ return /* @__PURE__ */ jsx("div", { style: emptyStateStyle, children: emptyMessage });
4379
4396
  }
4380
4397
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4381
4398
  /* @__PURE__ */ jsxs("div", { style: tableHeaderStyle, children: [
@@ -4386,7 +4403,7 @@ var YourOrders = o.forwardRef(
4386
4403
  /* @__PURE__ */ jsx("div", { style: tableHeaderCell, children: "Avg Price" }),
4387
4404
  /* @__PURE__ */ jsx("div", { style: tableHeaderCell, children: "P&L" })
4388
4405
  ] }),
4389
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.65rem" }, children: orders.map((order) => {
4406
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.65rem" }, children: activeOrders.map((order) => {
4390
4407
  const propertyName = order.asset;
4391
4408
  const holding = order.holdingLabel ?? `${order.amount.toLocaleString(void 0, {
4392
4409
  minimumFractionDigits: 0,
@@ -4479,24 +4496,7 @@ var YourOrders = o.forwardRef(
4479
4496
  }) })
4480
4497
  ] });
4481
4498
  };
4482
- const renderOtherTab = (label) => /* @__PURE__ */ jsx("div", { style: emptyStateStyle, children: `No ${label.toLowerCase()} data available.` });
4483
- let tabContent = null;
4484
- switch (activeTab) {
4485
- case "portfolio":
4486
- tabContent = renderPortfolio();
4487
- break;
4488
- case "openOrders":
4489
- tabContent = renderOtherTab("Open Orders");
4490
- break;
4491
- case "tradeHistory":
4492
- tabContent = renderOtherTab("Trade History");
4493
- break;
4494
- case "orderHistory":
4495
- tabContent = renderOtherTab("Order History");
4496
- break;
4497
- default:
4498
- tabContent = null;
4499
- }
4499
+ const tabContent = renderOrders();
4500
4500
  return /* @__PURE__ */ jsxs(
4501
4501
  "div",
4502
4502
  {
@@ -4505,14 +4505,14 @@ var YourOrders = o.forwardRef(
4505
4505
  className,
4506
4506
  ...props,
4507
4507
  children: [
4508
- /* @__PURE__ */ jsx("div", { style: headerStyle, children: /* @__PURE__ */ jsx("h3", { style: titleStyle, children: title }) }),
4509
- /* @__PURE__ */ jsx("div", { style: tabsRowStyle, children: TABS.map((tab) => {
4510
- const isActive = activeTab === tab.id;
4508
+ /* @__PURE__ */ jsx("div", { style: headerStyle, children: /* @__PURE__ */ jsx("h3", { style: titleStyle, children: displayTitle }) }),
4509
+ resolvedTabs.length > 1 && /* @__PURE__ */ jsx("div", { style: tabsRowStyle, children: resolvedTabs.map((tab) => {
4510
+ const isActive = effectiveActiveTabId === tab.id;
4511
4511
  return /* @__PURE__ */ jsxs(
4512
4512
  "button",
4513
4513
  {
4514
4514
  type: "button",
4515
- onClick: () => setActiveTab(tab.id),
4515
+ onClick: () => handleTabChange(tab.id),
4516
4516
  style: {
4517
4517
  ...tabButtonBase,
4518
4518
  color: isActive ? "#ffffff" : "rgba(255,255,255,0.55)",
@@ -4545,7 +4545,97 @@ var YourOrders = o.forwardRef(
4545
4545
  }
4546
4546
  );
4547
4547
  YourOrders.displayName = "YourOrders";
4548
- var defaultRanges = ["1D", "1W", "1M", "3M", "1Y"];
4548
+ var timeToDate = (time) => {
4549
+ if (typeof time === "number") {
4550
+ return new Date(time * 1e3);
4551
+ }
4552
+ if (typeof time === "object" && time !== null && "year" in time && "month" in time && "day" in time) {
4553
+ const { year, month, day } = time;
4554
+ return new Date(Date.UTC(year, month - 1, day));
4555
+ }
4556
+ return null;
4557
+ };
4558
+ var createTickFormatter = (formatOptions) => {
4559
+ return (time, _tickMarkType, locale) => {
4560
+ const date = timeToDate(time);
4561
+ if (!date) return "";
4562
+ return date.toLocaleString(locale || void 0, formatOptions);
4563
+ };
4564
+ };
4565
+ var getTimeScaleOptions = (range) => {
4566
+ switch (range) {
4567
+ case "15m":
4568
+ return {
4569
+ timeVisible: true,
4570
+ secondsVisible: false,
4571
+ borderColor: "rgba(255,255,255,0.06)",
4572
+ tickMarkFormatter: createTickFormatter({ hour: "2-digit", minute: "2-digit" })
4573
+ };
4574
+ case "1h":
4575
+ return {
4576
+ timeVisible: true,
4577
+ secondsVisible: false,
4578
+ borderColor: "rgba(255,255,255,0.06)",
4579
+ tickMarkFormatter: createTickFormatter({ hour: "2-digit", minute: "2-digit" })
4580
+ };
4581
+ case "4h":
4582
+ return {
4583
+ timeVisible: true,
4584
+ secondsVisible: false,
4585
+ borderColor: "rgba(255,255,255,0.06)",
4586
+ tickMarkFormatter: createTickFormatter({ weekday: "short", hour: "2-digit" })
4587
+ };
4588
+ case "24h":
4589
+ return {
4590
+ timeVisible: true,
4591
+ secondsVisible: false,
4592
+ borderColor: "rgba(255,255,255,0.06)",
4593
+ tickMarkFormatter: createTickFormatter({ month: "short", day: "numeric" })
4594
+ };
4595
+ case "1W":
4596
+ return {
4597
+ timeVisible: true,
4598
+ secondsVisible: false,
4599
+ borderColor: "rgba(255,255,255,0.06)",
4600
+ tickMarkFormatter: createTickFormatter({ month: "short", day: "numeric" })
4601
+ };
4602
+ case "1M":
4603
+ return {
4604
+ timeVisible: true,
4605
+ secondsVisible: false,
4606
+ borderColor: "rgba(255,255,255,0.06)",
4607
+ tickMarkFormatter: createTickFormatter({ month: "short", year: "2-digit" })
4608
+ };
4609
+ default:
4610
+ return {
4611
+ timeVisible: true,
4612
+ secondsVisible: false,
4613
+ borderColor: "rgba(255,255,255,0.06)"
4614
+ };
4615
+ }
4616
+ };
4617
+ var getPriceScaleOptions = (data) => {
4618
+ if (!data.length) return {
4619
+ borderColor: "rgba(230, 200, 126, 0.25)",
4620
+ textColor: "rgba(230, 200, 126, 0.7)"
4621
+ };
4622
+ const prices = data.flatMap((d2) => [d2.open, d2.high, d2.low, d2.close]);
4623
+ const minPrice = Math.min(...prices);
4624
+ const maxPrice = Math.max(...prices);
4625
+ const priceRange = maxPrice - minPrice;
4626
+ let scaleMargins = { top: 0.1, bottom: 0.1 };
4627
+ if (priceRange < 1) {
4628
+ scaleMargins = { top: 0.2, bottom: 0.2 };
4629
+ } else if (priceRange > 1e3) {
4630
+ scaleMargins = { top: 0.05, bottom: 0.05 };
4631
+ }
4632
+ return {
4633
+ borderColor: "rgba(230, 200, 126, 0.25)",
4634
+ textColor: "rgba(230, 200, 126, 0.7)",
4635
+ scaleMargins
4636
+ };
4637
+ };
4638
+ var defaultRanges = ["15m", "1h", "4h", "24h", "1W", "1M"];
4549
4639
  var formatPrice = (value, currencySymbol) => {
4550
4640
  return `${currencySymbol}${value.toLocaleString(void 0, {
4551
4641
  minimumFractionDigits: 2,
@@ -4614,15 +4704,8 @@ var PriceChart = o.forwardRef(
4614
4704
  vertLines: { color: "rgba(255,255,255,0.06)" },
4615
4705
  horzLines: { color: "rgba(255,255,255,0.06)" }
4616
4706
  },
4617
- rightPriceScale: {
4618
- borderColor: "rgba(230, 200, 126, 0.25)",
4619
- textColor: "rgba(230, 200, 126, 0.7)"
4620
- },
4621
- timeScale: {
4622
- borderColor: "rgba(255,255,255,0.06)",
4623
- timeVisible: true,
4624
- secondsVisible: false
4625
- },
4707
+ rightPriceScale: getPriceScaleOptions(data),
4708
+ timeScale: getTimeScaleOptions(selectedRange || defaultRanges[0]),
4626
4709
  crosshair: {
4627
4710
  vertLine: { color: "rgba(255,255,255,0.12)" },
4628
4711
  horzLine: { color: "rgba(255,255,255,0.12)" }
@@ -4643,11 +4726,22 @@ var PriceChart = o.forwardRef(
4643
4726
  chart.remove();
4644
4727
  };
4645
4728
  }, []);
4729
+ o.useEffect(() => {
4730
+ const chart = chartRef.current;
4731
+ if (!chart) return;
4732
+ const effectiveRange = selectedRange ?? ranges?.[0] ?? "1D";
4733
+ chart.applyOptions({
4734
+ timeScale: getTimeScaleOptions(effectiveRange)
4735
+ });
4736
+ }, [selectedRange, ranges]);
4646
4737
  o.useEffect(() => {
4647
4738
  const chart = chartRef.current;
4648
4739
  const series = seriesRef.current;
4649
4740
  if (!chart || !series) return;
4650
4741
  series.setData(data);
4742
+ chart.applyOptions({
4743
+ rightPriceScale: getPriceScaleOptions(data)
4744
+ });
4651
4745
  if (priceLineRef.current) {
4652
4746
  series.removePriceLine(priceLineRef.current);
4653
4747
  priceLineRef.current = null;
@@ -5118,243 +5212,99 @@ var PriceBlock2 = at.span`
5118
5212
  `;
5119
5213
  var PropertySubheader = o.forwardRef(
5120
5214
  ({ className, tabs, activeTabId, onTabChange, actions, ...props }, ref) => {
5121
- const tabRefs = o.useRef([]);
5122
- const tabsWrapperRef = o.useRef(null);
5123
- const scrollContainerRef = o.useRef(null);
5124
- const indicatorRef = o.useRef(null);
5125
- const [isMobile, setIsMobile] = o.useState(false);
5126
- const [tabScrollThumb, setTabScrollThumb] = o.useState({
5127
- widthPercent: 100,
5128
- leftPercent: 0,
5129
- scrollable: false
5130
- });
5131
- const actionContainerStyle = o.useMemo(() => {
5132
- if (isMobile) {
5133
- return {
5134
- order: -1,
5135
- justifyContent: "center",
5136
- gap: "0.45rem",
5137
- flexWrap: "wrap"
5138
- };
5139
- }
5140
- return { order: 0 };
5141
- }, [isMobile]);
5142
- const actionButtonStyle = o.useMemo(() => {
5143
- if (isMobile) {
5144
- return { padding: "0.35rem 0.6rem", fontSize: "11px" };
5145
- }
5146
- return void 0;
5147
- }, [isMobile]);
5148
- const updateTabScrollThumb = o.useCallback(() => {
5149
- const container = scrollContainerRef.current;
5150
- if (!container) return;
5151
- const visibleWidth = container.clientWidth;
5152
- const totalWidth = container.scrollWidth;
5153
- if (totalWidth <= visibleWidth || visibleWidth === 0) {
5154
- setTabScrollThumb(
5155
- (prev2) => prev2.scrollable ? { widthPercent: 100, leftPercent: 0, scrollable: false } : prev2
5156
- );
5157
- return;
5158
- }
5159
- const widthPercent = visibleWidth / totalWidth * 100;
5160
- const maxScroll = Math.max(totalWidth - visibleWidth, 0);
5161
- const scrollRatio = maxScroll === 0 ? 0 : container.scrollLeft / maxScroll;
5162
- const usableTrack = Math.max(100 - widthPercent, 0);
5163
- const leftPercent = scrollRatio * usableTrack;
5164
- setTabScrollThumb({
5165
- widthPercent,
5166
- leftPercent,
5167
- scrollable: true
5168
- });
5169
- }, []);
5170
- const updateMobileIndicator = o.useCallback(() => {
5171
- if (typeof window === "undefined") return;
5172
- if (!indicatorRef.current || !tabsWrapperRef.current) return;
5173
- const isMobile2 = window.matchMedia("(max-width: 768px)").matches;
5174
- if (!isMobile2) {
5175
- indicatorRef.current.style.width = "0px";
5176
- indicatorRef.current.style.transform = "translateX(0)";
5177
- setTabScrollThumb(
5178
- (prev2) => prev2.scrollable ? { widthPercent: 100, leftPercent: 0, scrollable: false } : prev2
5179
- );
5180
- return;
5181
- }
5182
- const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);
5183
- if (activeIndex === -1) return;
5184
- const activeButton = tabRefs.current[activeIndex];
5185
- if (!activeButton) return;
5186
- const wrapperRect = tabsWrapperRef.current.getBoundingClientRect();
5187
- const buttonRect = activeButton.getBoundingClientRect();
5188
- const width = buttonRect.width;
5189
- const left = buttonRect.left - wrapperRect.left;
5190
- indicatorRef.current.style.width = `${width}px`;
5191
- indicatorRef.current.style.transform = `translateX(${left}px)`;
5192
- updateTabScrollThumb();
5193
- }, [activeTabId, tabs, updateTabScrollThumb]);
5194
- o.useEffect(() => {
5195
- updateMobileIndicator();
5196
- }, [updateMobileIndicator]);
5215
+ const tabsContainerRef = o.useRef(null);
5197
5216
  o.useEffect(() => {
5198
- if (typeof window === "undefined") return;
5199
- const handleResize = () => updateMobileIndicator();
5200
- window.addEventListener("resize", handleResize);
5201
- return () => window.removeEventListener("resize", handleResize);
5202
- }, [updateMobileIndicator]);
5203
- o.useEffect(() => {
5204
- const scrollEl = scrollContainerRef.current;
5205
- if (!scrollEl) return;
5206
- const handleScroll = () => {
5207
- updateMobileIndicator();
5208
- updateTabScrollThumb();
5217
+ const container = tabsContainerRef.current;
5218
+ if (!container) return;
5219
+ const isMobile = window.innerWidth <= 768;
5220
+ if (!isMobile) return;
5221
+ const forceScrollbar = () => {
5222
+ if (container.scrollWidth > container.clientWidth) {
5223
+ container.scrollTop = 1;
5224
+ container.scrollTop = 0;
5225
+ container.scrollLeft = 1;
5226
+ container.scrollLeft = 0;
5227
+ }
5209
5228
  };
5210
- scrollEl.addEventListener("scroll", handleScroll, { passive: true });
5211
- return () => scrollEl.removeEventListener("scroll", handleScroll);
5212
- }, [updateMobileIndicator, updateTabScrollThumb]);
5213
- o.useEffect(() => {
5214
- if (isMobile) {
5215
- updateTabScrollThumb();
5216
- }
5217
- }, [isMobile, updateTabScrollThumb, tabs.length]);
5218
- o.useEffect(() => {
5219
- if (typeof window === "undefined") return;
5220
- const media = window.matchMedia("(max-width: 768px)");
5221
- const setMatch = () => setIsMobile(media.matches);
5222
- setMatch();
5223
- media.addEventListener("change", setMatch);
5224
- return () => media.removeEventListener("change", setMatch);
5225
- }, []);
5229
+ setTimeout(forceScrollbar, 100);
5230
+ window.addEventListener("resize", forceScrollbar);
5231
+ return () => window.removeEventListener("resize", forceScrollbar);
5232
+ }, [tabs]);
5226
5233
  return /* @__PURE__ */ jsxs(
5227
5234
  "div",
5228
5235
  {
5229
5236
  ref,
5230
- className: cn("w-full font-normal flex flex-col gap-3 md:flex-row md:items-center md:justify-between", className),
5237
+ className: cn(
5238
+ "w-full font-normal",
5239
+ "flex flex-col-reverse gap-3",
5240
+ "md:flex-row md:items-center md:justify-between",
5241
+ className
5242
+ ),
5231
5243
  ...props,
5232
5244
  children: [
5233
- /* @__PURE__ */ jsxs(
5245
+ /* @__PURE__ */ jsx(
5234
5246
  "div",
5235
5247
  {
5236
- ref: tabsWrapperRef,
5248
+ ref: tabsContainerRef,
5237
5249
  className: cn(
5238
- "relative flex w-full min-w-0 flex-col",
5239
- "max-[768px]:gap-0",
5240
- "max-[768px]:order-0",
5241
- "md:flex-row md:items-center md:justify-between"
5250
+ "flex items-center border-b border-white/10",
5251
+ "overflow-x-auto md:overflow-visible",
5252
+ "[-webkit-overflow-scrolling:touch]",
5253
+ "[scroll-behavior:smooth]",
5254
+ "[touch-action:pan-x]",
5255
+ "md:border-b-0"
5242
5256
  ),
5243
- style: isMobile ? { gap: 0 } : void 0,
5244
- children: [
5245
- /* @__PURE__ */ jsx(
5246
- "div",
5257
+ style: { WebkitTapHighlightColor: "transparent" },
5258
+ children: /* @__PURE__ */ jsx("div", { className: "flex min-w-max", children: tabs.map((tab) => {
5259
+ const active = tab.id === activeTabId;
5260
+ return /* @__PURE__ */ jsxs(
5261
+ "button",
5247
5262
  {
5248
- ref: scrollContainerRef,
5263
+ type: "button",
5264
+ onClick: () => onTabChange?.(tab.id),
5249
5265
  className: cn(
5250
- "flex w-full min-w-0 items-center",
5251
- "overflow-x-auto md:overflow-visible",
5252
- "[-webkit-overflow-scrolling:touch]",
5253
- "[scrollbar-width:none]",
5254
- "[scroll-behavior:smooth]",
5255
- "[touch-action:pan-x]",
5256
- "md:border-b md:border-white/10"
5266
+ "relative whitespace-nowrap",
5267
+ "px-6 py-4",
5268
+ "font-normal",
5269
+ "transition-colors",
5270
+ "max-[768px]:px-[1.2rem] max-[768px]:py-[0.8rem]",
5271
+ "max-[480px]:px-4 max-[480px]:py-[0.7rem] max-[480px]:text-[0.9rem]",
5272
+ active ? "font-semibold text-[var(--color-accent,#e6c87e)]" : "text-white/60 hover:text-white"
5257
5273
  ),
5258
- style: { WebkitTapHighlightColor: "transparent" },
5259
- children: /* @__PURE__ */ jsx("div", { className: "flex min-w-max gap-2 lg:gap-4", children: tabs.map((tab, index) => {
5260
- const active = tab.id === activeTabId;
5261
- return /* @__PURE__ */ jsxs(
5262
- "button",
5263
- {
5264
- ref: (node2) => {
5265
- tabRefs.current[index] = node2;
5266
- },
5267
- type: "button",
5268
- onClick: () => onTabChange?.(tab.id),
5269
- className: cn(
5270
- "relative whitespace-nowrap",
5271
- "px-5 py-4 lg:px-6",
5272
- "text-[16px]",
5273
- "font-medium",
5274
- "transition-colors",
5275
- "max-[768px]:rounded-full max-[768px]:px-5 max-[768px]:py-3",
5276
- "max-[768px]:text-[15px]",
5277
- "max-[480px]:px-4 max-[480px]:py-[0.75rem] max-[480px]:text-sm",
5278
- active ? "font-semibold text-[var(--color-accent,#e6c87e)] hover:text-[var(--color-accent,#f1d27a)]" : "text-white/65 hover:text-white"
5279
- ),
5280
- style: {
5281
- borderBottom: active ? "2px solid var(--color-accent, #e6c87e)" : "2px solid transparent",
5282
- minWidth: "80px",
5283
- touchAction: "manipulation"
5284
- },
5285
- children: [
5286
- /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
5287
- tab.id === "trade" ? /* @__PURE__ */ jsx("span", { className: "hidden h-4 w-4 items-center justify-center rounded-full bg-white/10 text-[11px] text-[var(--color-accent,#e6c87e)] max-[768px]:inline-flex", children: "\u21C5" }) : null,
5288
- tab.label
5289
- ] }),
5290
- tab.hasNotification ? /* @__PURE__ */ jsx(
5291
- "span",
5292
- {
5293
- className: "absolute right-[10px] top-[10px] h-2 w-2 rounded-full animate-pulse",
5294
- style: {
5295
- backgroundColor: tab.notificationColor ?? "#f6465d",
5296
- boxShadow: "0 0 0 0 rgba(246, 70, 93, 0.7)"
5297
- }
5298
- }
5299
- ) : null
5300
- ]
5301
- },
5302
- tab.id
5303
- );
5304
- }) })
5305
- }
5306
- ),
5307
- /* @__PURE__ */ jsx("div", { className: "pointer-events-none relative hidden h-[3px] w-full min-w-0 overflow-hidden rounded-full bg-white/10 max-[768px]:block", style: { marginBottom: "1px" }, children: /* @__PURE__ */ jsx(
5308
- "span",
5309
- {
5310
- ref: indicatorRef,
5311
- className: "absolute left-0 top-0 block h-full rounded-full bg-[var(--color-accent,#e6c87e)] transition-all duration-300 ease-out"
5312
- }
5313
- ) }),
5314
- /* @__PURE__ */ jsx(
5315
- "div",
5316
- {
5317
5274
  style: {
5318
- display: isMobile ? "block" : "none",
5319
- height: "8px",
5320
- width: "100%",
5321
- borderRadius: "999px",
5322
- background: "rgba(18,19,22,0.85)",
5323
- marginTop: "0",
5324
- position: "relative"
5275
+ borderBottom: active ? "2px solid var(--color-accent, #e6c87e)" : "2px solid transparent",
5276
+ minWidth: "80px",
5277
+ touchAction: "manipulation"
5325
5278
  },
5326
- children: /* @__PURE__ */ jsx(
5327
- "div",
5328
- {
5329
- style: {
5330
- position: "absolute",
5331
- top: 0,
5332
- left: `${tabScrollThumb.leftPercent}%`,
5333
- height: "100%",
5334
- borderRadius: "999px",
5335
- background: "rgba(92,94,102,0.85)",
5336
- width: `${tabScrollThumb.widthPercent}%`,
5337
- transition: "left 0.2s ease-out, width 0.2s ease-out, opacity 0.2s ease-out",
5338
- opacity: tabScrollThumb.scrollable ? 1 : 0.25
5279
+ children: [
5280
+ tab.label,
5281
+ tab.hasNotification ? /* @__PURE__ */ jsx(
5282
+ "span",
5283
+ {
5284
+ className: "absolute right-[10px] top-[10px] h-2 w-2 rounded-full animate-pulse",
5285
+ style: {
5286
+ backgroundColor: tab.notificationColor ?? "#f6465d",
5287
+ boxShadow: "0 0 0 0 rgba(246, 70, 93, 0.7)"
5288
+ }
5339
5289
  }
5340
- }
5341
- )
5342
- }
5343
- )
5344
- ]
5290
+ ) : null
5291
+ ]
5292
+ },
5293
+ tab.id
5294
+ );
5295
+ }) })
5345
5296
  }
5346
5297
  ),
5347
5298
  actions != null && actions.length > 0 ? /* @__PURE__ */ jsx(
5348
5299
  "div",
5349
5300
  {
5350
5301
  className: cn(
5351
- "flex items-center gap-[4px] md:gap-[10px]",
5352
- "justify-center md:justify-end",
5302
+ "flex items-center gap-[10px]",
5353
5303
  "overflow-x-auto md:overflow-visible",
5354
5304
  "[scrollbar-width:none]",
5355
- "max-[768px]:w-full max-[768px]:pb-2 max-[768px]:mb-2"
5305
+ "md:justify-end",
5306
+ "max-[768px]:w-full max-[768px]:justify-center max-[768px]:pb-2 max-[768px]:mb-4"
5356
5307
  ),
5357
- style: actionContainerStyle,
5358
5308
  children: actions.map((action) => /* @__PURE__ */ jsxs(
5359
5309
  "button",
5360
5310
  {
@@ -5362,14 +5312,14 @@ var PropertySubheader = o.forwardRef(
5362
5312
  onClick: action.onClick,
5363
5313
  className: cn(
5364
5314
  "flex shrink-0 items-center gap-[5px] whitespace-nowrap",
5365
- "rounded-[6px]",
5366
- "border border-white/15",
5315
+ "rounded",
5316
+ "border border-white/10",
5367
5317
  "bg-transparent",
5368
- "px-3.5 py-1.5 text-[14px] font-medium",
5318
+ "px-3 py-1.5 text-[14px] font-normal",
5369
5319
  "transition-all",
5320
+ "max-[768px]:px-2.5 max-[768px]:py-[5px] max-[768px]:text-[13px]",
5370
5321
  "hover:bg-white/5 hover:border-[var(--color-accent,#e6c87e)] hover:text-[var(--color-accent,#e6c87e)]"
5371
5322
  ),
5372
- style: actionButtonStyle,
5373
5323
  children: [
5374
5324
  action.icon,
5375
5325
  action.label