JSFiddle - React, Tailwind, and code Playground

HTML

<div ng-app="MyApp">
    <form name="personalDataForm">
        <div class="form-group">
            
  <div style="padding-left:0px;" ng-class="{'has-error':personalDataForm.phone.$invalid && personalDataForm.phone.$dirty}" class="col-md-6">
    <label>Teléfono</label>
    <input type="tel" name="phone" ng-required="true" ng-trim="true" ng-model="phone" class="form-control phoneRegexInput"/>
  </div>
            
            
            
            
            
  <div style="padding-left:0px;" ng-class="{'has-error':personalDataForm.mobile.$invalid && personalDataForm.mobile.$dirty}" class="col-md-6">
    <label>Celular</label>
    <input type="tel" name="mobile" ng-required="true" ng-trim="true" ng-model="mobile" class="form-control phoneRegexInput"/>
  </div>
</div>
    </form>
</div>

CSS

.has-error{
    background-color: red;
}

JavaScript

'use strict';

angular
    .module('MyApp',[])
    .directive('input-o', inputTel);

var NANP_REGEXP = /^([0-9]{3})([0-9]{7})$/;
function inputTel() {
    return {
        restrict: 'E',
        require: '?ngModel',
        link: function (scope, elem, attr, ctrl) {
            if (ctrl && attr.type === 'tel') {
                ctrl.$parsers.push(function (viewValue) {
                    if(ctrl.$isEmpty(viewValue)){
                        ctrl.$setValidity('tel', true);
                        return viewValue;
                    }
                    var numbers = viewValue? viewValue.replace(/\D/g, "") : '';
                    if (NANP_REGEXP.test(numbers)) {
                        var formatted = numbers.replace(NANP_REGEXP, '$1-$2');
                        if (formatted !== viewValue) {
                            ctrl.$setViewValue(formatted);
                            ctrl.$render();
                        }
                        ctrl.$setValidity('tel', true);
                        return numbers.replace(NANP_REGEXP, '$1$2');
                    } else {
                        ctrl.$setValidity('tel', false);
                        return undefined;
                    }
                });

                ctrl.$formatters.push(function (viewValue) {
                    if(ctrl.$isEmpty(viewValue)){
                        ctrl.$setValidity('tel', true);
                        return viewValue;
                    }
                    var numbers = ctrl.$modelValue? ctrl.$modelValue.replace(/\D/g, "") : '';
                     if (NANP_REGEXP.test(numbers)) {
                        ctrl.$setValidity('tel', true);
                        return numbers.replace(NANP_REGEXP, '$1-$2');
                    } else {
                        ctrl.$setValidity('tel', false);
                        return undefined;
                    }
                });
            }
        }
    };
}