feat(members): carve rounded TL/BL on members drawer with 12px void seam to chat and extract VoidGap helper consolidating four per-pane seams
This commit is contained in:
parent
b4f77b6f80
commit
3fb5f012e5
2 changed files with 58 additions and 28 deletions
|
|
@ -1,8 +1,18 @@
|
|||
import { keyframes, style } from '@vanilla-extract/css';
|
||||
import { config, toRem } from 'folds';
|
||||
import { VOJO_HORSESHOE_RADIUS_PX } from '../../styles/horseshoe';
|
||||
|
||||
// Left edge carves TL + BL the same way `RoomViewProfileSidePanel` does
|
||||
// across the 12px horseshoe void gap rendered by Room.tsx — same design
|
||||
// language as the page-nav <-> chat split. `overflow: hidden` keeps the
|
||||
// rounded corners clean against header / scroll content; the void
|
||||
// colour beneath is painted by the parent flex row, not by the panel
|
||||
// itself.
|
||||
export const MembersDrawer = style({
|
||||
width: toRem(266),
|
||||
overflow: 'hidden',
|
||||
borderTopLeftRadius: toRem(VOJO_HORSESHOE_RADIUS_PX),
|
||||
borderBottomLeftRadius: toRem(VOJO_HORSESHOE_RADIUS_PX),
|
||||
});
|
||||
|
||||
export const MembersDrawerHeader = style({
|
||||
|
|
|
|||
|
|
@ -38,6 +38,22 @@ type RoomProps = {
|
|||
renderRoomView?: (props: { eventId?: string }) => React.ReactNode;
|
||||
};
|
||||
|
||||
// 12px black seam between the chat column and the right-side pane (profile,
|
||||
// media, thread, members). Every active right-side pane renders one of
|
||||
// these locally; the parent flex row is painted the same void colour by
|
||||
// `Room` so each pane's TL/BL rounded carve can expose the void cleanly.
|
||||
function VoidGap() {
|
||||
return (
|
||||
<Box
|
||||
shrink="No"
|
||||
style={{
|
||||
width: toRem(VOJO_HORSESHOE_GAP_PX),
|
||||
backgroundColor: VOJO_HORSESHOE_VOID_COLOR,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function Room({ renderRoomView }: RoomProps) {
|
||||
const { eventId } = useParams();
|
||||
const room = useRoom();
|
||||
|
|
@ -115,18 +131,40 @@ export function Room({ renderRoomView }: RoomProps) {
|
|||
// parent void can't bleed through any transparent slivers.
|
||||
const profileOpen = !!useAtomValue(userRoomProfileAtom);
|
||||
const mediaOpen = !!useAtomValue(mediaViewerAtom);
|
||||
const callView = room.isCallRoom();
|
||||
const showProfileHorseshoe = profileOpen && !isMobile && !showThreadDrawer;
|
||||
// Media viewer side pane on desktop — same horseshoe seam idiom
|
||||
// as the profile pane. The two are mutually exclusive in practice
|
||||
// (the open hooks clear the other atom), so at most one shows at
|
||||
// a time; both feed into `showAnyHorseshoe` for the chat-column
|
||||
// bg + the void-gap render gate.
|
||||
// a time; both feed into `paintParentVoid` for the chat-column bg
|
||||
// and locally gate the shared `<VoidGap />` seam.
|
||||
const showMediaHorseshoe = mediaOpen && !isMobile && !showThreadDrawer;
|
||||
// Thread drawer side pane on desktop. Mobile hides the chat column
|
||||
// entirely (`drawerHidesChat`) so the seam doesn't apply there.
|
||||
const showThreadHorseshoe = showThreadDrawer && !isMobile;
|
||||
const showAnyHorseshoe =
|
||||
showProfileHorseshoe || showMediaHorseshoe || showThreadHorseshoe;
|
||||
// Members drawer side pane — mirrors the same horseshoe seam as the
|
||||
// profile/media/thread panes. Gated on the exact same conditions that
|
||||
// mount `<MembersDrawer>` below (group room, desktop, drawer setting on,
|
||||
// no thread overlay, no call surface) so the void gap appears iff the
|
||||
// pane appears.
|
||||
const showMembersHorseshoe =
|
||||
!callView &&
|
||||
!isOneOnOne &&
|
||||
!showThreadDrawer &&
|
||||
screenSize === ScreenSize.Desktop &&
|
||||
isDrawer;
|
||||
// True whenever any right-side pane is mounted. Drives the parent flex
|
||||
// row's void background and the chat column's explicit Background paint
|
||||
// — both prevent the chat-side surface from bleeding through the carved
|
||||
// TL/BL of whichever pane is open. The per-pane `<VoidGap />` decisions
|
||||
// remain local to each render site (a single `paintParentVoid` gate
|
||||
// would over-render when only members is open — there is no
|
||||
// profile/media slot to anchor it to).
|
||||
const paintParentVoid =
|
||||
showProfileHorseshoe ||
|
||||
showMediaHorseshoe ||
|
||||
showThreadHorseshoe ||
|
||||
showMembersHorseshoe;
|
||||
|
||||
useKeyDown(
|
||||
window,
|
||||
|
|
@ -152,8 +190,6 @@ export function Room({ renderRoomView }: RoomProps) {
|
|||
)
|
||||
);
|
||||
|
||||
const callView = room.isCallRoom();
|
||||
|
||||
// Disable the atom-driven media viewer when the desktop thread
|
||||
// drawer is open — the side-pane mount block below is gated on
|
||||
// `!showThreadDrawer`, so the new viewer's right pane wouldn't
|
||||
|
|
@ -181,7 +217,7 @@ export function Room({ renderRoomView }: RoomProps) {
|
|||
<Box
|
||||
grow="Yes"
|
||||
style={
|
||||
showAnyHorseshoe
|
||||
paintParentVoid
|
||||
? { backgroundColor: VOJO_HORSESHOE_VOID_COLOR }
|
||||
: undefined
|
||||
}
|
||||
|
|
@ -191,7 +227,7 @@ export function Room({ renderRoomView }: RoomProps) {
|
|||
grow="Yes"
|
||||
direction="Column"
|
||||
className={
|
||||
showAnyHorseshoe
|
||||
paintParentVoid
|
||||
? ContainerColor({ variant: 'Background' })
|
||||
: undefined
|
||||
}
|
||||
|
|
@ -213,7 +249,7 @@ export function Room({ renderRoomView }: RoomProps) {
|
|||
grow="Yes"
|
||||
direction="Column"
|
||||
className={
|
||||
showAnyHorseshoe
|
||||
paintParentVoid
|
||||
? ContainerColor({ variant: 'Background' })
|
||||
: undefined
|
||||
}
|
||||
|
|
@ -245,15 +281,7 @@ export function Room({ renderRoomView }: RoomProps) {
|
|||
exclusive via the open hooks. */}
|
||||
{!isMobile && !showThreadDrawer && (
|
||||
<>
|
||||
{showAnyHorseshoe && (
|
||||
<Box
|
||||
shrink="No"
|
||||
style={{
|
||||
width: toRem(VOJO_HORSESHOE_GAP_PX),
|
||||
backgroundColor: VOJO_HORSESHOE_VOID_COLOR,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{(showProfileHorseshoe || showMediaHorseshoe) && <VoidGap />}
|
||||
<RoomViewProfileSidePanel />
|
||||
<RoomViewMediaSidePanel />
|
||||
</>
|
||||
|
|
@ -277,21 +305,13 @@ export function Room({ renderRoomView }: RoomProps) {
|
|||
screenSize === ScreenSize.Desktop &&
|
||||
isDrawer && (
|
||||
<>
|
||||
<Line variant="Background" direction="Vertical" size="300" />
|
||||
{showMembersHorseshoe && <VoidGap />}
|
||||
<MembersDrawer key={room.roomId} room={room} members={members} />
|
||||
</>
|
||||
)}
|
||||
{showThreadDrawer && decodedRootId && parentRoomPath && (
|
||||
<>
|
||||
{showThreadHorseshoe && (
|
||||
<Box
|
||||
shrink="No"
|
||||
style={{
|
||||
width: toRem(VOJO_HORSESHOE_GAP_PX),
|
||||
backgroundColor: VOJO_HORSESHOE_VOID_COLOR,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{showThreadHorseshoe && <VoidGap />}
|
||||
<ThreadDrawer
|
||||
key={`${room.roomId}/${decodedRootId}`}
|
||||
room={room}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue