diff --git a/src/app/features/message-search/SearchFilters.tsx b/src/app/features/message-search/SearchFilters.tsx index 561f89a3..21b304a8 100644 --- a/src/app/features/message-search/SearchFilters.tsx +++ b/src/app/features/message-search/SearchFilters.tsx @@ -40,6 +40,7 @@ import { import { DebounceOptions, useDebounce } from '../../hooks/useDebounce'; import { VirtualTile } from '../../components/virtualizer'; import { stopPropagation } from '../../utils/keyboard'; +import { SectionLabel } from '../settings/styles.css'; type OrderButtonProps = { order?: string; @@ -278,7 +279,7 @@ function SelectRoomButton({ roomList, selectedRooms, onChange }: SelectRoomButto - {t('Search.filter')} + + + {t('Search.filter')} + } - outlined + radii="Pill" onClick={() => onGlobalChange()} > {defaultRoomsFilterName} {allowGlobal && ( } - outlined + radii="Pill" onClick={() => onGlobalChange(true)} > {t('Search.global')} @@ -400,7 +403,7 @@ export function SearchFilters({ return ( onSelectedRoomsChange(selectedRooms.filter((rId) => rId !== roomId))} radii="Pill" before={ diff --git a/src/app/features/message-search/SearchInput.tsx b/src/app/features/message-search/SearchInput.tsx index 8b1efe13..ed089918 100644 --- a/src/app/features/message-search/SearchInput.tsx +++ b/src/app/features/message-search/SearchInput.tsx @@ -1,7 +1,10 @@ import React, { FormEventHandler, RefObject } from 'react'; -import { Box, Text, Input, Icon, Icons, Spinner, Chip, config } from 'folds'; +import { Box, Text, Icon, Icons, Spinner, Chip, color, config, toRem } from 'folds'; import { useTranslation } from 'react-i18next'; +// Dawn hairline divider (the canon's rgba(255,255,255,0.06–0.08) row line). +const HAIRLINE = '1px solid rgba(255, 255, 255, 0.08)'; + type SearchProps = { active?: boolean; loading?: boolean; @@ -24,46 +27,61 @@ export function SearchInput({ active, loading, searchInputRef, onSearch, onReset }; return ( - - - {t('Search.search')} - - ) : ( - - ) - } - after={ - active ? ( - } - onClick={onReset} - > - {t('Search.clear')} - - ) : ( - - {t('Search.enter')} - - ) - } - /> + + {/* Integrated hairline search row — shares the panel material instead of + a boxed folds Input under a floating «Поиск» label. */} + + {active && loading ? ( + + ) : ( + + )} + + {active ? ( + } + onClick={onReset} + > + {t('Search.clear')} + + ) : ( + + {t('Search.enter')} + + )} + ); } diff --git a/src/app/features/message-search/SearchResultGroup.tsx b/src/app/features/message-search/SearchResultGroup.tsx index fd0567fe..eaeed321 100644 --- a/src/app/features/message-search/SearchResultGroup.tsx +++ b/src/app/features/message-search/SearchResultGroup.tsx @@ -35,7 +35,6 @@ import * as customHtmlCss from '../../styles/CustomHtml.css'; import { RoomAvatar, RoomIcon } from '../../components/room-avatar'; import { getMemberAvatarMxc, getMemberDisplayName, getRoomAvatarUrl } from '../../utils/room'; import { ResultItem } from './useMessageSearch'; -import { SequenceCard } from '../../components/sequence-card'; import { UserAvatar } from '../../components/user-avatar'; import { useMentionClickHandler } from '../../hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '../../hooks/useSpoilerClickHandler'; @@ -53,6 +52,9 @@ import { import { useRoomCreators } from '../../hooks/useRoomCreators'; import { useRoomCreatorsTag } from '../../hooks/useRoomCreatorsTag'; +// Dawn hairline for the grouped result-list panel + its internal row dividers. +const HAIRLINE = '1px solid rgba(255, 255, 255, 0.08)'; + type SearchResultGroupProps = { room: Room; highlights: string[]; @@ -215,8 +217,17 @@ export function SearchResultGroup({ - - {items.map((item) => { + {/* Grouped hairline-divided list — one panel, internal row dividers, + instead of a pile of floating SequenceCard cards. */} + + {items.map((item, itemIndex) => { const { event } = item; const displayName = @@ -247,11 +258,13 @@ export function SearchResultGroup({ const usernameColor = legacyUsernameColor ? colorMXID(event.sender) : tagColor; return ( - {tagIconSrc && } - {t('Search.open')} @@ -314,7 +327,7 @@ export function SearchResultGroup({ )} {renderMatrixEvent(event.type, false, event, displayName, getContent)} - + ); })} diff --git a/src/app/features/search/Search.tsx b/src/app/features/search/Search.tsx index f7d575d2..772ef6fe 100644 --- a/src/app/features/search/Search.tsx +++ b/src/app/features/search/Search.tsx @@ -2,11 +2,10 @@ import FocusTrap from 'focus-trap-react'; import { Avatar, Box, + color, config, Icon, Icons, - Input, - Line, MenuItem, Modal, Overlay, @@ -16,7 +15,7 @@ import { toRem, } from 'folds'; import React, { useCallback } from 'react'; -import { Trans, useTranslation } from 'react-i18next'; +import { useTranslation } from 'react-i18next'; import { isKeyHotkey } from 'is-hotkey'; import { useAtom } from 'jotai'; import { useMatrixClient } from '../../hooks/useMatrixClient'; @@ -35,10 +34,11 @@ import { UnreadBadge, UnreadBadgeCenter } from '../../components/unread-badge'; import { searchModalAtom } from '../../state/searchModal'; import { useKeyDown } from '../../hooks/useKeyDown'; import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; -import { KeySymbol } from '../../utils/key-symbol'; -import { isMacOS } from '../../utils/user-agent'; import { getDmUserId, useRoomSearch } from './useRoomSearch'; +// Dawn hairline divider (the canon's rgba(255,255,255,0.06–0.08) row line). +const HAIRLINE = '1px solid rgba(255, 255, 255, 0.08)'; + type SearchProps = { requestClose: () => void; }; @@ -91,22 +91,45 @@ export function Search({ requestClose }: SearchProps) { }, }} > - + + {/* ── Input row: hairline-divided, integrated (not a boxed Input) ── */} - + } + autoComplete="off" onChange={handleInputChange} onKeyDown={handleInputKeyDown} + style={{ + flex: 1, + appearance: 'none', + border: 'none', + outline: 'none', + background: 'transparent', + font: 'inherit', + fontSize: toRem(15), + color: color.Background.OnContainer, + minWidth: 0, + }} /> @@ -131,7 +154,7 @@ export function Search({ requestClose }: SearchProps) { )} {roomsToRender.length > 0 && ( -
+
{roomsToRender.map((roomId, index) => { const room = getRoom(roomId); if (!room) return null; @@ -153,6 +176,7 @@ export function Search({ requestClose }: SearchProps) { exactParents && guessPerfectParent(mx, roomId, Array.from(exactParents)); const unread = roomToUnread.get(roomId); + const focused = listFocus.index === index; return ( {dmUserServer && ( - - {dmUserServer} + + {dmUserServer} )} {!dm && perfectOrphanParent && ( - - {getRoom(perfectOrphanParent)?.name ?? perfectOrphanParent} + + {getRoom(perfectOrphanParent)?.name ?? perfectOrphanParent} )} {unread && ( @@ -221,7 +261,13 @@ export function Search({ requestClose }: SearchProps) { : room.name} {dmUsername && ( - + @ {queryHighlightRegex ? highlightText(queryHighlightRegex, [dmUsername]) @@ -241,14 +287,25 @@ export function Search({ requestClose }: SearchProps) { )} - - - - }} - /> + {/* ── Mono keyboard-hint footer (hairline-divided) ── */} + + + {`↑↓ ${t('Search.kbd_select')}`} + + + {`↵ ${t('Search.kbd_open')}`} + + + {`esc ${t('Search.kbd_close')}`}