# Changelog ## [1.10.1] - 2026-11-08 ### Added - **Tap-to-call phone links on Android and iOS.** Enable `autoDetectPhoneNumbers` in the editor or preview configuration to make detected numbers tappable in previews and unfocused built-in text blocks. The setting is also available in the native iOS SDK and defaults to `false`. Explicit links take precedence, and detected links stay out of saved documents. See the [phone link setup guide](docs/PhoneNumberLinks.md). ### Fixed - Manually entered `tel:` links keep their scheme when saved through the editor’s link controls. ### Changed - `CascadeEditorConfig` and `CascadeDocumentPreviewConfig` have new binary signatures for their constructors and `copy` methods. Rebuild Kotlin libraries compiled against 1.10.0 that use those APIs. In Swift, pass `autoDetectPhoneNumbers` when calling `doCopy` on either native configuration. ## [1.10.0] - 2026-11-05 ### Changed - **Raised consumer toolchain requirements.** Projects consuming the Maven artifacts must now meet these minimums: - Kotlin Multiplatform consumers with iOS or Wasm targets need Kotlin 2.4.0 or newer: klibs are published with ABI version 2.4.0, and Kotlin/Native and Kotlin/Wasm compilers do not read klibs from a newer compiler - Android and JVM consumers need Kotlin 2.3.0 or newer (Kotlin metadata 2.4.0) - Android consumers need `compileSdk` 37 and Android Gradle Plugin 9.1.0 or newer. The AAR declares `minCompileSdk=37`, and AndroidX Compose 1.12.1, pulled in by Compose Multiplatform 1.12, requires both - `minSdk` 26, iOS 16, and the JVM 11 bytecode target are unchanged. The native iOS SDK (XCFramework / Swift package) adds no new consumer toolchain requirement - Upgraded Kotlin from 2.3.21 to 2.4.21 and Compose Multiplatform from 1.11.1 to 1.12.2 (AndroidX Compose 1.12.1, Skiko 0.150.2), kotlinx.serialization from 1.11.0 to 1.12.0, and JetBrains Markdown from 0.7.14 to 0.7.18 - Artifacts are now built with `compileSdk` 37, Android Gradle Plugin 9.5.0, and Gradle 9.8.2 - On the JVM, `CascadeDocumentPreviewConfig` gains a public no-argument constructor generated by Kotlin 2.4. This is a binary-compatible addition ### Fixed - Documented the SwiftUI keyboard-inset contract. A SwiftUI host that enables `keyboardInsetsEnabled` must opt the editor out of SwiftUI keyboard avoidance with `.ignoresSafeArea(.keyboard, edges: .bottom)`; otherwise the inset is applied twice and, on iOS 26, leaves a keyboard-height gap between the toolbar and the keyboard. The native iOS sample now follows this contract, and its comment composer leaves keyboard avoidance to SwiftUI ## [1.9.3] - 2026-09-17 ### Fixed - Upgraded JetBrains Markdown from 0.7.7 to 0.7.14. The 0.7.7 lexer compiled its `ArrayList.pop()` helper to `java.util.ArrayList.removeLast()`, which exists only on Android 15 (API 35) and throws `NoSuchMethodError` on older devices; it also triggered the Play Console "Kotlin incompatibilities" warning for every consuming app. Cascade's own GFM decode path never reached that lexer, but the class shipped in every consumer APK ### Changed - The Android artifact is now built and published with Android Gradle Plugin 9.2.1 through `com.android.kotlin.multiplatform.library`. Consumer keep rules are still published with the artifact; no consumer code changes are required ## [1.9.2] - 2026-08-02 ### Changed - Reduced the native iOS arm64 framework executable by about 32% using size-optimized Kotlin/Native release linking and staged local-symbol stripping, while preserving the exported Swift/Objective-C surface and matching dSYMs ## [1.9.1] - 2026-08-02 ### Added - Added opt-in `keyboardInsetsEnabled` configuration for Compose Multiplatform and native iOS so the document viewport and built-in toolbar can share one software-keyboard inset - Added experimental default-profile Markdown load and export APIs to the native iOS editor and preview controllers, including warning and data-loss reports and preservation of existing content when decoding aborts ### Changed - Native Swift callers constructing `CascadeEditorConfiguration` must now pass `keyboardInsetsEnabled`; keep it `false` when the host already owns keyboard avoidance, or enable it only when Cascade is the sole inset owner ### Fixed - Fixed clipping of the built-in formatting toolbar's top shadow ## [1.9.0] - 2026-07-28 ### Added - Added the experimental `CascadeDocumentPreview` API for bounded, static document summaries in Compose lists, grids, feeds, and search results without mounting editor state, text fields, focus, history, or internal scrolling - Added configurable preview block and line limits, text scaling, optional text selection, host-owned link handling, dedicated custom preview renderers, and bounded fallbacks for unknown or custom blocks - Added the experimental native iOS `CascadeDocumentPreviewController` and `CascadeDocumentPreviewConfiguration` with JSON loading, live configuration and theme updates, link and error callbacks, and a non-scrolling UIKit host - Added persisted preview-gallery and edit-round-trip examples to both the Compose Multiplatform and native Swift samples - Added the Swift-visible `CascadeEditorColors` palette and runtime `setColors()` / `clearCustomColors()` support for editable and preview controllers - Added an opt-in empty-document placeholder with configurable localized text and theme color, including native iOS configuration and localization bridges - Added `CascadeEditorController.focusFirstBlock()` for native hosts that need to move directly from a preview into editing ## [1.8.1] - 2026-07-26 ### Added - Added Swift Package Manager publication assets, a reproducible release ZIP and checksum script, embedded dSYMs and dependency notices, and tag-driven GitHub Release automation - Added the SDK privacy manifest for file-timestamp and system-boot-time required-reason APIs used by the linked Compose/Skiko runtime ### Changed - Changed the iOS SDK from a static to a dynamic XCFramework so SwiftPM embeds the framework-owned Compose resources without a consumer copy phase ### Fixed - Bound iOS Compose resource lookup to the CascadeEditor framework bundle, preventing ambiguity when an app embeds more than one Compose-based SDK ## [1.8.0] - 2026-07-23 ### Added - Added an experimental, profile-driven Markdown codec with `MarkdownSchema` and `EditorStateHolder` import/export helpers, CommonMark/GFM-oriented block and inline support, policy-driven HTML bridging, structured warnings, bounded resource limits, source preservation for unsupported syntax, and fidelity analysis that recommends native editing or a raw-text fallback - Added the Swift-facing `:editor-ios-sdk` static framework with a controller and UIKit host, JSON/HTML document APIs, toolbar state and actions, localization, change callbacks, native custom blocks, and native slash commands; also added an XCFramework build script and a native Swift sample - Added `CascadeEditorConfig(blockIndentationEnabled = ...)` to disable built-in indentation commands while keeping drag-and-drop at the payload's original indentation - Added public integration seams for external editor chrome and platform bridges: `EditorStateHolder.dispatchStructuralAction(...)`, `EditorStateHolder.resolveDocumentBlocks(...)`, `BlockRenderer.supportsDragPreview`, and stable built-in slash-command ID helpers - Added comments-composer and Markdown round-trip examples to the sample app ### Changed - Lowered the Android minimum SDK from 28 to 26 - Updated Compose Multiplatform from 1.11.0 to 1.11.1 ### Fixed - Fixed block renderers and slash commands registered after the editor is mounted not becoming available until an unrelated state change - Fixed built-in slash conversion to non-text custom blocks so blank anchors are replaced safely and nonblank anchor text is never discarded - Fixed JSON, HTML, and Markdown link persistence rewriting relative, fragment, `mailto:`, `tel:`, and custom-scheme targets as HTTPS URLs - Fixed drag previews for platform-view renderers by allowing them to opt out of duplicate live composition and use a lightweight placeholder ## [1.7.0] - 2026-06-28 ### Added - Added `ScopedBlockRenderer` and the public `BlockRenderScope` seam for interactive custom blocks: scoped renderers receive a live, capability-gated scope to inspect editor state and apply block mutations (`updateBlock`, `replaceBlock`, `insertBlockBefore`/`insertBlockAfter`, `deleteBlock`, `focusBlock`), each producing a single structural undo/redo entry - Added read-only/policy capability flags on `BlockRenderScope` (`readOnly`, `canUpdateBlock`, `canEditBlockStructure`, `canSelectBlocks`, `canDragBlocks`) that are re-checked at call time so mutations are safe no-ops when disabled or when the target block is missing ### Changed - Redesigned the default `RichTextToolbar` as a floating pill: a fixed `/` slash circle, scrollable formatting and indent/outdent/link controls, the iOS hide-keyboard button pinned right, and accent-tinted active states - Redesigned the sample app landing page, editor chrome, and theming ## [1.6.0] - 2026-06-07 ### Added - Added crash containment for built-in editor surfaces: per-block measure/draw failures are caught at a containment boundary so a failing block degrades to a safe fallback instead of crashing the host - Added `CrashPolicy` (`Rethrow` / `ContainAndReport`), `CascadeError`, and the `CascadeErrorReporter` host hook for routing contained failures into application crash reporting - Added `CascadeEditorConfig(crashPolicy = ..., onInternalError = ...)` to control containment behavior; defaults to `ContainAndReport` for release and supports `Rethrow` for tests and debug builds - Added always-contain-and-warn guarantees for serialization entry points: `loadFromJson()` / `loadFromHtml()` no longer throw on malformed input, returning `DocumentDecodeWarning.DocumentParseFailed` / `HtmlDecodeWarning.InputLimitExceeded` instead ### Changed - Updated dependencies: Compose Multiplatform 1.11.0, Kotlin 2.3.21 ### Fixed - Fixed scroll-to-unfocused-block behavior on the Android target ## [1.5.0] - 2026-05-17 ### Added - Added `CascadeEditorConfig(readOnly = ...)` and public `LocalCascadeEditorConfig` for UI-scoped read-only editor behavior. - Added read-only enforcement for built-in editor interaction surfaces: text input, formatting, indentation, link editing, slash commands, todo toggles, block selection, drag/reorder, empty-space focus, and structural keyboard edits are disabled while scrolling, text selection/copy, and existing link opening remain available. - Added support for editor-independent external toolbars. - Added support for disabling the Slash Command Palette. ## [1.4.0] - 2026-05-06 ### Added - Added experimental HTML import/export support with profile-driven decode/encode APIs, default block/span mappings, parser policies, warnings, and `EditorStateHolder.toHtml()` / `loadFromHtml()` helpers - Added link spans with URL validation, serialization, toolbar actions, popup editing, link opening hooks, and custom chrome access through link state/actions - Added code block support with plain-text editing semantics, dedicated rendering, serialization, slash-command integration, and span-formatting guards ## [1.3.0] - 2026-04-28 ### Changed - Expanded supported block indentation from `0..3` to `0..5` - Added free indentation: supported blocks can now start at any indentation level, including the first block and blocks after unsupported boundaries - Drag-and-drop now supports free target indentation while still moving child blocks with their parent payload - Numbered-list prefixes now follow numbered-list ancestry with a `1.` → `a.` → `i.` cycle instead of absolute indentation depth - Updated indentation serialization, documentation, and regression coverage for the new outline rules ## [1.2.0] - 2026-04-26 ### Added - Flat-outline block indentation for paragraphs, todos, bullet lists, and numbered lists - Public indentation state/actions for custom editor chrome, plus default toolbar indent/outdent controls - Depth-aware drag-and-drop, nested numbered-list formatting, and indentation-aware Enter/Backspace editing behavior - Editor now supports Desktop target as well ### Changed - Document serialization now preserves supported indentation attributes and normalizes invalid outlines on decode - Undo/redo history now captures indentation and drag reindentation as semantic structural transactions - Sample landing page layout now adapts better to widescreen displays ## [1.1.0] - 2026-04-09 ### Added - Undo/redo support with a hybrid linear history model: compact one-block entries for typing and eligible formatting edits, plus full-document checkpoints for structural edits - Public history API on `EditorStateHolder`: `canUndo`, `canRedo`, `undo()`, and `redo()` - Built-in history keyboard shortcuts: `Cmd/Ctrl+Z` for undo and `Shift+Cmd/Ctrl+Z` for redo - History-aware replay that restores focused block selection/caret and pending formatting styles - Demo toolbar controls for undo and redo in the sample editor screen ### Changed - Built-in editor flows such as split/merge, drag reorder, slash commands, list auto-detection, todo toggles, and selected-range formatting now participate in undo/redo history - Hard document replacement paths (`setState(...)`, `loadFromJson(...)`) now clear undo/redo history ## [1.0.0] - 2026-04-02 ### Added - Block-based editing with paragraphs, headings (H1-H6), todo lists, bullet lists, numbered lists, quotes, and dividers - Rich text formatting: bold, italic, underline, strikethrough, inline code, highlight, and custom span styles - Full span preservation across split, merge, and block conversion operations - Drag and drop block reordering with auto-scroll, drop indicator, and drag preview - Block selection: single, multi-select, and range selection with visual feedback - Slash command system with searchable popup, keyboard navigation, submenu support, and custom command registration - Custom block type support via `CustomBlockType` and `BlockRenderer` interfaces - Document serialization with `toJson()` / `loadFromJson()`, versioned schemas, and codec hooks for custom types - Theming API with `CascadeEditorTheme`, configurable colors and typography, light/dark presets - Localization support with `CascadeEditorStrings` and `CascadeEditorBlockStrings` for full UI string customization - List auto-detection: typing `- ` or `1. ` converts a paragraph into the corresponding list type - Smart list continuation on Enter and exit-to-paragraph on empty Enter - Keyboard shortcuts for formatting (Cmd+B/I/U on macOS, Ctrl+B/I/U on other platforms) - iOS keyboard dismiss button in the formatting toolbar - Kotlin Multiplatform support targeting Android and iOS with native Compose rendering