Skip to content

Commit

Permalink
:IBX-6843: Focus mode
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasOsti committed Oct 26, 2023
1 parent 69e8a2c commit 8ee4b53
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/bundle/Resources/encore/ibexa.js.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const layout = [
path.resolve(__dirname, '../public/js/scripts/admin.form.autosubmit.js'),
path.resolve(__dirname, '../public/js/scripts/admin.anchor.navigation'),
path.resolve(__dirname, '../public/js/scripts/admin.context.menu'),
path.resolve(__dirname, '../public/js/scripts/admin.focus.mode.js'),
path.resolve(__dirname, '../public/js/scripts/sidebar/main.menu.js'),
path.resolve(__dirname, '../public/js/scripts/admin.input.text.js'),
path.resolve(__dirname, '../public/js/scripts/admin.table.js'),
Expand Down
71 changes: 71 additions & 0 deletions src/bundle/Resources/public/js/scripts/admin.focus.mode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
(function (global, doc, ibexa) {
let activeFieldEdit = null;
const ENABLE_FOCUS_MODE_EVENT_NAME = 'ibexa-focus-mode:on';
const DISABLE_FOCUS_MODE_EVENT_NAME = 'ibexa-focus-mode:off';
const focusModeEnableBtns = doc.querySelectorAll('.ibexa-field-edit__focus-mode-control-btn--enable');
const focusModeDisbaleBtns = doc.querySelectorAll('.ibexa-field-edit__focus-mode-control-btn--disable');
const noticeContainers = doc.querySelectorAll('.ibexa-field-edit__focus-mode-notice-container')
const getEditorUiInstance = (editorContainer) => {
const editorSourceElement = editorContainer.querySelector('.ibexa-data-source__richtext');
const editorInstance = editorSourceElement.ckeditorInstance;

return editorInstance.ui;
};
const changeFocusModeState = (enable) => {
if (!activeFieldEdit) {
return;
}

const dispatchEventName = enable
? ENABLE_FOCUS_MODE_EVENT_NAME
: DISABLE_FOCUS_MODE_EVENT_NAME;
const editorSourceElement = activeFieldEdit.querySelector('.ibexa-data-source__richtext');
const editorInstance = editorSourceElement.ckeditorInstance;

activeFieldEdit.classList.toggle('ibexa-field-edit--in-focus-mode', enable);
editorInstance.set('focusModeEnabled', enable);

doc.body.dispatchEvent(
new CustomEvent(dispatchEventName, {
detail: {
activeFieldEdit
},
}),
);

if (!enable) {
activeFieldEdit = null;
}
}
const watchDisableFocusModeByKeyboard = (event) => {
if (event.key === 'Escape' || event.keyCode === 27) {
changeFocusModeState(false)
}
}

focusModeEnableBtns.forEach((btn) => {
btn.addEventListener('click', ({ currentTarget }) => {
activeFieldEdit = currentTarget.closest('.ibexa-field-edit')
changeFocusModeState(true)
}, false)
});
focusModeDisbaleBtns.forEach((btn) => {
btn.addEventListener('click', () => changeFocusModeState(false), false)
});

noticeContainers.forEach((noticeContainer) => {
const alerts = noticeContainer.querySelectorAll('.ibexa-alert');

alerts.forEach((alert) => {
alert.addEventListener('closed.bs.alert', () => {
const container = noticeContainer.closest('.ibexa-field-edit');
const editorUiInstance = getEditorUiInstance(container);

editorUiInstance.fire('ibexa-rt-update-ui');
});
})
});

doc.body.addEventListener(ENABLE_FOCUS_MODE_EVENT_NAME, () => doc.body.addEventListener('keydown', watchDisableFocusModeByKeyboard), false);
doc.body.addEventListener(DISABLE_FOCUS_MODE_EVENT_NAME, () => doc.body.removeEventListener('keydown', watchDisableFocusModeByKeyboard), false);
})(window, window.document, window.ibexa);
10 changes: 10 additions & 0 deletions src/bundle/Resources/public/scss/_alerts.scss
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,14 @@
}
}
}

&--complementary {
color: $ibexa-color-complementary-700;
background-color: $ibexa-color-complementary-100;
border-color: $ibexa-color-complementary;

.ibexa-icon {
fill: $ibexa-color-complementary-700;
}
}
}
131 changes: 131 additions & 0 deletions src/bundle/Resources/public/scss/fieldType/edit/_base-field.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,35 @@
color: $ibexa-color-danger;
}

&__focus-mode {
display: flex;
flex-direction: column;
height: auto;
background: $ibexa-color-white;
border-radius: $ibexa-border-radius $ibexa-border-radius 0 0;
}

&__focus-mode-notice-container {
display: none;
}

&__focus-mode-control-container {
display: flex;
align-self: flex-end;
}

&__focus-mode-control-btn {
align-self: flex-end;

&--enable {
display: inline-flex;
}

&--disable {
display: none;
}
}

.ibexa-input-text-wrapper {
width: auto;
}
Expand Down Expand Up @@ -59,6 +88,108 @@
}
}
}

&--has-focus-mode {
display: flex;
flex-wrap: wrap;

.ibexa-field-edit {
&__focus-mode {
margin: auto 0 0 0;
align-self: baseline;
}

&__label-wrapper {
width: 80%;
}

&__focus-mode {
width: 20%;
}

&__data {
width: 100%;
}
}
}

&--in-focus-mode {
position: fixed;
top: 0;
left: 0;
z-index: 1080;
flex-direction: column;
width: 100vw;
height: 100vh;
padding: calculateRem(16px);
background: $ibexa-color-black;

.ibexa-field-edit {
&__label-wrapper {
display: none;
}

&__focus-mode {
width: 100%;
height: fit-content;
padding: calculateRem(32px) calculateRem(32px) 0 calculateRem(32px);
}

&__focus-mode-notice-container {
display: block;
width: 100%;
}

&__focus-mode-control-container {
height: calculateRem(40px);
}

&__focus-mode-control-btn {
margin: 0;

&--enable {
display: none;
}

&--disable {
display: inline-flex;
}
}

&__data {
width: 100%;
overflow-y: auto;
align-self: stretch;
flex-grow: 1;
padding: calculateRem(8px) calculateRem(32px) calculateRem(32px) calculateRem(32px);
background: $ibexa-color-white;
border-radius: 0 0 $ibexa-border-radius $ibexa-border-radius;

.ibexa-data-source {
height: 100%;
}
}
}

.ibexa-alert {
margin-bottom: calculateRem(4px);
}
}

&--in-focus-mode.is-invalid {
.ibexa-field-edit {
&__data {
border-radius: 0;
padding-bottom: 0;
}
}

.ibexa-form-error {
padding: calculateRem(16px) calculateRem(32px);
background: $ibexa-color-white;
border-radius: 0 0 $ibexa-border-radius $ibexa-border-radius;
}
}
}

.ibexa-content-edit {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@
{% set fieldtype_identifier = fieldtype.vars.value.fieldDefinition.fieldTypeIdentifier %}
{% set translation_mode = fieldtype.vars.mainLanguageCode != fieldtype.vars.languageCode %}
{% set fieldtype_is_not_translatable = translation_mode and not fieldtype.vars.value.fieldDefinition.isTranslatable %}
{% set has_focus_mode = fieldtype_identifier == 'ezrichtext' %}

{% set widget_wrapper_attr = widget_wrapper_attr|default({})|merge({'class': (widget_wrapper_attr.class|default('') ~ ' ibexa-field-edit__data ibexa-field-edit__data')|trim}) %}
{% set wrapper_class = 'ibexa-field-edit ibexa-field-edit--' ~ fieldtype_identifier ~ ' ibexa-field-edit ibexa-field-edit--' ~ fieldtype_identifier %}
{% set wrapper_class = 'ibexa-field-edit ibexa-field-edit--' ~ fieldtype_identifier ~ ' ibexa-field-edit ibexa-field-edit--' ~ fieldtype_identifier ~ (has_focus_mode ? ' ibexa-field-edit--has-focus-mode') %}

{% if fieldtype.vars.disabled %}
{% set wrapper_class = wrapper_class ~ ' ibexa-field-edit--disabled ibexa-field-edit--disabled' %}
Expand Down Expand Up @@ -114,9 +115,13 @@

<div {% with { attr: wrapper_attr } %}{{ block('attributes') }}{% endwith %}>
<div{% with { attr: label_wrapper_attr } %}{{ block('attributes') }}{% endwith %}>
{% with { 'compound': false } %}{{- block('form_label') }}{% endwith %}
{% with { 'compound': false } %}{{ block('form_label') }}{% endwith %}
</div>

{% if has_focus_mode %}
{{- block('focus_mode') }}
{% endif %}

{% if widget_container_block is defined %}
{{ widget_container_block|raw }}
{% else %}
Expand Down
41 changes: 40 additions & 1 deletion src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@

{%- block richtext_widget -%}
{% set attr = attr|merge({ 'hidden': true }) %}

<div class="ibexa-data-source ibexa-data-source--richtext">
<textarea {{ block('widget_attributes') }}>{{ value }}</textarea>
<div class="hidden" data-udw-config-name="richtext_embed" data-udw-config="{{ ibexa_udw_config('richtext_embed', udw_context) }}"></div>
Expand Down Expand Up @@ -500,3 +499,43 @@
{{- form_errors(form) -}}
</div>
{%- endblock %}

{%- block focus_mode -%}
{%- set title_icon -%}
<svg class="ibexa-icon ibexa-icon--small">
<use xlink:href="{{ ibexa_icon_path('un-focus') }}"></use>
</svg>
{%- endset -%}
{%- set title -%}
{{ 'focus_mode.disbale_hint'|trans({ '%icon%': title_icon|raw })|desc('To exit distraction free mode, click the %icon% or press Esc')|raw }}
{%- endset -%}

<div class="ibexa-field-edit__focus-mode">
<div class="ibexa-field-edit__focus-mode-notice-container">
{% include '@ibexadesign/ui/component/alert/alert.html.twig' with {
type: 'complementary',
title,
icon_path: ibexa_icon_path('system-information'),
show_close_btn: true
} only %}
</div>
<div class="ibexa-field-edit__focus-mode-control-container">
<button type="button" class="btn ibexa-btn ibexa-btn--ghost ibexa-btn--small ibexa-field-edit__focus-mode-control-btn ibexa-field-edit__focus-mode-control-btn--enable">
<svg class="ibexa-icon ibexa-icon--small">
<use xlink:href="{{ ibexa_icon_path('focus') }}"></use>
</svg>
<span class="ibexa-btn__label">
{{ 'focus_mode.enable.label'|trans|desc('Focus mode') }}
</span>
</button>
<button type="button" class="btn ibexa-btn ibexa-btn--ghost ibexa-btn--small ibexa-field-edit__focus-mode-control-btn ibexa-field-edit__focus-mode-control-btn--disable">
<svg class="ibexa-icon ibexa-icon--small">
<use xlink:href="{{ ibexa_icon_path('un-focus') }}"></use>
</svg>
<span class="ibexa-btn__label">
{{ 'focus_mode.disable.label'|trans|desc('Distraction free mode') }}
</span>
</button>
</div>
</div>
{%- endblock -%}

0 comments on commit 8ee4b53

Please sign in to comment.