From 276919a814cefab8cb509d6ae1c27381a1e96587 Mon Sep 17 00:00:00 2001 From: Allan Galdino Date: Fri, 17 May 2024 17:23:39 -0300 Subject: [PATCH 1/2] enhance create methods to support additional properties on base definition --- packages/template-tachyons/src/Css.ts | 67 ++++++++++--------- packages/testing-tachyons/src/Css.ts | 67 ++++++++++--------- packages/truss/src/methods.test.ts | 63 ++++++++++++++++- packages/truss/src/methods.ts | 14 ++-- .../truss/src/sections/tachyons/lineClamp.ts | 44 +++++++----- 5 files changed, 173 insertions(+), 82 deletions(-) diff --git a/packages/template-tachyons/src/Css.ts b/packages/template-tachyons/src/Css.ts index 6dd4cdd..88e6774 100644 --- a/packages/template-tachyons/src/Css.ts +++ b/packages/template-tachyons/src/Css.ts @@ -1172,52 +1172,59 @@ class CssBuilder { } // lineClamp - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 1; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 1`. */ get lineClamp1() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 1).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 1); } - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 2; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 2`. */ get lineClamp2() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 2).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 2); } - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 3; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 3`. */ get lineClamp3() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 3).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 3); } - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 4; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 4`. */ get lineClamp4() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 4).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 4); } - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 5; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 5`. */ get lineClamp5() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 5).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 5); } - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 6; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 6`. */ get lineClamp6() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 6).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 6); } /** Sets `WebkitLineClamp: "unset"`. */ get lineClampNone() { return this.add("WebkitLineClamp", "unset"); } + /** Sets `WebkitLineClamp: value`. */ + lineClamp(value: Properties["WebkitLineClamp"]) { + return this.add("WebkitLineClamp", value).add("overflow", "hidden").add("display", "-webkit-box").add( + "WebkitBoxOrient", + "vertical", + ).add("textOverflow", "ellipsis"); + } // objectFit /** Sets `objectFit: "contain"`. */ diff --git a/packages/testing-tachyons/src/Css.ts b/packages/testing-tachyons/src/Css.ts index 0f93417..1465dd2 100644 --- a/packages/testing-tachyons/src/Css.ts +++ b/packages/testing-tachyons/src/Css.ts @@ -1072,52 +1072,59 @@ class CssBuilder { } // lineClamp - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 1; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 1`. */ get lineClamp1() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 1).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 1); } - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 2; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 2`. */ get lineClamp2() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 2).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 2); } - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 3; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 3`. */ get lineClamp3() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 3).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 3); } - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 4; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 4`. */ get lineClamp4() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 4).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 4); } - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 5; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 5`. */ get lineClamp5() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 5).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 5); } - /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitLineClamp: 6; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"`. */ + /** Sets `overflow: "hidden"; display: "-webkit-box"; WebkitBoxOrient: "vertical"; textOverflow: "ellipsis"; WebkitLineClamp: 6`. */ get lineClamp6() { - return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitLineClamp", 6).add( - "WebkitBoxOrient", - "vertical", - ).add("textOverflow", "ellipsis"); + return this.add("overflow", "hidden").add("display", "-webkit-box").add("WebkitBoxOrient", "vertical").add( + "textOverflow", + "ellipsis", + ).add("WebkitLineClamp", 6); } /** Sets `WebkitLineClamp: "unset"`. */ get lineClampNone() { return this.add("WebkitLineClamp", "unset"); } + /** Sets `WebkitLineClamp: value`. */ + lineClamp(value: Properties["WebkitLineClamp"]) { + return this.add("WebkitLineClamp", value).add("overflow", "hidden").add("display", "-webkit-box").add( + "WebkitBoxOrient", + "vertical", + ).add("textOverflow", "ellipsis"); + } // objectFit /** Sets `objectFit: "contain"`. */ diff --git a/packages/truss/src/methods.test.ts b/packages/truss/src/methods.test.ts index 8ec72a5..3d1cadd 100644 --- a/packages/truss/src/methods.test.ts +++ b/packages/truss/src/methods.test.ts @@ -1,5 +1,6 @@ +import { Properties } from "csstype"; import { Config } from "src/config"; -import { newIncrementMethods } from "src/methods"; +import { newIncrementMethods, newMethod, newMethodsForProp, newParamMethod } from "src/methods"; describe("methods", () => { const config: Config = { @@ -73,4 +74,64 @@ describe("methods", () => { `); }); }); + + describe("newParamMethod", () => { + it("creates a new method with a parameter", () => { + // Given a new method with a parameter + const result = newParamMethod("bgColor", "backgroundColor"); + // Then it should output the expected method + expect(result).toMatchInlineSnapshot(` + "/** Sets \`backgroundColor: value\`. */ + bgColor(value: Properties["backgroundColor"]) { return this.add("backgroundColor", value); }" + `); + }); + + it("creates a new method with a parameter and additional properties", () => { + // Given a new method with a parameter and additional properties + const result = newParamMethod("bgColor", "backgroundColor", { display: "block" }); + // Then it should output the expected method + expect(result).toMatchInlineSnapshot(` + "/** Sets \`backgroundColor: value\`. */ + bgColor(value: Properties["backgroundColor"]) { return this.add("backgroundColor", value).add("display", "block"); }" + `); + }); + }); + + describe("newMethodsForProp", () => { + it("creates a new method for prop", () => { + // Given a new method for "lineClamp" prop with different definitions + const baseProperties: Properties = { overflow: "hidden", textOverflow: "ellipsis" }; + const def: (lineClamp: Properties["WebkitLineClamp"]) => Properties = (lineClamp) => ({ + WebkitLineClamp: lineClamp, + ...baseProperties, + }); + // When we create the new methods + const result = newMethodsForProp("lineClamp", { lineClamp1: def(1), lineClampNone: def("unset") }); + // Then it should output the expected methods + expect(result).toMatchInlineSnapshot(` + [ + "/** Sets \`WebkitLineClamp: 1; overflow: "hidden"; textOverflow: "ellipsis"\`. */ + get lineClamp1() { return this.add("WebkitLineClamp", 1).add("overflow", "hidden").add("textOverflow", "ellipsis"); }", + "/** Sets \`WebkitLineClamp: "unset"; overflow: "hidden"; textOverflow: "ellipsis"\`. */ + get lineClampNone() { return this.add("WebkitLineClamp", "unset").add("overflow", "hidden").add("textOverflow", "ellipsis"); }", + "/** Sets \`lineClamp: value\`. */ + lineClamp(value: Properties["lineClamp"]) { return this.add("lineClamp", value); }", + ] + `); + }); + + it("creates method extra base definitions", () => { + // Given some base properties + const baseProperties: Properties = { overflow: "hidden", textOverflow: "ellipsis" }; + // When we call newMethodsForProp with the base properties for "lineClamp" + const result = newMethodsForProp("WebkitLineClamp", {}, "lineClamp", false, baseProperties); + // Then it should output a lineClamp function with the base properties + expect(result).toMatchInlineSnapshot(` + [ + "/** Sets \`WebkitLineClamp: value\`. */ + lineClamp(value: Properties["WebkitLineClamp"]) { return this.add("WebkitLineClamp", value).add("overflow", "hidden").add("textOverflow", "ellipsis"); }", + ] + `); + }); + }); }); diff --git a/packages/truss/src/methods.ts b/packages/truss/src/methods.ts index 5a508dd..143dfe5 100644 --- a/packages/truss/src/methods.ts +++ b/packages/truss/src/methods.ts @@ -16,11 +16,13 @@ export function newMethod(abbr: UtilityName, defs: Properties): UtilityMethod { /** * Given a single abbreviation (i.e. `mt`) and a property name (i.e. `marginTop`), returns the * TypeScript code for a `mt` utility method that accepts a user-provided value of the prop to set. + * Use `extraDefs` for additional properties to set. * * I.e. `Css.mt(someValue).$` */ -export function newParamMethod(abbr: UtilityName, prop: keyof Properties): UtilityMethod { - return `${comment({ [prop]: "value" })} ${abbr}(value: Properties["${prop}"]) { return this.add("${prop}", value); }`; +export function newParamMethod(abbr: UtilityName, prop: keyof Properties, extraDefs: Properties = {}): UtilityMethod { + const additionalDefs = Object.entries(extraDefs).map(([prop, value]) => `.add("${prop}", ${maybeWrap(value)})`).join(""); + return `${comment({ [prop]: "value" })} ${abbr}(value: Properties["${prop}"]) { return this.add("${prop}", value)${additionalDefs}; }`; } /** @@ -38,17 +40,19 @@ export function newParamMethod(abbr: UtilityName, prop: keyof Properties): Utili * @param defs a map of abbreviation name --> value * @param baseName the base name to use, i.e. `mt` * @param includePx generate an extra `${baseName}Px` method that calls the base method with a converted px value + * @param baseDefs additional properties to set for the base method */ export function newMethodsForProp

( prop: P, - defs: Record, + defs: Record, baseName: string | null = prop, includePx: boolean = false, + baseDefs?: Omit, ): UtilityMethod[] { return [ - ...Object.entries(defs).map(([abbr, value]) => newMethod(abbr, { [prop]: value })), + ...Object.entries(defs).map(([abbr, value]) => newMethod(abbr, typeof value === "object" ? value : { [prop]: value })), // Conditionally add a method that directly accepts a value for prop - ...(baseName !== null ? [newParamMethod(baseName, prop)] : []), + ...(baseName !== null ? [newParamMethod(baseName, prop, baseDefs)] : []), ...(baseName !== null && includePx ? [newPxMethod(baseName, prop)] : []), ]; } diff --git a/packages/truss/src/sections/tachyons/lineClamp.ts b/packages/truss/src/sections/tachyons/lineClamp.ts index 25732ff..a8e6156 100644 --- a/packages/truss/src/sections/tachyons/lineClamp.ts +++ b/packages/truss/src/sections/tachyons/lineClamp.ts @@ -1,19 +1,31 @@ -import { newMethod, zeroTo } from "src/methods"; +import { Properties } from "csstype"; import { CreateMethodsFn } from "src/config"; +import { newMethodsForProp } from "src/methods"; + +const additionalDefs: Properties = { + overflow: "hidden", + display: "-webkit-box", + // As of 11/28/2022, this is deprecated but still necessary for lineClamp to work: + // https://github.com/tailwindlabs/tailwindcss-line-clamp/blob/master/src/index.js + WebkitBoxOrient: "vertical", + // tailwinds doesn't add this by default, but it seems like a good default for us. + textOverflow: "ellipsis", +} // https://github.com/tailwindlabs/tailwindcss-line-clamp/ -export const lineClamp: CreateMethodsFn = () => [ - ...zeroTo(5).map((i) => - newMethod(`lineClamp${i + 1}`, { - overflow: "hidden", - display: "-webkit-box", - WebkitLineClamp: i + 1, - // As of 11/28/2022, this is deprecated but still necessary for lineClamp to work: - // https://github.com/tailwindlabs/tailwindcss-line-clamp/blob/master/src/index.js - WebkitBoxOrient: "vertical", - // tailwinds doesn't add this by default, but it seems like a good default for us. - textOverflow: "ellipsis", - }), - ), - newMethod(`lineClampNone`, { WebkitLineClamp: "unset" }), -]; +export const lineClamp: CreateMethodsFn = () => + newMethodsForProp( + "WebkitLineClamp", + { + lineClamp1: { ...additionalDefs, WebkitLineClamp: 1 }, + lineClamp2: { ...additionalDefs, WebkitLineClamp: 2 }, + lineClamp3: { ...additionalDefs, WebkitLineClamp: 3 }, + lineClamp4: { ...additionalDefs, WebkitLineClamp: 4 }, + lineClamp5: { ...additionalDefs, WebkitLineClamp: 5 }, + lineClamp6: { ...additionalDefs, WebkitLineClamp: 6 }, + lineClampNone: { WebkitLineClamp: "unset" }, + }, + "lineClamp", + false, + additionalDefs +); \ No newline at end of file From f411d2ce2355bd4f1efb7b3c920be6d75c642f89 Mon Sep 17 00:00:00 2001 From: Allan Galdino Date: Mon, 20 May 2024 10:22:24 -0300 Subject: [PATCH 2/2] feedback PR: renaming --- packages/truss/src/methods.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/truss/src/methods.ts b/packages/truss/src/methods.ts index 143dfe5..648ba48 100644 --- a/packages/truss/src/methods.ts +++ b/packages/truss/src/methods.ts @@ -16,12 +16,12 @@ export function newMethod(abbr: UtilityName, defs: Properties): UtilityMethod { /** * Given a single abbreviation (i.e. `mt`) and a property name (i.e. `marginTop`), returns the * TypeScript code for a `mt` utility method that accepts a user-provided value of the prop to set. - * Use `extraDefs` for additional properties to set. + * Use `extraProperties` for additional properties to set. * * I.e. `Css.mt(someValue).$` */ -export function newParamMethod(abbr: UtilityName, prop: keyof Properties, extraDefs: Properties = {}): UtilityMethod { - const additionalDefs = Object.entries(extraDefs).map(([prop, value]) => `.add("${prop}", ${maybeWrap(value)})`).join(""); +export function newParamMethod(abbr: UtilityName, prop: keyof Properties, extraProperties: Properties = {}): UtilityMethod { + const additionalDefs = Object.entries(extraProperties).map(([prop, value]) => `.add("${prop}", ${maybeWrap(value)})`).join(""); return `${comment({ [prop]: "value" })} ${abbr}(value: Properties["${prop}"]) { return this.add("${prop}", value)${additionalDefs}; }`; } @@ -37,7 +37,7 @@ export function newParamMethod(abbr: UtilityName, prop: keyof Properties, extraD * to `null`. * * @param prop the CSS property we're setting, i.e. `marginTop` - * @param defs a map of abbreviation name --> value + * @param defs a map of abbreviation name --> value (a property value or an object of properties to set) * @param baseName the base name to use, i.e. `mt` * @param includePx generate an extra `${baseName}Px` method that calls the base method with a converted px value * @param baseDefs additional properties to set for the base method @@ -47,12 +47,15 @@ export function newMethodsForProp

( defs: Record, baseName: string | null = prop, includePx: boolean = false, - baseDefs?: Omit, + valueMethodExtraProperties?: Omit, ): UtilityMethod[] { return [ - ...Object.entries(defs).map(([abbr, value]) => newMethod(abbr, typeof value === "object" ? value : { [prop]: value })), + ...Object.entries(defs).map(([abbr, value]) => newMethod(abbr, + // If the value is an object, use it as the full defs, otherwise, use it as the prop value + typeof value === "object" ? value : { [prop]: value } + )), // Conditionally add a method that directly accepts a value for prop - ...(baseName !== null ? [newParamMethod(baseName, prop, baseDefs)] : []), + ...(baseName !== null ? [newParamMethod(baseName, prop, valueMethodExtraProperties)] : []), ...(baseName !== null && includePx ? [newPxMethod(baseName, prop)] : []), ]; }