@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 Composables —
useForm,useTable,useSelect, and more for rapid feature development - 🏗️ Repository Pattern — Built-in
BaseRepositorywith filtering, sorting, pagination, and request deduplication - 🎯 Form Binding System — Reactive
getBinding()API that wires upv-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-kitPeer 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 installAvailable 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 |
