Fries

Fries

Components

UI building blocks

Action bars

Action bars serve as your main navigation throughout your app. These hold the app icon, app title, action buttons, and can also hold tabs.

App icons must be 32px in height. It can have any width though as long as your prototype doesn't break its layout.

Title

<header class="action-bar">
<a href="javascript: void(0);" class="app-icon action">
  <i class="icon-fries"></i>
</a>
<h1 class="title">Title</h1>
</header>

Action bar with Up button

Adding the Up button means that the current screen is not at the top level. The data attribute data-transition="pop" tells Fries that when this button is pressed, the browser's history stack is popped, taking the user back to the previous page or whatever is in the href.

Title

<header class="action-bar">
<a href="javascript: void(0);" class="app-icon action up" data-transition="pop">
  <i class="icon-up-button"></i>
  <i class="icon-fries"></i>
</a>
<h1 class="title">Title</h1>
</header>

Action bar with subtitles

You can also create an action bar with a title and a subtitle

Title Subtitle

<header class="action-bar">
<a href="javascript: void(0);" class="app-icon action">
  <i class="icon-fries"></i>
</a>
<h2 class="title">Title <span class="subtitle">Subtitle</span></h2>
</header>

Action buttons

Action bars can also have buttons in them.

Action Buttons

<header class="action-bar fixed-top">
<a href="javascript: void(0);" class="app-icon action">
  <i class="icon-fries"></i>
</a>
<h1 class="title">Action Buttons</h1>
<ul class="actions pull-right">
  <li><a href="javascript: void(0);" class="action" title="Search"><i class="icon-search"></i></a></li>
  <li><a href="javascript: void(0);" class="action" title="Settings"><i class="icon-settings"></i></a></li>
</ul>
</header>

Action overflows

Currently, in Fries, you can only add a maximum of two (2) action buttons to the action bar when the device width is less than 480 pixels (which will most likely change in future updates to follow the official Android rules for setting overflows) and you have an app icon and title. This is where action overflows come in.

Action overflows automatically convert action buttons into a Spinner when there are more than two buttons in your action bar. Fries will automatically use the value of the button's title attribute to generate a Spinner item. So make sure that you add a title to your action buttons.

Action Overflows

<header class="action-bar fixed-top">
<a href="javascript: void(0);" class="app-icon action">
  <i class="icon-fries"></i>
</a>
<h1 class="title">Action Buttons</h1>
<ul class="actions pull-right">
  <li><a href="javascript: void(0);" class="action" title="Search"><i class="icon-search"></i></a></li>
  <li><a href="javascript: void(0);" class="action" title="Copy"><i class="icon-copy"></i></a></li>
  <li><a href="javascript: void(0);" class="action" title="Cut"><i class="icon-cut"></i></a></li>
  <li><a href="javascript: void(0);" class="action" title="Settings"><i class="icon-settings"></i></a></li>
</ul>
</header>

Bottom-fixed action bars

You can also fix your action bars at the bottom of the page by adding .fixed-bottom class to your action bars.

<nav class="action-bar fixed-bottom">
<ul class="actions flex">
  <li><a href="javascript: void(0);" class="action" title="Map"><i class="icon-location-marker"></i></a></li>
  <li><a href="javascript: void(0);" class="action" title="Calendar"><i class="icon-calendar"></i></a></li>
  <li><a href="javascript: void(0);" class="action" title="Dial"><i class="icon-dial"></i></a></li>
  <li><a href="javascript: void(0);" class="action" title="Hang up"><i class="icon-hang-up"></i></a></li>
</ul>
</nav>

Tabs

Tabs are usually used to navigate between multiple screens.

The following example is rendered by the code below it.

<nav class="tab-fixed">
<ul class="tab-inner">
  <li class="active"><a href="#item1" data-ignore="true">Tab 1</a></li>
  <li><a href="#item2" data-ignore="true">Tab 2</a></li>
  <li><a href="#item3" data-ignore="true">Tab 3</a></li>
</ul>
</nav>

The content that slides when a tab is clicked should follow the following markup. Notice that the href attributes of the tabs above match the id attributes of each .tab-item.

<div class="content">
<div class="slider">
  <ul>
    <li id="item1" class="tab-item active">
      <!-- Any content can go here -->
      <div class="inset">
        <p>Item 1</p>
      </div>
    </li>
    <li id="item2" class="tab-item">
      <!-- Any content can go here -->
      <div class="inset">
        <p>Item 2</p>
      </div>
    </li>
    <li id="item3" class="tab-item">
      <!-- Any content can go here -->
      <div class="inset">
        <p>Item 3</p>
    </li>
  </ul>
</div>
</div>

Buttons

Buttons come in two sizes and supports all button states.

<button class="btn">Normal</button>
<button class="btn-small">Small</button>
<button class="btn focused">Focused Normal</button>
<button class="btn-small focused">Focused Small</button>
<button class="btn active">Pressed Normal</button>
<button class="btn-small active">Pressed Small</button>
<button class="btn focused" disabled>Focused Disabled</button>
<button class="btn-small focused" disabled>Focused Disabled Small</button>
<button class="btn" disabled>Disabled</button>
<button class="btn-small" disabled>Disabled Small</button>

Spinners

Spinners come in handy when you want to save up on horizontal real estate and works like a dropdown UI component. Currently, Fries does not change the value of the selected spinner item. It's up to you to do that for now.

<div class="form-spinner">
<a href="javascript: void(0);" class="toggle-spinner">Home</a>
<ul class="spinner">
<li class="spinner-item"><a href="javascript: void(0);">Work</a></li>
<li class="spinner-item"><a href="javascript: void(0);">Secondary</a></li>
</ul>
</div>

An action overflow is also an example of a spinner.

Lists

Lists can be used to organize your data.

  • Single Line List
  • List item number one
  • Second list item
  • This is the third item and this is a very long line.
<ul class="list inset">
<li class="list-divider">Single Line List</li>
<li class="list-item-single-line">List item number one</li>
<li class="list-item-single-line">Second list item</li>
<li class="list-item-single-line">This is the third item and this is a very long line.</li>
</ul>

2-Line Lists

  • 2 Line List
  • First Item

    Lorem ipsum dolor sit amet.

  • Second Item

    Another list item's description.

<ul class="list inset">
<li class="list-divider">2 Line List</li>
<li class="list-item-two-lines">
  <h3>First Item</h3>
  <p>Lorem ipsum dolor sit amet.</p>
</li>
<li class="list-item-two-lines">
  <h3>Second Item</h3>
  <p>Another list item's description.</p>
</li>
</ul>

Multi Line Lists

  • Multi Line List
  • Multi Line List Item

    Suspendisse potenti. Mauris accumsan consequat urna ut ornare. Nunc velit magna, vulputate ac faucibus eu, laoreet eget eros. Quisque tortor dui, gravida in condimentum non, tempus et nibh. Integer congue felis et diam hendrerit imperdiet. Sed pellentesque, ipsum nec vehicula molestie.

  • Second Multi Line List Item

    Nunc velit magna, vulputate ac faucibus eu, laoreet eget eros. Quisque tortor dui, gravida in condimentum non, tempus et nibh.

<ul class="list inset">
<li class="list-divider">Multi Line List</li>
<li class="list-item-multi-line">
  <h3>Multi Line List Item</h3>
  <p>Suspendisse potenti. Mauris accumsan consequat urna ut ornare. Nunc velit magna, vulputate ac faucibus eu, laoreet eget eros. Quisque tortor dui, gravida in condimentum non, tempus et nibh. Integer congue felis et diam hendrerit imperdiet. Sed pellentesque, ipsum nec vehicula molestie.</p>
</li>
<li class="list-item-multi-line">
  <h3>Second Multi Line List Item</h3>
  <p>Nunc velit magna, vulputate ac faucibus eu, laoreet eget eros. Quisque tortor dui, gravida in condimentum non, tempus et nibh.</p>
</li>
</ul>

Forms

The default style of the form component is at block level. All elements are sitting on its own line.

<form class="inset">
<label class="block-label">Email</label>
<input type="email" name="email" placeholder="Email" class="input-text">
<label class="block-label">Password</label>
<input type="password" name="password" placeholder="Password" class="input-text">
<div class="form-actions">
  <input type="submit" class="btn btn-block" value="Submit">
  <button type="button" class="btn btn-block">Cancel</button>
</div>
</form>

Flexible Forms

Flexible forms utilize the layout mode flexbox to fill out each elements parent container either growing to fill unused space or shrinking to avoid overflowing the parent. You can use this form layout by adding the form-flex class to the <form> tag.

In a Fries prototype, elements inside a flex-group container are flexible by default.

<form class="form-flex inset">
<label class="block-label">Full Name</label>
<div class="flex-group">
  <input type="text" placeholder="First Name" class="input-text flex1">
  <input type="text" placeholder="Last Name" class="input-text flex1">
</div>
<label class="block-label">Address</label>
<div class="flex-group">
  <input type="text" placeholder="Address" class="input-text flex2">
  <div class="form-spinner">
    <a href="javascript: void(0);" class="toggle-spinner">Home</a>
    <ul class="spinner">
      <li class="spinner-item"><a href="javascript: void(0);">Work</a></li>
      <li class="spinner-item"><a href="javascript: void(0);">Secondary</a></li>
    </ul>
  </div>
</div>
</form>

You can use the classes flex1, flex2, and flex3 to tell how each form element flexes and just remove them if you want to fill the whole line.

<form class="form-flex">
<div class="flex-group">
  <input type="text" placeholder="Full Name" class="input-text">
</div>
<div class="flex-group">
  <input type="text" placeholder="Flex 1" class="input-text flex1">
  <input type="text" placeholder="Flex 2" class="input-text flex2">
</div>
</form>

Dialogs

A dialog is a small window that prompts the user to make a decision or enter additional information. A dialog does not fill the screen and is normally used for modal events that require users to take an action before they can proceed.

The .dialogs container must be on the same level as .action-bar and .tab-fixed. This container holds all your dialogs.

<!-- Button to show the dialog -->
<a href="javascript: void(0);" class="btn" id="show-dialog">Show Dialog</a>

<!-- Required container for dialogs -->
<div class="dialogs">
<div id="my-dialog" class="dialog">
  <header class="dialog-title-region">
    <h1 class="title">Hello Fries</h1>
  </header>
  <div class="dialog-content">
    <p>Hi, I'm a dialog.</p>
  </div>
  <ul class="dialog-actions">
    <li><a href="javascript: void(0);" class="dialog-cancel-button">Cancel</a></li>
    <li><a href="javascript: void(0);" class="dialog-ok-button">OK</a></li>
  </ul>
</div>

<!-- Other dialogs go here -->
</div>

Then in your JavaScript code:

var dialog = new fries.Dialog({
selector: '#my-dialog',
callbackOk: function () {
  // Do something here
  this.hide(); // hide the dialog
},
callbackCancel: function () {
  // Do nothing, the user cancelled
  this.hide(); // hide the dialog
}
});

Then show the dialog with:

dialog.show();

Toast Notifications

A Toast notification provides a subtle feedback to the users that something happened.

The good thing about Toast notifications in Fries is that no markup is needed, just JavaScript. Check out the following code to see how to create Toast notifications:

// Add this to a 'click' or 'touchend' event of a button
var toast = new fries.Toast({ content: "Message saved as draft." });

Pretty cool right? The code above creates a Toast notification with the message "Message saved as draft" and shows it to the user.

You can also change the duration which the Toast is show by passing the length (in milliseconds) or by using either fries.Toast.duration.SHORT or fries.Toast.duration.LONG as a parameter when creating your Toast notifications.

// A short Toast lasts 3 seconds
var shortToast = new fries.Toast({
content: "I'm a short Toast.",
duration: fries.Toast.duraton.SHORT
});

// A long one lasts 5 seconds
var longToast = new fries.Toast({
content: "I'm a long Toast.",
duration: fries.Toast.duration.LONG
});

// Or custom timing
var custom = new fries.Toast({
content: "Custom Toast",
duration: 7500 // in milliseconds
});

Helpers

There are a few helpers that you might want to take note of when you're creating Fries prototypes.

Inset

The .inset class adds a 15px padding to all sides of a container.

Selectable

The .selectable class adds a highlight to an element when it's in its active state. This is usually added to list items so they get highlighted when clicked or touched.

Pretty Input

By default, Fries styles text boxes such as <input type="text"> just as how they would normally look in a native Android app. This is done by wrapping these elements in <span class="input-pretty"></span>. This span adds those small lines on the edges of the element. However, you can turn this feature off by excluding forms.js in your build.

Stack.js

Stack.js is an engine adapted from Ratchet's push.js to seamlessly piece together Fries pages. It dynamically loads HTML on the fly and inserts it to your app. This works by firing an AJAX request to get the target HTML and replacing the contents of .page div.

Same as push.js, stack.js uses the HTML5 History API so the Android device's back button functionality doesn't break.

<!-- An action button that inserts map.html's .page into the current page's .page -->
<a href="map.html" class="action" title="Map"><i class="icon-location-marker"></i></a>

You can also specify the transition by adding the data-transition attribute. You can choose from push and pop transitions when stacking pages.

<!-- An action button that pushes map.html -->
<a href="map.html" class="action" title="Map" data-transition="push"><i class="icon-location-marker"></i></a>

Since Stack.js listens for all touches, some of your links might not work. To solve this, you can add the data attribute data-ignore="true" so Stack.js ignores that link.

You may, however, use your own paging engine for your prototypes. Just exclude Stack.js from your build and run your app normally. You'll lose the page animations this way though.

Choose ringtone