npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

bs-storybook

v1.1.0

Published

BuckleScript bindings for Storybook.js

Downloads

73

Readme

bs-storybook

BuckleScript bindings for Storybook.

The goal of this project is to provide bindings for the main Storybook API, as well as the official add-ons. Currently it supports:

Getting Started

First install this package:

npm install bs-storybook

bs-platform versions

  • bs-platform 8.4.2 or higher requires 1.1.0
  • anything lower uses 1.0.0

Next, you'll need to add bs-storybook to your bsconfig.json as a dependency.

Then, get Storybook up and running according to their docs

Note: This library does not attempt to provide a way to configure storybook in Reason - just use the standard JS configs.

In your /.storybook/config.js, import your stories from wherever your compiled Reason modules end up. For example, if you're writing your stories inside a __stories__ directory, and bsb is configured for a standard build, you might do something like:

const req = require.context("../lib/js", true, /\__stories__\/.*.js$/);
configure(() => {
  req.keys().forEach((module) => {
    req(module).default();
  });
}, module);

or if you are using Storybook v6.

/* .storybook/main.js */
module.exports = {
  stories: ["../stories/**/*.js"],
  addons: [
    "@storybook/addon-actions",
    "@storybook/addon-links",
    "@storybook/addon-knobs/register",
  ],
};

Note that in the above example, we're assuming the convention of each module containing a function as the default export. bs-storybook is accountable for that while writting your stories:

Writing a story

Here's a basic story in its entirety:

open BsStorybook.Story;

let _module = [%bs.raw "module"];

storiesOf("My First Reason Story", _module)
->add("Chapter I", () => <span> {React.string("Hello bs-storybook!")} </span>);

Storybook uses a reference to the module global provided by webpack to facilitate hot-reloading. We'll access that via the [%bs.raw] decorator.

Writing a CSF Story

If you'd prefer to use the newer Component Story Format, you can do that as well:

open BsStorybook;

let default = CSF.make(~title="My CSF Story", ());

let button = () => <MyButton />;

button->CSF.addMeta(~name="Plain Button", ());

The Actions Addon

The action addon's API is essentially unchanged from its JS implementation:

Make sure that you have @storybook/addon-actions in the config

let clickAction = Action.action("I Clicked The Button!");

<div onClick={clickAction} />

The Knobs Addon

To use knobs you have twoo ways:

Make sure that you have @storybook/addon-knobs/register in the config

As a decorator

open Storybook;
open Story;

let _module = [%bs.raw "module"];

storiesOf("My First Reason Story", _module)
->addDecorator(Knobs.withKnobs)
->add("Chaper with Knobs", () => {
    let name = Knobs.text(~label="Name", ~defaultValue="Patrick", ());
    <span> {React.string(name)} </span>;
  })

Creating the story

open Storybook;
open Story;

let _module = [%bs.raw "module"];

let knobsStory =
  Main.createStory(
    ~title="Hey look, knobs!",
    ~decorators=[Knobs.withKnobs],
    ~_module,
    (),
  );

knobsStory.add("Chaper with Knobs", () => {
  let name = Knobs.text(~label="Name", ~defaultValue="Patrick", ());
  <span> {React.string(name)} </span>;
})

Each knob type is invoked using a function with labeled arguments, and each requires passing unit as the final argument. They all share a ~label argument, and a ~defaultValue argument (where appropriate):

Text

let myText = Knobs.text(~label="What should it say?", ~defaultValue="Sup?", ());

Boolean

let myBoolean = Knobs.boolean(~label="Should Show?", ~defaultValue=true, ());

Note: The boolean type will call the underlying JS knob with a defaultValue of false if one is not provided.

Color

let myColor = Knobs.color(~label="Color", ~defaultValue="#333" ());

Number

The number type works with floats. If no defaultValue is provided, it will pass 0. It also takes an optional rangeConfig record, which allows for specifying a min, max, and step so that the knob is displayed as a range slider.

let num1 = Knobs.number(~label="Number 1", ());
let num2 =
  Knobs.number(
    ~label="Number 2",
    ~rangeConfiguration={range: true, min: 0., max: 10., step: 1.},
    ()
  );

Select

To use the select knob, first define a record type that contains the shape of the options, then the actual options as a type of selectConfig, passing your shape as the constructor type:

type selectOptions = {
  one: string,
  two: string
};

let options : Knobs.selectConfig(selectOptions) = {
  one: "Hello",
  two: "Hi"
};

Then define the select knob like so:

let greeting = Knobs.select(~label="Greeting", ~options, ~defaultValue=options.one, ());

Button

Knobs.button(
  ~label="Knob Button",
  ~handler=Action.action("Clicked the knob button"),
  ()
)

Object

let obj = Knobs.object_(~label="User", ~defaultValue={"color": "grey"}, ());

Js.Dict

https://bucklescript.github.io/bucklescript/api/Js.Dict.html

let options =
  Js.Dict.fromArray([|
    ("Red", "red"),
    ("Blue", "blue"),
    ("Yellow", "yellow"),
    ("None", ""),
  |]);

let color =
  Knobs.selectFromDict(
    ~label="MySelection",
    ~options,
    ~defaultValue="red",
    (),
  );

Array

let color =
  Knobs.selectFromArray(
    ~label="MySelection",
    ~options=[|"red", "blue", "yellow"|],
    ~defaultValue="red",
    (),
  );