) {
+ super.updated(_changedProperties);
+ if (this._open) {
+ if (_changedProperties.has("_open") || _changedProperties.has("_searchText"))
+ this._focusedIndex = 0;
+ const list = this._focusableValues;
+
+ this._focusedIndex = Math.min(this._focusedIndex, Math.max(0, list.length - 1));
+ }
+ }
+
+ private _renderCount(node: TreeNode): TemplateResult | string {
+ return node.count != null ? html`${node.count}` : "";
+ }
+
+ private _renderNode(node: TreeNode, depth: number): TemplateResult {
+ const hasChildren = !!node.children?.length;
+ const expanded = this._isExpanded(node);
+ const checked = this._isChecked(node);
+ const indeterminate = this._isIndeterminate(node);
+ const expandIcon = hasChildren ? (expanded ? "arrow_down" : "arrow_right") : null;
+ const singleMode = !this.isMultiple;
+ const isLeaf = !hasChildren;
+ const singleLeafChecked = singleMode && isLeaf && this._singleValue === node.value;
+ const singleParent = singleMode && hasChildren;
+
+ const rowFocused = this._focusedValue === node.value;
+
+ return html`
+
+
+ {
+ e.stopPropagation();
+ if (hasChildren) this._toggleExpand(node);
+ }}
+ role="button"
+ tabindex=${hasChildren ? 0 : -1}
+ aria-expanded=${hasChildren && expanded}
+ >
+ ${expandIcon
+ ? html``
+ : html``}
+
+ ${singleParent
+ ? html`
+ ${node.label}
+ ${this._renderCount(node)}
+ `
+ : singleMode && isLeaf
+ ? html`
+ ) =>
+ this._setSingleLeafValue(node, e.detail)}
+ >
+ ${node.label}
+
+ ${this._renderCount(node)}
+ `
+ : html`
+ ) =>
+ this._toggleNode(node, e.detail)}
+ >
+ ${node.label}
+
+ ${this._renderCount(node)}
+ `}
+
+ ${hasChildren && expanded
+ ? html`
+
+ ${node.children!.map(child => this._renderNode(child, depth + 1))}
+
+ `
+ : ""}
+
+ `;
+ }
+
+ private _renderTree(nodes: TreeNode[]): TemplateResult {
+ const visible = this._filterVisible(nodes, this._searchText.toLowerCase());
+
+ return html` ${visible.map(node => this._renderNode(node, 0))}
`;
+ }
+
+ private _renderAutocompleteList(): TemplateResult {
+ return html`
+
+ ${this._autocompleteList.map(
+ ({ node, path }) => html`
+
this._selectAutocompleteItem(node)}
+ >
+ ${this._highlightPath(path, this._searchText)}
+
+ `
+ )}
+
+ `;
+ }
+
+ private _renderSelectAllRow(): TemplateResult | string {
+ if (!this.isMultiple || !this.viewSelectAll) return "";
+ const { checked, indeterminate } = this._selectAllState;
+ const count = this.selectedSet.size;
+
+ return html`
+
+ ) => this._handleSelectAll(e.detail)}
+ >
+ ${this.selectAllText || msg("Select All", { desc: "bl-select: select all text" })}
+ ${count > 0
+ ? html`${msg(str`(${count} selected)`, { desc: "bl-tree-select: selected count" })}`
+ : ""}
+
+
+ `;
+ }
+
+ private _renderPanelContent(): TemplateResult {
+ if (this._searchText.trim()) {
+ return this._autocompleteList.length > 0
+ ? this._renderAutocompleteList()
+ : html`
+ ${this.searchNotFoundText ??
+ msg("No Result Found", { desc: "bl-tree-select: search no result text" })}
+
`;
+ }
+ return html`${this._renderSelectAllRow()} ${this._renderTree(this.items)}`;
+ }
+
+ render(): TemplateResult {
+ const displayText = this._getDisplayText();
+ const searchPh =
+ this.searchPlaceholder ||
+ this.placeholder ||
+ msg("Search...", { desc: "bl-tree-select: search placeholder" });
+ const inputPlaceholder = this._open ? searchPh : displayText || this.placeholder || undefined;
+
+ return html`
+
+ ${this.label
+ ? html``
+ : ""}
+
+ {
+ if (this._open) e.stopPropagation();
+ }}
+ />
+ ${this.isSearchLoading && this._open
+ ? html``
+ : ""}
+ ${this._hasValue && !this.disabled
+ ? html`
+ {
+ e.stopPropagation();
+ this._clearSelection();
+ }}
+ >
+ `
+ : ""}
+
+
+
+
+ ${this._renderPanelContent()}
+
+
+
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "bl-tree-select": BlTreeSelect;
+ }
+}
diff --git a/src/components/tree-select/doc/ADR.md b/src/components/tree-select/doc/ADR.md
new file mode 100644
index 000000000..75e796572
--- /dev/null
+++ b/src/components/tree-select/doc/ADR.md
@@ -0,0 +1,91 @@
+# Tree Select Component
+
+## Figma Design Document
+
+[Baklava Design Guide – Tree Select](https://www.figma.com/design/RrcLH0mWpIUy4vwuTlDeKN/Baklava-Design-Guide?node-id=26640-5823&p=f&t=FjujjxTaCNkGYHd4-0)
+
+## ADR / Issue
+
+[Component: Tree Select (#1125)](https://github.com/Trendyol/baklava/issues/1125)
+
+## Overview
+
+The Tree Select component allows hierarchical selection (e.g. category tree). It supports single and multiple selection, expand/collapse, autocomplete with path display, keyboard navigation, and optional "Select All".
+
+## Implementation
+
+### General usage example
+
+```html
+
+```
+
+Tree data shape (`TreeNode[]`):
+
+```ts
+interface TreeNode {
+ value: string;
+ label: string;
+ count?: number;
+ children?: TreeNode[];
+}
+```
+
+### Rules
+
+- **Single mode (`is-multiple="false"`)**: Only leaf nodes (nodes without children) are selectable; parent nodes have no checkbox and only expand/collapse.
+- **Multiple mode**: All nodes have checkboxes; optional "Select All" row when `view-select-all` is set.
+- **Autocomplete**: When the user types in the input, the panel shows a filtered list of paths (e.g. `Parent/Child/Leaf`) with the search term highlighted; when there are no matches, the empty state message is shown.
+- **Value**: Single mode uses `string | null`; multiple mode uses `string[]`.
+
+---
+
+## API Reference
+
+### `bl-tree-select`
+
+| Attribute | Type | Description | Default |
+| --------- | ---- | ----------- | ------- |
+| `label` | `string` | Label above the input | `""` |
+| `placeholder` | `string` | Placeholder for the input | `""` |
+| `items` | `TreeNode[]` | Tree data (root nodes with optional `children`, `count`) | `[]` |
+| `value` | `string \| string[] \| null` | Selected value(s). Single: one string; multiple: array of strings | `null` |
+| `is-multiple` | `boolean` | Multiple selection with checkboxes and Select All; when false, single selection (leaf-only) | `true` |
+| `view-select-all` | `boolean` | Show "Select All" row (only when `is-multiple`) | `false` |
+| `select-all-text` | `string` | Text for Select All row | `""` (localized fallback: `"Select All"`) |
+| `search-placeholder` | `string` | Placeholder for search inside dropdown | `""` (localized fallback: `"Search..."`) |
+| `empty-result-text` | `string` | Message when search has no results | `undefined` (localized fallback: `"No Result Found"`) |
+| `disabled` | `boolean` | Disables the component | `false` |
+| `required` | `boolean` | Marks the field as required | `false` |
+
+### Events
+
+| Event | Description | Payload |
+| ----- | ----------- | ------- |
+| `bl-tree-select-change` | Fired when selection changes | `{ value: string \| string[] \| null }` |
+
+### Methods
+
+| Method | Description |
+| ------ | ----------- |
+| `open()` | Opens the dropdown panel |
+| `close()` | Closes the dropdown and clears search text |
+
+---
+
+## States
+
+- **Default**: Input with placeholder; chevron indicates dropdown.
+- **Open**: Panel with tree or autocomplete list; loading spinner shown while user is typing (when search is non-empty).
+- **Selected**: Selected item(s) shown in input; clear (X) button visible when not disabled.
+- **Empty (no results)**: When search has no matches, panel shows `empty-result-text` in a bordered message area.
+- **Disabled**: Component is dimmed and non-interactive; cursor `not-allowed`.
diff --git a/src/generated/locales/ar.ts b/src/generated/locales/ar.ts
index 00d1aa5e9..28b1385d5 100644
--- a/src/generated/locales/ar.ts
+++ b/src/generated/locales/ar.ts
@@ -23,5 +23,9 @@
'sbaace8219b5f4612': `اختر الكل`,
'sc2b31c8d71636c74': str`صفحة ${0}`,
'sf3ff78cc329d3528': `السابق`,
+'s837243444fe86fab': str`(${0} selected)`,
+'s011cb4b34942843f': `No Result Found`,
+'sffa721bb6aa3128d': `Search...`,
+'sb4f1dffbb6be6302': `Clear`,
};
\ No newline at end of file
diff --git a/src/generated/locales/ro.ts b/src/generated/locales/ro.ts
index d1fad197d..312202449 100644
--- a/src/generated/locales/ro.ts
+++ b/src/generated/locales/ro.ts
@@ -23,5 +23,9 @@
'sbaace8219b5f4612': `Selectează tot`,
'sc2b31c8d71636c74': str`Pagina ${0}`,
'sf3ff78cc329d3528': `Anteriorul`,
+'s837243444fe86fab': str`(${0} selected)`,
+'s011cb4b34942843f': `No Result Found`,
+'sffa721bb6aa3128d': `Search...`,
+'sb4f1dffbb6be6302': `Clear`,
};
\ No newline at end of file
diff --git a/src/generated/locales/tr.ts b/src/generated/locales/tr.ts
index d830696b9..567d8a6b5 100644
--- a/src/generated/locales/tr.ts
+++ b/src/generated/locales/tr.ts
@@ -23,5 +23,9 @@
'sbaace8219b5f4612': `Tümünü Seç`,
'sc2b31c8d71636c74': str`Sayfa ${0}`,
'sf3ff78cc329d3528': `Önceki`,
+'s837243444fe86fab': str`(${0} selected)`,
+'s011cb4b34942843f': `No Result Found`,
+'sffa721bb6aa3128d': `Search...`,
+'sb4f1dffbb6be6302': `Clear`,
};
\ No newline at end of file
diff --git a/translations/ar.xlf b/translations/ar.xlf
index 0bde0cd30..1e50257e4 100644
--- a/translations/ar.xlf
+++ b/translations/ar.xlf
@@ -72,6 +72,22 @@
صفحة
bl-pagination: page number button
+
+ Clear
+ bl-tree-select: clear selection button
+
+
+ No Result Found
+ bl-tree-select: search no result text
+
+
+ Search...
+ bl-tree-select: search placeholder
+
+
+ ( selected)
+ bl-tree-select: selected count
+