npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@stsdti/funky-ui-kit

v1.0.3

Published

A library with all our UI reusable components and helper functions to help speed up Vue development

Readme


✨ Highlights

  • 🧩 70+ Components — From basic inputs to complex data tables, form wizards, and file previews
  • 🪝 Powerful ComposablesuseForm, 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

npm install @stsdti/funky-ui-kit

Peer Dependencies

Make sure the following are installed in your host project:

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

🚀 Quick Start

1. Register the Plugin

// 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

<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

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.

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')
<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.

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.

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:

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:

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:

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.

<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

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 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 |