Logo

dev-resources.site

for different kinds of informations.

8 Tips for Creating a Native Look and Feel in Tauri Applications

Published at
10/7/2022
Categories
tauri
rust
react
webview
Author
akr
Categories
4 categories in total
tauri
open
rust
open
react
open
webview
open
Author
3 person written this
akr
open
8 Tips for Creating a Native Look and Feel in Tauri Applications

I recently released Jomai, a Markdown-focused desktop search app made in Tauri.
Apps made with Tauri is, of course, native app. But its UI part runs on WebView, so its look and feel tend to be like a web app. I designed Jomai to behave as much as possible like a native app, so I will summarize that here.
Jomai is currently available only for macOS, so this article is also intended for macOS.

Environment:

  • Tauri: 1.1.1
  • Platform: macOS

Contents

Get rid of the beep sound on keystrokes for non-input fields

A beep sounds when keystrokes are made while the focus is on a non-input item other than <input> or <textarea>. This issue occurs in WebView on macOS and has a GitHub issue, which has not been resolved as of October 6, 2022.
https://github.com/tauri-apps/tauri/issues/2626

You can suppress the beep sound by calling preventDefault() on keydown event, but this will also disable all input to <input>, etc., so it is necessary to suppress it selectively.

Jomai uses the following code.

export const useKey = (callback: UseKeyCallback) => {
  const onKeydown = useCallback(
    (event: KeyboardEvent) => {
γ€€γ€€γ€€ // callback should return true if processed
      const consumed = callback(event.code, {
        ctrl: event.ctrlKey,
        shift: event.shiftKey,
      });

      const e = event.composedPath()[0];
      if (
        !(e instanceof HTMLInputElement || e instanceof HTMLAreaElement)
        || consumed
      ) {
        // preventDefault() if it is not an input item
        // also preventDefault() if it was handled by a callback
        applyBeepSoundWorkaround(event);
      }
    },
    [callback],
  );

  useEffect(() => {
    window.addEventListener('keydown', onKeydown);
    return () => {
      window.removeEventListener('keydown', onKeydown);
    };
  }, [onKeydown]);
};
Enter fullscreen mode Exit fullscreen mode

It solves most cases of the problem to call preventDefault() if the event source is not an HTMLInputElement or HTMLAreaEelement. However, when the focus is on one of these input items and the keyboard shortcut is used to move the focus to a non-input item (yes, it isn't very easy), there will be the sound. So I've done more to fix the problem.

Make text in UI not selectable

While it is normal to be able to select text on a web page, this is generally not the case in native apps. To avoid unintentional text selection when trying to manipulate the UI, use user-select: none at the base of DOM elements such as <body>.

body {
  user-select: none;
}
Enter fullscreen mode Exit fullscreen mode

Set mouse cursor to default

Since the previous section has limited the operation of UI elements to button pressing, etc., let's express it that way for the mouse cursor as well.

body {
  cursor: default;
}
Enter fullscreen mode Exit fullscreen mode

cursor: default prevents I-beam when hovering text, for example. The cursor attribute should be explicitly specified if the UI element is manipulatable, such as a button.

button {
  cursor: pointer;
}
Enter fullscreen mode Exit fullscreen mode

Do not scroll the entire screen

When content is larger than the size of the screen, it's usual for web pages to scroll the entire screen. In native apps, it is natural to display fixed UI components and make only some scrollable.

In Jomai, tabs and forms at the top of the screen are always visible, and only the content part at the bottom is scrollable.

scrollable and non-scarollable areas in the app
See it in action.

only contents area is scrollable

To achieve this, set overflow: hidden for the entire screen, and set overflow: scroll and height for the scrollable area.

.page {
  overflow: hidden;
}

.contents {
  overflow: scroll;
  height: calc(100vh - 40px)
}
Enter fullscreen mode Exit fullscreen mode

Suppress bounce scrolling across the screen

Bounce scrolling is that thing that makes a spring-like motion when scrolling to the edge of the screen. By default, the entire screen is scrollable with the bounce motion. See this video.

bounce scroll

Bounce scrolling is associated with scrollability, so it should be suppressed if the entire screen should not be scrollable.

body {
  overflow: hidden;
}
Enter fullscreen mode Exit fullscreen mode

Prepare your own menu

Tauri provides a basic menu by default.

default menus

If you need customization, you will need to build these menus yourself, which is a bit tedious. See tauri::Menu::os_default for reference.

Prepare your own keyboard shortcuts

Be careful when using your own keyboard shortcuts on web pages, as they can confuse users, but be proactive about introducing them in native apps.

Support dark mode

I am a fan of dark mode and would like to see dark mode support in apps I use regularly.
Tauri has appWindow.theme() to get the current theme and appWindow.onThemeChanged() to monitor change events. Using these, you can change the app to match the OS theme settings.

Here is an example implementation in React.

import { appWindow, Theme } from '@tauri-apps/api/window';

export const useTheme = () => {
  const [theme, setTheme] = useState<'light' | 'dark'>('light');

  useEffect(() => {
    let unlisten: UnlistenFn | undefined;

    (async () => {
      setTheme(await appWindow.theme());

      unlisten = await appWindow.onThemeChanged(({ payload: theme }) => {
        console.log(`theme changed to ${theme}`);
        setTheme(theme);
      });
    })();

    return () => {
      if (unlisten != null) {
        unlisten();
      }
    };
  }, []);

  return theme;
};
Enter fullscreen mode Exit fullscreen mode

Summary

In this article, I have introduced some tips to make Tauri-made apps more native-like. A little effort will improve the usability of your apps. I hope you find them helpful.

Overall, developing with Tauri has been a great experience, and I look forward to creating many more apps with Tauri.

Please also check out Jomai, which I'm developing using these techniques.

webview Article's
30 articles in total
Favicon
A New Era of Cross-Platform Desktop Application Development in Go Language: A Comprehensive Analysis of LCL, CEF, and Webview
Favicon
Building Document PDF Scanner for Windows, Android and iOS with .NET MAUI Blazor
Favicon
Webview em QML (Qt Modeling Language)
Favicon
Switching from .NET MAUI Blazor to WebView Control for Document Scanning
Favicon
Developing a Desktop Document Scanner Application with .NET MAUI Blazor
Favicon
Is there any fix in react native which I can apply for upi payment using react-native-webview?
Favicon
Notification List - inbox list Webview
Favicon
Android WebView: Handle special Intent URI requests
Favicon
Chrome extensions in WebView2, CefSharp, and DotNetBrowser
Favicon
It is possible to build a full-featured browser using react-native.
Favicon
React Native WebView: Make Android pullToRefresh work without any glitches
Favicon
8 Tips for Creating a Native Look and Feel in Tauri Applications
Favicon
How to Add CanvasJS Charts to your Android App?
Favicon
WebView Callback response in Flutter
Favicon
What is a WebView And How To Test It?
Favicon
Aplikasi WebView Pro (Convert Web ke Apk)
Favicon
Creating a GO GUI with Alpine.js and Webview
Favicon
WKWebView persistent cookies open source solution and other useful things for WKWebView
Favicon
Download PDF files to device storage with React Native Webview
Favicon
Fix: physical keyboard can't type in Flutter's Webview
Favicon
ERR_CLEARTEXT_NOT_PERMITTED from Android WebView
Favicon
Append a new User-Agent to WebView in Android
Favicon
Which Embed Browser engine to use?
Favicon
Interaction between Vue JS Webview and native Apps
Favicon
Flutter둜 μ›Ήμ•± λ§Œλ“€λ©° μ§„ν–‰ν–ˆλ˜ 정리 (1)
Favicon
Generate Right Big Arrow 👲 with CSS for Local Webview
Favicon
VsCode extension using webview and message posting
Favicon
React Native WebView debugging
Favicon
Proton Native
Favicon
WebView Apps on your OS

Featured ones: