@feedlog-ai/webcomponents 0.0.27 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +6 -5
  2. package/dist/cjs/feedlog-badge.cjs.entry.js +2 -2
  3. package/dist/cjs/feedlog-button_3.cjs.entry.js +30 -3
  4. package/dist/cjs/feedlog-card.cjs.entry.js +1 -1
  5. package/dist/cjs/feedlog-issues-client.cjs.entry.js +1 -1
  6. package/dist/cjs/feedlog-issues.cjs.entry.js +2 -2
  7. package/dist/cjs/feedlog-toolkit.cjs.js +1 -1
  8. package/dist/cjs/{index-Bk1-M_w_.js → index-CXKBwRlh.js} +663 -7
  9. package/dist/cjs/loader.cjs.js +1 -1
  10. package/dist/collection/components/feedlog-badge/feedlog-badge.css +50 -50
  11. package/dist/collection/components/feedlog-issue/feedlog-issue.css +89 -64
  12. package/dist/collection/components/feedlog-issue/feedlog-issue.js +28 -1
  13. package/dist/collection/components/feedlog-issue/feedlog-issue.stories.js +3 -2
  14. package/dist/collection/components/feedlog-issues/feedlog-issues.css +0 -2
  15. package/dist/collection/components/feedlog-issues/feedlog-issues.stories.js +3 -2
  16. package/dist/components/feedlog-badge.js +1 -1
  17. package/dist/components/feedlog-issue.js +1 -1
  18. package/dist/components/feedlog-issues-client.js +1 -1
  19. package/dist/components/feedlog-issues-list.js +1 -1
  20. package/dist/components/feedlog-issues.js +1 -1
  21. package/dist/components/index.js +1 -1
  22. package/dist/components/{p-GzOCQT_k.js → p-BBbiSGNf.js} +1 -1
  23. package/dist/components/{p-BuX7UXwe.js → p-BRjVS8bz.js} +2 -2
  24. package/dist/components/{p-DMKFbFjj.js → p-CuFKEckF.js} +1 -1
  25. package/dist/components/p-DzATWlAC.js +1 -0
  26. package/dist/esm/feedlog-badge.entry.js +2 -2
  27. package/dist/esm/feedlog-button_3.entry.js +30 -3
  28. package/dist/esm/feedlog-card.entry.js +1 -1
  29. package/dist/esm/feedlog-issues-client.entry.js +1 -1
  30. package/dist/esm/feedlog-issues.entry.js +2 -2
  31. package/dist/esm/feedlog-toolkit.js +2 -2
  32. package/dist/esm/{index-CHawAwGP.js → index-CgNWSmzU.js} +663 -7
  33. package/dist/esm/loader.js +2 -2
  34. package/dist/feedlog-toolkit/feedlog-toolkit.esm.js +1 -1
  35. package/dist/feedlog-toolkit/{p-bc48ec0d.entry.js → p-32663f65.entry.js} +1 -1
  36. package/dist/feedlog-toolkit/p-891c349f.entry.js +3 -0
  37. package/dist/feedlog-toolkit/p-CgNWSmzU.js +2 -0
  38. package/dist/feedlog-toolkit/{p-c974a35e.entry.js → p-c3e9b94b.entry.js} +1 -1
  39. package/dist/feedlog-toolkit/p-da0268a8.entry.js +1 -0
  40. package/dist/feedlog-toolkit/{p-7f8133b3.entry.js → p-f22117ae.entry.js} +1 -1
  41. package/dist/types/components/feedlog-issue/feedlog-issue.d.ts +5 -0
  42. package/hydrate/index.d.ts +287 -0
  43. package/hydrate/index.js +25334 -0
  44. package/hydrate/index.mjs +25324 -0
  45. package/hydrate/package.json +12 -0
  46. package/package.json +10 -3
  47. package/dist/components/p-Chc3XZ5Y.js +0 -1
  48. package/dist/feedlog-toolkit/p-13089dc5.entry.js +0 -1
  49. package/dist/feedlog-toolkit/p-CHawAwGP.js +0 -2
  50. package/dist/feedlog-toolkit/p-f868da29.entry.js +0 -3
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Bk1-M_w_.js');
3
+ var index = require('./index-CXKBwRlh.js');
4
4
 
5
5
  const defineCustomElements = async (win, options) => {
6
6
  if (typeof window === 'undefined') return undefined;
@@ -4,26 +4,42 @@
4
4
  /* Light theme defaults */
5
5
  --feedlog-badge-font-size: 0.75rem;
6
6
  --feedlog-badge-font-weight: 500;
7
- --feedlog-badge-padding-x: 0.5rem;
7
+ --feedlog-badge-padding-x: 0.625rem;
8
8
  --feedlog-badge-padding-y: 0.125rem;
9
- --feedlog-badge-border-radius: calc(0.625rem - 2px);
10
-
11
- /* Default/Enhancement variant colors */
12
- --feedlog-blue-500: oklch(0.623 0.214 259.815);
13
- --feedlog-blue-600: oklch(0.546 0.245 262.881);
14
- --feedlog-blue-700: oklch(0.488 0.243 264.376);
15
-
16
- /* Destructive variant colors */
17
- --feedlog-destructive: #d4183d;
18
- --feedlog-destructive-hover: #b91c1c;
9
+ --feedlog-badge-border-radius: 9999px; /* Pill shape */
10
+
11
+ /* Default/Enhancement variant colors - Soft Blue */
12
+ --feedlog-blue-bg: #eff6ff;
13
+ --feedlog-blue-text: #1e40af;
14
+ --feedlog-blue-bg-hover: #dbeafe;
15
+
16
+ /* Destructive variant colors - Soft Red */
17
+ --feedlog-red-bg: #fef2f2;
18
+ --feedlog-red-text: #991b1b;
19
+ --feedlog-red-bg-hover: #fee2e2;
20
+
21
+ /* Secondary variant - Muted */
22
+ --feedlog-muted-bg: #f1f5f9;
23
+ --feedlog-muted-text: #475569;
24
+ --feedlog-muted-bg-hover: #e2e8f0;
19
25
  }
20
26
 
21
27
  :host(.dark) {
22
28
  /* Dark theme values */
23
- --feedlog-blue-500: oklch(0.623 0.214 259.815);
24
- --feedlog-blue-600: oklch(0.546 0.245 262.881);
25
- --feedlog-destructive: oklch(0.396 0.141 25.723);
26
- --feedlog-destructive-hover: oklch(0.45 0.16 25.723);
29
+ /* Default/Enhancement variant colors - Dark Blue */
30
+ --feedlog-blue-bg: rgba(37, 99, 235, 0.15);
31
+ --feedlog-blue-text: #93c5fd;
32
+ --feedlog-blue-bg-hover: rgba(37, 99, 235, 0.25);
33
+
34
+ /* Destructive variant colors - Dark Red */
35
+ --feedlog-red-bg: rgba(220, 38, 38, 0.15);
36
+ --feedlog-red-text: #fca5a5;
37
+ --feedlog-red-bg-hover: rgba(220, 38, 38, 0.25);
38
+
39
+ /* Secondary variant - Dark Muted */
40
+ --feedlog-muted-bg: oklch(0.32 0.01 260);
41
+ --feedlog-muted-text: oklch(0.8 0.02 260);
42
+ --feedlog-muted-bg-hover: oklch(0.38 0.01 260);
27
43
  }
28
44
 
29
45
  .badge {
@@ -36,63 +52,47 @@
36
52
  padding: var(--feedlog-badge-padding-y) var(--feedlog-badge-padding-x);
37
53
  border-radius: var(--feedlog-badge-border-radius);
38
54
  white-space: nowrap;
39
- transition: background-color 0.15s ease;
55
+ transition: background-color 0.2s ease, color 0.2s ease;
40
56
  font-family: inherit;
57
+ border: 1px solid transparent;
41
58
  }
42
59
 
43
- /* Default variant - uses blue like enhancement */
60
+ /* Default variant - Soft Blue */
44
61
  .badge-default {
45
- background-color: var(--feedlog-blue-600);
46
- color: #ffffff;
62
+ background-color: var(--feedlog-blue-bg);
63
+ color: var(--feedlog-blue-text);
47
64
  }
48
65
 
49
66
  .badge-default:hover {
50
- background-color: var(--feedlog-blue-700);
51
- }
52
-
53
- :host(.dark) .badge-default {
54
- background-color: var(--feedlog-blue-500);
55
- }
56
-
57
- :host(.dark) .badge-default:hover {
58
- background-color: var(--feedlog-blue-600);
67
+ background-color: var(--feedlog-blue-bg-hover);
59
68
  }
60
69
 
61
- /* Enhancement variant - blue styling */
70
+ /* Enhancement variant - Soft Blue */
62
71
  .badge-enhancement {
63
- background-color: var(--feedlog-blue-600);
64
- color: #ffffff;
72
+ background-color: var(--feedlog-blue-bg);
73
+ color: var(--feedlog-blue-text);
65
74
  }
66
75
 
67
76
  .badge-enhancement:hover {
68
- background-color: var(--feedlog-blue-700);
69
- }
70
-
71
- :host(.dark) .badge-enhancement {
72
- background-color: var(--feedlog-blue-500);
73
- }
74
-
75
- :host(.dark) .badge-enhancement:hover {
76
- background-color: var(--feedlog-blue-600);
77
+ background-color: var(--feedlog-blue-bg-hover);
77
78
  }
78
79
 
79
- /* Destructive variant - red/danger styling */
80
+ /* Destructive variant - Soft Red */
80
81
  .badge-destructive {
81
- background-color: var(--feedlog-destructive);
82
- color: #ffffff;
82
+ background-color: var(--feedlog-red-bg);
83
+ color: var(--feedlog-red-text);
83
84
  }
84
85
 
85
86
  .badge-destructive:hover {
86
- background-color: var(--feedlog-destructive-hover);
87
+ background-color: var(--feedlog-red-bg-hover);
87
88
  }
88
89
 
89
- /* Secondary variant - muted styling for status badges */
90
+ /* Secondary variant - Muted styling */
90
91
  .badge-secondary {
91
- background-color: var(--feedlog-muted, #f1f5f9);
92
- color: var(--feedlog-muted-foreground, #64748b);
92
+ background-color: var(--feedlog-muted-bg);
93
+ color: var(--feedlog-muted-text);
93
94
  }
94
95
 
95
- :host(.dark) .badge-secondary {
96
- background-color: var(--feedlog-muted, oklch(0.32 0.01 260));
97
- color: var(--feedlog-muted-foreground, oklch(0.72 0.02 260));
96
+ .badge-secondary:hover {
97
+ background-color: var(--feedlog-muted-bg-hover);
98
98
  }
@@ -23,29 +23,28 @@
23
23
  --feedlog-destructive: #d4183d;
24
24
  --feedlog-blue-400: oklch(0.707 0.165 254.624);
25
25
  --feedlog-blue-600: oklch(0.546 0.245 262.881);
26
- --feedlog-blue-100: oklch(0.932 0.032 255.585);
27
- --feedlog-red-100: #fce7f3;
28
- --feedlog-red-400: #f472b6;
29
26
  --feedlog-red-600: #db2777;
30
27
  --feedlog-radius: 0.625rem;
31
28
  --feedlog-gap: 0.5rem;
32
29
 
33
30
  /* Customization variables */
34
31
  --feedlog-card-padding: 1.25rem;
35
- --feedlog-title-font-size: 0.9375rem;
32
+ --feedlog-title-font-size: 1.125rem;
36
33
  --feedlog-title-font-weight: 600;
37
- --feedlog-body-font-size: 0.8125rem;
38
- --feedlog-body-line-height: 1.5;
34
+ --feedlog-body-font-size: 0.875rem;
35
+ --feedlog-body-line-height: 1.6;
39
36
  --feedlog-timestamp-font-size: 0.6875rem;
40
37
  --feedlog-timestamp-color: var(--feedlog-muted-foreground);
41
- --feedlog-card-accent-width: 3px;
38
+ --feedlog-card-radius: 0.75rem;
42
39
  --feedlog-icon-color: var(--feedlog-muted-foreground);
43
40
  --feedlog-icon-color-muted: var(--feedlog-muted-foreground);
44
41
  --feedlog-pin-color: var(--feedlog-accent-color);
45
42
  --feedlog-upvote-icon-color: var(--feedlog-blue-600);
46
43
  --feedlog-upvote-icon-filled-color: var(--feedlog-red-600);
47
- --feedlog-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.08), 0 1px 2px -1px rgba(0, 0, 0, 0.08);
48
- --feedlog-shadow-hover: 0 4px 12px -2px rgba(0, 0, 0, 0.1), 0 2px 6px -2px rgba(0, 0, 0, 0.08);
44
+ /* Layered shadows for depth */
45
+ --feedlog-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.5);
46
+ --feedlog-shadow-hover-enhancement: 0 8px 16px rgba(37, 99, 235, 0.08), 0 12px 24px rgba(37, 99, 235, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.6);
47
+ --feedlog-shadow-hover-bug: 0 8px 16px rgba(212, 24, 61, 0.08), 0 12px 24px rgba(212, 24, 61, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.6);
49
48
  }
50
49
 
51
50
  :host(.dark) {
@@ -59,20 +58,20 @@
59
58
  --feedlog-border: oklch(0.34 0.01 260);
60
59
  --feedlog-accent-color: #3b82f6;
61
60
  --feedlog-destructive: oklch(0.396 0.141 25.723);
61
+ --feedlog-blue-300: oklch(0.78 0.12 255);
62
62
  --feedlog-blue-400: oklch(0.707 0.165 254.624);
63
63
  --feedlog-blue-600: oklch(0.546 0.245 262.881);
64
- --feedlog-blue-900-30: color-mix(in oklab, oklch(0.379 0.146 265.522) 30%, transparent);
65
- --feedlog-red-900-30: color-mix(in oklab, oklch(0.396 0.141 25.723) 30%, transparent);
66
64
  --feedlog-upvote-icon-color: var(--feedlog-blue-400);
67
65
  --feedlog-upvote-icon-filled-color: var(--feedlog-red-600);
68
- --feedlog-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.3);
69
- --feedlog-shadow-hover: 0 4px 12px -2px rgba(0, 0, 0, 0.4);
66
+ --feedlog-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 4px 12px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.05);
67
+ --feedlog-shadow-hover-enhancement: 0 8px 16px rgba(59, 130, 246, 0.15), 0 12px 24px rgba(59, 130, 246, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.08);
68
+ --feedlog-shadow-hover-bug: 0 8px 16px rgba(220, 38, 38, 0.15), 0 12px 24px rgba(220, 38, 38, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.08);
70
69
  }
71
70
 
72
71
  .issue-card {
73
- background-color: var(--feedlog-card);
72
+ background: linear-gradient(180deg, var(--feedlog-card) 0%, color-mix(in oklab, var(--feedlog-card) 98%, var(--feedlog-muted) 2%) 100%);
74
73
  border: 1px solid var(--feedlog-border);
75
- border-radius: var(--feedlog-radius);
74
+ border-radius: var(--feedlog-card-radius, var(--feedlog-radius));
76
75
  box-shadow: var(--feedlog-shadow);
77
76
  transition:
78
77
  box-shadow 0.2s ease,
@@ -81,49 +80,66 @@
81
80
  overflow: hidden;
82
81
  }
83
82
 
84
- .issue-card::before {
85
- content: '';
86
- position: absolute;
87
- left: 0;
88
- top: 0;
89
- bottom: 0;
90
- width: var(--feedlog-card-accent-width);
91
- background: var(--feedlog-accent-color);
83
+ .issue-card:hover {
92
84
  }
93
85
 
94
- .issue-card.issue-type-bug::before {
95
- background: var(--feedlog-destructive);
86
+ .issue-card.issue-type-enhancement:hover {
87
+ box-shadow: var(--feedlog-shadow-hover-enhancement);
96
88
  }
97
89
 
98
- .issue-card:hover {
99
- box-shadow: var(--feedlog-shadow-hover);
90
+ .issue-card.issue-type-bug:hover {
91
+ box-shadow: var(--feedlog-shadow-hover-bug);
92
+ }
93
+
94
+ /* Media area - ready for future images/videos. Hidden until media support is added. */
95
+ .issue-media {
96
+ display: none;
97
+ aspect-ratio: 16 / 9;
98
+ overflow: hidden;
99
+ border-radius: var(--feedlog-card-radius, var(--feedlog-radius)) var(--feedlog-card-radius, var(--feedlog-radius)) 0 0;
100
+ background-color: var(--feedlog-muted);
101
+ border-bottom: 1px solid var(--feedlog-border);
102
+ }
103
+
104
+ .issue-media.has-media {
105
+ display: block;
106
+ }
107
+
108
+ .issue-media ::slotted(img),
109
+ .issue-media ::slotted(video) {
110
+ width: 100%;
111
+ height: 100%;
112
+ object-fit: cover;
113
+ display: block;
100
114
  }
101
115
 
102
116
  .issue-content {
103
117
  padding: var(--feedlog-card-padding);
104
- padding-left: calc(var(--feedlog-card-padding) + var(--feedlog-card-accent-width));
105
118
  display: flex;
106
119
  flex-direction: column;
107
120
  gap: 0.875rem;
108
121
  }
109
122
 
110
- .issue-header {
123
+ .issue-header-top {
111
124
  display: flex;
112
125
  align-items: flex-start;
113
126
  justify-content: space-between;
114
- gap: 0.75rem;
115
- min-height: 1.5rem;
127
+ gap: 1rem;
128
+ margin-bottom: 0.875rem;
116
129
  }
117
130
 
118
- .issue-header-left {
131
+ .issue-badges {
119
132
  display: flex;
120
133
  align-items: center;
121
134
  gap: 0.375rem;
122
135
  flex-wrap: wrap;
136
+ margin-left: -0.25rem;
123
137
  }
124
138
 
125
- .issue-type-badge {
126
- width: fit-content;
139
+ .issue-meta-right {
140
+ display: flex;
141
+ align-items: center;
142
+ gap: 0.5rem;
127
143
  }
128
144
 
129
145
  .pinned-indicator {
@@ -155,9 +171,23 @@
155
171
 
156
172
  .issue-footer {
157
173
  display: flex;
174
+ flex-direction: row;
158
175
  align-items: center;
159
- justify-content: flex-end;
176
+ justify-content: space-between;
177
+ gap: 0.75rem;
160
178
  margin-top: 0.75rem;
179
+ padding-top: 1rem;
180
+ border-top: 1px solid var(--feedlog-border);
181
+ flex-wrap: wrap;
182
+ }
183
+
184
+ .issue-footer-meta {
185
+ display: flex;
186
+ align-items: center;
187
+ gap: 0.5rem;
188
+ font-size: 0.75rem;
189
+ color: var(--feedlog-muted-foreground);
190
+ flex-wrap: wrap;
161
191
  }
162
192
 
163
193
  .issue-title {
@@ -165,7 +195,8 @@
165
195
  font-size: var(--feedlog-title-font-size);
166
196
  font-weight: var(--feedlog-title-font-weight);
167
197
  margin: 0 0 0.5rem 0;
168
- line-height: 1.4;
198
+ line-height: 1.3;
199
+ letter-spacing: -0.015em;
169
200
  word-break: break-word;
170
201
  }
171
202
 
@@ -186,7 +217,7 @@
186
217
  }
187
218
 
188
219
  .issue-body p {
189
- margin: 0 0 0.5em 0;
220
+ margin: 0 0 0.75em 0;
190
221
  }
191
222
 
192
223
  .issue-body p:last-child {
@@ -244,15 +275,6 @@
244
275
  color: var(--feedlog-muted-foreground);
245
276
  }
246
277
 
247
- .issue-repository {
248
- display: flex;
249
- align-items: center;
250
- gap: 0.5rem;
251
- font-size: 0.75rem;
252
- color: var(--feedlog-muted-foreground);
253
- flex-wrap: wrap;
254
- }
255
-
256
278
  .repo-name {
257
279
  font-weight: 500;
258
280
  }
@@ -261,19 +283,20 @@
261
283
  display: inline-flex;
262
284
  align-items: center;
263
285
  gap: 0.25rem;
264
- color: var(--feedlog-accent-color);
286
+ color: var(--feedlog-muted-foreground);
265
287
  text-decoration: none;
266
288
  font-weight: 500;
267
289
  font-size: 0.75rem;
268
- padding: 0.125rem 0.375rem;
269
- border-radius: 0.25rem;
290
+ padding: 0.25rem 0.5rem;
291
+ border-radius: 0.375rem;
270
292
  transition:
271
- background-color 0.15s ease,
272
- color 0.15s ease;
293
+ background-color 0.2s ease,
294
+ color 0.2s ease;
273
295
  }
274
296
 
275
297
  .github-link:hover {
276
- text-decoration: underline;
298
+ color: var(--feedlog-card-foreground);
299
+ background-color: var(--feedlog-muted);
277
300
  }
278
301
 
279
302
  .github-link-icon {
@@ -298,25 +321,27 @@
298
321
  display: inline-flex;
299
322
  flex-direction: row;
300
323
  align-items: center;
301
- border-radius: 0.375rem; /* 6px */
302
- background-color: #ffffff;
324
+ border-radius: 9999px;
325
+ background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
303
326
  border: 1px solid #e2e8f0;
304
327
  cursor: pointer;
305
- transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
328
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
306
329
  flex-shrink: 0;
307
330
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
308
331
  overflow: hidden;
309
- padding: 0.375rem 0.75rem;
332
+ padding: 0.375rem 0.875rem;
310
333
  gap: 0.5rem;
311
334
  font-family: inherit;
312
335
  line-height: 1;
313
336
  }
314
337
 
315
338
  .upvote-button:hover {
316
- background-color: #f8fafc;
339
+ background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%);
317
340
  border-color: #cbd5e1;
318
341
  transform: translateY(-1px);
319
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.04);
342
+ box-shadow:
343
+ 0 4px 6px -1px rgba(0, 0, 0, 0.08),
344
+ 0 2px 4px -2px rgba(0, 0, 0, 0.04);
320
345
  }
321
346
 
322
347
  .upvote-button:active {
@@ -325,12 +350,12 @@
325
350
  }
326
351
 
327
352
  .upvote-button.upvoted {
328
- background-color: #eff6ff;
353
+ background: linear-gradient(180deg, #eff6ff 0%, #e0e7ff 100%);
329
354
  border-color: #bfdbfe;
330
355
  }
331
356
 
332
357
  .upvote-button.upvoted:hover {
333
- background-color: #dbeafe;
358
+ background: linear-gradient(180deg, #dbeafe 0%, #c7d2fe 100%);
334
359
  border-color: #93c5fd;
335
360
  }
336
361
 
@@ -446,22 +471,22 @@
446
471
 
447
472
  /* Dark theme overrides */
448
473
  :host(.dark) .upvote-button {
449
- background-color: var(--feedlog-card);
474
+ background: linear-gradient(180deg, var(--feedlog-card) 0%, color-mix(in oklab, var(--feedlog-card) 95%, var(--feedlog-muted) 5%) 100%);
450
475
  border-color: var(--feedlog-border);
451
476
  }
452
477
 
453
478
  :host(.dark) .upvote-button:hover {
454
- background-color: var(--feedlog-muted);
479
+ background: var(--feedlog-muted);
455
480
  border-color: var(--feedlog-muted-foreground);
456
481
  }
457
482
 
458
483
  :host(.dark) .upvote-button.upvoted {
459
- background-color: rgba(37, 99, 235, 0.15);
484
+ background: linear-gradient(180deg, rgba(37, 99, 235, 0.15) 0%, rgba(37, 99, 235, 0.2) 100%);
460
485
  border-color: rgba(37, 99, 235, 0.3);
461
486
  }
462
487
 
463
488
  :host(.dark) .upvote-button.upvoted:hover {
464
- background-color: rgba(37, 99, 235, 0.25);
489
+ background: linear-gradient(180deg, rgba(37, 99, 235, 0.25) 0%, rgba(37, 99, 235, 0.3) 100%);
465
490
  border-color: rgba(37, 99, 235, 0.4);
466
491
  }
467
492
 
@@ -11,6 +11,9 @@ export class FeedlogIssueComponent {
11
11
  * Theme variant: 'light' or 'dark'
12
12
  */
13
13
  this.theme = 'light';
14
+ this.handleMediaSlotChange = () => {
15
+ this.updateMediaVisibility();
16
+ };
14
17
  this.handleUpvote = (event) => {
15
18
  event.stopPropagation();
16
19
  this.feedlogUpvote.emit({
@@ -20,6 +23,29 @@ export class FeedlogIssueComponent {
20
23
  });
21
24
  };
22
25
  }
26
+ componentDidLoad() {
27
+ var _a;
28
+ const mediaSlot = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot[name="media"]');
29
+ if (mediaSlot) {
30
+ mediaSlot.addEventListener('slotchange', this.handleMediaSlotChange);
31
+ this.updateMediaVisibility();
32
+ }
33
+ }
34
+ disconnectedCallback() {
35
+ var _a;
36
+ const mediaSlot = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot[name="media"]');
37
+ if (mediaSlot) {
38
+ mediaSlot.removeEventListener('slotchange', this.handleMediaSlotChange);
39
+ }
40
+ }
41
+ updateMediaVisibility() {
42
+ var _a;
43
+ const mediaEl = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.issue-media');
44
+ if (!mediaEl)
45
+ return;
46
+ const slot = this.host.querySelector('[slot="media"]');
47
+ mediaEl.classList.toggle('has-media', !!slot);
48
+ }
23
49
  /**
24
50
  * Renders the pin icon SVG (Lucide/Feather style)
25
51
  */
@@ -104,7 +130,7 @@ export class FeedlogIssueComponent {
104
130
  const statusBadgeLabel = this.getStatusBadgeLabel();
105
131
  const githubUrl = (_b = issue.githubIssueLink) !== null && _b !== void 0 ? _b : issueUrl;
106
132
  const showGithubButton = githubUrl != null && githubUrl !== '';
107
- return (h(Host, { class: this.theme === 'dark' ? 'dark' : '', "data-upvoted": issue.hasUpvoted ? 'true' : 'false' }, h("div", { class: `issue-card issue-type-${issue.type}` }, h("div", { class: "issue-content" }, h("div", { class: "issue-header" }, h("div", { class: "issue-header-left" }, h("div", { class: "issue-type-badge" }, issue.type === 'bug' ? (h("feedlog-badge", { variant: "destructive" }, "Bug")) : (h("feedlog-badge", { variant: "enhancement" }, "Enhancement"))), statusBadgeLabel && (h("feedlog-badge", { variant: "secondary" }, statusBadgeLabel)), issue.pinnedAt && (h("div", { class: "pinned-indicator", title: "Pinned issue" }, this.renderPinIcon()))), h("span", { class: "issue-timestamp", title: timestampTitle }, timestampLabel, " ", this.formatDate(timestampDate))), h("div", { class: "issue-main" }, h("h3", { class: "issue-title" }, displayTitle), issue.body != null && issue.body !== '' && (h("div", { class: "issue-body", innerHTML: parseMarkdown(issue.body) })), h("div", { class: "issue-repository" }, repoName != null && (h("span", { class: "repo-name", title: repoTooltip }, repoName)), showGithubButton && (h("a", { part: "github-link", class: "github-link", href: githubUrl, target: "_blank", rel: "noopener noreferrer", title: "View on GitHub" }, this.renderExternalLinkIcon(), h("span", { class: "github-link-text" }, "View on GitHub")))), issue.type !== 'bug' && (h("div", { class: "issue-footer" }, h("button", { part: "upvote-button", class: `upvote-button ${issue.hasUpvoted ? 'upvoted' : ''}`, onClick: (e) => this.handleUpvote(e), title: issue.hasUpvoted ? 'Remove upvote' : 'Upvote this issue' }, h("div", { class: "upvote-action" }, h("slot", { name: "upvote-icon" }, this.renderUpvoteIcon(issue.hasUpvoted)), h("span", { class: "upvote-label" }, "Upvote")), h("div", { class: "reel-container" }, h("span", { class: "upvote-count reel-number", key: issue.upvoteCount }, issue.upvoteCount))))))))));
133
+ return (h(Host, { class: this.theme === 'dark' ? 'dark' : '', "data-upvoted": issue.hasUpvoted ? 'true' : 'false' }, h("div", { class: `issue-card issue-type-${issue.type}` }, h("div", { class: "issue-media", part: "media" }, h("slot", { name: "media" })), h("div", { class: "issue-content" }, h("div", { class: "issue-main" }, h("div", { class: "issue-header-top" }, h("div", { class: "issue-badges" }, issue.type === 'bug' ? (h("feedlog-badge", { variant: "destructive" }, "Bug")) : (h("feedlog-badge", { variant: "enhancement" }, "Enhancement")), statusBadgeLabel && (h("feedlog-badge", { variant: "secondary" }, statusBadgeLabel))), h("div", { class: "issue-meta-right" }, issue.pinnedAt && (h("div", { class: "pinned-indicator", title: "Pinned issue" }, this.renderPinIcon())), h("span", { class: "issue-timestamp", title: timestampTitle }, timestampLabel, " ", this.formatDate(timestampDate)))), h("h3", { class: "issue-title" }, displayTitle), issue.body != null && issue.body !== '' && (h("div", { class: "issue-body", innerHTML: parseMarkdown(issue.body) })), (repoName != null || showGithubButton || issue.type !== 'bug') && (h("div", { class: "issue-footer" }, (repoName != null || showGithubButton) && (h("div", { class: "issue-footer-meta" }, repoName != null && (h("span", { class: "repo-name", title: repoTooltip }, repoName)), showGithubButton && (h("a", { part: "github-link", class: "github-link", href: githubUrl, target: "_blank", rel: "noopener noreferrer", title: "View on GitHub" }, this.renderExternalLinkIcon(), h("span", { class: "github-link-text" }, "View on GitHub"))))), issue.type !== 'bug' && (h("button", { part: "upvote-button", class: `upvote-button ${issue.hasUpvoted ? 'upvoted' : ''}`, onClick: (e) => this.handleUpvote(e), title: issue.hasUpvoted ? 'Remove upvote' : 'Upvote this issue' }, h("div", { class: "upvote-action" }, h("slot", { name: "upvote-icon" }, this.renderUpvoteIcon(issue.hasUpvoted)), h("span", { class: "upvote-label" }, "Upvote")), h("div", { class: "reel-container" }, h("span", { class: "upvote-count reel-number", key: issue.upvoteCount }, issue.upvoteCount)))))))))));
108
134
  }
109
135
  static get is() { return "feedlog-issue"; }
110
136
  static get encapsulation() { return "shadow"; }
@@ -202,4 +228,5 @@ export class FeedlogIssueComponent {
202
228
  }
203
229
  }];
204
230
  }
231
+ static get elementRef() { return "host"; }
205
232
  }
@@ -157,10 +157,11 @@ export const CustomCSSVars = {
157
157
  fontFamily: "'Georgia', 'Times New Roman', serif",
158
158
  /* Card */
159
159
  '--feedlog-card-padding': '1.5rem',
160
- '--feedlog-card-accent-width': '5px',
160
+ '--feedlog-card-radius': '0.875rem',
161
161
  '--feedlog-radius': '0.875rem',
162
162
  '--feedlog-shadow': '0 2px 8px 0 rgba(0, 0, 0, 0.12), 0 1px 3px -1px rgba(0, 0, 0, 0.1)',
163
- '--feedlog-shadow-hover': '0 8px 24px -4px rgba(0, 0, 0, 0.15), 0 4px 8px -2px rgba(0, 0, 0, 0.1)',
163
+ '--feedlog-shadow-hover-enhancement': '0 8px 24px -4px rgba(5, 150, 105, 0.15), 0 4px 8px -2px rgba(5, 150, 105, 0.1)',
164
+ '--feedlog-shadow-hover-bug': '0 8px 24px -4px rgba(220, 38, 38, 0.15), 0 4px 8px -2px rgba(220, 38, 38, 0.1)',
164
165
  /* Typography */
165
166
  '--feedlog-title-font-size': '1.0625rem',
166
167
  '--feedlog-title-font-weight': '700',
@@ -39,8 +39,6 @@
39
39
  --feedlog-destructive: oklch(0.396 0.141 25.723);
40
40
  --feedlog-blue-400: oklch(0.707 0.165 254.624);
41
41
  --feedlog-blue-600: oklch(0.546 0.245 262.881);
42
- --feedlog-blue-900-30: color-mix(in oklab, oklch(0.379 0.146 265.522) 30%, transparent);
43
- --feedlog-red-900-30: color-mix(in oklab, oklch(0.396 0.141 25.723) 30%, transparent);
44
42
  --feedlog-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.3);
45
43
  }
46
44
 
@@ -286,10 +286,11 @@ export const CustomCSSVars = {
286
286
  fontFamily: "'Georgia', 'Times New Roman', serif",
287
287
  /* Card */
288
288
  '--feedlog-card-padding': '1.5rem',
289
- '--feedlog-card-accent-width': '5px',
289
+ '--feedlog-card-radius': '0.875rem',
290
290
  '--feedlog-radius': '0.875rem',
291
291
  '--feedlog-shadow': '0 2px 8px 0 rgba(0, 0, 0, 0.12), 0 1px 3px -1px rgba(0, 0, 0, 0.1)',
292
- '--feedlog-shadow-hover': '0 8px 24px -4px rgba(0, 0, 0, 0.15), 0 4px 8px -2px rgba(0, 0, 0, 0.1)',
292
+ '--feedlog-shadow-hover-enhancement': '0 8px 24px -4px rgba(5, 150, 105, 0.15), 0 4px 8px -2px rgba(5, 150, 105, 0.1)',
293
+ '--feedlog-shadow-hover-bug': '0 8px 24px -4px rgba(220, 38, 38, 0.15), 0 4px 8px -2px rgba(220, 38, 38, 0.1)',
293
294
  /* Typography */
294
295
  '--feedlog-title-font-size': '1.0625rem',
295
296
  '--feedlog-title-font-weight': '700',
@@ -1 +1 @@
1
- import{F as o,d as s}from"./p-Chc3XZ5Y.js";const p=o,r=s;export{p as FeedlogBadge,r as defineCustomElement}
1
+ import{F as o,d as s}from"./p-DzATWlAC.js";const p=o,r=s;export{p as FeedlogBadge,r as defineCustomElement}
@@ -1 +1 @@
1
- import{F as o,d as s}from"./p-BuX7UXwe.js";const p=o,r=s;export{p as FeedlogIssue,r as defineCustomElement}
1
+ import{F as o,d as s}from"./p-BRjVS8bz.js";const p=o,r=s;export{p as FeedlogIssue,r as defineCustomElement}
@@ -1 +1 @@
1
- import{t,p as e,H as s,c as i,h as o}from"./index.js";import{d as r}from"./p-Chc3XZ5Y.js";import{d as n}from"./p-DMdb-G26.js";import{d as h}from"./p-BuX7UXwe.js";import{d as a}from"./p-GzOCQT_k.js";import{d as u}from"./p-DMKFbFjj.js";function l(t){if("string"!=typeof t)return"";let e=t.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"");return e=e.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi,""),e=e.replace(/\s*on\w+\s*=\s*[^\s>]*/gi,""),e=e.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,""),e=e.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi,""),e=e.replace(/<(embed|object)\b[^<]*>/gi,""),e=e.replace(/javascript:/gi,""),e=e.replace(/data:(?!image\/(?:png|jpg|jpeg|gif|webp);)/gi,""),e}class d extends Error{constructor(t,e,s){super(t),this.statusCode=e,this.originalError=s,this.name="FeedlogError",Object.setPrototypeOf(this,d.prototype)}}class c extends d{constructor(t){super(t),this.name="FeedlogValidationError",Object.setPrototypeOf(this,c.prototype)}}class p extends d{constructor(t,e,s){super(t,e,s),this.name="FeedlogNetworkError",Object.setPrototypeOf(this,p.prototype)}}class f extends d{constructor(t="Request timed out"){super(t),this.name="FeedlogTimeoutError",Object.setPrototypeOf(this,f.prototype)}}class g{constructor(t){if(this.config={credentials:"include",...t},this.apiKey=this.config.apiKey,!this.apiKey)throw new c("apiKey is required in FeedlogSDKConfig");this.endpoint=this.config.endpoint||"https://api.feedlog.app",this.timeout=this.config.timeout||3e4,this.endpoint=this.endpoint.replace(/\/$/,"")}async fetchIssues(t={}){try{const e=this.buildIssuesUrl(t),s=await this.fetchWithTimeout(e,{method:"GET",headers:this.getAuthHeaders(),credentials:this.config.credentials||"include"});if(!s.ok)throw new p("Failed to fetch issues: "+s.statusText,s.status);const i=await s.json();return this.validateIssuesResponse(i)}catch(t){if(t instanceof d)throw t;if(t instanceof TypeError&&t.message.includes("fetch"))throw new p("Network error: Unable to reach API",void 0,t);throw new d("Failed to fetch issues: "+(t instanceof Error?t.message:"Unknown error"),void 0,t)}}async toggleUpvote(t){if(!t||"string"!=typeof t)throw new c("Issue ID is required");try{const e=`${this.endpoint}/api/issues/${encodeURIComponent(t)}/upvote`,s=await this.fetchWithTimeout(e,{method:"POST",headers:this.getAuthHeaders(),credentials:this.config.credentials||"include",body:JSON.stringify({})});if(404===s.status)throw new p("Issue not found",404);if(401===s.status)throw new p("Unauthorized",401);if(403===s.status)throw new p("Forbidden: Domain not allowed for this repository",403);if(!s.ok)throw new p("Failed to toggle upvote: "+s.statusText,s.status);const i=await s.json();return this.validateUpvoteResponse(i)}catch(t){if(t instanceof d)throw t;if(t instanceof TypeError&&t.message.includes("fetch"))throw new p("Network error: Unable to reach API",void 0,t);throw new d("Failed to toggle upvote: "+(t instanceof Error?t.message:"Unknown error"),void 0,t)}}buildIssuesUrl(t){const e=new URL(this.endpoint+"/api/issues");if(t.repositoryIds){const s=Array.isArray(t.repositoryIds)?t.repositoryIds:[t.repositoryIds];for(const t of s)e.searchParams.append("repositoryIds",t)}return t.type&&e.searchParams.set("type",t.type),t.sortBy&&e.searchParams.set("sortBy",t.sortBy),t.cursor&&e.searchParams.set("cursor",t.cursor),void 0!==t.limit&&e.searchParams.set("limit",""+t.limit),""+e}getAuthHeaders(){const t={"Content-Type":"application/json"};return this.apiKey&&(t["x-api-key"]=this.apiKey),t}async fetchWithTimeout(t,e){const s=new AbortController,i=setTimeout((()=>s.abort()),this.timeout);try{const o=await fetch(t,{...e,signal:s.signal});return clearTimeout(i),o}catch(t){if(clearTimeout(i),t instanceof Error&&"AbortError"===t.name)throw new f(`Request timed out after ${this.timeout}ms`);throw t}}validateIssuesResponse(t){if(!t||"object"!=typeof t)throw new c("Invalid API response: expected object");const e=t;if(!Array.isArray(e.issues))throw new c("Invalid API response: issues must be an array");if(!e.pagination||"object"!=typeof e.pagination)throw new c("Invalid API response: pagination is required");return{issues:e.issues.map((t=>this.validateIssue(t))),pagination:{cursor:e.pagination.cursor,hasMore:!!e.pagination.hasMore}}}validateIssue(t){if(!t||"object"!=typeof t)throw new c("Invalid issue: expected object");const e=t;if("string"!=typeof e.id)throw new c("Invalid issue: id is required and must be a string");if(!["bug","enhancement"].includes(e.type+""))throw new c('Invalid issue: type must be "bug" or "enhancement"');if(!["open","in_progress","closed"].includes(e.status+""))throw new c('Invalid issue: status must be "open", "in_progress", or "closed"');if(!e.repository||"object"!=typeof e.repository)throw new c("Invalid issue: repository is required");const s=e.repository;if("string"!=typeof s.id)throw new c("Invalid issue: repository must have id");const i=null!==e.githubIssueLink&&"string"==typeof e.githubIssueLink?e.githubIssueLink+"":null,o=e.title,r=null!=o&&""!==o?l(o+""):null,n=e.body,h=null!=n&&""!==n?l(n+""):null,a=s.name,u=null!=a&&""!==a?a+"":null,d=s.description,p=null!=d&&""!==d?l(d+""):null;return{id:e.id+"",githubIssueLink:i,type:e.type||"bug",status:e.status||"open",pinnedAt:e.pinnedAt?e.pinnedAt+"":null,revision:Number(e.revision)||1,title:r,body:h,repository:{id:s.id+"",name:u,description:p},updatedAt:e.updatedAt+""||(new Date).toISOString(),createdAt:e.createdAt+""||(new Date).toISOString(),upvoteCount:Number(e.upvoteCount)||0,hasUpvoted:!!e.hasUpvoted}}validateUpvoteResponse(t){if(!t||"object"!=typeof t)throw new c("Invalid upvote response: expected object");const e=t;if("boolean"!=typeof e.upvoted)throw new c("Invalid upvote response: upvoted must be a boolean");if("number"!=typeof e.upvoteCount)throw new c("Invalid upvote response: upvoteCount must be a number");if("string"!=typeof e.anonymousUserId)throw new c("Invalid upvote response: anonymousUserId must be a string");return{upvoted:e.upvoted,upvoteCount:e.upvoteCount,anonymousUserId:e.anonymousUserId}}getEndpoint(){return this.endpoint}getTimeout(){return this.timeout}}const m=e(class extends s{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.feedlogUpvote=i(this,"feedlogUpvote"),this.feedlogError=i(this,"feedlogError"),this.maxWidth="42rem",this.theme="light",this.issues=[],this.loading=!0,this.error=null,this.cursor=null,this.hasMore=!1,this.isLoadingMore=!1,this.sdk=null,this.fetchRequestId=0,this.isDisconnected=!1,this.upvoteRequestIds=new Map,this.handleUpvote=async t=>{if(!this.sdk||this.isDisconnected)return;const{issueId:e,currentUpvoted:s,currentCount:i}=t.detail,o=(this.upvoteRequestIds.get(e)||0)+1;this.upvoteRequestIds.set(e,o),this.issues=this.issues.map((t=>t.id===e?Object.assign(Object.assign({},t),{hasUpvoted:!s,upvoteCount:s?i-1:i+1}):t));try{const t=await this.sdk.toggleUpvote(e);if(this.isDisconnected||this.upvoteRequestIds.get(e)!==o)return;this.issues=this.issues.map((s=>s.id===e?Object.assign(Object.assign({},s),{hasUpvoted:t.upvoted,upvoteCount:t.upvoteCount}):s)),this.feedlogUpvote.emit({issueId:e,upvoted:t.upvoted,upvoteCount:t.upvoteCount})}catch(t){if(this.isDisconnected||this.upvoteRequestIds.get(e)!==o)return;this.issues=this.issues.map((t=>t.id===e?Object.assign(Object.assign({},t),{hasUpvoted:s,upvoteCount:i}):t)),this.feedlogError.emit({error:t instanceof Error?t.message:"Failed to toggle upvote"})}}}componentWillLoad(){this.previousType=this.type,this.previousLimit=this.limit,this.previousSortBy=this.sortBy,this.initializeSDK(),this.fetchIssues()}disconnectedCallback(){this.isDisconnected=!0,this.fetchRequestId++}componentDidUpdate(){(this.previousType!==this.type||this.previousLimit!==this.limit||this.previousSortBy!==this.sortBy)&&(this.fetchRequestId++,this.cursor=null,this.hasMore=!1,this.issues=[],this.fetchIssues(),this.previousType=this.type,this.previousLimit=this.limit,this.previousSortBy=this.sortBy)}initializeSDK(){try{if(!this.apiKey)throw Error("API key is required for the Feedlog SDK");this.sdk=new g(Object.assign({apiKey:this.apiKey},this.endpoint&&{endpoint:this.endpoint})),this.error=null}catch(t){const e=t instanceof Error?t.message:"Failed to initialize SDK";this.error=e,this.feedlogError.emit({error:e})}}async fetchIssues(){if(!this.sdk)return;const t=this.fetchRequestId;try{this.loading=!0,this.error=null;const e={};this.type&&(e.type=this.type),this.sortBy&&(e.sortBy=this.sortBy),this.limit&&(e.limit=this.limit),this.cursor&&(e.cursor=this.cursor);const s=await this.sdk.fetchIssues(e);if(this.isDisconnected||t!==this.fetchRequestId)return;this.issues=s.issues,this.cursor=s.pagination.cursor,this.hasMore=s.pagination.hasMore}catch(e){if(this.isDisconnected||t!==this.fetchRequestId)return;const s=e instanceof Error?e.message:"Couldn't load updates";this.error=s,this.issues=[],this.feedlogError.emit({error:s,code:null==e?void 0:e.statusCode})}finally{this.isDisconnected||t!==this.fetchRequestId||(this.loading=!1,this.isLoadingMore=!1)}}async loadMore(){if(!this.sdk||!this.hasMore||this.isLoadingMore||this.loading)return;const t=this.fetchRequestId;this.isLoadingMore=!0;try{const e={};this.type&&(e.type=this.type),this.sortBy&&(e.sortBy=this.sortBy),this.limit&&(e.limit=this.limit),this.cursor&&(e.cursor=this.cursor);const s=await this.sdk.fetchIssues(e);if(this.isDisconnected||t!==this.fetchRequestId)return;this.issues=[...this.issues,...s.issues],this.cursor=s.pagination.cursor,this.hasMore=s.pagination.hasMore}catch(e){if(this.isDisconnected||t!==this.fetchRequestId)return;this.feedlogError.emit({error:e instanceof Error?e.message:"Failed to load more issues",code:null==e?void 0:e.statusCode})}finally{this.isDisconnected||t!==this.fetchRequestId||(this.isLoadingMore=!1)}}render(){var t,e;const s=null===(e=null===(t=this.el)||void 0===t?void 0:t.style)||void 0===e?void 0:e.getPropertyValue("--feedlog-background");return o("feedlog-issues",{key:"15ae96d7d7b51964026f873f8b97e10530ed02b4",style:s?{"--feedlog-background":s}:void 0,issues:this.issues,limit:this.limit,maxWidth:this.maxWidth,theme:this.theme,heading:this.heading,subtitle:this.subtitle,emptyStateTitle:this.emptyStateTitle,emptyStateMessage:this.emptyStateMessage,getIssueUrl:this.getIssueUrl,loading:this.loading,error:this.error,hasMore:this.hasMore,isLoadingMore:this.isLoadingMore,onFeedlogUpvote:this.handleUpvote,onFeedlogLoadMore:async()=>this.loadMore()})}get el(){return this}},[1,"feedlog-issues-client",{apiKey:[1,"api-key"],type:[1],limit:[2],sortBy:[1,"sort-by"],endpoint:[1],maxWidth:[1,"max-width"],theme:[1],heading:[1],subtitle:[1],emptyStateTitle:[1,"empty-state-title"],emptyStateMessage:[1,"empty-state-message"],getIssueUrl:[16],issues:[32],loading:[32],error:[32],cursor:[32],hasMore:[32],isLoadingMore:[32]}]);function w(){"undefined"!=typeof customElements&&["feedlog-issues-client","feedlog-badge","feedlog-button","feedlog-issue","feedlog-issues","feedlog-issues-list"].forEach((e=>{switch(e){case"feedlog-issues-client":customElements.get(t(e))||customElements.define(t(e),m);break;case"feedlog-badge":customElements.get(t(e))||r();break;case"feedlog-button":customElements.get(t(e))||n();break;case"feedlog-issue":customElements.get(t(e))||h();break;case"feedlog-issues":customElements.get(t(e))||a();break;case"feedlog-issues-list":customElements.get(t(e))||u()}}))}w();const b=m,y=w;export{b as FeedlogIssuesClient,y as defineCustomElement}
1
+ import{t,p as e,H as s,c as i,h as o}from"./index.js";import{d as r}from"./p-DzATWlAC.js";import{d as n}from"./p-DMdb-G26.js";import{d as h}from"./p-BRjVS8bz.js";import{d as a}from"./p-BBbiSGNf.js";import{d as u}from"./p-CuFKEckF.js";function l(t){if("string"!=typeof t)return"";let e=t.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"");return e=e.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi,""),e=e.replace(/\s*on\w+\s*=\s*[^\s>]*/gi,""),e=e.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,""),e=e.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi,""),e=e.replace(/<(embed|object)\b[^<]*>/gi,""),e=e.replace(/javascript:/gi,""),e=e.replace(/data:(?!image\/(?:png|jpg|jpeg|gif|webp);)/gi,""),e}class d extends Error{constructor(t,e,s){super(t),this.statusCode=e,this.originalError=s,this.name="FeedlogError",Object.setPrototypeOf(this,d.prototype)}}class c extends d{constructor(t){super(t),this.name="FeedlogValidationError",Object.setPrototypeOf(this,c.prototype)}}class p extends d{constructor(t,e,s){super(t,e,s),this.name="FeedlogNetworkError",Object.setPrototypeOf(this,p.prototype)}}class f extends d{constructor(t="Request timed out"){super(t),this.name="FeedlogTimeoutError",Object.setPrototypeOf(this,f.prototype)}}class g{constructor(t){if(this.config={credentials:"include",...t},this.apiKey=this.config.apiKey,!this.apiKey)throw new c("apiKey is required in FeedlogSDKConfig");this.endpoint=this.config.endpoint||"https://api.feedlog.app",this.timeout=this.config.timeout||3e4,this.endpoint=this.endpoint.replace(/\/$/,"")}async fetchIssues(t={}){try{const e=this.buildIssuesUrl(t),s=await this.fetchWithTimeout(e,{method:"GET",headers:this.getAuthHeaders(),credentials:this.config.credentials||"include"});if(!s.ok)throw new p("Failed to fetch issues: "+s.statusText,s.status);const i=await s.json();return this.validateIssuesResponse(i)}catch(t){if(t instanceof d)throw t;if(t instanceof TypeError&&t.message.includes("fetch"))throw new p("Network error: Unable to reach API",void 0,t);throw new d("Failed to fetch issues: "+(t instanceof Error?t.message:"Unknown error"),void 0,t)}}async toggleUpvote(t){if(!t||"string"!=typeof t)throw new c("Issue ID is required");try{const e=`${this.endpoint}/api/issues/${encodeURIComponent(t)}/upvote`,s=await this.fetchWithTimeout(e,{method:"POST",headers:this.getAuthHeaders(),credentials:this.config.credentials||"include",body:JSON.stringify({})});if(404===s.status)throw new p("Issue not found",404);if(401===s.status)throw new p("Unauthorized",401);if(403===s.status)throw new p("Forbidden: Domain not allowed for this repository",403);if(!s.ok)throw new p("Failed to toggle upvote: "+s.statusText,s.status);const i=await s.json();return this.validateUpvoteResponse(i)}catch(t){if(t instanceof d)throw t;if(t instanceof TypeError&&t.message.includes("fetch"))throw new p("Network error: Unable to reach API",void 0,t);throw new d("Failed to toggle upvote: "+(t instanceof Error?t.message:"Unknown error"),void 0,t)}}buildIssuesUrl(t){const e=new URL(this.endpoint+"/api/issues");if(t.repositoryIds){const s=Array.isArray(t.repositoryIds)?t.repositoryIds:[t.repositoryIds];for(const t of s)e.searchParams.append("repositoryIds",t)}return t.type&&e.searchParams.set("type",t.type),t.sortBy&&e.searchParams.set("sortBy",t.sortBy),t.cursor&&e.searchParams.set("cursor",t.cursor),void 0!==t.limit&&e.searchParams.set("limit",""+t.limit),""+e}getAuthHeaders(){const t={"Content-Type":"application/json"};return this.apiKey&&(t["x-api-key"]=this.apiKey),t}async fetchWithTimeout(t,e){const s=new AbortController,i=setTimeout((()=>s.abort()),this.timeout);try{const o=await fetch(t,{...e,signal:s.signal});return clearTimeout(i),o}catch(t){if(clearTimeout(i),t instanceof Error&&"AbortError"===t.name)throw new f(`Request timed out after ${this.timeout}ms`);throw t}}validateIssuesResponse(t){if(!t||"object"!=typeof t)throw new c("Invalid API response: expected object");const e=t;if(!Array.isArray(e.issues))throw new c("Invalid API response: issues must be an array");if(!e.pagination||"object"!=typeof e.pagination)throw new c("Invalid API response: pagination is required");return{issues:e.issues.map((t=>this.validateIssue(t))),pagination:{cursor:e.pagination.cursor,hasMore:!!e.pagination.hasMore}}}validateIssue(t){if(!t||"object"!=typeof t)throw new c("Invalid issue: expected object");const e=t;if("string"!=typeof e.id)throw new c("Invalid issue: id is required and must be a string");if(!["bug","enhancement"].includes(e.type+""))throw new c('Invalid issue: type must be "bug" or "enhancement"');if(!["open","in_progress","closed"].includes(e.status+""))throw new c('Invalid issue: status must be "open", "in_progress", or "closed"');if(!e.repository||"object"!=typeof e.repository)throw new c("Invalid issue: repository is required");const s=e.repository;if("string"!=typeof s.id)throw new c("Invalid issue: repository must have id");const i=null!==e.githubIssueLink&&"string"==typeof e.githubIssueLink?e.githubIssueLink+"":null,o=e.title,r=null!=o&&""!==o?l(o+""):null,n=e.body,h=null!=n&&""!==n?l(n+""):null,a=s.name,u=null!=a&&""!==a?a+"":null,d=s.description,p=null!=d&&""!==d?l(d+""):null;return{id:e.id+"",githubIssueLink:i,type:e.type||"bug",status:e.status||"open",pinnedAt:e.pinnedAt?e.pinnedAt+"":null,revision:Number(e.revision)||1,title:r,body:h,repository:{id:s.id+"",name:u,description:p},updatedAt:e.updatedAt+""||(new Date).toISOString(),createdAt:e.createdAt+""||(new Date).toISOString(),upvoteCount:Number(e.upvoteCount)||0,hasUpvoted:!!e.hasUpvoted}}validateUpvoteResponse(t){if(!t||"object"!=typeof t)throw new c("Invalid upvote response: expected object");const e=t;if("boolean"!=typeof e.upvoted)throw new c("Invalid upvote response: upvoted must be a boolean");if("number"!=typeof e.upvoteCount)throw new c("Invalid upvote response: upvoteCount must be a number");if("string"!=typeof e.anonymousUserId)throw new c("Invalid upvote response: anonymousUserId must be a string");return{upvoted:e.upvoted,upvoteCount:e.upvoteCount,anonymousUserId:e.anonymousUserId}}getEndpoint(){return this.endpoint}getTimeout(){return this.timeout}}const m=e(class extends s{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.feedlogUpvote=i(this,"feedlogUpvote"),this.feedlogError=i(this,"feedlogError"),this.maxWidth="42rem",this.theme="light",this.issues=[],this.loading=!0,this.error=null,this.cursor=null,this.hasMore=!1,this.isLoadingMore=!1,this.sdk=null,this.fetchRequestId=0,this.isDisconnected=!1,this.upvoteRequestIds=new Map,this.handleUpvote=async t=>{if(!this.sdk||this.isDisconnected)return;const{issueId:e,currentUpvoted:s,currentCount:i}=t.detail,o=(this.upvoteRequestIds.get(e)||0)+1;this.upvoteRequestIds.set(e,o),this.issues=this.issues.map((t=>t.id===e?Object.assign(Object.assign({},t),{hasUpvoted:!s,upvoteCount:s?i-1:i+1}):t));try{const t=await this.sdk.toggleUpvote(e);if(this.isDisconnected||this.upvoteRequestIds.get(e)!==o)return;this.issues=this.issues.map((s=>s.id===e?Object.assign(Object.assign({},s),{hasUpvoted:t.upvoted,upvoteCount:t.upvoteCount}):s)),this.feedlogUpvote.emit({issueId:e,upvoted:t.upvoted,upvoteCount:t.upvoteCount})}catch(t){if(this.isDisconnected||this.upvoteRequestIds.get(e)!==o)return;this.issues=this.issues.map((t=>t.id===e?Object.assign(Object.assign({},t),{hasUpvoted:s,upvoteCount:i}):t)),this.feedlogError.emit({error:t instanceof Error?t.message:"Failed to toggle upvote"})}}}componentWillLoad(){this.previousType=this.type,this.previousLimit=this.limit,this.previousSortBy=this.sortBy,this.initializeSDK(),this.fetchIssues()}disconnectedCallback(){this.isDisconnected=!0,this.fetchRequestId++}componentDidUpdate(){(this.previousType!==this.type||this.previousLimit!==this.limit||this.previousSortBy!==this.sortBy)&&(this.fetchRequestId++,this.cursor=null,this.hasMore=!1,this.issues=[],this.fetchIssues(),this.previousType=this.type,this.previousLimit=this.limit,this.previousSortBy=this.sortBy)}initializeSDK(){try{if(!this.apiKey)throw Error("API key is required for the Feedlog SDK");this.sdk=new g(Object.assign({apiKey:this.apiKey},this.endpoint&&{endpoint:this.endpoint})),this.error=null}catch(t){const e=t instanceof Error?t.message:"Failed to initialize SDK";this.error=e,this.feedlogError.emit({error:e})}}async fetchIssues(){if(!this.sdk)return;const t=this.fetchRequestId;try{this.loading=!0,this.error=null;const e={};this.type&&(e.type=this.type),this.sortBy&&(e.sortBy=this.sortBy),this.limit&&(e.limit=this.limit),this.cursor&&(e.cursor=this.cursor);const s=await this.sdk.fetchIssues(e);if(this.isDisconnected||t!==this.fetchRequestId)return;this.issues=s.issues,this.cursor=s.pagination.cursor,this.hasMore=s.pagination.hasMore}catch(e){if(this.isDisconnected||t!==this.fetchRequestId)return;const s=e instanceof Error?e.message:"Couldn't load updates";this.error=s,this.issues=[],this.feedlogError.emit({error:s,code:null==e?void 0:e.statusCode})}finally{this.isDisconnected||t!==this.fetchRequestId||(this.loading=!1,this.isLoadingMore=!1)}}async loadMore(){if(!this.sdk||!this.hasMore||this.isLoadingMore||this.loading)return;const t=this.fetchRequestId;this.isLoadingMore=!0;try{const e={};this.type&&(e.type=this.type),this.sortBy&&(e.sortBy=this.sortBy),this.limit&&(e.limit=this.limit),this.cursor&&(e.cursor=this.cursor);const s=await this.sdk.fetchIssues(e);if(this.isDisconnected||t!==this.fetchRequestId)return;this.issues=[...this.issues,...s.issues],this.cursor=s.pagination.cursor,this.hasMore=s.pagination.hasMore}catch(e){if(this.isDisconnected||t!==this.fetchRequestId)return;this.feedlogError.emit({error:e instanceof Error?e.message:"Failed to load more issues",code:null==e?void 0:e.statusCode})}finally{this.isDisconnected||t!==this.fetchRequestId||(this.isLoadingMore=!1)}}render(){var t,e;const s=null===(e=null===(t=this.el)||void 0===t?void 0:t.style)||void 0===e?void 0:e.getPropertyValue("--feedlog-background");return o("feedlog-issues",{key:"15ae96d7d7b51964026f873f8b97e10530ed02b4",style:s?{"--feedlog-background":s}:void 0,issues:this.issues,limit:this.limit,maxWidth:this.maxWidth,theme:this.theme,heading:this.heading,subtitle:this.subtitle,emptyStateTitle:this.emptyStateTitle,emptyStateMessage:this.emptyStateMessage,getIssueUrl:this.getIssueUrl,loading:this.loading,error:this.error,hasMore:this.hasMore,isLoadingMore:this.isLoadingMore,onFeedlogUpvote:this.handleUpvote,onFeedlogLoadMore:async()=>this.loadMore()})}get el(){return this}},[1,"feedlog-issues-client",{apiKey:[1,"api-key"],type:[1],limit:[2],sortBy:[1,"sort-by"],endpoint:[1],maxWidth:[1,"max-width"],theme:[1],heading:[1],subtitle:[1],emptyStateTitle:[1,"empty-state-title"],emptyStateMessage:[1,"empty-state-message"],getIssueUrl:[16],issues:[32],loading:[32],error:[32],cursor:[32],hasMore:[32],isLoadingMore:[32]}]);function w(){"undefined"!=typeof customElements&&["feedlog-issues-client","feedlog-badge","feedlog-button","feedlog-issue","feedlog-issues","feedlog-issues-list"].forEach((e=>{switch(e){case"feedlog-issues-client":customElements.get(t(e))||customElements.define(t(e),m);break;case"feedlog-badge":customElements.get(t(e))||r();break;case"feedlog-button":customElements.get(t(e))||n();break;case"feedlog-issue":customElements.get(t(e))||h();break;case"feedlog-issues":customElements.get(t(e))||a();break;case"feedlog-issues-list":customElements.get(t(e))||u()}}))}w();const b=m,y=w;export{b as FeedlogIssuesClient,y as defineCustomElement}
@@ -1 +1 @@
1
- import{F as o,d as s}from"./p-DMKFbFjj.js";const j=o,p=s;export{j as FeedlogIssuesList,p as defineCustomElement}
1
+ import{F as o,d as s}from"./p-CuFKEckF.js";const p=o,r=s;export{p as FeedlogIssuesList,r as defineCustomElement}
@@ -1 +1 @@
1
- import{F as o,d as s}from"./p-GzOCQT_k.js";const p=o,r=s;export{p as FeedlogIssues,r as defineCustomElement}
1
+ import{F as o,d as s}from"./p-BBbiSGNf.js";const p=o,r=s;export{p as FeedlogIssues,r as defineCustomElement}