@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 +17 -3
- package/dist/index.d.ts +17 -3
- package/dist/index.js +203 -253
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +203 -253
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -255,18 +255,32 @@ type YourOrder = {
|
|
|
255
255
|
priceChangePercent?: number;
|
|
256
256
|
priceChangePositive?: boolean;
|
|
257
257
|
};
|
|
258
|
-
type
|
|
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
|
|
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 = "
|
|
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
|
|
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
|
|
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 = "
|
|
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
|
|
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
|
|
4396
|
-
const [
|
|
4397
|
-
const
|
|
4398
|
-
const
|
|
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:
|
|
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:
|
|
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
|
|
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:
|
|
4531
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: tabsRowStyle, children:
|
|
4532
|
-
const isActive =
|
|
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: () =>
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
5221
|
-
|
|
5222
|
-
window.
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
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
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
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(
|
|
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.
|
|
5267
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5256
5268
|
"div",
|
|
5257
5269
|
{
|
|
5258
|
-
ref:
|
|
5270
|
+
ref: tabsContainerRef,
|
|
5259
5271
|
className: cn(
|
|
5260
|
-
"
|
|
5261
|
-
"
|
|
5262
|
-
"
|
|
5263
|
-
"
|
|
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:
|
|
5266
|
-
children:
|
|
5267
|
-
|
|
5268
|
-
|
|
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
|
-
|
|
5285
|
+
type: "button",
|
|
5286
|
+
onClick: () => onTabChange?.(tab.id),
|
|
5271
5287
|
className: cn(
|
|
5272
|
-
"
|
|
5273
|
-
"
|
|
5274
|
-
"
|
|
5275
|
-
"
|
|
5276
|
-
"[
|
|
5277
|
-
"[
|
|
5278
|
-
"
|
|
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
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
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:
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
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-[
|
|
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
|
-
"
|
|
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
|
|
5388
|
-
"border border-white/
|
|
5337
|
+
"rounded",
|
|
5338
|
+
"border border-white/10",
|
|
5389
5339
|
"bg-transparent",
|
|
5390
|
-
"px-3
|
|
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
|