From 2cdf7c0e65d7304bc43f4090aad1c33fdde0a185 Mon Sep 17 00:00:00 2001 From: Marcus Date: Thu, 27 Jun 2024 14:07:45 -0700 Subject: [PATCH] quick tags search mvp --- src/features/quick_tags.css | 36 +++++++++++++++++++++----- src/features/quick_tags.js | 51 +++++++++++++++++++++++++++++++------ 2 files changed, 72 insertions(+), 15 deletions(-) diff --git a/src/features/quick_tags.css b/src/features/quick_tags.css index 6ce55c4ab..76476a7d2 100644 --- a/src/features/quick_tags.css +++ b/src/features/quick_tags.css @@ -8,7 +8,6 @@ align-items: stretch; width: 250px; max-height: 250px; - overflow-y: auto; padding: 2px; border-radius: 3px; @@ -21,13 +20,22 @@ font-weight: normal; } -#quick-tags-post-option.below { +.quick-tags-popup .bundle-buttons { + display: flex; + flex-direction: column; + overflow-y: auto; + + color: inherit; + font: inherit; +} + +#quick-tags-post-option[data-position="below"] { top: 100%; right: 50%; transform: translate(50%, 12px); } -#quick-tags-post-option.above { +#quick-tags-post-option[data-position="above"] { bottom: 100%; right: 50%; transform: translate(50%, -12px); @@ -43,11 +51,11 @@ } @media (min-width: 650px) { - #quick-tags.below { + #quick-tags[data-position="below"] { inset: 100% 50% auto auto; transform: translate(50%, var(--icon-spacing)); } - #quick-tags.above { + #quick-tags[data-position="above"] { inset: auto 50% 100% auto; transform: translate(50%, calc(0px - var(--icon-spacing))); } @@ -78,7 +86,7 @@ margin: 2px 0; } -#quick-tags input { +.quick-tags-popup input { box-sizing: border-box; width: 0; min-width: 100%; @@ -96,7 +104,7 @@ #quick-tags-post-option button { padding: 1ch; - background-color: inherit; + background-color: rgb(var(--white)); color: inherit; font: inherit; text-align: initial; @@ -107,6 +115,20 @@ margin-bottom: 2px; } +.quick-tags-popup button.search-hidden { + display: none; +} + +.quick-tags-popup .no-results { + display: none; + justify-content: center; + align-items: center; +} + +.quick-tags-popup .bundle-buttons:has(> button):not(:has(> button:not(.search-hidden))) + .no-results { + display: flex; +} + .xkit-quick-tags-tags { position: relative; diff --git a/src/features/quick_tags.js b/src/features/quick_tags.js index ec4f1f109..5f0ee4068 100644 --- a/src/features/quick_tags.js +++ b/src/features/quick_tags.js @@ -23,10 +23,11 @@ let autoTagAsker; let controlButtonTemplate; -const popupElement = dom('div', { id: 'quick-tags' }); +const popupElement = dom('div', { id: 'quick-tags', class: 'quick-tags-popup' }); const popupInput = dom( 'input', { + class: 'input', placeholder: 'Tags (comma separated)', autocomplete: 'off' }, @@ -53,23 +54,57 @@ const checkLength = ({ currentTarget }) => { popupInput.addEventListener('input', checkLength); const popupForm = dom('form', null, { submit: event => event.preventDefault() }, [popupInput]); -const postOptionPopupElement = dom('div', { id: 'quick-tags-post-option' }); +const postOptionPopupElement = dom('div', { id: 'quick-tags-post-option', class: 'quick-tags-popup' }); const storageKey = 'quick_tags.preferences.tagBundles'; let editedTagsMap = new WeakMap(); -const createBundleButton = tagBundle => { +const createBundleButtons = tagBundles => dom('div', { class: 'bundle-buttons' }, null, tagBundles.map(tagBundle => { const bundleButton = dom('button', null, null, [tagBundle.title]); bundleButton.dataset.tags = tagBundle.tags; return bundleButton; -}; +})); + +const searchElements = bundleCount => + bundleCount > 4 + ? [ + dom('div', { class: 'no-results' }, null, [ + dom('p', null, null, ['No results found.']) + ]), + dom( + 'input', + { + class: 'search', + type: 'text', + placeholder: 'Search', + autocomplete: 'off', + spellcheck: 'false' + }, + { + input: event => { + const query = event.currentTarget.value.toLowerCase(); + [...event.currentTarget.closest('.quick-tags-popup').querySelectorAll('button')].forEach(bundleButton => { + if ( + bundleButton.textContent.toLowerCase().includes(query) || + bundleButton.dataset.tags.toLowerCase().includes(query) + ) { + bundleButton.classList.remove('search-hidden'); + } else { + bundleButton.classList.add('search-hidden'); + } + }); + } + } + ) + ] + : []; const populatePopups = async function () { const { [storageKey]: tagBundles = [] } = await browser.storage.local.get(storageKey); - popupElement.replaceChildren(popupForm, ...tagBundles.map(createBundleButton)); - postOptionPopupElement.replaceChildren(...tagBundles.map(createBundleButton)); + popupElement.replaceChildren(popupForm, createBundleButtons(tagBundles), ...searchElements(tagBundles.length)); + postOptionPopupElement.replaceChildren(createBundleButtons(tagBundles), ...searchElements(tagBundles.length)); }; const processPostForm = async function ([selectedTagsElement]) { @@ -116,10 +151,10 @@ export const onStorageChanged = async function (changes, areaName) { }; const appendWithoutViewportOverflow = (element, target) => { - element.className = 'below'; + element.dataset.position = 'below'; target.appendChild(element); if (element.getBoundingClientRect().bottom > document.documentElement.clientHeight) { - element.className = 'above'; + element.dataset.position = 'above'; } };