feat(app): updates to project avatar (#30964)
This commit is contained in:
parent
93a58f55ca
commit
24347f336c
@ -1,14 +1,24 @@
|
||||
[data-component="project-avatar-v2"] {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-unread] {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
[data-slot="project-avatar-surface"] {
|
||||
--project-avatar-bg: var(--v2-avatar-bg-gray);
|
||||
--project-avatar-border: var(--v2-avatar-border-gray);
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
background:
|
||||
@ -26,56 +36,56 @@
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-variant="orange"] {
|
||||
[data-slot="project-avatar-surface"][data-variant="orange"] {
|
||||
--project-avatar-bg: var(--v2-avatar-bg-orange);
|
||||
--project-avatar-border: var(--v2-avatar-border-orange);
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-variant="yellow"] {
|
||||
[data-slot="project-avatar-surface"][data-variant="yellow"] {
|
||||
--project-avatar-bg: var(--v2-avatar-bg-yellow);
|
||||
--project-avatar-border: var(--v2-avatar-border-yellow);
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-variant="cyan"] {
|
||||
[data-slot="project-avatar-surface"][data-variant="cyan"] {
|
||||
--project-avatar-bg: var(--v2-avatar-bg-cyan);
|
||||
--project-avatar-border: var(--v2-avatar-border-cyan);
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-variant="green"] {
|
||||
[data-slot="project-avatar-surface"][data-variant="green"] {
|
||||
--project-avatar-bg: var(--v2-avatar-bg-green);
|
||||
--project-avatar-border: var(--v2-avatar-border-green);
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-variant="red"] {
|
||||
[data-slot="project-avatar-surface"][data-variant="red"] {
|
||||
--project-avatar-bg: var(--v2-avatar-bg-red);
|
||||
--project-avatar-border: var(--v2-avatar-border-red);
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-variant="pink"] {
|
||||
[data-slot="project-avatar-surface"][data-variant="pink"] {
|
||||
--project-avatar-bg: var(--v2-avatar-bg-pink);
|
||||
--project-avatar-border: var(--v2-avatar-border-pink);
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-variant="blue"] {
|
||||
[data-slot="project-avatar-surface"][data-variant="blue"] {
|
||||
--project-avatar-bg: var(--v2-avatar-bg-blue);
|
||||
--project-avatar-border: var(--v2-avatar-border-blue);
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-variant="purple"] {
|
||||
[data-slot="project-avatar-surface"][data-variant="purple"] {
|
||||
--project-avatar-bg: var(--v2-avatar-bg-purple);
|
||||
--project-avatar-border: var(--v2-avatar-border-purple);
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-variant="gray"] {
|
||||
[data-slot="project-avatar-surface"][data-variant="gray"] {
|
||||
--project-avatar-bg: var(--v2-avatar-bg-gray);
|
||||
--project-avatar-border: var(--v2-avatar-border-gray);
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-has-image] {
|
||||
[data-slot="project-avatar-surface"][data-has-image] {
|
||||
background: var(--project-avatar-bg);
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"] [data-slot="project-avatar-image"] {
|
||||
[data-slot="project-avatar-surface"] [data-slot="project-avatar-image"] {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: block;
|
||||
@ -88,11 +98,11 @@
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"] [data-slot="project-avatar-loader"] {
|
||||
[data-slot="project-avatar-surface"] [data-slot="project-avatar-loader"] {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
inset: -3px;
|
||||
z-index: 2;
|
||||
border-radius: 4px;
|
||||
border-radius: 0;
|
||||
background: conic-gradient(
|
||||
from 180deg at 50% 50%,
|
||||
var(--v2-grey-100) 0deg,
|
||||
@ -111,6 +121,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-unread] [data-slot="project-avatar-surface"] {
|
||||
-webkit-mask-image: radial-gradient(
|
||||
circle 4.5px at calc(100% - 1px) 1px,
|
||||
transparent 4.5px,
|
||||
black 4.5px
|
||||
);
|
||||
mask-image: radial-gradient(circle 4.5px at calc(100% - 1px) 1px, transparent 4.5px, black 4.5px);
|
||||
}
|
||||
|
||||
[data-slot="project-avatar-unread-dot"] {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
right: -2px;
|
||||
top: -2px;
|
||||
border-radius: 9999px;
|
||||
background: var(--v2-background-bg-accent);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[data-slot="project-avatar-slot"] {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
@ -120,9 +151,3 @@
|
||||
height: 22px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
[data-component="project-avatar-v2"][data-unread] {
|
||||
overflow: visible;
|
||||
outline: 2px solid var(--v2-background-bg-accent);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { For } from "solid-js"
|
||||
import { ProjectAvatar, PROJECT_AVATAR_VARIANTS } from "./project-avatar-v2"
|
||||
|
||||
const docs = `### Overview
|
||||
Saturated 16px project avatar with color variants and optional unread ring.
|
||||
Saturated 16px project avatar with color variants and optional unread dot.
|
||||
|
||||
### API
|
||||
- Required: \`fallback\` string.
|
||||
@ -12,7 +12,7 @@ Saturated 16px project avatar with color variants and optional unread ring.
|
||||
### Variants
|
||||
- Color: orange, yellow, cyan, green, red, pink, blue, purple, gray.
|
||||
- Image vs initial content state.
|
||||
- Unread ring when \`unread\` is set.
|
||||
- Unread dot with corner mask when \`unread\` is set.
|
||||
|
||||
### Theming
|
||||
- Uses \`--v2-avatar-bg-*\` and \`--v2-avatar-border-*\` tokens with inset box-shadow borders.
|
||||
@ -70,6 +70,18 @@ export const Unread = {
|
||||
},
|
||||
}
|
||||
|
||||
export const AllVariantsUnread = {
|
||||
render: () => (
|
||||
<div style={{ display: "flex", gap: "16px", "align-items": "center" }}>
|
||||
<For each={PROJECT_AVATAR_VARIANTS}>
|
||||
{(variant) => (
|
||||
<ProjectAvatar fallback={variant[0].toUpperCase()} variant={variant} unread />
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
),
|
||||
}
|
||||
|
||||
export const Loading = {
|
||||
args: {
|
||||
fallback: "O",
|
||||
|
||||
@ -50,21 +50,28 @@ export function ProjectAvatar(props: ProjectAvatarProps) {
|
||||
<div
|
||||
{...rest}
|
||||
data-component="project-avatar-v2"
|
||||
data-variant={split.variant ?? "gray"}
|
||||
data-has-image={src ? "" : undefined}
|
||||
data-unread={split.unread ? "" : undefined}
|
||||
data-loading={split.loading ? "" : undefined}
|
||||
classList={{
|
||||
...split.classList,
|
||||
[split.class ?? ""]: !!split.class,
|
||||
}}
|
||||
style={typeof split.style === "object" ? split.style : undefined}
|
||||
>
|
||||
<Show when={src} fallback={first(split.fallback)}>
|
||||
{(value) => <img src={value()} draggable={false} data-slot="project-avatar-image" />}
|
||||
</Show>
|
||||
<Show when={split.loading}>
|
||||
<span data-slot="project-avatar-loader" aria-hidden="true" />
|
||||
<div
|
||||
data-slot="project-avatar-surface"
|
||||
data-variant={split.variant ?? "gray"}
|
||||
data-has-image={src ? "" : undefined}
|
||||
data-loading={split.loading ? "" : undefined}
|
||||
>
|
||||
<Show when={src} fallback={first(split.fallback)}>
|
||||
{(value) => <img src={value()} draggable={false} data-slot="project-avatar-image" />}
|
||||
</Show>
|
||||
<Show when={split.loading}>
|
||||
<span data-slot="project-avatar-loader" aria-hidden="true" />
|
||||
</Show>
|
||||
</div>
|
||||
<Show when={split.unread}>
|
||||
<span data-slot="project-avatar-unread-dot" aria-hidden="true" />
|
||||
</Show>
|
||||
</div>
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user