resonantjs 1.0.0 → 1.0.1

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/Demo.gif ADDED
Binary file
package/README.md CHANGED
@@ -7,9 +7,28 @@ Resonant.js is an open-source lightweight JavaScript framework that enables reac
7
7
  - **Reactive Data Binding**: Automatically synchronize your data with the UI.
8
8
  - **Dynamic List Rendering**: Easily render lists that react to data changes.
9
9
  - **Bidirectional Input Binding**: Bind HTML input fields directly to your data model.
10
+ - **Efficient Conditional Updates**: Only evaluate conditional expressions tied to specific variable changes.
10
11
  - **Lightweight and Easy to Integrate**: Minimal setup required to get started.
11
12
  - **Compatible with Modern Browsers**: Works seamlessly across all modern web browsers.
12
13
 
14
+ ## Installation
15
+ ## NPM
16
+ To install via NPM, use the following command:
17
+
18
+ ```bash
19
+ npm i resonantjs
20
+ ```
21
+
22
+ ## CDN
23
+ To use via CDN, include the following URLs in your HTML file:
24
+
25
+ ```html
26
+ <script src="https://unpkg.com/resonantjs@latest/resonant.js"></script>
27
+ ```
28
+
29
+ ## Demo
30
+ ![](https://github.com/amurgola/ResonantJs/blob/main/Demo.gif)
31
+
13
32
  ## Usage
14
33
  Include resonant.js in your HTML file, and use the following example to understand how to integrate it into your web application.
15
34
 
@@ -18,79 +37,81 @@ Include resonant.js in your HTML file, and use the following example to understa
18
37
  <html lang="en">
19
38
  <head>
20
39
  <title>Resonant.js Quick Demo</title>
21
- <script src="./resonant.js"></script>
40
+ <script src="https://unpkg.com/resonantjs@latest/resonant.js"></script>
22
41
  </head>
23
42
  <body>
24
- <h1>Resonant.js Quick Demo</h1>
25
-
26
- <!-- Display and update a single item -->
27
- <div>
28
- <h2>Counter</h2>
29
- <p>Current count: <span res="counter"></span></p>
30
- <button onclick="incrementCounter()">Increment Counter</button>
43
+ <h1>Resonant.js Quick Demo</h1>
44
+
45
+ <!-- Display and update a single item -->
46
+ <div>
47
+ <h2>Counter</h2>
48
+ <p>
49
+ Current count: <span res="counter"></span>
50
+ </p>
51
+ <div res-conditional="counter >= 5">
52
+ Only shows when counter is greater than or equal to 5
31
53
  </div>
32
-
33
- <!-- Demonstrate object property binding -->
34
- <div>
35
- <h2>Person Information</h2>
36
- <div res="person">
37
- <span res-prop="firstname"></span>
38
- <span res-prop="lastname"></span>
39
- <br/><br/>
40
- First Name: <input type="text" res-prop="firstname">
41
- Last Name: <input type="text" res-prop="lastname">
42
- </div>
43
- </div>
44
-
45
- <!-- Demonstrate dynamic list rendering -->
46
- <div>
47
- <h2>Team Members</h2>
48
- <ul res="team">
49
- <li>
50
- <span res-prop="name"></span> - <span res-prop="role"></span>
51
- </li>
52
- </ul>
53
- <button onclick="addTeamMember()">Add Team Member</button>
54
+ <button onclick="counter++">Increment Counter</button>
55
+ </div>
56
+
57
+ <!-- Demonstrate object property binding -->
58
+ <div>
59
+ <h2>Person Information</h2>
60
+ <div res="person">
61
+ <span res-prop="firstname"></span>
62
+ <span res-prop="lastname"></span>
63
+ <br/>
64
+ <div res-conditional="person.firstname == 'Andrew' && person.lastname == 'Murgola'">
65
+ Only shows when firstname is Andrew and lastname is Murgola
66
+ </div>
67
+ <br/>
68
+
69
+ First Name: <input type="text" res-prop="firstname" />
70
+ Last Name: <input type="text" res-prop="lastname" />
54
71
  </div>
55
-
56
- <script>
57
- const resonantJs = new Resonant();
58
-
59
- // Initialize a counter
60
- resonantJs.add("counter", 0);
61
-
62
- // Initialize a single person object
63
- resonantJs.add("person", {
64
- firstname: "Andy",
65
- lastname: "Murgola"
66
- });
67
-
68
- // Example of a callback
69
- resonantJs.addCallback("person", exampleCallbackOutput);
70
-
71
- // Initialize a list of people with dynamic properties
72
- resonantJs.add("team", [
73
- { name: "Alice", role: "Developer" },
74
- { name: "Bob", role: "Designer" }
75
- ]);
76
-
77
- function incrementCounter() {
78
- counter++;
79
- }
80
-
81
- function addTeamMember() {
82
- const newMember = { name: "Charlie", role: "Product Manager" };
83
- team.push(newMember);
84
- }
85
-
86
- function exampleCallbackOutput(result) {
87
- console.log(result.firstname + " " + result.lastname);
88
- }
89
-
90
- </script>
72
+ </div>
73
+
74
+ <!-- Demonstrate dynamic list rendering -->
75
+ <div>
76
+ <h2>Team Members</h2>
77
+ <ul res="team">
78
+ <li>
79
+ <span res-prop="name"></span> - <span res-prop="role"></span>
80
+ </li>
81
+ </ul>
82
+ <button onclick="addTeamMember()">Add Team Member</button>
83
+ </div>
84
+
85
+ <script>
86
+ const resonantJs = new Resonant();
87
+
88
+ // Initialize a counter
89
+ resonantJs.add("counter", 0);
90
+
91
+ // Initialize a single object
92
+ resonantJs.add("person", {
93
+ firstname: "Andrew",
94
+ lastname: "Murgola"
95
+ });
96
+
97
+ // Initialize an array of objects
98
+ resonantJs.add("team", [
99
+ { name: "Alice", role: "Developer" },
100
+ { name: "Bob", role: "Designer" }
101
+ ]);
102
+
103
+ // Example of a callback
104
+ resonantJs.addCallback("person", (result) => {
105
+ console.log(result.firstname + " " + result.lastname);
106
+ });
107
+
108
+ function addTeamMember() {
109
+ const newMember = { name: "Charlie", role: "Product Manager" };
110
+ team.push(newMember);
111
+ }
112
+ </script>
91
113
  </body>
92
114
  </html>
93
-
94
115
  ```
95
116
  ## Features Overview
96
117
 
@@ -98,7 +119,7 @@ Include resonant.js in your HTML file, and use the following example to understa
98
119
  - **`res` and `res-prop` Attributes**: Bind HTML elements to your data model seamlessly.
99
120
  - `res` is used to identify an overarching data model.
100
121
  - `res-prop` links individual properties within that model to corresponding UI elements.
101
-
122
+ - **`res-conditional` Attribute**: Conditionally display elements based on the data model's properties.
102
123
  - **Automatic UI Updates**: Changes to your JavaScript objects instantly reflect in the associated UI components, reducing manual DOM manipulation.
103
124
 
104
125
  ### Advanced Features
package/example.html CHANGED
@@ -13,7 +13,10 @@
13
13
  <p>
14
14
  Current count: <span res="counter"></span>
15
15
  </p>
16
- <button onclick="incrementCounter()">Increment Counter</button>
16
+ <div res-conditional="counter >= 5">
17
+ Only shows when counter is greater than or equal to 5
18
+ </div>
19
+ <button onclick="counter++">Increment Counter</button>
17
20
  </div>
18
21
 
19
22
  <!-- Demonstrate object property binding -->
@@ -23,6 +26,9 @@
23
26
  <span res-prop="firstname"></span>
24
27
  <span res-prop="lastname"></span>
25
28
  <br/>
29
+ <div res-conditional="person.firstname == 'Andrew' && person.lastname == 'Murgola'">
30
+ Only shows when firstname is Andrew and lastname is Murgola
31
+ </div>
26
32
  <br/>
27
33
 
28
34
  First Name: <input type="text" res-prop="firstname" />
@@ -47,32 +53,22 @@
47
53
  // Initialize a counter
48
54
  resonantJs.add("counter", 0);
49
55
 
50
- function exampleCallbackOutput(result) {
51
- console.log(result.firstname + " " + result.lastname);
52
- }
53
-
54
- // Initialize a single person object
56
+ // Initialize a single object
55
57
  resonantJs.add("person", {
56
- firstname: "Andy",
58
+ firstname: "Andrew",
57
59
  lastname: "Murgola"
58
60
  });
59
61
 
60
- // Initialize a list of people with dynamic properties
62
+ // Initialize an array of objects
61
63
  resonantJs.add("team", [
62
64
  { name: "Alice", role: "Developer" },
63
65
  { name: "Bob", role: "Designer" }
64
66
  ]);
65
67
 
66
68
  // Example of a callback
67
- resonantJs.addCallback("person", exampleCallbackOutput);
68
-
69
- function incrementCounter() {
70
- counter++;
71
- }
72
-
73
- function updatePersonInfo(prop, value) {
74
- person[prop] = value;
75
- }
69
+ resonantJs.addCallback("person", (result) => {
70
+ console.log(result.firstname + " " + result.lastname);
71
+ });
76
72
 
77
73
  function addTeamMember() {
78
74
  const newMember = { name: "Charlie", role: "Product Manager" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "resonantjs",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A lightweight JavaScript framework that enables reactive data-binding for building dynamic and responsive web applications. It simplifies creating interactive UIs by automatically updating the DOM when your data changes.",
5
5
  "main": "resonant.js",
6
6
  "repository": {
package/resonant.js CHANGED
@@ -33,6 +33,7 @@ class Resonant {
33
33
  set: (target, property, value) => {
34
34
  target[property] = value;
35
35
  this.updateElement(parentName);
36
+ this.updateConditionalsFor(parentName);
36
37
  return true;
37
38
  }
38
39
  });
@@ -41,7 +42,7 @@ class Resonant {
41
42
  _createArray(variableName, arr) {
42
43
  return new Proxy(arr, {
43
44
  get: (target, index) => {
44
- if (typeof target[index] === 'object') {
45
+ if (typeof target[index] === 'object' && !target[index][Symbol('isProxy')]) {
45
46
  target[index] = this._createObject(`${variableName}[${index}]`, target[index]);
46
47
  }
47
48
  return target[index];
@@ -49,6 +50,7 @@ class Resonant {
49
50
  set: (target, index, value) => {
50
51
  target[index] = value;
51
52
  this.updateElement(variableName);
53
+ this.updateConditionalsFor(variableName);
52
54
  return true;
53
55
  }
54
56
  });
@@ -60,6 +62,7 @@ class Resonant {
60
62
  set: (newValue) => {
61
63
  this._assignValueToData(variableName, newValue);
62
64
  this.updateElement(variableName);
65
+ this.updateConditionalsFor(variableName);
63
66
  }
64
67
  });
65
68
  }
@@ -91,11 +94,29 @@ class Resonant {
91
94
  }
92
95
  });
93
96
 
97
+ // Call the variable-specific condition update
98
+ this.updateConditionalsFor(variableName);
99
+
94
100
  if (this.callbacks[variableName]) {
95
101
  this.callbacks[variableName](value);
96
102
  }
97
103
  }
98
104
 
105
+ updateConditionalsFor(variableName) {
106
+ const conditionalElements = document.querySelectorAll(`[res-conditional*="${variableName}"]`);
107
+ conditionalElements.forEach(conditionalElement => {
108
+ const condition = conditionalElement.getAttribute('res-conditional');
109
+ try {
110
+ if (eval(condition)) {
111
+ conditionalElement.style.display = '';
112
+ } else {
113
+ conditionalElement.style.display = 'none';
114
+ }
115
+ } catch (e) {
116
+ console.error(`Error evaluating condition for ${variableName}: ${condition}`, e);
117
+ }
118
+ });
119
+ }
99
120
 
100
121
  _renderArray(variableName, el) {
101
122
  let template = el.cloneNode(true);