@liwe3/webcomponents 1.0.14 → 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.
Files changed (85) hide show
  1. package/dist/AIMarkdownEditor.d.ts +35 -0
  2. package/dist/AIMarkdownEditor.d.ts.map +1 -0
  3. package/dist/AIMarkdownEditor.js +412 -0
  4. package/dist/AIMarkdownEditor.js.map +1 -0
  5. package/dist/AITextEditor.d.ts +183 -0
  6. package/dist/AITextEditor.d.ts.map +1 -0
  7. package/dist/AITextEditor.js +63 -27
  8. package/dist/AITextEditor.js.map +1 -1
  9. package/dist/ButtonToolbar.d.ts +35 -0
  10. package/dist/ButtonToolbar.d.ts.map +1 -0
  11. package/dist/ButtonToolbar.js +220 -0
  12. package/dist/ButtonToolbar.js.map +1 -0
  13. package/dist/CheckList.d.ts +31 -0
  14. package/dist/CheckList.d.ts.map +1 -0
  15. package/dist/CheckList.js +336 -0
  16. package/dist/CheckList.js.map +1 -0
  17. package/dist/ChunkUploader.d.ts +125 -0
  18. package/dist/ChunkUploader.d.ts.map +1 -0
  19. package/dist/ChunkUploader.js +756 -0
  20. package/dist/ChunkUploader.js.map +1 -0
  21. package/dist/ComicBalloon.d.ts +82 -0
  22. package/dist/ComicBalloon.d.ts.map +1 -0
  23. package/dist/ComicBalloon.js +346 -0
  24. package/dist/ComicBalloon.js.map +1 -0
  25. package/dist/ContainerBox.d.ts +112 -0
  26. package/dist/ContainerBox.d.ts.map +1 -0
  27. package/dist/ContainerBox.js +359 -0
  28. package/dist/ContainerBox.js.map +1 -0
  29. package/dist/DateSelector.d.ts +103 -0
  30. package/dist/DateSelector.d.ts.map +1 -0
  31. package/dist/Dialog.d.ts +102 -0
  32. package/dist/Dialog.d.ts.map +1 -0
  33. package/dist/Dialog.js +299 -0
  34. package/dist/Dialog.js.map +1 -0
  35. package/dist/Drawer.d.ts +63 -0
  36. package/dist/Drawer.d.ts.map +1 -0
  37. package/dist/Drawer.js +340 -0
  38. package/dist/Drawer.js.map +1 -0
  39. package/dist/ImageView.d.ts +42 -0
  40. package/dist/ImageView.d.ts.map +1 -0
  41. package/dist/ImageView.js +209 -0
  42. package/dist/ImageView.js.map +1 -0
  43. package/dist/MarkdownPreview.d.ts +25 -0
  44. package/dist/MarkdownPreview.d.ts.map +1 -0
  45. package/dist/MarkdownPreview.js +147 -0
  46. package/dist/MarkdownPreview.js.map +1 -0
  47. package/dist/PopoverMenu.d.ts +103 -0
  48. package/dist/PopoverMenu.d.ts.map +1 -0
  49. package/dist/ResizableCropper.d.ts +158 -0
  50. package/dist/ResizableCropper.d.ts.map +1 -0
  51. package/dist/ResizableCropper.js +562 -0
  52. package/dist/ResizableCropper.js.map +1 -0
  53. package/dist/SmartSelect.d.ts +100 -0
  54. package/dist/SmartSelect.d.ts.map +1 -0
  55. package/dist/SmartSelect.js +45 -2
  56. package/dist/SmartSelect.js.map +1 -1
  57. package/dist/Toast.d.ts +127 -0
  58. package/dist/Toast.d.ts.map +1 -0
  59. package/dist/Toast.js +79 -49
  60. package/dist/Toast.js.map +1 -1
  61. package/dist/TreeView.d.ts +84 -0
  62. package/dist/TreeView.d.ts.map +1 -0
  63. package/dist/TreeView.js +478 -0
  64. package/dist/TreeView.js.map +1 -0
  65. package/dist/index.d.ts +23 -0
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js +51 -14
  68. package/dist/index.js.map +1 -1
  69. package/package.json +60 -5
  70. package/src/AIMarkdownEditor.ts +568 -0
  71. package/src/AITextEditor.ts +97 -2
  72. package/src/ButtonToolbar.ts +302 -0
  73. package/src/CheckList.ts +438 -0
  74. package/src/ChunkUploader.ts +1135 -0
  75. package/src/ComicBalloon.ts +709 -0
  76. package/src/ContainerBox.ts +570 -0
  77. package/src/Dialog.ts +510 -0
  78. package/src/Drawer.ts +435 -0
  79. package/src/ImageView.ts +265 -0
  80. package/src/MarkdownPreview.ts +213 -0
  81. package/src/ResizableCropper.ts +1099 -0
  82. package/src/SmartSelect.ts +48 -2
  83. package/src/Toast.ts +96 -32
  84. package/src/TreeView.ts +673 -0
  85. package/src/index.ts +129 -27
@@ -0,0 +1,220 @@
1
+ class l extends HTMLElement {
2
+ constructor() {
3
+ super(), this._groups = [], this.attachShadow({ mode: "open" });
4
+ }
5
+ static get observedAttributes() {
6
+ return ["orientation", "groups"];
7
+ }
8
+ attributeChangedCallback(o, i, n) {
9
+ i !== n && this.render();
10
+ }
11
+ get orientation() {
12
+ return this.getAttribute("orientation") || "horizontal";
13
+ }
14
+ set orientation(o) {
15
+ this.setAttribute("orientation", o);
16
+ }
17
+ get groups() {
18
+ const o = this.getAttribute("groups");
19
+ if (o)
20
+ try {
21
+ return JSON.parse(o);
22
+ } catch (i) {
23
+ return console.error("Invalid groups format:", i), [];
24
+ }
25
+ return this._groups;
26
+ }
27
+ set groups(o) {
28
+ this._groups = o, this.setAttribute("groups", JSON.stringify(o));
29
+ }
30
+ connectedCallback() {
31
+ this.render();
32
+ }
33
+ handleButtonClick(o, i) {
34
+ o.disabled || this.dispatchEvent(new CustomEvent("button-click", {
35
+ detail: {
36
+ id: o.id,
37
+ action: o.action || o.id,
38
+ originalEvent: i,
39
+ item: o
40
+ },
41
+ bubbles: !0,
42
+ composed: !0
43
+ }));
44
+ }
45
+ render() {
46
+ if (!this.shadowRoot) return;
47
+ const o = `
48
+ :host {
49
+ display: block;
50
+ font-family: var(--liwe3-font-family, system-ui, -apple-system, sans-serif);
51
+ }
52
+
53
+ .toolbar {
54
+ display: flex;
55
+ gap: var(--liwe3-toolbar-gap, 0.5rem);
56
+ width: 100%;
57
+ box-sizing: border-box;
58
+ }
59
+
60
+ .toolbar.horizontal {
61
+ flex-direction: row;
62
+ align-items: center;
63
+ }
64
+
65
+ .toolbar.vertical {
66
+ flex-direction: column;
67
+ align-items: stretch;
68
+ }
69
+
70
+ .group {
71
+ display: flex;
72
+ gap: 1px; /* Gap between buttons in a group */
73
+ background-color: var(--liwe3-toolbar-group-bg, transparent);
74
+ border-radius: var(--liwe3-toolbar-radius, 0.375rem);
75
+ overflow: hidden;
76
+ }
77
+
78
+ .toolbar.horizontal .group {
79
+ flex-direction: row;
80
+ }
81
+
82
+ .toolbar.vertical .group {
83
+ flex-direction: column;
84
+ }
85
+
86
+ .button {
87
+ display: inline-flex;
88
+ align-items: center;
89
+ justify-content: center;
90
+ gap: 0.5rem;
91
+ padding: var(--liwe3-button-padding, 0.5rem 1rem);
92
+ border: none;
93
+ cursor: pointer;
94
+ font-size: var(--liwe3-button-font-size, 0.875rem);
95
+ line-height: 1.25;
96
+ transition: all 0.2s;
97
+ background-color: var(--liwe3-button-bg, #f3f4f6);
98
+ color: var(--liwe3-button-color, #1f2937);
99
+ min-height: var(--liwe3-button-height, 2.5rem);
100
+ }
101
+
102
+ .button:hover:not(:disabled) {
103
+ filter: brightness(0.95);
104
+ }
105
+
106
+ .button:active:not(:disabled) {
107
+ filter: brightness(0.9);
108
+ }
109
+
110
+ .button:disabled {
111
+ opacity: 0.5;
112
+ cursor: not-allowed;
113
+ }
114
+
115
+ /* Button Types */
116
+ .button.default {
117
+ background-color: var(--liwe3-button-default-bg, #f3f4f6);
118
+ color: var(--liwe3-button-default-color, #1f2937);
119
+ }
120
+
121
+ .button.info {
122
+ background-color: var(--liwe3-button-info-bg, #3b82f6);
123
+ color: var(--liwe3-button-info-color, #ffffff);
124
+ }
125
+
126
+ .button.error {
127
+ background-color: var(--liwe3-button-error-bg, #ef4444);
128
+ color: var(--liwe3-button-error-color, #ffffff);
129
+ }
130
+
131
+ .button.warn {
132
+ background-color: var(--liwe3-button-warn-bg, #f59e0b);
133
+ color: var(--liwe3-button-warn-color, #ffffff);
134
+ }
135
+
136
+ .button.success {
137
+ background-color: var(--liwe3-button-success-bg, #10b981);
138
+ color: var(--liwe3-button-success-color, #ffffff);
139
+ }
140
+
141
+ /* Content styling */
142
+ .icon {
143
+ width: 1.25em;
144
+ height: 1.25em;
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: center;
148
+ }
149
+
150
+ .icon svg {
151
+ width: 100%;
152
+ height: 100%;
153
+ fill: currentColor;
154
+ }
155
+
156
+ .image {
157
+ width: 1.5em;
158
+ height: 1.5em;
159
+ object-fit: cover;
160
+ border-radius: 50%;
161
+ }
162
+
163
+ /* Group styling - rounded corners logic */
164
+ .toolbar.horizontal .group .button:first-child {
165
+ border-top-left-radius: var(--liwe3-toolbar-radius, 0.375rem);
166
+ border-bottom-left-radius: var(--liwe3-toolbar-radius, 0.375rem);
167
+ }
168
+
169
+ .toolbar.horizontal .group .button:last-child {
170
+ border-top-right-radius: var(--liwe3-toolbar-radius, 0.375rem);
171
+ border-bottom-right-radius: var(--liwe3-toolbar-radius, 0.375rem);
172
+ }
173
+
174
+ .toolbar.vertical .group .button:first-child {
175
+ border-top-left-radius: var(--liwe3-toolbar-radius, 0.375rem);
176
+ border-top-right-radius: var(--liwe3-toolbar-radius, 0.375rem);
177
+ }
178
+
179
+ .toolbar.vertical .group .button:last-child {
180
+ border-bottom-left-radius: var(--liwe3-toolbar-radius, 0.375rem);
181
+ border-bottom-right-radius: var(--liwe3-toolbar-radius, 0.375rem);
182
+ }
183
+ `, i = (t) => {
184
+ const e = document.createElement("button");
185
+ if (e.className = `button ${t.type || "default"}`, t.disabled && (e.disabled = !0), t.tooltip && (e.title = t.tooltip), e.onclick = (r) => this.handleButtonClick(t, r), t.icon) {
186
+ const r = document.createElement("span");
187
+ if (r.className = "icon", t.icon.trim().startsWith("<"))
188
+ r.innerHTML = t.icon;
189
+ else {
190
+ const a = document.createElement("i");
191
+ a.className = t.icon, r.appendChild(a);
192
+ }
193
+ e.appendChild(r);
194
+ }
195
+ if (t.image) {
196
+ const r = document.createElement("img");
197
+ r.src = t.image, r.className = "image", r.alt = t.label || "", e.appendChild(r);
198
+ }
199
+ if (t.label) {
200
+ const r = document.createElement("span");
201
+ r.textContent = t.label, e.appendChild(r);
202
+ }
203
+ return e;
204
+ }, n = document.createElement("div");
205
+ n.className = `toolbar ${this.orientation}`, this._groups.forEach((t) => {
206
+ const e = document.createElement("div");
207
+ e.className = `group ${t.class || ""}`, t.items.forEach((r) => {
208
+ e.appendChild(i(r));
209
+ }), n.appendChild(e);
210
+ }), this.shadowRoot.innerHTML = `<style>${o}</style>`, this.shadowRoot.appendChild(n);
211
+ }
212
+ }
213
+ const u = () => {
214
+ typeof window < "u" && !customElements.get("liwe3-button-toolbar") && customElements.define("liwe3-button-toolbar", l);
215
+ };
216
+ export {
217
+ l as ButtonToolbarElement,
218
+ u as defineButtonToolbar
219
+ };
220
+ //# sourceMappingURL=ButtonToolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonToolbar.js","sources":["../src/ButtonToolbar.ts"],"sourcesContent":["/**\n * ButtonToolbar Web Component\n * A customizable toolbar with groups of buttons, supporting horizontal/vertical orientation\n */\n\nexport type ButtonToolbarItem = {\n id: string;\n label?: string;\n icon?: string; // SVG content or icon class\n image?: string; // Image URL\n type?: 'default' | 'info' | 'error' | 'warn' | 'success';\n disabled?: boolean;\n tooltip?: string;\n action?: string; // Optional action name to dispatch\n};\n\nexport type ButtonToolbarGroup = {\n id?: string;\n items: ButtonToolbarItem[];\n class?: string; // Optional CSS class for the group\n};\n\nexport class ButtonToolbarElement extends HTMLElement {\n declare shadowRoot: ShadowRoot;\n private _groups: ButtonToolbarGroup[] = [];\n\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n }\n\n static get observedAttributes(): string[] {\n return ['orientation', 'groups'];\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue !== newValue) {\n this.render();\n }\n }\n\n get orientation(): 'horizontal' | 'vertical' {\n return (this.getAttribute('orientation') as 'horizontal' | 'vertical') || 'horizontal';\n }\n\n set orientation(value: 'horizontal' | 'vertical') {\n this.setAttribute('orientation', value);\n }\n\n get groups(): ButtonToolbarGroup[] {\n const groupsAttr = this.getAttribute('groups');\n if (groupsAttr) {\n try {\n return JSON.parse(groupsAttr);\n } catch (e) {\n console.error('Invalid groups format:', e);\n return [];\n }\n }\n return this._groups;\n }\n\n set groups(value: ButtonToolbarGroup[]) {\n this._groups = value;\n // Also update attribute for consistency, but be careful with large data\n // For now, let's just render. If we want to sync property to attribute:\n // this.setAttribute('groups', JSON.stringify(value));\n // But usually for complex data, property is preferred source of truth if set directly.\n \n // SmartSelect implementation:\n // set options ( opts: SelectOption[] ) {\n // this.setAttribute( 'options', JSON.stringify( opts ) );\n // }\n \n // I'll follow SmartSelect pattern for consistency\n this.setAttribute('groups', JSON.stringify(value));\n }\n\n connectedCallback(): void {\n this.render();\n }\n\n private handleButtonClick(item: ButtonToolbarItem, event: Event): void {\n if (item.disabled) return;\n \n this.dispatchEvent(new CustomEvent('button-click', {\n detail: {\n id: item.id,\n action: item.action || item.id,\n originalEvent: event,\n item\n },\n bubbles: true,\n composed: true\n }));\n }\n\n private render(): void {\n if (!this.shadowRoot) return;\n\n const style = `\n :host {\n display: block;\n font-family: var(--liwe3-font-family, system-ui, -apple-system, sans-serif);\n }\n\n .toolbar {\n display: flex;\n gap: var(--liwe3-toolbar-gap, 0.5rem);\n width: 100%;\n box-sizing: border-box;\n }\n\n .toolbar.horizontal {\n flex-direction: row;\n align-items: center;\n }\n\n .toolbar.vertical {\n flex-direction: column;\n align-items: stretch;\n }\n\n .group {\n display: flex;\n gap: 1px; /* Gap between buttons in a group */\n background-color: var(--liwe3-toolbar-group-bg, transparent);\n border-radius: var(--liwe3-toolbar-radius, 0.375rem);\n overflow: hidden;\n }\n\n .toolbar.horizontal .group {\n flex-direction: row;\n }\n\n .toolbar.vertical .group {\n flex-direction: column;\n }\n\n .button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: var(--liwe3-button-padding, 0.5rem 1rem);\n border: none;\n cursor: pointer;\n font-size: var(--liwe3-button-font-size, 0.875rem);\n line-height: 1.25;\n transition: all 0.2s;\n background-color: var(--liwe3-button-bg, #f3f4f6);\n color: var(--liwe3-button-color, #1f2937);\n min-height: var(--liwe3-button-height, 2.5rem);\n }\n\n .button:hover:not(:disabled) {\n filter: brightness(0.95);\n }\n\n .button:active:not(:disabled) {\n filter: brightness(0.9);\n }\n\n .button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* Button Types */\n .button.default {\n background-color: var(--liwe3-button-default-bg, #f3f4f6);\n color: var(--liwe3-button-default-color, #1f2937);\n }\n\n .button.info {\n background-color: var(--liwe3-button-info-bg, #3b82f6);\n color: var(--liwe3-button-info-color, #ffffff);\n }\n\n .button.error {\n background-color: var(--liwe3-button-error-bg, #ef4444);\n color: var(--liwe3-button-error-color, #ffffff);\n }\n\n .button.warn {\n background-color: var(--liwe3-button-warn-bg, #f59e0b);\n color: var(--liwe3-button-warn-color, #ffffff);\n }\n \n .button.success {\n background-color: var(--liwe3-button-success-bg, #10b981);\n color: var(--liwe3-button-success-color, #ffffff);\n }\n\n /* Content styling */\n .icon {\n width: 1.25em;\n height: 1.25em;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n .icon svg {\n width: 100%;\n height: 100%;\n fill: currentColor;\n }\n\n .image {\n width: 1.5em;\n height: 1.5em;\n object-fit: cover;\n border-radius: 50%;\n }\n \n /* Group styling - rounded corners logic */\n .toolbar.horizontal .group .button:first-child {\n border-top-left-radius: var(--liwe3-toolbar-radius, 0.375rem);\n border-bottom-left-radius: var(--liwe3-toolbar-radius, 0.375rem);\n }\n \n .toolbar.horizontal .group .button:last-child {\n border-top-right-radius: var(--liwe3-toolbar-radius, 0.375rem);\n border-bottom-right-radius: var(--liwe3-toolbar-radius, 0.375rem);\n }\n \n .toolbar.vertical .group .button:first-child {\n border-top-left-radius: var(--liwe3-toolbar-radius, 0.375rem);\n border-top-right-radius: var(--liwe3-toolbar-radius, 0.375rem);\n }\n \n .toolbar.vertical .group .button:last-child {\n border-bottom-left-radius: var(--liwe3-toolbar-radius, 0.375rem);\n border-bottom-right-radius: var(--liwe3-toolbar-radius, 0.375rem);\n }\n `;\n\n const renderButton = (item: ButtonToolbarItem) => {\n const btn = document.createElement('button');\n btn.className = `button ${item.type || 'default'}`;\n if (item.disabled) btn.disabled = true;\n if (item.tooltip) btn.title = item.tooltip;\n \n btn.onclick = (e) => this.handleButtonClick(item, e);\n\n if (item.icon) {\n const iconSpan = document.createElement('span');\n iconSpan.className = 'icon';\n // Check if it's an SVG string or just a class name (simple heuristic)\n if (item.icon.trim().startsWith('<')) {\n iconSpan.innerHTML = item.icon;\n } else {\n // Assuming it might be a class name if not SVG\n const i = document.createElement('i');\n i.className = item.icon;\n iconSpan.appendChild(i);\n }\n btn.appendChild(iconSpan);\n }\n\n if (item.image) {\n const img = document.createElement('img');\n img.src = item.image;\n img.className = 'image';\n img.alt = item.label || '';\n btn.appendChild(img);\n }\n\n if (item.label) {\n const span = document.createElement('span');\n span.textContent = item.label;\n btn.appendChild(span);\n }\n\n return btn;\n };\n\n const container = document.createElement('div');\n container.className = `toolbar ${this.orientation}`;\n\n this._groups.forEach(group => {\n const groupDiv = document.createElement('div');\n groupDiv.className = `group ${group.class || ''}`;\n \n group.items.forEach(item => {\n groupDiv.appendChild(renderButton(item));\n });\n \n container.appendChild(groupDiv);\n });\n\n this.shadowRoot.innerHTML = `<style>${style}</style>`;\n this.shadowRoot.appendChild(container);\n }\n}\n\nexport const defineButtonToolbar = (): void => {\n if (typeof window !== 'undefined' && !customElements.get('liwe3-button-toolbar')) {\n customElements.define('liwe3-button-toolbar', ButtonToolbarElement);\n }\n};\n"],"names":["ButtonToolbarElement","_name","oldValue","newValue","value","groupsAttr","e","item","event","style","renderButton","btn","iconSpan","i","img","span","container","group","groupDiv","defineButtonToolbar"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * CheckList Web Component
3
+ * A customizable checklist with progress bar and JSON support
4
+ */
5
+ export type CheckListItem = {
6
+ label: string;
7
+ checked: boolean;
8
+ };
9
+ export declare class CheckListElement extends HTMLElement {
10
+ shadowRoot: ShadowRoot;
11
+ private _items;
12
+ private _title;
13
+ constructor();
14
+ static get observedAttributes(): string[];
15
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
16
+ get title(): string;
17
+ set title(value: string);
18
+ get items(): CheckListItem[];
19
+ set items(value: CheckListItem[]);
20
+ get percentage(): number;
21
+ loadJSON(json: string): void;
22
+ toJSON(): string;
23
+ private addItem;
24
+ private removeItem;
25
+ private toggleItem;
26
+ private updateItemLabel;
27
+ private render;
28
+ private bindEvents;
29
+ }
30
+ export declare const defineCheckList: (tagName?: string) => void;
31
+ //# sourceMappingURL=CheckList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckList.d.ts","sourceRoot":"","sources":["../src/CheckList.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,WAAW;IACvC,UAAU,EAAE,UAAU,CAAC;IAC/B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAuB;;IAQrC,MAAM,KAAK,kBAAkB,IAAK,MAAM,EAAE,CAEzC;IAED,wBAAwB,CAAG,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAI,IAAI;IAejG,IAAI,KAAK,IAAK,MAAM,CAEnB;IAED,IAAI,KAAK,CAAG,KAAK,EAAE,MAAM,EAIxB;IAED,IAAI,KAAK,IAAK,aAAa,EAAE,CAE5B;IAED,IAAI,KAAK,CAAG,KAAK,EAAE,aAAa,EAAE,EAIjC;IAED,IAAI,UAAU,IAAK,MAAM,CAIxB;IAED,QAAQ,CAAG,IAAI,EAAE,MAAM,GAAI,IAAI;IAY/B,MAAM,IAAK,MAAM;IAOjB,OAAO,CAAC,OAAO;IAaf,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,MAAM;IA0Pd,OAAO,CAAC,UAAU;CA+DnB;AAED,eAAO,MAAM,eAAe,GAAK,UAAS,MAA0B,KAAI,IAIvE,CAAC"}
@@ -0,0 +1,336 @@
1
+ class c extends HTMLElement {
2
+ constructor() {
3
+ super(), this._items = [], this._title = "Checklist", this.attachShadow({ mode: "open" }), this.render();
4
+ }
5
+ static get observedAttributes() {
6
+ return ["title", "items"];
7
+ }
8
+ attributeChangedCallback(t, e, i) {
9
+ if (e !== i) {
10
+ if (t === "title")
11
+ this._title = i || "Checklist";
12
+ else if (t === "items" && i)
13
+ try {
14
+ this._items = JSON.parse(i);
15
+ } catch (r) {
16
+ console.error("Invalid items JSON:", r);
17
+ }
18
+ this.render();
19
+ }
20
+ }
21
+ get title() {
22
+ return this._title;
23
+ }
24
+ set title(t) {
25
+ this._title = t, this.setAttribute("title", t), this.render();
26
+ }
27
+ get items() {
28
+ return [...this._items];
29
+ }
30
+ set items(t) {
31
+ this._items = [...t], this.render(), this.dispatchEvent(new CustomEvent("change", { detail: { items: this._items } }));
32
+ }
33
+ get percentage() {
34
+ if (this._items.length === 0) return 0;
35
+ const t = this._items.filter((e) => e.checked).length;
36
+ return Math.round(t / this._items.length * 100);
37
+ }
38
+ loadJSON(t) {
39
+ try {
40
+ const e = JSON.parse(t);
41
+ e.title && (this.title = e.title), e.items && Array.isArray(e.items) && (this.items = e.items);
42
+ } catch (e) {
43
+ console.error("Error loading JSON:", e);
44
+ }
45
+ }
46
+ toJSON() {
47
+ return JSON.stringify({
48
+ title: this.title,
49
+ items: this.items
50
+ }, null, 2);
51
+ }
52
+ addItem(t) {
53
+ t.trim() && (this._items.push({ label: t, checked: !1 }), this.render(), this.dispatchEvent(new CustomEvent("change", { detail: { items: this._items } })), requestAnimationFrame(() => {
54
+ const e = this.shadowRoot.querySelector(".add-item-input");
55
+ e && e.focus();
56
+ }));
57
+ }
58
+ removeItem(t) {
59
+ this._items.splice(t, 1), this.render(), this.dispatchEvent(new CustomEvent("change", { detail: { items: this._items } }));
60
+ }
61
+ toggleItem(t) {
62
+ this._items[t].checked = !this._items[t].checked, this.render(), this.dispatchEvent(new CustomEvent("change", { detail: { items: this._items } }));
63
+ }
64
+ updateItemLabel(t, e) {
65
+ this._items[t].label = e, this.dispatchEvent(new CustomEvent("change", { detail: { items: this._items } }));
66
+ }
67
+ render() {
68
+ const t = this.percentage, e = this._items.filter((n) => n.checked).length, i = this._items.length;
69
+ this.shadowRoot.querySelector(".list") || (this.shadowRoot.innerHTML = `
70
+ <style>
71
+ :host {
72
+ display: block;
73
+ font-family: var(--font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
74
+ background: var(--background, #fff);
75
+ border-radius: var(--border-radius, 8px);
76
+ padding: var(--padding, 16px);
77
+ box-shadow: var(--box-shadow, 0 2px 4px rgba(0,0,0,0.1));
78
+ max-width: var(--max-width, 100%);
79
+ }
80
+
81
+ .header {
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: space-between;
85
+ margin-bottom: 16px;
86
+ }
87
+
88
+ .title {
89
+ font-size: 1.1rem;
90
+ font-weight: 600;
91
+ display: flex;
92
+ align-items: center;
93
+ gap: 8px;
94
+ color: var(--text-color, #333);
95
+ }
96
+
97
+ .title-icon {
98
+ width: 20px;
99
+ height: 20px;
100
+ fill: currentColor;
101
+ }
102
+
103
+ .progress-container {
104
+ display: flex;
105
+ align-items: center;
106
+ gap: 12px;
107
+ margin-bottom: 20px;
108
+ }
109
+
110
+ .progress-text {
111
+ font-size: 0.9rem;
112
+ font-weight: 600;
113
+ color: var(--text-color, #333);
114
+ min-width: 40px;
115
+ }
116
+
117
+ .progress-bar-bg {
118
+ flex: 1;
119
+ height: 6px;
120
+ background: #e0e0e0;
121
+ border-radius: 3px;
122
+ overflow: hidden;
123
+ }
124
+
125
+ .progress-bar-fill {
126
+ height: 100%;
127
+ background: var(--primary-color, #1976d2);
128
+ width: 0%;
129
+ transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);
130
+ }
131
+
132
+ .list {
133
+ display: flex;
134
+ flex-direction: column;
135
+ gap: 8px;
136
+ }
137
+
138
+ .list-item {
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 12px;
142
+ padding: 4px 0;
143
+ }
144
+
145
+ .checkbox {
146
+ width: 20px;
147
+ height: 20px;
148
+ border: 2px solid #757575;
149
+ border-radius: 4px;
150
+ cursor: pointer;
151
+ display: flex;
152
+ align-items: center;
153
+ justify-content: center;
154
+ transition: all 0.2s;
155
+ flex-shrink: 0;
156
+ }
157
+
158
+ .checkbox.checked {
159
+ background: var(--primary-color, #1976d2);
160
+ border-color: var(--primary-color, #1976d2);
161
+ }
162
+
163
+ .checkbox svg {
164
+ width: 14px;
165
+ height: 14px;
166
+ fill: white;
167
+ display: none;
168
+ }
169
+
170
+ .checkbox.checked svg {
171
+ display: block;
172
+ }
173
+
174
+ .item-input {
175
+ flex: 1;
176
+ padding: 8px 12px;
177
+ border: 1px solid #e0e0e0;
178
+ border-radius: 4px;
179
+ font-size: 0.95rem;
180
+ outline: none;
181
+ transition: border-color 0.2s;
182
+ color: var(--text-color, #333);
183
+ }
184
+
185
+ .item-input:focus {
186
+ border-color: var(--primary-color, #1976d2);
187
+ }
188
+
189
+ .item-input.add-item-input {
190
+ color: #666;
191
+ }
192
+
193
+ .item-input.add-item-input::placeholder {
194
+ color: #999;
195
+ }
196
+
197
+ .delete-btn {
198
+ background: none;
199
+ border: none;
200
+ cursor: pointer;
201
+ padding: 4px;
202
+ color: #9e9e9e;
203
+ transition: color 0.2s;
204
+ display: flex;
205
+ align-items: center;
206
+ justify-content: center;
207
+ }
208
+
209
+ .delete-btn:hover {
210
+ color: #f44336;
211
+ }
212
+
213
+ .delete-btn svg {
214
+ width: 18px;
215
+ height: 18px;
216
+ fill: currentColor;
217
+ }
218
+
219
+ .add-btn {
220
+ background: #f5f5f5;
221
+ border: none;
222
+ border-radius: 50%;
223
+ width: 32px;
224
+ height: 32px;
225
+ display: flex;
226
+ align-items: center;
227
+ justify-content: center;
228
+ cursor: pointer;
229
+ color: #757575;
230
+ transition: background 0.2s;
231
+ }
232
+
233
+ .add-btn:hover {
234
+ background: #e0e0e0;
235
+ }
236
+ </style>
237
+
238
+ <div class="header">
239
+ <div class="title">
240
+ <svg class="title-icon" viewBox="0 0 24 24">
241
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
242
+ </svg>
243
+ <span class="title-text">${this._title}</span>
244
+ </div>
245
+ <slot name="menu"></slot>
246
+ </div>
247
+
248
+ <div class="progress-container">
249
+ <div class="progress-text"></div>
250
+ <div class="progress-bar-bg">
251
+ <div class="progress-bar-fill"></div>
252
+ </div>
253
+ </div>
254
+
255
+ <div class="list"></div>
256
+ `);
257
+ const r = this.shadowRoot.querySelector(".title-text");
258
+ r && (r.textContent = this._title);
259
+ const s = this.shadowRoot.querySelector(".progress-text");
260
+ s && (s.textContent = `${e} / ${i}`);
261
+ const o = this.shadowRoot.querySelector(".progress-bar-fill");
262
+ o && (o.style.width = `${t}%`);
263
+ const l = this.shadowRoot.querySelector(".list");
264
+ l && (l.innerHTML = `
265
+ ${this._items.map((n, a) => `
266
+ <div class="list-item">
267
+ <div class="checkbox ${n.checked ? "checked" : ""}" data-index="${a}">
268
+ <svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
269
+ </div>
270
+ <input
271
+ type="text"
272
+ class="item-input"
273
+ value="${n.label}"
274
+ data-index="${a}"
275
+ >
276
+ <button class="delete-btn" data-index="${a}" title="Delete item">
277
+ <svg viewBox="0 0 24 24">
278
+ <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/>
279
+ </svg>
280
+ </button>
281
+ </div>
282
+ `).join("")}
283
+
284
+ <div class="list-item">
285
+ <div class="checkbox" style="border-color: transparent; cursor: default;"></div>
286
+ <input
287
+ type="text"
288
+ class="item-input add-item-input"
289
+ placeholder="Add an item"
290
+ >
291
+ <div class="add-btn" title="Add item">
292
+ <svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
293
+ <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
294
+ </svg>
295
+ </div>
296
+ </div>
297
+ `), this.bindEvents();
298
+ }
299
+ bindEvents() {
300
+ this.shadowRoot.querySelectorAll(".checkbox").forEach((i) => {
301
+ i.addEventListener("click", (r) => {
302
+ const s = r.currentTarget.dataset.index;
303
+ s !== void 0 && this.toggleItem(parseInt(s));
304
+ });
305
+ }), this.shadowRoot.querySelectorAll(".delete-btn").forEach((i) => {
306
+ i.addEventListener("click", (r) => {
307
+ const s = r.currentTarget.dataset.index;
308
+ s !== void 0 && this.removeItem(parseInt(s));
309
+ });
310
+ }), this.shadowRoot.querySelectorAll(".item-input:not(.add-item-input)").forEach((i) => {
311
+ i.addEventListener("input", (r) => {
312
+ const s = r.target, o = s.dataset.index;
313
+ o !== void 0 && this.updateItemLabel(parseInt(o), s.value);
314
+ });
315
+ });
316
+ const t = this.shadowRoot.querySelector(".add-item-input");
317
+ t && (t.addEventListener("keydown", (i) => {
318
+ i.key === "Enter" && (this.addItem(t.value), t.value = "");
319
+ }), t.addEventListener("blur", () => {
320
+ t.value.trim() && (this.addItem(t.value), t.value = "");
321
+ }));
322
+ const e = this.shadowRoot.querySelector(".add-btn");
323
+ e && t && e.addEventListener("click", () => {
324
+ t.value.trim() ? (this.addItem(t.value), t.value = "") : t.focus();
325
+ });
326
+ }
327
+ }
328
+ const h = (d = "liwe3-checklist") => {
329
+ typeof window < "u" && !window.customElements.get(d) && customElements.define(d, c);
330
+ };
331
+ h();
332
+ export {
333
+ c as CheckListElement,
334
+ h as defineCheckList
335
+ };
336
+ //# sourceMappingURL=CheckList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckList.js","sources":["../src/CheckList.ts"],"sourcesContent":["/**\n * CheckList Web Component\n * A customizable checklist with progress bar and JSON support\n */\n\nexport type CheckListItem = {\n label: string;\n checked: boolean;\n};\n\nexport class CheckListElement extends HTMLElement {\n declare shadowRoot: ShadowRoot;\n private _items: CheckListItem[] = [];\n private _title: string = 'Checklist';\n\n constructor () {\n super();\n this.attachShadow( { mode: 'open' } );\n this.render();\n }\n\n static get observedAttributes (): string[] {\n return [ 'title', 'items' ];\n }\n\n attributeChangedCallback ( name: string, oldValue: string | null, newValue: string | null ): void {\n if ( oldValue !== newValue ) {\n if ( name === 'title' ) {\n this._title = newValue || 'Checklist';\n } else if ( name === 'items' && newValue ) {\n try {\n this._items = JSON.parse( newValue );\n } catch ( e ) {\n console.error( 'Invalid items JSON:', e );\n }\n }\n this.render();\n }\n }\n\n get title (): string {\n return this._title;\n }\n\n set title ( value: string ) {\n this._title = value;\n this.setAttribute( 'title', value );\n this.render();\n }\n\n get items (): CheckListItem[] {\n return [ ...this._items ];\n }\n\n set items ( value: CheckListItem[] ) {\n this._items = [ ...value ];\n this.render();\n this.dispatchEvent( new CustomEvent( 'change', { detail: { items: this._items } } ) );\n }\n\n get percentage (): number {\n if ( this._items.length === 0 ) return 0;\n const completed = this._items.filter( item => item.checked ).length;\n return Math.round( ( completed / this._items.length ) * 100 );\n }\n\n loadJSON ( json: string ): void {\n try {\n const data = JSON.parse( json );\n if ( data.title ) this.title = data.title;\n if ( data.items && Array.isArray( data.items ) ) {\n this.items = data.items;\n }\n } catch ( e ) {\n console.error( 'Error loading JSON:', e );\n }\n }\n\n toJSON (): string {\n return JSON.stringify( {\n title: this.title,\n items: this.items\n }, null, 2 );\n }\n\n private addItem ( label: string ): void {\n if ( !label.trim() ) return;\n this._items.push( { label, checked: false } );\n this.render();\n this.dispatchEvent( new CustomEvent( 'change', { detail: { items: this._items } } ) );\n \n // Focus the new add item input after rendering\n requestAnimationFrame( () => {\n const addInput = this.shadowRoot.querySelector( '.add-item-input' ) as HTMLInputElement;\n if ( addInput ) addInput.focus();\n } );\n }\n\n private removeItem ( index: number ): void {\n this._items.splice( index, 1 );\n this.render();\n this.dispatchEvent( new CustomEvent( 'change', { detail: { items: this._items } } ) );\n }\n\n private toggleItem ( index: number ): void {\n this._items[ index ].checked = !this._items[ index ].checked;\n this.render();\n this.dispatchEvent( new CustomEvent( 'change', { detail: { items: this._items } } ) );\n }\n\n private updateItemLabel ( index: number, label: string ): void {\n this._items[ index ].label = label;\n // We don't re-render here to avoid losing focus, just update the model\n this.dispatchEvent( new CustomEvent( 'change', { detail: { items: this._items } } ) );\n }\n\n private render (): void {\n const percentage = this.percentage;\n const completedCount = this._items.filter( i => i.checked ).length;\n const totalCount = this._items.length;\n\n // Initial render of structure if needed\n if ( !this.shadowRoot.querySelector( '.list' ) ) {\n this.shadowRoot.innerHTML = `\n <style>\n :host {\n display: block;\n font-family: var(--font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);\n background: var(--background, #fff);\n border-radius: var(--border-radius, 8px);\n padding: var(--padding, 16px);\n box-shadow: var(--box-shadow, 0 2px 4px rgba(0,0,0,0.1));\n max-width: var(--max-width, 100%);\n }\n \n .header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n }\n \n .title {\n font-size: 1.1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--text-color, #333);\n }\n \n .title-icon {\n width: 20px;\n height: 20px;\n fill: currentColor;\n }\n \n .progress-container {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n }\n \n .progress-text {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--text-color, #333);\n min-width: 40px;\n }\n \n .progress-bar-bg {\n flex: 1;\n height: 6px;\n background: #e0e0e0;\n border-radius: 3px;\n overflow: hidden;\n }\n \n .progress-bar-fill {\n height: 100%;\n background: var(--primary-color, #1976d2);\n width: 0%;\n transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n .list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n \n .list-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 4px 0;\n }\n \n .checkbox {\n width: 20px;\n height: 20px;\n border: 2px solid #757575;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n flex-shrink: 0;\n }\n \n .checkbox.checked {\n background: var(--primary-color, #1976d2);\n border-color: var(--primary-color, #1976d2);\n }\n \n .checkbox svg {\n width: 14px;\n height: 14px;\n fill: white;\n display: none;\n }\n \n .checkbox.checked svg {\n display: block;\n }\n \n .item-input {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n font-size: 0.95rem;\n outline: none;\n transition: border-color 0.2s;\n color: var(--text-color, #333);\n }\n \n .item-input:focus {\n border-color: var(--primary-color, #1976d2);\n }\n \n .item-input.add-item-input {\n color: #666;\n }\n \n .item-input.add-item-input::placeholder {\n color: #999;\n }\n \n .delete-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px;\n color: #9e9e9e;\n transition: color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n .delete-btn:hover {\n color: #f44336;\n }\n \n .delete-btn svg {\n width: 18px;\n height: 18px;\n fill: currentColor;\n }\n \n .add-btn {\n background: #f5f5f5;\n border: none;\n border-radius: 50%;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n color: #757575;\n transition: background 0.2s;\n }\n \n .add-btn:hover {\n background: #e0e0e0;\n }\n </style>\n \n <div class=\"header\">\n <div class=\"title\">\n <svg class=\"title-icon\" viewBox=\"0 0 24 24\">\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/>\n </svg>\n <span class=\"title-text\">${ this._title }</span>\n </div>\n <slot name=\"menu\"></slot>\n </div>\n \n <div class=\"progress-container\">\n <div class=\"progress-text\"></div>\n <div class=\"progress-bar-bg\">\n <div class=\"progress-bar-fill\"></div>\n </div>\n </div>\n \n <div class=\"list\"></div>\n `;\n }\n\n // Update Title\n const titleText = this.shadowRoot.querySelector( '.title-text' );\n if ( titleText ) titleText.textContent = this._title;\n\n // Update Progress\n const progressText = this.shadowRoot.querySelector( '.progress-text' );\n if ( progressText ) progressText.textContent = `${ completedCount } / ${ totalCount }`;\n\n const progressBar = this.shadowRoot.querySelector( '.progress-bar-fill' ) as HTMLElement;\n if ( progressBar ) progressBar.style.width = `${ percentage }%`;\n\n // Update List\n const list = this.shadowRoot.querySelector( '.list' );\n if ( list ) {\n list.innerHTML = `\n ${ this._items.map( ( item, index ) => `\n <div class=\"list-item\">\n <div class=\"checkbox ${ item.checked ? 'checked' : '' }\" data-index=\"${ index }\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/></svg>\n </div>\n <input \n type=\"text\" \n class=\"item-input\" \n value=\"${ item.label }\" \n data-index=\"${ index }\"\n >\n <button class=\"delete-btn\" data-index=\"${ index }\" title=\"Delete item\">\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\"/>\n </svg>\n </button>\n </div>\n `).join( '' ) }\n\n <div class=\"list-item\">\n <div class=\"checkbox\" style=\"border-color: transparent; cursor: default;\"></div>\n <input \n type=\"text\" \n class=\"item-input add-item-input\" \n placeholder=\"Add an item\"\n >\n <div class=\"add-btn\" title=\"Add item\">\n <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"currentColor\">\n <path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\"/>\n </svg>\n </div>\n </div>\n `;\n }\n\n this.bindEvents();\n }\n\n private bindEvents (): void {\n // Checkbox toggle\n this.shadowRoot.querySelectorAll( '.checkbox' ).forEach( checkbox => {\n checkbox.addEventListener( 'click', ( e ) => {\n const index = ( e.currentTarget as HTMLElement ).dataset.index;\n if ( index !== undefined ) {\n this.toggleItem( parseInt( index ) );\n }\n } );\n } );\n\n // Delete button\n this.shadowRoot.querySelectorAll( '.delete-btn' ).forEach( btn => {\n btn.addEventListener( 'click', ( e ) => {\n const index = ( e.currentTarget as HTMLElement ).dataset.index;\n if ( index !== undefined ) {\n this.removeItem( parseInt( index ) );\n }\n } );\n } );\n\n // Item input update\n this.shadowRoot.querySelectorAll( '.item-input:not(.add-item-input)' ).forEach( input => {\n input.addEventListener( 'input', ( e ) => {\n const target = e.target as HTMLInputElement;\n const index = target.dataset.index;\n if ( index !== undefined ) {\n this.updateItemLabel( parseInt( index ), target.value );\n }\n } );\n } );\n\n // Add item input\n const addInput = this.shadowRoot.querySelector( '.add-item-input' ) as HTMLInputElement;\n if ( addInput ) {\n addInput.addEventListener( 'keydown', ( e ) => {\n if ( e.key === 'Enter' ) {\n this.addItem( addInput.value );\n addInput.value = '';\n }\n } );\n \n addInput.addEventListener( 'blur', () => {\n if ( addInput.value.trim() ) {\n this.addItem( addInput.value );\n addInput.value = '';\n }\n } );\n }\n \n // Add button click\n const addBtn = this.shadowRoot.querySelector( '.add-btn' );\n if ( addBtn && addInput ) {\n addBtn.addEventListener( 'click', () => {\n if ( addInput.value.trim() ) {\n this.addItem( addInput.value );\n addInput.value = '';\n } else {\n addInput.focus();\n }\n } );\n }\n }\n}\n\nexport const defineCheckList = ( tagName: string = 'liwe3-checklist' ): void => {\n if ( typeof window !== 'undefined' && !window.customElements.get( tagName ) ) {\n customElements.define( tagName, CheckListElement );\n }\n};\n\ndefineCheckList();\n"],"names":["CheckListElement","name","oldValue","newValue","e","value","completed","item","json","data","label","addInput","index","percentage","completedCount","i","totalCount","titleText","progressText","progressBar","list","checkbox","btn","input","target","addBtn","defineCheckList","tagName"],"mappings":"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"}