Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

adonisjs-livewire

kabbouchi499MIT0.15.0TypeScript support: included

A front-end framework for AdonisJS

adonisjs, livewire, components

readme

AdonisJS Livewire (WIP)

A front-end framework for AdonisJS

Demo

https://pingcrm.kabbouchi.com/ - https://github.com/KABBOUCHI/adonisjs-livewire-pingcrm

Getting Started

This package is available in the npm registry.

npm install adonisjs-livewire

Next, configure the package by running the following command.

node ace configure adonisjs-livewire

Configuration

Enable ALS in config/app.ts https://docs.adonisjs.com/guides/async-local-storage#usage

// config/app.ts
export const http: ServerConfig = {
  useAsyncLocalStorage: true,
}

now you can use this.ctx in your Livewire components.

Create a Livewire component

node ace make:livewire Counter

# or

node ace make:livewire Counter --inline

Basic Usage

// views/welcome.edge
<!DOCTYPE html>
<html lang="en">
<head>
  @livewireStyles
</head>
<body>
  @livewire('counter') or  @livewire('Counter') or <livewire:counter />
  @livewire('search-users') or  @livewire('SearchUsers') or <livewire:search-users />

  @livewireScripts
</body>
</html>

Component as Page

Create layout file

node ace livewire:layout
node ace livewire:layout <name>

Add routes

// start/routes.ts

router.livewire('/', 'counter') // app/livewire/counter.ts
router.livewire('/', 'counter', { initialCounter: 10 })
router.livewire('/search-users', 'search-users') // app/livewire/search-users.ts
router.livewire('/search-users') // app/livewire/search-users.ts
router.livewire('/search-users', 'search-users.index') // app/livewire/search-users/index.ts

Registering Custom Components

You may manually register components using the Livewire::component method. This can be useful if you want to provide Livewire components from a composer package. Typically this should be done in the ready method of a service provider.

import type { ApplicationService } from '@adonisjs/core/types'
import { Component } from 'adonisjs-livewire'

export default class AppProvider {
  constructor(protected app: ApplicationService) {}

  public async ready() {
    const Livewire = await this.app.container.make('livewire')

    Livewire.component(
      'custom-component',
      class extends Component {
        public title = ''

        public mount({ title }) {
          this.title = title
        }

        async render() {
          return '<div>{{ title }}</div>'
        }
      }
    )
  }
}

Now, applications with your package installed can consume your component in their views like so:

@livewire('custom-component', {
  title: 'My Component'
})

// or

<livewire:custom-component title="My Component" />

Creating mixins

// app/livewire_mixins/my_mixin.ts
import { Component } from 'adonisjs-livewire'
export interface MyMixin extends Component {}
export class MyMixin {
  public foo = 'bar'

  public baz() {
    return 'baz'
  }
}

// or (not recommended)

export class MyMixin extends Component {
  public foo = 'bar'

  public baz() {
    return 'baz'
  }
}
// app/livewire/counter.ts
import { Component, Mixin } from 'adonisjs-livewire'
import MyMixin from '#app/livewire_mixins/my_mixin'

export default class Counter extends Mixin(Component, MyMixin) {
  public count = 0

  public increment() {
    this.count++
  }

  public decrement() {
    this.count--
  }

  public render() {
    return `
      <div>
        <button wire:click="increment">+</button>
        <h1>{{ count }}</h1>
        <button wire:click="decrement">-</button>
        <h2>{{ foo }}</h2>
        <h3>{{ baz() }}</h3>
      </div>
    `
  }
}

SFC (Experimental)

Define component logic using <script server> tag inside livewire edge component. e.g: resources/views/livewire/counter.edge

<script server>
  import { Component } from 'adonisjs-livewire'

  export default class extends Component {
    count = 0

    increment() {
      this.count++
    }

    decrement() {
      this.count--
    }
  }
</script>

<div>
  <button wire:click="decrement">-</button>

  <h1>{{ count }}</h1>

  <button wire:click="increment">+</button>
</div>

Helpers

Edge tag compiler (Experimental)

This package includes Edge tags support via edge-tags.

<x-button class="bg-red" a="b" :foo="bar" baz="{{ 1 + 2 }}">
  Hello
</x-button>

will be compiled to

@component('button or components/button or components/button/index', { class: 'bg-red', a: 'b', foo: bar, baz: `${1 + 2}` })
  Hello
@end

Edge component class (Experimental)

// app/compoments/button.ts
import { ViewComponent } from 'adonisjs-livewire'

export default class Button extends ViewComponent {
  type = 'button'
  text = ''

  constructor({ type, text }) {
    this.type = type || this.type
    this.text = text || this.text
  }

  isLoading() {
    return true // some logic
  }

  public render() {
    // or return this.view.render("components/button")
    return `
      <button type="{{ type }}" {{ isLoading() ? 'data-loading': '' }} {{ $props.only(['class']).toAttrs() }}>
        {{{ text || await $slots.main() }}}
      </button>
    `
  }
}