Skip to content

layerx-oss/slack-blockbook

Repository files navigation

slack-blockbook

Storybook-like preview tool for Slack Block Kit development.

License npm version

Features

  • Real-time preview with hot reload
  • Storybook-style controls for dynamic arguments
  • Block Kit Builder URL generation
  • Static build for hosting on GitHub Pages, Netlify, etc.
  • Support for jsx-slack

Installation

npm install -D @layerx/slack-blockbook
# or
yarn add -D @layerx/slack-blockbook
# or
pnpm add -D @layerx/slack-blockbook

Quick Start

1. Create a preview server config

// scripts/blockbook.ts
import { startBlockKitPreviewServer } from "@layerx/slack-blockbook";
import path from "path";

// Export config so `slack-blockbook build` can also use it
export const config = {
  port: 5176,
  workspaceId: "YOUR_SLACK_WORKSPACE_ID",
  searchDir: path.join(process.cwd(), "src/slack"),
  projectName: "my-project",
  baseDir: process.cwd(),
  restartOnChange: true,
  watchPatterns: ["**/*.tsx", "**/*.ts"],
};

startBlockKitPreviewServer(config);

2. Create a Block Kit story

// src/slack/hello.blockkit.tsx
import { createStory } from "@layerx/slack-blockbook";
import { Blocks, Section } from "jsx-slack";

export const stories = [
  createStory({
    name: "Hello World",
    component: () => (
      <Blocks>
        <Section>Hello, World!</Section>
      </Blocks>
    ),
  }),
];

3. Run the preview server

npx @layerx/slack-blockbook scripts/blockbook.ts

4. Open in browser

Open http://localhost:5176 in your browser.

API

startBlockKitPreviewServer(config)

Starts the preview server with hot reload support.

interface BlockKitPreviewConfig {
  port?: number;              // Default: 5176
  workspaceId: string;        // Slack workspace ID
  searchDir: string;          // Directory to search for .blockkit.tsx files
  fileExtension?: string;     // Default: ".blockkit.tsx"
  projectName?: string;       // Displayed in header
  baseDir?: string;           // Base directory for relative paths
  watchPatterns?: string[];   // Additional file patterns to watch
  restartOnChange?: boolean;  // Restart process on file change
}

createStory(options)

Creates a story definition with type inference.

interface BlockKitStory<TArgs> {
  name: string;                                    // Story name
  description?: string;                            // Story description
  component: (args?: TArgs) => unknown;            // Block Kit JSON component
  tags?: string[];                                 // Tags for filtering
  args?: TArgs;                                    // Default arguments
  argTypes?: Record<keyof TArgs, ArgType>;         // Control types
}

generateBlockKitUrls(config)

Generates Block Kit Builder URLs to a Markdown file.

interface BlockKitGeneratorConfig {
  workspaceId: string;
  searchDir: string;
  fileExtension?: string;
  outputPath: string;
  baseDir?: string;
}

Controls (argTypes)

Supports Storybook-like controls:

Control Description
text Text input
number Number input with min/max/step
boolean Checkbox
select Dropdown select
date Date picker

Example with Controls

createStory<{ message: string; count: number; showIcon: boolean }>({
  name: "Configurable Message",
  args: {
    message: "Hello",
    count: 1,
    showIcon: true,
  },
  argTypes: {
    message: { control: "text", description: "Message to display" },
    count: { control: "number", min: 1, max: 10 },
    showIcon: { control: "boolean" },
  },
  component: (args) => (
    <Blocks>
      <Section>
        {args?.showIcon && "πŸ‘‹ "}
        {args?.message} (x{args?.count})
      </Section>
    </Blocks>
  ),
});

Static Build

Generate a fully interactive static HTML site for hosting (GitHub Pages, Netlify, etc.). Controls work without a server β€” story components are bundled for client-side re-rendering.

# Build static site
npx @layerx/slack-blockbook build scripts/blockbook.ts

# With custom output directory
npx @layerx/slack-blockbook build scripts/blockbook.ts --outDir ./dist

The same config file used for the dev server works for static builds. Output is written to ./blockbook-static/ by default.

Programmatic API

import { buildStaticBlockBook } from "@layerx/slack-blockbook";

await buildStaticBlockBook({
  workspaceId: "YOUR_SLACK_WORKSPACE_ID",
  searchDir: "./src/slack",
  projectName: "my-project",
  outputDir: "./blockbook-static",
});

buildStaticBlockBook(config)

Builds a static HTML site with bundled story components.

interface StaticBuildConfig {
  workspaceId: string;        // Slack workspace ID
  searchDir: string;          // Directory to search for .blockkit.tsx files
  fileExtension?: string;     // Default: ".blockkit.tsx"
  projectName?: string;       // Displayed in header
  baseDir?: string;           // Base directory for relative paths
  outputDir?: string;         // Default: "./blockbook-static"
}

CLI

# Start preview server
npx @layerx/slack-blockbook scripts/blockbook.ts

# Build static site
npx @layerx/slack-blockbook build scripts/blockbook.ts
npx @layerx/slack-blockbook build scripts/blockbook.ts --outDir ./dist

Requirements

  • Node.js >= 18

License

MIT

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

About

Storybook-like preview tool for Slack Block Kit development.

Resources

License

Stars

Watchers

Forks

Contributors