From 3f52e54207d201d6cb12b3b2de93c97b3aa00e5c Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Sat, 18 Apr 2026 16:54:49 +0100 Subject: [PATCH] fix(base): pin selection bar to viewport with Confluence-style dark pill --- .../components/grid/selection-action-bar.tsx | 25 +++--- .../src/features/base/styles/grid.module.css | 79 ++++++++++++++++--- 2 files changed, 80 insertions(+), 24 deletions(-) diff --git a/apps/client/src/features/base/components/grid/selection-action-bar.tsx b/apps/client/src/features/base/components/grid/selection-action-bar.tsx index a60d9c99..f9ba1b98 100644 --- a/apps/client/src/features/base/components/grid/selection-action-bar.tsx +++ b/apps/client/src/features/base/components/grid/selection-action-bar.tsx @@ -1,5 +1,5 @@ import { memo } from "react"; -import { ActionIcon, Button, Transition } from "@mantine/core"; +import { Transition } from "@mantine/core"; import { IconTrash, IconX } from "@tabler/icons-react"; import { useTranslation } from "react-i18next"; import { useRowSelection } from "@/features/base/hooks/use-row-selection"; @@ -23,28 +23,27 @@ export const SelectionActionBar = memo(function SelectionActionBar({ {(styles) => (
-
+
{t("{{count}} selected", { count: selectionCount })} - - +
)} diff --git a/apps/client/src/features/base/styles/grid.module.css b/apps/client/src/features/base/styles/grid.module.css index 0a265481..cb78e03b 100644 --- a/apps/client/src/features/base/styles/grid.module.css +++ b/apps/client/src/features/base/styles/grid.module.css @@ -376,28 +376,85 @@ } .selectionActionBarWrapper { - position: sticky; - bottom: 16px; + position: fixed; + left: 50%; + bottom: 24px; + transform: translateX(-50%); display: flex; justify-content: center; pointer-events: none; - z-index: 5; - grid-column: 1 / -1; + z-index: 200; } .selectionActionBar { pointer-events: auto; display: inline-flex; align-items: center; - gap: 8px; - padding: 6px 10px; - border-radius: var(--mantine-radius-md); - box-shadow: var(--mantine-shadow-lg); - background: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6)); - border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); + gap: 4px; + padding: 6px 6px 6px 14px; + border-radius: 999px; + box-shadow: + 0 10px 30px rgba(0, 0, 0, 0.25), + 0 2px 8px rgba(0, 0, 0, 0.18); + background: light-dark( + var(--mantine-color-dark-8), + var(--mantine-color-dark-5) + ); + color: var(--mantine-color-white); + border: 1px solid light-dark( + var(--mantine-color-dark-9), + var(--mantine-color-dark-4) + ); } .selectionActionBarCount { font-size: var(--mantine-font-size-sm); - color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0)); + font-weight: 500; + color: var(--mantine-color-white); + padding-right: 10px; + margin-right: 2px; + border-right: 1px solid rgba(255, 255, 255, 0.15); +} + +.selectionActionBarDelete { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 4px 10px; + border: none; + background: transparent; + color: var(--mantine-color-red-4); + font-size: var(--mantine-font-size-sm); + font-weight: 500; + border-radius: 999px; + cursor: pointer; + transition: background 120ms ease; +} + +.selectionActionBarDelete:hover:not(:disabled) { + background: rgba(255, 255, 255, 0.08); +} + +.selectionActionBarDelete:disabled { + opacity: 0.6; + cursor: default; +} + +.selectionActionBarClose { + display: inline-flex; + align-items: center; + justify-content: center; + width: 26px; + height: 26px; + border: none; + background: transparent; + color: var(--mantine-color-gray-3); + border-radius: 999px; + cursor: pointer; + transition: background 120ms ease, color 120ms ease; +} + +.selectionActionBarClose:hover { + background: rgba(255, 255, 255, 0.08); + color: var(--mantine-color-white); }