Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

📁 Added File Input element. #128

Merged
merged 2 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions src/elements/file-input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ElementBuilderBase } from '../internal/base';
import { ElementType } from '../internal/constants';
import { SlackElementDto } from '../internal/dto';
import { applyMixins } from '../internal/helpers';
import {
ActionId,
Filetypes,
MaxFiles,
End,
} from '../internal/methods';

export interface FileInputParams {
actionId?: string;
filetypes?: string[];
maxFiles?: number;
}

export interface FileInputBuilder extends ActionId,
Filetypes,
MaxFiles,
End {
}

/**
* @@link https://api.slack.com/reference/block-kit/block-elements#file_input
* @@displayName File Input Builder
*/

export class FileInputBuilder extends ElementBuilderBase {
/** @internal */

public build(): Readonly<SlackElementDto> {
return this.getResult(SlackElementDto, {
type: ElementType.FileInput,
});
}
}

applyMixins(FileInputBuilder, [
ActionId,
Filetypes,
MaxFiles,
End,
]);
16 changes: 16 additions & 0 deletions src/elements/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { TimePickerBuilder, TimePickerParams } from './timepicker';
import { URLInputBuilder, URLInputParams } from './url-input';
import { UserMultiSelectBuilder, UserMultiSelectParams } from './user-multi-select';
import { UserSelectBuilder, UserSelectParams } from './user-select';
import { FileInputBuilder, FileInputParams } from './file-input';

export type {
ButtonBuilder,
Expand Down Expand Up @@ -68,6 +69,8 @@ export type {
UserMultiSelectParams,
UserSelectBuilder,
UserSelectParams,
FileInputBuilder,
FileInputParams,
};

/**
Expand Down Expand Up @@ -229,6 +232,18 @@ export function Img(params?: ImgParams): ImgBuilder {
return new ImgBuilder(params);
}

/**
* @param {Object} [params] Parameters passed to the constructor.
* @param {string} [params.filetypes] Sets the accepted filetypes.
* @param {string} [params.maxFiles] Sets the maximum number of files to upload.
*
* {@link https://api.slack.com/reference/block-kit/block-elements#file_input|View in Slack API Documentation}
*/

export function FileInput(params?: FileInputParams): FileInputBuilder {
return new FileInputBuilder(params);
}

/**
* @param {Object} [params] Parameters passed to the constructor.
* @param {string} [params.actionId] Sets a string to be an identifier for the source of an action in interaction payloads.
Expand Down Expand Up @@ -382,6 +397,7 @@ const elements = {
URLInput,
UserMultiSelect,
UserSelect,
FileInput,
};

// Strange export. I know. For IDE highlighting purposes.
Expand Down
1 change: 1 addition & 0 deletions src/internal/constants/element-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export enum ElementType {
URLInput = 'url_text_input',
EmailInput = 'email_text_input',
NumberInput = 'number_input',
FileInput = 'file_input',
}
2 changes: 2 additions & 0 deletions src/internal/constants/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,6 @@ export enum Prop {
TitleUrl = 'titleUrl',
ThumbnailUrl = 'thumbnailUrl',
VideoUrl = 'videoUrl',
MaxFiles = 'maxFiles',
Filetypes = 'filetypes',
}
2 changes: 2 additions & 0 deletions src/internal/dto/slack-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ export enum Param {
videoUrl = 'video_url',
minValue = 'min_value',
maxValue = 'max_value',
maxFiles = 'max_files',
filetypes = 'filetypes',
}

export class SlackDto implements ObjectLiteral {
Expand Down
32 changes: 32 additions & 0 deletions src/internal/methods/set-methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -769,3 +769,35 @@ export abstract class VideoUrl extends Builder {
return this.set(videoUrl, Prop.VideoUrl);
}
}

export abstract class MaxFiles extends Builder {
/**
* @description Maximum number of files that can be uploaded for this file_input element. Minimum of 1, maximum of 10. Defaults to 10 if not specified.
*
* {@link https://api.slack.com/block-kit|Open Official Slack Block Kit Documentation}
* {@link https://www.blockbuilder.dev|Open Block Builder Documentation}
*/

public maxFiles(maxFiles:Settable<number> = 10): this {
return this.set(maxFiles, Prop.MaxFiles);
}
}

export abstract class Filetypes extends Builder {
/**
* @description An array of valid file extensions that will be accepted for this element. All file extensions will be accepted if filetypes is not specified.
*
* **Slack Validation Rules and Tips:**
* * **Required if the text property is undefined** ⚠
* * Maximum of 10 items.
* * Maximum of 2000 characters for each field.
* * Markdown supported.
*
* {@link https://api.slack.com/block-kit|Open Official Slack Block Kit Documentation}
* {@link https://www.blockbuilder.dev|Open Block Builder Documentation}
*/

public filetypes(filetypes:Settable<string[]> = []): this {
return this.set(filetypes.flat(), Prop.Filetypes);
}
}
4 changes: 3 additions & 1 deletion src/internal/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
DatePickerBuilder, DateTimePickerBuilder,
ExternalMultiSelectBuilder,
ExternalSelectBuilder,
FileInputBuilder,
ImgBuilder,
OverflowMenuBuilder,
RadioButtonsBuilder,
Expand Down Expand Up @@ -83,7 +84,8 @@ export type InputElementBuilder =
| TimePickerBuilder
| URLInputBuilder
| UserMultiSelectBuilder
| UserSelectBuilder;
| UserSelectBuilder
| FileInputBuilder;

export type ContextElement = ImgBuilder | string;

Expand Down
23 changes: 23 additions & 0 deletions tests/elements/file-input.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FileInputBuilder as Class } from '../../src/elements/file-input';
import { SlackElementDto as DtoClass } from '../../src/internal';
import { params } from './mocks/file-input.mock';
import * as methods from '../methods';
import { testCompositeBuilderClass } from '../test-composite-builder-class';

const className = 'FileInput';
const category = 'Elements';

const config = {
Class,
DtoClass,
params,
className,
category,
};

const methodsConfig = [
methods.filetypes,
methods.maxFiles,
];

testCompositeBuilderClass({ config, methods: methodsConfig });
9 changes: 9 additions & 0 deletions tests/elements/mocks/file-input.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { FileInputBuilder } from '../../../src/elements/file-input';

export const params = {
actionId: 'actionId',
filetypes: 'filetypes',
maxFiles: 'maxFiles',
};

export const mock = new FileInputBuilder(params);
1 change: 1 addition & 0 deletions tests/elements/mocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export * as TimePicker from './time-picker.mock';
export * as URLInput from './url-input.mock';
export * as UserMultiSelect from './user-multiselect.mock';
export * as UserSelect from './user-select.mock';
export * as FileInput from './file-input.mock';
19 changes: 19 additions & 0 deletions tests/methods/filetypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { CompositeBuilderClassConfig } from '../test-config-types';
import { Prop } from '../../src/internal/constants';
import { methodArgMocks } from '../mocks/method-arg-mocks';
import { SlackDto } from '../../src/internal';
import * as checks from '../checks';

export const filetypes = (params: CompositeBuilderClassConfig): void => {
const config = {
...params,
methodArgMock: methodArgMocks.filetypes,
methodName: Prop.Filetypes,
propSetterPropName: Prop.Filetypes,
slackDtoParamName: SlackDto.mapParam(Prop.Filetypes),
expectArray: true,
};

checks.settableProperty(config);
checks.literalBuild(config);
};
2 changes: 2 additions & 0 deletions tests/methods/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,5 @@ export * from './ts';
export * from './url';
export * from './value';
export * from './video-url';
export * from './max-files';
export * from './filetypes';
18 changes: 18 additions & 0 deletions tests/methods/max-files.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { CompositeBuilderClassConfig } from '../test-config-types';
import { Prop } from '../../src/internal/constants';
import { methodArgMocks } from '../mocks/method-arg-mocks';
import { SlackDto } from '../../src/internal';
import * as checks from '../checks';

export const maxFiles = (params: CompositeBuilderClassConfig): void => {
const config = {
...params,
methodArgMock: methodArgMocks.maxFiles,
methodName: Prop.MaxFiles,
propSetterPropName: Prop.MaxFiles,
slackDtoParamName: SlackDto.mapParam(Prop.MaxFiles),
};

checks.settableProperty(config);
checks.literalBuild(config);
};
2 changes: 2 additions & 0 deletions tests/mocks/method-arg-mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,6 @@ export const methodArgMocks = {
titleUrl: methodArgMocksByType.string,
thumbnailUrl: methodArgMocksByType.string,
videoUrl: methodArgMocksByType.string,
maxFiles: methodArgMocksByType.int,
filetypes: methodArgMocksByType.arrayStrings,
};