carbon-custom-elements
Version:
A Carbon Design System variant that's as easy to use as native HTML elements, with no framework tax, no framework silo.
1 lines • 7.02 kB
Source Map (JSON)
{"version":3,"sources":["components/date-picker/focus-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAEtD,OAAO,MAAM,MAAM,+BAA+B,CAAC;AACnD,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,SAAS,EAAE,iBAAiB,CAAC;IAE7B;;OAEG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,oCAAqC,SAAQ,iBAAiB;IAC7E;;OAEG;IACH,+BAA+B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhD;;OAEG;IACH,sCAAsC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvD;;OAEG;IACH,oCAAoC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAErD;;OAEG;IACH,oCAAoC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAErD;;OAEG;IACH,kCAAkC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnD;;OAEG;IACH,eAAe,CAAC,EAAE,gBAAgB,CAAC;CACpC;;AAED;;;GAGG;AACH,wBA4GE","file":"focus-plugin.d.ts","sourcesContent":["/**\n * @license\n *\n * Copyright IBM Corp. 2019\n *\n * This source code is licensed under the Apache-2.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { Instance as FlatpickrInstance } from 'flatpickr/dist/types/instance';\nimport { Plugin } from 'flatpickr/dist/types/options';\nimport on from 'carbon-components/es/globals/js/misc/on';\nimport Handle from '../../globals/internal/handle';\nimport BXDatePickerInput from './date-picker-input';\n\n/**\n * The configuration for the Flatpickr plugin to set CSS classes specific to this design system.\n */\nexport interface DatePickerFocusPluginConfig {\n /**\n * The input box to enter starting date.\n */\n inputFrom: BXDatePickerInput;\n\n /**\n * The input box to enter end date.\n */\n inputTo?: BXDatePickerInput;\n}\n\n/**\n * `FlatpickrInstance` with additional properties used for `carbonFlatpickrFocusPlugin`.\n */\nexport interface ExtendedFlatpickrInstanceFocusPlugin extends FlatpickrInstance {\n /**\n * The handle for `blur` event handler in calendar dropdown.\n */\n _hBXCEDatePickerFocusPluginBlur?: Handle | null;\n\n /**\n * The handle for `keydown` event handler in the `<input>` for the starting date.\n */\n _hBXCEDatePickerFocusPluginKeydownFrom?: Handle | null;\n\n /**\n * The handle for `keydown` event handler in the `<input>` for the end date.\n */\n _hBXCEDatePickerFocusPluginKeydownTo?: Handle | null;\n\n /**\n * The handle for `focus` event handler in the `<input>` for the starting date.\n */\n _hBXCEDatePickerFocusPluginFocusFrom?: Handle | null;\n\n /**\n * The handle for `focus` event handler in the `<input>` for the end date.\n */\n _hBXCEDatePickerFocusPluginFocusTo?: Handle | null;\n\n /**\n * Lastly focused `<input>` for starting/end date.\n */\n _lastFocusInput?: HTMLInputElement;\n}\n\n/**\n * @param config Plugin configuration.\n * @returns A Flatpickr plugin to manage focus to align with the UX pattern in our design system.\n */\nexport default (config: DatePickerFocusPluginConfig): Plugin => (fp: ExtendedFlatpickrInstanceFocusPlugin) => {\n /**\n * Focuses on calendar dropdown.\n */\n const focusCalendar = () => {\n const { calendarContainer, selectedDateElem, todayDateElem } = fp;\n (selectedDateElem || todayDateElem || calendarContainer).focus();\n };\n\n /**\n * Handles `blur` event to move the focus back to the `<input>`.\n */\n const handleBlur = ({ target, relatedTarget }: FocusEvent) => {\n // Obtains `beingUpdated` up-front because it'll be flushed out shortly\n const { calendarContainer, isOpen } = fp;\n if (isOpen && calendarContainer.contains(target as Node) && !calendarContainer.contains(relatedTarget as Node)) {\n Promise.resolve().then(() => {\n const rootNode = (target as Node).getRootNode();\n // This `blur` event handler can be called from Flatpickr's code cleaning up calenar dropdown's DOM,\n // and changing focus in such condition causes removing an orphaned DOM node,\n // because Flatpickr redraws the calendar dropdown when the `<input>` gets focus.\n if (rootNode.nodeType === Node.DOCUMENT_NODE || rootNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n if (fp._lastFocusInput === config.inputTo) {\n config.inputTo!.focus();\n } else {\n config.inputFrom.focus();\n }\n // Closing after moving focus. Reversing the order will cause re-opening calendar dropdown upon focusing\n fp.close();\n }\n });\n }\n };\n\n /**\n * Handles `keydown` event to move focus on calendar dropdown.\n */\n const handleInputKeydown = (event: KeyboardEvent) => {\n const { key } = event;\n if (key === 'ArrowDown' || key === 'Down' || key === 'Enter') {\n event.preventDefault();\n fp.open();\n if (key !== 'Enter') {\n focusCalendar();\n } else {\n // Hitting Enter key blurs the `<input>`, causing any element to lose focus\n setTimeout(focusCalendar, 0);\n }\n }\n };\n\n /**\n * Handles `focus` event on `<input>` for starting/end date to track the lastly focused one.\n */\n const handleInputFocus = ({ target }: FocusEvent) => {\n fp._lastFocusInput = target as HTMLInputElement;\n };\n\n /**\n * Releases event listeners used in this Flatpickr plugin.\n */\n const release = () => {\n if (fp._hBXCEDatePickerFocusPluginBlur) {\n fp._hBXCEDatePickerFocusPluginBlur = fp._hBXCEDatePickerFocusPluginBlur.release();\n }\n if (fp._hBXCEDatePickerFocusPluginFocusTo) {\n fp._hBXCEDatePickerFocusPluginFocusTo = fp._hBXCEDatePickerFocusPluginFocusTo.release();\n }\n if (fp._hBXCEDatePickerFocusPluginFocusFrom) {\n fp._hBXCEDatePickerFocusPluginFocusFrom = fp._hBXCEDatePickerFocusPluginFocusFrom.release();\n }\n if (fp._hBXCEDatePickerFocusPluginKeydownTo) {\n fp._hBXCEDatePickerFocusPluginKeydownTo = fp._hBXCEDatePickerFocusPluginKeydownTo.release();\n }\n if (fp._hBXCEDatePickerFocusPluginKeydownFrom) {\n fp._hBXCEDatePickerFocusPluginKeydownFrom = fp._hBXCEDatePickerFocusPluginKeydownFrom.release();\n }\n };\n\n /**\n * Sets up event listeners used for this Flatpickr plugin.\n */\n const init = () => {\n release();\n const { inputFrom, inputTo } = config;\n fp._hBXCEDatePickerFocusPluginBlur = on(fp.calendarContainer, 'blur', handleBlur, true);\n fp._hBXCEDatePickerFocusPluginKeydownFrom = on(inputFrom, 'keydown', handleInputKeydown);\n if (inputTo) {\n fp._hBXCEDatePickerFocusPluginKeydownTo = on(inputTo, 'keydown', handleInputKeydown);\n }\n fp._hBXCEDatePickerFocusPluginFocusFrom = on(inputFrom, 'focus', handleInputFocus);\n if (inputTo) {\n fp._hBXCEDatePickerFocusPluginFocusTo = on(inputTo, 'focus', handleInputFocus);\n }\n };\n\n /**\n * Registers this Flatpickr plugin.\n * @param calendar The Flatpickr instance.\n */\n const register = () => {\n fp.loadedPlugins.push('carbonFlatpickrFocusPlugin');\n };\n\n return {\n onReady: [register, init],\n onDestroy: release,\n };\n};\n"]}