function toTag(segment, ix) {
    if (!segment) return <Empty key={ix} />;

    const MatchElement = allElements.find(
      (e) =>
        e.craft.related &&
        e.craft.related.fields &&
        e.craft.related.segment_type &&
        e.craft.related.segment_type == segment.type &&
        (!e.craft.related.segment_match ||
          e.craft.related.segment_match(segment))
    );
    if (MatchElement) {
      const related = MatchElement.craft.related;
      const props = {};
      related.fields.forEach((f) => {
        if (f.type === "Nodes" && f.nodeID) {
          props[f.name || f] = toTag(segment[f.segment_name || f.name || f]);
          //).map(toTag);
        } else {
          const v = segment[f.segment_name || f.name || f];
          props[f.name || f] = typeof v === "undefined" ? f.default : v;
        }
      });
      if (related.fields.some((f) => f.canBeFormula))
        props.isFormula = segment.isFormula;
      if (related.hasContents)
        return (
          <Element
            key={ix}
            canvas
            {...props}
            is={MatchElement}
            custom={segment._custom || {}}
          >
            {toTag(segment.contents)}
          </Element>
        );
      else
        return (
          <MatchElement key={ix} custom={segment._custom || {}} {...props} />
        );
    }
    if (segment.type === "blank") {
      return (
        <Text
          custom={segment._custom || {}}
          key={ix}
          text={segment.contents}
          isFormula={segment.isFormula || {}}
          block={segment.block || false}
          inline={segment.inline || false}
          textStyle={segment.textStyle || ""}
          labelFor={segment.labelFor || ""}
          customClass={segment.customClass || ""}
          style={segment.style || {}}
          icon={segment.icon}
          font={segment.font || ""}
        />
      );
    } else if (segment.type === "view") {
      return (
        <View
          custom={segment._custom || {}}
          key={ix}
          view={segment.view}
          relation={segment.relation}
          order_field={segment.order_field}
          view_name={segment.view_name}
          name={segment.name}
          state={segment.state}
          extra_state_fml={segment.extra_state_fml}
          configuration={segment.configuration || {}}
        />
      );
    } else if (segment.type === "action") {
      return (
        <Action
          custom={segment._custom || {}}
          key={ix}
          name={segment.action_name}
          rndid={segment.rndid || "not_assigned"}
          action_row_variable={segment.action_row_variable || ""}
          action_row_limit={segment.action_row_limit || ""}
          action_label={segment.action_label || ""}
          action_style={segment.action_style || "btn-primary"}
          action_size={segment.action_size || ""}
          action_icon={segment.action_icon || ""}
          action_title={segment.action_title || ""}
          action_class={segment.action_class || ""}
          action_bgcol={segment.action_bgcol || ""}
          action_bordercol={segment.action_bordercol || ""}
          action_textcol={segment.action_textcol || ""}
          nsteps={segment.nsteps || ""}
          step_only_ifs={segment.step_only_ifs || ""}
          step_action_names={segment.step_action_names || ""}
          confirm={segment.confirm}
          spinner={segment.spinner}
          is_submit_action={segment.is_submit_action}
          configuration={segment.configuration || {}}
          block={segment.block || false}
          minRole={segment.minRole || 10}
          isFormula={segment.isFormula || {}}
        />
      );
    } else if (segment.type === "container") {
      return (
        <Element
          key={ix}
          custom={segment._custom || {}}
          canvas
          gradStartColor={segment.gradStartColor}
          gradEndColor={segment.gradEndColor}
          gradDirection={segment.gradDirection}
          rotate={segment.rotate || 0}
          animateName={segment.animateName}
          animateDuration={segment.animateDuration}
          animateDelay={segment.animateDelay}
          animateInitialHide={segment.animateInitialHide}
          customClass={segment.customClass}
          customId={segment.customId}
          customCSS={segment.customCSS}
          overflow={segment.overflow}
          margin={segment.margin || [0, 0, 0, 0]}
          padding={segment.padding || [0, 0, 0, 0]}
          minHeight={segment.minHeight}
          height={segment.height}
          width={segment.width}
          click_action={segment.click_action}
          url={segment.url}
          hoverColor={segment.hoverColor}
          minHeightUnit={segment.minHeightUnit || "px"}
          heightUnit={segment.heightUnit || "px"}
          widthUnit={segment.widthUnit || "px"}
          vAlign={segment.vAlign}
          hAlign={segment.hAlign}
          htmlElement={segment.htmlElement || "div"}
          display={
            segment.display ||
            (segment.block === true
              ? "block"
              : segment.block === false
                ? "inline-block"
                : "block")
          }
          fullPageWidth={
            typeof segment.fullPageWidth === "undefined"
              ? false
              : segment.fullPageWidth
          }
          bgFileId={segment.bgFileId}
          bgField={segment.bgField}
          imageSize={segment.imageSize || "contain"}
          imgResponsiveWidths={segment.imgResponsiveWidths}
          bgType={segment.bgType || "None"}
          style={segment.style || {}}
          transform={segment.transform || {}}
          bgColor={segment.bgColor || "#ffffff"}
          setTextColor={!!segment.setTextColor}
          textColor={segment.textColor || "#000000"}
          isFormula={segment.isFormula || {}}
          showIfFormula={segment.showIfFormula || ""}
          showForRole={segment.showForRole || []}
          minScreenWidth={segment.minScreenWidth || ""}
          maxScreenWidth={segment.maxScreenWidth || ""}
          show_for_owner={!!segment.show_for_owner}
          is={Container}
        >
          {toTag(segment.contents)}
        </Element>
      );
    } else if (segment.type === "tabs") {
      let contentsArray = segment.contents.map(toTag);
      let contents;
      if (segment.tabsStyle === "Value switch") {
        contents = {};
        segment.titles.forEach(({ label, value }, ix) => {
          contents[value] = contentsArray[ix];
        });
      } else contents = contentsArray;
      return (
        <Tabs
          key={ix}
          custom={segment._custom || {}}
          titles={segment.titles}
          showif={segment.showif}
          ntabs={segment.ntabs}
          setting_tab_n={segment.setting_tab_n}
          independent={segment.independent}
          startClosed={segment.startClosed}
          deeplink={segment.deeplink}
          acc_init_opens={segment.acc_init_opens}
          disable_inactive={segment.disable_inactive}
          serverRendered={segment.serverRendered}
          tabId={segment.tabId}
          field={segment.field}
          tabsStyle={segment.tabsStyle}
          contents={contents}
        />
      );
    } else if (segment.type === "table") {
      return (
        <Table
          key={ix}
          custom={segment._custom || {}}
          rows={segment.rows || 2}
          columns={segment.columns || 2}
          bs_style={segment.bs_style || false}
          customClass={segment.customClass}
          bs_small={segment.bs_small || false}
          bs_striped={segment.bs_striped || false}
          bs_bordered={segment.bs_bordered || false}
          bs_wauto={segment.bs_wauto || false}
          bs_borderless={segment.bs_borderless || false}
          contents={(segment.contents || []).map((row) =>
            (row || []).map(toTag)
          )}
        />
      );
    } else if (segment.besides && segment.list_columns) {
      const addFields = options.additionalColumnFields;

      return segment.besides.map((col, jx) => {
        const addProps = {};
        (addFields || []).forEach((f) => {
          addProps[f.name] = col[f.name];
        });
        return (
          <ListColumn
            custom={segment._custom || {}}
            key={jx}
            alignment={col.alignment}
            header_label={col.header_label}
            col_width={col.col_width}
            showif={col.showif}
            col_width_units={col.col_width_units}
            contents={toTag(col.contents)}
            {...addProps}
          ></ListColumn>
        );
      });
    } else if (segment.besides) {
      return (
        <Columns
          key={ix}
          custom={segment._custom || {}}
          breakpoints={segment.breakpoints || default_breakpoints(segment)}
          ncols={segment.besides.length}
          widths={getColWidths(segment)}
          style={segment.style || {}}
          gx={segment.gx}
          gy={segment.gy}
          customClass={segment.customClass}
          vAligns={segment.vAligns}
          colClasses={segment.colClasses}
          colStyles={segment.colStyles}
          aligns={segment.aligns}
          setting_col_n={1}
          contents={segment.besides.map(toTag)}
        />
      );
    } else if (segment.above) {
      return segment.above.map((e, ix) => toTag(e, ix));
    }
  }
@param {object} segment
@param {string} ix
@returns {Element|Text|View|Action|Tabs|Columns}