@luckydraw/blex 0.1.3 → 0.1.4

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.
@@ -27,12 +27,28 @@ function getWeekStart(date) {
27
27
  d.setDate(d.getDate() - d.getDay());
28
28
  return d;
29
29
  }
30
+ function formatTime(iso) {
31
+ const d = new Date(iso);
32
+ if (isNaN(d.getTime())) return iso;
33
+ const h = d.getHours();
34
+ const m = d.getMinutes();
35
+ const ampm = h >= 12 ? "PM" : "AM";
36
+ const h12 = h % 12 || 12;
37
+ return m === 0 ? `${h12} ${ampm}` : `${h12}:${String(m).padStart(2, "0")} ${ampm}`;
38
+ }
39
+ function formatDateReadable(iso) {
40
+ const d = new Date(iso);
41
+ if (isNaN(d.getTime())) return iso;
42
+ const shortMonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
43
+ return `${shortMonths[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`;
44
+ }
30
45
  var CalendarRenderer = class extends BaseRenderer {
31
46
  constructor() {
32
47
  super(...arguments);
33
48
  this.currentBlock = null;
34
49
  this.viewDate = /* @__PURE__ */ new Date();
35
50
  this.currentView = "month";
51
+ this.activeDetailEl = null;
36
52
  }
37
53
  render(block, container) {
38
54
  this.container = container;
@@ -44,8 +60,59 @@ var CalendarRenderer = class extends BaseRenderer {
44
60
  }
45
61
  revertInteraction(_interaction) {
46
62
  }
63
+ // ---------------------------------------------------------------------------
64
+ // Event detail panel
65
+ // ---------------------------------------------------------------------------
66
+ dismissDetail() {
67
+ if (this.activeDetailEl) {
68
+ this.activeDetailEl.remove();
69
+ this.activeDetailEl = null;
70
+ }
71
+ }
72
+ showDetailPanel(event, _anchor, block) {
73
+ this.dismissDetail();
74
+ const panel = document.createElement("div");
75
+ panel.className = "blex-calendar__detail";
76
+ panel.setAttribute("data-testid", `blex-calendar-detail-${event.id}`);
77
+ const colorBar = document.createElement("div");
78
+ colorBar.className = "blex-calendar__detail-color";
79
+ colorBar.style.backgroundColor = event.color ?? "var(--blex-accent)";
80
+ panel.appendChild(colorBar);
81
+ const content = document.createElement("div");
82
+ content.className = "blex-calendar__detail-content";
83
+ const title = document.createElement("div");
84
+ title.className = "blex-calendar__detail-title";
85
+ title.textContent = event.title;
86
+ content.appendChild(title);
87
+ const time = document.createElement("div");
88
+ time.className = "blex-calendar__detail-time";
89
+ const startDate = formatDateReadable(event.start);
90
+ const startTime = formatTime(event.start);
91
+ const endTime = formatTime(event.end);
92
+ const sameDay = event.start.slice(0, 10) === event.end.slice(0, 10);
93
+ time.textContent = sameDay ? `${startDate}, ${startTime} \u2013 ${endTime}` : `${formatDateReadable(event.start)} ${startTime} \u2013 ${formatDateReadable(event.end)} ${endTime}`;
94
+ content.appendChild(time);
95
+ panel.appendChild(content);
96
+ const dismiss = document.createElement("button");
97
+ dismiss.className = "blex-calendar__detail-dismiss";
98
+ dismiss.setAttribute("data-testid", `blex-calendar-detail-dismiss-${block.id}`);
99
+ dismiss.textContent = "Dismiss";
100
+ this.addListener(dismiss, "click", ((e) => {
101
+ e.stopPropagation();
102
+ this.dismissDetail();
103
+ }));
104
+ panel.appendChild(dismiss);
105
+ const root = this.container?.querySelector(".blex-calendar");
106
+ if (root) {
107
+ root.appendChild(panel);
108
+ } else {
109
+ this.container?.appendChild(panel);
110
+ }
111
+ this.activeDetailEl = panel;
112
+ }
47
113
  update(block) {
48
114
  if (!this.container) return;
115
+ this.activeDetailEl = null;
49
116
  this.currentBlock = block;
50
117
  if (block.data.view) {
51
118
  this.currentView = block.data.view;
@@ -302,6 +369,7 @@ var CalendarRenderer = class extends BaseRenderer {
302
369
  }
303
370
  this.addListener(el, "click", ((e) => {
304
371
  e.stopPropagation();
372
+ this.showDetailPanel(event, el, block);
305
373
  this.emit({
306
374
  blockId: block.id,
307
375
  type: "select",
@@ -328,5 +396,5 @@ function createCalendarRenderer() {
328
396
  }
329
397
 
330
398
  export { CalendarRenderer, createCalendarRenderer };
331
- //# sourceMappingURL=calendar-PNRNENA4.js.map
332
- //# sourceMappingURL=calendar-PNRNENA4.js.map
399
+ //# sourceMappingURL=calendar-DOOC3ERV.js.map
400
+ //# sourceMappingURL=calendar-DOOC3ERV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/renderers/calendar.ts"],"names":[],"mappings":"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","file":"calendar-DOOC3ERV.js","sourcesContent":["import { BaseRenderer } from '../base-renderer.js';\nimport type { ContentBlock, BlockInteraction } from '../types.js';\n\nexport interface CalendarEvent {\n id: string;\n title: string;\n start: string;\n end: string;\n color?: string;\n}\n\nexport type CalendarView = 'month' | 'week' | 'day';\n\nexport interface CalendarData {\n events: CalendarEvent[];\n view?: CalendarView;\n initialDate?: string;\n}\n\nconst DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n\nconst MONTH_NAMES = [\n 'January', 'February', 'March', 'April', 'May', 'June',\n 'July', 'August', 'September', 'October', 'November', 'December',\n];\n\n/** Format a Date as \"YYYY-MM-DD\". */\nfunction formatDate(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n}\n\n/** Return the first day (Sunday) of the week containing date. */\nfunction getWeekStart(date: Date): Date {\n const d = new Date(date);\n d.setDate(d.getDate() - d.getDay());\n return d;\n}\n\n/** Format an ISO datetime string as a readable time like \"2:00 PM\". */\nfunction formatTime(iso: string): string {\n const d = new Date(iso);\n if (isNaN(d.getTime())) return iso;\n const h = d.getHours();\n const m = d.getMinutes();\n const ampm = h >= 12 ? 'PM' : 'AM';\n const h12 = h % 12 || 12;\n return m === 0 ? `${h12} ${ampm}` : `${h12}:${String(m).padStart(2, '0')} ${ampm}`;\n}\n\n/** Format an ISO datetime as a readable date like \"Mar 25, 2026\". */\nfunction formatDateReadable(iso: string): string {\n const d = new Date(iso);\n if (isNaN(d.getTime())) return iso;\n const shortMonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n return `${shortMonths[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`;\n}\n\nexport class CalendarRenderer extends BaseRenderer<CalendarData> {\n private currentBlock: ContentBlock<CalendarData> | null = null;\n private viewDate: Date = new Date();\n private currentView: CalendarView = 'month';\n private activeDetailEl: HTMLElement | null = null;\n\n render(block: ContentBlock<CalendarData>, container: HTMLElement): void {\n this.container = container;\n this.currentBlock = block;\n this.currentView = block.data.view ?? 'month';\n this.viewDate = block.data.initialDate\n ? new Date(block.data.initialDate)\n : new Date();\n this.buildCalendar(block);\n container.setAttribute('data-blex-ready', 'true');\n }\n\n revertInteraction(_interaction: BlockInteraction): void {\n // Calendar interactions (select, slot-click) don't mutate local state,\n // so revert is a no-op on the renderer side. The consumer just removes the chip.\n }\n\n // ---------------------------------------------------------------------------\n // Event detail panel\n // ---------------------------------------------------------------------------\n\n private dismissDetail(): void {\n if (this.activeDetailEl) {\n this.activeDetailEl.remove();\n this.activeDetailEl = null;\n }\n }\n\n private showDetailPanel(event: CalendarEvent, _anchor: HTMLElement, block: ContentBlock<CalendarData>): void {\n this.dismissDetail();\n\n const panel = document.createElement('div');\n panel.className = 'blex-calendar__detail';\n panel.setAttribute('data-testid', `blex-calendar-detail-${event.id}`);\n\n // Color bar\n const colorBar = document.createElement('div');\n colorBar.className = 'blex-calendar__detail-color';\n colorBar.style.backgroundColor = event.color ?? 'var(--blex-accent)';\n panel.appendChild(colorBar);\n\n // Content area\n const content = document.createElement('div');\n content.className = 'blex-calendar__detail-content';\n\n const title = document.createElement('div');\n title.className = 'blex-calendar__detail-title';\n title.textContent = event.title;\n content.appendChild(title);\n\n const time = document.createElement('div');\n time.className = 'blex-calendar__detail-time';\n const startDate = formatDateReadable(event.start);\n const startTime = formatTime(event.start);\n const endTime = formatTime(event.end);\n // Check if same day\n const sameDay = event.start.slice(0, 10) === event.end.slice(0, 10);\n time.textContent = sameDay\n ? `${startDate}, ${startTime} – ${endTime}`\n : `${formatDateReadable(event.start)} ${startTime} – ${formatDateReadable(event.end)} ${endTime}`;\n content.appendChild(time);\n\n panel.appendChild(content);\n\n // Dismiss button\n const dismiss = document.createElement('button');\n dismiss.className = 'blex-calendar__detail-dismiss';\n dismiss.setAttribute('data-testid', `blex-calendar-detail-dismiss-${block.id}`);\n dismiss.textContent = 'Dismiss';\n this.addListener(dismiss, 'click', ((e: MouseEvent) => {\n e.stopPropagation();\n this.dismissDetail();\n }) as EventListener);\n panel.appendChild(dismiss);\n\n // Position: insert after the anchor's parent calendar root\n const root = this.container?.querySelector('.blex-calendar');\n if (root) {\n root.appendChild(panel);\n } else {\n this.container?.appendChild(panel);\n }\n\n this.activeDetailEl = panel;\n }\n\n update(block: ContentBlock<CalendarData>): void {\n if (!this.container) return;\n this.activeDetailEl = null;\n this.currentBlock = block;\n if (block.data.view) {\n this.currentView = block.data.view;\n }\n this.container.innerHTML = '';\n this.buildCalendar(block);\n }\n\n // ---------------------------------------------------------------------------\n // Top-level builder\n // ---------------------------------------------------------------------------\n\n private buildCalendar(block: ContentBlock<CalendarData>): void {\n const container = this.container!;\n\n const root = document.createElement('div');\n root.className = 'blex-calendar';\n root.setAttribute('data-testid', `blex-calendar-${block.id}`);\n\n root.appendChild(this.buildViewToggle(block));\n root.appendChild(this.buildNav(block));\n\n const grid = document.createElement('div');\n grid.className = 'blex-calendar__grid';\n\n if (this.currentView === 'month') {\n this.buildMonthGrid(grid, block);\n } else if (this.currentView === 'week') {\n this.buildWeekGrid(grid, block);\n } else {\n this.buildDayGrid(grid, block);\n }\n\n root.appendChild(grid);\n container.appendChild(root);\n }\n\n // ---------------------------------------------------------------------------\n // View toggle\n // ---------------------------------------------------------------------------\n\n private buildViewToggle(block: ContentBlock<CalendarData>): HTMLElement {\n const bar = document.createElement('div');\n bar.className = 'blex-calendar__view-toggle';\n\n const views: CalendarView[] = ['month', 'week', 'day'];\n for (const v of views) {\n const btn = document.createElement('button');\n btn.className = 'blex-calendar__view-btn';\n btn.setAttribute('data-testid', `blex-calendar-view-${v}`);\n btn.textContent = v.charAt(0).toUpperCase() + v.slice(1);\n if (v === this.currentView) {\n btn.setAttribute('aria-pressed', 'true');\n }\n\n this.addListener(btn, 'click', (() => {\n this.currentView = v;\n this.container!.innerHTML = '';\n this.buildCalendar(block);\n }) as EventListener);\n\n bar.appendChild(btn);\n }\n\n return bar;\n }\n\n // ---------------------------------------------------------------------------\n // Navigation bar\n // ---------------------------------------------------------------------------\n\n private buildNav(block: ContentBlock<CalendarData>): HTMLElement {\n const nav = document.createElement('div');\n nav.className = 'blex-calendar__nav';\n\n const prev = document.createElement('button');\n prev.className = 'blex-calendar__nav-btn';\n prev.setAttribute('data-testid', `blex-calendar-prev-${block.id}`);\n prev.textContent = '‹';\n this.addListener(prev, 'click', (() => {\n this.navigate(-1);\n }) as EventListener);\n\n const title = document.createElement('span');\n title.className = 'blex-calendar__title';\n title.textContent = this.getHeaderTitle();\n\n const next = document.createElement('button');\n next.className = 'blex-calendar__nav-btn';\n next.setAttribute('data-testid', `blex-calendar-next-${block.id}`);\n next.textContent = '›';\n this.addListener(next, 'click', (() => {\n this.navigate(1);\n }) as EventListener);\n\n nav.appendChild(prev);\n nav.appendChild(title);\n nav.appendChild(next);\n return nav;\n }\n\n private getHeaderTitle(): string {\n if (this.currentView === 'month') {\n return `${MONTH_NAMES[this.viewDate.getMonth()]} ${this.viewDate.getFullYear()}`;\n } else if (this.currentView === 'week') {\n const start = getWeekStart(this.viewDate);\n const end = new Date(start);\n end.setDate(end.getDate() + 6);\n return `${MONTH_NAMES[start.getMonth()]} ${start.getDate()} – ${end.getDate()}, ${start.getFullYear()}`;\n } else {\n return `${MONTH_NAMES[this.viewDate.getMonth()]} ${this.viewDate.getDate()}, ${this.viewDate.getFullYear()}`;\n }\n }\n\n private navigate(direction: number): void {\n if (this.currentView === 'month') {\n this.viewDate.setMonth(this.viewDate.getMonth() + direction);\n } else if (this.currentView === 'week') {\n this.viewDate.setDate(this.viewDate.getDate() + direction * 7);\n } else {\n this.viewDate.setDate(this.viewDate.getDate() + direction);\n }\n this.container!.innerHTML = '';\n this.buildCalendar(this.currentBlock!);\n }\n\n // ---------------------------------------------------------------------------\n // Month grid\n // ---------------------------------------------------------------------------\n\n private buildMonthGrid(grid: HTMLElement, block: ContentBlock<CalendarData>): void {\n const year = this.viewDate.getFullYear();\n const month = this.viewDate.getMonth();\n\n // Day-of-week header row\n for (const name of DAY_NAMES) {\n const hdr = document.createElement('div');\n hdr.className = 'blex-calendar__day-header';\n hdr.textContent = name;\n grid.appendChild(hdr);\n }\n\n const firstDay = new Date(year, month, 1).getDay();\n const daysInMonth = new Date(year, month + 1, 0).getDate();\n\n // Blank cells before the 1st\n for (let i = 0; i < firstDay; i++) {\n const blank = document.createElement('div');\n blank.className = 'blex-calendar__day blex-calendar__day--filler';\n grid.appendChild(blank);\n }\n\n // Day cells\n for (let day = 1; day <= daysInMonth; day++) {\n const mm = String(month + 1).padStart(2, '0');\n const dd = String(day).padStart(2, '0');\n const dateStr = `${year}-${mm}-${dd}`;\n const cell = document.createElement('div');\n cell.className = 'blex-calendar__day';\n cell.setAttribute('data-testid', `blex-calendar-day-${dateStr}`);\n cell.setAttribute('data-date', dateStr);\n\n const dayNum = document.createElement('span');\n dayNum.className = 'blex-calendar__day-number';\n dayNum.textContent = String(day);\n cell.appendChild(dayNum);\n\n // Events inside this day cell\n const dayEvents = this.getEventsForDate(block.data.events, dateStr);\n for (const event of dayEvents) {\n cell.appendChild(this.buildEventEl(event, block));\n }\n\n // Clicking on the day cell (not on an event) emits slot-click\n this.addListener(cell, 'click', ((e: MouseEvent) => {\n if ((e.target as HTMLElement).closest('.blex-calendar__event')) return;\n const start = `${dateStr}T00:00`;\n const end = `${dateStr}T23:59`;\n this.emit({\n blockId: block.id,\n type: 'slot-click',\n payload: { start, end },\n serialized: `Selected time slot: ${start} - ${end}`,\n summary: `Selected slot: ${start}`,\n icon: '📅',\n immediate: false,\n revertable: true,\n });\n }) as EventListener);\n\n grid.appendChild(cell);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Week grid (structural)\n // ---------------------------------------------------------------------------\n\n private buildWeekGrid(grid: HTMLElement, block: ContentBlock<CalendarData>): void {\n const weekStart = getWeekStart(this.viewDate);\n\n for (let i = 0; i < 7; i++) {\n const day = new Date(weekStart);\n day.setDate(weekStart.getDate() + i);\n const dateStr = formatDate(day);\n\n const col = document.createElement('div');\n col.className = 'blex-calendar__day';\n col.setAttribute('data-testid', `blex-calendar-day-${dateStr}`);\n col.setAttribute('data-date', dateStr);\n\n const hdr = document.createElement('div');\n hdr.className = 'blex-calendar__day-header';\n hdr.textContent = `${DAY_NAMES[day.getDay()]} ${day.getDate()}`;\n col.appendChild(hdr);\n\n // Hourly slots\n for (let hour = 0; hour < 24; hour++) {\n const hourStr = String(hour).padStart(2, '0');\n const slotStart = `${dateStr}T${hourStr}:00`;\n const slotEnd = `${dateStr}T${hourStr}:59`;\n\n const slot = document.createElement('div');\n slot.className = 'blex-calendar__slot';\n slot.setAttribute('data-start', slotStart);\n slot.setAttribute('data-end', slotEnd);\n slot.textContent = `${hourStr}:00`;\n\n this.addListener(slot, 'click', (() => {\n this.emit({\n blockId: block.id,\n type: 'slot-click',\n payload: { start: slotStart, end: slotEnd },\n serialized: `Selected time slot: ${slotStart} - ${slotEnd}`,\n summary: `Selected slot: ${slotStart}`,\n icon: '📅',\n immediate: false,\n revertable: true,\n });\n }) as EventListener);\n\n col.appendChild(slot);\n }\n\n // Events for this day\n const dayEvents = this.getEventsForDate(block.data.events, dateStr);\n for (const event of dayEvents) {\n col.appendChild(this.buildEventEl(event, block));\n }\n\n grid.appendChild(col);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Day grid (structural)\n // ---------------------------------------------------------------------------\n\n private buildDayGrid(grid: HTMLElement, block: ContentBlock<CalendarData>): void {\n const dateStr = formatDate(this.viewDate);\n\n const col = document.createElement('div');\n col.className = 'blex-calendar__day';\n col.setAttribute('data-testid', `blex-calendar-day-${dateStr}`);\n col.setAttribute('data-date', dateStr);\n\n // Hourly slots\n for (let hour = 0; hour < 24; hour++) {\n const hourStr = String(hour).padStart(2, '0');\n const slotStart = `${dateStr}T${hourStr}:00`;\n const slotEnd = `${dateStr}T${hourStr}:59`;\n\n const slot = document.createElement('div');\n slot.className = 'blex-calendar__slot';\n slot.setAttribute('data-start', slotStart);\n slot.setAttribute('data-end', slotEnd);\n slot.textContent = `${hourStr}:00`;\n\n this.addListener(slot, 'click', (() => {\n this.emit({\n blockId: block.id,\n type: 'slot-click',\n payload: { start: slotStart, end: slotEnd },\n serialized: `Selected time slot: ${slotStart} - ${slotEnd}`,\n summary: `Selected slot: ${slotStart}`,\n icon: '📅',\n immediate: false,\n revertable: true,\n });\n }) as EventListener);\n\n col.appendChild(slot);\n }\n\n // Events for this day\n const dayEvents = this.getEventsForDate(block.data.events, dateStr);\n for (const event of dayEvents) {\n col.appendChild(this.buildEventEl(event, block));\n }\n\n grid.appendChild(col);\n }\n\n // ---------------------------------------------------------------------------\n // Shared helpers\n // ---------------------------------------------------------------------------\n\n private buildEventEl(event: CalendarEvent, block: ContentBlock<CalendarData>): HTMLElement {\n const el = document.createElement('div');\n el.className = 'blex-calendar__event';\n el.setAttribute('data-testid', `blex-calendar-event-${event.id}`);\n el.setAttribute('data-event-id', event.id);\n el.textContent = event.title;\n\n if (event.color) {\n el.style.backgroundColor = event.color;\n }\n\n this.addListener(el, 'click', ((e: MouseEvent) => {\n e.stopPropagation();\n this.showDetailPanel(event, el, block);\n this.emit({\n blockId: block.id,\n type: 'select',\n payload: { eventId: event.id },\n serialized: `Selected event: ${event.title}`,\n summary: `Viewed \"${event.title}\"`,\n icon: '📅',\n immediate: false,\n revertable: true,\n });\n }) as EventListener);\n\n return el;\n }\n\n private getEventsForDate(events: CalendarEvent[], dateStr: string): CalendarEvent[] {\n return events.filter((event) => {\n const eventStart = event.start.slice(0, 10);\n const eventEnd = event.end.slice(0, 10);\n return dateStr >= eventStart && dateStr <= eventEnd;\n });\n }\n}\n\nexport function createCalendarRenderer(): CalendarRenderer {\n return new CalendarRenderer();\n}\n"]}
@@ -198,6 +198,39 @@ var DEFAULT_STYLES = `
198
198
  .blex-poll__submit { background: var(--blex-accent); color: #fff; border-color: var(--blex-accent); }
199
199
  .blex-poll__submit:hover { opacity: 0.9; background: var(--blex-accent); }
200
200
 
201
+ /* Poll carousel */
202
+ .blex-poll--carousel { position: relative; }
203
+ .blex-poll__carousel-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
204
+ .blex-poll__dots { display: flex; gap: 6px; }
205
+ .blex-poll__dot {
206
+ width: 10px; height: 10px; border-radius: 50%; border: 2px solid var(--blex-border);
207
+ background: transparent; padding: 0; cursor: pointer; transition: all var(--blex-animation-duration);
208
+ }
209
+ .blex-poll__dot--answered { background: var(--blex-accent); border-color: var(--blex-accent); }
210
+ .blex-poll__dot--active { border-color: var(--blex-accent); box-shadow: 0 0 0 2px var(--blex-accent); }
211
+ .blex-poll__dot--active.blex-poll__dot--answered { background: var(--blex-accent); }
212
+ .blex-poll__counter { font-size: 12px; color: var(--blex-text); opacity: 0.6; }
213
+ .blex-poll__hint { font-weight: 400; opacity: 0.7; font-size: 12px; }
214
+ .blex-poll__nav { display: flex; justify-content: space-between; align-items: center; margin-top: 12px; }
215
+ .blex-poll__nav-btn {
216
+ background: transparent; border: 1px solid var(--blex-border); border-radius: 4px;
217
+ padding: 6px 14px; cursor: pointer; font-size: 13px; color: var(--blex-text);
218
+ font-family: var(--blex-font-family);
219
+ }
220
+ .blex-poll__nav-btn:hover { background: var(--blex-border); }
221
+
222
+ /* Poll summary */
223
+ .blex-poll--summary .blex-poll__summary-heading { font-size: 14px; font-weight: 600; margin-bottom: 8px; }
224
+ .blex-poll__summary-list { display: flex; flex-direction: column; gap: 4px; font-size: 13px; margin-bottom: 12px; }
225
+ .blex-poll__summary-item { padding: 4px 0; border-bottom: 1px solid var(--blex-border); }
226
+ .blex-poll__summary-item:last-child { border-bottom: none; }
227
+ .blex-poll__review-btn {
228
+ background: transparent; border: 1px solid var(--blex-border); border-radius: 4px;
229
+ padding: 6px 14px; cursor: pointer; font-size: 13px; color: var(--blex-text);
230
+ font-family: var(--blex-font-family);
231
+ }
232
+ .blex-poll__review-btn:hover { background: var(--blex-border); }
233
+
201
234
  /* \u2500\u2500 status \u2500\u2500 */
202
235
  .blex-status { padding: 8px 12px; }
203
236
  .blex-status__entry {
@@ -466,6 +499,7 @@ var DEFAULT_STYLES = `
466
499
 
467
500
  /* \u2500\u2500 calendar \u2500\u2500 */
468
501
  .blex-calendar {
502
+ position: relative;
469
503
  font-family: var(--blex-font-family); color: var(--blex-text);
470
504
  border: 1px solid var(--blex-border); border-radius: 6px; padding: 12px;
471
505
  background: var(--blex-bg);
@@ -501,6 +535,26 @@ var DEFAULT_STYLES = `
501
535
  font-size: 11px; color: #fff; background: var(--blex-accent);
502
536
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer;
503
537
  }
538
+ .blex-calendar__detail {
539
+ position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);
540
+ display: flex; flex-direction: column; gap: 8px;
541
+ background: var(--blex-bg); border: 1px solid var(--blex-border);
542
+ border-radius: 8px; padding: 12px 16px; min-width: 220px; max-width: 320px;
543
+ box-shadow: 0 4px 16px rgba(0,0,0,0.12); z-index: 10;
544
+ font-family: var(--blex-font-family); color: var(--blex-text);
545
+ }
546
+ .blex-calendar__detail-color {
547
+ width: 100%; height: 4px; border-radius: 2px; background: var(--blex-accent);
548
+ }
549
+ .blex-calendar__detail-content { display: flex; flex-direction: column; gap: 4px; }
550
+ .blex-calendar__detail-title { font-weight: 600; font-size: 14px; }
551
+ .blex-calendar__detail-time { font-size: 12px; color: var(--blex-muted); }
552
+ .blex-calendar__detail-dismiss {
553
+ align-self: flex-end; padding: 4px 12px; border: 1px solid var(--blex-border);
554
+ border-radius: 4px; background: var(--blex-bg); color: var(--blex-text);
555
+ font-size: 12px; cursor: pointer;
556
+ }
557
+ .blex-calendar__detail-dismiss:hover { background: rgba(0,0,0,0.04); }
504
558
 
505
559
  /* \u2500\u2500 gallery \u2500\u2500 */
506
560
  .blex-gallery {
@@ -636,92 +690,336 @@ function createConfirmRenderer() {
636
690
  var PollRenderer = class extends BaseRenderer {
637
691
  constructor() {
638
692
  super(...arguments);
639
- this.selected = /* @__PURE__ */ new Set();
640
- this.writeInValue = "";
693
+ this.questionStates = [];
694
+ this.currentIndex = 0;
695
+ this.normalizedQuestions = [];
696
+ this.submitted = false;
641
697
  }
642
698
  render(block, container) {
643
699
  this.container = container;
700
+ this.normalizedQuestions = this._normalizeQuestions(block.data);
701
+ this.questionStates = this.normalizedQuestions.map(() => ({
702
+ selected: /* @__PURE__ */ new Set(),
703
+ writeInValue: ""
704
+ }));
705
+ this.currentIndex = 0;
706
+ this.submitted = false;
644
707
  this._build(block);
645
708
  container.setAttribute("data-blex-ready", "true");
646
709
  }
647
710
  update(block) {
648
711
  if (!this.container) return;
649
- const newOptionCount = block.data.options.length;
650
- for (const idx of Array.from(this.selected)) {
651
- if (idx >= newOptionCount) this.selected.delete(idx);
712
+ const newQuestions = this._normalizeQuestions(block.data);
713
+ const newStates = newQuestions.map((q, i) => {
714
+ if (i < this.questionStates.length) {
715
+ const existing = this.questionStates[i];
716
+ const filtered = /* @__PURE__ */ new Set();
717
+ for (const idx of existing.selected) {
718
+ if (idx < q.options.length) filtered.add(idx);
719
+ }
720
+ return { selected: filtered, writeInValue: existing.writeInValue };
721
+ }
722
+ return { selected: /* @__PURE__ */ new Set(), writeInValue: "" };
723
+ });
724
+ this.normalizedQuestions = newQuestions;
725
+ this.questionStates = newStates;
726
+ if (this.currentIndex >= newQuestions.length) {
727
+ this.currentIndex = Math.max(0, newQuestions.length - 1);
652
728
  }
653
729
  this.container.innerHTML = "";
654
730
  this._build(block);
655
731
  }
732
+ _normalizeQuestions(data) {
733
+ if (data.questions && data.questions.length > 0) {
734
+ return data.questions;
735
+ }
736
+ return [{
737
+ question: data.question || "",
738
+ options: data.options || [],
739
+ multiSelect: data.multiSelect,
740
+ writeIn: data.writeIn
741
+ }];
742
+ }
743
+ _isCarousel() {
744
+ return this.normalizedQuestions.length > 1;
745
+ }
656
746
  _build(block) {
747
+ if (this.submitted) {
748
+ this._buildSummary(block);
749
+ return;
750
+ }
751
+ if (this._isCarousel()) {
752
+ this._buildCarousel(block);
753
+ } else {
754
+ this._buildSingle(block);
755
+ }
756
+ }
757
+ _buildSingle(block) {
657
758
  const container = this.container;
658
- const { question, options, multiSelect, writeIn } = block.data;
759
+ const q = this.normalizedQuestions[0];
760
+ const state = this.questionStates[0];
659
761
  const wrapper = document.createElement("div");
660
762
  wrapper.className = "blex-poll";
661
763
  wrapper.setAttribute("data-testid", `blex-poll-${block.id}`);
662
- const q = document.createElement("p");
663
- q.className = "blex-poll__question";
664
- q.textContent = question;
665
- wrapper.appendChild(q);
764
+ const qEl = document.createElement("p");
765
+ qEl.className = "blex-poll__question";
766
+ qEl.textContent = q.question;
767
+ wrapper.appendChild(qEl);
768
+ this._buildOptions(wrapper, q, state, block.id, 0);
769
+ if (q.writeIn) {
770
+ this._buildWriteIn(wrapper, state, block.id, 0);
771
+ }
772
+ const submitBtn = document.createElement("button");
773
+ submitBtn.className = "blex-poll__submit";
774
+ submitBtn.textContent = "Submit";
775
+ submitBtn.setAttribute("data-testid", `blex-poll-submit-${block.id}`);
776
+ this.addListener(submitBtn, "click", () => {
777
+ this._emitSubmit(block);
778
+ });
779
+ wrapper.appendChild(submitBtn);
780
+ container.appendChild(wrapper);
781
+ }
782
+ _buildCarousel(block) {
783
+ const container = this.container;
784
+ const questions = this.normalizedQuestions;
785
+ const idx = this.currentIndex;
786
+ const q = questions[idx];
787
+ const state = this.questionStates[idx];
788
+ const total = questions.length;
789
+ const wrapper = document.createElement("div");
790
+ wrapper.className = "blex-poll blex-poll--carousel";
791
+ wrapper.setAttribute("data-testid", `blex-poll-${block.id}`);
792
+ const header = document.createElement("div");
793
+ header.className = "blex-poll__carousel-header";
794
+ header.setAttribute("data-testid", "blex-poll-carousel-header");
795
+ const dots = document.createElement("div");
796
+ dots.className = "blex-poll__dots";
797
+ dots.setAttribute("data-testid", "blex-poll-dots");
798
+ for (let i = 0; i < total; i++) {
799
+ const dot = document.createElement("button");
800
+ dot.className = "blex-poll__dot";
801
+ dot.setAttribute("data-testid", `blex-poll-dot-${i}`);
802
+ dot.setAttribute("aria-label", `Question ${i + 1}`);
803
+ if (i === idx) {
804
+ dot.classList.add("blex-poll__dot--active");
805
+ } else if (this.questionStates[i].selected.size > 0 || this.questionStates[i].writeInValue) {
806
+ dot.classList.add("blex-poll__dot--answered");
807
+ }
808
+ this.addListener(dot, "click", () => {
809
+ this.currentIndex = i;
810
+ this.container.innerHTML = "";
811
+ this._build(block);
812
+ });
813
+ dots.appendChild(dot);
814
+ }
815
+ header.appendChild(dots);
816
+ const counter = document.createElement("span");
817
+ counter.className = "blex-poll__counter";
818
+ counter.setAttribute("data-testid", "blex-poll-counter");
819
+ counter.textContent = `${idx + 1} of ${total}`;
820
+ header.appendChild(counter);
821
+ wrapper.appendChild(header);
822
+ const qEl = document.createElement("p");
823
+ qEl.className = "blex-poll__question";
824
+ qEl.textContent = q.question;
825
+ if (q.multiSelect) {
826
+ const hint = document.createElement("span");
827
+ hint.className = "blex-poll__hint";
828
+ hint.textContent = " (select all that apply)";
829
+ qEl.appendChild(hint);
830
+ }
831
+ wrapper.appendChild(qEl);
832
+ this._buildOptions(wrapper, q, state, block.id, idx);
833
+ if (q.writeIn) {
834
+ this._buildWriteIn(wrapper, state, block.id, idx);
835
+ }
836
+ const nav = document.createElement("div");
837
+ nav.className = "blex-poll__nav";
838
+ if (idx > 0) {
839
+ const backBtn = document.createElement("button");
840
+ backBtn.className = "blex-poll__nav-btn blex-poll__nav-btn--back";
841
+ backBtn.setAttribute("data-testid", "blex-poll-back");
842
+ backBtn.textContent = "\u2190 Back";
843
+ this.addListener(backBtn, "click", () => {
844
+ this.currentIndex = idx - 1;
845
+ this.container.innerHTML = "";
846
+ this._build(block);
847
+ });
848
+ nav.appendChild(backBtn);
849
+ } else {
850
+ const spacer = document.createElement("div");
851
+ nav.appendChild(spacer);
852
+ }
853
+ if (idx < total - 1) {
854
+ const nextBtn = document.createElement("button");
855
+ nextBtn.className = "blex-poll__nav-btn blex-poll__nav-btn--next";
856
+ nextBtn.setAttribute("data-testid", "blex-poll-next");
857
+ nextBtn.textContent = "Next \u2192";
858
+ this.addListener(nextBtn, "click", () => {
859
+ this.currentIndex = idx + 1;
860
+ this.container.innerHTML = "";
861
+ this._build(block);
862
+ });
863
+ nav.appendChild(nextBtn);
864
+ } else {
865
+ const submitBtn = document.createElement("button");
866
+ submitBtn.className = "blex-poll__submit";
867
+ submitBtn.setAttribute("data-testid", `blex-poll-submit-${block.id}`);
868
+ submitBtn.textContent = "Submit \u27A4";
869
+ this.addListener(submitBtn, "click", () => {
870
+ this._emitSubmit(block);
871
+ });
872
+ nav.appendChild(submitBtn);
873
+ }
874
+ wrapper.appendChild(nav);
875
+ container.appendChild(wrapper);
876
+ }
877
+ _buildOptions(wrapper, q, state, _blockId, questionIndex) {
666
878
  const optionsList = document.createElement("div");
667
879
  optionsList.className = "blex-poll__options";
668
- options.forEach((opt, i) => {
880
+ q.options.forEach((opt, i) => {
669
881
  const btn = document.createElement("button");
670
882
  btn.className = "blex-poll__option";
671
- if (this.selected.has(i)) {
883
+ if (state.selected.has(i)) {
672
884
  btn.classList.add("blex-poll__option--selected");
673
885
  }
674
886
  btn.setAttribute("data-testid", `blex-poll-option-${i}`);
675
887
  btn.textContent = opt;
676
888
  this.addListener(btn, "click", () => {
677
- if (multiSelect) {
678
- if (this.selected.has(i)) {
679
- this.selected.delete(i);
889
+ if (q.multiSelect) {
890
+ if (state.selected.has(i)) {
891
+ state.selected.delete(i);
680
892
  btn.classList.remove("blex-poll__option--selected");
681
893
  } else {
682
- this.selected.add(i);
894
+ state.selected.add(i);
683
895
  btn.classList.add("blex-poll__option--selected");
684
896
  }
685
897
  } else {
686
898
  const allOptionBtns = optionsList.querySelectorAll(".blex-poll__option");
687
899
  allOptionBtns.forEach((b) => b.classList.remove("blex-poll__option--selected"));
688
- this.selected.clear();
689
- this.selected.add(i);
900
+ state.selected.clear();
901
+ state.selected.add(i);
690
902
  btn.classList.add("blex-poll__option--selected");
691
903
  }
904
+ if (this._isCarousel()) {
905
+ const dot = this.container?.querySelector(`[data-testid="blex-poll-dot-${questionIndex}"]`);
906
+ if (dot) {
907
+ dot.classList.add("blex-poll__dot--answered");
908
+ }
909
+ }
692
910
  });
693
911
  optionsList.appendChild(btn);
694
912
  });
695
913
  wrapper.appendChild(optionsList);
696
- if (writeIn) {
697
- const writeInInput = document.createElement("input");
698
- writeInInput.type = "text";
699
- writeInInput.className = "blex-poll__writein";
700
- writeInInput.placeholder = "Other...";
701
- writeInInput.setAttribute("data-testid", `blex-poll-writein-${block.id}`);
702
- writeInInput.value = this.writeInValue;
703
- this.addListener(writeInInput, "input", () => {
704
- this.writeInValue = writeInInput.value;
914
+ }
915
+ _buildWriteIn(wrapper, state, blockId, questionIndex) {
916
+ const writeInInput = document.createElement("input");
917
+ writeInInput.type = "text";
918
+ writeInInput.className = "blex-poll__writein";
919
+ writeInInput.placeholder = "Other...";
920
+ writeInInput.setAttribute("data-testid", `blex-poll-writein-${blockId}`);
921
+ writeInInput.value = state.writeInValue;
922
+ this.addListener(writeInInput, "input", () => {
923
+ state.writeInValue = writeInInput.value;
924
+ if (this._isCarousel() && writeInInput.value) {
925
+ const dot = this.container?.querySelector(`[data-testid="blex-poll-dot-${questionIndex}"]`);
926
+ if (dot) {
927
+ dot.classList.add("blex-poll__dot--answered");
928
+ }
929
+ }
930
+ });
931
+ wrapper.appendChild(writeInInput);
932
+ }
933
+ _buildSummary(block) {
934
+ const container = this.container;
935
+ const questions = this.normalizedQuestions;
936
+ const wrapper = document.createElement("div");
937
+ wrapper.className = "blex-poll blex-poll--summary";
938
+ wrapper.setAttribute("data-testid", `blex-poll-${block.id}`);
939
+ const heading = document.createElement("div");
940
+ heading.className = "blex-poll__summary-heading";
941
+ heading.textContent = `\u{1F5F3} Survey complete (${questions.length} question${questions.length !== 1 ? "s" : ""})`;
942
+ wrapper.appendChild(heading);
943
+ const list = document.createElement("div");
944
+ list.className = "blex-poll__summary-list";
945
+ list.setAttribute("data-testid", "blex-poll-summary-list");
946
+ questions.forEach((q, i) => {
947
+ const state = this.questionStates[i];
948
+ const selectedLabels = Array.from(state.selected).sort((a, b) => a - b).map((si) => q.options[si]);
949
+ const item = document.createElement("div");
950
+ item.className = "blex-poll__summary-item";
951
+ let answerText = selectedLabels.join(", ") || "(no selection)";
952
+ if (state.writeInValue) {
953
+ answerText += answerText !== "(no selection)" ? `: "${state.writeInValue}"` : `"${state.writeInValue}"`;
954
+ }
955
+ item.textContent = `${i + 1}. ${q.question} \u2192 ${answerText}`;
956
+ list.appendChild(item);
957
+ });
958
+ wrapper.appendChild(list);
959
+ if (this._isCarousel()) {
960
+ const reviewBtn = document.createElement("button");
961
+ reviewBtn.className = "blex-poll__review-btn";
962
+ reviewBtn.setAttribute("data-testid", "blex-poll-review");
963
+ reviewBtn.textContent = "Review \u25BE";
964
+ this.addListener(reviewBtn, "click", () => {
965
+ this.submitted = false;
966
+ this.currentIndex = 0;
967
+ this.container.innerHTML = "";
968
+ this._build(block);
705
969
  });
706
- wrapper.appendChild(writeInInput);
970
+ wrapper.appendChild(reviewBtn);
707
971
  }
708
- const submitBtn = document.createElement("button");
709
- submitBtn.className = "blex-poll__submit";
710
- submitBtn.textContent = "Submit";
711
- submitBtn.setAttribute("data-testid", `blex-poll-submit-${block.id}`);
712
- this.addListener(submitBtn, "click", () => {
713
- const selectedLabels = Array.from(this.selected).sort((a, b) => a - b).map((i) => options[i]);
972
+ container.appendChild(wrapper);
973
+ }
974
+ _emitSubmit(block) {
975
+ const questions = this.normalizedQuestions;
976
+ const isCarousel = this._isCarousel();
977
+ if (isCarousel) {
978
+ const answers = [];
979
+ const lines = [`Survey response (${questions.length} questions):`];
980
+ questions.forEach((q, i) => {
981
+ const state = this.questionStates[i];
982
+ const selectedLabels = Array.from(state.selected).sort((a, b) => a - b).map((si) => q.options[si]);
983
+ const answer = {
984
+ question: q.question,
985
+ selected: selectedLabels
986
+ };
987
+ if (state.writeInValue) answer.writeIn = state.writeInValue;
988
+ answers.push(answer);
989
+ let line = `${i + 1}. ${q.question} \u2192 ${selectedLabels.join(", ") || "(no selection)"}`;
990
+ if (state.writeInValue) line += `
991
+ Write-in: ${state.writeInValue}`;
992
+ lines.push(line);
993
+ });
994
+ const answeredCount = answers.filter((a) => a.selected.length > 0 || a.writeIn).length;
995
+ const summary = `Survey: ${answeredCount}/${questions.length} answered`;
996
+ this.submitted = true;
997
+ this.container.innerHTML = "";
998
+ this._build(block);
999
+ this.emit({
1000
+ blockId: block.id,
1001
+ type: "submit",
1002
+ payload: { answers },
1003
+ serialized: lines.join("\n"),
1004
+ summary,
1005
+ icon: "\u{1F5F3}",
1006
+ immediate: true
1007
+ });
1008
+ } else {
1009
+ const q = questions[0];
1010
+ const state = this.questionStates[0];
1011
+ const selectedLabels = Array.from(state.selected).sort((a, b) => a - b).map((i) => q.options[i]);
714
1012
  const payload = {
715
1013
  selected: selectedLabels
716
1014
  };
717
- let serialized = `Poll response: ${question}
1015
+ let serialized = `Poll response: ${q.question}
718
1016
  Selected: ${selectedLabels.join(", ")}`;
719
- if (this.writeInValue) {
720
- payload.writeIn = this.writeInValue;
1017
+ if (state.writeInValue) {
1018
+ payload.writeIn = state.writeInValue;
721
1019
  serialized += `
722
- Write-in: ${this.writeInValue}`;
1020
+ Write-in: ${state.writeInValue}`;
723
1021
  }
724
- const summary = selectedLabels.length > 0 ? `Voted: ${selectedLabels.join(", ")}${this.writeInValue ? ` + "${this.writeInValue}"` : ""}` : `Write-in: ${this.writeInValue}`;
1022
+ const summary = selectedLabels.length > 0 ? `Voted: ${selectedLabels.join(", ")}${state.writeInValue ? ` + "${state.writeInValue}"` : ""}` : `Write-in: ${state.writeInValue}`;
725
1023
  this.emit({
726
1024
  blockId: block.id,
727
1025
  type: "submit",
@@ -731,9 +1029,7 @@ Write-in: ${this.writeInValue}`;
731
1029
  icon: "\u{1F5F3}",
732
1030
  immediate: true
733
1031
  });
734
- });
735
- wrapper.appendChild(submitBtn);
736
- container.appendChild(wrapper);
1032
+ }
737
1033
  }
738
1034
  };
739
1035
  function createPollRenderer() {
@@ -1993,7 +2289,7 @@ function registerDefaults() {
1993
2289
  return createKanbanRenderer;
1994
2290
  });
1995
2291
  registerLazyBlockType("calendar", async () => {
1996
- const { createCalendarRenderer } = await import('./calendar-PNRNENA4.js');
2292
+ const { createCalendarRenderer } = await import('./calendar-DOOC3ERV.js');
1997
2293
  return createCalendarRenderer;
1998
2294
  });
1999
2295
  registerLazyBlockType("gallery", async () => {
@@ -2028,5 +2324,5 @@ function registerDefaults() {
2028
2324
  }
2029
2325
 
2030
2326
  export { getRegisteredTypes, hasBlockType, isBuiltIn, registerBlockType, registerDefaults, registerLazyBlockType, renderBlock, unregisterBlockType };
2031
- //# sourceMappingURL=chunk-6QSZG6F7.js.map
2032
- //# sourceMappingURL=chunk-6QSZG6F7.js.map
2327
+ //# sourceMappingURL=chunk-RQXBRXSU.js.map
2328
+ //# sourceMappingURL=chunk-RQXBRXSU.js.map