Implement this in the code: Built-in Right-Click Menu
tksheet provides a built-in right-click menu option to edit headers directly in the GUI:

    Right-click on the header you want to rename.
    Select the "Edit header" option from the context menu.
    Enter the new header name in the dialog box that appears.

This feature is available if both the right-click menu and header editing are enabled.  Python 3.12 code: import tkinter as tk
from tksheet import Sheet
import json
from pathlib import Path
import ctypes


def set_dpi_awareness():
    """Enable DPI awareness to ensure high DPI settings are supported."""
    try:
        ctypes.windll.shcore.SetProcessDpiAwareness(1)
    except Exception as e:
        print(f"Error setting DPI awareness: {e}")


class TableApp:
    def __init__(self, root):
        """Initialize the Table Editor application."""
        self.root = root
        self.root.title("Table Editor with Sidebar")
        self.root.geometry("1280x720")

        self.sidebar = tk.Frame(root, width=200, bg='#F7F8FC', bd=0, relief='flat')
        self.sidebar.pack(expand=False, fill='y', side='left', anchor='nw')

        self.separator = tk.Frame(root, width=100, bg='white', bd=0, relief='flat')
        self.separator.pack(expand=False, fill='y', side='left', anchor='nw')

        self.main_frame = tk.Frame(root)
        self.main_frame.pack(expand=True, fill='both', side='right')

        self.header_frame = tk.Frame(self.main_frame, height=50, bg='white')
        self.header_frame.pack(fill='x')

        self.filter_label = tk.Label(self.header_frame, text="Filter:", bg='white', anchor="w")
        self.filter_label.pack(side='left', padx=5, pady=10)

        self.filter_entry = tk.Entry(self.header_frame)
        self.filter_entry.pack(side='left', padx=5, pady=10)
        self.filter_entry.bind("<KeyRelease>", lambda event: self.apply_filter())

        self.table_frame = tk.Frame(self.main_frame, bg='white')
        self.table_frame.pack(expand=True, fill='both')

        self.new_table_button = tk.Button(
            self.sidebar,
            text="New Table",
            command=self.create_new_table,
            bg='#F7F8FC',
            borderwidth=0,
            highlightthickness=0,
            relief='flat'
        )
        self.new_table_button.pack(padx=10, pady=10, fill='x')

        self.table_listbox = tk.Listbox(
            self.sidebar,
            bg='#F7F8FC',
            borderwidth=0,
            highlightthickness=0,
            relief='flat',
            selectbackground='#EAEDEF',
            selectforeground='black',
            activestyle='none'
        )
        self.table_listbox.pack(expand=True, fill='both', padx=10, pady=10)
        self.table_listbox.bind('<<ListboxSelect>>', self.load_selected_table)
        self.table_listbox.bind('<Double-1>', self.begin_rename)

        self.save_file_dir = Path("tables")
        self.tables = {}
        self.original_data = {}

        self.rename_entry = None
        if not self.save_file_dir.exists():
            self.save_file_dir.mkdir()
        self.load_tables()

    def create_new_table(self):
        """Create a new table and add it to the available tables list."""
        table_name = f"Table {len(self.tables) + 1}"
        self.add_table(table_name)

    def add_table(self, table_name, data=None):
        """Add a table to the UI and internal storage."""
        self.tables[table_name] = Sheet(
            self.table_frame,
            data=data if data else [["" for _ in range(5)] for _ in range(10)]
        )
        self.tables[table_name].enable_bindings()
        self.tables[table_name].extra_bindings([
            ("end_edit_cell", lambda event, table_name=table_name: self.save_data(table_name)),
        ])
        self.tables[table_name].pack_forget()
        self.original_data[table_name] = self.tables[table_name].get_sheet_data()
        self.table_listbox.insert('end', table_name)

    def begin_rename(self, _):
        """Begin renaming of the table name in the listbox."""
        selection = self.table_listbox.curselection()
        if selection:
            index = selection[0]
            current_name = self.table_listbox.get(index)

            bbox = self.table_listbox.bbox(index)
            if not bbox:
                return

            listbox_x = self.table_listbox.winfo_x()
            listbox_y = self.table_listbox.winfo_y()

            bbox_x, bbox_y, bbox_width, bbox_height = bbox
            entry_x = listbox_x + bbox_x
            entry_y = listbox_y + bbox_y

            self.rename_entry = tk.Entry(
                self.sidebar,
                bg='#EAEDEF',
                fg='black',
                selectbackground='#EAEDEF',
                selectforeground='black',
                borderwidth=0,
                relief='flat',
                highlightthickness=0
            )

            entry_width = self.table_listbox.winfo_width()

            self.rename_entry.place(
                x=entry_x,
                y=entry_y,
                width=entry_width,
                height=bbox_height
            )
            self.rename_entry.insert(0, current_name)
            self.rename_entry.focus()
            self.rename_entry.configure(font=self.table_listbox.cget("font"))
            self.rename_entry.bind('<Return>', lambda _: self.end_rename(index))
            self.rename_entry.bind('<FocusOut>', lambda _: self.cancel_rename())

    def end_rename(self, index):
        """Finish the renaming process and update the table name."""
        new_name = self.rename_entry.get().strip()
        current_name = self.table_listbox.get(index)

        if new_name and new_name != current_name and new_name not in self.tables:
            self.tables[new_name] = self.tables.pop(current_name)
            self.original_data[new_name] = self.original_data.pop(current_name)

            self.table_listbox.delete(index)
            self.table_listbox.insert(index, new_name)

            current_file = self.save_file_dir / f"{current_name}.json"
            new_file = self.save_file_dir / f"{new_name}.json"

            if current_file.exists():
                current_file.rename(new_file)

        self.rename_entry.destroy()
        self.rename_entry = None

    def cancel_rename(self):
        """Cancel the renaming process."""
        if self.rename_entry:
            self.rename_entry.destroy()
            self.rename_entry = None

    def load_tables(self):
        """Load existing tables from the directory."""
        for file_path in self.save_file_dir.glob("*.json"):
            table_name = file_path.stem
            with file_path.open('r') as file:
                data = json.load(file)
                self.add_table(table_name, data)

    def load_selected_table(self, _=None):
        """Display the selected table and hide others."""
        selection = self.table_listbox.curselection()
        for sheet in self.tables.values():
            sheet.pack_forget()

        if selection:
            selected_table_name = self.table_listbox.get(selection[0])
            self.tables[selected_table_name].pack(expand=True, fill='both')
            self.apply_filter()
        else:
            self.table_frame.configure(bg='white')

    def save_data(self, table_name):
        """Save current data of a table to a file."""
        data = self.tables[table_name].get_sheet_data()
        file_path = self.save_file_dir / f"{table_name}.json"
        with file_path.open('w') as file:
            json.dump(data, file)
        print(f"Data for {table_name} saved successfully.")

    def apply_filter(self):
        """Apply filtering based on the entered term."""
        term = self.filter_entry.get().lower()
        selection = self.table_listbox.curselection()
        if selection:
            table_name = self.table_listbox.get(selection[0])
            original_data = self.original_data[table_name]

            filtered_data = [
                row for row in original_data if any(term in str(cell).lower() for cell in row)
            ]

            self.tables[table_name].set_sheet_data(filtered_data)


if __name__ == "__main__":
    set_dpi_awareness()
    root = tk.Tk()
    app = TableApp(root)
    root.mainloop()