MDL-80747 output: Inline labels in the single-select combobox widget

This commit is contained in:
Shamim Rezaie 2024-06-22 05:43:20 +10:00
parent c171c6ef6b
commit 0d23024ad0
6 changed files with 40 additions and 8 deletions

View File

@ -0,0 +1,9 @@
issueNumber: MDL-80747
notes:
core:
- message: >
The `core\output\select_menu` widget now supports a new feature: inline
labels. You can render the label inside the combobox widget by passing
`true` to the `$inlinelabel` parameter when calling the `->set_label()`
method.
type: improved

View File

@ -39,6 +39,9 @@ class select_menu implements renderable, templatable {
/** @var array Button label's attributes */
protected $labelattributes = [];
/** @var bool Whether the label is inline or not */
protected $inlinelabel = false;
/** @var string Name of the combobox element */
protected $name;
@ -61,10 +64,12 @@ class select_menu implements renderable, templatable {
*
* @param string $label The label.
* @param array $attributes List of attributes to apply on the label element.
* @param bool $inlinelabel Whether the label is inline or not.
*/
public function set_label(string $label, array $attributes = []) {
public function set_label(string $label, array $attributes = [], bool $inlinelabel = false) {
$this->label = $label;
$this->labelattributes = $attributes;
$this->inlinelabel = $inlinelabel;
}
/**
@ -161,6 +166,7 @@ class select_menu implements renderable, templatable {
$data = new \stdClass();
$data->baseid = \html_writer::random_id('select-menu');
$data->label = $this->label;
$data->inlinelabel = $this->inlinelabel;
$data->options = $this->flatten_options();
$data->selectedoption = $this->get_selected_option();
$data->name = $this->name;

View File

@ -85,11 +85,11 @@
}
}}
<div class="dropdown select-menu" id="{{baseid}}">
{{#label}}
{{#label}}{{^inlinelabel}}
<label id="{{baseid}}-label"{{#labelattributes}} {{name}}="{{value}}"{{/labelattributes}}>{{label}}</label>
{{/label}}
{{/inlinelabel}}{{/label}}
<div
class="btn dropdown-toggle"
class="btn dropdown-toggle{{#inlinelabel}} d-flex text-left align-items-center p-0{{/inlinelabel}}"
role="combobox"
data-toggle="dropdown"
{{#label}}aria-labelledby="{{baseid}}-label"{{/label}}
@ -99,7 +99,19 @@
data-input-element="{{baseid}}-input"
tabindex="0"
>
{{selectedoption}}
{{#inlinelabel}}
<div class="pr-3 text-truncate">
{{#label}}
<label class="d-block m-0 small" id="{{baseid}}-label"{{#labelattributes}} {{name}}="{{value}}"{{/labelattributes}}>{{label}}</label>
{{/label}}
<span class="font-weight-bold" data-selected-option>
{{selectedoption}}
</span>
</div>
{{/inlinelabel}}
{{^inlinelabel}}
{{selectedoption}}
{{/inlinelabel}}
</div>
<ul class="dropdown-menu" role="listbox" id="{{baseid}}-listbox" {{#label}}aria-labelledby="{{baseid}}-label"{{/label}}>
{{#options}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -380,7 +380,12 @@ const comboboxFix = () => {
if (combobox.hasAttribute('value')) {
combobox.value = option.dataset.shortText || option.textContent.replace(/[\n\r]+|[\s]{2,}/g, ' ').trim();
} else {
combobox.textContent = option.dataset.shortText || option.textContent;
const selectedOptionContainer = combobox.querySelector('[data-selected-option]');
if (selectedOptionContainer) {
selectedOptionContainer.textContent = option.dataset.shortText || option.textContent;
} else {
combobox.textContent = option.dataset.shortText || option.textContent;
}
}
if (combobox.dataset.inputElement) {