fix(mobile): popover styles (#15351)

This commit is contained in:
DarkSky
2026-07-26 20:09:02 +08:00
committed by GitHub
parent b975e6b562
commit 749f1c5f0b
15 changed files with 799 additions and 557 deletions
Generated
+18 -8
View File
@@ -2930,7 +2930,7 @@ dependencies = [
"libc", "libc",
"log", "log",
"rustversion", "rustversion",
"windows-link 0.2.1", "windows-link 0.1.3",
"windows-result 0.4.1", "windows-result 0.4.1",
] ]
@@ -6504,9 +6504,9 @@ dependencies = [
[[package]] [[package]]
name = "quinn" name = "quinn"
version = "0.11.9" version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8"
dependencies = [ dependencies = [
"bytes", "bytes",
"cfg_aliases", "cfg_aliases",
@@ -6524,15 +6524,16 @@ dependencies = [
[[package]] [[package]]
name = "quinn-proto" name = "quinn-proto"
version = "0.11.14" version = "0.11.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560"
dependencies = [ dependencies = [
"aws-lc-rs", "aws-lc-rs",
"bytes", "bytes",
"getrandom 0.3.4", "getrandom 0.4.2",
"lru-slab", "lru-slab",
"rand 0.9.4", "rand 0.10.1",
"rand_pcg",
"ring", "ring",
"rustc-hash 2.1.1", "rustc-hash 2.1.1",
"rustls", "rustls",
@@ -6665,6 +6666,15 @@ dependencies = [
"rand 0.9.4", "rand 0.9.4",
] ]
[[package]]
name = "rand_pcg"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a"
dependencies = [
"rand_core 0.10.1",
]
[[package]] [[package]]
name = "rawpointer" name = "rawpointer"
version = "0.2.1" version = "0.2.1"
@@ -10157,7 +10167,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.48.0",
] ]
[[package]] [[package]]
@@ -29,7 +29,7 @@
"yjs": "^13.6.27" "yjs": "^13.6.27"
}, },
"devDependencies": { "devDependencies": {
"@vitest/browser-playwright": "^4.1.8", "@vitest/browser-playwright": "^4.1.10",
"playwright": "=1.58.2", "playwright": "=1.58.2",
"vitest": "^4.1.8" "vitest": "^4.1.8"
}, },
@@ -55,6 +55,7 @@ export class EditorMenuButton extends WithDisposable(LitElement) {
}, },
mainAxis: 0, mainAxis: 0,
offsetHeight: 6 * 4, offsetHeight: 6 * 4,
topLayer: true,
...this.popperOptions, ...this.popperOptions,
}); });
} }
@@ -124,6 +125,14 @@ export class EditorMenuContent extends LitElement {
outline: none; outline: none;
} }
:host([popover]) {
inset: auto;
margin: 0;
border: 0;
background: transparent;
color: inherit;
}
:host([data-show]) { :host([data-show]) {
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -25,7 +25,7 @@
"zod": "^3.25.76" "zod": "^3.25.76"
}, },
"devDependencies": { "devDependencies": {
"@vitest/browser-playwright": "^4.1.8", "@vitest/browser-playwright": "^4.1.10",
"playwright": "=1.58.2", "playwright": "=1.58.2",
"vitest": "^4.1.8" "vitest": "^4.1.8"
}, },
@@ -37,6 +37,7 @@ const ATTR_SHOW = 'data-show';
export type ButtonPopperOptions = { export type ButtonPopperOptions = {
reference: HTMLElement; reference: HTMLElement;
popperElement: HTMLElement; popperElement: HTMLElement;
topLayer?: boolean;
stateUpdated?: (state: { display: Display }) => void; stateUpdated?: (state: { display: Display }) => void;
mainAxis?: number; mainAxis?: number;
crossAxis?: number; crossAxis?: number;
@@ -62,6 +63,7 @@ export function createButtonPopper(options: ButtonPopperOptions) {
const { const {
reference, reference,
popperElement, popperElement,
topLayer = false,
stateUpdated = () => {}, stateUpdated = () => {},
mainAxis, mainAxis,
crossAxis, crossAxis,
@@ -69,6 +71,12 @@ export function createButtonPopper(options: ButtonPopperOptions) {
rootBoundary, rootBoundary,
offsetHeight, offsetHeight,
} = options; } = options;
const useTopLayer =
topLayer && typeof popperElement.showPopover === 'function';
if (useTopLayer) {
popperElement.popover = 'manual';
}
const originMaxHeight = window.getComputedStyle(popperElement).maxHeight; const originMaxHeight = window.getComputedStyle(popperElement).maxHeight;
@@ -79,6 +87,7 @@ export function createButtonPopper(options: ButtonPopperOptions) {
}; };
computePosition(reference, popperElement, { computePosition(reference, popperElement, {
strategy: useTopLayer ? 'fixed' : 'absolute',
middleware: [ middleware: [
offset({ offset({
mainAxis: mainAxis ?? 14, mainAxis: mainAxis ?? 14,
@@ -102,7 +111,7 @@ export function createButtonPopper(options: ButtonPopperOptions) {
}) })
.then(({ x, y }) => { .then(({ x, y }) => {
Object.assign(popperElement.style, { Object.assign(popperElement.style, {
position: 'absolute', position: useTopLayer ? 'fixed' : 'absolute',
zIndex: 1, zIndex: 1,
left: `${x}px`, left: `${x}px`,
top: `${y}px`, top: `${y}px`,
@@ -118,6 +127,9 @@ export function createButtonPopper(options: ButtonPopperOptions) {
if (!displayed) { if (!displayed) {
popperElement.setAttribute(ATTR_SHOW, ''); popperElement.setAttribute(ATTR_SHOW, '');
if (useTopLayer) {
popperElement.showPopover();
}
display = 'show'; display = 'show';
stateUpdated({ display }); stateUpdated({ display });
} }
@@ -130,6 +142,9 @@ export function createButtonPopper(options: ButtonPopperOptions) {
const hide = () => { const hide = () => {
if (display === 'hidden') return; if (display === 'hidden') return;
if (useTopLayer) {
popperElement.hidePopover();
}
popperElement.removeAttribute(ATTR_SHOW); popperElement.removeAttribute(ATTR_SHOW);
display = 'hidden'; display = 'hidden';
stateUpdated({ display }); stateUpdated({ display });
+1 -1
View File
@@ -33,7 +33,7 @@
"zod": "^3.25.76" "zod": "^3.25.76"
}, },
"devDependencies": { "devDependencies": {
"@vitest/browser-playwright": "^4.1.8", "@vitest/browser-playwright": "^4.1.10",
"playwright": "=1.58.2", "playwright": "=1.58.2",
"vitest": "^4.1.8" "vitest": "^4.1.8"
}, },
+1 -1
View File
@@ -35,7 +35,7 @@
], ],
"devDependencies": { "devDependencies": {
"@vanilla-extract/vite-plugin": "^5.0.0", "@vanilla-extract/vite-plugin": "^5.0.0",
"@vitest/browser-playwright": "^4.1.8", "@vitest/browser-playwright": "^4.1.10",
"playwright": "=1.58.2", "playwright": "=1.58.2",
"vite": "^7.3.5", "vite": "^7.3.5",
"vite-plugin-wasm": "^3.5.0", "vite-plugin-wasm": "^3.5.0",
+6 -9
View File
@@ -64,9 +64,9 @@
"@types/node": "^22.0.0", "@types/node": "^22.0.0",
"@typescript-eslint/parser": "^8.55.0", "@typescript-eslint/parser": "^8.55.0",
"@vanilla-extract/vite-plugin": "^5.0.0", "@vanilla-extract/vite-plugin": "^5.0.0",
"@vitest/browser": "^4.1.8", "@vitest/browser": "^4.1.10",
"@vitest/coverage-istanbul": "^4.1.8", "@vitest/coverage-istanbul": "^4.1.10",
"@vitest/ui": "^4.1.8", "@vitest/ui": "^4.1.10",
"cross-env": "^10.1.0", "cross-env": "^10.1.0",
"electron": "^39.0.0", "electron": "^39.0.0",
"eslint": "^9.39.2", "eslint": "^9.39.2",
@@ -91,7 +91,7 @@
"typescript-eslint": "^8.55.0", "typescript-eslint": "^8.55.0",
"unplugin-swc": "^1.5.9", "unplugin-swc": "^1.5.9",
"vite": "^7.3.5", "vite": "^7.3.5",
"vitest": "^4.1.8" "vitest": "^4.1.10"
}, },
"packageManager": "yarn@4.13.0", "packageManager": "yarn@4.13.0",
"resolutions": { "resolutions": {
@@ -167,16 +167,13 @@
"typedarray": "npm:@nolyfill/typedarray@^1", "typedarray": "npm:@nolyfill/typedarray@^1",
"macos-alias": "npm:@napi-rs/macos-alias@0.0.4", "macos-alias": "npm:@napi-rs/macos-alias@0.0.4",
"fs-xattr": "npm:@napi-rs/xattr@latest", "fs-xattr": "npm:@napi-rs/xattr@latest",
"@opentelemetry/core": "^2.8.0", "@opentelemetry/core": "^2.10.0",
"@opentelemetry/resources": "^2.8.0",
"@opentelemetry/sdk-trace-base": "^2.8.0",
"@tootallnate/once": "^2.0.1",
"ioredis": "^5.11.1", "ioredis": "^5.11.1",
"js-yaml@npm:^4.1.0": "^4.2.0", "js-yaml@npm:^4.1.0": "^4.2.0",
"js-yaml@npm:4.1.1": "^4.2.0", "js-yaml@npm:4.1.1": "^4.2.0",
"multer": "^2.2.0", "multer": "^2.2.0",
"protobufjs": "^7.6.4", "protobufjs": "^7.6.4",
"tar": "^7.5.16", "tar": "^7.5.21",
"tmp": "^0.2.7", "tmp": "^0.2.7",
"ws@npm:^8.18.0": "^8.21.0", "ws@npm:^8.18.0": "^8.21.0",
"ws@npm:^8.18.3": "^8.21.0", "ws@npm:^8.18.3": "^8.21.0",
+10 -10
View File
@@ -45,21 +45,21 @@
"@node-rs/argon2": "^2.0.2", "@node-rs/argon2": "^2.0.2",
"@node-rs/crc32": "^1.10.6", "@node-rs/crc32": "^1.10.6",
"@opentelemetry/api": "^1.9.0", "@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^2.8.0", "@opentelemetry/core": "^2.10.0",
"@opentelemetry/exporter-prometheus": "^0.219.0", "@opentelemetry/exporter-prometheus": "^0.221.0",
"@opentelemetry/exporter-zipkin": "^2.8.0", "@opentelemetry/exporter-zipkin": "^2.10.0",
"@opentelemetry/host-metrics": "^0.39.0", "@opentelemetry/host-metrics": "^0.39.0",
"@opentelemetry/instrumentation": "^0.219.0", "@opentelemetry/instrumentation": "^0.221.0",
"@opentelemetry/instrumentation-graphql": "^0.67.0", "@opentelemetry/instrumentation-graphql": "^0.67.0",
"@opentelemetry/instrumentation-http": "^0.219.0", "@opentelemetry/instrumentation-http": "^0.221.0",
"@opentelemetry/instrumentation-ioredis": "^0.67.0", "@opentelemetry/instrumentation-ioredis": "^0.67.0",
"@opentelemetry/instrumentation-nestjs-core": "^0.65.0", "@opentelemetry/instrumentation-nestjs-core": "^0.65.0",
"@opentelemetry/instrumentation-socket.io": "^0.66.0", "@opentelemetry/instrumentation-socket.io": "^0.66.0",
"@opentelemetry/resources": "^2.8.0", "@opentelemetry/resources": "^2.10.0",
"@opentelemetry/sdk-metrics": "^2.8.0", "@opentelemetry/sdk-metrics": "^2.10.0",
"@opentelemetry/sdk-node": "^0.219.0", "@opentelemetry/sdk-node": "^0.221.0",
"@opentelemetry/sdk-trace-base": "^2.8.0", "@opentelemetry/sdk-trace-base": "^2.10.0",
"@opentelemetry/sdk-trace-node": "^2.8.0", "@opentelemetry/sdk-trace-node": "^2.10.0",
"@opentelemetry/semantic-conventions": "^1.41.1", "@opentelemetry/semantic-conventions": "^1.41.1",
"@prisma/client": "^6.6.0", "@prisma/client": "^6.6.0",
"@prisma/instrumentation": "^6.7.0", "@prisma/instrumentation": "^6.7.0",
+1 -1
View File
@@ -51,7 +51,7 @@
"react-dom": "^19.2.1", "react-dom": "^19.2.1",
"react-hook-form": "^7.54.1", "react-hook-form": "^7.54.1",
"react-resizable-panels": "^3.0.6", "react-resizable-panels": "^3.0.6",
"react-router-dom": "^7.18.0", "react-router-dom": "^7.18.1",
"recharts": "^2.15.4", "recharts": "^2.15.4",
"sonner": "^2.0.7", "sonner": "^2.0.7",
"swr": "^2.3.7", "swr": "^2.3.7",
+3 -3
View File
@@ -53,8 +53,8 @@
"@sentry/esbuild-plugin": "^5.3.0", "@sentry/esbuild-plugin": "^5.3.0",
"@toeverything/infra": "workspace:*", "@toeverything/infra": "workspace:*",
"@types/set-cookie-parser": "^2.4.10", "@types/set-cookie-parser": "^2.4.10",
"app-builder-lib": "^26.8.1", "app-builder-lib": "^26.15.0",
"builder-util-runtime": "^9.5.1", "builder-util-runtime": "^9.7.0",
"cross-env": "^10.1.0", "cross-env": "^10.1.0",
"debug": "^4.4.0", "debug": "^4.4.0",
"electron": "^39.0.0", "electron": "^39.0.0",
@@ -77,7 +77,7 @@
}, },
"dependencies": { "dependencies": {
"async-call-rpc": "^6.4.2", "async-call-rpc": "^6.4.2",
"electron-updater": "^6.8.3", "electron-updater": "^6.8.9",
"link-preview-js": "^4.0.0", "link-preview-js": "^4.0.0",
"set-cookie-parser": "^2.7.1", "set-cookie-parser": "^2.7.1",
"yjs": "^13.6.27" "yjs": "^13.6.27"
+1 -2
View File
@@ -16,7 +16,6 @@
"vitest": "^4.1.8" "vitest": "^4.1.8"
}, },
"peerDependencies": { "peerDependencies": {
"react": "^19.2.1", "react": "^19.2.1"
"react-router-dom": "^7.18.0"
} }
} }
+13 -1
View File
@@ -239,10 +239,22 @@ test('should format quick bar be able to change background color', async ({
// select `456` paragraph by dragging // select `456` paragraph by dragging
await dragBetweenIndices(page, [1, 0], [1, 3]); await dragBetweenIndices(page, [1, 0], [1, 3]);
const { highlight } = getFormatBar(page); const { formatBar, highlight } = getFormatBar(page);
await formatBar.evaluate(toolbar => {
toolbar.style.overflowX = 'auto';
});
await highlight.highlightBtn.click(); await highlight.highlightBtn.click();
await expect(highlight.redForegroundBtn).toBeVisible(); await expect(highlight.redForegroundBtn).toBeVisible();
await expect(
formatBar.locator('editor-menu-content[data-show]')
).toHaveAttribute('popover', 'manual');
expect(
await formatBar
.locator('editor-menu-content[data-show]')
.evaluate(menu => menu.matches(':popover-open'))
).toBe(true);
// TODO(@fundon): these recent settings should be added to the dropdown menu. // TODO(@fundon): these recent settings should be added to the dropdown menu.
// await expect(highlight.highlightBtn).toHaveAttribute( // await expect(highlight.highlightBtn).toHaveAttribute(
+1 -1
View File
@@ -32,7 +32,7 @@
"jsonc-parser": "^3.3.1", "jsonc-parser": "^3.3.1",
"lodash-es": "^4.17.23", "lodash-es": "^4.17.23",
"mime-types": "^3.0.0", "mime-types": "^3.0.0",
"postcss": "^8.4.49", "postcss": "^8.5.18",
"postcss-loader": "^8.2.1", "postcss-loader": "^8.2.1",
"postcss-selector-parser": "^7.1.0", "postcss-selector-parser": "^7.1.0",
"prettier": "^3.7.4", "prettier": "^3.7.4",
+717 -517
View File
File diff suppressed because it is too large Load Diff