@malto/sdk 0.1.1 → 0.1.3
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/index.cjs +498 -173
- package/dist/index.d.cts +25 -5
- package/dist/index.d.ts +25 -5
- package/dist/index.js +498 -173
- package/dist/malto.umd.js +252 -49
- package/package.json +1 -1
package/dist/malto.umd.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
var Malto=(function(exports){'use strict';var
|
|
1
|
+
var Malto=(function(exports){'use strict';var $="https://malto-api-production.up.railway.app",v=class{constructor(t){this.apiKey=t.apiKey,this.apiUrl=(t.apiUrl??$).replace(/\/$/,""),this.getSessionToken=t.getSessionToken;}async request(t,e={}){let a={"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`};if(e.headers){let s=e.headers;for(let[l,d]of Object.entries(s))a[l]=d;}if(e.auth){let s=this.getSessionToken();s&&(a["X-Malto-Session"]=s);}let o=await fetch(`${this.apiUrl}${t}`,{...e,headers:a}),r=await o.text(),n=r?O(r):null;if(!o.ok){let s=n&&(n.message||n.error)||`Request failed (${o.status})`;throw new k(Array.isArray(s)?s.join(", "):String(s),o.status)}return n}board(){return this.request("/v1/sdk/board")}listFeedbacks(){return this.request("/v1/sdk/feedbacks",{auth:true})}feedback(t){return this.request(`/v1/sdk/feedbacks/${t}`,{auth:true})}createFeedback(t){return this.request("/v1/sdk/feedbacks",{method:"POST",auth:true,body:JSON.stringify(t)})}vote(t){return this.request(`/v1/sdk/feedbacks/${t}/vote`,{method:"POST",auth:true})}comments(t){return this.request(`/v1/sdk/feedbacks/${t}/comments`,{auth:true})}addComment(t,e,a){return this.request(`/v1/sdk/feedbacks/${t}/comments`,{method:"POST",auth:true,body:JSON.stringify({body:e,parentId:a})})}roadmap(){return this.request("/v1/sdk/roadmap")}releases(){return this.request("/v1/sdk/releases")}startMagicLink(t){return this.request("/v1/sdk/auth/magic-link",{method:"POST",body:JSON.stringify(t)})}verifyMagicLink(t){return this.request("/v1/sdk/auth/verify",{method:"POST",body:JSON.stringify({token:t})})}identify(t){return this.request("/v1/sdk/auth/identify",{method:"POST",body:JSON.stringify(t)})}},k=class extends Error{constructor(e,a){super(e);this.status=a;this.name="MaltoApiError";}};function O(i){try{return JSON.parse(i)}catch{return null}}var w="malto:session:";function N(i){if(typeof window>"u")return null;try{let t=window.localStorage.getItem(w+i);if(!t)return null;let e=JSON.parse(t);return !e?.token||!e?.expiresAt?null:new Date(e.expiresAt).getTime()<Date.now()?(window.localStorage.removeItem(w+i),null):e}catch{return null}}function S(i,t){if(!(typeof window>"u"))try{window.localStorage.setItem(w+i,JSON.stringify(t));}catch{}}function y(i){if(!(typeof window>"u"))try{window.localStorage.removeItem(w+i);}catch{}}var B="malto-sdk-styles",P="malto-sdk-styles-custom";function H(i){if(typeof document>"u")return;let t=j(i);z(B,t),i.customCss?z(P,F(i.customCss)):document.getElementById(P)?.remove();}function F(i){return i.replace(/<\/style/gi,"<\\/style").replace(/<\/script/gi,"<\\/script").replace(/expression\s*\(/gi,"expr\\(").replace(/javascript\s*:/gi,"javascript\\:")}function z(i,t){let e=document.getElementById(i);if(e){e.textContent=t;return}let a=document.createElement("style");a.id=i,a.textContent=t,document.head.appendChild(a);}function j(i){let t=i.primary,e=U(t),a=i.radius==="sm"?"12px":i.radius==="lg"?"24px":"20px",o=i.appearance??"light",r=i.cssVars??{};return `
|
|
2
|
+
@import url('https://fonts.googleapis.com/css2?family=Google+Sans:ital,opsz,wght@0,17..18,400..700;1,17..18,400..700&display=swap');
|
|
3
|
+
|
|
2
4
|
:where(.malto-root, .malto-root *) {
|
|
3
5
|
box-sizing: border-box;
|
|
4
6
|
}
|
|
@@ -11,27 +13,27 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
11
13
|
--malto-primary-600: ${e.shade600};
|
|
12
14
|
--malto-primary-rgb: ${e.rgb};
|
|
13
15
|
--malto-surface: ${r.surface??"#ffffff"};
|
|
14
|
-
--malto-surface-muted: ${r.surfaceMuted??"#
|
|
15
|
-
--malto-surface-elevated: rgba(255,255,255,0.
|
|
16
|
-
--malto-border: ${r.border??"
|
|
17
|
-
--malto-border-strong:
|
|
18
|
-
--malto-text: ${r.text??"#
|
|
16
|
+
--malto-surface-muted: ${r.surfaceMuted??"#f2eeff"};
|
|
17
|
+
--malto-surface-elevated: rgba(255,255,255,0.92);
|
|
18
|
+
--malto-border: ${r.border??"#e2e8f0"};
|
|
19
|
+
--malto-border-strong: #cbd1de;
|
|
20
|
+
--malto-text: ${r.text??"#0a0a0a"};
|
|
19
21
|
--malto-text-muted: ${r.textMuted??"#5b5871"};
|
|
20
|
-
--malto-text-subtle: rgba(
|
|
22
|
+
--malto-text-subtle: rgba(10, 10, 10, 0.5);
|
|
21
23
|
--malto-radius: ${r.radius??a};
|
|
22
|
-
--malto-radius-sm:
|
|
24
|
+
--malto-radius-sm: 12px;
|
|
23
25
|
--malto-radius-pill: 999px;
|
|
24
|
-
--malto-shadow-sm: ${r.shadow??"0 4px 12px -
|
|
25
|
-
--malto-shadow-md: 0
|
|
26
|
-
--malto-shadow-lg: 0 30px 60px -20px rgba(
|
|
27
|
-
--malto-shadow-glow: 0
|
|
28
|
-
--malto-font: ${r.font??"
|
|
26
|
+
--malto-shadow-sm: ${r.shadow??"0 4px 12px -6px rgba(25, 24, 56, 0.12)"};
|
|
27
|
+
--malto-shadow-md: 0 10px 30px -10px rgba(25, 24, 56, 0.15);
|
|
28
|
+
--malto-shadow-lg: 0 30px 60px -20px rgba(25, 24, 56, 0.25);
|
|
29
|
+
--malto-shadow-glow: 0 8px 20px -6px rgba(var(--malto-primary-rgb), 0.45);
|
|
30
|
+
--malto-font: ${r.font??"'Google Sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif"};
|
|
29
31
|
--malto-ease-spring: cubic-bezier(0.34, 1.4, 0.5, 1);
|
|
30
32
|
--malto-ease-smooth: cubic-bezier(0.32, 0.72, 0, 1);
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
${o==="dark"?
|
|
34
|
-
${o==="auto"?`@media (prefers-color-scheme: dark) { ${
|
|
35
|
+
${o==="dark"?R():""}
|
|
36
|
+
${o==="auto"?`@media (prefers-color-scheme: dark) { ${R()} }`:""}
|
|
35
37
|
|
|
36
38
|
.malto-root, .malto-root *, .malto-root *::before, .malto-root *::after {
|
|
37
39
|
font-family: var(--malto-font);
|
|
@@ -86,12 +88,12 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
86
88
|
|
|
87
89
|
.malto-trigger {
|
|
88
90
|
display: inline-flex; align-items: center; gap: 8px;
|
|
89
|
-
padding:
|
|
91
|
+
padding: 10px 20px;
|
|
90
92
|
border-radius: var(--malto-radius-pill);
|
|
91
93
|
background: var(--malto-primary);
|
|
92
94
|
color: var(--malto-primary-contrast);
|
|
93
95
|
border: none; cursor: pointer;
|
|
94
|
-
font-size:
|
|
96
|
+
font-size: 14px; font-weight: 600; letter-spacing: -0.01em;
|
|
95
97
|
box-shadow: var(--malto-shadow-glow);
|
|
96
98
|
transition: transform .25s var(--malto-ease-spring), box-shadow .2s ease;
|
|
97
99
|
}
|
|
@@ -117,7 +119,8 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
117
119
|
.malto-modal {
|
|
118
120
|
background: var(--malto-surface);
|
|
119
121
|
width: 100%;
|
|
120
|
-
max-width:
|
|
122
|
+
max-width: 1152px;
|
|
123
|
+
height: 720px;
|
|
121
124
|
max-height: 92vh;
|
|
122
125
|
border-radius: var(--malto-radius) var(--malto-radius) 0 0;
|
|
123
126
|
box-shadow: var(--malto-shadow-lg);
|
|
@@ -145,23 +148,23 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
145
148
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
146
149
|
.malto-header {
|
|
147
150
|
display: flex; align-items: center; justify-content: space-between;
|
|
148
|
-
padding:
|
|
151
|
+
padding: 22px 24px 16px;
|
|
149
152
|
position: relative;
|
|
150
153
|
flex: none;
|
|
151
154
|
}
|
|
152
155
|
.malto-header h3 {
|
|
153
156
|
margin: 0;
|
|
154
|
-
font-size:
|
|
157
|
+
font-size: 17px; font-weight: 600;
|
|
155
158
|
color: var(--malto-text);
|
|
156
|
-
letter-spacing: -0.
|
|
159
|
+
letter-spacing: -0.02em;
|
|
157
160
|
}
|
|
158
161
|
.malto-header-meta {
|
|
159
162
|
display: flex; align-items: center; gap: 10px;
|
|
160
163
|
}
|
|
161
164
|
.malto-board-logo {
|
|
162
165
|
width: 28px; height: 28px;
|
|
163
|
-
border-radius:
|
|
164
|
-
background: var(--malto-
|
|
166
|
+
border-radius: 10px;
|
|
167
|
+
background: var(--malto-surface-muted);
|
|
165
168
|
display: flex; align-items: center; justify-content: center;
|
|
166
169
|
color: var(--malto-primary);
|
|
167
170
|
font-size: 12px; font-weight: 700;
|
|
@@ -179,7 +182,7 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
179
182
|
transition: background .15s ease, color .15s ease;
|
|
180
183
|
}
|
|
181
184
|
.malto-close:hover {
|
|
182
|
-
background: var(--malto-
|
|
185
|
+
background: var(--malto-surface-muted);
|
|
183
186
|
color: var(--malto-text);
|
|
184
187
|
}
|
|
185
188
|
|
|
@@ -187,8 +190,8 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
187
190
|
.malto-tabs {
|
|
188
191
|
display: flex;
|
|
189
192
|
padding: 4px;
|
|
190
|
-
margin: 0
|
|
191
|
-
background: var(--malto-
|
|
193
|
+
margin: 0 24px 16px;
|
|
194
|
+
background: var(--malto-surface-muted);
|
|
192
195
|
border-radius: var(--malto-radius-sm);
|
|
193
196
|
flex: none;
|
|
194
197
|
}
|
|
@@ -214,7 +217,7 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
214
217
|
.malto-body {
|
|
215
218
|
flex: 1;
|
|
216
219
|
overflow-y: auto;
|
|
217
|
-
padding: 4px
|
|
220
|
+
padding: 4px 24px 22px;
|
|
218
221
|
background: var(--malto-surface);
|
|
219
222
|
scroll-behavior: smooth;
|
|
220
223
|
}
|
|
@@ -229,7 +232,7 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
229
232
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Feedback row \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
230
233
|
.malto-item {
|
|
231
234
|
display: flex; gap: 12px;
|
|
232
|
-
padding:
|
|
235
|
+
padding: 14px;
|
|
233
236
|
border-radius: 12px;
|
|
234
237
|
background: var(--malto-surface);
|
|
235
238
|
border: 1px solid var(--malto-border);
|
|
@@ -240,15 +243,15 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
240
243
|
.malto-item:hover {
|
|
241
244
|
border-color: var(--malto-border-strong);
|
|
242
245
|
transform: translateY(-1px);
|
|
243
|
-
box-shadow:
|
|
246
|
+
box-shadow: 0 6px 16px -8px rgba(25, 24, 56, 0.12);
|
|
244
247
|
}
|
|
245
248
|
.malto-vote {
|
|
246
249
|
display: flex; flex-direction: column;
|
|
247
250
|
align-items: center; justify-content: center;
|
|
248
251
|
min-width: 44px; padding: 6px 4px;
|
|
249
|
-
border-radius:
|
|
252
|
+
border-radius: 12px;
|
|
250
253
|
border: 1px solid var(--malto-border);
|
|
251
|
-
background: var(--malto-surface
|
|
254
|
+
background: var(--malto-surface);
|
|
252
255
|
cursor: pointer;
|
|
253
256
|
font-size: 11px; color: var(--malto-text-muted);
|
|
254
257
|
transition: all .2s var(--malto-ease-spring);
|
|
@@ -335,10 +338,10 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
335
338
|
}
|
|
336
339
|
.malto-input, .malto-textarea {
|
|
337
340
|
width: 100%;
|
|
338
|
-
padding:
|
|
339
|
-
border: 1px solid var(--malto-border
|
|
341
|
+
padding: 12px 14px;
|
|
342
|
+
border: 1px solid var(--malto-border);
|
|
340
343
|
border-radius: 12px;
|
|
341
|
-
font-size:
|
|
344
|
+
font-size: 14px;
|
|
342
345
|
color: var(--malto-text);
|
|
343
346
|
background: var(--malto-surface);
|
|
344
347
|
outline: none;
|
|
@@ -350,7 +353,7 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
350
353
|
}
|
|
351
354
|
.malto-input:focus, .malto-textarea:focus {
|
|
352
355
|
border-color: var(--malto-primary);
|
|
353
|
-
box-shadow: 0 0 0 4px rgba(var(--malto-primary-rgb), 0.
|
|
356
|
+
box-shadow: 0 0 0 4px rgba(var(--malto-primary-rgb), 0.12);
|
|
354
357
|
}
|
|
355
358
|
.malto-textarea {
|
|
356
359
|
min-height: 110px;
|
|
@@ -358,13 +361,13 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
358
361
|
line-height: 1.5;
|
|
359
362
|
}
|
|
360
363
|
.malto-button {
|
|
361
|
-
padding:
|
|
364
|
+
padding: 12px 20px;
|
|
362
365
|
border-radius: 12px;
|
|
363
366
|
background: var(--malto-primary);
|
|
364
367
|
color: var(--malto-primary-contrast);
|
|
365
368
|
border: none; cursor: pointer;
|
|
366
|
-
font-size:
|
|
367
|
-
letter-spacing: -0.
|
|
369
|
+
font-size: 14px; font-weight: 600;
|
|
370
|
+
letter-spacing: -0.01em;
|
|
368
371
|
box-shadow: var(--malto-shadow-glow);
|
|
369
372
|
transition: transform .2s var(--malto-ease-spring), box-shadow .2s ease, opacity .2s ease;
|
|
370
373
|
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
@@ -373,13 +376,13 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
373
376
|
.malto-button:active { transform: scale(0.97); }
|
|
374
377
|
.malto-button[disabled] { opacity: .5; cursor: not-allowed; transform: none; }
|
|
375
378
|
.malto-secondary {
|
|
376
|
-
padding:
|
|
377
|
-
border-radius:
|
|
379
|
+
padding: 10px 16px;
|
|
380
|
+
border-radius: 12px;
|
|
378
381
|
background: transparent;
|
|
379
382
|
color: var(--malto-text);
|
|
380
|
-
border: 1px solid var(--malto-border
|
|
383
|
+
border: 1px solid var(--malto-border);
|
|
381
384
|
cursor: pointer;
|
|
382
|
-
font-size:
|
|
385
|
+
font-size: 13.5px; font-weight: 500;
|
|
383
386
|
transition: all .2s ease;
|
|
384
387
|
}
|
|
385
388
|
.malto-secondary:hover {
|
|
@@ -472,7 +475,7 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
472
475
|
|
|
473
476
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Releases / changelog \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
474
477
|
.malto-release {
|
|
475
|
-
padding:
|
|
478
|
+
padding: 16px;
|
|
476
479
|
border: 1px solid var(--malto-border);
|
|
477
480
|
border-radius: 12px;
|
|
478
481
|
margin-bottom: 8px;
|
|
@@ -542,10 +545,10 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
542
545
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Footer banner (sign-in CTA) \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
543
546
|
.malto-footer-banner {
|
|
544
547
|
flex: none;
|
|
545
|
-
padding:
|
|
548
|
+
padding: 14px 24px;
|
|
546
549
|
background: var(--malto-surface-muted);
|
|
547
550
|
border-top: 1px solid var(--malto-border);
|
|
548
|
-
font-size:
|
|
551
|
+
font-size: 12.5px;
|
|
549
552
|
color: var(--malto-text-muted);
|
|
550
553
|
display: flex; align-items: center; justify-content: space-between;
|
|
551
554
|
gap: 10px;
|
|
@@ -565,7 +568,207 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
565
568
|
}
|
|
566
569
|
.malto-back:hover {
|
|
567
570
|
color: var(--malto-text);
|
|
568
|
-
background: var(--malto-
|
|
571
|
+
background: var(--malto-surface-muted);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/* \u2500\u2500\u2500\u2500\u2500\u2500 Kanban (roadmap) \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
575
|
+
.malto-kanban {
|
|
576
|
+
display: grid;
|
|
577
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
578
|
+
gap: 16px;
|
|
579
|
+
align-items: start;
|
|
580
|
+
}
|
|
581
|
+
@media (max-width: 960px) {
|
|
582
|
+
.malto-kanban { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
583
|
+
}
|
|
584
|
+
@media (max-width: 560px) {
|
|
585
|
+
.malto-kanban { grid-template-columns: 1fr; }
|
|
586
|
+
}
|
|
587
|
+
.malto-kanban-col {
|
|
588
|
+
display: flex; flex-direction: column;
|
|
589
|
+
gap: 12px;
|
|
590
|
+
min-width: 0;
|
|
591
|
+
}
|
|
592
|
+
.malto-kanban-head {
|
|
593
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
594
|
+
padding: 0 4px;
|
|
595
|
+
}
|
|
596
|
+
.malto-kanban-title {
|
|
597
|
+
margin: 0;
|
|
598
|
+
font-size: 11px;
|
|
599
|
+
font-weight: 600;
|
|
600
|
+
text-transform: uppercase;
|
|
601
|
+
letter-spacing: 0.06em;
|
|
602
|
+
color: var(--malto-text-muted);
|
|
603
|
+
}
|
|
604
|
+
.malto-kanban-count {
|
|
605
|
+
font-size: 11px;
|
|
606
|
+
font-weight: 700;
|
|
607
|
+
color: var(--malto-text-subtle);
|
|
608
|
+
letter-spacing: 0.04em;
|
|
609
|
+
}
|
|
610
|
+
.malto-kanban-list {
|
|
611
|
+
display: flex; flex-direction: column;
|
|
612
|
+
gap: 12px;
|
|
613
|
+
}
|
|
614
|
+
.malto-kanban-empty {
|
|
615
|
+
padding: 14px 12px;
|
|
616
|
+
font-size: 12px;
|
|
617
|
+
color: var(--malto-text-subtle);
|
|
618
|
+
border: 1px dashed var(--malto-border);
|
|
619
|
+
border-radius: 12px;
|
|
620
|
+
text-align: center;
|
|
621
|
+
background: var(--malto-surface-muted);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/* Card \u2014 mirrors malto-web FeedbackCard */
|
|
625
|
+
.malto-card {
|
|
626
|
+
display: block;
|
|
627
|
+
text-decoration: none;
|
|
628
|
+
color: inherit;
|
|
629
|
+
position: relative;
|
|
630
|
+
padding: 16px;
|
|
631
|
+
background: var(--malto-surface);
|
|
632
|
+
border: 1px solid rgba(200, 196, 216, 0.18);
|
|
633
|
+
border-radius: 12px;
|
|
634
|
+
box-shadow: 0 0 40px rgba(var(--malto-primary-rgb), 0.06),
|
|
635
|
+
0 0 80px rgba(var(--malto-primary-rgb), 0.02);
|
|
636
|
+
transition: transform .2s var(--malto-ease-spring),
|
|
637
|
+
box-shadow .2s ease, border-color .2s ease;
|
|
638
|
+
cursor: pointer;
|
|
639
|
+
}
|
|
640
|
+
.malto-card:hover {
|
|
641
|
+
transform: translateY(-2px);
|
|
642
|
+
box-shadow: 0 0 50px rgba(var(--malto-primary-rgb), 0.14),
|
|
643
|
+
0 0 90px rgba(var(--malto-primary-rgb), 0.04);
|
|
644
|
+
border-color: rgba(var(--malto-primary-rgb), 0.2);
|
|
645
|
+
}
|
|
646
|
+
.malto-card-top {
|
|
647
|
+
display: flex; align-items: flex-start; justify-content: space-between;
|
|
648
|
+
gap: 8px;
|
|
649
|
+
}
|
|
650
|
+
.malto-card-cat {
|
|
651
|
+
display: inline-flex; align-items: center;
|
|
652
|
+
padding: 3px 9px;
|
|
653
|
+
border-radius: 999px;
|
|
654
|
+
background: rgba(var(--malto-primary-rgb), 0.1);
|
|
655
|
+
color: var(--malto-primary-600);
|
|
656
|
+
font-size: 10px;
|
|
657
|
+
font-weight: 600;
|
|
658
|
+
text-transform: uppercase;
|
|
659
|
+
letter-spacing: 0.05em;
|
|
660
|
+
line-height: 1.4;
|
|
661
|
+
}
|
|
662
|
+
.malto-card-votes {
|
|
663
|
+
display: inline-flex; flex-direction: column;
|
|
664
|
+
align-items: center;
|
|
665
|
+
padding: 4px 8px;
|
|
666
|
+
border: 1px solid var(--malto-border);
|
|
667
|
+
border-radius: 8px;
|
|
668
|
+
background: var(--malto-surface);
|
|
669
|
+
color: var(--malto-text);
|
|
670
|
+
font-size: 12px;
|
|
671
|
+
font-weight: 700;
|
|
672
|
+
line-height: 1;
|
|
673
|
+
transition: border-color .2s ease, background .2s ease;
|
|
674
|
+
}
|
|
675
|
+
.malto-card:hover .malto-card-votes {
|
|
676
|
+
border-color: rgba(var(--malto-primary-rgb), 0.3);
|
|
677
|
+
background: rgba(var(--malto-primary-rgb), 0.05);
|
|
678
|
+
}
|
|
679
|
+
.malto-card-votes svg {
|
|
680
|
+
color: var(--malto-text-muted);
|
|
681
|
+
margin-bottom: 2px;
|
|
682
|
+
}
|
|
683
|
+
.malto-card-title {
|
|
684
|
+
margin: 12px 0 0;
|
|
685
|
+
font-size: 14.5px;
|
|
686
|
+
font-weight: 600;
|
|
687
|
+
letter-spacing: -0.01em;
|
|
688
|
+
line-height: 1.35;
|
|
689
|
+
color: var(--malto-text);
|
|
690
|
+
display: -webkit-box;
|
|
691
|
+
-webkit-line-clamp: 2;
|
|
692
|
+
-webkit-box-orient: vertical;
|
|
693
|
+
overflow: hidden;
|
|
694
|
+
}
|
|
695
|
+
.malto-card-desc {
|
|
696
|
+
margin: 6px 0 0;
|
|
697
|
+
font-size: 12.5px;
|
|
698
|
+
line-height: 1.45;
|
|
699
|
+
color: var(--malto-text-muted);
|
|
700
|
+
display: -webkit-box;
|
|
701
|
+
-webkit-line-clamp: 2;
|
|
702
|
+
-webkit-box-orient: vertical;
|
|
703
|
+
overflow: hidden;
|
|
704
|
+
}
|
|
705
|
+
.malto-card-foot {
|
|
706
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
707
|
+
gap: 8px;
|
|
708
|
+
margin-top: 14px;
|
|
709
|
+
padding-top: 12px;
|
|
710
|
+
border-top: 1px solid rgba(var(--malto-primary-rgb), 0.08);
|
|
711
|
+
font-size: 11px;
|
|
712
|
+
color: var(--malto-text-subtle);
|
|
713
|
+
}
|
|
714
|
+
.malto-card-who {
|
|
715
|
+
display: flex; align-items: center; gap: 6px;
|
|
716
|
+
min-width: 0;
|
|
717
|
+
flex: 1;
|
|
718
|
+
}
|
|
719
|
+
.malto-card-avatar {
|
|
720
|
+
flex: none;
|
|
721
|
+
width: 20px; height: 20px;
|
|
722
|
+
border-radius: 999px;
|
|
723
|
+
display: flex; align-items: center; justify-content: center;
|
|
724
|
+
color: #ffffff;
|
|
725
|
+
font-size: 9px;
|
|
726
|
+
font-weight: 700;
|
|
727
|
+
overflow: hidden;
|
|
728
|
+
}
|
|
729
|
+
.malto-card-avatar img {
|
|
730
|
+
width: 100%; height: 100%;
|
|
731
|
+
object-fit: cover;
|
|
732
|
+
}
|
|
733
|
+
.malto-avatar-bg-0 { background: #5f4ff8; }
|
|
734
|
+
.malto-avatar-bg-1 { background: #ec4899; }
|
|
735
|
+
.malto-avatar-bg-2 { background: #0ea5e9; }
|
|
736
|
+
.malto-avatar-bg-3 { background: #10b981; }
|
|
737
|
+
.malto-avatar-bg-4 { background: #f59e0b; }
|
|
738
|
+
.malto-avatar-bg-5 { background: #7e2eaa; }
|
|
739
|
+
.malto-avatar-bg-6 { background: #ef4444; }
|
|
740
|
+
.malto-avatar-bg-7 { background: #06b6d4; }
|
|
741
|
+
.malto-card-author {
|
|
742
|
+
font-size: 11px;
|
|
743
|
+
font-weight: 500;
|
|
744
|
+
color: var(--malto-text-muted);
|
|
745
|
+
min-width: 0;
|
|
746
|
+
overflow: hidden;
|
|
747
|
+
text-overflow: ellipsis;
|
|
748
|
+
white-space: nowrap;
|
|
749
|
+
}
|
|
750
|
+
.malto-card-dot {
|
|
751
|
+
color: var(--malto-border-strong);
|
|
752
|
+
flex: none;
|
|
753
|
+
}
|
|
754
|
+
.malto-card-time {
|
|
755
|
+
color: var(--malto-text-muted);
|
|
756
|
+
flex: none;
|
|
757
|
+
}
|
|
758
|
+
.malto-card-comments {
|
|
759
|
+
display: inline-flex; align-items: center; gap: 4px;
|
|
760
|
+
color: var(--malto-text-muted);
|
|
761
|
+
font-weight: 500;
|
|
762
|
+
flex: none;
|
|
763
|
+
}
|
|
764
|
+
.malto-card-skeleton {
|
|
765
|
+
cursor: default;
|
|
766
|
+
box-shadow: none;
|
|
767
|
+
}
|
|
768
|
+
.malto-card-skeleton:hover {
|
|
769
|
+
transform: none;
|
|
770
|
+
box-shadow: none;
|
|
771
|
+
border-color: rgba(200, 196, 216, 0.18);
|
|
569
772
|
}
|
|
570
773
|
|
|
571
774
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Animations \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
@@ -593,7 +796,7 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
593
796
|
transition-duration: 0.01ms !important;
|
|
594
797
|
}
|
|
595
798
|
}
|
|
596
|
-
`}function
|
|
799
|
+
`}function R(){return `
|
|
597
800
|
.malto-root {
|
|
598
801
|
--malto-surface: #131127;
|
|
599
802
|
--malto-surface-muted: #1a1834;
|
|
@@ -603,5 +806,5 @@ var Malto=(function(exports){'use strict';var F="https://malto-api-production.up
|
|
|
603
806
|
--malto-text-muted: #a09cc7;
|
|
604
807
|
--malto-text-subtle: rgba(230, 227, 245, 0.5);
|
|
605
808
|
}
|
|
606
|
-
`}function D(i){let{r:t,g:e,b:a}=U(i);return {rgb:`${t}, ${e}, ${a}`,contrast:j(t,e,a),tint50:N(t,e,a,.06),tint100:N(t,e,a,.12),tint200:N(t,e,a,.18),shade600:V(t,e,a,-0.18)}}function U(i){let t=i.trim().replace(/^#/,"");return t.length===3&&(t=t.split("").map(e=>e+e).join("")),/^[0-9a-fA-F]{6}$/.test(t)?{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}:{r:69,g:47,b:223}}function j(i,t,e){return (.2126*i+.7152*t+.0722*e)/255>.65?"#0f0d23":"#ffffff"}function N(i,t,e,a,o){return `rgba(${i}, ${t}, ${e}, ${a})`}function V(i,t,e,a){let o=n=>Math.max(0,Math.min(255,Math.round(n+255*a))),r=n=>o(n).toString(16).padStart(2,"0");return `#${r(i)}${r(t)}${r(e)}`}var q={"bottom-right":{right:"24px",bottom:"24px"},"bottom-left":{left:"24px",bottom:"24px"},"top-right":{right:"24px",top:"24px"},"top-left":{left:"24px",top:"24px"}},v=class{constructor(t){this.resolvedMode="bubble";this.root=null;this.container=null;this.trigger=null;this.board=null;if(!t.apiKey)throw new Error("Malto: apiKey is required");this.apiKeyPrefix=t.apiKey.slice(0,16),this.config={apiKey:t.apiKey,apiUrl:t.apiUrl??"https://malto-api-production.up.railway.app",mode:t.mode??"auto",position:t.position??"bottom-right",triggerLabel:t.triggerLabel??"Feedback",primaryColor:t.primaryColor,cssVars:t.cssVars,customCss:t.customCss,radius:t.radius??"md",appearance:t.appearance??"auto",zIndex:t.zIndex??2147483600,views:t.views,identify:t.identify,target:t.target,onReady:t.onReady,onError:t.onError};let e=E(this.apiKeyPrefix);this.state={open:false,view:"list",loading:false,error:null,feedbacks:[],roadmap:{},releases:[],selectedFeedback:null,comments:[],authEmail:"",authStatus:"idle",email:e?.email??null,name:e?.name??null},this.client=new h({apiKey:this.config.apiKey,apiUrl:this.config.apiUrl,getSessionToken:()=>E(this.apiKeyPrefix)?.token??null});}async mount(){try{let t=await this.client.board();this.board=t;let e=this.config.primaryColor||t.widget.primaryColor||t.board.boardThemeColor||"#452fdf";R({primary:e,cssVars:this.config.cssVars,customCss:this.config.customCss,radius:this.config.radius,appearance:this.config.appearance}),this.resolvedMode=this.config.mode==="auto"?t.widget.defaultMode:this.config.mode,this.config.identify&&await this.runIdentify(this.config.identify),this.renderHost(this.resolvedMode),this.config.onReady?.();}catch(t){this.config.onError?.(t);}}unmount(){this.root?.parentElement?.removeChild(this.root),this.trigger?.parentElement?.removeChild(this.trigger),this.root=null,this.trigger=null,this.container=null;}open(){this.state.open=true,this.render();}close(){this.state.open=false,this.render();}setIdentify(t){if(!t){g(this.apiKeyPrefix),this.state.email=null,this.state.name=null,this.render();return}this.runIdentify(t);}async runIdentify(t){try{let e=await this.client.identify(t);S(this.apiKeyPrefix,{token:e.sessionToken,expiresAt:e.expiresAt,email:e.user.email,name:e.user.name}),this.state.email=e.user.email,this.state.name=e.user.name,this.render();}catch(e){this.config.onError?.(e);}}renderHost(t){let e=document.createElement("div");if(e.className="malto-root",e.style.setProperty("--malto-z",String(this.config.zIndex)),document.body.appendChild(e),this.root=e,t==="inline"){let a=this.resolveTarget();if(!a){this.config.onError?.(new Error("Malto: inline target not found"));return}let o=document.createElement("div");o.className="malto-root malto-inline",o.style.setProperty("--malto-z",String(this.config.zIndex)),a.appendChild(o),this.container=o,this.state.open=true,this.render();return}if(t==="bubble"){let a=this.buildBubble(),o=q[this.config.position];Object.assign(a.style,o);let r=document.createElement("div");r.className="malto-root",r.style.setProperty("--malto-z",String(this.config.zIndex)),r.appendChild(a),document.body.appendChild(r),this.trigger=r;}else if(t==="trigger"){let a=this.resolveTarget();if(!a){this.config.onError?.(new Error("Malto: trigger target not found"));return}let o=document.createElement("span");o.className="malto-root",o.style.setProperty("--malto-z",String(this.config.zIndex));let r=document.createElement("button");r.className="malto-trigger",r.innerHTML=`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg><span>${L(this.config.triggerLabel)}</span>`,r.addEventListener("click",()=>this.open()),o.appendChild(r),a.appendChild(o),this.trigger=o;}else t==="modal"&&(this.state.open=true);this.render();}buildBubble(){let t=document.createElement("button");return t.className="malto-bubble",t.setAttribute("aria-label",this.config.triggerLabel),t.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',t.addEventListener("click",()=>{this.state.open?this.close():this.open();}),t}resolveTarget(){return this.config.target?typeof this.config.target=="string"?document.querySelector(this.config.target):this.config.target:null}render(){if(!this.root)return;if(this.resolvedMode==="inline"){if(!this.container)return;this.container.innerHTML="",this.container.appendChild(this.buildPanelBody());return}if(this.root.innerHTML="",!this.state.open)return;let t=document.createElement("div");t.className="malto-overlay",t.addEventListener("click",a=>{a.target===t&&this.close();});let e=document.createElement("div");e.className="malto-modal",e.appendChild(this.buildPanelBody()),t.appendChild(e),this.root.appendChild(t);}buildPanelBody(){let t=document.createElement("div");t.style.display="flex",t.style.flexDirection="column",t.style.height="100%",t.style.minHeight="0",t.appendChild(this.buildHeader()),t.appendChild(this.buildTabs());let e=document.createElement("div");if(e.className="malto-body",e.appendChild(this.buildView()),t.appendChild(e),this.state.view!=="auth"&&!this.state.email){let a=document.createElement("div");a.className="malto-footer-banner";let o=document.createElement("span");o.innerHTML="Sign in to vote, comment, or submit ideas.";let r=document.createElement("button");r.className="malto-link",r.textContent="Sign in",r.addEventListener("click",()=>this.go("auth")),a.appendChild(o),a.appendChild(r),t.appendChild(a);}return t}buildHeader(){let t=document.createElement("div");t.className="malto-header";let e=document.createElement("div");e.className="malto-header-meta";let a=document.createElement("div");a.className="malto-board-logo";let o=$(this.board?.board.companyLogoUrl);if(o){let n=document.createElement("img");n.src=o,n.alt="",n.referrerPolicy="no-referrer",n.crossOrigin="anonymous",a.appendChild(n);}else a.textContent=(this.board?.board.companyName??this.board?.board.boardName??"M").charAt(0).toUpperCase();let r=document.createElement("h3");if(r.textContent=this.board?.board.boardName??this.board?.board.companyName??"Feedback",e.appendChild(a),e.appendChild(r),t.appendChild(e),this.resolvedMode!=="inline"){let n=document.createElement("button");n.className="malto-close",n.setAttribute("aria-label","Close"),n.innerHTML='<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',n.addEventListener("click",()=>this.close()),t.appendChild(n);}return t}buildTabs(){let t=document.createElement("div");t.className="malto-tabs";let e=this.allowedViews();return e.includes("list")&&t.appendChild(this.tabBtn("Feed","list")),e.includes("submit")&&t.appendChild(this.tabBtn("New","submit")),e.includes("roadmap")&&t.appendChild(this.tabBtn("Roadmap","roadmap")),e.includes("changelog")&&t.appendChild(this.tabBtn("Updates","changelog")),t}tabBtn(t,e){let a=document.createElement("button");return a.className="malto-tab",a.setAttribute("aria-selected",this.state.view===e?"true":"false"),a.textContent=t,a.addEventListener("click",()=>this.go(e)),a}go(t){this.state.view=t,this.state.error=null,this.render(),t==="list"&&this.loadFeedbacks(),t==="roadmap"&&this.loadRoadmap(),t==="changelog"&&this.loadReleases(),t==="detail"&&this.state.selectedFeedback&&this.loadComments(this.state.selectedFeedback.id);}allowedViews(){let t=this.board?.widget.enabledFeatures??["list","submit","vote","comment","roadmap","changelog"];return (this.config.views??["list","submit","roadmap","changelog"]).filter(a=>t.includes(a))}buildView(){let t=document.createElement("div");if(this.state.error){let e=document.createElement("div");e.className="malto-error",e.textContent=this.state.error,t.appendChild(e);}switch(this.state.view){case "list":t.appendChild(this.viewList()),this.state.feedbacks.length===0&&!this.state.loading&&this.loadFeedbacks();break;case "submit":t.appendChild(this.viewSubmit());break;case "auth":t.appendChild(this.viewAuth());break;case "roadmap":t.appendChild(this.viewRoadmap()),Object.keys(this.state.roadmap).length===0&&!this.state.loading&&this.loadRoadmap();break;case "changelog":t.appendChild(this.viewChangelog()),this.state.releases.length===0&&!this.state.loading&&this.loadReleases();break;case "detail":t.appendChild(this.viewDetail());break}return t}viewList(){let t=document.createElement("div");if(this.state.loading)return t.appendChild(this.skeletonList(4)),t;if(this.state.feedbacks.length===0)return t.appendChild(this.emptyState("\u{1F4A1}","No requests yet","Be the first to share an idea or report something.")),t;let e=document.createElement("div");e.className="malto-list";for(let a of this.state.feedbacks)e.appendChild(this.feedbackRow(a));return t.appendChild(e),t}feedbackRow(t){let e=document.createElement("div");e.className="malto-item";let a=document.createElement("button");a.className="malto-vote",a.setAttribute("aria-pressed",t.hasVoted?"true":"false");let o=document.createElement("span");o.className="malto-vote-arrow",o.textContent="\u25B2";let r=document.createElement("span");r.className="malto-vote-count",r.textContent=_(t.votes??0),a.appendChild(o),a.appendChild(r),a.addEventListener("click",m=>{m.stopPropagation(),this.handleVote(t);});let n=document.createElement("div");n.className="malto-item-content";let s=document.createElement("h4");if(s.textContent=t.title,n.appendChild(s),t.description){let m=document.createElement("p");m.textContent=t.description,n.appendChild(m);}let d=document.createElement("div");if(d.className="malto-item-meta",t.status&&t.status!=="BACKLOG"){let m=K(t.status);d.appendChild(m);}let l=document.createElement("span");return l.textContent=z(t.createdAt),d.appendChild(l),n.appendChild(d),e.appendChild(a),e.appendChild(n),e.addEventListener("click",()=>{this.state.selectedFeedback=t,this.go("detail");}),e}viewSubmit(){let t=document.createElement("form");t.className="malto-form";let e=document.createElement("input");e.className="malto-input",e.required=true,e.maxLength=200,e.placeholder="What would you like?";let a=document.createElement("textarea");a.className="malto-textarea",a.maxLength=5e3,a.placeholder="Add some context (optional)";let o=document.createElement("button");return o.className="malto-button",o.textContent="Submit feedback",o.type="submit",t.appendChild(e),t.appendChild(a),t.appendChild(o),t.addEventListener("submit",async r=>{if(r.preventDefault(),!this.state.email){this.go("auth");return}o.setAttribute("disabled","true");try{await this.client.createFeedback({title:e.value.trim(),description:a.value.trim()||void 0}),e.value="",a.value="",await this.loadFeedbacks(),this.go("list");}catch(n){this.state.error=n.message,o.removeAttribute("disabled"),this.render();}}),t}viewAuth(){let t=document.createElement("div");if(this.state.email){let n=document.createElement("p");n.style.fontSize="13px",n.style.color="var(--malto-text)",n.style.marginBottom="10px",n.innerHTML=`Signed in as <strong>${L(this.state.email)}</strong>`;let s=document.createElement("button");return s.className="malto-secondary",s.textContent="Sign out",s.addEventListener("click",()=>{g(this.apiKeyPrefix),this.state.email=null,this.state.name=null,this.go("list");}),t.appendChild(n),t.appendChild(s),t}if(this.state.authStatus==="sent"){let n=document.createElement("p");n.style.fontSize="13px",n.style.color="var(--malto-text)",n.style.marginBottom="12px",n.style.lineHeight="1.5",n.innerHTML=`We sent a sign-in link to <strong>${L(this.state.authEmail)}</strong>. Open the email and paste the token below.`;let s=document.createElement("input");s.className="malto-input",s.placeholder="Paste token from email";let d=document.createElement("button");d.className="malto-button",d.style.marginTop="8px",d.textContent="Verify",d.addEventListener("click",async()=>{d.setAttribute("disabled","true");try{let m=await this.client.verifyMagicLink(s.value.trim());S(this.apiKeyPrefix,{token:m.sessionToken,expiresAt:m.expiresAt,email:m.user.email,name:m.user.name}),this.state.email=m.user.email,this.state.name=m.user.name,this.state.authStatus="idle",this.go("list");}catch(m){this.state.error=m.message,d.removeAttribute("disabled"),this.render();}});let l=document.createElement("button");return l.className="malto-link",l.style.marginTop="12px",l.style.display="block",l.textContent="Use a different email",l.addEventListener("click",()=>{this.state.authStatus="idle",this.render();}),t.appendChild(n),t.appendChild(s),t.appendChild(d),t.appendChild(l),t}let e=document.createElement("form");e.className="malto-form";let a=document.createElement("p");a.style.fontSize="13px",a.style.color="var(--malto-text-muted)",a.style.marginBottom="4px",a.style.lineHeight="1.5",a.textContent="Enter your email to receive a one-click sign-in link.";let o=document.createElement("input");o.className="malto-input",o.type="email",o.required=true,o.placeholder="you@company.com",o.value=this.state.authEmail;let r=document.createElement("button");return r.className="malto-button",r.type="submit",r.textContent="Send sign-in link",e.appendChild(a),e.appendChild(o),e.appendChild(r),e.addEventListener("submit",async n=>{n.preventDefault(),r.setAttribute("disabled","true");try{await this.client.startMagicLink({email:o.value.trim()}),this.state.authEmail=o.value.trim(),this.state.authStatus="sent",this.render();}catch(s){this.state.error=s.message,r.removeAttribute("disabled"),this.render();}}),e}viewRoadmap(){let t=document.createElement("div");if(this.state.loading)return t.appendChild(this.skeletonList(3)),t;let e={PLANNED:"Planned",IN_PROGRESS:"In Progress",COMPLETED:"Done"},a=false;for(let o of ["PLANNED","IN_PROGRESS","COMPLETED"]){let r=this.state.roadmap[o]??[],n=document.createElement("div");n.className="malto-roadmap-col";let s=document.createElement("h5");s.textContent=e[o]??o;let d=document.createElement("span");if(d.className="malto-roadmap-count",d.textContent=String(r.length),s.appendChild(d),n.appendChild(s),r.length===0){let l=document.createElement("div");l.className="malto-empty-desc",l.style.padding="8px 0 12px",l.textContent="Nothing here yet.",n.appendChild(l);}else {a=true;for(let l of r)n.appendChild(this.feedbackRow(l));}t.appendChild(n);}return !a&&Object.keys(this.state.roadmap).length===0&&(t.innerHTML="",t.appendChild(this.emptyState("\u{1F5FA}\uFE0F","Empty roadmap","Once admins move items into Planned, In Progress or Done, you'll see them here."))),t}viewChangelog(){let t=document.createElement("div");if(this.state.loading)return t.appendChild(this.skeletonList(2)),t;if(this.state.releases.length===0)return t.appendChild(this.emptyState("\u2728","No updates yet","Check back soon.")),t;for(let e of this.state.releases){let a=document.createElement("div");if(a.className="malto-release",e.publishedAt){let n=document.createElement("span");n.className="malto-release-date",n.textContent=Y(e.publishedAt),a.appendChild(n);}let o=document.createElement("h4");o.textContent=e.title;let r=document.createElement("p");r.textContent=e.body,a.appendChild(o),a.appendChild(r),t.appendChild(a);}return t}viewDetail(){let t=document.createElement("div"),e=this.state.selectedFeedback;if(!e)return t.appendChild(this.emptyState("\u{1F4ED}","Nothing selected","Pick a request from Feed.")),t;let a=document.createElement("button");if(a.className="malto-back",a.innerHTML='<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg> Back',a.addEventListener("click",()=>this.go("list")),t.appendChild(a),t.appendChild(this.feedbackRow(e)),this.allowedViews().includes("comment")){let r=document.createElement("h5");if(r.textContent="Comments",r.style.cssText="margin: 16px 0 8px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--malto-text-muted); font-weight: 600;",t.appendChild(r),this.state.loading)t.appendChild(this.skeletonList(2));else if(this.state.comments.length===0){let l=document.createElement("div");l.className="malto-empty-desc",l.style.padding="8px 0 12px",l.textContent="No comments yet \u2014 start the conversation.",t.appendChild(l);}else for(let l of this.state.comments){let m=document.createElement("div");m.className="malto-comment";let f=document.createElement("div");f.className="malto-avatar";let M=$(l.author?.avatarUrl);if(M){let u=document.createElement("img");u.src=M,u.alt="",u.referrerPolicy="no-referrer",u.crossOrigin="anonymous",f.appendChild(u);}else f.textContent=(l.author?.name??"?").charAt(0).toUpperCase();let p=document.createElement("div");p.style.flex="1",p.style.minWidth="0";let y=document.createElement("div"),k=document.createElement("span");k.className="malto-comment-author",k.textContent=l.author?.name??"User";let w=document.createElement("span");w.className="malto-comment-time",w.textContent=z(l.createdAt),y.appendChild(k),y.appendChild(w);let C=document.createElement("div");C.className="malto-comment-body",C.textContent=l.body,p.appendChild(y),p.appendChild(C),m.appendChild(f),m.appendChild(p),t.appendChild(m);}let n=document.createElement("form");n.className="malto-form",n.style.marginTop="12px";let s=document.createElement("textarea");s.className="malto-textarea",s.placeholder="Write a comment",s.required=true;let d=document.createElement("button");d.className="malto-button",d.type="submit",d.textContent="Post comment",n.appendChild(s),n.appendChild(d),n.addEventListener("submit",async l=>{if(l.preventDefault(),!this.state.email){this.go("auth");return}d.setAttribute("disabled","true");try{await this.client.addComment(e.id,s.value.trim()),s.value="",await this.loadComments(e.id);}catch(m){this.state.error=m.message;}finally{d.removeAttribute("disabled"),this.render();}}),t.appendChild(n);}return t}skeletonList(t){let e=document.createElement("div");for(let a=0;a<t;a++){let o=document.createElement("div");o.className="malto-skeleton-row";let r=document.createElement("div");r.className="malto-skeleton",r.style.width="44px",r.style.height="48px",r.style.flex="none";let n=document.createElement("div");n.style.flex="1";let s=document.createElement("div");s.className="malto-skeleton",s.style.height="12px",s.style.width="70%",s.style.marginBottom="6px";let d=document.createElement("div");d.className="malto-skeleton",d.style.height="10px",d.style.width="90%",n.appendChild(s),n.appendChild(d),o.appendChild(r),o.appendChild(n),e.appendChild(o);}return e}emptyState(t,e,a){let o=document.createElement("div");o.className="malto-empty";let r=document.createElement("div");r.className="malto-empty-icon",r.style.fontSize="20px",r.textContent=t;let n=document.createElement("div");n.className="malto-empty-title",n.textContent=e;let s=document.createElement("div");return s.className="malto-empty-desc",s.textContent=a,o.appendChild(r),o.appendChild(n),o.appendChild(s),o}async loadFeedbacks(){this.state.loading=true,this.render();try{this.state.feedbacks=await this.client.listFeedbacks();}catch(t){this.state.error=t.message;}finally{this.state.loading=false,this.render();}}async loadRoadmap(){this.state.loading=true,this.render();try{this.state.roadmap=await this.client.roadmap();}catch(t){this.state.error=t.message;}finally{this.state.loading=false,this.render();}}async loadReleases(){this.state.loading=true,this.render();try{this.state.releases=await this.client.releases();}catch(t){this.state.error=t.message;}finally{this.state.loading=false,this.render();}}async loadComments(t){this.state.loading=true,this.render();try{this.state.comments=await this.client.comments(t);}catch(e){this.state.error=e.message;}finally{this.state.loading=false,this.render();}}async handleVote(t){if(!this.state.email){this.go("auth");return}try{let e=await this.client.vote(t.id);t.hasVoted=e.voted,t.votes=e.votes,this.render();}catch(e){this.state.error=e.message,this.render();}}};function K(i){let t=document.createElement("span");t.className=`malto-status malto-status-${i}`;let e=document.createElement("span");e.className="malto-status-dot",t.appendChild(e);let a=document.createElement("span"),o={PLANNED:"Planned",IN_PROGRESS:"In progress",COMPLETED:"Done",DECLINED:"Declined",UNDER_REVIEW:"Under review",BACKLOG:"Backlog"};return a.textContent=o[i]??i,t.appendChild(a),t}function _(i){return i<1e3?String(i):i<1e4?(i/1e3).toFixed(1).replace(/\.0$/,"")+"k":Math.floor(i/1e3)+"k"}function z(i){let t=Date.now()-new Date(i).getTime(),e=Math.floor(t/1e3);if(e<60)return "just now";let a=Math.floor(e/60);if(a<60)return `${a}m`;let o=Math.floor(a/60);if(o<24)return `${o}h`;let r=Math.floor(o/24);if(r<30)return `${r}d`;let n=Math.floor(r/30);return n<12?`${n}mo`:`${Math.floor(n/12)}y`}function Y(i){try{return new Date(i).toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"})}catch{return i}}function L(i){return i.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function $(i){if(!i||typeof i!="string")return null;let t;try{t=new URL(i,typeof location<"u"?location.href:"https://x");}catch{return null}return t.protocol!=="https:"&&t.protocol!=="http:"?null:t.toString()}var c=null;function ot(i){c&&c.unmount();let t=new v(i);return c=t,t.mount(),t}function nt(){c?.open();}function it(){c?.close();}function st(i){c?.setIdentify(i);}function lt(i){g(i.slice(0,16)),c?.setIdentify(null);}function dt(){c?.unmount(),c=null;}
|
|
607
|
-
exports.MaltoApiError=
|
|
809
|
+
`}function U(i){let{r:t,g:e,b:a}=D(i);return {rgb:`${t}, ${e}, ${a}`,contrast:V(t,e,a),tint50:L(t,e,a,.06),tint100:L(t,e,a,.12),tint200:L(t,e,a,.18),shade600:K(t,e,a,-0.18)}}function D(i){let t=i.trim().replace(/^#/,"");return t.length===3&&(t=t.split("").map(e=>e+e).join("")),/^[0-9a-fA-F]{6}$/.test(t)?{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}:{r:69,g:47,b:223}}function V(i,t,e){return (.2126*i+.7152*t+.0722*e)/255>.65?"#0f0d23":"#ffffff"}function L(i,t,e,a,o){return `rgba(${i}, ${t}, ${e}, ${a})`}function K(i,t,e,a){let o=n=>Math.max(0,Math.min(255,Math.round(n+255*a))),r=n=>o(n).toString(16).padStart(2,"0");return `#${r(i)}${r(t)}${r(e)}`}var q={"bottom-right":{right:"24px",bottom:"24px"},"bottom-left":{left:"24px",bottom:"24px"},"top-right":{right:"24px",top:"24px"},"top-left":{left:"24px",top:"24px"}},E=class{constructor(t){this.resolvedMode="bubble";this.root=null;this.container=null;this.trigger=null;this.board=null;this.shellEl=null;this.bodyEl=null;this.tabRefs={};this.bannerEl=null;this.initialLoaded=false;if(!t.apiKey)throw new Error("Malto: apiKey is required");this.apiKeyPrefix=t.apiKey.slice(0,16),this.config={apiKey:t.apiKey,apiUrl:t.apiUrl??"https://malto-api-production.up.railway.app",mode:t.mode??"auto",position:t.position??"bottom-right",triggerLabel:t.triggerLabel??"Feedback",primaryColor:t.primaryColor,cssVars:t.cssVars,customCss:t.customCss,radius:t.radius??"md",appearance:t.appearance??"light",zIndex:t.zIndex??2147483600,views:t.views,identify:t.identify,target:t.target,onReady:t.onReady,onError:t.onError};let e=N(this.apiKeyPrefix);this.state={open:false,view:"roadmap",loading:true,error:null,roadmap:{},releases:[],selectedFeedback:null,comments:[],authEmail:"",authStatus:"idle",email:e?.email??null,name:e?.name??null},this.client=new v({apiKey:this.config.apiKey,apiUrl:this.config.apiUrl,getSessionToken:()=>N(this.apiKeyPrefix)?.token??null});}async mount(){try{let t=await this.client.board();this.board=t;let e=this.config.primaryColor||t.widget.primaryColor||t.board.boardThemeColor||"#452fdf";H({primary:e,cssVars:this.config.cssVars,customCss:this.config.customCss,radius:this.config.radius,appearance:this.config.appearance}),this.resolvedMode=this.config.mode==="auto"?t.widget.defaultMode:this.config.mode,this.config.identify&&await this.runIdentify(this.config.identify),this.renderHost(this.resolvedMode),this.ensureInitialLoad(),this.config.onReady?.();}catch(t){this.config.onError?.(t);}}ensureInitialLoad(){this.initialLoaded||(this.initialLoaded=true,this.state.view==="roadmap"?this.loadRoadmap():this.state.view==="changelog"&&this.loadReleases());}unmount(){this.root?.parentElement?.removeChild(this.root),this.trigger?.parentElement?.removeChild(this.trigger),this.root=null,this.trigger=null,this.container=null,this.shellEl=null,this.bodyEl=null,this.tabRefs={},this.bannerEl=null;}open(){this.state.open=true,this.render();}close(){this.state.open=false,this.render();}setIdentify(t){if(!t){y(this.apiKeyPrefix),this.state.email=null,this.state.name=null,this.render();return}this.runIdentify(t);}async runIdentify(t){try{let e=await this.client.identify(t);S(this.apiKeyPrefix,{token:e.sessionToken,expiresAt:e.expiresAt,email:e.user.email,name:e.user.name}),this.state.email=e.user.email,this.state.name=e.user.name,this.render();}catch(e){this.config.onError?.(e);}}renderHost(t){let e=document.createElement("div");if(e.className="malto-root",e.style.setProperty("--malto-z",String(this.config.zIndex)),document.body.appendChild(e),this.root=e,t==="inline"){let a=this.resolveTarget();if(!a){this.config.onError?.(new Error("Malto: inline target not found"));return}let o=document.createElement("div");o.className="malto-root malto-inline",o.style.setProperty("--malto-z",String(this.config.zIndex)),a.appendChild(o),this.container=o,this.state.open=true,this.render();return}if(t==="bubble"){let a=this.buildBubble(),o=q[this.config.position];Object.assign(a.style,o);let r=document.createElement("div");r.className="malto-root",r.style.setProperty("--malto-z",String(this.config.zIndex)),r.appendChild(a),document.body.appendChild(r),this.trigger=r;}else if(t==="trigger"){let a=this.resolveTarget();if(!a){this.config.onError?.(new Error("Malto: trigger target not found"));return}let o=document.createElement("span");o.className="malto-root",o.style.setProperty("--malto-z",String(this.config.zIndex));let r=document.createElement("button");r.className="malto-trigger",r.innerHTML=`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg><span>${T(this.config.triggerLabel)}</span>`,r.addEventListener("click",()=>this.open()),o.appendChild(r),a.appendChild(o),this.trigger=o;}else t==="modal"&&(this.state.open=true);this.render();}buildBubble(){let t=document.createElement("button");return t.className="malto-bubble",t.setAttribute("aria-label",this.config.triggerLabel),t.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',t.addEventListener("click",()=>{this.state.open?this.close():this.open();}),t}resolveTarget(){return this.config.target?typeof this.config.target=="string"?document.querySelector(this.config.target):this.config.target:null}render(){if(this.root){if(this.resolvedMode==="inline"){if(!this.container)return;(!this.shellEl||this.shellEl.parentElement!==this.container)&&(this.container.innerHTML="",this.shellEl=this.buildShell(),this.container.appendChild(this.shellEl)),this.refreshShell();return}if(!this.state.open){this.root.innerHTML="",this.shellEl=null,this.bodyEl=null,this.tabRefs={},this.bannerEl=null;return}if(!this.shellEl||this.shellEl.parentElement===null){this.root.innerHTML="";let t=document.createElement("div");t.className="malto-overlay",t.addEventListener("click",a=>{a.target===t&&this.close();});let e=document.createElement("div");e.className="malto-modal",this.shellEl=this.buildShell(),e.appendChild(this.shellEl),t.appendChild(e),this.root.appendChild(t);}this.refreshShell();}}buildShell(){let t=document.createElement("div");t.style.display="flex",t.style.flexDirection="column",t.style.height="100%",t.style.minHeight="0",t.appendChild(this.buildHeader()),t.appendChild(this.buildTabs());let e=document.createElement("div");e.className="malto-body",this.bodyEl=e,t.appendChild(e);let a=document.createElement("div");a.className="malto-footer-banner",a.style.display="none";let o=document.createElement("span");o.innerHTML="Sign in to vote, comment, or submit ideas.";let r=document.createElement("button");return r.className="malto-link",r.textContent="Sign in",r.addEventListener("click",()=>this.go("auth")),a.appendChild(o),a.appendChild(r),this.bannerEl=a,t.appendChild(a),t}refreshShell(){for(let[t,e]of Object.entries(this.tabRefs))e?.setAttribute("aria-selected",t===this.state.view?"true":"false");if(this.bodyEl&&(this.bodyEl.innerHTML="",this.bodyEl.appendChild(this.buildView())),this.bannerEl){let t=this.state.view!=="auth"&&!this.state.email;this.bannerEl.style.display=t?"":"none";}}buildHeader(){let t=document.createElement("div");t.className="malto-header";let e=document.createElement("div");e.className="malto-header-meta";let a=document.createElement("div");a.className="malto-board-logo";let o=I(this.board?.board.companyLogoUrl);if(o){let n=document.createElement("img");n.src=o,n.alt="",n.referrerPolicy="no-referrer",n.crossOrigin="anonymous",a.appendChild(n);}else a.textContent=(this.board?.board.companyName??this.board?.board.boardName??"M").charAt(0).toUpperCase();let r=document.createElement("h3");if(r.textContent=this.board?.board.boardName??this.board?.board.companyName??"Feedback",e.appendChild(a),e.appendChild(r),t.appendChild(e),this.resolvedMode!=="inline"){let n=document.createElement("button");n.className="malto-close",n.setAttribute("aria-label","Close"),n.innerHTML='<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',n.addEventListener("click",()=>this.close()),t.appendChild(n);}return t}buildTabs(){let t=document.createElement("div");t.className="malto-tabs",this.tabRefs={};let e=this.allowedViews();return e.includes("roadmap")&&t.appendChild(this.tabBtn("Roadmap","roadmap")),e.includes("changelog")&&t.appendChild(this.tabBtn("Updates","changelog")),e.includes("submit")&&t.appendChild(this.tabBtn("New","submit")),t}tabBtn(t,e){let a=document.createElement("button");return a.className="malto-tab",a.setAttribute("aria-selected",this.state.view===e?"true":"false"),a.textContent=t,a.addEventListener("click",()=>this.go(e)),this.tabRefs[e]=a,a}go(t){this.state.view=t,this.state.error=null,(t==="roadmap"||t==="changelog"||t==="detail"&&this.state.selectedFeedback)&&(this.state.loading=true),this.render(),t==="roadmap"&&this.loadRoadmap(),t==="changelog"&&this.loadReleases(),t==="detail"&&this.state.selectedFeedback&&this.loadComments(this.state.selectedFeedback.id);}allowedViews(){let t=["roadmap","submit","changelog"],e=this.board?.widget.enabledFeatures??t,a=this.config.views??t;return t.filter(o=>e.includes(o)&&a.includes(o))}buildView(){let t=document.createElement("div");if(this.state.error){let e=document.createElement("div");e.className="malto-error",e.textContent=this.state.error,t.appendChild(e);}switch(this.state.view){case "submit":t.appendChild(this.viewSubmit());break;case "auth":t.appendChild(this.viewAuth());break;case "roadmap":t.appendChild(this.viewRoadmap());break;case "changelog":t.appendChild(this.viewChangelog());break;case "detail":t.appendChild(this.viewDetail());break}return t}feedbackRow(t){let e=document.createElement("div");e.className="malto-item";let a=document.createElement("button");a.className="malto-vote",a.setAttribute("aria-pressed",t.hasVoted?"true":"false");let o=document.createElement("span");o.className="malto-vote-arrow",o.textContent="\u25B2";let r=document.createElement("span");r.className="malto-vote-count",r.textContent=A(t.votes??0),a.appendChild(o),a.appendChild(r),a.addEventListener("click",m=>{m.stopPropagation(),this.handleVote(t);});let n=document.createElement("div");n.className="malto-item-content";let s=document.createElement("h4");if(s.textContent=t.title,n.appendChild(s),t.description){let m=document.createElement("p");m.textContent=t.description,n.appendChild(m);}let l=document.createElement("div");if(l.className="malto-item-meta",t.status&&t.status!=="BACKLOG"){let m=_(t.status);l.appendChild(m);}let d=document.createElement("span");return d.textContent=M(t.createdAt),l.appendChild(d),n.appendChild(l),e.appendChild(a),e.appendChild(n),e.addEventListener("click",()=>{this.state.selectedFeedback=t,this.go("detail");}),e}viewSubmit(){let t=document.createElement("form");t.className="malto-form";let e=document.createElement("input");e.className="malto-input",e.required=true,e.maxLength=200,e.placeholder="What would you like?";let a=document.createElement("textarea");a.className="malto-textarea",a.maxLength=5e3,a.placeholder="Add some context (optional)";let o=document.createElement("button");return o.className="malto-button",o.textContent="Submit feedback",o.type="submit",t.appendChild(e),t.appendChild(a),t.appendChild(o),t.addEventListener("submit",async r=>{if(r.preventDefault(),!this.state.email){this.go("auth");return}o.setAttribute("disabled","true");try{await this.client.createFeedback({title:e.value.trim(),description:a.value.trim()||void 0}),e.value="",a.value="",this.go("roadmap");}catch(n){this.state.error=n.message,o.removeAttribute("disabled"),this.render();}}),t}viewAuth(){let t=document.createElement("div");if(this.state.email){let n=document.createElement("p");n.style.fontSize="13px",n.style.color="var(--malto-text)",n.style.marginBottom="10px",n.innerHTML=`Signed in as <strong>${T(this.state.email)}</strong>`;let s=document.createElement("button");return s.className="malto-secondary",s.textContent="Sign out",s.addEventListener("click",()=>{y(this.apiKeyPrefix),this.state.email=null,this.state.name=null,this.go("roadmap");}),t.appendChild(n),t.appendChild(s),t}if(this.state.authStatus==="sent"){let n=document.createElement("p");n.style.fontSize="13px",n.style.color="var(--malto-text)",n.style.marginBottom="12px",n.style.lineHeight="1.5",n.innerHTML=`We sent a sign-in link to <strong>${T(this.state.authEmail)}</strong>. Open the email and paste the token below.`;let s=document.createElement("input");s.className="malto-input",s.placeholder="Paste token from email";let l=document.createElement("button");l.className="malto-button",l.style.marginTop="8px",l.textContent="Verify",l.addEventListener("click",async()=>{l.setAttribute("disabled","true");try{let m=await this.client.verifyMagicLink(s.value.trim());S(this.apiKeyPrefix,{token:m.sessionToken,expiresAt:m.expiresAt,email:m.user.email,name:m.user.name}),this.state.email=m.user.email,this.state.name=m.user.name,this.state.authStatus="idle",this.go("roadmap");}catch(m){this.state.error=m.message,l.removeAttribute("disabled"),this.render();}});let d=document.createElement("button");return d.className="malto-link",d.style.marginTop="12px",d.style.display="block",d.textContent="Use a different email",d.addEventListener("click",()=>{this.state.authStatus="idle",this.render();}),t.appendChild(n),t.appendChild(s),t.appendChild(l),t.appendChild(d),t}let e=document.createElement("form");e.className="malto-form";let a=document.createElement("p");a.style.fontSize="13px",a.style.color="var(--malto-text-muted)",a.style.marginBottom="4px",a.style.lineHeight="1.5",a.textContent="Enter your email to receive a one-click sign-in link.";let o=document.createElement("input");o.className="malto-input",o.type="email",o.required=true,o.placeholder="you@company.com",o.value=this.state.authEmail;let r=document.createElement("button");return r.className="malto-button",r.type="submit",r.textContent="Send sign-in link",e.appendChild(a),e.appendChild(o),e.appendChild(r),e.addEventListener("submit",async n=>{n.preventDefault(),r.setAttribute("disabled","true");try{await this.client.startMagicLink({email:o.value.trim()}),this.state.authEmail=o.value.trim(),this.state.authStatus="sent",this.render();}catch(s){this.state.error=s.message,r.removeAttribute("disabled"),this.render();}}),e}viewRoadmap(){let t=document.createElement("div");if(t.className="malto-kanban",this.state.loading){for(let o=0;o<4;o++){let r=document.createElement("div");r.className="malto-kanban-col";let n=document.createElement("h5");n.className="malto-kanban-title",n.textContent="Loading",r.appendChild(n),r.appendChild(this.skeletonCards(2)),t.appendChild(r);}return t}let e=[{status:"BACKLOG",title:"Backlog"},{status:"PLANNED",title:"Planned"},{status:"IN_PROGRESS",title:"In Progress"},{status:"UNDER_REVIEW",title:"Under Review"}],a=false;for(let{status:o,title:r}of e){let n=this.state.roadmap[o]??[];n.length>0&&(a=true);let s=document.createElement("div");s.className="malto-kanban-col";let l=document.createElement("div");l.className="malto-kanban-head";let d=document.createElement("h5");d.className="malto-kanban-title",d.textContent=r;let m=document.createElement("span");m.className="malto-kanban-count",m.textContent=G(n.length),l.appendChild(d),l.appendChild(m),s.appendChild(l);let c=document.createElement("div");if(c.className="malto-kanban-list",n.length===0){let u=document.createElement("div");u.className="malto-kanban-empty",u.textContent="Nothing here.",c.appendChild(u);}else for(let u of n)c.appendChild(this.feedbackCard(u));s.appendChild(c),t.appendChild(s);}return a||(t.innerHTML="",t.appendChild(this.emptyState("\u{1F5FA}\uFE0F","Empty roadmap","Once admins move items into Planned, In Progress or Done, you'll see them here."))),t}feedbackCard(t){let e=t.url??"",a=document.createElement(e?"a":"div");a.className="malto-card",e&&(a.href=e,a.target="_blank",a.rel="noopener noreferrer");let o=document.createElement("div");o.className="malto-card-top";let r=document.createElement("span");r.className="malto-card-cat",r.textContent=t.category??"General";let n=document.createElement("span");n.className="malto-card-votes",n.innerHTML=`<svg viewBox="0 0 12 12" width="10" height="10" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 7 6 4 9 7"/></svg><span>${A(t.votes??0)}</span>`,o.appendChild(r),o.appendChild(n),a.appendChild(o);let s=document.createElement("h4");if(s.className="malto-card-title",s.textContent=t.title,a.appendChild(s),t.description){let p=document.createElement("p");p.className="malto-card-desc",p.textContent=t.description,a.appendChild(p);}let l=document.createElement("div");l.className="malto-card-foot";let d=document.createElement("div");d.className="malto-card-who";let m=I(t.author?.avatarUrl),c=document.createElement("span");if(c.className="malto-card-avatar",m){let p=document.createElement("img");p.src=m,p.alt="",p.referrerPolicy="no-referrer",p.crossOrigin="anonymous",c.appendChild(p);}else c.classList.add(`malto-avatar-bg-${W(t.author?.name??t.title)}`),c.textContent=Y(t.author?.name);d.appendChild(c);let u=document.createElement("span");u.className="malto-card-author",u.textContent=t.author?.name??"Anon",d.appendChild(u);let h=document.createElement("span");h.className="malto-card-dot",h.textContent="\xB7",d.appendChild(h);let b=document.createElement("span");b.className="malto-card-time",b.textContent=M(t.createdAt),d.appendChild(b);let f=document.createElement("span");return f.className="malto-card-comments",f.innerHTML=`<svg viewBox="0 0 14 14" width="11" height="11" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 9a1.5 1.5 0 0 1-1.5 1.5H5l-3 3v-9A1.5 1.5 0 0 1 3.5 3h7A1.5 1.5 0 0 1 12 4.5z"/></svg><span>${t.commentCount??0}</span>`,l.appendChild(d),l.appendChild(f),a.appendChild(l),a}skeletonCards(t){let e=document.createElement("div");e.className="malto-kanban-list";for(let a=0;a<t;a++){let o=document.createElement("div");o.className="malto-card malto-card-skeleton";let r=document.createElement("div");r.className="malto-skeleton",r.style.height="14px",r.style.width="60px";let n=document.createElement("div");n.className="malto-skeleton",n.style.height="12px",n.style.width="85%",n.style.marginTop="10px";let s=document.createElement("div");s.className="malto-skeleton",s.style.height="10px",s.style.width="70%",s.style.marginTop="6px",o.appendChild(r),o.appendChild(n),o.appendChild(s),e.appendChild(o);}return e}viewChangelog(){let t=document.createElement("div");if(this.state.loading)return t.appendChild(this.skeletonList(2)),t;if(this.state.releases.length===0)return t.appendChild(this.emptyState("\u2728","No updates yet","Check back soon.")),t;for(let e of this.state.releases){let a=document.createElement("div");if(a.className="malto-release",e.publishedAt){let n=document.createElement("span");n.className="malto-release-date",n.textContent=J(e.publishedAt),a.appendChild(n);}let o=document.createElement("h4");o.textContent=e.title;let r=document.createElement("p");r.textContent=e.body,a.appendChild(o),a.appendChild(r),t.appendChild(a);}return t}viewDetail(){let t=document.createElement("div"),e=this.state.selectedFeedback;if(!e)return t.appendChild(this.emptyState("\u{1F4ED}","Nothing selected","Pick a request from the roadmap.")),t;let a=document.createElement("button");if(a.className="malto-back",a.innerHTML='<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg> Back',a.addEventListener("click",()=>this.go("roadmap")),t.appendChild(a),t.appendChild(this.feedbackRow(e)),this.board?.widget.enabledFeatures.includes("comment")??true){let r=document.createElement("h5");if(r.textContent="Comments",r.style.cssText="margin: 16px 0 8px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--malto-text-muted); font-weight: 600;",t.appendChild(r),this.state.loading)t.appendChild(this.skeletonList(2));else if(this.state.comments.length===0){let d=document.createElement("div");d.className="malto-empty-desc",d.style.padding="8px 0 12px",d.textContent="No comments yet \u2014 start the conversation.",t.appendChild(d);}else for(let d of this.state.comments){let m=document.createElement("div");m.className="malto-comment";let c=document.createElement("div");c.className="malto-avatar";let u=I(d.author?.avatarUrl);if(u){let x=document.createElement("img");x.src=u,x.alt="",x.referrerPolicy="no-referrer",x.crossOrigin="anonymous",c.appendChild(x);}else c.textContent=(d.author?.name??"?").charAt(0).toUpperCase();let h=document.createElement("div");h.style.flex="1",h.style.minWidth="0";let b=document.createElement("div"),f=document.createElement("span");f.className="malto-comment-author",f.textContent=d.author?.name??"User";let p=document.createElement("span");p.className="malto-comment-time",p.textContent=M(d.createdAt),b.appendChild(f),b.appendChild(p);let C=document.createElement("div");C.className="malto-comment-body",C.textContent=d.body,h.appendChild(b),h.appendChild(C),m.appendChild(c),m.appendChild(h),t.appendChild(m);}let n=document.createElement("form");n.className="malto-form",n.style.marginTop="12px";let s=document.createElement("textarea");s.className="malto-textarea",s.placeholder="Write a comment",s.required=true;let l=document.createElement("button");l.className="malto-button",l.type="submit",l.textContent="Post comment",n.appendChild(s),n.appendChild(l),n.addEventListener("submit",async d=>{if(d.preventDefault(),!this.state.email){this.go("auth");return}l.setAttribute("disabled","true");try{await this.client.addComment(e.id,s.value.trim()),s.value="",await this.loadComments(e.id);}catch(m){this.state.error=m.message;}finally{l.removeAttribute("disabled"),this.render();}}),t.appendChild(n);}return t}skeletonList(t){let e=document.createElement("div");for(let a=0;a<t;a++){let o=document.createElement("div");o.className="malto-skeleton-row";let r=document.createElement("div");r.className="malto-skeleton",r.style.width="44px",r.style.height="48px",r.style.flex="none";let n=document.createElement("div");n.style.flex="1";let s=document.createElement("div");s.className="malto-skeleton",s.style.height="12px",s.style.width="70%",s.style.marginBottom="6px";let l=document.createElement("div");l.className="malto-skeleton",l.style.height="10px",l.style.width="90%",n.appendChild(s),n.appendChild(l),o.appendChild(r),o.appendChild(n),e.appendChild(o);}return e}emptyState(t,e,a){let o=document.createElement("div");o.className="malto-empty";let r=document.createElement("div");r.className="malto-empty-icon",r.style.fontSize="20px",r.textContent=t;let n=document.createElement("div");n.className="malto-empty-title",n.textContent=e;let s=document.createElement("div");return s.className="malto-empty-desc",s.textContent=a,o.appendChild(r),o.appendChild(n),o.appendChild(s),o}async loadRoadmap(){this.state.loading=true,this.render();try{this.state.roadmap=await this.client.roadmap();}catch(t){this.state.error=t.message;}finally{this.state.loading=false,this.render();}}async loadReleases(){this.state.loading=true,this.render();try{this.state.releases=await this.client.releases();}catch(t){this.state.error=t.message;}finally{this.state.loading=false,this.render();}}async loadComments(t){this.state.loading=true,this.render();try{this.state.comments=await this.client.comments(t);}catch(e){this.state.error=e.message;}finally{this.state.loading=false,this.render();}}async handleVote(t){if(!this.state.email){this.go("auth");return}try{let e=await this.client.vote(t.id);t.hasVoted=e.voted,t.votes=e.votes,this.render();}catch(e){this.state.error=e.message,this.render();}}};function _(i){let t=document.createElement("span");t.className=`malto-status malto-status-${i}`;let e=document.createElement("span");e.className="malto-status-dot",t.appendChild(e);let a=document.createElement("span"),o={PLANNED:"Planned",IN_PROGRESS:"In progress",COMPLETED:"Done",DECLINED:"Declined",UNDER_REVIEW:"Under review",BACKLOG:"Backlog"};return a.textContent=o[i]??i,t.appendChild(a),t}function Y(i){if(!i)return "?";let t=i.trim().split(/\s+/).filter(Boolean);if(t.length===0)return "?";let e=t[0]?.[0]??"",a=t.length>1?t[t.length-1]?.[0]??"":"";return (e+a).toUpperCase()||"?"}function W(i){let t=0;for(let e=0;e<i.length;e++)t=t*31+i.charCodeAt(e)>>>0;return t%8}function G(i){return i<10?`0${i}`:String(i)}function A(i){return i<1e3?String(i):i<1e4?(i/1e3).toFixed(1).replace(/\.0$/,"")+"k":Math.floor(i/1e3)+"k"}function M(i){let t=Date.now()-new Date(i).getTime(),e=Math.floor(t/1e3);if(e<60)return "just now";let a=Math.floor(e/60);if(a<60)return `${a}m`;let o=Math.floor(a/60);if(o<24)return `${o}h`;let r=Math.floor(o/24);if(r<30)return `${r}d`;let n=Math.floor(r/30);return n<12?`${n}mo`:`${Math.floor(n/12)}y`}function J(i){try{return new Date(i).toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"})}catch{return i}}function T(i){return i.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function I(i){if(!i||typeof i!="string")return null;let t;try{t=new URL(i,typeof location<"u"?location.href:"https://x");}catch{return null}return t.protocol!=="https:"&&t.protocol!=="http:"?null:t.toString()}var g=null;function st(i){g&&g.unmount();let t=new E(i);return g=t,t.mount(),t}function lt(){g?.open();}function dt(){g?.close();}function mt(i){g?.setIdentify(i);}function ct(i){y(i.slice(0,16)),g?.setIdentify(null);}function pt(){g?.unmount(),g=null;}
|
|
810
|
+
exports.MaltoApiError=k;exports.MaltoClient=v;exports.MaltoWidget=E;exports.close=dt;exports.destroy=pt;exports.identify=mt;exports.init=st;exports.open=lt;exports.reset=ct;return exports;})({});
|
package/package.json
CHANGED