kempo 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/components/Icon.js +1 -1
  2. package/dist/components/Table.js +1 -0
  3. package/dist/index.js +1 -1
  4. package/dist/kempo-styles.css +1 -1
  5. package/dist/kempo-vars.css +1 -1
  6. package/dist/utils/string.js +1 -1
  7. package/docs/components/_template.html +46 -0
  8. package/docs/components/component.html +1 -1
  9. package/docs/components/table.html +153 -0
  10. package/docs/icons/edit.svg +1 -0
  11. package/docs/index.html +3 -0
  12. package/docs/kempo/components/Icon.js +1 -1
  13. package/docs/kempo/components/Table.js +1 -0
  14. package/docs/kempo/index.js +1 -1
  15. package/docs/kempo/kempo-styles.css +1 -1
  16. package/docs/kempo/kempo-vars.css +1 -1
  17. package/docs/kempo/utils/string.js +1 -1
  18. package/docs/nav-1.inc.html +1 -0
  19. package/docs/nav.inc.html +1 -0
  20. package/docs/search.json +11 -0
  21. package/docs/styles/displays-layouts.html +2 -0
  22. package/docs/styles/embed-1.html +1 -0
  23. package/icons/edit.svg +1 -0
  24. package/package.json +1 -1
  25. package/scripts/build.js +1 -4
  26. package/src/components/Icon.js +37 -5
  27. package/src/components/Table.js +71 -0
  28. package/src/kempo-styles.css +8 -3
  29. package/src/kempo-vars.css +2 -0
  30. package/src/utils/string.js +1 -0
  31. package/dist/components/CodeEditor.js +0 -1
  32. package/dist/components/WebSnippetEditor.js +0 -1
  33. package/dist/kempo.css +0 -1
  34. package/dist/kempo.js +0 -1
  35. package/docs/kempo/components/CodeEditor.js +0 -1
  36. package/docs/kempo/components/WebSnippetEditor.js +0 -1
  37. package/docs/kempo/kempo.css +0 -1
  38. package/docs/kempo/kempo.js +0 -1
  39. package/src/components/CodeEditor.js +0 -144
  40. package/src/components/WebSnippetEditor.js +0 -159
@@ -49,6 +49,7 @@
49
49
  <a href="../components/show-more.html">Show More</a>
50
50
  <a href="../components/sidemenu.html">Side Menu</a>
51
51
  <a href="../components/split.html">Split</a>
52
+ <a href="../components/table.html">Table</a>
52
53
  <a href="../components/tabs.html">Tabs</a>
53
54
  <a href="../components/toggle.html">Toggle</a>
54
55
  <a href="../components/websnippeteditor.html">Web Snippet Editor</a>
package/docs/nav.inc.html CHANGED
@@ -49,6 +49,7 @@
49
49
  <a href="./components/show-more.html">Show More</a>
50
50
  <a href="./components/sidemenu.html">Side Menu</a>
51
51
  <a href="./components/split.html">Split</a>
52
+ <a href="./components/table.html">Table</a>
52
53
  <a href="./components/tabs.html">Tabs</a>
53
54
  <a href="./components/toggle.html">Toggle</a>
54
55
  <a href="./components/websnippeteditor.html">Web Snippet Editor</a>
package/docs/search.json CHANGED
@@ -29,6 +29,17 @@
29
29
  "content"
30
30
  ]
31
31
  },
32
+ "/components/table.html": {
33
+ "name": "Components > Table",
34
+ "terms": [
35
+ "component",
36
+ "table",
37
+ "content",
38
+ "records",
39
+ "fields",
40
+ "data"
41
+ ]
42
+ },
32
43
  "/components/tabs.html": {
33
44
  "name": "Components > Tabs",
34
45
  "terms": [
@@ -148,5 +148,7 @@
148
148
  <p><i>Additional styles may be added to the example output (borders, spacing, colors) for demonstration.</i></p>
149
149
  </main>
150
150
  <script type="module" src="../kempo/components/Import.js"></script>
151
+ <script type="module" src="../kempo/components/Card.js"></script>
152
+ <script type="module" src="../kempo/components/Resize.js"></script>
151
153
  </body>
152
154
  </html>
@@ -27,5 +27,6 @@
27
27
  </div>
28
28
  </div>
29
29
  <script type="module" src="../kempo/components/Import.js"></script>
30
+ <script type="module" src="../kempo/components/ThemeSwitcher.js"></script>
30
31
  </body>
31
32
  </html>
package/icons/edit.svg ADDED
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z"/></svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kempo",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "description": "A web component library",
6
6
  "main": "dist/index.js",
package/scripts/build.js CHANGED
@@ -115,10 +115,7 @@ console.log('Saving kempo-hljs.css');
115
115
  await fs.writeFile('./dist/kempo-hljs.css', minifiedKempoHljsCSS, 'utf-8');
116
116
 
117
117
  console.log('Copying dist/ to docs/');
118
- await fse.ensureDir('./docs/icons'); // will also ensure docs/kempo
118
+ await fse.ensureDir('./docs/'); // will also ensure docs/kempo
119
119
  await fse.copy('./dist', './docs/kempo')
120
120
 
121
- console.log('Copying icons/ to docs/icons/');
122
- await fse.copy('./icons', './docs/icons')
123
-
124
121
  console.log('Build Complete');
@@ -1,5 +1,29 @@
1
1
  import Component from './Component.js';
2
2
 
3
+ const getIconByName = (name) => {
4
+ const tryDir = async (dir) => {
5
+ try {
6
+ const response = await fetch(`${dir}/${name}.svg`);
7
+ if(response.status === 200) return await (response).text();
8
+ } catch(e){
9
+ console.log(e);
10
+ }
11
+ return false;
12
+ }
13
+
14
+ return new Promise( async (resolve, reject) => {
15
+ let svg;
16
+ for(let i=0; i < Icon.pathToIcons.length && !svg; i++){
17
+ svg = await tryDir(Icon.pathToIcons[i]);
18
+ }
19
+ if(svg){
20
+ resolve(svg);
21
+ } else {
22
+ reject('Icon not found');
23
+ }
24
+ });
25
+ }
26
+
3
27
  export default class Icon extends Component {
4
28
  constructor(){
5
29
  super();
@@ -8,6 +32,11 @@ export default class Icon extends Component {
8
32
  name: ''
9
33
  });
10
34
  }
35
+ connectedCallback(){
36
+ // super.connectedCallback();
37
+ // do not call super.connectedCallback because it will attempt to render and then again on attribute change
38
+ // so we are overwriting the parent method and not calling it
39
+ }
11
40
  async render(force){
12
41
  if(await super.render(force)){
13
42
  if(this.src){
@@ -17,9 +46,9 @@ export default class Icon extends Component {
17
46
  this.fixSVG();
18
47
  } else if(!this.innerHTML.length) this.innerHTML = Icon.fallback;
19
48
  } else if(this.name){
20
- const response = await fetch(`${Icon.pathToIcons}/${this.name}.svg`);
21
- if(response.status === 200){
22
- this.innerHTML = await (response).text();
49
+ const svg = await getIconByName(this.name);
50
+ if(svg){
51
+ this.innerHTML = svg;
23
52
  this.fixSVG();
24
53
  } else if(!this.innerHTML.length) this.innerHTML = Icon.fallback;
25
54
  } else {
@@ -31,7 +60,8 @@ export default class Icon extends Component {
31
60
  return false;
32
61
  }
33
62
  attributeChangedCallback(n, oV, nV){
34
- if(['src', 'name'].includes(n)){
63
+ super.attributeChangedCallback(n, oV, nV);
64
+ if(['src', 'name'].includes(n) && nV){
35
65
  this.render(true);
36
66
  }
37
67
  }
@@ -61,7 +91,9 @@ export default class Icon extends Component {
61
91
  'src'
62
92
  ];
63
93
 
64
- static pathToIcons = '/icons';
94
+ static pathToIcons = [
95
+ '/icons'
96
+ ];
65
97
  static fallback = /*html*/`
66
98
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currnetColor" d="M480-79q-16 0-30.5-6T423-102L102-423q-11-12-17-26.5T79-480q0-16 6-31t17-26l321-321q12-12 26.5-17.5T480-881q16 0 31 5.5t26 17.5l321 321q12 11 17.5 26t5.5 31q0 16-5.5 30.5T858-423L537-102q-11 11-26 17t-31 6Zm0-80 321-321-321-321-321 321 321 321Zm-40-281h80v-240h-80v240Zm40 120q17 0 28.5-11.5T520-360q0-17-11.5-28.5T480-400q-17 0-28.5 11.5T440-360q0 17 11.5 28.5T480-320Zm0-160Z"/></svg>
67
99
  `;
@@ -0,0 +1,71 @@
1
+ import Component from './Component.js';
2
+ import { toTitleCase } from '../utils/string.js';
3
+
4
+ export default class Table extends Component {
5
+ constructor(data = false, fields = false){
6
+ super();
7
+
8
+ this.registerProps({
9
+ fields: [],
10
+ records: []
11
+ });
12
+
13
+ /* Init */
14
+ if(data){
15
+ this.setData(data, fields);
16
+ }
17
+ }
18
+ async render(force){
19
+ if(await super.render(force)){
20
+ this.renderFields();
21
+ this.renderRecords();
22
+ return true;
23
+ }
24
+ return false;
25
+ }
26
+ renderFields(){
27
+ this.shadowRoot.getElementById('fields').innerHTML = this.fields.map(({label})=>`<th>${label}</th>`).join('');
28
+ }
29
+ renderRecords(){
30
+ this.shadowRoot.getElementById('records').innerHTML = this.records.map((record) => {
31
+ return `<tr>${this.fields.map(({name})=>`<td>${record[name] || ''}</td>`).join('')}</tr>`;
32
+ }).join('');
33
+ }
34
+
35
+ setData(records, fields = false){
36
+ this.records = records;
37
+ this.fields = fields || Table.extractFieldsFromRecords(this.records);
38
+ this.renderFields();
39
+ this.renderRecords();
40
+ }
41
+
42
+ get shadowTemplate(){
43
+ return /*html*/`
44
+ ${super.shadowTemplate}
45
+ <div class="responsive-table">
46
+ <table>
47
+ <thead id="fields"></thead>
48
+ <tbody id="records"></tbody>
49
+ </table>
50
+ </div>
51
+ `;
52
+ }
53
+ get shadowStyles(){
54
+ return /*css*/`
55
+ ${super.shadowStyles}
56
+ :host {
57
+ display: block;
58
+ margin-bottom: var(--spacer);
59
+ }
60
+ `;
61
+ }
62
+
63
+ static extractFieldsFromRecords(records, recordLimit = 100){
64
+ const names = new Set();
65
+ records.slice(0, recordLimit).forEach( record => {
66
+ Object.keys(record).forEach( name => names.add(name) )
67
+ });
68
+ return [...names].map(name=>({name,label:toTitleCase(name)}));
69
+ }
70
+ }
71
+ window.customElements.define('k-table', Table);
@@ -216,7 +216,7 @@ mark {
216
216
  background-color: var(--c_highlight);
217
217
  color: inherit;
218
218
  }
219
- pre, code {
219
+ .ff-mono, pre, code {
220
220
  font-family: var(--ff_mono);
221
221
  }
222
222
  code {
@@ -258,6 +258,11 @@ a:focus,
258
258
  .link:focus-visible {
259
259
  box-shadow: var(--focus_shadow);
260
260
  }
261
+ .no-link,
262
+ .no-link:hover {
263
+ text-decoration: none;
264
+ color: inherit;
265
+ }
261
266
  hr {
262
267
  border: none;
263
268
  border-top: 1px solid var(--c_border);
@@ -463,7 +468,7 @@ input[type="button"],
463
468
  input[type="submit"],
464
469
  input[type="reset"] {
465
470
  display: inline-block;
466
- padding: var(--spacer_h) var(--spacer);
471
+ padding: var(--btn_padding);
467
472
  background-color: var(--btn_bg);
468
473
  border: 1px solid var(--btn_border);
469
474
  cursor: pointer;
@@ -641,7 +646,7 @@ textarea {
641
646
  background-color: var(--input_bg);
642
647
  color: var(--input_tc);
643
648
  border: var(--input_border_width) solid var(--c_border);
644
- padding: var(--spacer_h) var(--spacer);
649
+ padding: var(--input_padding);
645
650
  margin-bottom: var(--spacer);
646
651
  border-radius: var(--radius);
647
652
  outline: none;
@@ -21,7 +21,9 @@
21
21
  --animation_ms: 256ms;
22
22
  --radius: 0.25rem;
23
23
  --link_decoration: underline;
24
+ --input_padding: var(--spacer_h) var(--spacer);
24
25
  --input_border_width: 2px;
26
+ --btn_padding: var(--spacer_h) var(--spacer);
25
27
  }
26
28
 
27
29
  :root,
@@ -52,6 +52,7 @@ export const unescapeHTML = str => str.replace(/&amp;|&lt;|&gt;|&quot;|&#39;|&#x
52
52
  });
53
53
  export const trim = (str, chars) => str.replace(new RegExp(`^[${chars}]+|[${chars}]+$`, 'g'), '');
54
54
  export const compoundKey = keys => trim(keys.join('.'), '.');
55
+ export const toTitleCase = (input) => input.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/_/g, ' ').trim().replace(/\s+/g, ' ').split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' ');
55
56
 
56
57
  export default {
57
58
  camelToDash,
@@ -1 +0,0 @@
1
- import Component from"./Component.js";import{escapeHTML}from"../utils/string.js";const keyDownHandler=Symbol(),lastValue=Symbol();export default class CodeEditor extends Component{constructor(){super(),this[lastValue]="",this[keyDownHandler]=e=>{const{key:t}=e;"Tab"==t?(e.preventDefault(),document.execCommand("insertText",!1," ")):(e.ctrlKey||e.metaKey)&&"z"===e.key&&(e.preventDefault(),document.execCommand("undo",!1,null))},this.registerAttribute("language","")}async connectedCallback(){super.connectedCallback();this.shadowRoot.getElementById("editor").addEventListener("keydown",this[keyDownHandler]),this.addEventListener("blur",this.highlight),this.value=escapeHTML(this.textContent.trim())}disconnectedCallback(){super.disconnectedCallback(),this.shadowRoot.getElementById("editor").removeEventListener("keydown",this[keyDownHandler])}highlight(){let e;this.value!==this[lastValue]&&this.dispatchEvent(new CustomEvent("change")),e="undefined"!=typeof hljs?this.language?hljs.highlight(this.value,{language:this.language}).value:hljs.highlightAuto(this.value).value:this.value,this.shadowRoot.getElementById("editor").innerHTML=e.split("\n").map((e=>`<div class="line">${e}</div>`)).join(""),this[lastValue]=this.value}get value(){return[...this.shadowRoot.getElementById("editor").querySelectorAll(".line")].map((e=>e.textContent)).join("\n")}set value(e){this.shadowRoot.getElementById("editor").innerHTML=e.split("\n").map((e=>`<div class="line">${e}</div>`)).join(""),this.highlight()}get shadowTemplate(){return'\n <link rel="stylesheet" href="../kempo/kempo-hljs.css" />\n <pre id="editor" contenteditable="true"></pre>\n '}get shadowStyles(){return`\n ${super.shadowStyles}\n :root {\n --d_caret: white;\n --l_caret: black;\n --caret: var(--l_caret);\n }\n @media (prefers-color-scheme: light) { \n :root:not([theme="dark"]) {\n --caret: var(--l_caret);\n }\n }\n :root[theme="light"] {\n --caret: var(--l_caret);\n }\n @media (prefers-color-scheme: dark) {\n :root:not([theme="light"]) {\n --caret: var(--d_caret);\n }\n }\n :root[theme="dark"] {\n --caret: var(--d_caret);\n }\n :host {\n display: block;\n border: 1px solid var(--c_border);\n border-radius: var(--radius);\n max-height: 20rem;\n overflow: auto;\n caret-color: var(--caret);\n }\n :host(:focus-within){\n box-shadow: var(--focus_shadow);\n }\n #editor {\n min-height: 6rem;\n outline: none;\n font-family: var(--ff_mono);\n resize: vertical;\n padding: var(--spacer);\n margin-bottom: 0;\n resize: vertical;\n counter-reset: line-number;\n white-space: pre-wrap;\n padding-left: 2.5rem;\n position: relative;\n }\n #editor .line::before {\n content: counter(line-number); /* Use the counter value as content */\n counter-increment: line-number; /* Increment the counter */\n display: inline-block;\n width: 2rem;\n text-align: right; /* Align numbers to the right */\n opacity: 0.65;\n position: absolute;\n left: 0;\n user-select: none;\n }\n .line {\n width: 100%;\n overflow-wrap: break-word;\n word-break: break-all;\n }\n `}}window.customElements.define("k-code-editor",CodeEditor);
@@ -1 +0,0 @@
1
- import Component from"./Component.js";import{escapeHTML,unescapeHTML}from"../utils/string.js";import"./Split.js";import"./Tabs.js";import"./CodeEditor.js";const changeHandler=Symbol();export default class WebSnippetEditor extends Component{constructor(){super(),this[changeHandler]=()=>{this.renderResults()},this.registerAttributes({useKempo:!1,showHtml:!0,showCss:!0,showJs:!0,scripts:""})}async render(){await super.render();const t=this.querySelector('pre[for="html"]'),e=this.shadowRoot.getElementById("html");e.addEventListener("change",this[changeHandler]),e.value=escapeHTML(t?t.textContent:"<div>\n \n</div>");const n=this.querySelector('pre[for="css"]'),s=this.shadowRoot.getElementById("css");s.addEventListener("change",this[changeHandler]),s.value=n?n.textContent:"div {\n \n}";const o=this.querySelector('pre[for="js"]'),a=this.shadowRoot.getElementById("js");a.addEventListener("change",this[changeHandler]),a.value=o?o.textContent:"",this.renderResults()}renderResults(){const t=this.shadowRoot.getElementById("html").value,e=this.shadowRoot.getElementById("css").value,n=this.shadowRoot.getElementById("js").value,s=this.shadowRoot.getElementById("results");s.innerHTML="";const o=document.createElement("iframe");o.frameBorder="0",s.appendChild(o);const a=o.contentDocument||o.contentWindow.document;a.body.innerHTML=`\n ${this.useKempo?'<link rel="stylesheet" href="../kempo/kempo-vars.css" /><link rel="stylesheet" href="../kempo/kempo-styles.css" />':""}\n <style>\n body, html {\n background-color: transparent;\n }\n body {\n overflow-y: auto;\n padding: var(--spacer_q, 4px);\n }\n ${e}\n </style>\n ${t}\n `,this.useKempo&&this.scripts&&this.scripts.split(",").forEach((t=>{const e=document.createElement("script");e.type="module",e.src=t,a.head.appendChild(e)}));const r=document.createElement("script");r.textContent=n,a.head.appendChild(r)}get shadowTemplate(){return`\n <k-split id="split">\n <k-tabs class="ml">\n ${this.showHtml?'<k-tab for="html">HTML</k-tab>':""}\n ${this.showCss?'<k-tab for="css">CSS</k-tab>':""}\n ${this.showJs?'<k-tab for="js">JS</k-tab>':""}\n <k-tab-content name="html">\n <k-code-editor\n id="html"\n language="xml"\n class="my"\n ></k-code-editor>\n </k-tab-content>\n <k-tab-content name="css">\n <k-code-editor\n id="css"\n language="css"\n class="my"\n ></k-code-editor>\n </k-tab-content>\n <k-tab-content name="js">\n <k-code-editor\n id="js"\n language="js"\n class="my"\n ></k-code-editor>\n </k-tab-content>\n </k-tabs>\n <div\n id="results"\n slot="right"\n ></div>\n </k-split>\n `}get shadowStyles(){return"\n :host {\n --min-height: auto;\n --height: auto;\n --max-height: auto;\n display: block;\n }\n k-tab-content {\n min-height: var(--min-height);\n height: var(--height);\n max-height: var(--max-height);\n }\n k-code-editor {\n max-height: calc(100% - (2 * var(--spacer)));\n }\n #results,\n iframe {\n width: 100%;\n height: 100%;\n background-color: transparent;\n }\n "}}window.customElements.define("k-web-snippet-editor",WebSnippetEditor);
package/dist/kempo.css DELETED
@@ -1 +0,0 @@
1
- :root,[theme="light"]{color-scheme:light;--c_bg:#f9f9f9;--c_bg__inv:#333;--c_bg__alt:#eee;--c_overscroll:white;--c_border:#ccc;--c_border__inv:var(--d_c_bg_border);--c_primary:#36f;--c_primary__hover:#14d;--c_secondary:#93f;--c_secondary__hover:#71d;--c_success:#080;--c_success__hover:#060;--c_warning:#f60;--c_warning__hover:#d40;--c_danger:#f03;--c_danger__hover:#d01;--c_input_accent:#36f;--c_highlight:rgba(41, 100, 210, 0.25);--tc:rgba(0, 0, 0, 0.93);--tc_dark:var(--tc);--tc_light:rgba(255, 255, 255, 0.93);--tc_muted:rgba(0, 0, 0, 0.5);--tc_on_primary:var(--tc_light);--tc_on_secondary:var(--tc_light);--tc_on_success:var(--tc_light);--tc_on_warning:var(--tc_light);--tc_on_danger:var(--tc_light);--c_overlay:rgba(0, 0, 0, 0.5);--tc_primary:#36f;--tc_secondary:#93f;--tc_success:#080;--tc_warning:#f60;--tc_danger:#f03;--btn_box_shadow:0 0 0 transparent;--btn_box_shadow__hover:0 0 0 transparent;--btn_border:transparent;--tc_link:var(--tc_primary);--tc_link__hover:var(--tc_secondary);--tc_link__inv:var(--tc_primary__inv);--tc_link__inv__hover:var(--tc_secondary__inv);--focus_shadow:0 0 2px 2px var(--c_primary);--focus_shadow_on_primary:0 0 2px 2px var(--tc_on_primary);--btn_bg:#f0f0f0;--btn_bg__hover:#e9e9e9;--btn_tc:rgba(0, 0, 0, 0.93);--btn_transparent__hover:rgba(0, 0, 0, 0.05);--input_bg:white;--input_tc:rgba(0, 0, 0, 0.93);--ff_body:"Helvetica Neue", Helvetica, Arial, sans-serif;--ff_heading:"Helvetica Neue", Helvetica, Arial, sans-serif;--ff_mono:Consolas, monaco, monospace;--fs_base:16px;--fs_h6:var(--fs_base);--fs_h5:calc(1.25 * var(--fs_base));--fs_h4:calc(1.5 * var(--fs_base));--fs_h3:calc(1.75 * var(--fs_base));--fs_h2:calc(2 * var(--fs_base));--fs_h1:calc(2.5 * var(--fs_base));--fw_base:400;--fw_bold:700;--spacer:1rem;--spacer_h:calc(0.5 * var(--spacer));--spacer_q:calc(0.25 * var(--spacer));--line-height:1.35em;--container_width:90rem;--animation_ms:256ms;--radius:0.25rem;--drop_shadow:0 0.25rem 0.5rem rgba(0, 0, 0, 0.333);--link_decoration:underline;--input_border_width:2px}[theme="dark"]{color-scheme:dark;--c_bg:#333;--c_bg__inv:#f9f9f9;--c_bg__alt:#222;--c_overscroll:black;--c_border:#777;--c_border__inv:#ccc;--c_primary:#36f;--c_primary__hover:#14d;--c_secondary:#93f;--c_secondary__hover:#71d;--c_success:#080;--c_success__hover:#060;--c_warning:#f60;--c_warning__hover:#d40;--c_danger:#f03;--c_danger__hover:#d01;--c_input_accent:#36f;--c_highlight:rgba(0, 89, 255, 0.25);--tc:rgba(255, 255, 255, 0.93);--tc_dark:rgba(0, 0, 0, 0.93);--tc_light:var(--tc);--tc_muted:rgba(255, 255, 255, 0.5);--tc_on_primary:var(--tc);--tc_on_secondary:var(--tc);--tc_on_success:var(--tc);--tc_on_warning:var(--tc);--tc_on_danger:var(--tc);--c_overlay:rgba(0, 0, 0, 0.5);--tc_primary:#8ab4f8;--tc_secondary:#b6f;--tc_success:#6b6;--tc_warning:#f93;--tc_danger:#f57;--btn_box_shadow:0 0 0 transparent;--btn_box_shadow__hover:0 0 0 transparent;--btn_border:transparent;--tc_link:var(--tc_primary);--tc_link__hover:var(--tc_secondary);--tc_link__inv:var(--tc_primary__inv);--tc_link__inv__hover:var(--tc_secondary__inv);--focus_shadow:0 0 2px 2px var(--c_primary);--focus_shadow_on_primary:0 0 2px 2px var(--tc_on_primary);--btn_bg:#aaa;--btn_bg__hover:#bbb;--btn_tc:rgba(0, 0, 0, 0.93);--btn_transparent__hover:rgba(255, 255, 255, 0.05);--input_bg:white;--input_tc:rgba(0, 0, 0, 0.93);--ff_body:"Helvetica Neue", Helvetica, Arial, sans-serif;--ff_heading:"Helvetica Neue", Helvetica, Arial, sans-serif;--ff_mono:Consolas, monaco, monospace;--fs_base:16px;--fs_h6:var(--fs_base);--fs_h5:calc(1.25 * var(--fs_base));--fs_h4:calc(1.5 * var(--fs_base));--fs_h3:calc(1.75 * var(--fs_base));--fs_h2:calc(2 * var(--fs_base));--fs_h1:calc(2.5 * var(--fs_base));--fw_base:400;--fw_bold:700;--spacer:1rem;--spacer_h:calc(0.5 * var(--spacer));--spacer_q:calc(0.25 * var(--spacer));--line-height:1.35em;--container_width:90rem;--animation_ms:256ms;--radius:0.25rem;--drop_shadow:0 0.25rem 0.5rem rgba(0, 0, 0, 0.25);--link_decoration:underline;--input_border_width:2px}@import './kempo-styles.css';
package/dist/kempo.js DELETED
@@ -1 +0,0 @@
1
- const components={"k-card":"Card","k-code-editor":"CodeEditor","k-dialog":"Dialog","k-icon":"Icon","k-import":"Import","k-resize":"Resize","k-search":"Search","k-show-more":"ShowMore","k-side-menu":"SideMenu","k-split":"Split","k-tabs":"Tabs","k-web-snippet-editor":"WebSnippetEditor"},lookFor=new Set(Object.keys(components));window.kempo=Object.assign({},{pathToRoot:"./",pathToKempoFromRoot:"./kempo/",pathToIconsFromRoot:"./kempo/icons/",autoLoadComponents:()=>{lookFor.forEach((async e=>{if(document.querySelector(e)){const o=`${kempo.pathToRoot}${kempo.pathToKempoFromRoot}components/${components[e]}.js`;console.log(o),import(o),lookFor.delete(e)}}))},_darkModeQuery:window.matchMedia("(prefers-color-scheme: dark)"),_theme:"auto",_themeListener:e=>{"auto"===window.kempo._theme&&document.documentElement.setAttribute("theme",e.matches?"dark":"light")},setTheme:e=>{window.kempo._theme=e,"auto"===window.kempo._theme?document.documentElement.setAttribute("theme",window.kempo._darkModeQuery.matches?"dark":"light"):document.documentElement.setAttribute("theme",e)}},window.kempo||{}),window.kempo.autoLoadComponents(),window.kempo._darkModeQuery.addEventListener("change",window.kempo._themeListener),window.kempo.setTheme(document.documentElement.getAttribute("theme")||"auto");
@@ -1 +0,0 @@
1
- import Component from"./Component.js";import{escapeHTML}from"../utils/string.js";const keyDownHandler=Symbol(),lastValue=Symbol();export default class CodeEditor extends Component{constructor(){super(),this[lastValue]="",this[keyDownHandler]=e=>{const{key:t}=e;"Tab"==t?(e.preventDefault(),document.execCommand("insertText",!1," ")):(e.ctrlKey||e.metaKey)&&"z"===e.key&&(e.preventDefault(),document.execCommand("undo",!1,null))},this.registerAttribute("language","")}async connectedCallback(){super.connectedCallback();this.shadowRoot.getElementById("editor").addEventListener("keydown",this[keyDownHandler]),this.addEventListener("blur",this.highlight),this.value=escapeHTML(this.textContent.trim())}disconnectedCallback(){super.disconnectedCallback(),this.shadowRoot.getElementById("editor").removeEventListener("keydown",this[keyDownHandler])}highlight(){let e;this.value!==this[lastValue]&&this.dispatchEvent(new CustomEvent("change")),e="undefined"!=typeof hljs?this.language?hljs.highlight(this.value,{language:this.language}).value:hljs.highlightAuto(this.value).value:this.value,this.shadowRoot.getElementById("editor").innerHTML=e.split("\n").map((e=>`<div class="line">${e}</div>`)).join(""),this[lastValue]=this.value}get value(){return[...this.shadowRoot.getElementById("editor").querySelectorAll(".line")].map((e=>e.textContent)).join("\n")}set value(e){this.shadowRoot.getElementById("editor").innerHTML=e.split("\n").map((e=>`<div class="line">${e}</div>`)).join(""),this.highlight()}get shadowTemplate(){return'\n <link rel="stylesheet" href="../kempo/kempo-hljs.css" />\n <pre id="editor" contenteditable="true"></pre>\n '}get shadowStyles(){return`\n ${super.shadowStyles}\n :root {\n --d_caret: white;\n --l_caret: black;\n --caret: var(--l_caret);\n }\n @media (prefers-color-scheme: light) { \n :root:not([theme="dark"]) {\n --caret: var(--l_caret);\n }\n }\n :root[theme="light"] {\n --caret: var(--l_caret);\n }\n @media (prefers-color-scheme: dark) {\n :root:not([theme="light"]) {\n --caret: var(--d_caret);\n }\n }\n :root[theme="dark"] {\n --caret: var(--d_caret);\n }\n :host {\n display: block;\n border: 1px solid var(--c_border);\n border-radius: var(--radius);\n max-height: 20rem;\n overflow: auto;\n caret-color: var(--caret);\n }\n :host(:focus-within){\n box-shadow: var(--focus_shadow);\n }\n #editor {\n min-height: 6rem;\n outline: none;\n font-family: var(--ff_mono);\n resize: vertical;\n padding: var(--spacer);\n margin-bottom: 0;\n resize: vertical;\n counter-reset: line-number;\n white-space: pre-wrap;\n padding-left: 2.5rem;\n position: relative;\n }\n #editor .line::before {\n content: counter(line-number); /* Use the counter value as content */\n counter-increment: line-number; /* Increment the counter */\n display: inline-block;\n width: 2rem;\n text-align: right; /* Align numbers to the right */\n opacity: 0.65;\n position: absolute;\n left: 0;\n user-select: none;\n }\n .line {\n width: 100%;\n overflow-wrap: break-word;\n word-break: break-all;\n }\n `}}window.customElements.define("k-code-editor",CodeEditor);
@@ -1 +0,0 @@
1
- import Component from"./Component.js";import{escapeHTML,unescapeHTML}from"../utils/string.js";import"./Split.js";import"./Tabs.js";import"./CodeEditor.js";const changeHandler=Symbol();export default class WebSnippetEditor extends Component{constructor(){super(),this[changeHandler]=()=>{this.renderResults()},this.registerAttributes({useKempo:!1,showHtml:!0,showCss:!0,showJs:!0,scripts:""})}async render(){await super.render();const t=this.querySelector('pre[for="html"]'),e=this.shadowRoot.getElementById("html");e.addEventListener("change",this[changeHandler]),e.value=escapeHTML(t?t.textContent:"<div>\n \n</div>");const n=this.querySelector('pre[for="css"]'),s=this.shadowRoot.getElementById("css");s.addEventListener("change",this[changeHandler]),s.value=n?n.textContent:"div {\n \n}";const o=this.querySelector('pre[for="js"]'),a=this.shadowRoot.getElementById("js");a.addEventListener("change",this[changeHandler]),a.value=o?o.textContent:"",this.renderResults()}renderResults(){const t=this.shadowRoot.getElementById("html").value,e=this.shadowRoot.getElementById("css").value,n=this.shadowRoot.getElementById("js").value,s=this.shadowRoot.getElementById("results");s.innerHTML="";const o=document.createElement("iframe");o.frameBorder="0",s.appendChild(o);const a=o.contentDocument||o.contentWindow.document;a.body.innerHTML=`\n ${this.useKempo?'<link rel="stylesheet" href="../kempo/kempo-vars.css" /><link rel="stylesheet" href="../kempo/kempo-styles.css" />':""}\n <style>\n body, html {\n background-color: transparent;\n }\n body {\n overflow-y: auto;\n padding: var(--spacer_q, 4px);\n }\n ${e}\n </style>\n ${t}\n `,this.useKempo&&this.scripts&&this.scripts.split(",").forEach((t=>{const e=document.createElement("script");e.type="module",e.src=t,a.head.appendChild(e)}));const r=document.createElement("script");r.textContent=n,a.head.appendChild(r)}get shadowTemplate(){return`\n <k-split id="split">\n <k-tabs class="ml">\n ${this.showHtml?'<k-tab for="html">HTML</k-tab>':""}\n ${this.showCss?'<k-tab for="css">CSS</k-tab>':""}\n ${this.showJs?'<k-tab for="js">JS</k-tab>':""}\n <k-tab-content name="html">\n <k-code-editor\n id="html"\n language="xml"\n class="my"\n ></k-code-editor>\n </k-tab-content>\n <k-tab-content name="css">\n <k-code-editor\n id="css"\n language="css"\n class="my"\n ></k-code-editor>\n </k-tab-content>\n <k-tab-content name="js">\n <k-code-editor\n id="js"\n language="js"\n class="my"\n ></k-code-editor>\n </k-tab-content>\n </k-tabs>\n <div\n id="results"\n slot="right"\n ></div>\n </k-split>\n `}get shadowStyles(){return"\n :host {\n --min-height: auto;\n --height: auto;\n --max-height: auto;\n display: block;\n }\n k-tab-content {\n min-height: var(--min-height);\n height: var(--height);\n max-height: var(--max-height);\n }\n k-code-editor {\n max-height: calc(100% - (2 * var(--spacer)));\n }\n #results,\n iframe {\n width: 100%;\n height: 100%;\n background-color: transparent;\n }\n "}}window.customElements.define("k-web-snippet-editor",WebSnippetEditor);
@@ -1 +0,0 @@
1
- :root,[theme="light"]{color-scheme:light;--c_bg:#f9f9f9;--c_bg__inv:#333;--c_bg__alt:#eee;--c_overscroll:white;--c_border:#ccc;--c_border__inv:var(--d_c_bg_border);--c_primary:#36f;--c_primary__hover:#14d;--c_secondary:#93f;--c_secondary__hover:#71d;--c_success:#080;--c_success__hover:#060;--c_warning:#f60;--c_warning__hover:#d40;--c_danger:#f03;--c_danger__hover:#d01;--c_input_accent:#36f;--c_highlight:rgba(41, 100, 210, 0.25);--tc:rgba(0, 0, 0, 0.93);--tc_dark:var(--tc);--tc_light:rgba(255, 255, 255, 0.93);--tc_muted:rgba(0, 0, 0, 0.5);--tc_on_primary:var(--tc_light);--tc_on_secondary:var(--tc_light);--tc_on_success:var(--tc_light);--tc_on_warning:var(--tc_light);--tc_on_danger:var(--tc_light);--c_overlay:rgba(0, 0, 0, 0.5);--tc_primary:#36f;--tc_secondary:#93f;--tc_success:#080;--tc_warning:#f60;--tc_danger:#f03;--btn_box_shadow:0 0 0 transparent;--btn_box_shadow__hover:0 0 0 transparent;--btn_border:transparent;--tc_link:var(--tc_primary);--tc_link__hover:var(--tc_secondary);--tc_link__inv:var(--tc_primary__inv);--tc_link__inv__hover:var(--tc_secondary__inv);--focus_shadow:0 0 2px 2px var(--c_primary);--focus_shadow_on_primary:0 0 2px 2px var(--tc_on_primary);--btn_bg:#f0f0f0;--btn_bg__hover:#e9e9e9;--btn_tc:rgba(0, 0, 0, 0.93);--btn_transparent__hover:rgba(0, 0, 0, 0.05);--input_bg:white;--input_tc:rgba(0, 0, 0, 0.93);--ff_body:"Helvetica Neue", Helvetica, Arial, sans-serif;--ff_heading:"Helvetica Neue", Helvetica, Arial, sans-serif;--ff_mono:Consolas, monaco, monospace;--fs_base:16px;--fs_h6:var(--fs_base);--fs_h5:calc(1.25 * var(--fs_base));--fs_h4:calc(1.5 * var(--fs_base));--fs_h3:calc(1.75 * var(--fs_base));--fs_h2:calc(2 * var(--fs_base));--fs_h1:calc(2.5 * var(--fs_base));--fw_base:400;--fw_bold:700;--spacer:1rem;--spacer_h:calc(0.5 * var(--spacer));--spacer_q:calc(0.25 * var(--spacer));--line-height:1.35em;--container_width:90rem;--animation_ms:256ms;--radius:0.25rem;--drop_shadow:0 0.25rem 0.5rem rgba(0, 0, 0, 0.333);--link_decoration:underline;--input_border_width:2px}[theme="dark"]{color-scheme:dark;--c_bg:#333;--c_bg__inv:#f9f9f9;--c_bg__alt:#222;--c_overscroll:black;--c_border:#777;--c_border__inv:#ccc;--c_primary:#36f;--c_primary__hover:#14d;--c_secondary:#93f;--c_secondary__hover:#71d;--c_success:#080;--c_success__hover:#060;--c_warning:#f60;--c_warning__hover:#d40;--c_danger:#f03;--c_danger__hover:#d01;--c_input_accent:#36f;--c_highlight:rgba(0, 89, 255, 0.25);--tc:rgba(255, 255, 255, 0.93);--tc_dark:rgba(0, 0, 0, 0.93);--tc_light:var(--tc);--tc_muted:rgba(255, 255, 255, 0.5);--tc_on_primary:var(--tc);--tc_on_secondary:var(--tc);--tc_on_success:var(--tc);--tc_on_warning:var(--tc);--tc_on_danger:var(--tc);--c_overlay:rgba(0, 0, 0, 0.5);--tc_primary:#8ab4f8;--tc_secondary:#b6f;--tc_success:#6b6;--tc_warning:#f93;--tc_danger:#f57;--btn_box_shadow:0 0 0 transparent;--btn_box_shadow__hover:0 0 0 transparent;--btn_border:transparent;--tc_link:var(--tc_primary);--tc_link__hover:var(--tc_secondary);--tc_link__inv:var(--tc_primary__inv);--tc_link__inv__hover:var(--tc_secondary__inv);--focus_shadow:0 0 2px 2px var(--c_primary);--focus_shadow_on_primary:0 0 2px 2px var(--tc_on_primary);--btn_bg:#aaa;--btn_bg__hover:#bbb;--btn_tc:rgba(0, 0, 0, 0.93);--btn_transparent__hover:rgba(255, 255, 255, 0.05);--input_bg:white;--input_tc:rgba(0, 0, 0, 0.93);--ff_body:"Helvetica Neue", Helvetica, Arial, sans-serif;--ff_heading:"Helvetica Neue", Helvetica, Arial, sans-serif;--ff_mono:Consolas, monaco, monospace;--fs_base:16px;--fs_h6:var(--fs_base);--fs_h5:calc(1.25 * var(--fs_base));--fs_h4:calc(1.5 * var(--fs_base));--fs_h3:calc(1.75 * var(--fs_base));--fs_h2:calc(2 * var(--fs_base));--fs_h1:calc(2.5 * var(--fs_base));--fw_base:400;--fw_bold:700;--spacer:1rem;--spacer_h:calc(0.5 * var(--spacer));--spacer_q:calc(0.25 * var(--spacer));--line-height:1.35em;--container_width:90rem;--animation_ms:256ms;--radius:0.25rem;--drop_shadow:0 0.25rem 0.5rem rgba(0, 0, 0, 0.25);--link_decoration:underline;--input_border_width:2px}@import './kempo-styles.css';
@@ -1 +0,0 @@
1
- const components={"k-card":"Card","k-code-editor":"CodeEditor","k-dialog":"Dialog","k-icon":"Icon","k-import":"Import","k-resize":"Resize","k-search":"Search","k-show-more":"ShowMore","k-side-menu":"SideMenu","k-split":"Split","k-tabs":"Tabs","k-web-snippet-editor":"WebSnippetEditor"},lookFor=new Set(Object.keys(components));window.kempo=Object.assign({},{pathToRoot:"./",pathToKempoFromRoot:"./kempo/",pathToIconsFromRoot:"./kempo/icons/",autoLoadComponents:()=>{lookFor.forEach((async e=>{if(document.querySelector(e)){const o=`${kempo.pathToRoot}${kempo.pathToKempoFromRoot}components/${components[e]}.js`;console.log(o),import(o),lookFor.delete(e)}}))},_darkModeQuery:window.matchMedia("(prefers-color-scheme: dark)"),_theme:"auto",_themeListener:e=>{"auto"===window.kempo._theme&&document.documentElement.setAttribute("theme",e.matches?"dark":"light")},setTheme:e=>{window.kempo._theme=e,"auto"===window.kempo._theme?document.documentElement.setAttribute("theme",window.kempo._darkModeQuery.matches?"dark":"light"):document.documentElement.setAttribute("theme",e)}},window.kempo||{}),window.kempo.autoLoadComponents(),window.kempo._darkModeQuery.addEventListener("change",window.kempo._themeListener),window.kempo.setTheme(document.documentElement.getAttribute("theme")||"auto");
@@ -1,144 +0,0 @@
1
- import Component from './Component.js';
2
- import {
3
- escapeHTML
4
- } from '../utils/string.js';
5
-
6
- const keyDownHandler = Symbol(),
7
- lastValue = Symbol();
8
- export default class CodeEditor extends Component {
9
- constructor(){
10
- super();
11
-
12
- /* Private Members */
13
- this[lastValue] = '';
14
-
15
- /* Private Methods */
16
- this[keyDownHandler] = (event) => {
17
- const { key } = event;
18
- if(key == 'Tab'){
19
- event.preventDefault();
20
- document.execCommand('insertText', false, ' ');
21
- } else if ((event.ctrlKey || event.metaKey) && event.key === 'z') {
22
- event.preventDefault();
23
- document.execCommand('undo', false, null);
24
- }
25
- }
26
-
27
- this.registerAttribute('language', '');
28
- }
29
-
30
- async connectedCallback(){
31
- super.connectedCallback();
32
- const $editor = this.shadowRoot.getElementById('editor');
33
- $editor.addEventListener('keydown', this[keyDownHandler]);
34
- this.addEventListener('blur', this.highlight);
35
- this.value = escapeHTML(this.textContent.trim());
36
- }
37
- disconnectedCallback(){
38
- super.disconnectedCallback();
39
- this.shadowRoot.getElementById('editor').removeEventListener('keydown', this[keyDownHandler]);
40
- }
41
-
42
- highlight(){
43
- if(this.value !== this[lastValue]){
44
- this.dispatchEvent(new CustomEvent('change'));
45
- }
46
- let result;
47
- if(typeof(hljs) !== 'undefined'){
48
- if(this.language){
49
- result = (hljs.highlight(
50
- this.value,
51
- { language: this.language }
52
- )).value;
53
- } else {
54
- result = (hljs.highlightAuto(this.value)).value;
55
- }
56
- } else {
57
- result = this.value;
58
- }
59
- this.shadowRoot.getElementById('editor').innerHTML = result.split('\n').map(p=>`<div class="line">${p}</div>`).join('');
60
- this[lastValue] = this.value;
61
- }
62
-
63
- get value(){
64
- return [...this.shadowRoot.getElementById('editor').querySelectorAll('.line')].map($line=>$line.textContent).join('\n');
65
- }
66
- set value(v){
67
- this.shadowRoot.getElementById('editor').innerHTML = v.split('\n').map(p=>`<div class="line">${p}</div>`).join('');
68
- this.highlight();
69
- }
70
-
71
- get shadowTemplate(){
72
- return /*html*/`
73
- <link rel="stylesheet" href="../kempo/kempo-hljs.css" />
74
- <pre id="editor" contenteditable="true"></pre>
75
- `;
76
- }
77
- get shadowStyles(){
78
- return /*css*/`
79
- ${super.shadowStyles}
80
- :root {
81
- --d_caret: white;
82
- --l_caret: black;
83
- --caret: var(--l_caret);
84
- }
85
- @media (prefers-color-scheme: light) {
86
- :root:not([theme="dark"]) {
87
- --caret: var(--l_caret);
88
- }
89
- }
90
- :root[theme="light"] {
91
- --caret: var(--l_caret);
92
- }
93
- @media (prefers-color-scheme: dark) {
94
- :root:not([theme="light"]) {
95
- --caret: var(--d_caret);
96
- }
97
- }
98
- :root[theme="dark"] {
99
- --caret: var(--d_caret);
100
- }
101
- :host {
102
- display: block;
103
- border: 1px solid var(--c_border);
104
- border-radius: var(--radius);
105
- max-height: 20rem;
106
- overflow: auto;
107
- caret-color: var(--caret);
108
- }
109
- :host(:focus-within){
110
- box-shadow: var(--focus_shadow);
111
- }
112
- #editor {
113
- min-height: 6rem;
114
- outline: none;
115
- font-family: var(--ff_mono);
116
- resize: vertical;
117
- padding: var(--spacer);
118
- margin-bottom: 0;
119
- resize: vertical;
120
- counter-reset: line-number;
121
- white-space: pre-wrap;
122
- padding-left: 2.5rem;
123
- position: relative;
124
- }
125
- #editor .line::before {
126
- content: counter(line-number); /* Use the counter value as content */
127
- counter-increment: line-number; /* Increment the counter */
128
- display: inline-block;
129
- width: 2rem;
130
- text-align: right; /* Align numbers to the right */
131
- opacity: 0.65;
132
- position: absolute;
133
- left: 0;
134
- user-select: none;
135
- }
136
- .line {
137
- width: 100%;
138
- overflow-wrap: break-word;
139
- word-break: break-all;
140
- }
141
- `;
142
- }
143
- }
144
- window.customElements.define('k-code-editor', CodeEditor);