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

Block tunes as a popover #2091

Merged
merged 83 commits into from Nov 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
1aa1017
Default tunes to popover
TatianaFomina Jul 3, 2022
5b9c6c7
Add the rest of default tunes
TatianaFomina Jul 4, 2022
9b698ef
Add popover
TatianaFomina Jul 4, 2022
6a7db2e
Cleanup
TatianaFomina Jul 4, 2022
e04c401
Rename custom content
TatianaFomina Jul 4, 2022
a0c87fb
Cleanup
TatianaFomina Jul 4, 2022
ac05f80
Add ability to open block settings upwards
TatianaFomina Jul 4, 2022
6392cc1
Fix tests
TatianaFomina Jul 4, 2022
9ad9e41
Cleanup default tunes
TatianaFomina Jul 4, 2022
3e2f624
Rename and cleanup
TatianaFomina Jul 4, 2022
28ca17d
Add ability to display rendered custom tunes
TatianaFomina Jul 12, 2022
aece45d
cleanup
TatianaFomina Jul 13, 2022
62f0ae8
Rename
TatianaFomina Jul 20, 2022
e3bad74
Add flag to close tunes popover
TatianaFomina Jul 20, 2022
8807d5e
Cleanup
TatianaFomina Jul 20, 2022
c9defd9
i18n
TatianaFomina Jul 20, 2022
ac69d08
Cleanup
TatianaFomina Jul 20, 2022
1d34042
Fix build and tests
TatianaFomina Jul 22, 2022
18283c9
Fix for iframe
TatianaFomina Jul 22, 2022
80aecdd
Merge branch 'next' into tunes-vertical
TatianaFomina Jul 22, 2022
41b108d
Add comments
TatianaFomina Jul 29, 2022
fbff337
Display active item, move closeOnActivate to popover
TatianaFomina Jul 29, 2022
58a2f97
Add confirmation support to popover
TatianaFomina Jul 29, 2022
7907272
Handle boolean value in confirmation param
TatianaFomina Aug 1, 2022
820a2b5
Clarify flippable logic in popover
TatianaFomina Aug 1, 2022
12012c1
Comments
TatianaFomina Aug 1, 2022
a62d305
Pass editor element as a param of popover constructor
TatianaFomina Aug 1, 2022
e62c56e
Fix readability
TatianaFomina Aug 1, 2022
cc213f4
Tests
TatianaFomina Aug 1, 2022
292f7fa
Fix flipper for confirmation element
TatianaFomina Aug 3, 2022
0f55a45
Update confirmation config structure
TatianaFomina Aug 3, 2022
9513665
Rename onClick to onActivate
TatianaFomina Aug 3, 2022
da1dd6f
Fix tests and build
TatianaFomina Aug 5, 2022
54f07f7
Make confirmation props optional
TatianaFomina Aug 5, 2022
4ca9dc0
Simplify processing tunes
TatianaFomina Aug 8, 2022
5d1584c
Renamings
TatianaFomina Aug 8, 2022
3b4d18b
Fix text block tunes
TatianaFomina Aug 8, 2022
f0ee7b6
Docs
TatianaFomina Aug 12, 2022
60d8ba5
Update event type
TatianaFomina Aug 12, 2022
5fc72f5
Move enabling confirmation state to separate method
TatianaFomina Aug 12, 2022
e8aa6c6
move popover types
TatianaFomina Aug 12, 2022
3cf8308
Unhardcode color
TatianaFomina Aug 14, 2022
b566332
Support toggling
TatianaFomina Aug 14, 2022
25713c6
Add support of disabled items
TatianaFomina Aug 14, 2022
ae5c05b
Fix tab in empty block leading to selecting second item in popover
TatianaFomina Aug 14, 2022
f82fc2a
Remove margins for styles api settings button class
TatianaFomina Aug 14, 2022
0079151
Fix arrow navigation between blocks after opening block tunes
TatianaFomina Aug 16, 2022
ad4b23d
Cleaup in default tunes code
TatianaFomina Aug 17, 2022
c590217
Fix chaining confirmations
TatianaFomina Aug 17, 2022
7ef6dae
Colors
TatianaFomina Aug 17, 2022
81823f5
Types
TatianaFomina Aug 17, 2022
7d05d42
Change the way flippable elements of popover custom area are set
TatianaFomina Aug 18, 2022
7f5e744
Remove borders around popover icons
TatianaFomina Aug 18, 2022
2441139
Fix untabbable inline toolbar
TatianaFomina Aug 20, 2022
887b786
Fix locked scroll after closing tunes popover on mobile
TatianaFomina Aug 20, 2022
bbf9f93
Cleanup
TatianaFomina Aug 31, 2022
f158cee
Set max popover width
TatianaFomina Aug 31, 2022
a807707
Make popover icon's border outside
TatianaFomina Aug 31, 2022
e12dc20
Fix tab issue
TatianaFomina Aug 31, 2022
c5eb273
Fix focus/hover issue
TatianaFomina Sep 12, 2022
7d75821
Reformat
TatianaFomina Sep 15, 2022
2c07cf8
Cleanup
TatianaFomina Sep 19, 2022
d854ade
Fix opening block tunes via keyboard
TatianaFomina Sep 19, 2022
0e37e74
Add disableSpecialHoverAndFocusBehavior
TatianaFomina Sep 19, 2022
2284f11
Add deprecated comment
TatianaFomina Sep 19, 2022
ad3d3dc
Cleanup
TatianaFomina Sep 19, 2022
3a1745e
Fix popover active state
TatianaFomina Sep 20, 2022
2030da5
Fix checklist deletion with confirmation
TatianaFomina Oct 26, 2022
ae270f1
Fix checklist deletion 2
TatianaFomina Oct 28, 2022
616b882
Fix popover focus
TatianaFomina Oct 28, 2022
dd651c9
Fix popover items being impossible to flip after searching
TatianaFomina Oct 28, 2022
9959709
Fix popover item highlighting issue
TatianaFomina Oct 28, 2022
2a6b0f2
Update flipper.spec.ts
neSpecc Oct 29, 2022
d5e71d4
Fixes after review
TatianaFomina Oct 29, 2022
53b7e87
Add Tunes Api tests
TatianaFomina Oct 31, 2022
ac12b58
Fix multiple popover entries configured by one tune
TatianaFomina Oct 31, 2022
18149d3
Add tool's renderSettings() tests
TatianaFomina Oct 31, 2022
ea8eaa8
Add popover confirmation state test
TatianaFomina Oct 31, 2022
1ff925f
Fix popover width on mobile
TatianaFomina Nov 2, 2022
0d73b02
Add popover tests
TatianaFomina Nov 2, 2022
d05e544
Add changelog and update version
TatianaFomina Nov 2, 2022
d7ebf59
Update changelog
TatianaFomina Nov 3, 2022
89601e1
Fix block tunes being unable to open after tune activation
TatianaFomina Nov 3, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/CHANGELOG.md
@@ -1,5 +1,14 @@
# Changelog


### 2.26.0

- `New` — *UI* — Meet the new Block Tunes look! Vertical menu with simple JSON configuration (and support for legacy way of defining block tunes).
- `New` — *Block Tunes API* — Now `render()` method of a Block Tune can return `TunesMenuConfig` besides `HTMLElement`. This impovement is a key to the new straightforward way of configuring tune's appearance in Block Tunes menu.
- `New` — *Tools API* — As well as `render()` in `Tunes Api`, Tool's `renderSettings()` now also supports `TunesMenuConfig` return value format.
- `Deprecated` — *Styles API* — CSS classes `.cdx-settings-button` and `.cdx-settings-button--active` are not recommended to use. Consider configuring your block settings with new JSON API instead.
- `Fix` — Prevent flipper from handling the event which caused it's instantiating.

### 2.25.0

- `New` — *Tools API* — Introducing new feature — toolbox now can have multiple entries for one tool! <br>
Expand Down
6 changes: 4 additions & 2 deletions example/example-i18n.html
Expand Up @@ -194,9 +194,11 @@
"toolbar": {
"toolbox": {
"Add": "Добавить",
"Filter": "Поиск",
"Nothing found": "Ничего не найдено"
}
},
"popover": {
"Filter": "Поиск",
"Nothing found": "Ничего не найдено"
}
},

Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@editorjs/editorjs",
"version": "2.25.0",
"version": "2.26.0",
"description": "Editor.js — Native JS, based on API and Open Source",
"main": "dist/editor.js",
"types": "./types/index.d.ts",
Expand Down
98 changes: 13 additions & 85 deletions src/components/block-tunes/block-tune-delete.ts
Expand Up @@ -4,7 +4,7 @@
*
* @copyright <CodeX Team> 2018
*/
import { API, BlockTune } from '../../../types';
import { API, BlockTune, PopoverItem } from '../../../types';
import $ from '../dom';

/**
Expand All @@ -23,63 +23,28 @@ export default class DeleteTune implements BlockTune {
*/
private readonly api: API;

/**
* Styles
*/
private CSS = {
button: 'ce-settings__button',
buttonDelete: 'ce-settings__button--delete',
buttonConfirm: 'ce-settings__button--confirm',
};

/**
* Delete confirmation
*/
private needConfirmation: boolean;

/**
* set false confirmation state
*/
private readonly resetConfirmation: () => void;

/**
* Tune nodes
*/
private nodes: {button: HTMLElement} = {
button: null,
};

/**
* DeleteTune constructor
*
* @param {API} api - Editor's API
*/
constructor({ api }) {
this.api = api;

this.resetConfirmation = (): void => {
this.setConfirmation(false);
};
}

/**
* Create "Delete" button and add click event listener
*
* @returns {HTMLElement}
* Tune's appearance in block settings menu
*/
public render(): HTMLElement {
this.nodes.button = $.make('div', [this.CSS.button, this.CSS.buttonDelete], {});
this.nodes.button.appendChild($.svg('cross', 12, 12));
this.api.listeners.on(this.nodes.button, 'click', (event: MouseEvent) => this.handleClick(event), false);

/**
* Enable tooltip module
*/
this.api.tooltip.onHover(this.nodes.button, this.api.i18n.t('Delete'), {
hidingDelay: 300,
});

return this.nodes.button;
public render(): PopoverItem {
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
return {
icon: $.svg('cross', 14, 14).outerHTML,
label: this.api.i18n.t('Delete'),
name: 'delete',
confirmation: {
label: this.api.i18n.t('Click to delete'),
onActivate: (item, e): void => this.handleClick(e),
},
};
}

/**
Expand All @@ -88,43 +53,6 @@ export default class DeleteTune implements BlockTune {
* @param {MouseEvent} event - click event
*/
public handleClick(event: MouseEvent): void {
/**
* if block is not waiting the confirmation, subscribe on block-settings-closing event to reset
* otherwise delete block
*/
if (!this.needConfirmation) {
this.setConfirmation(true);

/**
* Subscribe on event.
* When toolbar block settings is closed but block deletion is not confirmed,
* then reset confirmation state
*/
this.api.events.on('block-settings-closed', this.resetConfirmation);
} else {
/**
* Unsubscribe from block-settings closing event
*/
this.api.events.off('block-settings-closed', this.resetConfirmation);

this.api.blocks.delete();
this.api.toolbar.close();
this.api.tooltip.hide();

/**
* Prevent firing ui~documentClicked that can drop currentBlock pointer
*/
event.stopPropagation();
}
}

/**
* change tune state
*
* @param {boolean} state - delete confirmation state
*/
private setConfirmation(state: boolean): void {
this.needConfirmation = state;
this.nodes.button.classList.add(this.CSS.buttonConfirm);
this.api.blocks.delete();
}
}
49 changes: 16 additions & 33 deletions src/components/block-tunes/block-tune-move-down.ts
Expand Up @@ -6,7 +6,8 @@
*/

import $ from '../dom';
import { API, BlockTune } from '../../../types';
import { API, BlockTune, PopoverItem } from '../../../types';
import Popover from '../utils/popover';

/**
*
Expand All @@ -26,12 +27,8 @@ export default class MoveDownTune implements BlockTune {

/**
* Styles
*
* @type {{wrapper: string}}
*/
private CSS = {
button: 'ce-settings__button',
wrapper: 'ce-tune-move-down',
animation: 'wobble',
};

Expand All @@ -45,43 +42,32 @@ export default class MoveDownTune implements BlockTune {
}

/**
* Return 'move down' button
*
* @returns {HTMLElement}
* Tune's appearance in block settings menu
*/
public render(): HTMLElement {
const moveDownButton = $.make('div', [this.CSS.button, this.CSS.wrapper], {});

moveDownButton.appendChild($.svg('arrow-down', 14, 14));
this.api.listeners.on(
moveDownButton,
'click',
(event) => this.handleClick(event as MouseEvent, moveDownButton),
false
);

/**
* Enable tooltip module on button
*/
this.api.tooltip.onHover(moveDownButton, this.api.i18n.t('Move down'), {
hidingDelay: 300,
});

return moveDownButton;
public render(): PopoverItem {
return {
icon: $.svg('arrow-down', 14, 14).outerHTML,
label: this.api.i18n.t('Move down'),
onActivate: (item, event): void => this.handleClick(event),
name: 'move-down',
};
}

/**
* Handle clicks on 'move down' button
*
* @param {MouseEvent} event - click event
* @param {HTMLElement} button - clicked button
* @param event - click event
*/
public handleClick(event: MouseEvent, button: HTMLElement): void {
public handleClick(event: MouseEvent): void {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();
const nextBlock = this.api.blocks.getBlockByIndex(currentBlockIndex + 1);

// If Block is last do nothing
if (!nextBlock) {
const button = (event.target as HTMLElement)
.closest('.' + Popover.CSS.item)
.querySelector('.' + Popover.CSS.itemIcon);

button.classList.add(this.CSS.animation);

window.setTimeout(() => {
Expand Down Expand Up @@ -110,8 +96,5 @@ export default class MoveDownTune implements BlockTune {
this.api.blocks.move(currentBlockIndex + 1);

this.api.toolbar.toggleBlockSettings(true);

/** Hide the Tooltip */
this.api.tooltip.hide();
}
}
47 changes: 15 additions & 32 deletions src/components/block-tunes/block-tune-move-up.ts
Expand Up @@ -5,7 +5,8 @@
* @copyright <CodeX Team> 2018
*/
import $ from '../dom';
import { API, BlockTune } from '../../../types';
import { API, BlockTune, BlockAPI, PopoverItem } from '../../../types';
import Popover from '../../components/utils/popover';

/**
*
Expand All @@ -25,12 +26,8 @@ export default class MoveUpTune implements BlockTune {

/**
* Styles
*
* @type {{wrapper: string}}
*/
private CSS = {
button: 'ce-settings__button',
wrapper: 'ce-tune-move-up',
animation: 'wobble',
};

Expand All @@ -44,43 +41,32 @@ export default class MoveUpTune implements BlockTune {
}

/**
* Create "MoveUp" button and add click event listener
*
* @returns {HTMLElement}
* Tune's appearance in block settings menu
*/
public render(): HTMLElement {
const moveUpButton = $.make('div', [this.CSS.button, this.CSS.wrapper], {});

moveUpButton.appendChild($.svg('arrow-up', 14, 14));
this.api.listeners.on(
moveUpButton,
'click',
(event) => this.handleClick(event as MouseEvent, moveUpButton),
false
);

/**
* Enable tooltip module on button
*/
this.api.tooltip.onHover(moveUpButton, this.api.i18n.t('Move up'), {
hidingDelay: 300,
});

return moveUpButton;
public render(): PopoverItem {
return {
icon: $.svg('arrow-up', 14, 14).outerHTML,
label: this.api.i18n.t('Move up'),
onActivate: (item, e): void => this.handleClick(e),
name: 'move-up',
};
}

/**
* Move current block up
*
* @param {MouseEvent} event - click event
* @param {HTMLElement} button - clicked button
*/
public handleClick(event: MouseEvent, button: HTMLElement): void {
public handleClick(event: MouseEvent): void {
const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();
const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
const previousBlock = this.api.blocks.getBlockByIndex(currentBlockIndex - 1);

if (currentBlockIndex === 0 || !currentBlock || !previousBlock) {
const button = (event.target as HTMLElement)
.closest('.' + Popover.CSS.item)
.querySelector('.' + Popover.CSS.itemIcon);

button.classList.add(this.CSS.animation);

window.setTimeout(() => {
Expand Down Expand Up @@ -118,8 +104,5 @@ export default class MoveUpTune implements BlockTune {
this.api.blocks.move(currentBlockIndex - 1);

this.api.toolbar.toggleBlockSettings(true);

/** Hide the Tooltip */
this.api.tooltip.hide();
}
}