Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
dd0aa29
fix: viewId when no View in context (#2662)
adil192 Oct 18, 2025
74f75b1
Updated Brazilian Portuguese translations (#2638)
gabrielsso Oct 18, 2025
9641f2c
chore: format files with newer Dart formatter, upgrade deps
EchoEllet Oct 18, 2025
a71c7e7
chore(release): prepare to publish 11.5.0
EchoEllet Oct 18, 2025
0794e7b
chore: dart fix --apply
EchoEllet Oct 18, 2025
e14689b
l10n: support mn locale (#2673)
sadespresso Oct 20, 2025
5854fcd
chore: fix pre-existing CI analyze failures (#2728)
Alspb May 7, 2026
1643f56
feat: add onFocusReceived implementation for Flutter 3.44 compatibili…
jodinathan May 20, 2026
ad6330e
chore(example): update deps, remove CocoaPods integration
EchoEllet May 20, 2026
db0da10
chore(release): prepare to publish 11.5.1
EchoEllet May 20, 2026
d07b8fb
chore(release): prepare to publish 11.5.1
EchoEllet May 20, 2026
5c96e65
Complete the Flutter 3.44 / Dart 3.12 migration (#2740)
Alspb Jun 9, 2026
760c092
Chore/dart 3.12 format (#2744)
Alspb Jun 15, 2026
ae53f18
fix: normalize list point spacing when toggling RTL formatting (#2745)
Alspb Jun 20, 2026
c273155
fix(android): sync IME selection so typing follows the tapped caret (…
Alspb Jun 29, 2026
3d226b1
fix: prevent toolbar flicker when tapping a checklist checkbox (#2747)
Alspb Sep 10, 2026
222f584
Added custom callback to transform a link before it is launched (#2727)
Alspb Sep 11, 2026
9b44ade
Search bar: whole-word seach fixed for Unicode, search dialog style i…
Alspb Sep 13, 2026
baed3f7
Fix: selection handle horizontal drag stays on current line (#2731)
Alspb Sep 13, 2026
843f6df
Code block invisible line numbers fixed, QuillEditorConfig.showCodeBl…
Alspb Sep 13, 2026
6313f19
Fix/selection context menu out of view (#2739)
Alspb Sep 13, 2026
954e713
fix: reveal caret when keyboard inset changes (#2742)
Alspb Sep 13, 2026
febf14c
Merge singerdmx/master into sync
ppamorim Sep 14, 2026
9b44ad9
Merge master into sync
ppamorim Oct 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Revisions for `git blame` to skip (large, mechanical changes with no logic impact).
#
# Enable locally once with:
# git config blame.ignoreRevsFile .git-blame-ignore-revs
#
# GitHub honors this file automatically. List full 40-char commit SHAs only.

# style: apply Dart 3.12 format (tall style) — repo-wide dart_format, no logic changes
10e0814088ae3b12f0cca4673f885e2828eaaa7a
9 changes: 6 additions & 3 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ jobs:
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
# Pinned so a future Flutter/Dart release can't change formatter output
# and turn the format check below red on unrelated PRs. Bump deliberately
# alongside a repo-wide reformat (see .git-blame-ignore-revs).
flutter-version: 3.44.1
channel: stable
cache: true

Expand All @@ -34,9 +38,8 @@ jobs:
- name: Perform Flutter Analysis
run: flutter analyze

# TODO: Restore Dart formatting check, disabled due to an issue https://github.com/singerdmx/flutter-quill/actions/runs/13355109619/job/37296760819.
# - name: Check Dart code formatting
# run: dart format --set-exit-if-changed .
- name: Check Dart code formatting
run: dart format --set-exit-if-changed .

- name: Preview Dart proposed changes
run: dart fix --dry-run
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:

- if: ${{ !cancelled() }}
name: Run Flutter Analyze Commenter
continue-on-error: true
uses: yorifuji/flutter-analyze-commenter@v1
with:
analyze-log: flutter_analyze.log
Expand Down
54 changes: 49 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,64 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [11.5.0] - 2026-10-07
## [11.5.2] - 2026-10-07

### Added

- `QuillFocusNode`, which can disable the keyboard while the editor keeps focus.
- Added `QuillEditorConfig.showCodeBlockLineNumbers` (defaults to `true`). When set to `false`, code-block line numbers are hidden and the left gutter shrinks to match the code block's right indent, giving the block symmetric horizontal padding instead of a flush-left edge. `customLeadingBlockBuilder` remains available for finer control and still takes precedence when both are set.

### Fixed

- Memory leaks in the editor, selection overlay, and toolbar. Notifiers, listeners, and overlay entries the editor creates are now disposed.
- Crash when a focus retry runs after the editor is disposed.
- Implement `onFocusReceived()` so the editor builds on Flutter 3.44.0.
- Stop exporting the deprecated internal `linkPrefixes` constant.
- Fixed an issue where bullet points became visually detached from the text body when toggling text direction formatting (RTL) by locking the list leading block to the editor's base text direction.
- Fixed a brief toolbar flicker when tapping a checkbox: the header, inline, and color buttons momentarily reflected the tapped line's style and the checklist button briefly toggled before the selection was restored. The checkbox tap's gesture-driven caret move is now ignored and the checkbox is formatted silently.
- Fixed typed text being inserted at the previous caret position on Android after moving the caret with a tap/mouse by keeping the platform IME's editing state in sync with the selection even when the keyboard is hidden.
- Added `transformLink` callback to `QuillEditorConfig` (and `RawEditorConfig`) to allow customizing how a link string is transformed before it is launched on tap. When `null`, the previous default behavior (prepending `https://` to scheme-less links) is preserved [#2727](https://github.com/singerdmx/flutter-quill/pull/2727).
- Whole-word search now matches non-ASCII text (Cyrillic, CJK, accented Latin).
- Fixed dragging the right selection handle horizontally extends the selection into the line below instead of staying on the current line.
- Code block line numbers were not visible for non-indented code blocks because the leading-gutter width was reserved at zero pixels in `TextBlockUtils.defaultIndentWidthBuilder`. The gutter is now sized correctly so line numbers are visible by default. Nested indent levels continue to rotate the numbering style through Arabic, lowercase letters, and lowercase Roman numerals, matching ordered-list behavior.
- Fixed the selection (Cut/Copy/Paste) context menu not appearing when the selection extends beyond the visible viewport — e.g. selecting a range taller than the viewport, scrolling a selection out of view, or **Select All** on a long document. The context menu anchors are now clamped into the editor's visible region so it stays on-screen, matching the behavior of a multiline `TextField`.
- Reveal the caret when the bottom view inset (on-screen keyboard) changes, so it is no longer hidden behind the keyboard when it appears or changes height mid-edit (e.g. on app resume, IME/emoji switch, rotation, split-screen or foldable resize). `QuillRawEditorState` now overrides `didChangeMetrics` and re-reveals the caret once the inset settles.

### Deprecated

- Deprecated `QuillController.toolbarButtonToggler`. It was an internal-only workaround for syncing a few toolbar block buttons during checkbox taps and no longer has any effect now that the flicker is fixed at its source. Toolbar button state derives from `getSelectionStyle()`. It will be removed in future versions.

### Removed

- Removed the already-`@Deprecated` and `@internal` `linkPrefixes` constant from the public API surface (it is hidden from the `flutter_quill.dart` export). Use `LinkValidator.linkPrefixes` instead.

### Changed

- Depend on the T-Pro `quill_native_bridge` fork with `xclip` removed.
- Search dialog buttons now adopt the toolbar's `QuillIconTheme`; bar height and spacing tightened.
- Tightened the code-block leading gutter: its reserved width is now slightly narrower than the ordered-list gutter (by `fontSize / 4`), pulling the right-aligned line number closer to the left edge of the block.
- Reduced the right-side padding inside the code-block leading container from `fontSize` to `fontSize / 2`, shrinking the gap between the line number and the code text to match ordered/unordered lists.
- Reduced the left content padding inside the code-block decoration from `16` to `4`, so the line number sits closer to the left edge of the grey code-block box.
- Made the code-block content padding symmetric (`EdgeInsets.symmetric(horizontal: 4, vertical: 16)`, previously `16` on the right), and added a `fontSize / 2` right indent to code blocks in `TextBlockUtils.defaultIndentWidthBuilder` so the code text no longer runs to the right edge of the box. The right indent is part of the default `indentWidthBuilder`, so a custom `indentWidthBuilder` can override it.

## [11.5.1] - 2026-05-20

### Added

- Added localization support for `mn` (Mongolian, Mongolia)

### Changed

- Updated minimum supported SDK version to Flutter 3.44/Dart 3.12.
- Implemented the new [TextInputClient.onFocusReceived](https://github.com/flutter/flutter/blob/stable/packages/flutter/lib/src/services/text_input.dart#L1395-L1401) method required by Flutter SDK 3.44+ (`returns false`).

## [11.5.0] - 2025-10-18

### Fixed

- Fixed `View.of(context)` calls throwing when used with the `screenshot` package [#2662](https://github.com/singerdmx/flutter-quill/pull/2662).

### Added

- Add missing Brazilian Portuguese translations

## [11.4.2] - 2025-07-22

Expand Down Expand Up @@ -190,8 +232,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Apple-specific font dependency for subscript and superscript functionality from the example.
- **BREAKING**: The [`super_clipboard`](https://pub.dev/packages/super_clipboard) plugin, To restore legacy behavior for `super_clipboard`, use [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions) package and `FlutterQuillExtensions.useSuperClipboardPlugin()`.

[unreleased]: https://github.com/singerdmx/flutter-quill/compare/v11.5.0...HEAD
[11.5.0]: https://github.com/singerdmx/flutter-quill/compare/v11.4.2...v11.5.0
[unreleased]: https://github.com/singerdmx/flutter-quill/compare/v11.5.2...HEAD
[11.5.2]: https://github.com/singerdmx/flutter-quill/compare/v11.5.1...v11.5.2
[11.5.1]: https://github.com/singerdmx/flutter-quill/compare/v10.0.0...v11.5.1
[11.5.0]: https://github.com/singerdmx/flutter-quill/compare/v10.0.0...v11.5.0
[11.4.2]: https://github.com/singerdmx/flutter-quill/compare/v10.0.0...v11.4.2
[11.4.1]: https://github.com/singerdmx/flutter-quill/compare/v10.0.0...v11.4.1
[11.4.0]: https://github.com/singerdmx/flutter-quill/compare/v10.0.0...v11.4.0
Expand Down
4 changes: 2 additions & 2 deletions doc/translation.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ your `WidgetsApp` for example `MaterialApp` which usually follows the system loc

## 🌐 Supported Locales

Currently, translations are available for these 48 locales:
Currently, translations are available for these 49 locales:

* `ar`, `bg`, `bn`, `ca`, `cs`, `da`, `de`
* `en`, `en_US`, `es`, `fa`, `fr`, `he`
* `hi`, `id`, `it`, `ja`, `ko`, `km`, `ku`
* `ms`, `ne`, `nl`, `no`, `pl`, `pt`
* `mn`, `ms`, `ne`, `nl`, `no`, `pl`, `pt`
* `pt_BR`, `ro`, `ro_RO`, `ru`, `sk`, `sr`
* `sv`, `sw`, `th`, `tk`, `tr`, `uk`, `ur`
* `vi`, `zh`, `zh_CN`, `zh_HK`, `hr`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
plugins {
id "com.android.application"
id "kotlin-android"
id("com.android.application")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
id("dev.flutter.flutter-gradle-plugin")
}

android {
Expand All @@ -15,10 +14,6 @@ android {
targetCompatibility = JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}

defaultConfig {
applicationId = "dev.flutterquill.flutter_quill_example"
minSdk = flutter.minSdkVersion
Expand All @@ -29,11 +24,18 @@ android {

buildTypes {
release {
signingConfig = signingConfigs.debug
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}

kotlin {
compilerOptions {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
}
}

flutter {
source = "../.."
}
18 changes: 0 additions & 18 deletions example/android/build.gradle

This file was deleted.

24 changes: 24 additions & 0 deletions example/android/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
allprojects {
repositories {
google()
mavenCentral()
}
}

val newBuildDir: Directory =
rootProject.layout.buildDirectory
.dir("../../build")
.get()
rootProject.layout.buildDirectory.value(newBuildDir)

subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}

tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}
4 changes: 4 additions & 0 deletions example/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false
2 changes: 1 addition & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
25 changes: 0 additions & 25 deletions example/android/settings.gradle

This file was deleted.

26 changes: 26 additions & 0 deletions example/android/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
pluginManagement {
val flutterSdkPath =
run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
}

includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}

plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "9.0.1" apply false
id("org.jetbrains.kotlin.android") version "2.3.20" apply false
}

include(":app")
11 changes: 6 additions & 5 deletions example/integration_test/flutter_quill_integration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ import 'package:integration_test/integration_test.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

testWidgets('$QuillEditor renders and handles input without crashing',
(tester) async {
testWidgets('$QuillEditor renders and handles input without crashing', (
tester,
) async {
// This test ensures that the QuillEditor can be created and accepts input
// without crashing on any platform.
//
// Example fix: https://github.com/singerdmx/flutter-quill/pull/2579

final controller = QuillController.basic();
await tester.pumpWidget(MaterialApp(
home: QuillEditor.basic(controller: controller),
));
await tester.pumpWidget(
MaterialApp(home: QuillEditor.basic(controller: controller)),
);

// Simulate text input to trigger user interactions.
await tester.quillEnterText(find.byType(QuillEditor), 'sample text\n');
Expand Down
1 change: 0 additions & 1 deletion example/ios/Flutter/Debug.xcconfig
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
1 change: 0 additions & 1 deletion example/ios/Flutter/Release.xcconfig
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
44 changes: 0 additions & 44 deletions example/ios/Podfile

This file was deleted.

Loading
Loading