Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,181 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>GaiaTabs Demo</title>
<meta name="description" content="Demo app for gaia-switch" />
<style type="text/css">
html {
font-size: 10px;
}
body {
margin: 0;
font: 16px sans-serif;
}
section {
box-sizing: border-box;
position: relative;
float: left;
width: 50%;
height: 400px;
border: solid 1px #eee;
overflow: hidden
}
gaia-tabs > a,
gaia-tabs > div,
gaia-tabs > button {
background-repeat: no-repeat;
background-position: top center;
}
.info {
position: absolute;
top: 50%;
left: 0;
width: 100%;
text-align: center;
}
/* icons */
.icon-call-log {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSI5MCIgdmlld0JveD0iMCAwIDMwIDkwIj48cGF0aCBmaWxsPSIjMDBDQUYyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IiBkPSJNMjkuODYzIDY4LjU2OWgtNS41Nzd2Mi43MmMtLjMyLjA2Ni0uNjY1LS4wMDgtLjkxMi0uMjU5bC0zLjA0NC0zLjA5NGMtLjM5NC0uNC0uMzk0LTEuMDQ4IDAtMS40NDhsMy4wNDQtMy4wOTNjLjI0OS0uMjUzLjU5NC0uMzI2LjkxMi0uMjYxdjIuNzM0aDUuNTc4Yy4xODEuODkuMTgxIDEuODEyLS4wMDEgMi43MDF6bS0xMS44MDktNS43MzJjLS4yNDguMjUzLS41OTEuMzI2LS45MTIuMjYxdi0yLjcyaC01LjU3N2MtLjE4MS0uODktLjE4MS0xLjgxLS4wMDEtMi42OTloNS41Nzd2LTIuNzM1Yy4zMjEtLjA2Ni42NjYuMDA4LjkxMi4yNjFsMy4wNDQgMy4wOTRjLjM5NS40LjM5NSAxLjA0OCAwIDEuNDQ2bC0zLjA0MyAzLjA5MnptLTEuNTIxIDEwLjY4bC4wMjIuMDIyYy42MTMtLjM0MyAxLjIxNy0uNzU2IDEuODE3LTEuMTk5bDUuNzI5IDUuMTU0Yy0xLjIwOCAxLjA2MS0yLjUyIDEuOTMtMy44OTkgMi41ODYtMy42NjUtLjY4OC04LjM2My0zLjQ1OS0xMi41NzktNy43NDUtNC4yMTctNC4yODItNi45NDItOS4wNTMtNy42MjMtMTIuNzc1LjY0NS0xLjQwNCAxLjUwMy0yLjczNyAyLjU0OC0zLjk2OGw1LjA3NiA1LjgyNmMtLjQzNS42MDktLjg0MSAxLjIyMy0xLjE3OSAxLjg0NWwuMDIyLjAyM2MtLjU5NCAxLjMyNi43ODEgNC4yMSAzLjM1MiA2LjgyMyAyLjU3MiAyLjYxMyA1LjQxMSA0LjAxMSA2LjcxNCAzLjQwOHoiLz48cGF0aCBmaWxsPSIjNUY1RjVGIiBkPSJNMjkuODYzIDIzLjU2OGgtNS41Nzd2Mi43MmMtLjMyLjA2Ni0uNjY1LS4wMDgtLjkxMi0uMjU5bC0zLjA0NC0zLjA5NGMtLjM5NC0uNC0uMzk0LTEuMDQ4IDAtMS40NDhsMy4wNDQtMy4wOTNjLjI0OS0uMjUzLjU5NC0uMzI4LjkxMi0uMjYxdjIuNzM0aDUuNTc4Yy4xODEuODkxLjE4MSAxLjgxMi0uMDAxIDIuNzAxem0tMTEuODA5LTUuNzMxYy0uMjQ4LjI1My0uNTkxLjMyOC0uOTEyLjI2MXYtMi43MTloLTUuNTc3Yy0uMTgxLS44OS0uMTgxLTEuODEtLjAwMS0yLjcwMWg1LjU3N3YtMi43MzZjLjMyMS0uMDY2LjY2Ni4wMDguOTEyLjI2MWwzLjA0NCAzLjA5NGMuMzk1LjQuMzk1IDEuMDQ4IDAgMS40NDZsLTMuMDQzIDMuMDk0em0tMS41MjEgMTAuNjhsLjAyMi4wMjJjLjYxMy0uMzQzIDEuMjE3LS43NTYgMS44MTctMS4xOTdsNS43MjkgNS4xNTRjLTEuMjA4IDEuMDYxLTIuNTIgMS45MjktMy44OTkgMi41ODYtMy42NjUtLjY4OC04LjM2My0zLjQ1OC0xMi41NzktNy43NDUtNC4yMTctNC4yODQtNi45NDItOS4wNTMtNy42MjMtMTIuNzc3LjY0NS0xLjQwNCAxLjUwMy0yLjczNyAyLjU0OC0zLjk2OGw1LjA3NiA1LjgyNmMtLjQzNS42MDktLjg0MSAxLjIyMy0xLjE3OSAxLjg0NGwuMDIyLjAyM2MtLjU5NCAxLjMyNi43ODEgNC4yMSAzLjM1MiA2LjgyM3M1LjQxMSA0LjAxMSA2LjcxNCAzLjQwOXoiLz48L3N2Zz4=);
}
.icon-contacts {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSI5MCIgdmlld0JveD0iMCAwIDMwIDkwIj48cGF0aCBmaWxsPSIjMDBDQUYyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IiBkPSJNMjQuMjU5IDcyLjk1OGMwIDIuNTg0LS41MSA0Ljk5MS0xLjM3OCA3LjA0MmgtMTUuNzYyYy0uODY4LTIuMDUyLTEuMzc4LTQuNDU3LTEuMzc4LTcuMDQyaC4wMDV2LS4wMDFjMC0yLjU3NyAyLjEzMS00LjggNS4yMTctNS44NTZsNC4wMzggNC4wNzIgNC4wMzctNC4wNzJjMy4wODUgMS4wNTggNS4yMTcgMy4yNzkgNS4yMTcgNS44NTZ2LjAwMmwuMDA0LS4wMDF6bS05LjI1OS03LjMwNWMtMi45MTcgMC01LjI4NC0yLjM4NC01LjI4NC01LjMyNnMyLjM2Ny01LjMyNyA1LjI4NC01LjMyN2MyLjkxNiAwIDUuMjgzIDIuMzg1IDUuMjgzIDUuMzI3cy0yLjM2NyA1LjMyNi01LjI4MyA1LjMyNnoiLz48cGF0aCBmaWxsPSIjNUY1RjVGIiBkPSJNMjQuMjU5IDI3Ljk1OGMwIDIuNTg0LS41MSA0Ljk5MS0xLjM3OCA3LjA0MmgtMTUuNzYyYy0uODY4LTIuMDUyLTEuMzc4LTQuNDU4LTEuMzc4LTcuMDQyaC4wMDV2LS4wMDFjMC0yLjU3NyAyLjEzMS00LjggNS4yMTctNS44NTZsNC4wMzggNC4wNzIgNC4wMzctNC4wNzJjMy4wODUgMS4wNTggNS4yMTcgMy4yNzkgNS4yMTcgNS44NTZ2LjAwMmwuMDA0LS4wMDF6bS05LjI1OS03LjMwNWMtMi45MTcgMC01LjI4NC0yLjM4NC01LjI4NC01LjMyNiAwLTIuOTQzIDIuMzY3LTUuMzI3IDUuMjg0LTUuMzI3IDIuOTE2IDAgNS4yODMgMi4zODUgNS4yODMgNS4zMjcgMCAyLjk0MS0yLjM2NyA1LjMyNi01LjI4MyA1LjMyNnoiLz48L3N2Zz4=);
}
.icon-dialer {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSI5MCIgdmlld0JveD0iMCAwIDMwIDkwIj48cGF0aCBmaWxsPSIjMDBDQUYyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IiBkPSJNOS4zNTkgNjEuMDE1bC0uMDIzLjAxOWMtLjEwMy40MjMtLjQ5Ljc0Ni0uOTc3Ljc0NmwtLjAwMS4wMDFoLTIuNDg3bC0uMDAyLS4wMDFjLS40ODYgMC0uODczLS4zMjMtLjk3Ni0uNzQ2bC0uMDIzLS4wMTljLS4xODgtLjkxNS0uMzE4LTEuOTQ3LS4zNy0zLjA2aDUuMjI4Yy0uMDUyIDEuMTEzLS4xOCAyLjE0NS0uMzY5IDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ2LS45NzcuNzQ2bC0uMDAxLjAwMWgtMi40ODhsLS4wMDEtLjAwMWMtLjQ4NiAwLS44NzMtLjMyMy0uOTc2LS43NDZsLS4wMjMtLjAxOWMtLjE5LS45MTUtLjMxOC0xLjk0Ny0uMzY5LTMuMDZoNS4yMjhjLS4wNTMgMS4xMTMtLjE4MyAyLjE0NS0uMzcxIDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ2LS45NzcuNzQ2bC0uMDAxLjAwMWgtMi40ODh2LS4wMDFjLS40ODcgMC0uODc0LS4zMjMtLjk3OS0uNzQ2bC0uMDItLjAxOWMtLjE5LS45MTUtLjMxOC0xLjk0Ny0uMzY5LTMuMDZoNS4yMjVjLS4wNTIgMS4xMTMtLjE4MSAyLjE0NS0uMzY5IDMuMDZ6bS0xNS43NzIgNy42MzJsLS4wMjMuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ3LS45NzcuNzQ3aC0yLjQ5Yy0uNDg2IDAtLjg3My0uMzI1LS45NzYtLjc0N2wtLjAyMy0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ3LS4zNy0zLjA2aDUuMjI4Yy0uMDUyIDEuMTEzLS4xOCAyLjE0Ny0uMzY5IDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ3LS45NzcuNzQ3aC0yLjQ4OWMtLjQ4NiAwLS44NzMtLjMyNS0uOTc2LS43NDdsLS4wMjMtLjAxOWMtLjE5LS45MTQtLjMxOC0xLjk0OS0uMzY5LTMuMDZoNS4yMjhjLS4wNTQgMS4xMTMtLjE4NCAyLjE0Ny0uMzcyIDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ3LS45NzcuNzQ3aC0yLjQ4OWMtLjQ4NyAwLS44NzQtLjMyNS0uOTc5LS43NDdsLS4wMi0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ5LS4zNjktMy4wNmg1LjIyNWMtLjA1MiAxLjExMy0uMTgxIDIuMTQ3LS4zNjkgMy4wNnptLTE1Ljc3MiA3LjYzNGwtLjAyMy4wMTdjLS4xMDQuNDI1LS40OS43NDctLjk3OS43NDdoLTIuNDg5Yy0uNDg2IDAtLjg3My0uMzIzLS45NzYtLjc0N2wtLjAyMy0uMDE4Yy0uMTg4LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyOGMtLjA1MiAxLjExMS0uMTggMi4xNDYtLjM2OSAzLjA2MXptNy44ODYgMGwtLjAyMi4wMTdjLS4xMDQuNDI1LS40OTEuNzQ3LS45NzkuNzQ3aC0yLjQ4OWMtLjQ4NiAwLS44NzMtLjMyMy0uOTc2LS43NDdsLS4wMjMtLjAxOGMtLjE5LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyOGMtLjA1MiAxLjExMS0uMTgyIDIuMTQ2LS4zNyAzLjA2MXptNy44ODYgMGwtLjAyMi4wMTdjLS4xMDQuNDI1LS40OS43NDctLjk3OS43NDdoLTIuNDg5Yy0uNDg3IDAtLjg3NC0uMzIzLS45NzktLjc0N2wtLjAyLS4wMThjLS4xOS0uOTE1LS4zMTgtMS45NS0uMzY5LTMuMDZoNS4yMjdjLS4wNTIgMS4xMTEtLjE4MSAyLjE0Ni0uMzY5IDMuMDYxeiIvPjxwYXRoIGZpbGw9IiM1RjVGNUYiIGQ9Ik05LjM1OSAxNi4wMTVsLS4wMjMuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ2LS45NzcuNzQ2bC0uMDAxLjAwMWgtMi40ODdsLS4wMDItLjAwMWMtLjQ4NiAwLS44NzMtLjMyMy0uOTc2LS43NDZsLS4wMjMtLjAxOWMtLjE4OC0uOTE0LS4zMTgtMS45NDctLjM3LTMuMDZoNS4yMjhjLS4wNTIgMS4xMTMtLjE4IDIuMTQ1LS4zNjkgMy4wNnptNy44ODYgMGwtLjAyMi4wMTljLS4xMDMuNDIzLS40OS43NDYtLjk3Ny43NDZsLS4wMDEuMDAxaC0yLjQ4OGwtLjAwMS0uMDAxYy0uNDg2IDAtLjg3My0uMzIzLS45NzYtLjc0NmwtLjAyMy0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ3LS4zNjktMy4wNmg1LjIyOGMtLjA1MyAxLjExMy0uMTgzIDIuMTQ1LS4zNzEgMy4wNnptNy44ODYgMGwtLjAyMi4wMTljLS4xMDMuNDIzLS40OS43NDYtLjk3Ny43NDZsLS4wMDEuMDAxaC0yLjQ4OHYtLjAwMWMtLjQ4NyAwLS44NzQtLjMyMy0uOTc5LS43NDZsLS4wMi0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ3LS4zNjktMy4wNmg1LjIyNWMtLjA1MiAxLjExMy0uMTgxIDIuMTQ1LS4zNjkgMy4wNnptLTE1Ljc3MiA3LjYzMmwtLjAyMy4wMTljLS4xMDMuNDIzLS40OS43NDctLjk3Ny43NDdoLTIuNDljLS40ODYgMC0uODczLS4zMjUtLjk3Ni0uNzQ3bC0uMDIzLS4wMTljLS4xOS0uOTE0LS4zMTgtMS45NDctLjM3LTMuMDZoNS4yMjhjLS4wNTIgMS4xMTMtLjE4IDIuMTQ3LS4zNjkgMy4wNnptNy44ODYgMGwtLjAyMi4wMTljLS4xMDMuNDIzLS40OS43NDctLjk3Ny43NDdoLTIuNDg5Yy0uNDg2IDAtLjg3My0uMzI1LS45NzYtLjc0N2wtLjAyMy0uMDE5Yy0uMTktLjkxNS0uMzE4LTEuOTQ5LS4zNjktMy4wNjFoNS4yMjhjLS4wNTQgMS4xMTQtLjE4NCAyLjE0OC0uMzcyIDMuMDYxem03Ljg4NiAwbC0uMDIyLjAxOWMtLjEwMy40MjMtLjQ5Ljc0Ny0uOTc3Ljc0N2gtMi40ODljLS40ODcgMC0uODc0LS4zMjUtLjk3OS0uNzQ3bC0uMDItLjAxOWMtLjE5LS45MTUtLjMxOC0xLjk0OS0uMzY5LTMuMDYxaDUuMjI1Yy0uMDUyIDEuMTE0LS4xODEgMi4xNDgtLjM2OSAzLjA2MXptLTE1Ljc3MiA3LjYzNGwtLjAyMy4wMTdjLS4xMDQuNDI1LS40OS43NDctLjk3OS43NDdoLTIuNDg5Yy0uNDg2IDAtLjg3My0uMzIzLS45NzYtLjc0N2wtLjAyMy0uMDE3Yy0uMTg4LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyOGMtLjA1MiAxLjExLS4xOCAyLjE0NS0uMzY5IDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE3Yy0uMTA0LjQyNS0uNDkxLjc0Ny0uOTc5Ljc0N2gtMi40ODljLS40ODYgMC0uODczLS4zMjMtLjk3Ni0uNzQ3bC0uMDIzLS4wMTdjLS4xOS0uOTE1LS4zMTgtMS45NS0uMzY5LTMuMDZoNS4yMjhjLS4wNTIgMS4xMS0uMTgyIDIuMTQ1LS4zNyAzLjA2em03Ljg4NiAwbC0uMDIyLjAxN2MtLjEwNC40MjUtLjQ5Ljc0Ny0uOTc5Ljc0N2gtMi40ODljLS40ODcgMC0uODc0LS4zMjMtLjk3OS0uNzQ3bC0uMDItLjAxN2MtLjE5LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyN2MtLjA1MiAxLjExLS4xODEgMi4xNDUtLjM2OSAzLjA2eiIvPjwvc3ZnPg==);
}
/* icons */
.icon-call-log-dark {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSI5MCIgdmlld0JveD0iMCAwIDMwIDkwIj48cGF0aCBmaWxsPSIjMDBDQUYyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IiBkPSJNMjkuODYzIDY4LjU2OWgtNS41Nzd2Mi43MmMtLjMyLjA2Ni0uNjY1LS4wMDgtLjkxMi0uMjU5bC0zLjA0NC0zLjA5NGMtLjM5NC0uNC0uMzk0LTEuMDQ4IDAtMS40NDhsMy4wNDQtMy4wOTNjLjI0OS0uMjUzLjU5NC0uMzI2LjkxMi0uMjYxdjIuNzM0aDUuNTc4Yy4xODEuODkuMTgxIDEuODEyLS4wMDEgMi43MDF6bS0xMS44MDktNS43MzJjLS4yNDguMjUzLS41OTEuMzI2LS45MTIuMjYxdi0yLjcyaC01LjU3N2MtLjE4MS0uODktLjE4MS0xLjgxLS4wMDEtMi42OTloNS41Nzd2LTIuNzM1Yy4zMjEtLjA2Ni42NjYuMDA4LjkxMi4yNjFsMy4wNDQgMy4wOTRjLjM5NS40LjM5NSAxLjA0OCAwIDEuNDQ2bC0zLjA0MyAzLjA5MnptLTEuNTIxIDEwLjY4bC4wMjIuMDIyYy42MTMtLjM0MyAxLjIxNy0uNzU2IDEuODE3LTEuMTk5bDUuNzI5IDUuMTU0Yy0xLjIwOCAxLjA2MS0yLjUyIDEuOTMtMy44OTkgMi41ODYtMy42NjUtLjY4OC04LjM2My0zLjQ1OS0xMi41NzktNy43NDUtNC4yMTctNC4yODItNi45NDItOS4wNTMtNy42MjMtMTIuNzc1LjY0NS0xLjQwNCAxLjUwMy0yLjczNyAyLjU0OC0zLjk2OGw1LjA3NiA1LjgyNmMtLjQzNS42MDktLjg0MSAxLjIyMy0xLjE3OSAxLjg0NWwuMDIyLjAyM2MtLjU5NCAxLjMyNi43ODEgNC4yMSAzLjM1MiA2LjgyMyAyLjU3MiAyLjYxMyA1LjQxMSA0LjAxMSA2LjcxNCAzLjQwOHoiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMjkuODYzIDIzLjU2OGgtNS41Nzd2Mi43MmMtLjMyLjA2Ni0uNjY1LS4wMDgtLjkxMi0uMjU5bC0zLjA0NC0zLjA5NGMtLjM5NC0uNC0uMzk0LTEuMDQ4IDAtMS40NDhsMy4wNDQtMy4wOTNjLjI0OS0uMjUzLjU5NC0uMzI4LjkxMi0uMjYxdjIuNzM0aDUuNTc4Yy4xODEuODkxLjE4MSAxLjgxMi0uMDAxIDIuNzAxem0tMTEuODA5LTUuNzMxYy0uMjQ4LjI1My0uNTkxLjMyOC0uOTEyLjI2MXYtMi43MTloLTUuNTc3Yy0uMTgxLS44OS0uMTgxLTEuODEtLjAwMS0yLjcwMWg1LjU3N3YtMi43MzZjLjMyMS0uMDY2LjY2Ni4wMDguOTEyLjI2MWwzLjA0NCAzLjA5NGMuMzk1LjQuMzk1IDEuMDQ4IDAgMS40NDZsLTMuMDQzIDMuMDk0em0tMS41MjEgMTAuNjhsLjAyMi4wMjJjLjYxMy0uMzQzIDEuMjE3LS43NTYgMS44MTctMS4xOTdsNS43MjkgNS4xNTRjLTEuMjA4IDEuMDYxLTIuNTIgMS45MjktMy44OTkgMi41ODYtMy42NjUtLjY4OC04LjM2My0zLjQ1OC0xMi41NzktNy43NDUtNC4yMTctNC4yODQtNi45NDItOS4wNTMtNy42MjMtMTIuNzc3LjY0NS0xLjQwNCAxLjUwMy0yLjczNyAyLjU0OC0zLjk2OGw1LjA3NiA1LjgyNmMtLjQzNS42MDktLjg0MSAxLjIyMy0xLjE3OSAxLjg0NGwuMDIyLjAyM2MtLjU5NCAxLjMyNi43ODEgNC4yMSAzLjM1MiA2LjgyM3M1LjQxMSA0LjAxMSA2LjcxNCAzLjQwOXoiLz48L3N2Zz4=);
}
.icon-contacts-dark {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSI5MCIgdmlld0JveD0iMCAwIDMwIDkwIj48cGF0aCBmaWxsPSIjMDBDQUYyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IiBkPSJNMjQuMjU5IDcyLjk1OGMwIDIuNTg0LS41MSA0Ljk5MS0xLjM3OCA3LjA0MmgtMTUuNzYyYy0uODY4LTIuMDUyLTEuMzc4LTQuNDU3LTEuMzc4LTcuMDQyaC4wMDV2LS4wMDFjMC0yLjU3NyAyLjEzMS00LjggNS4yMTctNS44NTZsNC4wMzggNC4wNzIgNC4wMzctNC4wNzJjMy4wODUgMS4wNTggNS4yMTcgMy4yNzkgNS4yMTcgNS44NTZ2LjAwMmwuMDA0LS4wMDF6bS05LjI1OS03LjMwNWMtMi45MTcgMC01LjI4NC0yLjM4NC01LjI4NC01LjMyNnMyLjM2Ny01LjMyNyA1LjI4NC01LjMyN2MyLjkxNiAwIDUuMjgzIDIuMzg1IDUuMjgzIDUuMzI3cy0yLjM2NyA1LjMyNi01LjI4MyA1LjMyNnoiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMjQuMjU5IDI3Ljk1OGMwIDIuNTg0LS41MSA0Ljk5MS0xLjM3OCA3LjA0MmgtMTUuNzYyYy0uODY4LTIuMDUyLTEuMzc4LTQuNDU4LTEuMzc4LTcuMDQyaC4wMDV2LS4wMDFjMC0yLjU3NyAyLjEzMS00LjggNS4yMTctNS44NTZsNC4wMzggNC4wNzIgNC4wMzctNC4wNzJjMy4wODUgMS4wNTggNS4yMTcgMy4yNzkgNS4yMTcgNS44NTZ2LjAwMmwuMDA0LS4wMDF6bS05LjI1OS03LjMwNWMtMi45MTcgMC01LjI4NC0yLjM4NC01LjI4NC01LjMyNiAwLTIuOTQzIDIuMzY3LTUuMzI3IDUuMjg0LTUuMzI3IDIuOTE2IDAgNS4yODMgMi4zODUgNS4yODMgNS4zMjcgMCAyLjk0MS0yLjM2NyA1LjMyNi01LjI4MyA1LjMyNnoiLz48L3N2Zz4=);
}
.icon-dialer-dark {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSI5MCIgdmlld0JveD0iMCAwIDMwIDkwIj48cGF0aCBmaWxsPSIjMDBDQUYyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IiBkPSJNOS4zNTkgNjEuMDE1bC0uMDIzLjAxOWMtLjEwMy40MjMtLjQ5Ljc0Ni0uOTc3Ljc0NmwtLjAwMS4wMDFoLTIuNDg3bC0uMDAyLS4wMDFjLS40ODYgMC0uODczLS4zMjMtLjk3Ni0uNzQ2bC0uMDIzLS4wMTljLS4xODgtLjkxNS0uMzE4LTEuOTQ3LS4zNy0zLjA2aDUuMjI4Yy0uMDUyIDEuMTEzLS4xOCAyLjE0NS0uMzY5IDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ2LS45NzcuNzQ2bC0uMDAxLjAwMWgtMi40ODhsLS4wMDEtLjAwMWMtLjQ4NiAwLS44NzMtLjMyMy0uOTc2LS43NDZsLS4wMjMtLjAxOWMtLjE5LS45MTUtLjMxOC0xLjk0Ny0uMzY5LTMuMDZoNS4yMjhjLS4wNTMgMS4xMTMtLjE4MyAyLjE0NS0uMzcxIDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ2LS45NzcuNzQ2bC0uMDAxLjAwMWgtMi40ODh2LS4wMDFjLS40ODcgMC0uODc0LS4zMjMtLjk3OS0uNzQ2bC0uMDItLjAxOWMtLjE5LS45MTUtLjMxOC0xLjk0Ny0uMzY5LTMuMDZoNS4yMjVjLS4wNTIgMS4xMTMtLjE4MSAyLjE0NS0uMzY5IDMuMDZ6bS0xNS43NzIgNy42MzJsLS4wMjMuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ3LS45NzcuNzQ3aC0yLjQ5Yy0uNDg2IDAtLjg3My0uMzI1LS45NzYtLjc0N2wtLjAyMy0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ3LS4zNy0zLjA2aDUuMjI4Yy0uMDUyIDEuMTEzLS4xOCAyLjE0Ny0uMzY5IDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ3LS45NzcuNzQ3aC0yLjQ4OWMtLjQ4NiAwLS44NzMtLjMyNS0uOTc2LS43NDdsLS4wMjMtLjAxOWMtLjE5LS45MTQtLjMxOC0xLjk0OS0uMzY5LTMuMDZoNS4yMjhjLS4wNTQgMS4xMTMtLjE4NCAyLjE0Ny0uMzcyIDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ3LS45NzcuNzQ3aC0yLjQ4OWMtLjQ4NyAwLS44NzQtLjMyNS0uOTc5LS43NDdsLS4wMi0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ5LS4zNjktMy4wNmg1LjIyNWMtLjA1MiAxLjExMy0uMTgxIDIuMTQ3LS4zNjkgMy4wNnptLTE1Ljc3MiA3LjYzNGwtLjAyMy4wMTdjLS4xMDQuNDI1LS40OS43NDctLjk3OS43NDdoLTIuNDg5Yy0uNDg2IDAtLjg3My0uMzIzLS45NzYtLjc0N2wtLjAyMy0uMDE4Yy0uMTg4LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyOGMtLjA1MiAxLjExMS0uMTggMi4xNDYtLjM2OSAzLjA2MXptNy44ODYgMGwtLjAyMi4wMTdjLS4xMDQuNDI1LS40OTEuNzQ3LS45NzkuNzQ3aC0yLjQ4OWMtLjQ4NiAwLS44NzMtLjMyMy0uOTc2LS43NDdsLS4wMjMtLjAxOGMtLjE5LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyOGMtLjA1MiAxLjExMS0uMTgyIDIuMTQ2LS4zNyAzLjA2MXptNy44ODYgMGwtLjAyMi4wMTdjLS4xMDQuNDI1LS40OS43NDctLjk3OS43NDdoLTIuNDg5Yy0uNDg3IDAtLjg3NC0uMzIzLS45NzktLjc0N2wtLjAyLS4wMThjLS4xOS0uOTE1LS4zMTgtMS45NS0uMzY5LTMuMDZoNS4yMjdjLS4wNTIgMS4xMTEtLjE4MSAyLjE0Ni0uMzY5IDMuMDYxeiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik05LjM1OSAxNi4wMTVsLS4wMjMuMDE5Yy0uMTAzLjQyMy0uNDkuNzQ2LS45NzcuNzQ2bC0uMDAxLjAwMWgtMi40ODdsLS4wMDItLjAwMWMtLjQ4NiAwLS44NzMtLjMyMy0uOTc2LS43NDZsLS4wMjMtLjAxOWMtLjE4OC0uOTE0LS4zMTgtMS45NDctLjM3LTMuMDZoNS4yMjhjLS4wNTIgMS4xMTMtLjE4IDIuMTQ1LS4zNjkgMy4wNnptNy44ODYgMGwtLjAyMi4wMTljLS4xMDMuNDIzLS40OS43NDYtLjk3Ny43NDZsLS4wMDEuMDAxaC0yLjQ4OGwtLjAwMS0uMDAxYy0uNDg2IDAtLjg3My0uMzIzLS45NzYtLjc0NmwtLjAyMy0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ3LS4zNjktMy4wNmg1LjIyOGMtLjA1MyAxLjExMy0uMTgzIDIuMTQ1LS4zNzEgMy4wNnptNy44ODYgMGwtLjAyMi4wMTljLS4xMDMuNDIzLS40OS43NDYtLjk3Ny43NDZsLS4wMDEuMDAxaC0yLjQ4OHYtLjAwMWMtLjQ4NyAwLS44NzQtLjMyMy0uOTc5LS43NDZsLS4wMi0uMDE5Yy0uMTktLjkxNC0uMzE4LTEuOTQ3LS4zNjktMy4wNmg1LjIyNWMtLjA1MiAxLjExMy0uMTgxIDIuMTQ1LS4zNjkgMy4wNnptLTE1Ljc3MiA3LjYzMmwtLjAyMy4wMTljLS4xMDMuNDIzLS40OS43NDctLjk3Ny43NDdoLTIuNDljLS40ODYgMC0uODczLS4zMjUtLjk3Ni0uNzQ3bC0uMDIzLS4wMTljLS4xOS0uOTE0LS4zMTgtMS45NDctLjM3LTMuMDZoNS4yMjhjLS4wNTIgMS4xMTMtLjE4IDIuMTQ3LS4zNjkgMy4wNnptNy44ODYgMGwtLjAyMi4wMTljLS4xMDMuNDIzLS40OS43NDctLjk3Ny43NDdoLTIuNDg5Yy0uNDg2IDAtLjg3My0uMzI1LS45NzYtLjc0N2wtLjAyMy0uMDE5Yy0uMTktLjkxNS0uMzE4LTEuOTQ5LS4zNjktMy4wNjFoNS4yMjhjLS4wNTQgMS4xMTQtLjE4NCAyLjE0OC0uMzcyIDMuMDYxem03Ljg4NiAwbC0uMDIyLjAxOWMtLjEwMy40MjMtLjQ5Ljc0Ny0uOTc3Ljc0N2gtMi40ODljLS40ODcgMC0uODc0LS4zMjUtLjk3OS0uNzQ3bC0uMDItLjAxOWMtLjE5LS45MTUtLjMxOC0xLjk0OS0uMzY5LTMuMDYxaDUuMjI1Yy0uMDUyIDEuMTE0LS4xODEgMi4xNDgtLjM2OSAzLjA2MXptLTE1Ljc3MiA3LjYzNGwtLjAyMy4wMTdjLS4xMDQuNDI1LS40OS43NDctLjk3OS43NDdoLTIuNDg5Yy0uNDg2IDAtLjg3My0uMzIzLS45NzYtLjc0N2wtLjAyMy0uMDE3Yy0uMTg4LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyOGMtLjA1MiAxLjExLS4xOCAyLjE0NS0uMzY5IDMuMDZ6bTcuODg2IDBsLS4wMjIuMDE3Yy0uMTA0LjQyNS0uNDkxLjc0Ny0uOTc5Ljc0N2gtMi40ODljLS40ODYgMC0uODczLS4zMjMtLjk3Ni0uNzQ3bC0uMDIzLS4wMTdjLS4xOS0uOTE1LS4zMTgtMS45NS0uMzY5LTMuMDZoNS4yMjhjLS4wNTIgMS4xMS0uMTgyIDIuMTQ1LS4zNyAzLjA2em03Ljg4NiAwbC0uMDIyLjAxN2MtLjEwNC40MjUtLjQ5Ljc0Ny0uOTc5Ljc0N2gtMi40ODljLS40ODcgMC0uODc0LS4zMjMtLjk3OS0uNzQ3bC0uMDItLjAxN2MtLjE5LS45MTUtLjMxOC0xLjk1LS4zNjktMy4wNmg1LjIyN2MtLjA1MiAxLjExLS4xODEgMi4xNDUtLjM2OSAzLjA2eiIvPjwvc3ZnPg==);
}
</style>
<script>window.GaiaTabsBaseurl = '../';</script>
<script src="../../../js/component_utils.js"></script>
<script src="../script.js"></script>
</head>
<body role="application">
<section id="demo1">
<div class="info"></div>
<div class="panes">
<div class="pane selected" role="tabpanel" id="demo1_pane1">Dialer</div>
<div class="pane" role="tabpanel" id="demo1_pane2">Call Log</div>
<div class="pane" role="tabpanel" id="demo1_pane3">Contacts</div>
</div>
<gaia-tabs selected="0">
<button class="icon-dialer" aria-controls="demo1_pane1"></button>
<button class="icon-call-log" aria-controls="demo1_pane2"></button>
<button class="icon-contacts" aria-controls="demo1_pane2"></button>
</gaia-tabs>
<style>
#demo1 .panes {
width: 300%;
height: 100%;
transition: transform 300ms ease;
}
#demo1 .pane {
box-sizing: border-box;
display: flex;
float: left;
width: 33.333%;
height: 100%;
border: solid 1px #eee;
align-items: center;
justify-content: center;
transition: visibility 300ms;
visibility: hidden;
}
#demo1 .pane.selected {
visibility: visible;
}
#demo1 .info {
display: none;
}
</style>
<script>
(function() {
var tabs = demo1.querySelector('gaia-tabs');
var panes = demo1.querySelector('.panes');
tabs.addEventListener('change', function() {
panes.querySelector('.selected').classList.remove('selected');
panes.querySelectorAll('.pane')[tabs.selected].classList.add('selected');
var x = tabs.selected * -33.33;
panes.style.transform = 'translateX(' + x + '%)';
});
})();
</script>
</section>
<section>
<div class="info"></div>
<gaia-tabs selected="2">
<a href="#" class="icon-dialer"></a>
<a href="#" class="icon-contacts"></a>
<a href="#" class="icon-call-log"></a>
<a href="#" disabled="">More</a>
<a href="#">Things</a>
</gaia-tabs>
</section>
<section>
<div class="info"></div>
<gaia-tabs skin="dark" selected="4" >
<button class="icon-dialer-dark"></button>
<button class="icon-contacts-dark"></button>
<button class="icon-call-log-dark"></button>
<button disabled="">More</button>
<button>Things</button>
</gaia-tabs>
</section>
<section>
<div class="info"></div>
<gaia-tabs skin="dark" selected="0" position="top">
<button>All</button>
<button>Missed</button>
</gaia-tabs>
</section>
<section>
<div class="info"></div>
<gaia-tabs selected="0" position="top">
<button>All</button>
<button>Missed</button>
</gaia-tabs>
</section>
<section>
<div class="info"></div>
<gaia-tabs underline="child" selected="0" position="top">
<button><span>All</span></button>
<button><span>Missed</span></button>
</gaia-tabs>
</section>
<script>
var tabs = document.querySelectorAll('gaia-tabs');
var infos = document.querySelectorAll('.info');
[].forEach.call(tabs, function(tab, i) {
tab.addEventListener('change', function() {
infos[i].textContent = 'Selected: ' + tab.selected;
});
});
</script>
</body>
</html>

View file

@ -0,0 +1,106 @@
window.GaiaTabs = (function(win) {
/* global ComponentUtils */
'use strict';
// Extend from the HTMLElement prototype
var proto = Object.create(HTMLElement.prototype);
var indexOf = [].indexOf;
// Allow baseurl to be overridden (used for demo page)
var baseurl = window.GaiaTabsBaseurl ||
'/shared/elements/gaia_tabs/';
/**
* Runs when an instance of `GaiaTabs`
* is first created.
*
* The intial value of the `select` attribute
* is used to select a tab.
*
* @private
*/
proto.createdCallback = function() {
for (var el = this.firstElementChild; el; el = el.nextElementSibling) {
el.setAttribute('role', 'tab');
}
this.setAttribute('role', 'tablist');
ComponentUtils.style.call(this, baseurl);
this.addEventListener('click', this.onClick);
this.select(this.getAttribute('selected'));
};
/**
* Updates the selected tab when
* the `selected` attribute changes.
*
* @param {String} attr
* @param {String|null} oldVal
* @param {String|null} newVal [description]
* @private
*/
proto.attributeChangedCallback = function(attr, oldVal, newVal) {
if (attr === 'selected') { this.select(newVal); }
};
/**
* Walks up the DOM from the `event.target`
* until it finds an immendiate child
* of the element, then selects the index
* of that element.
*
* @param {Event} e
* @private
*/
proto.onClick = function(e) {
var el = e.target;
var i;
while (el) {
i = indexOf.call(this.children, el);
if (i > -1) { return this.select(i); }
el = el.parentNode;
}
};
/**
* Select a tab by index.
*
* @param {Number} index
* @public
*/
proto.select = function(index) {
if (index === null) { return; }
// Make sure it's a number
index = Number(index);
var el = this.children[index];
this.deselect(this.selected);
this.selectedChild = el;
this.selected = index;
el.setAttribute('aria-selected', 'true');
el.classList.add('selected');
var e = new CustomEvent('change');
setTimeout(this.dispatchEvent.bind(this, e));
};
/**
* Deselect a tab by index.
* @param {Number} index
* @public
*/
proto.deselect = function(index) {
var el = this.children[index];
if (!el) { return; }
el.removeAttribute('aria-selected');
el.classList.remove('selected');
if (this.current == el) {
this.selectedChild = null;
this.selected = null;
}
};
// Register and return the constructor
return document.registerElement('gaia-tabs', { prototype: proto });
})(window);

View file

@ -0,0 +1,170 @@
/**
* Gaia Tabs
*
* Tabs allow users to navigate between
* multiple views within a single screen.
*/
gaia-tabs {
display: flex;
position: absolute;
bottom: 0;
width: 100%;
margin: 0;
padding: 0;
z-index: 0;
background: #fff;
border-top: 0.1rem solid #e7e7e7;
}
/**
* [position="top"]
*/
gaia-tabs[position="top"] {
top: 0;
bottom: auto;
height: 4rem;
border-top: none;
border-bottom: 0.1rem solid #e7e7e7;
}
/**
* [skin="dark"]
*/
gaia-tabs[skin="dark"] {
border-color: rgba(189,189,189, 0.1);
}
/** Tab
---------------------------------------------------------*/
gaia-tabs > * {
box-sizing: content-box;
position: relative;
margin: 0;
padding: 0;
height: 4.5rem;
border: 0;
flex: 1 1 0;
font-size: 1.6rem;
line-height: 4.5rem;
text-align: center;
font-family: sans-serif;
text-decoration: none;
color: inherit;
background-color: transparent;
cursor: pointer;
list-style: none;
}
gaia-tabs a {
text-decoration: none;
color: inherit;
}
/**
* [position="top"]
*/
gaia-tabs[position="top"] > * {
height: 4.1rem;
}
/**
* [skin="dark"]
*/
gaia-tabs[skin="dark"] > * {
background-color: #000;
color: #fff;
}
/**
* :active
*/
gaia-tabs > :active {
border-radius: 0;
background-color: #b2f2ff;
}
/**
* .selected
*/
gaia-tabs > .selected {
color: #00aacc;
}
/**
* .selected &
* [skin="dark"]
*/
gaia-tabs[skin="dark"] > .selected {
color: #00aacc;
}
/**
* [disabled]
*/
gaia-tabs > [disabled] {
color: #333;
opacity: 0.25;
pointer-events: none;
}
/**
* [skin="dark"] &
* [disabled]
*/
gaia-tabs[skin="dark"] > [disabled] {
color: rgba(255,255,255,0.4);
opacity: 1;
}
/** Tab Bottom Border
---------------------------------------------------------*/
gaia-tabs > .selected:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
border-bottom: 0.3rem solid #00aacc;
}
/**
* [underline="child"]
* For this option we need a child element
* inside tabs, e.g:
* <gaia-tabs>
* <button><span>Text</span></button>
* </gaia-tabs>
*/
gaia-tabs[underline="child"] > .selected:after {
display: none;
}
gaia-tabs[underline="child"] > .selected > :after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
border-bottom: 0.3rem solid #00aacc;
}
gaia-tabs[underline="child"] > .selected > * {
position: relative;
display: inline-block;
height: 100%;
}