Skip to main content
Language:

Customize The Asset Library

In this example, we will show you how to customize the asset library in CreativeEditor SDK.

Explore a full code sample of the integration on CodeSandbox or view the code on GitHub.

The asset library is used to find assets to insert them into a scene or replace a currently selected asset. By default, we have already added a configuration of entries shown in the dock panel for images, text, stickers, shapes, and more. You can add and remove every entry or change the appearance of any entry.

First, every entry has a couple of configuration options to determine what and how assets will be displayed.

  • id: string A unique identifier for the library entry

  • sourceIds: string[] An array of source ids that will be shown in this entry. You can use custom asset source ids or asset sources provided by default.

    • ly.img.image includes all registered images
    • ly.img.sticker includes all registered stickers
    • ly.img.text includes text configurations
    • ly.img.vectorpath includes shapes
  • previewLength: number determines how many asset results will be shown in an overview or section overview.

  • previewBackgroundType: 'cover' | 'contain' determines if the thumbUri is set as a background that will be contained or covered by the card in an overview or section overview.

  • gridBackgroundType: 'cover' | 'contain' determines if the thumbUri is set as a background that will be contained or covered by the card in the grid view

  • gridColumns: number number of columns in the grid view

  • gridItemHeight: 'auto' | 'square' determines the height of an item in the grid view.

    • auto automatically determines height yielding a masonry-like grid view
    • square every card will have the same square size
  • cardLabel: (assetResult: AssetResult) => string | undefined overwrite the label of a card for a specific asset result

  • cardStyle: (assetResult: AssetResult) => Record<string, string | undefined> Add custom styles to a card for a specific asset result

  • cardLabelStyle: ( assetResult: AssetResult) => Record<string, string | undefined> add custom styles to a label for a specific asset result

  • icon: string | (({ theme, iconSize }: { theme: string; iconSize: string }) => string) uses a URL as string to set a custom icon for the library in the dock. If a function is passed, the current theme and the set icon size can be used within the function to return a corresponding icon URL. All image file types usable via a HTML <img /> are supported here.

  • title: string | (({ group, sourceId }, TFunction) => string | undefined) use a custom translation for this entry. Will be used in the dock as well as in the overviews for a group or a source. If undefined is returned by the function it will be handled like there wasn't a title function set at all. The second argument is the translation function that can be used to lookup translations with i18n keys.

Adding, changing, or removing entries is done in ui.libraries.insert.entries (for insertion) or ui.libraries.replace.entries (for replacement). It can be either an array of entries as defined above in which case all default entries will be replaced with the given entries. If a function is provided it will receive the default entries as an argument and expects an array of entries as a return value from this function. This allows adding, removing, and changing the default entries.

The basics of customizing the entries for replacement are the same as for insertion. The main difference is that these entries might vary depending on what block is currently selected and that the returned entries will determine if a replace action is shown on a selected block.

Most of the time it makes sense to provide a custom function to return different entries based on the type or fill of a block. If no replacement should be available for the current block, an empty array has to be returned. The UI will not show a replace button in that case.

As a second argument, you will get the current context in the editor, mainly what blocks are selected, their block type as well as fills. This makes it more convenient to quickly decide what to return, but of course, you can also use the API for further checks as well.

If you do not use a custom title function for an entry, you need a translation provided with the following keys in the i18n configuration:

  • libraries.<entry-id>.label The label used in the dock panel
  • libraries.<entry-id><group-id>.label The label for groups for a given entry.
  • libraries.<entry-id>.<source-id>.label The label for a source in the source overview of a given entry
  • libraries.<entry-id>.<source-id>.<group-id>.label The label for a given group in the group overview for a given entry.
  • libraries.<source-id>.label The label used for a source in all entries
  • libraries.<source-id><group-id>.label The label for groups for source in all entries.
File:
import 'https://cdn.img.ly/packages/imgly/cesdk-js/1.9.2/cesdk.umd.js';
let config = {
baseURL: 'https://cdn.img.ly/packages/imgly/cesdk-js/1.9.2/assets',
i18n: {
en: {
'libraries.empty-custom-asset-source.label': 'Empty'
}
},
assetSources: {
emptySource: {
findAssets: () => {
return Promise.resolve({
assets: [],
total: 0,
currentPage: 1,
nextPage: undefined
});
}
}
},
ui: {
elements: {
libraries: {
replace: {
entries: (defaultEntries, context) => {
if (context.selectedBlocks.length !== 1) {
return [];
}
const [selectedBlock] = context.selectedBlocks;
if (selectedBlock.blockType === 'ly.img.image') {
return [
...defaultEntries,
{
id: 'empty-custom-asset-source-for-replace',
sourceIds: ['emptySource'],
previewLength: 3,
gridColumns: 3,
gridItemHeight: 'square'
}
];
}
return [];
}
},
insert: {
entries: (defaultEntries) => {
const imageEntry = defaultEntries.find((entry) => {
return entry.id === 'ly.img.image';
});
if (imageEntry) {
imageEntry.gridColumns = 4;
}
return [
...defaultEntries,
{
id: 'empty-custom-asset-source',
sourceIds: ['emptySource'],
previewLength: 3,
gridColumns: 3,
gridItemHeight: 'square',
previewBackgroundType: 'contain',
gridBackgroundType: 'contain',
icon: ({ theme, iconSize }) => {
if (theme === 'dark') {
if (iconSize === 'normal') {
return 'https://img.ly/static/cesdk/guides/icon-normal-dark.svg';
} else {
return 'https://img.ly/static/cesdk/guides/icon-large-dark.svg';
}
}
if (iconSize === 'normal') {
return 'https://img.ly/static/cesdk/guides/icon-normal-light.svg';
} else {
return 'https://img.ly/static/cesdk/guides/icon-large-light.svg';
}
}
},
{
id: 'custom-images',
sourceIds: ['ly.img.image'],
previewLength: 5,
gridColumns: 5,
icon: 'https://img.ly/static/cesdk/guides/icon-normal-dark.svg'
}
];
}
}
}
}
}
};
CreativeEditorSDK.init('#cesdk_container', config).then((instance) => {
/** do something with the instance of CreativeEditor SDK **/
});