From dbc777b31d250fc9b7d8cb25ac9bc9c9fdaf10bc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 20:41:49 +0000 Subject: [PATCH 1/2] Initial plan From 892f39e79ff449f298ba7c32259b98a076e1c484 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 20:45:27 +0000 Subject: [PATCH 2/2] Add style tag for colored text and backgrounds in markdown Co-authored-by: Assem-Uber <137278762+Assem-Uber@users.noreply.github.com> Agent-Logs-Url: https://github.com/cadence-workflow/cadence-web/sessions/a8127137-8723-4181-bbc7-f5727e7f9fda --- .../markdown/__tests__/markdoc.test.tsx | 38 ++++++++++++++ .../markdown/markdoc-components/index.ts | 2 + .../markdoc-components/style/style.markdoc.ts | 13 +++++ .../markdoc-components/style/style.tsx | 23 +++++++++ .../markdoc-components/style/style.types.ts | 7 +++ src/components/markdown/markdoc-schema.ts | 2 + src/views/docs/markdown/markdown-guide.ts | 49 +++++++++++++++++++ 7 files changed, 134 insertions(+) create mode 100644 src/components/markdown/markdoc-components/style/style.markdoc.ts create mode 100644 src/components/markdown/markdoc-components/style/style.tsx create mode 100644 src/components/markdown/markdoc-components/style/style.types.ts diff --git a/src/components/markdown/__tests__/markdoc.test.tsx b/src/components/markdown/__tests__/markdoc.test.tsx index f5967cca9..f02ae04a2 100644 --- a/src/components/markdown/__tests__/markdoc.test.tsx +++ b/src/components/markdown/__tests__/markdoc.test.tsx @@ -123,4 +123,42 @@ console.log('Hello'); expect(screen.getByText('Bold text')).toBeInTheDocument(); expect(screen.getByText('italic text')).toBeInTheDocument(); }); + + it('renders style tag with color', () => { + const content = '{% style color="red" %}red text{% /style %}'; + render(); + + const styledEl = screen.getByText('red text'); + expect(styledEl).toBeInTheDocument(); + expect(styledEl).toHaveStyle({ color: 'red' }); + }); + + it('renders style tag with background color', () => { + const content = '{% style bg="yellow" %}highlighted text{% /style %}'; + render(); + + const styledEl = screen.getByText('highlighted text'); + expect(styledEl).toBeInTheDocument(); + expect(styledEl).toHaveStyle({ backgroundColor: 'yellow' }); + }); + + it('renders style tag with both color and background', () => { + const content = + '{% style color="white" bg="blue" %}styled text{% /style %}'; + render(); + + const styledEl = screen.getByText('styled text'); + expect(styledEl).toBeInTheDocument(); + expect(styledEl).toHaveStyle({ color: 'white', backgroundColor: 'blue' }); + }); + + it('renders nested style tags', () => { + const content = + '{% style color="blue" %}outer {% style color="red" %}inner{% /style %}{% /style %}'; + render(); + + const innerEl = screen.getByText('inner'); + expect(innerEl).toBeInTheDocument(); + expect(innerEl).toHaveStyle({ color: 'red' }); + }); }); diff --git a/src/components/markdown/markdoc-components/index.ts b/src/components/markdown/markdoc-components/index.ts index 55e6d7904..5d1fb597a 100644 --- a/src/components/markdown/markdoc-components/index.ts +++ b/src/components/markdown/markdoc-components/index.ts @@ -6,6 +6,7 @@ import InlineCode from './inline-code/inline-code'; import List from './list/list'; import SignalButton from './signal-button/signal-button'; import StartWorkflowButton from './start-workflow-button/start-workflow-button'; +import Style from './style/style'; // Export all components that Markdoc can use export const markdocComponents = { @@ -17,6 +18,7 @@ export const markdocComponents = { InlineCode, Image, Br, + Style, }; export type MarkdocComponents = typeof markdocComponents; diff --git a/src/components/markdown/markdoc-components/style/style.markdoc.ts b/src/components/markdown/markdoc-components/style/style.markdoc.ts new file mode 100644 index 000000000..ea1a21683 --- /dev/null +++ b/src/components/markdown/markdoc-components/style/style.markdoc.ts @@ -0,0 +1,13 @@ +export const styleMarkdocSchema = { + render: 'Style', + attributes: { + color: { + type: String, + required: false, + }, + bg: { + type: String, + required: false, + }, + }, +}; diff --git a/src/components/markdown/markdoc-components/style/style.tsx b/src/components/markdown/markdoc-components/style/style.tsx new file mode 100644 index 000000000..bd9b2c54f --- /dev/null +++ b/src/components/markdown/markdoc-components/style/style.tsx @@ -0,0 +1,23 @@ +import { type StyleProps } from './style.types'; + +// Validates CSS color values to prevent injection of unexpected values. +// Accepts named colors, hex codes, and rgb/rgba/hsl/hsla functions. +function isValidCssColor(value: string): boolean { + return /^(#[0-9a-fA-F]{3,8}|rgb\(.*\)|rgba\(.*\)|hsl\(.*\)|hsla\(.*\)|[a-zA-Z]+)$/.test( + value.trim() + ); +} + +export default function Style({ color, bg, children }: StyleProps) { + const cssStyle: React.CSSProperties = {}; + + if (color && isValidCssColor(color)) { + cssStyle.color = color; + } + + if (bg && isValidCssColor(bg)) { + cssStyle.backgroundColor = bg; + } + + return {children}; +} diff --git a/src/components/markdown/markdoc-components/style/style.types.ts b/src/components/markdown/markdoc-components/style/style.types.ts new file mode 100644 index 000000000..cdbacfe67 --- /dev/null +++ b/src/components/markdown/markdoc-components/style/style.types.ts @@ -0,0 +1,7 @@ +import { type ReactNode } from 'react'; + +export type StyleProps = { + color?: string; + bg?: string; + children?: ReactNode; +}; diff --git a/src/components/markdown/markdoc-schema.ts b/src/components/markdown/markdoc-schema.ts index 4c7b76c3a..6417cf37f 100644 --- a/src/components/markdown/markdoc-schema.ts +++ b/src/components/markdown/markdoc-schema.ts @@ -8,6 +8,7 @@ import { inlineCodeMarkdocSchema } from './markdoc-components/inline-code/inline import { listMarkdocSchema } from './markdoc-components/list/list.markdoc'; import { signalButtonMarkdocSchema } from './markdoc-components/signal-button/signal-button.markdoc'; import { startWorkflowButtonMarkdocSchema } from './markdoc-components/start-workflow-button/start-workflow-button.markdoc'; +import { styleMarkdocSchema } from './markdoc-components/style/style.markdoc'; export const markdocConfig: Config = { tags: { @@ -15,6 +16,7 @@ export const markdocConfig: Config = { start: startWorkflowButtonMarkdocSchema, image: imageSchema, br: brSchema, + style: styleMarkdocSchema, }, nodes: { // Standard HTML nodes diff --git a/src/views/docs/markdown/markdown-guide.ts b/src/views/docs/markdown/markdown-guide.ts index 8d7b81e3d..b07c2d2bc 100644 --- a/src/views/docs/markdown/markdown-guide.ts +++ b/src/views/docs/markdown/markdown-guide.ts @@ -127,6 +127,55 @@ Image with 100px height: Image with 100px width and 100px height: {% image src="https://cadenceworkflow.io/assets/images/workflow-84ef76d93c7ff138714a0aa7c9b92841.png" alt="Image with 100px width and 100px height" width="100" height="100" /%} +## Styled Text + +Use the \`{% style %}\` tag to apply custom text color or background color to any content. + +### Color + +Use the \`color\` attribute to set the text color: + +\`\`\` +{% style color="red" %}red text{% /style %} +{% style color="#0070f3" %}blue text{% /style %} +\`\`\` + +{% style color="red" %}red text{% /style %} + +{% style color="green" %}green text{% /style %} + +### Background + +Use the \`bg\` attribute to set the background color: + +\`\`\` +{% style bg="yellow" %}highlighted text{% /style %} +\`\`\` + +{% style bg="yellow" %}highlighted text{% /style %} + +### Combined + +Use both \`color\` and \`bg\` together: + +\`\`\` +{% style color="white" bg="blue" %}white text on blue background{% /style %} +\`\`\` + +{% style color="white" bg="blue" %}white text on blue background{% /style %} + +### Nesting + +Tags can be nested for fine-grained control: + +\`\`\` +{% style color="blue" %} + This is blue text, {% style color="red" %}this part is red{% /style %}, and back to blue. +{% /style %} +\`\`\` + +{% style color="blue" %}This is blue text, {% style color="red" %}this part is red{% /style %}, and back to blue.{% /style %} + `; export default content;