npm package: @kara5/utils
Description: > A lightweight frontend JavaScript utility library for animations, UI components, and interactivity — powered by [GSAP](https://greensock.com/gsap/) and vanilla JS. Compatible with modern CMS platforms and static projects.
Author: Kara5
Latest version: 1.0.0

# @kara5/utils

> A lightweight frontend JavaScript utility library for animations, UI components, and interactivity — powered by [GSAP](https://greensock.com/gsap/) and vanilla JS. Compatible with modern CMS platforms and static projects.

---

## Table of Contents

- [Installation](#installation)
- [Quick Start](#quick-start)
- [Classes](#classes)
  - [Counter](#1-counter)
  - [Accordion](#2-accordion)
  - [Dropdown](#3-dropdown)
  - [Marquee](#4-marquee)
  - [Modal](#5-modal)
  - [Tabs](#6-tabs)
  - [Tooltip](#7-tooltip)
- [Full Import](#full-import)

---

## Installation

Install via npm:

```bash
npm install @kara5/utils
```

For local development with symlinked packages:

```bash
npm link @kara5/utils
```

> **Note:** This library requires GSAP as a peer dependency. Make sure it's installed in your project.

---

## Quick Start

```js
import { Counter, Accordion, Marquee } from '@kara5/utils';

document.addEventListener("DOMContentLoaded", () => {
  // Animate counters on scroll
  Counter.initAll(".experience-projects", ".number");

  // Initialize accordions
  document.querySelectorAll(".accordion").forEach(acc => {
    new Accordion(acc, ".acc-header", ".acc-body");
  });

  // Scrolling marquee banner
  new Marquee(".contact-marquee", ".marquee-inner", { speed: 70 });
});
```

---

## Classes

---

### 1. Counter

Animates numbers from zero to a target value, triggered on scroll. Supports suffixes like `+`, `%`, `k`, etc.

#### Import

```js
import { Counter } from '@kara5/utils';
```

#### Usage

```js
document.addEventListener("DOMContentLoaded", () => {
  Counter.initAll(".experience-projects", ".number", {
    duration: 2,
    ease: "power3.out",
    start: "top 75%",
    suffixHandling: true
  });
});
```

#### HTML

```html
<div class="experience-projects">
  <h4 class="number">200+</h4>
  <p>Projects Completed</p>
</div>
```
#### Required Parameters

| Param | Type | Default | Description |
|---|---|---|---|
| `main class wrapper` | `string` | `experience-projects` | Main class that wraps your number that you want to animate |
| `number class` | `string` | `number` | The number class that is needed to be animated |

#### Options

| Option | Type | Default | Description |
|---|---|---|---|
| `duration` | `number` | `1.6` | Animation duration in seconds |
| `ease` | `string` | `"power3.out"` | GSAP easing function |
| `start` | `string` | `"top 75%"` | ScrollTrigger start position |
| `suffixHandling` | `boolean` | `true` | Preserve text suffixes (e.g. `+`, `%`) |

> **Tip:** Set `suffixHandling: false` if your numbers are plain integers with no trailing characters.

---

### 2. Accordion

Collapsible content panels with smooth animated height transitions.

#### Import

```js
import { Accordion } from '@kara5/utils';
```

#### Usage

```js
document.querySelectorAll(".accordion").forEach(acc => {
  new Accordion(acc, ".acc-header", ".acc-body", {
    openDuration: 0.35,
    closedDuration: 0.3,
    openEase: "power2.out"
  });
});
```

#### HTML

```html
<div class="accordion">
  <div class="acc-header">What is this?</div>
  <div class="acc-body">
    <p>This is the accordion body content.</p>
  </div>
</div>
```

#### Required Parameters

| Param | Type | Example | Description |
|---|---|---|---|
| `element` | `Element` | `acc` | The accordion DOM element (from `querySelectorAll`) |
| `header selector` | `string` | `".acc-header"` | Selector for the clickable toggle header |
| `body selector` | `string` | `".acc-body"` | Selector for the collapsible content panel |

#### Options

| Option | Type | Default | Description |
|---|---|---|---|
| `openHeight` | `number` | `0` | Starting height for the open animation |
| `closedHeight` | `number` | `0` | Height when fully closed |
| `openEase` | `string` | `"power2.out"` | GSAP easing for opening |
| `closedEase` | `string \| undefined` | `undefined` | GSAP easing for closing (falls back to `openEase` if not set) |
| `openDuration` | `number` | `0.35` | Duration of the open transition |
| `closedDuration` | `number` | `0.3` | Duration of the close transition |

---

### 3. Dropdown

Animated dropdown menus with open/close control and configurable child selectors.

#### Import

```js
import { Dropdown } from '@kara5/utils';
```

#### Usage

```js
Dropdown.initAll(".dropdown", ".dropdown-toggle", ".dropdown-menu", "*", {
  openDuration: 0.3,
  closedDuration: 0.25,
  openEase: "power2.out"
});
```

#### HTML

```html
<div class="dropdown">
  <button class="dropdown-toggle">Open Menu</button>
  <ul class="dropdown-menu">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
</div>
```

#### Required Parameters

| Param | Type | Example | Description |
|---|---|---|---|
| `wrapper selector` | `string` | `".dropdown"` | Selector for the outer dropdown container |
| `toggle selector` | `string` | `".dropdown-toggle"` | Selector for the button that opens/closes the dropdown |
| `menu selector` | `string` | `".dropdown-menu"` | Selector for the dropdown menu panel |
| `child selector` | `string` | `"*"` | Selector for items inside the menu used for staggered animations |

#### Options

| Option | Type | Default | Description |
|---|---|---|---|
| `openHeight` | `number` | `0` | Starting height for the open animation |
| `closedHeight` | `number` | `0` | Height when fully closed |
| `openEase` | `string` | `"power2.out"` | GSAP easing for opening |
| `closedEase` | `string \| undefined` | `undefined` | GSAP easing for closing (falls back to `openEase` if not set) |
| `openDuration` | `number` | `0.3` | Duration of the open transition |
| `closedDuration` | `number` | `0.25` | Duration of the close transition |

> **Note:** The fourth argument (`"*"`) is a child selector that targets elements inside the dropdown menu for staggered animations. Adjust it to match your markup.

---

### 4. Marquee

Infinite, smooth horizontal scrolling ticker — great for logos, announcements, or tag lines.

#### Import

```js
import { Marquee } from '@kara5/utils';
```

#### Usage

```js
new Marquee(".contact-marquee", ".marquee-inner", {
  speed: 70,
  direction: "left"
});
```

#### HTML

```html
<div class="contact-marquee">
  <div class="marquee-inner">
    <span>Hello World</span>
    <span>Another Item</span>
    <span>Keep Going →</span>
  </div>
</div>
```

#### Required Parameters

| Param | Type | Example | Description |
|---|---|---|---|
| `wrapper selector` | `string` | `".contact-marquee"` | Selector for the outer marquee container |
| `inner selector` | `string` | `".marquee-inner"` | Selector for the element containing the scrolling content |

#### Options

| Option | Type | Default | Description |
|---|---|---|---|
| `speed` | `number` | `50` | Scroll speed in pixels per second |
| `direction` | `"left" \| "right"` | `"left"` | Direction of the scroll |

> **Tip:** Higher `speed` values work well for short text. For dense content, keep it around `40–60` for readability.

---

### 5. Modal

Accessible modal with open/close support via click and the `Escape` key.

#### Import

```js
import { Modal } from '@kara5/utils';
```

#### Usage

```js
const modal = new Modal("myModal", "#triggerBtn", ".close-btn", ".modal-content");
```

#### HTML

```html
<button id="triggerBtn">Open Modal</button>

<div id="myModal">
  <div class="modal-content">
    <p>Modal body content goes here.</p>
    <button class="close-btn">Close</button>
  </div>
</div>
```

#### Required Parameters

| Param | Type | Example | Description |
|---|---|---|---|
| `id` | `string` | `"myModal"` | The `id` of the modal container element (without `#`) |
| `triggerSelector` | `string` | `"#triggerBtn"` | CSS selector for the element that opens the modal |
| `closeBtn` | `string` | `".close-btn"` | CSS selector for the close button inside the modal |
| `modalContent` | `string` | `".modal-content"` | CSS selector for the modal content wrapper |

> **Accessibility:** The modal automatically closes when the user presses `Escape`.

---

### 6. Tabs

Lightweight tab system using data attributes — no configuration needed.

#### Import

```js
import { Tabs } from '@kara5/utils';
```

#### Usage

```js
new Tabs("[data-tabs]");
```

#### HTML

```html
<div data-tabs>
  <button data-tab-toggle data-tab-target="#panel1">Tab 1</button>
  <button data-tab-toggle data-tab-target="#panel2">Tab 2</button>

  <div id="panel1" data-tab-panel>Content for Tab 1</div>
  <div id="panel2" data-tab-panel>Content for Tab 2</div>
</div>
```

#### Required Parameters

| Param | Type | Example | Description |
|---|---|---|---|
| `wrapper selector` | `string` | `"[data-tabs]"` | Selector for the container holding both tab toggles and panels |

> **Convention:** The `data-tab-target` value must match the `id` of the corresponding panel, prefixed with `#`. The first tab is active by default.

---

### 7. Tooltip

Cursor-following tooltip with optional link support, initialized across a container.

#### Import

```js
import { Tooltip } from '@kara5/utils';
```

#### Usage

```js
Tooltip.initAll(".map-wrapper", {
  tooltipClass: "map-tooltip",
  offset: 12
});
```

#### HTML

```html
<div class="map-wrapper">
  <!-- Basic tooltip -->
  <div data-tooltip="Hello, I'm a tooltip!">Hover me</div>

  <!-- Tooltip with a clickable link -->
  <div data-tooltip="Visit site" data-link="https://example.com">Hover for link</div>
</div>
```

#### Required Parameters

| Param | Type | Example | Description |
|---|---|---|---|
| `wrapper selector` | `string` | `".map-wrapper"` | Selector for the container that holds all tooltip trigger elements |

#### Options

| Option | Type | Default | Description |
|---|---|---|---|
| `tooltipClass` | `string` | `"map-tooltip"` | CSS class applied to the tooltip element |
| `offset` | `number` | `12` | Pixel distance between the cursor and the tooltip |

> **Tip:** Add `data-link` to any tooltip trigger to make the tooltip clickable — useful for interactive maps or portfolio grids.

---

## Full Import

Import everything at once:

```js
import { Counter, Accordion, Dropdown, Marquee, Modal, Tabs, Tooltip } from '@kara5/utils';
```

---

*Built with ❤️ using GSAP and vanilla JS.*