{"version":3,"file":"useKeyboardNavigableList-DDHj1U7Z.js","sources":["../../../app/javascript/shared/helpers/KeyboardHelpers.js","../../../app/javascript/dashboard/composables/useDetectKeyboardLayout.js","../../../node_modules/.pnpm/tinykeys@3.0.0/node_modules/tinykeys/dist/tinykeys.module.js","../../../app/javascript/dashboard/composables/useKeyboardEvents.js","../../../app/javascript/dashboard/composables/useKeyboardNavigableList.js"],"sourcesContent":["export const isEnter = e => {\n return e.key === 'Enter';\n};\n\nexport const isEscape = e => {\n return e.key === 'Escape';\n};\n\nexport const hasPressedShift = e => {\n return e.shiftKey;\n};\n\nexport const hasPressedCommand = e => {\n return e.metaKey;\n};\n\nexport const hasPressedEnterAndNotCmdOrShift = e => {\n return isEnter(e) && !hasPressedCommand(e) && !hasPressedShift(e);\n};\n\nexport const hasPressedCommandAndEnter = e => {\n return hasPressedCommand(e) && isEnter(e);\n};\n\n// If layout is QWERTZ then we add the Shift+keysToModify to fix an known issue\n// https://github.com/chatwoot/chatwoot/issues/9492\nexport const keysToModifyInQWERTZ = new Set(['Alt+KeyP', 'Alt+KeyL']);\n\nexport const LAYOUT_QWERTY = 'QWERTY';\nexport const LAYOUT_QWERTZ = 'QWERTZ';\nexport const LAYOUT_AZERTY = 'AZERTY';\n\n/**\n * Determines whether the active element is typeable.\n *\n * @param {KeyboardEvent} e - The keyboard event object.\n * @returns {boolean} `true` if the active element is typeable, `false` otherwise.\n *\n * @example\n * document.addEventListener('keydown', e => {\n * if (isActiveElementTypeable(e)) {\n * handleTypeableElement(e);\n * }\n * });\n */\nexport const isActiveElementTypeable = e => {\n /** @type {HTMLElement | null} */\n // @ts-ignore\n const activeElement = e.target || document.activeElement;\n\n return !!(\n activeElement?.tagName === 'INPUT' ||\n activeElement?.tagName === 'NINJA-KEYS' ||\n activeElement?.tagName === 'TEXTAREA' ||\n activeElement?.contentEditable === 'true' ||\n activeElement?.className?.includes('ProseMirror')\n );\n};\n","import {\n LAYOUT_QWERTY,\n LAYOUT_QWERTZ,\n LAYOUT_AZERTY,\n} from 'shared/helpers/KeyboardHelpers';\n\n/**\n * Detects the keyboard layout using a legacy method by creating a hidden input and dispatching a key event.\n * @returns {Promise} A promise that resolves to the detected keyboard layout.\n */\nasync function detectLegacy() {\n const input = document.createElement('input');\n input.style.position = 'fixed';\n input.style.top = '-100px';\n document.body.appendChild(input);\n input.focus();\n\n return new Promise(resolve => {\n const keyboardEvent = new KeyboardEvent('keypress', {\n key: 'y',\n keyCode: 89,\n which: 89,\n bubbles: true,\n cancelable: true,\n });\n\n const handler = e => {\n document.body.removeChild(input);\n document.removeEventListener('keypress', handler);\n if (e.key === 'z') {\n resolve(LAYOUT_QWERTY);\n } else if (e.key === 'y') {\n resolve(LAYOUT_QWERTZ);\n } else {\n resolve(LAYOUT_AZERTY);\n }\n };\n\n document.addEventListener('keypress', handler);\n input.dispatchEvent(keyboardEvent);\n });\n}\n\n/**\n * Detects the keyboard layout using the modern navigator.keyboard API.\n * @returns {Promise} A promise that resolves to the detected keyboard layout.\n */\nasync function detect() {\n const map = await navigator.keyboard.getLayoutMap();\n const q = map.get('KeyQ');\n const w = map.get('KeyW');\n const e = map.get('KeyE');\n const r = map.get('KeyR');\n const t = map.get('KeyT');\n const y = map.get('KeyY');\n\n return [q, w, e, r, t, y].join('').toUpperCase();\n}\n\n/**\n * Uses either the modern or legacy method to detect the keyboard layout, caching the result.\n * @returns {Promise} A promise that resolves to the detected keyboard layout.\n */\nexport async function useDetectKeyboardLayout() {\n const cachedLayout = window.cw_keyboard_layout;\n if (cachedLayout) {\n return cachedLayout;\n }\n\n const layout = navigator.keyboard ? await detect() : await detectLegacy();\n window.cw_keyboard_layout = layout;\n return layout;\n}\n","var t=[\"Shift\",\"Meta\",\"Alt\",\"Control\"],e=\"object\"==typeof navigator?navigator.platform:\"\",n=/Mac|iPod|iPhone|iPad/.test(e),o=n?\"Meta\":\"Control\",r=\"Win32\"===e?[\"Control\",\"Alt\"]:n?[\"Alt\"]:[];function i(t,e){return\"function\"==typeof t.getModifierState&&(t.getModifierState(e)||r.includes(e)&&t.getModifierState(\"AltGraph\"))}function a(t){return t.trim().split(\" \").map(function(t){var e=t.split(/\\b\\+/),n=e.pop(),r=n.match(/^\\((.+)\\)$/);return r&&(n=new RegExp(\"^\"+r[1]+\"$\")),[e=e.map(function(t){return\"$mod\"===t?o:t}),n]})}function u(e,n){var o=n[0],r=n[1];return!((r instanceof RegExp?!r.test(e.key)&&!r.test(e.code):r.toUpperCase()!==e.key.toUpperCase()&&r!==e.code)||o.find(function(t){return!i(e,t)})||t.find(function(t){return!o.includes(t)&&r!==t&&i(e,t)}))}function c(t,e){var n;void 0===e&&(e={});var o=null!=(n=e.timeout)?n:1e3,r=Object.keys(t).map(function(e){return[a(e),t[e]]}),c=new Map,f=null;return function(t){t instanceof KeyboardEvent&&(r.forEach(function(e){var n=e[0],o=e[1],r=c.get(n)||n;u(t,r[0])?r.length>1?c.set(n,r.slice(1)):(c.delete(n),o(t)):i(t,t.key)||c.delete(n)}),f&&clearTimeout(f),f=setTimeout(c.clear.bind(c),o))}}function f(t,e,n){var o=void 0===n?{}:n,r=o.event,i=void 0===r?\"keydown\":r,a=o.capture,u=c(e,{timeout:o.timeout});return t.addEventListener(i,u,a),function(){t.removeEventListener(i,u,a)}}export{c as createKeybindingsHandler,u as matchKeyBindingPress,a as parseKeybinding,f as tinykeys};\n//# sourceMappingURL=tinykeys.module.js.map\n","import {\n isActiveElementTypeable,\n isEscape,\n keysToModifyInQWERTZ,\n LAYOUT_QWERTZ,\n} from 'shared/helpers/KeyboardHelpers';\nimport { useDetectKeyboardLayout } from 'dashboard/composables/useDetectKeyboardLayout';\nimport { createKeybindingsHandler } from 'tinykeys';\nimport { onUnmounted, onMounted } from 'vue';\n\n/**\n * Determines if the keyboard event should be ignored based on the element type and handler settings.\n * @param {Event} e - The event object.\n * @param {Object|Function} handler - The handler configuration or function.\n * @returns {boolean} - True if the event should be ignored, false otherwise.\n */\nconst shouldIgnoreEvent = (e, handler) => {\n const isTypeable = isActiveElementTypeable(e);\n const allowOnFocusedInput =\n typeof handler === 'function' ? false : handler.allowOnFocusedInput;\n\n if (isTypeable) {\n if (isEscape(e)) {\n e.target.blur();\n }\n return !allowOnFocusedInput;\n }\n return false;\n};\n\n/**\n * Wraps the event handler to include custom logic before executing the handler.\n * @param {Function} handler - The original event handler.\n * @returns {Function} - The wrapped handler.\n */\nconst keydownWrapper = handler => {\n return e => {\n if (shouldIgnoreEvent(e, handler)) return;\n // extract the action to perform from the handler\n\n const actionToPerform =\n typeof handler === 'function' ? handler : handler.action;\n actionToPerform(e);\n };\n};\n\n/**\n * Wraps all provided keyboard events in handlers that respect the current keyboard layout.\n * @param {Object} events - The object containing event names and their handlers.\n * @returns {Object} - The object with event names possibly modified based on the keyboard layout and wrapped handlers.\n */\nasync function wrapEventsInKeybindingsHandler(events) {\n const wrappedEvents = {};\n const currentLayout = await useDetectKeyboardLayout();\n\n Object.keys(events).forEach(originalEventName => {\n const modifiedEventName =\n currentLayout === LAYOUT_QWERTZ &&\n keysToModifyInQWERTZ.has(originalEventName)\n ? `Shift+${originalEventName}`\n : originalEventName;\n\n wrappedEvents[modifiedEventName] = keydownWrapper(\n events[originalEventName]\n );\n });\n return wrappedEvents;\n}\n\n/**\n * Vue composable to handle keyboard events with support for different keyboard layouts.\n * @param {Object} keyboardEvents - The keyboard events to handle.\n */\nexport async function useKeyboardEvents(keyboardEvents) {\n let abortController = new AbortController();\n\n onMounted(async () => {\n if (!keyboardEvents) return;\n const wrappedEvents = await wrapEventsInKeybindingsHandler(keyboardEvents);\n const keydownHandler = createKeybindingsHandler(wrappedEvents);\n\n document.addEventListener('keydown', keydownHandler, {\n signal: abortController.signal,\n });\n });\n\n onUnmounted(() => {\n abortController.abort();\n });\n}\n","/**\n * This composable provides keyboard navigation functionality for list-like UI components\n * such as dropdowns, autocomplete suggestions, or any list of selectable items.\n *\n * TODO - Things that can be improved in the future\n * - The scrolling should be handled by the component instead of the consumer of this composable\n * it can be done if we know the item height.\n * - The focus should be trapped within the list.\n * - onSelect should be callback instead of a function that is passed\n */\nimport { useKeyboardEvents } from './useKeyboardEvents';\n\n/**\n * Wrap the action in a function that calls the action and prevents the default event behavior.\n * @param {Function} action - The action to be called.\n * @returns {{action: Function, allowOnFocusedInput: boolean}} An object containing the action and a flag to allow the event on focused input.\n */\nconst createAction = action => ({\n action: e => {\n action();\n e.preventDefault();\n },\n allowOnFocusedInput: true,\n});\n\n/**\n * Creates keyboard event handlers for navigation.\n * @param {Function} moveSelectionUp - Function to move selection up.\n * @param {Function} moveSelectionDown - Function to move selection down.\n * @param {Function} [onSelect] - Optional function to handle selection.\n * @param {import('vue').Ref} items - A ref to the array of selectable items.\n * @returns {Object.}\n */\nconst createKeyboardEvents = (\n moveSelectionUp,\n moveSelectionDown,\n onSelect,\n items\n) => {\n const events = {\n ArrowUp: createAction(moveSelectionUp),\n 'Control+KeyP': createAction(moveSelectionUp),\n ArrowDown: createAction(moveSelectionDown),\n 'Control+KeyN': createAction(moveSelectionDown),\n };\n\n // Adds an event handler for the Enter key if the onSelect function is provided.\n if (typeof onSelect === 'function') {\n events.Enter = createAction(() => items.value?.length > 0 && onSelect());\n }\n\n return events;\n};\n\n/**\n * Updates the selection index based on the current index, total number of items, and direction of movement.\n *\n * @param {number} currentIndex - The current index of the selected item.\n * @param {number} itemsLength - The total number of items in the list.\n * @param {string} direction - The direction of movement, either 'up' or 'down'.\n * @returns {number} The new index after moving in the specified direction.\n */\nconst updateSelectionIndex = (currentIndex, itemsLength, direction) => {\n // If the selected index is the first item, move to the last item\n // If the selected index is the last item, move to the first item\n if (direction === 'up') {\n return currentIndex === 0 ? itemsLength - 1 : currentIndex - 1;\n }\n return currentIndex === itemsLength - 1 ? 0 : currentIndex + 1;\n};\n\n/**\n * A composable for handling keyboard navigation in mention selection scenarios.\n *\n * @param {Object} options - The options for the composable.\n * @param {import('vue').Ref} options.elementRef - A ref to the DOM element that will receive keyboard events.\n * @param {import('vue').Ref} options.items - A ref to the array of selectable items.\n * @param {Function} [options.onSelect] - An optional function to be called when an item is selected.\n * @param {Function} options.adjustScroll - A function to adjust the scroll position after selection changes.\n * @param {import('vue').Ref} options.selectedIndex - A ref to the currently selected index.\n * @returns {{\n * moveSelectionUp: Function,\n * moveSelectionDown: Function\n * }} An object containing functions to move the selection up and down.\n */\nexport function useKeyboardNavigableList({\n items,\n onSelect,\n adjustScroll,\n selectedIndex,\n}) {\n const moveSelection = direction => {\n selectedIndex.value = updateSelectionIndex(\n selectedIndex.value,\n items.value.length,\n direction\n );\n adjustScroll();\n };\n\n const moveSelectionUp = () => moveSelection('up');\n const moveSelectionDown = () => moveSelection('down');\n\n const keyboardEvents = createKeyboardEvents(\n moveSelectionUp,\n moveSelectionDown,\n onSelect,\n items\n );\n\n useKeyboardEvents(keyboardEvents);\n\n return {\n moveSelectionUp,\n moveSelectionDown,\n };\n}\n"],"names":["isEnter","e","isEscape","hasPressedShift","hasPressedCommand","hasPressedEnterAndNotCmdOrShift","hasPressedCommandAndEnter","keysToModifyInQWERTZ","LAYOUT_QWERTY","LAYOUT_QWERTZ","LAYOUT_AZERTY","isActiveElementTypeable","activeElement","_a","detectLegacy","input","resolve","keyboardEvent","handler","detect","map","q","w","t","y","useDetectKeyboardLayout","cachedLayout","layout","n","o","r","i","a","u","c","f","shouldIgnoreEvent","isTypeable","allowOnFocusedInput","keydownWrapper","wrapEventsInKeybindingsHandler","events","wrappedEvents","currentLayout","originalEventName","modifiedEventName","useKeyboardEvents","keyboardEvents","abortController","onMounted","keydownHandler","createKeybindingsHandler","onUnmounted","createAction","action","createKeyboardEvents","moveSelectionUp","moveSelectionDown","onSelect","items","updateSelectionIndex","currentIndex","itemsLength","direction","useKeyboardNavigableList","adjustScroll","selectedIndex","moveSelection"],"mappings":"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","x_google_ignoreList":[2]}