Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Added localization support for `mn` (Mongolian, Mongolia)
- 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

- 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.

### Changed

- 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.0] - 2025-10-18

Expand Down
12 changes: 12 additions & 0 deletions lib/src/editor/config/editor_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,20 @@ class QuillEditorConfig {
this.readOnlyMouseCursor = SystemMouseCursors.text,
this.onPerformAction,
@experimental this.customLeadingBlockBuilder,
this.showCodeBlockLineNumbers = true,
});

@experimental
final LeadingBlockNodeBuilder? customLeadingBlockBuilder;

/// Whether to display line numbers in code blocks.
///
/// Defaults to `true`. When `false`, the line-number widget is hidden
/// and the left gutter shrinks to match the code block's right indent
/// (`fontSize / 2` by default), so the block has symmetric horizontal
/// padding instead of a flush-left edge.
final bool showCodeBlockLineNumbers;

/// The text placeholder in the quill editor
final String? placeholder;

Expand Down Expand Up @@ -531,10 +540,13 @@ class QuillEditorConfig {
void Function()? onScribbleActivated,
EdgeInsets? scribbleAreaInsets,
void Function(TextInputAction action)? onPerformAction,
bool? showCodeBlockLineNumbers,
}) {
return QuillEditorConfig(
customLeadingBlockBuilder:
customLeadingBlockBuilder ?? this.customLeadingBlockBuilder,
showCodeBlockLineNumbers:
showCodeBlockLineNumbers ?? this.showCodeBlockLineNumbers,
placeholder: placeholder ?? this.placeholder,
characterShortcutEvents:
characterShortcutEvents ?? this.characterShortcutEvents,
Expand Down
1 change: 1 addition & 0 deletions lib/src/editor/editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ class QuillEditorState extends State<QuillEditor>
spaceShortcutEvents: widget.config.spaceShortcutEvents,
onKeyPressed: widget.config.onKeyPressed,
customLeadingBuilder: widget.config.customLeadingBlockBuilder,
showCodeBlockLineNumbers: widget.config.showCodeBlockLineNumbers,
focusNode: widget.focusNode,
scrollController: widget.scrollController,
scrollable: config.scrollable,
Expand Down
4 changes: 4 additions & 0 deletions lib/src/editor/raw_editor/config/raw_editor_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class QuillRawEditorConfig {
this.onPerformAction,
@experimental this.customLeadingBuilder,
this.quillMagnifierBuilder,
this.showCodeBlockLineNumbers = true,
});

/// Controls whether this editor has keyboard focus.
Expand All @@ -82,6 +83,9 @@ class QuillRawEditorConfig {
@experimental
final LeadingBlockNodeBuilder? customLeadingBuilder;

/// See [QuillEditorConfig.showCodeBlockLineNumbers].
final bool showCodeBlockLineNumbers;

/// Contains all the events that will be handled when
/// the exact characters satifies the condition. This mean
/// if you press asterisk key, if you have a `CharacterShortcutEvent` with
Expand Down
3 changes: 2 additions & 1 deletion lib/src/editor/raw_editor/raw_editor_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ class QuillRawEditorState extends EditorState
block: node,
controller: controller,
customLeadingBlockBuilder: widget.config.customLeadingBuilder,
showCodeBlockLineNumbers: widget.config.showCodeBlockLineNumbers,
textDirection: nodeTextDirection,
scrollBottomInset: widget.config.scrollBottomInset,
horizontalSpacing: _getHorizontalSpacingForBlock(node, _styles),
Expand All @@ -605,7 +606,7 @@ class QuillRawEditorState extends EditorState
enableInteractiveSelection: widget.config.enableInteractiveSelection,
hasFocus: _hasFocus,
contentPadding: attrs.containsKey(Attribute.codeBlock.key)
? const EdgeInsets.all(16)
? const EdgeInsets.symmetric(horizontal: 4, vertical: 16)
: null,
embedBuilder: widget.config.embedBuilder,
textSpanBuilder: widget.config.textSpanBuilder,
Expand Down
26 changes: 20 additions & 6 deletions lib/src/editor/widgets/text/text_block.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class EditableTextBlock extends StatelessWidget {
this.customStyleBuilder,
this.customLinkPrefixes = const <String>[],
this.customLeadingBlockBuilder,
this.showCodeBlockLineNumbers = true,
super.key,
});

Expand All @@ -97,6 +98,7 @@ class EditableTextBlock extends StatelessWidget {
final Color color;
final DefaultStyles? styles;
final LeadingBlockNodeBuilder? customLeadingBlockBuilder;
final bool showCodeBlockLineNumbers;
final bool enableInteractiveSelection;
final bool hasFocus;
final EdgeInsets? contentPadding;
Expand Down Expand Up @@ -168,6 +170,17 @@ class EditableTextBlock extends StatelessWidget {
TextBlockUtils.defaultIndentWidthBuilder;

final count = block.children.length;
final isCodeBlock =
block.style.attributes.containsKey(Attribute.codeBlock.key);
final blockSpacing =
indentWidthBuilder(block, context, count, numberPointWidthBuilder);
final HorizontalSpacing horizontalSpacingForBlock;
if (isCodeBlock && !showCodeBlockLineNumbers) {
horizontalSpacingForBlock =
HorizontalSpacing(blockSpacing.right, blockSpacing.right);
Comment on lines +176 to +180
} else {
horizontalSpacingForBlock = blockSpacing;
}
final children = <Widget>[];
if (clearIndents) {
indentLevelCounts.clear();
Expand Down Expand Up @@ -199,7 +212,7 @@ class EditableTextBlock extends StatelessWidget {
customRecognizerBuilder: customRecognizerBuilder,
composingRange: composingRange,
),
indentWidthBuilder(block, context, count, numberPointWidthBuilder),
horizontalSpacingForBlock,
_getSpacingForLine(line, index, count, defaultStyles),
textDirection,
textSelection,
Expand Down Expand Up @@ -297,21 +310,21 @@ class EditableTextBlock extends StatelessWidget {
);
}(),
width: () {
if (isOrdered || isCodeBlock) {
if (isOrdered) {
return numberPointWidthBuilder(fontSize, count);
}
if (isCodeBlock) {
return numberPointWidthBuilder(fontSize, count) - fontSize / 4;
}
if (isUnordered) {
return numberPointWidthBuilder(fontSize, 1); // same as fontSize * 2
}
return null;
}(),
padding: () {
if (isOrdered || isUnordered) {
if (isOrdered || isUnordered || isCodeBlock) {
return fontSize / 2;
}
if (isCodeBlock) {
return fontSize;
}
return null;
}(),
lineSize: isCheck ? fontSize : null,
Expand Down Expand Up @@ -343,6 +356,7 @@ class EditableTextBlock extends StatelessWidget {
return checkboxLeading(leadingConfig);
}
if (isCodeBlock) {
if (!showCodeBlockLineNumbers) return null;
return codeBlockLineNumberLeading(leadingConfig);
}
return null;
Expand Down
5 changes: 3 additions & 2 deletions lib/src/editor/widgets/text/utils/text_block_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ abstract final class TextBlockUtils {
baseIndent = fontSize * 2;
if (attrs[Attribute.list.key] == Attribute.ol) {
baseIndent = numberPointWidthBuilder(fontSize, count);
} else if (attrs.containsKey(Attribute.codeBlock.key)) {
baseIndent = numberPointWidthBuilder(fontSize, count);
}
} else if (attrs.containsKey(Attribute.codeBlock.key)) {
baseIndent = numberPointWidthBuilder(fontSize, count) - fontSize / 4;
return HorizontalSpacing(baseIndent + extraIndent, fontSize / 2);
}
Comment on lines +72 to 75

return HorizontalSpacing(baseIndent + extraIndent, 0);
Expand Down
Loading