Originally, Phonon has been created for building hybrid apps with Apache Cordova by using web technologies such as HTML, CSS and JavaScript. Of course, there are many frameworks well known, but Phonon gives an intuitive and amuzing way of building apps. For example, the app's workflow can be defined with page events. When the user access on the page-X for the first time, the onCreate callback is called, when the page becomes visible, the onReady callback is called, etc. You can also prevent the automatic close if an action is required.
Furthermore, this framework is also an UI framework proposing many features that are generic, which means they don't differ from mobile platforms. On the other hand, you can define your style according to the platform, because Phonon adds the OS class in the body tag.
phonon-core.js is only 23 kB! This file is the minimal file for running Phonon with basic CSS only components. Then you can load each component that you need. In this table, we compare Phonon to other frameworks with the file named phonon.js which contains the entire framework.
Framework | Version | Minified Size | Size with required dependencies |
---|---|---|---|
Ionic | 1.1.0 | 209.4 kB (ionic.js, ionic-angular.js) | 414.5 kB (ionic-bundle.js) |
OnSenUI | 1.3.8 | 265.6 kB | 535.1 kB |
Framework7 | 1.2.0 | 253.8 kB | 253.8 kB |
Phonon | 1.0.0 | 62.1 kB ♥ | 62.1 kB ♥ |
Phonon + Riot | 1.0.0 - 2.2.4 | # | 74.85 kB |
Phonon + Angular | 1.0.0 - 1.4.3 | # | 207.6 kB |
Phonon + React | 1.0.0 - 1.4.3 | # | 183.6 kB |
Phonon takes care to act in a native way with active UI components. One practical example is if a dialog box is opened and the user clicks on the back button on Android, instead of going back to the previous page, the event controller will close the active dialog automatically.
Furthermore, you can define page event callbacks in order to organize tasks at a specific moment. The Navigator module is the master of page events: onCreate, onReady, onTransitionEnd, onClose, onHidden, etc. OnCreate is called when the page is first created. This is where you should do all of your normal static set up (this callback is called once). onReady is called every time the page becomes visible to the user, onClose is called only if data-prevent-close is true, this permits to prevent the page close if we want to keep the user on the same page (for example to accept conditions before using the app).
Phonon does not use and does not depend on any third party libraries.
Choose the right framework according to your needs and your project's size! You are free to use React, Vue, Angular, jQuery, Zepto, Riot, etc.
Example of a tag with page events:
<home class="app-page">
<div class="content">
<p class="padded-full">{title}</p>
</div>
<script>
this.title = 'Hello World!'
this.on('create', function() { })
this.on('ready', function() { })
this.on('transitionend', function() { })
this.on('close', function(self) { self.close(); })
this.on('hidden', function() { })
this.on('hash', function(req) { })
this.on('tabchanged', function(tabNumber) { })
</script>
</home>
Angular's hash prefix (#/!) is supported.
If you use Angular, please see our example.
Hybrid apps tend to be sluggish and poorly designed. The native look and feel is an important point.
The i18n module loads the user's language if the file is available otherwise it will load the default app's language. Then it binds HTML templates where data-i18n attributes are present.
Phonon is friendly with PhoneGap / Cordova. It supports the back button for example and can be optionally started after the device ready event.
Since the version 1.0.0 released on 2015 August, you can build both Web Apps and Hybrid Apps.
The MIT License is a permissive free software license. Phonon is completely open source. Build free or paid apps!
When the user changes the app's language, simply call updateLocale() in order to update your app.
Use the grid system in order to create smartphone and tablet layouts with the default 12-column.
Side panels can be exposed on tablet screens and closed by default on mobile screens.
Phonon uses Stylus to compile CSS files and Gulp as a streaming build system.
Modify stylus variables, then compile your custom CSS.
Android | iOS | IE | Chrome | Firefox | Opera |
---|---|---|---|---|---|
4.1+ | 7+ | 10+ | 30+ | 10+ | 12+ |
IE9 is supported partially, you need the following polyfills:
Dear developer, if your device or OS/Browser's version is not in the list, please open an issue on Github or contact the lead developer so that we can add it in the list!
Android:
iOS:
Browsers:
As a 100% free open-source project, developer participation is encouraged, as much or little as possible.
Fork it, open issues and star the project!
If this framework saved your day and you wish to support future developments you may consider sending some funds via PayPal.
$ cordova create hello com.example.hello HelloWorld
Add Platforms
$ cd hello
$ cordova platform add ios
$ cordova platform add android
...
You have the choice between several ways to install Phonon:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" />
<link rel="stylesheet" href="../../dist/css/phonon.css" />
<title>App</title>
</head>
<body>
<!-- Panel tags go here -->
<!-- Side Panel tags go here -->
<!-- Notification tags go here -->
<!-- Dialog tags go here -->
<!-- Popover tags go here -->
<!-- the home page is the default one. This page does not require to call its content because we define on its tag.-->
<home data-page="true">
<header class="header-bar">
<div class="center">
<h1 class="title">Phonon Example</h1>
</div>
</header>
<div class="content">
<ul class="list">
<li class="divider">Select a pizza</li>
<li><a class="padded-list" href="#!pagetwo/margherita">Margherita</a></li>
<li><a class="padded-list" href="#!pagetwo/calzone">Cheese Calzone</a></li>
<li><a class="padded-list" href="#!pagetwo/pesto">Pesto Pizza</a></li>
<li><a class="padded-list" href="#!pagetwo/roma">Roma</a></li>
<li><a class="padded-list" href="#!pagetwo/prosciutto">Prosciutto</a></li>
<li><a class="padded-list" href="#!pagetwo/funghi">Funghi</a></li>
</ul>
</div>
</home>
<!-- for the second page, Phonon will load its content. -->
<pagetwo data-page="true"></pagetwo>
<!-- scripts -->
<script src="../../dist/js/phonon.js"></script>
<!-- our app config -->
<script src="app.js"></script>
</body>
</html>
phonon.options({
navigator: {
defaultPage: 'home',
animatePages: true,
enableBrowserBackButton: true,
templateRootDirectory: './tpl'
},
i18n: null // for this example, we do not use internationalization
});
var app = phonon.navigator();
/**
* The activity scope is not mandatory.
* For the home page, we do not need to perform actions during
* page events such as onCreate, onReady, etc
*/
app.on({page: 'home', preventClose: false, content: null});
/**
* However, on the second page, we want to define the activity scope.
* [1] On the create callback, we add tap events on buttons. The OnCreate callback is called once.
* [2] If the user does not tap on buttons, we cancel the page transition. preventClose => true
* [3] The OnReady callback is called every time the user comes on this page,
* here we did not implement it, but if you do, you can use readyDelay to add a small delay
* between the OnCreate and the OnReady callbacks
*/
app.on({page: 'pagetwo', preventClose: true, content: 'pagetwo.html', readyDelay: 1}, function(activity) {
var action = null;
var onAction = function(evt) {
var target = evt.target;
action = 'ok';
if(target.getAttribute('data-order') === 'order') {
phonon.alert('Thank you for your order!', 'Dear customer');
} else {
phonon.alert('Your order has been canceled.', 'Dear customer');
}
};
activity.onCreate(function() {
document.querySelector('.order').on('tap', onAction);
document.querySelector('.cancel').on('tap', onAction);
});
activity.onClose(function(self) {
if(action !== null) {
self.close();
} else {
phonon.alert('Before leaving this page, you must perform an action.', 'Action required');
}
});
activity.onHidden(function() {
action = null;
});
activity.onHashChanged(function(pizza) {
document.querySelector('.pizza').textContent = pizza;
});
});
// Let's go!
app.start();
<pagetwo class="app-page">
<header class="header-bar">
<div class="left">
<button class="btn pull-left icon icon-arrow-back" data-navigation="$previous-page"></button>
<h1 class="title">Page Two</h1>
</div>
</header>
<div class="content">
<div class="padded-full">
<h2>Order</h2>
<p>1x Pizza: <span class="pizza"></span></p>
<p class="message"></p>
<button class="btn negative cancel" data-order="cancel">Cancel</button>
<button class="btn btn-flat primary order" data-order="order">Order</button>
</div>
</div>
</pagetwo>
<script>
/*
* JavaScript code can be executed when the template is loaded
*/
</script>
Your app is configured and ready to be launched. Phonon does the rest for you.
You are now invited to → read the docs in order to use the Phonon framework like a boss.
For example how to use more options, exposed side panel on tablets, etc..
Feel free to contribute to Phonon, we need your support as it is an open source project.
Open an issue, star and fork this project on Github (very important :) )