targetj 1.0.213 → 1.0.215

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 CHANGED
@@ -1,71 +1,72 @@
1
- # TargetJS: JavaScript UI Framework for Simplified Development and Enhanced User Experience
1
+ # TargetJS: UI Development as a Sequence
2
2
 
3
3
  **[targetjs.io](https://targetjs.io)**
4
4
  [![MIT LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/livetrails/targetjs/blob/main/LICENSE)
5
5
  [![Stars](https://img.shields.io/github/stars/livetrails/targetjs.svg)](https://github.com/livetrails/targetjs/stargazers)
6
6
  [![npm version](https://img.shields.io/npm/v/targetj.svg)](https://www.npmjs.com/package/targetj)
7
7
 
8
- TargetJS is a modern JavaScript UI framework that simplifies front-end development with a code-ordered reactivity model and an ultra-compact syntax. It provides a unified solution for key aspects like UI rendering, animations, APIs, state management, and event handling.
9
- It can be used as a full-featured framework or as a lightweight library alongside other frameworks. It is also a highly performant web framework, as shown in the [framework benchmark](https://krausest.github.io/js-framework-benchmark/current.html).
10
-
11
- ## The Philosophy Behind TargetJS
8
+ TargetJS is a high-performance JavaScript UI framework with ultra-compact syntax. It replaces the "State → Render" model with a Code-Ordered Reactivity. It unifies UI, animations, APIs, event handling, and state into self-contained "Targets" that stack together like intelligent Lego pieces.
12
9
 
13
- Frameworks often promise simplicity, but frequently require extensive boilerplate and libraries as they inherit the same software approach rooted in early programming models and try to force it to fit UI development by adding more complexity. User interfaces are dynamic and asynchronous and require a different paradigm.
14
-
15
- TargetJS adopts a new approach. First, it unifies class methods and fields into a single construct called targets. Each target is given state, lifecycles, timing, iterations, and the autonomy to execute mimicking the behavior of living cells. Targets are essentially self-contained, intelligent blocks of code.
16
-
17
- The second challenge is making these targets fit and work together especially since UI operations are highly asynchronous. Instead of relying on traditional method calls and callbacks that don't address asynchronous nature well, TargetJS allows targets to react to the execution or completion of preceding targets. A subsequent target can run independently, execute whenever the previous one does, or wait until the previous target completes. Targets stack together like Lego pieces. It can address complex asynchronous workflow while remaining easy to understand.
10
+ It can be used as a full-featured framework or as a lightweight library alongside other frameworks. It is also a highly performant web framework, as shown in the [framework benchmark](https://krausest.github.io/js-framework-benchmark/current.html).
18
11
 
19
- For example, setting a value can implicitly define an animation, where the current value iteratively progresses until it reaches the new value. When the animation completes, the next target might initiate a fetch API call. Once the data is received, it can trigger another target that creates 10 new elements, each with its own animation and API call. A subsequent target can then be set to run only after all 10 elements have completed their tasks. Targets simply react and chain together based on how the code is written.
20
12
 
21
- Furthermore, TargetJS adopts a Rebol-like style to make the code more compact.
13
+ ## The Philosophy Behind TargetJS
22
14
 
23
- ## Key Innovations and Concepts
15
+ Traditional frameworks model the UI as a function of state: change state, re-render the UI. When state changes from A to B, the UI immediately jumps to **B**. The framework doesn’t naturally represent the *journey* from A to B. But modern, rich user experiences are built on sequences that unfold over time. For example:
24
16
 
25
- 1. Reactive targets: A new construct called “targets” unifies class methods and fields. Targets are self-contained units of code with their own state, lifecycles, and timing. They are designed to execute themselves or react dynamically to the run or completion of preceding targets. This enables the declarative programming of complex asynchronous flows without explicit callbacks.
26
- 2. All-in-One solution: Offers a unified approach to UI rendering, API integration, state management, event handling, and animation.
27
- 3. Code-ordered execution, Rebol-like style: less code and more readable code.
17
+ > Click Animate button Chain secondary animation Fetch data Render list Animate items Pause Animate an important item
28
18
 
29
- ---
19
+ TargetJS is built for this reality. Instead of managing complex flags, your code structure mirrors these sequences directly.
30
20
 
31
- ## Examples: Like Button Animated Like with 4 Async Ops (in 7 Steps)
21
+ It achieves this through Targets. A Target is a self-contained unit that merges data (fields) and logic (methods) into a single reactive block. Each Target has its own internal state, timing, and lifecycle, acting like a living cell within your app. By simply ordering them in your code, you create complex asynchronous workflows without async/await or .then() chains.
32
22
 
33
- The example demonstrates how to run four asynchronous operations in a strict sequential sequence, where each step waits for the previous ones to complete. Any restart or delay in an operation delays the ones that follow. This is to showcase managing async operations rather than focusing on the user experience. We will show the example in 7 steps.
23
+ By building animation directly into the logic of the framework and adopting a compact style, TargetJS makes the journey from A to B explicit and with significantly less code than traditional frameworks.
34
24
 
35
- ### 1) Like button (view only)
25
+ ## Quick Start (30 Seconds)
36
26
 
37
- **What this shows:** One object defines a UI element without separate HTML/CSS. Static targets map directly to DOM styles/attributes. You can still use CSS if wanted.
27
+ **1. Install**
38
28
 
39
- Use .mount("#id") to choose where it renders. If you omit .mount(), TargetJS mounts to `body`.
29
+ ```bash
30
+ npm install targetj
31
+ ```
40
32
 
41
- <img src="https://targetjs.io/img/likeButton.png" width="130" />
33
+ **2. The "Hello World" Sequence**
42
34
 
43
- ```html
44
- <div id="likeButton"></div>
45
- ```
35
+ This creates a blue box that grows, then turns red, and then logs "Hello World" in order.
46
36
 
47
37
  ```javascript
48
38
  import { App } from "targetj";
49
39
 
50
40
  App({
51
- width: 220,
52
- height: 60,
53
- lineHeight: 60,
54
- textAlign: "center",
55
- borderRadius: 10,
56
- backgroundColor: "#f5f5f5",
57
- html: "♡ Like"
58
- }).mount("#likeButton");
41
+ backgroundColor: 'blue',
42
+ height: 100,
43
+ width: { value: [100, 200], steps: 100 }, // 1. Animate width in 100 steps using the default 8 ms interval per step.
44
+ backgroundColor$$: { value: 'red', steps: 100 }, // 2. Wait ($$) then turn red in 100 steps
45
+ done$$() { console.log("Hello World!"); } // 3. Wait ($$) then log
46
+ }).mount("#app");
59
47
  ```
60
48
 
61
- ---
49
+ ## Understanding TargetJS Syntax
50
+
51
+ These symbols tell the framework **when** a target should run.
52
+
53
+ | Symbol | Name | Behavior |
54
+ | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------|
55
+ | `name` | Standard | Runs immediately in the order it appears. |
56
+ | `name$` | Reactive | Runs every time the previous sibling target executes. |
57
+ | `name$$` | Deferred | Executes only after the entire preceding target chain including children, animations, and API calls has fully completed. |
58
+ | `_name` | Inactive | Does not run automatically. Trigger it manually via `.activateTarget()`. |
59
+
62
60
 
61
+ ## Examples: Like Button → Animated Like (in 3 Steps)
63
62
 
64
- ### 2) Animation
63
+ Let’s see how TargetJS handles a complex interaction that would usually require 50+ lines of React/CSS. The example demonstrates how to run four asynchronous operations in a strict sequential sequence, where each step waits for the previous ones to complete.
65
64
 
66
- **What this shows:** A mount-time animation that scales and changes the `backgroundColor` over 12 steps, with 12ms pauses between steps. Targets without (`$`, `$$`, `_`) execute immediately in the order they are defined.
65
+ ### 1) Like button
67
66
 
68
- <img src="https://targetjs.io/img/likeButton6.gif" width="130" />
67
+ One object defines a UI element without separate HTML/CSS. Static targets map directly to DOM styles/attributes. You can still use CSS if wanted.
68
+
69
+ <img src="https://targetjs.io/img/likeButton6.gif" width="130" />
69
70
 
70
71
  ```html
71
72
  <div id="likeButton"></div>
@@ -81,16 +82,17 @@ App({
81
82
  textAlign: "center",
82
83
  borderRadius: 10,
83
84
  html: "♡ Like",
85
+ // Runs immediately on mount
84
86
  scale: { value: [1.2, 1], steps: 12, interval: 12 },
85
87
  backgroundColor: { value: ["#ffe8ec", "#f5f5f5"], steps: 12, interval: 12 }
86
88
  }).mount("#likeButton");
87
89
  ```
88
90
 
89
- ### 3) Click animation (imperative `setTarget`)
91
+ ### 2) Adding the Interaction
90
92
 
91
- **What this shows:** Clicking plays the animations from the previous step using imperative `setTarget`.
93
+ We move the animation into an `onClick` and add a deferred heart animation.
92
94
 
93
- <img src="https://targetjs.io/img/likeButton4.gif" width="130" />
95
+ <img src="https://targetjs.io/img/likeButton-step2-2.gif" width="130" />
94
96
 
95
97
  ```html
96
98
  <div id="likeButton"></div>
@@ -103,132 +105,31 @@ App({
103
105
  borderRadius: 10, backgroundColor: "#f5f5f5",
104
106
  cursor: "pointer", userSelect: "none",
105
107
  html: "♡ Like",
106
-
107
- onClick() {
108
- this.setTarget('scale', { value: [1.2, 1], steps: 8, interval: 12 });
109
- this.setTarget('backgroundColor', { value: [ '#ffe8ec', '#f5f5f5' ], steps: 12, interval: 12 });
110
- }
111
- }).mount("#likeButton");
112
- ```
113
-
114
- ---
115
-
116
- ### 4) Sequencing with `$$`: Adding a small heart after click animation (first async op)
117
-
118
- **What this shows:** A `$$` target (deferred) runs only after all prior targets finish (including `onClick()` and its animations). Here it adds a new heart element and runs its fly motion only once the click sequence has completed. Repeated clicks will delay adding the heart.
119
-
120
- <img src="https://targetjs.io/img/likeButton7.gif" width="130" />
121
-
122
- ```html
123
- <div id="likeButton"></div>
124
- ```
125
- ```javascript
126
- import { App } from "targetj";
127
-
128
- App({
129
- width: 220, height: 60, lineHeight: 60, textAlign: "center",
130
- borderRadius: 10, backgroundColor: "#f5f5f5", cursor: "pointer", userSelect: "none",
131
- html: "♡ Like",
132
108
  onClick() {
133
109
  this.setTarget('scale', { value: [1.2, 1], steps: 8, interval: 12 });
134
110
  this.setTarget('backgroundColor', { value: [ '#ffe8ec', '#f5f5f5' ], steps: 12, interval: 12 });
135
111
  },
136
- heart$$: {
112
+ heart$$: { // Wait for the button animation to finish, THEN add and animate the heart.
137
113
  html: "♥", color: "crimson", fontSize: 20,
138
114
  fly() {
139
115
  const cx = this.getCenterX(), cy = this.getCenterY();
140
116
  this.setTarget({
141
- opacity: { list: [0, 1, 1, 0.8, 0.1] },
142
- scale: { list: [0.8, 1.4, 1.1, 0.9, 0.8] },
143
- rotate: { list: [0, 12, -8, 6, 0] },
144
- x: { list: [cx, cx + 22, cx - 16, cx + 10, cx] },
145
- y: { list: [cy - 8, cy - 70, cy - 90, cy - 120, cy - 150] }
146
- }, 20);
117
+ opacity: { value: [0, 1, 1, 0.8, 0.1], steps: 20 },
118
+ scale: { value: [0.8, 1.4, 1.1, 0.9, 0.8], steps: 20 },
119
+ rotate: { value: [0, 12, -8, 6, 0], steps: 20 },
120
+ x: { value: [cx, cx + 22, cx - 16, cx + 10, cx], steps: 30 },
121
+ y: { value: [cy - 8, cy - 70, cy - 90, cy - 120, cy - 150], steps: 30 }
122
+ });
147
123
  }
148
- }
149
- }).mount("#likeButton");
150
- ```
151
-
152
- ---
153
-
154
- ### 5) Another `$$`: Adding a big heart (second async op)
155
-
156
- **What this shows:** Deferred addition of a new element using $$. `bigHeart$$` waits for `heart$$` and the click sequence to complete their animation, then adds a larger heart and runs its own happy animation.
157
-
158
- <img src="https://targetjs.io/img/likeButton8.gif" width="130" />
159
-
160
- ```html
161
- <div id="likeButton"></div>
162
- ```
163
-
164
- ```javascript
165
- import { App } from "targetj";
166
-
167
- App({
168
- width: 220, height: 60, lineHeight: 60, textAlign: "center",
169
- borderRadius: 10, backgroundColor: "#f5f5f5", cursor: "pointer", userSelect: "none",
170
- html: "♡ Like",
171
-
172
- onClick() {
173
- this.setTarget('scale', { value: [1.2, 1], steps: 8, interval: 12 });
174
- this.setTarget('backgroundColor', { value: [ '#ffe8ec', '#f5f5f5' ], steps: 12, interval: 12 });
175
- },
176
-
177
- heart$$: {
178
- html: "♥", color: "crimson", fontSize: 20,
179
- fly() {
180
- const cx = this.getCenterX(), cy = this.getCenterY();
181
- this.setTarget({
182
- opacity: { list: [0, 1, 1, 0.8, 0.1] },
183
- scale: { list: [0.8, 1.4, 1.1, 0.9, 0.8] },
184
- rotate: { list: [0, 12, -8, 6, 0] },
185
- x: { list: [cx, cx + 22, cx - 16, cx + 10, cx] },
186
- y: { list: [cy - 8, cy - 70, cy - 90, cy - 120, cy - 150] }
187
- }, 20);
188
- }
189
- },
190
- bigHeart$$: {
191
- html: "♥", color: "blue", fontSize: 100,
192
- happyFly() {
193
- const cx = this.getCenterX(), cy = this.getCenterY();
194
- this.setTarget({
195
- opacity: { list: [0, 1, 1, 0.85, 0.6, 0.1] },
196
- scale: { list: [0.4, 1.9, 1.2, 1.6, 1.0, 0.95] },
197
- rotate: { list: [0, 4, -3, 4, -2, 0] },
198
- x: { list: [cx, cx + 14, cx + 10, cx - 6, cx - 14, cx] },
199
- y: { list: [cy, cy - 30, cy - 55, cy - 80, cy - 100, cy - 130] }
200
- }, 30);
201
- }
202
- }
203
- }).mount("#likeButton");
204
- ```
205
-
206
- ---
207
-
208
- ### 6) `fetch$$` (third async op)
209
-
210
- **What this shows:** Networking is just another target. The POST happens **only after** all prior visual steps complete, since the target is postfixed with `$$`. Similarly, repeated clicks delay `fetch$$`.
211
-
212
- ```html
213
- <div id="likeButton"></div>
214
- ```
215
- ```javascript
216
- import { App } from "targetj";
217
-
218
- App({
219
- // …same as step 5…
220
-
221
- fetch$$: { method: "POST", id: 123, url: "/api/like" }
124
+ }
222
125
  }).mount("#likeButton");
223
126
  ```
224
127
 
225
- ---
128
+ ### 3) The Full Async Workflow
226
129
 
227
- ### 7) Final version
130
+ We handle UI, two animations, a POST request, and a cleanup.
228
131
 
229
- **What this shows:** A Like button that consolidates the previous steps into a single component. After the POST completes, a cleanup `removeHearts$$` target (fourth async op) runs to remove the two heart elements. The button also includes basic accessibility (role, tabIndex, and Enter to activate). Demo: [Like button](https://targetj.io/examples/quick.html).
230
-
231
- <img src="https://targetjs.io/img/likeButton9.gif" width="130" />
132
+ <img src="https://targetjs.io/img/likeButton-step3-4.gif" width="130" />
232
133
 
233
134
  ```html
234
135
  <div id="likeButton"></div>
@@ -247,58 +148,40 @@ App({
247
148
  this.setTarget('scale', { value: [1.2, 1], steps: 8, interval: 12 });
248
149
  this.setTarget('backgroundColor', { value: [ '#ffe8ec', '#f5f5f5' ], steps: 12, interval: 12 });
249
150
  },
250
-
251
151
  heart$$: {
252
152
  html: "♥", color: "crimson", fontSize: 20,
253
153
  fly() {
254
154
  const cx = this.getCenterX(), cy = this.getCenterY();
255
155
  this.setTarget({
256
- opacity: { list: [0, 1, 1, 0.8, 0.1] },
257
- scale: { list: [0.8, 1.4, 1.1, 0.9, 0.8] },
258
- rotate: { list: [0, 12, -8, 6, 0] },
259
- x: { list: [cx, cx + 22, cx - 16, cx + 10, cx] },
260
- y: { list: [cy - 8, cy - 70, cy - 90, cy - 120, cy - 150] }
261
- }, 20);
156
+ opacity: { value: [0, 1, 1, 0.8, 0.1], steps: 20 },
157
+ scale: { value: [0.8, 1.4, 1.1, 0.9, 0.8], steps: 20 },
158
+ rotate: { value: [0, 12, -8, 6, 0], steps: 20 },
159
+ x: { value: [cx, cx + 22, cx - 16, cx + 10, cx], steps: 30 },
160
+ y: { value: [cy - 8, cy - 70, cy - 90, cy - 120, cy - 150], steps: 30 }
161
+ });
262
162
  }
263
163
  },
264
-
265
- bigHeart$$: {
266
- html: "♥", color: "blue", fontSize: 100,
267
- happyFly() {
268
- const cx = this.getCenterX(), cy = this.getCenterY();
269
- this.setTarget({
270
- opacity: { list: [0, 1, 1, 0.85, 0.6, 0.1] },
271
- scale: { list: [0.4, 1.9, 1.2, 1.6, 1.0, 0.95] },
272
- rotate: { list: [0, 4, -3, 4, -2, 0] },
273
- x: { list: [cx, cx + 14, cx + 10, cx - 6, cx - 14, cx] },
274
- y: { list: [cy, cy - 30, cy - 55, cy - 80, cy - 100, cy - 130] }
275
- }, 30);
276
- }
277
- },
278
- fetch$$: { method: "POST", id: 123, url: "/api/like" },
279
- removeHearts$$() { this.removeChildren(); },
164
+ fetch$$: { method: "POST", id: 123, url: "/api/like" }, // Wait for hearts to finish, THEN fetch
165
+ removeHearts$$() { this.removeChildren(); }, // Wait for fetch to finish, THEN cleanup
280
166
  onKey(e) { if (e.key === "Enter") this.activateTarget("onClick"); }
281
167
  }
282
168
  }).mount("#likeButton");
283
169
  ```
284
- ---
285
170
 
286
- ### Final takeaway
171
+ ### Summary
172
+
173
+ Instead of wiring callbacks and effects, you write a sequence of targets. All targets execute automatically in the order they are written. `$$` defers execution until all prior sibling steps finish. Animations, API calls, event handling, and child creation are all treated as the same kind of thing: targets. Complex asynchronous flows are expressed by structuring parent and child targets. In addition, targets also provide built-in capabilities such as `onComplete` callback, enabledOn, looping with delays, and more as explained below.
174
+
175
+ ---
287
176
 
288
- - Instead of wiring callbacks and effects, you write a sequence of targets. `$$` defers until all prior steps finish. Animations, API calls, and child creation are all the same kind of thing: targets.
289
- - Minimal plumbing yet full control to manage a flow of complex asynchronous operations.
290
-
291
177
  ## Table of Contents
292
178
 
293
- 1. [Targets: The Building Blocks of TargetJS](#targets-the-building-blocks-of-targetjs)
294
- 1. [Understanding TargetJS Syntax: Reactive Postfixes](#understanding-targetjs-syntax-reactive-postfixes)
295
- 1. [📦 Installation](#-installation)
296
- 1. [What Problems Does TargetJS Solve?](#what-problems-does-targetjs-solve)
179
+ 1. [📦 Alternative Installation Via CDN](#-alternative-installation-via-cdn)
180
+ 1. [🚀 Why TargetJS?](#-why-targetjs)
297
181
  1. More Examples:
298
182
  - [Loading Five Users Example](#loading-five-users-example)
299
183
  - [Infinite Loading and Scrolling Example](#infinite-loading-and-scrolling-example)
300
184
  1. [Target Methods](#target-methods)
301
- 1. [Target Variables](#target-variables)
302
185
  1. [Special Target Names](#special-target-names)
303
186
  1. [How to Debug in TargetJS](#how-to-debug-in-targetjs)
304
187
  1. [Documentation](#documentation)
@@ -306,55 +189,7 @@ App({
306
189
  1. [Contact](#contact)
307
190
  1. [💖 Support TargetJS](#-support-targetjs)
308
191
 
309
- ## Targets: The Building Blocks of TargetJS
310
-
311
- Targets provide a unified interface for both class methods and fields. Each Target comes equipped with a built-in set of capabilities:
312
-
313
- 1. State Management: Targets are inherently stateful, enabling implicit state handling across your application.
314
- 2. Iterations: They can iterate towards defined values, making them perfect for creating animations.
315
- 3. Multiple or Conditional Execution: Targets can execute repeatedly or only under specific conditions.
316
- 4. Execution timing: Targets enable fine-grained control over when they execute.
317
- 5. Code-Ordered Execution: Targets execute sequentially and predictably in the order they are written within a JavaScript object, thanks to ES2015's guaranteed property order.
318
-
319
- ## Understanding TargetJS Syntax: Reactive Postfixes
320
-
321
- All targets execute automatically in the order they are writte unless their names have a postfix or prefix. TargetJS defines reactive behavior using the $ and $$ postfixes, while the _ prefix marks a target as inactive so it runs only when explicitly activated imperatively by another target. Although this convention may seem a bit cryptic at first, it enables a compact syntax.
322
-
323
- **`$` Postfix (Immediate Reactivity):**
324
-
325
- A target name ending with a single `$` (e.g., `height$`) indicates that this target will execute every time its immediately preceding target runs or emits a new value. If the preceding target involves an asynchronous operation like an API call, the reactive target activates when the response is received. If there are multiple API calls made, `$` postfix ensures that the target reacts to the first API result when it becomes available, then the second, and so on, maintaining a strict, code-ordered sequence of operations.
326
-
327
- **`$$` Postfix (Deferred Reactivity):**
328
-
329
- A target name ending with a double `$$` (e.g., `fetch$$`) will activate only after all the preceding targets have fully and comprehensively completed all of their operations. This includes:
330
-
331
- - The successful resolution of any timed sequences, such as animations.
332
- - The completion and return of results from all associated API calls.
333
- - The finalization of all tasks, animations, and API calls initiated by any dependent child targets that were themselves triggered by a preceding target.
334
-
335
- **`_` Prefix (Inactive):**
336
-
337
- A target name starting with `_` (e.g., `_height`) indicates that the target is inactive and does not execute automatically. It runs only when explicitly activated imperatively by another target using `.activateTarget(targetName)`.
338
-
339
- ---
340
-
341
- ## **📦 Installation**
342
-
343
- **Via package manager**
344
-
345
- Install TargetJS via npm (note: there's no "s" at the end):
346
-
347
- ```bash
348
- npm install targetj
349
- ```
350
-
351
- Then import it into your JavaScript code:
352
-
353
- ```javascript
354
- import { App } from "targetj";
355
- ```
356
-
357
- **Via CDN**
192
+ ## 📦 Alternative Installation Via CDN
358
193
 
359
194
  Add the following `<script>` tag to your HTML to load TargetJS from a CDN:
360
195
 
@@ -362,7 +197,9 @@ Add the following `<script>` tag to your HTML to load TargetJS from a CDN:
362
197
  <script src="https://unpkg.com/targetj@latest/dist/targetjs.js"></script>
363
198
  ```
364
199
 
365
- This exposes `TargetJS` on `window`, so you can initialize your app with `TargetJS.App(...)`. Make sure your code runs after the TargetJS script and the DOM are ready (use defer, place your script below it, or wait for `DOMContentLoaded`).
200
+ This exposes `TargetJS` on `window`, so you can initialize your app with `TargetJS.App(...)`.
201
+
202
+ > Ensure your code runs after the DOM is ready (use `defer`, place your script at the bottom of the `<body>`, or wrap it in a `DOMContentLoaded` listener).
366
203
 
367
204
  ```html
368
205
  <div id='redbox'></div>
@@ -375,7 +212,10 @@ This exposes `TargetJS` on `window`, so you can initialize your app with `Target
375
212
  }).mount('#redbox');
376
213
  </script>
377
214
  ```
378
- Or, directly in your HTML with `tg-` attributes. Elements with tg- attributes are discovered automatically:
215
+
216
+ ### Zero-JS Declarative HTML
217
+
218
+ TargetJS can also be used as a "no-code" library. Elements with tg- attributes are discovered and activated automatically.
379
219
 
380
220
  ```html
381
221
  <div
@@ -385,21 +225,13 @@ Or, directly in your HTML with `tg-` attributes. Elements with tg- attributes ar
385
225
  </div>
386
226
  ```
387
227
 
388
- ---
389
-
390
- ## What Problems Does TargetJS Solve?
391
-
392
- TargetJS addresses several common pain points in front-end development:
228
+ ## 🚀 Why TargetJS?
393
229
 
394
- 1. **Scattered State Management:** Many frameworks require separate libraries or complex patterns for state management. In TargetJS, state management is inherently handled through its core concept of “targets”.
395
- 2. **Complexity of Asynchronous Operations:** Traditional JavaScript often involves complex handling of asynchronous operations (Promises, callbacks, `async/await`). TargetJS addresses this by providing a declarative reactive targets and synchronous execution flow.
396
- 3. **Disjointed Development Workflow:** Developers often juggle multiple tools and concepts (UI libraries, animation libraries, event handlers). TargetJS provides a unified solution.
397
- 4. **Rigid Static Layer of HTML:** Many frameworks use HTML as the primary medium for generating the user interface. TargetJS makes JavaScript the primary driver.
398
- 5. **Boilerplate and Verbosity:** TargetJS aims to reduce boilerplate code. The code is compact and follows a predictable execution flow.
399
- 6. **Difficult Animation Control:** TargetJS makes animations first-class citizens with fine-grained control.
400
- 7. **Performance Bottlenecks with Large Lists:** TargetJS optimizes rendering for large lists by using a tree structure that renders only the visible branches.
401
-
402
- ---
230
+ 1. Zero Boilerplate Async: The $$ postfix handles the "wait" for you.
231
+ 2. Unified State: State isn't "elsewhere". It's built into every Target.
232
+ 3. Animation by Default: High-performance animations are baked into the logic.
233
+ 4. Ultra-Compact: Write 70% less code than standard frameworks.
234
+ 5. Lower Cognitive Load: Code reads from top to bottom, exactly how the user experiences the interaction.
403
235
 
404
236
  ## More Examples
405
237
 
@@ -428,6 +260,8 @@ App({
428
260
  'https://targetjs.io/api/randomUser?id=user4'
429
261
  ],
430
262
  child$() {
263
+ // prevTargetValue Holds the previous target’s value. For fetch targets, this is each API result in code order,
264
+ // not the order in which responses arrive in the browser.
431
265
  const user = this.prevTargetValue;
432
266
  return {
433
267
  width: 200,
@@ -481,8 +315,6 @@ App({
481
315
 
482
316
  In this advanced example, we implement an infinite-scrolling application.
483
317
 
484
- **Explanation:**
485
-
486
318
  * `addChildren` is a special target that adds multiple items to the container’s children each time it executes. The `onVisibleChildrenChange` event detects changes in the visible children and activates `addChildren` to insert new items and fill any gaps.
487
319
 
488
320
  * `photo` and `userName` each add a `div` element inside every item, serving as placeholders for the photo and user name.
@@ -565,163 +397,52 @@ App({
565
397
  ```
566
398
  ---
567
399
 
568
- ## Target Methods
400
+ ## Technical Reference
401
+
402
+ ### Target Methods
569
403
 
570
- All methods and properties are optional, but they play integral roles in making targets useful for animation, API loading, event handling, and more:
404
+ Every target can be an object with these optional controls:
571
405
 
572
406
  1. **value**
573
- If defined, value is the primary target method that will be executed. The target value will be calculated based on the result of this method.
574
- `Value` can also be defined as a property.
407
+ The data or function that determines the target's state.
408
+
409
+ 1. **steps**
410
+ Turns a value change into an animation (e.g., steps: 20).
575
411
 
576
- 1. **Postfix `$` to the target name** (Reactive):
577
- A target name ending with $ indicates that it will be only activated when the preceding target is executed. If the preceding target involves API calls, it will be activated
578
- each time an API response is received, while ensuring the order of API calls is enforced. This means it will remain inactive until the first API result is received,
579
- then the second, and so on.
580
-
581
- 1. **Postfix `$$` to the target name** (Deferred):
582
- A target name ending with `$$` indicates that it will be activated only after all the preceding targets have completed, along with all its imperative targets,
583
- and after all API results have been received.
412
+ 1. **interval**
413
+ The delay (ms) between steps or executions.
584
414
 
585
- 1. **Prefix `_` to the target name** (Inactive):
586
- It indicates that the target is in an inactive state and must be activated by an event or other targets explicitly.
415
+ 1. **cycles**
416
+ How many times to repeat the target.
587
417
 
588
418
  1. **onComplete**
589
- It gets executed when the target and all proceeding targets fully complete their execution. It is equivalent to `$$`, but is executed from the same target.
419
+ Callback when this target (and its children) finishes.
590
420
 
591
421
  1. **enabledOn**
592
- Determines whether the target is eligible for execution. If enabledOn() returns false, the target remains active until it is enabled and gets executed.
422
+ Determines whether the target is enabled for execution.
593
423
 
594
424
  1. **loop**
595
- Controls the repetition of target execution. If loop() returns true, the target will continue to execute indefinitely. It can also be defined as a boolean instead of a method.
596
-
597
- 1. **cycles**
598
- It works similarly to `loop`, but it specifies an explicit number of repetitions. It can also be combined with `loop`, in which case, once the specified cycles complete, they will rerun as long as `loop` returns true. In other words, `loop` functions as an outer loop for `cycles`.
599
-
600
- 1. **interval**
601
- It specifies the pause between each target execution or each actual value update when steps are defined.
602
-
603
- 1. **steps**
604
- By default, the actual value is updated immediately after the target value. The steps option allows the actual value to be updated in iterations specified by the number of steps.
425
+ Managed the repetition of target execution. Similar to `cycles` but uses boolean instead.
605
426
 
606
427
  1. **easing**
607
428
  A string that defines a predefined easing function that controls how the actual value is updated in relation to the steps.
608
429
 
609
430
  1. **onValueChange**
610
- This callback is triggered whenever there is a change returned by the target method/property `value`.
611
-
612
- 1. **onStepsEnd**
613
- This method is invoked only after the final step of updating the actual value is completed, assuming the target has a defined steps value.
614
-
615
- 1. **onImperativeStep**
616
- This callback tracks the progress of imperative targets defined within a declarative target. If there are multiple imperative targets, this method is called at each step,
617
- identifiable by their target name. You can also use `on${targetName}Step` to track individual targets with their own callbacks. For example, `onWidthStep()` is called on each update of the `width` target.
618
-
619
- 1. **onImperativeEnd**
620
- Similar to `onImperativeStep`, but it is triggered when an imperative target completes. If multiple targets are expected to complete, you can use `on${targetName}End` instead. For example, `onWidthEnd` is called when the `width` target gets completed.
431
+ This callback is triggered when `value` emits a new value.
621
432
 
622
- 1. **initialValue**
623
- This is only a property. It defines the initial value of the actual value.
433
+ ### Special Target Names
624
434
 
625
- 1. **active**
626
- This is only a property. It indicates whether the target is ready for execution. When set to false, it behaves similarly to a `_` prefix. By default, all targets are active, so setting it to true is unnecessary.
627
-
628
- 1. **onSuccess**
629
- An optional callback for targets that make API calls. It will be invoked for each API response received.
435
+ TargetJS maps directly to the DOM for zero-friction styling. For example:
630
436
 
631
- 1. **onError**
632
- Similar to the `onSuccess` but it will be invoked on every error.
633
-
634
- ## Target Variables
635
- In all the target methods above, you can access the following variables:
636
-
637
- 1. **this.prevTargetValue**
638
- It holds the value of the preceding target. If the preceding target involves API calls, a single $ postfix means it will hold one API result at a time, as the target is
639
- activated with each API response. If the target is postfixed with $$, it will have the results as an array, ordered by the sequence of API calls rather than the order in
640
- which the responses are received.
641
-
642
- 2. **this.isPrevTargetUpdated()**
643
- It returns `true` if the previous target has been updated. This method is useful when a target is activated externally, such as by a user event, rather than by the preceding target.
644
-
645
- 3. **this.key**
646
- Represents the name of the current target.
647
-
648
- 4. **this.value**
649
- Represents the current value of the target.
650
-
651
-
652
- ## Special Target Names
653
-
654
- All HTML style names and attributes are treated as special target names. The most commonly used style names and attributes have already been added to the framework, with the possibility of adding more in the future.
655
-
656
- Examples:
657
- - `width`, `height`: Set the dimensions of the object.
658
- - `opacity`, `scale`, `rotate`: Adjust the opacity, scale, and rotation of the object.
659
- - `zIndex`: Sets the z-order of the object.
660
-
661
- In addition to styles and attribute names, we have the following special names:
662
-
663
- 1. **html**: Sets the content of the object, interpreted as text by default.
664
- 2. **children**: Adds new items to the parent each time it executes. Items can be either plain objects or instances of TModel for greater control.
665
- 3. **Child**: Similar to `children` but adds only one item.
666
- 4. **css**: A string that sets the CSS of the object.
667
- 5. **element**: Sets the HTML tag of the object, defaulting to `div`.
668
- 6. **shouldBeBracketed**: A boolean flag that, when set to true (the default), enables the creation of an optimization tree for a container with more items than the `bracketThreshold` (another target with a default value of 10). This optimization ensures only the visible branch receives updates and get executed.
669
- 7. **x** and **y**: Sets the location of the object.
670
- 8. **scrollLeft** and **scrollTop**: Control the scrolling position of the object.
671
- 9. **leftMargin**, **rightMargin**, **topMargin**, **bottomMargin**: Set margins between objects.
672
- 10. **domHolder**: When set to true, indicates that the current object serves as the DOM holder for all of its descendant objects. It can also return a DOM element, in which case the current object and all descendants will be contained within that DOM element.
673
- 11. **domParent**: Set by the container or children to control which DOM container they are embedded in.
674
- 12. **isVisible**: An optional target to explicitly control the visibility of the object, bypassing TargetJS’s automatic calculation.
675
- 13. **canHaveDom**: A boolean flag that determines if the object can have a DOM element on the page.
676
- 14. **canDeleteDom**: When set to true (the default), indicates that the object's DOM element will be removed when the object becomes invisible.
677
- 16. **widthFromDom** and **heightFromDom**: Boolean flags to explicilty control if the width and height should be derived from the DOM element.
678
- 17. **textOnly**: A boolean flag that specifies the content type as either text or HTML. The default value is false, indicating text.
679
- 18. **isInFlow**: A boolean flag that determines if the object will contribute to the content height and width of its parent.
680
- 19. **style**: An object to set the HTML style of the object, especially for style names that aren’t built-in.
681
-
682
-
683
- Lastly, we have the event targets which their values can be an array of targets to activate on specific events or may implement the event handler directly.
684
-
685
- **Example with Target Array:**
686
- ```javascript
687
- onResize: [ 'width', 'height' ] // Activates declarative 'width' and 'height' targets on screen resize.
688
- ```
689
-
690
- **Example with Event handler:**
691
- ```javascript
692
- onResize() {
693
- this.setTarget('width', getScreenWidth());
694
- this.setTarget('height', getScreenHeight());
695
- }
696
- ```
697
-
698
- Here are all the event targets:
699
- 1. **onResize**: Triggered on screen resize events.
700
- 2. **onParentResize**: Activated when the parent’s width or height is updated.
701
- 3. **onFocus**: Triggered on focus events.
702
- 4. **onBlur**: Triggered on blur events.
703
- 5. **onClick**: Activated on click events.
704
- 6. **onTouchStart**: Called when `touchstart` or `mousedown` events occur.
705
- 7. **onTouch**: Generic handler for all touch events.
706
- 8. **onTouchEnd**: Called when `touchend` or `mouseup` events occur.
707
- 9. **onSwipe**: Activated on swipe events.
708
- 10. **onEnter**: Triggered when the mouse cursor enters the object’s DOM.
709
- 11. **onLeave**: Triggered when the mouse cursor leaves the object’s DOM.
710
- 12. **onScrollTop**: Called on top scroll events.
711
- 13. **onScrollLeft**: Called on left scroll events.
712
- 14. **onScroll**: Called on both scroll events.
713
- 15. **onWindowScroll**: Called on window scroll events.
714
- 16. **onKey**: Triggered by key events.
715
- 17. **onVisible**: Activated when the object becomes visible.
716
- 18. **onChildrenChange**: Triggered when the children count changes.
717
- 19. **onVisibleChildrenChange**: Triggered when the count of visible children changes.
718
- 20. **onDomEvent**: It accepts an array of targets and activates them when their associated object acquires a DOM element.
437
+ - **Styles**: `width`, `height`, `opacity`, `x`, `y`, `rotate`, `scale`, `backgroundColor`.
438
+ - **Structure**: `html`, `children`, `element`, `domHolder`.
439
+ - **Events**: `onClick`, `onScroll`, `onKey`, `onVisibleChildrenChange`, `onResize`.
719
440
 
720
441
  ## How to Debug in TargetJS
721
442
 
722
443
  TargetJS provides built-in debugging tools:
723
444
 
724
- ```bash
445
+ ```js
725
446
  TargetJS.tApp.stop(); // Stop the application.
726
447
  TargetJS.tApp.start(); // Restart the application
727
448
  TargetJS.tApp.throttle = 0; // Slow down execution (milliseconds between cycles)