The Graphical User Interface is composed of various UI-elements. For every UI-element, there is a BaseUIElement which creates the actual HTMLElement when needed.
There are some basic elements, such as:
- FixedUIElement which shows a fixed, unchangeble element
- Img to show an image
- Combine which wrap everything given (strings and other elements) in a div
- List
There is one special component: the VariableUIElement
The variableUIElement takes a `UIEventSource<string|BaseUIElement>` and will dynamicaly show whatever the UIEventSource contains at the moment.
Note that every component offers support for `onClick( someCallBack)`
### Translations
To add a translation:
1. Open `langs/en.json`
2. Find a correct spot for your translation in the tree
3. run `npm run generate:translations`
4.`import Translations`
5. Translations.t.<your-translation>.Clone() is the UIElement offering your translation
### Input elements`
Input elements are a special kind of BaseElement and which offer a piece of a form to the user, e.g. a TextField, a Radio button, a dropdown, ...
The constructor will ask all the parameters to configure them. The actual value can be obtained via `inputElement.GetValue()`, which is a UIEVentSource that will be triggered every time the user changes the input.
### Advanced elements
There are some components which offer useful functionality:
- The `subtleButton` which is a friendly, big button
- The Toggle: `const t = new Toggle( componentA, componentB, source)` is a UIEventSource which shows `componentA` as long as `source` contains `true` and will show `componentB` otherwise.
### Styling
Styling is done as much as possible with [TailwindCSS](https://tailwindcss.com/). It contains a ton of utility classes, each of them containing a few rules.
For exmaple: ` someBaseUIElement.SetClass("flex flex-col border border-black rounded-full")` will set the component to be a flex object, as column, with a black border and pill-shaped.
If tailwind is not enough, `baseUiElement.SetStyle("background: red; someOtherCssRule: abc;")`
### An example
For example: the user should input wether or not a shop is closed during public holidays. There are three options:
1. closed
2. opened as usual
3. opened with different hours as usual
In the case of different hours, input hours should be too.
3. You'll notice that you'll end up with one certain component (in this example the combine) to wrap it all together. Change the class to extend this type of component and use super to wrap it all up:
```
export default class MyComponent extends Combine {
Theme and layer configuration files go into /assets/layers and assets/themes
### Images
Other files (mostly images that are part of the core of mapcomplete) go into 'assets/svg' and are usable with `Svg.image_file_ui()`. Run `npm run generate:images` if you added a new image
The last part is the business logic of the application, found in 'Logic'. Actors are small objects which react to UIEventSources to update other eventSources.
State.state is a big singleton object containing a lot of the state of the entire application. That one is a bit a mess