mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-12 23:31:02 +00:00
d06168d94a
After a tap, WebKit and Chrome keep :hover on what was tapped and send a
made-up mouseover, so buttons and rows stayed tinted until the next tap.
While a finger drives the app <html> carries data-touch-input: a PostCSS
step guards every :hover rule with it (no specificity change), and the
made-up mouseover and mouseout stop before any handler. A trackpad or mouse
clears the mark and gets hover back; a browser never sets it.
A control without a press of its own dims the moment a finger lands on it,
after a 60 ms wait so a scroll does not flash rows, and only the innermost
pressed control. A focus: ring no longer stays round a tapped button.
Fields get a fitting return key ("done", "go" in a form, "search" on the
search fields), and addresses, codes and numbers are no longer capitalised
or corrected. Ticking off packing items and tasks, a picker chip, a select
option, a picked date and dragging a plan row now give the haptics a native
list gives.
Confirmations ask through the system where the binary has the new
@capacitor/action-sheet and @capacitor/dialog plugins: a sheet with the
action in red when it destroys something, an alert otherwise, also for
"discard changes" in a sheet. An older app, a browser and a question with a
list under it keep the HTML dialog, as does a system that could not ask.
iOS no longer lifts a page preview on a long press on a link.
40 lines
1.7 KiB
TypeScript
40 lines
1.7 KiB
TypeScript
import postcss from 'postcss';
|
|
import { describe, expect, it } from 'vitest';
|
|
import touchHover, { guardHover } from '../../../postcss/touchHover.js';
|
|
|
|
const GUARD = ':where(:root:not([data-touch-input]) *)';
|
|
const run = (css: string) => postcss([touchHover()]).process(css, { from: undefined }).css;
|
|
|
|
describe('touchHover', () => {
|
|
it('makes a hover rule wait for the touch mark to be gone, keeping its specificity', () => {
|
|
expect(guardHover('.btn:hover')).toBe(`.btn:hover${GUARD}`);
|
|
expect(guardHover('.row:hover > .icon')).toBe(`.row:hover${GUARD} > .icon`);
|
|
});
|
|
|
|
it("guards Tailwind's escaped class names on their real :hover only", () => {
|
|
expect(guardHover('.hover\\:bg-red:hover')).toBe(`.hover\\:bg-red:hover${GUARD}`);
|
|
expect(guardHover('.group:hover .group-hover\\:opacity-100')).toBe(
|
|
`.group:hover${GUARD} .group-hover\\:opacity-100`
|
|
);
|
|
});
|
|
|
|
it('guards every :hover of a selector, inside :is() too', () => {
|
|
expect(guardHover(':is(.dark .dark\\:hover\\:x:hover)')).toBe(`:is(.dark .dark\\:hover\\:x:hover${GUARD})`);
|
|
expect(guardHover('a:hover, b:focus')).toBe(`a:hover${GUARD}, b:focus`);
|
|
});
|
|
|
|
it('leaves :hover after a pseudo-element alone, where nothing may follow it', () => {
|
|
expect(guardHover('.m-range::-webkit-slider-thumb:hover')).toBe('.m-range::-webkit-slider-thumb:hover');
|
|
});
|
|
|
|
it('touches neither rules without :hover nor ones already guarded', () => {
|
|
expect(run('.a:focus { color: red }')).toBe('.a:focus { color: red }');
|
|
const once = run('.a:hover { color: red }');
|
|
expect(run(once)).toBe(once);
|
|
});
|
|
|
|
it('rewrites each selector of a list on its own', () => {
|
|
expect(run('.a:hover, .b { color: red }')).toBe(`.a:hover${GUARD}, .b { color: red }`);
|
|
});
|
|
});
|