velxio/frontend/src/components/editor/FileExplorer.css

426 lines
8.4 KiB
CSS

.file-explorer {
width: 100%;
background: #252526;
border-right: 1px solid #333;
display: flex;
flex-direction: column;
overflow: hidden;
font-size: 12px;
font-family: 'Segoe UI', sans-serif;
}
/* Two rows, not one: the title on top, the three actions under it. Side by
side they set the pane's minimum width between them (a truncated "WORK..."
next to buttons that must stay reachable); stacked, the panel is free to be
narrow and the code editor takes the px that frees up. Vertical space is
what this column has to spare. */
.file-explorer-header {
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: center;
gap: 3px;
padding: 6px 6px 6px 8px;
color: #9d9d9d;
font-size: 10px;
font-weight: 600;
letter-spacing: 0.3px;
border-bottom: 1px solid #333;
flex-shrink: 0;
}
.file-explorer-title {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.file-explorer-header-actions {
display: flex;
align-items: center;
gap: 2px;
margin-left: -2px; /* optical: line the first glyph up with the title */
}
.file-explorer-new-btn {
background: none;
border: none;
color: #9d9d9d;
cursor: pointer;
padding: 2px;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
}
.file-explorer-new-btn svg,
.file-explorer-save-btn svg {
width: 16px;
height: 16px;
}
.file-explorer-new-btn:hover {
background: rgba(255, 255, 255, 0.08);
color: #fff;
}
.file-explorer-save-btn {
background: none;
border: none;
color: #9d9d9d;
cursor: pointer;
padding: 2px;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
}
.file-explorer-save-btn:hover {
background: rgba(255, 255, 255, 0.08);
color: var(--color-action-primary);
}
/* The Save button doubles as the auto-save indicator once a project is
loaded (replaces the "Unsaved changes" text pill in the header). */
.file-explorer-save-btn.is-saved {
color: #3fb950;
}
.file-explorer-save-btn.is-dirty {
color: #f0883e;
}
.file-explorer-save-btn.is-saving {
color: #3fb950;
animation: velxio-pulse 1s ease-in-out infinite;
}
.file-explorer-save-btn.is-error {
color: #f85149;
}
.file-explorer-save-btn.is-saved:hover,
.file-explorer-save-btn.is-dirty:hover,
.file-explorer-save-btn.is-error:hover {
filter: brightness(1.25);
}
.file-explorer-list {
flex: 1;
overflow-y: auto;
padding: 2px 0;
scrollbar-width: thin;
scrollbar-color: #3c3c3c transparent;
}
/* Rows are deliberately compact (VS Code density): the explorer is a narrow
pane and every px of padding, indent or icon here is a px the code editor
does not get. */
.file-explorer-item {
display: flex;
align-items: center;
gap: 4px;
padding: 3px 6px;
cursor: pointer;
color: #ccc;
border-radius: 3px;
margin: 0 2px;
font-size: 11px;
line-height: 16px;
white-space: nowrap;
overflow: hidden;
user-select: none;
}
.file-explorer-item:hover {
background: rgba(255, 255, 255, 0.06);
}
.file-explorer-item-active {
background: rgba(0, 113, 227, 0.12);
color: #e2e2e2;
}
.file-explorer-item-new {
background: rgba(255, 255, 255, 0.04);
}
.file-explorer-icon {
display: inline-flex;
align-items: center;
flex-shrink: 0;
opacity: 0.8;
}
.file-explorer-icon svg {
width: 16px;
height: 16px;
}
.file-explorer-name {
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
}
.file-explorer-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: #e8a87c;
flex-shrink: 0;
}
.file-explorer-rename-input {
flex: 1;
background: #3c3c3c;
border: 1px solid var(--color-action-primary);
color: #fff;
font-size: 11px;
padding: 1px 4px;
border-radius: 2px;
outline: none;
min-width: 0;
font-family: inherit;
}
/* Context menu */
.file-explorer-context-menu {
position: fixed;
background: #2d2d2d;
border: 1px solid #3c3c3c;
border-radius: 4px;
z-index: 2000;
display: flex;
flex-direction: column;
min-width: 120px;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
overflow: hidden;
}
.file-explorer-context-menu button {
background: none;
border: none;
color: #ccc;
padding: 7px 14px;
text-align: left;
cursor: pointer;
font-size: 12px;
font-family: inherit;
}
.file-explorer-context-menu button:hover:not(:disabled) {
background: rgba(255, 255, 255, 0.08);
color: #fff;
}
.file-explorer-context-menu button:disabled {
opacity: 0.35;
cursor: not-allowed;
}
.ctx-delete:hover:not(:disabled) {
color: #ef5350 !important;
}
/* ─── Board-grouped FileExplorer ─────────────────── */
.fe-board-section {
margin-bottom: 2px;
}
/* A board section header is two rows: its actions, then its name. The name
row then spans the full pane width, so "M5 Cardputer ADV" reads as a name
instead of an ellipsis squeezed between three buttons and a status dot. */
.fe-board-header {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 1px;
padding: 2px 4px 3px 2px;
cursor: pointer;
color: #aaa;
border-radius: 3px;
margin: 0 2px;
user-select: none;
position: relative;
}
.fe-board-name-row {
display: flex;
align-items: center;
gap: 4px;
min-width: 0;
}
/* The actions keep their row reserved whether or not they are showing: a row
that appears on hover would shove every file below it down by its height
under the pointer. */
.fe-board-actions-row {
display: flex;
align-items: center;
gap: 1px;
min-height: 16px;
padding-left: 2px;
}
/* Pushes the buttons to the right end and leaves the status dot at the left. */
.fe-board-actions-spacer {
flex: 1 1 auto;
}
.fe-board-header:hover {
background: rgba(255, 255, 255, 0.06);
color: #ddd;
}
.fe-board-header-active {
background: rgba(255, 255, 255, 0.05);
color: #e2e2e2;
}
.fe-collapse-btn {
background: none;
border: none;
color: inherit;
cursor: pointer;
padding: 0;
display: flex;
align-items: center;
flex-shrink: 0;
opacity: 0.6;
}
.fe-collapse-btn:hover {
opacity: 1;
}
.fe-board-icon {
font-size: 10px;
flex-shrink: 0;
line-height: 1;
}
.fe-board-label {
font-size: 11px;
font-weight: 600;
letter-spacing: 0.3px;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Inline rename input for a board/chip section header — flex into the label
slot and match the header's compact type. */
.fe-section-rename-input {
flex: 1;
min-width: 0;
font-size: 11px;
font-weight: 600;
}
.fe-status-dot {
width: 7px;
height: 7px;
border-radius: 50%;
flex-shrink: 0;
}
.fe-board-new-btn {
background: none;
border: none;
color: #9d9d9d;
cursor: pointer;
padding: 0;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
flex-shrink: 0;
opacity: 0;
transition: opacity 0.1s;
}
.fe-board-header:hover .fe-board-new-btn,
.fe-board-header-active .fe-board-new-btn {
opacity: 1;
}
.fe-board-new-btn svg {
width: 14px;
height: 14px;
}
.fe-board-new-btn:hover {
background: rgba(255, 255, 255, 0.1);
color: #fff;
}
.fe-board-files {
/* files are indented to show hierarchy */
}
.fe-file-item {
/* --fe-depth: nesting level inside the board's folder tree (0 = root).
Root files sit just inside the board header's chevron, not under its
icon — the deeper indent read as wasted margin in a 150px pane. */
padding-left: calc(16px + var(--fe-depth, 0) * 12px) !important;
}
/* ── Folder rows ────────────────────────────────────────────────────────── */
.fe-folder-item {
user-select: none;
}
.fe-folder-chevron {
display: inline-flex;
align-items: center;
margin-right: 2px;
color: #9d9d9d;
}
.fe-folder-icon {
color: #d8a12a;
}
.fe-folder-actions {
display: none;
margin-left: auto;
align-items: center;
gap: 2px;
}
.fe-folder-item:hover .fe-folder-actions {
display: inline-flex;
}
.fe-folder-actions button {
display: inline-flex;
align-items: center;
background: none;
border: none;
padding: 1px;
cursor: pointer;
color: #9d9d9d;
}
.fe-folder-actions button:hover {
color: #fff;
}
.fe-folder-actions button svg {
width: 14px;
height: 14px;
}
.fe-folder-actions .fe-folder-delete:hover {
color: #f87171;
}