pattern-library
pattern-library copied to clipboard
AXA CH UI component library. Please share, comment, create issues and work with us!
Pattern Library
>> Pattern Library Demo
Check out our Contribution File
Check out our Architecture File
Communication
Use the following channels for different kinds of requests/reports:
- Bug reports, small change requests, "wishes": https://github.com/axa-ch-webhub-cloud/pattern-library/issues
- Questions, requests for help, requests for product presentations, etc: Slack #patterns-lib-devs
- Feature requests (Components, etc): Slack @martin.stuedle
What we deliver
We release self-contained plug-and-play web components based on the custom elements specification, derived from the lit-element base class (maintained by Google).
Pattern Library via community CDN
You can add any Pattern Library component via the community CDN jsdelivr. This is useful for Prototyping or experimenting or if you don't want to bother with a frontend stack. This works only native (no react support). Here an example on how to add the JS for <axa-button></axa-button>
: <script src="https://cdn.jsdelivr.net/npm/@axa-ch/button@latest/dist/index.js"></script>
Build Pattern Library components in your own application
Pattern Library components are exported to npm with 2 types of build artifacts: /dist/index.js
and /lib/index.*
in ES2019. If you use the Pattern Library in AXA's DX WebHub context, you don't have to worry about this topic. All others, please read on.
The de-facto standard in the frontend community is to render /lib
exports as ESM, i.e. ES5 + import/export. Due to the nature of web components and lit-element, however, we are forced to export in ES6. For more details, see the custom element specification.
If you need to support Internet Explorer (11) in your application, you therefore need to transpile our component (/lib) artifacts in your build. To do so, you need to include the path to our components (@axa-ch) and their underlying framework (lit) in the section of your transpilation configuration that describes transpilation to ES5. Here is an example snippet of how this would look in a webpack config:
{
test: /.js$/,
include: [
/src/,
new RegExp(`node_modules${sep}lit`),
new RegExp(`node_modules${sep}@axa-ch(?!${sep}patterns-library-polyfill)`),
],
use: {
loader: 'babel-loader',
options: {
...babelrc,
},
},
},
Component versioning
Different versions of our web components can coexist on the same web page! Here you can read more about component versioning.
Released Polyfills
Released Components
Alpha-Released Components
- None
Design Guidelines
How to contribute
Whether you are helping us to fix bugs, or you are more into creating components, we would love to have you as contributor of the AXA Pattern Library!
Check out our Contributing Guide for ideas on contributing and setup steps for getting the repository up and running on your local machine.
Code of Conduct
We are dedicated to building a welcoming, diverse, and safe community. We expect everyone participating in the AXA community to read and accept our Code of Conduct
Version Control
This repository is a monorepo managed by Lerna. This means that all components are centrally managed here, even though we publish them to NPM as separate packages.
How do I get my (unit) tests to work when using Pattern Library components?
The problem
Unit-test frameworks like Jest run under the node
environment, which is quite different from a browser. The most commonly used abstraction to mimic a minimal browser within node
is jsdom
. However, jsdom
lacks crucial features such as Mutation Observer
, Custom Elements
and other browser APIs commonly needed by web components.
Solutions
So what are your options?
- Insisting on
jest
, one option would be to use a better DOM emulation. Exchangingjsdom
withhappydom
, we now have enough emulated browser features to test web components. The details are described here. - Instead of using
jest
, employ end-to-end (e2e) testing tools that control a real browser, e.g.Playwright
,Cypress
orTestcafe
. Arguably this is a better match for UI-heavy apps anyway, because e2e tests are closer to a real user experience. - Use a lightweight mocking strategy. The idea is to mock pattern library components by a simple, traditional-HTML replacement such as a <div> or a <button>. Here is a code sketch using Jest that employs this strategy:
All Pattern-Library React components are imported from this index.js. import createAXAButton from '@axa-ch/button/lib/index.react'; import createAXADropdown from '@axa-ch/dropdown/lib/index.react'; export const AXAButton = createAXAButton(createElement); export const AXADropdown = createAXADropdown(createElement); AXAButton.displayName = 'AXAButton'; AXADropdown.displayName = 'AXADropdown';
__mocks__/index.js export const AXAButton = (props) => { return <button {...props}>{props.children}</button>; }; ...
Testing with Selenium, Testcafe and other UI testing tools
By default, pattern-library web components make use of ShadowDOM. To trigger interactions inside such web component you need to access the DOM via the ShadowRoot. Schematically, this works like this: UI Testtool -> Driver -> native DOM selector -> ShadowRoot -> querySelector
Here is a concrete example in Java using Selenium:
public WebElement expandRootElement(WebElement element, WebDriver driver) {
WebElement ele = (WebElement) ((JavascriptExecutor) driver)
.executeScript("return arguments[0].shadowRoot",element);
return ele;
}
Calling this method gives you the ShadowRoot
in your Selenium environment. Beware: when calling findElement
on the return value of expandRootElement
only the following selectors will work:
- By.id
- By.className
- By.cssSelector
Dealing with F(lash) O(f) U(nstyled) C(ontent)
As described in ARCHITECTURE.md, FOUC can be mitigated by using the CSS pseudo-selector: :not(:defined)
. Below please find an example of how we can show to the user that the <axa-footer>
is not yet defined (pulsating blocks). The selector :not(:defined)
won't work in IE11 and therefore there won't have any effect on it. Following the principle of graceful degradation, this is fine, since the only downside in IE11 is that it doesn't look as good as the other browsers while no real functionality has been lost.
<style>
axa-footer:not(:defined) {
background-color: #3b3fd8;
color: #3b3fd8;
display: block;
}
axa-footer:not(:defined) svg {
display: none;
}
axa-footer:not(:defined) a {
color: #FFF;
background: #FFF;
display: inline-block;
margin-left: 10px;
pointer-events: none;
margin-top: 10px;
opacity: 0.2;
transition:opacity 500ms ease-out;
animation: pulseloadingaxafooter 1s infinite;
}
@keyframes pulseloadingaxafooter {
0% {
opacity: 0.2;
}
50% {
opacity: 0.3;
}
100% {
opacity: 0.2;
}
}
</style>