@funnest/charts-ui 0.5.0 → 0.5.2
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/components/keep-in-view.d.ts +6 -0
- package/dist/index.js +209 -65
- package/package.json +2 -2
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nudges an open dropdown horizontally so it stays inside the widget and the viewport (its CSS
|
|
3
|
+
* anchor may push it off-screen on phones; hosts often clip the widget with overflow: hidden).
|
|
4
|
+
* Attach the returned ref to the menu element.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useKeepInView<T extends HTMLElement>(open: boolean): import("preact").RefObject<T | null>;
|
package/dist/index.js
CHANGED
|
@@ -825,7 +825,7 @@ function DrawingToolbar({ ctx }) {
|
|
|
825
825
|
if (tool && ctx.store.get().drawbarOpen) ctx.store.set({ drawbarOpen: false });
|
|
826
826
|
};
|
|
827
827
|
return /* @__PURE__ */ a2($, { children: [
|
|
828
|
-
s3.drawbarCollapsed && /* @__PURE__ */ a2("button", { class: "fnc-drawbar-tab", "aria-label": t3.expandDrawbar,
|
|
828
|
+
s3.drawbarCollapsed && /* @__PURE__ */ a2("button", { class: "fnc-drawbar-tab", "aria-label": t3.expandDrawbar, "data-tip": t3.expandDrawbar, onClick: () => ctx.setDrawbarCollapsed(false), children: /* @__PURE__ */ a2(ChevronRightIcon, {}) }),
|
|
829
829
|
/* @__PURE__ */ a2(
|
|
830
830
|
"div",
|
|
831
831
|
{
|
|
@@ -840,7 +840,7 @@ function DrawingToolbar({ ctx }) {
|
|
|
840
840
|
"button",
|
|
841
841
|
{
|
|
842
842
|
class: "fnc-btn",
|
|
843
|
-
|
|
843
|
+
"data-tip": t3[label],
|
|
844
844
|
"aria-label": t3[label],
|
|
845
845
|
"aria-pressed": s3.drawingTool === tool,
|
|
846
846
|
onClick: () => pick(tool),
|
|
@@ -852,7 +852,7 @@ function DrawingToolbar({ ctx }) {
|
|
|
852
852
|
"button",
|
|
853
853
|
{
|
|
854
854
|
class: "fnc-btn",
|
|
855
|
-
|
|
855
|
+
"data-tip": t3.magnet,
|
|
856
856
|
"aria-label": t3.magnet,
|
|
857
857
|
"aria-pressed": s3.magnet,
|
|
858
858
|
onClick: () => ctx.chart.setMagnet(!s3.magnet),
|
|
@@ -863,7 +863,7 @@ function DrawingToolbar({ ctx }) {
|
|
|
863
863
|
"button",
|
|
864
864
|
{
|
|
865
865
|
class: "fnc-btn",
|
|
866
|
-
|
|
866
|
+
"data-tip": t3.removeAll,
|
|
867
867
|
"aria-label": t3.removeAll,
|
|
868
868
|
disabled: s3.drawingCount === 0,
|
|
869
869
|
onClick: () => ctx.chart.clearDrawings(),
|
|
@@ -875,7 +875,7 @@ function DrawingToolbar({ ctx }) {
|
|
|
875
875
|
"button",
|
|
876
876
|
{
|
|
877
877
|
class: "fnc-btn fnc-drawbar-collapse",
|
|
878
|
-
|
|
878
|
+
"data-tip": t3.collapseDrawbar,
|
|
879
879
|
"aria-label": t3.collapseDrawbar,
|
|
880
880
|
onClick: () => ctx.setDrawbarCollapsed(true),
|
|
881
881
|
children: /* @__PURE__ */ a2(ChevronLeftIcon, {})
|
|
@@ -898,17 +898,43 @@ function SelectionBar({ ctx }) {
|
|
|
898
898
|
{
|
|
899
899
|
class: "fnc-swatch",
|
|
900
900
|
style: { background: color },
|
|
901
|
-
|
|
901
|
+
"data-tip": t3.color,
|
|
902
902
|
"aria-label": `${t3.color} ${color}`,
|
|
903
903
|
"aria-pressed": (d3.color ?? SWATCHES[0]) === color,
|
|
904
904
|
onClick: () => ctx.chart.updateDrawing(d3.id, { color })
|
|
905
905
|
}
|
|
906
906
|
)),
|
|
907
907
|
/* @__PURE__ */ a2("div", { class: "fnc-sep" }),
|
|
908
|
-
/* @__PURE__ */ a2("button", { class: "fnc-btn",
|
|
908
|
+
/* @__PURE__ */ a2("button", { class: "fnc-btn", "data-tip": t3.remove, "aria-label": t3.remove, onClick: () => ctx.chart.removeDrawing(d3.id), children: /* @__PURE__ */ a2(TrashIcon, {}) })
|
|
909
909
|
] });
|
|
910
910
|
}
|
|
911
911
|
|
|
912
|
+
// src/components/keep-in-view.ts
|
|
913
|
+
var MARGIN = 8;
|
|
914
|
+
function useKeepInView(open) {
|
|
915
|
+
const ref = T2(null);
|
|
916
|
+
F2(() => {
|
|
917
|
+
const el = ref.current;
|
|
918
|
+
if (!open || !el) return;
|
|
919
|
+
el.style.translate = "";
|
|
920
|
+
const fit = () => {
|
|
921
|
+
el.style.translate = "";
|
|
922
|
+
const r3 = el.getBoundingClientRect();
|
|
923
|
+
const root = el.closest(".fnc-root")?.getBoundingClientRect();
|
|
924
|
+
const minX = Math.max(0, root?.left ?? 0) + MARGIN;
|
|
925
|
+
const maxX = Math.min(document.documentElement.clientWidth, root?.right ?? Infinity) - MARGIN;
|
|
926
|
+
let dx = 0;
|
|
927
|
+
if (r3.right > maxX) dx = maxX - r3.right;
|
|
928
|
+
if (r3.left + dx < minX) dx = minX - r3.left;
|
|
929
|
+
if (dx) el.style.translate = `${Math.round(dx)}px 0`;
|
|
930
|
+
};
|
|
931
|
+
fit();
|
|
932
|
+
window.addEventListener("resize", fit);
|
|
933
|
+
return () => window.removeEventListener("resize", fit);
|
|
934
|
+
}, [open]);
|
|
935
|
+
return ref;
|
|
936
|
+
}
|
|
937
|
+
|
|
912
938
|
// src/components/chart-type-menu.tsx
|
|
913
939
|
var TYPES = [
|
|
914
940
|
{ type: "candles", label: "candles", icon: CandlesIcon },
|
|
@@ -920,6 +946,7 @@ function ChartTypeMenu({ ctx }) {
|
|
|
920
946
|
const t3 = STRINGS[s3.locale];
|
|
921
947
|
const [open, setOpen] = d2(false);
|
|
922
948
|
const ref = T2(null);
|
|
949
|
+
const menuRef = useKeepInView(open);
|
|
923
950
|
const current = TYPES.find((x2) => x2.type === s3.chartType) ?? TYPES[0];
|
|
924
951
|
A2(() => {
|
|
925
952
|
if (!open) return;
|
|
@@ -937,12 +964,12 @@ function ChartTypeMenu({ ctx }) {
|
|
|
937
964
|
ctx.store.set({ chartType: type });
|
|
938
965
|
setOpen(false);
|
|
939
966
|
};
|
|
940
|
-
return /* @__PURE__ */ a2("div", { class: "fnc-menu-wrap", ref, children: [
|
|
967
|
+
return /* @__PURE__ */ a2("div", { class: "fnc-menu-wrap fnc-chart-type", ref, children: [
|
|
941
968
|
/* @__PURE__ */ a2(
|
|
942
969
|
"button",
|
|
943
970
|
{
|
|
944
971
|
class: "fnc-btn fnc-btn-wide",
|
|
945
|
-
|
|
972
|
+
"data-tip": t3.chartType,
|
|
946
973
|
"aria-label": t3.chartType,
|
|
947
974
|
"aria-haspopup": "menu",
|
|
948
975
|
"aria-expanded": open,
|
|
@@ -953,7 +980,7 @@ function ChartTypeMenu({ ctx }) {
|
|
|
953
980
|
]
|
|
954
981
|
}
|
|
955
982
|
),
|
|
956
|
-
open && /* @__PURE__ */ a2("div", { class: "fnc-menu", role: "menu", children: TYPES.map(({ type, label, icon: Icon2 }) => /* @__PURE__ */ a2(
|
|
983
|
+
open && /* @__PURE__ */ a2("div", { class: "fnc-menu", role: "menu", ref: menuRef, children: TYPES.map(({ type, label, icon: Icon2 }) => /* @__PURE__ */ a2(
|
|
957
984
|
"button",
|
|
958
985
|
{
|
|
959
986
|
class: "fnc-menu-item",
|
|
@@ -1230,7 +1257,7 @@ function IndicatorSettings({ ctx, id }) {
|
|
|
1230
1257
|
onInput: (e3) => updateLine(i3, { period: e3.currentTarget.value.replace(/\D/g, "") })
|
|
1231
1258
|
}
|
|
1232
1259
|
),
|
|
1233
|
-
/* @__PURE__ */ a2("button", { type: "button", class: "fnc-ind-btn", "aria-label": t3.removePeriod,
|
|
1260
|
+
/* @__PURE__ */ a2("button", { type: "button", class: "fnc-ind-btn", "aria-label": t3.removePeriod, "data-tip": t3.removePeriod, onClick: () => setLines(lines.filter((_3, j2) => j2 !== i3)), children: /* @__PURE__ */ a2(SmallCloseIcon, {}) })
|
|
1234
1261
|
] })),
|
|
1235
1262
|
/* @__PURE__ */ a2("button", { type: "button", class: "fnc-add-row", onClick: addLine, children: [
|
|
1236
1263
|
"+ ",
|
|
@@ -1302,6 +1329,7 @@ function IntervalPicker({ ctx }) {
|
|
|
1302
1329
|
const t3 = STRINGS[s3.locale];
|
|
1303
1330
|
const [open, setOpen] = d2(false);
|
|
1304
1331
|
const ref = T2(null);
|
|
1332
|
+
const menuRef = useKeepInView(open);
|
|
1305
1333
|
A2(() => {
|
|
1306
1334
|
if (!open) return;
|
|
1307
1335
|
const onDown = (e3) => !ref.current?.contains(e3.target) && setOpen(false);
|
|
@@ -1328,7 +1356,7 @@ function IntervalPicker({ ctx }) {
|
|
|
1328
1356
|
class: "fnc-chip",
|
|
1329
1357
|
"aria-pressed": r3 === s3.resolution,
|
|
1330
1358
|
disabled: !isSupported(r3),
|
|
1331
|
-
|
|
1359
|
+
"data-tip": isSupported(r3) ? resolutionLabel(r3, s3.locale, "long") : t3.unsupportedInterval,
|
|
1332
1360
|
onClick: () => select(r3),
|
|
1333
1361
|
children: resolutionLabel(r3, s3.locale)
|
|
1334
1362
|
}
|
|
@@ -1337,7 +1365,7 @@ function IntervalPicker({ ctx }) {
|
|
|
1337
1365
|
"button",
|
|
1338
1366
|
{
|
|
1339
1367
|
class: `fnc-btn fnc-btn-wide fnc-interval-trigger${favorites.includes(s3.resolution) ? "" : " fnc-interval-trigger-active"}`,
|
|
1340
|
-
|
|
1368
|
+
"data-tip": t3.moreIntervals,
|
|
1341
1369
|
"aria-label": t3.moreIntervals,
|
|
1342
1370
|
"aria-haspopup": "menu",
|
|
1343
1371
|
"aria-expanded": open,
|
|
@@ -1348,7 +1376,7 @@ function IntervalPicker({ ctx }) {
|
|
|
1348
1376
|
]
|
|
1349
1377
|
}
|
|
1350
1378
|
),
|
|
1351
|
-
open && /* @__PURE__ */ a2("div", { class: "fnc-menu fnc-interval-menu", role: "menu", children: ctx.intervalGroups.map((group) => /* @__PURE__ */ a2("div", { class: "fnc-menu-group", role: "group", "aria-label": t3[GROUP_LABEL[group.id]], children: [
|
|
1379
|
+
open && /* @__PURE__ */ a2("div", { class: "fnc-menu fnc-interval-menu", role: "menu", ref: menuRef, children: ctx.intervalGroups.map((group) => /* @__PURE__ */ a2("div", { class: "fnc-menu-group", role: "group", "aria-label": t3[GROUP_LABEL[group.id]], children: [
|
|
1352
1380
|
/* @__PURE__ */ a2("div", { class: "fnc-menu-title", children: t3[GROUP_LABEL[group.id]] }),
|
|
1353
1381
|
group.intervals.map((r3) => {
|
|
1354
1382
|
const favorite = s3.favoriteIntervals.includes(r3);
|
|
@@ -1361,7 +1389,7 @@ function IntervalPicker({ ctx }) {
|
|
|
1361
1389
|
role: "menuitemradio",
|
|
1362
1390
|
"aria-checked": r3 === s3.resolution,
|
|
1363
1391
|
disabled: !ok,
|
|
1364
|
-
|
|
1392
|
+
"data-tip": ok ? void 0 : t3.unsupportedInterval,
|
|
1365
1393
|
onClick: () => select(r3),
|
|
1366
1394
|
children: resolutionLabel(r3, s3.locale, "long")
|
|
1367
1395
|
}
|
|
@@ -1372,7 +1400,7 @@ function IntervalPicker({ ctx }) {
|
|
|
1372
1400
|
class: "fnc-star",
|
|
1373
1401
|
"aria-pressed": favorite,
|
|
1374
1402
|
"aria-label": `${resolutionLabel(r3, s3.locale, "long")} ${favorite ? t3.removeFavorite : t3.addFavorite}`,
|
|
1375
|
-
|
|
1403
|
+
"data-tip": favorite ? t3.removeFavorite : t3.addFavorite,
|
|
1376
1404
|
onClick: () => ctx.toggleFavoriteInterval(r3),
|
|
1377
1405
|
children: /* @__PURE__ */ a2(StarIcon, { filled: favorite })
|
|
1378
1406
|
}
|
|
@@ -1450,6 +1478,7 @@ function layoutRects(node, x2 = 0, y3 = 0, w3 = 20, h3 = 16, gap = 1.6) {
|
|
|
1450
1478
|
}
|
|
1451
1479
|
|
|
1452
1480
|
// src/components/layout-menu.tsx
|
|
1481
|
+
var LAYOUT_PANES = (id) => paneCount(LAYOUTS[id]);
|
|
1453
1482
|
function LayoutGlyph({ id }) {
|
|
1454
1483
|
return /* @__PURE__ */ a2("svg", { width: "20", height: "16", viewBox: "0 0 20 16", "aria-hidden": "true", children: layoutRects(LAYOUTS[id]).map((r3) => /* @__PURE__ */ a2("rect", { x: r3.x + 0.5, y: r3.y + 0.5, width: Math.max(0, r3.w - 1), height: Math.max(0, r3.h - 1), rx: "1.5", fill: "none", stroke: "currentColor", "stroke-width": "1.2" })) });
|
|
1455
1484
|
}
|
|
@@ -1481,6 +1510,8 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1481
1510
|
const t3 = STRINGS[s3.locale];
|
|
1482
1511
|
const layout = usePopover();
|
|
1483
1512
|
const sync = usePopover();
|
|
1513
|
+
const layoutMenuRef = useKeepInView(layout.open);
|
|
1514
|
+
const syncMenuRef = useKeepInView(sync.open);
|
|
1484
1515
|
const anySync = Object.values(m3.sync).some(Boolean);
|
|
1485
1516
|
return /* @__PURE__ */ a2($, { children: [
|
|
1486
1517
|
/* @__PURE__ */ a2("div", { class: "fnc-menu-wrap", ref: layout.ref, children: [
|
|
@@ -1488,7 +1519,7 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1488
1519
|
"button",
|
|
1489
1520
|
{
|
|
1490
1521
|
class: "fnc-btn fnc-btn-wide fnc-btn-layout",
|
|
1491
|
-
|
|
1522
|
+
"data-tip": t3.layout,
|
|
1492
1523
|
"aria-label": t3.layout,
|
|
1493
1524
|
"aria-haspopup": "menu",
|
|
1494
1525
|
"aria-expanded": layout.open,
|
|
@@ -1499,7 +1530,7 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1499
1530
|
]
|
|
1500
1531
|
}
|
|
1501
1532
|
),
|
|
1502
|
-
layout.open && /* @__PURE__ */ a2("div", { class: "fnc-menu fnc-layout-menu", role: "menu", "aria-label": t3.layout, children: LAYOUT_GROUPS.map((group) => /* @__PURE__ */ a2("div", { class: "fnc-layout-row", children: [
|
|
1533
|
+
layout.open && /* @__PURE__ */ a2("div", { class: "fnc-menu fnc-layout-menu", role: "menu", "aria-label": t3.layout, ref: layoutMenuRef, children: LAYOUT_GROUPS.map((group) => /* @__PURE__ */ a2("div", { class: "fnc-layout-row", children: [
|
|
1503
1534
|
/* @__PURE__ */ a2("span", { class: "fnc-layout-count", children: group[0].split("-")[0] }),
|
|
1504
1535
|
group.map((id) => /* @__PURE__ */ a2(
|
|
1505
1536
|
"button",
|
|
@@ -1508,7 +1539,7 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1508
1539
|
role: "menuitemradio",
|
|
1509
1540
|
"aria-checked": id === m3.layout,
|
|
1510
1541
|
"aria-label": `${t3.layout} ${id}`,
|
|
1511
|
-
|
|
1542
|
+
"data-layout": id,
|
|
1512
1543
|
onClick: () => {
|
|
1513
1544
|
multi.setLayout(id);
|
|
1514
1545
|
layout.setOpen(false);
|
|
@@ -1518,12 +1549,12 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1518
1549
|
))
|
|
1519
1550
|
] })) })
|
|
1520
1551
|
] }),
|
|
1521
|
-
/* @__PURE__ */ a2("div", { class: "fnc-menu-wrap", ref: sync.ref, children: [
|
|
1552
|
+
LAYOUT_PANES(m3.layout) > 1 && /* @__PURE__ */ a2("div", { class: "fnc-menu-wrap", ref: sync.ref, children: [
|
|
1522
1553
|
/* @__PURE__ */ a2(
|
|
1523
1554
|
"button",
|
|
1524
1555
|
{
|
|
1525
1556
|
class: "fnc-btn fnc-btn-sync",
|
|
1526
|
-
|
|
1557
|
+
"data-tip": t3.sync,
|
|
1527
1558
|
"aria-label": t3.sync,
|
|
1528
1559
|
"aria-haspopup": "menu",
|
|
1529
1560
|
"aria-expanded": sync.open,
|
|
@@ -1532,7 +1563,7 @@ function LayoutMenu({ ctx, multi }) {
|
|
|
1532
1563
|
children: /* @__PURE__ */ a2(LinkIcon, {})
|
|
1533
1564
|
}
|
|
1534
1565
|
),
|
|
1535
|
-
sync.open && /* @__PURE__ */ a2("div", { class: "fnc-menu fnc-sync-menu", role: "menu", "aria-label": t3.sync, children: [
|
|
1566
|
+
sync.open && /* @__PURE__ */ a2("div", { class: "fnc-menu fnc-sync-menu", role: "menu", "aria-label": t3.sync, ref: syncMenuRef, children: [
|
|
1536
1567
|
/* @__PURE__ */ a2("div", { class: "fnc-menu-title", children: [
|
|
1537
1568
|
t3.sync,
|
|
1538
1569
|
/* @__PURE__ */ a2("small", { children: t3.syncHint })
|
|
@@ -1711,7 +1742,7 @@ function SymbolSearch({ ctx }) {
|
|
|
1711
1742
|
class: `fnc-sr-star${fav ? " is-on" : ""}`,
|
|
1712
1743
|
"aria-pressed": fav,
|
|
1713
1744
|
"aria-label": `${info.name} ${fav ? t3.removeFavorite : t3.addFavorite}`,
|
|
1714
|
-
|
|
1745
|
+
"data-tip": fav ? t3.removeFavorite : t3.addFavorite,
|
|
1715
1746
|
onClick: (e3) => {
|
|
1716
1747
|
e3.stopPropagation();
|
|
1717
1748
|
toggleFavorite(info);
|
|
@@ -1746,7 +1777,7 @@ function SymbolSearch({ ctx }) {
|
|
|
1746
1777
|
{
|
|
1747
1778
|
class: "fnc-ind-btn",
|
|
1748
1779
|
"aria-label": `${info.name} ${t3.removeRecent}`,
|
|
1749
|
-
|
|
1780
|
+
"data-tip": t3.removeRecent,
|
|
1750
1781
|
onClick: (e3) => {
|
|
1751
1782
|
e3.stopPropagation();
|
|
1752
1783
|
save(RECENT_KEY, recent.filter((r3) => r3.symbol !== info.symbol), setRecent);
|
|
@@ -1784,7 +1815,7 @@ function SymbolSearch({ ctx }) {
|
|
|
1784
1815
|
}
|
|
1785
1816
|
),
|
|
1786
1817
|
query && /* @__PURE__ */ a2("button", { class: "fnc-ind-btn", "aria-label": t3.cancel, onClick: () => (setQuery(""), inputRef.current?.focus()), children: /* @__PURE__ */ a2(SmallCloseIcon, {}) }),
|
|
1787
|
-
/* @__PURE__ */ a2("
|
|
1818
|
+
/* @__PURE__ */ a2("button", { class: "fnc-kbd fnc-kbd-btn fnc-hide-mobile", "aria-label": t3.close, "data-tip": t3.close, onClick: close, children: "ESC" })
|
|
1788
1819
|
] }),
|
|
1789
1820
|
/* @__PURE__ */ a2("div", { class: "fnc-tabs", role: "tablist", children: ctx.searchCategories.map((c3) => /* @__PURE__ */ a2("button", { class: "fnc-tab", role: "tab", "aria-selected": c3.id === category, onClick: () => setCategory(c3.id), children: c3.label[locale] })) }),
|
|
1790
1821
|
/* @__PURE__ */ a2("div", { class: "fnc-sr-body", children: [
|
|
@@ -1819,7 +1850,7 @@ function SymbolSearch({ ctx }) {
|
|
|
1819
1850
|
" ",
|
|
1820
1851
|
t3.openAction
|
|
1821
1852
|
] }),
|
|
1822
|
-
/* @__PURE__ */ a2("
|
|
1853
|
+
/* @__PURE__ */ a2("button", { class: "fnc-sr-foot-btn", onClick: close, children: [
|
|
1823
1854
|
/* @__PURE__ */ a2("kbd", { class: "fnc-kbd", children: "ESC" }),
|
|
1824
1855
|
" ",
|
|
1825
1856
|
t3.close
|
|
@@ -1848,7 +1879,7 @@ function Toolbar({ ctx }) {
|
|
|
1848
1879
|
{
|
|
1849
1880
|
class: "fnc-symbol",
|
|
1850
1881
|
disabled: !canSearch,
|
|
1851
|
-
|
|
1882
|
+
"data-tip": canSearch ? t3.searchSymbol : void 0,
|
|
1852
1883
|
"aria-haspopup": "dialog",
|
|
1853
1884
|
onClick: () => ctx.setSearchOpen(true),
|
|
1854
1885
|
children: [
|
|
@@ -1861,29 +1892,31 @@ function Toolbar({ ctx }) {
|
|
|
1861
1892
|
/* @__PURE__ */ a2("div", { class: "fnc-sep" }),
|
|
1862
1893
|
/* @__PURE__ */ a2(IntervalPicker, { ctx }),
|
|
1863
1894
|
/* @__PURE__ */ a2(Slot, { el: ctx.slots.toolbar }),
|
|
1864
|
-
/* @__PURE__ */ a2("div", { class: "fnc-sep" }),
|
|
1865
|
-
/* @__PURE__ */ a2(ChartTypeMenu, { ctx }),
|
|
1866
|
-
/* @__PURE__ */ a2(
|
|
1867
|
-
"button",
|
|
1868
|
-
{
|
|
1869
|
-
class: "fnc-btn fnc-btn-wide fnc-btn-label",
|
|
1870
|
-
title: t3.addIndicator,
|
|
1871
|
-
"aria-label": t3.addIndicator,
|
|
1872
|
-
"aria-haspopup": "dialog",
|
|
1873
|
-
onClick: () => ctx.store.set({ dialog: { kind: "indicators" } }),
|
|
1874
|
-
children: [
|
|
1875
|
-
/* @__PURE__ */ a2(IndicatorIcon, {}),
|
|
1876
|
-
/* @__PURE__ */ a2("span", { children: t3.indicators })
|
|
1877
|
-
]
|
|
1878
|
-
}
|
|
1879
|
-
),
|
|
1880
|
-
ctx.multi && /* @__PURE__ */ a2(LayoutMenu, { ctx, multi: ctx.multi }),
|
|
1881
1895
|
/* @__PURE__ */ a2("div", { class: "fnc-spacer" }),
|
|
1896
|
+
/* @__PURE__ */ a2("div", { class: "fnc-tools", children: [
|
|
1897
|
+
/* @__PURE__ */ a2(ChartTypeMenu, { ctx }),
|
|
1898
|
+
/* @__PURE__ */ a2(
|
|
1899
|
+
"button",
|
|
1900
|
+
{
|
|
1901
|
+
class: "fnc-btn fnc-btn-wide fnc-btn-label fnc-btn-indicators",
|
|
1902
|
+
"data-tip": t3.addIndicator,
|
|
1903
|
+
"aria-label": t3.addIndicator,
|
|
1904
|
+
"aria-haspopup": "dialog",
|
|
1905
|
+
onClick: () => ctx.store.set({ dialog: { kind: "indicators" } }),
|
|
1906
|
+
children: [
|
|
1907
|
+
/* @__PURE__ */ a2(IndicatorIcon, {}),
|
|
1908
|
+
/* @__PURE__ */ a2("span", { children: t3.indicators })
|
|
1909
|
+
]
|
|
1910
|
+
}
|
|
1911
|
+
),
|
|
1912
|
+
ctx.multi && /* @__PURE__ */ a2(LayoutMenu, { ctx, multi: ctx.multi })
|
|
1913
|
+
] }),
|
|
1914
|
+
/* @__PURE__ */ a2("div", { class: "fnc-sep" }),
|
|
1882
1915
|
ctx.drawingToolbar && /* @__PURE__ */ a2(
|
|
1883
1916
|
"button",
|
|
1884
1917
|
{
|
|
1885
1918
|
class: "fnc-btn fnc-btn-drawbar",
|
|
1886
|
-
|
|
1919
|
+
"data-tip": t3.drawingTools,
|
|
1887
1920
|
"aria-label": t3.drawingTools,
|
|
1888
1921
|
"aria-pressed": s3.drawbarOpen || s3.drawingTool !== null,
|
|
1889
1922
|
onClick: () => ctx.store.set({ drawbarOpen: !s3.drawbarOpen }),
|
|
@@ -1894,20 +1927,20 @@ function Toolbar({ ctx }) {
|
|
|
1894
1927
|
/* @__PURE__ */ a2(
|
|
1895
1928
|
"button",
|
|
1896
1929
|
{
|
|
1897
|
-
class: "fnc-btn",
|
|
1898
|
-
|
|
1930
|
+
class: "fnc-btn fnc-btn-settings",
|
|
1931
|
+
"data-tip": t3.chartSettings,
|
|
1899
1932
|
"aria-label": t3.chartSettings,
|
|
1900
1933
|
"aria-haspopup": "dialog",
|
|
1901
1934
|
onClick: () => ctx.store.set({ dialog: { kind: "chartSettings" } }),
|
|
1902
1935
|
children: /* @__PURE__ */ a2(SettingsIcon, {})
|
|
1903
1936
|
}
|
|
1904
1937
|
),
|
|
1905
|
-
/* @__PURE__ */ a2("button", { class: "fnc-btn fnc-btn-screenshot",
|
|
1938
|
+
/* @__PURE__ */ a2("button", { class: "fnc-btn fnc-btn-screenshot", "data-tip": t3.screenshot, "aria-label": t3.screenshot, onClick: ctx.screenshot, children: /* @__PURE__ */ a2(CameraIcon, {}) }),
|
|
1906
1939
|
/* @__PURE__ */ a2(
|
|
1907
1940
|
"button",
|
|
1908
1941
|
{
|
|
1909
|
-
class: "fnc-btn",
|
|
1910
|
-
|
|
1942
|
+
class: "fnc-btn fnc-btn-fullscreen",
|
|
1943
|
+
"data-tip": s3.fullscreen ? t3.exitFullscreen : t3.fullscreen,
|
|
1911
1944
|
"aria-label": s3.fullscreen ? t3.exitFullscreen : t3.fullscreen,
|
|
1912
1945
|
onClick: ctx.toggleFullscreen,
|
|
1913
1946
|
children: s3.fullscreen ? /* @__PURE__ */ a2(CollapseIcon, {}) : /* @__PURE__ */ a2(ExpandIcon, {})
|
|
@@ -1945,7 +1978,7 @@ function IndicatorItem({ ctx, item }) {
|
|
|
1945
1978
|
"button",
|
|
1946
1979
|
{
|
|
1947
1980
|
class: "fnc-ind-btn fnc-ind-eye",
|
|
1948
|
-
|
|
1981
|
+
"data-tip": item.visible ? t3.hide : t3.show,
|
|
1949
1982
|
"aria-label": `${item.title} ${item.visible ? t3.hide : t3.show}`,
|
|
1950
1983
|
"aria-pressed": !item.visible,
|
|
1951
1984
|
onClick: (e3) => {
|
|
@@ -1956,13 +1989,13 @@ function IndicatorItem({ ctx, item }) {
|
|
|
1956
1989
|
}
|
|
1957
1990
|
),
|
|
1958
1991
|
/* @__PURE__ */ a2("span", { class: "fnc-ind-title", children: item.title }),
|
|
1959
|
-
item.visible && item.values.map((v3) => /* @__PURE__ */ a2("b", { style: { color: v3.color },
|
|
1992
|
+
item.visible && item.values.map((v3) => /* @__PURE__ */ a2("b", { style: { color: v3.color }, "data-tip": v3.label, children: v3.value })),
|
|
1960
1993
|
/* @__PURE__ */ a2("span", { class: "fnc-ind-actions", children: [
|
|
1961
1994
|
/* @__PURE__ */ a2(
|
|
1962
1995
|
"button",
|
|
1963
1996
|
{
|
|
1964
1997
|
class: "fnc-ind-btn",
|
|
1965
|
-
|
|
1998
|
+
"data-tip": t3.indicatorSettings,
|
|
1966
1999
|
"aria-label": `${item.title} ${t3.indicatorSettings}`,
|
|
1967
2000
|
onClick: () => ctx.store.set({ dialog: { kind: "indicatorSettings", id: item.id } }),
|
|
1968
2001
|
children: /* @__PURE__ */ a2(GearIcon, {})
|
|
@@ -1972,7 +2005,7 @@ function IndicatorItem({ ctx, item }) {
|
|
|
1972
2005
|
"button",
|
|
1973
2006
|
{
|
|
1974
2007
|
class: "fnc-ind-btn",
|
|
1975
|
-
|
|
2008
|
+
"data-tip": t3.removeIndicator,
|
|
1976
2009
|
"aria-label": `${item.title} ${t3.removeIndicator}`,
|
|
1977
2010
|
onClick: () => ctx.chart.removeIndicator(item.id),
|
|
1978
2011
|
children: /* @__PURE__ */ a2(SmallCloseIcon, {})
|
|
@@ -2071,7 +2104,7 @@ function Legend({ ctx }) {
|
|
|
2071
2104
|
] }),
|
|
2072
2105
|
values,
|
|
2073
2106
|
!collapsed && overlayItems.map((item) => /* @__PURE__ */ a2(IndicatorItem, { ctx, item })),
|
|
2074
|
-
overlayItems.length > 0 && (collapsed ? /* @__PURE__ */ a2("button", { class: "fnc-ind-handle", "aria-expanded": "false", "aria-label": t3.expand,
|
|
2107
|
+
overlayItems.length > 0 && (collapsed ? /* @__PURE__ */ a2("button", { class: "fnc-ind-handle", "aria-expanded": "false", "aria-label": t3.expand, "data-tip": t3.expand, onClick: () => setCollapsed(false), children: /* @__PURE__ */ a2("span", {}) }) : /* @__PURE__ */ a2("button", { class: "fnc-ind-collapse", "aria-expanded": "true", "aria-label": t3.collapse, "data-tip": t3.collapse, onClick: () => setCollapsed(true), children: /* @__PURE__ */ a2(CollapseLeftIcon, {}) }))
|
|
2075
2108
|
] }),
|
|
2076
2109
|
paneLegends.map(
|
|
2077
2110
|
({ pane, item }) => item && /* @__PURE__ */ a2("div", { class: "fnc-legend fnc-pane-legend", style: { top: `${pane.top + 4}px` }, children: /* @__PURE__ */ a2(IndicatorItem, { ctx, item }) })
|
|
@@ -2087,7 +2120,7 @@ function NavControls({ ctx }) {
|
|
|
2087
2120
|
if (plotWidth <= 0) return null;
|
|
2088
2121
|
const top = panesHeight - CONTROL_OFFSET;
|
|
2089
2122
|
const page = () => Math.max(1, Math.round(plotWidth / ctx.chart.timeScale.barSpacing / 3));
|
|
2090
|
-
const button = (label, onClick, icon) => /* @__PURE__ */ a2("button", { class: "fnc-btn",
|
|
2123
|
+
const button = (label, onClick, icon) => /* @__PURE__ */ a2("button", { class: "fnc-btn", "data-tip": label, "aria-label": label, onClick, children: icon });
|
|
2091
2124
|
return /* @__PURE__ */ a2($, { children: [
|
|
2092
2125
|
showButtons && /* @__PURE__ */ a2("div", { class: "fnc-nav", style: { left: `${plotWidth / 2}px`, top: `${top}px` }, children: [
|
|
2093
2126
|
button(t3.zoomOut, () => ctx.chart.zoom(1 / ZOOM_STEP), /* @__PURE__ */ a2(MinusIcon, {})),
|
|
@@ -2101,7 +2134,7 @@ function NavControls({ ctx }) {
|
|
|
2101
2134
|
{
|
|
2102
2135
|
class: "fnc-realtime",
|
|
2103
2136
|
style: { left: `${plotWidth - 44}px`, top: `${top}px` },
|
|
2104
|
-
|
|
2137
|
+
"data-tip": t3.toRealtime,
|
|
2105
2138
|
"aria-label": t3.toRealtime,
|
|
2106
2139
|
onClick: () => ctx.chart.scrollToRealtime(),
|
|
2107
2140
|
children: /* @__PURE__ */ a2(ToRealtimeIcon, {})
|
|
@@ -2122,7 +2155,7 @@ function Attribution({ ctx }) {
|
|
|
2122
2155
|
href: ATTRIBUTION_URL,
|
|
2123
2156
|
target: "_blank",
|
|
2124
2157
|
rel: "noopener",
|
|
2125
|
-
|
|
2158
|
+
"data-tip": label,
|
|
2126
2159
|
"aria-label": label,
|
|
2127
2160
|
style: { top: `${panesHeight - 36}px` },
|
|
2128
2161
|
children: [
|
|
@@ -2147,7 +2180,7 @@ function PaneMaximize({ ctx, multi }) {
|
|
|
2147
2180
|
{
|
|
2148
2181
|
class: "fnc-btn fnc-pane-max",
|
|
2149
2182
|
style: { left: `${s3.layout.plotWidth - 36}px` },
|
|
2150
|
-
|
|
2183
|
+
"data-tip": `${label} (Alt+Enter)`,
|
|
2151
2184
|
"aria-label": label,
|
|
2152
2185
|
"aria-pressed": maximized,
|
|
2153
2186
|
onClick: () => {
|
|
@@ -2693,6 +2726,45 @@ var CSS = (
|
|
|
2693
2726
|
flex: none;
|
|
2694
2727
|
}
|
|
2695
2728
|
|
|
2729
|
+
/* Tooltip (data-tip). Hosts can restyle it with --fnc-tip-bg / --fnc-tip-text. */
|
|
2730
|
+
.fnc-tip {
|
|
2731
|
+
position: fixed;
|
|
2732
|
+
z-index: 2147483001;
|
|
2733
|
+
max-width: 240px;
|
|
2734
|
+
padding: 6px 10px;
|
|
2735
|
+
border-radius: 8px;
|
|
2736
|
+
background: var(--fnc-tip-bg, #24242b);
|
|
2737
|
+
color: var(--fnc-tip-text, #f2f2f4);
|
|
2738
|
+
font-family: var(--fnc-font);
|
|
2739
|
+
font-size: 12px;
|
|
2740
|
+
font-weight: 500;
|
|
2741
|
+
line-height: 1.4;
|
|
2742
|
+
white-space: nowrap;
|
|
2743
|
+
box-shadow: 0 6px 20px rgb(0 0 0 / 0.28);
|
|
2744
|
+
pointer-events: none;
|
|
2745
|
+
opacity: 0;
|
|
2746
|
+
visibility: hidden;
|
|
2747
|
+
transition: opacity 120ms cubic-bezier(0.4, 0, 1, 1), transform 120ms cubic-bezier(0.4, 0, 1, 1), visibility 0s 120ms;
|
|
2748
|
+
}
|
|
2749
|
+
.fnc-tip[data-side='bottom'] { transform: translateY(-4px); }
|
|
2750
|
+
.fnc-tip[data-side='top'] { transform: translateY(4px); }
|
|
2751
|
+
.fnc-tip[data-side='right'] { transform: translateX(-4px); }
|
|
2752
|
+
.fnc-tip.is-on {
|
|
2753
|
+
opacity: 1;
|
|
2754
|
+
visibility: visible;
|
|
2755
|
+
transform: none;
|
|
2756
|
+
transition: opacity 180ms cubic-bezier(0.16, 1, 0.3, 1), transform 180ms cubic-bezier(0.16, 1, 0.3, 1), visibility 0s;
|
|
2757
|
+
}
|
|
2758
|
+
@media (prefers-reduced-motion: reduce) { .fnc-tip, .fnc-tip.is-on { transform: none; } }
|
|
2759
|
+
@media (hover: none) { .fnc-tip { display: none; } }
|
|
2760
|
+
|
|
2761
|
+
.fnc-tools { display: flex; align-items: center; gap: 4px; flex: none; }
|
|
2762
|
+
/* Right-hand menus open toward the left so they stay on screen. */
|
|
2763
|
+
.fnc-tools .fnc-menu { left: auto; right: 0; }
|
|
2764
|
+
.fnc-kbd-btn { cursor: pointer; }
|
|
2765
|
+
.fnc-kbd-btn:hover, .fnc-sr-foot-btn:hover { color: var(--fnc-text); }
|
|
2766
|
+
.fnc-sr-foot-btn { display: inline-flex; align-items: center; gap: 4px; font-size: inherit; color: inherit; cursor: pointer; }
|
|
2767
|
+
|
|
2696
2768
|
.fnc-up { color: var(--fnc-up); }
|
|
2697
2769
|
.fnc-down { color: var(--fnc-down); }
|
|
2698
2770
|
.fnc-flat { color: var(--fnc-text); }
|
|
@@ -2943,7 +3015,7 @@ var CSS = (
|
|
|
2943
3015
|
content: '';
|
|
2944
3016
|
position: absolute;
|
|
2945
3017
|
inset: 0;
|
|
2946
|
-
border: 1px solid var(--fnc-
|
|
3018
|
+
border: 1px solid var(--fnc-text-2);
|
|
2947
3019
|
pointer-events: none;
|
|
2948
3020
|
z-index: 3;
|
|
2949
3021
|
}
|
|
@@ -2953,7 +3025,7 @@ var CSS = (
|
|
|
2953
3025
|
.fnc-splitter-row::after { inset: 0 -4px; }
|
|
2954
3026
|
.fnc-splitter-col { height: 1px; cursor: row-resize; }
|
|
2955
3027
|
.fnc-splitter-col::after { inset: -4px 0; }
|
|
2956
|
-
.fnc-splitter:hover { background: var(--fnc-
|
|
3028
|
+
.fnc-splitter:hover { background: var(--fnc-text-2); }
|
|
2957
3029
|
.fnc-resizing-x, .fnc-resizing-x * { cursor: col-resize !important; user-select: none; }
|
|
2958
3030
|
.fnc-resizing-y, .fnc-resizing-y * { cursor: row-resize !important; user-select: none; }
|
|
2959
3031
|
.fnc-parking { display: none; }
|
|
@@ -3004,7 +3076,7 @@ var CSS = (
|
|
|
3004
3076
|
background: var(--fnc-surface);
|
|
3005
3077
|
font-size: 11px;
|
|
3006
3078
|
}
|
|
3007
|
-
.fnc-pane-tab[aria-selected='true'] .fnc-pane-tab-num { background: var(--fnc-
|
|
3079
|
+
.fnc-pane-tab[aria-selected='true'] .fnc-pane-tab-num { background: var(--fnc-text-2); color: var(--fnc-bg); }
|
|
3008
3080
|
.fnc-layout-menu { min-width: 0; gap: 2px; padding: 8px; }
|
|
3009
3081
|
.fnc-layout-row { display: flex; align-items: center; gap: 2px; }
|
|
3010
3082
|
.fnc-layout-count { width: 16px; flex: none; font-size: 12px; color: var(--fnc-text-2); text-align: center; }
|
|
@@ -3017,7 +3089,7 @@ var CSS = (
|
|
|
3017
3089
|
color: var(--fnc-text-2);
|
|
3018
3090
|
}
|
|
3019
3091
|
.fnc-layout-opt:hover { background: var(--fnc-surface); color: var(--fnc-text); }
|
|
3020
|
-
.fnc-layout-opt[aria-checked='true'] { background: var(--fnc-surface); color: var(--fnc-
|
|
3092
|
+
.fnc-layout-opt[aria-checked='true'] { background: var(--fnc-surface); color: var(--fnc-text); }
|
|
3021
3093
|
.fnc-sync-menu { min-width: 220px; }
|
|
3022
3094
|
.fnc-menu-title { display: flex; flex-direction: column; gap: 2px; padding: 6px 10px 8px; font-size: 13px; font-weight: 600; color: var(--fnc-text); }
|
|
3023
3095
|
.fnc-menu-title small { font-size: 12px; font-weight: 400; color: var(--fnc-text-2); }
|
|
@@ -3025,9 +3097,8 @@ var CSS = (
|
|
|
3025
3097
|
.fnc-sync-item[aria-checked='true'] { background: none; color: var(--fnc-text); }
|
|
3026
3098
|
.fnc-sync-item:hover { background: var(--fnc-surface); }
|
|
3027
3099
|
.fnc-sync-item .fnc-switch { display: inline-block; transform: scale(0.8); transform-origin: right center; }
|
|
3028
|
-
.fnc-switch[data-on='true'] { background: var(--fnc-
|
|
3100
|
+
.fnc-switch[data-on='true'] { background: var(--fnc-text-2); }
|
|
3029
3101
|
.fnc-switch[data-on='true']::after { transform: translateX(16px); }
|
|
3030
|
-
.fnc-btn-sync[aria-pressed='true'] { color: var(--fnc-accent); }
|
|
3031
3102
|
|
|
3032
3103
|
/* \u2500\u2500 Mobile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3033
3104
|
@media (max-width: 640px) {
|
|
@@ -3107,6 +3178,77 @@ function div(className, parent) {
|
|
|
3107
3178
|
parent?.appendChild(el);
|
|
3108
3179
|
return el;
|
|
3109
3180
|
}
|
|
3181
|
+
function bindTooltips(root) {
|
|
3182
|
+
const tip = div("fnc-tip", root);
|
|
3183
|
+
tip.setAttribute("role", "tooltip");
|
|
3184
|
+
tip.id = `fnc-tip-${Math.random().toString(36).slice(2, 8)}`;
|
|
3185
|
+
let current = null;
|
|
3186
|
+
let timer;
|
|
3187
|
+
let hiddenAt = 0;
|
|
3188
|
+
const place = (el) => {
|
|
3189
|
+
const r3 = el.getBoundingClientRect();
|
|
3190
|
+
const w3 = tip.offsetWidth;
|
|
3191
|
+
const h3 = tip.offsetHeight;
|
|
3192
|
+
const vw = window.innerWidth;
|
|
3193
|
+
const vh = window.innerHeight;
|
|
3194
|
+
let side = el.closest(".fnc-drawbar") ? "right" : el.closest(".fnc-nav") ? "top" : "bottom";
|
|
3195
|
+
if (side === "bottom" && r3.bottom + h3 + 10 > vh) side = "top";
|
|
3196
|
+
let left = side === "right" ? r3.right + 8 : r3.left + r3.width / 2 - w3 / 2;
|
|
3197
|
+
const top = side === "right" ? r3.top + r3.height / 2 - h3 / 2 : side === "top" ? r3.top - h3 - 6 : r3.bottom + 6;
|
|
3198
|
+
left = Math.max(4, Math.min(vw - w3 - 4, left));
|
|
3199
|
+
tip.style.left = `${Math.round(left)}px`;
|
|
3200
|
+
tip.style.top = `${Math.round(top)}px`;
|
|
3201
|
+
tip.dataset.side = side;
|
|
3202
|
+
};
|
|
3203
|
+
const show = (el) => {
|
|
3204
|
+
const text = el.dataset.tip;
|
|
3205
|
+
if (!text || !el.isConnected) return;
|
|
3206
|
+
tip.textContent = text;
|
|
3207
|
+
el.setAttribute("aria-describedby", tip.id);
|
|
3208
|
+
place(el);
|
|
3209
|
+
tip.classList.add("is-on");
|
|
3210
|
+
};
|
|
3211
|
+
const hide = () => {
|
|
3212
|
+
clearTimeout(timer);
|
|
3213
|
+
if (tip.classList.contains("is-on")) hiddenAt = Date.now();
|
|
3214
|
+
tip.classList.remove("is-on");
|
|
3215
|
+
current?.removeAttribute("aria-describedby");
|
|
3216
|
+
current = null;
|
|
3217
|
+
};
|
|
3218
|
+
const target = (e3) => e3.target instanceof Element ? e3.target.closest("[data-tip]") : null;
|
|
3219
|
+
const onOver = (e3) => {
|
|
3220
|
+
if (e3.pointerType === "touch") return;
|
|
3221
|
+
const el = target(e3);
|
|
3222
|
+
if (el === current) return;
|
|
3223
|
+
hide();
|
|
3224
|
+
if (!el || !root.contains(el)) return;
|
|
3225
|
+
current = el;
|
|
3226
|
+
timer = setTimeout(() => show(el), Date.now() - hiddenAt < 300 ? 0 : 350);
|
|
3227
|
+
};
|
|
3228
|
+
const onFocus = (e3) => {
|
|
3229
|
+
const el = target(e3);
|
|
3230
|
+
if (!el || !e3.target.matches?.(":focus-visible")) return;
|
|
3231
|
+
hide();
|
|
3232
|
+
current = el;
|
|
3233
|
+
show(el);
|
|
3234
|
+
};
|
|
3235
|
+
root.addEventListener("pointerover", onOver);
|
|
3236
|
+
root.addEventListener("pointerleave", hide);
|
|
3237
|
+
root.addEventListener("pointerdown", hide, true);
|
|
3238
|
+
root.addEventListener("wheel", hide, { passive: true });
|
|
3239
|
+
root.addEventListener("focusin", onFocus);
|
|
3240
|
+
root.addEventListener("focusout", hide);
|
|
3241
|
+
return () => {
|
|
3242
|
+
hide();
|
|
3243
|
+
root.removeEventListener("pointerover", onOver);
|
|
3244
|
+
root.removeEventListener("pointerleave", hide);
|
|
3245
|
+
root.removeEventListener("pointerdown", hide, true);
|
|
3246
|
+
root.removeEventListener("wheel", hide);
|
|
3247
|
+
root.removeEventListener("focusin", onFocus);
|
|
3248
|
+
root.removeEventListener("focusout", hide);
|
|
3249
|
+
tip.remove();
|
|
3250
|
+
};
|
|
3251
|
+
}
|
|
3110
3252
|
function createShell(container, options) {
|
|
3111
3253
|
injectStyles(container.ownerDocument);
|
|
3112
3254
|
const storage = createStorage(options.storageKey);
|
|
@@ -3133,6 +3275,7 @@ function createShell(container, options) {
|
|
|
3133
3275
|
bottom: div("fnc-slot fnc-slot-bottom"),
|
|
3134
3276
|
footer: div("fnc-slot fnc-slot-footer")
|
|
3135
3277
|
};
|
|
3278
|
+
const unbindTips = bindTooltips(root);
|
|
3136
3279
|
const body = div("fnc-body", root);
|
|
3137
3280
|
const drawbarHost = options.drawingToolbar ? div("fnc-drawbar-host", body) : null;
|
|
3138
3281
|
const main = div("fnc-main", body);
|
|
@@ -3198,6 +3341,7 @@ function createShell(container, options) {
|
|
|
3198
3341
|
options.onFavoriteIntervalsChange?.(favoriteIntervals);
|
|
3199
3342
|
},
|
|
3200
3343
|
destroy: () => {
|
|
3344
|
+
unbindTips();
|
|
3201
3345
|
document.removeEventListener("fullscreenchange", onFullscreenChange);
|
|
3202
3346
|
darkQuery?.removeEventListener?.("change", onSchemeChange);
|
|
3203
3347
|
if (isNativeFullscreen()) void document.exitFullscreen();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@funnest/charts-ui",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Pro trading UI (toolbar, drawing tools, sheets) for Funnest Charts. Framework-agnostic.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chart",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"NOTICE"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@funnest/charts": "0.5.
|
|
45
|
+
"@funnest/charts": "0.5.2"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"preact": "^11.2.0"
|