Markdown renders formatted text blocks from Markdown source. Use it for documentation fragments, release notes, rich helper content, lists, links, and fenced code blocks.
Python Contract¶
sdk.ui.Markdown(
id: str,
text: Any,
)text accepts literal Markdown, store bindings, and data-model bindings from the constructor. When a bound text value changes at runtime, desktop and web update the rendered Markdown without requiring a full page render.
Supported Properties¶
| Property | Type | Required | Python | YAML | Desktop | Web | Notes |
|---|---|---|---|---|---|---|---|
id |
str |
yes | yes | yes | yes | yes | Stable component id |
text |
str or binding | yes | constructor / text.set |
yes | yes | yes | Markdown source string; supports runtime binding updates |
style |
str | no | yes | yes | yes | yes | Inline style string applied to the rendered container |
content_style |
str | no | set_property |
yes | yes | no | Desktop-only style applied to rendered Markdown/code children |
show_if |
rule | no | yes | yes | yes | yes | Generic visibility contract |
hide_if |
rule | no | yes | yes | yes | yes | Generic visibility contract |
required_permissions |
list[str] | no | yes | yes | yes | yes | Generic permission gate |
Binding Paths¶
The component test page uses these paths:
- Store:
/components_test/markdown/text - Data model:
/components_test/markdown_model/text - Visibility store:
/components_test/visibility/markdown_show,/components_test/visibility/markdown_hide
Static Example¶
builder.add(
sdk.ui.Markdown(
"components_test_markdown_static",
"### Static Markdown\n\n- Literal Markdown\n- Rendered rich text",
)
)- kind: Markdown
id: components_test_markdown_yaml_static
text: |
### Static Markdown
- Literal Markdown
- Rendered rich textStore Binding Example¶
from democrai.sdk.ui import bound
builder.add(
sdk.ui.Markdown(
"components_test_markdown_store",
bound.store(
"/components_test/markdown/text",
scope="page",
default="### Store Markdown\n\nContent follows page store.",
),
)
)- kind: Markdown
id: components_test_markdown_yaml_store
text:
type: store
scope: page
path: /components_test/markdown/text
default: "### Store Markdown\n\nContent follows page store."Data Model Binding Example¶
builder.add(
sdk.ui.Markdown(
"components_test_markdown_data",
bound.data(
"/components_test/markdown_model/text",
default="### Data Markdown\n\nContent follows the surface data model.",
),
)
)- kind: Markdown
id: components_test_markdown_yaml_data
text: "@data/components_test/markdown_model/text"Runtime Property Update Example¶
builder.add(
sdk.ui.Markdown(
"components_test_markdown_live",
"### Runtime Markdown\n\nDefault content.",
)
)
builder.add(
sdk.ui.Button(
"components_test_markdown_set_alt_btn",
"Set alternate",
action="components.content_test_set",
params={"component": "markdown", "state_key": "alternate"},
variant="default",
)
)- kind: Markdown
id: components_test_markdown_yaml_live
text: |
### Runtime Markdown
Default content.
capabilities: [text.set]
- kind: Button
id: components_test_markdown_yaml_set_alt_btn
label: "Set alternate"
variant: default
action: components.content_test_set
params: {component: markdown, state_key: alternate}The action sends a plain Markdown string in the text property update. Direct property updates require the component to allow text.set; store and data-model binding updates do not require a capability declaration.
surface_id = str(ctx.get("_surface_id") or "main").strip() or "main"
return sdk.effects.respond(
sdk.effects.ui_property_update(
"components_test_markdown_live",
"text",
"### Updated Markdown\n\n- Data changed\n- Property updated",
surface_id=surface_id,
)
)Visibility And Permissions Example¶
markdown = sdk.ui.Markdown(
"components_test_markdown_show_if",
"### show_if visible\n\nVisibility rule target.",
)
markdown.set_show_if({
"conditions": [
{
"left": bound.store(
"/components_test/visibility/markdown_show",
scope="page",
default=True,
),
"op": "==",
"right": True,
}
]
})
builder.add(markdown)
gated = sdk.ui.Markdown(
"components_test_markdown_required_permissions",
"### required_permissions gate",
)
gated.set_required_permissions(["components.content.visibility"])
builder.add(gated)- kind: Markdown
id: components_test_markdown_yaml_show_if
text: "### show_if visible"
show_if:
conditions:
- left:
type: store
scope: page
path: /components_test/visibility/markdown_show
default: true
op: "=="
right: true
- kind: Markdown
id: components_test_markdown_yaml_hide_if
text: "### hide_if visible"
hide_if:
conditions:
- left:
type: store
scope: page
path: /components_test/visibility/markdown_hide
default: false
op: "=="
right: true
- kind: Markdown
id: components_test_markdown_yaml_required_permissions
text: "### required_permissions gate"
required_permissions: [components.content.visibility]Use an action to update the store values observed by show_if and hide_if.
Rendered Output¶
Desktop¶

Web¶

Usage Guidance¶
- Use
Markdownwhen the content requires formatting that plainTextdoes not provide. - Bind
textfrom the constructor when Markdown content follows store or data-model state; runtime binding updates refresh the rendered Markdown. - Declare
text.setin YAML when direct property updates target the component. - Use
show_if,hide_if, andrequired_permissionsfor visibility and authorization gates.