@feedlog-ai/webcomponents 0.0.20 → 0.0.21

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 (67) hide show
  1. package/README.md +20 -5
  2. package/dist/cjs/feedlog-badge.cjs.entry.js +3 -3
  3. package/dist/cjs/feedlog-button_2.cjs.entry.js +1547 -8
  4. package/dist/cjs/feedlog-card.cjs.entry.js +1 -1
  5. package/dist/cjs/feedlog-github-issues-client.cjs.entry.js +23 -17
  6. package/dist/cjs/feedlog-github-issues.cjs.entry.js +7 -4
  7. package/dist/cjs/feedlog-issues-list.cjs.entry.js +8 -37
  8. package/dist/cjs/feedlog-toolkit.cjs.js +2 -2
  9. package/dist/cjs/{index-5lluu_3h.js → index-DnsqTPII.js} +0 -37
  10. package/dist/cjs/loader.cjs.js +2 -2
  11. package/dist/collection/components/feedlog-badge/feedlog-badge.css +15 -3
  12. package/dist/collection/components/feedlog-badge/feedlog-badge.js +3 -3
  13. package/dist/collection/components/feedlog-github-issues/feedlog-github-issues.css +5 -5
  14. package/dist/collection/components/feedlog-github-issues/feedlog-github-issues.js +28 -2
  15. package/dist/collection/components/feedlog-github-issues/feedlog-github-issues.stories.js +41 -5
  16. package/dist/collection/components/feedlog-github-issues-client/feedlog-github-issues-client.js +24 -1
  17. package/dist/collection/components/feedlog-issue/feedlog-issue.css +196 -46
  18. package/dist/collection/components/feedlog-issue/feedlog-issue.js +71 -6
  19. package/dist/collection/components/feedlog-issue/feedlog-issue.stories.js +115 -3
  20. package/dist/collection/components/feedlog-issues-list/feedlog-issues-list.css +3 -209
  21. package/dist/collection/components/feedlog-issues-list/feedlog-issues-list.js +29 -35
  22. package/dist/collection/utils/markdown.js +48 -0
  23. package/dist/components/feedlog-badge.js +1 -1
  24. package/dist/components/feedlog-github-issues-client.js +1 -1
  25. package/dist/components/feedlog-github-issues.js +1 -1
  26. package/dist/components/feedlog-issue.js +1 -1
  27. package/dist/components/feedlog-issues-list.js +1 -1
  28. package/dist/components/index.js +1 -1
  29. package/dist/components/p-BBPFf6g7.js +3 -0
  30. package/dist/components/p-Chc3XZ5Y.js +1 -0
  31. package/dist/components/p-CyaPkQyN.js +1 -0
  32. package/dist/esm/feedlog-badge.entry.js +3 -3
  33. package/dist/esm/feedlog-button_2.entry.js +1547 -8
  34. package/dist/esm/feedlog-card.entry.js +1 -1
  35. package/dist/esm/feedlog-github-issues-client.entry.js +23 -17
  36. package/dist/esm/feedlog-github-issues.entry.js +7 -4
  37. package/dist/esm/feedlog-issues-list.entry.js +8 -37
  38. package/dist/esm/feedlog-toolkit.js +3 -3
  39. package/dist/esm/{index-CkB6Yzeb.js → index-rs_66Oq4.js} +0 -37
  40. package/dist/esm/loader.js +3 -3
  41. package/dist/feedlog-toolkit/feedlog-toolkit.esm.js +1 -1
  42. package/dist/feedlog-toolkit/p-3154bc80.entry.js +1 -0
  43. package/dist/feedlog-toolkit/{p-cdb2b098.entry.js → p-4e90285c.entry.js} +1 -1
  44. package/dist/feedlog-toolkit/p-5688651c.entry.js +1 -0
  45. package/dist/feedlog-toolkit/p-70bf31c4.entry.js +1 -0
  46. package/dist/feedlog-toolkit/p-da51c7fd.entry.js +1 -0
  47. package/dist/feedlog-toolkit/p-dad7b157.entry.js +3 -0
  48. package/dist/feedlog-toolkit/p-rs_66Oq4.js +2 -0
  49. package/dist/types/components/feedlog-badge/feedlog-badge.d.ts +1 -1
  50. package/dist/types/components/feedlog-github-issues/feedlog-github-issues.d.ts +6 -1
  51. package/dist/types/components/feedlog-github-issues/feedlog-github-issues.stories.d.ts +1 -0
  52. package/dist/types/components/feedlog-github-issues-client/feedlog-github-issues-client.d.ts +6 -1
  53. package/dist/types/components/feedlog-issue/feedlog-issue.d.ts +19 -2
  54. package/dist/types/components/feedlog-issue/feedlog-issue.stories.d.ts +10 -0
  55. package/dist/types/components/feedlog-issues-list/feedlog-issues-list.d.ts +5 -5
  56. package/dist/types/components.d.ts +36 -4
  57. package/dist/types/utils/markdown.d.ts +5 -0
  58. package/package.json +4 -2
  59. package/dist/components/p-Bu_AsIay.js +0 -1
  60. package/dist/components/p-CHtSMTyP.js +0 -1
  61. package/dist/components/p-Cp7B8xwh.js +0 -1
  62. package/dist/feedlog-toolkit/p-2401f510.entry.js +0 -1
  63. package/dist/feedlog-toolkit/p-5df44120.entry.js +0 -1
  64. package/dist/feedlog-toolkit/p-95fea2f4.entry.js +0 -1
  65. package/dist/feedlog-toolkit/p-CkB6Yzeb.js +0 -2
  66. package/dist/feedlog-toolkit/p-b4b631f3.entry.js +0 -1
  67. package/dist/feedlog-toolkit/p-c19a4d1b.entry.js +0 -1
@@ -1,15 +1,24 @@
1
1
  :host {
2
2
  display: block;
3
- font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
4
-
3
+ font-family:
4
+ ui-sans-serif,
5
+ system-ui,
6
+ -apple-system,
7
+ BlinkMacSystemFont,
8
+ 'Segoe UI',
9
+ Roboto,
10
+ 'Helvetica Neue',
11
+ Arial,
12
+ sans-serif;
13
+
5
14
  /* Light theme defaults */
6
15
  --feedlog-background: #ffffff;
7
16
  --feedlog-foreground: oklch(0.145 0 0);
8
17
  --feedlog-card: #ffffff;
9
18
  --feedlog-card-foreground: oklch(0.145 0 0);
10
- --feedlog-muted: #ececf0;
11
- --feedlog-muted-foreground: #717182;
12
- --feedlog-border: rgba(0, 0, 0, 0.1);
19
+ --feedlog-muted: #f1f5f9;
20
+ --feedlog-muted-foreground: #64748b;
21
+ --feedlog-border: rgba(0, 0, 0, 0.08);
13
22
  --feedlog-accent-color: #2563eb;
14
23
  --feedlog-destructive: #d4183d;
15
24
  --feedlog-blue-400: oklch(0.707 0.165 254.624);
@@ -20,50 +29,97 @@
20
29
  --feedlog-red-600: #db2777;
21
30
  --feedlog-radius: 0.625rem;
22
31
  --feedlog-gap: 0.5rem;
32
+
33
+ /* Customization variables */
34
+ --feedlog-card-padding: 1.25rem;
35
+ --feedlog-title-font-size: 0.9375rem;
36
+ --feedlog-title-font-weight: 600;
37
+ --feedlog-body-font-size: 0.8125rem;
38
+ --feedlog-body-line-height: 1.5;
39
+ --feedlog-timestamp-font-size: 0.6875rem;
40
+ --feedlog-timestamp-color: var(--feedlog-muted-foreground);
41
+ --feedlog-card-accent-width: 3px;
42
+ --feedlog-icon-color: var(--feedlog-muted-foreground);
43
+ --feedlog-icon-color-muted: var(--feedlog-muted-foreground);
44
+ --feedlog-pin-color: var(--feedlog-accent-color);
45
+ --feedlog-upvote-icon-color: var(--feedlog-blue-600);
46
+ --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);
23
49
  }
24
50
 
25
51
  :host(.dark) {
26
52
  /* Dark theme values */
27
- --feedlog-background: oklch(0.145 0 0);
53
+ --feedlog-background: oklch(0.18 0.01 260);
28
54
  --feedlog-foreground: oklch(0.985 0 0);
29
- --feedlog-card: oklch(0.145 0 0);
55
+ --feedlog-card: oklch(0.24 0.01 260);
30
56
  --feedlog-card-foreground: oklch(0.985 0 0);
31
- --feedlog-muted: oklch(0.269 0 0);
32
- --feedlog-muted-foreground: oklch(0.708 0 0);
33
- --feedlog-border: oklch(0.269 0 0);
57
+ --feedlog-muted: oklch(0.32 0.01 260);
58
+ --feedlog-muted-foreground: oklch(0.72 0.02 260);
59
+ --feedlog-border: oklch(0.34 0.01 260);
34
60
  --feedlog-accent-color: #3b82f6;
35
61
  --feedlog-destructive: oklch(0.396 0.141 25.723);
36
62
  --feedlog-blue-400: oklch(0.707 0.165 254.624);
37
63
  --feedlog-blue-600: oklch(0.546 0.245 262.881);
38
64
  --feedlog-blue-900-30: color-mix(in oklab, oklch(0.379 0.146 265.522) 30%, transparent);
39
65
  --feedlog-red-900-30: color-mix(in oklab, oklch(0.396 0.141 25.723) 30%, transparent);
66
+ --feedlog-upvote-icon-color: var(--feedlog-blue-400);
67
+ --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);
40
70
  }
41
71
 
42
72
  .issue-card {
43
73
  background-color: var(--feedlog-card);
44
74
  border: 1px solid var(--feedlog-border);
45
75
  border-radius: var(--feedlog-radius);
46
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
47
- transition: box-shadow 0.15s ease;
76
+ box-shadow: var(--feedlog-shadow);
77
+ transition:
78
+ box-shadow 0.2s ease,
79
+ transform 0.2s ease;
48
80
  position: relative;
81
+ overflow: hidden;
82
+ }
83
+
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);
92
+ }
93
+
94
+ .issue-card.issue-type-bug::before {
95
+ background: var(--feedlog-destructive);
49
96
  }
50
97
 
51
98
  .issue-card:hover {
52
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
99
+ box-shadow: var(--feedlog-shadow-hover);
53
100
  }
54
101
 
55
102
  .issue-content {
56
- padding: 1.5rem;
103
+ padding: var(--feedlog-card-padding);
104
+ padding-left: calc(var(--feedlog-card-padding) + var(--feedlog-card-accent-width));
57
105
  display: flex;
58
106
  flex-direction: column;
59
- gap: 1rem;
107
+ gap: 0.875rem;
60
108
  }
61
109
 
62
110
  .issue-header {
63
111
  display: flex;
64
- align-items: center;
65
- gap: 0.5rem;
112
+ align-items: flex-start;
66
113
  justify-content: space-between;
114
+ gap: 0.75rem;
115
+ min-height: 1.5rem;
116
+ }
117
+
118
+ .issue-header-left {
119
+ display: flex;
120
+ align-items: center;
121
+ gap: 0.375rem;
122
+ flex-wrap: wrap;
67
123
  }
68
124
 
69
125
  .issue-type-badge {
@@ -71,8 +127,24 @@
71
127
  }
72
128
 
73
129
  .pinned-indicator {
74
- font-size: 1rem;
75
- opacity: 0.7;
130
+ display: flex;
131
+ align-items: center;
132
+ color: var(--feedlog-pin-color, var(--feedlog-accent-color));
133
+ opacity: 0.9;
134
+ }
135
+
136
+ .pin-icon {
137
+ width: 0.875rem;
138
+ height: 0.875rem;
139
+ color: inherit;
140
+ }
141
+
142
+ .issue-timestamp {
143
+ font-size: var(--feedlog-timestamp-font-size);
144
+ color: var(--feedlog-timestamp-color);
145
+ white-space: nowrap;
146
+ flex-shrink: 0;
147
+ cursor: help;
76
148
  }
77
149
 
78
150
  .issue-main {
@@ -89,20 +161,86 @@
89
161
 
90
162
  .issue-title {
91
163
  color: var(--feedlog-card-foreground);
92
- font-size: 0.875rem;
93
- font-weight: 600;
94
- margin: 0 0 0.375rem 0;
164
+ font-size: var(--feedlog-title-font-size);
165
+ font-weight: var(--feedlog-title-font-weight);
166
+ margin: 0 0 0.5rem 0;
95
167
  line-height: 1.4;
96
168
  word-break: break-word;
97
169
  }
98
170
 
99
171
  .issue-body {
100
172
  color: var(--feedlog-muted-foreground);
101
- font-size: 0.75rem;
102
- line-height: 1.625;
173
+ font-size: var(--feedlog-body-font-size);
174
+ line-height: var(--feedlog-body-line-height);
103
175
  margin: 0 0 0.75rem 0;
104
176
  word-break: break-word;
105
- white-space: pre-wrap;
177
+ }
178
+
179
+ .issue-body :first-child {
180
+ margin-top: 0;
181
+ }
182
+
183
+ .issue-body :last-child {
184
+ margin-bottom: 0;
185
+ }
186
+
187
+ .issue-body p {
188
+ margin: 0 0 0.5em 0;
189
+ }
190
+
191
+ .issue-body p:last-child {
192
+ margin-bottom: 0;
193
+ }
194
+
195
+ .issue-body a {
196
+ color: var(--feedlog-accent-color);
197
+ text-decoration: none;
198
+ }
199
+
200
+ .issue-body a:hover {
201
+ text-decoration: underline;
202
+ }
203
+
204
+ .issue-body code {
205
+ background-color: var(--feedlog-muted);
206
+ padding: 0.125em 0.375em;
207
+ border-radius: 0.25rem;
208
+ font-size: 0.9em;
209
+ }
210
+
211
+ .issue-body pre {
212
+ margin: 0.5em 0;
213
+ padding: 0.75rem;
214
+ background-color: var(--feedlog-muted);
215
+ border-radius: 0.25rem;
216
+ overflow-x: auto;
217
+ font-size: 0.85em;
218
+ }
219
+
220
+ .issue-body pre code {
221
+ background: none;
222
+ padding: 0;
223
+ }
224
+
225
+ .issue-body strong {
226
+ font-weight: 600;
227
+ }
228
+
229
+ .issue-body ul,
230
+ .issue-body ol {
231
+ margin: 0.5em 0;
232
+ padding-left: 1.25em;
233
+ }
234
+
235
+ .issue-body li {
236
+ margin: 0.25em 0;
237
+ }
238
+
239
+ .issue-body blockquote {
240
+ margin: 0.5em 0;
241
+ padding-left: 1em;
242
+ border-left: 3px solid var(--feedlog-muted);
243
+ color: var(--feedlog-muted-foreground);
106
244
  }
107
245
 
108
246
  .issue-repository {
@@ -111,13 +249,41 @@
111
249
  gap: 0.5rem;
112
250
  font-size: 0.75rem;
113
251
  color: var(--feedlog-muted-foreground);
114
- margin-bottom: 0.5rem;
252
+ flex-wrap: wrap;
115
253
  }
116
254
 
117
255
  .repo-name {
118
256
  font-weight: 500;
119
257
  }
120
258
 
259
+ .github-link {
260
+ display: inline-flex;
261
+ align-items: center;
262
+ gap: 0.25rem;
263
+ color: var(--feedlog-accent-color);
264
+ text-decoration: none;
265
+ font-weight: 500;
266
+ font-size: 0.75rem;
267
+ padding: 0.125rem 0.375rem;
268
+ border-radius: 0.25rem;
269
+ transition:
270
+ background-color 0.15s ease,
271
+ color 0.15s ease;
272
+ }
273
+
274
+ .github-link:hover {
275
+ text-decoration: underline;
276
+ }
277
+
278
+ .github-link-icon {
279
+ flex-shrink: 0;
280
+ color: inherit;
281
+ }
282
+
283
+ .github-link-text {
284
+ white-space: nowrap;
285
+ }
286
+
121
287
  .github-number {
122
288
  color: var(--feedlog-blue-600);
123
289
  font-weight: 600;
@@ -137,7 +303,7 @@
137
303
  background-color: var(--feedlog-muted);
138
304
  border: 1px solid transparent;
139
305
  cursor: pointer;
140
- transition: all 0.15s ease;
306
+ transition: all 0.2s ease;
141
307
  flex-shrink: 0;
142
308
  font-size: 0.75rem;
143
309
  font-weight: 600;
@@ -171,19 +337,15 @@
171
337
  .upvote-icon {
172
338
  width: 1rem;
173
339
  height: 1rem;
174
- stroke-width: 2;
340
+ color: inherit;
175
341
  }
176
342
 
177
343
  .upvote-icon.filled {
178
- color: var(--feedlog-red-600);
344
+ color: var(--feedlog-upvote-icon-filled-color);
179
345
  }
180
346
 
181
347
  .upvote-icon.outline {
182
- color: var(--feedlog-blue-600);
183
- }
184
-
185
- :host(.dark) .upvote-icon.outline {
186
- color: var(--feedlog-blue-400);
348
+ color: var(--feedlog-upvote-icon-color);
187
349
  }
188
350
 
189
351
  .upvote-count {
@@ -191,15 +353,3 @@
191
353
  font-weight: 600;
192
354
  color: var(--feedlog-card-foreground);
193
355
  }
194
-
195
- .issue-footer {
196
- display: flex;
197
- flex-direction: column;
198
- gap: 0.25rem;
199
- font-size: 0.75rem;
200
- }
201
-
202
- .issue-date {
203
- color: var(--feedlog-muted-foreground);
204
- cursor: help;
205
- }
@@ -1,4 +1,5 @@
1
1
  import { h, Host } from "@stencil/core";
2
+ import { parseMarkdown } from "../../utils/markdown";
2
3
  /**
3
4
  * Feedlog Issue Component
4
5
  *
@@ -20,13 +21,19 @@ export class FeedlogIssueComponent {
20
21
  };
21
22
  }
22
23
  /**
23
- * Renders the heart icon SVG - filled or outline based on upvote state
24
+ * Renders the pin icon SVG (Lucide/Feather style)
24
25
  */
25
- renderHeartIcon(filled) {
26
+ renderPinIcon() {
27
+ return (h("svg", { class: "pin-icon", xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "M12 17v5" }), h("path", { d: "M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16h1v2a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1v-2h1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z" })));
28
+ }
29
+ /**
30
+ * Renders the upvote (thumbs-up) icon SVG
31
+ */
32
+ renderUpvoteIcon(filled) {
26
33
  if (filled) {
27
- return (h("svg", { class: "upvote-icon filled", xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor" }, h("path", { d: "M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" })));
34
+ return (h("svg", { class: "upvote-icon filled", xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor" }, h("path", { d: "M7 10v12" }), h("path", { d: "M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2h0a3.13 3.13 0 0 1 3 3.88Z" })));
28
35
  }
29
- return (h("svg", { class: "upvote-icon outline", xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" })));
36
+ return (h("svg", { class: "upvote-icon outline", xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "M7 10v12" }), h("path", { d: "M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2h0a3.13 3.13 0 0 1 3 3.88Z" })));
30
37
  }
31
38
  /**
32
39
  * Format an ISO date string to a relative time string
@@ -52,11 +59,50 @@ export class FeedlogIssueComponent {
52
59
  return 'unknown date';
53
60
  }
54
61
  }
55
- render() {
62
+ /**
63
+ * Get the status badge label for closed issues
64
+ */
65
+ getStatusBadgeLabel() {
56
66
  const { issue } = this;
67
+ if (issue.status === 'in_progress')
68
+ return 'In progress';
69
+ if (issue.status === 'closed' && issue.type === 'bug')
70
+ return 'Resolved';
71
+ if (issue.status === 'closed' && issue.type === 'enhancement')
72
+ return 'Implemented';
73
+ return null;
74
+ }
75
+ /**
76
+ * Renders the external link (GitHub) icon SVG
77
+ */
78
+ renderExternalLinkIcon() {
79
+ return (h("svg", { class: "github-link-icon", xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }), h("polyline", { points: "15 3 21 3 21 9" }), h("line", { x1: "10", y1: "14", x2: "21", y2: "3" })));
80
+ }
81
+ render() {
82
+ var _a, _b;
83
+ const { issue, issueUrl } = this;
57
84
  if (!issue)
58
85
  return null;
59
- return (h(Host, { class: this.theme === 'dark' ? 'dark' : '' }, h("div", { class: "issue-card" }, h("div", { class: "issue-content" }, h("div", { class: "issue-header" }, h("div", { class: "issue-type-badge" }, issue.type === 'bug' ? (h("feedlog-badge", { variant: "destructive" }, "Bug")) : (h("feedlog-badge", { variant: "enhancement" }, "Enhancement"))), issue.pinnedAt && (h("div", { class: "pinned-indicator", title: "Pinned issue" }, "\uD83D\uDCCC"))), h("div", { class: "issue-main" }, h("div", { class: "issue-details" }, h("h3", { class: "issue-title" }, issue.title), h("p", { class: "issue-body" }, issue.body), h("div", { class: "issue-repository" }, h("span", { class: "repo-name" }, issue.repository.owner, "/", issue.repository.name))), issue.type !== 'bug' && (h("button", { class: `upvote-button ${issue.hasUpvoted ? 'upvoted' : ''}`, onClick: (e) => this.handleUpvote(e), title: issue.hasUpvoted ? 'Remove upvote' : 'Upvote this issue' }, this.renderHeartIcon(issue.hasUpvoted), h("span", { class: "upvote-count" }, issue.upvoteCount)))), h("div", { class: "issue-footer" }, h("span", { class: "issue-date", title: `Updated: ${issue.updatedAt}` }, "Updated ", this.formatDate(issue.updatedAt)), h("span", { class: "issue-date", title: `Created: ${issue.createdAt}` }, "Created ", this.formatDate(issue.createdAt)))))));
86
+ const wasUpdated = new Date(issue.updatedAt).getTime() > new Date(issue.createdAt).getTime();
87
+ const timestampLabel = wasUpdated ? 'Updated' : 'Created';
88
+ const timestampDate = wasUpdated ? issue.updatedAt : issue.createdAt;
89
+ const timestampTitle = wasUpdated
90
+ ? `Updated: ${issue.updatedAt}`
91
+ : `Created: ${issue.createdAt}`;
92
+ const displayTitle = (_a = issue.title) !== null && _a !== void 0 ? _a : 'Untitled';
93
+ const rawRepoName = issue.repository.name;
94
+ const repoName = rawRepoName != null &&
95
+ rawRepoName !== '' &&
96
+ rawRepoName.toLowerCase() !== 'unnamed repository'
97
+ ? rawRepoName
98
+ : null;
99
+ const repoTooltip = issue.repository.description != null && issue.repository.description !== ''
100
+ ? issue.repository.description
101
+ : undefined;
102
+ const statusBadgeLabel = this.getStatusBadgeLabel();
103
+ const githubUrl = (_b = issue.githubIssueLink) !== null && _b !== void 0 ? _b : issueUrl;
104
+ const showGithubButton = githubUrl != null && githubUrl !== '';
105
+ 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("div", { class: "issue-details" }, 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("button", { part: "upvote-button", class: `upvote-button ${issue.hasUpvoted ? 'upvoted' : ''}`, onClick: (e) => this.handleUpvote(e), title: issue.hasUpvoted ? 'Remove upvote' : 'Upvote this issue' }, h("slot", { name: "upvote-icon" }, this.renderUpvoteIcon(issue.hasUpvoted)), h("span", { class: "upvote-count" }, issue.upvoteCount))))))));
60
106
  }
61
107
  static get is() { return "feedlog-issue"; }
62
108
  static get encapsulation() { return "shadow"; }
@@ -95,6 +141,25 @@ export class FeedlogIssueComponent {
95
141
  "getter": false,
96
142
  "setter": false
97
143
  },
144
+ "issueUrl": {
145
+ "type": "string",
146
+ "mutable": false,
147
+ "complexType": {
148
+ "original": "string | null",
149
+ "resolved": "null | string | undefined",
150
+ "references": {}
151
+ },
152
+ "required": false,
153
+ "optional": true,
154
+ "docs": {
155
+ "tags": [],
156
+ "text": "Optional URL for the GitHub issue. When provided along with githubIssueLink,\nshows a \"View on GitHub\" button. Required because owner is no longer in the API response."
157
+ },
158
+ "getter": false,
159
+ "setter": false,
160
+ "reflect": false,
161
+ "attribute": "issue-url"
162
+ },
98
163
  "theme": {
99
164
  "type": "string",
100
165
  "mutable": false,
@@ -1,6 +1,7 @@
1
1
  import { h } from "@stencil/core";
2
2
  const sampleBugIssue = {
3
3
  id: 'issue-bug-1',
4
+ githubIssueLink: 'https://github.com/feedlog/feedlog-toolkit/issues/42',
4
5
  title: 'Charts not rendering on mobile',
5
6
  body: 'The chart components are not properly responsive on smaller screens. They overflow the container and break the layout.',
6
7
  type: 'bug',
@@ -9,8 +10,8 @@ const sampleBugIssue = {
9
10
  revision: 1,
10
11
  repository: {
11
12
  id: 'repo-1',
12
- name: 'feedlog-toolkit',
13
- owner: 'feedlog',
13
+ name: 'My App',
14
+ description: 'Main application repository',
14
15
  },
15
16
  updatedAt: new Date(Date.now() - 5 * 60 * 60 * 1000).toISOString(), // 5 hours ago
16
17
  createdAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(), // 1 week ago
@@ -19,6 +20,7 @@ const sampleBugIssue = {
19
20
  };
20
21
  const sampleEnhancementIssue = {
21
22
  id: 'issue-enhancement-1',
23
+ githubIssueLink: 'https://github.com/feedlog/feedlog-toolkit/issues/24',
22
24
  title: 'Add dark mode support',
23
25
  body: 'It would be great to have a dark mode option for the dashboard. This would reduce eye strain for users working late at night.',
24
26
  type: 'enhancement',
@@ -28,7 +30,7 @@ const sampleEnhancementIssue = {
28
30
  repository: {
29
31
  id: 'repo-1',
30
32
  name: 'feedlog-toolkit',
31
- owner: 'feedlog',
33
+ description: 'Monorepo for Feedlog Toolkit',
32
34
  },
33
35
  updatedAt: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(), // 2 hours ago
34
36
  createdAt: new Date(Date.now() - 10 * 24 * 60 * 60 * 1000).toISOString(), // 10 days ago
@@ -37,6 +39,32 @@ const sampleEnhancementIssue = {
37
39
  };
38
40
  const sampleUpvotedEnhancementIssue = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-enhancement-upvoted', hasUpvoted: true });
39
41
  const samplePinnedIssue = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-enhancement-pinned', pinnedAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString() });
42
+ const sampleJustCreatedIssue = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-just-created', updatedAt: new Date(Date.now() - 2 * 60 * 1000).toISOString(), createdAt: new Date(Date.now() - 2 * 60 * 1000).toISOString(), upvoteCount: 0 });
43
+ /* --- API Change Stories (2025-02-16) --- */
44
+ const repositoryWithNullName = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-null-repo-name', repository: {
45
+ id: 'repo-2',
46
+ name: null,
47
+ description: 'Repository has no display name set.',
48
+ } });
49
+ const repositoryWithNullDescription = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-null-repo-desc', repository: {
50
+ id: 'repo-3',
51
+ name: 'My Public Repo',
52
+ description: null,
53
+ } });
54
+ const repositoryWithDescription = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-repo-with-desc', repository: {
55
+ id: 'repo-4',
56
+ name: 'Main App',
57
+ description: 'Main application repository - hover over the name to see this.',
58
+ } });
59
+ const issueInProgress = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-in-progress', status: 'in_progress', title: 'Add dark mode support' });
60
+ const issueClosedBug = Object.assign(Object.assign({}, sampleBugIssue), { id: 'issue-closed-bug', status: 'closed', title: 'Login fails on Safari' });
61
+ const issueClosedEnhancement = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-closed-enhancement', status: 'closed', title: 'Export data to CSV' });
62
+ const issueWithGithubLink = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-with-gh', githubIssueLink: 'https://github.com/feedlog/feedlog-toolkit/issues/42', title: 'Add dark mode support' });
63
+ const issueWithGithubLinkNull = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-private-repo', githubIssueLink: null, title: 'Private repo issue', repository: {
64
+ id: 'repo-private',
65
+ name: 'Private Repo',
66
+ description: null,
67
+ } });
40
68
  const meta = {
41
69
  title: 'Components/Issue',
42
70
  component: 'feedlog-issue',
@@ -48,6 +76,10 @@ const meta = {
48
76
  control: 'object',
49
77
  description: 'The issue to display',
50
78
  },
79
+ issueUrl: {
80
+ control: 'text',
81
+ description: 'Optional GitHub issue URL (when githubIssueLink is not available)',
82
+ },
51
83
  theme: {
52
84
  control: 'select',
53
85
  options: ['light', 'dark'],
@@ -111,3 +143,83 @@ export const HighUpvoteCount = {
111
143
  },
112
144
  render: (props) => h("feedlog-issue", Object.assign({}, props)),
113
145
  };
146
+ export const RecentlyCreated = {
147
+ args: {
148
+ issue: sampleJustCreatedIssue,
149
+ },
150
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
151
+ };
152
+ export const CustomCSSVars = {
153
+ args: {
154
+ issue: sampleEnhancementIssue,
155
+ },
156
+ render: (props) => (h("feedlog-issue", Object.assign({}, props, { style: {
157
+ fontFamily: "'Georgia', 'Times New Roman', serif",
158
+ /* Card */
159
+ '--feedlog-card-padding': '1.5rem',
160
+ '--feedlog-card-accent-width': '5px',
161
+ '--feedlog-radius': '0.875rem',
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)',
164
+ /* Typography */
165
+ '--feedlog-title-font-size': '1.0625rem',
166
+ '--feedlog-title-font-weight': '700',
167
+ '--feedlog-body-font-size': '0.875rem',
168
+ '--feedlog-body-line-height': '1.6',
169
+ '--feedlog-timestamp-font-size': '0.75rem',
170
+ /* Colors */
171
+ '--feedlog-accent-color': '#059669',
172
+ '--feedlog-muted': '#ecfdf5',
173
+ '--feedlog-muted-foreground': '#047857',
174
+ '--feedlog-border': 'rgba(5, 150, 105, 0.2)',
175
+ } }))),
176
+ };
177
+ /* --- API Change Stories (2025-02-16) --- */
178
+ export const RepositoryNullName = {
179
+ args: {
180
+ issue: repositoryWithNullName,
181
+ },
182
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
183
+ };
184
+ export const RepositoryNullDescription = {
185
+ args: {
186
+ issue: repositoryWithNullDescription,
187
+ },
188
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
189
+ };
190
+ export const RepositoryWithDescription = {
191
+ args: {
192
+ issue: repositoryWithDescription,
193
+ },
194
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
195
+ };
196
+ export const StatusInProgress = {
197
+ args: {
198
+ issue: issueInProgress,
199
+ },
200
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
201
+ };
202
+ export const StatusClosedBug = {
203
+ args: {
204
+ issue: issueClosedBug,
205
+ },
206
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
207
+ };
208
+ export const StatusClosedEnhancement = {
209
+ args: {
210
+ issue: issueClosedEnhancement,
211
+ },
212
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
213
+ };
214
+ export const WithGithubIssueLink = {
215
+ args: {
216
+ issue: issueWithGithubLink,
217
+ },
218
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
219
+ };
220
+ export const GithubIssueLinkNull = {
221
+ args: {
222
+ issue: issueWithGithubLinkNull,
223
+ },
224
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
225
+ };