joplin-plugin-my-calendar 1.2.7 → 1.3.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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [1.3.0](https://github.com/volodymyroliinyk/joplin-plugin-my-calendar/compare/v1.2.7...v1.3.0) (2026-02-04)
6
+
7
+
8
+ ### ✨ Features
9
+
10
+ * ui enhancements ([af04211](https://github.com/volodymyroliinyk/joplin-plugin-my-calendar/commit/af04211e1efcb8816ebd3decec7da11a74048118))
11
+
5
12
  ### [1.2.7](https://github.com/volodymyroliinyk/joplin-plugin-my-calendar/compare/v1.2.6...v1.2.7) (2026-02-02)
6
13
 
7
14
 
package/README.md CHANGED
@@ -18,6 +18,8 @@ note-taking app.
18
18
  ## 🌟 Key Features
19
19
 
20
20
  - **Monthly Calendar Grid**: Navigate through months, view event bars, and see your schedule at a glance.
21
+ - **Quick Month-Year Navigation**: Click the month/year header to open a picker and jump instantly to any date in the
22
+ past or future.
21
23
  - **Smart Day View**: Click any day to see a detailed list of scheduled events.
22
24
  - **Notes as Events**: Any note can become a calendar event simply by adding a small Markdown block.
23
25
  - **ICS Import**: Import standard `*.ics` files (from Google Calendar, Outlook, Apple, etc.) directly into your Joplin
@@ -64,8 +66,8 @@ You don't need to import files to use the calendar. Simply add the following blo
64
66
  ~~~markdown
65
67
  ```mycalendar-event
66
68
  title: Meeting with Team
67
- start: 2025-12-18 10:00+02:00
68
- end: 2025-12-18 11:30+02:00
69
+ start: 2026-02-04 10:00+02:00
70
+ end: 2026-02-04 11:30+02:00
69
71
  color: #3498db
70
72
  location: Conference Room B
71
73
  ```
@@ -128,14 +130,14 @@ The calendar supports several ways to specify the time and timezone of your even
128
130
  Explicitly define the time and its relation to UTC. This time will be automatically converted to your current
129
131
  device's timezone.
130
132
  ```text
131
- start: 2025-12-18 10:00+02:00
133
+ start: 2026-02-04 10:00+02:00
132
134
  ```
133
135
 
134
136
  2. **With `tz` Property (IANA)**
135
137
  Specify the time and the exact IANA Timezone name. The plugin will handle the conversion based on daylight saving
136
138
  rules.
137
139
  ```text
138
- start: 2025-12-18 10:00
140
+ start: 2026-02-04 10:00
139
141
  tz: America/Toronto
140
142
  ```
141
143
 
@@ -143,7 +145,7 @@ The calendar supports several ways to specify the time and timezone of your even
143
145
  If no offset or `tz` is provided, the time is considered "floating" and will be shown exactly as written, regardless
144
146
  of the device's timezone settings.
145
147
  ```text
146
- start: 2025-12-18 10:00
148
+ start: 2026-02-04 10:00
147
149
  ```
148
150
 
149
151
  ---
@@ -189,10 +191,10 @@ Customize your experience in the Joplin Settings (`Tools` > `Options` > `My Cale
189
191
 
190
192
  ## 👨‍💻 Development
191
193
 
192
- ### Commands:
194
+ ### Commands
193
195
 
194
196
  - `npm run build;`: Compile the project.
195
- - `npm run pack;`: Create the `.jpl` distribution file.
197
+ - `npm pack;`: Create the `.jpl` distribution file.
196
198
  - `npm test;`: Run the extensive test suite (250+ cases).
197
199
  - `npm run lint;`: Check code style and common patterns.
198
200
  - `pkill -f jest || true;pkill -f node || true;rm -rf node_modules/.cache;rm -rf ~/.cache/jest;npx jest --clearCache;`:
@@ -218,6 +220,14 @@ Automates the entire release workflow: bumps version, syncs manifest, tags, push
218
220
  bash ./scripts/release.sh [patch|minor|major];
219
221
  ```
220
222
 
223
+ #### `scripts/update-demo-ics.py`
224
+
225
+ Automatically shifts dates in the demo ICS file to start from today. Useful for refreshing screenshots.
226
+
227
+ ```bash
228
+ ./scripts/update-demo-ics.py;
229
+ ```
230
+
221
231
  ### Development Workflow
222
232
 
223
233
  For a detailed guide on branch naming, commit message formats, and the release process, please see the *
@@ -2,9 +2,9 @@
2
2
  "manifest_version": 1,
3
3
  "id": "com.volodymyroliinyk.joplin.plugin.my-calendar",
4
4
  "app_min_version": "3.3",
5
- "version": "1.2.7",
5
+ "version": "1.3.0",
6
6
  "name": "My Calendar",
7
- "description": "Calendar view from notes with event syntax",
7
+ "description": "Calendar plugin for Joplin",
8
8
  "author": "Volodymyr Oliinyk",
9
9
  "homepage_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
10
10
  "repository_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
@@ -244,6 +244,9 @@
244
244
  let current = startOfMonthLocal(new Date());
245
245
  let selectedDayUtc = localMidnightTs(new Date());
246
246
 
247
+ let isPickerOpen = false;
248
+ let pickerYear = null;
249
+
247
250
  // Events received for the current range of calendar grid (42 days)
248
251
  let gridEvents = [];
249
252
 
@@ -272,9 +275,10 @@
272
275
  // Ensure immediate behavior on settings toggle without requiring a full re-render.
273
276
  if (hidden) {
274
277
  ul.querySelectorAll('.mc-event-timeline').forEach((el) => el.remove());
278
+ ul.querySelectorAll('.mc-events-timeline-now-line-wrap').forEach((el) => el.remove());
275
279
  }
276
280
  }
277
-
281
+
278
282
  function markPastDayEvents() {
279
283
  const ul = document.getElementById('mc-events-list');
280
284
  if (!ul) return;
@@ -357,15 +361,16 @@
357
361
  const inDay = now >= dayStartUtc && now < (dayStartUtc + DAY);
358
362
  const pct = Math.max(0, Math.min(100, ((now - dayStartUtc) / DAY) * 100));
359
363
 
360
- ul.querySelectorAll('.mc-event-timeline-now').forEach((dot) => {
361
- const el = /** @type {HTMLElement} */ (dot);
364
+ const line = ul.querySelector('.mc-events-timeline-now-line');
365
+ if (line) {
366
+ const el = /** @type {HTMLElement} */ (line);
362
367
  if (!inDay) {
363
368
  el.style.display = 'none';
364
- return;
369
+ } else {
370
+ el.style.display = 'block';
371
+ el.style.left = pct + '%';
365
372
  }
366
- el.style.display = '';
367
- el.style.left = pct + '%';
368
- });
373
+ }
369
374
  }
370
375
 
371
376
  function scheduleDayNowTimelineTick() {
@@ -629,6 +634,83 @@
629
634
  return b;
630
635
  }
631
636
 
637
+ function renderMonthYearPicker() {
638
+ const dropdown = document.createElement('div');
639
+ dropdown.className = 'mc-picker-dropdown';
640
+ dropdown.addEventListener('click', (e) => e.stopPropagation());
641
+
642
+ if (pickerYear === null) {
643
+ pickerYear = current.getFullYear();
644
+ }
645
+
646
+ const yearRow = document.createElement('div');
647
+ yearRow.className = 'mc-picker-year-row';
648
+
649
+ const btnPrevYear = button('‹', 'Previous year', () => {
650
+ pickerYear--;
651
+ renderToolbar();
652
+ });
653
+ const yearLabel = document.createElement('div');
654
+ yearLabel.className = 'mc-picker-year';
655
+ yearLabel.textContent = String(pickerYear);
656
+ const btnNextYear = button('›', 'Next year', () => {
657
+ pickerYear++;
658
+ renderToolbar();
659
+ });
660
+
661
+ yearRow.appendChild(btnPrevYear);
662
+ yearRow.appendChild(yearLabel);
663
+ yearRow.appendChild(btnNextYear);
664
+ dropdown.appendChild(yearRow);
665
+
666
+ const monthsGrid = document.createElement('div');
667
+ monthsGrid.className = 'mc-picker-months';
668
+
669
+ const monthNames = [];
670
+ for (let m = 0; m < 12; m++) {
671
+ const d = new Date(2000, m, 1);
672
+ monthNames.push(d.toLocaleString(undefined, {month: 'short'}));
673
+ }
674
+
675
+ monthNames.forEach((name, idx) => {
676
+ const mBtn = document.createElement('div');
677
+ mBtn.className = 'mc-picker-month';
678
+ if (idx === current.getMonth() && pickerYear === current.getFullYear()) {
679
+ mBtn.classList.add('mc-active');
680
+ }
681
+ mBtn.textContent = name;
682
+ mBtn.addEventListener('click', () => {
683
+ current = new Date(pickerYear, idx, 1);
684
+ isPickerOpen = false;
685
+ pickerYear = null;
686
+ drawMonth();
687
+ });
688
+ monthsGrid.appendChild(mBtn);
689
+ });
690
+
691
+ dropdown.appendChild(monthsGrid);
692
+
693
+ // const footer = document.createElement('div');
694
+ // footer.style.display = 'flex';
695
+ // footer.style.justifyContent = 'center';
696
+ // footer.style.marginTop = '8px';
697
+ // footer.style.paddingTop = '8px';
698
+ // footer.style.borderTop = '1px solid var(--joplin-divider-color)';
699
+ //
700
+ // const btnTodayPicker = button('Go to Today', 'Go to current month', () => {
701
+ // current = startOfMonthLocal(new Date());
702
+ // selectedDayUtc = localMidnightTs(new Date());
703
+ // isPickerOpen = false;
704
+ // pickerYear = null;
705
+ // drawMonth();
706
+ // });
707
+ // btnTodayPicker.style.width = '100%';
708
+ // footer.appendChild(btnTodayPicker);
709
+ // dropdown.appendChild(footer);
710
+
711
+ return dropdown;
712
+ }
713
+
632
714
  function renderToolbar() {
633
715
  const root = $toolbar();
634
716
  if (!root) return;
@@ -637,15 +719,18 @@
637
719
  wrap.className = 'mc-toolbar-inner';
638
720
 
639
721
  const btnPrev = button('‹', 'Previous month', () => {
722
+ isPickerOpen = false;
640
723
  current = addMonthsLocal(current, -1);
641
724
  drawMonth();
642
725
  });
643
726
  const btnToday = button('Today', 'Today', () => {
727
+ isPickerOpen = false;
644
728
  current = startOfMonthLocal(new Date());
645
729
  selectedDayUtc = localMidnightTs(new Date());
646
730
  drawMonth();
647
731
  });
648
732
  const btnNext = button('›', 'Next month', () => {
733
+ isPickerOpen = false;
649
734
  current = addMonthsLocal(current, +1);
650
735
  drawMonth();
651
736
  });
@@ -653,15 +738,37 @@
653
738
  // Month YYYY title.
654
739
  const title = document.createElement('div');
655
740
  title.className = 'mc-title';
656
- title.textContent = monthLabel(current);
741
+ title.id = 'mc-picker-trigger';
742
+ title.innerHTML = `${monthLabel(current)} <span class="mc-picker-arrow">▾</span>`;
743
+ title.addEventListener('click', (e) => {
744
+ e.stopPropagation();
745
+ isPickerOpen = !isPickerOpen;
746
+ if (isPickerOpen) {
747
+ pickerYear = current.getFullYear();
748
+ }
749
+ renderToolbar();
750
+ });
657
751
 
658
752
  wrap.appendChild(btnPrev);
659
753
  wrap.appendChild(btnToday);
660
754
  wrap.appendChild(btnNext);
661
755
  wrap.appendChild(title);
756
+
757
+ if (isPickerOpen) {
758
+ const picker = renderMonthYearPicker();
759
+ title.appendChild(picker);
760
+ }
761
+
662
762
  root.appendChild(wrap);
663
763
  }
664
764
 
765
+ document.addEventListener('click', () => {
766
+ if (isPickerOpen) {
767
+ isPickerOpen = false;
768
+ renderToolbar();
769
+ }
770
+ });
771
+
665
772
  function drawMonth() {
666
773
  if (!uiSettings.weekStart) {
667
774
  log('drawMonth skipped: weekStart not set');
@@ -932,6 +1039,15 @@
932
1039
  return;
933
1040
  }
934
1041
 
1042
+ if (uiSettings.showEventTimeline !== false) {
1043
+ const wrap = document.createElement('div');
1044
+ wrap.className = 'mc-events-timeline-now-line-wrap';
1045
+ const line = document.createElement('div');
1046
+ line.className = 'mc-events-timeline-now-line';
1047
+ wrap.appendChild(line);
1048
+ ul.appendChild(wrap);
1049
+ }
1050
+
935
1051
  for (const item of daySlices) {
936
1052
  const ev = item.ev;
937
1053
  const slice = item.slice;
@@ -955,7 +1071,7 @@
955
1071
  li.appendChild(title);
956
1072
  li.appendChild(t);
957
1073
 
958
- // 24h timeline under the event (segment = event slice, dot = current time in day)
1074
+ // 24h timeline under the event (segment = event slice)
959
1075
  if (uiSettings.showEventTimeline !== false) {
960
1076
  const timeline = document.createElement('div');
961
1077
  timeline.className = 'mc-event-timeline';
@@ -972,11 +1088,7 @@
972
1088
  seg.style.left = left + '%';
973
1089
  seg.style.width = Math.max(0, (right - left)) + '%';
974
1090
 
975
- const nowDot = document.createElement('div');
976
- nowDot.className = 'mc-event-timeline-now';
977
-
978
1091
  timeline.appendChild(seg);
979
- timeline.appendChild(nowDot);
980
1092
  li.appendChild(timeline);
981
1093
  }
982
1094
 
@@ -1,35 +1,42 @@
1
1
  /* src/ui/mycalendar.css */
2
2
 
3
- html, body {
3
+ html,
4
+ body {
4
5
  height: 100%;
5
6
  margin: 0;
6
7
  overflow: auto;
7
8
  }
8
9
 
9
10
  /* TODO:[1]: parent --scrollbar-size is invisible inside of iframe, and size is 7px always. How to solve that? */
10
- body::-webkit-scrollbar, select::-webkit-scrollbar {
11
+ body::-webkit-scrollbar,
12
+ select::-webkit-scrollbar {
11
13
  width: var(--scrollbar-size, 7px);
12
14
  height: var(--scrollbar-size, 7px);
13
15
  }
14
16
 
15
- body::-webkit-scrollbar-corner, select::-webkit-scrollbar-corner {
17
+ body::-webkit-scrollbar-corner,
18
+ select::-webkit-scrollbar-corner {
16
19
  background: none;
17
20
  }
18
21
 
19
- body::-webkit-scrollbar-track, select::-webkit-scrollbar-track {
22
+ body::-webkit-scrollbar-track,
23
+ select::-webkit-scrollbar-track {
20
24
  border: none;
21
25
  }
22
26
 
23
- body::-webkit-scrollbar-thumb, select::-webkit-scrollbar-thumb {
27
+ body::-webkit-scrollbar-thumb,
28
+ select::-webkit-scrollbar-thumb {
24
29
  background: var(--scrollbar-thumb-color);
25
30
  border-radius: calc(var(--scrollbar-size, 7px) * 0.7);
26
31
  }
27
32
 
28
- body::-webkit-scrollbar-track:hover, select::-webkit-scrollbar-track:hover {
33
+ body::-webkit-scrollbar-track:hover,
34
+ select::-webkit-scrollbar-track:hover {
29
35
  background: rgba(0, 0, 0, 0.1);
30
36
  }
31
37
 
32
- body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
38
+ body::-webkit-scrollbar-thumb:hover,
39
+ select::-webkit-scrollbar-thumb:hover {
33
40
  background: var(--scrollbar-thumb-color-hover);
34
41
  }
35
42
 
@@ -37,6 +44,7 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
37
44
  --scrollbar-thumb-color: var(--joplin-scrollbar-thumb-color);
38
45
  --scrollbar-thumb-color-hover: var(--joplin-scrollbar-thumb-color-hover);
39
46
  --mc-default-event-color: #1470d9;
47
+ --mc-default-current-time-v-line-color: #ffa334;
40
48
  --mc-past-opacity: 0.45;
41
49
  /* Subtle weekend highlight (theme-aware) */
42
50
  --mc-weekend-head-bg: color-mix(in srgb, var(--joplin-background-color3) 70%, transparent);
@@ -44,11 +52,6 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
44
52
 
45
53
  }
46
54
 
47
- /*#joplin-plugin-content-root {*/
48
- /* min-width: 315px;*/
49
- /*}*/
50
-
51
-
52
55
  /* Outer container that will actually scroll */
53
56
  #mc-cal-scroll {
54
57
  height: 100%;
@@ -94,6 +97,102 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
94
97
  flex: 1;
95
98
  }
96
99
 
100
+ .mc-toolbar-inner .mc-title {
101
+ margin-left: 4px;
102
+ font-weight: 700;
103
+ flex: 1;
104
+ cursor: pointer;
105
+ display: flex;
106
+ align-items: center;
107
+ gap: 4px;
108
+ padding: 4px 8px;
109
+ border-radius: 4px;
110
+ transition: background 0.1s;
111
+ user-select: none;
112
+ position: relative;
113
+ }
114
+
115
+ .mc-toolbar-inner .mc-title:hover {
116
+ background: var(--joplin-background-color3);
117
+ }
118
+
119
+ .mc-btn.mc-calendar-nav-btn:hover {
120
+ background: var(--joplin-background-color3);
121
+ }
122
+
123
+ .mc-picker-dropdown {
124
+ position: absolute;
125
+ top: calc(100% + 4px);
126
+ right: 0;
127
+ background: var(--joplin-background-color);
128
+ border: 1px solid var(--joplin-divider-color);
129
+ border-radius: 8px;
130
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
131
+ z-index: 1000;
132
+ padding: 8px;
133
+ min-width: 200px;
134
+ display: flex;
135
+ flex-direction: column;
136
+ gap: 8px;
137
+ animation: mc-fade-in 0.15s ease-out;
138
+ }
139
+
140
+ @keyframes mc-fade-in {
141
+ from {
142
+ opacity: 0;
143
+ transform: translateY(-4px);
144
+ }
145
+
146
+ to {
147
+ opacity: 1;
148
+ transform: translateY(0);
149
+ }
150
+ }
151
+
152
+ .mc-picker-year-row {
153
+ display: flex;
154
+ align-items: center;
155
+ justify-content: space-between;
156
+ gap: 4px;
157
+ border-bottom: 1px solid var(--joplin-divider-color);
158
+ padding-bottom: 8px;
159
+ margin-bottom: 4px;
160
+ }
161
+
162
+ .mc-picker-year {
163
+ font-size: 14px;
164
+ font-weight: bold;
165
+ }
166
+
167
+ .mc-picker-months {
168
+ display: grid;
169
+ grid-template-columns: repeat(3, 1fr);
170
+ gap: 4px;
171
+ }
172
+
173
+ .mc-picker-month {
174
+ padding: 6px;
175
+ font-size: 12px;
176
+ text-align: center;
177
+ border-radius: 4px;
178
+ cursor: pointer;
179
+ transition: background 0.1s;
180
+ }
181
+
182
+ .mc-picker-month:hover {
183
+ background: var(--joplin-background-color3);
184
+ }
185
+
186
+ .mc-picker-month.mc-active {
187
+ background: var(--joplin-background-color3);
188
+ color: var(--joplin-color);
189
+ }
190
+
191
+ .mc-picker-arrow {
192
+ font-size: 10px;
193
+ opacity: 0.6;
194
+ }
195
+
97
196
  #mc-grid {
98
197
  border: 1px solid var(--joplin-divider-color);
99
198
  border-radius: 8px;
@@ -105,7 +204,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
105
204
  #mc-grid .mc-grid-loader {
106
205
  position: absolute;
107
206
  inset: 0;
108
- display: none; /* shown via .mc-loading */
207
+ display: none;
208
+ /* shown via .mc-loading */
109
209
  align-items: center;
110
210
  justify-content: center;
111
211
  background: color-mix(in srgb, var(--joplin-background-color) 70%, transparent);
@@ -142,7 +242,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
142
242
  }
143
243
  }
144
244
 
145
- .mc-grid-head, .mc-grid-body {
245
+ .mc-grid-head,
246
+ .mc-grid-body {
146
247
  display: grid;
147
248
  grid-template-columns: repeat(7, 1fr);
148
249
  gap: 4px;
@@ -208,8 +309,20 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
208
309
  .mc-grid-body .mc-cell {
209
310
  min-width: 0;
210
311
  padding: var(--mc-cell-pad-y) var(--mc-cell-pad-x);
312
+ border-right: 1px solid var(--joplin-divider-color);
313
+ border-top: 1px solid var(--joplin-divider-color);
314
+ overflow: hidden;
211
315
  }
212
316
 
317
+ .mc-grid-body .mc-cell.mc-weekend {
318
+ background: var(--mc-weekend-cell-bg);
319
+ }
320
+
321
+ .mc-grid-body .mc-cell:nth-child(7n) {
322
+ border-right: none;
323
+ }
324
+
325
+
213
326
  /* Scale typography inside cells */
214
327
  .mc-daynum {
215
328
  font-size: var(--mc-daynum-font);
@@ -258,24 +371,6 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
258
371
 
259
372
  /*****/
260
373
 
261
- .mc-grid-body .mc-cell {
262
- /*position: relative;*/
263
- /*min-height: 50px;*/
264
- border-right: 1px solid var(--joplin-divider-color);
265
- border-top: 1px solid var(--joplin-divider-color);
266
- padding: 4px 6px;
267
- overflow: hidden;
268
- }
269
-
270
- /* Highlight weekends inside the current month only (keep .mc-out styling as-is) */
271
- .mc-grid-body .mc-cell.mc-weekend:not(.mc-out) {
272
- background: var(--mc-weekend-cell-bg);
273
- }
274
-
275
- .mc-grid-body .mc-cell:nth-child(7n) {
276
- border-right: none;
277
- }
278
-
279
374
  .mc-daynum {
280
375
  font-size: 12px;
281
376
  opacity: 0.8;
@@ -297,7 +392,7 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
297
392
  }
298
393
 
299
394
  .mc-out {
300
- background: var(--joplin-background-color3);
395
+ opacity: 0.6;
301
396
  }
302
397
 
303
398
  .mc-today {
@@ -309,16 +404,6 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
309
404
  box-shadow: inset 0 0 0 2px var(--joplin-color);
310
405
  }
311
406
 
312
- /* Past days in the month grid */
313
- .mc-cell.mc-past {
314
- opacity: var(--mc-past-opacity);
315
- }
316
-
317
- /* Keep selection slightly more readable even if the day is in the past */
318
- .mc-cell.mc-past.mc-selected {
319
- opacity: 0.7;
320
- }
321
-
322
407
  .mc-events-header {
323
408
  display: flex;
324
409
  align-items: center;
@@ -332,13 +417,15 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
332
417
  white-space: nowrap;
333
418
  }
334
419
 
335
- #mc-events, #mc-import {
420
+ #mc-events,
421
+ #mc-import {
336
422
  border: 1px solid var(--joplin-divider-color);
337
423
  border-radius: 8px;
338
424
  overflow: hidden;
339
425
  }
340
426
 
341
- .mc-events-header, .mc-import-header {
427
+ .mc-events-header,
428
+ .mc-import-header {
342
429
  background: var(--joplin-background-color3);
343
430
  padding: 6px 10px;
344
431
  font-size: 12px;
@@ -349,6 +436,7 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
349
436
  list-style: none;
350
437
  margin: 0;
351
438
  padding: 8px 6px;
439
+ position: relative;
352
440
  }
353
441
 
354
442
  .mc-event {
@@ -358,6 +446,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
358
446
  padding: 6px;
359
447
  border-radius: 6px;
360
448
  cursor: pointer;
449
+ position: relative;
450
+ z-index: 2;
361
451
  }
362
452
 
363
453
  .mc-event:hover {
@@ -384,7 +474,6 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
384
474
 
385
475
  /* The container of strips in the cell */
386
476
  .mc-bars {
387
- /*position: absolute;*/
388
477
  left: 4px;
389
478
  right: 4px;
390
479
  bottom: 6px;
@@ -404,17 +493,16 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
404
493
 
405
494
  /* Badge-chiller is up to the right */
406
495
  .mc-count {
407
- /*position: absolute;*/
408
496
  top: 2px;
409
497
  right: 4px;
410
498
  font-size: 14px;
411
499
  font-weight: bold;
412
500
  text-align: center;
413
501
  line-height: 1;
414
- padding: 2px 4px;
415
- border-radius: 6px;
502
+ padding: 3px 4px;
503
+ border-radius: 4px;
416
504
  background: var(--joplin-background-color3);
417
- border: 1px solid var(--joplin-divider-color);
505
+ border: 0px solid var(--joplin-divider-color);
418
506
  opacity: 0.85;
419
507
  z-index: 3;
420
508
  }
@@ -424,8 +512,10 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
424
512
  }
425
513
 
426
514
  .mc-calendar-nav-btn {
427
- color: var(--joplin-color) !important; /* make the text white */
428
- background: transparent; /* The background is transparent */
515
+ color: var(--joplin-color) !important;
516
+ /* make the text white */
517
+ background: transparent;
518
+ /* The background is transparent */
429
519
  border: none;
430
520
  font-size: 12px;
431
521
  font-weight: 700;
@@ -433,7 +523,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
433
523
  }
434
524
 
435
525
  .mc-calendar-nav-btn:hover {
436
- color: var(--joplin-color) !important; /* lighter when creeping */
526
+ color: var(--joplin-color) !important;
527
+ /* lighter when creeping */
437
528
  }
438
529
 
439
530
  /* --- Events panel layout: list scroll + import at bottom --- */
@@ -450,7 +541,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
450
541
  #mc-ics-import-form .mc-grid-loader {
451
542
  position: absolute;
452
543
  inset: 0;
453
- display: none; /* shown via .mc-loading */
544
+ display: none;
545
+ /* shown via .mc-loading */
454
546
  align-items: center;
455
547
  justify-content: center;
456
548
  background: color-mix(in srgb, var(--joplin-background-color) 70%, transparent);
@@ -489,8 +581,10 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
489
581
  /* Container to be scrolled */
490
582
  #mc-import-body {
491
583
  margin: 0;
492
- max-height: 260px; /* choose the height that suits you */
493
- padding: 8px 6px; /* so that the scroll does not "stick" to the content */
584
+ max-height: 260px;
585
+ /* choose the height that suits you */
586
+ padding: 8px 6px;
587
+ /* so that the scroll does not "stick" to the content */
494
588
  }
495
589
 
496
590
  /* Very important for <input type="file"> in flex-line: otherwise it can inflate the width */
@@ -545,7 +639,6 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
545
639
  position: relative;
546
640
  flex: 0 0 100%;
547
641
  height: 2px;
548
- /*margin-top: 4px;*/
549
642
  border-radius: 999px;
550
643
  background: color-mix(in srgb, var(--joplin-color) 18%, transparent);
551
644
  overflow: hidden;
@@ -560,16 +653,28 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
560
653
  opacity: 0.9;
561
654
  }
562
655
 
563
- /* dot “now” */
564
- .mc-event-timeline .mc-event-timeline-now {
656
+ /* shared vertical line “now” */
657
+ .mc-events-timeline-now-line-wrap {
565
658
  position: absolute;
566
- top: 50%;
567
- width: 6px;
568
- height: 6px;
569
- border-radius: 50%;
570
- transform: translate(-50%, -50%);
571
- background: var(--joplin-color);
572
- box-shadow: 0 0 0 2px color-mix(in srgb, var(--joplin-background-color) 65%, transparent);
659
+ top: 0;
660
+ bottom: 0;
661
+ left: 12px;
662
+ /* 6px (ul padding) + 6px (li padding) */
663
+ right: 12px;
664
+ pointer-events: none;
665
+ z-index: 1;
666
+ }
667
+
668
+ .mc-events-timeline-now-line {
669
+ position: absolute;
670
+ top: 0;
671
+ bottom: 0;
672
+ width: 1px;
673
+ background: color-mix(in srgb, var(--mc-default-current-time-v-line-color) 40%, transparent);
674
+ box-shadow: 0 0 2px color-mix(in srgb, var(--mc-default-current-time-v-line-color) 20%, transparent);
675
+ z-index: 1;
676
+ display: none;
677
+ /* shown via JS when inDay */
573
678
  }
574
679
 
575
680
  /* slightly mute the timeline for past events */
@@ -689,7 +794,7 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
689
794
  gap: 2px;
690
795
  }
691
796
 
692
- .mc-cell {
797
+ .mc-grid-body .mc-cell {
693
798
  padding: 6px;
694
799
  }
695
800
 
@@ -697,7 +802,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
697
802
  font-size: 12px;
698
803
  }
699
804
 
700
- .mc-events-header, .mc-import-header {
805
+ .mc-events-header,
806
+ .mc-import-header {
701
807
  font-weight: normal;
702
808
  font-size: 12px;
703
809
  }
@@ -721,4 +827,8 @@ body::-webkit-scrollbar-thumb:hover, select::-webkit-scrollbar-thumb:hover {
721
827
  .mc-grid-head-cell.mc-weekend {
722
828
  background: var(--mc-weekend-head-bg);
723
829
  }
724
- }
830
+
831
+ .mc-count {
832
+ padding: 2px 4px;
833
+ }
834
+ }
package/manifest.json CHANGED
@@ -2,9 +2,9 @@
2
2
  "manifest_version": 1,
3
3
  "id": "com.volodymyroliinyk.joplin.plugin.my-calendar",
4
4
  "app_min_version": "3.3",
5
- "version": "1.2.7",
5
+ "version": "1.3.0",
6
6
  "name": "My Calendar",
7
- "description": "Calendar view from notes with event syntax",
7
+ "description": "Calendar plugin for Joplin",
8
8
  "author": "Volodymyr Oliinyk",
9
9
  "homepage_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
10
10
  "repository_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "joplin-plugin-my-calendar",
3
- "version": "1.2.7",
3
+ "version": "1.3.0",
4
4
  "description": "Calendar plugin for Joplin",
5
5
  "author": "Volodymyr Oliinyk",
6
6
  "license": "MIT",
@@ -2,9 +2,9 @@
2
2
  "manifest_version": 1,
3
3
  "id": "com.volodymyroliinyk.joplin.plugin.my-calendar",
4
4
  "app_min_version": "3.3",
5
- "version": "1.2.7",
5
+ "version": "1.3.0",
6
6
  "name": "My Calendar",
7
- "description": "Calendar view from notes with event syntax",
7
+ "description": "Calendar plugin for Joplin",
8
8
  "author": "Volodymyr Oliinyk",
9
9
  "homepage_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",
10
10
  "repository_url": "https://github.com/volodymyroliinyk/joplin-plugin-my-calendar",