From dedfec10d1e94b76a21e0d9ee90b6cf7fea5a4a9 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sat, 12 Sep 2026 19:29:11 +0300 Subject: [PATCH] feat(cards): show operation icons on hover --- src/pages/card/ui/CardPage.view.tsx | 67 +++++++++++++++++++++-------- src/shared/ui/EntryCard.module.css | 53 +++++++++++++++++++++++ src/shared/ui/EntryCard.tsx | 15 +++++-- 3 files changed, 115 insertions(+), 20 deletions(-) diff --git a/src/pages/card/ui/CardPage.view.tsx b/src/pages/card/ui/CardPage.view.tsx index f56ddd1..daa2886 100644 --- a/src/pages/card/ui/CardPage.view.tsx +++ b/src/pages/card/ui/CardPage.view.tsx @@ -1,4 +1,5 @@ import { + ActionIcon, Anchor, Badge, Button, @@ -161,24 +162,56 @@ const CardPageView: FC = (props) => { ) : null } + actions={ + + vm.setOperation(row.item)} + > + + + vm.setDeleting(row.item)} + > + + + + } /> - - - - )) ) : ( diff --git a/src/shared/ui/EntryCard.module.css b/src/shared/ui/EntryCard.module.css index cdd813b..efdcb3e 100644 --- a/src/shared/ui/EntryCard.module.css +++ b/src/shared/ui/EntryCard.module.css @@ -40,3 +40,56 @@ text-align: left; } } + +.valueFooter { + display: grid; + align-items: center; + justify-items: end; + min-height: 28px; +} +.valueLabel, +.actions { + grid-area: 1 / 1; + transition: opacity 180ms ease; +} +.valueLabel { + opacity: 0; +} +.actions { + display: flex; +} +@media (hover: hover) and (pointer: fine) { + .valueLabel { + opacity: 1; + } + .actions { + opacity: 0; + pointer-events: none; + } + .row:hover .actions, + .row:focus-within .actions { + opacity: 1; + pointer-events: auto; + } + .row:hover .valueLabel, + .row:focus-within .valueLabel { + opacity: 0; + } +} +@media (max-width: 36em) { + .valueFooter { + justify-items: start; + } +} +@media (pointer: coarse) { + .actions button { + min-width: 36px; + min-height: 36px; + } +} +@media (prefers-reduced-motion: reduce) { + .valueLabel, + .actions { + transition: none; + } +} diff --git a/src/shared/ui/EntryCard.tsx b/src/shared/ui/EntryCard.tsx index c7e38b0..7189f53 100644 --- a/src/shared/ui/EntryCard.tsx +++ b/src/shared/ui/EntryCard.tsx @@ -6,6 +6,7 @@ type EntryCardProps = { title: string; metadata: string; details?: ReactNode; + actions?: ReactNode; initial: string; imageSrc?: string | null; value: string; @@ -40,9 +41,17 @@ const EntryCard: FC = (props) => { {props.value} - - {props.valueLabel} - +
+ + {props.valueLabel} + + {props.actions && ( +
{props.actions}
+ )} +
);