【问题标题】:Storybook with web components - changing arguments dynamically on code带有 Web 组件的故事书 - 在代码上动态更改参数
【发布时间】:2022-09-25 16:32:42
【问题描述】:

我有一个模态组件,我正在为它写故事。它看起来像这样:

import { Story, Meta } from \'@storybook/html\';

export default {
  title: \'Components/Modal\',
  argTypes: {
    open: {
      name: \'Opened\',
      control: \'boolean\'
    },
  },
  args: {
    open: false,
  }
} as Meta;

const Template: Story = (args) => {
  return `
    <my-modal open=\"${args.open}\">
      Some example content inside the modal
    </my-modal>
  `;
};

export const Modal: Story = Template.bind({});

我在控件上有 arg open,我可以将其值更改为 true 并显示模态。但我希望故事有一个按钮,当它被点击时,模式会显示出来。 在当前版本的 Storybook for Web Components 中,我找不到执行此操作的方法。

我已经看到有一些可用于 React (import { useArgs } from \'@storybook/api\';) 的钩子,它们允许您动态更改参数值,但我看不到如何为 Web 组件执行此操作?

任何帮助将不胜感激。

    标签: javascript web-component storybook custom-element storybook-addon


    【解决方案1】:

    只需将该按钮添加到模板中:

    import { Story, Meta } from '@storybook/html';
    
    export default {
      title: 'Components/Modal',
      argTypes: {
        open: {
          name: 'Opened',
          control: 'boolean'
        },
      },
      args: {
        open: false,
      }
    } as Meta;
    
    const Template: Story = (args) => {
      return `
        <button 
          type="button" 
          onclick="this.nextElementSibling.open = !this.nextElementSibling.open">
            Toggle Modal
        </button>
        <my-modal .open=${args.open}>
          Some example content inside the modal
        </my-modal>
      `;
    };
    
    export const Modal: Story = Template.bind({});
    

    此外,对于布尔属性 - 如果实施得当 - 您应该使用属性(在模板中使用. 作为前缀)而不是属性。

    【讨论】:

    • 感谢您的回答:) 我实际上有类似的东西,只是添加了一个 <script> 标签和代码来做到这一点。但我一直在寻找与 Storybook 更“集成”的东西,就像使用 React 时 useArgs 钩子所做的一样。所以你实际上是在修改参数值。但我想没有办法用 web 组件来做到这一点:(
    • 我不知道 React 或 useArgs 或者那些钩子是什么。我更喜欢在可用时采用 DOM 路由;我讨厌依靠工具来完成工作,而且我永远不会考虑安装附加组件或类似的东西来完成它“更综合的方式”.集成到 imo 工具中是一件坏事;它让你更加依赖这些工具,依赖那些被维护而不被弃用的附加组件(就像许多 Storbook 附加组件/功能一样),随着时间的推移,你会绝不设法保持最新​​。
    • 如果没有更好的解决方案,为什么不将此标记为答案,以便其他人找到呢?
    【解决方案2】:

    这样做所有本机代码不是火箭科学...

    <my-dialog id="DIALOG" open>
      Hello *Native* Web Components world!
    </my-dialog>
    
    <button onclick="DIALOG.open()">OPEN</button>
    
    <script>
      customElements.define("my-dialog", class extends HTMLElement {
        static get observedAttributes() {
          return ["open"];
        }
        constructor() {
          super() // sets and returns 'this'
            .attachShadow({mode:"open"}) // sets and return this.shadowRoot
            .innerHTML = `<dialog><slot></slot><button>Close</button></dialog>`;
          this.dialog = this.shadowRoot.querySelector("dialog");
        }
        connectedCallback() {
          this.onclick = () => this.close(); // or attach to button
        }
        attributeChangedCallback(name,oldValue,newValue) {
          this.open();
        }
        open() {
          this.dialog.showModal(); // or .show()
        }
        close() {
          this.dialog.close();
        }
      });
    </script>

    【讨论】:

    • 感谢您的回答,但我在问故事书。
    猜你喜欢
    • 2020-09-13
    • 2020-12-15
    • 2021-11-20
    • 2021-05-30
    • 2011-05-28
    • 2019-07-07
    • 2011-10-16
    • 2020-12-07
    • 2021-06-22
    相关资源
    最近更新 更多