@horleng/awesome-components v1.0.0
Installation
npm install @horleng/awesome-components --save
style
inside main.ts
import "@horleng/awesome-components/dist/style.css"
ripple effect
inside main.ts
import {rippleEffect} from '@horleng/awesome-components'
// vue directive
app.directive('ripple',rippleEffect)
usage
<template>
<!-- call directive -->
<asc-button v-ripple >asc button</asc-button>
<asc-button v-ripple:color="blue" >asc button</asc-button>
</template>
Button
size : small | meduim | large type : default | primary | secondary | danger | warning icon : component rounded : boolean circle : boolean loading : boolean disabled : boolean iconAlignRight : boolean autoFocus : boolean text : boolean
<script setup lang="ts">
import {ref} from "vue"
import {AscButton} from "@horleng/awesome-components"
const el = ref<InstanceType<typeof AscButton>|null>(null);
</script>
<template>
<asc-button size="small" rounded type="danger">Close</asc-button>
<asc-button size="meduim" type="primary">Login</asc-button>
<asc-button size="large" type="warning" :icon="UploadSVG">Upload</asc-button>
<asc-button type="danger" :icon="Times" icon-align-right>Clear</asc-button>
<asc-button :icon="Edit" circle text/>
<asc-button auto-focus type="primary">Okay</asc-button>
</template>
slot
<template>
<asc-button>
<template #default>
<!-- custome here! -->
</template>
<template #icon>
<!-- custome here! -->
</template>
<template #loadingIcon>
<!-- custome here! -->
</template>
</asc-button>
</template>
input switch
id : string size : small | meduim | large
<script setup lang="ts">
import { AscInputSwitch } from "@horleng/awesome-components"
import {ref} from "vue"
const checked = ref(true);
const el = <InstanceType<typeof AscInputSwitch>|null>(null);
</script>
<template>
<div class="app-container">
<asc-input-switch v-model="checked" ref="el"/>
</div>
</template>
<style>
.app-container {
height : 100vh;
display : grid;
place-content : center;
}
</style>
checkbox
inputSize : small | meduim | large circle : boolean id : string inputError : boolean disabled : boolean
<script setup lang="ts">
import { AscCheckbox } from "@horleng/awesome-components"
import {ref} from "vue"
const checked = ref(true) ;
</script>
<template>
<asc-checkbox v-model="checked"/>
</template>
<style>
.app-container {
height : 100vh;
display : grid;
place-content : center;
}
</style>
Simple input
id : string placeholder : string disabled : boolean label : string inputType : text | password inputSize : small | meduim | large inputError : boolean iconLeft : component iconRight : component
<script setup lang="ts">
import {ref,onMounted} from "vue"
import {AscInputSimpleLabel,AscInputBorderBottom,AscInputStyleLabel} from "@horleng/awesome-components"
const firstName = ref("")
const lastName = ref("")
const phoneNumber = ref("")
const el = ref<InstanceType<typeof AscInputSimpleLabel>|null>(null);
onMounted(()=>{
console.log(el.value?.el) //log input element
})
</script>
<template>
<div class="app-container">
<div class="wrapper">
<asc-input-simple-label
v-model="firstName"
label="First Name"
placeholder="Enter first name...."
:icon-right="User"
/>
<asc-input-style-label
v-model="lastName"
label="Last Name"
placeholder="Enter last name...."
/>
<asc-input-border-bottom
v-model="phoneNumber"
input-type="number"
label="Phone Number"
placeholder="Enter your phone number..."
input-error
/>
</div>
</div>
</template>
<style scoped>
.app-container {
height : 100vh;
display : grid;
place-content : center;
}
.wrapper {
width : 300px;
display: flex;
flex-direction: column;
gap: 20px;
}
</style>
slot
<template>
<asc-input-border-bottom>
<template #inputIcon>
<!-- custome here! -->
</template>
</asc-input-border-bottom>
</template>
Dialog
width : number, specific width of dialog component modal : boolean title : string , title of dialog showClose : boolean , show button close at header of dialog outTargetClose : boolean , close when click overlay rounded : boolean animate : zoom-in | fade-down
<script setup lang="ts">
import { AscDialog,AscButton,AscInputSimpleLabel } from "@horleng/awesome-components"
import {ref} from "vue"
const isView = ref(false) ;
const _isView = ref(false) ;
</script>
<template>
<div class="app-container">
<div >
<asc-button type="primary" @click="isView = true" rounded>zoom in dialog</asc-button>
<asc-button type="primary" @click="_isView = true" rounded>fade down dialog 2</asc-button>
</div>
</div>
<asc-dialog
v-model:model-view="isView"
modal
:width="600"
title="Create/Update User"
out-target-close
>
<template #default>
<div class="row">
<div class="col">
<asc-input-simple-label placeholder="First Name"/>
</div>
<div class="col">
<asc-input-simple-label placeholder="Last Name"/>
</div>
</div>
<div class="row">
<div class="col">
<asc-input-simple-label placeholder="Email"/>
</div>
<div class="col">
<asc-input-simple-label placeholder="Phone number" input-type="number"/>
</div>
</div>
</template>
<template #footer>
<asc-button type="danger" @click="isView = false" rounded>Close</asc-button>
<asc-button type="primary" rounded>Save</asc-button>
</template>
</asc-dialog>
<asc-dialog
v-model:model-view="_isView"
modal :width="600"
title="Create/Update User"
animate="fade-down"
>
<template #default>
<div class="row">
<div class="col">
<asc-input-simple-label placeholder="First Name"/>
</div>
<div class="col">
<asc-input-simple-label placeholder="Last Name"/>
</div>
</div>
<div class="row">
<div class="col">
<asc-input-simple-label placeholder="Email"/>
</div>
<div class="col">
<asc-input-simple-label placeholder="Phone number" input-type="number"/>
</div>
</div>
</template>
<template #footer>
<asc-button type="danger" @click="_isView = false" rounded>Close</asc-button>
<asc-button type="primary" rounded>Save</asc-button>
</template>
</asc-dialog>
</template>
<style scoped>
.app-container {
height : 100vh;
display : grid ;
place-content : center ;
}
.row {
display : flex;
gap : 10px;
margin-top: 10px;
}
.col {
flex : 1;
}
</style>
slot
<template>
<asc-dialog>
<template #header>
<!-- custome here! -->
</template>
<template #default>
<!-- custome here! -->
</template>
<template #footer>
<!-- custome here! -->
</template>
</asc-dialog>
</template>
Pagination
showSelectPage align : left | right | center
<script setup lang="ts">
import { AscPagination,type Pagination} from "@horleng/awesome-components"
import {ref} from "vue"
const page = ref<Pagination>({pageCount:10,pageActive:5});
</script>
<template>
<div class="app-container">
{{ page }}
<asc-pagination v-model="page" show-select-page/>
</div>
</template>
<style scoped>
.app-container {
height : 100vh ;
display : grid;
place-content : center ;
}
</style>
table
fields : TableField[] showGridLines : boolean tableMinWidth : number tableHeight : number paginator : boolean loading : boolean rows : number totalRecord : number paginationAlign : 'center' | 'left' | 'right' serverSideRender : boolean expander : boolean selectRows : boolean
simple table
<script setup lang="ts">
import {AscTable,type TableField} from "@horleng/awesome-components";
import {ref,onMounted} from "vue"
import axios,{type AxiosResponse} from "axios"
const users = ref([]);
const loading = ref(false);
onMounted(async()=>{
loading.value = true
const res = (await axios.get("https://dummyjson.com/users?limit=20") as AxiosResponse).data
users.value = res?.users ?? []
loading.value = false
})
const fields = ref<TableField[]>([
{label:"No",index:true},
{key:'id',label:"ID"},
{key:'firstName',label:"First Name",sortTable:true,fieldType:"string"},
{key:'age',label:"Age"},
{key:'phone',label:"Phone"} ,
{key:'email',label:"Email"},
])
</script>
<template>
<div class="app-container">
<asc-table :data="users" :fields="fields" :loading="loading"/>
</div>
</template>
<style>
.app-container {
padding: 100px;
}
</style>
Pagination
<script setup lang="ts">
import { AscTable,AscButton} from "@horleng/awesome-components"
import type {TableField,SortDetail,Pagination} from "@horleng/awesome-components"
import axios,{type AxiosResponse} from "axios"
import {onMounted, ref} from "vue"
const users = ref([]);
const loading = ref(false);
const totalUsers = ref();
const fields = ref<TableField[]>([
{key:'id',label:"ID"},
{key:'firstName',label:"Name"},
{key:'gender',label:"Gender"},
{key:'phone',label:"Phone"},
{key:'email',label:"Email"},
{key:'birthDate',label:"Birthday",sortTable:true,fieldType:'date'},
{key:'custom',label:"Actions"},
])
//export type fieldType = string | number | bool | date
// export interface TableField {
// key? : string ,
// label? : string ,
// sortTable? : Boolean ,
// fieldType? : FieldType ,
// index ? : boolean
// }
onMounted(async()=>{
loading.value= true
const res = (await axios.get('https://dummyjson.com/users?limit=100') as AxiosResponse)?.data
users.value = res?.users ?? [];
totalUsers.value = res?.total ?? 0 ;
loading.value= false
})
</script>
<template>
<div class="app-container">
<asc-table
:fields="fields"
:data="users"
:loading="loading"
:total-record="totalUsers"
:rows="10"
paginator
expander
>
<template #col(birthday)="{value}">
{{ new Date(value?.birthDate)?.toDateString() }}
</template>
<template #col(custom)="{value}">
<asc-button type="danger" size="small" @click="handleDelete(value)">Delete</asc-button>
<asc-button type="primary" size="small" @click="handleUpdate(value)" >Edit</asc-button>
</template>
<template #expander={value} >
<!-- custom here ! -->
</template>
</asc-table>
</div>
</template>
<style scoped>
.app-container {
padding: 100px;
}
</style>
service side render
<script setup lang="ts">
import { AscTable,AscButton} from "@horleng/awesome-components"
import type {TableField,SortDetail,Pagination} from "@horleng/awesome-components"
import axios,{type AxiosResponse} from "axios"
import {onMounted, ref} from "vue"
const users = ref([]);
const loading = ref(false);
const totalUsers = ref();
const fields = ref<TableField[]>([
{key:'id',label:"ID"},
{key:'firstName',label:"Name"},
{key:'gender',label:"Gender"},
{key:'phone',label:"Phone"},
{key:'email',label:"Email"},
{key:'birthDate',label:"Birthday",sortTable:true,fieldType:'date'},
{key:'custom',label:"Actions"},
])
//export type fieldType = string | number | bool | date
// export interface TableField {
// key? : string ,
// label? : string ,
// sortTable? : Boolean ,
// fieldType? : FieldType ,
// index ? : boolean
// }
onMounted(async()=>{
loading.value= true
const res = (await axios.get('https://dummyjson.com/users?limit=5') as AxiosResponse)?.data
users.value = res?.users ?? [];
totalUsers.value = res?.total ?? 0 ;
loading.value= false
})
const handleSort = (e:SortDetail[])=>{
console.log(e);
}
const handlePage = async(page:Pagination)=>{
loading.value = true
const res = (await axios.get(`https://dummyjson.com/users?limit=5&&skip=${(page.pageActive-1)*page.rows}`) as AxiosResponse)?.data
users.value = res?.users ?? [];
totalUsers.value = res?.total ?? 0 ;
loading.value = false
}
const handleDelete = (row:any)=>{
console.log(row);
}
const handleUpdate = (row:any)=>{
console.log(row);
}
const myMethod = (rowsSelect:Array<any>)=>{
console.log(rowsSelect);
}
</script>
<template>
<div class="app-container">
<asc-table
:fields="fields"
:data="users"
:loading="loading"
:total-record="totalUsers"
:rows="5"
paginator
server-side-render
select-rows
@on-sort="handleSort"
@on-change-page="handlePage"
@on-rows-select="myMethod"
>
<template #col(birthday)="{value}">
{{ new Date(value?.birthDate)?.toDateString() }}
</template>
<template #col(custom)="{value}">
<asc-button type="danger" size="small" @click="handleDelete(value)">Delete</asc-button>
<asc-button type="primary" size="small" @click="handleUpdate(value)" >Edit</asc-button>
</template>
</asc-table>
</div>
</template>
<style scoped>
.app-container {
padding: 100px;
}
</style>
noted : if you want to make server side rener you need to pass props as serverSideRender slot
<asc-table>
<template #col(your_key)="{value}">
<!-- custome here! -->
</template>
<template #header>
<!-- custome here! -->
</template>
<template #footer>
<!-- custome here! -->
</template>
<!-- or -->
<template #footerItem>
<!-- cutome here! -->
</template>
<template #pagination>
<!-- cutome here! -->
</template>
</asc-table>
Dropdown
options : array label : string size : 'small' | 'meduim' | 'large' placeholder : string optionMaxHeight : number
<script setup lang="ts">
import { AscDropdown} from "@horleng/awesome-components"
import {ref} from "vue"
const options = ref([
{id:1,department:'Web Application'},
{id:2,department:'Mobille Application'},
{id:3,department:'UX/UI Designer'},
{id:4,department:'Core Banking'},
{id:5,department:'Human Resource'},
{id:6,department:'DevOpps'},
])
const option = ref<any>(null);
</script>
<template>
<div class="app-container">
<div>
{{ option }}
<asc-dropdown
:options="options"
label="department"
placeholder="select a department"
v-model="option"
>
</asc-dropdown>
</div>
</div>
</template>
<style>
.app-container {
display: grid;
height : 100vh;
place-content : center;
}
</style>
slote
<asc-dropdown
:options="options"
label="department"
placeholder="select a department"
v-model="option"
>
<template #default={value}>
<!-- custome value here -->
</template>
<template #option={value}>
<!-- custome option's value here -->
</template>
</asc-dropdown>
Global Loading
<script setup lang="ts">
import {AscGlobalLoading} from "@horleng/awesome-components";
</script>
<template>
<asc-global-loading :loading="true"/>
</template>
Contact me
if my component have any issue , please let me know thank!.
thank you for watching my package!