Add emoji confetti bursts and component playground.
Support app.relay.emoji_confetti on jumbo emoji clicks with canvas physics, per-emoji particle profiles, and a fixed overlay that does not affect scroll. Also add a Vite playground for live component previews and theme hover preview.
This commit is contained in:
106
src/playground/mocks/PlaygroundProviders.tsx
Normal file
106
src/playground/mocks/PlaygroundProviders.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import { ReactNode, useEffect, useMemo, useState } from 'react';
|
||||
import { Provider as JotaiProvider } from 'jotai';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import {
|
||||
Box,
|
||||
OverlayContainerProvider,
|
||||
PopOutContainerProvider,
|
||||
TooltipContainerProvider,
|
||||
configClass,
|
||||
varsClass,
|
||||
} from 'folds';
|
||||
import { MatrixClientProvider } from '@cinny/app/hooks/useMatrixClient';
|
||||
import { RoomProvider, IsDirectRoomProvider } from '@cinny/app/hooks/useRoom';
|
||||
import { SpecVersionsProvider } from '@cinny/app/hooks/useSpecVersions';
|
||||
import { DarkTheme, ThemeContextProvider } from '@cinny/app/hooks/useTheme';
|
||||
import {
|
||||
PowerLevelsContextProvider,
|
||||
type IPowerLevels,
|
||||
} from '@cinny/app/hooks/usePowerLevels';
|
||||
import { ContainerColor } from '@cinny/app/styles/ContainerColor.css';
|
||||
import type { MatrixClient, Room } from 'matrix-js-sdk';
|
||||
import { MOCK_POWER_LEVELS, createMockRoom, mocks } from './matrix';
|
||||
|
||||
type Props = {
|
||||
children: ReactNode;
|
||||
client?: MatrixClient;
|
||||
room?: Room;
|
||||
isDirect?: boolean;
|
||||
powerLevels?: IPowerLevels;
|
||||
};
|
||||
|
||||
const SPEC_VERSIONS = {
|
||||
versions: ['v1.11', 'v1.12'],
|
||||
unstable_features: {
|
||||
'org.matrix.msc3916.stable': true,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps a preview in the providers Cinny UI pieces usually expect.
|
||||
* Overlay/popout/tooltip portals stay inside the stage (not the full window).
|
||||
*/
|
||||
export function PlaygroundProviders({
|
||||
children,
|
||||
client,
|
||||
room,
|
||||
isDirect = false,
|
||||
powerLevels = MOCK_POWER_LEVELS as IPowerLevels,
|
||||
}: Props) {
|
||||
const [portal, setPortal] = useState<HTMLDivElement | null>(null);
|
||||
const queryClient = useMemo(() => new QueryClient(), []);
|
||||
const resolvedClient = client ?? mocks.client;
|
||||
// Always provide a room with `.client` set — RoomInput/useStateEvent require it.
|
||||
const resolvedRoom = useMemo(() => {
|
||||
if (room) return room;
|
||||
return createMockRoom({ client: resolvedClient });
|
||||
}, [room, resolvedClient]);
|
||||
|
||||
useEffect(() => {
|
||||
document.body.classList.add(configClass, varsClass, ...DarkTheme.classNames);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="preview-frame">
|
||||
<ThemeContextProvider value={DarkTheme}>
|
||||
<TooltipContainerProvider value={portal ?? undefined}>
|
||||
<PopOutContainerProvider value={portal ?? undefined}>
|
||||
<OverlayContainerProvider value={portal ?? undefined}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<JotaiProvider>
|
||||
<MemoryRouter>
|
||||
<SpecVersionsProvider value={SPEC_VERSIONS}>
|
||||
<MatrixClientProvider value={resolvedClient}>
|
||||
<RoomProvider value={resolvedRoom}>
|
||||
<IsDirectRoomProvider value={isDirect}>
|
||||
<PowerLevelsContextProvider value={powerLevels}>
|
||||
<Box
|
||||
className={ContainerColor({ variant: 'Surface' })}
|
||||
style={{
|
||||
width: '100%',
|
||||
minHeight: '100%',
|
||||
height: '100%',
|
||||
padding: 16,
|
||||
borderRadius: 8,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
</PowerLevelsContextProvider>
|
||||
</IsDirectRoomProvider>
|
||||
</RoomProvider>
|
||||
</MatrixClientProvider>
|
||||
</SpecVersionsProvider>
|
||||
</MemoryRouter>
|
||||
</JotaiProvider>
|
||||
</QueryClientProvider>
|
||||
</OverlayContainerProvider>
|
||||
</PopOutContainerProvider>
|
||||
</TooltipContainerProvider>
|
||||
</ThemeContextProvider>
|
||||
{/* Host for folds Overlay/Dialog portals — contained by .preview-frame */}
|
||||
<div className="preview-portal" ref={setPortal} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user