> For the complete documentation index, see [llms.txt](https://docs.17movement.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.17movement.net/complete-interface-system/api/client-exports.md).

# Client Exports

All client exports are available through the `17mov_Interface` resource.

```lua
local interface = exports['17mov_Interface']
```

Optional arguments and fields are marked with `?`.

\
All exports listed on this page are also fully demonstrated in:

```
client/examples.lua
```

You can use that file as a reference for usage examples.

***

### Notifications

#### `NotificationData`

* `id?` `string` - Reusing the same ID updates the existing notification.
* `type?` `string` - `success`, `info`, `warning`, `error` or `message`. Defaults to `info`.
* `title?` `string` - Notification title.
* `description?` `string` - Notification description.
* `duration?` `number` - Duration in milliseconds.
* `icon?` `string` - Lucide icon name.
* `iconColor?` `string` - Hex icon color.
* `group?` `string` - Group key used for duplicate stacking.

#### `showNotification(data)`

Displays a notification.

**Arguments**

* `data` `NotificationData | string`

When a string is provided, it is used as the notification title.

```lua
interface:showNotification({
    type = 'success',
    title = 'Payment received',
    description = 'You received $500',
    duration = 4000,
    icon = 'banknote'
})
```

***

### Text UI

#### `TextUIOptions`

* `type?` `string` - `accent`, `info`, `success`, `warning` or `error`.
* `icon?` `string` - Lucide icon name.
* `iconColor?` `string` - Hex icon color.
* `duration?` `number` - Automatically hides the Text UI after the specified time.

#### `showTextUI(text, options?)`

Displays a Text UI element.

**Arguments**

* `text` `string` - Text to display.
* `options?` `TextUIOptions`

Key hints such as `[E]` are rendered as key elements.

```lua
interface:showTextUI('[E] Open the door', {
    type = 'info',
    icon = 'door-open'
})
```

#### `hideTextUI()`

Hides the currently displayed Text UI.

```lua
interface:hideTextUI()
```

#### `isTextUIOpen()`

**Returns**

```lua
boolean isOpen, string|nil currentText
```

***

### Progress Bar

#### `ProgressAnimation`

Animation played while the progress bar is active.

* `dict?` `string` - Animation dictionary.
* `clip?` `string` - Animation clip.
* `flag?` `number` - Animation flag. Defaults to `49`.
* `blendIn?` `number`
* `blendOut?` `number`
* `duration?` `number`
* `playbackRate?` `number`
* `lockX?` `boolean`
* `lockY?` `boolean`
* `lockZ?` `boolean`
* `scenario?` `string` - Can be used instead of a dictionary and clip.
* `playExitAnim?` `boolean`

Example:

```lua
{
    dict = 'mini@repair',
    clip = 'fixing_a_ped',
    flag = 49
}
```

A scenario can also be used:

```lua
{
    scenario = 'PROP_HUMAN_BUM_BIN'
}
```

#### `ProgressProp`

Prop attached to the player while the progress bar is active.

* `model` `string | number` - Prop model.
* `bone?` `number` - Bone ID. Defaults to `60309`.
* `pos?` `vector3` - Position offset.
* `rot?` `vector3` - Rotation offset.
* `rotOrder?` `number` - Rotation order.

Example:

```lua
{
    model = 'prop_tool_wrench',
    bone = 60309,
    pos = vec3(0.0, 0.0, 0.0),
    rot = vec3(0.0, 0.0, 0.0)
}
```

#### `ProgressDisable`

Controls disabled while the progress bar is active.

* `move?` `boolean`
* `car?` `boolean`
* `combat?` `boolean`
* `sprint?` `boolean`
* `mouse?` `boolean`

Example:

```lua
{
    move = true,
    car = true,
    combat = true,
    sprint = true
}
```

#### `ProgressData`

* `duration` `number` - Duration in milliseconds.
* `label?` `string` - Main progress label.
* `description?` `string` - Additional description.
* `canCancel?` `boolean` - Allows the player to cancel the progress.
* `useWhileDead?` `boolean`
* `allowRagdoll?` `boolean`
* `allowCuffed?` `boolean`
* `allowFalling?` `boolean`
* `allowSwimming?` `boolean`
* `anim?` `ProgressAnimation`
* `prop?` `ProgressProp | ProgressProp[]`
* `propTwo?` `ProgressProp`
* `disable?` `ProgressDisable`

#### `progressBar(data)`

Starts a progress bar and waits until it finishes or gets cancelled.

**Arguments**

* `data` `ProgressData`

**Returns**

`true` when completed and `false` when cancelled or interrupted.

```lua
boolean
```

**Example**

```lua
local completed = interface:progressBar({
    duration = 5000,
    label = 'Repairing engine',
    description = 'Hold still',
    canCancel = true,

    anim = {
        dict = 'mini@repair',
        clip = 'fixing_a_ped',
        flag = 49
    },

    prop = {
        model = 'prop_tool_wrench',
        bone = 60309,
        pos = vec3(0.0, 0.0, 0.0),
        rot = vec3(0.0, 0.0, 0.0)
    },

    disable = {
        move = true,
        car = true,
        combat = true
    }
})
```

#### `progressCircle(data)`

Alias of `progressBar`.

**Arguments**

* `data` `ProgressData`

**Returns**

```lua
boolean
```

#### `startProgress(data, onStart?, onTick?, onFinish?)`

Starts a non-blocking progress bar.

**Arguments**

* `data` `ProgressData`
* `onStart?` `function`
* `onTick?` `function`
* `onFinish?` `function(cancelled: boolean)`

**Returns**

```lua
boolean started
```

#### `cancelProgress()`

Cancels the active progress bar.

```lua
interface:cancelProgress()
```

#### `stopProgress()`

Stops the active progress bar and marks it as completed.

```lua
interface:stopProgress()
```

#### `progressActive()`

Returns whether a progress bar is currently active.

**Returns**

```lua
boolean
```

***

### Input Dialog

#### `InputDialogHeader`

* `title?` `string`
* `description?` `string`
* `icon?` `string`

#### `InputDialogOptions`

* `allowCancel?` `boolean` - Displays a cancel button.

#### Common Input Fields

These fields are available for every input type:

* `type?` `string`
* `label?` `string`
* `description?` `string`
* `placeholder?` `string`
* `icon?` `string`
* `default?` `any`
* `required?` `boolean`
* `disabled?` `boolean`

#### `TextInput`

* `type` `"text" | "input"`
* `min?` `number` - Minimum length.
* `max?` `number` - Maximum length.
* `password?` `boolean`

Returns `string`.

#### `NumberInput`

* `type` `"number"`
* `min?` `number`
* `max?` `number`
* `step?` `number`
* `decimals?` `number`
* `negative?` `boolean`

Returns `number`.

#### `CheckboxInput`

* `type` `"checkbox"`
* `text?` `string`
* `checked?` `boolean`

Returns `boolean`.

#### `SelectOption`

* `value` `any`
* `label` `string`
* `disabled?` `boolean`

#### `SelectInput`

* `type` `"select" | "multi-select"`
* `options` `SelectOption[]`

Returns the selected value.

#### `SliderInput`

* `type` `"slider"`
* `min?` `number`
* `max?` `number`
* `step?` `number`
* `unit?` `string`

Returns `number`.

#### `ColorInput`

* `type` `"color"`
* `presets?` `string[]`

Returns a hex color string.

#### `DateInput`

* `type` `"date"`
* `format?` `string`
* `returnString?` `boolean`
* `clearable?` `boolean`

Returns a timestamp or formatted string.

#### `DateRangeInput`

* `type` `"date-range"`
* `format?` `string`
* `returnString?` `boolean`
* `clearable?` `boolean`

Returns:

```lua
{
    from = any,
    to = any
}
```

#### `DateTimeInput`

* `type` `"date-time"`
* `format?` `string`
* `returnString?` `boolean`
* `clearable?` `boolean`
* `minuteStep?` `number`

Returns a timestamp or formatted string.

#### `TimeInput`

* `type` `"time"`
* `minuteStep?` `number`
* `clearable?` `boolean`

Returns:

```
HH:mm
```

#### `TextareaInput`

* `type` `"textarea"`
* `rows?` `number`
* `min?` `number`
* `max?` `number`

Returns `string`.

#### `InputRow`

An input row can be any of the following types:

```
TextInput
NumberInput
CheckboxInput
SelectInput
SliderInput
ColorInput
DateInput
DateRangeInput
DateTimeInput
TimeInput
TextareaInput
```

#### `inputDialog(header, rows, options?)`

Displays an input dialog and waits for the player's response.

**Arguments**

* `header` `string | InputDialogHeader`
* `rows` `InputRow[]`
* `options?` `InputDialogOptions`

**Returns**

A table containing values in the same order as the provided rows, or `nil` when cancelled.

```lua
table|nil
```

**Example**

```lua
local input = interface:inputDialog({
    title = 'Vehicle registration',
    icon = 'file-text'
}, {
    {
        type = 'text',
        label = 'Plate',
        required = true,
        min = 2,
        max = 8
    },
    {
        type = 'number',
        label = 'Price',
        min = 0
    },
    {
        type = 'checkbox',
        label = 'Insurance'
    }
}, {
    allowCancel = true
})

if not input then return end

print(input[1], input[2], input[3])
```

#### `closeInputDialog()`

Closes the currently displayed input dialog.

```lua
interface:closeInputDialog()
```

***

### Alert Dialog

#### `AlertDialogHeader`

* `title?` `string`
* `description?` `string`
* `icon?` `string`

#### `AlertDialogLabels`

* `confirm?` `string`
* `cancel?` `string`

#### `AlertDialogOptions`

* `allowCancel?` `boolean`
* `labels?` `AlertDialogLabels`

#### `AlertDialogData`

* `header` `string | AlertDialogHeader`
* `content` `string` - Markdown is supported.
* `options?` `AlertDialogOptions`

#### `alertDialog(data, timeout?)`

Displays an alert dialog and waits for the player's response.

**Arguments**

* `data` `AlertDialogData`
* `timeout?` `number` - Timeout in milliseconds.

**Returns**

```lua
'confirm' | 'cancel' | nil
```

```lua
local result = interface:alertDialog({
    header = {
        title = 'Sell the vehicle?',
        icon = 'car'
    },

    content = 'You will receive **$4,500**.',

    options = {
        allowCancel = true,
        labels = {
            confirm = 'Sell',
            cancel = 'Keep'
        }
    }
})
```

When using `timeout`, the call is rejected with `timeout` after the specified time.

#### `closeAlertDialog(reason?)`

Closes the currently displayed alert dialog.

**Arguments**

* `reason?` `string`

```lua
interface:closeAlertDialog()
```

***

### Context Menu

#### `ContextMetadata`

* `label` `string`
* `value?` `any`
* `progress?` `number`

#### `ContextOption`

* `title?` `string`
* `description?` `string`
* `icon?` `string`
* `iconColor?` `string`
* `image?` `string`
* `progress?` `number`
* `colorScheme?` `string`
* `arrow?` `boolean`
* `disabled?` `boolean`
* `readOnly?` `boolean`
* `metadata?` `ContextMetadata[] | table`
* `menu?` `string`
* `onSelect?` `function(args)`
* `event?` `string`
* `serverEvent?` `string`
* `args?` `any`

#### `ContextMenu`

* `id` `string`
* `title` `string`
* `description?` `string`
* `menu?` `string` - Parent context ID.
* `canClose?` `boolean`
* `options` `ContextOption[] | table`
* `onExit?` `function`
* `onBack?` `function`

#### `registerContext(context)`

Registers one or multiple context menus.

**Arguments**

* `context` `ContextMenu | ContextMenu[]`

```lua
interface:registerContext({
    id = 'garage',
    title = 'Garage',

    options = {
        {
            title = 'Sultan RS',
            icon = 'car',
            progress = 87
        },
        {
            title = 'Sell vehicle',
            icon = 'banknote',
            serverEvent = 'garage:server:sell'
        }
    }
})
```

#### `showContext(id)`

Opens a registered context menu.

**Arguments**

* `id` `string`

```lua
interface:showContext('garage')
```

#### `hideContext(onExit?)`

Closes the currently displayed context menu.

**Arguments**

* `onExit?` `boolean`

#### `getOpenContext()`

**Returns**

```lua
string|nil
```

***

### List Menu

#### `ListMenuValue`

* `label` `string`
* `description?` `string`

A plain string can also be used instead.

#### `ListMenuOption`

* `label?` `string`
* `description?` `string`
* `icon?` `string`
* `iconColor?` `string`
* `values?` `string[] | ListMenuValue[]`
* `defaultIndex?` `number`
* `checked?` `boolean`
* `progress?` `number`
* `colorScheme?` `string`
* `close?` `boolean`
* `disabled?` `boolean`
* `args?` `any`

#### `ListMenu`

* `id` `string`
* `title` `string`
* `position?` `string` - `top-left`, `top-right`, `bottom-left` or `bottom-right`.
* `options` `ListMenuOption[]`
* `menu?` `string`
* `canClose?` `boolean`
* `cursor?` `boolean`
* `disableInput?` `boolean`
* `onClose?` `function(keyPressed)`
* `onSelected?` `function(index, secondary, args)`
* `onSideScroll?` `function(index, scrollIndex, args)`
* `onCheck?` `function(index, checked, args)`
* `cb?` `function(index, scrollIndex, args, checked)`

#### `registerMenu(data, cb?)`

Registers a list menu.

**Arguments**

* `data` `ListMenu`
* `cb?` `function(index, scrollIndex, args, checked)`

```lua
interface:registerMenu({
    id = 'settings',
    title = 'Settings',
    position = 'top-left',

    options = {
        {
            label = 'Radio volume',
            values = { 'Low', 'Mid', 'High' },
            defaultIndex = 2,
            close = false
        },
        {
            label = 'Dark mode',
            checked = true
        }
    }
}, function(selected, scrollIndex, args, checked)
    print(selected, scrollIndex, checked)
end)
```

#### `setMenuOptions(id, options, index?)`

Updates all options or one specific option.

**Arguments**

* `id` `string`
* `options` `ListMenuOption[] | ListMenuOption`
* `index?` `number`

#### `showMenu(id, startIndex?)`

Opens a registered menu.

**Arguments**

* `id` `string`
* `startIndex?` `number`

#### `hideMenu(onExit?)`

Closes the active menu.

**Arguments**

* `onExit?` `boolean`

#### `getOpenMenu()`

**Returns**

```lua
string|nil
```

***

### Radial Menu

#### `RadialItem`

* `id?` `string`
* `label` `string`
* `icon?` `string`
* `onSelect?` `function(menuId, index, args) | string`
* `event?` `string`
* `serverEvent?` `string`
* `args?` `any`
* `menu?` `string`
* `condition?` `function`
* `disabled?` `boolean`
* `keepOpen?` `boolean`

#### `RadialMenu`

* `id` `string`
* `items` `RadialItem[]`

#### `registerRadial(menu)`

Registers a radial submenu.

**Arguments**

* `menu` `RadialMenu`

```lua
interface:registerRadial({
    id = 'police_menu',

    items = {
        {
            id = 'search',
            label = 'Search',
            icon = 'search',
            serverEvent = 'police:server:search'
        }
    }
})
```

#### `addRadialItem(items, parentMenuId?)`

Adds one or multiple radial items.

**Arguments**

* `items` `RadialItem | RadialItem[]`
* `parentMenuId?` `string`

#### `removeRadialItem(id, parentMenuId?)`

**Arguments**

* `id` `string`
* `parentMenuId?` `string`

#### `clearRadialItems()`

Removes all root radial items.

#### `disableRadial(state)`

**Arguments**

* `state` `boolean`

#### `openRadial(id?)`

**Arguments**

* `id?` `string`

#### `closeRadial()`

Closes the radial menu.

#### `toggleRadial(id?)`

**Arguments**

* `id?` `string`

#### `isRadialOpen()`

**Returns**

```lua
boolean
```

#### `getCurrentRadial()`

**Returns**

```lua
string|nil
```

***

### NPC Dialog

#### `DialogCamera`

* `distance?` `number`
* `height?` `number`
* `side?` `number`
* `fov?` `number`
* `blend?` `number`

#### `DialogPed`

* `model` `string | number`
* `coords` `vector3 | vector4`
* `heading?` `number`
* `distance?` `number` - Spawn distance.
* `interact?` `number` - Interaction distance.
* `label?` `string`
* `icon?` `string`
* `prompt?` `string`
* `helpText?` `string`
* `scenario?` `string`
* `freeze?` `boolean`
* `canInteract?` `function(entity, distance)`
* `canInteractInterval?` `number`

#### `DialogOption`

* `label` `string`
* `description?` `string`
* `icon?` `string`
* `disabled?` `boolean`
* `condition?` `function`
* `next?` `string`
* `close?` `boolean`
* `value?` `any`
* `args?` `any`
* `onClick?` `function(args, ped, result) | string`
* `onSelect?` `function(args, ped, result) | string`
* `event?` `string`
* `serverEvent?` `string`

#### `DialogNode`

* `speaker?` `string`
* `text` `string | string[]`
* `options?` `DialogOption[]`
* `onOpen?` `function(nodeId, ped)`

#### `Dialog`

* `id?` `string`
* `title?` `string`
* `start` `string`
* `nodes` `table<string, DialogNode>`
* `radius?` `number`
* `camera?` `DialogCamera`
* `ped?` `DialogPed`
* `hideHud?` `boolean`
* `hidePlayer?` `boolean`
* `faceCamera?` `boolean`
* `facialAnim?` `boolean`
* `canClose?` `boolean`
* `canInteract?` `function(entity, distance)`
* `onStart?` `function(ped)`
* `onSelect?` `function(result, ped)`
* `onEnd?` `function(ped, result)`
* `onResult?` `function(result, ped)`

#### `DialogResult`

* `dialog` `string`
* `node` `string`
* `index` `number`
* `label` `string`
* `value?` `any`
* `args?` `any`
* `path` `string[]`

#### `registerDialog(dialog)`

Registers one or multiple dialogs.

**Arguments**

* `dialog` `Dialog | table<string, Dialog>`

**Returns**

The generated or provided dialog ID when a single dialog is registered.

```lua
string
```

#### `startDialog(dialogOrId, ped?, customSettings?)`

Starts a dialog and waits for the player's response.

**Arguments**

* `dialogOrId` `Dialog | string`
* `ped?` `number`
* `customSettings?` `table`

**Returns**

```lua
DialogResult|nil
```

#### `stopDialog(silent?)`

Stops the active dialog.

**Arguments**

* `silent?` `boolean`

#### `removeDialog(id)`

Removes a registered dialog and its interaction.

**Arguments**

* `id` `string`

#### `isDialogOpen()`

**Returns**

```lua
string|false openDialogId, string|false currentNodeId
```

***

### Sounds

#### `playSound(name, volume?, exclusive?)`

Plays a registered sound.

**Arguments**

* `name` `string`
* `volume?` `number`
* `exclusive?` `boolean`

```lua
interface:playSound('notify:success')
```

#### `stopSound(name?)`

Stops a specific sound.

**Arguments**

* `name?` `string`

When no sound is specified, all sounds are stopped.

***

### HUD

#### `toggleDisplay(state)`

Shows or hides the HUD.

**Arguments**

* `state` `boolean`

#### `openEditor()`

Opens the player's HUD editor.

#### `setValue(key, value)`

Sets a HUD value.

**Arguments**

* `key` `string`
* `value` `any`

#### `getValue(key)`

Returns a stored HUD value.

**Arguments**

* `key` `string`

**Returns**

```lua
any
```

#### `getStatus()`

Returns the current status values.

**Returns**

```lua
{
    hunger = number,
    thirst = number,
    stress = number
}
```

***

### Info Panel

#### `InfoItemValue`

* `value` `any`
* `sub?` `any`
* `badge?` `any`

#### `setInfoItem(id, value, sub?, badge?)`

Updates an info panel item.

**Arguments**

* `id` `string`
* `value` `any | InfoItemValue`
* `sub?` `any`
* `badge?` `any`

```lua
interface:setInfoItem('radio', '245.5 MHz', 'Dispatch', 'LIVE')
```

Or:

```lua
interface:setInfoItem('job', {
    value = 'Mechanic',
    sub = 'Boss',
    badge = 'ON DUTY'
})
```

#### `refreshInfoItems()`

Refreshes all function-driven info panel items.

***

### Radar / Minimap

#### `hideRadar(state)`

Temporarily hides or shows the minimap.

**Arguments**

* `state` `boolean`

#### `setMapLoop(state)`

Enables or disables minimap management.

**Arguments**

* `state` `boolean`

***

### Seatbelt

#### `updateBeltsState(state)`

Updates the seatbelt state without playing the toggle sound.

**Arguments**

* `state` `boolean`

#### `getBeltsState(cb?)`

**Arguments**

* `cb?` `function(state)`

**Returns**

```lua
boolean
```

***

### Cinematic Mode

#### `enableCinematic()`

Enables cinematic mode.

#### `disableCinematic()`

Disables cinematic mode.

#### `toggleCinematic()`

Toggles cinematic mode.

#### `isCinematic()`

**Returns**

```lua
boolean
```

***

### Stress

#### `addStress(amount)`

Adds stress.

**Arguments**

* `amount` `number`

#### `removeStress(amount)`

Removes stress.

**Arguments**

* `amount` `number`

#### `getStress()`

**Returns**

```lua
number
```

#### `setStressEnabled(state)`

Enables or disables the stress system.

**Arguments**

* `state` `boolean`

#### `isStressEnabled()`

**Returns**

```lua
boolean
```

#### `setStressEffects(state)`

Enables or disables stress effects.

**Arguments**

* `state` `boolean`

***

### Stress Sources

#### `StressSourceOptions`

* `enabled?` `boolean`
* `check?` `function(service, now, source)`
* `poll?` `boolean`
* `interval?` `number`
* `gain?` `number`
* `cooldown?` `number`
* `notify?` `boolean`

`check` is required unless `poll = false`.

#### `addStressSource(id, options)`

Registers a custom stress source.

**Arguments**

* `id` `string`
* `options` `StressSourceOptions`

```lua
interface:addStressSource('lowhealth', {
    gain = 3,
    interval = 2000,
    cooldown = 5000,

    check = function()
        return GetEntityHealth(PlayerPedId()) < 150
    end
})
```

#### `removeStressSource(id)`

**Arguments**

* `id` `string`

#### `setStressSource(id, state)`

**Arguments**

* `id` `string`
* `state` `boolean`

**Returns**

```lua
boolean
```

#### `setStressSourceGain(id, amount)`

**Arguments**

* `id` `string`
* `amount` `number`

#### `isStressSource(id)`

**Arguments**

* `id` `string`

**Returns**

```lua
boolean
```

#### `getStressSources()`

Returns all registered stress sources.

#### `triggerStressSource(id)`

Triggers a manually controlled stress source.

**Arguments**

* `id` `string`
