Skip to content

feat: v3.0 for typeset (breaking) - #67

Open
rohanjsh wants to merge 12 commits into
devfrom
feat/v3-beta
Open

feat: v3.0 for typeset (breaking)#67
rohanjsh wants to merge 12 commits into
devfrom
feat/v3-beta

Conversation

@rohanjsh

@rohanjsh rohanjsh commented Feb 24, 2026

Copy link
Copy Markdown
Owner

Status

IN DEVELOPMENT

Description

This pull request prepares for the 3.0.0 release of TypeSet, introducing a major overhaul to its configuration, parser/renderer architecture, and documentation. The update emphasizes a new centralized configuration API, breaking changes to syntax and widget/controller parameters, and improved documentation for migration and contribution. Below are the most important changes:

Major API and Architecture Changes

  • Introduced TypeSetConfig, TypeSetStyle, and TypeSetAutoLinkConfig for centralized and safer widget/controller configuration; parser and renderer are now structured as an AST pipeline. (CHANGELOG.md CHANGELOG.mdL1-R180)
  • Replaced legacy per-widget and per-controller style parameters with config objects; removed legacy parser/controller internals from the public API. (CHANGELOG.md CHANGELOG.mdL1-R180)

Breaking Changes and Migration

  • Changed underline syntax from #text# to __text__; removed several constructor parameters from TypeSet and TypeSetEditingController; removed StyleTypeEnum.link from context menus. (CHANGELOG.md [1] MIGRATION.md [2]
  • Added a comprehensive migration guide for upgrading from 2.x to 3.0.0, detailing all required code and usage changes. (MIGRATION.md MIGRATION.mdR1-R121)

Documentation and Project Maintenance

  • Rewrote and reorganized README.md to reflect the new configuration model, usage, and migration steps; added references to new documentation files. (README.md README.mdL1-R185)
  • Added a CONTRIBUTING.md file with clear guidelines for development, pull requests, and the release process. (CONTRIBUTING.md CONTRIBUTING.mdR1-R58)
  • Added a .pubignore file to exclude legacy files, build artifacts, and IDE/editor metadata from package publishing. (.pubignore .pubignoreR1-R38)

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 🛠️ Bug fix (non-breaking change which fixes an issue)
  • ❌ Breaking change (fix or feature that would cause existing functionality to change)
  • 🧹 Code refactor
  • ✅ Build configuration change
  • 📝 Documentation
  • 🗑️ Chore

Updates the package to version 3.0.0-beta.1, introducing a breaking release focused on parser/renderer architecture, configuration standardization, and safer AutoLink controls.

The update includes:
- Introduction of new configuration options such as `TypeSetConfig`, `TypeSetStyle`, and `TypeSetAutoLinkConfig`
- Restructuring of the `TypeSet` and `TypeSetEditingController` to utilize the new configuration model
- Changes to the underline delimiter syntax from `#text#` to `__text__`
- Removal of legacy parser/controller internals and style parameters
- Updates the README and CONTRIBUTING files with comprehensive documentation and contribution guidelines
- Adds a migration guide to facilitate upgrading from v2.x to v3.0.0
Introduces a new parser and renderer for handling rich text formatting.
The parser converts marked-up text into an abstract syntax tree (AST),
supporting styles like bold, italic, underline, and strikethrough, as well as code blocks and autolinking of URLs.

The renderer then transforms this AST into Flutter's InlineSpan objects for display.

Also introduces a config provider to customize text rendering.
Adds AST node definitions for text, code, links, and styled spans to represent the parsed structure.

Introduces configuration models for global settings, autolinking, and text styles, providing flexibility in customizing the typesetting behavior.

Removes the previous style enum and value model in favor of the new configuration approach.
This commit introduces a new `TypeSet` widget that leverages a
configuration object for styling and autolinking, providing
greater flexibility and customization. It deprecates the old
implementation by removing the old files, and introduces new ones.

The new implementation utilizes `Text.rich` and introduces a
`TypeSetEditingController` for applying formatting to editable text
fields, enhancing the user experience when creating and modifying
formatted text. Context menus are also added to easily style text.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Prepares TypeSet for the v3.0.0 (breaking) release by replacing the legacy span-based parser/controller with an AST parse → AutoLink → render pipeline and introducing centralized configuration APIs for rendering, editing, and link behavior.

Changes:

  • Introduces TypeSetConfig / TypeSetStyle / TypeSetAutoLinkConfig, plus scoped/global config mechanisms.
  • Replaces legacy parsing/rendering internals with new AST nodes, parser, AutoLink pass, and renderer.
  • Updates example app, tests, and documentation (README/migration/changelog/contributing), and removes url_launcher integration.

Reviewed changes

Copilot reviewed 48 out of 49 changed files in this pull request and generated no comments.

Show a summary per file
File Description
test/src/view/typeset_widget.dart Updates test demo widget usage to pass TypeSetConfig (AutoLink recognizer via config).
test/src/view/typeset_test.dart Removes legacy TypesetParser tests; keeps widget smoke tests.
test/src/view/typeset_editing_controller_test.dart Updates editing controller tests for new delimiter behavior and AutoLink rendering expectations.
test/src/view/typeset_context_menus_test.dart Updates context menu test expectations (underline delimiter change; link option removed).
test/src/models/style_type_value_model_test.dart Removes tests for deleted legacy model.
test/src/core/typeset_reserved_test.dart Updates reserved delimiter expectations (escape/backslash, underline __, sets).
test/src/core/typeset_renderer_test.dart Adds renderer + widget integration tests for new pipeline.
test/src/core/typeset_parser_test.dart Rewrites parser tests for AST output and AutoLink behavior.
test/src/core/typeset_controller_test.dart Removes tests for deleted legacy controller.
pubspec.yaml Bumps to 3.0.0-beta.1, updates metadata, removes url_launcher.
lib/typeset.dart Updates public exports to new config + reserved/style APIs.
lib/src/view/typeset_ext.dart Switches string extension API to accept TypeSetConfig instead of per-style params.
lib/src/view/typeset_editing_controller.dart Replaces inline parsing with AST parse + renderer (show delimiters) and config resolution.
lib/src/view/typeset_context_menus.dart Reworks context menu styles and wrapping logic; removes link menu option.
lib/src/view/typeset.dart Replaces legacy parser usage with AST parser + renderer and config resolution.
lib/src/models/typeset_style.dart Adds centralized style configuration model.
lib/src/models/typeset_reserved.dart Adds new reserved delimiter constants (underline __, escape \).
lib/src/models/typeset_global_config.dart Adds global singleton config holder (test reset supported).
lib/src/models/typeset_config.dart Adds central config object + defaults factory.
lib/src/models/typeset_autolink_config.dart Adds AutoLink policy (schemes/domains/validator/recognizer builder).
lib/src/models/style_type_value_model.dart Removes legacy model.
lib/src/models/style_type_enum.dart Removes legacy enum.
lib/src/models/ast/typeset_nodes.dart Adds AST node model (text/code/style/link nodes).
lib/src/core/typeset_reserved.dart Removes legacy reserved constants (including link markers/font-size regex).
lib/src/core/typeset_parser.dart Removes legacy TextSpan parser implementation (and url_launcher integration).
lib/src/core/typeset_controller.dart Removes legacy controller-based manipulation pipeline.
lib/src/core/typeset_config_provider.dart Adds inherited widget for subtree-scoped config.
lib/src/core/renderer/typeset_renderer.dart Adds AST → InlineSpan renderer with delimiter-visibility support.
lib/src/core/parser/typeset_parser.dart Adds new inline parser producing AST and optional AutoLink post-pass.
lib/src/core/parser/typeset_autolink_pass.dart Adds AutoLink transformation pass over AST.
example/windows/flutter/generated_plugins.cmake Removes url_launcher plugin registration.
example/windows/flutter/generated_plugin_registrant.cc Removes url_launcher plugin registration.
example/macos/Flutter/GeneratedPluginRegistrant.swift Removes url_launcher plugin registration.
example/linux/flutter/generated_plugins.cmake Removes url_launcher plugin registration.
example/linux/flutter/generated_plugin_registrant.cc Removes url_launcher plugin registration.
example/lib/main.dart Reworks example UI and demonstrates config + scoped editing/preview flow.
example/ios/Runner/Info.plist Reorders/adds keys (scene manifest/indirect input events).
example/ios/Runner/AppDelegate.swift Updates plugin registration to implicit engine delegate path.
example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme Adds custom LLDB init file.
example/ios/Runner.xcodeproj/project.pbxproj Updates iOS deployment target to 13.0 and removes embed pods frameworks phase.
example/ios/Podfile.lock Updates lockfile to remove url_launcher iOS pod.
example/ios/Podfile Updates commented platform version to 13.0.
example/ios/Flutter/AppFrameworkInfo.plist Removes MinimumOSVersion entry.
doc/UNDER_THE_HOOD.md Adds detailed explanation of the new pipeline and config precedence.
README.md Rewrites docs for v3 config model, new syntax, and migration links.
MIGRATION.md Adds 2.x → 3.0.0 migration guide for breaking API/syntax changes.
CONTRIBUTING.md Adds contribution and release workflow guidance.
CHANGELOG.md Adds 3.0.0-beta.1 changelog entry and restructures historical entries.
.pubignore Adds publish ignore list for legacy files and artifacts.
Comments suppressed due to low confidence (8)

lib/src/models/typeset_autolink_config.dart:70

  • TypeSetAutoLinkConfig.operator== compares allowedSchemes with ==, but Set equality in Dart is identity-based. Two configs with the same scheme values but different set instances will compare as unequal, which affects updateShouldNotify and any equality-based logic. Consider using deep set equality (e.g., allowedSchemes.length == other.allowedSchemes.length && allowedSchemes.containsAll(other.allowedSchemes)) and aligning hashCode accordingly.
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is TypeSetAutoLinkConfig &&
          runtimeType == other.runtimeType &&
          allowedSchemes == other.allowedSchemes &&
          allowedDomains == other.allowedDomains &&
          customValidator == other.customValidator &&
          linkRecognizerBuilder == other.linkRecognizerBuilder;

  @override
  int get hashCode =>
      allowedSchemes.hashCode ^
      allowedDomains.hashCode ^
      customValidator.hashCode ^
      linkRecognizerBuilder.hashCode;

lib/src/view/typeset_context_menus.dart:58

  • The “already styled” guard returns early whenever the selected text starts and ends with a delimiter. This incorrectly treats selections that are only delimiters (e.g. selecting _ or __) as already-styled text, preventing formatting actions even though there’s no wrapped content. Consider requiring selectionText.length > delimiter.length * 2 (or at least >= delimiter.length * 2 + 1) before treating it as styled.
    .pubignore:38
  • Several ignore patterns look unintended: _.iml, _.ipr, _.log, _.pyc won’t match typical filenames (likely meant *.iml, *.ipr, *.log, *.pyc). Also the escaped patterns like \*.iws / \*.swp match a literal * in gitignore-style syntax rather than acting as a wildcard. Consider switching to standard wildcard patterns so these files are actually excluded from dart pub publish.
# IDE/editor metadata

.idea/
.vscode/
_.iml
_.ipr
\*.iws

# Misc local artifacts

.DS_Store
_.log
_.pyc
\*.swp

README.md:6

  • The build status badge links to the issues page rather than the GitHub Actions workflow runs, so users clicking it won’t reach the build results. Consider updating the link target to the workflow (e.g., /actions/workflows/main.yaml) or the Actions page.
[![pub package](https://img.shields.io/pub/v/typeset.svg)](https://pub.dev/packages/typeset)
[![style: very good analysis](https://img.shields.io/badge/style-very_good_analysis-B22C89.svg)](https://pub.dev/packages/very_good_analysis)
[![build status](https://img.shields.io/github/actions/workflow/status/rohanjsh/typeset/main.yaml)](https://github.com/rohanjsh/typeset/issues)

lib/src/view/typeset.dart:97

  • TypeSetConfig docs say autoLinkConfig: null means “use scoped or global defaults”, but effectiveConfig = config ?? scopedConfig ?? TypeSetGlobalConfig.instance treats a partially-specified local config as overriding the entire config. This makes it impossible to override only style while inheriting AutoLink policy (and vice versa), and it diverges from the documented precedence behavior. Consider resolving an effective config by layering/merging (global defaults → provider → local), filling null fields from the next fallback rather than replacing the whole object.
    lib/src/view/typeset_editing_controller.dart:65
  • TypeSetConfig is documented as allowing null fields to fall back to scoped/global defaults, but effectiveConfig = config ?? scopedConfig ?? TypeSetGlobalConfig.instance doesn't merge fields. A local config that only sets style will silently drop any scoped/global autoLinkConfig (and vice versa). Consider composing the effective config by merging non-null fields from (global → provider → local) instead of picking a single object.
    lib/src/core/typeset_config_provider.dart:29
  • TypeSetConfigProvider.maybeOf currently falls back to TypeSetConfig.defaults() and ignores TypeSetGlobalConfig.instance. This is inconsistent with the documented precedence (local → provider → global → defaults) and can surprise callers that expect global defaults to apply when no provider is in the tree. Consider either (a) including TypeSetGlobalConfig.instance in the fallback chain, or (b) renaming/documenting maybeOf to make it clear it bypasses global config.
  /// Gets the configuration from the nearest ancestor provider.
  static TypeSetConfig? of(BuildContext context) {
    return context
        .dependOnInheritedWidgetOfExactType<TypeSetConfigProvider>()
        ?.config;
  }

  /// Gets the configuration from the nearest ancestor provider, or the default.
  static TypeSetConfig maybeOf(BuildContext context) {
    return context
            .dependOnInheritedWidgetOfExactType<TypeSetConfigProvider>()
            ?.config ??
        TypeSetConfig.defaults();
  }

lib/src/models/typeset_autolink_config.dart:18

  • TypeSetAutoLinkConfig.allowedSchemes is a mutable Set<String> but the class is marked @immutable. As written, callers can mutate the set after constructing the config, changing behavior at runtime and making equality/hashCode unreliable. Consider defensively copying to an unmodifiable set in the constructor/copyWith (e.g., Set.unmodifiable(...)) and documenting that the input set must not be mutated.
  const TypeSetAutoLinkConfig({
    this.allowedSchemes = const {'http', 'https'},
    this.allowedDomains,
    this.customValidator,
    this.linkRecognizerBuilder,
  });

  /// Allowed URL schemes (default: http, https). Empty set disables autolink.
  final Set<String> allowedSchemes;

  /// Optional regex pattern for domain allowlisting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

rohanjsh and others added 6 commits April 2, 2026 22:39
Introduces a compiled document model and cache to optimize rendering performance across the library. This update adds a runtime session for managing gesture recognizer lifecycles and implements hierarchical configuration resolution across theme, global, scoped, and local layers.

The editing controller is enhanced with safety guards for large text and improved composing range support, while the parser receives refinements for autolink boundaries and balanced closing delimiters.
Rewrites the README, Migration Guide, and Under the Hood documentation for improved clarity and detail. Optimizes the parser and autolink pass to use index-based scanning and text runs, significantly reducing string allocations during document compilation. Updates the minimum Flutter SDK requirement to 3.10.0 and bumps the package version.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants