Skip to content

Commit

Permalink
πŸ”— Ink Anchors βš“ - Show where you are going before you get there!
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanc1 committed Nov 13, 2019
1 parent f3dcf52 commit ac39f1f
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 4 deletions.
Binary file added images/explorables.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/tangle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@

<h1>Ink Components</h1>
<p>
The goal of <code>ink.js</code> is to provide web-components for interactive scientific writing, reactive documents and <a href="https://explorabl.es/" target="_blank">explorable explanations</a>.
The goal of <code>ink.js</code> is to provide web-components for interactive scientific writing, reactive documents and <ink-a href="//explorabl.es/" title="Explorables" description="Documents that enable and encourage active reading." image="/images/explorables.png">explorable explanations</ink-a>.
Included in <code>ink.js</code> are ways to create, update and display variables as text, equations and charts.
</p>

<h2>Tangled Cookies</h2>

<ink-scope>
<p>
<code>ink.js</code> is heavily inspired by <a href="http://worrydream.com/Tangle/guide.html" target="_blank">tangle.js</a>, updated to be use web-components!
<code>ink.js</code> is heavily inspired by <ink-a href="http://worrydream.com/Tangle/guide.html" title="Tangle" description="Tangle was created by Bret Victor." image="/images/tangle.png">tangle.js</ink-a>, updated to be use web-components!
This means you can declaratively write your variables and how to display them in <code>html</code> markup.
To get an idea of what that looks like, let's take the canonical example of <emph>Tangled Cookies</emph> - a simple reactive document to encourage you to not eat more than <ink-action bind="{cookies:42, hide:false}">42 cookies</ink-action> in one day.
</p>
Expand Down
161 changes: 161 additions & 0 deletions src/InkAnchor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { html } from 'lit-element';
import { BaseGetProps, propDef, getProp, setProp, getPropFunction } from './InkDynamicProps.js';

function isLinkExternal(url){
return url && (url.startsWith('http') || url.startsWith('//'));
}

function transformToApiLink(url){
// Obviously needs an update at some point
return '/api/bricks/rowan' + url;
}


class BaseVisible extends BaseGetProps {

static get properties() {
return {
...propDef('visible', Boolean),
src: String,
href: String,
title: String,
description: String,
image: String,
contain: Boolean,
}
}

setDefaults(){
this.visible = true;
this.src = '';
this.href = '';
this.title = '';
this.description = '';
this.image = '';
this.contain = false;
}

get visible() { return getProp(this, 'visible'); }
set visible(val) { return setProp(this, 'visible', val); }
get visibleFunction() { return getPropFunction(this, 'visible'); }

}

class InkAnchor extends BaseVisible {

setFromSrc(){
if(!this.src){
return;
}
// TODO: don't load this again if it is the same
// TODO: load when mouse over

let apiSrc = transformToApiLink(this.src);

fetch(apiSrc).then(data =>{
data.json().then(json =>{
this.href = '/' + json.uid;
this.title = json.title;
this.description = json.description;
this.image = json.thumbnail;
this.contain = json.thumbnail_contain;
});
});
}
updated(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
switch (propName) {
case 'src':
return this.setFromSrc();
default:
return;
}
});
}

render() {
return html`
<style>
a {
color: #1E88E5;
text-decoration: none;
font-weight: 500;
}
a:hover{
text-decoration: underline;
}
.container{
display: inline;
position: relative;
top: 0;
left:0;
}
.panel{
display: none;
position: absolute;
background: #FFFFFF;
top: calc(1em + 17px);
left: calc(50% - 150px);
width: 300px;
border: 1px solid rgba(0, 0, 0, 0.1);
background-color: rgba(250, 250, 250, 0.9);
box-shadow: 0 0 7px rgba(0, 0, 0, 0.1);
border-radius: 4px;
box-sizing: border-box;
backdrop-filter: blur(1px);
z-index: 100;
}
.panel img{
width: 100%;
}
.container:hover > div{
display: block;
}
.arrow {
display: none;
position: absolute;
left: 50%;
margin-left: -7px;
top: calc(1em + 4px);
clip: rect(0 18px 14px -4px);
z-index: 101;
}
.arrow:after {
content: '';
display: block;
width: 14px;
height: 14px;
border: 1px solid rgba(0, 0, 0, 0.1);
background-color: rgba(250, 250, 250, 0.9);
backdrop-filter: blur(1px);
box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
transform: rotate(45deg) translate(6px,6px);
}
</style>
<div class="container">
<a
?hidden="${ !this.visible }"
href="${ this.href }"
target="${isLinkExternal(this.href)? '_blank' : '_self'}"
><slot></slot></a><div class="panel">
<ink-card
title="${ this.title }"
description="${ this.description }"
img-src="${ this.image }"
?contain="${ this.contain }"
url="${ this.href }"
width="280px">
</ink-card>
</div><div class="arrow"></div></div>`;
}
}
customElements.define('ink-a', InkAnchor);

export { InkAnchor, isLinkExternal };
6 changes: 5 additions & 1 deletion src/InkSimple.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LitElement, html } from 'lit-element';
import date from 'date-and-time';
import { SERVER_DATE_FORMAT } from './constants.js';
import { isLinkExternal } from './InkAnchor.js';


class InkAside extends LitElement {
Expand Down Expand Up @@ -235,6 +236,9 @@ class InkCard extends LitElement {

return html`
<style>
:host{
text-align: left;
}
.card{
display: inline-block;
width: ${ this.width || '230px'};
Expand Down Expand Up @@ -286,7 +290,7 @@ class InkCard extends LitElement {
float: right;
}
</style>
<a class="card" title="${ this.title }" href="${ this.url }">
<a class="card" title="${ this.title }" href="${ this.url }" target="${isLinkExternal(this.url)? '_blank' : '_self'}">
<div class="image" style="background-image: url('${ this.imgSrc }')"></div>
<div class="date">${ d }</div>
<div class="title">${ this.title }</div>
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { InkOutline } from './InkOutline.js';
import { InkFigure } from './InkFigure.js';
import { InkCode, InkDemo } from './InkCode.js';
import { InkEquation } from './InkEquation.js';
import { InkAnchor } from './InkAnchor.js';
import { InkAside, InkCallout, InkQuote, InkCard, H2More, InkByline } from './InkSimple.js';
import { CvItem, CvAward } from './InkCV.js';

Expand Down Expand Up @@ -44,6 +45,7 @@ export {
InkCard,
H2More,
InkByline,
InkAnchor,
CvItem,
CvAward,
}
7 changes: 6 additions & 1 deletion webpack.dev.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const express = require('express');
const path = require('path');

module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
contentBase: './dist'
contentBase: './dist',
before(app) {
app.use('/images', express.static(path.resolve('images')));
}
}
});

0 comments on commit ac39f1f

Please sign in to comment.