-
Notifications
You must be signed in to change notification settings - Fork 21
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
feat: injector utility for the archetype and build config to override the one in X #1258
Merged
annacv
merged 2 commits into
main
from
feature/EMP-1613-add-css-injector-to-archetype-utils
Aug 8, 2023
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
packages/x-archetype-utils/src/__tests__/css-injector.spec.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,50 @@ | ||
import { CssInjector } from '../css-injector/css-injector'; | ||
import { WindowWithInjector } from '../css-injector/css-injector.types'; | ||
|
||
describe('Test custom css injector', () => { | ||
beforeEach(() => { | ||
delete (window as WindowWithInjector).xCSSInjector; | ||
}); | ||
|
||
it('reuses the same instance between initializations', () => { | ||
const injector1 = new CssInjector(); | ||
const injector2 = new CssInjector(); | ||
|
||
expect(injector1 === injector2).toBe(true); | ||
}); | ||
|
||
it('can be appended to the window under xCSSInjector', () => { | ||
const injector = new CssInjector(true); | ||
const windowCssInjector = (window as WindowWithInjector).xCSSInjector; | ||
|
||
expect(injector === windowCssInjector).toBe(true); | ||
}); | ||
|
||
it('can set the host element that will receive the styles', () => { | ||
const injector = new CssInjector(); | ||
const domElement = document.createElement('div'); | ||
|
||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore, | ||
expect(injector.host).toBe(undefined); | ||
|
||
injector.setHost(domElement); | ||
|
||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
expect(injector.host).toBe(domElement); | ||
}); | ||
|
||
it('adds styles string to the set host', () => { | ||
const injector = new CssInjector(); | ||
const domElement = document.createElement('div'); | ||
const styles = { | ||
source: "* { background: 'red' }" | ||
}; | ||
|
||
injector.setHost(domElement); | ||
injector.addStyle(styles); | ||
|
||
expect(domElement.getElementsByTagName('style')[0].textContent).toBe(styles.source); | ||
}); | ||
}); |
10 changes: 10 additions & 0 deletions
10
packages/x-archetype-utils/src/build/rollup/rollup.config.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,10 @@ | ||
export const rollupCssInjectorConfig = { | ||
replace: { | ||
// Replace X CSS injector by our custom one. | ||
'addStyle(id, style);': 'window.xCSSInjector.addStyle(style);', | ||
delimiters: ['', ''] | ||
}, | ||
styles: { | ||
mode: ['inject', (varname: string) => `window.xCSSInjector.addStyle({ source: ${varname} });`] | ||
} | ||
}; |
88 changes: 88 additions & 0 deletions
88
packages/x-archetype-utils/src/css-injector/css-injector.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,88 @@ | ||
import { WindowWithInjector, XCSSInjector } from './css-injector.types'; | ||
|
||
/** | ||
* Instance of the injector that will be used across all the initializations. | ||
*/ | ||
let instance: CssInjector | null = null; | ||
|
||
/** | ||
* Custom CSS injector that allows to inject styles into a host element. | ||
* | ||
* @public | ||
*/ | ||
export class CssInjector implements XCSSInjector { | ||
protected host!: Element | ShadowRoot; | ||
protected stylesQueue: string[] = []; | ||
|
||
/** | ||
* Initializes the instance of the injector if it's not already initialized and sets it in the | ||
* window object if it's required. | ||
* | ||
* @param setInWindow - Whether to set the injector instance in the window object. | ||
*/ | ||
public constructor(setInWindow = true) { | ||
if (!(instance instanceof CssInjector)) { | ||
// eslint-disable-next-line @typescript-eslint/no-this-alias | ||
instance = this; | ||
} | ||
|
||
if (setInWindow) { | ||
this.setInWindow(); | ||
} | ||
|
||
return instance; | ||
} | ||
|
||
/** | ||
* Adds the styles to the host element. | ||
* | ||
* @param styles - The styles to be added. | ||
*/ | ||
addStyle(styles: { source: string }): void { | ||
this.stylesQueue.push(styles.source); | ||
if (this.host) { | ||
this.stylesQueue.forEach(styles => { | ||
const styleTag = document.createElement('style'); | ||
styleTag.textContent = styles; | ||
this.host.appendChild(styleTag); | ||
}); | ||
this.stylesQueue = []; | ||
} | ||
} | ||
|
||
/** | ||
* Sets the host element. | ||
* | ||
* @param host - The host element. | ||
*/ | ||
setHost(host: Element | ShadowRoot): void { | ||
this.host = host; | ||
} | ||
|
||
/** | ||
* Sets the injector instance in the window object. | ||
*/ | ||
setInWindow(): void { | ||
if (typeof window !== 'undefined' && instance) { | ||
(window as WindowWithInjector).xCSSInjector = instance; | ||
} | ||
} | ||
|
||
/** | ||
* Checks if the injector instance is in the window object. | ||
* | ||
* @returns Whether the injector instance is in the window object. | ||
*/ | ||
isInWindow(): boolean { | ||
return typeof window === 'undefined' | ||
? false | ||
: (window as WindowWithInjector).xCSSInjector === instance; | ||
} | ||
} | ||
|
||
/** | ||
* Instance of the injector. | ||
* | ||
* @public | ||
*/ | ||
export const cssInjector = new CssInjector(typeof window !== 'undefined'); |
12 changes: 12 additions & 0 deletions
12
packages/x-archetype-utils/src/css-injector/css-injector.types.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 @@ | ||
export interface XCSSInjector { | ||
/** Function that will add the styles to the host. */ | ||
addStyle: (styles: { source: string }) => void; | ||
/** Function setting the host for the injector. */ | ||
setHost: (el: Element | ShadowRoot) => void; | ||
/** Set injector instance in the window object. */ | ||
setInWindow: () => void; | ||
/** Check if the instance is set in the window object. */ | ||
isInWindow: () => boolean; | ||
} | ||
|
||
export type WindowWithInjector = Window & { xCSSInjector?: XCSSInjector }; |
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,3 +1,6 @@ | ||
export * from './i18n/i18n.plugin'; | ||
export * from './i18n/i18n.types'; | ||
export * from './build/webpack/webpack.config'; | ||
export * from './build/rollup/rollup.config'; | ||
export * from './css-injector/css-injector'; | ||
export * from './css-injector/css-injector.types'; |
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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
👀
console.log
should be there?