diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..a39adc34
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+# IDE & System Related Files #
+.buildpath
+.editorconfig
+.project
+.settings
+.DS_Store
+.idea
+.vscode
+
+node_modules/
+bower_components/
diff --git a/Gruntfile.js b/Gruntfile.js
new file mode 100644
index 00000000..4d21f0aa
--- /dev/null
+++ b/Gruntfile.js
@@ -0,0 +1,216 @@
+module.exports = function (grunt) {
+ if (grunt.file.exists('settings-custom.yaml')) {
+ // We have a custom setup
+ var settings = grunt.file.readYAML('settings-custom.yaml');
+ console.log('Custom settings supplied')
+ } else {
+ // We will use the default options
+ var settings = grunt.file.readYAML('settings.yaml');
+ }
+
+ // Load required modules
+ grunt.loadNpmTasks('grunt-contrib-cssmin');
+ grunt.loadNpmTasks('grunt-babel');
+ grunt.loadNpmTasks('grunt-browserify');
+ grunt.loadNpmTasks('grunt-sass');
+ grunt.loadNpmTasks('grunt-shell');
+ grunt.loadNpmTasks('grunt-contrib-copy');
+ grunt.loadNpmTasks('grunt-contrib-uglify');
+
+ // Cleanup process
+ grunt.registerTask('clearFiles', 'Clean up', function () {
+ settings.elements.forEach(function (element) {
+ // Remove the non minified css
+ if (grunt.file.exists("dist/css/" + element + ".css")) {
+ grunt.file.delete("dist/css/" + element + ".css");
+ }
+ if (grunt.file.exists('elements/' + element + '/' + element + '_es6.js')) {
+ grunt.file.delete('elements/' + element + '/' + element + '_es6.js');
+ }
+ });
+ });
+
+ // Create WebComponents elements
+ grunt.registerTask('createHtml', 'Create Html version of the elements', function () {
+ settings.elements.forEach(function (element) {
+
+ if (grunt.file.exists('dist/js/' + element + '.min.js')) {
+ // Compose the element as .html
+ var tmpOutput = '';
+ tmpJs = grunt.file.read('dist/js/' + element + '.min.js');
+ tmpOutput += '';
+ tmpOutput += '';
+
+ // Write the Custom element
+ grunt.file.write('dist/html/' + settings.prefix + '-' + element + '.html', tmpOutput);
+ }
+ });
+ });
+
+ grunt.registerTask('default', function () {
+ String.prototype.capitalizeFirstLetter = function () {
+ return this.charAt(0).toUpperCase() + this.slice(1);
+ }
+
+ // Compile the css files
+ var compileCss = function(element) {
+ grunt.config.set('sass.' + element + '.files', [{
+ src: 'elements/' + element + '/' + element + '.scss',
+ dest: 'dist/css/' + element + '.css'
+ }]);
+
+ grunt.task.run('sass:' + element);
+
+ grunt.config.set('cssmin.' + element + '.files', [{
+ src: 'dist/css/' + element + '.css',
+ dest: 'dist/css/' + settings.prefix + '-' + element + '.min.css'
+ }]);
+
+ grunt.task.run('cssmin:' + element);
+
+ // Put a copy in the demo folder
+ grunt.config.set('copy.' + element + '-css-s' + '.files', [{
+ src: 'dist/css/' + settings.prefix + '-' + element + '.min.css',
+ dest: 'demo/css/' + settings.prefix + '-' + element + '.min.css'
+ }]);
+
+ grunt.task.run('copy:' + element + '-css-s');
+
+ // Put a copy in the demo folder
+ grunt.config.set('copy.' + element + '-css' + '.files', [{
+ src: 'dist/css/' + settings.prefix + '-' + element + '.min.css',
+ dest: 'docs/_media/css/' + settings.prefix + '-' + element + '.min.css'
+ }]);
+
+ grunt.task.run('copy:' + element + '-css');
+ };
+
+ // Create the custom element
+ var createElement = function(element, settings) {
+ var tmpJs = '', tmpJsPlain = '';
+
+ if (grunt.file.exists('elements/' + element + '/' + element + '.js')) {
+ tmpJs = grunt.file.read('elements/' + element + '/' + element + '.js');
+
+ // Repeat
+ tmpJs = grunt.file.read('elements/' + element + '/' + element + '.js');
+ tmpJs = tmpJs.replace(/{{REGISTERELEMENT}}/g, settings.prefix + '-' + element);
+ tmpJs = tmpJs.replace(/joomla-/g, settings.prefix + '-');
+ grunt.file.write('elements/' + element + '/' + element + '_es6.js', tmpJs);
+
+ // // As Web components (with shadow dom)
+ // grunt.config.set('shell.' + element, {
+ // command: 'browserify elements/' + element + '/' + element + '_a.js -o dist/js/' + element + '.min.js'
+ // });
+
+ // grunt.task.run('shell:' + element);
+
+ grunt.config.set('browserify.options', {
+ "transform": [
+ [
+ "babelify",
+ {
+ "presets": [
+ "es2015",
+ "babili"
+ ],
+ "plugins": [
+ "static-fs"
+ ]
+ }
+ ]
+ ]
+ });
+
+ // As custom elements (plain Js and css)
+ grunt.config.set('browserify.' + element + '.files', [{
+ dest: 'dist/js/' + settings.prefix + '-' + element + '.js',
+ src: 'elements/' + element + '/' + element + '_es6.js',
+ }]);
+
+ grunt.task.run('browserify:' + element);
+
+ // Uglify the scripts
+ grunt.config.set('uglify.' + element + '-js' + '.files', [{
+ src: ['dist/js/' + settings.prefix + '-' + element + '.js', '!dist/js/' + settings.prefix + '-' + element + '.min.js'],
+ dest: '',
+ ext: '.min.js',
+ expand: true
+ }]);
+
+ grunt.task.run('uglify:' + element + '-js');
+
+ // Put a copy in the demo folder
+ grunt.config.set('copy.' + element + '-js-a' + '.files', [{
+ src: 'dist/js/' + settings.prefix + '-' + element + '.min.js',
+ dest: 'demo/js/' + settings.prefix + '-' + element + '.min.js'
+ }]);
+
+ grunt.task.run('copy:' + element + '-js-a');
+
+ // Put a copy in the docs folder
+ grunt.config.set('copy.' + element + '-js' + '.files', [{
+ src: 'dist/js/' + settings.prefix + '-' + element + '.min.js',
+ dest: 'docs/_media/js/' + settings.prefix + '-' + element + '.min.js'
+ }]);
+
+ grunt.task.run('copy:' + element + '-js');
+ }
+ };
+
+ console.log('Build the custom Elements')
+ settings.elements.forEach(function (element) {
+ // Create the css for each element
+ compileCss(element);
+
+ // Create elements as html files, compatible with document-register-element polyfill
+ createElement(element, settings);
+
+ });
+
+ // Create elements as html files
+ // grunt.task.run('createHtml');
+
+ // Copy polyfills in dist and demo folders
+ if (grunt.file.exists('node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js')) {
+ var tmpPloyfillJs = grunt.file.read('node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js');
+
+ tmpPloyfillJs = tmpPloyfillJs.replace(/\(function \(\) {\n'use strict';\n\n/, '')
+ .replace(/(\n\n\/\*(?:(?!\*\/).|[\n])*\*\/\s\n}\(\)\);\n)/g, '').replace(/\;$/, '');
+
+ if (grunt.file.exists('elements/wc-loader.js')) {
+ var polyfill = grunt.file.read('elements/wc-loader.js');
+
+ polyfill = polyfill.replace('{{POLYFILL_JS}}', tmpPloyfillJs);
+
+ grunt.file.write('dist/polyfills/wc-loader.js', polyfill);
+ }
+
+var polyfills = ['webcomponents-hi-ce', 'webcomponents-hi-sd-ce', 'webcomponents-hi', 'webcomponents-lite', 'webcomponents-loader', 'webcomponents-sd-ce'];
+
+polyfills.forEach(function(polyfill, item) {
+ // Put a copy of webcomponentjs polyfills in the dist folder
+ grunt.config.set('copy.' + item + '.files', [{
+ src: 'node_modules/@webcomponents/webcomponentsjs/' + polyfill + '.js',
+ dest: 'dist/polyfills/' + polyfill + '.js'
+ }]);
+
+ grunt.task.run('copy:' + item);
+})
+
+
+ // Uglify the polyfills
+ grunt.config.set('uglify.polyfills-js.files', [{
+ src: ['!dist/polyfills/*.min.js', 'dist/polyfills/*.js'],
+ dest: '',
+ ext: '.min.js',
+ expand: true
+ }]);
+
+ grunt.task.run('uglify:polyfills-js');
+ }
+
+ // Do the clean up
+ grunt.task.run('clearFiles');
+ });
+};
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..fbad9f70
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Dimitrios Grammatikogiannis
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..4780a4fd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,40 @@
+# Joomla UI custom elements
+
+[![Built with Grunt](https://cdn.gruntjs.com/builtwith.svg)](http://gruntjs.com/)
+
+### UI components using modern technologies
+
+This is a collection of all the components that Joomla is using. They are developed with the new W3C standard: custom elements. Each component is using plain and optimized javascript for performance. Also the HTML markup (wherever possible) is reduced to offer a great convinience for front end developers).
+
+### Using the NPM power
+
+You can install this package by using NPM:
+```bash
+$ npm install joomla-custom-elements --save
+```
+
+### Configuration
+
+The prefix of all the elements is configuarable, to do so duplicate the file `settings.yaml` and name the new file as `settings-custom.yaml`. Open the file in your editor and change the prefix to your taste. (it needs to be one word check the W3C speifications for valid custom element naming).
+Build your custom elements by executing:
+```bash
+$ grunt
+```
+The folder named `dist` contains all your elements.
+
+### Usage
+
+For each component that you need to have available in your page you need to add the custom element in the head of the document:
+```html
+
+
+```
+
+### Browser support
+
+Although all the major browsers are **committed** to support custom elements some of the **all green browsers** do need a polyfill. The polyfills can be found in the dist folder and are created by the Polymer team (Polymer is a Google project).
+The repo for the actual polyfill is: https://github.com/webcomponents/webcomponentsjs
+
+### License
+
+The library is released under the [MIT license](LICENSE)
diff --git a/bower.json b/bower.json
new file mode 100644
index 00000000..c3f46506
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,22 @@
+{
+ "name": "joomla-ui-custom-elements",
+ "version": "0.0.1",
+ "description": "Joomla UI components as custom elements",
+ "main": "Gruntfile.js",
+ "authors": [
+ "Dimitrios Grammatikogiannis"
+ ],
+ "license": "MIT",
+ "keywords": [
+ "Joomla",
+ "web-component",
+ "web-components",
+ "custom-element",
+ "custom-elements"
+ ],
+ "devDependencies": {
+ "web-component-tester": "^6.0.0 ",
+ "webcomponentsjs": "^1.0.0",
+ "test-fixture": "^3.0.0-rc.1"
+ }
+}
diff --git a/demo/alert-bootstrap-demo.html b/demo/alert-bootstrap-demo.html
new file mode 100644
index 00000000..96d1f0c7
--- /dev/null
+++ b/demo/alert-bootstrap-demo.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+ Bootstrap
+
+
+
+
+
+
+
+
+
Alerts
+No params passed
+
+ Heads up! This alert needs your attention, but it's not super important.
+
+
+ Well done! You successfully read this important alert message.
+
+
+ Warning! This one will self distruct in 10secs.
+
+
+ Oh snap! Click open to go to Google.com
+
+
+ Advanced! Let's call a callback function!
+
+