Skip to content

Commit

Permalink
Merge pull request #70 from raycharius/components
Browse files Browse the repository at this point in the history
✨ Paginator, EasyPaginator, and Accordion UI Components
  • Loading branch information
raycharius authored Oct 3, 2021
2 parents bb44764 + 515cc19 commit 533922b
Show file tree
Hide file tree
Showing 61 changed files with 4,766 additions and 61 deletions.
124 changes: 101 additions & 23 deletions README.md

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
ignore:
- ".github/"
- "tests/"
- "docs/"
- "docs-generator/"
- "resources/"

coverage:
status:
project:
default:
threshold: 1.0%
threshold: 5.0%
2 changes: 1 addition & 1 deletion docs-generator/templates/builder-class-reference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// @ts-ignore
export default `# {{displayName}}
?> **Note:** This document is a reference to the \`{{name}}\` object in **Block Builder**. For information on the business logic for the **{{displayName}}** in the context of the Slack Block Kit framework, visit [the {{displayName}} docs]({{slackLink}}) on Slack's doc site.
?> **Note:** This document is a reference to the \`{{name}}\` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the {{displayName}} docs]({{slackLink}}) on Slack's doc site.
### Creating an Instance
Expand Down
5 changes: 5 additions & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@
* [Confirmation Dialog](bits/confirmation-dialog.md "Block Builder – Confirmation Dialog – Maintainable JavaScript Code for Slack Block Kit")
* [Option](bits/option.md "Block Builder – Option – Maintainable JavaScript Code for Slack Block Kit")
* [Option Group](bits/option-group.md "Block Builder – Option Group – Maintainable JavaScript Code for Slack Block Kit")

* **Component References**
* [Paginator](components/paginator.md "Block Builder – Paginator – Maintainable JavaScript Code for Slack Block Kit")
* [Easy Paginator](components/easy-paginator.md "Block Builder – Easy Paginator – Maintainable JavaScript Code for Slack Block Kit")
* [Accordion](components/accordion.md "Block Builder – Accordion – Maintainable JavaScript Code for Slack Block Kit")

* **Other**
* [Block Collection](other/block-collection.md "Block Builder – Block Collection – Maintainable JavaScript Code for Slack Block Kit")
Expand Down
2 changes: 1 addition & 1 deletion docs/bits/attachment.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Attachment

?> **Note:** This document is a reference to the `AttachmentBuilder` object in **Block Builder**. For information on the business logic for the **Attachment** in the context of the Slack Block Kit framework, visit [the Attachment docs](https://api.slack.com/reference/messaging/attachments) on Slack's doc site.
?> **Note:** This document is a reference to the `AttachmentBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Attachment docs](https://api.slack.com/reference/messaging/attachments) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/bits/confirmation-dialog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Confirmation Dialog

?> **Note:** This document is a reference to the `ConfirmationDialogBuilder` object in **Block Builder**. For information on the business logic for the **Confirmation Dialog** in the context of the Slack Block Kit framework, visit [the Confirmation Dialog docs](https://api.slack.com/reference/block-kit/composition-objects#confirm) on Slack's doc site.
?> **Note:** This document is a reference to the `ConfirmationDialogBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Confirmation Dialog docs](https://api.slack.com/reference/block-kit/composition-objects#confirm) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/bits/option-group.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Option Group

?> **Note:** This document is a reference to the `OptionGroupBuilder` object in **Block Builder**. For information on the business logic for the **Option Group** in the context of the Slack Block Kit framework, visit [the Option Group docs](https://api.slack.com/reference/block-kit/composition-objects#option_group) on Slack's doc site.
?> **Note:** This document is a reference to the `OptionGroupBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Option Group docs](https://api.slack.com/reference/block-kit/composition-objects#option_group) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/bits/option.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Option

?> **Note:** This document is a reference to the `OptionBuilder` object in **Block Builder**. For information on the business logic for the **Option** in the context of the Slack Block Kit framework, visit [the Option docs](https://api.slack.com/reference/block-kit/composition-objects#option) on Slack's doc site.
?> **Note:** This document is a reference to the `OptionBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Option docs](https://api.slack.com/reference/block-kit/composition-objects#option) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/blocks/actions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Actions

?> **Note:** This document is a reference to the `ActionsBuilder` object in **Block Builder**. For information on the business logic for the **Actions** in the context of the Slack Block Kit framework, visit [the Actions docs](https://api.slack.com/reference/block-kit/blocks#actions) on Slack's doc site.
?> **Note:** This document is a reference to the `ActionsBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Actions docs](https://api.slack.com/reference/block-kit/blocks#actions) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/blocks/context.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Context

?> **Note:** This document is a reference to the `ContextBuilder` object in **Block Builder**. For information on the business logic for the **Context** in the context of the Slack Block Kit framework, visit [the Context docs](https://api.slack.com/reference/block-kit/blocks#context) on Slack's doc site.
?> **Note:** This document is a reference to the `ContextBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Context docs](https://api.slack.com/reference/block-kit/blocks#context) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/blocks/divider.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Divider

?> **Note:** This document is a reference to the `DividerBuilder` object in **Block Builder**. For information on the business logic for the **Divider** in the context of the Slack Block Kit framework, visit [the Divider docs](https://api.slack.com/reference/block-kit/blocks#divider) on Slack's doc site.
?> **Note:** This document is a reference to the `DividerBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Divider docs](https://api.slack.com/reference/block-kit/blocks#divider) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/blocks/file.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# File

?> **Note:** This document is a reference to the `FileBuilder` object in **Block Builder**. For information on the business logic for the **File** in the context of the Slack Block Kit framework, visit [the File docs](https://api.slack.com/reference/block-kit/blocks#file) on Slack's doc site.
?> **Note:** This document is a reference to the `FileBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the File docs](https://api.slack.com/reference/block-kit/blocks#file) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/blocks/header.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Header

?> **Note:** This document is a reference to the `HeaderBuilder` object in **Block Builder**. For information on the business logic for the **Header** in the context of the Slack Block Kit framework, visit [the Header docs](https://api.slack.com/reference/block-kit/blocks#header) on Slack's doc site.
?> **Note:** This document is a reference to the `HeaderBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Header docs](https://api.slack.com/reference/block-kit/blocks#header) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/blocks/image.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Image

?> **Note:** This document is a reference to the `ImageBuilder` object in **Block Builder**. For information on the business logic for the **Image** in the context of the Slack Block Kit framework, visit [the Image docs](https://api.slack.com/reference/block-kit/blocks#image) on Slack's doc site.
?> **Note:** This document is a reference to the `ImageBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Image docs](https://api.slack.com/reference/block-kit/blocks#image) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/blocks/input.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Input

?> **Note:** This document is a reference to the `InputBuilder` object in **Block Builder**. For information on the business logic for the **Input** in the context of the Slack Block Kit framework, visit [the Input docs](https://api.slack.com/reference/block-kit/blocks#input) on Slack's doc site.
?> **Note:** This document is a reference to the `InputBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Input docs](https://api.slack.com/reference/block-kit/blocks#input) on Slack's doc site.

### Creating an Instance

Expand Down
2 changes: 1 addition & 1 deletion docs/blocks/section.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Section

?> **Note:** This document is a reference to the `SectionBuilder` object in **Block Builder**. For information on the business logic for the **Section** in the context of the Slack Block Kit framework, visit [the Section docs](https://api.slack.com/reference/block-kit/blocks#section) on Slack's doc site.
?> **Note:** This document is a reference to the `SectionBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Section docs](https://api.slack.com/reference/block-kit/blocks#section) on Slack's doc site.

### Creating an Instance

Expand Down
141 changes: 141 additions & 0 deletions docs/components/accordion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Accordion

?> **Note:** This document is a reference for using the `Accordion` component in **Block Builder**. For information on Slack's Block Kit framework and how this carries over to the API, visit [the official doc site](https://api.slack.com/block-kit) from Slack.

**Block Builder** provides a component for creating a UI with items that can be expanded and collapsed, called `Accordion`. It is one of a few UI components available in the library:

The `Accordion`:

* Generates a ready-to-use UI for expandable/collapsable content.
* Lets you pass in an array of objects and a function to use to build the UI for each item in the list when expanded.
* Provides context to your action IDs that can be passed back to your app's backend when a user clicks a button to expand or collapse an item that can be then be passed back into the accordion component to generate the next UI state.
* Supports the option to collapse all items when a new one is expanded.
* Allows you to customize the UI copy.

### Example

```javascript
import { Modal, Blocks, Accordion } from 'slack-block-builder';

export default ({ faqs, expandedItems }) => Modal({ title: 'FAQ' })
.blocks(
Blocks.Section({ text: 'Hi! :wave: And welcome to the FAQ section! Take a look around and if you don\'t find what you need, feel free to open an issue on GitHub.'}),
Blocks.Divider(),
Accordion({
items: faqs,
expandedItems: expandedItems || [], // In this case, the value is [1]
collapseOnExpand: true,
titleText: ({ item }) => `*${item.question}*`,
actionId: ({ expandedItems }) => JSON.stringify({ action: 'render-faqs', expandedItems }),
blocksForExpanded: ({ item }) => [
Blocks.Section({ text: `${item.answer}` }),
],
}).getBlocks())
.close('Done')
.buildToJSON();
```

The above code example produces the following UI. The `action_id` for each button contains data (an array of integers) about the next state of the UI.

![Modal Without Team Roster](../resources/images/accordion-modal-example.png)

### Using the Accordion

An accordion component can be created using the `Accordion` function, which is available as both a top-level import and as a member of the `Components` object.

The `getBlocks()` method returns the result blocks to be added to the intended surface object.

```javascript
import { Accordion } from 'slack-block-builder';

const accordion = Accordion(params);
const blocks = accordion.getBlocks();
```

```javascript
import { Accordion } from 'slack-block-builder';

const accordion = Components.Accordion(params);
const blocks = accordion.getBlocks();
```

When using with TypeScript, you'll want to dictate the shape of the objects being passed in:

```javascript
import { Accordion } from 'slack-block-builder';

const accordion = Accordion<Entity>(params);
const blocks = accordion.getBlocks();
```

### Params

`items`*Array*

An array of the items that are to be included in the expandable list.

`expandedItems`*Array*

An array of integers (indexes of expanded items) that dictates which items should be expanded. Should default to either `[]` for all items to be collapsed, or `[items[index]]` for a default expanded item. Then it should be updated with each view update using the data provided in the `action_id` of each button.

`titleText`*Function*

This is a function called to create the `action_id` of the Next and Previous buttons. See below for more details.

`actionId`*Function*

This is a function called to create the `action_id` of the buttons used to expand or collapse an item. See below for more details.

`blocksForExpanded`*Function*

The function that is called for each expanded item that should return the blocks to be displayed. See below for more details.

`collapseOnExpand`*Boolean* `Optional`

When set to `true`, only one item will be expanded at any given time. Expanding a new item will collapse the currently expanded one. Defaults to `false`.

`expandButtonText`*String* `Optional`

Used to customize the text for the expand button, which defaults to `'More'`.

`collapseButton`*String* `Optional`

Used to customize the text for the collapse button, which defaults to `'Close'`.

### The `titleText` Function

The `titleText` parameter accepts a function that takes an object that contains one of the items from the data set and returns a string to display as the title, next to the collapse/expand button. The object, at the moment, contains only one parameter, `item`, which is the item for which the title will be displayed.

### The `actionId` Function

The point of the `actionId` parameter is to provide a way to persist data back to your app's backend when a user clicks a button to expand or collapse an item.

The `actionId` parameter accepts a function that takes an object with, at the moment, a single parameter `expandedItems`, which is an arrray of integers, and returns a string that is then passed into the `action_id` of the collapse or expand buttons.

The data can be mutated into a string however you see it, depending on how your application works, for example:

```javascript
const actionId = ({ expandedItems }) => JSON.stringify({
expandedItems,
action: 'render-certain-modal',
});
```

Which would result in the following value, on a modal where the third item is expanded, and the fifth is clicked:

```javascript
// if collapseOnExpand is set to true

'{"expandedItems":[4],"action":"render-certain-modal"}'

// if collapseOnExpand is set to false

'{"expandedItems":[2,4],"action":"render-certain-modal"}'
```

Please visit [the demo repo on GitHub](https://github.com/raycharius/slack-block-builder-demo) to view an example of how this can be used.

### The `blocksForExpanded` Function

The `blocksForExpanded` parameter accepts a function that takes an object that contains one of the items from the data set and returns an array of blocks to display for that item when it is expanded. The object, at the moment, contains only one parameter, `item`, which is the item for which the blocks will be created.

70 changes: 70 additions & 0 deletions docs/components/easy-paginator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Easy Paginator

?> **Note:** This document is a reference for using the `Paginator` component in **Block Builder**. For information on Slack's Block Kit framework and how this carries over to the API, visit [the official doc site](https://api.slack.com/block-kit) from Slack.

**Block Builder** provides a component for creating paginated content called the `Paginator`. It is one of a few UI components available in the library.

The `EasyPaginator` function provides another way to create paginated UI for smaller data sets, where paginating data on the database level is overhead. With the `EasyPaginator` function, you can simply pass in an entire data set and the component will take care of extracting the items to be displayed on the current page.

It works the exact same way as the `Paginator` component ([see the docs](../components/paginator.md)), except that there is no need to pass in the `totalItems` parameter:

### Example

```javascript
import { Modal, Blocks, Elements, EasyPaginator } from 'slack-block-builder';

export default ({ tasks, page, perPage }) => Modal({ title: 'Open Tasks' })
.blocks(
Blocks.Section({ text: 'Hi! :wave: And welcome to the FAQ section! Take a look around and if you don\'t find what you need, feel free to open an issue on GitHub.' }),
Blocks.Section({ text: `You currently have *${tasks.length} open task(s)*:` }),
EasyPaginator({
perPage,
items: tasks, // The entire data set
page: page || 1,
actionId: ({ page, offset }) => JSON.stringify({ action: 'render-tasks', page, offset }),
blocksForEach: ({ item }) => [
Blocks.Divider(),
Blocks.Section({ text: `*${item.title}*` })
.accessory(
Elements.Button({ text: 'View Details' })
.actionId('view-details')
.value(item.id.toString())),
Blocks.Section({ text: `*Due Date:* ${getDate(item.dueDate)}` }),
],
}).getBlocks())
.close('Done')
.buildToJSON();
```

The above code example produces the following UI. In addition, when either Next or Previous is clicked, the app's backend has access to the `page` and `offset` parameter passed into the button's `action_id`.

![Modal Without Team Roster](../resources/images/paginator-modal-example.png)

### Using the Easy Paginator

A paginator component can be created using the `EasyPaginator` function, which is available as both a top-level import and as a member of the `Components` object.

The `getBlocks()` method returns the result blocks to be added to the intended surface object.

```javascript
import { EasyPaginator } from 'slack-block-builder';

const paginator = EasyPaginator(params);
const blocks = paginator.getBlocks();
```

```javascript
import { Components } from 'slack-block-builder';

const paginator = Components.EasyPaginator(params);
const blocks = paginator.getBlocks();
```

When using with TypeScript, you'll want to dictate the shape of the objects being passed in:

```javascript
import { EasyPaginator } from 'slack-block-builder';

const paginator = EasyPaginator<Entity>(params);
const blocks = paginator.getBlocks();
```
Loading

0 comments on commit 533922b

Please sign in to comment.