@homebound/truss 2.21.4 → 2.21.6
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 +25 -85
- package/build/index.js.map +1 -1
- package/build/plugin/index.d.ts +3 -2
- package/build/plugin/index.js +2686 -2732
- package/build/plugin/index.js.map +1 -1
- package/build/runtime.d.ts +4 -1
- package/build/runtime.js +37 -5
- package/build/runtime.js.map +1 -1
- package/package.json +7 -7
- package/tsconfig.tsbuildinfo +1 -0
- package/tsup.config.ts +5 -1
package/build/index.js
CHANGED
|
@@ -922,6 +922,18 @@ var reactNativeSections = {
|
|
|
922
922
|
spacing: spacing2
|
|
923
923
|
};
|
|
924
924
|
|
|
925
|
+
// src/pseudo-selectors.ts
|
|
926
|
+
var TRUSS_PSEUDO_METHODS = {
|
|
927
|
+
onHover: ":hover",
|
|
928
|
+
onFocus: ":focus",
|
|
929
|
+
onFocusVisible: ":focus-visible",
|
|
930
|
+
onFocusWithin: ":focus-within",
|
|
931
|
+
onActive: ":active",
|
|
932
|
+
onDisabled: ":disabled",
|
|
933
|
+
ifFirstOfType: ":first-of-type",
|
|
934
|
+
ifLastOfType: ":last-of-type"
|
|
935
|
+
};
|
|
936
|
+
|
|
925
937
|
// src/generate.ts
|
|
926
938
|
var CssProperties = imp("Properties@csstype");
|
|
927
939
|
var defaultTypeAliases = {
|
|
@@ -941,13 +953,13 @@ async function generate(config) {
|
|
|
941
953
|
return;
|
|
942
954
|
}
|
|
943
955
|
if (target === "react-native") {
|
|
944
|
-
const output =
|
|
956
|
+
const output = generateReactNativeBuilder(config).toString();
|
|
945
957
|
await fs.writeFile(outputPath, output);
|
|
946
958
|
return;
|
|
947
959
|
}
|
|
948
960
|
throw new Error(`Unsupported truss target "${target}". Use "web" (default) or "react-native".`);
|
|
949
961
|
}
|
|
950
|
-
function
|
|
962
|
+
function generateReactNativeBuilder(config) {
|
|
951
963
|
const { fonts, increment, extras, typeAliases, breakpoints = {}, palette } = config;
|
|
952
964
|
const sections = generateSections(config);
|
|
953
965
|
const lines = Object.entries(sections).map(([name, value]) => [`// ${name}`, ...value, ""]).flat();
|
|
@@ -1015,7 +1027,6 @@ ${typographyType}
|
|
|
1015
1027
|
type Opts<T> = {
|
|
1016
1028
|
rules: T,
|
|
1017
1029
|
enabled: boolean,
|
|
1018
|
-
important: boolean,
|
|
1019
1030
|
selector: string | undefined,
|
|
1020
1031
|
elseApplied: boolean,
|
|
1021
1032
|
};
|
|
@@ -1054,7 +1065,7 @@ class CssBuilder<T extends Properties> {
|
|
|
1054
1065
|
|
|
1055
1066
|
${lines.join("\n ").replace(/ +\n/g, "\n")}
|
|
1056
1067
|
|
|
1057
|
-
get $(): T { return
|
|
1068
|
+
get $(): T { return sortObject(this.rules); }
|
|
1058
1069
|
|
|
1059
1070
|
if(bp: Breakpoint): CssBuilder<T>;
|
|
1060
1071
|
if(cond: boolean): CssBuilder<T>;
|
|
@@ -1111,8 +1122,6 @@ class CssBuilder<T extends Properties> {
|
|
|
1111
1122
|
return this.newCss({ selector: undefined, elseApplied: false });
|
|
1112
1123
|
}
|
|
1113
1124
|
|
|
1114
|
-
get important() { return this.newCss({ important: true }); }
|
|
1115
|
-
|
|
1116
1125
|
/** Add real CSS property/value pairs, either as add("prop", value) or add({ prop: value, ... }). */
|
|
1117
1126
|
add<P extends Properties>(props: P): CssBuilder<T & P>;
|
|
1118
1127
|
add<K extends keyof Properties>(prop: K, value: Properties[K]): CssBuilder<T & { [U in K]: Properties[K] }>;
|
|
@@ -1140,25 +1149,6 @@ class CssBuilder<T extends Properties> {
|
|
|
1140
1149
|
return this.newCss({ rules: rules as any });
|
|
1141
1150
|
}
|
|
1142
1151
|
|
|
1143
|
-
/** Adds new properties, either a specific key/value or a Properties object, to a nested selector. */
|
|
1144
|
-
addIn<P extends Properties>(selector: string, props: P | undefined): CssBuilder<T & P>;
|
|
1145
|
-
addIn<K extends keyof Properties>(selector: string, prop: K, value: Properties[K]): CssBuilder<T & { [U in K]: Properties[K] }>;
|
|
1146
|
-
addIn<K extends keyof Properties>(selector: string, propOrProperties: K | Properties, value?: Properties[K]): CssBuilder<any> {
|
|
1147
|
-
const newRules = typeof propOrProperties === "string" ? { [propOrProperties]: value } : propOrProperties;
|
|
1148
|
-
if (!this.enabled) return this;
|
|
1149
|
-
if (newRules === undefined) {
|
|
1150
|
-
return this;
|
|
1151
|
-
}
|
|
1152
|
-
const rules = { ...this.rules, [selector]: { ...(this.rules as any)[selector], ...newRules } };
|
|
1153
|
-
return this.newCss({ rules: rules as any });
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
/** Marker for the build-time transform to append a raw className. */
|
|
1157
|
-
className(className: string | undefined): CssBuilder<T> {
|
|
1158
|
-
void className;
|
|
1159
|
-
return this;
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
1152
|
/** Marker for the build-time transform to append raw inline styles. */
|
|
1163
1153
|
style(inlineStyle: InlineStyle): CssBuilder<T> {
|
|
1164
1154
|
void inlineStyle;
|
|
@@ -1182,16 +1172,6 @@ function sortObject<T extends object>(obj: T): T {
|
|
|
1182
1172
|
}, ({} as any) as T) as T;
|
|
1183
1173
|
}
|
|
1184
1174
|
|
|
1185
|
-
/** Conditionally adds \`important!\` to everything. */
|
|
1186
|
-
function maybeImportant<T extends object>(obj: T, important: boolean): T {
|
|
1187
|
-
if (important) {
|
|
1188
|
-
Object.keys(obj).forEach(key => {
|
|
1189
|
-
(obj as any)[key] = \`\${(obj as any)[key]} !important\`;
|
|
1190
|
-
});
|
|
1191
|
-
}
|
|
1192
|
-
return obj;
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
1175
|
/** Converts \`inc\` into pixels value with a \`px\` suffix. */
|
|
1196
1176
|
export function maybeInc(inc: number | string): string {
|
|
1197
1177
|
return typeof inc === "string" ? inc : \`\${increment(inc)}px\`;
|
|
@@ -1224,7 +1204,7 @@ export enum Palette {
|
|
|
1224
1204
|
export type Xss<P extends keyof Properties> = Pick<Properties, P>;
|
|
1225
1205
|
|
|
1226
1206
|
/** An entry point for Css expressions. CssBuilder is immutable so this is safe to share. */
|
|
1227
|
-
export const Css = new CssBuilder({ rules: {}, enabled: true,
|
|
1207
|
+
export const Css = new CssBuilder({ rules: {}, enabled: true, selector: undefined, elseApplied: false });
|
|
1228
1208
|
|
|
1229
1209
|
${typeAliasCode}
|
|
1230
1210
|
|
|
@@ -1281,6 +1261,12 @@ function generateWebCssBuilder(config, sections) {
|
|
|
1281
1261
|
...Object.entries(genBreakpointsMap).map(([name, value]) => ` ${name} = "${value}",`),
|
|
1282
1262
|
`}`
|
|
1283
1263
|
];
|
|
1264
|
+
const pseudoGetterCode = Object.entries(TRUSS_PSEUDO_METHODS).map(([name, selector]) => {
|
|
1265
|
+
return code`
|
|
1266
|
+
get ${name}() {
|
|
1267
|
+
return this.newCss({ selector: ${quote(selector)} });
|
|
1268
|
+
}`;
|
|
1269
|
+
});
|
|
1284
1270
|
const typographyType = code`
|
|
1285
1271
|
export type ${def("Typography")} = ${Object.keys(fonts).map(quote).join(" | ")};
|
|
1286
1272
|
`;
|
|
@@ -1289,7 +1275,7 @@ function generateWebCssBuilder(config, sections) {
|
|
|
1289
1275
|
// See your project's \`truss-config.ts\` to make configuration changes (fonts, increments, etc).
|
|
1290
1276
|
// Target: web (build-time plugin)
|
|
1291
1277
|
|
|
1292
|
-
import { trussProps, useRuntimeStyle as _useRuntimeStyle } from "@homebound/truss/runtime";
|
|
1278
|
+
import { trussProps, useRuntimeStyle as _useRuntimeStyle, __invertTrussMediaQuery } from "@homebound/truss/runtime";
|
|
1293
1279
|
|
|
1294
1280
|
/** Given a type X, and the user's proposed type T, only allow keys in X and nothing else. */
|
|
1295
1281
|
export type Only<X, T> = X & Record<Exclude<keyof T, keyof X | "__kind">, never>;
|
|
@@ -1367,30 +1353,7 @@ class CssBuilder<T extends Properties, S extends StyleKind = "buildtime"> {
|
|
|
1367
1353
|
return this.rules as any;
|
|
1368
1354
|
}
|
|
1369
1355
|
|
|
1370
|
-
|
|
1371
|
-
return this.newCss({ selector: ":hover" });
|
|
1372
|
-
}
|
|
1373
|
-
get onFocus() {
|
|
1374
|
-
return this.newCss({ selector: ":focus" });
|
|
1375
|
-
}
|
|
1376
|
-
get onFocusVisible() {
|
|
1377
|
-
return this.newCss({ selector: ":focus-visible" });
|
|
1378
|
-
}
|
|
1379
|
-
get onFocusWithin() {
|
|
1380
|
-
return this.newCss({ selector: ":focus-within" });
|
|
1381
|
-
}
|
|
1382
|
-
get onActive() {
|
|
1383
|
-
return this.newCss({ selector: ":active" });
|
|
1384
|
-
}
|
|
1385
|
-
get onDisabled() {
|
|
1386
|
-
return this.newCss({ selector: ":disabled" });
|
|
1387
|
-
}
|
|
1388
|
-
get ifFirstOfType() {
|
|
1389
|
-
return this.newCss({ selector: ":first-of-type" });
|
|
1390
|
-
}
|
|
1391
|
-
get ifLastOfType() {
|
|
1392
|
-
return this.newCss({ selector: ":last-of-type" });
|
|
1393
|
-
}
|
|
1356
|
+
${pseudoGetterCode}
|
|
1394
1357
|
|
|
1395
1358
|
/** Marks this element as a default hover marker (for ancestor pseudo selectors). */
|
|
1396
1359
|
get marker(): CssBuilder<T, S> {
|
|
@@ -1466,7 +1429,7 @@ class CssBuilder<T extends Properties, S extends StyleKind = "buildtime"> {
|
|
|
1466
1429
|
if (this.opts.elseApplied) {
|
|
1467
1430
|
throw new Error("else was already called");
|
|
1468
1431
|
}
|
|
1469
|
-
return this.newCss({ selector:
|
|
1432
|
+
return this.newCss({ selector: __invertTrussMediaQuery(this.selector), elseApplied: true });
|
|
1470
1433
|
}
|
|
1471
1434
|
if (this.opts.elseApplied) {
|
|
1472
1435
|
throw new Error("else was already called");
|
|
@@ -1608,29 +1571,6 @@ ${typeAliasCode}
|
|
|
1608
1571
|
|
|
1609
1572
|
${breakpointCode}
|
|
1610
1573
|
|
|
1611
|
-
function invertMediaQuery(query: string): string {
|
|
1612
|
-
const screenPrefix = "@media screen and ";
|
|
1613
|
-
if (query.startsWith(screenPrefix)) {
|
|
1614
|
-
const conditions = query.slice(screenPrefix.length).trim();
|
|
1615
|
-
const rangeMatch = conditions.match(/^\(min-width: (\d+)px\) and \(max-width: (\d+)px\)$/);
|
|
1616
|
-
if (rangeMatch) {
|
|
1617
|
-
const min = Number(rangeMatch[1]);
|
|
1618
|
-
const max = Number(rangeMatch[2]);
|
|
1619
|
-
return \`@media screen and (max-width: \${min - 1}px), screen and (min-width: \${max + 1}px)\`;
|
|
1620
|
-
}
|
|
1621
|
-
const minMatch = conditions.match(/^\(min-width: (\d+)px\)$/);
|
|
1622
|
-
if (minMatch) {
|
|
1623
|
-
return \`@media screen and (max-width: \${Number(minMatch[1]) - 1}px)\`;
|
|
1624
|
-
}
|
|
1625
|
-
const maxMatch = conditions.match(/^\(max-width: (\d+)px\)$/);
|
|
1626
|
-
if (maxMatch) {
|
|
1627
|
-
return \`@media screen and (min-width: \${Number(maxMatch[1]) + 1}px)\`;
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
return query.replace("@media", "@media not");
|
|
1631
|
-
}
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
1574
|
${extras || ""}
|
|
1635
1575
|
`;
|
|
1636
1576
|
}
|