Skip to content

Commit dc4d594

Browse files
committed
frontend/project-nav/avatars: do not style the tab with the color -- instead paint an avatar with the color, or if there is an image, encircle it with that color
1 parent 7efabb8 commit dc4d594

File tree

1 file changed

+47
-41
lines changed

1 file changed

+47
-41
lines changed

src/packages/frontend/projects/projects-nav.tsx

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import type { TabsProps } from "antd";
77
import { Avatar, Popover, Tabs, Tooltip } from "antd";
8-
import { cloneElement, CSSProperties, useMemo, useState } from "react";
8+
import { CSSProperties, useMemo, useState } from "react";
99

1010
import {
1111
CSS,
@@ -17,8 +17,8 @@ import {
1717
import { set_window_title } from "@cocalc/frontend/browser";
1818
import { Icon, Loading } from "@cocalc/frontend/components";
1919
import {
20-
SortableTabs,
2120
SortableTab,
21+
SortableTabs,
2222
useItemContext,
2323
useSortable,
2424
} from "@cocalc/frontend/components/sortable-tabs";
@@ -31,7 +31,6 @@ import { COLORS } from "@cocalc/util/theme";
3131
import { useProjectState } from "../project/page/project-state-hook";
3232
import { useProjectHasInternetAccess } from "../project/settings/has-internet-access-hook";
3333
import { BuyLicenseForProject } from "../site-licenses/purchase/buy-license-for-project";
34-
import { blendBackgroundColor } from "./util";
3534

3635
const PROJECT_NAME_STYLE: CSS = {
3736
whiteSpace: "nowrap",
@@ -176,15 +175,36 @@ function ProjectTab({ project_id }: ProjectTabProps) {
176175

177176
function renderAvatar() {
178177
const avatar = project?.get("avatar_image_tiny");
179-
if (!avatar) return;
180-
return (
181-
<Avatar
182-
style={{ marginTop: "-2px" }}
183-
shape="circle"
184-
icon={<img src={project.get("avatar_image_tiny")} />}
185-
size={20}
186-
/>
187-
);
178+
const color = project?.get("color");
179+
180+
if (avatar) {
181+
// Avatar exists: show it with colored border
182+
return (
183+
<Avatar
184+
style={{
185+
marginTop: "-2px",
186+
border: color ? `2px solid ${color}` : undefined,
187+
}}
188+
shape="circle"
189+
icon={<img src={project.get("avatar_image_tiny")} />}
190+
size={20}
191+
/>
192+
);
193+
} else if (color) {
194+
// No avatar but has color: show colored circle
195+
return (
196+
<Avatar
197+
style={{
198+
marginTop: "-2px",
199+
backgroundColor: color,
200+
}}
201+
shape="circle"
202+
size={20}
203+
/>
204+
);
205+
}
206+
207+
return undefined;
188208
}
189209

190210
function onMouseUp(e: React.MouseEvent) {
@@ -242,7 +262,7 @@ export function ProjectsNav(props: ProjectsNavProps) {
242262
const projectActions = useActions("projects");
243263
const activeTopTab = useTypedRedux("page", "active_top_tab");
244264
const openProjects = useTypedRedux("projects", "open_projects");
245-
const project_map = useTypedRedux("projects", "project_map");
265+
//const project_map = useTypedRedux("projects", "project_map");
246266

247267
const items: TabsProps["items"] = useMemo(() => {
248268
if (openProjects == null) return [];
@@ -259,14 +279,14 @@ export function ProjectsNav(props: ProjectsNavProps) {
259279
return openProjects.toJS().map((project_id) => project_id);
260280
}, [openProjects]);
261281

262-
const onEdit = (project_id: string, action: "add" | "remove") => {
263-
if (action == "add") {
282+
function onEdit(project_id: string, action: "add" | "remove") {
283+
if (action === "add") {
264284
actions.set_active_tab("projects");
265285
} else {
266286
// close given project
267287
actions.close_project_tab(project_id);
268288
}
269-
};
289+
}
270290

271291
function onDragEnd(event) {
272292
const { active, over } = event;
@@ -289,39 +309,25 @@ export function ProjectsNav(props: ProjectsNavProps) {
289309
{(node) => {
290310
const project_id = node.key;
291311
const isActive = project_id === activeTopTab;
292-
const projectColor = project_map?.getIn([project_id, "color"]) as
293-
| string
294-
| undefined;
295312

296313
const wrapperStyle: CSS = {
297314
border: isActive
298-
? `2px solid ${projectColor ? projectColor : "#d3d3d3"}`
299-
: `2px solid ${projectColor ? projectColor : "transparent"}`,
315+
? `2px solid ${"#d3d3d3"}`
316+
: `2px solid ${"transparent"}`,
300317
borderRadius: "8px",
301318
};
302319

303-
// Add background color if project has a color
304-
if (projectColor) {
305-
// Active tab: lighter/brighter (less color), inactive: darker (more color)
306-
wrapperStyle.backgroundColor = blendBackgroundColor(
307-
projectColor,
308-
isActive ? "white" : COLORS.GRAY_LL,
309-
!isActive,
310-
);
311-
}
312-
313-
// Clone the node with additional style props to override Ant Design's background
314-
const styledNode = cloneElement(node, {
315-
style: {
316-
...node.props.style,
317-
backgroundColor: wrapperStyle.backgroundColor,
318-
},
319-
});
320-
321-
// this is similar to the renderTabBar in sortable-tabs.tsx, but with the above, also styles the background
320+
// Kept for reference, this allows to tweak the node props directly
321+
// const styledNode = cloneElement(node, {
322+
// style: {
323+
// ...node.props.style,
324+
// backgroundColor: wrapperStyle.backgroundColor,
325+
// },
326+
// });
327+
322328
return (
323329
<SortableTab key={node.key} id={node.key} style={wrapperStyle}>
324-
{styledNode}
330+
{node}
325331
</SortableTab>
326332
);
327333
}}

0 commit comments

Comments
 (0)