bluesky_text_flutter 0.1.2 copy "bluesky_text_flutter: ^0.1.2" to clipboard
bluesky_text_flutter: ^0.1.2 copied to clipboard

Flutter widgets for bluesky_text — a rich-text editing controller that highlights entities and the over-limit tail as you type, and a viewer for fetched posts.

Flutter widgets for bluesky_text 🦋

bluesky_text_flutter #

The "last mile" Flutter layer on top of bluesky_text: drop-in widgets for the two things every Bluesky client needs — a rich-text composer and a post viewer — so you never hand-roll TextSpan trees or manage GestureRecognizer lifecycles yourself.

Features ⭐ #

  • BlueskyTextEditingController — live-highlights entities (handles, links, tags) and the over-limit tail as the user types, in one pass per keystroke. Keeps the IME composing underline. Exposes overflow for a character counter.
  • BlueskyRichText — renders a fetched post from its authoritative server facets (mentions carry their DID) with tappable mentions, links and tags. Recognizers are owned and disposed by the widget — no leaks.
  • ✅ Re-exports all of bluesky_text, so you import a single package.

Composer #

final controller = BlueskyTextEditingController();

TextField(
  controller: controller,
  maxLines: null,
);

// Character counter:
final overflow = controller.overflow; // null when within the 300 / 3000 limit

Entities default to the theme's primary color and the over-limit tail to the error color; override with entityStyle, overflowStyle, or a full styleBuilder.

Viewer #

The simplest integration is onFeatureTap, a single callback invoked for any tapped feature with the resolved FacetFeature — a mention's DID, a link's URI, or a tag's value — and switch on feature.type:

BlueskyRichText(
  text: post.record.text,
  facets: post.record.facets
          ?.map((f) => PostFacet.fromJson(f.toJson()))
          .toList() ??
      const [],
  onFeatureTap: (feature) {
    switch (feature.type) {
      case EntityType.handle:
        context.go('/profile/${feature.value}'); // value is the DID
      case EntityType.link:
        launchUrlString(feature.value);
      case EntityType.tag || EntityType.cashtag:
        context.go('/tag/${feature.value}');
      case EntityType.markdownLink:
        break;
    }
  },
);

typedef FeatureTapCallback = void Function(FacetFeature feature);

If you prefer per-kind handlers, the typed conveniences onMentionTap(String did), onLinkTap(String uri) and onTagTap(String tag) are dispatched by feature kind and take precedence over onFeatureTap for their kind:

BlueskyRichText(
  text: post.record.text,
  facets: facets,
  onMentionTap: (did) => context.go('/profile/$did'),
  onLinkTap: (uri) => launchUrlString(uri),
  onTagTap: (tag) => context.go('/tag/$tag'),
);

Styling is controlled with featureStyle (applied to mention/link/tag slices, defaulting to the theme's primary color) and style (the base style for the whole text), plus the usual Text layout parameters textAlign, maxLines and overflow:

BlueskyRichText(
  text: post.record.text,
  facets: facets,
  style: theme.textTheme.bodyMedium,
  featureStyle: TextStyle(color: theme.colorScheme.primary),
  textAlign: TextAlign.start,
  maxLines: 4,
  overflow: TextOverflow.ellipsis,
  onFeatureTap: onFeatureTap,
);

Getting Started 💪 #

dependencies:
  bluesky_text_flutter: ^0.1.2

See example/lib/main.dart for a runnable demo of both widgets.

0
likes
160
points
250
downloads

Documentation

API reference

Publisher

verified publisheratprotodart.com

Weekly Downloads

Flutter widgets for bluesky_text — a rich-text editing controller that highlights entities and the over-limit tail as you type, and a viewer for fetched posts.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#atproto #bluesky #flutter #richtext

Funding

Consider supporting this project:

github.com

License

BSD-3-Clause (license)

Dependencies

bluesky_text, flutter

More

Packages that depend on bluesky_text_flutter