0.0.6 • Published 6 months ago

@peteai/presentation-editor v0.0.6

Weekly downloads
-
License
-
Repository
-
Last release
6 months ago

@peteai/presentation-editor

Introduction

This project is a Svelte component library which lets you create a customizable presentation editors.

Install

npm install @peteai/presentation-editor

Types

type Image = {
	id: string;
	src: string;
	width: number;
	height: number;
};

interface BaseLayer {
	id: string;
	x: number;
	y: number;
	width: number;
	height: number;
	rotate: number | null;
	opacity: number | null;
	sortOrder: number;
}

interface HtmlLayer extends BaseLayer {
	type: 'html';
	scale: number | null;
	html: JSONContent;
}

type LayerBorder = {
	borderStyle: 'solid' | 'dashed' | 'dotted' | null;
	borderWidth: number | null;
	borderColor: string | null;
};

interface ImageLayer extends BaseLayer, LayerBorder {
	type: 'image';
	scale: number | null;
	image: Image;
	offsetX: number | null;
	offsetY: number | null;
	cornerRadius: number | null;
	flipX: boolean;
	flipY: boolean;
}

type Layer = HtmlLayer | ImageLayer;

type Slide = {
	id: string;
	backgroundColor: string | null;
	layers: Layer[];
	sortOrder: number;
};

Html editor

PresentationEditor is using Tiptap editor for HtmlLayer content editing.

JSONContent type provided by @tiptap/core is used for html content of HtmlLayer to store data in json format.

Settings

The PresentationEditor component accepts a bunch of settings. Here is a typescript definition of all available settings:

interface BaseOptions {
	images?: Image[];
	width?: number;
	height?: number;
	generateId?: () => string;
	onImageUpload?: (file: File) => Promise<Image>;
	onLayerAdd?: (slideId: string, layer: Layer) => Promise<Layer>;
	onLayerUpdate?: (slideId: string, layerId: string, layerType: string, changes: object) => void;
	onLayerRemove?: (slideId: string, layerId: string, layerType: string) => Promise<void>;
}

interface MultipleModeOption extends BaseOptions {
	mode?: 'multiple';
	slides?: Slide[];
	onSlideAdd?: (slide: Slide) => Promise<Slide>;
	onSlideUpdate?: (slideId: string, changes: object) => void;
	onSlideRemove?: (slideId: string) => Promise<void>;
}

interface SingleModeOption extends BaseOptions {
	mode: 'single';
	slide?: Slide;
}

export type PresentationEditorOptions = MultipleModeOption | SingleModeOption;

Getting Started

import { createEditor } from '@peteai/presentation-editor';

// images list
const images: Image[];
// slides list
const slides: Slide[];

const editor = new createEditor({
	target: document.querySelector('.target'),
	props: {
		// function for new slides and layers ids generation
		generateId: () => crypto.randomUUID(),
		images,
		slides,
		onImageUpload: async (file) => {
			// called when user uploads image
			// callback to store file and return Image
			// which will be added to the images list
			// new ImageLayer gonna be created if image file was dropped on slide
			// ...
			return image;
		},
		onSlideAdd: async (slide) => {
			// called when new slide is added
			// expect Slide to be returned to overwrite newly created slide
		},
		onSlideUpdate: async (slideId, values) => {
			// called when slide is updated
		},
		onSlideRemove: async (slideId) => {
			// called when slide is removed
		},
		onLayerAdd: async (slideId, layer) => {
			// called when new layer is added
			// expect Layer to be returned to overwrite newly created layer
		},
		onLayerUpdate: async (slideId, layerId, layerType, values) => {
			// called when layer is updated
		},
		onLayerRemove: async (slideId, layerId, layerType) => {
			// called when layer is removed
		},
	},
});

Single Slide Mode

import { createEditor } from '@peteai/presentation-editor';

// images list
const images: Image[];
// slides list
const slide: Slide;

const editor = new createEditor({
	target: document.querySelector('.target'),
	props: {
		mode: 'single',
		// function for new slides and layers ids generation
		generateId: () => crypto.randomUUID(),
		images,
		slide,
		onImageUpload: async (file) => {
			// called when user uploads image
			// callback to store file and return Image
			// which will be added to the images list
			// new ImageLayer gonna be created if image file was dropped on slide
			// ...
			return image;
		},
		onLayerAdd: async (slideId, layer) => {
			// called when new layer is added
			// expect Layer to be returned to overwrite newly created layer
		},
		onLayerUpdate: async (slideId, layerId, layerType, values) => {
			// called when layer is updated
		},
		onLayerRemove: async (slideId, layerId, layerType) => {
			// called when layer is removed
		},
	},
});