README
Layout management sandbox POC
As always we are taking inspirating from VS-Code since there design patterns and implemenations are awesome.
The Design
At a high level the layout of the application can be described using the following diagram.
- Titlebar
- You can remove the native titlebar and use a JS-based titlebar here, otherwise it can be hidden.
- Activitybar
- Contains a vertical list of icons that when clicked-on perform actions.
- Sidebar
- Slide-out sidebar with variable content dependant on context.
- Panel
- The main 'chunk' of the application is placed here.
- Statusbar
- Similar to a footer component, this conatains a horiziontal list of components.
The details
The activity bar (1) and status bar (2) both hold a list of components (grouped left/right top/bottom). This list of items can be added to, and removed from at any point using a globally avaliable API (alternatively we we use Actions and Commands as described later to achieve the same effect).
The sidebar (4) will be composed of an optional titlebar which includes a text title and optional action components aligned right. The content of the sidebar will be added below this titlebar.
The divider between the sidebar and panel (3) is adjustable using a sliding component. The slider obeys the sidebars minimum and maximum sizes. If the sidebar goes below the minimum side it will disappear, the drag handle will be avaliable at right border of the activity bar to re-open when needed.
Context, Commands, Keybindings, Menus and Actions
Commands
A command is a uniquely identifiable function that is registered to the CommandRegistry
. At any point a command can be called using its id
as a lookup key.
Keybindings
The KeybindingRegistry
contains a set of expressions paired with commandId
and description
. Keybindings have a when
clause which when not met will short-circuit the event. The respective command will be executed when the keybinding is successfully called.
Menus
Similarly to Keybindings Menus are a Map of menuId
to menu list pairing, where a menu list is an object containing a description
, a commandId
and a when
clause which is functionally the same to the above case. When conditions allow the application to add and remove menu items to the same visible menu when additional conditions are met (e.g. isDebug
, isProduction
, isUserDeveloper
etc)
Context
Context is bound to the DOM-tree. As we move down the DOM-tree we can add key-value pairs to our context, these key-value pairs are only visible to components lower in the DOM-tree than where they were set. These key-value pairs are avaliable to use in the when
claues. (e.g. isSidebar
, isStatusbar
). There is also a root context for global information to be stored.
Actions
Actions are a more complex case.
The implementation
Since we use React the classic dependency injection issues will be solved using React.useContext
. I intend on refraining from using a DI service unless it's absolutely neccassary.
Icons
We use SVG for our icons for obvious reasons. There are two approaches to rendering SVG approaches we should use:
Masking
We use a masking approach to create a mask of the image, on which we can set a background-color
CSS classes / custom fonts
We can also use a custom font file which will allow rendering of icons simply by adding classnames to HTML elements.
String pattern matching
To avoid the need to write new components simply to render a different type of item we can use a string matching pattern that replaces matches with images. For example:
API
Injector - You can registry services you want injected throughout the entire application here. This should act like a classical dependency injection setup. Each service can then be accessed through its respective React.useContext
.
Layout - This encomposes the core 'parts' of the application; The Activitybar, Sidebar, Title, Panel and Statusbar.
useLayoutAPI
useStatusbarAPI
Controls the statusbar components, you can add, remove and update items.
useActivitybarAPI
Controls the activitybar components, you can add, remove and update items.