Add modal={false} to Select/DropdownMenu and polish cast carousel layout

- Set `modal={false}` on all Select and DropdownMenu instances to
  prevent scroll lock and backdrop interference when opened inside
  scrollable or fixed-position containers
- Reduce cast carousel card gap from `gap-4` to `gap-1` and switch
  actor name from `line-clamp-2` to `truncate` for a tighter layout
- Fix backup schedule description layout: move `suppressHydrationWarning`
  to wrapper span, add margin to inline SelectTrigger, use `!h-auto`
  to override default height
This commit is contained in:
2026-03-08 16:02:47 -04:00
parent 5fdc7ebd97
commit 29b80e304e
5 changed files with 14 additions and 9 deletions
@@ -95,6 +95,7 @@ function PeriodSelector({
<Select
value={period}
onValueChange={(v) => v && onPeriodChange(v as TimePeriod)}
modal={false}
>
<SelectTrigger
className={`${inlineTriggerClass} text-foreground/80 uppercase`}
@@ -76,6 +76,7 @@ export function FilmographyGrid({
<Select
value={sort}
onValueChange={(v) => v && setSort(v as Sort)}
modal={false}
aria-label="Sort filmography"
>
<SelectTrigger size="sm">
@@ -216,16 +216,17 @@ export function BackupScheduleSection({
<CardTitle>Backup schedule</CardTitle>
<CardDescription>
{enabled ? (
<span className="inline-flex flex-wrap items-baseline gap-1">
<span suppressHydrationWarning>
{formatNextBackup(frequency, time, dow)}.
</span>{" "}
Keeping{" "}
<span
className="inline-flex flex-wrap items-baseline"
suppressHydrationWarning
>
{formatNextBackup(frequency, time, dow)}. Keeping{" "}
<Select
value={String(maxRetention)}
onValueChange={(v) => v && changeMaxRetention(Number(v))}
modal={false}
>
<SelectTrigger className="h-auto w-auto gap-0.5 rounded-none border-0 bg-transparent p-0 underline decoration-muted-foreground/50 decoration-dotted underline-offset-4 shadow-none hover:bg-transparent hover:text-foreground hover:decoration-foreground/50 focus-visible:decoration-foreground focus-visible:decoration-solid focus-visible:ring-0 dark:bg-transparent dark:hover:bg-transparent">
<SelectTrigger className="!h-auto mr-0.5 ml-1.5 w-auto gap-0.5 rounded-none border-0 bg-transparent p-0 underline decoration-muted-foreground/50 decoration-dotted underline-offset-4 shadow-none hover:bg-transparent hover:text-foreground hover:decoration-foreground/50 focus-visible:decoration-foreground focus-visible:decoration-solid focus-visible:ring-0 dark:bg-transparent dark:hover:bg-transparent">
<SelectValue>
{(value: string | null) =>
value === "0"
@@ -319,6 +320,7 @@ export function BackupScheduleSection({
onValueChange={(v) =>
v && changeSchedule(frequency, time, Number(v))
}
modal={false}
>
<SelectTrigger className="h-auto gap-1 border-border/50 bg-muted/30 px-2.5 py-1 text-foreground text-xs hover:bg-muted/50 dark:bg-muted/30 dark:hover:bg-muted/50">
<SelectValue>
@@ -361,6 +363,7 @@ export function BackupScheduleSection({
<Select
value={time}
onValueChange={(v) => v && changeSchedule(frequency, v)}
modal={false}
>
<SelectTrigger className="h-auto gap-1 border-border/50 bg-muted/30 px-2.5 py-1 text-foreground text-xs hover:bg-muted/50 dark:bg-muted/30 dark:hover:bg-muted/50">
<SelectValue>
@@ -19,7 +19,7 @@ export function CastCarousel({ actors, titleType }: CastCarouselProps) {
{actors.length > 0 && (
<ScrollArea scrollFade hideScrollbar className="-mx-4 sm:-mx-0">
<div className="flex gap-4 px-4 py-2 sm:px-0">
<div className="flex gap-1 px-4 py-2 sm:px-0">
{actors.map((member, i) => (
<div key={member.id} className="w-[100px] shrink-0 sm:w-[120px]">
<div
@@ -49,7 +49,7 @@ export function CastCarousel({ actors, titleType }: CastCarouselProps) {
)}
</div>
<div className="w-full text-center">
<p className="line-clamp-2 font-medium text-xs leading-tight">
<p className="truncate font-medium text-xs">
{member.name}
</p>
{member.character && (