@ixfx/components 0.2.6 → 0.3.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/bundle/index.d.ts +213 -117
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +1438 -686
- package/bundle/index.js.map +1 -1
- package/dist/ac-text.js +3 -3
- package/dist/ac-text.js.map +1 -1
- package/dist/{button-B9ztaKyl.js → button-DMt5XWUK.js} +4 -4
- package/dist/{button-B9ztaKyl.js.map → button-DMt5XWUK.js.map} +1 -1
- package/dist/button.js +1 -1
- package/dist/checkbox.d.ts +2 -3
- package/dist/checkbox.d.ts.map +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/{colour-C3MQIjFJ-BJV-QC-3.js → colour-C3MQIjFJ-BLXg8W3U.js} +2 -2
- package/dist/{colour-C3MQIjFJ-BJV-QC-3.js.map → colour-C3MQIjFJ-BLXg8W3U.js.map} +1 -1
- package/dist/{colour-picker-BNqDz4wK.js → colour-picker-K6zu82lm.js} +5 -5
- package/dist/{colour-picker-BNqDz4wK.js.map → colour-picker-K6zu82lm.js.map} +1 -1
- package/dist/colour-picker.js +1 -1
- package/dist/crumbs.d.ts +2 -3
- package/dist/crumbs.d.ts.map +1 -1
- package/dist/crumbs.js +10 -10
- package/dist/crumbs.js.map +1 -1
- package/dist/data-display.js +3 -3
- package/dist/{decorate-O4m1U4l3.js → decorate-D7rC1gLP.js} +10 -8
- package/dist/decorate-D7rC1gLP.js.map +1 -0
- package/dist/{defaults-FEZaGiYZ.js → defaults-C7elhuyJ.js} +2 -2
- package/dist/{defaults-FEZaGiYZ.js.map → defaults-C7elhuyJ.js.map} +1 -1
- package/dist/{dist-By5URG0Y.js → dist-BX0OVIm7.js} +2 -2
- package/dist/{dist-By5URG0Y.js.map → dist-BX0OVIm7.js.map} +1 -1
- package/dist/{dist-D7kJgnSE.js → dist-TAGYwaju.js} +1 -1
- package/dist/{dist-D7kJgnSE.js.map → dist-TAGYwaju.js.map} +1 -1
- package/dist/editable-label.d.ts +6 -1
- package/dist/editable-label.d.ts.map +1 -1
- package/dist/editable-label.js +49 -2
- package/dist/editable-label.js.map +1 -1
- package/dist/{hex-editor-gH3mteMr.js → hex-editor-CsN_ySkH.js} +85 -85
- package/dist/hex-editor-CsN_ySkH.js.map +1 -0
- package/dist/{hex-editor-2_s0Ua5t.d.ts → hex-editor-DlfoA65y.d.ts} +5 -5
- package/dist/{hex-editor-2_s0Ua5t.d.ts.map → hex-editor-DlfoA65y.d.ts.map} +1 -1
- package/dist/hex.d.ts +1 -1
- package/dist/hex.js +1 -1
- package/dist/{highlight-CAjwQ4GE.js → highlight-TPbSHruI.js} +3 -3
- package/dist/highlight-TPbSHruI.js.map +1 -0
- package/dist/{icon-CYACf6o8.js → icon-9NWTXtE1.js} +4 -5
- package/dist/icon-9NWTXtE1.js.map +1 -0
- package/dist/icon-CeTDJhC7.d.ts.map +1 -1
- package/dist/icons.js +3 -3
- package/dist/{incr-search-BZawvrfl.js → incr-search-DSKKsk6w.js} +12 -10
- package/dist/incr-search-DSKKsk6w.js.map +1 -0
- package/dist/incr-search.d.ts +1 -1
- package/dist/incr-search.js +2 -2
- package/dist/{index-CwGkb9s1.d.ts → index--hrxPBkQ.d.ts} +69 -69
- package/dist/index--hrxPBkQ.d.ts.map +1 -0
- package/dist/{index-kY5gxbkI.d.ts → index-DSlPeWLK.d.ts} +15 -15
- package/dist/{index-kY5gxbkI.d.ts.map → index-DSlPeWLK.d.ts.map} +1 -1
- package/dist/{index-V2cJorlA.d.ts → index-hXFn14tM.d.ts} +4 -4
- package/dist/index-hXFn14tM.d.ts.map +1 -0
- package/dist/index.d.ts +109 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +748 -52
- package/dist/index.js.map +1 -1
- package/dist/keyboard-De_vOHLg.js.map +1 -1
- package/dist/{labelled-input-base-BvgH7ldm.js → labelled-input-base-CqPL5rKm.js} +2 -2
- package/dist/labelled-input-base-CqPL5rKm.js.map +1 -0
- package/dist/labelled-radial-input.js +3 -3
- package/dist/labelled-radial-input.js.map +1 -1
- package/dist/labelled-range-input.js +2 -2
- package/dist/led.js +1 -1
- package/dist/{menu-C3eANB5M.js → menu-DJJuCm-5.js} +48 -48
- package/dist/menu-DJJuCm-5.js.map +1 -0
- package/dist/{menu-item-6IU5weHi.js → menu-item-CKRfP0pN.js} +10 -10
- package/dist/menu-item-CKRfP0pN.js.map +1 -0
- package/dist/menu.d.ts +1 -1
- package/dist/menu.js +2 -2
- package/dist/miller.d.ts +5 -7
- package/dist/miller.d.ts.map +1 -1
- package/dist/miller.js +14 -14
- package/dist/miller.js.map +1 -1
- package/dist/narrowed-text.d.ts.map +1 -1
- package/dist/narrowed-text.js +4 -4
- package/dist/narrowed-text.js.map +1 -1
- package/dist/panel.js +2 -2
- package/dist/panel.js.map +1 -1
- package/dist/plots.js +1 -1
- package/dist/polar-pad.d.ts.map +1 -1
- package/dist/polar-pad.js +1 -1
- package/dist/polar-pad.js.map +1 -1
- package/dist/{popup-Ddx9LCzY.js → popup-ImtS9KnS.js} +1 -1
- package/dist/{popup-Ddx9LCzY.js.map → popup-ImtS9KnS.js.map} +1 -1
- package/dist/{prominence-CreDBdCs.js → prominence--ic9uWBl.js} +1 -1
- package/dist/{prominence-CreDBdCs.js.map → prominence--ic9uWBl.js.map} +1 -1
- package/dist/{radial-input-Dbc6fgCK.js → radial-input-DZA6WaFu.js} +14 -14
- package/dist/radial-input-DZA6WaFu.js.map +1 -0
- package/dist/radial-input.js +1 -1
- package/dist/range-input.js +1 -1
- package/dist/range.js +2 -2
- package/dist/{registry-CZEB1YI9.js → registry-Q2gYQCHM.js} +1 -1
- package/dist/{registry-CZEB1YI9.js.map → registry-Q2gYQCHM.js.map} +1 -1
- package/dist/selecthorizontal.js +1 -1
- package/dist/snap-container.js +1 -1
- package/dist/split-layout.js +4 -4
- package/dist/split-layout.js.map +1 -1
- package/dist/swipe.d.ts +1 -2
- package/dist/swipe.d.ts.map +1 -1
- package/dist/swipe.js +2 -2
- package/dist/swipe.js.map +1 -1
- package/dist/tab-list-BnqISNvO.d.ts.map +1 -1
- package/dist/tabs.js +2 -2
- package/dist/tabs.js.map +1 -1
- package/dist/{timeline-B62Sz6J_.js → timeline-Cv75Th2U.js} +120 -116
- package/dist/timeline-Cv75Th2U.js.map +1 -0
- package/dist/timeline.d.ts +1 -1
- package/dist/timeline.js +1 -1
- package/dist/tooltip-CwGfb4lp.d.ts.map +1 -1
- package/dist/tree-CvvKbO-f.js +1330 -0
- package/dist/tree-CvvKbO-f.js.map +1 -0
- package/dist/{tree-component-CQpoPo4s.d.ts → tree-component-D8Bg48tt.d.ts} +12 -12
- package/dist/{tree-component-CQpoPo4s.d.ts.map → tree-component-D8Bg48tt.d.ts.map} +1 -1
- package/dist/tree.d.ts +1 -1
- package/dist/tree.js +1 -1143
- package/dist/xy-axis-D9uwpGTT.d.ts.map +1 -1
- package/dist/{xy-axis-C7fNxDwY.js → xy-axis-DL0tfJDr.js} +10 -10
- package/dist/{xy-axis-C7fNxDwY.js.map → xy-axis-DL0tfJDr.js.map} +1 -1
- package/dist/xy-pad.js +2 -2
- package/package.json +3 -3
- package/dist/decorate-O4m1U4l3.js.map +0 -1
- package/dist/hex-editor-gH3mteMr.js.map +0 -1
- package/dist/highlight-CAjwQ4GE.js.map +0 -1
- package/dist/icon-CYACf6o8.js.map +0 -1
- package/dist/incr-search-BZawvrfl.js.map +0 -1
- package/dist/index-CwGkb9s1.d.ts.map +0 -1
- package/dist/index-V2cJorlA.d.ts.map +0 -1
- package/dist/labelled-input-base-BvgH7ldm.js.map +0 -1
- package/dist/menu-C3eANB5M.js.map +0 -1
- package/dist/menu-item-6IU5weHi.js.map +0 -1
- package/dist/radial-input-Dbc6fgCK.js.map +0 -1
- package/dist/timeline-B62Sz6J_.js.map +0 -1
- package/dist/tree-data-model-DGvRVOFY.js +0 -190
- package/dist/tree-data-model-DGvRVOFY.js.map +0 -1
- package/dist/tree.js.map +0 -1
- /package/dist/{interaction-CQDQJf2Q.js → interaction-DG7X1rhI.js} +0 -0
package/bundle/index.js
CHANGED
|
@@ -737,12 +737,12 @@ function buildHighlightTargets(root, itemSelector, positionsByItem, getItem, get
|
|
|
737
737
|
}
|
|
738
738
|
return targets;
|
|
739
739
|
}
|
|
740
|
-
|
|
740
|
+
function findTextNode(element, expectedText) {
|
|
741
741
|
for (const node of element.childNodes) if (node.nodeType === Node.TEXT_NODE) {
|
|
742
742
|
if (expectedText === void 0 || node.textContent === expectedText) return node;
|
|
743
743
|
}
|
|
744
744
|
return null;
|
|
745
|
-
}
|
|
745
|
+
}
|
|
746
746
|
//#endregion
|
|
747
747
|
//#region src/interaction/tickled-controller.ts
|
|
748
748
|
/**
|
|
@@ -1067,6 +1067,22 @@ const tickledItemStyles = i$7`
|
|
|
1067
1067
|
}
|
|
1068
1068
|
`;
|
|
1069
1069
|
//#endregion
|
|
1070
|
+
//#region src/util/custom-elements.ts
|
|
1071
|
+
function getRegistry() {
|
|
1072
|
+
if (typeof customElements === `undefined`) return void 0;
|
|
1073
|
+
return customElements;
|
|
1074
|
+
}
|
|
1075
|
+
function safeDefine(name, ctor) {
|
|
1076
|
+
const registry = getRegistry();
|
|
1077
|
+
if (!registry) return;
|
|
1078
|
+
if (registry.get(name) === void 0) registry.define(name, ctor);
|
|
1079
|
+
}
|
|
1080
|
+
function safeCustomElement(name) {
|
|
1081
|
+
return (ctor) => {
|
|
1082
|
+
safeDefine(name, ctor);
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
//#endregion
|
|
1070
1086
|
//#region node_modules/.pnpm/lit-html@3.3.3/node_modules/lit-html/directive.js
|
|
1071
1087
|
/**
|
|
1072
1088
|
* @license
|
|
@@ -1100,37 +1116,6 @@ var i$3 = class {
|
|
|
1100
1116
|
}
|
|
1101
1117
|
};
|
|
1102
1118
|
//#endregion
|
|
1103
|
-
//#region node_modules/.pnpm/lit-html@3.3.3/node_modules/lit-html/directives/style-map.js
|
|
1104
|
-
/**
|
|
1105
|
-
* @license
|
|
1106
|
-
* Copyright 2018 Google LLC
|
|
1107
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
1108
|
-
*/ const n$1 = "important", i$2 = " !" + n$1, o$1 = e$3(class extends i$3 {
|
|
1109
|
-
constructor(t) {
|
|
1110
|
-
if (super(t), t.type !== t$2.ATTRIBUTE || "style" !== t.name || t.strings?.length > 2) throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.");
|
|
1111
|
-
}
|
|
1112
|
-
render(t) {
|
|
1113
|
-
return Object.keys(t).reduce((e, r) => {
|
|
1114
|
-
const s = t[r];
|
|
1115
|
-
return null == s ? e : e + `${r = r.includes("-") ? r : r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g, "-$&").toLowerCase()}:${s};`;
|
|
1116
|
-
}, "");
|
|
1117
|
-
}
|
|
1118
|
-
update(e, [r]) {
|
|
1119
|
-
const { style: s } = e.element;
|
|
1120
|
-
if (void 0 === this.ft) return this.ft = new Set(Object.keys(r)), this.render(r);
|
|
1121
|
-
for (const t of this.ft) r[t] ?? (this.ft.delete(t), t.includes("-") ? s.removeProperty(t) : s[t] = null);
|
|
1122
|
-
for (const t in r) {
|
|
1123
|
-
const e = r[t];
|
|
1124
|
-
if (null != e) {
|
|
1125
|
-
this.ft.add(t);
|
|
1126
|
-
const r = "string" == typeof e && e.endsWith(i$2);
|
|
1127
|
-
t.includes("-") || r ? s.setProperty(t, r ? e.slice(0, -11) : e, r ? n$1 : "") : s[t] = e;
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
return E;
|
|
1131
|
-
}
|
|
1132
|
-
});
|
|
1133
|
-
//#endregion
|
|
1134
1119
|
//#region node_modules/.pnpm/lit-html@3.3.3/node_modules/lit-html/directives/unsafe-html.js
|
|
1135
1120
|
/**
|
|
1136
1121
|
* @license
|
|
@@ -1155,7 +1140,7 @@ var i$3 = class {
|
|
|
1155
1140
|
}
|
|
1156
1141
|
};
|
|
1157
1142
|
e$2.directiveName = "unsafeHTML", e$2.resultType = 1;
|
|
1158
|
-
const o = e$3(e$2);
|
|
1143
|
+
const o$1 = e$3(e$2);
|
|
1159
1144
|
//#endregion
|
|
1160
1145
|
//#region src/icons/registry.ts
|
|
1161
1146
|
const _registry = /* @__PURE__ */ new Map();
|
|
@@ -1175,20 +1160,6 @@ function svgToDataUri(svg) {
|
|
|
1175
1160
|
return `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
|
|
1176
1161
|
}
|
|
1177
1162
|
//#endregion
|
|
1178
|
-
//#region src/util/custom-elements.ts
|
|
1179
|
-
const getRegistry = () => {
|
|
1180
|
-
if (typeof customElements === `undefined`) return void 0;
|
|
1181
|
-
return customElements;
|
|
1182
|
-
};
|
|
1183
|
-
const safeDefine = (name, ctor) => {
|
|
1184
|
-
const registry = getRegistry();
|
|
1185
|
-
if (!registry) return;
|
|
1186
|
-
if (registry.get(name) === void 0) registry.define(name, ctor);
|
|
1187
|
-
};
|
|
1188
|
-
const safeCustomElement = (name) => (ctor) => {
|
|
1189
|
-
safeDefine(name, ctor);
|
|
1190
|
-
};
|
|
1191
|
-
//#endregion
|
|
1192
1163
|
//#region \0@oxc-project+runtime@0.130.0/helpers/decorate.js
|
|
1193
1164
|
function __decorate(decorators, target, key, desc) {
|
|
1194
1165
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -1227,7 +1198,7 @@ let IxfxIconElement = class IxfxIconElement extends i$4 {
|
|
|
1227
1198
|
class="icon-wrapper"
|
|
1228
1199
|
aria-hidden=${hasLabel ? A : `true`}
|
|
1229
1200
|
aria-label=${hasLabel ? this.label : A}
|
|
1230
|
-
>${o(svg)}</span>
|
|
1201
|
+
>${o$1(svg)}</span>
|
|
1231
1202
|
`;
|
|
1232
1203
|
}
|
|
1233
1204
|
updated(changed) {
|
|
@@ -1283,14 +1254,14 @@ __decorate([n$2({
|
|
|
1283
1254
|
})], IxfxIconElement.prototype, "prominence", void 0);
|
|
1284
1255
|
__decorate([n$2({
|
|
1285
1256
|
type: String,
|
|
1286
|
-
attribute:
|
|
1257
|
+
attribute: `rotate`,
|
|
1287
1258
|
reflect: true
|
|
1288
1259
|
})], IxfxIconElement.prototype, "rotate", void 0);
|
|
1289
1260
|
IxfxIconElement = __decorate([safeCustomElement(`ixfx-icon`)], IxfxIconElement);
|
|
1290
1261
|
//#endregion
|
|
1291
1262
|
//#region src/ac-text/ac-text.ts
|
|
1292
1263
|
const HIGHLIGHT_KEY$1 = `ac-text-highlight`;
|
|
1293
|
-
function makeLruCache(maxSize) {
|
|
1264
|
+
function makeLruCache$1(maxSize) {
|
|
1294
1265
|
const map = /* @__PURE__ */ new Map();
|
|
1295
1266
|
return {
|
|
1296
1267
|
get: (key) => map.get(key),
|
|
@@ -1322,7 +1293,7 @@ let AcTextElement = class AcTextElement extends i$4 {
|
|
|
1322
1293
|
id: i,
|
|
1323
1294
|
enabled: true
|
|
1324
1295
|
})) });
|
|
1325
|
-
this.#cache = makeLruCache(20);
|
|
1296
|
+
this.#cache = makeLruCache$1(20);
|
|
1326
1297
|
this.#onFocus = () => {
|
|
1327
1298
|
this._isOpen = true;
|
|
1328
1299
|
if (this._query.trim()) this.#triggerQuery(this._query);
|
|
@@ -1397,7 +1368,7 @@ let AcTextElement = class AcTextElement extends i$4 {
|
|
|
1397
1368
|
e.preventDefault();
|
|
1398
1369
|
this.#selectItem(item);
|
|
1399
1370
|
};
|
|
1400
|
-
this.#cache = makeLruCache(this.cacheSize);
|
|
1371
|
+
this.#cache = makeLruCache$1(this.cacheSize);
|
|
1401
1372
|
}
|
|
1402
1373
|
disconnectedCallback() {
|
|
1403
1374
|
super.disconnectedCallback();
|
|
@@ -1406,7 +1377,7 @@ let AcTextElement = class AcTextElement extends i$4 {
|
|
|
1406
1377
|
}
|
|
1407
1378
|
updated(changedProps) {
|
|
1408
1379
|
if (changedProps.has(`completionProvider`)) this.#cache.clear();
|
|
1409
|
-
if (changedProps.has(`cacheSize`)) this.#cache = makeLruCache(this.cacheSize);
|
|
1380
|
+
if (changedProps.has(`cacheSize`)) this.#cache = makeLruCache$1(this.cacheSize);
|
|
1410
1381
|
if (changedProps.has(`value`)) {
|
|
1411
1382
|
const input = this.shadowRoot?.querySelector(`input`);
|
|
1412
1383
|
if (!input || document.activeElement !== input) this._query = this.value;
|
|
@@ -1763,6 +1734,934 @@ __decorate([r$1()], AcTextElement.prototype, "_isOpen", void 0);
|
|
|
1763
1734
|
__decorate([r$1()], AcTextElement.prototype, "_isLoading", void 0);
|
|
1764
1735
|
AcTextElement = __decorate([safeCustomElement(`ixfx-ac-text`)], AcTextElement);
|
|
1765
1736
|
//#endregion
|
|
1737
|
+
//#region src/incr-search/fuzzy.ts
|
|
1738
|
+
function defaultSelector(item) {
|
|
1739
|
+
if (typeof item === `string`) return item;
|
|
1740
|
+
const r = item;
|
|
1741
|
+
if (typeof r.label === `string`) return r.label;
|
|
1742
|
+
if (typeof r.key === `string`) return r.key;
|
|
1743
|
+
if (typeof r.value === `string`) return r.value;
|
|
1744
|
+
return String(item);
|
|
1745
|
+
}
|
|
1746
|
+
function createFuzzySearch(items, options = {}) {
|
|
1747
|
+
const fzf = new Fzf(items, {
|
|
1748
|
+
selector: options.selector ?? defaultSelector,
|
|
1749
|
+
...options.fzf ?? {}
|
|
1750
|
+
});
|
|
1751
|
+
const find = (query) => {
|
|
1752
|
+
if (!query.trim()) return items.map((item) => ({
|
|
1753
|
+
item,
|
|
1754
|
+
positions: /* @__PURE__ */ new Set(),
|
|
1755
|
+
score: 0
|
|
1756
|
+
}));
|
|
1757
|
+
return fzf.find(query).map((r) => ({
|
|
1758
|
+
item: r.item,
|
|
1759
|
+
positions: r.positions,
|
|
1760
|
+
score: r.score
|
|
1761
|
+
}));
|
|
1762
|
+
};
|
|
1763
|
+
return {
|
|
1764
|
+
find,
|
|
1765
|
+
items
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1768
|
+
//#endregion
|
|
1769
|
+
//#region src/incr-search/ac-adapter.ts
|
|
1770
|
+
/**
|
|
1771
|
+
* Creates an ixfx-ac-text-compatible `completionProvider` function from a
|
|
1772
|
+
* static item list. Uses synchronous fuzzy search wrapped in a Promise so it
|
|
1773
|
+
* fits the async provider signature.
|
|
1774
|
+
*
|
|
1775
|
+
* Each returned item has `positions` populated with matched character indices,
|
|
1776
|
+
* which `ixfx-ac-text` uses to render CSS Custom Highlights on the label.
|
|
1777
|
+
*
|
|
1778
|
+
* Empty query returns all items in original order (no positions).
|
|
1779
|
+
* A cancelled signal causes the returned promise to reject with an AbortError.
|
|
1780
|
+
*/
|
|
1781
|
+
function createAcCompletionProvider(items, options = {}) {
|
|
1782
|
+
const fuzzy = createFuzzySearch(items, { selector: options.selector ?? ((item) => item.label) });
|
|
1783
|
+
return (query, signal) => new Promise((resolve, reject) => {
|
|
1784
|
+
if (signal.aborted) {
|
|
1785
|
+
reject(new DOMException(`Aborted`, `AbortError`));
|
|
1786
|
+
return;
|
|
1787
|
+
}
|
|
1788
|
+
const results = fuzzy.find(query).map((r) => ({
|
|
1789
|
+
...r.item,
|
|
1790
|
+
positions: r.positions
|
|
1791
|
+
}));
|
|
1792
|
+
if (signal.aborted) {
|
|
1793
|
+
reject(new DOMException(`Aborted`, `AbortError`));
|
|
1794
|
+
return;
|
|
1795
|
+
}
|
|
1796
|
+
resolve(results);
|
|
1797
|
+
});
|
|
1798
|
+
}
|
|
1799
|
+
//#endregion
|
|
1800
|
+
//#region src/incr-search/incr-search.ts
|
|
1801
|
+
function buildState(results, query) {
|
|
1802
|
+
const positionsByItem = /* @__PURE__ */ new Map();
|
|
1803
|
+
for (const r of results) positionsByItem.set(r.item, r.positions);
|
|
1804
|
+
return Object.freeze({
|
|
1805
|
+
query,
|
|
1806
|
+
results: Object.freeze([...results]),
|
|
1807
|
+
positionsByItem
|
|
1808
|
+
});
|
|
1809
|
+
}
|
|
1810
|
+
function createIncrSearch(options = {}) {
|
|
1811
|
+
let items = options.items ?? [];
|
|
1812
|
+
let query = ``;
|
|
1813
|
+
let fuzzy = createFuzzySearch(items, {
|
|
1814
|
+
selector: options.selector,
|
|
1815
|
+
fzf: options.fzf
|
|
1816
|
+
});
|
|
1817
|
+
let state = buildState(fuzzy.find(query), query);
|
|
1818
|
+
let disposed = false;
|
|
1819
|
+
const observers = /* @__PURE__ */ new Set();
|
|
1820
|
+
if (options.onChange) observers.add(options.onChange);
|
|
1821
|
+
const notify = (s) => {
|
|
1822
|
+
for (const cb of observers) cb(s);
|
|
1823
|
+
};
|
|
1824
|
+
const run = async (q, signal) => {
|
|
1825
|
+
await Promise.resolve();
|
|
1826
|
+
if (signal?.aborted || disposed) return state;
|
|
1827
|
+
const results = fuzzy.find(q);
|
|
1828
|
+
if (signal?.aborted || disposed) return state;
|
|
1829
|
+
state = buildState(results, q);
|
|
1830
|
+
notify(state);
|
|
1831
|
+
return state;
|
|
1832
|
+
};
|
|
1833
|
+
return {
|
|
1834
|
+
get state() {
|
|
1835
|
+
return state;
|
|
1836
|
+
},
|
|
1837
|
+
async setItems(newItems, signal) {
|
|
1838
|
+
items = newItems;
|
|
1839
|
+
fuzzy = createFuzzySearch(items, {
|
|
1840
|
+
selector: options.selector,
|
|
1841
|
+
fzf: options.fzf
|
|
1842
|
+
});
|
|
1843
|
+
await run(query, signal);
|
|
1844
|
+
},
|
|
1845
|
+
async setQuery(q, signal) {
|
|
1846
|
+
query = q;
|
|
1847
|
+
return run(q, signal);
|
|
1848
|
+
},
|
|
1849
|
+
async clearQuery() {
|
|
1850
|
+
query = ``;
|
|
1851
|
+
await run(``, void 0);
|
|
1852
|
+
},
|
|
1853
|
+
onChange(cb) {
|
|
1854
|
+
observers.add(cb);
|
|
1855
|
+
cb(state);
|
|
1856
|
+
return () => {
|
|
1857
|
+
observers.delete(cb);
|
|
1858
|
+
};
|
|
1859
|
+
},
|
|
1860
|
+
dispose() {
|
|
1861
|
+
disposed = true;
|
|
1862
|
+
observers.clear();
|
|
1863
|
+
items = [];
|
|
1864
|
+
}
|
|
1865
|
+
};
|
|
1866
|
+
}
|
|
1867
|
+
//#endregion
|
|
1868
|
+
//#region src/incr-search/controller-tree.ts
|
|
1869
|
+
const DEFAULT_HIGHLIGHT_KEY = `incr-search-highlight`;
|
|
1870
|
+
/**
|
|
1871
|
+
* Incremental-search controller for any component implementing `TreeSearchHost`
|
|
1872
|
+
* (i.e. `ixfx-tree-list`, `ixfx-miller-list`, `ixfx-crumb-navigation`).
|
|
1873
|
+
*
|
|
1874
|
+
* Replaces the previous separate `IncrSearchTreeController` / `IncrSearchMillerController`
|
|
1875
|
+
* classes — the unified `TreeFilterPredicate` (with depth) means one implementation works
|
|
1876
|
+
* for all tree-like components.
|
|
1877
|
+
*
|
|
1878
|
+
* @example Using with ixfx-tree-list:
|
|
1879
|
+
* ```typescript
|
|
1880
|
+
* const ctrl = new IncrSearchTreeController(myTreeList, {
|
|
1881
|
+
* selector: item => item.node.item.label,
|
|
1882
|
+
* });
|
|
1883
|
+
* ctrl.connect();
|
|
1884
|
+
* ```
|
|
1885
|
+
*
|
|
1886
|
+
* @example Using with ixfx-miller-list (different label selector):
|
|
1887
|
+
* ```typescript
|
|
1888
|
+
* const ctrl = new IncrSearchTreeController(myMillerList, {
|
|
1889
|
+
* selector: item => item.node.item.label,
|
|
1890
|
+
* labelSelector: '.label',
|
|
1891
|
+
* });
|
|
1892
|
+
* ctrl.connect();
|
|
1893
|
+
* ```
|
|
1894
|
+
*/
|
|
1895
|
+
var IncrSearchTreeController = class {
|
|
1896
|
+
#el;
|
|
1897
|
+
#opts;
|
|
1898
|
+
#search;
|
|
1899
|
+
#unsub;
|
|
1900
|
+
#labelMap = /* @__PURE__ */ new Map();
|
|
1901
|
+
constructor(el, opts) {
|
|
1902
|
+
this.#el = el;
|
|
1903
|
+
this.#opts = opts;
|
|
1904
|
+
this.#search = createIncrSearch({
|
|
1905
|
+
selector: opts.selector,
|
|
1906
|
+
fzf: opts.fzf
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1909
|
+
connect() {
|
|
1910
|
+
this.disconnect();
|
|
1911
|
+
const items = this.#el.getNodes();
|
|
1912
|
+
for (const item of items) this.#labelMap.set(this.#opts.selector(item), item);
|
|
1913
|
+
this.#search.setItems(items);
|
|
1914
|
+
if (this.#opts.input) {
|
|
1915
|
+
this.#opts.input.addEventListener(`input`, this.#onInput);
|
|
1916
|
+
this.#opts.input.addEventListener(`keydown`, this.#onKeydown);
|
|
1917
|
+
}
|
|
1918
|
+
this.#unsub = this.#search.onChange((state) => this.#onStateChange(state));
|
|
1919
|
+
}
|
|
1920
|
+
disconnect() {
|
|
1921
|
+
if (this.#unsub) {
|
|
1922
|
+
this.#unsub();
|
|
1923
|
+
this.#unsub = void 0;
|
|
1924
|
+
}
|
|
1925
|
+
if (this.#opts.input) {
|
|
1926
|
+
this.#opts.input.removeEventListener(`input`, this.#onInput);
|
|
1927
|
+
this.#opts.input.removeEventListener(`keydown`, this.#onKeydown);
|
|
1928
|
+
}
|
|
1929
|
+
this.#el.filterPredicate = void 0;
|
|
1930
|
+
clearHighlights({ key: this.#opts.highlightKey ?? DEFAULT_HIGHLIGHT_KEY });
|
|
1931
|
+
this.#labelMap.clear();
|
|
1932
|
+
}
|
|
1933
|
+
async setQuery(query) {
|
|
1934
|
+
await this.#search.setQuery(query);
|
|
1935
|
+
}
|
|
1936
|
+
async clearQuery() {
|
|
1937
|
+
await this.#search.clearQuery();
|
|
1938
|
+
}
|
|
1939
|
+
#onInput = () => {
|
|
1940
|
+
const value = this.#opts.input?.value ?? ``;
|
|
1941
|
+
this.setQuery(value);
|
|
1942
|
+
};
|
|
1943
|
+
#onKeydown = (e) => {
|
|
1944
|
+
if (e.key === `Escape` && this.#opts.input) {
|
|
1945
|
+
this.#opts.input.value = ``;
|
|
1946
|
+
this.clearQuery();
|
|
1947
|
+
}
|
|
1948
|
+
};
|
|
1949
|
+
#onStateChange(state) {
|
|
1950
|
+
const matched = new Set(state.results.map((r) => r.item.node.item.key));
|
|
1951
|
+
const hasQuery = state.query.trim().length > 0;
|
|
1952
|
+
this.#el.filterPredicate = hasQuery && matched.size > 0 ? (node, _depth) => matched.has(node.item.key) : void 0;
|
|
1953
|
+
const key = this.#opts.highlightKey ?? DEFAULT_HIGHLIGHT_KEY;
|
|
1954
|
+
if (!this.#el.shadowRoot) return;
|
|
1955
|
+
if (!state.query.trim()) {
|
|
1956
|
+
clearHighlights({ key });
|
|
1957
|
+
return;
|
|
1958
|
+
}
|
|
1959
|
+
const labelSelector = this.#opts.labelSelector ?? `.tree-label`;
|
|
1960
|
+
applyHighlights(buildHighlightTargets(this.#el.shadowRoot, labelSelector, state.positionsByItem, (labelEl) => {
|
|
1961
|
+
const text = labelEl.textContent ?? ``;
|
|
1962
|
+
return this.#labelMap.get(text);
|
|
1963
|
+
}, (labelEl) => labelEl.textContent ?? ``), { key });
|
|
1964
|
+
}
|
|
1965
|
+
};
|
|
1966
|
+
//#endregion
|
|
1967
|
+
//#region src/incr-search/element-search.ts
|
|
1968
|
+
const defaultGetLabel = (el) => el.textContent?.trim() ?? ``;
|
|
1969
|
+
function defaultGetKey(el) {
|
|
1970
|
+
return el.getAttribute(`data-key`) ?? el.getAttribute(`data-value`) ?? el.textContent?.trim() ?? ``;
|
|
1971
|
+
}
|
|
1972
|
+
function createElementIncrSearch(opts) {
|
|
1973
|
+
const { container, itemSelector, getLabel = defaultGetLabel, getKey = defaultGetKey, labelSelector, highlightKey } = opts;
|
|
1974
|
+
let elementByKey = /* @__PURE__ */ new Map();
|
|
1975
|
+
const search = createIncrSearch({
|
|
1976
|
+
selector: (item) => item.label,
|
|
1977
|
+
fzf: opts.fzf
|
|
1978
|
+
});
|
|
1979
|
+
const updateVisibility = (state) => {
|
|
1980
|
+
const matchedKeys = new Set(state.results.map((r) => r.item.key));
|
|
1981
|
+
const hasQuery = state.query.trim().length > 0;
|
|
1982
|
+
for (const [key, el] of elementByKey) el.hidden = hasQuery ? !matchedKeys.has(key) : false;
|
|
1983
|
+
};
|
|
1984
|
+
const updateHighlights = (state) => {
|
|
1985
|
+
if (!state.query.trim()) {
|
|
1986
|
+
clearHighlights({ key: highlightKey });
|
|
1987
|
+
return;
|
|
1988
|
+
}
|
|
1989
|
+
applyHighlights(buildHighlightTargets(container, labelSelector ?? itemSelector, state.positionsByItem, (el) => {
|
|
1990
|
+
const key = getKey(el);
|
|
1991
|
+
return state.results.find((r) => r.item.key === key)?.item;
|
|
1992
|
+
}, (el) => getLabel(el)), { key: highlightKey });
|
|
1993
|
+
};
|
|
1994
|
+
const unsubscribeState = search.onChange((state) => {
|
|
1995
|
+
updateVisibility(state);
|
|
1996
|
+
updateHighlights(state);
|
|
1997
|
+
opts.onChange?.(state);
|
|
1998
|
+
});
|
|
1999
|
+
let refreshPending = false;
|
|
2000
|
+
const refresh = () => {
|
|
2001
|
+
if (refreshPending) return;
|
|
2002
|
+
refreshPending = true;
|
|
2003
|
+
Promise.resolve().then(() => {
|
|
2004
|
+
refreshPending = false;
|
|
2005
|
+
elementByKey = /* @__PURE__ */ new Map();
|
|
2006
|
+
const els = container.querySelectorAll(itemSelector);
|
|
2007
|
+
const items = [];
|
|
2008
|
+
for (const el of els) {
|
|
2009
|
+
const key = getKey(el);
|
|
2010
|
+
elementByKey.set(key, el);
|
|
2011
|
+
items.push({
|
|
2012
|
+
key,
|
|
2013
|
+
label: getLabel(el)
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
search.setItems(items);
|
|
2017
|
+
});
|
|
2018
|
+
};
|
|
2019
|
+
const observer = new MutationObserver(() => refresh());
|
|
2020
|
+
observer.observe(container, {
|
|
2021
|
+
childList: true,
|
|
2022
|
+
subtree: false
|
|
2023
|
+
});
|
|
2024
|
+
refresh();
|
|
2025
|
+
return {
|
|
2026
|
+
async setQuery(query, signal) {
|
|
2027
|
+
await search.setQuery(query, signal);
|
|
2028
|
+
},
|
|
2029
|
+
async clearQuery() {
|
|
2030
|
+
await search.clearQuery();
|
|
2031
|
+
},
|
|
2032
|
+
refresh,
|
|
2033
|
+
onChange(cb) {
|
|
2034
|
+
return search.onChange(cb);
|
|
2035
|
+
},
|
|
2036
|
+
dispose() {
|
|
2037
|
+
observer.disconnect();
|
|
2038
|
+
unsubscribeState();
|
|
2039
|
+
search.dispose();
|
|
2040
|
+
clearHighlights({ key: highlightKey });
|
|
2041
|
+
}
|
|
2042
|
+
};
|
|
2043
|
+
}
|
|
2044
|
+
//#endregion
|
|
2045
|
+
//#region src/ac-token/ac-token.ts
|
|
2046
|
+
const DEFAULT_TOKENIZER = (text) => text.split(/[\s,;]+/);
|
|
2047
|
+
function makeLruCache(maxSize) {
|
|
2048
|
+
const map = /* @__PURE__ */ new Map();
|
|
2049
|
+
return {
|
|
2050
|
+
get: (k) => map.get(k),
|
|
2051
|
+
set: (k, v) => {
|
|
2052
|
+
if (map.has(k)) map.delete(k);
|
|
2053
|
+
map.set(k, v);
|
|
2054
|
+
if (map.size > maxSize) map.delete(map.keys().next().value);
|
|
2055
|
+
},
|
|
2056
|
+
has: (k) => map.has(k),
|
|
2057
|
+
clear: () => map.clear()
|
|
2058
|
+
};
|
|
2059
|
+
}
|
|
2060
|
+
let AcTokenElement = class AcTokenElement extends i$4 {
|
|
2061
|
+
#cache;
|
|
2062
|
+
#debounceTimer;
|
|
2063
|
+
#abortController;
|
|
2064
|
+
#staticProvider;
|
|
2065
|
+
constructor() {
|
|
2066
|
+
super();
|
|
2067
|
+
this.placeholder = ``;
|
|
2068
|
+
this.cacheSize = 20;
|
|
2069
|
+
this.debounceMs = 150;
|
|
2070
|
+
this.strict = false;
|
|
2071
|
+
this._tokens = [];
|
|
2072
|
+
this._draft = ``;
|
|
2073
|
+
this._suggestions = [];
|
|
2074
|
+
this._isOpen = false;
|
|
2075
|
+
this._isLoading = false;
|
|
2076
|
+
this._tickled = new TickledController(this, { getItems: () => this._suggestions.map((_, i) => ({
|
|
2077
|
+
id: i,
|
|
2078
|
+
enabled: true
|
|
2079
|
+
})) });
|
|
2080
|
+
this.#cache = makeLruCache(20);
|
|
2081
|
+
this.#onWrapperClick = (e) => {
|
|
2082
|
+
if (!e.target.closest(`.token-chip`)) this.shadowRoot?.querySelector(`input.draft`)?.focus();
|
|
2083
|
+
};
|
|
2084
|
+
this.#onFocus = () => {
|
|
2085
|
+
this._selectedTokenIndex = void 0;
|
|
2086
|
+
this.#scheduleSuggestionFetch(this._draft);
|
|
2087
|
+
};
|
|
2088
|
+
this.#onBlur = () => {
|
|
2089
|
+
setTimeout(() => {
|
|
2090
|
+
this._isOpen = false;
|
|
2091
|
+
this._tickled.clearTickled();
|
|
2092
|
+
this._selectedTokenIndex = void 0;
|
|
2093
|
+
}, 120);
|
|
2094
|
+
};
|
|
2095
|
+
this.#onInput = (e) => {
|
|
2096
|
+
const value = e.target.value;
|
|
2097
|
+
this._selectedTokenIndex = void 0;
|
|
2098
|
+
const parts = (this.tokenizer ?? DEFAULT_TOKENIZER)(value);
|
|
2099
|
+
if (parts.length > 1) {
|
|
2100
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
2101
|
+
const label = parts[i].trim();
|
|
2102
|
+
if (label) this.#addToken({ label });
|
|
2103
|
+
}
|
|
2104
|
+
this._draft = parts[parts.length - 1] ?? ``;
|
|
2105
|
+
} else this._draft = value;
|
|
2106
|
+
this.#scheduleSuggestionFetch(this._draft);
|
|
2107
|
+
};
|
|
2108
|
+
this.#onKeyDown = (e) => {
|
|
2109
|
+
const input = e.target;
|
|
2110
|
+
if ((e.metaKey || e.ctrlKey) && e.key === `a`) {
|
|
2111
|
+
e.preventDefault();
|
|
2112
|
+
const parts = [...this._tokens.map((t) => t.label), this._draft.trim()].filter(Boolean);
|
|
2113
|
+
navigator.clipboard.writeText(parts.join(` `)).catch(() => {});
|
|
2114
|
+
return;
|
|
2115
|
+
}
|
|
2116
|
+
if (this._selectedTokenIndex !== void 0 && e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey) {
|
|
2117
|
+
e.preventDefault();
|
|
2118
|
+
this.#startEditingSelectedToken(e.key);
|
|
2119
|
+
return;
|
|
2120
|
+
}
|
|
2121
|
+
this.#handleNavigationKey(e, input);
|
|
2122
|
+
};
|
|
2123
|
+
this.#onPaste = (e) => {
|
|
2124
|
+
e.preventDefault();
|
|
2125
|
+
const text = e.clipboardData?.getData(`text/plain`) ?? ``;
|
|
2126
|
+
if (!text) return;
|
|
2127
|
+
const parts = (this.tokenizer ?? DEFAULT_TOKENIZER)(this._draft + text).filter(Boolean);
|
|
2128
|
+
if (parts.length === 0) return;
|
|
2129
|
+
if (parts.length === 1) this._draft = parts[0];
|
|
2130
|
+
else {
|
|
2131
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
2132
|
+
const label = parts[i].trim();
|
|
2133
|
+
if (label) this.#addToken({ label });
|
|
2134
|
+
}
|
|
2135
|
+
this._draft = parts[parts.length - 1] ?? ``;
|
|
2136
|
+
}
|
|
2137
|
+
this.updateComplete.then(() => {
|
|
2138
|
+
this.shadowRoot?.querySelector(`input.draft`)?.setSelectionRange(this._draft.length, this._draft.length);
|
|
2139
|
+
});
|
|
2140
|
+
this.#scheduleSuggestionFetch(this._draft);
|
|
2141
|
+
};
|
|
2142
|
+
this.#onSuggestionPointerDown = (e, item) => {
|
|
2143
|
+
e.preventDefault();
|
|
2144
|
+
this.#selectSuggestion(item);
|
|
2145
|
+
};
|
|
2146
|
+
this.#onChipPointerDown = (e, index) => {
|
|
2147
|
+
if (e.button !== 0) return;
|
|
2148
|
+
e.preventDefault();
|
|
2149
|
+
const el = e.currentTarget;
|
|
2150
|
+
const startY = e.clientY;
|
|
2151
|
+
let dragged = false;
|
|
2152
|
+
el.setPointerCapture(e.pointerId);
|
|
2153
|
+
const cleanup = () => {
|
|
2154
|
+
el.removeEventListener(`pointermove`, onMove);
|
|
2155
|
+
el.removeEventListener(`pointerup`, onUp);
|
|
2156
|
+
};
|
|
2157
|
+
const onMove = (me) => {
|
|
2158
|
+
if (Math.abs(me.clientY - startY) > 28) {
|
|
2159
|
+
dragged = true;
|
|
2160
|
+
el.releasePointerCapture(me.pointerId);
|
|
2161
|
+
cleanup();
|
|
2162
|
+
this.#removeToken(index);
|
|
2163
|
+
this.shadowRoot?.querySelector(`input.draft`)?.focus();
|
|
2164
|
+
}
|
|
2165
|
+
};
|
|
2166
|
+
const onUp = () => {
|
|
2167
|
+
cleanup();
|
|
2168
|
+
if (!dragged) {
|
|
2169
|
+
this._selectedTokenIndex = this._selectedTokenIndex === index ? void 0 : index;
|
|
2170
|
+
this.shadowRoot?.querySelector(`input.draft`)?.focus();
|
|
2171
|
+
}
|
|
2172
|
+
};
|
|
2173
|
+
el.addEventListener(`pointermove`, onMove);
|
|
2174
|
+
el.addEventListener(`pointerup`, onUp);
|
|
2175
|
+
};
|
|
2176
|
+
this.#cache = makeLruCache(this.cacheSize);
|
|
2177
|
+
}
|
|
2178
|
+
get tokens() {
|
|
2179
|
+
return this._tokens;
|
|
2180
|
+
}
|
|
2181
|
+
set tokens(value) {
|
|
2182
|
+
this._tokens = [...value];
|
|
2183
|
+
this.#emitChange();
|
|
2184
|
+
}
|
|
2185
|
+
/** All committed token labels joined with commas. */
|
|
2186
|
+
get value() {
|
|
2187
|
+
return this._tokens.map((t) => t.label).join(`, `);
|
|
2188
|
+
}
|
|
2189
|
+
connectedCallback() {
|
|
2190
|
+
super.connectedCallback();
|
|
2191
|
+
this.#buildStaticProvider();
|
|
2192
|
+
}
|
|
2193
|
+
disconnectedCallback() {
|
|
2194
|
+
super.disconnectedCallback();
|
|
2195
|
+
this.#cancelPending();
|
|
2196
|
+
}
|
|
2197
|
+
updated(changedProps) {
|
|
2198
|
+
if (changedProps.has(`completionProvider`) || changedProps.has(`cacheSize`)) this.#cache = makeLruCache(this.cacheSize);
|
|
2199
|
+
if (changedProps.has(`completionProvider`)) this.#buildStaticProvider();
|
|
2200
|
+
}
|
|
2201
|
+
#buildStaticProvider() {
|
|
2202
|
+
const raw = this.getAttribute(`data-tokens`);
|
|
2203
|
+
if (!raw || this.completionProvider) {
|
|
2204
|
+
this.#staticProvider = void 0;
|
|
2205
|
+
return;
|
|
2206
|
+
}
|
|
2207
|
+
const items = raw.trim().split(/[\s,;]+/).filter(Boolean).map((label) => ({ label }));
|
|
2208
|
+
this.#staticProvider = createAcCompletionProvider(items);
|
|
2209
|
+
}
|
|
2210
|
+
#onWrapperClick;
|
|
2211
|
+
#onFocus;
|
|
2212
|
+
#onBlur;
|
|
2213
|
+
#onInput;
|
|
2214
|
+
#onKeyDown;
|
|
2215
|
+
#handleNavigationKey(e, input) {
|
|
2216
|
+
switch (e.key) {
|
|
2217
|
+
case `ArrowLeft`:
|
|
2218
|
+
if (input.selectionStart === 0 && input.selectionEnd === 0) {
|
|
2219
|
+
e.preventDefault();
|
|
2220
|
+
if (this._selectedTokenIndex === void 0) {
|
|
2221
|
+
if (this._tokens.length > 0) this._selectedTokenIndex = this._tokens.length - 1;
|
|
2222
|
+
} else if (this._selectedTokenIndex > 0) this._selectedTokenIndex--;
|
|
2223
|
+
}
|
|
2224
|
+
break;
|
|
2225
|
+
case `ArrowRight`:
|
|
2226
|
+
if (this._selectedTokenIndex !== void 0) {
|
|
2227
|
+
e.preventDefault();
|
|
2228
|
+
if (this._selectedTokenIndex < this._tokens.length - 1) this._selectedTokenIndex++;
|
|
2229
|
+
else this._selectedTokenIndex = void 0;
|
|
2230
|
+
}
|
|
2231
|
+
break;
|
|
2232
|
+
case `Backspace`:
|
|
2233
|
+
if (input.selectionStart === 0 && input.selectionEnd === 0) {
|
|
2234
|
+
e.preventDefault();
|
|
2235
|
+
if (this._selectedTokenIndex !== void 0) this.#removeToken(this._selectedTokenIndex);
|
|
2236
|
+
else if (this._tokens.length > 0) this.#removeToken(this._tokens.length - 1);
|
|
2237
|
+
}
|
|
2238
|
+
break;
|
|
2239
|
+
case `Enter`: {
|
|
2240
|
+
const tickledIdx = this._tickled.tickledId;
|
|
2241
|
+
if (this._isOpen && tickledIdx !== void 0 && this._suggestions[tickledIdx]) {
|
|
2242
|
+
e.preventDefault();
|
|
2243
|
+
this.#selectSuggestion(this._suggestions[tickledIdx]);
|
|
2244
|
+
} else if (!this.strict && this._draft.trim()) {
|
|
2245
|
+
e.preventDefault();
|
|
2246
|
+
this.#addToken({ label: this._draft.trim() });
|
|
2247
|
+
this._draft = ``;
|
|
2248
|
+
this.#closePopup();
|
|
2249
|
+
}
|
|
2250
|
+
break;
|
|
2251
|
+
}
|
|
2252
|
+
case `ArrowDown`:
|
|
2253
|
+
if (!this._isOpen) return;
|
|
2254
|
+
e.preventDefault();
|
|
2255
|
+
this._tickled.handleKeyboardNavigation(`next`);
|
|
2256
|
+
this.#scrollSuggestionIntoView();
|
|
2257
|
+
break;
|
|
2258
|
+
case `ArrowUp`:
|
|
2259
|
+
if (!this._isOpen) return;
|
|
2260
|
+
e.preventDefault();
|
|
2261
|
+
this._tickled.handleKeyboardNavigation(`previous`);
|
|
2262
|
+
this.#scrollSuggestionIntoView();
|
|
2263
|
+
break;
|
|
2264
|
+
case `Escape`:
|
|
2265
|
+
e.preventDefault();
|
|
2266
|
+
this.#closePopup();
|
|
2267
|
+
this._selectedTokenIndex = void 0;
|
|
2268
|
+
break;
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
#onPaste;
|
|
2272
|
+
#onSuggestionPointerDown;
|
|
2273
|
+
#onChipPointerDown;
|
|
2274
|
+
#startEditingSelectedToken(key) {
|
|
2275
|
+
const idx = this._selectedTokenIndex;
|
|
2276
|
+
if (idx === void 0) return;
|
|
2277
|
+
const token = this._tokens[idx];
|
|
2278
|
+
if (!token) return;
|
|
2279
|
+
const newDraft = token.label + key;
|
|
2280
|
+
this.#removeToken(idx);
|
|
2281
|
+
this._selectedTokenIndex = void 0;
|
|
2282
|
+
this._draft = newDraft;
|
|
2283
|
+
this.updateComplete.then(() => {
|
|
2284
|
+
const inp = this.shadowRoot?.querySelector(`input.draft`);
|
|
2285
|
+
if (!inp) return;
|
|
2286
|
+
inp.setSelectionRange(inp.value.length, inp.value.length);
|
|
2287
|
+
});
|
|
2288
|
+
this.#scheduleSuggestionFetch(newDraft);
|
|
2289
|
+
}
|
|
2290
|
+
#addToken(item) {
|
|
2291
|
+
const index = this._tokens.length;
|
|
2292
|
+
this._tokens = [...this._tokens, item];
|
|
2293
|
+
this.dispatchEvent(new CustomEvent(`ac-token-add`, {
|
|
2294
|
+
detail: {
|
|
2295
|
+
item,
|
|
2296
|
+
index
|
|
2297
|
+
},
|
|
2298
|
+
bubbles: true,
|
|
2299
|
+
composed: true
|
|
2300
|
+
}));
|
|
2301
|
+
this.#emitChange();
|
|
2302
|
+
}
|
|
2303
|
+
#removeToken(index) {
|
|
2304
|
+
const item = this._tokens[index];
|
|
2305
|
+
if (!item) return;
|
|
2306
|
+
this._tokens = this._tokens.filter((_, i) => i !== index);
|
|
2307
|
+
if (this._selectedTokenIndex !== void 0) {
|
|
2308
|
+
if (this._selectedTokenIndex === index) this._selectedTokenIndex = void 0;
|
|
2309
|
+
else if (this._selectedTokenIndex > index) this._selectedTokenIndex--;
|
|
2310
|
+
}
|
|
2311
|
+
this.dispatchEvent(new CustomEvent(`ac-token-remove`, {
|
|
2312
|
+
detail: {
|
|
2313
|
+
item,
|
|
2314
|
+
index
|
|
2315
|
+
},
|
|
2316
|
+
bubbles: true,
|
|
2317
|
+
composed: true
|
|
2318
|
+
}));
|
|
2319
|
+
this.#emitChange();
|
|
2320
|
+
}
|
|
2321
|
+
#selectSuggestion(item) {
|
|
2322
|
+
this.#addToken(item);
|
|
2323
|
+
this._draft = ``;
|
|
2324
|
+
this.#closePopup();
|
|
2325
|
+
}
|
|
2326
|
+
#emitChange() {
|
|
2327
|
+
this.dispatchEvent(new CustomEvent(`ac-token-change`, {
|
|
2328
|
+
detail: { tokens: this._tokens },
|
|
2329
|
+
bubbles: true,
|
|
2330
|
+
composed: true
|
|
2331
|
+
}));
|
|
2332
|
+
}
|
|
2333
|
+
#closePopup() {
|
|
2334
|
+
this._isOpen = false;
|
|
2335
|
+
this._tickled.clearTickled();
|
|
2336
|
+
}
|
|
2337
|
+
#cancelPending() {
|
|
2338
|
+
if (this.#debounceTimer !== void 0) {
|
|
2339
|
+
clearTimeout(this.#debounceTimer);
|
|
2340
|
+
this.#debounceTimer = void 0;
|
|
2341
|
+
}
|
|
2342
|
+
this.#abortController?.abort();
|
|
2343
|
+
this.#abortController = void 0;
|
|
2344
|
+
this._isLoading = false;
|
|
2345
|
+
}
|
|
2346
|
+
#scheduleSuggestionFetch(query) {
|
|
2347
|
+
const provider = this.completionProvider ?? this.#staticProvider;
|
|
2348
|
+
if (!provider) {
|
|
2349
|
+
this._isOpen = false;
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
if (this.#debounceTimer !== void 0) clearTimeout(this.#debounceTimer);
|
|
2353
|
+
this._isOpen = true;
|
|
2354
|
+
this.#debounceTimer = setTimeout(() => {
|
|
2355
|
+
this.#fetchSuggestions(query, provider);
|
|
2356
|
+
}, this.debounceMs);
|
|
2357
|
+
}
|
|
2358
|
+
#fetchSuggestions(query, provider) {
|
|
2359
|
+
const cached = this.#cache.get(query);
|
|
2360
|
+
if (cached !== void 0) {
|
|
2361
|
+
this._suggestions = cached;
|
|
2362
|
+
this._tickled.clearTickled();
|
|
2363
|
+
this._isLoading = false;
|
|
2364
|
+
return;
|
|
2365
|
+
}
|
|
2366
|
+
this.#abortController?.abort();
|
|
2367
|
+
this.#abortController = new AbortController();
|
|
2368
|
+
const { signal } = this.#abortController;
|
|
2369
|
+
this._isLoading = true;
|
|
2370
|
+
Promise.resolve(provider(query, signal)).then((results) => {
|
|
2371
|
+
if (signal.aborted) return;
|
|
2372
|
+
this.#cache.set(query, results);
|
|
2373
|
+
this._suggestions = results;
|
|
2374
|
+
this._tickled.clearTickled();
|
|
2375
|
+
this._isLoading = false;
|
|
2376
|
+
}).catch((err) => {
|
|
2377
|
+
if (signal.aborted) return;
|
|
2378
|
+
console.error(`[ixfx-ac-token] completionProvider error:`, err);
|
|
2379
|
+
this._suggestions = [];
|
|
2380
|
+
this._isLoading = false;
|
|
2381
|
+
});
|
|
2382
|
+
}
|
|
2383
|
+
#scrollSuggestionIntoView() {
|
|
2384
|
+
this.updateComplete.then(() => {
|
|
2385
|
+
this.shadowRoot?.querySelector(`.suggestion.tickled`)?.scrollIntoView({ block: `nearest` });
|
|
2386
|
+
});
|
|
2387
|
+
}
|
|
2388
|
+
#renderChip(item, index) {
|
|
2389
|
+
return b`
|
|
2390
|
+
<span
|
|
2391
|
+
class="token-chip ${this._selectedTokenIndex === index ? `selected` : ``}"
|
|
2392
|
+
title=${item.subLabel ?? A}
|
|
2393
|
+
@pointerdown=${(e) => this.#onChipPointerDown(e, index)}
|
|
2394
|
+
>
|
|
2395
|
+
${item.icon ? b`<ixfx-icon class="chip-icon" name=${item.icon}></ixfx-icon>` : A}
|
|
2396
|
+
<span class="chip-label">${item.label}</span>
|
|
2397
|
+
</span>
|
|
2398
|
+
`;
|
|
2399
|
+
}
|
|
2400
|
+
#renderSuggestion(item, index) {
|
|
2401
|
+
const isTickled = this._tickled.isTickled(index);
|
|
2402
|
+
return b`
|
|
2403
|
+
<div
|
|
2404
|
+
class="suggestion ${isTickled ? `tickled` : ``}"
|
|
2405
|
+
role="option"
|
|
2406
|
+
id="ac-token-sugg-${index}"
|
|
2407
|
+
aria-selected=${isTickled}
|
|
2408
|
+
@pointerenter=${() => this._tickled.handlePointerEnter(index)}
|
|
2409
|
+
@pointerdown=${(e) => this.#onSuggestionPointerDown(e, item)}
|
|
2410
|
+
>
|
|
2411
|
+
${item.icon ? b`<ixfx-icon class="sugg-icon" name=${item.icon}></ixfx-icon>` : A}
|
|
2412
|
+
<span class="sugg-label">${item.label}</span>
|
|
2413
|
+
${item.subLabel ? b`<span class="sugg-sublabel">${item.subLabel}</span>` : A}
|
|
2414
|
+
</div>
|
|
2415
|
+
`;
|
|
2416
|
+
}
|
|
2417
|
+
#renderPopup() {
|
|
2418
|
+
const showEmpty = !this._isLoading && this._suggestions.length === 0;
|
|
2419
|
+
return b`
|
|
2420
|
+
<div
|
|
2421
|
+
class="popup"
|
|
2422
|
+
role="listbox"
|
|
2423
|
+
aria-label="Suggestions"
|
|
2424
|
+
data-input-mode=${this._tickled.inputMode}
|
|
2425
|
+
@pointerleave=${(e) => this._tickled.handlePointerLeave(e)}
|
|
2426
|
+
>
|
|
2427
|
+
${showEmpty ? b`<div class="no-results">No matching results</div>` : this._suggestions.map((item, i) => this.#renderSuggestion(item, i))}
|
|
2428
|
+
</div>
|
|
2429
|
+
`;
|
|
2430
|
+
}
|
|
2431
|
+
render() {
|
|
2432
|
+
const tickledIdx = this._tickled.tickledId ?? -1;
|
|
2433
|
+
const activeDescendant = tickledIdx >= 0 ? `ac-token-sugg-${tickledIdx}` : void 0;
|
|
2434
|
+
const showPlaceholder = this._tokens.length === 0 ? this.placeholder || A : A;
|
|
2435
|
+
return b`
|
|
2436
|
+
<div class="wrapper" @click=${this.#onWrapperClick}>
|
|
2437
|
+
${this._tokens.map((t, i) => this.#renderChip(t, i))}
|
|
2438
|
+
<input
|
|
2439
|
+
type="text"
|
|
2440
|
+
class="draft"
|
|
2441
|
+
.value=${this._draft}
|
|
2442
|
+
placeholder=${showPlaceholder}
|
|
2443
|
+
autocomplete="off"
|
|
2444
|
+
spellcheck="false"
|
|
2445
|
+
role="combobox"
|
|
2446
|
+
aria-autocomplete="list"
|
|
2447
|
+
aria-expanded=${this._isOpen}
|
|
2448
|
+
aria-activedescendant=${activeDescendant ?? A}
|
|
2449
|
+
@input=${this.#onInput}
|
|
2450
|
+
@keydown=${this.#onKeyDown}
|
|
2451
|
+
@focus=${this.#onFocus}
|
|
2452
|
+
@blur=${this.#onBlur}
|
|
2453
|
+
@paste=${this.#onPaste}
|
|
2454
|
+
>
|
|
2455
|
+
${this._isLoading ? b`<span class="spinner" aria-hidden="true"></span>` : A}
|
|
2456
|
+
</div>
|
|
2457
|
+
${this._isOpen ? this.#renderPopup() : A}
|
|
2458
|
+
`;
|
|
2459
|
+
}
|
|
2460
|
+
static {
|
|
2461
|
+
this.styles = [tickledStyles, i$7`
|
|
2462
|
+
:host {
|
|
2463
|
+
display: block;
|
|
2464
|
+
position: relative;
|
|
2465
|
+
font-family: var(--font-family, system-ui, sans-serif);
|
|
2466
|
+
font-size: var(--text-m, 12px);
|
|
2467
|
+
color: var(--surface-2-text);
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2470
|
+
/* ---- Wrapper (looks like a text input) ---- */
|
|
2471
|
+
|
|
2472
|
+
.wrapper {
|
|
2473
|
+
display: flex;
|
|
2474
|
+
flex-wrap: wrap;
|
|
2475
|
+
align-items: center;
|
|
2476
|
+
gap: var(--ac-token-chip-gap, var(--space-xs, 3px));
|
|
2477
|
+
padding: var(--ac-token-input-padding, var(--space-xs, 3px) var(--space-m, 8px));
|
|
2478
|
+
background: var(--ac-token-input-background, var(--surface-3, var(--surface-2)));
|
|
2479
|
+
color: var(--surface-2-text);
|
|
2480
|
+
border: var(--ac-token-input-border, var(--border));
|
|
2481
|
+
border-radius: var(--ac-token-input-border-radius, var(--radius-m, 4px));
|
|
2482
|
+
cursor: text;
|
|
2483
|
+
min-height: 32px;
|
|
2484
|
+
box-sizing: border-box;
|
|
2485
|
+
transition: border-color var(--transition, 0.15s ease-out);
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2488
|
+
.wrapper:focus-within {
|
|
2489
|
+
border-color: var(--accent);
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
/* ---- Token chips ---- */
|
|
2493
|
+
|
|
2494
|
+
.token-chip {
|
|
2495
|
+
display: inline-flex;
|
|
2496
|
+
align-items: center;
|
|
2497
|
+
gap: var(--space-xs, 3px);
|
|
2498
|
+
padding: 1px var(--space-m, 8px);
|
|
2499
|
+
background: var(--ac-token-chip-background, var(--surface-4));
|
|
2500
|
+
border: var(--ac-token-chip-border, var(--border));
|
|
2501
|
+
border-radius: var(--ac-token-chip-border-radius, var(--radius-s, 3px));
|
|
2502
|
+
user-select: none;
|
|
2503
|
+
cursor: default;
|
|
2504
|
+
font-size: var(--text-s, 11px);
|
|
2505
|
+
white-space: nowrap;
|
|
2506
|
+
touch-action: none;
|
|
2507
|
+
transition:
|
|
2508
|
+
background var(--transition, 0.1s ease-out),
|
|
2509
|
+
border-color var(--transition, 0.1s ease-out),
|
|
2510
|
+
color var(--transition, 0.1s ease-out);
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
.token-chip.selected {
|
|
2514
|
+
background: var(--ac-token-chip-selected-background, var(--accent));
|
|
2515
|
+
color: var(--ac-token-chip-selected-color, var(--accent-text, #fff));
|
|
2516
|
+
border-color: var(--accent);
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
.chip-icon {
|
|
2520
|
+
flex-shrink: 0;
|
|
2521
|
+
width: 1em;
|
|
2522
|
+
height: 1em;
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
/* ---- Draft input ---- */
|
|
2526
|
+
|
|
2527
|
+
input.draft {
|
|
2528
|
+
flex: 1;
|
|
2529
|
+
min-width: 60px;
|
|
2530
|
+
border: none;
|
|
2531
|
+
background: transparent;
|
|
2532
|
+
color: inherit;
|
|
2533
|
+
font: inherit;
|
|
2534
|
+
outline: none;
|
|
2535
|
+
caret-color: var(--accent);
|
|
2536
|
+
padding: 1px 0;
|
|
2537
|
+
anchor-name: --ac-token-draft;
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
input.draft::placeholder {
|
|
2541
|
+
color: var(--surface-muted-text);
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
/* ---- Spinner ---- */
|
|
2545
|
+
|
|
2546
|
+
.spinner {
|
|
2547
|
+
width: 12px;
|
|
2548
|
+
height: 12px;
|
|
2549
|
+
border: 2px solid var(--surface-5);
|
|
2550
|
+
border-top-color: var(--accent);
|
|
2551
|
+
border-radius: 50%;
|
|
2552
|
+
animation: ac-token-spin 0.7s linear infinite;
|
|
2553
|
+
flex-shrink: 0;
|
|
2554
|
+
pointer-events: none;
|
|
2555
|
+
margin-left: var(--space-xs, 3px);
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
@keyframes ac-token-spin {
|
|
2559
|
+
to { transform: rotate(360deg); }
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
/* ---- Popup ---- */
|
|
2563
|
+
|
|
2564
|
+
.popup {
|
|
2565
|
+
position: fixed;
|
|
2566
|
+
position-anchor: --ac-token-draft;
|
|
2567
|
+
top: anchor(bottom);
|
|
2568
|
+
left: anchor(left);
|
|
2569
|
+
margin-top: 2px;
|
|
2570
|
+
position-try-fallbacks: --ac-token-popup-above;
|
|
2571
|
+
z-index: 200;
|
|
2572
|
+
background: var(--surface-3, var(--surface-2));
|
|
2573
|
+
border: var(--border);
|
|
2574
|
+
border-radius: var(--radius-m, 4px);
|
|
2575
|
+
box-shadow: var(--shadow-l, 0 4px 24px rgba(0, 0, 0, 0.5));
|
|
2576
|
+
padding: var(--space-xs, 3px) 0;
|
|
2577
|
+
max-height: 260px;
|
|
2578
|
+
min-width: 160px;
|
|
2579
|
+
overflow-y: auto;
|
|
2580
|
+
font-size: var(--ac-token-popup-font-size, var(--text-s, 11px));
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
@position-try --ac-token-popup-above {
|
|
2584
|
+
top: auto;
|
|
2585
|
+
bottom: anchor(top);
|
|
2586
|
+
left: anchor(left);
|
|
2587
|
+
margin-top: 0;
|
|
2588
|
+
margin-bottom: 2px;
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
/* ---- Suggestion items ---- */
|
|
2592
|
+
|
|
2593
|
+
.suggestion {
|
|
2594
|
+
display: flex;
|
|
2595
|
+
align-items: center;
|
|
2596
|
+
gap: var(--space-m, 8px);
|
|
2597
|
+
padding: var(--space-xs, 3px) var(--space-l, 12px);
|
|
2598
|
+
cursor: pointer;
|
|
2599
|
+
border-radius: var(--radius-s, 3px);
|
|
2600
|
+
margin: 0 var(--space-xs, 3px);
|
|
2601
|
+
transition: background var(--transition, 0.1s ease-out);
|
|
2602
|
+
user-select: none;
|
|
2603
|
+
white-space: nowrap;
|
|
2604
|
+
min-height: 28px;
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2607
|
+
.suggestion.tickled {
|
|
2608
|
+
background: var(--_item-focused-bg, var(--accent));
|
|
2609
|
+
color: var(--accent-text, #fff);
|
|
2610
|
+
}
|
|
2611
|
+
|
|
2612
|
+
.suggestion.tickled .sugg-sublabel {
|
|
2613
|
+
color: color-mix(in srgb, var(--accent-text, #fff) 70%, transparent);
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
.sugg-icon {
|
|
2617
|
+
flex-shrink: 0;
|
|
2618
|
+
width: 1em;
|
|
2619
|
+
height: 1em;
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
.sugg-label {
|
|
2623
|
+
flex: 1;
|
|
2624
|
+
overflow: hidden;
|
|
2625
|
+
text-overflow: ellipsis;
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2628
|
+
.sugg-sublabel {
|
|
2629
|
+
flex-shrink: 0;
|
|
2630
|
+
margin-left: auto;
|
|
2631
|
+
color: var(--surface-muted-text);
|
|
2632
|
+
font-size: var(--text-s, 11px);
|
|
2633
|
+
}
|
|
2634
|
+
|
|
2635
|
+
/* ---- Empty state ---- */
|
|
2636
|
+
|
|
2637
|
+
.no-results {
|
|
2638
|
+
padding: var(--space-m, 8px) var(--space-l, 12px);
|
|
2639
|
+
color: var(--surface-muted-text);
|
|
2640
|
+
font-style: italic;
|
|
2641
|
+
}
|
|
2642
|
+
`];
|
|
2643
|
+
}
|
|
2644
|
+
};
|
|
2645
|
+
__decorate([n$2({ type: Object })], AcTokenElement.prototype, "completionProvider", void 0);
|
|
2646
|
+
__decorate([n$2({ type: Object })], AcTokenElement.prototype, "tokenizer", void 0);
|
|
2647
|
+
__decorate([n$2({ type: String })], AcTokenElement.prototype, "placeholder", void 0);
|
|
2648
|
+
__decorate([n$2({
|
|
2649
|
+
type: Number,
|
|
2650
|
+
attribute: `cache-size`
|
|
2651
|
+
})], AcTokenElement.prototype, "cacheSize", void 0);
|
|
2652
|
+
__decorate([n$2({
|
|
2653
|
+
type: Number,
|
|
2654
|
+
attribute: `debounce-ms`
|
|
2655
|
+
})], AcTokenElement.prototype, "debounceMs", void 0);
|
|
2656
|
+
__decorate([n$2({ type: Boolean })], AcTokenElement.prototype, "strict", void 0);
|
|
2657
|
+
__decorate([r$1()], AcTokenElement.prototype, "_tokens", void 0);
|
|
2658
|
+
__decorate([r$1()], AcTokenElement.prototype, "_draft", void 0);
|
|
2659
|
+
__decorate([r$1()], AcTokenElement.prototype, "_selectedTokenIndex", void 0);
|
|
2660
|
+
__decorate([r$1()], AcTokenElement.prototype, "_suggestions", void 0);
|
|
2661
|
+
__decorate([r$1()], AcTokenElement.prototype, "_isOpen", void 0);
|
|
2662
|
+
__decorate([r$1()], AcTokenElement.prototype, "_isLoading", void 0);
|
|
2663
|
+
AcTokenElement = __decorate([safeCustomElement(`ixfx-ac-token`)], AcTokenElement);
|
|
2664
|
+
//#endregion
|
|
1766
2665
|
//#region src/icons/defaults.ts
|
|
1767
2666
|
/**
|
|
1768
2667
|
* Chevron pointing down. Used for split-button dropdown toggle.
|
|
@@ -1979,7 +2878,7 @@ let ButtonElement = class ButtonElement extends i$4 {
|
|
|
1979
2878
|
}
|
|
1980
2879
|
_renderIcon() {
|
|
1981
2880
|
if (this.hideIcon || !this.icon) return A;
|
|
1982
|
-
if (this.icon.startsWith(`<svg`)) return b`<span class="button-icon">${o(this.icon)}</span>`;
|
|
2881
|
+
if (this.icon.startsWith(`<svg`)) return b`<span class="button-icon">${o$1(this.icon)}</span>`;
|
|
1983
2882
|
if (!getIcon(this.icon)) return A;
|
|
1984
2883
|
return b`<ixfx-icon class="button-icon" name="${this.icon}"></ixfx-icon>`;
|
|
1985
2884
|
}
|
|
@@ -2107,7 +3006,7 @@ let RadioGroup = class RadioGroup extends i$4 {
|
|
|
2107
3006
|
if (iconName) return b`<ixfx-icon class="radio-icon" name="${iconName}"></ixfx-icon>`;
|
|
2108
3007
|
const iconHtml = this._icons.get(item.value);
|
|
2109
3008
|
if (!iconHtml) return null;
|
|
2110
|
-
return b`<span class="radio-icon">${o(iconHtml)}</span>`;
|
|
3009
|
+
return b`<span class="radio-icon">${o$1(iconHtml)}</span>`;
|
|
2111
3010
|
}
|
|
2112
3011
|
render() {
|
|
2113
3012
|
if (this._isSingleToggle) {
|
|
@@ -2361,7 +3260,7 @@ let MenuContainer = class MenuContainer extends i$4 {
|
|
|
2361
3260
|
getItems: () => {
|
|
2362
3261
|
return this._getMenuItems().map((item, i) => ({
|
|
2363
3262
|
id: i,
|
|
2364
|
-
enabled: !item.hasAttribute(
|
|
3263
|
+
enabled: !item.hasAttribute(`disabled`)
|
|
2365
3264
|
}));
|
|
2366
3265
|
},
|
|
2367
3266
|
onTickle: (index) => {
|
|
@@ -2495,7 +3394,7 @@ let MenuContainer = class MenuContainer extends i$4 {
|
|
|
2495
3394
|
*/
|
|
2496
3395
|
willUpdate(changed) {
|
|
2497
3396
|
super.willUpdate(changed);
|
|
2498
|
-
this.setAttribute(
|
|
3397
|
+
this.setAttribute(`data-input-mode`, this.tickled.inputMode);
|
|
2499
3398
|
}
|
|
2500
3399
|
render() {
|
|
2501
3400
|
return b`
|
|
@@ -2553,14 +3452,14 @@ let MenuContainer = class MenuContainer extends i$4 {
|
|
|
2553
3452
|
}
|
|
2554
3453
|
}
|
|
2555
3454
|
});
|
|
2556
|
-
if (this.tickled.inputMode ===
|
|
3455
|
+
if (this.tickled.inputMode === `keyboard` && this.tickled.tickledId !== void 0) items[this.tickled.tickledId]?.focus();
|
|
2557
3456
|
}
|
|
2558
3457
|
focusFirst() {
|
|
2559
|
-
this.tickled.handleKeyboardNavigation(
|
|
3458
|
+
this.tickled.handleKeyboardNavigation(`first`);
|
|
2560
3459
|
}
|
|
2561
3460
|
_focusNext(items, direction) {
|
|
2562
3461
|
if (items.length === 0) return;
|
|
2563
|
-
this.tickled.handleKeyboardNavigation(direction > 0 ?
|
|
3462
|
+
this.tickled.handleKeyboardNavigation(direction > 0 ? `next` : `previous`);
|
|
2564
3463
|
}
|
|
2565
3464
|
_focusItem(items, index) {
|
|
2566
3465
|
if (items.length === 0) return;
|
|
@@ -18879,7 +19778,7 @@ let ColourPickerPopup = class ColourPickerPopup extends i$4 {
|
|
|
18879
19778
|
></ixfx-colour-picker>
|
|
18880
19779
|
${this.mode === `confirm` ? b`
|
|
18881
19780
|
<button class="confirm-btn" @click=${this._onConfirm} aria-label="Confirm colour" title="Confirm colour">
|
|
18882
|
-
${o(ICON_CHECK)}
|
|
19781
|
+
${o$1(ICON_CHECK)}
|
|
18883
19782
|
</button>
|
|
18884
19783
|
` : A}
|
|
18885
19784
|
` : A}
|
|
@@ -19110,7 +20009,7 @@ var TreeDataModel = class {
|
|
|
19110
20009
|
this.#root = root;
|
|
19111
20010
|
this.#cache.clear();
|
|
19112
20011
|
this.#notify({
|
|
19113
|
-
type:
|
|
20012
|
+
type: `root`,
|
|
19114
20013
|
root
|
|
19115
20014
|
});
|
|
19116
20015
|
}
|
|
@@ -19138,7 +20037,7 @@ var TreeDataModel = class {
|
|
|
19138
20037
|
invalidate(key) {
|
|
19139
20038
|
this.#cache.delete(key);
|
|
19140
20039
|
this.#notify({
|
|
19141
|
-
type:
|
|
20040
|
+
type: `invalidate`,
|
|
19142
20041
|
key
|
|
19143
20042
|
});
|
|
19144
20043
|
}
|
|
@@ -19149,7 +20048,7 @@ var TreeDataModel = class {
|
|
|
19149
20048
|
addNode(parentKey, node) {
|
|
19150
20049
|
this.#root = addChildTo(this.#root, parentKey, node);
|
|
19151
20050
|
this.#notify({
|
|
19152
|
-
type:
|
|
20051
|
+
type: `root`,
|
|
19153
20052
|
root: this.#root
|
|
19154
20053
|
});
|
|
19155
20054
|
return this.#root;
|
|
@@ -19162,7 +20061,7 @@ var TreeDataModel = class {
|
|
|
19162
20061
|
this.#cache.delete(key);
|
|
19163
20062
|
this.#root = removeNodeFrom(this.#root, key);
|
|
19164
20063
|
this.#notify({
|
|
19165
|
-
type:
|
|
20064
|
+
type: `root`,
|
|
19166
20065
|
root: this.#root
|
|
19167
20066
|
});
|
|
19168
20067
|
return this.#root;
|
|
@@ -19180,7 +20079,7 @@ var TreeDataModel = class {
|
|
|
19180
20079
|
children: n.children
|
|
19181
20080
|
}));
|
|
19182
20081
|
this.#notify({
|
|
19183
|
-
type:
|
|
20082
|
+
type: `root`,
|
|
19184
20083
|
root: this.#root
|
|
19185
20084
|
});
|
|
19186
20085
|
return this.#root;
|
|
@@ -19192,7 +20091,7 @@ var TreeDataModel = class {
|
|
|
19192
20091
|
moveNode(key, newParentKey) {
|
|
19193
20092
|
this.#root = moveNodeTo(this.#root, key, newParentKey);
|
|
19194
20093
|
this.#notify({
|
|
19195
|
-
type:
|
|
20094
|
+
type: `root`,
|
|
19196
20095
|
root: this.#root
|
|
19197
20096
|
});
|
|
19198
20097
|
return this.#root;
|
|
@@ -19212,312 +20111,6 @@ var TreeDataModel = class {
|
|
|
19212
20111
|
}
|
|
19213
20112
|
};
|
|
19214
20113
|
//#endregion
|
|
19215
|
-
//#region src/incr-search/fuzzy.ts
|
|
19216
|
-
const defaultSelector = (item) => {
|
|
19217
|
-
if (typeof item === `string`) return item;
|
|
19218
|
-
const r = item;
|
|
19219
|
-
if (typeof r[`label`] === `string`) return r[`label`];
|
|
19220
|
-
if (typeof r[`key`] === `string`) return r[`key`];
|
|
19221
|
-
if (typeof r[`value`] === `string`) return r[`value`];
|
|
19222
|
-
return String(item);
|
|
19223
|
-
};
|
|
19224
|
-
function createFuzzySearch(items, options = {}) {
|
|
19225
|
-
const fzf = new Fzf(items, {
|
|
19226
|
-
selector: options.selector ?? defaultSelector,
|
|
19227
|
-
...options.fzf ?? {}
|
|
19228
|
-
});
|
|
19229
|
-
const find = (query) => {
|
|
19230
|
-
if (!query.trim()) return items.map((item) => ({
|
|
19231
|
-
item,
|
|
19232
|
-
positions: /* @__PURE__ */ new Set(),
|
|
19233
|
-
score: 0
|
|
19234
|
-
}));
|
|
19235
|
-
return fzf.find(query).map((r) => ({
|
|
19236
|
-
item: r.item,
|
|
19237
|
-
positions: r.positions,
|
|
19238
|
-
score: r.score
|
|
19239
|
-
}));
|
|
19240
|
-
};
|
|
19241
|
-
return {
|
|
19242
|
-
find,
|
|
19243
|
-
items
|
|
19244
|
-
};
|
|
19245
|
-
}
|
|
19246
|
-
//#endregion
|
|
19247
|
-
//#region src/incr-search/ac-adapter.ts
|
|
19248
|
-
/**
|
|
19249
|
-
* Creates an ixfx-ac-text-compatible `completionProvider` function from a
|
|
19250
|
-
* static item list. Uses synchronous fuzzy search wrapped in a Promise so it
|
|
19251
|
-
* fits the async provider signature.
|
|
19252
|
-
*
|
|
19253
|
-
* Each returned item has `positions` populated with matched character indices,
|
|
19254
|
-
* which `ixfx-ac-text` uses to render CSS Custom Highlights on the label.
|
|
19255
|
-
*
|
|
19256
|
-
* Empty query returns all items in original order (no positions).
|
|
19257
|
-
* A cancelled signal causes the returned promise to reject with an AbortError.
|
|
19258
|
-
*/
|
|
19259
|
-
function createAcCompletionProvider(items, options = {}) {
|
|
19260
|
-
const fuzzy = createFuzzySearch(items, { selector: options.selector ?? ((item) => item.label) });
|
|
19261
|
-
return (query, signal) => new Promise((resolve, reject) => {
|
|
19262
|
-
if (signal.aborted) {
|
|
19263
|
-
reject(new DOMException(`Aborted`, `AbortError`));
|
|
19264
|
-
return;
|
|
19265
|
-
}
|
|
19266
|
-
const results = fuzzy.find(query).map((r) => ({
|
|
19267
|
-
...r.item,
|
|
19268
|
-
positions: r.positions
|
|
19269
|
-
}));
|
|
19270
|
-
if (signal.aborted) {
|
|
19271
|
-
reject(new DOMException(`Aborted`, `AbortError`));
|
|
19272
|
-
return;
|
|
19273
|
-
}
|
|
19274
|
-
resolve(results);
|
|
19275
|
-
});
|
|
19276
|
-
}
|
|
19277
|
-
//#endregion
|
|
19278
|
-
//#region src/incr-search/incr-search.ts
|
|
19279
|
-
const buildState = (results, query) => {
|
|
19280
|
-
const positionsByItem = /* @__PURE__ */ new Map();
|
|
19281
|
-
for (const r of results) positionsByItem.set(r.item, r.positions);
|
|
19282
|
-
return Object.freeze({
|
|
19283
|
-
query,
|
|
19284
|
-
results: Object.freeze([...results]),
|
|
19285
|
-
positionsByItem
|
|
19286
|
-
});
|
|
19287
|
-
};
|
|
19288
|
-
function createIncrSearch(options = {}) {
|
|
19289
|
-
let items = options.items ?? [];
|
|
19290
|
-
let query = ``;
|
|
19291
|
-
let fuzzy = createFuzzySearch(items, {
|
|
19292
|
-
selector: options.selector,
|
|
19293
|
-
fzf: options.fzf
|
|
19294
|
-
});
|
|
19295
|
-
let state = buildState(fuzzy.find(query), query);
|
|
19296
|
-
let disposed = false;
|
|
19297
|
-
const observers = /* @__PURE__ */ new Set();
|
|
19298
|
-
if (options.onChange) observers.add(options.onChange);
|
|
19299
|
-
const notify = (s) => {
|
|
19300
|
-
for (const cb of observers) cb(s);
|
|
19301
|
-
};
|
|
19302
|
-
const run = async (q, signal) => {
|
|
19303
|
-
await Promise.resolve();
|
|
19304
|
-
if (signal?.aborted || disposed) return state;
|
|
19305
|
-
const results = fuzzy.find(q);
|
|
19306
|
-
if (signal?.aborted || disposed) return state;
|
|
19307
|
-
state = buildState(results, q);
|
|
19308
|
-
notify(state);
|
|
19309
|
-
return state;
|
|
19310
|
-
};
|
|
19311
|
-
return {
|
|
19312
|
-
get state() {
|
|
19313
|
-
return state;
|
|
19314
|
-
},
|
|
19315
|
-
async setItems(newItems, signal) {
|
|
19316
|
-
items = newItems;
|
|
19317
|
-
fuzzy = createFuzzySearch(items, {
|
|
19318
|
-
selector: options.selector,
|
|
19319
|
-
fzf: options.fzf
|
|
19320
|
-
});
|
|
19321
|
-
await run(query, signal);
|
|
19322
|
-
},
|
|
19323
|
-
async setQuery(q, signal) {
|
|
19324
|
-
query = q;
|
|
19325
|
-
return run(q, signal);
|
|
19326
|
-
},
|
|
19327
|
-
async clearQuery() {
|
|
19328
|
-
query = ``;
|
|
19329
|
-
await run(``, void 0);
|
|
19330
|
-
},
|
|
19331
|
-
onChange(cb) {
|
|
19332
|
-
observers.add(cb);
|
|
19333
|
-
cb(state);
|
|
19334
|
-
return () => {
|
|
19335
|
-
observers.delete(cb);
|
|
19336
|
-
};
|
|
19337
|
-
},
|
|
19338
|
-
dispose() {
|
|
19339
|
-
disposed = true;
|
|
19340
|
-
observers.clear();
|
|
19341
|
-
items = [];
|
|
19342
|
-
}
|
|
19343
|
-
};
|
|
19344
|
-
}
|
|
19345
|
-
//#endregion
|
|
19346
|
-
//#region src/incr-search/controller-tree.ts
|
|
19347
|
-
const DEFAULT_HIGHLIGHT_KEY = `incr-search-highlight`;
|
|
19348
|
-
/**
|
|
19349
|
-
* Incremental-search controller for any component implementing `TreeSearchHost`
|
|
19350
|
-
* (i.e. `ixfx-tree-list`, `ixfx-miller-list`, `ixfx-crumb-navigation`).
|
|
19351
|
-
*
|
|
19352
|
-
* Replaces the previous separate `IncrSearchTreeController` / `IncrSearchMillerController`
|
|
19353
|
-
* classes — the unified `TreeFilterPredicate` (with depth) means one implementation works
|
|
19354
|
-
* for all tree-like components.
|
|
19355
|
-
*
|
|
19356
|
-
* @example Using with ixfx-tree-list:
|
|
19357
|
-
* ```typescript
|
|
19358
|
-
* const ctrl = new IncrSearchTreeController(myTreeList, {
|
|
19359
|
-
* selector: item => item.node.item.label,
|
|
19360
|
-
* });
|
|
19361
|
-
* ctrl.connect();
|
|
19362
|
-
* ```
|
|
19363
|
-
*
|
|
19364
|
-
* @example Using with ixfx-miller-list (different label selector):
|
|
19365
|
-
* ```typescript
|
|
19366
|
-
* const ctrl = new IncrSearchTreeController(myMillerList, {
|
|
19367
|
-
* selector: item => item.node.item.label,
|
|
19368
|
-
* labelSelector: '.label',
|
|
19369
|
-
* });
|
|
19370
|
-
* ctrl.connect();
|
|
19371
|
-
* ```
|
|
19372
|
-
*/
|
|
19373
|
-
var IncrSearchTreeController = class {
|
|
19374
|
-
#el;
|
|
19375
|
-
#opts;
|
|
19376
|
-
#search;
|
|
19377
|
-
#unsub;
|
|
19378
|
-
#labelMap = /* @__PURE__ */ new Map();
|
|
19379
|
-
constructor(el, opts) {
|
|
19380
|
-
this.#el = el;
|
|
19381
|
-
this.#opts = opts;
|
|
19382
|
-
this.#search = createIncrSearch({
|
|
19383
|
-
selector: opts.selector,
|
|
19384
|
-
fzf: opts.fzf
|
|
19385
|
-
});
|
|
19386
|
-
}
|
|
19387
|
-
connect() {
|
|
19388
|
-
this.disconnect();
|
|
19389
|
-
const items = this.#el.getNodes();
|
|
19390
|
-
for (const item of items) this.#labelMap.set(this.#opts.selector(item), item);
|
|
19391
|
-
this.#search.setItems(items);
|
|
19392
|
-
if (this.#opts.input) {
|
|
19393
|
-
this.#opts.input.addEventListener(`input`, this.#onInput);
|
|
19394
|
-
this.#opts.input.addEventListener(`keydown`, this.#onKeydown);
|
|
19395
|
-
}
|
|
19396
|
-
this.#unsub = this.#search.onChange((state) => this.#onStateChange(state));
|
|
19397
|
-
}
|
|
19398
|
-
disconnect() {
|
|
19399
|
-
if (this.#unsub) {
|
|
19400
|
-
this.#unsub();
|
|
19401
|
-
this.#unsub = void 0;
|
|
19402
|
-
}
|
|
19403
|
-
if (this.#opts.input) {
|
|
19404
|
-
this.#opts.input.removeEventListener(`input`, this.#onInput);
|
|
19405
|
-
this.#opts.input.removeEventListener(`keydown`, this.#onKeydown);
|
|
19406
|
-
}
|
|
19407
|
-
this.#el.filterPredicate = void 0;
|
|
19408
|
-
clearHighlights({ key: this.#opts.highlightKey ?? DEFAULT_HIGHLIGHT_KEY });
|
|
19409
|
-
this.#labelMap.clear();
|
|
19410
|
-
}
|
|
19411
|
-
async setQuery(query) {
|
|
19412
|
-
await this.#search.setQuery(query);
|
|
19413
|
-
}
|
|
19414
|
-
async clearQuery() {
|
|
19415
|
-
await this.#search.clearQuery();
|
|
19416
|
-
}
|
|
19417
|
-
#onInput = () => {
|
|
19418
|
-
const value = this.#opts.input?.value ?? ``;
|
|
19419
|
-
this.setQuery(value);
|
|
19420
|
-
};
|
|
19421
|
-
#onKeydown = (e) => {
|
|
19422
|
-
if (e.key === `Escape` && this.#opts.input) {
|
|
19423
|
-
this.#opts.input.value = ``;
|
|
19424
|
-
this.clearQuery();
|
|
19425
|
-
}
|
|
19426
|
-
};
|
|
19427
|
-
#onStateChange(state) {
|
|
19428
|
-
const matched = new Set(state.results.map((r) => r.item.node.item.key));
|
|
19429
|
-
const hasQuery = state.query.trim().length > 0;
|
|
19430
|
-
this.#el.filterPredicate = hasQuery && matched.size > 0 ? (node, _depth) => matched.has(node.item.key) : void 0;
|
|
19431
|
-
const key = this.#opts.highlightKey ?? DEFAULT_HIGHLIGHT_KEY;
|
|
19432
|
-
if (!this.#el.shadowRoot) return;
|
|
19433
|
-
if (!state.query.trim()) {
|
|
19434
|
-
clearHighlights({ key });
|
|
19435
|
-
return;
|
|
19436
|
-
}
|
|
19437
|
-
const labelSelector = this.#opts.labelSelector ?? `.tree-label`;
|
|
19438
|
-
applyHighlights(buildHighlightTargets(this.#el.shadowRoot, labelSelector, state.positionsByItem, (labelEl) => {
|
|
19439
|
-
const text = labelEl.textContent ?? ``;
|
|
19440
|
-
return this.#labelMap.get(text);
|
|
19441
|
-
}, (labelEl) => labelEl.textContent ?? ``), { key });
|
|
19442
|
-
}
|
|
19443
|
-
};
|
|
19444
|
-
//#endregion
|
|
19445
|
-
//#region src/incr-search/element-search.ts
|
|
19446
|
-
const defaultGetLabel = (el) => el.textContent?.trim() ?? ``;
|
|
19447
|
-
const defaultGetKey = (el) => el.getAttribute(`data-key`) ?? el.getAttribute(`data-value`) ?? el.textContent?.trim() ?? ``;
|
|
19448
|
-
function createElementIncrSearch(opts) {
|
|
19449
|
-
const { container, itemSelector, getLabel = defaultGetLabel, getKey = defaultGetKey, labelSelector, highlightKey } = opts;
|
|
19450
|
-
let elementByKey = /* @__PURE__ */ new Map();
|
|
19451
|
-
const search = createIncrSearch({
|
|
19452
|
-
selector: (item) => item.label,
|
|
19453
|
-
fzf: opts.fzf
|
|
19454
|
-
});
|
|
19455
|
-
const updateVisibility = (state) => {
|
|
19456
|
-
const matchedKeys = new Set(state.results.map((r) => r.item.key));
|
|
19457
|
-
const hasQuery = state.query.trim().length > 0;
|
|
19458
|
-
for (const [key, el] of elementByKey) el.hidden = hasQuery ? !matchedKeys.has(key) : false;
|
|
19459
|
-
};
|
|
19460
|
-
const updateHighlights = (state) => {
|
|
19461
|
-
if (!state.query.trim()) {
|
|
19462
|
-
clearHighlights({ key: highlightKey });
|
|
19463
|
-
return;
|
|
19464
|
-
}
|
|
19465
|
-
applyHighlights(buildHighlightTargets(container, labelSelector ?? itemSelector, state.positionsByItem, (el) => {
|
|
19466
|
-
const key = getKey(el);
|
|
19467
|
-
return state.results.find((r) => r.item.key === key)?.item;
|
|
19468
|
-
}, (el) => getLabel(el)), { key: highlightKey });
|
|
19469
|
-
};
|
|
19470
|
-
const unsubscribeState = search.onChange((state) => {
|
|
19471
|
-
updateVisibility(state);
|
|
19472
|
-
updateHighlights(state);
|
|
19473
|
-
opts.onChange?.(state);
|
|
19474
|
-
});
|
|
19475
|
-
let refreshPending = false;
|
|
19476
|
-
const refresh = () => {
|
|
19477
|
-
if (refreshPending) return;
|
|
19478
|
-
refreshPending = true;
|
|
19479
|
-
Promise.resolve().then(() => {
|
|
19480
|
-
refreshPending = false;
|
|
19481
|
-
elementByKey = /* @__PURE__ */ new Map();
|
|
19482
|
-
const els = container.querySelectorAll(itemSelector);
|
|
19483
|
-
const items = [];
|
|
19484
|
-
for (const el of els) {
|
|
19485
|
-
const key = getKey(el);
|
|
19486
|
-
elementByKey.set(key, el);
|
|
19487
|
-
items.push({
|
|
19488
|
-
key,
|
|
19489
|
-
label: getLabel(el)
|
|
19490
|
-
});
|
|
19491
|
-
}
|
|
19492
|
-
search.setItems(items);
|
|
19493
|
-
});
|
|
19494
|
-
};
|
|
19495
|
-
const observer = new MutationObserver(() => refresh());
|
|
19496
|
-
observer.observe(container, {
|
|
19497
|
-
childList: true,
|
|
19498
|
-
subtree: false
|
|
19499
|
-
});
|
|
19500
|
-
refresh();
|
|
19501
|
-
return {
|
|
19502
|
-
async setQuery(query, signal) {
|
|
19503
|
-
await search.setQuery(query, signal);
|
|
19504
|
-
},
|
|
19505
|
-
async clearQuery() {
|
|
19506
|
-
await search.clearQuery();
|
|
19507
|
-
},
|
|
19508
|
-
refresh,
|
|
19509
|
-
onChange(cb) {
|
|
19510
|
-
return search.onChange(cb);
|
|
19511
|
-
},
|
|
19512
|
-
dispose() {
|
|
19513
|
-
observer.disconnect();
|
|
19514
|
-
unsubscribeState();
|
|
19515
|
-
search.dispose();
|
|
19516
|
-
clearHighlights({ key: highlightKey });
|
|
19517
|
-
}
|
|
19518
|
-
};
|
|
19519
|
-
}
|
|
19520
|
-
//#endregion
|
|
19521
20114
|
//#region src/narrowed-text/narrowed-text.ts
|
|
19522
20115
|
const HIGHLIGHT_KEY = `narrowed-text-highlight`;
|
|
19523
20116
|
let NarrowedTextElement = class NarrowedTextElement extends i$4 {
|
|
@@ -20084,13 +20677,13 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i$4 {
|
|
|
20084
20677
|
constructor(..._args) {
|
|
20085
20678
|
super(..._args);
|
|
20086
20679
|
this._selectedNodes = /* @__PURE__ */ new Set();
|
|
20087
|
-
this.exclusivity =
|
|
20088
|
-
this.selectionFilter =
|
|
20680
|
+
this.exclusivity = `none`;
|
|
20681
|
+
this.selectionFilter = `leaf`;
|
|
20089
20682
|
this._openIdx = -1;
|
|
20090
20683
|
this._isFocused = false;
|
|
20091
20684
|
this._menuOpen = false;
|
|
20092
20685
|
this._focusOnNarrowedText = false;
|
|
20093
|
-
this.inputMode =
|
|
20686
|
+
this.inputMode = ``;
|
|
20094
20687
|
this.#previousSelectionKey = ``;
|
|
20095
20688
|
this.#menuOpenedByKeyboard = false;
|
|
20096
20689
|
this.#currentOpenTrigger = null;
|
|
@@ -20355,7 +20948,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i$4 {
|
|
|
20355
20948
|
if (model) {
|
|
20356
20949
|
this.root = model.root;
|
|
20357
20950
|
this.#modelUnsubscribe = model._subscribe((event) => {
|
|
20358
|
-
if (event.type ===
|
|
20951
|
+
if (event.type === `root`) {
|
|
20359
20952
|
this.root = event.root;
|
|
20360
20953
|
this.requestUpdate();
|
|
20361
20954
|
}
|
|
@@ -20842,11 +21435,11 @@ __decorate([n$2({ attribute: false })], CrumbNavigationElement.prototype, "loadC
|
|
|
20842
21435
|
__decorate([n$2({ attribute: false })], CrumbNavigationElement.prototype, "filterPredicate", void 0);
|
|
20843
21436
|
__decorate([n$2({
|
|
20844
21437
|
reflect: true,
|
|
20845
|
-
attribute:
|
|
21438
|
+
attribute: `exclusivity`
|
|
20846
21439
|
})], CrumbNavigationElement.prototype, "exclusivity", void 0);
|
|
20847
21440
|
__decorate([n$2({
|
|
20848
21441
|
reflect: true,
|
|
20849
|
-
attribute:
|
|
21442
|
+
attribute: `selection-filter`
|
|
20850
21443
|
})], CrumbNavigationElement.prototype, "selectionFilter", void 0);
|
|
20851
21444
|
__decorate([r$1()], CrumbNavigationElement.prototype, "_openIdx", void 0);
|
|
20852
21445
|
__decorate([r$1()], CrumbNavigationElement.prototype, "_isFocused", void 0);
|
|
@@ -20854,7 +21447,7 @@ __decorate([r$1()], CrumbNavigationElement.prototype, "_menuOpen", void 0);
|
|
|
20854
21447
|
__decorate([r$1()], CrumbNavigationElement.prototype, "_focusOnNarrowedText", void 0);
|
|
20855
21448
|
__decorate([n$2({
|
|
20856
21449
|
reflect: true,
|
|
20857
|
-
attribute:
|
|
21450
|
+
attribute: `input-mode`
|
|
20858
21451
|
})], CrumbNavigationElement.prototype, "inputMode", void 0);
|
|
20859
21452
|
CrumbNavigationElement = __decorate([safeCustomElement(`ixfx-crumb-navigation`)], CrumbNavigationElement);
|
|
20860
21453
|
//#endregion
|
|
@@ -21668,6 +22261,9 @@ let EditableLabel = class EditableLabel extends i$4 {
|
|
|
21668
22261
|
this._hovering = false;
|
|
21669
22262
|
this._startTransientRevertTimer();
|
|
21670
22263
|
};
|
|
22264
|
+
this._handleClick = () => {
|
|
22265
|
+
if (this.mode === `label` && !this.disabled && !this._editing) this._beginEdit();
|
|
22266
|
+
};
|
|
21671
22267
|
this._handleFocus = () => {
|
|
21672
22268
|
if (this.mode === `editor` && !this.disabled && !this._editing) this._beginEdit();
|
|
21673
22269
|
};
|
|
@@ -21703,6 +22299,17 @@ let EditableLabel = class EditableLabel extends i$4 {
|
|
|
21703
22299
|
get _contentEl() {
|
|
21704
22300
|
return this.renderRoot?.querySelector(`.content`) ?? void 0;
|
|
21705
22301
|
}
|
|
22302
|
+
connectedCallback() {
|
|
22303
|
+
super.connectedCallback();
|
|
22304
|
+
this.addEventListener(`mouseenter`, this._onMouseEnter);
|
|
22305
|
+
this.addEventListener(`mouseleave`, this._onMouseLeave);
|
|
22306
|
+
}
|
|
22307
|
+
disconnectedCallback() {
|
|
22308
|
+
super.disconnectedCallback();
|
|
22309
|
+
this.removeEventListener(`mouseenter`, this._onMouseEnter);
|
|
22310
|
+
this.removeEventListener(`mouseleave`, this._onMouseLeave);
|
|
22311
|
+
this._clearTransientTimer();
|
|
22312
|
+
}
|
|
21706
22313
|
_clearTransientTimer() {
|
|
21707
22314
|
if (this._transientTimer !== void 0) {
|
|
21708
22315
|
clearTimeout(this._transientTimer);
|
|
@@ -21796,6 +22403,32 @@ let EditableLabel = class EditableLabel extends i$4 {
|
|
|
21796
22403
|
default: return true;
|
|
21797
22404
|
}
|
|
21798
22405
|
}
|
|
22406
|
+
render() {
|
|
22407
|
+
const isEditor = this.mode === `editor`;
|
|
22408
|
+
return b`<div
|
|
22409
|
+
class="content"
|
|
22410
|
+
contenteditable=${this._editing ? `plaintext-only` : `false`}
|
|
22411
|
+
data-placeholder=${this.placeholder}
|
|
22412
|
+
tabindex=${isEditor && !this._editing ? `0` : A}
|
|
22413
|
+
@click=${this._handleClick}
|
|
22414
|
+
@focus=${this._handleFocus}
|
|
22415
|
+
@blur=${this._handleBlur}
|
|
22416
|
+
@keydown=${this._handleKeydown}
|
|
22417
|
+
@beforeinput=${this._handleBeforeInput}
|
|
22418
|
+
@input=${this._handleInput}
|
|
22419
|
+
>${this._editing ? A : this._getDisplayText()}</div>`;
|
|
22420
|
+
}
|
|
22421
|
+
updated(changed) {
|
|
22422
|
+
super.updated(changed);
|
|
22423
|
+
if (changed.has(`_editing`) && this._editing) {
|
|
22424
|
+
const el = this._contentEl;
|
|
22425
|
+
if (el) {
|
|
22426
|
+
el.textContent = this.value;
|
|
22427
|
+
el.focus();
|
|
22428
|
+
_selectAll(el);
|
|
22429
|
+
}
|
|
22430
|
+
}
|
|
22431
|
+
}
|
|
21799
22432
|
static {
|
|
21800
22433
|
this.styles = [i$7`
|
|
21801
22434
|
:host {
|
|
@@ -21908,6 +22541,13 @@ __decorate([n$2({ attribute: false })], EditableLabel.prototype, "validator", vo
|
|
|
21908
22541
|
__decorate([n$2({ attribute: false })], EditableLabel.prototype, "formatter", void 0);
|
|
21909
22542
|
__decorate([r$1()], EditableLabel.prototype, "_editing", void 0);
|
|
21910
22543
|
EditableLabel = __decorate([safeCustomElement(`ixfx-editable-label`)], EditableLabel);
|
|
22544
|
+
function _selectAll(el) {
|
|
22545
|
+
const range = document.createRange();
|
|
22546
|
+
range.selectNodeContents(el);
|
|
22547
|
+
const sel = window.getSelection();
|
|
22548
|
+
sel?.removeAllRanges();
|
|
22549
|
+
sel?.addRange(range);
|
|
22550
|
+
}
|
|
21911
22551
|
//#endregion
|
|
21912
22552
|
//#region src/keyboard.ts
|
|
21913
22553
|
/**
|
|
@@ -22509,7 +23149,7 @@ EditableNumber = __decorate([safeCustomElement(`ixfx-editable-number`)], Editabl
|
|
|
22509
23149
|
* @license
|
|
22510
23150
|
* Copyright 2020 Google LLC
|
|
22511
23151
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
22512
|
-
*/ const { I: t$1 } = j$1, i$
|
|
23152
|
+
*/ const { I: t$1 } = j$1, i$2 = (o) => o, s = () => document.createComment(""), v = (o, n, e) => {
|
|
22513
23153
|
const l = o._$AA.parentNode, d = void 0 === n ? o._$AB : n._$AA;
|
|
22514
23154
|
if (void 0 === e) e = new t$1(l.insertBefore(s(), d), l.insertBefore(s(), d), o, o.options);
|
|
22515
23155
|
else {
|
|
@@ -22521,8 +23161,8 @@ EditableNumber = __decorate([safeCustomElement(`ixfx-editable-number`)], Editabl
|
|
|
22521
23161
|
if (t !== d || c) {
|
|
22522
23162
|
let o = e._$AA;
|
|
22523
23163
|
for (; o !== t;) {
|
|
22524
|
-
const t = i$
|
|
22525
|
-
i$
|
|
23164
|
+
const t = i$2(o).nextSibling;
|
|
23165
|
+
i$2(l).insertBefore(o, d), o = t;
|
|
22526
23166
|
}
|
|
22527
23167
|
}
|
|
22528
23168
|
}
|
|
@@ -22591,6 +23231,37 @@ const u = (e, s, t) => {
|
|
|
22591
23231
|
}
|
|
22592
23232
|
});
|
|
22593
23233
|
//#endregion
|
|
23234
|
+
//#region node_modules/.pnpm/lit-html@3.3.3/node_modules/lit-html/directives/style-map.js
|
|
23235
|
+
/**
|
|
23236
|
+
* @license
|
|
23237
|
+
* Copyright 2018 Google LLC
|
|
23238
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
23239
|
+
*/ const n = "important", i$1 = " !" + n, o = e$3(class extends i$3 {
|
|
23240
|
+
constructor(t) {
|
|
23241
|
+
if (super(t), t.type !== t$2.ATTRIBUTE || "style" !== t.name || t.strings?.length > 2) throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.");
|
|
23242
|
+
}
|
|
23243
|
+
render(t) {
|
|
23244
|
+
return Object.keys(t).reduce((e, r) => {
|
|
23245
|
+
const s = t[r];
|
|
23246
|
+
return null == s ? e : e + `${r = r.includes("-") ? r : r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g, "-$&").toLowerCase()}:${s};`;
|
|
23247
|
+
}, "");
|
|
23248
|
+
}
|
|
23249
|
+
update(e, [r]) {
|
|
23250
|
+
const { style: s } = e.element;
|
|
23251
|
+
if (void 0 === this.ft) return this.ft = new Set(Object.keys(r)), this.render(r);
|
|
23252
|
+
for (const t of this.ft) r[t] ?? (this.ft.delete(t), t.includes("-") ? s.removeProperty(t) : s[t] = null);
|
|
23253
|
+
for (const t in r) {
|
|
23254
|
+
const e = r[t];
|
|
23255
|
+
if (null != e) {
|
|
23256
|
+
this.ft.add(t);
|
|
23257
|
+
const r = "string" == typeof e && e.endsWith(i$1);
|
|
23258
|
+
t.includes("-") || r ? s.setProperty(t, r ? e.slice(0, -11) : e, r ? n : "") : s[t] = e;
|
|
23259
|
+
}
|
|
23260
|
+
}
|
|
23261
|
+
return E;
|
|
23262
|
+
}
|
|
23263
|
+
});
|
|
23264
|
+
//#endregion
|
|
22594
23265
|
//#region src/hex/colour.ts
|
|
22595
23266
|
const WHITESPACE_BYTES = new Set([
|
|
22596
23267
|
9,
|
|
@@ -22600,45 +23271,45 @@ const WHITESPACE_BYTES = new Set([
|
|
|
22600
23271
|
13,
|
|
22601
23272
|
32
|
|
22602
23273
|
]);
|
|
22603
|
-
|
|
23274
|
+
function isControlByte(byte) {
|
|
22604
23275
|
return byte < 32 && byte !== 9 && byte !== 10 && byte !== 11 && byte !== 12 && byte !== 13;
|
|
22605
|
-
}
|
|
22606
|
-
|
|
23276
|
+
}
|
|
23277
|
+
function isPrintableAscii(byte) {
|
|
22607
23278
|
return byte >= 32 && byte <= 126;
|
|
22608
|
-
}
|
|
22609
|
-
|
|
22610
|
-
if (byte === 0) return
|
|
22611
|
-
if (WHITESPACE_BYTES.has(byte)) return
|
|
22612
|
-
if (isControlByte(byte)) return
|
|
22613
|
-
if (isPrintableAscii(byte)) return
|
|
22614
|
-
return
|
|
22615
|
-
}
|
|
22616
|
-
|
|
23279
|
+
}
|
|
23280
|
+
function getAsciiClass(byte) {
|
|
23281
|
+
if (byte === 0) return `byte-null`;
|
|
23282
|
+
if (WHITESPACE_BYTES.has(byte)) return `byte-whitespace`;
|
|
23283
|
+
if (isControlByte(byte)) return `byte-control`;
|
|
23284
|
+
if (isPrintableAscii(byte)) return `byte-printable`;
|
|
23285
|
+
return `byte-other`;
|
|
23286
|
+
}
|
|
23287
|
+
function createShadeMap(nullColour, maxColour, stepStart, stepEnd) {
|
|
22617
23288
|
const cssSteps = colour_exports.createSteps(stepStart, stepEnd, { steps: 16 }).map(colour_exports.toCssColour);
|
|
22618
23289
|
return { forByte: (byte) => {
|
|
22619
23290
|
if (byte === 0) return nullColour;
|
|
22620
23291
|
if (byte === 255) return maxColour;
|
|
22621
23292
|
return cssSteps[byte >> 4];
|
|
22622
23293
|
} };
|
|
22623
|
-
}
|
|
23294
|
+
}
|
|
22624
23295
|
//#endregion
|
|
22625
23296
|
//#region src/hex/data.ts
|
|
22626
|
-
|
|
23297
|
+
function createHexStore(data) {
|
|
22627
23298
|
return {
|
|
22628
23299
|
data: new Uint8Array(data),
|
|
22629
23300
|
changeset: /* @__PURE__ */ new Set()
|
|
22630
23301
|
};
|
|
22631
|
-
}
|
|
22632
|
-
|
|
23302
|
+
}
|
|
23303
|
+
function readByte(store, pos) {
|
|
22633
23304
|
return store.data[pos] ?? 0;
|
|
22634
|
-
}
|
|
22635
|
-
|
|
23305
|
+
}
|
|
23306
|
+
function length(store) {
|
|
22636
23307
|
return store.data.length;
|
|
22637
|
-
}
|
|
22638
|
-
|
|
23308
|
+
}
|
|
23309
|
+
function clamp$1(value) {
|
|
22639
23310
|
return Math.max(0, Math.min(255, value));
|
|
22640
|
-
}
|
|
22641
|
-
|
|
23311
|
+
}
|
|
23312
|
+
function writeByte(store, pos, value) {
|
|
22642
23313
|
const clampedValue = clamp$1(value);
|
|
22643
23314
|
const before = store.data[pos];
|
|
22644
23315
|
const diff = new Map([[pos, {
|
|
@@ -22648,8 +23319,8 @@ const writeByte = (store, pos, value) => {
|
|
|
22648
23319
|
store.data[pos] = clampedValue;
|
|
22649
23320
|
store.changeset.add(pos);
|
|
22650
23321
|
return diff;
|
|
22651
|
-
}
|
|
22652
|
-
|
|
23322
|
+
}
|
|
23323
|
+
function writeBytes(store, entries) {
|
|
22653
23324
|
const diff = /* @__PURE__ */ new Map();
|
|
22654
23325
|
entries.forEach((value, pos) => {
|
|
22655
23326
|
const clampedValue = clamp$1(value);
|
|
@@ -22662,8 +23333,8 @@ const writeBytes = (store, entries) => {
|
|
|
22662
23333
|
store.changeset.add(pos);
|
|
22663
23334
|
});
|
|
22664
23335
|
return diff;
|
|
22665
|
-
}
|
|
22666
|
-
|
|
23336
|
+
}
|
|
23337
|
+
function applyDiff(store, diff) {
|
|
22667
23338
|
const reverse = /* @__PURE__ */ new Map();
|
|
22668
23339
|
diff.forEach((entry, pos) => {
|
|
22669
23340
|
const before = store.data[pos];
|
|
@@ -22675,8 +23346,8 @@ const applyDiff = (store, diff) => {
|
|
|
22675
23346
|
store.changeset.add(pos);
|
|
22676
23347
|
});
|
|
22677
23348
|
return reverse;
|
|
22678
|
-
}
|
|
22679
|
-
|
|
23349
|
+
}
|
|
23350
|
+
function reverseDiff(diff) {
|
|
22680
23351
|
const reversed = /* @__PURE__ */ new Map();
|
|
22681
23352
|
diff.forEach((entry, pos) => {
|
|
22682
23353
|
reversed.set(pos, {
|
|
@@ -22685,52 +23356,52 @@ const reverseDiff = (diff) => {
|
|
|
22685
23356
|
});
|
|
22686
23357
|
});
|
|
22687
23358
|
return reversed;
|
|
22688
|
-
}
|
|
22689
|
-
|
|
23359
|
+
}
|
|
23360
|
+
function getChangeset(store) {
|
|
22690
23361
|
return store.changeset;
|
|
22691
|
-
}
|
|
23362
|
+
}
|
|
22692
23363
|
//#endregion
|
|
22693
23364
|
//#region src/hex/diff.ts
|
|
22694
|
-
|
|
23365
|
+
function createUndoRedoStack() {
|
|
22695
23366
|
return {
|
|
22696
23367
|
undos: [],
|
|
22697
23368
|
redos: []
|
|
22698
23369
|
};
|
|
22699
|
-
}
|
|
22700
|
-
|
|
23370
|
+
}
|
|
23371
|
+
function push(stack, diff) {
|
|
22701
23372
|
stack.undos.push(diff);
|
|
22702
23373
|
stack.redos = [];
|
|
22703
|
-
}
|
|
22704
|
-
|
|
23374
|
+
}
|
|
23375
|
+
function undo(stack) {
|
|
22705
23376
|
const diff = stack.undos.pop();
|
|
22706
23377
|
if (diff) stack.redos.push(diff);
|
|
22707
23378
|
return diff;
|
|
22708
|
-
}
|
|
22709
|
-
|
|
23379
|
+
}
|
|
23380
|
+
function redo(stack) {
|
|
22710
23381
|
const diff = stack.redos.pop();
|
|
22711
23382
|
if (diff) stack.undos.push(diff);
|
|
22712
23383
|
return diff;
|
|
22713
|
-
}
|
|
23384
|
+
}
|
|
22714
23385
|
//#endregion
|
|
22715
23386
|
//#region src/hex/selection.ts
|
|
22716
23387
|
const bytesPerRow = (columns) => columns * 4;
|
|
22717
23388
|
const min = (a, b) => a < b ? a : b;
|
|
22718
23389
|
const max = (a, b) => a > b ? a : b;
|
|
22719
|
-
|
|
23390
|
+
function clampPos(pos, dataLength) {
|
|
22720
23391
|
return Math.max(0, Math.min(pos, dataLength - 1));
|
|
22721
|
-
}
|
|
22722
|
-
|
|
23392
|
+
}
|
|
23393
|
+
function getSelectedPositions(sel, columns) {
|
|
22723
23394
|
if (!sel) return [];
|
|
22724
23395
|
const bpr = bytesPerRow(columns);
|
|
22725
|
-
if (sel.kind ===
|
|
22726
|
-
if (sel.kind ===
|
|
23396
|
+
if (sel.kind === `single`) return [sel.pos];
|
|
23397
|
+
if (sel.kind === `contiguous`) {
|
|
22727
23398
|
const start = min(sel.start, sel.end);
|
|
22728
23399
|
const end = max(sel.start, sel.end);
|
|
22729
23400
|
const positions = [];
|
|
22730
23401
|
for (let i = start; i <= end; i++) positions.push(i);
|
|
22731
23402
|
return positions;
|
|
22732
23403
|
}
|
|
22733
|
-
if (sel.kind ===
|
|
23404
|
+
if (sel.kind === `rectangular`) {
|
|
22734
23405
|
const positions = [];
|
|
22735
23406
|
for (let row = 0; row < sel.height; row++) for (let col = 0; col < sel.width; col++) {
|
|
22736
23407
|
const y = sel.y + row;
|
|
@@ -22741,17 +23412,17 @@ const getSelectedPositions = (sel, columns) => {
|
|
|
22741
23412
|
return positions;
|
|
22742
23413
|
}
|
|
22743
23414
|
return [];
|
|
22744
|
-
}
|
|
22745
|
-
|
|
23415
|
+
}
|
|
23416
|
+
function selectionContains(sel, pos, columns) {
|
|
22746
23417
|
if (!sel) return false;
|
|
22747
23418
|
const bpr = bytesPerRow(columns);
|
|
22748
|
-
if (sel.kind ===
|
|
22749
|
-
if (sel.kind ===
|
|
23419
|
+
if (sel.kind === `single`) return pos === sel.pos;
|
|
23420
|
+
if (sel.kind === `contiguous`) {
|
|
22750
23421
|
const start = min(sel.start, sel.end);
|
|
22751
23422
|
const end = max(sel.start, sel.end);
|
|
22752
23423
|
return pos >= start && pos <= end;
|
|
22753
23424
|
}
|
|
22754
|
-
if (sel.kind ===
|
|
23425
|
+
if (sel.kind === `rectangular`) {
|
|
22755
23426
|
const row = Math.floor(pos / bpr);
|
|
22756
23427
|
const col = pos % bpr;
|
|
22757
23428
|
const x = sel.x;
|
|
@@ -22761,59 +23432,59 @@ const selectionContains = (sel, pos, columns) => {
|
|
|
22761
23432
|
return row >= y && row < y + height && col >= x && col < x + width;
|
|
22762
23433
|
}
|
|
22763
23434
|
return false;
|
|
22764
|
-
}
|
|
22765
|
-
|
|
23435
|
+
}
|
|
23436
|
+
function getCursorPos(sel, dir, columns, dataLength) {
|
|
22766
23437
|
let currentPos;
|
|
22767
23438
|
if (!sel) currentPos = 0;
|
|
22768
|
-
else if (sel.kind ===
|
|
22769
|
-
else if (sel.kind ===
|
|
22770
|
-
else if (sel.kind ===
|
|
23439
|
+
else if (sel.kind === `single`) currentPos = sel.pos;
|
|
23440
|
+
else if (sel.kind === `contiguous`) currentPos = max(sel.start, sel.end);
|
|
23441
|
+
else if (sel.kind === `rectangular`) currentPos = sel.y * bytesPerRow(columns) + sel.x + sel.width - 1;
|
|
22771
23442
|
else currentPos = 0;
|
|
22772
23443
|
const bpr = bytesPerRow(columns);
|
|
22773
23444
|
let newPos;
|
|
22774
23445
|
switch (dir) {
|
|
22775
|
-
case
|
|
23446
|
+
case `left`:
|
|
22776
23447
|
newPos = currentPos - 1;
|
|
22777
23448
|
break;
|
|
22778
|
-
case
|
|
23449
|
+
case `right`:
|
|
22779
23450
|
newPos = currentPos + 1;
|
|
22780
23451
|
break;
|
|
22781
|
-
case
|
|
23452
|
+
case `up`:
|
|
22782
23453
|
newPos = currentPos - bpr;
|
|
22783
23454
|
break;
|
|
22784
|
-
case
|
|
23455
|
+
case `down`:
|
|
22785
23456
|
newPos = currentPos + bpr;
|
|
22786
23457
|
break;
|
|
22787
23458
|
default: newPos = currentPos;
|
|
22788
23459
|
}
|
|
22789
23460
|
return clampPos(newPos, dataLength);
|
|
22790
|
-
}
|
|
22791
|
-
|
|
23461
|
+
}
|
|
23462
|
+
function moveSelection(sel, dir, columns, dataLength) {
|
|
22792
23463
|
return {
|
|
22793
|
-
kind:
|
|
23464
|
+
kind: `single`,
|
|
22794
23465
|
pos: getCursorPos(sel, dir, columns, dataLength)
|
|
22795
23466
|
};
|
|
22796
|
-
}
|
|
22797
|
-
|
|
23467
|
+
}
|
|
23468
|
+
function extendRectangular(sel, dir, columns, _dataLength, anchorX = 0, anchorY = 0) {
|
|
22798
23469
|
const bpr = bytesPerRow(columns);
|
|
22799
23470
|
let x;
|
|
22800
23471
|
let y;
|
|
22801
23472
|
let width;
|
|
22802
23473
|
let height;
|
|
22803
|
-
if (!sel || sel.kind ===
|
|
22804
|
-
const pos = sel?.kind ===
|
|
23474
|
+
if (!sel || sel.kind === `single`) {
|
|
23475
|
+
const pos = sel?.kind === `single` ? sel.pos : 0;
|
|
22805
23476
|
x = pos % bpr;
|
|
22806
23477
|
y = Math.floor(pos / bpr);
|
|
22807
23478
|
width = 1;
|
|
22808
23479
|
height = 1;
|
|
22809
|
-
} else if (sel.kind ===
|
|
23480
|
+
} else if (sel.kind === `contiguous`) {
|
|
22810
23481
|
const start = min(sel.start, sel.end);
|
|
22811
23482
|
const end = max(sel.start, sel.end);
|
|
22812
23483
|
x = start % bpr;
|
|
22813
23484
|
y = Math.floor(start / bpr);
|
|
22814
23485
|
width = end - start + 1;
|
|
22815
23486
|
height = 1;
|
|
22816
|
-
} else if (sel.kind ===
|
|
23487
|
+
} else if (sel.kind === `rectangular`) {
|
|
22817
23488
|
x = sel.x;
|
|
22818
23489
|
y = sel.y;
|
|
22819
23490
|
width = sel.width;
|
|
@@ -22824,10 +23495,10 @@ const extendRectangular = (sel, dir, columns, _dataLength, anchorX = 0, anchorY
|
|
|
22824
23495
|
width = 1;
|
|
22825
23496
|
height = 1;
|
|
22826
23497
|
}
|
|
22827
|
-
const effectiveAnchorX = anchorX > 0 || sel?.kind ===
|
|
22828
|
-
const effectiveAnchorY = anchorY > 0 || sel?.kind ===
|
|
23498
|
+
const effectiveAnchorX = anchorX > 0 || sel?.kind === `rectangular` ? anchorX : x;
|
|
23499
|
+
const effectiveAnchorY = anchorY > 0 || sel?.kind === `rectangular` ? anchorY : y;
|
|
22829
23500
|
switch (dir) {
|
|
22830
|
-
case
|
|
23501
|
+
case `left`:
|
|
22831
23502
|
if (x > effectiveAnchorX) width -= 1;
|
|
22832
23503
|
else if (x === effectiveAnchorX && width > 1) {
|
|
22833
23504
|
x -= 1;
|
|
@@ -22837,10 +23508,10 @@ const extendRectangular = (sel, dir, columns, _dataLength, anchorX = 0, anchorY
|
|
|
22837
23508
|
width += 1;
|
|
22838
23509
|
}
|
|
22839
23510
|
break;
|
|
22840
|
-
case
|
|
23511
|
+
case `right`:
|
|
22841
23512
|
if (x + width < bpr) width += 1;
|
|
22842
23513
|
break;
|
|
22843
|
-
case
|
|
23514
|
+
case `up`:
|
|
22844
23515
|
if (y > effectiveAnchorY) height -= 1;
|
|
22845
23516
|
else if (y === effectiveAnchorY && height > 1) {
|
|
22846
23517
|
y -= 1;
|
|
@@ -22850,22 +23521,22 @@ const extendRectangular = (sel, dir, columns, _dataLength, anchorX = 0, anchorY
|
|
|
22850
23521
|
height += 1;
|
|
22851
23522
|
}
|
|
22852
23523
|
break;
|
|
22853
|
-
case
|
|
23524
|
+
case `down`:
|
|
22854
23525
|
height += 1;
|
|
22855
23526
|
break;
|
|
22856
23527
|
}
|
|
22857
23528
|
return {
|
|
22858
|
-
kind:
|
|
23529
|
+
kind: `rectangular`,
|
|
22859
23530
|
x,
|
|
22860
23531
|
y,
|
|
22861
23532
|
width,
|
|
22862
23533
|
height
|
|
22863
23534
|
};
|
|
22864
|
-
}
|
|
22865
|
-
|
|
23535
|
+
}
|
|
23536
|
+
function selectionFromPointerRange(start, end, mode, columns) {
|
|
22866
23537
|
const bpr = bytesPerRow(columns);
|
|
22867
|
-
if (mode ===
|
|
22868
|
-
kind:
|
|
23538
|
+
if (mode === `contiguous`) return {
|
|
23539
|
+
kind: `contiguous`,
|
|
22869
23540
|
start: min(start, end),
|
|
22870
23541
|
end: max(start, end)
|
|
22871
23542
|
};
|
|
@@ -22874,13 +23545,13 @@ const selectionFromPointerRange = (start, end, mode, columns) => {
|
|
|
22874
23545
|
const endX = end % bpr;
|
|
22875
23546
|
const endY = Math.floor(end / bpr);
|
|
22876
23547
|
return {
|
|
22877
|
-
kind:
|
|
23548
|
+
kind: `rectangular`,
|
|
22878
23549
|
x: min(startX, endX),
|
|
22879
23550
|
y: min(startY, endY),
|
|
22880
23551
|
width: Math.abs(endX - startX) + 1,
|
|
22881
23552
|
height: Math.abs(endY - startY) + 1
|
|
22882
23553
|
};
|
|
22883
|
-
}
|
|
23554
|
+
}
|
|
22884
23555
|
//#endregion
|
|
22885
23556
|
//#region src/hex/hex-editor.ts
|
|
22886
23557
|
let IxfxHexEditorElement = class IxfxHexEditorElement extends i$4 {
|
|
@@ -23675,7 +24346,7 @@ let IxfxHexEditorElement = class IxfxHexEditorElement extends i$4 {
|
|
|
23675
24346
|
return b`
|
|
23676
24347
|
<span
|
|
23677
24348
|
class=${classes.join(` `)}
|
|
23678
|
-
style=${o
|
|
24349
|
+
style=${o(colourStyle || {})}
|
|
23679
24350
|
@pointerdown=${(e) => this._onPointerDown(pos, `hex`, e)}
|
|
23680
24351
|
@pointerup=${(e) => this._onPointerUp(pos, `hex`, e)}
|
|
23681
24352
|
@pointermove=${(e) => this._onPointerMove(pos, `hex`, e)}
|
|
@@ -23698,7 +24369,7 @@ let IxfxHexEditorElement = class IxfxHexEditorElement extends i$4 {
|
|
|
23698
24369
|
return b`
|
|
23699
24370
|
<span
|
|
23700
24371
|
class=${classes.join(` `)}
|
|
23701
|
-
style=${o
|
|
24372
|
+
style=${o(colourStyle || {})}
|
|
23702
24373
|
@pointerdown=${(e) => this._onPointerDown(pos, `text`, e)}
|
|
23703
24374
|
@pointerup=${(e) => this._onPointerUp(pos, `text`, e)}
|
|
23704
24375
|
@pointermove=${(e) => this._onPointerMove(pos, `text`, e)}
|
|
@@ -23774,10 +24445,10 @@ function getFlattenedCircleAngles(flatten) {
|
|
|
23774
24445
|
function valueToAngle(relativeValue, valueMode, flatten) {
|
|
23775
24446
|
const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);
|
|
23776
24447
|
switch (valueMode) {
|
|
23777
|
-
case
|
|
23778
|
-
case
|
|
24448
|
+
case `range`: return startAngle + relativeValue * totalArc;
|
|
24449
|
+
case `bipolar`: if (relativeValue <= .5) return startAngle + relativeValue / .5 * (MIDPOINT_ANGLE - startAngle);
|
|
23779
24450
|
else return MIDPOINT_ANGLE + (relativeValue - .5) / .5 * (endAngle - MIDPOINT_ANGLE);
|
|
23780
|
-
case
|
|
24451
|
+
case `unipolar`: return MIDPOINT_ANGLE;
|
|
23781
24452
|
default: return startAngle;
|
|
23782
24453
|
}
|
|
23783
24454
|
}
|
|
@@ -23791,11 +24462,11 @@ function valueToAngle(relativeValue, valueMode, flatten) {
|
|
|
23791
24462
|
function getValueArcAngles(relativeValue, valueMode, flatten) {
|
|
23792
24463
|
const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);
|
|
23793
24464
|
switch (valueMode) {
|
|
23794
|
-
case
|
|
24465
|
+
case `range`: return {
|
|
23795
24466
|
startAngle,
|
|
23796
24467
|
endAngle: startAngle + relativeValue * totalArc
|
|
23797
24468
|
};
|
|
23798
|
-
case
|
|
24469
|
+
case `bipolar`: if (relativeValue < .5) return {
|
|
23799
24470
|
startAngle: startAngle + relativeValue / .5 * (MIDPOINT_ANGLE - startAngle),
|
|
23800
24471
|
endAngle: MIDPOINT_ANGLE
|
|
23801
24472
|
};
|
|
@@ -23807,7 +24478,7 @@ function getValueArcAngles(relativeValue, valueMode, flatten) {
|
|
|
23807
24478
|
startAngle: MIDPOINT_ANGLE,
|
|
23808
24479
|
endAngle: MIDPOINT_ANGLE
|
|
23809
24480
|
};
|
|
23810
|
-
case
|
|
24481
|
+
case `unipolar`: {
|
|
23811
24482
|
const spreadAmount = relativeValue * totalArc / 2;
|
|
23812
24483
|
return {
|
|
23813
24484
|
startAngle: MIDPOINT_ANGLE - spreadAmount,
|
|
@@ -23858,7 +24529,7 @@ function generateArcPath(startAngle, endAngle, radius, center = {
|
|
|
23858
24529
|
x: 50,
|
|
23859
24530
|
y: 50
|
|
23860
24531
|
}) {
|
|
23861
|
-
if (startAngle === endAngle) return
|
|
24532
|
+
if (startAngle === endAngle) return ``;
|
|
23862
24533
|
let arcLength = endAngle - startAngle;
|
|
23863
24534
|
if (arcLength < 0) arcLength += PI2;
|
|
23864
24535
|
if (arcLength >= PI2 - .001) {
|
|
@@ -23899,7 +24570,7 @@ function generateWedgePath(startAngle, endAngle, radius, center = {
|
|
|
23899
24570
|
x: 50,
|
|
23900
24571
|
y: 50
|
|
23901
24572
|
}, clockwise = true) {
|
|
23902
|
-
if (startAngle === endAngle) return
|
|
24573
|
+
if (startAngle === endAngle) return ``;
|
|
23903
24574
|
let arcLength = endAngle - startAngle;
|
|
23904
24575
|
if (arcLength < 0) arcLength += PI2;
|
|
23905
24576
|
if (arcLength >= PI2 - .001) {
|
|
@@ -23935,12 +24606,12 @@ function getWedgeAngles(relativeValue, valueMode, flatten) {
|
|
|
23935
24606
|
const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);
|
|
23936
24607
|
const valueAngle = valueToAngle(relativeValue, valueMode, flatten);
|
|
23937
24608
|
switch (valueMode) {
|
|
23938
|
-
case
|
|
24609
|
+
case `range`: return {
|
|
23939
24610
|
startAngle,
|
|
23940
24611
|
endAngle: valueAngle,
|
|
23941
24612
|
clockwise: true
|
|
23942
24613
|
};
|
|
23943
|
-
case
|
|
24614
|
+
case `bipolar`: if (relativeValue < .5) return {
|
|
23944
24615
|
startAngle: MIDPOINT_ANGLE,
|
|
23945
24616
|
endAngle: valueAngle,
|
|
23946
24617
|
clockwise: false
|
|
@@ -23950,7 +24621,7 @@ function getWedgeAngles(relativeValue, valueMode, flatten) {
|
|
|
23950
24621
|
endAngle: valueAngle,
|
|
23951
24622
|
clockwise: true
|
|
23952
24623
|
};
|
|
23953
|
-
case
|
|
24624
|
+
case `unipolar`: {
|
|
23954
24625
|
const halfSpread = relativeValue * totalArc / 2;
|
|
23955
24626
|
return {
|
|
23956
24627
|
startAngle: MIDPOINT_ANGLE - halfSpread,
|
|
@@ -25091,32 +25762,6 @@ var MenuCommandController = class {
|
|
|
25091
25762
|
}
|
|
25092
25763
|
};
|
|
25093
25764
|
//#endregion
|
|
25094
|
-
//#region src/menu/menu-header.ts
|
|
25095
|
-
let MenuHeader = class MenuHeader extends i$4 {
|
|
25096
|
-
constructor(..._args) {
|
|
25097
|
-
super(..._args);
|
|
25098
|
-
this.label = ``;
|
|
25099
|
-
}
|
|
25100
|
-
static {
|
|
25101
|
-
this.styles = i$7`
|
|
25102
|
-
:host {
|
|
25103
|
-
display: block;
|
|
25104
|
-
padding: 6px var(--space-m) var(--space-xs);
|
|
25105
|
-
font-size: var(--text-s);
|
|
25106
|
-
font-weight: var(--font-weight-bold);
|
|
25107
|
-
text-transform: uppercase;
|
|
25108
|
-
color: var(--surface-muted-text);
|
|
25109
|
-
letter-spacing: 0.5px;
|
|
25110
|
-
}
|
|
25111
|
-
`;
|
|
25112
|
-
}
|
|
25113
|
-
render() {
|
|
25114
|
-
return b`<div>${this.label}</div>`;
|
|
25115
|
-
}
|
|
25116
|
-
};
|
|
25117
|
-
__decorate([n$2({ type: String })], MenuHeader.prototype, "label", void 0);
|
|
25118
|
-
MenuHeader = __decorate([safeCustomElement(`ixfx-menu-header`)], MenuHeader);
|
|
25119
|
-
//#endregion
|
|
25120
25765
|
//#region src/menu/menu-sub-trigger.ts
|
|
25121
25766
|
var _MenuSubTrigger;
|
|
25122
25767
|
let MenuSubTrigger = class MenuSubTrigger extends i$4 {
|
|
@@ -25395,6 +26040,32 @@ let MenuSeparator = class MenuSeparator extends i$4 {
|
|
|
25395
26040
|
};
|
|
25396
26041
|
MenuSeparator = __decorate([safeCustomElement(`ixfx-menu-separator`)], MenuSeparator);
|
|
25397
26042
|
//#endregion
|
|
26043
|
+
//#region src/menu/menu-header.ts
|
|
26044
|
+
let MenuHeader = class MenuHeader extends i$4 {
|
|
26045
|
+
constructor(..._args) {
|
|
26046
|
+
super(..._args);
|
|
26047
|
+
this.label = ``;
|
|
26048
|
+
}
|
|
26049
|
+
static {
|
|
26050
|
+
this.styles = i$7`
|
|
26051
|
+
:host {
|
|
26052
|
+
display: block;
|
|
26053
|
+
padding: 6px var(--space-m) var(--space-xs);
|
|
26054
|
+
font-size: var(--text-s);
|
|
26055
|
+
font-weight: var(--font-weight-bold);
|
|
26056
|
+
text-transform: uppercase;
|
|
26057
|
+
color: var(--surface-muted-text);
|
|
26058
|
+
letter-spacing: 0.5px;
|
|
26059
|
+
}
|
|
26060
|
+
`;
|
|
26061
|
+
}
|
|
26062
|
+
render() {
|
|
26063
|
+
return b`<div>${this.label}</div>`;
|
|
26064
|
+
}
|
|
26065
|
+
};
|
|
26066
|
+
__decorate([n$2({ type: String })], MenuHeader.prototype, "label", void 0);
|
|
26067
|
+
MenuHeader = __decorate([safeCustomElement(`ixfx-menu-header`)], MenuHeader);
|
|
26068
|
+
//#endregion
|
|
25398
26069
|
//#region src/menu/menu-from-tree.ts
|
|
25399
26070
|
function isLeaf(node) {
|
|
25400
26071
|
return node.children === void 0 || node.children.length === 0;
|
|
@@ -25403,8 +26074,8 @@ function menuFromTree(nodes, options = {}) {
|
|
|
25403
26074
|
const { onCommand, registry, keyboardManager } = options;
|
|
25404
26075
|
return b`${nodes.map((node) => {
|
|
25405
26076
|
const label = node.item.label;
|
|
25406
|
-
if (label ===
|
|
25407
|
-
if (label.startsWith(
|
|
26077
|
+
if (label === `-`) return b`<ixfx-menu-separator></ixfx-menu-separator>`;
|
|
26078
|
+
if (label.startsWith(`# `)) return b`<ixfx-menu-header label="${label.slice(2)}"></ixfx-menu-header>`;
|
|
25408
26079
|
if (!isLeaf(node)) {
|
|
25409
26080
|
const submenu = menuFromTree(node.children, options);
|
|
25410
26081
|
return b`
|
|
@@ -25430,30 +26101,30 @@ function menuFromTree(nodes, options = {}) {
|
|
|
25430
26101
|
function buildMenuItemEl(node, options) {
|
|
25431
26102
|
const { onCommand, registry } = options;
|
|
25432
26103
|
const label = node.item.label;
|
|
25433
|
-
const el = document.createElement(
|
|
25434
|
-
el.setAttribute(
|
|
25435
|
-
el.setAttribute(
|
|
25436
|
-
if (node.item.icon) el.setAttribute(
|
|
25437
|
-
if (onCommand) el.addEventListener(
|
|
26104
|
+
const el = document.createElement(`ixfx-menu-item`);
|
|
26105
|
+
el.setAttribute(`command`, node.item.key);
|
|
26106
|
+
el.setAttribute(`label`, label);
|
|
26107
|
+
if (node.item.icon) el.setAttribute(`icon-name`, node.item.icon);
|
|
26108
|
+
if (onCommand) el.addEventListener(`command`, (e) => onCommand(e.detail));
|
|
25438
26109
|
if (registry) el.registry = registry;
|
|
25439
26110
|
return el;
|
|
25440
26111
|
}
|
|
25441
26112
|
function buildMenuSeparatorEl() {
|
|
25442
|
-
return document.createElement(
|
|
26113
|
+
return document.createElement(`ixfx-menu-separator`);
|
|
25443
26114
|
}
|
|
25444
26115
|
function buildMenuHeaderEl(label) {
|
|
25445
|
-
const el = document.createElement(
|
|
25446
|
-
el.setAttribute(
|
|
26116
|
+
const el = document.createElement(`ixfx-menu-header`);
|
|
26117
|
+
el.setAttribute(`label`, label);
|
|
25447
26118
|
return el;
|
|
25448
26119
|
}
|
|
25449
26120
|
function buildMenuSubTriggerEl(node, options) {
|
|
25450
26121
|
const { onCommand, registry, keyboardManager } = options;
|
|
25451
|
-
const el = document.createElement(
|
|
25452
|
-
el.setAttribute(
|
|
26122
|
+
const el = document.createElement(`ixfx-menu-sub-trigger`);
|
|
26123
|
+
el.setAttribute(`label`, node.item.label);
|
|
25453
26124
|
if (registry) el.registry = registry;
|
|
25454
26125
|
if (keyboardManager) el.keyboardManager = keyboardManager;
|
|
25455
|
-
const container = document.createElement(
|
|
25456
|
-
container.setAttribute(
|
|
26126
|
+
const container = document.createElement(`ixfx-menu-container`);
|
|
26127
|
+
container.setAttribute(`slot`, `submenu`);
|
|
25457
26128
|
if (registry) container.registry = registry;
|
|
25458
26129
|
if (keyboardManager) container.keyboardManager = keyboardManager;
|
|
25459
26130
|
const childEls = menuFromTreeToElements(node.children, options);
|
|
@@ -25464,8 +26135,8 @@ function buildMenuSubTriggerEl(node, options) {
|
|
|
25464
26135
|
function menuFromTreeToElements(nodes, options = {}) {
|
|
25465
26136
|
return nodes.map((node) => {
|
|
25466
26137
|
const label = node.item.label;
|
|
25467
|
-
if (label ===
|
|
25468
|
-
if (label.startsWith(
|
|
26138
|
+
if (label === `-`) return buildMenuSeparatorEl();
|
|
26139
|
+
if (label.startsWith(`# `)) return buildMenuHeaderEl(label.slice(2));
|
|
25469
26140
|
if (!isLeaf(node)) return buildMenuSubTriggerEl(node, options);
|
|
25470
26141
|
return buildMenuItemEl(node, options);
|
|
25471
26142
|
});
|
|
@@ -25645,8 +26316,8 @@ let MillerBaseElement = class MillerBaseElement extends i$4 {
|
|
|
25645
26316
|
super(..._args);
|
|
25646
26317
|
this.headers = false;
|
|
25647
26318
|
this.interactionMode = `standard`;
|
|
25648
|
-
this.selectionFilter =
|
|
25649
|
-
this.exclusivity =
|
|
26319
|
+
this.selectionFilter = `leaf`;
|
|
26320
|
+
this.exclusivity = `none`;
|
|
25650
26321
|
this._columns = [];
|
|
25651
26322
|
this._selectedByDepth = /* @__PURE__ */ new Map();
|
|
25652
26323
|
this._selectedKeys = /* @__PURE__ */ new Set();
|
|
@@ -25876,7 +26547,7 @@ let MillerBaseElement = class MillerBaseElement extends i$4 {
|
|
|
25876
26547
|
#getTickledDepth() {
|
|
25877
26548
|
const id = this.tickled.tickledId;
|
|
25878
26549
|
if (!id) return void 0;
|
|
25879
|
-
const colonIndex = id.indexOf(
|
|
26550
|
+
const colonIndex = id.indexOf(`:`);
|
|
25880
26551
|
if (colonIndex < 0) return void 0;
|
|
25881
26552
|
return Number(id.substring(0, colonIndex));
|
|
25882
26553
|
}
|
|
@@ -25898,10 +26569,10 @@ let MillerBaseElement = class MillerBaseElement extends i$4 {
|
|
|
25898
26569
|
if (model) {
|
|
25899
26570
|
this.root = model.root;
|
|
25900
26571
|
this.#modelUnsubscribe = model._subscribe((event) => {
|
|
25901
|
-
if (event.type ===
|
|
26572
|
+
if (event.type === `root`) {
|
|
25902
26573
|
this.root = event.root;
|
|
25903
26574
|
this.requestUpdate();
|
|
25904
|
-
} else if (event.type ===
|
|
26575
|
+
} else if (event.type === `invalidate`) {
|
|
25905
26576
|
for (let depth = 0; depth < this._columns.length - 1; depth++) if (this._columns[depth]?.some((n) => n.item.key === event.key)) {
|
|
25906
26577
|
this._columns = this._columns.slice(0, depth + 1);
|
|
25907
26578
|
this.requestUpdate();
|
|
@@ -26181,9 +26852,9 @@ let MillerBaseElement = class MillerBaseElement extends i$4 {
|
|
|
26181
26852
|
};
|
|
26182
26853
|
}
|
|
26183
26854
|
#canSelect(node) {
|
|
26184
|
-
if (this.selectionFilter ===
|
|
26185
|
-
if (this.selectionFilter ===
|
|
26186
|
-
if (this.selectionFilter ===
|
|
26855
|
+
if (this.selectionFilter === `none`) return false;
|
|
26856
|
+
if (this.selectionFilter === `leaf`) return node.item.isLeaf !== false;
|
|
26857
|
+
if (this.selectionFilter === `branch`) return node.item.isLeaf === false || node.children !== void 0 && node.children.length > 0;
|
|
26187
26858
|
return true;
|
|
26188
26859
|
}
|
|
26189
26860
|
#dispatchSelectEvent(previous) {
|
|
@@ -26420,7 +27091,7 @@ let MillerBaseElement = class MillerBaseElement extends i$4 {
|
|
|
26420
27091
|
#getTickledNodeAndDepth() {
|
|
26421
27092
|
const id = this.tickled.tickledId;
|
|
26422
27093
|
if (!id) return void 0;
|
|
26423
|
-
const colonIndex = id.indexOf(
|
|
27094
|
+
const colonIndex = id.indexOf(`:`);
|
|
26424
27095
|
if (colonIndex < 0) return void 0;
|
|
26425
27096
|
const depth = Number(id.substring(0, colonIndex));
|
|
26426
27097
|
const key = id.substring(colonIndex + 1);
|
|
@@ -26553,7 +27224,7 @@ let MillerBaseElement = class MillerBaseElement extends i$4 {
|
|
|
26553
27224
|
* Called by subclasses when pointer leaves the column container.
|
|
26554
27225
|
*/
|
|
26555
27226
|
_handleColumnPointerLeave() {
|
|
26556
|
-
this.tickled.handlePointerLeave(new PointerEvent(
|
|
27227
|
+
this.tickled.handlePointerLeave(new PointerEvent(`pointerleave`));
|
|
26557
27228
|
}
|
|
26558
27229
|
static {
|
|
26559
27230
|
this.styles = [tickledStyles, i$7`
|
|
@@ -26675,11 +27346,11 @@ __decorate([n$2({ type: Boolean })], MillerBaseElement.prototype, "headers", voi
|
|
|
26675
27346
|
__decorate([n$2({ type: String })], MillerBaseElement.prototype, "interactionMode", void 0);
|
|
26676
27347
|
__decorate([n$2({
|
|
26677
27348
|
reflect: true,
|
|
26678
|
-
attribute:
|
|
27349
|
+
attribute: `selection-filter`
|
|
26679
27350
|
})], MillerBaseElement.prototype, "selectionFilter", void 0);
|
|
26680
27351
|
__decorate([n$2({
|
|
26681
27352
|
reflect: true,
|
|
26682
|
-
attribute:
|
|
27353
|
+
attribute: `exclusivity`
|
|
26683
27354
|
})], MillerBaseElement.prototype, "exclusivity", void 0);
|
|
26684
27355
|
__decorate([n$2({ type: Object })], MillerBaseElement.prototype, "loadChildren", void 0);
|
|
26685
27356
|
__decorate([n$2({ attribute: false })], MillerBaseElement.prototype, "filterPredicate", void 0);
|
|
@@ -28247,7 +28918,7 @@ let PlotSingleAxis = class PlotSingleAxis extends i$4 {
|
|
|
28247
28918
|
this.paused = false;
|
|
28248
28919
|
this.clickPauses = false;
|
|
28249
28920
|
this.shaded = false;
|
|
28250
|
-
this.areaColor =
|
|
28921
|
+
this.areaColor = ``;
|
|
28251
28922
|
this.colorMode = `fixed`;
|
|
28252
28923
|
this.colorEasing = ``;
|
|
28253
28924
|
this.colorScale = ``;
|
|
@@ -28290,7 +28961,7 @@ let PlotSingleAxis = class PlotSingleAxis extends i$4 {
|
|
|
28290
28961
|
#hasProgrammaticData;
|
|
28291
28962
|
#parseDeclarativeData(text) {
|
|
28292
28963
|
if (!text) return [];
|
|
28293
|
-
return text.trim().split(/[,\s;]+/).map((t) => parseFloat(t)).filter((n) => !isNaN(n));
|
|
28964
|
+
return text.trim().split(/[,\s;]+/).map((t) => Number.parseFloat(t)).filter((n) => !isNaN(n));
|
|
28294
28965
|
}
|
|
28295
28966
|
#lastClientX;
|
|
28296
28967
|
#lastClientY;
|
|
@@ -28321,7 +28992,7 @@ let PlotSingleAxis = class PlotSingleAxis extends i$4 {
|
|
|
28321
28992
|
this._height = e.contentRect.height;
|
|
28322
28993
|
}).observe(this);
|
|
28323
28994
|
if (!this.#hasProgrammaticData) {
|
|
28324
|
-
const data = this.#parseDeclarativeData(this.textContent ??
|
|
28995
|
+
const data = this.#parseDeclarativeData(this.textContent ?? ``);
|
|
28325
28996
|
if (data.length > 0) this.#series.set(data);
|
|
28326
28997
|
}
|
|
28327
28998
|
}
|
|
@@ -28503,9 +29174,9 @@ __decorate([n$2({
|
|
|
28503
29174
|
})], PlotSingleAxis.prototype, "clickPauses", void 0);
|
|
28504
29175
|
__decorate([n$2({
|
|
28505
29176
|
type: Boolean,
|
|
28506
|
-
attribute:
|
|
29177
|
+
attribute: `shaded`
|
|
28507
29178
|
})], PlotSingleAxis.prototype, "shaded", void 0);
|
|
28508
|
-
__decorate([n$2({ attribute:
|
|
29179
|
+
__decorate([n$2({ attribute: `area-color` })], PlotSingleAxis.prototype, "areaColor", void 0);
|
|
28509
29180
|
__decorate([n$2({ attribute: `color-mode` })], PlotSingleAxis.prototype, "colorMode", void 0);
|
|
28510
29181
|
__decorate([n$2({ attribute: `color-easing` })], PlotSingleAxis.prototype, "colorEasing", void 0);
|
|
28511
29182
|
__decorate([n$2({ attribute: `color-scale` })], PlotSingleAxis.prototype, "colorScale", void 0);
|
|
@@ -31005,7 +31676,7 @@ let SplitLayoutElement = class SplitLayoutElement extends i$4 {
|
|
|
31005
31676
|
const cursorZoneLocalY = event.clientY - zoneBounds.top;
|
|
31006
31677
|
if (this.layout === `vertical` && nestedSplit.layout === `horizontal`) {
|
|
31007
31678
|
let newOuterFraction = cursorZoneLocalX / outerBounds.width;
|
|
31008
|
-
|
|
31679
|
+
const newNestedFraction = cursorZoneLocalY / outerBounds.height;
|
|
31009
31680
|
const { sizeA: constrainedA, sizeB: constrainedB } = this.#applyConstraints(`${newOuterFraction * 100}%`, `${(1 - newOuterFraction) * 100}%`, outerBounds.width);
|
|
31010
31681
|
newOuterFraction = this.#parseSizeAsFraction(constrainedA, outerBounds.width);
|
|
31011
31682
|
this.sizeA = constrainedA;
|
|
@@ -31021,7 +31692,7 @@ let SplitLayoutElement = class SplitLayoutElement extends i$4 {
|
|
|
31021
31692
|
cornerZone.style.top = `${cursorZoneLocalY - 6}px`;
|
|
31022
31693
|
}
|
|
31023
31694
|
} else if (this.layout === `horizontal` && nestedSplit.layout === `vertical`) {
|
|
31024
|
-
|
|
31695
|
+
const newNestedFraction = cursorZoneLocalX / outerBounds.width;
|
|
31025
31696
|
let newOuterFraction = cursorZoneLocalY / outerBounds.height;
|
|
31026
31697
|
const { sizeA: constrainedA, sizeB: constrainedB } = this.#applyConstraints(`${newOuterFraction * 100}%`, `${(1 - newOuterFraction) * 100}%`, outerBounds.height);
|
|
31027
31698
|
newOuterFraction = this.#parseSizeAsFraction(constrainedA, outerBounds.height);
|
|
@@ -31621,16 +32292,19 @@ let TabListItemElement = class TabListItemElement extends i$4 {
|
|
|
31621
32292
|
<div>
|
|
31622
32293
|
${this.iconName ? b`<ixfx-icon name="${this.iconName}"></ixfx-icon>` : A}
|
|
31623
32294
|
${showLabel ? b`<span class="label"><slot></slot></span>` : A}
|
|
31624
|
-
|
|
31625
|
-
<
|
|
31626
|
-
|
|
31627
|
-
|
|
31628
|
-
|
|
31629
|
-
|
|
31630
|
-
|
|
31631
|
-
|
|
31632
|
-
|
|
31633
|
-
|
|
32295
|
+
<div class="actions">
|
|
32296
|
+
<div class="toolbar"><slot name="toolbar"></slot></div>
|
|
32297
|
+
${this.closeable ? b`
|
|
32298
|
+
<button
|
|
32299
|
+
class="close-btn"
|
|
32300
|
+
type="button"
|
|
32301
|
+
aria-label="Close tab"
|
|
32302
|
+
@click=${this._onCloseClick}
|
|
32303
|
+
>
|
|
32304
|
+
<ixfx-icon name="close"></ixfx-icon>
|
|
32305
|
+
</button>
|
|
32306
|
+
` : A}
|
|
32307
|
+
</div>
|
|
31634
32308
|
</div>
|
|
31635
32309
|
`;
|
|
31636
32310
|
}
|
|
@@ -31654,7 +32328,7 @@ let TabListItemElement = class TabListItemElement extends i$4 {
|
|
|
31654
32328
|
box-sizing: border-box;
|
|
31655
32329
|
}
|
|
31656
32330
|
|
|
31657
|
-
div {
|
|
32331
|
+
:host > div {
|
|
31658
32332
|
display: flex;
|
|
31659
32333
|
align-items: center;
|
|
31660
32334
|
gap: var(--space-s, 4px);
|
|
@@ -31685,6 +32359,28 @@ let TabListItemElement = class TabListItemElement extends i$4 {
|
|
|
31685
32359
|
flex-shrink: 0;
|
|
31686
32360
|
}
|
|
31687
32361
|
|
|
32362
|
+
.actions {
|
|
32363
|
+
display: flex;
|
|
32364
|
+
align-items: center;
|
|
32365
|
+
gap: var(--space-xs);
|
|
32366
|
+
margin-left: auto;
|
|
32367
|
+
flex-shrink: 0;
|
|
32368
|
+
}
|
|
32369
|
+
|
|
32370
|
+
.toolbar {
|
|
32371
|
+
display: none;
|
|
32372
|
+
align-items: center;
|
|
32373
|
+
gap: var(--space-xs);
|
|
32374
|
+
}
|
|
32375
|
+
|
|
32376
|
+
:host([selected]) .toolbar {
|
|
32377
|
+
display: flex;
|
|
32378
|
+
}
|
|
32379
|
+
|
|
32380
|
+
slot[name="toolbar"] {
|
|
32381
|
+
display: contents;
|
|
32382
|
+
}
|
|
32383
|
+
|
|
31688
32384
|
.close-btn {
|
|
31689
32385
|
display: inline-flex;
|
|
31690
32386
|
align-items: center;
|
|
@@ -31692,7 +32388,6 @@ let TabListItemElement = class TabListItemElement extends i$4 {
|
|
|
31692
32388
|
background: none;
|
|
31693
32389
|
border: none;
|
|
31694
32390
|
padding: var(--space-xs);
|
|
31695
|
-
margin-left: auto;
|
|
31696
32391
|
cursor: pointer;
|
|
31697
32392
|
color: inherit;
|
|
31698
32393
|
border-radius: var(--radius-s);
|
|
@@ -31798,7 +32493,7 @@ let TabListElement = class TabListElement extends i$4 {
|
|
|
31798
32493
|
}
|
|
31799
32494
|
updated(changedProperties) {
|
|
31800
32495
|
super.updated(changedProperties);
|
|
31801
|
-
this.classList.toggle(
|
|
32496
|
+
this.classList.toggle(`scrollable`, this.scrollable);
|
|
31802
32497
|
}
|
|
31803
32498
|
#syncIndicatorColors() {
|
|
31804
32499
|
for (const item of this.#items) {
|
|
@@ -31971,14 +32666,17 @@ let TabPanelsElement = class TabPanelsElement extends i$4 {
|
|
|
31971
32666
|
if (this.onSelectedPanel) this.onSelectedPanel(el.id, el);
|
|
31972
32667
|
}
|
|
31973
32668
|
syncWithList(el) {
|
|
32669
|
+
const apply = (t) => {
|
|
32670
|
+
if (!t) return;
|
|
32671
|
+
const forEl = t.getAttribute(`for`);
|
|
32672
|
+
if (forEl) this.selectPanel(forEl);
|
|
32673
|
+
};
|
|
31974
32674
|
const t = el.getSelectedElement();
|
|
31975
32675
|
if (!t) {
|
|
31976
|
-
el.updateComplete.then(() =>
|
|
32676
|
+
el.updateComplete.then(() => apply(el.getSelectedElement()));
|
|
31977
32677
|
return;
|
|
31978
32678
|
}
|
|
31979
|
-
|
|
31980
|
-
if (!forEl) return;
|
|
31981
|
-
this.selectPanel(forEl);
|
|
32679
|
+
apply(t);
|
|
31982
32680
|
}
|
|
31983
32681
|
selectPanel(id) {
|
|
31984
32682
|
const current = this.getSelectedElement();
|
|
@@ -32005,6 +32703,70 @@ let TabPanelsElement = class TabPanelsElement extends i$4 {
|
|
|
32005
32703
|
__decorate([o$2()], TabPanelsElement.prototype, "_listItems", void 0);
|
|
32006
32704
|
TabPanelsElement = __decorate([safeCustomElement(`ixfx-tab-panels`)], TabPanelsElement);
|
|
32007
32705
|
//#endregion
|
|
32706
|
+
//#region src/timeline/timeline-controller.ts
|
|
32707
|
+
/**
|
|
32708
|
+
* External adapter class that can configure a timeline element
|
|
32709
|
+
* with musical time, custom label formatting, etc.
|
|
32710
|
+
*
|
|
32711
|
+
* The controller has no import of any timeline element type.
|
|
32712
|
+
* Users create a controller, pass it the component instance,
|
|
32713
|
+
* and the controller calls the component's public API.
|
|
32714
|
+
*/
|
|
32715
|
+
var TimelineController = class {
|
|
32716
|
+
#host;
|
|
32717
|
+
#config;
|
|
32718
|
+
#bpm = 120;
|
|
32719
|
+
#timeSignatureNumerator = 4;
|
|
32720
|
+
#timeSignatureDenominator = 4;
|
|
32721
|
+
constructor(timeline, config) {
|
|
32722
|
+
this.#host = timeline;
|
|
32723
|
+
this.#config = config;
|
|
32724
|
+
timeline.min = config.logicalMin;
|
|
32725
|
+
timeline.max = config.logicalMax;
|
|
32726
|
+
if (config.labelFormatter) timeline.formatLabel = config.labelFormatter;
|
|
32727
|
+
timeline.addEventListener(`track-select`, this.#onTrackSelect);
|
|
32728
|
+
}
|
|
32729
|
+
/** Update the tempo (BPM) for musical time calculations. */
|
|
32730
|
+
setTempo(bpm) {
|
|
32731
|
+
this.#bpm = bpm;
|
|
32732
|
+
this.#updateFormatLabel();
|
|
32733
|
+
}
|
|
32734
|
+
/** Update the time signature for musical time calculations. */
|
|
32735
|
+
setTimeSignature(numerator, denominator) {
|
|
32736
|
+
this.#timeSignatureNumerator = numerator;
|
|
32737
|
+
this.#timeSignatureDenominator = denominator;
|
|
32738
|
+
this.#updateFormatLabel();
|
|
32739
|
+
}
|
|
32740
|
+
/** Set the visible view range on the timeline. */
|
|
32741
|
+
setViewRange(range) {
|
|
32742
|
+
this.#host.setViewRange(range);
|
|
32743
|
+
}
|
|
32744
|
+
/** Clean up any resources held by the controller. */
|
|
32745
|
+
dispose() {
|
|
32746
|
+
this.#host.removeEventListener(`track-select`, this.#onTrackSelect);
|
|
32747
|
+
}
|
|
32748
|
+
#onTrackSelect = (e) => {
|
|
32749
|
+
const detail = e.detail;
|
|
32750
|
+
const trackEventIds = this.#host.getTrackEvents(detail.trackKey).map((e) => e.id);
|
|
32751
|
+
if (detail.shiftKey) {
|
|
32752
|
+
const current = new Set(this.#host.selectedIds);
|
|
32753
|
+
for (const id of trackEventIds) if (current.has(id)) current.delete(id);
|
|
32754
|
+
else current.add(id);
|
|
32755
|
+
this.#host.selectedIds = [...current];
|
|
32756
|
+
} else this.#host.selectedIds = trackEventIds;
|
|
32757
|
+
};
|
|
32758
|
+
#updateFormatLabel() {
|
|
32759
|
+
if (this.#config.labelFormatter) return;
|
|
32760
|
+
this.#bpm;
|
|
32761
|
+
const num = this.#timeSignatureNumerator;
|
|
32762
|
+
this.#host.formatLabel = (v) => {
|
|
32763
|
+
const beatsPerBar = num;
|
|
32764
|
+
const totalBeats = v;
|
|
32765
|
+
return `${Math.floor(totalBeats / beatsPerBar) + 1}.${Math.floor(totalBeats % beatsPerBar) + 1}`;
|
|
32766
|
+
};
|
|
32767
|
+
}
|
|
32768
|
+
};
|
|
32769
|
+
//#endregion
|
|
32008
32770
|
//#region src/timeline/timeline-draw.ts
|
|
32009
32771
|
const NICE_STEPS = [
|
|
32010
32772
|
1,
|
|
@@ -32015,15 +32777,15 @@ const NICE_STEPS = [
|
|
|
32015
32777
|
/**
|
|
32016
32778
|
* Dispatch to adaptive or fixed grid mode.
|
|
32017
32779
|
*/
|
|
32018
|
-
|
|
32780
|
+
function resolveGrid(viewRange, userScale, viewportWidth, mode = `adaptive`, fixedMinorStep, ppu) {
|
|
32019
32781
|
if (mode === `fixed` && fixedMinorStep !== void 0 && ppu !== void 0) return resolveFixedGrid(fixedMinorStep, ppu);
|
|
32020
32782
|
return resolveAdaptiveGrid(viewRange, userScale, viewportWidth);
|
|
32021
|
-
}
|
|
32783
|
+
}
|
|
32022
32784
|
/**
|
|
32023
32785
|
* Compute a nice major/minor grid resolution for the current view.
|
|
32024
32786
|
* Uses a 1-2-5-10 "nice number" algorithm.
|
|
32025
32787
|
*/
|
|
32026
|
-
|
|
32788
|
+
function resolveAdaptiveGrid(viewRange, userScale, viewportWidth) {
|
|
32027
32789
|
const span = viewRange.max - viewRange.min;
|
|
32028
32790
|
if (span <= 0 || viewportWidth <= 0) return {
|
|
32029
32791
|
majorStep: 100,
|
|
@@ -32032,7 +32794,7 @@ const resolveAdaptiveGrid = (viewRange, userScale, viewportWidth) => {
|
|
|
32032
32794
|
};
|
|
32033
32795
|
const targetPx = 80 * scaleMultiplier(userScale);
|
|
32034
32796
|
const rawStep = span / Math.max(2, Math.floor(viewportWidth / targetPx));
|
|
32035
|
-
const magnitude =
|
|
32797
|
+
const magnitude = 10 ** Math.floor(Math.log10(rawStep));
|
|
32036
32798
|
let bestStep = magnitude;
|
|
32037
32799
|
for (const n of NICE_STEPS) {
|
|
32038
32800
|
const candidate = n * magnitude;
|
|
@@ -32049,14 +32811,14 @@ const resolveAdaptiveGrid = (viewRange, userScale, viewportWidth) => {
|
|
|
32049
32811
|
minorDivisions,
|
|
32050
32812
|
minorStep
|
|
32051
32813
|
};
|
|
32052
|
-
}
|
|
32814
|
+
}
|
|
32053
32815
|
/**
|
|
32054
32816
|
* Fixed grid: user specifies a base minor step in logical units.
|
|
32055
32817
|
* If the minor step at current zoom would produce lines < 5px apart,
|
|
32056
32818
|
* double the effective step until they're >= 5px.
|
|
32057
32819
|
* Major = 4× effective minor.
|
|
32058
32820
|
*/
|
|
32059
|
-
|
|
32821
|
+
function resolveFixedGrid(baseMinorStep, ppu) {
|
|
32060
32822
|
const MIN_PX_BETWEEN = 5;
|
|
32061
32823
|
let effectiveMinor = baseMinorStep;
|
|
32062
32824
|
while (effectiveMinor * ppu < MIN_PX_BETWEEN && effectiveMinor < 0xe8d4a51000) effectiveMinor *= 2;
|
|
@@ -32066,8 +32828,8 @@ const resolveFixedGrid = (baseMinorStep, ppu) => {
|
|
|
32066
32828
|
minorDivisions,
|
|
32067
32829
|
minorStep: effectiveMinor
|
|
32068
32830
|
};
|
|
32069
|
-
}
|
|
32070
|
-
|
|
32831
|
+
}
|
|
32832
|
+
function scaleMultiplier(scale) {
|
|
32071
32833
|
switch (scale) {
|
|
32072
32834
|
case `x-wide`: return 2;
|
|
32073
32835
|
case `wide`: return 1.5;
|
|
@@ -32076,8 +32838,8 @@ const scaleMultiplier = (scale) => {
|
|
|
32076
32838
|
case `x-slim`: return .5;
|
|
32077
32839
|
default: return 1;
|
|
32078
32840
|
}
|
|
32079
|
-
}
|
|
32080
|
-
|
|
32841
|
+
}
|
|
32842
|
+
function drawMajorMinorGrid(ctx, region, resolution, altMajorBg, vars, ppu) {
|
|
32081
32843
|
const { majorStep, minorStep } = resolution;
|
|
32082
32844
|
if (majorStep <= 0) return;
|
|
32083
32845
|
const regionEnd = region.x + region.width;
|
|
@@ -32091,7 +32853,7 @@ const drawMajorMinorGrid = (ctx, region, resolution, altMajorBg, vars, ppu) => {
|
|
|
32091
32853
|
}
|
|
32092
32854
|
if (minorStep > 0) {
|
|
32093
32855
|
ctx.strokeStyle = vars[`--timeline-grid-minor-color`] ?? `rgba(255,255,255,0.05)`;
|
|
32094
|
-
ctx.lineWidth = parseFloat(vars[`--timeline-grid-minor-width`] ?? `0.5`);
|
|
32856
|
+
ctx.lineWidth = Number.parseFloat(vars[`--timeline-grid-minor-width`] ?? `0.5`);
|
|
32095
32857
|
ctx.beginPath();
|
|
32096
32858
|
const firstMinor = Math.floor(region.x / minorStep) * minorStep;
|
|
32097
32859
|
for (let val = firstMinor; val < regionEnd; val += minorStep) {
|
|
@@ -32103,7 +32865,7 @@ const drawMajorMinorGrid = (ctx, region, resolution, altMajorBg, vars, ppu) => {
|
|
|
32103
32865
|
ctx.stroke();
|
|
32104
32866
|
}
|
|
32105
32867
|
ctx.strokeStyle = vars[`--timeline-grid-major-color`] ?? `rgba(255,255,255,0.12)`;
|
|
32106
|
-
ctx.lineWidth = parseFloat(vars[`--timeline-grid-major-width`] ?? `1`);
|
|
32868
|
+
ctx.lineWidth = Number.parseFloat(vars[`--timeline-grid-major-width`] ?? `1`);
|
|
32107
32869
|
ctx.beginPath();
|
|
32108
32870
|
const firstMajor = Math.floor(region.x / majorStep) * majorStep;
|
|
32109
32871
|
for (let val = firstMajor; val < regionEnd; val += majorStep) {
|
|
@@ -32112,13 +32874,13 @@ const drawMajorMinorGrid = (ctx, region, resolution, altMajorBg, vars, ppu) => {
|
|
|
32112
32874
|
ctx.lineTo(px, region.y + region.height);
|
|
32113
32875
|
}
|
|
32114
32876
|
ctx.stroke();
|
|
32115
|
-
}
|
|
32877
|
+
}
|
|
32116
32878
|
/**
|
|
32117
32879
|
* Draw the axis header band. With 2D virtualization the axis is "sticky" —
|
|
32118
32880
|
* it is always drawn at the current vertical scroll position (`scrollTop`)
|
|
32119
32881
|
* so it appears fixed at the viewport top.
|
|
32120
32882
|
*/
|
|
32121
|
-
|
|
32883
|
+
function drawAxis(ctx, region, resolution, axisHeight, formatLabel, vars, ppu, scrollTop = 0) {
|
|
32122
32884
|
const { majorStep } = resolution;
|
|
32123
32885
|
if (majorStep <= 0 || axisHeight <= 0) return;
|
|
32124
32886
|
const axisTop = scrollTop;
|
|
@@ -32130,7 +32892,7 @@ const drawAxis = (ctx, region, resolution, axisHeight, formatLabel, vars, ppu, s
|
|
|
32130
32892
|
const bgLeft = region.x * ppu;
|
|
32131
32893
|
ctx.fillRect(bgLeft, axisTop, region.width * ppu, bgHeight);
|
|
32132
32894
|
ctx.strokeStyle = vars[`--timeline-grid-major-color`] ?? `rgba(255,255,255,0.12)`;
|
|
32133
|
-
ctx.lineWidth = parseFloat(vars[`--timeline-grid-major-width`] ?? `1`);
|
|
32895
|
+
ctx.lineWidth = Number.parseFloat(vars[`--timeline-grid-major-width`] ?? `1`);
|
|
32134
32896
|
ctx.beginPath();
|
|
32135
32897
|
const firstMajor = Math.ceil(region.x / majorStep) * majorStep;
|
|
32136
32898
|
for (let val = firstMajor; val < regionEnd; val += majorStep) {
|
|
@@ -32155,8 +32917,8 @@ const drawAxis = (ctx, region, resolution, axisHeight, formatLabel, vars, ppu, s
|
|
|
32155
32917
|
ctx.fillText(formatLabel(val), px + labelPadding, axisTop + bgHeight / 2);
|
|
32156
32918
|
}
|
|
32157
32919
|
ctx.textAlign = `start`;
|
|
32158
|
-
}
|
|
32159
|
-
|
|
32920
|
+
}
|
|
32921
|
+
function drawTrackBackgrounds(ctx, region, trackLayout, tracks, vars, ppu) {
|
|
32160
32922
|
const bgDefault = vars[`--timeline-track-bg`] ?? `#1a1a1a`;
|
|
32161
32923
|
const bgAlt = vars[`--timeline-track-bg-alt`] ?? `#1e1e1e`;
|
|
32162
32924
|
for (let i = 0; i < trackLayout.length; i++) {
|
|
@@ -32164,7 +32926,7 @@ const drawTrackBackgrounds = (ctx, region, trackLayout, tracks, vars, ppu) => {
|
|
|
32164
32926
|
if (layout.y + layout.height < region.y) continue;
|
|
32165
32927
|
if (layout.y > region.y + region.height) break;
|
|
32166
32928
|
const track = tracks.find((t) => t.key === layout.trackKey);
|
|
32167
|
-
ctx.fillStyle = track?.color ? track.color
|
|
32929
|
+
ctx.fillStyle = track?.color ? `${track.color}22` : i % 2 === 0 ? bgDefault : bgAlt;
|
|
32168
32930
|
ctx.fillRect(region.x * ppu, layout.y, region.width * ppu, layout.height);
|
|
32169
32931
|
ctx.strokeStyle = vars[`--timeline-grid-major-color`] ?? `rgba(255,255,255,0.12)`;
|
|
32170
32932
|
ctx.lineWidth = .5;
|
|
@@ -32173,13 +32935,13 @@ const drawTrackBackgrounds = (ctx, region, trackLayout, tracks, vars, ppu) => {
|
|
|
32173
32935
|
ctx.lineTo((region.x + region.width) * ppu, layout.y + layout.height);
|
|
32174
32936
|
ctx.stroke();
|
|
32175
32937
|
}
|
|
32176
|
-
}
|
|
32177
|
-
|
|
32938
|
+
}
|
|
32939
|
+
function drawEventRects(ctx, region, events, trackLayout, selectedIds, tickledId, drag, vars, ppu) {
|
|
32178
32940
|
const eventBg = vars[`--timeline-event-bg`] ?? `#3498db`;
|
|
32179
32941
|
const eventSelectedBg = vars[`--timeline-event-selected-bg`] ?? `#5dade2`;
|
|
32180
32942
|
const eventTickledBg = vars[`--timeline-event-tickled-bg`] ?? `#444`;
|
|
32181
32943
|
const eventLabelColor = vars[`--timeline-event-label-color`] ?? `#fff`;
|
|
32182
|
-
const radius = parseFloat(vars[`--timeline-event-radius`] ?? `4`);
|
|
32944
|
+
const radius = Number.parseFloat(vars[`--timeline-event-radius`] ?? `4`);
|
|
32183
32945
|
const regionEnd = region.x + region.width;
|
|
32184
32946
|
const padding = 3;
|
|
32185
32947
|
for (const evt of events) {
|
|
@@ -32233,8 +32995,8 @@ const drawEventRects = (ctx, region, events, trackLayout, selectedIds, tickledId
|
|
|
32233
32995
|
ctx.restore();
|
|
32234
32996
|
}
|
|
32235
32997
|
}
|
|
32236
|
-
}
|
|
32237
|
-
|
|
32998
|
+
}
|
|
32999
|
+
function drawMarquee(ctx, drag, ppu) {
|
|
32238
33000
|
if (drag.kind !== `marquee`) return;
|
|
32239
33001
|
const x1 = Math.min(drag.startLogicalX, drag.currentLogicalX) * ppu;
|
|
32240
33002
|
const x2 = Math.max(drag.startLogicalX, drag.currentLogicalX) * ppu;
|
|
@@ -32245,8 +33007,8 @@ const drawMarquee = (ctx, drag, ppu) => {
|
|
|
32245
33007
|
ctx.strokeStyle = `rgba(100, 150, 255, 0.6)`;
|
|
32246
33008
|
ctx.lineWidth = 1;
|
|
32247
33009
|
ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);
|
|
32248
|
-
}
|
|
32249
|
-
|
|
33010
|
+
}
|
|
33011
|
+
function drawRoundRect(ctx, x, y, w, h, r) {
|
|
32250
33012
|
r = Math.max(0, r);
|
|
32251
33013
|
ctx.moveTo(x + r, y);
|
|
32252
33014
|
ctx.arcTo(x + w, y, x + w, y + h, r);
|
|
@@ -32254,7 +33016,7 @@ const drawRoundRect = (ctx, x, y, w, h, r) => {
|
|
|
32254
33016
|
ctx.arcTo(x, y + h, x, y, r);
|
|
32255
33017
|
ctx.arcTo(x, y, x + w, y, r);
|
|
32256
33018
|
ctx.closePath();
|
|
32257
|
-
}
|
|
33019
|
+
}
|
|
32258
33020
|
const TIMELINE_CSS_VARS = [
|
|
32259
33021
|
`--timeline-bg`,
|
|
32260
33022
|
`--timeline-track-bg`,
|
|
@@ -32271,12 +33033,12 @@ const TIMELINE_CSS_VARS = [
|
|
|
32271
33033
|
`--timeline-event-radius`,
|
|
32272
33034
|
`--timeline-axis-label-color`
|
|
32273
33035
|
];
|
|
32274
|
-
|
|
33036
|
+
function resolveCssVars(host) {
|
|
32275
33037
|
const computed = getComputedStyle(host);
|
|
32276
33038
|
const vars = {};
|
|
32277
33039
|
for (const v of TIMELINE_CSS_VARS) vars[v] = computed.getPropertyValue(v).trim();
|
|
32278
33040
|
return vars;
|
|
32279
|
-
}
|
|
33041
|
+
}
|
|
32280
33042
|
//#endregion
|
|
32281
33043
|
//#region src/timeline/timeline-interactions.ts
|
|
32282
33044
|
/** Hit zone near the edge of an event (px in screen space) */
|
|
@@ -32285,13 +33047,17 @@ const EDGE_HIT_PX = 8;
|
|
|
32285
33047
|
* Convert a vcanvas logical (pixel) coordinate to timeline logical units.
|
|
32286
33048
|
* vcanvas pixel coordinates are in the 1:1 pixel space; divide by ppu then add min.
|
|
32287
33049
|
*/
|
|
32288
|
-
|
|
33050
|
+
function canvasToTimeline(canvasX, ppu, min) {
|
|
33051
|
+
return canvasX / ppu + min;
|
|
33052
|
+
}
|
|
32289
33053
|
/**
|
|
32290
33054
|
* Convert screen-space pixel distance to timeline logical units.
|
|
32291
33055
|
* Used for edge hit threshold: how many logical units does EDGE_HIT_PX correspond to.
|
|
32292
33056
|
*/
|
|
32293
|
-
|
|
32294
|
-
|
|
33057
|
+
function pxToLogicalUnits(ppu) {
|
|
33058
|
+
return ppu > 0 ? 1 / ppu : 1;
|
|
33059
|
+
}
|
|
33060
|
+
function hitTest(logicalX, y, events, trackLayout, ppu) {
|
|
32295
33061
|
const track = trackLayout.find((tl) => y >= tl.y && y < tl.y + tl.height);
|
|
32296
33062
|
if (!track) return {
|
|
32297
33063
|
kind: `empty`,
|
|
@@ -32324,17 +33090,19 @@ const hitTest = (logicalX, y, events, trackLayout, ppu) => {
|
|
|
32324
33090
|
y,
|
|
32325
33091
|
trackKey: track.trackKey
|
|
32326
33092
|
};
|
|
32327
|
-
}
|
|
32328
|
-
|
|
33093
|
+
}
|
|
33094
|
+
function trackAtY(y, trackLayout) {
|
|
32329
33095
|
return trackLayout.find((tl) => y >= tl.y && y < tl.y + tl.height)?.trackKey;
|
|
32330
|
-
}
|
|
33096
|
+
}
|
|
32331
33097
|
/** Sensitivity: how many pixels of vertical drag = 1 e-fold of zoom */
|
|
32332
33098
|
const ZOOM_SENSITIVITY_PX = 100;
|
|
32333
33099
|
/**
|
|
32334
33100
|
* Subtract a deadzone from a value.
|
|
32335
33101
|
* Returns 0 if |value| <= deadzone, otherwise value shifted toward zero by deadzone.
|
|
32336
33102
|
*/
|
|
32337
|
-
|
|
33103
|
+
function applyDeadzone(value, deadzone) {
|
|
33104
|
+
return Math.abs(value) > deadzone ? value - Math.sign(value) * deadzone : 0;
|
|
33105
|
+
}
|
|
32338
33106
|
/**
|
|
32339
33107
|
* Compute new ppu + viewMin from an axis-zoom drag.
|
|
32340
33108
|
* Vertical delta (dy) controls zoom (up = zoom in, down = zoom out), anchored at `anchorUnit`.
|
|
@@ -32342,7 +33110,7 @@ const applyDeadzone = (value, deadzone) => Math.abs(value) > deadzone ? value -
|
|
|
32342
33110
|
*
|
|
32343
33111
|
* Returns { ppu, viewMin } — the caller uses host.setZoomPan() to apply.
|
|
32344
33112
|
*/
|
|
32345
|
-
|
|
33113
|
+
function computeAxisZoom(startViewMin, startPpu, anchorUnit, dx, dy) {
|
|
32346
33114
|
const newPpu = startPpu * Math.exp(-dy / ZOOM_SENSITIVITY_PX);
|
|
32347
33115
|
let newMin = anchorUnit - (anchorUnit - startViewMin) * startPpu / newPpu;
|
|
32348
33116
|
if (newPpu > 0) newMin += -dx / newPpu;
|
|
@@ -32350,7 +33118,7 @@ const computeAxisZoom = (startViewMin, startPpu, anchorUnit, dx, dy) => {
|
|
|
32350
33118
|
ppu: newPpu,
|
|
32351
33119
|
viewMin: newMin
|
|
32352
33120
|
};
|
|
32353
|
-
}
|
|
33121
|
+
}
|
|
32354
33122
|
/**
|
|
32355
33123
|
* Compute new vertical view range from a v-axis-zoom drag.
|
|
32356
33124
|
* Horizontal delta (dx) controls zoom (right = zoom in, left = zoom out),
|
|
@@ -32359,7 +33127,7 @@ const computeAxisZoom = (startViewMin, startPpu, anchorUnit, dx, dy) => {
|
|
|
32359
33127
|
*
|
|
32360
33128
|
* Returns { vMin, vMax } — the caller uses host.setVerticalZoomPan() to apply.
|
|
32361
33129
|
*/
|
|
32362
|
-
|
|
33130
|
+
function computeVerticalAxisZoom(startVMin, startVMax, startVScale, anchorBaseY, dx, dy) {
|
|
32363
33131
|
const startSpan = startVMax - startVMin;
|
|
32364
33132
|
const newSpan = startSpan * Math.exp(-dx / ZOOM_SENSITIVITY_PX);
|
|
32365
33133
|
let newMin = anchorBaseY - (startSpan > 0 ? (anchorBaseY - startVMin) / startSpan : .5) * newSpan;
|
|
@@ -32368,12 +33136,12 @@ const computeVerticalAxisZoom = (startVMin, startVMax, startVScale, anchorBaseY,
|
|
|
32368
33136
|
vMin: newMin,
|
|
32369
33137
|
vMax: newMin + newSpan
|
|
32370
33138
|
};
|
|
32371
|
-
}
|
|
33139
|
+
}
|
|
32372
33140
|
/**
|
|
32373
33141
|
* Attaches pointer and keyboard interaction handlers to the timeline.
|
|
32374
33142
|
* Returns a cleanup function.
|
|
32375
33143
|
*/
|
|
32376
|
-
|
|
33144
|
+
function attachTimelineInteractions(host, vcanvasEl) {
|
|
32377
33145
|
const ac = new AbortController();
|
|
32378
33146
|
const signal = ac.signal;
|
|
32379
33147
|
vcanvasEl.addEventListener(`pointerdown`, (e) => {
|
|
@@ -32434,7 +33202,6 @@ const attachTimelineInteractions = (host, vcanvasEl) => {
|
|
|
32434
33202
|
currentLogicalX: lx,
|
|
32435
33203
|
currentY: ly
|
|
32436
33204
|
};
|
|
32437
|
-
return;
|
|
32438
33205
|
}
|
|
32439
33206
|
}, { signal });
|
|
32440
33207
|
vcanvasEl.addEventListener(`pointermove`, (e) => {
|
|
@@ -32507,7 +33274,6 @@ const attachTimelineInteractions = (host, vcanvasEl) => {
|
|
|
32507
33274
|
end: newEnd
|
|
32508
33275
|
} : ev);
|
|
32509
33276
|
vcanvasEl.invalidateAll();
|
|
32510
|
-
return;
|
|
32511
33277
|
}
|
|
32512
33278
|
}, { signal });
|
|
32513
33279
|
vcanvasEl.addEventListener(`pointerup`, (e) => {
|
|
@@ -32580,8 +33346,8 @@ const attachTimelineInteractions = (host, vcanvasEl) => {
|
|
|
32580
33346
|
}
|
|
32581
33347
|
}, { signal });
|
|
32582
33348
|
return () => ac.abort();
|
|
32583
|
-
}
|
|
32584
|
-
|
|
33349
|
+
}
|
|
33350
|
+
function handleHover(host, vcanvasEl, e) {
|
|
32585
33351
|
const ppu = host.pxPerUnit;
|
|
32586
33352
|
const canvasCoord = vcanvasEl.convertFromViewportToCanvas(e.offsetX, e.offsetY);
|
|
32587
33353
|
const lx = canvasToTimeline(canvasCoord.x, ppu, host.min);
|
|
@@ -32605,22 +33371,22 @@ const handleHover = (host, vcanvasEl, e) => {
|
|
|
32605
33371
|
host._tickledId = newTickledId;
|
|
32606
33372
|
vcanvasEl.invalidateAll();
|
|
32607
33373
|
}
|
|
32608
|
-
}
|
|
32609
|
-
|
|
33374
|
+
}
|
|
33375
|
+
function toggleSelection(host, eventId) {
|
|
32610
33376
|
const next = new Set(host._selectedIds);
|
|
32611
33377
|
if (next.has(eventId)) next.delete(eventId);
|
|
32612
33378
|
else next.add(eventId);
|
|
32613
33379
|
host._selectedIds = next;
|
|
32614
33380
|
fireSelectionChange(host);
|
|
32615
33381
|
host.getVCanvas()?.invalidateAll();
|
|
32616
|
-
}
|
|
32617
|
-
|
|
33382
|
+
}
|
|
33383
|
+
function fireSelectionChange(host) {
|
|
32618
33384
|
host.dispatchEvent(new CustomEvent(`selection-change`, {
|
|
32619
33385
|
detail: { selectedIds: [...host._selectedIds] },
|
|
32620
33386
|
bubbles: true,
|
|
32621
33387
|
composed: true
|
|
32622
33388
|
}));
|
|
32623
|
-
}
|
|
33389
|
+
}
|
|
32624
33390
|
//#endregion
|
|
32625
33391
|
//#region src/timeline/timeline-styles.ts
|
|
32626
33392
|
const timelineStyles = i$7`
|
|
@@ -33682,70 +34448,6 @@ __decorate([r$1()], IxfxTimelineElement.prototype, "_internalEvents", void 0);
|
|
|
33682
34448
|
__decorate([r$1()], IxfxTimelineElement.prototype, "_internalTracks", void 0);
|
|
33683
34449
|
IxfxTimelineElement = __decorate([safeCustomElement(`ixfx-timeline`)], IxfxTimelineElement);
|
|
33684
34450
|
//#endregion
|
|
33685
|
-
//#region src/timeline/timeline-controller.ts
|
|
33686
|
-
/**
|
|
33687
|
-
* External adapter class that can configure a timeline element
|
|
33688
|
-
* with musical time, custom label formatting, etc.
|
|
33689
|
-
*
|
|
33690
|
-
* The controller has no import of any timeline element type.
|
|
33691
|
-
* Users create a controller, pass it the component instance,
|
|
33692
|
-
* and the controller calls the component's public API.
|
|
33693
|
-
*/
|
|
33694
|
-
var TimelineController = class {
|
|
33695
|
-
#host;
|
|
33696
|
-
#config;
|
|
33697
|
-
#bpm = 120;
|
|
33698
|
-
#timeSignatureNumerator = 4;
|
|
33699
|
-
#timeSignatureDenominator = 4;
|
|
33700
|
-
constructor(timeline, config) {
|
|
33701
|
-
this.#host = timeline;
|
|
33702
|
-
this.#config = config;
|
|
33703
|
-
timeline.min = config.logicalMin;
|
|
33704
|
-
timeline.max = config.logicalMax;
|
|
33705
|
-
if (config.labelFormatter) timeline.formatLabel = config.labelFormatter;
|
|
33706
|
-
timeline.addEventListener(`track-select`, this.#onTrackSelect);
|
|
33707
|
-
}
|
|
33708
|
-
/** Update the tempo (BPM) for musical time calculations. */
|
|
33709
|
-
setTempo(bpm) {
|
|
33710
|
-
this.#bpm = bpm;
|
|
33711
|
-
this.#updateFormatLabel();
|
|
33712
|
-
}
|
|
33713
|
-
/** Update the time signature for musical time calculations. */
|
|
33714
|
-
setTimeSignature(numerator, denominator) {
|
|
33715
|
-
this.#timeSignatureNumerator = numerator;
|
|
33716
|
-
this.#timeSignatureDenominator = denominator;
|
|
33717
|
-
this.#updateFormatLabel();
|
|
33718
|
-
}
|
|
33719
|
-
/** Set the visible view range on the timeline. */
|
|
33720
|
-
setViewRange(range) {
|
|
33721
|
-
this.#host.setViewRange(range);
|
|
33722
|
-
}
|
|
33723
|
-
/** Clean up any resources held by the controller. */
|
|
33724
|
-
dispose() {
|
|
33725
|
-
this.#host.removeEventListener(`track-select`, this.#onTrackSelect);
|
|
33726
|
-
}
|
|
33727
|
-
#onTrackSelect = (e) => {
|
|
33728
|
-
const detail = e.detail;
|
|
33729
|
-
const trackEventIds = this.#host.getTrackEvents(detail.trackKey).map((e) => e.id);
|
|
33730
|
-
if (detail.shiftKey) {
|
|
33731
|
-
const current = new Set(this.#host.selectedIds);
|
|
33732
|
-
for (const id of trackEventIds) if (current.has(id)) current.delete(id);
|
|
33733
|
-
else current.add(id);
|
|
33734
|
-
this.#host.selectedIds = [...current];
|
|
33735
|
-
} else this.#host.selectedIds = trackEventIds;
|
|
33736
|
-
};
|
|
33737
|
-
#updateFormatLabel() {
|
|
33738
|
-
if (this.#config.labelFormatter) return;
|
|
33739
|
-
this.#bpm;
|
|
33740
|
-
const num = this.#timeSignatureNumerator;
|
|
33741
|
-
this.#host.formatLabel = (v) => {
|
|
33742
|
-
const beatsPerBar = num;
|
|
33743
|
-
const totalBeats = v;
|
|
33744
|
-
return `${Math.floor(totalBeats / beatsPerBar) + 1}.${Math.floor(totalBeats % beatsPerBar) + 1}`;
|
|
33745
|
-
};
|
|
33746
|
-
}
|
|
33747
|
-
};
|
|
33748
|
-
//#endregion
|
|
33749
34451
|
//#region node_modules/.pnpm/lit-html@3.3.3/node_modules/lit-html/directives/keyed.js
|
|
33750
34452
|
/**
|
|
33751
34453
|
* @license
|
|
@@ -34115,7 +34817,7 @@ let TreeBaseElement = class TreeBaseElement extends i$4 {
|
|
|
34115
34817
|
event.preventDefault();
|
|
34116
34818
|
const current = nodes[currentIdx];
|
|
34117
34819
|
if (!current) break;
|
|
34118
|
-
if (this.interactionMode === `checked`) this._handleCheckboxClick(new MouseEvent(
|
|
34820
|
+
if (this.interactionMode === `checked`) this._handleCheckboxClick(new MouseEvent(`click`), current.node, current.depth);
|
|
34119
34821
|
else if (this.interactionMode === `standard` || this.interactionMode === `vscode` || this.interactionMode === `manual`) this.#toggleSelection(current.node, current.depth);
|
|
34120
34822
|
break;
|
|
34121
34823
|
}
|
|
@@ -35254,7 +35956,7 @@ let TooltipElement = class TooltipElement extends i$4 {
|
|
|
35254
35956
|
}
|
|
35255
35957
|
#renderIcon() {
|
|
35256
35958
|
if (!this.icon) return A;
|
|
35257
|
-
if (this.icon.startsWith(`<svg`)) return b`<span class="tooltip-icon" style="display:inline-flex;align-items:center;margin-right:0.25em">${o(this.icon)}</span>`;
|
|
35959
|
+
if (this.icon.startsWith(`<svg`)) return b`<span class="tooltip-icon" style="display:inline-flex;align-items:center;margin-right:0.25em">${o$1(this.icon)}</span>`;
|
|
35258
35960
|
if (!getIcon(this.icon)) return A;
|
|
35259
35961
|
return b`<ixfx-icon class="tooltip-icon" style="margin-right:0.25em" name="${this.icon}"></ixfx-icon>`;
|
|
35260
35962
|
}
|
|
@@ -35297,7 +35999,9 @@ TooltipElement = _TooltipElement = __decorate([safeCustomElement(`ixfx-tooltip`)
|
|
|
35297
35999
|
//#endregion
|
|
35298
36000
|
//#region src/vertical-list/vertical-list.ts
|
|
35299
36001
|
const ITEM_SELECTOR = `li, [data-list-item]`;
|
|
35300
|
-
|
|
36002
|
+
function isMultiMode(mode) {
|
|
36003
|
+
return mode === `checked` || mode === `vscode` || mode === `standard`;
|
|
36004
|
+
}
|
|
35301
36005
|
let VerticalListElement = class VerticalListElement extends i$4 {
|
|
35302
36006
|
constructor(..._args) {
|
|
35303
36007
|
super(..._args);
|
|
@@ -35306,6 +36010,7 @@ let VerticalListElement = class VerticalListElement extends i$4 {
|
|
|
35306
36010
|
this._selectedItems = /* @__PURE__ */ new Set();
|
|
35307
36011
|
this._searchVisible = false;
|
|
35308
36012
|
this._searchQuery = ``;
|
|
36013
|
+
this.#customWrappers = /* @__PURE__ */ new Map();
|
|
35309
36014
|
this.tickled = new TickledController(this, {
|
|
35310
36015
|
getItems: () => this._getVisibleItems().map((el) => ({
|
|
35311
36016
|
id: el,
|
|
@@ -35415,6 +36120,7 @@ let VerticalListElement = class VerticalListElement extends i$4 {
|
|
|
35415
36120
|
}
|
|
35416
36121
|
#search;
|
|
35417
36122
|
#selectionAnchor;
|
|
36123
|
+
#customWrappers;
|
|
35418
36124
|
connectedCallback() {
|
|
35419
36125
|
super.connectedCallback();
|
|
35420
36126
|
if (!this.hasAttribute(`tabindex`)) this.tabIndex = 0;
|
|
@@ -35447,9 +36153,29 @@ let VerticalListElement = class VerticalListElement extends i$4 {
|
|
|
35447
36153
|
super.updated(changed);
|
|
35448
36154
|
if (changed.has(`interactionMode`)) {
|
|
35449
36155
|
this.#selectionAnchor = void 0;
|
|
35450
|
-
this.
|
|
36156
|
+
const previousSelected = this._selectedItems;
|
|
36157
|
+
const savedWrappers = changed.get(`interactionMode`) === `checked` ? new Map(this.#customWrappers) : null;
|
|
36158
|
+
this._syncCheckboxes();
|
|
36159
|
+
if (previousSelected.size > 0) {
|
|
36160
|
+
let remapped;
|
|
36161
|
+
if (savedWrappers && savedWrappers.size > 0) remapped = new Set([...previousSelected].map((el) => savedWrappers.get(el) ?? el));
|
|
36162
|
+
else if (this.#customWrappers.size > 0) {
|
|
36163
|
+
const innerToWrapper = new Map([...this.#customWrappers].map(([w, i]) => [i, w]));
|
|
36164
|
+
remapped = new Set([...previousSelected].map((el) => innerToWrapper.get(el) ?? el));
|
|
36165
|
+
} else remapped = new Set(previousSelected);
|
|
36166
|
+
this._selectedItems = remapped;
|
|
36167
|
+
}
|
|
36168
|
+
this._syncItemStates();
|
|
35451
36169
|
}
|
|
35452
36170
|
}
|
|
36171
|
+
/** The most recently selected item, or `undefined` if nothing is selected. */
|
|
36172
|
+
get selectedItem() {
|
|
36173
|
+
return [...this._selectedItems].at(-1);
|
|
36174
|
+
}
|
|
36175
|
+
/** The full current selection set (read-only). */
|
|
36176
|
+
get selectedItems() {
|
|
36177
|
+
return this._selectedItems;
|
|
36178
|
+
}
|
|
35453
36179
|
addItem(item) {
|
|
35454
36180
|
if (typeof item === `string`) {
|
|
35455
36181
|
const li = document.createElement(`li`);
|
|
@@ -35462,6 +36188,7 @@ let VerticalListElement = class VerticalListElement extends i$4 {
|
|
|
35462
36188
|
item.remove();
|
|
35463
36189
|
}
|
|
35464
36190
|
clearItems() {
|
|
36191
|
+
this.#customWrappers.clear();
|
|
35465
36192
|
this.replaceChildren();
|
|
35466
36193
|
this.#selectionAnchor = void 0;
|
|
35467
36194
|
this._selectedItems = /* @__PURE__ */ new Set();
|
|
@@ -35470,6 +36197,19 @@ let VerticalListElement = class VerticalListElement extends i$4 {
|
|
|
35470
36197
|
select(item) {
|
|
35471
36198
|
this._replaceSelection(item);
|
|
35472
36199
|
}
|
|
36200
|
+
selectMany(items) {
|
|
36201
|
+
if (this.selectionMode !== `multiple`) throw new Error(`selectMany requires selectionMode="multiple" (current: "${this.selectionMode}")`);
|
|
36202
|
+
const previous = this._selectedItems;
|
|
36203
|
+
const next = new Set(items);
|
|
36204
|
+
if (next.size === 0) return;
|
|
36205
|
+
this._selectedItems = next;
|
|
36206
|
+
this.#selectionAnchor = [...next].at(-1);
|
|
36207
|
+
this._syncItemStates();
|
|
36208
|
+
this._dispatch(`list-select`, {
|
|
36209
|
+
selected: next,
|
|
36210
|
+
previous
|
|
36211
|
+
});
|
|
36212
|
+
}
|
|
35473
36213
|
deselect(item) {
|
|
35474
36214
|
if (!this._selectedItems.has(item)) return;
|
|
35475
36215
|
const previous = this._selectedItems;
|
|
@@ -35601,11 +36341,34 @@ let VerticalListElement = class VerticalListElement extends i$4 {
|
|
|
35601
36341
|
if (this.interactionMode === `checked`) el.toggleAttribute(`data-checked`, this._selectedItems.has(el));
|
|
35602
36342
|
else el.removeAttribute(`data-checked`);
|
|
35603
36343
|
}
|
|
35604
|
-
this.dataset
|
|
36344
|
+
this.dataset.inputMode = this.tickled.inputMode;
|
|
35605
36345
|
this._syncCheckboxes();
|
|
35606
36346
|
}
|
|
35607
36347
|
_syncCheckboxes() {
|
|
35608
36348
|
const inCheckedMode = this.interactionMode === `checked`;
|
|
36349
|
+
if (inCheckedMode) for (const inner of Array.from(this.children)) {
|
|
36350
|
+
if (!inner.hasAttribute(`data-list-item`)) continue;
|
|
36351
|
+
if (inner.parentElement !== this) continue;
|
|
36352
|
+
const wrapper = document.createElement(`li`);
|
|
36353
|
+
wrapper.className = `ixfx-custom-row`;
|
|
36354
|
+
const key = inner.getAttribute(`data-key`);
|
|
36355
|
+
const label = inner.getAttribute(`data-search-label`);
|
|
36356
|
+
if (key !== null) wrapper.setAttribute(`data-key`, key);
|
|
36357
|
+
if (label !== null) wrapper.setAttribute(`data-search-label`, label);
|
|
36358
|
+
inner.removeAttribute(`data-list-item`);
|
|
36359
|
+
this.insertBefore(wrapper, inner);
|
|
36360
|
+
wrapper.appendChild(inner);
|
|
36361
|
+
this.#customWrappers.set(wrapper, inner);
|
|
36362
|
+
}
|
|
36363
|
+
else {
|
|
36364
|
+
for (const [wrapper, inner] of this.#customWrappers) {
|
|
36365
|
+
if (wrapper.parentElement !== this) continue;
|
|
36366
|
+
inner.setAttribute(`data-list-item`, ``);
|
|
36367
|
+
this.insertBefore(inner, wrapper);
|
|
36368
|
+
wrapper.remove();
|
|
36369
|
+
}
|
|
36370
|
+
this.#customWrappers.clear();
|
|
36371
|
+
}
|
|
35609
36372
|
for (const el of this.querySelectorAll(`li`)) {
|
|
35610
36373
|
let cb = el.querySelector(`input.ixfx-list-checkbox`);
|
|
35611
36374
|
if (inCheckedMode) {
|
|
@@ -35747,17 +36510,6 @@ let VerticalListElement = class VerticalListElement extends i$4 {
|
|
|
35747
36510
|
outline: 1px solid var(--accent, #60a5fa);
|
|
35748
36511
|
}
|
|
35749
36512
|
|
|
35750
|
-
/* checked mode: left-border indicator for custom shadow-DOM items (no checkbox injection possible) */
|
|
35751
|
-
:host([interaction-mode="checked"]) ::slotted([data-list-item]) {
|
|
35752
|
-
border-left: 3px solid transparent;
|
|
35753
|
-
transition: background var(--transition, 0.1s ease-out),
|
|
35754
|
-
border-color var(--transition, 0.1s ease-out);
|
|
35755
|
-
}
|
|
35756
|
-
|
|
35757
|
-
:host([interaction-mode="checked"]) ::slotted([data-list-item][data-checked]) {
|
|
35758
|
-
border-left: 3px solid var(--accent, #60a5fa);
|
|
35759
|
-
}
|
|
35760
|
-
|
|
35761
36513
|
.search-overlay {
|
|
35762
36514
|
position: absolute;
|
|
35763
36515
|
top: 8px;
|
|
@@ -36273,6 +37025,6 @@ function init() {
|
|
|
36273
37025
|
console.log(`Init`);
|
|
36274
37026
|
}
|
|
36275
37027
|
//#endregion
|
|
36276
|
-
export { AcTextElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataDisplayComponent, EditableLabel, EditableNumber, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, SelectHorizontalElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
|
|
37028
|
+
export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataDisplayComponent, EditableLabel, EditableNumber, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, SelectHorizontalElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
|
|
36277
37029
|
|
|
36278
37030
|
//# sourceMappingURL=index.js.map
|