[WIP] Dropdown => Popover for userlist.

Seems to make more sense with the fixed header and footer elements.
This commit is contained in:
barnabasmolnar 2023-08-08 01:13:01 +02:00
parent b4867cb3dc
commit ada5ddc675
3 changed files with 109 additions and 52 deletions

View File

@ -1,6 +1,5 @@
import { getClientColor } from "../clients";
import { Avatar } from "../components/Avatar";
import DropdownMenu from "../components/dropdownMenu/DropdownMenu";
import { centerScrollOn } from "../scene/scroll";
import { Collaborator } from "../types";
import { register } from "./register";
@ -58,20 +57,19 @@ export const actionGoToCollaborator = register({
const background = getClientColor(clientId);
return withName ? (
<DropdownMenu.Item
onSelect={() => updateData({ ...collaborator, clientId })}
icon={
<Avatar
color={background}
onClick={() => {}}
name={collaborator.username || ""}
src={collaborator.avatarUrl}
isBeingFollowed={appState.userToFollow?.clientId === clientId}
/>
}
<div
className="dropdown-menu-item dropdown-menu-item-base"
onClick={() => updateData({ ...collaborator, clientId })}
>
<Avatar
color={background}
onClick={() => {}}
name={collaborator.username || ""}
src={collaborator.avatarUrl}
isBeingFollowed={appState.userToFollow?.clientId === clientId}
/>
{collaborator.username}
</DropdownMenu.Item>
</div>
) : (
<Avatar
color={background}

View File

@ -49,4 +49,43 @@
flex-shrink: 0;
color: var(--color-gray-70);
}
.UserList__collaborators {
position: static;
top: auto;
margin-top: 0;
max-height: 12rem;
overflow-y: auto;
padding: 0.25rem 0.5rem;
}
--userlist-hint-bg-color: var(--color-gray-10);
--userlist-hint-heading-color: var(--color-gray-80);
--userlist-hint-text-color: var(--color-gray-60);
&.theme--dark {
--userlist-hint-bg-color: var(--color-gray-90);
--userlist-hint-heading-color: var(--color-gray-30);
--userlist-hint-text-color: var(--color-gray-40);
}
.UserList__hint {
background-color: var(--userlist-hint-bg-color);
padding: 0.5rem 0.75rem;
overflow: hidden;
border-radius: 0 0 var(--border-radius-lg) var(--border-radius-lg);
&-heading {
color: var(--userlist-hint-heading-color);
font-size: 0.875rem;
font-weight: 600;
line-height: 150%;
}
&-text {
color: var(--userlist-hint-text-color);
font-size: 0.75rem;
line-height: 150%;
}
}
}

View File

@ -5,9 +5,11 @@ import clsx from "clsx";
import { AppState, Collaborator } from "../types";
import { Tooltip } from "./Tooltip";
import { useExcalidrawActionManager } from "./App";
import DropdownMenu from "./dropdownMenu/DropdownMenu";
import { ActionManager } from "../actions/manager";
import * as Popover from "@radix-ui/react-popover";
import { Island } from "./Island";
const sampleCollaborators = new Map([
[
"client-id-1",
@ -51,6 +53,20 @@ const sampleCollaborators = new Map([
color: "#FCCB5F",
},
],
[
"client-id-7",
{
username: "Jack Doe",
color: "#BCE784",
},
],
[
"client-id-8",
{
username: "Jolly Doe",
color: "#5DD39E",
},
],
]) as any as Map<string, Collaborator>;
const FIRST_N_AVATARS = 3;
@ -116,18 +132,16 @@ export const UserList = ({
}) => {
const actionManager = useExcalidrawActionManager();
const [open, setOpen] = React.useState(false);
// const uniqueCollaboratorsMap = new Map<string, Collaborator>();
// collaborators.forEach((collaborator, socketId) => {
// uniqueCollaboratorsMap.set(
// // filter on user id, else fall back on unique socketId
// collaborator.id || socketId,
// collaborator,
// );
// });
const uniqueCollaboratorsMap = new Map<string, Collaborator>();
collaborators.forEach((collaborator, socketId) => {
uniqueCollaboratorsMap.set(
// filter on user id, else fall back on unique socketId
collaborator.id || socketId,
collaborator,
);
});
// const uniqueCollaboratorsMap = sampleCollaborators;
const uniqueCollaboratorsMap = sampleCollaborators;
const uniqueCollaboratorsArray = Array.from(uniqueCollaboratorsMap).filter(
([_, collaborator]) => Object.keys(collaborator).length !== 0,
);
@ -167,33 +181,39 @@ export const UserList = ({
{first3avatarsJSX}
{uniqueCollaboratorsArray.length > FIRST_N_AVATARS && (
<div style={{ position: "relative" }}>
<DropdownMenu open={open}>
<DropdownMenu.Trigger
className="UserList__more"
onToggle={() => {
setOpen(!open);
}}
>
+{uniqueCollaboratorsArray.length - FIRST_N_AVATARS}
</DropdownMenu.Trigger>
<DropdownMenu.Content
style={{ width: "10rem" }}
onClickOutside={() => {
setOpen(false);
}}
>
{uniqueCollaboratorsArray.map(([clientId, collaborator]) =>
renderCollaborator({
actionManager,
collaborator,
clientId,
withName: true,
}),
)}
</DropdownMenu.Content>
</DropdownMenu>
</div>
<Popover.Root>
<Popover.Trigger className="UserList__more">
+{uniqueCollaboratorsArray.length - FIRST_N_AVATARS}
</Popover.Trigger>
<Popover.Content
style={{ zIndex: 2, maxWidth: "14rem", textAlign: "left" }}
align="end"
sideOffset={10}
>
<Island>
{/* TODO follow-participant */}
<div>TODO search</div>
<div className="dropdown-menu UserList__collaborators">
{uniqueCollaboratorsArray.map(([clientId, collaborator]) =>
renderCollaborator({
actionManager,
collaborator,
clientId,
withName: true,
}),
)}
</div>
{/* TODO follow-participant */}
<div className="UserList__hint">
<div className="UserList__hint-heading">TODO hint</div>
<div className="UserList__hint-text">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Quibusdam, ipsum!
</div>
</div>
</Island>
</Popover.Content>
</Popover.Root>
)}
</div>
);