Categorías: Labs

Construyendo una Lista de Tareas para Firefox OS, parte 1

Este artículo fue originalmente publicado en el blog de Mozilla Hacks. Traducción por Ángel Fernando Quiroz.

Ésta es la primera de dos partes en un tutorial donde construiremos una aplicación de Lista de Tareas para Firefox OS desde cero. Asumimos que entiendes algo de HTML5, CSS3, JavaScript, jQuery/Zepto, y Backbone.js. En esta parte elaboraremos una interfaz de usuario semántica y estructurada apropiadamente de una Lista de Tareas usando las mejores prácticas para diseño de interfaces de usuario móviles.

El código fuente de la aplicación de Lista de Tareas está disponible en GitHub.

Configurando el entorno

Usaremos volo como nuestro gestor de paquetes y herramienta de construcción.

Paso 1

Primero, necesitas instalar Node.js porque volo depende de ello. Los usuarios de Windows y Mac pueden descargarlo desde aquí. Pero para los usuarios Linux, les recomendamos usar el gestor de paquetes: instrucciones para la instalación usando el gestor de paquetes en diferentes distribuciones.

Paso 2

Instalar volo utilizando el siguiente comando.

npm install -g volo

Asegúrate de usar  ‘sudo’ antes, en entornos *nix.

Paso 3

Crea un nuevo proyecto fos-todo-app usando el comando ‘volo create’.

volo create fos-todo-app

Esto creará el directorio fos-todo-app y copiará los archivos requeridos del proyecto volo desde GitHub.

Recuerda que trabajaremos solamente con los archivos que están en el directorio fos-todo-app/www. Si nunca antes has trabajado con volo, Optimiza tu proceso con Volo, es una lectura recomendada.

Paso 4

Asegúrate que tienes la última versión estable de Firefox instalada. Luego instala Firefox OS Simulator. Al final de este artículo podrás probar la interfaz de usuario de la aplicación en este simulador.

Paso 5

Descarga e instala la fuente MozTT. MozTT es la fuente usada en Firefox OS. Este es un paso opcional pero es mejor instalar esta fuente en tu sistema, así que puedes tener una apariencia consistente entre Firefox OS Simulator y el teléfono real.

Vista de la lista de tareas

La primera interfaz de usuario que construiremos, mostrará un título en la cabecera, botones de Agregar/Eliminar en el pie de página y una lista de tareas. Esta vista podrá ser usada para visualizar, editar, marcar como completa y eliminar las tareas.


Interfaz inicial de la lista

Agrega el atributo role=”application” al elemento ‘body’ y escribe el siguiente código HTML para la vista Lista de Tareas.

<section id="view-todos" role="region">
  <header>
    <h1>List de tareas</h1>
  </header>
 
  <article class="view-content">
    <ul id="todo-list" class="todo-list reset-list" role="list">
      <li role="listitem">
        <label>
          <input type="checkbox"/>
          <span>Mi tarea 1</span>
        </label>
 
        <input type="text" aria-hidden="true"/>
        <button class="btn edit"><span>Editar</span></button>
      </li>
 
      <li role="listitem">
        <label>
          <input type="checkbox" checked/>
          <span>Mi tarea 2</span>
        </label>
 
        <input type="text" aria-hidden="true"/>
        <button class="btn edit"><span>Editar</span></button>
      </li>
    </ul>
  </article>
 
  <footer>
    <menu role="toolbar">
      <button role="menuitem" class="btn add"><span>Agregar</span></button>
      <button role="menuitem" class="btn del" disabled><span>Eliminar</span></button>
    </menu>
  </footer>
</section><!--fin de la vista-->

Cada vista es asignada a un role=”region”. Dentro de la vista, puedes tener un header, footer y cualquier elemento contenedor que tengan la clase view-content que tendrá el contenido de la vista.

En la parte superior del contenido de la vista, tenemos ul[role=list] que contiene tareas ingresadas por el usuario. Para propósito de pruebas, agregamos dos tareas sencillas para que puedas entender cada estructura de los ítems de la lista (li[role=listitem]). Dentro de cada ítem de la lista, tenemos un elemento label conteniendo un <input type=”checkbox”> y un elemento span conteniendo el texto de la tarea. El segundo elemento en lista de ítems contiene un elemento <input type=”text”> que está inicialmente oculto usando el atributo aria-hidden=”true”. Finalmente el tercer elemento es .btn.edit (botón para editar).

Nota: Claro que no es magia. Escribiremos CSS para todos estos atributos. Echa un vistazo a ARIA y la mejora progresiva, si eres nuevo en WAI-ARIA.

El propósito de poner el label en el ítem de la lista es para mostrar cada nombre de tarea y el input[type=text] (que inicialmente está oculto) será usado para editar ese texto. Cualquier tarea puede iniciar el modo de edición cuando el usuario pulse en .btn.edit (botón de editar). Igualmente, las tareas pueden ser “marcadas como completadas” cuando el usuario pulse en el label.

En el footer, tenemos un menu[role=toolbar] conteniendo los botones Agregar/Eliminar. Luego, usando CSS para esos botones, mostraremos un ícono svg en el fondo y ocultamos un span interno en cada uno.

Vista de Agregar

La segunda y última vista en nuestra aplicación será usado para agregar tareas a la lista de tareas.

Vista de agregar

En esta vista tenemos un caja de texto para ingresar el nombre de la tarea, y un enlace de contacto que será usado para agregar el número de contacto usando Web Activities. Aquí está el HTML para la vista Agregar.

<section id="view-add" role="region">
  <header>
    <h1>[+] Lista de tareas</h1>
  </header>
 
  </section><section class="view-content">
    <div class="wrapper">
      <menu class="options">
        <ul id="activities" class="reset-list" role="list">
          <li role="listitem"><a href="#"><label for="task">[Insertar Contacto]</label></a></li>
        </ul>
      </menu>
 
      <form aria-owns="btn-add-done">
        <input type="text" name="task" id="task" required/>
      </form>
    </div>
  </section>
 
  <footer>
    <menu role="toolbar">
      <button id="btn-add-done" role="menuitem" class="btn done" disabled><span>Done</span></button>
      <button role="menuitem" class="btn del"><span>Cancelar</span></button>
    </menu>
  </footer>
<!--fin de la vista Agregar-->

Ten en cuenta que el contenido en section.view-content está envuelto usando div.wrapper, as que podemos limitar su max-width y alinearlo a la derecha de menu.option.

La segunda cosa a tener en cuenta aquí es el atributo aria-owns en el elemento form. Este atributo relaciona el form con btn-add-done.

Estilos de los elementos

Vamos a escribir el CSS para los elementos HTML. Se da una explicación en los comentarios encima de cada selector.

/* Estirar verticalmente */
html, body { height: 100%; }
body {
  background: radial-gradient(ellipse at center, rgba(231,76,60,1) 0%,rgba(192,57,43,1) 100%);
  color: #fff;
  font-family: MozTT, sans-serif;
  /* Restablecer el tamaño base */
  font-size: 16px;
  /* Establecer el tamaño relativo de la fuente al tamaño base */
  /* Lee sobre cómo usar rem &lt;a href="http://snook.ca/archives/html_and_css/font-size-with-rem"&gt;this&lt;/a&gt; */
  font-size: 1.4rem;
  font-weight: 300;
  /* Quitar el espaciado */
  margin: 0;
}
h1, h2, h3, h4, h5, h6 { font-weight: 300; }
h1 { font-size: 3rem; }
a {
  color: #FFA49E;
  text-decoration: none;
  text-shadow: 0px 1px 1px rgba(0,0,0,.3);
}
a:hover { color: #fff; }
input, button, select, textarea {
  border-radius: 0;
  box-shadow: none;
}
input[type=text], textarea, select {
  border: none;
  font-family: MozTT, sans-serif;
  font-size: 1.3rem;
  font-weight: 300;
  padding: .7rem .8rem;
}

Estilos específicos para las vistas

#view-todos &gt; .view-content {
  margin-left: 0;
  margin-right: 0;
}
#view-add &gt; .view-content {
  margin-top: 2rem;
}
#view-add &gt; .view-content &gt; .wrapper {
  overflow: hidden;
  margin: 0 auto;
  max-width: 800px;
  width: 100%;
}
#view-add input[name=task] {
  width: 100%;
}
#view-add .options {
  margin: 0 0 .5rem 0;
  text-align: right;
}
#view-add .options [role=listitem] {
  margin: .5rem 0;
}
#view-add .options a {
  padding: .4rem;
}

Estilos de módulo

Módulo de vista

/* Todas las vistas tienen un role=region para seleccionarlos con el selector de atributos  */
[role=region] {
  background: radial-gradient(ellipse at center, rgba(231,76,60,1) 0%,rgba(192,57,43,1) 100%);
  /* Estirar tanto vertical como horizontalmente */
  top: 0; right: 0; bottom: 0; left: 0;
  position: fixed;
  overflow-x: hidden;
}
[role=region] &gt; header {
  margin: .5rem 0 1rem 0;
  text-align: center;
}
[role=region] &gt; header &gt; h1 {
  margin: 0;
  text-shadow: 0px 1px 1px rgba(0,0,0,.4);
}
[role=region] &gt; .view-content {
  margin: 0 1rem 4rem 1rem;
}
[role=region] &gt; footer {
  background: rgba(0,0,0,.2);
  right: 0; bottom: 0; left: 0;
  position: fixed;
  text-align: center;
}
[role=region] &gt; footer &gt; menu[role=toolbar] {
  margin: 0;
  padding: 0;
}

Módulo de botón

.btn {
border: none;
width: 3.5rem;
height: 3.5rem;
}
.btn &gt; span {
display: none;
}
.btn:disabled {
opacity: .2;
}
.btn.done {
background: url(../img/check.svg) no-repeat center center;
}
.btn.add {
background: url(../img/add.svg) no-repeat center center;
}
.btn.del {
background: url(../img/del.svg) no-repeat center center;
}
.btn.edit {
background: url(../img/edit.svg) no-repeat center center;
}
.btn:hover {
background-color: rgba(255,255,255,.1);
}

Módulo de lista de tareas

.todo-list &gt; li {
  border-bottom: 1px solid rgba(255,255,255,.1);
  position: relative;
}
.todo-list &gt; li &gt; .btn {
  top: 0; right: 0;
  position: absolute;
  height: 3.9rem;
}
.todo-list label {
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
  display: block;
  padding: 1rem 2.8rem 1rem 1rem;
}
.todo-list &gt; li:last-child,
.todo-list &gt; li:last-child &gt; label {
  border-bottom: none;
}
.todo-list label &gt; span {
  transition: all .5s;
}
/***
 Este selector es interesante. Agrega un línea transversal y disminuye
 la opacidad del texto en el span cuando el checkbox está seleccionado
***/
.todo-list input[type=checkbox]:checked + span {
  text-decoration: line-through;
  opacity: .4;
}
.todo-list &gt; li &gt; input[type=text] {
  margin: .4rem;
  /* remover el relleno y margin del input desde 100% */
  width: calc(100% - 2.3rem);
}

Estilos de utilidad

.reset-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
[aria-hidden=true] {
  display: none !important;
}

Animaciones

Los siguientes son unos pocos efectos de animación que usaremos para nuestras vistas. Aunque vamos a usar Zepto.js que en tiempo de ejecución genera animaciones CSS3 usando JavaScript,  preferimos escribir animaciones propias usando CSS3 y hacer uso de ellas aplicando y quitando clases CSS en los elementos del DOM.

Zepto es una librería JavaScript minimalista para navegadores modernos compatible con el API de jQuery. Si usas jQuery, ya sabes cómo usar Zepto. – zepto.com

Echa un vistazo al tutorial Cómo usar animaciones CSS para entender mejor las animaciones CSS3.

.slide-up-in {
  animation-name: slide-up-in;
  animation-duration: .6s;
  transform: translateY(0%);
  opacity: 1;
}
@keyframes slide-up-in {
  0% { transform: translateY(30%); opacity: 0; }
  100% { transform: translateY(0%); opacity: 1; }
}
.slide-down-out {
  animation-name: slide-down-out;
  animation-duration: .6s;
  transform: translateY(30%);
  opacity: 0;
}
@keyframes slide-down-out {
  0% { transform: translateY(0%); opacity: 1; }
  100% { transform: translateY(30%); opacity: 0; }
}
.slide-right-in {
  animation-name: slide-right-in;
  animation-duration: .6s;
  transform: translateX(0%);
}
@keyframes slide-right-in {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(0%); }
}
.slide-left-out {
  animation-name: slide-left-out;
  animation-duration: .6s;
  transform: translateX(-100%);
}
@keyframes slide-left-out {
  0% { transform: translateX(0%); }
  100% { transform: translateX(-100%); }
}

Probando la aplicación en Firefox OS Simulator

Ventana del simulador

Puedes probar fácilmente la interfaz de usuario desarrollada usando Firefox OS Simulator. Todo lo que necesitas es un archivo manifest.webapp en el directorio principal (fos-todo-app/www). Agrégale el siguiente JSON.

{
  "version": "0.1",
  "name": "Todos",
  "description": "Awesome todo app by iFadey",
  "launch_path": "/index.html",
  "icons": {
    "16": "/img/icons/icon-16.png",
    "48": "/img/icons/icon-48.png",
    "128": "/img/icons/icon-128.png"
  },
  "developer": {
    "name": "Fawad Hassan",
    "url": "http://ifadey.com"
  },
  "installs_allowed_from": ["*"],
  "appcache_path": "/cache.manifest",
  "default_locale": "en"
}

Por el momento no tenemos un icono de la aplicación, pero no te preocupes por eso. Firefox OS agrega un icono por defecto a la aplicación, si no encuentra uno mencionado en el archivo de manifiesto. Ahora, abre el la pestaña del simulador desde Herramientas > Desarrollador Web > Firefox OS Simulator. Luego haz click en el botón Add Directory y selecciona el archivo el archivo de manifiesto en el directorio de la aplicación. Esto agregará nuestra aplicación en el simulador.

todo-in-simulator

Fin de la parte 1

Ahora has empezado con la aplicación de Lista de Tareas con unos pocos pasos. En la siguiente parte, le daremos vida a nuestra aplicación usando JavaScript (Backbone/Zepto). Crearemos un modelo, colección y vistas de Lista de Tareas y por motivos de simplicidad, solamente almacenaremos nuestra colección de tareas en IndexedDB. También vamos a hacer uso de las Web Activities para insertar un número de contacto en texto en la lista de tareas.

The following two tabs change content below.

jorgev

Add-ons Developer Relations Lead at Mozilla
Jorge trabaja para el equipo de complementos de Mozilla, y se dedica a Mozilla Hispano y Mozilla Costa Rica en su tiempo libre. Actualmente está encargado del blog de Mozilla Hispano Labs.