aberdeen 1.3.2 → 1.4.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/README.md CHANGED
@@ -162,7 +162,7 @@ Some further examples:
162
162
  - [Input demo](https://aberdeenjs.org/examples/input/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/input)
163
163
  - [Tic Tac Toe demo](https://aberdeenjs.org/examples/tictactoe/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/tictactoe)
164
164
  - [List demo](https://aberdeenjs.org/examples/list/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/list)
165
- - [Routing demo](https://aberdeenjs.org/examples/router/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/router)
165
+ - [Routing demo](https://aberdeenjs.org/examples/route/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/route)
166
166
  - [JS Framework Benchmark demo](https://aberdeenjs.org/examples/js-framework-benchmark/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/js-framework-benchmark)
167
167
 
168
168
  ## Learning Aberdeen
@@ -172,7 +172,42 @@ Some further examples:
172
172
 
173
173
  And you may want to study the examples above, of course!
174
174
 
175
+
176
+ ## AI Integration
177
+
178
+ If you use Claude Code, GitHub Copilot or another AI agents that supports Skills, Aberdeen includes a `skill/` directory that provides specialized knowledge to the AI about how to use the library effectively.
179
+
180
+ To use this, it is recommended to symlink the skill into your project's `.claude/skills` directory:
181
+
182
+ ```bash
183
+ mkdir -p .claude/skills
184
+ ln -s ../../node_modules/aberdeen/skill .claude/skills/aberdeen
185
+ ```
186
+
187
+
175
188
  ## Changelog
189
+ ### 1.4.1 (2026-01-14)
190
+
191
+ **Additions:**
192
+ - Created an AI agent Skill (Claude Code, GitHub Copilot) for using Aberdeen in your projects.
193
+
194
+ **Enhancements:**
195
+ - The `html-to-aberdeen` tool now automatically converts `style` attributes to Aberdeen's CSS shortcuts (like `mt:10px` for `margin-top: 10px`) and uses the modern `#text` syntax.
196
+
197
+ **Fixes:**
198
+ - Fixed an issue in `docs/live-code.js` where it was still trying to import the removed `observe` function.
199
+
200
+ ### 1.4.0 (2025-01-07)
201
+
202
+ **Enhancements:**
203
+ - Shortcuts for common CSS properties. For instance: `$('div mv:10px')` for setting vertical (top and bottom) margins.
204
+ - Variables you can set and use in CSS styles, e.g. `$('div bg:@myColor')` after setting `cssVars.myColor = 'red'`.
205
+ - Default CSS variables are defined for spacing: `@2` is `0.5rem`, `@3` is `1rem`, etc. For example: `$('r:@3')` sets border radius to (a dynamically configurable) `1rem`.
206
+ - All CSS shortcuts and `@` variables are also supported in `insertCss` and `insertGlobalCss`.
207
+ - Added `insertGlobalCss` for adding global styles. The `global` argument to `insertCss` is now deprecated.
208
+
209
+ **Fixes:**
210
+ - When doing `$('div #first', () => $('#second'))`, *second* now comes after *first*. It used to be the other way around.
176
211
 
177
212
  ### 1.3.2 (2025-01-07)
178
213
 
@@ -251,6 +251,21 @@ export declare function merge<T extends object>(dst: T, dstKey: keyof T, value:
251
251
  * be observed for changes.
252
252
  */
253
253
  export declare const NO_COPY: unique symbol;
254
+ /**
255
+ * CSS variable lookup table for the `@` value prefix.
256
+ *
257
+ * When a CSS value starts with `@`, the rest is used as a key to look up the actual value.
258
+ * Pre-initialized with keys '1'-'12' mapping to an exponential rem scale (e.g., @1=0.25rem, @3=1rem).
259
+ *
260
+ * @example
261
+ * ```typescript
262
+ * cssVars.primary = '#3b82f6';
263
+ * cssVars[3] = '16px'; // Override @3 to be 16px instead of 1rem
264
+ * $('p color:@primary'); // Sets color to #3b82f6
265
+ * $('div mt:@3'); // Sets margin-top to 16px
266
+ * ```
267
+ */
268
+ export declare const cssVars: Record<string, string>;
254
269
  /**
255
270
  * Clone an (optionally proxied) object or array.
256
271
  *
@@ -392,7 +407,7 @@ export declare function ref<T extends TargetType, K extends keyof T>(target: T,
392
407
  */
393
408
  export declare function $(...args: any[]): undefined | Element;
394
409
  /**
395
- * Inserts CSS rules into the document, optionally scoping them with a unique class name.
410
+ * Inserts CSS rules into the document, scoping them with a unique class name.
396
411
  *
397
412
  * Takes a JavaScript object representation of CSS rules. camelCased property keys are
398
413
  * converted to kebab-case (e.g., `fontSize` becomes `font-size`).
@@ -403,11 +418,9 @@ export declare function $(...args: any[]): undefined | Element;
403
418
  * - In case a selector contains a `&`, that character will be replaced by the parent selector.
404
419
  * - Selectors will be split on `,` characters, each combining with the parent selector with *or* semantics.
405
420
  * - Selector starting with `'@'` define at-rules like media queries. They may be nested within regular selectors.
406
- * @param global - If `true`, styles are inserted globally without prefixing.
407
- * If `false` (default), all selectors are prefixed with a unique generated
408
- * class name (e.g., `.AbdStl1`) to scope the styles.
409
- * @returns The unique class name prefix used for scoping (e.g., `.AbdStl1`), or an empty string
410
- * if `global` was `true`. Use this prefix with {@link $} to apply the styles.
421
+ * @param global - @deprecated Use {@link insertGlobalCss} instead.
422
+ * @returns The unique class name prefix used for scoping (e.g., `.AbdStl1`). Use this
423
+ * prefix with {@link $} to apply the styles.
411
424
  *
412
425
  * @example Scoped Styles
413
426
  * ```typescript
@@ -432,23 +445,30 @@ export declare function $(...args: any[]): undefined | Element;
432
445
  * $('div.child-element#Child'); // .AbdStl1 .child-element rule applies
433
446
  * });
434
447
  * ```
448
+ */
449
+ export declare function insertCss(style: object, global?: boolean): string;
450
+ /**
451
+ * Inserts CSS rules globally.
452
+ *
453
+ * Works exactly like {@link insertCss}, but without prefixing selectors with a unique class name.
435
454
  *
436
455
  * @example Global Styles
437
456
  * ```typescript
438
- * insertCss({
457
+ * insertGlobalCss({
439
458
  * '*': {
440
459
  * fontFamily: 'monospace',
460
+ * m: 0, // Using shortcut for margin
441
461
  * },
442
462
  * 'a': {
443
463
  * textDecoration: 'none',
444
- * color: "#107ab0",
464
+ * fg: "@primary", // Using foreground shortcut and CSS variable
445
465
  * }
446
- * }, true); // Pass true for global
466
+ * });
447
467
  *
448
468
  * $('a#Styled link');
449
469
  * ```
450
470
  */
451
- export declare function insertCss(style: object, global?: boolean): string;
471
+ export declare function insertGlobalCss(style: object): string;
452
472
  /**
453
473
  * Sets a custom error handler function for errors that occur asynchronously
454
474
  * within reactive scopes (e.g., during updates triggered by proxy changes in
package/dist/aberdeen.js CHANGED
@@ -224,6 +224,8 @@ class ChainedScope extends ContentScope {
224
224
  if (el === currentScope.el) {
225
225
  this.prevSibling = currentScope.getChildPrevSibling();
226
226
  currentScope.lastChild = this;
227
+ } else {
228
+ this.prevSibling = el.lastChild || undefined;
227
229
  }
228
230
  if (!useParentCleaners)
229
231
  currentScope.cleaners.push(this);
@@ -1061,6 +1063,10 @@ var COPY_SUBSCRIBE = 32;
1061
1063
  var COPY_EMIT = 64;
1062
1064
  var NO_COPY = Symbol("NO_COPY");
1063
1065
  Promise.prototype[NO_COPY] = true;
1066
+ var cssVars = optProxy({});
1067
+ for (let i = 1;i <= 12; i++) {
1068
+ cssVars[i] = 2 ** (i - 3) + "rem";
1069
+ }
1064
1070
  function clone(src) {
1065
1071
  if (NO_COPY in src)
1066
1072
  return src;
@@ -1260,6 +1266,30 @@ function insertCss(style, global = false) {
1260
1266
  $(`style#${css}`);
1261
1267
  return prefix;
1262
1268
  }
1269
+ function insertGlobalCss(style) {
1270
+ return insertCss(style, true);
1271
+ }
1272
+ var CSS_SHORT = {
1273
+ m: "margin",
1274
+ mt: "marginTop",
1275
+ mb: "marginBottom",
1276
+ ml: "marginLeft",
1277
+ mr: "marginRight",
1278
+ mh: ["marginLeft", "marginRight"],
1279
+ mv: ["marginTop", "marginBottom"],
1280
+ p: "padding",
1281
+ pt: "paddingTop",
1282
+ pb: "paddingBottom",
1283
+ pl: "paddingLeft",
1284
+ pr: "paddingRight",
1285
+ ph: ["paddingLeft", "paddingRight"],
1286
+ pv: ["paddingTop", "paddingBottom"],
1287
+ w: "width",
1288
+ h: "height",
1289
+ bg: "background",
1290
+ fg: "color",
1291
+ r: "borderRadius"
1292
+ };
1263
1293
  function styleToCss(style, prefix) {
1264
1294
  let props = "";
1265
1295
  let rules = "";
@@ -1275,7 +1305,11 @@ ${styleToCss(v, prefix)}}
1275
1305
  rules += styleToCss(v, k.includes("&") ? k.replace(/&/g, prefix) : `${prefix} ${k}`);
1276
1306
  }
1277
1307
  } else {
1278
- props += `${k.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}:${v};`;
1308
+ const val = v == null || v === false ? "" : typeof v === "string" ? v[0] === "@" ? cssVars[v.substring(1)] || "" : v : String(v);
1309
+ const expanded = CSS_SHORT[k] || k;
1310
+ for (const prop of Array.isArray(expanded) ? expanded : [expanded]) {
1311
+ props += `${prop.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}:${val};`;
1312
+ }
1279
1313
  }
1280
1314
  }
1281
1315
  }
@@ -1298,11 +1332,15 @@ function applyArg(el, key, value) {
1298
1332
  else
1299
1333
  el.classList.remove(...classes);
1300
1334
  } else if (key[0] === "$") {
1301
- const name = key.substring(1);
1302
- if (value == null || value === false)
1303
- el.style[name] = "";
1304
- else
1305
- el.style[name] = `${value}`;
1335
+ key = key.substring(1);
1336
+ const val = value == null || value === false ? "" : typeof value === "string" ? value[0] === "@" ? cssVars[value.substring(1)] || "" : value : String(value);
1337
+ const expanded = CSS_SHORT[key] || key;
1338
+ if (typeof expanded === "string") {
1339
+ el.style[expanded] = val;
1340
+ } else {
1341
+ for (const prop of expanded)
1342
+ el.style[prop] = val;
1343
+ }
1306
1344
  } else if (value == null) {} else if (key in SPECIAL_PROPS) {
1307
1345
  SPECIAL_PROPS[key](el, value);
1308
1346
  } else if (typeof value === "function") {
@@ -1482,11 +1520,13 @@ export {
1482
1520
  leakScope,
1483
1521
  isEmpty,
1484
1522
  invertString,
1523
+ insertGlobalCss,
1485
1524
  insertCss,
1486
1525
  getParentElement,
1487
1526
  dump,
1488
1527
  derive,
1489
1528
  defaultEmitHandler,
1529
+ cssVars,
1490
1530
  count,
1491
1531
  copy,
1492
1532
  clone,
@@ -1495,5 +1535,5 @@ export {
1495
1535
  $
1496
1536
  };
1497
1537
 
1498
- //# debugId=FE7EA671EAA8B7E164756E2164756E21
1538
+ //# debugId=BD37C20F6280CE8164756E2164756E21
1499
1539
  //# sourceMappingURL=aberdeen.js.map