npm package: @legalesignlab/ui
Description: This is a Legalesign components library that uses Stencil, Storybook and Vite
Latest version: 0.0.4

# Legalesign Components Library

This repository is a StencilJS project that builds a component library built by Legalesign which can be exported to any frontend framework project including React.

## Languages

Generally speaking, pages should be built and tested using StencilJS language and TypeScript(jsx) where that is allowed.

## Folder Structure

```
/.stencil
/.storybook
/storybook-static
/.wireit
/dist
/loader
/www
/src
    /components
        /my-component
            my-component.tsx
            my-component.css
            my-component.stories.tsx
            my-component.spec.ts
    /global-styles
    /stories
    <!-- This is where local types for Typescript can be added if needed. Those should be used for the components locally -->
    /types
```

<!-- TODO: Update the installation with Jodie-->


## Development

Assumes that you have node, pnpm and git installed.
To install pnpm, run the following command:
```
npm install -g pnpm
```

```
git clone git@github.com:legalesign/ui.git
cd ui
pnpm install
pnpm start
```

To start the development server, run the following command:

```
pnpm start
```

If you want to only run the stencil part of the project (without storybook), run the following command:
```
pnpm stencil:start
```
That will run a server in index.html and components should be added there.

**Steps to add a new Icon:**
1. Add an object with the following structure to `src/components/ls-icon/icons.ts`:
```
{
  name: "icon-1",
  svgSolid: html`<svg>{the svg string here}</svg>`,
  svgOutline: html`<svg>{the svg string here}</svg>`,
},
```
2. Add the icon to `src/types/Icon` file as an enum.


**Steps to add a new Component:**
1. Create a folder in src/components and name it after the new component. Ensure that the folder name is in kebab-case as this is a StencilJS requirement. Usually that would be ls-comp.
2. Create the following files:
  - ls-comp.tsx
  - ls-comp.css
  - ls-comp.stories.tsx
  - ls-comp.spec.ts
3. Ensure the same component structure as this in ls-comp.tsx:
```
import { Component, Prop, h } from "@stencil/core";

@Component({
  tag: "ls-comp",
  styleUrl: "ls-comp.css",
  shadow: true,
})

export class LsComp {
  @Prop() name?: string;
  @Prop() rounded?: boolean;

  render() {
    return (
      <div>        
        <div>{this.name}</div>
      </div>
    );
  }
}
```

4. Add the styles for your components in ls-comp.css.
5. Add unit tests to ls-comp.spec.ts. Example format for unit test:
```
import { newSpecPage } from "@stencil/core/testing";
import { LsComp } from "./ls-comp";

describe('ls-comp', () => {
  it('builds', async () => {
    const page = await newSpecPage({
      components: [LsComp],
      html: `<ls-comp></ls-comp>`,
    });
    expect(page.root).toBeTruthy();
  });
});
```
6. Add stories to ls-comp.stories.tsx. Stories should be in this format:
```
import { Rounded } from "../../types/Rounded";

type IArgs = {
  name: string;
  rounded: Rounded;
};

export default {
  title: "Components/ls-comp",
  component: "ls-comp",
  args: {
    name: "my-test-name",
    rounded: Rounded.SOFT,
  },
  argTypes: {
    variant: {
      control: {
        type: "text",
      },
    },
    rounded: {
      control: {
        type: "radio",
      },
      options: Object.values(Rounded),
    },
  },
};

const Template = (args: IArgs) => {
  return `
    <ls-comp
      name="${args.name}"
      rounded="${args.rounded}"
    />
  `;
};

export const Default = Template.bind({});
```

**Steps to add a new Component using CLI:**
```
pnpm stencil g ls-component
```

## Usage
To use the components in your project, you should install @legalesignlab/ui npm package.
This can be done by running:
```
npm install @legalesignlab/ui
```

Then it will get added to your package.json file:
```
  "dependencies": {
    "@legalesignlab/ui": "^0.0.1"
  }
```

There are 3 ways to import the components:

1. Import the components in your project like this in the entry point of your application:
```
import '@legalesignlab/ui';
```

2. Add script tag to your index.html file like this:
```
<script type="module" src="/node_modules/@legalesignlab/ui/dist/legalesign-components/legalesign-components.esm.js"></script>
```

3. Add this to your entry point file - index.js or App.tsx:
```
import { defineCustomElements } from '@legalesignlab/ui/loader';

defineCustomElements(window);
```

After components have been imported you need to import the global styles. This should be done in the entry point of the app like this:
```
import '@legalesignlab/ui/styles';
```

Then you can use the components in your project like this:
```jsx
<ls-comp name="whatever-the-name" size="small" />
```
P.S. Make sure to add the props in kebab-case.

**Temporary way to import components' types when consuming them in a Typescript app:**

#METHOD 1
Create a file in your project's src folder called register-web-components.ts and add the following:
```
// register-web-components.ts
/* eslint-disable */
import { defineCustomElements, JSX as LocalJSX } from '@legalesignlab/ui/loader';
import { HTMLAttributes } from 'react';

type StencilToReact<T> = {
  [P in keyof T]?: T[P] & Omit<HTMLAttributes<Element>, 'className'> & {
    class?: string;
  };
} ;

declare global {
  export namespace JSX {
    interface IntrinsicElements extends StencilToReact<LocalJSX.IntrinsicElements> {
    }
  }
}

defineCustomElements(window)
```

#METHOD 2
Create components.d.ts file in your project's src folder and add them there. It can look something like this:
```
import {Components as LsComponents} from '@legalesignlab/ui/dist';

declare global {
    namespace JSX {
        export interface IntrinsicElements {
          'ls-my-comp': LsComponents.LsMyComp;
    }
  }
}
```

Then add the following to your project's tsconfig.json:
```
  "include": ["src", "src/components.d.ts"],
```

A full types list can be found in GitHub Wiki - https://github.com/legalesign/ui/wiki/Props

<!-- TODO: Add the Component library as a npm project  -->