dev-master
9999999-devCSS Modules for Atomic.Fusion
GPL-3.0
The Requires
v2.0.0
2.0.0.0CSS Modules for Atomic.Fusion
GPL-3.0
The Requires
v1.0.0
1.0.0.0CSS Modules for Atomic.Fusion
GPL-3.0
The Requires
CSS Modules for Atomic.Fusion
CSS Modules for Atomic.Fusion, (*1)
Atomic.Fusion enables you to implement a frontend component architecture in Neos.Fusion. In similar environments (like React or Vue.js), CSS Modules have been proven to be a robust solution to avoid CSS global namespace issues and to make your styles portable alongside your components., (*2)
To enable this technology felt like a natural extension to the ecosystem of Atomic.Fusion., (*3)
In short: CSS Modules convert your CSS class names and other global
identifiers (like @keyframes
) into unique identifiers. When processing your CSS files, a JSON file is created, that
maps the original class name to the new unique one., (*4)
This way it is ensured, that you can always use speaking identifiers that make sense in the context of your component, without having to worry about potential global naming conflicts., (*5)
PackageFactory.AtomicFusion.CssModules helps you to include those *.json files at the right place. It expects them to be present alongisde your Fusion components already - it won't generate them., (*6)
In order to generate CSS Module files, you have to configure your frontend build pipeline accordingly. An example of how this could look like is given in the next section., (*7)
The following describes an example setup for postcss and postcss-modules. This is not the only way to create such a setup. For further information on this, I suggest you have a look at the postcss-cli and postcss-modules repositories., (*8)
CSS modules require Node JS and two essential dependencies. Make sure, Node JS is available to your set up and that
you have a valid package.json
file at the root of your repository (or whereever you prefer it to reside)., (*9)
Then install the following packages:, (*10)
yarn add --dev postcss postcss-modules
This example also uses postcss-cli
:, (*11)
yarn add --dev postcss-cli
Then create a postcss.config.js
in the same directory as your package.json
:, (*12)
module.exports = { plugins: [ require('postcss-modules') ] }
Create a Makefile containing a recipe for building your CSS in the same directory as your package.json
:, (*13)
SHELL=/bin/bash export PATH := $(PATH):./node_modules/.bin export SITE_PACKGE_DIR="./Packages/Sites/Vendor.Site" build-css: # Build CSS with postcss postcss \ ${SITE_PACKGE_DIR}/Resources/Private/Fusion/**/*.css \ --dir ${SITE_PACKGE_DIR}/Resources/Public/Styles/temp # Concat all built CSS files cat ${SITE_PACKGE_DIR}/Resources/Public/Styles/temp/* > ${SITE_PACKGE_DIR}/Resources/Public/Styles/main.css # Remove temporary CSS files rm -rf ${SITE_PACKGE_DIR}/Resources/Public/Styles/temp
When you run make build-css
, all *.css files you have placed alongside your *.fusion component files will
afterwards be accompanied by a corresponding *.css.json
file containing the map mentioned above., (*14)
Consider the following css file (let's say Vendor.Site/Resources/Private/Fusion/MyComponent/MyComponent.css
):, (*15)
.myComponent { display: block; } .isActive { background-color: blue; }
After running make build-css
, a file Vendor.Site/Resources/Private/Fusion/MyComponent/MyComponent.css.json
should
appear., (*16)
In your Vendor.Site/Resources/Private/Fusion/MyComponent/MyComponent.fusion
file, you can now access the class names
like this:, (*17)
prototype(Vendor.Site:MyAwesomeComponent) < prototype(PackageFactory.AtomicFusion:Component) { # Fusion renderer = Neos.Fusion:Tag { attributes.class = ${AtomicFusion.classNames(styles.myComponent, props.isActive && styles.isActive)} } # AFX renderer = afx` <div class={AtomicFusion.classNames( styles.myComponent, props.isActive && styles.isActive )} > </div> ` }
Notice that within your components renderer
path, you can now access a special styles
context, that contains the
class name map., (*18)
Side note:
AtomicFusion.classNames
is a helper method to concatenate class names conditionally. More on this can found in the Atomic.Fusion main repository., (*19)
Fusion actually holds no information about the file a prototype is defined in. So, to enable the discovery of files put alongside those component *.fusion files, we need to configure a lookup pattern:, (*20)
PackageFactory: AtomicFusion: CssModules: tryFiles: - resource://{packageKey}/Private/Fusion/{componentPath}.css.json
With the above configuration the CSS module file for the prototype prototype(Vendor.Site:MyAwesomeComponent)
will be
assumed as resource://Vendor.Site/Private/Fusion/MyAwesomeComponent.css.json
., (*21)
{packageKey}
and {componentPath}
are variables that will be replaced with runtime information of the respective
fusion prototype., (*22)
The following variables are considered:, (*23)
{prototypeName}
- The entire prototype name{packageKey}
- The part of the prototype name before the :
{componentName}
- The part of the prototype name after the :
{componentBaseName}
- The last part of the componentName, if seperated by dots (for Vendor.Site:Atom.Button
that would be: Button
){componentPath}
- Similar to {componentName}
with all dots being replaced by Directory Separators.By default, the package looks at the following patterns:, (*24)
resource://{packageKey}/Private/Fusion/{componentPath}.css.json resource://{packageKey}/Private/Fusion/{componentPath}/{componentBaseName}.css.json resource://{packageKey}/Private/Fusion/{componentPath}/style.css.json resource://{packageKey}/Private/Fusion/{componentPath}/Style.css.json resource://{packageKey}/Private/Fusion/{componentPath}/styles.css.json resource://{packageKey}/Private/Fusion/{componentPath}/Styles.css.json resource://{packageKey}/Private/Fusion/{componentPath}/index.css.json resource://{packageKey}/Private/Fusion/{componentPath}/Index.css.json resource://{packageKey}/Private/Fusion/{componentPath}/component.css.json resource://{packageKey}/Private/Fusion/{componentPath}/Component.css.json
Recently, the native component prototype Neos.Fusion:Component
has arrived in the Neos.Fusion core. Unfortunately,
this package won't work with this new prototype and relies on PackageFactory.AtomicFusion:Component
to be present., (*25)
This will likely change in the future, either through this package or a PR to Neos.Fusion., (*26)
If you still want to use this package with an existing code base, that relies on Neos.Fusion:Component
, you could
replace the Neos.Fusion:Component
standard implementation with the one for PackageFactory.AtomicFusion:Component
:, (*27)
prototype(Neos.Fusion:Component) { @class = 'PackageFactory\\AtomicFusion\\FusionObjects\\ComponentImplementation' }
PackageFactory.AtomicFusion:Component
is fully compatible to Neos.Fusion:Component
, but you should be nonetheless
aware:, (*28)
THIS IS NOT THE JEDI WAY!, (*29)
see LICENSE.md, (*30)
CSS Modules for Atomic.Fusion
GPL-3.0
CSS Modules for Atomic.Fusion
GPL-3.0
CSS Modules for Atomic.Fusion
GPL-3.0