npm package: @stsdti/funky-ui-kit
Description: A library with all our UI reusable components and helper functions to help speed up Vue development
Author: STS - DTI
Latest version: 1.0.3

<p align="center">
  <img src="https://img.shields.io/badge/vue-3.x-42b883?style=for-the-badge&logo=vuedotjs&logoColor=white" alt="Vue 3" />
  <img src="https://img.shields.io/badge/vite-6.x-646cff?style=for-the-badge&logo=vite&logoColor=white" alt="Vite" />
  <img src="https://img.shields.io/badge/version-1.16.0-blue?style=for-the-badge" alt="Version" />
  <img src="https://img.shields.io/badge/license-proprietary-red?style=for-the-badge" alt="License" />
</p>

<h1 align="center">🎨 Funky UI Kit</h1>

<p align="center">
  <strong>A comprehensive, opinionated Vue 3 component library packed with 70+ ready-to-use components, powerful composables, and utility functions — designed to accelerate enterprise Vue development.</strong>
</p>

<p align="center">
  <code>@stsdti/funky-ui-kit</code>
</p>

---

## ✨ Highlights

- 🧩 **70+ Components** — From basic inputs to complex data tables, form wizards, and file previews
- 🪝 **Powerful Composables** — `useForm`, `useTable`, `useSelect`, and more for rapid feature development
- 🏗️ **Repository Pattern** — Built-in `BaseRepository` with filtering, sorting, pagination, and request deduplication
- 🎯 **Form Binding System** — Reactive `getBinding()` API that wires up `v-model`, validation, and field state in one call
- 🔌 **Plugin Architecture** — Single `app.use()` call registers all components, directives, and integrations
- 📦 **Tree-Shakable** — ESM output with code-split CSS for optimized bundle sizes
- 🎨 **Limitless Theme** — Built-in SCSS-based design system with a rich color palette and icon set
- 🧪 **TypeScript Support** — Ships with generated type declarations and JetBrains `web-types.json`

---

## 📦 Installation

```bash
npm install @stsdti/funky-ui-kit
```

### Peer Dependencies

Make sure the following are installed in your host project:

```bash
npm install vue@^3.5 vue-router@^4.2 axios@^1.6
```

---

## 🚀 Quick Start

### 1. Register the Plugin

```js
// main.js
import { createApp } from 'vue'
import FunkyUIKit from '@stsdti/funky-ui-kit'
import '@stsdti/funky-ui-kit/dist/funky-ui-kit.css'

const app = createApp(App)

app.use(FunkyUIKit, {
  router,        // vue-router instance — enables route-aware features
  mediaType,     // optional — configures media handling strategy
})

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

> **That's it!** All 70+ components are now globally available. No individual imports needed.

### 2. Use Components

```vue
<template>
  <AppCard>
    <AppInput v-model="name" label="Full Name" />
    <AppSelect v-model="role" :fetch="fetchRoles" />
    <AppButton @click="submit">Save</AppButton>
  </AppCard>
</template>
```

### 3. Import Composables & Utilities

```js
import {
  useForm,
  useTable,
  useSelect,
  useFormValidation,
  useTableFilters,
  BaseRepository,
  DateUtils,
  UIUtils,
  ResponseUtils,
} from '@stsdti/funky-ui-kit'
```

---

## 🧩 Component Catalog

### Layout Components

| Component | Description |
|-----------|-------------|
| `AppSidebar` | Application sidebar with collapsible navigation |
| `AppSidebarHeader` | Header section for the sidebar |
| `AppToolbar` | Top toolbar / app bar |
| `AppFooter` | Application footer |

### Form Inputs

| Component | Description |
|-----------|-------------|
| `AppInput` | Text input with label, validation, and form element integration |
| `AppNumberInput` | Numeric input with increment/decrement controls |
| `AppTextArea` | Multi-line text input |
| `AppCheckbox` | Checkbox with label support |
| `AppRadioButton` | Radio button group |
| `AppToggleButton` | Toggle / switch control |
| `AppSliderInput` | Range slider input |
| `AppColorPicker` | Color picker with palette support |
| `AppFormElement` | Base wrapper that provides label, validation state, and layout to any input |

### Select & Pickers

| Component | Description |
|-----------|-------------|
| `AppSelect` | Feature-rich dropdown select with search, async fetching, and multi-select |
| `AppSelectNew` | Next-generation select component |
| `AppSelectBoolean` | Boolean yes/no select |
| `AppSelectIcon` | Icon picker select |
| `AppDatePicker` | Date picker (powered by `@vuepic/vue-datepicker`) |
| `AppDatePickerRange` | Date range picker |
| `AppDatePickerDayOfWeek` | Day-of-week picker |
| `AppDateTimePicker` | Combined date + time picker |
| `AppTimePicker` | Standalone time picker |
| `AppMonthPicker` | Month-only picker |
| `AppMonthYearPicker` | Month + year picker |
| `AppYearPicker` | Year-only picker |
| `AppGridPicker` | Grid-based option picker |

### Data Display

| Component | Description |
|-----------|-------------|
| `AppTable` | Data table with sorting, pagination, and filtering |
| `AppTableMagic` | Enhanced table with advanced features |
| `AppTableFilter` | Filter panel for tables |
| `AppTableFilterDrawer` | Side-drawer variant of table filters |
| `AppPagination` | Standalone pagination control |
| `AppBadge` | Status badge / label |
| `AppTag` | Colored tag chip |
| `AppRemovableTag` | Tag with remove action |
| `AppProgressBar` | Determinate progress bar |
| `AppProgressBarOverlay` | Full-screen progress overlay |
| `AppSummary` | Summary info display |
| `AppEllipsisText` | Text with overflow ellipsis and tooltip |
| `AppHtml` | Sanitized HTML renderer (powered by DOMPurify) |
| `AppTree` | Hierarchical tree view |

### Navigation

| Component | Description |
|-----------|-------------|
| `AppBreadcrumbs` | Breadcrumb trail |
| `AppTabs` | Tab navigation |
| `AppTabsBoolean` | Two-state tab toggle |
| `AppLink` | Enhanced router link |
| `AppMenu` | Dropdown menu |
| `AppScrollToTop` | Scroll-to-top button |
| `AppScrollToBottom` | Scroll-to-bottom button |
| `AppScrollTopAndBottom` | Combined scroll controls |
| `AppToolbarSubheader` | Secondary toolbar header |

### Buttons

| Component | Description |
|-----------|-------------|
| `AppButton` | Primary button with variants and icons |
| `AppButtonGroup` | Grouped button set |

### Feedback & Overlays

| Component | Description |
|-----------|-------------|
| `AppModal` | Modal dialog |
| `AppModalCard` | Card-style modal |
| `AppFormModal` | Modal with built-in form handling |
| `AppPreviewModal` | Preview / detail modal |
| `AppLoadingModal` | Loading state modal |
| `AppDrawer` | Slide-out drawer panel |
| `AppOverlay` | Background overlay |
| `AppLoadingOverlay` | Full-screen loading overlay |
| `AppLoading` | Inline loading spinner |
| `AppDirtyToast` | Unsaved changes notification |

### Files & Media

| Component | Description |
|-----------|-------------|
| `AppFile` | File display component |
| `AppFileNew` | Next-generation file component |
| `AppFileInput` | File upload input |
| `AppFileUpload` | Drag-and-drop file upload |
| `AppFilePreview` | File preview (supports PDF via `pdfjs-dist` and DOCX via `docx-preview`) |
| `AppIframe` | Embedded iframe viewer |
| `AppCarousel` | Image/content carousel |

### Layout & Structure

| Component | Description |
|-----------|-------------|
| `AppCard` | Content card container |
| `AppPage` | Page-level layout wrapper |
| `AppChild` | Router child view wrapper |
| `AppIcon` | Icon component (powered by `@tabler/icons-vue`) |
| `AppDualListMagic` | Dual-list transfer component |
| `AppFormRepeater` | Dynamic form field repeater |
| `AppFormWizard` | Multi-step form wizard |
| `AppTeleport` | Vue Teleport wrapper |
| `AppTeleportTarget` | Teleport mount target |

### Skeleton & Placeholders

| Component | Description |
|-----------|-------------|
| `AppSkeleton` | Loading skeleton element |
| `AppSkeletonGroup` | Grouped skeleton layout |
| `AppPlaceholderCard` | Card placeholder |
| `AppPlaceholderHeading` | Heading placeholder |
| `AppPlaceholderImage` | Image placeholder |
| `AppPlaceholderText` | Text placeholder |
| `AppPlaceholderTitle` | Title placeholder |

---

## 🪝 Composables

### `useForm` — Full-Featured Form Management

The crown jewel of Funky UI Kit. Manages the entire lifecycle of a form: fetching, binding, validation, dirty tracking, saving, and deleting.

```js
import { useForm } from '@stsdti/funky-ui-kit'

const form = useForm({
  model: MyModel,           // model with repository + transformer
  useDirty: true,           // track unsaved changes
  onEvent: (event, ctx) => {
    // 'mounted' | 'inited' | 'fetched'
  },
}, emit)

// Reactive field binding — wires up v-model + validation in one call
const nameBinding = form.getBinding('name')
const emailBinding = form.getBinding('email')
```

```vue
<template>
  <AppInput v-bind="nameBinding" label="Name" />
  <AppInput v-bind="emailBinding" label="Email" />
  <AppButton @click="form.onSave()">Save</AppButton>
</template>
```

**Returned API:**

| Property / Method | Description |
|---|---|
| `item` | Reactive ref containing the form data |
| `isLoading` | Loading state ref |
| `isDirty` | Computed — `true` if form has unsaved changes |
| `getBinding(path)` | Creates a reactive binding object for a field path |
| `getBindingMedia(path, tag)` | Creates media-specific bindings with tag filtering |
| `initItem({ id, value })` | Initialize or reset the form item |
| `onSave()` | Validate → transform → save (insert or update) |
| `onDelete()` | Show confirmation → delete → navigate |
| `refreshItem()` | Re-fetch the current item |
| `setPayloadIsDisabled(key)` | Programmatically disable fields |
| `setPayloadIsHidden(key)` | Programmatically hide fields |

---

### `useTable` — Server-Side Table Management

Manages paginated, sortable, filterable tables with full URL-based filter persistence.

```js
import { useTable } from '@stsdti/funky-ui-kit'

const table = useTable({
  fetchOnMount: true,
  getTable: async (request) => {
    return await myRepository.fetchTable(request)
  },
  tableFilters: {
    filters: { search: '', status: null },
    filterBuilders: {
      search: (value) => ({ field: 'search', value }),
      status: (value) => ({ field: 'status', value }),
    },
  },
}, emit)
```

**Returned API:**

| Property / Method | Description |
|---|---|
| `tableData` | Reactive table response (rows, pagination meta) |
| `tableRows` | Computed array of current rows |
| `isLoading` | Loading state |
| `onFilterSet()` | Apply current filters and refetch |
| `onFilterReset()` | Reset all filters to defaults |
| `onTablePageChange(page)` | Navigate to a specific page |
| `onTableSortChange(sort)` | Apply column sorting |
| `fetchTable()` | Manually trigger a table fetch |

---

### `useSelect` — Async Select Options

Manages option fetching, search, debouncing, and auto-selection for select components.

```js
import { useSelect } from '@stsdti/funky-ui-kit'

const { options, isLoading, fetchOptions, onSearch } = useSelect({
  modelValue: selectedRef,
  fetch: async (search) => api.searchUsers(search),
  shouldFetchOnMount: ref(true),
}, emit)
```

---

### Other Composables

| Composable | Description |
|---|---|
| `useFormValidation` | Yup-based validation engine used internally by `useForm` |
| `useFormDirty` | Dirty-state tracking with toast notifications |
| `useTableFilters` | Filter builder with URL persistence and backend filter generation |
| `useModelWatch` | Deep watcher for model changes with debounce |
| `useAppFormElement` | Shared form element logic (labels, errors, required state) |
| `useAdaptiveDropdown` | Dropdown positioning that adapts to viewport boundaries |
| `useTeleport` | Helper for teleporting content to specific DOM targets |
| `useScrollToError` | Auto-scroll to the first validation error in a form |

---

## 🏗️ Architecture

### Repository Pattern

`BaseRepository` provides a complete data-access layer with built-in request deduplication:

```js
import { BaseRepository } from '@stsdti/funky-ui-kit'
import axios from 'axios'

class UserRepository extends BaseRepository {
  constructor() {
    super('/api/users', axios)
  }
}

const repo = new UserRepository()

// CRUD
const user = await repo.fetchOne(1)
const users = await repo.fetchAll({ filters: [{ field: 'role', value: 'admin' }] })
await repo.insert({ name: 'John' })
await repo.update(1, { name: 'Jane' })
await repo.delete(1)

// Table integration
const tableData = await repo.fetchTable(tableRequest)

// Fetch all pages automatically
const allRecords = await repo.fetchAllWithMerge({ filters: [...], limit: 100 })
```

### Transformer Pattern

Transform data between API and frontend representations:

```js
class UserTransformer extends Transformer {
  transformFromApi(data) {
    return { ...data, fullName: `${data.first_name} ${data.last_name}` }
  }

  transformToApi(data) {
    const { fullName, ...rest } = data
    return rest
  }
}
```

### Model Pattern

Models tie together repositories, transformers, empty states, and routes:

```js
class UserModel extends BaseModel {
  getRepository() { return new UserRepository() }
  getTransformer() { return new UserTransformer() }
  getEmpty() { return { name: '', email: '', role: null } }
  getRouteForm() { return '/users/:id' }
  getRouteList() { return '/users' }
}
```

---

## 🛠️ Utilities

### DateUtils
Date formatting and manipulation powered by `date-fns`.

### UIUtils
UI helpers including toast notifications (`showToastSuccess`, `showToastError`) and SweetAlert2 confirmations (`showDeleteConfirmation`).

### ResponseUtils
Response status checking and error extraction helpers.

### VueUtils
Advanced Vue reactivity utilities:

| Function | Description |
|---|---|
| `getFormBuilder(veeForm)` | Create form bindings from a VeeValidate form instance |
| `getBinding(veeForm, path)` | Generate reactive field binding with validation |
| `bindOneWay(source, dest)` | One-directional reactive binding between refs |
| `bindTwoWay(source, dest)` | Bi-directional reactive binding between refs |
| `generateComputedChildren(ref, keys)` | Create computed properties for nested object keys |
| `getBindingImmutableFor(modelValue)` | Immutable binding factory for deeply nested forms |
| `flattenSchemaFields(fields)` | Flatten nested Yup schema for field enumeration |

### Other Utilities

| Module | Description |
|---|---|
| `AccentUtils` | Diacritics-aware string normalization |
| `DataUtils` | General data manipulation helpers |
| `TableUtils` | Table request/response factories |
| `UrlUtils` | URL manipulation utilities |
| `BackgroundColorUtils` | Dynamic background color calculations |
| `BreadcrumbUtils` | Breadcrumb path generation |

---

## 📋 Directives

### `v-horizontal-scroll`

Enables horizontal scrolling via mouse wheel on any container element.

```vue
<div v-horizontal-scroll>
  <!-- horizontally overflowing content -->
</div>
```

---

## ⚙️ Configuration

### Colors
A comprehensive color palette available via `Colors.js` — provides a curated set of named colors for consistent theming across the application.

### IconConstants
A centralized icon mapping dictionary providing consistent icon usage throughout the application, backed by `@tabler/icons-vue`.

### Constants
Application-wide constants including default pagination values and shared enumerations.

### APIConstants
HTTP status code helpers and response validation utilities.

---

## 🔧 Development

### Prerequisites

- Node.js 18+
- npm 9+

### Setup

```bash
git clone <repository-url>
cd funky-ui-kit
npm install
```

### Available Scripts

| Command | Description |
|---------|-------------|
| `npm run dev` | Start the Vite dev server with the demo app |
| `npm run build` | Build the library for production |
| `npm run build:watch` | Build in watch mode for development |
| `npm run build:package` | Build in package mode |
| `npm run post-processing` | Generate composable re-exports and type declarations |
| `npm run lint` | Lint and auto-fix with ESLint |
| `npm run format` | Format code with Prettier |

### Project Structure

```
funky-ui-kit/
├── src/
│   ├── assets/              # Theme files, fonts, icons (Limitless theme)
│   ├── components/
│   │   ├── big/             # Layout components (Sidebar, Toolbar, Footer)
│   │   └── small/           # All feature components (70+ components)
│   ├── composables/         # Vue composables (useForm, useTable, useSelect, …)
│   ├── config/              # Constants, colors, icons, API config
│   ├── directives/          # Custom Vue directives
│   ├── mixins/              # Shared prop definitions
│   ├── models/              # BaseModel, Media model
│   ├── repositories/        # BaseRepository
│   ├── transformers/        # Transformer, ApiTransformer
│   ├── utils/               # Utility modules
│   ├── components.js        # Component registry
│   ├── index.js             # Library entry point & exports
│   └── plugin.js            # Vue plugin core (router, media config)
├── demo/                    # Demo/playground app
├── scripts/                 # Build post-processing scripts
├── dist/                    # Built output
├── web-types.json           # JetBrains IDE autocomplete support
└── package.json
```

---

## 🤝 IDE Support

Funky UI Kit ships with `web-types.json` for **JetBrains IDEs** (WebStorm, IntelliJ) — providing full component autocompletion, prop hints, and documentation inline.

For **VS Code**, install the [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) extension for optimal Vue 3 + TypeScript support.

---

## 📄 Key Dependencies

| Package | Purpose |
|---------|---------|
| `@tabler/icons-vue` | Icon library |
| `@vuepic/vue-datepicker` | Date picker engine |
| `@vueuse/core` | Vue composition utilities |
| `date-fns` | Date manipulation |
| `dompurify` | HTML sanitization |
| `gsap` | Animations |
| `pdfjs-dist` | PDF rendering |
| `docx-preview` | DOCX file preview |
| `sweetalert2` | Alert/confirmation dialogs |
| `vue-tippy` | Tooltip directive |
| `vue-toast-notification` | Toast notifications |
| `vuedraggable` | Drag-and-drop lists |
| `viewerjs` | Image viewer |

---

<p align="center">
  <sub>Built with ❤️ by <strong>STS — DTI</strong></sub>
</p>