UNPKG

handsontable

Version:

Handsontable is a JavaScript Data Grid available for React, Angular and Vue.

260 lines (246 loc) • 7.79 kB
import { addClass, removeClass, setAttribute } from "../../../helpers/dom/element.mjs"; import { A11Y_HIDDEN, A11Y_LABEL } from "../../../helpers/a11y.mjs"; import { getCheckboxElement } from "../utils/utils.mjs"; const classPrefix = 'ht-multi-select-editor'; const SEARCH_INPUT_WRAPPER_CLASS = `${classPrefix}-search-input-wrapper`; const SEARCH_ICON_CLASS = `${classPrefix}-search-icon`; const SEARCH_INPUT_CLASS = `${classPrefix}-search-input`; const SEPARATOR_CLASS = `${classPrefix}-separator`; const SEARCH_INPUT_PLACEHOLDER = 'Search...'; const SEARCH_INPUT_ARIA_LABEL = 'Search options'; const CHECKBOX_ID_PREFIX = `${classPrefix}-item-`; export const SELECTED_ITEM_CLASS = `${classPrefix}-item-selected`; /** * Applies visual selection state and checks the checkbox. * * @param {HTMLLIElement} itemElement Dropdown row element. */ export function selectItem(itemElement) { const checkbox = getCheckboxElement(itemElement); addClass(itemElement, SELECTED_ITEM_CLASS); if (!checkbox.checked) { checkbox.checked = true; } } /** * Clears selection classes and unchecks the checkbox. * * @param {HTMLLIElement} itemElement Dropdown row element. */ export function deselectItem(itemElement) { const checkbox = getCheckboxElement(itemElement); removeClass(itemElement, SELECTED_ITEM_CLASS); if (checkbox.checked) { checkbox.checked = false; } } /** * Creates the wrapper div for the search input. * * @param {object} options Options object. * @param {Document} options.root Root document element. * @returns {HTMLDivElement} */ export function createSearchInputWrapper(_ref) { let { root } = _ref; const wrapperElement = root.createElement('div'); wrapperElement.className = SEARCH_INPUT_WRAPPER_CLASS; return wrapperElement; } /** * Creates the search icon element. * * @param {object} options Options object. * @param {Document} options.root Root document element. * @returns {HTMLElement} */ export function createSearchIcon(_ref2) { let { root } = _ref2; const iconElement = root.createElement('div'); addClass(iconElement, SEARCH_ICON_CLASS); setAttribute(iconElement, [A11Y_HIDDEN()]); return iconElement; } /** * Creates the search input element. * * @param {object} options Options object. * @param {Document} options.root Root document element. * @returns {HTMLInputElement} */ export function createSearchInputElement(_ref3) { let { root } = _ref3; const inputElement = root.createElement('input'); setAttribute(inputElement, [A11Y_LABEL(SEARCH_INPUT_ARIA_LABEL), ['type', 'text'], ['size', 3], ['placeholder', SEARCH_INPUT_PLACEHOLDER], ['id', SEARCH_INPUT_CLASS]]); addClass(inputElement, SEARCH_INPUT_CLASS); return inputElement; } /** * Creates the separator line element. * * @param {object} options Options object. * @param {Document} options.root Root document element. * @returns {HTMLElement} */ export function createSeparatorElement(_ref4) { let { root } = _ref4; const separatorElement = root.createElement('div'); separatorElement.className = SEPARATOR_CLASS; return separatorElement; } /** * Creates the list element that holds dropdown items. * * @param {object} options Options object. * @param {Document} options.root Root document element. * @returns {HTMLUListElement} */ export function createListElement(_ref5) { let { root } = _ref5; return root.createElement('ul'); } /** * Gets the width of the dropdown. * * @param {object} options Options object. * @param {HTMLUListElement} options.dropdownListElement The dropdown list element. * @returns {number} Width of the dropdown. */ export function getDropdownWidth(_ref6) { let { dropdownListElement } = _ref6; return dropdownListElement.offsetWidth; } /** * Deselects all items in the dropdown. * * @param {object} options Options object. * @param {HTMLUListElement} options.dropdownListElement The dropdown list element. */ export function deselectAllItems(_ref7) { let { dropdownListElement } = _ref7; dropdownListElement.querySelectorAll(`.${SELECTED_ITEM_CLASS}`).forEach(itemElement => deselectItem(itemElement)); } /** * Defocuses the item at the given index. * * @param {object} options Options object. * @param {HTMLUListElement} options.dropdownListElement The dropdown list element. * @param {number} options.index Index of the item to defocus. */ export function defocusItem(_ref8) { let { dropdownListElement, index } = _ref8; const itemElement = dropdownListElement.children[index]; if (itemElement) { const checkbox = getCheckboxElement(itemElement); if (checkbox) { checkbox.blur(); } } } /** * Focuses the item at the given index. * * @param {object} options Options object. * @param {HTMLUListElement} options.dropdownListElement The dropdown list element. * @param {number} options.index Index of the item to focus. */ export function focusItemAt(_ref9) { let { dropdownListElement, index } = _ref9; const itemElement = dropdownListElement.children[index]; if (itemElement) { const checkbox = getCheckboxElement(itemElement); if (checkbox) { checkbox.focus(); } } } /** * Disables the unchecked checkboxes in the dropdown. * * @param {object} options Options object. * @param {HTMLUListElement} options.dropdownListElement The dropdown list element. */ export function disableUncheckedCheckboxes(_ref0) { let { dropdownListElement } = _ref0; dropdownListElement.querySelectorAll('input[type="checkbox"]:not(:checked)').forEach(checkbox => { checkbox.dataset.disabled = true; }); } /** * Enables all checkboxes in the dropdown. * * @param {object} options Options object. * @param {HTMLUListElement} options.dropdownListElement The dropdown list element. */ export function enableAllCheckboxes(_ref1) { let { dropdownListElement } = _ref1; dropdownListElement.querySelectorAll('input[type="checkbox"]').forEach(checkbox => { checkbox.dataset.disabled = false; }); } /** * Creates a single dropdown row with a checkbox and label. * * @param {object} options Options object. * @param {Document} options.rootDocument Root document element. * @param {string} options.instanceId Handsontable instance id. * @param {string} options.itemKey Key stored in the associated checkbox dataset. * @param {string} options.itemValue Text shown next to the checkbox. * @param {number} options.indexWithinList Index of the item within the list. * @param {boolean} [options.checked=false] Flag indicating whether the checkbox starts selected. * @param {boolean} [options.disabled=false] Flag indicating whether the checkbox starts disabled. * @returns {HTMLLIElement} */ export function createListItemElement(_ref10) { let { rootDocument, instanceId, itemKey, itemValue, indexWithinList, checked = false, disabled = false } = _ref10; const itemElement = rootDocument.createElement('li'); const innerContainer = rootDocument.createElement('div'); const checkboxElement = rootDocument.createElement('input'); const labelElement = rootDocument.createElement('label'); checkboxElement.id = `${instanceId}-${CHECKBOX_ID_PREFIX}${indexWithinList}`; checkboxElement.type = 'checkbox'; checkboxElement.dataset.value = itemValue; checkboxElement.dataset.index = indexWithinList; checkboxElement.dataset.disabled = checked ? false : disabled; if (itemKey) { checkboxElement.dataset.key = itemKey; } labelElement.htmlFor = checkboxElement.id; labelElement.textContent = itemValue; innerContainer.appendChild(checkboxElement); innerContainer.appendChild(labelElement); itemElement.appendChild(innerContainer); return itemElement; }