User:Roan Kattouw (WMF)/Codex example gadget

From mediawiki.org

In MediaWiki:Gadgets-definition[edit]

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

MediaWiki:Gadget-codextest.js[edit]

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

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

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

module.exports = {
	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>
	`,
    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
        };
    }
};

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

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

module.exports = {
	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>
	`,
    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
        };
    }
};