diff --git a/settings/settings-tab.ts b/settings/settings-tab.ts index 3fe0d83..fd40c35 100644 --- a/settings/settings-tab.ts +++ b/settings/settings-tab.ts @@ -291,14 +291,8 @@ export class NoteStatusSettingTab extends PluginSettingTab { template.statuses.forEach(status => { const statusEl = statusesEl.createEl('div', { cls: 'template-status-chip' }); - // Create colored dot for the status const colorDot = statusEl.createEl('span', { cls: 'status-color-dot' }); - colorDot.style.display = 'inline-block'; - colorDot.style.width = '8px'; - colorDot.style.height = '8px'; - colorDot.style.borderRadius = '50%'; - colorDot.style.backgroundColor = status.color || '#ffffff'; - colorDot.style.marginRight = '4px'; + colorDot.style.setProperty('--dot-color', status.color || '#ffffff') // Status icon and name statusEl.createSpan({ text: `${status.icon} ${status.name}` }); @@ -307,9 +301,6 @@ export class NoteStatusSettingTab extends PluginSettingTab { // Import/Export buttons for templates const buttonsContainer = containerEl.createDiv({ cls: 'template-buttons' }); - buttonsContainer.style.marginTop = '15px'; - buttonsContainer.style.display = 'flex'; - buttonsContainer.style.gap = '10px'; // Import button const importButton = buttonsContainer.createEl('button', { diff --git a/styles.css b/styles.css index 1998835..b3a66dd 100644 --- a/styles.css +++ b/styles.css @@ -440,6 +440,7 @@ } .status-group .nav-folder-title { + cursor: pointer; padding: var(--size-4-1, 4px) var(--size-4-2, 8px); background: var(--background-secondary-alt); transition: background var(--status-transition-time) var(--ease-out); @@ -1089,6 +1090,8 @@ z-index: 1000; width: 0; height: 0; + left: var(--pos-x-px, 0); + top: var(--pos-y-px, 0); pointer-events: none; } @@ -1107,17 +1110,6 @@ max-height: var(--max-height); } -/* Classes for viewport adjustments */ -.note-status-popover-right { - left: auto !important; - right: calc(1px * (attr(data-offset-right number, 10))); -} - -.note-status-popover-bottom { - top: auto !important; - bottom: calc(1px * (attr(data-offset-bottom number, 10))); -} - /* Since attr() with units doesn't have widespread support yet, we'll add a fallback using CSS variables that can be updated via JS */ .note-status-popover-fixed { @@ -1152,9 +1144,27 @@ /* Fallback positioning for right/bottom adjustments */ .note-status-popover-right { + left: auto !important; right: var(--right-offset-px, 10px); } .note-status-popover-bottom { + top: auto !important; bottom: var(--bottom-offset-px, 10px); -} \ No newline at end of file +} + +.status-color-dot { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + background-color: var(--dot-color, #ffffff); + margin-right: 4px; +} + +.template-buttons { + margin-top: 15px; + display: flex; + gap: 10px; +} + diff --git a/ui/components/status-dropdown-component.ts b/ui/components/status-dropdown-component.ts index 54b1a42..7b86ca8 100644 --- a/ui/components/status-dropdown-component.ts +++ b/ui/components/status-dropdown-component.ts @@ -527,10 +527,9 @@ export class StatusDropdownComponent { private positionAt(x: number, y: number): void { if (!this.dropdownElement) return; - this.dropdownElement.style.position = 'fixed'; - this.dropdownElement.style.zIndex = '999'; - this.dropdownElement.style.left = `${x}px`; - this.dropdownElement.style.top = `${y}px`; + this.dropdownElement.addClass('note-status-popover-fixed'); + this.dropdownElement.style.setProperty('--pos-x-px', `${x}px`); + this.dropdownElement.style.setProperty('--pos-y-px', `${y}px`); // Ensure dropdown doesn't go off-screen setTimeout(() => this.adjustPositionToViewport(), 0); @@ -545,16 +544,22 @@ export class StatusDropdownComponent { const rect = this.dropdownElement.getBoundingClientRect(); if (rect.right > window.innerWidth) { - this.dropdownElement.style.left = `${window.innerWidth - rect.width - 10}px`; + this.dropdownElement.addClass('note-status-popover-right'); + this.dropdownElement.style.setProperty('--right-offset-px', '10px'); + } else { + this.dropdownElement.removeClass('note-status-popover-right'); } if (rect.bottom > window.innerHeight) { - this.dropdownElement.style.top = `${window.innerHeight - rect.height - 10}px`; + this.dropdownElement.addClass('note-status-popover-bottom'); + this.dropdownElement.style.setProperty('--bottom-offset-px', '10px'); + } else { + this.dropdownElement.removeClass('note-status-popover-bottom'); } // Set max height based on viewport const maxHeight = window.innerHeight - rect.top - 20; - this.dropdownElement.style.maxHeight = `${maxHeight}px`; + this.dropdownElement.style.setProperty('--max-height-px', `${maxHeight}px`); } /** @@ -563,18 +568,17 @@ export class StatusDropdownComponent { private positionRelativeTo(targetEl: HTMLElement): void { if (!this.dropdownElement) return; - // Reset positioning - this.dropdownElement.style.position = 'fixed'; - this.dropdownElement.style.zIndex = '999'; + // Apply positioning class + this.dropdownElement.addClass('note-status-popover-fixed'); // Get target element's position const targetRect = targetEl.getBoundingClientRect(); - // Position below the element - this.dropdownElement.style.top = `${targetRect.bottom + 5}px`; + // Position below the element - using CSS custom properties + this.dropdownElement.style.setProperty('--pos-y-px', `${targetRect.bottom + 5}px`); // Align to left edge of target by default - this.dropdownElement.style.left = `${targetRect.left}px`; + this.dropdownElement.style.setProperty('--pos-x-px', `${targetRect.left}px`); // Check if dropdown would go off-screen setTimeout(() => this.adjustRelativePosition(targetRect), 0); @@ -590,19 +594,23 @@ export class StatusDropdownComponent { if (rect.right > window.innerWidth) { // Align to right edge instead - this.dropdownElement.style.left = 'auto'; - this.dropdownElement.style.right = `${window.innerWidth - targetRect.right}px`; + this.dropdownElement.addClass('note-status-popover-right'); + this.dropdownElement.style.setProperty('--right-offset-px', `${window.innerWidth - targetRect.right}px`); + } else { + this.dropdownElement.removeClass('note-status-popover-right'); } if (rect.bottom > window.innerHeight) { // Position above the element instead - this.dropdownElement.style.top = 'auto'; - this.dropdownElement.style.bottom = `${window.innerHeight - targetRect.top + 5}px`; + this.dropdownElement.addClass('note-status-popover-bottom'); + this.dropdownElement.style.setProperty('--bottom-offset-px', `${window.innerHeight - targetRect.top + 5}px`); + } else { + this.dropdownElement.removeClass('note-status-popover-bottom'); } // Set max height based on viewport const maxHeight = window.innerHeight - rect.top - 20; - this.dropdownElement.style.maxHeight = `${maxHeight}px`; + this.dropdownElement.style.setProperty('--max-height-px', `${maxHeight}px`); } /** diff --git a/ui/components/status-dropdown.ts b/ui/components/status-dropdown.ts index 1ddbfc5..38f67cb 100644 --- a/ui/components/status-dropdown.ts +++ b/ui/components/status-dropdown.ts @@ -283,10 +283,9 @@ export class StatusDropdown { */ private createDummyTarget(position: { x: number, y: number }): HTMLElement { const dummyTarget = document.createElement('div'); - dummyTarget.style.position = 'fixed'; - dummyTarget.style.left = `${position.x}px`; - dummyTarget.style.top = `${position.y}px`; - dummyTarget.style.zIndex = '1000'; + dummyTarget.addClass('note-status-dummy-target'); + dummyTarget.style.setProperty('--pos-x-px', `${position.x}px`); + dummyTarget.style.setProperty('--pos-y-px', `${position.y}px`); document.body.appendChild(dummyTarget); return dummyTarget; } @@ -354,27 +353,27 @@ export class StatusDropdown { new Notice('No files selected'); return; } - + // Determine if we're handling single or multiple files const isSingleFile = files.length === 1; const targetFile = isSingleFile ? files[0] : null; - + // Set target file (if single) or null (if multiple) this.dropdownComponent.setTargetFile(targetFile); - + // Get current statuses if single file, or reset to unknown for multiple const currentStatuses = targetFile ? this.statusService.getFileStatuses(targetFile) : ['unknown']; - + // Update dropdown with current statuses this.dropdownComponent.updateStatuses(currentStatuses); - + // Set custom callback for status changes if provided if (options.onStatusChange) { const originalCallback = this.dropdownComponent.getOnStatusChange(); this.dropdownComponent.setOnStatusChange(options.onStatusChange); - + // Restore original callback after operation setTimeout(() => { this.dropdownComponent.setOnStatusChange(originalCallback); @@ -384,7 +383,7 @@ export class StatusDropdown { this.dropdownComponent.setOnStatusChange(async (statuses) => { if (statuses.length > 0) { await this.statusService.batchUpdateStatuses(files, statuses, options.mode || 'replace'); - + // Dispatch events for UI update window.dispatchEvent(new CustomEvent('note-status:batch-update-complete', { detail: { @@ -397,13 +396,13 @@ export class StatusDropdown { } }); } - + // For dropdown from editor if (options.editor && options.view) { const position = this.getCursorPosition(options.editor, options.view); const dummyTarget = this.createDummyTarget(position); this.dropdownComponent.open(dummyTarget, position); - + // Clean up dummy target setTimeout(() => { if (dummyTarget.parentNode) { @@ -412,7 +411,7 @@ export class StatusDropdown { }, 100); return; } - + // For dropdown from toolbar button if (options.target) { if (options.position) { @@ -427,19 +426,17 @@ export class StatusDropdown { } return; } - + // For direct position (context menus) if (options.position) { const dummyTarget = document.createElement('div'); - dummyTarget.style.position = 'fixed'; - dummyTarget.style.left = `${options.position.x}px`; - dummyTarget.style.top = `${options.position.y}px`; - dummyTarget.style.width = '0'; - dummyTarget.style.height = '0'; + dummyTarget.addClass('note-status-dummy-target'); + dummyTarget.style.setProperty('--pos-x-px', `${options.position.x}px`); + dummyTarget.style.setProperty('--pos-y-px', `${options.position.y}px`); document.body.appendChild(dummyTarget); - + this.dropdownComponent.open(dummyTarget, options.position); - + // Clean up dummy target setTimeout(() => { if (dummyTarget.parentNode) { @@ -448,20 +445,20 @@ export class StatusDropdown { }, 100); return; } - + // Fallback to center position const center = { x: window.innerWidth / 2, y: window.innerHeight / 3 }; const fallbackTarget = document.createElement('div'); - fallbackTarget.style.position = 'fixed'; - fallbackTarget.style.left = `${center.x}px`; - fallbackTarget.style.top = `${center.y}px`; + fallbackTarget.addClass('note-status-dummy-target'); + fallbackTarget.style.setProperty('--pos-x-px', `${center.x}px`); + fallbackTarget.style.setProperty('--pos-y-px', `${center.y}px`); document.body.appendChild(fallbackTarget); - + this.dropdownComponent.open(fallbackTarget, center); - + // Clean up fallback target setTimeout(() => { if (fallbackTarget.parentNode) { diff --git a/ui/components/status-pane-view.ts b/ui/components/status-pane-view.ts index f045a6e..dfd4da4 100644 --- a/ui/components/status-pane-view.ts +++ b/ui/components/status-pane-view.ts @@ -173,7 +173,6 @@ export class StatusPaneView extends View { }); // Handle collapsing/expanding behavior - titleEl.style.cursor = 'pointer'; const isCollapsed = this.settings.collapsedStatuses[status] ?? false; if (isCollapsed) {