fix: Narrow the type of Action.name
while still allowing custom names
This commit is contained in:
parent
cbb349e34b
commit
00691631d8
@ -2,6 +2,7 @@ import React from "react";
|
|||||||
import {
|
import {
|
||||||
Action,
|
Action,
|
||||||
UpdaterFn,
|
UpdaterFn,
|
||||||
|
ActionName,
|
||||||
ActionResult,
|
ActionResult,
|
||||||
PanelComponentProps,
|
PanelComponentProps,
|
||||||
ActionSource,
|
ActionSource,
|
||||||
@ -40,7 +41,7 @@ const trackAction = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class ActionManager {
|
export class ActionManager {
|
||||||
actions = {} as Record<Action["name"], Action>;
|
actions = {} as Record<ActionName, Action>;
|
||||||
actionPredicates = [] as ActionPredicateFn[];
|
actionPredicates = [] as ActionPredicateFn[];
|
||||||
|
|
||||||
updater: (actionResult: ActionResult | Promise<ActionResult>) => void;
|
updater: (actionResult: ActionResult | Promise<ActionResult>) => void;
|
||||||
@ -92,7 +93,7 @@ export class ActionManager {
|
|||||||
|
|
||||||
const actions: Action[] = [];
|
const actions: Action[] = [];
|
||||||
for (const key in this.actions) {
|
for (const key in this.actions) {
|
||||||
const action = this.actions[key];
|
const action = this.actions[key as ActionName];
|
||||||
if (filter(action, elements, appState, data)) {
|
if (filter(action, elements, appState, data)) {
|
||||||
actions.push(action);
|
actions.push(action);
|
||||||
}
|
}
|
||||||
@ -167,7 +168,7 @@ export class ActionManager {
|
|||||||
/**
|
/**
|
||||||
* @param data additional data sent to the PanelComponent
|
* @param data additional data sent to the PanelComponent
|
||||||
*/
|
*/
|
||||||
renderAction = (name: Action["name"], data?: PanelComponentProps["data"]) => {
|
renderAction = (name: ActionName, data?: PanelComponentProps["data"]) => {
|
||||||
const canvasActions = this.app.props.UIOptions.canvasActions;
|
const canvasActions = this.app.props.UIOptions.canvasActions;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -45,6 +45,7 @@ export type UpdaterFn = (res: ActionResult) => void;
|
|||||||
export type ActionFilterFn = (action: Action) => void;
|
export type ActionFilterFn = (action: Action) => void;
|
||||||
|
|
||||||
export type ActionName =
|
export type ActionName =
|
||||||
|
| `custom.${string}`
|
||||||
| "copy"
|
| "copy"
|
||||||
| "cut"
|
| "cut"
|
||||||
| "paste"
|
| "paste"
|
||||||
@ -145,7 +146,7 @@ export type PanelComponentProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export interface Action {
|
export interface Action {
|
||||||
name: string;
|
name: ActionName;
|
||||||
PanelComponent?: React.FC<PanelComponentProps>;
|
PanelComponent?: React.FC<PanelComponentProps>;
|
||||||
perform: ActionFn;
|
perform: ActionFn;
|
||||||
keyPriority?: number;
|
keyPriority?: number;
|
||||||
|
@ -28,7 +28,7 @@ export const SubtypeButton = (
|
|||||||
const keyTest: Action["keyTest"] =
|
const keyTest: Action["keyTest"] =
|
||||||
key !== undefined ? (event) => event.code === `Key${key}` : undefined;
|
key !== undefined ? (event) => event.code === `Key${key}` : undefined;
|
||||||
const subtypeAction: Action = {
|
const subtypeAction: Action = {
|
||||||
name: subtype,
|
name: `custom.${subtype}`,
|
||||||
trackEvent: false,
|
trackEvent: false,
|
||||||
predicate: (...rest) => rest[4]?.subtype === subtype,
|
predicate: (...rest) => rest[4]?.subtype === subtype,
|
||||||
perform: (elements, appState) => {
|
perform: (elements, appState) => {
|
||||||
@ -147,7 +147,7 @@ export const SubtypeToggles = () => {
|
|||||||
<>
|
<>
|
||||||
{getSubtypeNames().map((subtype) =>
|
{getSubtypeNames().map((subtype) =>
|
||||||
am.renderAction(
|
am.renderAction(
|
||||||
subtype,
|
`custom.${subtype}`,
|
||||||
hasAlwaysEnabledActions(subtype) ? { onContextMenu } : {},
|
hasAlwaysEnabledActions(subtype) ? { onContextMenu } : {},
|
||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
|
@ -28,7 +28,7 @@ let parentTypeMap: readonly {
|
|||||||
}[] = [];
|
}[] = [];
|
||||||
let subtypeActionMap: readonly {
|
let subtypeActionMap: readonly {
|
||||||
subtype: Subtype;
|
subtype: Subtype;
|
||||||
actions: readonly SubtypeActionName[];
|
actions: readonly ActionName[];
|
||||||
}[] = [];
|
}[] = [];
|
||||||
let disabledActionMap: readonly {
|
let disabledActionMap: readonly {
|
||||||
subtype: Subtype;
|
subtype: Subtype;
|
||||||
@ -91,7 +91,7 @@ const isDisabledActionName = (s: any): s is DisabledActionName =>
|
|||||||
// by `subtype` (if `isAdded` is false)?
|
// by `subtype` (if `isAdded` is false)?
|
||||||
const isForSubtype = (
|
const isForSubtype = (
|
||||||
subtype: ExcalidrawElement["subtype"],
|
subtype: ExcalidrawElement["subtype"],
|
||||||
actionName: ActionName | SubtypeActionName,
|
actionName: ActionName,
|
||||||
isAdded: boolean,
|
isAdded: boolean,
|
||||||
) => {
|
) => {
|
||||||
const actions = isAdded ? subtypeActionMap : disabledActionMap;
|
const actions = isAdded ? subtypeActionMap : disabledActionMap;
|
||||||
@ -371,7 +371,12 @@ export const prepareSubtype = (
|
|||||||
if (record.actionNames) {
|
if (record.actionNames) {
|
||||||
subtypeActionMap = [
|
subtypeActionMap = [
|
||||||
...subtypeActionMap,
|
...subtypeActionMap,
|
||||||
{ subtype, actions: record.actionNames },
|
{
|
||||||
|
subtype,
|
||||||
|
actions: record.actionNames.map(
|
||||||
|
(actionName) => `custom.${actionName}` as ActionName,
|
||||||
|
),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
if (record.disabledNames) {
|
if (record.disabledNames) {
|
||||||
@ -383,7 +388,12 @@ export const prepareSubtype = (
|
|||||||
if (record.alwaysEnabledNames) {
|
if (record.alwaysEnabledNames) {
|
||||||
alwaysEnabledMap = [
|
alwaysEnabledMap = [
|
||||||
...alwaysEnabledMap,
|
...alwaysEnabledMap,
|
||||||
{ subtype, actions: record.alwaysEnabledNames },
|
{
|
||||||
|
subtype,
|
||||||
|
actions: record.alwaysEnabledNames.map(
|
||||||
|
(actionName) => `custom.${actionName}` as ActionName,
|
||||||
|
),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
if (record.shortcutMap) {
|
if (record.shortcutMap) {
|
||||||
|
@ -1395,7 +1395,7 @@ const enableActionChangeMathProps = (
|
|||||||
const createMathActions = () => {
|
const createMathActions = () => {
|
||||||
const mathActions: Action[] = [];
|
const mathActions: Action[] = [];
|
||||||
const actionUseTexTrue: Action = {
|
const actionUseTexTrue: Action = {
|
||||||
name: "useTexTrue",
|
name: "custom.useTexTrue",
|
||||||
perform: (elements, appState) => {
|
perform: (elements, appState) => {
|
||||||
const mathOnly = getMathProps.getMathOnly(appState);
|
const mathOnly = getMathProps.getMathOnly(appState);
|
||||||
const customData = appState.customData ?? {};
|
const customData = appState.customData ?? {};
|
||||||
@ -1414,7 +1414,7 @@ const createMathActions = () => {
|
|||||||
trackEvent: false,
|
trackEvent: false,
|
||||||
};
|
};
|
||||||
const actionUseTexFalse: Action = {
|
const actionUseTexFalse: Action = {
|
||||||
name: "useTexFalse",
|
name: "custom.useTexFalse",
|
||||||
perform: (elements, appState) => {
|
perform: (elements, appState) => {
|
||||||
const mathOnly = getMathProps.getMathOnly(appState);
|
const mathOnly = getMathProps.getMathOnly(appState);
|
||||||
const customData = appState.customData ?? {};
|
const customData = appState.customData ?? {};
|
||||||
@ -1433,7 +1433,7 @@ const createMathActions = () => {
|
|||||||
trackEvent: false,
|
trackEvent: false,
|
||||||
};
|
};
|
||||||
const actionResetUseTex: Action = {
|
const actionResetUseTex: Action = {
|
||||||
name: "resetUseTex",
|
name: "custom.resetUseTex",
|
||||||
perform: (elements, appState) => {
|
perform: (elements, appState) => {
|
||||||
const useTex = getMathProps.getUseTex(appState);
|
const useTex = getMathProps.getUseTex(appState);
|
||||||
const modElements = changeProperty(
|
const modElements = changeProperty(
|
||||||
@ -1481,7 +1481,7 @@ const createMathActions = () => {
|
|||||||
trackEvent: false,
|
trackEvent: false,
|
||||||
};
|
};
|
||||||
const actionChangeMathOnly: Action = {
|
const actionChangeMathOnly: Action = {
|
||||||
name: "changeMathOnly",
|
name: "custom.changeMathOnly",
|
||||||
perform: (elements, appState, mathOnly: boolean | null) => {
|
perform: (elements, appState, mathOnly: boolean | null) => {
|
||||||
if (mathOnly === null) {
|
if (mathOnly === null) {
|
||||||
mathOnly = getFormValue(
|
mathOnly = getFormValue(
|
||||||
|
@ -37,7 +37,7 @@ describe("regression tests", () => {
|
|||||||
const el23: ExcalidrawElement[] = [el2, el3];
|
const el23: ExcalidrawElement[] = [el2, el3];
|
||||||
const el123: ExcalidrawElement[] = [el1, el2, el3];
|
const el123: ExcalidrawElement[] = [el1, el2, el3];
|
||||||
// Set up the custom Action enablers
|
// Set up the custom Action enablers
|
||||||
const enableName = "custom" as Action["name"];
|
const enableName = "custom.enable";
|
||||||
const enableAction: Action = {
|
const enableAction: Action = {
|
||||||
name: enableName,
|
name: enableName,
|
||||||
perform: (): ActionResult => {
|
perform: (): ActionResult => {
|
||||||
|
@ -81,7 +81,7 @@ const test1: SubtypeRecord = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const testAction: Action = {
|
const testAction: Action = {
|
||||||
name: TEST_ACTION,
|
name: `custom.${TEST_ACTION}`,
|
||||||
trackEvent: false,
|
trackEvent: false,
|
||||||
perform: (elements, appState) => {
|
perform: (elements, appState) => {
|
||||||
return {
|
return {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user