mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
feat(navigator): responsive layout + saved-search refinement (P4 wave 1c)
- Stack sidebar above results below sm; cap card width to viewport - Fix tab-bar wrap overlapping content on narrow screens (max-height/height/flex reset) - Saved-search rows: whole row opens search, hover-reveal delete (no layout shift), bolt icon, empty state - Hover affordance on navigator grid items and saved-search rows
This commit is contained in:
@@ -109,7 +109,7 @@ export const NavigatorView: FC<{}> = props =>
|
||||
<>
|
||||
{ isVisible &&
|
||||
<NitroCard
|
||||
className={ `${ isOpenSavesSearches ? 'w-[600px] min-w-[600px]' : 'w-navigator-w min-w-navigator-w' } h-navigator-h min-h-navigator-h` }
|
||||
className={ `${ isOpenSavesSearches ? 'w-[600px] sm:min-w-[600px]' : 'w-navigator-w sm:min-w-navigator-w' } max-w-[calc(100vw-1rem)] h-navigator-h min-h-navigator-h` }
|
||||
uniqueKey="navigator">
|
||||
<NitroCard.Header
|
||||
headerText={ LocalizeText(isCreatorOpen ? 'navigator.createroom.title' : 'navigator.title') }
|
||||
@@ -136,12 +136,12 @@ export const NavigatorView: FC<{}> = props =>
|
||||
</NitroCard.Tabs>
|
||||
<NitroCard.Content>
|
||||
{ !isCreatorOpen &&
|
||||
<div className="flex h-full overflow-hidden gap-2">
|
||||
<div className="flex flex-col sm:flex-row h-full overflow-hidden gap-2">
|
||||
{ isOpenSavesSearches &&
|
||||
<div className="overflow-hidden pr-1 shrink-0">
|
||||
<div className="overflow-hidden pr-1 shrink-0 w-full sm:w-auto max-h-40 sm:max-h-none">
|
||||
<NavigatorSearchSavesResultView searches={ navigatorSearches || [] } />
|
||||
</div> }
|
||||
<div className="flex flex-col w-full overflow-hidden gap-2">
|
||||
<div className="flex flex-col w-full min-h-0 overflow-hidden gap-2">
|
||||
<NavigatorSearchView searchResult={ searchResult } />
|
||||
<div ref={ elementRef } className="flex flex-col flex-1 min-h-0 overflow-auto gap-2">
|
||||
{ (isFetching && !searchResult) &&
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NavigatorDeleteSavedSearchComposer, NavigatorSavedSearch, NavigatorSearchComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useState } from 'react';
|
||||
import { FC, MouseEvent } from 'react';
|
||||
import { FaBolt } from 'react-icons/fa';
|
||||
import { LocalizeText, SendMessageComposer } from '../../../../api';
|
||||
import { Flex, Text } from '../../../../common';
|
||||
|
||||
@@ -11,7 +12,6 @@ export interface NavigatorSearchSavesResultItemViewProps
|
||||
export const NavigatorSearchSavesResultItemView: FC<NavigatorSearchSavesResultItemViewProps> = props =>
|
||||
{
|
||||
const { search = null } = props;
|
||||
const [ isHovered, setIsHovered ] = useState(false);
|
||||
|
||||
const getResultTitle = () =>
|
||||
{
|
||||
@@ -24,23 +24,33 @@ export const NavigatorSearchSavesResultItemView: FC<NavigatorSearchSavesResultIt
|
||||
return ('navigator.searchcode.title.' + name);
|
||||
};
|
||||
|
||||
const openSearch = () => SendMessageComposer(new NavigatorSearchComposer(search.code.split('.').reverse()[0], search.filter));
|
||||
|
||||
const deleteSearch = (event: MouseEvent) =>
|
||||
{
|
||||
event.stopPropagation();
|
||||
SendMessageComposer(new NavigatorDeleteSavedSearchComposer(search.id));
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex grow pointer alignItems="center" gap={ 1 } onMouseEnter={ () => setIsHovered(true) } onMouseLeave={ () => setIsHovered(false) }>
|
||||
{ isHovered &&
|
||||
<i
|
||||
className="nitro-icon icon-navigator-search-delete cursor-pointer flex-shrink-0"
|
||||
title={ LocalizeText('navigator.tooltip.remove.saved.search') }
|
||||
onClick={ () => SendMessageComposer(new NavigatorDeleteSavedSearchComposer(search.id)) }
|
||||
/> }
|
||||
<Text
|
||||
small
|
||||
pointer
|
||||
variant="black"
|
||||
title={ LocalizeText('navigator.tooltip.open.saved.search') }
|
||||
onClick={ () => SendMessageComposer(new NavigatorSearchComposer(search.code.split('.').reverse()[0], search.filter)) }
|
||||
>
|
||||
<Flex
|
||||
grow
|
||||
pointer
|
||||
alignItems="center"
|
||||
gap={ 1 }
|
||||
className="saved-search-row group px-1 py-0.5"
|
||||
title={ LocalizeText('navigator.tooltip.open.saved.search') }
|
||||
onClick={ openSearch }
|
||||
>
|
||||
<FaBolt className="text-orange-500 shrink-0 text-[10px]" />
|
||||
<Text small pointer truncate variant="black" className="grow! min-w-0">
|
||||
{ LocalizeText(getResultTitle()) }
|
||||
</Text>
|
||||
<i
|
||||
className="nitro-icon icon-navigator-search-delete cursor-pointer flex-shrink-0 opacity-0 transition-opacity group-hover:opacity-100"
|
||||
title={ LocalizeText('navigator.tooltip.remove.saved.search') }
|
||||
onClick={ deleteSearch }
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -15,16 +15,19 @@ export const NavigatorSearchSavesResultView: FC<NavigatorSearchSavesResultViewPr
|
||||
const { searches = [] } = props;
|
||||
|
||||
return (
|
||||
<Column className="nitro-navigator-search-saves-result min-w-[100px]">
|
||||
<Flex className="rounded px-2 py-1 bg-orange-500" gap={ 1 } alignItems="center">
|
||||
<Column className="nitro-navigator-search-saves-result h-full min-w-[100px] sm:w-[150px]" gap={ 1 }>
|
||||
<Flex className="rounded px-2 py-1 bg-orange-500 shrink-0" gap={ 1 } alignItems="center">
|
||||
<FaBolt color="white" />
|
||||
<Text variant="white">{ LocalizeText('navigator.quick.links.title') }</Text>
|
||||
<Text variant="white" truncate>{ LocalizeText('navigator.quick.links.title') }</Text>
|
||||
</Flex>
|
||||
<Column className="p-1 overflow-x-hidden overflow-y-auto">
|
||||
{ (searches && searches.length > 0) &&
|
||||
searches.map((search: NavigatorSavedSearch) => (
|
||||
<Column className="flex-1 min-h-0 p-1 overflow-x-hidden overflow-y-auto" gap={ 0 }>
|
||||
{ (searches && searches.length > 0)
|
||||
? searches.map((search: NavigatorSavedSearch) => (
|
||||
<NavigatorSearchSavesResultItemView key={ search.id } search={ search } />
|
||||
)) }
|
||||
))
|
||||
: <Flex center className="py-4 opacity-30">
|
||||
<FaBolt className="text-orange-500" size={ 22 } />
|
||||
</Flex> }
|
||||
</Column>
|
||||
</Column>
|
||||
);
|
||||
|
||||
@@ -476,6 +476,24 @@ body {
|
||||
border-color: #aeb7aa !important;
|
||||
}
|
||||
|
||||
.navigator-grid .navigator-item {
|
||||
border-radius: 6px;
|
||||
transition: background-color .15s ease;
|
||||
}
|
||||
|
||||
.navigator-grid .navigator-item:hover {
|
||||
background: rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
.nitro-navigator-search-saves-result .saved-search-row {
|
||||
border-radius: 6px;
|
||||
transition: background-color .15s ease;
|
||||
}
|
||||
|
||||
.nitro-navigator-search-saves-result .saved-search-row:hover {
|
||||
background: rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
.nitro-card-divider {
|
||||
border-color: #c4cabf !important;
|
||||
box-shadow: none !important;
|
||||
@@ -523,6 +541,9 @@ body {
|
||||
flex-wrap: wrap;
|
||||
gap: 3px;
|
||||
padding: 4px 6px 0;
|
||||
max-height: none;
|
||||
height: auto;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.nitro-card-tab-item {
|
||||
|
||||
Reference in New Issue
Block a user