[LWC] window.alert、window.confirm、window.promptの代替

Chromeなどのブラウザで、window.alert()、window.confirm()、window.prompt()のクロスオリジン使用のサポートが終了しました[^1]。代わりにSummer'22で追加された下記のLWCの標準モジュールを使用しましょう。

## window.alertの代替：LightningAlert
window.alertの代替として、LightningAlertが使用できます。ボタンはOKのみが表示されます。LightningAlertのopenメソッドはPromiseを返却します。

![LightningAlert01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/80afdf97-b921-5f6c-d0d7-1960a9fc4fb6.png)

```html:alertSample.html
<template>
  <lightning-button label="sample" onclick={handleAlertClick}></lightning-button>
</template>
```

```js:alertSample.js
import { LightningElement } from "lwc";
import LightningAlert from "lightning/alert";

export default class AlertSample extends LightningElement {
    async handleAlertClick() {
        await LightningAlert.open({
            label: 'サンプル',
            message: 'LightningAlertのサンプル', // 省略可能
            theme: 'default', // 省略可能
            variant: 'header' // デフォルトはheader。
        });
        // OK押した後の処理
    }
}
```

variantをheaderlessにするとヘッダーが表示されません。
テーマは下記が選択可能です。

- default： 白
- shade： グレー
- inverse： 濃紺
- alt-inverse：濃い青
- offline: 黒
- info：濃いグレー
- success： 緑
- error： 赤
- warning： 黄色

### バリエーション
![LightningAlert02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/10e379ea-110d-34c2-fb0f-13160be7c5c3.png)
![LightningAlert03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/2cbee277-99f9-fb80-ab5d-62dd393324bc.png)

## window.confirmの代替：LightningConfirm
window.confirmの代替として、LightningConfirmが使用できます。
OKボタンとキャンセルボタンが表示され、OKをクリックするとtrueで解決され、キャンセルをクリックするとfalseで解決されます。
カラーバリエーションはLightningAlertと同じです。

![LightningConfirm01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/a16a7886-38be-5b1f-6218-ef867d30e2b4.png)


```js:confirmSample.js
import { LightningElement } from "lwc";
import LightningConfirm from "lightning/confirm";

export default class ConfirmSample extends LightningElement {
    async handleConfirmClick() {
        /** @type {boolean} */
        const result = await LightningConfirm.open({
            label: 'サンプル',
            message: 'LightningConfirmのサンプル', // 省略可能
            theme: 'default', // 省略可能
            variant: 'header' // デフォルトはheader。
        });
    }
}
```

## window.promptの代替：LightningPrompt
window.promptの代替として、LightningPromptが使用できます。
テキストの入力欄、OKボタン、キャンセルボタンが表示されます。OKをクリックすると入力文字列で解決され（未入力の時は空文字列）、キャンセルをクリックするとnullで解決されます。
カラーバリエーションはLightningAlertと同じです。

![LightningPrompt01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/2e66c0c6-2239-69da-c988-72134d81191b.png)

```js:promptSample.js
import { LightningElement } from "lwc";
import LightningPrompt from "lightning/prompt";

export default class PromptSample extends LightningElement {
    async handlePromptClick() {
        /** @type {string?} */
        const result = await LightningPrompt.open({
            label: 'サンプル',
            message: 'LightningPromptのサンプル', // 省略可能
            theme: 'default', // 省略可能
            variant: 'header' // デフォルトはheader。
        });
    }
}
```

## 参考
- [新規アラート、確認、プロンプトモジュールを使用した通知の作成](https://help.salesforce.com/s/articleView?id=release-notes.rn_lc_alert_confirm_prompt.htm&release=238&type=5)
- [lightning-alert - documentation - Salesforce Lightning Component Library](https://developer.salesforce.com/docs/component-library/bundle/lightning-alert/documentation)
- [lightning-confirm - documentation - Salesforce Lightning Component Library](https://developer.salesforce.com/docs/component-library/bundle/lightning-confirm/documentation)
- [lightning-prompt - documentation - Salesforce Lightning Component Library](https://developer.salesforce.com/docs/component-library/bundle/lightning-prompt/documentation)


[^1]:https://chromestatus.com/feature/5148698084376576

<!--
```html:サンプル画像用
<template>
  <lightning-card>
    <ul>
      <li>
        <lightning-button
          label="alert default"
          onclick={handleAlertClick}
          class="slds-m-left_x-small"
          data-theme="default"
          data-title="LightningAlertサンプル"
          data-description="theme=defaultのサンプル"
        ></lightning-button>
      </li>
      <li>
        <lightning-button
          label="alert shade"
          onclick={handleAlertClick}
          class="slds-m-left_x-small"
          data-theme="shade"
          data-title="LightningAlertサンプル"
          data-description="theme=shadeのサンプル"
        ></lightning-button>
      </li>
      <li>
        <lightning-button
          label="alert inverse"
          onclick={handleAlertClick}
          class="slds-m-left_x-small"
          data-theme="inverse"
          data-title="LightningAlertサンプル"
          data-description="theme=inverseのサンプル"
        ></lightning-button>
      </li>
      <li>
        <lightning-button
          label="alert alt-inverse"
          onclick={handleAlertClick}
          class="slds-m-left_x-small"
          data-theme="alt-inverse"
          data-title="LightningAlertサンプル"
          data-description="theme=alt-inverseのサンプル"
        ></lightning-button>
      </li>
      <li>
        <lightning-button
          label="alert success"
          onclick={handleAlertClick}
          class="slds-m-left_x-small"
          data-theme="success"
          data-title="LightningAlertサンプル"
          data-description="theme=successのサンプル"
        ></lightning-button>
      </li>
      <li>
        <lightning-button
          label="alert info"
          onclick={handleAlertClick}
          class="slds-m-left_x-small"
          data-theme="info"
          data-title="LightningAlertサンプル"
          data-description="theme=infoのサンプル"
        ></lightning-button>
      </li>
      <li>
        <lightning-button
          label="alert warning"
          onclick={handleAlertClick}
          class="slds-m-left_x-small"
          data-theme="warning"
          data-title="LightningAlertサンプル"
          data-description="theme=warningのサンプル"
        ></lightning-button>
      </li>
      <li>
        <lightning-button
          label="alert error"
          onclick={handleAlertClick}
          class="slds-m-left_x-small"
          data-theme="error"
          data-title="LightningAlertサンプル"
          data-description="theme=errorのサンプル"
        ></lightning-button>
      </li>
      <li>
        <lightning-button
          label="alert offline"
          onclick={handleAlertClick}
          class="slds-m-left_x-small"
          data-theme="offline"
          data-title="LightningAlertサンプル"
          data-description="theme=offlineのサンプル"
        ></lightning-button>
      </li>
      <li>
        <lightning-button
          label="alert headerless"
          onclick={handleAlertClick}
          class="slds-m-left_x-small"
          data-variant="headerless"
          data-title="LightningAlertサンプル"
          data-description="variant=headerlessのサンプル"
        ></lightning-button>
      </li>
    </ul>
  </lightning-card>
</template>
```

```js:サンプル画像用
import { LightningElement } from "lwc";
import LightningAlert from "lightning/alert";

export default class Sample extends LightningElement {
    async handleAlertClick(event) {
        const isHeaderLess = event.target.dataset.variant === "headerless";
        const theme = event.target.dataset.theme ?? "default";
        const label = event.target.dataset.title;
        const message = event.target.dataset.description;

        await LightningAlert.open({
            message,
            theme,
            label,
            variant: isHeaderLess ? "headerless" : "header"
        });
    }
}
```
-->