@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
@@ -1,5 +1,5 @@
1
- import { updateElementValue } from "./element-value.mjs";
2
1
  import { updateProperty } from "./property.mjs";
2
+ import { updateElementValue } from "./element-value.mjs";
3
3
  import { isPlainObject } from "@oscarpalmer/atoms/is";
4
4
  import { getString } from "@oscarpalmer/atoms/string";
5
5
  import { kebabCase } from "@oscarpalmer/atoms/string/case";
@@ -96,7 +96,7 @@ const booleanAttributes = Object.freeze([
96
96
  "selected"
97
97
  ]);
98
98
  const booleanAttributesSet = new Set(booleanAttributes);
99
- const dispatchedAttributes = new Set([
99
+ const dispatchedAttributes = /* @__PURE__ */ new Set([
100
100
  "checked",
101
101
  "open",
102
102
  "value"
@@ -1,5 +1,3 @@
1
- import { isHTMLOrSVGElement } from "./is.mjs";
2
- import "../is.mjs";
3
1
  import { isAttribute } from "./attribute.mjs";
4
2
  import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
5
3
  import { getString } from "@oscarpalmer/atoms/string";
@@ -13,12 +11,12 @@ function normalizeKey(key, style) {
13
11
  return style && key.startsWith(CSS_VARIABLE_PREFIX) ? key : kebabCase(key);
14
12
  }
15
13
  function setElementValue(element, first, second, third, callback, style) {
16
- if (!isHTMLOrSVGElement(element)) return;
14
+ if (!(element instanceof Element)) return;
17
15
  if (typeof first === "string") setElementValues(element, first, second, third, callback, style);
18
16
  else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback, style);
19
17
  }
20
18
  function setElementValues(element, first, second, third, callback, style) {
21
- if (!isHTMLOrSVGElement(element)) return;
19
+ if (!(element instanceof Element)) return;
22
20
  const dispatch = third !== false;
23
21
  if (typeof first === "string") {
24
22
  callback(element, normalizeKey(first, style), second, dispatch);
@@ -1,21 +1,33 @@
1
+ import { EventPosition } from "@oscarpalmer/atoms/models";
2
+
1
3
  //#region src/internal/is.d.ts
4
+ /**
5
+ * Is the value an event position?
6
+ *
7
+ * @param value Value to check
8
+ * @returns `true` if it's an event position, otherwise `false`
9
+ */
10
+ declare function isEventPosition(value: unknown): value is EventPosition;
2
11
  /**
3
12
  * Is the value an event target?
13
+ *
4
14
  * @param value Value to check
5
15
  * @returns `true` if it's an event target, otherwise `false`
6
16
  */
7
17
  declare function isEventTarget(value: unknown): value is EventTarget;
8
18
  /**
9
- * Is the value an HTML or SVG element?
19
+ * Is the value an _HTML_ or _SVG_ element?
20
+ *
10
21
  * @param value Value to check
11
- * @returns `true` if it's an HTML or SVG element, otherwise `false`
22
+ * @returns `true` if it's an _HTML_ or _SVG_ element, otherwise `false`
12
23
  */
13
24
  declare function isHTMLOrSVGElement(value: unknown): value is HTMLElement | SVGElement;
14
25
  /**
15
26
  * Is the value an input element? _(`<input>`, `<select>`, or `<textarea>`)_
27
+ *
16
28
  * @param value Value to check
17
29
  * @returns `true` if it's an input element, otherwise `false`
18
30
  */
19
31
  declare function isInputElement(value: unknown): value is HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
20
32
  //#endregion
21
- export { isEventTarget, isHTMLOrSVGElement, isInputElement };
33
+ export { isEventPosition, isEventTarget, isHTMLOrSVGElement, isInputElement };
@@ -1,6 +1,16 @@
1
1
  //#region src/internal/is.ts
2
2
  /**
3
+ * Is the value an event position?
4
+ *
5
+ * @param value Value to check
6
+ * @returns `true` if it's an event position, otherwise `false`
7
+ */
8
+ function isEventPosition(value) {
9
+ return typeof value === "object" && value != null && typeof value.x === "number" && typeof value.y === "number";
10
+ }
11
+ /**
3
12
  * Is the value an event target?
13
+ *
4
14
  * @param value Value to check
5
15
  * @returns `true` if it's an event target, otherwise `false`
6
16
  */
@@ -8,15 +18,17 @@ function isEventTarget(value) {
8
18
  return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
9
19
  }
10
20
  /**
11
- * Is the value an HTML or SVG element?
21
+ * Is the value an _HTML_ or _SVG_ element?
22
+ *
12
23
  * @param value Value to check
13
- * @returns `true` if it's an HTML or SVG element, otherwise `false`
24
+ * @returns `true` if it's an _HTML_ or _SVG_ element, otherwise `false`
14
25
  */
15
26
  function isHTMLOrSVGElement(value) {
16
27
  return value instanceof HTMLElement || value instanceof SVGElement;
17
28
  }
18
29
  /**
19
30
  * Is the value an input element? _(`<input>`, `<select>`, or `<textarea>`)_
31
+ *
20
32
  * @param value Value to check
21
33
  * @returns `true` if it's an input element, otherwise `false`
22
34
  */
@@ -24,4 +36,4 @@ function isInputElement(value) {
24
36
  return value instanceof HTMLInputElement || value instanceof HTMLSelectElement || value instanceof HTMLTextAreaElement;
25
37
  }
26
38
  //#endregion
27
- export { isEventTarget, isHTMLOrSVGElement, isInputElement };
39
+ export { isEventPosition, isEventTarget, isHTMLOrSVGElement, isInputElement };
package/dist/is.d.mts CHANGED
@@ -1,24 +1,27 @@
1
- import { isEventTarget, isHTMLOrSVGElement, isInputElement } from "./internal/is.mjs";
1
+ import { isEventPosition, isEventTarget, isHTMLOrSVGElement, isInputElement } from "./internal/is.mjs";
2
2
 
3
3
  //#region src/is.d.ts
4
4
  /**
5
5
  * Is the value a child node?
6
+ *
6
7
  * @param value Value to check
7
8
  * @returns `true` if it's a child node, otherwise `false`
8
9
  */
9
10
  declare function isChildNode(value: unknown): value is ChildNode;
10
11
  /**
11
12
  * Is the node inside a document?
13
+ *
12
14
  * @param node Node to check
13
15
  * @returns `true` if it's inside a document, otherwise `false`
14
16
  */
15
17
  declare function isInDocument(node: Node): boolean;
16
18
  /**
17
19
  * Is the node inside a specific document?
20
+ *
18
21
  * @param node Node to check
19
22
  * @param document Document to check within
20
23
  * @returns `true` if it's inside the document, otherwise `false`
21
24
  */
22
25
  declare function isInDocument(node: Node, document: Document): boolean;
23
26
  //#endregion
24
- export { isChildNode, isEventTarget, isHTMLOrSVGElement, isInDocument, isInputElement };
27
+ export { isChildNode, isEventPosition, isEventTarget, isHTMLOrSVGElement, isInDocument, isInputElement };
package/dist/is.mjs CHANGED
@@ -1,7 +1,8 @@
1
- import { isEventTarget, isHTMLOrSVGElement, isInputElement } from "./internal/is.mjs";
1
+ import { isEventPosition, isEventTarget, isHTMLOrSVGElement, isInputElement } from "./internal/is.mjs";
2
2
  //#region src/is.ts
3
3
  /**
4
4
  * Is the value a child node?
5
+ *
5
6
  * @param value Value to check
6
7
  * @returns `true` if it's a child node, otherwise `false`
7
8
  */
@@ -13,7 +14,7 @@ function isInDocument(node, doc) {
13
14
  if (!(doc instanceof Document)) return node.ownerDocument?.contains(node) ?? true;
14
15
  return node.ownerDocument == null ? node === doc : node.ownerDocument === doc && doc.contains(node);
15
16
  }
16
- const CHILD_NODE_TYPES = new Set([
17
+ const CHILD_NODE_TYPES = /* @__PURE__ */ new Set([
17
18
  Node.ELEMENT_NODE,
18
19
  Node.TEXT_NODE,
19
20
  Node.PROCESSING_INSTRUCTION_NODE,
@@ -21,4 +22,4 @@ const CHILD_NODE_TYPES = new Set([
21
22
  Node.DOCUMENT_TYPE_NODE
22
23
  ]);
23
24
  //#endregion
24
- export { isChildNode, isEventTarget, isHTMLOrSVGElement, isInDocument, isInputElement };
25
+ export { isChildNode, isEventPosition, isEventTarget, isHTMLOrSVGElement, isInDocument, isInputElement };
package/dist/models.d.mts CHANGED
@@ -1,4 +1,24 @@
1
1
  //#region src/models.d.ts
2
+ /**
3
+ * _ARIA_ attribute for an element
4
+ *
5
+ * _(https://www.w3.org/TR/wai-aria-1.3/#aria-attributes)_
6
+ */
7
+ type AriaAttribute = keyof AriaAttributes;
8
+ /**
9
+ * _ARIA_ attribute for an element without the `aria-` prefix
10
+ *
11
+ * _(https://www.w3.org/TR/wai-aria-1.3/#aria-attributes)_
12
+ */
13
+ type AriaAttributeUnprefixed = keyof { [Key in AriaAttribute as Key extends `aria-${infer Name}` ? Name : never]: string | null };
14
+ type AriaAttributes = { [Key in keyof ARIAMixin as NormalizedName<Key>]: string | null };
15
+ type NormalizedName<Key extends string> = Key extends `aria${infer Name}` ? Name extends `${infer Part}Element` ? `aria-${Lowercase<Part>}` : Name extends `${infer Part}Elements` ? `aria-${Lowercase<Part>}` : `aria-${Lowercase<Name>}` : never;
16
+ /**
17
+ * _ARIA_ role for an element
18
+ *
19
+ * _(https://www.w3.org/TR/wai-aria-1.3/#role_definitions)_
20
+ */
21
+ type AriaRole = 'alert' | 'alertdialog' | 'application' | 'article' | 'banner' | 'blockquote' | 'button' | 'caption' | 'cell' | 'checkbox' | 'code' | 'columnheader' | 'combobox' | 'comment' | 'complementary' | 'contentinfo' | 'definition' | 'deletion' | 'dialog' | 'directory' | 'document' | 'emphasis' | 'feed' | 'figure' | 'form' | 'generic' | 'grid' | 'gridcell' | 'group' | 'heading' | 'img' | 'insertion' | 'link' | 'list' | 'listbox' | 'listitem' | 'log' | 'main' | 'mark' | 'marquee' | 'math' | 'menu' | 'menubar' | 'menuitem' | 'menuitemcheckbox' | 'menuitemradio' | 'meter' | 'navigation' | 'none' | 'note' | 'option' | 'paragraph' | 'presentation' | 'progressbar' | 'radio' | 'radiogroup' | 'region' | 'row' | 'rowgroup' | 'rowheader' | 'scrollbar' | 'search' | 'searchbox' | 'sectionfooter' | 'sectionheader' | 'separator' | 'slider' | 'spinbutton' | 'status' | 'strong' | 'subscript' | 'suggestion' | 'superscript' | 'switch' | 'tab' | 'table' | 'tablist' | 'tabpanel' | 'term' | 'textbox' | 'time' | 'timer' | 'toolbar' | 'tooltip' | 'tree' | 'treegrid' | 'treeitem';
2
22
  /**
3
23
  * Attribute for an element
4
24
  */
@@ -10,13 +30,6 @@ type Attribute = {
10
30
  * Event listener for custom events
11
31
  */
12
32
  type CustomEventListener = (event: CustomEvent) => void;
13
- /**
14
- * The position of an event
15
- */
16
- type EventPosition = {
17
- x: number;
18
- y: number;
19
- };
20
33
  /**
21
34
  * Event listener that can be removed
22
35
  */
@@ -30,4 +43,4 @@ type Selector = string | Node | Node[] | NodeList;
30
43
  */
31
44
  type TextDirection = 'ltr' | 'rtl';
32
45
  //#endregion
33
- export { Attribute, CustomEventListener, EventPosition, RemovableEventListener, Selector, TextDirection };
46
+ export { AriaAttribute, AriaAttributeUnprefixed, AriaRole, Attribute, CustomEventListener, RemovableEventListener, Selector, TextDirection };
@@ -4,6 +4,7 @@ import { Primitive } from "@oscarpalmer/atoms/models";
4
4
  type GetProperties<Target extends Element> = { [Property in keyof Target as Target[Property] extends Primitive ? Property : never]?: Target[Property] };
5
5
  /**
6
6
  * Get the values of one or more properties on an element
7
+ *
7
8
  * @param target Target element
8
9
  * @param properties Properties to get
9
10
  * @returns Property values
@@ -11,6 +12,7 @@ type GetProperties<Target extends Element> = { [Property in keyof Target as Targ
11
12
  declare function getProperties<Target extends Element, Property extends keyof GetProperties<Target>>(target: Target, properties: Property[]): Pick<GetProperties<Target>, Property>;
12
13
  /**
13
14
  * Get the value of a property on an element
15
+ *
14
16
  * @param target Target element
15
17
  * @param property Property to get
16
18
  * @returns Property value
@@ -1,15 +1,15 @@
1
- import { isHTMLOrSVGElement } from "../internal/is.mjs";
2
1
  import { camelCase } from "@oscarpalmer/atoms/string/case";
3
2
  //#region src/property/get.property.ts
4
3
  /**
5
4
  * Get the values of one or more properties on an element
5
+ *
6
6
  * @param target Target element
7
7
  * @param properties Properties to get
8
8
  * @returns Property values
9
9
  */
10
10
  function getProperties(target, properties) {
11
11
  const values = {};
12
- if (!isHTMLOrSVGElement(target) || !Array.isArray(properties)) return values;
12
+ if (!(target instanceof Element && Array.isArray(properties))) return values;
13
13
  const { length } = properties;
14
14
  for (let index = 0; index < length; index += 1) {
15
15
  const property = properties[index];
@@ -19,12 +19,13 @@ function getProperties(target, properties) {
19
19
  }
20
20
  /**
21
21
  * Get the value of a property on an element
22
+ *
22
23
  * @param target Target element
23
24
  * @param property Property to get
24
25
  * @returns Property value
25
26
  */
26
27
  function getProperty(target, property) {
27
- if (isHTMLOrSVGElement(target) && typeof property === "string") return getPropertyValue(target, property);
28
+ if (target instanceof Element && typeof property === "string") return getPropertyValue(target, property);
28
29
  }
29
30
  function getPropertyValue(element, property) {
30
31
  let actual = property;
@@ -8,6 +8,7 @@ type SetProperties<Target extends Element> = { [Property in keyof Target as Targ
8
8
  * Set the values of one or more properties on an element
9
9
  *
10
10
  * Also updates attributes for boolean/dispatchable properties, and if `dispatch` is `true`, will dispatch events for dispatchable properties
11
+ *
11
12
  * @param target Target element
12
13
  * @param properties Properties to set
13
14
  * @param dispatch Dispatch events for properties? _(defaults to `true`)_
@@ -15,6 +16,7 @@ type SetProperties<Target extends Element> = { [Property in keyof Target as Targ
15
16
  declare function setProperties<Target extends Element>(target: Target, properties: SetProperties<Target>, dispatch?: boolean): void;
16
17
  /**
17
18
  * Set the value for a dispatchable property on an element
19
+ *
18
20
  * @param target Target element
19
21
  * @param property Property to set
20
22
  * @param value Value to set
@@ -23,6 +25,7 @@ declare function setProperties<Target extends Element>(target: Target, propertie
23
25
  declare function setProperty<Target extends Element, Property extends DispatchedAttributeName>(target: Target, property: Property, value: DispatchedPropertyValue<Target, Property>, dispatch?: boolean): void;
24
26
  /**
25
27
  * Set the value for a property on an element
28
+ *
26
29
  * @param target Target element
27
30
  * @param property Property to set
28
31
  * @param value Value to set
@@ -1,5 +1,3 @@
1
- import { isHTMLOrSVGElement } from "../internal/is.mjs";
2
- import "../is.mjs";
3
1
  import { updateProperty } from "../internal/property.mjs";
4
2
  import { booleanAttributesSet, dispatchedAttributes } from "../internal/attribute.mjs";
5
3
  import { setAttribute } from "../attribute/set.attribute.mjs";
@@ -10,19 +8,20 @@ import { isPlainObject } from "@oscarpalmer/atoms/is";
10
8
  * Set the values of one or more properties on an element
11
9
  *
12
10
  * Also updates attributes for boolean/dispatchable properties, and if `dispatch` is `true`, will dispatch events for dispatchable properties
11
+ *
13
12
  * @param target Target element
14
13
  * @param properties Properties to set
15
14
  * @param dispatch Dispatch events for properties? _(defaults to `true`)_
16
15
  */
17
16
  function setProperties(target, properties, dispatch) {
18
- if (!isHTMLOrSVGElement(target) || !isPlainObject(properties)) return;
17
+ if (!(target instanceof Element) || !isPlainObject(properties)) return;
19
18
  const shouldDispatch = dispatch !== false;
20
19
  const keys = Object.keys(properties);
21
20
  const { length } = keys;
22
21
  for (let index = 0; index < length; index += 1) setPropertyValue(target, keys[index], properties[keys[index]], shouldDispatch);
23
22
  }
24
23
  function setProperty(target, property, value, dispatch) {
25
- if (isHTMLOrSVGElement(target) && typeof property === "string") setPropertyValue(target, property, value, dispatch !== false);
24
+ if (target instanceof Element && typeof property === "string") setPropertyValue(target, property, value, dispatch !== false);
26
25
  }
27
26
  function setPropertyValue(element, property, value, dispatch) {
28
27
  if (booleanAttributesSet.has(property.toLowerCase()) || dispatchedAttributes.has(property)) setAttribute(element, property, value, dispatch);
package/dist/style.d.mts CHANGED
@@ -16,6 +16,7 @@ type Styles = Partial<Record<keyof CSSStyleValues, unknown>>;
16
16
  type Variables<Value extends Record<string, string | undefined> = Record<string, string | undefined>> = { [property in keyof Value as `--${string & property}`]?: string | undefined };
17
17
  /**
18
18
  * Get a style from an element
19
+ *
19
20
  * @param element Element to get the style from
20
21
  * @param property Style name
21
22
  * @param computed Get the computed style? _(defaults to `false`)_
@@ -24,6 +25,7 @@ type Variables<Value extends Record<string, string | undefined> = Record<string,
24
25
  declare function getStyle(element: Element, property: keyof CSSStyleValues, computed?: boolean): string | undefined;
25
26
  /**
26
27
  * Get styles from an element
28
+ *
27
29
  * @param element Element to get the styles from
28
30
  * @param properties Styles to get
29
31
  * @param computed Get the computed styles? _(defaults to `false`)_
@@ -32,17 +34,20 @@ declare function getStyle(element: Element, property: keyof CSSStyleValues, comp
32
34
  declare function getStyles<Property extends keyof CSSStyleValues>(element: Element, properties: Property[], computed?: boolean): Record<Property, string | undefined>;
33
35
  /**
34
36
  * Get the text direction of a node or element _(or document, if element is invalid)_
37
+ *
35
38
  * @param node Node or element to get the text direction from
36
39
  * @returns Text direction
37
40
  */
38
41
  declare function getTextDirection(node: Element | Node): TextDirection;
39
42
  /**
40
43
  * Get the text direction of the document
44
+ *
41
45
  * @returns Text direction
42
46
  */
43
47
  declare function getTextDirection(): TextDirection;
44
48
  /**
45
49
  * Set a style on an element
50
+ *
46
51
  * @param element Element to set the style on
47
52
  * @param property Style name
48
53
  * @param value Style value
@@ -50,12 +55,14 @@ declare function getTextDirection(): TextDirection;
50
55
  declare function setStyle(element: Element, property: keyof CSSStyleValues, value?: unknown): void;
51
56
  /**
52
57
  * Set styles on an element
58
+ *
53
59
  * @param element Element to set the styles on
54
60
  * @param styles Styles to set
55
61
  */
56
62
  declare function setStyles(element: Element, styles: Styles): void;
57
63
  /**
58
64
  * Toggle styles for an element
65
+ *
59
66
  * @param element Element to style
60
67
  * @param styles Styles to be set or removed
61
68
  * @returns Style toggler
package/dist/style.mjs CHANGED
@@ -1,20 +1,21 @@
1
- import { isHTMLOrSVGElement } from "./internal/is.mjs";
2
1
  import { setElementValues, updateElementValue } from "./internal/element-value.mjs";
3
2
  import { getStyleValue } from "./internal/get-value.mjs";
4
3
  import { getString } from "@oscarpalmer/atoms/string";
5
4
  //#region src/style.ts
6
5
  /**
7
6
  * Get a style from an element
7
+ *
8
8
  * @param element Element to get the style from
9
9
  * @param property Style name
10
10
  * @param computed Get the computed style? _(defaults to `false`)_
11
11
  * @returns Style value
12
12
  */
13
13
  function getStyle(element, property, computed) {
14
- if (isHTMLOrSVGElement(element) && typeof property === "string") return getStyleValue(element, property, computed === true);
14
+ if (element instanceof Element && typeof property === "string") return getStyleValue(element, property, computed === true);
15
15
  }
16
16
  /**
17
17
  * Get styles from an element
18
+ *
18
19
  * @param element Element to get the styles from
19
20
  * @param properties Styles to get
20
21
  * @param computed Get the computed styles? _(defaults to `false`)_
@@ -22,7 +23,7 @@ function getStyle(element, property, computed) {
22
23
  */
23
24
  function getStyles(element, properties, computed) {
24
25
  const styles = {};
25
- if (!(isHTMLOrSVGElement(element) && Array.isArray(properties))) return styles;
26
+ if (!(element instanceof Element && Array.isArray(properties))) return styles;
26
27
  const { length } = properties;
27
28
  for (let index = 0; index < length; index += 1) {
28
29
  const property = properties[index];
@@ -32,7 +33,7 @@ function getStyles(element, properties, computed) {
32
33
  }
33
34
  function getTextDirection(node) {
34
35
  let target;
35
- if (isHTMLOrSVGElement(node)) target = node;
36
+ if (node instanceof Element) target = node;
36
37
  else target = node instanceof Node ? node.ownerDocument?.documentElement ?? document.documentElement : document.documentElement;
37
38
  let { direction } = target.style;
38
39
  if (direction === "") direction = getStyleValue(target, PROPERTY_DIRECTION, true);
@@ -40,6 +41,7 @@ function getTextDirection(node) {
40
41
  }
41
42
  /**
42
43
  * Set a style on an element
44
+ *
43
45
  * @param element Element to set the style on
44
46
  * @param property Style name
45
47
  * @param value Style value
@@ -49,6 +51,7 @@ function setStyle(element, property, value) {
49
51
  }
50
52
  /**
51
53
  * Set styles on an element
54
+ *
52
55
  * @param element Element to set the styles on
53
56
  * @param styles Styles to set
54
57
  */
@@ -57,6 +60,7 @@ function setStyles(element, styles) {
57
60
  }
58
61
  /**
59
62
  * Toggle styles for an element
63
+ *
60
64
  * @param element Element to style
61
65
  * @param styles Styles to be set or removed
62
66
  * @returns Style toggler
package/dist/touch.d.mts CHANGED
@@ -6,10 +6,14 @@ type SupporsTouch = {
6
6
  readonly value: boolean;
7
7
  /**
8
8
  * Are touch events supported?
9
+ *
10
+ * @returns `true` if touch events are supported, otherwise `false`
9
11
  */
10
12
  get(): boolean;
11
13
  /**
12
14
  * Re-evaluate if touch events are supported
15
+ *
16
+ * @returns `true` if touch events are supported, otherwise `false`
13
17
  */
14
18
  update(): boolean;
15
19
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/toretto",
3
- "version": "0.45.0",
3
+ "version": "0.47.0",
4
4
  "description": "A collection of badass DOM utilities.",
5
5
  "keywords": [
6
6
  "dom",
@@ -30,6 +30,10 @@
30
30
  "types": "./dist/index.d.mts",
31
31
  "default": "./dist/index.mjs"
32
32
  },
33
+ "./aria": {
34
+ "types": "./dist/aria.d.mts",
35
+ "default": "./dist/aria.mjs"
36
+ },
33
37
  "./attribute": {
34
38
  "types": "./dist/attribute/index.d.mts",
35
39
  "default": "./dist/attribute/index.mjs"
@@ -86,15 +90,15 @@
86
90
  "test:leak": "npx vp test run --detect-async-leaks --coverage"
87
91
  },
88
92
  "dependencies": {
89
- "@oscarpalmer/atoms": "^0.185"
93
+ "@oscarpalmer/atoms": "^0.188.1"
90
94
  },
91
95
  "devDependencies": {
92
- "@oxlint/plugins": "^1.62",
93
- "@types/node": "^25.6",
96
+ "@oxlint/plugins": "^1.73",
97
+ "@types/node": "^26.1",
94
98
  "@vitest/coverage-istanbul": "^4.1",
95
99
  "jsdom": "^29.1",
96
- "tsdown": "^0.21",
97
- "typescript": "^5.9",
100
+ "tsdown": "^0.22",
101
+ "typescript": "^6",
98
102
  "vite": "npm:@voidzero-dev/vite-plus-core@latest",
99
103
  "vite-plus": "latest",
100
104
  "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
package/src/aria.ts ADDED
@@ -0,0 +1,166 @@
1
+ import {setElementValues, updateElementValue} from './internal/element-value';
2
+ import type {AriaAttribute, AriaAttributeUnprefixed, AriaRole} from './models';
3
+
4
+ // #region Types
5
+
6
+ type AnyAriaAttribute = AriaAttribute | AriaAttributeUnprefixed;
7
+
8
+ type AriaAttributeItem = {
9
+ name: AnyAriaAttribute;
10
+ value?: string;
11
+ };
12
+
13
+ // #endregion
14
+
15
+ // #region Functions
16
+
17
+ /**
18
+ * Get the value of a specific _ARIA_ attribute from an element
19
+ *
20
+ * @param element Element to get _ARIA_ attribute from
21
+ * @param name _ARIA_ name
22
+ * @returns _ARIA_ value _(or `undefined`)_
23
+ */
24
+ export function getAria(element: Element, attribute: AnyAriaAttribute): string | undefined;
25
+
26
+ /**
27
+ * Get specific _ARIA_ attributes from an element
28
+ *
29
+ * @param element Element to get _ARIA_ attributes from
30
+ * @param names _ARIA_ attribute names
31
+ * @returns Object of named _ARIA_ attributes
32
+ */
33
+ export function getAria<Attribute extends AnyAriaAttribute>(
34
+ element: Element,
35
+ attributes: Attribute[],
36
+ ): Record<Attribute, string | undefined>;
37
+
38
+ export function getAria(element: Element, value: string | string[]): unknown {
39
+ if (!(element instanceof Element)) {
40
+ return Array.isArray(value) ? {} : undefined;
41
+ }
42
+
43
+ if (!Array.isArray(value)) {
44
+ return typeof value === 'string' ? getAriaValue(element, value) : undefined;
45
+ }
46
+
47
+ const arias = {} as Record<string, string | undefined>;
48
+
49
+ const {length} = value;
50
+
51
+ for (let index = 0; index < length; index += 1) {
52
+ const attribute = value[index];
53
+
54
+ if (typeof attribute === 'string') {
55
+ arias[attribute.replace(ATTRIBUTE_ARIA_PREFIX, '')] = getAriaValue(element, attribute);
56
+ }
57
+ }
58
+
59
+ return arias;
60
+ }
61
+
62
+ function getAriaValue(element: Element, attribute: string): string | undefined {
63
+ return element.getAttribute(getName(attribute)) ?? undefined;
64
+ }
65
+
66
+ function getName(value: string): string {
67
+ return EXPRESSION_ARIA_PREFIX.test(value) ? value : `${ATTRIBUTE_ARIA_PREFIX}${value}`;
68
+ }
69
+
70
+ /**
71
+ * Get the role of an element
72
+ *
73
+ * @param element Element to get role from
74
+ * @returns Element role _(or `undefined`)_
75
+ */
76
+ export function getRole(element: Element): unknown {
77
+ if (element instanceof Element) {
78
+ return element.getAttribute('role') ?? undefined;
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Set an _ARIA_ attribute on an element
84
+ *
85
+ * _(Or remove it, if value is `null` or `undefined`)_
86
+ *
87
+ * @param element Element for _ARIA_ attribute
88
+ * @param attribute _ARIA_ attribute to set
89
+ * @param value _ARIA_ attribute value
90
+ */
91
+ export function setAria(element: Element, attribute: AnyAriaAttribute, value?: string): void;
92
+
93
+ /**
94
+ * Set one or more _ARIA_ attributes on an element
95
+ *
96
+ * _(Or remove them, if their value is `null` or `undefined`)_
97
+ *
98
+ * @param element Element for _ARIA_ attributes
99
+ * @param attributes _ARIA_ attributes to set
100
+ */
101
+ export function setAria(element: Element, attributes: AriaAttributeItem[]): void;
102
+
103
+ /**
104
+ * Set one or more _ARIA_ attributes on an element
105
+ *
106
+ * _(Or remove them, if their value is `null` or `undefined`)_
107
+ *
108
+ * @param element Element for _ARIA_ attributes
109
+ * @param attributes _ARIA_ attributes to set
110
+ */
111
+ export function setAria(
112
+ element: Element,
113
+ attributes: Partial<Record<AnyAriaAttribute, unknown>>,
114
+ ): void;
115
+
116
+ export function setAria(
117
+ element: Element,
118
+ first: AnyAriaAttribute | AriaAttributeItem[] | Partial<Record<AnyAriaAttribute, unknown>>,
119
+ second?: unknown,
120
+ ): void {
121
+ setElementValues(element, first, second, null, updateAriaAttribute);
122
+ }
123
+
124
+ /**
125
+ * Set the role of an element
126
+ *
127
+ * @param element Element for role
128
+ * @param role Role to set _(or `undefined` to remove it)_
129
+ */
130
+ export function setRole(element: Element, role?: AriaRole): void {
131
+ if (!(element instanceof Element)) {
132
+ return;
133
+ }
134
+
135
+ if (typeof role === 'string') {
136
+ element.setAttribute('role', role);
137
+ } else {
138
+ element.removeAttribute('role');
139
+ }
140
+ }
141
+
142
+ function updateAriaAttribute(element: Element, key: string, value: unknown): void {
143
+ updateElementValue(
144
+ element,
145
+ getName(key),
146
+ value,
147
+ // Using `.call` in `updateElementValue`
148
+ // oxlint-disable-next-line typescript/unbound-method
149
+ element.setAttribute,
150
+ // Using `.call` in `updateElementValue`
151
+ // oxlint-disable-next-line typescript/unbound-method
152
+ element.removeAttribute,
153
+ false,
154
+ false,
155
+ );
156
+ }
157
+
158
+ // #endregion
159
+
160
+ // #region Variables
161
+
162
+ const ATTRIBUTE_ARIA_PREFIX = 'aria-';
163
+
164
+ const EXPRESSION_ARIA_PREFIX = /^aria-/i;
165
+
166
+ // #endregion