Merge branch 'master' into mtolmacs/feat/precise-hitboxes
This commit is contained in:
commit
49613ad0c3
@ -52,7 +52,7 @@
|
|||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.excalidraw .panelColumn {
|
.excalidraw .selected-shape-actions {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ import type { Scene } from "@excalidraw/element";
|
|||||||
import type { CaptureUpdateActionType } from "@excalidraw/element";
|
import type { CaptureUpdateActionType } from "@excalidraw/element";
|
||||||
|
|
||||||
import { trackEvent } from "../analytics";
|
import { trackEvent } from "../analytics";
|
||||||
import { ButtonIconSelect } from "../components/ButtonIconSelect";
|
import { RadioSelection } from "../components/RadioSelection";
|
||||||
import { ColorPicker } from "../components/ColorPicker/ColorPicker";
|
import { ColorPicker } from "../components/ColorPicker/ColorPicker";
|
||||||
import { FontPicker } from "../components/FontPicker/FontPicker";
|
import { FontPicker } from "../components/FontPicker/FontPicker";
|
||||||
import { IconPicker } from "../components/IconPicker";
|
import { IconPicker } from "../components/IconPicker";
|
||||||
@ -418,7 +418,8 @@ export const actionChangeFillStyle = register({
|
|||||||
return (
|
return (
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t("labels.fill")}</legend>
|
<legend>{t("labels.fill")}</legend>
|
||||||
<ButtonIconSelect
|
<div className="buttonList">
|
||||||
|
<RadioSelection
|
||||||
type="button"
|
type="button"
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
@ -462,6 +463,7 @@ export const actionChangeFillStyle = register({
|
|||||||
updateData(nextValue);
|
updateData(nextValue);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -485,7 +487,8 @@ export const actionChangeStrokeWidth = register({
|
|||||||
PanelComponent: ({ elements, appState, updateData, app }) => (
|
PanelComponent: ({ elements, appState, updateData, app }) => (
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t("labels.strokeWidth")}</legend>
|
<legend>{t("labels.strokeWidth")}</legend>
|
||||||
<ButtonIconSelect
|
<div className="buttonList">
|
||||||
|
<RadioSelection
|
||||||
group="stroke-width"
|
group="stroke-width"
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
@ -517,6 +520,7 @@ export const actionChangeStrokeWidth = register({
|
|||||||
)}
|
)}
|
||||||
onChange={(value) => updateData(value)}
|
onChange={(value) => updateData(value)}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
@ -540,7 +544,8 @@ export const actionChangeSloppiness = register({
|
|||||||
PanelComponent: ({ elements, appState, updateData, app }) => (
|
PanelComponent: ({ elements, appState, updateData, app }) => (
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t("labels.sloppiness")}</legend>
|
<legend>{t("labels.sloppiness")}</legend>
|
||||||
<ButtonIconSelect
|
<div className="buttonList">
|
||||||
|
<RadioSelection
|
||||||
group="sloppiness"
|
group="sloppiness"
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
@ -569,6 +574,7 @@ export const actionChangeSloppiness = register({
|
|||||||
)}
|
)}
|
||||||
onChange={(value) => updateData(value)}
|
onChange={(value) => updateData(value)}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
@ -591,7 +597,8 @@ export const actionChangeStrokeStyle = register({
|
|||||||
PanelComponent: ({ elements, appState, updateData, app }) => (
|
PanelComponent: ({ elements, appState, updateData, app }) => (
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t("labels.strokeStyle")}</legend>
|
<legend>{t("labels.strokeStyle")}</legend>
|
||||||
<ButtonIconSelect
|
<div className="buttonList">
|
||||||
|
<RadioSelection
|
||||||
group="strokeStyle"
|
group="strokeStyle"
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
@ -620,6 +627,7 @@ export const actionChangeStrokeStyle = register({
|
|||||||
)}
|
)}
|
||||||
onChange={(value) => updateData(value)}
|
onChange={(value) => updateData(value)}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
@ -658,7 +666,8 @@ export const actionChangeFontSize = register({
|
|||||||
PanelComponent: ({ elements, appState, updateData, app }) => (
|
PanelComponent: ({ elements, appState, updateData, app }) => (
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t("labels.fontSize")}</legend>
|
<legend>{t("labels.fontSize")}</legend>
|
||||||
<ButtonIconSelect
|
<div className="buttonList">
|
||||||
|
<RadioSelection
|
||||||
group="font-size"
|
group="font-size"
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
@ -715,6 +724,7 @@ export const actionChangeFontSize = register({
|
|||||||
)}
|
)}
|
||||||
onChange={(value) => updateData(value)}
|
onChange={(value) => updateData(value)}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
@ -1186,7 +1196,8 @@ export const actionChangeTextAlign = register({
|
|||||||
return (
|
return (
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t("labels.textAlign")}</legend>
|
<legend>{t("labels.textAlign")}</legend>
|
||||||
<ButtonIconSelect<TextAlign | false>
|
<div className="buttonList">
|
||||||
|
<RadioSelection<TextAlign | false>
|
||||||
group="text-align"
|
group="text-align"
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
@ -1232,6 +1243,7 @@ export const actionChangeTextAlign = register({
|
|||||||
)}
|
)}
|
||||||
onChange={(value) => updateData(value)}
|
onChange={(value) => updateData(value)}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -1274,7 +1286,8 @@ export const actionChangeVerticalAlign = register({
|
|||||||
PanelComponent: ({ elements, appState, updateData, app }) => {
|
PanelComponent: ({ elements, appState, updateData, app }) => {
|
||||||
return (
|
return (
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<ButtonIconSelect<VerticalAlign | false>
|
<div className="buttonList">
|
||||||
|
<RadioSelection<VerticalAlign | false>
|
||||||
group="text-align"
|
group="text-align"
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
@ -1322,6 +1335,7 @@ export const actionChangeVerticalAlign = register({
|
|||||||
)}
|
)}
|
||||||
onChange={(value) => updateData(value)}
|
onChange={(value) => updateData(value)}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -1369,7 +1383,8 @@ export const actionChangeRoundness = register({
|
|||||||
return (
|
return (
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t("labels.edges")}</legend>
|
<legend>{t("labels.edges")}</legend>
|
||||||
<ButtonIconSelect
|
<div className="buttonList">
|
||||||
|
<RadioSelection
|
||||||
group="edges"
|
group="edges"
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
@ -1387,7 +1402,11 @@ export const actionChangeRoundness = register({
|
|||||||
elements,
|
elements,
|
||||||
app,
|
app,
|
||||||
(element) =>
|
(element) =>
|
||||||
hasLegacyRoundness ? null : element.roundness ? "round" : "sharp",
|
hasLegacyRoundness
|
||||||
|
? null
|
||||||
|
: element.roundness
|
||||||
|
? "round"
|
||||||
|
: "sharp",
|
||||||
(element) =>
|
(element) =>
|
||||||
!isArrowElement(element) && element.hasOwnProperty("roundness"),
|
!isArrowElement(element) && element.hasOwnProperty("roundness"),
|
||||||
(hasSelection) =>
|
(hasSelection) =>
|
||||||
@ -1395,6 +1414,7 @@ export const actionChangeRoundness = register({
|
|||||||
)}
|
)}
|
||||||
onChange={(value) => updateData(value)}
|
onChange={(value) => updateData(value)}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -1710,7 +1730,8 @@ export const actionChangeArrowType = register({
|
|||||||
return (
|
return (
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t("labels.arrowtypes")}</legend>
|
<legend>{t("labels.arrowtypes")}</legend>
|
||||||
<ButtonIconSelect
|
<div className="buttonList">
|
||||||
|
<RadioSelection
|
||||||
group="arrowtypes"
|
group="arrowtypes"
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
@ -1752,6 +1773,7 @@ export const actionChangeArrowType = register({
|
|||||||
)}
|
)}
|
||||||
onChange={(value) => updateData(value)}
|
onChange={(value) => updateData(value)}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -154,7 +154,7 @@ export const SelectedShapeActions = ({
|
|||||||
!isSingleElementBoundContainer && alignActionsPredicate(appState, app);
|
!isSingleElementBoundContainer && alignActionsPredicate(appState, app);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="panelColumn">
|
<div className="selected-shape-actions">
|
||||||
<div>
|
<div>
|
||||||
{canChangeStrokeColor(appState, targetElements) &&
|
{canChangeStrokeColor(appState, targetElements) &&
|
||||||
renderAction("changeStrokeColor")}
|
renderAction("changeStrokeColor")}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
import clsx from "clsx";
|
|
||||||
|
|
||||||
export const ButtonSelect = <T extends Object>({
|
|
||||||
options,
|
|
||||||
value,
|
|
||||||
onChange,
|
|
||||||
group,
|
|
||||||
}: {
|
|
||||||
options: { value: T; text: string }[];
|
|
||||||
value: T | null;
|
|
||||||
onChange: (value: T) => void;
|
|
||||||
group: string;
|
|
||||||
}) => (
|
|
||||||
<div className="buttonList">
|
|
||||||
{options.map((option) => (
|
|
||||||
<label
|
|
||||||
key={option.text}
|
|
||||||
className={clsx({ active: value === option.value })}
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
name={group}
|
|
||||||
onChange={() => onChange(option.value)}
|
|
||||||
checked={value === option.value}
|
|
||||||
/>
|
|
||||||
{option.text}
|
|
||||||
</label>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
@ -6,7 +6,7 @@ import { FONT_FAMILY } from "@excalidraw/common";
|
|||||||
import type { FontFamilyValues } from "@excalidraw/element/types";
|
import type { FontFamilyValues } from "@excalidraw/element/types";
|
||||||
|
|
||||||
import { t } from "../../i18n";
|
import { t } from "../../i18n";
|
||||||
import { ButtonIconSelect } from "../ButtonIconSelect";
|
import { RadioSelection } from "../RadioSelection";
|
||||||
import { ButtonSeparator } from "../ButtonSeparator";
|
import { ButtonSeparator } from "../ButtonSeparator";
|
||||||
import {
|
import {
|
||||||
FontFamilyCodeIcon,
|
FontFamilyCodeIcon,
|
||||||
@ -82,12 +82,14 @@ export const FontPicker = React.memo(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div role="dialog" aria-modal="true" className="FontPicker__container">
|
<div role="dialog" aria-modal="true" className="FontPicker__container">
|
||||||
<ButtonIconSelect<FontFamilyValues | false>
|
<div className="buttonList">
|
||||||
|
<RadioSelection<FontFamilyValues | false>
|
||||||
type="button"
|
type="button"
|
||||||
options={defaultFonts}
|
options={defaultFonts}
|
||||||
value={selectedFontFamily}
|
value={selectedFontFamily}
|
||||||
onClick={onSelectCallback}
|
onClick={onSelectCallback}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
<ButtonSeparator />
|
<ButtonSeparator />
|
||||||
<Popover.Root open={isOpened} onOpenChange={onPopupChange}>
|
<Popover.Root open={isOpened} onOpenChange={onPopupChange}>
|
||||||
<FontPickerTrigger selectedFontFamily={selectedFontFamily} />
|
<FontPickerTrigger selectedFontFamily={selectedFontFamily} />
|
||||||
|
@ -4,8 +4,7 @@ import { ButtonIcon } from "./ButtonIcon";
|
|||||||
|
|
||||||
import type { JSX } from "react";
|
import type { JSX } from "react";
|
||||||
|
|
||||||
// TODO: It might be "clever" to add option.icon to the existing component <ButtonSelect />
|
export const RadioSelection = <T extends Object>(
|
||||||
export const ButtonIconSelect = <T extends Object>(
|
|
||||||
props: {
|
props: {
|
||||||
options: {
|
options: {
|
||||||
value: T;
|
value: T;
|
||||||
@ -28,7 +27,7 @@ export const ButtonIconSelect = <T extends Object>(
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
) => (
|
) => (
|
||||||
<div className="buttonList">
|
<>
|
||||||
{props.options.map((option) =>
|
{props.options.map((option) =>
|
||||||
props.type === "button" ? (
|
props.type === "button" ? (
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
@ -56,5 +55,5 @@ export const ButtonIconSelect = <T extends Object>(
|
|||||||
</label>
|
</label>
|
||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
@ -140,7 +140,7 @@ body.excalidraw-cursor-resize * {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panelColumn {
|
.selected-shape-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
row-gap: 0.75rem;
|
row-gap: 0.75rem;
|
||||||
@ -245,10 +245,6 @@ body.excalidraw-cursor-resize * {
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
--bar-padding: calc(4 * var(--space-factor));
|
--bar-padding: calc(4 * var(--space-factor));
|
||||||
padding-top: #{"max(var(--bar-padding), var(--sat,0))"};
|
|
||||||
padding-right: var(--sar, 0);
|
|
||||||
padding-bottom: var(--sab, 0);
|
|
||||||
padding-left: var(--sal, 0);
|
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
@ -263,10 +259,6 @@ body.excalidraw-cursor-resize * {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
pointer-events: var(--ui-pointerEvents);
|
pointer-events: var(--ui-pointerEvents);
|
||||||
|
|
||||||
.panelColumn {
|
|
||||||
padding: 8px 8px 0 8px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +294,10 @@ body.excalidraw-cursor-resize * {
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-bottom: var(--bar-padding);
|
margin-bottom: var(--bar-padding);
|
||||||
|
|
||||||
|
.selected-shape-actions {
|
||||||
|
padding: 8px 8px 0 8px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.App-menu {
|
.App-menu {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user