Coder Social home page Coder Social logo

chulwoo-park / timelines Goto Github PK

View Code? Open in Web Editor NEW
693.0 7.0 140.0 3.34 MB

A powerful & easy to use timeline package for Flutter! πŸš€

Home Page: https://pub.dev/packages/timelines

License: MIT License

Dart 97.89% Kotlin 0.08% Swift 0.25% Objective-C 0.02% HTML 0.93% Ruby 0.83%
flutter flutter-ui timeline timelines dart flutter-widget flutter-package timeline-component flutter-widgets

timelines's Introduction

banner

Pub Awesome Flutter License: MIT

A powerful & easy to use timeline package for Flutter! πŸš€

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 or look at the source code.

Timeline status Package delivery tracking Process timeline
timeline_status package_delivery_tracking.gif process_timeline.gif

More examples
🚧 WIP 🚧

Features

The timeline and each 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

1. Depend on it

Add this to your package's pubspec.yaml file:

dependencies:
  timelines: ^[latest_version]

2. Install it

You can install packages from the command line:

with Flutter:

$ 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:

import 'package:timelines/timelines.dart';

Basic Usage

@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 or the API reference for more details.

Components

Theme

Check out Theme Demo to see how the values inside TimelineTile work with the theme.

To customize the timeline component with a theme, do the following:

TimelineTheme(
  data: TimelineThemeData(...),
  child: DotIndicator(...),
);

If you only want to change part of the parent theme, use TimelineTheme.of(context):

TimelineTheme(
  data: TimelineThemeData.of(context).copyWith(...),
  child: DotIndicator(...),
);

If the component you want to customize is Timeline or FixedTimeline, this is also possible:

FixedTimeline(
  theme: TimelineThemeData(...),
  children: [...],
);

Indicator

ContainerIndicator
ContainerIndicator
ContainerIndicator(
  child: Container(
    width: 15.0,
    height: 15.0,
    color: Colors.blue,
  ),
)
DotIndicator
DotIndicator
DotIndicator()
OutlinedDotIndicator
OutlinedDotIndicator
OutlinedDotIndicator()

Connector

SolidLineConnector
SolidLineConnector
SizedBox(
  height: 20.0,
  child: SolidLineConnector(),
)
DashedLineConnector
DashedLineConnector
SizedBox(
  height: 20.0,
  child: DashedLineConnector(),
)
DecoratedLineConnector
DecoratedLineConnector
SizedBox(
  height: 20.0,
  child: DecoratedLineConnector(
    decoration: BoxDecoration(
      gradient: LinearGradient(
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
        colors: [Colors.blue, Colors.lightBlueAccent[100]],
      ),
    ),
  ),
)

TimelineNode

Pure timeline UI component with no content.

The TimelineNode contains an indicator and two connectors on both sides of the indicator:

Simple TimelineNode
Simple TimelineNode
SizedBox(
  height: 50.0,
  child: TimelineNode.simple(),
)
Complex TimelineNode
Complex TimelineNode
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(),
  ),
)

TimelineTile

Displays content on both sides of the node:

TimelineTile
TimelineTile
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(),
  ),
)

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.

ConnectionDirection.before
Connection direction before
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,
  ),
)
ConnectionDirection.after
Connection direction after
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,
  ),
)

ContentsAlign

This value determines how the contents of the timeline will be built:

ContentsAlign.basic
Basic contents align
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,
  ),
)
ContentsAlign.reverse
Reverse contents align
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,
  ),
)
ContentsAlign.alternating
Alternating contents align
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,
  ),
)

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.

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

Changelog

See CHANGELOG.md.

Code of conduct

See CODE_OF_CONDUCT.md.

License

MIT

timelines's People

Contributors

akora-ingdkb avatar areille avatar chulwoo-park avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

timelines's Issues

OppositeContentsBuilder

Can I remove space of OppositeContentsBuilder in top timeline?
I don't use it, but it alsway take space in the top.

on RTL mode (i.e. in Arabic languages) indicatorBuilder's text is bit shifted up

here's my code:

indicatorBuilder: (_, index) =>
              Container(
                    width: 24,
                    height: 24,
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      color: AppColors.accentExtraLight,
                      border: Border.all(color: AppColors.accentGreenPrimary),
                    ),
                    child: Center(
                      child: Text(
                        "${index + 1}",
                      ),
                    ),
                  ),

I can add some padding, but I'm afraid it might break on other size devices and that's not a correct way of doing it.
I even tried force making this widget LTR always but no luck
on LTR mode looks fine.

image

Pressing an Individual Node

Is there a way to change the colour of a node when it's pressed? I can't seem to see any onTap or onPress methods for a specific node.

Extend Timeline Line

Is it possible extend the timeline when donΒ΄t existis items?

Today it ends like this
image

Is there a possibility to do something like this?
image

Question: Top alignment between content and indicator

How can I align the top of the indicator with the top of the content, when the content is longer than a single line?

Basically making sure the two red lines are aligned in the following example:

Screenshot 2022-01-10 at 11 15 04

Is there any option to accomplish this already?

Thanks

SolidLineConnector and other connectors should have a child parameter.

I want to create a custom timeline. A TimelineTile that will show contents, with a node that has a custom indicator. The node has an endConnector parameter that I think the connector widget should have a child parameter in case you want to connect to another TimeLineTile.

           TimelineTile(
             contents: const Padding(
               padding: EdgeInsets.all(8.0),
               child: Text(
                 "WORK EXPERIENCE",
                 style: TextStyle(
                     color: Colors.white, fontWeight: FontWeight.bold),
               ),
             ),
             node: TimelineNode(
               endConnector: const SolidLineConnector(
                 color: Colors.white,
               ),
               indicator: Container(
                 width: 50,
                 height: 50,
                 decoration: BoxDecoration(
                     borderRadius: BorderRadius.circular(25),
                     color: HexColor('#eab676')),
                 child: const Icon(
                   Icons.work,
                   color: Colors.white,
                 ),
               ),
             ),
           ),
         )),

Suggested feature: Animations

Hi. This is a great library by all means. It is just missing animation from one indicator to another. That would be cool if I could show it animated to the user.

Missing dot background color value?

I want to create this moc but I can't find how to change the dots to be with background color and using FixedTimeline.tileBuilder(

This is the moc
image1

The dots have a border color and different background color.

This is the closest that I have reached

image2

Values that I think are missing:

  • Background color for outlined indicator (for border like effect).
  • Option to control the number of lines in the dashedLine.
  • A way to choose the currently selected position in the timeline and automatically all outlined indicators before that will have selected properties (like a purple background) and the rest will have different indicator properties (like a white background).

Question: timeline branching?

Hello and thanks for making this package.
I am wondering if you have any plans of implementing the ability to have parallel timelines similar to what you might see in a git history graph;

image

This may be a feature I would want for a personal project of mine and if I do end up needing it, I would be more than happy to contribute the code to this awesome package!

Vertical align indicators with item content

Thanks for the promising plugin. Is there any way to control vertical positioning of the indicators? For example, if I use larger titles, can I force the indicators down in order to line them up with the content titles better ? Here's the problem I'm facing:

Screenshot_20201209-081739

and my item builder:

            contentsBuilder: (context, index) => Padding(
            padding: const EdgeInsets.only(
              left: 30,
              bottom: 30,
              right: 30,
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'Timeline Event $index',
                  textScaleFactor: 3,
                ),
                SizedBox(height: 10),
                Text('Nam libero tempore, cum soluta nobis...') // truncated for brevity here
              ],
            ),
          ),

But it's not clear to me how I can shift the indicators down, either all together, or individually, in order to line up with the titles better...? Thanks.

Documentation and examples are not clear

The Showcase screen in the code example only shows png files with the results, but how are they implemented?

How can I control each connector and each Node?
I want the connectors be in in different lengths and have different Icon on each Node.

horizontal timeline home widget

I try to create a widget with timeline, to put on homepage.

Something like this,
image

but I always got an error

The following assertion was thrown during performLayout():
RenderFlex children have non-zero flex but incoming width constraints are unbounded.

When a row is in a parent that does not provide a finite width constraint, for example if it is in a horizontal scrollable, it will try to shrink-wrap its children along the horizontal axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining space in the horizontal direction.
These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child cannot simultaneously expand to fit its parent.

Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible children (using Flexible rather than Expanded). This will allow the flexible children to size themselves to less than the infinite remaining space they would otherwise be forced to take, and then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum constraints provided by the parent.

Support indicatorPositionOffset with value in px

Currently we can adjust alignment of indicator along the connecters using indicatorPosition but this accepts value in 0-1 range. A common use case is to have the indicator X px from the start/end.

Question : How to align the nodes to the left ?

Hi,

I would like to align the nodes to the left in order to have a fixed size for the content and the remaining space for the opposite content. There is a property nodeAlign in TimelineTile that used to compute the effective node position :

  double _getEffectiveNodePosition(BuildContext context) {
    if (nodeAlign == TimelineNodeAlign.start) return 0.0;
    if (nodeAlign == TimelineNodeAlign.end) return 1.0;
    var nodePosition = this.nodePosition;
    nodePosition ??= (node is TimelineTileNode)
        ? (node as TimelineTileNode).getEffectivePosition(context)
        : TimelineTheme.of(context).nodePosition;
    return nodePosition;
  }

This property can't be used in TimelineTileBuilder so please what is the simplest way to define the nodeAlign ?

null-safety release is not available

Hi, according to the changelog there should be a version available 0.1.0-null which includes null-safety changes, but when I try to set this version in my pubspec.yaml then I get an error that this version is not available

pubspec.yaml:

timelines: 0.1.0-null

error:

Because project depends on timelines 0.1.0-null which doesn't match any versions, version solving failed.

version from pub.dev:
image

Hundreds of data

Hi,

Can i used it with hundred of data like a list that is recycled?

I want make something like this:

image

Is it possible?

Thanks.

Stacked InnerTimeline

Thanks for contribute this plugin.

i faced Stacked InnerTimeline issue.

i want to display 3 line in InnerTimeline (inside contentsBuilder) so it only work 2 line.

here is my code:

contentsBuilder: (_, index) {
            if (isEdgeIndex(index)) {
              return null;
            }
            return Container(
              padding: EdgeInsets.only(left: 8.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: [
                  Flexible(
                    child: Text(
                      childs[index -1].note ?? "",
                      style: TextStyle(
                        color: Color(0xFF4964D8),
                        fontSize: 16.0,
                        fontWeight: FontWeight.w500,
                        fontFamily: 'AvenirRoman',
                      ),
                    )
                  ),
                  // Flexible(child: _buildTags(childs[index - 1].tags)),
                  Flexible(
                    child: Text(
                      myParseDatetime1(childs[index - 1].createdAt),
                      style: TextStyle(
                        color: Color(0xFFA8A8A8),
                        fontSize: 14.0,
                        fontWeight: FontWeight.w500,
                        fontFamily: 'AvenirRoman',
                      ),
                    )
                  ),
                  Text('123')
                ],
              ),
            );

          },

Screen Shot 2021-01-06 at 16 52 53

here is 2 line. it's work

Screen Shot 2021-01-06 at 17 00 31

Pagination with timeline

Hey, I'm trying to implement pagination with timelines.
Currently, I'm wrapping timelines in a listview. But that leads to the complete timeline being rebuilt on each change. Is there any way to use a ListView.builder() like extending of the timeline?

The best solution would be to only draw the items currently visible on the screen and extend the timeline on the fly.

How to add timeline in the end?

Currently, my timeline like this image:
Screenshot 2023-11-13 at 10 17 31 AM
But i wanna like this image, add line in the end (in red square), so how to do this?
Screenshot 2023-11-13 at 10 19 45 AM
My code:

Expanded(
                          child: Timeline.tileBuilder(
                            theme: TimelineThemeData(
                              nodePosition: 0,
                              color: ThemeHelper.backgroundRealm(context),
                              connectorTheme: const ConnectorThemeData(
                                thickness: 3.0,
                              ),
                            ),
                            builder: TimelineTileBuilder.connected(
                              indicatorBuilder: (context, index) {
                                return DotIndicator(
                                  size: 18,
                                  color: ThemeHelper.primaryBlueColor(context),
                                  border: Border.all(
                                    color: ThemeHelper.borderProcessHistoryDot(
                                        context),
                                    width: 3,
                                  ),
                                );
                              },
                              connectorBuilder: (_, index, connectorType) {
                                return SolidLineConnector(
                                  indent: connectorType == ConnectorType.start
                                      ? 5.0
                                      : 5.0,
                                  endIndent: connectorType == ConnectorType.end
                                      ? 5.0
                                      : 5.0,
                                  color: ThemeHelper.black(context),
                                  thickness: 1,
                                );
                              },
                              indicatorPositionBuilder: (context, index) => 0,
                              contentsBuilder: (_, index) => WidgetA,
                              itemExtentBuilder: (_, index) {
                                return 110;
                              },
                              itemCount: processHistoryList.length,
                            ),
                          ),
                        )

Thank you so much!

Possible integration with video_player

Hi :) First of all, thanks you for such great package. After all these days of seraching, it seems to me I found the right place to ask.

So I would like to create the timeline (or something like archive) for my videostream. The issue is quite non-trivial and hard, because videostream dosen't have the end. I could say, it is infinite videostream if we would scroll it back. Also the timeline should be under the videostream and I would like to have acess to it by double tap. So my question is could I customize it like I described above? And could I make the post-request to put two timestapms? Can these package work with API-request?

How to change contentsAlign for individual items.

Was unable to find any clue in the documentation on how to use different contentsAlign for different items.

Im trying to use reverse align for some items in the timeline.

Example: For a timeline of football/soccer match, events come from both teams. Is it possible to use 'reverse' for the "away" team events only?

Please let me know if it is possible. Thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.