User:Roan Kattouw (WMF)/Codex example gadget (assuming better Vue support in gadgets)

From mediawiki.org

In MediaWiki:Gadgets-definition[edit]

* codextest [ResourceLoader | package | default | dependencies=vue,@wikimedia/codex ] | codextest.js | codextest-main.vue | codextest-ChangeNameDialog.vue

MediaWiki:Gadget-codextest.js[edit]

const Main = require( './codextest-main.vue' );
$( '#bodyContent' ).prepend( '<div id="testgadget"></div>' );
Vue.createMwApp( Main ).mount( '#testgadget' );

MediaWiki:Gadget-codextest-main.vue[edit]

<template>
    <p class="testgadget-name">
        Hello [[:Template:DisplayName]]!
    </p>
    <cdx-button
        action="progressive"
        weight="primary"
        @click="dialogOpen = true"
    >
        Change your name
    </cdx-button>
    <change-name-dialog v-model:open="dialogOpen" @save-name="saveName"></change-name-dialog>
</template>

<script>
const { ref } = require( 'vue' );
const { CdxButton } = require( '@wikimedia/codex' );
const ChangeNameDialog = require( './codextest-ChangeNameDialog.vue' );

module.exports = {
    components: {
        CdxButton,
        ChangeNameDialog
    },
    setup() {
        const dialogOpen = ref( false );
        const displayName = ref( '(name unknown)' );

        function saveName( newName ) {
            displayName.value = newName;
            dialogOpen.value = false;
        }

        return {
            dialogOpen,
            displayName,
            saveName
        };
    }
};
</script>

<style>
.testgadget-name {
    font-style: italic;
}
</style>

MediaWiki:Gadget-codextest-ChangeNameDialog.vue[edit]

<template>
    <cdx-dialog
        v-model:open="wrappedOpen"
        title="Change name"
        close-button-label="Close"
        :primary-action="saveAction"
        @primary="saveName" 
    >
        <p>New name:</p>
        <cdx-text-input v-model="nameInput" placeholder="Choose a new name"></cdx-text-input>
    </cdx-dialog>
</template>

<script>
const { ref, computed, toRef } = require( 'vue' );
const { CdxDialog, CdxTextInput, useModelWrapper } = require( '@wikimedia/codex' );

module.exports = {
    components: {
        CdxDialog,
        CdxTextInput
    },
    props: {
        open: { type: Boolean, required: true }
    },
    emits: [
        'update:open',
        'save-name'
    ],
    setup( props, { emit } ) {
        const wrappedOpen = useModelWrapper( toRef( props, 'open' ), emit, 'update:open' );
        const nameInput = ref( '' );
        const saveAction = computed( () => ( {
            label: 'Save',
            actionType: 'progressive',
            disabled: nameInput.value === ''
        } ) );

        function saveName() {
            emit( 'save-name', nameInput.value );
        }

        return {
            wrappedOpen,
            nameInput,
            saveAction,
            saveName
        };
    }
};
</script>