diff --git a/e2e/reflow.spec.js b/e2e/reflow.spec.js index 738f26f7..be08028b 100644 --- a/e2e/reflow.spec.js +++ b/e2e/reflow.spec.js @@ -63,6 +63,56 @@ test.describe('on a touch screen', () => { expect(wide, 'the page does not scroll sideways').toBeLessThanOrEqual(320); }); } + + for (const language of ['fr', 'fa']) { + test(`the icon colour picker fits at 320px in ${language}`, async ({ page, request }) => { + await seedConfig(request, { items: [app('one', 'One')], settings: { language } }); + await dismissSetupPrompt(request); + await page.setViewportSize({ width: 320, height: 700 }); + await page.goto('/admin/#dashboard'); + await page.locator('#al [data-act="edit"]').first().click(); + await page.locator('#icon-color-slot .cc-swatch[data-v="custom"]').click(); + const picker = page.locator('#icon-color-slot'); + await picker.locator('.cc-hues').waitFor({ state: 'visible' }); + await animationsDone(page); + const misfits = await picker.evaluate(slot => { + const out = []; + for (const row of slot.querySelectorAll('.row')) { + const r = row.getBoundingClientRect(); + for (const n of row.querySelectorAll('.cc-swatch, .rl, .hsb-ico, .hsb-range')) { + const b = n.getBoundingClientRect(); + if (!b.width) continue; + if (b.left < r.left - 0.5 || b.right > r.right + 0.5) out.push(`${n.className} leaves its row`); + if (n.classList.contains('rl') && n.scrollWidth > n.clientWidth) + out.push(`label "${n.textContent}" is cut off`); + } + const sw = [...row.querySelectorAll('.cc-swatch')].map(n => n.getBoundingClientRect()); + for (let i = 1; i < sw.length; i++) + if (Math.abs(sw[i].top - sw[i - 1].top) < 1 && Math.abs(sw[i].left - sw[i - 1].left) < sw[i].width) + out.push('two swatches overlap'); + } + return out; + }); + expect(misfits).toEqual([]); + }); + } +}); + +test('the colour sliders share one length', async ({ page, request }) => { + await seedConfig(request, { items: [app('one', 'One')] }); + await dismissSetupPrompt(request); + await page.setViewportSize({ width: 1280, height: 900 }); + await openDashboardList(page); + await page.locator('#al [data-act="edit"]').first().click(); + await page.locator('#icon-color-slot .cc-swatch[data-v="custom"]').click(); + const sliders = page.locator('#icon-color-slot .hsb-range'); + await expect(sliders).toHaveCount(3); + await animationsDone(page); + const boxes = await Promise.all((await sliders.all()).map(box)); + for (const b of boxes.slice(1)) { + expect(b.x, 'every slider starts where the first does').toBeCloseTo(boxes[0].x, 0); + expect(b.width, 'every slider is as long as the first').toBeCloseTo(boxes[0].width, 0); + } }); test('the desktop Settings sidebar stays on screen while the list scrolls', async ({ page, request }) => { diff --git a/ui/admin/index.html b/ui/admin/index.html index 998dbaa3..28a56421 100644 --- a/ui/admin/index.html +++ b/ui/admin/index.html @@ -11,7 +11,7 @@ - + diff --git a/ui/css/admin.css b/ui/css/admin.css index d195fea5..08b2ac4d 100644 --- a/ui/css/admin.css +++ b/ui/css/admin.css @@ -363,10 +363,12 @@ button.rnm{font-family:inherit;color:inherit;background:none;border:0;padding:0; .cc-swatch.on{outline-color:Highlight} } .cc-rainbow{background:conic-gradient(from 90deg,#ff3b30,#ffcd00,#35c759,#0289ff,#cb30df,#ff3b30)} -.hsb-row{min-height:46px} -.hsb-track{display:flex;align-items:center;gap:10px;margin-inline-start:auto;flex:2;max-width:none} +.cc-tune > .reveal-in{display:grid;grid-template-columns:max-content minmax(0,1fr);column-gap:10px} +.cc-tune > .reveal-in > *{grid-column:1/-1} +.hsb-row{min-height:46px;display:grid;grid-template-columns:subgrid;align-items:center} +.hsb-track{display:flex;align-items:center;gap:10px} .hsb-ico{width:17px;height:17px;color:var(--dm);flex-shrink:0;display:flex} -.hsb-range{flex:1;height:6px;-webkit-appearance:none;appearance:none;border-radius:3px;cursor:pointer;outline:none} +.hsb-range{flex:1;min-width:0;height:6px;-webkit-appearance:none;appearance:none;border-radius:3px;cursor:pointer;outline:none} .hsb-hue{background:linear-gradient(var(--slider-dir),#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00)} /* ── Segmented control (Container/Ping, Disk Health/System Summary) ── @@ -734,6 +736,7 @@ a:focus-visible,button:focus-visible,[role="button"]:focus-visible{outline:2px s .adm-range { height:44px; padding-block:19px; background-clip:content-box; border-radius:3px / 22px; } .hsb-range { height:44px; padding-block:19px; background-clip:content-box; border-radius:3px / 22px; } .cc-swatch { width:34px; height:34px; } + .cc-sw { grid-template-columns:repeat(auto-fit,34px); } .cc-kw-clear { background-size:10px 10px; } .cc-hues .cc-sw { grid-template-columns:repeat(7,34px); } .cc-hues .cc-swatch { width:34px; height:34px; } @@ -753,7 +756,9 @@ html.is-mobile .sb{display:none} html.is-mobile .cp{width:100%} html.is-mobile .sec{padding-block:16px calc(132px + env(safe-area-inset-bottom));padding-inline:max(16px,env(safe-area-inset-left)) max(16px,env(safe-area-inset-right))} html.is-mobile .sec-title{font-size:var(--fs-large-title);line-height:var(--lh-large-title);letter-spacing:var(--tr-large-title)} -html.is-mobile .hsb-track{max-width:min(240px,62%)} +html.is-mobile .cc-row{flex-wrap:wrap;row-gap:10px} +html.is-mobile .cc-row .rl{flex:0 0 100%} +html.is-mobile .cc-sw{flex:1 1 100%;grid-template-columns:repeat(7,auto);column-gap:0;justify-content:space-between} html.is-mobile .sec-hdr{padding:10px 0 10px;flex-wrap:wrap;row-gap:6px} html.is-mobile .sec-title{order:1;flex-basis:100%;min-width:0;overflow-wrap:break-word} html.is-mobile .sec-hdr-actions{margin-inline-start:auto}