General Component API

See below for an overview of the various possibilities Matestack provides for component implementation:

Response

Use the response method to define the UI of the component by using other components.

  class Some::Component < Matestack::Ui::Component

    def response
      div id: "my-component" do
        plain "hello world!"
      end
    end

  end
class ExamplePage < Matestack::Ui::Page

  def response
    div id: "div-on-page" do
      some_component
    end
  end

end

This is the HTML which gets created:

If no response method is defined, matestack will look for a corresponding HAML template file lying next to Ruby component file.

Prepare

Use a prepare method to resolve data before rendering a component!

This is the HTML which gets created:

The prepare method comes in handy to read from the database or to resolve content before displaying it!

Params access

A component can access request information, e.g. url query params, by calling the params method:

On the example page, reference the component as usual.

Now, visiting the respective route to the page, e.g. via /xyz?foo=bar, the component reads the [:foo] from the params and displays it like so:

Passing options to components

Define optional and required properties

Matestack components give you the option to define required and optional properties for a component. It creates helpers for these properties automatically.

Requires

Required properties are required for your component to work, like the name suggests. If at least one required property is missing a Matestack::Ui::Core::Properties::PropertyMissingException is raised.

Declare your required properties by calling requires as follows:

You then can use these properties simply by calling the provided helper method, which is generated for you. The helper method name corresponds to the passed property name.

Optional

To define optional attributes you can use the same syntax as requires. Just use optional instead of requires. Optional attributes are optional and not validated for presence like required attributes.

Passing properties to components

Pass the properties as a hash directly to the component when calling it. You can pass any object you like and use it in the component with the helper.

Use it in the example page and pass in the properties as a hash

The outcome is quite as expected:

Alias properties

Matestack tries to prevent overriding existing methods while creating helpers. If you pass a property with a name that matches any instance method of your component matestack will raise a Matestack::Ui::Core::Properties::PropertyOverwritingExistingMethodException. To use property names that would raise this exception, simply provide an alias name with the as: option. You can then use the alias accordingly.

Some common names that could not be used as properties:

Arguments

If no hash was given, a component can also access/accept a simple argument!

Just make sure to pass an argument on the example page:

No miracle to find here, just what was expected!

Yielding inside components

Components can yield a block with access to scope, where a block is defined. This works the way yield usually works in Ruby. But make sure to explicitly call 'yield_components' within the component response!

Pass a block to a component on the page as shown below:

Not a fancy example, but this is the result:

Partials

Use partials to keep the code dry and indentation layers manageable!

Local partials on component level

In the component definition, see how this time from inside the response, the my_partial method below is called:

As everything is already defined in the component, calling the some_component on the example page is all there is to do:

The outcome is the usual, boring HTML response. Below the HTML snippet, a more exciting example of partial usage is waiting!

Modules: Partials on steriods!

Extract code snippets to modules for an even better project structure. First, create a module:

Include the module in the component:

Then reference the component on the example page as before:

The output is unspectacular in this example, but more complex codebases will greatly benefit from this refactoring option!

Try combining partials with options and slots (see below) for maximum readability, dryness and fun!

Slots

Similar to named slots in Vue.js, slots in Matestack allows us to inject whole UI snippets into the component. It's a more specific yielding mechanism as you will yield multiple "named" blocks into the component. Each of these blocks can be referenced and positioned independently in the component,

Slots on the page instance scope

Define the slots within the component file as shown below. Please make sure to inject slots within a hash slots: { ... } into the component.

Slots have access to the scope of the class, where they are defined. In this case @foo

This gets rendered into HTML as shown below. Notice that the @foo from the component configuration got overwritten by the page's local @foo!

Using slots of components within components

To use component instance scope slots, first define slots within a static component:

and also in some component:

Then, put both components (note that some component uses other component so that's how they're both in here) to use on the example page:

This gets rendered into the HTML below:

This may seem complicated at first, but it can provide valuable freedom of configuration and great fallbacks in more complex scenarios!

Last updated

Was this helpful?