@funnest/charts-ui 0.6.13 → 0.6.15
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/context.d.ts +12 -0
- package/dist/i18n.d.ts +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +102 -7
- package/dist/pane.d.ts +3 -1
- package/dist/trading-chart.d.ts +8 -1
- package/package.json +2 -2
package/dist/context.d.ts
CHANGED
|
@@ -60,6 +60,15 @@ export interface SearchCategory {
|
|
|
60
60
|
label: Record<Locale, string>;
|
|
61
61
|
match(info: SymbolInfo): boolean;
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* An exchange listed in the symbol search sidebar from the start (before any results), with its
|
|
65
|
+
* logo. `name` is the `SymbolInfo.exchange` its symbols carry; `label` what to show.
|
|
66
|
+
*/
|
|
67
|
+
export interface SearchExchange {
|
|
68
|
+
name: string;
|
|
69
|
+
label?: Record<Locale, string>;
|
|
70
|
+
logoUrl?: string;
|
|
71
|
+
}
|
|
63
72
|
/** Everything components need; created once per widget. */
|
|
64
73
|
export interface WidgetContext {
|
|
65
74
|
/** The widget's root element (theme variables live here). */
|
|
@@ -70,6 +79,9 @@ export interface WidgetContext {
|
|
|
70
79
|
storage: WidgetStorage;
|
|
71
80
|
intervalGroups: readonly IntervalGroup[];
|
|
72
81
|
searchCategories: readonly SearchCategory[];
|
|
82
|
+
searchExchanges: readonly SearchExchange[];
|
|
83
|
+
/** Rows per exchange before a "모두 보기" (0: all). */
|
|
84
|
+
searchPreviewPerExchange: number;
|
|
73
85
|
/** IANA zone used for the status-bar clock (KST for Korean users by default). */
|
|
74
86
|
displayTimezone: string;
|
|
75
87
|
showLogo: boolean;
|
package/dist/i18n.d.ts
CHANGED
|
@@ -124,6 +124,7 @@ export declare const STRINGS: {
|
|
|
124
124
|
allSymbols: string;
|
|
125
125
|
favorites: string;
|
|
126
126
|
exchanges: string;
|
|
127
|
+
showAllIn: string;
|
|
127
128
|
noFavorites: string;
|
|
128
129
|
navigate: string;
|
|
129
130
|
openAction: string;
|
|
@@ -268,6 +269,7 @@ export declare const STRINGS: {
|
|
|
268
269
|
allSymbols: string;
|
|
269
270
|
favorites: string;
|
|
270
271
|
exchanges: string;
|
|
272
|
+
showAllIn: string;
|
|
271
273
|
noFavorites: string;
|
|
272
274
|
navigate: string;
|
|
273
275
|
openAction: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export { createMultiChart } from './multi-chart';
|
|
|
8
8
|
export type { MultiChart, MultiChartEvents, MultiChartOptions, MultiChartState, PaneSpec } from './multi-chart';
|
|
9
9
|
export { LAYOUT_GROUPS, LAYOUTS, MAX_PANES, paneCount } from './layouts';
|
|
10
10
|
export type { LayoutId, SplitNode, SplitSizes } from './layouts';
|
|
11
|
-
export type { ContextMenuItem, ContextMenuItems, IntervalGroup, LayoutSync, SearchCategory } from './context';
|
|
11
|
+
export type { ContextMenuItem, ContextMenuItems, IntervalGroup, LayoutSync, SearchCategory, SearchExchange } from './context';
|
|
12
12
|
export type { ColorScheme, TradingChart, TradingChartOptions, TradingChartSlots } from './trading-chart';
|
|
13
13
|
export { resolutionLabel } from './i18n';
|
package/dist/index.js
CHANGED
|
@@ -549,6 +549,7 @@ var STRINGS = {
|
|
|
549
549
|
allSymbols: "\uC804\uCCB4",
|
|
550
550
|
favorites: "\uC990\uACA8\uCC3E\uAE30",
|
|
551
551
|
exchanges: "\uAC70\uB798\uC18C",
|
|
552
|
+
showAllIn: "{exchange} {n}\uAC1C \uBAA8\uB450 \uBCF4\uAE30 \u203A",
|
|
552
553
|
noFavorites: "\uC990\uACA8\uCC3E\uAE30\uD55C \uC885\uBAA9\uC774 \uC5C6\uC5B4\uC694. \u2606\uB97C \uB20C\uB7EC \uCD94\uAC00\uD574 \uBCF4\uC138\uC694",
|
|
553
554
|
navigate: "\uC774\uB3D9",
|
|
554
555
|
openAction: "\uC5F4\uAE30",
|
|
@@ -693,6 +694,7 @@ var STRINGS = {
|
|
|
693
694
|
allSymbols: "All",
|
|
694
695
|
favorites: "Favorites",
|
|
695
696
|
exchanges: "Exchanges",
|
|
697
|
+
showAllIn: "All {n} on {exchange} \u203A",
|
|
696
698
|
noFavorites: "No favorites yet \u2014 tap \u2606 to add one",
|
|
697
699
|
navigate: "navigate",
|
|
698
700
|
openAction: "open",
|
|
@@ -1836,6 +1838,41 @@ function Highlight({ text, query }) {
|
|
|
1836
1838
|
parts.push(text.slice(i3));
|
|
1837
1839
|
return /* @__PURE__ */ a3($, { children: parts });
|
|
1838
1840
|
}
|
|
1841
|
+
var sparkCache = /* @__PURE__ */ new Map();
|
|
1842
|
+
var SPARK_TTL = 12e4;
|
|
1843
|
+
var SPARK_DWELL_MS = 300;
|
|
1844
|
+
function LazySparkline({ ctx, info, up }) {
|
|
1845
|
+
const ref = T2(null);
|
|
1846
|
+
const [values, setValues] = d2(info.sparkline ?? null);
|
|
1847
|
+
A2(() => {
|
|
1848
|
+
if (info.sparkline || !ctx.datafeed.getSparkline || !ref.current) return;
|
|
1849
|
+
let alive = true;
|
|
1850
|
+
const load = () => {
|
|
1851
|
+
let hit = sparkCache.get(info.symbol);
|
|
1852
|
+
if (!hit || Date.now() - hit.at > SPARK_TTL) {
|
|
1853
|
+
hit = { at: Date.now(), values: ctx.datafeed.getSparkline(info.symbol).catch(() => []) };
|
|
1854
|
+
sparkCache.set(info.symbol, hit);
|
|
1855
|
+
}
|
|
1856
|
+
void hit.values.then((v3) => alive && setValues(v3));
|
|
1857
|
+
};
|
|
1858
|
+
let timer;
|
|
1859
|
+
const io = new IntersectionObserver((entries) => {
|
|
1860
|
+
clearTimeout(timer);
|
|
1861
|
+
if (!entries.some((e3) => e3.isIntersecting)) return;
|
|
1862
|
+
timer = setTimeout(() => {
|
|
1863
|
+
io.disconnect();
|
|
1864
|
+
load();
|
|
1865
|
+
}, SPARK_DWELL_MS);
|
|
1866
|
+
});
|
|
1867
|
+
io.observe(ref.current);
|
|
1868
|
+
return () => {
|
|
1869
|
+
alive = false;
|
|
1870
|
+
clearTimeout(timer);
|
|
1871
|
+
io.disconnect();
|
|
1872
|
+
};
|
|
1873
|
+
}, [info.symbol]);
|
|
1874
|
+
return /* @__PURE__ */ a3("span", { ref, class: "fnc-sr-spark-slot", children: values && /* @__PURE__ */ a3(Sparkline, { values, up }) });
|
|
1875
|
+
}
|
|
1839
1876
|
function Sparkline({ values, up }) {
|
|
1840
1877
|
if (values.length < 2) return null;
|
|
1841
1878
|
const min = Math.min(...values);
|
|
@@ -1855,6 +1892,7 @@ function SymbolSearch({ ctx }) {
|
|
|
1855
1892
|
const [exchange, setExchange] = d2(null);
|
|
1856
1893
|
const [results, setResults] = d2(null);
|
|
1857
1894
|
const [loading, setLoading] = d2(true);
|
|
1895
|
+
const [pending, setPending] = d2(true);
|
|
1858
1896
|
const [recent, setRecent] = d2(() => ctx.storage.get(RECENT_KEY2, []));
|
|
1859
1897
|
const [favorites, setFavorites] = d2(() => ctx.storage.get(FAVORITE_KEY, []));
|
|
1860
1898
|
const [active, setActive] = d2(0);
|
|
@@ -1864,8 +1902,19 @@ function SymbolSearch({ ctx }) {
|
|
|
1864
1902
|
A2(() => {
|
|
1865
1903
|
let alive = true;
|
|
1866
1904
|
setLoading(true);
|
|
1905
|
+
setPending(true);
|
|
1867
1906
|
const id = setTimeout(() => {
|
|
1868
|
-
|
|
1907
|
+
const feed = ctx.datafeed;
|
|
1908
|
+
const search = feed.searchSymbolsProgressive ? feed.searchSymbolsProgressive(query.trim(), (partial) => {
|
|
1909
|
+
if (!alive) return;
|
|
1910
|
+
setResults(partial);
|
|
1911
|
+
setLoading(false);
|
|
1912
|
+
}) : feed.searchSymbols?.(query.trim());
|
|
1913
|
+
search?.then((items) => alive && setResults(items)).catch(() => alive && setResults([])).finally(() => {
|
|
1914
|
+
if (!alive) return;
|
|
1915
|
+
setLoading(false);
|
|
1916
|
+
setPending(false);
|
|
1917
|
+
});
|
|
1869
1918
|
}, DEBOUNCE_MS);
|
|
1870
1919
|
return () => {
|
|
1871
1920
|
alive = false;
|
|
@@ -1879,14 +1928,33 @@ function SymbolSearch({ ctx }) {
|
|
|
1879
1928
|
const exchanges = w2(() => {
|
|
1880
1929
|
const counts = /* @__PURE__ */ new Map();
|
|
1881
1930
|
for (const r3 of results ?? []) if (matchCategory(r3)) counts.set(r3.exchange, (counts.get(r3.exchange) ?? 0) + 1);
|
|
1882
|
-
|
|
1931
|
+
const declared = ctx.searchExchanges.map((e3) => ({ ...e3, count: counts.get(e3.name) }));
|
|
1932
|
+
const others = [...counts.entries()].filter(([name]) => !ctx.searchExchanges.some((e3) => e3.name === name)).sort((a4, b) => b[1] - a4[1]).map(([name, count]) => ({ name, label: void 0, logoUrl: void 0, count }));
|
|
1933
|
+
return [...declared, ...others];
|
|
1883
1934
|
}, [results, category]);
|
|
1884
1935
|
const q2 = query.trim().toLowerCase();
|
|
1885
1936
|
const favoriteRows = filter(favorites).filter((f4) => !q2 || f4.name.toLowerCase().includes(q2) || f4.symbol.toLowerCase().includes(q2));
|
|
1886
1937
|
const showRecent = view.kind === "all" && !q2 && recent.length > 0;
|
|
1887
1938
|
const recentRows = showRecent ? filter(recent) : [];
|
|
1888
|
-
const
|
|
1939
|
+
const allResults = view.kind === "favorites" ? favoriteRows : filter(results ?? []);
|
|
1940
|
+
const preview = ctx.searchPreviewPerExchange;
|
|
1941
|
+
const more = /* @__PURE__ */ new Map();
|
|
1942
|
+
let resultRows = allResults;
|
|
1943
|
+
if (preview > 0 && view.kind === "all" && !exchange) {
|
|
1944
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1945
|
+
const total = /* @__PURE__ */ new Map();
|
|
1946
|
+
for (const r3 of allResults) total.set(r3.exchange, (total.get(r3.exchange) ?? 0) + 1);
|
|
1947
|
+
resultRows = [];
|
|
1948
|
+
for (const r3 of allResults) {
|
|
1949
|
+
const n2 = (seen.get(r3.exchange) ?? 0) + 1;
|
|
1950
|
+
seen.set(r3.exchange, n2);
|
|
1951
|
+
if (n2 > preview) continue;
|
|
1952
|
+
resultRows.push(r3);
|
|
1953
|
+
if (n2 === preview && (total.get(r3.exchange) ?? 0) > preview) more.set(resultRows.length - 1, { exchange: r3.exchange, count: total.get(r3.exchange) });
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1889
1956
|
const rows = [...recentRows, ...resultRows];
|
|
1957
|
+
const exchangeLabel = (name) => ctx.searchExchanges.find((e3) => e3.name === name)?.label?.[locale] ?? name;
|
|
1890
1958
|
A2(() => setActive(0), [query, category, exchange, view, results]);
|
|
1891
1959
|
A2(() => {
|
|
1892
1960
|
listRef.current?.querySelector(`[data-index="${active}"]`)?.scrollIntoView({ block: "nearest" });
|
|
@@ -1957,7 +2025,7 @@ function SymbolSearch({ ctx }) {
|
|
|
1957
2025
|
cat && ` \xB7 ${cat.label[locale]}`
|
|
1958
2026
|
] })
|
|
1959
2027
|
] }),
|
|
1960
|
-
info.sparkline && /* @__PURE__ */ a3(
|
|
2028
|
+
(info.sparkline || ctx.datafeed.getSparkline) && /* @__PURE__ */ a3(LazySparkline, { ctx, info, up }, info.symbol),
|
|
1961
2029
|
info.price !== void 0 && /* @__PURE__ */ a3("span", { class: "fnc-sr-quote", children: [
|
|
1962
2030
|
/* @__PURE__ */ a3("b", { children: formatPrice(info.price, info.pricePrecision) }),
|
|
1963
2031
|
info.changePercent !== void 0 && /* @__PURE__ */ a3("span", { class: trend, children: [
|
|
@@ -1983,7 +2051,8 @@ function SymbolSearch({ ctx }) {
|
|
|
1983
2051
|
}
|
|
1984
2052
|
);
|
|
1985
2053
|
};
|
|
1986
|
-
const sideItem = (label, selected, onClick, extra) => /* @__PURE__ */ a3("button", { class: "fnc-sr-side-item", "aria-pressed": selected, onClick, children: [
|
|
2054
|
+
const sideItem = (label, selected, onClick, extra, logoUrl) => /* @__PURE__ */ a3("button", { class: "fnc-sr-side-item", "aria-pressed": selected, onClick, children: [
|
|
2055
|
+
logoUrl !== void 0 && (logoUrl ? /* @__PURE__ */ a3("img", { class: "fnc-sr-side-logo", src: logoUrl, alt: "", "aria-hidden": "true" }) : /* @__PURE__ */ a3("i", { class: "fnc-sr-side-logo", "aria-hidden": "true" })),
|
|
1987
2056
|
/* @__PURE__ */ a3("span", { children: label }),
|
|
1988
2057
|
extra
|
|
1989
2058
|
] });
|
|
@@ -2019,7 +2088,13 @@ function SymbolSearch({ ctx }) {
|
|
|
2019
2088
|
sideItem(t3.favorites, view.kind === "favorites", () => (setView({ kind: "favorites" }), setExchange(null)), /* @__PURE__ */ a3("em", { children: favorites.length || "" })),
|
|
2020
2089
|
exchanges.length > 0 && /* @__PURE__ */ a3("div", { class: "fnc-sr-side-title", children: t3.exchanges }),
|
|
2021
2090
|
exchanges.map(
|
|
2022
|
-
(
|
|
2091
|
+
(x2) => sideItem(
|
|
2092
|
+
x2.label?.[locale] ?? x2.name,
|
|
2093
|
+
exchange === x2.name,
|
|
2094
|
+
() => (setView({ kind: "all" }), setExchange(exchange === x2.name ? null : x2.name)),
|
|
2095
|
+
/* @__PURE__ */ a3("em", { children: x2.count ?? (pending ? "" : 0) }),
|
|
2096
|
+
ctx.searchExchanges.length ? x2.logoUrl ?? "" : void 0
|
|
2097
|
+
)
|
|
2023
2098
|
)
|
|
2024
2099
|
] }),
|
|
2025
2100
|
/* @__PURE__ */ a3("div", { class: "fnc-sr-list fnc-scroll", id: "fnc-search-results", role: "listbox", ref: listRef, children: [
|
|
@@ -2029,7 +2104,13 @@ function SymbolSearch({ ctx }) {
|
|
|
2029
2104
|
] }),
|
|
2030
2105
|
recentRows.map((info, i3) => row2(info, i3, true)),
|
|
2031
2106
|
(recentRows.length > 0 || view.kind === "favorites") && /* @__PURE__ */ a3("div", { class: "fnc-sr-section", children: view.kind === "favorites" ? t3.favorites : t3.symbols }),
|
|
2032
|
-
loading && !results && view.kind === "all" ? Array.from({ length: 6 }, () => /* @__PURE__ */ a3("div", { class: "fnc-sr-skeleton", "aria-hidden": "true" })) : resultRows.map((info, i3) =>
|
|
2107
|
+
loading && !results && view.kind === "all" ? Array.from({ length: 6 }, () => /* @__PURE__ */ a3("div", { class: "fnc-sr-skeleton", "aria-hidden": "true" })) : resultRows.map((info, i3) => {
|
|
2108
|
+
const m3 = more.get(i3);
|
|
2109
|
+
return m3 ? /* @__PURE__ */ a3($, { children: [
|
|
2110
|
+
row2(info, recentRows.length + i3, false),
|
|
2111
|
+
/* @__PURE__ */ a3("button", { class: "fnc-sr-more", onClick: () => (setView({ kind: "all" }), setExchange(m3.exchange)), children: t3.showAllIn.replace("{exchange}", exchangeLabel(m3.exchange)).replace("{n}", m3.count.toLocaleString(locale === "ko" ? "ko-KR" : "en-US")) })
|
|
2112
|
+
] }) : row2(info, recentRows.length + i3, false);
|
|
2113
|
+
}),
|
|
2033
2114
|
!loading && rows.length === 0 && /* @__PURE__ */ a3("div", { class: "fnc-empty", children: view.kind === "favorites" && favorites.length === 0 ? t3.noFavorites : t3.noResults })
|
|
2034
2115
|
] })
|
|
2035
2116
|
] }),
|
|
@@ -3170,6 +3251,10 @@ var CSS = (
|
|
|
3170
3251
|
}
|
|
3171
3252
|
.fnc-sr-side-item span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
3172
3253
|
.fnc-sr-side-item em { font-style: normal; font-size: 12px; color: var(--fnc-text-2); }
|
|
3254
|
+
.fnc-sr-side-logo { flex: none; width: 18px; height: 18px; border-radius: 5px; object-fit: cover; background: var(--fnc-surface); }
|
|
3255
|
+
.fnc-sr-spark-slot { display: inline-flex; flex: none; width: 72px; height: 24px; }
|
|
3256
|
+
.fnc-sr-more { display: block; width: calc(100% - 16px); margin: 2px 8px 8px; padding: 8px 12px; border-radius: var(--fnc-radius); background: var(--fnc-surface); color: var(--fnc-text-2); font-size: 13px; font-weight: 600; text-align: left; }
|
|
3257
|
+
.fnc-sr-more:hover { color: var(--fnc-text); }
|
|
3173
3258
|
.fnc-sr-side-item:hover { background: var(--fnc-surface); }
|
|
3174
3259
|
.fnc-sr-side-item[aria-pressed='true'] { background: var(--fnc-surface); font-weight: 700; }
|
|
3175
3260
|
.fnc-chip-token {
|
|
@@ -4196,6 +4281,8 @@ function createPane(shell, config) {
|
|
|
4196
4281
|
storage: shell.storage,
|
|
4197
4282
|
intervalGroups: config.intervalGroups,
|
|
4198
4283
|
searchCategories: config.searchCategories,
|
|
4284
|
+
searchExchanges: config.searchExchanges ?? [],
|
|
4285
|
+
searchPreviewPerExchange: config.searchPreviewPerExchange ?? 0,
|
|
4199
4286
|
displayTimezone: config.displayTimezone,
|
|
4200
4287
|
showLogo: config.symbolLogo,
|
|
4201
4288
|
searchHotkey: config.searchHotkey,
|
|
@@ -4270,6 +4357,8 @@ function createTradingChart(container, options) {
|
|
|
4270
4357
|
favoriteIntervals,
|
|
4271
4358
|
onFavoriteIntervalsChange,
|
|
4272
4359
|
searchCategories = DEFAULT_SEARCH_CATEGORIES,
|
|
4360
|
+
searchExchanges = [],
|
|
4361
|
+
searchPreviewPerExchange = 0,
|
|
4273
4362
|
storageKey = "funnest-charts",
|
|
4274
4363
|
searchHotkey = true,
|
|
4275
4364
|
symbolLogo = true,
|
|
@@ -4299,6 +4388,8 @@ function createTradingChart(container, options) {
|
|
|
4299
4388
|
chartType,
|
|
4300
4389
|
intervalGroups,
|
|
4301
4390
|
searchCategories,
|
|
4391
|
+
searchExchanges,
|
|
4392
|
+
searchPreviewPerExchange,
|
|
4302
4393
|
symbolLogo,
|
|
4303
4394
|
searchHotkey,
|
|
4304
4395
|
drawingToolbar,
|
|
@@ -4368,6 +4459,8 @@ function createMultiChart(container, options) {
|
|
|
4368
4459
|
favoriteIntervals,
|
|
4369
4460
|
onFavoriteIntervalsChange,
|
|
4370
4461
|
searchCategories = DEFAULT_SEARCH_CATEGORIES,
|
|
4462
|
+
searchExchanges = [],
|
|
4463
|
+
searchPreviewPerExchange = 0,
|
|
4371
4464
|
storageKey = "funnest-charts",
|
|
4372
4465
|
searchHotkey = true,
|
|
4373
4466
|
symbolLogo = true,
|
|
@@ -4438,6 +4531,8 @@ function createMultiChart(container, options) {
|
|
|
4438
4531
|
chartType,
|
|
4439
4532
|
intervalGroups,
|
|
4440
4533
|
searchCategories,
|
|
4534
|
+
searchExchanges,
|
|
4535
|
+
searchPreviewPerExchange,
|
|
4441
4536
|
symbolLogo,
|
|
4442
4537
|
searchHotkey,
|
|
4443
4538
|
drawingToolbar,
|
package/dist/pane.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @jsxImportSource preact */
|
|
2
2
|
import { type Chart, type ChartOptions, type ChartType, type Datafeed, type Resolution } from '@funnest/charts';
|
|
3
|
-
import type { ContextMenuItems, IntervalGroup, MultiControls, SearchCategory, UiState, WidgetContext } from './context';
|
|
3
|
+
import type { ContextMenuItems, IntervalGroup, MultiControls, SearchCategory, SearchExchange, UiState, WidgetContext } from './context';
|
|
4
4
|
import { type Shell } from './shell';
|
|
5
5
|
import { Store } from './store';
|
|
6
6
|
export interface PaneConfig {
|
|
@@ -11,6 +11,8 @@ export interface PaneConfig {
|
|
|
11
11
|
chartType: ChartType;
|
|
12
12
|
intervalGroups: readonly IntervalGroup[];
|
|
13
13
|
searchCategories: readonly SearchCategory[];
|
|
14
|
+
searchExchanges?: readonly SearchExchange[];
|
|
15
|
+
searchPreviewPerExchange?: number;
|
|
14
16
|
symbolLogo: boolean;
|
|
15
17
|
drawingToolbar: boolean;
|
|
16
18
|
attribution: boolean;
|
package/dist/trading-chart.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @jsxImportSource preact */
|
|
2
2
|
import { type Chart, type ChartOptions, type ChartType, type Datafeed, type Locale, type ChartState, type Resolution, type ThemeTokens } from '@funnest/charts';
|
|
3
|
-
import type { ContextMenuItems, IntervalGroup, SearchCategory } from './context';
|
|
3
|
+
import type { ContextMenuItems, IntervalGroup, SearchCategory, SearchExchange } from './context';
|
|
4
4
|
import { type ColorScheme, type TradingChartSlots } from './shell';
|
|
5
5
|
export type { ColorScheme, TradingChartSlots } from './shell';
|
|
6
6
|
/** Interval menu: 분 | 시간 | 일. '12M' is shown as 1년. */
|
|
@@ -22,6 +22,13 @@ export interface TradingChartOptions extends Omit<ChartOptions, 'datafeed'> {
|
|
|
22
22
|
onFavoriteIntervalsChange?: (intervals: Resolution[]) => void;
|
|
23
23
|
/** Symbol search tabs. */
|
|
24
24
|
searchCategories?: readonly SearchCategory[];
|
|
25
|
+
/** Exchanges listed in the symbol search sidebar from the start, with logos (counts fill in as results come). */
|
|
26
|
+
searchExchanges?: readonly SearchExchange[];
|
|
27
|
+
/**
|
|
28
|
+
* Symbol search: rows per exchange shown at first, each followed by "N개 모두 보기" when there
|
|
29
|
+
* are more (picking the exchange lists them all). Default 0: everything at once.
|
|
30
|
+
*/
|
|
31
|
+
searchPreviewPerExchange?: number;
|
|
25
32
|
/**
|
|
26
33
|
* localStorage key prefix for UI preferences (favorite intervals, recent searches).
|
|
27
34
|
* Default 'funnest-charts'. Pass null to keep them in memory only.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@funnest/charts-ui",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.15",
|
|
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.6.
|
|
45
|
+
"@funnest/charts": "0.6.15"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"preact": "^11.2.0"
|