@splendidlabz/utils 1.5.0-alpha.3 → 1.5.0-alpha.4

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @splendidlabz/utils
2
2
 
3
+ ## 1.5.0-alpha.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Updates
8
+
3
9
  ## 1.5.0-alpha.3
4
10
 
5
11
  ### Minor Changes
@@ -1,5 +1,3 @@
1
1
  export * from './masonry.js'
2
- export * from './mutation-observer.js'
3
2
  export * from './prefer-horizontal-scroll.js'
4
- export * from './resize-observer.js'
5
3
  export * from './sticky.js'
@@ -1,6 +1,6 @@
1
- import { getChildrenElements, mediaLoaded } from '../dom/index.js'
2
-
3
- import { resizeObserver } from './resize-observer.js'
1
+ import { getChildrenElements } from '../get-element.js'
2
+ import { mediaLoaded } from '../media.js'
3
+ import { resizeObserver } from '../observers/resize-observer.js'
4
4
 
5
5
  export async function masonry(node) {
6
6
  if (nativeMasonrySupport(node)) return
@@ -3,9 +3,9 @@ import {
3
3
  getCSSVar,
4
4
  removeListeners,
5
5
  setCSSVar,
6
- } from '../dom/index.js'
6
+ } from '../index.js'
7
7
 
8
- import { omitEmpty } from '../lib/index.js'
8
+ import { omitEmpty } from '../../lib/index.js'
9
9
 
10
10
  const DEFAULT_OPTIONS = {
11
11
  scrollSnapDelay: 1000,
@@ -1,12 +1,9 @@
1
- import {
2
- boundingBoxRelativeToAncestor,
3
- findScrollContainer,
4
- } from '../dom/index.js'
5
- import { resizeObserver } from './resize-observer.js'
1
+ import { boundingBoxRelativeToAncestor } from '../bounding-box.js'
2
+ import { resizeObserver } from '../observers/resize-observer.js'
3
+ import { findScrollContainer } from '../ui/scroll-container.js'
6
4
 
7
5
  export function sticky(node, props = {}) {
8
6
  const scrollContainer = findScrollContainer(node)
9
-
10
7
  let stickyTBLR = getComputedTBLR(node)
11
8
 
12
9
  const obs = resizeObserver(node, {
package/dom/events.js CHANGED
@@ -10,12 +10,13 @@ export function removeListeners(listeners) {
10
10
  })
11
11
  }
12
12
 
13
+ // Dispatch a custom event from a Node.
13
14
  export function dispatchEvent(node, eventName, detail, options = {}) {
14
15
  node.dispatchEvent(
15
16
  new CustomEvent(eventName, {
16
17
  ...options,
17
18
  detail,
18
- }),
19
+ })
19
20
  )
20
21
  }
21
22
 
package/dom/font-size.js CHANGED
@@ -6,13 +6,19 @@ export function getUnit(value) {
6
6
  }
7
7
 
8
8
  export function em(element = document.body, multiple = 1) {
9
- const unit = parseFloat(getComputedStyle(element)['font-size'])
10
- return Math.round(unit * multiple)
9
+ const value = parseFloat(getComputedStyle(element)['font-size'])
10
+ return Math.round(value * multiple)
11
11
  }
12
12
 
13
13
  export function rem(multiple = 1) {
14
- const unit = parseFloat(getComputedStyle(document.body)['font-size'])
15
- return Math.round(unit * multiple)
14
+ const value = parseFloat(getComputedStyle(document.body)['font-size'])
15
+ return Math.round(value * multiple)
16
+ }
17
+
18
+ export function lh(element = document.body, multiple = 1) {
19
+ const lineHeight = getComputedStyle(element)['line-height']
20
+ const value = parseFloat(lineHeight)
21
+ return Math.round(value * multiple)
16
22
  }
17
23
 
18
24
  export function toPx(value, element = null) {
@@ -21,6 +27,7 @@ export function toPx(value, element = null) {
21
27
 
22
28
  if (unit === 'rem') finalValue = rem(numeric)
23
29
  if (unit === 'em') finalValue = em(element, numeric)
30
+ if (unit === 'lh') finalValue = lh(element, numeric)
24
31
  if (unit === 'px') finalValue = numeric
25
32
  if (!unit) finalValue = numeric // Default to px offsets
26
33
 
@@ -4,6 +4,13 @@
4
4
 
5
5
  const astroNodes = ['ASTRO-SLOT', 'ASTRO-ISLAND']
6
6
 
7
+ // Returns the type of the node.
8
+ export function getNodeType(node) {
9
+ if (node instanceof Element) return 'element'
10
+ if (node instanceof NodeList) return 'nodelist'
11
+ if (Array.isArray(node)) return 'array'
12
+ }
13
+
7
14
  export function getElement(selector) {
8
15
  if (!selector) return
9
16
  if (selector instanceof HTMLElement) return selector
@@ -26,7 +33,7 @@ export function getParentElement(element) {
26
33
 
27
34
  export function getSiblingElements(element) {
28
35
  return Array.from(element.parentElement.children).filter(
29
- child => child !== element,
36
+ child => child !== element
30
37
  )
31
38
  }
32
39
 
package/dom/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './accessibility.js'
2
+ export * from './actions/index.js'
2
3
  export * from './bounding-box.js'
3
4
  export * from './clipboard.js'
4
5
  export * from './cookie.js'
@@ -11,6 +12,7 @@ export * from './hash.js'
11
12
  export * from './keyboard.js'
12
13
  export * from './local-store.js'
13
14
  export * from './media.js'
15
+ export * from './observers/index.js'
14
16
  export * from './pkce.js'
15
17
  export * from './query-params.js'
16
18
  export * from './random-string.js'
package/dom/media.js CHANGED
@@ -5,6 +5,7 @@ export async function imagesLoaded(node) {
5
5
  if (img.complete) return resolve()
6
6
  img.onload = resolve
7
7
  img.onerror = e => {
8
+ // eslint-disable-next-line prefer-promise-reject-errors
8
9
  reject('Image failed to load')
9
10
  }
10
11
  })
@@ -0,0 +1,3 @@
1
+ export * from './intersection-observer.js'
2
+ export * from './mutation-observer.js'
3
+ export * from './resize-observer.js'
@@ -0,0 +1,43 @@
1
+ import { dispatchEvent } from '../events.js'
2
+ import { useObserverMethodOnTarget } from './observer.js'
3
+
4
+ // See https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver#options for options
5
+ export function intersectionObserver(target, options = {}) {
6
+ const { callback, ...opts } = options
7
+ const observer = new IntersectionObserver(observerFn, opts)
8
+
9
+ useObserverMethodOnTarget(target, observer, 'observe')
10
+
11
+ function observerFn(entries) {
12
+ for (const entry of entries) {
13
+ if (callback) callback({ entry, entries, observer })
14
+ else dispatchEvent(target, 'intersect', { entry, entries, observer })
15
+ }
16
+ }
17
+
18
+ return {
19
+ observer,
20
+ observe(target, options) {
21
+ useObserverMethodOnTarget(target, observer, 'observe', options)
22
+ },
23
+
24
+ unobserve(target) {
25
+ useObserverMethodOnTarget(target, observer, 'unobserve')
26
+ },
27
+
28
+ takeRecords() {
29
+ return observer.takeRecords()
30
+ },
31
+
32
+ disconnect() {
33
+ // Take records before disconnecting.
34
+ const records = observer.takeRecords()
35
+ observer.disconnect()
36
+ if (records.length > 0) observerFn(records)
37
+ },
38
+
39
+ destroy() {
40
+ observer.disconnect()
41
+ },
42
+ }
43
+ }
@@ -0,0 +1,51 @@
1
+ /* eslint-env browser */
2
+ import { dispatchEvent } from '../events.js'
3
+ import { useObserverMethodOnTarget } from './observer.js'
4
+
5
+ // https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe
6
+
7
+ // These are simply options that will often be used. Check the docs for other options. Adding them here simply because it's easier to refer them here than reading the docs.
8
+ const defaultOptions = {
9
+ attributes: false,
10
+ childList: false,
11
+ subtree: false,
12
+ }
13
+
14
+ export function mutationObserver(target, options) {
15
+ options = { ...defaultOptions, ...options }
16
+ const { callback, ...opts } = options
17
+ const observer = new MutationObserver(observerFn)
18
+
19
+ if (target === window) target = document.body
20
+ useObserverMethodOnTarget(target, observer, 'observe', opts)
21
+
22
+ function observerFn(entries) {
23
+ for (const entry of entries) {
24
+ if (callback) callback({ entry, entries, observer })
25
+ else dispatchEvent(target, 'mutate', { entry, entries, observer })
26
+ }
27
+ }
28
+
29
+ return {
30
+ observer,
31
+ observe(target, options) {
32
+ useObserverMethodOnTarget(target, observer, 'observe', options)
33
+ },
34
+
35
+ takeRecords() {
36
+ return observer.takeRecords()
37
+ },
38
+
39
+ disconnect() {
40
+ // Take records before disconnecting.
41
+ // https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/takeRecords
42
+ const records = observer.takeRecords()
43
+ observer.disconnect()
44
+ if (records.length > 0) observerFn(records)
45
+ },
46
+
47
+ destroy() {
48
+ observer.disconnect()
49
+ },
50
+ }
51
+ }
@@ -0,0 +1,18 @@
1
+ import { getNodeType } from '../get-element.js'
2
+
3
+ export function useObserverMethodOnTarget(
4
+ target,
5
+ observer,
6
+ method = 'observe',
7
+ options = undefined
8
+ ) {
9
+ const targetType = getNodeType(target)
10
+ if (targetType === 'element') observer[method](target, options)
11
+ if (targetType === 'nodelist') {
12
+ const elements = Array.from(target)
13
+ elements.forEach(element => observer[method](element, options))
14
+ }
15
+ if (targetType === 'array') {
16
+ target.forEach(element => observer[method](element, options))
17
+ }
18
+ }
@@ -0,0 +1,34 @@
1
+ /* eslint-env browser */
2
+ import { dispatchEvent } from '../events.js'
3
+ import { useObserverMethodOnTarget } from './observer.js'
4
+
5
+ export function resizeObserver(target, options) {
6
+ // We set the option here to prevent observer from being created unless necessary.
7
+ options = { observe: true, ...options }
8
+ if (!options.observe) return
9
+ const { callback, ...opts } = options
10
+ const observer = new ResizeObserver(observerFn)
11
+
12
+ if (target === window) target = document.body
13
+ useObserverMethodOnTarget(target, observer, 'observe', opts)
14
+
15
+ function observerFn(entries) {
16
+ for (const entry of entries) {
17
+ if (callback) callback({ entry, entries, observer })
18
+ else dispatchEvent(target, 'resize-obs', { entry, entries, observer })
19
+ }
20
+ }
21
+
22
+ return {
23
+ observe(target, options) {
24
+ useObserverMethodOnTarget(target, observer, 'observe', options)
25
+ },
26
+
27
+ unobserve(target) {
28
+ useObserverMethodOnTarget(target, observer, 'unobserve')
29
+ },
30
+
31
+ disconnect: _ => observer.disconnect(),
32
+ destroy: _ => observer.disconnect(),
33
+ }
34
+ }
@@ -1,5 +1,6 @@
1
1
  import DOMPurify from 'dompurify'
2
2
 
3
+ // MIGHT HAVE TO SHIFT THIS TO DOM, because DOMPurify doesn't work with Node
3
4
  /**
4
5
  * Sanitizes HTML string using DOMPurify.
5
6
  * @param {string} html - The HTML string to sanitize.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splendidlabz/utils",
3
- "version": "1.5.0-alpha.3",
3
+ "version": "1.5.0-alpha.4",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -9,8 +9,6 @@
9
9
  "./lib/*": "./lib/*.js",
10
10
  "./dom": "./dom/index.js",
11
11
  "./dom/*": "./dom/*.js",
12
- "./actions": "./actions/index.js",
13
- "./actions/*": "./actions/*.js",
14
12
  "./node": "./node/index.js",
15
13
  "./node/*": "./node/*.js"
16
14
  },
@@ -30,7 +28,7 @@
30
28
  "statuses": "^2.0.1"
31
29
  },
32
30
  "devDependencies": {
33
- "@splendidlabz/eslint-config": "2.0.0-alpha.0",
31
+ "@splendidlabz/eslint-config": "2.0.0-alpha.1",
34
32
  "jsdom": "^26.0.0",
35
33
  "np": "^10.2.0",
36
34
  "vitest": "^3.1.1"
@@ -1,10 +0,0 @@
1
-
2
- > @splendidlabs/utils@1.0.3 lint
3
- > eslint . --fix
4
-
5
- 
6
- /Users/zellwk/projects/@splendidlabs/packages/utils/lib/index.test.js
7
-  4:10 error 'expect' is defined but never used no-unused-vars
8
- 
9
- ✖ 1 problem (1 error, 0 warnings)
10
- 
@@ -1,10 +0,0 @@
1
-
2
- > @splendidlabs/utils@1.0.3 test
3
- > vitest run
4
-
5
- sh: vitest: command not found
6
- npm ERR! Lifecycle script `test` failed with error:
7
- npm ERR! Error: command failed
8
- npm ERR!  in workspace: @splendidlabs/utils@1.0.3
9
- npm ERR!  at location: /Users/zellwk/projects/@splendidlabs/packages/utils
10
- 
@@ -1,37 +0,0 @@
1
- // See https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver#options for options
2
- const options = {}
3
-
4
- export function intersectionObserver(node, options) {
5
- const { callback, opts } = options
6
- const observer = new IntersectionObserver(observerFn, opts)
7
-
8
- function observerFn(entries, observer) {
9
- entries.forEach(entry => {
10
- for (const entry of entries) {
11
- // Needs testing to see what's in entry
12
- if (callback) callback({ node, entry, observer })
13
- else {
14
- node.dispatchEvent(
15
- new CustomEvent('intersect', {
16
- detail: { node, entry, observer },
17
- }),
18
- )
19
- }
20
- }
21
- })
22
- }
23
-
24
- observer.observe(node)
25
-
26
- return {
27
- observer,
28
- disconnect() {
29
- observer.disconnect()
30
- },
31
-
32
- // Destroy is used for Svelte actions
33
- destroy() {
34
- observer.disconnect()
35
- },
36
- }
37
- }
@@ -1,42 +0,0 @@
1
- /* eslint-env browser */
2
- // https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe
3
-
4
- // These are simply options that will often be used. Check the docs for other options.
5
- const defaultOptions = {
6
- attributes: false,
7
- childList: false,
8
- subtree: false,
9
- }
10
-
11
- export function mutationObserver(node, options) {
12
- options = { ...defaultOptions, ...options }
13
- const { callback, ...opts } = options
14
- const observer = new MutationObserver(observerFn)
15
-
16
- function observerFn(entries) {
17
- for (const entry of entries) {
18
- if (callback) callback({ node, entry, observer })
19
- else {
20
- node.dispatchEvent(
21
- new CustomEvent('mutate', {
22
- detail: { node, entry, observer },
23
- }),
24
- )
25
- }
26
- }
27
- }
28
-
29
- if (node === window) node = document.body
30
- observer.observe(node, opts)
31
-
32
- return {
33
- disconnect() {
34
- observer.disconnect()
35
- },
36
-
37
- // Destroy is used for Svelte actions
38
- destroy() {
39
- observer.disconnect()
40
- },
41
- }
42
- }
@@ -1,33 +0,0 @@
1
- /* eslint-env browser */
2
- export function resizeObserver(node, options) {
3
- // We set the option here to prevent observer from being created unless necessary.
4
- options = { observe: true, ...options }
5
- if (!options.observe) return
6
-
7
- const observer = new ResizeObserver(observerFn)
8
-
9
- function observerFn(entries) {
10
- for (const entry of entries) {
11
- if (options.callback) options.callback({ node, entry, entries, observer })
12
- else {
13
- node.dispatchEvent(
14
- new CustomEvent('resize-obs', {
15
- detail: { node, entry, entries, observer },
16
- }),
17
- )
18
- }
19
- }
20
- }
21
-
22
- observer.observe(node)
23
-
24
- return {
25
- disconnect() {
26
- observer.unobserve(node)
27
- },
28
-
29
- destroy() {
30
- observer.unobserve(node)
31
- },
32
- }
33
- }