Skip to content

Commit a92172d

Browse files
feat: support additional properties to utility method (#120)
This PR enhances the utility method to support additional properties. For instance, the `lineClamp` [property](https://github.com/homebound-team/truss/blob/main/packages/truss/src/sections/tachyons/lineClamp.ts) does have additional properties but those can't be passed to the `lineClamp(value)` utility method. Before ```ts /** Sets `WebkitLineClamp: value`. */ lineClamp(value: Properties["WebkitLineClamp"]) { return this.add("WebkitLineClamp", value); } ``` After ```ts /** Sets `WebkitLineClamp: value`. */ lineClamp(value: Properties["WebkitLineClamp"]) { return this.add("WebkitLineClamp", value) // default def .add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient","vertical",).add("textOverflow", "ellipsis"); // additional defs } ``` With these changes, `lineClamp(value)` will have the ability to define additional properties combining to the `value` param. Also, added a few tests for `packages/truss/src/methods.test.ts` cc @bdow since he's going to use it.
1 parent 9314b16 commit a92172d

File tree

5 files changed

+177
-83
lines changed

5 files changed

+177
-83
lines changed

packages/template-tachyons/src/Css.ts

+37-30
Original file line numberDiff line numberDiff line change
@@ -1172,52 +1172,59 @@ class CssBuilder<T extends Properties> {
11721172
}
11731173

11741174
// lineClamp
1175-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 1; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1175+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 1`. */
11761176
get lineClamp1() {
1177-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 1).add(
1178-
"WebkitBoxOrient",
1179-
"vertical",
1180-
).add("textOverflow", "ellipsis");
1177+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1178+
"textOverflow",
1179+
"ellipsis",
1180+
).add("WebkitLineClamp", 1);
11811181
}
1182-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 2; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1182+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 2`. */
11831183
get lineClamp2() {
1184-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 2).add(
1185-
"WebkitBoxOrient",
1186-
"vertical",
1187-
).add("textOverflow", "ellipsis");
1184+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1185+
"textOverflow",
1186+
"ellipsis",
1187+
).add("WebkitLineClamp", 2);
11881188
}
1189-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 3; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1189+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 3`. */
11901190
get lineClamp3() {
1191-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 3).add(
1192-
"WebkitBoxOrient",
1193-
"vertical",
1194-
).add("textOverflow", "ellipsis");
1191+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1192+
"textOverflow",
1193+
"ellipsis",
1194+
).add("WebkitLineClamp", 3);
11951195
}
1196-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 4; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1196+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 4`. */
11971197
get lineClamp4() {
1198-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 4).add(
1199-
"WebkitBoxOrient",
1200-
"vertical",
1201-
).add("textOverflow", "ellipsis");
1198+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1199+
"textOverflow",
1200+
"ellipsis",
1201+
).add("WebkitLineClamp", 4);
12021202
}
1203-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 5; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1203+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 5`. */
12041204
get lineClamp5() {
1205-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 5).add(
1206-
"WebkitBoxOrient",
1207-
"vertical",
1208-
).add("textOverflow", "ellipsis");
1205+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1206+
"textOverflow",
1207+
"ellipsis",
1208+
).add("WebkitLineClamp", 5);
12091209
}
1210-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 6; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1210+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 6`. */
12111211
get lineClamp6() {
1212-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 6).add(
1213-
"WebkitBoxOrient",
1214-
"vertical",
1215-
).add("textOverflow", "ellipsis");
1212+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1213+
"textOverflow",
1214+
"ellipsis",
1215+
).add("WebkitLineClamp", 6);
12161216
}
12171217
/** Sets `WebkitLineClamp: "unset"`. */
12181218
get lineClampNone() {
12191219
return this.add("WebkitLineClamp", "unset");
12201220
}
1221+
/** Sets `WebkitLineClamp: value`. */
1222+
lineClamp(value: Properties["WebkitLineClamp"]) {
1223+
return this.add("WebkitLineClamp", value).add("overflow", "hidden").add("display", "-webkit-box").add(
1224+
"WebkitBoxOrient",
1225+
"vertical",
1226+
).add("textOverflow", "ellipsis");
1227+
}
12211228

12221229
// objectFit
12231230
/** Sets `objectFit: "contain"`. */

packages/testing-tachyons/src/Css.ts

+37-30
Original file line numberDiff line numberDiff line change
@@ -1072,52 +1072,59 @@ class CssBuilder<T extends Properties> {
10721072
}
10731073

10741074
// lineClamp
1075-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 1; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1075+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 1`. */
10761076
get lineClamp1() {
1077-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 1).add(
1078-
"WebkitBoxOrient",
1079-
"vertical",
1080-
).add("textOverflow", "ellipsis");
1077+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1078+
"textOverflow",
1079+
"ellipsis",
1080+
).add("WebkitLineClamp", 1);
10811081
}
1082-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 2; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1082+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 2`. */
10831083
get lineClamp2() {
1084-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 2).add(
1085-
"WebkitBoxOrient",
1086-
"vertical",
1087-
).add("textOverflow", "ellipsis");
1084+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1085+
"textOverflow",
1086+
"ellipsis",
1087+
).add("WebkitLineClamp", 2);
10881088
}
1089-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 3; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1089+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 3`. */
10901090
get lineClamp3() {
1091-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 3).add(
1092-
"WebkitBoxOrient",
1093-
"vertical",
1094-
).add("textOverflow", "ellipsis");
1091+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1092+
"textOverflow",
1093+
"ellipsis",
1094+
).add("WebkitLineClamp", 3);
10951095
}
1096-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 4; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1096+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 4`. */
10971097
get lineClamp4() {
1098-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 4).add(
1099-
"WebkitBoxOrient",
1100-
"vertical",
1101-
).add("textOverflow", "ellipsis");
1098+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1099+
"textOverflow",
1100+
"ellipsis",
1101+
).add("WebkitLineClamp", 4);
11021102
}
1103-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 5; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1103+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 5`. */
11041104
get lineClamp5() {
1105-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 5).add(
1106-
"WebkitBoxOrient",
1107-
"vertical",
1108-
).add("textOverflow", "ellipsis");
1105+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1106+
"textOverflow",
1107+
"ellipsis",
1108+
).add("WebkitLineClamp", 5);
11091109
}
1110-
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 6; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */
1110+
/** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 6`. */
11111111
get lineClamp6() {
1112-
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 6).add(
1113-
"WebkitBoxOrient",
1114-
"vertical",
1115-
).add("textOverflow", "ellipsis");
1112+
return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add(
1113+
"textOverflow",
1114+
"ellipsis",
1115+
).add("WebkitLineClamp", 6);
11161116
}
11171117
/** Sets `WebkitLineClamp: "unset"`. */
11181118
get lineClampNone() {
11191119
return this.add("WebkitLineClamp", "unset");
11201120
}
1121+
/** Sets `WebkitLineClamp: value`. */
1122+
lineClamp(value: Properties["WebkitLineClamp"]) {
1123+
return this.add("WebkitLineClamp", value).add("overflow", "hidden").add("display", "-webkit-box").add(
1124+
"WebkitBoxOrient",
1125+
"vertical",
1126+
).add("textOverflow", "ellipsis");
1127+
}
11211128

11221129
// objectFit
11231130
/** Sets `objectFit: "contain"`. */

packages/truss/src/methods.test.ts

+62-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import { Properties } from "csstype";
12
import { Config } from "src/config";
2-
import { newIncrementMethods } from "src/methods";
3+
import { newIncrementMethods, newMethod, newMethodsForProp, newParamMethod } from "src/methods";
34

45
describe("methods", () => {
56
const config: Config = {
@@ -73,4 +74,64 @@ describe("methods", () => {
7374
`);
7475
});
7576
});
77+
78+
describe("newParamMethod", () => {
79+
it("creates a new method with a parameter", () => {
80+
// Given a new method with a parameter
81+
const result = newParamMethod("bgColor", "backgroundColor");
82+
// Then it should output the expected method
83+
expect(result).toMatchInlineSnapshot(`
84+
"/** Sets \`backgroundColor: value\`. */
85+
bgColor(value: Properties["backgroundColor"]) { return this.add("backgroundColor", value); }"
86+
`);
87+
});
88+
89+
it("creates a new method with a parameter and additional properties", () => {
90+
// Given a new method with a parameter and additional properties
91+
const result = newParamMethod("bgColor", "backgroundColor", { display: "block" });
92+
// Then it should output the expected method
93+
expect(result).toMatchInlineSnapshot(`
94+
"/** Sets \`backgroundColor: value\`. */
95+
bgColor(value: Properties["backgroundColor"]) { return this.add("backgroundColor", value).add("display", "block"); }"
96+
`);
97+
});
98+
});
99+
100+
describe("newMethodsForProp", () => {
101+
it("creates a new method for prop", () => {
102+
// Given a new method for "lineClamp" prop with different definitions
103+
const baseProperties: Properties = { overflow: "hidden", textOverflow: "ellipsis" };
104+
const def: (lineClamp: Properties["WebkitLineClamp"]) => Properties = (lineClamp) => ({
105+
WebkitLineClamp: lineClamp,
106+
...baseProperties,
107+
});
108+
// When we create the new methods
109+
const result = newMethodsForProp("lineClamp", { lineClamp1: def(1), lineClampNone: def("unset") });
110+
// Then it should output the expected methods
111+
expect(result).toMatchInlineSnapshot(`
112+
[
113+
"/** Sets \`WebkitLineClamp: 1; overflow: "hidden"; textOverflow: "ellipsis"\`. */
114+
get lineClamp1() { return this.add("WebkitLineClamp", 1).add("overflow", "hidden").add("textOverflow", "ellipsis"); }",
115+
"/** Sets \`WebkitLineClamp: "unset"; overflow: "hidden"; textOverflow: "ellipsis"\`. */
116+
get lineClampNone() { return this.add("WebkitLineClamp", "unset").add("overflow", "hidden").add("textOverflow", "ellipsis"); }",
117+
"/** Sets \`lineClamp: value\`. */
118+
lineClamp(value: Properties["lineClamp"]) { return this.add("lineClamp", value); }",
119+
]
120+
`);
121+
});
122+
123+
it("creates method extra base definitions", () => {
124+
// Given some base properties
125+
const baseProperties: Properties = { overflow: "hidden", textOverflow: "ellipsis" };
126+
// When we call newMethodsForProp with the base properties for "lineClamp"
127+
const result = newMethodsForProp("WebkitLineClamp", {}, "lineClamp", false, baseProperties);
128+
// Then it should output a lineClamp function with the base properties
129+
expect(result).toMatchInlineSnapshot(`
130+
[
131+
"/** Sets \`WebkitLineClamp: value\`. */
132+
lineClamp(value: Properties["WebkitLineClamp"]) { return this.add("WebkitLineClamp", value).add("overflow", "hidden").add("textOverflow", "ellipsis"); }",
133+
]
134+
`);
135+
});
136+
});
76137
});

packages/truss/src/methods.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ export function newMethod(abbr: UtilityName, defs: Properties): UtilityMethod {
1616
/**
1717
* Given a single abbreviation (i.e. `mt`) and a property name (i.e. `marginTop`), returns the
1818
* TypeScript code for a `mt` utility method that accepts a user-provided value of the prop to set.
19+
* Use `extraProperties` for additional properties to set.
1920
*
2021
* I.e. `Css.mt(someValue).$`
2122
*/
22-
export function newParamMethod(abbr: UtilityName, prop: keyof Properties): UtilityMethod {
23-
return `${comment({ [prop]: "value" })} ${abbr}(value: Properties["${prop}"]) { return this.add("${prop}", value); }`;
23+
export function newParamMethod(abbr: UtilityName, prop: keyof Properties, extraProperties: Properties = {}): UtilityMethod {
24+
const additionalDefs = Object.entries(extraProperties).map(([prop, value]) => `.add("${prop}", ${maybeWrap(value)})`).join("");
25+
return `${comment({ [prop]: "value" })} ${abbr}(value: Properties["${prop}"]) { return this.add("${prop}", value)${additionalDefs}; }`;
2426
}
2527

2628
/**
@@ -35,20 +37,25 @@ export function newParamMethod(abbr: UtilityName, prop: keyof Properties): Utili
3537
* to `null`.
3638
*
3739
* @param prop the CSS property we're setting, i.e. `marginTop`
38-
* @param defs a map of abbreviation name --> value
40+
* @param defs a map of abbreviation name --> value (a property value or an object of properties to set)
3941
* @param baseName the base name to use, i.e. `mt`
4042
* @param includePx generate an extra `${baseName}Px` method that calls the base method with a converted px value
43+
* @param baseDefs additional properties to set for the base method
4144
*/
4245
export function newMethodsForProp<P extends Prop>(
4346
prop: P,
44-
defs: Record<UtilityName, Properties[P]>,
47+
defs: Record<UtilityName, Properties[P] | Properties>,
4548
baseName: string | null = prop,
4649
includePx: boolean = false,
50+
valueMethodExtraProperties?: Omit<Properties, P>,
4751
): UtilityMethod[] {
4852
return [
49-
...Object.entries(defs).map(([abbr, value]) => newMethod(abbr, { [prop]: value })),
53+
...Object.entries(defs).map(([abbr, value]) => newMethod(abbr,
54+
// If the value is an object, use it as the full defs, otherwise, use it as the prop value
55+
typeof value === "object" ? value : { [prop]: value }
56+
)),
5057
// Conditionally add a method that directly accepts a value for prop
51-
...(baseName !== null ? [newParamMethod(baseName, prop)] : []),
58+
...(baseName !== null ? [newParamMethod(baseName, prop, valueMethodExtraProperties)] : []),
5259
...(baseName !== null && includePx ? [newPxMethod(baseName, prop)] : []),
5360
];
5461
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,31 @@
1-
import { newMethod, zeroTo } from "src/methods";
1+
import { Properties } from "csstype";
22
import { CreateMethodsFn } from "src/config";
3+
import { newMethodsForProp } from "src/methods";
4+
5+
const additionalDefs: Properties = {
6+
overflow: "hidden",
7+
display: "-webkit-box",
8+
// As of 11/28/2022, this is deprecated but still necessary for lineClamp to work:
9+
// https://github.com/tailwindlabs/tailwindcss-line-clamp/blob/master/src/index.js
10+
WebkitBoxOrient: "vertical",
11+
// tailwinds doesn't add this by default, but it seems like a good default for us.
12+
textOverflow: "ellipsis",
13+
}
314

415
// https://github.com/tailwindlabs/tailwindcss-line-clamp/
5-
export const lineClamp: CreateMethodsFn = () => [
6-
...zeroTo(5).map((i) =>
7-
newMethod(`lineClamp${i + 1}`, {
8-
overflow: "hidden",
9-
display: "-webkit-box",
10-
WebkitLineClamp: i + 1,
11-
// As of 11/28/2022, this is deprecated but still necessary for lineClamp to work:
12-
// https://github.com/tailwindlabs/tailwindcss-line-clamp/blob/master/src/index.js
13-
WebkitBoxOrient: "vertical",
14-
// tailwinds doesn't add this by default, but it seems like a good default for us.
15-
textOverflow: "ellipsis",
16-
}),
17-
),
18-
newMethod(`lineClampNone`, { WebkitLineClamp: "unset" }),
19-
];
16+
export const lineClamp: CreateMethodsFn = () =>
17+
newMethodsForProp(
18+
"WebkitLineClamp",
19+
{
20+
lineClamp1: { ...additionalDefs, WebkitLineClamp: 1 },
21+
lineClamp2: { ...additionalDefs, WebkitLineClamp: 2 },
22+
lineClamp3: { ...additionalDefs, WebkitLineClamp: 3 },
23+
lineClamp4: { ...additionalDefs, WebkitLineClamp: 4 },
24+
lineClamp5: { ...additionalDefs, WebkitLineClamp: 5 },
25+
lineClamp6: { ...additionalDefs, WebkitLineClamp: 6 },
26+
lineClampNone: { WebkitLineClamp: "unset" },
27+
},
28+
"lineClamp",
29+
false,
30+
additionalDefs
31+
);

0 commit comments

Comments
 (0)