@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.d.mts CHANGED
@@ -255,18 +255,32 @@ type YourOrder = {
255
255
  priceChangePercent?: number;
256
256
  priceChangePositive?: boolean;
257
257
  };
258
- type YourOrdersProps = React.HTMLAttributes<HTMLDivElement> & {
258
+ type YourOrdersTab = {
259
+ id: string;
260
+ label: string;
259
261
  title?: string;
260
262
  orders: YourOrder[];
263
+ emptyState?: string;
264
+ enableCancel?: boolean;
265
+ };
266
+ type YourOrdersProps = React.HTMLAttributes<HTMLDivElement> & {
267
+ title?: string;
268
+ orders?: YourOrder[];
269
+ tabs?: YourOrdersTab[];
270
+ activeTabId?: string;
271
+ onTabChange?: (tabId: string) => void;
261
272
  renderOrderActions?: (order: YourOrder) => React.ReactNode;
262
273
  };
263
274
  declare const YourOrders: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
264
275
  title?: string;
265
- orders: YourOrder[];
276
+ orders?: YourOrder[];
277
+ tabs?: YourOrdersTab[];
278
+ activeTabId?: string;
279
+ onTabChange?: (tabId: string) => void;
266
280
  renderOrderActions?: (order: YourOrder) => React.ReactNode;
267
281
  } & React.RefAttributes<HTMLDivElement>>;
268
282
 
269
- type PriceChartRange = "1D" | "1W" | "1M" | "3M" | "1Y";
283
+ type PriceChartRange = "15m" | "1h" | "4h" | "24h" | "1W" | "1M";
270
284
  type PriceChartCandle = {
271
285
  time: LightweightCharts.Time;
272
286
  open: number;
package/dist/index.d.ts CHANGED
@@ -255,18 +255,32 @@ type YourOrder = {
255
255
  priceChangePercent?: number;
256
256
  priceChangePositive?: boolean;
257
257
  };
258
- type YourOrdersProps = React.HTMLAttributes<HTMLDivElement> & {
258
+ type YourOrdersTab = {
259
+ id: string;
260
+ label: string;
259
261
  title?: string;
260
262
  orders: YourOrder[];
263
+ emptyState?: string;
264
+ enableCancel?: boolean;
265
+ };
266
+ type YourOrdersProps = React.HTMLAttributes<HTMLDivElement> & {
267
+ title?: string;
268
+ orders?: YourOrder[];
269
+ tabs?: YourOrdersTab[];
270
+ activeTabId?: string;
271
+ onTabChange?: (tabId: string) => void;
261
272
  renderOrderActions?: (order: YourOrder) => React.ReactNode;
262
273
  };
263
274
  declare const YourOrders: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
264
275
  title?: string;
265
- orders: YourOrder[];
276
+ orders?: YourOrder[];
277
+ tabs?: YourOrdersTab[];
278
+ activeTabId?: string;
279
+ onTabChange?: (tabId: string) => void;
266
280
  renderOrderActions?: (order: YourOrder) => React.ReactNode;
267
281
  } & React.RefAttributes<HTMLDivElement>>;
268
282
 
269
- type PriceChartRange = "1D" | "1W" | "1M" | "3M" | "1Y";
283
+ type PriceChartRange = "15m" | "1h" | "4h" | "24h" | "1W" | "1M";
270
284
  type PriceChartCandle = {
271
285
  time: LightweightCharts.Time;
272
286
  open: number;
package/dist/index.js CHANGED
@@ -4297,7 +4297,7 @@ var PriceChange = at.span`
4297
4297
  gap: 0.35rem;
4298
4298
  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)"};
4299
4299
  `;
4300
- var TABS = [
4300
+ var DEFAULT_TABS = [
4301
4301
  { id: "portfolio", label: "Portfolio" },
4302
4302
  { id: "openOrders", label: "Open Orders" },
4303
4303
  { id: "tradeHistory", label: "Trade History" },
@@ -4392,12 +4392,29 @@ var formatPercent = (value, fractionDigits = 2) => {
4392
4392
  return `${value.toFixed(fractionDigits)}%`;
4393
4393
  };
4394
4394
  var YourOrders = o__namespace.forwardRef(
4395
- ({ className, title = "Portfolio Holdings (Demo)", orders, renderOrderActions, ...props }, ref) => {
4396
- const [activeTab, setActiveTab] = o__namespace.useState("portfolio");
4397
- const hasOrders = Array.isArray(orders) && orders.length > 0;
4398
- const renderPortfolio = () => {
4395
+ ({ className, title, orders, tabs, activeTabId, onTabChange, renderOrderActions, ...props }, ref) => {
4396
+ const [internalActiveTab, setInternalActiveTab] = o__namespace.useState(tabs?.[0]?.id ?? "portfolio");
4397
+ const effectiveActiveTabId = activeTabId ?? internalActiveTab;
4398
+ const handleTabChange = (tabId) => {
4399
+ if (onTabChange) {
4400
+ onTabChange(tabId);
4401
+ } else {
4402
+ setInternalActiveTab(tabId);
4403
+ }
4404
+ };
4405
+ const resolvedTabs = tabs ?? DEFAULT_TABS.map((t) => ({ ...t, orders: orders ?? [], emptyState: `No ${t.label.toLowerCase()} data available.` }));
4406
+ const activeTab = resolvedTabs.find((t) => t.id === effectiveActiveTabId) ?? resolvedTabs[0];
4407
+ const activeOrders = activeTab?.orders ?? orders ?? [];
4408
+ const displayTitle = title ?? activeTab?.title ?? activeTab?.label ?? "Portfolio Holdings";
4409
+ console.log("[YourOrders] tabs:", tabs?.map((t) => ({ id: t.id, ordersCount: t.orders?.length })));
4410
+ console.log("[YourOrders] activeTabId prop:", activeTabId);
4411
+ console.log("[YourOrders] effectiveActiveTabId:", effectiveActiveTabId);
4412
+ console.log("[YourOrders] activeTab:", activeTab?.id, "orders count:", activeOrders?.length);
4413
+ const hasOrders = Array.isArray(activeOrders) && activeOrders.length > 0;
4414
+ const emptyMessage = activeTab?.emptyState ?? "No holdings yet. Start trading to build your portfolio.";
4415
+ const renderOrders = () => {
4399
4416
  if (!hasOrders) {
4400
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: emptyStateStyle, children: "No holdings yet. Start trading to build your portfolio." });
4417
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: emptyStateStyle, children: emptyMessage });
4401
4418
  }
4402
4419
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4403
4420
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tableHeaderStyle, children: [
@@ -4408,7 +4425,7 @@ var YourOrders = o__namespace.forwardRef(
4408
4425
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: tableHeaderCell, children: "Avg Price" }),
4409
4426
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: tableHeaderCell, children: "P&L" })
4410
4427
  ] }),
4411
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.65rem" }, children: orders.map((order) => {
4428
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.65rem" }, children: activeOrders.map((order) => {
4412
4429
  const propertyName = order.asset;
4413
4430
  const holding = order.holdingLabel ?? `${order.amount.toLocaleString(void 0, {
4414
4431
  minimumFractionDigits: 0,
@@ -4501,24 +4518,7 @@ var YourOrders = o__namespace.forwardRef(
4501
4518
  }) })
4502
4519
  ] });
4503
4520
  };
4504
- const renderOtherTab = (label) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: emptyStateStyle, children: `No ${label.toLowerCase()} data available.` });
4505
- let tabContent = null;
4506
- switch (activeTab) {
4507
- case "portfolio":
4508
- tabContent = renderPortfolio();
4509
- break;
4510
- case "openOrders":
4511
- tabContent = renderOtherTab("Open Orders");
4512
- break;
4513
- case "tradeHistory":
4514
- tabContent = renderOtherTab("Trade History");
4515
- break;
4516
- case "orderHistory":
4517
- tabContent = renderOtherTab("Order History");
4518
- break;
4519
- default:
4520
- tabContent = null;
4521
- }
4521
+ const tabContent = renderOrders();
4522
4522
  return /* @__PURE__ */ jsxRuntime.jsxs(
4523
4523
  "div",
4524
4524
  {
@@ -4527,14 +4527,14 @@ var YourOrders = o__namespace.forwardRef(
4527
4527
  className,
4528
4528
  ...props,
4529
4529
  children: [
4530
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: headerStyle, children: /* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyle, children: title }) }),
4531
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: tabsRowStyle, children: TABS.map((tab) => {
4532
- const isActive = activeTab === tab.id;
4530
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: headerStyle, children: /* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyle, children: displayTitle }) }),
4531
+ resolvedTabs.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: tabsRowStyle, children: resolvedTabs.map((tab) => {
4532
+ const isActive = effectiveActiveTabId === tab.id;
4533
4533
  return /* @__PURE__ */ jsxRuntime.jsxs(
4534
4534
  "button",
4535
4535
  {
4536
4536
  type: "button",
4537
- onClick: () => setActiveTab(tab.id),
4537
+ onClick: () => handleTabChange(tab.id),
4538
4538
  style: {
4539
4539
  ...tabButtonBase,
4540
4540
  color: isActive ? "#ffffff" : "rgba(255,255,255,0.55)",
@@ -4567,7 +4567,97 @@ var YourOrders = o__namespace.forwardRef(
4567
4567
  }
4568
4568
  );
4569
4569
  YourOrders.displayName = "YourOrders";
4570
- var defaultRanges = ["1D", "1W", "1M", "3M", "1Y"];
4570
+ var timeToDate = (time) => {
4571
+ if (typeof time === "number") {
4572
+ return new Date(time * 1e3);
4573
+ }
4574
+ if (typeof time === "object" && time !== null && "year" in time && "month" in time && "day" in time) {
4575
+ const { year, month, day } = time;
4576
+ return new Date(Date.UTC(year, month - 1, day));
4577
+ }
4578
+ return null;
4579
+ };
4580
+ var createTickFormatter = (formatOptions) => {
4581
+ return (time, _tickMarkType, locale) => {
4582
+ const date = timeToDate(time);
4583
+ if (!date) return "";
4584
+ return date.toLocaleString(locale || void 0, formatOptions);
4585
+ };
4586
+ };
4587
+ var getTimeScaleOptions = (range) => {
4588
+ switch (range) {
4589
+ case "15m":
4590
+ return {
4591
+ timeVisible: true,
4592
+ secondsVisible: false,
4593
+ borderColor: "rgba(255,255,255,0.06)",
4594
+ tickMarkFormatter: createTickFormatter({ hour: "2-digit", minute: "2-digit" })
4595
+ };
4596
+ case "1h":
4597
+ return {
4598
+ timeVisible: true,
4599
+ secondsVisible: false,
4600
+ borderColor: "rgba(255,255,255,0.06)",
4601
+ tickMarkFormatter: createTickFormatter({ hour: "2-digit", minute: "2-digit" })
4602
+ };
4603
+ case "4h":
4604
+ return {
4605
+ timeVisible: true,
4606
+ secondsVisible: false,
4607
+ borderColor: "rgba(255,255,255,0.06)",
4608
+ tickMarkFormatter: createTickFormatter({ weekday: "short", hour: "2-digit" })
4609
+ };
4610
+ case "24h":
4611
+ return {
4612
+ timeVisible: true,
4613
+ secondsVisible: false,
4614
+ borderColor: "rgba(255,255,255,0.06)",
4615
+ tickMarkFormatter: createTickFormatter({ month: "short", day: "numeric" })
4616
+ };
4617
+ case "1W":
4618
+ return {
4619
+ timeVisible: true,
4620
+ secondsVisible: false,
4621
+ borderColor: "rgba(255,255,255,0.06)",
4622
+ tickMarkFormatter: createTickFormatter({ month: "short", day: "numeric" })
4623
+ };
4624
+ case "1M":
4625
+ return {
4626
+ timeVisible: true,
4627
+ secondsVisible: false,
4628
+ borderColor: "rgba(255,255,255,0.06)",
4629
+ tickMarkFormatter: createTickFormatter({ month: "short", year: "2-digit" })
4630
+ };
4631
+ default:
4632
+ return {
4633
+ timeVisible: true,
4634
+ secondsVisible: false,
4635
+ borderColor: "rgba(255,255,255,0.06)"
4636
+ };
4637
+ }
4638
+ };
4639
+ var getPriceScaleOptions = (data) => {
4640
+ if (!data.length) return {
4641
+ borderColor: "rgba(230, 200, 126, 0.25)",
4642
+ textColor: "rgba(230, 200, 126, 0.7)"
4643
+ };
4644
+ const prices = data.flatMap((d2) => [d2.open, d2.high, d2.low, d2.close]);
4645
+ const minPrice = Math.min(...prices);
4646
+ const maxPrice = Math.max(...prices);
4647
+ const priceRange = maxPrice - minPrice;
4648
+ let scaleMargins = { top: 0.1, bottom: 0.1 };
4649
+ if (priceRange < 1) {
4650
+ scaleMargins = { top: 0.2, bottom: 0.2 };
4651
+ } else if (priceRange > 1e3) {
4652
+ scaleMargins = { top: 0.05, bottom: 0.05 };
4653
+ }
4654
+ return {
4655
+ borderColor: "rgba(230, 200, 126, 0.25)",
4656
+ textColor: "rgba(230, 200, 126, 0.7)",
4657
+ scaleMargins
4658
+ };
4659
+ };
4660
+ var defaultRanges = ["15m", "1h", "4h", "24h", "1W", "1M"];
4571
4661
  var formatPrice = (value, currencySymbol) => {
4572
4662
  return `${currencySymbol}${value.toLocaleString(void 0, {
4573
4663
  minimumFractionDigits: 2,
@@ -4636,15 +4726,8 @@ var PriceChart = o__namespace.forwardRef(
4636
4726
  vertLines: { color: "rgba(255,255,255,0.06)" },
4637
4727
  horzLines: { color: "rgba(255,255,255,0.06)" }
4638
4728
  },
4639
- rightPriceScale: {
4640
- borderColor: "rgba(230, 200, 126, 0.25)",
4641
- textColor: "rgba(230, 200, 126, 0.7)"
4642
- },
4643
- timeScale: {
4644
- borderColor: "rgba(255,255,255,0.06)",
4645
- timeVisible: true,
4646
- secondsVisible: false
4647
- },
4729
+ rightPriceScale: getPriceScaleOptions(data),
4730
+ timeScale: getTimeScaleOptions(selectedRange || defaultRanges[0]),
4648
4731
  crosshair: {
4649
4732
  vertLine: { color: "rgba(255,255,255,0.12)" },
4650
4733
  horzLine: { color: "rgba(255,255,255,0.12)" }
@@ -4665,11 +4748,22 @@ var PriceChart = o__namespace.forwardRef(
4665
4748
  chart.remove();
4666
4749
  };
4667
4750
  }, []);
4751
+ o__namespace.useEffect(() => {
4752
+ const chart = chartRef.current;
4753
+ if (!chart) return;
4754
+ const effectiveRange = selectedRange ?? ranges?.[0] ?? "1D";
4755
+ chart.applyOptions({
4756
+ timeScale: getTimeScaleOptions(effectiveRange)
4757
+ });
4758
+ }, [selectedRange, ranges]);
4668
4759
  o__namespace.useEffect(() => {
4669
4760
  const chart = chartRef.current;
4670
4761
  const series = seriesRef.current;
4671
4762
  if (!chart || !series) return;
4672
4763
  series.setData(data);
4764
+ chart.applyOptions({
4765
+ rightPriceScale: getPriceScaleOptions(data)
4766
+ });
4673
4767
  if (priceLineRef.current) {
4674
4768
  series.removePriceLine(priceLineRef.current);
4675
4769
  priceLineRef.current = null;
@@ -5140,243 +5234,99 @@ var PriceBlock2 = at.span`
5140
5234
  `;
5141
5235
  var PropertySubheader = o__namespace.forwardRef(
5142
5236
  ({ className, tabs, activeTabId, onTabChange, actions, ...props }, ref) => {
5143
- const tabRefs = o__namespace.useRef([]);
5144
- const tabsWrapperRef = o__namespace.useRef(null);
5145
- const scrollContainerRef = o__namespace.useRef(null);
5146
- const indicatorRef = o__namespace.useRef(null);
5147
- const [isMobile, setIsMobile] = o__namespace.useState(false);
5148
- const [tabScrollThumb, setTabScrollThumb] = o__namespace.useState({
5149
- widthPercent: 100,
5150
- leftPercent: 0,
5151
- scrollable: false
5152
- });
5153
- const actionContainerStyle = o__namespace.useMemo(() => {
5154
- if (isMobile) {
5155
- return {
5156
- order: -1,
5157
- justifyContent: "center",
5158
- gap: "0.45rem",
5159
- flexWrap: "wrap"
5160
- };
5161
- }
5162
- return { order: 0 };
5163
- }, [isMobile]);
5164
- const actionButtonStyle = o__namespace.useMemo(() => {
5165
- if (isMobile) {
5166
- return { padding: "0.35rem 0.6rem", fontSize: "11px" };
5167
- }
5168
- return void 0;
5169
- }, [isMobile]);
5170
- const updateTabScrollThumb = o__namespace.useCallback(() => {
5171
- const container = scrollContainerRef.current;
5172
- if (!container) return;
5173
- const visibleWidth = container.clientWidth;
5174
- const totalWidth = container.scrollWidth;
5175
- if (totalWidth <= visibleWidth || visibleWidth === 0) {
5176
- setTabScrollThumb(
5177
- (prev2) => prev2.scrollable ? { widthPercent: 100, leftPercent: 0, scrollable: false } : prev2
5178
- );
5179
- return;
5180
- }
5181
- const widthPercent = visibleWidth / totalWidth * 100;
5182
- const maxScroll = Math.max(totalWidth - visibleWidth, 0);
5183
- const scrollRatio = maxScroll === 0 ? 0 : container.scrollLeft / maxScroll;
5184
- const usableTrack = Math.max(100 - widthPercent, 0);
5185
- const leftPercent = scrollRatio * usableTrack;
5186
- setTabScrollThumb({
5187
- widthPercent,
5188
- leftPercent,
5189
- scrollable: true
5190
- });
5191
- }, []);
5192
- const updateMobileIndicator = o__namespace.useCallback(() => {
5193
- if (typeof window === "undefined") return;
5194
- if (!indicatorRef.current || !tabsWrapperRef.current) return;
5195
- const isMobile2 = window.matchMedia("(max-width: 768px)").matches;
5196
- if (!isMobile2) {
5197
- indicatorRef.current.style.width = "0px";
5198
- indicatorRef.current.style.transform = "translateX(0)";
5199
- setTabScrollThumb(
5200
- (prev2) => prev2.scrollable ? { widthPercent: 100, leftPercent: 0, scrollable: false } : prev2
5201
- );
5202
- return;
5203
- }
5204
- const activeIndex = tabs.findIndex((tab) => tab.id === activeTabId);
5205
- if (activeIndex === -1) return;
5206
- const activeButton = tabRefs.current[activeIndex];
5207
- if (!activeButton) return;
5208
- const wrapperRect = tabsWrapperRef.current.getBoundingClientRect();
5209
- const buttonRect = activeButton.getBoundingClientRect();
5210
- const width = buttonRect.width;
5211
- const left = buttonRect.left - wrapperRect.left;
5212
- indicatorRef.current.style.width = `${width}px`;
5213
- indicatorRef.current.style.transform = `translateX(${left}px)`;
5214
- updateTabScrollThumb();
5215
- }, [activeTabId, tabs, updateTabScrollThumb]);
5216
- o__namespace.useEffect(() => {
5217
- updateMobileIndicator();
5218
- }, [updateMobileIndicator]);
5237
+ const tabsContainerRef = o__namespace.useRef(null);
5219
5238
  o__namespace.useEffect(() => {
5220
- if (typeof window === "undefined") return;
5221
- const handleResize = () => updateMobileIndicator();
5222
- window.addEventListener("resize", handleResize);
5223
- return () => window.removeEventListener("resize", handleResize);
5224
- }, [updateMobileIndicator]);
5225
- o__namespace.useEffect(() => {
5226
- const scrollEl = scrollContainerRef.current;
5227
- if (!scrollEl) return;
5228
- const handleScroll = () => {
5229
- updateMobileIndicator();
5230
- updateTabScrollThumb();
5239
+ const container = tabsContainerRef.current;
5240
+ if (!container) return;
5241
+ const isMobile = window.innerWidth <= 768;
5242
+ if (!isMobile) return;
5243
+ const forceScrollbar = () => {
5244
+ if (container.scrollWidth > container.clientWidth) {
5245
+ container.scrollTop = 1;
5246
+ container.scrollTop = 0;
5247
+ container.scrollLeft = 1;
5248
+ container.scrollLeft = 0;
5249
+ }
5231
5250
  };
5232
- scrollEl.addEventListener("scroll", handleScroll, { passive: true });
5233
- return () => scrollEl.removeEventListener("scroll", handleScroll);
5234
- }, [updateMobileIndicator, updateTabScrollThumb]);
5235
- o__namespace.useEffect(() => {
5236
- if (isMobile) {
5237
- updateTabScrollThumb();
5238
- }
5239
- }, [isMobile, updateTabScrollThumb, tabs.length]);
5240
- o__namespace.useEffect(() => {
5241
- if (typeof window === "undefined") return;
5242
- const media = window.matchMedia("(max-width: 768px)");
5243
- const setMatch = () => setIsMobile(media.matches);
5244
- setMatch();
5245
- media.addEventListener("change", setMatch);
5246
- return () => media.removeEventListener("change", setMatch);
5247
- }, []);
5251
+ setTimeout(forceScrollbar, 100);
5252
+ window.addEventListener("resize", forceScrollbar);
5253
+ return () => window.removeEventListener("resize", forceScrollbar);
5254
+ }, [tabs]);
5248
5255
  return /* @__PURE__ */ jsxRuntime.jsxs(
5249
5256
  "div",
5250
5257
  {
5251
5258
  ref,
5252
- className: cn("w-full font-normal flex flex-col gap-3 md:flex-row md:items-center md:justify-between", className),
5259
+ className: cn(
5260
+ "w-full font-normal",
5261
+ "flex flex-col-reverse gap-3",
5262
+ "md:flex-row md:items-center md:justify-between",
5263
+ className
5264
+ ),
5253
5265
  ...props,
5254
5266
  children: [
5255
- /* @__PURE__ */ jsxRuntime.jsxs(
5267
+ /* @__PURE__ */ jsxRuntime.jsx(
5256
5268
  "div",
5257
5269
  {
5258
- ref: tabsWrapperRef,
5270
+ ref: tabsContainerRef,
5259
5271
  className: cn(
5260
- "relative flex w-full min-w-0 flex-col",
5261
- "max-[768px]:gap-0",
5262
- "max-[768px]:order-0",
5263
- "md:flex-row md:items-center md:justify-between"
5272
+ "flex items-center border-b border-white/10",
5273
+ "overflow-x-auto md:overflow-visible",
5274
+ "[-webkit-overflow-scrolling:touch]",
5275
+ "[scroll-behavior:smooth]",
5276
+ "[touch-action:pan-x]",
5277
+ "md:border-b-0"
5264
5278
  ),
5265
- style: isMobile ? { gap: 0 } : void 0,
5266
- children: [
5267
- /* @__PURE__ */ jsxRuntime.jsx(
5268
- "div",
5279
+ style: { WebkitTapHighlightColor: "transparent" },
5280
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-max", children: tabs.map((tab) => {
5281
+ const active = tab.id === activeTabId;
5282
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5283
+ "button",
5269
5284
  {
5270
- ref: scrollContainerRef,
5285
+ type: "button",
5286
+ onClick: () => onTabChange?.(tab.id),
5271
5287
  className: cn(
5272
- "flex w-full min-w-0 items-center",
5273
- "overflow-x-auto md:overflow-visible",
5274
- "[-webkit-overflow-scrolling:touch]",
5275
- "[scrollbar-width:none]",
5276
- "[scroll-behavior:smooth]",
5277
- "[touch-action:pan-x]",
5278
- "md:border-b md:border-white/10"
5288
+ "relative whitespace-nowrap",
5289
+ "px-6 py-4",
5290
+ "font-normal",
5291
+ "transition-colors",
5292
+ "max-[768px]:px-[1.2rem] max-[768px]:py-[0.8rem]",
5293
+ "max-[480px]:px-4 max-[480px]:py-[0.7rem] max-[480px]:text-[0.9rem]",
5294
+ active ? "font-semibold text-[var(--color-accent,#e6c87e)]" : "text-white/60 hover:text-white"
5279
5295
  ),
5280
- style: { WebkitTapHighlightColor: "transparent" },
5281
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-max gap-2 lg:gap-4", children: tabs.map((tab, index) => {
5282
- const active = tab.id === activeTabId;
5283
- return /* @__PURE__ */ jsxRuntime.jsxs(
5284
- "button",
5285
- {
5286
- ref: (node2) => {
5287
- tabRefs.current[index] = node2;
5288
- },
5289
- type: "button",
5290
- onClick: () => onTabChange?.(tab.id),
5291
- className: cn(
5292
- "relative whitespace-nowrap",
5293
- "px-5 py-4 lg:px-6",
5294
- "text-[16px]",
5295
- "font-medium",
5296
- "transition-colors",
5297
- "max-[768px]:rounded-full max-[768px]:px-5 max-[768px]:py-3",
5298
- "max-[768px]:text-[15px]",
5299
- "max-[480px]:px-4 max-[480px]:py-[0.75rem] max-[480px]:text-sm",
5300
- active ? "font-semibold text-[var(--color-accent,#e6c87e)] hover:text-[var(--color-accent,#f1d27a)]" : "text-white/65 hover:text-white"
5301
- ),
5302
- style: {
5303
- borderBottom: active ? "2px solid var(--color-accent, #e6c87e)" : "2px solid transparent",
5304
- minWidth: "80px",
5305
- touchAction: "manipulation"
5306
- },
5307
- children: [
5308
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
5309
- tab.id === "trade" ? /* @__PURE__ */ jsxRuntime.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,
5310
- tab.label
5311
- ] }),
5312
- tab.hasNotification ? /* @__PURE__ */ jsxRuntime.jsx(
5313
- "span",
5314
- {
5315
- className: "absolute right-[10px] top-[10px] h-2 w-2 rounded-full animate-pulse",
5316
- style: {
5317
- backgroundColor: tab.notificationColor ?? "#f6465d",
5318
- boxShadow: "0 0 0 0 rgba(246, 70, 93, 0.7)"
5319
- }
5320
- }
5321
- ) : null
5322
- ]
5323
- },
5324
- tab.id
5325
- );
5326
- }) })
5327
- }
5328
- ),
5329
- /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(
5330
- "span",
5331
- {
5332
- ref: indicatorRef,
5333
- className: "absolute left-0 top-0 block h-full rounded-full bg-[var(--color-accent,#e6c87e)] transition-all duration-300 ease-out"
5334
- }
5335
- ) }),
5336
- /* @__PURE__ */ jsxRuntime.jsx(
5337
- "div",
5338
- {
5339
5296
  style: {
5340
- display: isMobile ? "block" : "none",
5341
- height: "8px",
5342
- width: "100%",
5343
- borderRadius: "999px",
5344
- background: "rgba(18,19,22,0.85)",
5345
- marginTop: "0",
5346
- position: "relative"
5297
+ borderBottom: active ? "2px solid var(--color-accent, #e6c87e)" : "2px solid transparent",
5298
+ minWidth: "80px",
5299
+ touchAction: "manipulation"
5347
5300
  },
5348
- children: /* @__PURE__ */ jsxRuntime.jsx(
5349
- "div",
5350
- {
5351
- style: {
5352
- position: "absolute",
5353
- top: 0,
5354
- left: `${tabScrollThumb.leftPercent}%`,
5355
- height: "100%",
5356
- borderRadius: "999px",
5357
- background: "rgba(92,94,102,0.85)",
5358
- width: `${tabScrollThumb.widthPercent}%`,
5359
- transition: "left 0.2s ease-out, width 0.2s ease-out, opacity 0.2s ease-out",
5360
- opacity: tabScrollThumb.scrollable ? 1 : 0.25
5301
+ children: [
5302
+ tab.label,
5303
+ tab.hasNotification ? /* @__PURE__ */ jsxRuntime.jsx(
5304
+ "span",
5305
+ {
5306
+ className: "absolute right-[10px] top-[10px] h-2 w-2 rounded-full animate-pulse",
5307
+ style: {
5308
+ backgroundColor: tab.notificationColor ?? "#f6465d",
5309
+ boxShadow: "0 0 0 0 rgba(246, 70, 93, 0.7)"
5310
+ }
5361
5311
  }
5362
- }
5363
- )
5364
- }
5365
- )
5366
- ]
5312
+ ) : null
5313
+ ]
5314
+ },
5315
+ tab.id
5316
+ );
5317
+ }) })
5367
5318
  }
5368
5319
  ),
5369
5320
  actions != null && actions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
5370
5321
  "div",
5371
5322
  {
5372
5323
  className: cn(
5373
- "flex items-center gap-[4px] md:gap-[10px]",
5374
- "justify-center md:justify-end",
5324
+ "flex items-center gap-[10px]",
5375
5325
  "overflow-x-auto md:overflow-visible",
5376
5326
  "[scrollbar-width:none]",
5377
- "max-[768px]:w-full max-[768px]:pb-2 max-[768px]:mb-2"
5327
+ "md:justify-end",
5328
+ "max-[768px]:w-full max-[768px]:justify-center max-[768px]:pb-2 max-[768px]:mb-4"
5378
5329
  ),
5379
- style: actionContainerStyle,
5380
5330
  children: actions.map((action) => /* @__PURE__ */ jsxRuntime.jsxs(
5381
5331
  "button",
5382
5332
  {
@@ -5384,14 +5334,14 @@ var PropertySubheader = o__namespace.forwardRef(
5384
5334
  onClick: action.onClick,
5385
5335
  className: cn(
5386
5336
  "flex shrink-0 items-center gap-[5px] whitespace-nowrap",
5387
- "rounded-[6px]",
5388
- "border border-white/15",
5337
+ "rounded",
5338
+ "border border-white/10",
5389
5339
  "bg-transparent",
5390
- "px-3.5 py-1.5 text-[14px] font-medium",
5340
+ "px-3 py-1.5 text-[14px] font-normal",
5391
5341
  "transition-all",
5342
+ "max-[768px]:px-2.5 max-[768px]:py-[5px] max-[768px]:text-[13px]",
5392
5343
  "hover:bg-white/5 hover:border-[var(--color-accent,#e6c87e)] hover:text-[var(--color-accent,#e6c87e)]"
5393
5344
  ),
5394
- style: actionButtonStyle,
5395
5345
  children: [
5396
5346
  action.icon,
5397
5347
  action.label