Components
One of the main features of PhotoEditorSDK is the capability to customize the colors and fonts and different components of the UI.
Please refer to the nomenclature for a better understanding of the naming convention.
The following components can be customised and replaced in the configuration:
- AdvancedUICategoryCard
- AdvancedUIItemCard
- AdvancedUIToolbarItem
- ColorItem
- Checkbox
- Loader
- Buttons
- MainCanvasActionUndo
- MainCanvasActionRedo
- MainCanvasActionExport
- MainCanvasActionClose
- CanvasActionEdit
- CanvasActionBringToFront
- CanvasActionDuplicate
- CanvasActionDelete
- CanvasActionInvert
- CanvasActionFlip
- TransformActionFlipHorizontal
- TransformActionFlipVertical
- TransformActionRotateClockwise
- TransformActionRotateAntiClockwise
- TextAlignment
- ToolControlBarPrimaryButton
- ToolControlBarSecondaryButton
Styling
The custom components are also part of the styled-components
theme context and can use the values which are defined in the theme.
import { Buttons } from "photoeditorsdk";
import styled from "styled-components";
const ExportButton = styled(Buttons.ContainedPrimaryButton)`
color: ${({ theme }) => theme.button.containedPrimaryForeground}
background: ${({ theme }) => theme.button.containedPrimaryBackground}
`;
const editor = await PhotoEditorSDKUI.init({
custom: {
components: {
buttons: {
mainCanvasActionExport: ExportButton,
},
},
},
});
It is also possible to style the default components through the className
or style
props.
Replacing Components
The components in the the configuration can be replaced by any React component and will receive the same props as the default components.
The photoeditorsdk
package exports all default components which makes it quite easy to modify the behaviour of certain parts of the app.
e.g.:
import { AdvancedUIItemCard } from "photoeditorsdk";
const ItemCard = ({ onClick, tool, ...props }) => {
const handleClick = () => {
if (tool === "sticker") {
// add your custom click handeling here
}
onClick();
};
return <AdvancedUIItemCard {...props} onClick={handleClick} tool={tool} />;
};
const editor = await PhotoEditorSDKUI.init({
custom: {
components: {
advancedUIItemCard: ItemCard,
},
},
});
The following components are available in the photoeditorsdk
package:
AdvancedUICategoryCard,
AdvancedUIItemCard,
AdvancedUICardLabel,
AdvancedUIToolbarItem,
Loader,
CanvasBarTextSecondaryButton,
ContainedPrimaryButton,
OutlinedPrimaryButton,
OutlinedSecondaryButton,
SpriteActionButton,
IconButton,
ColorItem,
ColorItemActiveOverlay,
ColorItemBase,
ColorItemBackground,
ColorItemTiledBackground,
Checkbox,
CheckboxCheckMark,
CheckboxBase,
CheckboxInput,
Label,
Category Card in AdvancedUI
This will replace the category cards in the toolControlBar
.
The React component will receive the following props:
{
tool: Tool
label: string
image?: string
isActive?: boolean
type: CardType
isDisabled?: boolean
onClick: (e?: React.MouseEvent<HTMLButtonElement>) => void
className?: string
style?: { [key: string]: string }
children?: React.ReactNode
}
import React from "react";
import styled from "styled-components";
import { CustomCardProps, AdvancedUICategoryCard } from "photoeditorsdk";
const Card = styled(AdvancedUICategoryCard)`
height: 50px;
width: 180px;
border-radius: 16px;
margin-bottom: 16px;
`;
const Label = styled.div<{ isActive: boolean | void }>`
width: 180px;
text-align: center;
font-size: 12px;
margin-bottom: 10px;
color: ${(props) =>
props.isActive ? props.theme.primary : props.theme.card.labelForeground};
`;
const CategoryCard: React.FC<CustomCardProps> = ({
label,
isActive,
children,
...props
}) => (
<div>
<Label isActive={isActive}>{label}</Label>
<Card {...props} isActive={isActive} />
</div>
);
const editor = await PhotoEditorSDKUI.init({
custom: {
components: {
advancedUICategoryCard: CategoryCard,
},
},
});
Item Card in AdvancedUI
This will replace the item cards in the toolControlBar
.
The React component will receive the following props:
{
tool: Tool
label?: string
image?: string
isActive?: boolean
type: CardType
isDisabled?: boolean
onClick: (e?: React.MouseEvent<HTMLButtonElement>) => void
className?: string
style?: { [key: string]: string }
children?: React.ReactNode
}
import React from "react";
import styled from "styled-components";
import { CustomCardProps, AdvancedUIItemCard, Tool } from "photoeditorsdk";
const Container = styled.div`
margin-bottom: 10px;
&:nth-child(2n + 1) {
margin-right: ${(props) =>
props.theme.measurements.advancedSpacer}px !important;
}
`;
const CardStyles = styled(AdvancedUIItemCard).attrs((props) => {
const style: any = {};
if (props.image) {
style.backgroundImage = `url(${props.image})`;
}
if (props.isActive) {
style.border = `2px solid ${props.theme.primary}`;
}
return { style };
})`
height: 87px;
width: 87px;
padding: 5px;
border-radius: 50%;
margin-right: 0px !important;
background-position: center center;
background-repeat: no-repeat;
background-clip: content-box;
`;
const Label = styled.div`
max-width: 80px;
text-align: center;
font-size: 12px;
margin-bottom: 10px;
`;
const ItemCard: React.FC<CustomCardProps> = ({
label,
children,
tool,
style,
...props
}) => {
if (tool === Tool.FRAME && style) {
style.backgroundSize = "55%";
}
return (
<Container>
<CardStyles {...props} tool={tool} style={style} />
<Label>{label}</Label>
</Container>
);
};
const editor = await PhotoEditorSDKUI.init({
custom: {
components: {
advancedUIItemCard: ItemCard,
},
},
});
Toolbar Item in AdvancedUI
This will replace the icons in the toolbar
. Available only in AdvancedUI
.
The React component will receive the following props:
{
tool: string
label: string
icon: React.ReactNode
isActive: boolean
isReverse: boolean
style?: { [key: string]: string }
onClick: (e?: React.MouseEvent<HTMLButtonElement>) => void
}
You can choose to use the default icons or replace them with your own icons.
import React from "react";
import styled, { css } from "styled-components";
import { CustomToolbarItemProps, AdvancedUIToolbarItem } from "photoeditorsdk";
const Item = styled(AdvancedUIToolbarItem)`
height: 48px;
width: 48px;
margin: 4px;
* button {
border-radius: 50%;
background: transparent;
color: ${(props) => props.theme.foreground};
}
${(props) => {
if (props.isActive) {
return css`
* button {
color: white !important;
background: ${props.theme.primary};
}
`;
}
return "";
}}
`;
const Container = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
`;
const Label = styled.div`
max-width: 48px;
text-align: center;
font-size: 12px;
margin-bottom: 10px;
margin: 4px;
`;
const ToolbarItem: React.FC<CustomToolbarItemProps> = ({
label,
isActive,
...props
}) => {
return (
<Container>
<Item label={label} isActive={isActive} {...props} />
<Label>{label}</Label>
</Container>
);
};
const editor = await PhotoEditorSDKUI.init({
custom: {
measurements: {
advancedUIToolbar: {
width: 80,
},
},
components: {
advancedUIToolbarItem: ToolbarItem,
},
},
});
ColorItem
This will replace the items which are used to select a color in the Text, Text Design, Sticker, Frame and Brush tool. Available in both AdvancedUI
and BasicUI
The PhotoEditorSDK exports the default ColorItem
and also all components which are used to build the ColorItem
.
The React component will receive the following props:
{
color: string
label: string
isActive: boolean
isDisabled: boolean
tiledBackgroundUrl: string
onClick: (e: React.MouseEvent<HTMLButtonElement>) => void
className?: string
style?: { [key: string]: string }
children?: React.ReactNode
}
Modifying the default ColorItem
import React from "react";
import styled from "styled-components";
import { ColorItem, CustomColorItemProps } from "photoeditorsdk";
const CustomColorItem = styled(ColorItem)<CustomColorItemProps>`
margin: 8px;
`;
const editor = await PhotoEditorSDKUI.init({
custom: {
components: {
colorItem: CustomColorItem,
},
},
});
Building your own ColorItem
This example will use the following child components of the ColorItem
:
ColorItemBase
: This is a container which will handle theonClick
behaviourColorItemBackground
: This component will display the current colorColorItemTiledBackground
: This component will display the tiled background for transparent colorsColorItemActiveOverlay
: This component will display the border around theColorItem
import React from "react";
import styled from "styled-components";
import {
CustomColorItemProps,
CustomConfiguration,
ColorItemActiveOverlay,
ColorItemBase,
ColorItemBackground,
ColorItemTiledBackground,
} from "photoeditorsdk";
const ActiveOverlay = styled(ColorItemActiveOverlay)`
box-sizing: content-box;
padding: 2px;
left: -4px;
top: -4px;
`;
export const CustomColorItem: React.FC<CustomColorItemProps> = ({
label,
color,
isActive,
isDisabled,
tiledBackgroundUrl,
onClick,
}) => {
return (
<ColorItemBase onClick={onClick} disabled={isDisabled} aria-label={label}>
<ColorItemBackground color={color} />
<ColorItemTiledBackground url={tiledBackgroundUrl} />
<ActiveOverlay isActive={isActive} />
</ColorItemBase>
);
};
const editor = await PhotoEditorSDKUI.init({
custom: {
measurements: {
colorItem: {
size: 28,
},
},
themes: {
dark: {
colorItem: {
borderRadius: "50%",
margin: "6px",
},
},
},
components: {
colorItem: CustomColorItem,
},
},
});
Checkbox
This will replace all checkboxes which are used in the PhotoeditorSDK. Available in both AdvancedUI
and BasicUI
The PhotoEditorSDK exports the default Checkbox
and also all components which are used to build the Checkbox
.
The React component will receive the following props:
{
label: string
value: boolean
isDisabled?: boolean
checkMarkPosition?: 'left' | 'right'
onClick: (e?: React.SyntheticEvent) => void
className?: string
style?: { [key: string]: string }
children?: React.ReactNode
}
Modifying the default Checkbox
import React from "react";
import styled from "styled-components";
import { Checkbox, CustomCheckboxProps } from "photoeditorsdk";
const CustomCheckbox = styled(Checkbox)<CustomCheckboxProps>`
margin: 8px;
`;
const editor = await PhotoEditorSDKUI.init({
custom: {
components: {
checkbox: CustomCheckbox,
},
},
});
Building your own Checkbox
This example will use the following child components of the ColorItem
:
CheckboxBase
: This is a container around the child componentsCheckboxCheckMark
: This component will display the checkmarkCheckboxInput
: This component is used for accessibilityLabel
: This component will display the label next to the checkmark and is also clickable
import React from "react";
import styled from "styled-components";
import {
CustomCheckbox,
CheckboxCheckMark,
CheckboxBase,
CheckboxInput,
Label,
} from "photoeditorsdk";
const Base = styled(CheckboxBase)`
justify-content: unset;
`;
const CheckMark = styled(CheckboxCheckMark)`
margin-right: 8px;
`;
const Checkbox: CustomCheckbox = ({
label,
value,
isDisabled,
onClick,
...props
}) => {
const id = `photoeditorsdk-${label.replace(" ", "-")}`;
const onChange = () => {
onClick();
};
return (
<Base {...props}>
<CheckMark isDisabled={isDisabled} isChecked={value} onClick={onClick} />
<Label isDisabled={isDisabled} label={label} htmlFor={id} />
<CheckboxInput
id={id}
disabled={isDisabled}
checked={value}
onChange={onChange}
/>
</Base>
);
};
const editor = await PhotoEditorSDKUI.init({
custom: {
components: {
checkbox: Checkbox,
},
},
});
Loader
This will replace the initial loading screen. Available in both AdvancedUI
and BasicUI
.
The React component will receive the following props:
{
show: boolean
heading: string
body: string
position?: { x: number; y: number }
className?: string
}
import React from "react";
import styled from "styled-components";
import { CustomLoaderProps } from "photoeditorsdk";
const Backdrop = styled.div<{ show: boolean }>`
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.6);
position: absolute;
top: 0;
left: 0;
z-index: 100;
opacity: ${({ show }) => (show ? 1 : 0)};
`;
const LoaderStyles = styled.div`
background: white;
position: absolute;
z-index: 5;
top: 50%;
left: 50%;
border-radius: 4px;
transform: translate(-50%, -50%);
color: ${(props) => props.theme.primary};
padding: 20px;
`;
const Loader: React.FC<CustomLoaderProps> = ({ show, body }) => {
return (
<Backdrop show={show}>
<LoaderStyles>{body}</LoaderStyles>
</Backdrop>
);
};
const editor = await PhotoEditorSDKUI.init({
custom: {
components: {
loader: Loader,
},
},
});
custom: {
components: {
advancedUICategoryCard: AdvancedUICategoryCard,
advancedUIItemCard: AdvancedUIItemCard,
advancedUIToolbarItem: AdvancedUIToolbarItem,
loader: Loader,
colorItem: ColorItem,
buttons: {
mainCanvasActionUndo: CanvasBarTextSecondaryButton,
mainCanvasActionRedo: CanvasBarTextSecondaryButton,
mainCanvasActionExport: ContainedPrimaryButton,
mainCanvasActionClose: OutlinedSecondaryButton,
canvasActionEdit: SpriteActionButton,
canvasActionBringToFront: SpriteActionButton,
canvasActionDuplicate: SpriteActionButton,
canvasActionDelete: SpriteActionButton,
canvasActionInvert: SpriteActionButton,
canvasActionFlip: SpriteActionButton,
transformActionFlipHorizontal: IconButton,
transformActionFlipVertical: IconButton,
transformActionRotateClockwise: IconButton,
transformActionRotateAntiClockwise: IconButton,
textAlignment: IconButton,
toolControlBarPrimaryButton: OutlinedPrimaryButton,
toolControlBarSecondaryButton: OutlinedSecondaryButton,
},
}
}