diff --git a/webapp/channels/src/utils/__snapshots__/message_html_to_component.test.tsx.snap b/webapp/channels/src/utils/__snapshots__/message_html_to_component.test.tsx.snap index af71c5e7a7..b83bf4a2f1 100644 --- a/webapp/channels/src/utils/__snapshots__/message_html_to_component.test.tsx.snap +++ b/webapp/channels/src/utils/__snapshots__/message_html_to_component.test.tsx.snap @@ -147,7 +147,7 @@ exports[`messageHtmlToComponent link with enabled a tooltip plugin 1`] = ` { }); }); }); + +describe('convertPropsToReactStandard', () => { + test('converts class to className', () => { + const inputProps = {class: 'button-class'} as AnchorHTMLAttributes; + const expected = {className: 'button-class'}; + + expect(convertPropsToReactStandard(inputProps)).toEqual(expected); + }); + + test('converts for to htmlFor', () => { + const inputProps = {for: 'input-id'} as AnchorHTMLAttributes; + const expected = {htmlFor: 'input-id'}; + + expect(convertPropsToReactStandard(inputProps)).toEqual(expected); + }); + + test('converts tabindex to tabIndex', () => { + const inputProps = {tabindex: '0'} as AnchorHTMLAttributes; + const expected = {tabIndex: '0'}; + + expect(convertPropsToReactStandard(inputProps)).toEqual(expected); + }); + + test('converts readonly to readOnly', () => { + const inputProps = {readonly: true} as AnchorHTMLAttributes; + const expected = {readOnly: true}; + + expect(convertPropsToReactStandard(inputProps)).toEqual(expected); + }); + + test('keeps other properties unchanged', () => { + const inputProps = {id: 'unique-id', type: 'text'} as AnchorHTMLAttributes; + const expected = {id: 'unique-id', type: 'text'}; + + expect(convertPropsToReactStandard(inputProps)).toEqual(expected); + }); + + test('handles multiple conversions and keeps other properties', () => { + const inputProps = { + class: 'button-class', + for: 'input-id', + tabindex: '0', + readonly: true, + id: 'unique-id', + }; + const expected = { + className: 'button-class', + htmlFor: 'input-id', + tabIndex: '0', + readOnly: true, + id: 'unique-id', + }; + expect(convertPropsToReactStandard(inputProps)).toEqual(expected); + }); +}); diff --git a/webapp/channels/src/utils/message_html_to_component.tsx b/webapp/channels/src/utils/message_html_to_component.tsx index 15eb7fb702..abedbd0c82 100644 --- a/webapp/channels/src/utils/message_html_to_component.tsx +++ b/webapp/channels/src/utils/message_html_to_component.tsx @@ -2,6 +2,7 @@ // See LICENSE.txt for license information. import {Parser, ProcessNodeDefinitions} from 'html-to-react'; +import type {AllHTMLAttributes} from 'react'; import React from 'react'; import AtMention from 'components/at_mention'; @@ -64,7 +65,7 @@ type ProcessingInstruction = { * - hasPluginTooltips - If specified, the LinkTooltip component is placed inside links. Defaults to false. * - channelId = If specified, to be passed along to ProfilePopover via AtMention */ -export function messageHtmlToComponent(html: string, options: Options = {}) { +export default function messageHtmlToComponent(html: string, options: Options = {}) { if (!html) { return null; } @@ -112,7 +113,7 @@ export function messageHtmlToComponent(html: string, options: Options = {}) { shouldProcessNode: (node: any) => node.type === 'tag' && node.name === 'a' && node.attribs.href, processNode: (node: any, children: any) => { return ( - + {children} ); @@ -281,4 +282,32 @@ export function messageHtmlToComponent(html: string, options: Options = {}) { return parser.parseWithInstructions(html, isValidNode, processingInstructions); } -export default messageHtmlToComponent; +/** + * This function converts HTML attributes to React-specific props. + * For example, it changes 'class' to 'className'. Note that this function + * is not exhaustive and may not cover all HTML attributes. Add more cases as needed. + */ +export function convertPropsToReactStandard(propsToConvert: AllHTMLAttributes): Record { + const newProps: Record = {}; + + for (const [key, value] of Object.entries(propsToConvert)) { + switch (key) { + case 'class': + newProps.className = value; + break; + case 'for': + newProps.htmlFor = value; + break; + case 'tabindex': + newProps.tabIndex = value; + break; + case 'readonly': + newProps.readOnly = value; + break; + default: + newProps[key] = value; + } + } + + return newProps; +}