Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab9cd5460b |
@@ -552,4 +552,4 @@ export const MOBILE_ACTION_BUTTON_BG = {
|
||||
} as const;
|
||||
|
||||
export const DEFAULT_STROKE_STREAMLINE = 0.5;
|
||||
export const DEFAULT_STROKE_STREAMLINE_PRECISE = 0.2;
|
||||
export const DEFAULT_STROKE_STREAMLINE_PRECISE = 0.3;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/types",
|
||||
"rootDir": "../"
|
||||
"outDir": "./dist/types"
|
||||
},
|
||||
"include": ["src/**/*", "global.d.ts"],
|
||||
"exclude": ["**/*.test.*", "tests", "types", "examples", "dist"]
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
curvePointDistance,
|
||||
distanceToLineSegment,
|
||||
pointRotateRads,
|
||||
polygonIncludesPointNonZero,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import { ellipse, ellipseDistanceFromPoint } from "@excalidraw/math/ellipse";
|
||||
@@ -47,8 +48,9 @@ export const distanceToElement = (
|
||||
return distanceToEllipseElement(element, elementsMap, p);
|
||||
case "line":
|
||||
case "arrow":
|
||||
case "freedraw":
|
||||
return distanceToLinearOrFreeDraElement(element, elementsMap, p);
|
||||
case "freedraw":
|
||||
return distanceToFreeDrawElement(element, elementsMap, p);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -145,3 +147,30 @@ const distanceToLinearOrFreeDraElement = (
|
||||
...curves.map((a) => curvePointDistance(a, p)),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the distance of a point to a freedraw element.
|
||||
*
|
||||
* @param element The freedraw element
|
||||
* @param p The point to consider
|
||||
* @returns 0 if the point is within the inked area, otherwise the euclidean
|
||||
* distance to the stroke outline
|
||||
*/
|
||||
const distanceToFreeDrawElement = (
|
||||
element: ExcalidrawFreeDrawElement,
|
||||
elementsMap: ElementsMap,
|
||||
p: GlobalPoint,
|
||||
) => {
|
||||
const [lines] = deconstructLinearOrFreeDrawElement(element, elementsMap);
|
||||
|
||||
if (lines.length === 0) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const polygon = lines.map((line) => line[0]);
|
||||
if (polygonIncludesPointNonZero(p, polygon)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.min(...lines.map((s) => distanceToLineSegment(p, s)));
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
LINE_POLYGON_POINT_MERGE_DISTANCE,
|
||||
applyDarkModeFilter,
|
||||
DEFAULT_STROKE_STREAMLINE,
|
||||
DEFAULT_STROKE_STREAMLINE_PRECISE,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import { RoughGenerator } from "roughjs/bin/generator";
|
||||
@@ -676,69 +677,45 @@ export const generateLinearCollisionShape = (
|
||||
});
|
||||
}
|
||||
case "freedraw": {
|
||||
if (element.points.length < 2) {
|
||||
const outlinePoints = getFreedrawOutlinePoints(element);
|
||||
|
||||
if (outlinePoints.length < 2) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const simplifiedPoints = simplify(
|
||||
element.points as Mutable<LocalPoint[]>,
|
||||
0.75,
|
||||
);
|
||||
const collisionOutline =
|
||||
element.strokeOptions?.variability === "constant" &&
|
||||
CONSTANT_WIDTH_FREEDRAW.STREAMLINE > 0
|
||||
? (simplify(
|
||||
outlinePoints as Mutable<LocalPoint[]>,
|
||||
CONSTANT_WIDTH_FREEDRAW.STREAMLINE,
|
||||
) as [number, number][])
|
||||
: outlinePoints;
|
||||
|
||||
return generator
|
||||
.curve(simplifiedPoints as [number, number][], options)
|
||||
.sets[0].ops.slice(0, element.points.length)
|
||||
.map((op, i) => {
|
||||
if (i === 0) {
|
||||
const p = pointRotateRads<GlobalPoint>(
|
||||
pointFrom<GlobalPoint>(
|
||||
element.x + op.data[0],
|
||||
element.y + op.data[1],
|
||||
),
|
||||
center,
|
||||
element.angle,
|
||||
);
|
||||
if (collisionOutline.length < 2) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return {
|
||||
op: "move",
|
||||
data: pointFrom<LocalPoint>(p[0] - element.x, p[1] - element.y),
|
||||
};
|
||||
}
|
||||
// Close the outline polygon so its boundary never has a gap at the seam.
|
||||
const [firstX, firstY] = collisionOutline[0];
|
||||
const [lastX, lastY] = collisionOutline[collisionOutline.length - 1];
|
||||
const closedOutline =
|
||||
firstX === lastX && firstY === lastY
|
||||
? collisionOutline
|
||||
: [...collisionOutline, collisionOutline[0]];
|
||||
|
||||
return {
|
||||
op: "bcurveTo",
|
||||
data: [
|
||||
pointRotateRads(
|
||||
pointFrom<GlobalPoint>(
|
||||
element.x + op.data[0],
|
||||
element.y + op.data[1],
|
||||
),
|
||||
center,
|
||||
element.angle,
|
||||
),
|
||||
pointRotateRads(
|
||||
pointFrom<GlobalPoint>(
|
||||
element.x + op.data[2],
|
||||
element.y + op.data[3],
|
||||
),
|
||||
center,
|
||||
element.angle,
|
||||
),
|
||||
pointRotateRads(
|
||||
pointFrom<GlobalPoint>(
|
||||
element.x + op.data[4],
|
||||
element.y + op.data[5],
|
||||
),
|
||||
center,
|
||||
element.angle,
|
||||
),
|
||||
]
|
||||
.map((p) =>
|
||||
pointFrom<LocalPoint>(p[0] - element.x, p[1] - element.y),
|
||||
)
|
||||
.flat(),
|
||||
};
|
||||
});
|
||||
return closedOutline.map((point, idx) => {
|
||||
const p = pointRotateRads<GlobalPoint>(
|
||||
pointFrom<GlobalPoint>(element.x + point[0], element.y + point[1]),
|
||||
center,
|
||||
element.angle,
|
||||
);
|
||||
|
||||
return {
|
||||
op: idx === 0 ? "move" : "lineTo",
|
||||
data: pointFrom<LocalPoint>(p[0] - element.x, p[1] - element.y),
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1185,15 +1162,20 @@ const VARIABLE_WIDTH_FREEDRAW = {
|
||||
SIZE_FACTOR: 4.25,
|
||||
THINNING: 0.6,
|
||||
SMOOTHING: 0.5,
|
||||
STREAMLINE: DEFAULT_STROKE_STREAMLINE,
|
||||
} as const;
|
||||
|
||||
const CONSTANT_WIDTH_FREEDRAW = {
|
||||
/** Stroke size relative to `strokeWidth` for uniform (laser) strokes. */
|
||||
SIZE_FACTOR: 1.4,
|
||||
STREAMLINE: DEFAULT_STROKE_STREAMLINE_PRECISE,
|
||||
} as const;
|
||||
|
||||
const getFreedrawStreamline = (element: ExcalidrawFreeDrawElement) =>
|
||||
element.strokeOptions?.streamline ?? DEFAULT_STROKE_STREAMLINE;
|
||||
element.strokeOptions?.streamline ??
|
||||
(element.strokeOptions?.variability === "constant"
|
||||
? CONSTANT_WIDTH_FREEDRAW.STREAMLINE
|
||||
: VARIABLE_WIDTH_FREEDRAW.STREAMLINE);
|
||||
|
||||
/**
|
||||
* Pressure-sensitive (variable width) freedraw outline, rendered with
|
||||
|
||||
@@ -218,3 +218,54 @@ describe("hitElementItself cache", () => {
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("freedraw collision matches the rendered stroke width", () => {
|
||||
// A straight, horizontal stroke centered on y === 0.
|
||||
const points = Array.from({ length: 21 }, (_, i) =>
|
||||
pointFrom<LocalPoint>(i * 5, 0),
|
||||
);
|
||||
|
||||
const createFreeDraw = (variability: "variable" | "constant") =>
|
||||
API.createElement({
|
||||
type: "freedraw",
|
||||
x: 0,
|
||||
y: 0,
|
||||
strokeWidth: 10,
|
||||
points,
|
||||
strokeOptions: { variability, streamline: 0.5 },
|
||||
});
|
||||
|
||||
const distanceAt = (
|
||||
element: ReturnType<typeof createFreeDraw>,
|
||||
x: number,
|
||||
y: number,
|
||||
) =>
|
||||
distance.distanceToElement(
|
||||
element,
|
||||
arrayToMap([element]),
|
||||
pointFrom<GlobalPoint>(x, y),
|
||||
);
|
||||
|
||||
it("treats a point on the centerline as a direct hit for both modes", () => {
|
||||
expect(distanceAt(createFreeDraw("variable"), 50, 0)).toBe(0);
|
||||
expect(distanceAt(createFreeDraw("constant"), 50, 0)).toBe(0);
|
||||
});
|
||||
|
||||
it("hits across the body of a thick stroke, not just near the centerline", () => {
|
||||
expect(distanceAt(createFreeDraw("variable"), 50, 20)).toBe(0);
|
||||
});
|
||||
|
||||
it("uses a wider hit area for variable-width than for constant-width strokes", () => {
|
||||
const offset = 20;
|
||||
const variableDistance = distanceAt(createFreeDraw("variable"), 50, offset);
|
||||
const constantDistance = distanceAt(createFreeDraw("constant"), 50, offset);
|
||||
|
||||
expect(variableDistance).toBe(0);
|
||||
expect(constantDistance).toBeGreaterThan(0);
|
||||
expect(variableDistance).toBeLessThan(constantDistance);
|
||||
});
|
||||
|
||||
it("does not hit points clearly outside even the widest stroke", () => {
|
||||
expect(distanceAt(createFreeDraw("variable"), 50, 45)).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "../",
|
||||
"outDir": "./dist/types"
|
||||
},
|
||||
"include": ["src/**/*", "global.d.ts"],
|
||||
|
||||
@@ -112,6 +112,9 @@ export const actionClearCanvas = register({
|
||||
theme: appState.theme,
|
||||
penMode: appState.penMode,
|
||||
penDetected: appState.penDetected,
|
||||
currentItemStrokeVariability: appState.penDetected
|
||||
? "variable"
|
||||
: "constant",
|
||||
exportBackground: appState.exportBackground,
|
||||
exportEmbedScene: appState.exportEmbedScene,
|
||||
gridSize: appState.gridSize,
|
||||
|
||||
@@ -87,7 +87,6 @@ import type { CaptureUpdateActionType } from "@excalidraw/element";
|
||||
|
||||
import { trackEvent } from "../analytics";
|
||||
import { RadioSelection } from "../components/RadioSelection";
|
||||
import { ToolButton } from "../components/ToolButton";
|
||||
import { ColorPicker } from "../components/ColorPicker/ColorPicker";
|
||||
import { FontPicker } from "../components/FontPicker/FontPicker";
|
||||
import { IconPicker } from "../components/IconPicker";
|
||||
@@ -719,25 +718,6 @@ export const actionChangeFreedrawMode = register<StrokeVariability>({
|
||||
hasSelection ? null : appState.currentItemStrokeVariability,
|
||||
) ?? appState.currentItemStrokeVariability;
|
||||
|
||||
// in the compact UI the pressure setting is rendered as a single button
|
||||
// that cycles between the two variability modes on click
|
||||
if (data?.cycle) {
|
||||
const isVariable = strokeVariability === "variable";
|
||||
return (
|
||||
<ToolButton
|
||||
type="button"
|
||||
icon={
|
||||
isVariable
|
||||
? strokeVariabilityVariableIcon
|
||||
: strokeVariabilityConstantIcon
|
||||
}
|
||||
title={t("labels.pressure")}
|
||||
aria-label={t("labels.pressure")}
|
||||
onClick={() => updateData(isVariable ? "constant" : "variable")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<fieldset>
|
||||
<legend>{t("labels.pressure")}</legend>
|
||||
|
||||
@@ -395,17 +395,11 @@ const CombinedShapeProperties = ({
|
||||
hasStrokeWidth(element.type),
|
||||
)) &&
|
||||
renderAction("changeStrokeWidth")}
|
||||
{
|
||||
/* in compact UI the freedraw pressure setting is rendered as a
|
||||
standalone cycle button in the compact actions list; we render
|
||||
it in the combined properties popup as well for clarity
|
||||
*/
|
||||
(hasFreedrawMode(appState.activeTool.type) ||
|
||||
targetElements.some((element) =>
|
||||
hasFreedrawMode(element.type),
|
||||
)) &&
|
||||
renderAction("changeFreedrawMode")
|
||||
}
|
||||
{(hasFreedrawMode(appState.activeTool.type) ||
|
||||
targetElements.some((element) =>
|
||||
hasFreedrawMode(element.type),
|
||||
)) &&
|
||||
renderAction("changeFreedrawMode")}
|
||||
{(hasStrokeStyle(appState.activeTool.type) ||
|
||||
targetElements.some((element) =>
|
||||
hasStrokeStyle(element.type),
|
||||
@@ -838,14 +832,6 @@ export const CompactShapeActions = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Freedraw pressure: standalone button cycling the variability mode */}
|
||||
{(hasFreedrawMode(appState.activeTool.type) ||
|
||||
targetElements.some((element) => hasFreedrawMode(element.type))) && (
|
||||
<div className="compact-action-item">
|
||||
{renderAction("changeFreedrawMode", { cycle: true })}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<CombinedShapeProperties
|
||||
appState={appState}
|
||||
renderAction={renderAction}
|
||||
@@ -1074,11 +1060,6 @@ export const ShapesSwitcher = ({
|
||||
const isFullStylesPanel = stylesPanelMode === "full";
|
||||
const isCompactStylesPanel = stylesPanelMode === "compact";
|
||||
|
||||
// a pen detected on a tool button's pointer-down, to be applied (enabling
|
||||
// pen mode) only after the tap's `change` has committed — see the tool
|
||||
// button handlers below
|
||||
const pendingPenDetectionRef = useRef(false);
|
||||
|
||||
const SELECTION_TOOLS = [
|
||||
{
|
||||
type: "selection",
|
||||
@@ -1177,13 +1158,8 @@ export const ShapesSwitcher = ({
|
||||
aria-keyshortcuts={shortcut}
|
||||
data-testid={`toolbar-${value}`}
|
||||
onPointerDown={({ pointerType }) => {
|
||||
// Detect the pen here (pointerType is reliable on pointer-down)
|
||||
// but DON'T enable pen mode yet: calling setState mid-gesture
|
||||
// re-renders the controlled radio and, on iOS/iPadOS, aborts
|
||||
// the ensuing click so the tool isn't selected on the first pen
|
||||
// tap. Defer it until the tap's `change` has committed (below).
|
||||
if (!app.state.penDetected && pointerType === "pen") {
|
||||
pendingPenDetectionRef.current = true;
|
||||
app.togglePenMode(true);
|
||||
}
|
||||
|
||||
if (value === "selection") {
|
||||
@@ -1194,21 +1170,16 @@ export const ShapesSwitcher = ({
|
||||
}
|
||||
}
|
||||
}}
|
||||
onChange={() => {
|
||||
onChange={({ pointerType }) => {
|
||||
if (app.state.activeTool.type !== value) {
|
||||
trackEvent("toolbar", value, "ui");
|
||||
}
|
||||
app.setActiveTool({ type: value });
|
||||
|
||||
// Apply the pen detection captured on pointer-down now that the
|
||||
// tool is selected. rAF keeps the resulting re-render out of the
|
||||
// `change` event itself. We rely on the pointer-down detection
|
||||
// rather than this handler's pointerType because the latter is
|
||||
// unreliable on iOS (its backing ref is cleared before the
|
||||
// delayed click fires).
|
||||
if (pendingPenDetectionRef.current) {
|
||||
pendingPenDetectionRef.current = false;
|
||||
requestAnimationFrame(() => app.togglePenMode(true));
|
||||
if (value === "image") {
|
||||
app.setActiveTool({
|
||||
type: value,
|
||||
});
|
||||
} else {
|
||||
app.setActiveTool({ type: value });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -4308,9 +4308,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
return {
|
||||
penMode: force ?? !prevState.penMode,
|
||||
penDetected: true,
|
||||
currentItemStrokeVariability: !prevState.penDetected
|
||||
? "variable"
|
||||
: prevState.currentItemStrokeVariability,
|
||||
currentItemStrokeVariability: "variable",
|
||||
};
|
||||
});
|
||||
};
|
||||
@@ -9017,7 +9015,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
strokeOptions: {
|
||||
variability: strokeVariability,
|
||||
streamline:
|
||||
event.pointerType !== "mouse"
|
||||
strokeVariability === "constant" && event.pointerType !== "mouse"
|
||||
? DEFAULT_STROKE_STREAMLINE_PRECISE
|
||||
: DEFAULT_STROKE_STREAMLINE,
|
||||
},
|
||||
|
||||
@@ -120,24 +120,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// on tablet, the pen mode button is rendered as a separate floating button
|
||||
// below the compact actions menu (see LayerUI.tsx)
|
||||
.App-menu_top__left > .ToolIcon__penMode {
|
||||
justify-self: center;
|
||||
|
||||
.ToolIcon__icon {
|
||||
width: var(--lg-button-size);
|
||||
height: var(--lg-button-size);
|
||||
background-color: var(--island-bg-color);
|
||||
box-shadow: var(--shadow-island);
|
||||
}
|
||||
|
||||
// no shadow while pen mode is active (the active fill is enough)
|
||||
.ToolIcon_type_checkbox:checked + .ToolIcon__icon {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.disable-view-mode {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
@@ -235,6 +235,8 @@ const LayerUI = ({
|
||||
);
|
||||
|
||||
const renderSelectedShapeActions = () => {
|
||||
const isCompactMode = isCompactStylesPanel;
|
||||
|
||||
return (
|
||||
<Section
|
||||
heading="selectedShapeActions"
|
||||
@@ -242,7 +244,7 @@ const LayerUI = ({
|
||||
"transition-left": appState.zenModeEnabled,
|
||||
})}
|
||||
>
|
||||
{isCompactStylesPanel ? (
|
||||
{isCompactMode ? (
|
||||
<Island
|
||||
className={clsx("compact-shape-actions-island")}
|
||||
padding={0}
|
||||
@@ -310,23 +312,6 @@ const LayerUI = ({
|
||||
>
|
||||
{shouldRenderSelectedShapeActions && renderSelectedShapeActions()}
|
||||
</div>
|
||||
{/* in compact UI the pen mode button lives outside the toolbar, as
|
||||
a separate floating button below the compact actions menu
|
||||
(same as we render it on mobile); shown alongside the compact
|
||||
actions island, i.e. when a drawing tool or elements are
|
||||
selected */}
|
||||
{isCompactStylesPanel &&
|
||||
!appState.viewModeEnabled &&
|
||||
shouldRenderSelectedShapeActions && (
|
||||
<PenModeButton
|
||||
zenModeEnabled={appState.zenModeEnabled}
|
||||
checked={appState.penMode}
|
||||
onChange={() => onPenModeToggle(null)}
|
||||
title={t("toolBar.penMode")}
|
||||
isMobile
|
||||
penDetected={appState.penDetected}
|
||||
/>
|
||||
)}
|
||||
</Stack.Col>
|
||||
{!appState.viewModeEnabled &&
|
||||
appState.openDialog?.name !== "elementLinkSelector" && (
|
||||
@@ -358,18 +343,13 @@ const LayerUI = ({
|
||||
/>
|
||||
{heading}
|
||||
<Stack.Row gap={spacing.toolbarInnerRowGap}>
|
||||
{/* in compact UI the pen mode button is rendered
|
||||
as a separate floating button below the compact
|
||||
actions menu */}
|
||||
{!isCompactStylesPanel && (
|
||||
<PenModeButton
|
||||
zenModeEnabled={appState.zenModeEnabled}
|
||||
checked={appState.penMode}
|
||||
onChange={() => onPenModeToggle(null)}
|
||||
title={t("toolBar.penMode")}
|
||||
penDetected={appState.penDetected}
|
||||
/>
|
||||
)}
|
||||
<PenModeButton
|
||||
zenModeEnabled={appState.zenModeEnabled}
|
||||
checked={appState.penMode}
|
||||
onChange={() => onPenModeToggle(null)}
|
||||
title={t("toolBar.penMode")}
|
||||
penDetected={appState.penDetected}
|
||||
/>
|
||||
<LockButton
|
||||
checked={appState.activeTool.locked}
|
||||
onChange={onLockToggle}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "../",
|
||||
"outDir": "./dist/types"
|
||||
},
|
||||
"include": ["**/*"],
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/types",
|
||||
"rootDir": "../"
|
||||
"outDir": "./dist/types"
|
||||
},
|
||||
"include": ["src/**/*", "global.d.ts"],
|
||||
"exclude": ["**/*.test.*", "tests", "types", "examples", "dist"]
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
"version": "1.3.1",
|
||||
"description": "Generate outline for laser pointer tool",
|
||||
"type": "module",
|
||||
"types": "./dist/types/laser-pointer/src/index.d.ts",
|
||||
"types": "./dist/types/index.d.ts",
|
||||
"main": "./dist/prod/index.js",
|
||||
"module": "./dist/prod/index.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/types/laser-pointer/src/index.d.ts",
|
||||
"types": "./dist/types/index.d.ts",
|
||||
"development": "./dist/dev/index.js",
|
||||
"production": "./dist/prod/index.js",
|
||||
"default": "./dist/prod/index.js"
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/types",
|
||||
"rootDir": "../"
|
||||
"outDir": "./dist/types"
|
||||
},
|
||||
"include": ["src/**/*", "global.d.ts"],
|
||||
"exclude": ["**/*.test.*", "tests", "types", "examples", "dist"]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "../",
|
||||
"outDir": "./dist/types"
|
||||
},
|
||||
"include": ["src/**/*", "global.d.ts"],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"declaration": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"moduleResolution": "Node",
|
||||
"resolveJsonModule": true,
|
||||
"jsx": "react-jsx",
|
||||
"emitDeclarationOnly": true,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "../",
|
||||
"outDir": "./dist/types"
|
||||
},
|
||||
"include": ["src/**/*", "global.d.ts"],
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
|
||||
Reference in New Issue
Block a user