旋钮

用于编辑属性的 Storybook 附加组件

在 Github 上查看

Storybook 附加组件旋钮(已弃用)

我们正在弃用旋钮,转而使用 @storybook/addon-controls。

讨论:https://github.com/storybookjs/storybook/discussions/15060

Storybook 附加组件旋钮允许您使用 Storybook UI 动态编辑属性。您还可以将旋钮用作 Storybook 中故事的动态变量。

框架支持.

这就是旋钮的样子

Storybook Knobs Demo

查看上面的 实时 Storybook观看此视频

入门

首先,您需要将旋钮作为开发依赖项安装到您的项目中。

yarn add @storybook/addon-knobs --dev

此附加组件的最新版本支持 Storybook v7。如果您使用的是旧版本的 Storybook,则需要安装此附加组件的匹配版本,例如 @storybook/[email protected]

.storybook/main.js

module.exports = {
  addons: ['@storybook/addon-knobs'],
};

现在,使用旋钮编写您的故事。

使用 React

import React from 'react';
import { withKnobs, text, boolean, number } from '@storybook/addon-knobs';

export default {
  title: 'Storybook Knobs',
  decorators: [withKnobs],
};
// Add the `withKnobs` decorator to add knobs support to your stories.
// You can also configure `withKnobs` as a global decorator.

// Knobs for React props
export const withAButton = () => (
  <button disabled={boolean('Disabled', false)}>{text('Label', 'Hello Storybook')}</button>
);

// Knobs as dynamic variables.
export const asDynamicVariables = () => {
  const name = text('Name', 'James');
  const age = number('Age', 35);
  const content = `I am ${name} and I'm ${age} years old.`;

  return <div>{content}</div>;
};

使用 Vue.js

MyButton.story.js

import { storiesOf } from '@storybook/vue';
import { withKnobs, text, boolean } from '@storybook/addon-knobs';

import MyButton from './MyButton.vue';

export default {
  title: 'Storybook Knobs',
  decorators: [withKnobs],
};

// Assign `props` to the story's component, calling
// knob methods within the `default` property of each prop,
// then pass the story's prop data to the component’s prop in
// the template with `v-bind:` or by placing the prop within
// the component’s slot.
export const exampleWithKnobs = () => ({
  components: { MyButton },
  props: {
    isDisabled: {
      default: boolean('Disabled', false),
    },
    text: {
      default: text('Text', 'Hello Storybook'),
    },
  },
  template: `<MyButton :isDisabled="isDisabled">{{ text }}</MyButton>`,
});

MyButton.vue

<template>
  <button :disabled="isDisabled">
    <slot></slot>
  </button>
</template>

<script>
export default {
  props: {
    isDisabled: {
      type: Boolean,
      default: false,
    },
  },
};
</script>

使用 Angular

import { storiesOf } from '@storybook/angular';
import { boolean, number, text, withKnobs } from '@storybook/addon-knobs';

import { Button } from '@storybook/angular/demo';

export default {
  title: 'Storybook Knobs',
  decorators: [withKnobs],
};

export const withKnobs = () => ({
  component: Button,
  props: {
    text: text('text', 'Hello Storybook'), // The first param of the knob function has to be exactly the same as the component input.
  },
});

使用 Ember

import { withKnobs, text, boolean } from '@storybook/addon-knobs';
import { hbs } from 'ember-cli-htmlbars';

export default {
  title: 'StoryBook with Knobs',
  decorators: [withKnobs],
};

export const button = () => ({
  template: hbs`
    <button disabled={{disabled}}>{{label}}</button>
  `,
  context: {
    label: text('label', 'Hello Storybook'),
    disabled: boolean('disabled', false),
  },
});

分类

通过为旋钮分配一个 groupId 来对旋钮进行分类。当存在 groupId 时,将在旋钮 Storybook 面板中出现选项卡以在组之间进行筛选。没有 groupId 的旋钮会自动分类到 ALL 组中。

export const inGroups = () => {
  const personalGroupId = 'personal info';
  const generalGroupId = 'general info';

  const name = text('Name', 'James', personalGroupId);
  const age = number('Age', 35, { min: 0, max: 99 }, personalGroupId);
  const message = text('Hello!', 35, generalGroupId);
  const content = `
    I am ${name} and I'm ${age} years old.
    ${message}
  `;

  return <div>{content}</div>;
};

您可以在 Storybook 面板中看到您的旋钮,如下所示。

可用旋钮

这些是您可以使用的可用旋钮。您可以从 @storybook/addon-knobs 模块导入这些旋钮。以下是如何导入 文本 旋钮。

import { text } from '@storybook/addon-knobs';

就这样,您可以导入任何其他以下旋钮

text

允许您从用户那里获取一些文本。

import { text } from '@storybook/addon-knobs';

const label = 'Your Name';
const defaultValue = 'James';
const groupId = 'GROUP-ID1';

const value = text(label, defaultValue, groupId);

boolean

允许您从用户那里获取布尔值。

import { boolean } from '@storybook/addon-knobs';

const label = 'Agree?';
const defaultValue = false;
const groupId = 'GROUP-ID1';

const value = boolean(label, defaultValue, groupId);

number

允许您从用户那里获取数字。

import { number } from '@storybook/addon-knobs';

const label = 'Age';
const defaultValue = 78;
const groupId = 'GROUP-ID1';

const value = number(label, defaultValue);

对于与 groupId 一起使用,请将默认的 options 作为第三个参数传递。

const value = number(label, defaultValue, {}, groupId);

受范围限制的数字

允许您使用范围滑块从用户那里获取数字。

import { number } from '@storybook/addon-knobs';

const label = 'Temperature';
const defaultValue = 73;
const options = {
  range: true,
  min: 60,
  max: 90,
  step: 1,
};
const groupId = 'GROUP-ID1';

const value = number(label, defaultValue, options, groupId);

color

允许您从用户那里获取颜色。

import { color } from '@storybook/addon-knobs';

const label = 'Color';
const defaultValue = '#ff00ff';
const groupId = 'GROUP-ID1';

const value = color(label, defaultValue, groupId);

object

允许您从用户那里获取 JSON 对象或数组。

import { object } from '@storybook/addon-knobs';

const label = 'Styles';
const defaultValue = {
  backgroundColor: 'red',
};
const groupId = 'GROUP-ID1';

const value = object(label, defaultValue, groupId);

在旋钮中编辑值时,请确保输入有效的 JSON 语法。

array

允许您从用户那里获取字符串数组。

import { array } from '@storybook/addon-knobs';

const label = 'Styles';
const defaultValue = ['Red'];
const groupId = 'GROUP-ID1';

const value = array(label, defaultValue);

在旋钮中编辑值时,您需要使用分隔符。默认情况下,它是一个逗号,但可以通过传递分隔符变量来覆盖此选项。

import { array } from '@storybook/addon-knobs';

const label = 'Styles';
const defaultValue = ['Red'];
const separator = ':';
const value = array(label, defaultValue, separator);

对于与 groupId 一起使用,请将默认的 separator 作为第三个参数传递。

const value = array(label, defaultValue, ',', groupId);

select

它允许您从用户那里获取选择框中的值。

import { select } from '@storybook/addon-knobs';

const label = 'Colors';
const options = {
  Red: 'red',
  Blue: 'blue',
  Yellow: 'yellow',
  Rainbow: ['red', 'orange', 'etc'],
  None: null,
};
const defaultValue = 'red';
const groupId = 'GROUP-ID1';

const value = select(label, options, defaultValue, groupId);

选项也可以是数组

import { select } from '@storybook/addon-knobs';
const label = 'Cats';
const options = ['linus', 'eleanor', 'lover'];
const defaultValue = 'eleanor';
const groupId = 'GROUP-ID2';
const value = select(label, options, defaultValue, groupId);

选项也可以是对象数组

const label = 'Dogs';
const arrayOfObjects = [
  {
    label: 'Sparky',
    dogParent: 'Matthew',
    location: 'Austin',
  },
  {
    label: 'Juniper',
    dogParent: 'Joshua',
    location: 'Austin',
  },
];
const defaultValue = arrayOfObjects[0];
const groupId = 'GROUP-ID3';
const value = select(label, arrayOfObjects, defaultValue, groupId);

单选按钮

它允许您从用户那里获取单选按钮列表中的值。

import { radios } from '@storybook/addon-knobs';

const label = 'Fruits';
const options = {
  Kiwi: 'kiwi',
  Guava: 'guava',
  Watermelon: 'watermelon',
};
const defaultValue = 'kiwi';
const groupId = 'GROUP-ID1';

const value = radios(label, options, defaultValue, groupId);

options

用于从一组选项中选择值的 可配置 UI。

import { optionsKnob } from '@storybook/addon-knobs';

const label = 'Fruits';
const valuesObj = {
  Kiwi: 'kiwi',
  Guava: 'guava',
  Watermelon: 'watermelon',
};
const defaultValue = 'kiwi';
const optionsObj = {
  display: 'inline-radio',
};
const groupId = 'GROUP-ID1';

const value = optionsKnob(label, valuesObj, defaultValue, optionsObj, groupId);

或者,您可以使用此导入

import { optionsKnob as options } from '@storybook/addon-knobs';

...

const value = options(label, valuesObj, defaultValue, optionsObj, groupId);

optionsObj 的显示属性接受

  • radio
  • inline-radio
  • check
  • inline-check
  • select
  • multi-select

files

它允许您从用户那里获取文件输入的值。

import { files } from '@storybook/addon-knobs';

const label = 'Images';
const accept = '.xlsx, .pdf';
const defaultValue = [];
const groupId = 'GROUP-ID1';

const value = files(label, accept, defaultValue, groupId);

您可以选择指定一个 文件类型列表,文件输入应该接受这些类型。可以选中多个文件,并将作为 数据 URL 数组返回。

date

允许您从用户那里获取日期(和时间)。

import { date } from '@storybook/addon-knobs';

const label = 'Event Date';
const defaultValue = new Date('Jan 20 2017');
const groupId = 'GROUP-ID1';

const value = date(label, defaultValue, groupId);

注意:默认值不得更改 - 例如,不要执行 date('Label', new Date())date('Label')

date 旋钮以字符串化的 Unix 时间戳形式返回所选日期(例如 "1510913096516")。如果您的组件需要以其他形式使用日期,您可以包装 date 函数

function myDateKnob(name, defaultValue) {
  const stringTimestamp = date(name, defaultValue);
  return new Date(stringTimestamp);
}

button

它允许您包含一个按钮和关联的处理程序。

import { button } from '@storybook/addon-knobs';

const label = 'Do Something';
const handler = () => doSomething('foobar');
const groupId = 'GROUP-ID1';

button(label, handler, groupId);

按钮旋钮在处理程序触发后会导致故事重新渲染。您可以通过让处理程序返回 false 来防止这种情况。

withKnobs 选项

withKnobs 还接受两个可选选项作为故事参数。用法

import { withKnobs } from '@storybook/addon-knobs';

export default {
  title: 'Storybook Knobs',
  decorators: [withKnobs],
};

export const defaultView = () => <div />;
defaultView.parameters = {
  knobs: {
    // Doesn't emit events while user is typing.
    timestamps: true,

    // Escapes strings to be safe for inserting as innerHTML. This option is true by default. It's safe to set it to `false` with frameworks like React which do escaping on their side.
    // You can still set it to false, but it's strongly discouraged to set to true in cases when you host your storybook on some route of your main site or web app.
    escapeHTML: true,
  },
};

Typescript

如果您使用的是 Typescript,请确保您已为以下库安装了类型定义

  • node
  • react

您可以使用以下命令安装它们:(*假设您使用的是 Typescript >2.0.*)

yarn add @types/node @types/react --dev
作者
  • koga73
    koga73
支持
    Angular
    Ember
    HTML
    Marko
    Mithril
    Preact
    Rax
    React
    Riot
    Svelte
    Vue
    Web Components
标签