custom-file-tree
Version:
Add the custom element to your page context using plain old HTML:
205 lines (169 loc) • 4.02 kB
CSS
.drag-and-drop-hidden {
display: none ;
opacity: 0;
}
file-tree {
--fallback-icon: "🌲";
--open-dir-icon: "📒";
--closed-dir-icon: "📕";
--file-icon: "📄";
--dir-touch-padding: 0;
--open-dir-icon-cursor: pointer;
--closed-dir-icon-cursor: pointer;
--dir-heading-cursor: pointer;
--file-icon-cursor: pointer;
--file-heading-cursor: pointer;
--icon-size: 1.25em;
--line-height: 1.5em;
--indent: 1em;
--entry-padding: 0.25em;
--highlight-background: lightcyan;
--highlight-background-bw: #ddd;
--highlight-border-color: blue;
--drop-target-color: rgb(205, 255, 242);
position: relative;
&:not([show-top-level]) {
padding-top: 0;
padding-left: 0;
dir-entry[path="."] {
& > span.icon,
& > entry-heading {
display: none;
}
& > .buttons {
width: calc(100% + 0.5em);
background: var(--highlight-background-bw);
text-align: center;
border-bottom: 1px solid black;
}
}
}
/* All entries in the file tree have a handy icon */
.icon {
position: relative;
display: inline-block;
width: var(--icon-size);
height: var(--icon-size);
cursor: pointer;
&:before {
position: absolute;
bottom: -0.25em;
left: 0;
content: var(--fallback-icon);
}
}
/* The root dir has an icon, but it's "inactive" */
[path="."] > .icon {
cursor: default ;
}
/*
And the file tree technically has an icon and even a
heading, but they're both "dummy" nodes.
*/
& > .icon {
display: none ;
}
& > entry-heading {
display: none ;
}
/*
The root buttons should always be visible, but entry
buttons should only be revealed when the associated
entry has been selected by the user.
*/
& .buttons {
display: none;
height: var(--line-height);
}
& .selected > .buttons,
& [path="."] > .buttons {
display: inline-block;
}
/* Headings are clickable */
entry-heading {
cursor: pointer;
display: inline-block;
}
[path="."] > entry-heading {
cursor: default;
}
.selected {
& > entry-heading {
background: var(--highlight-background);
border: 1px solid var(--highlight-border-color);
margin-top: -1px;
margin-bottom: -1px;
padding-left: var(--entry-padding);
padding-right: var(--entry-padding);
}
& .buttons {
max-height: 1em;
}
}
/* Drag and drop has its own visual cues */
.dragging {
opacity: 0.2;
}
.drop-target {
background: var(--drop-target-color);
}
/* Directories */
dir-entry {
display: block;
min-height: var(--line-height);
margin-left: var(--indent);
/* Note: the root dir does not get indented */
&[path="."] {
margin-left: 0;
}
& > .icon {
cursor: var(--open-dir-icon-cursor);
&:before {
content: var(--open-dir-icon);
}
}
& > entry-heading {
cursor: var(--dir-heading-cursor);
/*
It's super easy to mistouch dirs, so we give them a little more space
*/
padding-top: var(--dir-touch-padding);
padding-bottom: var(--dir-touch-padding);
}
&.closed {
& > file-entry,
& > dir-entry {
display: none;
}
& > .icon {
cursor: var(--closed-dir-icon-cursor);
&:before {
content: var(--closed-dir-icon);
}
}
}
/* Files */
file-entry {
display: block;
margin-left: var(--indent);
height: var(--line-height);
& > .icon {
cursor: var(--file-icon-cursor);
&:before {
content: var(--file-icon);
}
}
& > entry-heading {
cursor: var(--file-heading-cursor);
}
}
}
}
/*
for touch devices, we want to make sure that our fat fingers can still click drag entries
*/
@media (pointer: coarse) {
file-tree {
--dir-touch-padding: 0.4em;
}
}