Skip to content

Commit 69f71e2

Browse files
author
Dominik Decker
committed
Updated Project to use TypeScript
1 parent 4395ccc commit 69f71e2

File tree

11 files changed

+546
-236
lines changed

11 files changed

+546
-236
lines changed

package.json

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
11
{
22
"name": "vue-overlay-host",
3-
"version": "0.1.2",
3+
"version": "0.2.0",
44
"private": false,
5-
"main": "dist/vue-overlay-host.common.js",
65
"scripts": {
7-
"serve": "vue-cli-service serve ./example/main.js",
86
"build": "vue-cli-service build --target lib ./src/lib.js",
97
"lint": "vue-cli-service lint"
108
},
119
"dependencies": {
1210
"vue": "^2.5.17",
11+
"vue-class-component": "^6.0.0",
12+
"vue-property-decorator": "^7.0.0",
1313
"vuex": "^3.0.1"
1414
},
1515
"devDependencies": {
1616
"@vue/cli-plugin-babel": "^3.0.3",
1717
"@vue/cli-plugin-eslint": "^3.0.3",
18+
"@vue/cli-plugin-typescript": "^3.0.4",
1819
"@vue/cli-service": "^3.0.3",
20+
"@vue/eslint-config-typescript": "^3.0.4",
1921
"eslint-config-prettier": "^3.1.0",
2022
"eslint-plugin-prettier": "^2.6.2",
2123
"eslint-plugin-vue": "^4.7.1",
2224
"node-sass": "^4.9.3",
2325
"sass-loader": "^7.1.0",
24-
"vue-template-compiler": "^2.5.17"
26+
"typescript": "^3.0.0",
27+
"vue-template-compiler": "^2.5.17",
28+
"vuex-class": "^0.3.1"
2529
},
2630
"eslintConfig": {
2731
"root": true,
@@ -30,11 +34,12 @@
3034
},
3135
"extends": [
3236
"plugin:vue/essential",
33-
"eslint:recommended"
37+
"eslint:recommended",
38+
"@vue/typescript"
3439
],
3540
"rules": {},
3641
"parserOptions": {
37-
"parser": "babel-eslint"
42+
"parser": "typescript-eslint-parser"
3843
}
3944
},
4045
"postcss": {
@@ -46,5 +51,6 @@
4651
"> 1%",
4752
"last 2 versions",
4853
"not ie <= 8"
49-
]
54+
],
55+
"main": "dist/vue-overlay-host.common.js"
5056
}

src/common.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { Vue } from 'vue-property-decorator';
2+
3+
export const NAMESPACE_NAME = 'overlay-host';
4+
5+
export interface PluginSettings {
6+
timeout?: number;
7+
}
8+
9+
export interface OverlayHostState {
10+
items: EntrySetting[];
11+
idCounter: number;
12+
}
13+
14+
export interface EntrySetting {
15+
id: number;
16+
timeoutId?: number;
17+
resolver: (value?: any, origin?: string) => any;
18+
rejector: (value?: any, origin?: string) => any;
19+
settings: FinalShowOptions;
20+
}
21+
22+
interface OverlayOptions {
23+
show: boolean;
24+
closeOnClick: boolean;
25+
}
26+
27+
interface BaseShowOptions {
28+
component: string | Vue;
29+
closeOnEscape?: boolean;
30+
timeout?: number;
31+
props?: {
32+
[name: string]: any;
33+
};
34+
}
35+
36+
interface FinalShowOptions extends BaseShowOptions {
37+
overlay: OverlayOptions;
38+
}
39+
40+
export interface ShowOptions extends BaseShowOptions {
41+
overlay?: boolean | OverlayOptions;
42+
}
43+
44+
export interface ShowResponse {
45+
id: number;
46+
promise: Promise<RemoveRequest>;
47+
close: (value?: any, origin?: string) => void;
48+
abort: (value?: any, origin?: string) => void;
49+
}
50+
51+
export interface RemoveRequest {
52+
id: number;
53+
origin?: string;
54+
value?: any;
55+
}

src/components/OverlayHost.vue

Lines changed: 78 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -17,85 +17,100 @@
1717
</div>
1818
</template>
1919

20-
<script>
21-
import { mapState } from 'vuex';
20+
<script lang="ts">
21+
import { Component, Vue } from 'vue-property-decorator';
22+
import { namespace } from 'vuex-class';
23+
24+
import { NAMESPACE_NAME, EntrySetting } from '@/common';
25+
26+
const moduleNamespace = namespace(NAMESPACE_NAME);
27+
28+
@Component({
29+
name: 'overlay-host'
30+
})
31+
export default class OverlayHost extends Vue {
32+
/**
33+
* Flag if the Overlay (behind the elements) should be shown.
34+
*/
35+
public showOverlay = false;
36+
37+
/**
38+
* Handle of the store-watcher which should be removed once the
39+
* component is getting destroyed.
40+
*/
41+
private storeWatcher() {}
42+
43+
@moduleNamespace.State('items')
44+
public items: EntrySetting[];
2245
23-
export default {
24-
name: 'overlay-host',
2546
created() {
26-
this.storeWatcher = this.$store.watch(state => state['overlay-host'].items, this.itemsChange, {
47+
this.storeWatcher = this.$store.watch(state => state[NAMESPACE_NAME].items, this.itemsChange, {
2748
deep: true
2849
});
2950
window.addEventListener('keydown', this.handleWindowKeydown);
30-
},
51+
}
52+
3153
beforeDestroy() {
3254
if (this.storeWatcher != null) {
3355
this.storeWatcher();
3456
}
3557
window.removeEventListener('keydown', this.handleWindowKeydown);
36-
},
37-
data() {
38-
return {
39-
storeWatcher: null,
40-
showOverlay: false
41-
};
42-
},
43-
computed: {
44-
...mapState('overlay-host', ['items'])
45-
},
46-
methods: {
47-
itemsChange() {
48-
this.showOverlay = false;
49-
for (let i = 0; i < this.items.length; i++) {
50-
if (this.items[i].settings.overlay.show) {
51-
this.showOverlay = true;
52-
break;
53-
}
54-
}
55-
},
56-
overlayClick() {
57-
this.removeLast('click');
58-
},
59-
handleWindowKeydown(event) {
60-
if (event.key === 'Escape' || event.keyCode === 27) {
61-
event.preventDefault();
62-
this.removeLast('escape');
63-
}
64-
},
65-
removeLast(origin) {
66-
// No items to iterate over
67-
if (this.items.length <= 0) {
68-
return;
69-
}
70-
let removed = false;
71-
72-
// Clone the items to be able to edit it
73-
const workItems = [...this.items];
74-
75-
// Iterate over the array in reverse to get the latestly added item
76-
// which should be closed on escape
77-
for (let i = workItems.length - 1; i >= 0; i--) {
78-
const item = workItems[i];
79-
if (
80-
(origin === 'click' && (!item.settings.overlay.show || !item.settings.overlay.closeOnClick)) ||
81-
(origin === 'escape' && !item.settings.closeOnEscape)
82-
) {
83-
continue;
84-
}
85-
86-
clearTimeout(item.timeoutId);
87-
item.resolver({ value: undefined, origin });
88-
workItems.splice(i, 1);
89-
removed = true;
58+
}
59+
60+
itemsChange() {
61+
this.showOverlay = false;
62+
for (let i = 0; i < this.items.length; i++) {
63+
if (this.items[i].settings.overlay.show) {
64+
this.showOverlay = true;
9065
break;
9166
}
67+
}
68+
}
69+
70+
overlayClick() {
71+
this.removeLast('click');
72+
}
9273
93-
if (removed) {
94-
this.$store.commit('overlay-host/setItems', workItems);
74+
handleWindowKeydown(event: KeyboardEvent) {
75+
if (event.key === 'Escape' || event.keyCode === 27) {
76+
event.preventDefault();
77+
this.removeLast('escape');
78+
}
79+
}
80+
81+
removeLast(origin: 'click' | 'escape') {
82+
// No items to iterate over
83+
if (this.items.length <= 0) {
84+
return;
85+
}
86+
let removed = false;
87+
88+
// Clone the items to be able to edit it
89+
const workItems = [...this.items];
90+
91+
// Iterate over the array in reverse to get the latestly added item
92+
// which should be closed on escape
93+
for (let i = workItems.length - 1; i >= 0; i--) {
94+
const item = workItems[i];
95+
if (
96+
(origin === 'click' && (!item.settings.overlay.show || !item.settings.overlay.closeOnClick)) ||
97+
(origin === 'escape' && !item.settings.closeOnEscape)
98+
) {
99+
continue;
95100
}
101+
102+
clearTimeout(item.timeoutId);
103+
item.resolver({ value: undefined, origin });
104+
workItems.splice(i, 1);
105+
removed = true;
106+
break;
107+
}
108+
109+
if (removed) {
110+
this.$store.commit(`${NAMESPACE_NAME}/setItems`, workItems);
96111
}
97112
}
98-
};
113+
}
99114
</script>
100115

101116
<style>

src/lib.js

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/lib.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Store } from 'vuex';
2+
3+
import { PluginSettings, OverlayHostState } from './common';
4+
import OverlayHost from './components/OverlayHost.vue';
5+
import { createModule } from './store';
6+
7+
export * from './common';
8+
export { OverlayHost };
9+
export function OverlayHostPlugin(store: Store<any>, settings: PluginSettings) {
10+
store.registerModule('overlay-host', createModule(settings));
11+
}

src/shims-tsx.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Vue, { VNode } from 'vue'
2+
3+
declare global {
4+
namespace JSX {
5+
// tslint:disable no-empty-interface
6+
interface Element extends VNode {}
7+
// tslint:disable no-empty-interface
8+
interface ElementClass extends Vue {}
9+
interface IntrinsicElements {
10+
[elem: string]: any
11+
}
12+
}
13+
}

src/shims-vue.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module '*.vue' {
2+
import Vue from 'vue'
3+
export default Vue
4+
}

0 commit comments

Comments
 (0)