fix: Expose variable width on tablet UI

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Mark Tolmacs
2026-04-16 17:31:10 +00:00
parent 5aa16c3052
commit b547dc4f7a
2 changed files with 83 additions and 40 deletions
@@ -1,3 +1,5 @@
import clsx from "clsx";
import { pointFrom } from "@excalidraw/math"; import { pointFrom } from "@excalidraw/math";
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useRef, useState } from "react";
@@ -2063,44 +2065,70 @@ export const actionChangeStrokeShape = register<boolean>({
captureUpdate: CaptureUpdateAction.IMMEDIATELY, captureUpdate: CaptureUpdateAction.IMMEDIATELY,
}; };
}, },
PanelComponent: ({ elements, appState, updateData, app }) => ( PanelComponent: ({ elements, appState, updateData, app }) => {
<fieldset> const { isCompact } = getStylesPanelInfo(app);
<legend>{t("labels.strokeShape")}</legend>
<div className="buttonList"> const currentValue = getFormValue(
<RadioSelection elements,
group="stroke-shape" app,
options={[ (element) => {
{ if (isFreeDrawElement(element)) {
value: true, return element.simulatePressure;
text: t("labels.strokeShape_constant"), }
icon: FreedrawPressureConstantIcon, return null;
testId: "strokeShape-constant", },
}, (element) => isFreeDrawElement(element),
{ (hasSelection) =>
value: false, hasSelection ? null : appState.currentItemFreedrawConstantPressure,
text: t("labels.strokeShape_pressure"), );
icon: FreedrawPressureSensitiveIcon,
testId: "strokeShape-pressure", if (isCompact) {
}, const isConstantPressure = currentValue !== false;
]} return (
value={getFormValue( <button
elements, type="button"
app, className={clsx("compact-action-button", {
(element) => { active: !isConstantPressure,
if (isFreeDrawElement(element)) { })}
return element.simulatePressure; title={
} isConstantPressure
return null; ? t("labels.strokeShape_constant")
}, : t("labels.strokeShape_pressure")
(element) => isFreeDrawElement(element), }
(hasSelection) => onClick={() => updateData(!isConstantPressure)}
hasSelection >
? null {isConstantPressure
: appState.currentItemFreedrawConstantPressure, ? FreedrawPressureConstantIcon
)} : FreedrawPressureSensitiveIcon}
onChange={(value) => updateData(value)} </button>
/> );
</div> }
</fieldset>
), return (
<fieldset>
<legend>{t("labels.strokeShape")}</legend>
<div className="buttonList">
<RadioSelection
group="stroke-shape"
options={[
{
value: true,
text: t("labels.strokeShape_constant"),
icon: FreedrawPressureConstantIcon,
testId: "strokeShape-constant",
},
{
value: false,
text: t("labels.strokeShape_pressure"),
icon: FreedrawPressureSensitiveIcon,
testId: "strokeShape-pressure",
},
]}
value={currentValue}
onChange={(value) => updateData(value)}
/>
</div>
</fieldset>
);
},
}); });
@@ -834,6 +834,14 @@ export const CompactShapeActions = ({
container={container} container={container}
/> />
{/* Stroke Shape Toggle (freedraw only) */}
{(appState.activeTool.type === "freedraw" ||
targetElements.some((element) => element.type === "freedraw")) && (
<div className="compact-action-item">
{renderAction("changeStrokeShape")}
</div>
)}
<CombinedArrowProperties <CombinedArrowProperties
appState={appState} appState={appState}
renderAction={renderAction} renderAction={renderAction}
@@ -969,6 +977,13 @@ export const MobileShapeActions = ({
targetElements={targetElements} targetElements={targetElements}
container={container} container={container}
/> />
{/* Stroke Shape Toggle (freedraw only) */}
{(appState.activeTool.type === "freedraw" ||
targetElements.some((element) => element.type === "freedraw")) && (
<div className="compact-action-item">
{renderAction("changeStrokeShape")}
</div>
)}
{/* Combined Arrow Properties */} {/* Combined Arrow Properties */}
<CombinedArrowProperties <CombinedArrowProperties
appState={appState} appState={appState}