@feedlog-ai/webcomponents 0.0.9 → 0.0.11

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 (51) hide show
  1. package/dist/cjs/feedlog-badge.cjs.entry.js +21 -0
  2. package/dist/cjs/feedlog-button_2.cjs.entry.js +101 -0
  3. package/dist/cjs/feedlog-github-issues-client.cjs.entry.js +55 -5
  4. package/dist/cjs/feedlog-github-issues.cjs.entry.js +5 -2
  5. package/dist/cjs/feedlog-issues-list.cjs.entry.js +66 -0
  6. package/dist/cjs/feedlog-toolkit.cjs.js +1 -1
  7. package/dist/cjs/loader.cjs.js +1 -1
  8. package/dist/collection/collection-manifest.json +1 -0
  9. package/dist/collection/components/feedlog-github-issues/feedlog-github-issues.css +36 -1
  10. package/dist/collection/components/feedlog-github-issues/feedlog-github-issues.js +7 -4
  11. package/dist/collection/components/feedlog-github-issues-client/feedlog-github-issues-client.js +55 -5
  12. package/dist/collection/components/feedlog-issue/feedlog-issue.css +205 -0
  13. package/dist/collection/components/feedlog-issue/feedlog-issue.js +137 -0
  14. package/dist/collection/components/feedlog-issue/feedlog-issue.stories.js +113 -0
  15. package/dist/collection/components/feedlog-issues-list/feedlog-issues-list.css +64 -55
  16. package/dist/collection/components/feedlog-issues-list/feedlog-issues-list.js +6 -6
  17. package/dist/collection/components/index.js +1 -0
  18. package/dist/components/feedlog-github-issues-client.js +1 -1
  19. package/dist/components/feedlog-github-issues.js +1 -1
  20. package/dist/components/feedlog-issue.d.ts +11 -0
  21. package/dist/components/feedlog-issue.js +1 -0
  22. package/dist/components/feedlog-issues-list.js +1 -1
  23. package/dist/components/p-5qPAHrMz.js +1 -0
  24. package/dist/components/p-DaNa3wCt.js +1 -0
  25. package/dist/esm/feedlog-badge.entry.js +19 -0
  26. package/dist/esm/feedlog-button_2.entry.js +98 -0
  27. package/dist/esm/feedlog-github-issues-client.entry.js +55 -5
  28. package/dist/esm/feedlog-github-issues.entry.js +5 -2
  29. package/dist/esm/feedlog-issues-list.entry.js +64 -0
  30. package/dist/esm/feedlog-toolkit.js +1 -1
  31. package/dist/esm/loader.js +1 -1
  32. package/dist/feedlog-toolkit/feedlog-toolkit.esm.js +1 -1
  33. package/dist/feedlog-toolkit/p-386ab9fb.entry.js +1 -0
  34. package/dist/feedlog-toolkit/p-5df44120.entry.js +1 -0
  35. package/dist/feedlog-toolkit/{p-964cfcd8.entry.js → p-767ecb94.entry.js} +1 -1
  36. package/dist/feedlog-toolkit/p-95fea2f4.entry.js +1 -0
  37. package/dist/feedlog-toolkit/p-f172074f.entry.js +1 -0
  38. package/dist/types/components/feedlog-github-issues/feedlog-github-issues.d.ts +4 -3
  39. package/dist/types/components/feedlog-github-issues-client/feedlog-github-issues-client.d.ts +9 -2
  40. package/dist/types/components/feedlog-issue/feedlog-issue.d.ts +31 -0
  41. package/dist/types/components/feedlog-issue/feedlog-issue.stories.d.ts +12 -0
  42. package/dist/types/components/feedlog-issues-list/feedlog-issues-list.d.ts +4 -4
  43. package/dist/types/components/index.d.ts +1 -0
  44. package/dist/types/components.d.ts +85 -11
  45. package/package.json +2 -2
  46. package/dist/cjs/feedlog-badge_3.cjs.entry.js +0 -119
  47. package/dist/components/p-C7AZiNqt.js +0 -1
  48. package/dist/components/p-rh0Uv7Ks.js +0 -1
  49. package/dist/esm/feedlog-badge_3.entry.js +0 -115
  50. package/dist/feedlog-toolkit/p-4874f7e8.entry.js +0 -1
  51. package/dist/feedlog-toolkit/p-f16f2491.entry.js +0 -1
@@ -23,16 +23,29 @@ export class FeedlogGithubIssuesClient {
23
23
  this.hasMore = false;
24
24
  this.isLoadingMore = false;
25
25
  this.sdk = null;
26
+ /** Counter to track fetch operations and prevent stale updates */
27
+ this.fetchRequestId = 0;
28
+ /** Flag to prevent state updates after component disconnect */
29
+ this.isDisconnected = false;
30
+ /** Map to track the latest upvote request ID for each issue to handle race conditions */
31
+ this.upvoteRequestIds = new Map();
26
32
  this.handleUpvote = async (event) => {
27
- if (!this.sdk) {
33
+ if (!this.sdk || this.isDisconnected) {
28
34
  return;
29
35
  }
30
36
  const { issueId, currentUpvoted, currentCount } = event.detail;
37
+ // Track request to handle race conditions
38
+ const requestId = (this.upvoteRequestIds.get(issueId) || 0) + 1;
39
+ this.upvoteRequestIds.set(issueId, requestId);
31
40
  // Optimistic update
32
41
  this.issues = this.issues.map(issue => issue.id === issueId
33
42
  ? Object.assign(Object.assign({}, issue), { hasUpvoted: !currentUpvoted, upvoteCount: currentUpvoted ? currentCount - 1 : currentCount + 1 }) : issue);
34
43
  try {
35
44
  const result = await this.sdk.toggleUpvote(issueId);
45
+ // Ignore if component disconnected or request is stale
46
+ if (this.isDisconnected || this.upvoteRequestIds.get(issueId) !== requestId) {
47
+ return;
48
+ }
36
49
  // Update with server response
37
50
  this.issues = this.issues.map(issue => issue.id === issueId
38
51
  ? Object.assign(Object.assign({}, issue), { hasUpvoted: result.upvoted, upvoteCount: result.upvoteCount }) : issue);
@@ -43,6 +56,10 @@ export class FeedlogGithubIssuesClient {
43
56
  });
44
57
  }
45
58
  catch (err) {
59
+ // Ignore if component disconnected or request is stale
60
+ if (this.isDisconnected || this.upvoteRequestIds.get(issueId) !== requestId) {
61
+ return;
62
+ }
46
63
  // Revert optimistic update on error
47
64
  this.issues = this.issues.map(issue => issue.id === issueId
48
65
  ? Object.assign(Object.assign({}, issue), { hasUpvoted: currentUpvoted, upvoteCount: currentCount }) : issue);
@@ -57,11 +74,18 @@ export class FeedlogGithubIssuesClient {
57
74
  this.initializeSDK();
58
75
  this.fetchIssues();
59
76
  }
77
+ disconnectedCallback() {
78
+ // Prevent any pending async operations from updating state
79
+ this.isDisconnected = true;
80
+ this.fetchRequestId++;
81
+ }
60
82
  componentDidUpdate() {
61
83
  // Re-fetch if any props changed
62
84
  const typeChanged = this.previousType !== this.type;
63
85
  const limitChanged = this.previousLimit !== this.limit;
64
86
  if (typeChanged || limitChanged) {
87
+ // Invalidate any in-flight requests
88
+ this.fetchRequestId++;
65
89
  // Reset pagination when filters change
66
90
  this.cursor = null;
67
91
  this.hasMore = false;
@@ -89,6 +113,8 @@ export class FeedlogGithubIssuesClient {
89
113
  if (!this.sdk) {
90
114
  return;
91
115
  }
116
+ // Capture current request ID to detect stale responses
117
+ const currentRequestId = this.fetchRequestId;
92
118
  try {
93
119
  this.loading = true;
94
120
  this.error = null;
@@ -103,11 +129,19 @@ export class FeedlogGithubIssuesClient {
103
129
  params.cursor = this.cursor;
104
130
  }
105
131
  const response = await this.sdk.fetchIssues(params);
132
+ // Ignore response if component disconnected or a newer request was made
133
+ if (this.isDisconnected || currentRequestId !== this.fetchRequestId) {
134
+ return;
135
+ }
106
136
  this.issues = response.issues;
107
137
  this.cursor = response.pagination.cursor;
108
138
  this.hasMore = response.pagination.hasMore;
109
139
  }
110
140
  catch (err) {
141
+ // Ignore errors from stale requests
142
+ if (this.isDisconnected || currentRequestId !== this.fetchRequestId) {
143
+ return;
144
+ }
111
145
  const errorMsg = err instanceof Error ? err.message : 'Failed to fetch issues';
112
146
  this.error = errorMsg;
113
147
  this.issues = [];
@@ -117,14 +151,19 @@ export class FeedlogGithubIssuesClient {
117
151
  });
118
152
  }
119
153
  finally {
120
- this.loading = false;
121
- this.isLoadingMore = false;
154
+ // Only update loading state if this is still the current request
155
+ if (!this.isDisconnected && currentRequestId === this.fetchRequestId) {
156
+ this.loading = false;
157
+ this.isLoadingMore = false;
158
+ }
122
159
  }
123
160
  }
124
161
  async loadMore() {
125
162
  if (!this.sdk || !this.hasMore || this.isLoadingMore || this.loading) {
126
163
  return;
127
164
  }
165
+ // Capture current request ID to detect stale responses
166
+ const currentRequestId = this.fetchRequestId;
128
167
  this.isLoadingMore = true;
129
168
  try {
130
169
  const params = {};
@@ -138,11 +177,19 @@ export class FeedlogGithubIssuesClient {
138
177
  params.cursor = this.cursor;
139
178
  }
140
179
  const response = await this.sdk.fetchIssues(params);
180
+ // Ignore response if component disconnected or a newer request was made
181
+ if (this.isDisconnected || currentRequestId !== this.fetchRequestId) {
182
+ return;
183
+ }
141
184
  this.issues = [...this.issues, ...response.issues];
142
185
  this.cursor = response.pagination.cursor;
143
186
  this.hasMore = response.pagination.hasMore;
144
187
  }
145
188
  catch (err) {
189
+ // Ignore errors from stale requests
190
+ if (this.isDisconnected || currentRequestId !== this.fetchRequestId) {
191
+ return;
192
+ }
146
193
  const errorMsg = err instanceof Error ? err.message : 'Failed to load more issues';
147
194
  this.feedlogError.emit({
148
195
  error: errorMsg,
@@ -150,11 +197,14 @@ export class FeedlogGithubIssuesClient {
150
197
  });
151
198
  }
152
199
  finally {
153
- this.isLoadingMore = false;
200
+ // Only update loading state if this is still the current request
201
+ if (!this.isDisconnected && currentRequestId === this.fetchRequestId) {
202
+ this.isLoadingMore = false;
203
+ }
154
204
  }
155
205
  }
156
206
  render() {
157
- return (h("feedlog-github-issues", { key: 'fe6a4397654075ddef24a3c28b2b1b0c515cfed1', issues: this.issues, maxWidth: this.maxWidth, theme: this.theme, heading: this.heading, subtitle: this.subtitle, loading: this.loading, error: this.error, hasMore: this.hasMore, isLoadingMore: this.isLoadingMore, onFeedlogUpvote: this.handleUpvote, onFeedlogLoadMore: async () => this.loadMore() }));
207
+ return (h("feedlog-github-issues", { key: 'bb63dd29e99dfd9418b6cb12a1f45dff086378ab', issues: this.issues, maxWidth: this.maxWidth, theme: this.theme, heading: this.heading, subtitle: this.subtitle, loading: this.loading, error: this.error, hasMore: this.hasMore, isLoadingMore: this.isLoadingMore, onFeedlogUpvote: this.handleUpvote, onFeedlogLoadMore: async () => this.loadMore() }));
158
208
  }
159
209
  static get is() { return "feedlog-github-issues-client"; }
160
210
  static get encapsulation() { return "shadow"; }
@@ -0,0 +1,205 @@
1
+ :host {
2
+ display: block;
3
+ font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
4
+
5
+ /* Light theme defaults */
6
+ --feedlog-background: #ffffff;
7
+ --feedlog-foreground: oklch(0.145 0 0);
8
+ --feedlog-card: #ffffff;
9
+ --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);
13
+ --feedlog-accent-color: #2563eb;
14
+ --feedlog-destructive: #d4183d;
15
+ --feedlog-blue-400: oklch(0.707 0.165 254.624);
16
+ --feedlog-blue-600: oklch(0.546 0.245 262.881);
17
+ --feedlog-blue-100: oklch(0.932 0.032 255.585);
18
+ --feedlog-red-100: #fce7f3;
19
+ --feedlog-red-400: #f472b6;
20
+ --feedlog-red-600: #db2777;
21
+ --feedlog-radius: 0.625rem;
22
+ --feedlog-gap: 0.5rem;
23
+ }
24
+
25
+ :host(.dark) {
26
+ /* Dark theme values */
27
+ --feedlog-background: oklch(0.145 0 0);
28
+ --feedlog-foreground: oklch(0.985 0 0);
29
+ --feedlog-card: oklch(0.145 0 0);
30
+ --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);
34
+ --feedlog-accent-color: #3b82f6;
35
+ --feedlog-destructive: oklch(0.396 0.141 25.723);
36
+ --feedlog-blue-400: oklch(0.707 0.165 254.624);
37
+ --feedlog-blue-600: oklch(0.546 0.245 262.881);
38
+ --feedlog-blue-900-30: color-mix(in oklab, oklch(0.379 0.146 265.522) 30%, transparent);
39
+ --feedlog-red-900-30: color-mix(in oklab, oklch(0.396 0.141 25.723) 30%, transparent);
40
+ }
41
+
42
+ .issue-card {
43
+ background-color: var(--feedlog-card);
44
+ border: 1px solid var(--feedlog-border);
45
+ 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;
48
+ position: relative;
49
+ }
50
+
51
+ .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);
53
+ }
54
+
55
+ .issue-content {
56
+ padding: 1.5rem;
57
+ display: flex;
58
+ flex-direction: column;
59
+ gap: 1rem;
60
+ }
61
+
62
+ .issue-header {
63
+ display: flex;
64
+ align-items: center;
65
+ gap: 0.5rem;
66
+ justify-content: space-between;
67
+ }
68
+
69
+ .issue-type-badge {
70
+ width: fit-content;
71
+ }
72
+
73
+ .pinned-indicator {
74
+ font-size: 1rem;
75
+ opacity: 0.7;
76
+ }
77
+
78
+ .issue-main {
79
+ display: flex;
80
+ align-items: flex-start;
81
+ justify-content: space-between;
82
+ gap: 1rem;
83
+ }
84
+
85
+ .issue-details {
86
+ flex: 1;
87
+ min-width: 0;
88
+ }
89
+
90
+ .issue-title {
91
+ color: var(--feedlog-card-foreground);
92
+ font-size: 0.875rem;
93
+ font-weight: 600;
94
+ margin: 0 0 0.375rem 0;
95
+ line-height: 1.4;
96
+ word-break: break-word;
97
+ }
98
+
99
+ .issue-body {
100
+ color: var(--feedlog-muted-foreground);
101
+ font-size: 0.75rem;
102
+ line-height: 1.625;
103
+ margin: 0 0 0.75rem 0;
104
+ word-break: break-word;
105
+ white-space: pre-wrap;
106
+ }
107
+
108
+ .issue-repository {
109
+ display: flex;
110
+ align-items: center;
111
+ gap: 0.5rem;
112
+ font-size: 0.75rem;
113
+ color: var(--feedlog-muted-foreground);
114
+ margin-bottom: 0.5rem;
115
+ }
116
+
117
+ .repo-name {
118
+ font-weight: 500;
119
+ }
120
+
121
+ .github-number {
122
+ color: var(--feedlog-blue-600);
123
+ font-weight: 600;
124
+ }
125
+
126
+ :host(.dark) .github-number {
127
+ color: var(--feedlog-blue-400);
128
+ }
129
+
130
+ .upvote-button {
131
+ display: flex;
132
+ flex-direction: column;
133
+ align-items: center;
134
+ gap: 0.125rem;
135
+ padding: 0.5rem 0.75rem;
136
+ border-radius: 0.5rem;
137
+ background-color: var(--feedlog-muted);
138
+ border: 1px solid transparent;
139
+ cursor: pointer;
140
+ transition: all 0.15s ease;
141
+ flex-shrink: 0;
142
+ font-size: 0.75rem;
143
+ font-weight: 600;
144
+ }
145
+
146
+ .upvote-button:hover {
147
+ background-color: var(--feedlog-blue-100);
148
+ border-color: var(--feedlog-blue-400);
149
+ }
150
+
151
+ .upvote-button.upvoted {
152
+ background-color: var(--feedlog-red-100);
153
+ border-color: var(--feedlog-red-400);
154
+ }
155
+
156
+ .upvote-button.upvoted:hover {
157
+ background-color: var(--feedlog-red-100);
158
+ border-color: var(--feedlog-red-600);
159
+ }
160
+
161
+ :host(.dark) .upvote-button:hover {
162
+ background-color: var(--feedlog-blue-900-30);
163
+ border-color: var(--feedlog-blue-600);
164
+ }
165
+
166
+ :host(.dark) .upvote-button.upvoted {
167
+ background-color: var(--feedlog-red-900-30);
168
+ border-color: var(--feedlog-red-600);
169
+ }
170
+
171
+ .upvote-icon {
172
+ width: 1rem;
173
+ height: 1rem;
174
+ stroke-width: 2;
175
+ }
176
+
177
+ .upvote-icon.filled {
178
+ color: var(--feedlog-red-600);
179
+ }
180
+
181
+ .upvote-icon.outline {
182
+ color: var(--feedlog-blue-600);
183
+ }
184
+
185
+ :host(.dark) .upvote-icon.outline {
186
+ color: var(--feedlog-blue-400);
187
+ }
188
+
189
+ .upvote-count {
190
+ font-size: 0.75rem;
191
+ font-weight: 600;
192
+ color: var(--feedlog-card-foreground);
193
+ }
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
+ }
@@ -0,0 +1,137 @@
1
+ import { h, Host } from "@stencil/core";
2
+ /**
3
+ * Heart icon SVG component (filled)
4
+ */
5
+ const HeartFilledIcon = () => (h("svg", { class: "upvote-icon filled", xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", stroke: "none" }, 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" })));
6
+ /**
7
+ * Heart icon SVG component (outline)
8
+ */
9
+ const HeartOutlineIcon = () => (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" })));
10
+ /**
11
+ * Feedlog Issue Component
12
+ *
13
+ * A component for displaying a single GitHub issue.
14
+ */
15
+ export class FeedlogIssueComponent {
16
+ constructor() {
17
+ /**
18
+ * Theme variant: 'light' or 'dark'
19
+ */
20
+ this.theme = 'light';
21
+ this.handleUpvote = (event) => {
22
+ event.stopPropagation();
23
+ this.feedlogUpvote.emit({
24
+ issueId: this.issue.id,
25
+ currentUpvoted: this.issue.hasUpvoted,
26
+ currentCount: this.issue.upvoteCount,
27
+ });
28
+ };
29
+ }
30
+ /**
31
+ * Format an ISO date string to a relative time string
32
+ */
33
+ formatDate(dateString) {
34
+ try {
35
+ const date = new Date(dateString);
36
+ const now = new Date();
37
+ const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
38
+ if (seconds < 60)
39
+ return 'just now';
40
+ if (seconds < 3600)
41
+ return `${Math.floor(seconds / 60)}m ago`;
42
+ if (seconds < 86400)
43
+ return `${Math.floor(seconds / 3600)}h ago`;
44
+ if (seconds < 604800)
45
+ return `${Math.floor(seconds / 86400)}d ago`;
46
+ if (seconds < 2592000)
47
+ return `${Math.floor(seconds / 604800)}w ago`;
48
+ return date.toLocaleDateString();
49
+ }
50
+ catch (_a) {
51
+ return 'unknown date';
52
+ }
53
+ }
54
+ render() {
55
+ const { issue } = this;
56
+ if (!issue)
57
+ return null;
58
+ 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' }, issue.hasUpvoted ? h(HeartFilledIcon, null) : h(HeartOutlineIcon, null), 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)))))));
59
+ }
60
+ static get is() { return "feedlog-issue"; }
61
+ static get encapsulation() { return "shadow"; }
62
+ static get originalStyleUrls() {
63
+ return {
64
+ "$": ["feedlog-issue.css"]
65
+ };
66
+ }
67
+ static get styleUrls() {
68
+ return {
69
+ "$": ["feedlog-issue.css"]
70
+ };
71
+ }
72
+ static get properties() {
73
+ return {
74
+ "issue": {
75
+ "type": "unknown",
76
+ "mutable": false,
77
+ "complexType": {
78
+ "original": "FeedlogIssueType",
79
+ "resolved": "FeedlogIssue",
80
+ "references": {
81
+ "FeedlogIssueType": {
82
+ "location": "import",
83
+ "path": "@feedlog-ai/core",
84
+ "id": "../core/dist/index.d.ts::FeedlogIssue"
85
+ }
86
+ }
87
+ },
88
+ "required": true,
89
+ "optional": false,
90
+ "docs": {
91
+ "tags": [],
92
+ "text": "The issue to display"
93
+ },
94
+ "getter": false,
95
+ "setter": false
96
+ },
97
+ "theme": {
98
+ "type": "string",
99
+ "mutable": false,
100
+ "complexType": {
101
+ "original": "'light' | 'dark'",
102
+ "resolved": "\"dark\" | \"light\"",
103
+ "references": {}
104
+ },
105
+ "required": false,
106
+ "optional": false,
107
+ "docs": {
108
+ "tags": [],
109
+ "text": "Theme variant: 'light' or 'dark'"
110
+ },
111
+ "getter": false,
112
+ "setter": false,
113
+ "reflect": false,
114
+ "attribute": "theme",
115
+ "defaultValue": "'light'"
116
+ }
117
+ };
118
+ }
119
+ static get events() {
120
+ return [{
121
+ "method": "feedlogUpvote",
122
+ "name": "feedlogUpvote",
123
+ "bubbles": true,
124
+ "cancelable": true,
125
+ "composed": true,
126
+ "docs": {
127
+ "tags": [],
128
+ "text": "Event emitted when the issue is upvoted"
129
+ },
130
+ "complexType": {
131
+ "original": "{\n issueId: string;\n currentUpvoted: boolean;\n currentCount: number;\n }",
132
+ "resolved": "{ issueId: string; currentUpvoted: boolean; currentCount: number; }",
133
+ "references": {}
134
+ }
135
+ }];
136
+ }
137
+ }
@@ -0,0 +1,113 @@
1
+ import { h } from "@stencil/core";
2
+ const sampleBugIssue = {
3
+ id: 'issue-bug-1',
4
+ title: 'Charts not rendering on mobile',
5
+ body: 'The chart components are not properly responsive on smaller screens. They overflow the container and break the layout.',
6
+ type: 'bug',
7
+ status: 'open',
8
+ pinnedAt: null,
9
+ revision: 1,
10
+ repository: {
11
+ id: 'repo-1',
12
+ name: 'feedlog-toolkit',
13
+ owner: 'feedlog',
14
+ },
15
+ updatedAt: new Date(Date.now() - 5 * 60 * 60 * 1000).toISOString(), // 5 hours ago
16
+ createdAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(), // 1 week ago
17
+ upvoteCount: 3,
18
+ hasUpvoted: false,
19
+ };
20
+ const sampleEnhancementIssue = {
21
+ id: 'issue-enhancement-1',
22
+ title: 'Add dark mode support',
23
+ 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
+ type: 'enhancement',
25
+ status: 'open',
26
+ pinnedAt: null,
27
+ revision: 1,
28
+ repository: {
29
+ id: 'repo-1',
30
+ name: 'feedlog-toolkit',
31
+ owner: 'feedlog',
32
+ },
33
+ updatedAt: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(), // 2 hours ago
34
+ createdAt: new Date(Date.now() - 10 * 24 * 60 * 60 * 1000).toISOString(), // 10 days ago
35
+ upvoteCount: 24,
36
+ hasUpvoted: false,
37
+ };
38
+ const sampleUpvotedEnhancementIssue = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-enhancement-upvoted', hasUpvoted: true });
39
+ const samplePinnedIssue = Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-enhancement-pinned', pinnedAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString() });
40
+ const meta = {
41
+ title: 'Components/Issue',
42
+ component: 'feedlog-issue',
43
+ parameters: {
44
+ layout: 'centered',
45
+ },
46
+ argTypes: {
47
+ issue: {
48
+ control: 'object',
49
+ description: 'The issue to display',
50
+ },
51
+ theme: {
52
+ control: 'select',
53
+ options: ['light', 'dark'],
54
+ description: 'Theme variant',
55
+ },
56
+ },
57
+ args: {
58
+ issue: sampleEnhancementIssue,
59
+ theme: 'light',
60
+ },
61
+ };
62
+ export default meta;
63
+ export const Default = {
64
+ args: {
65
+ issue: sampleEnhancementIssue,
66
+ },
67
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
68
+ };
69
+ export const Bug = {
70
+ args: {
71
+ issue: sampleBugIssue,
72
+ },
73
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
74
+ };
75
+ export const Upvoted = {
76
+ args: {
77
+ issue: sampleUpvotedEnhancementIssue,
78
+ },
79
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
80
+ };
81
+ export const Pinned = {
82
+ args: {
83
+ issue: samplePinnedIssue,
84
+ },
85
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
86
+ };
87
+ export const DarkTheme = {
88
+ args: {
89
+ issue: sampleEnhancementIssue,
90
+ theme: 'dark',
91
+ },
92
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
93
+ };
94
+ export const DarkThemeBug = {
95
+ args: {
96
+ issue: sampleBugIssue,
97
+ theme: 'dark',
98
+ },
99
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
100
+ };
101
+ export const DarkThemePinned = {
102
+ args: {
103
+ issue: samplePinnedIssue,
104
+ theme: 'dark',
105
+ },
106
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
107
+ };
108
+ export const HighUpvoteCount = {
109
+ args: {
110
+ issue: Object.assign(Object.assign({}, sampleEnhancementIssue), { id: 'issue-high-upvote', upvoteCount: 156 }),
111
+ },
112
+ render: (props) => h("feedlog-issue", Object.assign({}, props)),
113
+ };