A lightweight, customizable menu library for creating interactive user interfaces in userscripts.
Add to your userscript header:
// @require https://raw.githubusercontent.com/FrozenProductions/Frost-UI/main/scripts/Library.jsconst menu = window.frostManager.addMenu(
"uniqueId", // Unique identifier for the menu
"Menu Title", // Display title
{ x: 100, y: 100 }, // Initial position (optional)
"ShiftRight" // Toggle key (optional)
);Menus support snap-to-grid functionality for easier alignment and positioning. When enabled, the menu will snap to grid points while dragging and optionally show a visual grid overlay.
const menu = window.frostManager.addMenu(
"uniqueId",
"Menu Title",
{ x: 100, y: 100 },
"ShiftRight",
{
enabled: true, // Enable snap-to-grid
gridSize: 20, // Grid cell size in pixels
showGrid: true // Show grid overlay while dragging
}
);| Property | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
false |
Enable snap-to-grid functionality |
gridSize |
number |
20 |
Size of grid cells in pixels |
showGrid |
boolean |
true |
Show grid overlay while dragging |
// Get current grid configuration
const config = menu.getGridConfig();
console.log(config); // { enabled: true, gridSize: 20, showGrid: true }
// Update grid configuration
menu.setGridConfig({ gridSize: 40 });
menu.setGridConfig({ enabled: false, showGrid: false });
// Check if grid is enabled
const isEnabled = menu.isGridEnabled();
// Enable/disable grid snapping
menu.setGridEnabled(true);
menu.setGridEnabled(false);Categories help organize menu items:
menu.addCategory("Combat") // Creates a collapsible section
.addCategory("Movement") // Chain multiple categories
.addCategory("Render"); // Each category can contain multiple itemsCreates a toggle with optional keybind:
menu.addToggle(
"Combat", // Category name
"KillAura", // Toggle name
(enabled) => {
console.log(`KillAura ${enabled ? "enabled" : "disabled"}`);
},
"KeyK" // Optional keybind
);Creates a numeric slider:
menu.addSlider(
"Combat", // Category name
"Range", // Slider name
3, // Minimum value
6, // Maximum value
4, // Default value
(value) => {
console.log(`Range set to ${value}`);
},
0.5 // Optional step value
);Creates mutually exclusive options:
menu.addRadioGroup(
"Combat", // Category name
"Target Mode", // Group name
[
// Available options
"Single",
"Multiple",
"Switch",
],
"Single", // Default selected value
(selected) => {
console.log(`Mode changed to ${selected}`);
}
);The Select component creates a dropdown menu with single-item selection:
// Basic usage with string array
menu.addSelect(
"Settings", // Category name
"Language", // Select name
["English", "Spanish", "French"], // Options
"English", // Default value
(selected) => {
console.log(`Language changed to: ${selected}`);
}
);
// Using key-value pairs
menu.addSelect(
"Settings",
"Theme",
{
dark: "Dark Mode",
light: "Light Mode",
system: "System Default",
},
"system",
(selected) => {
applyTheme(selected);
}
);- Smooth open/close animations
- Keyboard navigation support
- Search by typing
- Custom styling per theme
- Automatic positioning
- Scrolling for many options
| Method | Description |
|---|---|
getValue() |
Get the currently selected value |
setValue(value: string) |
Programmatically set the selected value |
Creates a color input with preview and hex/rgba support:
menu.addColorInput(
"Render", // Category name
"ESP Color", // Input name
"#7289DA", // Default color (hex format)
(color) => {
console.log(`Color changed to ${color}`);
}
);- Color picker with hue/saturation selection
- Hex and RGBA input support
- Live color preview
- Copy/paste support
- Theme-aware styling
| Method | Description |
|---|---|
getValue() |
Get the current color value |
setValue(color: string) |
Set the color programmatically |
// With RGBA values
menu.addColorInput(
"Visual",
"Overlay Color",
"rgba(114, 137, 218, 0.5)", // Semi-transparent color
(color) => updateOverlay(color)
);
// Get/Set programmatically
const colorInput = menu.addColorInput("Visual", "Theme Color", "#ff0000");
const currentColor = colorInput.getValue();
colorInput.setValue("#00ff00");Creates a dropdown with multiple selectable options:
menu.addMultiSelect(
"Combat", // Category name
"Target Types", // Select name
[
// Available options
"Players",
"Animals",
"Monsters",
],
["Players"], // Default selected values
(selected) => {
console.log("Selected targets:", selected);
}
);- Multiple item selection
- Search/filter functionality
- Checkbox indicators
- Select all/none options
- Keyboard navigation
- Custom styling per theme
| Method | Description |
|---|---|
getValues() |
Get array of selected values |
setValues(values: string[]) |
Set selected values programmatically |
// With key-value pairs
menu.addMultiSelect(
"Settings",
"Features",
{
esp: "ESP Overlay",
tracers: "Tracers",
boxes: "Bounding Boxes",
health: "Health Bars",
},
["esp", "health"],
(selected) => updateFeatures(selected)
);
// Programmatic control
const multiSelect = menu.addMultiSelect("Combat", "Targets", options, []);
multiSelect.setValues(["Players", "Monsters"]);
const currentSelection = multiSelect.getValues();Creates a paginated interface for switching between different views:
menu.addPageSelector(
"Settings", // Category name
"Mode", // Selector name
[
// Page names
"Normal",
"Advanced",
"Custom",
],
0, // Default page index
(page, index) => {
console.log(`Switched to ${page} mode (index: ${index})`);
}
);- Smooth page transitions
- Keyboard navigation support
- Visual page indicators
- Custom styling per theme
- Automatic page management
| Method | Description |
|---|---|
getValue() |
Get current page index |
setValue(value: number) |
Switch to specific page by index |
// Create page selector with custom configuration
const pageSelector = menu.addPageSelector(
"Settings",
"Configuration",
["Basic", "Advanced", "Expert", "Debug"],
0,
(page, index) => {
console.log(`Switched to ${page} mode (index: ${index})`);
updateConfigurationView(index);
}
);
// Programmatic control
pageSelector.setValue(2); // Switch to "Expert" page
const currentPageIndex = pageSelector.getValue();Creates clickable buttons with different styles and variants:
menu.addButton(
"Settings", // Category name
"Save Config", // Button text
() => {
saveConfig();
},
"primary" // Button variant ('default', 'primary', 'destructive')
);- Multiple button variants
- Ripple effect on click
- Loading state support
- Custom styling per theme
- Keyboard accessibility
| Method | Description |
|---|---|
setEnabled(enabled: boolean) |
Enable or disable button |
isEnabled() |
Check if button is enabled |
// Default button
menu.addButton("Settings", "Reset", resetSettings);
// Primary button
menu.addButton("Settings", "Save", saveSettings, "primary");
// Destructive button
menu.addButton("Settings", "Delete", deleteConfig, "destructive");
// With loading state
const button = menu.addButton("Settings", "Export", async () => {
button.setLoading(true);
await exportData();
button.setLoading(false);
});Creates a draggable and reorderable list of items with smooth animations:
menu.addOrderList(
"Category", // Category name
"Priority List", // List name
[
// Initial items
"Item 1",
"Item 2",
"Item 3",
],
(items) => {
console.log("New order:", items);
}
);- Drag and drop reordering
- Smooth animations
- Up/down arrow buttons
- Visual feedback during drag
- Touch-friendly interface
- Keyboard accessibility
| Method | Description |
|---|---|
getValue() |
Get current items array |
setValue(items: string[]) |
Update list items |
// With configuration object
const config = {
priority: ["High", "Medium", "Low"],
};
const orderList = menu.addOrderList("Priority", "Task Priority", config.priority, (items) => {
config.priority = items;
saveConfig();
});
// Programmatic control
const currentOrder = orderList.getValue();
orderList.setValue(["Critical", "High", "Medium", "Low"]);Creates a dual-handle slider for selecting a range of values:
menu.addDualSlider(
"Combat", // Category name
"Distance Range", // Slider name
3, // Minimum value
10, // Maximum value
4, // Default start value
7, // Default end value
(values) => {
console.log(`Range set to ${values.start} - ${values.end}`);
},
0.5 // Optional step value
);- Two draggable handles
- Range selection
- Smooth animations
- Step value support
- Visual range indicator
- Touch-friendly interface
| Method | Description |
|---|---|
getValue() |
Get current range values |
setValue({ start, end }) |
Set range values |
// Create dual slider with configuration
const dualSlider = menu.addDualSlider(
"Settings",
"Price Range",
0,
1000,
200,
800,
(values) => {
updatePriceFilter(values.start, values.end);
},
50
);
// Programmatic control
dualSlider.setValue({ start: 300, end: 700 });
const currentRange = dualSlider.getValue();Creates a grid of selectable items with optional icons and labels:
menu.addGridSelector(
"Combat", // Category name
"Targets", // Selector name
[
// Grid items
{ id: "player", icon: "👤", label: "Players" },
{ id: "monster", icon: "👾", label: "Monsters" },
{ id: "animal", icon: "🦊", label: "Animals" },
{ id: "vehicle", icon: "🚗", label: "Vehicles" },
{ id: "item", icon: "📦", label: "Items" },
{ id: "block", icon: "⬛", label: "Blocks" },
],
["player", "monster"], // Default selected items
(selected) => {
console.log("Selected targets:", selected);
},
3 // Number of columns (optional)
);- Grid layout with customizable columns
- Icon and label support
- Multiple item selection
- Smooth hover animations
- Keyboard navigation
- Touch-friendly interface
| Method | Description |
|---|---|
getValue() |
Get selected item IDs |
setValue(ids: string[]) |
Set selected items |
// Create grid selector with custom configuration
const gridSelector = menu.addGridSelector(
"Settings",
"Quick Actions",
[
{ id: "save", icon: "💾", label: "Save" },
{ id: "load", icon: "📂", label: "Load" },
{ id: "reset", icon: "🔄", label: "Reset" },
{ id: "export", icon: "📤", label: "Export" },
],
["save"],
(selected) => updateQuickActions(selected),
2
);
// Programmatic control
gridSelector.setValue(["save", "load"]);
const currentSelection = gridSelector.getValue();Creates real-time data visualization with smooth animations and multiple series support:
menu.addChart(
"Performance", // Category name
"FPS Monitor", // Chart name
{
width: 260, // Optional, default: 260
height: 150, // Optional, default: 150
maxDataPoints: 100, // Optional, default: 100
series: [
{
label: "FPS",
color: "#2ecc71",
data: [], // Initial data points
},
{
label: "Frame Time",
color: "#e74c3c",
data: [], // Initial data points
},
],
minY: 0, // Optional, minimum Y-axis value
maxY: 144, // Optional, maximum Y-axis value
}
);- Real-time data visualization
- Multiple data series support
- Interactive tooltips
- Smooth animations
- Auto-scaling Y-axis
- Grid lines
- Hover indicators
| Method | Description |
|---|---|
addDataPoint(seriesIndex: number, value: number) |
Add new data point |
clearData() |
Clear all data |
getValue() |
Get current data |
// Create performance monitor
const chart = menu.addChart("Metrics", "System Performance", {
series: [
{
label: "CPU Usage",
color: "#3498db",
},
{
label: "Memory Usage",
color: "#e67e22",
},
],
minY: 0,
maxY: 100,
});
// Update chart every second
setInterval(() => {
chart.addDataPoint(0, Math.random() * 100); // CPU usage
chart.addDataPoint(1, Math.random() * 100); // Memory usage
}, 1000);The Search component provides a macOS Spotlight-like search interface for finding items across one or multiple menus:
// Basic usage with single menu
const menu = new FrostUI("myMenu", "My Menu");
const search = new window.frostSearch(menu);
// With multiple menus
const search = new window.frostSearch(
{
"Main Menu": mainMenu,
Settings: settingsMenu,
},
"k"
); // Use Cmd/Ctrl+K to open search- Real-time search through categories and items
- Shows parent category name for each item
- Displays component type badge (Toggle, Slider, Grid Selector, etc.)
- Keyboard navigation (up/down/enter)
- Visual highlighting of matches
- Smooth scrolling to selected items
- Theme synchronization with menus
- Multiple menu support
- Customizable keyboard shortcut
Search results show enhanced information:
- Categories:
Category Name - Menu Name - Items:
Item Name (Parent Category) [Component Type]
For example:
Movement Abilities (Movement) [Grid Selector]Enabled (AutoClicker) [Toggle]Reach (Combat) [Slider]
| Method | Description |
|---|---|
setKeybind(key: string) |
Change keyboard shortcut key |
getKeybind() |
Get current shortcut key |
setTheme(theme: string) |
Set search menu theme |
getTheme() |
Get current theme |
show() |
Show search menu |
hide() |
Hide search menu |
toggle() |
Toggle visibility |
| Shortcut | Action |
|---|---|
Cmd/Ctrl + K |
Open search (default) |
Escape |
Close search |
Arrow Up |
Previous result |
Arrow Down |
Next result |
Enter |
Select result |
const mainMenu = new FrostUI("main", "Main Menu");
const settingsMenu = new FrostUI("settings", "Settings");
// Add items to menus
mainMenu.addCategory("General").addToggle("General", "Dark Mode").addSlider("General", "Volume", 0, 100, 50);
settingsMenu.addCategory("Preferences").addColorInput("Preferences", "Theme Color", "#ffffff");
// Create search with custom keybind
const search = new window.frostSearch(
{
"Main Menu": mainMenu,
Settings: settingsMenu,
},
"p"
); // Use Cmd/Ctrl+P to open
// Match search theme with menu theme
search.setTheme(mainMenu.getTheme());The Modal component provides centered dialog overlays for user confirmations, alerts, and custom interactions:
const manager = window.frostManager;
// Basic modal with buttons
const result = await manager.showModal({
title: 'Confirm Action',
message: 'Are you sure you want to proceed?',
buttons: [
{ text: 'Cancel', variant: manager.buttonVariant.DEFAULT, result: 'cancel' },
{ text: 'Confirm', variant: manager.buttonVariant.PRIMARY, result: 'confirm' }
]
});
console.log(result); // 'cancel', 'confirm', or null (if dismissed)
// Info-only modal (no buttons)
await manager.showModal({
title: 'Notice',
message: 'Click outside to close',
closeOn: [manager.modal.closeOn.BACKDROP]
});Frost-UI provides type constants for better autocomplete and type safety:
// Theme constants
manager.themes.DARK // 'dark'
manager.themes.MIDNIGHT // 'midnight'
manager.themes.NORD // 'nord'
manager.themes.DEEP // 'deep'
manager.themes.OBSIDIAN // 'obsidian'
manager.themes.DUSK // 'dusk'
manager.themes.CATPPUCCIN_MACCHIATO // 'catppuccin-macchiato'
manager.themes.CATPPUCCIN_LATTE // 'catppuccin-latte'
manager.themes.DRACULA // 'dracula'
manager.themes.GRUVBOX // 'gruvbox'
manager.themes.TOKYO_NIGHT // 'tokyo-night'
// Close method constants
manager.modal.closeOn.BUTTON // 'button'
manager.modal.closeOn.ESCAPE // 'escape'
manager.modal.closeOn.BACKDROP // 'backdrop'
manager.modal.closeOn.ANY // 'any'
// Button variant constants
manager.buttonVariant.DEFAULT // 'default'
manager.buttonVariant.PRIMARY // 'primary'
manager.buttonVariant.DESTRUCTIVE // 'destructive'
// Toast type constants
manager.toastType.SUCCESS // 'success'
manager.toastType.ERROR // 'error'
manager.toastType.INFO // 'info'
manager.toastType.WARNING // 'warning'| Property | Type | Default | Description |
|---|---|---|---|
title |
string |
required | Modal title text |
message |
string |
required | Modal content message |
buttons |
ModalButton[] |
[] |
Array of button objects (0-2 buttons) |
closeOn |
ModalCloseMethod[] |
[manager.modal.closeOn.ANY] |
How modal can be closed |
dim |
boolean |
true |
Enable backdrop darkening |
blur |
boolean |
true |
Enable backdrop blur effect |
theme |
string |
auto-detect | Theme to apply (use manager.themes.*) |
| Property | Type | Default | Description |
|---|---|---|---|
text |
string |
required | Button label |
variant |
'default' | 'primary' | 'destructive' |
manager.buttonVariant.DEFAULT |
Button style variant |
result |
string |
button text | Value returned when this button is clicked |
| Method | Description |
|---|---|
'button' |
Only close via button click |
'escape' |
Close on Escape key press |
'backdrop' |
Close on backdrop click |
'any' |
All of the above methods |
The showModal() method returns a Promise<string | null>:
- Returns the
resultvalue of the clicked button - Returns
nullif closed via Escape or backdrop click (when allowed)
- Promise-based API for async/await usage
- 0-2 button support with customizable variants
- Flexible close behavior (button, escape, backdrop, or any combination)
- Optional backdrop dimming and blur effects
- Automatic theme detection or explicit theme setting
- Keyboard accessibility (Escape key)
- Smooth fade/slide animations
// Confirmation dialog
const result = await manager.showModal({
title: 'Delete Item',
message: 'This action cannot be undone.',
buttons: [
{ text: 'Cancel', variant: manager.buttonVariant.DEFAULT, result: 'cancel' },
{ text: 'Delete', variant: manager.buttonVariant.DESTRUCTIVE, result: 'delete' }
]
});
if (result === 'delete') {
deleteItem();
}
// Force button choice (no escape/backdrop)
const choice = await manager.showModal({
title: 'Required Choice',
message: 'You must select an option:',
buttons: [
{ text: 'Option A', result: 'a' },
{ text: 'Option B', result: 'b' }
],
closeOn: [manager.modal.closeOn.BUTTON]
});
// choice is guaranteed to be 'a' or 'b', never null
// No visual effects
await manager.showModal({
title: 'Subtle Notice',
message: 'No backdrop effects applied',
dim: false,
blur: false
});
// Explicit theme
await manager.showModal({
title: 'Themed Modal',
message: 'Using midnight theme',
buttons: [{ text: 'Close', result: 'close' }],
theme: manager.themes.MIDNIGHT
});
// Close on specific methods only
await manager.showModal({
title: 'Escape or Backdrop',
message: 'Close via Escape key or backdrop click',
closeOn: [manager.modal.closeOn.ESCAPE, manager.modal.closeOn.BACKDROP]
});
// Single button
const confirmed = await manager.showModal({
title: 'Welcome',
message: 'Press Continue to proceed',
buttons: [
{ text: 'Continue', variant: manager.buttonVariant.PRIMARY, result: 'continue' }
]
});// Async confirmation with error handling
try {
const result = await manager.showModal({
title: 'Save Changes',
message: 'Do you want to save your changes before exiting?',
buttons: [
{ text: "Don't Save", variant: manager.buttonVariant.DEFAULT, result: 'discard' },
{ text: 'Save', variant: manager.buttonVariant.PRIMARY, result: 'save' }
],
closeOn: [manager.modal.closeOn.BUTTON, manager.modal.closeOn.ESCAPE]
});
if (result === 'save') {
await saveChanges();
} else if (result === 'discard') {
// User chose to discard
} else {
// User pressed Escape - don't exit
return;
}
exitApplication();
} catch (error) {
console.error('Modal error:', error);
}
// With custom theme per modal
const themes = [manager.themes.DARK, manager.themes.MIDNIGHT, manager.themes.NORD];
for (const theme of themes) {
await manager.showModal({
title: `${theme.charAt(0).toUpperCase() + theme.slice(1)} Theme`,
message: `This modal uses the ${theme} theme`,
buttons: [{ text: 'Next', result: 'next' }],
theme: theme
});
}Frost-UI comes with a built-in theme system and several preset themes:
Dark Themes:
- Dark (default)
- Midnight
- Nord
- Deep
- Obsidian
- Dusk
- Catppuccin Macchiato
- Dracula
- Gruvbox
- Tokyo Night
Light Themes:
- Catppuccin Latte
const menuElement = document.querySelector(".frost-menu");
menuElement.setTheme("Dark");
menuElement.setTheme("Midnight");
menuElement.setTheme("Nord");
menuElement.setTheme("Deep");
menuElement.setTheme("Obsidian");
menuElement.setTheme("Dusk");
menuElement.setTheme("Catppuccin-Macchiato");
menuElement.setTheme("Catppuccin-Latte");
menuElement.setTheme("Dracula");
menuElement.setTheme("Gruvbox");
menuElement.setTheme("Tokyo-Night");For type-safe theme references, use the FrostThemes constant:
import { FrostThemes } from 'frost-ui';
menuElement.setTheme(FrostThemes.DARK);
menuElement.setTheme(FrostThemes.MIDNIGHT);
menuElement.setTheme(FrostThemes.NORD);
menuElement.setTheme(FrostThemes.DEEP);
menuElement.setTheme(FrostThemes.OBSIDIAN);
menuElement.setTheme(FrostThemes.DUSK);
menuElement.setTheme(FrostThemes.CATPPUCCIN_MACCHIATO);
menuElement.setTheme(FrostThemes.CATPPUCCIN_LATTE);
menuElement.setTheme(FrostThemes.DRACULA);
menuElement.setTheme(FrostThemes.GRUVBOX);
menuElement.setTheme(FrostThemes.TOKYO_NIGHT);Available constants:
Dark Themes:
FrostThemes.DARK- Default blue-accented dark themeFrostThemes.MIDNIGHT- Purple-accented darker themeFrostThemes.NORD- Nord-inspired arctic themeFrostThemes.DEEP- Deep ocean blue/teal themeFrostThemes.OBSIDIAN- Dark stone theme with green accentsFrostThemes.DUSK- Warm sunset orange/purple themeFrostThemes.CATPPUCCIN_MACCHIATO- Soothing pastel dark theme with mauve accents (Catppuccin Macchiato)FrostThemes.DRACULA- Popular dark theme with purple accentsFrostThemes.GRUVBOX- Warm retro dark theme with orange accentsFrostThemes.TOKYO_NIGHT- Clean dark theme with blue accents
Light Themes:
FrostThemes.CATPPUCCIN_LATTE- Soothing pastel light theme with purple accents (Catppuccin Latte)
Create custom themes by defining CSS variables:
.frost-theme-custom {
--frost-bg-primary: rgba(20, 25, 35, 0.95); /* Main background */
--frost-bg-secondary: rgba(25, 30, 40, 0.6); /* Secondary elements */
--frost-bg-tertiary: rgba(30, 35, 45, 0.4); /* Interactive elements */
--frost-text-primary: rgba(255, 255, 255, 0.9); /* Main text */
--frost-text-secondary: rgba(255, 255, 255, 0.7); /* Secondary text */
--frost-accent-color: #ff7675; /* Primary accent color */
--frost-accent-hover: #e66767; /* Accent hover color */
--frost-border-color: rgba(255, 255, 255, 0.1); /* Borders */
--frost-shadow-color: rgba(0, 0, 0, 0.2); /* Shadows */
--frost-ripple-color: rgba(255, 255, 255, 0.7); /* Click effects */
}| Variable | Description |
|---|---|
--frost-bg-primary |
Main background color |
--frost-bg-secondary |
Secondary background |
--frost-bg-tertiary |
Interactive elements |
--frost-text-primary |
Main text color |
--frost-text-secondary |
Secondary text |
--frost-accent-color |
Primary accent |
--frost-accent-hover |
Hover state color |
--frost-border-color |
Border color |
--frost-shadow-color |
Shadow color |
--frost-ripple-color |
Click effect color |
/* Emerald theme */
.frost-theme-emerald {
--frost-bg-primary: rgba(20, 30, 25, 0.95);
--frost-bg-secondary: rgba(25, 35, 30, 0.6);
--frost-bg-tertiary: rgba(30, 40, 35, 0.4);
--frost-text-primary: rgba(255, 255, 255, 0.9);
--frost-text-secondary: rgba(255, 255, 255, 0.7);
--frost-accent-color: #2ecc71;
--frost-accent-hover: #27ae60;
--frost-border-color: rgba(255, 255, 255, 0.1);
--frost-shadow-color: rgba(0, 0, 0, 0.2);
--frost-ripple-color: rgba(255, 255, 255, 0.7);
}
/* Ocean theme */
.frost-theme-ocean {
--frost-bg-primary: rgba(20, 25, 35, 0.95);
--frost-bg-secondary: rgba(25, 30, 45, 0.6);
--frost-bg-tertiary: rgba(30, 35, 55, 0.4);
--frost-text-primary: rgba(255, 255, 255, 0.9);
--frost-text-secondary: rgba(255, 255, 255, 0.7);
--frost-accent-color: #3498db;
--frost-accent-hover: #2980b9;
--frost-border-color: rgba(255, 255, 255, 0.1);
--frost-shadow-color: rgba(0, 0, 0, 0.2);
--frost-ripple-color: rgba(255, 255, 255, 0.7);
}The Menu Manager provides basic control over Frost-UI menus in your application:
const manager = window.frostManager;
// Create a new menu
const menu = manager.addMenu(
"uniqueId", // Unique identifier for the menu
"Menu Title", // Display title
{ x: 100, y: 100 }, // Initial position (optional)
"ShiftRight" // Toggle key (optional, defaults to 'ShiftRight')
);
// Update menu toggle key
manager.updateMenuToggleKey("uniqueId", "ShiftLeft");
// Update keybind for a specific toggle
manager.updateKeybind(
"uniqueId", // Menu ID
"Combat", // Category name
"KillAura", // Toggle name
"KeyK" // New keybind
);
// Show toast notification
manager.showToast("Operation completed");
// or with options (using constants for type safety)
manager.showToast({
message: "Settings saved",
type: manager.toastType.SUCCESS,
duration: 3000,
});
// Show modal dialog (using constants)
const result = await manager.showModal({
title: "Confirm Action",
message: "Are you sure you want to proceed?",
buttons: [
{ text: "Cancel", variant: manager.buttonVariant.DEFAULT, result: "cancel" },
{ text: "Confirm", variant: manager.buttonVariant.PRIMARY, result: "confirm" }
]
});
console.log(result); // 'cancel', 'confirm', or nullOnce you have a menu instance, you can use these methods:
// Toggle menu visibility
menu.toggle();
// Check if menu is open
const isOpen = menu.isMenuOpen();
// Change toggle key
menu.setToggleKey("ShiftLeft");
// Change theme
menu.setTheme("dark"); // or "midnight", "nord", etc.
// Get menu container element
const container = menu.getContainer();
// Get all categories
const categories = menu.getCategories();
// Grid configuration methods
const gridConfig = menu.getGridConfig(); // Get grid config
menu.setGridConfig({ gridSize: 40 }); // Update grid config
menu.setGridEnabled(true); // Enable/disable grid
const isGridEnabled = menu.isGridEnabled(); // Check if grid is enabled// Create multiple menus
const mainMenu = manager.addMenu("main", "Main Menu", { x: 100, y: 100 });
const settingsMenu = manager.addMenu("settings", "Settings", { x: 400, y: 100 });
// Create search that works with both menus
const search = new window.frostSearch(
{
"Main Menu": mainMenu,
Settings: settingsMenu,
},
"k"
); // Use Cmd/Ctrl+K to open searchFrost-UI supports global configuration options that control behavior across all menus:
const manager = window.frostManager;
// Get current configuration
const config = manager.getConfig();
console.log(config);
// {
// dimOnMenuOpen: false,
// blurOnMenuOpen: false,
// rememberPositions: false,
// theme: undefined
// }
// Update configuration (partial updates supported)
manager.setConfig({
dimOnMenuOpen: true,
blurOnMenuOpen: true,
rememberPositions: true,
theme: 'nord'
});| Option | Type | Default | Description |
|---|---|---|---|
dimOnMenuOpen |
boolean | false |
Dim the background when any menu is open |
blurOnMenuOpen |
boolean | false |
Blur the background when any menu is open |
rememberPositions |
boolean | false |
Save menu positions to localStorage |
theme |
string | undefined |
Global theme override (see Global Theme) |
When dimOnMenuOpen or blurOnMenuOpen is enabled, a backdrop effect appears whenever any menu is open:
// Enable both dim and blur effects
window.frostManager.setConfig({
dimOnMenuOpen: true,
blurOnMenuOpen: true
});
// Now opening any menu will show the backdrop effect
menu.toggle();The backdrop automatically shows when at least one menu is open and hides when all menus are closed.
When rememberPositions is enabled, menu positions are automatically saved to localStorage and restored on page load:
// Enable position persistence
window.frostManager.setConfig({
rememberPositions: true
});
// Move a menu by dragging it...
// Position is automatically saved when drag ends
// On page reload, the menu will appear at its last positionNote: Position persistence uses the frost-menu-positions key in localStorage. Each menu's position is stored by its unique ID.
The theme configuration option allows you to set a global theme that overrides all individual component themes:
// Set a global theme - applies to all menus, modals, search, and toasts
window.frostManager.setConfig({
theme: 'nord'
});When a global theme is set:
- All existing menus immediately update to the new theme
- All new modals use the global theme
- The search menu uses the global theme
- All toast notifications use the global theme
- Individual
setTheme()calls on components are ignored - The setting persists across page reloads
// Create menus with individual themes
const menu1 = window.frostManager.addMenu("menu1", "Menu 1");
const menu2 = window.frostManager.addMenu("menu2", "Menu 2");
menu1.setTheme('tokyo-night');
menu2.setTheme('midnight');
// Set global theme - overrides both menus
window.frostManager.setConfig({ theme: 'nord' });
// Both menu1 and menu2 now use 'nord' theme
// Individual theme changes are ignored when global theme is active
menu1.setTheme('dracula'); // No effect - global theme takes precedence
// Clear global theme to restore individual themes
window.frostManager.setConfig({ theme: undefined });
// Menus revert to their individual themes (tokyo-night and midnight)Note: Global theme uses the frost-config key in localStorage and is automatically restored on page load.
// Setup Frost-UI with custom configuration
const manager = window.frostManager;
// Configure global settings
manager.setConfig({
dimOnMenuOpen: true,
blurOnMenuOpen: true,
rememberPositions: true
});
// Create menus - positions will be remembered
const mainMenu = manager.addMenu("main", "Main Menu", { x: 100, y: 100 });
const settingsMenu = manager.addMenu("settings", "Settings", { x: 400, y: 100 });
// When user drags menus to new positions, they're saved automatically
// On next page load, menus appear at their saved positions