@jamwidgets/astro 0.6.1 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jamwidgets/astro",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Astro components and content loaders for Jamwidgets",
5
5
  "repository": {
6
6
  "type": "git",
@@ -60,7 +60,7 @@
60
60
  ],
61
61
  "license": "MIT",
62
62
  "dependencies": {
63
- "@jamwidgets/core": "^0.5.1"
63
+ "@jamwidgets/core": "^0.5.2"
64
64
  },
65
65
  "peerDependencies": {
66
66
  "astro": "^5.9.0 || ^6.0.0 || ^7.0.0"
@@ -89,6 +89,16 @@ import Theme from "./Theme.astro";
89
89
  }
90
90
  }
91
91
 
92
+ function safeLinkUrl(value?: string): string | null {
93
+ if (!value) return null;
94
+ try {
95
+ const url = new URL(value, window.location.href);
96
+ return url.protocol === "http:" || url.protocol === "https:" ? url.href : null;
97
+ } catch {
98
+ return null;
99
+ }
100
+ }
101
+
92
102
  function renderAnnouncements(announcements: Announcement[]) {
93
103
  container.innerHTML = "";
94
104
 
@@ -97,25 +107,31 @@ import Theme from "./Theme.astro";
97
107
  el.className = `jamwidgets-announcement jamwidgets-announcement-${announcement.announcementType}`;
98
108
  el.dataset.announcementId = announcement.id;
99
109
 
100
- let content = `<span class="jamwidgets-announcement-content">${announcement.content}</span>`;
101
-
102
- if (announcement.linkUrl) {
103
- content += ` <a href="${announcement.linkUrl}" class="jamwidgets-announcement-link">${announcement.linkText || "Learn more"}</a>`;
110
+ const contentEl = document.createElement("span");
111
+ contentEl.className = "jamwidgets-announcement-content";
112
+ contentEl.textContent = announcement.content;
113
+ el.append(contentEl);
114
+
115
+ const linkUrl = safeLinkUrl(announcement.linkUrl);
116
+ if (linkUrl) {
117
+ const link = document.createElement("a");
118
+ link.className = "jamwidgets-announcement-link";
119
+ link.href = linkUrl;
120
+ link.textContent = announcement.linkText || "Learn more";
121
+ el.append(" ", link);
104
122
  }
105
123
 
106
124
  if (announcement.isDismissible) {
107
- content += `
125
+ el.insertAdjacentHTML("beforeend", `
108
126
  <button type="button" class="jamwidgets-announcement-dismiss" aria-label="Dismiss">
109
127
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
110
128
  <line x1="18" y1="6" x2="6" y2="18"></line>
111
129
  <line x1="6" y1="6" x2="18" y2="18"></line>
112
130
  </svg>
113
131
  </button>
114
- `;
132
+ `);
115
133
  }
116
134
 
117
- el.innerHTML = content;
118
-
119
135
  // Handle dismiss
120
136
  const dismissBtn = el.querySelector(".jamwidgets-announcement-dismiss");
121
137
  dismissBtn?.addEventListener("click", async () => {
package/src/Embed.astro CHANGED
@@ -188,11 +188,13 @@ import Theme from "./Theme.astro";
188
188
  const inputType = poll!.settings.multiSelect ? "checkbox" : "radio";
189
189
  optionEl.innerHTML = `
190
190
  <label class="jamwidgets-poll-label ${isSelected ? "jamwidgets-selected" : ""}">
191
- <input type="${inputType}" name="poll-${poll!.id}" value="${option.id}" ${isSelected ? "checked" : ""} />
192
- <span class="jamwidgets-poll-text">${option.text}</span>
191
+ <input type="${inputType}" ${isSelected ? "checked" : ""} />
192
+ <span class="jamwidgets-poll-text"></span>
193
193
  </label>
194
194
  `;
195
195
  const input = optionEl.querySelector("input")!;
196
+ input.name = `poll-${poll!.id}`;
197
+ input.value = option.id;
196
198
  input.addEventListener("change", () => {
197
199
  if (poll!.settings.multiSelect) {
198
200
  if (input.checked) {
@@ -215,7 +217,7 @@ import Theme from "./Theme.astro";
215
217
  optionEl.innerHTML = `
216
218
  <div class="jamwidgets-poll-result ${isSelected ? "jamwidgets-voted" : ""}">
217
219
  <div class="jamwidgets-poll-bar" style="width: ${percent}%"></div>
218
- <span class="jamwidgets-poll-text">${option.text}</span>
220
+ <span class="jamwidgets-poll-text"></span>
219
221
  <span class="jamwidgets-poll-percent">${percent}%</span>
220
222
  </div>
221
223
  `;
@@ -223,10 +225,11 @@ import Theme from "./Theme.astro";
223
225
  // Show without results (voted but results hidden)
224
226
  optionEl.innerHTML = `
225
227
  <div class="jamwidgets-poll-result jamwidgets-no-results ${isSelected ? "jamwidgets-voted" : ""}">
226
- <span class="jamwidgets-poll-text">${option.text}</span>
228
+ <span class="jamwidgets-poll-text"></span>
227
229
  </div>
228
230
  `;
229
231
  }
232
+ optionEl.querySelector(".jamwidgets-poll-text")!.textContent = option.text;
230
233
  optionsEl.appendChild(optionEl);
231
234
  });
232
235
 
package/src/Poll.astro CHANGED
@@ -172,11 +172,13 @@ import Theme from "./Theme.astro";
172
172
  const inputType = poll!.settings.multiSelect ? "checkbox" : "radio";
173
173
  optionEl.innerHTML = `
174
174
  <label class="jamwidgets-poll-label ${isSelected ? "jamwidgets-selected" : ""}">
175
- <input type="${inputType}" name="poll-${poll!.id}" value="${option.id}" ${isSelected ? "checked" : ""} />
176
- <span class="jamwidgets-poll-text">${option.text}</span>
175
+ <input type="${inputType}" ${isSelected ? "checked" : ""} />
176
+ <span class="jamwidgets-poll-text"></span>
177
177
  </label>
178
178
  `;
179
179
  const input = optionEl.querySelector("input")!;
180
+ input.name = `poll-${poll!.id}`;
181
+ input.value = option.id;
180
182
  input.addEventListener("change", () => {
181
183
  if (poll!.settings.multiSelect) {
182
184
  if (input.checked) {
@@ -199,7 +201,7 @@ import Theme from "./Theme.astro";
199
201
  optionEl.innerHTML = `
200
202
  <div class="jamwidgets-poll-result ${isSelected ? "jamwidgets-voted" : ""}">
201
203
  <div class="jamwidgets-poll-bar" style="width: ${percent}%"></div>
202
- <span class="jamwidgets-poll-text">${option.text}</span>
204
+ <span class="jamwidgets-poll-text"></span>
203
205
  <span class="jamwidgets-poll-percent">${percent}%</span>
204
206
  </div>
205
207
  `;
@@ -207,10 +209,11 @@ import Theme from "./Theme.astro";
207
209
  // Show without results (voted but results hidden)
208
210
  optionEl.innerHTML = `
209
211
  <div class="jamwidgets-poll-result jamwidgets-no-results ${isSelected ? "jamwidgets-voted" : ""}">
210
- <span class="jamwidgets-poll-text">${option.text}</span>
212
+ <span class="jamwidgets-poll-text"></span>
211
213
  </div>
212
214
  `;
213
215
  }
216
+ optionEl.querySelector(".jamwidgets-poll-text")!.textContent = option.text;
214
217
  optionsEl.appendChild(optionEl);
215
218
  });
216
219