targetj 1.0.240 → 1.0.242

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/Export.js CHANGED
@@ -1,4 +1,26 @@
1
- export * from "./build/App.js";
1
+ export {
2
+ App,
3
+ tApp,
4
+ tRoot,
5
+ isRunning,
6
+ getEvents,
7
+ getPager,
8
+ getLoader,
9
+ fetch,
10
+ fetchImage,
11
+ getManager,
12
+ getTargetManager,
13
+ getAnimationManager,
14
+ getRunScheduler,
15
+ getLocationManager,
16
+ getScreenWidth,
17
+ getScreenHeight,
18
+ getVisibles,
19
+ getResizeLastUpdate,
20
+ getTModelById,
21
+ getDomTModelById
22
+ } from "./build/App.js";
23
+
2
24
  export * from "./build/TModel.js";
3
25
  export * from "./build/Moves.js";
4
26
  export * from "./build/SearchUtil.js";
@@ -7,7 +29,7 @@ export * from "./build/TargetUtil.js";
7
29
  export * from "./build/TargetParser.js";
8
30
  export * from "./build/TModelUtil.js";
9
31
  export * from "./build/TUtil.js";
10
- export * from "./build/DomInit.js"
32
+ export * from "./build/DomInit.js";
11
33
  export * from "./build/$Dom.js";
12
34
  export * from "./build/Bracket.js";
13
35
  export * from "./build/BracketGenerator.js";
@@ -19,7 +41,7 @@ export * from "./build/AnimationUtil.js";
19
41
  export * from "./build/VisibilityUtil.js";
20
42
  export * from "./build/ScheduleUtil.js";
21
43
 
22
- import * as App from './build/App.js';
44
+ import * as AppModule from './build/App.js';
23
45
  import * as TModel from './build/TModel.js';
24
46
  import * as Moves from './build/Moves.js';
25
47
  import * as SearchUtil from './build/SearchUtil.js';
@@ -41,7 +63,7 @@ import * as VisibilityUtil from './build/VisibilityUtil.js';
41
63
  import * as ScheduleUtil from './build/ScheduleUtil.js';
42
64
 
43
65
  const TargetJS = {
44
- ...App,
66
+ ...AppModule,
45
67
  ...TModel,
46
68
  ...Moves,
47
69
  ...SearchUtil,
@@ -67,4 +89,4 @@ if (typeof window !== 'undefined') {
67
89
  window.TargetJS = TargetJS;
68
90
  }
69
91
 
70
- export default TargetJS;
92
+ export default TargetJS;
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![Stars](https://img.shields.io/github/stars/livetrails/targetjs.svg)](https://github.com/livetrails/targetjs/stargazers)
8
8
  [![npm version](https://img.shields.io/npm/v/targetj.svg)](https://www.npmjs.com/package/targetj)
9
9
 
10
- TargetJS is a JavaScript UI framework that replaces the "State → Render" model with "State → Transition → Render". It also lets code order directly define the UI sequence. It unifies UI, animations, API calls, event handling, and state into self-contained "Targets" that stack together like intelligent Lego pieces using Code-Ordered Reactivity.
10
+ TargetJS is a JavaScript UI framework that replaces the "State → Render" model with "State → Transition → Render". It also lets code order directly define the UI sequence. It unifies UI, animations, API calls, event handling, and state into self-contained "Targets" that stack together like Lego pieces using Code-Ordered Reactivity.
11
11
 
12
12
  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).
13
13
 
@@ -40,11 +40,11 @@ With its compact style, TargetJS makes the journey from A → B explicit and eff
40
40
 
41
41
  ## 🚀 Why TargetJS?
42
42
 
43
- 1. Unified State: State isn't "elsewhere". It is built into every Target.
44
- 2. Animation by Default: High-performance animations are baked into the logic.
45
- 3. Ultra-Compact: Write 30% to 70% less code than standard frameworks.
46
- 4. UI as Sequence: Code describes the UI story from top to bottom, exactly how the user experiences the interaction: "When this finishes, do that."
47
- 5. Zero Boilerplate Async: Targets can handle waiting for asynchronous operations automatically.
43
+ 1. Unified State: One single state. Transitions are state too.
44
+ 1. UI as Sequence: Code describes the UI story from top to bottom, just like the user experiences the interaction: "When this finishes, do that."
45
+ 1. Ultra-Compact: Minimal code, with no coordination variables.
46
+ 1. Zero Boilerplate Async: Targets handle waiting for nested asynchronous operations automatically.
47
+ 1. Animation by Default: High-performance animations are baked into the logic.
48
48
 
49
49
  ## ⚡ Quick Start (30 Seconds)
50
50
 
@@ -54,19 +54,31 @@ With its compact style, TargetJS makes the journey from A → B explicit and eff
54
54
  npm install targetj
55
55
  ```
56
56
 
57
- **2. The "Hello World" Sequence**
57
+ **2. Example**
58
58
 
59
- This creates a blue box that grows, then turns red, and then logs "Hello World" in order.
59
+ This creates the following sequential sequence: appear bounce → move → turn red → log. Notice how the code follows the UI sequence. There is only one state, and the animation transitions are part of that state.
60
60
 
61
61
  ```javascript
62
62
  import { App } from "targetj";
63
63
 
64
64
  App({
65
- backgroundColor: 'blue', // Starts immediately
66
- width: { value: [100, 200], steps: 100, interval: 8 }, // Starts immediately: animate width from 100px to 200px in 100 steps with 8 ms interval per step.
67
- height: { value: [100, 200], steps: 100, interval: 8 }, // Starts immediately: animate height.
68
- backgroundColor$$: { value: 'red', steps: 100, interval: 8 }, // Wait ($$) for width/height to finish
69
- done$$() { console.log("Hello World!"); } // 3. Waits ($$) for the background color, width/height to finish
65
+ width: 100,
66
+ height: 100,
67
+ backgroundColor: "blue",
68
+
69
+ // Starts immediately: bounce in.
70
+ scale: { value: [0.5, 1.2, 1], steps: 24, interval: 12 },
71
+
72
+ // Waits for scale to finish, then moves right.
73
+ x$$: { value: [0, 180], steps: 40, interval: 8 },
74
+
75
+ // Waits for x to finish, then turns red.
76
+ backgroundColor$$: { value: "crimson", steps: 30, interval: 8 },
77
+
78
+ // Waits for the color change to finish.
79
+ done$$() {
80
+ console.log("Sequence complete");
81
+ }
70
82
  }).mount("#app");
71
83
  ```
72
84
 
@@ -80,11 +92,12 @@ Methods and properties both are internally transformed into targets that the fra
80
92
  A target can:
81
93
  - execute a method
82
94
  - hold a value
83
- - move toward that value over time
84
- - wait for previous targets
95
+ - move toward a new value over time
96
+ - pause while moving toward a value
97
+ - wait for previous targets to complete
85
98
  - react when previous targets update
86
99
  - fetch data
87
- - react to an event
100
+ - respond to events
88
101
  - create children
89
102
  - run callbacks
90
103
  - control its own lifecycle
@@ -101,13 +114,13 @@ A target can also be defined as an object with optional controls that manage its
101
114
  | `steps` | Turns a value change into an animation. |
102
115
  | `interval` | Delay (ms) between steps or executions. |
103
116
  | `cycles` | Number of times the target repeats. |
104
- | `loop` | Boolean form of repetition for continuous execution. |
117
+ | `loop` | Controls repetition, either actively for continuous execution or passively when the value changes. |
105
118
  | `active` | Boolean property controlling when `value` is executed. |
106
119
  | `enabledOn` | Determines whether the target is enabled for execution. |
120
+ | `pauseOn` | Pauses execution while the target is in progress. |
107
121
  | `easing` | Predefined easing function controlling how values update over steps. |
108
122
  | `onComplete` | Callback triggered when this target (and its children) finishes. |
109
123
  | `onValueChange` | Callback triggered when the target emits a new value. |
110
- | `onChange` | Callback triggered when the target emits a new value. |
111
124
  | `on<PropertyName>Step` | Callback triggered on every step of a specific property. |
112
125
 
113
126
  ### Compact Execution Syntax
@@ -222,7 +235,7 @@ App({
222
235
 
223
236
  ### Summary
224
237
 
225
- Each target has its own state and lifecycle. Targets execute automatically in the order they are written. `$$` defers execution until all prior sibling targets (including their children) are fully complete. Animations, API calls, event handling, and child creation are all treated uniformly as targets. Complex asynchronous flows can be structured by organizing work into parent and child targets. In addition, targets provide built-in capabilities such as `onComplete` callbacks, `enabledOn`, looping with delays, and more. This also makes the code more compact, as it avoids using extra variables to track progress and reduces the need for loops and conditional statements.
238
+ Each target has its own state and lifecycle. Targets execute automatically in the order they are written. `$$` defers execution until all prior sibling targets (including their children) are fully complete. Animations, API calls, event handling, and child creation are all treated uniformly as targets. Complex asynchronous flows can be structured by organizing work into parent and child targets. In addition, targets provide built-in capabilities such as `onComplete` callbacks, `pauseOn`, `enabledOn`, looping with delays, and more. This also makes the code more compact, as it avoids using extra variables to track progress and reduces the need for loops and conditional statements.
226
239
 
227
240
  ---
228
241
 
@@ -399,13 +412,13 @@ In this advanced example, we implement an infinite-scrolling application.
399
412
 
400
413
  * `photo` and `userName` each add a `div` element inside every item, serving as placeholders for the photo and user name.
401
414
 
402
- * `pause$$` delays the execution of all targets that follow it by 100 ms.
415
+ * `pause$$` delays the execution of all targets that follow it by 300 ms. It also has `pauseOn: 'hidden'`, which means the delay is paused if the item becomes invisible, such as when the user scrolls down quickly. This also puts all following `$$` targets on hold, so `fetch$$` will not execute until the item becomes visible again.
403
416
 
404
417
  * `fetch$$` retrieves the user’s details.
405
418
 
406
419
  * `reveal$$` executes after `fetch$$`, revealing the user name and populating the photo with a random color.
407
420
 
408
- * `wave$$` executes only after all preceding children have completed their targets, giving each user item a coordinated animation.
421
+ * `wave` executes when all visible children have completed their targets or when scrolling ends, giving each user item a coordinated animation.
409
422
 
410
423
  TargetJS employs a tree-like structure to track visible branches, optimizing scroller performance.
411
424
 
@@ -421,61 +434,88 @@ import { App, getEvents, getScreenWidth, getScreenHeight } from "targetj";
421
434
 
422
435
  App({
423
436
  preventDefault: true,
424
- width: 250,
437
+ width: 300,
425
438
  height() { return getScreenHeight(); },
426
439
  x() { return (getScreenWidth() - this.getWidth()) / 2; },
427
440
  containerOverflowMode: "always",
441
+ canDeleteDom: false,
442
+ overflow: 'scroll',
443
+ onWindowScroll: true,
428
444
  addChildren: {
429
- waitForChildren: 'visible',
430
- value() {
431
- return Array.from({ length: 10 }, (_, i) => ({
432
- height: 56,
433
- width() { return this.parent.getWidth(); },
434
- bottomMargin: 8,
435
- borderRadius: 12,
436
- backgroundColor: "white",
437
- boxShadow: "0 8px 20px rgba(0,0,0,0.08)",
438
- photo: {
439
- x: 10, y: 10, width: 34, height: 34,
440
- borderRadius: "50%",
441
- backgroundColor: "#ddd"
442
- },
443
- userName: {
444
- x: 60, y: 10, width: 180, height: 30,
445
- overflow: "hidden",
446
- borderRadius: 5,
447
- backgroundColor: "#ddd"
448
- },
449
- pause$$: { interval: 100 },
450
- fetch$$: "https://targetjs.io/api/randomUser",
451
- reveal$$() {
452
- const userName = this.getChild("userName");
453
- userName.setTarget("html", this.val("fetch$$").name);
454
- userName.setTarget("backgroundColor", { value: "white", steps: 20 });
455
- this.getChild("photo").setTarget("backgroundColor", { value: "#" + Math.random().toString(16).slice(-6), steps: 20 });
456
- },
457
- }));
458
- }
445
+ value() {
446
+ return Array.from({length: 10}, (_, i) => ({
447
+ height: 56,
448
+ width() { return this.parent.getWidth() - 30; },
449
+ bottomMargin: 8,
450
+ borderRadius: 12,
451
+ backgroundColor: 'white',
452
+ boxShadow: "0 8px 20px rgba(0,0,0,0.08)",
453
+ pause: {
454
+ interval() { return getEvents().isWindowScrolling() ? 600 : 0; },
455
+ pauseOn: 'hidden'
456
+ },
457
+ photo$$: {
458
+ x: 10,
459
+ y: 10,
460
+ width:34,
461
+ height:34,
462
+ borderRadius: '50%',
463
+ backgroundColor: '#ddd'
464
+ },
465
+ userName$$: {
466
+ x: 60,
467
+ y: 10,
468
+ width: 180,
469
+ height: 30,
470
+ overflow: 'hidden',
471
+ borderRadius: 5,
472
+ backgroundColor: '#ddd'
473
+ },
474
+ pause$$: {
475
+ interval: 300,
476
+ pauseOn: 'hidden'
477
+ },
478
+ fetch$$: "https://targetjs.io/api/randomUser",
479
+ reveal$$() {
480
+ const userName = this.getChild('userName$$');
481
+ userName.setTarget('html', this.val('fetch$$').name);
482
+ userName.setTarget('backgroundColor', { value: 'white', steps: 20 });
483
+ this.getChild('photo$$').setTarget('backgroundColor', { value: '#' + Math.random().toString(16).slice(-6), steps: 20 });
484
+ }
485
+ }));
486
+ },
487
+ onVisibleComplete() {
488
+ if (!getEvents().isWindowScrolling()) {
489
+ this.activateTarget('wave');
490
+ }
491
+ }
459
492
  },
460
- wave$$: {
461
- interval: 30,
462
- cycles() { return this.visibleChildren.length; },
463
- value(i) {
464
- const child = this.visibleChildren[i];
465
- if (child) {
466
- child.setTarget("scale", { value: [1, 1.06, 1], steps: 18 });
467
- child.setTarget("opacity", { value: [1, 0.92, 1], steps: 18 });
468
- }
469
- }
493
+ onWindowScrollTopEnd() {
494
+ if (this.isTargetVisibleTreeComplete('addChildren')) {
495
+ this.activateTarget('wave');
496
+ }
470
497
  },
471
- onScroll() {
472
- this.setTarget("scrollTop", Math.max(0, this.getScrollTop() + getEvents().deltaY()));
498
+ wave: {
499
+ active: false,
500
+ interval: 30,
501
+ cycles() { return this.visibleChildren.length; },
502
+ value(i) {
503
+ const child = this.visibleChildren[i];
504
+ if (child) {
505
+ child.setTarget("scale", { value: [1, 1.06, 1], steps: 18 });
506
+ child.setTarget("opacity", { value: [1, 0.7, 1], steps: 18 });
507
+ }
508
+ }
473
509
  },
474
510
  onVisibleChildrenChange() {
475
- const visibleCount = this.visibleChildren.length;
476
- if (getEvents().dir() !== "up" && visibleCount * 64 < this.getHeight()) {
477
- this.activateTarget("addChildren");
478
- }
511
+ if (!this.visibleChildren.length) {
512
+ return this.activateTarget("addChildren");
513
+ }
514
+ const scrollTop = this.$dom?.getScrollTop() ?? 0;
515
+ const lastY = this.getLastChild().getY() - scrollTop - 500;
516
+ if (lastY <= this.getHeight()) {
517
+ this.activateTarget("addChildren");
518
+ }
479
519
  }
480
520
  }).mount("#userList");
481
521
  ```
package/build/$Dom.js CHANGED
@@ -1,21 +1,16 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.$Dom = void 0;
7
- var _TUtil = require("./TUtil.js");
8
- var _App = require("./App.js");
9
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
10
2
  function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
11
3
  function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
12
4
  function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
13
5
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
14
6
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ import { TUtil } from "./TUtil.js";
8
+ import { getManager } from "./App.js";
9
+
15
10
  /**
16
11
  * It serves as a wrapper for all DOM operations.
17
12
  */
18
- var $Dom = exports.$Dom = /*#__PURE__*/function () {
13
+ var $Dom = /*#__PURE__*/function () {
19
14
  function $Dom(elemSelector) {
20
15
  _classCallCheck(this, $Dom);
21
16
  if (typeof elemSelector === 'string') {
@@ -208,7 +203,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
208
203
  if (!this.element) {
209
204
  return;
210
205
  }
211
- if (_TUtil.TUtil.isDefined(value)) {
206
+ if (TUtil.isDefined(value)) {
212
207
  this.element.setAttribute(name, value);
213
208
  } else {
214
209
  return this.element.getAttribute(name);
@@ -221,7 +216,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
221
216
  return;
222
217
  }
223
218
  var currentValue = this.element.value;
224
- if (_TUtil.TUtil.isDefined(_value)) {
219
+ if (TUtil.isDefined(_value)) {
225
220
  this.element.value = _value;
226
221
  }
227
222
  return currentValue;
@@ -236,8 +231,8 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
236
231
  }, {
237
232
  key: "width",
238
233
  value: function width(_width) {
239
- if (_TUtil.TUtil.isDefined(_width)) {
240
- this.element.style.width = _TUtil.TUtil.isNumber(_width) ? "".concat(_width, "px") : _width;
234
+ if (TUtil.isDefined(_width)) {
235
+ this.element.style.width = TUtil.isNumber(_width) ? "".concat(_width, "px") : _width;
241
236
  } else {
242
237
  return this.element.offsetWidth;
243
238
  }
@@ -245,8 +240,8 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
245
240
  }, {
246
241
  key: "height",
247
242
  value: function height(_height) {
248
- if (_TUtil.TUtil.isDefined(_height)) {
249
- this.element.style.height = _TUtil.TUtil.isNumber(_height) ? "".concat(_height, "px") : _height;
243
+ if (TUtil.isDefined(_height)) {
244
+ this.element.style.height = TUtil.isNumber(_height) ? "".concat(_height, "px") : _height;
250
245
  } else {
251
246
  return this.element.offsetHeight;
252
247
  }
@@ -254,7 +249,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
254
249
  }, {
255
250
  key: "css",
256
251
  value: function css(_css) {
257
- if (_TUtil.TUtil.isDefined(_css)) {
252
+ if (TUtil.isDefined(_css)) {
258
253
  this.element.className = _css;
259
254
  } else {
260
255
  return this.element.className;
@@ -283,7 +278,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
283
278
  key: "getStyleValue",
284
279
  value: function getStyleValue(name) {
285
280
  var styleValue = this.style(name);
286
- var numericValue = _TUtil.TUtil.isDefined(styleValue) ? styleValue.replace(/[^-\d.]/g, '') : 0;
281
+ var numericValue = TUtil.isDefined(styleValue) ? styleValue.replace(/[^-\d.]/g, '') : 0;
287
282
  return parseFloat(numericValue);
288
283
  }
289
284
  }, {
@@ -402,7 +397,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
402
397
  }, {
403
398
  key: "html",
404
399
  value: function html(_html) {
405
- if (_TUtil.TUtil.isDefined(_html)) {
400
+ if (TUtil.isDefined(_html)) {
406
401
  if (this.isNoSlotHost() || !this.hasRealChildren) {
407
402
  this.element.innerHTML = _html;
408
403
  } else {
@@ -416,7 +411,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
416
411
  }, {
417
412
  key: "text",
418
413
  value: function text(_text) {
419
- if (_TUtil.TUtil.isDefined(_text)) {
414
+ if (TUtil.isDefined(_text)) {
420
415
  if (this.isNoSlotHost() || !this.hasRealChildren) {
421
416
  this.element.textContent = _text;
422
417
  } else {
@@ -464,7 +459,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
464
459
  }, {
465
460
  key: "innerHTML",
466
461
  value: function innerHTML(html) {
467
- if (_TUtil.TUtil.isDefined(html)) {
462
+ if (TUtil.isDefined(html)) {
468
463
  this.element.innerHTML = html;
469
464
  } else {
470
465
  return this.element.innerHTML;
@@ -473,7 +468,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
473
468
  }, {
474
469
  key: "innerText",
475
470
  value: function innerText(text) {
476
- if (_TUtil.TUtil.isDefined(text)) {
471
+ if (TUtil.isDefined(text)) {
477
472
  this.element.innerText = text;
478
473
  } else {
479
474
  return this.element.innerText;
@@ -524,7 +519,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
524
519
  }, {
525
520
  key: "getContext",
526
521
  value: function getContext(type, selector) {
527
- var element = _TUtil.TUtil.isDefined(selector) ? $Dom.query(selector) : this.query('canvas');
522
+ var element = TUtil.isDefined(selector) ? $Dom.query(selector) : this.query('canvas');
528
523
  return element ? element.getContext(type) : undefined;
529
524
  }
530
525
  }, {
@@ -616,7 +611,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
616
611
  value: function findNearestParentWithId(element) {
617
612
  while (element) {
618
613
  var oid = typeof element.getAttribute === 'function' && element.getAttribute("id") ? element.getAttribute("id") : null;
619
- if (oid && (0, _App.getManager)().visibleOidMap[oid]) {
614
+ if (oid && getManager().visibleOidMap[oid]) {
620
615
  return oid;
621
616
  }
622
617
  element = element.parentElement;
@@ -625,7 +620,7 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
625
620
  }, {
626
621
  key: "detach",
627
622
  value: function detach(element) {
628
- var parent = _TUtil.TUtil.isDefined(element) ? element.parentElement : null;
623
+ var parent = TUtil.isDefined(element) ? element.parentElement : null;
629
624
  if (parent) {
630
625
  parent.removeChild(element);
631
626
  }
@@ -692,4 +687,5 @@ var $Dom = exports.$Dom = /*#__PURE__*/function () {
692
687
  }
693
688
  }
694
689
  }]);
695
- }();
690
+ }();
691
+ export { $Dom };