# tgui ## Introduction tgui is a robust user interface framework of /tg/station. tgui is very different from most UIs you will encounter in BYOND programming. It is heavily reliant on Javascript and web technologies as opposed to DM. If you are familiar with NanoUI (a library which can be found on almost every other SS13 codebase), tgui should be fairly easy to pick up. ## Learn tgui People come to tgui from different backgrounds and with different learning styles. Whether you prefer a more theoretical or a practical approach, we hope you’ll find this section helpful. ### Practical tutorial If you are completely new to frontend and prefer to **learn by doing**, start with our [practical tutorial](docs/tutorial-and-examples.md). ### Guides This project uses **Inferno** - a very fast UI rendering engine with a similar API to React. Take your time to read these guides: - [React guide](https://reactjs.org/docs/hello-world.html) - [Inferno documentation](https://infernojs.org/docs/guides/components) - highlights differences with React. If you were already familiar with an older, Ractive-based tgui, and want to translate concepts between old and new tgui, read this [interface conversion guide](docs/converting-old-tgui-interfaces.md). ## Pre-requisites You will need these programs to start developing in tgui: - [Node v12.13+](https://nodejs.org/en/download/) - [Yarn v1.19+](https://yarnpkg.com/en/docs/install) - [MSys2](https://www.msys2.org/) (optional) > MSys2 closely replicates a unix-like environment which is necessary for > the `bin/tgui` script to run. It comes with a robust "mintty" terminal > emulator which is better than any standard Windows shell, it supports > "git" out of the box (almost like Git for Windows, but better), has > a "pacman" package manager, and you can install a text editor like "vim" > for a full boomer experience. ## Usage **For MSys2, Git Bash, WSL, Linux or macOS users:** First and foremost, change your directory to `tgui-next`. Run `bin/tgui --install-git-hooks` (optional) to install merge drivers which will assist you in conflict resolution when rebasing your branches. Run one of the following: - `bin/tgui` - build the project in production mode. - `bin/tgui --dev` - launch a development server. - tgui development server provides you with incremental compilation, hot module replacement and logging facilities in all running instances of tgui. In short, this means that you will instantly see changes in the game as you code it. Very useful, highly recommended. In order to use, you should start the game server first, connect to it so dreamseeker is open, then start the dev server. You'll know if it's hooked correctly if data gets dumped to the log when tgui windows are opened. - `bin/tgui --dev --reload` - reload byond cache once. - `bin/tgui --dev --debug` - run server with debug logging enabled. - `bin/tgui --dev --no-hot` - disable hot module replacement (helps when doing development on IE8). - `bin/tgui --lint` - show problems with the code. - `bin/tgui --lint --fix` - auto-fix problems with the code. - `bin/tgui --analyze` - run a bundle analyzer. - `bin/tgui --clean` - clean up project repo. - `bin/tgui [webpack options]` - build the project with custom webpack options. **For everyone else:** If you haven't opened the console already, you can do that by holding Shift and right clicking on the `tgui-next` folder, then pressing either `Open command window here` or `Open PowerShell window here`. Run `yarn install` to install npm dependencies, then one of the following: - `yarn run build` - build the project in production mode. - `yarn run watch` - launch a development server. - `yarn run lint` - show problems with the code. - `yarn run lint --fix` - auto-fix problems with the code. - `yarn run analyze` - run a bundle analyzer. We also got some batch files in store, for those who don't like fiddling with the console: - `bin/tgui-build.bat` - build the project in production mode. - `bin/tgui-dev-server.bat` - launch a development server. > Remember to always run a full build before submitting a PR. It creates > a compressed javascript bundle which is then referenced from DM code. > We prefer to keep it version controlled, so that people could build the > game just by using Dream Maker. ## Project structure - `/packages` - Each folder here represents a self-contained Node module. - `/packages/common` - Helper functions - `/packages/tgui/index.js` - Application entry point. - `/packages/tgui/components` - Basic UI building blocks. - `/packages/tgui/interfaces` - Actual in-game interfaces. Interface takes data via the `state` prop and outputs an html-like stucture, which you can build using existing UI components. - `/packages/tgui/routes.js` - This is where you want to register new interfaces, otherwise they simply won't load. - `/packages/tgui/layout.js` - A root-level component, holding the window elements, like the titlebar, buttons, resize handlers. Calls `routes.js` to decide which component to render. - `/packages/tgui/styles/main.scss` - CSS entry point. - `/packages/tgui/styles/atomic.scss` - Atomic CSS classes. These are very simple, tiny, reusable CSS classes which you can use and combine to change appearance of your elements. Keep them small. - `/packages/tgui/styles/components.scss` - CSS classes which are used in UI components, and most of the stylesheets referenced here are located in `/packages/tgui/components`. These stylesheets closely follow the [BEM](https://en.bem.info/methodology/) methodology. - `/packages/tgui/styles/functions.scss` - Useful SASS functions. Stuff like `lighten`, `darken`, `luminance` are defined here. ## Component reference > Notice: This documentation might be out of date, so always check the source > code to see the most up-to-date information. These are the components which you can use for interface construction. If you have trouble finding the exact prop you need on a component, please note, that most of these components inherit from other basic components, such as `Box`. This component in particular provides a lot of styling options for all components, e.g. `color` and `opacity`, thus it is used a lot in this framework. There are a few important semantics you need to know about: - `content` prop is a synonym to a `children` prop. - `content` is better used when your element is a self-closing tag (like ``), and when content is long and complex. This is a native React prop (unlike `content`), and contains all elements you defined between the opening and the closing tag of an element. - You should never use both on a same element. - You should never use `children` explicitly as a prop on an element. - Inferno supports both camelcase (`onClick`) and lowercase (`onclick`) event names. - Camel case names are what's called "synthetic" events, and are the *preferred way* of handling events in React, for efficiency and performance reasons. Please read [Inferno Event Handling](https://infernojs.org/docs/guides/event-handling) to understand what this is about. - Lower case names are native browser events and should be used sparingly, for example when you need an explicit IE8 support. **DO NOT** use lowercase event handlers unless you really know what you are doing. - [Button](#button) component straight up does not support lowercase event handlers. Use the camel case `onClick` instead. ### `AnimatedNumber` This component provides animations for numeric values. Props: - `value: number` - Value to animate. - `initial: number` - Initial value to use in animation when element first appears. If you set initial to `0` for example, number will always animate starting from `0`, and if omitted, it will not play an initial animation. - `format: value => value` - Output formatter. - Example: `value => Math.round(value)`. - `children: (formattedValue, rawValue) => any` - Pull the animated number to animate more complex things deeper in the DOM tree. - Example: `(_, value) => ` ### `BlockQuote` Just a block quote, just like this example in markdown: > Here's an example of a block quote. Props: - See inherited props: [Box](#box) ### `Box` The Box component serves as a wrapper component for most of the CSS utility needs. It creates a new DOM element, a `
` by default that can be changed with the `as` property. Let's say you want to use a `` instead: ```jsx