@oscarpalmer/toretto 0.45.0 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/aria.d.mts +68 -0
  2. package/dist/aria.mjs +49 -0
  3. package/dist/attribute/get.attribute.d.mts +3 -0
  4. package/dist/attribute/get.attribute.mjs +3 -3
  5. package/dist/attribute/index.d.mts +7 -1
  6. package/dist/attribute/set.attribute.d.mts +5 -0
  7. package/dist/attribute/set.attribute.mjs +1 -1
  8. package/dist/create.d.mts +4 -2
  9. package/dist/create.mjs +1 -1
  10. package/dist/data.d.mts +4 -0
  11. package/dist/data.mjs +1 -2
  12. package/dist/event/delegation.mjs +3 -4
  13. package/dist/event/index.d.mts +9 -1
  14. package/dist/event/index.mjs +3 -2
  15. package/dist/find/index.d.mts +14 -1
  16. package/dist/find/index.mjs +36 -1
  17. package/dist/find/relative.d.mts +5 -0
  18. package/dist/find/relative.mjs +1 -0
  19. package/dist/focusable.d.mts +4 -0
  20. package/dist/focusable.mjs +4 -0
  21. package/dist/html/index.d.mts +8 -4
  22. package/dist/html/index.mjs +4 -3
  23. package/dist/index.d.mts +185 -22
  24. package/dist/index.mjs +295 -144
  25. package/dist/internal/attribute.mjs +2 -2
  26. package/dist/internal/element-value.mjs +2 -4
  27. package/dist/internal/is.d.mts +15 -3
  28. package/dist/internal/is.mjs +15 -3
  29. package/dist/is.d.mts +5 -2
  30. package/dist/is.mjs +4 -3
  31. package/dist/models.d.mts +21 -8
  32. package/dist/property/get.property.d.mts +2 -0
  33. package/dist/property/get.property.mjs +4 -3
  34. package/dist/property/set.property.d.mts +3 -0
  35. package/dist/property/set.property.mjs +3 -4
  36. package/dist/style.d.mts +7 -0
  37. package/dist/style.mjs +8 -4
  38. package/dist/touch.d.mts +4 -0
  39. package/package.json +10 -6
  40. package/src/aria.ts +166 -0
  41. package/src/attribute/get.attribute.ts +5 -3
  42. package/src/attribute/index.ts +6 -0
  43. package/src/attribute/set.attribute.ts +5 -0
  44. package/src/create.ts +5 -3
  45. package/src/data.ts +11 -6
  46. package/src/event/delegation.ts +5 -6
  47. package/src/event/index.ts +11 -8
  48. package/src/find/index.ts +64 -1
  49. package/src/find/relative.ts +5 -0
  50. package/src/focusable.ts +4 -0
  51. package/src/html/index.ts +11 -9
  52. package/src/index.ts +1 -0
  53. package/src/internal/attribute.ts +4 -2
  54. package/src/internal/element-value.ts +2 -3
  55. package/src/internal/is.ts +22 -2
  56. package/src/is.ts +4 -1
  57. package/src/models.ts +122 -8
  58. package/src/property/get.property.ts +6 -5
  59. package/src/property/set.property.ts +5 -3
  60. package/src/style.ts +12 -6
  61. package/src/touch.ts +4 -0
@@ -0,0 +1,68 @@
1
+ import { AriaAttribute, AriaAttributeUnprefixed, AriaRole } from "./models.mjs";
2
+
3
+ //#region src/aria.d.ts
4
+ type AnyAriaAttribute = AriaAttribute | AriaAttributeUnprefixed;
5
+ type AriaAttributeItem = {
6
+ name: AnyAriaAttribute;
7
+ value?: string;
8
+ };
9
+ /**
10
+ * Get the value of a specific _ARIA_ attribute from an element
11
+ *
12
+ * @param element Element to get _ARIA_ attribute from
13
+ * @param name _ARIA_ name
14
+ * @returns _ARIA_ value _(or `undefined`)_
15
+ */
16
+ declare function getAria(element: Element, attribute: AnyAriaAttribute): string | undefined;
17
+ /**
18
+ * Get specific _ARIA_ attributes from an element
19
+ *
20
+ * @param element Element to get _ARIA_ attributes from
21
+ * @param names _ARIA_ attribute names
22
+ * @returns Object of named _ARIA_ attributes
23
+ */
24
+ declare function getAria<Attribute extends AnyAriaAttribute>(element: Element, attributes: Attribute[]): Record<Attribute, string | undefined>;
25
+ /**
26
+ * Get the role of an element
27
+ *
28
+ * @param element Element to get role from
29
+ * @returns Element role _(or `undefined`)_
30
+ */
31
+ declare function getRole(element: Element): unknown;
32
+ /**
33
+ * Set an _ARIA_ attribute on an element
34
+ *
35
+ * _(Or remove it, if value is `null` or `undefined`)_
36
+ *
37
+ * @param element Element for _ARIA_ attribute
38
+ * @param attribute _ARIA_ attribute to set
39
+ * @param value _ARIA_ attribute value
40
+ */
41
+ declare function setAria(element: Element, attribute: AnyAriaAttribute, value?: string): void;
42
+ /**
43
+ * Set one or more _ARIA_ attributes on an element
44
+ *
45
+ * _(Or remove them, if their value is `null` or `undefined`)_
46
+ *
47
+ * @param element Element for _ARIA_ attributes
48
+ * @param attributes _ARIA_ attributes to set
49
+ */
50
+ declare function setAria(element: Element, attributes: AriaAttributeItem[]): void;
51
+ /**
52
+ * Set one or more _ARIA_ attributes on an element
53
+ *
54
+ * _(Or remove them, if their value is `null` or `undefined`)_
55
+ *
56
+ * @param element Element for _ARIA_ attributes
57
+ * @param attributes _ARIA_ attributes to set
58
+ */
59
+ declare function setAria(element: Element, attributes: Partial<Record<AnyAriaAttribute, unknown>>): void;
60
+ /**
61
+ * Set the role of an element
62
+ *
63
+ * @param element Element for role
64
+ * @param role Role to set _(or `undefined` to remove it)_
65
+ */
66
+ declare function setRole(element: Element, role?: AriaRole): void;
67
+ //#endregion
68
+ export { getAria, getRole, setAria, setRole };
package/dist/aria.mjs ADDED
@@ -0,0 +1,49 @@
1
+ import { setElementValues, updateElementValue } from "./internal/element-value.mjs";
2
+ //#region src/aria.ts
3
+ function getAria(element, value) {
4
+ if (!(element instanceof Element)) return Array.isArray(value) ? {} : void 0;
5
+ if (!Array.isArray(value)) return typeof value === "string" ? getAriaValue(element, value) : void 0;
6
+ const arias = {};
7
+ const { length } = value;
8
+ for (let index = 0; index < length; index += 1) {
9
+ const attribute = value[index];
10
+ if (typeof attribute === "string") arias[attribute.replace(ATTRIBUTE_ARIA_PREFIX, "")] = getAriaValue(element, attribute);
11
+ }
12
+ return arias;
13
+ }
14
+ function getAriaValue(element, attribute) {
15
+ return element.getAttribute(getName(attribute)) ?? void 0;
16
+ }
17
+ function getName(value) {
18
+ return EXPRESSION_ARIA_PREFIX.test(value) ? value : `${ATTRIBUTE_ARIA_PREFIX}${value}`;
19
+ }
20
+ /**
21
+ * Get the role of an element
22
+ *
23
+ * @param element Element to get role from
24
+ * @returns Element role _(or `undefined`)_
25
+ */
26
+ function getRole(element) {
27
+ if (element instanceof Element) return element.getAttribute("role") ?? void 0;
28
+ }
29
+ function setAria(element, first, second) {
30
+ setElementValues(element, first, second, null, updateAriaAttribute);
31
+ }
32
+ /**
33
+ * Set the role of an element
34
+ *
35
+ * @param element Element for role
36
+ * @param role Role to set _(or `undefined` to remove it)_
37
+ */
38
+ function setRole(element, role) {
39
+ if (!(element instanceof Element)) return;
40
+ if (typeof role === "string") element.setAttribute("role", role);
41
+ else element.removeAttribute("role");
42
+ }
43
+ function updateAriaAttribute(element, key, value) {
44
+ updateElementValue(element, getName(key), value, element.setAttribute, element.removeAttribute, false, false);
45
+ }
46
+ const ATTRIBUTE_ARIA_PREFIX = "aria-";
47
+ const EXPRESSION_ARIA_PREFIX = /^aria-/i;
48
+ //#endregion
49
+ export { getAria, getRole, setAria, setRole };
@@ -2,6 +2,7 @@
2
2
  type DataPrefixedName = `data-${string}`;
3
3
  /**
4
4
  * Get the value of a specific attribute from an element
5
+ *
5
6
  * @param element Element to get attribute from
6
7
  * @param name Attribute name
7
8
  * @param parse Parse value? _(defaults to `true`)_
@@ -10,6 +11,7 @@ type DataPrefixedName = `data-${string}`;
10
11
  declare function getAttribute(element: Element, name: DataPrefixedName, parse?: boolean): unknown;
11
12
  /**
12
13
  * Get the value of a specific attribute from an element
14
+ *
13
15
  * @param element Element to get attribute from
14
16
  * @param name Attribute name
15
17
  * @returns Attribute value _(or `undefined`)_
@@ -17,6 +19,7 @@ declare function getAttribute(element: Element, name: DataPrefixedName, parse?:
17
19
  declare function getAttribute(element: Element, name: string): unknown;
18
20
  /**
19
21
  * Get specific attributes from an element
22
+ *
20
23
  * @param element Element to get attributes from
21
24
  * @param names Attribute names
22
25
  * @param parseData Parse data values? _(defaults to `true`)_
@@ -1,12 +1,12 @@
1
- import { isHTMLOrSVGElement } from "../internal/is.mjs";
2
1
  import { getAttributeValue } from "../internal/get-value.mjs";
3
2
  import { kebabCase } from "@oscarpalmer/atoms/string/case";
4
3
  //#region src/attribute/get.attribute.ts
5
4
  function getAttribute(element, name, parseValues) {
6
- if (isHTMLOrSVGElement(element) && typeof name === "string") return getAttributeValue(element, kebabCase(name), parseValues !== false);
5
+ if (element instanceof Element && typeof name === "string") return getAttributeValue(element, kebabCase(name), parseValues !== false);
7
6
  }
8
7
  /**
9
8
  * Get specific attributes from an element
9
+ *
10
10
  * @param element Element to get attributes from
11
11
  * @param names Attribute names
12
12
  * @param parseData Parse data values? _(defaults to `true`)_
@@ -14,7 +14,7 @@ function getAttribute(element, name, parseValues) {
14
14
  */
15
15
  function getAttributes(element, names, parseData) {
16
16
  const attributes = {};
17
- if (!(isHTMLOrSVGElement(element) && Array.isArray(names))) return attributes;
17
+ if (!(element instanceof Element && Array.isArray(names))) return attributes;
18
18
  const shouldParse = parseData !== false;
19
19
  const { length } = names;
20
20
  for (let index = 0; index < length; index += 1) {
@@ -1,17 +1,19 @@
1
- import { getAttribute, getAttributes } from "./get.attribute.mjs";
2
1
  import { Attribute } from "../models.mjs";
2
+ import { getAttribute, getAttributes } from "./get.attribute.mjs";
3
3
  import { booleanAttributes } from "../internal/attribute.mjs";
4
4
  import { setAttribute, setAttributes } from "./set.attribute.mjs";
5
5
 
6
6
  //#region src/attribute/index.d.ts
7
7
  /**
8
8
  * Is the attribute considered bad and potentially harmful?
9
+ *
9
10
  * @param attribute Attribute to check
10
11
  * @returns `true` if attribute is considered bad
11
12
  */
12
13
  declare function isBadAttribute(attribute: Attr | Attribute): boolean;
13
14
  /**
14
15
  * Is the attribute considered bad and potentially harmful?
16
+ *
15
17
  * @param name Attribute name
16
18
  * @param value Attribute value
17
19
  * @returns `true` if attribute is considered bad
@@ -19,12 +21,14 @@ declare function isBadAttribute(attribute: Attr | Attribute): boolean;
19
21
  declare function isBadAttribute(name: string, value: string): boolean;
20
22
  /**
21
23
  * Is the attribute a boolean attribute?
24
+ *
22
25
  * @param name Attribute to check
23
26
  * @returns `true` if attribute is a boolean attribute
24
27
  */
25
28
  declare function isBooleanAttribute(attribute: Attr | Attribute): boolean;
26
29
  /**
27
30
  * Is the attribute a boolean attribute?
31
+ *
28
32
  * @param name Attribute name
29
33
  * @returns `true` if attribute is a boolean attribute
30
34
  */
@@ -33,6 +37,7 @@ declare function isBooleanAttribute(name: string): boolean;
33
37
  * Is the attribute an invalid boolean attribute?
34
38
  *
35
39
  * _(I.e., its value is not empty or the same as its name)_
40
+ *
36
41
  * @param attribute Attribute to check
37
42
  * @returns `true` if attribute is an invalid boolean attribute
38
43
  */
@@ -41,6 +46,7 @@ declare function isInvalidBooleanAttribute(attribute: Attr | Attribute): boolean
41
46
  * Is the attribute an invalid boolean attribute?
42
47
  *
43
48
  * _(I.e., its value is not empty or the same as its name)_
49
+ *
44
50
  * @param name Attribute name
45
51
  * @param value Attribute value
46
52
  * @returns `true` if attribute is an invalid boolean attribute
@@ -6,6 +6,7 @@ type DispatchedAttributeName = 'checked' | 'open' | 'value';
6
6
  * Set an attribute on an element
7
7
  *
8
8
  * _(Or remove it, if value is `null` or `undefined`)_
9
+ *
9
10
  * @param element Element for attribute
10
11
  * @param name Attribute name
11
12
  * @param value Attribute value
@@ -16,6 +17,7 @@ declare function setAttribute(element: Element, name: DispatchedAttributeName, v
16
17
  * Set an attribute on an element
17
18
  *
18
19
  * _(Or remove it, if value is `null` or `undefined`)_
20
+ *
19
21
  * @param element Element for attribute
20
22
  * @param name Attribute name
21
23
  * @param value Attribute value
@@ -25,6 +27,7 @@ declare function setAttribute(element: Element, name: string, value?: unknown):
25
27
  * Set an attribute on an element
26
28
  *
27
29
  * _(Or remove it, if value is `null` or `undefined`)_
30
+ *
28
31
  * @param element Element for attribute
29
32
  * @param attribute Attribute to set
30
33
  * @param dispatch Dispatch event for attribute? _(defaults to `true`)_
@@ -34,6 +37,7 @@ declare function setAttribute(element: Element, attribute: Attr | Attribute, dis
34
37
  * Set one or more attributes on an element
35
38
  *
36
39
  * _(Or remove them, if their value is `null` or `undefined`)_
40
+ *
37
41
  * @param element Element for attributes
38
42
  * @param attributes Attributes to set
39
43
  * @param dispatch Dispatch events for relevant attributes? _(defaults to `true`)_
@@ -43,6 +47,7 @@ declare function setAttributes(element: Element, attributes: Array<Attr | Attrib
43
47
  * Set one or more attributes on an element
44
48
  *
45
49
  * _(Or remove them, if their value is `null` or `undefined`)_
50
+ *
46
51
  * @param element Element for attributes
47
52
  * @param attributes Attributes to set
48
53
  * @param dispatch Dispatch events for relevant attributes? _(defaults to `true`)_
@@ -1,5 +1,5 @@
1
- import { setElementValue, setElementValues } from "../internal/element-value.mjs";
2
1
  import { updateAttribute } from "../internal/attribute.mjs";
2
+ import { setElementValue, setElementValues } from "../internal/element-value.mjs";
3
3
  //#region src/attribute/set.attribute.ts
4
4
  function setAttribute(element, first, second, third) {
5
5
  setElementValue(element, first, second, third, updateAttribute);
package/dist/create.d.mts CHANGED
@@ -4,7 +4,8 @@ import { Primitive } from "@oscarpalmer/atoms/models";
4
4
  type Properties<Target extends Element> = { [Property in keyof Target]?: Target[Property] extends Primitive ? Target[Property] : never };
5
5
  type Styles = Partial<Record<keyof CSSStyleDeclaration, unknown>>;
6
6
  /**
7
- * Creates an HTML element with the specified tag name together with optional properties, attributes, and styles
7
+ * Creates an _HTML_ element with the specified tag name together with optional properties, attributes, and styles
8
+ *
8
9
  * @param tag Tag name
9
10
  * @param properties Element properties
10
11
  * @param attributes Element attributes
@@ -13,7 +14,8 @@ type Styles = Partial<Record<keyof CSSStyleDeclaration, unknown>>;
13
14
  */
14
15
  declare function createElement<TagName extends keyof HTMLElementTagNameMap>(tag: TagName, properties?: Properties<HTMLElementTagNameMap[TagName]>, attributes?: Record<string, unknown>, styles?: Styles): HTMLElementTagNameMap[TagName];
15
16
  /**
16
- * Creates an HTML element with the specified tag name together with optional properties, attributes, and styles
17
+ * Creates an _HTML_ element with the specified tag name together with optional properties, attributes, and styles
18
+ *
17
19
  * @param tag Tag name
18
20
  * @param properties Element properties
19
21
  * @param attributes Element attributes
package/dist/create.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { setAttributes } from "./attribute/set.attribute.mjs";
2
2
  import "./attribute/index.mjs";
3
- import { setStyles } from "./style.mjs";
4
3
  import { setProperties } from "./property/set.property.mjs";
5
4
  import "./property/index.mjs";
5
+ import { setStyles } from "./style.mjs";
6
6
  //#region src/create.ts
7
7
  function createElement(tag, properties, attributes, styles) {
8
8
  if (typeof tag !== "string") throw new TypeError(MESSAGE);
package/dist/data.d.mts CHANGED
@@ -3,6 +3,7 @@ import { PlainObject } from "@oscarpalmer/atoms/models";
3
3
  //#region src/data.d.ts
4
4
  /**
5
5
  * Get a keyed data value from an element
6
+ *
6
7
  * @param element Element to get data from
7
8
  * @param key Data key
8
9
  * @param parse Parse values? _(defaults to `true`)_
@@ -11,6 +12,7 @@ import { PlainObject } from "@oscarpalmer/atoms/models";
11
12
  declare function getData(element: Element, key: string, parse?: boolean): unknown;
12
13
  /**
13
14
  * Get keyed data values from an element
15
+ *
14
16
  * @param element Element to get data from
15
17
  * @param keys Keys of the data values to get
16
18
  * @param parse Parse values? _(defaults to `true`)_
@@ -19,12 +21,14 @@ declare function getData(element: Element, key: string, parse?: boolean): unknow
19
21
  declare function getData<Key extends string>(element: Element, keys: Key[], parse?: boolean): Record<Key, unknown>;
20
22
  /**
21
23
  * Set data values on an element
24
+ *
22
25
  * @param element Element to set data on
23
26
  * @param data Data to set
24
27
  */
25
28
  declare function setData(element: Element, data: PlainObject): void;
26
29
  /**
27
30
  * Set a data value on an element
31
+ *
28
32
  * @param element Element to set data on
29
33
  * @param key Data key
30
34
  * @param value Data value
package/dist/data.mjs CHANGED
@@ -1,11 +1,10 @@
1
- import { isHTMLOrSVGElement } from "./internal/is.mjs";
2
1
  import { setElementValues, updateElementValue } from "./internal/element-value.mjs";
3
2
  import { EXPRESSION_DATA_PREFIX } from "./internal/get-value.mjs";
4
3
  import { parse } from "@oscarpalmer/atoms/string";
5
4
  import { camelCase, kebabCase } from "@oscarpalmer/atoms/string/case";
6
5
  //#region src/data.ts
7
6
  function getData(element, keys, parseValues) {
8
- if (!isHTMLOrSVGElement(element)) return;
7
+ if (!(element instanceof Element)) return;
9
8
  const noParse = parseValues === false;
10
9
  if (typeof keys === "string") {
11
10
  const value = element.dataset[camelCase(keys)];
@@ -14,7 +14,7 @@ function addDelegatedListener(target, type, name, listener, passive) {
14
14
  };
15
15
  }
16
16
  function delegatedEventHandler(event) {
17
- const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
17
+ const key = `@${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
18
18
  const items = event.composedPath();
19
19
  const { length } = items;
20
20
  let cancelled = false;
@@ -49,7 +49,7 @@ function delegatedEventHandler(event) {
49
49
  }
50
50
  }
51
51
  function getDelegatedName(target, type, options) {
52
- if (isEventTarget(target) && EVENT_TYPES.has(type) && !options.capture && !options.once && options.signal == null) return `${EVENT_PREFIX}${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
52
+ if (isEventTarget(target) && EVENT_TYPES.has(type) && !options.capture && !options.once && options.signal == null) return `@${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
53
53
  }
54
54
  function removeDelegatedListener(target, name, listener) {
55
55
  const handlers = target[name];
@@ -59,10 +59,9 @@ function removeDelegatedListener(target, name, listener) {
59
59
  return true;
60
60
  }
61
61
  const DELEGATED = /* @__PURE__ */ new Set();
62
- const EVENT_PREFIX = "@";
63
62
  const EVENT_SUFFIX_ACTIVE = ":active";
64
63
  const EVENT_SUFFIX_PASSIVE = ":passive";
65
- const EVENT_TYPES = new Set([
64
+ const EVENT_TYPES = /* @__PURE__ */ new Set([
66
65
  "beforeinput",
67
66
  "click",
68
67
  "dblclick",
@@ -1,8 +1,10 @@
1
- import { CustomEventListener, EventPosition, RemovableEventListener } from "../models.mjs";
1
+ import { CustomEventListener, RemovableEventListener } from "../models.mjs";
2
+ import { EventPosition } from "@oscarpalmer/atoms/models";
2
3
 
3
4
  //#region src/event/index.d.ts
4
5
  /**
5
6
  * Dispatch an event for a target
7
+ *
6
8
  * @param target Event target
7
9
  * @param type Type of event
8
10
  * @param options Options for event _(bubbles and is cancelable by default)_
@@ -10,6 +12,7 @@ import { CustomEventListener, EventPosition, RemovableEventListener } from "../m
10
12
  declare function dispatch<Type extends keyof HTMLElementEventMap>(target: EventTarget, type: Type, options?: CustomEventInit): void;
11
13
  /**
12
14
  * Dispatch an event for a target
15
+ *
13
16
  * @param target Event target
14
17
  * @param type Type of event
15
18
  * @param options Options for event _(bubbles and is cancelable by default)_
@@ -17,12 +20,14 @@ declare function dispatch<Type extends keyof HTMLElementEventMap>(target: EventT
17
20
  declare function dispatch(target: EventTarget, type: string, options?: CustomEventInit): void;
18
21
  /**
19
22
  * Get the X- and Y-coordinates from a pointer event
23
+ *
20
24
  * @param event Pointer event
21
25
  * @returns X- and Y-coordinates
22
26
  */
23
27
  declare function getPosition(event: MouseEvent | TouchEvent): EventPosition | undefined;
24
28
  /**
25
29
  * Remove an event listener
30
+ *
26
31
  * @param target Event target
27
32
  * @param type Type of event
28
33
  * @param listener Event listener
@@ -31,6 +36,7 @@ declare function getPosition(event: MouseEvent | TouchEvent): EventPosition | un
31
36
  declare function off(target: EventTarget, type: keyof HTMLElementEventMap, listener: EventListener | CustomEventListener, options?: EventListenerOptions): void;
32
37
  /**
33
38
  * Remove an event listener
39
+ *
34
40
  * @param target Event target
35
41
  * @param type Type of event
36
42
  * @param listener Event listener
@@ -39,6 +45,7 @@ declare function off(target: EventTarget, type: keyof HTMLElementEventMap, liste
39
45
  declare function off(target: EventTarget, type: string, listener: EventListener | CustomEventListener, options?: EventListenerOptions): void;
40
46
  /**
41
47
  * Add an event listener
48
+ *
42
49
  * @param target Event target
43
50
  * @param type Type of event
44
51
  * @param listener Event listener
@@ -47,6 +54,7 @@ declare function off(target: EventTarget, type: string, listener: EventListener
47
54
  declare function on<Type extends keyof HTMLElementEventMap>(target: EventTarget, type: Type, listener: (event: HTMLElementEventMap[Type]) => void, options?: AddEventListenerOptions): RemovableEventListener;
48
55
  /**
49
56
  * Add an event listener
57
+ *
50
58
  * @param target Event target
51
59
  * @param type Type of event
52
60
  * @param listener Event listener
@@ -13,7 +13,7 @@ function createDispatchOptions(options) {
13
13
  }
14
14
  function createEvent(type, options) {
15
15
  const hasOptions = isPlainObject(options);
16
- if (hasOptions && PROPERTY_DETAIL in options) return new CustomEvent(type, {
16
+ if (hasOptions && "detail" in options) return new CustomEvent(type, {
17
17
  ...createDispatchOptions(options),
18
18
  detail: options?.detail
19
19
  });
@@ -32,6 +32,7 @@ function dispatch(target, type, options) {
32
32
  }
33
33
  /**
34
34
  * Get the X- and Y-coordinates from a pointer event
35
+ *
35
36
  * @param event Pointer event
36
37
  * @returns X- and Y-coordinates
37
38
  */
@@ -52,6 +53,7 @@ function getPosition(event) {
52
53
  }
53
54
  /**
54
55
  * Remove an event listener
56
+ *
55
57
  * @param target Event target
56
58
  * @param type Type of event
57
59
  * @param listener Event listener
@@ -74,6 +76,5 @@ function on(target, type, listener, options) {
74
76
  target.removeEventListener(type, listener, extended);
75
77
  };
76
78
  }
77
- const PROPERTY_DETAIL = "detail";
78
79
  //#endregion
79
80
  export { dispatch, getPosition, off, on };
@@ -1,9 +1,11 @@
1
1
  import { Selector } from "../models.mjs";
2
2
  import { findAncestor, findRelatives, getDistance } from "./relative.mjs";
3
+ import { EventPosition } from "@oscarpalmer/atoms/models";
3
4
 
4
5
  //#region src/find/index.d.ts
5
6
  /**
6
7
  * Find the first element that matches the tag name
8
+ *
7
9
  * @param tagName Tag name of element to find
8
10
  * @param context Context to search within _(defaults to `document`)_
9
11
  * @returns Found element or `null`
@@ -11,6 +13,7 @@ import { findAncestor, findRelatives, getDistance } from "./relative.mjs";
11
13
  declare function findElement<TagName extends keyof HTMLElementTagNameMap>(tagName: TagName, context?: Selector | null): HTMLElementTagNameMap[TagName] | null;
12
14
  /**
13
15
  * Find the first element that matches the selector
16
+ *
14
17
  * @param selector Selector to find element for
15
18
  * @param context Context to search within _(defaults to `document`)_
16
19
  * @returns Found element or `null`
@@ -18,6 +21,7 @@ declare function findElement<TagName extends keyof HTMLElementTagNameMap>(tagNam
18
21
  declare function findElement(selector: string, context?: Selector | null): Element | null;
19
22
  /**
20
23
  * Find elements that match the selector
24
+ *
21
25
  * @param tagName tagName to find elements for
22
26
  * @param context Context to search within _(defaults to `document`)_
23
27
  * @returns Found elements
@@ -25,19 +29,28 @@ declare function findElement(selector: string, context?: Selector | null): Eleme
25
29
  declare function findElements(tagName: keyof HTMLElementTagNameMap, context?: Selector | null): HTMLElementTagNameMap[typeof tagName][];
26
30
  /**
27
31
  * Find elements that match the selector
32
+ *
28
33
  * @param selector Selector to find elements for
29
34
  * @param context Context to search within _(defaults to `document`)_
30
35
  * @returns Found elements
31
36
  */
32
37
  declare function findElements(selector: Selector, context?: Selector | null): Element[];
38
+ /**
39
+ * Get elements from an event position
40
+ *
41
+ * @param position Event position
42
+ * @returns Elements at the event position
43
+ */
44
+ declare function getElementFromPosition(position: EventPosition): Element[];
33
45
  /**
34
46
  * Get the most specific element under the pointer
35
47
  *
36
48
  * - Ignores elements with `pointer-events: none` and `visibility: hidden`
37
49
  * - _(If `skipIgnore` is `true`, no elements are ignored)_
50
+ *
38
51
  * @param skipIgnore Skip ignored elements?
39
52
  * @returns Found element or `null`
40
53
  */
41
54
  declare function getElementUnderPointer(skipIgnore?: boolean): Element | null;
42
55
  //#endregion
43
- export { findElement as $, findElement, findElements as $$, findElements, findAncestor, findRelatives, getDistance, getElementUnderPointer };
56
+ export { findElement as $, findElement, findElements as $$, findElements, findAncestor, findRelatives, getDistance, getElementFromPosition, getElementUnderPointer };
@@ -1,3 +1,4 @@
1
+ import { isEventPosition } from "../internal/is.mjs";
1
2
  import { findAncestor, findRelatives, getDistance } from "./relative.mjs";
2
3
  //#region src/find/index.ts
3
4
  function findElement(selector, context) {
@@ -42,10 +43,42 @@ function findElements(selector, context) {
42
43
  return findElementOrElements(selector, context, false);
43
44
  }
44
45
  /**
46
+ * Get elements from an event position
47
+ *
48
+ * @param position Event position
49
+ * @returns Elements at the event position
50
+ */
51
+ function getElementFromPosition(position) {
52
+ if (!isEventPosition(position) || typeof document.elementFromPoint !== "function") return [];
53
+ const { x, y } = position;
54
+ const elements = [];
55
+ const events = [];
56
+ let current;
57
+ while (true) {
58
+ current = document.elementFromPoint(x, y);
59
+ if (current == null || elements.indexOf(current) !== -1) break;
60
+ if (!(current instanceof HTMLElement)) continue;
61
+ elements.push(current);
62
+ events.push({
63
+ value: current.style.getPropertyValue(STYLE_POINTER_EVENTS),
64
+ priority: current.style.getPropertyPriority(STYLE_POINTER_EVENTS)
65
+ });
66
+ current.style.setProperty(STYLE_POINTER_EVENTS, STYLE_NONE, STYLE_IMPORTANT);
67
+ }
68
+ const { length } = elements;
69
+ for (let index = 0; index < length; index += 1) {
70
+ const element = elements[index];
71
+ const event = events[index];
72
+ if (element instanceof HTMLElement) element.style.setProperty(STYLE_POINTER_EVENTS, event.value ?? "", event.priority);
73
+ }
74
+ return elements;
75
+ }
76
+ /**
45
77
  * Get the most specific element under the pointer
46
78
  *
47
79
  * - Ignores elements with `pointer-events: none` and `visibility: hidden`
48
80
  * - _(If `skipIgnore` is `true`, no elements are ignored)_
81
+ *
49
82
  * @param skipIgnore Skip ignored elements?
50
83
  * @returns Found element or `null`
51
84
  */
@@ -67,8 +100,10 @@ function isContext(value) {
67
100
  const QUERY_SELECTOR_ALL = "querySelectorAll";
68
101
  const QUERY_SELECTOR_SINGLE = "querySelector";
69
102
  const STYLE_HIDDEN = "hidden";
103
+ const STYLE_IMPORTANT = "important";
70
104
  const STYLE_NONE = "none";
105
+ const STYLE_POINTER_EVENTS = "pointer-events";
71
106
  const SUFFIX_HOVER = ":hover";
72
107
  const TAG_HEAD = "HEAD";
73
108
  //#endregion
74
- export { findElement as $, findElement, findElements as $$, findElements, findAncestor, findRelatives, getDistance, getElementUnderPointer };
109
+ export { findElement as $, findElement, findElements as $$, findElements, findAncestor, findRelatives, getDistance, getElementFromPosition, getElementUnderPointer };
@@ -4,6 +4,7 @@
4
4
  *
5
5
  * - If no match is found, `null` is returned
6
6
  * - _(If you want to search upwards, downwards, and sideways, use {@link findRelatives})_
7
+ *
7
8
  * @param origin Origin to start from
8
9
  * @param tagName Tag name to match
9
10
  * @returns Found ancestor or `null`
@@ -14,6 +15,7 @@ declare function findAncestor<TagName extends keyof HTMLElementTagNameMap>(origi
14
15
  *
15
16
  * - If no match is found, `null` is returned
16
17
  * - _(If you want to search upwards, downwards, and sideways, use {@link findRelatives})_
18
+ *
17
19
  * @param origin Origin to start from
18
20
  * @param selector Selector to match
19
21
  * @returns Found ancestor or `null`
@@ -23,6 +25,7 @@ declare function findAncestor(origin: Element | Event | EventTarget, selector: s
23
25
  * Finds the closest elements to the origin element that matches the tag name
24
26
  *
25
27
  * Traverses up, down, and sideways in the _DOM_-tree. _(If you only want to traverse up, use {@link findAncestor})_
28
+ *
26
29
  * @param origin Element to start from
27
30
  * @param tagName Tag name to match
28
31
  * @param context Context to search within
@@ -33,6 +36,7 @@ declare function findRelatives<TagName extends keyof HTMLElementTagNameMap>(orig
33
36
  * Finds the closest elements to the origin element that matches the selector
34
37
  *
35
38
  * Traverses up, down, and sideways in the _DOM_-tree. _(If you only want to traverse up, use {@link findAncestor})_
39
+ *
36
40
  * @param origin Element to start from
37
41
  * @param selector Selector to match
38
42
  * @param context Context to search within
@@ -41,6 +45,7 @@ declare function findRelatives<TagName extends keyof HTMLElementTagNameMap>(orig
41
45
  declare function findRelatives(origin: Element, selector: string, context?: Document | Element): Element[];
42
46
  /**
43
47
  * Get the distance between two elements _(i.e., the amount of nodes of between them)_
48
+ *
44
49
  * @param origin Origin element
45
50
  * @param target Target element
46
51
  * @returns Distance between elements, or `-1` if distance cannot be calculated
@@ -37,6 +37,7 @@ function findRelatives(origin, selector, context) {
37
37
  }
38
38
  /**
39
39
  * Get the distance between two elements _(i.e., the amount of nodes of between them)_
40
+ *
40
41
  * @param origin Origin element
41
42
  * @param target Target element
42
43
  * @returns Distance between elements, or `-1` if distance cannot be calculated
@@ -1,24 +1,28 @@
1
1
  //#region src/focusable.d.ts
2
2
  /**
3
3
  * Get a list of focusable elements within a parent element
4
+ *
4
5
  * @param parent Parent element
5
6
  * @returns Focusable elements
6
7
  */
7
8
  declare function getFocusable(parent: Element): Element[];
8
9
  /**
9
10
  * Get a list of tabbable elements within a parent element
11
+ *
10
12
  * @param parent Parent element
11
13
  * @returns Tabbable elements
12
14
  */
13
15
  declare function getTabbable(parent: Element): Element[];
14
16
  /**
15
17
  * Is the element focusable?
18
+ *
16
19
  * @param element Element to check
17
20
  * @returns `true` if focusable, otherwise `false`
18
21
  */
19
22
  declare function isFocusable(element: Element): boolean;
20
23
  /**
21
24
  * Is the element tabbable?
25
+ *
22
26
  * @param element Element to check
23
27
  * @returns `true` if tabbable, otherwise `false`
24
28
  */