telega/menu_builder

Menu Builder Module

This module provides an advanced menu system for Telegram bots, extending beyond basic keyboards to create rich, interactive menu experiences with state management, navigation, and pagination.

Key Features

Quick Start

Simple Menu

let menu = menu_builder.new("main_menu")
  |> menu_builder.title("๐Ÿ  Main Menu")
  |> menu_builder.add_item("๐Ÿ“‹ View Items", "view_items")
  |> menu_builder.add_item("โž• Add Item", "add_item")
  |> menu_builder.add_item("โš™๏ธ Settings", "settings")
  |> menu_builder.build()

Paginated Menu

let items = ["Item 1", "Item 2", "Item 3", ..., "Item 100"]
let menu = menu_builder.new("item_list")
  |> menu_builder.title("๐Ÿ“‹ Items")
  |> menu_builder.paginate(items, page: 1, items_per_page: 10)
  |> menu_builder.with_back_button("main_menu")
  |> menu_builder.build()

Stateful Menu with Actions

pub type MenuState {
  MenuState(items: List(String), selected: Option(Int))
}

let menu = menu_builder.new_stateful("item_selector", initial_state)
  |> menu_builder.title("Select an Item")
  |> menu_builder.add_stateful_items(state.items, fn(item, index) {
    let selected = case state.selected {
      Some(i) if i == index -> "โœ… "
      _ -> ""
    }
    #(selected <> item, "select:" <> int.to_string(index))
  })
  |> menu_builder.on_action("select", fn(state, data) {
    let index = int.parse(data) |> result.unwrap(0)
    MenuState(..state, selected: Some(index))
  })
  |> menu_builder.build()

Types

Menu configuration

pub opaque type Menu(state)

Menu action handler

pub type MenuAction(state) =
  fn(MenuState(state), String) -> MenuState(state)

Menu builder for constructing menus

pub opaque type MenuBuilder(state)

Represents a menu item with text and action data

pub type MenuItem {
  MenuItem(text: String, action: String, enabled: Bool)
}

Constructors

  • MenuItem(text: String, action: String, enabled: Bool)

Menu layout configuration

pub type MenuLayout {
  MenuLayout(
    columns: Int,
    max_rows_per_section: option.Option(Int),
    section_separator: Bool,
  )
}

Constructors

  • MenuLayout(
      columns: Int,
      max_rows_per_section: option.Option(Int),
      section_separator: Bool,
    )

Represents a menu section for grouping related items

pub type MenuSection {
  MenuSection(
    title: option.Option(String),
    items: List(MenuItem),
  )
}

Constructors

Menu state for stateful menus

pub type MenuState(state) {
  MenuState(
    id: String,
    data: state,
    current_page: Int,
    navigation_stack: List(String),
    context: dict.Dict(String, String),
  )
}

Constructors

  • MenuState(
      id: String,
      data: state,
      current_page: Int,
      navigation_stack: List(String),
      context: dict.Dict(String, String),
    )

Navigation configuration

pub type NavigationConfig {
  NavigationConfig(
    back_button: option.Option(String),
    back_text: String,
    home_button: option.Option(String),
    home_text: String,
    show_breadcrumbs: Bool,
  )
}

Constructors

  • NavigationConfig(
      back_button: option.Option(String),
      back_text: String,
      home_button: option.Option(String),
      home_text: String,
      show_breadcrumbs: Bool,
    )

Configuration for pagination

pub type PaginationConfig {
  PaginationConfig(
    items_per_page: Int,
    show_page_info: Bool,
    prev_text: String,
    next_text: String,
    page_info_template: String,
  )
}

Constructors

  • PaginationConfig(
      items_per_page: Int,
      show_page_info: Bool,
      prev_text: String,
      next_text: String,
      page_info_template: String,
    )

Values

pub fn add_disabled_item(
  builder: MenuBuilder(state),
  text: String,
  action: String,
) -> MenuBuilder(state)

Add a disabled menu item

pub fn add_item(
  builder: MenuBuilder(state),
  text: String,
  action: String,
) -> MenuBuilder(state)

Add a simple menu item

pub fn add_items_from_list(
  builder: MenuBuilder(state),
  items: List(item),
  formatter: fn(item, Int) -> #(String, String),
) -> MenuBuilder(state)

Add multiple items from a list with custom formatting

pub fn add_stateful_items(
  builder: MenuBuilder(state),
  items: List(item),
  formatter: fn(item, Int, state) -> #(String, String, Bool),
) -> MenuBuilder(state)

Add items for stateful menus that can access state

pub fn add_submenu(
  builder: MenuBuilder(state),
  text: String,
  submenu_id: String,
) -> MenuBuilder(state)

Create a submenu item that navigates to another menu

pub fn add_toggle(
  builder: MenuBuilder(state),
  text_template: String,
  action: String,
  current_value: Bool,
) -> MenuBuilder(state)

Create a toggle item for boolean settings

pub fn build(builder: MenuBuilder(state)) -> Menu(state)

Build the final menu

pub fn confirmation(
  id: String,
  message: String,
  confirm_action: String,
  cancel_action: String,
  confirm_text: String,
  cancel_text: String,
) -> Menu(Nil)

Create a confirmation menu

pub fn get_callback_data(
  menu: Menu(state),
) -> keyboard.KeyboardCallbackData(String)

Get menu callback data for filtering

pub fn get_state(
  menu: Menu(state),
) -> option.Option(MenuState(state))

Get menu state

pub fn get_title(menu: Menu(state)) -> String

Helper to get menu title with optional state formatting

pub fn handle_action(
  menu: Menu(state),
  action: String,
) -> Result(Menu(state), String)

Handle menu action and return updated menu

pub fn layout(
  builder: MenuBuilder(state),
  columns: Int,
  max_rows_per_section: option.Option(Int),
  section_separator: Bool,
) -> MenuBuilder(state)

Configure menu layout

pub fn new(id: String) -> MenuBuilder(Nil)

Create a new stateless menu builder

pub fn new_stateful(
  id: String,
  initial_state: state,
) -> MenuBuilder(state)

Create a new stateful menu builder

pub fn on_action(
  builder: MenuBuilder(state),
  action_name: String,
  handler: fn(MenuState(state), String) -> MenuState(state),
) -> MenuBuilder(state)

Register an action handler for stateful menus

pub fn paginate(
  builder: MenuBuilder(state),
  items_per_page: Int,
  show_page_info: Bool,
) -> MenuBuilder(state)

Configure pagination

pub fn paginate_with_text(
  builder: MenuBuilder(state),
  items_per_page: Int,
  show_page_info: Bool,
  prev_text: String,
  next_text: String,
  page_info_template: String,
) -> MenuBuilder(state)

Configure pagination with custom texts

pub fn section(
  builder: MenuBuilder(state),
  title: option.Option(String),
) -> MenuBuilder(state)

Start a new section with optional title

pub fn settings_menu(
  id: String,
  menu_title: String,
  settings: List(#(String, String, Bool)),
) -> Menu(Nil)

Create a settings menu with toggles

pub fn title(
  builder: MenuBuilder(state),
  title: String,
) -> MenuBuilder(state)

Set the menu title

pub fn to_keyboard(
  menu: Menu(state),
) -> Result(keyboard.InlineKeyboard, String)

Convert menu to inline keyboard

pub fn update_state(
  menu: Menu(state),
  updater: fn(MenuState(state)) -> MenuState(state),
) -> Menu(state)

Update menu state

pub fn with_back_button(
  builder: MenuBuilder(state),
  back_action: String,
) -> MenuBuilder(state)

Add back button navigation

pub fn with_back_button_text(
  builder: MenuBuilder(state),
  back_action: String,
  back_text: String,
) -> MenuBuilder(state)

Add back button navigation with custom text

pub fn with_home_button(
  builder: MenuBuilder(state),
  home_action: String,
) -> MenuBuilder(state)

Add home button navigation

pub fn with_home_button_text(
  builder: MenuBuilder(state),
  home_action: String,
  home_text: String,
) -> MenuBuilder(state)

Add home button navigation with custom text

โœจ Search Document