### Ordered List Example Source: https://mohamedrejeb.github.io/compose-rich-editor/ordered_unordered_lists Demonstrates the visual structure of a nested ordered list with different numbering styles for each level. ```plaintext 1. First level item a. Second level item i. Third level item b. Another second level 2. Back to first level ``` -------------------------------- ### Unordered List Example Source: https://mohamedrejeb.github.io/compose-rich-editor/ordered_unordered_lists Illustrates the visual structure of a nested unordered list with different bullet styles for each level. ```plaintext • First level item ◦ Second level item ▪ Third level item ◦ Another second level • Back to first level ``` -------------------------------- ### Custom Resource ImageLoader Implementation Source: https://mohamedrejeb.github.io/compose-rich-editor/images Implement `ImageLoader` to integrate custom image loading, such as from local resources. This example shows loading an image using its resource ID. ```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, ) } } ``` -------------------------------- ### Implementing onSelect for Mention Tokens Source: https://mohamedrejeb.github.io/compose-rich-editor/mentions_and_triggers The onSelect lambda must return a RichSpanStyle.Token with a triggerId matching the popup's triggerId and a label that starts with the trigger's character. Ensure the label begins with the correct prefix (e.g., '@' for mentions). ```kotlin onSelect = { user -> RichSpanStyle.Token( triggerId = "mention", id = user.id, // stable id for serialization label = "@" + user.handle, // MUST begin with '@' ) } ``` -------------------------------- ### Get Link Text and URL Source: https://mohamedrejeb.github.io/compose-rich-editor/links Retrieve the text and URL of the currently selected link using `selectedLinkText` and `selectedLinkUrl` properties. ```kotlin // Get link text and URL val linkText = richTextState.selectedLinkText val linkUrl = richTextState.selectedLinkUrl ``` -------------------------------- ### Get and Check Current Paragraph Styles Source: https://mohamedrejeb.github.io/compose-rich-editor/paragraph_style Retrieve the current paragraph style of the selection to check properties like text alignment. This is useful for UI feedback or conditional logic. ```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 ``` -------------------------------- ### Get Current Paragraph Style Source: https://mohamedrejeb.github.io/compose-rich-editor/getting_started Retrieve the ParagraphStyle of the current selection to check for applied formatting, like text alignment. This helps in updating UI elements. ```kotlin val currentParagraphStyle = richTextState.currentParagraphStyle val isCentered = currentParagraphStyle.textAlign == TextAlign.Center ``` -------------------------------- ### Get Current Span Style Source: https://mohamedrejeb.github.io/compose-rich-editor Access RichTextState.currentSpanStyle to retrieve the styling properties of the currently selected text. ```kotlin // Get the current span style. val currentSpanStyle = richTextState.currentSpanStyle val isBold = currentSpanStyle.fontWeight = FontWeight.Bold ``` -------------------------------- ### Compose Mentions Sample Source: https://mohamedrejeb.github.io/compose-rich-editor/mentions_and_triggers Demonstrates how to set up a basic @mention trigger and suggestions popup in a Composable function. Requires `ExperimentalRichTextApi`. ```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) } }, ) } } ``` -------------------------------- ### Insert Image from HTML Source: https://mohamedrejeb.github.io/compose-rich-editor/images Import HTML content containing `` tags to automatically render images. The parser uses `width` and `height` attributes for initial placeholder sizing. ```kotlin val html = """

Header paragraph.

Footer paragraph.

""" state.setHtml(html) ``` -------------------------------- ### Get Current Paragraph Style Source: https://mohamedrejeb.github.io/compose-rich-editor Access RichTextState.currentParagraphStyle to retrieve the alignment and other paragraph styling properties of the selected text. ```kotlin // Get the current paragraph style. val currentParagraphStyle = richTextState.currentParagraphStyle val isCentered = currentParagraphStyle.textAlign = TextAlign.Center ``` -------------------------------- ### Provide Coil3ImageLoader via CompositionLocal Source: https://mohamedrejeb.github.io/compose-rich-editor/images 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(), ) } ``` -------------------------------- ### Initialize Undo/Redo History Source: https://mohamedrejeb.github.io/compose-rich-editor/rich_text_state Configure the undo/redo history with custom limits and coalescing windows. This enables robust undo and redo functionality for rich text edits. ```kotlin val state = rememberRichTextState( historyLimit = 100, coalesceWindowMs = 500L, ) 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") } ``` -------------------------------- ### Programmatically Create RichSpanStyle.Image Source: https://mohamedrejeb.github.io/compose-rich-editor/images Construct `RichSpanStyle.Image` directly to insert images when composing content outside of HTML. Ensure at least one of `width` or `height` is specified, and both must be finite and non-negative. ```kotlin val image = RichSpanStyle.Image( model = "https://picsum.photos/id/1015/600/400", width = 600.sp, height = 400.sp, contentDescription = "Landscape photo", ) ``` -------------------------------- ### Get Current Span Style Source: https://mohamedrejeb.github.io/compose-rich-editor/getting_started Retrieve the SpanStyle of the current selection to check for applied formatting, like bold. This is useful for UI feedback. ```kotlin val currentSpanStyle = richTextState.currentSpanStyle val isBold = currentSpanStyle.fontWeight == FontWeight.Bold ``` -------------------------------- ### Provide Custom ImageLoader via CompositionLocal Source: https://mohamedrejeb.github.io/compose-rich-editor/images Plug in a custom `ImageLoader` implementation using `CompositionLocalProvider` to make it available throughout the editor's composition. ```kotlin CompositionLocalProvider(LocalImageLoader provides MyResourceImageLoader) { RichText(state = state) } ``` -------------------------------- ### Add Snapshot Repository to settings.gradle.kts Source: https://mohamedrejeb.github.io/compose-rich-editor/faq Configure your settings.gradle.kts file to include the snapshots repository for dependency resolution. This is an alternative to configuring it in build.gradle.kts. ```kotlin dependencyResolutionManagement { repositories { maven("https://s01.oss.sonatype.org/content/repositories/snapshots") } } ``` -------------------------------- ### Initialize RichTextState Source: https://mohamedrejeb.github.io/compose-rich-editor/getting_started 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, ) ``` -------------------------------- ### ExpandableRichText Basic Usage Source: https://mohamedrejeb.github.io/compose-rich-editor/expandable_text Demonstrates the basic usage of ExpandableRichText with hoisted expanded state. ```APIDOC ## ExpandableRichText Basic Usage ### Description This example shows how to use `ExpandableRichText` with a hoisted `expanded` state managed by the caller. The `onExpandedChange` callback is used to update this state. ### Composable Signature ```kotlin @OptIn(ExperimentalRichTextApi::class) @Composable fun ExpandableRichText( state: RichTextState, expanded: Boolean, onExpandedChange: (Boolean) -> Unit, collapsedMaxLines: Int = 3, // ... other parameters ) ``` ### Code Example ```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, ) } ``` ### Notes - The composable is marked `@ExperimentalRichTextApi`. - When content fits within `collapsedMaxLines`, the toggle is not rendered. ``` -------------------------------- ### Import Markdown Content into RichTextState Source: https://mohamedrejeb.github.io/compose-rich-editor Convert Markdown strings to a RichTextState using the setMarkdown method. This enables loading content written in Markdown format. ```kotlin val markdown = "**Compose** *Rich* Editor" richTextState.setMarkdown(markdown) ``` -------------------------------- ### Apply Text Decoration Source: https://mohamedrejeb.github.io/compose-rich-editor/span_style Add or combine text decorations such as underline and strikethrough to text. ```kotlin richTextState.addSpanStyle(SpanStyle( textDecoration = TextDecoration.Underline // or TextDecoration.LineThrough // or TextDecoration.combine(listOf(TextDecoration.Underline, TextDecoration.LineThrough)) )) ``` -------------------------------- ### Registering Multiple Triggers Source: https://mohamedrejeb.github.io/compose-rich-editor/mentions_and_triggers Shows how to register different types of triggers like @mentions, #hashtags, and /commands with custom styles. Each trigger requires a unique ID and character. ```kotlin // @mention state.registerTrigger( Trigger( id = "mention", char = '@', style = { SpanStyle(color = it.linkColor, fontWeight = FontWeight.Medium) }, ) ) // #hashtag state.registerTrigger( Trigger( id = "hashtag", char = '#', style = { SpanStyle(color = Color.Magenta) }, ) ) // /command state.registerTrigger( Trigger( id = "command", char = '/', style = { SpanStyle(color = Color(0xFF009688), fontFamily = FontFamily.Monospace) }, ) ) ``` -------------------------------- ### Import Markdown to RichTextState Source: https://mohamedrejeb.github.io/compose-rich-editor/markdown_import_export Use the `setMarkdown` method to convert Markdown strings into `RichTextState` objects. Supports basic 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) ``` -------------------------------- ### HTML Image Import/Export Source: https://mohamedrejeb.github.io/compose-rich-editor/images Handles image import and export using HTML `` tags. Attributes like src, width, height, and alt are mapped to model properties. Use this for preserving explicit image dimensions. ```kotlin state.setHtml("

\"Hero\"

") val roundTripped = state.toHtml() ``` -------------------------------- ### Add Snapshot Repository to build.gradle.kts Source: https://mohamedrejeb.github.io/compose-rich-editor/faq Configure your build.gradle.kts file to include the snapshots repository for development builds. This allows you to use the latest development versions. ```kotlin allprojects { repositories { maven("https://s01.oss.sonatype.org/content/repositories/snapshots") } } ``` -------------------------------- ### Apply Text Indentation Style Source: https://mohamedrejeb.github.io/compose-rich-editor/paragraph_style Configure text indentation using `textIndent`. This allows separate control over the indentation of the first line and the rest of the lines. ```kotlin richTextState.addParagraphStyle( ParagraphStyle( textIndent = TextIndent( firstLine = 20.sp, // First line indent restLine = 10.sp // Rest of lines indent ) ) ) ``` -------------------------------- ### Markdown Serialization of Headings Source: https://mohamedrejeb.github.io/compose-rich-editor/headings ATX-style headings (e.g., `# Heading`) are exported and imported losslessly. Setext-style headings are not supported for export. ```kotlin state.setHtml("

Section

Body.

") val markdown = state.toMarkdown() // "## Section\n\nBody." ``` -------------------------------- ### Create RichTextState Source: https://mohamedrejeb.github.io/compose-rich-editor/rich_text_state Initialize the RichTextState using rememberRichTextState. This state object will manage the editor's content and behavior. ```kotlin val state = rememberRichTextState() RichTextEditor( state = state, modifier = Modifier.fillMaxWidth() ) ``` -------------------------------- ### Apply Text and Background Colors Source: https://mohamedrejeb.github.io/compose-rich-editor/span_style Set the text color and background color for spans using predefined or custom colors. ```kotlin richTextState.addSpanStyle(SpanStyle( color = Color.Blue )) richTextState.addSpanStyle(SpanStyle( background = Color.Yellow )) ``` -------------------------------- ### ExpandableRichText Parameters Source: https://mohamedrejeb.github.io/compose-rich-editor/expandable_text Lists and describes all available parameters for the ExpandableRichText composable. ```APIDOC ## ExpandableRichText Parameters ### Description This section details the parameters available for the `ExpandableRichText` composable. | Name | Required | Default | Notes | |---|---|---|---| | `state` | yes | - | The `RichTextState` to display. | | `expanded` | yes | - | Hoisted boolean. The composable does not own this state. | | `onExpandedChange` | yes | - | Called with `true` when `See more` is tapped, `false` for `See less`. | | `modifier` | no | `Modifier` | Applied to the underlying `BasicText`. | | `style` | no | `TextStyle.Default` (foundation) / `LocalTextStyle.current` (Material3) | Base text style. | | `collapsedMaxLines` | no | `3` | Must be `>= 1`. | | `seeMoreLabel` | no | `"… See more"` | Inline label appended to the last visible line when collapsed. | | `seeLessLabel` | no | `" See less"` | Inline label appended at the end of the content when expanded. | | `seeMoreStyle` (foundation) | no | underlined, color inherited | `SpanStyle` applied to both labels via `TextLinkStyles`. | | `seeMoreColor` (Material3) | no | `MaterialTheme.colorScheme.primary` | Forwarded into a `SpanStyle` with underline. | | `softWrap` | no | `true` | Standard `BasicText` softWrap. | | `inlineContent` | no | `mapOf()` | Inline content map merged with the state's own. | | `imageLoader` | no | `LocalImageLoader.current` | For inline images carried by the state. | ``` -------------------------------- ### Importing HTML Source: https://mohamedrejeb.github.io/compose-rich-editor/html_import_export Use the `setHtml` method to convert HTML strings into RichTextState objects. This method supports various formatting and structural HTML tags. ```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) ``` ``` -------------------------------- ### Configure Code Block Appearance Source: https://mohamedrejeb.github.io/compose-rich-editor/rich_text_state Set the visual style for code spans, including color, background color, and stroke color. ```kotlin richTextState.config.codeSpanColor = Color.Yellow richTextState.config.codeSpanBackgroundColor = Color.Transparent richTextState.config.codeSpanStrokeColor = Color.LightGray ``` -------------------------------- ### Handle Link Clicks with Custom UriHandler Source: https://mohamedrejeb.github.io/compose-rich-editor/faq Implement a custom `UriHandler` to manage how link clicks are processed. Provide this handler using `CompositionLocalProvider` to override the default platform behavior. ```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() ) } ``` -------------------------------- ### Apply Font Weight and Style Source: https://mohamedrejeb.github.io/compose-rich-editor/span_style Control the boldness and italicization of text by applying specific font weights and styles. ```kotlin richTextState.addSpanStyle(SpanStyle( fontWeight = FontWeight.Bold // or FontWeight.W500, etc. )) richTextState.addSpanStyle(SpanStyle( fontStyle = FontStyle.Italic )) ``` -------------------------------- ### Token Serialization (Markdown) Source: https://mohamedrejeb.github.io/compose-rich-editor/mentions_and_triggers Explains the Markdown serialization format for tokens, which uses a link-like structure. ```APIDOC ## Serialization - Markdown ### Description Tokens serialize to a link-shaped Markdown format: `[label](trigger::)`. This format preserves readability and survives other Markdown renderers. Trigger IDs and token IDs must not contain ':' characters. ``` -------------------------------- ### Providing Screen-Wide Default Token Handlers Source: https://mohamedrejeb.github.io/compose-rich-editor/mentions_and_triggers Use CompositionLocalProvider with LocalTokenClickHandler and LocalTokenHoverHandler to set default handlers 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) } ``` -------------------------------- ### Customizing Expandable Text Toggle Styling (Basic) Source: https://mohamedrejeb.github.io/compose-rich-editor/expandable_text For full control over the SpanStyle, use ExpandableBasicRichText and provide a custom 'seeMoreStyle'. This allows for different focus, hover, pressed styling, and custom font weights. ```kotlin ExpandableBasicRichText( state = state, expanded = expanded, onExpandedChange = { expanded = it }, seeMoreStyle = SpanStyle( color = Color(0xFF1F6FEB), fontWeight = FontWeight.SemiBold, textDecoration = TextDecoration.None, ), ) ``` -------------------------------- ### Custom Link Click Handling Source: https://mohamedrejeb.github.io/compose-rich-editor/links Implement a custom `UriHandler` to control how link clicks are processed, overriding the default platform behavior. ```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() ) } ``` -------------------------------- ### Save and Restore Editor Content Source: https://mohamedrejeb.github.io/compose-rich-editor/faq Convert the editor's content to HTML or Markdown for saving, and restore it using the `setHtml` or `setMarkdown` methods. This allows for persistent storage of editor content. ```kotlin // Save content val html = richTextState.toHtml() // or val markdown = richTextState.toMarkdown() // Restore content richTextState.setHtml(savedHtml) // or richTextState.setMarkdown(savedMarkdown) ``` -------------------------------- ### Screen-wide Defaults for Token Handlers Source: https://mohamedrejeb.github.io/compose-rich-editor/mentions_and_triggers Allows setting default token click and hover handlers for all RichText components within a certain scope using CompositionLocalProvider. ```APIDOC ## Screen-wide Defaults ### Description `LocalTokenClickHandler` and `LocalTokenHoverHandler` allow providing default handlers for all `RichText` components within a `CompositionLocalProvider`. Per-composable handlers take precedence. ### Usage ```kotlin CompositionLocalProvider( LocalTokenClickHandler provides TokenClickHandler { token, _ -> openReferenceSheet(token) } ) { // All RichText composables within this scope will inherit the handler RichText(state = commentState) RichText(state = replyState) } ``` ``` -------------------------------- ### Apply Text Alignment Styles Source: https://mohamedrejeb.github.io/compose-rich-editor/paragraph_style Set the text alignment for paragraphs using `addParagraphStyle`. Supported alignments include Center, Left, Right, and Justify. ```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 Expandable Text Usage Source: https://mohamedrejeb.github.io/compose-rich-editor/expandable_text Use this composable to display RichTextState with an expandable toggle. The expanded state is hoisted, requiring a mutable boolean state variable. ```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, ) } ``` -------------------------------- ### Import HTML to RichTextState Source: https://mohamedrejeb.github.io/compose-rich-editor/html_import_export Use the `setHtml` method to convert HTML strings into `RichTextState`. This method handles basic and complex HTML structures, including paragraphs, 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.

  • Unordered list item 1
  • Unordered list item 2
  1. Ordered list item 1
  2. Ordered list item 2

Link to Example

Code block example
""" richTextState.setHtml(complexHtml) ``` -------------------------------- ### Compose Rich Editor 1.x: Using RichTextState Source: https://mohamedrejeb.github.io/compose-rich-editor/upgrading Version 1.x deprecates RichTextValue in favor of RichTextState for managing the editor's state. Use rememberRichTextState() to initialize. ```kotlin val richTextState = rememberRichTextState() RichTextEditor( state = richTextState, ) ``` -------------------------------- ### Add Coil3 Integration Dependency Source: https://mohamedrejeb.github.io/compose-rich-editor/images Include the Coil3 integration artifact to enable seamless image loading with Coil's `rememberAsyncImagePainter`. ```kotlin implementation("com.mohamedrejeb.richeditor:richeditor-compose-coil3:1.0.0-rc14") ``` -------------------------------- ### Configure List Marker Style Behavior Source: https://mohamedrejeb.github.io/compose-rich-editor/ordered_unordered_lists 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 ``` -------------------------------- ### Register and Display Mention Suggestions Source: https://mohamedrejeb.github.io/compose-rich-editor Register a mention trigger with '@' character and display suggestions using TriggerSuggestions. The suggestions lambda filters users based on the query, and onSelect maps a user to a RichSpanStyle.Token. ```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) }, ) } ``` -------------------------------- ### Customizing Expandable Text Labels Source: https://mohamedrejeb.github.io/compose-rich-editor/expandable_text Customize the 'See more' and 'See less' labels by passing plain strings. For localization, use string resources. ```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), ) ``` -------------------------------- ### List Indentation Configuration Source: https://mohamedrejeb.github.io/compose-rich-editor/ordered_unordered_lists APIs for controlling the indentation of lists, both universally and for specific list types. ```APIDOC ## List Indentation ### Description Provides control over the horizontal spacing of lists from the left margin. Indentation can be set globally or individually for ordered and unordered lists. ### Configuration - `richTextState.config.listIndent`: Sets the indentation for all lists (ordered and unordered) in pixels. - `richTextState.config.orderedListIndent`: Sets the indentation specifically for ordered lists in pixels. - `richTextState.config.unorderedListIndent`: Sets the indentation specifically for unordered lists in pixels. ### Usage Example ```kotlin // Change list indentation for all lists to 20 pixels richTextState.config.listIndent = 20 // Change only ordered list indentation to 20 pixels richTextState.config.orderedListIndent = 20 // Change only unordered list indentation to 20 pixels richTextState.config.unorderedListIndent = 20 ``` ``` -------------------------------- ### Add Link Source: https://mohamedrejeb.github.io/compose-rich-editor/links Adds a new text with a specified URL. If text is selected, it will be replaced with the new link. ```APIDOC ## Add Link ### Description Adds a new text with a specified URL. If text is selected, it will be replaced with the new link. ### Method Signature ```kotlin fun addLink(text: String, url: String) ``` ### Parameters - **text** (String) - The text content for the link. - **url** (String) - The URL the link should point to. ### Request Example ```kotlin richTextState.addLink( text = "Compose Rich Editor", url = "https://github.com/MohamedRejeb/Compose-Rich-Editor" ) ``` ``` -------------------------------- ### Markdown Image Import/Export Source: https://mohamedrejeb.github.io/compose-rich-editor/images Supports standard Markdown image syntax for import and export. Note that programmatic sizes (width/height) are lost in a Markdown round-trip due to Markdown's limitations. ```markdown ![alt text](https://.../hero.png) ``` -------------------------------- ### Handling Token Clicks in RichText Source: https://mohamedrejeb.github.io/compose-rich-editor/mentions_and_triggers Wire tokens in read-only RichText surfaces to click handlers using the onTokenClick parameter. This allows driving actions like profile navigation or command execution based on the token's triggerId and id. ```kotlin RichText( state = state, onTokenClick = { token, tapOffset -> when (token.triggerId) { "mention" -> openProfile(token.id) "hashtag" -> navigateToTag(token.id) "command" -> runCommand(token.id) } }, ) ``` -------------------------------- ### Importing Markdown to RichTextState Source: https://mohamedrejeb.github.io/compose-rich-editor/markdown_import_export Use the `setMarkdown` method to convert Markdown strings into a `RichTextState` object. This method supports both simple and complex Markdown structures. ```APIDOC ## Importing Markdown To convert Markdown to `RichTextState`, use the `setMarkdown` method: ```kotlin // Basic formatting val simpleMarkdown = """ **Bold** and *italic* text with __underline__ """.trimIndent() richTextState.setMarkdown(simpleMarkdown) // Complex structure 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) ``` ``` -------------------------------- ### Convert Between Heading Levels and Formats Source: https://mohamedrejeb.github.io/compose-rich-editor/headings Convert between integer levels, HTML tag names, and `HeadingStyle` enum values. Access markdown prefixes and HTML tags directly from `HeadingStyle` constants. ```kotlin val style = HeadingStyle.fromLevel(3) val fromHtml = HeadingStyle.fromHtmlTag("h2") val unknown = HeadingStyle.fromHtmlTag("div") HeadingStyle.H3.markdownPrefix HeadingStyle.H3.htmlTag ``` -------------------------------- ### HTML Serialization of Headings Source: https://mohamedrejeb.github.io/compose-rich-editor/headings Headings are serialized to their corresponding HTML tags (e.g., `

`, `

`). Importing HTML with recognized heading tags automatically applies the correct `HeadingStyle`. ```kotlin state.setMarkdown("# Title\n\nBody paragraph.") val html = state.toHtml() //

Title

Body paragraph.

``` -------------------------------- ### Save and Restore State Source: https://mohamedrejeb.github.io/compose-rich-editor/rich_text_state Persist the editor's state by converting it to HTML or Markdown, and restore it later using the provided methods. This is essential for saving user progress. ```kotlin // Save state val html = richTextState.toHtml() // or val markdown = richTextState.toMarkdown() // Restore state richTextState.setHtml(savedHtml) // or richTextState.setMarkdown(savedMarkdown) ``` -------------------------------- ### Applying Paragraph Styles Source: https://mohamedrejeb.github.io/compose-rich-editor/paragraph_style Methods to toggle, add, or remove paragraph styles from the current selection. ```APIDOC ## Applying Paragraph Styles ### Description Methods to toggle, add, or remove paragraph styles from the current selection. ### Methods #### `toggleParagraphStyle` - **Description**: Toggles a paragraph style (adds if not present, removes if present). - **Parameters**: - `style` (ParagraphStyle) - The paragraph style to toggle. #### `addParagraphStyle` - **Description**: Adds a paragraph style, overwriting existing values for the same property. - **Parameters**: - `style` (ParagraphStyle) - The paragraph style to add. #### `removeParagraphStyle` - **Description**: Removes a paragraph style, restoring the default value. - **Parameters**: - `style` (ParagraphStyle) - The paragraph style to remove. ### Example Usage ```kotlin // Toggle center alignment richTextState.toggleParagraphStyle(ParagraphStyle(textAlign = TextAlign.Center)) // Add specific line spacing richTextState.addParagraphStyle(ParagraphStyle(lineHeight = 1.5.em)) // Remove text direction style richTextState.removeParagraphStyle(ParagraphStyle(textDirection = TextDirection.Rtl)) ``` ``` -------------------------------- ### List Prefix Alignment Source: https://mohamedrejeb.github.io/compose-rich-editor/ordered_unordered_lists Experimental API to control the alignment of list markers relative to the indentation gutter. ```APIDOC ## List Prefix Alignment ### Description This API, marked as `@ExperimentalRichTextApi`, allows fine-tuning the positioning of list markers (like `1.` or `•`) within the indentation area. It affects how markers align with the content and with each other across different list item widths. ### Configuration - `richTextState.config.listPrefixAlignment`: Sets the alignment strategy for list markers. Accepts `ListPrefixAlignment.End` (default) or `ListPrefixAlignment.Start`. ### `ListPrefixAlignment` Options - `End` (default): The marker is right-aligned to the content start. This results in the dots of numbered lists aligning vertically (e.g., `1.`, `10.`, `11.` all have their dots in a column). - `Start`: The marker's left edge aligns with the indent origin. This creates a uniform left edge for all markers, stacking them vertically even when numbers have different widths (e.g., `1.`, `10.`, `11.` all start at the same horizontal position). ### Behavior Notes If the configured indent is less than the marker's width, `End` alignment clamps the first-line indent to `0` to ensure visibility, maintaining consistent list layout. ### Usage Example ```kotlin // Set list prefix alignment to End (default behavior) richTextState.config.listPrefixAlignment = ListPrefixAlignment.End // Set list prefix alignment to Start for uniform marker edges richTextState.config.listPrefixAlignment = ListPrefixAlignment.Start ``` ``` -------------------------------- ### Toggle, Add, and Remove Paragraph Styles Source: https://mohamedrejeb.github.io/compose-rich-editor/paragraph_style Use these methods to manage paragraph styles. `toggleParagraphStyle` adds a style if it's not present and removes it if it is. `addParagraphStyle` overwrites existing styles, 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)) ``` -------------------------------- ### Manage Text Selection Source: https://mohamedrejeb.github.io/compose-rich-editor/rich_text_state Programmatically control the text selection range or move the cursor. Useful for implementing custom selection behaviors. ```kotlin // Set selection range richTextState.selection = TextRange(0, 5) // Select all text richTextState.selection = TextRange(0, richTextState.annotatedString.text.length) // Move cursor to end richTextState.selection = TextRange(richTextState.annotatedString.text.length) ``` -------------------------------- ### Apply and Remove Heading Styles Source: https://mohamedrejeb.github.io/compose-rich-editor/headings Use `setHeadingStyle` to change the heading level of the current selection. Wrap calls in `recordHistory` for undo/redo functionality. ```kotlin richTextState.setHeadingStyle(HeadingStyle.H2) richTextState.setHeadingStyle(HeadingStyle.Normal) ``` -------------------------------- ### Ordered List Style Types Source: https://mohamedrejeb.github.io/compose-rich-editor/ordered_unordered_lists Configuration options for customizing the appearance of ordered list markers. ```APIDOC ## Ordered List Style Types ### Description Allows customization of the markers used for ordered lists, supporting various numbering and lettering formats, including multi-level configurations. ### Configuration - `richTextState.config.orderedListStyleType`: Sets the style for ordered lists. Accepts `OrderedListStyleType` enum values or a `Multiple` configuration for different nesting levels. ### `OrderedListStyleType` Options - `Decimal`: `1`, `2`, `3`, ... - `LowerAlpha`: `a`, `b`, `c`, ... - `UpperAlpha`: `A`, `B`, `C`, ... - `LowerRoman`: `i`, `ii`, `iii`, ... - `UpperRoman`: `I`, `II`, `III`, ... - `Multiple(style1, style2, ...)`: Defines styles for successive nesting levels. ### Usage Example ```kotlin // Set ordered list style to Decimal richTextState.config.orderedListStyleType = OrderedListStyleType.Decimal // Set ordered list style to Lower Alpha richTextState.config.orderedListStyleType = OrderedListStyleType.LowerAlpha // Set ordered list style to Upper Alpha richTextState.config.orderedListStyleType = OrderedListStyleType.UpperAlpha // Set ordered list style to Lower Roman richTextState.config.orderedListStyleType = OrderedListStyleType.LowerRoman // Set ordered list style to Upper Roman richTextState.config.orderedListStyleType = OrderedListStyleType.UpperRoman // Use different styles for different nesting levels richTextState.config.orderedListStyleType = OrderedListStyleType.Multiple( OrderedListStyleType.UpperAlpha, // First level: A, B, C OrderedListStyleType.LowerAlpha, // Second level: a, b, c OrderedListStyleType.Decimal // Third level: 1, 2, 3 ) ``` ``` -------------------------------- ### Custom Link Handling Source: https://mohamedrejeb.github.io/compose-rich-editor/links Provides a mechanism to override the default behavior for opening URIs, allowing custom link handling logic. ```APIDOC ## Custom Link Handling ### Description Provides a mechanism to override the default behavior for opening URIs, allowing custom link handling logic. ### Usage Implement the `UriHandler` interface and provide it using `CompositionLocalProvider`. ### Example ```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() ) } ``` ``` -------------------------------- ### List Nesting and Levels Source: https://mohamedrejeb.github.io/compose-rich-editor/ordered_unordered_lists APIs for managing the nesting level of lists, including increasing, decreasing, and checking the possibility of level changes. ```APIDOC ## List Nesting and Levels ### Description Enables users to adjust the nesting depth of lists, allowing for hierarchical structures. It also provides checks to determine if level adjustments are permissible. ### 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 val canIncrease = richTextState.canIncreaseListLevel // Check if list level can be decreased val canDecrease = richTextState.canDecreaseListLevel ``` ``` -------------------------------- ### Link Appearance Customization Source: https://mohamedrejeb.github.io/compose-rich-editor/links Allows customization of the link's color and text decoration. ```APIDOC ## Link Appearance Customization ### Description Allows customization of the link's color and text decoration. ### Configuration Properties ```kotlin richTextState.config.linkColor = Color.Blue richTextState.config.linkTextDecoration = TextDecoration.Underline ``` ``` -------------------------------- ### Apache License 2.0 Source: https://mohamedrejeb.github.io/compose-rich-editor The Apache License, Version 2.0, governs the use of this software. It grants permissions for use, modification, and distribution, with certain conditions. ```text Copyright 2023 Mohamed Rejeb Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` -------------------------------- ### Export RichTextState to HTML Source: https://mohamedrejeb.github.io/compose-rich-editor/html_import_export Convert the current `RichTextState` into an HTML string using the `toHtml` method. The output is a clean and properly formatted HTML string. ```kotlin val html = richTextState.toHtml() println(html) // Outputs formatted HTML string ``` -------------------------------- ### Toggle Paragraph Style Source: https://mohamedrejeb.github.io/compose-rich-editor/getting_started Apply or remove a ParagraphStyle, such as centered text alignment, to the current selection. This affects the entire paragraph. ```kotlin richTextState.toggleParagraphStyle(ParagraphStyle(textAlign = TextAlign.Center)) ``` -------------------------------- ### Provide ImageLoader via Composable Parameter Source: https://mohamedrejeb.github.io/compose-rich-editor/images Alternatively, pass a specific `ImageLoader` directly to the `RichText` composable. This parameter takes precedence over the `CompositionLocal` setting. ```kotlin RichText( state = state, imageLoader = Coil3ImageLoader, ) ``` -------------------------------- ### Exporting to HTML Source: https://mohamedrejeb.github.io/compose-rich-editor/html_import_export Convert the current `RichTextState` into an HTML string using the `toHtml` method. The output is clean and properly formatted HTML. ```APIDOC ## Exporting to HTML To convert `RichTextState` to HTML, use the `toHtml` method: ```kotlin val html = richTextState.toHtml() println(html) // Outputs formatted HTML string ``` ``` -------------------------------- ### Add New Text with Link Source: https://mohamedrejeb.github.io/compose-rich-editor/links Use the `addLink` method to insert a new text segment with an associated URL. ```kotlin richTextState.addLink( text = "Compose Rich Editor", url = "https://github.com/MohamedRejeb/Compose-Rich-Editor" ) ``` -------------------------------- ### Customizing Expandable Text Toggle Color (Material3) Source: https://mohamedrejeb.github.io/compose-rich-editor/expandable_text The Material3 wrapper exposes a 'seeMoreColor' parameter to customize the toggle's color, defaulting to the primary color scheme. ```kotlin ExpandableRichText( state = state, expanded = expanded, onExpandedChange = { expanded = it }, seeMoreColor = Color(0xFF1F6FEB), ) ``` -------------------------------- ### Registering Multiple Triggers with TriggerSuggestions Source: https://mohamedrejeb.github.io/compose-rich-editor/mentions_and_triggers Place TriggerSuggestions inside a Box alongside the editor. Render one TriggerSuggestions per registered trigger, each checking activeTriggerQuery.triggerId to display suggestions only when its trigger is active. ```kotlin Box { OutlinedRichTextEditor(state = state) TriggerSuggestions(state = state, triggerId = "mention", ...) TriggerSuggestions(state = state, triggerId = "hashtag", ...) TriggerSuggestions(state = state, triggerId = "command", ...) } ``` -------------------------------- ### Use Snapshot Version of Rich Editor Source: https://mohamedrejeb.github.io/compose-rich-editor/faq Include the snapshot version of the rich editor in your project's dependencies. Note that snapshots may be unstable or contain breaking changes. ```kotlin implementation("com.mohamedrejeb.richeditor:richeditor-compose:1.0.0-SNAPSHOT") ``` -------------------------------- ### Committing a Token Programmatically Source: https://mohamedrejeb.github.io/compose-rich-editor/mentions_and_triggers Allows you to insert a token directly into the editor without using the suggestion popup. This is useful for pre-defined or automatically generated tokens. ```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) - The stable ID for the token, used for serialization. - **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. ``` -------------------------------- ### ExpandableRichText Customizing Toggle Styling (Material3) Source: https://mohamedrejeb.github.io/compose-rich-editor/expandable_text Explains how to customize the color of the 'See more' toggle in ExpandableRichText using the `seeMoreColor` parameter. ```APIDOC ## ExpandableRichText Customizing Toggle Styling (Material3) ### Description Customize the color of the 'See more' toggle when using the Material3 wrapper. The label is underlined by default. ### Parameters - `seeMoreColor` (Color, optional): The color for the 'See more' label. Defaults to `MaterialTheme.colorScheme.primary`. ### Code Example ```kotlin ExpandableRichText( state = state, expanded = expanded, onExpandedChange = { expanded = it }, seeMoreColor = Color(0xFF1F6FEB), ) ``` ``` -------------------------------- ### Configure List Indentation Source: https://mohamedrejeb.github.io/compose-rich-editor/rich_text_state Adjust the indentation for ordered and unordered lists globally or specifically. This affects the spacing of list items. ```kotlin // Global list indentation richTextState.config.listIndent = 20 // Specific list type indentation richTextState.config.orderedListIndent = 20 richTextState.config.unorderedListIndent = 20 // List behavior richTextState.config.exitListOnEmptyItem = true // Exit list when pressing Enter on empty item ``` -------------------------------- ### Convert Selected Text to Link Source: https://mohamedrejeb.github.io/compose-rich-editor/links Use the `addLinkToSelection` method to transform currently selected text into a hyperlink. ```kotlin richTextState.addLinkToSelection( url = "https://kotlinlang.org/" ) ``` -------------------------------- ### Handling Token Clicks Source: https://mohamedrejeb.github.io/compose-rich-editor/mentions_and_triggers Enables handling click events on tokens displayed in read-only RichText surfaces. ```APIDOC ## Handling Token Clicks ### Description Provides a callback for handling click events on tokens in read-only `RichText` or `BasicRichText` surfaces. Useful for navigation or triggering actions based on the token. ### Parameter `onTokenClick: (token: RichSpanStyle.Token, tapOffset: Offset) -> Unit` - **token** (RichSpanStyle.Token) - The token that was clicked. - **tapOffset** (Offset) - The local coordinates of the tap within the rich-text composable, useful for anchoring popovers. ``` -------------------------------- ### Customize Rich Text Editor Colors and Decorations Source: https://mohamedrejeb.github.io/compose-rich-editor Customize the appearance of links and code spans by modifying properties on the richTextState.config object. This allows for changes to link color, text decoration, code span color, background, and stroke. ```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 ``` -------------------------------- ### Combine Multiple Span Styles Source: https://mohamedrejeb.github.io/compose-rich-editor/span_style Apply several formatting properties simultaneously within a single SpanStyle object for comprehensive text styling. ```kotlin richTextState.addSpanStyle(SpanStyle( fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic, color = Color.Blue, fontSize = 16.sp, background = Color.Yellow.copy(alpha = 0.3f) )) ``` -------------------------------- ### ImageLoader Interface Definition Source: https://mohamedrejeb.github.io/compose-rich-editor/images Defines the `ImageLoader` interface for custom image loading logic. Return `null` while the image is loading or has failed to prevent layout jumps. ```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(), ) ```