goodteditor-ui 1.0.3 → 1.0.7
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/{public → dist}/js.png +0 -0
- package/index.js +2 -0
- package/package.json +8 -4
- package/src/components/ui/FileSelector.vue +1 -0
- package/src/components/ui/InputUnits.vue +5 -5
- package/src/components/ui/Lazy.md +37 -0
- package/src/components/ui/Lazy.vue +92 -0
- package/src/components/ui/Popover.vue +17 -11
- package/src/components/ui/utils/Helpers.js +18 -6
- package/public/index.html +0 -29
package/{public → dist}/js.png
RENAMED
|
File without changes
|
package/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import InputDatePicker from './src/components/ui/InputDatePicker.vue';
|
|
|
11
11
|
import InputTags from './src/components/ui/InputTags.vue';
|
|
12
12
|
import InputTimePicker from './src/components/ui/InputTimePicker.vue';
|
|
13
13
|
import InputUnits from './src/components/ui/InputUnits.vue';
|
|
14
|
+
import Lazy from './src/components/ui/Lazy.vue';
|
|
14
15
|
import Pagination from './src/components/ui/Pagination.vue';
|
|
15
16
|
import Paginator from './src/components/ui/Paginator.vue';
|
|
16
17
|
import Popover from './src/components/ui/Popover.vue';
|
|
@@ -33,6 +34,7 @@ export {
|
|
|
33
34
|
InputTags,
|
|
34
35
|
InputTimePicker,
|
|
35
36
|
InputUnits,
|
|
37
|
+
Lazy,
|
|
36
38
|
Pagination,
|
|
37
39
|
Paginator,
|
|
38
40
|
Popover,
|
package/package.json
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goodteditor-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"main": "index.js",
|
|
5
|
+
"homepage": "https://goodt-ui.netlify.app/",
|
|
5
6
|
"scripts": {
|
|
6
7
|
"serve": "vue-cli-service serve",
|
|
7
8
|
"build": "vue-cli-service build",
|
|
8
9
|
"lint": "vue-cli-service lint",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"deploy
|
|
10
|
+
"dev": "vue-styleguidist server",
|
|
11
|
+
"docs:build": "set NODE_ENV=development && vue-styleguidist build",
|
|
12
|
+
"docs:deploy": "npx netlify deploy --dir=docs --prod",
|
|
13
|
+
"notify": "node ./ci/teams-notify.js",
|
|
14
|
+
"publish": "npm run docs:build && npm run docs:deploy && npm run notify"
|
|
12
15
|
},
|
|
13
16
|
"devDependencies": {
|
|
14
17
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
15
18
|
"@vue/cli-plugin-babel": "^4.5.11",
|
|
16
19
|
"@vue/cli-plugin-eslint": "^4.5.11",
|
|
17
20
|
"@vue/cli-service": "^4.5.11",
|
|
21
|
+
"axios": "^0.24.0",
|
|
18
22
|
"babel-eslint": "^10.1.0",
|
|
19
23
|
"eslint": "^6.7.2",
|
|
20
24
|
"eslint-plugin-vue": "^6.2.2",
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
@focus="onRootFocus"
|
|
7
7
|
tabindex="0"
|
|
8
8
|
>
|
|
9
|
-
<!--
|
|
9
|
+
<!--
|
|
10
10
|
@slot Custom input slot
|
|
11
11
|
@binding {String} id input id attribute value
|
|
12
12
|
@binding {String} value input value
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
@select-option="onUnitChange"
|
|
37
37
|
>
|
|
38
38
|
<template #header>
|
|
39
|
-
<!--
|
|
39
|
+
<!--
|
|
40
40
|
@slot Dropdown header content
|
|
41
41
|
-->
|
|
42
42
|
<slot name="dropdown-header"></slot>
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
setCursorIndex,
|
|
50
50
|
}"
|
|
51
51
|
>
|
|
52
|
-
<!--
|
|
52
|
+
<!--
|
|
53
53
|
@slot Dropdown option
|
|
54
54
|
@binding {String} option option
|
|
55
55
|
@binding {Number} index option index
|
|
56
56
|
@binding {String} selectedOption current selected option
|
|
57
|
-
@binding {Number} cursorIndex current dropdown selection index
|
|
57
|
+
@binding {Number} cursorIndex current dropdown selection index
|
|
58
58
|
@binding {Function} selectOption function that select's the option
|
|
59
59
|
@binding {Function} setCursorIndex function that sets the cursor index
|
|
60
60
|
-->
|
|
@@ -121,7 +121,7 @@ import UiDatalist from './Datalist.vue';
|
|
|
121
121
|
import UiPopover from './Popover.vue';
|
|
122
122
|
import { Key, Position } from './utils/Helpers';
|
|
123
123
|
|
|
124
|
-
const withUnitRegExp = /^([\d.]*)(\D+)$/i;
|
|
124
|
+
const withUnitRegExp = /^(-?[\d.]*)(\D+)$/i;
|
|
125
125
|
|
|
126
126
|
export default {
|
|
127
127
|
mixins: [FormComponent, WithPopover],
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
```vue
|
|
2
|
+
<template>
|
|
3
|
+
<div class="pad-l5">
|
|
4
|
+
<p>Lazy list: {{ numItems }} items (see devtools)</p>
|
|
5
|
+
<div id="lazy-container" class="tile">
|
|
6
|
+
<ui-lazy v-bind="props" v-for="i in numItems" :key="`lazy` + i">
|
|
7
|
+
<test-component>lazy #{{ i }}</test-component>
|
|
8
|
+
</ui-lazy>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
<script>
|
|
13
|
+
import UiLazy from './Lazy.vue';
|
|
14
|
+
|
|
15
|
+
const TestComponent = {
|
|
16
|
+
template: `<div class="pad-h-l1 pad-v-3"><slot></slot></div>`,
|
|
17
|
+
};
|
|
18
|
+
export default {
|
|
19
|
+
components: { UiLazy, TestComponent },
|
|
20
|
+
data() {
|
|
21
|
+
return {
|
|
22
|
+
props: {
|
|
23
|
+
root: '#lazy-container',
|
|
24
|
+
minHeight: '2rem',
|
|
25
|
+
},
|
|
26
|
+
numItems: 1000,
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
</script>
|
|
31
|
+
<style scoped>
|
|
32
|
+
#lazy-container {
|
|
33
|
+
overflow: auto;
|
|
34
|
+
max-height: 10rem;
|
|
35
|
+
}
|
|
36
|
+
</style>
|
|
37
|
+
```
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { useIntersectionObserver } from './utils/Helpers';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
props: {
|
|
6
|
+
/** which tag name to use when wrapping slot */
|
|
7
|
+
tag: { type: String, default: 'div' },
|
|
8
|
+
/** viewport element selector/reference or null for 'viewport' */
|
|
9
|
+
root: { type: [String, Element], default: null },
|
|
10
|
+
/** viewport margins */
|
|
11
|
+
rootMargin: { type: String, default: '300px' },
|
|
12
|
+
/** target's visibility ratios */
|
|
13
|
+
threshold: { type: [Number, Array], default: 0 },
|
|
14
|
+
/** defered rendering delay (ms) */
|
|
15
|
+
renderDelay: { type: Number, default: 100 },
|
|
16
|
+
/** defered rendering delay (ms) */
|
|
17
|
+
unrenderDelay: { type: Number, default: 500 },
|
|
18
|
+
/** default initial min-height of the lazy content */
|
|
19
|
+
minHeight: { type: String, default: '' },
|
|
20
|
+
},
|
|
21
|
+
data: () => ({ shouldRender: false, minHeightCalc: 0 }),
|
|
22
|
+
created() {
|
|
23
|
+
/** @type {Function} */
|
|
24
|
+
this.stopObserver = null;
|
|
25
|
+
/** @type {number} */
|
|
26
|
+
this.renderTimeout = null;
|
|
27
|
+
},
|
|
28
|
+
computed: {
|
|
29
|
+
/** @return {object} */
|
|
30
|
+
cssStyle() {
|
|
31
|
+
const { minHeight, minHeightCalc } = this;
|
|
32
|
+
const mh = minHeightCalc ? `${minHeightCalc}px` : minHeight;
|
|
33
|
+
return { minHeight: mh };
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
mounted() {
|
|
37
|
+
const { root: rootSelector, rootMargin, threshold } = this;
|
|
38
|
+
const root =
|
|
39
|
+
rootSelector instanceof Element ? rootSelector : document.querySelector(rootSelector);
|
|
40
|
+
const { stop } = useIntersectionObserver(
|
|
41
|
+
this.$el,
|
|
42
|
+
([{ isIntersecting }]) => this.handleIntersection(isIntersecting),
|
|
43
|
+
{ root, rootMargin, threshold }
|
|
44
|
+
);
|
|
45
|
+
this.stopObserver = stop;
|
|
46
|
+
this.calcMinHeight();
|
|
47
|
+
},
|
|
48
|
+
beforeDestroy() {
|
|
49
|
+
if (this.stopObserver) {
|
|
50
|
+
this.stopObserver();
|
|
51
|
+
}
|
|
52
|
+
this.calcMinHeight();
|
|
53
|
+
},
|
|
54
|
+
methods: {
|
|
55
|
+
/**
|
|
56
|
+
* @param {boolean} shouldRender
|
|
57
|
+
* @effect shouldRender, renderTimeout
|
|
58
|
+
*/
|
|
59
|
+
handleIntersection(shouldRender) {
|
|
60
|
+
const { renderTimeout, renderDelay, unrenderDelay } = this;
|
|
61
|
+
// clear prev render/unrender if any
|
|
62
|
+
if (renderTimeout) {
|
|
63
|
+
clearTimeout(renderTimeout);
|
|
64
|
+
}
|
|
65
|
+
const delay = shouldRender ? renderDelay : unrenderDelay;
|
|
66
|
+
this.renderTimeout = setTimeout(() => {
|
|
67
|
+
this.$nextTick(() => {
|
|
68
|
+
this.shouldRender = shouldRender;
|
|
69
|
+
if (shouldRender) {
|
|
70
|
+
this.calcMinHeight();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}, delay);
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* Recalcs min-height
|
|
77
|
+
* @effect minHeightCalc
|
|
78
|
+
*/
|
|
79
|
+
calcMinHeight() {
|
|
80
|
+
this.$nextTick(() => {
|
|
81
|
+
this.minHeightCalc = this.$el.clientHeight;
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
render(h) {
|
|
86
|
+
const { tag, shouldRender, cssStyle: style } = this;
|
|
87
|
+
const { default: defaultSlot } = this.$scopedSlots;
|
|
88
|
+
const children = shouldRender && defaultSlot ? defaultSlot() : [];
|
|
89
|
+
return h(tag, { style }, children);
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
</script>
|
|
@@ -97,17 +97,10 @@ export default {
|
|
|
97
97
|
default: false,
|
|
98
98
|
},
|
|
99
99
|
},
|
|
100
|
+
data() {
|
|
101
|
+
return { cssStyle: {} };
|
|
102
|
+
},
|
|
100
103
|
computed: {
|
|
101
|
-
cssStyle() {
|
|
102
|
-
const { zIndex, autoWidth } = this;
|
|
103
|
-
const obj = { zIndex };
|
|
104
|
-
const target = this.getTarget();
|
|
105
|
-
if (autoWidth && target) {
|
|
106
|
-
const b = target.getBoundingClientRect();
|
|
107
|
-
obj.width = `${b.width}px`;
|
|
108
|
-
}
|
|
109
|
-
return obj;
|
|
110
|
-
},
|
|
111
104
|
placement() {
|
|
112
105
|
const { position } = this;
|
|
113
106
|
const map = { t: Position.TOP, l: Position.START, r: Position.END, b: Position.BOTTOM };
|
|
@@ -146,7 +139,10 @@ export default {
|
|
|
146
139
|
},
|
|
147
140
|
],
|
|
148
141
|
});
|
|
149
|
-
this.$nextTick(() =>
|
|
142
|
+
this.$nextTick(() => {
|
|
143
|
+
this.calcStyle();
|
|
144
|
+
this.popper.update();
|
|
145
|
+
});
|
|
150
146
|
} else {
|
|
151
147
|
this.removeEventListeners();
|
|
152
148
|
this.destroyPopper();
|
|
@@ -172,6 +168,16 @@ export default {
|
|
|
172
168
|
window.removeEventListener('blur', this.onWinBlur);
|
|
173
169
|
document.removeEventListener('mousedown', this.onDocMouseDown);
|
|
174
170
|
},
|
|
171
|
+
calcStyle() {
|
|
172
|
+
const { zIndex, autoWidth } = this;
|
|
173
|
+
const target = this.getTarget();
|
|
174
|
+
const style = { zIndex };
|
|
175
|
+
if (autoWidth && target) {
|
|
176
|
+
const b = target.getBoundingClientRect();
|
|
177
|
+
style.width = `${b.width}px`;
|
|
178
|
+
}
|
|
179
|
+
this.cssStyle = style;
|
|
180
|
+
},
|
|
175
181
|
getTarget() {
|
|
176
182
|
let { target } = this;
|
|
177
183
|
return isElem(target) ? target : document.querySelector(target);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
const scrollIntoView = c => {
|
|
2
2
|
if (!c || !c.parentNode) {
|
|
3
3
|
return;
|
|
4
4
|
}
|
|
@@ -15,8 +15,8 @@ let scrollIntoView = c => {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
let ID = 1;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const nextId = prefix => `${prefix}-${ID++}`;
|
|
19
|
+
const isDateValid = d => d instanceof Date && !isNaN(d.getTime());
|
|
20
20
|
|
|
21
21
|
const Key = {
|
|
22
22
|
UP: 'ArrowUp',
|
|
@@ -34,7 +34,7 @@ const Position = {
|
|
|
34
34
|
END: 'end',
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
const debounce = (func,
|
|
37
|
+
const debounce = (func, delay) => {
|
|
38
38
|
let timeout;
|
|
39
39
|
return function executedFunction(...args) {
|
|
40
40
|
const later = () => {
|
|
@@ -42,8 +42,20 @@ const debounce = (func, wait) => {
|
|
|
42
42
|
func(...args);
|
|
43
43
|
};
|
|
44
44
|
clearTimeout(timeout);
|
|
45
|
-
timeout = setTimeout(later,
|
|
45
|
+
timeout = setTimeout(later, delay);
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
/**
|
|
50
|
+
* @param {Element} target
|
|
51
|
+
* @param {IntersectionObserverCallback} callback
|
|
52
|
+
* @param {IntersectionObserverInit} options
|
|
53
|
+
* @return {{ observer:IntersectionObserver, stop:Function }}
|
|
54
|
+
*/
|
|
55
|
+
const useIntersectionObserver = (target, callback, options) => {
|
|
56
|
+
const observer = new IntersectionObserver(callback, options);
|
|
57
|
+
observer.observe(target);
|
|
58
|
+
return { observer, stop: () => observer.disconnect() };
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export { scrollIntoView, isDateValid, nextId, Key, Position, debounce, useIntersectionObserver };
|
package/public/index.html
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
6
|
-
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
|
7
|
-
<link rel="stylesheet" href="https://goodt-css.netlify.app/css/all.css" />
|
|
8
|
-
<link
|
|
9
|
-
rel="stylesheet"
|
|
10
|
-
href="https://cdn.materialdesignicons.com/5.4.55/css/materialdesignicons.min.css"
|
|
11
|
-
/>
|
|
12
|
-
<link
|
|
13
|
-
rel="stylesheet"
|
|
14
|
-
href="http://cdn.materialdesignicons.com/light/0.2.63/css/materialdesignicons-light.min.css"
|
|
15
|
-
/>
|
|
16
|
-
<title><%= htmlWebpackPlugin.options.title %></title>
|
|
17
|
-
</head>
|
|
18
|
-
|
|
19
|
-
<body>
|
|
20
|
-
<noscript>
|
|
21
|
-
<strong
|
|
22
|
-
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly
|
|
23
|
-
without JavaScript enabled. Please enable it to continue.</strong
|
|
24
|
-
>
|
|
25
|
-
</noscript>
|
|
26
|
-
<div id="app"></div>
|
|
27
|
-
<!-- built files will be auto injected -->
|
|
28
|
-
</body>
|
|
29
|
-
</html>
|