aberdeen 1.4.3 → 1.5.0

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": "1.4.3",
3
+ "version": "1.5.0",
4
4
  "author": "Frank van Viegen",
5
5
  "main": "dist-min/aberdeen.js",
6
6
  "devDependencies": {
package/skill/SKILL.md CHANGED
@@ -78,18 +78,23 @@ $('button', { click: handler, '.active': isActive });
78
78
  | `r` | borderRadius | | |
79
79
 
80
80
  ### CSS Variables (`@`)
81
- Values starting with `@` reference `cssVars`. Predefined spacing scale:
82
- | Var | Value | Var | Value |
83
- |-----|-------|-----|-------|
84
- | `@1` | 0.25rem | `@4` | 2rem |
85
- | `@2` | 0.5rem | `@5` | 4rem |
86
- | `@3` | 1rem | `@n` | 2^(n-3) rem |
81
+ Values starting with `@` expand to native CSS custom properties via `var(--name)`. Numeric keys are prefixed with `m` (e.g., `@3` → `var(--m3)`).
82
+
83
+ Predefined spacing scale:
84
+ | Var | CSS Output | Value |
85
+ |-----|------------|-------|
86
+ | `@1` | `var(--m1)` | 0.25rem |
87
+ | `@2` | `var(--m2)` | 0.5rem |
88
+ | `@3` | `var(--m3)` | 1rem |
89
+ | `@4` | `var(--m4)` | 2rem |
90
+ | `@5` | `var(--m5)` | 4rem |
91
+ | `@n` | `var(--mn)` | 2^(n-3) rem |
87
92
 
88
93
  **Best practice:** Use `@3` and `@4` for most margins/paddings. For new projects, define color variables:
89
94
  ```typescript
90
95
  cssVars.primary = '#3b82f6';
91
96
  cssVars.danger = '#ef4444';
92
- $('button bg:@primary fg:white#Save');
97
+ $('button bg:@primary fg:white#Save'); // outputs: background: var(--primary); color: white
93
98
  ```
94
99
 
95
100
  ## Reactive State: `proxy()`
package/src/aberdeen.ts CHANGED
@@ -1704,17 +1704,20 @@ export const NO_COPY = Symbol("NO_COPY");
1704
1704
  (Promise.prototype as any)[NO_COPY] = true;
1705
1705
 
1706
1706
  /**
1707
- * CSS variable lookup table for the `@` value prefix.
1707
+ * CSS variables that are output as native CSS custom properties.
1708
1708
  *
1709
- * When a CSS value starts with `@`, the rest is used as a key to look up the actual value.
1709
+ * When a CSS value starts with `@`, it becomes `var(--name)` (or `var(--mN)` for numeric keys).
1710
1710
  * Pre-initialized with keys '1'-'12' mapping to an exponential rem scale (e.g., @1=0.25rem, @3=1rem).
1711
1711
  *
1712
+ * Changes to cssVars are automatically reflected in a `<style>` tag in `<head>`, making updates
1713
+ * reactive across all elements using those variables.
1714
+ *
1712
1715
  * @example
1713
1716
  * ```typescript
1714
1717
  * cssVars.primary = '#3b82f6';
1715
1718
  * cssVars[3] = '16px'; // Override @3 to be 16px instead of 1rem
1716
- * $('p color:@primary'); // Sets color to #3b82f6
1717
- * $('div mt:@3'); // Sets margin-top to 16px
1719
+ * $('p color:@primary'); // Sets color to var(--primary)
1720
+ * $('div mt:@3'); // Sets margin-top to var(--m3)
1718
1721
  * ```
1719
1722
  */
1720
1723
  export const cssVars: Record<string, string> = optProxy({});
@@ -1723,6 +1726,13 @@ for (let i = 1; i <= 12; i++) {
1723
1726
  cssVars[i] = 2 ** (i - 3) + "rem";
1724
1727
  }
1725
1728
 
1729
+ const DIGIT_FIRST = /^\d/;
1730
+ function cssVarRef(name: string): string {
1731
+ // Prefix numeric keys with 'm' (CSS custom property names can't start with a digit)
1732
+ const varName = DIGIT_FIRST.test(name) ? `m${name}` : name;
1733
+ return `var(--${varName})`;
1734
+ }
1735
+
1726
1736
  /**
1727
1737
  * Clone an (optionally proxied) object or array.
1728
1738
  *
@@ -2178,7 +2188,7 @@ function styleToCss(style: object, prefix: string): string {
2178
2188
  );
2179
2189
  }
2180
2190
  } else {
2181
- const val = v == null || v === false ? "" : typeof v === 'string' ? (v[0] === '@' ? (cssVars as any)[v.substring(1)] || "" : v) : String(v);
2191
+ const val = v == null || v === false ? "" : typeof v === 'string' ? (v[0] === '@' ? cssVarRef(v.substring(1)) : v) : String(v);
2182
2192
  const expanded = CSS_SHORT[k] || k;
2183
2193
  for (const prop of (Array.isArray(expanded) ? expanded : [expanded])) {
2184
2194
  props += `${prop.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}:${val};`;
@@ -2207,7 +2217,7 @@ function applyArg(el: Element, key: string, value: any) {
2207
2217
  } else if (key[0] === "$") {
2208
2218
  // Style (with shortcuts)
2209
2219
  key = key.substring(1);
2210
- const val = value == null || value === false ? "" : typeof value === 'string' ? (value[0] === '@' ? (cssVars as any)[value.substring(1)] || "" : value) : String(value);
2220
+ const val = value == null || value === false ? "" : typeof value === 'string' ? (value[0] === '@' ? cssVarRef(value.substring(1)) : value) : String(value);
2211
2221
  const expanded = CSS_SHORT[key] || key;
2212
2222
  if (typeof expanded === "string") {
2213
2223
  (el as any).style[expanded] = val;
@@ -2903,3 +2913,21 @@ export function withEmitHandler(
2903
2913
  emit = oldEmitHandler;
2904
2914
  }
2905
2915
  }
2916
+
2917
+ // Initialize the cssVars style tag in document.head
2918
+ // This runs at module load time, after all functions are defined
2919
+ if (typeof document !== "undefined") {
2920
+ leakScope(() => {
2921
+ mount(document.head, () => {
2922
+ $('style', () => {
2923
+ let css = ":root {\n";
2924
+ for(const [key, value] of Object.entries(cssVars)) {
2925
+ const varName = DIGIT_FIRST.test(String(key)) ? `m${key}` : key;
2926
+ css += ` --${varName}: ${value};\n`;
2927
+ }
2928
+ css += "}";
2929
+ $(`#${css}`);
2930
+ })
2931
+ });
2932
+ });
2933
+ }