### Ordered List Visual Example Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/ordered_unordered_lists.md Demonstrates the visual structure of a nested ordered list with first, second, and third-level items. ```plaintext 1. First level item a. Second level item i. Third level item b. Another second level 2. Back to first level ``` -------------------------------- ### Custom Resource ImageLoader Implementation Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/images.md Implement `ImageLoader` to load images from resources using `painterResource`. This example shows how to handle integer resource IDs. ```kotlin @OptIn(ExperimentalRichTextApi::class) object MyResourceImageLoader : ImageLoader { @Composable override fun load(model: Any): ImageData? { val id = model as? Int ?: return null return ImageData( painter = painterResource(id), contentScale = ContentScale.Fit, ) } } ``` -------------------------------- ### Unordered List Visual Example Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/ordered_unordered_lists.md Illustrates the visual appearance of a nested unordered list using different bullet styles for each level. ```plaintext • First level item ◦ Second level item ▪ Third level item ◦ Another second level • Back to first level ``` -------------------------------- ### Define onSelect for Token Creation Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md The onSelect lambda must return a RichSpanStyle.Token with a matching triggerId and a label that starts with the trigger's character. ```kotlin onSelect = { user -> RichSpanStyle.Token( triggerId = "mention", id = user.id, // stable id for serialization label = "@" + user.handle, // MUST begin with '@' ) } ``` -------------------------------- ### Configure List Prefix Alignment Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/ordered_unordered_lists.md Control the alignment of list markers relative to the indent gutter. `ListPrefixAlignment.End` aligns markers to the content start, while `ListPrefixAlignment.Start` aligns them to the indent origin. ```kotlin // Default: HTML-style - the marker sits inside the gutter and ends at the content // start, so "1." and "10." have their dots aligned vertically. richTextState.config.listPrefixAlignment = ListPrefixAlignment.End // Alternative: every item's marker starts at the same left edge, giving a uniform // left edge even when item widths differ (e.g. "1." vs "10."). richTextState.config.listPrefixAlignment = ListPrefixAlignment.Start ``` -------------------------------- ### Get Selected Link Text and URL Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/links.md Retrieve the text and URL of the currently selected hyperlink using `selectedLinkText` and `selectedLinkUrl` properties. ```kotlin // Get link text and URL val linkText = richTextState.selectedLinkText val linkUrl = richTextState.selectedLinkUrl ``` -------------------------------- ### Commit Token Programmatically Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md Insert a token directly without using the suggestion popup. Ensure a matching query is active, the trigger is registered, and the label starts with the trigger character. ```kotlin state.insertToken( triggerId = "mention", id = "u123", label = "@mohamed", ) ``` -------------------------------- ### Add Compose Rich Editor Dependency Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Add the Compose Rich Editor dependency to your project's build.gradle file to start using the library. ```kotlin implementation("com.mohamedrejeb.richeditor:richeditor-compose:1.0.0-rc14") ``` -------------------------------- ### Get and Check Current Paragraph Styles Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/paragraph_style.md Retrieve the current paragraph style of the selection to check properties like text alignment. This is useful for UI feedback or conditional styling. ```kotlin val currentParagraphStyle = richTextState.currentParagraphStyle val isCentered = currentParagraphStyle.textAlign == TextAlign.Center val isLeft = currentParagraphStyle.textAlign == TextAlign.Left val isRight = currentParagraphStyle.textAlign == TextAlign.Right val isJustified = currentParagraphStyle.textAlign == TextAlign.Justify ``` -------------------------------- ### Insert Image from HTML Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/images.md Import HTML content containing `` tags to display images. The parser uses `width` and `height` attributes for initial sizing. ```kotlin val html = """

Header paragraph.

Footer paragraph.

""" state.setHtml(html) ``` -------------------------------- ### Get Current Paragraph Style Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Access RichTextState.currentParagraphStyle to retrieve the paragraph style of the current selection, useful for UI feedback. ```kotlin val currentParagraphStyle = richTextState.currentParagraphStyle val isCentered = currentParagraphStyle.textAlign = TextAlign.Center ``` -------------------------------- ### Get Current Span Style Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Access RichTextState.currentSpanStyle to retrieve the span style of the current selection, useful for UI feedback. ```kotlin val currentSpanStyle = richTextState.currentSpanStyle val isBold = currentSpanStyle.fontWeight = FontWeight.Bold ``` -------------------------------- ### Apply Text and Background Colors Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/span_style.md Set the text color using the `color` property and the background color using the `background` property. ```kotlin richTextState.addSpanStyle(SpanStyle( color = Color.Blue )) richTextState.addSpanStyle(SpanStyle( background = Color.Yellow )) ``` -------------------------------- ### Initialize RichTextState with History Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/rich_text_state.md Configure the undo/redo history limit and coalescing window when creating the RichTextState. This allows for fine-grained control over undo behavior. ```kotlin val state = rememberRichTextState( historyLimit = 100, coalesceWindowMs = 500L, ) ``` -------------------------------- ### Handling Link Clicks Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/links.md Information on how to customize the default behavior for handling link clicks, allowing for custom logic when a link is activated. ```APIDOC ## Handling Link Clicks By default, links are opened by your platform's `UriHandler`. To customize link handling: ```kotlin val myUriHandler = remember { object : UriHandler { override fun openUri(uri: String) { // Custom link handling logic // For example: open in specific browser, validate URL, etc. } } } CompositionLocalProvider(LocalUriHandler provides myUriHandler) { RichText( state = richTextState, modifier = Modifier.fillMaxWidth() ) } ``` ``` -------------------------------- ### Compose Rich Text Editor Mentions Sample Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md Demonstrates how to set up and use the MentionsSample composable for @mention functionality in a rich text editor. It registers a trigger for '@' and displays suggestions. ```kotlin @OptIn(ExperimentalRichTextApi::class) @Composable fun MentionsSample() { val state = rememberRichTextState() LaunchedEffect(Unit) { state.registerTrigger( Trigger( id = "mention", char = '@', style = { SpanStyle(color = Color(0xFF0969DA), fontWeight = FontWeight.Medium) }, ) ) } Box { OutlinedRichTextEditor(state = state) TriggerSuggestions( state = state, triggerId = "mention", suggestions = { query -> users.filter { it.handle.contains(query, ignoreCase = true) } }, onSelect = { user -> RichSpanStyle.Token( triggerId = "mention", id = user.id, label = user.handle, // must start with '@' ) }, item = { user -> Column { Text(user.handle, fontWeight = FontWeight.Medium) Text(user.name, style = MaterialTheme.typography.bodySmall) } }, ) } } ``` -------------------------------- ### Basic ExpandableRichText Usage Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/expandable_text.md Demonstrates how to use ExpandableRichText with a hoisted expanded state. The composable is marked @ExperimentalRichTextApi. ```kotlin @OptIn(ExperimentalRichTextApi::class) @Composable fun PostBody(state: RichTextState) { var expanded by rememberSaveable { mutableStateOf(false) } ExpandableRichText( state = state, expanded = expanded, onExpandedChange = { expanded = it }, collapsedMaxLines = 3, ) } ``` -------------------------------- ### Get Current Paragraph Style Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/README.md Retrieve the current ParagraphStyle of the selected text using RichTextState.currentParagraphStyle. This enables checking for paragraph-level formatting, such as text alignment. ```kotlin val currentParagraphStyle = richTextState.currentParagraphStyle val isCentered = currentParagraphStyle.textAlign == TextAlign.Center ``` -------------------------------- ### Provide Coil3ImageLoader via CompositionLocal Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/images.md Provide the `Coil3ImageLoader` using `CompositionLocalProvider` at the root of your editor screen to handle image loading. ```kotlin CompositionLocalProvider(LocalImageLoader provides Coil3ImageLoader) { RichText( state = state, modifier = Modifier.fillMaxWidth(), ) } ``` -------------------------------- ### Add Snapshots Repository to settings.gradle.kts Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/faq.md Configure dependency resolution management in settings.gradle.kts to include the snapshots repository for development builds. ```kotlin dependencyResolutionManagement { repositories { maven("https://s01.oss.sonatype.org/content/repositories/snapshots") } } ``` -------------------------------- ### Integrate Coil3 Image Loader Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Add the Coil3 dependency for network image loading and provide `Coil3ImageLoader` via `LocalImageLoader` to enable image rendering in the rich text editor. ```kotlin implementation("com.mohamedrejeb.richeditor:richeditor-compose-coil3:1.0.0-rc14") ``` ```kotlin CompositionLocalProvider(LocalImageLoader provides Coil3ImageLoader) { RichText(state = richTextState) } ``` -------------------------------- ### Initialize RichTextState Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/getting_started.md Create and remember a RichTextState instance to manage the editor's state. This state is required by the RichTextEditor composable. ```kotlin val state = rememberRichTextState() RichTextEditor( state = state, ) ``` -------------------------------- ### Provide Custom ImageLoader via CompositionLocal Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/images.md Provide your custom `ImageLoader` (e.g., `MyResourceImageLoader`) using `CompositionLocalProvider` to integrate it with the editor. ```kotlin CompositionLocalProvider(LocalImageLoader provides MyResourceImageLoader) { RichText(state = state) } ``` -------------------------------- ### Import HTML Content Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Convert an HTML string into a `RichTextState` object using the `setHtml` method. This is useful for loading pre-formatted text. ```kotlin val html = "

Compose Rich Editor

" richTextState.setHtml(html) ``` -------------------------------- ### Heading Button Active State and Click Handler Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/headings.md Implement toolbar buttons to reflect the active heading style and toggle between heading levels and normal paragraphs. ```kotlin HeadingButton( label = "H2", isActive = state.currentHeadingStyle == HeadingStyle.H2, onClick = { val next = if (state.currentHeadingStyle == HeadingStyle.H2) HeadingStyle.Normal else HeadingStyle.H2 state.setHeadingStyle(next) }, ) ``` -------------------------------- ### Import Markdown to RichTextState Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Use the `setMarkdown` method to convert a Markdown string into the RichTextState object. This replaces the current content. ```kotlin val markdown = "**Compose** *Rich* Editor" richTextState.setMarkdown(markdown) ``` -------------------------------- ### Convert Between Heading Levels and Formats Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/headings.md Convert between heading levels using integers, HTML tag names, or access serialization constants like `markdownPrefix` and `htmlTag`. ```kotlin // From an integer (e.g. a toolbar picker) val style = HeadingStyle.fromLevel(3) // H3 // From an HTML tag name val fromHtml = HeadingStyle.fromHtmlTag("h2") // H2 val unknown = HeadingStyle.fromHtmlTag("div") // Normal // Access the serialization constants directly HeadingStyle.H3.markdownPrefix // "### " HeadingStyle.H3.htmlTag // "h3" ``` -------------------------------- ### Customizing ExpandableRichText Labels Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/expandable_text.md Shows how to customize the 'See more' and 'See less' labels using plain strings or resource strings for localization. ```kotlin ExpandableRichText( state = state, expanded = expanded, onExpandedChange = { expanded = it }, collapsedMaxLines = 4, seeMoreLabel = "… read more", seeLessLabel = " hide", ) ``` ```kotlin ExpandableRichText( state = state, expanded = expanded, onExpandedChange = { expanded = it }, seeMoreLabel = stringResource(R.string.expandable_see_more), seeLessLabel = stringResource(R.string.expandable_see_less), ) ``` -------------------------------- ### Configure List Behavior Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/rich_text_state.md Control how users exit lists. Setting exitListOnEmptyItem to true allows exiting a list by pressing Enter on an empty item. ```kotlin richTextState.config.exitListOnEmptyItem = true ``` -------------------------------- ### Customizing Links Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/links.md How to customize the appearance of links, including color and text decoration. ```APIDOC ## Customizing Links ### Link Appearance You can customize how links appear in the editor: ```kotlin richTextState.config.linkColor = Color.Blue richTextState.config.linkTextDecoration = TextDecoration.Underline ``` ``` -------------------------------- ### Add Snapshots Repository to build.gradle.kts Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/faq.md Include the snapshots repository in your project's build.gradle.kts file to access development versions. ```kotlin allprojects { repositories { maven("https://s01.oss.sonatype.org/content/repositories/snapshots") } } ``` -------------------------------- ### Provide Screen-wide Token Click Handler Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md Use CompositionLocalProvider with LocalTokenClickHandler to set a default handler for all RichText composables within a scope. Per-composable handlers take precedence. ```kotlin CompositionLocalProvider( LocalTokenClickHandler provides TokenClickHandler { token, _ -> openReferenceSheet(token) }, ) { // every RichText here inherits the handler RichText(state = commentState) RichText(state = replyState) } ``` -------------------------------- ### Import Markdown to RichTextState Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/markdown_import_export.md Use the `setMarkdown` method to convert Markdown strings into a `RichTextState` object. This method handles both simple and complex Markdown structures. ```kotlin val simpleMarkdown = """ **Bold** and *italic* text with __underline__ """.trimIndent() richTextState.setMarkdown(simpleMarkdown) ``` ```kotlin val complexMarkdown = """ # Heading 1 ## Heading 2 Paragraph with **bold** and *italic* text. * Unordered list item 1 * Unordered list item 2 1. Ordered list item 1 2. Ordered list item 2 [Link to Example](https://example.com) `Code span example` """.trimIndent() richTextState.setMarkdown(complexMarkdown) ``` -------------------------------- ### Configure Code Block Appearance Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/rich_text_state.md Set the appearance for code spans, including color and background. This allows for distinct styling of code blocks. ```kotlin richTextState.config.codeSpanColor = Color.Yellow richTextState.config.codeSpanBackgroundColor = Color.Transparent richTextState.config.codeSpanStrokeColor = Color.LightGray ``` -------------------------------- ### Apply Text Indentation Style Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/paragraph_style.md Configure text indentation for paragraphs, specifying different indents for the first line and subsequent lines using `TextIndent`. ```kotlin richTextState.addParagraphStyle( ParagraphStyle( textIndent = TextIndent( firstLine = 20.sp, // First line indent restLine = 10.sp // Rest of lines indent ) ) ) ``` -------------------------------- ### Handle Link Clicks with Custom UriHandler Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/faq.md Implement a custom UriHandler to manage link clicks instead of relying on the platform's default behavior. Provide this handler via CompositionLocalProvider. ```kotlin val myUriHandler = remember { object : UriHandler { override fun openUri(uri: String) { // Your custom link handling logic } } } CompositionLocalProvider(LocalUriHandler provides myUriHandler) { RichText( state = richTextState, modifier = Modifier.fillMaxWidth() ) } ``` -------------------------------- ### Import HTML to RichTextState Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/html_import_export.md Use the `setHtml` method to convert HTML strings into the editor's rich text state. Supports basic formatting and complex structures including lists, links, and code blocks. ```kotlin val simpleHtml = """

Bold and italic text with underline

""" richTextState.setHtml(simpleHtml) ``` ```kotlin val complexHtml = """

Title

Paragraph with bold and italic text.

  1. Ordered list item 1
  2. Ordered list item 2

Link to Example

Code block example
""" richTextState.setHtml(complexHtml) ``` -------------------------------- ### Use Snapshot Version in build.gradle.kts Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/faq.md Specify the snapshot version of the Compose Rich Editor library in your build.gradle.kts file. ```kotlin implementation("com.mohamedrejeb.richeditor:richeditor-compose:1.0.0-SNAPSHOT") ``` -------------------------------- ### Toggle Ordered and Unordered Lists Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/ordered_unordered_lists.md Use these functions to toggle ordered or unordered lists for the current selection. Ensure RichTextState is initialized. ```kotlin richTextState.toggleOrderedList() // Toggle unordered list. richTextState.toggleUnorderedList() ``` -------------------------------- ### Apply Text Alignment Styles Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/paragraph_style.md Set the text alignment for paragraphs to center, left, right, or justify using `addParagraphStyle`. ```kotlin richTextState.addParagraphStyle( ParagraphStyle( textAlign = TextAlign.Center ) ) richTextState.addParagraphStyle( ParagraphStyle( textAlign = TextAlign.Left ) ) richTextState.addParagraphStyle( ParagraphStyle( textAlign = TextAlign.Right ) ) richTextState.addParagraphStyle( ParagraphStyle( textAlign = TextAlign.Justify ) ) ``` -------------------------------- ### Basic List Operations Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/ordered_unordered_lists.md Toggle ordered and unordered lists, and check the current list state. ```APIDOC ## Basic List Operations ### Description Provides methods to toggle list types and query the current list state. ### Methods - `toggleOrderedList()`: Toggles the ordered list state for the current selection. - `toggleUnorderedList()`: Toggles the unordered list state for the current selection. - `isOrderedList` (getter): Returns `true` if the current selection is an ordered list, `false` otherwise. - `isUnorderedList` (getter): Returns `true` if the current selection is an unordered list, `false` otherwise. ### Usage Example ```kotlin // Toggle ordered list. richTextState.toggleOrderedList() // Toggle unordered list. richTextState.toggleUnorderedList() // Get if the current selection is an ordered list. val isOrderedList = richTextState.isOrderedList // Get if the current selection is an unordered list. val isUnorderedList = richTextState.isUnorderedList ``` ``` -------------------------------- ### Importing HTML Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/html_import_export.md Use the `setHtml` method to convert HTML strings into the editor's `RichTextState`. This method supports basic formatting, complex structures, lists, links, and custom tokens. ```APIDOC ## Importing HTML To convert HTML to `RichTextState`, use the `setHtml` method: ```kotlin // Basic formatting val simpleHtml = """

Bold and italic text with underline

""" richTextState.setHtml(simpleHtml) // Complex structure val complexHtml = """

Title

Paragraph with bold and italic text.

  1. Ordered list item 1
  2. Ordered list item 2

Link to Example

Code block example
""" richTextState.setHtml(complexHtml) ``` ``` -------------------------------- ### Markdown Serialization of Headings Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/headings.md ATX-style headings (`#`..`###### `) are serialized losslessly to Markdown. Setext-style headings are not supported on export. ```kotlin state.setHtml("

Section

Body.

") val markdown = state.toMarkdown() // "## Section\n\nBody." ``` -------------------------------- ### Registering /command Trigger Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md Registers a trigger for /commands with a teal color and monospace font family style. ```kotlin // /command state.registerTrigger( Trigger( id = "command", char = '/', style = { SpanStyle(color = Color(0xFF009688), fontFamily = FontFamily.Monospace) }, ) ) ``` -------------------------------- ### Save and Restore Editor Content Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/faq.md Convert editor content to HTML or Markdown for saving, and restore it using setHtml or setMarkdown methods. ```kotlin // Save content val html = richTextState.toHtml() // or val markdown = richTextState.toMarkdown() // Restore content richTextState.setHtml(savedHtml) // or richTextState.setMarkdown(savedMarkdown) ``` -------------------------------- ### HTML Serialization of Headings Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/headings.md Headings serialize to their corresponding HTML tags (e.g., `

`, `

`). Import recognizes `h1`-`h6` tags as heading styles. ```kotlin state.setMarkdown("# Title\n\nBody paragraph.") val html = state.toHtml() //

Title

Body paragraph.

``` -------------------------------- ### Apply Text Decoration Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/span_style.md Add underlines, strikethroughs, or a combination of both to text using the `textDecoration` property. ```kotlin richTextState.addSpanStyle(SpanStyle( textDecoration = TextDecoration.Underline // or TextDecoration.LineThrough // or TextDecoration.combine(listOf(TextDecoration.Underline, TextDecoration.LineThrough)) )) ``` -------------------------------- ### Token Serialization Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md Details how tokens are serialized to HTML and Markdown formats. ```APIDOC ## Serialization ### HTML Committed tokens are serialized as `` elements with `data-trigger-id` and `data-token-id` attributes. When parsing HTML with `setHtml`, unknown `triggerId`s are rendered as plain text. Ensure triggers are registered before loading HTML content containing tokens. ### Markdown Tokens serialize to a link-like format: `[label](trigger::)`. This format preserves readability and survives other Markdown renderers. Both `triggerId` and `tokenId` must not contain the `:` character. ``` -------------------------------- ### Configure List Marker Style Behavior Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/ordered_unordered_lists.md Control how list markers inherit styles from the list item's text. Use `InheritFromText` for default behavior matching Google Docs, or `AlwaysDefault` for consistent marker styling. ```kotlin richTextState.config.listMarkerStyleBehavior = ListMarkerStyleBehavior.InheritFromText ``` ```kotlin richTextState.config.listMarkerStyleBehavior = ListMarkerStyleBehavior.AlwaysDefault ``` -------------------------------- ### Customizing ExpandableBasicRichText Styling Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/expandable_text.md Demonstrates how to apply custom SpanStyle to the 'See more' label in ExpandableBasicRichText for full control over its appearance. ```kotlin ExpandableBasicRichText( state = state, expanded = expanded, onExpandedChange = { expanded = it }, seeMoreStyle = SpanStyle( color = Color(0xFF1F6FEB), fontWeight = FontWeight.SemiBold, textDecoration = TextDecoration.None, ), ) ``` -------------------------------- ### Programmatically Insert Image Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/images.md Construct `RichSpanStyle.Image` directly to insert images when composing content outside of HTML. Ensure at least one of `width` or `height` is specified. ```kotlin val image = RichSpanStyle.Image( model = "https://picsum.photos/id/1015/600/400", width = 600.sp, height = 400.sp, contentDescription = "Landscape photo", ) ``` -------------------------------- ### Register Triggers for Mentions, Hashtags, and Slash Commands Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Register custom triggers (like '@' for mentions) on the `RichTextState` and use `TriggerSuggestions` to display a popup for selecting suggestions. ```kotlin state.registerTrigger( Trigger(id = "mention", char = '@') ) Box { OutlinedRichTextEditor(state = state) TriggerSuggestions( state = state, triggerId = "mention", suggestions = { query -> users.filter { it.handle.contains(query, ignoreCase = true) } }, onSelect = { user -> RichSpanStyle.Token(triggerId = "mention", id = user.id, label = user.handle) }, item = { user -> Text(user.handle) }, ) } ``` -------------------------------- ### Markdown Image Syntax in Compose Rich Editor Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/images.md This demonstrates the standard Markdown image syntax supported for import and export. Note that programmatic sizes specified in HTML are lost during a Markdown round-trip. ```markdown ![alt text](https://.../hero.png) ``` -------------------------------- ### Handle Token Clicks in RichText Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md Wire click handlers to tokens in read-only RichText surfaces to drive actions like navigation or command execution. The tapOffset is in local coordinates. ```kotlin RichText( state = state, onTokenClick = { token, tapOffset -> when (token.triggerId) { "mention" -> openProfile(token.id) "hashtag" -> navigateToTag(token.id) "command" -> runCommand(token.id) } }, ) ``` -------------------------------- ### Export RichTextState to HTML Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/html_import_export.md Convert the current rich text state into a formatted HTML string using the `toHtml` method. The output is clean and properly formatted. ```kotlin val html = richTextState.toHtml() println(html) // Outputs formatted HTML string ``` -------------------------------- ### Undo and Redo Actions Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/rich_text_state.md Provide UI elements (like buttons) to trigger undo and redo actions on the RichTextState. The enabled state of these buttons reflects whether undo/redo is possible. ```kotlin IconButton(onClick = { state.history.undo() }, enabled = state.history.canUndo) { Icon(Icons.AutoMirrored.Filled.Undo, contentDescription = "Undo") } IconButton(onClick = { state.history.redo() }, enabled = state.history.canRedo) { Icon(Icons.AutoMirrored.Filled.Redo, contentDescription = "Redo") } ``` -------------------------------- ### Replace Text Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/rich_text_state.md Modify existing text by replacing a specified range or the selected text with new content. Styles are preserved during replacement. ```kotlin richTextState.replaceTextRange(TextRange(0, 5), "Hello") richTextState.replaceSelectedText("Hello") ``` -------------------------------- ### Basic RichTextEditor Usage Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/README.md Use the RichTextEditor composable, passing the rememberRichTextState instance to manage its state. This is the fundamental way to display and interact with the rich text editor. ```kotlin RichTextEditor( state = state, ) ``` -------------------------------- ### HTML Image Import/Export in Compose Rich Editor Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/images.md Use this snippet to import HTML content containing images into the editor and export it back to HTML. Attributes like src, width, height, and alt are mapped to the editor's model. ```kotlin state.setHtml("

\"Hero\"

") val roundTripped = state.toHtml() ``` -------------------------------- ### Handling Token Clicks and Hover Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md Enables handling user interactions with tokens in read-only rich text surfaces. ```APIDOC ## Handling Token Clicks and Hover ### onTokenClick #### Description Callback function invoked when a token is clicked. Provides the token and the tap offset within the composable. #### Parameters - **token** (RichSpanStyle.Token) - The token that was clicked. - **tapOffset** (Offset) - The local coordinates of the tap event. ### onTokenHover #### Description Callback function invoked when the pointer enters, exits, or moves between tokens. Provides the token and the pointer offset. #### Parameters - **token** (RichSpanStyle.Token?) - The token under the pointer, or null if not over a token. - **pointerOffset** (Offset) - The local coordinates of the pointer event. ### Screen-wide Defaults #### Description `LocalTokenClickHandler` and `LocalTokenHoverHandler` allow providing default handlers for all `RichText` composables within a `CompositionLocalProvider`. #### Example ```kotlin CompositionLocalProvider( LocalTokenClickHandler provides TokenClickHandler { token, _ -> openReferenceSheet(token) }, ) { // All RichText composables here inherit the handler RichText(state = commentState) RichText(state = replyState) } ``` **Note:** Per-composable `onTokenClick` and `onTokenHover` parameters take precedence over `CompositionLocal` defaults. ``` -------------------------------- ### Implement Trigger Suggestions Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md Use TriggerSuggestions composable within a Box alongside the editor. Render one TriggerSuggestions per registered trigger, filtering by activeTriggerQuery.triggerId. ```kotlin @Composable fun TriggerSuggestions( state: RichTextState, triggerId: String, suggestions: (query: String) -> List, onSelect: (T) -> RichSpanStyle.Token, modifier: Modifier = Modifier, verticalOffset: Dp = 4.dp, containerColor: Color = MaterialTheme.colorScheme.surface, contentColor: Color = MaterialTheme.colorScheme.onSurface, highlightColor: Color = MaterialTheme.colorScheme.surfaceVariant, shape: Shape = RoundedCornerShape(8.dp), maxVisibleItems: Int = 5, item: @Composable (T) -> Unit, ) ``` ```kotlin Box { OutlinedRichTextEditor(state = state) TriggerSuggestions(state = state, triggerId = "mention", ...) TriggerSuggestions(state = state, triggerId = "hashtag", ...) TriggerSuggestions(state = state, triggerId = "command", ...) } ``` -------------------------------- ### Apply Font Weight and Style Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/span_style.md Control the boldness and italicization of text using the `fontWeight` and `fontStyle` properties within `SpanStyle`. ```kotlin richTextState.addSpanStyle(SpanStyle( fontWeight = FontWeight.Bold // or FontWeight.W500, etc. )) richTextState.addSpanStyle(SpanStyle( fontStyle = FontStyle.Italic )) ``` -------------------------------- ### Handle Token Hovers in RichText Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md Implement hover handlers for tokens to display previews or tooltips. This fires on enter, exit, and change between adjacent tokens. ```kotlin RichText( state = state, onTokenHover = { token, pointerOffset -> hoveredToken = token }, ) ``` -------------------------------- ### Toggle Ordered and Unordered Lists Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Control list formatting by using `toggleOrderedList` and `toggleUnorderedList` methods on `RichTextState` to apply or remove list styles from the current selection. ```kotlin // Toggle ordered list. richTextState.toggleOrderedList() // Toggle unordered list. richTextState.toggleUnorderedList() ``` -------------------------------- ### Toggle, Add, and Remove Paragraph Styles Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/paragraph_style.md Use these methods to dynamically change paragraph styles. `toggleParagraphStyle` adds a style if it's not present and removes it if it is. `addParagraphStyle` overwrites existing values, while `removeParagraphStyle` reverts to the default. ```kotlin richTextState.toggleParagraphStyle(ParagraphStyle(textAlign = TextAlign.Center)) richTextState.addParagraphStyle(ParagraphStyle(textAlign = TextAlign.Center)) richTextState.removeParagraphStyle(ParagraphStyle(textAlign = TextAlign.Center)) ``` -------------------------------- ### Custom URI Handling for Links Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Override the default `UriHandler` to manage how links are opened. This is done by providing a custom `UriHandler` object via `CompositionLocalProvider`. ```kotlin val myUriHandler by remember { mutableStateOf(object : UriHandler { override fun openUri(uri: String) { // Handle the clicked link however you want } }) } CompositionLocalProvider(LocalUriHandler provides myUriHandler) { RichText( state = richTextState, modifier = Modifier.fillMaxWidth() ) } ``` -------------------------------- ### Exporting to HTML Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/html_import_export.md Convert the current `RichTextState` of the editor into an HTML string using the `toHtml` method. The output is a clean and properly formatted HTML string. ```APIDOC ## Exporting to HTML To convert `RichTextState` to HTML, use the `toHtml` method: ```kotlin val html = richTextState.toHtml() println(html) // Outputs formatted HTML string ``` ``` -------------------------------- ### Customize Link Appearance Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/faq.md Modify the color and text decoration of links within the RichText editor using the config property. ```kotlin richTextState.config.linkColor = Color.Blue richTextState.config.linkTextDecoration = TextDecoration.Underline ``` -------------------------------- ### Apply and Remove Heading Styles Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/headings.md Use `setHeadingStyle` to apply or remove heading levels from the current selection. Wrap calls in `recordHistory` for undo/redo functionality. ```kotlin richTextState.setHeadingStyle(HeadingStyle.H2) // Remove heading level (back to a normal paragraph) richTextState.setHeadingStyle(HeadingStyle.Normal) ``` -------------------------------- ### Using RichTextState with RichTextEditor (1.x) Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/upgrading.md Version 1.x deprecates RichTextValue in favor of RichTextState. Use rememberRichTextState() to create the state and pass it to the state parameter of RichTextEditor. ```kotlin val richTextState = rememberRichTextState() RichTextEditor( state = richTextState, ) ``` -------------------------------- ### Register Triggers and Display Suggestions Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/README.md Register custom triggers like '@' for mentions and '#' for hashtags on the RichTextState. Use TriggerSuggestions to display a popup for user selection based on the active trigger query. The onSelect lambda defines how to create a Token span when a suggestion is chosen. ```kotlin import com.mohamedrejeb.richeditor.model.trigger.Trigger import com.mohamedrejeb.richeditor.ui.material3.TriggerSuggestions val state = rememberRichTextState() LaunchedEffect(Unit) { state.registerTrigger(Trigger(id = "mention", char = '@')) state.registerTrigger(Trigger(id = "hashtag", char = '#')) } Box { RichTextEditor(state = state) // Drop in the built-in popup, or roll your own using state.activeTriggerQuery. TriggerSuggestions( state = state, triggerId = "mention", suggestions = { query -> users.filter { it.handle.contains(query) } }, onSelect = { user -> RichSpanStyle.Token( triggerId = "mention", id = user.id, label = "@${user.handle}", ) }, item = { user -> Text(user.handle) }, ) } ``` -------------------------------- ### Committing a Token Programmatically Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/mentions_and_triggers.md Allows for programmatically inserting a token into the rich text editor, bypassing the suggestion popup. ```APIDOC ## Committing a Token Programmatically ### Description Inserts a token into the rich text editor at the current cursor position, replacing the trigger query range with the token and a trailing space. ### Method `state.insertToken( triggerId: String, id: String, label: String, )` ### Parameters - **triggerId** (String) - The ID of the trigger associated with the token. - **id** (String) - A stable, unique identifier for the token. - **label** (String) - The display label for the token. Must start with the trigger's character. ### Preconditions - A matching query must be active (`state.activeTriggerQuery?.triggerId == triggerId`). - The trigger must be registered on the state. - `label` must start with the trigger's character. ``` -------------------------------- ### Provide ImageLoader Directly to RichText Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/images.md Alternatively, pass an `ImageLoader` instance directly to the `RichText` composable. This parameter takes precedence over the `CompositionLocal`. ```kotlin RichText( state = state, imageLoader = Coil3ImageLoader, ) ``` -------------------------------- ### Link Information Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/links.md Methods to check if the current selection is a link and to retrieve the text and URL of the selected link. ```APIDOC ## Link Information ### Checking Link Status To check if the current selection is a link: ```kotlin val isLink = richTextState.isLink ``` ### Getting Link Details To get the current link's text and URL: ```kotlin // Get link text and URL val linkText = richTextState.selectedLinkText val linkUrl = richTextState.selectedLinkUrl ``` ``` -------------------------------- ### Customizing ExpandableRichText Color Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/expandable_text.md Illustrates how to change the color of the 'See more' label in ExpandableRichText using the seeMoreColor parameter. ```kotlin ExpandableRichText( state = state, expanded = expanded, onExpandedChange = { expanded = it }, seeMoreColor = Color(0xFF1F6FEB), ) ``` -------------------------------- ### Create RichTextState Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/rich_text_state.md Use rememberRichTextState to initialize the state for a RichTextEditor. This function is essential for managing the editor's state. ```kotlin val state = rememberRichTextState() RichTextEditor( state = state, modifier = Modifier.fillMaxWidth() ) ``` -------------------------------- ### Save and Restore State Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/rich_text_state.md Persist the editor's state by converting it to HTML or Markdown format. Restore the state later using the setHtml or setMarkdown methods. ```kotlin // Save state val html = richTextState.toHtml() // or val markdown = richTextState.toMarkdown() // Restore state richTextState.setHtml(savedHtml) // or richTextState.setMarkdown(savedMarkdown) ``` -------------------------------- ### Apply Line Spacing Style Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/paragraph_style.md Control the spacing between lines of text within a paragraph by setting the `lineHeight` property. The value is relative to the font size. ```kotlin richTextState.addParagraphStyle( ParagraphStyle( lineHeight = 1.5.em // 1.5 times the font size ) ) ``` -------------------------------- ### Customize Rich Text Editor Configuration Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Modify the appearance of rich text elements like links and code blocks by directly accessing and updating properties within `richTextState.config`. ```kotlin richTextState.config.linkColor = Color.Blue richTextState.config.linkTextDecoration = TextDecoration.Underline richTextState.config.codeSpanColor = Color.Yellow richTextState.config.codeSpanBackgroundColor = Color.Transparent richTextState.config.codeSpanStrokeColor = Color.LightGray ``` -------------------------------- ### List Nesting and Levels Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/ordered_unordered_lists.md Control the nesting level of lists. ```APIDOC ## List Nesting and Levels ### Description Allows increasing or decreasing the nesting level of lists and checking if these actions are possible. ### Methods - `increaseListLevel()`: Increases the nesting level of the current list item. - `decreaseListLevel()`: Decreases the nesting level of the current list item. - `canIncreaseListLevel` (getter): Returns `true` if the list level can be increased, `false` otherwise. - `canDecreaseListLevel` (getter): Returns `true` if the list level can be decreased, `false` otherwise. ### Usage Example ```kotlin // Increase list level (nesting) richTextState.increaseListLevel() // Decrease list level (un-nesting) richTextState.decreaseListLevel() // Check if list level can be increased/decreased val canIncrease = richTextState.canIncreaseListLevel val canDecrease = richTextState.canDecreaseListLevel ``` ``` -------------------------------- ### Apply Text Direction Styles Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/paragraph_style.md Set the text direction for paragraphs to support languages that read from right-to-left (Rtl) or left-to-right (Ltr). ```kotlin richTextState.addParagraphStyle( ParagraphStyle( textDirection = TextDirection.Rtl ) ) richTextState.addParagraphStyle( ParagraphStyle( textDirection = TextDirection.Ltr ) ) ``` -------------------------------- ### Configure List Indentation Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/rich_text_state.md Adjust the indentation for lists globally or for specific list types. This controls the visual spacing of list items. ```kotlin richTextState.config.listIndent = 20 richTextState.config.orderedListIndent = 20 richTextState.config.unorderedListIndent = 20 ``` -------------------------------- ### Convert Selected Text to Link Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/links.md Use the `addLinkToSelection` method to transform the currently selected text into a hyperlink. ```kotlin richTextState.addLinkToSelection( url = "https://kotlinlang.org/" ) ``` -------------------------------- ### Add Coil3 Integration Dependency Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/images.md Include the `richeditor-compose-coil3` artifact in your project's dependencies to enable Coil3 image loading. ```kotlin implementation("com.mohamedrejeb.richeditor:richeditor-compose-coil3:1.0.0-rc14") ``` -------------------------------- ### Add Link to Rich Text Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Use the `addLink` method on `RichTextState` to insert a hyperlink with specified text and URL after the current selection. ```kotlin // Add link after selection. richTextState.addLink( text = "Compose Rich Editor", url = "https://github.com/MohamedRejeb/Compose-Rich-Editor" ) ``` -------------------------------- ### Export RichTextState to Markdown Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/markdown_import_export.md Convert the current `RichTextState` into a Markdown formatted string using the `toMarkdown` method. The output is a clean and properly formatted Markdown string. ```kotlin val markdown = richTextState.toMarkdown() println(markdown) // Outputs formatted Markdown string ``` -------------------------------- ### Set Font Size Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/span_style.md Adjust the size of the text using the `fontSize` property, typically specified in scaled pixels (sp). ```kotlin richTextState.addSpanStyle(SpanStyle( fontSize = 18.sp )) ``` -------------------------------- ### Add Link to New Text Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/links.md Use the `addLink` method to insert a new text with an associated URL after the current selection. ```kotlin richTextState.addLink( text = "Compose Rich Editor", url = "https://github.com/MohamedRejeb/Compose-Rich-Editor" ) ``` -------------------------------- ### Insert HTML Content at Specific Position Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/index.md Insert HTML content into the `RichTextState` at a designated `position` using the `insertHtml` method. ```kotlin val html = "inserted content" richTextState.insertHtml(html, position = 5) ``` -------------------------------- ### Adding Links Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/links.md Methods for adding hyperlinks to text. You can add a link to new text or convert existing selected text into a link. ```APIDOC ## Adding Links ### New Text with Link To add a new text with a link, use the `addLink` method: ```kotlin // Add link after selection richTextState.addLink( text = "Compose Rich Editor", url = "https://github.com/MohamedRejeb/Compose-Rich-Editor" ) ``` ### Converting Text to Link To convert selected text into a link, use the `addLinkToSelection` method: ```kotlin // Add link to selected text richTextState.addLinkToSelection( url = "https://kotlinlang.org/" ) ``` ``` -------------------------------- ### ImageLoader Interface Definition Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/images.md Defines the `ImageLoader` interface and the `ImageData` class used for loading and displaying images within the editor. ```kotlin interface ImageLoader { @Composable fun load(model: Any): ImageData? } class ImageData( val painter: Painter, val contentDescription: String? = null, val alignment: Alignment = Alignment.Center, val contentScale: ContentScale = ContentScale.Fit, val modifier: Modifier = Modifier.fillMaxWidth(), ) ``` -------------------------------- ### Managing Links Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/links.md Methods for updating and removing existing links. You can change the URL of a link or remove it while preserving the text. ```APIDOC ## Managing Links ### Updating Links To update an existing link's URL: ```kotlin // Update selected link URL richTextState.updateLink( url = "https://kotlinlang.org/" ) ``` ### Removing Links To remove a link while keeping the text: ```kotlin // Remove link from selected text richTextState.removeLink() ``` ``` -------------------------------- ### Insert Text Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/rich_text_state.md Modify the text content by inserting new text at a specific index or after the current selection. Styles are preserved during insertion. ```kotlin richTextState.addTextAtIndex(5, "Hello") richTextState.addTextAfterSelection("Hello") ``` -------------------------------- ### List Prefix Alignment Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/ordered_unordered_lists.md Control the alignment of list markers relative to the indentation gutter. ```APIDOC ## List Prefix Alignment > **Note:** This API is marked `@ExperimentalRichTextApi` and may change in a future release. ### Description Determines how list markers (e.g., `1.`, `•`) are positioned within the indentation area, affecting visual alignment. ### Configuration - `config.listPrefixAlignment`: Sets the alignment strategy for list markers. ### `ListPrefixAlignment` Enum Values - `End` (default): The marker is right-aligned to the content start, ensuring dots or ends of markers align vertically. Example: `1.`, `10.`, `11.` with dots stacked. - `Start`: The marker's left edge aligns with the indent origin, creating a uniform left edge for all markers, even with varying widths. Example: `1.`, `10. `, `11. ` with numbers stacked. ### Usage Example ```kotlin // Set alignment to End (default) richTextState.config.listPrefixAlignment = ListPrefixAlignment.End // Set alignment to Start richTextState.config.listPrefixAlignment = ListPrefixAlignment.Start ``` ### Behavior Notes If the configured indent is smaller than the marker width, `End` alignment clamps the first-line indent at `0` to ensure the marker remains visible and consistent across list items. ``` -------------------------------- ### Combine Multiple Span Styles Source: https://github.com/mohamedrejeb/compose-rich-editor/blob/main/docs/span_style.md Apply several styling properties simultaneously within a single `SpanStyle` object to create complex text formatting. ```kotlin richTextState.addSpanStyle(SpanStyle( fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic, color = Color.Blue, fontSize = 16.sp, background = Color.Yellow.copy(alpha = 0.3f) )) ```