Add arrow to message bubbles and improve spacing

This commit is contained in:
Ajay Bura 2025-08-31 08:18:10 +05:30
parent 90ca8ca2c5
commit 01d57deea1
4 changed files with 72 additions and 12 deletions

View file

@ -1,18 +1,35 @@
import React, { ReactNode } from 'react'; import React, { ReactNode } from 'react';
import classNames from 'classnames';
import { Box, as } from 'folds'; import { Box, as } from 'folds';
import * as css from './layout.css'; import * as css from './layout.css';
type BubbleLayoutProps = { type BubbleLayoutProps = {
self?: boolean;
before?: ReactNode; before?: ReactNode;
}; };
export const BubbleLayout = as<'div', BubbleLayoutProps>(({ before, children, ...props }, ref) => ( export const BubbleLayout = as<'div', BubbleLayoutProps>(
<Box gap="300" {...props} ref={ref}> ({ self, before, children, ...props }, ref) => (
<Box className={css.BubbleBefore} shrink="No"> <Box direction={self ? 'RowReverse' : 'Row'} gap="300" {...props} ref={ref}>
{before} <Box className={css.BubbleBefore} shrink="No">
{before}
</Box>
<Box
className={classNames(
css.BubbleContent,
css.BubbleContentArrow,
self
? {
[css.BubbleContentArrowRight]: !!before,
}
: {
[css.BubbleContentArrowLeft]: !!before,
}
)}
direction="Column"
>
{children}
</Box>
</Box> </Box>
<Box className={css.BubbleContent} direction="Column"> )
{children} );
</Box>
</Box>
));

View file

@ -140,7 +140,44 @@ export const BubbleContent = style({
padding: config.space.S200, padding: config.space.S200,
backgroundColor: color.SurfaceVariant.Container, backgroundColor: color.SurfaceVariant.Container,
color: color.SurfaceVariant.OnContainer, color: color.SurfaceVariant.OnContainer,
borderRadius: config.radii.R400, borderRadius: config.radii.R500,
position: 'relative',
});
export const BubbleContentArrow = style({
selectors: {
'&::before': {
content: '',
display: 'inline-block',
background: 'inherit',
width: toRem(8),
height: toRem(8),
position: 'absolute',
transform: 'rotateZ(45deg)',
},
},
});
export const BubbleContentArrowLeft = style({
selectors: {
'&::before': {
left: toRem(-4),
top: config.radii.R500,
zIndex: 1,
borderBottomLeftRadius: toRem(2),
},
},
});
export const BubbleContentArrowRight = style({
selectors: {
'&::before': {
right: toRem(-4),
top: config.radii.R500,
zIndex: 1,
borderTopRightRadius: toRem(2),
},
},
}); });
export const Username = style({ export const Username = style({

View file

@ -723,6 +723,7 @@ export const Message = as<'div', MessageProps>(
const mx = useMatrixClient(); const mx = useMatrixClient();
const useAuthentication = useMediaAuthentication(); const useAuthentication = useMediaAuthentication();
const senderId = mEvent.getSender() ?? ''; const senderId = mEvent.getSender() ?? '';
const [hover, setHover] = useState(false); const [hover, setHover] = useState(false);
const { hoverProps } = useHover({ onHoverChange: setHover }); const { hoverProps } = useHover({ onHoverChange: setHover });
const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setHover }); const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setHover });
@ -746,7 +747,7 @@ export const Message = as<'div', MessageProps>(
<Box <Box
gap="300" gap="300"
direction={messageLayout === MessageLayout.Compact ? 'RowReverse' : 'Row'} direction={messageLayout === MessageLayout.Compact ? 'RowReverse' : 'Row'}
justifyContent="SpaceBetween" justifyContent={messageLayout === MessageLayout.Bubble ? undefined : 'SpaceBetween'}
alignItems="Baseline" alignItems="Baseline"
grow="Yes" grow="Yes"
> >
@ -875,7 +876,9 @@ export const Message = as<'div', MessageProps>(
return ( return (
<MessageBase <MessageBase
className={classNames(css.MessageBase, className)} className={classNames(css.MessageBase, className, {
[css.MessageBaseBubbleCollapsed]: messageLayout === MessageLayout.Bubble && collapse,
})}
tabIndex={0} tabIndex={0}
space={messageSpacing} space={messageSpacing}
collapse={collapse} collapse={collapse}

View file

@ -4,6 +4,9 @@ import { DefaultReset, config, toRem } from 'folds';
export const MessageBase = style({ export const MessageBase = style({
position: 'relative', position: 'relative',
}); });
export const MessageBaseBubbleCollapsed = style({
paddingTop: 0,
});
export const MessageOptionsBase = style([ export const MessageOptionsBase = style([
DefaultReset, DefaultReset,