Add Stationery and Stationery Dark themes with notebook chrome.
Manila folders, ruled chat, post-it nav, and folder tabs; dark variant uses Catppuccin Mocha colors with muted stickies and soft glows.
This commit is contained in:
@@ -7,6 +7,8 @@ import { getHexcodeForEmoji, getShortcodeFor } from '../../plugins/emoji';
|
||||
import { getMemberDisplayName } from '../../utils/room';
|
||||
import { eventWithShortcode, getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
||||
const MAX_STICKER_STACK = 4;
|
||||
|
||||
export const Reaction = as<
|
||||
'button',
|
||||
{
|
||||
@@ -15,35 +17,67 @@ export const Reaction = as<
|
||||
reaction: string;
|
||||
useAuthentication?: boolean;
|
||||
}
|
||||
>(({ className, mx, count, reaction, useAuthentication, ...props }, ref) => (
|
||||
<Box
|
||||
as="button"
|
||||
className={classNames(css.Reaction, className)}
|
||||
alignItems="Center"
|
||||
shrink="No"
|
||||
gap="200"
|
||||
{...props}
|
||||
ref={ref}
|
||||
>
|
||||
<Text className={css.ReactionText} as="span" size="T400">
|
||||
{reaction.startsWith('mxc://') ? (
|
||||
<img
|
||||
className={css.ReactionImg}
|
||||
src={mxcUrlToHttp(mx, reaction, useAuthentication) ?? reaction
|
||||
}
|
||||
alt={reaction}
|
||||
/>
|
||||
) : (
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
{reaction}
|
||||
>(({ className, mx, count, reaction, useAuthentication, ...props }, ref) => {
|
||||
const stackCount = Math.min(Math.max(count, 1), MAX_STICKER_STACK);
|
||||
const showCount = count > 2;
|
||||
const isCustomEmoji = reaction.startsWith('mxc://');
|
||||
const customSrc = isCustomEmoji
|
||||
? mxcUrlToHttp(mx, reaction, useAuthentication) ?? reaction
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<Box
|
||||
as="button"
|
||||
className={classNames(css.Reaction, className)}
|
||||
alignItems="Center"
|
||||
shrink="No"
|
||||
gap="200"
|
||||
data-reaction=""
|
||||
data-reaction-stack={stackCount}
|
||||
aria-label={`${reaction}, ${count}`}
|
||||
{...props}
|
||||
ref={ref}
|
||||
>
|
||||
<span className={css.ReactionStack} data-reaction-stack-layer="">
|
||||
{Array.from({ length: stackCount }, (_, i) => {
|
||||
// Draw back-to-front so the top sticker is the last layer
|
||||
const layer = stackCount - 1 - i;
|
||||
return (
|
||||
<Text
|
||||
key={layer}
|
||||
className={css.ReactionText}
|
||||
as="span"
|
||||
size="T400"
|
||||
data-reaction-sticker=""
|
||||
style={{
|
||||
['--sticker-i' as string]: layer,
|
||||
zIndex: i + 1,
|
||||
}}
|
||||
aria-hidden={i < stackCount - 1 ? true : undefined}
|
||||
>
|
||||
{isCustomEmoji ? (
|
||||
<img
|
||||
className={css.ReactionImg}
|
||||
src={customSrc}
|
||||
alt={i === stackCount - 1 ? reaction : ''}
|
||||
/>
|
||||
) : (
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
{reaction}
|
||||
</Text>
|
||||
)}
|
||||
</Text>
|
||||
);
|
||||
})}
|
||||
</span>
|
||||
{showCount && (
|
||||
<Text as="span" size="T300" data-reaction-count="">
|
||||
{count}
|
||||
</Text>
|
||||
)}
|
||||
</Text>
|
||||
<Text as="span" size="T300">
|
||||
{count}
|
||||
</Text>
|
||||
</Box>
|
||||
));
|
||||
</Box>
|
||||
);
|
||||
});
|
||||
|
||||
type ReactionTooltipMsgProps = {
|
||||
room: Room;
|
||||
|
||||
Reference in New Issue
Block a user