پیشنمایش زنده
کد HTML
<div class="tree-container">
<ul>
<li class="tree-item">
<input type="checkbox" id="folder-src" class="tree-toggle" checked="" />
<label for="folder-src" class="tree-label">
<svg
class="icon folder-closed-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"
></path>
</svg>
<svg
class="icon folder-open-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"
></path>
<path d="M2 10h20"></path>
</svg>
src
</label>
<div class="tree-children-wrapper">
<ul class="tree-children">
<li class="tree-item">
<input
type="checkbox"
id="folder-app"
class="tree-toggle"
checked=""
/>
<label for="folder-app" class="tree-label">
<svg
class="icon folder-closed-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"
></path>
</svg>
<svg
class="icon folder-open-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"
></path>
<path d="M2 10h20"></path>
</svg>
app
</label>
<div class="tree-children-wrapper">
<ul class="tree-children">
<li class="tree-item">
<div class="file-item">
<svg
class="icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"
></path>
<polyline points="14 2 14 8 20 8"></polyline>
</svg>
layout.tsx
</div>
</li>
<li class="tree-item">
<div class="file-item">
<svg
class="icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"
></path>
<polyline points="14 2 14 8 20 8"></polyline>
</svg>
page.tsx
</div>
</li>
</ul>
</div>
</li>
<li class="tree-item">
<input
type="checkbox"
id="folder-components"
class="tree-toggle"
checked=""
/>
<label for="folder-components" class="tree-label">
<svg
class="icon folder-closed-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"
></path>
</svg>
<svg
class="icon folder-open-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"
></path>
<path d="M2 10h20"></path>
</svg>
components
</label>
<div class="tree-children-wrapper">
<ul class="tree-children">
<li class="tree-item">
<input
type="checkbox"
id="folder-ui"
class="tree-toggle"
checked=""
/>
<label for="folder-ui" class="tree-label">
<svg
class="icon folder-closed-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"
></path>
</svg>
<svg
class="icon folder-open-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"
></path>
<path d="M2 10h20"></path>
</svg>
ui
</label>
<div class="tree-children-wrapper">
<ul class="tree-children">
<li class="tree-item">
<div class="file-item is-selected">
<svg
class="icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"
></path>
<polyline points="14 2 14 8 20 8"></polyline>
</svg>
button.tsx
</div>
</li>
</ul>
</div>
</li>
<li class="tree-item">
<div class="file-item">
<svg
class="icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"
></path>
<polyline points="14 2 14 8 20 8"></polyline>
</svg>
header.tsx
</div>
</li>
<li class="tree-item">
<div class="file-item">
<svg
class="icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"
></path>
<polyline points="14 2 14 8 20 8"></polyline>
</svg>
footer.tsx
</div>
</li>
</ul>
</div>
</li>
<li class="tree-item">
<input
type="checkbox"
id="folder-lib"
class="tree-toggle"
checked=""
/>
<label for="folder-lib" class="tree-label">
<svg
class="icon folder-closed-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"
></path>
</svg>
<svg
class="icon folder-open-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"
></path>
<path d="M2 10h20"></path>
</svg>
lib
</label>
<div class="tree-children-wrapper">
<ul class="tree-children">
<li class="tree-item">
<div class="file-item">
<svg
class="icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"
></path>
<polyline points="14 2 14 8 20 8"></polyline>
</svg>
utils.ts
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
کد CSS
.tree-container {
width: 320px;
border: 1px solid #e4e4e7;
border-radius: 8px;
padding: 24px;
background: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
ul ul {
margin-left: 11px;
padding-left: 11px;
border-left: 1px solid #e4e4e7;
}
.tree-item {
position: relative;
margin-top: 4px;
}
ul ul .tree-item::before {
content: "";
position: absolute;
left: -11px;
top: 14px;
width: 11px;
height: 1px;
background-color: #e4e4e7;
}
.tree-label,
.file-item {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 8px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
color: #09090b;
transition: background-color 0.2s;
user-select: none;
text-decoration: none;
height: 28px;
}
.tree-label:hover,
.file-item:hover {
background-color: #f4f4f5;
}
.is-selected {
background-color: #f4f4f5;
color: #09090b;
font-weight: 500;
}
.icon {
width: 16px;
height: 16px;
color: #71717a;
flex-shrink: 0;
}
.folder-open-icon {
display: none;
}
.folder-closed-icon {
display: block;
}
.tree-toggle:checked ~ .tree-label .folder-open-icon {
display: block;
color: #09090b;
}
.tree-toggle:checked ~ .tree-label .folder-closed-icon {
display: none;
}
.tree-toggle {
display: none;
}
.tree-children-wrapper {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.3s ease-in-out;
}
.tree-children {
overflow: hidden;
}
/* State: Open */
.tree-toggle:checked ~ .tree-children-wrapper {
grid-template-rows: 1fr;
}