From fff9d1522af073112cd117921af4bb167c9ee766 Mon Sep 17 00:00:00 2001 From: David Luzar Date: Sat, 13 May 2023 13:18:14 +0200 Subject: [PATCH] feat: library sidebar design tweaks (#6582) --- src/components/LibraryMenu.scss | 31 ++++++- src/components/LibraryMenu.tsx | 3 +- src/components/LibraryMenuControlButtons.tsx | 22 ++--- src/components/LibraryMenuHeaderContent.tsx | 8 +- src/components/LibraryMenuItems.scss | 17 +++- src/components/LibraryMenuItems.tsx | 96 +++++++++++--------- src/components/Sidebar/Sidebar.scss | 19 ++-- 7 files changed, 128 insertions(+), 68 deletions(-) diff --git a/src/components/LibraryMenu.scss b/src/components/LibraryMenu.scss index 6598b151..16715614 100644 --- a/src/components/LibraryMenu.scss +++ b/src/components/LibraryMenu.scss @@ -1,11 +1,6 @@ @import "open-color/open-color"; .excalidraw { - .library-menu-items-container { - height: 100%; - width: 100%; - } - .layer-ui__library { display: flex; flex-direction: column; @@ -70,6 +65,16 @@ align-items: center; justify-content: center; gap: 0.625rem; + position: relative; + + &--at-bottom::before { + content: ""; + width: calc(100% - 1.5rem); + height: 1px; + position: absolute; + top: -1px; + background: var(--sidebar-border-color); + } } .library-menu-browse-button { @@ -126,4 +131,20 @@ padding: 0.25rem 0.5rem; } } + + .layer-ui__library .library-menu-dropdown-container { + position: relative; + + &--in-heading { + padding: 0; + position: absolute; + top: 1rem; + right: 0.75rem; + z-index: 1; + + .dropdown-menu { + top: 100%; + } + } + } } diff --git a/src/components/LibraryMenu.tsx b/src/components/LibraryMenu.tsx index 7f25a696..0101d0cb 100644 --- a/src/components/LibraryMenu.tsx +++ b/src/components/LibraryMenu.tsx @@ -121,12 +121,11 @@ export const LibraryMenuContent = ({ /> {showBtn && ( )} diff --git a/src/components/LibraryMenuControlButtons.tsx b/src/components/LibraryMenuControlButtons.tsx index 6f3e7520..86ac1b63 100644 --- a/src/components/LibraryMenuControlButtons.tsx +++ b/src/components/LibraryMenuControlButtons.tsx @@ -1,33 +1,33 @@ -import { LibraryItem, ExcalidrawProps, UIAppState } from "../types"; +import { ExcalidrawProps, UIAppState } from "../types"; import LibraryMenuBrowseButton from "./LibraryMenuBrowseButton"; -import { LibraryDropdownMenu } from "./LibraryMenuHeaderContent"; +import clsx from "clsx"; export const LibraryMenuControlButtons = ({ - selectedItems, - onSelectItems, libraryReturnUrl, theme, id, style, + children, + className, }: { - selectedItems: LibraryItem["id"][]; - onSelectItems: (id: LibraryItem["id"][]) => void; libraryReturnUrl: ExcalidrawProps["libraryReturnUrl"]; theme: UIAppState["theme"]; id: string; style: React.CSSProperties; + children?: React.ReactNode; + className?: string; }) => { return ( -
+
- + {children}
); }; diff --git a/src/components/LibraryMenuHeaderContent.tsx b/src/components/LibraryMenuHeaderContent.tsx index 07736f9d..3f16bdb6 100644 --- a/src/components/LibraryMenuHeaderContent.tsx +++ b/src/components/LibraryMenuHeaderContent.tsx @@ -23,6 +23,7 @@ import { Dialog } from "./Dialog"; import DropdownMenu from "./dropdownMenu/DropdownMenu"; import { isLibraryMenuOpenAtom } from "./LibraryMenu"; import { useUIAppState } from "../context/ui-appState"; +import clsx from "clsx"; const getSelectedItems = ( libraryItems: LibraryItems, @@ -37,6 +38,7 @@ export const LibraryDropdownMenuButton: React.FC<{ resetLibrary: () => void; onSelectItems: (items: LibraryItem["id"][]) => void; appState: UIAppState; + className?: string; }> = ({ setAppState, selectedItems, @@ -45,6 +47,7 @@ export const LibraryDropdownMenuButton: React.FC<{ resetLibrary, onSelectItems, appState, + className, }) => { const [libraryItemsData] = useAtom(libraryItemsAtom, jotaiScope); const [isLibraryMenuOpen, setIsLibraryMenuOpen] = useAtom( @@ -236,7 +239,7 @@ export const LibraryDropdownMenuButton: React.FC<{ }; return ( -
+
{renderLibraryMenu()} {selectedItems.length > 0 && (
{selectedItems.length}
@@ -270,9 +273,11 @@ export const LibraryDropdownMenuButton: React.FC<{ export const LibraryDropdownMenu = ({ selectedItems, onSelectItems, + className, }: { selectedItems: LibraryItem["id"][]; onSelectItems: (id: LibraryItem["id"][]) => void; + className?: string; }) => { const { library } = useApp(); const appState = useUIAppState(); @@ -308,6 +313,7 @@ export const LibraryDropdownMenu = ({ removeFromLibrary(libraryItemsData.libraryItems) } resetLibrary={resetLibrary} + className={className} /> ); }; diff --git a/src/components/LibraryMenuItems.scss b/src/components/LibraryMenuItems.scss index 01c2a36e..1a3fa971 100644 --- a/src/components/LibraryMenuItems.scss +++ b/src/components/LibraryMenuItems.scss @@ -26,6 +26,7 @@ } .library-menu-items-container { + width: 100%; display: flex; flex-grow: 1; flex-shrink: 1; @@ -35,10 +36,14 @@ height: 100%; justify-content: center; margin: 0; - border-bottom: 1px solid var(--sidebar-border-color); position: relative; + & > div { + padding-left: 0.75rem; + padding-right: 0.75rem; + } + &__row { display: grid; grid-template-columns: repeat(4, 1fr); @@ -59,6 +64,9 @@ font-size: 1.125rem; font-weight: bold; margin-bottom: 0.75rem; + width: 100%; + padding-right: 4rem; // due to dropdown button + box-sizing: border-box; &--excal { margin-top: 2rem; @@ -75,4 +83,11 @@ color: var(--text-primary-color); } } + + .library-menu-items-private-library-container { + // so that when you toggle between pending item and no items, there's + // no layout shift (this is hardcoded and works only with ENG locale) + min-height: 3.75rem; + width: 100%; + } } diff --git a/src/components/LibraryMenuItems.tsx b/src/components/LibraryMenuItems.tsx index bc914c19..0f4dda58 100644 --- a/src/components/LibraryMenuItems.tsx +++ b/src/components/LibraryMenuItems.tsx @@ -15,6 +15,7 @@ import { MIME_TYPES } from "../constants"; import Spinner from "./Spinner"; import { duplicateElements } from "../element/newElement"; import { LibraryMenuControlButtons } from "./LibraryMenuControlButtons"; +import { LibraryDropdownMenu } from "./LibraryMenuHeaderContent"; import "./LibraryMenuItems.scss"; @@ -207,6 +208,11 @@ const LibraryMenuItems = ({ const showBtn = !libraryItems.length && !pendingElements.length; + const isLibraryEmpty = + !pendingElements.length && + !unpublishedItems.length && + !publishedItems.length; + return (
+ {!isLibraryEmpty && ( + + )} <> -
- {(pendingElements.length > 0 || - unpublishedItems.length > 0 || - publishedItems.length > 0) && ( -
- {t("labels.personalLib")} -
- )} - {isLoading && ( -
- + {!isLibraryEmpty && ( +
+ {t("labels.personalLib")} +
+ )} + {isLoading && ( +
+ +
+ )} +
+ {!pendingElements.length && !unpublishedItems.length ? ( +
+
+ {t("library.noItems")} +
+
+ {publishedItems.length > 0 + ? t("library.hint_emptyPrivateLibrary") + : t("library.hint_emptyLibrary")} +
+ ) : ( + renderLibrarySection([ + // append pending library item + ...(pendingElements.length + ? [{ id: null, elements: pendingElements }] + : []), + ...unpublishedItems, + ]) )}
- {!pendingElements.length && !unpublishedItems.length ? ( -
-
- {t("library.noItems")} -
-
- {publishedItems.length > 0 - ? t("library.hint_emptyPrivateLibrary") - : t("library.hint_emptyLibrary")} -
-
- ) : ( - renderLibrarySection([ - // append pending library item - ...(pendingElements.length - ? [{ id: null, elements: pendingElements }] - : []), - ...unpublishedItems, - ]) - )} <> @@ -304,9 +315,12 @@ const LibraryMenuItems = ({ id={id} libraryReturnUrl={libraryReturnUrl} theme={theme} - selectedItems={selectedItems} - onSelectItems={onSelectItems} - /> + > + + )}
diff --git a/src/components/Sidebar/Sidebar.scss b/src/components/Sidebar/Sidebar.scss index 1b71af11..200e94ef 100644 --- a/src/components/Sidebar/Sidebar.scss +++ b/src/components/Sidebar/Sidebar.scss @@ -46,8 +46,17 @@ justify-content: space-between; align-items: center; width: 100%; - padding-top: 1rem; - padding-bottom: 1rem; + padding: 1rem 0.75rem; + position: relative; + + &::after { + content: ""; + width: calc(100% - 1.5rem); + height: 1px; + background: var(--sidebar-border-color); + position: absolute; + bottom: -1px; + } } .sidebar__header__buttons { @@ -89,7 +98,7 @@ display: flex; flex-direction: column; flex: 1 1 auto; - padding: 1rem 0.75rem; + padding: 1rem 0; [role="tabpanel"] { flex: 1; @@ -161,9 +170,5 @@ border: none; } } - - .sidebar__header { - border-bottom: 1px solid var(--sidebar-border-color); - } } }