Awoken UI
Awoken UI hooks into ox_lib at runtime, so existing scripts that already uselib.notify(), lib.progressBar(), etc. will automatically use the Awoken
theme with zero code changes.
You can also call exports directly via exports['awoken_ui'].
Notifications
exports['awoken_ui']:Notify({
title = 'Awoken Labs',
description = 'This is a notification',
type = 'success', -- 'info' | 'success' | 'warning' | 'error'
icon = 'circle-check',
duration = 5000,
position = 'top-right',
})
Progress bar
local completed = exports['awoken_ui']:ProgressBar({
label = 'Lockpicking...',
duration = 4000,
canCancel = true,
disable = {
move = true,
car = true,
combat = true,
},
anim = {
dict = 'mini@repair',
clip = 'fixing_a_ped',
},
})
if completed then
-- Player finished the bar without cancelling
end
Progress circle
local completed = exports['awoken_ui']:ProgressCircle({
label = 'Hacking...',
duration = 6000,
canCancel = true,
})
Cancel / query progress
exports['awoken_ui']:CancelProgress()
local active = exports['awoken_ui']:IsProgressActive()
Text UI
The Text UI surfaces a persistent on-screen prompt with optional keybind chips. Any[X] token in the text is auto-detected and rendered as a styled chip. Use | between actions and the prompt will stack them vertically, one chip per line.
- Direct export
- ox_lib
-- Single keybind (renders inline on one row)
exports['awoken_ui']:ShowTextUI('[E] Open stash', {
icon = 'warehouse',
})
-- Multi-character keys work the same way
exports['awoken_ui']:ShowTextUI('[CTRL + E] Sprint', {
icon = 'person-running',
})
-- Multiple keybinds split with `|` stack vertically
exports['awoken_ui']:ShowTextUI(
'[E] Open Trunk | [G] Lock Vehicle | [H] Honk Horn',
{ icon = 'car' }
)
-- Markdown still works inside non-chip text
exports['awoken_ui']:ShowTextUI('[E] **Open** the safe', { icon = 'lock' })
-- Hide it
exports['awoken_ui']:HideTextUI()
-- Check state
local isOpen, currentText = exports['awoken_ui']:IsTextUIOpen()
-- Single keybind (renders inline on one row)
lib.showTextUI('[E] Open stash', { icon = 'warehouse' })
-- Multi-character keys work the same way
lib.showTextUI('[CTRL + E] Sprint', { icon = 'person-running' })
-- Multiple keybinds split with `|` stack vertically
lib.showTextUI(
'[E] Open Trunk | [G] Lock Vehicle | [H] Honk Horn',
{ icon = 'car' }
)
-- Markdown still works inside non-chip text
lib.showTextUI('[E] **Open** the safe', { icon = 'lock' })
-- Hide it
lib.hideTextUI()
The script API hasn’t changed. Existing prompts like
'Press [E] to interact' automatically pick up the new chip styling without code changes.Input dialog
Each row can carry adescription, a default value, a placeholder, a required flag, and a type-specific icon highlight in the label. select fields render via a portal-mounted dropdown so they can overflow the dialog cleanly.
- Direct export
- ox_lib
local result = exports['awoken_ui']:InputDialog('Create character', {
{
type = 'input',
label = 'First name',
required = true,
placeholder = 'Enter your first name',
},
{
type = 'input',
label = 'Last name',
required = true,
placeholder = 'Enter your last name',
},
{
type = 'number',
label = 'Age',
min = 18, max = 90, default = 25,
description = 'Must be 18 or older to register',
},
{
type = 'select',
label = 'Nationality',
default = 'us',
options = {
{ label = 'American', value = 'us' },
{ label = 'British', value = 'uk' },
{ label = 'German', value = 'de' },
{ label = 'French', value = 'fr' },
{ label = 'Japanese', value = 'jp' },
},
},
{
type = 'multi-select',
label = 'Languages spoken',
placeholder = 'Select all that apply',
options = {
{ label = 'English', value = 'en' },
{ label = 'Spanish', value = 'es' },
{ label = 'French', value = 'fr' },
},
},
{
type = 'slider',
label = 'Voice volume',
min = 0, max = 100, step = 5, default = 75,
description = 'In-game voice chat volume level',
},
{
type = 'checkbox',
label = 'Accept terms of service',
required = true,
},
{
type = 'textarea',
label = 'Backstory',
placeholder = 'Tell us about your character...',
},
{
type = 'color',
label = 'Profile colour',
default = '#00E5FF',
},
{
type = 'date',
label = 'Date of birth',
required = true,
},
{
type = 'time',
label = 'Preferred play time',
},
}, { size = 'md' })
if result then
-- result is an array of field values in field order
local firstName = result[1]
local lastName = result[2]
local age = result[3]
-- ...etc
end
-- Close programmatically
exports['awoken_ui']:CloseInputDialog()
local result = lib.inputDialog('Create character', {
{
type = 'input',
label = 'First name',
required = true,
placeholder = 'Enter your first name',
},
{
type = 'input',
label = 'Last name',
required = true,
placeholder = 'Enter your last name',
},
{
type = 'number',
label = 'Age',
min = 18, max = 90, default = 25,
description = 'Must be 18 or older to register',
},
{
type = 'select',
label = 'Nationality',
default = 'us',
options = {
{ label = 'American', value = 'us' },
{ label = 'British', value = 'uk' },
{ label = 'German', value = 'de' },
{ label = 'French', value = 'fr' },
{ label = 'Japanese', value = 'jp' },
},
},
{
type = 'multi-select',
label = 'Languages spoken',
placeholder = 'Select all that apply',
options = {
{ label = 'English', value = 'en' },
{ label = 'Spanish', value = 'es' },
{ label = 'French', value = 'fr' },
},
},
{
type = 'slider',
label = 'Voice volume',
min = 0, max = 100, step = 5, default = 75,
description = 'In-game voice chat volume level',
},
{
type = 'checkbox',
label = 'Accept terms of service',
required = true,
},
{
type = 'textarea',
label = 'Backstory',
placeholder = 'Tell us about your character...',
},
{
type = 'color',
label = 'Profile colour',
default = '#00E5FF',
},
{
type = 'date',
label = 'Date of birth',
required = true,
},
{
type = 'time',
label = 'Preferred play time',
},
})
if result then
local firstName = result[1]
local lastName = result[2]
local age = result[3]
-- ...etc
end
Each field label gets a small type-specific icon highlight automatically (text, number, select, slider, etc). Mark a field with
required = true to add a red asterisk and prevent submission until it’s filled.Alert dialog
local confirmed = exports['awoken_ui']:AlertDialog({
header = 'Confirm purchase',
content = 'Buy this vehicle for $50,000?',
cancel = 'No',
confirm = 'Yes',
}, 30000) -- optional timeout in ms
-- confirmed is 'confirm' or 'cancel'
-- Close programmatically
exports['awoken_ui']:CloseAlertDialog()
Context menu
-- Register a menu (can be done once at resource start)
exports['awoken_ui']:RegisterContext({
id = 'garage_menu',
title = 'Garage',
options = {
{ title = 'Withdraw vehicle', icon = 'car', event = 'garage:withdraw' },
{ title = 'Store vehicle', icon = 'warehouse', event = 'garage:store' },
{ title = 'Vehicle list', icon = 'list', menu = 'garage_vehicles' },
},
})
-- Open it
exports['awoken_ui']:ShowContext('garage_menu')
-- Close it
exports['awoken_ui']:HideContext()
-- Check which menu is open
local menuId = exports['awoken_ui']:GetOpenContextMenu() -- returns id or nil
List menu
lib.registerMenu({
id = 'my_list',
title = 'Select an option',
options = {
{ label = 'Option 1' },
{ label = 'Option 2' },
{ label = 'Option 3' },
},
}, function(selected, scrollIndex, args)
-- callback when an item is selected
end)
exports['awoken_ui']:ShowMenu('my_list')
-- Update a menu's options (all of them, or a single item by index)
exports['awoken_ui']:SetMenuOptions('my_list', { { label = 'New Option' } })
exports['awoken_ui']:SetMenuOptions('my_list', { label = 'Updated Item 2' }, 2)
-- Close it
exports['awoken_ui']:HideMenu()
-- Check which menu is open
local menuId = exports['awoken_ui']:GetOpenMenu() -- returns id or nil
Radial menu
-- Add items to the global radial menu
exports['awoken_ui']:AddRadialItem({
{
id = 'police_menu',
label = 'Police',
icon = 'shield',
menu = 'police_radial',
},
})
-- Register a sub-menu
exports['awoken_ui']:RegisterRadial({
id = 'police_radial',
items = {
{ label = 'Cuff', icon = 'handcuffs', onSelect = function() end },
{ label = 'Search', icon = 'magnifying-glass', onSelect = function() end },
},
})
-- Remove an item from the global radial
exports['awoken_ui']:RemoveRadialItem('police_menu')
-- Clear all global radial items
exports['awoken_ui']:ClearRadialItems()
-- Close the radial menu
exports['awoken_ui']:HideRadial()
-- Enable / disable the radial menu (true = disabled)
exports['awoken_ui']:DisableRadial(true)
-- Check which radial sub-menu is open
local id = exports['awoken_ui']:GetCurrentRadialId() -- returns id or nil
The radial menu keybind defaults to Z and can be changed in
config.lua via AwokenConfig.radialOpenKey.Skill check
local success = exports['awoken_ui']:SkillCheck(
{ 'easy', 'easy', 'medium' }, -- difficulty per stage: 'easy' | 'medium' | 'hard'
{ 'w', 'a', 's', 'd' } -- optional: custom input keys (random per stage)
)
if success then
-- player passed all stages
end
-- Cancel / query
exports['awoken_ui']:CancelSkillCheck()
local active = exports['awoken_ui']:IsSkillCheckActive()
Runtime config override
Merge config fields into the live UI without restarting the resource. Useful for previewing variants (e.g.progressBarVariant, skillcheckVariant) on the fly. Not persisted - reverts to config.lua on restart.
exports['awoken_ui']:SetConfig({ progressBarVariant = 'secondary' })
Every export is registered in PascalCase (
Notify, ShowContext) and also as a camelCase alias matching ox_lib’s lib.* names (notify, showContext), so either casing resolves to the same function.