Exports & Developer API

These are client exports unless stated otherwise. Add dependency 'finals_UI' to the caller and start Finals first. Waiting APIs must run in a yieldable thread/event/callback.


Optional helper

Lua
-- Your fxmanifest.lua:
client_scripts {'@finals_UI/init.lua','client.lua'}
dependency 'finals_UI'
-- Your client.lua:
fui.notify({title='Hello',type='success'})

Direct calls use exports.finals_UI:method(...).

Notification and TextUI

Lua
exports.finals_UI:notify({
    title='Outfit saved',description='Your new look is ready.',
    type='success',duration=4000,position='top-right',icon='check'
})
exports.finals_UI:showTextUI('[E] Open locker  [G] View options',{
    icon='hand',position='right-center'
})
exports.finals_UI:hideTextUI()
local open,text=exports.finals_UI:isTextUIOpen()

defaultNotify is also available. TextUI uses separate bracketed key tokens. Notifications do not take menu focus.

Progress bar and circle

Lua
CreateThread(function()
    local success=exports.finals_UI:progressCircle({
        duration=5000,label='Searching for the car keys...',position='middle',
        canCancel=true,disable={move=true,car=true,combat=true}
    })
    print(success and 'Completed' or 'Canceled')
end)

Use progressBar(data) for a linear bar. Duration is milliseconds. These calls wait and return completion/cancellation. progressActive() checks activity; cancelProgress() cancels. Optional animation/prop settings are supported. Revalidate rewards on the server.

Timer

Lua
exports.finals_UI:showTimer({
    id='event',label='Event countdown',seconds=5652,position='left-center',
    onComplete=function() print('Countdown finished') end
})
exports.finals_UI:updateTimer('event',{seconds=120,label='Final round'})
local timer=exports.finals_UI:getTimer('event')
local active=exports.finals_UI:isTimerActive('event')
exports.finals_UI:hideTimer('event')

Timer duration is seconds, unlike progress. IDs are caller-scoped; update/remove from that resource. autoHide=false keeps a completed timer until hidden. Timers are display utilities, not authoritative server clocks.

Input and confirmation

Lua
CreateThread(function()
    local input=exports.finals_UI:inputDialog('Save outfit',{
        {type='input',label='Name',required=true},
        {type='select',label='Category',options={{value='casual',label='Casual'},{value='work',label='Work'}}}
    })
    if not input then return end
    print(input[1],input[2])
    local answer=exports.finals_UI:alertDialog({
        header='Save this outfit?',content='You can change it later.',centered=true,cancel=true
    })
    if answer=='confirm' then print('Confirmed') end
end)

Supported controls include inputs/passwords, number, checkbox, select/multi-select, slider and supported date/time fields. closeInputDialog() and closeAlertDialog() close active dialogs. Handle cancellation and validate values on the server.

Context menu

Lua
exports.finals_UI:registerContext({
    id='my_garage',title='Garage',options={
        {title='View vehicles',icon='car',onSelect=function() print('Open garage') end},
        {title='Unavailable',disabled=true}
    }
})
exports.finals_UI:showContext('my_garage')
-- hideContext(onExit?) / getOpenContextMenu()

Submenus use menu on an option and a registered child context. Give the child the parent menu ID for Back navigation. Keep IDs unique.

List menu

Lua
exports.finals_UI:registerMenu({
    id='vehicle_prefs',title='Vehicle preferences',position='top-right',
    options={{label='Headlights',values={'Off','Low','High'}},{label='Lock doors',checked=true}}
},function(selected,scrollIndex,args)
    print(selected,scrollIndex)
end)
exports.finals_UI:showMenu('vehicle_prefs')
-- hideMenu(onExit?) / getOpenMenu() / setMenuOptions(id,options,index?)

Radial menu

Lua
exports.finals_UI:addRadialItem({
    id='example',label='Information',icon='circle-info',
    onSelect=function() print('Selected radial item') end
})
-- removeRadialItem('example') / clearRadialItems() / hideRadial()

registerRadial(data) defines a submenu; root items may reference its menu ID. Other APIs are showRadial(), disableRadial(boolean), getCurrentRadialId(). Use the configured key rather than duplicating the binding in another script.

Skill check

Lua
CreateThread(function()
    local passed=exports.finals_UI:skillCheck({'easy','medium'},{'e'})
    print(passed and 'Success' or 'Failed/canceled')
end)
-- skillCheckActive() / cancelSkillCheck()

Visibility

Lua
exports.finals_UI:hideHud()
exports.finals_UI:showHud()
exports.finals_UI:setHudVisible(false)
exports.finals_UI:hideUI('speedometer')
exports.finals_UI:showUI('speedometer')
exports.finals_UI:setComponentVisible('minimap',false)
exports.finals_UI:hideUI() -- all UI
exports.finals_UI:showUI()
local visible=exports.finals_UI:isComponentVisible('hud')
local state=exports.finals_UI:getUIVisibility()

Each caller owns its hides. Show from the same resource to release a hide; other resources' hides remain active. Requests clear on caller stop. Config/player settings and parent hides retain priority. Show does not reopen a canceled dialog or force an inactive component open.

Names: hud, stats, speedometer, minimap, compass, voice, logo, info, infoName, infoServer, infoCash, infoBank, infoJob, infoGang, chat, notify, textui, timer, progress, context, menu, radial, input, alert, skillcheck, target, interaction, pausemenu, editor, all.

Hiding an interactive component closes/releases focus; progress/input/skill checks cancel. HUD visibility does not hide unrelated chat/notifications/menus. Voice includes the world mic; speedometer includes the hologram. Server scripts should use their own validated client event for these calls.

Other APIs

  • setClipboard(text) copies client text.
  • getTheme() returns the palette; setUiTheme(key) selects a configured theme.
  • setSeatbelt(boolean) pushes belt display state.
  • World registration methods are covered in Targets & 3D World Interactions.
  • registerTargetProvider, targetMessage and setTargetFocus are adapter plumbing. Ordinary scripts should continue calling their target API.

Server authority

Never treat a client UI success as authorization. Revalidate permissions, distance, inventory, cooldown and transaction/reward conditions server-side before changing gameplay state.