olu

pub package License: MIT

RTL-first Flutter UI kit with zero dependencies.

Production-ready widgets for Arabic and multilingual apps: advanced typography (OLUText), responsive Bento dashboards (OLUBento), and RTL-aware carousels (OLUCarousel). Built with CustomPainter, implicit animations, and full ThemeData integration — no third-party packages.

Why olu?

Problem olu solution
Arabic justify / kashida breaks words or sacred phrases Smart kashida engine with exclusions, font-aware tatweel, Mushaf variant
Mixed Arabic/Latin/CJK baseline misalignment Script-aware spans, bidi isolation, auto-detection
RTL layouts feel bolted-on Native RTL mirroring (Bento), swipe physics & indicators (Carousel)
Heavy carousel / grid dependencies Zero deps — theme-only colors, lightweight painters

Features

OLUText

Drop-in Text / RichText replacement with:

  • Kashida & smart justify — sacred-word and hamza exclusions, font-aware tatweel scaling
  • Global scripts — Arabic, Persian, Urdu, Hebrew, Latin, CJK with script-aware line height
  • Bidi utilitiesOLUBidi.isolateLtr, normalizeMixed, mixed inline icons without WidgetSpan
  • Tajweed — grouped color spans (phase A) and per-glyph painter (phase B)
  • Effects — gradient, shadow, stroke; marquee scrolling
  • Links & rich spansOLULinkSpan, OLUArabicSpan, OLULatinSpan, OLUCjkSpan

OLUBento

Smart Bento grid with:

  • RTL auto-mirroring, scroll, responsive breakpoints, drag reorder
  • 16 preset tiles — Hero, Stat, Media, Banner, List, CTA, Icon, Chart, Profile, Progress, ProgressRing, Quote, Event, Alert, Rating, Toggle
  • OLUBentoThemeData — radius, padding, gaps, skeleton colors
  • Tile states — ready, loading, error, empty

OLUCarousel

RTL-aware carousel with:

  • Autoplay, loop, external controller — pause on touch / manual navigation
  • 3 indicator styles — glass dots (tappable), bar progress, numeric fraction
  • Page transforms — scale and parallax peek effect
  • RTL arrows & physics — direction-correct swipe and navigation
  • 6 preset slides — Hero, Image, Product, Text, Stat, CTA

Installation

dependencies:
  olu: ^1.0.0
flutter pub get

Import everything from a single entry point:

import 'package:olu/olu.dart';

Quick start

Register theme extensions once in your MaterialApp:

MaterialApp(
  theme: ThemeData(
    colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
    extensions: const [
      OLUBentoThemeData(),
      OLUCarouselThemeData(),
    ],
  ),
  // ...
);

All widgets read colors from Theme.of(context) — no hard-coded palette.

OLUText

// Smart justify (kashida / word-spacing / Flutter justify by script)
OLUText(
  'النص العربي',
  textAlign: OLUTextAlign.justify,
  style: Theme.of(context).textTheme.bodyLarge,
);

// Auto-detect mixed scripts
OLUText.auto('Price: \$99 / السعر ٩٩ ريال');

// Kashida with sacred-word exclusions (default)
OLUText(
  'إن اللّٰه على كل شيء قدير',
  textAlign: OLUTextAlign.kashidaJustify,
);

// Per-glyph tajweed (custom painter)
OLUText.tajweed(
  'بِسْمِ اللَّهِ',
  style: Theme.of(context).textTheme.headlineSmall,
  tajweedRules: [
    OLUTajweedRule(start: 0, end: 1, color: Theme.of(context).colorScheme.primary),
  ],
);

// RTL-safe inline icons (no WidgetSpan)
OLUText.mixed(
  spans: [
    OLUIconSpan(Icons.check, color: Theme.of(context).colorScheme.primary),
    OLUArabicSpan(' عنصر القائمة'),
  ],
);

OLUBento

OLUBento(
  crossAxisCount: 4,
  gap: 12,
  breakpoints: {480: 3, 720: 4, 1024: 6},
  children: [
    ...OLUBentoLayouts.dashboard4Col(context),
    OLUBentoItem(
      colSpan: 2,
      rowSpan: 1,
      child: OLUBentoHeroTile(title: 'Welcome', subtitle: 'Dashboard'),
    ),
  ],
);

// All 16 tile types in one layout
OLUBento(
  crossAxisCount: 2,
  children: OLUBentoLayouts.fullCatalog(context),
);

Preset tiles: OLUBentoHeroTile, OLUBentoStatTile, OLUBentoMediaTile, OLUBentoBannerTile, OLUBentoListTile, OLUBentoCtaTile, OLUBentoIconTile, OLUBentoChartTile, OLUBentoProfileTile, OLUBentoProgressTile, OLUBentoProgressRingTile, OLUBentoQuoteTile, OLUBentoEventTile, OLUBentoAlertTile, OLUBentoRatingTile, OLUBentoToggleTile.

See doc/olu_bento_guide.md for layout presets, responsive breakpoints, and tile catalog.

OLUCarousel

// Autoplay hero banner with bar indicator
OLUCarousel(
  height: 240,
  autoPlay: true,
  loop: true,
  showArrows: true,
  indicatorStyle: OLUCarouselIndicatorStyle.bar,
  children: OLUCarouselLayouts.hero3(context),
);

// Peek carousel with scale transform + numeric indicator
OLUCarousel(
  height: 200,
  viewportFraction: 0.85,
  enlargeStrategy: OLUCarouselEnlargeStrategy.scale,
  indicatorStyle: OLUCarouselIndicatorStyle.number,
  items: OLUCarouselLayouts.productStrip(context),
);

// External controller
final controller = OLUCarouselController();
OLUCarousel(controller: controller, height: 200, children: slides);
await controller.next();

Preset slides: OLUCarouselHeroSlide, OLUCarouselImageSlide, OLUCarouselProductSlide, OLUCarouselTextSlide, OLUCarouselStatSlide, OLUCarouselCtaSlide.

See doc/olu_carousel_guide.md for controller API, autoplay options, and indicator styles.

Documentation

Guide Contents
doc/olu_bento_guide.md Tile catalog, OLUBentoLayouts, responsive grid, theme
doc/olu_carousel_guide.md Autoplay, loop, indicators, transforms, preset slides
doc/olu_text_field_scope.md Planned OLUTextField scope (v1.1)
CHANGELOG.md Release history
API docs Generated dartdoc on pub.flutter-io.cn

Example app

A full showcase ships in the example/ directory:

cd example
flutter run

Demos include RTL/LTR toggle, dark/light mode, kashida exclusions, tajweed, mixed scripts, all 16 Bento tiles, and 6 Carousel slide types.

Platform support

Platform Supported
Android
iOS
Web ✓ (use CanvasKit for Arabic — see below)
macOS
Windows
Linux
Use case Suggested fonts
General UI Noto Naskh Arabic, Amiri
Quranic / Mushaf KFGQPC Uthmanic script, Amiri Quran, Scheherazade New
Persian Noto Naskh Arabic or Vazirmatn
Urdu Noto Nastaliq Urdu (display), Noto Naskh Arabic (UI)

Register fonts in your app's pubspec.yaml and set fontFamily on TextStyle, or use OLUTextVariant.mushaf for Quranic defaults.

Web (Flutter)

Arabic and complex scripts on Flutter web render most reliably with CanvasKit:

flutter run -d chrome --web-renderer canvaskit
flutter build web --web-renderer canvaskit

The HTML renderer may show joining or diacritic issues; prefer CanvasKit for production RTL apps.

Known limitations

Some RTL text issues are engine-level and cannot be fully fixed inside this package:

  • Wrapped RTL selection rects — multi-line Arabic selection highlights may misalign (flutter#175983). Avoid textAlign: OLUTextAlign.justify with selectable: true when possible.
  • WidgetSpan in selectable text — baseline correction uses plain TextSpan when selectable: true.
  • Per-glyph tajweedOLUText.tajweed uses a custom painter; not selectable in v1.0.
  • TextField RTL input — display (OLUText) and input (TextField) are separate; see doc/olu_text_field_scope.md.

OLUText mitigates selection issues with selectionHeightStyle: BoxHeightStyle.includeLineSpacingMiddle (default) and forceTextDirection for single-language blocks.

Architecture

All widgets:

  • Read colors and styles from Theme.of(context)
  • Wrap roots in RepaintBoundary for performance
  • Adapt automatically to Directionality.of(context)
  • Support key and semanticLabel for accessibility

Zero external dependencies — only flutter SDK.

Testing

The package includes 80+ widget and unit tests:

flutter test

Contributing

Issues and pull requests are welcome on GitHub.

Before submitting, run:

dart format .
dart analyze
flutter test

License

MIT License. See LICENSE for details.

Libraries

olu
RTL-first Flutter UI package with zero dependencies.