github maizzle/framework v4.4.0-beta.1

latest releases: v5.0.0-beta.26, v5.0.0-beta.25, v5.0.0-beta.24...
pre-release23 months ago

Maizzle v4.4.0-beta.1

This release adds Laravel Blade-like components to Maizzle.

We're currently testing this in beta, so if you want to try it out in an existing project do a clean install of Maizzle from the next tag:

  1. delete your node_modules and package-lock.json

  2. update package.json:

    -	"@maizzle/framework": "latest",
    +	"@maizzle/framework": "next",
  3. run npm install

For new projects, scaffold using the next branch of the official Starter:

npx degit maizzle/maizzle#next my-project

Configuration

Components are still configured via your build.components config key.

Until we get a proper guide to configuring the new components, please have a look at the posthtml-component options.

For reference, these are the defaults that Maizzle uses:

{
  root: build.components.root || './',
  folders: ['src/components', 'src/layouts', 'src/templates'],
  tag: 'component',
  attribute: 'src',
  yield: 'content',
  propsAttribute: 'locals',
}

Using the new syntax

The syntax is similar to Laravel Blade, where the component tag name is based on the component's file name or path (dot syntax).

By default, Maizzle is configured to look for components in the following folders in your project:

  • src/components
  • src/layouts
  • src/templates

This makes it easy to use the new components even for layouts.

For a basic example, create src/components/sample.html:

Hello, <content></content>

You can use it like this:

<x-sample>world!</x-sample>

Result:

Hello, world!

Nested path syntax

You may reference components inside a folder like in Blade, through dot notation.

Let's say you have the following components:

  • src/components/footer/index.html
  • src/components/footer/legal.html

You can use dot notation like so:

<x-footer:index>Footer</x-footer:index>
<!-- you can also omit the `:index` part if the file is index.html -->
<x-footer>Footer</x-footer>

<x-footer:legal>Legal Footer</x-footer:legal>

Slots

You may define slots and fill them with content like so:

<slot:header></slot:header>
Hello, <content></content>

You can use it like this:

<x-sample>
  <fill:header>
    👋
  </fill:header>
world!
</x-sample>

Result:

👋
Hello, world!

This means you can replace the old way of extending layouts and only use components everywhere:

src/layouts/main.html:

- <block name="template></block>
+ <fill:template></fill:template>

src/templates/example.html:

- <extends src="src/layouts/main.html">
- 	<block name="template></block>
- </extends>
+ <x-main>
+ 	<fill:template></fill:template>
+ </x-main>

Stacks

You may push content to named stacks and render them in a different place:

<!-- src/layouts/main.html -->
<html>
<head>
  <stack name="head"></stack>
</head>
<body>
  <fill:template></fill:template>
</body>
</html>

Then, in a component:

<!-- src/components/sample.html -->
<push name="head">
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400&&family=Raleway:wght@400&display=swap" rel="stylesheet" media="screen">
</push>

The contents of the <push> tag will replace <stack name="head">.

Props

You can pass props to a component through attributes.

Define the props that the component accepts in a <script props> tag like so:

<!-- src/components/sample.html -->
<script props>
  module.exports = {
    text: props.text || 'Default text'
  }
</script>
<div>
  {{ text }}
</div>

You can then pass the prop to the component:

<x-sample text="Hello world!"></x-sample>

Result:

<div>
  Hello world!
</div>

Important: if you don't setup the props that the component accepts, any attributes you add to the component will also be added to the first HTML node inside it. This is how frontend frameworks work too.

Passing locals

If you need to pass a JSON string, use the locals attribute (configurable):

<x-sample locals='{"text": "Hello world"}'></x-sample>

Make sure that the value is a valid JSON string.

Component nesting and aware props

Similar to Laravel Blade, props passed to a parent component will not be available by default to any child components.

To achieve this, pass the prop by prefixing it with the aware: keyword.

Consider these parent/child components:

<!-- src/components/parent.html -->
<script props>
  module.exports = {
    text: props.text || 'Default text'
  }
</script>
<div>
  Prop in parent: {{ text }}
  <x-child></x-child>
</div>
<!-- src/components/child.html -->
<script props>
  module.exports = {
    text: props.text|| 'Default text'
  }
</script>
<div>
  Prop in child: {{ text }}
</div>

To make text available to <x-child>, you'd pass it like so:

<x-parent aware:text="Hello world!"></x-parent>

Attributes

Any attributes that you pass to a component will be added to the first node:

<!-- src/components/sample.html -->
<div class="font-bold">
  <content></content>
</div>
<x-sample class="text-base" data-id="1">Test</x-sample>

Result:

<div class="font-bold text-base" data-id="1">
  Test
</div>

class and style attributes will be merged with existing ones, unles you override them with the override: prefix:

<x-sample override:class="text-base" data-id="1">Test</x-sample>

Result:

<div class="text-base" data-id="1">
  Test
</div>

You may also change the root element that attributes are added to in a component, through the attributes attribute:

<!-- src/components/sample.html -->
<main class="font-bold">
  <div attributes>
    <content></content>
  </div>
</main>
<x-sample data-id="1">Test</x-sample>

Result:

<main class="font-bold">
  <div data-id="1">
    Test
  </div>
</main>

Backwards compatibility

The new components system is backwards-compatible with the previous one, so you can still write components as:

<component src="src/components/example.html">
  This text will replace the `<content>` tag in the Component.
</component>

Components as layouts

Components can now also be used as a replacement for the existing layout/template templating relationship.

The old <extends> / <block> syntax can still be used, but will very likely be removed in Maizzle 5.

Commits

  • Merge pull request #843 from maizzle/refactor-components d0be315
  • test: add new components test def5611
  • fix: user defined components options b67cebe
  • refactor: components 6b60126

v4.3.1...v4.4.0-beta.1

Don't miss a new framework release

NewReleases is sending notifications on new releases.