Skip to content

Commit

Permalink
feat: support override token (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
zombieJ authored Mar 21, 2022
1 parent 012efb3 commit a9ca392
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 13 deletions.
22 changes: 15 additions & 7 deletions src/useCacheToken.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface Option {
* This is used to generate different hashId even same derivative token for different version.
*/
salt?: string;
override?: object;
}

const tokenKeys = new Map<string, number>();
Expand Down Expand Up @@ -60,30 +61,37 @@ export default function useCacheToken<
theme: Theme<any, any>,
tokens: Partial<DesignToken>[],
option: Option = {},
): [DerivativeToken, string] {
const { salt = '' } = option;
): [DerivativeToken & { _tokenKey: string }, string] {
const { salt = '', override = {} } = option;

// Basic
const mergedToken = Object.assign({}, ...tokens);
const tokenStr = flattenToken(mergedToken);
const overrideTokenStr = flattenToken(override);

const cachedToken = useGlobalCache<
[DerivativeToken & { _tokenKey: string }, string]
>(
'token',
[salt, tokenStr],
[salt, tokenStr, overrideTokenStr],
() => {
const derivativeToken = theme.getDerivativeToken(mergedToken);

// Merge with override
const mergedDerivativeToken = {
...derivativeToken,
...override,
};

// Optimize for `useStyleRegister` performance
const tokenKey = token2key(derivativeToken, salt);
derivativeToken._tokenKey = tokenKey;
const tokenKey = token2key(mergedDerivativeToken, salt);
mergedDerivativeToken._tokenKey = tokenKey;
recordCleanToken(tokenKey);

const hashId = `css-${hash(tokenKey)}`;
derivativeToken._hashId = hashId; // Not used
mergedDerivativeToken._hashId = hashId; // Not used

return [derivativeToken, hashId];
return [mergedDerivativeToken, hashId];
},
(cache) => {
// Remove token will remove all related style
Expand Down
63 changes: 59 additions & 4 deletions tests/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import * as React from 'react';
import { mount } from 'enzyme';
import classNames from 'classnames';
import { Theme, useCacheToken, useStyleRegister, StyleProvider } from '../src';
import {
Theme,
useCacheToken,
useStyleRegister,
StyleProvider,
createCache,
} from '../src';
import type { CSSInterpolation } from '../src';

interface DesignToken {
Expand Down Expand Up @@ -48,7 +54,7 @@ describe('csssinjs', () => {
});

const Box = ({ propToken = baseToken }: { propToken?: DesignToken }) => {
const [token] = useCacheToken(theme, [propToken]);
const [token] = useCacheToken<DerivativeToken>(theme, [propToken]);

useStyleRegister({ theme, token, path: ['.box'] }, () => [
genStyle(token),
Expand Down Expand Up @@ -132,7 +138,7 @@ describe('csssinjs', () => {
});

const Nest = () => {
const [token] = useCacheToken(theme, [baseToken]);
const [token] = useCacheToken<DerivativeToken>(theme, [baseToken]);

useStyleRegister({ theme, token, path: ['.parent'] }, () => [
genStyle(token),
Expand All @@ -153,7 +159,7 @@ describe('csssinjs', () => {
});

it('serialize nest object token', () => {
const TokenShower = () => {
const TokenShower = (): any => {
const [token] = useCacheToken(theme, [
{
nest: {
Expand Down Expand Up @@ -204,4 +210,53 @@ describe('csssinjs', () => {

wrapper.unmount();
});

describe('override', () => {
const genStyle = (token: DerivativeToken): CSSInterpolation => ({
'.box': {
width: 93,
lineHeight: 1,
backgroundColor: token.primaryColor,
},
});

const Box = ({
override,
}: {
propToken?: DesignToken;
override: object;
}) => {
const [token] = useCacheToken<DerivativeToken>(theme, [baseToken], {
override,
});

useStyleRegister({ theme, token, path: ['.box'] }, () => [
genStyle(token),
]);

return <div className="box" />;
};

it('work', () => {
const Demo = () => (
<StyleProvider cache={createCache()}>
<Box
override={{
primaryColor: '#010203',
}}
/>
</StyleProvider>
);

const wrapper = mount(<Demo />);

const styles = Array.from(document.head.querySelectorAll('style'));
expect(styles).toHaveLength(1);

const style = styles[0];
expect(style.innerHTML).toContain('background-color:#010203;');

wrapper.unmount();
});
});
});
4 changes: 2 additions & 2 deletions tests/server.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import * as React from 'react';
import { render, unmountComponentAtNode, hydrate } from 'react-dom';
import { hydrate } from 'react-dom';
import { renderToString } from 'react-dom/server';
import { mount } from 'enzyme';
import {
Theme,
useCacheToken,
CSSInterpolation,
useStyleRegister,
StyleProvider,
extractStyle,
createCache,
} from '../src';
import type { CSSInterpolation } from '../src';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import canUseDom from 'rc-util/lib/Dom/canUseDom';

Expand Down

0 comments on commit a9ca392

Please sign in to comment.