# Bridgeman Accessible Web / Front-End Component Library
This package provides definitions for various different types of "complex" components that can be reused across various different web apps.
## Getting Started
The following provides a quick overview of how to start using this library. However, it's likely worth getting to know the library and needed configurations for each component before usage because the flexibility the components are built with can mean complexity in their usage (though we do try to keep it to a reasonable minimum as much as possible)
### Installing the library
This component library is packaged as a standard NPM package within our own package registry
```bash
npm install @BridgemanAccessible/ba-web-components
```
### Exposing the library
To be able to use the library you first need to register the middleware. Note, there are different ways of doing this based on level of customization required. The following only shows the simplest case.
```ts
import express from 'express';
import components from '@BridgemanAccessible/ba-web-components';
// ...
const app = express();
// ...
app.use(components(app));
```
### Using the components
To be able to use the component within a EJS template there are two parts:
1. Script Inclusion
2. Component Usage
#### Script Inclusion
Because of how the components work, a client side JavaScript file needs to be added to the page. The details of what the script's URL is will vary based on the configurations passed to the middleware. But the basics of how this works is that all client-side JavaScript across components gets bundled and minified at build / compile time and needs to be included separately because it tells the browser how to handle custom tags / "Web Components" so that the component code can run properly.
```ejs
```
#### Component Usage
When ready to actually use a component the code would look something like:
```ejs
<%# ... %>
<%- useComponent('', { [paramName]: pramValue, ... }) %>
<%# ... %>
```
Replacing ``, `paramName`, and `paramValue` as appropriate, including specifying whatever parameters and configurations are needed or desired.
## Library Structure
The library roughly has 2 main parts:
1. **The middleware (`src/index.ts`)**: This does the translation, loading and other needed work to make the components as easy to use as they are
2. **The components (`src/components/*`)**: These are the components that make up the library
### Middleware
The code for the middleware is largely self-documenting so that won't be discussed here. But in broad strokes this defines a `useComponent` function on the `res.locals` object that when used takes the parameters renders the component template and passes back the string of code that makes up the component.
### Components
Components are defined within their own folders underneath the `src/components` folder. This is to keep things neat and organized as well as to allow for documentation (README) for each component that provides information on expected parameters and configurations.
That said, each component generally has a `.ejs` file, `.js` file and a `.css` file or `templates` (folder containing `.ejs` files), `scripts` (folder containing `.js` files) and `styles` (folder containing `.css` files) or some combination therein. Additionally most have a `README.md` that gives information about the component.
It's worth noting this structure described under `src/components` is very different from the structure under `dist/` this is largely for efficiency because all JS and CSS files get bundled and minified into a single `components.js` and `components.css` file. And the file structure gets slightly flattened so that file lookup only involves a single directory scan instead of multiple directory scans and changing directories.
## Adding A New Component
Adding a new component to the library is virtually as easy as following the structure described in the previous section. In particular under the `src/components` directory create a folder with the new components name and place a `.ejs`, `.js` and `.css` file within it (or some variation as described). Likely also creating a `README.md` for documentation of the individual component.
The somewhat complex but also helpful tool chain should do the rest of the work (in terms of bundling, minifying, moving needed files, etc.)
## Build Tool Chain
Because the component library is designed to be efficient but equally good Developer Experience (DX) we utilize a few different technologies in a relatively complex "tool chain" to attempt to achieve this.
### Gulp
We use Gulp as the overarching automation technology that allows us to run different tasks to create the end result.
### Typescript
Using typescript allows us to write type safe code
### Rollup
We use Rollup to bundle the client-side Web Component JS code.
## CI / CD (Forgejo Actions)
We use CI / CD to run our build change on pushes and publish the created package to our private NPM registry.