123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- const DropdownIcon = "<svg viewbox=\"0 0 18 18\"><polygon class=\"ql-stroke\" points=\"7 11 9 13 11 11 7 11\"/><polygon class=\"ql-stroke\" points=\"7 7 9 5 11 7 7 7\"/></svg>";
- let optionsCounter = 0;
- function toggleAriaAttribute(element, attribute) {
- element.setAttribute(attribute, `${!(element.getAttribute(attribute) === 'true')}`);
- }
- class Picker {
- constructor(select) {
- this.select = select;
- this.container = document.createElement('span');
- this.buildPicker();
- this.select.style.display = 'none';
- // @ts-expect-error Fix me later
- this.select.parentNode.insertBefore(this.container, this.select);
- this.label.addEventListener('mousedown', () => {
- this.togglePicker();
- });
- this.label.addEventListener('keydown', event => {
- switch (event.key) {
- case 'Enter':
- this.togglePicker();
- break;
- case 'Escape':
- this.escape();
- event.preventDefault();
- break;
- default:
- }
- });
- this.select.addEventListener('change', this.update.bind(this));
- }
- togglePicker() {
- this.container.classList.toggle('ql-expanded');
- // Toggle aria-expanded and aria-hidden to make the picker accessible
- toggleAriaAttribute(this.label, 'aria-expanded');
- // @ts-expect-error
- toggleAriaAttribute(this.options, 'aria-hidden');
- }
- buildItem(option) {
- const item = document.createElement('span');
- // @ts-expect-error
- item.tabIndex = '0';
- item.setAttribute('role', 'button');
- item.classList.add('ql-picker-item');
- const value = option.getAttribute('value');
- if (value) {
- item.setAttribute('data-value', value);
- }
- if (option.textContent) {
- item.setAttribute('data-label', option.textContent);
- }
- item.addEventListener('click', () => {
- this.selectItem(item, true);
- });
- item.addEventListener('keydown', event => {
- switch (event.key) {
- case 'Enter':
- this.selectItem(item, true);
- event.preventDefault();
- break;
- case 'Escape':
- this.escape();
- event.preventDefault();
- break;
- default:
- }
- });
- return item;
- }
- buildLabel() {
- const label = document.createElement('span');
- label.classList.add('ql-picker-label');
- label.innerHTML = DropdownIcon;
- // @ts-expect-error
- label.tabIndex = '0';
- label.setAttribute('role', 'button');
- label.setAttribute('aria-expanded', 'false');
- this.container.appendChild(label);
- return label;
- }
- buildOptions() {
- const options = document.createElement('span');
- options.classList.add('ql-picker-options');
- // Don't want screen readers to read this until options are visible
- options.setAttribute('aria-hidden', 'true');
- // @ts-expect-error
- options.tabIndex = '-1';
- // Need a unique id for aria-controls
- options.id = `ql-picker-options-${optionsCounter}`;
- optionsCounter += 1;
- this.label.setAttribute('aria-controls', options.id);
- // @ts-expect-error
- this.options = options;
- Array.from(this.select.options).forEach(option => {
- const item = this.buildItem(option);
- options.appendChild(item);
- if (option.selected === true) {
- this.selectItem(item);
- }
- });
- this.container.appendChild(options);
- }
- buildPicker() {
- Array.from(this.select.attributes).forEach(item => {
- this.container.setAttribute(item.name, item.value);
- });
- this.container.classList.add('ql-picker');
- this.label = this.buildLabel();
- this.buildOptions();
- }
- escape() {
- // Close menu and return focus to trigger label
- this.close();
- // Need setTimeout for accessibility to ensure that the browser executes
- // focus on the next process thread and after any DOM content changes
- setTimeout(() => this.label.focus(), 1);
- }
- close() {
- this.container.classList.remove('ql-expanded');
- this.label.setAttribute('aria-expanded', 'false');
- // @ts-expect-error
- this.options.setAttribute('aria-hidden', 'true');
- }
- selectItem(item) {
- let trigger = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
- const selected = this.container.querySelector('.ql-selected');
- if (item === selected) return;
- if (selected != null) {
- selected.classList.remove('ql-selected');
- }
- if (item == null) return;
- item.classList.add('ql-selected');
- // @ts-expect-error Fix me later
- this.select.selectedIndex = Array.from(item.parentNode.children).indexOf(item);
- if (item.hasAttribute('data-value')) {
- // @ts-expect-error Fix me later
- this.label.setAttribute('data-value', item.getAttribute('data-value'));
- } else {
- this.label.removeAttribute('data-value');
- }
- if (item.hasAttribute('data-label')) {
- // @ts-expect-error Fix me later
- this.label.setAttribute('data-label', item.getAttribute('data-label'));
- } else {
- this.label.removeAttribute('data-label');
- }
- if (trigger) {
- this.select.dispatchEvent(new Event('change'));
- this.close();
- }
- }
- update() {
- let option;
- if (this.select.selectedIndex > -1) {
- const item =
- // @ts-expect-error Fix me later
- this.container.querySelector('.ql-picker-options').children[this.select.selectedIndex];
- option = this.select.options[this.select.selectedIndex];
- // @ts-expect-error
- this.selectItem(item);
- } else {
- this.selectItem(null);
- }
- const isActive = option != null && option !== this.select.querySelector('option[selected]');
- this.label.classList.toggle('ql-active', isActive);
- }
- }
- export default Picker;
- //# sourceMappingURL=picker.js.map
|