From d554e3ee3b52b0121d79ec017a23a4a6b6b27ecc Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Thu, 7 Sep 2023 15:08:00 -0400 Subject: [PATCH 01/11] Adding jsdocs to Calls types. `avatar_url` for external Call user is optional --- packages/types/src/calls.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/types/src/calls.ts b/packages/types/src/calls.ts index f183787a9..9dc0ac949 100644 --- a/packages/types/src/calls.ts +++ b/packages/types/src/calls.ts @@ -1,11 +1,31 @@ +// These types represent users in Slack Calls, which is an API for showing 3rd party calls within the Slack client. +// More information on the API guide for Calls: https://api.slack.com/apis/calls +// and on User objects for use with Calls: https://api.slack.com/apis/calls#users + +/** + * @description For use in representing {@link https://api.slack.com/apis/calls#users users in a Slack Call}. + */ export type CallUser = CallUserSlack | CallUserExternal; export interface CallUserSlack { + /** + * @description The Slack encoded user ID, e.g. U1234ABCD. Set this if you have it or know it, otherwise, set + * `external_id` and `display_name`. + */ slack_id: string; } export interface CallUserExternal { + /** + * @description A unique ID created by your app to represent your users. + */ external_id: string; + /** + * @description Name of the user to be displayed in the Call block in a message. + */ display_name: string; - avatar_url: string; + /** + * @description URL to an avatar image of the user. + */ + avatar_url?: string; } From 959c2d8cbaa8f1835012d2cdb12bbd58d4ab935d Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Thu, 7 Sep 2023 15:29:17 -0400 Subject: [PATCH 02/11] jsdocs for message metadata. --- packages/types/src/message-metadata.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/types/src/message-metadata.ts b/packages/types/src/message-metadata.ts index af0be7b0b..66e2a8758 100644 --- a/packages/types/src/message-metadata.ts +++ b/packages/types/src/message-metadata.ts @@ -1,5 +1,17 @@ +/** + * @description Application-specific data to attach to Slack message. + * @see {@link https://api.slack.com/metadata/using Using Metadata} + * @see {@link https://api.slack.com/reference/metadata#payload_structure Metadata Payload Structure} + */ export interface MessageMetadata { + /** + * @description A human readable alphanumeric string representing your application's metadata event. + * The value of this field may appear in the UI to developers. + */ event_type: string; + /** + * @description A free-form object containing whatever data your application wishes to attach to messages. + */ event_payload: { [key: string]: string | number | boolean | MessageMetadataEventPayloadObject | MessageMetadataEventPayloadObject[]; } From 09bc90bab59ffa5a0ec9d3a241ea954d283e1c1a Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Thu, 7 Sep 2023 17:29:37 -0400 Subject: [PATCH 03/11] add todos and jsdocs to message attachments. --- packages/types/src/message-attachments.ts | 137 +++++++++++++++++++--- 1 file changed, 120 insertions(+), 17 deletions(-) diff --git a/packages/types/src/message-attachments.ts b/packages/types/src/message-attachments.ts index 17e5f9b0d..5fabb3b7a 100644 --- a/packages/types/src/message-attachments.ts +++ b/packages/types/src/message-attachments.ts @@ -1,40 +1,141 @@ import { PlainTextElement } from './block-kit/composition-objects'; import { Block, KnownBlock } from './block-kit/blocks'; +// TODO: breaking changes, use discriminated union for `fallback`, `text` and `block` properties, maybe LegacyAttachment +// vs. BlocksAttachment? as per https://api.slack.com/reference/messaging/attachments#legacy_fields +// "these fields are optional if you're including blocks as above. If you aren't, one of fallback or text are required" +// also further nested discriminated union types that could be helpful here: +// - LegacyAttachmentWithAuthor: if author_name is present, then author_icon and author_link are optional fields +// - LegacyAttachmentWithFooter: if footer is present, then footer_icon is an optional field +// - image_url and thumb_url cannot be used together /** * Add {@link https://api.slack.com/messaging/composing/layouts#attachments secondary attachments} to your messages in Slack. - * Message attachments are considered a legacy part of messaging functionality. They are not deprecated per se, but they may change in the future, in ways that reduce their visibility or utility. We recommend moving to {@see Block} constructs instead. Read more about {@link https://api.slack.com/messaging/composing/layouts#when-to-use-attachments when to use message attachments}. + * Message attachments are considered a legacy part of messaging functionality. They are not deprecated per se, but they may change in the future, in ways that reduce their visibility or utility. We recommend moving to Block Kit instead. Read more about {@link https://api.slack.com/messaging/composing/layouts#when-to-use-attachments when to use message attachments}. + * @see {@link https://api.slack.com/reference/messaging/attachments Secondary message attachments reference documentation} */ export interface MessageAttachment { + /** + * @description An array of {@link KnownBlock layout blocks} in the same format + * {@link https://api.slack.com/block-kit/building as described in the building blocks guide}. + */ blocks?: (KnownBlock | Block)[]; + /** + * @description A plain text summary of the attachment used in clients that + * don't show formatted text (e.g. mobile notifications). + */ fallback?: string; // either this or text must be defined + /** + * @description Changes the color of the border on the left side of this attachment from the default gray. Can either + * be one of `good` (green), `warning` (yellow), `danger` (red), or any hex color code (eg. `#439FE0`) + */ color?: 'good' | 'warning' | 'danger' | string; + /** + * @description Text that appears above the message attachment block. It can be formatted as plain text, + * or with {@link https://api.slack.com/reference/surfaces/formatting#basics `mrkdwn`} by including it in the `mrkdwn_in` field. + */ pretext?: string; + /** + * @description Small text used to display the author's name. + */ author_name?: string; - author_link?: string; // author_name must be present + /** + * @description A valid URL that will hyperlink the `author_name` text. Will only work if `author_name` is present. + */ + author_link?: string; + /** + * @description A valid URL that displays a small 16px by 16px image to the left of the `author_name` text. + * Will only work if `author_name` is present. + */ author_icon?: string; // author_name must be present - author_subname?: string; + author_subname?: string; // TODO: not documented in https://api.slack.com/reference/messaging/attachments + /** + * @description Large title text near the top of the attachment. + */ title?: string; + /** + * @description A valid URL that turns the `title` text into a hyperlink. + */ title_link?: string; // title must be present + /** + * @description The main body text of the attachment. It can be formatted as plain text, or with + * {@link https://api.slack.com/reference/surfaces/formatting#basics `mrkdwn`} by including it in the `mrkdwn_in` field. + * The content will automatically collapse if it contains 700+ characters or 5+ line breaks, and will display + * a "Show more..." link to expand the content. + */ text?: string; // either this or fallback must be defined - fields?: { - title: string; - value: string; - short?: boolean; - }[]; + /** + * @description An array of {@link MessageAttachmentField} that get displayed in a table-like way + * (see {@link https://api.slack.com/reference/messaging/attachments#example this example}). + * For best results, include no more than 2-3 field objects. + */ + fields?: MessageAttachmentField[]; + /** + * @description A valid URL to an image file that will be displayed at the bottom of the attachment. + * We support GIF, JPEG, PNG, and BMP formats. + * Large images will be resized to a maximum width of 360px or a maximum height of 500px, while still + * maintaining the original aspect ratio. Cannot be used with `thumb_url`. + */ image_url?: string; + /** + * @description A valid URL to an image file that will be displayed as a thumbnail on the right side of + * a message attachment. We currently support the following formats: GIF, JPEG, PNG, and BMP. + * The thumbnail's longest dimension will be scaled down to 75px while maintaining the aspect ratio of the image. + * The file size of the image must also be less than 500 KB. + * For best results, please use images that are already 75px by 75px. + */ thumb_url?: string; + /** + * @description Some brief text to help contextualize and identify an attachment. Limited to 300 characters, + * and may be truncated further when displayed to users in environments with limited screen real estate. + */ footer?: string; - footer_icon?: string; // footer must be present + /** + * @description A valid URL to an image file that will be displayed beside the `footer` text. + * Will only work if `footer` is present. We'll render what you provide at 16px by 16px. + * It's best to use an image that is similarly sized. + */ + footer_icon?: string; + /** + * @description A Unix timestamp that is used to relate your attachment to a specific time. + * The attachment will display the additional timestamp value as part of the attachment's footer. + * Your message's timestamp will be displayed in varying ways, depending on how far in the past or future it is, + * relative to the present. Form factors, like mobile versus desktop may also transform its rendered appearance. + */ ts?: string; - actions?: AttachmentAction[]; - callback_id?: string; - mrkdwn_in?: ('pretext' | 'text' | 'fields')[]; - app_unfurl_url?: string; - is_app_unfurl?: boolean; - app_id?: string; - bot_id?: string; - preview?: MessageAttachmentPreview; // https://api.slack.com/methods/chat.unfurl#markdown + actions?: AttachmentAction[]; // TODO: not documented in https://api.slack.com/reference/messaging/attachments + callback_id?: string; // TODO: not documented in https://api.slack.com/reference/messaging/attachments + /** + * @description Field names that should be {@link https://api.slack.com/reference/surfaces/formatting#basics formatted by `mrkdwn` syntax}. + * The fields that can be formatted in this way include the names of the `fields` property, or + * the `text` or `pretext` properties. + */ + mrkdwn_in?: ('pretext' | 'text' | 'fields')[]; // TODO: I think `fields` here is wrong? instead they should reference field names from `fields` + app_unfurl_url?: string; // TODO: not documented in https://api.slack.com/reference/messaging/attachments + is_app_unfurl?: boolean; // TODO: not documented in https://api.slack.com/reference/messaging/attachments + app_id?: string; // TODO: not documented in https://api.slack.com/reference/messaging/attachments + bot_id?: string; // TODO: not documented in https://api.slack.com/reference/messaging/attachments + preview?: MessageAttachmentPreview; // https://api.slack.com/methods/chat.unfurl#markdown TODO: not documented in https://api.slack.com/reference/messaging/attachments, also unclear why this links to chat.unfurl? +} + +/** + * @description A field object to include in a {@link MessageAttachment}. + * @see {@link https://api.slack.com/reference/messaging/attachments#field_objects Field objects reference}. + */ +export interface MessageAttachmentField { + /** + * @description Shown as a bold heading displayed in the field object. It cannot contain markup and + * will be escaped for you. + */ + title: string; + /** + * @description The text value displayed in the field object. It can be formatted as plain text, or with {@link https://api.slack.com/reference/surfaces/formatting#basics `mrkdwn`} by using the `mrkdwn_in` option of {@link MessageAttachment}. + */ + value: string; + /** + * @description Indicates whether the field object is short enough to be displayed side-by-side with + * other field objects. Defaults to `false`. + */ + short?: boolean; } // https://api.slack.com/methods/chat.unfurl#markdown @@ -46,6 +147,7 @@ export interface MessageAttachmentPreview { iconUrl?: string; } +// TODO: unclear what or how to use this export interface AttachmentAction { id?: string; confirm?: Confirmation; @@ -71,6 +173,7 @@ export interface OptionField { value: string; } +// Used in bolt-js block-action types export interface Confirmation { dismiss_text?: string; ok_text?: string; From 43eb84d751450b2bbc659b93d707987fd5f44ea4 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Thu, 14 Sep 2023 16:45:50 -0700 Subject: [PATCH 04/11] Adding JSdocs for existing properties for block kit composition objects. Factor out a new Descriptor interface for easier re-use. Dropping lots of TODOs and notes on future breaking changes. --- .../src/block-kit/composition-objects.ts | 112 ++++++++++++++++-- packages/types/src/message-attachments.ts | 3 +- 2 files changed, 101 insertions(+), 14 deletions(-) diff --git a/packages/types/src/block-kit/composition-objects.ts b/packages/types/src/block-kit/composition-objects.ts index f5ae3ffa0..85f902b2e 100644 --- a/packages/types/src/block-kit/composition-objects.ts +++ b/packages/types/src/block-kit/composition-objects.ts @@ -1,20 +1,46 @@ // 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 +// TODO: maybe consider this as a breaking change, but, what about aliasing Confirm to ConfirmationDialog or some such? +// and deprecating this interface? this would line up the terms between these types and api.slack.com +/** + * @description Defines a dialog that adds a confirmation step to interactive elements. + * @see {@link https://api.slack.com/reference/block-kit/composition-objects#confirm Confirmation dialog object reference}. + */ export interface Confirm { - title?: PlainTextElement; + /** + * @description A {@link PlainTextElement} text object that defines the dialog's title. + * Maximum length for this field is 100 characters. + */ + title?: PlainTextElement; // TODO: breaking change, title is required according to https://api.slack.com/reference/block-kit/composition-objects#confirm + /** + * @description A {@link PlainTextElement} text object that defines the explanatory text that appears in the confirm + * dialog. Maximum length for the `text` in this field is 300 characters. + */ text: PlainTextElement | MrkdwnElement; - confirm?: PlainTextElement; - deny?: PlainTextElement; + /** + * @description A {@link PlainTextElement} text object to define the text of the button that confirms the action. + * Maximum length for the `text` in this field is 30 characters. + */ + confirm?: PlainTextElement; // TODO: breaking change, text is required according to https://api.slack.com/reference/block-kit/composition-objects#confirm + /** + * @description A {@link PlainTextElement} text object to define the text of the button that cancels the action. + * Maximum length for the `text` in this field is 30 characters. + */ + deny?: PlainTextElement; // TODO: breaking change, deny is required according to https://api.slack.com/reference/block-kit/composition-objects#confirm + /** + * @description Defines the color scheme applied to the `confirm` button. A value of `danger` will display the button + * with a red background on desktop, or red text on mobile. A value of `primary` will display the button with a green + * background on desktop, or blue text on mobile. If this field is not provided, the default value will be `primary`. + */ 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}. + * @description Defines when a {@link PlainTextElement} will return a {@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` interaction payload}. + * @see {@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` interaction payload}. */ export interface DispatchActionConfig { /** @@ -28,30 +54,90 @@ export interface DispatchActionConfig { trigger_actions_on?: ('on_enter_pressed' | 'on_character_entered')[]; } -export interface MrkdwnOption { - text: MrkdwnElement; - value?: string; +interface OptionDescriptor { + /** + * @description A unique string value that will be passed to your app when this option is chosen. + * Maximum length for this field is 75 characters. + */ + value?: string; // TODO: breaking change - this value is required according to https://api.slack.com/reference/block-kit/composition-objects#option + /** + * @description Only available in overflow menus! A URL to load in the user's browser when the option is clicked. + * Maximum length for this field is 3000 characters. + */ url?: string; + /** + * @description A {@link PlainTextElement} that defines a line of descriptive text shown below the `text` field. + * Maximum length for the `text` within this field is 75 characters. + */ description?: PlainTextElement; } -export interface PlainTextOption { +export interface MrkdwnOption extends OptionDescriptor { + /** + * @description A {@link MrkdwnElement} that defines the text shown in the option on the menu. To be used with + * radio buttons and checkboxes. Maximum length for the `text` in this field is 75 characters. + */ + text: MrkdwnElement; +} + +export interface PlainTextOption extends OptionDescriptor { + /** + * @description A {@link PlainTextElement} that defines the text shown in the option on the menu. To be used with + * overflow, select and multi-select menus. Maximum length for the `text` in this field is 75 characters. + */ text: PlainTextElement; - value?: string; - url?: string; - description?: PlainTextElement; } +/** + * @description Defines a single item in a number of item selection elements. An object that represents a single + * selectable item in a select menu, multi-select menu, checkbox group, radio button group, or overflow menu. + * @see {@link https://api.slack.com/reference/block-kit/composition-objects#option Option object reference}. + */ export type Option = MrkdwnOption | PlainTextOption; +// TODO: (additive change) maybe worth adding a TextObject union for them, if they are meant to be used this way, +// as they seem to be documented together? https://api.slack.com/reference/block-kit/composition-objects#text +/** + * @description Defines an object containing some text. + * @see {@link https://api.slack.com/reference/block-kit/composition-objects#text Text object reference}. + */ export interface PlainTextElement { + /** + * @description The formatting to use for this text object. + */ type: 'plain_text'; + /** + * @description The text for the block. The minimum length is 1 and maximum length is 3000 characters. + */ text: string; + /** + * @description Indicates whether emojis in a text field should be escaped into the colon emoji format. + */ emoji?: boolean; } +/** + * @description Defines an object containing some text. + * @see {@link https://api.slack.com/reference/block-kit/composition-objects#text Text object reference}. + */ export interface MrkdwnElement { + /** + * @description The formatting to use for this text object. + */ type: 'mrkdwn'; + /** + * @description The text for the block. This field accepts any of the standard text formatting markup. + * The minimum length is 1 and maximum length is 3000 characters. + */ text: string; + /** + * @description When set to `false` (as is default) URLs will be auto-converted into links, conversation names will + * be link-ified, and certain mentions will be {@link https://api.slack.com/reference/surfaces/formatting#automatic-parsing automatically parsed}. + * Using a value of `true` will skip any preprocessing of this nature, although you can still include + * {@link https://api.slack.com/reference/surfaces/formatting#advanced manual parsing strings}. + */ verbatim?: boolean; } + +// TODO: add Option group type, and use it in this package. https://api.slack.com/reference/block-kit/composition-objects#option_group +// TODO: add Conversation filter type, and use it in this package. https://api.slack.com/reference/block-kit/composition-objects#filter_conversations diff --git a/packages/types/src/message-attachments.ts b/packages/types/src/message-attachments.ts index 5fabb3b7a..3b487131a 100644 --- a/packages/types/src/message-attachments.ts +++ b/packages/types/src/message-attachments.ts @@ -138,6 +138,7 @@ export interface MessageAttachmentField { short?: boolean; } +// TODO: unclear what this is or how to use this // https://api.slack.com/methods/chat.unfurl#markdown export interface MessageAttachmentPreview { type?: string; @@ -147,7 +148,7 @@ export interface MessageAttachmentPreview { iconUrl?: string; } -// TODO: unclear what or how to use this +// TODO: unclear what this is or how to use this export interface AttachmentAction { id?: string; confirm?: Confirmation; From 55dd0f0cc95a7d1f70839e426f86af3284572c3e Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Fri, 22 Sep 2023 15:49:36 -0400 Subject: [PATCH 05/11] Add OptionGroup type and a new ConversationFilter type, slightly more sophisticated, with discriminated union to more accurately reflect the either/or properties used within those. --- .../types/src/block-kit/block-elements.ts | 4 +- .../src/block-kit/composition-objects.ts | 55 ++++++++++++++++--- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/packages/types/src/block-kit/block-elements.ts b/packages/types/src/block-kit/block-elements.ts index 8eaa89c72..675b9c61c 100644 --- a/packages/types/src/block-kit/block-elements.ts +++ b/packages/types/src/block-kit/block-elements.ts @@ -110,7 +110,7 @@ export interface ConversationsSelect extends Action, Confirmable, Focusable, Pla initial_conversation?: string; response_url_enabled?: boolean; default_to_current_conversation?: boolean; - filter?: { + filter?: { // TODO: breaking change: replace with ConversationFilter object from composition-objects include?: ('im' | 'mpim' | 'private' | 'public')[]; exclude_external_shared_channels?: boolean; exclude_bot_users?: boolean; @@ -122,7 +122,7 @@ export interface MultiConversationsSelect extends Action, Confirmable, Focusable initial_conversations?: string[]; max_selected_items?: number; default_to_current_conversation?: boolean; - filter?: { + filter?: { // TODO: breaking change: replace with ConversationFilter object from composition-objects include?: ('im' | 'mpim' | 'private' | 'public')[]; exclude_external_shared_channels?: boolean; exclude_bot_users?: boolean; diff --git a/packages/types/src/block-kit/composition-objects.ts b/packages/types/src/block-kit/composition-objects.ts index 85f902b2e..6e6555400 100644 --- a/packages/types/src/block-kit/composition-objects.ts +++ b/packages/types/src/block-kit/composition-objects.ts @@ -1,9 +1,6 @@ // 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 -// - define missing objects, and -// - add further TODOs for future improvements / breaking changes, in prep for next major release -// TODO: maybe consider this as a breaking change, but, what about aliasing Confirm to ConfirmationDialog or some such? +// TODO: maybe a breaking change, but, what about aliasing Confirm to ConfirmationDialog or some such? // and deprecating this interface? this would line up the terms between these types and api.slack.com /** * @description Defines a dialog that adds a confirmation step to interactive elements. @@ -59,7 +56,7 @@ interface OptionDescriptor { * @description A unique string value that will be passed to your app when this option is chosen. * Maximum length for this field is 75 characters. */ - value?: string; // TODO: breaking change - this value is required according to https://api.slack.com/reference/block-kit/composition-objects#option + value?: string; // TODO: breaking change - value is required according to https://api.slack.com/reference/block-kit/composition-objects#option /** * @description Only available in overflow menus! A URL to load in the user's browser when the option is clicked. * Maximum length for this field is 3000 characters. @@ -95,8 +92,24 @@ export interface PlainTextOption extends OptionDescriptor { */ export type Option = MrkdwnOption | PlainTextOption; -// TODO: (additive change) maybe worth adding a TextObject union for them, if they are meant to be used this way, -// as they seem to be documented together? https://api.slack.com/reference/block-kit/composition-objects#text +/** + * @description Defines a way to group options in a select or multi-select menu. + * @see {@link https://api.slack.com/reference/block-kit/composition-objects#option_group Option group object reference}. + */ +export interface OptionGroup { + /** + * @description A {@link PlainTextElement} text object that defines the label shown above this group of options. + * Maximum length for the `text` in this field is 75 characters. + */ + label: PlainTextElement; + /** + * @description An array of {@link Option} that belong to this specific group. Maximum of 100 items. + */ + options: Option[]; +} + +// TODO: (additive change) maybe worth adding a TextObject union for both PlainTextElement and MrkdwnElement, if they +// are meant to be used this way, as they seem to be documented together? https://api.slack.com/reference/block-kit/composition-objects#text /** * @description Defines an object containing some text. * @see {@link https://api.slack.com/reference/block-kit/composition-objects#text Text object reference}. @@ -139,5 +152,29 @@ export interface MrkdwnElement { verbatim?: boolean; } -// TODO: add Option group type, and use it in this package. https://api.slack.com/reference/block-kit/composition-objects#option_group -// TODO: add Conversation filter type, and use it in this package. https://api.slack.com/reference/block-kit/composition-objects#filter_conversations +type Conversation = 'im' | 'mpim' | 'private' | 'public'; + +interface BaseConversationFilter { + /** + * @description Indicates which type of conversations should be included in the list. When this field is provided, any + * conversations that do not match will be excluded. You should provide an array of strings from the following options: + * `im`, `mpim`, `private`, and `public`. The array cannot be empty. + */ + include?: [Conversation, ...Conversation[]]; // TS gymnastics for "at least one item" + /** + * @description Indicates whether to exclude external {@link https://api.slack.com/enterprise/shared-channels shared channels} + * from conversation lists. This field will not exclude users from shared channels. Defaults to `false`. + */ + exclude_external_shared_channels?: boolean; + /** + * @description Indicates whether to exclude bot users from conversation lists. Defaults to `false`. + */ + exclude_bot_users?: boolean; +} + +/** + * @description Defines a filter for the list of options in a conversation selector menu. The menu can be either a + * conversations select menu or a conversations multi-select menu. + * @see {@link https://api.slack.com/reference/block-kit/composition-objects#filter_conversations Conversation filter object reference}. + */ +export type ConversationFilter = (BaseConversationFilter & Required>) | (BaseConversationFilter & Required>) | (BaseConversationFilter & Required>); From a3dab5ee0ea227f05771b8b10dddd7259697db74 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Mon, 25 Sep 2023 13:35:13 -0400 Subject: [PATCH 06/11] Many JSdocs added to block kit element types. Dropped many TODOs, highlighting those that would be improvements but breaking changes. Use inline `{@link}` jsdoc tags instead of inline `{@see}`. --- .../types/src/block-kit/block-elements.ts | 466 +++++++++++++++++- packages/types/src/block-kit/extensions.ts | 8 +- 2 files changed, 450 insertions(+), 24 deletions(-) diff --git a/packages/types/src/block-kit/block-elements.ts b/packages/types/src/block-kit/block-elements.ts index 675b9c61c..3668303ea 100644 --- a/packages/types/src/block-kit/block-elements.ts +++ b/packages/types/src/block-kit/block-elements.ts @@ -1,55 +1,125 @@ // 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'; +import { Option, PlainTextElement, PlainTextOption } from './composition-objects'; +// TODO: breaking change: `Action` the button extends from has an optional action_id, but is required for buttons. +/** + * @description Allows users a direct path to performing basic actions. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#button Button element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface Button extends Action, Confirmable { + /** + * @description The type of element. In this case `type` is always `button`. + */ type: 'button'; + /** + * @description A {@link PlainTextElement} that defines the button's text. `text` may truncate with ~30 characters. + * Maximum length for the text in this field is 75 characters. + */ text: PlainTextElement; + /** + * @description The value to send along with the {@link https://api.slack.com/interactivity/handling#payloads interaction payload}. + * Maximum length for this field is 2000 characters. + */ value?: string; + /** + * @description A URL to load in the user's browser when the button is clicked. Maximum length for this field is 3000 + * characters. If you're using `url`, you'll still receive an {@link https://api.slack.com/interactivity/handling#payloads interaction payload} + * and will need to send an {@link https://api.slack.com/interactivity/handling#acknowledgment_response acknowledgement response}. + */ url?: string; + /** + * @description Decorates buttons with alternative visual color schemes. Use this option with restraint. + * `primary` gives buttons a green outline and text, ideal for affirmation or confirmation actions. `primary` should + * only be used for one button within a set. + * `danger` gives buttons a red outline and text, and should be used when the action is destructive. Use `danger` even + * more sparingly than primary. + * If you don't include this field, the default button style will be used. + */ style?: 'danger' | 'primary'; + /** + * @description A label for longer descriptive text about a button element. This label will be read out by screen + * readers instead of the button `text` object. Maximum length for this field is 75 characters. + */ accessibility_label?: string; } +// TODO: breaking change: `Action` the checkbox extends from has an optional action_id, but is required for checkboxes. +/** + * @description Allows users to choose multiple items from a list of options. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#checkboxes Checkboxes element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface Checkboxes extends Action, Confirmable, Focusable { + /** + * @description The type of element. In this case `type` is always `checkboxes`. + */ type: 'checkboxes'; + /** + * @description An array of {@link Option} objects that exactly matches one or more of the options within `options`. + * These options will be selected when the checkbox group initially loads. + */ initial_options?: Option[]; + /** + * @description An array of {@link Option} objects. A maximum of 10 options are allowed. + */ options: Option[]; } +// TODO: breaking change: `Action` the datepicker extends from has an optional action_id, but is required for +// datepicker. +/** + * @description Allows users to select a date from a calendar style UI. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#datepicker Date picker element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface Datepicker extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `datepicker`. + */ type: 'datepicker'; + /** + * @description The initial date that is selected when the element is loaded. + * This should be in the format `YYYY-MM-DD`. + */ initial_date?: string; } +// TODO: breaking change: `Action` the datetimepicker extends from has an optional action_id, but is required for +// datetimepicker. /** - * @description An element that allows the selection of a time of day formatted as a UNIX timestamp. On desktop + * @description Allows users to select both a date and 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} + * @see {@link https://api.slack.com/reference/block-kit/block-elements#datetimepicker Datetime picker element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. */ export interface DateTimepicker extends Action, Confirmable, Focusable { + /** + * @description The type of element. In this case `type` is always `datetimepicker`. + */ 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 + * 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; } +// TODO: breaking change: `Action` the email extends from has an optional action_id, but is required for email inputs. /** - * @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} + * @description Allows user to enter an email into a single-line field. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#email Email input element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. */ export interface EmailInput extends Action, Dispatchable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `email_text_input`. + */ type: 'email_text_input'; /** * @description The initial value in the email input when it is loaded. @@ -57,9 +127,23 @@ export interface EmailInput extends Action, Dispatchable, Focusable, Placeholdab initial_value?: string; } +/** + * @description Displays an image as part of a larger block of content. Use this `image` block if you want a block with + * only an image in it. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#image Image element reference}. + */ export interface ImageElement { + /** + * @description The type of element. In this case `type` is always `image`. + */ type: 'image'; + /** + * @description The URL of the image to be displayed. + */ image_url: string; + /** + * @description A plain-text summary of the image. This should not contain any markup. + */ alt_text: string; } @@ -68,48 +152,189 @@ export interface ImageElement { */ // Selects and Multiselects are available in different surface areas so I've separated them here +/** + * @description Allows users to choose an option from a drop down menu. + * The select menu also includes type-ahead functionality, where a user can type a part or all of an option string to + * filter the list. There are different types of select menu elements that depend on different data sources for their + * lists of options: {@link StaticSelect}, {@link ExternalSelect}, {@link UsersSelect}, {@link ConversationsSelect}, + * {@link ChannelsSelect}. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#select Select menu element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export type Select = UsersSelect | StaticSelect | ConversationsSelect | ChannelsSelect | ExternalSelect; +/** + * @description Allows users to select multiple items from a list of options. + * Just like regular {@link Select}, multi-select menus also include type-ahead functionality, where a user can type a + * part or all of an option string to filter the list. + * There are different types of multi-select menu that depend on different data sources for their lists of options: + * {@link MultiStaticSelect}, {@link MultiExternalSelect}, {@link MultiUsersSelect}, {@link MultiConversationsSelect}, + * {@link MultiChannelsSelect}. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#multi_select Multi-select menu element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export type MultiSelect = MultiUsersSelect | MultiStaticSelect | MultiConversationsSelect | MultiChannelsSelect | MultiExternalSelect; +// TODO: breaking change: `Action` the user select extends from has an optional action_id, but is required for +// user select. +/** + * @description This select menu will populate its options with a list of Slack users visible to the current user in the + * active workspace. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#users_select Select menu of users reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface UsersSelect extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `users_select`. + */ type: 'users_select'; + /** + * @description The user ID of any valid user to be pre-selected when the menu loads. + */ initial_user?: string; } +// TODO: breaking change: `Action` the user select extends from has an optional action_id, but is required for +// user select. +/** + * @description This multi-select menu will populate its options with a list of Slack users visible to the current user + * in the active workspace. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#users_multi_select Multi-select menu of users reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface MultiUsersSelect extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `multi_users_select`. + */ type: 'multi_users_select'; + /** + * @description An array of user IDs of any valid users to be pre-selected when the menu loads. + */ initial_users?: string[]; + /** + * @description Specifies the maximum number of items that can be selected in the menu. Minimum number is `1`. + */ max_selected_items?: number; } +// TODO: breaking change: `Action` the statuc select extends from has an optional action_id, but is required for +// static select. +/** + * @description This is the simplest form of select menu, with a static list of options passed in when defining the + * element. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#static_select Select menu of static options reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface StaticSelect extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `static_select`. + */ type: 'static_select'; + // TODO: breaking change: use discriminative union and separate types for static select of options vs. option groups + /** + * @description A single option that exactly matches one of the options within `options` or `option_groups`. + * This option will be selected when the menu initially loads. + */ initial_option?: PlainTextOption; + // TODO: breaking change: use discriminative union and separate types for static select of options vs. option groups + // so this is not always optional. Also in theory this should support mrkdown options too? + /** + * @description An array of {@link PlainTextOption}. Maximum number of options is 100. If `option_groups` is + * specified, this field should not be. + */ options?: PlainTextOption[]; + // TODO: breaking change: use composition-objects.ts' `OptionGroup` - which allows both plaintext and mrkdown + // options, whereas the below doesn't. Also use a discriminative union here to separate option vs. option groups + // static menu. + /** + * @description An array of option group objects. Maximum number of option groups is 100. If `options` is specified, + * this field should not be. + */ option_groups?: { label: PlainTextElement; options: PlainTextOption[]; }[]; } +// TODO: breaking change: `Action` the statuc select extends from has an optional action_id, but is required for +// static select. +/** + * @description This is the simplest form of select menu, with a static list of options passed in when defining the + * element. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#static_multi_select Multi-select menu of static options reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface MultiStaticSelect extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `multi_static_select`. + */ type: 'multi_static_select'; + // TODO: breaking change: use discriminative union and separate types for static select of options vs. option groups + /** + * @description An array of option objects that exactly match one or more of the options within `options` or + * `option_groups`. These options will be selected when the menu initially loads. + */ initial_options?: PlainTextOption[]; + // TODO: breaking change: use discriminative union and separate types for static select of options vs. option groups + // so this is not always optional. Also in theory this should support mrkdown options too? + /** + * @description An array of {@link PlainTextOption}. Maximum number of options is 100. If `option_groups` is + * specified, this field should not be. + */ options?: PlainTextOption[]; + // TODO: breaking change: use composition-objects.ts' `OptionGroup` - which allows both plaintext and mrkdown + // options, whereas the below doesn't. Also use a discriminative union here to separate option vs. option groups + // static menu. + /** + * @description An array of option group objects. Maximum number of option groups is 100. If `options` is specified, + * this field should not be. + */ option_groups?: { label: PlainTextElement; options: PlainTextOption[]; }[]; + /** + * @description Specifies the maximum number of items that can be selected in the menu. Minimum number is 1. + */ max_selected_items?: number; } +// TODO: breaking change: `Action` the convo select extends from has an optional action_id, but is required for +// convo select. +/** + * @description This select menu will populate its options with a list of public and private channels, DMs, and MPIMs + * visible to the current user in the active workspace. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#conversations_select Select menu of conversations reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface ConversationsSelect extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `conversations_select`. + */ type: 'conversations_select'; + /** + * @description The ID of any valid conversation to be pre-selected when the menu loads. If + * `default_to_current_conversation` is also supplied, `initial_conversation` will take precedence. + */ initial_conversation?: string; + // TODO: maybe factor out `response_url_enabled` into its own mixin as part of `extensions.ts`? + // this is used in channel select too + /** + * @description When set to `true`, the {@link https://api.slack.com/reference/interaction-payloads/views#view_submission `view_submission` payload} + * from the menu's parent view will contain a `response_url`. This `response_url` can be used for + * {@link https://api.slack.com/interactivity/handling#message_responses message responses}. The target conversation + * for the message will be determined by the value of this select menu. + */ response_url_enabled?: boolean; + /** + * @description Pre-populates the select menu with the conversation that the user was viewing when they opened the + * modal, if available. Default is `false`. + */ default_to_current_conversation?: boolean; + /** + * @description A filter object that reduces the list of available conversations using the specified criteria. + */ filter?: { // TODO: breaking change: replace with ConversationFilter object from composition-objects include?: ('im' | 'mpim' | 'private' | 'public')[]; exclude_external_shared_channels?: boolean; @@ -117,11 +342,40 @@ export interface ConversationsSelect extends Action, Confirmable, Focusable, Pla }; } +// TODO: breaking change: `Action` the convo select extends from has an optional action_id, but is required for +// convo select. +// TODO: breaking change: maybe can use a discriminative union to differentiate between a multi-select convo element +// that uses `default_to_current_conversation` vs. `initial_conversation`? +/** + * @description This multi-select menu will populate its options with a list of public and private channels, DMs, and + * MPIMs visible to the current user in the active workspace. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#conversation_multi_select Multi-select menu of conversations reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface MultiConversationsSelect extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `conversations_select`. + */ type: 'multi_conversations_select'; + // TODO: breaking change: change array type to formalize 'at least one element' requirement. + /** + * @description An array of one or more IDs of any valid conversations to be pre-selected when the menu loads. If + * `default_to_current_conversation` is also supplied, `initial_conversation` will be ignored. + */ initial_conversations?: string[]; + // TODO: factor `max_selected_items` into its own extension / mixin? + /** + * @description Specifies the maximum number of items that can be selected in the menu. Minimum number is 1. + */ max_selected_items?: number; + /** + * @description Pre-populates the select menu with the conversation that the user was viewing when they opened the + * modal, if available. Default is `false`. + */ default_to_current_conversation?: boolean; + /** + * @description A filter object that reduces the list of available conversations using the specified criteria. + */ filter?: { // TODO: breaking change: replace with ConversationFilter object from composition-objects include?: ('im' | 'mpim' | 'private' | 'public')[]; exclude_external_shared_channels?: boolean; @@ -129,27 +383,112 @@ export interface MultiConversationsSelect extends Action, Confirmable, Focusable }; } +// TODO: breaking change: `Action` the channel select extends from has an optional action_id, but is required for +// channel select. +/** + * @description This select menu will populate its options with a list of public channels visible to the current user + * in the active workspace. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#channels_select Select menu of public channels reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface ChannelsSelect extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `channels_select`. + */ type: 'channels_select'; + /** + * @description The ID of any valid public channel to be pre-selected when the menu loads. + */ initial_channel?: string; + // TODO: maybe factor out `response_url_enabled` into its own mixin as part of `extensions.ts`? + // this is used in convo selects too + /** + * @description When set to `true`, the {@link https://api.slack.com/reference/interaction-payloads/views#view_submission `view_submission` payload} + * from the menu's parent view will contain a `response_url`. This `response_url` can be used for + * {@link https://api.slack.com/interactivity/handling#message_responses message responses}. The target channel + * for the message will be determined by the value of this select menu. + */ + response_url_enabled?: boolean; } +// TODO: breaking change: `Action` the channel select extends from has an optional action_id, but is required for +// channel select. +/** + * @description This multi-select menu will populate its options with a list of public channels visible to the current + * user in the active workspace. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#channel_multi_select Multi-select menu of public channels reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface MultiChannelsSelect extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `multi_channels_select`. + */ type: 'multi_channels_select'; + // TODO: breaking change: change type to enforce "at least one" array restriction + /** + * @description An array of one or more IDs of any valid public channel to be pre-selected when the menu loads. + */ initial_channels?: string[]; + // TODO: maybe factor out `max_selected_items` into its own mixin in `extensions.ts`? + /** + * @description Specifies the maximum number of items that can be selected in the menu. Minimum number is 1. + */ max_selected_items?: number; } +// TODO: breaking change: `Action` the external select extends from has an optional action_id, but is required for +// external select. +/** + * @description This select menu will load its options from an external data source, allowing for a dynamic list of + * options. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#external_select Select menu of external data source reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface ExternalSelect extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `external_select`. + */ type: 'external_select'; + // TODO: breaking change: should be able to support both options and option groups, both mrkdwn and plaintext + /** + * @description A single option to be selected when the menu initially loads. + */ initial_option?: PlainTextOption; + /** + * @description When the typeahead field is used, a request will be sent on every character change. If you prefer + * fewer requests or more fully ideated queries, use the `min_query_length` attribute to tell Slack the fewest number + * of typed characters required before dispatch. The default value is `3`. + */ min_query_length?: number; } +// TODO: breaking change: `Action` the external select extends from has an optional action_id, but is required for +// external select. +/** + * @description This menu will load its options from an external data source, allowing for a dynamic list of options. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#external_multi_select Multi-select menu of external data source reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface MultiExternalSelect extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `multi_external_select`. + */ type: 'multi_external_select'; + // TODO: breaking change: should be able to support both options and option groups, both mrkdwn and plaintext + /** + * @description An array of options to be selected when the menu initially loads. + */ initial_options?: PlainTextOption[]; + /** + * @description When the typeahead field is used, a request will be sent on every character change. If you prefer + * fewer requests or more fully ideated queries, use the `min_query_length` attribute to tell Slack the fewest number + * of typed characters required before dispatch. The default value is `3`. + */ min_query_length?: number; + // TODO: maybe factor out `max_selected_items` into its own mixin in `extensions.ts`? + /** + * @description Specifies the maximum number of items that can be selected in the menu. Minimum number is 1. + */ max_selected_items?: number; } @@ -157,13 +496,18 @@ export interface MultiExternalSelect extends Action, Confirmable, Focusable, Pla * End of select/multi-select menus */ +// TODO: the action_id inherited from Action type here IS apparently optional, unlike everywhere else! /** - * @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} + * @description Allows user to enter a number into a single-line field. The number input element accepts both whole and + * decimal 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`. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#number Number input element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. */ export interface NumberInput extends Action, Dispatchable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `number_input`. + */ type: 'number_input'; /** * @description Decimal numbers are allowed if this property is `true`, set the value to `false` otherwise. @@ -183,39 +527,121 @@ export interface NumberInput extends Action, Dispatchable, Focusable, Placeholda max_value?: string; } +/** + * @description Allows users to press a button to view a list of options. + * Unlike the select menu, there is no typeahead field, and the button always appears with an ellipsis ("…") rather + * than customizable text. As such, it is usually used if you want a more compact layout than a select menu, or to + * supply a list of less visually important actions after a row of buttons. You can also specify simple URL links as + * overflow menu options, instead of actions. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#overflow Overflow menu element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface Overflow extends Action, Confirmable { + /** + * @description The type of element. In this case `type` is always `number_input`. + */ type: 'overflow'; + // TODO: breaking change: this should support mrkdown options too? + /** + * @description An array of up to 5 {@link PlainTextOption} to display in the menu. + */ options: PlainTextOption[]; } +// TODO: breaking change: `Action` the plaintext input extends from has an optional action_id, but is required for +// plaintext input. +/** + * @description Allows users to enter freeform text data into a single-line or multi-line field. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#input Plain-text input element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface PlainTextInput extends Action, Dispatchable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `plain_text_input`. + */ type: 'plain_text_input'; + /** + * @description The initial value in the plain-text input when it is loaded. + */ initial_value?: string; + /** + * @description Indicates whether the input will be a single line (`false`) or a larger textarea (`true`). + * Defaults to `false`. + */ multiline?: boolean; + /** + * @description The minimum length of input that the user must provide. If the user provides less, they will receive + * an error. Maximum value is 3000. + */ min_length?: number; + /** + * @description The maximum length of input that the user can provide. If the user provides more, + * they will receive an error. + */ max_length?: number; - dispatch_action_config?: DispatchActionConfig; - focus_on_load?: boolean; } +// TODO: breaking change: `Action` the radio input extends from has an optional action_id, but is required for +// radio input. +/** + * @description Allows users to choose one item from a list of possible options. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#radio Radio button group element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface RadioButtons extends Action, Confirmable, Focusable { + /** + * @description The type of element. In this case `type` is always `radio_buttons`. + */ type: 'radio_buttons'; + /** + * @description An {@link Option} object that exactly matches one of the options within `options`. This option will + * be selected when the radio button group initially loads. + */ initial_option?: Option; + /** + * @description An array of {@link Option} objects. A maximum of 10 options are allowed. + */ options: Option[]; } +// TODO: breaking change: `Action` the time input extends from has an optional action_id, but is required for +// time input. +/** + * @description Allows users to choose a time from a rich dropdown UI. On desktop clients, this time picker will take + * the form of a dropdown list with free-text entry for precise choices. On mobile clients, the time picker will use + * native time picker UIs. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#timepicker Time picker element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. + */ export interface Timepicker extends Action, Confirmable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `timepicker`. + */ type: 'timepicker'; + /** + * @description The initial time that is selected when the element is loaded. This should be in the format `HH:mm`, + * where `HH` is the 24-hour format of an hour (00 to 23) and `mm` is minutes with leading zeros (00 to 59), + * for example 22:25 for 10:25pm. + */ initial_time?: string; + /** + * @description A string in the IANA format, e.g. "America/Chicago". The timezone is displayed to end users as hint + * text underneath the time picker. It is also passed to the app upon certain interactions, such as view_submission. + */ timezone?: string; } +// TODO: breaking change: `Action` the URL input extends from has an optional action_id, but is required for +// URL input. /** - * @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} + * @description Allows user to enter a URL into a single-line field. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#url URL input element reference}. + * @see {@link https://api.slack.com/interactivity/handling This is an interactive component - see our guide to enabling interactivity}. */ export interface URLInput extends Action, Dispatchable, Focusable, Placeholdable { + /** + * @description The type of element. In this case `type` is always `url_text_input`. + */ type: 'url_text_input'; /** * @description The initial value in the URL input when it is loaded. diff --git a/packages/types/src/block-kit/extensions.ts b/packages/types/src/block-kit/extensions.ts index 2c6658fc4..8a2bce148 100644 --- a/packages/types/src/block-kit/extensions.ts +++ b/packages/types/src/block-kit/extensions.ts @@ -8,12 +8,12 @@ export interface Action { * {@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique * among all other `action_id`s in the containing block. Maximum length for this field is 255 characters. */ - action_id?: string; + action_id?: string; // TODO: this field is required in many cases, validate if that is always the case } export interface Confirmable { /** - * @description A {@see Confirm} object that defines an optional confirmation dialog after the element is interacted + * @description A {@link Confirm} object that defines an optional confirmation dialog after the element is interacted * with. */ confirm?: Confirm; @@ -30,7 +30,7 @@ export interface Focusable { export interface Placeholdable { /** - * @description A {@see PlainTextElement} object that defines the placeholder text shown on the element. Maximum + * @description A {@link PlainTextElement} object that defines the placeholder text shown on the element. Maximum * length for the `text` field in this object is 150 characters. */ placeholder?: PlainTextElement; @@ -38,7 +38,7 @@ export interface Placeholdable { export interface Dispatchable { /** - * @description A {@see DispatchActionConfig} object that determines when during text input the element returns a + * @description A {@link DispatchActionConfig} object that determines when during text input the element returns a * {@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` payload}. */ dispatch_action_config?: DispatchActionConfig; From df1ef9ed3e1dd3f15129172abc1dd16592aa4ccc Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Mon, 25 Sep 2023 15:27:09 -0400 Subject: [PATCH 07/11] Final jsdoc additions for block kit elements and blocks! --- .../types/src/block-kit/block-elements.ts | 61 ++++++ packages/types/src/block-kit/blocks.ts | 191 +++++++++++++++++- 2 files changed, 243 insertions(+), 9 deletions(-) diff --git a/packages/types/src/block-kit/block-elements.ts b/packages/types/src/block-kit/block-elements.ts index 3668303ea..8c79bd990 100644 --- a/packages/types/src/block-kit/block-elements.ts +++ b/packages/types/src/block-kit/block-elements.ts @@ -648,3 +648,64 @@ export interface URLInput extends Action, Dispatchable, Focusable, Placeholdable */ initial_value?: string; } + +/** + * @description Allows users to run a {@link https://api.slack.com/automation/triggers/link#workflow_buttons link trigger} with customizable inputs. + * @see {@link https://api.slack.com/reference/block-kit/block-elements#workflow_button Workflow button element reference}. + */ +export interface WorkflowButton extends Confirmable { + /** + * @description The type of element. In this case `type` is always `workflow_button`. + */ + type: 'workflow_button'; + /** + * @description A {@link PlainTextElement} that defines the button's text. `text` may truncate with ~30 characters. + * Maximum length for the `text` in this field is 75 characters. + */ + text: PlainTextElement; + /** + * @description A workflow object that contains details about the workflow that will run when the button is clicked. + */ + workflow: { + /** + * @description Properties of the {@link https://api.slack.com/automation/triggers/link#workflow_buttons link trigger} + * that will be invoked via this button. + */ + trigger: { + /** + * @description The trigger URL of the {@link https://api.slack.com/automation/triggers/link#workflow_buttons link trigger} + */ + url: string; + /** + * @description List of customizable input parameters and their values. Should match input parameters specified on + * the provided trigger. + */ + customizable_input_parameters?: { + /** + * @description Name of the customizable input, which should be the name of a workflow input parameter for the + * matching workflow of the link trigger. + */ + name: string; + /** + * @description The value of the customizable input parameter. The type of the value is expected to match the + * specified type for the matching workflow input parameter. + */ + value: string; + }[]; + } + }; + /** + * @description Decorates buttons with alternative visual color schemes. Use this option with restraint. + * `primary` gives buttons a green outline and text, ideal for affirmation or confirmation actions. `primary` should + * only be used for one button within a set. + * `danger` gives buttons a red outline and text, and should be used when the action is destructive. Use `danger` even + * more sparingly than primary. + * If you don't include this field, the default button style will be used. + */ + style?: 'danger' | 'primary'; + /** + * @description A label for longer descriptive text about a button element. This label will be read out by screen + * readers instead of the button `text` object. Maximum length for this field is 75 characters. + */ + accessibility_label?: string; +} diff --git a/packages/types/src/block-kit/blocks.ts b/packages/types/src/block-kit/blocks.ts index 285cc0b93..46680e614 100644 --- a/packages/types/src/block-kit/blocks.ts +++ b/packages/types/src/block-kit/blocks.ts @@ -1,68 +1,202 @@ // 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 { Button, Checkboxes, Datepicker, DateTimepicker, EmailInput, ImageElement, MultiSelect, NumberInput, Overflow, PlainTextInput, RadioButtons, Select, Timepicker, URLInput, WorkflowButton } from './block-elements'; import { Action } from './extensions'; export interface Block { type: string; + /** + * @description A string acting as a unique identifier for a block. If not specified, a `block_id` will be generated. + * You can use this `block_id` when you receive an interaction payload to + * {@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. + * Maximum length for this field is 255 characters. `block_id` should be unique for each message and each iteration of + * a message. If a message is updated, use a new `block_id`. + */ block_id?: string; } export type KnownBlock = ImageBlock | ContextBlock | ActionsBlock | DividerBlock | SectionBlock | InputBlock | FileBlock | HeaderBlock | VideoBlock; +/** + * @description Holds multiple interactive elements. + * @see {@link https://api.slack.com/reference/block-kit/blocks#actions Actions block reference}. + */ export interface ActionsBlock extends Block { + /** + * @description The type of block. For an actions block, `type` is always `actions`. + */ type: 'actions'; - elements: (Button | Overflow | Datepicker | Timepicker | DateTimepicker | Select | RadioButtons | Checkboxes - | Action)[]; + // TODO: add rich text input to this list once ready + /** + * @description An array of {@link InteractiveElements} objects. + * There is a maximum of 25 elements in each action block. + */ + elements: (Button | Checkboxes | Datepicker | DateTimepicker | MultiSelect | Overflow | RadioButtons | Select | + Timepicker | WorkflowButton)[]; } +/** + * @description Displays contextual info, which can include both images and text. + * @see {@link https://api.slack.com/reference/block-kit/blocks#context Context block reference}. + */ export interface ContextBlock extends Block { + /** + * @description The type of block. For a context block, `type` is always `context`. + */ type: 'context'; + // TODO: use the future planned plaintext/mrkdwn union here instead + /** + * @description An array of {@link ImageElement}, {@link PlainTextElement} or {@link MrkdwnElement} objects. + * Maximum number of items is 10. + */ elements: (ImageElement | PlainTextElement | MrkdwnElement)[]; } +/** + * @description Visually separates pieces of info inside of a message. A content divider, like an `
`, to split up + * different blocks inside of a message. The divider block is nice and neat, requiring only a `type`. + * @see {@link https://api.slack.com/reference/block-kit/blocks#divider Divider block reference}. + */ export interface DividerBlock extends Block { + /** + * @description The type of block. For a divider block, `type` is always `divider`. + */ type: 'divider'; } +/** + * @description Displays a {@link https://api.slack.com/messaging/files/remote remote file}. You can't add this block to + * app surfaces directly, but it will show up when {@link https://api.slack.com/messaging/retrieving retrieving messages} + * that contain remote files. If you want to add remote files to messages, + * {@link https://api.slack.com/messaging/files/remote follow our guide}. + * @see {@link https://api.slack.com/reference/block-kit/blocks#file File block reference}. + */ export interface FileBlock extends Block { + /** + * @description The type of block. For a file block, `type` is always `file`. + */ type: 'file'; - source: string; // 'remote' + /** + * @description At the moment, source will always be `remote` for a remote file. + */ + source: string; // TODO: breaking change: set this to the string literal 'remote' ? + /** + * @description The external unique ID for this file. + */ external_id: string; } +/** + * @description Displays a larger-sized text block. A `header` is a plain-text block that displays in a larger, bold + * font. Use it to delineate between different groups of content in your app's surfaces. + * @see {@link https://api.slack.com/reference/block-kit/blocks#header Header block reference}. + */ export interface HeaderBlock extends Block { + /** + * @description The type of block. For a header block, `type` is always `header`. + */ type: 'header'; + /** + * @description The text for the block, in the form of a {@link PlainTextElement}. + * Maximum length for the text in this field is 150 characters. + */ text: PlainTextElement; } +/** + * @description Displays an image. A simple image block, designed to make those cat photos really pop. + * @see {@link https://api.slack.com/reference/block-kit/blocks#image Image block reference}. + */ export interface ImageBlock extends Block { + /** + * @description The type of block. For an image block, `type` is always `image`. + */ type: 'image'; + /** + * @description The URL of the image to be displayed. Maximum length for this field is 3000 characters. + */ image_url: string; + /** + * @description A plain-text summary of the image. This should not contain any markup. + * Maximum length for this field is 2000 characters. + */ alt_text: string; + /** + * @description An optional title for the image in the form of a {@link PlainTextElement} object. + * Maximum length for the text in this field is 2000 characters. + */ title?: PlainTextElement; } +/** + * @description Collects information from users via block elements. + * @see {@link https://api.slack.com/reference/block-kit/blocks#input Input block reference}. + * @see {@link https://api.slack.com/surfaces/modals#gathering_input Collecting input in modals guide}. + * @see {@link https://api.slack.com/surfaces/app-home#gathering_input Collecting input in Home tabs guide}. + */ export interface InputBlock extends Block { + /** + * @description The type of block. For an input block, `type` is always `input`. + */ type: 'input'; + /** + * @description A label that appears above an input element in the form of a {@link PlainTextElement} object. + * Maximum length for the text in this field is 2000 characters. + */ label: PlainTextElement; + /** + * @description An optional hint that appears below an input element in a lighter grey. It must be a + * {@link PlainTextElement object}. Maximum length for the `text` in this field is 2000 characters. + */ hint?: PlainTextElement; + /** + * @description A boolean that indicates whether the input element may be empty when a user submits the modal. + * Defaults to `false`. + */ optional?: boolean; + /** + * @description A block element. + */ element: Select | MultiSelect | Datepicker | Timepicker | DateTimepicker | PlainTextInput | URLInput | EmailInput | NumberInput | RadioButtons | Checkboxes; + /** + * @description A boolean that indicates whether or not the use of elements in this block should dispatch a + * {@link https://api.slack.com/reference/interaction-payloads/block-actions block_actions payload}. Defaults to `false`. + */ dispatch_action?: boolean; } +// TODO: breaking change: use a discriminative union to represent section block using `text` or `fields` but +// not both or neither. +/** + * @description Displays text, possibly alongside block elements. A section can be used as a simple text block, in + * combination with text fields, or side-by-side with certain + * {@link https://api.slack.com/reference/messaging/block-elements block elements}. + * @see {@link https://api.slack.com/reference/block-kit/blocks#section Section block reference}. + */ export interface SectionBlock extends Block { + /** + * @description The type of block. For a section block, `type` is always `section`. + */ type: 'section'; - text?: PlainTextElement | MrkdwnElement; // either this or fields must be defined + /** + * @description The text for the block, in the form of a text object. Minimum length for the `text` in this field is + * 1 and maximum length is 3000 characters. This field is not required if a valid array of `fields` objects is + * provided instead. + */ + text?: PlainTextElement | MrkdwnElement; + /** + * @description Required if no `text` is provided. An array of text objects. Any text objects included with `fields` + * will be rendered in a compact format that allows for 2 columns of side-by-side text. Maximum number of items is 10. + * Maximum length for the text in each item is 2000 characters. + * {@link https://app.slack.com/block-kit-builder/T029V6468RL#%7B%22blocks%22:%5B%7B%22type%22:%22section%22,%22text%22:%7B%22text%22:%22A%20message%20*with%20some%20bold%20text*%20and%20_some%20italicized%20text_.%22,%22type%22:%22mrkdwn%22%7D,%22fields%22:%5B%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Priority*%22%7D,%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Type*%22%7D,%7B%22type%22:%22plain_text%22,%22text%22:%22High%22%7D,%7B%22type%22:%22plain_text%22,%22text%22:%22String%22%7D%5D%7D%5D%7D Click here for an example}. + */ fields?: (PlainTextElement | MrkdwnElement)[]; // either this or text must be defined + /** + * @description One of the compatible element objects. + */ accessory?: Button | Overflow | Datepicker @@ -75,15 +209,54 @@ export interface SectionBlock extends Block { | Checkboxes; } +/** + * @description Displays an embedded video player. A video block is designed to embed videos in all app surfaces (e.g. + * link unfurls, messages, modals, App Home) — anywhere you can put blocks! To use the video block within your app, you + * must have the {@link https://api.slack.com/scopes/links.embed:write `links.embed:write` scope}. + * @see {@link https://api.slack.com/reference/block-kit/blocks#video Video block reference}. + */ export interface VideoBlock extends Block { + /** + * @description The type of block. For a video block, `type` is always `video`. + */ type: 'video'; + /** + * @description The URL to be embedded. Must match any existing + * {@link https://api.slack.com/reference/messaging/link-unfurling#configuring_domains unfurl domains} within the app + * and point to a HTTPS URL. + */ video_url: string; + /** + * @description The thumbnail image URL. + */ thumbnail_url: string; + /** + * @description A tooltip for the video. Required for accessibility. + */ alt_text: string; + /** + * @description Video title as a {@link PlainTextElement} object. `text` within must be less than 200 characters. + */ title: PlainTextElement; + /** + * @description Hyperlink for the title text. Must correspond to the non-embeddable URL for the video. + * Must go to an HTTPS URL. + */ title_url?: string; + /** + * @description Author name to be displayed. Must be less than 50 characters. + */ author_name?: string; + /** + * @description The originating application or domain of the video, e.g. YouTube. + */ provider_name?: string; + /** + * @description Icon for the video provider, e.g. YouTube icon. + */ provider_icon_url?: string; + /** + * @description Description for video using a {@link PlainTextElement} object. + */ description?: PlainTextElement; } From 2f2537e0e276c13b75fa73f02721f9fedc9554d6 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Tue, 26 Sep 2023 08:54:55 -0400 Subject: [PATCH 08/11] Update packages/types/src/block-kit/blocks.ts Co-authored-by: Kazuhiro Sera --- packages/types/src/block-kit/blocks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/block-kit/blocks.ts b/packages/types/src/block-kit/blocks.ts index 46680e614..eb2121dac 100644 --- a/packages/types/src/block-kit/blocks.ts +++ b/packages/types/src/block-kit/blocks.ts @@ -191,7 +191,7 @@ export interface SectionBlock extends Block { * @description Required if no `text` is provided. An array of text objects. Any text objects included with `fields` * will be rendered in a compact format that allows for 2 columns of side-by-side text. Maximum number of items is 10. * Maximum length for the text in each item is 2000 characters. - * {@link https://app.slack.com/block-kit-builder/T029V6468RL#%7B%22blocks%22:%5B%7B%22type%22:%22section%22,%22text%22:%7B%22text%22:%22A%20message%20*with%20some%20bold%20text*%20and%20_some%20italicized%20text_.%22,%22type%22:%22mrkdwn%22%7D,%22fields%22:%5B%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Priority*%22%7D,%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Type*%22%7D,%7B%22type%22:%22plain_text%22,%22text%22:%22High%22%7D,%7B%22type%22:%22plain_text%22,%22text%22:%22String%22%7D%5D%7D%5D%7D Click here for an example}. + * {@link https://app.slack.com/block-kit-builder/#%7B%22blocks%22:%5B%7B%22type%22:%22section%22,%22text%22:%7B%22text%22:%22A%20message%20*with%20some%20bold%20text*%20and%20_some%20italicized%20text_.%22,%22type%22:%22mrkdwn%22%7D,%22fields%22:%5B%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Priority*%22%7D,%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Type*%22%7D,%7B%22type%22:%22plain_text%22,%22text%22:%22High%22%7D,%7B%22type%22:%22plain_text%22,%22text%22:%22String%22%7D%5D%7D%5D%7D Click here for an example}. */ fields?: (PlainTextElement | MrkdwnElement)[]; // either this or text must be defined /** From ab9e427c4d04c2b5bf86543fcb45d8a754cc21f4 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Tue, 26 Sep 2023 12:29:30 -0400 Subject: [PATCH 09/11] `action_id` is indeed optional for all BK elements. --- .../types/src/block-kit/block-elements.ts | 36 ------------------- packages/types/src/block-kit/extensions.ts | 4 ++- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/packages/types/src/block-kit/block-elements.ts b/packages/types/src/block-kit/block-elements.ts index 8c79bd990..669b8a0ab 100644 --- a/packages/types/src/block-kit/block-elements.ts +++ b/packages/types/src/block-kit/block-elements.ts @@ -3,7 +3,6 @@ import { Action, Confirmable, Dispatchable, Focusable, Placeholdable } from './extensions'; import { Option, PlainTextElement, PlainTextOption } from './composition-objects'; -// TODO: breaking change: `Action` the button extends from has an optional action_id, but is required for buttons. /** * @description Allows users a direct path to performing basic actions. * @see {@link https://api.slack.com/reference/block-kit/block-elements#button Button element reference}. @@ -46,7 +45,6 @@ export interface Button extends Action, Confirmable { accessibility_label?: string; } -// TODO: breaking change: `Action` the checkbox extends from has an optional action_id, but is required for checkboxes. /** * @description Allows users to choose multiple items from a list of options. * @see {@link https://api.slack.com/reference/block-kit/block-elements#checkboxes Checkboxes element reference}. @@ -68,8 +66,6 @@ export interface Checkboxes extends Action, Confirmable, Focusable { options: Option[]; } -// TODO: breaking change: `Action` the datepicker extends from has an optional action_id, but is required for -// datepicker. /** * @description Allows users to select a date from a calendar style UI. * @see {@link https://api.slack.com/reference/block-kit/block-elements#datepicker Date picker element reference}. @@ -87,8 +83,6 @@ export interface Datepicker extends Action, Confirmable, Focusable, Placeholdabl initial_date?: string; } -// TODO: breaking change: `Action` the datetimepicker extends from has an optional action_id, but is required for -// datetimepicker. /** * @description Allows users to select both a date and 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 @@ -110,7 +104,6 @@ export interface DateTimepicker extends Action, Confirmable, Focusable { initial_date_time?: number; } -// TODO: breaking change: `Action` the email extends from has an optional action_id, but is required for email inputs. /** * @description Allows user to enter an email into a single-line field. * @see {@link https://api.slack.com/reference/block-kit/block-elements#email Email input element reference}. @@ -176,8 +169,6 @@ export type Select = UsersSelect | StaticSelect | ConversationsSelect | Channels export type MultiSelect = MultiUsersSelect | MultiStaticSelect | MultiConversationsSelect | MultiChannelsSelect | MultiExternalSelect; -// TODO: breaking change: `Action` the user select extends from has an optional action_id, but is required for -// user select. /** * @description This select menu will populate its options with a list of Slack users visible to the current user in the * active workspace. @@ -195,8 +186,6 @@ export interface UsersSelect extends Action, Confirmable, Focusable, Placeholdab initial_user?: string; } -// TODO: breaking change: `Action` the user select extends from has an optional action_id, but is required for -// user select. /** * @description This multi-select menu will populate its options with a list of Slack users visible to the current user * in the active workspace. @@ -218,8 +207,6 @@ export interface MultiUsersSelect extends Action, Confirmable, Focusable, Placeh max_selected_items?: number; } -// TODO: breaking change: `Action` the statuc select extends from has an optional action_id, but is required for -// static select. /** * @description This is the simplest form of select menu, with a static list of options passed in when defining the * element. @@ -257,8 +244,6 @@ export interface StaticSelect extends Action, Confirmable, Focusable, Placeholda }[]; } -// TODO: breaking change: `Action` the statuc select extends from has an optional action_id, but is required for -// static select. /** * @description This is the simplest form of select menu, with a static list of options passed in when defining the * element. @@ -300,8 +285,6 @@ export interface MultiStaticSelect extends Action, Confirmable, Focusable, Place max_selected_items?: number; } -// TODO: breaking change: `Action` the convo select extends from has an optional action_id, but is required for -// convo select. /** * @description This select menu will populate its options with a list of public and private channels, DMs, and MPIMs * visible to the current user in the active workspace. @@ -342,8 +325,6 @@ export interface ConversationsSelect extends Action, Confirmable, Focusable, Pla }; } -// TODO: breaking change: `Action` the convo select extends from has an optional action_id, but is required for -// convo select. // TODO: breaking change: maybe can use a discriminative union to differentiate between a multi-select convo element // that uses `default_to_current_conversation` vs. `initial_conversation`? /** @@ -383,8 +364,6 @@ export interface MultiConversationsSelect extends Action, Confirmable, Focusable }; } -// TODO: breaking change: `Action` the channel select extends from has an optional action_id, but is required for -// channel select. /** * @description This select menu will populate its options with a list of public channels visible to the current user * in the active workspace. @@ -411,8 +390,6 @@ export interface ChannelsSelect extends Action, Confirmable, Focusable, Placehol response_url_enabled?: boolean; } -// TODO: breaking change: `Action` the channel select extends from has an optional action_id, but is required for -// channel select. /** * @description This multi-select menu will populate its options with a list of public channels visible to the current * user in the active workspace. @@ -436,8 +413,6 @@ export interface MultiChannelsSelect extends Action, Confirmable, Focusable, Pla max_selected_items?: number; } -// TODO: breaking change: `Action` the external select extends from has an optional action_id, but is required for -// external select. /** * @description This select menu will load its options from an external data source, allowing for a dynamic list of * options. @@ -462,8 +437,6 @@ export interface ExternalSelect extends Action, Confirmable, Focusable, Placehol min_query_length?: number; } -// TODO: breaking change: `Action` the external select extends from has an optional action_id, but is required for -// external select. /** * @description This menu will load its options from an external data source, allowing for a dynamic list of options. * @see {@link https://api.slack.com/reference/block-kit/block-elements#external_multi_select Multi-select menu of external data source reference}. @@ -496,7 +469,6 @@ export interface MultiExternalSelect extends Action, Confirmable, Focusable, Pla * End of select/multi-select menus */ -// TODO: the action_id inherited from Action type here IS apparently optional, unlike everywhere else! /** * @description Allows user to enter a number into a single-line field. The number input element accepts both whole and * decimal numbers. For example, 0.25, 5.5, and -10 are all valid input values. Decimal numbers are only allowed when @@ -548,8 +520,6 @@ export interface Overflow extends Action, Confirmable { options: PlainTextOption[]; } -// TODO: breaking change: `Action` the plaintext input extends from has an optional action_id, but is required for -// plaintext input. /** * @description Allows users to enter freeform text data into a single-line or multi-line field. * @see {@link https://api.slack.com/reference/block-kit/block-elements#input Plain-text input element reference}. @@ -581,8 +551,6 @@ export interface PlainTextInput extends Action, Dispatchable, Focusable, Placeho max_length?: number; } -// TODO: breaking change: `Action` the radio input extends from has an optional action_id, but is required for -// radio input. /** * @description Allows users to choose one item from a list of possible options. * @see {@link https://api.slack.com/reference/block-kit/block-elements#radio Radio button group element reference}. @@ -604,8 +572,6 @@ export interface RadioButtons extends Action, Confirmable, Focusable { options: Option[]; } -// TODO: breaking change: `Action` the time input extends from has an optional action_id, but is required for -// time input. /** * @description Allows users to choose a time from a rich dropdown UI. On desktop clients, this time picker will take * the form of a dropdown list with free-text entry for precise choices. On mobile clients, the time picker will use @@ -631,8 +597,6 @@ export interface Timepicker extends Action, Confirmable, Focusable, Placeholdabl timezone?: string; } -// TODO: breaking change: `Action` the URL input extends from has an optional action_id, but is required for -// URL input. /** * @description Allows user to enter a URL into a single-line field. * @see {@link https://api.slack.com/reference/block-kit/block-elements#url URL input element reference}. diff --git a/packages/types/src/block-kit/extensions.ts b/packages/types/src/block-kit/extensions.ts index 8a2bce148..45cd9de90 100644 --- a/packages/types/src/block-kit/extensions.ts +++ b/packages/types/src/block-kit/extensions.ts @@ -1,6 +1,8 @@ // This file contains reusable extensions/mixins that other Block Kit elements will extend from. import { Confirm, PlainTextElement, DispatchActionConfig } from './composition-objects'; +// TODO: what about aliasing this to `Actionable` to line up the mixin terms in this file? +// And deprecate the old `Action` interface? export interface Action { type: string; /** @@ -8,7 +10,7 @@ export interface Action { * {@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique * among all other `action_id`s in the containing block. Maximum length for this field is 255 characters. */ - action_id?: string; // TODO: this field is required in many cases, validate if that is always the case + action_id?: string; } export interface Confirmable { From 7ddf85b79ee5f06e91545c294607d003f6537a86 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Tue, 26 Sep 2023 12:36:26 -0400 Subject: [PATCH 10/11] Deprecate `Confirm` interface and alias to a new `ConfirmationDialog` type --- packages/types/src/block-kit/composition-objects.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/types/src/block-kit/composition-objects.ts b/packages/types/src/block-kit/composition-objects.ts index 6e6555400..3b2b96ecc 100644 --- a/packages/types/src/block-kit/composition-objects.ts +++ b/packages/types/src/block-kit/composition-objects.ts @@ -1,8 +1,9 @@ // This file contains objects documented here: https://api.slack.com/reference/block-kit/composition-objects -// TODO: maybe a breaking change, but, what about aliasing Confirm to ConfirmationDialog or some such? -// and deprecating this interface? this would line up the terms between these types and api.slack.com +// TODO: breaking change: remove `Confirm` and move properties to `ConfirmationDialog` below on next major release. /** + * @deprecated {@link Confirm} has been aliased to {@link ConfirmationDialog} in order to make the construct clearer + * and line up terminology with api.slack.com. * @description Defines a dialog that adds a confirmation step to interactive elements. * @see {@link https://api.slack.com/reference/block-kit/composition-objects#confirm Confirmation dialog object reference}. */ @@ -35,6 +36,12 @@ export interface Confirm { style?: 'primary' | 'danger'; } +/** + * @description Defines a dialog that adds a confirmation step to interactive elements. + * @see {@link https://api.slack.com/reference/block-kit/composition-objects#confirm Confirmation dialog object reference}. + */ +export type ConfirmationDialog = Confirm; + /** * @description Defines when a {@link PlainTextElement} will return a {@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` interaction payload}. * @see {@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` interaction payload}. From b97cb20b78a24fa6a903b71edeeff5e8bf81853f Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Tue, 26 Sep 2023 12:44:01 -0400 Subject: [PATCH 11/11] Alias `Confirm` to `ConfirmationDialog` interface and `Action` to `Actionable`. --- packages/types/src/block-kit/composition-objects.ts | 4 ++-- packages/types/src/block-kit/extensions.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/types/src/block-kit/composition-objects.ts b/packages/types/src/block-kit/composition-objects.ts index 3b2b96ecc..c21e9a9c4 100644 --- a/packages/types/src/block-kit/composition-objects.ts +++ b/packages/types/src/block-kit/composition-objects.ts @@ -2,7 +2,7 @@ // TODO: breaking change: remove `Confirm` and move properties to `ConfirmationDialog` below on next major release. /** - * @deprecated {@link Confirm} has been aliased to {@link ConfirmationDialog} in order to make the construct clearer + * @deprecated {@link Confirm} aliased to {@link ConfirmationDialog} in order to make the construct clearer * and line up terminology with api.slack.com. * @description Defines a dialog that adds a confirmation step to interactive elements. * @see {@link https://api.slack.com/reference/block-kit/composition-objects#confirm Confirmation dialog object reference}. @@ -40,7 +40,7 @@ export interface Confirm { * @description Defines a dialog that adds a confirmation step to interactive elements. * @see {@link https://api.slack.com/reference/block-kit/composition-objects#confirm Confirmation dialog object reference}. */ -export type ConfirmationDialog = Confirm; +export interface ConfirmationDialog extends Confirm {} // eslint-disable-line @typescript-eslint/no-empty-interface /** * @description Defines when a {@link PlainTextElement} will return a {@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` interaction payload}. diff --git a/packages/types/src/block-kit/extensions.ts b/packages/types/src/block-kit/extensions.ts index 45cd9de90..53d304839 100644 --- a/packages/types/src/block-kit/extensions.ts +++ b/packages/types/src/block-kit/extensions.ts @@ -1,8 +1,10 @@ // This file contains reusable extensions/mixins that other Block Kit elements will extend from. import { Confirm, PlainTextElement, DispatchActionConfig } from './composition-objects'; -// TODO: what about aliasing this to `Actionable` to line up the mixin terms in this file? -// And deprecate the old `Action` interface? +// TODO: breaking change: remove `Action` and move properties to `Actionable` on next major release. +/** + * @deprecated {@link Action} aliased to {@link Actionable} in order to name the mixins in this file consistently. + */ export interface Action { type: string; /** @@ -13,6 +15,8 @@ export interface Action { action_id?: string; } +export interface Actionable extends Action {} // eslint-disable-line @typescript-eslint/no-empty-interface + export interface Confirmable { /** * @description A {@link Confirm} object that defines an optional confirmation dialog after the element is interacted