@oscarpalmer/toretto 0.35.0 → 0.37.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.
@@ -1,12 +1,13 @@
1
1
  function findAncestor(origin, selector) {
2
- if (!(origin instanceof Element) || selector == null) return null;
2
+ const element = getElement(origin);
3
+ if (element == null || selector == null) return null;
3
4
  if (typeof selector === "string") {
4
- if (origin.matches?.(selector)) return origin;
5
- return origin.closest(selector);
5
+ if (element.matches?.(selector)) return element;
6
+ return element.closest(selector);
6
7
  }
7
8
  if (typeof selector !== "function") return null;
8
- if (selector(origin)) return origin;
9
- let parent = origin.parentElement;
9
+ if (selector(element)) return element;
10
+ let parent = element.parentElement;
10
11
  while (parent != null && !selector(parent)) {
11
12
  if (parent === document.body) return null;
12
13
  parent = parent.parentElement;
@@ -45,6 +46,10 @@ function getDistance(origin, target) {
45
46
  const preceding = comparison & Node.DOCUMENT_POSITION_PRECEDING;
46
47
  return traverse(preceding ? origin : target, preceding ? target : origin) ?? -1;
47
48
  }
49
+ function getElement(origin) {
50
+ if (origin instanceof Element) return origin;
51
+ return origin instanceof Event && origin.target instanceof Element ? origin.target : void 0;
52
+ }
48
53
  function traverse(from, to) {
49
54
  let current = from;
50
55
  let distance = 0;
@@ -368,7 +368,7 @@ function toCaseCallback(value) {
368
368
  const { capitalizeAny, capitalizeFirst, type } = this;
369
369
  const parts = words(value);
370
370
  const partsLength = parts.length;
371
- const result = [];
371
+ const cased = [];
372
372
  for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
373
373
  const items = parts[partIndex].replace(EXPRESSION_ACRONYM, (full, one, two, three) => three === "s" ? full : `${one}-${two}${three}`).replace(EXPRESSION_CAMEL_CASE, REPLACEMENT_CAMEL_CASE).split("-");
374
374
  const itemsLength = items.length;
@@ -381,9 +381,9 @@ function toCaseCallback(value) {
381
381
  else partResult.push(capitalize(item));
382
382
  itemCount += 1;
383
383
  }
384
- result.push(join(partResult, delimiters[type]));
384
+ cased.push(join(partResult, delimiters[type]));
385
385
  }
386
- return join(result, delimiters[type]);
386
+ return join(cased, delimiters[type]);
387
387
  }
388
388
  var EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
389
389
  var EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
@@ -417,7 +417,7 @@ function handleValue(data, path, value, get, ignoreCase) {
417
417
  if (typeof data === "object" && data !== null && !ignoreKey(path)) {
418
418
  const key = ignoreCase ? findKey(path, data) : path;
419
419
  if (get) return data[key];
420
- data[key] = value;
420
+ data[key] = typeof value === "function" ? value(data[key]) : value;
421
421
  }
422
422
  }
423
423
  var EXPRESSION_BRACKET = /\[(\w+)\]/g;
@@ -656,14 +656,15 @@ function on(target, type, listener, options) {
656
656
  }
657
657
  const PROPERTY_DETAIL = "detail";
658
658
  function findAncestor(origin, selector) {
659
- if (!(origin instanceof Element) || selector == null) return null;
659
+ const element = getElement(origin);
660
+ if (element == null || selector == null) return null;
660
661
  if (typeof selector === "string") {
661
- if (origin.matches?.(selector)) return origin;
662
- return origin.closest(selector);
662
+ if (element.matches?.(selector)) return element;
663
+ return element.closest(selector);
663
664
  }
664
665
  if (typeof selector !== "function") return null;
665
- if (selector(origin)) return origin;
666
- let parent = origin.parentElement;
666
+ if (selector(element)) return element;
667
+ let parent = element.parentElement;
667
668
  while (parent != null && !selector(parent)) {
668
669
  if (parent === document.body) return null;
669
670
  parent = parent.parentElement;
@@ -702,6 +703,10 @@ function getDistance(origin, target) {
702
703
  const preceding = comparison & Node.DOCUMENT_POSITION_PRECEDING;
703
704
  return traverse(preceding ? origin : target, preceding ? target : origin) ?? -1;
704
705
  }
706
+ function getElement(origin) {
707
+ if (origin instanceof Element) return origin;
708
+ return origin instanceof Event && origin.target instanceof Element ? origin.target : void 0;
709
+ }
705
710
  function traverse(from, to) {
706
711
  let current = from;
707
712
  let distance = 0;
package/package.json CHANGED
@@ -4,19 +4,19 @@
4
4
  "url": "https://oscarpalmer.se"
5
5
  },
6
6
  "dependencies": {
7
- "@oscarpalmer/atoms": "^0.127"
7
+ "@oscarpalmer/atoms": "^0.128.1"
8
8
  },
9
9
  "description": "A collection of badass DOM utilities.",
10
10
  "devDependencies": {
11
11
  "@types/node": "^25",
12
12
  "@vitest/coverage-istanbul": "^4",
13
13
  "jsdom": "^27.4",
14
- "oxfmt": "^0.22",
15
- "oxlint": "^1.38",
16
- "rolldown": "1.0.0-beta.58",
14
+ "oxfmt": "^0.26",
15
+ "oxlint": "^1.41",
16
+ "rolldown": "1.0.0-beta.60",
17
17
  "tslib": "^2.8",
18
18
  "typescript": "^5.9",
19
- "vite": "8.0.0-beta.5",
19
+ "vite": "8.0.0-beta.8",
20
20
  "vitest": "^4"
21
21
  },
22
22
  "exports": {
@@ -93,5 +93,5 @@
93
93
  },
94
94
  "type": "module",
95
95
  "types": "types/index.d.ts",
96
- "version": "0.35.0"
96
+ "version": "0.37.0"
97
97
  }
package/src/find/index.ts CHANGED
@@ -1,12 +1,25 @@
1
1
  import type {PlainObject} from '@oscarpalmer/atoms';
2
2
  import type {Selector} from '../models';
3
3
 
4
+ /**
5
+ * Find the first element that matches the tag name
6
+ * @param tagName Tag name of element to find
7
+ * @param context Context to search within _(defaults to `document`)_
8
+ * @returns Found element or `null`
9
+ */
10
+ export function findElement<TagName extends keyof HTMLElementTagNameMap>(
11
+ tagName: TagName,
12
+ context?: Selector | null,
13
+ ): HTMLElementTagNameMap[TagName] | null;
14
+
4
15
  /**
5
16
  * Find the first element that matches the selector
6
17
  * @param selector Selector to find element for
7
18
  * @param context Context to search within _(defaults to `document`)_
8
19
  * @returns Found element or `null`
9
20
  */
21
+ export function findElement(selector: string, context?: Selector | null): Element | null;
22
+
10
23
  export function findElement(selector: string, context?: Selector | null): Element | null {
11
24
  return findElementOrElements(selector, context, true) as never;
12
25
  }
@@ -103,12 +116,25 @@ function findElementOrElementsFromNodes(
103
116
  return result;
104
117
  }
105
118
 
119
+ /**
120
+ * Find elements that match the selector
121
+ * @param tagName tagName to find elements for
122
+ * @param context Context to search within _(defaults to `document`)_
123
+ * @returns Found elements
124
+ */
125
+ export function findElements(
126
+ tagName: keyof HTMLElementTagNameMap,
127
+ context?: Selector | null,
128
+ ): HTMLElementTagNameMap[typeof tagName][];
129
+
106
130
  /**
107
131
  * Find elements that match the selector
108
132
  * @param selector Selector to find elements for
109
133
  * @param context Context to search within _(defaults to `document`)_
110
134
  * @returns Found elements
111
135
  */
136
+ export function findElements(selector: Selector, context?: Selector | null): Element[];
137
+
112
138
  export function findElements(selector: Selector, context?: Selector | null): Element[] {
113
139
  return findElementOrElements(selector, context, false) as never;
114
140
  }
@@ -1,37 +1,58 @@
1
+ /**
2
+ * Find the closest ancestor element that matches the tag name
3
+ *
4
+ * - If no match is found, `null` is returned
5
+ * - _(If you want to search upwards, downwards, and sideways, use {@link findRelatives})_
6
+ * @param origin Origin to start from
7
+ * @param tagName Tag name to match
8
+ * @returns Found ancestor or `null`
9
+ */
10
+ export function findAncestor<TagName extends keyof HTMLElementTagNameMap>(
11
+ origin: Element | Event | EventTarget,
12
+ tagName: TagName,
13
+ ): HTMLElementTagNameMap[TagName] | null;
14
+
1
15
  /**
2
16
  * Find the closest ancestor element that matches the selector _(string or callback)_
3
17
  *
4
18
  * - If no match is found, `null` is returned
5
19
  * - _(If you want to search upwards, downwards, and sideways, use {@link findRelatives})_
6
- * @param origin Element to start from
20
+ * @param origin Origin to start from
7
21
  * @param selector Selector to match
8
22
  * @returns Found ancestor or `null`
9
23
  */
10
24
  export function findAncestor(
11
- origin: Element,
25
+ origin: Element | Event | EventTarget,
26
+ selector: string | ((element: Element) => boolean),
27
+ ): Element | null;
28
+
29
+ export function findAncestor(
30
+ origin: Element | Event | EventTarget,
12
31
  selector: string | ((element: Element) => boolean),
13
32
  ): Element | null {
14
- if (!(origin instanceof Element) || selector == null) {
33
+ const element = getElement(origin);
34
+
35
+ if (element == null || selector == null) {
15
36
  return null;
16
37
  }
17
38
 
18
39
  if (typeof selector === 'string') {
19
- if (origin.matches?.(selector)) {
20
- return origin;
40
+ if (element.matches?.(selector)) {
41
+ return element;
21
42
  }
22
43
 
23
- return origin.closest(selector);
44
+ return element.closest(selector);
24
45
  }
25
46
 
26
47
  if (typeof selector !== 'function') {
27
48
  return null;
28
49
  }
29
50
 
30
- if (selector(origin)) {
31
- return origin;
51
+ if (selector(element)) {
52
+ return element;
32
53
  }
33
54
 
34
- let parent: Element | null = origin.parentElement;
55
+ let parent: Element | null = element.parentElement;
35
56
 
36
57
  while (parent != null && !selector(parent)) {
37
58
  if (parent === document.body) {
@@ -44,6 +65,21 @@ export function findAncestor(
44
65
  return parent;
45
66
  }
46
67
 
68
+ /**
69
+ * Finds the closest elements to the origin element that matches the tag name
70
+ *
71
+ * Traverses up, down, and sideways in the _DOM_-tree. _(If you only want to traverse up, use {@link findAncestor})_
72
+ * @param origin Element to start from
73
+ * @param tagName Tag name to match
74
+ * @param context Context to search within
75
+ * @returns Found elements
76
+ */
77
+ export function findRelatives<TagName extends keyof HTMLElementTagNameMap>(
78
+ origin: Element,
79
+ tagName: TagName,
80
+ context?: Document | Element,
81
+ ): HTMLElementTagNameMap[TagName][];
82
+
47
83
  /**
48
84
  * Finds the closest elements to the origin element that matches the selector
49
85
  *
@@ -53,6 +89,12 @@ export function findAncestor(
53
89
  * @param context Context to search within
54
90
  * @returns Found elements
55
91
  */
92
+ export function findRelatives(
93
+ origin: Element,
94
+ selector: string,
95
+ context?: Document | Element,
96
+ ): Element[];
97
+
56
98
  export function findRelatives(
57
99
  origin: Element,
58
100
  selector: string,
@@ -95,9 +137,7 @@ export function findRelatives(
95
137
  }
96
138
  }
97
139
 
98
- return distances
99
- .filter(found => found.distance === minimum)
100
- .map(found => found.element);
140
+ return distances.filter(found => found.distance === minimum).map(found => found.element);
101
141
  }
102
142
 
103
143
  /**
@@ -132,6 +172,14 @@ export function getDistance(origin: Element, target: Element): number {
132
172
  return traverse(preceding ? origin : target, preceding ? target : origin) ?? -1;
133
173
  }
134
174
 
175
+ function getElement(origin: unknown): Element | undefined {
176
+ if (origin instanceof Element) {
177
+ return origin;
178
+ }
179
+
180
+ return origin instanceof Event && origin.target instanceof Element ? origin.target : undefined;
181
+ }
182
+
135
183
  function traverse(from: Element, to: Element): number | undefined {
136
184
  let current = from;
137
185
  let distance = 0;
@@ -1,4 +1,11 @@
1
1
  import type { Selector } from '../models';
2
+ /**
3
+ * Find the first element that matches the tag name
4
+ * @param tagName Tag name of element to find
5
+ * @param context Context to search within _(defaults to `document`)_
6
+ * @returns Found element or `null`
7
+ */
8
+ export declare function findElement<TagName extends keyof HTMLElementTagNameMap>(tagName: TagName, context?: Selector | null): HTMLElementTagNameMap[TagName] | null;
2
9
  /**
3
10
  * Find the first element that matches the selector
4
11
  * @param selector Selector to find element for
@@ -6,6 +13,13 @@ import type { Selector } from '../models';
6
13
  * @returns Found element or `null`
7
14
  */
8
15
  export declare function findElement(selector: string, context?: Selector | null): Element | null;
16
+ /**
17
+ * Find elements that match the selector
18
+ * @param tagName tagName to find elements for
19
+ * @param context Context to search within _(defaults to `document`)_
20
+ * @returns Found elements
21
+ */
22
+ export declare function findElements(tagName: keyof HTMLElementTagNameMap, context?: Selector | null): HTMLElementTagNameMap[typeof tagName][];
9
23
  /**
10
24
  * Find elements that match the selector
11
25
  * @param selector Selector to find elements for
@@ -1,13 +1,33 @@
1
+ /**
2
+ * Find the closest ancestor element that matches the tag name
3
+ *
4
+ * - If no match is found, `null` is returned
5
+ * - _(If you want to search upwards, downwards, and sideways, use {@link findRelatives})_
6
+ * @param origin Origin to start from
7
+ * @param tagName Tag name to match
8
+ * @returns Found ancestor or `null`
9
+ */
10
+ export declare function findAncestor<TagName extends keyof HTMLElementTagNameMap>(origin: Element | Event | EventTarget, tagName: TagName): HTMLElementTagNameMap[TagName] | null;
1
11
  /**
2
12
  * Find the closest ancestor element that matches the selector _(string or callback)_
3
13
  *
4
14
  * - If no match is found, `null` is returned
5
15
  * - _(If you want to search upwards, downwards, and sideways, use {@link findRelatives})_
6
- * @param origin Element to start from
16
+ * @param origin Origin to start from
7
17
  * @param selector Selector to match
8
18
  * @returns Found ancestor or `null`
9
19
  */
10
- export declare function findAncestor(origin: Element, selector: string | ((element: Element) => boolean)): Element | null;
20
+ export declare function findAncestor(origin: Element | Event | EventTarget, selector: string | ((element: Element) => boolean)): Element | null;
21
+ /**
22
+ * Finds the closest elements to the origin element that matches the tag name
23
+ *
24
+ * Traverses up, down, and sideways in the _DOM_-tree. _(If you only want to traverse up, use {@link findAncestor})_
25
+ * @param origin Element to start from
26
+ * @param tagName Tag name to match
27
+ * @param context Context to search within
28
+ * @returns Found elements
29
+ */
30
+ export declare function findRelatives<TagName extends keyof HTMLElementTagNameMap>(origin: Element, tagName: TagName, context?: Document | Element): HTMLElementTagNameMap[TagName][];
11
31
  /**
12
32
  * Finds the closest elements to the origin element that matches the selector
13
33
  *