Skip to content

Instantly share code, notes, and snippets.

@zimt28

zimt28/app.riot Secret

Last active May 9, 2019 20:02
Show Gist options
  • Save zimt28/6b7886ee7fa42af5d7cc540a7e404b4c to your computer and use it in GitHub Desktop.
Save zimt28/6b7886ee7fa42af5d7cc540a7e404b4c to your computer and use it in GitHub Desktop.
Multipage Invoice
<app>
<page
each={ page in state.pages }
items={ page.items }
currentPage={ page.pageNumber }
pageCount={ state.pages.length }
removeItemFromPage={ removeItemFromPage }></page>
<script>
export default {
onBeforeMount(props, state) {
this.state = {
pages: [{pageNumber: 1, items: props.invoiceItems}]
}
},
removeItemFromPage(pageNumber) {
const nextPageNumber = pageNumber + 1
const pages = [...this.state.pages]
const lastItem = pages[pageNumber - 1].items.pop()
if (nextPageNumber > this.state.pages.length) {
pages.push({pageNumber: nextPageNumber, items: []})
}
pages[pageNumber].items.unshift(lastItem)
var _this = this;
setTimeout(() => { _this.update({ pages: pages} ) }, 0);
}
}
</script>
</app>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Riot App</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css">
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/paper-css/0.4.1/paper.css">
<link rel="stylesheet" href="/style.css">
</head>
<body class="A4">
<app></app>
<script src="/app.riot" type="riot"></script>
<script src="/page.riot" type="riot"></script>
<script src="https://unpkg.com/riot@next/riot+compiler.min.js"></script>
<script>
(async function main() {
await riot.compile()
const props = {
invoiceItems: [
{ title: "Item 1", price: "1,00" },
{ title: "Item 2", price: "2,00" },
{ title: "Item 3", price: "3,00" },
{ title: "Item 4", price: "4,00" },
{ title: "Item 5", price: "5,00" },
{ title: "Item 6", price: "6,00" },
{ title: "Item 7", price: "7,00" },
{ title: "Item 8", price: "8,00" },
{ title: "Item 9", price: "9,00" },
{ title: "Item 10", price: "10,00" },
{ title: "Item 11", price: "11,00" },
{ title: "Item 12", price: "12,00" },
{ title: "Item 13", price: "13,00" },
{ title: "Item 14", price: "14,00" },
{ title: "Item 15", price: "15,00" },
{ title: "Item 16", price: "16,00" },
{ title: "Item 17", price: "17,00" },
{ title: "Item 18", price: "18,00" },
{ title: "Item 19", price: "19,00" },
{ title: "Item 20", price: "20,00" },
{ title: "Item 21", price: "21,00" },
{ title: "Item 22", price: "22,00" },
{ title: "Item 23", price: "23,00" },
{ title: "Item 24", price: "24,00" },
{ title: "Item 25", price: "25,00" },
{ title: "Item 26", price: "26,00" },
{ title: "Item 27", price: "27,00" },
{ title: "Item 28", price: "28,00" }
]
}
riot.mount('app', props)
}())
</script>
</body>
</html>
<page>
<section class="sheet padding-10mm">
<header>
<h1>Invoice</h1>
</header>
<article>This is an invoice.</article>
<div class="content-frame" data-content-frame>
<div if={ props.currentPage == 1 } class="address">
Address goes here
</div>
<div each={ item in props.items} class="invoice-item">
{ item.title }
<label>{ item.amount} €</label>
</div>
</div>
<div if={ props.currentPage != props.pageCount }>
Continuing on next page.
<br/><br/>
(Next page is no. { props.currentPage + 1 })
</div>
<footer>
Page { props.currentPage } of { props.pageCount }
</footer>
</section>
<script>
const checkOverflow = (el) => {
var curOverflow = el.style.overflow;
if (!curOverflow || curOverflow === "visible")
el.style.overflow = "hidden";
var isOverflowing = el.clientWidth < el.scrollWidth || el.clientHeight < el.scrollHeight;
el.style.overflow = curOverflow;
return isOverflowing;
}
export default {
onMounted(props, state) {
if (checkOverflow(this.$("[data-content-frame]"))) {
props.removeItemFromPage(props.currentPage)
}
},
onUpdated(props, state) {
if (checkOverflow(this.$("[data-content-frame]"))) {
props.removeItemFromPage(props.currentPage)
}
}
}
</script>
</page>
@page {
size: A4;
}
.content-frame {
border: 1px solid grey;
margin-top: 50px;
max-height: 800px;
overflow: hidden;
}
.address {
background-color: #f3f3f3;
height: 200px;
margin-bottom: 100px;
}
.invoice-item {
border-bottom: 1px solid blue;
height: 30px;
padding-bottom: 20px;
padding-top: 20px;
width: 100%;
}
.invoice-item label {
float: right;
}
footer {
background-color: green;
bottom: 50px;
position: absolute;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment