Skip to content

Commit

Permalink
RC-v1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
rachelniceday committed Aug 16, 2023
1 parent fad03b4 commit a19fc54
Show file tree
Hide file tree
Showing 28 changed files with 557 additions and 151 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## 2023-08-16

### 🧰 Added
- `@canva/design`
- Added a `title` property to the response payload of `requestExport`, which represents the title of a successful export.
- Support shape element with image or video fill.
- `@canva/preview`
- Added `ui.startDrag` method for drag and drop behaviour.
- Added `rotate` and `reload` icon. Shout out to [NoahDavey](https://github.com/canva-sdks/canva-apps-sdk-starter-kit/pull/6) for submiting a PR to add the rotate icon.

### 🐞 Fixed
- Fixed an issue where the `DraggableVideo` component would ignore onClick events.
- Community shout out:
- [srelbo](https://github.com/canva-sdks/canva-apps-sdk-starter-kit/pull/4) submitted a fix to an issue with the video badge where text would not be vertically centered.

### 🔧 Changed
- Updated draggable example apps to include click to insert functionality by default.

## 2023-07-27

### 💥 Breaking changes
Expand Down
11 changes: 11 additions & 0 deletions assets/icons/reload.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions assets/icons/rotate.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions components/draggable_audio/draggable_audio.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
.draggableAudioContainer {
width: 100%;
padding: 8px;
border: 0;
border-radius: 4px;
cursor: pointer;
background: transparent;
}

.draggableAudioInner {
Expand All @@ -22,6 +24,7 @@
width: 100%;
display: flex;
flex-direction: column;
align-items: baseline;
}

.draggableAudioText {
Expand Down
13 changes: 6 additions & 7 deletions components/draggable_audio/draggable_audio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as React from "react";
import { AudioCover } from "../audio_player";
import styles from "./draggable_audio.css";

type ElementProps = React.HTMLAttributes<HTMLDivElement> &
type ElementProps = React.HTMLAttributes<HTMLButtonElement> &
Omit<UserSuppliedAudioDragData, "type"> & {
/*
* Url of the audio to play in the app when the user clicks the play button.
Expand All @@ -27,7 +27,7 @@ const getDragDataAndProps = (
props: ElementProps
): {
data: UserSuppliedAudioDragData;
props: React.HTMLAttributes<HTMLDivElement> & {
props: React.HTMLAttributes<HTMLButtonElement> & {
previewUrl: string;
};
} => {
Expand All @@ -52,14 +52,14 @@ const getDragDataAndProps = (
export const DraggableAudio = (props: ElementProps) => {
const [isHovering, setIsHovering] = React.useState(false);
const [isDragging, setIsDragging] = React.useState(false);
const [node, setNode] = React.useState<HTMLDivElement | null>();
const [node, setNode] = React.useState<HTMLButtonElement | null>();
const {
data: dragData,
props: { previewUrl, ...imgProps },
} = getDragDataAndProps(props);
const opacity = isDragging ? 0 : props.style?.opacity || 1;

const makeDraggable = (node: HTMLDivElement) => {
const makeDraggable = (node: HTMLButtonElement) => {
if (!node) {
return;
}
Expand Down Expand Up @@ -94,9 +94,8 @@ export const DraggableAudio = (props: ElementProps) => {
});

return (
<div
<button
{...imgProps}
role="button"
onMouseEnter={() => setIsHovering(true)}
onMouseLeave={() => setIsHovering(false)}
ref={setNode}
Expand All @@ -120,6 +119,6 @@ export const DraggableAudio = (props: ElementProps) => {
</div>
</div>
</div>
</div>
</button>
);
};
70 changes: 59 additions & 11 deletions components/draggable_image/draggable_image.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,53 @@
import * as React from "react";
import clsx from "clsx";
import type {
UserSuppliedExternalImageDragData,
UserSuppliedDataUrlImageDragData,
UserSuppliedImageDragData,
} from "@canva/design";
import { ui } from "@canva/design";
import styles from "./styles.css";

type ClickableImageProps = Omit<
React.ImgHTMLAttributes<HTMLImageElement>,
"onClick"
> & {
/**
* @deprecated use the previewSize, previewSrc, fullSize, fullSizeSrc props instead
*/
dragData?: Partial<UserSuppliedDataUrlImageDragData>;
} & {
/**
* ClassNames for the button containing the image.
* When an onClick is supplied, the image will be wrapped with a button.
* Use this prop to adjust the styles of that button.
*/
containerClassName?: string;
/**
* Handler for when a user clicks the image.
* Ideally should be configured to insert the image via the design api.
*/
onClick: (evt: React.MouseEvent<HTMLElement>) => void;
};

type StaticImageProps = Omit<
React.ImgHTMLAttributes<HTMLImageElement>,
"onClick"
> & {
/**
* @deprecated use the previewSize, previewSrc, fullSize, fullSizeSrc props instead
*/
dragData?: Partial<UserSuppliedDataUrlImageDragData>;
} & { onClick?: never; containerClassName?: never };

type ImageProps = ClickableImageProps | StaticImageProps;

type DraggableExternalUrlProps = Partial<UserSuppliedExternalImageDragData> &
Pick<UserSuppliedExternalImageDragData, "resolveImageRef"> &
React.ImgHTMLAttributes<HTMLImageElement>;
ImageProps;

type DraggableDataUrlProps = Partial<UserSuppliedDataUrlImageDragData> &
React.ImgHTMLAttributes<HTMLImageElement> & {
/**
* @deprecated use the previewSize, previewSrc, fullSize, fullSizeSrc props instead
*/
dragData?: Partial<UserSuppliedDataUrlImageDragData>;
};
ImageProps;

export type DraggableImageProps =
| DraggableDataUrlProps
Expand All @@ -32,7 +63,7 @@ const getDragDataAndProps = (
props: DraggableImageProps
): {
data: Partial<UserSuppliedImageDragData>;
props: React.ImgHTMLAttributes<HTMLImageElement>;
props: ImageProps;
} => {
if (isExternalProps(props)) {
const { fullSize, previewSize, resolveImageRef, previewSrc, ...imgProps } =
Expand Down Expand Up @@ -85,7 +116,10 @@ const getDragDataAndProps = (
export const DraggableImage = (props: DraggableImageProps) => {
const [isDragging, setIsDragging] = React.useState(false);
const [canDrag, setCanDrag] = React.useState(false);
const { data: dragData, props: imgProps } = getDragDataAndProps(props);
const {
data: dragData,
props: { onClick, containerClassName, ...imgProps },
} = getDragDataAndProps(props);
const opacity = isDragging ? 0 : props.style?.opacity || 1;

const makeDraggable = (
Expand All @@ -110,12 +144,26 @@ export const DraggableImage = (props: DraggableImageProps) => {
}
};

return (
const Content = (
<img
{...imgProps}
onLoad={makeDraggable}
draggable={canDrag}
style={{ cursor: "pointer", ...props.style, opacity }}
style={{ ...imgProps.style }}
/>
);

if (onClick) {
return (
<button
className={clsx(styles.draggableButton, containerClassName)}
style={{ opacity }}
onClick={onClick}
>
{Content}
</button>
);
}

return Content;
};
7 changes: 7 additions & 0 deletions components/draggable_image/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.draggableButton {
padding: 0;
border: 0;
background: transparent;
width: fit-content;
cursor: pointer;
}
57 changes: 45 additions & 12 deletions components/draggable_text/draggable_text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,32 @@ import type { DraggableElementData } from "@canva/design";
import * as React from "react";
import styles from "styles/components.css";
import { ui } from "@canva/design";
import textStyles from "./styles.css";
import clsx from "clsx";

type DragProps = Omit<
DraggableElementData["dragData"] & { type: "TEXT" },
"type" | "children"
>;

export type DraggableTextProps = React.HTMLAttributes<HTMLElement> & DragProps;
export type DraggableTextProps = React.HTMLAttributes<HTMLElement> &
DragProps &
(
| {
/**
* ClassNames for the button containing the text.
* When an onClick is supplied, the text will be wrapped with a button.
* Use this prop to adjust the styles of that button.
*/
containerClassName?: string;
/**
* Handler for when a user clicks the text.
* Ideally should be configured to insert the image via the design api.
*/
onClick: (evt: React.MouseEvent<HTMLElement>) => void;
}
| { containerClassName?: never; onClick?: never }
);

export const DraggableText = (props: DraggableTextProps) => {
const [node, setNode] = React.useState<HTMLElement | null>();
Expand All @@ -20,6 +39,8 @@ export const DraggableText = (props: DraggableTextProps) => {
fontWeight,
fontStyle,
children,
onClick,
containerClassName,
...nodeProps
} = props;

Expand Down Expand Up @@ -59,16 +80,28 @@ export const DraggableText = (props: DraggableTextProps) => {
opacity,
};

return (
<div style={style}>
<p
{...nodeProps}
draggable={canDrag}
className={styles.draggable}
ref={setNode}
>
{children}
</p>
</div>
const Content = (
<p
{...nodeProps}
draggable={canDrag}
className={styles.draggable}
ref={setNode}
>
{children}
</p>
);

if (onClick) {
return (
<button
style={style}
onClick={onClick}
className={clsx(textStyles.draggableButton, containerClassName)}
>
{Content}
</button>
);
}

return <div style={style}>{Content}</div>;
};
6 changes: 6 additions & 0 deletions components/draggable_text/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.draggableButton {
padding: 0;
border: 0;
background: transparent;
width: fit-content;
}
Loading

0 comments on commit a19fc54

Please sign in to comment.