@dogsbay/elements 0.2.0-beta.12 → 0.2.0-beta.120
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{base-BtvRtAsC.d.ts → base-D1Rz70fn.d.ts} +1 -0
- package/dist/chunk-3AEQ6KHV.js +70 -0
- package/dist/chunk-3AEQ6KHV.js.map +1 -0
- package/dist/chunk-3FMXAKOU.js +383 -0
- package/dist/chunk-3FMXAKOU.js.map +1 -0
- package/dist/{chunk-LVXR7KTB.js → chunk-4YPDR3W6.js} +41 -12
- package/dist/chunk-4YPDR3W6.js.map +1 -0
- package/dist/{chunk-7M7SFLKN.js → chunk-CLUADA3G.js} +5 -3
- package/dist/chunk-CLUADA3G.js.map +1 -0
- package/dist/chunk-EGU66XCL.js +116 -0
- package/dist/chunk-EGU66XCL.js.map +1 -0
- package/dist/{chunk-7BIVQSGP.js → chunk-ETBBSA3I.js} +5 -3
- package/dist/chunk-ETBBSA3I.js.map +1 -0
- package/dist/chunk-FIJZRZEN.js +90 -0
- package/dist/chunk-FIJZRZEN.js.map +1 -0
- package/dist/chunk-K6DPDBAG.js +72 -0
- package/dist/chunk-K6DPDBAG.js.map +1 -0
- package/dist/{chunk-TTNTPXBA.js → chunk-LAUNXWKJ.js} +5 -3
- package/dist/chunk-LAUNXWKJ.js.map +1 -0
- package/dist/chunk-MAD6XJY4.js +256 -0
- package/dist/chunk-MAD6XJY4.js.map +1 -0
- package/dist/chunk-MEOIAZDF.js +140 -0
- package/dist/chunk-MEOIAZDF.js.map +1 -0
- package/dist/{chunk-LFXZQ4YV.js → chunk-QSRUT67Y.js} +5 -3
- package/dist/chunk-QSRUT67Y.js.map +1 -0
- package/dist/chunk-S62ZVVO3.js +234 -0
- package/dist/chunk-S62ZVVO3.js.map +1 -0
- package/dist/chunk-SLJG53M7.js +208 -0
- package/dist/chunk-SLJG53M7.js.map +1 -0
- package/dist/{chunk-FWAAU5UY.js → chunk-V4P3UR4I.js} +5 -3
- package/dist/chunk-V4P3UR4I.js.map +1 -0
- package/dist/{chunk-5T4OXQA2.js → chunk-VW7HZY2B.js} +6 -6
- package/dist/chunk-VW7HZY2B.js.map +1 -0
- package/dist/db-accordion.d.ts +1 -1
- package/dist/db-accordion.js +2 -2
- package/dist/db-card.d.ts +1 -1
- package/dist/db-card.js +2 -2
- package/dist/db-code-block.d.ts +1 -1
- package/dist/db-code-block.js +2 -2
- package/dist/db-collapsible.d.ts +1 -1
- package/dist/db-collapsible.js +2 -2
- package/dist/db-combobox.d.ts +70 -0
- package/dist/db-combobox.js +9 -0
- package/dist/db-combobox.js.map +1 -0
- package/dist/db-dialog.d.ts +62 -0
- package/dist/db-dialog.js +9 -0
- package/dist/db-dialog.js.map +1 -0
- package/dist/db-link-button.d.ts +1 -1
- package/dist/db-link-button.js +2 -2
- package/dist/db-nav-tree.d.ts +83 -0
- package/dist/db-nav-tree.js +9 -0
- package/dist/db-nav-tree.js.map +1 -0
- package/dist/db-popover.d.ts +42 -0
- package/dist/db-popover.js +9 -0
- package/dist/db-popover.js.map +1 -0
- package/dist/db-select.d.ts +72 -0
- package/dist/db-select.js +9 -0
- package/dist/db-select.js.map +1 -0
- package/dist/db-steps.d.ts +1 -1
- package/dist/db-steps.js +2 -2
- package/dist/db-tabs.d.ts +28 -1
- package/dist/db-tabs.js +2 -2
- package/dist/db-toc.d.ts +32 -0
- package/dist/db-toc.js +8 -0
- package/dist/db-toc.js.map +1 -0
- package/dist/db-tooltip.d.ts +48 -0
- package/dist/db-tooltip.js +9 -0
- package/dist/db-tooltip.js.map +1 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +40 -11
- package/package.json +34 -6
- package/dist/chunk-5T4OXQA2.js.map +0 -1
- package/dist/chunk-7BIVQSGP.js.map +0 -1
- package/dist/chunk-7M7SFLKN.js.map +0 -1
- package/dist/chunk-FWAAU5UY.js.map +0 -1
- package/dist/chunk-LFXZQ4YV.js.map +0 -1
- package/dist/chunk-LVXR7KTB.js.map +0 -1
- package/dist/chunk-TTNTPXBA.js.map +0 -1
- package/dist/chunk-XBMLE4N3.js +0 -28
- package/dist/chunk-XBMLE4N3.js.map +0 -1
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isDisabled,
|
|
3
|
+
ownOne,
|
|
4
|
+
uid
|
|
5
|
+
} from "./chunk-3AEQ6KHV.js";
|
|
6
|
+
import {
|
|
7
|
+
DogsbayElement,
|
|
8
|
+
ensureDefaultDisplay
|
|
9
|
+
} from "./chunk-K6DPDBAG.js";
|
|
10
|
+
|
|
11
|
+
// src/db-combobox.ts
|
|
12
|
+
var DbCombobox = class extends DogsbayElement {
|
|
13
|
+
input = null;
|
|
14
|
+
listbox = null;
|
|
15
|
+
empty = null;
|
|
16
|
+
_open = false;
|
|
17
|
+
highlighted = null;
|
|
18
|
+
observer = null;
|
|
19
|
+
base = uid("db-combobox");
|
|
20
|
+
optionSeq = 0;
|
|
21
|
+
get open() {
|
|
22
|
+
return this._open;
|
|
23
|
+
}
|
|
24
|
+
get inline() {
|
|
25
|
+
return this.hasAttribute("inline");
|
|
26
|
+
}
|
|
27
|
+
get filtering() {
|
|
28
|
+
return (this.getAttribute("filter") ?? "contains") !== "none";
|
|
29
|
+
}
|
|
30
|
+
/** All options, in order. Read live, so page-supplied results are always current. */
|
|
31
|
+
options() {
|
|
32
|
+
if (!this.listbox) return [];
|
|
33
|
+
return Array.from(this.listbox.querySelectorAll("[data-part='option']")).filter((o) => o.closest("db-combobox") === this);
|
|
34
|
+
}
|
|
35
|
+
visible() {
|
|
36
|
+
return this.options().filter((o) => !o.hidden && !isDisabled(o));
|
|
37
|
+
}
|
|
38
|
+
setup() {
|
|
39
|
+
this.input = ownOne(this, "[data-part='input']");
|
|
40
|
+
this.listbox = ownOne(this, "[data-part='listbox']");
|
|
41
|
+
this.empty = ownOne(this, "[data-part='empty']");
|
|
42
|
+
if (!this.input || !this.listbox) return;
|
|
43
|
+
const { input, listbox } = this;
|
|
44
|
+
listbox.id ||= `${this.base}-listbox`;
|
|
45
|
+
listbox.setAttribute("role", "listbox");
|
|
46
|
+
input.setAttribute("role", "combobox");
|
|
47
|
+
input.setAttribute("aria-autocomplete", "list");
|
|
48
|
+
input.setAttribute("aria-controls", listbox.id);
|
|
49
|
+
input.setAttribute("autocomplete", "off");
|
|
50
|
+
if (!this.inline) listbox.hidden = true;
|
|
51
|
+
this.prepareOptions();
|
|
52
|
+
this.syncExpanded();
|
|
53
|
+
}
|
|
54
|
+
prepareOptions() {
|
|
55
|
+
this.options().forEach((o) => {
|
|
56
|
+
o.id ||= `${this.base}-option-${++this.optionSeq}`;
|
|
57
|
+
o.setAttribute("role", "option");
|
|
58
|
+
if (!o.hasAttribute("aria-selected")) o.setAttribute("aria-selected", "false");
|
|
59
|
+
if (o.matches("a[href], button")) o.setAttribute("tabindex", "-1");
|
|
60
|
+
o.querySelectorAll("a, button").forEach((el) => el.setAttribute("tabindex", "-1"));
|
|
61
|
+
if (o.parentElement && o.parentElement !== this.listbox && o.parentElement.localName === "li" && !o.parentElement.hasAttribute("role")) {
|
|
62
|
+
o.parentElement.setAttribute("role", "none");
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
onInput = () => {
|
|
67
|
+
if (this.filtering) this.filter(this.input.value);
|
|
68
|
+
else this.show();
|
|
69
|
+
};
|
|
70
|
+
onFocus = () => {
|
|
71
|
+
if (this.hasAttribute("open-on-focus") || this.filtering && this.input.value) {
|
|
72
|
+
if (this.filtering) this.filter(this.input.value);
|
|
73
|
+
else this.show();
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
onKey = (e) => {
|
|
77
|
+
const vis = this.visible();
|
|
78
|
+
const cur = this.highlighted ? vis.indexOf(this.highlighted) : -1;
|
|
79
|
+
switch (e.key) {
|
|
80
|
+
case "ArrowDown":
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
if (!this._open) this.show();
|
|
83
|
+
if (vis.length) this.highlight(vis[cur < 0 ? 0 : Math.min(cur + 1, vis.length - 1)]);
|
|
84
|
+
break;
|
|
85
|
+
case "ArrowUp":
|
|
86
|
+
e.preventDefault();
|
|
87
|
+
if (!this._open) this.show();
|
|
88
|
+
if (vis.length) this.highlight(vis[cur < 0 ? vis.length - 1 : Math.max(cur - 1, 0)]);
|
|
89
|
+
break;
|
|
90
|
+
case "Home":
|
|
91
|
+
case "End":
|
|
92
|
+
if (this._open && this.highlighted && vis.length) {
|
|
93
|
+
e.preventDefault();
|
|
94
|
+
this.highlight(e.key === "Home" ? vis[0] : vis[vis.length - 1]);
|
|
95
|
+
}
|
|
96
|
+
break;
|
|
97
|
+
case "Enter":
|
|
98
|
+
if (this._open && this.highlighted) {
|
|
99
|
+
e.preventDefault();
|
|
100
|
+
this.choose(this.highlighted);
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
case "Escape":
|
|
104
|
+
if (this._open && !this.inline) {
|
|
105
|
+
e.preventDefault();
|
|
106
|
+
e.stopPropagation();
|
|
107
|
+
this.hide();
|
|
108
|
+
} else if (this.input.value) {
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
e.stopPropagation();
|
|
111
|
+
this.input.value = "";
|
|
112
|
+
this.input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
113
|
+
this.hide();
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
case "Tab":
|
|
117
|
+
if (!this.inline) this.hide();
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
onListClick = (e) => {
|
|
122
|
+
const o = e.target.closest("[data-part='option']");
|
|
123
|
+
if (!o || o.closest("db-combobox") !== this || isDisabled(o)) return;
|
|
124
|
+
const link = e.target.closest("a[href]");
|
|
125
|
+
if (!this.choose(o, !link) && link) e.preventDefault();
|
|
126
|
+
};
|
|
127
|
+
onListPointer = (e) => {
|
|
128
|
+
const o = e.target.closest("[data-part='option']");
|
|
129
|
+
if (o && o.closest("db-combobox") === this && !isDisabled(o) && !o.hidden) this.highlight(o);
|
|
130
|
+
};
|
|
131
|
+
onListDown = (e) => e.preventDefault();
|
|
132
|
+
// keep focus in the input
|
|
133
|
+
onDocDown = (e) => {
|
|
134
|
+
if (this._open && !this.inline && !this.contains(e.target)) this.hide();
|
|
135
|
+
};
|
|
136
|
+
connect() {
|
|
137
|
+
const { input, listbox } = this;
|
|
138
|
+
if (!input || !listbox) return;
|
|
139
|
+
input.addEventListener("input", this.onInput);
|
|
140
|
+
input.addEventListener("focus", this.onFocus);
|
|
141
|
+
input.addEventListener("keydown", this.onKey);
|
|
142
|
+
listbox.addEventListener("click", this.onListClick);
|
|
143
|
+
listbox.addEventListener("pointermove", this.onListPointer);
|
|
144
|
+
listbox.addEventListener("mousedown", this.onListDown);
|
|
145
|
+
document.addEventListener("pointerdown", this.onDocDown);
|
|
146
|
+
if (typeof MutationObserver !== "undefined") {
|
|
147
|
+
this.observer = new MutationObserver(() => this.onOptionsChanged());
|
|
148
|
+
this.observer.observe(listbox, { childList: true, subtree: true });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
disconnect() {
|
|
152
|
+
const { input, listbox } = this;
|
|
153
|
+
input?.removeEventListener("input", this.onInput);
|
|
154
|
+
input?.removeEventListener("focus", this.onFocus);
|
|
155
|
+
input?.removeEventListener("keydown", this.onKey);
|
|
156
|
+
listbox?.removeEventListener("click", this.onListClick);
|
|
157
|
+
listbox?.removeEventListener("pointermove", this.onListPointer);
|
|
158
|
+
listbox?.removeEventListener("mousedown", this.onListDown);
|
|
159
|
+
document.removeEventListener("pointerdown", this.onDocDown);
|
|
160
|
+
this.observer?.disconnect();
|
|
161
|
+
this.observer = null;
|
|
162
|
+
}
|
|
163
|
+
/** Re-scan options after the page replaced them (filter="none"). */
|
|
164
|
+
refresh() {
|
|
165
|
+
this.onOptionsChanged();
|
|
166
|
+
}
|
|
167
|
+
onOptionsChanged() {
|
|
168
|
+
this.prepareOptions();
|
|
169
|
+
if (this.highlighted && !this.options().includes(this.highlighted)) this.clearHighlight();
|
|
170
|
+
const vis = this.visible();
|
|
171
|
+
if (!this.filtering) {
|
|
172
|
+
if (vis.length || this.inline) this.show();
|
|
173
|
+
else this.hide();
|
|
174
|
+
if (vis.length && !this.highlighted && !this.hasAttribute("no-autohighlight")) this.highlight(vis[0]);
|
|
175
|
+
}
|
|
176
|
+
this.syncExpanded();
|
|
177
|
+
this.dispatchEvent(new CustomEvent("db-combobox:update", { detail: { count: vis.length }, bubbles: true }));
|
|
178
|
+
}
|
|
179
|
+
filter(query) {
|
|
180
|
+
const q = query.toLowerCase().trim();
|
|
181
|
+
let count = 0;
|
|
182
|
+
for (const o of this.options()) {
|
|
183
|
+
const hit = !q || (o.textContent ?? "").toLowerCase().includes(q) || (o.dataset.value ?? "").toLowerCase().includes(q);
|
|
184
|
+
o.hidden = !hit;
|
|
185
|
+
if (hit) count++;
|
|
186
|
+
}
|
|
187
|
+
if (this.empty) this.empty.hidden = count > 0 || !q;
|
|
188
|
+
this.clearHighlight();
|
|
189
|
+
if (count || q && this.empty) this.show();
|
|
190
|
+
else this.hide();
|
|
191
|
+
const vis = this.visible();
|
|
192
|
+
if (vis.length && !this.hasAttribute("no-autohighlight")) this.highlight(vis[0]);
|
|
193
|
+
this.dispatchEvent(new CustomEvent("db-combobox:update", { detail: { count }, bubbles: true }));
|
|
194
|
+
}
|
|
195
|
+
syncExpanded() {
|
|
196
|
+
if (!this.input) return;
|
|
197
|
+
const expanded = this.inline ? this.visible().length > 0 : this._open;
|
|
198
|
+
this.input.setAttribute("aria-expanded", String(expanded));
|
|
199
|
+
this.setAttribute("data-state", expanded ? "open" : "closed");
|
|
200
|
+
}
|
|
201
|
+
show() {
|
|
202
|
+
if (!this.listbox || this._open) return this.syncExpanded();
|
|
203
|
+
this._open = true;
|
|
204
|
+
this.listbox.hidden = false;
|
|
205
|
+
this.syncExpanded();
|
|
206
|
+
}
|
|
207
|
+
hide() {
|
|
208
|
+
if (!this.listbox) return;
|
|
209
|
+
this.clearHighlight();
|
|
210
|
+
if (!this._open) return this.syncExpanded();
|
|
211
|
+
this._open = false;
|
|
212
|
+
if (!this.inline) this.listbox.hidden = true;
|
|
213
|
+
this.syncExpanded();
|
|
214
|
+
}
|
|
215
|
+
highlight(o) {
|
|
216
|
+
if (!this.input) return;
|
|
217
|
+
this.highlighted?.removeAttribute("data-highlighted");
|
|
218
|
+
this.highlighted?.setAttribute("aria-selected", "false");
|
|
219
|
+
this.highlighted = o;
|
|
220
|
+
o.setAttribute("data-highlighted", "");
|
|
221
|
+
o.setAttribute("aria-selected", "true");
|
|
222
|
+
this.input.setAttribute("aria-activedescendant", o.id);
|
|
223
|
+
o.scrollIntoView?.({ block: "nearest" });
|
|
224
|
+
}
|
|
225
|
+
clearHighlight() {
|
|
226
|
+
this.highlighted?.removeAttribute("data-highlighted");
|
|
227
|
+
this.highlighted?.setAttribute("aria-selected", "false");
|
|
228
|
+
this.highlighted = null;
|
|
229
|
+
this.input?.removeAttribute("aria-activedescendant");
|
|
230
|
+
}
|
|
231
|
+
/** Returns false when a `db-combobox:select` listener cancelled the choice. */
|
|
232
|
+
choose(o, followLink = true) {
|
|
233
|
+
const value = o.dataset.value ?? "";
|
|
234
|
+
const text = o.textContent?.trim() ?? value;
|
|
235
|
+
const ev = new CustomEvent("db-combobox:select", { detail: { value, text, option: o }, bubbles: true, cancelable: true });
|
|
236
|
+
if (!this.dispatchEvent(ev)) return false;
|
|
237
|
+
const link = o.matches("a[href]") ? o : o.querySelector("a[href]");
|
|
238
|
+
if (link) {
|
|
239
|
+
if (followLink) link.click();
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
if (this.input) this.input.value = o.getAttribute("data-label") ?? text;
|
|
243
|
+
if (!this.inline) this.hide();
|
|
244
|
+
this.dispatchEvent(new CustomEvent("db-combobox:change", { detail: { value, text }, bubbles: true }));
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
ensureDefaultDisplay();
|
|
249
|
+
if (!customElements.get("db-combobox")) {
|
|
250
|
+
customElements.define("db-combobox", DbCombobox);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export {
|
|
254
|
+
DbCombobox
|
|
255
|
+
};
|
|
256
|
+
//# sourceMappingURL=chunk-MAD6XJY4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/db-combobox.ts"],"sourcesContent":["import { DogsbayElement, ensureDefaultDisplay } from \"./base.js\";\nimport { isDisabled, ownOne, uid } from \"./utils.js\";\n\n/**\n * `<db-combobox>` — Editable combobox with a listbox (APG \"Editable\n * Combobox With List Autocomplete\"). Focus stays in the input; the\n * highlighted option is exposed with aria-activedescendant.\n *\n * Parts (same contract as the Astro Combobox):\n * [data-part=\"input\"] text input, role=combobox\n * [data-part=\"listbox\"] role=listbox\n * [data-part=\"option\"] role=option, data-value, data-disabled\n * [data-part=\"empty\"] shown when a query has no matches (optional)\n *\n * Attributes:\n * filter=\"contains\" (default) the element filters its own options by text\n * filter=\"none\" the page supplies options (search results); the element\n * watches the listbox and manages highlight and ARIA\n * inline the listbox is always shown (e.g. inside a search dialog);\n * aria-expanded tracks whether it has options\n * no-autohighlight do not highlight the first option when the list changes\n *\n * Choosing an option dispatches a cancelable `db-combobox:select`\n * (detail: { value, text, option }). If not cancelled, a link option\n * (`<a href data-part=\"option\">`, the accessible shape for results that\n * navigate: ARIA allows role=option on a link, but not a link inside an\n * option) is followed; otherwise the input takes the option's text and\n * `db-combobox:change` fires. Wrap link options in `<li role=\"none\">`.\n *\n * Other events: db-combobox:update (detail: { count }) when the visible options change.\n */\nexport class DbCombobox extends DogsbayElement {\n private input: HTMLInputElement | null = null;\n private listbox: HTMLElement | null = null;\n private empty: HTMLElement | null = null;\n private _open = false;\n private highlighted: HTMLElement | null = null;\n private observer: MutationObserver | null = null;\n private base = uid(\"db-combobox\");\n private optionSeq = 0;\n\n get open(): boolean {\n return this._open;\n }\n\n private get inline(): boolean {\n return this.hasAttribute(\"inline\");\n }\n\n private get filtering(): boolean {\n return (this.getAttribute(\"filter\") ?? \"contains\") !== \"none\";\n }\n\n /** All options, in order. Read live, so page-supplied results are always current. */\n options(): HTMLElement[] {\n if (!this.listbox) return [];\n return Array.from(this.listbox.querySelectorAll<HTMLElement>(\"[data-part='option']\")).filter((o) => o.closest(\"db-combobox\") === this);\n }\n\n private visible(): HTMLElement[] {\n return this.options().filter((o) => !o.hidden && !isDisabled(o));\n }\n\n protected setup() {\n this.input = ownOne<HTMLInputElement>(this, \"[data-part='input']\");\n this.listbox = ownOne(this, \"[data-part='listbox']\");\n this.empty = ownOne(this, \"[data-part='empty']\");\n if (!this.input || !this.listbox) return;\n const { input, listbox } = this;\n listbox.id ||= `${this.base}-listbox`;\n listbox.setAttribute(\"role\", \"listbox\");\n input.setAttribute(\"role\", \"combobox\");\n input.setAttribute(\"aria-autocomplete\", \"list\");\n input.setAttribute(\"aria-controls\", listbox.id);\n input.setAttribute(\"autocomplete\", \"off\");\n if (!this.inline) listbox.hidden = true;\n this.prepareOptions();\n this.syncExpanded();\n }\n\n private prepareOptions() {\n this.options().forEach((o) => {\n // A running counter, not the index: page-supplied options come and go, and a\n // reused id would point aria-activedescendant at the wrong option.\n o.id ||= `${this.base}-option-${++this.optionSeq}`;\n o.setAttribute(\"role\", \"option\");\n if (!o.hasAttribute(\"aria-selected\")) o.setAttribute(\"aria-selected\", \"false\");\n // Options are reached through the combobox, not by Tab.\n if (o.matches(\"a[href], button\")) o.setAttribute(\"tabindex\", \"-1\");\n o.querySelectorAll(\"a, button\").forEach((el) => el.setAttribute(\"tabindex\", \"-1\"));\n if (o.parentElement && o.parentElement !== this.listbox && o.parentElement.localName === \"li\" && !o.parentElement.hasAttribute(\"role\")) {\n o.parentElement.setAttribute(\"role\", \"none\");\n }\n });\n }\n\n private onInput = () => {\n if (this.filtering) this.filter(this.input!.value);\n else this.show();\n };\n\n private onFocus = () => {\n if (this.hasAttribute(\"open-on-focus\") || (this.filtering && this.input!.value)) {\n if (this.filtering) this.filter(this.input!.value);\n else this.show();\n }\n };\n\n private onKey = (e: KeyboardEvent) => {\n const vis = this.visible();\n const cur = this.highlighted ? vis.indexOf(this.highlighted) : -1;\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n if (!this._open) this.show();\n if (vis.length) this.highlight(vis[cur < 0 ? 0 : Math.min(cur + 1, vis.length - 1)]);\n break;\n case \"ArrowUp\":\n e.preventDefault();\n if (!this._open) this.show();\n if (vis.length) this.highlight(vis[cur < 0 ? vis.length - 1 : Math.max(cur - 1, 0)]);\n break;\n case \"Home\":\n case \"End\":\n // In a text field Home/End move the caret unless the list is being navigated.\n if (this._open && this.highlighted && vis.length) {\n e.preventDefault();\n this.highlight(e.key === \"Home\" ? vis[0] : vis[vis.length - 1]);\n }\n break;\n case \"Enter\":\n if (this._open && this.highlighted) {\n e.preventDefault();\n this.choose(this.highlighted);\n }\n break;\n case \"Escape\":\n if (this._open && !this.inline) {\n e.preventDefault();\n e.stopPropagation();\n this.hide();\n } else if (this.input!.value) {\n // Escape on a closed (or inline) list clears the field, per APG.\n e.preventDefault();\n e.stopPropagation();\n this.input!.value = \"\";\n this.input!.dispatchEvent(new Event(\"input\", { bubbles: true }));\n // Cleared and closed (APG): the input event would otherwise reopen the full list.\n this.hide();\n }\n break;\n case \"Tab\":\n if (!this.inline) this.hide();\n break;\n }\n };\n\n private onListClick = (e: MouseEvent) => {\n const o = (e.target as HTMLElement).closest<HTMLElement>(\"[data-part='option']\");\n if (!o || o.closest(\"db-combobox\") !== this || isDisabled(o)) return;\n // A real link click navigates by itself; only announce the choice, and stop the\n // navigation when a listener cancels it.\n const link = (e.target as HTMLElement).closest(\"a[href]\");\n if (!this.choose(o, !link) && link) e.preventDefault();\n };\n\n private onListPointer = (e: PointerEvent) => {\n const o = (e.target as HTMLElement).closest<HTMLElement>(\"[data-part='option']\");\n if (o && o.closest(\"db-combobox\") === this && !isDisabled(o) && !o.hidden) this.highlight(o);\n };\n\n private onListDown = (e: Event) => e.preventDefault(); // keep focus in the input\n\n private onDocDown = (e: PointerEvent) => {\n if (this._open && !this.inline && !this.contains(e.target as Node)) this.hide();\n };\n\n protected connect() {\n const { input, listbox } = this;\n if (!input || !listbox) return;\n input.addEventListener(\"input\", this.onInput);\n input.addEventListener(\"focus\", this.onFocus);\n input.addEventListener(\"keydown\", this.onKey);\n listbox.addEventListener(\"click\", this.onListClick);\n listbox.addEventListener(\"pointermove\", this.onListPointer as EventListener);\n listbox.addEventListener(\"mousedown\", this.onListDown);\n document.addEventListener(\"pointerdown\", this.onDocDown as EventListener);\n if (typeof MutationObserver !== \"undefined\") {\n this.observer = new MutationObserver(() => this.onOptionsChanged());\n this.observer.observe(listbox, { childList: true, subtree: true });\n }\n }\n\n protected disconnect() {\n const { input, listbox } = this;\n input?.removeEventListener(\"input\", this.onInput);\n input?.removeEventListener(\"focus\", this.onFocus);\n input?.removeEventListener(\"keydown\", this.onKey);\n listbox?.removeEventListener(\"click\", this.onListClick);\n listbox?.removeEventListener(\"pointermove\", this.onListPointer as EventListener);\n listbox?.removeEventListener(\"mousedown\", this.onListDown);\n document.removeEventListener(\"pointerdown\", this.onDocDown as EventListener);\n this.observer?.disconnect();\n this.observer = null;\n }\n\n /** Re-scan options after the page replaced them (filter=\"none\"). */\n refresh() {\n this.onOptionsChanged();\n }\n\n private onOptionsChanged() {\n this.prepareOptions();\n if (this.highlighted && !this.options().includes(this.highlighted)) this.clearHighlight();\n const vis = this.visible();\n if (!this.filtering) {\n if (vis.length || this.inline) this.show();\n else this.hide();\n if (vis.length && !this.highlighted && !this.hasAttribute(\"no-autohighlight\")) this.highlight(vis[0]);\n }\n this.syncExpanded();\n this.dispatchEvent(new CustomEvent(\"db-combobox:update\", { detail: { count: vis.length }, bubbles: true }));\n }\n\n private filter(query: string) {\n const q = query.toLowerCase().trim();\n let count = 0;\n for (const o of this.options()) {\n const hit = !q || (o.textContent ?? \"\").toLowerCase().includes(q) || (o.dataset.value ?? \"\").toLowerCase().includes(q);\n o.hidden = !hit;\n if (hit) count++;\n }\n if (this.empty) this.empty.hidden = count > 0 || !q;\n this.clearHighlight();\n if (count || (q && this.empty)) this.show();\n else this.hide();\n const vis = this.visible();\n if (vis.length && !this.hasAttribute(\"no-autohighlight\")) this.highlight(vis[0]);\n this.dispatchEvent(new CustomEvent(\"db-combobox:update\", { detail: { count }, bubbles: true }));\n }\n\n private syncExpanded() {\n if (!this.input) return;\n const expanded = this.inline ? this.visible().length > 0 : this._open;\n this.input.setAttribute(\"aria-expanded\", String(expanded));\n this.setAttribute(\"data-state\", expanded ? \"open\" : \"closed\");\n }\n\n show() {\n if (!this.listbox || this._open) return this.syncExpanded();\n this._open = true;\n this.listbox.hidden = false;\n this.syncExpanded();\n }\n\n hide() {\n if (!this.listbox) return;\n this.clearHighlight();\n if (!this._open) return this.syncExpanded();\n this._open = false;\n if (!this.inline) this.listbox.hidden = true;\n this.syncExpanded();\n }\n\n private highlight(o: HTMLElement) {\n if (!this.input) return;\n this.highlighted?.removeAttribute(\"data-highlighted\");\n this.highlighted?.setAttribute(\"aria-selected\", \"false\");\n this.highlighted = o;\n o.setAttribute(\"data-highlighted\", \"\");\n // In a list-autocomplete combobox the highlighted option is the selected one (APG).\n o.setAttribute(\"aria-selected\", \"true\");\n this.input.setAttribute(\"aria-activedescendant\", o.id);\n o.scrollIntoView?.({ block: \"nearest\" });\n }\n\n private clearHighlight() {\n this.highlighted?.removeAttribute(\"data-highlighted\");\n this.highlighted?.setAttribute(\"aria-selected\", \"false\");\n this.highlighted = null;\n this.input?.removeAttribute(\"aria-activedescendant\");\n }\n\n /** Returns false when a `db-combobox:select` listener cancelled the choice. */\n private choose(o: HTMLElement, followLink = true): boolean {\n const value = o.dataset.value ?? \"\";\n const text = o.textContent?.trim() ?? value;\n const ev = new CustomEvent(\"db-combobox:select\", { detail: { value, text, option: o }, bubbles: true, cancelable: true });\n if (!this.dispatchEvent(ev)) return false;\n const link = o.matches(\"a[href]\") ? (o as HTMLAnchorElement) : o.querySelector<HTMLAnchorElement>(\"a[href]\");\n if (link) {\n if (followLink) link.click();\n return true;\n }\n if (this.input) this.input.value = o.getAttribute(\"data-label\") ?? text;\n if (!this.inline) this.hide();\n this.dispatchEvent(new CustomEvent(\"db-combobox:change\", { detail: { value, text }, bubbles: true }));\n return true;\n }\n}\n\nensureDefaultDisplay();\n\nif (!customElements.get(\"db-combobox\")) {\n customElements.define(\"db-combobox\", DbCombobox);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hideFloating,
|
|
3
|
+
ownOne,
|
|
4
|
+
resolveAsChild,
|
|
5
|
+
showFloating,
|
|
6
|
+
uid
|
|
7
|
+
} from "./chunk-3AEQ6KHV.js";
|
|
8
|
+
import {
|
|
9
|
+
DogsbayElement,
|
|
10
|
+
ensureDefaultDisplay
|
|
11
|
+
} from "./chunk-K6DPDBAG.js";
|
|
12
|
+
|
|
13
|
+
// src/db-tooltip.ts
|
|
14
|
+
import { setupFloating } from "@dogsbay/primitives/floating";
|
|
15
|
+
var DbTooltip = class extends DogsbayElement {
|
|
16
|
+
trigger = null;
|
|
17
|
+
content = null;
|
|
18
|
+
cleanupFloating = null;
|
|
19
|
+
showTimer = null;
|
|
20
|
+
hideTimer = null;
|
|
21
|
+
_open = false;
|
|
22
|
+
get open() {
|
|
23
|
+
return this._open;
|
|
24
|
+
}
|
|
25
|
+
num(name, fallback) {
|
|
26
|
+
const v = Number(this.getAttribute(name));
|
|
27
|
+
return Number.isFinite(v) && this.hasAttribute(name) ? v : fallback;
|
|
28
|
+
}
|
|
29
|
+
onEnter = (e) => {
|
|
30
|
+
if (e.pointerType === "touch") return;
|
|
31
|
+
this.clearTimers();
|
|
32
|
+
if (!this._open) this.showTimer = setTimeout(() => this.show(), this.num("delay", 200));
|
|
33
|
+
};
|
|
34
|
+
onLeave = (e) => {
|
|
35
|
+
if (e.pointerType === "touch") return;
|
|
36
|
+
this.clearTimers();
|
|
37
|
+
this.hideTimer = setTimeout(() => this.hide(), this.num("close-delay", 100));
|
|
38
|
+
};
|
|
39
|
+
onContentEnter = () => this.clearTimers();
|
|
40
|
+
// Keyboard focus only: a mouse press focuses the button too, and would reopen
|
|
41
|
+
// the tooltip the press just closed.
|
|
42
|
+
onFocus = () => {
|
|
43
|
+
let keyboard = true;
|
|
44
|
+
try {
|
|
45
|
+
keyboard = this.trigger.matches(":focus-visible");
|
|
46
|
+
} catch {
|
|
47
|
+
}
|
|
48
|
+
if (!keyboard) return;
|
|
49
|
+
this.clearTimers();
|
|
50
|
+
this.show();
|
|
51
|
+
};
|
|
52
|
+
onBlur = () => this.hide();
|
|
53
|
+
onPress = () => this.hide();
|
|
54
|
+
// Capture phase, consumed: Escape dismisses only the tooltip, not a popover or
|
|
55
|
+
// dialog around its trigger (WCAG 1.4.13, APG tooltip).
|
|
56
|
+
onKey = (e) => {
|
|
57
|
+
if (e.key === "Escape" && this._open) {
|
|
58
|
+
e.preventDefault();
|
|
59
|
+
e.stopImmediatePropagation();
|
|
60
|
+
this.hide();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
setup() {
|
|
64
|
+
this.trigger = resolveAsChild(ownOne(this, "[data-part='trigger']"));
|
|
65
|
+
this.content = ownOne(this, "[data-part='content']");
|
|
66
|
+
if (!this.trigger || !this.content) return;
|
|
67
|
+
this.content.id ||= uid("db-tooltip");
|
|
68
|
+
this.content.setAttribute("role", "tooltip");
|
|
69
|
+
this.content.hidden = true;
|
|
70
|
+
const described = (this.trigger.getAttribute("aria-describedby") ?? "").split(/\s+/).filter(Boolean);
|
|
71
|
+
if (!described.includes(this.content.id)) this.trigger.setAttribute("aria-describedby", [...described, this.content.id].join(" "));
|
|
72
|
+
this.setState("closed");
|
|
73
|
+
}
|
|
74
|
+
connect() {
|
|
75
|
+
const { trigger, content } = this;
|
|
76
|
+
if (!trigger || !content) return;
|
|
77
|
+
trigger.addEventListener("pointerenter", this.onEnter);
|
|
78
|
+
trigger.addEventListener("pointerleave", this.onLeave);
|
|
79
|
+
trigger.addEventListener("focus", this.onFocus);
|
|
80
|
+
trigger.addEventListener("blur", this.onBlur);
|
|
81
|
+
trigger.addEventListener("pointerdown", this.onPress);
|
|
82
|
+
content.addEventListener("pointerenter", this.onContentEnter);
|
|
83
|
+
content.addEventListener("pointerleave", this.onLeave);
|
|
84
|
+
}
|
|
85
|
+
disconnect() {
|
|
86
|
+
const { trigger, content } = this;
|
|
87
|
+
trigger?.removeEventListener("pointerenter", this.onEnter);
|
|
88
|
+
trigger?.removeEventListener("pointerleave", this.onLeave);
|
|
89
|
+
trigger?.removeEventListener("focus", this.onFocus);
|
|
90
|
+
trigger?.removeEventListener("blur", this.onBlur);
|
|
91
|
+
trigger?.removeEventListener("pointerdown", this.onPress);
|
|
92
|
+
content?.removeEventListener("pointerenter", this.onContentEnter);
|
|
93
|
+
content?.removeEventListener("pointerleave", this.onLeave);
|
|
94
|
+
this.hide();
|
|
95
|
+
}
|
|
96
|
+
clearTimers() {
|
|
97
|
+
if (this.showTimer) clearTimeout(this.showTimer);
|
|
98
|
+
if (this.hideTimer) clearTimeout(this.hideTimer);
|
|
99
|
+
this.showTimer = this.hideTimer = null;
|
|
100
|
+
}
|
|
101
|
+
setState(state) {
|
|
102
|
+
this.setAttribute("data-state", state);
|
|
103
|
+
this.content?.setAttribute("data-state", state);
|
|
104
|
+
}
|
|
105
|
+
show() {
|
|
106
|
+
const { trigger, content } = this;
|
|
107
|
+
if (!trigger || !content || this._open) return;
|
|
108
|
+
this._open = true;
|
|
109
|
+
this.clearTimers();
|
|
110
|
+
const layer = showFloating(content);
|
|
111
|
+
this.setState("open");
|
|
112
|
+
this.cleanupFloating = setupFloating(trigger, content, {
|
|
113
|
+
placement: this.getAttribute("placement") || content.dataset.side || "top",
|
|
114
|
+
offset: 8,
|
|
115
|
+
strategy: layer === "top-layer" ? "fixed" : "absolute"
|
|
116
|
+
});
|
|
117
|
+
document.addEventListener("keydown", this.onKey, true);
|
|
118
|
+
this.dispatchEvent(new CustomEvent("db-tooltip:open", { bubbles: true }));
|
|
119
|
+
}
|
|
120
|
+
hide() {
|
|
121
|
+
this.clearTimers();
|
|
122
|
+
if (!this._open || !this.content) return;
|
|
123
|
+
this._open = false;
|
|
124
|
+
document.removeEventListener("keydown", this.onKey, true);
|
|
125
|
+
this.cleanupFloating?.();
|
|
126
|
+
this.cleanupFloating = null;
|
|
127
|
+
hideFloating(this.content);
|
|
128
|
+
this.setState("closed");
|
|
129
|
+
this.dispatchEvent(new CustomEvent("db-tooltip:close", { bubbles: true }));
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
ensureDefaultDisplay();
|
|
133
|
+
if (!customElements.get("db-tooltip")) {
|
|
134
|
+
customElements.define("db-tooltip", DbTooltip);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export {
|
|
138
|
+
DbTooltip
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=chunk-MEOIAZDF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/db-tooltip.ts"],"sourcesContent":["import { setupFloating, type FloatingOptions } from \"@dogsbay/primitives/floating\";\nimport { DogsbayElement, ensureDefaultDisplay } from \"./base.js\";\nimport { hideFloating, ownOne, resolveAsChild, showFloating, uid } from \"./utils.js\";\n\ntype Placement = NonNullable<FloatingOptions[\"placement\"]>;\n\n/**\n * `<db-tooltip>` — Short description shown on hover and keyboard focus\n * (APG \"Tooltip\"). The trigger is described by the content\n * (aria-describedby), so screen readers announce it without showing it.\n *\n * WCAG 1.4.13 (content on hover or focus):\n * - hoverable: the pointer can move from the trigger onto the tooltip\n * without it closing (`close-delay`, default 100 ms);\n * - dismissible: Escape hides it, whether it opened from hover or focus;\n * - persistent: it stays until the pointer leaves, focus moves or Escape.\n *\n * Attributes:\n * delay — ms before showing on hover (default 200)\n * close-delay — ms grace period on leave (default 100)\n * placement — \"top\" (default), or data-side on the content\n *\n * Parts: [data-part=\"trigger\"] (`data-as-child` supported), [data-part=\"content\"]\n *\n * Events: db-tooltip:open, db-tooltip:close\n */\nexport class DbTooltip extends DogsbayElement {\n private trigger: HTMLElement | null = null;\n private content: HTMLElement | null = null;\n private cleanupFloating: (() => void) | null = null;\n private showTimer: ReturnType<typeof setTimeout> | null = null;\n private hideTimer: ReturnType<typeof setTimeout> | null = null;\n private _open = false;\n\n get open(): boolean {\n return this._open;\n }\n\n private num(name: string, fallback: number): number {\n const v = Number(this.getAttribute(name));\n return Number.isFinite(v) && this.hasAttribute(name) ? v : fallback;\n }\n\n private onEnter = (e: PointerEvent) => {\n if (e.pointerType === \"touch\") return;\n this.clearTimers();\n if (!this._open) this.showTimer = setTimeout(() => this.show(), this.num(\"delay\", 200));\n };\n\n private onLeave = (e: PointerEvent) => {\n if (e.pointerType === \"touch\") return;\n this.clearTimers();\n this.hideTimer = setTimeout(() => this.hide(), this.num(\"close-delay\", 100));\n };\n\n private onContentEnter = () => this.clearTimers();\n\n // Keyboard focus only: a mouse press focuses the button too, and would reopen\n // the tooltip the press just closed.\n private onFocus = () => {\n let keyboard = true;\n try {\n keyboard = this.trigger!.matches(\":focus-visible\");\n } catch {\n /* :focus-visible unsupported: treat as keyboard */\n }\n if (!keyboard) return;\n this.clearTimers();\n this.show();\n };\n\n private onBlur = () => this.hide();\n\n private onPress = () => this.hide();\n\n // Capture phase, consumed: Escape dismisses only the tooltip, not a popover or\n // dialog around its trigger (WCAG 1.4.13, APG tooltip).\n private onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && this._open) {\n e.preventDefault();\n e.stopImmediatePropagation();\n this.hide();\n }\n };\n\n protected setup() {\n this.trigger = resolveAsChild(ownOne(this, \"[data-part='trigger']\"));\n this.content = ownOne(this, \"[data-part='content']\");\n if (!this.trigger || !this.content) return;\n this.content.id ||= uid(\"db-tooltip\");\n this.content.setAttribute(\"role\", \"tooltip\");\n this.content.hidden = true;\n const described = (this.trigger.getAttribute(\"aria-describedby\") ?? \"\").split(/\\s+/).filter(Boolean);\n if (!described.includes(this.content.id)) this.trigger.setAttribute(\"aria-describedby\", [...described, this.content.id].join(\" \"));\n this.setState(\"closed\");\n }\n\n protected connect() {\n const { trigger, content } = this;\n if (!trigger || !content) return;\n trigger.addEventListener(\"pointerenter\", this.onEnter);\n trigger.addEventListener(\"pointerleave\", this.onLeave);\n trigger.addEventListener(\"focus\", this.onFocus);\n trigger.addEventListener(\"blur\", this.onBlur);\n trigger.addEventListener(\"pointerdown\", this.onPress);\n content.addEventListener(\"pointerenter\", this.onContentEnter);\n content.addEventListener(\"pointerleave\", this.onLeave);\n }\n\n protected disconnect() {\n const { trigger, content } = this;\n trigger?.removeEventListener(\"pointerenter\", this.onEnter);\n trigger?.removeEventListener(\"pointerleave\", this.onLeave);\n trigger?.removeEventListener(\"focus\", this.onFocus);\n trigger?.removeEventListener(\"blur\", this.onBlur);\n trigger?.removeEventListener(\"pointerdown\", this.onPress);\n content?.removeEventListener(\"pointerenter\", this.onContentEnter);\n content?.removeEventListener(\"pointerleave\", this.onLeave);\n this.hide();\n }\n\n private clearTimers() {\n if (this.showTimer) clearTimeout(this.showTimer);\n if (this.hideTimer) clearTimeout(this.hideTimer);\n this.showTimer = this.hideTimer = null;\n }\n\n private setState(state: \"open\" | \"closed\") {\n this.setAttribute(\"data-state\", state);\n this.content?.setAttribute(\"data-state\", state);\n }\n\n show() {\n const { trigger, content } = this;\n if (!trigger || !content || this._open) return;\n this._open = true;\n this.clearTimers();\n const layer = showFloating(content);\n this.setState(\"open\");\n this.cleanupFloating = setupFloating(trigger, content, {\n placement: (this.getAttribute(\"placement\") || content.dataset.side || \"top\") as Placement,\n offset: 8,\n strategy: layer === \"top-layer\" ? \"fixed\" : \"absolute\",\n });\n document.addEventListener(\"keydown\", this.onKey, true);\n this.dispatchEvent(new CustomEvent(\"db-tooltip:open\", { bubbles: true }));\n }\n\n hide() {\n this.clearTimers();\n if (!this._open || !this.content) return;\n this._open = false;\n document.removeEventListener(\"keydown\", this.onKey, true);\n this.cleanupFloating?.();\n this.cleanupFloating = null;\n hideFloating(this.content);\n this.setState(\"closed\");\n this.dispatchEvent(new CustomEvent(\"db-tooltip:close\", { bubbles: true }));\n }\n}\n\nensureDefaultDisplay();\n\nif (!customElements.get(\"db-tooltip\")) {\n customElements.define(\"db-tooltip\", DbTooltip);\n}\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAS,qBAA2C;AA0B7C,IAAM,YAAN,cAAwB,eAAe;AAAA,EACpC,UAA8B;AAAA,EAC9B,UAA8B;AAAA,EAC9B,kBAAuC;AAAA,EACvC,YAAkD;AAAA,EAClD,YAAkD;AAAA,EAClD,QAAQ;AAAA,EAEhB,IAAI,OAAgB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,IAAI,MAAc,UAA0B;AAClD,UAAM,IAAI,OAAO,KAAK,aAAa,IAAI,CAAC;AACxC,WAAO,OAAO,SAAS,CAAC,KAAK,KAAK,aAAa,IAAI,IAAI,IAAI;AAAA,EAC7D;AAAA,EAEQ,UAAU,CAAC,MAAoB;AACrC,QAAI,EAAE,gBAAgB,QAAS;AAC/B,SAAK,YAAY;AACjB,QAAI,CAAC,KAAK,MAAO,MAAK,YAAY,WAAW,MAAM,KAAK,KAAK,GAAG,KAAK,IAAI,SAAS,GAAG,CAAC;AAAA,EACxF;AAAA,EAEQ,UAAU,CAAC,MAAoB;AACrC,QAAI,EAAE,gBAAgB,QAAS;AAC/B,SAAK,YAAY;AACjB,SAAK,YAAY,WAAW,MAAM,KAAK,KAAK,GAAG,KAAK,IAAI,eAAe,GAAG,CAAC;AAAA,EAC7E;AAAA,EAEQ,iBAAiB,MAAM,KAAK,YAAY;AAAA;AAAA;AAAA,EAIxC,UAAU,MAAM;AACtB,QAAI,WAAW;AACf,QAAI;AACF,iBAAW,KAAK,QAAS,QAAQ,gBAAgB;AAAA,IACnD,QAAQ;AAAA,IAER;AACA,QAAI,CAAC,SAAU;AACf,SAAK,YAAY;AACjB,SAAK,KAAK;AAAA,EACZ;AAAA,EAEQ,SAAS,MAAM,KAAK,KAAK;AAAA,EAEzB,UAAU,MAAM,KAAK,KAAK;AAAA;AAAA;AAAA,EAI1B,QAAQ,CAAC,MAAqB;AACpC,QAAI,EAAE,QAAQ,YAAY,KAAK,OAAO;AACpC,QAAE,eAAe;AACjB,QAAE,yBAAyB;AAC3B,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA,EAEU,QAAQ;AAChB,SAAK,UAAU,eAAe,OAAO,MAAM,uBAAuB,CAAC;AACnE,SAAK,UAAU,OAAO,MAAM,uBAAuB;AACnD,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,QAAS;AACpC,SAAK,QAAQ,OAAO,IAAI,YAAY;AACpC,SAAK,QAAQ,aAAa,QAAQ,SAAS;AAC3C,SAAK,QAAQ,SAAS;AACtB,UAAM,aAAa,KAAK,QAAQ,aAAa,kBAAkB,KAAK,IAAI,MAAM,KAAK,EAAE,OAAO,OAAO;AACnG,QAAI,CAAC,UAAU,SAAS,KAAK,QAAQ,EAAE,EAAG,MAAK,QAAQ,aAAa,oBAAoB,CAAC,GAAG,WAAW,KAAK,QAAQ,EAAE,EAAE,KAAK,GAAG,CAAC;AACjI,SAAK,SAAS,QAAQ;AAAA,EACxB;AAAA,EAEU,UAAU;AAClB,UAAM,EAAE,SAAS,QAAQ,IAAI;AAC7B,QAAI,CAAC,WAAW,CAAC,QAAS;AAC1B,YAAQ,iBAAiB,gBAAgB,KAAK,OAAO;AACrD,YAAQ,iBAAiB,gBAAgB,KAAK,OAAO;AACrD,YAAQ,iBAAiB,SAAS,KAAK,OAAO;AAC9C,YAAQ,iBAAiB,QAAQ,KAAK,MAAM;AAC5C,YAAQ,iBAAiB,eAAe,KAAK,OAAO;AACpD,YAAQ,iBAAiB,gBAAgB,KAAK,cAAc;AAC5D,YAAQ,iBAAiB,gBAAgB,KAAK,OAAO;AAAA,EACvD;AAAA,EAEU,aAAa;AACrB,UAAM,EAAE,SAAS,QAAQ,IAAI;AAC7B,aAAS,oBAAoB,gBAAgB,KAAK,OAAO;AACzD,aAAS,oBAAoB,gBAAgB,KAAK,OAAO;AACzD,aAAS,oBAAoB,SAAS,KAAK,OAAO;AAClD,aAAS,oBAAoB,QAAQ,KAAK,MAAM;AAChD,aAAS,oBAAoB,eAAe,KAAK,OAAO;AACxD,aAAS,oBAAoB,gBAAgB,KAAK,cAAc;AAChE,aAAS,oBAAoB,gBAAgB,KAAK,OAAO;AACzD,SAAK,KAAK;AAAA,EACZ;AAAA,EAEQ,cAAc;AACpB,QAAI,KAAK,UAAW,cAAa,KAAK,SAAS;AAC/C,QAAI,KAAK,UAAW,cAAa,KAAK,SAAS;AAC/C,SAAK,YAAY,KAAK,YAAY;AAAA,EACpC;AAAA,EAEQ,SAAS,OAA0B;AACzC,SAAK,aAAa,cAAc,KAAK;AACrC,SAAK,SAAS,aAAa,cAAc,KAAK;AAAA,EAChD;AAAA,EAEA,OAAO;AACL,UAAM,EAAE,SAAS,QAAQ,IAAI;AAC7B,QAAI,CAAC,WAAW,CAAC,WAAW,KAAK,MAAO;AACxC,SAAK,QAAQ;AACb,SAAK,YAAY;AACjB,UAAM,QAAQ,aAAa,OAAO;AAClC,SAAK,SAAS,MAAM;AACpB,SAAK,kBAAkB,cAAc,SAAS,SAAS;AAAA,MACrD,WAAY,KAAK,aAAa,WAAW,KAAK,QAAQ,QAAQ,QAAQ;AAAA,MACtE,QAAQ;AAAA,MACR,UAAU,UAAU,cAAc,UAAU;AAAA,IAC9C,CAAC;AACD,aAAS,iBAAiB,WAAW,KAAK,OAAO,IAAI;AACrD,SAAK,cAAc,IAAI,YAAY,mBAAmB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,EAC1E;AAAA,EAEA,OAAO;AACL,SAAK,YAAY;AACjB,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,QAAS;AAClC,SAAK,QAAQ;AACb,aAAS,oBAAoB,WAAW,KAAK,OAAO,IAAI;AACxD,SAAK,kBAAkB;AACvB,SAAK,kBAAkB;AACvB,iBAAa,KAAK,OAAO;AACzB,SAAK,SAAS,QAAQ;AACtB,SAAK,cAAc,IAAI,YAAY,oBAAoB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,EAC3E;AACF;AAEA,qBAAqB;AAErB,IAAI,CAAC,eAAe,IAAI,YAAY,GAAG;AACrC,iBAAe,OAAO,cAAc,SAAS;AAC/C;","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DogsbayElement
|
|
3
|
-
|
|
2
|
+
DogsbayElement,
|
|
3
|
+
ensureDefaultDisplay
|
|
4
|
+
} from "./chunk-K6DPDBAG.js";
|
|
4
5
|
|
|
5
6
|
// src/db-link-button.ts
|
|
6
7
|
var DbLinkButton = class extends DogsbayElement {
|
|
@@ -27,6 +28,7 @@ var DbLinkButton = class extends DogsbayElement {
|
|
|
27
28
|
this.appendChild(this.anchor);
|
|
28
29
|
}
|
|
29
30
|
};
|
|
31
|
+
ensureDefaultDisplay();
|
|
30
32
|
if (!customElements.get("db-link-button")) {
|
|
31
33
|
customElements.define("db-link-button", DbLinkButton);
|
|
32
34
|
}
|
|
@@ -34,4 +36,4 @@ if (!customElements.get("db-link-button")) {
|
|
|
34
36
|
export {
|
|
35
37
|
DbLinkButton
|
|
36
38
|
};
|
|
37
|
-
//# sourceMappingURL=chunk-
|
|
39
|
+
//# sourceMappingURL=chunk-QSRUT67Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/db-link-button.ts"],"sourcesContent":["import { DogsbayElement, ensureDefaultDisplay } from \"./base.js\";\n\n/**\n * `<db-link-button>` — Styled link that looks like a button.\n *\n * Attributes:\n * href — target URL (required)\n * variant — \"primary\" | \"secondary\" | \"outline\" (default: \"primary\")\n *\n * Light DOM: renders as an <a> tag with button styling.\n * Works in both Astro (matches Button component) and Obsidian.\n *\n * In Astro, the format-astro serializer maps link-button TreeNode to\n * the Button.astro component with href prop.\n *\n * In Obsidian, the plugin emits <db-link-button> which this element\n * auto-upgrades with styling and keyboard navigation.\n */\nexport class DbLinkButton extends DogsbayElement {\n private anchor: HTMLAnchorElement | null = null;\n\n protected setup() {\n const href = this.getAttribute(\"href\") || \"#\";\n const variant = this.getAttribute(\"variant\") || \"primary\";\n const text = this.textContent?.trim() || href;\n\n // Create the anchor element\n this.anchor = document.createElement(\"a\");\n this.anchor.href = href;\n this.anchor.textContent = text;\n this.anchor.className = \"db-link-button-anchor\";\n this.anchor.dataset.variant = variant;\n\n // External links open in new tab\n if (href.startsWith(\"http\")) {\n this.anchor.target = \"_blank\";\n this.anchor.rel = \"noopener noreferrer\";\n\n // Add external icon\n const icon = document.createElement(\"span\");\n icon.className = \"db-link-button-icon\";\n icon.setAttribute(\"aria-hidden\", \"true\");\n icon.textContent = \"↗\";\n this.anchor.appendChild(icon);\n }\n\n this.textContent = \"\";\n this.appendChild(this.anchor);\n }\n}\n\nensureDefaultDisplay();\n\nif (!customElements.get(\"db-link-button\")) {\n customElements.define(\"db-link-button\", DbLinkButton);\n}\n"],"mappings":";;;;;;AAkBO,IAAM,eAAN,cAA2B,eAAe;AAAA,EACvC,SAAmC;AAAA,EAEjC,QAAQ;AAChB,UAAM,OAAO,KAAK,aAAa,MAAM,KAAK;AAC1C,UAAM,UAAU,KAAK,aAAa,SAAS,KAAK;AAChD,UAAM,OAAO,KAAK,aAAa,KAAK,KAAK;AAGzC,SAAK,SAAS,SAAS,cAAc,GAAG;AACxC,SAAK,OAAO,OAAO;AACnB,SAAK,OAAO,cAAc;AAC1B,SAAK,OAAO,YAAY;AACxB,SAAK,OAAO,QAAQ,UAAU;AAG9B,QAAI,KAAK,WAAW,MAAM,GAAG;AAC3B,WAAK,OAAO,SAAS;AACrB,WAAK,OAAO,MAAM;AAGlB,YAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,WAAK,YAAY;AACjB,WAAK,aAAa,eAAe,MAAM;AACvC,WAAK,cAAc;AACnB,WAAK,OAAO,YAAY,IAAI;AAAA,IAC9B;AAEA,SAAK,cAAc;AACnB,SAAK,YAAY,KAAK,MAAM;AAAA,EAC9B;AACF;AAEA,qBAAqB;AAErB,IAAI,CAAC,eAAe,IAAI,gBAAgB,GAAG;AACzC,iBAAe,OAAO,kBAAkB,YAAY;AACtD;","names":[]}
|