feat: skeleton

This commit is contained in:
tresabhi committed 2025-04-02 17:59:23 -05:00
1 parent 3d940f4b47
commit ba57d61af5
2 files changed
+57 -24

No files matched your search

@@ -5,6 +5,8 @@ import { times } from 'lodash-es';
import { getStrings } from '../../core/i18n/getStrings'; import { getStrings } from '../../core/i18n/getStrings';
import { Var } from '../../core/radix/var'; import { Var } from '../../core/radix/var';
import type { LocaleAcceptorProps } from '../../hooks/useLocale'; import type { LocaleAcceptorProps } from '../../hooks/useLocale';
import type { MaybeSkeletonComponentProps } from '../../types/maybeSkeletonComponentProps';
import { InlineSkeleton } from '../InlineSkeleton';
import './index.css'; import './index.css';
export interface DiscordWidget { export interface DiscordWidget {
@@ -57,21 +59,31 @@ const columns = times(COLUMN_COUNT, (index) => {
return filteredMembers.slice(start, end); return filteredMembers.slice(start, end);
}); });
function Member({ id, avatar_url, username, status }: Member) { function Member({
id,
avatar_url,
username,
status,
skeleton,
}: Member & MaybeSkeletonComponentProps) {
let statusColor: string; let statusColor: string;
switch (status) { if (skeleton) {
case Status.DND: statusColor = Var('gray-9');
statusColor = Var('red-9'); } else {
break; switch (status) {
case Status.DND:
statusColor = Var('red-9');
break;
case Status.Idle: case Status.Idle:
statusColor = Var('amber-9'); statusColor = Var('amber-9');
break; break;
case Status.Online: case Status.Online:
statusColor = Var('jade-9'); statusColor = Var('jade-9');
break; break;
}
} }
return ( return (
@@ -85,13 +97,25 @@ function Member({ id, avatar_url, username, status }: Member) {
}} }}
color="gray" color="gray"
> >
<Flex key={id} align="center" gap="2" flexShrink="0"> <Flex key={id} align="center" gap="2" flexShrink="0" width="8rem">
<Box width="1.5em" height="1.5em" flexShrink="0" position="relative"> <Box width="1.5em" height="1.5em" flexShrink="0" position="relative">
<img {!skeleton && (
src={avatar_url} <img
alt={`${username} profile picture`} src={avatar_url}
style={{ width: '100%', height: '100%', borderRadius: '50%' }} alt={`${username} profile picture`}
/> style={{ width: '100%', height: '100%', borderRadius: '50%' }}
/>
)}
{skeleton && (
<Box
style={{
width: '100%',
height: '100%',
borderRadius: '50%',
background: Var('gray-6'),
}}
/>
)}
<Box <Box
width="0.5em" width="0.5em"
@@ -103,19 +127,23 @@ function Member({ id, avatar_url, username, status }: Member) {
/> />
</Box> </Box>
{username} {skeleton && <InlineSkeleton style={{ flex: 1 }} />}
{!skeleton && username}
</Flex> </Flex>
</Text> </Text>
); );
} }
function Scroller({ index }: { index: number }) { function Scroller({
index,
skeleton,
}: { index: number } & MaybeSkeletonComponentProps) {
return ( return (
<Flex gap="6" className={`scroller-${index}`} pt="2"> <Flex gap="6" className={`scroller-${index}`} pt="2">
{columns.map((column) => ( {columns.map((column) => (
<Flex direction="column" gap="2"> <Flex direction="column" gap="2">
{column.map((member) => ( {column.map((member) => (
<Member key={member.id} {...member} /> <Member skeleton={skeleton} key={member.id} {...member} />
))} ))}
</Flex> </Flex>
))} ))}
@@ -123,7 +151,10 @@ function Scroller({ index }: { index: number }) {
); );
} }
export function DiscordPlug({ locale }: LocaleAcceptorProps) { export function DiscordPlug({
locale,
skeleton,
}: LocaleAcceptorProps & MaybeSkeletonComponentProps) {
const strings = getStrings(locale); const strings = getStrings(locale);
return ( return (
@@ -162,8 +193,8 @@ export function DiscordPlug({ locale }: LocaleAcceptorProps) {
transform: 'rotateX(60deg) rotateZ(-20deg)', transform: 'rotateX(60deg) rotateZ(-20deg)',
}} }}
> >
<Scroller index={0} /> <Scroller skeleton={skeleton} index={0} />
<Scroller index={1} /> <Scroller skeleton={skeleton} index={1} />
</Flex> </Flex>
</Box> </Box>
@@ -56,7 +56,9 @@ export const getStaticPaths = (() => {
flexGrow="1" flexGrow="1"
> >
<HomeLocaleSwitcher {locale} client:load /> <HomeLocaleSwitcher {locale} client:load />
<DiscordPlug {locale} /> <DiscordPlug {locale} client:only="react">
<DiscordPlug {locale} skeleton slot="fallback" />
</DiscordPlug>
</Flex> </Flex>
</Flex> </Flex>