-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[zero] Add
useThemeProps
processor (#40648)
- Loading branch information
1 parent
2a29460
commit 2d39985
Showing
18 changed files
with
210 additions
and
30 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
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
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 was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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,8 @@ | ||
import useThemeProps from '../styles/useThemeProps'; | ||
|
||
export { default as styled } from '../styles/styled'; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
export function createUseThemeProps(name: string) { | ||
return useThemeProps; | ||
} |
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/createUseThemeProps').CreateUseThemePropsProcessor; |
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,5 @@ | ||
interface UseThemeProps { | ||
<Props>(params: { theme: Record<string, any>; props: Props; name: string }): Props; | ||
} | ||
|
||
export default function createUseThemeProps(theme: any): UseThemeProps; |
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,52 @@ | ||
import { internal_resolveProps as resolveProps } from '@mui/utils'; | ||
|
||
/** | ||
* Runtime function for creating `useThemeProps`. | ||
* In the codebase, the first argument will be a string that represent the component slug (should match one of the `theme.components.*`). | ||
* Then, the transformation will replace the first argument with the `defaultProps` object if provided. | ||
*/ | ||
export default function createUseThemeProps(nameOrDefaultProps) { | ||
return function useThemeProps({ props }) { | ||
if (typeof nameOrDefaultProps === 'string') { | ||
// if no default props provided in the theme, return the props as is. | ||
return props; | ||
} | ||
const defaultProps = nameOrDefaultProps; | ||
// The same logic as in packages/mui-utils/src/resolveProps.ts | ||
// TODO: consider reusing the logic from the utils package | ||
const output = { ...props }; | ||
|
||
Object.keys(defaultProps).forEach((propName) => { | ||
if (propName.toString().match(/^(components|slots)$/)) { | ||
output[propName] = { | ||
...defaultProps[propName], | ||
...output[propName], | ||
}; | ||
} else if (propName.toString().match(/^(componentsProps|slotProps)$/)) { | ||
const defaultSlotProps = defaultProps[propName] || {}; | ||
const slotProps = props[propName]; | ||
output[propName] = {}; | ||
|
||
if (!slotProps || !Object.keys(slotProps)) { | ||
// Reduce the iteration if the slot props is empty | ||
output[propName] = defaultSlotProps; | ||
} else if (!defaultSlotProps || !Object.keys(defaultSlotProps)) { | ||
// Reduce the iteration if the default slot props is empty | ||
output[propName] = slotProps; | ||
} else { | ||
output[propName] = { ...slotProps }; | ||
Object.keys(defaultSlotProps).forEach((slotPropName) => { | ||
output[propName][slotPropName] = resolveProps( | ||
defaultSlotProps[slotPropName], | ||
slotProps[slotPropName], | ||
); | ||
}); | ||
} | ||
} else if (output[propName] === undefined) { | ||
output[propName] = defaultProps[propName]; | ||
} | ||
}); | ||
|
||
return output; | ||
}; | ||
} |
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
68 changes: 68 additions & 0 deletions
68
packages/zero-runtime/src/processors/createUseThemeProps.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,68 @@ | ||
import { validateParams, IOptions as IBaseOptions } from '@linaria/tags'; | ||
import type { Expression, Params, TailProcessorParams } from '@linaria/tags'; | ||
import BaseProcessor from './base-processor'; | ||
import { valueToLiteral } from '../utils/valueToLiteral'; | ||
|
||
type IOptions = IBaseOptions & { | ||
themeArgs: { | ||
theme: { components?: Record<string, { defaultProps?: Record<string, unknown> }> }; | ||
}; | ||
}; | ||
|
||
export class CreateUseThemePropsProcessor extends BaseProcessor { | ||
componentName: string; | ||
|
||
constructor(params: Params, ...args: TailProcessorParams) { | ||
super(params, ...args); | ||
if (params.length > 2) { | ||
// no need to do any processing if it is an already transformed call or just a reference. | ||
throw BaseProcessor.SKIP; | ||
} | ||
validateParams(params, ['callee', 'call'], `Invalid use of ${this.tagSource.imported} tag.`); | ||
const [, callParam] = params; | ||
const [, callArg] = callParam; | ||
if (!callArg || callArg.ex.type !== 'StringLiteral') { | ||
throw new Error( | ||
`Invalid usage of \`createUseThemeProps\` tag, expected one string literal argument but got ${callArg?.ex.type}.`, | ||
); | ||
} | ||
this.componentName = callArg.ex.value; | ||
} | ||
|
||
// eslint-disable-next-line class-methods-use-this | ||
build(): void {} | ||
|
||
doEvaltimeReplacement(): void { | ||
this.replacer(this.value, false); | ||
} | ||
|
||
get value(): Expression { | ||
return this.astService.nullLiteral(); | ||
} | ||
|
||
doRuntimeReplacement(): void { | ||
const t = this.astService; | ||
|
||
const { themeArgs: { theme } = {} } = this.options as IOptions; | ||
if (!theme?.components?.[this.componentName]?.defaultProps) { | ||
return; | ||
} | ||
|
||
const useThemePropsImportIdentifier = t.addNamedImport( | ||
this.tagSource.imported, | ||
process.env.PACKAGE_NAME as string, | ||
); | ||
|
||
this.replacer( | ||
t.callExpression(useThemePropsImportIdentifier, [ | ||
valueToLiteral(theme.components[this.componentName].defaultProps), | ||
]), | ||
true, | ||
); | ||
} | ||
|
||
public override get asSelector(): string { | ||
// For completeness, this is not intended to be used. | ||
return `.${this.className}`; | ||
} | ||
} |
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
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