@modeltables/fontawesome-vuetify 1.0.1
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/README.md +86 -0
- package/components/headerFilters/Date.vue +41 -0
- package/components/headerFilters/Number.vue +41 -0
- package/components/headerFilters/Text.vue +39 -0
- package/components/helpers/resources.ts +5 -0
- package/components/index.d.ts +14 -0
- package/components/models/table-models.ts +20 -0
- package/components/pagination/PaginationView.vue +114 -0
- package/components/sort/SortView.vue +45 -0
- package/components/table/TableView.vue +391 -0
- package/dist/index.amd.ts +574 -0
- package/dist/index.cjs.ts +574 -0
- package/dist/style.css +1 -0
- package/package.json +55 -0
- package/tsconfig.json +52 -0
- package/vite.config.js +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
@modelforms/fontawesome-vuetify is a focused Vue library that
|
|
2
|
+
modelforms-fontawesome-vuetify is a focused Vue library that brings Font Awesome icons into Vuetify-powered model forms with minimal fuss. It streamlines the process of decorating form fields with meaningful icons so forms feel polished and intuitive. Developers can rapidly prototype UIs by dropping in ready-made wrappers that handle both icon placement and Vuetify styling. Because it's built for the reactive Vue ecosystem, icons update predictably as form state changes. Customization is straightforward: swap icons, tweak sizes, or apply Vuetify themes without touching core logic. Accessibility is considered through aria-friendly patterns and clear visual affordances that help users understand form intent. The library’s lightweight design keeps your bundle lean while delivering a big UX payoff. Concise examples and clear documentation make it easy for new users to get productive in minutes. Whether you’re building an admin dashboard or a public-facing signup flow, it elevates both form clarity and aesthetics. In short, modelforms-fontawesome-vuetify is a practical toolkit for anyone who wants to combine the expressive power of Font Awesome with Vuetify’s polished components to make forms that both look and feel professional.
|
|
3
|
+
|
|
4
|
+
#First step create component
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
<template>
|
|
8
|
+
<FormComponent
|
|
9
|
+
:form="form"
|
|
10
|
+
@submit="submit($event)"/>
|
|
11
|
+
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script lang="ts">
|
|
15
|
+
import { FormPlate } from '@modelforms/fontawesome-vuetify';
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
|
|
19
|
+
components: {
|
|
20
|
+
FormComponent: FormPlate
|
|
21
|
+
},
|
|
22
|
+
data() {
|
|
23
|
+
return {
|
|
24
|
+
form: testForm
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
methods:{
|
|
28
|
+
submit(event){
|
|
29
|
+
console.log(event);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
</script>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
#Second step create sub model
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { GridModel } from '@modelforms/fontawesome-vuetify';
|
|
40
|
+
|
|
41
|
+
class UserModel {
|
|
42
|
+
name: string;
|
|
43
|
+
phone: any[] = []
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const testForm: GridModel<UserModel> = {
|
|
47
|
+
model: new UserModel(),
|
|
48
|
+
rows: [
|
|
49
|
+
{
|
|
50
|
+
colSize: 12,
|
|
51
|
+
cols: [
|
|
52
|
+
{
|
|
53
|
+
name: "name",
|
|
54
|
+
type: "text",
|
|
55
|
+
rules: {
|
|
56
|
+
rules: [(v) => v?.length <= 3 || "Not longer than 3!"]
|
|
57
|
+
},
|
|
58
|
+
label: "Name",
|
|
59
|
+
size: 12,
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
colSize: 12,
|
|
65
|
+
cols: [
|
|
66
|
+
{
|
|
67
|
+
name: "Description",
|
|
68
|
+
type: "area",
|
|
69
|
+
label: "Description",
|
|
70
|
+
size: 6,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "phone",
|
|
74
|
+
type: "complete",
|
|
75
|
+
label: "Phone",
|
|
76
|
+
size: 12,
|
|
77
|
+
complete: {
|
|
78
|
+
items : [],
|
|
79
|
+
itemValue: [],
|
|
80
|
+
title: "title"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}]
|
|
85
|
+
}
|
|
86
|
+
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { faCalendar } from '@fortawesome/free-regular-svg-icons';
|
|
3
|
+
export default {
|
|
4
|
+
props: {
|
|
5
|
+
data: {
|
|
6
|
+
type: Object,
|
|
7
|
+
required: true
|
|
8
|
+
},
|
|
9
|
+
filter: {
|
|
10
|
+
type: Object,
|
|
11
|
+
required: true
|
|
12
|
+
},
|
|
13
|
+
prop: {
|
|
14
|
+
type: String,
|
|
15
|
+
required: true
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
data() {
|
|
19
|
+
return {
|
|
20
|
+
data: this.data,
|
|
21
|
+
filter: this.filter,
|
|
22
|
+
prop: this.prop,
|
|
23
|
+
calendar: faCalendar
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
methods: {
|
|
27
|
+
filterDate(event: any){
|
|
28
|
+
this.data[this.prop] = event.target.value;
|
|
29
|
+
this.$emit('filterValue', event);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<v-date-input :prepend-icon="''" label="Date input" @save="filterDate($event)" :v-model="data" :model-value="filter">
|
|
37
|
+
<template v-if="calendar" #prepend-inner>
|
|
38
|
+
<FontAwesomeIcon :icon="calendar" />
|
|
39
|
+
</template>
|
|
40
|
+
</v-date-input>
|
|
41
|
+
</template>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default {
|
|
3
|
+
props: {
|
|
4
|
+
data: {
|
|
5
|
+
type: Object,
|
|
6
|
+
required: true
|
|
7
|
+
},
|
|
8
|
+
filter: {
|
|
9
|
+
type: Object,
|
|
10
|
+
required: true
|
|
11
|
+
},
|
|
12
|
+
prop: {
|
|
13
|
+
type: String,
|
|
14
|
+
required: true
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
data() {
|
|
18
|
+
return {
|
|
19
|
+
data: this.data,
|
|
20
|
+
filter: this.filter,
|
|
21
|
+
prop: this.prop
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
methods: {
|
|
25
|
+
filterValue(event: any, prop: string){
|
|
26
|
+
this.data[this.prop] = event.target.value;
|
|
27
|
+
this.$emit('filterValue', event, prop);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<v-number-input
|
|
35
|
+
@blur="filterValue($event, prop)"
|
|
36
|
+
:v-model="data"
|
|
37
|
+
:model-value="filter"
|
|
38
|
+
:precision="2"
|
|
39
|
+
control-variant="hidden">
|
|
40
|
+
</v-number-input>
|
|
41
|
+
</template>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default {
|
|
3
|
+
props: {
|
|
4
|
+
data: {
|
|
5
|
+
type: Object,
|
|
6
|
+
required: true
|
|
7
|
+
},
|
|
8
|
+
filter: {
|
|
9
|
+
type: Object,
|
|
10
|
+
required: true
|
|
11
|
+
},
|
|
12
|
+
prop: {
|
|
13
|
+
type: String,
|
|
14
|
+
required: true
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
data() {
|
|
18
|
+
return {
|
|
19
|
+
data: this.data,
|
|
20
|
+
filter: this.filter,
|
|
21
|
+
prop: this.prop
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
methods: {
|
|
25
|
+
filterValue(event: any){
|
|
26
|
+
this.data[this.prop] = event.target.value;
|
|
27
|
+
this.$emit('filterValue', event);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<v-text-field
|
|
35
|
+
@blur="filterValue($event)"
|
|
36
|
+
:v-model="data"
|
|
37
|
+
:model-value="filter">
|
|
38
|
+
</v-text-field>
|
|
39
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*! @licence MIT */
|
|
2
|
+
|
|
3
|
+
export { default as TableView } from "./table/TableView.vue";
|
|
4
|
+
export { HeaderModel, PaginatonModel, PaginatedResponse } from './models/table-models';
|
|
5
|
+
|
|
6
|
+
/*!
|
|
7
|
+
* Vuetify Labs v3.4.0 by vuetify - https://vuetifyjs.com
|
|
8
|
+
* Licensed under the MIT License (MIT), see LICENSE.
|
|
9
|
+
* Copyright 2025S Vuetify Labs, Inc.
|
|
10
|
+
|
|
11
|
+
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
|
12
|
+
* License - https://fontawesome.com/license/free - MIT License
|
|
13
|
+
* Copyright 2025 Fonticons, Inc.
|
|
14
|
+
*/
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class HeaderModel{
|
|
2
|
+
title: string = '';
|
|
3
|
+
key?: string;
|
|
4
|
+
sort?: any;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export class PaginatonModel{
|
|
8
|
+
PageCount: number = 1;
|
|
9
|
+
PerPage: number = 10;
|
|
10
|
+
CurrentPage: number = 1;
|
|
11
|
+
TotalCount: number = 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class PaginatedResponse<T>{
|
|
15
|
+
PageSize?: number;
|
|
16
|
+
PageCount?: number;
|
|
17
|
+
CurrentPage?: number;
|
|
18
|
+
TotalCount?: number;
|
|
19
|
+
Items: Array<T> = []
|
|
20
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { faArrowAltCircleDown } from '@fortawesome/free-regular-svg-icons';
|
|
3
|
+
import { faChevronLeft, faChevronRight, faFastBackward, faFastForward } from '@fortawesome/free-solid-svg-icons';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
props: {
|
|
7
|
+
totalCount: {
|
|
8
|
+
type: Number,
|
|
9
|
+
required: true
|
|
10
|
+
},
|
|
11
|
+
pageCount: {
|
|
12
|
+
type: Number,
|
|
13
|
+
required: true
|
|
14
|
+
},
|
|
15
|
+
perPage: {
|
|
16
|
+
type: Number,
|
|
17
|
+
required: true
|
|
18
|
+
},
|
|
19
|
+
page: {
|
|
20
|
+
type: Number,
|
|
21
|
+
required: true
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
data() {
|
|
25
|
+
return {
|
|
26
|
+
totalCount: this.totalCount,
|
|
27
|
+
pageCount: this.pageCount,
|
|
28
|
+
perPage: this.perPage,
|
|
29
|
+
page: this.page,
|
|
30
|
+
arrowDown: faArrowAltCircleDown,
|
|
31
|
+
chevronLeft: faChevronLeft,
|
|
32
|
+
chevronRight: faChevronRight,
|
|
33
|
+
fastBackward: faFastBackward,
|
|
34
|
+
fastForward: faFastForward
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
methods: {
|
|
38
|
+
pageChange(event: any){
|
|
39
|
+
this.$emit('pageChange', event);
|
|
40
|
+
},
|
|
41
|
+
pageSize(event: any){
|
|
42
|
+
this.$emit('pageSize', event);
|
|
43
|
+
},
|
|
44
|
+
firstPage(event: any){
|
|
45
|
+
this.$emit('firstPage', event);
|
|
46
|
+
},
|
|
47
|
+
lastPage(event: any){
|
|
48
|
+
this.$emit('lastPage', event);
|
|
49
|
+
},
|
|
50
|
+
previousPage(event: any){
|
|
51
|
+
this.$emit('previousPage', event);
|
|
52
|
+
},
|
|
53
|
+
nextPage(event: any){
|
|
54
|
+
this.$emit('nextPage', event);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<template>
|
|
62
|
+
<v-row class="text-center px-4 align-center" wrap>
|
|
63
|
+
<v-col class="text-truncate" cols="12" md="2">
|
|
64
|
+
Total {{ totalCount }} records
|
|
65
|
+
</v-col>
|
|
66
|
+
<v-col cols="12" md="8">
|
|
67
|
+
<v-pagination
|
|
68
|
+
v-model="page"
|
|
69
|
+
:prev-icon="''"
|
|
70
|
+
:next-icon="''"
|
|
71
|
+
:width="'200px'"
|
|
72
|
+
:length="pageCount"
|
|
73
|
+
@update:model-value="pageChange($event)">
|
|
74
|
+
<template v-if="fastBackward" #prev>
|
|
75
|
+
<div style="display:flex; margin-top: 6px;">
|
|
76
|
+
<v-btn v-if="pageCount > 1" @click="firstPage($event)" style="margin-right: 10px;">
|
|
77
|
+
<FontAwesomeIcon :icon="fastBackward" color="#303133"/>
|
|
78
|
+
</v-btn>
|
|
79
|
+
<v-btn v-if="pageCount > 1" @click="previousPage($event)">
|
|
80
|
+
<FontAwesomeIcon color="#303133" :icon="chevronLeft"/>
|
|
81
|
+
</v-btn>
|
|
82
|
+
</div>
|
|
83
|
+
</template>
|
|
84
|
+
<template v-if="chevronLeft" #next>
|
|
85
|
+
<div style="display:flex; margin-top: 6px;">
|
|
86
|
+
<v-btn v-if="pageCount > 1" @click="nextPage($event)">
|
|
87
|
+
<FontAwesomeIcon color="#303133" :icon="chevronRight"/>
|
|
88
|
+
</v-btn>
|
|
89
|
+
<v-btn v-if="pageCount > 1" @click="lastPage($event)" style="margin-left: 10px;">
|
|
90
|
+
<FontAwesomeIcon color="#303133" :icon="fastForward"/>
|
|
91
|
+
</v-btn>
|
|
92
|
+
</div>
|
|
93
|
+
</template>
|
|
94
|
+
</v-pagination>
|
|
95
|
+
</v-col>
|
|
96
|
+
<v-col cols="12" md="2">
|
|
97
|
+
<v-select
|
|
98
|
+
v-if="pageCount > 1"
|
|
99
|
+
dense
|
|
100
|
+
outlined
|
|
101
|
+
hide-details
|
|
102
|
+
:value="perPage"
|
|
103
|
+
:menu-icon="''"
|
|
104
|
+
label="Items per page"
|
|
105
|
+
:items="[10,20,50,100]"
|
|
106
|
+
@update:modelValue="pageSize($event)">
|
|
107
|
+
<template v-if="arrowDown" #append-inner>
|
|
108
|
+
<FontAwesomeIcon :icon="arrowDown" />
|
|
109
|
+
</template>
|
|
110
|
+
</v-select>
|
|
111
|
+
</v-col>
|
|
112
|
+
</v-row>
|
|
113
|
+
|
|
114
|
+
</template>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
|
3
|
+
import { faCaretDown, faCaretUp } from '@fortawesome/free-solid-svg-icons';
|
|
4
|
+
export default {
|
|
5
|
+
components: {
|
|
6
|
+
FontAwesomeIcon
|
|
7
|
+
},
|
|
8
|
+
props: {
|
|
9
|
+
prop: {
|
|
10
|
+
type: Object,
|
|
11
|
+
required: true
|
|
12
|
+
},
|
|
13
|
+
index: {
|
|
14
|
+
type: Number,
|
|
15
|
+
required: true
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
data() {
|
|
19
|
+
return {
|
|
20
|
+
prop: this.prop,
|
|
21
|
+
index: this.index,
|
|
22
|
+
carretDown: faCaretDown,
|
|
23
|
+
carretUp: faCaretUp
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
methods: {
|
|
27
|
+
sort(event: any, prop: any, index: number){
|
|
28
|
+
this.$emit('sort', event, prop, index);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<div style="display: flex">
|
|
36
|
+
{{ prop.title }}
|
|
37
|
+
<div v-if="prop.sort">
|
|
38
|
+
<FontAwesomeIcon @click="sort($event, prop, index)" :icon="carretDown"></FontAwesomeIcon>
|
|
39
|
+
</div>
|
|
40
|
+
<div v-else>
|
|
41
|
+
<FontAwesomeIcon @click="sort($event, prop, index)" :icon="carretUp"></FontAwesomeIcon>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
</template>
|