diff --git a/tests/ui/app.spec.js b/tests/ui/app.spec.js index 207752f..f51d07d 100644 --- a/tests/ui/app.spec.js +++ b/tests/ui/app.spec.js @@ -1951,6 +1951,22 @@ test('a page brought back into view catches up with what was read elsewhere', as await expect(badge).toHaveText(String(before - 1)); }); +test('a search box has an x that clears it once something is typed', async ({ page }) => { + // #291: inside the box, at its right end, and the list comes back whole. + const box = page.locator('#feedFilter'); + const x = page.locator('.searchwrap .clearx'); + const all = await page.locator('#feedlist .feed').count(); + await expect(x).toBeHidden(); + await box.fill('zzz-nothing'); + await expect(x).toBeVisible(); + await expect(page.locator('#feedlist .feed')).toHaveCount(0); + await x.click(); + await expect(box).toHaveValue(''); + await expect(box).toBeFocused(); + await expect(x).toBeHidden(); + await expect(page.locator('#feedlist .feed')).toHaveCount(all); +}); + test('a feed\'s settings say what downloads, take words as chips, and keep what is saved', async ({ page }) => { // The redesigned dialog (#167): the download choice, word chips, the fold, and a save that holds. const open = async () => { diff --git a/web/CHANGELOG.md b/web/CHANGELOG.md index 0316ada..1e804d1 100644 --- a/web/CHANGELOG.md +++ b/web/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- A search box has an x at its right end once something is typed in it, which clears it: items, the feed list, the log in Admin and a Signal's icons (#291). - A feed's, an OPML subscription's or a Patreon creator's settings have In All Subscriptions: off keeps its items out of All Subscriptions and its unread count, still there on its own page, in Signals and in Currently Listening (#288). - A feed's settings have a Signals switch beside All Subscriptions, to keep its items out of every Signal (#289). - An item sent as both HTML and Markdown, as Scripting News's are, has a choice beside its buttons to show it as the publisher's HTML or as the Markdown, kept from one item to the next (#285). diff --git a/web/app.css b/web/app.css index 6a1744c..7b9f62e 100644 --- a/web/app.css +++ b/web/app.css @@ -537,7 +537,7 @@ a{color:var(--accent)} position:sticky;top:0; } #topbar .grow{flex:1} -#topbar #epSearch{width:260px;flex:none} +#topbar #epBox{width:260px;flex:none} .tgroup{display:flex;flex:none;border:1px solid var(--line);border-radius:8px;overflow:hidden;background:var(--panel2)} .tgroup button,.tgroup a{padding:5px 11px;min-width:34px;color:var(--dim);font-size:14px;line-height:1.3} .tgroup a{display:inline-grid;place-items:center} @@ -567,6 +567,17 @@ input[type=search],input[type=text],input[type=password],input[type=number],sele border-radius:8px;padding:7px 10px;font:inherit;font-size:13.5px; } input:focus,select:focus{outline:0;border-color:var(--accent)} +/* A search box and the x that clears it, inside its right end, there only once something is typed + (#291). The browser's own x, in some browsers and not others, gives way to it. */ +.clearable{position:relative;display:flex;align-items:center;min-width:0} +/* With [type=search], or the phone's padding for every text box, later on, takes the room back. */ +.clearable>input[type=search]{flex:1;min-width:0;padding-right:32px} +.clearable>input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none} +.clearx{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:grid;place-items:center;width:26px;height:26px;padding:0;border-radius:50%;color:var(--faint)} +.clearx:hover{color:var(--fg)} +.clearx svg{width:11px;height:11px} +.clearable:has(>input:placeholder-shown) .clearx{display:none} +.inline .clearable{flex:1} /* The wider left gutter is the folder triangle's; everything in the list shifts with it, so the feeds still line up with the places above. */ #feedlist{overflow-y:auto;padding:0 8px 12px 16px;flex:1;min-height:0} @@ -1251,7 +1262,7 @@ body:has(#player.on) #status{padding-bottom:3px} padding-left:calc(8px + var(--safe-l));padding-right:calc(8px + var(--safe-r)); } #topbar .grow,.tgroup.item{display:none} - #topbar #epSearch{width:auto;flex:1;min-width:0} + #topbar #epBox{width:auto;flex:1;min-width:0} .tgroup button,.tgroup a{padding:4px 8px;min-width:32px} .fhead.slim .acts{flex:1 1 100%} .iconbtn{width:38px;height:38px} @@ -1359,7 +1370,7 @@ body:has(#player.on) #status{padding-bottom:3px} input[type=search],input[type=text],input[type=password],input[type=number],select{ font-size:17px;background:var(--panel2);border-color:var(--edge);border-radius:10px;padding:9px 12px; } - #topbar #epSearch{font-size:16px;border-radius:999px;padding:9px 14px} + #topbar #epSearch{font-size:16px;border-radius:999px;padding:9px 34px 9px 14px} input:focus,select:focus{border-color:var(--accent)} /* The feed's name as the page's large title, the way Podcasts heads a show. */ diff --git a/web/index.html b/web/index.html index f7eb5ca..d944f26 100644 --- a/web/index.html +++ b/web/index.html @@ -28,7 +28,7 @@ - +