mn_loc 1.0.0 copy "mn_loc: ^1.0.0" to clipboard
mn_loc: ^1.0.0 copied to clipboard

A Flutter package for 3-level dependent dropdowns (District -> Subdivision -> Circle) loaded directly from JSON data.

๐Ÿ“ mn_loc โ€” Dependent Dropdowns from JSON #

pub package License: MIT Flutter Platform

A modern, highly customizable Flutter package for 3-level dependent dropdown selections (District โž” Subdivision โž” Circle) loaded directly from JSON files (district.json, subdivision.json, circle.json).


๐ŸŽฏ Key Design Philosophy: Individual Standalone Widgets #

Important

No Monolithic Single-Widget Wrappers! Unlike traditional packages that force all dropdowns into one fixed container, mn_loc provides unwrapped, standalone individual widgets:

  • <DistrictDropdown />
  • <SubdivisionDropdown />
  • <CircleDropdown />

You can place each widget anywhere in your UI tree โ€” across different cards, grid columns, form tabs, or stepper screens. They reactively sync state through LocationDropdownProvider.


โœจ Features #

  • ๐Ÿงฉ 100% Modular & Unwrapped: Place District, Subdivision, and Circle dropdowns anywhere in your layout.
  • โšก Reactive Auto-Dependencies: Selecting a District automatically updates Subdivisions and resets Circle selections.
  • ๐Ÿ“ JSON Asset & Raw String Support: Built-in JSON loader (LocationJsonService) for asset paths, raw JSON strings, or direct model lists.
  • ๐ŸŽจ Material 3 Design: Supports theme customization, custom input decorations, custom item builders, icons, and disabled states.
  • ๐Ÿงน Clean State Management: Built with provider (ChangeNotifier).

๐Ÿš€ Getting Started #

Add mn_loc to your pubspec.yaml:

dependencies:
  mn_loc: ^1.0.0
  provider: ^6.1.2

Ensure your pubspec.yaml includes the location JSON assets:

flutter:
  assets:
    - assets/data/district.json
    - assets/data/subdivision.json
    - assets/data/circle.json

๐Ÿ’ป Usage Guide #

1. Register LocationDropdownProvider #

Wrap your root widget or screen with MultiProvider or ChangeNotifierProvider:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:mn_loc/mn_loc.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => LocationDropdownProvider()..initialize(),
        ),
      ],
      child: const MyApp(),
    ),
  );
}

2. Place Dropdown Widgets Independently #

Each widget connects automatically to LocationDropdownProvider:

import 'package:flutter/material.dart';
import 'package:mn_loc/mn_loc.dart';

class LocationFormPage extends StatelessWidget {
  const LocationFormPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Location Form')),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            // 1. District Dropdown Widget
            const DistrictDropdown(
              label: 'District',
              hint: 'Choose a district...',
            ),
            const SizedBox(height: 16),

            // 2. Subdivision Dropdown Widget (Auto-disabled until District is chosen)
            const SubdivisionDropdown(
              label: 'Subdivision',
              hint: 'Choose a subdivision...',
              disabledHint: 'Select District first',
            ),
            const SizedBox(height: 16),

            // 3. Circle Dropdown Widget (Auto-disabled until Subdivision is chosen)
            const CircleDropdown(
              label: 'Circle',
              hint: 'Choose a circle...',
              disabledHint: 'Select Subdivision first',
            ),
            const SizedBox(height: 24),

            // Display current selection summary card
            const LocationSummaryCard(),
          ],
        ),
      ),
    );
  }
}

๐Ÿ“‹ JSON Schema Specification #

district.json #

[
  { "id": "d_01", "name": "Imphal West", "code": "IW" },
  { "id": "d_02", "name": "Imphal East", "code": "IE" }
]

subdivision.json #

[
  { "id": "s_01", "district_id": "d_01", "name": "Lamphelpat" },
  { "id": "s_02", "district_id": "d_01", "name": "Patsoi" }
]

circle.json #

[
  { "id": "c_01", "subdivision_id": "s_01", "name": "Lamphel Circle I" },
  { "id": "c_02", "subdivision_id": "s_01", "name": "Lamphel Circle II" }
]

๐Ÿ” Accessing Selected Data #

Access selections reactively anywhere in your code using Provider:

final provider = context.watch<LocationDropdownProvider>();

final DistrictModel? district = provider.selectedDistrict;
final SubdivisionModel? subdivision = provider.selectedSubdivision;
final CircleModel? circle = provider.selectedCircle;

print('District ID: ${district?.id}, Name: ${district?.name}');
print('Subdivision ID: ${subdivision?.id}, Name: ${subdivision?.name}');
print('Circle ID: ${circle?.id}, Name: ${circle?.name}');

To reset selections programmatically:

context.read<LocationDropdownProvider>().resetSelections();

๐Ÿ› ๏ธ API Reference #

DistrictDropdown #

Parameter Type Default Description
label String? 'District' Input decoration field label.
hint String 'Select District' Placeholder text.
decoration InputDecoration? null Custom input decoration.
onChanged ValueChanged<DistrictModel?>? null Optional selection change listener callback.
itemBuilder Widget Function(...) null Custom dropdown item builder widget.

SubdivisionDropdown #

Parameter Type Default Description
label String? 'Subdivision' Input decoration field label.
hint String 'Select Subdivision' Placeholder text when enabled.
disabledHint String 'Select District First' Placeholder text when parent district is not selected.
onChanged ValueChanged<SubdivisionModel?>? null Selection change listener.

CircleDropdown #

Parameter Type Default Description
label String? 'Circle' Input decoration field label.
hint String 'Select Circle' Placeholder text when enabled.
disabledHint String 'Select Subdivision First' Placeholder text when parent subdivision is not selected.
onChanged ValueChanged<CircleModel?>? null Selection change listener.

๐Ÿ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.

0
likes
0
points
21
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package for 3-level dependent dropdowns (District -> Subdivision -> Circle) loaded directly from JSON data.

Repository (GitHub)
View/report issues

Topics

#dropdown #dependent-dropdown #location #json #provider

License

unknown (license)

Dependencies

dio, flutter, go_router, google_fonts, provider

More

Packages that depend on mn_loc