-
-
Notifications
You must be signed in to change notification settings - Fork 47
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
Add support for RichText elements group #133
Comments
Any idea when this may be worked on? |
Another related enhancement #85 |
I'd say there is a better workaround available, as the compositional API makes it really easy to fall back into raw JSON if you need it:
It's possible that this very bare bones implementation will break some advanced usage (I couldn't get the TS types just right; hence the |
I wound up writing some components to support my needs (basic bulleted lists with nesting) for an internal project. If I had to guess, I'd imagine @raycharius (and/or any other maintainers) haven't yet added support because rich text is extremely verbose w.r.t. boilerplate, so it's unlikely to be used unless people absolutely need it. If it were me, I'd want to come up with a builder design that reduces that complexity somewhat for common use cases, otherwise things are likely to get quite unreadable quite quickly in user code. I'll share the code that I wrote here in case someone wants to use it as a starting point for a PR. Note that I started off using the internal mixins, but I ran into issues and wound up writing the common methods like import {
Appendable,
BlockBuilderBase,
ElementBuilderBase,
getElementsForContext,
Settable,
SlackBlockDto,
SlackElementDto
} from 'slack-block-builder/dist/internal';
export class RichTextTextElementBuilder extends ElementBuilderBase {
constructor(options?: { text?: string }) {
super();
const { text } = options ?? {};
this.text(text);
}
bold(value: Settable<boolean> = true) {
return this.set(value, 'bold');
}
italic(value: Settable<boolean> = true) {
return this.set(value, 'italic');
}
strike(value: Settable<boolean> = true) {
return this.set(value, 'strike');
}
code(value: Settable<boolean> = true) {
return this.set(value, 'code');
}
text(value: Settable<string>) {
return this.set(value, 'text');
}
build() {
return this.getResult(SlackElementDto, {
type: 'text',
text: this.props.text,
...(this.props.bold || this.props.italic || this.props.strike || this.props.code
? {
style: {
bold: this.props.bold,
italic: this.props.italic,
strike: this.props.strike,
code: this.props.code
}
}
: {})
});
}
}
export function RichTextTextElement(options?: { text?: string }) {
return new RichTextTextElementBuilder(options);
}
export class RichTextSectionBuilder extends ElementBuilderBase {
elements<T>(...elements: Appendable<T>) {
return this.append(elements.flat(), 'elements');
}
build() {
return this.getResult(SlackElementDto, {
type: 'rich_text_section',
elements: getElementsForContext(this.props.elements)
});
}
}
export function RichTextSection() {
return new RichTextSectionBuilder();
}
export class RichTextListBuilder extends ElementBuilderBase {
style(style: Settable<'bullet' | 'ordered'>) {
return this.set(style, 'style');
}
indent(indent: Settable<number>) {
return this.set(indent, 'indent');
}
border(border: Settable<number>) {
return this.set(border, 'border');
}
offset(offset: Settable<number>) {
return this.set(offset, 'offset');
}
elements<T>(...elements: Appendable<T>) {
return this.append(elements.flat(), 'elements');
}
build() {
return this.getResult(SlackElementDto, {
type: 'rich_text_list',
style: this.props.style ?? 'bullet',
indent: this.props.indent,
border: this.props.border,
offset: this.props.offset,
elements: getElementsForContext(this.props.elements)
});
}
}
export function RichTextList() {
return new RichTextListBuilder();
}
export class RichTextBuilder extends BlockBuilderBase {
blockId(value: Settable<string>) {
return this.set(value, 'block_id');
}
elements<T>(...elements: Appendable<T>) {
return this.append(elements.flat(), 'elements');
}
end() {
return this;
}
build() {
return this.getResult(SlackBlockDto, {
type: 'rich_text',
elements: getElementsForContext(this.props.elements)
});
}
}
export function RichText() {
return new RichTextBuilder();
} Example usage (simple bulleted list with nesting and text styling): RichText().elements(
RichTextSection().elements(
RichTextTextElement().text('Title of list').bold(),
RichTextTextElement().text('\n')
),
RichTextList().elements(
// top-level bullet
RichTextSection().elements(
// styled and unstyled text on the same line, just here to show how verbose this stuff is
RichTextTextElement().text('list item:').bold(),
RichTextTextElement().text('1')
),
// sub-list
RichTextSection().elements(
RichTextList().indent(1).elements(
RichTextSection().elements(
RichTextTextElement().text('sub item:').bold(),
RichTextTextElement().text('1.1')
),
RichTextSection().elements(
RichTextTextElement().text('sub item:').bold(),
RichTextTextElement().text('1.2')
)
)
),
// top-level bullet
RichTextSection().elements(
RichTextTextElement().text('list item:').bold(),
RichTextTextElement().text('2')
),
// top-level bullet
RichTextSection().elements(
RichTextTextElement().text('list item:').bold(),
RichTextTextElement().text('3')
)
)
) |
Yeah, a really good code sample to start with. It could be expanded to support even more functionality (like user and channel tags), but still it's pretty good. Thanks! |
Is your feature request related to a problem? Please describe.
Currently, it is not possible to create and manage RichText elements as they are not supported by this package.
So in order to use any RichText element (input, section or block), you have to use builder, build to json, parse the result, manually add RichText elements, convert updated entity to json again. This may be used as a workaround (but still a bad one), but when you have to add such elements multiple times - it's pure hell to manage it manually.
Describe the solution you'd like
Add support for RichText (section, input, block, etc.).
Describe alternatives you've considered
You can manually add this (as was described in first section), but I thinkits not even a workaround.
Additional context
So if you only need f.e. to add it to the end of your UI - it may seem OK.
But for more complex UI with multiple unsupported elements - it will be pure hell to manage it.
The text was updated successfully, but these errors were encountered: