wox-gui 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,3569 @@
1
- import { FX_STYLES as r, WoxBadge as w, WoxButton as n, WoxColorPicker as p, WoxColorSwatch as i, WoxContextMenu as c, WoxDatagrid as d, WoxDatePicker as l, WoxElement as b, WoxGradientEditor as m, WoxGradientSelector as W, WoxIcon as u, WoxInput as g, WoxLayerItem as f, WoxMenu as h, WoxMenuItem as S, WoxMenubar as z, WoxModal as T, WoxPanel as C, WoxSection as y, WoxSelect as E, WoxSeparator as I, WoxSlider as M, WoxStatusbar as G, WoxTab as v, WoxTabs as B, WoxToast as P, WoxToolbar as _, WoxToolbarGroup as k, WoxTooltip as D, cssToGradient as L, gradientToCSS as X } from "./wox-gui.js";
2
- import "./register.js";
3
- const x = () => {
1
+ var Dt = Object.defineProperty;
2
+ var Rt = (l, p, t) => p in l ? Dt(l, p, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[p] = t;
3
+ var n = (l, p, t) => Rt(l, typeof p != "symbol" ? p + "" : p, t);
4
+ const Mt = `
5
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
6
+ :host { display: inline-block; font-family: var(--wox-font, 'Inter', sans-serif); color: var(--wox-text-primary, #eee); font-size: var(--wox-font-size-base, 12px); }
7
+ :host([hidden]) { display: none !important; }
8
+ `, F = class F extends HTMLElement {
9
+ constructor() {
10
+ super();
11
+ /**
12
+ * Sets the shadow root innerHTML from CSS + HTML strings.
13
+ * @param {string} css - Component-specific CSS
14
+ * @param {string} html - Component markup
15
+ */
16
+ n(this, "render", (t, e) => {
17
+ this.shadowRoot.innerHTML = `<style>${F.BASE_STYLES}${t}</style>${e}`;
18
+ });
19
+ /**
20
+ * Dispatches a composed, bubbling CustomEvent.
21
+ * @param {string} name - Event name
22
+ * @param {*} detail - Event payload
23
+ */
24
+ n(this, "emit", (t, e) => {
25
+ this.dispatchEvent(new CustomEvent(t, { detail: e, bubbles: !0, composed: !0 }));
26
+ });
27
+ /**
28
+ * Query shortcut for a single element inside the shadow root.
29
+ * @param {string} sel - CSS selector
30
+ * @returns {Element|null}
31
+ */
32
+ n(this, "$", (t) => this.shadowRoot.querySelector(t));
33
+ /**
34
+ * Query shortcut for all matching elements inside the shadow root.
35
+ * @param {string} sel - CSS selector
36
+ * @returns {NodeList}
37
+ */
38
+ n(this, "$$", (t) => this.shadowRoot.querySelectorAll(t));
39
+ this.attachShadow({ mode: "open" });
40
+ }
41
+ };
42
+ /** Common CSS reset applied inside every component's Shadow DOM */
43
+ n(F, "BASE_STYLES", Mt);
44
+ let v = F;
45
+ const M = `
46
+ /* glow: neon glow effect using --wox-fx-color */
47
+ .glow {
48
+ border-color: var(--wox-fx-color);
49
+ color: var(--wox-fx-color);
50
+ background: color-mix(in srgb, var(--wox-fx-color), transparent 90%);
51
+ box-shadow: 0 0 20px color-mix(in srgb, var(--wox-fx-color), transparent 60%),
52
+ 0 0 40px color-mix(in srgb, var(--wox-fx-color), transparent 85%),
53
+ inset 0 0 15px color-mix(in srgb, var(--wox-fx-color), transparent 90%);
54
+ animation: wox-glow-pulse 2s ease-in-out infinite alternate;
55
+ }
56
+ .glow svg, .glow .material-icons {
57
+ filter: drop-shadow(0 0 6px var(--wox-fx-color)); opacity: 1;
58
+ }
59
+ .glow span { text-shadow: 0 0 8px var(--wox-fx-color); }
60
+ @keyframes wox-glow-pulse {
61
+ from { box-shadow: 0 0 15px color-mix(in srgb, var(--wox-fx-color), transparent 65%), 0 0 30px color-mix(in srgb, var(--wox-fx-color), transparent 88%), inset 0 0 12px color-mix(in srgb, var(--wox-fx-color), transparent 92%); }
62
+ to { box-shadow: 0 0 25px color-mix(in srgb, var(--wox-fx-color), transparent 50%), 0 0 50px color-mix(in srgb, var(--wox-fx-color), transparent 80%), inset 0 0 20px color-mix(in srgb, var(--wox-fx-color), transparent 88%); }
63
+ }
64
+
65
+ /* pulse: opacity pulse animation */
66
+ .pulse { animation: wox-pulse-fade 1.5s ease-in-out infinite alternate; }
67
+ .glow.pulse { animation: wox-glow-pulse 2s ease-in-out infinite alternate, wox-pulse-fade 1.5s ease-in-out infinite alternate; }
68
+ @keyframes wox-pulse-fade {
69
+ from { opacity: 1; }
70
+ to { opacity: 0.4; }
71
+ }
72
+ `, Ot = `
73
+ :host { display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; }
74
+ .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; font-size: var(--size, 18px); display: inline-block; line-height: 1; text-transform: none; letter-spacing: normal; word-wrap: normal; white-space: nowrap; direction: ltr; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; -moz-osx-font-smoothing: grayscale; color: inherit; }
75
+ ::slotted(svg) { width: var(--size, 18px); height: var(--size, 18px); }
76
+ slot { display: inline-flex; align-items: center; justify-content: center; }
77
+ .fx-wrap { display: inline-flex; align-items: center; justify-content: center; border-radius: var(--wox-radius-sm, 3px); padding: 4px; }
78
+ `;
79
+ class nt extends v {
80
+ constructor() {
81
+ super(...arguments);
82
+ /** @private */
83
+ n(this, "_render", () => {
84
+ const t = this.getAttribute("name"), e = this.getAttribute("size") || "18", o = this.getAttribute("color") || "", i = this.hasAttribute("glow"), s = this.hasAttribute("pulse"), r = i || s, a = t ? `<span class="material-icons" style="--size:${e}px">${t}</span>` : "<slot></slot>", d = r ? `<span class="fx-wrap${i ? " glow" : ""}${s ? " pulse" : ""}" style="--wox-fx-color:${o};color:${o}">${a}</span>` : a;
85
+ this.render(`${Ot} ${M} :host { --size: ${e}px; }`, d);
86
+ });
87
+ }
88
+ connectedCallback() {
89
+ this._render();
90
+ }
91
+ attributeChangedCallback() {
92
+ this.isConnected && this._render();
93
+ }
94
+ }
95
+ n(nt, "observedAttributes", ["name", "size", "color", "glow", "pulse"]);
96
+ const Tt = `
97
+ :host { display: block; flex-shrink: 0; }
98
+ :host([direction="v"]) { display: inline-block; }
99
+ .sep { background: var(--wox-border, #333); }
100
+ .h { width: 100%; height: 1px; margin: var(--spacing, 0) 0; }
101
+ .v { height: 100%; width: 1px; margin: 0 var(--spacing, 0); display: inline-block; vertical-align: middle; min-height: 16px; }
102
+ `;
103
+ class rt extends v {
104
+ constructor() {
105
+ super(...arguments);
106
+ /** @private */
107
+ n(this, "_render", () => {
108
+ const t = this.getAttribute("direction") || "h", e = this.getAttribute("spacing") || "0";
109
+ this.render(
110
+ `${Tt} :host { --spacing: ${e}; }`,
111
+ `<div class="sep ${t}"></div>`
112
+ );
113
+ });
114
+ }
115
+ connectedCallback() {
116
+ this._render();
117
+ }
118
+ attributeChangedCallback() {
119
+ this.isConnected && this._render();
120
+ }
121
+ }
122
+ n(rt, "observedAttributes", ["direction", "spacing"]);
123
+ const It = `
124
+ :host { display: inline-flex; align-items: center; justify-content: center; }
125
+ .badge { display: inline-flex; align-items: center; justify-content: center; }
126
+ .dot { width: 8px; height: 8px; border-radius: var(--wox-radius-round, 50%); background: var(--color, var(--wox-accent, #00e5ff)); }
127
+ .diamond { width: 8px; height: 8px; background: var(--color, var(--wox-accent, #00e5ff)); transform: rotate(45deg); box-shadow: 0 0 10px color-mix(in srgb, var(--color, var(--wox-accent, #00e5ff)), transparent 50%); }
128
+ .text { background: color-mix(in srgb, var(--color, var(--wox-accent, #00e5ff)), transparent 85%); color: var(--color, var(--wox-accent, #00e5ff)); padding: 3px 8px; border-radius: var(--wox-radius-sm, 3px); font-weight: 600; font-size: var(--wox-font-size-sm, 10px); text-transform: uppercase; letter-spacing: 0.5px; }
129
+ `;
130
+ class at extends v {
131
+ constructor() {
132
+ super(...arguments);
133
+ /** @private */
134
+ n(this, "_render", () => {
135
+ const t = this.getAttribute("variant") || "dot", e = this.getAttribute("text") || "", o = this.getAttribute("color") || "", i = o ? `--color: ${o};` : "";
136
+ let s = "";
137
+ t === "dot" ? s = `<span class="badge dot" style="${i}"></span>` : t === "diamond" ? s = `<span class="badge diamond" style="${i}"></span>` : s = `<span class="badge text" style="${i}">${e}</span>`, this.render(It, s);
138
+ });
139
+ }
140
+ connectedCallback() {
141
+ this._render();
142
+ }
143
+ attributeChangedCallback() {
144
+ this.isConnected && this._render();
145
+ }
146
+ }
147
+ n(at, "observedAttributes", ["variant", "text", "color"]);
148
+ const Nt = `
149
+ :host { display: inline-block; }
150
+ button {
151
+ display: flex; align-items: center; justify-content: center; gap: 6px;
152
+ background: transparent; border: 1px solid var(--wox-border); color: var(--wox-text-secondary, #999);
153
+ cursor: pointer; font-family: var(--wox-font, sans-serif); font-size: var(--wox-font-size-base, 12px);
154
+ transition: all var(--wox-transition-fast, 0.12s); border-radius: var(--wox-radius-sm, 3px);
155
+ padding: 0; margin: 0; line-height: 1; user-select: none;
156
+ }
157
+ button:hover { background: var(--wox-bg-hover, #2a2a2e); color: var(--wox-text-hi, #fff); }
158
+ button:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
159
+ button.active { background: var(--wox-bg-hover, #2a2a2e); color: var(--wox-accent, #00e5ff); border-color: var(--wox-border-light, #444); }
160
+
161
+ /* icon variant */
162
+ button.v-icon { width: 34px; height: 32px; border-radius: var(--wox-radius-sm, 3px); }
163
+ button.v-icon .material-icons { font-size: 18px; }
164
+
165
+ /* text variant */
166
+ button.v-text { padding: 6px 12px; border-radius: var(--wox-radius-md, 6px); font-size: var(--wox-font-size-base, 12px); }
167
+
168
+ /* tile variant */
169
+ button.v-tile {
170
+ flex-direction: column; gap: 6px; background: var(--wox-bg-toolbar, #1e1e22);
171
+ border: 1px solid var(--wox-border, #333); border-radius: var(--wox-radius-xl, 10px);
172
+ padding: 12px 10px; min-width: 68px; font-size: var(--wox-font-size-sm, 10px);
173
+ font-weight: 500; text-transform: uppercase;
174
+ transition: all var(--wox-transition-smooth, 0.25s cubic-bezier(0.4, 0, 0.2, 1));
175
+ position: relative; overflow: hidden;
176
+ }
177
+ button.v-tile:hover { background: var(--wox-bg-hover, #2a2a2e); border-color: #555; color: var(--wox-text-primary, #eee); transform: translateY(-1px); }
178
+ button.v-tile:hover svg, button.v-tile:hover .material-icons { transform: scale(1.05); opacity: 1; }
179
+ button.v-tile svg, button.v-tile .material-icons { display: block; width: 32px; height: 32px; transition: transform 0.2s; opacity: 0.8; font-size: 28px; }
180
+ button.v-tile.delete:hover { border-color: var(--wox-danger, #f72585); color: var(--wox-danger, #f72585); background: rgba(247, 37, 133, 0.05); }
181
+
182
+ /* tile with custom color accent */
183
+ button.v-tile[data-color] { --wox-fx-color: var(--wox-text-secondary, #999); }
184
+ button.v-tile[data-color]:hover {
185
+ background: color-mix(in srgb, var(--wox-fx-color), transparent 92%);
186
+ border-color: var(--wox-fx-color); color: var(--wox-fx-color);
187
+ box-shadow: 0 0 15px color-mix(in srgb, var(--wox-fx-color), transparent 80%);
188
+ }
189
+ button.v-tile[data-color]:hover svg { filter: drop-shadow(0 0 4px var(--wox-fx-color)); }
190
+
191
+ /* dash variant */
192
+ button.v-dash {
193
+ width: 42px; height: 26px; background: #1c1c21;
194
+ border: 1px solid var(--wox-border, #333); border-radius: var(--wox-radius-lg, 8px);
195
+ transition: all 0.2s;
196
+ }
197
+ button.v-dash:hover { background: var(--wox-bg-hover, #2a2a2e); border-color: #555; transform: translateY(-1px); }
198
+ button.v-dash.active { border-color: var(--wox-accent, #00e5ff); box-shadow: var(--wox-shadow-accent, 0 0 10px rgba(0, 229, 255, 0.3)); }
199
+ .dash-line { width: 16px; height: 3px; background: #666; border-radius: 1px; }
200
+ button.v-dash.active .dash-line { background: var(--wox-accent, #00e5ff); }
201
+ .dash-line.dotted { background: radial-gradient(circle, currentColor 1px, transparent 1px); background-size: 4px 100%; color: #666; }
202
+ button.v-dash.active .dash-line.dotted { color: var(--wox-accent, #00e5ff); }
203
+ .dash-line.dashed { background: linear-gradient(to right, currentColor 6px, transparent 6px); background-size: 10px 100%; color: #666; }
204
+ button.v-dash.active .dash-line.dashed { color: var(--wox-accent, #00e5ff); }
205
+ .dash-line.longdash { background: linear-gradient(to right, currentColor 12px, transparent 4px); background-size: 16px 100%; color: #666; }
206
+ button.v-dash.active .dash-line.longdash { color: var(--wox-accent, #00e5ff); }
207
+ .dash-line.dotdash { background: linear-gradient(to right, currentColor 8px, transparent 4px, currentColor 2px, transparent 4px); background-size: 18px 100%; color: #666; }
208
+ button.v-dash.active .dash-line.dotdash { color: var(--wox-accent, #00e5ff); }
209
+ .dash-line.zigzag { background: repeating-linear-gradient(45deg, currentColor, currentColor 2px, transparent 2px, transparent 4px); color: #666; }
210
+ button.v-dash.active .dash-line.zigzag { color: var(--wox-accent, #00e5ff); }
211
+
212
+ .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; display: inline-block; line-height: 1; text-transform: none; letter-spacing: normal; word-wrap: normal; white-space: nowrap; direction: ltr; -webkit-font-smoothing: antialiased; }
213
+ `;
214
+ class lt extends v {
215
+ constructor() {
216
+ super(...arguments);
217
+ /** @private */
218
+ n(this, "_render", () => {
219
+ const t = this.getAttribute("variant") || "icon", e = this.getAttribute("icon") || "", o = this.getAttribute("label") || "", i = this.hasAttribute("active"), s = this.hasAttribute("disabled"), r = this.getAttribute("dash") || "solid", a = this.getAttribute("color") || "", d = this.hasAttribute("glow"), c = this.hasAttribute("pulse"), u = [
220
+ `v-${t}`,
221
+ i ? "active" : "",
222
+ d ? "glow" : "",
223
+ c ? "pulse" : ""
224
+ ].filter(Boolean).join(" ");
225
+ let h = "";
226
+ t === "icon" ? h = e ? `<span class="material-icons">${e}</span>` : "<slot></slot>" : t === "text" ? h = (e ? `<span class="material-icons" style="font-size:14px">${e}</span>` : "") + (o || "<slot></slot>") : t === "tile" ? h = (e ? `<span class="material-icons">${e}</span>` : '<slot name="icon"></slot>') + `<span>${o}</span>` : t === "dash" && (h = `<div class="dash-line${r === "solid" ? "" : ` ${r}`}"></div>`);
227
+ const x = a ? ` data-color style="--wox-fx-color:${a}"` : "";
228
+ this.render(
229
+ Nt + M,
230
+ `<button class="${u}"${x} ${s ? "disabled" : ""}>${h}</button>`
231
+ ), this.$("button").addEventListener("click", (g) => {
232
+ s || this.emit("wox-click", { originalEvent: g });
233
+ });
234
+ });
235
+ }
236
+ connectedCallback() {
237
+ this._render();
238
+ }
239
+ attributeChangedCallback() {
240
+ this.isConnected && this._render();
241
+ }
242
+ }
243
+ n(lt, "observedAttributes", [
244
+ "variant",
245
+ "icon",
246
+ "label",
247
+ "active",
248
+ "disabled",
249
+ "color",
250
+ "size",
251
+ "dash",
252
+ "glow",
253
+ "pulse"
254
+ ]);
255
+ const Pt = `
256
+ :host { display: inline-block; }
257
+ .wrapper { display: flex; flex-direction: column; gap: 3px; }
258
+ label {
259
+ font-size: var(--wox-font-size-sm, 10px); color: var(--wox-text-secondary, #999);
260
+ display: flex; justify-content: space-between; cursor: default; user-select: none;
261
+ }
262
+ label.scrub { cursor: ew-resize; }
263
+ .unit { color: var(--wox-text-secondary, #999); font-size: var(--wox-font-size-sm, 10px); }
264
+ .input-wrap { position: relative; display: flex; align-items: center; }
265
+ input {
266
+ background: var(--wox-bg-input, #1a1a1d); border: 1px solid var(--wox-border, #333);
267
+ color: var(--wox-text-primary, #eee); padding: 6px 8px; border-radius: var(--wox-radius-md, 6px);
268
+ font-size: var(--wox-font-size-md, 11px); font-family: var(--wox-font, sans-serif);
269
+ width: 100%; transition: all var(--wox-transition-normal, 0.2s);
270
+ box-shadow: var(--wox-shadow-input, inset 0 1px 3px rgba(0, 0, 0, 0.2));
271
+ }
272
+ input[type="number"] { text-align: right; }
273
+ input:focus { outline: none; border-color: var(--wox-accent, #00e5ff); background: #222; box-shadow: 0 0 0 2px rgba(0, 229, 255, 0.1), var(--wox-shadow-input, inset 0 1px 3px rgba(0, 0, 0, 0.2)); }
274
+ input:disabled { opacity: 0.4; cursor: not-allowed; }
275
+ input.has-unit { padding-right: 28px; }
276
+ .suffix { position: absolute; right: 8px; font-size: var(--wox-font-size-sm, 10px); color: var(--wox-text-secondary, #999); pointer-events: none; }
277
+ `;
278
+ class dt extends v {
279
+ constructor() {
280
+ super(...arguments);
281
+ /** @private */
282
+ n(this, "_render", () => {
283
+ const t = this.getAttribute("type") || "text", e = this.getAttribute("value") || "", o = this.getAttribute("unit") || "", i = this.getAttribute("label") || "", s = this.getAttribute("min"), r = this.getAttribute("max"), a = this.getAttribute("step"), d = this.getAttribute("placeholder") || "", c = this.hasAttribute("disabled"), u = t === "number", h = u ? `${s !== null ? ` min="${s}"` : ""}${r !== null ? ` max="${r}"` : ""}${a !== null ? ` step="${a}"` : ""}` : "";
284
+ this.render(Pt, `
285
+ <div class="wrapper">
286
+ ${i ? `<label class="${u ? "scrub" : ""}">${i}${o ? `<span class="unit">${o}</span>` : ""}</label>` : ""}
287
+ <div class="input-wrap">
288
+ <input type="${u ? "number" : "text"}" value="${e}" placeholder="${d}" ${h} ${c ? "disabled" : ""} class="${o && !i ? "has-unit" : ""}">
289
+ ${o && !i ? `<span class="suffix">${o}</span>` : ""}
290
+ </div>
291
+ </div>
292
+ `);
293
+ const x = this.$("input");
294
+ if (x.addEventListener("input", () => {
295
+ const g = u ? parseFloat(x.value) : x.value;
296
+ this.emit("wox-input", { value: g });
297
+ }), x.addEventListener("change", () => {
298
+ const g = u ? parseFloat(x.value) : x.value;
299
+ this.emit("wox-change", { value: g });
300
+ }), x.addEventListener("keydown", (g) => {
301
+ g.key === "Enter" && x.blur();
302
+ }), u && i) {
303
+ const g = this.$("label");
304
+ let b = 0, f = 0;
305
+ const w = (S) => {
306
+ const O = S.clientX - b, _ = parseFloat(a) || 1;
307
+ let k = f + Math.round(O / 2) * _;
308
+ s !== null && (k = Math.max(parseFloat(s), k)), r !== null && (k = Math.min(parseFloat(r), k)), x.value = k, this.emit("wox-input", { value: k });
309
+ }, y = () => {
310
+ document.removeEventListener("mousemove", w), document.removeEventListener("mouseup", y), this.emit("wox-change", { value: parseFloat(x.value) });
311
+ };
312
+ g.addEventListener("mousedown", (S) => {
313
+ c || (b = S.clientX, f = parseFloat(x.value) || 0, document.addEventListener("mousemove", w), document.addEventListener("mouseup", y), S.preventDefault());
314
+ });
315
+ }
316
+ });
317
+ }
318
+ connectedCallback() {
319
+ this._render();
320
+ }
321
+ attributeChangedCallback(t) {
322
+ if (this.isConnected) {
323
+ if (t === "value") {
324
+ const e = this.$("input");
325
+ e && document.activeElement !== this && (e.value = this.getAttribute("value") || "");
326
+ return;
327
+ }
328
+ this._render();
329
+ }
330
+ }
331
+ get value() {
332
+ const t = this.$("input");
333
+ return t ? t.value : this.getAttribute("value") || "";
334
+ }
335
+ set value(t) {
336
+ this.setAttribute("value", t);
337
+ const e = this.$("input");
338
+ e && (e.value = t);
339
+ }
340
+ }
341
+ n(dt, "observedAttributes", ["type", "value", "unit", "label", "min", "max", "step", "placeholder", "disabled"]);
342
+ const Ft = `
343
+ :host {
344
+ display: inline-block;
345
+ position: relative;
346
+ min-width: 200px;
347
+ font-family: var(--wox-font, 'Inter', sans-serif);
348
+ font-size: var(--wox-font-size-base, 12px);
349
+ outline: none;
350
+ }
351
+
352
+ :host(:focus) .trigger,
353
+ :host(:focus-within) .trigger {
354
+ border-color: var(--wox-accent, #00e5ff);
355
+ box-shadow: 0 0 0 2px rgba(0, 229, 255, 0.1);
356
+ }
357
+
358
+ :host([disabled]) {
359
+ opacity: 0.4;
360
+ cursor: not-allowed;
361
+ pointer-events: none;
362
+ }
363
+
364
+ .trigger {
365
+ display: flex;
366
+ align-items: center;
367
+ justify-content: space-between;
368
+ gap: 6px;
369
+ background: var(--wox-bg-input, #1a1a1d);
370
+ border: 1px solid var(--wox-border, #333);
371
+ border-radius: var(--wox-radius-md, 6px);
372
+ padding: 6px 8px;
373
+ cursor: pointer;
374
+ min-height: 30px;
375
+ box-sizing: border-box;
376
+ color: var(--wox-text-primary, #eee);
377
+ user-select: none;
378
+ transition: border-color var(--wox-transition-fast, 0.12s);
379
+ }
380
+
381
+ .trigger:focus { outline: none; }
382
+
383
+ .selected-content {
384
+ display: flex;
385
+ align-items: center;
386
+ gap: 4px;
387
+ flex-wrap: wrap;
388
+ flex: 1;
389
+ min-width: 0;
390
+ }
391
+
392
+ .placeholder {
393
+ color: var(--wox-text-secondary, #999);
394
+ white-space: nowrap;
395
+ overflow: hidden;
396
+ text-overflow: ellipsis;
397
+ }
398
+
399
+ .single-value {
400
+ display: flex;
401
+ align-items: center;
402
+ gap: 6px;
403
+ white-space: nowrap;
404
+ overflow: hidden;
405
+ text-overflow: ellipsis;
406
+ }
407
+
408
+ .single-img {
409
+ width: 18px;
410
+ height: 18px;
411
+ border-radius: var(--wox-radius-round, 50%);
412
+ object-fit: cover;
413
+ flex-shrink: 0;
414
+ }
415
+
416
+ .tag {
417
+ display: inline-flex;
418
+ align-items: center;
419
+ gap: 3px;
420
+ padding: 1px 6px;
421
+ background: var(--wox-bg-hover, #2a2a2e);
422
+ border: 1px solid var(--wox-border-light, #444);
423
+ border-radius: var(--wox-radius-sm, 3px);
424
+ font-size: var(--wox-font-size-sm, 10px);
425
+ color: var(--wox-text-primary, #eee);
426
+ user-select: none;
427
+ }
428
+
429
+ .tag-img {
430
+ width: 14px;
431
+ height: 14px;
432
+ border-radius: var(--wox-radius-round, 50%);
433
+ object-fit: cover;
434
+ flex-shrink: 0;
435
+ }
436
+
437
+ .remove-tag {
438
+ cursor: pointer;
439
+ color: var(--wox-text-secondary, #999);
440
+ font-size: 12px;
441
+ line-height: 1;
442
+ padding: 0 1px;
443
+ }
444
+
445
+ .remove-tag:hover { color: var(--wox-danger, #f72585); }
446
+
447
+ .arrow {
448
+ width: 0;
449
+ height: 0;
450
+ border-left: 4px solid transparent;
451
+ border-right: 4px solid transparent;
452
+ border-top: 5px solid var(--wox-text-secondary, #999);
453
+ flex-shrink: 0;
454
+ transition: transform var(--wox-transition-fast, 0.12s);
455
+ }
456
+
457
+ .arrow.open { transform: rotate(180deg); }
458
+
459
+ .dropdown {
460
+ position: fixed;
461
+ z-index: var(--wox-z-dropdown, 1000);
462
+ background: var(--wox-bg-panel, #17171a);
463
+ border: 1px solid var(--wox-border, #333);
464
+ border-radius: var(--wox-radius-md, 6px);
465
+ box-shadow: var(--wox-shadow-md, 0 4px 16px rgba(0, 0, 0, 0.4));
466
+ max-height: 200px;
467
+ overflow-y: auto;
468
+ scroll-behavior: smooth;
469
+ }
470
+
471
+ .search-input {
472
+ width: 100%;
473
+ padding: 6px 10px;
474
+ background: var(--wox-bg-input, #1a1a1d);
475
+ border: none;
476
+ border-bottom: 1px solid var(--wox-border, #333);
477
+ color: var(--wox-text-primary, #eee);
478
+ font-size: var(--wox-font-size-base, 12px);
479
+ font-family: var(--wox-font, sans-serif);
480
+ outline: none;
481
+ box-sizing: border-box;
482
+ }
483
+
484
+ .option {
485
+ display: flex;
486
+ align-items: center;
487
+ gap: 8px;
488
+ padding: 6px 10px;
489
+ cursor: pointer;
490
+ color: var(--wox-text-primary, #eee);
491
+ font-size: var(--wox-font-size-base, 12px);
492
+ transition: background var(--wox-transition-fast, 0.12s);
493
+ user-select: none;
494
+ }
495
+
496
+ .option:hover { background: var(--wox-bg-hover, #2a2a2e); }
497
+
498
+ .option.focused {
499
+ background: rgba(0, 229, 255, 0.1);
500
+ color: var(--wox-accent, #00e5ff);
501
+ }
502
+
503
+ .option.selected { color: var(--wox-accent, #00e5ff); }
504
+
505
+ .option-img {
506
+ width: 20px;
507
+ height: 20px;
508
+ border-radius: var(--wox-radius-round, 50%);
509
+ object-fit: cover;
510
+ flex-shrink: 0;
511
+ }
512
+
513
+ .no-options {
514
+ padding: 8px 10px;
515
+ color: var(--wox-text-secondary, #999);
516
+ font-style: italic;
517
+ font-size: var(--wox-font-size-base, 12px);
518
+ }
519
+ `, $ = (l) => String(l).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
520
+ class ct extends v {
521
+ constructor() {
522
+ super(...arguments);
523
+ /** @type {boolean} */
524
+ n(this, "_isOpen", !1);
525
+ /** @type {boolean} */
526
+ n(this, "_openUpward", !1);
527
+ /** @type {Array<{value:string,label:string,image?:string}>} */
528
+ n(this, "_selectedOptions", []);
529
+ /** @type {Array<{value:string,label:string,image?:string}>} */
530
+ n(this, "_filteredOptions", []);
531
+ /** @type {number} */
532
+ n(this, "_focusedIndex", -1);
533
+ /** @type {string} */
534
+ n(this, "_searchValue", "");
535
+ /** @type {boolean} */
536
+ n(this, "_keyboardNavigating", !1);
537
+ /** @type {number|undefined} */
538
+ n(this, "_keyboardTimer");
539
+ /** @type {Array<{value:string,label:string,image?:string}>|null} */
540
+ n(this, "_parsedOptions", null);
541
+ // ── Private ────────────────────────────────────────────────────────────────
542
+ /** @private */
543
+ n(this, "_handleSearch", (t) => {
544
+ this._searchValue = t, this._filteredOptions = this.options.filter(
545
+ (e) => e.label.toLowerCase().includes(t.toLowerCase())
546
+ ), this._focusedIndex = -1, this._render(), this.emit("wox-search", { query: t });
547
+ });
548
+ /** @private */
549
+ n(this, "_updateFocusedOption", () => {
550
+ const t = this.$$(".option");
551
+ t.forEach((e) => e.classList.remove("focused")), this._focusedIndex >= 0 && this._focusedIndex < t.length && t[this._focusedIndex].classList.add("focused"), this._scrollToFocused();
552
+ });
553
+ /** @private */
554
+ n(this, "_scrollToFocused", () => {
555
+ this._focusedIndex < 0 || requestAnimationFrame(() => {
556
+ const t = this.$(".dropdown"), e = this.$(".option.focused");
557
+ if (!t || !e) return;
558
+ const o = t.getBoundingClientRect(), i = e.getBoundingClientRect();
559
+ i.top < o.top ? t.scrollTop -= o.top - i.top : i.bottom > o.bottom && (t.scrollTop += i.bottom - o.bottom);
560
+ });
561
+ });
562
+ /** @private */
563
+ n(this, "_calculateDropdownPosition", () => {
564
+ const t = this.$(".trigger");
565
+ if (!t) return null;
566
+ const e = t.getBoundingClientRect(), o = window.innerHeight, i = window.innerWidth, s = 200, r = 2, a = 10, d = o - e.bottom, c = e.top, u = e.width, h = Math.max(0, Math.min(e.left, i - u));
567
+ return this._openUpward ? {
568
+ bottom: o - e.top + r,
569
+ left: h,
570
+ width: u,
571
+ maxHeight: Math.max(100, Math.min(s, c - a))
572
+ } : {
573
+ top: e.bottom + r,
574
+ left: h,
575
+ width: u,
576
+ maxHeight: Math.max(100, Math.min(s, d - a))
577
+ };
578
+ });
579
+ /** @private */
580
+ n(this, "_updateDropdownPosition", () => {
581
+ requestAnimationFrame(() => {
582
+ const t = this.$(".dropdown");
583
+ if (!t) return;
584
+ const e = this._calculateDropdownPosition();
585
+ e && (t.style.top = "", t.style.bottom = "", e.top !== void 0 && (t.style.top = `${e.top}px`), e.bottom !== void 0 && (t.style.bottom = `${e.bottom}px`), t.style.left = `${e.left}px`, t.style.width = `${e.width}px`, t.style.maxHeight = `${e.maxHeight}px`);
586
+ });
587
+ });
588
+ /** @private */
589
+ n(this, "_handleKeydown", (t) => {
590
+ if (!this.disabled)
591
+ switch (t.key) {
592
+ case "ArrowDown":
593
+ if (t.preventDefault(), this._keyboardNavigating = !0, clearTimeout(this._keyboardTimer), this._keyboardTimer = window.setTimeout(() => {
594
+ this._keyboardNavigating = !1;
595
+ }, 100), !this._isOpen)
596
+ this.open();
597
+ else {
598
+ const e = this.$(".search-input");
599
+ if (this.searchable && e === this.shadowRoot.activeElement) {
600
+ this._focusedIndex = 0, e.blur(), this.focus(), this._updateFocusedOption();
601
+ return;
602
+ }
603
+ this._focusedIndex = Math.min(this._focusedIndex + 1, this._filteredOptions.length - 1), this._updateFocusedOption();
604
+ }
605
+ break;
606
+ case "ArrowUp":
607
+ if (t.preventDefault(), this._keyboardNavigating = !0, clearTimeout(this._keyboardTimer), this._keyboardTimer = window.setTimeout(() => {
608
+ this._keyboardNavigating = !1;
609
+ }, 100), this._isOpen) {
610
+ if (this._focusedIndex === 0 && this.searchable) {
611
+ this._focusedIndex = -1, this._updateFocusedOption(), requestAnimationFrame(() => {
612
+ const o = this.$(".search-input");
613
+ o && (o.focus(), o.setSelectionRange(o.value.length, o.value.length));
614
+ });
615
+ return;
616
+ }
617
+ const e = this.$(".search-input");
618
+ if (this.searchable && e === this.shadowRoot.activeElement) return;
619
+ this._focusedIndex = Math.max(this._focusedIndex - 1, -1), this._updateFocusedOption();
620
+ }
621
+ break;
622
+ case "Enter":
623
+ t.preventDefault(), this._isOpen && this._focusedIndex >= 0 && this._focusedIndex < this._filteredOptions.length ? this.selectOption(this._filteredOptions[this._focusedIndex].value) : this._isOpen || this.open();
624
+ break;
625
+ case "Escape":
626
+ t.preventDefault(), this.close();
627
+ break;
628
+ case "Tab":
629
+ this.close();
630
+ break;
631
+ }
632
+ });
633
+ /** @private */
634
+ n(this, "_render", () => {
635
+ this._filteredOptions.length === 0 && this.options.length > 0 && (this._filteredOptions = [...this.options]);
636
+ const t = this.$(".search-input") === this.shadowRoot.activeElement;
637
+ let e = "";
638
+ if (this.multiple && this._selectedOptions.length > 0)
639
+ e = this._selectedOptions.map((i) => `
640
+ <span class="tag">
641
+ ${i.image ? `<img src="${$(i.image)}" class="tag-img" alt="">` : ""}
642
+ ${$(i.label)}
643
+ <span class="remove-tag" data-value="${$(i.value)}">×</span>
644
+ </span>
645
+ `).join("");
646
+ else if (this._selectedOptions.length > 0) {
647
+ const i = this._selectedOptions[0];
648
+ e = `<span class="single-value">
649
+ ${i.image ? `<img src="${$(i.image)}" class="single-img" alt="">` : ""}
650
+ <span>${$(i.label)}</span>
651
+ </span>`;
652
+ } else
653
+ e = `<span class="placeholder">${$(this.placeholder)}</span>`;
654
+ let o = "";
655
+ if (this._isOpen) {
656
+ const i = this.searchable ? `<input type="text" class="search-input" placeholder="Search..." value="${$(this._searchValue)}">` : "", s = this._filteredOptions.length > 0 ? this._filteredOptions.map((r, a) => {
657
+ const d = this._selectedOptions.some((u) => u.value === r.value), c = a === this._focusedIndex;
658
+ return `<div
659
+ class="option${d ? " selected" : ""}${c ? " focused" : ""}"
660
+ data-value="${$(r.value)}"
661
+ >
662
+ ${r.image ? `<img src="${$(r.image)}" class="option-img" alt="">` : ""}
663
+ <span>${$(r.label)}</span>
664
+ </div>`;
665
+ }).join("") : '<div class="no-options">No options found</div>';
666
+ o = `<div class="dropdown">${i}${s}</div>`;
667
+ }
668
+ if (this.render(Ft, `
669
+ <div class="trigger" tabindex="-1">
670
+ <div class="selected-content">${e}</div>
671
+ <div class="arrow${this._isOpen ? " open" : ""}"></div>
672
+ </div>
673
+ ${o}
674
+ `), this._isOpen) {
675
+ const i = this.$(".dropdown");
676
+ i && i.addEventListener("mouseleave", () => {
677
+ var s;
678
+ this._keyboardNavigating || ((s = this.$(".option.focused")) == null || s.classList.remove("focused"), this._focusedIndex = -1);
679
+ });
680
+ }
681
+ t && this.searchable && this._isOpen && requestAnimationFrame(() => {
682
+ const i = this.$(".search-input");
683
+ i && (i.focus(), i.setSelectionRange(i.value.length, i.value.length));
684
+ }), this._isOpen && this._updateDropdownPosition();
685
+ });
686
+ }
687
+ connectedCallback() {
688
+ this.hasAttribute("tabindex") || this.setAttribute("tabindex", "0"), this._boundDocumentClick = (t) => {
689
+ this.contains(t.target) || this.close();
690
+ }, this._boundWindowResize = () => {
691
+ this._isOpen && this._updateDropdownPosition();
692
+ }, this._boundWindowScroll = () => {
693
+ this._isOpen && this._updateDropdownPosition();
694
+ }, this._boundShadowClick = (t) => {
695
+ t.stopPropagation();
696
+ const e = t.target.closest(".remove-tag");
697
+ if (e) {
698
+ this.deselectOption(e.dataset.value);
699
+ return;
700
+ }
701
+ const o = t.target.closest(".option");
702
+ if (o) {
703
+ this.selectOption(o.dataset.value);
704
+ return;
705
+ }
706
+ t.target.closest(".trigger") && this.toggle();
707
+ }, this._boundShadowMouseover = (t) => {
708
+ var s;
709
+ if (this._keyboardNavigating) return;
710
+ const e = t.target.closest(".option");
711
+ if (!e) return;
712
+ const i = Array.from(this.$$(".option")).indexOf(e);
713
+ this._focusedIndex !== i && ((s = this.$(".option.focused")) == null || s.classList.remove("focused"), e.classList.add("focused"), this._focusedIndex = i);
714
+ }, this._boundShadowInput = (t) => {
715
+ t.target.classList.contains("search-input") && this._handleSearch(t.target.value);
716
+ }, document.addEventListener("click", this._boundDocumentClick), window.addEventListener("resize", this._boundWindowResize), window.addEventListener("scroll", this._boundWindowScroll, !0), this.addEventListener("keydown", this._handleKeydown), this.shadowRoot.addEventListener("click", this._boundShadowClick), this.shadowRoot.addEventListener("mouseover", this._boundShadowMouseover), this.shadowRoot.addEventListener("input", this._boundShadowInput), this._render();
717
+ }
718
+ disconnectedCallback() {
719
+ clearTimeout(this._keyboardTimer), document.removeEventListener("click", this._boundDocumentClick), window.removeEventListener("resize", this._boundWindowResize), window.removeEventListener("scroll", this._boundWindowScroll, !0), this.removeEventListener("keydown", this._handleKeydown), this.shadowRoot.removeEventListener("click", this._boundShadowClick), this.shadowRoot.removeEventListener("mouseover", this._boundShadowMouseover), this.shadowRoot.removeEventListener("input", this._boundShadowInput);
720
+ }
721
+ attributeChangedCallback(t, e, o) {
722
+ if (!(e === o || !this.isConnected)) {
723
+ if (t === "options") {
724
+ this._parsedOptions = null;
725
+ const i = this.options;
726
+ this._filteredOptions = [...i], this._selectedOptions = this._selectedOptions.filter(
727
+ (s) => i.some((r) => r.value === s.value)
728
+ );
729
+ } else if (t === "value" && o !== null) {
730
+ const i = this.options.find((s) => s.value === o);
731
+ this._selectedOptions = i ? [i] : [];
732
+ }
733
+ this._render();
734
+ }
735
+ }
736
+ // ── Getters / setters ──────────────────────────────────────────────────────
737
+ get multiple() {
738
+ return this.hasAttribute("multiple");
739
+ }
740
+ set multiple(t) {
741
+ t ? this.setAttribute("multiple", "") : this.removeAttribute("multiple");
742
+ }
743
+ get searchable() {
744
+ return this.hasAttribute("searchable");
745
+ }
746
+ set searchable(t) {
747
+ t ? this.setAttribute("searchable", "") : this.removeAttribute("searchable");
748
+ }
749
+ get placeholder() {
750
+ return this.getAttribute("placeholder") || "Select an option";
751
+ }
752
+ set placeholder(t) {
753
+ this.setAttribute("placeholder", t);
754
+ }
755
+ get disabled() {
756
+ return this.hasAttribute("disabled");
757
+ }
758
+ set disabled(t) {
759
+ t ? this.setAttribute("disabled", "") : this.removeAttribute("disabled");
760
+ }
761
+ get value() {
762
+ return this.multiple ? this._selectedOptions.map((t) => t.value) : this._selectedOptions.length > 0 ? this._selectedOptions[0].value : "";
763
+ }
764
+ set value(t) {
765
+ if (this.multiple && Array.isArray(t))
766
+ this._selectedOptions = this.options.filter((e) => t.includes(e.value));
767
+ else {
768
+ const e = this.options.find((o) => o.value === t);
769
+ this._selectedOptions = e ? [e] : [];
770
+ }
771
+ this._render();
772
+ }
773
+ get options() {
774
+ if (this._parsedOptions !== null) return this._parsedOptions;
775
+ const t = this.getAttribute("options");
776
+ if (t)
777
+ try {
778
+ return this._parsedOptions = JSON.parse(t), this._parsedOptions;
779
+ } catch (e) {
780
+ return console.error("wox-select: invalid options JSON", e), [];
781
+ }
782
+ return [];
783
+ }
784
+ set options(t) {
785
+ this._parsedOptions = null, this.setAttribute("options", JSON.stringify(t));
786
+ }
787
+ // ── Public API ─────────────────────────────────────────────────────────────
788
+ /** Opens the dropdown */
789
+ open() {
790
+ if (this.disabled) return;
791
+ this._isOpen = !0, this._focusedIndex = -1, this._filteredOptions = [...this.options];
792
+ const t = this.$(".trigger");
793
+ if (t) {
794
+ const e = t.getBoundingClientRect(), o = window.innerHeight - e.bottom, i = e.top;
795
+ this._openUpward = o < 210 && i > o;
796
+ }
797
+ this._render(), this._updateDropdownPosition(), this.searchable && requestAnimationFrame(() => {
798
+ const e = this.$(".search-input");
799
+ e && e.focus();
800
+ }), this.emit("wox-open", null);
801
+ }
802
+ /** Closes the dropdown */
803
+ close() {
804
+ this._isOpen = !1, this._openUpward = !1, this._focusedIndex = -1, this._searchValue = "", this._filteredOptions = [...this.options];
805
+ const t = this.$(".dropdown");
806
+ t && (t.style.top = "", t.style.left = "", t.style.width = "", t.style.maxHeight = ""), this._render(), this.emit("wox-close", null);
807
+ }
808
+ /** Toggles the dropdown open/closed */
809
+ toggle() {
810
+ this._isOpen ? this.close() : this.open();
811
+ }
812
+ /**
813
+ * Selects an option by value
814
+ * @param {string} value
815
+ */
816
+ selectOption(t) {
817
+ const e = this.options.find((o) => o.value === t);
818
+ e && (this.multiple ? (this._selectedOptions.find((o) => o.value === t) || this._selectedOptions.push(e), this._render()) : (this._selectedOptions = [e], this.close()), this.emit("wox-change", { value: this.value }));
819
+ }
820
+ /**
821
+ * Deselects an option by value
822
+ * @param {string} value
823
+ */
824
+ deselectOption(t) {
825
+ this._selectedOptions = this._selectedOptions.filter((e) => e.value !== t), this._render(), this.emit("wox-change", { value: this.value });
826
+ }
827
+ /**
828
+ * Returns a copy of the currently selected options
829
+ * @returns {Array<{value:string,label:string,image?:string}>}
830
+ */
831
+ getSelectedOptions() {
832
+ return [...this._selectedOptions];
833
+ }
834
+ /**
835
+ * Replaces all options and clears the selection
836
+ * @param {Array<{value:string,label:string,image?:string}>} opts
837
+ */
838
+ setOptions(t) {
839
+ this._selectedOptions = [], this._filteredOptions = [...t], this._parsedOptions = null, this.setAttribute("options", JSON.stringify(t));
840
+ }
841
+ }
842
+ n(ct, "observedAttributes", ["multiple", "searchable", "placeholder", "disabled", "value", "options"]);
843
+ const Ht = `
844
+ :host { display: inline-block; width: 100%; }
845
+ .wrapper { display: flex; align-items: center; gap: var(--wox-space-lg, 12px); }
846
+ .label {
847
+ font-size: var(--wox-font-size-sm, 10px); color: var(--wox-text-secondary, #999);
848
+ font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase; min-width: 50px;
849
+ user-select: none;
850
+ }
851
+ .track-wrap { flex: 1; position: relative; height: 20px; display: flex; align-items: center; cursor: pointer; }
852
+ .track { width: 100%; height: 4px; background: var(--wox-border, #333); border-radius: 2px; position: relative; overflow: hidden; }
853
+ .fill { height: 100%; background: var(--wox-accent, #00e5ff); border-radius: 2px; }
854
+ .thumb {
855
+ position: absolute; top: 50%; width: 14px; height: 14px; border-radius: 50%;
856
+ background: var(--wox-text-hi, #fff); border: 2px solid var(--wox-accent, #00e5ff);
857
+ transform: translate(-50%, -50%); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
858
+ transition: box-shadow 0.15s; pointer-events: none;
859
+ }
860
+ .thumb.dragging { box-shadow: 0 0 8px rgba(0, 229, 255, 0.4); }
861
+ .value {
862
+ font-size: var(--wox-font-size-base, 12px); color: var(--wox-text-secondary, #999);
863
+ font-weight: 600; min-width: 35px; text-align: right; user-select: none;
864
+ }
865
+ .fill.custom-color { background: var(--wox-fx-color); }
866
+ .thumb.glow { width: 16px; height: 16px; }
867
+ `;
868
+ class pt extends v {
869
+ constructor() {
870
+ super();
871
+ /** @private — Reads config attrs (not value) */
872
+ n(this, "_getConfig", () => ({
873
+ min: parseFloat(this.getAttribute("min") ?? 0),
874
+ max: parseFloat(this.getAttribute("max") ?? 100),
875
+ step: parseFloat(this.getAttribute("step") ?? 1),
876
+ unit: this.getAttribute("unit") || ""
877
+ }));
878
+ /** @private — Format a numeric value for display */
879
+ n(this, "_formatVal", (t) => {
880
+ const { unit: e, step: o } = this._getConfig();
881
+ return e === "%" ? Math.round(t * 100) + "%" : o < 1 ? t.toFixed(2) : String(t);
882
+ });
883
+ /** @private — Update fill/thumb/value text without rebuilding DOM */
884
+ n(this, "_updateVisuals", () => {
885
+ const { min: t, max: e } = this._getConfig(), o = parseFloat(this.getAttribute("value") ?? t), i = (o - t) / (e - t) * 100, s = this.$(".fill"), r = this.$(".thumb"), a = this.$(".value");
886
+ s && (s.style.width = i + "%"), r && (r.style.left = i + "%"), a && (a.textContent = this._formatVal(o));
887
+ });
888
+ /** @private — Full DOM build (only on structural attr changes or first connect) */
889
+ n(this, "_build", () => {
890
+ const { min: t, max: e } = this._getConfig(), o = parseFloat(this.getAttribute("value") ?? t), i = this.getAttribute("label") || "", s = this.hasAttribute("show-value"), r = (o - t) / (e - t) * 100, a = this.getAttribute("color") || "", d = this.hasAttribute("glow"), c = this.hasAttribute("pulse"), u = [d ? "glow" : "", c ? "pulse" : ""].filter(Boolean).join(" "), h = a ? `--wox-fx-color:${a};border-color:${a}` : "", x = a ? " custom-color" : "";
891
+ this.render(Ht + M, `
892
+ <div class="wrapper">
893
+ ${i ? `<span class="label">${i}</span>` : ""}
894
+ <div class="track-wrap">
895
+ <div class="track"><div class="fill${x}" style="width:${r}%;${a ? "--wox-fx-color:" + a : ""}"></div></div>
896
+ <div class="thumb ${u}" style="${h};left:${r}%"></div>
897
+ </div>
898
+ ${s ? `<span class="value">${this._formatVal(o)}</span>` : ""}
899
+ </div>
900
+ `), this._attachDrag();
901
+ });
902
+ /** @private — Wire up drag interaction on the track */
903
+ n(this, "_attachDrag", () => {
904
+ const { min: t, max: e, step: o, unit: i } = this._getConfig(), s = this.$(".track-wrap"), r = this.$(".fill"), a = this.$(".thumb"), d = this.$(".value"), c = (x) => {
905
+ const g = s.getBoundingClientRect();
906
+ let b = (x - g.left) / g.width;
907
+ b = Math.max(0, Math.min(1, b));
908
+ let f = t + b * (e - t);
909
+ f = Math.round(f / o) * o, f = Math.max(t, Math.min(e, f));
910
+ const w = (f - t) / (e - t) * 100;
911
+ return r.style.width = w + "%", a.style.left = w + "%", d && (i === "%" ? d.textContent = Math.round(f * 100) + "%" : d.textContent = o < 1 ? f.toFixed(2) : String(f)), f;
912
+ }, u = (x) => {
913
+ const g = c(x.clientX);
914
+ this.emit("wox-input", { value: g });
915
+ }, h = (x) => {
916
+ this._dragging = !1, a.classList.remove("dragging"), document.removeEventListener("mousemove", u), document.removeEventListener("mouseup", h);
917
+ const g = c(x.clientX);
918
+ this.setAttribute("value", g), this.emit("wox-change", { value: g });
919
+ };
920
+ s.addEventListener("mousedown", (x) => {
921
+ this._dragging = !0, a.classList.add("dragging");
922
+ const g = c(x.clientX);
923
+ this.emit("wox-input", { value: g }), document.addEventListener("mousemove", u), document.addEventListener("mouseup", h), x.preventDefault();
924
+ });
925
+ });
926
+ this._dragging = !1;
927
+ }
928
+ connectedCallback() {
929
+ this._build();
930
+ }
931
+ attributeChangedCallback(t) {
932
+ this.isConnected && (this._dragging || (t === "value" ? this._updateVisuals() : this._build()));
933
+ }
934
+ }
935
+ n(pt, "observedAttributes", ["value", "min", "max", "step", "label", "unit", "show-value", "color", "glow", "pulse"]);
936
+ const Bt = `
937
+ :host { display: inline-block; }
938
+ .swatch {
939
+ width: var(--size, 24px); height: var(--size, 24px);
940
+ border-radius: var(--wox-radius-sm, 3px); cursor: pointer;
941
+ border: 1px solid rgba(0, 0, 0, 0.5);
942
+ box-shadow: var(--wox-shadow-sm, 0 2px 4px rgba(0, 0, 0, 0.3));
943
+ transition: all var(--wox-transition-fast, 0.12s);
944
+ position: relative; overflow: hidden;
945
+ }
946
+ .swatch:hover { transform: scale(1.1); border-color: var(--wox-accent, #00e5ff); }
947
+ .swatch.selected { border-color: var(--wox-text-hi, #fff); border-width: 2px; box-shadow: 0 0 15px rgba(255, 255, 255, 0.2); }
948
+ .checker {
949
+ position: absolute; inset: 0;
950
+ background: repeating-conic-gradient(#888 0% 25%, #fff 0% 50%) 0 0 / 8px 8px;
951
+ }
952
+ .color { position: absolute; inset: 0; }
953
+ `;
954
+ class ht extends v {
955
+ constructor() {
956
+ super(...arguments);
957
+ /** @private */
958
+ n(this, "_render", () => {
959
+ const t = this.getAttribute("color") || "transparent", e = this.getAttribute("size") || "24", o = this.hasAttribute("selected"), i = this.hasAttribute("glow"), s = this.hasAttribute("pulse"), r = [o ? "selected" : "", i ? "glow" : "", s ? "pulse" : ""].filter(Boolean).join(" "), a = i || s ? ` style="--wox-fx-color:${t}"` : "";
960
+ this.render(
961
+ `${Bt} ${M} :host { --size: ${e}px; }`,
962
+ `<div class="swatch ${r}"${a}>
963
+ <div class="checker"></div>
964
+ <div class="color" style="background:${t}"></div>
965
+ </div>`
966
+ ), this.$(".swatch").addEventListener("click", () => {
967
+ this.emit("wox-click", { color: t });
968
+ });
969
+ });
970
+ }
971
+ connectedCallback() {
972
+ this._render();
973
+ }
974
+ attributeChangedCallback() {
975
+ this.isConnected && this._render();
976
+ }
977
+ }
978
+ n(ht, "observedAttributes", ["color", "size", "selected", "glow", "pulse"]);
979
+ const Yt = `
980
+ :host { display: inline-block; position: relative; }
981
+ .tip {
982
+ position: fixed; z-index: var(--wox-z-overlay, 10000);
983
+ background: #222; color: var(--wox-text-hi, #fff); border: 1px solid var(--wox-border-light, #444);
984
+ border-radius: var(--wox-radius-sm, 3px); padding: 4px 8px; font-size: var(--wox-font-size-md, 11px);
985
+ white-space: nowrap; pointer-events: none;
986
+ opacity: 0; transition: opacity var(--wox-transition-fast, 0.12s);
987
+ box-shadow: var(--wox-shadow-md, 0 4px 16px rgba(0, 0, 0, 0.4));
988
+ }
989
+ :host(:hover) .tip { opacity: 1; }
990
+ `;
991
+ class xt extends v {
992
+ constructor() {
993
+ super(...arguments);
994
+ /** @private */
995
+ n(this, "_render", () => {
996
+ const t = this.getAttribute("text") || "";
997
+ this.render(Yt, `
998
+ <slot></slot>
999
+ ${t ? `<div class="tip">${t}</div>` : ""}
1000
+ `), t && this.addEventListener("mouseenter", this._position);
1001
+ });
1002
+ /** @private Positions the tooltip relative to the host, flipping if it would overflow the viewport */
1003
+ n(this, "_position", () => {
1004
+ const t = this.shadowRoot.querySelector(".tip");
1005
+ if (!t) return;
1006
+ const e = 6, o = this.getAttribute("position") || "top", i = this.getBoundingClientRect(), s = t.getBoundingClientRect(), r = window.innerWidth, a = window.innerHeight, d = {
1007
+ top: i.top - e - s.height >= 0,
1008
+ bottom: i.bottom + e + s.height <= a,
1009
+ left: i.left - e - s.width >= 0,
1010
+ right: i.right + e + s.width <= r
1011
+ }, c = { top: "bottom", bottom: "top", left: "right", right: "left" }, h = [o, c[o], ...["top", "bottom", "left", "right"].filter((b) => b !== o && b !== c[o])].find((b) => d[b]) || o;
1012
+ let x, g;
1013
+ h === "top" ? (x = i.top - e - s.height, g = i.left + i.width / 2 - s.width / 2) : h === "bottom" ? (x = i.bottom + e, g = i.left + i.width / 2 - s.width / 2) : h === "left" ? (x = i.top + i.height / 2 - s.height / 2, g = i.left - e - s.width) : (x = i.top + i.height / 2 - s.height / 2, g = i.right + e), g = Math.max(4, Math.min(g, r - s.width - 4)), x = Math.max(4, Math.min(x, a - s.height - 4)), t.style.top = `${x}px`, t.style.left = `${g}px`;
1014
+ });
1015
+ }
1016
+ connectedCallback() {
1017
+ this._render();
1018
+ }
1019
+ attributeChangedCallback() {
1020
+ this.isConnected && this._render();
1021
+ }
1022
+ }
1023
+ n(xt, "observedAttributes", ["text", "position", "delay"]);
1024
+ const A = 220, T = 104, z = 78, D = 104, E = 192, L = 14, jt = `
1025
+ :host { display: block; }
1026
+ .cp-popup {
1027
+ position: fixed; z-index: var(--wox-z-modal, 20000);
1028
+ flex-direction: column; align-items: center; gap: 12px;
1029
+ background: var(--wox-bg-panel, #17171a); border: 1px solid var(--wox-border, #333);
1030
+ border-radius: var(--wox-radius-2xl, 12px); padding: 16px;
1031
+ box-shadow: var(--wox-shadow-xl), 0 0 0 1px rgba(255, 255, 255, 0.04);
1032
+ width: 252px; user-select: none; overflow: hidden; display: none;
1033
+ }
1034
+ .cp-popup.open { display: flex; }
1035
+ .cp-header {
1036
+ width: calc(100% + 32px); margin: -16px -16px 12px -16px; padding: 10px 16px;
1037
+ background: var(--wox-bg-section-header, #22222a); border-bottom: 1px solid var(--wox-border-section, #2e2e2e);
1038
+ display: flex; justify-content: space-between; align-items: center; cursor: move;
1039
+ }
1040
+ .cp-title { font-size: var(--wox-font-size-base, 12px); font-weight: 600; color: #c0c0c0; letter-spacing: 0.5px; text-transform: uppercase; }
1041
+ .cp-close {
1042
+ background: none; border: none; color: #666; cursor: pointer; font-size: 14px;
1043
+ padding: 2px 6px; border-radius: var(--wox-radius-sm, 3px); transition: all var(--wox-transition-fast);
1044
+ }
1045
+ .cp-close:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
1046
+ .cp-wheel { border-radius: 50%; cursor: crosshair; display: block; }
1047
+ .cp-alpha-wrap { width: ${E}px; position: relative; height: ${L}px; border-radius: 7px; cursor: pointer; }
1048
+ .cp-alpha-canvas { display: block; border-radius: 7px; width: ${E}px; height: ${L}px; }
1049
+ .cp-alpha-knob {
1050
+ position: absolute; top: -3px; width: 20px; height: 20px; border-radius: 50%;
1051
+ border: 2.5px solid #fff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
1052
+ background: transparent; pointer-events: none;
1053
+ }
1054
+ .cp-bottom { width: 100%; display: flex; align-items: center; gap: 10px; }
1055
+ .cp-preview {
1056
+ width: 34px; height: 34px; border-radius: var(--wox-radius-lg, 8px);
1057
+ border: 2px solid rgba(255, 255, 255, 0.12); flex-shrink: 0;
1058
+ background: repeating-conic-gradient(#888 0% 25%, #fff 0% 50%) 0 0 / 8px 8px;
1059
+ }
1060
+ .cp-hexwrap { flex: 1; display: flex; flex-direction: column; gap: 3px; }
1061
+ .cp-hex {
1062
+ background: #27272b; border: 1px solid var(--wox-border-light, #444);
1063
+ border-radius: var(--wox-radius-md, 6px); color: #e8e8e8;
1064
+ font-size: var(--wox-font-size-base, 12px); font-family: var(--wox-font-mono, monospace);
1065
+ padding: 6px 8px; width: 100%; transition: border var(--wox-transition-fast);
1066
+ }
1067
+ .cp-hex:focus { outline: none; border-color: var(--wox-accent, #00e5ff); }
1068
+ .cp-hex-label { font-size: var(--wox-font-size-xs, 9px); color: #555; letter-spacing: 1px; text-align: center; text-transform: uppercase; }
1069
+ `;
1070
+ class ut extends v {
1071
+ constructor() {
1072
+ super();
1073
+ /** @private */
1074
+ n(this, "_initFromAttrs", () => {
1075
+ const t = this.getAttribute("color");
1076
+ if (t && /^#[0-9a-fA-F]{6}$/.test(t)) {
1077
+ const [o, i, s] = this._hexToRgb(t);
1078
+ [this._hue, this._sat, this._val] = this._rgbToHsv(o, i, s);
1079
+ }
1080
+ const e = this.getAttribute("alpha");
1081
+ e !== null && (this._alpha = parseFloat(e));
1082
+ });
1083
+ /** @private */
1084
+ n(this, "_build", () => {
1085
+ this._built || (this._built = !0, this.render(jt, `
1086
+ <div class="cp-popup">
1087
+ <div class="cp-header">
1088
+ <span class="cp-title">Color</span>
1089
+ <button class="cp-close">&#x2715;</button>
1090
+ </div>
1091
+ <canvas class="cp-wheel" width="${A}" height="${A}"></canvas>
1092
+ <div class="cp-alpha-wrap">
1093
+ <canvas class="cp-alpha-canvas" width="${E}" height="${L}"></canvas>
1094
+ <div class="cp-alpha-knob"></div>
1095
+ </div>
1096
+ <div class="cp-bottom">
1097
+ <div class="cp-preview"></div>
1098
+ <div class="cp-hexwrap">
1099
+ <input class="cp-hex" type="text" maxlength="9" spellcheck="false">
1100
+ <span class="cp-hex-label">HEX</span>
1101
+ </div>
1102
+ </div>
1103
+ </div>
1104
+ `), this._wheelCanvas = this.$(".cp-wheel"), this._wCtx = this._wheelCanvas.getContext("2d"), this._alphaCanvas = this.$(".cp-alpha-canvas"), this._aCtx = this._alphaCanvas.getContext("2d"), this._alphaKnob = this.$(".cp-alpha-knob"), this._preview = this.$(".cp-preview"), this._hexInput = this.$(".cp-hex"), this._popup = this.$(".cp-popup"), this.$(".cp-close").addEventListener("click", () => {
1105
+ this.removeAttribute("open"), this.emit("wox-color-close", {});
1106
+ }), this._popup.addEventListener("mousedown", (t) => t.stopPropagation()), this._wheelCanvas.addEventListener("mousedown", (t) => this._wheelDown(t)), this.$(".cp-alpha-wrap").addEventListener("mousedown", (t) => {
1107
+ this._dragging = "alpha", this._doAlpha(t), t.preventDefault();
1108
+ }), document.addEventListener("mousemove", (t) => {
1109
+ this._mouseMove(t), this._dragState && (this._popup.style.left = t.clientX - this._dragState.dx + "px", this._popup.style.top = t.clientY - this._dragState.dy + "px");
1110
+ }), document.addEventListener("mouseup", () => {
1111
+ this._dragging = null, this._dragState = null;
1112
+ }), this.$(".cp-header").addEventListener("mousedown", (t) => {
1113
+ if (t.target.closest(".cp-close")) return;
1114
+ const e = this._popup.getBoundingClientRect();
1115
+ this._dragState = { dx: t.clientX - e.left, dy: t.clientY - e.top }, t.preventDefault();
1116
+ }), this._hexInput.addEventListener("input", (t) => {
1117
+ const e = t.target.value.trim();
1118
+ if (/^#[0-9a-fA-F]{6}$/.test(e)) {
1119
+ const [o, i, s] = this._hexToRgb(e);
1120
+ [this._hue, this._sat, this._val] = this._rgbToHsv(o, i, s), this._redraw(), this._emitColor();
1121
+ }
1122
+ }), this.hasAttribute("open") && (this._popup.classList.add("open"), this._initFromAttrs(), this._redraw()));
1123
+ });
1124
+ /**
1125
+ * Positions and opens the picker near an anchor element.
1126
+ * @param {HTMLElement} anchorEl - Element to anchor near
1127
+ */
1128
+ n(this, "showAt", (t) => {
1129
+ const e = t.getBoundingClientRect(), o = 252, i = 320;
1130
+ let s = e.left + e.width / 2 - o / 2, r = e.top - i - 10;
1131
+ r < 10 && (r = e.bottom + 10), s < 10 && (s = 10), s + o > window.innerWidth - 10 && (s = window.innerWidth - o - 10), r + i > window.innerHeight - 10 && (r = window.innerHeight - i - 10), this._popup.style.left = s + "px", this._popup.style.top = r + "px", this.setAttribute("open", "");
1132
+ });
1133
+ /** @private */
1134
+ n(this, "_redraw", () => {
1135
+ this._drawWheel(), this._drawAlpha(), this._updatePreview();
1136
+ });
1137
+ /** @private */
1138
+ n(this, "_drawWheel", () => {
1139
+ const t = this._wCtx, e = A, o = e / 2, i = e / 2;
1140
+ t.clearRect(0, 0, e, e);
1141
+ const s = t.createConicGradient(-Math.PI / 2, o, i);
1142
+ for (let y = 0; y <= 36; y++) s.addColorStop(y / 36, `hsl(${y * 10},100%,50%)`);
1143
+ t.fillStyle = s, t.beginPath(), t.arc(o, i, T, 0, Math.PI * 2), t.fill(), t.save(), t.globalCompositeOperation = "destination-out", t.beginPath(), t.arc(o, i, z, 0, Math.PI * 2), t.fill(), t.restore(), t.strokeStyle = "rgba(0,0,0,0.25)", t.lineWidth = 1, t.beginPath(), t.arc(o, i, T - 0.5, 0, Math.PI * 2), t.stroke(), t.beginPath(), t.arc(o, i, z + 0.5, 0, Math.PI * 2), t.stroke();
1144
+ const r = this._hue * Math.PI * 2 - Math.PI / 2, a = (T + z) / 2, d = o + Math.cos(r) * a, c = i + Math.sin(r) * a;
1145
+ t.strokeStyle = "#fff", t.lineWidth = 2.5, t.beginPath(), t.arc(d, c, 8, 0, Math.PI * 2), t.stroke(), t.strokeStyle = "rgba(0,0,0,0.4)", t.lineWidth = 1, t.beginPath(), t.arc(d, c, 8, 0, Math.PI * 2), t.stroke();
1146
+ const u = D, h = o - u / 2, x = i - u / 2, g = t.createLinearGradient(h, 0, h + u, 0);
1147
+ g.addColorStop(0, "#fff"), g.addColorStop(1, `hsl(${this._hue * 360},100%,50%)`), t.fillStyle = g, t.fillRect(h, x, u, u);
1148
+ const b = t.createLinearGradient(0, x, 0, x + u);
1149
+ b.addColorStop(0, "rgba(0,0,0,0)"), b.addColorStop(1, "rgba(0,0,0,1)"), t.fillStyle = b, t.fillRect(h, x, u, u);
1150
+ const f = h + this._sat * u, w = x + (1 - this._val) * u;
1151
+ t.strokeStyle = "#fff", t.lineWidth = 2.5, t.beginPath(), t.arc(f, w, 7, 0, Math.PI * 2), t.stroke(), t.strokeStyle = "rgba(0,0,0,0.4)", t.lineWidth = 1, t.beginPath(), t.arc(f, w, 7, 0, Math.PI * 2), t.stroke();
1152
+ });
1153
+ /** @private */
1154
+ n(this, "_drawAlpha", () => {
1155
+ const t = this._aCtx;
1156
+ t.clearRect(0, 0, E, L);
1157
+ for (let r = 0; r < E; r += 8) for (let a = 0; a < L; a += 8)
1158
+ t.fillStyle = (r / 8 + a / 8) % 2 === 0 ? "#aaa" : "#fff", t.fillRect(r, a, 8, 8);
1159
+ const [e, o, i] = this._hsvToRgb(this._hue, this._sat, this._val), s = t.createLinearGradient(0, 0, E, 0);
1160
+ s.addColorStop(0, `rgba(${e},${o},${i},0)`), s.addColorStop(1, `rgba(${e},${o},${i},1)`), t.fillStyle = s, t.fillRect(0, 0, E, L), this._alphaKnob.style.left = this._alpha * E - 7 + "px";
1161
+ });
1162
+ /** @private */
1163
+ n(this, "_updatePreview", () => {
1164
+ const [t, e, o] = this._hsvToRgb(this._hue, this._sat, this._val);
1165
+ this._preview.style.background = `rgba(${t},${e},${o},${this._alpha})`, this._hexInput.value = this._rgbToHex(t, e, o);
1166
+ });
1167
+ /** @private */
1168
+ n(this, "_wheelDown", (t) => {
1169
+ const e = this._wheelCanvas.getBoundingClientRect(), o = t.clientX - e.left, i = t.clientY - e.top, s = A / 2, r = A / 2, a = Math.hypot(o - s, i - r);
1170
+ a >= z - 2 && a <= T + 2 ? this._dragging = "ring" : a < z && (this._dragging = "sq"), this._handleWheel(o, i);
1171
+ });
1172
+ /** @private */
1173
+ n(this, "_mouseMove", (t) => {
1174
+ if (this._dragging)
1175
+ if (this._dragging === "ring" || this._dragging === "sq") {
1176
+ const e = this._wheelCanvas.getBoundingClientRect();
1177
+ this._handleWheel(t.clientX - e.left, t.clientY - e.top);
1178
+ } else this._dragging === "alpha" && this._doAlpha(t);
1179
+ });
1180
+ /** @private */
1181
+ n(this, "_handleWheel", (t, e) => {
1182
+ const o = A / 2, i = A / 2;
1183
+ if (this._dragging === "ring") {
1184
+ const s = Math.atan2(e - i, t - o) + Math.PI / 2;
1185
+ this._hue = (s / (Math.PI * 2) % 1 + 1) % 1;
1186
+ } else if (this._dragging === "sq") {
1187
+ const s = o - D / 2, r = i - D / 2;
1188
+ this._sat = Math.max(0, Math.min(1, (t - s) / D)), this._val = Math.max(0, Math.min(1, 1 - (e - r) / D));
1189
+ }
1190
+ this._redraw(), this._emitColor();
1191
+ });
1192
+ /** @private */
1193
+ n(this, "_doAlpha", (t) => {
1194
+ const e = this.$(".cp-alpha-wrap").getBoundingClientRect();
1195
+ this._alpha = Math.max(0, Math.min(1, (t.clientX - e.left) / E)), this._drawAlpha(), this._updatePreview(), this._emitColor();
1196
+ });
1197
+ /** @private */
1198
+ n(this, "_emitColor", () => {
1199
+ const [t, e, o] = this._hsvToRgb(this._hue, this._sat, this._val);
1200
+ this.emit("wox-color-change", { color: [t / 255, e / 255, o / 255, this._alpha] });
1201
+ });
1202
+ // ── Color math ──
1203
+ /** @private */
1204
+ n(this, "_hsvToRgb", (t, e, o) => {
1205
+ const i = (s) => {
1206
+ const r = (s + t * 6) % 6;
1207
+ return o - o * e * Math.max(0, Math.min(r, 4 - r, 1));
1208
+ };
1209
+ return [Math.round(i(5) * 255), Math.round(i(3) * 255), Math.round(i(1) * 255)];
1210
+ });
1211
+ /** @private */
1212
+ n(this, "_rgbToHsv", (t, e, o) => {
1213
+ t /= 255, e /= 255, o /= 255;
1214
+ const i = Math.max(t, e, o), s = i - Math.min(t, e, o);
1215
+ let r = 0;
1216
+ return s && (i === t ? r = ((e - o) / s % 6 + 6) % 6 : i === e ? r = (o - t) / s + 2 : r = (t - e) / s + 4), [r / 6, i ? s / i : 0, i];
1217
+ });
1218
+ /** @private */
1219
+ n(this, "_hexToRgb", (t) => {
1220
+ const e = parseInt(t.slice(1), 16);
1221
+ return [e >> 16 & 255, e >> 8 & 255, e & 255];
1222
+ });
1223
+ /** @private */
1224
+ n(this, "_rgbToHex", (t, e, o) => "#" + [t, e, o].map((i) => i.toString(16).padStart(2, "0")).join(""));
1225
+ this._hue = 0, this._sat = 0.8, this._val = 0.9, this._alpha = 1, this._dragging = null, this._dragState = null, this._built = !1;
1226
+ }
1227
+ connectedCallback() {
1228
+ this._build();
1229
+ }
1230
+ attributeChangedCallback(t) {
1231
+ if (this.isConnected)
1232
+ if (t === "open") {
1233
+ const e = this.$(".cp-popup");
1234
+ e && (this.hasAttribute("open") ? (e.classList.add("open"), this._initFromAttrs(), this._redraw()) : e.classList.remove("open"));
1235
+ } else (t === "color" || t === "alpha") && (this._initFromAttrs(), this.hasAttribute("open") && this._redraw());
1236
+ }
1237
+ }
1238
+ n(ut, "observedAttributes", ["color", "alpha", "open"]);
1239
+ const H = `
1240
+ :host { display: block; }
1241
+ .item {
1242
+ color: var(--wox-text-primary, #eee); padding: 8px 12px; display: flex; align-items: center;
1243
+ gap: 8px; cursor: pointer; font-size: 11.5px; font-family: var(--wox-font, sans-serif);
1244
+ transition: all 0.2s; border-radius: var(--wox-radius-sm, 3px); user-select: none;
1245
+ }
1246
+ .item:hover { background-color: rgba(0, 229, 255, 0.1); color: var(--wox-accent, #00e5ff); }
1247
+ .item.disabled { opacity: 0.4; pointer-events: none; }
1248
+ .label { flex: 1; }
1249
+ .shortcut { font-size: var(--wox-font-size-sm, 10px); color: var(--wox-text-secondary, #999); margin-left: auto; }
1250
+ .item:hover .shortcut { color: rgba(0, 229, 255, 0.6); }
1251
+ .icon { font-size: 14px; width: 18px; text-align: center; }
1252
+ .arrow { font-size: 10px; color: var(--wox-text-secondary, #999); margin-left: 4px; }
1253
+ .separator { height: 1px; background: var(--wox-border, #333); margin: 4px 0; }
1254
+ .header {
1255
+ padding: 8px 12px; font-size: var(--wox-font-size-sm, 10px); color: var(--wox-text-secondary, #999);
1256
+ text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600; cursor: default;
1257
+ }
1258
+ .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; display: inline-block; line-height: 1; text-transform: none; letter-spacing: normal; word-wrap: normal; white-space: nowrap; direction: ltr; -webkit-font-smoothing: antialiased; }
1259
+ `;
1260
+ class gt extends v {
1261
+ constructor() {
1262
+ super(...arguments);
1263
+ /** @private */
1264
+ n(this, "_render", () => {
1265
+ const t = this.getAttribute("type") || "item", e = this.getAttribute("label") || "", o = this.getAttribute("shortcut") || "", i = this.getAttribute("icon") || "", s = this.hasAttribute("disabled"), r = this.hasAttribute("submenu");
1266
+ if (t === "separator") {
1267
+ this.render(H, '<div class="separator"></div>');
1268
+ return;
1269
+ }
1270
+ if (t === "header") {
1271
+ this.render(H, `<div class="header">${e}</div>`);
1272
+ return;
1273
+ }
1274
+ this.render(H, `
1275
+ <div class="item ${s ? "disabled" : ""}">
1276
+ ${i ? `<span class="icon material-icons">${i}</span>` : ""}
1277
+ <span class="label">${e}</span>
1278
+ ${o ? `<span class="shortcut">${o}</span>` : ""}
1279
+ ${r ? '<span class="arrow">&#9654;</span>' : ""}
1280
+ </div>
1281
+ `), s || this.$(".item").addEventListener("click", () => {
1282
+ this.emit("wox-select", { label: e });
1283
+ });
1284
+ });
1285
+ }
1286
+ connectedCallback() {
1287
+ this._render();
1288
+ }
1289
+ attributeChangedCallback() {
1290
+ this.isConnected && this._render();
1291
+ }
1292
+ }
1293
+ n(gt, "observedAttributes", ["label", "shortcut", "icon", "disabled", "type", "submenu"]);
1294
+ const Gt = `
1295
+ :host { display: inline-block; position: relative; }
1296
+ .trigger { color: var(--wox-text-primary, #eee); padding: 3px 8px; border-radius: var(--wox-radius-sm, 3px); cursor: pointer; font-size: var(--wox-font-size-base, 12px); display: block; user-select: none; }
1297
+ .trigger:hover { background: var(--wox-bg-hover, #2a2a2e); color: var(--wox-text-hi, #fff); }
1298
+ .dropdown {
1299
+ display: none; position: fixed; z-index: var(--wox-z-dropdown, 1000);
1300
+ background: var(--wox-bg-panel, #17171a); min-width: 160px;
1301
+ box-shadow: var(--wox-shadow-lg, 0 12px 32px rgba(0, 0, 0, 0.6));
1302
+ border: 1px solid var(--wox-border, #333); border-radius: var(--wox-radius-lg, 8px);
1303
+ overflow: hidden; padding: 4px;
1304
+ }
1305
+ .dropdown.open { display: block; }
1306
+ /* Invisible bridge to keep menu open while moving mouse */
1307
+ .dropdown::before { content: ''; position: absolute; top: -10px; left: 0; right: 0; height: 10px; }
1308
+ `;
1309
+ class bt extends v {
1310
+ constructor() {
1311
+ super(...arguments);
1312
+ /** @private */
1313
+ n(this, "_render", () => {
1314
+ const t = this.getAttribute("label") || "", e = this.hasAttribute("open"), o = this.getAttribute("trigger") || "click";
1315
+ this.render(Gt, `
1316
+ <span class="trigger">${t}</span>
1317
+ <div class="dropdown ${e ? "open" : ""}">
1318
+ <slot></slot>
1319
+ </div>
1320
+ `);
1321
+ const i = this.$(".trigger");
1322
+ this.$(".dropdown"), o === "click" ? i.addEventListener("click", (s) => {
1323
+ s.stopPropagation(), this._toggle();
1324
+ }) : o === "hover" && (this.addEventListener("mouseenter", () => this._open()), this.addEventListener("mouseleave", () => this._close())), this._outsideClick = (s) => {
1325
+ !this.contains(s.target) && this.hasAttribute("open") && this._close();
1326
+ }, document.addEventListener("mousedown", this._outsideClick), this.addEventListener("wox-select", () => this._close());
1327
+ });
1328
+ /** @private */
1329
+ n(this, "_toggle", () => {
1330
+ this.hasAttribute("open") ? this._close() : this._open();
1331
+ });
1332
+ /** @private */
1333
+ n(this, "_open", () => {
1334
+ this.setAttribute("open", ""), this._positionDropdown();
1335
+ });
1336
+ /** @private — Position the fixed dropdown relative to the trigger, flipping if needed. */
1337
+ n(this, "_positionDropdown", () => {
1338
+ requestAnimationFrame(() => {
1339
+ const t = this.$(".trigger"), e = this.$(".dropdown");
1340
+ if (!t || !e) return;
1341
+ const o = t.getBoundingClientRect(), i = window.innerWidth, s = window.innerHeight, r = e.getBoundingClientRect();
1342
+ o.left + r.width > i ? e.style.left = `${o.right - r.width}px` : e.style.left = `${o.left}px`;
1343
+ const a = s - o.bottom, d = o.top;
1344
+ a >= r.height || a >= d ? (e.style.top = `${o.bottom}px`, e.style.bottom = "") : (e.style.top = "", e.style.bottom = `${s - o.top}px`);
1345
+ });
1346
+ });
1347
+ /** @private */
1348
+ n(this, "_close", () => {
1349
+ this.removeAttribute("open");
1350
+ });
1351
+ }
1352
+ connectedCallback() {
1353
+ this._render();
1354
+ }
1355
+ attributeChangedCallback(t) {
1356
+ if (this.isConnected) {
1357
+ if (t === "open") {
1358
+ const e = this.$(".dropdown");
1359
+ if (!e) return;
1360
+ this.hasAttribute("open") ? (e.classList.add("open"), this._positionDropdown(), this.emit("wox-open", {})) : (e.classList.remove("open"), this.emit("wox-close", {}));
1361
+ return;
1362
+ }
1363
+ this._render();
1364
+ }
1365
+ }
1366
+ disconnectedCallback() {
1367
+ this._outsideClick && document.removeEventListener("mousedown", this._outsideClick);
1368
+ }
1369
+ }
1370
+ n(bt, "observedAttributes", ["label", "open", "trigger"]);
1371
+ const Wt = `
1372
+ :host { display: block; }
1373
+ .layer {
1374
+ display: flex; align-items: center; gap: 6px; padding: 6px 10px 6px 12px;
1375
+ margin: 4px 8px 0 8px; border-radius: var(--wox-radius-md, 6px);
1376
+ background: rgba(255, 255, 255, 0.04); border: 1px solid transparent;
1377
+ cursor: pointer; user-select: none; font-size: var(--wox-font-size-md, 11px);
1378
+ font-weight: 600; color: var(--wox-text-secondary, #999); text-transform: uppercase;
1379
+ letter-spacing: 0.5px; transition: background 0.1s, border-color 0.1s;
1380
+ }
1381
+ :host([depth="1"]) .layer { margin-left: 24px; }
1382
+ :host([depth="2"]) .layer { margin-left: 40px; }
1383
+ .layer:hover { background: rgba(255, 255, 255, 0.07); }
1384
+ .layer.selected { border-color: var(--wox-accent, #00e5ff); color: var(--wox-accent, #00e5ff); background: rgba(0, 229, 255, 0.06); }
1385
+ .name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--wox-font-size-lg, 13px); color: #ccc; font-weight: 400; text-transform: none; letter-spacing: 0; }
1386
+ .layer.selected .name { color: var(--wox-text-hi, #fff); }
1387
+ .name-input {
1388
+ flex: 1; background: rgba(0, 0, 0, 0.4); border: 1px solid #4A8CFF;
1389
+ color: #fff; font-size: var(--wox-font-size-lg, 13px); font-family: var(--wox-font, sans-serif);
1390
+ padding: 2px 4px; border-radius: var(--wox-radius-sm, 3px); outline: none; width: 100%;
1391
+ }
1392
+ .type-icon { font-size: 14px; opacity: 0.6; width: 18px; text-align: center; }
1393
+ .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; display: inline-block; line-height: 1; text-transform: none; letter-spacing: normal; word-wrap: normal; white-space: nowrap; direction: ltr; -webkit-font-smoothing: antialiased; }
1394
+ .toggle { display: flex; align-items: center; opacity: 0.4; cursor: pointer; transition: opacity 0.15s, color 0.15s; padding: 0 2px; font-size: 16px; }
1395
+ .toggle:hover, .toggle.on { opacity: 1; color: var(--wox-accent, #00e5ff); }
1396
+ `, Xt = {
1397
+ rectangle: "crop_square",
1398
+ ellipse: "radio_button_unchecked",
1399
+ path: "timeline",
1400
+ image: "image",
1401
+ text: "text_fields",
1402
+ group: "folder",
1403
+ layer: "layers"
1404
+ };
1405
+ class ft extends v {
1406
+ constructor() {
1407
+ super(...arguments);
1408
+ /** @private */
1409
+ n(this, "_render", () => {
1410
+ const t = this.getAttribute("name") || "Layer", e = this.getAttribute("type") || "layer", o = this.hasAttribute("visible"), i = this.hasAttribute("locked"), s = this.hasAttribute("selected"), r = Xt[e] || "layers";
1411
+ this.render(Wt, `
1412
+ <div class="layer ${s ? "selected" : ""}">
1413
+ <span class="type-icon material-icons">${r}</span>
1414
+ <span class="name">${t}</span>
1415
+ <span class="toggle eye ${o ? "on" : ""} material-icons">${o ? "visibility" : "visibility_off"}</span>
1416
+ <span class="toggle lock ${i ? "on" : ""} material-icons">${i ? "lock" : "lock_open"}</span>
1417
+ </div>
1418
+ `), this.$(".layer").addEventListener("click", (a) => {
1419
+ a.target.closest(".toggle") || this.emit("wox-select", { name: t });
1420
+ }), this.$(".name").addEventListener("dblclick", () => this._startEditing()), this.$(".eye").addEventListener("click", (a) => {
1421
+ a.stopPropagation();
1422
+ const d = !o;
1423
+ d ? this.setAttribute("visible", "") : this.removeAttribute("visible"), this.emit("wox-visibility", { visible: d });
1424
+ }), this.$(".lock").addEventListener("click", (a) => {
1425
+ a.stopPropagation();
1426
+ const d = !i;
1427
+ d ? this.setAttribute("locked", "") : this.removeAttribute("locked"), this.emit("wox-lock", { locked: d });
1428
+ });
1429
+ });
1430
+ /** @private */
1431
+ n(this, "_startEditing", () => {
1432
+ this._editing = !0;
1433
+ const t = this.$(".name"), e = this.getAttribute("name") || "Layer", o = document.createElement("input");
1434
+ o.className = "name-input", o.value = e, t.replaceWith(o), o.focus(), o.select();
1435
+ const i = () => {
1436
+ this._editing = !1;
1437
+ const s = o.value.trim() || e;
1438
+ this.setAttribute("name", s), this._render();
1439
+ };
1440
+ o.addEventListener("blur", i), o.addEventListener("keydown", (s) => {
1441
+ s.key === "Enter" && o.blur(), s.key === "Escape" && (o.value = e, o.blur());
1442
+ });
1443
+ });
1444
+ }
1445
+ connectedCallback() {
1446
+ this._editing = !1, this._render();
1447
+ }
1448
+ attributeChangedCallback() {
1449
+ this.isConnected && !this._editing && this._render();
1450
+ }
1451
+ }
1452
+ n(ft, "observedAttributes", ["name", "type", "visible", "locked", "selected", "depth"]);
1453
+ const qt = `
1454
+ :host { display: block; border-bottom: 1px solid var(--wox-border-section, #2e2e2e); }
1455
+ .header {
1456
+ background: var(--wox-bg-section-header, #22222a); padding: 8px 16px;
1457
+ display: flex; align-items: center; gap: 10px;
1458
+ border-bottom: 1px solid var(--wox-border-section, #2e2e2e);
1459
+ font-size: var(--wox-font-size-md, 11px); color: var(--wox-text-primary, #eee);
1460
+ font-weight: 500; text-transform: uppercase; letter-spacing: 0.5px;
1461
+ cursor: pointer; user-select: none;
1462
+ }
1463
+ .diamond {
1464
+ display: flex; align-items: center; color: var(--wox-accent, #00e5ff); font-size: 13px;
1465
+ }
1466
+ .diamond::before {
1467
+ content: ''; display: block; width: 8px; height: 8px;
1468
+ background: var(--wox-accent, #00e5ff); transform: rotate(45deg); flex-shrink: 0;
1469
+ box-shadow: 0 0 10px rgba(0, 229, 255, 0.5);
1470
+ }
1471
+ .title { font-size: var(--wox-font-size-md, 11px); font-weight: 600; text-transform: uppercase; letter-spacing: 0.8px; margin-left: 8px; }
1472
+ .chevron { margin-left: auto; font-size: 16px; transition: transform 0.2s; color: var(--wox-text-secondary, #999); }
1473
+ .chevron.collapsed { transform: rotate(-90deg); }
1474
+ .actions { margin-left: auto; display: flex; gap: 4px; align-items: center; }
1475
+ .body {
1476
+ padding: var(--wox-space-xl, 16px); overflow: hidden;
1477
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.02) 0%, rgba(255, 255, 255, 0) 100%);
1478
+ box-shadow: var(--wox-shadow-section);
1479
+ }
1480
+ .body.collapsed { display: none; }
1481
+ .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; display: inline-block; line-height: 1; text-transform: none; letter-spacing: normal; word-wrap: normal; white-space: nowrap; direction: ltr; -webkit-font-smoothing: antialiased; }
1482
+ `;
1483
+ class vt extends v {
1484
+ constructor() {
1485
+ super(...arguments);
1486
+ /** @private */
1487
+ n(this, "_render", () => {
1488
+ const t = this.getAttribute("title") || "", e = this.hasAttribute("collapsed");
1489
+ this.render(qt, `
1490
+ <div class="header">
1491
+ <div class="diamond"></div>
1492
+ <span class="title">${t}</span>
1493
+ <div class="actions"><slot name="header-actions"></slot></div>
1494
+ <span class="chevron material-icons ${e ? "collapsed" : ""}">expand_more</span>
1495
+ </div>
1496
+ <div class="body ${e ? "collapsed" : ""}">
1497
+ <slot></slot>
1498
+ </div>
1499
+ `), this.$(".header").addEventListener("click", () => {
1500
+ const o = !this.hasAttribute("collapsed");
1501
+ o ? this.setAttribute("collapsed", "") : this.removeAttribute("collapsed"), this.emit("wox-toggle", { collapsed: o });
1502
+ });
1503
+ });
1504
+ }
1505
+ connectedCallback() {
1506
+ this._render();
1507
+ }
1508
+ attributeChangedCallback() {
1509
+ this.isConnected && this._render();
1510
+ }
1511
+ }
1512
+ n(vt, "observedAttributes", ["title", "collapsed", "icon"]);
1513
+ const Jt = `
1514
+ :host { display: none; flex: 1; overflow-y: auto; overflow-x: hidden; flex-direction: column; }
1515
+ :host([active]) { display: flex; }
1516
+ `;
1517
+ class wt extends v {
1518
+ connectedCallback() {
1519
+ this.render(Jt, "<slot></slot>");
1520
+ }
1521
+ }
1522
+ n(wt, "observedAttributes", ["name", "label", "icon", "active"]);
1523
+ const Kt = `
1524
+ :host { display: flex; flex-direction: column; flex: 1; overflow: hidden; }
1525
+ .tab-headers {
1526
+ background: var(--wox-bg-section-header, #22222a); display: flex;
1527
+ padding: 0 4px; border-bottom: 1px solid var(--wox-border-section, #2e2e2e); flex-shrink: 0;
1528
+ }
1529
+ .tab-btn {
1530
+ flex: 1; padding: 8px 4px; background: transparent; border: none;
1531
+ border-bottom: 2px solid transparent; color: var(--wox-text-secondary, #999);
1532
+ cursor: pointer; font-size: var(--wox-font-size-base, 12px); font-family: var(--wox-font, sans-serif);
1533
+ transition: all var(--wox-transition-fast, 0.12s); margin-bottom: -1px;
1534
+ }
1535
+ .tab-btn.active { color: var(--wox-text-hi, #fff); border-bottom-color: var(--wox-accent, #00e5ff); }
1536
+ .tab-btn:hover { color: var(--wox-text-primary, #eee); }
1537
+ .body { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
1538
+
1539
+ /* Vertical left placement */
1540
+ :host([placement="left"]) { flex-direction: row; }
1541
+ :host([placement="left"]) .tab-headers {
1542
+ flex-direction: column; padding: 4px 0; border-bottom: none;
1543
+ border-right: 1px solid var(--wox-border-section, #2e2e2e);
1544
+ }
1545
+ :host([placement="left"]) .tab-btn {
1546
+ flex: none; border-bottom: none; margin-bottom: 0;
1547
+ border-right: 2px solid transparent; margin-right: -1px;
1548
+ writing-mode: vertical-rl; transform: rotate(180deg); padding: 8px 6px;
1549
+ }
1550
+ :host([placement="left"]) .tab-btn.active { border-right-color: var(--wox-accent, #00e5ff); }
1551
+
1552
+ /* Vertical right placement */
1553
+ :host([placement="right"]) { flex-direction: row-reverse; }
1554
+ :host([placement="right"]) .tab-headers {
1555
+ flex-direction: column; padding: 4px 0; border-bottom: none;
1556
+ border-left: 1px solid var(--wox-border-section, #2e2e2e);
1557
+ }
1558
+ :host([placement="right"]) .tab-btn {
1559
+ flex: none; border-bottom: none; margin-bottom: 0;
1560
+ border-left: 2px solid transparent; margin-left: -1px;
1561
+ writing-mode: vertical-rl; padding: 8px 6px;
1562
+ }
1563
+ :host([placement="right"]) .tab-btn.active { border-left-color: var(--wox-accent, #00e5ff); }
1564
+ `;
1565
+ class mt extends v {
1566
+ constructor() {
1567
+ super(...arguments);
1568
+ /** @private */
1569
+ n(this, "_render", () => {
1570
+ this.render(Kt, `
1571
+ <div class="tab-headers"></div>
1572
+ <div class="body"><slot></slot></div>
1573
+ `), this.$("slot").addEventListener("slotchange", () => this._buildHeaders()), this._buildHeaders();
1574
+ });
1575
+ /** @private */
1576
+ n(this, "_buildHeaders", () => {
1577
+ var i;
1578
+ const t = this.$(".tab-headers");
1579
+ t.innerHTML = "";
1580
+ const e = this._getTabs(), o = this.getAttribute("active") || ((i = e[0]) == null ? void 0 : i.getAttribute("name")) || "";
1581
+ e.forEach((s) => {
1582
+ const r = s.getAttribute("name") || "", a = s.getAttribute("label") || r, d = document.createElement("button");
1583
+ d.className = "tab-btn" + (r === o ? " active" : ""), d.textContent = a, d.addEventListener("click", () => {
1584
+ this.setAttribute("active", r), this.emit("wox-tab-change", { name: r });
1585
+ }), t.appendChild(d);
1586
+ }), this._updateActive();
1587
+ });
1588
+ /** @private */
1589
+ n(this, "_updateActive", () => {
1590
+ var o;
1591
+ const t = this._getTabs(), e = this.getAttribute("active") || ((o = t[0]) == null ? void 0 : o.getAttribute("name")) || "";
1592
+ t.forEach((i) => {
1593
+ (i.getAttribute("name") || "") === e ? i.setAttribute("active", "") : i.removeAttribute("active");
1594
+ }), this.$$(".tab-btn").forEach((i, s) => {
1595
+ var a;
1596
+ const r = ((a = t[s]) == null ? void 0 : a.getAttribute("name")) || "";
1597
+ i.classList.toggle("active", r === e);
1598
+ });
1599
+ });
1600
+ /** @private */
1601
+ n(this, "_getTabs", () => [...this.querySelectorAll(":scope > wox-tab")]);
1602
+ }
1603
+ connectedCallback() {
1604
+ this._render();
1605
+ }
1606
+ attributeChangedCallback() {
1607
+ this.isConnected && this._updateActive();
1608
+ }
1609
+ }
1610
+ n(mt, "observedAttributes", ["active", "placement"]);
1611
+ const Vt = `
1612
+ :host { display: flex; flex-direction: column; align-items: center; padding: 4px 0; border-bottom: 1px solid var(--wox-border, #333); width: 100%; }
1613
+ :host(:last-of-type) { border-bottom: none; }
1614
+ .label { font-size: var(--wox-font-size-xs, 9px); color: var(--wox-text-secondary, #999); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 2px; }
1615
+ `;
1616
+ class _t extends v {
1617
+ constructor() {
1618
+ super(...arguments);
1619
+ /** @private */
1620
+ n(this, "_render", () => {
1621
+ const t = this.getAttribute("label") || "";
1622
+ this.render(Vt, `
1623
+ <slot></slot>
1624
+ ${t ? `<span class="label">${t}</span>` : ""}
1625
+ `);
1626
+ });
1627
+ }
1628
+ connectedCallback() {
1629
+ this._render();
1630
+ }
1631
+ attributeChangedCallback() {
1632
+ this.isConnected && this._render();
1633
+ }
1634
+ }
1635
+ n(_t, "observedAttributes", ["label"]);
1636
+ const Ut = `
1637
+ :host {
1638
+ display: flex; flex-direction: column; align-items: center;
1639
+ background: var(--wox-bg-toolbar, #1e1e22);
1640
+ border-right: 1px solid var(--wox-border, #333);
1641
+ padding: 6px 0; flex-shrink: 0;
1642
+ width: var(--width, 44px);
1643
+ }
1644
+ :host([position="right"]) { border-right: none; border-left: 1px solid var(--wox-border, #333); }
1645
+ `;
1646
+ class yt extends v {
1647
+ constructor() {
1648
+ super(...arguments);
1649
+ /** @private */
1650
+ n(this, "_render", () => {
1651
+ const t = this.getAttribute("width") || "44px";
1652
+ this.render(
1653
+ `${Ut} :host { --width: ${t}; }`,
1654
+ "<slot></slot>"
1655
+ );
1656
+ });
1657
+ }
1658
+ connectedCallback() {
1659
+ this._render();
1660
+ }
1661
+ attributeChangedCallback() {
1662
+ this.isConnected && this._render();
1663
+ }
1664
+ }
1665
+ n(yt, "observedAttributes", ["width", "position"]);
1666
+ const Zt = `
1667
+ :host {
1668
+ display: flex; flex-direction: column; flex-shrink: 0; position: relative;
1669
+ width: var(--width, 280px); height: 100%;
1670
+ background: var(--wox-bg-panel, #17171a);
1671
+ border-left: 1px solid var(--wox-border-light, #444);
1672
+ z-index: var(--wox-z-base, 1);
1673
+ }
1674
+ :host([position="left"]) { border-left: none; border-right: 1px solid var(--wox-border-light, #444); }
1675
+ .resizer {
1676
+ position: absolute; top: 0; bottom: 0; width: 5px; cursor: col-resize;
1677
+ z-index: 2; transition: background 0.2s;
1678
+ }
1679
+ :host([position="left"]) .resizer { right: -2px; }
1680
+ :host(:not([position="left"])) .resizer { left: -2px; }
1681
+ .resizer:hover { background: rgba(0, 229, 255, 0.4); }
1682
+ .content { flex: 1; overflow-y: auto; overflow-x: hidden; display: flex; flex-direction: column; }
1683
+ `;
1684
+ class kt extends v {
1685
+ constructor() {
1686
+ super(...arguments);
1687
+ /** @private */
1688
+ n(this, "_render", () => {
1689
+ const t = this.getAttribute("width") || "280px", e = this.hasAttribute("resizable");
1690
+ if (this.render(
1691
+ `${Zt} :host { --width: ${t}; }`,
1692
+ `${e ? '<div class="resizer"></div>' : ""}<div class="content"><slot></slot></div>`
1693
+ ), e) {
1694
+ const o = this.$(".resizer");
1695
+ if (!o) return;
1696
+ let i = 0, s = 0;
1697
+ const r = this.getAttribute("position") === "left", a = (c) => {
1698
+ const u = r ? c.clientX - i : i - c.clientX, h = Math.max(180, Math.min(600, s + u));
1699
+ this.style.width = h + "px";
1700
+ }, d = () => {
1701
+ document.removeEventListener("mousemove", a), document.removeEventListener("mouseup", d);
1702
+ };
1703
+ o.addEventListener("mousedown", (c) => {
1704
+ i = c.clientX, s = this.getBoundingClientRect().width, document.addEventListener("mousemove", a), document.addEventListener("mouseup", d), c.preventDefault();
1705
+ });
1706
+ }
1707
+ });
1708
+ }
1709
+ connectedCallback() {
1710
+ this._render();
1711
+ }
1712
+ attributeChangedCallback() {
1713
+ this.isConnected && this._render();
1714
+ }
1715
+ }
1716
+ n(kt, "observedAttributes", ["width", "position", "resizable"]);
1717
+ const Qt = `
1718
+ :host {
1719
+ display: flex; align-items: center; flex-shrink: 0;
1720
+ height: var(--height, 32px); background: var(--wox-bg-toolbar, #1e1e22);
1721
+ border-bottom: 1px solid var(--wox-border, #333); padding: 0 12px; gap: 2px;
1722
+ }
1723
+ ::slotted(.logo) { display: flex; align-items: center; gap: 6px; margin-right: 18px; }
1724
+ `;
1725
+ class $t extends v {
1726
+ constructor() {
1727
+ super(...arguments);
1728
+ /** @private */
1729
+ n(this, "_render", () => {
1730
+ const t = this.getAttribute("height") || "32px";
1731
+ this.render(
1732
+ `${Qt} :host { --height: ${t}; }`,
1733
+ "<slot></slot>"
1734
+ ), this.addEventListener("keydown", (e) => {
1735
+ if (e.key !== "ArrowLeft" && e.key !== "ArrowRight") return;
1736
+ const o = [...this.querySelectorAll("wox-menu")], i = o.findIndex((r) => r.hasAttribute("open"));
1737
+ if (i < 0) return;
1738
+ o[i].removeAttribute("open");
1739
+ const s = e.key === "ArrowRight" ? (i + 1) % o.length : (i - 1 + o.length) % o.length;
1740
+ o[s].setAttribute("open", "");
1741
+ });
1742
+ });
1743
+ }
1744
+ connectedCallback() {
1745
+ this._render();
1746
+ }
1747
+ attributeChangedCallback() {
1748
+ this.isConnected && this._render();
1749
+ }
1750
+ }
1751
+ n($t, "observedAttributes", ["height"]);
1752
+ const te = `
1753
+ :host {
1754
+ display: flex; align-items: center; flex-shrink: 0;
1755
+ height: var(--height, 24px); background: var(--wox-accent, #00e5ff);
1756
+ border-top: 1px solid var(--wox-border, #333); padding: 0 12px;
1757
+ }
1758
+ .left, .center, .right { display: flex; align-items: center; gap: 8px; }
1759
+ .left { flex: 1; justify-content: flex-start; }
1760
+ .center { flex: 1; justify-content: center; }
1761
+ .right { flex: 1; justify-content: flex-end; }
1762
+ ::slotted(*) { font-size: var(--wox-font-size-md, 11px); color: rgba(255, 255, 255, 0.9); }
1763
+ `;
1764
+ class Et extends v {
1765
+ constructor() {
1766
+ super(...arguments);
1767
+ /** @private */
1768
+ n(this, "_render", () => {
1769
+ const t = this.getAttribute("height") || "24px";
1770
+ this.render(
1771
+ `${te} :host { --height: ${t}; }`,
1772
+ `<div class="left"><slot name="left"></slot></div>
1773
+ <div class="center"><slot name="center"></slot></div>
1774
+ <div class="right"><slot name="right"></slot></div>`
1775
+ );
1776
+ });
1777
+ }
1778
+ connectedCallback() {
1779
+ this._render();
1780
+ }
1781
+ attributeChangedCallback() {
1782
+ this.isConnected && this._render();
1783
+ }
1784
+ }
1785
+ n(Et, "observedAttributes", ["height"]);
1786
+ const ee = `
1787
+ :host { display: none; }
1788
+ :host([open]) { display: block; }
1789
+ .overlay {
1790
+ position: fixed; top: 0; left: 0; right: 0; bottom: 0;
1791
+ background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(2px);
1792
+ z-index: var(--wox-z-modal, 20000); display: flex;
1793
+ align-items: center; justify-content: center;
1794
+ opacity: 1; transition: opacity 0.2s ease;
1795
+ }
1796
+ .box {
1797
+ background: #1e1e24; border: 1px solid var(--wox-border, #333);
1798
+ border-radius: var(--wox-radius-2xl, 12px); padding: 24px;
1799
+ min-width: 300px; max-width: var(--width, 400px);
1800
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
1801
+ transform: translateY(0) scale(1);
1802
+ transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
1803
+ }
1804
+ .header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
1805
+ .title { font-size: var(--wox-font-size-2xl, 16px); color: var(--wox-text-hi, #fff); font-weight: 500; }
1806
+ .close-btn {
1807
+ background: none; border: none; color: #666; font-size: 18px; cursor: pointer;
1808
+ padding: 4px 8px; border-radius: var(--wox-radius-sm, 3px); transition: all 0.12s;
1809
+ }
1810
+ .close-btn:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
1811
+ .body { color: #bbb; font-size: var(--wox-font-size-xl, 14px); margin-bottom: 24px; line-height: 1.5; }
1812
+ .footer { display: flex; justify-content: flex-end; gap: 12px; }
1813
+ .btn {
1814
+ padding: 8px 16px; border-radius: var(--wox-radius-md, 6px);
1815
+ font-family: var(--wox-font, sans-serif); font-size: var(--wox-font-size-lg, 13px);
1816
+ font-weight: 500; cursor: pointer; border: none; transition: background 0.15s;
1817
+ }
1818
+ .btn-secondary { background: var(--wox-border, #333); color: var(--wox-text-primary, #eee); }
1819
+ .btn-secondary:hover { background: var(--wox-border-light, #444); }
1820
+ .btn-primary { background: var(--wox-accent, #00e5ff); color: var(--wox-text-hi, #fff); }
1821
+ .btn-primary:hover { background: #3bb3d9; }
1822
+ `;
1823
+ class Ct extends v {
1824
+ constructor() {
1825
+ super(...arguments);
1826
+ /** @private */
1827
+ n(this, "_render", () => {
1828
+ const t = this.getAttribute("title") || "", e = !this.hasAttribute("closable") || this.getAttribute("closable") !== "false", o = this.getAttribute("width") || "400px", i = this.getAttribute("color") || "", s = this.hasAttribute("glow"), r = this.hasAttribute("pulse"), a = [s ? "glow" : "", r ? "pulse" : ""].filter(Boolean).join(" "), d = i ? ` style="--wox-fx-color:${i}"` : "";
1829
+ this.render(`${ee} ${M} .box { --width: ${o}; }`, `
1830
+ <div class="overlay">
1831
+ <div class="box ${a}"${d}>
1832
+ <div class="header">
1833
+ <span class="title">${t}</span>
1834
+ ${e ? '<button class="close-btn">&#x2715;</button>' : ""}
1835
+ </div>
1836
+ <div class="body"><slot></slot></div>
1837
+ <div class="footer">
1838
+ <slot name="footer">
1839
+ <button class="btn btn-secondary cancel-btn">Cancel</button>
1840
+ <button class="btn btn-primary ok-btn">OK</button>
1841
+ </slot>
1842
+ </div>
1843
+ </div>
1844
+ </div>
1845
+ `), this.$(".overlay").addEventListener("click", (x) => {
1846
+ x.target === this.$(".overlay") && (this.removeAttribute("open"), this.emit("wox-close", {}));
1847
+ });
1848
+ const c = this.$(".close-btn");
1849
+ c && c.addEventListener("click", () => {
1850
+ this.removeAttribute("open"), this.emit("wox-close", {});
1851
+ });
1852
+ const u = this.$(".cancel-btn");
1853
+ u && u.addEventListener("click", () => {
1854
+ this.removeAttribute("open"), this.emit("wox-cancel", {});
1855
+ });
1856
+ const h = this.$(".ok-btn");
1857
+ h && h.addEventListener("click", () => {
1858
+ this.removeAttribute("open"), this.emit("wox-confirm", {});
1859
+ });
1860
+ });
1861
+ /** @private */
1862
+ n(this, "_keyHandler", (t) => {
1863
+ t.key === "Escape" && (this.removeAttribute("open"), this.emit("wox-close", {}));
1864
+ });
1865
+ /** @private */
1866
+ n(this, "_attachKeyHandler", () => {
1867
+ document.addEventListener("keydown", this._keyHandler);
1868
+ });
1869
+ /** @private */
1870
+ n(this, "_detachKeyHandler", () => {
1871
+ document.removeEventListener("keydown", this._keyHandler);
1872
+ });
1873
+ }
1874
+ connectedCallback() {
1875
+ this._render();
1876
+ }
1877
+ attributeChangedCallback(t) {
1878
+ this.isConnected && (t === "open" && (this.hasAttribute("open") ? this._attachKeyHandler() : this._detachKeyHandler()), this._render());
1879
+ }
1880
+ disconnectedCallback() {
1881
+ this._detachKeyHandler();
1882
+ }
1883
+ open() {
1884
+ this.setAttribute("open", "");
1885
+ }
1886
+ close() {
1887
+ this.removeAttribute("open");
1888
+ }
1889
+ get openState() {
1890
+ return this.hasAttribute("open");
1891
+ }
1892
+ set openState(t) {
1893
+ t ? this.setAttribute("open", "") : this.removeAttribute("open");
1894
+ }
1895
+ }
1896
+ n(Ct, "observedAttributes", ["open", "title", "closable", "width", "color", "glow", "pulse"]);
1897
+ const oe = `
1898
+ :host { display: block; overflow: hidden; border: 1px solid var(--wox-border, #333); border-radius: var(--wox-radius-md, 6px); background: var(--wox-bg-panel, #17171a); }
1899
+
1900
+ .grid-wrapper { display: flex; flex-direction: column; height: 100%; overflow: hidden; }
1901
+
1902
+ /* ── Header ── */
1903
+ .header {
1904
+ display: flex; flex-shrink: 0;
1905
+ background: var(--wox-bg-section-header, #22222a);
1906
+ border-bottom: 1px solid var(--wox-border, #333);
1907
+ user-select: none;
1908
+ }
1909
+ .header-cell {
1910
+ position: relative; display: flex; align-items: center; gap: 4px;
1911
+ padding: 0 12px; height: 32px; flex-shrink: 0; overflow: hidden;
1912
+ font-size: var(--wox-font-size-sm, 10px); font-weight: 600;
1913
+ text-transform: uppercase; letter-spacing: 0.5px;
1914
+ color: var(--wox-text-secondary, #999); cursor: pointer;
1915
+ transition: color var(--wox-transition-fast, 0.12s);
1916
+ }
1917
+ .header-cell:hover { color: var(--wox-text-hi, #fff); }
1918
+ .header-cell.sorted { color: var(--wox-accent, #00e5ff); }
1919
+
1920
+ /* Sort arrow */
1921
+ .sort-arrow { font-size: 14px; opacity: 0; transition: opacity 0.15s, transform 0.15s; line-height: 1; }
1922
+ .header-cell:hover .sort-arrow { opacity: 0.4; }
1923
+ .header-cell.sorted .sort-arrow { opacity: 1; }
1924
+ .header-cell.sorted.desc .sort-arrow { transform: rotate(180deg); }
1925
+
1926
+ /* Resize handle */
1927
+ .resize-handle {
1928
+ position: absolute; top: 0; right: 0; width: 5px; height: 100%;
1929
+ cursor: col-resize; z-index: 1;
1930
+ }
1931
+ .resize-handle::after {
1932
+ content: ''; position: absolute; top: 6px; bottom: 6px; right: 2px; width: 1px;
1933
+ background: var(--wox-border-light, #444);
1934
+ transition: background var(--wox-transition-fast, 0.12s);
1935
+ }
1936
+ .resize-handle:hover::after, .resize-handle.active::after {
1937
+ background: var(--wox-accent, #00e5ff);
1938
+ }
1939
+
1940
+ .header-cell.dragging { opacity: 0.4; background: var(--wox-bg-hover, #2a2a2e); }
1941
+ .header-cell.drag-over { border-left: 2px solid var(--wox-accent, #00e5ff); }
1942
+
1943
+ /* ── Body ── */
1944
+ .body {
1945
+ flex: 1; overflow-y: auto; overflow-x: hidden;
1946
+ scrollbar-width: thin; scrollbar-color: var(--wox-border, #333) transparent;
1947
+ }
1948
+ .body::-webkit-scrollbar { width: 6px; }
1949
+ .body::-webkit-scrollbar-thumb { background: var(--wox-border, #333); border-radius: 3px; }
1950
+
1951
+ /* ── Rows ── */
1952
+ .row {
1953
+ display: flex; border-bottom: 1px solid var(--wox-border-section, #2e2e2e);
1954
+ transition: background var(--wox-transition-fast, 0.12s);
1955
+ cursor: default;
1956
+ }
1957
+ .row.even { background: var(--wox-bg-panel, #17171a); }
1958
+ .row.odd { background: var(--wox-bg-toolbar, #1e1e22); }
1959
+ .row:hover { background: var(--wox-bg-hover, #2a2a2e); }
1960
+
1961
+ .cell {
1962
+ display: flex; align-items: center;
1963
+ padding: 0 12px; height: 30px; flex-shrink: 0; overflow: hidden;
1964
+ font-size: var(--wox-font-size-base, 12px); color: var(--wox-text-primary, #eee);
1965
+ white-space: nowrap; text-overflow: ellipsis;
1966
+ }
1967
+ .cell.align-right { justify-content: flex-end; }
1968
+ .cell.align-center { justify-content: center; }
1969
+
1970
+ .cell-input {
1971
+ width: 100%; height: 24px; background: #222; border: 1px solid var(--wox-accent, #00e5ff);
1972
+ color: #fff; padding: 2px 4px; border-radius: 4px; font-size: 11px; outline: none;
1973
+ }
1974
+
1975
+ /* ── Empty state ── */
1976
+ .empty {
1977
+ display: flex; align-items: center; justify-content: center;
1978
+ height: 80px; color: var(--wox-text-secondary, #999);
1979
+ font-size: var(--wox-font-size-md, 11px); font-style: italic;
1980
+ }
1981
+ `, ie = 120, se = 40;
1982
+ class ne extends v {
1983
+ constructor() {
1984
+ super(...arguments);
1985
+ /** @private */
1986
+ n(this, "_columns", []);
1987
+ /** @private */
1988
+ n(this, "_rows", []);
1989
+ /** @private */
1990
+ n(this, "_sortKey", null);
1991
+ /** @private */
1992
+ n(this, "_sortDir", "asc");
1993
+ /** @private */
1994
+ n(this, "_colWidths", []);
1995
+ /** @private */
1996
+ n(this, "_editingCell", null);
1997
+ /** @private */
1998
+ n(this, "_getSortedRows", () => {
1999
+ if (!this._sortKey) return this._rows;
2000
+ const t = this._sortKey, e = this._sortDir === "asc" ? 1 : -1;
2001
+ return [...this._rows].sort((o, i) => {
2002
+ const s = o[t], r = i[t];
2003
+ return s == null && r == null ? 0 : s == null ? e : r == null ? -e : typeof s == "number" && typeof r == "number" ? (s - r) * e : String(s).localeCompare(String(r)) * e;
2004
+ });
2005
+ });
2006
+ /** @private */
2007
+ n(this, "_render", () => {
2008
+ const t = this._getSortedRows(), e = this._columns.map((i, s) => {
2009
+ const r = this._sortKey === i.key, a = [r ? "sorted" : "", r && this._sortDir === "desc" ? "desc" : ""].filter(Boolean).join(" "), d = i.sortable !== !1;
2010
+ return `<div class="header-cell ${a}" data-col="${s}" style="width:${this._colWidths[s]}px" draggable="true">
2011
+ <span class="label-text">${i.label || i.key}</span>
2012
+ ${d ? '<span class="sort-arrow">&#9650;</span>' : ""}
2013
+ <div class="resize-handle" data-col="${s}"></div>
2014
+ </div>`;
2015
+ }).join(""), o = t.length === 0 ? '<div class="empty">No data</div>' : t.map((i, s) => {
2016
+ const r = s % 2 === 0 ? "even" : "odd", a = this._columns.map((d, c) => {
2017
+ const u = d.align ? ` align-${d.align}` : "", h = this._editingCell && this._editingCell.rowIndex === s && this._editingCell.key === d.key, x = i[d.key] != null ? i[d.key] : "";
2018
+ return h ? `<div class="cell${u}" style="width:${this._colWidths[c]}px" data-key="${d.key}">
2019
+ <input class="cell-input" spellcheck="false">
2020
+ </div>` : `<div class="cell${u}" style="width:${this._colWidths[c]}px" data-key="${d.key}">${x}</div>`;
2021
+ }).join("");
2022
+ return `<div class="row ${r}" data-row="${s}">${a}</div>`;
2023
+ }).join("");
2024
+ if (this.render(oe, `
2025
+ <div class="grid-wrapper">
2026
+ <div class="header">${e}</div>
2027
+ <div class="body">${o}</div>
2028
+ </div>
2029
+ `), this._bindEvents(), this._editingCell) {
2030
+ const i = this.$(".cell-input");
2031
+ if (i) {
2032
+ const { rowIndex: s, key: r } = this._editingCell, a = this._getSortedRows();
2033
+ let d = a[s][r] != null ? a[s][r] : "";
2034
+ const c = document.createElement("div");
2035
+ c.innerHTML = d;
2036
+ const u = c.textContent || c.innerText || d;
2037
+ i.value = u, i.dataset.oldValue = u, i.focus(), i.select(), i.addEventListener("keydown", (h) => {
2038
+ h.key === "Enter" ? this._commitEdit(i.value) : h.key === "Escape" && (this._editingCell = null, this._render());
2039
+ }), i.addEventListener("blur", () => {
2040
+ this._commitEdit(i.value);
2041
+ });
2042
+ }
2043
+ }
2044
+ });
2045
+ /** @private */
2046
+ n(this, "_commitEdit", (t) => {
2047
+ if (!this._editingCell) return;
2048
+ const { rowIndex: e, key: o } = this._editingCell, i = this.$(".cell-input"), s = i ? i.dataset.oldValue : "", a = this._getSortedRows()[e];
2049
+ s !== t && (this.emit("wox-cell-change", { row: a, key: o, oldValue: s, newValue: t }), a[o] = t), this._editingCell = null, this._render();
2050
+ });
2051
+ /** @private */
2052
+ n(this, "_bindEvents", () => {
2053
+ this.$$(".header-cell").forEach((t) => {
2054
+ t.addEventListener("click", (e) => {
2055
+ if (e.target.closest(".resize-handle")) return;
2056
+ const o = Number(t.dataset.col), i = this._columns[o];
2057
+ i.sortable !== !1 && (this._sortKey === i.key ? this._sortDir = this._sortDir === "asc" ? "desc" : "asc" : (this._sortKey = i.key, this._sortDir = "asc"), this.emit("wox-sort", { key: this._sortKey, direction: this._sortDir }), this._render());
2058
+ }), t.addEventListener("dragstart", (e) => {
2059
+ const o = t.dataset.col;
2060
+ e.dataTransfer.setData("text/plain", o), t.classList.add("dragging");
2061
+ }), t.addEventListener("dragover", (e) => {
2062
+ e.preventDefault(), t.classList.add("drag-over");
2063
+ }), t.addEventListener("dragleave", () => {
2064
+ t.classList.remove("drag-over");
2065
+ }), t.addEventListener("drop", (e) => {
2066
+ e.preventDefault(), t.classList.remove("drag-over");
2067
+ const o = parseInt(e.dataTransfer.getData("text/plain"), 10), i = parseInt(t.dataset.col, 10);
2068
+ o !== i && this._swapColumns(o, i);
2069
+ }), t.addEventListener("dragend", () => {
2070
+ t.classList.remove("dragging");
2071
+ });
2072
+ }), this.$$(".row").forEach((t) => {
2073
+ t.addEventListener("click", () => {
2074
+ const e = Number(t.dataset.row), o = this._getSortedRows();
2075
+ this.emit("wox-row-click", { row: o[e], index: e });
2076
+ }), t.querySelectorAll(".cell").forEach((e) => {
2077
+ e.addEventListener("dblclick", (o) => {
2078
+ o.stopPropagation();
2079
+ const i = Number(t.dataset.row), s = e.dataset.key, r = this._columns.findIndex((a) => a.key === s);
2080
+ this._columns[r].editable !== !1 && (this._editingCell = { rowIndex: i, key: s }, this._render());
2081
+ });
2082
+ });
2083
+ }), this.$$(".resize-handle").forEach((t) => {
2084
+ t.addEventListener("mousedown", (e) => {
2085
+ e.preventDefault(), e.stopPropagation();
2086
+ const o = Number(t.dataset.col), i = e.clientX, s = this._colWidths[o];
2087
+ t.classList.add("active");
2088
+ const r = (d) => {
2089
+ const c = d.clientX - i;
2090
+ this._colWidths[o] = Math.max(se, s + c), this._applyWidths();
2091
+ }, a = () => {
2092
+ t.classList.remove("active"), document.removeEventListener("mousemove", r), document.removeEventListener("mouseup", a);
2093
+ };
2094
+ document.addEventListener("mousemove", r), document.addEventListener("mouseup", a);
2095
+ });
2096
+ });
2097
+ });
2098
+ /**
2099
+ * Updates column widths in-place without full re-render (for smooth resize).
2100
+ * @private
2101
+ */
2102
+ n(this, "_applyWidths", () => {
2103
+ this.$$(".header-cell").forEach((t, e) => {
2104
+ t.style.width = `${this._colWidths[e]}px`;
2105
+ }), this.$$(".row").forEach((t) => {
2106
+ t.querySelectorAll(".cell").forEach((o, i) => {
2107
+ o.style.width = `${this._colWidths[i]}px`;
2108
+ });
2109
+ });
2110
+ });
2111
+ /** @private */
2112
+ n(this, "_swapColumns", (t, e) => {
2113
+ const o = [...this._columns], i = [...this._colWidths], [s] = o.splice(t, 1);
2114
+ o.splice(e, 0, s);
2115
+ const [r] = i.splice(t, 1);
2116
+ i.splice(e, 0, r), this._columns = o, this._colWidths = i, this._render();
2117
+ });
2118
+ }
2119
+ // { rowIndex: number, key: string }
2120
+ connectedCallback() {
2121
+ this._render();
2122
+ }
2123
+ /**
2124
+ * Sets the column definitions.
2125
+ * @param {Array<{key: string, label: string, width?: number, align?: string, sortable?: boolean}>} cols
2126
+ */
2127
+ set columns(t) {
2128
+ this._columns = t || [], this._colWidths = this._columns.map((e) => e.width || ie), this._sortKey = null, this._sortDir = "asc", this._render();
2129
+ }
2130
+ /** @returns {Array} current column definitions */
2131
+ get columns() {
2132
+ return this._columns;
2133
+ }
2134
+ /**
2135
+ * Sets the row data.
2136
+ * @param {Array<Object>} data
2137
+ */
2138
+ set rows(t) {
2139
+ this._rows = t || [], this._render();
2140
+ }
2141
+ /** @returns {Array} current row data */
2142
+ get rows() {
2143
+ return this._rows;
2144
+ }
2145
+ }
2146
+ const re = 4e3, W = 300, ae = 200, le = 8, de = 99999, At = {
2147
+ TL: { top: "16px", left: "16px" },
2148
+ TC: { top: "16px", left: "50%", transform: "translateX(-50%)" },
2149
+ TR: { top: "16px", right: "16px" },
2150
+ BL: { bottom: "16px", left: "16px" },
2151
+ BC: { bottom: "16px", left: "50%", transform: "translateX(-50%)" },
2152
+ BR: { bottom: "16px", right: "16px" }
2153
+ }, ce = {
2154
+ TL: "translateX(-120%)",
2155
+ TC: "translateY(-120%)",
2156
+ TR: "translateX(120%)",
2157
+ BL: "translateX(-120%)",
2158
+ BC: "translateY(120%)",
2159
+ BR: "translateX(120%)"
2160
+ }, X = {
2161
+ success: { bg: "#1a2e1a", border: "#4CAF50", icon: "#66BB6A", progress: "#4CAF50", text: "#c8e6c9" },
2162
+ error: { bg: "#2e1a1a", border: "#f44336", icon: "#ef5350", progress: "#f44336", text: "#ffcdd2" },
2163
+ warning: { bg: "#2e2a1a", border: "#FF9800", icon: "#FFA726", progress: "#FF9800", text: "#ffe0b2" },
2164
+ info: { bg: "#1a222e", border: "#2196F3", icon: "#42A5F5", progress: "#2196F3", text: "#bbdefb" }
2165
+ }, q = {
2166
+ success: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>',
2167
+ error: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>',
2168
+ warning: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',
2169
+ info: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>'
2170
+ };
2171
+ let J = !1;
2172
+ const pe = () => {
2173
+ if (J) return;
2174
+ J = !0;
2175
+ const l = document.createElement("style");
2176
+ l.textContent = `
2177
+ .wox-toast-container {
2178
+ position: fixed;
2179
+ display: flex;
2180
+ flex-direction: column;
2181
+ gap: ${le}px;
2182
+ z-index: ${de};
2183
+ pointer-events: none;
2184
+ }
2185
+ .wox-toast {
2186
+ pointer-events: auto;
2187
+ display: flex;
2188
+ align-items: flex-start;
2189
+ gap: 10px;
2190
+ min-width: 280px;
2191
+ max-width: 420px;
2192
+ padding: 12px 14px;
2193
+ border-radius: var(--wox-radius-md, 6px);
2194
+ border-left: 4px solid transparent;
2195
+ box-shadow: var(--wox-shadow-md, 0 4px 16px rgba(0,0,0,.4));
2196
+ font-family: var(--wox-font, 'Inter', sans-serif);
2197
+ font-size: 14px;
2198
+ line-height: 1.4;
2199
+ overflow: hidden;
2200
+ position: relative;
2201
+ }
2202
+ .wox-toast-icon {
2203
+ flex-shrink: 0;
2204
+ display: flex;
2205
+ align-items: center;
2206
+ margin-top: 1px;
2207
+ }
2208
+ .wox-toast-message {
2209
+ flex: 1;
2210
+ word-break: break-word;
2211
+ }
2212
+ .wox-toast-close {
2213
+ flex-shrink: 0;
2214
+ background: none;
2215
+ border: none;
2216
+ cursor: pointer;
2217
+ padding: 0 0 0 4px;
2218
+ color: #666;
2219
+ font-size: 18px;
2220
+ line-height: 1;
2221
+ transition: color .15s;
2222
+ }
2223
+ .wox-toast-progress {
2224
+ position: absolute;
2225
+ bottom: 0;
2226
+ left: 0;
2227
+ height: 3px;
2228
+ border-radius: 0 0 0 var(--wox-radius-md, 6px);
2229
+ }
2230
+ `, document.head.appendChild(l);
2231
+ }, B = /* @__PURE__ */ new Set(), Y = {}, he = (l) => {
2232
+ if (Y[l]) return Y[l];
2233
+ const p = document.createElement("div");
2234
+ p.className = `wox-toast-container wox-toast-container-${l}`;
2235
+ const t = At[l];
2236
+ return Object.assign(p.style, t), l.startsWith("B") && (p.style.flexDirection = "column-reverse"), document.body.appendChild(p), Y[l] = p, p;
2237
+ }, I = (l, p, t = {}) => {
2238
+ pe();
2239
+ const e = `${l}::${p}`;
2240
+ if (B.has(e)) return;
2241
+ B.add(e);
2242
+ const {
2243
+ duration: o = re,
2244
+ closable: i = !0,
2245
+ position: s = "BR"
2246
+ } = t, r = X[l] || X.info, a = At[s] ? s : "BR", d = he(a), c = document.createElement("div");
2247
+ c.className = `wox-toast wox-toast-${l}`, c.style.backgroundColor = r.bg, c.style.borderLeftColor = r.border, c.style.color = r.text;
2248
+ let u = `
2249
+ <span class="wox-toast-icon" style="color:${r.icon}">${q[l] || q.info}</span>
2250
+ <span class="wox-toast-message">${p}</span>
2251
+ `;
2252
+ if (i && (u += '<button class="wox-toast-close" aria-label="Close">&times;</button>'), c.innerHTML = u, i) {
2253
+ const _ = c.querySelector(".wox-toast-close");
2254
+ _ && (_.addEventListener("mouseenter", () => {
2255
+ _.style.color = r.icon;
2256
+ }), _.addEventListener("mouseleave", () => {
2257
+ _.style.color = "#666";
2258
+ }));
2259
+ }
2260
+ let h = null;
2261
+ o > 0 && (h = document.createElement("div"), h.className = "wox-toast-progress", h.style.backgroundColor = r.progress, h.style.width = "100%", c.appendChild(h));
2262
+ const x = ce[a];
2263
+ c.animate(
2264
+ [
2265
+ { transform: x, opacity: 0 },
2266
+ { transform: "translateX(0) translateY(0)", opacity: 1 }
2267
+ ],
2268
+ { duration: W, easing: "cubic-bezier(.22,1,.36,1)", fill: "forwards" }
2269
+ ), d.appendChild(c);
2270
+ let g = null, b = o, f = 0, w = null;
2271
+ const y = () => {
2272
+ o <= 0 || (f = Date.now(), h && (w = h.animate(
2273
+ [
2274
+ { width: h.style.width },
2275
+ { width: "0%" }
2276
+ ],
2277
+ { duration: b, easing: "linear", fill: "forwards" }
2278
+ )), g = setTimeout(() => O(), b));
2279
+ }, S = () => {
2280
+ g && (clearTimeout(g), g = null), w && w.pause();
2281
+ const _ = Date.now() - f;
2282
+ if (b = Math.max(b - _, 0), h && w) {
2283
+ const k = o > 0 ? b / o * 100 : 0;
2284
+ h.style.width = `${k}%`;
2285
+ }
2286
+ }, O = () => {
2287
+ B.delete(e), g && (clearTimeout(g), g = null), w && w.cancel();
2288
+ const _ = c.animate(
2289
+ [
2290
+ { transform: "translateX(0) translateY(0)", opacity: 1 },
2291
+ { transform: x, opacity: 0 }
2292
+ ],
2293
+ { duration: W, easing: "cubic-bezier(.22,1,.36,1)", fill: "forwards" }
2294
+ );
2295
+ _.onfinish = () => {
2296
+ const k = c.offsetHeight;
2297
+ c.style.minHeight = "0", c.style.padding = "0", c.style.margin = "0", c.style.overflow = "hidden";
2298
+ const zt = c.animate(
2299
+ [{ height: `${k}px` }, { height: "0px" }],
2300
+ { duration: ae, easing: "ease" }
2301
+ );
2302
+ zt.onfinish = () => c.remove();
2303
+ };
2304
+ };
2305
+ if (c.addEventListener("mouseenter", S), c.addEventListener("mouseleave", y), i) {
2306
+ const _ = c.querySelector(".wox-toast-close");
2307
+ _ && _.addEventListener("click", O);
2308
+ }
2309
+ y();
2310
+ };
2311
+ class R extends v {
2312
+ }
2313
+ /**
2314
+ * Show a success toast notification.
2315
+ * @param {string} message - Message to display
2316
+ * @param {object} [options] - { duration?: number, closable?: boolean, position?: string }
2317
+ */
2318
+ n(R, "success", (p, t) => I("success", p, t)), /**
2319
+ * Show an error toast notification.
2320
+ * @param {string} message - Message to display
2321
+ * @param {object} [options] - { duration?: number, closable?: boolean, position?: string }
2322
+ */
2323
+ n(R, "error", (p, t) => I("error", p, t)), /**
2324
+ * Show a warning toast notification.
2325
+ * @param {string} message - Message to display
2326
+ * @param {object} [options] - { duration?: number, closable?: boolean, position?: string }
2327
+ */
2328
+ n(R, "warning", (p, t) => I("warning", p, t)), /**
2329
+ * Show an info toast notification.
2330
+ * @param {string} message - Message to display
2331
+ * @param {object} [options] - { duration?: number, closable?: boolean, position?: string }
2332
+ */
2333
+ n(R, "info", (p, t) => I("info", p, t));
2334
+ const K = "wox-ctx-menu-styles", xe = "wox-ctx-menu", V = 4, ue = 3e4, ge = `
2335
+ .wox-ctx-menu {
2336
+ position: fixed;
2337
+ background: var(--wox-bg-panel, #17171a);
2338
+ border: 1px solid var(--wox-border, #333);
2339
+ border-radius: var(--wox-radius-md, 6px);
2340
+ box-shadow: var(--wox-shadow-lg);
2341
+ padding: var(--wox-space-sm, 4px);
2342
+ min-width: 180px;
2343
+ z-index: ${ue};
2344
+ font-family: var(--wox-font, 'Inter', sans-serif);
2345
+ font-size: var(--wox-font-size-base, 12px);
2346
+ color: var(--wox-text-primary, #eee);
2347
+ display: none;
2348
+ }
2349
+ .wox-ctx-menu-item {
2350
+ display: flex; align-items: center; gap: 8px;
2351
+ padding: 6px 12px; border-radius: var(--wox-radius-sm, 3px);
2352
+ cursor: pointer; transition: background var(--wox-transition-fast, 0.12s ease);
2353
+ user-select: none;
2354
+ }
2355
+ .wox-ctx-menu-item:hover { background: var(--wox-bg-hover, #2a2a2e); }
2356
+ .wox-ctx-menu-item--disabled { opacity: 0.4; pointer-events: none; }
2357
+ .wox-ctx-menu-icon { width: 18px; text-align: center; flex-shrink: 0; font-size: 16px; color: var(--wox-text-secondary, #999); }
2358
+ .wox-ctx-menu-label { flex: 1; }
2359
+ .wox-ctx-menu-shortcut { font-size: var(--wox-font-size-sm, 10px); color: var(--wox-text-secondary, #999); margin-left: 16px; }
2360
+ .wox-ctx-menu-divider { height: 1px; background: var(--wox-border, #333); margin: 4px 8px; }
2361
+ `, be = () => {
2362
+ if (document.getElementById(K)) return;
2363
+ const l = document.createElement("style");
2364
+ l.id = K, l.textContent = ge, document.head.appendChild(l);
2365
+ }, m = class m extends v {
2366
+ };
2367
+ /* ── Singleton state ── */
2368
+ /** @type {HTMLDivElement|null} */
2369
+ n(m, "_el", null), /** @type {boolean} */
2370
+ n(m, "_listenersReady", !1), /**
2371
+ * Show the context menu at the pointer position.
2372
+ * @param {MouseEvent} event - The triggering mouse event (used for clientX / clientY).
2373
+ * @param {Array<{label?: string, icon?: string, action?: Function, disabled?: boolean, divider?: boolean, shortcut?: string}>} items
2374
+ */
2375
+ n(m, "show", (p, t) => {
2376
+ if (!p || !t) return;
2377
+ p.preventDefault(), p.stopPropagation(), be();
2378
+ let e = m._el;
2379
+ e || (e = document.createElement("div"), e.id = xe, e.className = "wox-ctx-menu", document.body.appendChild(e), m._el = e), e.innerHTML = "", t.forEach((o) => {
2380
+ if (o.divider) {
2381
+ const a = document.createElement("div");
2382
+ a.className = "wox-ctx-menu-divider", e.appendChild(a);
2383
+ return;
2384
+ }
2385
+ const i = document.createElement("div");
2386
+ i.className = "wox-ctx-menu-item", o.disabled && i.classList.add("wox-ctx-menu-item--disabled");
2387
+ const s = document.createElement("i");
2388
+ s.className = "material-icons wox-ctx-menu-icon", s.textContent = o.icon || "", i.appendChild(s);
2389
+ const r = document.createElement("span");
2390
+ if (r.className = "wox-ctx-menu-label", r.textContent = o.label || "", i.appendChild(r), o.shortcut) {
2391
+ const a = document.createElement("span");
2392
+ a.className = "wox-ctx-menu-shortcut", a.textContent = o.shortcut, i.appendChild(a);
2393
+ }
2394
+ o.disabled || i.addEventListener("click", () => {
2395
+ m.hide(), o.action && o.action();
2396
+ }), e.appendChild(i);
2397
+ }), e.style.display = "block", e.style.left = `${p.clientX}px`, e.style.top = `${p.clientY}px`, requestAnimationFrame(() => {
2398
+ const o = e.getBoundingClientRect(), i = window.innerWidth, s = window.innerHeight;
2399
+ o.right > i && (e.style.left = `${i - o.width - V}px`), o.bottom > s && (e.style.top = `${s - o.height - V}px`);
2400
+ }), m._listenersReady || (document.addEventListener("click", m._onClickOutside, !0), document.addEventListener("contextmenu", m._onClickOutside, !0), document.addEventListener("keydown", m._onKeyDown, !0), m._listenersReady = !0);
2401
+ }), /**
2402
+ * Hide the context menu if it is currently visible.
2403
+ */
2404
+ n(m, "hide", () => {
2405
+ m._el && (m._el.style.display = "none");
2406
+ }), /* ── Private global handlers ── */
2407
+ /**
2408
+ * Closes the menu when clicking outside of it.
2409
+ * @param {MouseEvent} e
2410
+ * @private
2411
+ */
2412
+ n(m, "_onClickOutside", (p) => {
2413
+ m._el && m._el.style.display !== "none" && (m._el.contains(p.target) || m.hide());
2414
+ }), /**
2415
+ * Closes the menu on Escape key press.
2416
+ * @param {KeyboardEvent} e
2417
+ * @private
2418
+ */
2419
+ n(m, "_onKeyDown", (p) => {
2420
+ p.key === "Escape" && m.hide();
2421
+ });
2422
+ let G = m;
2423
+ const U = 2, Z = 40, Q = 3, C = (l) => {
2424
+ if (!l || !l.stops || l.stops.length < 2) return "";
2425
+ const t = [...l.stops].sort((e, o) => e.position - o.position).map((e) => `${e.color} ${e.position}%`).join(", ");
2426
+ return l.type === "linear" ? `linear-gradient(${l.angle}deg, ${t})` : `radial-gradient(circle, ${t})`;
2427
+ }, tt = (l) => {
2428
+ if (!l) return null;
2429
+ let p = null, t = 90, e = null;
2430
+ const o = l.match(/^linear-gradient\(\s*(\d+)deg\s*,\s*(.+)\)$/i);
2431
+ if (o && (p = "linear", t = parseInt(o[1], 10), e = o[2]), !p) {
2432
+ const a = l.match(/^radial-gradient\(\s*(?:circle|ellipse)?\s*,?\s*(.+)\)$/i);
2433
+ a && (p = "radial", e = a[1]);
2434
+ }
2435
+ if (!p || !e) return null;
2436
+ const i = [], s = /(#[0-9a-fA-F]{3,8}|rgba?\([^)]+\))\s+(\d+(?:\.\d+)?)%/g;
2437
+ let r;
2438
+ for (; (r = s.exec(e)) !== null; )
2439
+ i.push({
2440
+ color: r[1],
2441
+ position: parseFloat(r[2])
2442
+ });
2443
+ return i.length < 2 ? null : { type: p, angle: t, stops: i };
2444
+ }, fe = `
2445
+ :host { display: block; }
2446
+ .editor { padding: var(--wox-space-md, 8px) 0; }
2447
+ .bar-wrapper { position: relative; margin-bottom: var(--wox-space-md, 8px); }
2448
+ .bar {
2449
+ height: 24px; border-radius: var(--wox-radius-sm, 3px);
2450
+ border: 1px solid var(--wox-border, #333); cursor: crosshair;
2451
+ }
2452
+ .stops { position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none; }
2453
+ .handle {
2454
+ position: absolute; top: 50%; width: 14px; height: 14px;
2455
+ border: 2px solid var(--wox-bg-panel, #17171a);
2456
+ border-radius: 2px; cursor: grab; transform: translate(-50%, -50%);
2457
+ pointer-events: auto; transition: box-shadow 0.15s, transform 0.15s;
2458
+ box-shadow: 0 1px 3px rgba(0,0,0,0.6); z-index: 1;
2459
+ }
2460
+ .handle:hover { box-shadow: 0 2px 6px rgba(0,0,0,0.7); transform: translate(-50%,-50%) scale(1.15); }
2461
+ .handle.dragging { cursor: grabbing; box-shadow: 0 3px 8px rgba(0,0,0,0.8); transform: translate(-50%,-50%) scale(1.2); z-index: 10; }
2462
+ .handle.removing { opacity: 0.4; border-color: var(--wox-danger, #f72585); box-shadow: 0 2px 6px rgba(247,37,133,0.4); }
2463
+ .color-input { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; pointer-events: none; }
2464
+ .hint { font-size: var(--wox-font-size-xs, 9px); color: var(--wox-text-secondary, #999); text-align: center; margin-top: var(--wox-space-sm, 4px); }
2465
+ `;
2466
+ class ve extends v {
2467
+ constructor() {
2468
+ super(...arguments);
2469
+ /** @private */
2470
+ n(this, "_gradient", null);
2471
+ /** @private */
2472
+ n(this, "_dragging", null);
2473
+ /** @private */
2474
+ n(this, "_justDragged", !1);
2475
+ /**
2476
+ * Builds the full editor DOM and binds all events.
2477
+ * @private
2478
+ */
2479
+ n(this, "_build", () => {
2480
+ if (!this._gradient) return;
2481
+ const t = C(this._gradient);
2482
+ this.render(fe, `
2483
+ <div class="editor">
2484
+ <div class="bar-wrapper">
2485
+ <div class="bar" style="background: ${t}"></div>
2486
+ <div class="stops"></div>
2487
+ </div>
2488
+ <div class="hint">Double-click bar to add stop &middot; Drag down to remove</div>
2489
+ </div>
2490
+ `), this._renderStops(), this._bindBarEvents();
2491
+ });
2492
+ /**
2493
+ * Updates the gradient bar preview background.
2494
+ * @private
2495
+ */
2496
+ n(this, "_updatePreview", () => {
2497
+ const t = this.$(".bar");
2498
+ t && (t.style.background = C(this._gradient));
2499
+ });
2500
+ /**
2501
+ * Emits a gradient event with current state.
2502
+ * @private
2503
+ * @param {string} eventName - Event name to dispatch
2504
+ */
2505
+ n(this, "_emitGradient", (t) => {
2506
+ this.emit(t, {
2507
+ gradient: this.gradient,
2508
+ css: C(this._gradient)
2509
+ });
2510
+ });
2511
+ /**
2512
+ * Renders all color stop handles into the stops container.
2513
+ * @private
2514
+ */
2515
+ n(this, "_renderStops", () => {
2516
+ const t = this.$(".stops");
2517
+ if (!t) return;
2518
+ t.innerHTML = "", [...this._gradient.stops].sort((o, i) => o.position - i.position).forEach((o) => {
2519
+ const i = this._gradient.stops.indexOf(o), s = document.createElement("div");
2520
+ s.className = "handle", s.style.left = o.position + "%", s.style.backgroundColor = o.color, s.dataset.index = i;
2521
+ const r = document.createElement("input");
2522
+ r.type = "color", r.value = o.color, r.className = "color-input", s.appendChild(r), s.addEventListener("click", (a) => {
2523
+ if (this._justDragged) {
2524
+ this._justDragged = !1;
2525
+ return;
2526
+ }
2527
+ a.stopPropagation(), r.click();
2528
+ }), r.addEventListener("input", (a) => {
2529
+ const d = parseInt(s.dataset.index, 10);
2530
+ this._gradient.stops[d].color = a.target.value, s.style.backgroundColor = a.target.value, this._updatePreview(), this._emitGradient("wox-gradient-input");
2531
+ }), r.addEventListener("change", () => {
2532
+ this._emitGradient("wox-gradient-change");
2533
+ }), r.addEventListener("click", (a) => a.stopPropagation()), s.addEventListener("mousedown", (a) => {
2534
+ if (a.target === r) return;
2535
+ a.preventDefault(), a.stopPropagation();
2536
+ const d = this.$(".bar");
2537
+ if (!d) return;
2538
+ const c = d.getBoundingClientRect(), u = parseInt(s.dataset.index, 10);
2539
+ this._dragging = { idx: u, startY: a.clientY }, s.classList.add("dragging");
2540
+ const h = (g) => {
2541
+ const b = (g.clientX - c.left) / c.width * 100, f = Math.max(0, Math.min(100, Math.round(b * 10) / 10));
2542
+ this._gradient.stops[u].position = f, s.style.left = f + "%", Math.abs(g.clientY - this._dragging.startY) > Z && this._gradient.stops.length > U ? s.classList.add("removing") : s.classList.remove("removing"), this._updatePreview(), this._emitGradient("wox-gradient-input");
2543
+ }, x = (g) => {
2544
+ var w;
2545
+ document.removeEventListener("mousemove", h), document.removeEventListener("mouseup", x), s.classList.remove("dragging");
2546
+ const b = Math.abs(g.clientY - this._dragging.startY);
2547
+ b > Z && this._gradient.stops.length > U ? (this._gradient.stops.splice(u, 1), this._renderStops(), this._updatePreview(), this._emitGradient("wox-gradient-change")) : this._emitGradient("wox-gradient-change");
2548
+ const f = Math.abs(g.clientX - (c.left + (((w = this._gradient.stops[u]) == null ? void 0 : w.position) || 0) * c.width / 100));
2549
+ (b > Q || f > Q) && (this._justDragged = !0), this._dragging = null;
2550
+ };
2551
+ document.addEventListener("mousemove", h), document.addEventListener("mouseup", x);
2552
+ }), t.appendChild(s);
2553
+ });
2554
+ });
2555
+ /**
2556
+ * Binds the double-click event on the gradient bar to add new stops.
2557
+ * @private
2558
+ */
2559
+ n(this, "_bindBarEvents", () => {
2560
+ const t = this.$(".bar");
2561
+ t && t.addEventListener("dblclick", (e) => {
2562
+ const o = t.getBoundingClientRect(), i = Math.round((e.clientX - o.left) / o.width * 100), s = Math.max(0, Math.min(100, i)), r = [...this._gradient.stops].sort((d, c) => d.position - c.position);
2563
+ let a = "#888888";
2564
+ for (let d = 0; d < r.length - 1; d++)
2565
+ if (s >= r[d].position && s <= r[d + 1].position) {
2566
+ a = r[d].color;
2567
+ break;
2568
+ }
2569
+ this._gradient.stops.push({ color: a, position: s }), this._renderStops(), this._updatePreview(), this._emitGradient("wox-gradient-change");
2570
+ });
2571
+ });
2572
+ }
2573
+ connectedCallback() {
2574
+ this._gradient && this._build();
2575
+ }
2576
+ /**
2577
+ * Sets the gradient data and re-renders the editor.
2578
+ * @param {{ type: string, angle: number, stops: Array<{color: string, position: number}> }} g
2579
+ */
2580
+ set gradient(t) {
2581
+ this._gradient = JSON.parse(JSON.stringify(t)), this.isConnected && this._build();
2582
+ }
2583
+ /**
2584
+ * Returns a deep copy of the current gradient data.
2585
+ * @returns {{ type: string, angle: number, stops: Array<{color: string, position: number}> }|null}
2586
+ */
2587
+ get gradient() {
2588
+ return this._gradient ? JSON.parse(JSON.stringify(this._gradient)) : null;
2589
+ }
2590
+ }
2591
+ const et = "wox_gradients", we = "grad_preset_", me = [
2592
+ { id: "grad_preset_sunset", name: "Sunset", type: "linear", angle: 135, stops: [{ color: "#ff512f", position: 0 }, { color: "#f09819", position: 100 }] },
2593
+ { id: "grad_preset_ocean", name: "Ocean", type: "linear", angle: 135, stops: [{ color: "#2193b0", position: 0 }, { color: "#6dd5ed", position: 100 }] },
2594
+ { id: "grad_preset_forest", name: "Forest", type: "linear", angle: 135, stops: [{ color: "#11998e", position: 0 }, { color: "#38ef7d", position: 100 }] },
2595
+ { id: "grad_preset_purple_haze", name: "Purple Haze", type: "linear", angle: 135, stops: [{ color: "#7b4397", position: 0 }, { color: "#dc2430", position: 100 }] },
2596
+ { id: "grad_preset_midnight", name: "Midnight", type: "linear", angle: 135, stops: [{ color: "#232526", position: 0 }, { color: "#414345", position: 100 }] },
2597
+ { id: "grad_preset_peach", name: "Peach", type: "linear", angle: 135, stops: [{ color: "#ffecd2", position: 0 }, { color: "#fcb69f", position: 100 }] }
2598
+ ], _e = `
2599
+ :host { display: block; }
2600
+ .selector { position: relative; }
2601
+ .current {
2602
+ display: flex; align-items: center; gap: 8px;
2603
+ padding: 6px 8px; border: 1px solid var(--wox-border, #333);
2604
+ border-radius: var(--wox-radius-sm, 3px); cursor: pointer;
2605
+ background: var(--wox-bg-input, #1a1a1d); transition: border-color var(--wox-transition-fast);
2606
+ }
2607
+ .current:hover { border-color: var(--wox-accent, #00e5ff); }
2608
+ .selector.open .current { border-color: var(--wox-accent, #00e5ff); }
2609
+ .preview { width: 32px; height: 20px; border-radius: 3px; border: 1px solid var(--wox-border, #333); flex-shrink: 0; }
2610
+ .label { flex: 1; font-size: var(--wox-font-size-lg, 13px); color: var(--wox-text-primary, #eee); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
2611
+ .chevron { font-size: 10px; color: var(--wox-text-secondary, #999); flex-shrink: 0; }
2612
+ .dropdown {
2613
+ display: none; position: fixed;
2614
+ z-index: var(--wox-z-dropdown, 1000); background: var(--wox-bg-panel, #17171a);
2615
+ border: 1px solid var(--wox-border, #333);
2616
+ border-radius: var(--wox-radius-sm, 3px);
2617
+ box-shadow: var(--wox-shadow-md); max-height: 280px; overflow-y: auto;
2618
+ }
2619
+ .selector.open .dropdown { display: block; }
2620
+ .dropdown-item {
2621
+ display: flex; align-items: center; gap: 8px; padding: 8px 10px;
2622
+ cursor: pointer; transition: background var(--wox-transition-fast);
2623
+ }
2624
+ .dropdown-item:hover { background: var(--wox-bg-hover, #2a2a2e); }
2625
+ .dropdown-item-preview { width: 40px; height: 20px; border-radius: 3px; border: 1px solid var(--wox-border, #333); flex-shrink: 0; }
2626
+ .dropdown-item-label { flex: 1; font-size: var(--wox-font-size-lg, 13px); color: var(--wox-text-primary, #eee); }
2627
+ .dropdown-item-btn {
2628
+ display: none; background: none; border: none; color: var(--wox-text-secondary, #999);
2629
+ font-size: 14px; cursor: pointer; padding: 0 4px; line-height: 1; transition: color var(--wox-transition-fast);
2630
+ }
2631
+ .dropdown-item-btn.delete-btn { font-size: 16px; }
2632
+ .dropdown-item:hover .dropdown-item-btn { display: block; }
2633
+ .dropdown-item-btn:hover { color: var(--wox-accent, #00e5ff); }
2634
+ .dropdown-item-btn.delete-btn:hover { color: var(--wox-danger, #f72585); }
2635
+ .dropdown-custom { border-top: 1px solid var(--wox-border, #333); }
2636
+ .dropdown-custom .dropdown-item-label { color: var(--wox-accent, #00e5ff); font-weight: 500; }
2637
+ .solid-input { position: absolute; opacity: 0; pointer-events: none; }
2638
+
2639
+ /* Controls */
2640
+ .controls { margin-top: 10px; display: none; }
2641
+ .controls.visible { display: block; }
2642
+ .ctrl-label { font-size: var(--wox-font-size-sm, 10px); color: var(--wox-text-secondary, #999); font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase; min-width: 40px; }
2643
+ .type-row { display: flex; align-items: center; gap: 8px; margin-bottom: var(--wox-space-lg, 12px); }
2644
+ .type-toggle { display: flex; gap: var(--wox-space-sm, 4px); background: var(--wox-bg-input, #1a1a1d); padding: 3px; border-radius: var(--wox-radius-sm, 3px); }
2645
+ .type-btn {
2646
+ background: transparent; border: none; padding: 4px 14px; cursor: pointer;
2647
+ border-radius: 3px; font-size: var(--wox-font-size-base, 12px); font-weight: 500;
2648
+ color: var(--wox-text-secondary, #999); transition: all var(--wox-transition-fast);
2649
+ font-family: var(--wox-font, 'Inter', sans-serif);
2650
+ }
2651
+ .type-btn:hover { color: var(--wox-text-primary, #eee); background: var(--wox-bg-hover, #2a2a2e); }
2652
+ .type-btn.active { background: var(--wox-accent, #00e5ff); color: var(--wox-text-hi, #fff); }
2653
+ .angle-row, .speed-row { margin-bottom: var(--wox-space-lg, 12px); }
2654
+ .anim-type-row { display: flex; align-items: center; gap: 8px; margin-bottom: var(--wox-space-lg, 12px); }
2655
+ .anim-select {
2656
+ flex: 1; padding: 4px 8px; border: 1px solid var(--wox-border, #333);
2657
+ border-radius: var(--wox-radius-sm, 3px); font-size: var(--wox-font-size-base, 12px);
2658
+ background: var(--wox-bg-input, #1a1a1d); color: var(--wox-text-primary, #eee); cursor: pointer;
2659
+ font-family: var(--wox-font, 'Inter', sans-serif);
2660
+ }
2661
+
2662
+ /* Modal body */
2663
+ .editor-body { min-width: 400px; }
2664
+ .name-row { display: flex; align-items: center; gap: 8px; margin-top: var(--wox-space-xl, 16px); }
2665
+ .name-input {
2666
+ flex: 1; padding: 6px 8px; border: 1px solid var(--wox-border, #333);
2667
+ border-radius: var(--wox-radius-sm, 3px); font-size: var(--wox-font-size-base, 12px);
2668
+ background: var(--wox-bg-input, #1a1a1d); color: var(--wox-text-primary, #eee);
2669
+ font-family: var(--wox-font, 'Inter', sans-serif);
2670
+ }
2671
+ .name-input:focus { outline: none; border-color: var(--wox-accent, #00e5ff); }
2672
+
2673
+ /* Footer buttons */
2674
+ .btn {
2675
+ padding: 8px 16px; border-radius: var(--wox-radius-md, 6px);
2676
+ font-family: var(--wox-font, sans-serif); font-size: var(--wox-font-size-lg, 13px);
2677
+ font-weight: 500; cursor: pointer; border: none; transition: background var(--wox-transition-fast);
2678
+ }
2679
+ .btn-secondary { background: var(--wox-border, #333); color: var(--wox-text-primary, #eee); }
2680
+ .btn-secondary:hover { background: var(--wox-border-light, #444); }
2681
+ .btn-primary { background: var(--wox-accent, #00e5ff); color: var(--wox-text-hi, #fff); }
2682
+ .btn-primary:hover { background: #3bb3d9; }
2683
+ `, N = () => "grad_" + Date.now().toString(36) + "_" + Math.random().toString(36).slice(2, 7), ot = (l) => l ? l.startsWith("linear-gradient") || l.startsWith("radial-gradient") : !1;
2684
+ class St extends v {
2685
+ constructor() {
2686
+ super(...arguments);
2687
+ /** @private — Current CSS value (hex or gradient string) */
2688
+ n(this, "_value", "#ffffff");
2689
+ /** @private — Parsed gradient object or null for solid colors */
2690
+ n(this, "_gradient", null);
2691
+ /** @private — Animation speed 0-10 */
2692
+ n(this, "_animationSpeed", 0);
2693
+ /** @private — Animation type: 'pingpong' or 'cycle' */
2694
+ n(this, "_animationType", "pingpong");
2695
+ /** @private — Whether the dropdown is currently open */
2696
+ n(this, "_open", !1);
2697
+ /** @private — Saved gradients array */
2698
+ n(this, "_gradients", []);
2699
+ /** @private — Gradient currently being edited in the modal */
2700
+ n(this, "_editingGradient", null);
2701
+ /** @private — Name captured from the modal name input */
2702
+ n(this, "_editingName", "");
2703
+ /**
2704
+ * Read attributes and update internal state.
2705
+ * @private
2706
+ */
2707
+ n(this, "_syncFromAttributes", () => {
2708
+ const t = this.getAttribute("value");
2709
+ t && (this._value = t, this._gradient = ot(t) ? tt(t) : null);
2710
+ const e = this.getAttribute("animation-speed");
2711
+ e !== null && (this._animationSpeed = parseInt(e, 10) || 0);
2712
+ const o = this.getAttribute("animation-type");
2713
+ o && (this._animationType = o);
2714
+ });
2715
+ /**
2716
+ * Load gradients from localStorage, or seed with defaults.
2717
+ * @private
2718
+ */
2719
+ n(this, "_loadGradients", () => {
2720
+ try {
2721
+ const t = localStorage.getItem(et);
2722
+ if (t) {
2723
+ this._gradients = JSON.parse(t);
2724
+ return;
2725
+ }
2726
+ } catch {
2727
+ }
2728
+ this._gradients = me.map((t) => ({ ...t, stops: t.stops.map((e) => ({ ...e })) })), this._persistGradients();
2729
+ });
2730
+ /**
2731
+ * Persist gradients array to localStorage.
2732
+ * @private
2733
+ */
2734
+ n(this, "_persistGradients", () => {
2735
+ try {
2736
+ localStorage.setItem(et, JSON.stringify(this._gradients));
2737
+ } catch {
2738
+ }
2739
+ });
2740
+ /**
2741
+ * Upsert a gradient (update if id exists, insert otherwise) and persist.
2742
+ * @private
2743
+ * @param {Object} gradient - Gradient object with id, name, type, angle, stops
2744
+ */
2745
+ n(this, "_save", (t) => {
2746
+ const e = this._gradients.findIndex((o) => o.id === t.id);
2747
+ e >= 0 ? this._gradients[e] = t : this._gradients.push(t), this._persistGradients();
2748
+ });
2749
+ /**
2750
+ * Delete a gradient by ID and persist.
2751
+ * @private
2752
+ * @param {string} id - Gradient ID to remove
2753
+ */
2754
+ n(this, "_delete", (t) => {
2755
+ this._gradients = this._gradients.filter((e) => e.id !== t), this._persistGradients();
2756
+ });
2757
+ /**
2758
+ * Find a gradient by its ID.
2759
+ * @private
2760
+ * @param {string} id
2761
+ * @returns {Object|undefined}
2762
+ */
2763
+ n(this, "_getById", (t) => this._gradients.find((e) => e.id === t));
2764
+ /**
2765
+ * Derive a human-readable label from a CSS value.
2766
+ * @private
2767
+ * @param {string} value
2768
+ * @returns {string}
2769
+ */
2770
+ n(this, "_labelForValue", (t) => {
2771
+ if (!t) return "None";
2772
+ if (ot(t)) {
2773
+ for (const e of this._gradients)
2774
+ if (C(e) === t) return e.name;
2775
+ return "Custom Gradient";
2776
+ }
2777
+ return t;
2778
+ });
2779
+ /**
2780
+ * Build the full shadow DOM and bind events.
2781
+ * @private
2782
+ */
2783
+ n(this, "_build", () => {
2784
+ const t = !!this._gradient, e = this._gradient ? this._gradient.type : "linear", o = this._gradient ? this._gradient.angle : 90, i = e !== "radial";
2785
+ this.render(_e, `
2786
+ <div class="selector">
2787
+ <div class="current">
2788
+ <div class="preview"></div>
2789
+ <span class="label">${this._labelForValue(this._value)}</span>
2790
+ <span class="chevron">&#9662;</span>
2791
+ </div>
2792
+ <div class="dropdown"></div>
2793
+ </div>
2794
+ <div class="controls${t ? " visible" : ""}">
2795
+ <div class="type-row">
2796
+ <span class="ctrl-label">Type</span>
2797
+ <div class="type-toggle">
2798
+ <button class="type-btn${i ? " active" : ""}" data-type="linear">Linear</button>
2799
+ <button class="type-btn${i ? "" : " active"}" data-type="radial">Radial</button>
2800
+ </div>
2801
+ </div>
2802
+ <div class="angle-row" ${i ? "" : 'style="display:none"'}>
2803
+ <wox-slider label="ANGLE" value="${o}" min="0" max="360" step="1" show-value></wox-slider>
2804
+ </div>
2805
+ <div class="speed-row">
2806
+ <wox-slider label="SPEED" value="${this._animationSpeed}" min="0" max="10" step="1" show-value></wox-slider>
2807
+ </div>
2808
+ <div class="anim-type-row" ${this._animationSpeed <= 0 ? 'style="display:none"' : ""}>
2809
+ <span class="ctrl-label">Anim</span>
2810
+ <select class="anim-select">
2811
+ <option value="pingpong"${this._animationType === "pingpong" ? " selected" : ""}>Ping Pong</option>
2812
+ <option value="cycle"${this._animationType === "cycle" ? " selected" : ""}>Cycle</option>
2813
+ </select>
2814
+ </div>
2815
+ </div>
2816
+ <wox-modal class="editor-modal" title="Custom Gradient" width="480px">
2817
+ <div class="editor-body">
2818
+ <wox-gradient-editor class="modal-editor"></wox-gradient-editor>
2819
+ <div class="name-row">
2820
+ <span class="ctrl-label">Name</span>
2821
+ <input type="text" class="name-input" placeholder="Gradient name">
2822
+ </div>
2823
+ </div>
2824
+ <div slot="footer">
2825
+ <button class="btn btn-secondary cancel-btn">Cancel</button>
2826
+ <button class="btn btn-primary apply-btn">Apply</button>
2827
+ <button class="btn btn-primary save-btn">Save &amp; Apply</button>
2828
+ </div>
2829
+ </wox-modal>
2830
+ `), this._updatePreview(), this._bindEvents();
2831
+ });
2832
+ /**
2833
+ * Update the preview swatch and label text.
2834
+ * @private
2835
+ */
2836
+ n(this, "_updatePreview", () => {
2837
+ const t = this.$(".preview"), e = this.$(".label");
2838
+ t && (t.style.background = this._value), e && (e.textContent = this._labelForValue(this._value));
2839
+ });
2840
+ /**
2841
+ * Sync all controls (type toggle, angle, speed, anim type) to current state.
2842
+ * @private
2843
+ */
2844
+ n(this, "_syncControls", () => {
2845
+ const t = this.$(".controls");
2846
+ if (!t) return;
2847
+ if (!this._gradient) {
2848
+ t.classList.remove("visible");
2849
+ return;
2850
+ }
2851
+ t.classList.add("visible");
2852
+ const e = this._gradient.type !== "radial";
2853
+ this.$$(".type-btn").forEach((d) => {
2854
+ d.classList.toggle("active", d.dataset.type === this._gradient.type);
2855
+ });
2856
+ const o = this.$(".angle-row");
2857
+ o && (o.style.display = e ? "" : "none");
2858
+ const i = this.$(".angle-row wox-slider");
2859
+ i && i.setAttribute("value", this._gradient.angle);
2860
+ const s = this.$(".speed-row wox-slider");
2861
+ s && s.setAttribute("value", this._animationSpeed);
2862
+ const r = this.$(".anim-type-row");
2863
+ r && (r.style.display = this._animationSpeed > 0 ? "" : "none");
2864
+ const a = this.$(".anim-select");
2865
+ a && (a.value = this._animationType);
2866
+ });
2867
+ /**
2868
+ * Bind all interactive event listeners.
2869
+ * @private
2870
+ */
2871
+ n(this, "_bindEvents", () => {
2872
+ this.$(".current").addEventListener("click", (h) => {
2873
+ h.stopPropagation(), this._open ? this._closeDropdown() : this._openDropdown();
2874
+ }), this.$$(".type-btn").forEach((h) => {
2875
+ h.addEventListener("click", () => {
2876
+ if (!this._gradient) return;
2877
+ this.$$(".type-btn").forEach((g) => g.classList.remove("active")), h.classList.add("active"), this._gradient.type = h.dataset.type;
2878
+ const x = this.$(".angle-row");
2879
+ x && (x.style.display = h.dataset.type === "linear" ? "" : "none"), this._applyGradient();
2880
+ });
2881
+ });
2882
+ const e = this.$(".angle-row wox-slider");
2883
+ e && (e.addEventListener("wox-input", (h) => {
2884
+ this._gradient && (this._gradient.angle = h.detail.value, this._applyGradient());
2885
+ }), e.addEventListener("wox-change", (h) => {
2886
+ this._gradient && (this._gradient.angle = h.detail.value, this._applyGradient());
2887
+ }));
2888
+ const o = this.$(".speed-row wox-slider");
2889
+ o && (o.addEventListener("wox-input", (h) => {
2890
+ this._animationSpeed = h.detail.value;
2891
+ const x = this.$(".anim-type-row");
2892
+ x && (x.style.display = this._animationSpeed > 0 ? "" : "none"), this._emitChange();
2893
+ }), o.addEventListener("wox-change", (h) => {
2894
+ this._animationSpeed = h.detail.value;
2895
+ const x = this.$(".anim-type-row");
2896
+ x && (x.style.display = this._animationSpeed > 0 ? "" : "none"), this._emitChange();
2897
+ }));
2898
+ const i = this.$(".anim-select");
2899
+ i && i.addEventListener("change", (h) => {
2900
+ this._animationType = h.target.value, this._emitChange();
2901
+ });
2902
+ const s = this.$(".cancel-btn");
2903
+ s && s.addEventListener("click", () => {
2904
+ this._closeModal();
2905
+ });
2906
+ const r = this.$(".apply-btn");
2907
+ r && r.addEventListener("click", () => {
2908
+ this._applyFromEditor(!1);
2909
+ });
2910
+ const a = this.$(".save-btn");
2911
+ a && a.addEventListener("click", () => {
2912
+ this._applyFromEditor(!0);
2913
+ });
2914
+ const d = this.$(".name-input");
2915
+ d && d.addEventListener("input", (h) => {
2916
+ this._editingName = h.target.value.trim();
2917
+ });
2918
+ const c = this.$(".modal-editor");
2919
+ c && (c.addEventListener("wox-gradient-input", (h) => {
2920
+ this._editingGradient = h.detail.gradient;
2921
+ }), c.addEventListener("wox-gradient-change", (h) => {
2922
+ this._editingGradient = h.detail.gradient;
2923
+ }));
2924
+ const u = this.$(".editor-modal");
2925
+ u && u.addEventListener("wox-close", () => {
2926
+ this._editingGradient = null, this._editingName = "";
2927
+ });
2928
+ });
2929
+ /**
2930
+ * Open the dropdown and populate its items.
2931
+ * @private
2932
+ */
2933
+ n(this, "_openDropdown", () => {
2934
+ this._open = !0, this.$(".selector").classList.add("open"), this._populateDropdown(), this._positionDropdown();
2935
+ });
2936
+ /**
2937
+ * Position the fixed dropdown relative to the trigger, flipping up if needed.
2938
+ * @private
2939
+ */
2940
+ n(this, "_positionDropdown", () => {
2941
+ const t = this.$(".current"), e = this.$(".dropdown");
2942
+ if (!t || !e) return;
2943
+ const o = t.getBoundingClientRect(), i = window.innerHeight;
2944
+ e.style.left = `${o.left}px`, e.style.width = `${o.width}px`;
2945
+ const s = i - o.bottom, r = o.top, a = 280;
2946
+ s >= a || s >= r ? (e.style.top = `${o.bottom}px`, e.style.bottom = "", e.style.maxHeight = `${Math.min(a, s - 4)}px`) : (e.style.top = "", e.style.bottom = `${i - o.top}px`, e.style.maxHeight = `${Math.min(a, r - 4)}px`);
2947
+ });
2948
+ /**
2949
+ * Close the dropdown.
2950
+ * @private
2951
+ */
2952
+ n(this, "_closeDropdown", () => {
2953
+ this._open = !1, this.$(".selector").classList.remove("open");
2954
+ });
2955
+ /**
2956
+ * Build dropdown items: solid color, saved gradients, custom option.
2957
+ * @private
2958
+ */
2959
+ n(this, "_populateDropdown", () => {
2960
+ const t = this.$(".dropdown");
2961
+ if (!t) return;
2962
+ let e = "";
2963
+ const o = this._value.startsWith("#") ? this._value : "#ffffff";
2964
+ e += `
2965
+ <div class="dropdown-item" data-action="solid">
2966
+ <div class="dropdown-item-preview" style="background: #ffffff"></div>
2967
+ <span class="dropdown-item-label">Solid Color</span>
2968
+ <input type="color" class="solid-input" value="${o}">
2969
+ </div>
2970
+ `, this._gradients.forEach((i) => {
2971
+ const s = C(i), r = i.id.startsWith(we), a = r ? `<button class="dropdown-item-btn" data-dup-id="${i.id}" title="Duplicate gradient">&#x2398;</button>` : "", d = r ? "" : `<button class="dropdown-item-btn" data-edit-id="${i.id}" title="Edit gradient">&#9998;</button>`, c = r ? "" : `<button class="dropdown-item-btn delete-btn" data-delete-id="${i.id}" title="Delete gradient">&times;</button>`;
2972
+ e += `
2973
+ <div class="dropdown-item" data-gradient-id="${i.id}">
2974
+ <div class="dropdown-item-preview" style="background: ${s}"></div>
2975
+ <span class="dropdown-item-label">${i.name}</span>
2976
+ ${a}
2977
+ ${d}
2978
+ ${c}
2979
+ </div>
2980
+ `;
2981
+ }), e += `
2982
+ <div class="dropdown-item dropdown-custom" data-action="custom">
2983
+ <span class="dropdown-item-label">Custom Gradient...</span>
2984
+ </div>
2985
+ `, t.innerHTML = e, this._bindDropdown();
2986
+ });
2987
+ /**
2988
+ * Bind event listeners for dropdown items.
2989
+ * @private
2990
+ */
2991
+ n(this, "_bindDropdown", () => {
2992
+ const t = this.$(".dropdown");
2993
+ if (!t) return;
2994
+ const e = t.querySelector('[data-action="solid"]'), o = t.querySelector(".solid-input");
2995
+ e && o && (e.addEventListener("click", (s) => {
2996
+ s.stopPropagation(), o.style.pointerEvents = "auto", o.click();
2997
+ }), o.addEventListener("input", (s) => {
2998
+ this._value = s.target.value, this._gradient = null, this._animationSpeed = 0, this._updatePreview(), this._syncControls(), this._emitChange();
2999
+ }), o.addEventListener("change", () => {
3000
+ o.style.pointerEvents = "none";
3001
+ }), o.addEventListener("click", (s) => s.stopPropagation())), t.querySelectorAll("[data-gradient-id]").forEach((s) => {
3002
+ s.addEventListener("click", (r) => {
3003
+ if (r.target.hasAttribute("data-delete-id") || r.target.hasAttribute("data-edit-id") || r.target.hasAttribute("data-dup-id")) return;
3004
+ const a = this._getById(s.dataset.gradientId);
3005
+ a && (this._gradient = JSON.parse(JSON.stringify(a)), this._value = C(this._gradient), this._updatePreview(), this._syncControls(), this._emitChange(), this._closeDropdown());
3006
+ });
3007
+ }), t.querySelectorAll("[data-dup-id]").forEach((s) => {
3008
+ s.addEventListener("click", (r) => {
3009
+ r.stopPropagation();
3010
+ const a = this._getById(s.dataset.dupId);
3011
+ if (!a) return;
3012
+ const d = {
3013
+ id: N(),
3014
+ name: a.name + " Copy",
3015
+ type: a.type,
3016
+ angle: a.angle,
3017
+ stops: a.stops.map((c) => ({ ...c }))
3018
+ };
3019
+ this._closeDropdown(), this._openEditorDialog(d);
3020
+ });
3021
+ }), t.querySelectorAll("[data-edit-id]").forEach((s) => {
3022
+ s.addEventListener("click", (r) => {
3023
+ r.stopPropagation();
3024
+ const a = this._getById(s.dataset.editId);
3025
+ a && (this._closeDropdown(), this._openEditorDialog(JSON.parse(JSON.stringify(a))));
3026
+ });
3027
+ }), t.querySelectorAll("[data-delete-id]").forEach((s) => {
3028
+ s.addEventListener("click", (r) => {
3029
+ r.stopPropagation(), this._delete(s.dataset.deleteId), this._populateDropdown();
3030
+ });
3031
+ });
3032
+ const i = t.querySelector('[data-action="custom"]');
3033
+ i && i.addEventListener("click", (s) => {
3034
+ s.stopPropagation(), this._closeDropdown(), this._openEditorDialog();
3035
+ });
3036
+ });
3037
+ /**
3038
+ * Open the editor modal with a gradient to edit.
3039
+ * @private
3040
+ * @param {Object} [existingGradient] - Gradient to edit; omit to create new
3041
+ */
3042
+ n(this, "_openEditorDialog", (t) => {
3043
+ let e;
3044
+ t ? e = JSON.parse(JSON.stringify(t)) : (e = tt(this._value), e ? (e.id = e.id || N(), e.name = e.name || "Custom Gradient") : e = {
3045
+ id: N(),
3046
+ name: "Custom Gradient",
3047
+ type: "linear",
3048
+ angle: 90,
3049
+ stops: [
3050
+ { color: this._value.startsWith("#") ? this._value : "#000000", position: 0 },
3051
+ { color: "#ffffff", position: 100 }
3052
+ ]
3053
+ }), this._editingGradient = JSON.parse(JSON.stringify(e)), this._editingName = e.name;
3054
+ const o = this.$(".modal-editor");
3055
+ o && (o.gradient = this._editingGradient);
3056
+ const i = this.$(".name-input");
3057
+ i && (i.value = e.name), this._editingOriginalId = e.id;
3058
+ const s = this.$(".editor-modal");
3059
+ s && s.setAttribute("open", "");
3060
+ });
3061
+ /**
3062
+ * Apply the edited gradient from the modal.
3063
+ * @private
3064
+ * @param {boolean} save - Whether to persist to localStorage
3065
+ */
3066
+ n(this, "_applyFromEditor", (t) => {
3067
+ if (!this._editingGradient) return;
3068
+ const e = JSON.parse(JSON.stringify(this._editingGradient));
3069
+ this._editingName && (e.name = this._editingName), e.id = this._editingOriginalId || e.id || N(), t && this._save(e), this._gradient = JSON.parse(JSON.stringify(e)), this._value = C(this._gradient), this._updatePreview(), this._syncControls(), this._emitChange(), this._closeModal();
3070
+ });
3071
+ /**
3072
+ * Close the editor modal.
3073
+ * @private
3074
+ */
3075
+ n(this, "_closeModal", () => {
3076
+ const t = this.$(".editor-modal");
3077
+ t && t.removeAttribute("open"), this._editingGradient = null, this._editingName = "", this._editingOriginalId = null;
3078
+ });
3079
+ /**
3080
+ * Recompute CSS from the current gradient object and emit change.
3081
+ * @private
3082
+ */
3083
+ n(this, "_applyGradient", () => {
3084
+ this._gradient && (this._value = C(this._gradient), this._updatePreview(), this._emitChange());
3085
+ });
3086
+ /**
3087
+ * Emit the wox-gradient-change event with current state.
3088
+ * @private
3089
+ */
3090
+ n(this, "_emitChange", () => {
3091
+ this.emit("wox-gradient-change", {
3092
+ value: this._value,
3093
+ animationSpeed: this._animationSpeed,
3094
+ animationType: this._animationType
3095
+ });
3096
+ });
3097
+ }
3098
+ connectedCallback() {
3099
+ this._loadGradients(), this._syncFromAttributes(), this._build(), this._outsideClickHandler = (t) => {
3100
+ !this._open || this.contains(t.target) || t.composedPath().includes(this) || this._closeDropdown();
3101
+ }, document.addEventListener("click", this._outsideClickHandler);
3102
+ }
3103
+ disconnectedCallback() {
3104
+ this._outsideClickHandler && document.removeEventListener("click", this._outsideClickHandler);
3105
+ }
3106
+ attributeChangedCallback(t) {
3107
+ this.isConnected && (this._syncFromAttributes(), this._updatePreview(), this._syncControls());
3108
+ }
3109
+ }
3110
+ n(St, "observedAttributes", ["value", "animation-speed", "animation-type"]);
3111
+ const ye = [
3112
+ "January",
3113
+ "February",
3114
+ "March",
3115
+ "April",
3116
+ "May",
3117
+ "June",
3118
+ "July",
3119
+ "August",
3120
+ "September",
3121
+ "October",
3122
+ "November",
3123
+ "December"
3124
+ ], ke = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], it = 10, $e = `
3125
+ :host {
3126
+ display: block;
3127
+ width: 280px;
3128
+ background: var(--wox-bg-panel, #17171a);
3129
+ border: 1px solid var(--wox-border, #333);
3130
+ border-radius: var(--wox-radius-md, 6px);
3131
+ box-shadow: var(--wox-shadow-md, 0 4px 16px rgba(0,0,0,0.4));
3132
+ padding: 12px;
3133
+ user-select: none;
3134
+ font-family: var(--wox-font, 'Inter', sans-serif);
3135
+ font-size: var(--wox-font-size-base, 12px);
3136
+ color: var(--wox-text-primary, #eee);
3137
+ }
3138
+
3139
+ .header {
3140
+ display: flex;
3141
+ align-items: center;
3142
+ justify-content: space-between;
3143
+ margin-bottom: 10px;
3144
+ }
3145
+
3146
+ .month-year {
3147
+ display: flex;
3148
+ align-items: center;
3149
+ gap: 4px;
3150
+ font-weight: 600;
3151
+ font-size: 13px;
3152
+ color: var(--wox-text-primary, #eee);
3153
+ }
3154
+
3155
+ .year-select {
3156
+ background: transparent;
3157
+ border: none;
3158
+ color: var(--wox-text-primary, #eee);
3159
+ font-size: 13px;
3160
+ font-weight: 600;
3161
+ font-family: var(--wox-font, sans-serif);
3162
+ cursor: pointer;
3163
+ padding: 2px 4px;
3164
+ border-radius: var(--wox-radius-md, 6px);
3165
+ outline: none;
3166
+ }
3167
+
3168
+ .year-select:hover {
3169
+ background: var(--wox-bg-hover, #2a2a2e);
3170
+ }
3171
+
3172
+ .year-select option {
3173
+ background: var(--wox-bg-panel, #17171a);
3174
+ color: var(--wox-text-primary, #eee);
3175
+ }
3176
+
3177
+ .nav-btn {
3178
+ background: none;
3179
+ border: none;
3180
+ cursor: pointer;
3181
+ color: var(--wox-text-secondary, #999);
3182
+ width: 26px;
3183
+ height: 26px;
3184
+ border-radius: var(--wox-radius-md, 6px);
3185
+ display: flex;
3186
+ align-items: center;
3187
+ justify-content: center;
3188
+ font-size: 16px;
3189
+ line-height: 1;
3190
+ transition: background 0.12s, color 0.12s;
3191
+ padding: 0;
3192
+ }
3193
+
3194
+ .nav-btn:hover {
3195
+ background: var(--wox-bg-hover, #2a2a2e);
3196
+ color: var(--wox-text-primary, #eee);
3197
+ }
3198
+
3199
+ .day-headers {
3200
+ display: grid;
3201
+ grid-template-columns: repeat(7, 1fr);
3202
+ margin-bottom: 2px;
3203
+ }
3204
+
3205
+ .day-header {
3206
+ text-align: center;
3207
+ font-size: 10px;
3208
+ font-weight: 600;
3209
+ color: var(--wox-text-secondary, #999);
3210
+ padding: 4px 0;
3211
+ }
3212
+
3213
+ .calendar-grid {
3214
+ display: grid;
3215
+ grid-template-columns: repeat(7, 1fr);
3216
+ gap: 1px;
3217
+ }
3218
+
3219
+ .day-cell {
3220
+ aspect-ratio: 1;
3221
+ display: flex;
3222
+ align-items: center;
3223
+ justify-content: center;
3224
+ font-size: 11px;
3225
+ border-radius: var(--wox-radius-md, 6px);
3226
+ cursor: pointer;
3227
+ transition: background 0.1s, color 0.1s;
3228
+ color: var(--wox-text-primary, #eee);
3229
+ position: relative;
3230
+ }
3231
+
3232
+ .day-cell:hover {
3233
+ background: var(--wox-bg-hover, #2a2a2e);
3234
+ }
3235
+
3236
+ .day-cell.other-month {
3237
+ color: var(--wox-text-secondary, #999);
3238
+ opacity: 0.4;
3239
+ }
3240
+
3241
+ .day-cell.today {
3242
+ outline: 1px solid var(--wox-accent, #00e5ff);
3243
+ outline-offset: -1px;
3244
+ color: var(--wox-accent, #00e5ff);
3245
+ font-weight: 600;
3246
+ }
3247
+
3248
+ .day-cell.selected {
3249
+ background: var(--wox-accent, #00e5ff);
3250
+ color: #000;
3251
+ font-weight: 600;
3252
+ }
3253
+
3254
+ .day-cell.selected:hover {
3255
+ background: var(--wox-accent, #00e5ff);
3256
+ }
3257
+
3258
+ .day-cell.range-start,
3259
+ .day-cell.range-end {
3260
+ background: var(--wox-accent, #00e5ff);
3261
+ color: #000;
3262
+ font-weight: 600;
3263
+ }
3264
+
3265
+ .day-cell.range-start:hover,
3266
+ .day-cell.range-end:hover {
3267
+ background: var(--wox-accent, #00e5ff);
3268
+ }
3269
+
3270
+ .day-cell.in-range {
3271
+ background: rgba(0, 229, 255, 0.15);
3272
+ border-radius: 0;
3273
+ }
3274
+
3275
+ .day-cell.range-start { border-radius: var(--wox-radius-md, 6px) 0 0 var(--wox-radius-md, 6px); }
3276
+ .day-cell.range-end { border-radius: 0 var(--wox-radius-md, 6px) var(--wox-radius-md, 6px) 0; }
3277
+
3278
+ .day-cell.range-hover {
3279
+ background: rgba(0, 229, 255, 0.08);
3280
+ }
3281
+
3282
+ .day-cell.disabled {
3283
+ pointer-events: none;
3284
+ opacity: 0.25;
3285
+ }
3286
+
3287
+ .footer {
3288
+ display: flex;
3289
+ justify-content: space-between;
3290
+ align-items: center;
3291
+ margin-top: 10px;
3292
+ gap: 8px;
3293
+ }
3294
+
3295
+ .mode-hint {
3296
+ font-size: 10px;
3297
+ color: var(--wox-text-secondary, #999);
3298
+ flex: 1;
3299
+ }
3300
+
3301
+ .today-btn {
3302
+ background: none;
3303
+ border: 1px solid var(--wox-border, #333);
3304
+ border-radius: var(--wox-radius-md, 6px);
3305
+ color: var(--wox-text-secondary, #999);
3306
+ font-size: 10px;
3307
+ font-family: var(--wox-font, sans-serif);
3308
+ cursor: pointer;
3309
+ padding: 3px 8px;
3310
+ transition: background 0.12s, color 0.12s, border-color 0.12s;
3311
+ }
3312
+
3313
+ .today-btn:hover {
3314
+ background: var(--wox-bg-hover, #2a2a2e);
3315
+ color: var(--wox-accent, #00e5ff);
3316
+ border-color: var(--wox-accent, #00e5ff);
3317
+ }
3318
+
3319
+ :host([disabled]) {
3320
+ opacity: 0.4;
3321
+ pointer-events: none;
3322
+ }
3323
+ `;
3324
+ class Lt extends v {
3325
+ constructor() {
3326
+ super(...arguments);
3327
+ /** @type {Date} Currently viewed month/year */
3328
+ n(this, "_currentDate", /* @__PURE__ */ new Date());
3329
+ /** @type {string|null} Selected date in single mode (YYYY-MM-DD) */
3330
+ n(this, "_selectedDate", null);
3331
+ /** @type {{ start: string|null, end: string|null }} */
3332
+ n(this, "_selectedRange", { start: null, end: null });
3333
+ // ── Private ─────────────────────────────────────────────────────────────────
3334
+ /** @private */
3335
+ n(this, "_navigateMonth", (t) => {
3336
+ const e = this._currentDate.getFullYear(), o = this._currentDate.getMonth() + t;
3337
+ this._currentDate = new Date(e, o, 1), this._render();
3338
+ });
3339
+ /** @private */
3340
+ n(this, "_navigateToYear", (t) => {
3341
+ this._currentDate = new Date(t, this._currentDate.getMonth(), 1), this._render();
3342
+ });
3343
+ /** @private */
3344
+ n(this, "_goToday", () => {
3345
+ const t = /* @__PURE__ */ new Date(), e = st(t);
3346
+ this._currentDate = new Date(t.getFullYear(), t.getMonth(), 1), this.rangeMode ? this._selectedRange = { start: e, end: null } : (this._selectedDate = e, this.emit("wox-change", { date: e })), this._render();
3347
+ });
3348
+ /** @private */
3349
+ n(this, "_handleDayClick", (t) => {
3350
+ const e = t.dataset.date;
3351
+ if (e) {
3352
+ if (t.classList.contains("other-month")) {
3353
+ const o = P(e);
3354
+ this._currentDate = new Date(o.getFullYear(), o.getMonth(), 1);
3355
+ }
3356
+ this.rangeMode ? this._handleRangeSelection(e) : (this._selectedDate = e, this.emit("wox-change", { date: e }), this._render());
3357
+ }
3358
+ });
3359
+ /** @private */
3360
+ n(this, "_handleRangeSelection", (t) => {
3361
+ !this._selectedRange.start || this._selectedRange.end ? this._selectedRange = { start: t, end: null } : (t < this._selectedRange.start ? this._selectedRange = { start: t, end: this._selectedRange.start } : this._selectedRange.end = t, this.emit("wox-change", { start: this._selectedRange.start, end: this._selectedRange.end })), this._render();
3362
+ });
3363
+ /** @private DOM manipulation only — no re-render */
3364
+ n(this, "_updateRangeHover", (t) => {
3365
+ if (!t) return;
3366
+ const e = this._selectedRange.start;
3367
+ this.$$(".day-cell:not(.other-month)").forEach((o) => {
3368
+ const i = o.dataset.date;
3369
+ o.classList.toggle("range-hover", i > e && i <= t);
3370
+ });
3371
+ });
3372
+ /** @private */
3373
+ n(this, "_clearRangeHover", () => {
3374
+ this.$$(".day-cell.range-hover").forEach((t) => t.classList.remove("range-hover"));
3375
+ });
3376
+ /** @private */
3377
+ n(this, "_generateYearOptions", (t) => {
3378
+ let e = "";
3379
+ for (let o = t - it; o <= t + it; o++)
3380
+ e += `<option value="${o}"${o === t ? " selected" : ""}>${o}</option>`;
3381
+ return e;
3382
+ });
3383
+ /** @private */
3384
+ n(this, "_generateGrid", (t, e) => {
3385
+ const i = st(/* @__PURE__ */ new Date()), s = new Date(t, e, 1).getDay(), r = new Date(t, e + 1, 0).getDate();
3386
+ let a = "";
3387
+ const d = e === 0 ? t - 1 : t, c = e === 0 ? 11 : e - 1, u = new Date(d, c + 1, 0).getDate();
3388
+ for (let b = s - 1; b >= 0; b--) {
3389
+ const f = u - b, w = j(d, c, f);
3390
+ a += `<div class="day-cell other-month" data-date="${w}">${f}</div>`;
3391
+ }
3392
+ for (let b = 1; b <= r; b++) {
3393
+ const f = j(t, e, b);
3394
+ let w = "day-cell";
3395
+ f === i && (w += " today"), this.rangeMode ? this._selectedRange.start && f === this._selectedRange.start ? w += " range-start" : this._selectedRange.end && f === this._selectedRange.end ? w += " range-end" : Ee(f, this._selectedRange.start, this._selectedRange.end) && (w += " in-range") : this._selectedDate && f === this._selectedDate && (w += " selected"), a += `<div class="${w}" data-date="${f}">${b}</div>`;
3396
+ }
3397
+ const h = Math.ceil((s + r) / 7) * 7, x = e === 11 ? t + 1 : t, g = e === 11 ? 0 : e + 1;
3398
+ for (let b = 1; b <= h - s - r; b++) {
3399
+ const f = j(x, g, b);
3400
+ a += `<div class="day-cell other-month" data-date="${f}">${b}</div>`;
3401
+ }
3402
+ return a;
3403
+ });
3404
+ /** @private */
3405
+ n(this, "_getModeHint", () => this.rangeMode ? this._selectedRange.start ? this._selectedRange.end ? `${this._selectedRange.start} → ${this._selectedRange.end}` : "Select end date" : "Select start date" : "Select a date");
3406
+ /** @private */
3407
+ n(this, "_render", () => {
3408
+ const t = this._currentDate.getFullYear(), e = this._currentDate.getMonth();
3409
+ this.render($e, `
3410
+ <div class="header">
3411
+ <button class="nav-btn" id="prev-month">&#8249;</button>
3412
+ <div class="month-year">
3413
+ ${ye[e]}
3414
+ <select class="year-select">${this._generateYearOptions(t)}</select>
3415
+ </div>
3416
+ <button class="nav-btn" id="next-month">&#8250;</button>
3417
+ </div>
3418
+ <div class="day-headers">
3419
+ ${ke.map((o) => `<div class="day-header">${o}</div>`).join("")}
3420
+ </div>
3421
+ <div class="calendar-grid">
3422
+ ${this._generateGrid(t, e)}
3423
+ </div>
3424
+ <div class="footer">
3425
+ <span class="mode-hint">${this._getModeHint()}</span>
3426
+ <button class="today-btn">Today</button>
3427
+ </div>
3428
+ `);
3429
+ });
3430
+ }
3431
+ connectedCallback() {
3432
+ this._boundShadowClick = (t) => {
3433
+ if (this.hasAttribute("disabled")) return;
3434
+ const e = t.target.closest("button");
3435
+ if (e) {
3436
+ if (e.id === "prev-month") {
3437
+ this._navigateMonth(-1);
3438
+ return;
3439
+ }
3440
+ if (e.id === "next-month") {
3441
+ this._navigateMonth(1);
3442
+ return;
3443
+ }
3444
+ if (e.classList.contains("today-btn")) {
3445
+ this._goToday();
3446
+ return;
3447
+ }
3448
+ }
3449
+ const o = t.target.closest(".day-cell");
3450
+ if (o) {
3451
+ this._handleDayClick(o);
3452
+ return;
3453
+ }
3454
+ }, this._boundShadowChange = (t) => {
3455
+ t.target.classList.contains("year-select") && this._navigateToYear(parseInt(t.target.value, 10));
3456
+ }, this._boundShadowMouseover = (t) => {
3457
+ if (!this.hasAttribute("range-mode")) return;
3458
+ const e = t.target.closest(".day-cell");
3459
+ e && this._selectedRange.start && !this._selectedRange.end && this._updateRangeHover(e.dataset.date);
3460
+ }, this._boundShadowMouseleave = () => {
3461
+ this._clearRangeHover();
3462
+ }, this.shadowRoot.addEventListener("click", this._boundShadowClick), this.shadowRoot.addEventListener("change", this._boundShadowChange), this.shadowRoot.addEventListener("mouseover", this._boundShadowMouseover), this.addEventListener("mouseleave", this._boundShadowMouseleave), this._render();
3463
+ }
3464
+ disconnectedCallback() {
3465
+ this.shadowRoot.removeEventListener("click", this._boundShadowClick), this.shadowRoot.removeEventListener("change", this._boundShadowChange), this.shadowRoot.removeEventListener("mouseover", this._boundShadowMouseover), this.removeEventListener("mouseleave", this._boundShadowMouseleave);
3466
+ }
3467
+ attributeChangedCallback(t, e, o) {
3468
+ if (!(e === o || !this.isConnected)) {
3469
+ if (t === "range-mode")
3470
+ this._selectedDate = null, this._selectedRange = { start: null, end: null };
3471
+ else if (t === "value" && o !== null) {
3472
+ this._selectedDate = o;
3473
+ const i = P(o);
3474
+ isNaN(i) || (this._currentDate = new Date(i.getFullYear(), i.getMonth(), 1));
3475
+ } else t === "range-start" ? this._selectedRange.start = o : t === "range-end" && (this._selectedRange.end = o);
3476
+ this._render();
3477
+ }
3478
+ }
3479
+ // ── Getters / Setters ───────────────────────────────────────────────────────
3480
+ /** @type {boolean} Enables range selection mode. */
3481
+ get rangeMode() {
3482
+ return this.hasAttribute("range-mode");
3483
+ }
3484
+ set rangeMode(t) {
3485
+ t ? this.setAttribute("range-mode", "") : this.removeAttribute("range-mode");
3486
+ }
3487
+ /** @type {boolean} Disables all interaction. */
3488
+ get disabled() {
3489
+ return this.hasAttribute("disabled");
3490
+ }
3491
+ set disabled(t) {
3492
+ t ? this.setAttribute("disabled", "") : this.removeAttribute("disabled");
3493
+ }
3494
+ // ── Public API ──────────────────────────────────────────────────────────────
3495
+ /**
3496
+ * Selects a date in single mode and navigates to its month.
3497
+ * @param {string} dateStr - YYYY-MM-DD
3498
+ */
3499
+ setDate(t) {
3500
+ if (this.rangeMode) return;
3501
+ this._selectedDate = t;
3502
+ const e = P(t);
3503
+ isNaN(e) || (this._currentDate = new Date(e.getFullYear(), e.getMonth(), 1)), this._render();
3504
+ }
3505
+ /**
3506
+ * Sets both range endpoints and navigates to the start month.
3507
+ * @param {string} start - YYYY-MM-DD
3508
+ * @param {string} end - YYYY-MM-DD
3509
+ */
3510
+ setRange(t, e) {
3511
+ if (!this.rangeMode) return;
3512
+ this._selectedRange = { start: t, end: e };
3513
+ const o = P(t);
3514
+ this._currentDate = new Date(o.getFullYear(), o.getMonth(), 1), this._render();
3515
+ }
3516
+ /** @returns {string|null} */
3517
+ getSelectedDate() {
3518
+ return this._selectedDate;
3519
+ }
3520
+ /** @returns {{ start: string|null, end: string|null }} */
3521
+ getSelectedRange() {
3522
+ return { ...this._selectedRange };
3523
+ }
3524
+ /** Clears selection and re-renders. */
3525
+ clear() {
3526
+ this._selectedDate = null, this._selectedRange = { start: null, end: null }, this._render();
3527
+ }
3528
+ }
3529
+ n(Lt, "observedAttributes", ["range-mode", "value", "range-start", "range-end", "disabled"]);
3530
+ const st = (l) => `${l.getFullYear()}-${String(l.getMonth() + 1).padStart(2, "0")}-${String(l.getDate()).padStart(2, "0")}`, P = (l) => {
3531
+ const [p, t, e] = l.split("-").map(Number);
3532
+ return new Date(p, t - 1, e);
3533
+ }, j = (l, p, t) => `${l}-${String(p + 1).padStart(2, "0")}-${String(t).padStart(2, "0")}`, Ee = (l, p, t) => !p || !t ? !1 : l > p && l < t;
3534
+ customElements.define("wox-icon", nt);
3535
+ customElements.define("wox-separator", rt);
3536
+ customElements.define("wox-badge", at);
3537
+ customElements.define("wox-button", lt);
3538
+ customElements.define("wox-input", dt);
3539
+ customElements.define("wox-select", ct);
3540
+ customElements.define("wox-slider", pt);
3541
+ customElements.define("wox-color-swatch", ht);
3542
+ customElements.define("wox-tooltip", xt);
3543
+ customElements.define("wox-color-picker", ut);
3544
+ customElements.define("wox-menu-item", gt);
3545
+ customElements.define("wox-menu", bt);
3546
+ customElements.define("wox-layer-item", ft);
3547
+ customElements.define("wox-section", vt);
3548
+ customElements.define("wox-tab", wt);
3549
+ customElements.define("wox-tabs", mt);
3550
+ customElements.define("wox-toolbar-group", _t);
3551
+ customElements.define("wox-toolbar", yt);
3552
+ customElements.define("wox-panel", kt);
3553
+ customElements.define("wox-menubar", $t);
3554
+ customElements.define("wox-statusbar", Et);
3555
+ customElements.define("wox-modal", Ct);
3556
+ customElements.define("wox-datagrid", ne);
3557
+ customElements.define("wox-toast", R);
3558
+ customElements.define("wox-context-menu", G);
3559
+ customElements.define("wox-gradient-editor", ve);
3560
+ customElements.define("wox-gradient-selector", St);
3561
+ customElements.define("wox-date-picker", Lt);
3562
+ const Ce = () => {
4
3563
  if (document.getElementById("wox-theme")) return;
5
- const o = document.createElement("style");
6
- o.id = "wox-theme", o.textContent = e, document.head.appendChild(o);
7
- }, e = `/* wox-theme.css — Global CSS custom properties for the WOX component library */
3564
+ const l = document.createElement("style");
3565
+ l.id = "wox-theme", l.textContent = Ae, document.head.appendChild(l);
3566
+ }, Ae = `/* wox-theme.css — Global CSS custom properties for the WOX component library */
8
3567
  :root {
9
3568
  --wox-bg-app: #121214;
10
3569
  --wox-bg-panel: #17171a;
@@ -62,38 +3621,38 @@ const x = () => {
62
3621
  --wox-shadow-section: inset 0 -12px 24px -12px rgba(0, 0, 0, 0.5);
63
3622
  --wox-shadow-accent: 0 0 10px rgba(0, 229, 255, 0.3);
64
3623
  }`;
65
- x();
3624
+ Ce();
66
3625
  export {
67
- r as FX_STYLES,
68
- w as WoxBadge,
69
- n as WoxButton,
70
- p as WoxColorPicker,
71
- i as WoxColorSwatch,
72
- c as WoxContextMenu,
73
- d as WoxDatagrid,
74
- l as WoxDatePicker,
75
- b as WoxElement,
76
- m as WoxGradientEditor,
77
- W as WoxGradientSelector,
78
- u as WoxIcon,
79
- g as WoxInput,
80
- f as WoxLayerItem,
81
- h as WoxMenu,
82
- S as WoxMenuItem,
83
- z as WoxMenubar,
84
- T as WoxModal,
85
- C as WoxPanel,
86
- y as WoxSection,
87
- E as WoxSelect,
88
- I as WoxSeparator,
89
- M as WoxSlider,
90
- G as WoxStatusbar,
91
- v as WoxTab,
92
- B as WoxTabs,
93
- P as WoxToast,
94
- _ as WoxToolbar,
95
- k as WoxToolbarGroup,
96
- D as WoxTooltip,
97
- L as cssToGradient,
98
- X as gradientToCSS
3626
+ M as FX_STYLES,
3627
+ at as WoxBadge,
3628
+ lt as WoxButton,
3629
+ ut as WoxColorPicker,
3630
+ ht as WoxColorSwatch,
3631
+ G as WoxContextMenu,
3632
+ ne as WoxDatagrid,
3633
+ Lt as WoxDatePicker,
3634
+ v as WoxElement,
3635
+ ve as WoxGradientEditor,
3636
+ St as WoxGradientSelector,
3637
+ nt as WoxIcon,
3638
+ dt as WoxInput,
3639
+ ft as WoxLayerItem,
3640
+ bt as WoxMenu,
3641
+ gt as WoxMenuItem,
3642
+ $t as WoxMenubar,
3643
+ Ct as WoxModal,
3644
+ kt as WoxPanel,
3645
+ vt as WoxSection,
3646
+ ct as WoxSelect,
3647
+ rt as WoxSeparator,
3648
+ pt as WoxSlider,
3649
+ Et as WoxStatusbar,
3650
+ wt as WoxTab,
3651
+ mt as WoxTabs,
3652
+ R as WoxToast,
3653
+ yt as WoxToolbar,
3654
+ _t as WoxToolbarGroup,
3655
+ xt as WoxTooltip,
3656
+ tt as cssToGradient,
3657
+ C as gradientToCSS
99
3658
  };