Skip to content

Commit

Permalink
Merge pull request #19 from WieFel/feature/prev-next-button-content
Browse files Browse the repository at this point in the history
Prev/next button customisations
  • Loading branch information
WieFel authored Sep 29, 2023
2 parents d9472b7 + ee31036 commit 1266d91
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 105 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## [0.4.0] - 29.09.2023

- New properties `showNextButton` and `showPrevButton` for showing/hiding the next/prev buttons
- New way to customize prev/next buttons using `prevButtonBuilder` or `nextButtonBuilder`
- Slight adaptation of margin/padding of "three dots" (only noticeable if it's background is colored)

## [0.3.2] - 30.07.2023

- Correct images in README.md
Expand Down
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ floatingActionButton: FloatingActionButton(

### Customize
`NumberPaginator` allows for several customizations.

#### Button look and feel
```dart
NumberPaginator(
// by default, the paginator shows numbers as center content
Expand Down Expand Up @@ -85,6 +87,37 @@ NumberPaginator(
<img alt="custom buttons" src="https://user-images.githubusercontent.com/8345062/189089917-05bde1aa-6150-4e1f-bb35-e35a50fafecb.png" width="30%"/>
</p>

#### Visibility/customisation of prev/next buttons
```dart
NumberPaginator(
// by default, the paginator shows numbers as center content
numberPages: 10,
onPageChange: (int index) {
setState(() {
_currentPage = index; // _currentPage is a variable within State of StatefulWidget
});
},
// show/hide the prev/next buttons
showPrevButton: true,
showNextButton: false, // defaults to true
// custom content of the prev/next buttons, maintains their behavior
nextButtonContent: Icon(Icons.arrow_right_alt),
// custom prev/next buttons using builder (ignored if showPrevButton/showNextButton is false)
prevButtonBuilder: (context) => TextButton(
onPressed: _controller.currentPage > 0 ? () => _controller.prev() : null, // _controller must be passed to NumberPaginator
child: const Row(
children: [
Icon(Icons.chevron_left),
Text("Previous"),
],
),
),
)
```
<p align="center">
<img alt="prev/next button customisation" src="https://github.com/WieFel/number_paginator/assets/8345062/fe2dd053-9573-4cb3-b81b-43b22b1a3b38" width="30%"/>
</p>

### Content variations
The new version of `NumberPaginator` allows for further customization of how a user can navigate between pages. It provides three different modes and an additional possibility of complete customization o the content using a `builder`.

Expand Down
2 changes: 1 addition & 1 deletion example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
38 changes: 19 additions & 19 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
version: "1.17.1"
version: "1.17.2"
fake_async:
dependency: transitive
description:
Expand All @@ -75,14 +75,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
js:
dependency: transitive
description:
name: js
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.6.7"
lints:
dependency: transitive
description:
Expand All @@ -95,18 +87,18 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.15"
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
version: "0.5.0"
meta:
dependency: transitive
description:
Expand Down Expand Up @@ -139,10 +131,10 @@ packages:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
stack_trace:
dependency: transitive
description:
Expand Down Expand Up @@ -179,10 +171,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
version: "0.6.0"
vector_math:
dependency: transitive
description:
Expand All @@ -191,6 +183,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
web:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
sdks:
dart: ">=3.0.0-0 <4.0.0"
dart: ">=3.1.0-185.0.dev <4.0.0"
flutter: ">=1.17.0"
89 changes: 78 additions & 11 deletions lib/src/ui/number_paginator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:number_paginator/src/model/config.dart';
import 'package:number_paginator/src/model/display_mode.dart';
import 'package:number_paginator/src/ui/number_paginator_controller.dart';
import 'package:number_paginator/src/ui/widgets/buttons/paginator_icon_button.dart';
import 'package:number_paginator/src/ui/widgets/buttons/paginator_button.dart';
import 'package:number_paginator/src/ui/widgets/inherited_number_paginator.dart';
import 'package:number_paginator/src/ui/widgets/paginator_content.dart';

Expand All @@ -27,8 +27,48 @@ class NumberPaginator extends StatefulWidget {
/// [config] is ignored.
final NumberPaginatorContentBuilder? contentBuilder;

/// The controller for the paginator. Can be used to control the paginator from the outside.
/// If not provided, a new controller is created.
final NumberPaginatorController? controller;

/// Whether the "prev" button should be shown.
///
/// Defaults to `true`.
final bool showPrevButton;

/// Whether the "next" button should be shown.
///
/// Defaults to `true`.
final bool showNextButton;

/// Content of the "previous" button which when pressed goes one page back.
///
/// Defaults to:
/// ```dart
/// Icon(Icons.chevron_left),
/// ```
final Widget prevButtonContent;

/// Content of the "next" button which when pressed goes one page forward.
///
/// Defaults to:
/// ```dart
/// Icon(Icons.chevron_right),
/// ```
final Widget nextButtonContent;

/// Builder option for providing a custom "previous" button.
///
/// If this is provided, [prevButtonContent] is ignored.
/// If [showPrevButton] is `false`, this is ignored.
final WidgetBuilder? prevButtonBuilder;

/// Builder option for providing a custom "next" button.
///
/// If this is provided, [nextButtonContent] is ignored.
/// If [showNextButton] is `false`, this is ignored.
final WidgetBuilder? nextButtonBuilder;

/// Creates an instance of [NumberPaginator].
const NumberPaginator({
Key? key,
Expand All @@ -38,10 +78,34 @@ class NumberPaginator extends StatefulWidget {
this.config = const NumberPaginatorUIConfig(),
this.contentBuilder,
this.controller,
this.showPrevButton = true,
this.showNextButton = true,
this.prevButtonContent = const Icon(Icons.chevron_left),
this.nextButtonContent = const Icon(Icons.chevron_right),
this.prevButtonBuilder,
this.nextButtonBuilder,
}) : assert(initialPage >= 0),
assert(initialPage <= numberPages - 1),
super(key: key);

const NumberPaginator.noPrevNextButtons({
Key? key,
required this.numberPages,
this.initialPage = 0,
this.onPageChange,
this.config = const NumberPaginatorUIConfig(),
this.contentBuilder,
this.controller,
}) : showPrevButton = false,
showNextButton = false,
prevButtonContent = const SizedBox(),
nextButtonContent = const SizedBox(),
prevButtonBuilder = null,
nextButtonBuilder = null,
assert(initialPage >= 0),
assert(initialPage <= numberPages - 1),
super(key: key);

@override
NumberPaginatorState createState() => NumberPaginatorState();
}
Expand Down Expand Up @@ -72,17 +136,20 @@ class NumberPaginatorState extends State<NumberPaginator> {
child: Row(
mainAxisAlignment: widget.config.mainAxisAlignment,
children: [
PaginatorIconButton(
onPressed: _controller.currentPage > 0 ? _controller.prev : null,
icon: Icons.chevron_left,
),
if (widget.showPrevButton)
widget.prevButtonBuilder?.call(context) ??
PaginatorButton(
onPressed: _controller.currentPage > 0 ? _controller.prev : null,
child: widget.prevButtonContent,
),
..._buildCenterContent(),
PaginatorIconButton(
onPressed: _controller.currentPage < widget.numberPages - 1
? _controller.next
: null,
icon: Icons.chevron_right,
),
if (widget.showNextButton)
widget.nextButtonBuilder?.call(context) ??
PaginatorButton(
onPressed:
_controller.currentPage < widget.numberPages - 1 ? _controller.next : null,
child: widget.nextButtonContent,
),
],
),
),
Expand Down
26 changes: 0 additions & 26 deletions lib/src/ui/widgets/buttons/paginator_icon_button.dart

This file was deleted.

38 changes: 13 additions & 25 deletions lib/src/ui/widgets/paginator_content/number_content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,12 @@ class NumberContent extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildPageButton(context, 0),
if (_frontDotsShouldShow(context, availableSpots))
_buildDots(context),
if (_frontDotsShouldShow(context, availableSpots)) _buildDots(context),
if (InheritedNumberPaginator.of(context).numberPages > 1)
..._generateButtonList(context, availableSpots),
if (_backDotsShouldShow(context, availableSpots))
_buildDots(context),
if (_backDotsShouldShow(context, availableSpots)) _buildDots(context),
if (InheritedNumberPaginator.of(context).numberPages > 1)
_buildPageButton(context,
InheritedNumberPaginator.of(context).numberPages - 1),
_buildPageButton(context, InheritedNumberPaginator.of(context).numberPages - 1),
],
);
},
Expand All @@ -59,38 +56,31 @@ class NumberContent extends StatelessWidget {
minValue = (maxValue - shownPages).clamp(1, numberPages - 1);
}

return List.generate(maxValue - minValue,
(index) => _buildPageButton(context, minValue + index));
return List.generate(
maxValue - minValue, (index) => _buildPageButton(context, minValue + index));
}

/// Builds a button for the given index.
Widget _buildPageButton(BuildContext context, int index) => PaginatorButton(
onPressed: () =>
InheritedNumberPaginator.of(context).onPageChange?.call(index),
onPressed: () => InheritedNumberPaginator.of(context).onPageChange?.call(index),
selected: _selected(index),
child:
AutoSizeText((index + 1).toString(), maxLines: 1, minFontSize: 5),
child: AutoSizeText((index + 1).toString(), maxLines: 1, minFontSize: 5),
);

Widget _buildDots(BuildContext context) => AspectRatio(
aspectRatio: 1,
child: Container(
// padding: const EdgeInsets.all(4.0),
margin: const EdgeInsets.all(8.0),
padding: const EdgeInsets.all(4.0),
margin: const EdgeInsets.all(4.0),
alignment: Alignment.bottomCenter,
decoration: ShapeDecoration(
shape: InheritedNumberPaginator.of(context).config.buttonShape ??
const CircleBorder(),
color: InheritedNumberPaginator.of(context)
.config
.buttonUnselectedBackgroundColor,
shape: InheritedNumberPaginator.of(context).config.buttonShape ?? const CircleBorder(),
color: InheritedNumberPaginator.of(context).config.buttonUnselectedBackgroundColor,
),
child: AutoSizeText(
"...",
style: TextStyle(
color: InheritedNumberPaginator.of(context)
.config
.buttonUnselectedForegroundColor ??
color: InheritedNumberPaginator.of(context).config.buttonUnselectedForegroundColor ??
Theme.of(context).colorScheme.secondary,
fontSize: 16,
fontWeight: FontWeight.bold,
Expand All @@ -102,9 +92,7 @@ class NumberContent extends StatelessWidget {
/// Checks if pages don't fit in available spots and dots have to be shown.
bool _backDotsShouldShow(BuildContext context, int availableSpots) =>
availableSpots < InheritedNumberPaginator.of(context).numberPages &&
currentPage <
InheritedNumberPaginator.of(context).numberPages -
availableSpots ~/ 2;
currentPage < InheritedNumberPaginator.of(context).numberPages - availableSpots ~/ 2;

bool _frontDotsShouldShow(BuildContext context, int availableSpots) =>
availableSpots < InheritedNumberPaginator.of(context).numberPages &&
Expand Down
Loading

0 comments on commit 1266d91

Please sign in to comment.