Skip to content

Commit 7c3f34e

Browse files
committed
styling for ui api caller
1 parent 6250ba5 commit 7c3f34e

File tree

3 files changed

+64
-38
lines changed

3 files changed

+64
-38
lines changed

example/client/component/api-fetch.js

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import './key-val.js';
2+
import {w3CodeColor} from './w3CodeColor.js';
23
import {API, APIProxy} from '../API.js';
3-
import {w3CodeColor} from '../w3CodeColor.js';
44

55
class APIFetch extends HTMLElement {
66
static __tag = 'api-fetch';
77
static __template = document.createElement('template');
8+
static #funcpattern = /^[_a-zA-Z][_a-zA-Z0-9-.]*$/;
89
#root;
910
#pcntr;
1011
#ccntr;
1112
#rcntr;
13+
#ocntr;
1214
#fname;
1315
#api;
1416
constructor() {
@@ -24,13 +26,17 @@ class APIFetch extends HTMLElement {
2426

2527
this.#fname = this.#root.querySelector('#func');
2628
this.#pcntr = this.#root.querySelector('#para_cntr');
27-
this.#ccntr = this.#root.querySelector('#code_cntr');
28-
this.#rcntr = this.#root.querySelector('#resp_cntr');
29+
this.#ccntr = this.#root.querySelector('#code_cntr pre');
30+
this.#rcntr = this.#root.querySelector('#resp_cntr pre');
31+
this.#ocntr = this.#root.querySelector('#out_cntr');
32+
33+
this.#ocntr.style.display = 'none';
2934

30-
this.#ccntr.style.display = 'none';
31-
this.#rcntr.style.display = 'none';
3235
this.#root.querySelector('#fetch').onclick = async () => {
33-
if(!this.#fname.reportValidity()) {
36+
this.#ocntr.style.display = 'none';
37+
if(!APIFetch.#funcpattern.test(this.#fname.value)) {
38+
this.#fname.setCustomValidity(`Required 'function-name' pattern: ${APIFetch.#funcpattern}`);
39+
this.#fname.reportValidity();
3440
return;
3541
}
3642
let fname = this.#fname.value;
@@ -42,15 +48,15 @@ class APIFetch extends HTMLElement {
4248
}
4349
param = {...param, ...d};
4450
}
45-
this.#rcntr.querySelector('pre').innerHTML = JSON.stringify(await this.#api.fetchRaw(fname, param), null, 4);
51+
this.#rcntr.innerHTML = JSON.stringify(await this.#api.fetchRaw(fname, param), null, 4);
4652

4753
let paramjson = JSON.stringify(param);
4854
let hasparam = Object.entries(param).length === 0;
4955
let paramstr1 = hasparam ? '' : `, ${paramjson}`;
5056
let paramstr2 = hasparam ? '' : paramjson;
5157
let jsonfname = JSON.stringify(fname);
5258

53-
this.#ccntr.querySelector('pre').innerText = `<script type="module">
59+
this.#ccntr.innerText = `<script type="module">
5460
import {API, APIProxy} from './API.js';
5561
const url = '../server/public'; /* The API URL eg: '', 'api' */
5662
const base = window.location.href /* The API base path eg: 'https://api.example.com' */
@@ -86,9 +92,8 @@ const base = window.location.href /* The API base path eg: 'https://api.example.
8692
}
8793
}
8894
</script>`;
89-
w3CodeColor(this.#ccntr.querySelector('pre', 'html'));
90-
this.#ccntr.style.display = 'block';
91-
this.#rcntr.style.display = 'block';
95+
w3CodeColor(this.#ccntr, 'html');
96+
this.#ocntr.style.display = 'grid';
9297
};
9398
}
9499
}
@@ -114,36 +119,47 @@ header {
114119
}
115120
pre {
116121
font-family: Consolas,'Courier New', monospace;
122+
white-space: pre-wrap;
123+
padding: 0;
124+
margin: 0;
125+
margin-top: 0.5em;
117126
}
118127
#cntr {
119128
display: grid;
120129
gap: 0.5em;
121-
grid-template-areas:
122-
"heading heading"
123-
"func func"
124-
"pcntr pcntr"
125-
"add fetch"
126-
"ccntr rcntr";
130+
grid-template-columns: 1fr;
131+
background: #1a237e;
132+
color: white;
127133
}
128134
#para_cntr {
129135
display: grid;
130136
gap: 0.5em;
131137
}
138+
#out_cntr {
139+
display: grid;
140+
grid-template-columns: 1fr 1fr;
141+
padding: 0.5em 1em;
142+
gap: 0.5em
143+
}
144+
#out_cntr > section {
145+
box-shadow: 0 0 0.5em black;
146+
padding: 0.5em 1em;
147+
}
132148
</style><div id="cntr">
133-
<header style="grid-area: heading;">API Caller</header>
134-
<input pattern="[_a-zA-Z][_a-zA-Z0-9-.]*" style="grid-area: func;" type="text" id="func" placeholder="Function Name" required />
135-
<section style="grid-area: pcntr;" id="para_cntr">
136-
<header>Parameters:</header>
137-
</section>
138-
<button style="grid-area: add;" id="add_para">Add parameter</button>
139-
<button style="grid-area: fetch;" id="fetch">Fetch Result</button>
140-
<section style="grid-area: ccntr;" id="code_cntr">
141-
<header>Code Example:</header>
142-
<pre></pre>
143-
</section>
144-
<section style="grid-area: rcntr;" id="resp_cntr">
145-
<header>Raw Response:</header>
146-
<pre></pre>
147-
</section>
149+
<header>API Function: <button id="fetch">Execute 🗘</button></header>
150+
<input type="text" id="func" placeholder="Function Name" required />
151+
<section id="para_cntr">
152+
<header>Parameters: <button id="add_para"><strong>+</strong></button></header>
153+
</section>
154+
</div>
155+
<div id="out_cntr">
156+
<section id="code_cntr">
157+
<header>Code Example:</header>
158+
<pre></pre>
159+
</section>
160+
<section id="resp_cntr">
161+
<header>Raw Response:</header>
162+
<pre></pre>
163+
</section>
148164
</div>`;
149165
customElements.define(APIFetch.__tag, APIFetch);

example/client/component/key-val.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
class KeyVal extends HTMLElement {
22
static __tag = 'key-val';
33
static __template = document.createElement('template');
4+
static #keypattern = /^[_a-zA-Z][_a-zA-Z0-9-]*$/;
45
#root;
56
constructor() {
67
super();
@@ -13,12 +14,21 @@ class KeyVal extends HTMLElement {
1314
get data() {
1415
let keynode = this.#root.querySelector('#key');
1516
let valnode = this.#root.querySelector('#val');
16-
if(!keynode.reportValidity() || !valnode.reportValidity()) {
17+
if(!KeyVal.#keypattern.test(keynode.value)) {
18+
keynode.setCustomValidity(`Required 'key' pattern: ${KeyVal.#keypattern.toString()}`);
19+
keynode.reportValidity();
20+
return null;
21+
}
22+
try {
23+
let value = (valnode.value === '') ? null : JSON.parse(valnode.value);
24+
return {
25+
[keynode.value]: value
26+
};
27+
} catch (error) {
28+
valnode.setCustomValidity('Must be a JSON value');
29+
valnode.reportValidity();
1730
return null;
1831
}
19-
return {
20-
[keynode.value]: valnode.value
21-
};
2232
}
2333
}
2434
KeyVal.__template.innerHTML = `<style>
@@ -45,8 +55,8 @@ input[type="text"], textarea {
4555
vertical-align: middle;
4656
padding: 0.25em;
4757
}
48-
</style><input type="text" name="key" id="key" pattern="[_a-zA-Z][_a-zA-Z0-9-]*" placeholder="Parameter Name" required />
58+
</style><input type="text" name="key" id="key" placeholder="Parameter Name" required />
4959
<strong>:</strong>
50-
<textarea name="val" id="val" cols="30" rows="1" placeholder="Parameter Value"></textarea>
60+
<textarea name="val" id="val" cols="30" rows="1" placeholder="Parameter Value; Must be a JSON value"></textarea>
5161
<input type="button" id="rem" value="🗙" />`;
5262
customElements.define(KeyVal.__tag, KeyVal);

0 commit comments

Comments
 (0)