mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
build: decouple package deps and introduce yarn workspaces (#7415)
* feat: decouple package deps and introduce yarn workspaces * update root directory * fix * fix scripts * fix lint * update path in scripts * remove yarn.lock files from packages * ignore workspace * dummy * dummy * remove comment check * revert workflow changes * ignore ws when installing gh actions * remove log * update path * fix * fix typo
This commit is contained in:
parent
b7d7ccc929
commit
d6cd8b78f1
567 changed files with 5066 additions and 8648 deletions
|
@ -0,0 +1,126 @@
|
|||
@import "../../css/variables.module";
|
||||
|
||||
.excalidraw {
|
||||
.OverwriteConfirm {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
isolation: isolate;
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
|
||||
font-weight: 700;
|
||||
font-size: 1.3125rem;
|
||||
line-height: 130%;
|
||||
align-self: flex-start;
|
||||
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
|
||||
&__Description {
|
||||
box-sizing: border-box;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 1rem;
|
||||
|
||||
@include isMobile {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
padding: 2.5rem;
|
||||
|
||||
background: var(--color-danger-background);
|
||||
border-radius: 0.5rem;
|
||||
|
||||
font-family: "Assistant";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 1rem;
|
||||
line-height: 150%;
|
||||
|
||||
color: var(--color-danger-color);
|
||||
|
||||
&__spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 2.5rem;
|
||||
background: var(--color-danger-icon-background);
|
||||
width: 3.5rem;
|
||||
height: 3.5rem;
|
||||
|
||||
padding: 0.75rem;
|
||||
|
||||
svg {
|
||||
color: var(--color-danger-icon-color);
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.OverwriteConfirm__Description--color-warning {
|
||||
background: var(--color-warning-background);
|
||||
color: var(--color-warning-color);
|
||||
|
||||
.OverwriteConfirm__Description__icon {
|
||||
background: var(--color-warning-icon-background);
|
||||
flex: 0 0 auto;
|
||||
|
||||
svg {
|
||||
color: var(--color-warning-icon-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__Actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
justify-items: stretch;
|
||||
justify-content: center;
|
||||
gap: 1.5rem;
|
||||
|
||||
@include isMobile {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&__Action {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 1.5rem;
|
||||
gap: 0.75rem;
|
||||
flex-basis: 50%;
|
||||
flex-grow: 0;
|
||||
|
||||
&__content {
|
||||
height: 100%;
|
||||
font-size: 0.875rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-weight: 700;
|
||||
font-size: 1.125rem;
|
||||
line-height: 130%;
|
||||
|
||||
margin: 0;
|
||||
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
import React from "react";
|
||||
import { useAtom } from "jotai";
|
||||
|
||||
import { useTunnels } from "../../context/tunnels";
|
||||
import { jotaiScope } from "../../jotai";
|
||||
import { Dialog } from "../Dialog";
|
||||
import { withInternalFallback } from "../hoc/withInternalFallback";
|
||||
import { overwriteConfirmStateAtom } from "./OverwriteConfirmState";
|
||||
|
||||
import { FilledButton } from "../FilledButton";
|
||||
import { alertTriangleIcon } from "../icons";
|
||||
import { Actions, Action } from "./OverwriteConfirmActions";
|
||||
import "./OverwriteConfirm.scss";
|
||||
|
||||
export type OverwriteConfirmDialogProps = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
const OverwriteConfirmDialog = Object.assign(
|
||||
withInternalFallback(
|
||||
"OverwriteConfirmDialog",
|
||||
({ children }: OverwriteConfirmDialogProps) => {
|
||||
const { OverwriteConfirmDialogTunnel } = useTunnels();
|
||||
const [overwriteConfirmState, setState] = useAtom(
|
||||
overwriteConfirmStateAtom,
|
||||
jotaiScope,
|
||||
);
|
||||
|
||||
if (!overwriteConfirmState.active) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
overwriteConfirmState.onClose();
|
||||
setState((state) => ({ ...state, active: false }));
|
||||
};
|
||||
|
||||
const handleConfirm = () => {
|
||||
overwriteConfirmState.onConfirm();
|
||||
setState((state) => ({ ...state, active: false }));
|
||||
};
|
||||
|
||||
return (
|
||||
<OverwriteConfirmDialogTunnel.In>
|
||||
<Dialog onCloseRequest={handleClose} title={false} size={916}>
|
||||
<div className="OverwriteConfirm">
|
||||
<h3>{overwriteConfirmState.title}</h3>
|
||||
<div
|
||||
className={`OverwriteConfirm__Description OverwriteConfirm__Description--color-${overwriteConfirmState.color}`}
|
||||
>
|
||||
<div className="OverwriteConfirm__Description__icon">
|
||||
{alertTriangleIcon}
|
||||
</div>
|
||||
<div>{overwriteConfirmState.description}</div>
|
||||
<div className="OverwriteConfirm__Description__spacer"></div>
|
||||
<FilledButton
|
||||
color={overwriteConfirmState.color}
|
||||
size="large"
|
||||
label={overwriteConfirmState.actionLabel}
|
||||
onClick={handleConfirm}
|
||||
/>
|
||||
</div>
|
||||
<Actions>{children}</Actions>
|
||||
</div>
|
||||
</Dialog>
|
||||
</OverwriteConfirmDialogTunnel.In>
|
||||
);
|
||||
},
|
||||
),
|
||||
{
|
||||
Actions,
|
||||
Action,
|
||||
},
|
||||
);
|
||||
|
||||
export { OverwriteConfirmDialog };
|
|
@ -0,0 +1,85 @@
|
|||
import React from "react";
|
||||
import { FilledButton } from "../FilledButton";
|
||||
import { useExcalidrawActionManager, useExcalidrawSetAppState } from "../App";
|
||||
import { actionSaveFileToDisk } from "../../actions";
|
||||
import { useI18n } from "../../i18n";
|
||||
import { actionChangeExportEmbedScene } from "../../actions/actionExport";
|
||||
|
||||
export type ActionProps = {
|
||||
title: string;
|
||||
children: React.ReactNode;
|
||||
actionLabel: string;
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
export const Action = ({
|
||||
title,
|
||||
children,
|
||||
actionLabel,
|
||||
onClick,
|
||||
}: ActionProps) => {
|
||||
return (
|
||||
<div className="OverwriteConfirm__Actions__Action">
|
||||
<h4>{title}</h4>
|
||||
<div className="OverwriteConfirm__Actions__Action__content">
|
||||
{children}
|
||||
</div>
|
||||
<FilledButton
|
||||
variant="outlined"
|
||||
color="muted"
|
||||
label={actionLabel}
|
||||
size="large"
|
||||
fullWidth
|
||||
onClick={onClick}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const ExportToImage = () => {
|
||||
const { t } = useI18n();
|
||||
const actionManager = useExcalidrawActionManager();
|
||||
const setAppState = useExcalidrawSetAppState();
|
||||
|
||||
return (
|
||||
<Action
|
||||
title={t("overwriteConfirm.action.exportToImage.title")}
|
||||
actionLabel={t("overwriteConfirm.action.exportToImage.button")}
|
||||
onClick={() => {
|
||||
actionManager.executeAction(actionChangeExportEmbedScene, "ui", true);
|
||||
setAppState({ openDialog: { name: "imageExport" } });
|
||||
}}
|
||||
>
|
||||
{t("overwriteConfirm.action.exportToImage.description")}
|
||||
</Action>
|
||||
);
|
||||
};
|
||||
|
||||
export const SaveToDisk = () => {
|
||||
const { t } = useI18n();
|
||||
const actionManager = useExcalidrawActionManager();
|
||||
|
||||
return (
|
||||
<Action
|
||||
title={t("overwriteConfirm.action.saveToDisk.title")}
|
||||
actionLabel={t("overwriteConfirm.action.saveToDisk.button")}
|
||||
onClick={() => {
|
||||
actionManager.executeAction(actionSaveFileToDisk, "ui");
|
||||
}}
|
||||
>
|
||||
{t("overwriteConfirm.action.saveToDisk.description")}
|
||||
</Action>
|
||||
);
|
||||
};
|
||||
|
||||
const Actions = Object.assign(
|
||||
({ children }: { children: React.ReactNode }) => {
|
||||
return <div className="OverwriteConfirm__Actions">{children}</div>;
|
||||
},
|
||||
{
|
||||
ExportToImage,
|
||||
SaveToDisk,
|
||||
},
|
||||
);
|
||||
|
||||
export { Actions };
|
|
@ -0,0 +1,46 @@
|
|||
import { atom } from "jotai";
|
||||
import { jotaiStore } from "../../jotai";
|
||||
import React from "react";
|
||||
|
||||
export type OverwriteConfirmState =
|
||||
| {
|
||||
active: true;
|
||||
title: string;
|
||||
description: React.ReactNode;
|
||||
actionLabel: string;
|
||||
color: "danger" | "warning";
|
||||
|
||||
onClose: () => void;
|
||||
onConfirm: () => void;
|
||||
onReject: () => void;
|
||||
}
|
||||
| { active: false };
|
||||
|
||||
export const overwriteConfirmStateAtom = atom<OverwriteConfirmState>({
|
||||
active: false,
|
||||
});
|
||||
|
||||
export async function openConfirmModal({
|
||||
title,
|
||||
description,
|
||||
actionLabel,
|
||||
color,
|
||||
}: {
|
||||
title: string;
|
||||
description: React.ReactNode;
|
||||
actionLabel: string;
|
||||
color: "danger" | "warning";
|
||||
}) {
|
||||
return new Promise<boolean>((resolve) => {
|
||||
jotaiStore.set(overwriteConfirmStateAtom, {
|
||||
active: true,
|
||||
onConfirm: () => resolve(true),
|
||||
onClose: () => resolve(false),
|
||||
onReject: () => resolve(false),
|
||||
title,
|
||||
description,
|
||||
actionLabel,
|
||||
color,
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue