diff --git a/main_src.js b/main_src.js index f08790a..b8a7f1e 100644 --- a/main_src.js +++ b/main_src.js @@ -1,4 +1,4 @@ -const { Plugin, ItemView, TFolder, TFile, Setting, Menu, setIcon } = require('obsidian'); +const { Plugin, ItemView, Modal, TFolder, TFile, PluginSettingTab, Setting, Menu, setIcon, getLanguage, getFrontMatterInfo } = require('obsidian'); // 語系檔案 const TRANSLATIONS = { @@ -64,13 +64,13 @@ const TRANSLATIONS = { // Buttons and Labels 'sorting': 'Sort by', 'refresh': 'Refresh', - 'reselect_folder': 'Reselect Folder', + 'reselect_folder': 'Reselect folder', 'go_up': 'Go Up', - 'no_backlinks': 'No Backlinks', + 'no_backlinks': 'No backlinks', 'search': 'Search', 'search_placeholder': 'Search keyword', 'cancel': 'Cancel', - 'new_note': 'New Note', + 'new_note': 'New note', 'untitled': 'Untitled', 'notes': 'Notes', @@ -78,39 +78,39 @@ const TRANSLATIONS = { 'grid_view_title': 'Grid View', 'bookmarks_mode': 'Bookmarks', 'folder_mode': 'Folder', - 'search_results': 'Search Results', + 'search_results': 'Search results', 'backlinks_mode': 'Backlinks', - 'all_notes_mode': 'All Notes', + 'all_notes_mode': 'All notes', // Sort Options 'sort_name_asc': 'Name (A → Z)', 'sort_name_desc': 'Name (Z → A)', - 'sort_mtime_desc': 'Modified Time (New → Old)', - 'sort_mtime_asc': 'Modified Time (Old → New)', - 'sort_ctime_desc': 'Created Time (New → Old)', - 'sort_ctime_asc': 'Created Time (Old → New)', + 'sort_mtime_desc': 'Modified time (New → Old)', + 'sort_mtime_asc': 'Modified time (Old → New)', + 'sort_ctime_desc': 'Created time (New → Old)', + 'sort_ctime_asc': 'Created time (Old → New)', 'sort_random': 'Random', // Settings - 'grid_view_settings': 'Grid View Settings', - 'ignored_folders': 'Ignored Folders', + 'grid_view_settings': 'Grid view settings', + 'ignored_folders': 'Ignored folders', 'ignored_folders_desc': 'Set folders to be ignored (one path per line)', 'ignored_folders_placeholder': 'Example:\n.obsidian\nTemplates', - 'default_sort_type': 'Default Sort Type', + 'default_sort_type': 'Default sort type', 'default_sort_type_desc': 'Set the default sorting method when opening Grid View', - 'grid_item_width': 'Grid Item Width', + 'grid_item_width': 'Grid item width', 'grid_item_width_desc': 'Set the width of grid items', - 'image_area_width': 'Image Area Width', + 'image_area_width': 'Image area width', 'image_area_width_desc': 'Set the width of the image preview area', - 'image_area_height': 'Image Area Height', + 'image_area_height': 'Image area height', 'image_area_height_desc': 'Set the height of the image preview area', // Folder Selection Dialog - 'select_folders': 'Select Folder', + 'select_folders': 'Select folder', 'open_grid_view': 'Open Grid View', - 'open_in_grid_view': 'Open in Grid View', - 'delete_note': 'Delete Note', - 'open_in_new_tab': 'Open in New Tab', + 'open_in_grid_view': 'Open in grid view', + 'delete_note': 'Delete note', + 'open_in_new_tab': 'Open in new tab', }, 'zh': { // 通知信息 @@ -226,12 +226,11 @@ const TRANSLATIONS = { // 全域翻譯函式 function t(key) { - const langSetting = window.localStorage.getItem('language'); + const langSetting = getLanguage(); const lang = TRANSLATIONS[langSetting] || TRANSLATIONS['en']; return lang[key] || key; } - // 處理媒體連結 function processMediaLink(app, linkText) { // 處理 Obsidian 內部連結 ![[file]] @@ -285,7 +284,7 @@ class GridView extends ItemView { constructor(leaf, plugin) { super(leaf); this.plugin = plugin; - this.containerEl.addClass('grid-view-container'); + this.containerEl.addClass('ge-grid-view-container'); this.sourceMode = ''; // 預設為書籤模式 this.sourcePath = null; // 用於資料夾模式的路徑 this.sortType = this.plugin.settings.defaultSortType; // 使用設定中的預設排序模式 @@ -323,6 +322,8 @@ class GridView extends ItemView { this.sourceMode = mode; this.sourcePath = path; this.render(); + // 通知 Obsidian 保存視圖狀態 + this.app.workspace.requestSaveLayout(); } async getFiles() { @@ -422,7 +423,7 @@ class GridView extends ItemView { return files; } - //忽略設定內指定的資料夾 + //忽略檔案 ignoredFiles(files) { return files.filter(file => !this.plugin.settings.ignoredFolders.some(folder => file.path.startsWith(`${folder}/`))); } @@ -436,7 +437,7 @@ class GridView extends ItemView { this.containerEl.empty(); // 創建頂部按鈕區域 - const headerButtonsDiv = this.containerEl.createDiv('header-buttons'); + const headerButtonsDiv = this.containerEl.createDiv('ge-header-buttons'); // 添加新增筆記按鈕 if (this.sourceMode === 'folder' && this.searchQuery === '') { @@ -483,7 +484,7 @@ class GridView extends ItemView { // 添加重新選擇資料夾按鈕 const reselectButton = headerButtonsDiv.createEl('button', { attr: { 'aria-label': t('reselect_folder') } }); reselectButton.addEventListener('click', () => { - showFolderSelectionModal(this.app, this.plugin, this); + showFolderSelectionModal(this.app, this, this); }); setIcon(reselectButton, "folder"); @@ -518,6 +519,8 @@ class GridView extends ItemView { .onClick(() => { this.sortType = option.value; this.render(); + // 通知 Obsidian 保存視圖狀態 + this.app.workspace.requestSaveLayout(); }); }); }); @@ -527,7 +530,7 @@ class GridView extends ItemView { } // 添加搜尋按鈕 - const searchButtonContainer = headerButtonsDiv.createDiv('search-button-container'); + const searchButtonContainer = headerButtonsDiv.createDiv('ge-search-button-container'); // 搜尋按鈕 const searchButton = searchButtonContainer.createEl('button', { @@ -543,10 +546,10 @@ class GridView extends ItemView { // 如果有搜尋關鍵字,顯示搜尋文字和取消按鈕 if (this.searchQuery) { searchButton.style.display = 'none'; - const searchTextContainer = searchButtonContainer.createDiv('search-text-container'); + const searchTextContainer = searchButtonContainer.createDiv('ge-search-text-container'); // 創建取消按鈕 - const clearButton = searchTextContainer.createDiv('clear-button'); + const clearButton = searchTextContainer.createDiv('ge-clear-button'); setIcon(clearButton, 'x'); clearButton.addEventListener('click', (e) => { e.stopPropagation(); // 防止觸發搜尋文字的點擊事件 @@ -554,8 +557,7 @@ class GridView extends ItemView { this.render(); }); - const searchText = searchTextContainer.createSpan('search-text'); - searchText.textContent = this.searchQuery; + const searchText = searchTextContainer.createEl('span', { text: this.searchQuery, cls: 'ge-search-text' }); // 讓搜尋文字可點選 searchText.style.cursor = 'pointer'; searchText.addEventListener('click', () => { @@ -579,7 +581,7 @@ class GridView extends ItemView { async grid_render() { const container = this.containerEl.children[1]; container.empty(); - container.addClass('grid-container'); + container.addClass('ge-grid-container'); container.style.setProperty('--grid-item-width', this.plugin.settings.gridItemWidth + 'px'); container.style.setProperty('--image-area-width', this.plugin.settings.imageAreaWidth + 'px'); container.style.setProperty('--image-area-height', this.plugin.settings.imageAreaHeight + 'px'); @@ -612,11 +614,10 @@ class GridView extends ItemView { .sort((a, b) => a.name.localeCompare(b.name)); for (const folder of subfolders) { - const folderEl = container.createDiv('grid-item folder-item'); + const folderEl = container.createDiv('ge-grid-item ge-folder-item'); - const contentArea = folderEl.createDiv('content-area'); - const titleEl = contentArea.createEl('h3'); - titleEl.textContent = `📁 ${folder.name}`; + const contentArea = folderEl.createDiv('ge-content-area'); + const titleEl = contentArea.createEl('h3', { text: `📁 ${folder.name}` }); // 點擊時進入子資料夾 folderEl.addEventListener('click', () => { @@ -660,13 +661,14 @@ class GridView extends ItemView { const file = noteEl.file; // 載入預覽內容 - const contentArea = noteEl.querySelector('.content-area'); + const contentArea = noteEl.querySelector('.ge-content-area'); if (!contentArea.hasAttribute('data-loaded')) { const content = await this.app.vault.cachedRead(file); - // 移除 frontmatter 區域,並移除內部連結和圖片連結 - const contentWithoutFrontmatter = content.replace(/^---\n[\s\S]*?\n---\n|`{3}[\s\S]*?`{3}||(!?\[([^\]]*)\]\(([^)]+)\))|!?\[\[([^\]]+)\]\]/g, ''); + const frontMatterInfo = getFrontMatterInfo(content); + const contentWithoutFrontmatter = content.substring(frontMatterInfo.contentStart); + const contentWithoutMediaLinks = contentWithoutFrontmatter.replace(/^`{3}[\s\S]*?`{3}||(!?\[([^\]]*)\]\(([^)]+)\))|!?\[\[([^\]]+)\]\]/g, ''); // 只取前100個字符作為預覽 - const preview = contentWithoutFrontmatter.slice(0, 100) + (contentWithoutFrontmatter.length > 100 ? '...' : ''); + const preview = contentWithoutMediaLinks.slice(0, 100) + (contentWithoutMediaLinks.length > 100 ? '...' : ''); // 創建預覽內容 const contentEl = contentArea.createEl('p', { text: preview.trim() }); @@ -674,7 +676,7 @@ class GridView extends ItemView { } // 載入圖片 - const imageArea = noteEl.querySelector('.image-area'); + const imageArea = noteEl.querySelector('.ge-image-area'); if (!imageArea.hasAttribute('data-loaded')) { const imageUrl = await findFirstImageInNote(this.app, file); if (imageUrl) { @@ -699,17 +701,17 @@ class GridView extends ItemView { // 顯示筆記 for (const file of files) { - const noteEl = container.createDiv('grid-item'); + const noteEl = container.createDiv('ge-grid-item'); noteEl.file = file; // 儲存檔案引用以供後續使用 // 創建左側內容區,但先只放標題 - const contentArea = noteEl.createDiv('content-area'); + const contentArea = noteEl.createDiv('ge-content-area'); // 創建標題(立即載入) const titleEl = contentArea.createEl('h3', { text: file.basename }); // 創建圖片區域,但先不載入圖片 - const imageArea = noteEl.createDiv('image-area'); + const imageArea = noteEl.createDiv('ge-image-area'); // 開始觀察這個筆記元素 observer.observe(noteEl); @@ -746,7 +748,7 @@ class GridView extends ItemView { .setTitle(t('delete_note')) .setIcon('trash') .onClick(async () => { - await this.app.vault.trash(file, false); + await this.app.fileManager.trashFile(file); }); }); menu.showAtMouseEvent(event); @@ -760,8 +762,6 @@ class GridView extends ItemView { // 顯示搜尋 modal showSearchModal(defaultQuery = '') { - const { Modal } = require('obsidian'); - class SearchModal extends Modal { constructor(app, gridView, defaultQuery) { super(app); @@ -775,7 +775,7 @@ class GridView extends ItemView { contentEl.createEl('h2', { text: t('search') }); // 創建搜尋輸入框容器 - const searchContainer = contentEl.createDiv('search-container'); + const searchContainer = contentEl.createDiv('ge-search-container'); // 創建搜尋輸入框 const searchInput = searchContainer.createEl('input', { @@ -785,7 +785,7 @@ class GridView extends ItemView { }); // 創建清空按鈕 - const clearButton = searchContainer.createDiv('search-clear-button'); + const clearButton = searchContainer.createDiv('ge-search-clear-button'); clearButton.style.display = this.defaultQuery ? 'flex' : 'none'; setIcon(clearButton, 'x'); @@ -802,7 +802,7 @@ class GridView extends ItemView { }); // 創建按鈕容器 - const buttonContainer = contentEl.createDiv('button-container'); + const buttonContainer = contentEl.createDiv('ge-button-container'); // 創建搜尋按鈕 const searchButton = buttonContainer.createEl('button', { @@ -818,6 +818,8 @@ class GridView extends ItemView { const performSearch = () => { this.gridView.searchQuery = searchInput.value; this.gridView.render(); + // 通知 Obsidian 保存視圖狀態 + this.gridView.app.workspace.requestSaveLayout(); this.close(); }; @@ -927,7 +929,7 @@ const DEFAULT_SETTINGS = { }; // 設定頁面類別 -class GridExplorerSettingTab extends require('obsidian').PluginSettingTab { +class GridExplorerSettingTab extends PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.plugin = plugin; @@ -937,7 +939,8 @@ class GridExplorerSettingTab extends require('obsidian').PluginSettingTab { const { containerEl } = this; containerEl.empty(); - containerEl.createEl('h2', { text: t('grid_view_settings') }); + // 等到有不同分類的設定再使用 + //containerEl.createEl('h2', { text: t('grid_view_settings') }); // 忽略的資料夾設定 new Setting(containerEl) @@ -1016,8 +1019,6 @@ class GridExplorerSettingTab extends require('obsidian').PluginSettingTab { // 顯示資料夾選擇 modal async function showFolderSelectionModal(app, plugin, activeView = null) { - const { Modal, TFolder } = require('obsidian'); - class FolderSelectionModal extends Modal { constructor(app, plugin, activeView) { super(app); @@ -1034,14 +1035,9 @@ async function showFolderSelectionModal(app, plugin, activeView = null) { const bookmarksPlugin = this.app.internalPlugins.plugins.bookmarks; if (bookmarksPlugin?.enabled) { const bookmarkOption = contentEl.createEl('div', { - cls: 'grid-view-folder-option', + cls: 'ge-grid-view-folder-option', text: `📑 ${t('bookmarks_mode')}` }); - bookmarkOption.style.cursor = 'pointer'; - bookmarkOption.style.padding = '8px'; - bookmarkOption.style.marginBottom = '8px'; - bookmarkOption.style.border = '1px solid var(--background-modifier-border)'; - bookmarkOption.style.borderRadius = '4px'; bookmarkOption.addEventListener('click', () => { if (this.activeView) { @@ -1051,14 +1047,6 @@ async function showFolderSelectionModal(app, plugin, activeView = null) { } this.close(); }); - - bookmarkOption.addEventListener('mouseenter', () => { - bookmarkOption.style.backgroundColor = 'var(--background-modifier-hover)'; - }); - - bookmarkOption.addEventListener('mouseleave', () => { - bookmarkOption.style.backgroundColor = ''; - }); } // 建立搜尋結果選項 @@ -1069,14 +1057,9 @@ async function showFolderSelectionModal(app, plugin, activeView = null) { if(searchInput) { if (searchInput.value.trim().length > 0) { const searchOption = contentEl.createEl('div', { - cls: 'grid-view-folder-option', + cls: 'ge-grid-view-folder-option', text: `🔍 ${t('search_results')}: ${searchInput.value}` }); - searchOption.style.cursor = 'pointer'; - searchOption.style.padding = '8px'; - searchOption.style.marginBottom = '8px'; - searchOption.style.border = '1px solid var(--background-modifier-border)'; - searchOption.style.borderRadius = '4px'; searchOption.addEventListener('click', () => { if (this.activeView) { @@ -1086,14 +1069,6 @@ async function showFolderSelectionModal(app, plugin, activeView = null) { } this.close(); }); - - searchOption.addEventListener('mouseenter', () => { - searchOption.style.backgroundColor = 'var(--background-modifier-hover)'; - }); - - searchOption.addEventListener('mouseleave', () => { - searchOption.style.backgroundColor = ''; - }); } } } @@ -1103,14 +1078,9 @@ async function showFolderSelectionModal(app, plugin, activeView = null) { if (activeFile) { const activeFileName = activeFile ? `: ${activeFile.basename}` : ''; const backlinksOption = contentEl.createEl('div', { - cls: 'grid-view-folder-option', + cls: 'ge-grid-view-folder-option', text: `🔗 ${t('backlinks_mode')}${activeFileName}` }); - backlinksOption.style.cursor = 'pointer'; - backlinksOption.style.padding = '8px'; - backlinksOption.style.marginBottom = '8px'; - backlinksOption.style.border = '1px solid var(--background-modifier-border)'; - backlinksOption.style.borderRadius = '4px'; backlinksOption.addEventListener('click', () => { if (this.activeView) { @@ -1120,27 +1090,14 @@ async function showFolderSelectionModal(app, plugin, activeView = null) { } this.close(); }); - - backlinksOption.addEventListener('mouseenter', () => { - backlinksOption.style.backgroundColor = 'var(--background-modifier-hover)'; - }); - - backlinksOption.addEventListener('mouseleave', () => { - backlinksOption.style.backgroundColor = ''; - }); } // 建立所有筆記選項 const allNotesOption = contentEl.createEl('div', { - cls: 'grid-view-folder-option', + cls: 'ge-grid-view-folder-option', text: `📔 ${t('all_notes_mode')}` }); - allNotesOption.style.cursor = 'pointer'; - allNotesOption.style.padding = '8px'; - allNotesOption.style.marginBottom = '8px'; - allNotesOption.style.border = '1px solid var(--background-modifier-border)'; - allNotesOption.style.borderRadius = '4px'; allNotesOption.addEventListener('click', () => { if (this.activeView) { @@ -1151,36 +1108,37 @@ async function showFolderSelectionModal(app, plugin, activeView = null) { this.close(); }); - allNotesOption.addEventListener('mouseenter', () => { - allNotesOption.style.backgroundColor = 'var(--background-modifier-hover)'; + // 建立根目錄選項 + const rootFolderOption = contentEl.createEl('div', { + cls: 'ge-grid-view-folder-option', + text: `📁 /` }); - allNotesOption.addEventListener('mouseleave', () => { - allNotesOption.style.backgroundColor = ''; + rootFolderOption.addEventListener('click', () => { + if (this.activeView) { + this.activeView.setSource('folder', '/'); + } else { + this.plugin.activateView('folder', '/'); + } + this.close(); }); // 取得所有資料夾(排除被忽略的資料夾) - const folders = app.vault.getAllLoadedFiles() - .filter(file => { - if (!(file instanceof TFolder)) return false; + const folders = app.vault.getAllFolders() + .filter(folder => { // 檢查資料夾是否在忽略清單中 return !this.plugin.settings.ignoredFolders.some( - ignoredPath => file.path === ignoredPath || file.path.startsWith(ignoredPath + '/') + ignoredPath => folder.path === ignoredPath || folder.path.startsWith(ignoredPath + '/') ); }) .sort((a, b) => a.path.localeCompare(b.path)); - + // 建立資料夾選項 folders.forEach(folder => { const folderOption = contentEl.createEl('div', { - cls: 'grid-view-folder-option', + cls: 'ge-grid-view-folder-option', text: `📁 ${folder.path || '/'}` }); - folderOption.style.cursor = 'pointer'; - folderOption.style.padding = '8px'; - folderOption.style.marginBottom = '8px'; - folderOption.style.border = '1px solid var(--background-modifier-border)'; - folderOption.style.borderRadius = '4px'; folderOption.addEventListener('click', () => { if (this.activeView) { @@ -1190,14 +1148,6 @@ async function showFolderSelectionModal(app, plugin, activeView = null) { } this.close(); }); - - folderOption.addEventListener('mouseenter', () => { - folderOption.style.backgroundColor = 'var(--background-modifier-hover)'; - }); - - folderOption.addEventListener('mouseleave', () => { - folderOption.style.backgroundColor = ''; - }); }); } @@ -1264,7 +1214,6 @@ module.exports = class GridExplorerPlugin extends Plugin { } async onunload() { - this.app.workspace.detachLeavesOfType('grid-view'); } async activateView(mode = 'bookmarks', path = null) { diff --git a/manifest.json b/manifest.json index 6b96f63..c4ac6e3 100644 --- a/manifest.json +++ b/manifest.json @@ -1,8 +1,8 @@ { "id": "gridexplorer", "name": "GridExplorer", - "version": "1.5.0", - "minAppVersion": "0.15.0", + "version": "1.6.0", + "minAppVersion": "1.8.0", "description": "Browse note files in a grid view.", "main": "main.js", "author": "Devon22", diff --git a/styles.css b/styles.css index e4d15f9..ef22694 100644 --- a/styles.css +++ b/styles.css @@ -1,9 +1,23 @@ -.grid-view-container { +.ge-grid-view-container { padding: 0px; height: 100%; } -.grid-container { +/* 選擇資料夾的樣式 */ +.ge-grid-view-folder-option { + cursor: pointer; + padding: 8px; + margin-bottom: 8px; + border: 1px solid var(--background-modifier-border); + border-radius: 4px; +} + +.ge-grid-view-folder-option:hover { + background-color: var(--background-modifier-hover); +} + +/* Grid 樣式 */ +.ge-grid-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--grid-item-width, 300px), 1fr)); gap: 12px; @@ -11,19 +25,16 @@ align-items: start; align-content: start; background: var(--background-secondary) !important; -} - -.is-mobile .grid-container::-webkit-scrollbar { - display: none !important; - width: 0 !important; -} - -.view-content { flex: 1; overflow-y: auto; } -.grid-item { +.is-mobile .ge-grid-container::-webkit-scrollbar { + display: none !important; + width: 0 !important; +} + +.ge-grid-item { background-color: var(--background-primary); border: 1px solid var(--background-modifier-border); border-radius: var(--button-radius); @@ -35,31 +46,31 @@ height: 100%; } -.grid-item:hover { +.ge-grid-item:hover { transform: translateY(-2px); background-color: var(--text-selection); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } -.content-area { +.ge-content-area { flex: 1; min-width: 0; } -.image-area { +.ge-image-area { width: var(--image-area-width); height: var(--image-area-height); flex-shrink: 0; } -.image-area img { +.ge-image-area img { width: 100%; height: 100%; object-fit: cover; border-radius: 4px; } -.grid-item h3 { +.ge-grid-item h3 { margin: 0; font-size: var(--font-text-size); color: var(--text-normal); @@ -68,7 +79,7 @@ white-space: nowrap; } -.grid-item p { +.ge-grid-item p { margin: 8px 0 0 0; color: var(--text-faint); font-size: 0.85em; @@ -79,21 +90,21 @@ -webkit-box-orient: vertical; } -.grid-item p:empty { +.ge-grid-item p:empty { margin: 0; } /* 資料夾項目的特殊樣式 */ -.grid-item.folder-item { +.ge-grid-item.ge-folder-item { background-color: var(--background-primary-alt); border: 2px solid var(--background-modifier-border); } -.grid-item.folder-item:hover { +.ge-grid-item.ge-folder-item:hover { background-color: var(--background-modifier-hover); } -.grid-item.folder-item h3 { +.ge-grid-item.ge-folder-item h3 { margin: 0; color: var(--text-normal); display: flex; @@ -102,23 +113,23 @@ } /* 上層資料夾的特殊樣式 */ -.grid-item.parent-folder { +.ge-grid-item.parent-folder { background-color: var(--background-secondary-alt); } -.grid-item.parent-folder:hover { +.ge-grid-item.parent-folder:hover { background-color: var(--background-modifier-hover); } /* 調整資料夾項目的高度 */ -.grid-item.folder-item .content-area { +.ge-grid-item.ge-folder-item .ge-content-area { display: flex; align-items: center; min-height: 0px; } /* 頂部按鈕區域樣式 */ -.header-buttons { +.ge-header-buttons { display: flex; gap: 8px; padding: 12px 16px; @@ -128,7 +139,7 @@ justify-content: center; } -.header-buttons button { +.ge-header-buttons button { display: flex; align-items: center; gap: 4px; @@ -142,33 +153,37 @@ min-width: 38px; } -.header-buttons button:hover { +.is-tablet .ge-header-buttons button:not(.clickable-icon) { + padding: 6px 12px; +} + +.ge-header-buttons button:hover { background-color: var(--interactive-hover); transform: translateY(-1px); } -.header-buttons button:active { +.ge-header-buttons button:active { transform: translateY(0); } /* 特定按鈕樣式 */ -.header-buttons .sort-button, -.header-buttons .reselect-button, -.header-buttons .refresh-button, -.header-buttons .up-button { +.ge-header-buttons .sort-button, +.ge-header-buttons .reselect-button, +.ge-header-buttons .refresh-button, +.ge-header-buttons .up-button { display: inline-flex; align-items: center; } /* 搜尋對話框樣式 */ -.search-container { +.ge-search-container { margin-bottom: 16px; position: relative; display: flex; align-items: center; } -.search-container input { +.ge-search-container input { width: 100%; padding: 8px 12px; border: 1px solid var(--background-modifier-border); @@ -181,21 +196,21 @@ padding-right: 25px; } -.search-container input:focus { +.ge-search-container input:focus { border-color: var(--interactive-accent); } -.search-container input::placeholder { +.ge-search-container input::placeholder { color: var(--text-muted); } -.button-container { +.ge-button-container { display: flex; gap: 8px; justify-content: flex-end; } -.button-container button { +.ge-button-container button { padding: 6px 12px; border-radius: 4px; font-size: 14px; @@ -203,34 +218,34 @@ transition: background-color 0.2s, transform 0.1s; } -.button-container button:first-child { +.ge-button-container button:first-child { background-color: var(--interactive-accent); color: var(--text-on-accent); } -.button-container button:last-child { +.ge-button-container button:last-child { background-color: var(--interactive-normal); color: var(--text-normal); } -.button-container button:hover { +.ge-button-container button:hover { transform: translateY(-1px); } -.button-container button:first-child:hover { +.ge-button-container button:first-child:hover { background-color: var(--interactive-accent-hover); } -.button-container button:last-child:hover { +.ge-button-container button:last-child:hover { background-color: var(--interactive-hover); } -.button-container button:active { +.ge-button-container button:active { transform: translateY(0); } /* 搜尋按鈕容器 */ -.search-button-container { +.ge-search-button-container { display: flex; align-items: center; gap: 8px; @@ -240,13 +255,13 @@ } /* 搜尋按鈕啟用狀態 */ -.search-button-container button.active { +.ge-search-button-container button.active { background-color: var(--interactive-accent); color: var(--text-on-accent); } /* 搜尋文字容器 */ -.search-text-container { +.ge-search-text-container { position: relative; display: inline-block; max-width: 100px; @@ -259,8 +274,12 @@ transition: border-color 0.15s ease; } +.ge-search-text-container:hover { + border-color: var(--interactive-accent); +} + /* 搜尋文字 */ -.search-text { +.ge-search-text { font-size: 14px; color: var(--text-normal); padding: 8px 10px; @@ -268,12 +287,8 @@ align-items: center; } -.search-text-container:hover { - border-color: var(--interactive-accent); -} - /* 取消按鈕 */ -.clear-button { +.ge-clear-button { position: absolute; left: 4px; top: 50%; @@ -289,17 +304,17 @@ font-size: 14px; } -.clear-button:hover { +.ge-clear-button:hover { color: #FFF; background-color: var(--background-modifier-error-hover); } -.clear-button svg { +.ge-clear-button svg { width: 18px; height: 18px; } -.search-clear-button { +.ge-search-clear-button { color: var(--text-muted); border-radius: 50%; width: 18px; @@ -312,7 +327,7 @@ padding: 3px; } -.search-clear-button:hover { +.ge-search-clear-button:hover { color: var(--text-normal); background-color: var(--background-modifier-hover); } \ No newline at end of file