mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-11-10 05:53:05 +09:00
fix(frontend): mobile layout for intro strip, info tips and card headers
- IconStepStrip stays a compact horizontal row on narrow screens (smaller tiles, label under icon, horizontal chevrons) - tip-card-head stacks top-to-bottom with a smaller illustration - InfoTip clamps to the viewport (collision padding clears the sticky header, flips below when no room above, max-height scroll) - card headers wrap on narrow screens; security subtitle gets its own line
This commit is contained in:
1 parent
bddca28881
commit
a4ea3fccbd
4 files changed
+54
-2
No files matched your search
@@ -1,6 +1,7 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import { Info } from 'lucide-react';
|
||||
import { Popover, PopoverTrigger, PopoverContent } from '@/components/ui/popover';
|
||||
import useMediaQuery from '../hooks/useMediaQuery';
|
||||
import { t } from '../i18n/t';
|
||||
|
||||
// An (i) button that holds the explanation a page used to print inline.
|
||||
@@ -9,6 +10,9 @@ import { t } from '../i18n/t';
|
||||
// (no button-in-button) and above Modal/Sheet (.info-tip__panel z-index).
|
||||
export default function InfoTip({ children, label, side = 'top', size = 'sm', className = '' }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
// Narrow screens: keep the panel clear of the sticky app header.
|
||||
const narrow = useMediaQuery('(max-width: 640px)');
|
||||
const collisionPadding = narrow ? { top: 72, right: 12, bottom: 12, left: 12 } : 8; // geometry: header 56px + safe area
|
||||
const pinned = useRef(false);
|
||||
const hoverable = (e) => e.pointerType === 'mouse';
|
||||
|
||||
@@ -37,6 +41,8 @@ export default function InfoTip({ children, label, side = 'top', size = 'sm', cl
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
side={side}
|
||||
avoidCollisions
|
||||
collisionPadding={collisionPadding}
|
||||
className="info-tip__panel"
|
||||
onOpenAutoFocus={(e) => e.preventDefault()}
|
||||
onCloseAutoFocus={(e) => e.preventDefault()}
|
||||
|
||||
@@ -15,6 +15,14 @@
|
||||
.card-header {
|
||||
@include flex-between();
|
||||
margin-bottom: $space-4;
|
||||
|
||||
// Narrow: title takes the row, trailing chips/actions wrap below.
|
||||
@include respond-to($breakpoint-sm) {
|
||||
flex-wrap: wrap;
|
||||
gap: $space-2;
|
||||
|
||||
> h3 { flex: 1 1 auto; min-width: 0; }
|
||||
}
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
z-index: $z-tooltip + 10;
|
||||
width: auto;
|
||||
max-width: min(320px, calc(100vw - 24px));
|
||||
max-height: var(--radix-popover-content-available-height, 60vh);
|
||||
overflow-y: auto;
|
||||
padding: $space-2 $space-3;
|
||||
font-size: $text-sm;
|
||||
font-weight: $font-weight-normal;
|
||||
@@ -94,11 +96,32 @@
|
||||
svg { width: 16px; height: 16px; } // geometry: connector icon
|
||||
}
|
||||
|
||||
// Narrow: stay one compact row; label sits under a smaller tile.
|
||||
@include respond-to($breakpoint-sm) {
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
gap: $space-1;
|
||||
|
||||
&__arrow { transform: rotate(90deg); margin-inline-start: $space-3; }
|
||||
&__step {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: $space-1;
|
||||
}
|
||||
|
||||
&__tile {
|
||||
grid-column: 1 / -1;
|
||||
justify-self: center;
|
||||
width: 36px; // geometry: compact tile
|
||||
height: 36px; // geometry: compact tile
|
||||
svg { width: 18px; height: 18px; } // geometry: icon in compact tile
|
||||
}
|
||||
|
||||
&__label { font-size: $text-xs; }
|
||||
|
||||
// Centre the 14px chevron on the 36px tile.
|
||||
&__arrow { margin-block-start: 11px; svg { width: 14px; height: 14px; } } // geometry: connector
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,6 +200,19 @@
|
||||
gap: $space-3;
|
||||
|
||||
&__text { flex: 1; min-width: 0; }
|
||||
|
||||
@include respond-to($breakpoint-sm) {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: $space-2;
|
||||
|
||||
.tip-illustration {
|
||||
width: 36px; // geometry: compact illustration
|
||||
height: 36px; // geometry: compact illustration
|
||||
}
|
||||
|
||||
&__text { flex: none; width: 100%; }
|
||||
}
|
||||
&__title { display: flex; align-items: center; gap: $space-1; color: $text-primary; font-weight: $font-weight-medium; }
|
||||
&__line { margin: 0; color: $text-secondary; font-size: $text-sm; }
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@
|
||||
font-weight: $font-weight-medium;
|
||||
color: var(--text-faint);
|
||||
letter-spacing: 0;
|
||||
|
||||
@include respond-to($breakpoint-sm) { display: block; }
|
||||
}
|
||||
|
||||
// Severity / state chip (mono uppercase on a semantic wash) —
|
||||
|
||||
Reference in new issue
Block a user