Home

Awesome

inertia-can

The CanJS adapter for inertia.js

Introduction:

Before using this library, is important to know what is Inertia.js, what is it for and how it works, in the official Inertia.js website

Also, from the official CanJS website, is very important to know:

Installation:

Install inertiajs and canjs adapter using npm or yarn:

$ npm install @inertiajs/inertia can inertia-can
$ yarn add @inertiajs/inertia can inertia-can

Application initialization:

inertia-app is a StacheElement custom element, needs to be intialized in the main js file of the application like the following:

import { InertiaApp } from "inertia-can";

const app = new InertiaApp().initialize({
  initialpage: json.parse(target.dataset.page),
  resolvecomponent: (name) =>
    import(`./pages/${name}`).then((module) => module.default),
});

let target = document.getElementById("app");
app.initialize({ target });
target.appendChild(app);

The code above will instantiated inertia-app custom and inserted it in the application root view html page.

A async/await polyfill like regenerator-runtime might be needed.

note: it is important to not instantiate the returned module in resolvecomponent function, the adapter will handle the instantiation and passing the needed StacheElement instance properties.

Pages:

Pages are just StacheElement custom tags, for example:

import { StacheElement } from 'can';

export default class Dashboard extends StacheElement {
    static view = `<h1>Dashboard</h1>`

}

customElements.define('app-dashboard', Dashboard);

Persistent layouts:

The example of the <app-dashboard /> page above will have its own local layout, this is not useful when some pages has shared layout. to make a presistent layout:

1- Define a layout custom element:

import { StacheElement } from "can";
import { store } from 'inertia-can';

class Layout extends StacheElement {
  static view = `
        {{# portal(head)}}
            <title>
                {{# if (this.title) }}
                    {{ this.title }} - my app
                {{ else }}
                    my app
                {{/ if }}
            </title>
        {{/ portal }}

        <app-navbar />

        <app-side-menu />

        {{ this.component }}
    `;

  static props = {
    head: {
      get default() {
        return document.head;
      },
    },
  };

  get title() {
    return this.component.title;
  }

  get component() {
    return store.component;
  }
}
customElements.define("app-layout", layout);

export default new Layout();

The above example assume there's a <app-navbar /> and <app-side-menu /> already defined and imported.

Notice CanJS portal feature is used to change the HTML document title inside the head tag.

The store an observable object where the application state defined, it contains the following with the default values:

{   
    component: null,
    page: {},
    key: null
}

NOTE: It is important to export an instance of the layout custom element, like this the layout will not be instantiated on every page change.

2- Define a page custom element, so the example of <app-dashboard /> will be:

import { StacheElement } from 'can';
import { default as layout } from '@/components/layout/layout';

export default class Dashboard extends StacheElement {

    static view = `
        <h1> {{ this.title }} </h1>
    `

    get layout() {
        return layout;
    }

    get  title() {
        return 'Tableau de bord';
    }

}

customElements.define('app-dashboard', Dashboard);

Links:

Links are created using <inertia-link> custom element:

import { StacheElement } from 'can';
import { Link } from 'inertia-can';

class MyPage extends satcheElement {
    static view = `
        <inertia-can href:raw='https://canjs.com/'>
            <can-template name="linkTemplate">
                canjs website
            </can-template>
        </inertia-can>
    `
}

customElements.define('my-page', Mypage);

Notice the can-template tag is used to passe custom templates to StacheElement.

The following properties are available for inertia-link:

data: type: deepobserble, required: false

href: type: string

method: type: string, default: 'get' (post, get, put, patch, delete)

replace: type: boolean, default: false

preserveScroll: type: boolean, defaut: false

preserveState: type: boolean, default: false

only: type:(deepobservable), required: false

headers type: deepobservable, required: false

linkTemplate type: function, required: true

classname: type: string

basically, inertia-link is a wrapper around inertia link

License

MIT License.