npm package: @horleng/awesome-components
Description: ```bash npm install @horleng/awesome-components --save ``` ## style inside main.ts ```ts import "@horleng/awesome-components/dist/style.css" ```
Latest version: 1.0.0
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

## Installation

```bash
npm install @horleng/awesome-components --save
```
## style
inside main.ts
```ts
import "@horleng/awesome-components/dist/style.css"
```

### ripple effect
inside *main.ts*

```ts
import {rippleEffect} from '@horleng/awesome-components'

// vue directive
app.directive('ripple',rippleEffect)

```
###### usage
```html
<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 <br>
type : default | primary | secondary | danger | warning <br>
icon : component <br>
rounded : boolean <br>
circle : boolean <br>
loading : boolean <br>
disabled : boolean <br>
iconAlignRight : boolean <br>
autoFocus : boolean <br>
text : boolean <br>
```html
<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** 
```html
<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 <br>
size : small | meduim | large <br>

```html
<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 <br>
circle : boolean <br>
id : string <br>
inputError : boolean <br>
disabled : boolean <br>

```html
<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 <br>
placeholder : string <br>
disabled : boolean <br>
label : string <br>
inputType : text | password <br>
inputSize : small | meduim | large <br>
inputError : boolean <br>
iconLeft : component <br>
iconRight : component <br>
```html
<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** 
```html
<template>
  <asc-input-border-bottom>
    <template #inputIcon>
      <!-- custome here! -->
    </template>
  </asc-input-border-bottom>
</template>
```


### Dialog
width : number, specific width of dialog component <br>
modal : boolean <br>
title : string , title of dialog <br>
showClose : boolean , show button close at header of dialog <br>
outTargetClose : boolean , close when click overlay <br>
rounded : boolean <br>
animate : zoom-in | fade-down <br>

```html
<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** 
```html
<template>
  <asc-dialog>
    <template #header>
      <!-- custome here! -->
    </template>
    <template #default>
      <!-- custome here! -->
    </template>
    <template #footer>
      <!-- custome here! -->
    </template>
  </asc-dialog>
</template>

```

### Pagination
showSelectPage   <br>
align : left | right | center  <br>

```html
<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[]<br>
showGridLines : boolean  <br>
tableMinWidth : number  <br>
tableHeight : number  <br>
paginator : boolean<br>
loading : boolean  <br>
rows : number<br>
totalRecord : number  <br>
paginationAlign : 'center' | 'left' | 'right'  <br>
serverSideRender : boolean  <br>
expander : boolean <br>
selectRows : boolean <br>

***simple table***
```html

<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***

```html
<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***

```html

<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*<br>
**slot** 
```html
<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 <br>
label : string <br>
size : 'small' | 'meduim' | 'large' <br>
placeholder : string <br>
optionMaxHeight : number

```html
<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** 
```html
<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

```html
<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!. 
* [website](https://horlengg.vercel.app)
* [facebook](https://web.facebook.com/horlengg) 
* [telegram](https://t.me/ly_horleng) 
* [github](https://github.com/horlengg) 

*thank you for watching my package!*