Component improvement & adjustments

This commit is contained in:
cristij 2018-10-07 22:32:30 +03:00
parent a6421f4a51
commit 69f7d9a8e8
17 changed files with 334 additions and 105 deletions

View File

@ -19,7 +19,7 @@
import { FadeTransition } from 'vue2-transitions';
export default {
name: 'alert',
name: 'base-alert',
components: {
FadeTransition
},

View File

@ -1,18 +1,20 @@
<template>
<component
:is="tag"
:type="nativeType"
:type="tag === 'button' ? nativeType : ''"
:disabled="disabled || loading"
@click="handleClick"
class="btn"
:class="[
{'btn-round': round},
{'btn-block': block},
{'btn-icon': icon},
{'btn-icon btn-fab': icon},
{[`btn-${type}`]: type && !outline},
{[`btn-outline-${type}`]: type && outline},
{[`btn-${size}`]: size},
{'btn-link': simple}
{'btn-simple': simple},
{'btn-link': link},
{'disabled': disabled && tag !== 'button'}
]">
<slot name="loading">
<i v-if="loading" class="fa fa-spinner fa-spin"></i>
@ -46,7 +48,8 @@ export default {
type: String,
default: ""
},
simple: Boolean
simple: Boolean,
link: Boolean,
},
methods: {
handleClick(evt) {

View File

@ -16,9 +16,9 @@
</template>
<script>
export default {
name: 'base-checkbox',
name: "base-checkbox",
model: {
prop: 'checked'
prop: "checked"
},
props: {
checked: [Array, Boolean],

View File

@ -4,17 +4,19 @@
:class="{show:isOpen}"
@click="toggleDropDown"
v-click-outside="closeDropDown">
<a class="dropdown-toggle btn-rotate"
<slot name="title-container" :is-open="isOpen">
<component
:is="titleTag"
class="dropdown-toggle btn-rotate"
:class="titleClasses"
:aria-expanded="isOpen"
data-toggle="dropdown">
<slot name="title">
<slot name="title" :is-open="isOpen">
<i :class="icon"></i>
<span class="notification">{{title}}
<b class="caret"></b>
</span>
{{title}}
</slot>
</component>
</slot>
</a>
<ul class="dropdown-menu" :class="[{show:isOpen}, {'dropdown-menu-right': menuOnRight}, menuClasses]">
<slot></slot>
</ul>
@ -22,11 +24,15 @@
</template>
<script>
export default {
name: 'base-dropdown',
name: "base-dropdown",
props: {
tag: {
type: String,
default: "li"
default: "div"
},
titleTag: {
type: String,
default: "button"
},
title: String,
icon: String,

97
src/components/BaseNav.vue Executable file
View File

@ -0,0 +1,97 @@
<template>
<nav class="navbar"
:class="[
{'navbar-expand-lg': expand},
{[`navbar-${effect}`]: effect},
{'navbar-transparent': transparent},
{[`bg-${type}`]: type},
{'rounded': round}
]">
<div class="container">
<slot name="container-pre"></slot>
<slot name="brand">
<a class="navbar-brand" href="#" @click.prevent="onTitleClick">
{{title}}
</a>
</slot>
<navbar-toggle-button :toggled="toggled"
:target="contentId"
@click.native.stop="toggled = !toggled">
</navbar-toggle-button>
<slot name="container-after"></slot>
<div class="collapse navbar-collapse" :class="{show: toggled}" :id="contentId" v-click-outside="closeMenu">
<div class="navbar-collapse-header">
<slot name="content-header" :close-menu="closeMenu"></slot>
</div>
<slot :close-menu="closeMenu"></slot>
</div>
</div>
</nav>
</template>
<script>
import { FadeTransition } from "vue2-transitions";
import NavbarToggleButton from "./NavbarToggleButton";
export default {
name: "base-nav",
components: {
FadeTransition,
NavbarToggleButton
},
props: {
type: {
type: String,
default: "primary",
description: "Navbar type (e.g default, primary etc)"
},
title: {
type: String,
default: "",
description: "Title of navbar"
},
contentId: {
type: [String, Number],
default: Math.random().toString(),
description:
"Explicit id for the menu. By default it's a generated random number"
},
effect: {
type: String,
default: "dark",
description: "Effect of the navbar (light|dark)"
},
round: {
type: Boolean,
default: false,
description: "Whether nav has rounded corners"
},
transparent: {
type: Boolean,
default: false,
description: "Whether navbar is transparent"
},
expand: {
type: Boolean,
default: false,
description: "Whether navbar should contain `navbar-expand-lg` class"
}
},
data() {
return {
toggled: false
};
},
methods: {
onTitleClick(evt) {
this.$emit("title-click", evt);
},
closeMenu() {
this.toggled = false;
}
}
};
</script>
<style>
</style>

63
src/components/BaseRadio.vue Executable file
View File

@ -0,0 +1,63 @@
<template>
<div class="form-check form-check-radio" :class="[inlineClass, {disabled: disabled}]">
<label :for="cbId" class="form-check-label">
<input :id="cbId"
class="form-check-input"
type="radio"
:disabled="disabled"
:value="name"
v-model="model" />
<slot></slot>
<span class="form-check-sign"></span>
</label>
</div>
</template>
<script>
export default {
name: "base-radio",
props: {
name: {
type: [String, Number],
description: "Radio label"
},
disabled: {
type: Boolean,
description: "Whether radio is disabled"
},
value: {
type: [String, Boolean],
description: "Radio value"
},
inline: {
type: Boolean,
description: "Whether radio is inline"
}
},
data() {
return {
cbId: ""
};
},
computed: {
model: {
get() {
return this.value;
},
set(value) {
this.$emit("input", value);
}
},
inlineClass() {
if (this.inline) {
return `form-check-inline`;
}
return "";
}
},
created() {
this.cbId = Math.random()
.toString(16)
.slice(2);
}
};
</script>

View File

@ -1,11 +1,11 @@
<template>
<table class="table tablesorter" :class="tableClass">
<thead :class="theadClasses">
<slot name="columns">
<tr>
<slot name="columns">
<th v-for="column in columns" :key="column">{{column}}</th>
</tr>
</slot>
</tr>
</thead>
<tbody :class="tbodyClasses">
<tr v-for="(item, index) in data" :key="index">

View File

@ -12,6 +12,9 @@
<div class="card-body" v-if="$slots.default">
<slot></slot>
</div>
<div class="card-image" v-if="$slots['image-bottom']">
<slot name="image-bottom"></slot>
</div>
<slot name="raw-content"></slot>
<div class="card-footer" v-if="$slots.footer">
<slot name="footer"></slot>

34
src/components/CloseButton.vue Executable file
View File

@ -0,0 +1,34 @@
<template>
<button type="button" class="navbar-toggler"
data-toggle="collapse"
@click="handleClick"
:data-target="`#${target}`"
:aria-controls="target"
:aria-expanded="expanded"
aria-label="Toggle navigation">
<span></span>
<span></span>
</button>
</template>
<script>
export default {
name: "close-button",
props: {
target: {
type: [String, Number],
description: "Close button target element"
},
expanded: {
type: Boolean,
description: "Whether button is expanded (aria-expanded attribute)"
}
},
methods: {
handleClick(evt) {
this.$emit("click", evt);
}
}
};
</script>
<style>
</style>

View File

@ -1,5 +1,9 @@
<template>
<div class="form-group" :class="{'input-group': hasIcon}">
<div class="form-group"
:class="{
'input-group': hasIcon,
'input-group-focus': focused
}">
<slot name="label">
<label v-if="label" class="control-label">
{{label}}
@ -7,38 +11,71 @@
</slot>
<slot name="addonLeft">
<span v-if="addonLeftIcon" class="input-group-prepend">
<i :class="addonLeftIcon" class="input-group-text"></i>
<div class="input-group-text">
<i :class="addonLeftIcon"></i>
</div>
</span>
</slot>
<slot>
<input
:value="value"
@input="$emit('input',$event.target.value)"
v-bind="$attrs"
v-on="listeners"
class="form-control"
aria-describedby="addon-right addon-left">
</slot>
<slot name="addonRight">
<span v-if="addonRightIcon" class="input-group-append">
<i :class="addonRightIcon" class="input-group-text"></i>
<div class="input-group-text">
<i :class="addonRightIcon"></i>
</div>
</span>
</slot>
<slot name="helperText"></slot>
</div>
</template>
<script>
export default {
inheritAttrs: false,
name: "fg-input",
name: "base-input",
props: {
label: String,
value: [String, Number],
addonRightIcon: String,
addonLeftIcon: String
},
model: {
prop: 'value',
event: 'input'
},
data() {
return {
focused: false
}
},
computed: {
hasIcon() {
const { addonRight, addonLeft } = this.$slots;
return addonRight !== undefined || addonLeft !== undefined || this.addonRightIcon !== undefined || this.addonLeftIcon !== undefined;
},
listeners() {
return {
...this.$listeners,
input: this.onInput,
blur: this.onBlur,
focus: this.onFocus
}
}
},
methods: {
onInput(evt) {
this.$emit('input', evt.target.value)
},
onFocus() {
this.focused = true;
},
onBlur() {
this.focused = false;
}
}
}

View File

@ -0,0 +1,27 @@
<template>
<button class="navbar-toggler" type="button"
data-toggle="collapse"
:data-target="target"
:aria-controls="target"
:aria-expanded="toggled"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</template>
<script>
export default {
props: {
target: {
type: [String, Number],
description: "Button target element"
},
toggled: {
type: Boolean,
default: false,
description: "Whether button is toggled"
}
}
};
</script>
<style>
</style>

View File

@ -1,44 +0,0 @@
<template>
<div class="moving-arrow" :style="arrowStyle">
</div>
</template>
<script>
export default {
props: {
moveY: {
type: Number,
default: 0
}
},
computed: {
/**
* Styles to animate the arrow
* @returns {{transform: string}}
*/
arrowStyle() {
return {
transform: `translate3d(0px, ${this.moveY}px, 0px)`
};
}
}
};
</script>
<style lang="scss">
$bg-nude: #f4f3ef !default;
.moving-arrow {
border-right: 17px solid $bg-nude;
border-top: 17px solid transparent;
border-bottom: 17px solid transparent;
display: inline-block;
position: absolute;
left: 243px;
top: 95px;
transition: all 0.5s cubic-bezier(0.29, 1.42, 0.79, 1);
}
@media (max-width: 992px) {
.moving-arrow {
display: none;
}
}
</style>

View File

@ -33,14 +33,10 @@
</sidebar-link>
</slot>
</ul>
<moving-arrow :move-y="arrowMovePx">
</moving-arrow>
</div>
</div>
</template>
<script>
import MovingArrow from "./MovingArrow.vue";
import SidebarLink from "./SidebarLink";
export default {
@ -88,7 +84,6 @@
};
},
components: {
MovingArrow,
SidebarLink
},
computed: {

View File

@ -1,10 +1,14 @@
import FormGroupInput from "./Inputs/formGroupInput.vue";
import BaseInput from "./Inputs/BaseInput.vue";
import BaseCheckbox from "./BaseCheckbox.vue";
import BaseRadio from "./BaseRadio.vue";
import BaseDropdown from "./BaseDropdown.vue";
import BaseTable from "./BaseTable.vue";
import BaseButton from "./BaseButton";
import BaseAlert from "./BaseAlert";
import BaseNav from "./BaseNav";
import Modal from "./Modal";
import CloseButton from "./CloseButton";
import Card from "./Cards/Card.vue";
import StatsCard from "./Cards/StatsCard.vue";
@ -12,13 +16,17 @@ import StatsCard from "./Cards/StatsCard.vue";
import SidebarPlugin from "./SidebarPlugin/index";
export {
FormGroupInput,
BaseInput,
Card,
Modal,
CloseButton,
StatsCard,
BaseTable,
BaseCheckbox,
BaseRadio,
BaseDropdown,
BaseButton,
BaseAlert,
SidebarPlugin
SidebarPlugin,
BaseNav
};

View File

@ -41,7 +41,7 @@
:show-close="true">
<input slot="header" type="text" class="form-control" id="inlineFormInputGroup" placeholder="SEARCH">
</modal>
<base-dropdown class="nav-item" menu-on-right>
<base-dropdown tag="li" title-tag="a" class="nav-item" menu-on-right>
<a slot="title" href="#" class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="true">
<div class="notification d-none d-lg-block d-xl-block"></div>
<i class="tim-icons icon-sound-wave"></i>
@ -65,7 +65,7 @@
<a href="#" class="nav-item dropdown-item">Another one</a>
</li>
</base-dropdown>
<base-dropdown class="nav-item" menu-classes="dropdown-navbar">
<base-dropdown tag="li" title-tag="a" class="nav-item" menu-classes="dropdown-navbar">
<a slot="title" href="#" class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="true">
<div class="photo">
<img src="/img/anime3.png">

View File

@ -3,69 +3,69 @@
<h5 slot="header" class="title">Edit Profile</h5>
<div class="row">
<div class="col-md-5 pr-md-1">
<fg-input label="Company (disabled)"
<base-input label="Company (disabled)"
placeholder="Company"
v-model="model.company"
disabled>
</fg-input>
</base-input>
</div>
<div class="col-md-3 px-md-1">
<fg-input label="Username"
<base-input label="Username"
placeholder="Username"
v-model="model.username">
</fg-input>
</base-input>
</div>
<div class="col-md-4 pl-md-1">
<fg-input label="Email address"
<base-input label="Email address"
type="email"
placeholder="mike@email.com">
</fg-input>
</base-input>
</div>
</div>
<div class="row">
<div class="col-md-6 pr-md-1">
<fg-input label="First Name"
<base-input label="First Name"
v-model="model.firstName"
placeholder="First Name">
</fg-input>
</base-input>
</div>
<div class="col-md-6 pl-md-1">
<fg-input label="Last Name"
<base-input label="Last Name"
v-model="model.lastName"
placeholder="Last Name">
</fg-input>
</base-input>
</div>
</div>
<div class="row">
<div class="col-md-12">
<fg-input label="Address"
<base-input label="Address"
v-model="model.address"
placeholder="Home Address">
</fg-input>
</base-input>
</div>
</div>
<div class="row">
<div class="col-md-4 pr-md-1">
<fg-input label="City"
<base-input label="City"
v-model="model.city"
placeholder="City">
</fg-input>
</base-input>
</div>
<div class="col-md-4 px-md-1">
<fg-input label="Country"
<base-input label="Country"
v-model="model.country"
placeholder="Country">
</fg-input>
</base-input>
</div>
<div class="col-md-4 pl-md-1">
<fg-input label="Postal Code"
<base-input label="Postal Code"
placeholder="ZIP Code">
</fg-input>
</base-input>
</div>
</div>
<div class="row">
<div class="col-md-8">
<fg-input>
<base-input>
<label>About Me</label>
<textarea rows="4" cols="80"
class="form-control"
@ -73,7 +73,7 @@
v-model="model.about">
</textarea>
</fg-input>
</base-input>
</div>
</div>
<base-button slot="footer" type="primary" fill>Save</base-button>

View File

@ -1,11 +1,11 @@
import { FormGroupInput, Card, BaseDropdown, BaseButton, BaseCheckbox } from "../components/index";
import { BaseInput, Card, BaseDropdown, BaseButton, BaseCheckbox } from "../components/index";
/**
* You can register global components here and use them as a plugin in your main Vue instance
*/
const GlobalComponents = {
install(Vue) {
Vue.component(FormGroupInput.name, FormGroupInput);
Vue.component(BaseInput.name, BaseInput);
Vue.component(Card.name, Card);
Vue.component(BaseDropdown.name, BaseDropdown);
Vue.component(BaseButton.name, BaseButton);