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