powerpagestoolkit 2.5.409 → 2.5.4111
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/README.md +97 -34
- package/dist/DOMNodeReference.d.ts +8 -9
- package/dist/bundle.js +69 -62
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ A TypeScript/JavaScript utility package for seamless DOM manipulation and DataVe
|
|
|
19
19
|
npm install powerpagestoolkit
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
# Core Modules
|
|
23
23
|
|
|
24
24
|
### DOMNodeReference
|
|
25
25
|
|
|
@@ -27,13 +27,28 @@ A powerful class for managing DOM elements with automatic value synchronization
|
|
|
27
27
|
|
|
28
28
|
#### Basic Usage
|
|
29
29
|
|
|
30
|
+
DOMNodeReferences are instantiated with the help of the following factory function
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
createRef(
|
|
34
|
+
target: HTMLElement | string, /* You can target an HTMLElement directly,
|
|
35
|
+
or use standard querySelector syntax */
|
|
36
|
+
multiple: (() => boolean) | boolean = false /* are you targeting a single
|
|
37
|
+
element, or multiple? true = multiple. Default is false (single) */
|
|
38
|
+
): Promise<DOMNodeReference | DOMNodeReferenceArray>;
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Import the utility function for creating DOMNodeReference(s)
|
|
42
|
+
|
|
30
43
|
```typescript
|
|
31
44
|
import { createRef } from "powerpagestoolkit";
|
|
45
|
+
```
|
|
32
46
|
|
|
33
|
-
|
|
47
|
+
Instantiate one, or multiple instances of a DOMNodeReference
|
|
34
48
|
|
|
49
|
+
```typescript
|
|
35
50
|
// Create a single reference
|
|
36
|
-
const node = await createRef("#myElement");
|
|
51
|
+
const node = await createRef("#myElement", false);
|
|
37
52
|
|
|
38
53
|
// Create multiple references
|
|
39
54
|
const nodes = await createRef(".my-class", true);
|
|
@@ -57,14 +72,16 @@ const nodes = await createRef(".my-class", true);
|
|
|
57
72
|
|
|
58
73
|
```typescript
|
|
59
74
|
// Add event listener with proper 'this' context
|
|
75
|
+
// uses standard eventListener API, and so supports all DOM events
|
|
60
76
|
node.on("change", function (e) {
|
|
61
77
|
console.log("Current value:", this.value);
|
|
62
78
|
});
|
|
63
79
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
console.log("Element ready:", instance.element);
|
|
80
|
+
node.on("click", function (e) {
|
|
81
|
+
console.log(this, " has been clicked");
|
|
67
82
|
});
|
|
83
|
+
|
|
84
|
+
...
|
|
68
85
|
```
|
|
69
86
|
|
|
70
87
|
##### Visibility Control
|
|
@@ -73,63 +90,113 @@ node.onceLoaded((instance) => {
|
|
|
73
90
|
// Basic visibility
|
|
74
91
|
node.hide();
|
|
75
92
|
node.show();
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**_Advanced conditional rendering_**
|
|
96
|
+
|
|
97
|
+
Out of the box, Microsoft does not provide PowerPages developers the ability to hide or show fields or form elements based on the value of another field. This method allows such configurations
|
|
76
98
|
|
|
77
|
-
|
|
99
|
+
_Method signature:_
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
DOMNodeReference.configureConditionalRendering(
|
|
103
|
+
condition: () => boolean,
|
|
104
|
+
dependencies?: Array<DOMNodeReference>,
|
|
105
|
+
clearValuesOnHide: boolean = true
|
|
106
|
+
): DOMNodeReference
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
_Example implementation:_
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
78
112
|
node.configureConditionalRendering(
|
|
79
113
|
// Function to evaluate wether this node should be visible or not
|
|
80
114
|
function () {
|
|
81
|
-
return otherNode.value === "
|
|
115
|
+
return otherNode.value === "some value";
|
|
82
116
|
},
|
|
83
|
-
[otherNode]
|
|
117
|
+
[otherNode] /* Dependency array | if the values or visibility of these
|
|
118
|
+
change, the function is re-evaluated */,
|
|
119
|
+
true /* should the values in the targeted elements (this.element)
|
|
120
|
+
be cleared if this node is hidden? Default = true */
|
|
84
121
|
);
|
|
85
122
|
```
|
|
86
123
|
|
|
87
124
|
##### Validation and Requirements
|
|
88
125
|
|
|
126
|
+
This utility enhances PowerPages forms by adding dynamic field validation and conditional requirements based on other field values.
|
|
127
|
+
|
|
128
|
+
_Method signature:_
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// Core method for setting up validation
|
|
132
|
+
function configureValidationAndRequirements(
|
|
133
|
+
isRequired: () => boolean, // Determines if field is required
|
|
134
|
+
isValid: () => boolean, // Validates field content
|
|
135
|
+
fieldDisplayName: string, // User-facing field name for error messages
|
|
136
|
+
dependencies: DOMNodeReference[] // Fields that trigger validation checks
|
|
137
|
+
): DOMNodeReference; /* instance of this is returned for optional
|
|
138
|
+
method chaining */
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
_Example implementation:_
|
|
142
|
+
|
|
89
143
|
```typescript
|
|
90
144
|
node.configureValidationAndRequirements(
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
// Function to evaluate if the data in this field is valid
|
|
145
|
+
// Make field required only when "Yes" is checked
|
|
146
|
+
() => dependentNode.yesRadio?.checked ?? false,
|
|
147
|
+
|
|
148
|
+
// Basic validation: ensure field isn't empty
|
|
96
149
|
function () {
|
|
97
150
|
return this.value != null && this.value !== "";
|
|
98
151
|
},
|
|
99
|
-
|
|
100
|
-
|
|
152
|
+
|
|
153
|
+
"Contact Phone", // Shows in error message: "Contact Phone is required"
|
|
154
|
+
|
|
155
|
+
[dependentNode] // Revalidate when dependentNode changes
|
|
101
156
|
);
|
|
102
157
|
```
|
|
103
158
|
|
|
104
159
|
##### Element Manipulation
|
|
105
160
|
|
|
106
161
|
```typescript
|
|
107
|
-
|
|
108
|
-
|
|
162
|
+
/****/ Value management /****/
|
|
163
|
+
|
|
164
|
+
// set a static value
|
|
165
|
+
node.setValue("new value");
|
|
166
|
+
|
|
109
167
|
// or set a value by using some sort of logic
|
|
110
168
|
node.setValue(() => {
|
|
111
169
|
if (true) {
|
|
112
170
|
return "value";
|
|
113
171
|
} else return "default";
|
|
114
172
|
});
|
|
115
|
-
node.updateValue(); // Sync with DOM
|
|
116
173
|
|
|
117
|
-
//
|
|
174
|
+
// Sync with DOM
|
|
175
|
+
node.updateValue();
|
|
176
|
+
|
|
177
|
+
// Clear the value for both the instance and the target element
|
|
178
|
+
node.clearValue()
|
|
179
|
+
|
|
180
|
+
/****/ Content manipulation /****/
|
|
181
|
+
|
|
118
182
|
node.setInnerHTML("<span>New content</span>");
|
|
119
183
|
node.append(childElement);
|
|
120
184
|
node.prepend(headerElement);
|
|
121
185
|
node.after(siblingElement);
|
|
122
186
|
node.before(labelElement);
|
|
123
187
|
|
|
124
|
-
|
|
188
|
+
/****/ Styling /****/
|
|
189
|
+
|
|
125
190
|
node.setStyle({
|
|
126
191
|
display: "block",
|
|
127
192
|
color: "red",
|
|
128
193
|
});
|
|
129
194
|
|
|
130
|
-
|
|
195
|
+
/****/ State management /****/
|
|
196
|
+
|
|
131
197
|
node.disable();
|
|
132
198
|
node.enable();
|
|
199
|
+
|
|
133
200
|
```
|
|
134
201
|
|
|
135
202
|
##### Label and Tooltip Management
|
|
@@ -153,9 +220,9 @@ node.addTooltip(
|
|
|
153
220
|
|
|
154
221
|
### DataVerse API
|
|
155
222
|
|
|
156
|
-
|
|
223
|
+
Perform secure API calls to DataVerse from your PowerPages site. This method implements the shell deferred token to send requests with `__RequestVerificationToken`
|
|
157
224
|
|
|
158
|
-
#### Create
|
|
225
|
+
#### Create Records
|
|
159
226
|
|
|
160
227
|
```typescript
|
|
161
228
|
await API.createRecord("accounts", {
|
|
@@ -215,18 +282,10 @@ node.configureConditionalRendering(
|
|
|
215
282
|
|
|
216
283
|
3. Use TypeScript for better type safety and IntelliSense support.
|
|
217
284
|
|
|
218
|
-
4.
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
node.onceLoaded((instance) => {
|
|
222
|
-
// Safe to manipulate the element here
|
|
223
|
-
});
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
5. Use proper error handling with API operations:
|
|
285
|
+
4. Use proper error handling with API operations:
|
|
227
286
|
|
|
228
287
|
```typescript
|
|
229
|
-
await API.createRecord(/*...*/)
|
|
288
|
+
/* optionally await */ API.createRecord(/*...*/)
|
|
230
289
|
.then((recordId) => {})
|
|
231
290
|
.catch((error) => {
|
|
232
291
|
// handle your errors appropriately
|
|
@@ -244,3 +303,7 @@ Contributions are welcome, feel free to create a pull request with enhancements.
|
|
|
244
303
|
## License
|
|
245
304
|
|
|
246
305
|
This project is licensed under the AGPL-3.0 License - see the [LICENSE](LICENSE) file for details.
|
|
306
|
+
|
|
307
|
+
## Funding
|
|
308
|
+
|
|
309
|
+
If you like this project, found it useful, or would like to help support the long-term support of this package, please feel free to contribute via GitHub Sponsors: [Keaton-Brewster](https://github.com/sponsors/Keaton-Brewster)
|
|
@@ -6,14 +6,12 @@ export default class DOMNodeReference {
|
|
|
6
6
|
/**
|
|
7
7
|
* The value of the element that this node represents
|
|
8
8
|
* stays in syncs with the live DOM elements?.,m via event handler
|
|
9
|
-
* @type {any}
|
|
10
9
|
*/
|
|
11
10
|
value: any;
|
|
12
11
|
/**
|
|
13
12
|
* The element targeted when instantiating DOMNodeReference.
|
|
14
13
|
* Made available in order to perform normal DOM traversal,
|
|
15
14
|
* or access properties not available through this class.
|
|
16
|
-
* @property {HTMLElement | null}
|
|
17
15
|
*/
|
|
18
16
|
element: Element;
|
|
19
17
|
private visibilityController;
|
|
@@ -22,19 +20,17 @@ export default class DOMNodeReference {
|
|
|
22
20
|
* Represents the 'yes' option of a boolean radio field.
|
|
23
21
|
* This property is only available when the parent node
|
|
24
22
|
* is a main field for a boolean radio input.
|
|
25
|
-
* @property {DOMNodeReferenceProxy | null}
|
|
26
23
|
*/
|
|
27
24
|
yesRadio?: DOMNodeReference | null;
|
|
28
25
|
/**
|
|
29
26
|
* Represents the 'no' option of a boolean radio field.
|
|
30
27
|
* This property is only available when the parent node
|
|
31
28
|
* is a main field for a boolean radio input.
|
|
32
|
-
* @property {DOMNodeReferenceProxy | null}
|
|
33
29
|
*/
|
|
34
30
|
noRadio?: DOMNodeReference | null;
|
|
35
31
|
/**
|
|
36
32
|
* Creates an instance of DOMNodeReference.
|
|
37
|
-
* @param
|
|
33
|
+
* @param target - The CSS selector to find the desired DOM element.
|
|
38
34
|
*/
|
|
39
35
|
/******/ /******/ constructor(target: HTMLElement | string);
|
|
40
36
|
[_init](): Promise<void>;
|
|
@@ -84,7 +80,7 @@ export default class DOMNodeReference {
|
|
|
84
80
|
show(): DOMNodeReference;
|
|
85
81
|
/**
|
|
86
82
|
*
|
|
87
|
-
* @param
|
|
83
|
+
* @param shouldShow - Either a function that returns true or false,
|
|
88
84
|
* or a natural boolean to determine the visibility of this
|
|
89
85
|
* @returns - Instance of this [provides option to method chain]
|
|
90
86
|
*/
|
|
@@ -109,7 +105,7 @@ export default class DOMNodeReference {
|
|
|
109
105
|
* @returns - Instance of this [provides option to method chain]
|
|
110
106
|
* @throws If clearing values fails
|
|
111
107
|
*/
|
|
112
|
-
|
|
108
|
+
clearValue(): Promise<DOMNodeReference>;
|
|
113
109
|
/**
|
|
114
110
|
* Enables the element so that users can input data
|
|
115
111
|
* @returns - Instance of this [provides option to method chain]
|
|
@@ -206,10 +202,13 @@ export default class DOMNodeReference {
|
|
|
206
202
|
*/
|
|
207
203
|
configureValidationAndRequirements(isRequired: () => boolean, isValid: () => boolean, fieldDisplayName: string, dependencies: Array<DOMNodeReference>): DOMNodeReference;
|
|
208
204
|
/**
|
|
209
|
-
* Sets up tracking for
|
|
205
|
+
* Sets up tracking for dependencies using both event listeners and mutation observers.
|
|
210
206
|
* @private
|
|
207
|
+
* @param handler - The function to execute when dependencies change
|
|
208
|
+
* @param dependencies - Array of dependent DOM nodes to track
|
|
209
|
+
* @param options - Additional configuration options
|
|
211
210
|
*/
|
|
212
|
-
private
|
|
211
|
+
private _configDependencyTracking;
|
|
213
212
|
/**
|
|
214
213
|
* Sets the required level for the field by adding or removing the "required-field" class on the label.
|
|
215
214
|
*
|
package/dist/bundle.js
CHANGED
|
@@ -237,12 +237,11 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
237
237
|
/**
|
|
238
238
|
* The value of the element that this node represents
|
|
239
239
|
* stays in syncs with the live DOM elements?.,m via event handler
|
|
240
|
-
* @type {any}
|
|
241
240
|
*/
|
|
242
241
|
value;
|
|
243
242
|
/**
|
|
244
243
|
* Creates an instance of DOMNodeReference.
|
|
245
|
-
* @param
|
|
244
|
+
* @param target - The CSS selector to find the desired DOM element.
|
|
246
245
|
*/
|
|
247
246
|
/******/
|
|
248
247
|
/******/
|
|
@@ -442,7 +441,7 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
442
441
|
}
|
|
443
442
|
/**
|
|
444
443
|
*
|
|
445
|
-
* @param
|
|
444
|
+
* @param shouldShow - Either a function that returns true or false,
|
|
446
445
|
* or a natural boolean to determine the visibility of this
|
|
447
446
|
* @returns - Instance of this [provides option to method chain]
|
|
448
447
|
*/
|
|
@@ -494,7 +493,7 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
494
493
|
* @returns - Instance of this [provides option to method chain]
|
|
495
494
|
* @throws If clearing values fails
|
|
496
495
|
*/
|
|
497
|
-
async
|
|
496
|
+
async clearValue() {
|
|
498
497
|
try {
|
|
499
498
|
const element = this.element;
|
|
500
499
|
if (element instanceof HTMLInputElement) {
|
|
@@ -535,14 +534,14 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
535
534
|
if (childInputs.length > 0) {
|
|
536
535
|
const clearPromises = childInputs.map(async (input) => {
|
|
537
536
|
const inputRef = await createDOMNodeReference(input, false);
|
|
538
|
-
return inputRef.
|
|
537
|
+
return inputRef.clearValue();
|
|
539
538
|
});
|
|
540
539
|
await Promise.all(clearPromises);
|
|
541
540
|
}
|
|
542
541
|
}
|
|
543
542
|
if (this.yesRadio instanceof _DOMNodeReference && this.noRadio instanceof _DOMNodeReference) {
|
|
544
|
-
await this.yesRadio.
|
|
545
|
-
await this.noRadio.
|
|
543
|
+
await this.yesRadio.clearValue();
|
|
544
|
+
await this.noRadio.clearValue();
|
|
546
545
|
}
|
|
547
546
|
const events = [
|
|
548
547
|
new Event("input", { bubbles: true }),
|
|
@@ -710,40 +709,16 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
710
709
|
);
|
|
711
710
|
return this;
|
|
712
711
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
712
|
+
this._configDependencyTracking(
|
|
713
|
+
() => this.toggleVisibility(condition()),
|
|
714
|
+
dependencies,
|
|
715
|
+
{
|
|
716
|
+
clearValuesOnHide,
|
|
717
|
+
observeVisibility: true,
|
|
718
|
+
trackInputEvents: false,
|
|
719
|
+
trackRadioButtons: false
|
|
718
720
|
}
|
|
719
|
-
|
|
720
|
-
try {
|
|
721
|
-
this.toggleVisibility(condition());
|
|
722
|
-
if (condition() === false && clearValuesOnHide) {
|
|
723
|
-
this.clearValues();
|
|
724
|
-
}
|
|
725
|
-
} catch (error) {
|
|
726
|
-
console.error("Error in change handler:", error);
|
|
727
|
-
}
|
|
728
|
-
};
|
|
729
|
-
node.on("change", handleChange);
|
|
730
|
-
const observer = new MutationObserver(() => {
|
|
731
|
-
try {
|
|
732
|
-
const display = window.getComputedStyle(
|
|
733
|
-
node.visibilityController
|
|
734
|
-
).display;
|
|
735
|
-
this.toggleVisibility(display !== "none" && condition());
|
|
736
|
-
} catch (error) {
|
|
737
|
-
0;
|
|
738
|
-
console.error("Error in mutation observer:", error);
|
|
739
|
-
observer.disconnect();
|
|
740
|
-
}
|
|
741
|
-
});
|
|
742
|
-
observer.observe(node.visibilityController, {
|
|
743
|
-
attributes: true,
|
|
744
|
-
attributeFilter: ["style"]
|
|
745
|
-
});
|
|
746
|
-
});
|
|
721
|
+
);
|
|
747
722
|
return this;
|
|
748
723
|
} catch (error) {
|
|
749
724
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -792,7 +767,10 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
792
767
|
Object.assign(newValidator, validatorConfig);
|
|
793
768
|
Page_Validators.push(newValidator);
|
|
794
769
|
this.setRequiredLevel(isRequired());
|
|
795
|
-
this.
|
|
770
|
+
this._configDependencyTracking(
|
|
771
|
+
() => this.setRequiredLevel(isRequired()),
|
|
772
|
+
dependencies
|
|
773
|
+
);
|
|
796
774
|
} catch (error) {
|
|
797
775
|
throw new ValidationConfigError(
|
|
798
776
|
this,
|
|
@@ -802,35 +780,64 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
802
780
|
return this;
|
|
803
781
|
}
|
|
804
782
|
/**
|
|
805
|
-
* Sets up tracking for
|
|
783
|
+
* Sets up tracking for dependencies using both event listeners and mutation observers.
|
|
806
784
|
* @private
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
785
|
+
* @param handler - The function to execute when dependencies change
|
|
786
|
+
* @param dependencies - Array of dependent DOM nodes to track
|
|
787
|
+
* @param options - Additional configuration options
|
|
788
|
+
*/
|
|
789
|
+
_configDependencyTracking(handler, dependencies, options = {
|
|
790
|
+
clearValuesOnHide: false,
|
|
791
|
+
observeVisibility: true,
|
|
792
|
+
trackInputEvents: true,
|
|
793
|
+
trackRadioButtons: true
|
|
794
|
+
}) {
|
|
795
|
+
const {
|
|
796
|
+
clearValuesOnHide = false,
|
|
797
|
+
observeVisibility = true,
|
|
798
|
+
trackInputEvents = true,
|
|
799
|
+
trackRadioButtons = true
|
|
800
|
+
} = options;
|
|
801
|
+
if (!dependencies?.length) {
|
|
810
802
|
console.warn(
|
|
811
|
-
`powerpagestoolkit: No dependencies specified for ${this.element.id}. Include all referenced nodes in the dependency array for proper
|
|
803
|
+
`powerpagestoolkit: No dependencies specified for ${this.element.id}. Include all referenced nodes in the dependency array for proper tracking.`
|
|
812
804
|
);
|
|
813
805
|
return;
|
|
814
806
|
}
|
|
815
807
|
dependencies.forEach((dep) => {
|
|
816
|
-
dep
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
808
|
+
if (!dep || !(dep instanceof _DOMNodeReference)) {
|
|
809
|
+
throw new TypeError(
|
|
810
|
+
"Each dependency must be a valid DOMNodeReference instance"
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
const handleChange = () => {
|
|
814
|
+
handler();
|
|
815
|
+
if (clearValuesOnHide && window.getComputedStyle(this.visibilityController).display === "none") {
|
|
816
|
+
this.clearValue();
|
|
824
817
|
}
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
818
|
+
};
|
|
819
|
+
dep.on("change", handleChange);
|
|
820
|
+
if (trackInputEvents) {
|
|
821
|
+
dep.on("input", handleChange);
|
|
822
|
+
}
|
|
823
|
+
if (observeVisibility) {
|
|
824
|
+
const observer = new MutationObserver(() => {
|
|
825
|
+
const display = window.getComputedStyle(
|
|
826
|
+
dep.visibilityController
|
|
827
|
+
).display;
|
|
828
|
+
if (display !== "none") {
|
|
829
|
+
handler();
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
observer.observe(dep.visibilityController, {
|
|
833
|
+
attributes: true,
|
|
834
|
+
attributeFilter: ["style"],
|
|
835
|
+
subtree: false
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
if (trackRadioButtons && (dep.yesRadio || dep.noRadio)) {
|
|
832
839
|
[dep.yesRadio, dep.noRadio].forEach((radio) => {
|
|
833
|
-
radio?.on("change",
|
|
840
|
+
radio?.on("change", handleChange);
|
|
834
841
|
});
|
|
835
842
|
}
|
|
836
843
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "powerpagestoolkit",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.4111",
|
|
4
4
|
"description": "Reference, manipulate, and engage with Power Pages sites through the nodes in the DOM; use a variety of custom methods that allow customizing your power pages site quicker and easier. ",
|
|
5
5
|
"main": "./dist/bundle.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|