Merge remote-tracking branch 'origin/master' into aakansha-next

This commit is contained in:
Aakansha Doshi
2022-07-04 16:56:32 +05:30
21 changed files with 1032 additions and 977 deletions

View File

@@ -1731,11 +1731,13 @@ class App extends React.Component<AppProps, AppState> {
});
}
// bail if
if (
// inside an input
(isWritableElement(event.target) &&
!event[KEYS.CTRL_OR_CMD] &&
// unless pressing escape (finalize action)
event.key !== KEYS.ESCAPE) ||
// case: using arrows to move between buttons
// or unless using arrows (to move between buttons)
(isArrowKey(event.key) && isInputLike(event.target))
) {
return;

View File

@@ -129,19 +129,7 @@ const Picker = ({
const handleKeyDown = (event: React.KeyboardEvent) => {
let handled = false;
if (event.key === KEYS.TAB) {
handled = true;
const { activeElement } = document;
if (event.shiftKey) {
if (activeElement === firstItem.current) {
colorInput.current?.focus();
event.preventDefault();
}
} else if (activeElement === colorInput.current) {
firstItem.current?.focus();
event.preventDefault();
}
} else if (isArrowKey(event.key)) {
if (isArrowKey(event.key)) {
handled = true;
const { activeElement } = document;
const isRTL = getLanguage().rtl;
@@ -272,7 +260,8 @@ const Picker = ({
gallery.current = el;
}
}}
tabIndex={0}
// to allow focusing by clicking but not by tabbing
tabIndex={-1}
>
<div className="color-picker-content--default">
{renderColors(colors)}

View File

@@ -9,6 +9,7 @@ import { back, close } from "./icons";
import { Island } from "./Island";
import { Modal } from "./Modal";
import { AppState } from "../types";
import { queryFocusableElements } from "../utils";
export interface DialogProps {
children: React.ReactNode;
@@ -64,14 +65,6 @@ export const Dialog = (props: DialogProps) => {
return () => islandNode.removeEventListener("keydown", handleKeyDown);
}, [islandNode, props.autofocus]);
const queryFocusableElements = (node: HTMLElement) => {
const focusableElements = node.querySelectorAll<HTMLElement>(
"button, a, input, select, textarea, div[tabindex]",
);
return focusableElements ? Array.from(focusableElements) : [];
};
const onClose = () => {
(lastActiveElement as HTMLElement).focus();
props.onCloseRequest();

View File

@@ -14,11 +14,11 @@ export const InitializeApp = (props: Props) => {
useEffect(() => {
const updateLang = async () => {
await setLanguage(currentLang);
setLoading(false);
};
const currentLang =
languages.find((lang) => lang.code === props.langCode) || defaultLang;
updateLang();
setLoading(false);
}, [props.langCode]);
return loading ? <LoadingMessage /> : props.children;

View File

@@ -428,7 +428,7 @@ const LibraryMenuItems = ({
align="start"
gap={1}
style={{
flex: publishedItems.length > 0 ? 1 : "0 0 auto",
flex: publishedItems.length > 0 ? 1 : "0 1 auto",
marginBottom: 0,
}}
>
@@ -467,7 +467,7 @@ const LibraryMenuItems = ({
fontSize: ".9rem",
}}
>
No items yet!
{t("library.noItems")}
<div
style={{
margin: ".6rem 0",
@@ -498,7 +498,23 @@ const LibraryMenuItems = ({
(pendingElements.length > 0 || unpublishedItems.length > 0))) && (
<div className="separator">{t("labels.excalidrawLib")}</div>
)}
{publishedItems.length > 0 && renderLibrarySection(publishedItems)}
{publishedItems.length > 0 ? (
renderLibrarySection(publishedItems)
) : unpublishedItems.length > 0 ? (
<div
style={{
margin: "1rem 0",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
width: "100%",
fontSize: ".9rem",
}}
>
{t("library.noItems")}
</div>
) : null}
</>
</Stack.Col>
);

View File

@@ -1,6 +1,8 @@
import React, { useLayoutEffect, useRef, useEffect } from "react";
import "./Popover.scss";
import { unstable_batchedUpdates } from "react-dom";
import { queryFocusableElements } from "../utils";
import { KEYS } from "../keys";
type Props = {
top?: number;
@@ -27,6 +29,41 @@ export const Popover = ({
}: Props) => {
const popoverRef = useRef<HTMLDivElement>(null);
const container = popoverRef.current;
useEffect(() => {
if (!container) {
return;
}
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === KEYS.TAB) {
const focusableElements = queryFocusableElements(container);
const { activeElement } = document;
const currentIndex = focusableElements.findIndex(
(element) => element === activeElement,
);
if (currentIndex === 0 && event.shiftKey) {
focusableElements[focusableElements.length - 1].focus();
event.preventDefault();
event.stopImmediatePropagation();
} else if (
currentIndex === focusableElements.length - 1 &&
!event.shiftKey
) {
focusableElements[0].focus();
event.preventDefault();
event.stopImmediatePropagation();
}
}
};
container.addEventListener("keydown", handleKeyDown);
return () => container.removeEventListener("keydown", handleKeyDown);
}, [container]);
// ensure the popover doesn't overflow the viewport
useLayoutEffect(() => {
if (fitInViewport && popoverRef.current) {

View File

@@ -98,7 +98,12 @@ export const loadFromJSON = async (
// gets resolved. Else, iOS users cannot open `.excalidraw` files.
// extensions: ["json", "excalidraw", "png", "svg"],
});
return loadFromBlob(await normalizeFile(file), localAppState, localElements);
return loadFromBlob(
await normalizeFile(file),
localAppState,
localElements,
file.handle,
);
};
export const isValidExcalidrawData = (data?: {

View File

@@ -124,6 +124,7 @@
"sidebarLock": "Keep sidebar open"
},
"library": {
"noItems": "No items added yet...",
"hint_emptyLibrary": "Select an item on canvas to add it here, or install a library from the public repository, below.",
"hint_emptyPrivateLibrary": "Select an item on canvas to add it here."
},

View File

@@ -49,7 +49,7 @@
"@babel/plugin-transform-async-to-generator": "7.16.0",
"@babel/plugin-transform-runtime": "7.17.10",
"@babel/plugin-transform-typescript": "7.16.1",
"@babel/preset-env": "7.17.10",
"@babel/preset-env": "7.18.6",
"@babel/preset-react": "7.16.7",
"@babel/preset-typescript": "7.16.7",
"autoprefixer": "10.4.7",
@@ -66,7 +66,7 @@
"webpack": "5.72.0",
"webpack-bundle-analyzer": "4.5.0",
"webpack-cli": "4.9.2",
"webpack-dev-server": "4.9.0",
"webpack-dev-server": "4.9.3",
"webpack-merge": "5.8.0"
},
"bugs": "https://github.com/excalidraw/excalidraw/issues",

File diff suppressed because it is too large Load Diff

View File

@@ -37,7 +37,7 @@
"@babel/core": "7.17.2",
"@babel/plugin-transform-arrow-functions": "7.16.0",
"@babel/plugin-transform-async-to-generator": "7.16.5",
"@babel/plugin-transform-runtime": "7.17.10",
"@babel/plugin-transform-runtime": "7.18.6",
"@babel/plugin-transform-typescript": "7.16.1",
"@babel/preset-env": "7.16.7",
"@babel/preset-typescript": "7.16.7",

View File

@@ -205,12 +205,12 @@
dependencies:
"@babel/types" "^7.16.7"
"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.0", "@babel/helper-module-imports@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437"
integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==
"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.0", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
dependencies:
"@babel/types" "^7.16.7"
"@babel/types" "^7.18.6"
"@babel/helper-module-transforms@^7.16.7":
version "7.16.7"
@@ -233,10 +233,10 @@
dependencies:
"@babel/types" "^7.16.7"
"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5"
integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==
"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.6.tgz#9448974dd4fb1d80fefe72e8a0af37809cd30d6d"
integrity sha512-gvZnm1YAAxh13eJdkb9EWHBnF3eAub3XTLCZEehHT2kWxiKVRL64+ae5Y6Ivne0mVHmMYKT+xWgZO+gQhuLUBg==
"@babel/helper-remap-async-to-generator@^7.16.5":
version "7.16.5"
@@ -293,6 +293,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad"
integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
"@babel/helper-validator-identifier@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076"
integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==
"@babel/helper-validator-option@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23"
@@ -805,16 +810,16 @@
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-transform-runtime@7.17.10":
version "7.17.10"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.10.tgz#b89d821c55d61b5e3d3c3d1d636d8d5a81040ae1"
integrity sha512-6jrMilUAJhktTr56kACL8LnWC5hx3Lf27BS0R0DSyW/OoJfb/iTHeE96V3b1dgKG3FSFdd/0culnYWMkjcKCig==
"@babel/plugin-transform-runtime@7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.6.tgz#77b14416015ea93367ca06979710f5000ff34ccb"
integrity sha512-8uRHk9ZmRSnWqUgyae249EJZ94b0yAGLBIqzZzl+0iEdbno55Pmlt/32JZsHwXD9k/uZj18Aqqk35wBX4CBTXA==
dependencies:
"@babel/helper-module-imports" "^7.16.7"
"@babel/helper-plugin-utils" "^7.16.7"
babel-plugin-polyfill-corejs2 "^0.3.0"
babel-plugin-polyfill-corejs3 "^0.5.0"
babel-plugin-polyfill-regenerator "^0.3.0"
"@babel/helper-module-imports" "^7.18.6"
"@babel/helper-plugin-utils" "^7.18.6"
babel-plugin-polyfill-corejs2 "^0.3.1"
babel-plugin-polyfill-corejs3 "^0.5.2"
babel-plugin-polyfill-regenerator "^0.3.1"
semver "^6.3.0"
"@babel/plugin-transform-shorthand-properties@^7.16.7":
@@ -1026,6 +1031,14 @@
"@babel/helper-validator-identifier" "^7.16.7"
to-fast-properties "^2.0.0"
"@babel/types@^7.18.6":
version "7.18.7"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.7.tgz#a4a2c910c15040ea52cdd1ddb1614a65c8041726"
integrity sha512-QG3yxTcTIBoAcQmkCs+wAPYZhu7Dk9rXKacINfNbdJDNERTbLQbHGyVG8q/YGMPeCJRIhSY0+fTc5+xuh6WPSQ==
dependencies:
"@babel/helper-validator-identifier" "^7.18.6"
to-fast-properties "^2.0.0"
"@discoveryjs/json-ext@^0.5.0":
version "0.5.2"
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752"
@@ -1344,13 +1357,13 @@ babel-plugin-dynamic-import-node@^2.3.3:
dependencies:
object.assign "^4.1.0"
babel-plugin-polyfill-corejs2@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz#407082d0d355ba565af24126fb6cb8e9115251fd"
integrity sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==
babel-plugin-polyfill-corejs2@^0.3.0, babel-plugin-polyfill-corejs2@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5"
integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==
dependencies:
"@babel/compat-data" "^7.13.11"
"@babel/helper-define-polyfill-provider" "^0.3.0"
"@babel/helper-define-polyfill-provider" "^0.3.1"
semver "^6.1.1"
babel-plugin-polyfill-corejs3@^0.4.0:
@@ -1361,7 +1374,7 @@ babel-plugin-polyfill-corejs3@^0.4.0:
"@babel/helper-define-polyfill-provider" "^0.3.0"
core-js-compat "^3.18.0"
babel-plugin-polyfill-corejs3@^0.5.0:
babel-plugin-polyfill-corejs3@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72"
integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==
@@ -1369,12 +1382,12 @@ babel-plugin-polyfill-corejs3@^0.5.0:
"@babel/helper-define-polyfill-provider" "^0.3.1"
core-js-compat "^3.21.0"
babel-plugin-polyfill-regenerator@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz#9ebbcd7186e1a33e21c5e20cae4e7983949533be"
integrity sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==
babel-plugin-polyfill-regenerator@^0.3.0, babel-plugin-polyfill-regenerator@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990"
integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.3.0"
"@babel/helper-define-polyfill-provider" "^0.3.1"
babel-plugin-syntax-class-properties@^6.8.0:
version "6.13.0"

View File

@@ -1,66 +0,0 @@
// eslint-disable-next-line no-restricted-globals
// eslint-disable-next-line no-unused-expressions
/* eslint-disable no-restricted-globals */
/* global importScripts, workbox */
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("/workbox/workbox-sw.js");
workbox.setConfig({
modulePathPrefix: "/workbox/",
});
self.addEventListener("message", (event) => {
if (event.data && event.data.type === "SKIP_WAITING") {
self.skipWaiting();
}
});
workbox.core.clientsClaim();
workbox.precaching.precacheAndRoute(self.__WB_MANIFEST);
workbox.routing.registerNavigationRoute(
workbox.precaching.getCacheKeyForURL("./index.html"),
{
blacklist: [/^\/_/, /\/[^/?]+\.[^/]+$/],
},
);
// Cache relevant font files
workbox.routing.registerRoute(
new RegExp("/(fonts.css|.+.(ttf|woff2|otf))"),
new workbox.strategies.StaleWhileRevalidate({
cacheName: "fonts",
plugins: [new workbox.expiration.Plugin({ maxEntries: 10 })],
}),
);
self.addEventListener("fetch", (event) => {
if (
event.request.method === "POST" &&
event.request.url.endsWith("/web-share-target")
) {
return event.respondWith(
(async () => {
const formData = await event.request.formData();
const file = formData.get("file");
const webShareTargetCache = await caches.open("web-share-target");
await webShareTargetCache.put("shared-file", new Response(file));
return Response.redirect("/?web-share-target", 303);
})(),
);
}
});

View File

@@ -26,7 +26,11 @@ type Config = {
};
export const register = (config?: Config) => {
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
if (
(process.env.NODE_ENV === "production" ||
process.env.REACT_APP_DEV_ENABLE_SW?.toLowerCase() === "true") &&
"serviceWorker" in navigator
) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
if (publicUrl.origin !== window.location.origin) {

View File

@@ -668,3 +668,16 @@ export const isPromiseLike = (
"finally" in value
);
};
export const queryFocusableElements = (container: HTMLElement | null) => {
const focusableElements = container?.querySelectorAll<HTMLElement>(
"button, a, input, select, textarea, div[tabindex], label[tabindex]",
);
return focusableElements
? Array.from(focusableElements).filter(
(element) =>
element.tabIndex > -1 && !(element as HTMLInputElement).disabled,
)
: [];
};