Inputs Outputs Visualization
Angular @Inputs and @Outputs visualization of presentation components
by kontrach
HTML
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<div class="code">
<p class='component-first-line'>
@<span class="decorator">Component</span> ({
</p>
<div class="metadata">
<p class="selector-part">
<span class="props">
selector:
</span>
<span class="string">
'
<span class="selector">user-card</span>
'
</span>,
</p>
<div class="template-part">
<span class="props">
template:
</span>
<span class="string">`</span>
<pre class="string template"> <p>
<span>Name: {{person.name}}</span>
<span>Age: {{person.age}}</span>
<button (click)="addAge.emit()">Add age</button>
</p></pre>
<span class="string">`</span>
</div>
</div>
})
<div class="class">
<span class="export">export</span>
<span class="decorator">class</span>
<span class="className">PresentationalComponent</span> {
<div class="class-body">
<p class="input-line">
@<span class="decorator">Input</span>()
<span class="props">person</span>:
<span class="className">Person</span>;
</p>
<p class="output-line">
@<span class="decorator">Output</span>()
<span class="props">addAge</span> =
<span class="decorator">new</span>
<span class="className">EventEmitter</span>();
</p>
</div>
</div>
}
</div>
<button class="next-step">Next step</button><button class="clear-queue">
Clear Queue
</button>
SCSS
p, pre{margin:0 0 5px 0;}
.code {
color: black;
font-size: 1.2em;
position: relative;
.props {
color: blue;
}
.string {
color: brown;
}
.decorator{
color: darkblue;
}
.metadata{
padding-left: 20px;
}
.template-part{
position: relative;
}
.template.copy{
top: 0;
left: 0;
position: absolute;
}
.export{
color: purple;
}
.className{
color: darkgreen;
}
.class-body{
padding-left:15px;
}
.props.copy{
position: absolute;
}
}
.selector {
position: relative;
}
.open-tag,
.close-tag{
position: absolute;
&:before{
font-weight: bold;
}
&:after{
content:'>';
font-weight: bold;
float: right;
}
}
.open-tag{
&:before{
content:'<';
}
}
.close-tag{
&:before{
content:'</';
}
}
JavaScript
const $selector = $('.selector');
const $openTag = $selector.clone();
const $template = $('.template');
const $templateCopy = $template.clone().addClass('copy');
const $nextBtn = $('.next-step');
let $closeTag;
const config = {
delay: 900
}
let clicksNum = 0;
let n;
$nextBtn.click(function(){
if (clicksNum === 0) {
registerQueue();
n = $openTag.queue( "fx" );
}
clicksNum++;
console.info(Math.abs(n.length - 4))
console.dir(n);
$openTag.dequeue();
});
$('.clear-queue').click(() => {
$openTag
.clearQueue()
.queue([
moveOpeningTagToRight,
addClosingTag,
moveClosingTagToRight,
putClosingTagDown,
putTemplateInsideTag
])
})
function registerQueue(){
$openTag
.queue(moveOpeningTagToRight)
.queue(addClosingTag)
.queue(moveClosingTagToRight)
.queue(putClosingTagDown)
.queue(putTemplateInsideTag)
.queue(addInput)
.queue(addOutput)
//.queue(function(){
//console.log($(this));
//$(this).animate({width:'+=30'}, config.delay).dequeue();
//});
}
function moveOpeningTagToRight(){
$selector.after($openTag.addClass('open-tag'));
$openTag
.animate({left: '+=300'}, config.delay)
}
function addClosingTag(){
$closeTag = $openTag.clone();
$closeTag
.addClass('close-tag')
.removeClass('open-tag');
$openTag
.after($closeTag)
.dequeue();
}
function moveClosingTagToRight(){
$closeTag
.animate(
{left: '+=100'},
config.delay
);
}
function putClosingTagDown(){
$closeTag
.animate({
left: '-=100',
top: '+=115'
},
config.delay,
() => $(this).dequeue()
);
}
function putTemplateInsideTag(){
$template.after($templateCopy);
$templateCopy
.animate({
left: '+=460'
}, config.delay);
}
function addInput(){
$input = $('.input-line .props');
$inputCopy = $input.clone().addClass('copy');
$input.after( $inputCopy );
$inputCopy
.animate({
left:...