Tech People at Work Podcast: "Relocating for work with Alex Castillo"

I'm very excited to share my first Podcast appearance. In this episode of "Tech People at Work" by Gistia Labs, Carlos Taborda and I talk about my experience on relocation from New York to the Bay Area for my new journey working for Netflix. Other topics include my involvement in the Angular community and my side project: NeuroJavascript.

Now, in his own words, Carlos from Gistia Labs:


Hello everybody,

today we have Alex Castillo on the show, and we’re going to be chatting about his transition coming from New York City all the way to California in chase of a dream job. He’s now working at Netflix, and we’re going to be chatting about some of the day-to-day things that he’s doing at Netflix, but also some of the aspects of his transition and I think a few key areas that had made it better for him, or easier, that Netflix has been a part of, which I think is really important for everybody who’s interested in basically moving to another part of the country or employers who are interested in hiring people from other parts of the country.

So without further ado, let’s welcome Alex.
— Carlos Taborda, Gistia Labs

Text Size Slider with AngularJS

Recently, my coworker Rick was working on some wires using a UI control to decrease/increase text size. He asked me about any technical risks of using a slider on mobile/desktop, as opposed to the usual click/tap on plus/minus to increase decrease text size and this is what I came up with by using: AngularJS, HTML5 and CSS3.

Demo

See the Pen Text Size via HTML5 Slider by Alex Castillo (@alexandercastillo) on CodePen.

Using the AngularJS Directive

Reference the javascript module on your page:

<script type="javascript" src="/lib/angular-text-slider.min.js"></script>

Add 'textSizeSlider' as a dependency on your main module:

angular.module('myApp', ['textSizeSlider']);

And include the directive on your view:

<text-size-slider min="12" max="24" unit="px" value="18"></text-size-slider>

The attributes are self explanatory but here's their definition:

  • min (int): minimum font size value
  • max (int): maximum font size value
  • unit (string): font size value unit (px, pt, %, em, rem, vw, vh, etc)
  • value (int): default font size value

* All attributes are required.

Creating the AngularJS Directive

angular.module('textSizeSlider', [])
  .directive('textSizeSlider', ['$document', function ($document) {
    return {
      restrict: 'E',
      template: '<div class="text-size-slider"><span class="small-letter" ng-style="{ fontSize: min + unit }">A</span> <input type="range" min="{{ min }}" max="{{ max }}" ng-model="textSize" class="slider" value="{{ value }}" /> <span class="big-letter" ng-style="{ fontSize: max + unit }">A</span></div>',
      scope: {
        min: '@',
        max: '@',
        unit: '@',
        value: '@',
      },
      link: function (scope, element, attr) {
        scope.textSize = scope.value;
        scope.$watch('textSize', function (size) {
          $document[0].body.style.fontSize = size + scope.unit;
        });
      }
    }
  }]);

The implementation of this directive is simple. We define an Angular Directive. Specify a template containing an input type range (HTML5's native slider). Add an ngModel to the slider. Then, we watch the ngModel of the slider for changes, and we set the body's font size to the current value of the slider's ngModel.

Styling the slider with CSS

http://www.hongkiat.com/blog/html5-range-slider-style/

A native input type range HTML element will have different default style depending on the browser used. Luckily, we can change the default appearance of sliders with CSS3. The code below was targeted for Webkit browsers (Chrome, Opera nad Safari) specifically. For Firefox and IE, please visit see this tutorial.

/**
 * Text Slider Directive - CSS  
 **/

.text-size-slider {
  line-height: 100%;
  font-size: 14px;
}

.text-size-slider .small-letter,
.text-size-slider .big-letter {
  font-weight: bold;
}

.text-size-slider .slider {
  -webkit-appearance: none;
  margin: 0 8px;
}

.text-size-slider .slider:focus {
  outline: none;
}

.text-size-slider .slider::-webkit-slider-thumb {
  border: none;
  cursor: pointer;
  -webkit-appearance: none;
  background-color: white;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  margin-top: -6px;
}

.text-size-slider .slider::-webkit-slider-runnable-track {
  width: 100%;
  height: 2px;
  cursor: pointer;
  background: white;
  border: 0;
}

Browser Support

There are 2 main parts of this component where browser support should be considered:

  1. AngularJS 1.4.x (IE9+)
  2. HTML5's Input Type Range (IE10+)

According to caniuse.com there is 88.8% browser support for the input type range (#2).

Teaching App Design at Altos de Chavón Summer 2015

It's been 7 years since I graduated from Altos de Chavón school of design, Dominican Republic. Being a student at Chavón has truly been one of the best experiences of my life, and this summer I'll back as a teacher for the App Design intensive course.

From their website:

Every year during the months of July and August, The School of Design holds its International Summer Program. This two-month period offers short intensive courses in the fields of Design, Photography, Fashion Design, Editorial Design, Illustration, Interior Design, Art Therapy, Film Production, Scriptwriting, Painting, Sculpture, among others.

The courses offered by the International Summer program give students the opportunity to create and enhance their portfolio for the purpose of admission to the School, and in turn opens the door to a wider audience – from young people in the process of going to college, to students pursuing careers in art and design, to emerging and established professionals and hobbyists. During the International Summer Program, a diverse audience of students converges in The School of Design, making it a dynamic environment among its national and international participants.
— http://altosdechavon.edu.do/en/programs/special-programs/

For more information, contact: specialprograms@altosdechavon.com

Telephone: + 1 (809) 523.8011

Introducing AngularCSS: CSS On-Demand for AngularJS

Optimize the presentation layer of your single-page apps by dynamically injecting stylesheets as needed.

A lot has changed on how we develop web applications these days. The languages have evolved, the tools have improved, and now we have technologies like AngularJS. All these things create interesting presentation layer challenges in modern web application development and most of these challenges are related to how we reference stylesheets on single-page apps. One way to overcome these challenges is to use the AngularCSS library. It optimizes the presentation layer of your apps by dynamically injecting stylesheets as needed.

So how do you implement AngularCSS into your apps?

The Early Days of the Web

Before we dive into AngularCSS, lets take a step back to the early days of the web. The presentation layer is not what it used to be. It has changed and while overall evolution has been positive, modern presentation layer architecture has some weaknesses. Historically, while creating a website, there would be an index.html file and other html files such as about.html, contact.html, etc. With that approach you could organize your CSS in the same fashion by referencing different stylesheets in the head section of each document accordingly: home.css, about.css, contact.css, etc. There are some great benefits that come with this, one of them being that stylesheets are loaded as they are needed and removed when they are not in a page-by-page basis.

These days we have responsive web design and media queries in CSS. This makes for larger files or more files dedicated to different breakpoints. We also have the concept of single-page apps. They usually feature a single master template file with a head tag, and multiple headless views or partials, leading us to reference all CSS files from the master template. This is not ideal.

The whole presentation layer of the app is being front-loaded, with potentially thousands of lines depending on the size of the app. This seems rather unnecessary due to the fact that the user may never access some parts of the app or breakpoints for that matter.

So how do we overcome this? By using AngularCSS to meet these challenges head on.

Introducing AngularCSS

Throughout my career I have developed some very robust cross-platform single-page apps. Some of them covering from hand-held devices to kiosks or even TVs. All with a single codebase. At times with so much CSS, the load time and performance become a huge concern on the presentation layer. This is the reason I have created AngularCSS.

AngularCSS is a JavaScript library for Angular that optimizes the presentation layer of your single-page apps by dynamically injecting stylesheets as needed. This approach is also referred as “on-demand” or “lazy loading”. The main benefit of lazy loading is performance of course, but there are other great things we can leverage from this approach like Encapsulation and SMQ (Smart Media Queries).

Getting Started

Before we get into encapsulation and SMQ, lets get started with the library. Using AngularCSS is very simple. There are two basics steps for setting it up.

1. Reference the JavaScript library in your index.html after angular.js.

<script src="libs/angular-css/angular-css.js"></script>

You can download AngularCSS from GitHub. Also available via Bower and CDN.

2. Add “door3.css” as a dependency for your app.

var myApp = angular.module('myApp', ['ngRoute','door3.css'']);

Now you can start referencing stylesheets from the route provider.

$routeProvider
    .when('/tickets', {
        templateUrl: 'tickets/tickets.html',
        controller: 'ticketsCtrl',
        css: 'tickets/tickets.css'
    });

Or directly in directives.

myApp.directive('itinerary', function () {
    return {
        restrict: 'E',
        templateUrl: 'itinerary/itinerary.html',
        css: 'itinerary/itinerary.css''
    }
});

See full demo.

Web Component Encapsulation

I believe in progressive enhancement. I also believe that AngularJS and Web Components are the future of the web. In Angular we can attach templates (structure) and controllers (behavior) to pages and components. AngularCSS enables the last missing piece: attaching stylesheets (presentation). For me, being able to have these three things in a single unit is vital based on the way the web is moving towards component-based development.

Smart Media Queries

AngularCSS supports Smart Media Queries via the matchMedia API. This means that stylesheets with media queries will be only added if the breakpoint matches. Consider the example below. If a user accesses your responsive app from a mobile device, the browser will only load the mobile stylesheets because AngularCSS will first evaluate the media query and check if it matches before adding the stylesheet to the page. This can significantly optimize the load time of your apps.

$routeProvider
    .when('/tickets', {
        templateUrl: 'tickets/tickets.html',
        controller: 'ticketsCtrl',
        css: [
            {
                href: 'tickets/tickets.mobile.css',
                media: '(max-width: 480px)'
            }, {
                href: 'tickets/tickets.tablet.css',
                media: '(min-width: 768px) and (max-width: 1024px)'
            }, {
                href: 'tickets/tickets.desktop.css',
                media: '(min-width: 1224px)'
            }
        ]
    });

Application Architecture

As you can already tell, this way of referencing stylesheets requires separate files for each breakpoint, page and component, opposed to having page-specific and component-specific CSS in the same files. This approach encourages an organized and scalable CSS architecture by separating stylesheets by sections, pages, components and devices.

AngularCSS reintroduces the concept of CSS scope on single-page apps. Stylesheets only live for as long as the current route or directives are active. This means that the chances of unwanted CSS overrides are slim to none. And because there could be use cases for persisting stylesheets, I have added a feature to persist stylesheets if desired.

$routeProvider
    .when('/page1', {
        templateUrl: 'page1/page1.html',
        controller: 'page1Ctrl',
        css: {
            href: 'page1/page1.css',
            persist: true
        }
    });

CSS and Cache

It is possible to preload stylesheets before the route or directive are active. This is accomplished internally via HTTP request. That way when the stylesheets are added, they are loaded from the browser’s cache making it way faster to resolve.

$routeProvider
    .when('/page1', {
        templateUrl: 'page1/page1.html',
        controller: 'page1Ctrl',
        css: {
            href: 'page1/page1.css',
            preload: true
        }
    });

Browser cache is awesome because it speeds thing up. But, busting the cache can be very helpful when publishing CSS updates to your app, since it forces the browser download the latest version of the stylesheet. This can be done similarly by setting bustCache to true

$routeProvider
    .when('/page1', {
        templateUrl: 'page1/page1.html',
        controller: 'page1Ctrl',
        css: {
            href: 'page1/page1.css',
            bustCache: true
        }
    });

All these examples illustrate how to configure features at the stylesheet level, but it is possible to do it globally by setting some defaults in $cssProvider via module config.

myApp.config(function($cssProvider) {
    angular.extend($cssProvider.defaults, {
        persist: true,
        preload: true,
        bustCache: true
    });
});

How AngularCSS works

In order to provide a seamless API integration with AngularJS, I had to figure out ways to intercept routes and directives. For routes, the AngularCSS service listens for route and states event changes. These events expose the current and previous route object. Since we are extending the route object with a custom “css” property, AngularCSS adds the CSS defined on the current route and removes it from the previous route via its service: $css. Same concept applies when using states with UI Router.

For directives, well, it is a little bit more complicated. Since Angular doesn’t expose events for directives I was forced to add them ourselves by hacking or “monkey-patching” Angular core. First, I had to get inside angular.module and angular.directive in order to get a list of all custom directives. Then proceed to decorate all directives and get inside the compile and link functions. Finally, I added a custom event via $rootScope.$broadcast that triggers as each directive is being compiled. We pass the DDO (Directive Definition Object) and scope containing our custom “css” property to the custom event. The scope is passed in order to remove the directive’s stylesheets on scope destroy event. After all this nonsense, AngularCSS is able to extend the AngularJS API in a native-like fashion. It is my hope that the AngularJS team and community embrace AngularCSS and with their help/collaboration a solution will arise.

See the hack here.

Because Angular is totally modular, you can easily replace any of its parts.
— Brian Ford, Angular Team Member

With AngularCSS we can now encapsulate presentation in Angular pages and components in an organized and scalable fashion. There’s no need to reference the stylesheets via HTML with the tag anymore (yay!). Stylesheets are requested on-demand. Responsive design can be optimized at the breakpoint/device level. And we also get some useful features like busting cache.

This post originally appeared at DOOR3.

Source: http://door3.com/insights/introducing-angu...