targetj 1.0.201 → 1.0.202
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 +86 -60
- package/build/BaseModel.js +1 -1
- package/dist/targetjs.js +1 -1
- package/dist/targetjs.js.gz +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,26 +26,20 @@ Targets unlock a fundamentally new way of coding that simplifies everything from
|
|
|
26
26
|
2. Declarative Reactive Targets: Targets can explicitly declare reactive execution triggered by the run or completion of their immediately preceding targets, whether synchronous or asynchronous.
|
|
27
27
|
3. All-in-One Solution: Offers a unified approach to UI rendering, API integration, state management, event handling, and animation.
|
|
28
28
|
4. Code-Ordered Execution: Targets are chained top to bottom and the execution flow generally follows the order in which the code is written.
|
|
29
|
-
5. Autonomous Methods: Methods in TargetJS are not directly callable. Instead, they are designed to execute themselves or react dynamically to the execution or completion of preedings targets. This
|
|
29
|
+
5. Autonomous Methods: Methods in TargetJS are not directly callable. Instead, they are designed to execute themselves or react dynamically to the execution or completion of preedings targets. This enables declarative programming that inherently supports asynchronous operations without explicit plumbing like using async/await keywords.
|
|
30
30
|
6. Compactness: TargetJS allows developers to achieve interactive UIs with significantly less code.
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
## Examples: From like button → animated like + API (in 7 steps)
|
|
34
34
|
|
|
35
|
-
> **Postfixes**
|
|
36
|
-
>
|
|
37
|
-
> * **`$`** = *reactive*: runs every time the **immediately previous** target updates.
|
|
38
|
-
> * **`$$`** = *deferred*: runs after all prior targets complete including animations and fetches.
|
|
39
|
-
>
|
|
40
|
-
> **Reordering**
|
|
41
|
-
> Targets execute in the order they’re written. You can reorder them like LEGO bricks to change the flow. `$$` automatically follow the new sequence.
|
|
42
|
-
|
|
43
35
|
---
|
|
44
36
|
|
|
45
37
|
## 1) Like button (view only)
|
|
46
38
|
|
|
47
39
|
**What this shows:** One object defines a UI element without separate HTML/CSS. Static targets map directly to DOM styles/attributes.
|
|
48
40
|
|
|
41
|
+
<img src="https://targetjs.io/img/likeButton.png" width="130" />
|
|
42
|
+
|
|
49
43
|
```javascript
|
|
50
44
|
import { App } from "targetj";
|
|
51
45
|
|
|
@@ -65,7 +59,10 @@ App({
|
|
|
65
59
|
|
|
66
60
|
## 2) Animation
|
|
67
61
|
|
|
68
|
-
**What this shows:** A mount-time animation that scales and changes the background over 12 steps, with 12ms pauses between steps.
|
|
62
|
+
**What this shows:** A mount-time animation that scales and changes the background over 12 steps, with 12ms pauses between steps. Targets without (`$`, `$$`, `_`) execute immediately in the order they are defined.
|
|
63
|
+
|
|
64
|
+
<img src="https://targetjs.io/img/likeButton6.gif" width="130" />
|
|
65
|
+
|
|
69
66
|
```javascript
|
|
70
67
|
import { App } from "targetj";
|
|
71
68
|
|
|
@@ -76,14 +73,16 @@ App({
|
|
|
76
73
|
textAlign: "center",
|
|
77
74
|
borderRadius: 10,
|
|
78
75
|
html: "♡ Like",
|
|
79
|
-
scale: [ { list: [1.2, 1] },
|
|
76
|
+
scale: [ { list: [1.2, 1] }, 12, 12 ],
|
|
80
77
|
background: [ { list: ["#ffe8ec", "#f5f5f5"] }, 12, 12 ]
|
|
81
78
|
});
|
|
82
79
|
```
|
|
83
80
|
|
|
84
81
|
## 3) Click → animation (imperative `setTarget`)
|
|
85
82
|
|
|
86
|
-
**What this shows:** Clicking plays the animations from the previous step
|
|
83
|
+
**What this shows:** Clicking plays the animations from the previous step using imperative `setTarget`.
|
|
84
|
+
|
|
85
|
+
<img src="https://targetjs.io/img/likeButton4.gif" width="130" />
|
|
87
86
|
|
|
88
87
|
```javascript
|
|
89
88
|
import { App } from "targetj";
|
|
@@ -95,7 +94,7 @@ App({
|
|
|
95
94
|
html: "♡ Like",
|
|
96
95
|
|
|
97
96
|
onClick() {
|
|
98
|
-
this.setTarget("scale", { list: [1.2, 1] },
|
|
97
|
+
this.setTarget("scale", { list: [1.2, 1] }, 12, 12);
|
|
99
98
|
this.setTarget("background", { list: ["#ffe8ec", "#f5f5f5"] }, 12, 12);
|
|
100
99
|
this.setTarget("html", "♥ Liked");
|
|
101
100
|
}
|
|
@@ -104,10 +103,11 @@ App({
|
|
|
104
103
|
|
|
105
104
|
---
|
|
106
105
|
|
|
107
|
-
## 4) Sequencing with `$$`: small heart
|
|
106
|
+
## 4) Sequencing with `$$`: Adding a small heart after click
|
|
108
107
|
|
|
109
|
-
**What this shows:** A `$$` target (deferred) runs only after all prior targets finish (including `onClick` and animations). Here it adds a new heart element and runs its fly motion only once the click sequence has completed.
|
|
108
|
+
**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.
|
|
110
109
|
|
|
110
|
+
<img src="https://targetjs.io/img/likeButton7.gif" width="130" />
|
|
111
111
|
|
|
112
112
|
```javascript
|
|
113
113
|
import { App } from "targetj";
|
|
@@ -117,7 +117,7 @@ App({
|
|
|
117
117
|
borderRadius: 10, background: "#f5f5f5", cursor: "pointer", userSelect: "none",
|
|
118
118
|
html: "♡ Like",
|
|
119
119
|
onClick() {
|
|
120
|
-
this.setTarget("scale", { list: [1.2, 1] },
|
|
120
|
+
this.setTarget("scale", { list: [1.2, 1] }, 12, 12);
|
|
121
121
|
this.setTarget("background", { list: ["#ffe8ec", "#f5f5f5"] }, 12, 12);
|
|
122
122
|
this.setTarget("html", "♥ Liked");
|
|
123
123
|
},
|
|
@@ -141,7 +141,9 @@ App({
|
|
|
141
141
|
|
|
142
142
|
## 5) Another `$$`: big heart, different motion
|
|
143
143
|
|
|
144
|
-
**What this shows:**
|
|
144
|
+
**What this shows:** Deferred addition of a new element using $$. `bigHeart$$` waits for `heart$$` to complete its animation, then adds a larger heart and runs its own animation.
|
|
145
|
+
|
|
146
|
+
<img src="https://targetjs.io/img/likeButton8.gif" width="130" />
|
|
145
147
|
|
|
146
148
|
```javascript
|
|
147
149
|
import { App } from "targetj";
|
|
@@ -152,7 +154,7 @@ App({
|
|
|
152
154
|
html: "♡ Like",
|
|
153
155
|
|
|
154
156
|
onClick() {
|
|
155
|
-
this.setTarget("scale", { list: [1.2, 1] },
|
|
157
|
+
this.setTarget("scale", { list: [1.2, 1] }, 12, 12);
|
|
156
158
|
this.setTarget("background", { list: ["#ffe8ec", "#f5f5f5"] }, 12, 12);
|
|
157
159
|
this.setTarget("html", "♥ Liked");
|
|
158
160
|
},
|
|
@@ -190,11 +192,11 @@ App({
|
|
|
190
192
|
|
|
191
193
|
## 6) `fetch$$`
|
|
192
194
|
|
|
193
|
-
**What this shows:** Networking is just another target. The POST happens **only after** all prior visual steps complete
|
|
195
|
+
**What this shows:** Networking is just another target. The POST happens **only after** all prior visual steps complete, since the target is postfixed with `$$`.
|
|
194
196
|
|
|
195
197
|
```javascript
|
|
196
198
|
App({
|
|
197
|
-
// …same as step
|
|
199
|
+
// …same as step 5…
|
|
198
200
|
|
|
199
201
|
fetch$$: { method: "POST", id: 123, url: "/api/like" }
|
|
200
202
|
});
|
|
@@ -202,9 +204,11 @@ App({
|
|
|
202
204
|
|
|
203
205
|
---
|
|
204
206
|
|
|
205
|
-
## 7) Final version
|
|
207
|
+
## 7) Final version
|
|
206
208
|
|
|
207
|
-
**What this shows:** A
|
|
209
|
+
**What this shows:** A Like button that consolidates the previous steps into a single component. After the POST completes, a cleanup `removeHearts$$` target runs to remove the two heart elements. The button also includes basic accessibility (role, tabIndex, and Enter to activate).
|
|
210
|
+
|
|
211
|
+
<img src="https://targetjs.io/img/likeButton9.gif" width="130" />
|
|
208
212
|
|
|
209
213
|
```javascript
|
|
210
214
|
import { App } from "targetj";
|
|
@@ -216,7 +220,7 @@ App({
|
|
|
216
220
|
role: "button", tabIndex: 0,
|
|
217
221
|
html: "♡ Like",
|
|
218
222
|
onClick() {
|
|
219
|
-
this.setTarget("scale", { list: [1.2, 1] },
|
|
223
|
+
this.setTarget("scale", { list: [1.2, 1] }, 12, 12);
|
|
220
224
|
this.setTarget("background", { list: ["#ffe8ec", "#f5f5f5"] }, 12, 12);
|
|
221
225
|
this.setTarget("html", "♥ Liked");
|
|
222
226
|
},
|
|
@@ -272,7 +276,7 @@ Or in HTML (no JavaScript required), using tg- attributes that mirror object lit
|
|
|
272
276
|
tg-html="♡ Like"
|
|
273
277
|
tg-tabIndex="0"
|
|
274
278
|
tg-onClick="function() {
|
|
275
|
-
this.setTarget('scale', { list: [1.2, 1] },
|
|
279
|
+
this.setTarget('scale', { list: [1.2, 1] }, 12, 12);
|
|
276
280
|
this.setTarget('background', { list: ['#ffe8ec', '#f5f5f5'] }, 12, 12);
|
|
277
281
|
this.setTarget('html', '♥ Liked');
|
|
278
282
|
}"
|
|
@@ -316,11 +320,11 @@ Or in HTML (no JavaScript required), using tg- attributes that mirror object lit
|
|
|
316
320
|
|
|
317
321
|
## Final takeaway
|
|
318
322
|
|
|
319
|
-
TargetJS treats time as a first-class concept. Instead of wiring callbacks and effects, you write a sequence of targets.
|
|
323
|
+
- TargetJS treats time as a first-class concept. Instead of wiring callbacks and effects, you write a sequence of targets.
|
|
320
324
|
$ reacts to the previous step; $$ defers until all prior steps finish. Animations, API calls, and child creation are all the same kind of thing: targets.
|
|
321
|
-
So complex flows read top-to-bottom
|
|
322
|
-
|
|
323
|
-
|
|
325
|
+
So complex flows read top-to-bottom.
|
|
326
|
+
- Minimal plumbing yet full control to manage a flow of complex asynchronous operations.
|
|
327
|
+
|
|
324
328
|
## Table of Contents
|
|
325
329
|
|
|
326
330
|
1. [Targets: The Building Blocks of TargetJS](#targets-the-building-blocks-of-targetjs)
|
|
@@ -416,53 +420,75 @@ TargetJS addresses several common pain points in front-end development:
|
|
|
416
420
|
|
|
417
421
|
## More Examples
|
|
418
422
|
|
|
419
|
-
## Loading
|
|
423
|
+
## Loading Five Users Example
|
|
420
424
|
|
|
421
|
-
In this example, we load
|
|
425
|
+
In this example, we load five separate users and display five boxes, each containing a user's name and email.
|
|
422
426
|
|
|
423
|
-
- `fetch` calls
|
|
424
|
-
- `
|
|
425
|
-
- TargetJS ensures that API results are processed in the same sequence as the API calls. For example, if the user1 API result arrives before user0, `
|
|
426
|
-
|
|
427
|
-
|
|
427
|
+
- `fetch` calls five APIs to retrieve details for five users.
|
|
428
|
+
- `child` is a special target that adds a new item to the parent each time it executes. Because it ends with `$` in this example, it executes every time an API call returns a result.
|
|
429
|
+
- TargetJS ensures that API results are processed in the same sequence as the API calls. For example, if the user1 API result arrives before user0, `child` will not execute until the result for user0 has been received.
|
|
430
|
+
|
|
431
|
+
<img src="https://targetjs.io/img/fetch-5-users.gif" width="130" />
|
|
428
432
|
|
|
429
433
|
```javascript
|
|
430
|
-
import { App
|
|
434
|
+
import { App } from "targetj";
|
|
431
435
|
|
|
432
436
|
App({
|
|
437
|
+
gap: 10,
|
|
433
438
|
fetch: ['https://targetjs.io/api/randomUser?id=user0',
|
|
434
|
-
'https://targetjs.io/api/randomUser?id=user1'
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
439
|
+
'https://targetjs.io/api/randomUser?id=user1',
|
|
440
|
+
'https://targetjs.io/api/randomUser?id=user2',
|
|
441
|
+
'https://targetjs.io/api/randomUser?id=user3',
|
|
442
|
+
'https://targetjs.io/api/randomUser?id=user4'
|
|
443
|
+
],
|
|
444
|
+
child$() {
|
|
445
|
+
const user = this.prevTargetValue;
|
|
446
|
+
return {
|
|
447
|
+
width: 200,
|
|
448
|
+
height: 65,
|
|
449
|
+
borderRadius: 10,
|
|
450
|
+
boxSizing: "border-box",
|
|
451
|
+
padding: 10,
|
|
452
|
+
fontSize: 14,
|
|
453
|
+
background: "#f0f0f0",
|
|
454
|
+
scale: [{ list: [0.8, 1] }, 14, 12],
|
|
455
|
+
html$() {
|
|
456
|
+
return `<div style="font-weight:600">${user.name}</div>
|
|
457
|
+
<div style="opacity:.65">${user.email}</div>`;
|
|
458
|
+
},
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
It can also be written using a target’s `cycles` and `intervals` properties/methods to fetch users at intervals instead of in a single batch. In this example, we set interval to 1000, making the API call once every second.
|
|
465
|
+
|
|
466
|
+
<img src="https://targetjs.io/img/fetch-5-users2.gif" width="130" />
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
```javascript
|
|
470
|
+
App({
|
|
471
|
+
gap: 10,
|
|
472
|
+
fetch: {
|
|
473
|
+
interval: 1000,
|
|
474
|
+
cycles: 4,
|
|
475
|
+
value(i) { return `https://targetjs.io/api/randomUser?id=user${i}`; }
|
|
476
|
+
},
|
|
477
|
+
child$() {
|
|
478
|
+
return {
|
|
479
|
+
// …same as the previous example…
|
|
480
|
+
};
|
|
442
481
|
}
|
|
443
482
|
});
|
|
444
483
|
```
|
|
445
|
-
Or in HTML:
|
|
446
|
-
|
|
447
|
-
```html
|
|
448
|
-
<div tg-fetch="['https://targetjs.io/api/randomUser?id=user0', 'https://targetjs.io/api/randomUser?id=user1']">
|
|
449
|
-
<div
|
|
450
|
-
tg-background="mediumpurple"
|
|
451
|
-
tg-html="function(index) { return this.getParentValue('fetch')[index].name; }"
|
|
452
|
-
tg-width="[{ list: [100, 250, 100] }, 50, 10]"
|
|
453
|
-
tg-height$="return this.prevTargetValue / 2;"
|
|
454
|
-
>
|
|
455
|
-
</div>
|
|
456
|
-
</div>
|
|
457
|
-
```
|
|
458
484
|
|
|
459
485
|
### Infinite Loading and Scrolling Example
|
|
460
486
|
|
|
461
487
|
In this advanced example, we demonstrate an infinite scrolling application where each item is animated, and upon completing its animation, it dynamically triggers an API call to fetch and display its details.
|
|
462
488
|
|
|
463
|
-
- children: `children` is a special target that adds items to the container's children each time it is executed. The `onVisibleChildrenChange` event function detects changes in the visible children and activates the `children` target to add new items that fill the gaps.
|
|
489
|
+
- children: `children` is a special target that adds several items to the container's children each time it is executed. The `onVisibleChildrenChange` event function detects changes in the visible children and activates the `children` target to add new items that fill the gaps.
|
|
464
490
|
|
|
465
|
-
|
|
491
|
+
- loadItems: Since the target name ends with `$$`, it executes only after the newly created children finish their animations. It then iterates over all visible children and fetches their details. The result is an array of users. TargetJS ensures that this array preserves the order in which the API calls were made, not the order in which responses were received.
|
|
466
492
|
|
|
467
493
|
- populate: Since the target name ends with `$$`, it executes only after all API calls have completed. It updates the content of each scrollable item with the name returned by the API.
|
|
468
494
|
|
|
@@ -470,7 +496,7 @@ TargetJS employs a tree-like structure to track visible branches, optimizing the
|
|
|
470
496
|
|
|
471
497
|
We use the TModel class instead of a plain object to demonstrate how it can provide additional functionality and control. A plain object would also have worked in this example.
|
|
472
498
|
|
|
473
|
-
|
|
499
|
+
<img src="https://targetjs.io/img/infiniteScrolling.gif" width="130" />
|
|
474
500
|
|
|
475
501
|
```javascript
|
|
476
502
|
import { App, TModel, getEvents, fetch, getScreenWidth, getScreenHeight } from "targetj";
|
package/build/BaseModel.js
CHANGED
|
@@ -344,7 +344,7 @@ var BaseModel = exports.BaseModel = /*#__PURE__*/function () {
|
|
|
344
344
|
var nextKey = keyIndex < this.originalTargetNames.length - 1 ? this.originalTargetNames[keyIndex + 1] : undefined;
|
|
345
345
|
doesNextTargetUsePrevValue = nextKey && nextKey.endsWith('$') ? true : false;
|
|
346
346
|
if (doesNextTargetUsePrevValue || isInactiveKey || isExternalEvent || isInternalEvent || targetType === 'object' || targetType === 'function') {
|
|
347
|
-
if (!target.value && !_TargetParser.TargetParser.isChildObjectTarget(key, target) && !_TargetParser.TargetParser.isIntervalTarget(target)) {
|
|
347
|
+
if (!_TUtil.TUtil.isDefined(target.value) && !_TargetParser.TargetParser.isChildObjectTarget(key, target) && !_TargetParser.TargetParser.isIntervalTarget(target)) {
|
|
348
348
|
needsTargetExecution = true;
|
|
349
349
|
target = _TargetUtil.TargetUtil.wrapTarget(this, target, key);
|
|
350
350
|
}
|