feat: add langCode and renderFooter props (#2644)

Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
Aakansha Doshi 2021-01-04 02:21:52 +05:30 committed by GitHub
parent c35d983fef
commit ade2565f49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 271 additions and 192 deletions

View File

@ -111,7 +111,7 @@ import {
selectGroupsForSelectedElements,
} from "../groups";
import { createHistory, SceneHistory } from "../history";
import { getLanguage, t } from "../i18n";
import { t, getLanguage, setLanguage, languages, defaultLang } from "../i18n";
import {
CODES,
getResizeCenterPointKey,
@ -332,7 +332,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
offsetLeft,
} = this.state;
const { onCollabButtonClick, onExportToBackend } = this.props;
const { onCollabButtonClick, onExportToBackend, renderFooter } = this.props;
const canvasScale = window.devicePixelRatio;
const canvasWidth = canvasDOMWidth * canvasScale;
@ -369,9 +369,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
}
zenModeEnabled={zenModeEnabled}
toggleZenMode={this.toggleZenMode}
lng={getLanguage().lng}
langCode={getLanguage().code}
isCollaborating={this.props.isCollaborating || false}
onExportToBackend={onExportToBackend}
renderCustomFooter={renderFooter}
/>
{this.state.showStats && (
<Stats
@ -738,6 +739,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
}
componentDidUpdate(prevProps: ExcalidrawProps, prevState: AppState) {
if (prevProps.langCode !== this.props.langCode) {
this.updateLanguage();
}
if (
prevProps.width !== this.props.width ||
prevProps.height !== this.props.height ||
@ -3849,6 +3854,14 @@ class App extends React.Component<ExcalidrawProps, AppState> {
offsetTop: typeof offsets?.offsetTop === "number" ? offsets.offsetTop : 0,
};
}
private async updateLanguage() {
const currentLang =
languages.find((lang) => lang.code === this.props.langCode) ||
defaultLang;
await setLanguage(currentLang);
this.setAppState({});
}
}
// -----------------------------------------------------------------------------

View File

@ -1,18 +1,29 @@
import React from "react";
import { LoadingMessage } from "./LoadingMessage";
import { setLanguageFirstTime } from "../i18n";
import {
defaultLang,
Language,
languages,
setLanguageFirstTime,
} from "../i18n";
export class InitializeApp extends React.Component<
any,
{ isLoading: boolean }
> {
interface Props {
langCode: Language["code"];
}
interface State {
isLoading: boolean;
}
export class InitializeApp extends React.Component<Props, State> {
public state: { isLoading: boolean } = {
isLoading: true,
};
async componentDidMount() {
await setLanguageFirstTime();
const currentLang =
languages.find((lang) => lang.code === this.props.langCode) ||
defaultLang;
await setLanguageFirstTime(currentLang);
this.setState({
isLoading: false,
});

View File

@ -19,8 +19,7 @@ import { FixedSideContainer } from "./FixedSideContainer";
import { UserList } from "./UserList";
import { LockIcon } from "./LockIcon";
import { ExportDialog, ExportCB } from "./ExportDialog";
import { LanguageList } from "./LanguageList";
import { t, languages, setLanguage } from "../i18n";
import { Language, t } from "../i18n";
import { HintViewer } from "./HintViewer";
import useIsMobile from "../is-mobile";
@ -64,13 +63,14 @@ interface LayerUIProps {
onInsertElements: (elements: readonly NonDeletedExcalidrawElement[]) => void;
zenModeEnabled: boolean;
toggleZenMode: () => void;
lng: string;
langCode: Language["code"];
isCollaborating: boolean;
onExportToBackend?: (
exportedElements: readonly NonDeletedExcalidrawElement[],
appState: AppState,
canvas: HTMLCanvasElement | null,
) => void;
renderCustomFooter?: (isMobile: boolean) => JSX.Element;
}
const useOnClickOutside = (
@ -316,6 +316,7 @@ const LayerUI = ({
toggleZenMode,
isCollaborating,
onExportToBackend,
renderCustomFooter,
}: LayerUIProps) => {
const isMobile = useIsMobile();
@ -551,14 +552,7 @@ const LayerUI = ({
"transition-right disable-pointerEvents": zenModeEnabled,
})}
>
<LanguageList
onChange={async (lng) => {
await setLanguage(lng);
setAppState({});
}}
languages={languages}
floating
/>
{renderCustomFooter?.(false)}
{actionManager.renderAction("toggleShortcuts")}
</div>
<button
@ -628,6 +622,7 @@ const LayerUI = ({
onLockToggle={onLockToggle}
canvas={canvas}
isCollaborating={isCollaborating}
renderCustomFooter={renderCustomFooter}
/>
</>
) : (
@ -665,9 +660,8 @@ const areEqual = (prev: LayerUIProps, next: LayerUIProps) => {
const nextAppState = getNecessaryObj(next.appState);
const keys = Object.keys(prevAppState) as (keyof Partial<AppState>)[];
return (
prev.lng === next.lng &&
prev.langCode === next.langCode &&
prev.elements === next.elements &&
keys.every((key) => prevAppState[key] === nextAppState[key])
);

View File

@ -1,9 +1,8 @@
import React from "react";
import { AppState } from "../types";
import { ActionManager } from "../actions/manager";
import { t, setLanguage } from "../i18n";
import { t } from "../i18n";
import Stack from "./Stack";
import { LanguageList } from "./LanguageList";
import { showSelectedShapeActions } from "../element";
import { NonDeletedExcalidrawElement } from "../element/types";
import { FixedSideContainer } from "./FixedSideContainer";
@ -30,6 +29,7 @@ type MobileMenuProps = {
onLockToggle: () => void;
canvas: HTMLCanvasElement | null;
isCollaborating: boolean;
renderCustomFooter?: (isMobile: boolean) => JSX.Element;
};
export const MobileMenu = ({
@ -43,6 +43,7 @@ export const MobileMenu = ({
onLockToggle,
canvas,
isCollaborating,
renderCustomFooter,
}: MobileMenuProps) => (
<>
<FixedSideContainer side="top">
@ -102,15 +103,7 @@ export const MobileMenu = ({
appState={appState}
setAppState={setAppState}
/>
<fieldset>
<legend>{t("labels.language")}</legend>
<LanguageList
onChange={async (lng) => {
await setLanguage(lng);
setAppState({});
}}
/>
</fieldset>
{renderCustomFooter?.(true)}
<fieldset>
<legend>{t("labels.collaborators")}</legend>
<UserList mobile>

View File

@ -1,16 +1,16 @@
import React from "react";
import clsx from "clsx";
import * as i18n from "../i18n";
import * as i18n from "../../i18n";
export const LanguageList = ({
onChange,
languages = i18n.languages,
currentLanguage = i18n.getLanguage().lng,
currentLangCode = i18n.getLanguage().code,
floating,
}: {
languages?: { lng: string; label: string }[];
onChange: (value: string) => void;
currentLanguage?: string;
languages?: { code: string; label: string }[];
onChange: (langCode: i18n.Language["code"]) => void;
currentLangCode?: i18n.Language["code"];
floating?: boolean;
}) => (
<React.Fragment>
@ -19,12 +19,12 @@ export const LanguageList = ({
"dropdown-select--floating": floating,
})}
onChange={({ target }) => onChange(target.value)}
value={currentLanguage}
value={currentLangCode}
aria-label={i18n.t("buttons.selectLanguage")}
>
{languages.map((language) => (
<option key={language.lng} value={language.lng}>
{language.label}
{languages.map((lang) => (
<option key={lang.code} value={lang.code}>
{lang.label}
</option>
))}
</select>

View File

@ -1,6 +1,16 @@
import React, { useState, useLayoutEffect, useEffect, useRef } from "react";
import React, {
useState,
useLayoutEffect,
useEffect,
useRef,
useCallback,
} from "react";
import LanguageDetector from "i18next-browser-languagedetector";
import Excalidraw from "../packages/excalidraw/index";
import Excalidraw, {
languages,
defaultLang,
} from "../packages/excalidraw/index";
import {
getTotalStorageSize,
@ -12,7 +22,7 @@ import {
import { ImportedDataState } from "../data/types";
import CollabWrapper, { CollabAPI } from "./collab/CollabWrapper";
import { TopErrorBoundary } from "../components/TopErrorBoundary";
import { t } from "../i18n";
import { Language, t } from "../i18n";
import { exportToBackend, loadScene } from "./data";
import { getCollaborationLinkData } from "./data";
import { EVENT } from "../constants";
@ -29,6 +39,16 @@ import { EVENT_LOAD, EVENT_SHARE, trackEvent } from "../analytics";
import { ErrorDialog } from "../components/ErrorDialog";
import { getDefaultAppState } from "../appState";
import { APP_NAME, TITLE_TIMEOUT } from "../constants";
import { LanguageList } from "./components/LanguageList";
const languageDetector = new LanguageDetector();
languageDetector.init({
languageUtils: {
formatLanguageCode: (langCode: Language["code"]) => langCode,
isWhitelisted: () => true,
},
checkWhitelist: false,
});
const excalidrawRef: React.MutableRefObject<
MarkRequired<ExcalidrawAPIRefValue, "ready" | "readyPromise">
@ -182,6 +202,8 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
height: window.innerHeight,
});
const [errorMessage, setErrorMessage] = useState("");
const currentLangCode = languageDetector.detect() || defaultLang.code;
const [langCode, setLangCode] = useState(currentLangCode);
useLayoutEffect(() => {
const onResize = () => {
@ -256,6 +278,10 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
};
}, [collab.initializeSocketClient]);
useEffect(() => {
languageDetector.cacheUserLanguage(langCode);
}, [langCode]);
const onChange = (
elements: readonly ExcalidrawElement[],
appState: AppState,
@ -291,6 +317,32 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
}
}
};
const renderFooter = useCallback(
(isMobile: boolean) => {
const renderLanguageList = () => (
<LanguageList
onChange={(langCode) => {
setLangCode(langCode);
}}
languages={languages}
floating={!isMobile}
currentLangCode={langCode}
/>
);
if (isMobile) {
return (
<fieldset>
<legend>{t("labels.language")}</legend>
{renderLanguageList()}
</fieldset>
);
}
return renderLanguageList();
},
[langCode],
);
return (
<>
<Excalidraw
@ -304,6 +356,8 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
isCollaborating={collab.isCollaborating}
onPointerUpdate={collab.onPointerUpdate}
onExportToBackend={onExportToBackend}
renderFooter={renderFooter}
langCode={langCode}
/>
{errorMessage && (
<ErrorDialog

View File

@ -1,93 +1,85 @@
import LanguageDetector from "i18next-browser-languagedetector";
import { EVENT_CHANGE, trackEvent } from "./analytics";
import fallbackLanguageData from "./locales/en.json";
import fallbackLangData from "./locales/en.json";
import percentages from "./locales/percentages.json";
const COMPLETION_THRESHOLD = 85;
interface Language {
lng: string;
export interface Language {
code: string;
label: string;
rtl?: boolean;
}
const allLanguages: Language[] = [
{ lng: "ar-SA", label: "العربية", rtl: true },
{ lng: "bg-BG", label: "Български" },
{ lng: "ca-ES", label: "Catalan" },
{ lng: "de-DE", label: "Deutsch" },
{ lng: "el-GR", label: "Ελληνικά" },
{ lng: "es-ES", label: "Español" },
{ lng: "fa-IR", label: "فارسی", rtl: true },
{ lng: "fi-FI", label: "Suomi" },
{ lng: "fr-FR", label: "Français" },
{ lng: "he-IL", label: "עברית", rtl: true },
{ lng: "hi-IN", label: "हिन्दी" },
{ lng: "hu-HU", label: "Magyar" },
{ lng: "id-ID", label: "Bahasa Indonesia" },
{ lng: "it-IT", label: "Italiano" },
{ lng: "ja-JP", label: "日本語" },
{ lng: "ko-KR", label: "한국어" },
{ lng: "my-MM", label: "Burmese" },
{ lng: "nb-NO", label: "Norsk bokmål" },
{ lng: "nl-NL", label: "Nederlands" },
{ lng: "nn-NO", label: "Norsk nynorsk" },
{ lng: "pl-PL", label: "Polski" },
{ lng: "pt-BR", label: "Português Brasileiro" },
{ lng: "pt-PT", label: "Português" },
{ lng: "ro-RO", label: "Română" },
{ lng: "ru-RU", label: "Русский" },
{ lng: "sk-SK", label: "Slovenčina" },
{ lng: "sv-SE", label: "Svenska" },
{ lng: "tr-TR", label: "Türkçe" },
{ lng: "uk-UA", label: "Українська" },
{ lng: "zh-CN", label: "简体中文" },
{ lng: "zh-TW", label: "繁體中文" },
{ code: "ar-SA", label: "العربية", rtl: true },
{ code: "bg-BG", label: "Български" },
{ code: "ca-ES", label: "Catalan" },
{ code: "de-DE", label: "Deutsch" },
{ code: "el-GR", label: "Ελληνικά" },
{ code: "es-ES", label: "Español" },
{ code: "fa-IR", label: "فارسی", rtl: true },
{ code: "fi-FI", label: "Suomi" },
{ code: "fr-FR", label: "Français" },
{ code: "he-IL", label: "עברית", rtl: true },
{ code: "hi-IN", label: "हिन्दी" },
{ code: "hu-HU", label: "Magyar" },
{ code: "id-ID", label: "Bahasa Indonesia" },
{ code: "it-IT", label: "Italiano" },
{ code: "ja-JP", label: "日本語" },
{ code: "ko-KR", label: "한국어" },
{ code: "my-MM", label: "Burmese" },
{ code: "nb-NO", label: "Norsk bokmål" },
{ code: "nl-NL", label: "Nederlands" },
{ code: "nn-NO", label: "Norsk nynorsk" },
{ code: "pl-PL", label: "Polski" },
{ code: "pt-BR", label: "Português Brasileiro" },
{ code: "pt-PT", label: "Português" },
{ code: "ro-RO", label: "Română" },
{ code: "ru-RU", label: "Русский" },
{ code: "sk-SK", label: "Slovenčina" },
{ code: "sv-SE", label: "Svenska" },
{ code: "tr-TR", label: "Türkçe" },
{ code: "uk-UA", label: "Українська" },
{ code: "zh-CN", label: "简体中文" },
{ code: "zh-TW", label: "繁體中文" },
];
export const languages: Language[] = [{ lng: "en", label: "English" }]
export const defaultLang = { code: "en", label: "English" };
export const languages: Language[] = [defaultLang]
.concat(
allLanguages.sort((left, right) => (left.label > right.label ? 1 : -1)),
)
.filter(
(lang) =>
(percentages as Record<string, number>)[lang.lng] >= COMPLETION_THRESHOLD,
(percentages as Record<string, number>)[lang.code] >=
COMPLETION_THRESHOLD,
);
let currentLanguage = languages[0];
let currentLanguageData = {};
const fallbackLanguage = languages[0];
let currentLang: Language = defaultLang;
let currentLangData = {};
export const setLanguage = async (newLng: string | undefined) => {
currentLanguage =
languages.find((language) => language.lng === newLng) || fallbackLanguage;
export const setLanguage = async (lang: Language) => {
currentLang = lang;
document.documentElement.dir = currentLang.rtl ? "rtl" : "ltr";
document.documentElement.dir = currentLanguage.rtl ? "rtl" : "ltr";
currentLanguageData = await import(
/* webpackChunkName: "i18n-[request]" */ `./locales/${currentLanguage.lng}.json`
currentLangData = await import(
/* webpackChunkName: "i18n-[request]" */ `./locales/${currentLang.code}.json`
);
languageDetector.cacheUserLanguage(currentLanguage.lng);
trackEvent(EVENT_CHANGE, "language", currentLanguage.lng);
trackEvent(EVENT_CHANGE, "language", currentLang.code);
};
export const setLanguageFirstTime = async () => {
const newLng: string | undefined = languageDetector.detect();
export const setLanguageFirstTime = async (lang: Language) => {
currentLang = lang;
document.documentElement.dir = currentLang.rtl ? "rtl" : "ltr";
currentLanguage =
languages.find((language) => language.lng === newLng) || fallbackLanguage;
document.documentElement.dir = currentLanguage.rtl ? "rtl" : "ltr";
currentLanguageData = await import(
/* webpackChunkName: "i18n-[request]" */ `./locales/${currentLanguage.lng}.json`
currentLangData = await import(
/* webpackChunkName: "i18n-[request]" */ `./locales/${currentLang.code}.json`
);
languageDetector.cacheUserLanguage(currentLanguage.lng);
};
export const getLanguage = () => currentLanguage;
export const getLanguage = () => currentLang;
const findPartsForData = (data: any, parts: string[]) => {
for (let index = 0; index < parts.length; ++index) {
@ -106,8 +98,8 @@ const findPartsForData = (data: any, parts: string[]) => {
export const t = (path: string, replacement?: { [key: string]: string }) => {
const parts = path.split(".");
let translation =
findPartsForData(currentLanguageData, parts) ||
findPartsForData(fallbackLanguageData, parts);
findPartsForData(currentLangData, parts) ||
findPartsForData(fallbackLangData, parts);
if (translation === undefined) {
throw new Error(`Can't find translation for ${path}`);
}
@ -119,12 +111,3 @@ export const t = (path: string, replacement?: { [key: string]: string }) => {
}
return translation;
};
const languageDetector = new LanguageDetector();
languageDetector.init({
languageUtils: {
formatLanguageCode: (lng: string) => lng,
isWhitelisted: () => true,
},
checkWhitelist: false,
});

View File

@ -16,6 +16,9 @@ Please add the latest change on the top under the correct section.
### Features
- Remove language picker, and add `langCode`, `renderFooter` [#2644](https://github.com/excalidraw/excalidraw/pull/2644):
- BREAKING: removed the language picker from UI. It is now the host app's responsibility to implement a language picker if desirable, using the newly added [`renderFooter`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#renderFooter) prop. The reasoning is that the i18n should be controlled by the app itself, not by the nested Excalidraw component.
- Added [`langCode`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#langCode) prop to control the UI language.
- Add support for `exportToBackend` prop to allow host apps to implement shareable links [#2612](https://github.com/excalidraw/excalidraw/pull/2612/files)
- Add zoom to selection [#2522](https://github.com/excalidraw/excalidraw/pull/2522)
- Insert Library items in the middle of the screen [#2527](https://github.com/excalidraw/excalidraw/pull/2527)

View File

@ -139,6 +139,8 @@ export default function App() {
| [`isCollaborating`](#isCollaborating) | `boolean` | | This implies if the app is in collaboration mode |
| [`onPointerUpdate`](#onPointerUpdate) | Function | | Callback triggered when mouse pointer is updated. |
| [`onExportToBackend`](#onExportToBackend) | Function | | Callback triggered when link button is clicked on export dialog |
| [`langCode`](#langCode) | string | `en` | Language code string |
| [`renderFooter `](#renderFooter) | Function | | Function that renders custom UI footer |
#### `width`
@ -270,3 +272,21 @@ This callback is triggered when the shareable-link button is clicked in the expo
1. `exportedElements`: An array of [non deleted elements](https://github.com/excalidraw/excalidraw/blob/6e45cb95dbd7a8be1859c7055b06957298e3097c/src/element/types.ts#L76) which needs to be exported.
2. `appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/4c90ea5667d29effe8ec4a115e49efc7c340cdb3/src/types.ts#L33) of the scene.
3. `canvas`: The `HTMLCanvasElement` of the scene.
#### `langCode`
Determines the language of the UI. It should be one of the [available language codes](https://github.com/excalidraw/excalidraw/blob/d337c8b15f6c1085287b12ecbe59c96e2c4e0ff4/src/i18n.ts#L14). Defaults to `en` (English).
We also export default language and supported languages which you can import as shown below.
```js
import { defaultLang, languages } from "@excalidraw/excalidraw";
```
| name | type |
| ----------- | -------------------------------------------------------------------------------------------------------------------- |
| defaultLang | string |
| languages | [Language []](https://github.com/excalidraw/excalidraw/blob/c35d983fef8a83ba842dd892c0f461111a3e8589/src/i18n.ts#L9) |
#### `renderFooter`
A function that renders (returns JSX) custom UI footer. For example, you can use this to render a language picker that was previously being rendered by Excalidraw itself (for now, you'll need to implement your own language picker).

View File

@ -8,6 +8,7 @@ import "../../css/styles.scss";
import { ExcalidrawAPIRefValue, ExcalidrawProps } from "../../types";
import { IsMobileProvider } from "../../is-mobile";
import { defaultLang } from "../../i18n";
const Excalidraw = (props: ExcalidrawProps) => {
const {
@ -23,6 +24,8 @@ const Excalidraw = (props: ExcalidrawProps) => {
isCollaborating,
onPointerUpdate,
onExportToBackend,
renderFooter,
langCode = defaultLang.code,
} = props;
useEffect(() => {
@ -44,7 +47,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
}, []);
return (
<InitializeApp>
<InitializeApp langCode={langCode}>
<IsMobileProvider>
<App
width={width}
@ -59,6 +62,8 @@ const Excalidraw = (props: ExcalidrawProps) => {
isCollaborating={isCollaborating}
onPointerUpdate={onPointerUpdate}
onExportToBackend={onExportToBackend}
renderFooter={renderFooter}
langCode={langCode}
/>
</IsMobileProvider>
</InitializeApp>
@ -94,3 +99,4 @@ export {
getSyncableElements,
getElementMap,
} from "../../element";
export { defaultLang, languages } from "../../i18n";

View File

@ -456,7 +456,7 @@ Object {
exports[`given element A and group of elements B and given both are selected when user clicks on B, on pointer up only elements from B should be selected: [end of test] number of elements 1`] = `3`;
exports[`given element A and group of elements B and given both are selected when user clicks on B, on pointer up only elements from B should be selected: [end of test] number of renders 1`] = `24`;
exports[`given element A and group of elements B and given both are selected when user clicks on B, on pointer up only elements from B should be selected: [end of test] number of renders 1`] = `25`;
exports[`given element A and group of elements B and given both are selected when user shift-clicks on B, on pointer up only element A should be selected: [end of test] appState 1`] = `
Object {
@ -920,7 +920,7 @@ Object {
exports[`given element A and group of elements B and given both are selected when user shift-clicks on B, on pointer up only element A should be selected: [end of test] number of elements 1`] = `3`;
exports[`given element A and group of elements B and given both are selected when user shift-clicks on B, on pointer up only element A should be selected: [end of test] number of renders 1`] = `20`;
exports[`given element A and group of elements B and given both are selected when user shift-clicks on B, on pointer up only element A should be selected: [end of test] number of renders 1`] = `21`;
exports[`regression tests Cmd/Ctrl-click exclusively select element under pointer: [end of test] appState 1`] = `
Object {
@ -1693,7 +1693,7 @@ Object {
exports[`regression tests Cmd/Ctrl-click exclusively select element under pointer: [end of test] number of elements 1`] = `3`;
exports[`regression tests Cmd/Ctrl-click exclusively select element under pointer: [end of test] number of renders 1`] = `39`;
exports[`regression tests Cmd/Ctrl-click exclusively select element under pointer: [end of test] number of renders 1`] = `40`;
exports[`regression tests Drags selected element when hitting only bounding box and keeps element selected: [end of test] appState 1`] = `
Object {
@ -1894,7 +1894,7 @@ Object {
exports[`regression tests Drags selected element when hitting only bounding box and keeps element selected: [end of test] number of elements 1`] = `1`;
exports[`regression tests Drags selected element when hitting only bounding box and keeps element selected: [end of test] number of renders 1`] = `8`;
exports[`regression tests Drags selected element when hitting only bounding box and keeps element selected: [end of test] number of renders 1`] = `9`;
exports[`regression tests adjusts z order when grouping: [end of test] appState 1`] = `
Object {
@ -2349,7 +2349,7 @@ Object {
exports[`regression tests adjusts z order when grouping: [end of test] number of elements 1`] = `3`;
exports[`regression tests adjusts z order when grouping: [end of test] number of renders 1`] = `18`;
exports[`regression tests adjusts z order when grouping: [end of test] number of renders 1`] = `19`;
exports[`regression tests alt-drag duplicates an element: [end of test] appState 1`] = `
Object {
@ -2599,7 +2599,7 @@ Object {
exports[`regression tests alt-drag duplicates an element: [end of test] number of elements 1`] = `2`;
exports[`regression tests alt-drag duplicates an element: [end of test] number of renders 1`] = `8`;
exports[`regression tests alt-drag duplicates an element: [end of test] number of renders 1`] = `9`;
exports[`regression tests arrow keys: [end of test] appState 1`] = `
Object {
@ -2760,7 +2760,7 @@ Object {
exports[`regression tests arrow keys: [end of test] number of elements 1`] = `1`;
exports[`regression tests arrow keys: [end of test] number of renders 1`] = `17`;
exports[`regression tests arrow keys: [end of test] number of renders 1`] = `18`;
exports[`regression tests can drag element that covers another element, while another elem is selected: [end of test] appState 1`] = `
Object {
@ -3234,7 +3234,7 @@ Object {
exports[`regression tests can drag element that covers another element, while another elem is selected: [end of test] number of elements 1`] = `3`;
exports[`regression tests can drag element that covers another element, while another elem is selected: [end of test] number of renders 1`] = `16`;
exports[`regression tests can drag element that covers another element, while another elem is selected: [end of test] number of renders 1`] = `17`;
exports[`regression tests change the properties of a shape: [end of test] appState 1`] = `
Object {
@ -3539,7 +3539,7 @@ Object {
exports[`regression tests change the properties of a shape: [end of test] number of elements 1`] = `1`;
exports[`regression tests change the properties of a shape: [end of test] number of renders 1`] = `9`;
exports[`regression tests change the properties of a shape: [end of test] number of renders 1`] = `10`;
exports[`regression tests click on an element and drag it: [dragged] appState 1`] = `
Object {
@ -3740,7 +3740,7 @@ Object {
exports[`regression tests click on an element and drag it: [dragged] number of elements 1`] = `1`;
exports[`regression tests click on an element and drag it: [dragged] number of renders 1`] = `8`;
exports[`regression tests click on an element and drag it: [dragged] number of renders 1`] = `9`;
exports[`regression tests click on an element and drag it: [end of test] appState 1`] = `
Object {
@ -3981,7 +3981,7 @@ Object {
exports[`regression tests click on an element and drag it: [end of test] number of elements 1`] = `1`;
exports[`regression tests click on an element and drag it: [end of test] number of renders 1`] = `11`;
exports[`regression tests click on an element and drag it: [end of test] number of renders 1`] = `12`;
exports[`regression tests click to select a shape: [end of test] appState 1`] = `
Object {
@ -4230,7 +4230,7 @@ Object {
exports[`regression tests click to select a shape: [end of test] number of elements 1`] = `2`;
exports[`regression tests click to select a shape: [end of test] number of renders 1`] = `11`;
exports[`regression tests click to select a shape: [end of test] number of renders 1`] = `12`;
exports[`regression tests click-drag to select a group: [end of test] appState 1`] = `
Object {
@ -4588,7 +4588,7 @@ Object {
exports[`regression tests click-drag to select a group: [end of test] number of elements 1`] = `3`;
exports[`regression tests click-drag to select a group: [end of test] number of renders 1`] = `17`;
exports[`regression tests click-drag to select a group: [end of test] number of renders 1`] = `18`;
exports[`regression tests deselects group of selected elements on pointer down when pointer doesn't hit any element: [end of test] appState 1`] = `
Object {
@ -4880,7 +4880,7 @@ Object {
exports[`regression tests deselects group of selected elements on pointer down when pointer doesn't hit any element: [end of test] number of elements 1`] = `2`;
exports[`regression tests deselects group of selected elements on pointer down when pointer doesn't hit any element: [end of test] number of renders 1`] = `12`;
exports[`regression tests deselects group of selected elements on pointer down when pointer doesn't hit any element: [end of test] number of renders 1`] = `13`;
exports[`regression tests deselects group of selected elements on pointer up when pointer hits common bounding box without hitting any element: [end of test] appState 1`] = `
Object {
@ -5184,7 +5184,7 @@ Object {
exports[`regression tests deselects group of selected elements on pointer up when pointer hits common bounding box without hitting any element: [end of test] number of elements 1`] = `2`;
exports[`regression tests deselects group of selected elements on pointer up when pointer hits common bounding box without hitting any element: [end of test] number of renders 1`] = `13`;
exports[`regression tests deselects group of selected elements on pointer up when pointer hits common bounding box without hitting any element: [end of test] number of renders 1`] = `14`;
exports[`regression tests deselects selected element on pointer down when pointer doesn't hit any element: [end of test] appState 1`] = `
Object {
@ -5389,7 +5389,7 @@ Object {
exports[`regression tests deselects selected element on pointer down when pointer doesn't hit any element: [end of test] number of elements 1`] = `1`;
exports[`regression tests deselects selected element on pointer down when pointer doesn't hit any element: [end of test] number of renders 1`] = `6`;
exports[`regression tests deselects selected element on pointer down when pointer doesn't hit any element: [end of test] number of renders 1`] = `7`;
exports[`regression tests deselects selected element, on pointer up, when click hits element bounding box but doesn't hit the element: [end of test] appState 1`] = `
Object {
@ -5572,7 +5572,7 @@ Object {
exports[`regression tests deselects selected element, on pointer up, when click hits element bounding box but doesn't hit the element: [end of test] number of elements 1`] = `1`;
exports[`regression tests deselects selected element, on pointer up, when click hits element bounding box but doesn't hit the element: [end of test] number of renders 1`] = `7`;
exports[`regression tests deselects selected element, on pointer up, when click hits element bounding box but doesn't hit the element: [end of test] number of renders 1`] = `8`;
exports[`regression tests double click to edit a group: [end of test] appState 1`] = `
Object {
@ -6022,7 +6022,7 @@ Object {
exports[`regression tests double click to edit a group: [end of test] number of elements 1`] = `3`;
exports[`regression tests double click to edit a group: [end of test] number of renders 1`] = `16`;
exports[`regression tests double click to edit a group: [end of test] number of renders 1`] = `17`;
exports[`regression tests drags selected elements from point inside common bounding box that doesn't hit any element and keeps elements selected after dragging: [end of test] appState 1`] = `
Object {
@ -6337,7 +6337,7 @@ Object {
exports[`regression tests drags selected elements from point inside common bounding box that doesn't hit any element and keeps elements selected after dragging: [end of test] number of elements 1`] = `2`;
exports[`regression tests drags selected elements from point inside common bounding box that doesn't hit any element and keeps elements selected after dragging: [end of test] number of renders 1`] = `14`;
exports[`regression tests drags selected elements from point inside common bounding box that doesn't hit any element and keeps elements selected after dragging: [end of test] number of renders 1`] = `15`;
exports[`regression tests draw every type of shape: [end of test] appState 1`] = `
Object {
@ -8368,7 +8368,7 @@ Object {
exports[`regression tests draw every type of shape: [end of test] number of elements 1`] = `8`;
exports[`regression tests draw every type of shape: [end of test] number of renders 1`] = `49`;
exports[`regression tests draw every type of shape: [end of test] number of renders 1`] = `50`;
exports[`regression tests given a group of selected elements with an element that is not selected inside the group common bounding box when element that is not selected is clicked should switch selection to not selected element on pointer up: [end of test] appState 1`] = `
Object {
@ -8727,7 +8727,7 @@ Object {
exports[`regression tests given a group of selected elements with an element that is not selected inside the group common bounding box when element that is not selected is clicked should switch selection to not selected element on pointer up: [end of test] number of elements 1`] = `3`;
exports[`regression tests given a group of selected elements with an element that is not selected inside the group common bounding box when element that is not selected is clicked should switch selection to not selected element on pointer up: [end of test] number of renders 1`] = `17`;
exports[`regression tests given a group of selected elements with an element that is not selected inside the group common bounding box when element that is not selected is clicked should switch selection to not selected element on pointer up: [end of test] number of renders 1`] = `18`;
exports[`regression tests given a selected element A and a not selected element B with higher z-index than A and given B partialy overlaps A when there's a shift-click on the overlapped section B is added to the selection: [end of test] appState 1`] = `
Object {
@ -8979,7 +8979,7 @@ Object {
exports[`regression tests given a selected element A and a not selected element B with higher z-index than A and given B partialy overlaps A when there's a shift-click on the overlapped section B is added to the selection: [end of test] number of elements 1`] = `2`;
exports[`regression tests given a selected element A and a not selected element B with higher z-index than A and given B partialy overlaps A when there's a shift-click on the overlapped section B is added to the selection: [end of test] number of renders 1`] = `15`;
exports[`regression tests given a selected element A and a not selected element B with higher z-index than A and given B partialy overlaps A when there's a shift-click on the overlapped section B is added to the selection: [end of test] number of renders 1`] = `16`;
exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when clicking intersection between A and B B should be selected on pointer up: [end of test] appState 1`] = `
Object {
@ -9229,7 +9229,7 @@ Object {
exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when clicking intersection between A and B B should be selected on pointer up: [end of test] number of elements 1`] = `2`;
exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when clicking intersection between A and B B should be selected on pointer up: [end of test] number of renders 1`] = `15`;
exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when clicking intersection between A and B B should be selected on pointer up: [end of test] number of renders 1`] = `16`;
exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when dragging on intersection between A and B A should be dragged and keep being selected: [end of test] appState 1`] = `
Object {
@ -9541,7 +9541,7 @@ Object {
exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when dragging on intersection between A and B A should be dragged and keep being selected: [end of test] number of elements 1`] = `2`;
exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when dragging on intersection between A and B A should be dragged and keep being selected: [end of test] number of renders 1`] = `16`;
exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when dragging on intersection between A and B A should be dragged and keep being selected: [end of test] number of renders 1`] = `17`;
exports[`regression tests key 2 selects rectangle tool: [end of test] appState 1`] = `
Object {
@ -9702,7 +9702,7 @@ Object {
exports[`regression tests key 2 selects rectangle tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key 2 selects rectangle tool: [end of test] number of renders 1`] = `5`;
exports[`regression tests key 2 selects rectangle tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key 3 selects diamond tool: [end of test] appState 1`] = `
Object {
@ -9863,7 +9863,7 @@ Object {
exports[`regression tests key 3 selects diamond tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key 3 selects diamond tool: [end of test] number of renders 1`] = `5`;
exports[`regression tests key 3 selects diamond tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key 4 selects ellipse tool: [end of test] appState 1`] = `
Object {
@ -10024,7 +10024,7 @@ Object {
exports[`regression tests key 4 selects ellipse tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key 4 selects ellipse tool: [end of test] number of renders 1`] = `5`;
exports[`regression tests key 4 selects ellipse tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key 5 selects arrow tool: [end of test] appState 1`] = `
Object {
@ -10215,7 +10215,7 @@ Object {
exports[`regression tests key 5 selects arrow tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key 5 selects arrow tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key 5 selects arrow tool: [end of test] number of renders 1`] = `7`;
exports[`regression tests key 6 selects line tool: [end of test] appState 1`] = `
Object {
@ -10406,7 +10406,7 @@ Object {
exports[`regression tests key 6 selects line tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key 6 selects line tool: [end of test] number of renders 1`] = `5`;
exports[`regression tests key 6 selects line tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key 7 selects draw tool: [end of test] appState 1`] = `
Object {
@ -10597,7 +10597,7 @@ Object {
exports[`regression tests key 7 selects draw tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key 7 selects draw tool: [end of test] number of renders 1`] = `5`;
exports[`regression tests key 7 selects draw tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key a selects arrow tool: [end of test] appState 1`] = `
Object {
@ -10788,7 +10788,7 @@ Object {
exports[`regression tests key a selects arrow tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key a selects arrow tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key a selects arrow tool: [end of test] number of renders 1`] = `7`;
exports[`regression tests key d selects diamond tool: [end of test] appState 1`] = `
Object {
@ -10949,7 +10949,7 @@ Object {
exports[`regression tests key d selects diamond tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key d selects diamond tool: [end of test] number of renders 1`] = `5`;
exports[`regression tests key d selects diamond tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key e selects ellipse tool: [end of test] appState 1`] = `
Object {
@ -11110,7 +11110,7 @@ Object {
exports[`regression tests key e selects ellipse tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key e selects ellipse tool: [end of test] number of renders 1`] = `5`;
exports[`regression tests key e selects ellipse tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key l selects line tool: [end of test] appState 1`] = `
Object {
@ -11301,7 +11301,7 @@ Object {
exports[`regression tests key l selects line tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key l selects line tool: [end of test] number of renders 1`] = `5`;
exports[`regression tests key l selects line tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key r selects rectangle tool: [end of test] appState 1`] = `
Object {
@ -11462,7 +11462,7 @@ Object {
exports[`regression tests key r selects rectangle tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key r selects rectangle tool: [end of test] number of renders 1`] = `5`;
exports[`regression tests key r selects rectangle tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests key x selects draw tool: [end of test] appState 1`] = `
Object {
@ -11653,7 +11653,7 @@ Object {
exports[`regression tests key x selects draw tool: [end of test] number of elements 1`] = `1`;
exports[`regression tests key x selects draw tool: [end of test] number of renders 1`] = `5`;
exports[`regression tests key x selects draw tool: [end of test] number of renders 1`] = `6`;
exports[`regression tests make a group and duplicate it: [end of test] appState 1`] = `
Object {
@ -12366,7 +12366,7 @@ Object {
exports[`regression tests make a group and duplicate it: [end of test] number of elements 1`] = `6`;
exports[`regression tests make a group and duplicate it: [end of test] number of renders 1`] = `20`;
exports[`regression tests make a group and duplicate it: [end of test] number of renders 1`] = `21`;
exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] appState 1`] = `
Object {
@ -12616,7 +12616,7 @@ Object {
exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] number of elements 1`] = `2`;
exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] number of renders 1`] = `17`;
exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] number of renders 1`] = `18`;
exports[`regression tests pinch-to-zoom works: [end of test] appState 1`] = `
Object {
@ -12715,7 +12715,7 @@ Object {
exports[`regression tests pinch-to-zoom works: [end of test] number of elements 1`] = `0`;
exports[`regression tests pinch-to-zoom works: [end of test] number of renders 1`] = `7`;
exports[`regression tests pinch-to-zoom works: [end of test] number of renders 1`] = `8`;
exports[`regression tests rerenders UI on language change: [end of test] appState 1`] = `
Object {
@ -12812,7 +12812,7 @@ Object {
exports[`regression tests rerenders UI on language change: [end of test] number of elements 1`] = `0`;
exports[`regression tests rerenders UI on language change: [end of test] number of renders 1`] = `4`;
exports[`regression tests rerenders UI on language change: [end of test] number of renders 1`] = `7`;
exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] appState 1`] = `
Object {
@ -12973,7 +12973,7 @@ Object {
exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] number of elements 1`] = `1`;
exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] number of renders 1`] = `5`;
exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] number of renders 1`] = `6`;
exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] appState 1`] = `
Object {
@ -13278,7 +13278,7 @@ Object {
exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] number of elements 1`] = `2`;
exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] number of renders 1`] = `11`;
exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] number of renders 1`] = `12`;
exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] appState 1`] = `
Object {
@ -13583,7 +13583,7 @@ Object {
exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] number of elements 1`] = `2`;
exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] number of renders 1`] = `11`;
exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] number of renders 1`] = `12`;
exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] appState 1`] = `
Object {
@ -13744,7 +13744,7 @@ Object {
exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] number of elements 1`] = `1`;
exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] number of renders 1`] = `5`;
exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] number of renders 1`] = `6`;
exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] appState 1`] = `
Object {
@ -13937,7 +13937,7 @@ Object {
exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] number of elements 1`] = `1`;
exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] number of renders 1`] = `6`;
exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] number of renders 1`] = `7`;
exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] appState 1`] = `
Object {
@ -14183,7 +14183,7 @@ Object {
exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] number of elements 1`] = `2`;
exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] number of renders 1`] = `6`;
exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] number of renders 1`] = `7`;
exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] appState 1`] = `
Object {
@ -14504,7 +14504,7 @@ Object {
exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] number of elements 1`] = `2`;
exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] number of renders 1`] = `12`;
exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] number of renders 1`] = `13`;
exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] appState 1`] = `
Object {
@ -15340,7 +15340,7 @@ Object {
exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] number of elements 1`] = `2`;
exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] number of renders 1`] = `20`;
exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] number of renders 1`] = `21`;
exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] appState 1`] = `
Object {
@ -15645,7 +15645,7 @@ Object {
exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] number of elements 1`] = `2`;
exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] number of renders 1`] = `10`;
exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] number of renders 1`] = `11`;
exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] appState 1`] = `
Object {
@ -15950,7 +15950,7 @@ Object {
exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] number of elements 1`] = `2`;
exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] number of renders 1`] = `10`;
exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] number of renders 1`] = `11`;
exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] appState 1`] = `
Object {
@ -16326,7 +16326,7 @@ Object {
exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] number of elements 1`] = `2`;
exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] number of renders 1`] = `13`;
exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] number of renders 1`] = `14`;
exports[`regression tests shift click on selected element should deselect it on pointer up: [end of test] appState 1`] = `
Object {
@ -16490,7 +16490,7 @@ Object {
exports[`regression tests shift click on selected element should deselect it on pointer up: [end of test] number of elements 1`] = `1`;
exports[`regression tests shift click on selected element should deselect it on pointer up: [end of test] number of renders 1`] = `7`;
exports[`regression tests shift click on selected element should deselect it on pointer up: [end of test] number of renders 1`] = `8`;
exports[`regression tests shift-click to multiselect, then drag: [end of test] appState 1`] = `
Object {
@ -16808,7 +16808,7 @@ Object {
exports[`regression tests shift-click to multiselect, then drag: [end of test] number of elements 1`] = `2`;
exports[`regression tests shift-click to multiselect, then drag: [end of test] number of renders 1`] = `16`;
exports[`regression tests shift-click to multiselect, then drag: [end of test] number of renders 1`] = `17`;
exports[`regression tests should show fill icons when element has non transparent background: [end of test] appState 1`] = `
Object {
@ -17044,7 +17044,7 @@ Object {
exports[`regression tests should show fill icons when element has non transparent background: [end of test] number of elements 1`] = `1`;
exports[`regression tests should show fill icons when element has non transparent background: [end of test] number of renders 1`] = `9`;
exports[`regression tests should show fill icons when element has non transparent background: [end of test] number of renders 1`] = `10`;
exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] appState 1`] = `
Object {
@ -17296,7 +17296,7 @@ Object {
exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] number of elements 1`] = `2`;
exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] number of renders 1`] = `13`;
exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] number of renders 1`] = `14`;
exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] appState 1`] = `
Object {
@ -17620,7 +17620,7 @@ Object {
exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] number of elements 1`] = `2`;
exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] number of renders 1`] = `14`;
exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] number of renders 1`] = `15`;
exports[`regression tests shows context menu for canvas: [end of test] appState 1`] = `
Object {
@ -17717,7 +17717,7 @@ Object {
exports[`regression tests shows context menu for canvas: [end of test] number of elements 1`] = `0`;
exports[`regression tests shows context menu for canvas: [end of test] number of renders 1`] = `1`;
exports[`regression tests shows context menu for canvas: [end of test] number of renders 1`] = `2`;
exports[`regression tests shows context menu for element: [end of test] appState 1`] = `
Object {
@ -17878,7 +17878,7 @@ Object {
exports[`regression tests shows context menu for element: [end of test] number of elements 1`] = `1`;
exports[`regression tests shows context menu for element: [end of test] number of renders 1`] = `5`;
exports[`regression tests shows context menu for element: [end of test] number of renders 1`] = `6`;
exports[`regression tests single-clicking on a subgroup of a selected group should not alter selection: [end of test] appState 1`] = `
Object {
@ -18696,7 +18696,7 @@ Object {
exports[`regression tests single-clicking on a subgroup of a selected group should not alter selection: [end of test] number of elements 1`] = `4`;
exports[`regression tests single-clicking on a subgroup of a selected group should not alter selection: [end of test] number of renders 1`] = `35`;
exports[`regression tests single-clicking on a subgroup of a selected group should not alter selection: [end of test] number of renders 1`] = `36`;
exports[`regression tests spacebar + drag scrolls the canvas: [end of test] appState 1`] = `
Object {
@ -18793,7 +18793,7 @@ Object {
exports[`regression tests spacebar + drag scrolls the canvas: [end of test] number of elements 1`] = `0`;
exports[`regression tests spacebar + drag scrolls the canvas: [end of test] number of renders 1`] = `4`;
exports[`regression tests spacebar + drag scrolls the canvas: [end of test] number of renders 1`] = `5`;
exports[`regression tests supports nested groups: [end of test] appState 1`] = `
Object {
@ -19522,7 +19522,7 @@ Object {
exports[`regression tests supports nested groups: [end of test] number of elements 1`] = `3`;
exports[`regression tests supports nested groups: [end of test] number of renders 1`] = `28`;
exports[`regression tests supports nested groups: [end of test] number of renders 1`] = `29`;
exports[`regression tests switches from group of selected elements to another element on pointer down: [end of test] appState 1`] = `
Object {
@ -19924,7 +19924,7 @@ Object {
exports[`regression tests switches from group of selected elements to another element on pointer down: [end of test] number of elements 1`] = `3`;
exports[`regression tests switches from group of selected elements to another element on pointer down: [end of test] number of renders 1`] = `16`;
exports[`regression tests switches from group of selected elements to another element on pointer down: [end of test] number of renders 1`] = `17`;
exports[`regression tests switches selected element on pointer down: [end of test] appState 1`] = `
Object {
@ -20216,7 +20216,7 @@ Object {
exports[`regression tests switches selected element on pointer down: [end of test] number of elements 1`] = `2`;
exports[`regression tests switches selected element on pointer down: [end of test] number of renders 1`] = `10`;
exports[`regression tests switches selected element on pointer down: [end of test] number of renders 1`] = `11`;
exports[`regression tests two-finger scroll works: [end of test] appState 1`] = `
Object {
@ -20315,7 +20315,7 @@ Object {
exports[`regression tests two-finger scroll works: [end of test] number of elements 1`] = `0`;
exports[`regression tests two-finger scroll works: [end of test] number of renders 1`] = `9`;
exports[`regression tests two-finger scroll works: [end of test] number of renders 1`] = `10`;
exports[`regression tests undo/redo drawing an element: [end of test] appState 1`] = `
Object {
@ -20810,7 +20810,7 @@ Object {
exports[`regression tests undo/redo drawing an element: [end of test] number of elements 1`] = `3`;
exports[`regression tests undo/redo drawing an element: [end of test] number of renders 1`] = `26`;
exports[`regression tests undo/redo drawing an element: [end of test] number of renders 1`] = `27`;
exports[`regression tests updates fontSize & fontFamily appState: [end of test] appState 1`] = `
Object {
@ -20907,7 +20907,7 @@ Object {
exports[`regression tests updates fontSize & fontFamily appState: [end of test] number of elements 1`] = `0`;
exports[`regression tests updates fontSize & fontFamily appState: [end of test] number of renders 1`] = `3`;
exports[`regression tests updates fontSize & fontFamily appState: [end of test] number of renders 1`] = `4`;
exports[`regression tests zoom hotkeys: [end of test] appState 1`] = `
Object {
@ -21004,4 +21004,4 @@ Object {
exports[`regression tests zoom hotkeys: [end of test] number of elements 1`] = `0`;
exports[`regression tests zoom hotkeys: [end of test] number of renders 1`] = `3`;
exports[`regression tests zoom hotkeys: [end of test] number of renders 1`] = `4`;

View File

@ -2,7 +2,7 @@ import React from "react";
import ReactDOM from "react-dom";
import { render } from "./test-utils";
import ExcalidrawApp from "../excalidraw-app";
import { setLanguage } from "../i18n";
import { defaultLang, setLanguage } from "../i18n";
import { UI, Pointer, Keyboard } from "./helpers/ui";
import { API } from "./helpers/api";
import { KEYS } from "../keys";
@ -60,7 +60,7 @@ describe("aligning", () => {
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
mouse.reset();
await setLanguage("en.json");
await setLanguage(defaultLang);
await render(<ExcalidrawApp />);
});

View File

@ -4,9 +4,8 @@ import ReactDOM from "react-dom";
import { copiedStyles } from "../actions/actionStyles";
import { ShortcutName } from "../actions/shortcuts";
import { ExcalidrawElement } from "../element/types";
import { setLanguage } from "../i18n";
import { CODES, KEYS } from "../keys";
import Excalidraw from "../packages/excalidraw/index";
import ExcalidrawApp from "../excalidraw-app";
import { reseed } from "../random";
import * as Renderer from "../renderer/renderScene";
import { setDateTimeForTests } from "../utils";
@ -19,6 +18,7 @@ import {
screen,
waitFor,
} from "./test-utils";
import { defaultLang } from "../i18n";
const { h } = window;
@ -75,8 +75,7 @@ beforeEach(async () => {
finger1.reset();
finger2.reset();
await setLanguage("en.json");
await render(<Excalidraw offsetLeft={0} offsetTop={0} />);
await render(<ExcalidrawApp />);
});
afterEach(() => {
@ -439,7 +438,7 @@ describe("regression tests", () => {
await waitFor(() => expect(screen.queryByTitle(/thin/i)).toBeNull());
// reset language
fireEvent.change(document.querySelector(".dropdown-select__language")!, {
target: { value: "en" },
target: { value: defaultLang.code },
});
// switching back to English
await waitFor(() => expect(screen.queryByTitle(/thin/i)).not.toBeNull());

View File

@ -19,6 +19,7 @@ import { ImportedDataState } from "./data/types";
import { ExcalidrawImperativeAPI } from "./components/App";
import type { ResolvablePromise } from "./utils";
import { Spreadsheet } from "./charts";
import { Language } from "./i18n";
export type FlooredNumber = number & { _brand: "FlooredNumber" };
export type Point = Readonly<RoughPoint>;
@ -181,6 +182,8 @@ export interface ExcalidrawProps {
appState: AppState,
canvas: HTMLCanvasElement | null,
) => void;
renderFooter?: (isMobile: boolean) => JSX.Element;
langCode?: Language["code"];
}
export type SceneData = {