kempo 1.0.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.
- package/.gitattributes +2 -0
- package/LICENSE +21 -0
- package/README.md +2 -0
- package/dist/components/Card.js +1 -0
- package/dist/components/CodeEditor.js +1 -0
- package/dist/components/Component.js +1 -0
- package/dist/components/Dialog.js +1 -0
- package/dist/components/FocusCapture.js +1 -0
- package/dist/components/Icon.js +1 -0
- package/dist/components/Import.js +1 -0
- package/dist/components/LazyComponent.js +1 -0
- package/dist/components/ReactiveComponent.js +1 -0
- package/dist/components/ReactiveLazyComponent.js +1 -0
- package/dist/components/Resize.js +1 -0
- package/dist/components/Search.js +1 -0
- package/dist/components/ShowMore.js +1 -0
- package/dist/components/SideMenu.js +1 -0
- package/dist/components/Split.js +1 -0
- package/dist/components/Tabs.js +1 -0
- package/dist/components/ThemeSwitcher.js +1 -0
- package/dist/components/Timestamp.js +1 -0
- package/dist/components/WebSnippetEditor.js +1 -0
- package/dist/index.js +1 -0
- package/dist/kempo-hljs.css +1 -0
- package/dist/kempo-styles.css +1 -0
- package/dist/kempo-vars.css +1 -0
- package/dist/kempo.css +1 -0
- package/dist/kempo.js +1 -0
- package/dist/utils/cli.js +1 -0
- package/dist/utils/cookie.js +1 -0
- package/dist/utils/debounce.js +1 -0
- package/dist/utils/drag.js +1 -0
- package/dist/utils/element.js +1 -0
- package/dist/utils/formatTimestamp.js +1 -0
- package/dist/utils/fuzzyMatch.js +1 -0
- package/dist/utils/getPreferredTheme.js +1 -0
- package/dist/utils/loadCss.js +1 -0
- package/dist/utils/loadScript.js +1 -0
- package/dist/utils/object.js +1 -0
- package/dist/utils/string.js +1 -0
- package/dist/utils/toFunction.js +1 -0
- package/dist/utils/type.js +1 -0
- package/dist/utils/waitFrames.js +1 -0
- package/docs/components/_template.html +22 -0
- package/docs/components/card.html +35 -0
- package/docs/components/codeeditor.html +29 -0
- package/docs/components/component.html +88 -0
- package/docs/components/dialog.html +89 -0
- package/docs/components/icon.html +73 -0
- package/docs/components/import.html +34 -0
- package/docs/components/lazycomponent.html +50 -0
- package/docs/components/resize.html +107 -0
- package/docs/components/show-more.html +92 -0
- package/docs/components/sidemenu.html +97 -0
- package/docs/components/split.html +70 -0
- package/docs/components/tabs.html +33 -0
- package/docs/components/websnippeteditor.html +42 -0
- package/docs/index.html +17 -0
- package/docs/kempo/components/Card.js +1 -0
- package/docs/kempo/components/CodeEditor.js +1 -0
- package/docs/kempo/components/Collapse.js +1 -0
- package/docs/kempo/components/Component.js +1 -0
- package/docs/kempo/components/Dialog.js +1 -0
- package/docs/kempo/components/FocusCapture.js +1 -0
- package/docs/kempo/components/Icon.js +1 -0
- package/docs/kempo/components/Import.js +1 -0
- package/docs/kempo/components/LazyComponent.js +1 -0
- package/docs/kempo/components/ReactiveComponent.js +1 -0
- package/docs/kempo/components/ReactiveLazyComponent.js +1 -0
- package/docs/kempo/components/Resize.js +1 -0
- package/docs/kempo/components/Search.js +1 -0
- package/docs/kempo/components/ShowMore.js +1 -0
- package/docs/kempo/components/SideMenu.js +1 -0
- package/docs/kempo/components/Split.js +1 -0
- package/docs/kempo/components/Tabs.js +1 -0
- package/docs/kempo/components/ThemeSwitcher.js +1 -0
- package/docs/kempo/components/Timestamp.js +1 -0
- package/docs/kempo/components/WebSnippetEditor.js +1 -0
- package/docs/kempo/icons/arrow-down-double.svg +1 -0
- package/docs/kempo/icons/arrow-up-double.svg +1 -0
- package/docs/kempo/icons/close.svg +2 -0
- package/docs/kempo/icons/compare.svg +1 -0
- package/docs/kempo/icons/dark-mode.svg +1 -0
- package/docs/kempo/icons/delete.svg +1 -0
- package/docs/kempo/icons/filter-off.svg +1 -0
- package/docs/kempo/icons/filter.svg +1 -0
- package/docs/kempo/icons/light-mode.svg +1 -0
- package/docs/kempo/icons/menu.svg +1 -0
- package/docs/kempo/icons/pause.svg +1 -0
- package/docs/kempo/icons/play.svg +1 -0
- package/docs/kempo/icons/search.svg +1 -0
- package/docs/kempo/icons/settings.svg +1 -0
- package/docs/kempo/icons/storage.svg +1 -0
- package/docs/kempo/icons/trash-x.svg +1 -0
- package/docs/kempo/index.js +1 -0
- package/docs/kempo/kempo-hljs.css +1 -0
- package/docs/kempo/kempo-styles.css +1 -0
- package/docs/kempo/kempo-vars.css +1 -0
- package/docs/kempo/kempo.css +1 -0
- package/docs/kempo/kempo.js +1 -0
- package/docs/kempo/utils/cli.js +1 -0
- package/docs/kempo/utils/cookie.js +1 -0
- package/docs/kempo/utils/debounce.js +1 -0
- package/docs/kempo/utils/drag.js +1 -0
- package/docs/kempo/utils/element.js +1 -0
- package/docs/kempo/utils/formatTimestamp.js +1 -0
- package/docs/kempo/utils/fuzzyMatch.js +1 -0
- package/docs/kempo/utils/getPreferredTheme.js +1 -0
- package/docs/kempo/utils/loadCss.js +1 -0
- package/docs/kempo/utils/loadScript.js +1 -0
- package/docs/kempo/utils/object.js +1 -0
- package/docs/kempo/utils/string.js +1 -0
- package/docs/kempo/utils/toFunction.js +1 -0
- package/docs/kempo/utils/type.js +1 -0
- package/docs/kempo/utils/waitFrames.js +1 -0
- package/docs/nav-1.inc.html +66 -0
- package/docs/nav.inc.html +66 -0
- package/docs/search.json +94 -0
- package/docs/styles/_template.html +22 -0
- package/docs/styles/borders-spacing.html +193 -0
- package/docs/styles/buttons.html +113 -0
- package/docs/styles/colors.html +65 -0
- package/docs/styles/displays-layouts.html +156 -0
- package/docs/styles/embed-1.html +35 -0
- package/docs/styles/inputs.html +89 -0
- package/docs/styles/tables.html +143 -0
- package/docs/styles/typography.html +116 -0
- package/icons/arrow-down-double.svg +1 -0
- package/icons/arrow-up-double.svg +1 -0
- package/icons/close.svg +2 -0
- package/icons/compare.svg +1 -0
- package/icons/dark-mode.svg +1 -0
- package/icons/delete.svg +1 -0
- package/icons/filter-off.svg +1 -0
- package/icons/filter.svg +1 -0
- package/icons/light-mode.svg +1 -0
- package/icons/menu.svg +1 -0
- package/icons/pause.svg +1 -0
- package/icons/play.svg +1 -0
- package/icons/search.svg +1 -0
- package/icons/settings.svg +1 -0
- package/icons/storage.svg +1 -0
- package/icons/trash-x.svg +1 -0
- package/kempo/components/Card.js +65 -0
- package/kempo/components/CodeEditor.js +141 -0
- package/kempo/components/Component.js +109 -0
- package/kempo/components/Dialog.js +277 -0
- package/kempo/components/FocusCapture.js +30 -0
- package/kempo/components/Icon.js +60 -0
- package/kempo/components/Import.js +40 -0
- package/kempo/components/LazyComponent.js +40 -0
- package/kempo/components/ReactiveComponent.js +11 -0
- package/kempo/components/ReactiveLazyComponent.js +11 -0
- package/kempo/components/Resize.js +168 -0
- package/kempo/components/Search.js +136 -0
- package/kempo/components/ShowMore.js +82 -0
- package/kempo/components/SideMenu.js +156 -0
- package/kempo/components/Split.js +133 -0
- package/kempo/components/Tabs.js +254 -0
- package/kempo/components/ThemeSwitcher.js +77 -0
- package/kempo/components/Timestamp.js +25 -0
- package/kempo/components/WebSnippetEditor.js +159 -0
- package/kempo/kempo-hljs.css +145 -0
- package/kempo/kempo-styles.css +893 -0
- package/kempo/kempo-vars.css +154 -0
- package/kempo/kempo.js +48 -0
- package/kempo/utils/cli.js +54 -0
- package/kempo/utils/cookie.js +16 -0
- package/kempo/utils/debounce.js +9 -0
- package/kempo/utils/drag.js +74 -0
- package/kempo/utils/element.js +69 -0
- package/kempo/utils/formatTimestamp.js +11 -0
- package/kempo/utils/fuzzyMatch.js +55 -0
- package/kempo/utils/getPreferredTheme.js +1 -0
- package/kempo/utils/loadCss.js +10 -0
- package/kempo/utils/loadScript.js +10 -0
- package/kempo/utils/object.js +177 -0
- package/kempo/utils/string.js +54 -0
- package/kempo/utils/toFunction.js +24 -0
- package/kempo/utils/type.js +8 -0
- package/kempo/utils/waitFrames.js +17 -0
- package/package.json +33 -0
- package/scripts/build.js +131 -0
- package/scripts/docs.js +14 -0
- package/test/components/SuiteList.js +26 -0
- package/test/components/Test.js +357 -0
- package/test/index.html +49 -0
- package/test/index.js +25 -0
- package/test/suite.html +45 -0
- package/test/suites.inc.html +4 -0
- package/test/tests/components/Component.test.js +138 -0
- package/test/tests/utils/cli.test.js +113 -0
- package/test/tests/utils/cookie.test.js +87 -0
- package/test/tests/utils/debounce.test.js +71 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--ff_body: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
3
|
+
--ff_heading: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
4
|
+
--ff_mono: Consolas, monaco, monospace;
|
|
5
|
+
--fs_base: 16px;
|
|
6
|
+
--fs_small: calc(0.6 * var(--fs_base));
|
|
7
|
+
--fs_large: calc(1.5 * var(--fs_base));
|
|
8
|
+
--fs_h6: var(--fs_base);
|
|
9
|
+
--fs_h5: calc(1.25 * var(--fs_base));
|
|
10
|
+
--fs_h4: calc(1.5 * var(--fs_base));
|
|
11
|
+
--fs_h3: calc(1.75 * var(--fs_base));
|
|
12
|
+
--fs_h2: calc(2 * var(--fs_base));
|
|
13
|
+
--fs_h1: calc(2.5 * var(--fs_base));
|
|
14
|
+
--fw_base: 400;
|
|
15
|
+
--fw_bold: 700;
|
|
16
|
+
--spacer: 1rem;
|
|
17
|
+
--spacer_h: calc(0.5 * var(--spacer));
|
|
18
|
+
--spacer_q: calc(0.25 * var(--spacer));
|
|
19
|
+
--line-height: 1.35em;
|
|
20
|
+
--container_width: 90rem;
|
|
21
|
+
--animation_ms: 256ms;
|
|
22
|
+
--radius: 0.25rem;
|
|
23
|
+
--link_decoration: underline;
|
|
24
|
+
--input_border_width: 2px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:root,
|
|
28
|
+
[theme="light"] {
|
|
29
|
+
color-scheme: light;
|
|
30
|
+
--c_bg: #f9f9f9;
|
|
31
|
+
--c_bg__inv: #333;
|
|
32
|
+
--c_bg__alt: #eee;
|
|
33
|
+
--c_overscroll: white;
|
|
34
|
+
--c_border: #ccc;
|
|
35
|
+
--c_border__inv: var(--d_c_bg_border);
|
|
36
|
+
--c_primary: #36f;
|
|
37
|
+
--c_primary__hover: #14d;
|
|
38
|
+
--c_secondary: #93f;
|
|
39
|
+
--c_secondary__hover: #71d;
|
|
40
|
+
--c_success: #080;
|
|
41
|
+
--c_success__hover: #060;
|
|
42
|
+
--c_warning: #f60;
|
|
43
|
+
--c_warning__hover: #d40;
|
|
44
|
+
--c_danger: #f03;
|
|
45
|
+
--c_danger__hover: #d01;
|
|
46
|
+
--c_input_accent: #36f;
|
|
47
|
+
--c_highlight: rgba(41, 100, 210, 0.25);
|
|
48
|
+
--tc: rgba(0, 0, 0, 0.93);
|
|
49
|
+
--tc_dark: var(--tc);
|
|
50
|
+
--tc_light: rgba(255, 255, 255, 0.93);
|
|
51
|
+
--tc_inv: var(--tc_light);
|
|
52
|
+
--tc_muted: rgba(0, 0, 0, 0.5);
|
|
53
|
+
--tc_on_primary: var(--tc_light);
|
|
54
|
+
--tc_on_secondary: var(--tc_light);
|
|
55
|
+
--tc_on_success: var(--tc_light);
|
|
56
|
+
--tc_on_warning: var(--tc_light);
|
|
57
|
+
--tc_on_danger: var(--tc_light);
|
|
58
|
+
--c_overlay: rgba(0, 0, 0, 0.5);
|
|
59
|
+
--tc_primary: #36f;
|
|
60
|
+
--tc_secondary: #93f;
|
|
61
|
+
--tc_success: #080;
|
|
62
|
+
--tc_warning: #f60;
|
|
63
|
+
--tc_danger: #f03;
|
|
64
|
+
--btn_box_shadow: 0 0 0 transparent;
|
|
65
|
+
--btn_box_shadow__hover: 0 0 0 transparent;
|
|
66
|
+
--btn_border: transparent;
|
|
67
|
+
--btn_bg: #ddd;
|
|
68
|
+
--btn_bg__hover: #ccc;
|
|
69
|
+
--btn_tc: rgba(0, 0, 0, 0.93);
|
|
70
|
+
--btn_transparent__hover: rgba(0, 0, 0, 0.05);
|
|
71
|
+
--tc_link: var(--tc_primary);
|
|
72
|
+
--tc_link__hover: var(--tc_secondary);
|
|
73
|
+
--tc_link__inv: var(--tc_primary__inv);
|
|
74
|
+
--tc_link__inv__hover: var(--tc_secondary__inv);
|
|
75
|
+
--focus_shadow: 0 0 2px 2px var(--c_primary);
|
|
76
|
+
--focus_shadow_on_primary: 0 0 2px 2px var(--tc_on_primary);
|
|
77
|
+
--input_bg: white;
|
|
78
|
+
--input_tc: rgba(0, 0, 0, 0.93);
|
|
79
|
+
--drop_shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.333);
|
|
80
|
+
}
|
|
81
|
+
[theme="dark"] {
|
|
82
|
+
color-scheme: dark;
|
|
83
|
+
--c_bg: #333;
|
|
84
|
+
--c_bg__inv: #f9f9f9;
|
|
85
|
+
--c_bg__alt: #222;
|
|
86
|
+
--c_overscroll: black;
|
|
87
|
+
--c_border: #777;
|
|
88
|
+
--c_border__inv: #ccc;
|
|
89
|
+
--c_primary: #36f;
|
|
90
|
+
--c_primary__hover: #14d;
|
|
91
|
+
--c_secondary: #93f;
|
|
92
|
+
--c_secondary__hover: #71d;
|
|
93
|
+
--c_success: #080;
|
|
94
|
+
--c_success__hover: #060;
|
|
95
|
+
--c_warning: #f60;
|
|
96
|
+
--c_warning__hover: #d40;
|
|
97
|
+
--c_danger: #f03;
|
|
98
|
+
--c_danger__hover: #d01;
|
|
99
|
+
--c_input_accent: #36f;
|
|
100
|
+
--c_highlight: rgba(0, 89, 255, 0.25);
|
|
101
|
+
--tc: rgba(255, 255, 255, 0.93);
|
|
102
|
+
--tc_dark: rgba(0, 0, 0, 0.93);
|
|
103
|
+
--tc_light: var(--tc);
|
|
104
|
+
--tc_inv: var(--tc_dark);
|
|
105
|
+
--tc_muted: rgba(255, 255, 255, 0.5);
|
|
106
|
+
--tc_on_primary: var(--tc);
|
|
107
|
+
--tc_on_secondary: var(--tc);
|
|
108
|
+
--tc_on_success: var(--tc);
|
|
109
|
+
--tc_on_warning: var(--tc);
|
|
110
|
+
--tc_on_danger: var(--tc);
|
|
111
|
+
--c_overlay: rgba(0, 0, 0, 0.5);
|
|
112
|
+
--tc_primary: #8ab4f8;
|
|
113
|
+
--tc_secondary: #b6f;
|
|
114
|
+
--tc_success: #6b6;
|
|
115
|
+
--tc_warning: #f93;
|
|
116
|
+
--tc_danger: #f57;
|
|
117
|
+
--btn_bg: #aaa;
|
|
118
|
+
--btn_bg__hover: #bbb;
|
|
119
|
+
--btn_tc: rgba(0, 0, 0, 0.93);
|
|
120
|
+
--btn_transparent__hover: rgba(255, 255, 255, 0.05);
|
|
121
|
+
--btn_box_shadow: 0 0 0 transparent;
|
|
122
|
+
--btn_box_shadow__hover: 0 0 0 transparent;
|
|
123
|
+
--btn_border: transparent;
|
|
124
|
+
--tc_link: var(--tc_primary);
|
|
125
|
+
--tc_link__hover: var(--tc_secondary);
|
|
126
|
+
--tc_link__inv: var(--tc_primary__inv);
|
|
127
|
+
--tc_link__inv__hover: var(--tc_secondary__inv);
|
|
128
|
+
--focus_shadow: 0 0 2px 2px var(--c_primary);
|
|
129
|
+
--focus_shadow_on_primary: 0 0 2px 2px var(--tc_on_primary);
|
|
130
|
+
--input_bg: white;
|
|
131
|
+
--input_tc: rgba(0, 0, 0, 0.93);
|
|
132
|
+
--ff_body: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
133
|
+
--ff_heading: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
134
|
+
--ff_mono: Consolas, monaco, monospace;
|
|
135
|
+
--fs_base: 16px;
|
|
136
|
+
--fs_h6: var(--fs_base);
|
|
137
|
+
--fs_h5: calc(1.25 * var(--fs_base));
|
|
138
|
+
--fs_h4: calc(1.5 * var(--fs_base));
|
|
139
|
+
--fs_h3: calc(1.75 * var(--fs_base));
|
|
140
|
+
--fs_h2: calc(2 * var(--fs_base));
|
|
141
|
+
--fs_h1: calc(2.5 * var(--fs_base));
|
|
142
|
+
--fw_base: 400;
|
|
143
|
+
--fw_bold: 700;
|
|
144
|
+
--spacer: 1rem;
|
|
145
|
+
--spacer_h: calc(0.5 * var(--spacer));
|
|
146
|
+
--spacer_q: calc(0.25 * var(--spacer));
|
|
147
|
+
--line-height: 1.35em;
|
|
148
|
+
--container_width: 90rem;
|
|
149
|
+
--animation_ms: 256ms;
|
|
150
|
+
--radius: 0.25rem;
|
|
151
|
+
--drop_shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.25);
|
|
152
|
+
--link_decoration: underline;
|
|
153
|
+
--input_border_width: 2px;
|
|
154
|
+
}
|
package/kempo/kempo.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const components = {
|
|
2
|
+
'k-card': 'Card',
|
|
3
|
+
'k-code-editor': 'CodeEditor',
|
|
4
|
+
'k-dialog': 'Dialog',
|
|
5
|
+
'k-icon': 'Icon',
|
|
6
|
+
'k-import': 'Import',
|
|
7
|
+
'k-resize': 'Resize',
|
|
8
|
+
'k-search': 'Search',
|
|
9
|
+
'k-show-more': 'ShowMore',
|
|
10
|
+
'k-side-menu': 'SideMenu',
|
|
11
|
+
'k-split': 'Split',
|
|
12
|
+
'k-tabs': 'Tabs',
|
|
13
|
+
'k-web-snippet-editor': 'WebSnippetEditor'
|
|
14
|
+
}
|
|
15
|
+
const lookFor = new Set(Object.keys(components));
|
|
16
|
+
window.kempo = Object.assign({}, {
|
|
17
|
+
pathToRoot: './',
|
|
18
|
+
pathToKempoFromRoot: './kempo/',
|
|
19
|
+
pathToIconsFromRoot: './kempo/icons/',
|
|
20
|
+
autoLoadComponents: () => {
|
|
21
|
+
lookFor.forEach( async component => {
|
|
22
|
+
if(document.querySelector(component)){
|
|
23
|
+
const path = `${kempo.pathToRoot}${kempo.pathToKempoFromRoot}components/${components[component]}.js`;
|
|
24
|
+
console.log(path);
|
|
25
|
+
import(path);
|
|
26
|
+
lookFor.delete(component);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
_darkModeQuery: window.matchMedia('(prefers-color-scheme: dark)'),
|
|
31
|
+
_theme: 'auto',
|
|
32
|
+
_themeListener: (e) => {
|
|
33
|
+
if(window.kempo._theme === 'auto'){
|
|
34
|
+
document.documentElement.setAttribute('theme', e.matches?'dark':'light');
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
setTheme: (theme) => {
|
|
38
|
+
window.kempo._theme = theme;
|
|
39
|
+
if(window.kempo._theme === 'auto'){
|
|
40
|
+
document.documentElement.setAttribute('theme', window.kempo._darkModeQuery.matches?'dark':'light');
|
|
41
|
+
} else {
|
|
42
|
+
document.documentElement.setAttribute('theme', theme);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}, window.kempo || {});
|
|
46
|
+
window.kempo.autoLoadComponents();
|
|
47
|
+
window.kempo._darkModeQuery.addEventListener('change', window.kempo._themeListener);
|
|
48
|
+
window.kempo.setTheme(document.documentElement.getAttribute('theme') || 'auto');
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const args = {};
|
|
2
|
+
let win = {};
|
|
3
|
+
if(typeof(window) !== 'undefined'){
|
|
4
|
+
win = window;
|
|
5
|
+
} else if(typeof(global) !== 'undefined'){
|
|
6
|
+
win = global;
|
|
7
|
+
}
|
|
8
|
+
win.log = (...messages) => {
|
|
9
|
+
if(args.debug){
|
|
10
|
+
console.log(...messages);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default (shortMap = {
|
|
15
|
+
d: 'debug'
|
|
16
|
+
}) => {
|
|
17
|
+
let name = '';
|
|
18
|
+
let values = [];
|
|
19
|
+
const save = () => {
|
|
20
|
+
if(name){
|
|
21
|
+
if(values.length === 0){ // flag
|
|
22
|
+
args[name] = true;
|
|
23
|
+
} else if(values.length === 1){ // single value
|
|
24
|
+
args[name] = values[0];
|
|
25
|
+
} else { // multiple values
|
|
26
|
+
args[name] = values;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
for(let i=2; i<process.argv.length; i++){
|
|
32
|
+
const arg = process.argv[i];
|
|
33
|
+
if(arg.startsWith('-')){
|
|
34
|
+
// new argument, save the last one
|
|
35
|
+
save()
|
|
36
|
+
// start a new one
|
|
37
|
+
if(arg.startsWith('--')){ // long form
|
|
38
|
+
name = arg.slice(2);
|
|
39
|
+
} else { // short form
|
|
40
|
+
name = arg.slice(1);
|
|
41
|
+
if(shortMap[name]){
|
|
42
|
+
name = shortMap[name];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
values = [];
|
|
46
|
+
} else {
|
|
47
|
+
// value
|
|
48
|
+
values.push(arg);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// save last arg
|
|
52
|
+
save();
|
|
53
|
+
return args;
|
|
54
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const saveCookie = (name, value, minutes = 30 * 24 * 60, path = '/') => {
|
|
2
|
+
const expires = new Date(Date.now() + minutes * 60 * 1000);
|
|
3
|
+
document.cookie = `${name}=${value};expires=${expires.toUTCString()};path=${path}`;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
const getCookie = (name) => {
|
|
7
|
+
const cookies = document.cookie.split(';').map(cookie => cookie.trim().split('='));
|
|
8
|
+
const cookie = cookies.find(cookie => cookie[0] === name);
|
|
9
|
+
return cookie ? cookie[1] : null;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const deleteCookie = (name) => {
|
|
13
|
+
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { saveCookie, getCookie, deleteCookie };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export default (options = {}) => {
|
|
2
|
+
let startX, startY, timeoutId;
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
element = () => {},
|
|
6
|
+
callback = () => {},
|
|
7
|
+
startCallback = () => {},
|
|
8
|
+
moveCallback = () => {},
|
|
9
|
+
endCallback = () => {},
|
|
10
|
+
preventScroll = false
|
|
11
|
+
} = options;
|
|
12
|
+
|
|
13
|
+
const dragMove = (event) => {
|
|
14
|
+
if (preventScroll) {
|
|
15
|
+
event.preventDefault(); // prevent drag scrolling
|
|
16
|
+
}
|
|
17
|
+
clearTimeout(timeoutId);
|
|
18
|
+
const pageX = event.pageX || event.touches[0].pageX;
|
|
19
|
+
const pageY = event.pageY || event.touches[0].pageY;
|
|
20
|
+
const diff = {
|
|
21
|
+
x: pageX - startX,
|
|
22
|
+
y: pageY - startY,
|
|
23
|
+
...options
|
|
24
|
+
};
|
|
25
|
+
callback(diff);
|
|
26
|
+
moveCallback(diff);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const dragEnd = ({ pageX, pageY }) => {
|
|
30
|
+
clearTimeout(timeoutId);
|
|
31
|
+
const diff = {
|
|
32
|
+
x: pageX - startX,
|
|
33
|
+
y: pageY - startY,
|
|
34
|
+
...options
|
|
35
|
+
};
|
|
36
|
+
callback(diff);
|
|
37
|
+
endCallback(diff);
|
|
38
|
+
removeListeners();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const dragStart = (event) => {
|
|
42
|
+
clearTimeout(timeoutId);
|
|
43
|
+
startX = event.pageX || event.touches[0].pageX;;
|
|
44
|
+
startY = event.pageY || event.touches[0].pageY;;
|
|
45
|
+
const diff = {
|
|
46
|
+
x: 0,
|
|
47
|
+
y: 0,
|
|
48
|
+
...options
|
|
49
|
+
};
|
|
50
|
+
startCallback(diff);
|
|
51
|
+
window.addEventListener('mousemove', dragMove, {passive:!preventScroll});
|
|
52
|
+
window.addEventListener('mouseup', dragEnd, {passive:!preventScroll});
|
|
53
|
+
window.addEventListener('touchmove', dragMove, {passive:!preventScroll});
|
|
54
|
+
window.addEventListener('touchend', dragEnd, {passive:!preventScroll});
|
|
55
|
+
// window.addEventListener('mouseout', dragEnd);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const removeListeners = () => {
|
|
59
|
+
window.removeEventListener('mousemove', dragMove);
|
|
60
|
+
window.removeEventListener('mouseup', dragEnd);
|
|
61
|
+
window.removeEventListener('touchmove', dragMove);
|
|
62
|
+
window.removeEventListener('touchend', dragEnd);
|
|
63
|
+
// window.removeEventListener('mouseout', dragEnd);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
element.addEventListener('mousedown', dragStart, {passive:!preventScroll});
|
|
67
|
+
element.addEventListener('touchstart', dragStart, {passive:!preventScroll});
|
|
68
|
+
|
|
69
|
+
// Return removeListeners for cleanup
|
|
70
|
+
return ()=>{
|
|
71
|
+
element.removeEventListener('mousedown', dragStart);
|
|
72
|
+
removeListeners();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import waitFrames from './waitFrames.js';
|
|
2
|
+
|
|
3
|
+
export const onEvent = (element, events, handler, scope = document) => {
|
|
4
|
+
if(element instanceof EventTarget){
|
|
5
|
+
events.toLowerCase().split(' ').forEach( event => {
|
|
6
|
+
element.addEventListener(event, handler);
|
|
7
|
+
});
|
|
8
|
+
} else if(element instanceof NodeList || element instanceof Array){
|
|
9
|
+
element.forEach( el => onEvent(el, events, handler));
|
|
10
|
+
} else if(typeof(element) == 'string'){
|
|
11
|
+
scope.querySelectorAll(element).forEach( el => onEvent(el, events, handler));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export const offEvent = (element, events, handler, scope = document) => {
|
|
15
|
+
if(element instanceof EventTarget){
|
|
16
|
+
events.toLowerCase().split(' ').forEach( event => {
|
|
17
|
+
element.removeEventListener(event, handler);
|
|
18
|
+
});
|
|
19
|
+
} else if(element instanceof NodeList || element instanceof Array){
|
|
20
|
+
element.forEach( el => offEvent(el, events, handler));
|
|
21
|
+
} else if(typeof(element) == 'string'){
|
|
22
|
+
scope.querySelectorAll(element).forEach( el => offEvent(el, events, handler));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export const dispatchEvent = (element, events, detail, scope = document) => {
|
|
26
|
+
if(element instanceof EventTarget){
|
|
27
|
+
events.toLowerCase().split(' ').forEach( event => {
|
|
28
|
+
element.dispatchEvent(new CustomEvent(event, { detail } ));
|
|
29
|
+
});
|
|
30
|
+
} else if(element instanceof NodeList || element instanceof Array){
|
|
31
|
+
element.forEach( el => dispatchEvent(el, events, handler));
|
|
32
|
+
} else if(typeof(element) == 'string'){
|
|
33
|
+
scope.querySelectorAll(element).forEach( el => dispatchEvent(el, events, handler));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export const isInView = async (element) => {
|
|
37
|
+
await waitFrames(2);
|
|
38
|
+
const rect = element.getBoundingClientRect();
|
|
39
|
+
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
40
|
+
const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
41
|
+
if (
|
|
42
|
+
rect.bottom < 0 ||
|
|
43
|
+
rect.top > windowHeight ||
|
|
44
|
+
rect.right < 0 ||
|
|
45
|
+
rect.left > windowWidth
|
|
46
|
+
) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
while (element) {
|
|
50
|
+
const style = getComputedStyle(element);
|
|
51
|
+
if (style.display === 'none' || style.visibility === 'hidden') {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
element = element.parentElement;
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
export const firstFocusable = (scope) => {
|
|
59
|
+
return scope.querySelector('a[href]:not([disabled]), button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])');
|
|
60
|
+
}
|
|
61
|
+
export const setProp = (element, prop, value, scope = document) => {
|
|
62
|
+
if(element instanceof HTMLElement){
|
|
63
|
+
element[prop] = value;
|
|
64
|
+
} else if(element instanceof NodeList || element instanceof Array){
|
|
65
|
+
[...element].forEach(element => dispatchEvent(element, prop, value));
|
|
66
|
+
} else if(typeof(element) === 'string'){
|
|
67
|
+
dispatchEvent(scope.querySelectorAll(element), prop, value);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export default (timestamp, forceLocale) => {
|
|
2
|
+
return Intl.DateTimeFormat(forceLocale || navigator.language, {
|
|
3
|
+
year: 'numeric',
|
|
4
|
+
month: '2-digit',
|
|
5
|
+
day: '2-digit',
|
|
6
|
+
hour: '2-digit',
|
|
7
|
+
minute: '2-digit',
|
|
8
|
+
second: '2-digit',
|
|
9
|
+
millisecond: '3-digit'
|
|
10
|
+
}).format(new Date(parseInt(timestamp)));
|
|
11
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
This module was created by Chat GPT using the following prompts:
|
|
3
|
+
Write me a function in JS, that takes two strings, and does a fuzzy match to see if the first string contains the second string, this way if the second string has a typo or misspelling in it we still get a partial match. Make it return a score between 0 and 10 that indicates the strength of the match, with a perfect 10 being a perfect match, and a 0 being no characters match with the threashold greater than 3. Give a higher score if the match is towards the beginning of the first string.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const fuzzyMatch = (str1, str2) => {
|
|
7
|
+
const levenshteinDistance = (s1, s2) => {
|
|
8
|
+
const m = s1.length;
|
|
9
|
+
const n = s2.length;
|
|
10
|
+
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
11
|
+
|
|
12
|
+
for (let i = 0; i <= m; i++) {
|
|
13
|
+
for (let j = 0; j <= n; j++) {
|
|
14
|
+
if (i === 0) dp[i][j] = j;
|
|
15
|
+
else if (j === 0) dp[i][j] = i;
|
|
16
|
+
else dp[i][j] = Math.min(
|
|
17
|
+
dp[i - 1][j - 1] + (s1.charAt(i - 1) === s2.charAt(j - 1) ? 0 : 1),
|
|
18
|
+
dp[i][j - 1] + 1,
|
|
19
|
+
dp[i - 1][j] + 1
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return dp[m][n];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const fuzzyThreshold = 3;
|
|
28
|
+
|
|
29
|
+
const distance = levenshteinDistance(str1.toLowerCase(), str2.toLowerCase());
|
|
30
|
+
|
|
31
|
+
if (distance === 0) {
|
|
32
|
+
return 10; // Perfect match
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const score = Math.max(0, 10 - distance / fuzzyThreshold);
|
|
36
|
+
|
|
37
|
+
const positionScore = Math.min((str1.length - distance) / str1.length, 1);
|
|
38
|
+
|
|
39
|
+
return Math.round(score * 5 + positionScore * 5); // Scale to 0-10
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
Chat GPT Prompt
|
|
44
|
+
Can you write another function that takes an array of strings, and a string, creates a score based on how well the second string matches each of the function you created above. Then find the average non-zero match of the second string to the items in the array
|
|
45
|
+
*/
|
|
46
|
+
export const fuzzyMatchArray = (array, targetString) => {
|
|
47
|
+
const nonZeroScores = array
|
|
48
|
+
.map(currentString => fuzzyMatch(currentString, targetString))
|
|
49
|
+
.filter(score => score !== 0);
|
|
50
|
+
if (nonZeroScores.length === 0) {
|
|
51
|
+
return 0; // Return 0 if there are no non-zero scores
|
|
52
|
+
}
|
|
53
|
+
const averageScore = nonZeroScores.reduce((sum, score) => sum + score, 0) / nonZeroScores.length;
|
|
54
|
+
return averageScore;
|
|
55
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default () => window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default (url, type = 'stylesheet') => {
|
|
2
|
+
return new Promise((resolve, reject) => {
|
|
3
|
+
const link = document.createElement('link');
|
|
4
|
+
link.rel = type;
|
|
5
|
+
link.href = url;
|
|
6
|
+
link.onload = resolve;
|
|
7
|
+
link.onerror = reject;
|
|
8
|
+
document.head.appendChild(link);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default (scriptUrl, type = 'module') => {
|
|
2
|
+
return new Promise((resolve, reject) => {
|
|
3
|
+
const script = document.createElement('script');
|
|
4
|
+
script.type = type;
|
|
5
|
+
script.src = scriptUrl;
|
|
6
|
+
script.onload = resolve;
|
|
7
|
+
script.onerror = reject;
|
|
8
|
+
document.head.appendChild(script);
|
|
9
|
+
});
|
|
10
|
+
}
|