Skip to content

Commit

Permalink
Merge pull request #269 from editor-js/feature/enable-tune-selection
Browse files Browse the repository at this point in the history
Support for selecting and enabling specific tunes in ImageTool
  • Loading branch information
idebenone authored Oct 29, 2024
2 parents 5d1c57c + d5d98f3 commit b97f7d1
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 15 deletions.
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Image Block for the [Editor.js](https://editorjs.io).
- Pasting copied content from the web
- Pasting images by drag-n-drop
- Pasting files and screenshots from Clipboard
- Allows adding a border, and a background
- Allows adding a border, a background and a caption
- Allows stretching an image to the container's full-width

**Notes**
Expand Down Expand Up @@ -83,6 +83,7 @@ Image Tool supports these configuration parameters:
| buttonContent | `string` | Allows to override HTML content of «Select file» button |
| uploader | `{{uploadByFile: function, uploadByUrl: function}}` | Optional custom uploading methods. See details below. |
| actions | `array` | Array with custom actions to show in the tool's settings menu. See details below. |
| features | `object` | Allows you to enable/disable additional features such as border, background tunes and caption. See details below. |

Note that if you don't implement your custom uploader methods, the `endpoints` param is required.

Expand All @@ -96,6 +97,8 @@ Note that if you don't implement your custom uploader methods, the `endpoints` p

3. Add background

4. Add caption

Add extra setting-buttons by adding them to the `actions`-array in the configuration:
```js
actions: [
Expand All @@ -113,6 +116,17 @@ actions: [

**_NOTE:_** return value of `action` callback for settings whether action button should be toggled or not is *deprecated*. Consider using `toggle` option instead.

You can disable features such as border, background tunes and caption by defining `features` in the configuration:
```js
features: {
border: false,
caption: 'optional',
stretch: false
}
```

**_NOTE:_** set caption to `optional` in order to configure caption as a tune.

## Output data

This Tool returns `data` with following format
Expand All @@ -136,7 +150,7 @@ This Tool returns `data` with following format
"caption" : "Roadster // tesla.com",
"withBorder" : false,
"withBackground" : false,
"stretched" : true
"stretched" : true,
}
}
```
Expand Down
35 changes: 35 additions & 0 deletions dev/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Image Plugin Test | EditorJS</title>
</head>
<body>
<div id="editorjs"></div>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest/dist/editor.js"></script>
<script src="../dist/image.umd.js"></script>
<script>
const editor = new EditorJS({
holder: "editorjs",
tools: {
code: {
class: ImageTool,
config: {
endpoints: {
byFile: "http://localhost:8008/uploadFile",
byUrl: "http://localhost:8008/fetchUrl",
},
features: {
// caption: false,
border: false,
background: false,
stretch: false,
},
},
},
},
});
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@editorjs/image",
"version": "2.9.3",
"version": "2.10.0",
"keywords": [
"codex editor",
"image",
Expand Down
12 changes: 10 additions & 2 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
}

&__caption {
display: none;

&[contentEditable="true"][data-placeholder]::before {
position: absolute !important;
content: attr(data-placeholder);
Expand Down Expand Up @@ -86,7 +88,7 @@
margin: 0 6px 0 0;
}
}

&--filled {
.cdx-button {
display: none;
Expand Down Expand Up @@ -147,13 +149,19 @@
}
}

&--caption {
^&__caption {
display: block;
}
}
}

@keyframes image-preloader-spin {
0% {
transform: rotate(0deg);
}

100% {
transform: rotate(360deg);
}
}
}
49 changes: 39 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
* 1) index.ts — main Tool's interface, public API and methods for working with data
* 2) uploader.ts — module that has methods for sending files via AJAX: from device, by URL or File pasting
* 3) ui.ts — module for UI manipulations: render, showing preloader, etc
* 4) tunes.js — working with Block Tunes: render buttons, handle clicks
*
* For debug purposes there is a testing server
* that can save uploaded files and return a Response {@link UploadResponseFormat}
Expand All @@ -36,8 +35,8 @@ import './index.css';
import Ui from './ui';
import Uploader from './uploader';

import { IconAddBorder, IconStretch, IconAddBackground, IconPicture } from '@codexteam/icons';
import type { ActionConfig, UploadResponseFormat, ImageToolData, ImageConfig, HTMLPasteEventDetailExtended, ImageSetterParam } from './types/types';
import { IconAddBorder, IconStretch, IconAddBackground, IconPicture, IconText } from '@codexteam/icons';
import type { ActionConfig, UploadResponseFormat, ImageToolData, ImageConfig, HTMLPasteEventDetailExtended, ImageSetterParam, FeaturesConfig } from './types/types';

type ImageToolConstructorOptions = BlockToolConstructorOptions<ImageToolData, ImageConfig>;

Expand All @@ -50,11 +49,6 @@ export default class ImageTool implements BlockTool {
*/
private api: API;

/**
* Flag indicating read-only mode
*/
private readOnly: boolean;

/**
* Current Block API instance
*/
Expand Down Expand Up @@ -90,7 +84,6 @@ export default class ImageTool implements BlockTool {
*/
constructor({ data, config, api, readOnly, block }: ImageToolConstructorOptions) {
this.api = api;
this.readOnly = readOnly;
this.block = block;

/**
Expand All @@ -106,6 +99,7 @@ export default class ImageTool implements BlockTool {
buttonContent: config.buttonContent,
uploader: config.uploader,
actions: config.actions,
features: config.features || {},
};

/**
Expand Down Expand Up @@ -197,6 +191,10 @@ export default class ImageTool implements BlockTool {
* Renders Block content
*/
public render(): HTMLDivElement {
if (this.config.features?.caption === true || this.config.features?.caption === undefined || (this.config.features?.caption === 'optional' && this.data.caption)) {
this.ui.applyTune('caption', true);
}

return this.ui.render(this.data) as HTMLDivElement;
}

Expand Down Expand Up @@ -228,8 +226,33 @@ export default class ImageTool implements BlockTool {
// Merge default tunes with the ones that might be added by user
// @see https://github.com/editor-js/image/pull/49
const tunes = ImageTool.tunes.concat(this.config.actions || []);
const featureTuneMap: Record<string, string> = {
border: 'withBorder',
background: 'withBackground',
stretch: 'stretched',
caption: 'caption',
};

if (this.config.features?.caption === 'optional') {
tunes.push({
name: 'caption',
icon: IconText,
title: 'With caption',
toggle: true,
});
}

const availableTunes = tunes.filter((tune) => {
const featureKey = Object.keys(featureTuneMap).find(key => featureTuneMap[key] === tune.name);

if (featureKey === 'caption') {
return this.config.features?.caption !== false;
}

return tunes.map(tune => ({
return featureKey == null || this.config.features?.[featureKey as keyof FeaturesConfig] !== false;
});

return availableTunes.map(tune => ({
icon: tune.icon,
label: this.api.i18n.t(tune.title),
name: tune.name,
Expand Down Expand Up @@ -398,6 +421,12 @@ export default class ImageTool implements BlockTool {
private tuneToggled(tuneName: keyof ImageToolData): void {
// inverse tune state
this.setTune(tuneName, !(this._data[tuneName] as boolean));

// reset caption on toggle
if (tuneName === 'caption' && !this._data[tuneName]) {
this._data.caption = '';
this.ui.fillCaption('');
}
}

/**
Expand Down
28 changes: 28 additions & 0 deletions src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,29 @@ export type ImageToolData<Actions = {}, AdditionalFileData = {}> = {
} & AdditionalFileData;
} & (Actions extends Record<string, boolean> ? Actions : {});

/**
* @description Allows to enable or disable features.
*/
export type FeaturesConfig = {
/**
* Flag to enable/disable tune - background.
*/
background?: boolean;
/**
* Flag to enable/disable tune - border.
*/
border?: boolean;
/**
* Flag to enable/disable caption.
* Can be set to 'optional' to allow users to toggle via block tunes.
*/
caption?: boolean | 'optional';
/**
* Flag to enable/disable tune - stretched
*/
stretch?: boolean;
};

/**
*
* @description Config supported by Tool
Expand Down Expand Up @@ -171,6 +194,11 @@ export interface ImageConfig {
* Additional actions for the tool.
*/
actions?: ActionConfig[];

/**
* Tunes to be enabled.
*/
features?: FeaturesConfig;
}

/**
Expand Down

0 comments on commit b97f7d1

Please sign in to comment.