PageSourceSearch

https://site.fr/_static/8c8af5c529149f32/scripts/ui/options-dropdown.js

js site.fr collected 2026-09-24 18:21:20 UTC 2,585 bytes, 77 lines download raw bytes

1import { createDropdown, getUniqueDropdownMenuId } from './dropdown.js';
2
3const createOptionsDropdownController = ({
4  dropdown,
5  trigger,
6  menuIdFallback,
7  menuDataAttribute,
8  menuZIndexClass = 'z-60',
9  getOptions,
10  getSelectedValue,
11  onSelect,
12} = {}) => {
13  if (!(dropdown instanceof HTMLElement) || !(trigger instanceof HTMLButtonElement)) {
14    return null;
15  }
16
17  const menuId = getUniqueDropdownMenuId(trigger.getAttribute('aria-controls') || menuIdFallback);
18  const spacingValue = dropdown.getAttribute('data-dropdown-spacing');
19  const parsedSpacing = spacingValue ? Number(spacingValue) : NaN;
20  const spacing = Number.isFinite(parsedSpacing) ? parsedSpacing : undefined;
21  const menuClassNameBase = dropdown.getAttribute('data-dropdown-content-class') || '';
22  const itemClassName = (dropdown.getAttribute('data-dropdown-item-class') || '').trim();
23
24  trigger.setAttribute('aria-controls', menuId);
25
26  return createDropdown({
27    dropdown,
28    trigger,
29    menuId,
30    spacing,
31    menuClassName: `fixed ${menuZIndexClass} ${menuClassNameBase}`.trim(),
32    menuAttributes: {
33      role: 'listbox',
34      'data-select-menu': '',
35      [menuDataAttribute]: '',
36    },
37    renderMenu: (menuEl, setOpen) => {
38      menuEl.replaceChildren();
39
40      const selectedValue = String(getSelectedValue?.() || '');
41      (typeof getOptions === 'function' ? getOptions() : []).forEach((option) => {
42        const item = document.createElement('button');
43        item.type = 'button';
44        item.tabIndex = -1;
45        item.className = option?.disabled
46          ? `${itemClassName} cursor-not-allowed text-gray hover:text-gray focus:bg-transparent focus-visible:bg-transparent`
47          : itemClassName;
48        item.textContent = String(option?.label || '');
49        item.setAttribute('role', 'option');
50        item.dataset.dropdownItem = '';
51        item.dataset.selectOption = '';
52        item.dataset.label = String(option?.label || '');
53
54        if (String(option?.value || '') === selectedValue) {
55          item.setAttribute('aria-selected', 'true');
56        }
57
58        if (option?.disabled) {
59          item.disabled = true;
60          item.setAttribute('aria-disabled', 'true');
61        } else {
62          item.addEventListener('click', () => {
63            setOpen(false, { restoreFocus: true });
64            onSelect?.(option?.value);
65          });
66        }
67
68        menuEl.appendChild(item);
69      });
70
71      const rect = trigger.getBoundingClientRect();
72      menuEl.style.minWidth = `${rect.width}px`;
73    },
74  });
75};
76
77export { createOptionsDropdownController };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.