Skip to content
Open
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
12 changes: 1 addition & 11 deletions src/components/modules/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,11 @@ export default class UI extends Module<UINodes> {
* @returns {{editorWrapper: string, editorZone: string}}
*/
public get CSS(): {
editorWrapper: string; editorWrapperNarrow: string; editorZone: string; editorZoneHidden: string;
editorWrapper: string; editorZone: string; editorZoneHidden: string;
editorEmpty: string; editorRtlFix: string;
} {
return {
editorWrapper: 'codex-editor',
editorWrapperNarrow: 'codex-editor--narrow',
editorZone: 'codex-editor__redactor',
editorZoneHidden: 'codex-editor__redactor--hidden',
editorEmpty: 'codex-editor--empty',
Expand Down Expand Up @@ -290,15 +289,6 @@ export default class UI extends Module<UINodes> {
]);
this.nodes.redactor = $.make('div', this.CSS.editorZone);

/**
* If Editor has injected into the narrow container, enable Narrow Mode
*
* @todo Forced layout. Get rid of this feature
*/
if (this.nodes.holder.offsetWidth < this.contentRect.width) {
this.nodes.wrapper.classList.add(this.CSS.editorWrapperNarrow);
}

/**
* Set customizable bottom zone height
*/
Expand Down
18 changes: 18 additions & 0 deletions src/styles/block.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,31 @@

&--stretched &__content {
max-width: none;

@media (--not-mobile) {
width: max(0px, calc(100% - var(--toolbar-actions-space)));
margin-left: var(--toolbar-actions-space);
}
}

&__content {
position: relative;
max-width: var(--content-width);
margin: 0 auto;
transition: background-color 150ms ease;

@media (--not-mobile) {
width: min(
var(--content-width),
max(0px, calc(100% - var(--toolbar-actions-space)))
);
max-width: none;
margin-left: max(
var(--toolbar-actions-space),
calc((100% - var(--content-width)) / 2)
);
margin-right: 0;
}
}

&--drop-target &__content {
Expand Down
39 changes: 25 additions & 14 deletions src/styles/rtl.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
}

&__actions {
right: auto;
left: calc(var(--toolbox-buttons-size) * -1);

@media (--mobile){
right: auto;
left: calc(var(--toolbox-buttons-size) * -1);
margin-left: 0;
margin-right: auto;
padding-right: 0;
Expand Down Expand Up @@ -64,19 +63,31 @@

}

.codex-editor--narrow.codex-editor--rtl {
.ce-toolbar__plus {
@media (--not-mobile) {
left: 0px;
right: 5px;
@media (--not-mobile) {
.codex-editor.codex-editor--rtl {
.ce-block__content,
.ce-toolbar__content {
margin-left: 0;
margin-right: max(
var(--toolbar-actions-space),
calc((100% - var(--content-width)) / 2)
);
}
}

.ce-toolbar__actions {
@media (--not-mobile) {
left: -5px;
.ce-block--stretched .ce-block__content {
margin-right: var(--toolbar-actions-space);
}
}
}

.ce-toolbar__actions {
right: auto;
left: 100%;
padding-right: 0;
padding-left: 5px;
}

.ce-toolbar__settings-btn {
margin-left: 0;
margin-right: 3px;
}
}
}
27 changes: 18 additions & 9 deletions src/styles/toolbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@
max-width: var(--content-width);
margin: 0 auto;
position: relative;

@media (--not-mobile) {
width: min(
var(--content-width),
max(0px, calc(100% - var(--toolbar-actions-space)))
);
max-width: none;
margin-left: max(
var(--toolbar-actions-space),
calc((100% - var(--content-width)) / 2)
);
margin-right: 0;
}
}

&__plus {
Expand Down Expand Up @@ -52,6 +65,11 @@
@media (--mobile){
right: auto;
}

@media (--not-mobile){
width: var(--toolbar-actions-space);
box-sizing: border-box;
}
}

&__settings-btn {
Expand Down Expand Up @@ -83,12 +101,3 @@
}
}
}

/**
* Styles for Narrow mode
*/
.codex-editor--narrow .ce-toolbar__plus {
@media (--not-mobile) {
left: 5px;
}
}
9 changes: 0 additions & 9 deletions src/styles/toolbox.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
.ce-toolbox {

}

.codex-editor--narrow .ce-toolbox {
@media (--not-mobile){
.ce-popover {
right: 0;
left: unset;
}
}
}
23 changes: 0 additions & 23 deletions src/styles/ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,6 @@
}
}

/**
* Styles for narrow holder
*/
&--narrow &__redactor {
@media (--not-mobile) {
margin-right: var(--narrow-mode-right-padding);
}
}

&--narrow&--rtl &__redactor {
@media (--not-mobile) {
margin-left: var(--narrow-mode-right-padding);
margin-right: 0;
}
}

&--narrow .ce-toolbar__actions {
@media (--not-mobile) {
right: -5px;
}
}

&-copyable {
position: absolute;
height: 1px;
Expand Down Expand Up @@ -91,7 +69,6 @@
}
}


.codex-editor--toolbox-opened [contentEditable=true][data-placeholder]:focus::before {
opacity: 0 !important;
}
Expand Down
4 changes: 2 additions & 2 deletions src/styles/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@
--content-width: 650px;

/**
* In narrow mode, we increase right zone contained Block Actions button
* Width reserved for Block Actions beside editor content
*/
--narrow-mode-right-padding: 50px;
--toolbar-actions-space: 58px;

/**
* Toolbar Plus Button and Toolbox buttons height and width
Expand Down
134 changes: 134 additions & 0 deletions test/cypress/tests/modules/Ui.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,140 @@ import { createEditorWithTextBlocks } from '../../support/utils/createEditorWith
import type EditorJS from '../../../../types/index';

describe('Ui module', function () {
describe('responsive layout', function () {
it('should not read holder width during initialization', function () {
cy.window()
.then(async (window) => {
const holder = window.document.createElement('div');
let holderWidthRead = false;

holder.id = 'editorjs';
Object.defineProperty(holder, 'offsetWidth', {
configurable: true,
get: () => {
holderWidthRead = true;

return 700;
},
});
window.document.body.appendChild(holder);

const editor = new window.EditorJS({
holder,
});

await editor.isReady;

expect(holderWidthRead).to.be.false;

editor.destroy();
});
});

it('should keep the plus button left of the content in a thin holder on a wide screen', function () {
cy.viewport(1000, 800);
cy.createEditor();

cy.get('[data-cy=editorjs]')
.invoke('css', 'width', '500px')
.find('.ce-paragraph')
.click();

cy.get('[data-cy=editorjs]')
.then(($holder) => {
const holderRect = $holder[0].getBoundingClientRect();
const holderContentLeft = holderRect.left + $holder[0].clientLeft;
const plusButtonRect = $holder.find('.ce-toolbar__plus')[0].getBoundingClientRect();
const blockContentRect = $holder.find('.ce-block__content')[0].getBoundingClientRect();

expect(plusButtonRect.width).to.be.greaterThan(0);
expect(plusButtonRect.left).to.equal(holderContentLeft);
expect(plusButtonRect.right).to.be.at.most(blockContentRect.left);
});
});

it('should preserve the mobile toolbar and toolbox layout', function () {
cy.viewport(375, 667);
cy.createEditor();

cy.get('[data-cy=editorjs]')
.find('.ce-paragraph')
.click();

cy.get('[data-cy=editorjs]')
.then(($holder) => {
const holderRect = $holder[0].getBoundingClientRect();
const plusButtonRect = $holder.find('.ce-toolbar__plus')[0].getBoundingClientRect();

expect(plusButtonRect.left).to.be.at.least(holderRect.left);
expect(plusButtonRect.right).to.be.at.most(holderRect.right);
})
.find('.ce-toolbar__plus')
.click();

cy.get('[data-cy=toolbox]')
.find('.ce-popover__container')
.should('be.visible')
.should(($popover) => {
const popoverRect = $popover[0].getBoundingClientRect();
const viewport = $popover[0].ownerDocument.defaultView;

expect(viewport).not.to.be.null;
expect(popoverRect.left).to.be.at.least(0);
expect(popoverRect.right).to.be.at.most(viewport?.innerWidth);
expect(popoverRect.top).to.be.at.least(0);
expect(popoverRect.bottom).to.be.at.most(viewport?.innerHeight);
});
});

it('should mirror the responsive toolbar in a thin RTL holder', function () {
cy.viewport(1000, 800);
cy.createEditor({
i18n: {
direction: 'rtl',
},
});

cy.get('[data-cy=editorjs]')
.invoke('css', 'width', '500px')
.find('.ce-paragraph')
.click();

cy.get('[data-cy=editorjs]')
.then(($holder) => {
const holder = $holder[0];
const holderRect = holder.getBoundingClientRect();
const holderRightBorder = holder.offsetWidth - holder.clientWidth - holder.clientLeft;
const holderContentRight = holderRect.right - holderRightBorder;
const plusButtonRect = $holder.find('.ce-toolbar__plus')[0].getBoundingClientRect();
const blockContentRect = $holder.find('.ce-block__content')[0].getBoundingClientRect();

expect(plusButtonRect.right).to.equal(holderContentRight);
expect(plusButtonRect.left).to.be.at.least(blockContentRect.right);
});
});

it('should keep the rectangle selection overlay fixed to the viewport', function () {
cy.viewport(1000, 800);
cy.createEditor();

cy.get('[data-cy=editorjs]')
.invoke('css', {
marginLeft: '40px',
width: '500px',
})
.find('.codex-editor-overlay')
.then(($overlay) => {
const overlayRect = $overlay[0].getBoundingClientRect();

expect(overlayRect.left).to.equal(0);
expect(overlayRect.top).to.equal(0);
expect(overlayRect.right).to.equal(1000);
expect(overlayRect.bottom).to.equal(800);
});
});
});

describe('documentKeydown', function () {
describe('Backspace', function () {
it('should remove selected blocks', function () {
Expand Down