A port of kotlin-stdlib for Dart/Flutter including immutable collections (KtList, KtMap, KtSet) and other packages

Overview

kt.dart

Pub codecov

This project is a port of Kotlin's Kotlin Standard library for Dart/Flutter projects. It's a useful addition to dart:core and includes collections (KtList, KtMap, KtSet) as well as other packages which can improve every Dart/Flutter app.

dependencies: 
  kt_dart: ^0.10.0
import 'package:kt_dart/kt.dart';

Motivation

Dart's dart:core package provides basic building blocks. But sometimes they are too low level and not as straightforward as Kotlin's kotlin-stdlib.

Here are a few examples of what this project offers: (click to expand)

Immutable collections by default

dart:core collections

Dart's List is mutable by default. The immutable List.unmodifiable is the same type, but the mutation methods throw at runtime.

final dartList = [1, 2, 3];
dartList.add(4); // mutation is by default possible
assert(dartList.length == 4);

final immutableDartList = List.unmodifiable(dartList);
immutableDartList.add(5); // throws: Unsupported operation: Cannot add to an unmodifiable list

Dart's mutable List is indistinguishable from an immutable List which might cause errors.

void addDevice(List<Widget> widgets, Device device) {
  // no way to check whether widgets is mutable or not
  // add might or might now throw
  widgets.add(_deviceRow());
  widgets.add(Divider(height: 1.0));
}

kt_dart collections

KtList and KtMutableList are two different Types. KtList is immutable by default and has no mutation methods (such as add). Methods like map((T)->R) or plusElement(T) return a new KtList leaving the old one unmodified.

final ktList = listOf(1, 2, 3);
// The method 'add' isn't defined for the class 'KtList<int>'.
ktList.add(4); // compilation error
       ^^^

// Adding an item returns a new KtList
final mutatedList = ktList.plusElement(4);
assert(ktList.size == 3);
assert(mutatedList.size == 4);

KtMutableList offers mutation methods where the content of that collection can be actually mutated. I.e. with remove(T) or add(T);

// KtMutableList allow mutation
final mutableKtList = mutableListOf(1, 2, 3);
mutableKtList.add(4); // works!
assert(mutableKtList.size == 4);

All collection types have mutable counterparts:

Immutable Mutable
KtList KtMutableList
KtSet KtMutableSet, KtHashSet, KtLinkedSet
KtMap KtMutableMap, KtHashMap, KtLinkedMap
KtCollection KtMutableCollection and all the above
KtIterable KtMutableIterable and all the above
Deep equals

dart:core collections

Dart's List works like a Array in Java. Equals doesn't compare the items; it only checks the identity. To compare the contents you have to use helper methods methods from 'package:collection/collection.dart'.

// Comparing two Dart Lists works only by identity
final a = [1, 2, 3, 4];
final b = [1, 2, 3, 4];
print(a == b); // false, huh?

// Content-based comparisons require unnecessary glue code
Function listEq = const ListEquality().equals;
print(listEq(a, b)); // true

// MapEquality isn't deep by default
final x = {1: ["a", "b", "c"], 2: ["xx", "yy", "zz"]};
final y = {1: ["a", "b", "c"], 2: ["xx", "yy", "zz"]};
Function mapEq = const MapEquality().equals;
print(mapEq(x, y)); // false, wtf?!

Function deepEq = const DeepCollectionEquality().equals;
print(deepEq(x, y)); // true, finally

kt_dart collections

KtList and all other collection types implement equals by deeply comparing all items.

final a = listOf(1, 2, 3, 4);
final b = listOf(1, 2, 3, 4);
print(a == b); // true, as expected

final x = mapFrom({1: listOf("a", "b", "c"), 2: listOf("xx", "yy", "zz")});
final y = mapFrom({1: listOf("a", "b", "c"), 2: listOf("xx", "yy", "zz")});
print(x == y); // deep equals by default
Common methods

Some of Dart's method names feel unfamiliar. That's because modern languages and frameworks (Kotlin, Swift, TypeScript, ReactiveExtensions) kind of agreed on naming methods when it comes to collections. This makes it easy to switch platforms and discuss implementations with coworkers working with a different language.

expand -> flatMap

final dList = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
final kList = listOf(listOf(1, 2, 3), listOf(4, 5, 6), listOf(7, 8, 9));

// dart:core
final dFlat = dList.expand((l) => l).toList();
print(dFlat); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

// kt_dart
final kFlat = kList.flatMap((l) => l);
print(kFlat); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

where -> filter

final dNames = ["Chet", "Tor", "Romain", "Jake", "Dianne"];
final kNames = listFrom(dNames);

// dart:core
final dShortNames = dNames.where((name) => name.length <= 4).toList();
print(dShortNames); // [Chet, Tor, Jake]

// kt_dart
final kShortNames = kNames.filter((name) => name.length <= 4);
print(kShortNames); // [Chet, Tor, Jake]

firstWhere -> first, firstOrNull

final dNames = ["Chet", "Tor", "Romain", "Jake", "Dianne"];
final kNames = listFrom(dNames);

// dart:core
dNames.firstWhere((name) => name.contains("k")); // Jake
dNames.firstWhere((name) => name.contains("x"), orElse: () => null); // null
dNames.firstWhere((name) => name.contains("x"), orElse: () => "Nobody"); // Nobody

// kt_dart
kNames.first((name) => name.contains("k")); // Jake
kNames.firstOrNull((name) => name.contains("x")); // null
kNames.firstOrNull((name) => name.contains("x")) ?? "Nobody"; // Nobody

KtList

KtList is a read-only list of elements. It is immutable because it doesn't offer mutation methods such as remove or add. Use KtMutableMap if you want to use a mutable list.

To create a KtList/KtMutableList use the KtList.of constructor or convert an existing Dart List to a KtList with the list.toImmutableList() extension.

Create a KtList

// Create a KtList from scratch
final beatles = KtList.of("John", "Paul", "George", "Ringo");

// Convert a existing List to KtList
final abba = ["Agnetha", "Björn", "Benny", "Anni-Frid"];
final immutableAbba = abba.toImmutableList();

Create a KtMutableList

KtList is immutable by default, which means it doesn't offer methods like add or remove. To create mutable list with kt_dart use the KtMutableList constructor.

// Create a KtMutableList from scratch
final beatles = KtMutableList.of("John", "Paul", "George", "Ringo");
beatles.removeAt(0);
print(beatles); // [Paul, George, Ringo]

Mutable/Immutable conversion

Conversions between KtList and KtMutableList can be done with KtList.toMutableList() and KtMutableList.toList();

final beatles = KtList.of("John", "Paul", "George", "Ringo");
final mutable = beatles.toMutableList();
mutable.removeAt(0);
print(mutable); // [Paul, George, Ringo]
print(beatles); // [John, Paul, George, Ringo]

for loop

kt_dart collections do not implement Iterable. It is therefore not possible to directly iterate over the entries of a KtList.

All kt_dart collections offer a .iter property which exposes a Dart Iterable. For-loops therefore don't look much different.

final beatles = KtList.of("John", "Paul", "George", "Ringo");
for (final member in beatles.iter) {
  print(member);
}

Yes, alternatively you could use .asList() instead which returns a Dart List.

Kotlin syntax

Kotlin users might be more familiar with the listOf() and mutableListOf() functions. Use them if you like but keep in mind that the dart community is much more used to use constructors instead of top-level functions.

final beatles = listOf("John", "Paul", "George", "Ringo");
final abba = mutableListOf("Agnetha", "Björn", "Benny", "Anni-Frid");

KtSet

A KtSet is a unordered collection of elements without duplicates.

Creating a KtSet/KtMutableSet is very similar to the KtList API.

// Create a KtSet from scratch
final beatles = KtSet.of("John", "Paul", "George", "Ringo");

// Convert a existing Set to KtSet
final abba = {"Agnetha", "Björn", "Benny", "Anni-Frid"};
final immutableAbba = abba.toImmutableSet();

KtMap

To create a KtMap/KtMutableMap start with Dart Map and then convert it to a KtMap with either:

  • pokemon.toImmutableMap(): KtMap (since Dart 2.7)
  • KtMap.from(pokemon): KtMap
  • pokemon.kt: KtMutableMap (since Dart 2.7)
  • KtMutableMap.from(pokemon): KtMutableMap
// immutable
final pokemon = {
  1: "Bulbasaur",
  2: "Ivysaur",
  3: "Stegosaur",
}.toImmutableMap();

final newPokemon = KtMap.from({
  152: "Chikorita",
  153: "Bayleef",
  154: "Meganium",
});

// mutable
final mutablePokemon = {
  1: "Bulbasaur",
  2: "Ivysaur",
  3: "Stegosaur",
}.kt;

final newMutablePokemon = KtMutableMap.from({
  152: "Chikorita",
  153: "Bayleef",
  154: "Meganium",
});

KtHashMap and KtLinkedMap

You may want to use a specific Map implementation. kt_dart offers:

  • KtLinkedMap - based on Darts LinkedHashMap where the insertion order of keys is remembered and keys are iterated in the order they were inserted into the map
  • KtHashMap - based on Darts HashMap where keys of a HashMap must have consistent [Object.==] and [Object.hashCode] implementations. Iterating the map's keys, values or entries (through [forEach]) may happen in any order.

KtPair, KtTriple

kt_dart offer two types of tuples, KtPair with two elements and KtTriple with three elements. They are used by some collection APIs and prevent a 3rd party dependency.

final beatles = KtList.of("John", "Paul", "George", "Ringo");
final partitions = beatles.partition((it) => it.contains("n"));
print(partitions.first); // [John, Ringo]
print(partitions.second); // [Paul, George]

There won't be a KtQuadruple or TupleN in this library. If you want to use tuples heavily in you application consider using the tuple package. Better, use freezed to generated data classes which makes for a much better API.

Annotations

@nullable

Kotlin already has Non-Nullable types, something which is coming to Dart soon™. kt_dart already makes use of Non-Nullable Types and never returns null unless a method is annotated with @nullable.

/// Returns the value corresponding to the given [key], or `null` if such a key is not present in the map.
@nullable
V get(K key);

There isn't any tooling which will warn you about the wrong usage but at least it's documented. And once nnbd lands in Dart it will be fairly easy to convert.

@nonNull

This annotation annotates methods which never return null. Although this is the default in kt_dart, is makes it very obvious for methods which sometimes return null in other languages.

@experimental

A method/class annotated with @experimental marks the method/class as experimental feature. Experimental APIs can be changed or removed at any time.

License

Copyright 2019 Pascal Welsch

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • groupByTransform(_).getOrDefault(_, KtList.empty()) crashes always

    groupByTransform(_).getOrDefault(_, KtList.empty()) crashes always

    As groupByTransform directly casts KtMutableMap,KtMutableList to KtMap,KtList. when getOrDefault(key, KtList.empty()) is used on returned map from groupByTransform. It crashes with error type 'EmptyList<Currency>' is not a subtype of type 'KtMutableList<Currency>' of 'defaultValue'

    Reproducible code

    main() {
      var usd = Currency(1, "USD");
      var inr = Currency(2, "INR");
      KtList<Currency> currency = listOf(usd, inr);
      KtList<CurrencyConversionData> conversion =
          listOf(CurrencyConversionData(1, 2));
      KtMap<Currency, KtList<Currency>> conversions =
          _toCurrencyMap(conversion, currency);
    
      print(conversions.getOrDefault(Currency(1, "USD"), KtList.empty())); // CRASH HERE (type 'EmptyList<Currency>' is not a subtype of type 'KtMutableList<Currency>' of 'defaultValue')
    }
    
    KtMap<Currency, KtList<Currency>> _toCurrencyMap(
        KtList<CurrencyConversionData> conversion, KtList<Currency> currency) {
      KtMap<int, Currency> currencyMap = currency.associateBy((cur) => cur.id);
      return conversion.groupByTransform(
        (conv) => currencyMap.get(conv.fromRef)!,
        (conv) => currencyMap.get(conv.toRef)!,
      );
    }
    
    class Currency {
      final int id;
      final String ticker;
    
      Currency(this.id, this.ticker);
    }
    
    class CurrencyConversionData {
      final int fromRef;
      final int toRef;
    
      CurrencyConversionData(this.fromRef, this.toRef);
    }
    
    
    opened by Ashok-Varma 7
  • KtMap.map(MapEntry<K, V> -> R) : KtList<R>

    KtMap.map(MapEntry -> R) : KtList

    Kotlin allows mapping of entries in a map using .map

    mapOf(1 to "foo", 2 to "bar")
            .map { "${it.key} -> ${it.value}" }
            .forEach(::print)
    // 1 -> foo
    // 2 -> bar
    

    This leads to a name clash with KtMap.map which returns the Dart Map.

    Currently all kt.dart collections allow access to the dart equivalents.

    KtIterable.iter -> Iterable
    KtList.list -> List
    KtMap.map -> Map
    KtSet.set -> Set
    

    We have to find a way to provide standardized ways to access the dart equivalents. Additionally we should make it as easy as possible to make kt.dart collections useable using for loops.

    // kt.dart 0.5.0
    for(final i in listOf(1, 2, 3).iter) {
      print(i);
    }
    
    opened by passsy 7
  • Migration to Extensions (Dart 2.6)

    Migration to Extensions (Dart 2.6)

    Dart 2.6 introduces extension methods. The aim of this project was always to provide tons of extensions.

    This PR enables migrates the old extension mixins to real extensions. Nothing else. No further APIs or internal extension usage

    opened by passsy 6
  • Shuffle

    Shuffle

    I develop an app that involves massive working with lists. One of the popular features that I use is list shuffling.

    As I see there is no such a method in this library yet. It is very frustrating to switch to standard dart collections to just shuffle and then go back to kt.dart which is awesome btw.

    Do you have plans to implement this functionality?

    collection PR welcome 
    opened by votruk 5
  • Question about KtList

    Question about KtList

    In the docs there's this:

    kt_dart collections do not implement Iterable. It is therefore not possible to directly iterate over the entries of a KtList.

    But there package also exposes a iterator via .iter property as shown in the example. So here comes my question, is there a reason for kt.dart not to implement Iteratable?

    opened by Ascenio 4
  • Add @useResult to everything that returns a KtList

    Add @useResult to everything that returns a KtList

    This PR adds @useResult to every method with the docs Returns a list.

    Maybe this is a little too much, but could help users.

    Closes https://github.com/passsy/kt.dart/issues/193

    opened by nohli 2
  • Introduce minOf() on KtIterable

    Introduce minOf() on KtIterable

    Closes #157 by adding minOf() method on KtIterable.

    Kotlin does not allow to omit the selector function (see example)

    If wanted other functions could be checked too to let it be omitted if possible.

    opened by robiness 2
  • Use dart 2.14 to reformat

    Use dart 2.14 to reformat

    This tries to fix a format issue i ran into with #145 and of future PRs with the analysis workflow failing because of different cascade formatting when using dart 2.12.

    I am also wondering, if this empty line on eof is okay or why it is missing 🤔.

    opened by robiness 2
  • filterNotNull() doesn't change type to non nullable list

    filterNotNull() doesn't change type to non nullable list

    I have the following scenario.

    Actual: I get a KtList<T?> objects I run the following code final KtList<T> nonNullObjects = objects.filterNotNull();

    The dart type check still requires me to use a nullable T? type instead of a non-nullable one

    Expect: filterNotNull() also changes the returned type to T and doesn't require me to continue working with T?

    opened by luckyhandler 2
  • Performance Improvement to KtSet.contains

    Performance Improvement to KtSet.contains

    Hello there from a related project called Fast Immutable Collections (FIC). In it, we created a benchmark_app to compare our collections to the main ones and other notable packages — currently kt.dart and built_collection. The project is not finished yet and neither is the benchmark app itself, so please don't take what you find there as our final say.

    Anyway, we stumbled upon a peculiar result when running contains benchmarks for sets. All of the collections were giving similar results with the exception of KtDart's:

    WithIteratorMixin

    After a little bit of digging I found out that KtDart uses IterableMixin inside its UnmodifiableSetView. This lets the view implement the Set interface with way less work. However, it uses Iterable implementations of methods and not necessarily what you would like specifically for Sets. A contains for a Set and a contains for an Iterable would have require different implementations optimizations. For example, the contains for IterableMixin has an internal loop which slows down UnmodifiableSetView:

    bool contains(Object? element) {
      for (E e in this) {
        if (e == element) return true;
      }
      return false;
    }
    

    In the end, fixing this is apparently not that difficult. What I did was simply override contains to use the _set's contains instead:

    @override
    bool contains(Object? element) => _set.contains(element);
    

    This is the result after adding that bit of code:

    PatchedContains

    That said, I think it would be even easier and less code to use SetMixin instead, which is also what we ended up using in FIC. But I don't know the other requirements of the project, so I'll leave it for others to fill in the gaps.

    opened by psygo 2
  • The signature of mapNotNull is wrong.

    The signature of mapNotNull is wrong.

    Problem

    https://github.com/passsy/kt.dart/blob/80402d45f738fd88fcb4b07d5e9740a9f79add92/lib/src/collection/kt_iterable.dart#L1574 https://github.com/passsy/kt.dart/blob/80402d45f738fd88fcb4b07d5e9740a9f79add92/lib/src/collection/kt_iterable.dart#L1646-L1667

    This causes a build error with the following code:

          listOf("not null").mapNotNull((it) => it.startsWith("not") ? it : null); // error!!
          listOf("not null", null).mapNotNull((it) => it?.startsWith("not") == true ? it : null);
    

    The following code in Kotlin did not cause a build error .

            listOf("not null").mapNotNull { if (it.startsWith("not")) it else null }
            listOf("not null", null).mapNotNull { if (it?.startsWith("not") == true) it else null }
    

    It looks like the signature of RequireNoNullsKtIterableExtension.mapNotNull is wrong.

    Suggestion

    Quoting the implementation of mapNotNull from kotlin.collections:

    /**
     * Returns a list containing only the non-null results of applying the given [transform] function
     * to each element in the original collection.
     * 
     * @sample samples.collections.Collections.Transformations.mapNotNull
     */
    public inline fun <T, R : Any> Iterable<T>.mapNotNull(transform: (T) -> R?): List<R> {
        return mapNotNullTo(ArrayList<R>(), transform)
    }
    
    /**
     * Applies the given [transform] function to each element in the original collection
     * and appends only the non-null results to the given [destination].
     */
    public inline fun <T, R : Any, C : MutableCollection<in R>> Iterable<T>.mapNotNullTo(destination: C, transform: (T) -> R?): C {
        forEach { element -> transform(element)?.let { destination.add(it) } }
        return destination
    }
    

    The following code seems fine.

    extension _<T> on KtIterable<T> {
      /// Returns a list containing the results of applying the given [transform] function
      /// to each element in the original collection.
      KtList<R> mapNotNull2<R>(R? Function(T) transform) {
        final mapped = mapNotNullTo(mutableListOf<R>(), transform);
        // TODO ping dort-lang/sdk team to check type bug
        // When in single line: type "DartMutableList<String>' is not a subtype of type 'Null"
        return mapped;
      }
    
      /// Applies the given [transform] function to each element in the original collection
      /// and appends only the non-null results to the given [destination].
      C mapNotNullTo<R, C extends KtMutableCollection<R>>(C destination, R? Function(T) transform) {
        for (final item in iter) {
          final result = transform(item);
          if (result != null) {
            destination.add(result);
          }
        }
        return destination;
      }
    }
    

    Note that the code above is an extension of KtIterable<T>.

    I thought mapNotNull should be defined in extension KtIterableExtensions<T> on KtIterable<T> or extension ChainableKtIterableExtensions<T> on KtIterable<T>.

    Version

    This problem happened when I upgraded from 0.9.1 to 1.0.0.

       kt_dart: ^0.9.1 -> ^1.0.0
    
    opened by HideakiSago 0
  • Subtracting lists of different types

    Subtracting lists of different types

    Shouldn't all of these work?

    class A {}
    
    class B implements A {}
    
    // Works fine...
    listOf<A>(A()).minus(listOf<A>(B()));
    
    // _TypeError (type 'A' is not a subtype of type 'B' of 'element')
    listOf<A>(A()).minus(listOf<B>(B()));
    
    // Not sure why but this one will throw as well.
    listOf<A>(A()).minus(listOf<B>(B()).cast<A>());
    
    // This one works, though.
    // ignore: unnecessary_cast
    listOf<A>(A()).minus(listOf<B>(B()).map((element) => element as A));
    

    Relevant stack trace:

    DartList.contains (...\kt_dart-1.0.0\lib\src\collection\impl\list.dart:0)
    KtIterableExtensions.contains (...\kt_dart-1.0.0\lib\src\collection\kt_iterable.dart:336)
    KtIterableExtensions.minus.<anonymous closure> (...\kt_dart-1.0.0\lib\src\collection\kt_iterable.dart:1031)
    KtIterableExtensions.filterNotTo (...\kt_dart-1.0.0\lib\src\collection\kt_iterable.dart:536)
    KtIterableExtensions.filterNot (...\kt_dart-1.0.0\lib\src\collection\kt_iterable.dart:511)
    KtIterableExtensions.minus (...\kt_dart-1.0.0\lib\src\collection\kt_iterable.dart:1031)
    

    The reason why I'm asking is actually Dart's type inference. Depending on how the type is inferred, seemingly similar code might or might not work.

    Type inferred from the minus() signature - works fine:

    listOf(A()).minus(listOf(B()));
    

    Type inferred from the listOf() signature - won't work:

    final listOfA = listOf(A());
    final listOfB = listOf(B());
    listOfA.minus(listOfB);
    

    I tried to find what exactly is going on but honestly, I'm lost :). I can write a test if needed, though. I'm on Dart 2.18.2.

    opened by angel333 0
  • KtList (and others) has no const factories

    KtList (and others) has no const factories

    KtList (and others) has no const factories with const initializers. For example, KtList.of(1, 2, 3). And therefore no available pass constructed list with const to const constructors:

    class State {
        final KtList<int> keys;
        const State(this.keys);
    }
    ...
    
    final state = const State(KtList.of(1, 2, 3, 4)); //no compile
    
    
    opened by myvaheed 0
  • KMutableIterator.remove() doesn't remove item from collection

    KMutableIterator.remove() doesn't remove item from collection

    var abc = mutableListOf(["a", "b", "c"]);
    final KMutableIterator<String> i = abc.iterator();
    assert(i.next() == "a");
    i.remove();
    assert(abc[0] == "b"); // Failed assertion: 'abc[0] == "b"': is not true.
    

    abc[0] is still "a" because remove doesn't remove the item from the actual collection. Instead, it gets removed from the internal copy inside the iterator.

    To fix this problem a big refactoring is required so that remove actually removed the item from the original collection.

    This is how kotlin solves this

    bug collection 
    opened by passsy 2
Releases(v1.0.0)
  • v1.0.0(Sep 27, 2022)

    • #183 New: KtIterable.sumOf thx @nohli
    • Update dependencies and guarantee compatibility with Dart 2.12-2.18

    Full Changelog: https://github.com/passsy/kt.dart/compare/v0.10.0...v1.0.0

    Source code(tar.gz)
    Source code(zip)
  • v0.10.0(Oct 31, 2021)

    Some nullsafety improvements, type fixes and a lot of new Kotlin 1.4 extensions

    • #141 Fix: requireNoNulls() now converts T? to T

    • 1df6e1a Fix: .dart and .iter on Iterable<T> now work for all types not only if T implements Comparable

    • f43cbc5 Fix: *NotNull methods now return non-nullable types

    • b727893 Fix: The hashcode of all collections doesn't get cached anymore. That caused problems when mutable items in a KtList changed. The equals and hashCode methods now always change together.

    • #141 Improve: KtIterable.onEach can now be chained

    • #141 New: KtIterable.cast() to manually cast values

    • #141 New: KtIterable.onEachIndexed

    • #163 New: KtIterable.shuffled()

    • #166 New: KtIterable.reduceOrNull()

    • #169 New: KtMutableList.removeFirst() KtMutableList.removeLast()

    • #173 New: KtMutableList.removeFirstOrNull() KtMutableList.removeLastOrNull()

    • #171 New: KtIterable.minOf()

    • #165 New: String.replaceFirstChar()

    • #170 New: KtIterable.minOrNull(), KtIterable.maxOrNull(), deprecates KtIterable.min(), KtIterable.max(),

    • #174 New: KtIterable.runningReduce()

    • #177 New: KtCollection.randomOrNull()

    • #178 New: KtIterable.flatMapIndexed, KtIterable.flatMapIndexedTo

    Thanks to the #hacktoberfest contributors @Anas35, @robiness, @MatthaiosSait, @Dev-dfm, @marciokuroki, @Rishabh-Negi

    Source code(tar.gz)
    Source code(zip)
  • v0.9.1(May 22, 2021)

    • #138 Deprecate KtIterable<T>.sumByDouble in favor of KtIterable<T>.sumBy which now works for int and double
    • #140 KtMap.getOrDefault now returns V instead of V?
    • #140 Fix KtMap.groupBy returning KtMap<K, KtMutableList<T>> instead of KtMap<K, KtList<T>> causing generic type problems in further processing
    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Mar 14, 2021)

  • 0.9.0-nullsafety.0(Mar 14, 2021)

  • v0.8.0(Oct 1, 2020)

    New package:kt_dart/standard.dart library containing Kotlins loved standard extensions

    • #120 Standard extensions let, also, takeIf and takeUnless
    • #120 TODO([String message]) top-level function which throws NotImplementedException
    • #120 repeat(int times, void Function(int) action) top-level function

    More cool updates

    • #124 KtList.of and KtSet.of now allow null as parameters. Same for listOf and setOf
    • #131 Chain Comparators with the new thenBy and thenByDescending functions.
    • #126 Allow const .empty() constructors for KtList, KtMap and KtSet (Thanks @TimWhiting)
    • #127 plus, minus operator overrides for KtSet, returning KtSet and not KtList as the KtIterable operators do
    Source code(tar.gz)
    Source code(zip)
  • v0.8.0-dev.1(Apr 27, 2020)

    • #124 KtList.of and KtSet.of now allow null as parameters. Same for listOf and setOf
    • #120 Standard extensions let, also, takeIf and takeUnless
    • #120 TODO([String message]) top-level function which throws NotImplementedException
    • #120 repeat(int times, void Function(int) action) top-level function
    • #126 Allow const .empty() constructors for KtList, KtMap and KtSet (Thanks @TimWhiting)
    • #127 plus, minus operator overrides for KtSet, returning KtSet and not KtList as the KtIterable operators do
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(Mar 1, 2020)

    The library has be upgrade to use Static Extension Methods.

    Interop

    This update also includes extensions for Dart collections which allow easy interoperability between dart and kt.dart collections using the .kt and .dart getters.

      // New: Converting dart collections to KtDart collections (mutable views)
      final KtMutableList<String> ktList = ["hey"].kt;
      final KtMutableSet<String> ktSet = {"hey"}.kt;
      final KtMutableMap<String, int> ktMap = {"hey": 1}.kt;
    
      // Converting KtDart collections to dart collections
      final List<String> dartList = KtList.of("hey").dart;
      final Set<String> dartSet = KtSet.of("hey").dart;
      final Map<String, int> dartMap = KtMap.from({"hey": 1}).dart;
    

    Note: ["Hello", "World"].kt returns a KtMutableList<String> and mutations are reflected on the original dart list. It is not a copy! Because it doesn't copy it is very cheap and only syntax sugar.

    To convert dart collections to their immutable kt.dart counterparts use: .toImmutableList(), .toImmutableSet(), .toImmutableMap()

      // New: Make dart collections immutable
      final KtList<String> list = ["hey"].toImmutableList();
      final KtSet<String> set = {"hey"}.toImmutableSet();
      final KtMap<String, int> map = {"hey": 1}.toImmutableMap();
    

    Possible breaking changes

    • Relax sortBy/sortByDescending, maxBy/minBy typing to work better with ints and doubles #116
    // Was: int doesn't not implement Comparable<int> but Comparable<num>
    // minBy therefore required some help to figure out the correct type (<num>) 
    users.minBy<num>((it) => it.age);
    
    // Now: minBy doesn't require the Comparable (num) to have the same same as the value (int).
    users.minBy((it) => it.age);
    
    • Remove unnecessary generic R from KtIterable.zipWithNext #118

    New Extensions

    • KtPair and KtTriple now have a new toList() function to convert the values to a KtList
    • KtList?.orEmpty() returns an empty list when the list is null
    • KtSet?.orEmpty() returns an empty set when the set is null
    • KtMap?.orEmpty() returns an empty map when the map is null
    • KtMap.ifEmpty(() -> defaultValue) returns the default value when the map is empty
    • KtIterable<KtIterable<T>>.flatten() flattens the nested collections to KtIterable<T>
    • KtIterable<KtPair<T, U>>.unzip(): KtPair<KtList<T>, KtList<U>> unzips list of pairs to list of their first and second values
    • KtIterable<Comparable<T>>.min() returns the smallest element of any comparable iterable
    • KtIterable<Comparable<T>>.max() returns the largest element of any comparable iterable
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0-dev.4(Dec 29, 2019)

    • New extension Iterable.toImmutableList(): KtList
    • New extension Iterable.toImmutableSet(): KtSet
    • New extension KtIterable<num>.average(): double
    • Relax sortBy/sortByDescending, maxBy/minBy typing to work better with ints and doubles
    // Was: int doesn't not implement Comparable<int> but Comparable<num>
    // minBy therefore required some help to figure out the correct type (<num>) 
    users.minBy<num>((it) => it.age);
    
    // Now: minBy doesn't require the Comparable (num) to have the same same as the value (int).
    users.minBy((it) => it.age);
    
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0-dev.3(Dec 22, 2019)

    • Rename (List|Set|Map).immutable() extension to .toImmutableList() to match Dart SDK naming schema.
    • Remove int.rangeTo(X) extension. Please use the dartx as replacement which offers the same extension
    • Remove T.to(X) extension to create a KtPair. It's too general and should be offered by the dart SDK not a 3rd party package
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0-dev.2(Oct 21, 2019)

    New .dart extensions to convert KtDart collections back to dart collections.

      // New: Converting dart collections to KtDart collections (mutable views)
      final KtMutableList<String> ktList = ["hey"].kt;
      final KtMutableSet<String> ktSet = {"hey"}.kt;
      final KtMutableMap<String, int> ktMap = {"hey": 1}.kt;
    
      // Converting KtDart collections to dart collections
      final List<String> dartList = KtList.of("hey").dart;
      final Set<String> dartSet = KtSet.of("hey").dart;
      final Map<String, int> dartMap = KtMap.from({"hey": 1}).dart;
    

    Update

    dependencies:
      kt_dart: ^0.7.0-dev.2
    
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0-dev.1(Oct 21, 2019)

    KtDart makes full use of darts static extension methods, introduced with Dart 2.6.

    The public API stays unchanged and is backwards compatible.

    Improved interopt with dart collections

    It is now easier then ever to convert dart to ktdart collections and vice versa. Use the .kt property to convert dart collections to KtDart collections. (Note: .kt create a view, which allows you to mutate the original dart collection).

      // New: Make dart collections immutable
      final KtList<String> list = ["hey"].immutable();
      final KtSet<String> set = {"hey"}.immutable();
      final KtMap<String, int> map = {"hey": 1}.immutable();
    
      // New: Converting dart collections to KtDart collections (mutable views)
      final KtMutableList<String> ktList = ["hey"].kt;
      final KtMutableSet<String> ktSet = {"hey"}.kt;
      final KtMutableMap<String, int> ktMap = {"hey": 1}.kt;
    
      // Converting KtDart collections to dart collections
      final List<String> dartList = KtList.of("hey").asList();
      final Set<String> dartSet = KtSet.of("hey").asSet();
      final Map<String, int> dartMap = KtMap.from({"hey": 1}).asMap();
    

    Tuple improvements

    KtPairs can now created with the T0.to(T1) extension.

    final KtPair<String, int> pair = "foo".to(42);
    

    Also, KtPair and KtTriple now have a new toList() function to convert the values to a KtList.

    New Extensions

    • KtList?.orEmpty() returns an empty list when the list is null
    • KtSet?.orEmpty() returns an empty set when the set is null
    • KtMap?.orEmpty() returns an empty map when the map is null
    • KtMap.ifEmpty(() -> defaultValue) returns the default value when the map is empty
    • KtIterable<KtIterable<T>>.flatten() flattens the nested collections to KtIterable<T>
    • KtIterable<KtPair<T, U>>.unzip(): KtPair<KtList<T>, KtList<U>> unzips list of pairs to list of their first and second values
    • KtIterable<Comparable<T>>.min() returns the smallest element of any comparable iterable
    • KtIterable<Comparable<T>>.max() returns the largest element of any comparable iterable

    Upgrade

    dependencies:
      kt_dart: ^0.7.0-dev.1
    
    Source code(tar.gz)
    Source code(zip)
  • v0.6.2(Apr 24, 2019)

  • v0.6.1(Mar 27, 2019)

  • v0.6.0(Mar 27, 2019)

    diff v0.5.0...v0.6.0

    This major update of kt.dart adds 16+ extension methods to KtMap and makes working with maps even easier.

    Behavior Changes

    The properties KtList.list: List,KtSet.set: Set are now deprecated and KtMap.map: Map was removed. Those properties where used to convert kt.dart collections to dart collections. Instead use the new KtList.asList(): List, KtSet.asSet(): Set, KtMa.asMap(): Map methods. The old properties returned copies of the collections. The new as-methods return views of the original collections and reflect changes of the original data.

    This breaking change was necessary because the property KtMap.map: Map<K, V> was conflicting with KtMap.map(MapEntry<K, V> -> R) : KtList<R> to map the entries to items of a KtList. Read about further details here.

    If you have used properties to iterate over the collections using a for-loop you should now always use iter which is available for all kt.dart collections.

    for (final element in listOf("a", "b", "c").iter) {
      print(element); 
    }
    for (final element in setOf("a", "b", "c").iter) {
      print(element); 
    }
    for (final p in mapFrom({1: "Bulbasaur", 2: "Ivysaur"}).iter) {
      print("${p.key} -> ${p.value}"); 
    }
    

    Additions

    • #86 New: KtMap.map Returns a list containing the results of applying the given transform function to each entry in the original map.
    • #86 New: KtMap.iter Access to a Iterable to be used in for-loops
    • #87 New: KtMap.count Returns the number of entries matching the given [predicate] or the number of entries when predicate = null.
    • #89 New: KtMap.minBy Returns the first entry yielding the smallest value of the given function or null if there are no entries.
    • #89 New: KtMap.minWith Returns the first entry having the smallest value according to the provided comparator or null if there are no entries.
    • #89 New: KtMap.maxBy Returns the first entry yielding the largest value of the given function or null if there are no entries.
    • #89 New: KtMap.maxWith Returns the first entry having the largest value according to the provided comparator or null if there are no entries.
    • #90 New: KtMap.toList Returns a KtList containing all key-value pairs.
    • #78 New: KtMap.forEach Performs given action on each key/value pair from this map. thanks @acherkashyn
    • #80 New: KtMap.none Returns true if there is no entries in the map that match the given predicate. thanks @acherkashyn
    • #80 New: KtMap.all Returns true if all entries match the given predicate. thanks @acherkashyn
    • #80 New: KtMap.any Returns true if there is at least one entry that matches the given predicate. thanks @acherkashyn
    • #84 New: KtMap.filterKeys Returns a map containing all key-value pairs with keys matching the given predicate.
    • #84 New: KtMap.filterValues Returns a map containing all key-value pairs with values matching the given predicate.
    • #79 New: KtMap.asMap Returns a read-only dart:core Map
    • #79 New: KtMutableMap.asMap Creates a Map instance that wraps the original KtMap. It acts as a view.

    • #75 New: KtIterable.takeWhile Returns a list containing first elements satisfying the given predicate.
    • #76 New: KtIterable.takeLastWhile Returns a list containing last elements satisfying the given predicate.

    • #73 New: KtList.takeLast, Returns a list containing last n elements.
    • #79 New: KtList.asList Returns a read-only dart:core List
    • #79 New: KtMutableList.asList Creates a List instance that wraps the original KtList. It acts as a view.

    • #79, #91 New: KtSet.asSet Returns a read-only dart:core Set
    • #79 New: KtMutableSet.asSet Creates a Set instance that wraps the original KtSet. It acts as a view.

    Bugfixes

    • #74 Fix: KtList.dropLastWhile was off by 1
    • #88 Fix: KtIterable.minWith returned the max value

    Documentation

    • #68 Document KtSet constructors
    • #70 Fix README typos, thanks @RedBrogdon

    Misc.

    • #69 KtMutableListIterator throws IndexOutOfBoundsException when calling set before next was called
    • #81 Force dartfmt on CI
    • #83 Improve .gitignore

    Upgrade Instructions

    dependencies:
      kt_dart: ^0.6.0
    
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Jan 11, 2019)

    diff v0.4.2...v0.5.0

    This project has been renamed to kt.dart. If you're using a previous version upgrade like this:

    pubspec.yaml

    dependencies:
    -  dart_kollection: ^0.3.0
    -  kotlin_dart: ^0.4.0
    +  kt_dart: ^0.5.0
    

    your_source.dart

    - import 'package:dart_kollection/dart_kollection.dart';
    - import 'package:kotlin_dart/kotlin.dart';
    + import 'package:kt_dart/kt.dart';
    
    • #66 Rename KPair -> KtPair and KTriple -> KtTriple
    • #67 Rename package kotlin_dart -> kt_dart
    Source code(tar.gz)
    Source code(zip)
  • v0.4.3(Jan 11, 2019)

  • v0.3.2(Jan 11, 2019)

  • v0.4.2(Jan 9, 2019)

  • v0.4.1(Jan 9, 2019)

  • v0.4.0(Jan 9, 2019)

    diff v0.3.0...v0.4.0

    The kollection project was migrated to kotlin.dart where kollection becomes the collection module.

    Upgrade

    pubspec.yaml

    dependencies:
    -  dart_kollection: ^0.3.0
    +  kotlin_dart: ^0.4.0
    

    your_source.dart

    - import 'package:dart_kollection/dart_kollection.dart';
    + import 'package:kotlin_dart/kotlin.dart';
    

    Breaking Changes

    • #64 The class prefix of all collections has been changed from K to Kt (KList -> KtList)
    • #60 listOf now accepts up to 10 non-null arguments instead of an Iterable. Use listFrom to create KtLists from an dart Iterables
    • #60 Collections can now be created with factory constructors i.e. KtList.of(1, 2 ,3). Both APIs, factory constructor and function based one, are equally supported. It only depends on your personal taste.

    Here is a list of all collection creation APIs.

    Kotlin like, function based syntax

      /// List
      // Create immutable lists
      emptyList<int>();
      listOf(1, 2, 3, 4, 5);
      listFrom([1, 2, 3, 4, 5]);
      // Create mutable lists
      mutableListOf(1, 2, 3, 4, 5);
      mutableListFrom([1, 2, 3, 4, 5]);
      
      /// Set
      // Create immutable sets
      emptySet<int>();
      setOf(1, 2, 3, 4, 5);
      setFrom([1, 2, 3, 4, 5]);
      // Create a mutable set which keeps the order of the items
      linkedSetOf(1, 2, 3, 4, 5);
      linkedSetFrom([1, 2, 3, 4, 5]);
      // Create mutable, unordered hash-table based set
      hashSetOf(1, 2, 3, 4, 5);
      hashSetFrom([1, 2, 3, 4, 5]);
      
      /// Map
      // Create immutable maps
      emptyMap<int, String>();
      mapFrom({1: "a", 2: "b"});
      // Create mutable maps
      mutableMapFrom({1: "a", 2: "b"});
      // Create mutable maps without specified order when iterating over items
      hashMapFrom({1: "a", 2: "b"});
      // Create mutable maps which keep the order of the items
      linkedMapFrom({1: "a", 2: "b"});
    

    Dart like, constructor based syntax

      /// List
      // Create immutable lists
      KList<int>.empty();
      KList.of(1, 2, 3, 4, 5);
      KList.from([1, 2, 3, 4, 5]);
      // Create mutable lists
      KMutableList<int>.empty();
      KMutableList.of(1, 2, 3, 4, 5);
      KMutableList.from([1, 2, 3, 4, 5]);
      
      /// Set
      // Create immutable sets
      KSet<int>.empty();
      KSet.of(1, 2, 3, 4, 5);
      KSet.from([1, 2, 3, 4, 5]);
      // Create a mutable set which keeps the order of the items
      KMutableSet<int>.empty();
      KMutableSet.of(1, 2, 3, 4, 5);
      KMutableSet.from([1, 2, 3, 4, 5]);
      // Create mutable, unordered hash-table based set
      KHashSet<int>.empty();
      KHashSet.of(1, 2, 3, 4, 5);
      KHashSet.from([1, 2, 3, 4, 5]);
      // Create a mutable set which keeps the order of the items
      KLinkedSet<int>.empty();
      KLinkedSet.of(1, 2, 3, 4, 5);
      KLinkedSet.from([1, 2, 3, 4, 5]);
      
      /// Map
      // Create mutable maps
      KMutableMap<int, String>.empty();
      KMutableMap.from({1: "a", 2: "b"});
      // Create mutable maps without specified order when iterating over items
      KHashMap<int, String>.empty();
      KHashMap.from({1: "a", 2: "b"});
      // Create mutable maps which keep the order of the items
      KLinkedMap<int, String>.empty();
      KLinkedMap.from({1: "a", 2: "b"});
    
    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Jan 9, 2019)

  • v0.3.0(Jan 3, 2019)

    diff v0.2.0...v0.3.0

    Summary

    This release of Kollection fully covers the project with unit tests, from 52% to 99% :tada:. By doing that bugs where discovered and fixed.

    Because Dart doesn't support non-nullable types yet, this update manually checks all method arguments at runtime. Passing null in any method will throw ArgumentError unless documented otherwise.

    Behavior changes

    • #36 All method arguments are now validated for nullability. If a argument isn't documented as "nullable" the method will throw ArgumentError (when asserts are enabled)
    • #51, #46 KIterable<T>.associateWithTo, Kiterable<T>.filterTo, KIterable<T>.filterIndexedTo, KIterable<T>.filterNotTo, KIterable<T>.filterNotNullTo , KIterable<T>.groupByTo ,KMap<T>.mapKeysTo ,KMap<T>.mapValuesTo, KIterable.toCollection did not compile when called directly due to dart-lang/sdk/issues/35518. The type of destination of those methods has been changed to a dynamic type (i.e. KMutableList<T> -> KMutableList<dynamic>). Those methods will now be checked at runtime. This has one advantage: It allows to pass in contravariant types.
    final KIterable<int> iterable = listOf([4, 25, -12, 10]);
    final result = mutableListOf<num>(); // covariant!
    final filtered = iterable.filterIndexedTo(result, (i, it) => it < 10);
    expect(identical(result, filtered), isTrue);
    expect(result, listOf([4, -12]));
    
    • #56 KMutableEntry.setValue now throws UnimplementedError because of bug #55. It anyways never worked.
    • #58 KSet doesn't allow mutation of its elements with via set getter. It is now really immutable.

    API changes

    Bug fixes

    Documentation changes

    • #57 Document hashSetOf and linkedSetOf
    • #19 KIterable.any document return value when called without predicate
    • #51 Document expected type of now dynamically typed KIterable<T>.associateWithTo, Kiterable<T>.filterTo, KIterable<T>.filterIndexedTo, KIterable<T>.filterNotTo, KIterable<T>.filterNotNullTo , KIterable<T>.groupByTo ,KMap<T>.mapKeysTo ,KMap<T>.mapValuesTo, KIterable.toCollection

    Other changes

    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Dec 3, 2018)

    Changelog

    diff v0.1.0...v0.2.0

    Behavior change

    • #6 Breaking: KMutableIterator.remove now throws UnimplementedError because of bug #5

    API changes

    • #1 Add Set<T> get set returning the internal dart set
    • #1 Add Map<K, V> get map returning the intenral dart set
    • #7 Add KMap.toMap and KMap.toMutableMap
    • #8 Add KMap.isNotEmpty
    • 3e3228e Add KMap.toString()
    • #9 Add Map.plus, Map.minus and operator +(KMap<K, V> map), operator -(K key)
    • #12 Remove const constructors from collection interfaces
    • #13 Remove default implementations from collection interfaces

    Documentation changes

    • #15 Add documentation for compareBy and compareByDescending

    Other changes

    • #2 Travis CI #2
    • #3, #4 Code coverage
    • #10 Test KMutableList.fill
    • #11 Test KPair, KTriple
    • #14 Test Exceptions
    • #15 Test Comparators naturalOrder(), reverseOrder()
    • #15 Test reverse(Comparator) util function
    • 6dd0d85 Reformatted with dartfmt (80 chars)
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Nov 28, 2018)

Owner
Pascal Welsch
Google Developer Expert for Flutter / CTO of phntm.xyz / Co-founder of @wiredashio / speaker / cat-lover
Pascal Welsch
A collections of packages providing additional functionality for working with bloc

Bloc Extensions A collections of packages providing additional functionality for working with bloc. Index Packages Bloc Hooks Action Blocs Contributin

Aljoscha Grebe 2 Apr 19, 2022
This package helps developer to sort the flutter/dart packages and plugins alphabetically, This makes it easier when managing too many packages and when working with teams

Package helps to sort the flutter/dart packages and plugins alphabetically, This makes it easier when managing too many packages and when working with

DANCHE 7 Dec 21, 2022
Immutable value types, enum classes, and serialization.

Built Values for Dart Introduction Built Value provides: Immutable value types; EnumClass, classes that behave like enums; JSON serialization. Immutab

Google 816 Dec 23, 2022
Github Trending app built with Flutter+Redux+Built(Immutable Data)

Github Trending app built with Flutter+Redux+Built(Immutable Data)

huangyanxiong 9 May 13, 2020
Functional extensions to Dart collections.

collection_ext A set of extension methods for Dart collections, designed for the purpose of making it easier to write concise, functional-programming-

Yingxin Wu 7 Nov 21, 2022
Encode App-Dev is a open source project which contains different projects of Application development, Android development, IOS development, Flutter, Kotlin, Dart, Java, Swift etc.

HACKTOBERFEST 2022 Encode App-Dev is an open source project which contains different projects of Application development, Android development, IOS dev

null 4 Dec 4, 2022
A kotlin-style extension collection for dart.

Collection of extensions Dart is good but can be better. Kotlin Style Join QQ Group now: 1003811176 For objects: let run also takeIf takeUnless For st

OpenFlutter 6 Nov 2, 2022
A pure Dart utility library that checks for an internet connection by opening a socket to a list of specified addresses, each with individual port and timeout. Defaults are provided for convenience.

data_connection_checker A pure Dart utility library that checks for an internet connection by opening a socket to a list of specified addresses, each

Kristiyan Mitev 103 Nov 29, 2022
Dart port of FormCoreJS: A minimal pure functional language based on self dependent types.

FormCore.js port to Dart. So far only the parser and typechecker have been ported i.e. the FormCore.js file in the original repo. (Original readme fro

Modestas Valauskas 2 Jan 28, 2022
Radiance - Dart port of gdx-ai

⚠️ This package is currently under development. This library is a collection of AI algorithms used in games. This includes: Steering behaviors (NYI) F

Flame Engine 20 Oct 30, 2022
A dart port of the excellent Guard Clauses C# package by Ardalis

Guard Clauses A dart port of the excellent C# Guard Clauses package by Ardalis. A simple extensible package with guard clause extensions. A guard clau

Chris Hibler 1 Apr 15, 2022
Klutter plugin makes it possible to write a Flutter plugin for both Android and iOS using Kotlin only.

The Klutter Framework makes it possible to write a Flutter plugin for both Android and iOS using Kotlin Multiplatform. Instead of writing platform spe

Gillian 33 Dec 18, 2022
Safe is an open source mobile platorm to discretely capture incidents with ease, powered by an SMCE written in native Swift and Kotlin.

Safe A powerful tool for personal and community safety. joinsafe.me » Available for iOS & Android ~ Links will be added once a release is available. ~

Safe 10 Oct 26, 2022
A Sample Flutter project to show how to integrate native kotlin code with flutter

kotlin_flashlight A Sample Flutter project to show how to integrate native kotlin code with flutter. Getting Started Visit this docs for Flutter setup

null 0 Apr 4, 2022
Flutterkotlinlottie - A sample flutter app illustrating the implementation of a lottie splash screen natively through kotlin

flutter_lottie_splash_app A Flutter application to demonstrate how to add an ani

null 0 Jan 1, 2022
GitHub Action that uses the Dart Package Analyzer to compute the Pub score of Dart/Flutter packages

Dart/Flutter package analyzer This action uses the pana (Package ANAlysis) package to compute the score that your Dart or Flutter package will have on

Axel Ogereau-Peltier 45 Dec 29, 2022
📅 Customizable flutter calendar widget including day and week views

?? Customizable, animated calendar widget including day, week, and month views. Navigation Animation Callbacks Changing the VisibleDateRange Available

Jonas Wanke 276 Jan 1, 2023
Flutter mobile app with firestore authentication including Email and Social auth.

Flutter mobile app with firestore authentication including Email and Social auth.

Ionicfirebaseapp 96 Dec 7, 2022