Library improvements (#1925)
Co-authored-by: David Luzar <luzar.david@gmail.com>
This commit is contained in:
parent
29f803e25d
commit
cf36cb394b
@ -109,6 +109,7 @@ export const ShapesSwitcher = ({
|
|||||||
}`;
|
}`;
|
||||||
return (
|
return (
|
||||||
<ToolButton
|
<ToolButton
|
||||||
|
className="Shape"
|
||||||
key={value}
|
key={value}
|
||||||
type="radio"
|
type="radio"
|
||||||
icon={icon}
|
icon={icon}
|
||||||
@ -132,6 +133,7 @@ export const ShapesSwitcher = ({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<ToolButton
|
<ToolButton
|
||||||
|
className="Shape"
|
||||||
type="button"
|
type="button"
|
||||||
icon={LIBRARY_ICON}
|
icon={LIBRARY_ICON}
|
||||||
name="editor-library"
|
name="editor-library"
|
||||||
|
@ -103,8 +103,9 @@ const LibraryMenuItems = ({
|
|||||||
onInsertShape: (elements: readonly NonDeleted<ExcalidrawElement>[]) => void;
|
onInsertShape: (elements: readonly NonDeleted<ExcalidrawElement>[]) => void;
|
||||||
onAddToLibrary: (elements: NonDeleted<ExcalidrawElement>[]) => void;
|
onAddToLibrary: (elements: NonDeleted<ExcalidrawElement>[]) => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const isMobile = useIsMobile();
|
||||||
const numCells = library.length + (pendingElements.length > 0 ? 1 : 0);
|
const numCells = library.length + (pendingElements.length > 0 ? 1 : 0);
|
||||||
const CELLS_PER_ROW = 3;
|
const CELLS_PER_ROW = isMobile ? 4 : 6;
|
||||||
const numRows = Math.max(1, Math.ceil(numCells / CELLS_PER_ROW));
|
const numRows = Math.max(1, Math.ceil(numCells / CELLS_PER_ROW));
|
||||||
const rows = [];
|
const rows = [];
|
||||||
let addedPendingElements = false;
|
let addedPendingElements = false;
|
||||||
@ -112,7 +113,7 @@ const LibraryMenuItems = ({
|
|||||||
for (let row = 0; row < numRows; row++) {
|
for (let row = 0; row < numRows; row++) {
|
||||||
const i = CELLS_PER_ROW * row;
|
const i = CELLS_PER_ROW * row;
|
||||||
const children = [];
|
const children = [];
|
||||||
for (let j = 0; j < 3; j++) {
|
for (let j = 0; j < CELLS_PER_ROW; j++) {
|
||||||
const shouldAddPendingElements: boolean =
|
const shouldAddPendingElements: boolean =
|
||||||
pendingElements.length > 0 &&
|
pendingElements.length > 0 &&
|
||||||
!addedPendingElements &&
|
!addedPendingElements &&
|
||||||
@ -365,19 +366,21 @@ const LayerUI = ({
|
|||||||
});
|
});
|
||||||
}, [setAppState]);
|
}, [setAppState]);
|
||||||
|
|
||||||
|
const libraryMenu = appState.isLibraryOpen ? (
|
||||||
|
<LibraryMenu
|
||||||
|
pendingElements={getSelectedElements(elements, appState)}
|
||||||
|
onClickOutside={closeLibrary}
|
||||||
|
onInsertShape={onInsertShape}
|
||||||
|
onAddToLibrary={deselectItems}
|
||||||
|
/>
|
||||||
|
) : null;
|
||||||
|
|
||||||
const renderFixedSideContainer = () => {
|
const renderFixedSideContainer = () => {
|
||||||
const shouldRenderSelectedShapeActions = showSelectedShapeActions(
|
const shouldRenderSelectedShapeActions = showSelectedShapeActions(
|
||||||
appState,
|
appState,
|
||||||
elements,
|
elements,
|
||||||
);
|
);
|
||||||
const libraryMenu = appState.isLibraryOpen ? (
|
|
||||||
<LibraryMenu
|
|
||||||
pendingElements={getSelectedElements(elements, appState)}
|
|
||||||
onClickOutside={closeLibrary}
|
|
||||||
onInsertShape={onInsertShape}
|
|
||||||
onAddToLibrary={deselectItems}
|
|
||||||
/>
|
|
||||||
) : null;
|
|
||||||
return (
|
return (
|
||||||
<FixedSideContainer side="top">
|
<FixedSideContainer side="top">
|
||||||
<HintViewer appState={appState} elements={elements} />
|
<HintViewer appState={appState} elements={elements} />
|
||||||
@ -503,6 +506,7 @@ const LayerUI = ({
|
|||||||
appState={appState}
|
appState={appState}
|
||||||
elements={elements}
|
elements={elements}
|
||||||
actionManager={actionManager}
|
actionManager={actionManager}
|
||||||
|
libraryMenu={libraryMenu}
|
||||||
exportButton={renderExportDialog()}
|
exportButton={renderExportDialog()}
|
||||||
setAppState={setAppState}
|
setAppState={setAppState}
|
||||||
onUsernameChange={onUsernameChange}
|
onUsernameChange={onUsernameChange}
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 126px; // match width
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 126px; // exactly match the toolbar width when 3 are lined up + padding
|
width: 63px;
|
||||||
|
height: 63px; // match width
|
||||||
}
|
}
|
||||||
|
|
||||||
.library-unit__dragger {
|
.library-unit__dragger {
|
||||||
|
@ -5,6 +5,7 @@ import { close } from "../components/icons";
|
|||||||
|
|
||||||
import "./LibraryUnit.scss";
|
import "./LibraryUnit.scss";
|
||||||
import { t } from "../i18n";
|
import { t } from "../i18n";
|
||||||
|
import useIsMobile from "../is-mobile";
|
||||||
|
|
||||||
// fa-plus
|
// fa-plus
|
||||||
const PLUS_ICON = (
|
const PLUS_ICON = (
|
||||||
@ -50,8 +51,9 @@ export const LibraryUnit = ({
|
|||||||
}, [elements, pendingElements]);
|
}, [elements, pendingElements]);
|
||||||
|
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
const adder = isHovered && pendingElements && (
|
const adder = (isHovered || isMobile) && pendingElements && (
|
||||||
<div className="library-unit__adder">{PLUS_ICON}</div>
|
<div className="library-unit__adder">{PLUS_ICON}</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -79,7 +81,7 @@ export const LibraryUnit = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{adder}
|
{adder}
|
||||||
{elements && isHovered && (
|
{elements && (isHovered || isMobile) && (
|
||||||
<button
|
<button
|
||||||
className="library-unit__removeFromLibrary"
|
className="library-unit__removeFromLibrary"
|
||||||
aria-label={t("labels.removeFromLibrary")}
|
aria-label={t("labels.removeFromLibrary")}
|
||||||
|
@ -46,7 +46,7 @@ export const LockIcon = (props: LockIconProps) => {
|
|||||||
return (
|
return (
|
||||||
<label
|
<label
|
||||||
className={`ToolIcon ToolIcon__lock ToolIcon_type_floating ${sizeCn} zen-mode-visibility ${
|
className={`ToolIcon ToolIcon__lock ToolIcon_type_floating ${sizeCn} zen-mode-visibility ${
|
||||||
props.zenModeEnabled && "zen-mode-visibility--hidden"
|
props.zenModeEnabled ? "zen-mode-visibility--hidden" : ""
|
||||||
}`}
|
}`}
|
||||||
title={`${props.title} — Q`}
|
title={`${props.title} — Q`}
|
||||||
>
|
>
|
||||||
|
@ -24,6 +24,7 @@ type MobileMenuProps = {
|
|||||||
exportButton: React.ReactNode;
|
exportButton: React.ReactNode;
|
||||||
setAppState: any;
|
setAppState: any;
|
||||||
elements: readonly NonDeletedExcalidrawElement[];
|
elements: readonly NonDeletedExcalidrawElement[];
|
||||||
|
libraryMenu: JSX.Element | null;
|
||||||
onRoomCreate: () => void;
|
onRoomCreate: () => void;
|
||||||
onUsernameChange: (username: string) => void;
|
onUsernameChange: (username: string) => void;
|
||||||
onRoomDestroy: () => void;
|
onRoomDestroy: () => void;
|
||||||
@ -34,6 +35,7 @@ type MobileMenuProps = {
|
|||||||
export const MobileMenu = ({
|
export const MobileMenu = ({
|
||||||
appState,
|
appState,
|
||||||
elements,
|
elements,
|
||||||
|
libraryMenu,
|
||||||
actionManager,
|
actionManager,
|
||||||
exportButton,
|
exportButton,
|
||||||
setAppState,
|
setAppState,
|
||||||
@ -66,6 +68,7 @@ export const MobileMenu = ({
|
|||||||
title={t("toolBar.lock")}
|
title={t("toolBar.lock")}
|
||||||
/>
|
/>
|
||||||
</Stack.Row>
|
</Stack.Row>
|
||||||
|
{libraryMenu}
|
||||||
</Stack.Col>
|
</Stack.Col>
|
||||||
)}
|
)}
|
||||||
</Section>
|
</Section>
|
||||||
|
@ -78,7 +78,7 @@ export const ToolButton = React.forwardRef((props: ToolButtonProps, ref) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<label className="ToolIcon" title={props.title}>
|
<label className={`ToolIcon ${props.className ?? ""}`} title={props.title}>
|
||||||
<input
|
<input
|
||||||
className={`ToolIcon_type_radio ${sizeCn}`}
|
className={`ToolIcon_type_radio ${sizeCn}`}
|
||||||
type="radio"
|
type="radio"
|
||||||
|
@ -130,6 +130,17 @@
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 425px) {
|
||||||
|
.Shape .ToolIcon__icon {
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
height: 0.8em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 360px) {
|
@media (max-width: 360px) {
|
||||||
.ToolIcon.ToolIcon__lock {
|
.ToolIcon.ToolIcon__lock {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -149,8 +160,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ToolIcon__icon {
|
.ToolIcon__icon {
|
||||||
width: 2.5rem;
|
|
||||||
height: 2.5rem;
|
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
}
|
}
|
||||||
svg {
|
svg {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user