My company uses an in-house component library that is hosted on our private npm repository. I attempted to import these components into storybook stories like so:
import vxButton from 'vix-ui/Components/Button/vxButton.vue';
export default {
title: 'Vix/Button',
component: vxButton,
argTypes: {},
};
const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { "vx-button" : vxButton },
template: '<vx-button v-bind="$props"></vx-button>',
});
export const Primary = Template.bind({});
Primary.args = {};
The button in this example loads successfully, however half of the props of the button are not displayed when running the storybook. The props that do not show up are the props that are part of the mixin' that the button component implements. Find the code of the imported button below:
<template>
<div class="vxButton vxComponentContainer vxBorderContainer vxFocusContainer"
:uid = "compId"
:controlType="controlType"
:tabindex = acceptFocus
:class="{
'vxButton--primary' : stylePreset=== 'primary',
'vxButton--secondary' : stylePreset=== 'secondary',
'vxButton--alt-light' : stylePreset=== 'alt-light',
'vxButton--alt-dark' : stylePreset === 'alt-dark',
'vxButton--hasIcon' : icon!=null,
'vxButton--disabled': !enabled,
'vxButton--opened' : toggled,
'vxBorderContainer--error': validationState === 'error',
'vxBorderContainer--success': validationState === 'success',
'vxBorderContainer--loading': validationState === 'loading'
}"
v-bind:style = "{width : width }"
@mousedown = _mousedown
@keyup.enter= _enterup
@keydown.enter= _enterDown>
<vx-validationicon
v-if="validationState !== 'initial'"
:validationState="validationState"
:validationIconSpin="validationIconSpin"
:validationIcon="validationIcon"
></vx-validationicon>
<div class="vxButton__textContainer vxValueContainer">
<span class="vxButton__icon vxButton__icon--left" v-if="layout === 'icon-text' || layout === 'icon'">
<vx-icon :name="activeIcon" :color="iconColor" size="small"></vx-icon>
</span>
<span
v-if="layout !== 'icon'"
class="vxButton__displayValue"
:class="{
'vxButton__displayValue--directionRight' : layout === 'icon-text',
'vxButton__displayValue--directionLeft' : layout === 'text-icon'
}">
{{text}}
</span>
<span class="vxButton__icon vxButton__icon--right" v-if="layout === 'text-icon'">
<vx-icon :name="activeIcon" :color="toggleIconColor" size="small"></vx-icon>
</span>
</div>
</div>
</template>
<script>
import vxIcon from "../Icon/vxIcon.vue";
import vxTooltip from "../Tooltip/vxTooltip.vue";
import {
baseComponent, themedComponent, validatedComponent
} from "../../Mixins/Components/baseComponent_mixin.js";
import validationIconComponent from "../Icon/vxValidationIcon.vue";
export default {
name : "vx-Button",
mixins : [baseComponent, themedComponent,validatedComponent],
components : {
"vx-icon" : vxIcon,
"vx-tooltip" : vxTooltip,
"vx-validationicon" : validationIconComponent
},
props : {
text : {
type : String,
default : ""
},
layout : {
default : "text",
validator : function( value )
{
//TEST
return ["text","icon-text","text-icon","icon"].indexOf( value ) !== -1;
}
},
icon : {
type : String,
default : null,
},
iconColor : {
type : String,
default : "currentColor"
},
toggleable : {
default : false
},
tabable : {
default : true
},
toggleIcon : {
default : null,
validator : function( value )
{
return true;
}
},
toggleIconColor : {
type : String,
default : "currentColor"
}
},
data()
{
return {
toggled : false,
clickEventType : "click",
controlType : "vxButton"
}
},
computed : {
acceptFocus : function()
{
return this.tabable && this.enabled ? 0 : -1;
},
activeIcon : function()
{
if ( this.toggled )
{
return this.toggleIcon;
}
else
{
return this.icon;
}
},
activeIconColor : function()
{
if ( this.toggled )
{
return this.toggleIconColor;
}
else
{
return this.iconColor;
}
}
},
mounted : function()
{
if ( this.toggleable )
{
this.clickEventType = "untoggled";
}
},
methods : {
_mousedown : function ( event )
{
/* This is used in order to trigger a minor delay
so when a button is clicked immeaditly from a changed input
it completes the focus out functionality first. */
setTimeout( function()
{
/*
event.which 1 = left click
event.which 2 = middle click
event.which 3 = right click
*/
if ( this.enabled && event.which === 1 )
{
this.$el.blur();
if ( this.toggleable )
{
this.toggle( event );
}
else
{
this.click( event );
}
}
}.bind( this ), 0 );
},
_enterup : function( event )
{
// test
if ( this.enabled )
{
$( this.$el ).removeClass( "vxButton--active" );
this.$el.blur();
if ( this.toggleable )
{
this.toggle( event );
}
else
{
this.click( event );
}
}
},
_enterDown : function( event )
{
if ( this.enabled )
{
$( this.$el ).addClass( "vxButton--active" );
}
},
toggle : function( )
{
this.toggled = !this.toggled;
this.clickEventType = this.toggled ? "toggled" : "untoggled";
if ( this.eventHandlers && this.eventHandlers.toggle )
{
this.eventHandlers.toggle( this, this.clickEventType );
}
this.$emit( this.clickEventType );
},
click : function()
{
if ( this.enabled )
{
if ( this.eventHandlers && this.eventHandlers.click )
{
this.eventHandlers.click( this, this.clickEventType );
}
else
{
this.$emit( this.clickEventType, this.compId );
}
}
},
forceToggle : function( toggle )
{
this.toggled = toggle;
this.clickEventType = this.toggled ? "toggled" : "untoggled";
if ( this.eventHandlers && this.eventHandlers.toggle )
{
this.eventHandlers.toggle( this, this.clickEventType );
}
this.$emit( this.clickEventType );
},
}
}
</script>
<style lang="scss" scoped >
@import "~@brand-scss";
@import "~@mixin-scss";
.vxButton--secondary.vxButton--opened{
@include secondary-open();
@include secondary-open-contents();
}
.vxButton--secondary.vxButton--opened:not(.vxButton--disabled):hover{
@include secondary-open-hover();
}
.vxButton--secondary.vxButton--opened:not(.vxButton--disabled):active{
@include secondary-open-active();
}
.vxButton--alt-light.vxButton--opened{
@include alt-light-opened();
}
.vxButton--alt-dark.vxButton--opened{
@include alt-dark-opened();
}
.vxButton__textContainer{
position:relative;
top:0;
left:0;
clear:both;
height:100%;
width:100%;
line-height: 34px;
font-size:14px;
}
.vxButton__displayValue{
user-select: none;
}
.vxButton:not(.vxButton--hasIcon) .vxButton__displayValue{
display:block;
margin-left:16px;
margin-right:16px;
text-align:center;
}
.vxButton--alt-dark .vxButton__icon{
color:$dark1;
}
.vxButton__icon{
float: left;
display: block;
height: 34px;
// width: 34px;
padding-top: 3px;
padding-bottom: 3px;
padding-left: 3px;
padding-right: 3px;
user-select: none;
}
.vxButton__icon--right{
padding-top: 3px;
padding-bottom: 3px;
padding-left: 4px;
padding-right: 3px;
}
.vxButton__icon--left{
padding-top: 3px;
padding-bottom: 3px;
padding-left: 3px;
padding-right: 4px;
}
.vxButton--hasIcon .vxButton__displayValue--directionLeft{
float:left;
margin-left:8px;
margin-right:16px;
text-align:left;
height:100%;
font-size: 14px;
}
.vxButton--hasIcon .vxButton__displayValue--directionRight{
float:left;
text-align:left;
margin-left:0px;
margin-right:8px;
height:100%;
font-size: 14px;
}
</style>
When I try adding components with mixins located in the same folder, everything seems to work. The problem seems that it happens because my components are being installed through npm. Does anyone have any suggestions or has anyone encountered this?