A framework-agnostic web component wrapper for @keenmate/svelte-treeview. This component allows you to use the powerful Svelte TreeView in any web framework including React, Vue, Angular, or vanilla JavaScript.
Note: This is a wrapper around the original Svelte TreeView component. For comprehensive documentation about features, search options, and advanced configurations, please refer to the Svelte TreeView documentation.
- π Framework Agnostic: Works with React, Vue, Angular, or vanilla JavaScript
- π Full-text Search: Built-in search with FlexSearch integration
- π― Drag & Drop: Native drag and drop support with customizable handlers
- π¨ Custom Templates: Flexible template system using slots or functions
- π± Responsive: Mobile-friendly with touch support
- β‘ Performance: Virtual scrolling for large datasets
- π TypeScript: Full TypeScript support with type definitions
- π§© Extensible: Rich API with events and methods
- π― Accessible: ARIA compliant and keyboard navigation
npm install @keenmate/svelte-treeview-webcomponent<!DOCTYPE html>
<html>
<head>
<script type="module" src="./node_modules/@keenmate/svelte-treeview-webcomponent/dist/web-treeview.js"></script>
</head>
<body>
<svelte-tree-view
id="my-tree"
id-member="id"
path-member="path"
display-value-member="name"
expand-level="2">
</svelte-tree-view>
<script>
const tree = document.getElementById('my-tree');
tree.data = [
{ id: '1', path: '1', name: 'Documents' },
{ id: '2', path: '1.1', name: 'Projects' },
{ id: '3', path: '1.1.1', name: 'Web App' },
{ id: '4', path: '1.1.1.1', name: 'index.html' }
];
// Event listeners
tree.addEventListener('node-clicked', (e) => {
console.log('Clicked:', e.detail.node.data.name);
});
</script>
</body>
</html>import React, { useEffect, useRef } from 'react';
import '@keenmate/svelte-treeview-webcomponent';
import type { SvelteTreeView } from '@keenmate/svelte-treeview-webcomponent';
const MyComponent = () => {
const treeRef = useRef<SvelteTreeView>(null);
useEffect(() => {
if (treeRef.current) {
treeRef.current.data = [
{ id: '1', path: '1', name: 'Root' },
{ id: '2', path: '1.1', name: 'Child' }
];
}
}, []);
return (
<svelte-tree-view
ref={treeRef}
id-member="id"
path-member="path"
expand-level={2}
onNodeClicked={(e) => console.log('Node clicked:', e.detail.node)}
/>
);
};<template>
<svelte-tree-view
ref="treeRef"
id-member="id"
path-member="path"
:expand-level="2"
@node-clicked="handleNodeClick"
/>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import '@keenmate/svelte-treeview-webcomponent';
const treeRef = ref();
onMounted(() => {
treeRef.value.data = [
{ id: '1', path: '1', name: 'Root' },
{ id: '2', path: '1.1', name: 'Child' }
];
});
const handleNodeClick = (event) => {
console.log('Node clicked:', event.detail.node);
};
</script>Important: This web component automatically converts between JavaScript camelCase properties and HTML kebab-case attributes:
| JavaScript Property | HTML Attribute | Description |
|---|---|---|
idMember |
id-member |
Property name for unique identifier |
pathMember |
path-member |
Property name for hierarchical path |
displayValueMember |
display-value-member |
Property name for display text |
searchValueMember |
search-value-member |
Property name for search text |
expandLevel |
expand-level |
Initial expansion level |
scrollHighlightClass |
scroll-highlight-class |
CSS class for scroll highlighting |
Examples:
<!-- HTML attributes (kebab-case) -->
<svelte-tree-view
display-value-member="name"
expand-level="2"
scroll-highlight-class="highlight">
</svelte-tree-view>// JavaScript properties (camelCase)
tree.displayValueMember = 'name';
tree.expandLevel = 2;
tree.scrollHighlightClass = 'highlight';Use HTML templates with slot attributes to customize rendering:
<svelte-tree-view id-member="id" path-member="path">
<!-- Custom node template -->
<template slot="node-template">
<div class="custom-node">
<span class="icon">\${node.data.type === 'folder' ? 'π' : 'π'}</span>
<span class="name">\${node.data.name}</span>
<span class="size">\${node.data.size || ''}</span>
</div>
</template>
<!-- Header template -->
<template slot="tree-header">
<h3>π File Explorer</h3>
</template>
<!-- Empty state template -->
<template slot="no-data-found">
<div class="empty-state">No files found π</div>
</template>
</svelte-tree-view>Or set templates programmatically:
const tree = document.querySelector('svelte-tree-view');
tree.setNodeTemplate((node) => `
<div class="custom-node">
<strong>\${node.data.name}</strong>
<small>\${node.path}</small>
</div>
`);id-member: Property name for unique node identifierspath-member: Property name for hierarchical paths (e.g., "1", "1.1", "1.2.3")
| Attribute | Type | Default | Description |
|---|---|---|---|
expand-level |
number | 2 | Default expansion level |
search-text |
string | "" | Current search query |
tree-path-separator |
string | "." | Path separator character |
should-toggle-on-node-click |
boolean | true | Toggle expansion on click |
should-use-internal-search-index |
boolean | true | Enable FlexSearch integration |
should-display-debug-information |
boolean | false | Show debug info |
| Attribute | Description |
|---|---|
selected-node-class |
CSS class for selected nodes |
drag-over-node-class |
CSS class during drag over |
expand-icon-class |
CSS class for expand icons |
collapse-icon-class |
CSS class for collapse icons |
leaf-icon-class |
CSS class for leaf node icons |
const tree = document.querySelector('svelte-tree-view');
// Expansion control
await tree.expandNodes('1.2'); // Expand specific path
await tree.collapseNodes('1.2'); // Collapse specific path
tree.expandAll(); // Expand all nodes
tree.collapseAll(); // Collapse all nodes
// Search and filtering
tree.filterNodes('search term'); // Filter visible nodes
const results = tree.searchNodes('query'); // Get search results
// Navigation
await tree.scrollToPath('1.2.3', {
behavior: 'smooth',
block: 'center'
});
// Event handlers
tree.onNodeClicked = (node) => console.log('Clicked:', node);
tree.onNodeDragStart = (node, event) => console.log('Drag start:', node);
tree.onNodeDragOver = (node, event) => console.log('Drag over:', node);
tree.onNodeDrop = (dropNode, draggedNode, event) => {
console.log('Dropped:', draggedNode, 'on:', dropNode);
};Listen for custom events:
tree.addEventListener('node-clicked', (e) => {
console.log('Node clicked:', e.detail.node);
});
tree.addEventListener('selected-node-changed', (e) => {
console.log('Selection changed:', e.detail.selectedNode);
});
tree.addEventListener('search-text-changed', (e) => {
console.log('Search changed:', e.detail.searchText);
});
tree.addEventListener('node-drag-start', (e) => {
console.log('Drag started:', e.detail.node, e.detail.event);
});
tree.addEventListener('node-drop', (e) => {
console.log('Node dropped:', e.detail.node, e.detail.draggedNode);
});The component expects hierarchical data using LTree-style paths:
const data = [
{
id: '1', // Unique identifier
path: '1', // Hierarchical path
name: 'Documents', // Display name
// ... custom properties
},
{
id: '2',
path: '1.1', // Child of '1'
name: 'Projects',
},
{
id: '3',
path: '1.1.1', // Child of '1.1'
name: 'Web App',
},
{
id: '4',
path: '1.2', // Another child of '1'
name: 'Images',
}
];The component includes default styles but can be customized:
/* Custom CSS variables */
svelte-tree-view {
--tree-indent: 20px;
--node-height: 32px;
--selected-bg: #e3f2fd;
--hover-bg: #f5f5f5;
--icon-size: 16px;
--font-size: 14px;
}
/* Custom node styling */
svelte-tree-view .custom-node {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 8px;
border-radius: 4px;
}
svelte-tree-view .custom-node:hover {
background-color: var(--hover-bg);
}Check out the examples/ directory for complete implementations:
vanilla.html- Pure JavaScript implementationreact.tsx- React integrationvue.vue- Vue 3 composition API
This web component is a wrapper around @keenmate/svelte-treeview. It provides:
- β Framework-agnostic interface via web components
- β Shadow DOM encapsulation for style isolation
- β HTML attribute β JavaScript property conversion (kebab-case β camelCase)
- β Template slot β Svelte snippet conversion
- β Custom event dispatching for framework integration
For detailed documentation about the underlying TreeView features, search options, advanced configurations, and all available properties, please refer to the Svelte TreeView documentation.
- Attributes: Use kebab-case HTML attributes instead of camelCase props
- Data binding: Set
dataproperty programmatically instead of binding - Events: Listen for CustomEvents instead of component events
- Templates: Use HTML
<template slot="...">instead of Svelte snippets
Contributions are welcome! Please read the contributing guide for details.
MIT License - see LICENSE for details.
- @keenmate/svelte-treeview - Original Svelte component
- FlexSearch - Search engine integration
- π Documentation
- π Issue Tracker
- π¬ Discussions
Made with β€οΈ by KeenMate