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 all 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
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
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 === 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> = {
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
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 = {
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
*/
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
Loading