aberdeen 0.5.0 → 1.0.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aberdeen",
3
- "version": "0.5.0",
3
+ "version": "1.0.4",
4
4
  "author": "Frank van Viegen",
5
5
  "main": "dist-min/aberdeen.js",
6
6
  "devDependencies": {
@@ -12,31 +12,34 @@
12
12
  ".": {
13
13
  "default": "./dist-min/aberdeen.js",
14
14
  "development": "./dist/aberdeen.js",
15
- "types`": "./dist/aberdeen.d.ts"
15
+ "types": "./dist/aberdeen.d.ts"
16
16
  },
17
17
  "./route": {
18
18
  "default": "./dist-min/route.js",
19
19
  "development": "./dist/route.js",
20
- "types`": "./dist/route.d.ts"
20
+ "types": "./dist/route.d.ts"
21
21
  },
22
22
  "./transition": {
23
23
  "default": "./dist-min/transition.js",
24
24
  "development": "./dist/transition.js",
25
- "types`": "./dist/transition.d.ts"
25
+ "types": "./dist/transition.d.ts"
26
26
  },
27
27
  "./prediction": {
28
28
  "default": "./dist-min/prediction.js",
29
29
  "development": "./dist/prediction.js",
30
- "types`": "./dist/prediction.d.ts"
30
+ "types": "./dist/prediction.d.ts"
31
31
  },
32
32
  "./package.json": "./package.json"
33
33
  },
34
- "description": "A TypeScript/JavaScript library for quickly building performant declarative user interfaces without the use of a virtual DOM nor any transpilation.",
34
+ "description": "A TypeScript/JavaScript library for quickly building performant reactive user interfaces without the use of a virtual DOM nor any transpilation.",
35
35
  "files": [
36
36
  "dist",
37
37
  "dist-min",
38
38
  "src"
39
39
  ],
40
+ "bin": {
41
+ "html-to-aberdeen": "./html-to-aberdeen"
42
+ },
40
43
  "license": "MIT",
41
44
  "scripts": {
42
45
  "build": "bun run build:dist && typedoc && rm -rf dist-docs/assets/aberdeen ; cp -r dist dist-docs/assets/aberdeen",
package/src/aberdeen.ts CHANGED
@@ -1133,7 +1133,10 @@ export function proxy(target: TargetType): TargetType {
1133
1133
  * setTimeout(() => rawUser.name += '?', 2000);
1134
1134
  *
1135
1135
  * // Both userProxy and rawUser end up as `{name: 'Frank!?'}`
1136
- * setTimeout(() => console.log('final values', userProxy, rawUser), 3000);
1136
+ * setTimeout(() => {
1137
+ * console.log('final proxied', userProxy)
1138
+ * console.log('final unproxied', rawUser)
1139
+ * }, 3000);
1137
1140
  * ```
1138
1141
  */
1139
1142
  export function unproxy<T>(target: T): T {
@@ -1469,22 +1472,32 @@ const SPECIAL_PROPS: {[key: string]: (value: any) => void} = {
1469
1472
  * - `{html: string}`: Add the value as HTML to the *current* element. This should only be used in exceptional situations. And of course, beware of XSS.
1470
1473
  * - `{element: Node}`: Add a pre-existing HTML `Node` to the *current* element.
1471
1474
  *
1475
+ * @returns The most inner DOM element that was created (not counting text nodes nor elements created by content functions),
1476
+ * or undefined if no elements were created.
1472
1477
  *
1473
1478
  * @example Create Element
1474
1479
  * ```typescript
1475
1480
  * $('button.secondary.outline:Submit', {
1476
- * disabled: true,
1481
+ * disabled: false,
1477
1482
  * click: () => console.log('Clicked!'),
1478
1483
  * $color: 'red'
1479
1484
  * });
1480
1485
  * ```
1486
+ *
1487
+ * @example Create Nested Elements
1488
+ * ```typescript
1489
+ * let inputElement: Element = $('label:Click me', 'input', {type: 'checkbox'});
1490
+ * // You should usually not touch raw DOM elements, unless when integrating
1491
+ * // with non-Aberdeen code.
1492
+ * console.log('DOM element:', inputElement);
1493
+ * ```
1481
1494
  *
1482
- * @example Nested Elements & Reactive Scope
1495
+ * @example Content Functions & Reactive Scope
1483
1496
  * ```typescript
1484
1497
  * const state = proxy({ count: 0 });
1485
1498
  * $('div', () => { // Outer element
1486
1499
  * // This scope re-renders when state.count changes
1487
- * $('p:Count is ${state.count}`);
1500
+ * $(`p:Count is ${state.count}`);
1488
1501
  * $('button:Increment', { click: () => state.count++ });
1489
1502
  * });
1490
1503
  * ```
@@ -1511,9 +1524,10 @@ const SPECIAL_PROPS: {[key: string]: (value: any) => void} = {
1511
1524
  */
1512
1525
 
1513
1526
 
1514
- export function $(...args: (string | null | undefined | false | (() => void) | Record<string,any>)[]): void {
1527
+ export function $(...args: (string | null | undefined | false | (() => void) | Record<string,any>)[]): void | Element {
1515
1528
  let savedCurrentScope;
1516
1529
  let err;
1530
+ let result;
1517
1531
 
1518
1532
  for(let arg of args) {
1519
1533
  if (arg == null || arg === false) continue;
@@ -1542,15 +1556,15 @@ export function $(...args: (string | null | undefined | false | (() => void) | R
1542
1556
  err = `Tag '${arg}' cannot contain space`;
1543
1557
  break;
1544
1558
  } else {
1545
- const el = document.createElement(arg);
1546
- if (classes) el.className = classes.replaceAll('.', ' ');
1547
- if (text) el.textContent = text;
1548
- addNode(el);
1559
+ result = document.createElement(arg);
1560
+ if (classes) result.className = classes.replaceAll('.', ' ');
1561
+ if (text) result.textContent = text;
1562
+ addNode(result);
1549
1563
  if (!savedCurrentScope) {
1550
1564
  savedCurrentScope = currentScope;
1551
1565
  }
1552
- let newScope = new ChainedScope(el, true);
1553
- newScope.lastChild = el.lastChild || undefined;
1566
+ let newScope = new ChainedScope(result, true);
1567
+ newScope.lastChild = result.lastChild || undefined;
1554
1568
  if (topRedrawScope === currentScope) topRedrawScope = newScope;
1555
1569
  currentScope = newScope;
1556
1570
  }
@@ -1575,6 +1589,7 @@ export function $(...args: (string | null | undefined | false | (() => void) | R
1575
1589
  currentScope = savedCurrentScope;
1576
1590
  }
1577
1591
  if (err) throw new Error(err);
1592
+ return result;
1578
1593
  }
1579
1594
 
1580
1595
  let cssCount = 0;
@@ -1725,7 +1740,7 @@ let onError: (error: Error) => boolean | undefined = defaultOnError;
1725
1740
  *
1726
1741
  * try {
1727
1742
  * // Attempt to show a custom message in the UI
1728
- * $('div.error-display:Oops, something went wrong!');
1743
+ * $('div.error-message:Oops, something went wrong!');
1729
1744
  * } catch (e) {
1730
1745
  * // Ignore errors during error handling itself
1731
1746
  * }
@@ -1733,8 +1748,20 @@ let onError: (error: Error) => boolean | undefined = defaultOnError;
1733
1748
  * return false; // Suppress default console log and DOM error message
1734
1749
  * });
1735
1750
  *
1751
+ * // Styling for our custom error message
1752
+ * insertCss({
1753
+ * '.error-message': {
1754
+ * backgroundColor: '#e31f00',
1755
+ * display: 'inline-block',
1756
+ * color: 'white',
1757
+ * borderRadius: '3px',
1758
+ * padding: '2px 4px',
1759
+ * }
1760
+ * }, true); // global style
1761
+ *
1736
1762
  * // Cause an error within a render scope.
1737
1763
  * $('div.box', () => {
1764
+ * // Will cause our error handler to insert an error message within the box
1738
1765
  * noSuchFunction();
1739
1766
  * })
1740
1767
  * ```
@@ -1751,7 +1778,7 @@ export function setErrorHandler(handler?: (error: Error) => boolean | undefined)
1751
1778
  * call or a {@link $} element's render function).
1752
1779
  *
1753
1780
  * **Note:** While this provides access to the DOM element, directly manipulating it outside
1754
- * of Aberdeen's control is generally discouraged. Prefer declarative updates using {@link $}.
1781
+ * of Aberdeen's control is generally discouraged. Prefer reactive updates using {@link $}.
1755
1782
  *
1756
1783
  * @returns The current parent `Element` for DOM insertion.
1757
1784
  *