@loafmarkets/ui 0.1.3 → 0.1.4
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 +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +137 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +137 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -280,7 +280,7 @@ declare const YourOrders: React.ForwardRefExoticComponent<React.HTMLAttributes<H
|
|
|
280
280
|
renderOrderActions?: (order: YourOrder) => React.ReactNode;
|
|
281
281
|
} & React.RefAttributes<HTMLDivElement>>;
|
|
282
282
|
|
|
283
|
-
type PriceChartRange = "15m" | "1h" | "4h" | "24h" | "1W" | "1M";
|
|
283
|
+
type PriceChartRange = "30s" | "1m" | "5m" | "15m" | "1h" | "4h" | "24h" | "1W" | "1M";
|
|
284
284
|
type PriceChartCandle = {
|
|
285
285
|
time: LightweightCharts.Time;
|
|
286
286
|
open: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -280,7 +280,7 @@ declare const YourOrders: React.ForwardRefExoticComponent<React.HTMLAttributes<H
|
|
|
280
280
|
renderOrderActions?: (order: YourOrder) => React.ReactNode;
|
|
281
281
|
} & React.RefAttributes<HTMLDivElement>>;
|
|
282
282
|
|
|
283
|
-
type PriceChartRange = "15m" | "1h" | "4h" | "24h" | "1W" | "1M";
|
|
283
|
+
type PriceChartRange = "30s" | "1m" | "5m" | "15m" | "1h" | "4h" | "24h" | "1W" | "1M";
|
|
284
284
|
type PriceChartCandle = {
|
|
285
285
|
time: LightweightCharts.Time;
|
|
286
286
|
open: number;
|
package/dist/index.js
CHANGED
|
@@ -3300,7 +3300,7 @@ function DesktopOrderbookLayout({
|
|
|
3300
3300
|
)
|
|
3301
3301
|
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: rightHeader })
|
|
3302
3302
|
] }),
|
|
3303
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4
|
|
3303
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 pt-2", children: [
|
|
3304
3304
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-3 py-2 text-xs text-white/60", children: [
|
|
3305
3305
|
/* @__PURE__ */ jsxRuntime.jsx("div", { children: priceLabel }),
|
|
3306
3306
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: amountLabel })
|
|
@@ -3354,7 +3354,7 @@ function DesktopOrderbookLayout({
|
|
|
3354
3354
|
))
|
|
3355
3355
|
}
|
|
3356
3356
|
),
|
|
3357
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
3357
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3 bg-[#0b1a24] px-3 py-2", children: [
|
|
3358
3358
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("text-lg font-semibold tabular-nums", midClass), children: [
|
|
3359
3359
|
"$",
|
|
3360
3360
|
formatNumber(midPrice, precision),
|
|
@@ -4586,6 +4586,27 @@ var createTickFormatter = (formatOptions) => {
|
|
|
4586
4586
|
};
|
|
4587
4587
|
var getTimeScaleOptions = (range) => {
|
|
4588
4588
|
switch (range) {
|
|
4589
|
+
case "30s":
|
|
4590
|
+
return {
|
|
4591
|
+
timeVisible: true,
|
|
4592
|
+
secondsVisible: true,
|
|
4593
|
+
borderColor: "rgba(255,255,255,0.06)",
|
|
4594
|
+
tickMarkFormatter: createTickFormatter({ hour: "2-digit", minute: "2-digit", second: "2-digit" })
|
|
4595
|
+
};
|
|
4596
|
+
case "1m":
|
|
4597
|
+
return {
|
|
4598
|
+
timeVisible: true,
|
|
4599
|
+
secondsVisible: true,
|
|
4600
|
+
borderColor: "rgba(255,255,255,0.06)",
|
|
4601
|
+
tickMarkFormatter: createTickFormatter({ hour: "2-digit", minute: "2-digit", second: "2-digit" })
|
|
4602
|
+
};
|
|
4603
|
+
case "5m":
|
|
4604
|
+
return {
|
|
4605
|
+
timeVisible: true,
|
|
4606
|
+
secondsVisible: false,
|
|
4607
|
+
borderColor: "rgba(255,255,255,0.06)",
|
|
4608
|
+
tickMarkFormatter: createTickFormatter({ hour: "2-digit", minute: "2-digit" })
|
|
4609
|
+
};
|
|
4589
4610
|
case "15m":
|
|
4590
4611
|
return {
|
|
4591
4612
|
timeVisible: true,
|
|
@@ -4657,7 +4678,8 @@ var getPriceScaleOptions = (data) => {
|
|
|
4657
4678
|
scaleMargins
|
|
4658
4679
|
};
|
|
4659
4680
|
};
|
|
4660
|
-
var defaultRanges = ["15m", "1h", "4h", "24h", "1W", "1M"];
|
|
4681
|
+
var defaultRanges = ["30s", "1m", "5m", "15m", "1h", "4h", "24h", "1W", "1M"];
|
|
4682
|
+
var VISIBLE_RANGE_COUNT = 4;
|
|
4661
4683
|
var formatPrice = (value, currencySymbol) => {
|
|
4662
4684
|
return `${currencySymbol}${value.toLocaleString(void 0, {
|
|
4663
4685
|
minimumFractionDigits: 2,
|
|
@@ -4694,6 +4716,21 @@ var PriceChart = o__namespace.forwardRef(
|
|
|
4694
4716
|
const seriesRef = o__namespace.useRef(null);
|
|
4695
4717
|
const priceLineRef = o__namespace.useRef(null);
|
|
4696
4718
|
const [hoveredRange, setHoveredRange] = o__namespace.useState(null);
|
|
4719
|
+
const [dropdownOpen, setDropdownOpen] = o__namespace.useState(false);
|
|
4720
|
+
const dropdownRef = o__namespace.useRef(null);
|
|
4721
|
+
const isAutoScrollRef = o__namespace.useRef(true);
|
|
4722
|
+
const visibleRanges = ranges.slice(0, VISIBLE_RANGE_COUNT);
|
|
4723
|
+
const dropdownRanges = ranges.slice(VISIBLE_RANGE_COUNT);
|
|
4724
|
+
const selectedInDropdown = dropdownRanges.includes(selectedRange);
|
|
4725
|
+
o__namespace.useEffect(() => {
|
|
4726
|
+
const handleClickOutside = (e) => {
|
|
4727
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
4728
|
+
setDropdownOpen(false);
|
|
4729
|
+
}
|
|
4730
|
+
};
|
|
4731
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
4732
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
4733
|
+
}, []);
|
|
4697
4734
|
const resolvedPrice = o__namespace.useMemo(() => {
|
|
4698
4735
|
if (price != null) return price;
|
|
4699
4736
|
const last = data.at(-1);
|
|
@@ -4742,9 +4779,18 @@ var PriceChart = o__namespace.forwardRef(
|
|
|
4742
4779
|
});
|
|
4743
4780
|
chartRef.current = chart;
|
|
4744
4781
|
seriesRef.current = series;
|
|
4782
|
+
const handleVisibleRangeChange = () => {
|
|
4783
|
+
const timeScale2 = chart.timeScale();
|
|
4784
|
+
const position2 = timeScale2.scrollPosition();
|
|
4785
|
+
const atRightEdge = position2 <= 0.01;
|
|
4786
|
+
isAutoScrollRef.current = atRightEdge;
|
|
4787
|
+
};
|
|
4788
|
+
const timeScale = chart.timeScale();
|
|
4789
|
+
timeScale.subscribeVisibleLogicalRangeChange(handleVisibleRangeChange);
|
|
4745
4790
|
return () => {
|
|
4746
4791
|
chartRef.current = null;
|
|
4747
4792
|
seriesRef.current = null;
|
|
4793
|
+
timeScale.unsubscribeVisibleLogicalRangeChange(handleVisibleRangeChange);
|
|
4748
4794
|
chart.remove();
|
|
4749
4795
|
};
|
|
4750
4796
|
}, []);
|
|
@@ -4779,7 +4825,9 @@ var PriceChart = o__namespace.forwardRef(
|
|
|
4779
4825
|
title: resolvedPrice.toFixed(2)
|
|
4780
4826
|
});
|
|
4781
4827
|
}
|
|
4782
|
-
|
|
4828
|
+
if (isAutoScrollRef.current) {
|
|
4829
|
+
chart.timeScale().scrollToPosition(0, true);
|
|
4830
|
+
}
|
|
4783
4831
|
}, [data, resolvedPrice]);
|
|
4784
4832
|
const sign = inferredChangePercent == null ? null : inferredChangePercent >= 0 ? "+" : "";
|
|
4785
4833
|
const changeClass = inferredChangePercent == null ? "" : inferredChangePercent >= 0 ? "text-[#0ecb81]" : "text-[#f6465d]";
|
|
@@ -4811,30 +4859,97 @@ var PriceChart = o__namespace.forwardRef(
|
|
|
4811
4859
|
/* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "flex flex-col gap-4 px-4 pb-2 pt-5 md:flex-row md:items-start md:justify-between md:px-6 md:pt-6", children: [
|
|
4812
4860
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-col gap-3 md:w-auto", children: [
|
|
4813
4861
|
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "m-0 text-[1.1rem] font-semibold text-white", children: title }),
|
|
4814
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4862
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
4863
|
+
visibleRanges.map((r2) => {
|
|
4864
|
+
const active = r2 === selectedRange;
|
|
4865
|
+
const hovered = hoveredRange === r2;
|
|
4866
|
+
const style = {
|
|
4867
|
+
...btnBaseStyle,
|
|
4868
|
+
...hovered ? btnHoverStyle : null,
|
|
4869
|
+
...active ? btnActiveStyle : null
|
|
4870
|
+
};
|
|
4871
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4872
|
+
"button",
|
|
4873
|
+
{
|
|
4874
|
+
type: "button",
|
|
4875
|
+
onClick: () => onRangeChange?.(r2),
|
|
4876
|
+
onMouseEnter: () => setHoveredRange(r2),
|
|
4877
|
+
onMouseLeave: () => setHoveredRange((prev2) => prev2 === r2 ? null : prev2),
|
|
4878
|
+
style,
|
|
4879
|
+
className: cn(
|
|
4880
|
+
"rounded border px-3 py-1 text-[0.85rem] font-medium transition-all duration-200"
|
|
4881
|
+
),
|
|
4882
|
+
children: r2
|
|
4883
|
+
},
|
|
4884
|
+
r2
|
|
4885
|
+
);
|
|
4886
|
+
}),
|
|
4887
|
+
selectedInDropdown && selectedRange ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4823
4888
|
"button",
|
|
4824
4889
|
{
|
|
4825
4890
|
type: "button",
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4891
|
+
style: {
|
|
4892
|
+
...btnBaseStyle,
|
|
4893
|
+
...btnActiveStyle
|
|
4894
|
+
},
|
|
4830
4895
|
className: cn(
|
|
4831
4896
|
"rounded border px-3 py-1 text-[0.85rem] font-medium transition-all duration-200"
|
|
4832
4897
|
),
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
)
|
|
4837
|
-
|
|
4898
|
+
disabled: true,
|
|
4899
|
+
children: selectedRange
|
|
4900
|
+
}
|
|
4901
|
+
) : null,
|
|
4902
|
+
dropdownRanges.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", ref: dropdownRef, children: [
|
|
4903
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4904
|
+
"button",
|
|
4905
|
+
{
|
|
4906
|
+
type: "button",
|
|
4907
|
+
onClick: () => setDropdownOpen((prev2) => !prev2),
|
|
4908
|
+
onMouseEnter: () => setHoveredRange("__dropdown__"),
|
|
4909
|
+
onMouseLeave: () => setHoveredRange((prev2) => prev2 === "__dropdown__" ? null : prev2),
|
|
4910
|
+
style: {
|
|
4911
|
+
...btnBaseStyle,
|
|
4912
|
+
...hoveredRange === "__dropdown__" ? btnHoverStyle : null
|
|
4913
|
+
},
|
|
4914
|
+
className: cn(
|
|
4915
|
+
"flex items-center gap-1 rounded border px-3 py-1 text-[0.85rem] font-medium transition-all duration-200"
|
|
4916
|
+
),
|
|
4917
|
+
children: [
|
|
4918
|
+
"More",
|
|
4919
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4920
|
+
"svg",
|
|
4921
|
+
{
|
|
4922
|
+
className: cn("h-3 w-3 transition-transform", dropdownOpen && "rotate-180"),
|
|
4923
|
+
fill: "none",
|
|
4924
|
+
stroke: "currentColor",
|
|
4925
|
+
viewBox: "0 0 24 24",
|
|
4926
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
|
|
4927
|
+
}
|
|
4928
|
+
)
|
|
4929
|
+
]
|
|
4930
|
+
}
|
|
4931
|
+
),
|
|
4932
|
+
dropdownOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-full z-50 mt-1 min-w-[80px] rounded border border-white/10 bg-black/90 py-1 backdrop-blur-md", children: dropdownRanges.map((r2) => {
|
|
4933
|
+
const active = r2 === selectedRange;
|
|
4934
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4935
|
+
"button",
|
|
4936
|
+
{
|
|
4937
|
+
type: "button",
|
|
4938
|
+
onClick: () => {
|
|
4939
|
+
onRangeChange?.(r2);
|
|
4940
|
+
setDropdownOpen(false);
|
|
4941
|
+
},
|
|
4942
|
+
className: cn(
|
|
4943
|
+
"block w-full px-3 py-1.5 text-left text-[0.85rem] font-medium transition-colors hover:bg-white/10",
|
|
4944
|
+
active ? "bg-[#e6c87e]/20 text-[#e6c87e]" : "text-white/70"
|
|
4945
|
+
),
|
|
4946
|
+
children: r2
|
|
4947
|
+
},
|
|
4948
|
+
r2
|
|
4949
|
+
);
|
|
4950
|
+
}) })
|
|
4951
|
+
] })
|
|
4952
|
+
] })
|
|
4838
4953
|
] }),
|
|
4839
4954
|
resolvedPrice == null && inferredChangePercent == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [
|
|
4840
4955
|
resolvedPrice == null ? null : /* @__PURE__ */ jsxRuntime.jsx(
|