目的

LWC のlightning-quick-action-panelモーダル画面の幅を調整できないため、
今回 Aura と LWC でのアクションボタンが表示したモーダル画面の高さと幅を調整できる方法を共有します。
(※ExC 側も適用)

実装

  • Aura コンポーネント
    image.png

AuraActionCont(基底 Aura コンポーネント)

<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId,force:hasSObjectName"
  access="global" extensible="true">
  <aura:html tag="style">
    <!-- アクションモダール -->
    .slds-modal__container {
      margin: 0 auto !important;
      width: 70% !important;
      max-width: 75rem !important;
      min-width: 40rem !important;
    }
    .slds-p-around--medium {
      padding: 0 !important;
      height: fit-content !important;
      min-height: none !important;
      max-height: none !important;
    }
    .cuf-content {
      padding: 0 !important;
    }
  </aura:html>
  <!-- LWCコンポーネント名 -->
  <aura:attribute name="lwcName" type="String" default="" />
  <!-- ロード中 -->
  <aura:attribute name="isLoading" type="Boolean" default="true" />
  <!-- 初期化 -->
  <aura:handler name="init" value="{!this}" action="{!c.onInit}" />
  <div>
    <!-- LWC差し込む場所 -->
    {!v.body}
    <aura:if isTrue="{!v.isLoading}">
      <lightning:spinner alternativeText="Loading..." />
    </aura:if>
  </div>
</aura:component>
<?xml version="1.0" encoding="UTF-8"?>
<AuraDefinitionBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <description>A Lightning Component Bundle</description>
</AuraDefinitionBundle>
.THIS {
  position: relative;
}

.THIS .slds-spinner {
  position: sticky;
}
({
  /**
   * 初期化
   * @param {*} component コンポーネント
   * @param {*} event イベント
   * @param {*} helper ヘルパー
   */
    onInit: function (component, event, helper) {
      helper.init(component, event);
    },
    /**
     * Auraイベント
     * @param {*} component コンポーネント
     * @param {*} event イベント
     * @param {*} helper ヘルパー
     */
    onAuraEvent: function (component, event, helper) {
      helper.fireAuraEvent(event.getParam("name"), event.getParam("params"));
    },
    /**
     * ロードフラグ設定
     * @param {*} component コンポーネント
     * @param {*} event イベント
     * @param {*} helper ヘルパー
     */
    onSetLoading: function (component, event, helper) {
      helper.setLoading(component, event.getParam("isLoading"));
    },
    /**
     * QuickActionを閉じる
     */
    closeAction: function () {
      $A.get("e.force:closeQuickAction").fire();
    }
  });
({
    /**
     * 初期化
     * @param {*} component
     */
    init: function(component) {
        var lwcName = component.get('v.lwcName');
        this.createComponent(component, lwcName);
    },

    /**
     * LWCコンポーネント作成
     * @param {*} component
     * @param {*} lwcName LWCコンポーネント名
     */
    createComponent: function(component, lwcName) {
        const recordId = component.get("v.recordId");
        const sObjectName = component.get("v.sObjectName");
        $A.createComponent(
            `c:${lwcName}`, {
                recordId: recordId,
                sObjectName: sObjectName,
                onauraevent: component.getReference("c.onAuraEvent"),
                onsetloading: component.getReference("c.onSetLoading")
            },
            (lwcCmp, status, errorMessage) => {
                if (status === "SUCCESS") {
                    const body = component.get("v.body");
                    body.push(lwcCmp);
                    component.set("v.body", body);
                } else {
                    this.displayError(
                        `The '${lwcName}' can't be find. Check if it's exposed. More details in DevTools.`,
                        errorMessage
                    );
                    $A.enqueueAction(component.get("c.closeAction"));
                }
            }
        );
    },

    /**
     * Auraイベント
     * @param {*} name イベント名
     * @param {*} params パラメータ
     */
    fireAuraEvent: function(name, params) {
        const event = $A.get(name);
        if (params) event.setParams(params);
        event.fire();
    },

    /**
     * ロードフラグ設定
     * @param {*} component
     * @param {*} loading ロードフラグ
     */
    setLoading: function(component, loading) {
        component.set("v.isLoading", loading);
    },

    /**
     * Toastエラーメッセージ表示
     * @param {*} message メッセージ
     * @param {*} errorMessage エラーメッセージ
     */
    displayError: function(message, errorMessage) {
        console.error("Error: ", errorMessage);
        this.showToast(message, "error");
    },

    /**
     * Toastメッセージ表示
     * @param {*} message メッセージ
     * @param {*} type タイプ
     */
    showToast: function(message, type) {
        const toast = $A.get("e.force:showToast");
        toast.setParams({
            message: message,
            type: type
        });
        toast.fire();
    }
});

DeleteCont(LWC の容器)

<!-- 基底AuraActionContを継承する -->
<aura:component extends="c:AuraActionCont">
    <aura:html tag="style">
        <!-- アクションモダール -->
        .slds-modal__container {
          margin: 0 auto !important;
          width: 50% !important;
          max-width: 75rem !important;
          min-width: 40rem !important;
        }
        .slds-p-around--medium {
          padding: 0 !important;
          height: fit-content !important;
          min-height: none !important;
          max-height: none !important;
        }
        .cuf-content {
          padding: 0 !important;
        }
      </aura:html>
    <!-- LWCのコンポーネント名を指定する -->
    <aura:attribute name="lwcName" type="String" default="deleteButton" />
</aura:component>
<?xml version="1.0" encoding="UTF-8"?>
<AuraDefinitionBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <description>A Lightning Component Bundle</description>
</AuraDefinitionBundle>
  • LWC コンポーネント
    lwcAction(基底コンポーネント)
    image.png
import { LightningElement, api } from "lwc";
export default class LwcAction extends LightningElement {
    //レコードId
    @api recordId;
    //オブジェクト名
    @api sObjectName;

    //準備完了フラグ
    isReady = false;

    /**
     * ロード完了
     */
    ready() {
        this.hideSpinner();
        this.isReady = true;
    }

    /**
     * QuickActionを閉じる
     */
    closeAction() {
        this.dispatchEvent(LwcAction.getCloseQuickAction());
    }

    /**
     * 画面リフレッシュ
     */
    refreshView() {
        this.dispatchEvent(LwcAction.getRefreshView());
    }

    /**
     * ロード表示
     */
    showSpinner() {
        this.dispatchEvent(LwcAction.getSpinnerEvent(true));
    }

    /**
     * ロール非表示
     */
    hideSpinner() {
        this.dispatchEvent(LwcAction.getSpinnerEvent(false));
    }

    /**
     * Auraイベント
     * @param {*} name イベント名
     * @param {*} params パラメータ
     */
    fireAuraEvent(name, params) {
        this.dispatchEvent(LwcAction.getAuraEvent(name, params));
    }

    /**
     * 静的メソッド
     * QuickActionを閉じる
     * @param {*} element
     */
    static fireCloseAction(element) {
        element.dispatchEvent(LwcAction.getCloseQuickAction());
    }

    /**
     * 静的メソッド
     * 画面リフレッシュ
     * @param {*} element
     */
    static fireRefreshView(element) {
        element.dispatchEvent(LwcAction.getRefreshView());
    }

    /**
     * 静的メソッド
     * ロード表示
     * @param {*} element
     */
    static fireShowSpinner(element) {
        element.dispatchEvent(LwcAction.getSpinnerEvent(true));
    }

    /**
     * 静的メソッド
     * ロード非表示
     * @param {*} element
     */
    static fireHideSpinner(element) {
        element.dispatchEvent(LwcAction.getSpinnerEvent(false));
    }

    /**
     * 静的メソッド
     * Auraイベント
     * @param {*} element
     * @param {*} name
     * @param {*} params
     */
    static fireAuraEvent(element, name, params) {
        element.dispatchEvent(LwcAction.getAuraEvent(name, params));
    }

    /**
     * 静的メソッド
     * ロード制御
     * @param {*} isLoading
     * @returns
     */
    static getSpinnerEvent(isLoading) {
        return new CustomEvent("setloading", {
            detail: { isLoading: isLoading },
            composed: true,
            bubbles: true,
        });
    }

    /**
     * QuickActionを閉じる
     */
    static getCloseQuickAction() {
        return LwcAction.getAuraEvent("e.force:closeQuickAction");
    }

    /**
     * 静的メソッド
     * 画面リフレッシュ
     */
    static getRefreshView() {
        return LwcAction.getAuraEvent("e.force:refreshView");
    }

    /**
     * Auraイベント
     * @param {*} name 名
     * @param {*} params パラメータ
     * @returns
     */
    static getAuraEvent(name, params) {
        return new CustomEvent("auraevent", {
            detail: { name: name, params: params },
            composed: true,
            bubbles: true,
        });
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <isExposed>true</isExposed>
</LightningComponentBundle>

deleteButton
image.png

<template>
    <lightning-quick-action-panel header="メッセージ">
        メッセージ
        <div slot="footer">
            <lightning-button variant="neutral" label="いいえ" onclick={cancel}></lightning-button>
            <lightning-button variant="brand" label="はい" class="slds-m-left_x-small" onclick={confirm}>
            </lightning-button>
        </div>
    </lightning-quick-action-panel>
</template>
import LwcAction from "c/lwcAction";

export default class DeleteButton extends LwcAction {

    /**
     *  「はい」
     */
     async confirm(e) {
        try {
           //はいの処理TODO
        } catch (error) {
           console.error(error);
        } finally {
            this.closeAction();
        }
    }

    /**
     * 「いええ」
     */
    cancel(e) {
        e.preventDefault();
        this.closeAction();
    }


    /**
     * 初期化処理
     */
     connectedCallback() {
        this.ready();
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>

アクションボタン作成

該当オブジェクトのボタン、リンク、およびアクションを選択
image.png
新規アクションを押下
image.png
アクション種別をLightningコンポーネントを選択し、Lightning コンポーネントをc:DeleteContを選択し、表示ラベルと名前を入力してから、保存ボタン押下
image.png

ページレイアウトの設定

該当オブジェクトのケース ページレイアウトを選択

image.png

モバイルおよび Lighting のアクションを選択し、削除(カスタム)をドラグ&ドロップで、Salesforce モバイルおよび Lightning Experience のアクションに設定して保存

image.png
image.png

動作確認

詳細画面でアクションボタンを確認
image.png
アクションボタンを押下
image.png

参考