[![Built With Stencil](https://img.shields.io/badge/-Built%20With%20Stencil-16161d.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI%2BCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI%2BCgkuc3Qwe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU%2BCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik00MjQuNywzNzMuOWMwLDM3LjYtNTUuMSw2OC42LTkyLjcsNjguNkgxODAuNGMtMzcuOSwwLTkyLjctMzAuNy05Mi43LTY4LjZ2LTMuNmgzMzYuOVYzNzMuOXoiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQyNC43LDI5Mi4xSDE4MC40Yy0zNy42LDAtOTIuNy0zMS05Mi43LTY4LjZ2LTMuNkgzMzJjMzcuNiwwLDkyLjcsMzEsOTIuNyw2OC42VjI5Mi4xeiIvPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNNDI0LjcsMTQxLjdIODcuN3YtMy42YzAtMzcuNiw1NC44LTY4LjYsOTIuNy02OC42SDMzMmMzNy45LDAsOTIuNywzMC43LDkyLjcsNjguNlYxNDEuN3oiLz4KPC9zdmc%2BCg%3D%3D&colorA=16161d&style=flat-square)](https://stenciljs.com)

Stencil is a compiler for building web apps using Web Components.

# LMVZ Component Library

This is the component library of the LMVZ Design System

## About

This package uses **Stencil** to create web components—for browser-native usage—and framework-specific wrapper utils for angular and react (which are wrapped using their dedicated sibling packages).
It also uses **Effect** (aka. effect-ts) for improved type-safety error handling

## General Guidelines for Consuming This Package (in your project)

Always consider the Integration chapter in the Design Guide. In the context of a UI framework, consider using the specific wrapper packages: `@lmvz-ds/angular`, `@lmvz-ds/react`, `@lmvz-ds/vue`.

## NPM Integration

### Installation

```bash
npm i @lmvz-ds/components
```

> [!TIP]
> Our @lmvz-ds/aria-validation sibling is only used for YOUR development mode, and thus, optional.

## Usage

In a web app, import components directly (`import LmvzCard from '.../components/lmvz-card.js'`) or the loader (e.g., `import { defineCustomElements } from '.../loader';`) and call `defineCustomElements(window)` to register all components globally.
Use the CDN version (cdn.js) for direct browser inclusion via <script> tags.
The loader is essential when integrating Stencil components into non-Stencil projects (React, Angular, plain HTML) to ensure custom elements are defined and polyfills loaded.

### Runtime ARIA Validation (Opt-in)

ARIA validation is disabled by default and can be enabled on demand with a separate runtime import:

```ts
import '@lmvz-ds/components/ariaValidation';
```

This import enables validation globally for all LMVZ components, independent of integration mode.

To disable it again at runtime:

```ts
import { disableAriaValidation } from '@lmvz-ds/components/ariaValidation';

disableAriaValidation();
```

### Components

Components are built in standalone mode, using [`dist-custom-elements`](https://stenciljs.com/docs/custom-elements). This way, you can import the components individually, wherever they are needed.

For example, given you'd like to use `<my-component />` as part of your application, you can import the component directly via:

```tsx
import '@lmvz-ds/components/my-component';

function App() {
  return (
    <>
      <div>
        <my-component first="Stencil" middle="'Don't call me a framework'" last="JS"></my-component>
      </div>
    </>
  );
}

export default App;
```

⚠️ The components' bundled styles will not affect native HTML elements, so you still need to import style packages you want to use globally.

## Making changes to this package

### Getting Started

```bash
npm install
```

### Workflow

See the parent project's readme for the overarching process' description.

### Guidelines

- Components must each be provided as stand-alone bundles.
- Components must bring their own, ds-aligned, default styles. This increases flexibility (as components are usable stand-alone) and is achieved by build-time injection of defaults (based on base- and light-theme-variables). There is no need for importing any variables definitions. Instead, add base variables to the plugin config's list (`stencil.base.config.ts`).
  - Font file contents are exempt from bundling, to allow for browser-caching!
- To prevent styles from leaking out of your Components (into the global scope), wrap your own styles and `@import`s in `:host`.
- Components depending on Fragments must import them into their :host selector, for proper encapsulation.
  - This use of CSS' @import syntax is invalid, but properly handled by postcss.
  - Consider using custom-property abstractions instead of importing whole fragments!


### Configuration

Different Stencil configs are necessary, since we need the following constellations (which are not possible with a single config):

- local Stencil dev-server: classic dev build
- Storybook integration: prod build + source maps (dev build does not generate source files in dist/)
- release build: prod build without source maps

package.json exports should be generated along with the Stencil build (for new components).

### Development

Use the `pnpm run start:dev` script to start Stencil's dev server.  
(`start` will be called from the Storybook sibling package and will only run a (watching) production build).  

### Building

To build the components (and styles) for production, run the build script. This will also sync changes to the wrapper projects.

```bash
pnpm run build
```

### Creating New Components

Always use the `lmvz-` prefix when creating new components!

```bash
pnpm run @stencil/core generate lmvz-[component name]
```

### Testing

To run the unit tests for the components, run:

```bash
npm test
```

#### Integration Testing

Since components can be integrated in various ways, always test integrations:

- Stencil dev mode and preview (see package scripts).
- With the Storybook package.
- Angular, React, ... wrappers

#### E2E

TODOs

- Current Playwright integration is broken or will break Jest integration.  
- Vitest-Browser + Stencil is bleeding edge and needs eval.
