- commit
- d5e4dda73b8de33c3b0e9a3db30222662cb45aef
- parent
- 0eec7eb6e26a21eba9c06cf25b8ad90ff8a77a94
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2021-03-28 05:58
optgroup support
Diffstat
| M | README.md | 1 | - |
| M | select.css | 16 | ++++++++++++---- |
| M | select.js | 60 | ++++++++++++++++++++++++++++++++++++++++++++---------------- |
3 files changed, 56 insertions, 21 deletions
diff --git a/README.md b/README.md
@@ -17,7 +17,6 @@ The code is intentionally very simple and close to browser defaults. 17 17 ## Roadmap 18 18 19 19 - refactor constructor args20 -1 - optgroups21 20 - dynamic option creation 22 21 - localization 23 22 - allowClear
diff --git a/select.css b/select.css
@@ -29,22 +29,30 @@ 29 29 display: none; 30 30 } 31 3132 -1 .select__dropdown li {-1 32 .select__dropdown [role="option"], -1 33 .select__dropdown strong { 33 34 padding: 0.2em 0.4em; 34 35 white-space: nowrap; 35 36 overflow: hidden; 36 37 text-overflow: ellipsis; 37 38 cursor: default; 38 39 }39 -1 .select__dropdown li.select--selected,40 -1 .select__dropdown li:hover {-1 40 .select__dropdown [role="option"].select--selected, -1 41 .select__dropdown [role="option"]:hover { 41 42 background: rgba(128,128,128,.2); 42 43 color: inherit; 43 44 }44 -1 .select__dropdown li.select--has-focus {-1 45 .select__dropdown [role="option"].select--has-focus { 45 46 background: Highlight; 46 47 color: HighlightText; 47 48 } -1 49 .select__dropdown ul { -1 50 margin: 0; -1 51 padding: 0; -1 52 } -1 53 .select__dropdown ul [role="option"] { -1 54 padding-left: 2em; -1 55 } 48 56 49 57 .select__input > ul { 50 58 display: inline;
diff --git a/select.js b/select.js
@@ -83,8 +83,9 @@ export class Select {
83 83 }
84 84
85 85 update() {
86 -1 if (this.focus !== -1 && this.dropdown.children.length) {
87 -1 Array.from(this.dropdown.children).forEach((li, i) => {
-1 86 var options = this.dropdown.querySelectorAll('[role="option"]');
-1 87 if (this.focus !== -1 && options.length) {
-1 88 Array.from(options).forEach((li, i) => {
88 89 var op = this.original.options[this.indexMap[i]];
89 90 li.classList.toggle('select--has-focus', i === this.focus);
90 91 li.classList.toggle('select--selected', this.original.multiple && op.selected);
@@ -92,7 +93,7 @@ export class Select {
92 93 });
93 94 this.wrapper.setAttribute('aria-expanded', 'true');
94 95 this.input.setAttribute('aria-activedescendant', this.id + '_option_' + this.indexMap[this.focus]);
95 -1 this.dropdown.children[this.focus].scrollIntoView({block: 'nearest'});
-1 96 options[this.focus].scrollIntoView({block: 'nearest'});
96 97 } else {
97 98 this.wrapper.setAttribute('aria-expanded', 'false');
98 99 this.input.setAttribute('aria-activedescendant', '');
@@ -121,22 +122,48 @@ export class Select {
121 122 }
122 123 }
123 124
-1 125 createOption(op, i) {
-1 126 var li = document.createElement('li');
-1 127 li.id = this.id + '_option_' + i;
-1 128 li.textContent = op.label;
-1 129 li.setAttribute('role', 'option');
-1 130 li.onclick = () => {
-1 131 this.setValue(i, this.original.multiple);
-1 132 this.input.focus();
-1 133 };
-1 134 this.indexMap.push(i);
-1 135 return li;
-1 136 }
-1 137
124 138 open(complete) {
125 139 this.focus = 0;
126 140 this.dropdown.innerHTML = '';
127 141 this.indexMap = [];
128 -1 Array.from(this.original.options).forEach((op, i) => {
129 -1 if (op.label && (complete || this.isMatch(op.label))) {
130 -1 var li = document.createElement('li');
131 -1 li.id = this.id + '_option_' + i;
132 -1 li.textContent = op.label;
133 -1 li.setAttribute('role', 'option');
134 -1 li.onclick = () => {
135 -1 this.setValue(i, this.original.multiple);
136 -1 this.input.focus();
137 -1 };
138 -1 this.dropdown.append(li);
139 -1 this.indexMap.push(i);
-1 142 var i = 0;
-1 143 Array.from(this.original.children).forEach(child => {
-1 144 if (child.tagName === 'OPTION') {
-1 145 if (child.label && (complete || this.isMatch(child.label))) {
-1 146 this.dropdown.append(this.createOption(child, i));
-1 147 }
-1 148 i += 1;
-1 149 } else {
-1 150 var group = document.createElement('li');
-1 151 var label = document.createElement('strong');
-1 152 var ul = document.createElement('ul');
-1 153 group.setAttribute('role', 'group');
-1 154 label.textContent = child.label;
-1 155 ul.setAttribute('role', 'none');
-1 156 group.append(label);
-1 157 group.append(ul);
-1 158 Array.from(child.children).forEach(c => {
-1 159 if (c.label && (complete || this.isMatch(c.label))) {
-1 160 ul.append(this.createOption(c, i));
-1 161 }
-1 162 i += 1;
-1 163 });
-1 164 if (ul.children.length) {
-1 165 this.dropdown.append(group);
-1 166 }
140 167 }
141 168 });
142 169 this.update();
@@ -150,9 +177,10 @@ export class Select {
150 177 }
151 178
152 179 moveFocus(k) {
-1 180 var options = this.dropdown.querySelectorAll('[role="option"]');
153 181 this.focus += k;
154 182 this.focus = Math.max(this.focus, 0);
155 -1 this.focus = Math.min(this.focus, this.dropdown.children.length - 1);
-1 183 this.focus = Math.min(this.focus, options.length - 1);
156 184 this.update();
157 185 }
158 186