element-plus
Version:
A Component Library for Vue 3
1 lines • 5.66 kB
Source Map (JSON)
{"version":3,"file":"aria.mjs","names":[],"sources":["../../../../../packages/utils/dom/aria.ts"],"sourcesContent":["const FOCUSABLE_ELEMENT_SELECTORS = `a[href],button:not([disabled]),button:not([hidden]),:not([tabindex=\"-1\"]),input:not([disabled]),input:not([type=\"hidden\"]),select:not([disabled]),textarea:not([disabled])`\n\nexport const isShadowRoot = (e: unknown): e is ShadowRoot => {\n if (typeof ShadowRoot === 'undefined') return false\n return e instanceof ShadowRoot\n}\n\nconst isHTMLElement = (e: unknown): e is Element => {\n if (typeof Element === 'undefined') return false\n return e instanceof Element\n}\n\n/**\n * Determine if the testing element is visible on screen no matter if its on the viewport or not\n */\nexport const isVisible = (element: HTMLElement) => {\n if (process.env.NODE_ENV === 'test') return true\n const computed = getComputedStyle(element)\n // element.offsetParent won't work on fix positioned\n // WARNING: potential issue here, going to need some expert advices on this issue\n return computed.position === 'fixed' ? false : element.offsetParent !== null\n}\n\nexport const obtainAllFocusableElements = (\n element: HTMLElement\n): HTMLElement[] => {\n return Array.from(\n element.querySelectorAll<HTMLElement>(FOCUSABLE_ELEMENT_SELECTORS)\n ).filter((item: HTMLElement) => isFocusable(item) && isVisible(item))\n}\n\n/**\n * @desc Determine if target element is focusable\n * @param element {HTMLElement}\n * @returns {Boolean} true if it is focusable\n */\nexport const isFocusable = (element: HTMLElement): boolean => {\n if (\n element.tabIndex > 0 ||\n (element.tabIndex === 0 && element.getAttribute('tabIndex') !== null)\n ) {\n return true\n }\n if (\n element.tabIndex < 0 ||\n element.hasAttribute('disabled') ||\n element.getAttribute('aria-disabled') === 'true'\n ) {\n return false\n }\n\n switch (element.nodeName) {\n case 'A': {\n // casting current element to Specific HTMLElement in order to be more type precise\n return (\n !!(element as HTMLAnchorElement).href &&\n (element as HTMLAnchorElement).rel !== 'ignore'\n )\n }\n case 'INPUT': {\n return !(\n (element as HTMLInputElement).type === 'hidden' ||\n (element as HTMLInputElement).type === 'file'\n )\n }\n case 'BUTTON':\n case 'SELECT':\n case 'TEXTAREA': {\n return true\n }\n default: {\n return false\n }\n }\n}\n\n/**\n * Trigger an event\n * mouseenter, mouseleave, mouseover, keyup, change, click, etc.\n * @param {HTMLElement} elm\n * @param {String} name\n * @param {*} opts\n */\nexport const triggerEvent = function (\n elm: HTMLElement,\n name: string,\n ...opts: Array<boolean>\n): HTMLElement {\n let eventName: string\n\n if (name.includes('mouse') || name.includes('click')) {\n eventName = 'MouseEvents'\n } else if (name.includes('key')) {\n eventName = 'KeyboardEvent'\n } else {\n eventName = 'HTMLEvents'\n }\n const evt = document.createEvent(eventName)\n\n evt.initEvent(name, ...opts)\n elm.dispatchEvent(evt)\n return elm\n}\n\nexport const isLeaf = (el: HTMLElement) => !el.getAttribute('aria-owns')\n\nexport const getSibling = (\n el: HTMLElement,\n distance: number,\n elClass: string\n) => {\n const { parentNode } = el\n if (!parentNode) return null\n const siblings = parentNode.querySelectorAll(elClass)\n const index = Array.prototype.indexOf.call(siblings, el)\n return siblings[index + distance] || null\n}\n\nexport const focusElement = (\n el?: HTMLElement | { focus: () => void } | null,\n options?: FocusOptions\n) => {\n if (!el || !el.focus) return\n let cleanup: boolean = false\n\n if (isHTMLElement(el) && !isFocusable(el) && !el.getAttribute('tabindex')) {\n el.setAttribute('tabindex', '-1')\n cleanup = true\n }\n\n el.focus(options)\n\n if (isHTMLElement(el) && cleanup) {\n el.removeAttribute('tabindex')\n }\n}\n\nexport const focusNode = (el: HTMLElement) => {\n if (!el) return\n focusElement(el)\n !isLeaf(el) && el.click()\n}\n"],"mappings":";AAAA,MAAM,8BAA8B;AAEpC,MAAa,gBAAgB,MAAgC;CAC3D,IAAI,OAAO,eAAe,aAAa,OAAO;CAC9C,OAAO,aAAa;;AAGtB,MAAM,iBAAiB,MAA6B;CAClD,IAAI,OAAO,YAAY,aAAa,OAAO;CAC3C,OAAO,aAAa;;;;;AAMtB,MAAa,aAAa,YAAyB;CAKjD,OAHiB,iBAAiB,QAGnB,CAAC,aAAa,UAAU,QAAQ,QAAQ,iBAAiB;;AAG1E,MAAa,8BACX,YACkB;CAClB,OAAO,MAAM,KACX,QAAQ,iBAA8B,4BAA4B,CACnE,CAAC,QAAQ,SAAsB,YAAY,KAAK,IAAI,UAAU,KAAK,CAAC;;;;;;;AAQvE,MAAa,eAAe,YAAkC;CAC5D,IACE,QAAQ,WAAW,KAClB,QAAQ,aAAa,KAAK,QAAQ,aAAa,WAAW,KAAK,MAEhE,OAAO;CAET,IACE,QAAQ,WAAW,KACnB,QAAQ,aAAa,WAAW,IAChC,QAAQ,aAAa,gBAAgB,KAAK,QAE1C,OAAO;CAGT,QAAQ,QAAQ,UAAhB;EACE,KAAK,KAEH,OACE,CAAC,CAAE,QAA8B,QAChC,QAA8B,QAAQ;EAG3C,KAAK,SACH,OAAO,EACJ,QAA6B,SAAS,YACtC,QAA6B,SAAS;EAG3C,KAAK;EACL,KAAK;EACL,KAAK,YACH,OAAO;EAET,SACE,OAAO;;;;;;;;;;AAYb,MAAa,eAAe,SAC1B,KACA,MACA,GAAG,MACU;CACb,IAAI;CAEJ,IAAI,KAAK,SAAS,QAAQ,IAAI,KAAK,SAAS,QAAQ,EAClD,YAAY;MACP,IAAI,KAAK,SAAS,MAAM,EAC7B,YAAY;MAEZ,YAAY;CAEd,MAAM,MAAM,SAAS,YAAY,UAAU;CAE3C,IAAI,UAAU,MAAM,GAAG,KAAK;CAC5B,IAAI,cAAc,IAAI;CACtB,OAAO;;AAGT,MAAa,UAAU,OAAoB,CAAC,GAAG,aAAa,YAAY;AAExE,MAAa,cACX,IACA,UACA,YACG;CACH,MAAM,EAAE,eAAe;CACvB,IAAI,CAAC,YAAY,OAAO;CACxB,MAAM,WAAW,WAAW,iBAAiB,QAAQ;CAErD,OAAO,SADO,MAAM,UAAU,QAAQ,KAAK,UAAU,GAChC,GAAG,aAAa;;AAGvC,MAAa,gBACX,IACA,YACG;CACH,IAAI,CAAC,MAAM,CAAC,GAAG,OAAO;CACtB,IAAI,UAAmB;CAEvB,IAAI,cAAc,GAAG,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,aAAa,WAAW,EAAE;EACzE,GAAG,aAAa,YAAY,KAAK;EACjC,UAAU;;CAGZ,GAAG,MAAM,QAAQ;CAEjB,IAAI,cAAc,GAAG,IAAI,SACvB,GAAG,gBAAgB,WAAW;;AAIlC,MAAa,aAAa,OAAoB;CAC5C,IAAI,CAAC,IAAI;CACT,aAAa,GAAG;CAChB,CAAC,OAAO,GAAG,IAAI,GAAG,OAAO"}