1.0.6 • Published 11 months ago

gamon-vue v1.0.6

Weekly downloads
-
License
MIT
Repository
github
Last release
11 months ago

gamon-vue

gamon-vue is a highly customizable Vue 3 UI component library to make life easier for vue developers.

including components like:

some built in features (functions) like:

and directives like:

  • v-long-click => a directive to detect holding click (long click)
  • v-custom-click => a directive to detect both long and normal click together

installation

it's so simple to add gamon-vue to your project

npm i gamon-vue

usage

import { createApp } from 'vue'
import App from './App.vue'
import gamonVue from 'gamon-vue'

const app = createApp(App)
app.use(gamonVue)
app.mount('#app')

that's IT, done. you can use all gamon-vue components now.

Enjoy :)

Components

Button

<Buttton text="simple button" />

<Buttton> simple button </Button>

 /**
  *  ====== PROPS ======
  * 
  * text: string => text to be shown inside button
  * 
  * type?: 'submit' | 'reset' | 'button' => default is button
  * 
  * width?: number|string => width of the button. 
  *   e.g.
  *     <Button text="btn" width="100px" />
  *     <Button text="btn" :width="100" />
  *  
  * height?: number|string => height of the button
  *  e.g.
  *     <Button text="btn" height="50px" />
  *     <Button text="btn" :height="50" />
  * 
  * size?: 'small' | 'medium' | 'large'
  * 
  * loading?: boolean => if true, a loading animation will be shown inside button
  * 
  * loadingEffect?: 'simple' | 'default' => effect of loading animation
  * 
  * loadingType?: refer to Loading component "type" prop
  * 
  * loadingClassPrefix?: string => a class prefix for loading animation 
  *    (to customize animation)
  * 
  * widthParent?: boolean => button will adjust to parent width (responsive)
  * 
  * rounded?: boolean => button will apear rounded
  * 
  * outline?: boolean => button will apear outlined
  * 
  * disabled?: boolean
  * 
  * textClass?: string => class of the text
  * 
  * textStyle?: string | { [index: string]: string } => css style of the text
  * 
  */

Carousel

const indexOfVisibleSlide = ref(0)

<Carousel v-model="indexOfVisibleSlide">
  <img src="img1.jpg" />
  <img src="img2.jpg" />
  <img src="img3.jpg" />
</Carousel>

 /**
  * 
  *  ====== PROPS ======
  *   v-model?: number => index of visible slide
  * 
  *   itemsPerView?: number => how many items should be shown in each slide
  * 
  *   itemsPerSlide?: number => how many items should slide on slide
  * 
  *   eachItemMargin?: number => margin between items
  * 
  *   eachItemHeight?: number => height of each item
  * 
  *   auto?: boolean => if true, Carousel will slide automatically
  * 
  *   duration?: number => duration of auto slide in seconds
  * 
  *   stopAtEnd?: boolean => stop sliding at the last slide
  * 
  *   noIndicator?: boolean => slide indicators will not show
  *
  *   responsive?: {[index:number]:number} => responsive slides.
  *       e.g.
  *         <Carousel :responsive="{1000:5, 600:4, 400:2}">
            </Carousel>
  *     
  * 
  */

Grid

<Row>
  <Col width="xl-4 lg-6 md-8 sm-10 xs-12"> Col 1 </Col>
  <Col width="xl-4 lg-6 md-8 sm-10 xs-12"> Col 2 </Col>
  <Col width="xl-4 lg-6 md-8 sm-10 xs-12"> Col 3 </Col>
</Row>
 /**
  *   each Row can be divided into 12 sections
  *   xl-4 means the Col will take 4 sections in xl screen
  *   lg-6 means the Col will take 6 sections in lg screen
  *   md-8 means the Col will take 8 sections in md screen
  *   sm-10 means the Col will take 10 sections in sm screen
  *   xs-12 means the Col will take 12 sections in xs screen
  * 
  *  ====== PROPS ======
  *   width: string
  *  
  * 
  */

InputBasic

const inpModel = ref()

<InputBasic v-model="inpModel" />
/**
 *  ====== PROPS ======
 * 
 *  title?: string => title of the input
 * 
 *  placeholder?: string => placeholder of the input
 * 
 *  readonly?: boolean => input will be readonly
 * 
 *  focus?: boolean => if true, input will be focused
 * 
 *  delay?: boolean | number => if number value (in ms) provided, model will be 
  *     updated according to that delay, if number is not provided, the 
  *     default delay will be 500 ms  
 * 
 *  type?:  "text" | "number" | "tel" | "email" | "password"
 * 
 *  icon?: string => address of an image to show as icon at the start of input
 * 
 *  passwordVisibilityToggler?: boolean => displays a password visibility toggler
 *    icon for password input
 * 
 * 
 */

InputFile

const inpModel = ref()

<InputFile v-model="inpModel" />


/**
 * ====== PROPS ======
 * 
 *  title?: string => title of the input
 * 
 *  placeholder?: string => placeholder of the input
 * 
 *  icon?: string => address of an image to show as icon at the start of input
 * 
 *  accept?: string => the accept attribute of html file input 
 * 
 *  video?: boolean => input will only accept video files 
 * 
 *  audio?: boolean => input will only accept audio files 
 * 
 *  image?: boolean => input will only accept image files 
 * 
 *  preview?: boolean => input will show a preview of the selected file
 * 
 *   multi?: boolean => select multiple files
 * 
 *   maxSize?: number => max size of the selected file
 * 
 *   dragDrop?: boolean => input will select files by drag and drop
 * 
 *   cropper?: boolean => user can crop selected images
 * 
 *   previewSize?: {
         width ?:number|string,
         height ?:number|string,
         maxWidth ?:number|string,
         maxHeight ?:number|string,
     } => size of the preview
   
     e.g. 
   
     :previewSize = {
       width: 250,
       height: 250,
     }
 * 
 *  
 */

InputDate

const inpModel = ref()

<InputDate v-model="inpModel" />

/**
 * props:
 * 
 *  title?: string => title of the input
 * 
 *  placeholder?: string => placeholder of the input
 * 
 *  icon?: string => address of an image to show as icon at the start of input
 *  
 * 
 *  format?: string => format of the input and output
 *    not: allowed seperators are "/" and "-"
 *    e.g.
 *    format="yyyy/mm/dd" or format="yyyy/mm"
 *    format="yyyy-mm-dd"
 * 
 * timepicker?: boolean => user can select time
 * 
 * timepickerHourType?: string => either 12 or 24
 * 
 * defaultToday?: boolean => if true, default value will be today
 * 
 */

InputSelect

const inpModel = ref()

<InputSelect v-model="inpModel" :options="[ [1, 'one'], [2, 'two'] ]" />

/**
 * props:
 * 
 *  options: (number|string)[][] => select options
 *    e.g.
 *    :options="[ 
 *      ['option 1 value', 'option 1 text '],
 *      ['option 2 value', 'option 2 text '],
 *    ]" 
 * 
 *  title?: string => title of the input
 * 
 *  placeholder?: string => placeholder of the input
 * 
 *  icon?: string => address of an image to show as icon at the start of input
 *  
 *  multi?: boolean => user can select multiple options 
 *  
 *  displayType?: 'dropdown' | 'sheet-bottom' | 'sheet-center'
 */

InputTextarea

const inpModel = ref()

<InputTextarea v-model="inpModel"  />

/**
 * props:
 * 
 *  title?: string => title of the input
 * 
 *  placeholder?: string => placeholder of the input
 * 
 *  icon?: string => address of an image to show as icon at the start of input
 * 
 *  readonly?: boolean => input will be readonly
 * 
 *  focus?: boolean => if true, input will be focused
 * 
 *  cols?: number => cols attribute of html textarea
 * 
 *  rows?: number => rows attribute of html textarea
 * 
 */

InputCheckbox

const inpModel = ref()

<InputCheckbox v-model="inpModel" title="simple checkbox" value="foo" />

/**
 * props:
 * 
 * title: string => title of the checkbox
 * 
 * value: string|number => value of the checkbox
 * 
 * name?: string => name of the checkbox html input
 * 
 * binary?: boolean => if true, if the checkbox is selected value will be 1 and if not selected value will be 0
 * 
 * checkmarkStyle?: string | { [index: string]: string } => css style of the checkmark
 * 
 * titleStyle?: string | { [index: string]: string } => css style of the checkbox title
 * 
 * checkmarkClass?: string => class of checkmark
 * 
 * titleClass?: string => class of checkbox title
 * 
 */

InputToggle

const inpModel = ref()

<InputToggle v-model="inpModel" :default-value="[1, 'one']" :active-value="[2, 'two']"  />

/**
 * props:
 * 
 * defaultValue: [default value, text to display]
 * 
 * activeValue: [selected value, text to display]
 * 
 * rectangle?: boolean => input will be a rectangle
 * 
 * togglerStyle?: string | { [index: string]: string } => css style for toggler 
 * 
 * pointerStyle?: string | { [index: string]: string } => css style for toggler pointer 
 * 
 * activeValueStyle?: string | { [index: string]: string } => css style for active value text 
 * 
 * defaultValueStyle?: string | { [index: string]: string } => css style for default value text 
 * 
 * defaultValueClass?: string => class for default value text 
 * 
 * activeValueClass?: string => class for active value text 
 * 
 * pointerClass?: string => class for toggler pointer 
 * 
 * togglerClass?: string => class for toggler input 
 * 
 */

InputRadio

const inpModel = ref()

<InputRadio v-model="inpModel" title="simple checkbox" value="foo" />

/**
 * props:
 * 
 * title: string => title of the radio input
 * 
 * value: string|number => value of the radio input
 * 
 * name?: string => name of the radio input html input
 *  
 * checkmarkStyle?:  string | { [index: string]: string }  => css style of the checkmark
 * 
 * titleStyle?:  string | { [index: string]: string } => css style of the title
 * 
 * checkmarkClass?: string => class of checkmark
 * 
 * titleClass?: string => class of title
 * 
 */

InputRange

const inpModel = ref()

<InputRange v-model="inpModel"  />

/**
 * props:
 * 
 * min?: number
 * 
 * max?: number
 * 
 * step?: number
 * 
 * double?: boolean
 * 
 * outputDisplay?: 'none' | 'up'
 * 
 */

Loading

<Loading type="wave" />

/**
 * props:
 * 
 *  type?: 'dual-ring' | 'bouncing-balls' | 'cradle' | 'wave'
 * 
 *  classPrefix?: string => class prefix for loading component
 * 
 *  fullScreen?: boolean => loading will be full screen
 * 
 *  width?: string|number => width of the loading
 * 
 *  height?: string|number => height of the loading
 * 
 */

Picker

const inpModel = ref()

// method 1
<Picker v-model="inpModel" :options="[1,2,3,4]" />

// method 2
<Picker v-model="inpModel">
  <div> 1 </div>
  <div> 2 </div>
  <div> 3 </div>
</Picker>

// you can put any element inside the Picker, just remember that all element must be the same.

/**
 *  by default picker will update the model value (inpModel) with the index of
 *    the selected option. to get the value, you can use "getValue" prop
 * 
 * props:
 * 
 * options: (string|number)[] => options for picking
 *    e.g.
 *      <Picker :options="[1,2,3,4]" />
 *     
 * 
 * stopAtEnd?: boolean => stop at the last option
 * 
 * horizontal?: boolean => if true, picker will be horizontal
 * 
 * noSelectedFrame?: boolean => if true, selected frame will not be shown
 * 
 * startCenter?: boolean => if true, default selected value will be the middle 
 * (center) value
 * 
 * arrow?: boolean => if true, directional arrows will be shown
 * 
 * optionSize?: number => height for vertical , width for horizontal
 *    e.g. <Picker :options="[1,2,3,4]" :optionSize="50" />
 *    -- each option will have 50px height
 * 
 * height?: number => height of the picker
 * 
 * getValue?: boolean => if true, modelValue will be updated with the selected
 *    value instead of selected index. this prop works even with method 2.
 * 
 * selectedFrameClass?: string => class of the selected frame
 * 
 * optionClass?: string => class applied to each option
 * 
 * selectedFrameStyle?: string |  { [index: string]: string } => css style for selected frame
 * 
 * optionStyle?: string |  { [index: string]: string } => css style for each option
 * 
 */

Progressbar

<Progressbar :value="40" />

/**
 * props:
 * 
 * value: number => progress value in % e.g.(40)
 * 
 * text?: string => text to be shown beside the value
 * 
 * hideValue?: boolean => if true, value will not be shown
 * 
 * animation?: 'flash' | 'flow' 
 * 
 * progressColor?: string => color of the progress
 * 
 * flowParticleColor?: string => color of the flow animation particles
 * 
 * flasherColor?: string => color of the flash animation band
 * 
 * bgColor?: string => progressbar background color
 * 
 * textColor?: string => color of the text
 * 
 * textFontSize?: string => font size of text
 * 
 * progressStyle?: string | { [index: string]: string } => css style of progress
 * 
 * textStyle?: string | { [index: string]: string } => css style of text
 * 
 * flowParticleStyle?: string | { [index: string]: string } => css style of flow animation particles
 * 
 * flasherStyle?: string | { [index: string]: string } => css style of flasher animation band
 * 
 * progressClass?: string => class of progress
 * 
 * textClass?: string => class of text
 * 
 * flowParticleClass?: string => class of flow animation particles
 * 
 * flasherClass?: string => class of flasher animation band
 * 
 * 
 */

Sheet

// method 1: toggle the sheet using id
<Button text="toggle sheet" gamon-sheet-toggle="aUniqueId" />

<Sheet id="aUniqueId" title="a simple sheet" >
  <div>this is a simple sheet</div>
</Sheet>


// method 2: toggle the sheet using "v-model:display" model
// setting "sheetDisplay" to true will display the sheet
const sheetDisplay = ref(false)

<Sheet id="aUniqueId" title="a simple sheet" v-model:display="sheetDisplay" >
  <div>this is a simple sheet</div>
</Sheet>


/**
 * props:
 * 
 * id: string => unique ID of the sheet
 * 
 * type?: 'center' | 'bottom' | 'top' | 'left' | 'right' 
 * 
 * title?: string => title of the sheet(will be shown in sheet header)
 * 
 * width?: string|number => width of the sheet (responsive)
 * 
 * height?: string|number => height of the sheet
 * 
 * minHeight?: string|number => min height of the sheet
 * 
 * animation?: ToggleAnimation => e.g. animation="scale"
 * 
 * v-model:display?: boolean => with this prop, you can manually toggle the visibility of the sheet 
 * 
 * onDismiss?: function => callback function on sheet dismiss
 * 
 * onDisplay?: function => callback function on sheet display
 * 
 * onBackdropClick?: function => callback function on backdrop click
 * 
 * dismissDisabled?: boolean => sheet will not have a backdrop
 * 
 * bodyStyle?: string | { [index: string]: string } => css style of the sheet body
 * 
 * backdropStyle?: string | { [index: string]: string } => css style of the sheet backdrop
 * 
 * 
 */

you can set a global animation for all of your sheets, in plugin options in main.js:

const app = createApp(Demo)
app.use(gamonVue, {
  sheet: {
    animation: 'rotate'
  }
})
app.mount('#app')

TabBar

const selectedTab = ref()

// method 1 : selectedTab would be the index of the selected tab
<TabBar v-model="selectedTab" :tabs="[ 'tab 1', 'tab 2', 'tab 3'  ]" />

// method 2 : selectedTab would be the value of the selected tab
<TabBar v-model="selectedTab" :tabs="[  ['value 1', 'tab 1'], ['value 2','tab 2'] ]" />


/**
 * props:
 * 
 *  tabs: string[] | (string|number)[][]
 * 
 *  position?: 'default' | 'fixed-bottom' | 'fixed-top'
 * 
 *  indicatorType?: 'none' | 'box' | 'line-top' | 'line-bottom'
 * 
 *  width?: string|number
 * 
 *  responsiveWidth?: string => same as Col width 
 *    e.g. responsiveWidth="lg-5 md-8"
 *  
 *  bgColor?: string => background color of tabbar
 * 
 *  tabStyle?: string | { [index: string]: string } => css style of each tab
 * 
 *  tabClass?: string => class of each tab
 * 
 *  tabColor?: string => color of each tab
 * 
 *  indicatorStyle?: string | { [index: string]: string } => css style of active tab indicator
 * 
 *  indicatorClass?: string => class of of active tab indicator
 * 
 *  indicatorColor?: string => color of active tab indicator
 * 
 *  activeTabStyle?: string | { [index: string]: string } => css style of active tab
 * 
 *  activeTabClass?: string => class of active tab
 * 
 *  activeTabColor?: string => color of active tab
 * 
 */

Stepper

const stepperValue = ref()

// method 1 : selectedTab would be the index of the selected tab
<Stepper v-model="stepperValue"  />


/**
 * props:
 * 
 *  min?: number => min stepper value
 * 
 *  max?: number => max stepper value
 * 
 *  editable?: boolean => stepper is manually editable
 * 
 *  vertical?: boolean => stepper is vertical
 * 
 *  chevron?: boolean => display chevron icon instead of plus and minus
 *  
 *  width?: string|number => width of the stepper
 * 
 *  height?: string|number => height of the stepper
 * 
 *  incStyle?: string | { [index: string]: string } => css style of increase btn
 * 
 *  decStyle?: string | { [index: string]: string } => css style of decrease btn
 * 
 *  numberStyle?: string | { [index: string]: string } => css style of number
 *  
 *  incClass?: string => class of increase btn
 * 
 *  decClass?: string => class of decrease btn
 * 
 *  numberClass?: string => class of number
 * 
 */

Methods

gamon-vue has some amazing built in methods to help developers

just import Gamon from gamon-vue and you can use them

import {Gamon} from 'gamon-vue'

confirm

  import {Gamon} from 'gamon-vue'

  const deleteItem = ()=>{
    Gamon.confirm(
      'confirmation title', 
      'confirmation text',
      ()=>{
        console.log('user confirmed')
      }
    )
  }


  <Button text="Delete" @click="deleteItem" />


/**
 *  Gamon.confirm(title, text, confirmCallback, cancelCallback?, animation?, confirmButtonText?, cancelButtonText?)
 * 
 *  title: string => title of the confirmation 
 * 
 *  text: string => text of the confirmation 
 * 
 *  confirmCallback: function => confirmed callback 
 * 
 *  cancelCallback?: function => not confirmed callback 
 * 
 *  animation?: ToggleAnimation => e.g. animation="scale"
 * 
 *  type?: string => type of confirmation sheet (refer to Sheet component "type" prop)
 *  
 *  confirmButtonText?: string
 * 
 *  cancelButtonText?: string
 * 
 */

you can set a global config for all of your confirms, in plugin options in main.js:

const app = createApp(Demo)
app.use(gamonVue, {
  confirm: {
    confirmButtonText ?: string, // e.g. confirmButtonText: 'I agree'
    cancelButtonText ?: string, // e.g. cancelButtonText: 'No'
    animation ?: ToggleAnimations, // e.g. animation: 'scale'
    type ?: SheetTypes, //  e.g. type: 'bottom' (refer to Sheet "type" prop)
  },
})
app.mount('#app')

notify

  import {Gamon} from 'gamon-vue'

  const showNotif = ()=>{
    Gamon.notify('this is a simple notififcation')
  }



  <Button text="Show notif" @click="showNotif" />


/**
 *  Gamon.notify(text, type, duration, animation)
 * 
 *  text: string => notification text
 * 
 *  type: 'success' | 'error' | ''
 * 
 *  duration?: number => notification display diration in ms e.g. (3000) which is 3s
 * 
 *  animation?: ToggleAnimation => e.g. animation="scale"
 * 
 */

you can set a global config for all of your notifies, in plugin options in main.js:

const app = createApp(Demo)
app.use(gamonVue, {
  notify: {
    position?:'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' | 'center' ,
    animation?: ToggleAnimations,  // e.g. animation: 'scale'
    duration?:number, // e.g. duration : 4000
  },
})
app.mount('#app')

sheetToggle

toggle a Sheet with sheetToggle method

  import {Gamon} from 'gamon-vue'

  const toggleSheet = ()=>{
    Gamon.sheetToggle('simpleSheetId')
  }



  <Button text="toggle sheet" @click="toggleSheet" />

  <Sheet id="simpleSheetId">
    this is a simple sheet
  </Sheet>

/**
 *  Gamon.sheetToggle(id)
 * 
 *  id: string => unique ID of the sheet
 * 
 */

ToggleAnimation

type ToggleAnimations = 'slide-up'|'slide-down'|'slide-left'|'slide-right'|'fade'|'scale'|'rotate'

Directives

v-long-click

  // function will be called on long click
  const longClickDetected = (e: MouseEvent|TouchEvent)=>{
    console.log('long click detected')
  }



  <Button text="long click" v-long-click="longClickDetected" />

  
/**
 *  default hold time is 1000 ms (1 s)
 * 
 *  you can change this by =>
 *  
 *  <Button text="long click" v-long-click:3000="longClickDetected" />
 * 
 *  now, hold time is 3000 ms (3 s)
 * 
 */

v-custom-click

if you need both click and long click detection on one element. you can use this directive

  // function will be called on click
  const clickCallback = (e: MouseEvent|TouchEvent)=>{
    console.log('click detected')
  }

  // function will be called on long click
  const longClickCallback = (e: MouseEvent|TouchEvent)=>{
    console.log('long click detected')
  }



  <Button text="long click" v-custom-click="
    {
      click_callback: clickCallback,
      long_click_callback: longClickCallback,
      long_click_duration: 2000
    }
  " />