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
Wallogit.com
2017 © Pedro Peláez
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.classNamesis 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