Skip to content

Commit

Permalink
💥 Vuexless
Browse files Browse the repository at this point in the history
  • Loading branch information
gluons committed Oct 23, 2017
1 parent f6e2138 commit 490c993
Show file tree
Hide file tree
Showing 19 changed files with 91 additions and 216 deletions.
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@
"Firefox ESR",
"last 3 versions"
],
"peerDependencies": {},
"peerDependencies": {
"vue": ">=2.3.0"
},
"devDependencies": {
"@types/chai": "^4.0.3",
"@types/copy-webpack-plugin": "^4.0.0",
Expand Down Expand Up @@ -109,7 +111,6 @@
},
"dependencies": {
"array-filter": "^1.0.0",
"string-similarity": "^1.2.0",
"vuex": "^3.0.0"
"string-similarity": "^1.2.0"
}
}
49 changes: 39 additions & 10 deletions src/components/AddressForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,40 @@
.typeahead-address-form
.row
.col
typeahead-input(target='district', :label='subdistrictLabel')
typeahead-input(
:dataSource='dataSource',
target='district',
:label='subdistrictLabel',
@itemselect='onItemSelect'
)
.col
typeahead-input(target='amphoe', :label='districtLabel')
typeahead-input(
:dataSource='dataSource',
target='amphoe',
:label='districtLabel',
@itemselect='onItemSelect'
)
.row
.col
typeahead-input(target='province', :label='provinceLabel')
typeahead-input(
:dataSource='dataSource',
target='province',
:label='provinceLabel',
@itemselect='onItemSelect'
)
.col
typeahead-input(target='zipcode', :label='zipcodeLabel')
typeahead-input(
:dataSource='dataSource',
target='zipcode',
:label='zipcodeLabel',
@itemselect='onItemSelect'
)
</template>

<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';
import store from '@/store';
import { loadDataSource } from '@/lib/datasource-utils';
import TypeaheadInput from './TypeaheadInput.vue';
Expand All @@ -44,19 +62,30 @@ import TypeaheadInput from './TypeaheadInput.vue';
components: {
TypeaheadInput
},
store
data() {
return {
dataSource: []
};
}
})
export default class AddressForm extends Vue {
// Data
dataSource: AddressEntry[];
// Props
subdistrictLabel: string;
districtLabel: string;
provinceLabel: string;
zipcodeLabel: string;
// Hooks
created() {
let dataSource: AddressEntry[] = loadDataSource();
this.$store.dispatch('updateDataSource', dataSource);
async created() {
this.dataSource = await loadDataSource();
}
// Methods
onItemSelect(item: AddressEntry) {
console.log(item);
}
}
</script>
Expand Down
18 changes: 8 additions & 10 deletions src/components/Autocomplete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { addressToString, getDataItemKeys } from '@/lib/utils';
@Component({
name: 'autocomplete',
props: {
query: String,
possibles: Array,
target: {
type: String,
required: true
Expand All @@ -35,6 +37,8 @@ import { addressToString, getDataItemKeys } from '@/lib/utils';
})
export default class Autocomplete extends Vue {
// Props
query: string;
possibles: AddressEntry[];
target: string; // A property name in data item.
maxHeight: number; // Max autocomplete height.
selectedIndex: number;
Expand All @@ -45,14 +49,11 @@ export default class Autocomplete extends Vue {
'max-height': `${this.maxHeight}px`
};
}
get query(): string {
return this.$store.state[this.target].value;
}
get hasData(): boolean {
return this.$store.getters[`${this.target}/hasAutocomplete`];
return this.possibles && (this.possibles.length > 0);
}
get autocompleteList() {
let autocomplete: AddressEntry[] = this.$store.getters[`${this.target}/autocomplete`];
let autocomplete: AddressEntry[] = this.possibles;
return autocomplete.map(item => {
return {
Expand All @@ -63,11 +64,8 @@ export default class Autocomplete extends Vue {
}
// Methods
onItemClick(data: AddressEntry): void {
let keys: string[] = getDataItemKeys(data);
keys.forEach(key => {
this.$store.dispatch(`${key}/updateValue`, data[key]);
});
onItemClick(item: AddressEntry): void {
this.$emit('itemclick', item);
}
changeSelectedIndex(index: number): void {
if ((index >= 0) && (index < this.autocompleteList.length)) {
Expand Down
64 changes: 35 additions & 29 deletions src/components/TypeaheadInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@
@keyup.esc='closeAutocomplete',
@keyup.up='moveSelectedIndex(-1)',
@keyup.down='moveSelectedIndex(1)',
@keyup.enter.prevent='fillItemData'
@keyup.enter.prevent='selectItemData'
)
autocomplete(:query='query', :target='target', :selectedIndex.sync='selectedIndex')
autocomplete(
:query='query',
:possibles='possibles',
:target='target',
:selectedIndex.sync='selectedIndex',
@itemclick='onItemClick'
)
//- When no label
template(v-else)
input.typeahead-input(
Expand All @@ -27,9 +33,15 @@
@keyup.esc='closeAutocomplete',
@keyup.up='moveSelectedIndex(-1)',
@keyup.down='moveSelectedIndex(1)',
@keyup.enter.prevent='fillItemData'
@keyup.enter.prevent='selectItemData'
)
autocomplete(
:query='query',
:possibles='possibles',
:target='target',
:selectedIndex.sync='selectedIndex',
@itemclick='onItemClick'
)
autocomplete(:query='query', :target='target', :list='list', :selectedIndex.sync='selectedIndex')
</template>

<script lang="ts">
Expand All @@ -45,6 +57,10 @@ const AUTOCOMPLETE_CLOSE_DELAY = 250;
@Component({
name: 'typeahead-input',
props: {
dataSource: {
type: Array,
required: true
},
target: {
type: String,
required: true
Expand All @@ -56,33 +72,26 @@ const AUTOCOMPLETE_CLOSE_DELAY = 250;
},
data() {
return {
query: '',
possibles: [],
selectedIndex: -1,
autocompleteCount: 0
};
}
})
export default class TypeaheadInput extends Vue {
// Data
selectedIndex: number = -1;
autocompleteCount: number = 0;
query: string;
possibles: AddressEntry[];
selectedIndex: number;
autocompleteCount: number;
// Props
dataSource: AddressEntry[];
target: string; // Name. It's an actual property name in address data.
label: string; // Input label.
// Computed
get dataSource(): AddressEntry[] {
return this.$store.state.dataSource;
}
get possibles(): AddressEntry[] {
return this.$store.getters[`${this.target}/autocomplete`];
}
get query(): string {
return this.$store.state[this.target].value;
}
set query(value: string) {
this.$store.dispatch(`${this.target}/updateValue`, value);
}
get hasLabel(): boolean {
return (this.label != null) && (this.label.length > 0);
}
Expand All @@ -92,21 +101,18 @@ export default class TypeaheadInput extends Vue {
if (this.query.length > 0) {
let possibles = getPossibles(this.dataSource, this.target, this.query);
this.autocompleteCount = possibles.length;
this.$store.dispatch(`${this.target}/updateList`, possibles);
this.possibles = possibles;
} else {
this.selectedIndex = -1;
this.autocompleteCount = 0;
this.$store.dispatch(`${this.target}/clearList`);
this.possibles = [];
}
}
closeAutocomplete(immediate: boolean) {
setTimeout(() => {
this.selectedIndex = -1;
this.autocompleteCount = 0;
this.$store.dispatch(`${this.target}/clearList`);
this.possibles = [];
}, immediate ? 0 : AUTOCOMPLETE_CLOSE_DELAY);
}
moveSelectedIndex(indicator: number) {
Expand All @@ -122,17 +128,17 @@ export default class TypeaheadInput extends Vue {
this.selectedIndex = ((this.selectedIndex + indicator) >= this.autocompleteCount) ? 0 : (this.autocompleteCount - 1);
}
}
fillItemData() {
selectItemData() {
let selectedIndex = this.selectedIndex;
if (this.possibles[selectedIndex]) {
let selectedItem = Object.assign({}, this.possibles[selectedIndex]); // Shallow Clone
let keys = getDataItemKeys(selectedItem);
keys.forEach(key => {
this.$store.dispatch(`${key}/updateValue`, selectedItem[key]);
});
this.$emit('itemselect', selectedItem);
}
this.closeAutocomplete(true);
}
onItemClick(item: AddressEntry) {
this.$emit('itemselect', item);
}
}
</script>

Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ declare global {
*
* @param {typeof Vue} vue Vue instance.
*/
function install(vue: typeof Vue): void {
function install(vue): void {
vue.component('address-form', AddressForm);
}

Expand Down
20 changes: 0 additions & 20 deletions src/store/actions.ts

This file was deleted.

29 changes: 0 additions & 29 deletions src/store/index.ts

This file was deleted.

19 changes: 0 additions & 19 deletions src/store/modules/input-module/actions.ts

This file was deleted.

15 changes: 0 additions & 15 deletions src/store/modules/input-module/getters.ts

This file was deleted.

Loading

0 comments on commit 490c993

Please sign in to comment.