Skip to content

Commit a9f6330

Browse files
committed
refactor: improve HTML structure and formatting in ng-select component
- Enhanced readability by standardizing indentation and spacing throughout the template. - Cleaned up conditional templates and bindings for better clarity. - Ensured consistent formatting for improved maintainability. This refactor aligns with best practices for code structure and enhances the overall quality of the component.
1 parent b9eaa5a commit a9f6330

File tree

1 file changed

+173
-121
lines changed

1 file changed

+173
-121
lines changed
Lines changed: 173 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,187 @@
1-
<div (mousedown)="handleMousedown($event)" [class.ng-appearance-outline]="appearance() === 'outline'"
2-
[class.ng-has-value]="hasValue" class="ng-select-container">
3-
<div class="ng-value-container">
4-
@if ((selectedItems.length === 0 && !searchTerm) || (fixedPlaceholder() ?? config.fixedPlaceholder)) {
5-
<ng-template #defaultPlaceholderTemplate>
6-
<div class="ng-placeholder">{{ placeholder() ?? config.placeholder }}</div>
7-
</ng-template>
8-
<ng-template [ngTemplateOutlet]="placeholderTemplate() || defaultPlaceholderTemplate"> </ng-template>
9-
}
1+
<div
2+
(mousedown)="handleMousedown($event)"
3+
[class.ng-appearance-outline]="appearance() === 'outline'"
4+
[class.ng-has-value]="hasValue"
5+
class="ng-select-container">
6+
<div class="ng-value-container">
7+
@if ((selectedItems.length === 0 && !searchTerm) || (fixedPlaceholder() ?? config.fixedPlaceholder)) {
8+
<ng-template #defaultPlaceholderTemplate>
9+
<div class="ng-placeholder">{{ placeholder() ?? config.placeholder }}</div>
10+
</ng-template>
11+
<ng-template [ngTemplateOutlet]="placeholderTemplate() || defaultPlaceholderTemplate"> </ng-template>
12+
}
1013

11-
@if ((!multiLabelTemplate() || !multiple()) && selectedItems.length > 0) {
12-
@for (item of selectedItems; track trackByOption($index, item)) {
13-
<div [class.ng-value-disabled]="item.disabled" class="ng-value">
14-
<ng-template #defaultLabelTemplate>
15-
<span class="ng-value-icon left" (click)="unselect(item)" aria-hidden="true">×</span>
16-
<span class="ng-value-label" [ngItemLabel]="item.label" [escape]="escapeHTML"></span>
17-
</ng-template>
18-
<ng-template [ngTemplateOutlet]="labelTemplate() || defaultLabelTemplate"
19-
[ngTemplateOutletContext]="{ item: item.value, clear: clearItem, label: item.label }">
20-
</ng-template>
21-
</div>
22-
}
23-
}
14+
@if ((!multiLabelTemplate() || !multiple()) && selectedItems.length > 0) {
15+
@for (item of selectedItems; track trackByOption($index, item)) {
16+
<div [class.ng-value-disabled]="item.disabled" class="ng-value">
17+
<ng-template #defaultLabelTemplate>
18+
<span class="ng-value-icon left" (click)="unselect(item)" aria-hidden="true">×</span>
19+
<span class="ng-value-label" [ngItemLabel]="item.label" [escape]="escapeHTML"></span>
20+
</ng-template>
21+
<ng-template
22+
[ngTemplateOutlet]="labelTemplate() || defaultLabelTemplate"
23+
[ngTemplateOutletContext]="{ item: item.value, clear: clearItem, label: item.label }">
24+
</ng-template>
25+
</div>
26+
}
27+
}
2428

25-
@if (multiple() && multiLabelTemplate() && selectedValues.length > 0) {
26-
<ng-template [ngTemplateOutlet]="multiLabelTemplate()"
27-
[ngTemplateOutletContext]="{ items: selectedValues, clear: clearItem }">
28-
</ng-template>
29-
}
29+
@if (multiple() && multiLabelTemplate() && selectedValues.length > 0) {
30+
<ng-template [ngTemplateOutlet]="multiLabelTemplate()" [ngTemplateOutletContext]="{ items: selectedValues, clear: clearItem }">
31+
</ng-template>
32+
}
3033

31-
<div class="ng-input">
32-
<input #searchInput (blur)="onInputBlur($event)" (change)="$event.stopPropagation()"
33-
(compositionend)="onCompositionEnd(searchInput.value)" (compositionstart)="onCompositionStart()"
34-
(focus)="onInputFocus($event)" (input)="filter(searchInput.value)"
35-
[attr.aria-activedescendant]="isOpen() ? itemsList?.markedItem?.htmlId : null"
36-
[attr.aria-controls]="isOpen() ? dropdownId : null" [attr.aria-expanded]="isOpen()"
37-
[attr.aria-label]="ariaLabel()" [attr.id]="labelForId()" [attr.tabindex]="tabIndex()"
38-
[disabled]="disabled()" [readOnly]="!searchable() || itemsList.maxItemsSelected"
39-
[value]="searchTerm ?? ''" aria-autocomplete="list" role="combobox" />
40-
</div>
41-
</div>
34+
<div class="ng-input">
35+
<input
36+
#searchInput
37+
(blur)="onInputBlur($event)"
38+
(change)="$event.stopPropagation()"
39+
(compositionend)="onCompositionEnd(searchInput.value)"
40+
(compositionstart)="onCompositionStart()"
41+
(focus)="onInputFocus($event)"
42+
(input)="filter(searchInput.value)"
43+
[attr.aria-activedescendant]="isOpen() ? itemsList?.markedItem?.htmlId : null"
44+
[attr.aria-controls]="isOpen() ? dropdownId : null"
45+
[attr.aria-expanded]="isOpen()"
46+
[attr.aria-label]="ariaLabel()"
47+
[attr.id]="labelForId()"
48+
[attr.tabindex]="tabIndex()"
49+
[disabled]="disabled()"
50+
[readOnly]="!searchable() || itemsList.maxItemsSelected"
51+
[value]="searchTerm ?? ''"
52+
aria-autocomplete="list"
53+
role="combobox" />
54+
</div>
55+
</div>
4256

43-
@if (loading()) {
44-
<ng-template #defaultLoadingSpinnerTemplate>
45-
<div class="ng-spinner-loader"></div>
46-
</ng-template>
47-
<ng-template [ngTemplateOutlet]="loadingSpinnerTemplate() || defaultLoadingSpinnerTemplate"></ng-template>
48-
}
57+
@if (loading()) {
58+
<ng-template #defaultLoadingSpinnerTemplate>
59+
<div class="ng-spinner-loader"></div>
60+
</ng-template>
61+
<ng-template [ngTemplateOutlet]="loadingSpinnerTemplate() || defaultLoadingSpinnerTemplate"></ng-template>
62+
}
4963

50-
@if (showClear()) {
51-
@if (clearButtonTemplate()) {
52-
<ng-container [ngTemplateOutlet]="clearButtonTemplate()"></ng-container>
53-
} @else {
54-
<span class="ng-clear-wrapper" role="button" tabindex="0" [attr.tabindex]="tabFocusOnClear() ? 0 : -1"
55-
title="{{ clearAllText() || config.clearAllText }}" #clearButton (click)="handleClearClick($event)">
56-
<span class="ng-clear" aria-hidden="true">×</span>
57-
</span>
58-
}
59-
}
64+
@if (showClear()) {
65+
@if (clearButtonTemplate()) {
66+
<ng-container [ngTemplateOutlet]="clearButtonTemplate()"></ng-container>
67+
} @else {
68+
<span
69+
class="ng-clear-wrapper"
70+
role="button"
71+
tabindex="0"
72+
[attr.tabindex]="tabFocusOnClear() ? 0 : -1"
73+
title="{{ clearAllText() || config.clearAllText }}"
74+
#clearButton
75+
(click)="handleClearClick($event)">
76+
<span class="ng-clear" aria-hidden="true">×</span>
77+
</span>
78+
}
79+
}
6080

61-
<span class="ng-arrow-wrapper">
62-
<span class="ng-arrow"></span>
63-
</span>
81+
<span class="ng-arrow-wrapper">
82+
<span class="ng-arrow"></span>
83+
</span>
6484
</div>
6585

6686
@if (isOpen()) {
67-
@let appendToValue = appendTo() || config.appendTo;
68-
<ng-dropdown-panel class="ng-dropdown-panel" [virtualScroll]="virtualScroll() ?? !config.disableVirtualScroll ?? false"
69-
[bufferAmount]="bufferAmount()" [appendTo]="appendToValue" [position]="dropdownPosition()"
70-
[headerTemplate]="headerTemplate()" [footerTemplate]="footerTemplate()" [filterValue]="searchTerm"
71-
[items]="itemsList.filteredItems" [markedItem]="itemsList.markedItem" (update)="viewPortItems = $event"
72-
(scroll)="scroll.emit($event)" (scrollToEnd)="scrollToEnd.emit($event)" (outsideClick)="close()"
73-
[class.ng-select-multiple]="multiple()" [class]="appendToValue ? (ngClass() ? ngClass() : classes) : null"
74-
[id]="dropdownId" [ariaLabelDropdown]="ariaLabelDropdown()">
75-
<ng-container>
76-
@for (item of viewPortItems; track trackByOption($index, item)) {
77-
<div class="ng-option" [attr.role]="item.children ? 'group' : 'option'" (click)="toggleItem(item)"
78-
(mouseover)="onItemHover(item)" [class.ng-option-disabled]="item.disabled"
79-
[class.ng-option-selected]="item.selected" [class.ng-optgroup]="item.children"
80-
[class.ng-option]="!item.children" [class.ng-option-child]="!!item.parent"
81-
[class.ng-option-marked]="item === itemsList.markedItem" [attr.aria-selected]="item.selected"
82-
[attr.id]="item?.htmlId" [attr.aria-setsize]="itemsList.filteredItems.length"
83-
[attr.aria-posinset]="item.index + 1">
84-
<ng-template #defaultOptionTemplate>
85-
<span class="ng-option-label" [ngItemLabel]="item.label" [escape]="escapeHTML"></span>
86-
</ng-template>
87-
<ng-template [ngTemplateOutlet]="
87+
@let appendToValue = appendTo() || config.appendTo;
88+
<ng-dropdown-panel
89+
class="ng-dropdown-panel"
90+
[virtualScroll]="virtualScroll() ?? !config.disableVirtualScroll ?? false"
91+
[bufferAmount]="bufferAmount()"
92+
[appendTo]="appendToValue"
93+
[position]="dropdownPosition()"
94+
[headerTemplate]="headerTemplate()"
95+
[footerTemplate]="footerTemplate()"
96+
[filterValue]="searchTerm"
97+
[items]="itemsList.filteredItems"
98+
[markedItem]="itemsList.markedItem"
99+
(update)="viewPortItems = $event"
100+
(scroll)="scroll.emit($event)"
101+
(scrollToEnd)="scrollToEnd.emit($event)"
102+
(outsideClick)="close()"
103+
[class.ng-select-multiple]="multiple()"
104+
[class]="appendToValue ? (ngClass() ? ngClass() : classes) : null"
105+
[id]="dropdownId"
106+
[ariaLabelDropdown]="ariaLabelDropdown()">
107+
<ng-container>
108+
@for (item of viewPortItems; track trackByOption($index, item)) {
109+
<div
110+
class="ng-option"
111+
[attr.role]="item.children ? 'group' : 'option'"
112+
(click)="toggleItem(item)"
113+
(mouseover)="onItemHover(item)"
114+
[class.ng-option-disabled]="item.disabled"
115+
[class.ng-option-selected]="item.selected"
116+
[class.ng-optgroup]="item.children"
117+
[class.ng-option]="!item.children"
118+
[class.ng-option-child]="!!item.parent"
119+
[class.ng-option-marked]="item === itemsList.markedItem"
120+
[attr.aria-selected]="item.selected"
121+
[attr.id]="item?.htmlId"
122+
[attr.aria-setsize]="itemsList.filteredItems.length"
123+
[attr.aria-posinset]="item.index + 1">
124+
<ng-template #defaultOptionTemplate>
125+
<span class="ng-option-label" [ngItemLabel]="item.label" [escape]="escapeHTML"></span>
126+
</ng-template>
127+
<ng-template
128+
[ngTemplateOutlet]="
88129
item.children ? optgroupTemplate() || defaultOptionTemplate : optionTemplate() || defaultOptionTemplate
89-
" [ngTemplateOutletContext]="{ item: item.value, item$: item, index: item.index, searchTerm: searchTerm }">
90-
</ng-template>
91-
</div>
92-
}
93-
@if (showAddTag) {
94-
<div class="ng-option" [class.ng-option-marked]="!itemsList.markedItem" (mouseover)="itemsList.unmarkItem()"
95-
role="option" (click)="selectTag()">
96-
<ng-template #defaultTagTemplate>
97-
<span><span class="ng-tag-label">{{ addTagText() || config.addTagText }}</span>"{{ searchTerm }}"</span>
98-
</ng-template>
99-
<ng-template [ngTemplateOutlet]="tagTemplate() || defaultTagTemplate"
100-
[ngTemplateOutletContext]="{ searchTerm: searchTerm }">
101-
</ng-template>
102-
</div>
103-
}
104-
</ng-container>
105-
@if (showNoItemsFound()) {
106-
<ng-template #defaultNotFoundTemplate>
107-
<div class="ng-option ng-option-disabled">{{ notFoundText() ?? config.notFoundText }}</div>
108-
</ng-template>
109-
<ng-template [ngTemplateOutlet]="notFoundTemplate() || defaultNotFoundTemplate"
110-
[ngTemplateOutletContext]="{ searchTerm: searchTerm }">
111-
</ng-template>
112-
}
113-
@if (showTypeToSearch()) {
114-
<ng-template #defaultTypeToSearchTemplate>
115-
<div class="ng-option ng-option-disabled">{{ typeToSearchText() || config.typeToSearchText }}</div>
116-
</ng-template>
117-
<ng-template [ngTemplateOutlet]="typeToSearchTemplate() || defaultTypeToSearchTemplate"></ng-template>
118-
}
119-
@if (loading() && itemsList.filteredItems.length === 0) {
120-
<ng-template #defaultLoadingTextTemplate>
121-
<div class="ng-option ng-option-disabled">{{ loadingText() || config.loadingText }}</div>
122-
</ng-template>
123-
<ng-template [ngTemplateOutlet]="loadingTextTemplate() || defaultLoadingTextTemplate"
124-
[ngTemplateOutletContext]="{ searchTerm: searchTerm }">
125-
</ng-template>
126-
}
127-
</ng-dropdown-panel>
130+
"
131+
[ngTemplateOutletContext]="{ item: item.value, item$: item, index: item.index, searchTerm: searchTerm }">
132+
</ng-template>
133+
</div>
134+
}
135+
@if (showAddTag) {
136+
<div
137+
class="ng-option"
138+
[class.ng-option-marked]="!itemsList.markedItem"
139+
(mouseover)="itemsList.unmarkItem()"
140+
role="option"
141+
(click)="selectTag()">
142+
<ng-template #defaultTagTemplate>
143+
<span
144+
><span class="ng-tag-label">{{ addTagText() || config.addTagText }}</span
145+
>"{{ searchTerm }}"</span
146+
>
147+
</ng-template>
148+
<ng-template
149+
[ngTemplateOutlet]="tagTemplate() || defaultTagTemplate"
150+
[ngTemplateOutletContext]="{ searchTerm: searchTerm }">
151+
</ng-template>
152+
</div>
153+
}
154+
</ng-container>
155+
@if (showNoItemsFound()) {
156+
<ng-template #defaultNotFoundTemplate>
157+
<div class="ng-option ng-option-disabled">{{ notFoundText() ?? config.notFoundText }}</div>
158+
</ng-template>
159+
<ng-template
160+
[ngTemplateOutlet]="notFoundTemplate() || defaultNotFoundTemplate"
161+
[ngTemplateOutletContext]="{ searchTerm: searchTerm }">
162+
</ng-template>
163+
}
164+
@if (showTypeToSearch()) {
165+
<ng-template #defaultTypeToSearchTemplate>
166+
<div class="ng-option ng-option-disabled">{{ typeToSearchText() || config.typeToSearchText }}</div>
167+
</ng-template>
168+
<ng-template [ngTemplateOutlet]="typeToSearchTemplate() || defaultTypeToSearchTemplate"></ng-template>
169+
}
170+
@if (loading() && itemsList.filteredItems.length === 0) {
171+
<ng-template #defaultLoadingTextTemplate>
172+
<div class="ng-option ng-option-disabled">{{ loadingText() || config.loadingText }}</div>
173+
</ng-template>
174+
<ng-template
175+
[ngTemplateOutlet]="loadingTextTemplate() || defaultLoadingTextTemplate"
176+
[ngTemplateOutletContext]="{ searchTerm: searchTerm }">
177+
</ng-template>
178+
}
179+
</ng-dropdown-panel>
128180
}
129181

130182
<!-- Always present aria-live region -->
131183
<div aria-atomic="true" aria-live="polite" class="ng-visually-hidden" role="status">
132-
@if (isOpen() && showNoItemsFound()) {
133-
{{ notFoundText() ?? config.notFoundText }}
134-
}
135-
</div>
184+
@if (isOpen() && showNoItemsFound()) {
185+
{{ notFoundText() ?? config.notFoundText }}
186+
}
187+
</div>

0 commit comments

Comments
 (0)