[WIP] Dropdown => Popover for userlist.
Seems to make more sense with the fixed header and footer elements.
This commit is contained in:
parent
b4867cb3dc
commit
ada5ddc675
@ -1,6 +1,5 @@
|
|||||||
import { getClientColor } from "../clients";
|
import { getClientColor } from "../clients";
|
||||||
import { Avatar } from "../components/Avatar";
|
import { Avatar } from "../components/Avatar";
|
||||||
import DropdownMenu from "../components/dropdownMenu/DropdownMenu";
|
|
||||||
import { centerScrollOn } from "../scene/scroll";
|
import { centerScrollOn } from "../scene/scroll";
|
||||||
import { Collaborator } from "../types";
|
import { Collaborator } from "../types";
|
||||||
import { register } from "./register";
|
import { register } from "./register";
|
||||||
@ -58,20 +57,19 @@ export const actionGoToCollaborator = register({
|
|||||||
const background = getClientColor(clientId);
|
const background = getClientColor(clientId);
|
||||||
|
|
||||||
return withName ? (
|
return withName ? (
|
||||||
<DropdownMenu.Item
|
<div
|
||||||
onSelect={() => updateData({ ...collaborator, clientId })}
|
className="dropdown-menu-item dropdown-menu-item-base"
|
||||||
icon={
|
onClick={() => updateData({ ...collaborator, clientId })}
|
||||||
<Avatar
|
|
||||||
color={background}
|
|
||||||
onClick={() => {}}
|
|
||||||
name={collaborator.username || ""}
|
|
||||||
src={collaborator.avatarUrl}
|
|
||||||
isBeingFollowed={appState.userToFollow?.clientId === clientId}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
|
<Avatar
|
||||||
|
color={background}
|
||||||
|
onClick={() => {}}
|
||||||
|
name={collaborator.username || ""}
|
||||||
|
src={collaborator.avatarUrl}
|
||||||
|
isBeingFollowed={appState.userToFollow?.clientId === clientId}
|
||||||
|
/>
|
||||||
{collaborator.username}
|
{collaborator.username}
|
||||||
</DropdownMenu.Item>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Avatar
|
<Avatar
|
||||||
color={background}
|
color={background}
|
||||||
|
@ -49,4 +49,43 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
color: var(--color-gray-70);
|
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%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,11 @@ import clsx from "clsx";
|
|||||||
import { AppState, Collaborator } from "../types";
|
import { AppState, Collaborator } from "../types";
|
||||||
import { Tooltip } from "./Tooltip";
|
import { Tooltip } from "./Tooltip";
|
||||||
import { useExcalidrawActionManager } from "./App";
|
import { useExcalidrawActionManager } from "./App";
|
||||||
import DropdownMenu from "./dropdownMenu/DropdownMenu";
|
|
||||||
import { ActionManager } from "../actions/manager";
|
import { ActionManager } from "../actions/manager";
|
||||||
|
|
||||||
|
import * as Popover from "@radix-ui/react-popover";
|
||||||
|
import { Island } from "./Island";
|
||||||
|
|
||||||
const sampleCollaborators = new Map([
|
const sampleCollaborators = new Map([
|
||||||
[
|
[
|
||||||
"client-id-1",
|
"client-id-1",
|
||||||
@ -51,6 +53,20 @@ const sampleCollaborators = new Map([
|
|||||||
color: "#FCCB5F",
|
color: "#FCCB5F",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"client-id-7",
|
||||||
|
{
|
||||||
|
username: "Jack Doe",
|
||||||
|
color: "#BCE784",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"client-id-8",
|
||||||
|
{
|
||||||
|
username: "Jolly Doe",
|
||||||
|
color: "#5DD39E",
|
||||||
|
},
|
||||||
|
],
|
||||||
]) as any as Map<string, Collaborator>;
|
]) as any as Map<string, Collaborator>;
|
||||||
|
|
||||||
const FIRST_N_AVATARS = 3;
|
const FIRST_N_AVATARS = 3;
|
||||||
@ -116,18 +132,16 @@ export const UserList = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const actionManager = useExcalidrawActionManager();
|
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>();
|
const uniqueCollaboratorsMap = sampleCollaborators;
|
||||||
collaborators.forEach((collaborator, socketId) => {
|
|
||||||
uniqueCollaboratorsMap.set(
|
|
||||||
// filter on user id, else fall back on unique socketId
|
|
||||||
collaborator.id || socketId,
|
|
||||||
collaborator,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// const uniqueCollaboratorsMap = sampleCollaborators;
|
|
||||||
const uniqueCollaboratorsArray = Array.from(uniqueCollaboratorsMap).filter(
|
const uniqueCollaboratorsArray = Array.from(uniqueCollaboratorsMap).filter(
|
||||||
([_, collaborator]) => Object.keys(collaborator).length !== 0,
|
([_, collaborator]) => Object.keys(collaborator).length !== 0,
|
||||||
);
|
);
|
||||||
@ -167,33 +181,39 @@ export const UserList = ({
|
|||||||
{first3avatarsJSX}
|
{first3avatarsJSX}
|
||||||
|
|
||||||
{uniqueCollaboratorsArray.length > FIRST_N_AVATARS && (
|
{uniqueCollaboratorsArray.length > FIRST_N_AVATARS && (
|
||||||
<div style={{ position: "relative" }}>
|
<Popover.Root>
|
||||||
<DropdownMenu open={open}>
|
<Popover.Trigger className="UserList__more">
|
||||||
<DropdownMenu.Trigger
|
+{uniqueCollaboratorsArray.length - FIRST_N_AVATARS}
|
||||||
className="UserList__more"
|
</Popover.Trigger>
|
||||||
onToggle={() => {
|
<Popover.Content
|
||||||
setOpen(!open);
|
style={{ zIndex: 2, maxWidth: "14rem", textAlign: "left" }}
|
||||||
}}
|
align="end"
|
||||||
>
|
sideOffset={10}
|
||||||
+{uniqueCollaboratorsArray.length - FIRST_N_AVATARS}
|
>
|
||||||
</DropdownMenu.Trigger>
|
<Island>
|
||||||
<DropdownMenu.Content
|
{/* TODO follow-participant */}
|
||||||
style={{ width: "10rem" }}
|
<div>TODO search</div>
|
||||||
onClickOutside={() => {
|
<div className="dropdown-menu UserList__collaborators">
|
||||||
setOpen(false);
|
{uniqueCollaboratorsArray.map(([clientId, collaborator]) =>
|
||||||
}}
|
renderCollaborator({
|
||||||
>
|
actionManager,
|
||||||
{uniqueCollaboratorsArray.map(([clientId, collaborator]) =>
|
collaborator,
|
||||||
renderCollaborator({
|
clientId,
|
||||||
actionManager,
|
withName: true,
|
||||||
collaborator,
|
}),
|
||||||
clientId,
|
)}
|
||||||
withName: true,
|
</div>
|
||||||
}),
|
{/* TODO follow-participant */}
|
||||||
)}
|
<div className="UserList__hint">
|
||||||
</DropdownMenu.Content>
|
<div className="UserList__hint-heading">TODO hint</div>
|
||||||
</DropdownMenu>
|
<div className="UserList__hint-text">
|
||||||
</div>
|
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||||
|
Quibusdam, ipsum!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Island>
|
||||||
|
</Popover.Content>
|
||||||
|
</Popover.Root>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user