JSPM

  • Created
  • Published
  • Downloads 118337
  • Score
    100M100P100Q170928F
  • License MIT

Maintainable code for interactive Slack messages, modals, home tabs, and workflow steps. A must-have for the Slack Block Kit framework.

Package Exports

  • slack-block-builder

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (slack-block-builder) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Logo

Maintainable code for Slack interactive messages, modals, and home tabs.

Lightweight, zero-dependency library for declaratively building Slack Block Kit UI.

View the Docs Β»

Quick Start Guide Β· Request Feature Β· Report Bug

An example of using Block Builder


npm NPM codecov

πŸŽ‰ Block Builder Version 2.0 is now in beta! Learn about the new features and how to install it here.

Block Builder helps you keep your Slack app code for UI maintainable, testable, and reusable. It has a declarative, chainable syntax inspired by SwiftUI and is built for better UI architecture.

⚑   Features

  • Declarative SwiftUI inspired syntax.
  • The ability to build more complex flows using loops and conditionals.
  • A printPreviewURL() method that outputs a link to preview your UI on Slack's Block Kit Builder website for easier prototyping.
  • In-depth doc site at https://blockbuilder.dev.
  • Support for all current Slack Block Kit objects.
  • A great TypeScript experience.
  • Extensive JSDoc hints with explanations, validation rules, and quick links to full documentation.
  • Zero dependencies.

πŸš€   Coming Soon

  • Paginator component.
  • Accordion component.

🎁   Benefits

  • Write three times less code.
  • Build more sophistocated, elegant flows.
  • Design better UI architecture for your Slack apps.
  • Focus more on code in your IDE than on studying the Slack API docs.
  • Easily integrate localizations into your app.

☎️   Let's Talk?

Feedback – love it! Aside from GitHub Issues, there are Slack channels available in popular bot communities to discuss Block Builder – we'll see you there! πŸ™Œ

πŸ’Ύ   Installation

Using NPM:

npm install --save slack-block-builder

Using Yarn:

yarn add slack-block-builder

πŸ‘Ύ   Usage

For full documentation, make sure you head over to https://blockbuilder.dev.

Importing

The functions for creating objects can be both imported directly or through an object that groups them by category.

// Importing exposed groups of objects

import { Surfaces, Blocks, Elements, Bits, Utilities } from 'slack-block-builder';

// Importing objects top-level

import { Modal, Section, Actions, Button } from 'slack-block-builder';

Group Explanations

Surfaces – Contains functions for creating modals, messages, home tabs, and workflow steps.

Blocks – Layout blocks used to organize the UI.

Elements – UI elements that are used to capture user interaction.

Bits – These are composition objects and other bits and pieces from Slack's docs. Included are Attachment, Options, OptionGroup, and ConfirmationDialog. They felt like they were deserving of their own category.

Utilities – A group of utility functions. See Utility Functions.

Block Kit Support and Reference

Below is a list of supported objects and how to access them in Block Builder:

Name Type Support Accessed Via
Home Tab Surface βœ… Surfaces.HomeTab()
Message Surface βœ… Surfaces.Message()
Modal Surface βœ… Surfaces.Modal()
Workflow Step Surface βœ… Surfaces.WorkflowStep()
Actions Block βœ… Blocks.Actions()
Context Block βœ… Blocks.Context()
Divider Block βœ… Blocks.Divider()
File Block βœ… Blocks.File()
Header Block βœ… Blocks.Header()
Image Block βœ… Blocks.Image()
Input Block βœ… Blocks.Input()
Section Block βœ… Blocks.Section()
Button Element βœ…οΈ Elements.Button()
Checkboxes Element βœ… Elements.Checkboxes()
Date Picker Element βœ… Elements.DatePicker()
Time Picker Element βœ… Elements.TimePicker()
Image Element βœ… Elements.Img()
Overflow Menu Element βœ… Elements.OverflowMenu()
Radio Buttons Element βœ… Elements.RadioButtons()
Plain-Text Input Element βœ… Elements.TextInput()
Select Menus Element βœ… Elements.[Type]Select()
Multi-Select Menus Element βœ… Elements.[Type]MultiSelect()
Option Composition Object βœ… Bits.Option()
Confirm Dialog Composition Object βœ… Bits.ConfirmationDialog()
Option Group Composition Object βœ… Bits.OptionGroup()
Attachment Legacy Feature βœ… Bits.Attachment()

Creating a Simple Interactive Message

Let's take a look at how to compose an interactive message. Even though Slack now has modals, these have always been the basis for Slack apps.

Functions that return Block Kit objects have setter methods for all of the properties, but also support parameters that are passed into the constructor for properties with primitive types.

import { Message, Blocks, Elements } from 'slack-block-builder';

const myMessage = ({ channel, dangerLevel }) => {
  return Message()
    .channel(channel)
    .text('Alas, my friend.')
    .blocks(
      Blocks.Section()
        .text('One does not simply walk into Slack and click a button.'),
      Blocks.Section()
        .text('At least that\'s what my friend Slackomir said βš”οΈ'),
      Blocks.Divider(),
      Blocks.Actions()
        .elements(
          Elements.Button()
            .text('Sure One Does')
            .actionId('gotClicked')
            .danger(dangerLevel > 42), // Optional argument, defaults to 'true'
          Elements.Button()
            .text('One Does Not')
            .actionId('scaredyCat')
            .primary()))
    .asUser()
    .buildToJSON();
};

And now an example with using both the setter methods and passing parameters into the functions at initiation:

import { Message, Blocks, Elements } from 'slack-block-builder';

const myShorterMessage = ({ channel, dangerLevel }) => {
  return Message({ channel, text: 'Alas, my friend.' })
    .blocks(
      Blocks.Section({ text: 'One does not simply walk into Slack and click a button.' }),
      Blocks.Section({ text: 'At least that\'s what my friend Slackomir said βš”οΈ' }),
      Blocks.Divider(),
      Blocks.Actions()
        .elements(
          Elements.Button({ text: 'Sure One Does', actionId: 'gotClicked' })
            .danger(dangerLevel > 42), // Optional argument, defaults to 'true'
          Elements.Button({ text: 'One Does Not', actionId: 'scaredyCat' })
            .primary()))
    .asUser()
    .buildToJSON();
};

Both of these examples render the message below. And the best part? It only took 15 lines of code, as opposed to the 44 lines of JSON generated as a result.

An example of using Block Builder for Messages

View Example on Slack Block Kit Builder Website

Creating a Simple Modal

Let's take a look at how modals are created. Here we'll also take a look at working with Bits and with loops, by adding options with the Array.map() method.

You'll noticed that we've added an inline condition that returns an initial option only if one has been passed into the function. This is because all the setter methods prune values of undefined, uncovering opportunities for inline logic.

import { Modal, Blocks, Elements, Bits } from 'slack-block-builder';

const myShorterModal = ({ menuOptions, selected }) => {
  return Modal({ title: 'PizzaMate', submit: 'Get Fed' })
    .blocks(
      Blocks.Section({ text: 'Hey there, colleague!' }),
      Blocks.Section({ text: 'Hurray for corporate pizza! Let\'s get you fed and happy πŸ•' }),
      Blocks.Input({ label: 'What can we call you?' })
        .element(
          Elements.TextInput({ placeholder: 'Hi, my name is... (What?!) (Who?!)' })
            .actionId('name')),
      Blocks.Input({ label: 'Which floor are you on?' })
        .element(
          Elements.TextInput({ placeholder: 'HQ – Fifth Floor' })
            .actionId('floor')),
      Blocks.Input({ label: 'What\'ll you have?' })
        .element(
          Elements.StaticSelect({ placeholder: 'Choose your favorite...' })
            .actionId('item')
            .options(menuOptions
              .map((item) => Bits.Option({ text: item.name, value: item.id })))
            .initialOption(selected && Bits.Option({ text: selected.name, value: selected.id }))))
    .buildToJSON();
};

Both of these examples render the modal below.

An example of using Block Builder for Modals

View Example on Slack Block Kit Builder Website

Utility Functions

The Utilities object contains various utility functions. Currently, there are two:

BlockCollection() – Accepts multiple arguments or an array of blocks and returns them in an array, in their built state.

AttachmentCollection() – Accepts multiple arguments or an array of attachments and returns them in an array, in their built state.

These two functions are useful when you wish to keep surface or view configuration separate from UI representation.

An example using Slack's WebClient from their SDK for Node.js:

import { BlockCollection, AttachmentCollection, Blocks } from 'slack-block-builder';
import { WebClient } from '@slack/web-api';

const client = new WebClient(process.env.SLACK_TOKEN);

client.chat.postMessage({
  channel: 'ABCDEFG',
  text: 'Hello, my dear, sweet world!',
  blocks: BlockCollection( /* Pass in blocks */ ),
  attachments: AttachmentCollection( /* Pass in attachments */ ),
})
.then((response) => console.log(response))
.catch((error) => console.log(error));

Another example where you might find BlockCollection() helpful is when unfurling links in messages:

import { BlockCollection, Blocks } from 'slack-block-builder';
import { WebClient } from '@slack/web-api';

const client = new WebClient(process.env.SLACK_TOKEN);

const unfurl = ({ channel, ts, url }) => client.chat.unfurl({
  channel,
  ts,
  unfurls: { [url]: BlockCollection( /* Pass in blocks */ ) },
})
.then((response) => console.log(response))
.catch((error) => console.log(error));

Bolt for JavaScript – A simple framework for building Slack apps, developed by Slack themselves.

Node Slack SDK – A great and powerful SDK for building Slack Apps from the ground up.

πŸ”₯   Acknowledgements

@korywka Taras Neporozhniy (@korywka) - For help and ideas along the way!

@ft502 Alexey Chernyshov (@ft502 on Dribbble) - For such a beautiful logo!

@slackhq SlackHQ (@slackhq) - For such a wonderful product and API!

βœ’οΈ   Author

@raycharius Ray East (@raycharius) - Huge Fan of Slack and Block Builder Maintainer