Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for disabling features in ImageTool #269

Merged
merged 7 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 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,18 @@ 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 enable/disable features such as border, background tunes and caption by adding `features` array in the configuration:
```js
features: {
background: boolean,
border: boolean,
caption: boolean | 'optional',
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
stretched: boolean
}
```

**_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 +151,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: {
background: true,
border: true,
caption: true,
stretched: true,
},
},
},
},
});
</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",
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
"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
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
*
* 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;
neSpecc marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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 === 'optional' && this.data.caption)) {
this.ui.applyTune('caption', true);
}

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

Expand Down Expand Up @@ -228,8 +226,39 @@ 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 = new Map<string, string>([
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
['border', 'withBorder'],
['background', 'withBackground'],
['stretched', '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) => {
if (this.config.features) {
const featureKey = [...featureTuneMap.entries()].find(
([, value]) => value === tune.name
)?.[0];

if (featureKey != null) {
return this.config.features[featureKey as keyof FeaturesConfig];
}

return false;
}

return false;
});

return tunes.map(tune => ({
return availableTunes.map(tune => ({
icon: tune.icon,
label: this.api.i18n.t(tune.title),
name: tune.name,
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 = {
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
/**
* 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.
*/
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
caption: boolean | 'optional';
/**
* Flag to enable/disable tune - stretched
*/
stretched: 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
Loading