flutter_quill_kit_media 0.1.0
flutter_quill_kit_media: ^0.1.0 copied to clipboard
Image and video embeds for flutter_quill_kit: renderers, resize and alignment options, and toolbar insert buttons.
flutter_quill_kit_media #
Image and video embeds for flutter_quill_kit:
embed renderers, insert toolbar buttons, and flutter_quill-compatible size
attributes — with zero heavy dependencies. No image_picker, no
video_player, no cached_network_image; anything platform-specific is
injected by your app instead.
Features #
ImageEmbedRenderer— rendersimageembeds from network URLs,data:URIs, andasset://paths out of the box; file paths and caching via an injectedimageProviderBuilder. Respects flutter_quill'swidth/heightattributes and its css-ishstyleattribute (width: 100px; height: 80px;), shows a grey box while loading and a broken-image box (tooltip = source) on failure. OptionalonImageTap.VideoEmbedRenderer— rendersvideoembeds as a 16:9 thumbnail card (dark box, play icon, URL host). YouTube thumbnails are derived automatically; anything else via an injectedthumbnailBuilder. Tap runsonVideoTap, falling back to the editor'sLinkLauncherservice.MediaExtension— oneEditorExtensionwiring both renderers plus insert-image / insert-video toolbar buttons (groupmedia) with a URL dialog, validation, and an optional gallery button backed by your picker.MediaStrings/MediaStringsScope— localizable strings, same pattern as the coreQuillKitStrings.
Installation #
flutter pub add flutter_quill_kit_media
Requires flutter_quill_kit. Runs everywhere Flutter does — the
renderers are plain widgets with no platform channels.
Quick start #
import 'package:flutter_quill_kit/flutter_quill_kit.dart';
import 'package:flutter_quill_kit_media/flutter_quill_kit_media.dart';
final controller = QuillKitController(
document: Document.fromJson(deltaJson),
extensions: [
...QuillKitExtensions.standard(),
MediaExtension(),
],
);
// QuillKitToolbar(controller: controller) now shows the insert buttons,
// and QuillKitEditor picks the renderers up from the extension:
QuillKitEditor(controller: controller);
// The controller-free viewer takes the renderers explicitly:
QuillKitViewer(
document: document,
embedRenderers: const [ImageEmbedRenderer(), VideoEmbedRenderer()],
);
Block embeds land on their own line: inserting mid-line splits the line
around the embed (core InsertEmbedRule behavior). Alignment uses the
standard align attribute on the embed's line — no custom attribute.
Injection recipes #
File and cached images (cached_network_image) #
MediaExtension(
imageRenderer: ImageEmbedRenderer(
imageProviderBuilder: (source) => source.startsWith('http')
? CachedNetworkImageProvider(source)
: FileImage(File(source)),
),
)
The builder replaces the built-in resolution entirely, so it decides for every source string — URLs, file paths, whatever your documents store.
Picking images (image_picker) #
MediaExtension(
onPickImage: () async {
final file = await ImagePicker().pickImage(source: ImageSource.gallery);
if (file == null) return null;
// Return whatever source string your renderer understands:
// upload and return a URL, or return file.path with a
// FileImage-capable imageProviderBuilder (see above).
return file.path;
},
)
When onPickImage is set, the insert-image dialog gains a gallery button;
the returned string is inserted as the embed's source.
Inline video playback (video_player) #
The bundled video renderer is a tap-through card by design. For inline
playback, register your own renderer for type video instead:
class PlayingVideoRenderer extends EmbedRenderer {
const PlayingVideoRenderer();
@override
String get type => 'video';
@override
Widget build(BuildContext context, EmbedRenderContext ctx) {
final url = ctx.embed.data as String;
return MyVideoPlayerWidget(url: url); // wraps VideoPlayerController
}
}
MediaExtension(videoRenderer: const PlayingVideoRenderer())
Localization #
MediaStringsScope(
strings: MediaStrings(insertImage: 'Bild einfügen'),
child: QuillKitToolbar(controller: controller),
)
Delta compatibility #
Embeds serialize to standard Quill JSON — {"insert": {"image": "https://…"}}
— and the size attributes (width, height, style) match what
flutter_quill and its resize UI emit, so documents move between the two
ecosystems unchanged.
License #
MIT — see LICENSE.