We want to build something along the lines of an "Orthodox File Manager".
Browsers default to mouse interfaces, while file managers need to work with just keyboard, and have a lot of UI patterns that don't match what typical websites or webapps.
So we' need to implement this functionality yourselves.
Orthodox File Manager UI
Let's do a simple interface with the following features, implementing highly simplified "Orthodox File Manager" interface:
- two panels, switching between them with TAB
- each panel is a list of files, UP and DOWN arrow move between them
- any number of files can be selected with SPACE
- various Fn keys popup various modals to perform common actions (on either selected files, or currently focused file if none are selected on given panel)
- each panel remembers which file was focused, but focused file in inactive file is not indicated
But before we even get there, let do just styling with completely static data, similar to how we created the terminal app!
Data
I took static data from Cat Ipsum.
Header and footer are both placeholders.
Here's index.html
:
<!DOCTYPE html>
<html>
<head>
<link href="app.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="ui">
<header>
File Manager
</header>
<div class="panel panel-left active">
<div class="file selected">Cat.js</div>
<div class="file selected">ipsum.js</div>
<div class="file">dolor.js</div>
<div class="file selected">sit.js</div>
<div class="file selected">amet.js</div>
<div class="file focused">walk.js</div>
<div class="file">on.js</div>
<div class="file">keyboard.js</div>
<div class="file">hide.js</div>
<div class="file">when.js</div>
<div class="file">guests.js</div>
<div class="file">come.js</div>
<div class="file">over.js</div>
<div class="file">play.js</div>
<div class="file">with.js</div>
<div class="file">twist.js</div>
<div class="file">ties.js</div>
</div>
<div class="panel panel-right">
<div class="file">Ask.png</div>
<div class="file">to.png</div>
<div class="file focused">be.png</div>
<div class="file">pet.png</div>
<div class="file selected">then.png</div>
<div class="file selected">attack.png</div>
<div class="file selected">owners.png</div>
<div class="file selected">hand.png</div>
<div class="file">need.png</div>
<div class="file">to.png</div>
<div class="file">chase.png</div>
<div class="file">tail.png</div>
</div>
<footer>
<button>F1 Help</button>
<button>F2 Menu</button>
<button>F3 View</button>
<button>F4 Edit</button>
<button>F5 Copy</button>
<button>F6 Move</button>
<button>F7 Mkdir</button>
<button>F8 Delete</button>
<button>F10 Quit</button>
</footer>
</div>
</body>
</html>
It should be fairly self explanatory:
- we have 4 areas:
header
,panel-left
,panel-right
,footer
- each panel contains a lot of
file
items - some
file
items canselected
orfocused
or both - only one of the panels will be
active
at a time
Setting up basic styling
Terminals are traditionally white-on-black. File managers are traditionally white-on-blue. I did not make the rules.
body {
background-color: #226;
color: #fff;
font-family: monospace;
margin: 0;
font-size: 16px;
}
Setting up grid
It's very easy to do this with display: grid
:
.ui {
width: 100vw;
height: 100vh;
display: grid;
grid-template-areas:
"header header"
"panel-left panel-right"
"footer footer";
grid-template-columns: 1fr 1fr;
grid-template-rows: auto 1fr auto;
}
.ui header {
grid-area: header;
}
.ui .panel-left {
grid-area: panel-left;
}
.ui .panel-right {
grid-area: panel-right;
}
.ui footer {
grid-area: footer;
}
Setting up item styling
These are some reasonable colors to indicate selected
and focused
states. Additionally selected files are bolded, something terminal-based file managers don't normally do.
.ui .panel {
background: #338;
margin: 4px;
}
.panel .file.selected {
color: #ff2;
font-weight: bold;
}
.panel.active .file.focused {
background-color: #66b;
}
Styling header and footer
So far in this series I haven't used any CSS resets, so button
needs a bunch of inherit
rules. Most of the time I just nuke the whole CSS before starting, so then we wouldn't need any such rules:
header {
font-size: 24px;
margin: 4px;
}
.ui footer {
text-align: center;
}
button {
font-family: inherit;
font-size: inherit;
background-color: #66b;
color: inherit;
}
How much should we follow tradition?
Orthodox File Managers come from terminal era. I think the basic concept of keyboard-controlled two-panel UI is still great, but some of their design decisions are based on limitations of terminal UIs.
The most obvious question to ask is if we want to use monospace font or not. Pretty much no non-terminal programs do that, and nobody minds. Even text editors like VSCode use regular sans font for their file management.
There's a long list of such questions we could have.
We might explore some of them in the future.
Results
Here's the results:
As usual, all the code for the episode is here.
Top comments (0)