@preline/tree-view
v4.2.0
Published
Preline UI is an open-source set of prebuilt UI components based on the utility-first Tailwind CSS framework.
Downloads
690
Readme
Tree View
Tree View solutions for massive datasets.
Contents
Overview
The Tree View component provides a hierarchical structure for displaying nested data, similar to file explorers. It integrates with the Accordion component to create expandable/collapsible tree nodes and supports both checkbox and button selection modes.
Key Features:
- Hierarchical nested structure
- Expandable/collapsible nodes (using Accordion)
- Multiple selection modes (checkbox, button)
- Auto-select children option for directories
- Programmatic control via JavaScript API
- Event system for selection tracking
- Accessibility attributes (ARIA) built-in
Installation
To get started, install Tree View plugin via npm, else you can skip this step if you are already using Preline UI as a package.
npm i @preline/tree-view @preline/accordionCSS
Use @source to register the plugin's JavaScript path for Tailwind CSS scanning, then @import the plugin's CSS files into your Tailwind CSS file.
@import "tailwindcss";
/* @preline/accordion */
@source "../node_modules/@preline/accordion/*.js";
@import "./node_modules/@preline/accordion/variants.css";
/* @preline/tree-view */
@source "../node_modules/@preline/tree-view/*.js";
@import "./node_modules/@preline/tree-view/variants.css";
@import "./node_modules/@preline/tree-view/theme.css";JavaScript
Include the JavaScript that powers the interactive elements near the end of your </body> tag:
<script src="./node_modules/@preline/accordion/index.js"></script>
<script src="./node_modules/@preline/tree-view/index.js"></script>Manual Initialization
Use the non-auto entry if you need manual initialization. Tree View depends on Accordion for expand/collapse behavior, so call HSAccordion.autoInit() first and then initialize the specific Tree View element manually.
<script type="module">
import HSAccordion from "@preline/accordion/non-auto.mjs";
import HSTreeView from "@preline/tree-view/non-auto.mjs";
HSAccordion.autoInit();
new HSTreeView(document.querySelector("#tree-view"));
</script>Via Bundler
When using a bundler (Vite, webpack, etc.), import the plugin directly as an ES module. Initialize HSAccordion first, since it powers the expand/collapse nodes inside the tree.
The first example uses the auto-init entries. This means the plugins scan the DOM and initialize matching elements automatically.
The second example uses the manual non-auto entries. Use this when you want explicit control over initialization order and timing, or when you need to initialize a specific Tree View instance yourself.
import "@preline/accordion";
import "@preline/tree-view";import HSAccordion from "@preline/accordion/non-auto";
import HSTreeView from "@preline/tree-view/non-auto";
// Initialize all matching accordion nodes first
HSAccordion.autoInit();
// Then initialize all matching tree views
HSTreeView.autoInit();
// Or initialize a specific element manually
const el = document.querySelector("#tree-view");
if (el) new HSTreeView(el);TypeScript
This package ships with TypeScript type definitions. No additional @types/ package is needed.
Basic usage
The following example demonstrates the minimal HTML structure required for a tree view component. This is a base template without custom styling - you can apply your own CSS classes and styles as needed. The example shows a directory structure with expandable folders and files.
<div role="tree" aria-orientation="vertical" data-hs-tree-view>
<div class="hs-accordion active" role="treeitem" aria-expanded="true" id="hs-tree-view-heading-first" data-hs-tree-view-item='{
"value": "assets",
"isDir": true
}'>
<div class="hs-accordion-heading">
<button class="hs-accordion-toggle" aria-expanded="true" aria-controls="hs-tree-view-collapse-first">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path class="hs-accordion-active:hidden block" d="M12 5v14"/></svg>
</button>
assets
</div>
<div id="hs-tree-view-collapse-first" class="hs-accordion-content overflow-hidden transition-[height] duration-300" role="group" aria-labelledby="hs-tree-view-heading-first">
<div role="treeitem" data-hs-tree-view-item='{
"value": "image.jpg"
}'>image.jpg</div>
</div>
</div>
</div>Structure Requirements:
data-hs-tree-view: Required on the root container elementrole="tree": Required on the root containeraria-orientation="vertical": Required on the root containerhs-accordion: Required for each directory/folder nodedata-hs-tree-view-item: Required on each tree item (files and directories)- Proper ARIA attributes (
role="treeitem",aria-expanded,aria-controls,aria-labelledby)
Initial State:
- Directories can be expanded/collapsed using accordion functionality
- Items can be selected based on the
controlBymode
Configuration Options
Data Options
Data options are specified in the data-hs-tree-view and data-hs-tree-view-item attributes.
| Attribute | Target Element | Type | Default | Description |
| --- | --- | --- | --- | --- |
| data-hs-tree-view | Root container | - | - | Activate a Tree View by specifying on an element. Should be added to the wrapper container. |
| :controlBy | Inside data-hs-tree-view | "checkbox" | "button" | "button" | Tells the plugin which mode is active and processes events accordingly. checkbox mode allows multiple selections, button mode allows single selection. |
| :autoSelectChildren | Inside data-hs-tree-view | boolean | false | This option is available if controlBy is set to checkbox and if the item is a directory (isDir: true). When true, if a parent directory is selected, all nested items receive the same selection state. |
| :isIndeterminate | Inside data-hs-tree-view | boolean | true | Adds indeterminate visual style for checkboxes when controlBy is set to checkbox. Shows when some but not all children are selected. |
| data-hs-tree-view-item | Each tree item | - | - | Determines which element inside the initialized component is the item. Should be added to the item itself. |
| :id | Inside data-hs-tree-view-item | string | - | Optional. Desired identifier for the item. |
| :value | Inside data-hs-tree-view-item | string | - | The value that will be passed to the resulting array when item is selected. |
| :isDir | Inside data-hs-tree-view-item | boolean | false | Determines that the element is a directory and processes it accordingly. Directories can contain nested items. |
Example:
<div data-hs-tree-view='{
"controlBy": "checkbox",
"autoSelectChildren": true,
"isIndeterminate": true
}'>
<!-- Tree items -->
</div>Tailwind Modifiers
| Name | Description |
| --- | --- |
| hs-tree-view-selected:* | A modifier that allows you to set Tailwind classes when item has been selected. |
| hs-tree-view-disabled:* | A modifier that allows you to set Tailwind classes when item has "disabled" class. |
JavaScript API
The HSTreeView object is available in the global window object after the plugin is loaded.
Instance Methods
These methods are called on a tree view instance.
| Method | Parameters | Return Type | Description |
| --- | --- | --- | --- |
| update() | None | void | Updates the element. This is suitable, for example, in case of changing the order of elements or dynamically adding/removing items. |
| getSelectedItems() | None | ITreeViewItem[] | Returns a list of selected items as an array of objects with item properties. |
| changeItemProp(id, prop, val) | id: stringprop: stringval: any | void | Changes a property of a specific item. Useful for updating item state programmatically. |
| destroy() | None | void | Destroys the tree view instance, removes all generated markup, classes, and event listeners. Use when removing tree view from DOM. |
Static Methods
These methods are called directly on the HSTreeView class.
| Method | Parameters | Return Type | Description |
| --- | --- | --- | --- |
| HSTreeView.getInstance(target, isInstance) | target: HTMLElement \| string (CSS selector)isInstance: boolean (optional) | HTMLElement \| { id: string \| number, element: HSTreeView } \| null | Returns the tree view instance or element associated with the target. If isInstance is true, returns collection item object { id, element } where element is the HSTreeView instance. If isInstance is false or omitted, returns the DOM element (HTMLElement). Returns null if tree view instance is not found. |
Usage Examples
Example 1: Getting selected items
// Get the tree view instance
const instance = HSTreeView.getInstance('#hs-tree-view', true);
if (instance) {
const { element } = instance;
// Get all selected items
const selectedItems = element.getSelectedItems();
console.log('Selected items:', selectedItems);
}Example 2: Updating tree view after dynamic changes
const instance = HSTreeView.getInstance('#hs-tree-view', true);
if (instance) {
const { element } = instance;
// After adding or removing items dynamically
element.update();
}Example 3: Changing item properties programmatically
const instance = HSTreeView.getInstance('#hs-tree-view', true);
if (instance) {
const { element } = instance;
// Change item property
element.changeItemProp('item-id', 'isSelected', true);
}Example 4: Destroying tree view instance
const instance = HSTreeView.getInstance('#hs-tree-view', true);
if (instance) {
const { element } = instance;
const removeBtn = document.querySelector('#hs-remove-btn');
removeBtn.addEventListener('click', () => {
// Clean up before removing from DOM
element.destroy();
// Now safe to remove the element
document.querySelector('#hs-tree-view').remove();
});
}Events
Tree view instances emit events that can be listened to for selection tracking and custom behavior.
| Event Name | When Fired | Callback Parameter | Description |
| --- | --- | --- | --- |
| on:click | When any item is selected | { id: string, value: string, isDir: boolean, path: string, isSelected: boolean } | Fires when an item is clicked/selected. Returns an object with:- id: Item identifier- value: Item value- isDir: Whether item is a directory- path: Path to the item- isSelected: Whether item is currently selected |
Event Usage Example
// Get tree view instance
const instance = HSTreeView.getInstance('#hs-tree-view', true);
if (instance) {
const { element } = instance;
// Listen to click event
element.on('click', ({ id, value, isDir, path, isSelected }) => {
console.log('Item clicked:', {
id,
value,
isDirectory: isDir,
path,
isSelected
});
// Perform actions after item selection
// e.g., update UI, track analytics, load content
});
}Common Patterns
Pattern 1: Checkbox Mode with Auto-select Children
Enable checkbox selection with automatic child selection.
<div data-hs-tree-view='{
"controlBy": "checkbox",
"autoSelectChildren": true
}'>
<!-- Tree items -->
</div>Pattern 2: Getting Selected Items
Retrieve all selected items programmatically.
<div id="hs-tree-view-first" data-hs-tree-view>
<!-- Tree items -->
</div>
<button id="hs-get-selected">Get Selected</button>
<script>
const instance = HSTreeView.getInstance('#hs-tree-view-first', true);
if (instance) {
const { element } = instance;
document.querySelector('#hs-get-selected').addEventListener('click', () => {
const selected = element.getSelectedItems();
console.log('Selected items:', selected);
});
}
</script>License
Copyright (c) 2026 Preline Labs.
Licensed under the MIT License.
