mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
test: add mindmap collapse test (#9336)
This commit is contained in:
@@ -25,7 +25,12 @@ export class MindMapView extends GfxElementModelView<MindmapElementModel> {
|
|||||||
}
|
}
|
||||||
>();
|
>();
|
||||||
|
|
||||||
private _getCollapseButton(node: MindmapNode | string) {
|
/**
|
||||||
|
*
|
||||||
|
* @param node The mindmap node or its id to get the collapse button
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getCollapseButton(node: MindmapNode | string) {
|
||||||
const id = typeof node === 'string' ? node : node.id;
|
const id = typeof node === 'string' ? node : node.id;
|
||||||
return this._collapseButtons.get(`collapse-btn-${id}`);
|
return this._collapseButtons.get(`collapse-btn-${id}`);
|
||||||
}
|
}
|
||||||
@@ -149,7 +154,7 @@ export class MindMapView extends GfxElementModelView<MindmapElementModel> {
|
|||||||
elm?.id &&
|
elm?.id &&
|
||||||
this.model.children.has(elm.id)
|
this.model.children.has(elm.id)
|
||||||
) {
|
) {
|
||||||
const button = this._getCollapseButton(elm.id);
|
const button = this.getCollapseButton(elm.id);
|
||||||
|
|
||||||
if (!button) {
|
if (!button) {
|
||||||
return;
|
return;
|
||||||
@@ -164,7 +169,7 @@ export class MindMapView extends GfxElementModelView<MindmapElementModel> {
|
|||||||
|
|
||||||
private _updateButtonVisibility(node: string) {
|
private _updateButtonVisibility(node: string) {
|
||||||
const latestNode = this.model.getNode(node);
|
const latestNode = this.model.getNode(node);
|
||||||
const buttonModel = this._getCollapseButton(node);
|
const buttonModel = this.getCollapseButton(node);
|
||||||
|
|
||||||
if (!buttonModel) {
|
if (!buttonModel) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"test:unit": "nx vite:test --browser.headless --run",
|
"test:unit": "vitest --browser.headless --run",
|
||||||
"test:debug": "PWDEBUG=1 npx vitest"
|
"test:debug": "PWDEBUG=1 npx vitest"
|
||||||
},
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
@@ -37,5 +37,8 @@
|
|||||||
"themes",
|
"themes",
|
||||||
"!src/__tests__",
|
"!src/__tests__",
|
||||||
"!dist/__tests__"
|
"!dist/__tests__"
|
||||||
]
|
],
|
||||||
|
"devDependencies": {
|
||||||
|
"vitest": "^2.1.8"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
467
blocksuite/presets/src/__tests__/edgeless/mindmap.spec.ts
Normal file
467
blocksuite/presets/src/__tests__/edgeless/mindmap.spec.ts
Normal file
@@ -0,0 +1,467 @@
|
|||||||
|
import type { MindmapElementModel } from '@blocksuite/affine-model';
|
||||||
|
import type { GfxController } from '@blocksuite/block-std/gfx';
|
||||||
|
import { LayoutType, type MindMapView } from '@blocksuite/blocks';
|
||||||
|
import { Bound } from '@blocksuite/global/utils';
|
||||||
|
import { beforeEach, describe, expect, test } from 'vitest';
|
||||||
|
|
||||||
|
import { click, pointermove, wait } from '../utils/common.js';
|
||||||
|
import { getDocRootBlock } from '../utils/edgeless.js';
|
||||||
|
import { setupEditor } from '../utils/setup.js';
|
||||||
|
|
||||||
|
describe('mindmap', () => {
|
||||||
|
let gfx: GfxController;
|
||||||
|
const moveAndClick = ({ x, y, w, h }: Bound) => {
|
||||||
|
const { left, top } = gfx.viewport;
|
||||||
|
x += left;
|
||||||
|
y += top;
|
||||||
|
|
||||||
|
// trigger enter event
|
||||||
|
pointermove(editor.host!, { x: x + w / 2, y: y + h / 2 });
|
||||||
|
// trigger move event
|
||||||
|
pointermove(editor.host!, { x: x + w / 2 + 1, y: y + h / 2 + 1 });
|
||||||
|
click(editor.host!, { x: x + w / 2, y: y + h / 2 });
|
||||||
|
};
|
||||||
|
|
||||||
|
const move = ({ x, y, w, h }: Bound) => {
|
||||||
|
x += gfx.viewport.left;
|
||||||
|
y += gfx.viewport.top;
|
||||||
|
|
||||||
|
pointermove(editor.host!, { x: x + w / 2, y: y + h / 2 });
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const cleanup = await setupEditor('edgeless');
|
||||||
|
gfx = getDocRootBlock(window.doc, window.editor, 'edgeless').gfx;
|
||||||
|
|
||||||
|
return cleanup;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('delete the root node should remove all children', async () => {
|
||||||
|
const tree = {
|
||||||
|
text: 'root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf3',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const mindmapId = gfx.surface!.addElement({
|
||||||
|
type: 'mindmap',
|
||||||
|
children: tree,
|
||||||
|
});
|
||||||
|
const mindmap = () => gfx.getElementById(mindmapId) as MindmapElementModel;
|
||||||
|
|
||||||
|
expect(gfx.surface!.elementModels.length).toBe(6);
|
||||||
|
doc.captureSync();
|
||||||
|
|
||||||
|
gfx.deleteElement(mindmap().tree.element);
|
||||||
|
await wait();
|
||||||
|
expect(gfx.surface!.elementModels.length).toBe(0);
|
||||||
|
doc.captureSync();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
doc.undo();
|
||||||
|
expect(gfx.surface!.elementModels.length).toBe(6);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
gfx.deleteElement(mindmap().tree.children[2].element);
|
||||||
|
await wait();
|
||||||
|
expect(gfx.surface!.elementModels.length).toBe(4);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
doc.undo();
|
||||||
|
await wait();
|
||||||
|
expect(gfx.surface!.elementModels.length).toBe(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('mindmap should layout automatically when creating', async () => {
|
||||||
|
const tree = {
|
||||||
|
text: 'root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf3',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const mindmapId = gfx.surface!.addElement({
|
||||||
|
type: 'mindmap',
|
||||||
|
layoutType: LayoutType.RIGHT,
|
||||||
|
children: tree,
|
||||||
|
});
|
||||||
|
const mindmap = () => gfx.getElementById(mindmapId) as MindmapElementModel;
|
||||||
|
|
||||||
|
doc.captureSync();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
const root = mindmap().tree.element;
|
||||||
|
const children = mindmap().tree.children.map(child => child.element);
|
||||||
|
const leaf4 = mindmap().tree.children[2].children[0].element;
|
||||||
|
|
||||||
|
expect(children[0].x).greaterThan(root.x + root.w);
|
||||||
|
expect(children[1].x).greaterThan(root.x + root.w);
|
||||||
|
expect(children[2].x).greaterThan(root.x + root.w);
|
||||||
|
|
||||||
|
expect(children[1].y).greaterThan(children[0].y + children[0].h);
|
||||||
|
expect(children[2].y).greaterThan(children[1].y + children[1].h);
|
||||||
|
|
||||||
|
expect(leaf4.x).greaterThan(children[2].x + children[2].w);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('deliberately creating a circular reference should be resolved correctly', async () => {
|
||||||
|
const tree = {
|
||||||
|
text: 'root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf3',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const mindmapId = gfx.surface!.addElement({
|
||||||
|
type: 'mindmap',
|
||||||
|
layoutType: LayoutType.RIGHT,
|
||||||
|
children: tree,
|
||||||
|
});
|
||||||
|
const mindmap = () => gfx.getElementById(mindmapId) as MindmapElementModel;
|
||||||
|
|
||||||
|
doc.captureSync();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
// create a circular reference
|
||||||
|
doc.transact(() => {
|
||||||
|
const root = mindmap().tree;
|
||||||
|
const leaf3 = root.children[2];
|
||||||
|
const leaf4 = root.children[2].children[0];
|
||||||
|
|
||||||
|
mindmap().children.set(leaf3.id, {
|
||||||
|
index: leaf3.detail.index,
|
||||||
|
parent: leaf4.id,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
doc.captureSync();
|
||||||
|
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
// the circular referenced node should be removed
|
||||||
|
expect(mindmap().nodeMap.size).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('mindmap collapse and expand should work correctly', async () => {
|
||||||
|
const tree = {
|
||||||
|
text: 'root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf3',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// click to active the editor
|
||||||
|
click(editor.host!, { x: 50, y: 50 });
|
||||||
|
|
||||||
|
const mindmapId = gfx.surface!.addElement({
|
||||||
|
type: 'mindmap',
|
||||||
|
layoutType: LayoutType.RIGHT,
|
||||||
|
children: tree,
|
||||||
|
});
|
||||||
|
const mindmap = () => gfx.getElementById(mindmapId) as MindmapElementModel;
|
||||||
|
const mindmapView = () => gfx.view.get(mindmapId) as MindMapView;
|
||||||
|
|
||||||
|
doc.captureSync();
|
||||||
|
await wait(100);
|
||||||
|
|
||||||
|
// collapse the root node
|
||||||
|
{
|
||||||
|
const rootButton = mindmapView().getCollapseButton(mindmap().tree)!;
|
||||||
|
|
||||||
|
moveAndClick(gfx.viewport.toViewBound(rootButton.elementBound));
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(rootButton.hidden).toBe(false);
|
||||||
|
expect(rootButton.opacity).toBe(1);
|
||||||
|
expect(mindmap().tree.detail.collapsed).toBe(true);
|
||||||
|
expect(mindmap().getNodeByPath([0, 0])!.element.hidden).toBe(true);
|
||||||
|
expect(mindmap().getNodeByPath([0, 1])!.element.hidden).toBe(true);
|
||||||
|
expect(mindmap().getNodeByPath([0, 2])!.element.hidden).toBe(true);
|
||||||
|
expect(mindmap().getNodeByPath([0, 2, 0])!.element.hidden).toBe(true);
|
||||||
|
|
||||||
|
doc.captureSync();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
doc.undo();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(mindmap().tree.detail.collapsed).toBe(undefined);
|
||||||
|
expect(mindmap().getNodeByPath([0, 0])!.element.hidden).toBe(false);
|
||||||
|
expect(mindmap().getNodeByPath([0, 1])!.element.hidden).toBe(false);
|
||||||
|
expect(mindmap().getNodeByPath([0, 2])!.element.hidden).toBe(false);
|
||||||
|
expect(mindmap().getNodeByPath([0, 2, 0])!.element.hidden).toBe(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// collapse a child node
|
||||||
|
{
|
||||||
|
const node = mindmap().getNodeByPath([0, 2])!;
|
||||||
|
const childButton = mindmapView().getCollapseButton(node)!;
|
||||||
|
|
||||||
|
moveAndClick(gfx.viewport.toViewBound(childButton.elementBound));
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(childButton.hidden).toBe(false);
|
||||||
|
expect(childButton.opacity).toBe(1);
|
||||||
|
|
||||||
|
expect(mindmap().getNodeByPath([0, 2])!.element.hidden).toBe(false);
|
||||||
|
expect(mindmap().getNodeByPath([0, 2])!.detail.collapsed).toBe(true);
|
||||||
|
expect(mindmap().getNodeByPath([0, 2, 0])!.element.hidden).toBe(true);
|
||||||
|
|
||||||
|
doc.captureSync();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
doc.undo();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(mindmap().getNodeByPath([0, 2])!.detail.collapsed).toBe(undefined);
|
||||||
|
expect(mindmap().getNodeByPath([0, 2, 0])!.element.hidden).toBe(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// collapse root node and collapse a child node
|
||||||
|
{
|
||||||
|
const childButton = mindmapView().getCollapseButton(
|
||||||
|
mindmap().getNodeByPath([0, 2])!
|
||||||
|
)!;
|
||||||
|
// collapse child node
|
||||||
|
moveAndClick(gfx.viewport.toViewBound(childButton.elementBound));
|
||||||
|
|
||||||
|
doc.captureSync();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
const rootButton = mindmapView().getCollapseButton(mindmap().tree)!;
|
||||||
|
// collapse root node
|
||||||
|
moveAndClick(gfx.viewport.toViewBound(rootButton.elementBound));
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
// child button should be hidden
|
||||||
|
expect(childButton.hidden).toBe(true);
|
||||||
|
expect(childButton.opacity).toBe(0);
|
||||||
|
|
||||||
|
// expand root node
|
||||||
|
doc.undo();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
// child button should be visible
|
||||||
|
expect(childButton.hidden).toBe(false);
|
||||||
|
expect(childButton.opacity).toBe(1);
|
||||||
|
|
||||||
|
// child nodes should still be collapsed
|
||||||
|
expect(mindmap().getNodeByPath([0, 2])!.detail.collapsed).toBe(true);
|
||||||
|
expect(mindmap().getNodeByPath([0, 2, 0])!.element.hidden).toBe(true);
|
||||||
|
|
||||||
|
// expand child node
|
||||||
|
doc.undo();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
// child button should be visible
|
||||||
|
expect(mindmap().getNodeByPath([0, 2])!.detail.collapsed).toBe(undefined);
|
||||||
|
expect(mindmap().getNodeByPath([0, 2, 0])!.element.hidden).toBe(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("selected node's collapse button should be visible", async () => {
|
||||||
|
const tree = {
|
||||||
|
text: 'root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf3',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// click to active the editor
|
||||||
|
click(editor.host!, { x: 50, y: 50 });
|
||||||
|
|
||||||
|
const mindmapId = gfx.surface!.addElement({
|
||||||
|
type: 'mindmap',
|
||||||
|
layoutType: LayoutType.RIGHT,
|
||||||
|
children: tree,
|
||||||
|
});
|
||||||
|
const mindmap = () => gfx.getElementById(mindmapId) as MindmapElementModel;
|
||||||
|
const mindmapView = () => gfx.view.get(mindmapId) as MindMapView;
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
gfx.selection.set({ elements: [mindmap().tree.id] });
|
||||||
|
const rootButton = mindmapView().getCollapseButton(mindmap().tree)!;
|
||||||
|
expect(rootButton.hidden).toBe(false);
|
||||||
|
expect(rootButton.opacity).toBe(1);
|
||||||
|
|
||||||
|
gfx.selection.set({ elements: [mindmap().getNodeByPath([0, 2])!.id] });
|
||||||
|
const childButton = mindmapView().getCollapseButton(
|
||||||
|
mindmap().getNodeByPath([0, 2])!
|
||||||
|
)!;
|
||||||
|
expect(childButton.hidden).toBe(false);
|
||||||
|
expect(childButton.opacity).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('move near to the collapsed button should show the button', async () => {
|
||||||
|
const tree = {
|
||||||
|
text: 'root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf3',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// click to active the editor
|
||||||
|
click(editor.host!, { x: 50, y: 50 });
|
||||||
|
|
||||||
|
const mindmapId = gfx.surface!.addElement({
|
||||||
|
type: 'mindmap',
|
||||||
|
layoutType: LayoutType.RIGHT,
|
||||||
|
children: tree,
|
||||||
|
});
|
||||||
|
const mindmap = () => gfx.getElementById(mindmapId) as MindmapElementModel;
|
||||||
|
const mindmapView = () => gfx.view.get(mindmapId) as MindMapView;
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
const rootButton = mindmapView().getCollapseButton(mindmap().tree)!;
|
||||||
|
move(gfx.viewport.toViewBound(rootButton.elementBound).moveDelta(10, 10));
|
||||||
|
await wait();
|
||||||
|
expect(rootButton.opacity).toBe(1);
|
||||||
|
|
||||||
|
const childButton = mindmapView().getCollapseButton(
|
||||||
|
mindmap().getNodeByPath([0, 2])!
|
||||||
|
)!;
|
||||||
|
move(gfx.viewport.toViewBound(childButton.elementBound).moveDelta(10, 10));
|
||||||
|
await wait();
|
||||||
|
expect(childButton.opacity).toBe(1);
|
||||||
|
|
||||||
|
move(new Bound(0, 0, 0, 0));
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(childButton.opacity).toBe(0);
|
||||||
|
expect(rootButton.opacity).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("collapsed node's button should be always visible except its ancestor is collapsed", async () => {
|
||||||
|
const tree = {
|
||||||
|
text: 'root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'leaf3',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
text: 'leaf4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// click to active the editor
|
||||||
|
click(editor.host!, { x: 50, y: 50 });
|
||||||
|
|
||||||
|
const mindmapId = gfx.surface!.addElement({
|
||||||
|
type: 'mindmap',
|
||||||
|
layoutType: LayoutType.RIGHT,
|
||||||
|
children: tree,
|
||||||
|
});
|
||||||
|
const mindmap = () => gfx.getElementById(mindmapId) as MindmapElementModel;
|
||||||
|
const mindmapView = () => gfx.view.get(mindmapId) as MindMapView;
|
||||||
|
|
||||||
|
doc.captureSync();
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
const childButton = mindmapView().getCollapseButton(
|
||||||
|
mindmap().getNodeByPath([0, 2])!
|
||||||
|
)!;
|
||||||
|
// collapse the child node
|
||||||
|
moveAndClick(gfx.viewport.toViewBound(childButton.elementBound));
|
||||||
|
// move out of the button, the button should still be visible
|
||||||
|
move(new Bound(0, 0, 0, 0));
|
||||||
|
await wait();
|
||||||
|
expect(childButton.hidden).toBe(false);
|
||||||
|
expect(childButton.opacity).toBe(1);
|
||||||
|
|
||||||
|
const rootButton = mindmapView().getCollapseButton(mindmap().tree)!;
|
||||||
|
// collapse the root node
|
||||||
|
moveAndClick(gfx.viewport.toViewBound(rootButton.elementBound));
|
||||||
|
// move out of the button, the root button should be visible
|
||||||
|
move(new Bound(0, 0, 0, 0));
|
||||||
|
await wait();
|
||||||
|
expect(rootButton.hidden).toBe(false);
|
||||||
|
expect(rootButton.opacity).toBe(1);
|
||||||
|
// the collapsed child button should be hidden
|
||||||
|
expect(childButton.hidden).toBe(true);
|
||||||
|
expect(childButton.opacity).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -23,6 +23,10 @@ export default defineConfig(_configEnv =>
|
|||||||
provider: 'playwright',
|
provider: 'playwright',
|
||||||
isolate: false,
|
isolate: false,
|
||||||
providerOptions: {},
|
providerOptions: {},
|
||||||
|
viewport: {
|
||||||
|
width: 1024,
|
||||||
|
height: 768,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
coverage: {
|
coverage: {
|
||||||
provider: 'istanbul', // or 'c8'
|
provider: 'istanbul', // or 'c8'
|
||||||
|
|||||||
@@ -3773,6 +3773,7 @@ __metadata:
|
|||||||
"@preact/signals-core": "npm:^1.8.0"
|
"@preact/signals-core": "npm:^1.8.0"
|
||||||
"@toeverything/theme": "npm:^1.1.1"
|
"@toeverything/theme": "npm:^1.1.1"
|
||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
|
vitest: "npm:^2.1.8"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|||||||
Reference in New Issue
Block a user