npm package: @pequity/squirrel
Description: Squirrel component library
Latest version: 11.0.8

# squirrel <a href="https://npm.im/@pequity/squirrel"><img src="https://badgen.net/npm/v/@pequity/squirrel"></a> ![](coverage/badge.svg)

The [Squirrel component library](https://getpequity.github.io/squirrel) is a comprehensive suite of feature-rich UI components that encapsulate the styling of the Pequity Squirrel Design System.

The library is built using [Vue 3](https://vuejs.org/) and [Tailwind CSS](https://tailwindcss.com/) and is designed to be used in Vue 3 projects.
[Vite](https://vitejs.dev/) is used as the build tool for the library and [Storybook](https://storybook.js.org/) is used for component development and documentation.

## Installation and Usage

Install the package and its dependencies using `pnpm`:

```bash
pnpm i vue vue-i18n vue-router @pequity/squirrel @tanstack/vue-virtual @vuepic/vue-datepicker floating-vue iconify-icon lodash-es vue-currency-input vue-toastification@2.0.0-rc.5
```

### Internationalization (i18n) Setup

Squirrel requires vue-i18n (already included in the dependency list above). You'll need to install the Squirrel plugin to integrate Squirrel's translations with your i18n instance:

```js
import { createApp } from 'vue';
import { SquirrelPlugin } from '@pequity/squirrel';

const app = createApp(App);

// Install your i18n instance
app.use(i18n);

// Install Squirrel plugin with your i18n instance
app.use(SquirrelPlugin, i18n);

app.mount('#app');
```

Install Tailwind CSS:

```bash
pnpm i -D tailwindcss
```

Squirrel uses [iconify-icon](https://iconify.design/docs/iconify-icon/) for icons.  
In our consumer project, we need to tell Vue that `<iconify-icon>` is a web component.

Example of how to do this in a Vite project:

```js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: (tag) => tag === 'iconify-icon',
        },
      },
    }),
  ],
});
```

Import the Squirrel CSS to your project's `main.css` file:

```css
@import '@pequity/squirrel/assets/squirrel.css';
```

Add the "Inter" font to your project's `index.html` file:

```html
<link rel="preconnect" href="https://rsms.me/" /><link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
```

Use the Squirrel Tailwind configuration as a `preset` in your project's `tailwind.config.js` file:

```js
import { squirrelTailwindConfig } from '@pequity/squirrel';

export default {
  presets: [squirrelTailwindConfig],
  content: [
    './index.html',
    './src/**/*.{vue,js,ts,jsx,tsx,mdx}',
    './node_modules/@pequity/squirrel/dist/**/*.{vue,js,ts,jsx,tsx,mdx}',
  ],
};
```

Import and use the components you need in your Vue 3 project:

```html
<template>
  <PBtn type="secondary">Button</PBtn>
</template>

<script setup lang="ts">
  import { PBtn } from '@pequity/squirrel';
</script>
```

If you are using Jest for unit testing, you will need to add the following to your Jest configuration:

```js
{
  moduleNameMapper: {
    '^@pequity/squirrel$': '<rootDir>/node_modules/@pequity/squirrel/dist/cjs',
  }
}
```

## Developing Squirrel components while working on a consumer project

When working on a consumer project that relies on Squirrel components and requires experimentation and adjustments, our goal is to promptly test changes without the need to edit the library directly within the `node_modules` folder or publish a new version of it. To facilitate this process, we can utilize [Vite aliases](https://vitejs.dev/config/shared-options.html#resolve-alias) and point the entry point of the library to the _source code_ of the library that resides inside the `squirrel` directory within the Squirrel repo.

After we're happy with the changes, we can then commit them to the Squirrel repository and publish a new version.

### Setting up Vite aliases for local development

First you'll need to have the Squirrel repository cloned to your local machine.

Then, in your consumer project's `.env.local` file, add an `VUE_APP_SQUIRREL_LOCAL_PATH` variable that points to the `squirrel` folder inside the Squirrel repository:

> Make sure to replace `/home/user/development/pequity/squirrel/squirrel` with the actual path to the `squirrel` folder in your local Squirrel repository.

```bash
# Map squirrel path for local development - uncomment when you need to work on Squirrel components locally
# VUE_APP_SQUIRREL_LOCAL_PATH=/home/user/development/pequity/squirrel/squirrel
```

Finally, in your project's `vite.config` file, add the following:

> Heads up! The `vite.config.ts` file of the `pequity/frontendv2` already includes the following configuration.

```js
import { defineConfig, searchForWorkspaceRoot } from 'vite';

const squirrelLocalPath = process.env.VUE_APP_SQUIRREL_LOCAL_PATH;

export default defineConfig({
  // Other Vite config options...
  resolve: {
    alias: {
      ...(squirrelLocalPath && {
        '@squirrel': squirrelLocalPath,
        '@pequity/squirrel': squirrelLocalPath,
      }),
    },
  },
  ...(squirrelLocalPath && {
    server: {
      fs: {
        allow: [searchForWorkspaceRoot(process.cwd()), squirrelLocalPath],
      },
    },
  }),
});
```

Now, when you want to work on Squirrel components, you can uncomment the `VUE_APP_SQUIRREL_LOCAL_PATH` in your `.env.local` file and restart the dev server.  
The Squirrel components will be loaded from the local `<squirrel_repo_path>/squirrel` folder instead of the `node_modules` folder and HMR will work as expected.

## VSCode Configuration

For optimal development experience, you can use the following VSCode configuration. Add these settings to your `.vscode/settings.json` file:

```json
{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "tailwindCSS.experimental.classRegex": [["([\"'`][^\"'`]*.*?[\"'`])", "[\"'`]([^\"'`]*).*?[\"'`]"]]
}
```

This configuration enables:

- Automatic formatting on save using Prettier
- ESLint auto-fixing on save
- Tailwind CSS autocompletion for Tailwind Variants

## Contributing

---

:fire: **HEADS UP!** This repo uses [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) and [semantic-release](https://github.com/semantic-release/semantic-release) to automate the whole package release workflow including: determining the next version number, generating the release notes, and publishing the package to `npm`.  
Commit messages have to follow the conventional commit message format when contributing.

---

When adding a new component to the library, please make sure to add unit tests and Storybook stories for it.  
All components must be documented with comprehensive JSDoc comments following the `vue-component-meta` standards.
We strive to maintain a high level of code quality, test coverage, and documentation in this project.

## Project setup for development

This project uses [pnpm](https://pnpm.io/) as the package manager.

### Install dependencies

```bash
pnpm install
```

### Start the dev server

```bash
pnpm run dev
```

### Run Storybook

```bash
pnpm run storybook
```

### Run Storybook tests

```bash
pnpm run test-storybook
```

## Run unit tests

```bash
pnpm run test:unit
```

### Lint files

```bash
pnpm run lint
```

### Lint and fix files

```bash
pnpm run lint-fix
```

### Run Typechecks

```bash
pnpm run typecheck
```