-
Notifications
You must be signed in to change notification settings - Fork 78
feat: enhance layer configuration with composer support in StyleContext and useStyleRegister #224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,7 +52,13 @@ | |
|
||
export type HashPriority = 'low' | 'high'; | ||
|
||
export interface StyleContextProps { | ||
export type LayerComposer = (dependency: ReadonlySet<string>) => string; | ||
export type LayerConfig = { | ||
/** Define the hierarchical order here */ | ||
composer: LayerComposer; | ||
}; | ||
Comment on lines
+55
to
+59
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain类型命名冲突需要解决 在 建议重命名其中一个接口以避免冲突: -export type LayerConfig = {
+export type StyleLayerConfig = {
/** Define the hierarchical order here */
composer: LayerComposer;
}; 并相应更新所有引用。 🏁 Script executed: #!/bin/bash
# 验证是否存在 LayerConfig 类型冲突
rg -n "LayerConfig" --type ts Length of output: 372 修复:解决 在 请在
示例修改: --- a/src/StyleContext.tsx
+++ b/src/StyleContext.tsx
@@ -53,7 +53,7 @@ export type LayerComposer = (dependency: ReadonlySet<string>) => string;
-export type LayerConfig = {
+export type StyleLayerConfig = {
/** Define the hierarchical order here */
composer: LayerComposer;
};
@@ -87,7 +87,7 @@ export interface StyleProviderProps {
/** 启用层级模式时的配置 */
- layer?: LayerConfig;
+ layer?: StyleLayerConfig;
}
export const StyleProvider: React.FC<StyleProviderProps> = ({
@@ -103,7 +103,7 @@ export const StyleProvider: React.FC<StyleProviderProps> = ({
/** 如果传入布尔值,则使用默认 composer;若传入对象则按定义解析 */
- layer?: boolean | LayerConfig;
+ layer?: boolean | StyleLayerConfig;
children,
}) => { 完成重命名后,请确认相关导出和调用处(如统一导出的 🤖 Prompt for AI Agents
|
||
|
||
export interface StyleContextValue { | ||
autoClear?: boolean; | ||
/** @private Test only. Not work in production. */ | ||
mock?: 'server' | 'client'; | ||
|
@@ -77,38 +83,63 @@ | |
* Please note that `linters` do not support dynamic update. | ||
*/ | ||
linters?: Linter[]; | ||
/** Wrap css in a layer to avoid global style conflict */ | ||
layer?: boolean; | ||
/** | ||
* Wrap css in a layer to avoid global style conflict | ||
* @see [MDN-CSS Layer](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) | ||
*/ | ||
layer?: LayerConfig; | ||
} | ||
|
||
const StyleContext = React.createContext<StyleContextProps>({ | ||
export const defaultLayerComposer: LayerComposer = (dependency) => | ||
Array.from(dependency).join(); | ||
|
||
const noop = () => ``; | ||
|
||
const StyleContext = React.createContext<StyleContextValue>({ | ||
hashPriority: 'low', | ||
cache: createCache(), | ||
defaultCache: true, | ||
}); | ||
|
||
export type StyleProviderProps = Partial<StyleContextProps> & { | ||
children?: React.ReactNode; | ||
}; | ||
export interface StyleProviderProps | ||
extends Omit<Partial<StyleContextValue>, 'layer'> { | ||
layer?: boolean | LayerConfig; | ||
} | ||
|
||
export const StyleProvider: React.FC<StyleProviderProps> = (props) => { | ||
export const StyleProvider = ( | ||
props: React.PropsWithChildren<StyleProviderProps>, | ||
) => { | ||
const { children, ...restProps } = props; | ||
|
||
const parentContext = React.useContext(StyleContext); | ||
|
||
const context = useMemo<StyleContextProps>( | ||
const context = useMemo<StyleContextValue>( | ||
() => { | ||
const mergedContext: StyleContextProps = { | ||
const mergedContext: StyleContextValue = { | ||
...parentContext, | ||
}; | ||
|
||
(Object.keys(restProps) as (keyof StyleContextProps)[]).forEach((key) => { | ||
(Object.keys(restProps) as (keyof StyleContextValue)[]).forEach((key) => { | ||
const value = restProps[key]; | ||
if (restProps[key] !== undefined) { | ||
(mergedContext as any)[key] = value; | ||
} | ||
}); | ||
|
||
// Standardize layer | ||
const { layer } = mergedContext; | ||
if (typeof layer === 'boolean') { | ||
mergedContext.layer = layer | ||
? { composer: defaultLayerComposer } | ||
: { composer: noop }; | ||
} else if (typeof layer === 'object') { | ||
mergedContext.layer = { | ||
...layer, | ||
// Ensure composer is always a function | ||
composer: layer.composer ?? defaultLayerComposer, | ||
}; | ||
} | ||
|
||
const { cache } = restProps; | ||
mergedContext.cache = mergedContext.cache || createCache(); | ||
mergedContext.defaultCache = !cache && parentContext.defaultCache; | ||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -9,7 +9,7 @@ import type { Theme, Transformer } from '..'; | |||||||
import type Keyframes from '../Keyframes'; | ||||||||
import type { Linter } from '../linters'; | ||||||||
import { contentQuotesLinter, hashedAnimationLinter } from '../linters'; | ||||||||
import type { HashPriority } from '../StyleContext'; | ||||||||
import type { HashPriority, LayerComposer } from '../StyleContext'; | ||||||||
import StyleContext, { | ||||||||
ATTR_CACHE_PATH, | ||||||||
ATTR_MARK, | ||||||||
|
@@ -128,7 +128,9 @@ function injectSelectorHash( | |||||||
export interface ParseConfig { | ||||||||
hashId?: string; | ||||||||
hashPriority?: HashPriority; | ||||||||
layer?: LayerConfig; | ||||||||
layer?: LayerConfig & { | ||||||||
composer?: LayerComposer; | ||||||||
}; | ||||||||
path?: string; | ||||||||
transformers?: Transformer[]; | ||||||||
linters?: Linter[]; | ||||||||
|
@@ -333,15 +335,17 @@ export const parseStyle = ( | |||||||
if (!root) { | ||||||||
styleStr = `{${styleStr}}`; | ||||||||
} else if (layer) { | ||||||||
const { name, dependencies, composer } = layer; | ||||||||
// fixme: https://github.com/thysultan/stylis/pull/339 | ||||||||
if (styleStr) { | ||||||||
styleStr = `@layer ${layer.name} {${styleStr}}`; | ||||||||
styleStr = `@layer ${name} {${styleStr}}`; | ||||||||
} | ||||||||
|
||||||||
if (layer.dependencies) { | ||||||||
effectStyle[`@layer ${layer.name}`] = layer.dependencies | ||||||||
.map((deps) => `@layer ${deps}, ${layer.name};`) | ||||||||
.join('\n'); | ||||||||
if (dependencies) { | ||||||||
const dependency = new Set([...dependencies, name]); | ||||||||
const combinedDependencies = | ||||||||
composer?.(dependency) ?? Array.from(dependency).join(', '); | ||||||||
effectStyle[`@layer ${name}`] = `@layer ${combinedDependencies};`; | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
|
@@ -402,9 +406,10 @@ export default function useStyleRegister( | |||||||
transformers, | ||||||||
linters, | ||||||||
cache, | ||||||||
layer: enableLayer, | ||||||||
layer: ctxLayer, | ||||||||
} = React.useContext(StyleContext); | ||||||||
const tokenKey = token._tokenKey as string; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nitpick] Consider adding an inline comment to explain the rationale behind checking if 'composer' exists in ctxLayer to determine enableLayer. This will improve code clarity for future maintainers.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||||
const enableLayer = 'composer' in (ctxLayer || {}); | ||||||||
|
||||||||
const fullPath = [tokenKey]; | ||||||||
if (enableLayer) { | ||||||||
|
@@ -446,7 +451,12 @@ export default function useStyleRegister( | |||||||
const [parsedStyle, effectStyle] = parseStyle(styleObj, { | ||||||||
hashId, | ||||||||
hashPriority, | ||||||||
layer: enableLayer ? layer : undefined, | ||||||||
layer: enableLayer | ||||||||
? { | ||||||||
...layer!, | ||||||||
composer: ctxLayer!.composer, | ||||||||
} | ||||||||
: undefined, | ||||||||
path: path.join('-'), | ||||||||
transformers, | ||||||||
linters, | ||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
太复杂了,我们修复的话应该是让用户最简单的心智去处理。理论上来说,他们只要知道自己的上游依赖是什么就行了,而不用关心整体如何聚合出来。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
嗯嗯 get