Q:

how to load custom Field Type into a custom Module (form)

I'm trying to make a set of field type (location field type which contain of: country, City, Address, Google map which store lat & long, etc.) and this 'set' of field i need to load into my custom module (form).
so if i have:
FieldType
<?php

/**
 * @file
 * Contains \Drupal\arm_main\Plugin\Field\FieldType\CustomField.
 */

namespace Drupal\arm_main\Plugin\Field\FieldType;

use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface as StorageDefinition;

/**
 * Plugin implementation of the 'custom' field type.
 *
 * @FieldType(
 *   id = "custom",
 *   label = @Translation("Custom"),
 *   description = @Translation("Stores custom data."),
 *   category = @Translation("My Category"),
 *   default_widget = "custom_default",
 *   default_formatter = "CustomFieldDefaultFormatter"
 * )
 */

class CustomField extends FieldItemBase {

  const COUNTRY_ISO2_MAXLENGTH = 2;

  public static function propertyDefinitions(StorageDefinition $storage) {

    $properties = [];

    $properties['a'] = DataDefinition::create('string')
      ->setLabel(t('Label A'))
      ->setRequired(TRUE);

    $properties['b'] = DataDefinition::create('string')
      ->setLabel(t('Label B'))
      ->setRequired(TRUE);

    $properties['c'] = DataDefinition::create('string')
      ->setLabel(t('Label C'));

    $properties['d'] = DataDefinition::create('float')
      ->setLabel(t('Label D'));

    $properties['e'] = DataDefinition::create('float')
      ->setLabel(t('Label E'));

    $properties['f'] = DataDefinition::create('integer')
      ->setLabel(t('Label F'));

    return $properties;
  }

  public static function schema(StorageDefinition $storage) {

    $columns = [];
    $columns['a'] = [
      'type' => 'varchar',
      'length' => 255,
    ];
    $columns['b'] = [
      'type' => 'varchar',
      'length' => 255,
    ];
    $columns['c'] = [
      'type' => 'text',
      'length' => 255,
    ];

    $columns['d'] = [
      'type' => 'float',
      'size' => 'big',
      'default' => 0.0,
      'not null' => FALSE,
    ];
    $columns['e'] = [
      'type' => 'float',
      'size' => 'big',
      'default' => 0.0,
      'not null' => FALSE,
    ];
    $columns['f'] = [
      'type' => 'int',
      'length' => 10,
      'not null' => FALSE,
    ];

    return [
      'columns' => $columns,
      'indexes' => [],
    ];
  }

  public function isEmpty() {

    $isEmpty = 
      empty($this->get('a')->getValue()) &&
      empty($this->get('b')->getValue()) &&
      empty($this->get('c')->getValue()) &&
      empty($this->get('d')->getValue()) &&
      empty($this->get('e')->getValue());

    return $isEmpty;
  }

  /**
   * {@inheritdoc}
   */
  public function getConstraints() {
    $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
    $constraints = parent::getConstraints();

    $constraints[] = $constraint_manager->create('ComplexData', array(
      'value' => array(
        'Length' => array(
          'max' => static::COUNTRY_ISO2_MAXLENGTH,
          'maxMessage' => t('%name: the country iso-2 code may not be longer than @max characters.', array('%name' => $this->getFieldDefinition()->getLabel(), '@max' => static::COUNTRY_ISO2_MAXLENGTH)),
        )
      ),
    ));
    return $constraints;
  }

} // class

FieldWidget
<?php

/**
 * @file
 * Contains \Drupal\arm_main\Plugin\Field\FieldType\CustomFieldDefaultWidget.
 */

namespace Drupal\arm_main\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Plugin implementation of the 'custom_default' widget.
 *
 * @FieldWidget(
 *   id = "custom_default",
 *   label = @Translation("Custom"),
 *   field_types = {
 *     "custom"
 *   }
 * )
 */
class CustomFieldDefaultWidget extends WidgetBase {

/**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return array(
      'size' => 60,
      'placeholder' => '',
    ) + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $element['size'] = array(
      '#type' => 'number',
      '#title' => $this->t('Textfield size'),
      '#default_value' => $this->getSetting('size'),
      '#required' => TRUE,
      '#min' => 1,
    );
    $element['placeholder'] = array(
      '#type' => 'textfield',
      '#title' => t('Placeholder'),
      '#default_value' => $this->getSetting('placeholder'),
      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
    );
    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = array();

    $placeholder = $this->getSetting('placeholder');
    if (!empty($placeholder)) {
      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
    }else {
      $summary[] = t('No placeholder');
    }
    $summary[] = t('Textfield size: @size', array('@size' => $this->getSetting('size')));

    return $summary;
  }

  public function formElement(FieldItemListInterface $items, $delta, Array $element, Array &$form, FormStateInterface $formState) {

    $countries = \Drupal::service('country_manager')->getList();

    $element['a'] = [
        '#type' => 'select',
        '#options' => $countries,
        '#empty_value' => '',
        '#default_value' => (isset($items[$delta]->value) && isset($countries[$items[$delta]->value])) ? $items[$delta]->value : NULL,
        '#description' => t('Description here'),
      ];

    $element['b'] = [
      '#type' => 'textfield',
      '#title' => t('Title B'),
      '#default_value' => isset($items[$delta]->b) ? 
          $items[$delta]->b : null,
      '#empty_value' => '',
      '#placeholder' => t('B Here'),
    ];

    $element['c'] = [
      '#type' => 'textfield',
      '#title' => t('Title C'),

      '#default_value' => isset($items[$delta]->c) ? 
          $items[$delta]->c : null,

      '#empty_value' => '',
      '#placeholder' => t('C Here'),
    ];

    $element['intro'] = [
      '#type' => 'markup',
      '#markup' => t('<strong>some text here...</strong>'),
      '#prefix' => '<div>',
      '#suffix' => '</div>',
    ];

    $element['d'] = [
      '#title' => t('Title D'),
      '#type' => 'textfield',
      '#default_value' => isset($items[$delta]->d) ? $items[$delta]->d : NULL,
      '#empty_value' => 0,
      '#placeholder' => t('D Here'),
      '#attributes' => array(
        'data-d-delta' => $delta,
        'class' => array('custom-field-watch-change'),
      ),
    ];

    $element['e'] = [
      '#title' => t('Title E'),
      '#type' => 'textfield',
      '#default_value' => isset($items[$delta]->e) ? $items[$delta]->e : NULL,
      '#empty_value' => 0,
      '#placeholder' => t('E Here'),
      '#attributes' => array(
        'data-e-delta' => $delta,
        'class' => array('custom-field-watch-change'),
      ),
    ];

    $element['f'] = [
      '#title' => t('Title F'),
      '#type' => 'textfield',
      '#default_value' => isset($items[$delta]->f) ? $items[$delta]->f : NULL,
      '#empty_value' => 7,
      '#placeholder' => t('F Here'),
      '#attributes' => array(
        'data-f-delta' => $delta,
        'class' => array('custom-field-watch-change'),
      ),
    ];

    $element['open_but'] = [
      '#type' => 'button',
      '#value' => t('Set button Marker'),
      '#attributes' => array(
        'data-delta' => $delta,
        'id' => 'but_setter_' . $delta,
      ),
    ];

    $element['clear_fields'] = [
      '#type' => 'button',
      '#value' => t('Clear Fields'),
      '#attributes' => array(
        'data-delta' => $delta,
        'id' => 'clear_fields_' . $delta,
        'class' => array('custom-field-clear'),
      ),
      '#suffix' => '</div>',
    ];

    $element['preview'] = [
      '#type' => 'item',
      '#title' => t('Preview'),
      '#markup' => '<div class="custom-field-preview" data-delta="' . $delta . '"></div>',
      '#prefix' => '<div class="custom-field-widget right">',
      '#suffix' => '</div>',
    ];

    return $element;
  }

} // class

how do i load it into FormBase programmatically in here:
class testCreateForm extends FormBase {

  public function __construct($coreService, $mainService) {      }
  public static function create(ContainerInterface $container) {      }
  public function getFormId() {      }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['someSample'] = array(
      '#type' => 'details',
      '#title' => t('Add new things'),
      '#description' => t('desc here'),
      '#open' => TRUE,
    );
    $form['someSample']['test'] = array(
      '#type' => 'textfield',
      '#title' => t('test'),
      '#description' => $this->t('Your test code'),
      '#default_value' => "",
      '#size' => 10,
      '#maxlength' => 8,
      '#required' => TRUE,
    );
    $form['someSample']['custom'] = array( // i did this but not work
      '#type' => 'custom',
      '#title' => t('Custom Title'),
    );
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {      }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

  }

}

A:

i found some tutorial here:
https://docs.acquia.com/articles/drupal-8-creating-elements-theming-elements-and-managing-frontend-libraries
and it works to me, so generally all you need to build is an element class, define your element class, apply it to template then should be done.
if someone interested, i dont mind to write more detailed here
Thanks

