Skip to content

Commit

Permalink
feat: add <StyleDictionaryStyle> component
Browse files Browse the repository at this point in the history
  • Loading branch information
Robbert committed Oct 17, 2024
1 parent 76704c7 commit b332aa1
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/light-tables-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nl-design-system-unstable/theme-toolkit": minor
---

Add `<StyleDictionaryStyle>` component.
2 changes: 2 additions & 0 deletions packages/theme-toolkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@amsterdam/design-system-react": "0.11.0",
"@babel/plugin-transform-runtime": "7.24.7",
"@babel/preset-react": "7.24.7",
"@bundled-es-modules/memfs": "4.9.4",
"@dynamize/color-utilities": "1.0.11",
"@jest/globals": "29.7.0",
"@rollup/plugin-babel": "6.0.4",
Expand Down Expand Up @@ -154,6 +155,7 @@
"rimraf": "6.0.1",
"rollup": "4.19.2",
"rollup-plugin-peer-deps-external": "2.2.4",
"style-dictionary": "4.0.1",
"ts-jest": "29.2.4",
"tsx": "4.17.0",
"typescript": "5.5.4"
Expand Down
36 changes: 36 additions & 0 deletions packages/theme-toolkit/src/StyleDictionaryStyle.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-env jest */

import { describe, expect, it } from '@jest/globals';
import { StyleDictionaryStyle } from './StyleDictionaryStyle';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom';

describe('StyleDictionaryStyle', () => {
const simpleTree = {
example: {
button: {
color: {
value: 'red',
},
},
},
};

it('renders a HTML style element', () => {
const { container } = render(<StyleDictionaryStyle tokens={simpleTree}></StyleDictionaryStyle>);

const style = container.querySelector('style');

expect(style).toBeInTheDocument();
});

it('renders a class name selector', () => {
const { container } = render(
<StyleDictionaryStyle tokens={simpleTree} selector=".my-theme"></StyleDictionaryStyle>,
);

const style = container.querySelector('style');

expect(style).toContain('.my-theme');
});
});
60 changes: 60 additions & 0 deletions packages/theme-toolkit/src/StyleDictionaryStyle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import StyleDictionary from 'style-dictionary';
import memfs from '@bundled-es-modules/memfs';
import type { PropsWithChildren } from 'react';
import { useState, useEffect } from 'react';

const styleDictionaryConversion = async (tokens: any, selector?: string): Promise<string> => {
const { Volume } = memfs;
const vol = new Volume();
const sd = new StyleDictionary(
{
tokens,
platforms: {
css: {
transforms: ['name/kebab'],
transformGroup: 'css',
files: [
{
destination: 'variables.css',
format: 'css/variables',
options: {
selector,
outputReferences: true,
},
},
],
},
},
},
// typeof process !== 'undefined' ? { volume: vol } : {},
);

let css = '';

await sd.buildAllPlatforms();

try {
css = vol.readFileSync('/variables.css').toString('utf-8');
} catch (e) {
console.error(e);
}

return css;
};

export interface StyleDictionaryStyleProps {
tokens: any;
selector?: string;
}

export const StyleDictionaryStyle = ({ tokens, selector = ':root' }: PropsWithChildren<StyleDictionaryStyleProps>) => {
const [css, setCss] = useState('');

useEffect(() => {
styleDictionaryConversion(tokens, selector).then((css) => {
setCss(css);
}, console.error);
}, [tokens]);

return <style dangerouslySetInnerHTML={{ __html: css }}></style>;
};
5 changes: 5 additions & 0 deletions packages/theme-toolkit/src/style-dictionary.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// TODO: Make `"moduleResolution": "Bundler"` work in `tsconfig.json`
declare module 'style-dictionary' {
declare const StyleDictionary: any;
export default StyleDictionary;
}
25 changes: 8 additions & 17 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b332aa1

Please sign in to comment.