โจ sDesign - Flutter UI Component Library ๐
sDesign is a powerful Flutter UI component library designed to help developers craft stunning, consistent, and professional user interfaces with minimal effort. Featuring widgets like SScaffold
, SButton
, SCheckbox
, and SSonner
, itโs your go-to toolkit for building polished, responsive apps! ๐
๐ Installing ๐ฆ
Add sDesign to your Flutter project:
dependencies:
s_design: ^0.3.2+1
โก๏ธ Import
import 'package:s_design/s_design.dart';
๐ฎ Getting Started with SScaffold ๐๏ธ
The SScaffold
widget is a supercharged version of Flutterโs Scaffold
, offering advanced features like pull-to-refresh ๐, loading states with shimmer effects โณ, customizable floating action buttons ๐ ๏ธ, and drawers ๐. It simplifies building complex, user-friendly layouts.
Example: SScaffold with SButton, SCheckbox, and SSonner ๐
import 'package:flutter/material.dart';
import 'package:s_design/s_design.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final myOverlays = [
OverlayEntry(
builder: (overlayContext) {
WidgetsBinding.instance.addPostFrameCallback((_) {
final overlay = Overlay.of(overlayContext);
SSonner.instance.initialize(overlay);
SToast.initialize(overlay);
});
return const SizedBox.shrink();
},
),
];
return MaterialApp(
builder: sOverlayBuilder(overlays: myOverlays),
home: SScaffold(
appBar: AppBar(
title: const Text('sDesign Showcase ๐'),
backgroundColor: Colors.teal,
),
renderBody: (context) => SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'SCheckbox & SButton Demo',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Row(
children: [
SCheckbox(
value: SCheckboxState.unchecked,
onChanged: (state) => print('Checkbox: $state โ
'),
size: 24.0,
activeColor: Colors.teal,
checkColor: Colors.white,
intermediate: true,
),
const SizedBox(width: 10),
const Text('Custom Checkbox'),
],
),
const SizedBox(height: 20),
SButton(
onPressed: () {
SSonner.instance.show(
message: 'Success! Action completed! ๐',
type: SSonnerType.success,
duration: const Duration(seconds: 3),
);
},
child: const Text('Show Success Sonner ๐ข'),
variant: SButtonVariant.primary,
size: SButtonSize.lg,
icon: const Icon(Icons.check_circle),
),
const SizedBox(height: 20),
SButton(
onPressed: () {
SToast.show(
title: 'Hello!',
description: 'This is a default toast. ๐',
);
},
child: const Text('Show Default Toast ๐'),
variant: SButtonVariant.secondary,
),
],
),
),
scrollable: true,
refreshConfig: RefreshConfig(
enabled: true,
onRefresh: () async => await Future.delayed(const Duration(seconds: 2)),
indicatorColor: Colors.teal,
animationType: RefreshAnimationType.standard,
),
floatingActionButtonConfig: FloatingActionButtonConfig(
floatingActionButton: FloatingActionButton(
onPressed: () => print('FAB Pressed! ๐ ๏ธ'),
child: const Icon(Icons.add),
backgroundColor: Colors.teal,
),
),
backgroundColor: Colors.grey[100],
),
);
}
}
Example: SCheckbox Showcase with SScaffold โ
import 'package:flutter/material.dart';
import 'package:s_design/s_design.dart';
class CheckboxPage extends StatefulWidget {
const CheckboxPage({super.key});
@override
State<CheckboxPage> createState() => _CheckboxPageState();
}
class _CheckboxPageState extends State<CheckboxPage> {
SCheckboxState _defaultCheckboxState = SCheckboxState.unchecked;
SCheckboxState _customColoredCheckboxState = SCheckboxState.unchecked;
SCheckboxState _largeStyledCheckboxState = SCheckboxState.unchecked;
final SCheckboxState _disabledCheckboxState = SCheckboxState.unchecked;
SCheckboxState _indeterminateCheckboxState = SCheckboxState.unchecked;
@override
Widget build(BuildContext context) {
return SScaffold(
appBar: AppBar(
title: const Text('SCheckbox Showcase ๐'),
backgroundColor: Colors.teal,
),
renderBody: (context) => SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Default Checkbox'),
Row(
children: [
SCheckbox(
value: _defaultCheckboxState,
onChanged: (newState) => setState(() => _defaultCheckboxState = newState),
),
const SizedBox(width: 10),
const Text('Default Checkbox โ
'),
],
),
const Divider(height: 40),
_buildSectionTitle('Custom Colored Checkbox'),
Row(
children: [
SCheckbox(
value: _customColoredCheckboxState,
onChanged: (newState) => setState(() => _customColoredCheckboxState = newState),
size: 24.0,
activeColor: Colors.green,
checkColor: Colors.white,
borderColor: Colors.green,
),
const SizedBox(width: 10),
const Text('Custom Colored Checkbox ๐'),
],
),
const Divider(height: 40),
_buildSectionTitle('Large Styled Checkbox'),
Row(
children: [
SCheckbox(
value: _largeStyledCheckboxState,
onChanged: (newState) => setState(() => _largeStyledCheckboxState = newState),
size: 30.0,
activeColor: Colors.blue,
checkColor: Colors.yellow,
borderColor: Colors.blueAccent,
),
const SizedBox(width: 10),
const Text('Large Styled Checkbox ๐'),
],
),
const Divider(height: 40),
_buildSectionTitle('Disabled Checkbox'),
Row(
children: [
SCheckbox(
value: _disabledCheckboxState,
onChanged: null,
size: 24.0,
activeColor: Colors.grey,
checkColor: Colors.white,
borderColor: Colors.grey,
isDisabled: true,
),
const SizedBox(width: 10),
const Text('Disabled Checkbox ๐'),
],
),
const Divider(height: 40),
_buildSectionTitle('Determinate Checkbox'),
Row(
children: [
SCheckbox(
intermediate: false,
value: _indeterminateCheckboxState,
onChanged: (newState) => setState(() => _indeterminateCheckboxState = newState),
size: 24.0,
activeColor: Colors.orange,
checkColor: Colors.white,
borderColor: Colors.orange,
),
const SizedBox(width: 10),
const Text('Determinate Checkbox โ๏ธ'),
],
),
],
),
),
scrollable: true,
backgroundColor: Colors.grey[100],
);
}
Widget _buildSectionTitle(String title) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
title,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
);
}
}
Example: SButton Showcase with SScaffold ๐จ
import 'package:flutter/material.dart';
import 'package:s_design/s_design.dart';
class ButtonPage extends StatefulWidget {
const ButtonPage({super.key});
@override
State<ButtonPage> createState() => _ButtonPageState();
}
class _ButtonPageState extends State<ButtonPage> {
bool _isLoading = false;
bool _isEnabled = true;
void _toggleLoading() => setState(() => _isLoading = !_isLoading);
void _toggleEnabled() => setState(() => _isEnabled = !_isEnabled);
@override
Widget build(BuildContext context) {
return SScaffold(
appBar: AppBar(
title: const Text('SButton Showcase ๐จ'),
backgroundColor: Colors.teal,
),
renderBody: (context) => SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Variants', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Wrap(spacing: 10, runSpacing: 10, children: [
SButton(onPressed: () {}, child: const Text('Default')),
SButton(variant: SButtonVariant.destructive, onPressed: () {}, child: const Text('Destructive')),
SButton(variant: SButtonVariant.secondary, onPressed: () {}, child: const Text('Secondary')),
SButton(variant: SButtonVariant.outline, onPressed: () {}, child: const Text('Outline')),
SButton(variant: SButtonVariant.destructiveOutline, onPressed: () {}, child: const Text('Destructive Outline')),
SButton(variant: SButtonVariant.ghost, onPressed: () {}, child: const Text('Ghost')),
SButton(variant: SButtonVariant.link, onPressed: () {}, child: const Text('Link')),
]),
const Divider(height: 40),
const Text('Sizes', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Wrap(spacing: 10, runSpacing: 10, children: [
SButton(size: SButtonSize.sm, onPressed: () {}, child: const Text('Small')),
SButton(onPressed: () {}, child: const Text('Default')),
SButton(size: SButtonSize.lg, onPressed: () {}, child: const Text('Large')),
SButton(size: SButtonSize.icon, onPressed: () {}, icon: const Icon(Icons.thumb_up)),
]),
const Divider(height: 40),
const Text('States', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Wrap(spacing: 10, runSpacing: 10, children: [
SButton(onPressed: _toggleLoading, child: Text(_isLoading ? 'Stop Loading' : 'Start Loading')),
SButton(loading: _isLoading, onPressed: () {}, child: const Text('Loading')),
SButton(state: SButtonState.enabled, onPressed: () {}, child: const Text('Enabled')),
SButton(state: SButtonState.disabled, onPressed: () {}, child: const Text('Disabled')),
SButton(
state: _isEnabled ? SButtonState.enabled : SButtonState.disabled,
onPressed: _isEnabled ? () {} : null,
child: Text(_isEnabled ? 'Enabled' : 'Disabled'),
),
SButton(onPressed: _toggleEnabled, child: Text(_isEnabled ? 'Disable Button' : 'Enable Button')),
]),
const Divider(height: 40),
const Text('With Icons', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Wrap(spacing: 10, runSpacing: 10, children: [
SButton(icon: const Icon(Icons.add), onPressed: () {}, child: const Text('Add')),
SButton(variant: SButtonVariant.destructive, icon: const Icon(Icons.delete), onPressed: () {}, child: const Text('Delete')),
SButton(variant: SButtonVariant.secondary, icon: const Icon(Icons.edit), onPressed: () {}, child: const Text('Edit')),
SButton(size: SButtonSize.icon, icon: const Icon(Icons.favorite), onPressed: () {}),
]),
const Divider(height: 40),
const Text('Custom Themed Buttons', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Wrap(spacing: 10, runSpacing: 10, children: [
SButton(backgroundColor: const Color.fromARGB(170, 98, 25, 187), onPressed: () {}, child: const Text('Background Color')),
SButton(
buttonStyle: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.black),
foregroundColor: WidgetStateProperty.all(Colors.white),
elevation: WidgetStateProperty.all(5),
),
onPressed: () {},
child: const Text('Custom Styling'),
),
]),
],
),
),
scrollable: true,
backgroundColor: Colors.grey[100],
);
}
}
๐ Key Components in sDesign ๐ ๏ธ
SScaffold ๐๏ธ
A robust wrapper around Flutterโs Scaffold
with:
- Pull-to-Refresh ๐: Supports standard or custom animations via
refreshConfig
. - Loading States โณ: Shimmer effects and custom indicators with
loadingConfig
. - Floating Action Buttons ๐ ๏ธ: Flexible FAB placement and animations.
- Drawers & Footers ๐๐ฆถ: Side drawers and persistent footers for seamless navigation.
SButton ๐จ
A versatile button widget with:
- Variants:
primary
,secondary
,outline
,destructive
,ghost
,link
. - Sizes:
sm
,default
,lg
,icon
. - States:
enabled
,disabled
,loading
. - Customizations: Icons, custom dimensions, colors, and animations.
SCheckbox โ
A flexible checkbox supporting:
- Two or Three States:
checked
,unchecked
, and optionalindeterminate
. - Customizations: Size, active color, check color, border color, and disabled state.
- Animations: Smooth transitions for state changes.
SSonner ๐ข
A toast notification system with:
- Variants:
success
,info
,error
, etc. - Customizations: Position, duration, background color, and icons.
- Queue Management: Displays toasts sequentially with smooth animations.
๐ Showcase ๐ธ
![]() Sample View ๐ |
SButton ๐จ |
SCheckbox โ |
SSonner ๐ข |
๐ Bugs & Feature Requests ๐ ๏ธ
Found a bug or have a feature idea? Open an issue on GitHub. Pull requests are warmly welcomed! ๐
โ Note
New to Flutter? Dive into the Flutter documentation for a smooth start.
โ๏ธ Authors ๐จโ๐ป
|
โญ License ๐
MIT License