TauriのDialogを試してみる
Tags: tauri, typescript
Published: 2022-04-08 12:49:08

## Tauri Dialog API
TauriでDialogは以下の５種類を提供している
* [ask](https://tauri.studio/docs/api/js/modules/dialog#ask)
* [confirm](https://tauri.studio/docs/api/js/modules/dialog#confirm)
* [message](https://tauri.studio/docs/api/js/modules/dialog#message)
* [open](https://tauri.studio/docs/api/js/modules/dialog#open)
* [save](https://tauri.studio/docs/api/js/modules/dialog#save)

使いたい機能は `src-tauri/tauri.config.json` の `allowlist` に機能を許可する設定が必要。


## Ask Dialog
"Yes", "No" ボタンがあるDialog
![Ask Dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rlu693iz26nriayelhdq.png)

* `src-tauri/tauri.conf.json`に機能許可
```diff
{
  "tauri": {
    "allowlist": {
      "dialog": {
+       "ask": true
      }
    }
  }
}
```

* `main.ts`
```ts
import { dialog } from "@tauri-apps/api";

const result = await dialog.ask('Are you sure?', 'Ask Dialog');
if (result) { // yes
  ...
} else { // no
  ...
}
```

## Confirm Dialog
Ask Dialogとほぼ同じだが、ボタンが”OK","Cancel"になっているのが異なる。
![Confirm Dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9vppcvl9itvetrlbzxz.png)

* `src-tauri/tauri.conf.json`に機能許可
```diff
{
  "tauri": {
    "allowlist": {
      "dialog": {
+       "confirm": true
      }
    }
  }
}
```

* `main.ts`
```ts
import { dialog } from "@tauri-apps/api";

const result = await dialog.confirm('Are you sure?', 'Confirm Dialog');
if (result) { // ok
  ...
} else { // cancel
  ...
}
```

## Message Dialog
"OK"ボタンのみあるDialog
![Message Dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ixtoxnrgo6dy3y25sqwd.png)

* `src-tauri/tauri.conf.json`に機能許可
```diff
{
  "tauri": {
    "allowlist": {
      "dialog": {
+       "message": true
      }
    }
  }
}
```

* `main.ts`
```ts
import { dialog } from "@tauri-apps/api";

await dialog.message('This is a message dialog.');
```

## Open Dialog
FileやDirectory選択するDialog
![Open Dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w8sblncot4pmpkujviqt.png)

* OpenDialogOptions
  * https://tauri.studio/docs/api/js/interfaces/dialog.opendialogoptions/
  * 色んなOptionがあり、File選択なのかDirectory選択なのか、複数選択可能なのかやFilterなどが設定できる。

* `src-tauri/tauri.conf.json`に機能許可
```diff
{
  "tauri": {
    "allowlist": {
      "dialog": {
+       "open": true
      }
    }
  }
}
```

* `main.ts`
```ts
import { dialog } from "@tauri-apps/api";

const options: dialog.OpenDialogOptions = {
  filters: [
    {
      extensions: ["png", "jpeg"],
      name: "*",
    },
  ],
};

const result = await dialog.open(options);
if (Array.isArray(result)) { // string[]
  ...
} else if (result !== null) { // string
  ...
} else { // cancel
  ...
}
```

## Save Dialog
File保存先を選択するDialog
![Save Dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n3co41qu50c0ns2rf8o9.png)

* SaveDialogOptions
  * https://tauri.studio/docs/api/js/interfaces/dialog.savedialogoptions/

* `src-tauri/tauri.conf.json`に機能許可
```diff
{
  "tauri": {
    "allowlist": {
      "dialog": {
+       "save": true
      }
    }
  }
}
```

* `main.ts`
```ts
import { dialog } from "@tauri-apps/api";

const options: dialog.SaveDialogOptions = {
  title: 'Save Dialog Demo'
};

const result = await dialog.save(options);
if (result) { // path
  ...
} else { // cancel
  ...
}
```

## Demo Repository & Environment
1. Repository : https://github.com/dannygim/tauri-demo/tree/main/dialog-demo
2. Tauri info

```sh
% npx tauri info

Environment
  › OS: Mac OS 12.3.1 X64
  › Node.js: 17.8.0
  › npm: 8.5.5
  › pnpm: Not installed!
  › yarn: Not installed!
  › rustup: Not installed!
  › rustc: 1.59.0
  › cargo: 1.59.0
  › Rust toolchain: 

Packages
  › @tauri-apps/cli [NPM]: 1.0.0-rc.7(outdated, latest: 1.0.0-rc.8)
  › @tauri-apps/api [NPM]: 1.0.0-rc.3(outdated, latest: 1.0.0-rc.3)
  › tauri [RUST]: 1.0.0-rc.6,
  › tauri-build [RUST]: 1.0.0-rc.5,
  › tao [RUST]: 0.7.0,
  › wry [RUST]: 0.14.0,

App
  › build-type: bundle
  › CSP: unset
  › distDir: ../public
  › devPath: http://localhost:8080/
  › bundler: Rollup

App directory structure
  ├─ node_modules
  ├─ public
  ├─ src-tauri
  └─ src
```