Skip to content

Commit

Permalink
feat(rulesets): add custom definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
n1stre committed Nov 1, 2023
1 parent 90edaec commit 7581112
Show file tree
Hide file tree
Showing 12 changed files with 70 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { IRuleset } from "src/1_entities/Ruleset";
import RulesetsListBuilder, {
IRulesetsListBuilder,
} from "../../1_entities/RulesetsListBuilder";
Expand All @@ -6,6 +7,7 @@ export interface Props extends IRulesetsListBuilder.DTO {}

export interface DTO {
values: ValuesMap;
definitions: IRuleset.DTO[];
}

export type ClassnamesMap = IRulesetsListBuilder.ClassnamesMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const toString = (rs: IRuleset.DTO[]) =>
const basic: IBuildRulesets.Props = {
variantsMap: {},
classnamesMap: {
width: "w-$0",

filter: "ftr_$0",
filterCompound: "ftr~",
filterBlur: "~bl_$0",
Expand Down Expand Up @@ -50,6 +52,8 @@ const basic: IBuildRulesets.Props = {
transformPerspective: "~prs_$0",
},
declarationsMap: {
width: "width: $0;",

filter: "filter: $0;",
filterCompound:
"filter: blur(var(--filterBlur)) brightness(var(--filterBrightness)) contrast(var(--filterContrast)) drop-shadow(var(--filterDropShadow)) grayscale(var(--filterGrayscale)) hue-rotate(var(--filterHueRotate)) invert(var(--filterInvert)) opacity(var(--filterOpacity)) saturate(var(--filterSaturate)) sepia(var(--filterSepia));",
Expand Down Expand Up @@ -122,13 +126,27 @@ const withVariants: IBuildRulesets.Props = {
describe("BuildRulesets usecase", () => {
it("should not crash if nothing is provided", () => {
const build = BuildRulesets.create(basic);
const res = build.exec({ values: {} });
const res = build.exec({ values: {}, definitions: [] });
expect(res).toEqual([]);
});

it("should build from values and definitions", () => {
const build = BuildRulesets.create(basic);
const res = build.exec({
values: { width: { "20": "20px" } },
definitions: [{ classname: "height-sm", declarations: "height: 12px;" }],
});

expect(toString(res)).toEqual([
".w-20 { width: 20px; }",
".height-sm { height: 12px; }",
]);
});

it("should build font size rulesets", () => {
const build = BuildRulesets.create(basic);
const res = build.exec({
definitions: [],
values: {
fontSize: { "20": "20px", "2em": "2em", md: "16px/24px" },
},
Expand All @@ -144,6 +162,7 @@ describe("BuildRulesets usecase", () => {
it("should build flex grid rulesets", () => {
const build = BuildRulesets.create(basic);
const res = build.exec({
definitions: [],
values: {
flexGrid: { cols: 6 },
},
Expand All @@ -164,6 +183,7 @@ describe("BuildRulesets usecase", () => {
it("should build flex grid rulesets with gutters", () => {
const build = BuildRulesets.create(basic);
const res = build.exec({
definitions: [],
values: {
flexGrid: {
cols: 12,
Expand All @@ -172,6 +192,7 @@ describe("BuildRulesets usecase", () => {
},
},
});

// prettier-ignore
expect(toString(res)).toEqual([
".fxrow { display: flex; margin-left: -5px; margin-right: -5px; }",
Expand Down Expand Up @@ -200,6 +221,7 @@ describe("BuildRulesets usecase", () => {
const build = BuildRulesets.create(basic);

const res = build.exec({
definitions: [],
values: {
transform: {
custom: "translate(120px, 50%)",
Expand Down Expand Up @@ -260,6 +282,7 @@ describe("BuildRulesets usecase", () => {
const build = BuildRulesets.create(basic);

const res = build.exec({
definitions: [],
values: {
filterCompound: {},
filter: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export default class BuildRulesets {
);
});

dto.definitions.forEach((dto) => {
this.builder.addRulesetFromDTO(dto);
});

return this.builder.getResult();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default class StylesheetsController {
const rulesetsProps = this.io.getRulesetsBuildProps();
const rulesets = BuildRulesets.create(rulesetsProps).exec({
values: this.io.getRulesetsValues(),
definitions: this.io.getRulesetsDefinitions(),
});

const assetsProps = this.io.getAssetsGenerationProps();
Expand Down
2 changes: 2 additions & 0 deletions packages/rececss-core/src/3_adapters/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { IRuleset } from "src/1_entities/Ruleset";
import { IGenerateStylesheetAssets } from "../2_usecases/GenerateStylesheetAssets";
import { IBuildRulesets } from "../2_usecases/BuildRulesets";

export interface IInputOutput {
getAssetsGenerationProps(): IGenerateStylesheetAssets.Props;
getRulesetsBuildProps(): IBuildRulesets.Props;
getRulesetsValues(): IBuildRulesets.DTO["values"];
getRulesetsDefinitions(): IRuleset.DTO[];
getMediaQueries: () => Record<string, string>;
outputAssets(assets: { name: string; contents: string }[]): Promise<void>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { IRuleset } from "../../1_entities/Ruleset";
import { IBuildRulesets } from "../../2_usecases/BuildRulesets";

export interface Props {
Expand Down Expand Up @@ -35,6 +36,7 @@ export interface DTO {
values: CreatorFn<RawValues> | RawValues;
variants?: CreatorFn<Variants> | Variants;
associations?: CreatorFn<Associations> | Associations;
definitions?: IRuleset.DTO[];
}

type ValueOf<T> = T[keyof T];
Expand Down
10 changes: 10 additions & 0 deletions packages/rececss-core/src/4_infrastructures/config/Config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ describe("Config", () => {
expect(config.getVariantSeparator()).toBe(":");
});

test("definitions getter", () => {
const config = configBasic.create(dto);
expect(config.getRulesetDefinitions()).toEqual([
{
classname: "width-20px",
declarations: "width: 20px;",
},
]);
});

test("classnames getter", () => {
const classesConfig = configBasic.create({
output: { path: "" },
Expand Down
4 changes: 4 additions & 0 deletions packages/rececss-core/src/4_infrastructures/config/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ export default class Config {
return result;
}

getRulesetDefinitions() {
return this.dto.definitions || [];
}

private parseRuleValue(rule?: any): Record<string, string> {
if (!rule) return {};
return Object.keys(rule).reduce((acc, key) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,9 @@
import path from "path";
import IO from "./ConfigFileSystemIO";

const configDto = require("../../../tests/__fixtures__/rececss.config");
const writeFiles = jest.fn(() => Promise.resolve());

const configDto = {
output: {
path: "./website/styles",
filename: "rececss",
extension: "css",
splitByMedia: false,
purge: { content: ["./website/pages/**/*.js"] },
},
media: {
md: "only screen and (min-width: 768px)",
lg: "only screen and (min-width: 1024px)",
},
separator: {
media: ":",
variant: ":",
},
values: {},
};

describe("ConfigFileSystemIO", () => {
it("should return media queries", () => {
const io = IO.create(configDto, writeFiles);
Expand All @@ -42,13 +24,21 @@ describe("ConfigFileSystemIO", () => {
});
});

it("should return ruleset definitions", () => {
const io = IO.create(configDto, writeFiles);
const defs = io.getRulesetsDefinitions();
expect(defs).toEqual([
{ classname: "width-20px", declarations: "width: 20px;" },
]);
});

it("should return css processor input", () => {
const io = IO.create(configDto, writeFiles);
const input = io.getCSSProccesorInput();
expect(input).toEqual({ content: ["./website/pages/**/*.js"] });
});

it("should output assets by calling fs.writeFiles with proper filepaths", async () => {
it("should output assets by calling fs.writeFiles with proper filepaths", () => {
const io = IO.create(configDto, writeFiles);
io.outputAssets([{ name: "some", contents: "contents" }]);
expect(writeFiles).toHaveBeenCalledWith([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export default class ConfigFileSystemIO implements IInputOutput {
return this.config.getRulesetsValues();
}

getRulesetsDefinitions() {
return this.config.getRulesetDefinitions();
}

getRulesetsBuildProps() {
return {
classnamesMap: this.config.getRulesetsClassnames(),
Expand Down
6 changes: 6 additions & 0 deletions packages/rececss-core/tests/__fixtures__/rececss.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,10 @@ module.exports = {
variant: ":",
},
values: {},
definitions: [
{
classname: "width-20px",
declarations: "width: 20px;",
},
],
};
1 change: 1 addition & 0 deletions packages/rececss-core/tests/__mocks__/io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const ioMock: IInputOutput = {
outputAssets: jest.fn(),
getRulesetsBuildProps: jest.fn(),
getRulesetsValues: jest.fn(() => ({})),
getRulesetsDefinitions: jest.fn(() => []),
};

export default ioMock;

0 comments on commit 7581112

Please sign in to comment.