Appearance
Towser Component
A full-height slide-in panel component for displaying detailed content alongside the main page. Unlike a Modal which overlays the center of the screen, the Towser slides in from the right edge and occupies the full viewport height — ideal for editing forms, detail views, and data-heavy content that needs more space.
Table of Contents
Import
ts
import { Towser } from "dolphin-components";
import type { TowserProps, TowserTitle, TowserAction } from "dolphin-components";Basic Usage
vue
<template>
<button @click="showPanel = true" class="btn btn-primary">Open Panel</button>
<Towser
:show="showPanel"
:title="[{ name: 'User Details' }]"
:actions="[
{ title: 'Cancel', emit: 'onClose' },
{ title: 'Save', emit: 'onSave', class: 'btn btn-primary' },
]"
@onClose="showPanel = false"
@onSave="handleSave"
>
<p>Panel content goes here.</p>
</Towser>
</template>
<script setup>
import { ref } from "vue";
import { Towser } from "dolphin-components";
const showPanel = ref(false);
const handleSave = () => {
console.log("Saving...");
showPanel.value = false;
};
</script>Props
| Prop | Type | Default | Description |
|---|---|---|---|
show | boolean | false | Controls visibility of the panel. |
title | TowserTitle[] | [] | Breadcrumb-style title array with optional links. |
actions | TowserAction[] | [] | Footer action buttons. Each emits the specified event on click. |
double | boolean | false | Enable a two-column (split-pane) layout inside the panel. |
bodyWidth | number | 50 | Width percentage of the first column when double is true. |
body2Width | number | 50 | Width percentage of the second column when double is true. |
Events
| Event | Payload | Description |
|---|---|---|
onClose | — | Emitted when the panel should be closed. |
[custom emit] | — | Custom events from action buttons. Name comes from the emit property of the action. |
Slots
| Slot Name | Description |
|---|---|
default | Main content area of the panel. |
body2 | Second column content (only used when double is true). |
TypeScript Interfaces
typescript
interface TowserTitle {
name: string; // Display text
link?: string; // Optional Vue Router link path
}
interface TowserAction {
emit: string; // Event name to emit when clicked
title: string; // Button label text
class?: string; // CSS class for the button
}
interface TowserProps {
show: boolean;
title: TowserTitle[];
actions?: TowserAction[];
double?: boolean;
bodyWidth?: number;
body2Width?: number;
}Usage Examples
With Breadcrumb Title
vue
<Towser
:show="showPanel"
:title="[
{ name: 'Users', link: '/users' },
{ name: 'Edit User' },
]"
:actions="[{ title: 'Close', emit: 'onClose' }]"
@onClose="showPanel = false"
>
<form>
<label class="input-label">Name</label>
<input class="input-text" v-model="userName" />
</form>
</Towser>Two-Column (Split-Pane) Layout
Use the double prop to create a side-by-side layout, useful for showing a form alongside related data:
vue
<Towser
:show="showPanel"
:double="true"
:bodyWidth="60"
:body2Width="40"
:title="[{ name: 'Dashboard' }, { name: 'Product Details' }]"
:actions="[
{ title: 'Cancel', emit: 'onClose' },
{ title: 'Save', emit: 'onSave', class: 'btn btn-primary' },
]"
@onClose="showPanel = false"
@onSave="handleSave"
>
<template #default>
<h3>Product Form</h3>
<label class="input-label">Product Name</label>
<input class="input-text" v-model="product.name" />
<label class="input-label mt-3">Price</label>
<input class="input-text" v-model="product.price" type="number" />
</template>
<template #body2>
<h3>Preview</h3>
<div class="bg-gray-50 p-4 rounded">
<p class="font-bold">{{ product.name }}</p>
<p class="text-gray-600">Rs. {{ product.price }}</p>
</div>
</template>
</Towser>With TypeScript
vue
<script setup lang="ts">
import { ref } from "vue";
import { Towser, type TowserTitle, type TowserAction } from "dolphin-components";
const showPanel = ref(false);
const title: TowserTitle[] = [
{ name: "Settings", link: "/settings" },
{ name: "Profile" },
];
const actions: TowserAction[] = [
{ title: "Cancel", emit: "onClose" },
{ title: "Update", emit: "onUpdate", class: "btn btn-primary" },
];
</script>
<template>
<Towser
:show="showPanel"
:title="title"
:actions="actions"
@onClose="showPanel = false"
@onUpdate="handleUpdate"
>
<p>Profile settings form...</p>
</Towser>
</template>Screenshot

Best Practices
- Use Towser for data-heavy forms — When a Modal feels too cramped, the Towser's full-height design gives more room.
- Use breadcrumb titles — Provide navigation context, especially when opened from a list/detail page.
- Use the
doublelayout for preview — Show a form on one side and a live preview on the other. - Control from parent — Always set
:show="showPanel"and handle@onClose="showPanel = false"in the parent component.
Troubleshooting
Panel doesn't open
- Ensure
showis bound to a reactiverefvariable set totrue. - Check that no CSS is hiding overflow on the parent container.
Second column not visible
- Set
:double="true"to enable the two-column layout. - Provide content in the
#body2slot.
Actions not triggering
- Ensure the
@event listener matches theemitvalue exactly (e.g.,emit: 'onSave'→@onSave).
Notes
- The component uses a slide-in transition from the right edge.
- The header dynamically generates breadcrumb navigation from the
titleprop. - When
doubleistrue, the panel creates a split-pane layout with configurable column widths. - The Towser uses
<Teleport>for proper rendering above other content.