-
-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[core] Implement useTheme processor and runtime theme (#105)
- Loading branch information
1 parent
df6e7ef
commit ab5aabb
Showing
19 changed files
with
226 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true, | ||
}); | ||
|
||
exports.default = require('../processors/useTheme').UseThemeProcessor; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,3 @@ | ||
'use client'; | ||
/** | ||
* This package has it's own version of RtlProvider to avoid including | ||
* @mui/system in the bundle if someone is not using it. | ||
*/ | ||
import * as React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
type RtlContextType = boolean | undefined; | ||
|
||
type RtlProviderProps = { | ||
value?: RtlContextType; | ||
}; | ||
|
||
const RtlContext = React.createContext<RtlContextType>(false); | ||
|
||
function RtlProvider({ value, ...props }: RtlProviderProps) { | ||
return <RtlContext.Provider value={value ?? true} {...props} />; | ||
} | ||
|
||
RtlProvider.propTypes /* remove-proptypes */ = { | ||
// ┌────────────────────────────── Warning ──────────────────────────────┐ | ||
// │ These PropTypes are generated from the TypeScript type definitions. │ | ||
// │ To update them, edit the TypeScript types and run `pnpm proptypes`. │ | ||
// └─────────────────────────────────────────────────────────────────────┘ | ||
/** | ||
* @ignore | ||
*/ | ||
value: PropTypes.bool, | ||
} as any; | ||
|
||
export const useRtl = () => { | ||
const value = React.useContext(RtlContext); | ||
return value ?? false; | ||
}; | ||
|
||
export default RtlProvider; | ||
export * from '@mui/system/RtlProvider'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import type { Expression } from '@babel/types'; | ||
import { validateParams, type Params, type TailProcessorParams } from '@wyw-in-js/processor-utils'; | ||
import { type Replacements, type Rules } from '@wyw-in-js/shared'; | ||
import BaseProcessor from './base-processor'; | ||
|
||
export type Primitive = string | number | boolean | null | undefined; | ||
|
||
export type TemplateCallback = (params: Record<string, unknown> | undefined) => string | number; | ||
|
||
export class UseThemeProcessor extends BaseProcessor { | ||
constructor(params: Params, ...args: TailProcessorParams) { | ||
super([params[0]], ...args); | ||
validateParams(params, ['callee', ['call']], `Invalid use of ${this.tagSource.imported} tag.`); | ||
} | ||
|
||
build() { | ||
const cssText = '/* */'; | ||
const rules: Rules = { | ||
[this.asSelector]: { | ||
className: this.className, | ||
cssText, | ||
displayName: this.displayName, | ||
start: this.location?.start ?? null, | ||
}, | ||
}; | ||
const sourceMapReplacements: Replacements = [ | ||
{ | ||
length: cssText.length, | ||
original: { | ||
start: { | ||
column: this.location?.start.column ?? 0, | ||
line: this.location?.start.line ?? 0, | ||
}, | ||
end: { | ||
column: this.location?.end.column ?? 0, | ||
line: this.location?.end.line ?? 0, | ||
}, | ||
}, | ||
}, | ||
]; | ||
this.artifacts.push(['css', [rules, sourceMapReplacements]]); | ||
} | ||
|
||
doEvaltimeReplacement() { | ||
this.replacer(this.value, false); | ||
} | ||
|
||
doRuntimeReplacement() { | ||
const t = this.astService; | ||
const themeIdentifier = t.addDefaultImport(`${process.env.PACKAGE_NAME as string}/theme`); | ||
this.replacer(themeIdentifier, false); | ||
} | ||
|
||
get asSelector() { | ||
return this.className; | ||
} | ||
|
||
get value(): Expression { | ||
return this.astService.nullLiteral(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { ThemeArgs } from './theme'; | ||
|
||
export default function useTheme(): ThemeArgs extends { theme: any } ? ThemeArgs['theme'] : any; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export default function useTheme() { | ||
throw new Error( | ||
`${process.env.PACKAGE_NAME}: You were trying to call "useTheme" function without configuring your bundler. Make sure to install the bundler specific plugin and use it. @pigment-css/vite-plugin for Vite integration or @pigment-css/nextjs-plugin for Next.js integration.`, | ||
); | ||
} |
12 changes: 12 additions & 0 deletions
12
packages/pigment-css-react/src/utils/generateThemeSource.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type { Theme } from './extendTheme'; | ||
import { generateThemeTokens } from './generateCss'; | ||
|
||
export function generateThemeSource(theme?: Theme) { | ||
if (!theme) { | ||
return `export default {}`; | ||
} | ||
if (typeof theme.toRuntimeSource !== 'function') { | ||
return `export default ${JSON.stringify(generateThemeTokens(theme))};`; | ||
} | ||
return theme.toRuntimeSource.call(theme, theme); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
packages/pigment-css-react/tests/useTheme/fixtures/useTheme.input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { useTheme } from '../zero-styled'; | ||
|
||
export const Fade = React.forwardRef(function Fade(props, ref) { | ||
const theme = useTheme(); | ||
return <div style={{ backgroundColor: theme.palette.primary.main }} />; | ||
}); |
Empty file.
11 changes: 11 additions & 0 deletions
11
packages/pigment-css-react/tests/useTheme/fixtures/useTheme.output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import _default from '@pigment-css/react/theme'; | ||
export const Fade = React.forwardRef(function Fade(props, ref) { | ||
const theme = _default; | ||
return ( | ||
<div | ||
style={{ | ||
backgroundColor: theme.palette.primary.main, | ||
}} | ||
/> | ||
); | ||
}); |
45 changes: 45 additions & 0 deletions
45
packages/pigment-css-react/tests/useTheme/generateThemeSource.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { expect } from 'chai'; | ||
import { generateThemeSource } from '../../src/utils'; | ||
|
||
describe('Pigment CSS - generateThemeSource', () => { | ||
it('should export empty theme if theme is undefined', () => { | ||
expect(generateThemeSource()).to.equal(`export default {}`); | ||
}); | ||
|
||
it('should generate basic theme code with theme json', () => { | ||
const result = generateThemeSource({ | ||
vars: { | ||
palette: { | ||
primary: { | ||
main: 'red', | ||
secondary: 'blue', | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
expect(result).to.equal( | ||
`export default {"vars":{"palette":{"primary":{"main":"red","secondary":"blue"}}}};`, | ||
); | ||
}); | ||
|
||
it('should generate theme from toRuntimeSource method if present', () => { | ||
const result = generateThemeSource({ | ||
vars: { | ||
palette: { | ||
primary: { | ||
main: 'red', | ||
secondary: 'blue', | ||
}, | ||
}, | ||
}, | ||
toRuntimeSource(theme: any) { | ||
return `const theme = ${JSON.stringify(theme)};export default theme;`; | ||
}, | ||
}); | ||
|
||
expect(result).to.equal( | ||
`const theme = {"vars":{"palette":{"primary":{"main":"red","secondary":"blue"}}}};export default theme;`, | ||
); | ||
}); | ||
}); |
13 changes: 13 additions & 0 deletions
13
packages/pigment-css-react/tests/useTheme/useTheme.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import path from 'node:path'; | ||
import { runTransformation, expect } from '../testUtils'; | ||
|
||
describe('Pigment CSS - useTheme', () => { | ||
it('should replace useTheme call with the theme import', async () => { | ||
const { output, fixture } = await runTransformation( | ||
path.join(__dirname, 'fixtures/useTheme.input.js'), | ||
); | ||
|
||
expect(output.js).to.equal(fixture.js); | ||
expect(output.css).to.equal(fixture.css); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.