ntb_vistech_widgets 0.1.1-dev.16 copy "ntb_vistech_widgets: ^0.1.1-dev.16" to clipboard
ntb_vistech_widgets: ^0.1.1-dev.16 copied to clipboard

NTB reusable Flutter widgets library

NTB Vistech Widgets #

A Flutter widget library with customizable buttons, inputs, and UI components for NTB applications.

Pub Version License: MIT

๐ŸŽฏ Features #

  • โœ… NTBOutlinedButton - Customizable outlined buttons with multiple variants
  • โœ… Button - Elevated buttons with theme support
  • โœ… Multiple Variants - Primary, Secondary, Disabled, Transparent
  • โœ… Icon Support - Leading and trailing icons
  • โœ… Dark Mode - Automatic theme adaptation

๐Ÿ“ฆ Installation #

Add this to your app's pubspec.yaml:

dependencies:
  ntb_vistech_widgets: ^0.1.0

Then run:

flutter pub get

For local development or testing unreleased features, use a path dependency.

Step 1: Clone the Repository

Clone at the same level as your consumer app:

your-projects/
โ”œโ”€โ”€ your-app/                    # Your Flutter app
โ””โ”€โ”€ ntb-smartphone-widgetbook/   # This widget library
cd your-projects/
git clone https://bitbucket.org/NTB-NO/ntb-smartphone-widgetbook.git

Step 2: Update Your App's Dependencies

In your app's pubspec.yaml, add the path dependency:

dependencies:
  flutter:
    sdk: flutter

  # Use path dependency for local development
  ntb_vistech_widgets:
    path: ../ntb-smartphone-widgetbook

Step 3: Install Dependencies

cd your-app/
flutter pub get

Step 4: Import and Use

import 'package:ntb_vistech_widgets/ntb_vistech_widgets.dart';

// Use the widgets
NTBOutlinedButton(
  label: 'Click Me',
  variant: NTBButtonVariant.primary,
  onPressed: () => print('Clicked!'),
)

๐Ÿ”ฅ Hot Reload with Local Changes

When using path dependency, changes are picked up automatically:

  1. Make changes in ntb-smartphone-widgetbook/lib/
  2. Save the file
  3. Hot reload (r) in your app
  4. See changes instantly! โšก

๐Ÿ”„ Switching Between Versions

Use local version (development):

ntb_vistech_widgets:
  path: ../ntb-smartphone-widgetbook

Use published version (production):

ntb_vistech_widgets: ^0.1.0

Just comment/uncomment and run flutter pub get.


๐Ÿš€ Quick Start #

Basic Outlined Button #

import 'package:ntb_vistech_widgets/ntb_vistech_widgets.dart';

NTBOutlinedButton(
  label: 'Click Me',
  variant: NTBButtonVariant.primary,
  onPressed: () => print('Clicked!'),
)

Button with Icons #

NTBOutlinedButton(
  label: 'Download',
  variant: NTBButtonVariant.primary,
  leadingIcon: Icons.download,
  trailingIcon: Icons.arrow_forward,
  contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
  onPressed: () => print('Download started'),
)

Transparent Button #

NTBOutlinedButton(
  label: 'Cancel',
  variant: NTBButtonVariant.transparent,
  noBorder: true,
  contentPadding: EdgeInsets.symmetric(horizontal: 0, vertical: 12),
  onPressed: () => print('Cancelled'),
)

Elevated Button #

Button(
  label: 'Submit',
  variant: NTBButtonVariant.primary,
  onPressed: () => print('Submitted'),
)

๐ŸŽจ Button Variants #

Variant Description Use Case
primary Green background, white text Main call-to-action buttons
secondary Grey background, white text Secondary actions
disabled Grey tones, no interaction Disabled state
transparent Transparent background Subtle actions, links

Understanding Variants #

Variants provide pre-configured button styles that adapt to your app's theme (light/dark mode). Instead of manually setting colors for each button, use variants for consistency.

๐Ÿ› ๏ธ Customization #

NTBOutlinedButton(
  label: 'Custom Button',
  variant: NTBButtonVariant.primary,
  backgroundColor: Colors.purple,
  foregroundColor: Colors.white,
  borderColor: Colors.deepPurple,
  contentPadding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
  maxLines: 2,
  onPressed: () {},
)

Available Properties #

Property Type Default Description
label String required Button text
variant NTBButtonVariant primary Button style variant
onPressed VoidCallback? null Tap callback
leadingIcon IconData? null Icon before text
trailingIcon IconData? null Icon after text
backgroundColor Color? variant color Custom background
foregroundColor Color? variant color Custom text/icon color
borderColor Color? theme outline Custom border
contentPadding EdgeInsetsGeometry? (16, 8) Internal padding
noBorder bool false Remove border
maxLines int 3 Max text lines
style TextStyle? null Custom text style

๐Ÿ“š Widgetbook - Live Documentation #

This library includes Widgetbook - an interactive showcase where you can explore all widgets, variants, and configurations in real-time.

What is Widgetbook? #

Widgetbook is like Storybook for Flutter. It provides:

  • ๐ŸŽจ Live preview of all widgets
  • ๐ŸŽ›๏ธ Interactive controls (knobs) to modify properties in real-time
  • ๐ŸŒ“ Dark/Light mode toggle
  • ๐Ÿ“ฑ Responsive preview
  • ๐Ÿ” Search and filter widgets
  • ๐Ÿ“– Living documentation that stays in sync with code

Running Widgetbook Locally #

Understanding the Project Structure

This repository contains two separate Flutter projects:

ntb-smartphone-widgetbook/
โ”œโ”€โ”€ lib/                          # ๐Ÿ“ฆ Main widget library (published to pub.dev)
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ””โ”€โ”€ inputs/
โ”‚   โ”‚       โ”œโ”€โ”€ button.dart
โ”‚   โ”‚       โ””โ”€โ”€ outlined_button.dart
โ”‚   โ””โ”€โ”€ ntb_vistech_widgets.dart
โ”œโ”€โ”€ pubspec.yaml                  # Library dependencies
โ”‚
โ””โ”€โ”€ widgetbook/                   # ๐Ÿ“ฑ Separate Flutter app (not published)
    โ”œโ”€โ”€ lib/
    โ”‚   โ”œโ”€โ”€ main.dart
    โ”‚   โ”œโ”€โ”€ widgetbook.dart
    โ”‚   โ””โ”€โ”€ use_cases/
    โ”œโ”€โ”€ pubspec.yaml              # Widgetbook dependencies
    โ””โ”€โ”€ web/

Two projects explained:

  1. Main Library (/ root)

    • The reusable widget library you install in your apps
    • Gets published to pub.dev
    • Contains the actual widget implementations
  2. Widgetbook App (/widgetbook/ folder)

    • A standalone Flutter application
    • Showcases and documents the widgets
    • Used for development and testing only
    • Not published to pub.dev

Why this structure?

  • Widgetbook requires a separate Flutter app to run
  • The main library stays clean and lightweight for pub.dev
  • The widgetbook app can have its own dependencies without affecting the library
  • This is the standard pattern for Flutter widget libraries with Widgetbook
  • The widgetbook app can be built as a web version - (To be discussed?) this would allow us to deploy this library as a live documentation website where other team members can view and test all widget variants interactively in their browser before consuming the widgets.

Setup and Run

Step 1: Clone the Repository

# Clone the entire repository
git clone https://bitbucket.org/NTB-NO/ntb-smartphone-widgetbook.git
cd ntb-smartphone-widgetbook

Step 2: Install Main Library Dependencies

# From the root directory
flutter pub get

Step 3: Navigate to Widgetbook App

# Navigate into the widgetbook folder
cd widgetbook

Important: All remaining commands run from inside the widgetbook/ directory!

Step 4: Install Widgetbook Dependencies

# Inside widgetbook/ directory
flutter pub get

Step 5: Generate Widget Catalog

# Inside widgetbook/ directory
dart run build_runner build --delete-conflicting-outputs

This generates widgetbook.directories.g.dart which catalogs all widgets with @UseCase annotations.

Step 6: Run Widgetbook

# To run on Web (Recommended for Widgetbook)
flutter run -d chrome

# To run on a connected Simulator/Emulator
flutter run

The Widgetbook will open in your browser at http://localhost:XXXX


Quick Start Commands (TL;DR)

# One-liner to get started
git clone https://bitbucket.org/NTB-NO/ntb-smartphone-widgetbook.git && \
cd ntb-smartphone-widgetbook/widgetbook && \
flutter pub get && \
dart run build_runner build --delete-conflicting-outputs && \
flutter run -d chrome

Development Mode with Auto-Rebuild

For active development, use watch mode to automatically rebuild when you change use cases:

Terminal 1: Start watch mode

cd widgetbook
dart run build_runner watch --delete-conflicting-outputs

Terminal 2: Run the app

cd widgetbook
flutter run -d chrome

Now when you:

  1. Create new use cases
  2. Modify existing use cases
  3. Add @UseCase annotations

The catalog automatically rebuilds! Just hot reload (r) to see changes.


Typical Development Workflow

# 1. Edit widget in main library (from project root)
vim lib/src/inputs/my_widget.dart

# 2. Update use cases (from widgetbook/ directory)
cd widgetbook
vim lib/use_cases/inputs/my_widget_use_cases.dart

# 3. If watch mode is running, catalog rebuilds automatically
# 4. Press 'r' in the Flutter terminal to hot reload
# 5. See your changes in the browser instantly! โšก

Troubleshooting

"Port already in use" error?

flutter run -d chrome --web-port=8080

Build errors after adding new use cases?

# Clean and rebuild
cd widgetbook
dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs

Can't find your widgets in Widgetbook?

  • Ensure you've added @UseCase annotations to your use case functions
  • Check that build_runner completed successfully
  • Verify use case files are in widgetbook/lib/use_cases/
  • Make sure you're importing from package:ntb_vistech_widgets/ntb_vistech_widgets.dart

Hot reload not working?

# Try hot restart instead
# Press 'R' (capital R) in the Flutter terminal

๐ŸŽฏ How to Create New Widgets for Widgetbook #

Widget Naming Convention & Organization #

All widgets in this library follow the NTB prefix pattern:

โœ… NTBOutlinedButton    // Good
โœ… NTBTextField         // Good
โœ… NTBCheckbox          // Good
โŒ OutlinedButton       // Bad - missing NTB prefix
โŒ CustomButton         // Bad - not following convention

Why NTB prefix?

  • Clear identification - Easy to distinguish library widgets from Flutter's built-in widgets
  • No naming conflicts - Avoids collisions with Material/Cupertino widgets
  • Consistent imports - All widgets clearly come from ntb_vistech_widgets
  • Better IDE autocomplete - Type "NTB" to see all available widgets
  • Professional branding - Shows these are official NTB components

Widget Organization by Category #

Organize widgets in folders based on their purpose:

lib/src/
โ”œโ”€โ”€ actions/              # User action widgets
โ”‚   โ”œโ”€โ”€ button.dart              # NTBButton
โ”‚   โ””โ”€โ”€ outlined_button.dart     # NTBOutlinedButton
โ”‚
โ”œโ”€โ”€ inputs/               # Form input widgets
โ”‚   โ”œโ”€โ”€ text_field.dart          # NTBTextField
โ”‚   โ”œโ”€โ”€ text_area.dart           # NTBTextArea
โ”‚   โ”œโ”€โ”€ checkbox.dart            # NTBCheckbox
โ”‚   โ”œโ”€โ”€ radio.dart               # NTBRadio
โ”‚   โ”œโ”€โ”€ switch.dart              # NTBSwitch
โ”‚   โ””โ”€โ”€ multiselect.dart         # NTBMultiselect
โ”‚
โ”œโ”€โ”€ feedback/             # User feedback widgets
โ”‚   โ”œโ”€โ”€ snackbar.dart            # NTBSnackbar
โ”‚   โ”œโ”€โ”€ alert.dart               # NTBAlert
โ”‚   โ”œโ”€โ”€ badge.dart               # NTBBadge
โ”‚   โ””โ”€โ”€ progress_indicator.dart  # NTBProgressIndicator
โ”‚
โ”œโ”€โ”€ overlays/             # Modal/overlay widgets
โ”‚   โ”œโ”€โ”€ modal.dart               # NTBModal
โ”‚   โ”œโ”€โ”€ dialog.dart              # NTBDialog
โ”‚   โ””โ”€โ”€ bottom_sheet.dart        # NTBBottomSheet
โ”‚
โ””โ”€โ”€ display/              # Display/presentation widgets
    โ”œโ”€โ”€ card.dart                # NTBCard
    โ”œโ”€โ”€ chip.dart                # NTBChip
    โ””โ”€โ”€ avatar.dart              # NTBAvatar

Category Guidelines #

Category Purpose Examples
actions/ Trigger actions or navigation Buttons, FABs, Icon buttons
inputs/ Collect user input Text fields, checkboxes, dropdowns, switches
feedback/ Show status or notifications Alerts, snackbars, badges, loading indicators
overlays/ Temporary layered UI Modals, dialogs, bottom sheets, tooltips
display/ Present information Cards, chips, avatars, list tiles

Step 1: Create Your Widget #

Create your widget in the appropriate category folder with the NTB prefix:

// lib/src/inputs/text_field.dart
import 'package:flutter/material.dart';
import '../../global/button_variant.dart';

/// A customizable text input field following NTB design standards.
class NTBTextField extends StatelessWidget {
  final String label;
  final String? hintText;
  final TextEditingController? controller;
  final NTBButtonVariant variant;

  const NTBTextField({
    super.key,
    required this.label,
    this.hintText,
    this.controller,
    this.variant = NTBButtonVariant.primary,
  });

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: controller,
      decoration: InputDecoration(
        labelText: label,
        hintText: hintText,
        border: OutlineInputBorder(),
      ),
    );
  }
}

### Step 2: Export from Main Library

Add to `lib/ntb_vistech_widgets.dart`:

```dart
library ntb_vistech_widgets;

export 'src/inputs/ntb_button.dart';
export 'src/inputs/ntb_outlined_button.dart';
export 'src/inputs/ntb_my_custom_widget.dart';  // โฌ…๏ธ Add this
export 'global/ntb_button_variant.dart';

Step 3: Create Use Cases for Widgetbook #

Create a use case file in the widgetbook directory:

// widgetbook/lib/use_cases/inputs/my_custom_widget_use_cases.dart
import 'package:flutter/material.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:ntb_vistech_widgets/ntb_vistech_widgets.dart';

// Basic use case
@UseCase(name: 'Default', type: MyCustomWidget)
Widget defaultCustomWidget(BuildContext context) {
  final label = context.knobs.string(
    label: 'Label',
    initialValue: 'My Custom Widget',
  );

  return Center(
    child: MyCustomWidget(
      label: label,
      variant: NTBButtonVariant.primary,
      onPressed: () => print('Clicked!'),
    ),
  );
}

// Use case with variants
@UseCase(name: 'Interactive', type: MyCustomWidget)
Widget interactiveCustomWidget(BuildContext context) {
  final label = context.knobs.string(
    label: 'Label',
    initialValue: 'Interactive Widget',
  );

  final variant = context.knobs.list(
    label: 'Variant',
    options: NTBButtonVariant.values,
    labelBuilder: (v) => v.name,
  );

  return Center(
    child: MyCustomWidget(
      label: label,
      variant: variant,
      onPressed: () => print('Variant: ${variant.name}'),
    ),
  );
}

Step 4: Available Knobs (Interactive Controls) #

Widgetbook provides knobs to make properties interactive:

// Text input
final text = context.knobs.string(
  label: 'Label',
  initialValue: 'Default text',
);

// Number slider
final size = context.knobs.double.slider(
  label: 'Size',
  initialValue: 16,
  min: 10,
  max: 30,
);

// Integer slider
final count = context.knobs.int.slider(
  label: 'Count',
  initialValue: 3,
  min: 1,
  max: 10,
);

// Boolean toggle
final isEnabled = context.knobs.boolean(
  label: 'Enabled',
  initialValue: true,
);

// Dropdown list
final variant = context.knobs.list(
  label: 'Variant',
  options: NTBButtonVariant.values,
  labelBuilder: (v) => v.name,
);

// Color picker
final color = context.knobs.color(
  label: 'Color',
  initialValue: Colors.blue,
);

Step 5: Generate Widgetbook Catalog #

After creating use cases, regenerate the catalog:

cd widgetbook
dart run build_runner build --delete-conflicting-outputs

What this does:

Generates widgetbook/lib/widgetbook.directories.g.dart - the widget catalog Automatically discovers all @UseCase annotations in your use case files Creates the navigation structure you'll see in Widgetbook's sidebar โš ๏ธ Important: This step is mandatory for your widgets to appear in Widgetbook!

This auto-generates:

  • widgetbook/lib/widgetbook.directories.g.dart - Widget catalog
  • Automatically discovers all @UseCase annotations

Step 6: View in Widgetbook #

flutter run -d chrome

Your widget will appear in the sidebar under the appropriate category!


๐Ÿ“ Widgetbook Project Structure #

widgetbook/
โ”œโ”€โ”€ lib/
โ”‚   โ”œโ”€โ”€ main.dart                           # Widgetbook app entry point
โ”‚   โ”œโ”€โ”€ widgetbook.dart                     # Widgetbook configuration
โ”‚   โ”œโ”€โ”€ widgetbook.directories.g.dart       # Auto-generated catalog
โ”‚   โ””โ”€โ”€ use_cases/
โ”‚       โ”œโ”€โ”€ inputs/
โ”‚       โ”‚   โ”œโ”€โ”€ ntb_button_use_cases.dart       # Button examples
โ”‚       โ”‚   โ”œโ”€โ”€ ntb_outlined_button_use_cases.dart
โ”‚       โ”‚   โ””โ”€โ”€ ntb_my_custom_widget_use_cases.dart
โ”‚       โ””โ”€โ”€ other_category/
โ”‚           โ””โ”€โ”€ ...
โ”œโ”€โ”€ pubspec.yaml                            # Widgetbook dependencies
โ””โ”€โ”€ README.md

๐ŸŽจ Use Case Best Practices #

1. Create Multiple Use Cases #

Show different states and configurations:

@UseCase(name: 'Default', type: MyWidget)
Widget defaultWidget(BuildContext context) { ... }

@UseCase(name: 'With Icon', type: MyWidget)
Widget withIconWidget(BuildContext context) { ... }

@UseCase(name: 'Disabled', type: MyWidget)
Widget disabledWidget(BuildContext context) { ... }

@UseCase(name: 'Custom Colors', type: MyWidget)
Widget customColorsWidget(BuildContext context) { ... }

2. Use Descriptive Names #

Help users find what they need:

@UseCase(name: 'Primary Button with Leading Icon', type: NTBOutlinedButton)
@UseCase(name: 'Transparent Button - No Border', type: NTBOutlinedButton)

3. Add Interactive Controls #

Let users experiment with properties:

final hasIcon = context.knobs.boolean(
  label: 'Show Icon',
  initialValue: false,
);

final iconSize = context.knobs.double.slider(
  label: 'Icon Size',
  initialValue: 24,
  min: 16,
  max: 48,
);

4. Wrap in Padding #

Give widgets breathing room:

return Center(
  child: Padding(
    padding: const EdgeInsets.all(20),
    child: MyWidget(...),
  ),
);

Keep files organized by widget type:

  • button_use_cases.dart - All Button variants
  • outlined_button_use_cases.dart - All NTBOutlinedButton variants
  • input_field_use_cases.dart - All input variants

๐Ÿ”„ Development Workflow #

# 1. Make changes to your widget in lib/
vim lib/src/inputs/ntb_my_widget.dart

# 2. Update or create use cases in widgetbook/
vim widgetbook/lib/use_cases/inputs/ntb_my_widget_use_cases.dart

# 3. Rebuild Widgetbook catalog
cd widgetbook
dart run build_runner build --delete-conflicting-outputs

# 4. Hot reload in browser to see changes
# Press 'r' in terminal or refresh browser

Watch Mode for Continuous Development #

cd widgetbook

# Start watch mode (auto-rebuilds on file changes)
dart run build_runner watch --delete-conflicting-outputs

# In another terminal, run the app
flutter run -d chrome

Now any changes to use cases will automatically rebuild the catalog!


๐Ÿ“ฆ Publishing to pub.dev #

Step-by-Step Publishing Guide #

1.Update Version Number

Follow Semantic Versioning:

# pubspec.yaml
name: ntb_vistech_widgets
version: 0.1.1 # โฌ…๏ธ Increment this
# version: 0.1.1-dev.2 # โฌ…๏ธ Or use dev suffix for prereleases

# Version format: MAJOR.MINOR.PATCH
# - MAJOR: Breaking changes
# - MINOR: New features (backwards compatible)
# - PATCH: Bug fixes

2.Update git tag and commit message to match your new version number before pushing to Bitbucket.

This keeps the repository in sync with the published version on pub.dev. #

1. Stage your pubspec, changelog, and other files related to the version bump #

git add pubspec.yaml CHANGELOG.md

2. Commit the version bump #

git commit -m "chore: bump version to 0.1.1"

3. Create a version tag (matching your pubspec version) #

git tag v0.1.1

4. Push both your code changes and the new tag to Bitbucket #

(Change 'master' to 'main' if your default branch name differs) #

git push origin master --tags

3.Run a Dry Run

Before publishing, ensure you have:

  1. โœ… A pub.dev account (sign in with Google)
  2. โœ… Verified email address on pub.dev
  3. โœ… Updated version number in pubspec.yaml
  4. โœ… Updated CHANGELOG.md with version changes
  5. โœ… All tests passing (flutter test)
  6. โœ… No analysis issues (flutter analyze)
  7. โœ… Proper package documentation
dart pub publish --dry-run

4.Publish to pub.dev

If the dry run succeeds, run the live publishing command.

โš ๏ธ Warning: Publishing is permanent. You cannot delete or overwrite a version once it is live on pub.dev.

dart pub publish

๐ŸŒ Deploy Widgetbook (Optional) #

Deploy Widgetbook as a static website for team access (to be discussed):

cd widgetbook
flutter build web --release

# Upload build/web/ to hosting:
# - TeamCity CI/CD?


๐Ÿงช Testing #

# Run tests
flutter test

# Run tests with coverage
flutter test --coverage

# View coverage report
genhtml coverage/lcov.info -o coverage/html
open coverage/html/index.html

๐Ÿค Contributing #

Adding New Widgets #

  1. Create widget in lib/src/[category]/
  2. Export from lib/ntb_vistech_widgets.dart
  3. Create use cases in widgetbook/lib/use_cases/[category]/
  4. Rebuild Widgetbook: dart run build_runner build
  5. Update CHANGELOG.md
  6. Test thoroughly
  7. Submit PR with description

### Code Style

- Follow [Effective Dart](https://dart.dev/guides/language/effective-dart) guidelines
- Run `flutter analyze` before committing
- Use meaningful variable and function names
- Add documentation comments for public APIs
- Keep widgets composable and reusable

---

## ๐Ÿ“ Changelog

See [CHANGELOG.md](CHANGELOG.md) for version history and migration guides.

---

## ๐Ÿ“„ License

MIT License - see [LICENSE](LICENSE) file for details.

---

## ๐Ÿ”— Links

- ๐Ÿ“ฆ [Pub.dev Package](https://pub.dev/packages/ntb_vistech_widgets)
- ๐Ÿ  [Repository](https://bitbucket.org/NTB-NO/ntb-smartphone-widgetbook)
- ๐Ÿ› [Issue Tracker](https://bitbucket.org/NTB-NO/ntb-smartphone-widgetbook/issues)
- ๐Ÿ“š [Widgetbook Documentation](https://docs.widgetbook.io/)

---

## ๐Ÿ™ Acknowledgments

Built with:

- [Flutter](https://flutter.dev/) - UI framework
- [Widgetbook](https://www.widgetbook.io/) - Component library tool
- [Material Design](https://material.io/) - Design system

---

Made with โค๏ธ by NTB
2
likes
0
points
724
downloads

Publisher

verified publishermediebank.dev

Weekly Downloads

NTB reusable Flutter widgets library

Repository
View/report issues

License

unknown (license)

Dependencies

collection, flutter, flutter_svg, intl, remixicon, shadcn_ui

More

Packages that depend on ntb_vistech_widgets