diff --git a/README.md b/README.md
index a0d59f39..39e29a2d 100644
--- a/README.md
+++ b/README.md
@@ -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**
@@ -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.
@@ -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: [
@@ -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
@@ -136,7 +150,7 @@ This Tool returns `data` with following format
"caption" : "Roadster // tesla.com",
"withBorder" : false,
"withBackground" : false,
- "stretched" : true
+ "stretched" : true,
}
}
```
diff --git a/dev/index.html b/dev/index.html
new file mode 100644
index 00000000..f9495ce7
--- /dev/null
+++ b/dev/index.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+ Image Plugin Test | EditorJS
+
+
+
+
+
+
+
+
diff --git a/package.json b/package.json
index 7b27d495..5f75a71d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@editorjs/image",
- "version": "2.9.3",
+ "version": "2.10.0",
"keywords": [
"codex editor",
"image",
diff --git a/src/index.css b/src/index.css
index 2823c160..82331659 100644
--- a/src/index.css
+++ b/src/index.css
@@ -44,6 +44,8 @@
}
&__caption {
+ display: none;
+
&[contentEditable="true"][data-placeholder]::before {
position: absolute !important;
content: attr(data-placeholder);
@@ -86,7 +88,7 @@
margin: 0 6px 0 0;
}
}
-
+
&--filled {
.cdx-button {
display: none;
@@ -147,13 +149,19 @@
}
}
+ &--caption {
+ ^&__caption {
+ display: block;
+ }
+ }
}
@keyframes image-preloader-spin {
0% {
transform: rotate(0deg);
}
+
100% {
transform: rotate(360deg);
}
-}
+}
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index 7c7145aa..de1bece8 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -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}
@@ -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;
@@ -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
*/
@@ -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;
/**
@@ -106,6 +99,7 @@ export default class ImageTool implements BlockTool {
buttonContent: config.buttonContent,
uploader: config.uploader,
actions: config.actions,
+ features: config.features || {},
};
/**
@@ -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;
}
@@ -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 = {
+ 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,
@@ -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('');
+ }
}
/**
diff --git a/src/types/types.ts b/src/types/types.ts
index 6b4da7e7..3de55056 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -100,6 +100,29 @@ export type ImageToolData = {
} & AdditionalFileData;
} & (Actions extends Record ? 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
@@ -171,6 +194,11 @@ export interface ImageConfig {
* Additional actions for the tool.
*/
actions?: ActionConfig[];
+
+ /**
+ * Tunes to be enabled.
+ */
+ features?: FeaturesConfig;
}
/**