@homebound/truss 2.20.1 → 2.21.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/build/index.js CHANGED
@@ -1054,7 +1054,7 @@ class CssBuilder<T extends Properties> {
1054
1054
 
1055
1055
  ${lines.join("\n ").replace(/ +\n/g, "\n")}
1056
1056
 
1057
- get $(): T { maybeImportant(sortObject(this.rules), this.opts.important); }
1057
+ get $(): T { return maybeImportant(sortObject(this.rules), this.opts.important); }
1058
1058
 
1059
1059
  if(bp: Breakpoint): CssBuilder<T>;
1060
1060
  if(cond: boolean): CssBuilder<T>;
@@ -1289,23 +1289,42 @@ function generateStylexCssBuilder(config, sections) {
1289
1289
  // See your project's \`truss-config.ts\` to make configuration changes (fonts, increments, etc).
1290
1290
  // Target: native (build-time plugin)
1291
1291
 
1292
- import { trussProps } from "@homebound/truss/runtime";
1293
- export { RuntimeStyle, useRuntimeStyle } from "@homebound/truss/runtime";
1292
+ import { trussProps, useRuntimeStyle as _useRuntimeStyle } from "@homebound/truss/runtime";
1294
1293
 
1295
1294
  /** Given a type X, and the user's proposed type T, only allow keys in X and nothing else. */
1296
- export type Only<X, T> = X & Record<Exclude<keyof T, keyof X>, never>;
1295
+ export type Only<X, T> = X & Record<Exclude<keyof T, keyof X | "__kind">, never>;
1297
1296
 
1298
1297
  type UnionToIntersection<U> = (U extends unknown ? (value: U) => void : never) extends (value: infer I) => void
1299
1298
  ? I
1300
1299
  : never;
1301
1300
 
1302
- export type ${def("Properties")} = ${CssProperties}<string | 0, string>;
1301
+ /** Raw CSS properties from csstype, without any style-kind brand. */
1302
+ type RawCssProperties = ${CssProperties}<string | 0, string>;
1303
+
1304
+ /**
1305
+ * CSS properties with an optional buildtime brand.
1306
+ *
1307
+ * \`Properties\` is the standard type for passing CSS style objects around.
1308
+ * It carries an optional \`__kind\` discriminator so that \`RuntimeStyles\`
1309
+ * (which has \`__kind: "runtime"\`) is rejected when assigned to a
1310
+ * \`Properties\` slot like the \`css=\` prop.
1311
+ */
1312
+ export type ${def("Properties")} = RawCssProperties & { readonly __kind?: "buildtime" };
1303
1313
 
1304
1314
  export type ${def("InlineStyle")} = Record<string, string | number | undefined>;
1305
1315
 
1306
1316
  /** A marker token used with \`when\`/\`markerOf\` etc. */
1307
1317
  export type Marker = symbol;
1308
1318
 
1319
+ /** Discriminates between build-time and runtime Css expressions. */
1320
+ export type StyleKind = "buildtime" | "runtime";
1321
+
1322
+ /** The result of \`Css.*.$\` — for use in \`css=\` props (transformed at build time). */
1323
+ export type ${def("BuildtimeStyles")} = RawCssProperties & { readonly __kind: "buildtime" };
1324
+
1325
+ /** The result of \`RuntimeCss.*.$\` — for use in \`useRuntimeStyle\`. */
1326
+ export type ${def("RuntimeStyles")} = RawCssProperties & { readonly __kind: "runtime" };
1327
+
1309
1328
  ${typographyType}
1310
1329
 
1311
1330
  // Augment React types so all JSX elements accept the \`css\` prop:
@@ -1333,12 +1352,12 @@ type Opts<T> = {
1333
1352
  runtimeError: string | undefined;
1334
1353
  };
1335
1354
 
1336
- class CssBuilder<T extends Properties> {
1355
+ class CssBuilder<T extends Properties, S extends StyleKind = "buildtime"> {
1337
1356
  constructor(private opts: Opts<T>) {}
1338
1357
 
1339
1358
  ${lines.join("\n ").replace(/ +\n/g, "\n")}
1340
1359
 
1341
- get $(): T {
1360
+ get $(): T & { readonly __kind: S } {
1342
1361
  if (this.opts.runtimeError) {
1343
1362
  throw new Error(this.opts.runtimeError);
1344
1363
  }
@@ -1374,12 +1393,12 @@ class CssBuilder<T extends Properties> {
1374
1393
  }
1375
1394
 
1376
1395
  /** Marks this element as a default hover marker (for ancestor pseudo selectors). */
1377
- get marker(): CssBuilder<T> {
1396
+ get marker(): CssBuilder<T, S> {
1378
1397
  return this.unsupportedRuntime("marker cannot be used in RuntimeStyle css expressions.");
1379
1398
  }
1380
1399
 
1381
1400
  /** Marks this element with a user-defined marker. */
1382
- markerOf(_marker: Marker): CssBuilder<T> {
1401
+ markerOf(_marker: Marker): CssBuilder<T, S> {
1383
1402
  return this.unsupportedRuntime("markerOf() cannot be used in RuntimeStyle css expressions.");
1384
1403
  }
1385
1404
 
@@ -1388,7 +1407,7 @@ class CssBuilder<T extends Properties> {
1388
1407
  return Symbol("truss-marker");
1389
1408
  }
1390
1409
 
1391
- typography(key: Typography): CssBuilder<T> {
1410
+ typography(key: Typography): CssBuilder<T, S> {
1392
1411
  return (this as any)[key];
1393
1412
  }
1394
1413
 
@@ -1398,25 +1417,25 @@ class CssBuilder<T extends Properties> {
1398
1417
  * \`when(\":hover\")\` — same semantics as \`onHover\`
1399
1418
  * \`when(\":hover:not(:disabled)\")\` — hover only while enabled
1400
1419
  */
1401
- when(selector: string): CssBuilder<T>;
1420
+ when(selector: string): CssBuilder<T, S>;
1402
1421
  /**
1403
1422
  * Styles after this \`when\` are applied based on a marker relationship + pseudo selector.
1404
1423
  *
1405
1424
  * \`when(marker, "ancestor", ":hover")\` — react to marker ancestor hover
1406
1425
  * \`when(row, "descendant", ":focus")\` — react to a marked descendant focus
1407
1426
  */
1408
- when(marker: Marker, relationship: "ancestor" | "descendant" | "anySibling" | "siblingBefore" | "siblingAfter", pseudo: string): CssBuilder<T>;
1427
+ when(marker: Marker, relationship: "ancestor" | "descendant" | "anySibling" | "siblingBefore" | "siblingAfter", pseudo: string): CssBuilder<T, S>;
1409
1428
  /**
1410
1429
  * Apply different styles for each selector in the object.
1411
1430
  *
1412
1431
  * \`when({ ":hover": Css.blue.$, ":focus": Css.red.$ })\`
1413
1432
  */
1414
- when<W extends Record<string, Properties>>(selectors: W): CssBuilder<T & UnionToIntersection<W[keyof W]>>;
1433
+ when<W extends Record<string, Properties>>(selectors: W): CssBuilder<T & UnionToIntersection<W[keyof W]>, S>;
1415
1434
  when(
1416
1435
  _selectorOrMarker: string | Marker | Record<string, Properties>,
1417
1436
  _relationship?: string,
1418
1437
  _pseudo?: string,
1419
- ): CssBuilder<T> {
1438
+ ): CssBuilder<T, S> {
1420
1439
  return this.unsupportedRuntime("when() cannot be used in RuntimeStyle css expressions.");
1421
1440
  }
1422
1441
 
@@ -1425,24 +1444,24 @@ class CssBuilder<T extends Properties> {
1425
1444
  }
1426
1445
 
1427
1446
  /** Apply styles within a pseudo-element (e.g. \`"::placeholder"\`, \`"::selection"\`). */
1428
- element(_pseudoElement: string): CssBuilder<T> {
1447
+ element(_pseudoElement: string): CssBuilder<T, S> {
1429
1448
  return this.unsupportedRuntime("element() cannot be used in RuntimeStyle css expressions.");
1430
1449
  }
1431
1450
 
1432
1451
  ${breakpointIfs}
1433
1452
 
1434
1453
  /** Conditionally apply styles when \`cond\` is true. */
1435
- if(cond: boolean): CssBuilder<T>;
1454
+ if(cond: boolean): CssBuilder<T, S>;
1436
1455
  /** Apply styles within a media query (e.g. \`Breakpoints.sm\` or a raw \`@media\` string). */
1437
- if(mediaQuery: string): CssBuilder<T>;
1438
- if(condOrMediaQuery: boolean | string): CssBuilder<T> {
1456
+ if(mediaQuery: string): CssBuilder<T, S>;
1457
+ if(condOrMediaQuery: boolean | string): CssBuilder<T, S> {
1439
1458
  if (typeof condOrMediaQuery === "boolean") {
1440
- return new CssBuilder({ ...this.opts, enabled: condOrMediaQuery, elseApplied: false });
1459
+ return new CssBuilder({ ...this.opts, enabled: condOrMediaQuery, elseApplied: false }) as CssBuilder<T, S>;
1441
1460
  }
1442
1461
  return this.unsupportedRuntime("if(mediaQuery) cannot be used in RuntimeStyle css expressions.");
1443
1462
  }
1444
1463
 
1445
- get else(): CssBuilder<T> {
1464
+ get else(): CssBuilder<T, S> {
1446
1465
  if (this.selector !== undefined) {
1447
1466
  if (this.opts.elseApplied) {
1448
1467
  throw new Error("else was already called");
@@ -1452,18 +1471,18 @@ class CssBuilder<T extends Properties> {
1452
1471
  if (this.opts.elseApplied) {
1453
1472
  throw new Error("else was already called");
1454
1473
  }
1455
- return new CssBuilder({ ...this.opts, enabled: !this.enabled, elseApplied: true });
1474
+ return new CssBuilder({ ...this.opts, enabled: !this.enabled, elseApplied: true }) as CssBuilder<T, S>;
1456
1475
  }
1457
1476
 
1458
1477
  /** Reset active conditional modifiers for subsequent styles. */
1459
- get end(): CssBuilder<T> {
1478
+ get end(): CssBuilder<T, S> {
1460
1479
  return this.newCss({ selector: undefined, elseApplied: false });
1461
1480
  }
1462
1481
 
1463
1482
  /** Add real CSS property/value pairs, either as add("prop", value) or add({ prop: value, ... }). */
1464
- add<P extends Properties>(props: P): CssBuilder<T & P>;
1465
- add<K extends keyof Properties>(prop: K, value: Properties[K]): CssBuilder<T & { [U in K]: Properties[K] }>;
1466
- add<K extends keyof Properties>(propOrStyles: K | Properties, value?: Properties[K]): CssBuilder<any> {
1483
+ add<P extends Properties>(props: P): CssBuilder<T & P, S>;
1484
+ add<K extends keyof Properties>(prop: K, value: Properties[K]): CssBuilder<T & { [U in K]: Properties[K] }, S>;
1485
+ add<K extends keyof Properties>(propOrStyles: K | Properties, value?: Properties[K]): CssBuilder<any, S> {
1467
1486
  if (!this.enabled) return this;
1468
1487
 
1469
1488
  const newRules = typeof propOrStyles === "string" ? { [propOrStyles]: value } : propOrStyles;
@@ -1477,8 +1496,8 @@ class CssBuilder<T extends Properties> {
1477
1496
  }
1478
1497
 
1479
1498
  /** Compose an existing Css expression or partial style hash into this builder, skipping undefined values. */
1480
- with<P extends Properties>(cssProp: P): CssBuilder<T & P>;
1481
- with(cssProp: Properties): CssBuilder<any> {
1499
+ with<P extends Properties>(cssProp: P): CssBuilder<T & P, S>;
1500
+ with(cssProp: Properties): CssBuilder<any, S> {
1482
1501
  if (!this.enabled) return this;
1483
1502
  const { $css, ...rest } = cssProp as any;
1484
1503
  const filtered = omitUndefinedValues(rest);
@@ -1490,13 +1509,13 @@ class CssBuilder<T extends Properties> {
1490
1509
 
1491
1510
 
1492
1511
  /** Marker for the build-time transform to append a raw className. */
1493
- className(className: string | undefined): CssBuilder<T> {
1512
+ className(className: string | undefined): CssBuilder<T, S> {
1494
1513
  void className;
1495
1514
  return this.unsupportedRuntime("className() cannot be used in RuntimeStyle css expressions.");
1496
1515
  }
1497
1516
 
1498
1517
  /** Marker for the build-time transform to append raw inline styles. */
1499
- style(inlineStyle: InlineStyle): CssBuilder<T> {
1518
+ style(inlineStyle: InlineStyle): CssBuilder<T, S> {
1500
1519
  void inlineStyle;
1501
1520
  return this.unsupportedRuntime("style() cannot be used in RuntimeStyle css expressions.");
1502
1521
  }
@@ -1520,11 +1539,11 @@ class CssBuilder<T extends Properties> {
1520
1539
  private get selector(): string | undefined {
1521
1540
  return this.opts.selector;
1522
1541
  }
1523
- private unsupportedRuntime(message: string): CssBuilder<T> {
1542
+ private unsupportedRuntime(message: string): CssBuilder<T, S> {
1524
1543
  return this.newCss({ runtimeError: message });
1525
1544
  }
1526
- private newCss(opts: Partial<Opts<T>>): CssBuilder<T> {
1527
- return new CssBuilder({ ...this.opts, ...opts });
1545
+ private newCss(opts: Partial<Opts<T>>): CssBuilder<T, S> {
1546
+ return new CssBuilder({ ...this.opts, ...opts }) as CssBuilder<T, S>;
1528
1547
  }
1529
1548
  }
1530
1549
 
@@ -1562,8 +1581,8 @@ export type Xss<P extends keyof Properties> = Pick<Properties, P>;
1562
1581
  /** The shared marker token for \`when(marker, relationship, pseudo)\`. */
1563
1582
  export const marker: Marker = Symbol.for("truss-default-marker");
1564
1583
 
1565
- /** An entry point for Css expressions. CssBuilder is immutable so this is safe to share. */
1566
- export const Css = new CssBuilder({
1584
+ /** An entry point for build-time Css expressions. Use with \`css=\` props. */
1585
+ export const Css = new CssBuilder<{}, "buildtime">({
1567
1586
  rules: {},
1568
1587
  enabled: true,
1569
1588
  selector: undefined,
@@ -1571,6 +1590,20 @@ export const Css = new CssBuilder({
1571
1590
  runtimeError: undefined,
1572
1591
  });
1573
1592
 
1593
+ /** An entry point for runtime Css expressions. Use with \`useRuntimeStyle\`. */
1594
+ export const ${def("RuntimeCss")} = new CssBuilder<{}, "runtime">({
1595
+ rules: {},
1596
+ enabled: true,
1597
+ selector: undefined,
1598
+ elseApplied: false,
1599
+ runtimeError: undefined,
1600
+ });
1601
+
1602
+ /** Hook that injects dynamic CSS at runtime. Only accepts \`RuntimeCss.*.$\` expressions. */
1603
+ export function ${def("useRuntimeStyle")}(css: Record<string, RuntimeStyles | string>): void {
1604
+ _useRuntimeStyle(css as any);
1605
+ }
1606
+
1574
1607
  ${typeAliasCode}
1575
1608
 
1576
1609
  ${breakpointCode}