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

storybox-react

v1.1.0

Published

storybook at minimums

Downloads

67

Readme

storybook at minimums

DEMO

TRY IT OUT ON VERCEL

The solution if you need some tool similar to storybook, but

You just need to have some simple "test page" with all custom components, and you don't want so much features, that storybook offers

You don't want to set up build (from project to project it can be very hard to set up storybook). With storybox you can use same build config as you use in prod, since storybox doesn't care where you use it or how you build the project.

Usage examples

Clone this repo and go to examples directory.

  • private-page is about when you want to place storybox in the same app, but within some private page. npm start
  • separate-entry-point is about when you don't want to include storybox to your prod bundle, but instead, use separate entrypoint for storybox page (e.g. with react-app-rewired or craco) npm run start:storybox

Usage

  1. Define stories for each component you want. There are 6 types of controls available: boolean, checkbox, radio, button, number, number, string. (see controls API below)
import {Button} from '../components/button';
import {
    useBooleanControl,
    useNumberControl,
    useRadioControl,
    useStringControl,
} from 'storybox-react';

export const ButtonStory = () => {
    const [children] = useStringControl({
        defaultValue: 'my button',
        name: 'children',
        minLength: 0,
        maxLength: 30,
    });
    const [padding] = useNumberControl({
        defaultValue: 10,
        name: 'padding',
        max: 100,
        min: 10,
        integerOnly: true,
        appearance: 'range',
    });
    const [type] = useRadioControl({
        name: 'type',
        options: ['primary', 'danger'],
        defaultValue: 'primary',
    });
    const [disabled] = useBooleanControl({
        name: 'disabled',
        defaultValue: false,
    });
    return <Button children={children} padding={padding} type={type} disabled={disabled}/>;
};
  1. Define a story container. Import stories and place it in stories prop. Render StoryBox somewhere in the app and that's it
import React from 'react';
import ReactDOM from 'react-dom/client';
import 'storybox-react/dist/styles.css'; // import storybox css
import {StoryBox} from 'storybox-react'; // import stories container
import {ButtonStory} from '../stories/button.story'; // import your stories

const stories = {ButtonStory};

<StoryBox stories={stories}/> // and that's just it!

<StoryBox/> component API

export type StoryBox<T extends Record<string, FC> = Record<string, never>> = FC<{
    /** All your stories placed in one object */
    stories: T;
    /** Default selected story key */
    defaultSelectedStory?: keyof T;
    /** Callback triggers on story key change.
     * [string] if some story has been selected
     * [undefined] - if unselected
     */
    onStoryKeyChange?: (key?: string) => void;
    /** Decorate each story */
    decorator?: (Story: FC) => FC;
}>;

Controls API

useBooleanControl

type UseBooleanControlParams = {
    /** name for control that will be displayed on the left panel */
    name: string;
    /** initial value */
    defaultValue: boolean;
}

type UseBooleanControlReturn = [
    /** current control value */
    boolean,
    /** handler for manually value updating */
    (newValue: boolean) => void
]

export type useBooleanControl = (params: UseBooleanControlParams) => UseBooleanControlReturn;

useStringControl

type UseStringControlParams = {
    /** name for control that will be displayed on the left panel */
    name: string;
    /** initial value */
    defaultValue: boolean;
    /** validating input for min length if passed */
    minLength?: number;
    /** validating input for max length if passed */
    maxLength?: number;
    /**
     * "washing" input with that regex if passed
     * @example
     * you need a string only with numbers and spaces.
     * so you create a regex that will match all EXCEPT numbers and spaces.
     * all matches will be removed
     * "a4 bcd 123".replace(/[^\s\d]/g, "") => "4  123"
     */
    washRegex?: RegExp;
}

type UseStringControlReturn = [
    string, /** current control value */
    (newValue: string) => void /** handler for manually value updating */
]

export type useStringControl = (params: UseStringControlParams) => UseStringControlReturn;

useNumberControl

type UseNumberControlParams = {
    /** name for control that will be displayed on the left panel */
    name: string;
    /** initial value */
    defaultValue: boolean;
    /** validating input for min if passed */
    min?: number;
    /** validating input for max if passed */
    max?: number;
    /** accepts only integer if passed
     * @default [integerOnly=false]
     */
    integerOnly?: boolean;
    /** plain input or range appearance on left panel
     * @default [appearance="input"]
     */
    appearance?: "input" | "range";
    /** step for changing values if you have chosen "range" appearance
     * @default [step=1]
     */
    step?: number;
}

type UseNumberControlReturn = [
    number, /** current control value */
    (newValue: number) => void /** handler for manually value updating */
]

export type useNumberControl = (params: UseNumberControlParams) => UseNumberControlReturn;

useRadioControl

type UseRadioControlParams = {
    /** name for control that will be displayed on the left panel */
    name: string;
    /** initial value */
    defaultValue: string;
    /** options for radio group */
    options: string[];
}

type UseRadioControlReturn = [
    /** current control value */
    string,
    /** handler for manually value updating */
    (newValue: string) => void
]

export type useRadioControl = (params: UseRadioControlParams) => UseRadioControlReturn;

useCheckboxControl

type UseCheckboxControlParams = {
    /** name for control that will be displayed on the left panel */
    name: string;
    /** initial value */
    defaultValue: string[];
    /** options for checkbox group */
    options: string[];
}

type UseCheckboxControlReturn = [
    /** current control value */
    string,
    /** handler for manually value updating */
    (newValue: string[]) => void
]

export type useCheckboxControl = (params: UseCheckboxControlParams) => UseCheckboxControlReturn;

useButtonControl

type UseButtonControlParams = {
    /** name for control that will be displayed on the left panel */
    name: string;
    /** click handler */
    onClick?: () => void;
}

type UseButtonControlReturn = [
    /** counter: how many times the button has been clicked */
    number,
    /** update counter above */
    (newValue: number) => void,
]

export type useButtonControl = (params: UseButtonControlParams) => UseButtonControlReturn;

CHANGELOG

0.0.1 06.07.2022

  • Initial release

0.0.2 06.07.2022

  • Fix prepare script

0.0.3 06.07.2022

  • Correct dist files

0.0.4 07.07.2022

  • Add controls informers

0.0.5 07.07.2022

  • Add examples

0.0.6 07.07.2022

  • Fix description

0.1.0 17.07.2022

  • Fix updating controls on min/max change

1.0.0 17.07.2022

  • Change contracts

1.0.1 17.07.2022

  • Style fixes

1.0.2 18.07.2022

  • Style fixes

1.0.3 18.07.2022

  • Update readme

1.0.4 18.07.2022

  • Remove useless dependency

1.0.5 19.07.2022

  • Export types

1.0.6 19.07.2022

  • Style fixes

1.0.7 19.07.2022

  • Small fixes

1.0.8 19.07.2022

  • Add wash regex to string input

1.0.9 19.07.2022

  • Fixes

1.0.10 21.07.2022

  • Update readme

1.0.11 22.07.2022

  • Add default story key prop

1.0.12 23.07.2022

  • Fixes

1.0.13 23.07.2022

  • Add invariant context

1.0.14 07.08.2022

  • Update readme

1.0.15 18.09.2022

  • Add error boundary to the active story

1.0.16 18.09.2022

  • Replace with react-error-boundary npm

1.0.17 18.09.2022

  • Add more readable typings. Fix readme

1.0.18 19.09.2022

  • Add error boundary to stories container

1.0.19 19.09.2022

  • Style fix

1.0.20 26.09.2022

  • Fix error {nothing was returned from render}

1.0.21 26.09.2022

  • Fix checkbox force disappearance

1.0.22 27.09.2022

  • Add onStoryKeyChange prop

1.0.23 28.09.2022

  • Fix drag resizer

1.1.0 04.02.2023

  • Now you can double shift to hide/show panel
  • Added ability to decorate each story