Add arrow to message bubbles and improve spacing (#2474)
Some checks failed
Deploy to Netlify (dev) / Deploy to Netlify (push) Has been cancelled

* Add arrow to message bubbles and improve spacing

* make bubble message avatar smaller

* add bubble layout for event content

* adjust bubble arrow

* fix missing return statement for event content

* hide bubble for event content

* add new arrow to bubble message

* fix avatar username relative alignment

* fix types

* fix code block header background

* revert avatar size and make arrow less sharp

* show event messages timestamp to right when bubble is hidden

* fix avatar base css

* move message header outside bubble

* fix event time appears on left in hidden bubles
This commit is contained in:
Ajay Bura 2025-09-19 16:36:05 +05:30 committed by GitHub
parent 31efbf73b7
commit afc251aa7c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 111 additions and 27 deletions

View file

@ -1,6 +1,6 @@
import { Box, Icon, IconSrc } from 'folds';
import React, { ReactNode } from 'react';
import { CompactLayout, ModernLayout } from '..';
import { BubbleLayout, CompactLayout, ModernLayout } from '..';
import { MessageLayout } from '../../../state/settings';
export type EventContentProps = {
@ -30,9 +30,15 @@ export function EventContent({ messageLayout, time, iconSrc, content }: EventCon
</Box>
);
return messageLayout === MessageLayout.Compact ? (
<CompactLayout before={beforeJSX}>{msgContentJSX}</CompactLayout>
) : (
<ModernLayout before={beforeJSX}>{msgContentJSX}</ModernLayout>
);
if (messageLayout === MessageLayout.Compact) {
return <CompactLayout before={beforeJSX}>{msgContentJSX}</CompactLayout>;
}
if (messageLayout === MessageLayout.Bubble) {
return (
<BubbleLayout hideBubble before={beforeJSX}>
{msgContentJSX}
</BubbleLayout>
);
}
return <ModernLayout before={beforeJSX}>{msgContentJSX}</ModernLayout>;
}

View file

@ -1,18 +1,63 @@
import React, { ReactNode } from 'react';
import { Box, as } from 'folds';
import classNames from 'classnames';
import { Box, ContainerColor, as, color } from 'folds';
import * as css from './layout.css';
type BubbleArrowProps = {
variant: ContainerColor;
};
function BubbleLeftArrow({ variant }: BubbleArrowProps) {
return (
<svg
className={css.BubbleLeftArrow}
width="9"
height="8"
viewBox="0 0 9 8"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M9.00004 8V0H4.82847C3.04666 0 2.15433 2.15428 3.41426 3.41421L8.00004 8H9.00004Z"
fill={color[variant].Container}
/>
</svg>
);
}
type BubbleLayoutProps = {
hideBubble?: boolean;
before?: ReactNode;
header?: ReactNode;
};
export const BubbleLayout = as<'div', BubbleLayoutProps>(({ before, children, ...props }, ref) => (
<Box gap="300" {...props} ref={ref}>
<Box className={css.BubbleBefore} shrink="No">
{before}
export const BubbleLayout = as<'div', BubbleLayoutProps>(
({ hideBubble, before, header, children, ...props }, ref) => (
<Box gap="300" {...props} ref={ref}>
<Box className={css.BubbleBefore} shrink="No">
{before}
</Box>
<Box grow="Yes" direction="Column">
{header}
{hideBubble ? (
children
) : (
<Box>
<Box
className={
hideBubble
? undefined
: classNames(css.BubbleContent, before ? css.BubbleContentArrowLeft : undefined)
}
direction="Column"
>
{before ? <BubbleLeftArrow variant="SurfaceVariant" /> : null}
{children}
</Box>
</Box>
)}
</Box>
</Box>
<Box className={css.BubbleContent} direction="Column">
{children}
</Box>
</Box>
));
)
);

View file

@ -120,6 +120,7 @@ export const CompactHeader = style([
export const AvatarBase = style({
paddingTop: toRem(4),
transition: 'transform 200ms cubic-bezier(0, 0.8, 0.67, 0.97)',
display: 'flex',
alignSelf: 'start',
selectors: {
@ -133,14 +134,31 @@ export const ModernBefore = style({
minWidth: toRem(36),
});
export const BubbleBefore = style([ModernBefore]);
export const BubbleBefore = style({
minWidth: toRem(36),
});
export const BubbleContent = style({
maxWidth: toRem(800),
padding: config.space.S200,
backgroundColor: color.SurfaceVariant.Container,
color: color.SurfaceVariant.OnContainer,
borderRadius: config.radii.R400,
borderRadius: config.radii.R500,
position: 'relative',
});
export const BubbleContentArrowLeft = style({
borderTopLeftRadius: 0,
});
export const BubbleLeftArrow = style({
width: toRem(9),
height: toRem(8),
position: 'absolute',
top: 0,
left: toRem(-8),
zIndex: 1,
});
export const Username = style({