Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Types: split single index.ts file into files based on function/category #1656

Merged
merged 4 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 224 additions & 0 deletions packages/types/src/block-kit/block-elements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
// This file contains objects documented here: https://api.slack.com/reference/block-kit/block-elements
// TODO: go through https://api.slack.com/reference/block-kit/block-elements and
// - ensure JSdocs are up to date / added,
// - define missing objects, and
// - add further TODOs for future improvements / breaking changes, in prep for next major release

import { Action, Confirmable, Dispatchable, Focusable, Placeholdable } from './extensions';
import { DispatchActionConfig, Option, PlainTextElement, PlainTextOption } from './composition-objects';

export interface Button extends Action, Confirmable {
type: 'button';
text: PlainTextElement;
value?: string;
url?: string;
style?: 'danger' | 'primary';
accessibility_label?: string;
}

export interface Checkboxes extends Action, Confirmable, Focusable {
type: 'checkboxes';
initial_options?: Option[];
options: Option[];
}

export interface Datepicker extends Action, Confirmable, Focusable, Placeholdable {
type: 'datepicker';
initial_date?: string;
}

/**
* @description An element that allows the selection of a time of day formatted as a UNIX timestamp. On desktop
* clients, this time picker will take the form of a dropdown list and the date picker will take the form of a dropdown
* calendar. Both options will have free-text entry for precise choices. On mobile clients, the time picker and date
* picker will use native UIs.
* {@link https://api.slack.com/reference/block-kit/block-elements#datetimepicker}
*/
export interface DateTimepicker extends Action, Confirmable, Focusable {
type: 'datetimepicker';
/**
* @description The initial date and time that is selected when the element is loaded, represented as a UNIX
* timestamp in seconds. This should be in the format of 10 digits, for example 1628633820 represents the date and
* time August 10th, 2021 at 03:17pm PST.
*/
initial_date_time?: number;
}

/**
* @description An email input element, similar to the {@see PlainTextInput} element, creates a single line field where
* a user can enter an email address.
* {@link https://api.slack.com/reference/block-kit/block-elements#email}
*/
export interface EmailInput extends Action, Dispatchable, Focusable, Placeholdable {
type: 'email_text_input';
/**
* @description The initial value in the email input when it is loaded.
*/
initial_value?: string;
}

export interface ImageElement {
type: 'image';
image_url: string;
alt_text: string;
}

/*
* Multi-select and Select menus follow
*/

// Selects and Multiselects are available in different surface areas so I've separated them here
export type Select = UsersSelect | StaticSelect | ConversationsSelect | ChannelsSelect | ExternalSelect;

export type MultiSelect =
MultiUsersSelect | MultiStaticSelect | MultiConversationsSelect | MultiChannelsSelect | MultiExternalSelect;

export interface UsersSelect extends Action, Confirmable, Focusable, Placeholdable {
type: 'users_select';
initial_user?: string;
}

export interface MultiUsersSelect extends Action, Confirmable, Focusable, Placeholdable {
type: 'multi_users_select';
initial_users?: string[];
max_selected_items?: number;
}

export interface StaticSelect extends Action, Confirmable, Focusable, Placeholdable {
type: 'static_select';
initial_option?: PlainTextOption;
options?: PlainTextOption[];
option_groups?: {
label: PlainTextElement;
options: PlainTextOption[];
}[];
}

export interface MultiStaticSelect extends Action, Confirmable, Focusable, Placeholdable {
type: 'multi_static_select';
initial_options?: PlainTextOption[];
options?: PlainTextOption[];
option_groups?: {
label: PlainTextElement;
options: PlainTextOption[];
}[];
max_selected_items?: number;
}

export interface ConversationsSelect extends Action, Confirmable, Focusable, Placeholdable {
type: 'conversations_select';
initial_conversation?: string;
response_url_enabled?: boolean;
default_to_current_conversation?: boolean;
filter?: {
include?: ('im' | 'mpim' | 'private' | 'public')[];
exclude_external_shared_channels?: boolean;
exclude_bot_users?: boolean;
};
}

export interface MultiConversationsSelect extends Action, Confirmable, Focusable, Placeholdable {
type: 'multi_conversations_select';
initial_conversations?: string[];
max_selected_items?: number;
default_to_current_conversation?: boolean;
filter?: {
include?: ('im' | 'mpim' | 'private' | 'public')[];
exclude_external_shared_channels?: boolean;
exclude_bot_users?: boolean;
};
}

export interface ChannelsSelect extends Action, Confirmable, Focusable, Placeholdable {
type: 'channels_select';
initial_channel?: string;
}

export interface MultiChannelsSelect extends Action, Confirmable, Focusable, Placeholdable {
type: 'multi_channels_select';
initial_channels?: string[];
max_selected_items?: number;
}

export interface ExternalSelect extends Action, Confirmable, Focusable, Placeholdable {
type: 'external_select';
initial_option?: PlainTextOption;
min_query_length?: number;
}

export interface MultiExternalSelect extends Action, Confirmable, Focusable, Placeholdable {
type: 'multi_external_select';
initial_options?: PlainTextOption[];
min_query_length?: number;
max_selected_items?: number;
}

/*
* End of select/multi-select menus
*/

/**
* @description A number input element, similar to the {@see PlainTextInput} element, creates a single line field where
* a user can a number. This input elements accepts floating point numbers, for example, 0.25, 5.5, and -10 are all
* valid input values. Decimal numbers are only allowed when `is_decimal_allowed` is equal to `true`.
* {@link https://api.slack.com/reference/block-kit/block-elements#number}
*/
export interface NumberInput extends Action, Dispatchable, Focusable, Placeholdable {
type: 'number_input';
/**
* @description Decimal numbers are allowed if this property is `true`, set the value to `false` otherwise.
*/
is_decimal_allowed: boolean;
/**
* @description The initial value in the input when it is loaded.
*/
initial_value?: string;
/**
* @description The minimum value, cannot be greater than `max_value`.
*/
min_value?: string;
/**
* @description The maximum value, cannot be less than `min_value`.
*/
max_value?: string;
}

export interface Overflow extends Action, Confirmable {
type: 'overflow';
options: PlainTextOption[];
}

export interface PlainTextInput extends Action, Dispatchable, Focusable, Placeholdable {
type: 'plain_text_input';
initial_value?: string;
multiline?: boolean;
min_length?: number;
max_length?: number;
dispatch_action_config?: DispatchActionConfig;
focus_on_load?: boolean;
}

export interface RadioButtons extends Action, Confirmable, Focusable {
type: 'radio_buttons';
initial_option?: Option;
options: Option[];
}

export interface Timepicker extends Action, Confirmable, Focusable, Placeholdable {
type: 'timepicker';
initial_time?: string;
timezone?: string;
}

/**
* @description A URL input element, similar to the {@see PlainTextInput} element, creates a single line field where
* a user can enter URL-encoded data.
* {@link https://api.slack.com/reference/block-kit/block-elements#url}
*/
export interface URLInput extends Action, Dispatchable, Focusable, Placeholdable {
type: 'url_text_input';
/**
* @description The initial value in the URL input when it is loaded.
*/
initial_value?: string;
}
89 changes: 89 additions & 0 deletions packages/types/src/block-kit/blocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// This file contains objects documented here: https://api.slack.com/reference/block-kit/blocks
// TODO: go through https://api.slack.com/reference/block-kit/blocks and
// - ensure JSdocs are up to date / added,
// - define missing objects, and
// - add further TODOs for future improvements / breaking changes, in prep for next major release

import { PlainTextElement, MrkdwnElement } from './composition-objects';
import { Button, Checkboxes, Datepicker, DateTimepicker, EmailInput, ImageElement, MultiSelect, NumberInput, Overflow, PlainTextInput, RadioButtons, Select, Timepicker, URLInput } from './block-elements';
import { Action } from './extensions';

export interface Block {
type: string;
block_id?: string;
}

export type KnownBlock = ImageBlock | ContextBlock | ActionsBlock | DividerBlock |
SectionBlock | InputBlock | FileBlock | HeaderBlock | VideoBlock;

export interface ActionsBlock extends Block {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems worth it to adding additional annotation to more easily find the documentation link while we're at it?

Fine to punt to the later TODO moment referenced in the comments above as well.

Suggested change
export interface ActionsBlock extends Block {
// Reference: https://api.slack.com/reference/block-kit/blocks#actions
export interface ActionsBlock extends Block {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes exactly, I will be doing exactly these kind of changes in the next pull request 😄 I didn't want to add more additional lines in this specific PR as the diff would be too confusing given the movement of code across files. I think that in the next PR, though, these kinds of documentation additions you suggest would be clearer and easier to review.

type: 'actions';
elements: (Button | Overflow | Datepicker | Timepicker | DateTimepicker | Select | RadioButtons | Checkboxes
| Action)[];
}

export interface ContextBlock extends Block {
type: 'context';
elements: (ImageElement | PlainTextElement | MrkdwnElement)[];
}

export interface DividerBlock extends Block {
type: 'divider';
}

export interface FileBlock extends Block {
type: 'file';
source: string; // 'remote'
external_id: string;
}

export interface HeaderBlock extends Block {
type: 'header';
text: PlainTextElement;
}

export interface ImageBlock extends Block {
type: 'image';
image_url: string;
alt_text: string;
title?: PlainTextElement;
}

export interface InputBlock extends Block {
type: 'input';
label: PlainTextElement;
hint?: PlainTextElement;
optional?: boolean;
element: Select | MultiSelect | Datepicker | Timepicker | DateTimepicker | PlainTextInput | URLInput | EmailInput
| NumberInput | RadioButtons | Checkboxes;
dispatch_action?: boolean;
}

export interface SectionBlock extends Block {
type: 'section';
text?: PlainTextElement | MrkdwnElement; // either this or fields must be defined
fields?: (PlainTextElement | MrkdwnElement)[]; // either this or text must be defined
accessory?: Button
| Overflow
| Datepicker
| Timepicker
| Select
| MultiSelect
| Action
| ImageElement
| RadioButtons
| Checkboxes;
}

export interface VideoBlock extends Block {
type: 'video';
video_url: string;
thumbnail_url: string;
alt_text: string;
title: PlainTextElement;
title_url?: string;
author_name?: string;
provider_name?: string;
provider_icon_url?: string;
description?: PlainTextElement;
}
57 changes: 57 additions & 0 deletions packages/types/src/block-kit/composition-objects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// This file contains objects documented here: https://api.slack.com/reference/block-kit/composition-objects
// TODO: go through https://api.slack.com/reference/block-kit/composition-objects and
// - ensure JSdocs are up to date / added,
// - define missing objects, and
// - add further TODOs for future improvements / breaking changes, in prep for next major release

export interface Confirm {
title?: PlainTextElement;
text: PlainTextElement | MrkdwnElement;
confirm?: PlainTextElement;
deny?: PlainTextElement;
style?: 'primary' | 'danger';
}

/**
* @description Determines when an input element will return a
* {@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` interaction payload}.
*/
export interface DispatchActionConfig {
/**
* @description An array of interaction types that you would like to receive a
* {@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` payload} for. Should be
* one or both of:
* `on_enter_pressed` — payload is dispatched when user presses the enter key while the input is in focus. Hint
* text will appear underneath the input explaining to the user to press enter to submit.
* `on_character_entered` — payload is dispatched when a character is entered (or removed) in the input.
*/
trigger_actions_on?: ('on_enter_pressed' | 'on_character_entered')[];
}

export interface MrkdwnOption {
text: MrkdwnElement;
value?: string;
url?: string;
description?: PlainTextElement;
}

export interface PlainTextOption {
text: PlainTextElement;
value?: string;
url?: string;
description?: PlainTextElement;
}

export type Option = MrkdwnOption | PlainTextOption;

export interface PlainTextElement {
type: 'plain_text';
text: string;
emoji?: boolean;
}

export interface MrkdwnElement {
type: 'mrkdwn';
text: string;
verbatim?: boolean;
}
Loading
Loading