Skip to content

Commit

Permalink
Typescript: Convert story editor utils (#12737)
Browse files Browse the repository at this point in the history
Co-authored-by: Miina Sikk <miina.sikk@gmail.com>
Co-authored-by: Pascal Birchler <pascalb@google.com>
Co-authored-by: Morten Barklund <morten.barklund@xwp.co>
Co-authored-by: Marcin Pietruszka <marcin@webskill.pl>
  • Loading branch information
5 people committed Dec 9, 2022
1 parent 976a8c5 commit 1622add
Show file tree
Hide file tree
Showing 40 changed files with 335 additions and 394 deletions.
1 change: 1 addition & 0 deletions packages/elements/src/types/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export type TextElementFont =
| CustomTextElementFont;

export interface TextElement extends Element {
backgroundColor: Solid;
content: string;
font: TextElementFont;
}
10 changes: 9 additions & 1 deletion packages/elements/src/types/elementDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export interface DisplayProps<E extends Element> {
element: E;
}

export type Direction = [0 | 1, 0 | 1];

export interface ElementDefinition<E extends Element = Element> {
type: ElementType;
name: string;
Expand All @@ -71,7 +73,7 @@ export interface ElementDefinition<E extends Element = Element> {
Frame: React.VoidFunctionComponent<FrameProps<E>>;
Output: React.VoidFunctionComponent<OutputProps<E>>;
LayerIcon: React.VoidFunctionComponent<LayerIconProps<E>>;
TextContent: React.VoidFunctionComponent<TextContentProps<E>>;
TextContent: (element: E) => string;
Display: React.VoidFunctionComponent<DisplayProps<E>>;
canFlip: boolean;
isMaskable: boolean;
Expand All @@ -90,6 +92,12 @@ export interface ElementDefinition<E extends Element = Element> {
minHeight: number;
};
panels: string[];
updateForResizeEvent?: (
element: Element,
direction: Direction,
newWidth: number,
newHeight: number
) => { height: number };
}

export type ElementTypes = Record<ElementType, ElementDefinition<Element>>;
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import { useCallback, useRef } from '@googleforcreators/react';
/**
* Internal dependencies
*/
import storyPageToCanvas from '../../utils/storyPageToCanvas';
import { getAccessibleTextColorsFromPixels } from '../../utils/contrastUtils';
import useIdleQueue from '../../utils/useIdleTaskQueue';
import { useStory } from '../story';
import { STABLE_ARRAY } from '../../constants';
import storyPageToCanvas from './utils/storyPageToCanvas';
import Context from './context';
import getPixelDataFromCanvas from './getPixelDataFromCanvas';
import usePageCanvasMap from './usePageCanvasMap';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ import { act, renderHook } from '@testing-library/react-hooks';
* Internal dependencies
*/
import { PageCanvasProvider, usePageCanvas } from '..';
import storyPageToCanvas from '../../../utils/storyPageToCanvas';
import storyPageToCanvas from '../utils/storyPageToCanvas';
import useStory from '../../story/useStory';
import createMockPage from '../testUtils/createMockPage';
import { MockStoryProvider, useStoryMock } from '../testUtils/useStoryMock';

jest.mock('../../story/useStory');
jest.mock('../../../utils/storyPageToCanvas');
jest.mock('../utils/storyPageToCanvas');

jest.mock('../../../utils/contrastUtils', () => {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ import { TransformProvider } from '@googleforcreators/transform';
/**
* Internal dependencies
*/
import { FontProvider } from '../app/font';
import DisplayElement from '../components/canvas/displayElement';
import { FontProvider } from '../../font';
import DisplayElement from '../../../components/canvas/displayElement';

const Page = styled.div`
display: block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { useMemo, useCallback, useState } from '@googleforcreators/react';
* Internal dependencies
*/
import useIdleTaskQueue from '../../utils/useIdleTaskQueue';
import storyPageToDataUrl from '../../utils/storyPageToDataUrl';
import storyPageToDataUrl from '../pageCanvas/utils/storyPageToDataUrl';
import Context from './context';

/**
Expand Down Expand Up @@ -52,7 +52,10 @@ function PageDataUrlProvider({ children }) {
}));
};

const clearQueueOfPageTask = queueIdleTask([idleTaskUid, idleTask]);
const clearQueueOfPageTask = queueIdleTask({
taskId: idleTaskUid,
task: idleTask,
});
return () => {
clearQueueOfPageTask();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jest.mock('../../../utils/idleCallback', () => {
};
});

jest.mock('../../../utils/storyPageToDataUrl', () => {
jest.mock('../../pageCanvas/utils/storyPageToDataUrl', () => {
return {
__esModule: true,
// make dataUrl generation predictable
Expand All @@ -60,19 +60,19 @@ describe('usePageDataUrls', () => {
mockIdleCallbacks = [];
runIdleCallbacks = () => {
while (mockIdleCallbacks.length > 0) {
const [, callback] = mockIdleCallbacks.shift();
callback();
const { task } = mockIdleCallbacks.shift();
task();
}
};

requestIdleCallback.mockImplementation((callback) => {
const idleCallbackId = Symbol();
mockIdleCallbacks.push([idleCallbackId, callback]);
mockIdleCallbacks.push({ taskId: idleCallbackId, task: callback });
return idleCallbackId;
});
cancelIdleCallback.mockImplementation((idleCallbackId) => {
mockIdleCallbacks = mockIdleCallbacks.filter(
([id]) => id !== idleCallbackId
({ taskId }) => taskId !== idleCallbackId
);
});
});
Expand Down
5 changes: 2 additions & 3 deletions packages/story-editor/src/components/canvas/frameElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import WithProductPill from '../shopping/frame';
import useDoubleClick from '../../utils/useDoubleClick';
import usePerformanceTracking from '../../utils/usePerformanceTracking';
import { TRACKING_EVENTS } from '../../constants';
import { noop } from '../../utils/noop';
import {
FOCUS_GROUPS,
useFocusGroupRef,
Expand Down Expand Up @@ -103,8 +104,6 @@ const EmptyFrame = styled.div`
pointer-events: none;
`;

const NOOP = () => {};

const FRAME_ELEMENT_MESSAGE = sprintf(
/* translators: %s: Ctrl+Alt+P keyboard shortcut. */
__(
Expand Down Expand Up @@ -219,7 +218,7 @@ function FrameElement({ id }) {
},
[id, setEditingElement, handleSelectElement, isSelected]
);
const handleMediaClick = useDoubleClick(NOOP, handleMediaDoubleClick);
const handleMediaClick = useDoubleClick(noop, handleMediaDoubleClick);

/**
* Announce keyboard options on element.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ import { safeDecodeURIComponent } from '@googleforcreators/url';
*/
import { useStory } from '../../../../app/story';
import cleanForSlug from '../../../../utils/cleanForSlug';
import inRange from '../../../../utils/inRange';
import { Row } from '../../../form';
import { SimplePanel } from '../../panel';
import { inputContainerStyleOverride } from '../../shared/styles';

const inRange = (value, { MIN, MAX }) => value >= MIN && value <= MAX;

export const MIN_MAX = {
PERMALINK: {
MIN: 1,
Expand Down
3 changes: 1 addition & 2 deletions packages/story-editor/src/components/tabview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { useConfig } from '../../app';
import Tooltip from '../tooltip';
import usePerformanceTracking from '../../utils/usePerformanceTracking';
import { TRACKING_EVENTS } from '../../constants';
import { noop } from '../../utils/noop';

const ALERT_ICON_SIZE = 28;
export const TAB_HEIGHT = 32;
Expand Down Expand Up @@ -146,8 +147,6 @@ const TabText = styled(Headline).attrs({
color: inherit;
`;

const noop = () => {};

function UnreffedTab(
{ children, tooltip = null, placement, refId, tabRefs, ...rest },
ref
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,20 @@
* limitations under the License.
*/

class CustomError extends Error {
public file = '';
public isUserError = false;
}
/**
* Helper function to get create a js error.
*
* @param {string} name Error name.
* @param {string} fileName File name.
* @param {string} message Message in error.
* @return {Error} Error Object.
* @param name Error name.
* @param fileName File name.
* @param message Message in error.
* @return Error Object.
*/
function createError(name, fileName, message) {
const validError = new Error();
function createError(name: string, fileName: string, message: string) {
const validError = new CustomError();

validError.name = name;
validError.file = fileName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ import { PAGE_RATIO } from '@googleforcreators/units';
* Creates a thumbnail aspect ratio canvas when given a fullbleed aspect
* ratio canvas.
*
* @param {HTMLCanvasElement} fullbleedCanvas fullbleed aspect ratio canvas element
* @return {HTMLCanvasElement} a new thumbnail aspect ratio canvas element
* @param fullbleedCanvas fullbleed aspect ratio canvas element
* @return a new thumbnail aspect ratio canvas element
*/
function createThumbnailCanvasFromFullbleedCanvas(fullbleedCanvas) {
function createThumbnailCanvasFromFullbleedCanvas(
fullbleedCanvas: HTMLCanvasElement
) {
const thumbnailCanvas = document.createElement('canvas');
const thumbnailContext = thumbnailCanvas.getContext('2d');

Expand All @@ -34,8 +36,9 @@ function createThumbnailCanvasFromFullbleedCanvas(fullbleedCanvas) {
const dy = (fullbleedHeight - thumbnailHeight) / 2;
thumbnailCanvas.width = fullbleedCanvas.width;
thumbnailCanvas.height = thumbnailHeight;
thumbnailContext.drawImage(fullbleedCanvas, 0, -dy);

if (thumbnailContext) {
thumbnailContext.drawImage(fullbleedCanvas, 0, -dy);
}
return thumbnailCanvas;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,31 @@
* limitations under the License.
*/

/**
* External dependencies
*/
import type { DragEvent } from 'react';

/**
* Get Drag Type from event.
*
* @param {DragEvent} e The drag event.
* @param {string} type The type of transfer payload to test against
* @return {boolean} Whether the drag is of the specified type
* @param e The drag event.
* @param type The type of transfer payload to test against
* @return Whether the drag is of the specified type
*/
export function isDragType(e, type) {
export function isDragType(e: DragEvent, type: string) {
if (!e?.dataTransfer?.types) {
return false;
}
return Array.isArray(e.dataTransfer.types)
? e.dataTransfer.types.includes(type)
: e.dataTransfer.types.contains(type);
return e.dataTransfer.types.includes(type);
}

/**
* Get Drag Type from event.
*
* @param {DragEvent} e The drag event.
* @return {boolean} Whether the drag event is relating to a file transfer
* @param e The drag event.
* @return Whether the drag event is relating to a file transfer
*/
export function isDraggingFile(e) {
export function isDraggingFile(e: DragEvent) {
return isDragType(e, 'Files');
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
* External dependencies
*/
import { __, sprintf } from '@googleforcreators/i18n';
import type { Groups } from '@googleforcreators/elements';

export function getNextGroupNumber(groups) {
export function getNextGroupNumber(groups: Groups) {
const nums = [0];
const defaultName = __('Group', 'web-stories');
for (const prop in groups) {
Expand All @@ -34,13 +35,13 @@ export function getNextGroupNumber(groups) {
return Math.max(...nums) + 1;
}

function generateGroupName(groups, name) {
function generateGroupName(groups: Groups, name = '') {
if (!name) {
const groupNumber = getNextGroupNumber(groups);
return sprintf(
/* translators: %d: group number. */
__('Group %d', 'web-stories'),
groupNumber
groupNumber.toString()
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,42 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* External dependencies
*/
import type { MediaElement } from '@googleforcreators/elements';

/**
* Internal dependencies
*/
import type { CropParams } from '../app/media/types';
import { isOffCanvas } from './isOffCanvas';

export function getCropParams(selectedElement) {
export function getCropParams({
x,
y,
width,
height,
rotationAngle,
resource,
}: MediaElement): CropParams {
const { offCanvasLeft, offCanvasRight, offCanvasTop, offCanvasBottom } =
isOffCanvas(selectedElement);
const percentage = selectedElement.width / selectedElement.resource.width;
isOffCanvas({ x, y, width, height, rotationAngle });
const percentage = width / resource.width;
const multiplier = 100 / (percentage * 100);
const offCanvasX = Math.floor((offCanvasLeft + offCanvasRight) * multiplier);
const offCanvasY = Math.floor((offCanvasTop + offCanvasBottom) * multiplier);
const cropWidth = selectedElement.resource.width - offCanvasX;
const cropHeight = selectedElement.resource.height - offCanvasY;
const cropWidth = resource.width - offCanvasX;
const cropHeight = resource.height - offCanvasY;
const cropX = Math.floor(offCanvasLeft * multiplier);
const cropY = Math.floor(offCanvasTop * multiplier);
return {
cropElement: selectedElement,
cropElement: { x, y },
cropWidth,
cropHeight,
cropX,
cropY,
newWidth: selectedElement.width - offCanvasLeft - offCanvasRight,
newHeight: selectedElement.height - offCanvasTop - offCanvasBottom,
newWidth: width - offCanvasLeft - offCanvasRight,
newHeight: height - offCanvasTop - offCanvasBottom,
};
}

0 comments on commit 1622add

Please sign in to comment.