Created with <3 with dartpad.dev.
Last active
October 26, 2022 16:24
-
-
Save Zekfad/a92d65958eb8b0de4dd9c791cdad37a5 to your computer and use it in GitHub Desktop.
Question 74210767
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:tuple/tuple.dart'; | |
const Color darkBlue = Color.fromARGB(255, 18, 32, 47); | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
debugShowCheckedModeBanner: false, | |
home: Scaffold( | |
body: Row( | |
children: [ | |
Flexible( | |
// Main RichText, it is consists of `WidgetSpan`s and `TextSpan`s. | |
child: RichText( | |
maxLines: 1, | |
overflow: TextOverflow.ellipsis, | |
text: TextSpan( | |
children: [ | |
const Tuple2(1, 'Name1 Surname1'), | |
const Tuple2(2, 'Name2 Surname2'), | |
const Tuple2(3, 'Name3 Surname3'), | |
].map<InlineSpan>((entry) { | |
final nameWidget = Padding( | |
padding: const EdgeInsets.symmetric(vertical: 2), | |
child: Text( | |
entry.item2, | |
overflow: TextOverflow.ellipsis, | |
// softWrap: false, | |
), | |
); | |
return ButtonSpan( | |
onTap: () async { | |
print('Tap'); | |
}, | |
child: nameWidget, | |
); | |
}) | |
.interject( | |
(previous, index, next) => const TextSpan( | |
text: ', ', | |
), | |
) | |
.toList(), | |
), | |
), | |
), | |
], | |
), | |
), | |
); | |
} | |
} | |
// Custom `WidgetSpan` | |
class ButtonSpan extends WidgetSpan { | |
ButtonSpan({ | |
required super.child, | |
this.onTap, | |
this.maxWidthDelta, | |
}); | |
final void Function()? onTap; | |
final double? maxWidthDelta; | |
@override | |
// ignore: overridden_fields | |
late final Widget child = Material( | |
color: Colors.transparent, | |
child: InkWell( | |
borderRadius: const BorderRadius.all(Radius.circular(4)), | |
onTap: onTap, | |
child: maxWidthDelta == null | |
? super.child | |
// Failed attempt, as constrains are for full paragraph | |
: LayoutBuilder(builder: (context, constraints) => | |
ConstrainedBox( | |
constraints: constraints.copyWith( | |
maxWidth: constraints.maxWidth + maxWidthDelta!, | |
), | |
child: super.child, | |
), | |
), | |
), | |
); | |
} | |
// AUX code | |
/// Interjector function. It has 3 arguments: | |
/// * [E] previous element. | |
/// * [int] index of previous element in original iterable, | |
/// * [E] next element. | |
typedef IterableInterjectFunction<E> = E Function(E previous, int index, E next); | |
/// Interject values between elements of iterable. | |
/// [interjector] function has 3 arguments: | |
/// * [E] previous element. | |
/// * [int] index of previous element in original iterable, | |
/// * [E] next element. | |
Iterable<E> interjectIterable<E>(Iterable<E> iterable, IterableInterjectFunction<E> interjector) sync * { | |
if (iterable.length < 2) { | |
yield* iterable; | |
return; | |
} | |
final it = iterable.iterator | |
..moveNext(); | |
var previous = it.current; | |
var i = 0; | |
yield previous; | |
while (it.moveNext()) { | |
yield interjector(previous, i++, it.current); | |
yield previous = it.current; | |
} | |
} | |
extension IterableInterject<E> on Iterable<E> { | |
/// Interject values between elements of iterable. | |
/// [interjector] function has 3 arguments: | |
/// * [E] previous element. | |
/// * [int] index of previous element in original iterable, | |
/// * [E] next element. | |
Iterable<E> interject(IterableInterjectFunction<E> interjector) => | |
interjectIterable(this, interjector); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment