2.0.6 • Published 3 years ago

@xinsolutions/xincomponents v2.0.6

Weekly downloads
-
License
SEE LICENSE IN LI...
Repository
github
Last release
3 years ago

XIN Components Package

Contains functionality to define and render distributed component catalogues that can be interpreted either locally by an ExpressJS application, or can be requested with dynamic payloads by a 3rd party service.

Initialise

At the start of your application you can initialise a set of endpoints that expose the components to the world.

const express = require('express');
const hbs = require('express-hbs');
const {xinc, ComponentController, Handlebars} = require('@xinsolutions/xincomponents');

// initialise serving out the components
ComponentController.initialiseRoutes(xinc, app, "/_system/components", "SuperSecretInformation");
Handlebars.initialise(hbs, xinc);

One must pass in xinc, the express app instance, a prefix at which the endpoints will live, and an optional last parameter if you wish to protect invoking the endpoints with a simple token. In our case all endpoints must contain a query parameter ?secret=SuperSecretInformation.

Endpoints

The code above initialises a number of endpoints on the application instance.

  • app.get('${prefix}/': show a list of catalogue name ids
  • app.get('${prefix}/:catalogueId': show the list of groups with its components for a given catalogue id
  • app.get('${prefix}/:catalogueId/:groupId': show the list of components for a catalogue's group
  • app.get('${prefix}/:catalogueId/:groupId/:componentId': show a specific component's description
  • app.post('${prefix}/:catalogueId/:groupId/:componentId': render a component, it expects a payload like this:

The POST payload for the last entry above is as follows.

{

    // if set to true, handlerbar templates with render its sandboxLayout
    "inSandbox": true/false,
    
    // if not specified, default content renderer is called, otherwise
    // contentVariation with this ID is called. 
    "variation": ".json",

    "theme": {
        "type": "custom",
        "colours": ["#3398DB", "#1FBC9C", "#3D556E", "#DDE6E8", "#333333", "#111111", "#eeeeee"],
        "fonts": [
        {
            "id": "font-1",
            "family": "Taviraj",
            "weight": {"value": 200, "text": "Super Thin"},
            "size": 18
        },
        {
            "id": "font-2",
            "family": "Roboto",
            "weight": {"value": 600, "text": "Regular"},
            "size": 24
           
        }
    ]
    },
    "choices": {
          "switch": {"type" : "immediate", "value": true},
          "sizing": {"type" : "immediate", "value": 5},
          "title": {"type": "immediate", "value": "Header title"},
          "list": {"type": "immediate", "value": "success"},
    
          "c-h1": { "type": "ref", "value": 0 },
          "c-byline": { "type": "ref", "value": 5 },
          "c-content": { "type": "ref", "value": 4 },
          "c-background": { "type": "ref", "value": 6 },
        
          "f-h1": { "type" : "ref", "value": 0},
          "f-byline": { "type" : "ref", "value": 1},
          "f-content": { "type" : "ref", "value": 1}

    },
    
    // optional context (in not specified then .defaultContext() is used)
    context: {}

}

Defining Components

You can configure components to be part of a catalogue by using the built-in fluid API such as this:

/*
      ____                                             _      ____      _        _
     / ___|___  _ __ ___  _ __   ___  _ __   ___ _ __ | |_   / ___|__ _| |_ __ _| | ___   __ _ _   _  ___
    | |   / _ \| '_ ` _ \| '_ \ / _ \| '_ \ / _ \ '_ \| __| | |   / _` | __/ _` | |/ _ \ / _` | | | |/ _ \
    | |__| (_) | | | | | | |_) | (_) | | | |  __/ | | | |_  | |__| (_| | || (_| | | (_) | (_| | |_| |  __/
     \____\___/|_| |_| |_| .__/ \___/|_| |_|\___|_| |_|\__|  \____\__,_|\__\__,_|_|\___/ \__, |\__,_|\___|
                         |_|                                                             |___/

    Purpose:

        To initialise the components catalogue

 */

const {xinc} = require('@xinsolutions/xincomponents');
const StructureGroup = require("./structure/_componentGroup.js");

module.exports = {

    /**
     * Initialise the component catalogue
     *
     * @param app
     */
    initialise(app) {
        xinc.registerCatalogue(
            xinc.catalogue()
                .describe('one-church')
                .withGroup(StructureGroup.initialise(app))
        )
    }
}

Where _componentGroup.js is:

const {xinc} = require('@xinsolutions/xincomponents');

const Typography = require('./Typography.js');

module.exports = {

    initialise(app) {
        return (
            xinc.group()
                .describe('structure', 'Structure Component Group')
                .withComponent(Typography.initialise(app))
        );
    }

};

and Typography.js is:

const {xinc} = require('@xinsolutions/xincomponents');

module.exports = {

    /**
     * @return {Component}
     */
    initialise(app) {

        return (
            xinc.component()

                // a simple description of the component.
                .describe(
                    "typography",
                    "Typography",
                    "A description of typographical elements in body contents"
                )

                // the css prefix (.typo-c-h1)
                .prefix("typo")

                // the style requirements for this component
                .requires(

                    xinc.bool("switch", "Is the switch on or off?"),
                    xinc.number("sizing", "Sizing number", 0, 100, 1),
                    xinc.text("title", "Text field"),

                    xinc.list("list", "A list", "info", {
                        "debug" : "Debug",
                        "info" : "Information",
                        "success" : "Success",
                        "danger" : "Danger",
                        "warning" : "Warning",
                    }),

                    xinc.color("c-h1", "Header Colour")
                    xinc.color("c-content", "Content Colour"),
                    xinc.font("f-h1", "Header 1 Font"),
                    xinc.font("f-content", "Content Font"),

                    //
                    //	Colours for in the content
                    //
                    xinc.controlGroup('Colours',
                        xinc.color("c-h1", "Header 1 Colour"),
                        xinc.color("c-h2", "Header 2 Colour"),
                        xinc.color("c-h3", "Header 3 Colour"),
                        xinc.color("c-h4", "Header 4 Colour"),
                        xinc.color("c-h5", "Header 5 Colour"),
                        xinc.color("c-h6", "Header 6 Colour"),
                        xinc.color("c-byline", "Byline Colour"),
                        xinc.color("c-content", "Content Colour"),
                        xinc.color("c-background", "Background Colour")
                    ),

                )

                // the default context that is passed into the rendered template if none was specified
                // in the request. This is great for mock data, and expressing what model is expected.
                .defaultContext({})

                // a function that is passed the component, and a context with values that can manipulate the context
                // further before the application is rendered.
                .logic((component, context) => {
                    console.log("Executing the logic"); context['new'] = component._name;
                })

                .content(
                    xinc.handlebars(
                        app,
                        "structure/cmp-typography",
                        "components/content"
                    )
                )

                // if a variation starts with a period, it will not be shown in the component's description
                .contentVariation('.json', 'JSON representation', xinc.json())

        );
    }

};

Use in Handlebars templates

In your .hbs you can use the two registered helpers as follows:

{{{render (component "one-church/structure/typography" modelElement styleKit) }}}

Where component is an asynchronous helper that takes a single parameter. The parameter is prepared by the describe helper. In which:

  • the first parameter is the path to the component that we're rendering <catalog>/<group>/<componentName>
  • the second parameter contains the context element that is passed into the component logic.
  • there is a fourth optional parameter that describes which variation is to be rendered, normally though the styleKit choices will determine which variation is going to be rendered.
  • the third parameter is the styleKit, an object with theme and choices as keys.

Connecting OC Tools to a component catalogue

To let oc-tools know a catalogue exists at a certain URL we add or modify the urls property to this node:

  • /content/collections/styling/config/jcr:content/jcr:content

If your repository does not have this node, make sure you install the XIN Mods - Styling collections.zip from the oc-tools project.

2.0.6

3 years ago

2.0.5

3 years ago

2.0.4

3 years ago

2.0.3

3 years ago

2.0.1

3 years ago

1.3.15

3 years ago

1.3.14

3 years ago

1.3.13

4 years ago

1.3.12

4 years ago

1.3.11

4 years ago

1.3.10

4 years ago

1.3.9

4 years ago

1.3.8

4 years ago

1.3.7

4 years ago

1.3.6

4 years ago

1.3.5

4 years ago

1.3.4

4 years ago

1.3.3

4 years ago

1.3.2

4 years ago

1.3.1

4 years ago

1.3.0

4 years ago

1.2.20

4 years ago

1.2.19

4 years ago

1.2.18

4 years ago

1.2.17

4 years ago

1.2.16

4 years ago

1.2.15

4 years ago

1.2.14

4 years ago

1.2.13

4 years ago

1.2.12

4 years ago

1.2.11

4 years ago

1.2.10

4 years ago

1.2.9

4 years ago

1.2.8

4 years ago

1.2.7

4 years ago

1.2.6

4 years ago

1.2.5

4 years ago

1.2.4

4 years ago

1.2.3

4 years ago

1.2.2

4 years ago

1.2.1

4 years ago

1.2.0

4 years ago

1.1.2

4 years ago

1.1.1

4 years ago

1.1.0

4 years ago