fix: refine widget modernization

This commit is contained in:
Thomas Camlong authored and ajnart committed 2026-08-13 19:54:29 +02:00
1 parent 6f2cd7fc2b
commit 777bbd89a1
44 files changed
+259 -320

No files matched your search

@@ -22,6 +22,7 @@
overscroll-behavior: contain;
animation: focus-surface-in 220ms cubic-bezier(0.16, 1, 0.3, 1);
transform-origin: top left;
padding-top: 60px;
}
.backdropClosing {
@@ -57,6 +58,21 @@
pointer-events: none;
}
.surfaceControlsAdvanced {
right: 0;
bottom: auto;
height: 60px;
background: color-mix(in srgb, var(--mantine-color-body) 92%, transparent);
border-bottom: 1px solid var(--mantine-color-default-border);
}
.surfaceTitle {
position: absolute;
top: 20px;
right: 120px;
left: 16px;
}
.closeButton {
position: absolute;
top: 8px;
@@ -68,7 +84,7 @@
.pinButton {
position: absolute;
top: 8px;
right: 52px;
right: 60px;
z-index: 2;
pointer-events: auto;
}
@@ -82,7 +98,7 @@
pointer-events: auto;
}
@media (pointer: coarse) {
@media (any-pointer: coarse) {
.touchButton {
display: inline-flex;
}
@@ -4,12 +4,12 @@ import { getAdvancedFocusRect } from "./geometry";
describe("getAdvancedFocusRect", () => {
it("expands a widget and keeps it inside the viewport", () => {
expect(getAdvancedFocusRect({ left: 10, top: 10, width: 300, height: 200 }, { width: 1200, height: 800 })).toEqual({
left: 240,
top: 190,
width: 720,
height: 480,
});
const rect = getAdvancedFocusRect({ left: 10, top: 10, width: 300, height: 200 }, { width: 1200, height: 800 });
expect(rect.left).toBe(120);
expect(rect.top).toBeCloseTo(118.6);
expect(rect.width).toBe(960);
expect(rect.height).toBeCloseTo(622.8);
});
it("uses the available viewport on small screens", () => {
@@ -11,8 +11,10 @@ export const getAdvancedFocusRect = (source: FocusRect, viewport: { width: numbe
const margin = viewport.width < 640 ? 8 : 24;
const availableWidth = Math.max(0, viewport.width - margin * 2);
const availableHeight = Math.max(0, viewport.height - appShellHeaderHeight - margin * 2);
const width = Math.min(availableWidth, Math.max(source.width, Math.min(960, source.width * 2.4)));
const height = Math.min(availableHeight, Math.max(source.height, Math.min(720, source.height * 2.4)));
const preferredWidth = viewport.width < 640 ? availableWidth : Math.min(960, availableWidth * 0.9);
const preferredHeight = viewport.width < 640 ? availableHeight : Math.min(720, availableHeight * 0.9);
const width = Math.min(availableWidth, Math.max(source.width, preferredWidth));
const height = Math.min(availableHeight, Math.max(source.height, preferredHeight));
return {
left: Math.max(margin, (viewport.width - width) / 2),
@@ -3,7 +3,6 @@ import { useCallback } from "react";
import { useUpdateBoard } from "@homarr/boards/updater";
import type { BoardItemAdvancedOptions } from "@homarr/validation/shared";
import type { Board } from "~/app/[locale]/boards/_types";
import type { CreateItemInput } from "./actions/create-item";
import { createItemCallback } from "./actions/create-item";
import type { DuplicateItemInput } from "./actions/duplicate-item";
@@ -33,17 +32,7 @@ interface UpdateItemIntegrations {
export const useItemActions = () => {
const { updateBoard } = useUpdateBoard();
const createItem = useCallback(
(input: CreateItemInput) => {
let nextBoard: Board | undefined;
updateBoard((previous) => {
nextBoard = createItemCallback(input)(previous);
return nextBoard;
});
return nextBoard;
},
[updateBoard],
);
const createItem = useCallback((input: CreateItemInput) => updateBoard(createItemCallback(input)), [updateBoard]);
const duplicateItem = useCallback(
({ itemId }: DuplicateItemInput) => {