npm package: @ortelius/ortelius-web-components
Description: Grapical Web Components Library
Author: Ortelius AB
Latest version: 22.2.3

# Ortelius Web Components
 
This is a library for Ortelius web components.

<br>

# Usage
 
To use Ortelius web components in a browser you can simply import them using unpkg:
```html
<script src="https://unpkg.com/@ortelius/ortelius-web-components/dist/build/ouswc-bundle.js"></script>
```
 
For use in npm projects you can install the components by doing:
```bash
npm install @ortelius/ortelius-web-components --save
```
then add:
```html
<script src="node_modules/@ortelius/ortelius-web-components/dist/build/ouswc-bundle.js"></script>
``` 
to your index.html

Or import it right into your project:
```javascript
import "@ortelius/ortelius-web-components"
```

Some components need to be imported separately (as they are not part of the main bundle). In that case simply replace ouswc-bundle.js with ouswc-componentname.js

<br>

# Working with the project
## Commands
NPM Command | Description
--- | ---
npm start   |   Start the development environment, src/index.html will be used as an entrypoint. Some components use their own .html files, these can be copy-pasted into index.html when working with the specific components
npm test   |   Executes all tests. Snapshots can be overwritten by providing -- -u as an argument.
npm run storybook   |   Start storybook
npm run build   |   Build the entire project
npm run build:dist   |   Executes rollup for the production build
npm run build:documentation   |   Generates the custom-elements.json documentation file
npm run build:storybook   |   Builds storybook
npm run build:polyfill   |   Builds all polyfills
npm run build:test   |   Builds the test build used by jest
npm run rollup   |   Builds dist and polyfills
npm run prettier   |   Executes prettier on the entire project
npm run lint   |   Executes eslint on the entire project
npm run lint:fix   |   Executes prettier and eslint on the entire project, and attempts to fix any errors automatically.

<br>

## Project structure and features
### Web Components
All web components can be found in src/Components. Each component consists of (at least) 4 files: 
- .js -> Code for the component 
- .html -> All initial shadow DOM markup
- .scss -> Sass-stylesheets applied to the shadow DOM
- .test.js. -> Component-specific unit tests 

Together they make up a web component.

### Storybook
Inside of the "Stories" folder in the src directory you can find one storybook file for each component in the project. The storybook files are used to generate a storybook export page that shows and documents all existing web components. Storybook can also be used for testing components during development.

### SASS and stylesheets
The project is configured with a sass-compiler. This means that you can use sass-features when coding the stylesheets for your component.

#### Sass variables
Within the src/Assets/Stylsheets directory you will find a variables.scss. This should generally always be imported into component stylesheet files and be used instead of hard coding common default values.

#### Css variables
Within ouswcvariables.scss you can find a list of generic css variables that should (as far as possible) be used in components. If no generic variable is applicable then component specific ones can be created. All component specific variables should start with "--ouswc-componentname-". 

#### Sass Components
In src/Assets/Stylesheets/Components a number of reusable style components can be found. this is used to style things like texts according to the design system, without copy pasting.

For example, by importing text.scss you can extend it in sass-classes:
```sass
@import(".../text.scss");
.my-class {
    @extend %body-1
}
```
Some components only need to be imported to be applied, such as the scrollbar.scss. If imported all scrollbars will be styled according to the design system.

### Advanced components (Preact)
Some components require advanced rendering logic, and the use of additional tools and libraries. The project is configured with preact and a react compatibility layer that can be used for development of such components.

When building advanced components these should *not* be included in index.js (the default bundle), but rather be specified as a separate export in the rollup configuration. This is because these components generally grow substantially large in size.

When using Preact in the project you must use the .jsx file type, and you must specify it in all import statements, or you will get errors. Furthermore, you must always import { h } from "preact" at the top of each component file. This is to satisfy the compiler without affecting the main bundle.

<br>

## Component Guidelines
### Documentation
All components must be documented using a JSDOC comment at the top of the js component class. This must include:
- The element tag
- A component description
- All applicable element attributes
- All properties defined and used on the component
- All exposed functions defined and used on the component
- All events fired by the component
- All slots defined on the component

### Code order
A component should always follow this order of functions:
- static get observedAttributes()
- Constructor() {}
- Property getters and setters
- connectedCallback() {}
- attributeChangedCallback(name, oldValue, newValue) {}
- disconnectedCallback() {}
- Listeners and handlers (functions triggered by events)
- All your other code
- _render()

### _render()
When applicable components should have a _render() function. The _render() function should handle as much of the component (re)rendering as possible, collecting all logic in one place that can be executed when needed.

### General rules
- Functions and properties that should not be exposed externally should always begin with an underscore: "_". 
- It is preferred to use arrow function expressions over classic function definitions.
- All class properties must be defined in the constructor.
- Boolean attributes should start with "use" if they are truthy by nature, or "no" if they are falsey by nature. (e.g. "noheader", "usefullsize")
- Comments should follow the JSDOC standard: https://jsdoc.app/

### Tests
Each component has a test file that comes with it. Tests can be written both using Jest's built in DOM APIs, as well as using Puppeteer. Puppeteer, among other things, allows for screenshot tests.

If you ever need to overwrite test snapshots when something has changed on purpose then you can provide the -u option to the test runner like so:
```bash
npm run test -- -u
```

This will overwrite the snapshot with a new one, resolving any errors.

To simplify the use of Puppeteer a custom Puppet class can be found under \<root\>\/\_\_tests__/helpers/CustomPuppet.js. This class should be used for all puppeteer tests.

### Linting
ESLint a Prettier are both configured in the project. 

When committing something to git both prettier and eslint will execute and attempt to fix any errors before the commit is made. If either of the two fails then the commit will be stopped.


### Storybook
The project contains a storybook setup. Storybook will use the automatically generated custom-elements.json file to generate documentation for each component, as well as the story files to organize and present the web components in the component system.

In order for documentation to be properly generated you need to ensure that your JSDOC is correctly formatted.

Every time the develop branch gets pushed to origin storybook will be built and published to the following URL:
https://jbadevstorage.blob.core.windows.net/$web/index.html?path=/story/*

## Documentation
All components are documented in .src/custom-elements.json. This is generated by running: 
```bash
npm run build:documentation
```
The documentation file is based on the JSDOC in each web component.

This documentation is included in the distribution under dist/documentation


# Compatibility
The web component library aims to be compatible with all evergreen browsers.

# Commit checklist
When preparing a commit, the following checklist can be used.
- Does the linter pass? (npm run lint:fix)
- Do all tests pass? (npm run test)
- Has sass-components been used where applicable?
- Has css-variables been used where applicable and do they work as intended?
- Are there unused variables/functions/etc?
- Has everything relevant been documented in JSDOC?
- Are all listeners to external events removed on disconnectedCallback()? (if applicable)
- Can the component handle varying text length? (if applicable)
- Can the component handle viewport size changes? (if applicable)
- Can the component handle its container being squished together or dragged out? (if applicable)