@malto/sdk 0.1.0 → 0.1.2
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 +47 -45
- package/dist/index.js +47 -45
- package/dist/malto.umd.js +46 -44
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/client.ts
|
|
4
|
-
var DEFAULT_API_URL = "https://api.
|
|
4
|
+
var DEFAULT_API_URL = "https://malto-api-production.up.railway.app";
|
|
5
5
|
var MaltoClient = class {
|
|
6
6
|
constructor(opts) {
|
|
7
7
|
this.apiKey = opts.apiKey;
|
|
@@ -178,10 +178,12 @@ function upsert(id, css) {
|
|
|
178
178
|
function buildCss(opts) {
|
|
179
179
|
const primary = opts.primary;
|
|
180
180
|
const tones = derivePalette(primary);
|
|
181
|
-
const radiusScale = opts.radius === "sm" ? "
|
|
181
|
+
const radiusScale = opts.radius === "sm" ? "12px" : opts.radius === "lg" ? "24px" : "20px";
|
|
182
182
|
const appearance = opts.appearance ?? "auto";
|
|
183
183
|
const overrides = opts.cssVars ?? {};
|
|
184
184
|
return `
|
|
185
|
+
@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');
|
|
186
|
+
|
|
185
187
|
:where(.malto-root, .malto-root *) {
|
|
186
188
|
box-sizing: border-box;
|
|
187
189
|
}
|
|
@@ -194,21 +196,21 @@ function buildCss(opts) {
|
|
|
194
196
|
--malto-primary-600: ${tones.shade600};
|
|
195
197
|
--malto-primary-rgb: ${tones.rgb};
|
|
196
198
|
--malto-surface: ${overrides.surface ?? "#ffffff"};
|
|
197
|
-
--malto-surface-muted: ${overrides.surfaceMuted ?? "#
|
|
198
|
-
--malto-surface-elevated: rgba(255,255,255,0.
|
|
199
|
-
--malto-border: ${overrides.border ?? "
|
|
200
|
-
--malto-border-strong:
|
|
201
|
-
--malto-text: ${overrides.text ?? "#
|
|
199
|
+
--malto-surface-muted: ${overrides.surfaceMuted ?? "#f2eeff"};
|
|
200
|
+
--malto-surface-elevated: rgba(255,255,255,0.92);
|
|
201
|
+
--malto-border: ${overrides.border ?? "#e2e8f0"};
|
|
202
|
+
--malto-border-strong: #cbd1de;
|
|
203
|
+
--malto-text: ${overrides.text ?? "#0a0a0a"};
|
|
202
204
|
--malto-text-muted: ${overrides.textMuted ?? "#5b5871"};
|
|
203
|
-
--malto-text-subtle: rgba(
|
|
205
|
+
--malto-text-subtle: rgba(10, 10, 10, 0.5);
|
|
204
206
|
--malto-radius: ${overrides.radius ?? radiusScale};
|
|
205
|
-
--malto-radius-sm:
|
|
207
|
+
--malto-radius-sm: 12px;
|
|
206
208
|
--malto-radius-pill: 999px;
|
|
207
|
-
--malto-shadow-sm: ${overrides.shadow ?? "0 4px 12px -
|
|
208
|
-
--malto-shadow-md: 0
|
|
209
|
-
--malto-shadow-lg: 0 30px 60px -20px rgba(
|
|
210
|
-
--malto-shadow-glow: 0
|
|
211
|
-
--malto-font: ${overrides.font ?? "
|
|
209
|
+
--malto-shadow-sm: ${overrides.shadow ?? "0 4px 12px -6px rgba(25, 24, 56, 0.12)"};
|
|
210
|
+
--malto-shadow-md: 0 10px 30px -10px rgba(25, 24, 56, 0.15);
|
|
211
|
+
--malto-shadow-lg: 0 30px 60px -20px rgba(25, 24, 56, 0.25);
|
|
212
|
+
--malto-shadow-glow: 0 8px 20px -6px rgba(var(--malto-primary-rgb), 0.45);
|
|
213
|
+
--malto-font: ${overrides.font ?? "'Google Sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif"};
|
|
212
214
|
--malto-ease-spring: cubic-bezier(0.34, 1.4, 0.5, 1);
|
|
213
215
|
--malto-ease-smooth: cubic-bezier(0.32, 0.72, 0, 1);
|
|
214
216
|
}
|
|
@@ -269,12 +271,12 @@ function buildCss(opts) {
|
|
|
269
271
|
|
|
270
272
|
.malto-trigger {
|
|
271
273
|
display: inline-flex; align-items: center; gap: 8px;
|
|
272
|
-
padding:
|
|
274
|
+
padding: 10px 20px;
|
|
273
275
|
border-radius: var(--malto-radius-pill);
|
|
274
276
|
background: var(--malto-primary);
|
|
275
277
|
color: var(--malto-primary-contrast);
|
|
276
278
|
border: none; cursor: pointer;
|
|
277
|
-
font-size:
|
|
279
|
+
font-size: 14px; font-weight: 600; letter-spacing: -0.01em;
|
|
278
280
|
box-shadow: var(--malto-shadow-glow);
|
|
279
281
|
transition: transform .25s var(--malto-ease-spring), box-shadow .2s ease;
|
|
280
282
|
}
|
|
@@ -328,23 +330,23 @@ function buildCss(opts) {
|
|
|
328
330
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
329
331
|
.malto-header {
|
|
330
332
|
display: flex; align-items: center; justify-content: space-between;
|
|
331
|
-
padding:
|
|
333
|
+
padding: 22px 24px 16px;
|
|
332
334
|
position: relative;
|
|
333
335
|
flex: none;
|
|
334
336
|
}
|
|
335
337
|
.malto-header h3 {
|
|
336
338
|
margin: 0;
|
|
337
|
-
font-size:
|
|
339
|
+
font-size: 17px; font-weight: 600;
|
|
338
340
|
color: var(--malto-text);
|
|
339
|
-
letter-spacing: -0.
|
|
341
|
+
letter-spacing: -0.02em;
|
|
340
342
|
}
|
|
341
343
|
.malto-header-meta {
|
|
342
344
|
display: flex; align-items: center; gap: 10px;
|
|
343
345
|
}
|
|
344
346
|
.malto-board-logo {
|
|
345
347
|
width: 28px; height: 28px;
|
|
346
|
-
border-radius:
|
|
347
|
-
background: var(--malto-
|
|
348
|
+
border-radius: 10px;
|
|
349
|
+
background: var(--malto-surface-muted);
|
|
348
350
|
display: flex; align-items: center; justify-content: center;
|
|
349
351
|
color: var(--malto-primary);
|
|
350
352
|
font-size: 12px; font-weight: 700;
|
|
@@ -362,7 +364,7 @@ function buildCss(opts) {
|
|
|
362
364
|
transition: background .15s ease, color .15s ease;
|
|
363
365
|
}
|
|
364
366
|
.malto-close:hover {
|
|
365
|
-
background: var(--malto-
|
|
367
|
+
background: var(--malto-surface-muted);
|
|
366
368
|
color: var(--malto-text);
|
|
367
369
|
}
|
|
368
370
|
|
|
@@ -370,8 +372,8 @@ function buildCss(opts) {
|
|
|
370
372
|
.malto-tabs {
|
|
371
373
|
display: flex;
|
|
372
374
|
padding: 4px;
|
|
373
|
-
margin: 0
|
|
374
|
-
background: var(--malto-
|
|
375
|
+
margin: 0 24px 16px;
|
|
376
|
+
background: var(--malto-surface-muted);
|
|
375
377
|
border-radius: var(--malto-radius-sm);
|
|
376
378
|
flex: none;
|
|
377
379
|
}
|
|
@@ -397,7 +399,7 @@ function buildCss(opts) {
|
|
|
397
399
|
.malto-body {
|
|
398
400
|
flex: 1;
|
|
399
401
|
overflow-y: auto;
|
|
400
|
-
padding: 4px
|
|
402
|
+
padding: 4px 24px 22px;
|
|
401
403
|
background: var(--malto-surface);
|
|
402
404
|
scroll-behavior: smooth;
|
|
403
405
|
}
|
|
@@ -412,7 +414,7 @@ function buildCss(opts) {
|
|
|
412
414
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Feedback row \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
413
415
|
.malto-item {
|
|
414
416
|
display: flex; gap: 12px;
|
|
415
|
-
padding:
|
|
417
|
+
padding: 14px;
|
|
416
418
|
border-radius: 12px;
|
|
417
419
|
background: var(--malto-surface);
|
|
418
420
|
border: 1px solid var(--malto-border);
|
|
@@ -423,15 +425,15 @@ function buildCss(opts) {
|
|
|
423
425
|
.malto-item:hover {
|
|
424
426
|
border-color: var(--malto-border-strong);
|
|
425
427
|
transform: translateY(-1px);
|
|
426
|
-
box-shadow:
|
|
428
|
+
box-shadow: 0 6px 16px -8px rgba(25, 24, 56, 0.12);
|
|
427
429
|
}
|
|
428
430
|
.malto-vote {
|
|
429
431
|
display: flex; flex-direction: column;
|
|
430
432
|
align-items: center; justify-content: center;
|
|
431
433
|
min-width: 44px; padding: 6px 4px;
|
|
432
|
-
border-radius:
|
|
434
|
+
border-radius: 12px;
|
|
433
435
|
border: 1px solid var(--malto-border);
|
|
434
|
-
background: var(--malto-surface
|
|
436
|
+
background: var(--malto-surface);
|
|
435
437
|
cursor: pointer;
|
|
436
438
|
font-size: 11px; color: var(--malto-text-muted);
|
|
437
439
|
transition: all .2s var(--malto-ease-spring);
|
|
@@ -518,10 +520,10 @@ function buildCss(opts) {
|
|
|
518
520
|
}
|
|
519
521
|
.malto-input, .malto-textarea {
|
|
520
522
|
width: 100%;
|
|
521
|
-
padding:
|
|
522
|
-
border: 1px solid var(--malto-border
|
|
523
|
+
padding: 12px 14px;
|
|
524
|
+
border: 1px solid var(--malto-border);
|
|
523
525
|
border-radius: 12px;
|
|
524
|
-
font-size:
|
|
526
|
+
font-size: 14px;
|
|
525
527
|
color: var(--malto-text);
|
|
526
528
|
background: var(--malto-surface);
|
|
527
529
|
outline: none;
|
|
@@ -533,7 +535,7 @@ function buildCss(opts) {
|
|
|
533
535
|
}
|
|
534
536
|
.malto-input:focus, .malto-textarea:focus {
|
|
535
537
|
border-color: var(--malto-primary);
|
|
536
|
-
box-shadow: 0 0 0 4px rgba(var(--malto-primary-rgb), 0.
|
|
538
|
+
box-shadow: 0 0 0 4px rgba(var(--malto-primary-rgb), 0.12);
|
|
537
539
|
}
|
|
538
540
|
.malto-textarea {
|
|
539
541
|
min-height: 110px;
|
|
@@ -541,13 +543,13 @@ function buildCss(opts) {
|
|
|
541
543
|
line-height: 1.5;
|
|
542
544
|
}
|
|
543
545
|
.malto-button {
|
|
544
|
-
padding:
|
|
546
|
+
padding: 12px 20px;
|
|
545
547
|
border-radius: 12px;
|
|
546
548
|
background: var(--malto-primary);
|
|
547
549
|
color: var(--malto-primary-contrast);
|
|
548
550
|
border: none; cursor: pointer;
|
|
549
|
-
font-size:
|
|
550
|
-
letter-spacing: -0.
|
|
551
|
+
font-size: 14px; font-weight: 600;
|
|
552
|
+
letter-spacing: -0.01em;
|
|
551
553
|
box-shadow: var(--malto-shadow-glow);
|
|
552
554
|
transition: transform .2s var(--malto-ease-spring), box-shadow .2s ease, opacity .2s ease;
|
|
553
555
|
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
@@ -556,13 +558,13 @@ function buildCss(opts) {
|
|
|
556
558
|
.malto-button:active { transform: scale(0.97); }
|
|
557
559
|
.malto-button[disabled] { opacity: .5; cursor: not-allowed; transform: none; }
|
|
558
560
|
.malto-secondary {
|
|
559
|
-
padding:
|
|
560
|
-
border-radius:
|
|
561
|
+
padding: 10px 16px;
|
|
562
|
+
border-radius: 12px;
|
|
561
563
|
background: transparent;
|
|
562
564
|
color: var(--malto-text);
|
|
563
|
-
border: 1px solid var(--malto-border
|
|
565
|
+
border: 1px solid var(--malto-border);
|
|
564
566
|
cursor: pointer;
|
|
565
|
-
font-size:
|
|
567
|
+
font-size: 13.5px; font-weight: 500;
|
|
566
568
|
transition: all .2s ease;
|
|
567
569
|
}
|
|
568
570
|
.malto-secondary:hover {
|
|
@@ -655,7 +657,7 @@ function buildCss(opts) {
|
|
|
655
657
|
|
|
656
658
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Releases / changelog \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
657
659
|
.malto-release {
|
|
658
|
-
padding:
|
|
660
|
+
padding: 16px;
|
|
659
661
|
border: 1px solid var(--malto-border);
|
|
660
662
|
border-radius: 12px;
|
|
661
663
|
margin-bottom: 8px;
|
|
@@ -725,10 +727,10 @@ function buildCss(opts) {
|
|
|
725
727
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Footer banner (sign-in CTA) \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
726
728
|
.malto-footer-banner {
|
|
727
729
|
flex: none;
|
|
728
|
-
padding:
|
|
730
|
+
padding: 14px 24px;
|
|
729
731
|
background: var(--malto-surface-muted);
|
|
730
732
|
border-top: 1px solid var(--malto-border);
|
|
731
|
-
font-size:
|
|
733
|
+
font-size: 12.5px;
|
|
732
734
|
color: var(--malto-text-muted);
|
|
733
735
|
display: flex; align-items: center; justify-content: space-between;
|
|
734
736
|
gap: 10px;
|
|
@@ -748,7 +750,7 @@ function buildCss(opts) {
|
|
|
748
750
|
}
|
|
749
751
|
.malto-back:hover {
|
|
750
752
|
color: var(--malto-text);
|
|
751
|
-
background: var(--malto-
|
|
753
|
+
background: var(--malto-surface-muted);
|
|
752
754
|
}
|
|
753
755
|
|
|
754
756
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Animations \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
@@ -844,7 +846,7 @@ var MaltoWidget = class {
|
|
|
844
846
|
this.apiKeyPrefix = config.apiKey.slice(0, 16);
|
|
845
847
|
this.config = {
|
|
846
848
|
apiKey: config.apiKey,
|
|
847
|
-
apiUrl: config.apiUrl ?? "https://api.
|
|
849
|
+
apiUrl: config.apiUrl ?? "https://malto-api-production.up.railway.app",
|
|
848
850
|
mode: config.mode ?? "auto",
|
|
849
851
|
position: config.position ?? "bottom-right",
|
|
850
852
|
triggerLabel: config.triggerLabel ?? "Feedback",
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/client.ts
|
|
2
|
-
var DEFAULT_API_URL = "https://api.
|
|
2
|
+
var DEFAULT_API_URL = "https://malto-api-production.up.railway.app";
|
|
3
3
|
var MaltoClient = class {
|
|
4
4
|
constructor(opts) {
|
|
5
5
|
this.apiKey = opts.apiKey;
|
|
@@ -176,10 +176,12 @@ function upsert(id, css) {
|
|
|
176
176
|
function buildCss(opts) {
|
|
177
177
|
const primary = opts.primary;
|
|
178
178
|
const tones = derivePalette(primary);
|
|
179
|
-
const radiusScale = opts.radius === "sm" ? "
|
|
179
|
+
const radiusScale = opts.radius === "sm" ? "12px" : opts.radius === "lg" ? "24px" : "20px";
|
|
180
180
|
const appearance = opts.appearance ?? "auto";
|
|
181
181
|
const overrides = opts.cssVars ?? {};
|
|
182
182
|
return `
|
|
183
|
+
@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');
|
|
184
|
+
|
|
183
185
|
:where(.malto-root, .malto-root *) {
|
|
184
186
|
box-sizing: border-box;
|
|
185
187
|
}
|
|
@@ -192,21 +194,21 @@ function buildCss(opts) {
|
|
|
192
194
|
--malto-primary-600: ${tones.shade600};
|
|
193
195
|
--malto-primary-rgb: ${tones.rgb};
|
|
194
196
|
--malto-surface: ${overrides.surface ?? "#ffffff"};
|
|
195
|
-
--malto-surface-muted: ${overrides.surfaceMuted ?? "#
|
|
196
|
-
--malto-surface-elevated: rgba(255,255,255,0.
|
|
197
|
-
--malto-border: ${overrides.border ?? "
|
|
198
|
-
--malto-border-strong:
|
|
199
|
-
--malto-text: ${overrides.text ?? "#
|
|
197
|
+
--malto-surface-muted: ${overrides.surfaceMuted ?? "#f2eeff"};
|
|
198
|
+
--malto-surface-elevated: rgba(255,255,255,0.92);
|
|
199
|
+
--malto-border: ${overrides.border ?? "#e2e8f0"};
|
|
200
|
+
--malto-border-strong: #cbd1de;
|
|
201
|
+
--malto-text: ${overrides.text ?? "#0a0a0a"};
|
|
200
202
|
--malto-text-muted: ${overrides.textMuted ?? "#5b5871"};
|
|
201
|
-
--malto-text-subtle: rgba(
|
|
203
|
+
--malto-text-subtle: rgba(10, 10, 10, 0.5);
|
|
202
204
|
--malto-radius: ${overrides.radius ?? radiusScale};
|
|
203
|
-
--malto-radius-sm:
|
|
205
|
+
--malto-radius-sm: 12px;
|
|
204
206
|
--malto-radius-pill: 999px;
|
|
205
|
-
--malto-shadow-sm: ${overrides.shadow ?? "0 4px 12px -
|
|
206
|
-
--malto-shadow-md: 0
|
|
207
|
-
--malto-shadow-lg: 0 30px 60px -20px rgba(
|
|
208
|
-
--malto-shadow-glow: 0
|
|
209
|
-
--malto-font: ${overrides.font ?? "
|
|
207
|
+
--malto-shadow-sm: ${overrides.shadow ?? "0 4px 12px -6px rgba(25, 24, 56, 0.12)"};
|
|
208
|
+
--malto-shadow-md: 0 10px 30px -10px rgba(25, 24, 56, 0.15);
|
|
209
|
+
--malto-shadow-lg: 0 30px 60px -20px rgba(25, 24, 56, 0.25);
|
|
210
|
+
--malto-shadow-glow: 0 8px 20px -6px rgba(var(--malto-primary-rgb), 0.45);
|
|
211
|
+
--malto-font: ${overrides.font ?? "'Google Sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif"};
|
|
210
212
|
--malto-ease-spring: cubic-bezier(0.34, 1.4, 0.5, 1);
|
|
211
213
|
--malto-ease-smooth: cubic-bezier(0.32, 0.72, 0, 1);
|
|
212
214
|
}
|
|
@@ -267,12 +269,12 @@ function buildCss(opts) {
|
|
|
267
269
|
|
|
268
270
|
.malto-trigger {
|
|
269
271
|
display: inline-flex; align-items: center; gap: 8px;
|
|
270
|
-
padding:
|
|
272
|
+
padding: 10px 20px;
|
|
271
273
|
border-radius: var(--malto-radius-pill);
|
|
272
274
|
background: var(--malto-primary);
|
|
273
275
|
color: var(--malto-primary-contrast);
|
|
274
276
|
border: none; cursor: pointer;
|
|
275
|
-
font-size:
|
|
277
|
+
font-size: 14px; font-weight: 600; letter-spacing: -0.01em;
|
|
276
278
|
box-shadow: var(--malto-shadow-glow);
|
|
277
279
|
transition: transform .25s var(--malto-ease-spring), box-shadow .2s ease;
|
|
278
280
|
}
|
|
@@ -326,23 +328,23 @@ function buildCss(opts) {
|
|
|
326
328
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
327
329
|
.malto-header {
|
|
328
330
|
display: flex; align-items: center; justify-content: space-between;
|
|
329
|
-
padding:
|
|
331
|
+
padding: 22px 24px 16px;
|
|
330
332
|
position: relative;
|
|
331
333
|
flex: none;
|
|
332
334
|
}
|
|
333
335
|
.malto-header h3 {
|
|
334
336
|
margin: 0;
|
|
335
|
-
font-size:
|
|
337
|
+
font-size: 17px; font-weight: 600;
|
|
336
338
|
color: var(--malto-text);
|
|
337
|
-
letter-spacing: -0.
|
|
339
|
+
letter-spacing: -0.02em;
|
|
338
340
|
}
|
|
339
341
|
.malto-header-meta {
|
|
340
342
|
display: flex; align-items: center; gap: 10px;
|
|
341
343
|
}
|
|
342
344
|
.malto-board-logo {
|
|
343
345
|
width: 28px; height: 28px;
|
|
344
|
-
border-radius:
|
|
345
|
-
background: var(--malto-
|
|
346
|
+
border-radius: 10px;
|
|
347
|
+
background: var(--malto-surface-muted);
|
|
346
348
|
display: flex; align-items: center; justify-content: center;
|
|
347
349
|
color: var(--malto-primary);
|
|
348
350
|
font-size: 12px; font-weight: 700;
|
|
@@ -360,7 +362,7 @@ function buildCss(opts) {
|
|
|
360
362
|
transition: background .15s ease, color .15s ease;
|
|
361
363
|
}
|
|
362
364
|
.malto-close:hover {
|
|
363
|
-
background: var(--malto-
|
|
365
|
+
background: var(--malto-surface-muted);
|
|
364
366
|
color: var(--malto-text);
|
|
365
367
|
}
|
|
366
368
|
|
|
@@ -368,8 +370,8 @@ function buildCss(opts) {
|
|
|
368
370
|
.malto-tabs {
|
|
369
371
|
display: flex;
|
|
370
372
|
padding: 4px;
|
|
371
|
-
margin: 0
|
|
372
|
-
background: var(--malto-
|
|
373
|
+
margin: 0 24px 16px;
|
|
374
|
+
background: var(--malto-surface-muted);
|
|
373
375
|
border-radius: var(--malto-radius-sm);
|
|
374
376
|
flex: none;
|
|
375
377
|
}
|
|
@@ -395,7 +397,7 @@ function buildCss(opts) {
|
|
|
395
397
|
.malto-body {
|
|
396
398
|
flex: 1;
|
|
397
399
|
overflow-y: auto;
|
|
398
|
-
padding: 4px
|
|
400
|
+
padding: 4px 24px 22px;
|
|
399
401
|
background: var(--malto-surface);
|
|
400
402
|
scroll-behavior: smooth;
|
|
401
403
|
}
|
|
@@ -410,7 +412,7 @@ function buildCss(opts) {
|
|
|
410
412
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Feedback row \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
411
413
|
.malto-item {
|
|
412
414
|
display: flex; gap: 12px;
|
|
413
|
-
padding:
|
|
415
|
+
padding: 14px;
|
|
414
416
|
border-radius: 12px;
|
|
415
417
|
background: var(--malto-surface);
|
|
416
418
|
border: 1px solid var(--malto-border);
|
|
@@ -421,15 +423,15 @@ function buildCss(opts) {
|
|
|
421
423
|
.malto-item:hover {
|
|
422
424
|
border-color: var(--malto-border-strong);
|
|
423
425
|
transform: translateY(-1px);
|
|
424
|
-
box-shadow:
|
|
426
|
+
box-shadow: 0 6px 16px -8px rgba(25, 24, 56, 0.12);
|
|
425
427
|
}
|
|
426
428
|
.malto-vote {
|
|
427
429
|
display: flex; flex-direction: column;
|
|
428
430
|
align-items: center; justify-content: center;
|
|
429
431
|
min-width: 44px; padding: 6px 4px;
|
|
430
|
-
border-radius:
|
|
432
|
+
border-radius: 12px;
|
|
431
433
|
border: 1px solid var(--malto-border);
|
|
432
|
-
background: var(--malto-surface
|
|
434
|
+
background: var(--malto-surface);
|
|
433
435
|
cursor: pointer;
|
|
434
436
|
font-size: 11px; color: var(--malto-text-muted);
|
|
435
437
|
transition: all .2s var(--malto-ease-spring);
|
|
@@ -516,10 +518,10 @@ function buildCss(opts) {
|
|
|
516
518
|
}
|
|
517
519
|
.malto-input, .malto-textarea {
|
|
518
520
|
width: 100%;
|
|
519
|
-
padding:
|
|
520
|
-
border: 1px solid var(--malto-border
|
|
521
|
+
padding: 12px 14px;
|
|
522
|
+
border: 1px solid var(--malto-border);
|
|
521
523
|
border-radius: 12px;
|
|
522
|
-
font-size:
|
|
524
|
+
font-size: 14px;
|
|
523
525
|
color: var(--malto-text);
|
|
524
526
|
background: var(--malto-surface);
|
|
525
527
|
outline: none;
|
|
@@ -531,7 +533,7 @@ function buildCss(opts) {
|
|
|
531
533
|
}
|
|
532
534
|
.malto-input:focus, .malto-textarea:focus {
|
|
533
535
|
border-color: var(--malto-primary);
|
|
534
|
-
box-shadow: 0 0 0 4px rgba(var(--malto-primary-rgb), 0.
|
|
536
|
+
box-shadow: 0 0 0 4px rgba(var(--malto-primary-rgb), 0.12);
|
|
535
537
|
}
|
|
536
538
|
.malto-textarea {
|
|
537
539
|
min-height: 110px;
|
|
@@ -539,13 +541,13 @@ function buildCss(opts) {
|
|
|
539
541
|
line-height: 1.5;
|
|
540
542
|
}
|
|
541
543
|
.malto-button {
|
|
542
|
-
padding:
|
|
544
|
+
padding: 12px 20px;
|
|
543
545
|
border-radius: 12px;
|
|
544
546
|
background: var(--malto-primary);
|
|
545
547
|
color: var(--malto-primary-contrast);
|
|
546
548
|
border: none; cursor: pointer;
|
|
547
|
-
font-size:
|
|
548
|
-
letter-spacing: -0.
|
|
549
|
+
font-size: 14px; font-weight: 600;
|
|
550
|
+
letter-spacing: -0.01em;
|
|
549
551
|
box-shadow: var(--malto-shadow-glow);
|
|
550
552
|
transition: transform .2s var(--malto-ease-spring), box-shadow .2s ease, opacity .2s ease;
|
|
551
553
|
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
@@ -554,13 +556,13 @@ function buildCss(opts) {
|
|
|
554
556
|
.malto-button:active { transform: scale(0.97); }
|
|
555
557
|
.malto-button[disabled] { opacity: .5; cursor: not-allowed; transform: none; }
|
|
556
558
|
.malto-secondary {
|
|
557
|
-
padding:
|
|
558
|
-
border-radius:
|
|
559
|
+
padding: 10px 16px;
|
|
560
|
+
border-radius: 12px;
|
|
559
561
|
background: transparent;
|
|
560
562
|
color: var(--malto-text);
|
|
561
|
-
border: 1px solid var(--malto-border
|
|
563
|
+
border: 1px solid var(--malto-border);
|
|
562
564
|
cursor: pointer;
|
|
563
|
-
font-size:
|
|
565
|
+
font-size: 13.5px; font-weight: 500;
|
|
564
566
|
transition: all .2s ease;
|
|
565
567
|
}
|
|
566
568
|
.malto-secondary:hover {
|
|
@@ -653,7 +655,7 @@ function buildCss(opts) {
|
|
|
653
655
|
|
|
654
656
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Releases / changelog \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
655
657
|
.malto-release {
|
|
656
|
-
padding:
|
|
658
|
+
padding: 16px;
|
|
657
659
|
border: 1px solid var(--malto-border);
|
|
658
660
|
border-radius: 12px;
|
|
659
661
|
margin-bottom: 8px;
|
|
@@ -723,10 +725,10 @@ function buildCss(opts) {
|
|
|
723
725
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Footer banner (sign-in CTA) \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
724
726
|
.malto-footer-banner {
|
|
725
727
|
flex: none;
|
|
726
|
-
padding:
|
|
728
|
+
padding: 14px 24px;
|
|
727
729
|
background: var(--malto-surface-muted);
|
|
728
730
|
border-top: 1px solid var(--malto-border);
|
|
729
|
-
font-size:
|
|
731
|
+
font-size: 12.5px;
|
|
730
732
|
color: var(--malto-text-muted);
|
|
731
733
|
display: flex; align-items: center; justify-content: space-between;
|
|
732
734
|
gap: 10px;
|
|
@@ -746,7 +748,7 @@ function buildCss(opts) {
|
|
|
746
748
|
}
|
|
747
749
|
.malto-back:hover {
|
|
748
750
|
color: var(--malto-text);
|
|
749
|
-
background: var(--malto-
|
|
751
|
+
background: var(--malto-surface-muted);
|
|
750
752
|
}
|
|
751
753
|
|
|
752
754
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Animations \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
@@ -842,7 +844,7 @@ var MaltoWidget = class {
|
|
|
842
844
|
this.apiKeyPrefix = config.apiKey.slice(0, 16);
|
|
843
845
|
this.config = {
|
|
844
846
|
apiKey: config.apiKey,
|
|
845
|
-
apiUrl: config.apiUrl ?? "https://api.
|
|
847
|
+
apiUrl: config.apiUrl ?? "https://malto-api-production.up.railway.app",
|
|
846
848
|
mode: config.mode ?? "auto",
|
|
847
849
|
position: config.position ?? "bottom-right",
|
|
848
850
|
triggerLabel: config.triggerLabel ?? "Feedback",
|
package/dist/malto.umd.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
var Malto=(function(exports){'use strict';var F="https://api.
|
|
1
|
+
var Malto=(function(exports){'use strict';var F="https://malto-api-production.up.railway.app",h=class{constructor(t){this.apiKey=t.apiKey,this.apiUrl=(t.apiUrl??F).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[d,l]of Object.entries(s))a[d]=l;}if(e.auth){let s=this.getSessionToken();s&&(a["X-Malto-Session"]=s);}let r=await fetch(`${this.apiUrl}${t}`,{...e,headers:a}),o=await r.text(),n=o?A(o):null;if(!r.ok){let s=n&&(n.message||n.error)||`Request failed (${r.status})`;throw new b(Array.isArray(s)?s.join(", "):String(s),r.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)})}},b=class extends Error{constructor(e,a){super(e);this.status=a;this.name="MaltoApiError";}};function A(i){try{return JSON.parse(i)}catch{return null}}var x="malto:session:";function E(i){if(typeof window>"u")return null;try{let t=window.localStorage.getItem(x+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(x+i),null):e}catch{return null}}function S(i,t){if(!(typeof window>"u"))try{window.localStorage.setItem(x+i,JSON.stringify(t));}catch{}}function g(i){if(!(typeof window>"u"))try{window.localStorage.removeItem(x+i);}catch{}}var H="malto-sdk-styles",P="malto-sdk-styles-custom";function z(i){if(typeof document>"u")return;let t=B(i);I(H,t),i.customCss?I(P,O(i.customCss)):document.getElementById(P)?.remove();}function O(i){return i.replace(/<\/style/gi,"<\\/style").replace(/<\/script/gi,"<\\/script").replace(/expression\s*\(/gi,"expr\\(").replace(/javascript\s*:/gi,"javascript\\:")}function I(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 B(i){let t=i.primary,e=D(t),a=i.radius==="sm"?"12px":i.radius==="lg"?"24px":"20px",r=i.appearance??"auto",o=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,21 +13,21 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
11
13
|
--malto-primary-600: ${e.shade600};
|
|
12
14
|
--malto-primary-rgb: ${e.rgb};
|
|
13
15
|
--malto-surface: ${o.surface??"#ffffff"};
|
|
14
|
-
--malto-surface-muted: ${o.surfaceMuted??"#
|
|
15
|
-
--malto-surface-elevated: rgba(255,255,255,0.
|
|
16
|
-
--malto-border: ${o.border??"
|
|
17
|
-
--malto-border-strong:
|
|
18
|
-
--malto-text: ${o.text??"#
|
|
16
|
+
--malto-surface-muted: ${o.surfaceMuted??"#f2eeff"};
|
|
17
|
+
--malto-surface-elevated: rgba(255,255,255,0.92);
|
|
18
|
+
--malto-border: ${o.border??"#e2e8f0"};
|
|
19
|
+
--malto-border-strong: #cbd1de;
|
|
20
|
+
--malto-text: ${o.text??"#0a0a0a"};
|
|
19
21
|
--malto-text-muted: ${o.textMuted??"#5b5871"};
|
|
20
|
-
--malto-text-subtle: rgba(
|
|
22
|
+
--malto-text-subtle: rgba(10, 10, 10, 0.5);
|
|
21
23
|
--malto-radius: ${o.radius??a};
|
|
22
|
-
--malto-radius-sm:
|
|
24
|
+
--malto-radius-sm: 12px;
|
|
23
25
|
--malto-radius-pill: 999px;
|
|
24
|
-
--malto-shadow-sm: ${o.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: ${o.font??"
|
|
26
|
+
--malto-shadow-sm: ${o.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: ${o.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
|
}
|
|
@@ -86,12 +88,12 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
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
|
}
|
|
@@ -145,23 +147,23 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
145
147
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
146
148
|
.malto-header {
|
|
147
149
|
display: flex; align-items: center; justify-content: space-between;
|
|
148
|
-
padding:
|
|
150
|
+
padding: 22px 24px 16px;
|
|
149
151
|
position: relative;
|
|
150
152
|
flex: none;
|
|
151
153
|
}
|
|
152
154
|
.malto-header h3 {
|
|
153
155
|
margin: 0;
|
|
154
|
-
font-size:
|
|
156
|
+
font-size: 17px; font-weight: 600;
|
|
155
157
|
color: var(--malto-text);
|
|
156
|
-
letter-spacing: -0.
|
|
158
|
+
letter-spacing: -0.02em;
|
|
157
159
|
}
|
|
158
160
|
.malto-header-meta {
|
|
159
161
|
display: flex; align-items: center; gap: 10px;
|
|
160
162
|
}
|
|
161
163
|
.malto-board-logo {
|
|
162
164
|
width: 28px; height: 28px;
|
|
163
|
-
border-radius:
|
|
164
|
-
background: var(--malto-
|
|
165
|
+
border-radius: 10px;
|
|
166
|
+
background: var(--malto-surface-muted);
|
|
165
167
|
display: flex; align-items: center; justify-content: center;
|
|
166
168
|
color: var(--malto-primary);
|
|
167
169
|
font-size: 12px; font-weight: 700;
|
|
@@ -179,7 +181,7 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
179
181
|
transition: background .15s ease, color .15s ease;
|
|
180
182
|
}
|
|
181
183
|
.malto-close:hover {
|
|
182
|
-
background: var(--malto-
|
|
184
|
+
background: var(--malto-surface-muted);
|
|
183
185
|
color: var(--malto-text);
|
|
184
186
|
}
|
|
185
187
|
|
|
@@ -187,8 +189,8 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
187
189
|
.malto-tabs {
|
|
188
190
|
display: flex;
|
|
189
191
|
padding: 4px;
|
|
190
|
-
margin: 0
|
|
191
|
-
background: var(--malto-
|
|
192
|
+
margin: 0 24px 16px;
|
|
193
|
+
background: var(--malto-surface-muted);
|
|
192
194
|
border-radius: var(--malto-radius-sm);
|
|
193
195
|
flex: none;
|
|
194
196
|
}
|
|
@@ -214,7 +216,7 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
214
216
|
.malto-body {
|
|
215
217
|
flex: 1;
|
|
216
218
|
overflow-y: auto;
|
|
217
|
-
padding: 4px
|
|
219
|
+
padding: 4px 24px 22px;
|
|
218
220
|
background: var(--malto-surface);
|
|
219
221
|
scroll-behavior: smooth;
|
|
220
222
|
}
|
|
@@ -229,7 +231,7 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
229
231
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Feedback row \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
230
232
|
.malto-item {
|
|
231
233
|
display: flex; gap: 12px;
|
|
232
|
-
padding:
|
|
234
|
+
padding: 14px;
|
|
233
235
|
border-radius: 12px;
|
|
234
236
|
background: var(--malto-surface);
|
|
235
237
|
border: 1px solid var(--malto-border);
|
|
@@ -240,15 +242,15 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
240
242
|
.malto-item:hover {
|
|
241
243
|
border-color: var(--malto-border-strong);
|
|
242
244
|
transform: translateY(-1px);
|
|
243
|
-
box-shadow:
|
|
245
|
+
box-shadow: 0 6px 16px -8px rgba(25, 24, 56, 0.12);
|
|
244
246
|
}
|
|
245
247
|
.malto-vote {
|
|
246
248
|
display: flex; flex-direction: column;
|
|
247
249
|
align-items: center; justify-content: center;
|
|
248
250
|
min-width: 44px; padding: 6px 4px;
|
|
249
|
-
border-radius:
|
|
251
|
+
border-radius: 12px;
|
|
250
252
|
border: 1px solid var(--malto-border);
|
|
251
|
-
background: var(--malto-surface
|
|
253
|
+
background: var(--malto-surface);
|
|
252
254
|
cursor: pointer;
|
|
253
255
|
font-size: 11px; color: var(--malto-text-muted);
|
|
254
256
|
transition: all .2s var(--malto-ease-spring);
|
|
@@ -335,10 +337,10 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
335
337
|
}
|
|
336
338
|
.malto-input, .malto-textarea {
|
|
337
339
|
width: 100%;
|
|
338
|
-
padding:
|
|
339
|
-
border: 1px solid var(--malto-border
|
|
340
|
+
padding: 12px 14px;
|
|
341
|
+
border: 1px solid var(--malto-border);
|
|
340
342
|
border-radius: 12px;
|
|
341
|
-
font-size:
|
|
343
|
+
font-size: 14px;
|
|
342
344
|
color: var(--malto-text);
|
|
343
345
|
background: var(--malto-surface);
|
|
344
346
|
outline: none;
|
|
@@ -350,7 +352,7 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
350
352
|
}
|
|
351
353
|
.malto-input:focus, .malto-textarea:focus {
|
|
352
354
|
border-color: var(--malto-primary);
|
|
353
|
-
box-shadow: 0 0 0 4px rgba(var(--malto-primary-rgb), 0.
|
|
355
|
+
box-shadow: 0 0 0 4px rgba(var(--malto-primary-rgb), 0.12);
|
|
354
356
|
}
|
|
355
357
|
.malto-textarea {
|
|
356
358
|
min-height: 110px;
|
|
@@ -358,13 +360,13 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
358
360
|
line-height: 1.5;
|
|
359
361
|
}
|
|
360
362
|
.malto-button {
|
|
361
|
-
padding:
|
|
363
|
+
padding: 12px 20px;
|
|
362
364
|
border-radius: 12px;
|
|
363
365
|
background: var(--malto-primary);
|
|
364
366
|
color: var(--malto-primary-contrast);
|
|
365
367
|
border: none; cursor: pointer;
|
|
366
|
-
font-size:
|
|
367
|
-
letter-spacing: -0.
|
|
368
|
+
font-size: 14px; font-weight: 600;
|
|
369
|
+
letter-spacing: -0.01em;
|
|
368
370
|
box-shadow: var(--malto-shadow-glow);
|
|
369
371
|
transition: transform .2s var(--malto-ease-spring), box-shadow .2s ease, opacity .2s ease;
|
|
370
372
|
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
@@ -373,13 +375,13 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
373
375
|
.malto-button:active { transform: scale(0.97); }
|
|
374
376
|
.malto-button[disabled] { opacity: .5; cursor: not-allowed; transform: none; }
|
|
375
377
|
.malto-secondary {
|
|
376
|
-
padding:
|
|
377
|
-
border-radius:
|
|
378
|
+
padding: 10px 16px;
|
|
379
|
+
border-radius: 12px;
|
|
378
380
|
background: transparent;
|
|
379
381
|
color: var(--malto-text);
|
|
380
|
-
border: 1px solid var(--malto-border
|
|
382
|
+
border: 1px solid var(--malto-border);
|
|
381
383
|
cursor: pointer;
|
|
382
|
-
font-size:
|
|
384
|
+
font-size: 13.5px; font-weight: 500;
|
|
383
385
|
transition: all .2s ease;
|
|
384
386
|
}
|
|
385
387
|
.malto-secondary:hover {
|
|
@@ -472,7 +474,7 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
472
474
|
|
|
473
475
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Releases / changelog \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
474
476
|
.malto-release {
|
|
475
|
-
padding:
|
|
477
|
+
padding: 16px;
|
|
476
478
|
border: 1px solid var(--malto-border);
|
|
477
479
|
border-radius: 12px;
|
|
478
480
|
margin-bottom: 8px;
|
|
@@ -542,10 +544,10 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
542
544
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Footer banner (sign-in CTA) \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
543
545
|
.malto-footer-banner {
|
|
544
546
|
flex: none;
|
|
545
|
-
padding:
|
|
547
|
+
padding: 14px 24px;
|
|
546
548
|
background: var(--malto-surface-muted);
|
|
547
549
|
border-top: 1px solid var(--malto-border);
|
|
548
|
-
font-size:
|
|
550
|
+
font-size: 12.5px;
|
|
549
551
|
color: var(--malto-text-muted);
|
|
550
552
|
display: flex; align-items: center; justify-content: space-between;
|
|
551
553
|
gap: 10px;
|
|
@@ -565,7 +567,7 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
565
567
|
}
|
|
566
568
|
.malto-back:hover {
|
|
567
569
|
color: var(--malto-text);
|
|
568
|
-
background: var(--malto-
|
|
570
|
+
background: var(--malto-surface-muted);
|
|
569
571
|
}
|
|
570
572
|
|
|
571
573
|
/* \u2500\u2500\u2500\u2500\u2500\u2500 Animations \u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
@@ -603,5 +605,5 @@ var Malto=(function(exports){'use strict';var F="https://api.malto.io",h=class{c
|
|
|
603
605
|
--malto-text-muted: #a09cc7;
|
|
604
606
|
--malto-text-subtle: rgba(230, 227, 245, 0.5);
|
|
605
607
|
}
|
|
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,r){return `rgba(${i}, ${t}, ${e}, ${a})`}function V(i,t,e,a){let r=n=>Math.max(0,Math.min(255,Math.round(n+255*a))),o=n=>r(n).toString(16).padStart(2,"0");return `#${o(i)}${o(t)}${o(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://api.malto.io",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 r=document.createElement("div");r.className="malto-root malto-inline",r.style.setProperty("--malto-z",String(this.config.zIndex)),a.appendChild(r),this.container=r,this.state.open=true,this.render();return}if(t==="bubble"){let a=this.buildBubble(),r=q[this.config.position];Object.assign(a.style,r);let o=document.createElement("div");o.className="malto-root",o.style.setProperty("--malto-z",String(this.config.zIndex)),o.appendChild(a),document.body.appendChild(o),this.trigger=o;}else if(t==="trigger"){let a=this.resolveTarget();if(!a){this.config.onError?.(new Error("Malto: trigger target not found"));return}let r=document.createElement("span");r.className="malto-root",r.style.setProperty("--malto-z",String(this.config.zIndex));let o=document.createElement("button");o.className="malto-trigger",o.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>`,o.addEventListener("click",()=>this.open()),r.appendChild(o),a.appendChild(r),this.trigger=r;}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 r=document.createElement("span");r.innerHTML="Sign in to vote, comment, or submit ideas.";let o=document.createElement("button");o.className="malto-link",o.textContent="Sign in",o.addEventListener("click",()=>this.go("auth")),a.appendChild(r),a.appendChild(o),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 r=$(this.board?.board.companyLogoUrl);if(r){let n=document.createElement("img");n.src=r,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 o=document.createElement("h3");if(o.textContent=this.board?.board.boardName??this.board?.board.companyName??"Feedback",e.appendChild(a),e.appendChild(o),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 r=document.createElement("span");r.className="malto-vote-arrow",r.textContent="\u25B2";let o=document.createElement("span");o.className="malto-vote-count",o.textContent=_(t.votes??0),a.appendChild(r),a.appendChild(o),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 r=document.createElement("button");return r.className="malto-button",r.textContent="Submit feedback",r.type="submit",t.appendChild(e),t.appendChild(a),t.appendChild(r),t.addEventListener("submit",async o=>{if(o.preventDefault(),!this.state.email){this.go("auth");return}r.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,r.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 r=document.createElement("input");r.className="malto-input",r.type="email",r.required=true,r.placeholder="you@company.com",r.value=this.state.authEmail;let o=document.createElement("button");return o.className="malto-button",o.type="submit",o.textContent="Send sign-in link",e.appendChild(a),e.appendChild(r),e.appendChild(o),e.addEventListener("submit",async n=>{n.preventDefault(),o.setAttribute("disabled","true");try{await this.client.startMagicLink({email:r.value.trim()}),this.state.authEmail=r.value.trim(),this.state.authStatus="sent",this.render();}catch(s){this.state.error=s.message,o.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 r of ["PLANNED","IN_PROGRESS","COMPLETED"]){let o=this.state.roadmap[r]??[],n=document.createElement("div");n.className="malto-roadmap-col";let s=document.createElement("h5");s.textContent=e[r]??r;let d=document.createElement("span");if(d.className="malto-roadmap-count",d.textContent=String(o.length),s.appendChild(d),n.appendChild(s),o.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 o)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 r=document.createElement("h4");r.textContent=e.title;let o=document.createElement("p");o.textContent=e.body,a.appendChild(r),a.appendChild(o),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 o=document.createElement("h5");if(o.textContent="Comments",o.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(o),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 r=document.createElement("div");r.className="malto-skeleton-row";let o=document.createElement("div");o.className="malto-skeleton",o.style.width="44px",o.style.height="48px",o.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),r.appendChild(o),r.appendChild(n),e.appendChild(r);}return e}emptyState(t,e,a){let r=document.createElement("div");r.className="malto-empty";let o=document.createElement("div");o.className="malto-empty-icon",o.style.fontSize="20px",o.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,r.appendChild(o),r.appendChild(n),r.appendChild(s),r}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"),r={PLANNED:"Planned",IN_PROGRESS:"In progress",COMPLETED:"Done",DECLINED:"Declined",UNDER_REVIEW:"Under review",BACKLOG:"Backlog"};return a.textContent=r[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 r=Math.floor(a/60);if(r<24)return `${r}h`;let o=Math.floor(r/24);if(o<30)return `${o}d`;let n=Math.floor(o/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 rt(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;}
|
|
608
|
+
`}function D(i){let{r:t,g:e,b:a}=j(i);return {rgb:`${t}, ${e}, ${a}`,contrast:U(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 j(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 U(i,t,e){return (.2126*i+.7152*t+.0722*e)/255>.65?"#0f0d23":"#ffffff"}function N(i,t,e,a,r){return `rgba(${i}, ${t}, ${e}, ${a})`}function V(i,t,e,a){let r=n=>Math.max(0,Math.min(255,Math.round(n+255*a))),o=n=>r(n).toString(16).padStart(2,"0");return `#${o(i)}${o(t)}${o(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";z({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 r=document.createElement("div");r.className="malto-root malto-inline",r.style.setProperty("--malto-z",String(this.config.zIndex)),a.appendChild(r),this.container=r,this.state.open=true,this.render();return}if(t==="bubble"){let a=this.buildBubble(),r=q[this.config.position];Object.assign(a.style,r);let o=document.createElement("div");o.className="malto-root",o.style.setProperty("--malto-z",String(this.config.zIndex)),o.appendChild(a),document.body.appendChild(o),this.trigger=o;}else if(t==="trigger"){let a=this.resolveTarget();if(!a){this.config.onError?.(new Error("Malto: trigger target not found"));return}let r=document.createElement("span");r.className="malto-root",r.style.setProperty("--malto-z",String(this.config.zIndex));let o=document.createElement("button");o.className="malto-trigger",o.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>`,o.addEventListener("click",()=>this.open()),r.appendChild(o),a.appendChild(r),this.trigger=r;}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 r=document.createElement("span");r.innerHTML="Sign in to vote, comment, or submit ideas.";let o=document.createElement("button");o.className="malto-link",o.textContent="Sign in",o.addEventListener("click",()=>this.go("auth")),a.appendChild(r),a.appendChild(o),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 r=$(this.board?.board.companyLogoUrl);if(r){let n=document.createElement("img");n.src=r,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 o=document.createElement("h3");if(o.textContent=this.board?.board.boardName??this.board?.board.companyName??"Feedback",e.appendChild(a),e.appendChild(o),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 r=document.createElement("span");r.className="malto-vote-arrow",r.textContent="\u25B2";let o=document.createElement("span");o.className="malto-vote-count",o.textContent=_(t.votes??0),a.appendChild(r),a.appendChild(o),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=R(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 r=document.createElement("button");return r.className="malto-button",r.textContent="Submit feedback",r.type="submit",t.appendChild(e),t.appendChild(a),t.appendChild(r),t.addEventListener("submit",async o=>{if(o.preventDefault(),!this.state.email){this.go("auth");return}r.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,r.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 r=document.createElement("input");r.className="malto-input",r.type="email",r.required=true,r.placeholder="you@company.com",r.value=this.state.authEmail;let o=document.createElement("button");return o.className="malto-button",o.type="submit",o.textContent="Send sign-in link",e.appendChild(a),e.appendChild(r),e.appendChild(o),e.addEventListener("submit",async n=>{n.preventDefault(),o.setAttribute("disabled","true");try{await this.client.startMagicLink({email:r.value.trim()}),this.state.authEmail=r.value.trim(),this.state.authStatus="sent",this.render();}catch(s){this.state.error=s.message,o.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 r of ["PLANNED","IN_PROGRESS","COMPLETED"]){let o=this.state.roadmap[r]??[],n=document.createElement("div");n.className="malto-roadmap-col";let s=document.createElement("h5");s.textContent=e[r]??r;let d=document.createElement("span");if(d.className="malto-roadmap-count",d.textContent=String(o.length),s.appendChild(d),n.appendChild(s),o.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 o)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 r=document.createElement("h4");r.textContent=e.title;let o=document.createElement("p");o.textContent=e.body,a.appendChild(r),a.appendChild(o),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 o=document.createElement("h5");if(o.textContent="Comments",o.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(o),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=R(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 r=document.createElement("div");r.className="malto-skeleton-row";let o=document.createElement("div");o.className="malto-skeleton",o.style.width="44px",o.style.height="48px",o.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),r.appendChild(o),r.appendChild(n),e.appendChild(r);}return e}emptyState(t,e,a){let r=document.createElement("div");r.className="malto-empty";let o=document.createElement("div");o.className="malto-empty-icon",o.style.fontSize="20px",o.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,r.appendChild(o),r.appendChild(n),r.appendChild(s),r}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"),r={PLANNED:"Planned",IN_PROGRESS:"In progress",COMPLETED:"Done",DECLINED:"Declined",UNDER_REVIEW:"Under review",BACKLOG:"Backlog"};return a.textContent=r[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 R(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 r=Math.floor(a/60);if(r<24)return `${r}h`;let o=Math.floor(r/24);if(o<30)return `${o}d`;let n=Math.floor(o/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 rt(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
609
|
exports.MaltoApiError=b;exports.MaltoClient=h;exports.MaltoWidget=v;exports.close=it;exports.destroy=dt;exports.identify=st;exports.init=rt;exports.open=nt;exports.reset=lt;return exports;})({});
|
package/package.json
CHANGED