The initial rendering of components is not displayed by Vue Storybook

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>

Answer №1

To solve the problem, I implemented storybook into an existing project using vue add storybook. After customizing it to meet our requirements, I removed all unnecessary components and essentially started fresh as if I had set it up correctly from the beginning.

If you're facing a similar issue, consider taking this approach as it may prove to be helpful.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Typescript for parsing large JSON files

I have encountered an issue while trying to parse/process a large 25 MB JSON file using Typescript. It seems that the code I have written is taking too long (and sometimes even timing out). I am not sure why this is happening or if there is a more efficien ...

The component prop of Typography in TypeScript does not accept MUI styling

Working with MUI in typescript and attempting to utilize styled from MUI. Encountering an error when passing the component prop to the styled component. The typescript sandbox below displays the issue - any suggestions for a workaround? https://codesandbo ...

Make sure to wait for the observable to provide a value before proceeding with any operations involving the variable

Issue with handling observables: someObservable$.subscribe(response => this.ref = response); if (this.ref) { // do something with this.ref value } ERROR: this.ref is undefined How can I ensure that the code relying on this.ref only runs after ...

Passing headers using a universal method in HTTP CRUD process

My service function is structured like this: Please note: I am required to work with cookies book(data: Spa): Observable<any> { return this.http.post(`${environment.apiURL}:${environment.port}/${environment.domain}/abc/my.json`, data, { ...

Chrome fails the karma tests while phantomjs passes them

I've been struggling with this issue for some time now and can't seem to find a solution. I'm working on an Ionic 2 project that utilizes Angular 2's testing environment. When I run 'ng test' using Karma's Chrome launcher ...

How can I verify the validity of a regular expression in Typescript without encountering a syntax error?

I am facing an issue with my code where I load a set of regular expressions from an external source. My goal is to determine if a given string is a valid regex without causing the application to crash due to a syntax error. Despite trying to use try/catch ...

If the value is null, pass it as is; if it is not null, convert it to a date using the

I am currently facing an issue regarding passing a date value into the rrule plugin of a fullCalendar. Here is the snippet of code in question: Endate = null; rrule: { freq: "Daily", interval: 1, dtstart: StartDate.toDate ...

The outcome from using Array.reduce may not always match the expected result

After discovering an unexpected behavior in Typescript's type-inference, I suspect there may be a bug. Imagine having a list of the MyItem interface. interface MyItem { id?: string; value: string; } const myItemList: MyItem[] = []; It's ...

Is it possible to implement sanctum on multiple Vue projects simultaneously?

Greetings! I am currently using Sanctum to authenticate users in the system. My goal is for a user who logs in to vue project num1 to also be automatically logged in to vue project num2. I attempted to implement this functionality using cookies like so: $ ...

The Vuetify navigation drawer seems to have a quirk where it only closes after an item

I am brand new to Vue and struggling to figure out why my vue v-navigation-drawer is not working properly. It is located in app-root.vue and was initially closing when clicking on a drawer item, but now requires two clicks to close. After the first click, ...

Using ngTemplateOutlet to pass ng-template to a child component in Angular 5

I am looking to develop a versatile component that can utilize custom templates for data rendering, while consolidating the business logic to prevent redundancy. Imagine this use case: a paginated list. The pagination logic should be housed within the com ...

Leveraging an external JSON file within a Vue application

A friend of mine isn't very tech-savvy, so I'm building a website for him with an idea to simplify the process. I plan to create a JSON file to store all the text and image paths, allowing him to easily make changes without needing to delve into ...

Enabling HTML and Markdown in the footer of VuePress

I am currently attempting to incorporate HTML/markdown into the footer variable within VuePress' default theme. My goal is to include a URL in the footer that directs visitors to my website. Unfortunately, I have been unable to find a straightforward ...

ES6: The attribute 'selected' is not found on the data type 'Object'

While attempting to convert the JS code from 'AMcharts4 codepen pre selecting areas' into ES6, I encountered an error. Error TS2339: Property 'selected' does not exist on type 'Object'. Here is the code snippet that I am l ...

Can you explain the significance of the 'project' within the parserOptions in the .eslintrc.js file?

Initially, I struggle with speaking English. Apologies for the inconvenience :( Currently, I am using ESLint in Visual Studio Code and delving into studying Nest.js. I find it difficult to grasp the 'project' setting within the parserOptions sec ...

Leveraging ES6 Symbols in Typescript applications

Attempting to execute the following simple line of code: let INJECTION_KEY = Symbol.for('injection') However, I consistently encounter the error: Cannot find name 'Symbol'. Since I am new to TypeScript, I am unsure if there is somet ...

Highchart in ionic 2 not displaying

I inserted code for a highchart on my webpage, but it's not appearing I followed instructions from this video tutorial https://www.youtube.com/watch?v=FSg8n5_uaWs Can anyone help me troubleshoot this issue? This is the TypeScript code I used: ts; ...

Why does VSCode open a React app in Edge instead of Chrome?

Recently, I began a new project using the react-create-app template with typescript. However, when I run npm run dev, it unexpectedly opens in the Edge browser instead of Chrome. Does anyone know how to make it open in Chrome instead? ...

Tips for including an element at the start while creating a map()

enum StatusEnum { accepted = "AC", rejected = "RJ", } const select = (Object.keys(StatusEnum) as Array<keyof typeof StatusEnum>).map((x) => ({ value: x, name: x + "_random", })) /** * Console.log(select) * [ ...

Utilizing a child component within a parent component in VueJS

As I was exploring headlessui's menu component, I came across a unique nested component structure illustrated below: (check it out here: ) <template> <Menu> <MenuButton>More</MenuButton> <MenuItems> <Me ...