AI prompts
base on A powerful & easy to use timeline package for Flutter! 🚀 [](https://github.com/chulwoo-park/timelines)
<p align="center">
<a href="https://pub.dartlang.org/packages/timelines">
<img src="https://img.shields.io/pub/v/timelines.svg" alt="Pub" />
</a>
<a href="https://github.com/Solido/awesome-flutter">
<img alt="Awesome Flutter" src="https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true" />
</a>
<a href="https://opensource.org/licenses/MIT">
<img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT" />
</a>
</p>
<p align="center">A powerful & easy to use timeline package for Flutter! 🚀</p>
> ***Caveat***: This package is an early stage. Not enough testing has been done to guarantee stability. Some APIs may change.
# Examples
Check it out on the [web](https://chulwoo.dev/timelines/) or look at the [source code](https://github.com/chulwoo-park/timelines/tree/main/example).
| Timeline status | Package delivery tracking | Process timeline |
| - | - | - |
| [](https://chulwoo.dev/timelines/#/timeline_status) | [](https://chulwoo.dev/timelines/#/package_delivery_tracking) | [](https://chulwoo.dev/timelines/#/process_timeline) |
<p align="center">More examples<br/>🚧 WIP 🚧</p>
# Features
### The [timeline](#timeline) and each [components](#components) are all WIDGET.
* Common styles can be easily implemented with predefined components.
* Vertical, horizontal direction.
* Alternating contents.
* Combination with Flutter widgets(Row, Column, CustomScrollView, etc).
* Customize each range with themes.
# Getting started
- [Installation](#installation)
- [Basic Usage](#basic-usage)
- [Components](#components)
- [Theme](#theme)
- [Indicator](#indicator)
- [Connector](#connector)
- [TimelineNode](#timelinenode)
- [TimelineTile](#timelinetile)
- [Timeline](#timeline)
- [TimelineTileBuilder](#timelinetilebuilder)
## Installation
#### 1. Depend on it
Add this to your package's pubspec.yaml file:
``` yaml
dependencies:
timelines: ^[latest_version]
```
#### 2. Install it
You can install packages from the command line:
with Flutter:
``` console
$ flutter pub get
```
Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.
#### 3. Import it
Now in your Dart code, you can use:
``` dart
import 'package:timelines/timelines.dart';
```
## Basic Usage
``` dart
@override
Widget build(BuildContext context) {
return Timeline.tileBuilder(
builder: TimelineTileBuilder.fromStyle(
contentsAlign: ContentsAlign.alternating,
contentsBuilder: (context, index) => Padding(
padding: const EdgeInsets.all(24.0),
child: Text('Timeline Event $index'),
),
itemCount: 10,
),
);
}
```
Check the [Example](https://github.com/chulwoo-park/timelines/tree/main/example) or the [API reference](https://pub.dev/documentation/timelines/latest/) for more details.
## Components
### Theme
Check out [Theme Demo](https://chulwoo.dev/timelines/#/theme) to see how the values inside TimelineTile work with the theme.
To customize the timeline component with a theme, do the following:
``` dart
TimelineTheme(
data: TimelineThemeData(...),
child: DotIndicator(...),
);
```
If you only want to change part of the parent theme, use `TimelineTheme.of(context)`:
``` dart
TimelineTheme(
data: TimelineThemeData.of(context).copyWith(...),
child: DotIndicator(...),
);
```
If the component you want to customize is `Timeline` or `FixedTimeline`, this is also possible:
``` dart
FixedTimeline(
theme: TimelineThemeData(...),
children: [...],
);
```
### Indicator
<table>
<th colspan="2">ContainerIndicator</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/container_indicator.png" alt="ContainerIndicator">
</td>
<td>
<pre lang="dart">
ContainerIndicator(
child: Container(
width: 15.0,
height: 15.0,
color: Colors.blue,
),
)</pre>
</td>
</tr>
<th colspan="2">DotIndicator</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/dot_indicator.png" alt="DotIndicator">
</td>
<td><pre lang="dart">DotIndicator()</pre></td>
</tr>
<th colspan="2">OutlinedDotIndicator</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/outlined_dot_indicator.png" alt="OutlinedDotIndicator">
</td>
<td><pre lang="dart">OutlinedDotIndicator()</pre></td>
</tr>
</table>
### Connector
<table>
<th colspan="2">SolidLineConnector</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/solid_line_connector.png" alt="SolidLineConnector">
</td>
<td>
<pre lang="dart">
SizedBox(
height: 20.0,
child: SolidLineConnector(),
)</pre>
</td>
</tr>
<th colspan="2">DashedLineConnector</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/dashed_line_connector.png" alt="DashedLineConnector">
</td>
<td>
<pre lang="dart">
SizedBox(
height: 20.0,
child: DashedLineConnector(),
)</pre>
</td>
</tr>
<th colspan="2">DecoratedLineConnector</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/decorated_line_connector.png" alt="DecoratedLineConnector">
</td>
<td>
<pre lang="dart">
SizedBox(
height: 20.0,
child: DecoratedLineConnector(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.blue, Colors.lightBlueAccent[100]],
),
),
),
)</pre>
</td>
</tr>
</table>
### TimelineNode
Pure timeline UI component with no content.
The TimelineNode contains an indicator and two connectors on both sides of the indicator:
<table>
<th colspan="2">Simple TimelineNode</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/simple_timeline_node.png" alt="Simple TimelineNode">
</td>
<td>
<pre lang="dart">
SizedBox(
height: 50.0,
child: TimelineNode.simple(),
)</pre>
</td>
</tr>
<th colspan="2">Complex TimelineNode</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/complex_timeline_node.png" alt="Complex TimelineNode">
</td>
<td>
<pre lang="dart">
SizedBox(
height: 80.0,
child: TimelineNode(
indicator: Card(
margin: EdgeInsets.zero,
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text('Complex'),
),
),
startConnector: DashedLineConnector(),
endConnector: SolidLineConnector(),
),
)</pre>
</td>
</tr>
</table>
### TimelineTile
Displays content on both sides of the node:
<table>
<th colspan="2">TimelineTile</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/timeline_tile.png" alt="TimelineTile">
</td>
<td>
<pre lang="dart">
TimelineTile(
oppositeContents: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('opposite\ncontents'),
),
contents: Card(
child: Container(
padding: EdgeInsets.all(8.0),
child: Text('contents'),
),
),
node: TimelineNode(
indicator: DotIndicator(),
startConnector: SolidLineConnector(),
endConnector: SolidLineConnector(),
),
)</pre>
</td>
</tr>
</table>
### TimelineTileBuilder
TimelineTileBuilder provides powerful build features.
#### Connection
Each tile draws only half of the line connecting the neighboring tiles.
Using the `connected` constructor, lines connecting adjacent tiles can build as one index.
<table>
<th colspan="2">ConnectionDirection.before</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/connection_direction_before.png" alt="Connection direction before">
</td>
<td>
<pre lang="dart">
FixedTimeline.tileBuilder(
builder: TimelineTileBuilder.connectedFromStyle(
connectionDirection: ConnectionDirection.before,
connectorStyleBuilder: (context, index) {
return (index == 1) ? ConnectorStyle.dashedLine : ConnectorStyle.solidLine;
},
indicatorStyleBuilder: (context, index) => IndicatorStyle.dot,
itemExtent: 40.0,
itemCount: 3,
),
)</pre>
</td>
</tr>
<th colspan="2">ConnectionDirection.after</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/connection_direction_after.png" alt="Connection direction after">
</td>
<td>
<pre lang="dart">
FixedTimeline.tileBuilder(
builder: TimelineTileBuilder.connectedFromStyle(
connectionDirection: ConnectionDirection.after,
connectorStyleBuilder: (context, index) {
return (index == 1) ? ConnectorStyle.dashedLine : ConnectorStyle.solidLine;
},
indicatorStyleBuilder: (context, index) => IndicatorStyle.dot,
itemExtent: 40.0,
itemCount: 3,
),
)</pre>
</td>
</tr>
</table>
#### ContentsAlign
This value determines how the contents of the timeline will be built:
<table>
<th colspan="2">ContentsAlign.basic</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/contents_align_basic.png" alt="Basic contents align">
</td>
<td>
<pre lang="dart">
FixedTimeline.tileBuilder(
builder: TimelineTileBuilder.connectedFromStyle(
contentsAlign: ContentsAlign.basic,
oppositeContentsBuilder: (context, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Text('opposite\ncontents'),
),
contentsBuilder: (context, index) => Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Contents'),
),
),
connectorStyleBuilder: (context, index) => ConnectorStyle.solidLine,
indicatorStyleBuilder: (context, index) => IndicatorStyle.dot,
itemCount: 3,
),
)</pre>
</td>
</tr>
<th colspan="2">ContentsAlign.reverse</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/contents_align_reverse.png" alt="Reverse contents align">
</td>
<td>
<pre lang="dart">
FixedTimeline.tileBuilder(
builder: TimelineTileBuilder.connectedFromStyle(
contentsAlign: ContentsAlign.reverse,
oppositeContentsBuilder: (context, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Text('opposite\ncontents'),
),
contentsBuilder: (context, index) => Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Contents'),
),
),
connectorStyleBuilder: (context, index) => ConnectorStyle.solidLine,
indicatorStyleBuilder: (context, index) => IndicatorStyle.dot,
itemCount: 3,
),
)</pre>
</td>
</tr>
<th colspan="2">ContentsAlign.alternating</th>
<tr>
<td align="center">
<img src="https://raw.github.com/chulwoo-park/timelines/main/screenshots/contents_align_alternating.png" alt="Alternating contents align">
</td>
<td>
<pre lang="dart">
FixedTimeline.tileBuilder(
builder: TimelineTileBuilder.connectedFromStyle(
contentsAlign: ContentsAlign.alternating,
oppositeContentsBuilder: (context, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Text('opposite\ncontents'),
),
contentsBuilder: (context, index) => Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Contents'),
),
),
connectorStyleBuilder: (context, index) => ConnectorStyle.solidLine,
indicatorStyleBuilder: (context, index) => IndicatorStyle.dot,
itemCount: 3,
),
)</pre>
</td>
</tr>
</table>
### Timeline
The timeline component has two widgets, `Timeline` similar to ScrollView and `FixedTimeline` similar to Flex.
Also their constructors are similar to ScrollView and Flex.
The main difference is that they has TimelineTheme as an ancestor.
The `tileBuilder` constructor provides more powerful features using [TimelineTileBuilder](https://pub.dev/documentation/timelines/latest/timelines/TimelineTileBuilder-class.html).
If you don't need TimelineTileBuilder, you can use other flutter widgets like ListView, Column, Row, etc.
Even if you use the flutter widget, you can use TimelineTheme.
# Documentation
See full [documentation](https://pub.dev/documentation/timelines/latest/)
# Changelog
See [CHANGELOG.md](https://github.com/chulwoo-park/timelines/blob/main/CHANGELOG.md).
# Code of conduct
See [CODE_OF_CONDUCT.md](https://github.com/chulwoo-park/timelines/blob/main/CODE_OF_CONDUCT.md).
# License
[MIT](https://github.com/chulwoo-park/timelines/blob/main/LICENSE)
", Assign "at most 3 tags" to the expected json: {"id":"12724","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"