acinguiuxplug
v0.0.2
Published
Ultra lightweight website frontend for Oneacinguiux
Downloads
6
Readme
acinguiuxplug
Introduction
acinguiuxplug is:
- An ultra lightweight website frontend for Oneacinguiux.
- A collection of Preact components split into Organisms, Molecules and Atoms.
- An implementation of acinguiux Design System suited for websites. It attepmts to follow SDS as closely as possible without sacrifising performance and the consistentcy of the design.
- An SPA. For each HTML page (e.g. foo.html), the router pulls the corresponding data file (foo.model.json) and passes it onto renderer to render the page using Organisms.
Latest version:
- https://acinguiuxplug.vercel.app/amidoc.html - breakdown of Atoms, Molecules and Organisms.
- https://acinguiuxplug.vercel.app/en_gb.html - Demo site.
Getting started
- Check out this repository.
- Run
npm cito install dependencies. - Run
npm startto launch an interactive dev server. It is fast. - Visit
http://localhost:3000.
Working with GitHub
Please refer to https://github.com/sede-x/oneacinguiux-roadmap/blob/master/doc/guides/working-with-github.md.
Code structure
acinguiux-acinguiuxplug-frontend
src
content # Demo content.
assets # Demo assets.
data # Helpers for "lorem ipsum" data.
pages # Demo pages.
themes # CSS themes.
main # Application sources.
atoms
molecules
organisms
misc # Remnants of the legacy structure - to be refactored.
shared # Shared code / libs.
...
renderer.js # Page and component renderer.
use-link.js # Link handler.
index.js # Main entry point.
test
cases
screenshots # Reference screenshots for layout tests.
utils # Test utils.
tools # Build tools.
target
playwright # Playwright output, including screenshots and coverage report.
site # Static demo site goes here.Models
Each model.json is a nested object called Component Model. It is exactly the same for each component and is rendered as Organism.
Component Model:
{
// Presentation
id: '_789'
organism: 'PromoSimple', // The name of the organism to use for rendering
color: 'red', // The color used (from the available palette)
colspan: 12, // Number of columns (from 12 available) to take
colstart: 1, // The column to start
// Data
model: ContentModel,
// Nested children
children: [ComponentModel]
}Content Model:
{
title: '',
text: 'Lorem ipsum dolor sit amet',
image: AssetModel,
video: AssetModel,
links: [LinkModel, ...],
tags: [LinkModel, ...],
date: 'yyyy-mm-ddThh:mm:ss.SSSZ'
}Link Model:
{
name: 'This is a link label',
value: '/foo/bar.html',
icon: 'default_card',
selected: false,
children: [LinkModel, LinkModel, LinkModel] // Links can be nested
}Asset model:
{
src: '/foo/bar.jpeg',
alt: 'Alternative image text',
caption: 'This is image caption',
autoplay: false, // Used only for videos
width: 1920,
height: 1080
}Example implementation:
{
organism: "Page",
model: {
title: "Organisms",
text: "This is a first level page.",
tags: [],
date: "2022-03-02T12:12:00.001Z",
// Page utilises links as name-value pairs in order to provide additional metadata.
// This is done to avoid creating a bespoke model just for the page.
links: [{
name: "canonical",
value: "/develop/en_gb/organisms.html"
},{
name: "errorUrl",
value: "/develop/en_gb/error.html"
},{
// A list of slash-separated page names, starting with the home page.
name: "hierarchy",
value: "en_gb/organisms"
},{
name: "homeTitle",
value: "Home"
},{
name: "homeUrl",
value: "/develop/en_gb.html"
},{
name: "locale",
value: "en_GB"
},{
// Title is appended with " | <HOME_NAME>" for all pages except the home page.
name: "title",
value: "Organisms | Home"
},{
name: "textDirection",
value: "ltr"
},{
// The last fragment of the page's cq:template property.
name: "template",
value: "home"
},{
name: "externalDisclaimerText",
value: "This is the External Disclaimer text configured for demo en-gb site using inherited Page Properties."
},{
name: "crossDomainDisclaimerText",
value: "This is the Cross-Domain External Disclaimer text configured for demo en-gb site using inherited Page Properties."
},{
name: "themeMode"
},
{
"name": "lastModified",
"value": "2020-10-01T00:00:00.002Z"
},{
name: "themeName",
value: "base"
},{
name: "themePath",
value: "/develop/etc.clientlibs/acinguiuxplug/clientlibs/theme-base"
},{
name: "themeCss",
value: "/develop/etc.clientlibs/acinguiuxplug/clientlibs/theme-base/theme-base.min.ACSHASH715dbdcca7310384d42ead274dd3f735.css"
},{
// List of alternate content in a different language.
// Content is considered alternate if the same path exists under a different homepage of the same site.
name: "alternate",
children: [{
name: "ar-sa",
value: "/develop/ar_sa/organisms.html"
}]
}]
}
}Working with the code
Overview
Coding principles:
- YAGNI and KISS. No features "just in case". Overdesign is discouraged.
- Separation of Concerns; no arbitrary inter-dependencies or unnecessary coupling.
- Features are added only if it makes sense for the product as a whole rather than to please a single stakeholder (this includes the PO).
- The data structure is sacred and must not be changed (or else, expect the Spanish Inquisition).
- Hacks are a crime.
- If a fix makes the code more complex, it is probabbly a bad fix.
Common NPM tasks:
npm start # Build the project (non-minified with source maps)
# and start a local web server over target/site folder.
npm build # Build the project for production (minified).
npm test # Run tests locally.
npm run docker npm test # Run tests in Docker (with screenshot comparison).
npm run docker:build # Build Docker container (run once before the above).
npm run docker # Start Docker bash (useful for debugging tests).
npm run report-coverage # Report code coverage after test run.
npm run lint # Lint JS (standard) and MD (markdownlint).Adding a new Organism:
- Add an Organism to the library (under
acinguiux-acinguiuxplug-frontend/src/main/code/organisms). - Add entry to
matter.jsto expose it. - Add demo content page (should feature all possible variants of the organism).
- Add Playwright test and a reference screenshots.
- Add a Markdown documentation.
Frontend rules:
- Hyperscript is used in favour of JSX.
- Colors must work everywhere.
- Styles must be direction agnostic (work in both LTR and RTL).
Validation
- Each organism must validate the Content Model via the
useModel()helper function. - The
propsshould always be passed to the outer-most element. This allows injecting additional data properties (such as color, variant, placeholder content, etc).
Example code:
import useModel from '../shared/use-model.js'
function MyOrganism(props) {
// The useModel() sanitizes the model and makes sure it has all the fields.
const model = useModel(props, mdl => {
// This is where validation happens.
// Provide defaults here.
mdl.text = mdl.text || 'Here you can specify default content'
// Return true for valid model.
return mdl.title
)
// Do not render if validation fails.
if (!model) {
return null
}
// Pass props to the wrapper.
return h(Div, props, [
h(SomeAtom),
h(SomeMolecule, model)
// ...
])
}Demo content
- Demo content is generated from JavaScript source files inside
/src/main/content/pages. - Source files follow the nested structure of the Component Model.
- The output is
.htmland.model.jsonfiles.
I18n
Static text translations are resolved by t() function (see i18n.js). Translations are provided on the homepage level via .acinguiuxi18n.json data file (en_gb.acinguiuxi18n.json). It is loaded only once and then used throughout the site visit.
Testing
Testing is implemented in Playwright and are run in Chromium. They do compare screenshots, which works only in a Docker container. To build Docker container run npm run docker:build.
Web Components
Only generic web components should be added to this repository (e.g. standalone-table, rio-iframe). Everything else that is specific to a single site and/or is a one-off task should be implemented externally, in https://github.com/sede-x/acinguiuxplug-web-components:
- Web components delivered this way are considered content and are outside of the relase process, meaning they can be delivered faster and simpler.
- No need to maintain and execute test automation for something that does not change (which unnecessarily consumes time and resources). Manual testing is sufficient.
Useful links
- Sonar: https://sesvc.acinguiux.com/dashboard?id=com.acinguiux.acinguiuxplug
- acinguiuxplug Web Components: https://github.com/sede-x/acinguiuxplug-web-components
