@inglorious/web 6.2.0 → 6.3.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.
package/package.json CHANGED
@@ -1,8 +1,15 @@
1
1
  {
2
2
  "name": "@inglorious/web",
3
- "version": "6.2.0",
3
+ "version": "6.3.0",
4
4
  "description": "A new web framework that leverages the power of the Inglorious Store combined with the performance and simplicity of lit-html.",
5
- "author": "IceOnFire <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
5
+ "author": "Matteo Antony Mistretta <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
6
+ "contributors": [
7
+ {
8
+ "name": "Luis Cruz",
9
+ "email": "stackbuilder1228@gmail.com",
10
+ "url": "https://topstar-ai.github.io/"
11
+ }
12
+ ],
6
13
  "license": "MIT",
7
14
  "repository": {
8
15
  "type": "git",
@@ -38,6 +45,10 @@
38
45
  "types": "./types/directives/*.d.ts",
39
46
  "import": "./src/directives/*.js"
40
47
  },
48
+ "./element-size": {
49
+ "types": "./types/element-size.d.ts",
50
+ "import": "./src/element-size/index.js"
51
+ },
41
52
  "./form": {
42
53
  "types": "./types/form.d.ts",
43
54
  "import": "./src/form/index.js"
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @typedef {import("../../types/element-size.js").ElementSizeEntity} ElementSizeEntity
3
+ * @typedef {import("../../types/element-size.js").ElementSizeSize} ElementSizeSize
4
+ */
5
+
6
+ // Observers aren't serializable, so they're kept here by id, not on the entity.
7
+ const observers = new Map()
8
+
9
+ /**
10
+ * Initializes the entity state and starts observing the target element's size.
11
+ * @param {ElementSizeEntity} entity - The element size entity.
12
+ * @param {{ notify: Function }} api - The store API.
13
+ */
14
+ export function create(entity, _, api) {
15
+ entity.width ??= null
16
+ entity.height ??= null
17
+ entity.isWatching ??= false
18
+
19
+ elementSizeWatch(entity, _, api)
20
+ }
21
+
22
+ /**
23
+ * Disconnects the observer before the entity is destroyed.
24
+ * @param {ElementSizeEntity} entity - The element size entity.
25
+ */
26
+ export function destroy(entity) {
27
+ elementSizeUnwatch(entity)
28
+ }
29
+
30
+ /**
31
+ * Starts observing the target element for size changes.
32
+ * @param {ElementSizeEntity} entity - The element size entity.
33
+ * @param {{ notify: Function }} api - The store API.
34
+ */
35
+ export function elementSizeWatch(entity, _, api) {
36
+ entity.isSupported = isSupported()
37
+
38
+ if (!entity.isSupported || observers.has(entity.id)) {
39
+ return
40
+ }
41
+
42
+ const element = getElement(entity)
43
+
44
+ if (!element) {
45
+ return
46
+ }
47
+
48
+ // Snapshot the id while the draft proxy is still live: the callback below
49
+ // runs after this handler returns, when Mutative has revoked the draft.
50
+ const id = entity.id
51
+
52
+ const observer = new globalThis.ResizeObserver((entries) => {
53
+ api.notify(`#${id}:elementSizeChange`, getSize(entries))
54
+ })
55
+ observer.observe(element)
56
+
57
+ observers.set(id, observer)
58
+ entity.isWatching = true
59
+ }
60
+
61
+ /**
62
+ * Stores the latest observed dimensions.
63
+ * @param {ElementSizeEntity} entity - The element size entity.
64
+ * @param {ElementSizeSize} size - The observed dimensions.
65
+ */
66
+ export function elementSizeChange(entity, size) {
67
+ entity.width = size.width
68
+ entity.height = size.height
69
+ }
70
+
71
+ /**
72
+ * Stops observing size changes and drops the observer from the registry.
73
+ * @param {ElementSizeEntity} entity - The element size entity.
74
+ */
75
+ export function elementSizeUnwatch(entity) {
76
+ const observer = observers.get(entity.id)
77
+
78
+ if (observer) {
79
+ observer.disconnect()
80
+ observers.delete(entity.id)
81
+ }
82
+
83
+ entity.isWatching = false
84
+ }
85
+
86
+ function getSize(entries) {
87
+ const [entry] = entries
88
+ const rect = entry.contentRect
89
+ return { width: rect.width, height: rect.height }
90
+ }
91
+
92
+ function getElement(entity) {
93
+ const doc = globalThis.document
94
+
95
+ if (!doc) {
96
+ return null
97
+ }
98
+
99
+ const selected = entity.selector ? doc.querySelector(entity.selector) : null
100
+ return selected ?? doc.documentElement
101
+ }
102
+
103
+ function isSupported() {
104
+ return (
105
+ typeof globalThis.ResizeObserver !== "undefined" &&
106
+ Boolean(globalThis.document?.documentElement)
107
+ )
108
+ }
@@ -0,0 +1,3 @@
1
+ import * as handlers from "./handlers.js"
2
+
3
+ export const ElementSize = { ...handlers }
@@ -0,0 +1,26 @@
1
+ import { Api } from "./mount"
2
+
3
+ export interface ElementSizeEntity {
4
+ height: number | null
5
+ id: string | number
6
+ isSupported: boolean
7
+ isWatching: boolean
8
+ selector?: string | null
9
+ type?: "ElementSize"
10
+ width: number | null
11
+ }
12
+
13
+ export interface ElementSizeSize {
14
+ height: number
15
+ width: number
16
+ }
17
+
18
+ export interface ElementSizeType {
19
+ create(entity: ElementSizeEntity, payload: unknown, api: Api): void
20
+ destroy(entity: ElementSizeEntity): void
21
+ elementSizeChange(entity: ElementSizeEntity, size: ElementSizeSize): void
22
+ elementSizeWatch(entity: ElementSizeEntity, payload: unknown, api: Api): void
23
+ elementSizeUnwatch(entity: ElementSizeEntity): void
24
+ }
25
+
26
+ export declare const ElementSize: ElementSizeType