diff --git a/packages/components/src/components/Tree/Tree.css b/packages/components/src/components/Tree/Tree.css
index cfcd23c87..b324d56a7 100644
--- a/packages/components/src/components/Tree/Tree.css
+++ b/packages/components/src/components/Tree/Tree.css
@@ -49,6 +49,13 @@
}
}
+.kbq-TreeItem:has([data-slot='list-item-addon']) {
+ [data-slot='chevron'],
+ [data-slot='checkbox'] {
+ margin-inline-end: var(--kbq-size-s);
+ }
+}
+
.kbq-TreeLoader {
display: flex;
align-items: center;
diff --git a/packages/components/src/components/Tree/Tree.mdx b/packages/components/src/components/Tree/Tree.mdx
index 36f8b357d..46881cfc0 100644
--- a/packages/components/src/components/Tree/Tree.mdx
+++ b/packages/components/src/components/Tree/Tree.mdx
@@ -37,6 +37,8 @@ Use these components to build hierarchical navigation, selection, and lazy loadi
- `Tree` — Root container for hierarchical items.
- `Tree.Item` — Defines a node in the tree (leaf or branch).
- `Tree.ItemContent` — Customizes row content (text, icons, slots).
+- `Tree.ItemContentText` — Displays text and an optional caption in an item.
+- `Tree.ItemContentAddon` — Displays an icon, badge, or other secondary content in an item.
- `Tree.LoadMoreItem` — Triggers and displays async loading state for additional items.
## Content
@@ -53,12 +55,23 @@ Use `selectionBehavior="toggle"` to render checkbox selection controls.
-## Slots
+## Item content
-Use `Tree.ItemContent` to customize item layout.
-For example, you can add icons, typography, badges, and slot-specific props for chevron and checkbox controls.
+The `Tree.ItemContent` can be composed with helper components:
-
+- `Tree.ItemContentText` for text and captions.
+- `Tree.ItemContentAddon` for icons, badges, or other secondary content.
+
+The `Tree.Item` also have layout props, such as `align`, which sets vertical alignment.
+Use `align="start"` for captions or multi-line content.
+
+
+
+## Item actions
+
+Add an extra action to an item, revealed on hover or focus.
+
+
## Empty state
@@ -92,7 +105,3 @@ Tree supports progressive loading with `Tree.LoadMoreItem`.
Combine it with `useAsyncList` to fetch nested data on demand.
-
-## Other examples
-
-
diff --git a/packages/components/src/components/Tree/Tree.stories.tsx b/packages/components/src/components/Tree/Tree.stories.tsx
index 03aa1109e..e08bc83df 100644
--- a/packages/components/src/components/Tree/Tree.stories.tsx
+++ b/packages/components/src/components/Tree/Tree.stories.tsx
@@ -1,11 +1,16 @@
import { useState } from 'react';
-import { IconEllipsisVertical16, IconFolder16 } from '@koobiq/react-icons';
+import {
+ IconCircle16,
+ IconEllipsisVertical16,
+ IconFolder16,
+} from '@koobiq/react-icons';
import { Collection } from '@koobiq/react-primitives';
import type { Meta, StoryObj } from '@storybook/react';
-import { FlexBox, useAsyncList } from '../../index';
+import { useAsyncList } from '../../index';
import type { Selection } from '../../index';
+import { Badge } from '../Badge';
import { IconButton } from '../IconButton';
import { spacing } from '../layout';
import { Menu } from '../Menu';
@@ -22,10 +27,12 @@ const meta = {
subcomponents: {
'Tree.Item': Tree.Item,
'Tree.ItemContent': Tree.ItemContent,
+ 'Tree.ItemContentText': Tree.ItemContentText,
+ 'Tree.ItemContentAddon': Tree.ItemContentAddon,
'Tree.LoadMoreItem': Tree.LoadMoreItem,
},
argTypes: {},
- tags: ['status:new', 'date:2026-03-02'],
+ tags: ['status:updated', 'date:2026-07-03'],
} satisfies Meta;
export default meta;
@@ -222,7 +229,95 @@ export const Content: Story = {
},
};
-export const Slots: Story = {
+export const ItemContent: Story = {
+ name: 'Item content',
+ parameters: {
+ layout: 'padded',
+ },
+ render: function Render() {
+ const longText =
+ 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. A at cupiditate dolor itaque molestias quasi quisquam quo. Deleniti ducimus fugit nulla repudiandae tenetur. Aliquid autem corporis culpa debitis exercitationem inventore labore nihil officia recusandae veniam. Beatae, doloribus, suscipit. Aut beatae consectetur consequuntur cum hic, obcaecati quia sunt temporibus unde vel!';
+
+ return (
+
+
+
+
+
+
+ app
+
+
+
+
+ index.html
+
+
+
+
+
+
+
+
+
+
+ .gitignore
+
+
+ Badge
+
+
+
+
+
+
+
+
+
+ README.md
+
+
+
+
+
+
+
+
+
+
+ {longText}
+
+
+
+
+
+
+
+
+
+ {longText}
+
+
+ Badge
+
+
+
+
+ );
+ },
+};
+
+export const ItemActions: Story = {
+ name: 'Item actions',
parameters: {
layout: 'padded',
},
@@ -240,22 +335,28 @@ export const Slots: Story = {
{({ isHovered, isFocusVisibleWithin }) => (
<>
- {type === 'directory' && }
- {title}
+ {type === 'directory' && (
+
+
+
+ )}
+ {title}
{(isHovered || isFocusVisibleWithin || isMenuOpen) && (