Skip to content

Commit 91399a8

Browse files
committed
Tests for web components
1 parent fca0474 commit 91399a8

17 files changed

+1137
-98
lines changed

css/style.css

Lines changed: 100 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,103 @@
11

2-
/* Plus Button */
3-
.btn-circle {
4-
width: 40px;
5-
height: 40px;
6-
padding: 0px;
7-
margin: 40px;
8-
border-radius: 20px;
9-
text-align: center;
10-
font-size: 36px;
11-
line-height: 0;
12-
}
2+
:root {
3+
/* colours */
4+
--primary-color: #16f;
5+
--secondary-color: #aaa;
6+
--light-color: #eee;
7+
--white-color: #fff;
8+
--dark-color: #333;
9+
--black-color: #000;
10+
11+
/* controls */
12+
--control-color: #bbb;
13+
--control-color-hover: #ccc;
14+
--control-color-active: #ddd;
15+
--control-color-disabled: #ddd;
16+
17+
/* fonts */
18+
--font-size-normal: 0.9rem;
19+
--font-size-small: 0.75rem;
20+
--font-weight-normal: 500;
21+
--font-weight-bold: 700;
22+
--font-weight-extrabold: 700;
23+
24+
/* borders */
25+
--border-radius: 0.25em;
26+
27+
/* badge-view */
28+
--badge-background-color: var(--primary-color);
29+
--badge-color: var(--light-color);
30+
--badge-padding-x: 0.35em;
31+
--badge-padding-y: 0.35em;
32+
--badge-font-size: var(--font-size-small);
33+
--badge-font-weight: var(--font-weight-bold);
34+
--badge-border-radius: var(--border-radius);
35+
36+
/* button-view */
37+
--button-background-color: var(--control-color);
38+
--button-background-color-hover: var(--control-color-hover);
39+
--button-background-color-active: var(--control-color-active);
40+
--button-background-color-disabled: var(--control-color-disabled);
41+
--button-color: var(--dark-color);
42+
--button-color-hover: var(--dark-color);
43+
--button-color-active: var(--light-color);
44+
--button-color-disabled: var(--light-color);
45+
--button-font-weight: var(--font-weight-bold);
46+
--button-font-weight-hover: var(--font-weight-bold);
47+
--button-font-weight-active: var(--font-weight-bold);
48+
--button-font-weight-disabled: var(--font-weight-bold);
49+
--button-border-radius: var(--border-radius);
50+
--button-font-size: var(--font-size-normal);
51+
--button-padding-x: 0.45em;
52+
--button-padding-y: 0.45em;
53+
--button-offset-active: 0.1em;
54+
55+
/* card view */
56+
--card-margin: 0.05em;
57+
--card-padding: 0.15em;
58+
--card-background-color: none;
59+
--card-border-color: var(--light-color);
60+
--card-border-radius: var(--border-radius);
61+
62+
/* navbar-view */
63+
--navbar-background-color: var(--light-color);
64+
--navbar-color: var(--dark-color);
65+
--navbar-border-color: var(--light-color);
66+
--navbar-border-width: 0.5px;
67+
--navbar-padding-y: 0.5em;
68+
--navbar-padding-x: 0.5em;
69+
70+
/* nav-view */
71+
--nav-border-bottom: 1px solid var(--secondary-color);
72+
73+
/* navitem-view */
74+
--navitem-color: var(--dark-color);
75+
--navitem-color-hover: var(--dark-color);
76+
--navitem-color-active: var(--dark-color);
77+
--navitem-color-disabled: var(--light-color);
78+
--navitem-background-color: none;
79+
--navitem-background-color-hover: none;
80+
--navitem-background-color-active: none;
81+
--navitem-background-color-disabled: none;
82+
--navitem-font-weight: var(--font-weight-normal);
83+
--navitem-font-weight-active: var(--font-weight-extrabold);
84+
--navitem-font-weight-hover: var(--font-weight-bold);
85+
--navitem-font-weight-disabled: var(--font-weight-normal);
86+
--navitem-padding-x: 1rem;
87+
--navitem-padding-y: .5rem;
88+
89+
/* stepper-view */
90+
--stepper-background-color: var(--light-color);
91+
--stepper-color: var(--dark-color);
92+
--stepper-btn-color: var(--light-color);
93+
--stepper-btn-background-color: var(--control-color);
94+
--stepper-btn-background-color-hover: var(--control-color-hover);
95+
--stepper-btn-background-color-active: var(--control-color-active);
96+
--stepper-border-radius: var(--border-radius);
97+
--stepper-padding-x: 0.35em;
98+
--stepper-padding-y: 0.35em;
1399

14-
/* Copy Paste */
15-
.mvc-copypaste:before {
16-
content: "\f28b";
17-
display: inline-block;
18-
font-family: bootstrap-icons !important;
19-
font-style: normal;
20-
font-weight: normal;
21-
font-variant: normal;
22-
text-transform: none;
23-
line-height: 1;
24-
margin: 1px;
100+
/* icons */
101+
--icon-plus: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/></svg>');
102+
--icon-minus: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8z"/></svg>');
25103
}

etc/server.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins:
2+
- ../../bin/httpserver.plugin
3+
- ../../bin/log.plugin
4+
- ../../bin/static.plugin
5+
6+
static:
7+
"/": dist/
8+

html/index.html

Lines changed: 111 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,118 @@
11
<!DOCTYPE html>
2+
23
<head>
4+
<title>Storybook</title>
35
<link rel="stylesheet" href="./index.css">
6+
<script type="module" src="./index.js" defer></script>
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
48
</head>
9+
510
<body>
6-
<h1>Storybook</h1>
7-
<div class="row border">
8-
<div class="col-md-2 bg-light">
9-
<ul>
10-
<li>Button</li>
11-
<li>Offcanvas</li>
12-
<li>Tooltip</li>
13-
</ul>
14-
</div>
15-
<div class="col-md-10">
16-
<iframe class="w-100" src="/tooltip.html"></iframe>
17-
</div>
18-
</div>
11+
<navbar-view id="navbar">
12+
<navitem-view>First</navitem-view>
13+
<navitem-view active>Second</navitem-view>
14+
<navitem-view>Third</navitem-view>
15+
</navbar-view>
16+
17+
<row-view>
18+
<col-view width="4" id="left-col" style="border-right: 1px solid gray;">
19+
<nav-view direction="column" id="left-nav">
20+
<navitem-view>First</navitem-view>
21+
<navitem-view active>Second</navitem-view>
22+
<navitem-view>Third</navitem-view>
23+
</nav-view>
24+
</col-view>
25+
<col-view width="8" id="right-col">
26+
<nav-view class="m-4" id="nav">
27+
<navitem-view active name="first">First</navitem-view>
28+
<navitem-view name="second">Second</navitem-view>
29+
<navitem-view disabled name="third">Third</navitem-view>
30+
</nav-view>
31+
<div class="container m-2">
32+
<button-view id="btn-enable">Enabled</button-view>
33+
<button-view id="btn-disabled" disabled>Disabled</button-view>
34+
</div>
35+
<div class="container m-2">
36+
<row-view>
37+
<card-view width="6" background="light">
38+
<h4>Card1</h4>
39+
<p>This is some text within the card</p>
40+
</card-view>
41+
<card-view width="6">
42+
<h1>Card1</h1>
43+
</card-view>
44+
<card-view width="6">
45+
<h1>Card1</h1>
46+
</card-view>
47+
<card-view width="6">
48+
<h1>Card1</h1>
49+
</card-view>
50+
</row-view>
51+
</div>
52+
</col-view>
53+
</row-view>
54+
55+
<model-provider id="provider" href="/api/sqlite3"></model-provider>
56+
57+
<stepper-view id="stepper">4</stepper-view>
58+
59+
<script>
60+
const navBar = document.getElementById('navbar');
61+
const nav = document.getElementById('nav');
62+
const leftNav = document.getElementById('left-nav');
63+
const stepper = document.getElementById('stepper');
64+
const leftCol = document.getElementById('left-col');
65+
const rightCol = document.getElementById('right-col');
66+
const btnEnable = document.getElementById('btn-enable');
67+
const btnDisable = document.getElementById('btn-disabled');
68+
const p = document.getElementById('provider');
69+
70+
console.log(p);
71+
72+
btnEnable.addEventListener('button-view:click', (evt) => {
73+
btnDisable.disabled = false;
74+
});
75+
btnDisable.addEventListener('button-view:click', (evt) => {
76+
btnDisable.disabled = true;
77+
});
78+
navBar.addEventListener('navitem-view:click', (evt) => {
79+
if (navBar.active != evt.detail) {
80+
navBar.active = evt.detail;
81+
}
82+
});
83+
nav.addEventListener('navitem-view:click', (evt) => {
84+
if (nav.active != evt.detail) {
85+
nav.active = evt.detail;
86+
}
87+
});
88+
leftNav.addEventListener('navitem-view:click', (evt) => {
89+
if (leftNav.active != evt.detail) {
90+
leftNav.active = evt.detail;
91+
}
92+
});
93+
stepper.addEventListener('stepper-view:click', (event) => {
94+
switch (event.detail) {
95+
case 'left':
96+
value = parseInt(stepper.textContent, 10);
97+
if (value > 1) {
98+
value = value - 1;
99+
stepper.textContent = value;
100+
leftCol.width = value;
101+
rightCol.width = 12 - value;
102+
}
103+
break;
104+
case 'right':
105+
value = parseInt(stepper.textContent, 10);
106+
if (value < 11) {
107+
value = value + 1;
108+
stepper.textContent = value;
109+
leftCol.width = value;
110+
rightCol.width = 12 - value;
111+
}
112+
break;
113+
}
114+
});
115+
</script>
19116
</body>
117+
20118
</html>

js/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ import 'bootstrap/dist/css/bootstrap.min.css';
2727
import 'bootstrap-icons/font/bootstrap-icons.css';
2828
import '../css/style.css';
2929

30+
// Web Components
31+
import './view/navbar-view';
32+
import './view/nav-view';
33+
import './view/navitem-view';
34+
import './view/badge-view';
35+
import './view/button-view';
36+
import './view/row-view';
37+
import './view/col-view';
38+
import './view/stepper-view';
39+
import './view/card-view';
40+
import './model/model-provider';
41+
3042
// Exports
3143
export {
3244
Model, View, Controller, Provider, Error, Emitter, List, Nav, Toast, Button, Form,

js/model/model-provider.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { nothing } from 'lit-html';
2+
import Component from '../view/component';
3+
4+
/// //////////////////////////////////////////////////////////////////
5+
// EVENTS
6+
7+
const EVENT_ERROR = 'model-provider:error';
8+
9+
export default {
10+
EVENT_ERROR,
11+
};
12+
13+
customElements.define('model-provider', class extends Component {
14+
// Properties
15+
static get observedAttributes() {
16+
return ['href'];
17+
}
18+
19+
get href() {
20+
return this.getAttribute('href') || '/';
21+
}
22+
23+
set href(v) {
24+
this.setAttribute('href', v || '/');
25+
}
26+
27+
// Public methods
28+
request(path, req, interval) {
29+
this.$cancel();
30+
if (!this.$timer) {
31+
this.$fetch(path, req);
32+
}
33+
if (interval) {
34+
this.$timer = setInterval(this.$fetch.bind(this, path, req), interval);
35+
}
36+
}
37+
38+
// Private methods
39+
$cancel() {
40+
if (this.$timer) {
41+
clearTimeout(this.$timer);
42+
this.$timer = undefined;
43+
}
44+
}
45+
46+
$fetch(url, req) {
47+
let absurl = this.href + (url || '');
48+
if (!absurl.hasPrefix('/')) {
49+
absurl = `/${absurl}`;
50+
}
51+
fetch(absurl, req)
52+
.then((response) => {
53+
console.log('got', response);
54+
})
55+
.catch((error) => {
56+
this.dispatchEvent(new CustomEvent(EVENT_ERROR, {
57+
composed: true,
58+
bubbles: true,
59+
detail: error,
60+
}));
61+
});
62+
}
63+
64+
// eslint-disable-next-line class-methods-use-this
65+
template() {
66+
return nothing;
67+
}
68+
});

js/view/badge-view.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { html } from 'lit-html';
2+
import Component from './component';
3+
4+
customElements.define('badge-view', class extends Component {
5+
// eslint-disable-next-line class-methods-use-this
6+
template() {
7+
return html`
8+
<style type="text/css">
9+
slot {
10+
display: inline-block;
11+
background-color: var(--badge-background-color);
12+
color: var(--badge-color);
13+
padding: var(--badge-padding-y) var(--badge-padding-x);
14+
font-size: var(--badge-font-size);
15+
font-weight: var(--badge-font-weight);
16+
border-radius: var(--badge-border-radius);
17+
line-height: 1;
18+
text-align: center;
19+
white-space: nowrap;
20+
vertical-align: baseline;
21+
}
22+
</style>
23+
<slot></slot>
24+
`;
25+
}
26+
});

0 commit comments

Comments
 (0)