(react) add tokens.ts files handling

These files will be used to define the custom design tokens per components.
They are automatically aggregated by the packages/react/cunningham.ts file,
this is why handling typescript config file was important.
This commit is contained in:
Nathan Vasse
2023-01-04 15:52:24 +01:00
committed by NathanVss
parent 67dd0048d0
commit be1c9d000b
19 changed files with 147 additions and 29 deletions

View File

@@ -1,8 +1,10 @@
.c__button {
background-color: var(--c--colors--primary);
background-image: var(--c--theme--colors--primary-gradient);
padding: 8px 30px;
border-radius: 6px;
border-radius: var(--c--components--button--border-radius);
border: none;
box-shadow: var(--c--components--button--shadow);
color: white;
font-weight: bold;
cursor: pointer;
}

View File

@@ -1,12 +1,20 @@
import { describe, expect, it } from "vitest";
import { render, screen } from "@testing-library/react";
import React from "react";
import { buildTheme, loadTokens } from "tests/Theme";
import { Button } from "./index";
describe("<Button/>", () => {
it("renders", () => {
render(<Button />);
const button = screen.getByRole("button", { name: "<Button/>" });
render(<Button>Test button</Button>);
const button = screen.getByRole("button", { name: "Test button" });
expect(button.classList.contains("c__button")).toBe(true);
});
it("uses custom token", async () => {
await buildTheme();
const tokens = await loadTokens();
expect(tokens.components.button["border-radius"]).toBeDefined();
expect(tokens.components.button.shadow).toBeDefined();
});
});

View File

@@ -7,7 +7,9 @@ export default {
component: Button,
} as ComponentMeta<typeof Button>;
const Template: ComponentStory<typeof Button> = () => <Button />;
const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />;
export const Default = Template.bind({});
Default.args = {};
Default.args = {
children: "Amazing button",
};

View File

@@ -1,5 +1,7 @@
import React from "react";
import React, { PropsWithChildren } from "react";
export const Button = () => {
return <button className="c__button">{"<Button/>"}</button>;
interface Props extends PropsWithChildren {}
export const Button = ({ children }: Props) => {
return <button className="c__button">{children}</button>;
};

View File

@@ -0,0 +1,8 @@
import { DefaultTokens } from "@openfun/cunningham-tokens";
export const tokens = (defaults: DefaultTokens) => {
return {
"border-radius": "5px",
shadow: "0px 0px 10px 1px " + defaults.theme.colors.primary + ";",
};
};

View File

@@ -0,0 +1,7 @@
html {
--c--theme--colors--primary: #002d7f;
--c--theme--colors--primary-gradient: linear-gradient(90deg,#002d7f,#0069b3);
--c--theme--colors--secondary: #DA0000;
--c--components--button--border-radius: 5px;
--c--components--button--shadow: 0px 0px 10px 1px #002d7f;;
}

View File

@@ -0,0 +1 @@
export const tokens = {"theme":{"colors":{"primary":"#002d7f","primary-gradient":"linear-gradient(90deg,#002d7f,#0069b3)","secondary":"#DA0000"}},"components":{"button":{"border-radius":"5px","shadow":"0px 0px 10px 1px #002d7f;"}}};

View File

@@ -2,5 +2,6 @@
@import "@fontsource/roboto/400";
@import "@fontsource/roboto/700";
@import "@fontsource/roboto/900";
@import "cunningham-tokens";
@import '@openfun/cunningham-tokens/default-tokens';
@import './components/Button';

View File

@@ -0,0 +1,33 @@
import child_process from "child_process";
import path from "path";
/**
* Run the NPM script 'build-theme' in order to generate the tokens files ( cunningham-token.ts|css ).
* ( The purpose is mainly to generate the tokens files and then verify in tests that custom tokens defined in
* tokens.ts files are correctly taken into account. )
*/
export const buildTheme = (debug?: boolean) => {
const child = child_process.exec(
"cd " + path.join(__dirname, "..", "..") + " && yarn build-theme"
);
return new Promise<void>((resolve) => {
child.stdout?.on("data", (data) => {
// eslint-disable-next-line no-console
if (debug) console.log("stdout: " + data);
});
child.stderr?.on("data", (data) => {
// eslint-disable-next-line no-console
if (debug) console.log("stderr: " + data);
});
child.on("close", (code) => {
// eslint-disable-next-line no-console
if (debug) console.log("closing code: " + code);
resolve();
});
});
};
export const loadTokens = async () => {
const module = await import("../cunningham-tokens");
return module.tokens;
};