@tradecanvas/chart 1.71.0 → 1.72.1
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/LayoutSession-DO4bYkUi.cjs +2 -0
- package/dist/LayoutSession-DO4bYkUi.cjs.map +1 -0
- package/dist/{LayoutSession-BOQCN6yY.js → LayoutSession-qRYG8GTD.js} +539 -552
- package/dist/LayoutSession-qRYG8GTD.js.map +1 -0
- package/dist/WidgetCommandPalette-CeCLHPy1.js +177 -0
- package/dist/WidgetCommandPalette-CeCLHPy1.js.map +1 -0
- package/dist/WidgetCommandPalette-ZZNbWwCZ.cjs +2 -0
- package/dist/WidgetCommandPalette-ZZNbWwCZ.cjs.map +1 -0
- package/dist/WidgetDrawingSettings-BeW8fX7r.js +474 -0
- package/dist/WidgetDrawingSettings-BeW8fX7r.js.map +1 -0
- package/dist/WidgetDrawingSettings-Cyl2u_u8.cjs +2 -0
- package/dist/WidgetDrawingSettings-Cyl2u_u8.cjs.map +1 -0
- package/dist/WidgetGoToDate-BNdngHlg.cjs +2 -0
- package/dist/WidgetGoToDate-BNdngHlg.cjs.map +1 -0
- package/dist/WidgetGoToDate-hcDtezRm.js +191 -0
- package/dist/WidgetGoToDate-hcDtezRm.js.map +1 -0
- package/dist/WidgetHotkeySheet-1lRFSdvt.js +416 -0
- package/dist/WidgetHotkeySheet-1lRFSdvt.js.map +1 -0
- package/dist/WidgetHotkeySheet-y5LWKSG6.cjs +2 -0
- package/dist/WidgetHotkeySheet-y5LWKSG6.cjs.map +1 -0
- package/dist/WidgetIndicatorPicker-CGvZ5kYd.js +245 -0
- package/dist/WidgetIndicatorPicker-CGvZ5kYd.js.map +1 -0
- package/dist/WidgetIndicatorPicker-DuKJFPRC.cjs +2 -0
- package/dist/WidgetIndicatorPicker-DuKJFPRC.cjs.map +1 -0
- package/dist/WidgetIndicatorSettings-C7vpco6e.cjs +2 -0
- package/dist/WidgetIndicatorSettings-C7vpco6e.cjs.map +1 -0
- package/dist/WidgetIndicatorSettings-dDkqzzYo.js +326 -0
- package/dist/WidgetIndicatorSettings-dDkqzzYo.js.map +1 -0
- package/dist/WidgetSettings-D7Pq42zW.cjs +2 -0
- package/dist/WidgetSettings-D7Pq42zW.cjs.map +1 -0
- package/dist/WidgetSettings-eOo93L7Z.js +546 -0
- package/dist/WidgetSettings-eOo93L7Z.js.map +1 -0
- package/dist/WidgetSymbolSearch-C4OR42nZ.cjs +2 -0
- package/dist/WidgetSymbolSearch-C4OR42nZ.cjs.map +1 -0
- package/dist/WidgetSymbolSearch-CvPpjIwa.js +580 -0
- package/dist/WidgetSymbolSearch-CvPpjIwa.js.map +1 -0
- package/dist/focusTrap-Br9Zfje0.js +27 -0
- package/dist/focusTrap-Br9Zfje0.js.map +1 -0
- package/dist/focusTrap-DrhhmG0V.cjs +2 -0
- package/dist/focusTrap-DrhhmG0V.cjs.map +1 -0
- package/dist/i18n-C2nQBZTY.cjs +2 -0
- package/dist/i18n-C2nQBZTY.cjs.map +1 -0
- package/dist/{i18n-DUmd4Z_r.js → i18n-C5v6Tzp1.js} +3 -1
- package/dist/i18n-C5v6Tzp1.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/indicatorInputWords-Bd9Pt6qp.js +25 -0
- package/dist/indicatorInputWords-Bd9Pt6qp.js.map +1 -0
- package/dist/indicatorInputWords-CTA4IcJR.cjs +2 -0
- package/dist/indicatorInputWords-CTA4IcJR.cjs.map +1 -0
- package/dist/indicatorLabel-BNZvaOcl.cjs +2 -0
- package/dist/indicatorLabel-BNZvaOcl.cjs.map +1 -0
- package/dist/indicatorLabel-Sbegyhp2.js +17 -0
- package/dist/indicatorLabel-Sbegyhp2.js.map +1 -0
- package/dist/indicatorSettingsTabs-B0liE3ST.cjs +2 -0
- package/dist/indicatorSettingsTabs-B0liE3ST.cjs.map +1 -0
- package/dist/indicatorSettingsTabs-XcgMdbLp.js +161 -0
- package/dist/indicatorSettingsTabs-XcgMdbLp.js.map +1 -0
- package/dist/monthView-B-CieFDJ.cjs +2 -0
- package/dist/monthView-B-CieFDJ.cjs.map +1 -0
- package/dist/monthView-N8yDaTqZ.js +198 -0
- package/dist/monthView-N8yDaTqZ.js.map +1 -0
- package/dist/platformKeys-B82-j1Fs.cjs +2 -0
- package/dist/platformKeys-B82-j1Fs.cjs.map +1 -0
- package/dist/platformKeys-Dd1qOCjF.js +5 -0
- package/dist/platformKeys-Dd1qOCjF.js.map +1 -0
- package/dist/settingsControls-DIjzCFHI.js +379 -0
- package/dist/settingsControls-DIjzCFHI.js.map +1 -0
- package/dist/settingsControls-Tn8_vJJv.cjs +2 -0
- package/dist/settingsControls-Tn8_vJJv.cjs.map +1 -0
- package/dist/symbolCatalog-CA1fpz3s.js +90 -0
- package/dist/symbolCatalog-CA1fpz3s.js.map +1 -0
- package/dist/symbolCatalog-Dx1YnZgm.cjs +2 -0
- package/dist/symbolCatalog-Dx1YnZgm.cjs.map +1 -0
- package/dist/widget/ChartWidget.d.ts +102 -582
- package/dist/widget/ChartWidget.d.ts.map +1 -1
- package/dist/widget/WidgetAlerts.d.ts +35 -0
- package/dist/widget/WidgetAlerts.d.ts.map +1 -0
- package/dist/widget/WidgetChartSettings.d.ts +194 -0
- package/dist/widget/WidgetChartSettings.d.ts.map +1 -0
- package/dist/widget/WidgetCommands.d.ts +54 -0
- package/dist/widget/WidgetCommands.d.ts.map +1 -0
- package/dist/widget/WidgetCompares.d.ts +140 -0
- package/dist/widget/WidgetCompares.d.ts.map +1 -0
- package/dist/widget/WidgetDockArea.d.ts +89 -0
- package/dist/widget/WidgetDockArea.d.ts.map +1 -0
- package/dist/widget/WidgetDrawingEdit.d.ts +73 -0
- package/dist/widget/WidgetDrawingEdit.d.ts.map +1 -0
- package/dist/widget/WidgetGoToDate.d.ts +1 -14
- package/dist/widget/WidgetGoToDate.d.ts.map +1 -1
- package/dist/widget/WidgetIndicatorSettings.d.ts.map +1 -1
- package/dist/widget/WidgetIntervals.d.ts +66 -0
- package/dist/widget/WidgetIntervals.d.ts.map +1 -0
- package/dist/widget/WidgetLayouts.d.ts +85 -0
- package/dist/widget/WidgetLayouts.d.ts.map +1 -0
- package/dist/widget/WidgetLegendView.d.ts +54 -0
- package/dist/widget/WidgetLegendView.d.ts.map +1 -0
- package/dist/widget/WidgetMenus.d.ts +79 -0
- package/dist/widget/WidgetMenus.d.ts.map +1 -0
- package/dist/widget/WidgetReplay.d.ts +199 -0
- package/dist/widget/WidgetReplay.d.ts.map +1 -0
- package/dist/widget/WidgetTrading.d.ts +48 -0
- package/dist/widget/WidgetTrading.d.ts.map +1 -0
- package/dist/widget/WidgetWatchlists.d.ts +77 -0
- package/dist/widget/WidgetWatchlists.d.ts.map +1 -0
- package/dist/widget/drawingSettingsTabs.d.ts +2 -19
- package/dist/widget/drawingSettingsTabs.d.ts.map +1 -1
- package/dist/widget/drawingText.d.ts +24 -0
- package/dist/widget/drawingText.d.ts.map +1 -0
- package/dist/widget/index.cjs +22 -23
- package/dist/widget/index.cjs.map +1 -1
- package/dist/widget/index.js +6193 -9868
- package/dist/widget/index.js.map +1 -1
- package/dist/widget/keyTarget.d.ts +4 -0
- package/dist/widget/keyTarget.d.ts.map +1 -1
- package/dist/widget/lazyPart.d.ts +47 -0
- package/dist/widget/lazyPart.d.ts.map +1 -0
- package/dist/widget/locales/ar.d.ts.map +1 -1
- package/dist/widget/locales/cs.d.ts.map +1 -1
- package/dist/widget/locales/da.d.ts.map +1 -1
- package/dist/widget/locales/de.d.ts.map +1 -1
- package/dist/widget/locales/el.d.ts.map +1 -1
- package/dist/widget/locales/en.d.ts +1 -0
- package/dist/widget/locales/en.d.ts.map +1 -1
- package/dist/widget/locales/es.d.ts.map +1 -1
- package/dist/widget/locales/et.d.ts.map +1 -1
- package/dist/widget/locales/fa.d.ts.map +1 -1
- package/dist/widget/locales/fr.d.ts.map +1 -1
- package/dist/widget/locales/he.d.ts.map +1 -1
- package/dist/widget/locales/hu.d.ts.map +1 -1
- package/dist/widget/locales/id.d.ts.map +1 -1
- package/dist/widget/locales/index.cjs +1 -1
- package/dist/widget/locales/index.cjs.map +1 -1
- package/dist/widget/locales/index.js +29 -1
- package/dist/widget/locales/index.js.map +1 -1
- package/dist/widget/locales/it.d.ts.map +1 -1
- package/dist/widget/locales/ja.d.ts.map +1 -1
- package/dist/widget/locales/ko.d.ts.map +1 -1
- package/dist/widget/locales/ms.d.ts.map +1 -1
- package/dist/widget/locales/nb.d.ts.map +1 -1
- package/dist/widget/locales/nl.d.ts.map +1 -1
- package/dist/widget/locales/pl.d.ts.map +1 -1
- package/dist/widget/locales/pt.d.ts.map +1 -1
- package/dist/widget/locales/ro.d.ts.map +1 -1
- package/dist/widget/locales/ru.d.ts.map +1 -1
- package/dist/widget/locales/sk.d.ts.map +1 -1
- package/dist/widget/locales/sv.d.ts.map +1 -1
- package/dist/widget/locales/th.d.ts.map +1 -1
- package/dist/widget/locales/tr.d.ts.map +1 -1
- package/dist/widget/locales/vi.d.ts.map +1 -1
- package/dist/widget/locales/zh.d.ts.map +1 -1
- package/dist/widget/locales/zhHant.d.ts.map +1 -1
- package/dist/widget/pageEnv.d.ts +5 -0
- package/dist/widget/pageEnv.d.ts.map +1 -0
- package/dist/widget/signals.d.ts +41 -0
- package/dist/widget/signals.d.ts.map +1 -0
- package/dist/widget/wallTime.d.ts +15 -0
- package/dist/widget/wallTime.d.ts.map +1 -0
- package/dist/widget/widgetDialogs.d.ts +17 -0
- package/dist/widget/widgetDialogs.d.ts.map +1 -0
- package/dist/widgetFeatures-BM6u0u74.js +186 -0
- package/dist/widgetFeatures-BM6u0u74.js.map +1 -0
- package/dist/widgetFeatures-BZ8OVPN2.cjs +3 -0
- package/dist/widgetFeatures-BZ8OVPN2.cjs.map +1 -0
- package/dist/widgetLocales-BPK5i0Ok.cjs +2 -0
- package/dist/widgetLocales-BPK5i0Ok.cjs.map +1 -0
- package/dist/widgetLocales-DgTR8JSu.js +838 -0
- package/dist/widgetLocales-DgTR8JSu.js.map +1 -0
- package/package.json +3 -3
- package/dist/LayoutSession-BOQCN6yY.js.map +0 -1
- package/dist/LayoutSession-RF8OqOXy.cjs +0 -2
- package/dist/LayoutSession-RF8OqOXy.cjs.map +0 -1
- package/dist/i18n-BsstZ9md.cjs +0 -2
- package/dist/i18n-BsstZ9md.cjs.map +0 -1
- package/dist/i18n-DUmd4Z_r.js.map +0 -1
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
//#region src/widget/monthView.ts
|
|
2
|
+
var e = 42, t = 7, n = new Set([
|
|
3
|
+
"US",
|
|
4
|
+
"CA",
|
|
5
|
+
"MX",
|
|
6
|
+
"BR",
|
|
7
|
+
"JP",
|
|
8
|
+
"KR",
|
|
9
|
+
"TW",
|
|
10
|
+
"HK",
|
|
11
|
+
"IL",
|
|
12
|
+
"PH",
|
|
13
|
+
"IN",
|
|
14
|
+
"ZA",
|
|
15
|
+
"AU",
|
|
16
|
+
"TH",
|
|
17
|
+
"SA",
|
|
18
|
+
"PE",
|
|
19
|
+
"CO"
|
|
20
|
+
]);
|
|
21
|
+
function r(e) {
|
|
22
|
+
try {
|
|
23
|
+
let t = new Intl.Locale(e), r = t.getWeekInfo?.() ?? t.weekInfo;
|
|
24
|
+
return r ? r.firstDay === 7 ? 0 : 1 : +!n.has(t.maximize().region ?? "");
|
|
25
|
+
} catch {
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function i(n, r, i) {
|
|
30
|
+
let a = (new Date(Date.UTC(n, r, 1)).getUTCDay() - i + t) % t, o = [];
|
|
31
|
+
for (let t = 0; t < e; t++) {
|
|
32
|
+
let e = new Date(Date.UTC(n, r, 1 - a + t));
|
|
33
|
+
o.push({
|
|
34
|
+
year: e.getUTCFullYear(),
|
|
35
|
+
month: e.getUTCMonth(),
|
|
36
|
+
day: e.getUTCDate()
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return o;
|
|
40
|
+
}
|
|
41
|
+
var a = (e) => String(e).padStart(2, "0"), o = (e) => `${String(e.year).padStart(4, "0")}-${a(e.month + 1)}-${a(e.day)}`;
|
|
42
|
+
function s(e) {
|
|
43
|
+
let t = /^(\d{4})-(\d{2})-(\d{2})$/.exec(e ?? "");
|
|
44
|
+
return t ? {
|
|
45
|
+
year: Number(t[1]),
|
|
46
|
+
month: Number(t[2]) - 1,
|
|
47
|
+
day: Number(t[3])
|
|
48
|
+
} : null;
|
|
49
|
+
}
|
|
50
|
+
function c() {
|
|
51
|
+
let e = /* @__PURE__ */ new Date();
|
|
52
|
+
return {
|
|
53
|
+
year: e.getFullYear(),
|
|
54
|
+
month: e.getMonth(),
|
|
55
|
+
day: e.getDate()
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function l(e, t) {
|
|
59
|
+
let n = new Date(Date.UTC(e.year, e.month, e.day + t));
|
|
60
|
+
return {
|
|
61
|
+
year: n.getUTCFullYear(),
|
|
62
|
+
month: n.getUTCMonth(),
|
|
63
|
+
day: n.getUTCDate()
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
var u = class {
|
|
67
|
+
element;
|
|
68
|
+
grid;
|
|
69
|
+
titleEl;
|
|
70
|
+
chosen = "";
|
|
71
|
+
limits = {};
|
|
72
|
+
today = o(c());
|
|
73
|
+
view = {
|
|
74
|
+
year: 0,
|
|
75
|
+
month: 0
|
|
76
|
+
};
|
|
77
|
+
focusDay = c();
|
|
78
|
+
constructor(e, n, i) {
|
|
79
|
+
this.locale = n, this.onPick = i;
|
|
80
|
+
let a = document.createElement("div");
|
|
81
|
+
a.className = "tcw-calendar";
|
|
82
|
+
let o = document.createElement("div");
|
|
83
|
+
o.className = "tcw-calendar-head";
|
|
84
|
+
let s = document.createElement("div");
|
|
85
|
+
s.className = "tcw-calendar-title", s.setAttribute("aria-live", "polite"), o.append(this.navButton(e.prevMonth, -1), s, this.navButton(e.nextMonth, 1));
|
|
86
|
+
let c = document.createElement("div");
|
|
87
|
+
c.className = "tcw-calendar-weekdays", c.setAttribute("aria-hidden", "true");
|
|
88
|
+
let l = r(n), u = new Intl.DateTimeFormat(n, {
|
|
89
|
+
weekday: "narrow",
|
|
90
|
+
timeZone: "UTC"
|
|
91
|
+
});
|
|
92
|
+
for (let e = 0; e < t; e++) {
|
|
93
|
+
let n = document.createElement("span");
|
|
94
|
+
n.className = "tcw-calendar-weekday", n.textContent = u.format(new Date(Date.UTC(2023, 0, 1 + (l + e) % t))), c.appendChild(n);
|
|
95
|
+
}
|
|
96
|
+
let d = document.createElement("div");
|
|
97
|
+
d.className = "tcw-calendar-grid", d.setAttribute("role", "grid"), d.addEventListener("keydown", (e) => this.onKey(e)), d.addEventListener("click", (e) => {
|
|
98
|
+
let t = e.target.closest(".tcw-calendar-day");
|
|
99
|
+
t && !t.disabled && t.dataset.date && this.pick(t.dataset.date);
|
|
100
|
+
});
|
|
101
|
+
let f = document.createElement("div");
|
|
102
|
+
f.className = "tcw-calendar-foot";
|
|
103
|
+
let p = document.createElement("button");
|
|
104
|
+
p.type = "button", p.className = "tcw-calendar-today", p.textContent = e.today, p.addEventListener("click", () => this.pick(this.today)), f.appendChild(p), a.append(o, c, d, f), this.element = a, this.grid = d, this.titleEl = s;
|
|
105
|
+
}
|
|
106
|
+
show(e, t = {}) {
|
|
107
|
+
this.chosen = e, this.limits = t, this.today = s(t.today) ? t.today : o(c());
|
|
108
|
+
let n = this.clamp(s(e) ?? s(this.today));
|
|
109
|
+
this.focusDay = n, this.view = {
|
|
110
|
+
year: n.year,
|
|
111
|
+
month: n.month
|
|
112
|
+
}, this.render();
|
|
113
|
+
}
|
|
114
|
+
focusGrid() {
|
|
115
|
+
this.grid.querySelector("[tabindex=\"0\"]")?.focus();
|
|
116
|
+
}
|
|
117
|
+
navButton(e, t) {
|
|
118
|
+
let n = document.createElement("button");
|
|
119
|
+
return n.type = "button", n.className = "tcw-calendar-nav", n.setAttribute("aria-label", e), n.innerHTML = t < 0 ? "<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M10 3.5L5.5 8l4.5 4.5\"/></svg>" : "<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M6 3.5L10.5 8 6 12.5\"/></svg>", n.addEventListener("click", () => this.turn(t)), n;
|
|
120
|
+
}
|
|
121
|
+
turn(e) {
|
|
122
|
+
let t = new Date(Date.UTC(this.view.year, this.view.month + e, 1));
|
|
123
|
+
this.view = {
|
|
124
|
+
year: t.getUTCFullYear(),
|
|
125
|
+
month: t.getUTCMonth()
|
|
126
|
+
};
|
|
127
|
+
let n = new Date(Date.UTC(this.view.year, this.view.month + 1, 0)).getUTCDate();
|
|
128
|
+
this.focusDay = this.clamp({
|
|
129
|
+
...this.view,
|
|
130
|
+
day: Math.min(this.focusDay.day, n)
|
|
131
|
+
}), this.view = {
|
|
132
|
+
year: this.focusDay.year,
|
|
133
|
+
month: this.focusDay.month
|
|
134
|
+
}, this.render();
|
|
135
|
+
}
|
|
136
|
+
clamp(e) {
|
|
137
|
+
let t = o(e), n = s(this.limits.min), r = s(this.limits.max);
|
|
138
|
+
return n && t < o(n) ? n : r && t > o(r) ? r : e;
|
|
139
|
+
}
|
|
140
|
+
allowed(e) {
|
|
141
|
+
let { min: t, max: n } = this.limits;
|
|
142
|
+
return !(t && e < t) && !(n && e > n);
|
|
143
|
+
}
|
|
144
|
+
render() {
|
|
145
|
+
let e = this.locale;
|
|
146
|
+
this.titleEl.textContent = new Intl.DateTimeFormat(e, {
|
|
147
|
+
month: "long",
|
|
148
|
+
year: "numeric",
|
|
149
|
+
timeZone: "UTC"
|
|
150
|
+
}).format(new Date(Date.UTC(this.view.year, this.view.month, 1)));
|
|
151
|
+
let n = this.today, a = o(this.focusDay), s = new Intl.DateTimeFormat(e, {
|
|
152
|
+
dateStyle: "full",
|
|
153
|
+
timeZone: "UTC"
|
|
154
|
+
});
|
|
155
|
+
this.grid.textContent = "";
|
|
156
|
+
let c = null;
|
|
157
|
+
for (let [l, u] of i(this.view.year, this.view.month, r(e)).entries()) {
|
|
158
|
+
l % t === 0 && (c = document.createElement("div"), c.className = "tcw-calendar-week", c.setAttribute("role", "row"), this.grid.appendChild(c));
|
|
159
|
+
let e = o(u), r = document.createElement("button");
|
|
160
|
+
r.type = "button", r.className = "tcw-calendar-day", r.dataset.date = e, r.setAttribute("role", "gridcell"), r.textContent = String(u.day), r.setAttribute("aria-label", s.format(new Date(Date.UTC(u.year, u.month, u.day)))), r.setAttribute("aria-selected", String(e === this.chosen)), r.tabIndex = e === a ? 0 : -1, u.month !== this.view.month && r.classList.add("tcw-outside"), e === n && r.classList.add("tcw-today"), this.allowed(e) || (r.disabled = !0), c?.appendChild(r);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
onKey(e) {
|
|
164
|
+
let n = {
|
|
165
|
+
ArrowLeft: -1,
|
|
166
|
+
ArrowRight: 1,
|
|
167
|
+
ArrowUp: -t,
|
|
168
|
+
ArrowDown: t
|
|
169
|
+
}, r = this.element.isConnected && getComputedStyle(this.element).direction === "rtl";
|
|
170
|
+
if (e.key in n) {
|
|
171
|
+
let t = r && (e.key === "ArrowLeft" || e.key === "ArrowRight") ? -n[e.key] : n[e.key];
|
|
172
|
+
this.moveFocus(l(this.focusDay, t));
|
|
173
|
+
} else if (e.key === "PageUp" || e.key === "PageDown") this.turn(e.key === "PageUp" ? -1 : 1), this.focusGrid();
|
|
174
|
+
else if (e.key === "Home" || e.key === "End") {
|
|
175
|
+
let t = new Date(Date.UTC(this.view.year, this.view.month + 1, 0)).getUTCDate();
|
|
176
|
+
this.moveFocus({
|
|
177
|
+
...this.view,
|
|
178
|
+
day: e.key === "Home" ? 1 : t
|
|
179
|
+
});
|
|
180
|
+
} else if (e.key === "Enter" || e.key === " ") this.pick(o(this.focusDay));
|
|
181
|
+
else return;
|
|
182
|
+
e.preventDefault();
|
|
183
|
+
}
|
|
184
|
+
moveFocus(e) {
|
|
185
|
+
let t = this.clamp(e);
|
|
186
|
+
this.focusDay = t, (t.year !== this.view.year || t.month !== this.view.month) && (this.view = {
|
|
187
|
+
year: t.year,
|
|
188
|
+
month: t.month
|
|
189
|
+
}), this.render(), this.focusGrid();
|
|
190
|
+
}
|
|
191
|
+
pick(e) {
|
|
192
|
+
this.allowed(e) && this.onPick(e);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
//#endregion
|
|
196
|
+
export { u as t };
|
|
197
|
+
|
|
198
|
+
//# sourceMappingURL=monthView-N8yDaTqZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monthView-N8yDaTqZ.js","names":[],"sources":["../src/widget/monthView.ts"],"sourcesContent":["export interface CalendarLabels {\n prevMonth: string;\n nextMonth: string;\n today: string;\n}\n\nexport interface CalendarDay {\n year: number;\n /** 0–11. */\n month: number;\n day: number;\n}\n\n/** The first and last day that can be picked, and today, YYYY-MM-DD; each may be left out. */\nexport interface DayLimits {\n min?: string;\n max?: string;\n /** Today where the dates are read (the chart's time zone); the browser's when left out. */\n today?: string;\n}\n\nconst DAYS_SHOWN = 42;\nconst DAYS_IN_WEEK = 7;\n\n/** Regions whose weeks start on Sunday, for engines without week data. */\nconst SUNDAY_REGIONS = new Set(['US', 'CA', 'MX', 'BR', 'JP', 'KR', 'TW', 'HK', 'IL', 'PH', 'IN', 'ZA', 'AU', 'TH', 'SA', 'PE', 'CO']);\n\n/** The first day of the week where `locale` is spoken: 0 Sunday, 1 Monday. */\nexport function weekStart(locale: string): 0 | 1 {\n try {\n const loc = new Intl.Locale(locale) as Intl.Locale & {\n getWeekInfo?: () => { firstDay: number };\n weekInfo?: { firstDay: number };\n };\n const info = loc.getWeekInfo?.() ?? loc.weekInfo;\n if (info) return info.firstDay === 7 ? 0 : 1;\n return SUNDAY_REGIONS.has(loc.maximize().region ?? '') ? 0 : 1;\n } catch {\n return 1;\n }\n}\n\n/** Six whole weeks around month `month` of `year`, from `firstDay` (0 Sunday, 1 Monday). */\nexport function monthGrid(year: number, month: number, firstDay: 0 | 1): CalendarDay[] {\n const first = new Date(Date.UTC(year, month, 1));\n const lead = (first.getUTCDay() - firstDay + DAYS_IN_WEEK) % DAYS_IN_WEEK;\n const days: CalendarDay[] = [];\n for (let i = 0; i < DAYS_SHOWN; i++) {\n const d = new Date(Date.UTC(year, month, 1 - lead + i));\n days.push({ year: d.getUTCFullYear(), month: d.getUTCMonth(), day: d.getUTCDate() });\n }\n return days;\n}\n\nconst pad = (n: number) => String(n).padStart(2, '0');\nconst iso = (d: CalendarDay) => `${String(d.year).padStart(4, '0')}-${pad(d.month + 1)}-${pad(d.day)}`;\n\nfunction parseIso(value: string | undefined): CalendarDay | null {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value ?? '');\n if (!m) return null;\n return { year: Number(m[1]), month: Number(m[2]) - 1, day: Number(m[3]) };\n}\n\nfunction todayDay(): CalendarDay {\n const now = new Date();\n return { year: now.getFullYear(), month: now.getMonth(), day: now.getDate() };\n}\n\n/** `d` moved by `days` (any sign), across months and years. */\nfunction addDays(d: CalendarDay, days: number): CalendarDay {\n const t = new Date(Date.UTC(d.year, d.month, d.day + days));\n return { year: t.getUTCFullYear(), month: t.getUTCMonth(), day: t.getUTCDate() };\n}\n\n/**\n * A month of days drawn by the widget: arrows to turn it, today marked, the\n * chosen day marked, a button for today, and the keys a date grid takes. It\n * only tells which day was picked; what that day goes into is its owner's\n * business (a date field's calendar, the Go to dialog).\n */\nexport class MonthView {\n readonly element: HTMLDivElement;\n private readonly grid: HTMLDivElement;\n private readonly titleEl: HTMLDivElement;\n private chosen = '';\n private limits: DayLimits = {};\n private today = iso(todayDay());\n /** The month shown and the day the keys are on. */\n private view = { year: 0, month: 0 };\n private focusDay: CalendarDay = todayDay();\n\n constructor(\n labels: CalendarLabels,\n private readonly locale: string,\n private readonly onPick: (value: string) => void,\n ) {\n const element = document.createElement('div');\n element.className = 'tcw-calendar';\n\n const head = document.createElement('div');\n head.className = 'tcw-calendar-head';\n const title = document.createElement('div');\n title.className = 'tcw-calendar-title';\n title.setAttribute('aria-live', 'polite');\n head.append(this.navButton(labels.prevMonth, -1), title, this.navButton(labels.nextMonth, 1));\n\n const weekdays = document.createElement('div');\n weekdays.className = 'tcw-calendar-weekdays';\n weekdays.setAttribute('aria-hidden', 'true');\n const firstDay = weekStart(locale);\n const dayName = new Intl.DateTimeFormat(locale, { weekday: 'narrow', timeZone: 'UTC' });\n for (let i = 0; i < DAYS_IN_WEEK; i++) {\n // 2023-01-01 was a Sunday.\n const cell = document.createElement('span');\n cell.className = 'tcw-calendar-weekday';\n cell.textContent = dayName.format(new Date(Date.UTC(2023, 0, 1 + ((firstDay + i) % DAYS_IN_WEEK))));\n weekdays.appendChild(cell);\n }\n\n const grid = document.createElement('div');\n grid.className = 'tcw-calendar-grid';\n grid.setAttribute('role', 'grid');\n grid.addEventListener('keydown', (e) => this.onKey(e));\n grid.addEventListener('click', (e) => {\n const day = (e.target as Element).closest<HTMLButtonElement>('.tcw-calendar-day');\n if (day && !day.disabled && day.dataset.date) this.pick(day.dataset.date);\n });\n\n const foot = document.createElement('div');\n foot.className = 'tcw-calendar-foot';\n const today = document.createElement('button');\n today.type = 'button';\n today.className = 'tcw-calendar-today';\n today.textContent = labels.today;\n today.addEventListener('click', () => this.pick(this.today));\n foot.appendChild(today);\n\n element.append(head, weekdays, grid, foot);\n this.element = element;\n this.grid = grid;\n this.titleEl = title;\n }\n\n /** Show the month of `value` (today's when it is no date), that day marked, days outside `limits` greyed. */\n show(value: string, limits: DayLimits = {}): void {\n this.chosen = value;\n this.limits = limits;\n this.today = parseIso(limits.today) ? limits.today! : iso(todayDay());\n const start = this.clamp(parseIso(value) ?? parseIso(this.today)!);\n this.focusDay = start;\n this.view = { year: start.year, month: start.month };\n this.render();\n }\n\n /** Moves keyboard focus onto the days. */\n focusGrid(): void {\n this.grid.querySelector<HTMLButtonElement>('[tabindex=\"0\"]')?.focus();\n }\n\n private navButton(label: string, by: -1 | 1): HTMLButtonElement {\n const b = document.createElement('button');\n b.type = 'button';\n b.className = 'tcw-calendar-nav';\n b.setAttribute('aria-label', label);\n b.innerHTML = by < 0\n ? '<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M10 3.5L5.5 8l4.5 4.5\"/></svg>'\n : '<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M6 3.5L10.5 8 6 12.5\"/></svg>';\n b.addEventListener('click', () => this.turn(by));\n return b;\n }\n\n private turn(by: number): void {\n const t = new Date(Date.UTC(this.view.year, this.view.month + by, 1));\n this.view = { year: t.getUTCFullYear(), month: t.getUTCMonth() };\n // The keys' day follows into the new month, on the same date where it has one.\n const last = new Date(Date.UTC(this.view.year, this.view.month + 1, 0)).getUTCDate();\n this.focusDay = this.clamp({ ...this.view, day: Math.min(this.focusDay.day, last) });\n this.view = { year: this.focusDay.year, month: this.focusDay.month };\n this.render();\n }\n\n /** `day` moved inside the limits, so the keys never rest on a greyed day. */\n private clamp(day: CalendarDay): CalendarDay {\n const value = iso(day);\n const min = parseIso(this.limits.min);\n const max = parseIso(this.limits.max);\n if (min && value < iso(min)) return min;\n if (max && value > iso(max)) return max;\n return day;\n }\n\n private allowed(value: string): boolean {\n const { min, max } = this.limits;\n return !(min && value < min) && !(max && value > max);\n }\n\n private render(): void {\n const locale = this.locale;\n this.titleEl.textContent = new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric', timeZone: 'UTC' })\n .format(new Date(Date.UTC(this.view.year, this.view.month, 1)));\n const today = this.today;\n const focus = iso(this.focusDay);\n const fullDate = new Intl.DateTimeFormat(locale, { dateStyle: 'full', timeZone: 'UTC' });\n this.grid.textContent = '';\n let row: HTMLElement | null = null;\n for (const [i, day] of monthGrid(this.view.year, this.view.month, weekStart(locale)).entries()) {\n if (i % DAYS_IN_WEEK === 0) {\n row = document.createElement('div');\n row.className = 'tcw-calendar-week';\n row.setAttribute('role', 'row');\n this.grid.appendChild(row);\n }\n const value = iso(day);\n const b = document.createElement('button');\n b.type = 'button';\n b.className = 'tcw-calendar-day';\n b.dataset.date = value;\n b.setAttribute('role', 'gridcell');\n b.textContent = String(day.day);\n b.setAttribute('aria-label', fullDate.format(new Date(Date.UTC(day.year, day.month, day.day))));\n b.setAttribute('aria-selected', String(value === this.chosen));\n b.tabIndex = value === focus ? 0 : -1;\n if (day.month !== this.view.month) b.classList.add('tcw-outside');\n if (value === today) b.classList.add('tcw-today');\n if (!this.allowed(value)) b.disabled = true;\n row?.appendChild(b);\n }\n }\n\n private onKey(e: KeyboardEvent): void {\n const moves: Record<string, number> = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -DAYS_IN_WEEK, ArrowDown: DAYS_IN_WEEK };\n const rtl = this.element.isConnected && getComputedStyle(this.element).direction === 'rtl';\n if (e.key in moves) {\n const by = rtl && (e.key === 'ArrowLeft' || e.key === 'ArrowRight') ? -moves[e.key] : moves[e.key];\n this.moveFocus(addDays(this.focusDay, by));\n } else if (e.key === 'PageUp' || e.key === 'PageDown') {\n this.turn(e.key === 'PageUp' ? -1 : 1);\n this.focusGrid();\n } else if (e.key === 'Home' || e.key === 'End') {\n const last = new Date(Date.UTC(this.view.year, this.view.month + 1, 0)).getUTCDate();\n this.moveFocus({ ...this.view, day: e.key === 'Home' ? 1 : last });\n } else if (e.key === 'Enter' || e.key === ' ') {\n this.pick(iso(this.focusDay));\n } else {\n return;\n }\n e.preventDefault();\n }\n\n private moveFocus(target: CalendarDay): void {\n const day = this.clamp(target);\n this.focusDay = day;\n if (day.year !== this.view.year || day.month !== this.view.month) {\n this.view = { year: day.year, month: day.month };\n }\n this.render();\n this.focusGrid();\n }\n\n private pick(value: string): void {\n if (this.allowed(value)) this.onPick(value);\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=typeof navigator<`u`&&/mac|iphone|ipad|ipod/i.test(navigator.platform||navigator.userAgent)?`⌘`:`Ctrl`,t=e=>e.toLowerCase().replace(/[\s+]+/g,``).replace(/[\u2010-\u2015\u2212]/g,`-`);Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return e}});
|
|
2
|
+
//# sourceMappingURL=platformKeys-B82-j1Fs.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platformKeys-B82-j1Fs.cjs","names":[],"sources":["../src/widget/platformKeys.ts"],"sourcesContent":["/** Whether the keyboard is a Mac's, where Ctrl's shortcuts take ⌘. */\nconst isMac =\n typeof navigator !== 'undefined' && /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);\n\n/** The key Ctrl stands for here: ⌘ on a Mac. */\nexport const MOD_KEY = isMac ? '⌘' : 'Ctrl';\n\n/** Text as a search compares it: lower case, no spaces or pluses (\"alt g\", \"Alt+G\" alike), any dash a hyphen (\"0–9\"). */\nexport const searchForm = (text: string): string =>\n text.toLowerCase().replace(/[\\s+]+/g, '').replace(/[\\u2010-\\u2015\\u2212]/g, '-');\n"],"mappings":"AAKA,IAAa,EAHX,OAAO,UAAc,KAAe,wBAAwB,KAAK,UAAU,UAAY,UAAU,UAAU,CAG9E,IAAM,OAGxB,EAAc,GACzB,EAAK,aAAa,CAAC,QAAQ,UAAW,GAAG,CAAC,QAAQ,yBAA0B,IAAI"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
var e = typeof navigator < "u" && /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent) ? "⌘" : "Ctrl", t = (e) => e.toLowerCase().replace(/[\s+]+/g, "").replace(/[\u2010-\u2015\u2212]/g, "-");
|
|
2
|
+
//#endregion
|
|
3
|
+
export { t as n, e as t };
|
|
4
|
+
|
|
5
|
+
//# sourceMappingURL=platformKeys-Dd1qOCjF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platformKeys-Dd1qOCjF.js","names":[],"sources":["../src/widget/platformKeys.ts"],"sourcesContent":["/** Whether the keyboard is a Mac's, where Ctrl's shortcuts take ⌘. */\nconst isMac =\n typeof navigator !== 'undefined' && /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);\n\n/** The key Ctrl stands for here: ⌘ on a Mac. */\nexport const MOD_KEY = isMac ? '⌘' : 'Ctrl';\n\n/** Text as a search compares it: lower case, no spaces or pluses (\"alt g\", \"Alt+G\" alike), any dash a hyphen (\"0–9\"). */\nexport const searchForm = (text: string): string =>\n text.toLowerCase().replace(/[\\s+]+/g, '').replace(/[\\u2010-\\u2015\\u2212]/g, '-');\n"],"mappings":"AAKA,IAAa,IAHX,OAAO,YAAc,OAAe,wBAAwB,KAAK,UAAU,YAAY,UAAU,UAAU,GAG9E,MAAM,QAGxB,KAAc,MACzB,EAAK,aAAa,CAAC,QAAQ,WAAW,GAAG,CAAC,QAAQ,0BAA0B,IAAI"}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import { i as e } from "./focusTrap-Br9Zfje0.js";
|
|
2
|
+
import { stepDecimals as t } from "@tradecanvas/commons";
|
|
3
|
+
//#region src/widget/WidgetContextMenu.ts
|
|
4
|
+
var n = 4, r = 2, i = 150, a = "[role=menuitem], [role=menuitemcheckbox], [role=menuitemradio]", o = "(max-width: 640px)", s = "tcw:back", c = /* @__PURE__ */ new Set();
|
|
5
|
+
function l(e, t, n, r = e, i = !1) {
|
|
6
|
+
let a = i ? r - t >= 0 ? r - t : e : e + t > n ? r - t : e;
|
|
7
|
+
return Math.max(0, Math.min(a, n - t));
|
|
8
|
+
}
|
|
9
|
+
function u(e) {
|
|
10
|
+
return e.radio ? "menuitemradio" : e.checked === void 0 ? "menuitem" : "menuitemcheckbox";
|
|
11
|
+
}
|
|
12
|
+
function d(t) {
|
|
13
|
+
let n = "<span class=\"tcw-context-icon\"></span>";
|
|
14
|
+
return t.radio ? t.checked ? "<span class=\"tcw-context-icon tcw-context-dot\"></span>" : n : t.checked ? e("check", 14) : t.icon && e(t.icon, 14) || n;
|
|
15
|
+
}
|
|
16
|
+
var f = class t {
|
|
17
|
+
el;
|
|
18
|
+
onPick = null;
|
|
19
|
+
onRemove = null;
|
|
20
|
+
returnFocus = null;
|
|
21
|
+
anchor = null;
|
|
22
|
+
child = null;
|
|
23
|
+
parent = null;
|
|
24
|
+
hoverTimer = null;
|
|
25
|
+
hoverItem = null;
|
|
26
|
+
onDocPointer = (e) => {
|
|
27
|
+
let t = e.target;
|
|
28
|
+
this.holds(t) || this.anchor?.contains(t) || this.close();
|
|
29
|
+
};
|
|
30
|
+
onWheel = (e) => {
|
|
31
|
+
this.holds(e.target) || this.close();
|
|
32
|
+
};
|
|
33
|
+
onAway = () => this.close();
|
|
34
|
+
constructor(e, t, n = "") {
|
|
35
|
+
this.host = e, this.backLabel = n, this.el = document.createElement("div"), this.el.className = "tcw-context-menu", this.el.setAttribute("role", "menu"), this.el.setAttribute("aria-label", t), this.el.hidden = !0, this.el.addEventListener("keydown", (e) => this.onKeyDown(e)), e.appendChild(this.el);
|
|
36
|
+
}
|
|
37
|
+
open(e, t, n, r, i, a, o = t, s = !1) {
|
|
38
|
+
this.show(e, {
|
|
39
|
+
x: t,
|
|
40
|
+
y: n,
|
|
41
|
+
xBack: o,
|
|
42
|
+
yBack: n,
|
|
43
|
+
before: s
|
|
44
|
+
}, r, i, a, !0);
|
|
45
|
+
}
|
|
46
|
+
openUnder(e, t, n, i = "start", a = r) {
|
|
47
|
+
let o = t.getBoundingClientRect(), s = this.host.getBoundingClientRect(), c = i === "end" !== this.rtl();
|
|
48
|
+
this.open(e, o.left - s.left, o.bottom - s.top + a, n, t, void 0, o.right - s.left, c);
|
|
49
|
+
}
|
|
50
|
+
openBeside(e, t, n) {
|
|
51
|
+
let i = t.getBoundingClientRect(), a = this.host.getBoundingClientRect(), o = i.right - a.left + r, s = i.left - a.left - r;
|
|
52
|
+
this.show(e, {
|
|
53
|
+
x: o,
|
|
54
|
+
y: i.top - a.top,
|
|
55
|
+
xBack: s,
|
|
56
|
+
yBack: i.bottom - a.top,
|
|
57
|
+
before: this.rtl()
|
|
58
|
+
}, n, t, void 0, !0), this.returnFocus = t;
|
|
59
|
+
}
|
|
60
|
+
static closeAnchoredTo(e) {
|
|
61
|
+
let t = [...c].filter((t) => t.anchor === e);
|
|
62
|
+
for (let e of t) e.close();
|
|
63
|
+
return t.length > 0;
|
|
64
|
+
}
|
|
65
|
+
static focusedAnchor() {
|
|
66
|
+
return [...c].find((e) => e.anchor !== null && e.hasFocus())?.anchor ?? null;
|
|
67
|
+
}
|
|
68
|
+
close() {
|
|
69
|
+
if (this.clearHover(), this.child?.close(), this.el.hidden) return;
|
|
70
|
+
c.delete(this);
|
|
71
|
+
let e = !this.parent || this.el.contains(document.activeElement);
|
|
72
|
+
this.el.hidden = !0, this.onPick = null, this.onRemove = null, this.anchor?.setAttribute("aria-expanded", "false"), this.anchor = null, document.removeEventListener("pointerdown", this.onDocPointer, !0), document.removeEventListener("wheel", this.onWheel, { capture: !0 }), window.removeEventListener("resize", this.onAway), window.removeEventListener("blur", this.onAway), e && this.returnFocus?.isConnected && this.returnFocus.focus({ preventScroll: !0 }), this.returnFocus = null;
|
|
73
|
+
}
|
|
74
|
+
isOpen() {
|
|
75
|
+
return !this.el.hidden;
|
|
76
|
+
}
|
|
77
|
+
hasFocus() {
|
|
78
|
+
return document.activeElement !== null && this.holds(document.activeElement);
|
|
79
|
+
}
|
|
80
|
+
destroy() {
|
|
81
|
+
this.close(), this.child?.destroy(), this.el.remove();
|
|
82
|
+
}
|
|
83
|
+
show(e, t, r, i, a, o) {
|
|
84
|
+
this.clearHover(), this.child?.close(), this.returnFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null, this.onPick = r, this.onRemove = a ?? null, this.anchor = i ?? null, this.anchor?.setAttribute("aria-expanded", "true"), this.el.replaceChildren(...e.map((e) => this.entry(e))), this.el.hidden = !1, c.add(this);
|
|
85
|
+
let s = this.host.getBoundingClientRect(), u = Math.min(this.host.clientWidth, window.innerWidth - s.left) - n, d = Math.min(this.host.clientHeight, window.innerHeight - s.top) - n;
|
|
86
|
+
this.el.style.maxHeight = `${Math.max(0, d - this.frameHeight())}px`, this.el.style.left = `${l(t.x, this.el.offsetWidth, u, t.xBack, t.before)}px`, this.el.style.top = `${l(t.y, this.el.offsetHeight, d, t.yBack)}px`, document.addEventListener("pointerdown", this.onDocPointer, !0), document.addEventListener("wheel", this.onWheel, {
|
|
87
|
+
capture: !0,
|
|
88
|
+
passive: !0
|
|
89
|
+
}), window.addEventListener("resize", this.onAway), window.addEventListener("blur", this.onAway);
|
|
90
|
+
let f = this.revealChoice();
|
|
91
|
+
o && (f ?? this.items()[0])?.focus({ preventScroll: !0 });
|
|
92
|
+
}
|
|
93
|
+
frameHeight() {
|
|
94
|
+
let e = getComputedStyle(this.el);
|
|
95
|
+
if (e.boxSizing === "border-box") return 0;
|
|
96
|
+
let t = (e) => parseFloat(e) || 0;
|
|
97
|
+
return t(e.paddingTop) + t(e.paddingBottom) + t(e.borderTopWidth) + t(e.borderBottomWidth);
|
|
98
|
+
}
|
|
99
|
+
revealChoice() {
|
|
100
|
+
let e = this.el.querySelector("[role=menuitemradio][aria-checked=true]");
|
|
101
|
+
return !e || e.offsetTop + e.offsetHeight <= this.el.clientHeight ? null : (this.el.scrollTop = e.offsetTop - (this.el.clientHeight - e.offsetHeight) / 2, e);
|
|
102
|
+
}
|
|
103
|
+
rtl() {
|
|
104
|
+
return this.host.closest("[dir]")?.getAttribute("dir") === "rtl";
|
|
105
|
+
}
|
|
106
|
+
holds(e) {
|
|
107
|
+
return this.el.contains(e) || (this.child?.holds(e) ?? !1);
|
|
108
|
+
}
|
|
109
|
+
entry(e) {
|
|
110
|
+
if (e === "separator") {
|
|
111
|
+
let e = document.createElement("div");
|
|
112
|
+
return e.className = "tcw-context-sep", e.setAttribute("role", "separator"), e;
|
|
113
|
+
}
|
|
114
|
+
let t = document.createElement("button");
|
|
115
|
+
t.type = "button", t.className = `tcw-context-item${e.danger ? " tcw-context-danger" : ""}`, t.setAttribute("role", u(e)), (e.radio || e.checked !== void 0) && t.setAttribute("aria-checked", String(e.checked ?? !1)), t.tabIndex = -1, t.dataset.id = e.id, t.innerHTML = d(e);
|
|
116
|
+
let n = document.createElement("span");
|
|
117
|
+
n.className = "tcw-context-label", n.textContent = e.label, t.appendChild(n), this.appendEnd(t, e);
|
|
118
|
+
let r = e.submenu;
|
|
119
|
+
return t.addEventListener("pointermove", (n) => {
|
|
120
|
+
n.pointerType !== "touch" && this.hover(t, e.label, r);
|
|
121
|
+
}), t.addEventListener("click", () => {
|
|
122
|
+
r ? this.openSubmenu(t, e.label, r, !0) : this.pick(e.id);
|
|
123
|
+
}), e.remove ? this.removableRow(t, e.remove) : t;
|
|
124
|
+
}
|
|
125
|
+
appendEnd(t, n) {
|
|
126
|
+
if (n.count !== void 0) {
|
|
127
|
+
let e = document.createElement("span");
|
|
128
|
+
e.className = "tcw-context-count", e.textContent = String(n.count), t.appendChild(e);
|
|
129
|
+
}
|
|
130
|
+
if (n.shortcut) {
|
|
131
|
+
t.setAttribute("aria-keyshortcuts", n.shortcut);
|
|
132
|
+
let e = document.createElement("kbd");
|
|
133
|
+
e.className = "tcw-context-key", e.setAttribute("aria-hidden", "true"), e.textContent = n.shortcut, t.appendChild(e);
|
|
134
|
+
}
|
|
135
|
+
n.submenu && (t.setAttribute("aria-haspopup", "menu"), t.setAttribute("aria-expanded", "false"), t.insertAdjacentHTML("beforeend", e("chevronRight", 12)), t.lastElementChild?.classList.add("tcw-context-more"));
|
|
136
|
+
}
|
|
137
|
+
removableRow(t, n) {
|
|
138
|
+
t.setAttribute("aria-keyshortcuts", "Delete");
|
|
139
|
+
let r = document.createElement("button");
|
|
140
|
+
r.type = "button", r.className = "tcw-context-remove", r.tabIndex = -1, r.setAttribute("aria-hidden", "true"), r.title = n, r.innerHTML = e("x", 12), r.addEventListener("click", () => this.remove(t));
|
|
141
|
+
let i = document.createElement("div");
|
|
142
|
+
return i.className = "tcw-context-row", i.setAttribute("role", "none"), i.append(t, r), i;
|
|
143
|
+
}
|
|
144
|
+
openSubmenu(e, t, n, r) {
|
|
145
|
+
this.clearHover();
|
|
146
|
+
let i = this.child ?? this.makeChild();
|
|
147
|
+
if (i.isOpen() && i.anchor === e) {
|
|
148
|
+
r && i.items()[0]?.focus({ preventScroll: !0 });
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
i.close(), i.el.setAttribute("aria-label", t);
|
|
152
|
+
let a = this.host.getBoundingClientRect(), c = e.getBoundingClientRect(), l = {
|
|
153
|
+
x: c.right - a.left,
|
|
154
|
+
y: c.top - a.top,
|
|
155
|
+
xBack: c.left - a.left,
|
|
156
|
+
yBack: c.bottom - a.top,
|
|
157
|
+
before: this.rtl()
|
|
158
|
+
}, u = window.matchMedia?.(o).matches ?? !1, d = u ? [
|
|
159
|
+
{
|
|
160
|
+
id: s,
|
|
161
|
+
label: t,
|
|
162
|
+
icon: "chevronLeft"
|
|
163
|
+
},
|
|
164
|
+
"separator",
|
|
165
|
+
...n
|
|
166
|
+
] : n;
|
|
167
|
+
i.show(d, l, (e) => {
|
|
168
|
+
e !== s && this.pick(e);
|
|
169
|
+
}, e, (e) => this.onRemove?.(e), r);
|
|
170
|
+
let f = u ? i.el.querySelector(`[data-id="${s}"]`) : null;
|
|
171
|
+
f?.classList.add("tcw-context-back"), f && this.backLabel && f.setAttribute("aria-label", `${this.backLabel}: ${t}`), i.returnFocus = e;
|
|
172
|
+
}
|
|
173
|
+
makeChild() {
|
|
174
|
+
let e = new t(this.host, "", this.backLabel);
|
|
175
|
+
return e.parent = this, e.el.addEventListener("pointerenter", () => this.clearHover()), this.child = e, e;
|
|
176
|
+
}
|
|
177
|
+
hover(e, t, n) {
|
|
178
|
+
if (this.hoverTimer !== null && this.hoverItem === e) return;
|
|
179
|
+
this.clearHover();
|
|
180
|
+
let r = this.child?.isOpen() ? this.child.anchor : null;
|
|
181
|
+
(n ? r === e : r === null) || (this.hoverItem = e, this.hoverTimer = setTimeout(() => {
|
|
182
|
+
this.hoverTimer = null, this.hoverItem = null, n ? this.openSubmenu(e, t, n, !1) : this.child?.close();
|
|
183
|
+
}, i));
|
|
184
|
+
}
|
|
185
|
+
clearHover() {
|
|
186
|
+
this.hoverItem = null, this.hoverTimer !== null && (clearTimeout(this.hoverTimer), this.hoverTimer = null);
|
|
187
|
+
}
|
|
188
|
+
remove(e) {
|
|
189
|
+
let t = e.dataset.id, n = e.closest(".tcw-context-row");
|
|
190
|
+
if (!t || !n) return;
|
|
191
|
+
let r = this.items().indexOf(e);
|
|
192
|
+
this.onRemove?.(t), n.remove();
|
|
193
|
+
let i = [...this.el.children].filter((e, t, n) => e.classList.contains("tcw-context-sep") && (t === 0 || t === n.length - 1 || n[t - 1].classList.contains("tcw-context-sep")));
|
|
194
|
+
for (let e of i) e.remove();
|
|
195
|
+
let a = this.items();
|
|
196
|
+
if (a.length === 0) {
|
|
197
|
+
this.close();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
a[Math.min(r, a.length - 1)].focus({ preventScroll: !0 });
|
|
201
|
+
}
|
|
202
|
+
pick(e) {
|
|
203
|
+
let t = this.onPick;
|
|
204
|
+
this.close(), t?.(e);
|
|
205
|
+
}
|
|
206
|
+
items() {
|
|
207
|
+
return [...this.el.querySelectorAll(a)];
|
|
208
|
+
}
|
|
209
|
+
onKeyDown(e) {
|
|
210
|
+
let t = this.items(), n = t.indexOf(document.activeElement), [r, i] = this.rtl() ? ["ArrowLeft", "ArrowRight"] : ["ArrowRight", "ArrowLeft"], a = -1;
|
|
211
|
+
if (e.key === "ArrowDown") a = (n + 1) % t.length;
|
|
212
|
+
else if (e.key === "ArrowUp") a = (n - 1 + t.length) % t.length;
|
|
213
|
+
else if (e.key === "Home") a = 0;
|
|
214
|
+
else if (e.key === "End") a = t.length - 1;
|
|
215
|
+
else if (e.key === r && t[n]?.hasAttribute("aria-haspopup")) {
|
|
216
|
+
e.preventDefault(), t[n].click();
|
|
217
|
+
return;
|
|
218
|
+
} else if (e.key === i && this.parent) {
|
|
219
|
+
e.preventDefault(), this.close();
|
|
220
|
+
return;
|
|
221
|
+
} else if (e.key === "Delete" && n >= 0) {
|
|
222
|
+
e.preventDefault(), this.remove(t[n]);
|
|
223
|
+
return;
|
|
224
|
+
} else if (e.key === "Escape" || e.key === "Tab") {
|
|
225
|
+
e.preventDefault(), e.stopPropagation();
|
|
226
|
+
let t = this;
|
|
227
|
+
for (; e.key === "Tab" && t.parent;) t = t.parent;
|
|
228
|
+
t.close();
|
|
229
|
+
return;
|
|
230
|
+
} else return;
|
|
231
|
+
e.preventDefault(), this.child?.close(), t[a]?.focus({ preventScroll: !0 });
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/widget/settingsControls.ts
|
|
236
|
+
function p(e, t) {
|
|
237
|
+
let n = document.createElement("label");
|
|
238
|
+
n.className = "tcw-settings-row";
|
|
239
|
+
let r = document.createElement("span");
|
|
240
|
+
return r.className = "tcw-settings-label", r.textContent = e, n.append(r, t), n;
|
|
241
|
+
}
|
|
242
|
+
function m(e, t, n) {
|
|
243
|
+
let r = document.createElement("label");
|
|
244
|
+
r.className = "tcw-settings-row tcw-check-row";
|
|
245
|
+
let i = document.createElement("input");
|
|
246
|
+
i.type = "checkbox", i.checked = t, i.addEventListener("change", () => n(i.checked));
|
|
247
|
+
let a = document.createElement("span");
|
|
248
|
+
return a.className = "tcw-settings-label", a.textContent = e, r.append(i, a), r;
|
|
249
|
+
}
|
|
250
|
+
function h(e, t) {
|
|
251
|
+
let n = document.createElement("button");
|
|
252
|
+
return n.type = "button", n.className = `tcw-toggle${e ? " tcw-on" : ""}`, n.setAttribute("role", "switch"), n.setAttribute("aria-checked", String(e)), n.addEventListener("click", () => {
|
|
253
|
+
let e = !n.classList.contains("tcw-on");
|
|
254
|
+
n.classList.toggle("tcw-on", e), n.setAttribute("aria-checked", String(e)), t(e);
|
|
255
|
+
}), n;
|
|
256
|
+
}
|
|
257
|
+
function g(e, t, n) {
|
|
258
|
+
let r = document.createElement("input");
|
|
259
|
+
return r.type = "number", r.className = "tcw-indi-input", r.value = String(e), r.step = String(t.step ?? (Number.isInteger(e) ? 1 : .001)), t.min !== void 0 && (r.min = String(t.min)), t.max !== void 0 && (r.max = String(t.max)), r.addEventListener("change", () => {
|
|
260
|
+
if (r.value.trim() === "") return;
|
|
261
|
+
let e = Number(r.value);
|
|
262
|
+
Number.isFinite(e) && (t.whole && (e = Math.round(e)), t.min !== void 0 && (e = Math.max(t.min, e)), t.max !== void 0 && (e = Math.min(t.max, e)), r.value = String(e), n(e));
|
|
263
|
+
}), r;
|
|
264
|
+
}
|
|
265
|
+
function _(e, t) {
|
|
266
|
+
let n = document.createElement("input");
|
|
267
|
+
return n.type = "color", n.className = "tcw-indi-color", n.value = y(e), n.addEventListener("input", () => t(n.value)), n;
|
|
268
|
+
}
|
|
269
|
+
function v(e, t, n) {
|
|
270
|
+
let r = document.createElement("select");
|
|
271
|
+
r.className = "tcw-indi-input tcw-indi-select";
|
|
272
|
+
for (let t of e) {
|
|
273
|
+
let e = document.createElement("option");
|
|
274
|
+
e.value = t.value, e.textContent = t.label, r.appendChild(e);
|
|
275
|
+
}
|
|
276
|
+
return r.value = t, r.addEventListener("change", () => n(r.value)), r;
|
|
277
|
+
}
|
|
278
|
+
function y(e) {
|
|
279
|
+
if (typeof e != "string") return "#000000";
|
|
280
|
+
let t = e.trim();
|
|
281
|
+
if (/^#[0-9a-f]{6}$/i.test(t)) return t.toLowerCase();
|
|
282
|
+
if (/^#[0-9a-f]{8}$/i.test(t)) return t.slice(0, 7).toLowerCase();
|
|
283
|
+
if (/^#[0-9a-f]{3,4}$/i.test(t)) return `#${t[1]}${t[1]}${t[2]}${t[2]}${t[3]}${t[3]}`.toLowerCase();
|
|
284
|
+
let n = /^rgba?\(\s*(\d+)[\s,]+(\d+)[\s,]+(\d+)/i.exec(t);
|
|
285
|
+
if (n) return `#${[
|
|
286
|
+
n[1],
|
|
287
|
+
n[2],
|
|
288
|
+
n[3]
|
|
289
|
+
].map((e) => Math.min(255, Number(e)).toString(16).padStart(2, "0")).join("")}`;
|
|
290
|
+
let r = x(t);
|
|
291
|
+
return r !== null && r !== t ? y(r) : "#000000";
|
|
292
|
+
}
|
|
293
|
+
var b;
|
|
294
|
+
function x(e) {
|
|
295
|
+
if (b === void 0) try {
|
|
296
|
+
b = typeof document < "u" ? document.createElement("canvas").getContext("2d") : null;
|
|
297
|
+
} catch {
|
|
298
|
+
b = null;
|
|
299
|
+
}
|
|
300
|
+
if (!b) return null;
|
|
301
|
+
b.fillStyle = "#010203", b.fillStyle = e;
|
|
302
|
+
let t = String(b.fillStyle);
|
|
303
|
+
return t === "#010203" ? null : t;
|
|
304
|
+
}
|
|
305
|
+
function S(e) {
|
|
306
|
+
if (typeof e != "string") return 1;
|
|
307
|
+
let t = /^rgba\([^)]*,\s*([\d.]+)\s*\)$/i.exec(e.trim());
|
|
308
|
+
return t ? Math.max(0, Math.min(1, Number(t[1]))) : 1;
|
|
309
|
+
}
|
|
310
|
+
function C(e, t) {
|
|
311
|
+
let n = y(e), [r, i, a] = [
|
|
312
|
+
1,
|
|
313
|
+
3,
|
|
314
|
+
5
|
|
315
|
+
].map((e) => parseInt(n.slice(e, e + 2), 16));
|
|
316
|
+
return `rgba(${r}, ${i}, ${a}, ${Math.round(t * 100) / 100})`;
|
|
317
|
+
}
|
|
318
|
+
var w = {
|
|
319
|
+
ArrowRight: 1,
|
|
320
|
+
ArrowDown: 1,
|
|
321
|
+
ArrowLeft: -1,
|
|
322
|
+
ArrowUp: -1
|
|
323
|
+
};
|
|
324
|
+
function T(e, t, n, r) {
|
|
325
|
+
let i = document.createElement("div");
|
|
326
|
+
i.className = "tcw-segmented", i.setAttribute("role", "radiogroup"), i.setAttribute("aria-label", r);
|
|
327
|
+
let a = e.map((e) => {
|
|
328
|
+
let t = document.createElement("button");
|
|
329
|
+
return t.type = "button", t.className = "tcw-segment", t.setAttribute("role", "radio"), t.dataset.value = e.value, t.textContent = e.label, t.addEventListener("click", () => s(e.value)), t;
|
|
330
|
+
}), o = (e) => {
|
|
331
|
+
let t = Math.max(0, a.findIndex((t) => t.dataset.value === e));
|
|
332
|
+
a.forEach((n, r) => {
|
|
333
|
+
n.setAttribute("aria-checked", String(n.dataset.value === e)), n.tabIndex = r === t ? 0 : -1;
|
|
334
|
+
});
|
|
335
|
+
}, s = (e) => {
|
|
336
|
+
o(e), n(e);
|
|
337
|
+
};
|
|
338
|
+
return i.addEventListener("keydown", (t) => {
|
|
339
|
+
let n = a.findIndex((e) => e === t.target);
|
|
340
|
+
if (n < 0 || t.altKey || t.ctrlKey || t.metaKey) return;
|
|
341
|
+
let r = a.length - 1, o;
|
|
342
|
+
if (t.key === "Home") o = 0;
|
|
343
|
+
else if (t.key === "End") o = r;
|
|
344
|
+
else if (t.key in w) {
|
|
345
|
+
let e = i.closest("[dir]")?.getAttribute("dir") === "rtl", r = t.key === "ArrowLeft" || t.key === "ArrowRight";
|
|
346
|
+
o = (n + (e && r ? -w[t.key] : w[t.key]) + a.length) % a.length;
|
|
347
|
+
} else return;
|
|
348
|
+
t.preventDefault(), a[o].focus(), s(e[o].value);
|
|
349
|
+
}), o(t), i.append(...a), i;
|
|
350
|
+
}
|
|
351
|
+
function E(e, n, r) {
|
|
352
|
+
if (!(r > 0) || !Number.isFinite(e)) return e;
|
|
353
|
+
let i = e / r, a = Math.round(i), o = Math.abs(i - a) < 1e-9 * Math.max(1, Math.abs(i)), s = n > 0 ? o ? a + 1 : Math.ceil(i) : o ? a - 1 : Math.floor(i);
|
|
354
|
+
return s < 1 ? e : Number((s * r).toFixed(t(r)));
|
|
355
|
+
}
|
|
356
|
+
function D(t, n) {
|
|
357
|
+
let r = document.createElement("div");
|
|
358
|
+
r.className = "tcw-stepper", r.dir = "ltr";
|
|
359
|
+
let i = (e) => {
|
|
360
|
+
let r = Number(t.value), i = t.value.trim() !== "" && Number.isFinite(r) ? r : n.fallback?.() ?? 0, a = E(i, e, n.step(i, e));
|
|
361
|
+
t.value = n.format ? n.format(a) : String(a), t.dispatchEvent(new Event("input"));
|
|
362
|
+
}, a = (t, n) => {
|
|
363
|
+
let r = document.createElement("button");
|
|
364
|
+
return r.type = "button", r.className = "tcw-stepper-btn", r.tabIndex = -1, r.setAttribute("aria-label", n), r.innerHTML = e(t > 0 ? "plus" : "minus", 14), r.addEventListener("click", () => i(t)), r;
|
|
365
|
+
};
|
|
366
|
+
t.addEventListener("keydown", (e) => {
|
|
367
|
+
e.key !== "ArrowUp" && e.key !== "ArrowDown" || (e.preventDefault(), i(e.key === "ArrowUp" ? 1 : -1));
|
|
368
|
+
});
|
|
369
|
+
let o = a(-1, n.labels.down), s = a(1, n.labels.up);
|
|
370
|
+
return r.append(o, t, s), {
|
|
371
|
+
element: r,
|
|
372
|
+
down: o,
|
|
373
|
+
up: s
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
//#endregion
|
|
377
|
+
export { T as a, D as c, C as d, f, g as i, y as l, S as n, v as o, _ as r, p as s, m as t, h as u };
|
|
378
|
+
|
|
379
|
+
//# sourceMappingURL=settingsControls-DIjzCFHI.js.map
|