This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / components / ui / User.svelte
1.9 kB 88 lines
1<script module lang="ts"> 2 import { tv, type VariantProps } from "tailwind-variants"; 3 import type { AvatarSize } from "./Avatar.svelte"; 4 5 export const user = tv({ 6 slots: { 7 root: "inline-flex items-center", 8 handle: "truncate" 9 }, 10 variants: { 11 size: { 12 header: { 13 root: "gap-2", 14 handle: "typography-heading-4" 15 }, 16 large: { 17 root: "gap-1.5", 18 handle: "typography-paragraph-large" 19 }, 20 regular: { 21 root: "gap-1", 22 handle: "typography-paragraph-regular" 23 }, 24 small: { 25 root: "gap-1", 26 handle: "typography-paragraph-small" 27 }, 28 mini: { 29 root: "gap-1", 30 handle: "typography-paragraph-mini" 31 } 32 } 33 }, 34 defaultVariants: { 35 size: "regular" 36 } 37 }); 38 39 export type UserVariants = VariantProps<typeof user>; 40 41 // the avatar names its own size rather than taking a class through a slot, so 42 // that it can pick the image width it needs. header and large share a rung 43 // because in Figma they differ only in the text style beside the circle. 44 const avatarSize = { 45 header: "large", 46 large: "large", 47 regular: "regular", 48 small: "small", 49 mini: "mini" 50 } satisfies Record<NonNullable<UserVariants["size"]>, AvatarSize>; 51</script> 52 53<script lang="ts"> 54 import Avatar from "./Avatar.svelte"; 55 56 interface Props { 57 handle?: string; 58 did?: string; 59 size?: UserVariants["size"]; 60 showImage?: boolean; 61 showText?: boolean; 62 class?: string; 63 avatarClass?: string; 64 handleClass?: string; 65 } 66 67 let { 68 handle, 69 did, 70 size = "regular", 71 showImage = true, 72 showText = true, 73 class: className, 74 avatarClass, 75 handleClass 76 }: Props = $props(); 77 78 const slots = $derived(user({ size })); 79</script> 80 81<span class={slots.root({ class: className })}> 82 {#if showImage} 83 <Avatar {did} {handle} size={avatarSize[size]} class={avatarClass} /> 84 {/if} 85 {#if showText && handle} 86 <span class={slots.handle({ class: handleClass })}>{handle}</span> 87 {/if} 88</span>