npm package: @koleszar.norbert/vue3-virtual-keyboard
Description: A professional, touch-screen optimized virtual keyboard plugin for Vue 3
Author: Koleszár Norbert
Latest version: 1.0.0

# Vue 3 Virtual Keyboard Plugin

A professional, touch-screen optimized virtual keyboard for Vue 3 applications.

> 🇭🇺 Magyar dokumentáció: [README.hu.md](README.hu.md)

## Prerequisites

- **Vue 3**
- **Material Design Icons** (for icons — optional but recommended)

## Installation

```bash
npm install @koleszar.norbert/vue3-virtual-keyboard
```

## Setup

### 1. Copy static files (REQUIRED)

The plugin loads its layout and sounds from external files. Copy the following files from the package's `node_modules/@koleszar.norbert/vue3-virtual-keyboard/dist/` folder into your project's `public/` folder:

1. `keyboard-config.json` → Keyboard layouts and color settings.
2. `click.mp3` → Key press sound.

```bash
# Linux / macOS
cp node_modules/@koleszar.norbert/vue3-virtual-keyboard/dist/keyboard-config.json public/
cp node_modules/@koleszar.norbert/vue3-virtual-keyboard/dist/click.mp3 public/

# Windows
copy node_modules\@koleszar.norbert\vue3-virtual-keyboard\dist\keyboard-config.json public\
copy node_modules\@koleszar.norbert\vue3-virtual-keyboard\dist\click.mp3 public\
```

### 2. Register the plugin (main.js)

```javascript
import { createApp } from 'vue'
import App from './App.vue'
import VirtualKeyboard from '@koleszar.norbert/vue3-virtual-keyboard'
import '@koleszar.norbert/vue3-virtual-keyboard/dist/style.css'

const app = createApp(App)

app.use(VirtualKeyboard, {
  // Optional: provide a custom path to the config file
  configUrl: '/keyboard-config.json',
})

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

### 3. Usage in components

Place the `VirtualKeyboard` component (preferably in `App.vue` so it is globally available), then use the `v-virtual-keyboard` directive on input fields.

```vue
<template>
  <div>
    <input type="text" v-virtual-keyboard v-model="textValue" placeholder="Text field" />
    <input type="number" v-virtual-keyboard v-model="numericValue" placeholder="Numeric field" />

    <!-- The keyboard component -->
    <VirtualKeyboard />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const textValue = ref('')
const numericValue = ref(null)
</script>
```

> The plugin also works with Vuetify `v-text-field` components, but **Vuetify is not a required dependency**.

## Directives

`v-virtual-keyboard` activates the keyboard when the input is tapped or clicked.

```html
<!-- Auto-detect from input type -->
<input type="text" v-virtual-keyboard />
<input type="number" v-virtual-keyboard />

<!-- Explicit layout -->
<input v-virtual-keyboard="'text'" />
<input v-virtual-keyboard="'number'" />

<!-- Per-input config override (merged with global config) -->
<input v-virtual-keyboard="{ options: { clickSound: false } }" />
<input v-virtual-keyboard="{ type: 'number', options: { clickSound: false } }" />
```

The directive value can be:
- omitted — layout is inferred from `input type` (`number` → number layout, everything else → text)
- a string layout name: `'text'` or `'number'`
- a config object with optional `type` and `options` fields (deep-merged with global config for this input only)

## Themes

The plugin has two built-in themes: `"dark"` (default) and `"light"`. The theme is set in the `options` section of `keyboard-config.json`:

```json
{
  "options": {
    "theme": "light"
  }
}
```

### Defining a custom theme

You can define custom named themes in the `themes` object, overriding the default colors:

```json
{
  "options": {
    "theme": "custom",
    "themes": {
      "custom": {
        "keyboardBackgroundColor": "#1a1a2e",
        "buttonBackgroundColor": "#16213e",
        "functionButtonBackgroundColor": "#0f3460",
        "buttonTextColor": "#e0e0e0"
      }
    }
  }
}
```

Color properties available under `themes`:

| Property | Description |
|---|---|
| `keyboardBackgroundColor` | Background color of the keyboard |
| `buttonBackgroundColor` | Background color of regular keys |
| `functionButtonBackgroundColor` | Background color of function keys (`shift`, `backspace`, `spec`, `submit`, etc.) |
| `buttonTextColor` | Text color of all keys |
| `accentColor` | Color used for active states (shift/spec pressed) and long-press selection highlight |

### Per-button theme overrides

Each button can have a `themes` object to override colors per theme. This takes priority over the global theme colors for that specific button:

```json
{
  "keyType": "submit",
  "label": "enter",
  "icon": "mdi-arrow-left-bottom-bold",
  "flex": 2,
  "themes": {
    "dark": { "backgroundColor": "#4CAF50" },
    "light": { "backgroundColor": "#2E7D32", "color": "#ffffff" }
  }
}
```

For theme-independent overrides, use `backgroundColor` and `color` directly on the button definition.

---

## Configuration (keyboard-config.json)

The file has two main sections:

- `options`: Theme, custom theme definitions, sound file path, and layouts.
- `options.layouts`: Keyboard layouts (rows and button definitions).

Top-level `options` properties:

| Property | Default | Description |
|---|---|---|
| `theme` | `"dark"` | Active theme name (`"dark"`, `"light"`, or a custom name) |
| `themes` | see above | Theme color definitions |
| `layouts` | built-in | Keyboard layout definitions (`text`, `number`, or custom) |
| `clickSound` | `true` | Enable or disable key press sound (`true` / `false`) |
| `clickSoundUrl` | `"/click.mp3"` | Path to the key press sound file |

Button properties:

- `label`: The character typed and displayed on the key.
- `longPress`: Array of characters shown on long press.
- `spec`: Characters for the special (?123) mode.
- `keyType`: Function key type (`shift`, `backspace`, `spec`, `left`, `right`, `submit`).
- `flex`: Relative width of the key (default: 1).
- `icon`: Icon class name (e.g. `mdi-arrow-up-bold`). If the icon cannot be loaded, `label` is shown instead.
- `color`: Key text color (theme-independent fallback, overrides the theme's `buttonTextColor`).
- `backgroundColor`: Key background color (theme-independent fallback, overrides the theme's button color).
- `themes`: Per-theme color overrides for this button (see above).

## Icons

The default configuration uses **Material Design Icons** (`mdi-*` prefix).

### Installing MDI

```bash
npm install @mdi/font
```

```javascript
// main.js
import '@mdi/font/css/materialdesignicons.css'
```

### Using a different icon set

Any CSS-based icon library can be used — just provide the appropriate class names in the `icon` fields of `keyboard-config.json`. For example, with Font Awesome:

```json
{ "keyType": "backspace", "icon": "fa-solid fa-delete-left", "flex": 1.5 }
```

> **Note:** If an `icon` value does not match a valid CSS class, the plugin automatically falls back to displaying the `label` value.

## License

MIT