The functionality of the storybook is effective, but initially, it fails to "render" the component.
- By examining the screenshot, we can deduce that the component-template is being utilized in some way, as otherwise, the basic layout of the component would be unknown to the storybook.
- Additionally, the actions are already being invoked correctly.
- The primary issue seems to be that initially, the storybook attempts to manipulate every prop of the component, although the reason for this behavior is unclear.
- This issue is prevalent in both JavaScript and TypeScript files.
- Stories that do not necessitate a vue-component (e.g., only modify styles) appear to function properly.
Upon modifying any value using the controls, everything renders accurately.
https://i.sstatic.net/8pfCa.png
Below is the story for my most concise component:
import { action } from "@storybook/addon-actions";
import { ArgTypes, Meta, Story } from "@storybook/vue/types-6-0";
import { icons } from "../components/iconLoader";
import TsetButton from "../components/TsetButton.vue";
const argTypes = {
size: {
table: { disable: true },
},
type: {
table: { disable: true },
},
iconLeft: {
control: { type: "select" },
options: Object.keys(icons),
},
iconRight: {
control: { type: "select" },
options: Object.keys(icons),
},
iconOnly: {
control: { type: "select" },
options: Object.keys(icons),
},
label: {
control: { type: "text" },
},
} as ArgTypes;
export default {
title: "Tset/Components/TsetButton",
component: TsetButton,
// More on argTypes: https://storybook.js.org/docs/vue/api/argtypes
argTypes,
} as Meta;
const DefaultButton: Story = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: {
TsetButton,
},
template: `
<TsetButton
v-bind="$props"
type="primary"
@click="onClick"
@hoverStart="onHoverStart"
@hoverEnd="onHoverEnd"
size="default"
/>
`,
methods: {
onClick: action("clicked"),
onHoverStart: action("Hover Start"),
onHoverEnd: action("Hover End"),
},
});
export const Default = DefaultButton.bind({});
Default.args = {
label: "Button",
tooltip: "Tooltip",
};
Furthermore, here is the component without its styling:
<template>
<div v-tooltip="tooltipState">
<button
:class="[
{
'button-primary': isPrimary,
'button-secondary': isSecondary,
'button-ghost': isGhost,
'button-tertiary': isTertiary,
'button-loading': isLoading,
'h-40 px-14 py-8': size === 'default',
'h-32 px-16 py-8': size === 'small',
},
'flex items-center m-10',
]"
:disabled="isDisabled"
@click="onClick"
@mouseover="onHoverStart"
@mouseleave="onHoverEnd"
>
<TsetIcon
:class="[
{
'h-20 w-20': size === 'default',
'h-16 w-16': size === 'small',
},
]"
class="mr-11"
:is="iconLeft"
v-if="!iconOnly"
/>
<TsetIcon
:class="[
{
'h-20 w-20': size === 'default',
'h-16 w-16': size === 'small',
},
]"
:is="iconOnly"
/>
<template v-if="isLoading"> ... </template>
<div
v-if="!iconOnly && !isLoading"
:class="[
{
'text-14': size === 'default',
'text-12': size === 'small',
},
]"
>
{{ label }}
</div>
<TsetIcon
:class="[
{
'h-20 w-20': size === 'default',
'h-16 w-16': size === 'small',
},
]"
class="ml-13"
:is="iconRight"
v-if="!iconOnly"
/>
</button>
</div>
</template>
<script lang="ts">
export type ButtonType = "primary" | "secondary" | "tertiary" | "ghost";
export type ButtonSize = "default" | "small";
import { Component, Vue, Prop } from "vue-property-decorator";
import VTooltip from "v-tooltip";
Vue.use(VTooltip);
@Component({
name: "TsetButton",
})
export default class Button extends Vue {
@Prop()
private readonly type!: ButtonType;
@Prop()
private readonly size!: ButtonSize;
@Prop()
private readonly isDisabled!: boolean;
@Prop()
private readonly isLoading!: boolean;
@Prop()
private readonly iconLeft: string | null = null;
@Prop()
private readonly iconRight: string | null = null;
@Prop()
private readonly iconOnly: string | null = null;
@Prop()
private readonly label!: string;
@Prop()
private readonly tooltip!: string;
@Prop()
private readonly disabledTooltip!: string;
get tooltipState() {
if (this.tooltip) {
return this.tooltip;
} else if (this.disabledTooltip) {
return this.disabledTooltip;
} else {
return this.label;
}
}
get isPrimary(): boolean {
return this.type === "primary";
}
get isSecondary(): boolean {
return this.type === "secondary";
}
get isTertiary(): boolean {
return this.type === "tertiary";
}
get isGhost(): boolean {
return this.type === "ghost";
}
onClick(): void {
if (!this.isLoading && !this.isDisabled) this.$emit("click");
}
onHoverStart(): void {
if (!this.isLoading && !this.isDisabled) this.$emit("hoverStart");
}
onHoverEnd(): void {
if (!this.isLoading && !this.isDisabled) this.$emit("hoverEnd");
}
}
</script>