JSFiddle - React, Tailwind, and code Playground

by Hemanth HM

HTML

<pre id="out"></pre>

JavaScript

const common = [{
  name: 'line1',
  attr: {}
}, {
  name: 'line2',
  attr: {}
}]

const template = {
  selectedView: 'basicAccount',
  context: {},
  elements: [
    {
      name: 'email',
      component: 'TextInput',
      validations: ['required'],
      attributes: {
        type: 'email',
        name: 'email',
        autoComplete: true,
        label: 'basicAccount.email.placeholder',
      },
    },
    {
      name: 'businessAddress',
      type: 'Group',
      elements: [
        {
          type: 'VerticalLayout',
          elements: ['line1', 'line2'],
        },
        {
          type: 'HorizontalLayout',
          elements: ['line1', 'line1'],
        },
        {
          type: 'VerticalLayout',
          elements: ['line1'],
        },
      ],
    },
  ],
  views: [
    {
      name: 'basicAccount',
      layout: 'layoutType',
      elements: ['email', 'businessAddress'],
      action: {
        path: 'path/to/end/point',
        data: {},
        error: {},
      },
      nextView: 'businessInfo',
    },
  ],
}


const selectedView = template.views.find(view => view.name === template.selectedView)

const resolveFromCommon = name => common.find(cm => cm.name === name);
const resolveFromTemplate = name => template.elements.find(elm => elm.name === name);

const walk = (elements) => elements.flatMap(name => {

  if (Array.isArray(name.elements)) {
    name.elements = [...name.elements.map(resolveFromCommon), ...name.elements.map(resolveFromTemplate)].filter(Boolean)
    return name
  }
  let element = resolveFromCommon(name) || resolveFromTemplate(name);
  
  if (!element) {
    return [];
  }

  if (Array.isArray(element.elements)) {
    element = {
      ...element
    };
    element.elements = walk(element.elements);
  }

  return [element];
});

const updated = {
  ...selectedView,
  elements: walk(selectedView.elements)
};

out.textContent = JSON.stringify(updated, null, 2);

/*
0. Filter the views and pick the template.selectedView
1. For...