@open-webapp/calendar 0.6.1 → 0.7.0

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/README.md CHANGED
@@ -211,7 +211,7 @@ The exported standalone selector keeps its single-list props and behavior; Selec
211
211
 
212
212
  ### Host CSS
213
213
 
214
- Day ribbon styling: override `--calendar-today-accent` to recolour today's ribbon; `--calendar-day-header-height` tunes the sticky label offset.
214
+ Day ribbon styling: each day's ribbon alternates between two tones by day parity (`data-parity="even|odd"`), set with `--calendar-day-ribbon-a` and `--calendar-day-ribbon-b`. Parity is stable across scroll, filtering and month boundaries, and the ribbon does not mark today. `--calendar-day-header-height` tunes the sticky label offset.
215
215
 
216
216
  `styles.css` is self-contained, using component-scoped semantic palette tokens and native-control `color-scheme`. Each pane/selector root resets the full palette; explicit dark overrides and system-only `prefers-color-scheme` rules keep instances isolated. It requires no host CSS variables. Layout/status variables:
217
217
 
@@ -223,9 +223,15 @@ The Unaccepted count badge uses `.calendar-rsvp-chip-badge`, with light and dark
223
223
 
224
224
  The shared `.calendar-selector-trigger` uses border-box inline-flex, centered alignment, an 8px gap, 36px minimum height, 8px 12px padding, 6px radius, a 1px solid control border, inherited font and pointer cursor. `.calendar-selector-trigger-label` bounds long labels with ellipsis; `.calendar-selector-chevron` stays 12px and does not shrink or add a tab stop. Existing scoped surface/text/control-border tokens style the resting trigger, the hover token supplies its hover background, and the focus token supplies a 2px `:focus-visible` outline with 2px offset. This approved visual-only exception changes trigger geometry and its derived dropdown position, preserving surrounding layout and theme isolation. Import the shipped stylesheet for both footer and standalone use.
225
225
 
226
+ ## 0.7.0 (minor, breaking-visual)
227
+
228
+ - Day ribbons alternate between two tones by day parity (`data-parity="even|odd"`, days since 1970 of the date key mod 2) instead of highlighting today. Parity is stable across scroll, filter and month boundaries.
229
+ - "Today" is now the browser's local date (previously UTC, which could be off by a day for users away from UTC). Sticky day header text ("Today · Oct 26") is unchanged.
230
+ - Migration: `--calendar-today-accent` was removed in 0.7.0; use `--calendar-day-ribbon-a` / `--calendar-day-ribbon-b`. The ribbon no longer marks today (`data-today` is now `data-parity`).
231
+
226
232
  ## 0.6.0 (minor, additive-visual)
227
233
 
228
- - Each day has a thin vertical ribbon left of its events with a rotated `Mmm D` label; today's ribbon uses the new `--calendar-today-accent` token (defaults to the selected-chip colour in light and dark). The sticky day header is unchanged.
234
+ - Each day has a thin vertical ribbon left of its events with a rotated `Mmm D` label; ribbons alternate tones by day parity (see 0.7.0). The sticky day header is unchanged.
229
235
  - The RSVP status bar moved from the left edge to the right edge of event rows.
230
236
  - New helper `formatRibbonLabel`.
231
237
 
@@ -39,9 +39,6 @@ export function getRollingWindow(now) {
39
39
  const end = new Date(now.getTime() + 30 * MS_PER_DAY);
40
40
  return { start: start.toISOString(), end: end.toISOString() };
41
41
  }
42
- function toIsoDate(d) {
43
- return d.toISOString().slice(0, 10);
44
- }
45
42
  /**
46
43
  * Returns events whose `selfResponseStatus` is a member of `selected` —
47
44
  * declined is a normal, independently-selectable status now, not hard-excluded.
@@ -176,7 +173,8 @@ function addDaysToIso(dateKey, days) {
176
173
  const { year, month, day } = parseIsoDateParts(dateKey);
177
174
  const d = new Date(Date.UTC(year, month - 1, day));
178
175
  d.setUTCDate(d.getUTCDate() + days);
179
- return toIsoDate(d);
176
+ // d is built from pure UTC parts (not "now"), so the UTC date is the right one.
177
+ return d.toISOString().slice(0, 10);
180
178
  }
181
179
  /**
182
180
  * "Today · Sept 26" / "Tomorrow · Sept 27" / else "Sept 28"-style.
@@ -76,7 +76,12 @@ function openEventPopup(url, popupRef, popupName) {
76
76
  popup.focus();
77
77
  }
78
78
  function toIsoDate(d) {
79
- return d.toISOString().slice(0, 10);
79
+ const p = (n) => String(n).padStart(2, '0');
80
+ return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
81
+ }
82
+ function dayParity(dateKey) {
83
+ const [y, m, d] = dateKey.split('-').map(Number);
84
+ return Math.floor(Date.UTC(y, m - 1, d) / 86400000) % 2 === 0 ? 'even' : 'odd';
80
85
  }
81
86
  function formatTimeOfDay(dateTime) {
82
87
  const d = new Date(dateTime);
@@ -312,7 +317,7 @@ export function CalendarPane(props) {
312
317
  else {
313
318
  dayHeaderRefs.current.delete(group.dateKey);
314
319
  }
315
- }, children: formatDayHeader(group.dateKey, todayIso) }), group.events.length > 0 && (_jsxs("div", { className: "calendar-day-body", children: [_jsx("div", { className: "calendar-day-ribbon", "aria-hidden": "true", "data-today": group.dateKey === todayIso ? 'true' : undefined, children: _jsx("div", { className: "calendar-day-ribbon-window", children: _jsx("span", { className: "calendar-day-ribbon-label", children: formatRibbonLabel(group.dateKey) }) }) }), _jsx("div", { className: "calendar-day-events", children: group.events.map((event) => {
320
+ }, children: formatDayHeader(group.dateKey, todayIso) }), group.events.length > 0 && (_jsxs("div", { className: "calendar-day-body", children: [_jsx("div", { className: "calendar-day-ribbon", "aria-hidden": "true", "data-parity": dayParity(group.dateKey), children: _jsx("div", { className: "calendar-day-ribbon-window", children: _jsx("span", { className: "calendar-day-ribbon-label", children: formatRibbonLabel(group.dateKey) }) }) }), _jsx("div", { className: "calendar-day-events", children: group.events.map((event) => {
316
321
  const eventKey = getCalendarEventKey(event);
317
322
  const calendar = calendarsByKey.get(`${event.sourceId}\u0000${event.calendarId}`);
318
323
  const showCalendarLabel = calendar && !calendar.primary;
package/dist/styles.css CHANGED
@@ -11,7 +11,8 @@
11
11
  --calendar-chip-text: #333;
12
12
  --calendar-chip-border: #ccc;
13
13
  --calendar-chip-selected: #081a59;
14
- --calendar-today-accent: #081a59;
14
+ --calendar-day-ribbon-a: #e4e8ef;
15
+ --calendar-day-ribbon-b: #c8d6f0;
15
16
  --calendar-chip-selected-text: #ffffff;
16
17
  --calendar-badge: #e8eefb;
17
18
  --calendar-badge-text: #081a59;
@@ -217,9 +218,12 @@
217
218
  align-items: flex-start;
218
219
  }
219
220
 
220
- .calendar-day-ribbon[data-today='true'] {
221
- background: var(--calendar-today-accent);
222
- color: var(--calendar-chip-selected-text);
221
+ .calendar-day-ribbon[data-parity='even'] {
222
+ background: var(--calendar-day-ribbon-a);
223
+ }
224
+
225
+ .calendar-day-ribbon[data-parity='odd'] {
226
+ background: var(--calendar-day-ribbon-b);
223
227
  }
224
228
 
225
229
  .calendar-day-ribbon-window {
@@ -395,7 +399,8 @@
395
399
  --calendar-chip-text: #eee;
396
400
  --calendar-chip-border: #444;
397
401
  --calendar-chip-selected: #22d0ef;
398
- --calendar-today-accent: #22d0ef;
402
+ --calendar-day-ribbon-a: #2b3342;
403
+ --calendar-day-ribbon-b: #1c3a5e;
399
404
  --calendar-chip-selected-text: #081a59;
400
405
  --calendar-badge: #081a59;
401
406
  --calendar-badge-text: #e8eefb;
@@ -437,7 +442,8 @@
437
442
  --calendar-chip-text: #eee;
438
443
  --calendar-chip-border: #444;
439
444
  --calendar-chip-selected: #22d0ef;
440
- --calendar-today-accent: #22d0ef;
445
+ --calendar-day-ribbon-a: #2b3342;
446
+ --calendar-day-ribbon-b: #1c3a5e;
441
447
  --calendar-chip-selected-text: #081a59;
442
448
  --calendar-badge: #081a59;
443
449
  --calendar-badge-text: #e8eefb;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-webapp/calendar",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",