kempo-ui 0.0.2 → 0.0.3

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 (193) hide show
  1. package/.github/copilot-instructions.md +149 -149
  2. package/.github/workflows/publish-npm.yml +44 -44
  3. package/CONTRIBUTING.md +149 -149
  4. package/README.md +0 -0
  5. package/dist/kempo-vars.css +0 -0
  6. package/dist/src/components/FocusCapture.js +7 -0
  7. package/dist/src/components/Icon.js +10 -0
  8. package/dist/src/components/Import.js +1 -0
  9. package/dist/src/components/ShadowComponent.js +1 -0
  10. package/dist/src/components/SideMenu.js +97 -0
  11. package/dist/src/lit-all.min.js +120 -0
  12. package/docs/components/accordion.html +122 -0
  13. package/docs/components/card.html +91 -0
  14. package/docs/components/component.html +90 -0
  15. package/docs/components/content-slider.html +193 -0
  16. package/docs/components/dialog.html +245 -0
  17. package/docs/components/directory-viewer.html +90 -0
  18. package/docs/components/focus-capture.html +68 -0
  19. package/docs/components/icon.html +161 -0
  20. package/docs/components/import.html +78 -0
  21. package/docs/components/lazy-component.html +84 -0
  22. package/docs/components/reactive-component.html +69 -0
  23. package/docs/components/reactive-lazy-component.html +69 -0
  24. package/docs/components/resize.html +152 -0
  25. package/docs/components/search.html +102 -0
  26. package/docs/components/show-more.html +123 -0
  27. package/docs/components/side-menu.html +168 -0
  28. package/docs/components/sortable.html +96 -0
  29. package/docs/components/split.html +126 -0
  30. package/docs/components/table.html +312 -0
  31. package/docs/components/tableControls.html +77 -0
  32. package/docs/components/tableCustomFields.html +113 -0
  33. package/docs/components/tableFetchRecords.html +114 -0
  34. package/docs/components/tableFieldSortHide.html +75 -0
  35. package/docs/components/tablePagination.html +100 -0
  36. package/docs/components/tableRecordEditing.html +144 -0
  37. package/docs/components/tableRecordFiltering.html +75 -0
  38. package/docs/components/tableRecordHiding.html +80 -0
  39. package/docs/components/tableRecordSearching.html +75 -0
  40. package/docs/components/tableRecordSelection.html +75 -0
  41. package/docs/components/tableRowControls.html +78 -0
  42. package/docs/components/tableSorting.html +73 -0
  43. package/docs/components/tabs.html +163 -0
  44. package/docs/components/tags.html +94 -0
  45. package/docs/components/theme-switcher.html +129 -0
  46. package/docs/components/timestamp.html +86 -0
  47. package/docs/components/toast.html +328 -0
  48. package/docs/components/toggle.html +155 -0
  49. package/docs/dev.config.json +20 -0
  50. package/docs/icons/add.svg +1 -0
  51. package/docs/icons/arrow-back.svg +1 -0
  52. package/docs/icons/arrow-down-double.svg +1 -0
  53. package/docs/icons/arrow-down.svg +1 -0
  54. package/docs/icons/arrow-forward.svg +1 -0
  55. package/docs/icons/arrow-up-double.svg +1 -0
  56. package/docs/icons/arrow-up.svg +1 -0
  57. package/docs/icons/cards.svg +1 -0
  58. package/docs/icons/check.svg +1 -0
  59. package/docs/icons/chevron-left.svg +1 -0
  60. package/docs/icons/chevron-right.svg +1 -0
  61. package/docs/icons/close.svg +2 -0
  62. package/docs/icons/compare.svg +1 -0
  63. package/docs/icons/delete.svg +1 -0
  64. package/docs/icons/drag-handle.svg +1 -0
  65. package/docs/icons/drawing2.svg +124 -0
  66. package/docs/icons/edit.svg +1 -0
  67. package/docs/icons/error.svg +1 -0
  68. package/docs/icons/export-file.svg +1 -0
  69. package/docs/icons/file-text.svg +1 -0
  70. package/docs/icons/file.svg +1 -0
  71. package/docs/icons/filter-off.svg +1 -0
  72. package/docs/icons/filter.svg +1 -0
  73. package/docs/icons/first.svg +1 -0
  74. package/docs/icons/folder-clear.svg +1 -0
  75. package/docs/icons/folder-create.svg +1 -0
  76. package/docs/icons/folder-open.svg +1 -0
  77. package/docs/icons/folder.svg +1 -0
  78. package/docs/icons/hide.svg +1 -0
  79. package/docs/icons/image.svg +1 -0
  80. package/docs/icons/label-add.svg +1 -0
  81. package/docs/icons/label.svg +1 -0
  82. package/docs/icons/last.svg +1 -0
  83. package/docs/icons/menu.svg +1 -0
  84. package/docs/icons/mode-auto.svg +1 -0
  85. package/docs/icons/mode-dark.svg +1 -0
  86. package/docs/icons/mode-light.svg +1 -0
  87. package/docs/icons/open-in-browser.svg +1 -0
  88. package/docs/icons/pause.svg +1 -0
  89. package/docs/icons/play.svg +1 -0
  90. package/docs/icons/refresh.svg +1 -0
  91. package/docs/icons/remove.svg +1 -0
  92. package/docs/icons/save.svg +1 -0
  93. package/docs/icons/search.svg +1 -0
  94. package/docs/icons/settings.svg +1 -0
  95. package/docs/icons/show.svg +1 -0
  96. package/docs/icons/storage.svg +1 -0
  97. package/docs/icons/table-visibility.svg +1 -0
  98. package/docs/icons/tag.svg +1 -0
  99. package/docs/icons/tools.svg +1 -0
  100. package/docs/icons/trash-x.svg +1 -0
  101. package/docs/icons/warning.svg +1 -0
  102. package/docs/index.html +28 -21
  103. package/docs/nav.inc.html +73 -0
  104. package/docs/nav.inc.js +4 -0
  105. package/{config/production.json → docs/prod.config.json} +20 -16
  106. package/docs/src/components/FocusCapture.js +7 -0
  107. package/docs/src/components/HybridComponent.js +1 -0
  108. package/docs/src/components/Icon.js +10 -0
  109. package/docs/src/components/Import.js +1 -0
  110. package/docs/src/components/LightComponent.js +1 -0
  111. package/docs/src/components/ShadowComponent.js +1 -0
  112. package/docs/src/components/SideMenu.js +97 -0
  113. package/docs/src/lit-all.min.js +120 -0
  114. package/docs/src/utils/cli.js +1 -0
  115. package/docs/src/utils/fs-utils.js +1 -0
  116. package/docs/styles.css +6 -0
  117. package/icons/add.svg +1 -0
  118. package/icons/arrow-back.svg +1 -0
  119. package/icons/arrow-down-double.svg +1 -0
  120. package/icons/arrow-down.svg +1 -0
  121. package/icons/arrow-forward.svg +1 -0
  122. package/icons/arrow-up-double.svg +1 -0
  123. package/icons/arrow-up.svg +1 -0
  124. package/icons/cards.svg +1 -0
  125. package/icons/check.svg +1 -0
  126. package/icons/chevron-left.svg +1 -0
  127. package/icons/chevron-right.svg +1 -0
  128. package/icons/close.svg +2 -0
  129. package/icons/compare.svg +1 -0
  130. package/icons/delete.svg +1 -0
  131. package/icons/drag-handle.svg +1 -0
  132. package/icons/drawing2.svg +124 -0
  133. package/icons/edit.svg +1 -0
  134. package/icons/error.svg +1 -0
  135. package/icons/export-file.svg +1 -0
  136. package/icons/file-text.svg +1 -0
  137. package/icons/file.svg +1 -0
  138. package/icons/filter-off.svg +1 -0
  139. package/icons/filter.svg +1 -0
  140. package/icons/first.svg +1 -0
  141. package/icons/folder-clear.svg +1 -0
  142. package/icons/folder-create.svg +1 -0
  143. package/icons/folder-open.svg +1 -0
  144. package/icons/folder.svg +1 -0
  145. package/icons/hide.svg +1 -0
  146. package/icons/image.svg +1 -0
  147. package/icons/label-add.svg +1 -0
  148. package/icons/label.svg +1 -0
  149. package/icons/last.svg +1 -0
  150. package/icons/menu.svg +1 -0
  151. package/icons/mode-auto.svg +1 -0
  152. package/icons/mode-dark.svg +1 -0
  153. package/icons/mode-light.svg +1 -0
  154. package/icons/open-in-browser.svg +1 -0
  155. package/icons/pause.svg +1 -0
  156. package/icons/play.svg +1 -0
  157. package/icons/refresh.svg +1 -0
  158. package/icons/remove.svg +1 -0
  159. package/icons/save.svg +1 -0
  160. package/icons/search.svg +1 -0
  161. package/icons/settings.svg +1 -0
  162. package/icons/show.svg +1 -0
  163. package/icons/storage.svg +1 -0
  164. package/icons/table-visibility.svg +1 -0
  165. package/icons/tag.svg +1 -0
  166. package/icons/tools.svg +1 -0
  167. package/icons/trash-x.svg +1 -0
  168. package/icons/warning.svg +1 -0
  169. package/package.json +2 -2
  170. package/scripts/build.js +109 -138
  171. package/scripts/docs.js +60 -60
  172. package/src/components/Card.js +66 -0
  173. package/src/components/FocusCapture.js +23 -0
  174. package/src/components/HybridComponent.js +40 -40
  175. package/src/components/Icon.js +155 -0
  176. package/src/components/Import.js +104 -0
  177. package/src/components/LightComponent.js +32 -32
  178. package/src/components/ShadowComponent.js +30 -17
  179. package/src/components/SideMenu.js +167 -0
  180. package/src/components/ThemeSwitcher.js +108 -0
  181. package/src/kempo-hljs.css +146 -0
  182. package/src/utils/cli.js +43 -43
  183. package/src/utils/fs-utils.js +41 -41
  184. package/src/utils/propConverters.js +11 -0
  185. package/tests/HybridComponent.browser-test.js +214 -214
  186. package/tests/LightComponent.browser-test.js +169 -169
  187. package/tests/ShadowComponent.browser-test.js +130 -130
  188. package/config/development.json +0 -14
  189. package/docs/components/ShadowComponent.js +0 -1
  190. /package/{docs → dist/src}/components/HybridComponent.js +0 -0
  191. /package/{docs → dist/src}/components/LightComponent.js +0 -0
  192. /package/{docs → dist/src}/utils/cli.js +0 -0
  193. /package/{docs → dist/src}/utils/fs-utils.js +0 -0
@@ -0,0 +1,108 @@
1
+ import ShadowComponent from './ShadowComponent.js';
2
+ import { html, css } from '../lit-all.min.js';
3
+ import './Icon.js';
4
+
5
+ export default class ThemeSwitcher extends ShadowComponent {
6
+ /*
7
+ Properties
8
+ */
9
+ static properties = {
10
+ currentTheme: { type: String, reflect: true, attribute: 'current-theme' }
11
+ };
12
+
13
+ constructor() {
14
+ super();
15
+ this.currentTheme = ThemeSwitcher.getCurrentTheme();
16
+ }
17
+
18
+ /*
19
+ Event Handlers
20
+ */
21
+ handleClick = () => {
22
+ const current = ThemeSwitcher.getCurrentTheme();
23
+ if(current === 'auto') ThemeSwitcher.setTheme('light');
24
+ if(current === 'light') ThemeSwitcher.setTheme('dark');
25
+ if(current === 'dark') ThemeSwitcher.setTheme('auto');
26
+ }
27
+
28
+ handleStorageChange = () => {
29
+ this.currentTheme = ThemeSwitcher.getCurrentTheme();
30
+ }
31
+
32
+ /*
33
+ Lifecycle Callbacks
34
+ */
35
+ connectedCallback() {
36
+ super.connectedCallback();
37
+ window.addEventListener('storage', this.handleStorageChange);
38
+ }
39
+
40
+ disconnectedCallback() {
41
+ super.disconnectedCallback();
42
+ window.removeEventListener('storage', this.handleStorageChange);
43
+ }
44
+
45
+ /*
46
+ Styles
47
+ */
48
+ static styles = css`
49
+ :host {
50
+ --padding: var(--spacer);
51
+ display: flex;
52
+ }
53
+ button {
54
+ padding: var(--padding);
55
+ }
56
+ `;
57
+
58
+ /*
59
+ Rendering
60
+ */
61
+ render() {
62
+ const iconName = this.currentTheme === 'auto' ? 'mode-auto' :
63
+ this.currentTheme === 'light' ? 'mode-light' : 'mode-dark';
64
+
65
+ return html`
66
+ <button
67
+ class="no-btn"
68
+ @click=${this.handleClick}
69
+ >
70
+ <k-icon name=${iconName}></k-icon>
71
+ </button>
72
+ `;
73
+ }
74
+ static styles = css`
75
+ :host {
76
+ --padding: var(--spacer, 1rem);
77
+ }
78
+ button.no-btn {
79
+ padding: var(--padding);
80
+ }
81
+ `;
82
+
83
+ /*
84
+ Static Methods
85
+ */
86
+ static setTheme(theme) {
87
+ localStorage.setItem('theme', theme);
88
+ document.documentElement.setAttribute('theme', theme);
89
+ window.dispatchEvent(new StorageEvent('storage', { key: 'theme', newValue: theme }));
90
+ }
91
+
92
+ static getCurrentTheme() {
93
+ let theme = document.documentElement.getAttribute('theme');
94
+ if(!theme) theme = localStorage.getItem('theme');
95
+ return theme || 'auto';
96
+ }
97
+ }
98
+
99
+ /*
100
+ Auto Theme Detection
101
+ */
102
+ const colorSchemeQuery = window.matchMedia('(prefers-color-scheme: dark)');
103
+ const colorSchemeChangeHandler = event => document.documentElement.setAttribute('auto-theme', event.matches ? 'dark' : 'light');
104
+ colorSchemeQuery.addEventListener('change', colorSchemeChangeHandler);
105
+ colorSchemeChangeHandler(colorSchemeQuery);
106
+
107
+ ThemeSwitcher.setTheme(ThemeSwitcher.getCurrentTheme());
108
+ customElements.define('k-theme-switcher', ThemeSwitcher);
@@ -0,0 +1,146 @@
1
+ :root,
2
+ [theme="light"] {
3
+ --c_text: #000000;
4
+ --c_keyword: #0000ff;
5
+ --c_builtin: #00b0e8;
6
+ --c_number: #709756;
7
+ --c_string: #a31515;
8
+ --c_regex: #914525;
9
+ --c_function: inherit;
10
+ --c_comment: #008000;
11
+ --c_doc: #808080;
12
+ --c_tag: #7d7d7d;
13
+ --c_var: #b436bf;
14
+ --c_attr: #ff0000;
15
+ --c_section: #a31515;
16
+ --c_selector: #0000ff;
17
+ --c_addition: #a31515;
18
+ --c_deletion: #2b91af;
19
+ --c_caret: black;
20
+ }
21
+ [auto-theme="dark"]:not([theme="light"]),
22
+ [theme="dark"] {
23
+ --c_text: #DCDCDC;
24
+ --c_keyword: #569CD6;
25
+ --c_builtin: #4EC9B0;
26
+ --c_number: #B8D7A3;
27
+ --c_string: #D69D85;
28
+ --c_regex: #9A5334;
29
+ --c_function: inehrit;
30
+ --c_comment: #57A64A;
31
+ --c_doc: #608B4E;
32
+ --c_tag: #9B9B9B;
33
+ --c_var: #BD63C5;
34
+ --c_attr: #9CDCFE;
35
+ --c_section: #ffd700;
36
+ --c_selector: #569CD6;
37
+ --c_addition: #144212;
38
+ --c_deletion: #600;
39
+ --c_caret: white;
40
+ }
41
+
42
+ .hljs {
43
+ display: block;
44
+ overflow-x: auto;
45
+ color: var(--c_text);
46
+ }
47
+
48
+ .hljs-keyword,
49
+ .hljs-literal,
50
+ .hljs-symbol,
51
+ .hljs-name,
52
+ .hljs-link {
53
+ color: var(--c_keyword);
54
+ }
55
+
56
+ .hljs-link {
57
+ text-decoration: underline;
58
+ }
59
+
60
+ .hljs-built_in,
61
+ .hljs-type {
62
+ color: var(--c_builtin);
63
+ }
64
+
65
+ .hljs-number,
66
+ .hljs-class {
67
+ color: var(--c_number);
68
+ }
69
+
70
+ .hljs-string,
71
+ .hljs-meta-string {
72
+ color: var(--c_string);
73
+ }
74
+
75
+ .hljs-regexp,
76
+ .hljs-template-tag {
77
+ color: var(--c_regex);
78
+ }
79
+
80
+ .hljs-subst,
81
+ .hljs-function,
82
+ .hljs-title,
83
+ .hljs-params,
84
+ .hljs-formula {
85
+ color: var(--c_function);
86
+ }
87
+
88
+ .hljs-comment,
89
+ .hljs-quote {
90
+ color: var(--c_comment);
91
+ font-style: italic
92
+ }
93
+
94
+ .hljs-doctag {
95
+ color: var(--c_doc);
96
+ }
97
+
98
+ .hljs-meta,
99
+ .hljs-meta-keyword,
100
+ .hljs-tag {
101
+ color: var(--c_tag);
102
+ }
103
+
104
+ .hljs-variable,
105
+ .hljs-template-variable {
106
+ color: var(--c_var);
107
+ }
108
+
109
+ .hljs-attr,
110
+ .hljs-attribute,
111
+ .hljs-builtin-name {
112
+ color: var(--c_attr);
113
+ }
114
+
115
+ .hljs-section {
116
+ color: var(--c_section);
117
+ }
118
+
119
+ .hljs-emphasis {
120
+ font-style: italic
121
+ }
122
+
123
+ .hljs-strong {
124
+ font-weight: bold
125
+ }
126
+
127
+ .hljs-bullet,
128
+ .hljs-selector-tag,
129
+ .hljs-selector-id,
130
+ .hljs-selector-class,
131
+ .hljs-selector-attr,
132
+ .hljs-selector-pseudo {
133
+ color: var(--c_selector);
134
+ }
135
+
136
+ .hljs-addition {
137
+ background-color: var(--c_addition);
138
+ display: inline-block;
139
+ width: 100%
140
+ }
141
+
142
+ .hljs-deletion {
143
+ background-color: var(--c_deletion);
144
+ display: inline-block;
145
+ width: 100%
146
+ }
package/src/utils/cli.js CHANGED
@@ -1,43 +1,43 @@
1
- import { spawn } from 'child_process';
2
-
3
- export const getArgs = mapping => {
4
- const args = {};
5
- const argv = process.argv.slice(2);
6
-
7
- for(let i = 0; i < argv.length; i++) {
8
- const arg = argv[i];
9
- if(arg.startsWith('-')) {
10
- const key = arg.replace(/^-+/, '');
11
- const mappedKey = mapping[key] || key;
12
- const nextArg = argv[i + 1];
13
-
14
- if(nextArg && !nextArg.startsWith('-')) {
15
- args[mappedKey] = nextArg;
16
- i++;
17
- } else {
18
- args[mappedKey] = true;
19
- }
20
- }
21
- }
22
-
23
- return args;
24
- };
25
-
26
- export const runChildNodeProcess = scriptPath => {
27
- const child = spawn('node', [scriptPath], {
28
- stdio: 'inherit',
29
- shell: true
30
- });
31
-
32
- return new Promise((resolve, reject) => {
33
- child.on('close', code => {
34
- if(code === 0) {
35
- resolve();
36
- } else {
37
- reject(new Error(`Process exited with code ${code}`));
38
- }
39
- });
40
-
41
- child.on('error', reject);
42
- });
43
- };
1
+ import { spawn } from 'child_process';
2
+
3
+ export const getArgs = mapping => {
4
+ const args = {};
5
+ const argv = process.argv.slice(2);
6
+
7
+ for(let i = 0; i < argv.length; i++) {
8
+ const arg = argv[i];
9
+ if(arg.startsWith('-')) {
10
+ const key = arg.replace(/^-+/, '');
11
+ const mappedKey = mapping[key] || key;
12
+ const nextArg = argv[i + 1];
13
+
14
+ if(nextArg && !nextArg.startsWith('-')) {
15
+ args[mappedKey] = nextArg;
16
+ i++;
17
+ } else {
18
+ args[mappedKey] = true;
19
+ }
20
+ }
21
+ }
22
+
23
+ return args;
24
+ };
25
+
26
+ export const runChildNodeProcess = scriptPath => {
27
+ const child = spawn('node', [scriptPath], {
28
+ stdio: 'inherit',
29
+ shell: true
30
+ });
31
+
32
+ return new Promise((resolve, reject) => {
33
+ child.on('close', code => {
34
+ if(code === 0) {
35
+ resolve();
36
+ } else {
37
+ reject(new Error(`Process exited with code ${code}`));
38
+ }
39
+ });
40
+
41
+ child.on('error', reject);
42
+ });
43
+ };
@@ -1,41 +1,41 @@
1
- import fs from 'fs/promises';
2
- import path from 'path';
3
-
4
- export const ensureDir = async dirPath => {
5
- try {
6
- await fs.mkdir(dirPath, { recursive: true });
7
- } catch (error) {
8
- if(error.code !== 'EEXIST') {
9
- throw error;
10
- }
11
- }
12
- };
13
-
14
- export const copyDir = async (src, dest) => {
15
- await ensureDir(dest);
16
- const entries = await fs.readdir(src, { withFileTypes: true });
17
-
18
- for(const entry of entries) {
19
- const srcPath = path.join(src, entry.name);
20
- const destPath = path.join(dest, entry.name);
21
-
22
- if(entry.isDirectory()) {
23
- await copyDir(srcPath, destPath);
24
- } else {
25
- await fs.copyFile(srcPath, destPath);
26
- }
27
- }
28
- };
29
-
30
- export const emptyDir = async dirPath => {
31
- try {
32
- const entries = await fs.readdir(dirPath);
33
- await Promise.all(entries.map(entry =>
34
- fs.rm(path.join(dirPath, entry), { recursive: true, force: true })
35
- ));
36
- } catch (error) {
37
- if(error.code !== 'ENOENT') {
38
- throw error;
39
- }
40
- }
41
- };
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+
4
+ export const ensureDir = async dirPath => {
5
+ try {
6
+ await fs.mkdir(dirPath, { recursive: true });
7
+ } catch (error) {
8
+ if(error.code !== 'EEXIST') {
9
+ throw error;
10
+ }
11
+ }
12
+ };
13
+
14
+ export const copyDir = async (src, dest) => {
15
+ await ensureDir(dest);
16
+ const entries = await fs.readdir(src, { withFileTypes: true });
17
+
18
+ for(const entry of entries) {
19
+ const srcPath = path.join(src, entry.name);
20
+ const destPath = path.join(dest, entry.name);
21
+
22
+ if(entry.isDirectory()) {
23
+ await copyDir(srcPath, destPath);
24
+ } else {
25
+ await fs.copyFile(srcPath, destPath);
26
+ }
27
+ }
28
+ };
29
+
30
+ export const emptyDir = async dirPath => {
31
+ try {
32
+ const entries = await fs.readdir(dirPath);
33
+ await Promise.all(entries.map(entry =>
34
+ fs.rm(path.join(dirPath, entry), { recursive: true, force: true })
35
+ ));
36
+ } catch (error) {
37
+ if(error.code !== 'ENOENT') {
38
+ throw error;
39
+ }
40
+ }
41
+ };
@@ -0,0 +1,11 @@
1
+ // Boolean converter that uses explicit "true"/"false" string values
2
+ export const boolTrueFalse = {
3
+ fromAttribute: v => v === null ? undefined : v.toLowerCase() === 'true',
4
+ toAttribute: v => v ? 'true' : 'false'
5
+ };
6
+
7
+ // Boolean converter that uses attribute presence/absence
8
+ export const boolExists = {
9
+ fromAttribute: v => v !== null,
10
+ toAttribute: v => v ? '' : null
11
+ };