You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Storybook 7+Angular:argTypes无法生成选择控件问题求助

解决Storybook中Angular组件argTypes选择控件不显示问题

问题描述

我有一个Angular Header组件,尝试通过Storybook的argTypes为displayClass和displayType配置选择下拉框,但当前这两个参数仅显示“-”,无可用控件。希望实现选择下拉框,同时复用TypeScript类型定义的可选值。

组件代码

import { Component, Input, OnInit } from '@angular/core';
import { DisplayClassType, DisplayType, SizeType } from '../types/base.types';

@Component({
  selector: 'govc-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss'],
})
export class HeaderComponent implements OnInit {

  @Input() headerId = 'headerId-1';
  @Input() header = 'Title';
  @Input() displayClass: DisplayClassType = 'primary';
  @Input() displayType: DisplayType = 'flat';
  @Input() headerSize: SizeType = 'med';

  ngOnInit(): void {
    console.trace('**** Header Component');
  }
}

原Story代码

import { Meta } from '@storybook/angular';
import { HeaderComponent } from './header.component';

export default {
  title: 'HeaderComponent',
  component: HeaderComponent,
  argTypes: {
    displayClass: {
      description: 'Button display class',
      defaultValue: 'primary',
      control: {
        type: 'select',
        options: ['primary', 'secondary'],
      },
    },
    displayType: {
      description: 'Button display type',
      defaultValue: 'outline',
      control: {
        type: 'select',
        options: ['outline', 'flat', 'basic'],
      },
    },
  },
} as Meta<HeaderComponent>;

export const Primary = {
  render: (args: HeaderComponent) => ({
    props: args,
  }),
  args: {
    headerId: 'headerId-1',
    header: 'Title',
    displayClass: 'primary',
    displayType: 'flat',
    headerSize: 'med',
  },
};

解决方案

1. 重构TypeScript类型,实现取值复用

将字符串字面量类型的可选值定义为const数组,同时基于数组生成类型,既能保证类型安全,又能在Storybook中直接复用数组作为选择项,避免重复编写值导致的不一致。

修改../types/base.types.ts:

// 定义可选值数组,用as const确保类型是字面量而非string
export const DisplayClassOptions = ['primary', 'secondary'] as const;
// 基于数组生成类型
export type DisplayClassType = typeof DisplayClassOptions[number];

export const DisplayTypeOptions = ['outline', 'flat', 'basic'] as const;
export type DisplayType = typeof DisplayTypeOptions[number];

export const SizeTypeOptions = ['sm', 'med', 'lg'] as const;
export type SizeType = typeof SizeTypeOptions[number];

2. 修正Storybook的argTypes配置

  • 复用上述定义的可选值数组,避免手动重复编写选项
  • 确保defaultValue与组件@Input的默认值一致,避免配置冲突
  • 修正描述文本(原描述错误标注为Button,实际为Header)

修改后的Story代码:

import { Meta } from '@storybook/angular';
import { HeaderComponent } from './header.component';
import { DisplayClassOptions, DisplayTypeOptions } from '../types/base.types';

export default {
  title: 'HeaderComponent',
  component: HeaderComponent,
  argTypes: {
    displayClass: {
      description: 'Header display class',
      control: {
        type: 'select',
        options: DisplayClassOptions,
      },
      defaultValue: 'primary', // 与组件默认值保持一致
    },
    displayType: {
      description: 'Header display type',
      control: {
        type: 'select',
        options: DisplayTypeOptions,
      },
      defaultValue: 'flat', // 修正原配置的冲突值,与组件默认值一致
    },
  },
} as Meta<HeaderComponent>;

export const Primary = {
  render: (args: HeaderComponent) => ({
    props: args,
  }),
  args: {
    headerId: 'headerId-1',
    header: 'Title',
    displayClass: 'primary',
    displayType: 'flat',
    headerSize: 'med',
  },
};

3. 额外检查项

  • 确保@storybook/angular版本与你的Angular版本兼容,版本不匹配可能导致控件渲染异常
  • 确认组件的@Input属性没有被private/protected修饰,必须是公共属性才能被Storybook识别
  • 清除Storybook缓存(重启服务或删除.storybook缓存目录)

内容的提问来源于stack exchange,提问作者user22140771

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 23:34:54