diff --git a/src/views/CalendarView.ts b/src/views/CalendarView.ts index 540eb8a..a0fc33a 100644 --- a/src/views/CalendarView.ts +++ b/src/views/CalendarView.ts @@ -1,4 +1,4 @@ -import { ItemView, WorkspaceLeaf, Notice, TFile, DropdownComponent } from "obsidian"; +import { ItemView, WorkspaceLeaf, Notice, TFile, DropdownComponent, setIcon, Menu, MenuItem } from "obsidian"; import { CalendarEvent } from "../services/CalendarService"; import MemoChron from "../main"; import { MEMOCHRON_VIEW_TYPE } from "../utils/constants"; @@ -164,7 +164,7 @@ export class CalendarView extends ItemView { // Apply saved height if (this.plugin.settings.calendarHeight) { - this.calendar.style.height = `${this.plugin.settings.calendarHeight}px`; + this.calendar.style.height = `${this.plugin.settings.calendarHeight} px`; } // Create resize handle @@ -190,57 +190,74 @@ export class CalendarView extends ItemView { // Create navigation container const nav = controls.createEl("div", { cls: "memochron-nav" }); - // Add toggle button at the start of nav - const toggleBtn = nav.createEl("div", { - cls: "memochron-nav-link memochron-toggle-btn", - attr: { "aria-label": "Toggle calendar" } - }); - this.updateToggleButtonIcon(toggleBtn); - - toggleBtn.onclick = async () => { - await this.plugin.toggleCalendar(); - this.updateToggleButtonIcon(toggleBtn); - }; - nav.createEl("span", { cls: "memochron-title" }); - new DropdownComponent(controls) - .addOption("month", "Month") - .addOption("1", "1 Week") - .addOption("2", "2 Weeks") - .addOption("3", "3 Weeks") - .addOption("4", "4 Weeks") - .addOption("5", "5 Weeks") - .setValue(String(this.viewMode)) - .onChange(async (value) => { - this.viewMode = (value === 'month' ? 'month' : parseInt(value)) as CalendarViewMode; - await this.refreshEvents(); - }); + // View Options Button (Menu) + const viewOptionsBtn = controls.createEl("div", { + cls: "memochron-nav-link clickable-icon", + attr: { "aria-label": "View options" } + }); + setIcon(viewOptionsBtn, "layout-grid"); + + viewOptionsBtn.onclick = (e: MouseEvent) => { + this.showViewMenu(e, viewOptionsBtn); + }; const navButtons = nav.createEl("div", { cls: "memochron-nav-buttons" }); - this.createNavButton(navButtons, "<", () => this.navigate(-1)); - this.createNavButton(navButtons, "Today", () => this.goToToday()); - this.createNavButton(navButtons, ">", () => this.navigate(1)); + this.createNavButton(navButtons, "chevron-left", () => this.navigate(-1), true); + this.createNavButton(navButtons, "Today", () => this.goToToday(), false); + this.createNavButton(navButtons, "chevron-right", () => this.navigate(1), true); return controls; } - private updateToggleButtonIcon(btn: HTMLElement) { - const isHidden = this.plugin.settings.hideCalendar; - btn.textContent = isHidden ? "Show" : "Hide"; - // You could use icons here if preferred, e.g.: - // setIcon(btn, isHidden ? "eye" : "eye-off"); + private showViewMenu(event: MouseEvent, target: HTMLElement) { + const menu = new Menu(); + + const addOption = (label: string, value: CalendarViewMode) => { + menu.addItem((item: MenuItem) => { + item + .setTitle(label) + .setChecked(this.viewMode === value) + .onClick(async () => { + if (this.viewMode !== value) { + this.viewMode = value; + await this.refreshEvents(); + } + }); + }); + }; + + addOption("Month", "month"); + menu.addSeparator(); + addOption("1 Week", 1); + addOption("2 Weeks", 2); + addOption("3 Weeks", 3); + addOption("4 Weeks", 4); + addOption("5 Weeks", 5); + + menu.showAtMouseEvent(event); } + private createNavButton( parent: HTMLElement, - text: string, - onClick: () => void + content: string, + onClick: () => void, + isIcon: boolean ) { - const button = parent.createEl("span", { - text, - cls: "memochron-nav-link", + const button = parent.createEl("div", { + cls: "memochron-nav-link clickable-icon", // clickable-icon gives standard Obsidian icon behavior + attr: { "aria-label": isIcon ? (content === "chevron-left" ? "Previous" : "Next") : content } }); + + if (isIcon) { + setIcon(button, content); + } else { + button.setText(content); + button.addClass("text-button"); // Helper class for text buttons + } + button.onclick = onClick; } @@ -740,10 +757,7 @@ export class CalendarView extends ItemView { eventEl.createEl("div", { cls: "memochron-event-time", - text: `${event.start.toLocaleTimeString( - [], - timeFormat - )} - ${event.end.toLocaleTimeString([], timeFormat)}`, + text: `${event.start.toLocaleTimeString([], timeFormat)} - ${event.end.toLocaleTimeString([], timeFormat)}`, }); } } @@ -831,46 +845,22 @@ export class CalendarView extends ItemView { const controls = this.containerEl.querySelector( ".memochron-controls" ) as HTMLElement; - const navTitle = controls?.querySelector(".memochron-title") as HTMLElement; - const navButtons = controls?.querySelector(".memochron-nav-buttons") as HTMLElement; - const toggleBtn = controls?.querySelector(".memochron-toggle-btn") as HTMLElement; if (this.plugin.settings.hideCalendar) { this.calendar.style.display = "none"; if (this.resizeHandle) this.resizeHandle.style.display = "none"; - - // Hide nav elements but keep the toggle button visible - if (navTitle) navTitle.style.display = "none"; - if (navButtons) navButtons.style.display = "none"; if (controls) { - controls.style.display = ""; // Ensure controls container is visible - controls.classList.add("calendar-hidden"); - const dropdown = controls.querySelector("select"); - if (dropdown) dropdown.style.display = "none"; + controls.style.display = "none"; } - this.agenda.classList.add("agenda-only"); } else { this.calendar.style.display = ""; if (this.resizeHandle) this.resizeHandle.style.display = ""; - - // Show nav elements - if (navTitle) navTitle.style.display = ""; - if (navButtons) navButtons.style.display = ""; if (controls) { controls.style.display = ""; - controls.classList.remove("calendar-hidden"); - const dropdown = controls.querySelector("select"); - if (dropdown) dropdown.style.display = ""; } - this.agenda.classList.remove("agenda-only"); } - - // Update the button text/state - if (toggleBtn) { - this.updateToggleButtonIcon(toggleBtn); - } } private setupDragAndDrop() { diff --git a/styles.css b/styles.css index ea59c2a..510966b 100644 --- a/styles.css +++ b/styles.css @@ -22,13 +22,14 @@ overflow: hidden; } +/* Controls */ /* Controls */ .memochron-controls { display: flex; justify-content: space-between; align-items: center; - margin-bottom: var(--memochron-padding-sm); - padding: var(--memochron-padding-sm); + margin-bottom: var(--size-4-1); + padding: var(--size-4-1); } .memochron-nav { @@ -41,36 +42,44 @@ .memochron-nav-buttons { display: flex; align-items: center; - gap: var(--memochron-gap); + gap: var(--size-4-1); } +/* Ghost button base */ .memochron-nav-link { cursor: pointer; color: var(--text-muted); - font-size: 0.9em; - padding: var(--memochron-padding-xs) var(--memochron-padding-sm); border-radius: var(--radius-s); - transition: - color 0.1s ease, - background-color 0.1s ease; + transition: all 0.1s ease; user-select: none; display: inline-flex; align-items: center; + justify-content: center; + background-color: transparent; + width: 28px; + /* Standard icon button size */ + height: 28px; +} + +/* Specifics for text buttons like "Today" */ +.memochron-nav-link.text-button { + width: auto; + padding: 0 var(--size-4-2); + font-size: 0.85em; + font-weight: 500; } .memochron-nav-link:hover, .memochron-nav-link:focus { color: var(--text-normal); background-color: var(--background-modifier-hover); - outline: 2px solid var(--interactive-accent); - outline-offset: 1px; } .memochron-title { - font-size: 0.9em; + font-size: 1em; color: var(--text-normal); - font-weight: 500; - margin: 0 var(--memochron-padding-sm); + font-weight: 600; + margin: 0 var(--size-4-2); } /* Month View */ @@ -89,28 +98,30 @@ display: flex; align-items: center; justify-content: center; - font-size: 0.8em; - color: var(--text-muted); - background-color: var(--background-secondary); - border-radius: var(--radius-s); + font-size: 0.75em; + color: var(--text-faint); + background-color: transparent; margin: 1px; } .memochron-weekday.week-number-header { color: var(--text-faint); - font-size: 0.8em; + font-size: 0.75em; } .memochron-weekday { - padding: var(--memochron-padding-xs); + padding: var(--size-4-1); text-align: center; color: var(--text-muted); - font-size: 0.95em; + font-size: 0.8em; + text-transform: uppercase; + letter-spacing: 0.05em; + font-weight: 500; } .memochron-day { min-height: 2rem; - padding: var(--memochron-padding-xs); + padding: var(--size-4-1); position: relative; cursor: pointer; border-radius: var(--radius-s); @@ -118,14 +129,12 @@ flex-direction: column; align-items: center; background-color: transparent; - transition: - background-color 0.1s ease-in, - color 0.1s ease-in; + transition: background-color 0.1s ease-in; } .memochron-day:hover, .memochron-day:focus { - background-color: var(--interactive-hover); + background-color: var(--background-modifier-hover); outline: none; } @@ -136,44 +145,41 @@ .memochron-day.selected { background-color: var(--interactive-accent); - box-shadow: inset 0 0 0 1px var(--background-modifier-border); } /* Important: Always ensure text is visible on selected days */ .memochron-day.selected .memochron-day-header { color: var(--text-on-accent) !important; - /* Use !important to override any theme styles */ font-weight: 600; } .memochron-day.selected .memochron-event-dot { - color: var(--text-on-accent); -} - -.memochron-day.today { - border: 1px solid var(--interactive-accent); + opacity: 0.8; + /* Slight contrast on accent background */ } .memochron-day.today .memochron-day-header { - color: var(--color-text-today); + color: var(--interactive-accent); + font-weight: 700; } .memochron-day-header { - font-size: 1em; - color: var(--text-muted); + font-size: 0.95em; + color: var(--text-normal); transition: color 0.1s ease-in; } .memochron-day.has-events .memochron-day-header { - color: var(--color-text-day); + color: var(--text-normal); } .memochron-event-dot { - width: 6px; - height: 6px; + width: 4px; + height: 4px; border-radius: 50%; - background-color: var(--interactive-accent); - margin-bottom: 2px; + background-color: var(--text-muted); + /* Default to muted if no color */ + margin-bottom: 1px; } /* Colored dots container */ @@ -192,10 +198,7 @@ margin-bottom: 0; } -/* Daily note dot styling */ -.memochron-event-dot.daily-note-dot { - /* Ensure it looks the same as others */ -} +/* Daily note dot styling - inherits common dot styles */ /* Make daily note dot slightly larger when it's the only dot */ .memochron-event-dots-container:has(.daily-note-dot):not( :has(.memochron-event-dot:not(.daily-note-dot))) .daily-note-dot { @@ -318,8 +321,7 @@ } .memochron-controls.calendar-hidden { - /* display: none; <-- We want to keep this visible for the toggle button */ - display: flex; + display: none; } .memochron-agenda h3 { @@ -372,10 +374,7 @@ color: var(--text-muted); } -/* Daily note entry styling */ -.memochron-agenda-event.memochron-daily-note { - /* Keep the same background as regular events */ -} + /* Color picker styles */ .memochron-color-button { @@ -1132,14 +1131,6 @@ margin: var(--size-4-3) 0; } -/* Toggle Button */ -.memochron-toggle-btn { - font-weight: 500; - min-width: 60px; - /* Prevent layout jump */ - justify-content: center; -} - .memochron-controls.calendar-hidden .memochron-nav { justify-content: flex-start; /* Align left when alone */