Skip to content

Commit 8491b5f

Browse files
authored
IBX-9332: Add refine text support to eztext fields (#1416)
1 parent a655797 commit 8491b5f

File tree

4 files changed

+65
-3
lines changed

4 files changed

+65
-3
lines changed

src/bundle/Resources/public/js/scripts/admin.input.text.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(function (global, doc) {
22
const INPUT_PADDING = 12;
3+
const TEXTAREA_SCROLLBAR_PADDING = 6;
34
const togglePasswordVisibility = (event) => {
45
const passwordTogglerBtn = event.currentTarget;
56
const passwordShowIcon = passwordTogglerBtn.querySelector('.ibexa-input-text-wrapper__password-show');
@@ -40,9 +41,12 @@
4041
inputClearBtns.forEach((clearBtn) => clearBtn.addEventListener('click', clearText, false));
4142
passwordTogglerBtns.forEach((passwordTogglerBtn) => passwordTogglerBtn.addEventListener('click', togglePasswordVisibility, false));
4243
recalculateStyling();
44+
attachListenersToMultilineInputs();
4345
};
4446
const recalculateInputStyling = (inputActionsContainer) => {
45-
const input = inputActionsContainer.closest('.ibexa-input-text-wrapper').querySelector('input');
47+
const textWrapper = inputActionsContainer.closest('.ibexa-input-text-wrapper');
48+
const inputType = textWrapper.classList.contains('ibexa-input-text-wrapper--multiline') ? 'textarea' : 'input';
49+
const input = textWrapper.querySelector(inputType);
4650

4751
if (!input || input.type === 'number') {
4852
return;
@@ -64,6 +68,30 @@
6468
recalculateInputStyling(inputActionsContainer);
6569
});
6670
};
71+
const attachListenersToMultilineInputs = () => {
72+
const multilineInputWrappers = doc.querySelectorAll('.ibexa-input-text-wrapper.ibexa-input-text-wrapper--multiline');
73+
74+
multilineInputWrappers.forEach((multilineInputWrapper) => {
75+
const textareaComponent = multilineInputWrapper.querySelector('.ibexa-input--textarea');
76+
77+
const textareaComponentObserver = new ResizeObserver(() => {
78+
toggleScrollbarStyles(multilineInputWrapper);
79+
});
80+
81+
textareaComponentObserver.observe(textareaComponent);
82+
toggleScrollbarStyles(multilineInputWrapper);
83+
});
84+
};
85+
const toggleScrollbarStyles = (multilineInputWrapper) => {
86+
const textareaComponent = multilineInputWrapper.querySelector('textarea');
87+
const { scrollHeight, clientHeight, offsetWidth, clientWidth } = textareaComponent;
88+
const { overflowY } = global.getComputedStyle(textareaComponent);
89+
const hasScrollbar = overflowY !== 'hidden' && scrollHeight > clientHeight;
90+
const scrollbarWidth = offsetWidth - clientWidth;
91+
92+
multilineInputWrapper.classList.toggle('ibexa-input-text-wrapper--scrollbar-visible', hasScrollbar);
93+
multilineInputWrapper.style.setProperty('--scrollbar-width', `${scrollbarWidth + TEXTAREA_SCROLLBAR_PADDING}px`);
94+
};
6795

6896
doc.body.addEventListener('ibexa-inputs:added', attachListenersToAllInputs, false);
6997
doc.body.addEventListener('ibexa-inputs:recalculate-styling', recalculateStyling, false);

src/bundle/Resources/public/scss/_inputs.scss

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@
111111
box-shadow 0s; // Chrome does not render box-shadow properly with transition
112112
height: calculateRem(120px);
113113
padding: calculateRem(10px) calculateRem(16px);
114+
115+
&.form-control {
116+
min-height: calculateRem(48px);
117+
}
114118
}
115119

116120
&--checkbox,
@@ -406,7 +410,7 @@
406410
top: 50%;
407411
right: calculateRem(8px);
408412
transform: translate(0, -50%);
409-
height: calculateRem(24px);
413+
min-height: calculateRem(24px);
410414
padding: 0;
411415
fill: var(--ibexa-btn-icon-fill-color, #{$ibexa-color-dark});
412416
z-index: 1;
@@ -452,6 +456,23 @@
452456
}
453457
}
454458

459+
&--multiline {
460+
.ibexa-input-text-wrapper {
461+
&__actions {
462+
top: calculateRem(8px);
463+
transform: none;
464+
}
465+
}
466+
467+
&.ibexa-input-text-wrapper--scrollbar-visible {
468+
.ibexa-input-text-wrapper {
469+
&__actions {
470+
right: var(--scrollbar-width, 0);
471+
}
472+
}
473+
}
474+
}
475+
455476
&:hover {
456477
.ibexa-input {
457478
border-color: var(--ibexa-input-hover-border-color, #{$ibexa-color-primary});

src/bundle/Resources/views/themes/admin/ui/component/input_text.html.twig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
{% set is_password_type = type|default('') == 'password' %}
44
{% set is_password_input = is_password_input|default(is_password_type) %}
55
{% set has_search = has_search|default(false) %}
6+
{% set is_multiline = is_multiline|default(false) %}
67
{% set extra_btn = extra_btn|default({})|merge({
78
label: extra_btn.label|default(''),
89
attr: extra_btn.attr|default({})|merge({
@@ -20,6 +21,7 @@
2021
~ (is_password_input ? ' ibexa-input-text-wrapper--password')
2122
~ (type is defined ? " ibexa-input-text-wrapper--type-#{type}")
2223
~ (extra_btn.label ? ' ibexa-input-text-wrapper--extra-btn')
24+
~ (is_multiline ? ' ibexa-input-text-wrapper--multiline')
2325
)|trim
2426
}) %}
2527

src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,18 @@
268268

269269
{% block textarea_widget -%}
270270
{% set attr = attr|merge({class: (attr.class|default('') ~ ' ibexa-input ibexa-input--textarea')|trim}) %}
271-
{{- parent() -}}
271+
{%- set input_html -%}
272+
{{- parent() -}}
273+
{%- endset -%}
274+
{%- embed '@ibexadesign/ui/component/input_text.html.twig' with { is_multiline: true } -%}
275+
{% block content %}
276+
{{ input_html }}
277+
{% endblock %}
278+
279+
{% block actions %}
280+
{{ extra_actions_after|default(null)}}
281+
{% endblock %}
282+
{%- endembed -%}
272283
{%- endblock textarea_widget %}
273284

274285
{%- block richtext_widget -%}

0 commit comments

Comments
 (0)