JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<div ng-controller="SampleCtrl">
<table>
<thead>
<tr>
<td data-ng-repeat="(key,value) in data[0]" data-ng-bind="(key|uppercase)" align="center"></td>
<td>
<!--triggerButton invocation-->
<trigger-button data-ng-model="protected" class="dangerous-trigger" data-action="somethingDangerous()">
<i class="fa fa-trash" aria-hidden="true"></i>
</trigger-button>
</td>
</tr>
</thead>
<tbody data-ng-class="{'shake': !protected&&shake,'unprotected':!protected }">
<tr data-ng-repeat="row in data">
<td data-ng-repeat="(key, value) in row" data-ng-bind="value" data-ng-align="{'center':typeof(value)=='string','left':typeof(value)!='string'}"></td>
<td align="center"></td>
</tr>
</tbody>
</table>
<div>
<label ng-if="protected">Click the trash button</label>
<label ng-if="!protected">Click "cancel", or press esc,<br/> or wait 5 second to deactivate,<br> or click trash again to proceed.</label><br/><br/>
<label>Shake those</label><input id="shake-switch" type="checkbox" ng-model="shake"/>
</div>
</div>
CSS
/*Structural */
button {
font-size: 1rem;
}
.dangerous-trigger button {
transition: all 0.5s ease;
}
.dangerous-trigger .container {
display: flex;
width: 43px;
overflow: hidden;
padding:0px;
}
.dangerous-trigger.unlocked button:first-child {
margin-left: -22px;
}
/*Skin*/
/*Shaking of the rows */
.unprotected tr {
background:#FF6202;
}
table {
float:left;
}
table+div {
float:left;
padding:10px;
}
table thead td+td{
border-left: 1px solid black;
}
table thead td {
border-bottom: 1px solid black;
}
table {
border:1px solid black;
border-collapse: separate;
border-spacing: 0;
}
table td {
margin:0px;
padding:5px;
}
.shake>*{
-webkit-animation-name: spaceboots;
-webkit-animation-duration: 0.8s;
-webkit-transform-origin:20% 20%;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
.shake>*:nth-child(7n+5){
-webkit-animation-delay: 0.3s;
}
.shake>*:nth-child(5n+3){
-webkit-animation-delay: 0.1s;
}
.shake>*:nth-child(3n+2){
-webkit-animation-delay: 0.2s;
}
@-webkit-keyframes spaceboots {
0% { -webkit-transform: translate(2px, 1px) rotate(0deg); }
10% { -webkit-transform: translate(-1px, -2px) rotate(-0.1deg); }
20% { -webkit-transform: translate(-1px, 0px) rotate(0.1deg); }
30% { -webkit-transform: translate(0px, 2px) rotate(0deg); }
40% { -webkit-transform: translate(1px, -1px) rotate(0.1deg); }
50% { -webkit-transform: translate(-1px, 2px) rotate(-0.1deg); }
60% { -webkit-transform: translate(-1px, 1px) rotate(0deg); }
70% { -webkit-transform: translate(2px, 1px) rotate(-0.1deg); }
80% { -webkit-transform: translate(-1px, -1px) rotate(0.1deg); }
90% { -webkit-transform: translate(2px, 2px) rotate(0deg); }
100% { -webkit-transform: translate(1px, -2px) rotate(-0.1deg); }
}
JavaScript
/*
Example of trigger button with two states with inverted colors, charged button is uncharging after 5 second .
*/
/**
* @directive triggerButton
* @description two states button that makes modal dialog obsolete
* @params ngModel - protected state : true - locked, false - unlocked
*/
angular.module('TriggerButton',[]).directive('triggerButton',
function($timeout, $document) {
return {
restrict: 'AE',
require: '?ngModel',
transclude: true,
template:"<div class='container' style=''>" +
"<button ng-click='lock()' class='fa fa-ban cancel btn btn-info btn-xs' ></button>" +
"<button ng-click='clicked($event)' ng-transclude class='trigger btn btn-danger btn-xs'>" +
"</button><button ng-click='lock()' class='fa fa-ban btn btn-info btn-xs cancel'></button>" +
"</div>",
scope:{
action:'&'
},
link: function($scope, element, attrs, controller) {
element.addClass("trigger-button");
var currentTimeout;
/**
* @function setViewValue ( private )
* @description sets view value in case of ngModel provided
* @param val
*/
function setViewValue(val){
$timeout.cancel(currentTimeout);
controller && controller.$setViewValue(val);
}
/**
* @function lock (private)
* @description Locks the button
*/
function lock(){
$scope.protected = true;
element.removeClass("unlocked");
setViewValue($scope.protected);
}
/**
* @function unlock (private)
* @description Unlocks the button
*/
function unlock(){
...