(null);
-
- const handleClick = () => {
- // Measure where the search bar sits so the palette can animate from
- // that exact position — the FLIP technique. Custom properties are set
- // on and consumed by @keyframes palette-enter in global.css.
- const rect = barRef.current?.getBoundingClientRect();
- if (rect) {
- const root = document.documentElement;
- const paletteTop = 88; // palette resting position (CSS `top: 88px`)
- const paletteCenterX = window.innerWidth / 2;
- const paletteWidth = Math.min(720, window.innerWidth - 48);
-
- root.style.setProperty("--palette-dy", `${rect.top - paletteTop}px`);
- root.style.setProperty("--palette-dx", `${rect.left + rect.width / 2 - paletteCenterX}px`);
- root.style.setProperty("--palette-sx", `${rect.width / paletteWidth}`);
- }
- openPalette();
- };
return (
diff --git a/src/home/sections/ProjectCard.tsx b/src/home/sections/ProjectCard.tsx
index 40b2903..34bf1c7 100644
--- a/src/home/sections/ProjectCard.tsx
+++ b/src/home/sections/ProjectCard.tsx
@@ -1,4 +1,4 @@
-import { openPath } from "@tauri-apps/plugin-opener";
+import { revealItemInDir } from "@tauri-apps/plugin-opener";
import { useState } from "react";
import { ContextMenu } from "../../ide/tree/ContextMenu";
@@ -61,7 +61,7 @@ export function ProjectCard({ project, index = 0 }: Props) {
{ label: "Ouvrir", onSelect: () => void openProject(project.id) },
{
label: "Ouvrir le dossier",
- onSelect: () => void openPath(project.path),
+ onSelect: () => void revealItemInDir(project.path),
},
{ label: "Renommer", onSelect: () => openRename({ id: project.id }) },
{
diff --git a/src/styles/global.css b/src/styles/global.css
index 464ee21..535932b 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -923,6 +923,10 @@ button.brand {
.context-menu__item:hover {
background: var(--bg-3);
}
+.context-menu__item:focus-visible {
+ outline: none;
+ background: var(--bg-3);
+}
.context-menu__item--destructive {
color: var(--err);
}
@@ -2144,33 +2148,23 @@ button.brand {
}
}
-/* FLIP animation: HomeSearch measures its own rect on click and writes
- --palette-dy / --palette-dx / --palette-sx as CSS custom properties on
- . The keyframe starts at those offsets (the search bar's position
- and width) and settles at the palette's resting center. All transforms
- → GPU-composited, zero layout thrash. */
.palette-root {
position: fixed;
top: 88px;
left: 50%;
transform: translateX(-50%);
- width: min(720px, calc(100vw - 48px));
+ width: min(800px, calc(100vw - 48px));
z-index: var(--z-modal);
display: flex;
flex-direction: column;
font-family: var(--font-ui);
- animation: palette-enter 0.28s cubic-bezier(0.16, 1, 0.3, 1);
- transform-origin: top center;
+ animation: palette-enter 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes palette-enter {
from {
opacity: 0;
- transform: translateX(calc(-50% + var(--palette-dx, 0px))) translateY(var(--palette-dy, 0px))
- scaleX(var(--palette-sx, 1));
- }
- 15% {
- opacity: 1;
+ transform: translateX(-50%) scale(0.96) translateY(-8px);
}
}