aberdeen 1.4.3 → 1.6.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.
@@ -252,20 +252,85 @@ export declare function merge<T extends object>(dst: T, dstKey: keyof T, value:
252
252
  */
253
253
  export declare const NO_COPY: unique symbol;
254
254
  /**
255
- * CSS variable lookup table for the `@` value prefix.
255
+ * A reactive object containing CSS variable definitions.
256
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).
257
+ * Any property you assign to `cssVars` becomes available as a CSS custom property throughout your application.
258
+ *
259
+ * Use {@link setSpacingCssVars} to optionally initialize `cssVars[1]` through `cssVars[12]` with an exponential spacing scale.
260
+ *
261
+ * When you reference a CSS variable in Aberdeen using the `$` prefix (e.g., `$primary`), it automatically resolves to `var(--primary)`.
262
+ * For numeric keys (which can't be used directly as CSS custom property names), Aberdeen prefixes them with `m` (e.g., `$3` becomes `var(--m3)`).
263
+ *
264
+ * When you add the first property to cssVars, Aberdeen automatically creates a reactive `<style>` tag in `<head>`
265
+ * containing the `:root` CSS custom property declarations. The style tag is automatically removed if cssVars becomes empty.
259
266
  *
260
267
  * @example
261
- * ```typescript
268
+ * ```javascript
269
+ * import { cssVars, setSpacingCssVars, $ } from 'aberdeen';
270
+ *
271
+ * // Optionally initialize spacing scale
272
+ * setSpacingCssVars(); // Uses defaults: base=1, unit='rem'
273
+ *
274
+ * // Define custom colors - style tag is automatically created
262
275
  * 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
276
+ * cssVars.danger = '#ef4444';
277
+ *
278
+ * // Use in elements with the $ prefix
279
+ * $('button bg:$primary fg:white');
280
+ *
281
+ * // Use spacing (if setSpacingCssVars() was called)
282
+ * $('div mt:$3'); // Sets margin-top to var(--m3)
266
283
  * ```
267
284
  */
268
285
  export declare const cssVars: Record<string, string>;
286
+ /**
287
+ * Initializes `cssVars[1]` through `cssVars[12]` with an exponential spacing scale.
288
+ *
289
+ * The scale is calculated as `2^(n-3) * base`, providing values from `0.25 * base` to `512 * base`.
290
+ *
291
+ * @param base - The base size for the spacing scale (default: 1). If unit is 'rem' or 'em', this is in that unit. If unit is 'px', this is the pixel value.
292
+ * @param unit - The CSS unit to use (default: 'rem'). Can be 'rem', 'em', 'px', or any other valid CSS unit.
293
+ *
294
+ * @example
295
+ * ```javascript
296
+ * // Use default scale (0.25rem to 512rem)
297
+ * setSpacingCssVars();
298
+ *
299
+ * // Use custom base size
300
+ * setSpacingCssVars(16, 'px'); // 4px to 8192px
301
+ *
302
+ * // Use em units
303
+ * setSpacingCssVars(1, 'em'); // 0.25em to 512em
304
+ * ```
305
+ */
306
+ export declare function setSpacingCssVars(base?: number, unit?: string): void;
307
+ /**
308
+ * Returns whether the user's browser prefers a dark color scheme.
309
+ *
310
+ * This function is reactive - scopes that call it will re-execute when the
311
+ * browser's color scheme preference changes (via the `prefers-color-scheme` media query).
312
+ *
313
+ * Use this in combination with {@link $} and {@link cssVars} to implement theme switching:
314
+ *
315
+ * @returns `true` if the browser prefers dark mode, `false` if it prefers light mode.
316
+ *
317
+ * @example
318
+ * ```javascript
319
+ * import { darkMode, cssVars, $, mount } from 'aberdeen';
320
+ *
321
+ * // Reactively set colors based on browser preference
322
+ * $(() => {
323
+ * if (darkMode()) { // Optionally override this with user settings
324
+ * cssVars.bg = '#1a1a1a';
325
+ * cssVars.fg = '#e5e5e5';
326
+ * } else {
327
+ * cssVars.bg = '#ffffff';
328
+ * cssVars.fg = '#000000';
329
+ * }
330
+ * });
331
+ * ```
332
+ */
333
+ export declare function darkMode(): boolean;
269
334
  /**
270
335
  * Clone an (optionally proxied) object or array.
271
336
  *
package/dist/aberdeen.js CHANGED
@@ -1017,7 +1017,7 @@ function copyRecursive(dst, src, flags) {
1017
1017
  const old = dst.get(k);
1018
1018
  dst.delete(k);
1019
1019
  if (flags & COPY_EMIT) {
1020
- emit(dst, k, undefined, old);
1020
+ emit(dst, k, EMPTY, old);
1021
1021
  }
1022
1022
  changed = true;
1023
1023
  }
@@ -1047,7 +1047,7 @@ function copyRecursive(dst, src, flags) {
1047
1047
  const old = dst[k];
1048
1048
  delete dst[k];
1049
1049
  if (flags & COPY_EMIT && old !== undefined) {
1050
- emit(dst, k, undefined, old);
1050
+ emit(dst, k, EMPTY, old);
1051
1051
  }
1052
1052
  changed = true;
1053
1053
  }
@@ -1064,8 +1064,51 @@ var COPY_EMIT = 64;
1064
1064
  var NO_COPY = Symbol("NO_COPY");
1065
1065
  Promise.prototype[NO_COPY] = true;
1066
1066
  var cssVars = optProxy({});
1067
- for (let i = 1;i <= 12; i++) {
1068
- cssVars[i] = 2 ** (i - 3) + "rem";
1067
+ function setSpacingCssVars(base = 1, unit = "rem") {
1068
+ for (let i = 1;i <= 12; i++) {
1069
+ cssVars[i] = 2 ** (i - 3) * base + unit;
1070
+ }
1071
+ }
1072
+ var DIGIT_FIRST = /^\d/;
1073
+ function cssVarRef(name) {
1074
+ const varName = DIGIT_FIRST.test(name) ? `m${name}` : name;
1075
+ return `var(--${varName})`;
1076
+ }
1077
+ if (typeof document !== "undefined") {
1078
+ leakScope(() => {
1079
+ $(() => {
1080
+ if (!isEmpty(cssVars)) {
1081
+ mount(document.head, () => {
1082
+ $("style", () => {
1083
+ let css = `:root {
1084
+ `;
1085
+ for (const [key, value] of Object.entries(cssVars)) {
1086
+ const varName = DIGIT_FIRST.test(String(key)) ? `m${key}` : key;
1087
+ css += ` --${varName}: ${value};
1088
+ `;
1089
+ }
1090
+ css += "}";
1091
+ $(`#${css}`);
1092
+ });
1093
+ });
1094
+ }
1095
+ });
1096
+ });
1097
+ }
1098
+ function darkMode() {
1099
+ if (typeof window === "undefined" || !window.matchMedia)
1100
+ return false;
1101
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1102
+ const changed = proxy(false);
1103
+ changed.value;
1104
+ function onChange() {
1105
+ changed.value = true;
1106
+ }
1107
+ mediaQuery.addEventListener("change", onChange);
1108
+ clean(() => {
1109
+ mediaQuery.removeEventListener("change", onChange);
1110
+ });
1111
+ return mediaQuery.matches;
1069
1112
  }
1070
1113
  function clone(src) {
1071
1114
  if (NO_COPY in src)
@@ -1305,7 +1348,7 @@ ${styleToCss(v, prefix)}}
1305
1348
  rules += styleToCss(v, k.includes("&") ? k.replace(/&/g, prefix) : `${prefix} ${k}`);
1306
1349
  }
1307
1350
  } else {
1308
- const val = v == null || v === false ? "" : typeof v === "string" ? v[0] === "@" ? cssVars[v.substring(1)] || "" : v : String(v);
1351
+ const val = v == null || v === false ? "" : typeof v === "string" ? v[0] === "$" ? cssVarRef(v.substring(1)) : v : String(v);
1309
1352
  const expanded = CSS_SHORT[k] || k;
1310
1353
  for (const prop of Array.isArray(expanded) ? expanded : [expanded]) {
1311
1354
  props += `${prop.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}:${val};`;
@@ -1333,7 +1376,7 @@ function applyArg(el, key, value) {
1333
1376
  el.classList.remove(...classes);
1334
1377
  } else if (key[0] === "$") {
1335
1378
  key = key.substring(1);
1336
- const val = value == null || value === false ? "" : typeof value === "string" ? value[0] === "@" ? cssVars[value.substring(1)] || "" : value : String(value);
1379
+ const val = value == null || value === false ? "" : typeof value === "string" ? value[0] === "$" ? cssVarRef(value.substring(1)) : value : String(value);
1337
1380
  const expanded = CSS_SHORT[key] || key;
1338
1381
  if (typeof expanded === "string") {
1339
1382
  el.style[expanded] = val;
@@ -1506,6 +1549,7 @@ export {
1506
1549
  withEmitHandler,
1507
1550
  unproxy,
1508
1551
  unmountAll,
1552
+ setSpacingCssVars,
1509
1553
  setErrorHandler,
1510
1554
  runQueue,
1511
1555
  ref,
@@ -1526,6 +1570,7 @@ export {
1526
1570
  dump,
1527
1571
  derive,
1528
1572
  defaultEmitHandler,
1573
+ darkMode,
1529
1574
  cssVars,
1530
1575
  count,
1531
1576
  copy,
@@ -1535,5 +1580,5 @@ export {
1535
1580
  $
1536
1581
  };
1537
1582
 
1538
- //# debugId=BD37C20F6280CE8164756E2164756E21
1583
+ //# debugId=30E505D12852725E64756E2164756E21
1539
1584
  //# sourceMappingURL=aberdeen.js.map