kempo-css 1.0.7 → 1.0.9

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 (46) hide show
  1. package/.github/copilot-instructions.md +165 -0
  2. package/.github/prompts/build-theme-editor.prompt.md +89 -0
  3. package/LICENSE.md +91 -0
  4. package/README.md +13 -0
  5. package/docs/.config.json +17 -0
  6. package/docs/components/ThemePropertyInput.js +47 -0
  7. package/docs/demo.inc.html +182 -0
  8. package/docs/docs.inc.html +823 -0
  9. package/{examples → docs/examples}/responsive-grid.html +3 -1
  10. package/docs/index.html +105 -0
  11. package/docs/init.js +4 -0
  12. package/docs/kempo-hljs.min.css +1 -0
  13. package/docs/kempo.min.css +1 -0
  14. package/docs/manifest.json +87 -0
  15. package/docs/nav.js +17 -0
  16. package/docs/theme-editor.html +847 -0
  17. package/package.json +10 -7
  18. package/{build.js → scripts/build.js} +75 -2
  19. package/src/components/ThemePropertyInput.js +154 -0
  20. package/src/kempo-hljs.css +125 -0
  21. package/src/kempo.css +1027 -0
  22. package/index.html +0 -1101
  23. package/src/ColorEditor.js +0 -26
  24. package/src/CssVar.js +0 -56
  25. package/src/lit-all.min.js +0 -120
  26. package/theme-builder.html +0 -286
  27. /package/{kempo-hljs.css → docs/kempo-hljs.css} +0 -0
  28. /package/{kempo.css → docs/kempo.css} +0 -0
  29. /package/{media → docs/media}/hexagon.svg +0 -0
  30. /package/{media → docs/media}/icon-maskable.png +0 -0
  31. /package/{media → docs/media}/icon.svg +0 -0
  32. /package/{media → docs/media}/icon128.png +0 -0
  33. /package/{media → docs/media}/icon144.png +0 -0
  34. /package/{media → docs/media}/icon152.png +0 -0
  35. /package/{media → docs/media}/icon16-48.svg +0 -0
  36. /package/{media → docs/media}/icon16.png +0 -0
  37. /package/{media → docs/media}/icon192.png +0 -0
  38. /package/{media → docs/media}/icon256.png +0 -0
  39. /package/{media → docs/media}/icon32.png +0 -0
  40. /package/{media → docs/media}/icon384.png +0 -0
  41. /package/{media → docs/media}/icon48.png +0 -0
  42. /package/{media → docs/media}/icon512.png +0 -0
  43. /package/{media → docs/media}/icon64.png +0 -0
  44. /package/{media → docs/media}/icon72.png +0 -0
  45. /package/{media → docs/media}/icon96.png +0 -0
  46. /package/{media → docs/media}/kempo-fist.svg +0 -0
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "kempo-css",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "",
5
- "main": "build.js",
5
+ "main": "scripts/build.js",
6
6
  "scripts": {
7
- "build": "node build.js",
8
- "build:watch": "node build.js --watch",
9
- "test": "echo \"Error: no test specified\" && exit 1"
7
+ "build": "node scripts/build.js",
8
+ "build:watch": "node scripts/build.js --watch",
9
+ "test": "echo \"Error: no test specified\" && exit 1",
10
+ "docs": "npx kempo-server --root docs --port 4048"
10
11
  },
11
12
  "keywords": [],
12
13
  "author": "",
13
- "license": "ISC",
14
+ "license": "CC-BY-NC-SA-2.0",
14
15
  "devDependencies": {
15
16
  "clean-css-cli": "^5.6.3"
16
17
  },
@@ -19,6 +20,8 @@
19
20
  "url": "https://github.com/dustinpoissant/kempo-css"
20
21
  },
21
22
  "dependencies": {
22
- "@dustinpoissant/device-frame": "^1.0.1"
23
+ "kempo-server": "^1.9.1",
24
+ "kempo-ui": "^0.0.36",
25
+ "terser": "^5.44.1"
23
26
  }
24
27
  }
@@ -3,6 +3,7 @@
3
3
  const { execSync } = require('child_process');
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
+ const { minify } = require('terser');
6
7
 
7
8
  // Check for watch flag
8
9
  const isWatchMode = process.argv.includes('--watch');
@@ -62,8 +63,80 @@ inputFiles.forEach((inputFile, index) => {
62
63
  }
63
64
  });
64
65
 
65
- console.log('Build complete!');
66
- console.log(`Minified files are in the ${outputDir}/ directory`);
66
+ // Process and minify components
67
+ async function processComponents(){
68
+ const componentsDir = 'src/components';
69
+ const docsComponentsDir = 'docs/components';
70
+
71
+ if(!fs.existsSync(componentsDir)){
72
+ return;
73
+ }
74
+
75
+ if(!fs.existsSync(docsComponentsDir)){
76
+ fs.mkdirSync(docsComponentsDir, { recursive: true });
77
+ console.log(`Created ${docsComponentsDir}/ directory`);
78
+ }
79
+
80
+ const componentFiles = fs.readdirSync(componentsDir).filter(file => file.endsWith('.js'));
81
+
82
+ console.log('\nProcessing JavaScript files...');
83
+ for(const file of componentFiles){
84
+ const srcPath = path.join(componentsDir, file);
85
+ const destPath = path.join(docsComponentsDir, file);
86
+
87
+ try{
88
+ const code = fs.readFileSync(srcPath, 'utf-8');
89
+
90
+ if(file.endsWith('.min.js')){
91
+ fs.writeFileSync(destPath, code);
92
+ console.log(`Copied ${srcPath} → ${destPath} (already minified)`);
93
+ }else{
94
+ console.log(`Minifying ${srcPath}...`);
95
+ const result = await minify(code);
96
+ fs.writeFileSync(destPath, result.code);
97
+ const originalSize = Buffer.byteLength(code, 'utf-8');
98
+ const minifiedSize = Buffer.byteLength(result.code, 'utf-8');
99
+ const savings = ((originalSize - minifiedSize) / originalSize * 100).toFixed(1);
100
+ console.log(` Original: ${(originalSize / 1024).toFixed(1)}KB`);
101
+ console.log(` Minified: ${(minifiedSize / 1024).toFixed(1)}KB`);
102
+ console.log(` Savings: ${savings}%`);
103
+ }
104
+ }catch(error){
105
+ console.error(`Error processing ${srcPath}:`, error.message);
106
+ }
107
+ }
108
+ }
109
+
110
+ processComponents().then(() => {
111
+
112
+ // Copy CSS to docs
113
+ const cssFiles = ['src/kempo.css', 'src/kempo-hljs.css'];
114
+ const docsDir = 'docs';
115
+
116
+ cssFiles.forEach(file => {
117
+ if(fs.existsSync(file)){
118
+ const fileName = path.basename(file);
119
+ const destPath = path.join(docsDir, fileName);
120
+ fs.copyFileSync(file, destPath);
121
+ console.log(`Copied ${file} → ${destPath}`);
122
+ }
123
+ });
124
+
125
+ // Copy minified CSS to docs
126
+ const minifiedFiles = fs.readdirSync(outputDir).filter(file => file.endsWith('.css'));
127
+ minifiedFiles.forEach(file => {
128
+ const srcPath = path.join(outputDir, file);
129
+ const destPath = path.join(docsDir, file);
130
+ fs.copyFileSync(srcPath, destPath);
131
+ console.log(`Copied ${srcPath} → ${destPath}`);
132
+ });
133
+
134
+ console.log('\nBuild complete!');
135
+ console.log(`Minified files are in the ${outputDir}/ directory`);
136
+ }).catch(error => {
137
+ console.error('Build error:', error);
138
+ process.exit(1);
139
+ });
67
140
 
68
141
  // Watch mode functionality
69
142
  if (isWatchMode) {
@@ -0,0 +1,154 @@
1
+ import ShadowComponent from '/kempo-ui/components/ShadowComponent.js';
2
+ import { html, css } from '/kempo-ui/lit-all.min.js';
3
+
4
+ export default class ThemePropertyInput extends ShadowComponent {
5
+ static properties = {
6
+ propName: { type: String, attribute: 'prop-name' },
7
+ value: { type: String },
8
+ availableProperties: { type: Array, attribute: 'available-properties' },
9
+ mode: { type: String },
10
+ initialColor: { type: String, attribute: 'initial-color' }
11
+ };
12
+
13
+ static styles = css`
14
+ :host {
15
+ display: block;
16
+ }
17
+ label {
18
+ display: block;
19
+ margin-bottom: 0.25rem;
20
+ }
21
+ .input-wrapper {
22
+ display: flex;
23
+ gap: 0.5rem;
24
+ align-items: center;
25
+ }
26
+ .mode-select {
27
+ width: 100px;
28
+ flex-shrink: 0;
29
+ }
30
+ .value-input {
31
+ flex: 1;
32
+ }
33
+ `;
34
+
35
+ constructor() {
36
+ super();
37
+ this.propName = '';
38
+ this.value = '';
39
+ this.availableProperties = [];
40
+ this.mode = 'color';
41
+ this.initialColor = '';
42
+ }
43
+
44
+ connectedCallback() {
45
+ super.connectedCallback();
46
+
47
+ if(this.value?.startsWith('var(')) {
48
+ this.mode = 'var';
49
+ }
50
+ }
51
+
52
+ firstUpdated() {
53
+ this.attachColorPickerListener();
54
+ }
55
+
56
+ updated(changedProperties) {
57
+ super.updated?.(changedProperties);
58
+ this.attachColorPickerListener();
59
+ }
60
+
61
+ attachColorPickerListener() {
62
+ if(this.mode === 'color') {
63
+ const colorPicker = this.shadowRoot?.querySelector('k-color-picker');
64
+ if(colorPicker && !colorPicker._hasChangeListener) {
65
+ colorPicker._hasChangeListener = true;
66
+ colorPicker.addEventListener('change', this.handleColorChange);
67
+ colorPicker.addEventListener('input', this.handleColorChange);
68
+ }
69
+ }
70
+ }
71
+
72
+ /*
73
+ Event Handlers
74
+ */
75
+
76
+ handleModeChange = (e) => {
77
+ this.mode = e.target.value;
78
+
79
+ if(this.mode === 'var' && !this.value.startsWith('var(')) {
80
+ this.value = this.availableProperties[0] ? `var(${this.availableProperties[0]})` : '';
81
+ } else if(this.mode === 'color' && this.value.startsWith('var(')) {
82
+ this.value = this.initialColor || '#000000';
83
+ }
84
+
85
+ this.emitChange();
86
+ };
87
+
88
+ handleVarInput = (e) => {
89
+ const varName = e.target.value;
90
+ this.value = varName.startsWith('var(') ? varName : `var(${varName})`;
91
+ this.emitChange();
92
+ };
93
+
94
+ handleColorChange = (e) => {
95
+ this.value = e.target.value;
96
+ this.emitChange();
97
+ };
98
+
99
+ /*
100
+ Utility Functions
101
+ */
102
+
103
+ emitChange() {
104
+ this.dispatchEvent(new CustomEvent('value-change', {
105
+ detail: { propName: this.propName, value: this.value },
106
+ bubbles: true,
107
+ composed: true
108
+ }));
109
+ }
110
+
111
+ /*
112
+ Rendering
113
+ */
114
+
115
+ render() {
116
+ const datalistId = `${this.propName}-datalist`;
117
+ const varName = this.value?.startsWith('var(')
118
+ ? this.value.slice(4, -1).trim()
119
+ : '';
120
+
121
+ return html`
122
+ <label>${this.propName}</label>
123
+ <div class="input-wrapper">
124
+ <select class="mode-select" .value=${this.mode} @change=${this.handleModeChange}>
125
+ <option value="var">Var</option>
126
+ <option value="color">Color</option>
127
+ </select>
128
+
129
+ ${this.mode === 'var'
130
+ ? html`
131
+ <input
132
+ class="value-input"
133
+ list=${datalistId}
134
+ .value=${varName}
135
+ @input=${this.handleVarInput}
136
+ placeholder="--property-name"
137
+ />
138
+ <datalist id=${datalistId}>
139
+ ${this.availableProperties.map(prop => html`<option value=${prop}></option>`)}
140
+ </datalist>
141
+ `
142
+ : html`
143
+ <k-color-picker
144
+ class="value-input"
145
+ value=${this.value}
146
+ ></k-color-picker>
147
+ `
148
+ }
149
+ </div>
150
+ `;
151
+ }
152
+ }
153
+
154
+ customElements.define('k-theme-property-input', ThemePropertyInput);
@@ -0,0 +1,125 @@
1
+ :root {
2
+ --c_text: light-dark(#000000, #DCDCDC);
3
+ --c_keyword: light-dark(#0000ff, #569CD6);
4
+ --c_builtin: light-dark(#00b0e8, #4EC9B0);
5
+ --c_number: light-dark(#709756, #B8D7A3);
6
+ --c_string: light-dark(#a31515, #D69D85);
7
+ --c_regex: light-dark(#914525, #9A5334);
8
+ --c_function: inherit;
9
+ --c_comment: light-dark(#008000, #57A64A);
10
+ --c_doc: light-dark(#808080, #608B4E);
11
+ --c_tag: light-dark(#7d7d7d, #9B9B9B);
12
+ --c_var: light-dark(#b436bf, #BD63C5);
13
+ --c_attr: light-dark(#ff0000, #9CDCFE);
14
+ --c_section: light-dark(#a31515, #ffd700);
15
+ --c_selector: light-dark(#0000ff, #569CD6);
16
+ --c_addition: light-dark(#a31515, #144212);
17
+ --c_deletion: light-dark(#2b91af, #600);
18
+ --c_caret: light-dark(black, white);
19
+ }
20
+
21
+ .hljs {
22
+ display: block;
23
+ overflow-x: auto;
24
+ color: var(--c_text);
25
+ }
26
+
27
+ .hljs-keyword,
28
+ .hljs-literal,
29
+ .hljs-symbol,
30
+ .hljs-name,
31
+ .hljs-link {
32
+ color: var(--c_keyword);
33
+ }
34
+
35
+ .hljs-link {
36
+ text-decoration: underline;
37
+ }
38
+
39
+ .hljs-built_in,
40
+ .hljs-type {
41
+ color: var(--c_builtin);
42
+ }
43
+
44
+ .hljs-number,
45
+ .hljs-class {
46
+ color: var(--c_number);
47
+ }
48
+
49
+ .hljs-string,
50
+ .hljs-meta-string {
51
+ color: var(--c_string);
52
+ }
53
+
54
+ .hljs-regexp,
55
+ .hljs-template-tag {
56
+ color: var(--c_regex);
57
+ }
58
+
59
+ .hljs-subst,
60
+ .hljs-function,
61
+ .hljs-title,
62
+ .hljs-params,
63
+ .hljs-formula {
64
+ color: var(--c_function);
65
+ }
66
+
67
+ .hljs-comment,
68
+ .hljs-quote {
69
+ color: var(--c_comment);
70
+ font-style: italic
71
+ }
72
+
73
+ .hljs-doctag {
74
+ color: var(--c_doc);
75
+ }
76
+
77
+ .hljs-meta,
78
+ .hljs-meta-keyword,
79
+ .hljs-tag {
80
+ color: var(--c_tag);
81
+ }
82
+
83
+ .hljs-variable,
84
+ .hljs-template-variable {
85
+ color: var(--c_var);
86
+ }
87
+
88
+ .hljs-attr,
89
+ .hljs-attribute,
90
+ .hljs-builtin-name {
91
+ color: var(--c_attr);
92
+ }
93
+
94
+ .hljs-section {
95
+ color: var(--c_section);
96
+ }
97
+
98
+ .hljs-emphasis {
99
+ font-style: italic
100
+ }
101
+
102
+ .hljs-strong {
103
+ font-weight: bold
104
+ }
105
+
106
+ .hljs-bullet,
107
+ .hljs-selector-tag,
108
+ .hljs-selector-id,
109
+ .hljs-selector-class,
110
+ .hljs-selector-attr,
111
+ .hljs-selector-pseudo {
112
+ color: var(--c_selector);
113
+ }
114
+
115
+ .hljs-addition {
116
+ background-color: var(--c_addition);
117
+ display: inline-block;
118
+ width: 100%
119
+ }
120
+
121
+ .hljs-deletion {
122
+ background-color: var(--c_deletion);
123
+ display: inline-block;
124
+ width: 100%
125
+ }