Native button
Example apps / native / v0.1.0
Overlay app
A button and menu with no window around them, styled like the game, so they look like part of its UI.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>REDnode native-style button</title>
<script src="rednode://ui/rednode-ui.js"></script>
<style>
/* No window frame at all: only the button, the menu and notifications are
drawn. Everything else is transparent and clicks through to the game. */
html, body { margin: 0; width: 440px; height: 380px; overflow: hidden; background: transparent; }
.dock { position: absolute; left: 12px; bottom: 12px; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
rn-menu { width: 240px; }
rn-menu[hidden] { display: none; }
/* A small grip so the button can be moved without a title bar. */
.grip { width: 22px; height: 34px; cursor: move;
background: repeating-linear-gradient(0deg, var(--rn-accent) 0 2px, transparent 2px 6px); opacity: .7; }
.bar { display: flex; align-items: center; gap: 6px; }
#rn-notifications { top: 12px; bottom: auto !important; right: 12px; }
</style>
</head>
<body theme="hud">
<div class="dock">
<rn-menu id="menu" title="Stash" hidden>
<rn-menu-item value="sell">Sell junk <span slot="end">12</span></rn-menu-item>
<rn-menu-item value="sort">Sort by value</rn-menu-item>
<rn-menu-item value="disassemble">Disassemble all</rn-menu-item>
<rn-menu-item value="close">Close</rn-menu-item>
</rn-menu>
<div class="bar">
<div class="grip" data-rednode-drag title="Drag to move"></div>
<rn-button id="open">Open stash</rn-button>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
// A native-looking button: a borderless window with only a game-style button
// and its menu. Everything else in the window is transparent.
'use strict';
const menu = document.getElementById('menu');
document.getElementById('open').addEventListener('click', () => {
menu.hidden = !menu.hidden;
if (!menu.hidden) menu.querySelector('rn-menu-item')?.focus();
});
const messages = {
sell: 'Sold 12 junk items for 340 eddies (demo only)',
sort: 'Stash sorted by value (demo only)',
disassemble: 'Nothing to disassemble (demo only)',
};
menu.addEventListener('select', (e) => {
menu.hidden = true;
if (e.detail.value !== 'close') RednodeUI.notify(messages[e.detail.value], { title: 'Stash', theme: 'game' });
});
REDnode runs JavaScript. The rednode package also has TypeScript types, so an editor checks these calls; compile TypeScript to .mjs first.
{
"id": "native",
"name": "Native button",
"version": "0.1.0",
"author": "Edgemodders",
"description": "A borderless, game-style button and menu that look like part of the game UI.",
"entry": "index.html",
"kind": "window",
"width": 440,
"height": 380,
"anchor": "bottom-right",
"x": -40,
"y": -100,
"open": true
}
The manifest names the package and says how REDnode runs it. Its fields are in Overlay apps.
How it works
Without rn-window, only what you draw shows. data-rednode-drag makes any element a handle that moves the overlay window.
This is HTML, not the game's own UI (ink). The design for native ink UI is in the design doc, section 06.
What it uses
theme="hud" rn-menu data-rednode-drag RednodeUI.notify
Try this
- Add a menu item that shows a notification with
type: "success".
Use it
Copy the files into red4ext/plugins/REDnode/apps/native/ in the game folder, or start your own package from them: change id and name in the manifest first. The whole folder is on GitHub.