Adding A Component

Creating folders and files

The project is divided in various sub-projects.
In ./components/, you'll find main sub-folders in which you'll create your components.
Component categorization follows the atomic design principle.
As such, you'll find the following folders inside sub-project folders:

  • Atoms: Basic building blocks and smallest, simplest component.
  • Molecules: Simlple interface elements (can be built with or contain atoms).
  • Organisms: Most complex elements. Can be built by assembling molecules or groups thereof. Could also contain other organisms
  • Pages: Contains all of the above, assembled into a functioning page that should show what a final production page will look like.
  • Frames: Used as a template to inject content into. Can be used for smaller components as well as for pages. Is never used directly as is, only exists through the content that populates it.

Your typical component creation will look like this:

	
	molecules
	└── account-selector
	   └── account-selector.njk
	   └── account-selector.config.js
	   └── _account-selector.scss
	   └── AccountSelector.js // optional
	

Create a folder with a component name, inside of which will be a config file, component file and styles file, all containing the component's desired name, as shown above.
See fractal docs for more.

Including Components

Use fractal's render functionality (% render "@component-name",{contextdata},true %). See fractal docs for more.

You can also define component frames that will be used as structural basis for other components.
Usage example

	
	// snet/frames/button/button.njk
	
		<button type="button"></button>
	
	// as a frame will be used in snet/atoms/btn-base like so
	// replace parentheses with accolades
	(% include "@button" %)
	// define variants in config based on options in original button frame file
	

Including static assets in component files

Use the | path filter to link static assets in templates (e.g: images/scripts/styles)

Usage example
	
	// replace parentheses with accolades
	
	<a class="(( namespace ))navTopbar__logo navbar-brand" href="#">
		<img src="(( (mediaPath + '/logos/logo-bcee.svg') | path ))" class="img-fluid" alt="">
	</a>
	
	

All path variables are included in ./components/components.config.js and are usable throughout every sub-project.

Certain components (buttons and/or links) can also receive additional attributes.
You could add an attributes loop to your base component, that you would define through its options upon component inclusion.

Usage Example:


	// replace all parentheses by accolades
	<button type="button" class="(( namespace ))accountSelector(% for mod in modifiers %) (( mod ))(% endfor %)(% for mod in classes %) (( mod ))(% endfor %)"(% for attrKey, attr in attrs %) (( attrKey ))="((attr))"(% endfor %)></button>


Next set up a config template file with the following content.


module.exports = {
	context: {

	},
	variants: [
		{
			name: "",
			context: {

			}
		}
	]
}

This file ALWAYS ends in .config.js.

CSS

Namespacing Components

This only applies to elements created by APART. Vendor overrides will NOT be namespaced.
The SCSS namespace is in assets/css/framework/settings/_custom-variables.scss (first variable in the file), and the HTML namespace in config/config.js to be found under projectMetaData.
The file name must start with an underscore (_) and contain only the component's name in lower snake case, WITHOUT the project namespace.

Naming Conventions

ABEM


// classes are written like so
.sds-blockName__elementName.-modifierName {}
// states are always written like so
.sds-blockName__elementName.-isState {}

Mixing with bootstrap classes

In some instances, you'll have to style an existing bootstrap component using custom classes.
Should this situation arise, you will still need to use the bootstrap specific state classes, as these are used by bootstrap's javascript.
As such, you'll have to write your component state like so:


// use bootstrap's default active class in such cases
.sds-bootstrap__component.active {}
// don't write it like this
.sds-bootstrap__component.-isActive {}

Javascript

If JS functionality is needed for a specific component, and cannot be done through Bootstrap's components' JS, please add a JS class to the component folder and import it into assets/js/main.js


export default class AccountSelector {

	constructor() {

	}

}


Adding component resources

Resources are added through each component's config. Base resources are defined in the sub-project folder's master config file whose config all components will inherit.

All Paths are relative to the public folder.


// snet/snet.config.js
stylesResources: {
			0: {
				inAssets: false,
				resource: "https://clients.apart.lu/bcee/snet-styles-new/css/styles.css"
			},
			1: {
				inAssets: false,
				resource: "/libs/plyr/plyr.css"
			},
			2: {
				inAssets: false,
				resource: "/libs/plyr3/plyr.css",
			},
			3: {
				resource: "/snet.css"
			}
		},
		libsResources: [
			"jquery/jquery-3.1.0.min.js",
			"bootstrap/bootstrap.min.js",
			"bodymovin/bodymovin.min.js",
			"cropper/cropper.min.js",
			"plyr/plyr.js",
			"plyr3/plyr.js",
			"introjs/intro.min.js",
		],
		scriptsResources: []

Adding a new page

Use the nunjuck's extend functionality


// replace paretheses with accolades
(% extends "@snet-frame" %)

Add options needed for page variants. Look at pages.config.js


module.exports = {
	status: "ready",
	context: {
		noMenu: true,
		frameModifiers: ["-noMenu","-contentCentered"]
	}
}

Creating additional layouts

Include any and all new layouts in the _layouts folder located at the root of the components directory.