|
@@ -118,70 +118,83 @@ const LibraryMenuItems = ({
|
|
|
let addedPendingElements = false;
|
|
|
|
|
|
rows.push(
|
|
|
- <Stack.Row
|
|
|
- align="center"
|
|
|
- gap={1}
|
|
|
- key={"actions"}
|
|
|
- style={{ padding: "2px 0" }}
|
|
|
- >
|
|
|
- <ToolButton
|
|
|
- key="import"
|
|
|
- type="button"
|
|
|
- title={t("buttons.load")}
|
|
|
- aria-label={t("buttons.load")}
|
|
|
- icon={load}
|
|
|
+ <>
|
|
|
+ <a
|
|
|
+ className="browse-libraries"
|
|
|
+ href="https://libraries.excalidraw.com"
|
|
|
+ target="_excalidraw_libraries"
|
|
|
onClick={() => {
|
|
|
- importLibraryFromJSON()
|
|
|
- .then(() => {
|
|
|
- // Maybe we should close and open the menu so that the items get updated.
|
|
|
- // But for now we just close the menu.
|
|
|
- setAppState({ isLibraryOpen: false });
|
|
|
- })
|
|
|
- .catch(muteFSAbortError)
|
|
|
- .catch((error) => {
|
|
|
- setAppState({ errorMessage: error.message });
|
|
|
- });
|
|
|
+ trackEvent(EVENT_EXIT, "libraries");
|
|
|
}}
|
|
|
- />
|
|
|
- <ToolButton
|
|
|
- key="export"
|
|
|
- type="button"
|
|
|
- title={t("buttons.export")}
|
|
|
- aria-label={t("buttons.export")}
|
|
|
- icon={exportFile}
|
|
|
- onClick={() => {
|
|
|
- saveLibraryAsJSON()
|
|
|
- .catch(muteFSAbortError)
|
|
|
- .catch((error) => {
|
|
|
- setAppState({ errorMessage: error.message });
|
|
|
- });
|
|
|
- }}
|
|
|
- />
|
|
|
- </Stack.Row>,
|
|
|
+ >
|
|
|
+ {t("labels.libraries")}
|
|
|
+ </a>
|
|
|
+
|
|
|
+ <Stack.Row
|
|
|
+ align="center"
|
|
|
+ gap={1}
|
|
|
+ key={"actions"}
|
|
|
+ style={{ padding: "2px 0" }}
|
|
|
+ >
|
|
|
+ <ToolButton
|
|
|
+ key="import"
|
|
|
+ type="button"
|
|
|
+ title={t("buttons.load")}
|
|
|
+ aria-label={t("buttons.load")}
|
|
|
+ icon={load}
|
|
|
+ onClick={() => {
|
|
|
+ importLibraryFromJSON()
|
|
|
+ .then(() => {
|
|
|
+ // Maybe we should close and open the menu so that the items get updated.
|
|
|
+ // But for now we just close the menu.
|
|
|
+ setAppState({ isLibraryOpen: false });
|
|
|
+ })
|
|
|
+ .catch(muteFSAbortError)
|
|
|
+ .catch((error) => {
|
|
|
+ setAppState({ errorMessage: error.message });
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <ToolButton
|
|
|
+ key="export"
|
|
|
+ type="button"
|
|
|
+ title={t("buttons.export")}
|
|
|
+ aria-label={t("buttons.export")}
|
|
|
+ icon={exportFile}
|
|
|
+ onClick={() => {
|
|
|
+ saveLibraryAsJSON()
|
|
|
+ .catch(muteFSAbortError)
|
|
|
+ .catch((error) => {
|
|
|
+ setAppState({ errorMessage: error.message });
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </Stack.Row>
|
|
|
+ </>,
|
|
|
);
|
|
|
|
|
|
for (let row = 0; row < numRows; row++) {
|
|
|
- const i = CELLS_PER_ROW * row;
|
|
|
+ const y = CELLS_PER_ROW * row;
|
|
|
const children = [];
|
|
|
- for (let j = 0; j < CELLS_PER_ROW; j++) {
|
|
|
+ for (let x = 0; x < CELLS_PER_ROW; x++) {
|
|
|
const shouldAddPendingElements: boolean =
|
|
|
pendingElements.length > 0 &&
|
|
|
!addedPendingElements &&
|
|
|
- i + j >= library.length;
|
|
|
+ y + x >= library.length;
|
|
|
addedPendingElements = addedPendingElements || shouldAddPendingElements;
|
|
|
|
|
|
children.push(
|
|
|
- <Stack.Col key={j}>
|
|
|
+ <Stack.Col key={x}>
|
|
|
<LibraryUnit
|
|
|
- elements={library[i + j]}
|
|
|
+ elements={library[y + x]}
|
|
|
pendingElements={
|
|
|
shouldAddPendingElements ? pendingElements : undefined
|
|
|
}
|
|
|
- onRemoveFromLibrary={onRemoveFromLibrary.bind(null, i + j)}
|
|
|
+ onRemoveFromLibrary={onRemoveFromLibrary.bind(null, y + x)}
|
|
|
onClick={
|
|
|
shouldAddPendingElements
|
|
|
? onAddToLibrary.bind(null, pendingElements)
|
|
|
- : onInsertShape.bind(null, library[i + j])
|
|
|
+ : onInsertShape.bind(null, library[y + x])
|
|
|
}
|
|
|
/>
|
|
|
</Stack.Col>,
|