@liwe3/webcomponents 1.1.0 → 1.1.10
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/AIMarkdownEditor.d.ts +35 -0
- package/dist/AIMarkdownEditor.d.ts.map +1 -0
- package/dist/AIMarkdownEditor.js +412 -0
- package/dist/AIMarkdownEditor.js.map +1 -0
- package/dist/AITextEditor.d.ts +10 -0
- package/dist/AITextEditor.d.ts.map +1 -1
- package/dist/AITextEditor.js +63 -27
- package/dist/AITextEditor.js.map +1 -1
- package/dist/ButtonToolbar.d.ts +35 -0
- package/dist/ButtonToolbar.d.ts.map +1 -0
- package/dist/ButtonToolbar.js +220 -0
- package/dist/ButtonToolbar.js.map +1 -0
- package/dist/CheckList.d.ts +31 -0
- package/dist/CheckList.d.ts.map +1 -0
- package/dist/CheckList.js +336 -0
- package/dist/CheckList.js.map +1 -0
- package/dist/ChunkUploader.d.ts +22 -0
- package/dist/ChunkUploader.d.ts.map +1 -1
- package/dist/ChunkUploader.js +245 -103
- package/dist/ChunkUploader.js.map +1 -1
- package/dist/ComicBalloon.d.ts +82 -0
- package/dist/ComicBalloon.d.ts.map +1 -0
- package/dist/ComicBalloon.js +346 -0
- package/dist/ComicBalloon.js.map +1 -0
- package/dist/Dialog.d.ts +102 -0
- package/dist/Dialog.d.ts.map +1 -0
- package/dist/Dialog.js +299 -0
- package/dist/Dialog.js.map +1 -0
- package/dist/MarkdownPreview.d.ts +25 -0
- package/dist/MarkdownPreview.d.ts.map +1 -0
- package/dist/MarkdownPreview.js +147 -0
- package/dist/MarkdownPreview.js.map +1 -0
- package/dist/ResizableCropper.d.ts +158 -0
- package/dist/ResizableCropper.d.ts.map +1 -0
- package/dist/ResizableCropper.js +562 -0
- package/dist/ResizableCropper.js.map +1 -0
- package/dist/SmartSelect.d.ts +1 -0
- package/dist/SmartSelect.d.ts.map +1 -1
- package/dist/SmartSelect.js +45 -2
- package/dist/SmartSelect.js.map +1 -1
- package/dist/index.d.ts +16 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52 -29
- package/dist/index.js.map +1 -1
- package/package.json +33 -3
- package/src/AIMarkdownEditor.ts +568 -0
- package/src/AITextEditor.ts +97 -2
- package/src/ButtonToolbar.ts +302 -0
- package/src/CheckList.ts +438 -0
- package/src/ChunkUploader.ts +837 -623
- package/src/ComicBalloon.ts +709 -0
- package/src/Dialog.ts +510 -0
- package/src/MarkdownPreview.ts +213 -0
- package/src/ResizableCropper.ts +1099 -0
- package/src/SmartSelect.ts +48 -2
- package/src/index.ts +110 -47
package/dist/Dialog.js
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
class g extends HTMLElement {
|
|
2
|
+
constructor() {
|
|
3
|
+
super(), this.config = {
|
|
4
|
+
title: "Dialog",
|
|
5
|
+
body: "",
|
|
6
|
+
modal: !0,
|
|
7
|
+
escToClose: !0,
|
|
8
|
+
clickToClose: !0,
|
|
9
|
+
fxAppear: "none",
|
|
10
|
+
fxSpeed: 1e3
|
|
11
|
+
}, this.eventsBound = !1, this.attachShadow({ mode: "open" });
|
|
12
|
+
}
|
|
13
|
+
connectedCallback() {
|
|
14
|
+
this.render(), this.setupKeyboardListeners();
|
|
15
|
+
}
|
|
16
|
+
disconnectedCallback() {
|
|
17
|
+
this.removeKeyboardListeners(), this.backdrop && this.backdrop.remove();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Shows the dialog with the given configuration
|
|
21
|
+
*/
|
|
22
|
+
show(t) {
|
|
23
|
+
this.config = { ...this.config, ...t }, this.render(), this.setupKeyboardListeners(), this.config.modal && this.createBackdrop(), requestAnimationFrame(() => {
|
|
24
|
+
requestAnimationFrame(() => {
|
|
25
|
+
const o = this.shadowRoot.querySelector(".dialog-container");
|
|
26
|
+
o && o.classList.add("show"), this.backdrop && (this.backdrop.style.opacity = "1");
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Closes the dialog
|
|
32
|
+
*/
|
|
33
|
+
close() {
|
|
34
|
+
const t = this.shadowRoot.querySelector(".dialog-container");
|
|
35
|
+
t && t.classList.add("closing"), this.backdrop && (this.backdrop.remove(), this.backdrop = void 0);
|
|
36
|
+
const o = this.config.fxAppear === "none" ? 0 : this.config.fxSpeed || 1e3;
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
this.removeKeyboardListeners(), this.dispatchEvent(new CustomEvent("close")), this.config.onclose && this.config.onclose(), this.remove();
|
|
39
|
+
}, o);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Creates the modal backdrop
|
|
43
|
+
*/
|
|
44
|
+
createBackdrop() {
|
|
45
|
+
this.backdrop || (this.backdrop = document.createElement("div"), this.backdrop.className = "dialog-backdrop", this.backdrop.style.position = "fixed", this.backdrop.style.top = "0", this.backdrop.style.left = "0", this.backdrop.style.width = "100%", this.backdrop.style.height = "100%", this.backdrop.style.backgroundColor = "rgba(0, 0, 0, 0.6)", this.backdrop.style.backdropFilter = "blur(4px)", this.backdrop.style.webkitBackdropFilter = "blur(4px)", this.backdrop.style.zIndex = "99998", this.backdrop.style.opacity = "0", this.backdrop.style.transition = "opacity 0.3s ease", this.config.clickToClose && this.backdrop.addEventListener("click", () => {
|
|
46
|
+
this.close();
|
|
47
|
+
}), document.body.appendChild(this.backdrop));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Sets up keyboard event listeners
|
|
51
|
+
*/
|
|
52
|
+
setupKeyboardListeners() {
|
|
53
|
+
this.config.escToClose && (this.escKeyHandler = (t) => {
|
|
54
|
+
t.key === "Escape" && this.close();
|
|
55
|
+
}, document.addEventListener("keydown", this.escKeyHandler));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Removes keyboard event listeners
|
|
59
|
+
*/
|
|
60
|
+
removeKeyboardListeners() {
|
|
61
|
+
this.escKeyHandler && (document.removeEventListener("keydown", this.escKeyHandler), this.escKeyHandler = void 0);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Binds all event listeners
|
|
65
|
+
*/
|
|
66
|
+
bindEvents() {
|
|
67
|
+
if (this.eventsBound) return;
|
|
68
|
+
this.eventsBound = !0, this.shadowRoot.addEventListener("click", (o) => {
|
|
69
|
+
const n = o.target;
|
|
70
|
+
if (n.closest(".close-button"))
|
|
71
|
+
this.close();
|
|
72
|
+
else if (n.closest(".dialog-button")) {
|
|
73
|
+
const i = n.closest(".dialog-button").dataset.index;
|
|
74
|
+
if (i !== void 0) {
|
|
75
|
+
const r = this.config.buttons?.[parseInt(i, 10)];
|
|
76
|
+
r && r.onclick && r.onclick(this);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
const t = this.shadowRoot.querySelector(".dialog-container");
|
|
81
|
+
t && t.addEventListener("wheel", (o) => {
|
|
82
|
+
o.stopPropagation();
|
|
83
|
+
}, { passive: !0 });
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Renders the component
|
|
87
|
+
*/
|
|
88
|
+
render() {
|
|
89
|
+
const t = this.config.title || "Dialog", o = this.config.buttons || [], i = `${this.config.fxSpeed || 1e3}ms`, r = this.config.fxAppear === "fade" ? "fx-fade" : this.config.fxAppear === "slide" ? "fx-slide" : "", a = o.length > 1 ? o[0] : null, c = o.length === 1 ? o : o.slice(1);
|
|
90
|
+
this.shadowRoot.innerHTML = `
|
|
91
|
+
<style>
|
|
92
|
+
:host {
|
|
93
|
+
display: block;
|
|
94
|
+
font-family: var(--font-family, var(--liwe3-font-family, Ubuntu, sans-serif));
|
|
95
|
+
font-size: var(--font-size, 14px);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.dialog-container {
|
|
99
|
+
position: fixed;
|
|
100
|
+
top: 50%;
|
|
101
|
+
left: 50%;
|
|
102
|
+
transform: translate(-50%, -50%);
|
|
103
|
+
min-width: 400px;
|
|
104
|
+
max-width: 600px;
|
|
105
|
+
max-height: 80vh;
|
|
106
|
+
background: var(--dialog-background, var(--liwe3-surface-raised, white));
|
|
107
|
+
border-radius: var(--dialog-border-radius, var(--liwe3-border-radius, 8px));
|
|
108
|
+
box-shadow: var(--dialog-shadow, 0 10px 40px rgba(0, 0, 0, 0.2));
|
|
109
|
+
z-index: 99999;
|
|
110
|
+
display: flex;
|
|
111
|
+
flex-direction: column;
|
|
112
|
+
opacity: 1;
|
|
113
|
+
font-family: var(--font-family, var(--liwe3-font-family, Ubuntu, sans-serif));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Fade animation */
|
|
117
|
+
.dialog-container.fx-fade {
|
|
118
|
+
opacity: 0;
|
|
119
|
+
transition: opacity ${i} ease;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.dialog-container.fx-fade.show {
|
|
123
|
+
opacity: 1;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.dialog-container.fx-fade.closing {
|
|
127
|
+
opacity: 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Slide animation */
|
|
131
|
+
.dialog-container.fx-slide {
|
|
132
|
+
transform: translate(-50%, -100%);
|
|
133
|
+
opacity: 0;
|
|
134
|
+
transition: transform ${i} cubic-bezier(0.16, 1, 0.3, 1), opacity ${i} ease;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.dialog-container.fx-slide.show {
|
|
138
|
+
transform: translate(-50%, -50%);
|
|
139
|
+
opacity: 1;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.dialog-container.fx-slide.closing {
|
|
143
|
+
transform: translate(-50%, -100%);
|
|
144
|
+
opacity: 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.dialog-header {
|
|
148
|
+
padding: 0;
|
|
149
|
+
border-bottom: none;
|
|
150
|
+
flex-shrink: 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.dialog-title {
|
|
154
|
+
margin: 0;
|
|
155
|
+
padding: 20px 24px;
|
|
156
|
+
font-size: 20px;
|
|
157
|
+
font-weight: 600;
|
|
158
|
+
color: var(--dialog-title-color, var(--liwe3-text-inverse, white));
|
|
159
|
+
background: var(--dialog-title-background, linear-gradient(135deg,
|
|
160
|
+
var(--liwe3-mode1-500, #667eea),
|
|
161
|
+
var(--liwe3-mode4-500, #9f7aea)
|
|
162
|
+
));
|
|
163
|
+
border-bottom: 1px solid var(--dialog-border-color, var(--liwe3-border-default, #e0e0e0));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.dialog-body {
|
|
167
|
+
padding: 24px;
|
|
168
|
+
overflow-y: auto;
|
|
169
|
+
flex: 1;
|
|
170
|
+
color: var(--dialog-text-color, var(--liwe3-text-mode2, #555));
|
|
171
|
+
line-height: 1.6;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.dialog-footer {
|
|
175
|
+
padding: 16px 24px;
|
|
176
|
+
border-top: 1px solid var(--dialog-border-color, var(--liwe3-border-default, #e0e0e0));
|
|
177
|
+
display: flex;
|
|
178
|
+
justify-content: space-between;
|
|
179
|
+
align-items: center;
|
|
180
|
+
gap: 12px;
|
|
181
|
+
flex-shrink: 0;
|
|
182
|
+
background: var(--dialog-background, var(--liwe3-surface-raised, white));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.footer-left {
|
|
186
|
+
display: flex;
|
|
187
|
+
gap: 12px;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.footer-right {
|
|
191
|
+
display: flex;
|
|
192
|
+
gap: 12px;
|
|
193
|
+
margin-left: auto;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.dialog-button {
|
|
197
|
+
padding: 8px 20px;
|
|
198
|
+
border: 1px solid var(--dialog-button-border-color, var(--liwe3-border-default, #ccc));
|
|
199
|
+
border-radius: var(--dialog-button-border-radius, var(--liwe3-border-radius, 4px));
|
|
200
|
+
background: var(--dialog-button-background, var(--liwe3-surface-raised, white));
|
|
201
|
+
color: var(--dialog-button-color, var(--liwe3-text-mode1, #333));
|
|
202
|
+
font-size: 14px;
|
|
203
|
+
cursor: pointer;
|
|
204
|
+
transition: all 0.2s;
|
|
205
|
+
font-family: inherit;
|
|
206
|
+
font-weight: 500;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.dialog-button:hover {
|
|
210
|
+
background-color: var(--dialog-button-hover-background, var(--liwe3-hover-overlay, #f8f9fa));
|
|
211
|
+
border-color: var(--dialog-button-hover-border-color, var(--liwe3-border-strong, #999));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.dialog-button:active {
|
|
215
|
+
background-color: var(--dialog-button-active-background, var(--liwe3-active-overlay, #e9ecef));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.close-button {
|
|
219
|
+
padding: 8px 20px;
|
|
220
|
+
border: 1px solid var(--dialog-close-border-color, var(--liwe3-border-default, #ccc));
|
|
221
|
+
border-radius: var(--dialog-button-border-radius, var(--liwe3-border-radius, 4px));
|
|
222
|
+
background: var(--dialog-close-background, var(--liwe3-surface-raised, white));
|
|
223
|
+
color: var(--dialog-close-color, var(--liwe3-text-mode1, #333));
|
|
224
|
+
font-size: 14px;
|
|
225
|
+
cursor: pointer;
|
|
226
|
+
transition: all 0.2s;
|
|
227
|
+
font-family: inherit;
|
|
228
|
+
font-weight: 500;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.close-button:hover {
|
|
232
|
+
background-color: var(--dialog-close-hover-background, var(--liwe3-hover-overlay, #f8f9fa));
|
|
233
|
+
border-color: var(--dialog-close-hover-border-color, var(--liwe3-border-strong, #999));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
@media (max-width: 768px) {
|
|
237
|
+
.dialog-container {
|
|
238
|
+
min-width: 90vw;
|
|
239
|
+
max-width: 90vw;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
</style>
|
|
243
|
+
|
|
244
|
+
<div class="dialog-container ${r}">
|
|
245
|
+
<div class="dialog-header">
|
|
246
|
+
<h2 class="dialog-title">${t}</h2>
|
|
247
|
+
</div>
|
|
248
|
+
|
|
249
|
+
<div class="dialog-body">
|
|
250
|
+
${this.config.body}
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<div class="dialog-footer">
|
|
254
|
+
${a ? `
|
|
255
|
+
<div class="footer-left">
|
|
256
|
+
<button
|
|
257
|
+
class="dialog-button"
|
|
258
|
+
data-index="0"
|
|
259
|
+
style="${a.backgroundColor ? `background-color: ${a.backgroundColor}; color: white; border-color: ${a.backgroundColor};` : ""}"
|
|
260
|
+
>
|
|
261
|
+
${a.label}
|
|
262
|
+
</button>
|
|
263
|
+
</div>
|
|
264
|
+
` : ""}
|
|
265
|
+
|
|
266
|
+
<div class="footer-right">
|
|
267
|
+
${c.map((d, s) => `
|
|
268
|
+
<button
|
|
269
|
+
class="dialog-button"
|
|
270
|
+
data-index="${a ? s + 1 : s}"
|
|
271
|
+
style="${d.backgroundColor ? `background-color: ${d.backgroundColor}; color: white; border-color: ${d.backgroundColor};` : ""}"
|
|
272
|
+
>
|
|
273
|
+
${d.label}
|
|
274
|
+
</button>
|
|
275
|
+
`).join("")}
|
|
276
|
+
${o.length === 0 ? '<button class="close-button">Close</button>' : ""}
|
|
277
|
+
</div>
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
`, this.bindEvents();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
const b = (e = "liwe3-dialog") => {
|
|
284
|
+
typeof window < "u" && !window.customElements.get(e) && customElements.define(e, g);
|
|
285
|
+
};
|
|
286
|
+
b();
|
|
287
|
+
const l = "liwe3-dialog-container", f = () => {
|
|
288
|
+
let e = document.getElementById(l);
|
|
289
|
+
return e || (e = document.createElement("div"), e.id = l, e.style.position = "fixed", e.style.zIndex = "99999", e.style.pointerEvents = "none", document.body.appendChild(e)), e;
|
|
290
|
+
}, h = (e) => {
|
|
291
|
+
const t = f(), o = document.createElement("liwe3-dialog");
|
|
292
|
+
return o.style.pointerEvents = "auto", o.show(e), t.appendChild(o), o;
|
|
293
|
+
};
|
|
294
|
+
export {
|
|
295
|
+
g as DialogElement,
|
|
296
|
+
b as defineDialog,
|
|
297
|
+
h as dialogAdd
|
|
298
|
+
};
|
|
299
|
+
//# sourceMappingURL=Dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.js","sources":["../src/Dialog.ts"],"sourcesContent":["/**\n * Dialog Web Component\n * A customizable dialog with HTML body, custom buttons, and modal support\n */\n\nexport type DialogButton = {\n\tlabel : string;\n\tbackgroundColor? : string;\n\tonclick : ( dialog? : DialogElement ) => void;\n};\n\nexport type DialogConfig = {\n\ttitle? : string; // Default: \"Dialog\"\n\tbody : string; // HTML content\n\tbuttons? : DialogButton[];\n\tmodal? : boolean; // If true, dims background and prevents interaction outside dialog\n\tescToClose? : boolean; // If true, Esc key closes dialog\n\tclickToClose? : boolean; // If true, clicking outside closes dialog (like cancel)\n\tfxAppear? : 'none' | 'fade' | 'slide'; // Animation effect when dialog appears (default: 'none')\n\tfxSpeed? : number; // Animation duration in milliseconds (default: 1000)\n\tonclose? : () => void;\n};\n\nexport class DialogElement extends HTMLElement {\n\tdeclare shadowRoot : ShadowRoot;\n\tprivate config : DialogConfig = {\n\t\ttitle: 'Dialog',\n\t\tbody: '',\n\t\tmodal: true,\n\t\tescToClose: true,\n\t\tclickToClose: true,\n\t\tfxAppear: 'none',\n\t\tfxSpeed: 1000,\n\t};\n\tprivate backdrop? : HTMLElement;\n\tprivate escKeyHandler? : ( e : KeyboardEvent ) => void;\n\tprivate eventsBound : boolean = false;\n\n\tconstructor () {\n\t\tsuper();\n\t\tthis.attachShadow( { mode: 'open' } );\n\t}\n\n\tconnectedCallback () : void {\n\t\tthis.render();\n\t\tthis.setupKeyboardListeners();\n\t}\n\n\tdisconnectedCallback () : void {\n\t\tthis.removeKeyboardListeners();\n\t\tif ( this.backdrop ) {\n\t\t\tthis.backdrop.remove();\n\t\t}\n\t}\n\n\t/**\n\t * Shows the dialog with the given configuration\n\t */\n\tshow ( config : DialogConfig ) : void {\n\t\tthis.config = { ...this.config, ...config };\n\t\tthis.render();\n\t\tthis.setupKeyboardListeners();\n\n\t\t// Create backdrop if modal is enabled\n\t\tif ( this.config.modal ) {\n\t\t\tthis.createBackdrop();\n\t\t}\n\n\t\t// Add opening animation class\n\t\trequestAnimationFrame( () => {\n\t\t\trequestAnimationFrame( () => {\n\t\t\t\tconst dialog = this.shadowRoot.querySelector( '.dialog-container' ) as HTMLElement;\n\t\t\t\tif ( dialog ) {\n\t\t\t\t\tdialog.classList.add( 'show' );\n\t\t\t\t}\n\t\t\t\tif ( this.backdrop ) {\n\t\t\t\t\t// Use inline style instead of class since backdrop is outside shadow DOM\n\t\t\t\t\tthis.backdrop.style.opacity = '1';\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t/**\n\t * Closes the dialog\n\t */\n\tclose () : void {\n\t\tconst dialog = this.shadowRoot.querySelector( '.dialog-container' ) as HTMLElement;\n\n\t\t// Add closing animation\n\t\tif ( dialog ) {\n\t\t\tdialog.classList.add( 'closing' );\n\t\t}\n\t\tif ( this.backdrop ) {\n\t\t\tthis.backdrop.remove();\n\t\t\tthis.backdrop = undefined;\n\t\t}\n\n\t\t// Wait for animation to complete\n\t\tconst animationDuration = this.config.fxAppear === 'none' ? 0 : ( this.config.fxSpeed || 1000 );\n\t\tsetTimeout( () => {\n\t\t\tthis.removeKeyboardListeners();\n\n\t\t\tthis.dispatchEvent( new CustomEvent( 'close' ) );\n\t\t\tif ( this.config.onclose ) {\n\t\t\t\tthis.config.onclose();\n\t\t\t}\n\t\t\tthis.remove();\n\t\t}, animationDuration );\n\t}\n\n\t/**\n\t * Creates the modal backdrop\n\t */\n\tprivate createBackdrop () : void {\n\t\tif ( this.backdrop ) return;\n\n\t\tthis.backdrop = document.createElement( 'div' );\n\t\tthis.backdrop.className = 'dialog-backdrop';\n\t\tthis.backdrop.style.position = 'fixed';\n\t\tthis.backdrop.style.top = '0';\n\t\tthis.backdrop.style.left = '0';\n\t\tthis.backdrop.style.width = '100%';\n\t\tthis.backdrop.style.height = '100%';\n\t\tthis.backdrop.style.backgroundColor = 'rgba(0, 0, 0, 0.6)';\n\t\tthis.backdrop.style.backdropFilter = 'blur(4px)';\n\t\t( this.backdrop.style as any ).webkitBackdropFilter = 'blur(4px)'; // Safari support\n\t\tthis.backdrop.style.zIndex = '99998';\n\t\tthis.backdrop.style.opacity = '0';\n\t\tthis.backdrop.style.transition = 'opacity 0.3s ease';\n\n\t\t// Handle click outside to close\n\t\tif ( this.config.clickToClose ) {\n\t\t\tthis.backdrop.addEventListener( 'click', () => {\n\t\t\t\tthis.close();\n\t\t\t} );\n\t\t}\n\n\t\tdocument.body.appendChild( this.backdrop );\n\t}\n\n\t/**\n\t * Sets up keyboard event listeners\n\t */\n\tprivate setupKeyboardListeners () : void {\n\t\tif ( this.config.escToClose ) {\n\t\t\tthis.escKeyHandler = ( e : KeyboardEvent ) => {\n\t\t\t\tif ( e.key === 'Escape' ) {\n\t\t\t\t\tthis.close();\n\t\t\t\t}\n\t\t\t};\n\t\t\tdocument.addEventListener( 'keydown', this.escKeyHandler );\n\t\t}\n\t}\n\n\t/**\n\t * Removes keyboard event listeners\n\t */\n\tprivate removeKeyboardListeners () : void {\n\t\tif ( this.escKeyHandler ) {\n\t\t\tdocument.removeEventListener( 'keydown', this.escKeyHandler );\n\t\t\tthis.escKeyHandler = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Binds all event listeners\n\t */\n\tprivate bindEvents () : void {\n\t\t// Only bind events once to prevent duplicate event listeners\n\t\tif ( this.eventsBound ) return;\n\t\tthis.eventsBound = true;\n\n\t\t// Handle button clicks\n\t\tthis.shadowRoot.addEventListener( 'click', ( e ) => {\n\t\t\tconst target = e.target as HTMLElement;\n\n\t\t\tif ( target.closest( '.close-button' ) ) {\n\t\t\t\tthis.close();\n\t\t\t} else if ( target.closest( '.dialog-button' ) ) {\n\t\t\t\tconst buttonIndex = ( target.closest( '.dialog-button' ) as HTMLElement ).dataset.index;\n\t\t\t\tif ( buttonIndex !== undefined ) {\n\t\t\t\t\tconst button = this.config.buttons?.[parseInt( buttonIndex, 10 )];\n\t\t\t\t\tif ( button && button.onclick ) {\n\t\t\t\t\t\tbutton.onclick( this );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Prevent scroll propagation to body when scrolling within dialog\n\t\tconst dialogContainer = this.shadowRoot.querySelector( '.dialog-container' ) as HTMLElement;\n\t\tif ( dialogContainer ) {\n\t\t\tdialogContainer.addEventListener( 'wheel', ( e ) => {\n\t\t\t\te.stopPropagation();\n\t\t\t}, { passive: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Renders the component\n\t */\n\tprivate render () : void {\n\t\tconst title = this.config.title || 'Dialog';\n\t\tconst buttons = this.config.buttons || [];\n\t\tconst animationSpeed = this.config.fxSpeed || 1000;\n\t\tconst animationDuration = `${animationSpeed}ms`;\n\t\tconst fxClass = this.config.fxAppear === 'fade'\n\t\t\t? 'fx-fade'\n\t\t\t: this.config.fxAppear === 'slide'\n\t\t\t? 'fx-slide'\n\t\t\t: '';\n\n\t\t// Determine button layout:\n\t\t// - If only 1 button, put it on the right\n\t\t// - If 2+ buttons, put first on left, rest on right\n\t\tconst firstButton = buttons.length > 1 ? buttons[0] : null;\n\t\tconst rightButtons = buttons.length === 1 ? buttons : buttons.slice( 1 );\n\n\t\tthis.shadowRoot.innerHTML = `\n <style>\n :host {\n display: block;\n font-family: var(--font-family, var(--liwe3-font-family, Ubuntu, sans-serif));\n font-size: var(--font-size, 14px);\n }\n\n .dialog-container {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n min-width: 400px;\n max-width: 600px;\n max-height: 80vh;\n background: var(--dialog-background, var(--liwe3-surface-raised, white));\n border-radius: var(--dialog-border-radius, var(--liwe3-border-radius, 8px));\n box-shadow: var(--dialog-shadow, 0 10px 40px rgba(0, 0, 0, 0.2));\n z-index: 99999;\n display: flex;\n flex-direction: column;\n opacity: 1;\n font-family: var(--font-family, var(--liwe3-font-family, Ubuntu, sans-serif));\n }\n\n /* Fade animation */\n .dialog-container.fx-fade {\n opacity: 0;\n transition: opacity ${animationDuration} ease;\n }\n\n .dialog-container.fx-fade.show {\n opacity: 1;\n }\n\n .dialog-container.fx-fade.closing {\n opacity: 0;\n }\n\n /* Slide animation */\n .dialog-container.fx-slide {\n transform: translate(-50%, -100%);\n opacity: 0;\n transition: transform ${animationDuration} cubic-bezier(0.16, 1, 0.3, 1), opacity ${animationDuration} ease;\n }\n\n .dialog-container.fx-slide.show {\n transform: translate(-50%, -50%);\n opacity: 1;\n }\n\n .dialog-container.fx-slide.closing {\n transform: translate(-50%, -100%);\n opacity: 0;\n }\n\n .dialog-header {\n padding: 0;\n border-bottom: none;\n flex-shrink: 0;\n }\n\n .dialog-title {\n margin: 0;\n padding: 20px 24px;\n font-size: 20px;\n font-weight: 600;\n color: var(--dialog-title-color, var(--liwe3-text-inverse, white));\n background: var(--dialog-title-background, linear-gradient(135deg,\n var(--liwe3-mode1-500, #667eea),\n var(--liwe3-mode4-500, #9f7aea)\n ));\n border-bottom: 1px solid var(--dialog-border-color, var(--liwe3-border-default, #e0e0e0));\n }\n\n .dialog-body {\n padding: 24px;\n overflow-y: auto;\n flex: 1;\n color: var(--dialog-text-color, var(--liwe3-text-mode2, #555));\n line-height: 1.6;\n }\n\n .dialog-footer {\n padding: 16px 24px;\n border-top: 1px solid var(--dialog-border-color, var(--liwe3-border-default, #e0e0e0));\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n background: var(--dialog-background, var(--liwe3-surface-raised, white));\n }\n\n .footer-left {\n display: flex;\n gap: 12px;\n }\n\n .footer-right {\n display: flex;\n gap: 12px;\n margin-left: auto;\n }\n\n .dialog-button {\n padding: 8px 20px;\n border: 1px solid var(--dialog-button-border-color, var(--liwe3-border-default, #ccc));\n border-radius: var(--dialog-button-border-radius, var(--liwe3-border-radius, 4px));\n background: var(--dialog-button-background, var(--liwe3-surface-raised, white));\n color: var(--dialog-button-color, var(--liwe3-text-mode1, #333));\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n font-family: inherit;\n font-weight: 500;\n }\n\n .dialog-button:hover {\n background-color: var(--dialog-button-hover-background, var(--liwe3-hover-overlay, #f8f9fa));\n border-color: var(--dialog-button-hover-border-color, var(--liwe3-border-strong, #999));\n }\n\n .dialog-button:active {\n background-color: var(--dialog-button-active-background, var(--liwe3-active-overlay, #e9ecef));\n }\n\n .close-button {\n padding: 8px 20px;\n border: 1px solid var(--dialog-close-border-color, var(--liwe3-border-default, #ccc));\n border-radius: var(--dialog-button-border-radius, var(--liwe3-border-radius, 4px));\n background: var(--dialog-close-background, var(--liwe3-surface-raised, white));\n color: var(--dialog-close-color, var(--liwe3-text-mode1, #333));\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n font-family: inherit;\n font-weight: 500;\n }\n\n .close-button:hover {\n background-color: var(--dialog-close-hover-background, var(--liwe3-hover-overlay, #f8f9fa));\n border-color: var(--dialog-close-hover-border-color, var(--liwe3-border-strong, #999));\n }\n\n @media (max-width: 768px) {\n .dialog-container {\n min-width: 90vw;\n max-width: 90vw;\n }\n }\n </style>\n\n <div class=\"dialog-container ${fxClass}\">\n <div class=\"dialog-header\">\n <h2 class=\"dialog-title\">${title}</h2>\n </div>\n\n <div class=\"dialog-body\">\n ${this.config.body}\n </div>\n\n <div class=\"dialog-footer\">\n ${\n\t\t\tfirstButton\n\t\t\t\t? `\n <div class=\"footer-left\">\n <button\n class=\"dialog-button\"\n data-index=\"0\"\n style=\"${firstButton.backgroundColor ? `background-color: ${firstButton.backgroundColor}; color: white; border-color: ${firstButton.backgroundColor};` : ''}\"\n >\n ${firstButton.label}\n </button>\n </div>\n `\n\t\t\t\t: ''\n\t\t}\n\n <div class=\"footer-right\">\n ${\n\t\t\trightButtons.map( ( button, index ) => `\n <button\n class=\"dialog-button\"\n data-index=\"${firstButton ? index + 1 : index}\"\n style=\"${button.backgroundColor ? `background-color: ${button.backgroundColor}; color: white; border-color: ${button.backgroundColor};` : ''}\"\n >\n ${button.label}\n </button>\n ` ).join( '' )\n\t\t}\n ${buttons.length === 0 ? '<button class=\"close-button\">Close</button>' : ''}\n </div>\n </div>\n </div>\n `;\n\n\t\tthis.bindEvents();\n\t}\n}\n\n/**\n * Conditionally defines the custom element if in a browser environment.\n */\nconst defineDialog = ( tagName : string = 'liwe3-dialog' ) : void => {\n\tif ( typeof window !== 'undefined' && !window.customElements.get( tagName ) ) {\n\t\tcustomElements.define( tagName, DialogElement );\n\t}\n};\n\n// Auto-register with default tag name\ndefineDialog();\n\n/**\n * Container ID for dialogs\n */\nconst DIALOG_CONTAINER_ID = 'liwe3-dialog-container';\n\n/**\n * Gets or creates the dialog container element\n */\nconst getDialogContainer = () : HTMLElement => {\n\tlet container = document.getElementById( DIALOG_CONTAINER_ID );\n\n\tif ( !container ) {\n\t\tcontainer = document.createElement( 'div' );\n\t\tcontainer.id = DIALOG_CONTAINER_ID;\n\t\tcontainer.style.position = 'fixed';\n\t\tcontainer.style.zIndex = '99999';\n\t\tcontainer.style.pointerEvents = 'none';\n\t\tdocument.body.appendChild( container );\n\t}\n\n\treturn container;\n};\n\n/**\n * Shows a dialog with the given configuration.\n * This is the recommended way to display dialogs.\n *\n * @param config - The dialog configuration\n * @returns The dialog element instance\n *\n * @example\n * ```typescript\n * import { dialogAdd } from '@liwe3/webcomponents';\n *\n * dialogAdd({\n * title: 'Delete File',\n * body: '<p>Are you sure you want to delete this file? This action cannot be undone.</p>',\n * buttons: [\n * {\n * label: 'Delete',\n * backgroundColor: '#dc3545',\n * onclick: (dialog) => {\n * console.log('File deleted');\n * dialog.close();\n * }\n * },\n * {\n * label: 'Cancel',\n * onclick: (dialog) => {\n * console.log('Cancelled');\n * dialog.close();\n * }\n * }\n * ],\n * modal: true,\n * escToClose: true,\n * clickToClose: true\n * });\n * ```\n */\nconst dialogAdd = ( config : DialogConfig ) : DialogElement => {\n\tconst container = getDialogContainer();\n\tconst dialog = document.createElement( 'liwe3-dialog' ) as DialogElement;\n\n\t// Allow pointer events on individual dialogs\n\tdialog.style.pointerEvents = 'auto';\n\n\t// Show the dialog with the provided config\n\tdialog.show( config );\n\n\t// Add to container\n\tcontainer.appendChild( dialog );\n\n\treturn dialog;\n};\n\nexport { defineDialog, dialogAdd };\n"],"names":["DialogElement","config","dialog","animationDuration","e","target","buttonIndex","button","dialogContainer","title","buttons","fxClass","firstButton","rightButtons","index","defineDialog","tagName","DIALOG_CONTAINER_ID","getDialogContainer","container","dialogAdd"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MarkdownPreview Web Component
|
|
3
|
+
* Renders markdown content using a dynamically loaded library
|
|
4
|
+
*/
|
|
5
|
+
export declare class MarkdownPreviewElement extends HTMLElement {
|
|
6
|
+
shadowRoot: ShadowRoot;
|
|
7
|
+
private _libUrl;
|
|
8
|
+
private _value;
|
|
9
|
+
private _isLibLoaded;
|
|
10
|
+
private _isLoadingLib;
|
|
11
|
+
private container;
|
|
12
|
+
static get observedAttributes(): string[];
|
|
13
|
+
constructor();
|
|
14
|
+
connectedCallback(): void;
|
|
15
|
+
attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
|
|
16
|
+
get libUrl(): string;
|
|
17
|
+
set libUrl(value: string);
|
|
18
|
+
get value(): string;
|
|
19
|
+
set value(content: string);
|
|
20
|
+
private render;
|
|
21
|
+
private loadLibrary;
|
|
22
|
+
private updateContent;
|
|
23
|
+
}
|
|
24
|
+
export declare const defineMarkdownPreview: (tagName?: string) => void;
|
|
25
|
+
//# sourceMappingURL=MarkdownPreview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownPreview.d.ts","sourceRoot":"","sources":["../src/MarkdownPreview.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qBAAa,sBAAuB,SAAQ,WAAW;IAC7C,UAAU,EAAE,UAAU,CAAC;IAC/B,OAAO,CAAC,OAAO,CAAqE;IACpF,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,SAAS,CAAe;IAEhC,MAAM,KAAK,kBAAkB,aAE5B;;IAQD,iBAAiB;IAIjB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAezE,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAEvB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,OAAO,EAAE,MAAM,EAIxB;IAED,OAAO,CAAC,MAAM;YAoEA,WAAW;IAwCzB,OAAO,CAAC,aAAa;CAoCtB;AAED,eAAO,MAAM,qBAAqB,GAAI,UAAS,MAAiC,SAI/E,CAAC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
class n extends HTMLElement {
|
|
2
|
+
constructor() {
|
|
3
|
+
super(), this._libUrl = "https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js", this._value = "", this._isLibLoaded = !1, this._isLoadingLib = !1, this.attachShadow({ mode: "open" }), this.render();
|
|
4
|
+
}
|
|
5
|
+
static get observedAttributes() {
|
|
6
|
+
return ["lib-url", "value"];
|
|
7
|
+
}
|
|
8
|
+
connectedCallback() {
|
|
9
|
+
this.loadLibrary();
|
|
10
|
+
}
|
|
11
|
+
attributeChangedCallback(e, o, i) {
|
|
12
|
+
o !== i && (e === "lib-url" ? (this._libUrl = i, this._isLibLoaded = !1, this.loadLibrary()) : e === "value" && this._value !== i && (this.value = i));
|
|
13
|
+
}
|
|
14
|
+
get libUrl() {
|
|
15
|
+
return this._libUrl;
|
|
16
|
+
}
|
|
17
|
+
set libUrl(e) {
|
|
18
|
+
this.setAttribute("lib-url", e);
|
|
19
|
+
}
|
|
20
|
+
get value() {
|
|
21
|
+
return this._value;
|
|
22
|
+
}
|
|
23
|
+
set value(e) {
|
|
24
|
+
this._value = e, this.updateContent();
|
|
25
|
+
}
|
|
26
|
+
render() {
|
|
27
|
+
this.shadowRoot.innerHTML = `
|
|
28
|
+
<style>
|
|
29
|
+
:host {
|
|
30
|
+
display: block;
|
|
31
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
32
|
+
line-height: 1.6;
|
|
33
|
+
color: #333;
|
|
34
|
+
}
|
|
35
|
+
.markdown-body {
|
|
36
|
+
box-sizing: border-box;
|
|
37
|
+
min-width: 200px;
|
|
38
|
+
max-width: 980px;
|
|
39
|
+
margin: 0 auto;
|
|
40
|
+
padding: 15px;
|
|
41
|
+
}
|
|
42
|
+
img {
|
|
43
|
+
max-width: 100%;
|
|
44
|
+
}
|
|
45
|
+
pre {
|
|
46
|
+
background-color: #f6f8fa;
|
|
47
|
+
border-radius: 6px;
|
|
48
|
+
padding: 16px;
|
|
49
|
+
overflow: auto;
|
|
50
|
+
}
|
|
51
|
+
code {
|
|
52
|
+
font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
|
|
53
|
+
font-size: 85%;
|
|
54
|
+
background-color: rgba(175, 184, 193, 0.2);
|
|
55
|
+
padding: 0.2em 0.4em;
|
|
56
|
+
border-radius: 6px;
|
|
57
|
+
}
|
|
58
|
+
pre code {
|
|
59
|
+
background-color: transparent;
|
|
60
|
+
padding: 0;
|
|
61
|
+
}
|
|
62
|
+
blockquote {
|
|
63
|
+
border-left: 0.25em solid #d0d7de;
|
|
64
|
+
color: #656d76;
|
|
65
|
+
padding: 0 1em;
|
|
66
|
+
margin: 0;
|
|
67
|
+
}
|
|
68
|
+
table {
|
|
69
|
+
border-spacing: 0;
|
|
70
|
+
border-collapse: collapse;
|
|
71
|
+
display: block;
|
|
72
|
+
width: max-content;
|
|
73
|
+
max-width: 100%;
|
|
74
|
+
overflow: auto;
|
|
75
|
+
}
|
|
76
|
+
table th,
|
|
77
|
+
table td {
|
|
78
|
+
padding: 6px 13px;
|
|
79
|
+
border: 1px solid #d0d7de;
|
|
80
|
+
}
|
|
81
|
+
table tr {
|
|
82
|
+
background-color: #ffffff;
|
|
83
|
+
border-top: 1px solid #d8dee4;
|
|
84
|
+
}
|
|
85
|
+
table tr:nth-child(2n) {
|
|
86
|
+
background-color: #f6f8fa;
|
|
87
|
+
}
|
|
88
|
+
</style>
|
|
89
|
+
<div class="markdown-body" id="content"></div>
|
|
90
|
+
`, this.container = this.shadowRoot.getElementById("content");
|
|
91
|
+
}
|
|
92
|
+
async loadLibrary() {
|
|
93
|
+
if (!(this._isLibLoaded || this._isLoadingLib)) {
|
|
94
|
+
if (typeof window.marked == "function" || typeof window.marked == "object" && typeof window.marked.parse == "function") {
|
|
95
|
+
this._isLibLoaded = !0, this.updateContent();
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
this._isLoadingLib = !0;
|
|
99
|
+
try {
|
|
100
|
+
const e = document.createElement("script");
|
|
101
|
+
e.src = this._libUrl, e.onload = () => {
|
|
102
|
+
if (!window.marked) {
|
|
103
|
+
console.error("MarkdownPreview: Library loaded but window.marked is undefined"), this.container.innerHTML = '<div style="color: red;">Error: Markdown library loaded but not found. Try a different URL.</div>', this._isLoadingLib = !1;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
this._isLibLoaded = !0, this._isLoadingLib = !1, this.updateContent(), this.dispatchEvent(new CustomEvent("library-loaded"));
|
|
107
|
+
}, e.onerror = () => {
|
|
108
|
+
this._isLoadingLib = !1, console.error(`Failed to load markdown library from ${this._libUrl}`), this.container.innerHTML = '<div style="color: red;">Error loading markdown library</div>';
|
|
109
|
+
}, document.head.appendChild(e);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
this._isLoadingLib = !1, console.error(e);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
updateContent() {
|
|
116
|
+
if (!this._isLibLoaded) {
|
|
117
|
+
this._isLoadingLib || this.loadLibrary();
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const e = window.marked;
|
|
121
|
+
if (!e) {
|
|
122
|
+
console.error("Marked library loaded but not found in window");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const o = typeof e == "function" ? e : e.parse;
|
|
127
|
+
if (typeof o == "function") {
|
|
128
|
+
const i = o(this._value);
|
|
129
|
+
i instanceof Promise ? i.then((t) => {
|
|
130
|
+
this.container.innerHTML = t;
|
|
131
|
+
}) : this.container.innerHTML = i;
|
|
132
|
+
} else
|
|
133
|
+
console.error("Marked parse function not found"), this.container.innerHTML = '<div style="color: red;">Error: marked.parse not found</div>';
|
|
134
|
+
} catch (o) {
|
|
135
|
+
console.error("Error parsing markdown:", o), this.container.innerHTML = '<div style="color: red;">Error parsing markdown</div>';
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const d = (r = "liwe3-markdown-preview") => {
|
|
140
|
+
typeof window < "u" && !customElements.get(r) && customElements.define(r, n);
|
|
141
|
+
};
|
|
142
|
+
d();
|
|
143
|
+
export {
|
|
144
|
+
n as MarkdownPreviewElement,
|
|
145
|
+
d as defineMarkdownPreview
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=MarkdownPreview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownPreview.js","sources":["../src/MarkdownPreview.ts"],"sourcesContent":["/**\n * MarkdownPreview Web Component\n * Renders markdown content using a dynamically loaded library\n */\n\nexport class MarkdownPreviewElement extends HTMLElement {\n declare shadowRoot: ShadowRoot;\n private _libUrl: string = 'https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js';\n private _value: string = '';\n private _isLibLoaded: boolean = false;\n private _isLoadingLib: boolean = false;\n private container!: HTMLElement;\n\n static get observedAttributes() {\n return ['lib-url', 'value'];\n }\n\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n this.render();\n }\n\n connectedCallback() {\n this.loadLibrary();\n }\n\n attributeChangedCallback(name: string, oldValue: string, newValue: string) {\n if (oldValue === newValue) return;\n\n if (name === 'lib-url') {\n this._libUrl = newValue;\n this._isLibLoaded = false; // Reset loaded state if URL changes\n this.loadLibrary();\n } else if (name === 'value') {\n // Only update internal value if it differs, to avoid loops if we were to reflect\n if (this._value !== newValue) {\n this.value = newValue;\n }\n }\n }\n\n get libUrl(): string {\n return this._libUrl;\n }\n\n set libUrl(value: string) {\n this.setAttribute('lib-url', value);\n }\n\n get value(): string {\n return this._value;\n }\n\n set value(content: string) {\n this._value = content;\n this.updateContent();\n // We do NOT reflect to attribute to avoid performance issues with large content\n }\n\n private render() {\n this.shadowRoot.innerHTML = `\n <style>\n :host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n line-height: 1.6;\n color: #333;\n }\n .markdown-body {\n box-sizing: border-box;\n min-width: 200px;\n max-width: 980px;\n margin: 0 auto;\n padding: 15px;\n }\n img {\n max-width: 100%;\n }\n pre {\n background-color: #f6f8fa;\n border-radius: 6px;\n padding: 16px;\n overflow: auto;\n }\n code {\n font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;\n font-size: 85%;\n background-color: rgba(175, 184, 193, 0.2);\n padding: 0.2em 0.4em;\n border-radius: 6px;\n }\n pre code {\n background-color: transparent;\n padding: 0;\n }\n blockquote {\n border-left: 0.25em solid #d0d7de;\n color: #656d76;\n padding: 0 1em;\n margin: 0;\n }\n table {\n border-spacing: 0;\n border-collapse: collapse;\n display: block;\n width: max-content;\n max-width: 100%;\n overflow: auto;\n }\n table th,\n table td {\n padding: 6px 13px;\n border: 1px solid #d0d7de;\n }\n table tr {\n background-color: #ffffff;\n border-top: 1px solid #d8dee4;\n }\n table tr:nth-child(2n) {\n background-color: #f6f8fa;\n }\n </style>\n <div class=\"markdown-body\" id=\"content\"></div>\n `;\n this.container = this.shadowRoot.getElementById('content') as HTMLElement;\n }\n\n private async loadLibrary() {\n if (this._isLibLoaded || this._isLoadingLib) return;\n\n // Check if marked is already available globally\n if (typeof (window as any).marked === 'function' || (typeof (window as any).marked === 'object' && typeof (window as any).marked.parse === 'function')) {\n this._isLibLoaded = true;\n this.updateContent();\n return;\n }\n\n this._isLoadingLib = true;\n\n try {\n const script = document.createElement('script');\n script.src = this._libUrl;\n script.onload = () => {\n // Double check if marked is available\n if (!(window as any).marked) {\n console.error('MarkdownPreview: Library loaded but window.marked is undefined');\n this.container.innerHTML = `<div style=\"color: red;\">Error: Markdown library loaded but not found. Try a different URL.</div>`;\n this._isLoadingLib = false;\n return;\n }\n this._isLibLoaded = true;\n this._isLoadingLib = false;\n this.updateContent();\n this.dispatchEvent(new CustomEvent('library-loaded'));\n };\n script.onerror = () => {\n this._isLoadingLib = false;\n console.error(`Failed to load markdown library from ${this._libUrl}`);\n this.container.innerHTML = `<div style=\"color: red;\">Error loading markdown library</div>`;\n };\n document.head.appendChild(script);\n } catch (e) {\n this._isLoadingLib = false;\n console.error(e);\n }\n }\n\n private updateContent() {\n if (!this._isLibLoaded) {\n if (!this._isLoadingLib) {\n this.loadLibrary();\n }\n return;\n }\n\n const marked = (window as any).marked;\n if (!marked) {\n console.error('Marked library loaded but not found in window');\n return;\n }\n\n try {\n // Handle both function style (older marked) and object style (newer marked)\n const parse = typeof marked === 'function' ? marked : marked.parse;\n if (typeof parse === 'function') {\n const html = parse(this._value);\n // If it returns a promise (async), handle it\n if (html instanceof Promise) {\n html.then((res: string) => {\n this.container.innerHTML = res;\n });\n } else {\n this.container.innerHTML = html;\n }\n } else {\n console.error('Marked parse function not found');\n this.container.innerHTML = `<div style=\"color: red;\">Error: marked.parse not found</div>`;\n }\n } catch (e) {\n console.error('Error parsing markdown:', e);\n this.container.innerHTML = `<div style=\"color: red;\">Error parsing markdown</div>`;\n }\n }\n}\n\nexport const defineMarkdownPreview = (tagName: string = 'liwe3-markdown-preview') => {\n if (typeof window !== 'undefined' && !customElements.get(tagName)) {\n customElements.define(tagName, MarkdownPreviewElement);\n }\n};\n\ndefineMarkdownPreview();\n"],"names":["MarkdownPreviewElement","name","oldValue","newValue","value","content","script","marked","parse","html","res","e","defineMarkdownPreview","tagName"],"mappings":"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"}
|