diff options
Diffstat (limited to 'src/ui/objects/Avatar.tsx')
| -rw-r--r-- | src/ui/objects/Avatar.tsx | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/ui/objects/Avatar.tsx b/src/ui/objects/Avatar.tsx new file mode 100644 index 0000000..459af12 --- /dev/null +++ b/src/ui/objects/Avatar.tsx | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | import type { HTMLTag, Polymorphic } from "corvos/plugins/jsx.ts"; | ||
| 2 | |||
| 3 | import { StatusIndicator } from "$/ui/objects/StatusIndicator.tsx"; | ||
| 4 | |||
| 5 | export type Props<Tag extends HTMLTag> = Polymorphic<{ | ||
| 6 | "as"?: Tag; | ||
| 7 | "src"?: string; | ||
| 8 | "icon"?: JSX.Element; | ||
| 9 | "children"?: JSX.Element; | ||
| 10 | "class"?: string; | ||
| 11 | "circle"?: boolean; | ||
| 12 | "placeholder"?: boolean; | ||
| 13 | "color"?: `hsl(${number}, ${number}%, ${number}%)`; | ||
| 14 | "color2"?: `hsl(${number}, ${number}%, ${number}%)`; | ||
| 15 | "color-angle"?: number | `${number}`; | ||
| 16 | "size"?: "xs" | "sm" | "lg" | "xl" | "xxl" | "xxxl"; | ||
| 17 | "status"?: "accent" | "positive" | "negative" | "warning"; | ||
| 18 | }>; | ||
| 19 | |||
| 20 | const hslRegex = /^hsl\(([\d.]+), ([\d.]+%), ([\d.]+%)\)$/; | ||
| 21 | |||
| 22 | export const Avatar = <T extends HTMLTag = "div">({ | ||
| 23 | children, | ||
| 24 | as: Tag = "div" as T, | ||
| 25 | src, | ||
| 26 | icon, | ||
| 27 | circle, | ||
| 28 | placeholder, | ||
| 29 | color, | ||
| 30 | color2, | ||
| 31 | "color-angle": colorAngle, | ||
| 32 | size, | ||
| 33 | status, | ||
| 34 | class: cls, | ||
| 35 | ...props | ||
| 36 | }: Props<T>) => ( | ||
| 37 | <Tag | ||
| 38 | class:list={[ | ||
| 39 | "o-avatar", | ||
| 40 | { | ||
| 41 | "o-avatar--circle": circle, | ||
| 42 | "o-avatar--placeholder": placeholder, | ||
| 43 | "o-avatar--colored": color && !color2, | ||
| 44 | "o-avatar--colored-gradient": color && !!color2, | ||
| 45 | [`o-avatar--${size}`]: !!size, | ||
| 46 | }, | ||
| 47 | cls, | ||
| 48 | ]} | ||
| 49 | style={{ | ||
| 50 | "--o-avatar--bg-angle": colorAngle, | ||
| 51 | "--o-avatar--bg-color--h": color?.match(hslRegex)?.[1], | ||
| 52 | "--o-avatar--bg-color--l": color?.match(hslRegex)?.[3], | ||
| 53 | "--o-avatar--bg-color--s": color?.match(hslRegex)?.[2], | ||
| 54 | "--o-avatar--bg-color-2--h": color2?.match(hslRegex)?.[1], | ||
| 55 | "--o-avatar--bg-color-2--l": color2?.match(hslRegex)?.[3], | ||
| 56 | "--o-avatar--bg-color-2--s": color2?.match(hslRegex)?.[2], | ||
| 57 | }} | ||
| 58 | {...props} | ||
| 59 | > | ||
| 60 | {status && <StatusIndicator class="o-avatar__status" status={status} />} | ||
| 61 | {icon && <div class="o-avatar__icon u-ai-end u-jc-end">{icon}</div>} | ||
| 62 | |||
| 63 | {src ? ( | ||
| 64 | <img alt="" class="o-avatar__content" src={src} /> | ||
| 65 | ) : ( | ||
| 66 | <span class="o-avatar__content">{children}</span> | ||
| 67 | )} | ||
| 68 | </Tag> | ||
| 69 | ); | ||
