Search code examples
reactjstypescriptelectronwindowtitlebar

Adding Close, Minimize, and Maximize buttons to a React-based Electron App


I'm making an electron app with React Typescript for the UI framework and I'm having trouble implementing functionality for the minimize, maximize, and close buttons for a custom title bar.

Basically, I have a React component WindowControlButton.tsx which should run a function to close/min/max the window when clicked. I haven't been able to implement a function that bridges electron and react so that the window is actually closed, though.

In electron's main.js file I have the following:

webPreferences: {
    preload: path.join(__dirname, 'preload.js'),
    nodeIntegration: true,
    enableRemoteModule: true,
    contextIsolation: false,
}

And in preload.js:

contextBridge.exposeInMainWorld('windowControlAPI', {

  minimizeApp: () => { ipcRenderer.send('minimize') },
  maximizeApp: () => { ipcRenderer.send('maximize') },
  closeApp:    () => { ipcRenderer.send('close') }

});

Then, back in main.js:

ipcMain.on('close', () => { win.close() });

ipcMain.on('minimize', () => { win.minimize() });

ipcMain.on('maximize', () => {
    if (win.isMaximized()) win.unmaximize()
    else win.maximize()
});

Finally, in WindowControlButton.tsx I have:

declare global {
    interface Window {
        windowControlAPI: {
            minimizeApp: () => void,
            maximizeApp: () => void,
            closeApp: () => void
        };
    }
}

// These are kind of just to show how I'm trying to use the functions I've defined above
const closeApp = () => { window.windowControlAPI.closeApp() }
const minimizeApp = () => { window.windowControlAPI.minimizeApp() }
const maximizeApp = () => { window.windowControlAPI.maximizeApp() }

Note: Without the declare global block Typescript throws an error saying windowControlAPI does not exist. Currently, the project compiles and displays fine, but clicking the buttons throws Cannot read properties of undefined (reading 'closeApp') (I'm guessing it can't find closeApp() on window.windowControlAPI. Can anyone suggest either a better way to do this (I've tried a lot of different solutions so it might look like a ton of stuff mashed together right now) or why my React component can't seem to connect to the electron source?

Thanks :)


Solution

  • Cannot read properties of undefined (reading 'closeApp')

    Means window.windowControlAPI is undefined.

    Is your preload file really loaded?

    Ex. Do you have the correct path to your preload file?

    Hope this helps!