Code Monkey home page Code Monkey logo

flutter-neumorphic's Introduction

flutter_neumorphic

A complete, ready to use, Neumorphic ui kit for Flutter

flutter_logo

Try Flutter-Neumorphic on your browser : 👉 https://flutter-neumorphic.firebaseapp.com/ 🌐

neumorphic_playground

⚙️ Installation

https://pub.dev/packages/flutter_neumorphic

pub package pub package

dependencies:
  flutter_neumorphic: ^3.0.3

//requires flutter > 1.13.18

The in your .dart files

import 'package:flutter_neumorphic/flutter_neumorphic.dart';

🗂 Widgets

Preview Widget Description
Neumorphic The main Neumorphic Widget, a container which adds white/dark gradient depending on a lightsource and a depth
NeumorphicButton A neumorphic button that plays with the depth to respond to user interraction
NeumorphicRadio A set of neumorphic button whith only one selected at time, depending on a value and groupValue
NeumorphicCheckbox A button associated with a value, can be checked/unckecked, if checked, takes the accent color
NeumorphicText A Neumorphic text (only work with positive depth)
NeumorphicIcon A Neumorphic icon (only work with positive depth)
material.TextField For TextFields, just surround your existing material textfield widget with a Neumorphic (container)
NeumorphicSwitch An On/Off toggle, associated with a value, if toggled, takes the accent color
NeumorphicToggle An mutiple value toggle, associated with a selecteedIndex
NeumorphicSlider A Neumorphic seekbar (range slider), the user can select a value in a range
NeumorphicProgress A determinate progress, takes the displayed percentage
NeumorphicProgressIndeterminate An inderminate progress-bar
NeumorphicBackground Take the background color of the theme, can clip the screen with a borderRadius
NeumorphicApp An application that uses Neumorphic design. Handle theme, navigation, localisation, and much more
NeumorphicAppBar A Neumorphhic design app bar. Can be used inside Scaffold

👀 Showcases

Neumorphic Neumorphic

Neumorphic Neumorphic

📦 Neumorphic

Neumorphic(
  style: NeumorphicStyle(
    shape: NeumorphicShape.concave,
    boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(12)), 
    depth: 8,
    lightSource: LightSource.topLeft,
    color: Colors.grey
  ),
  child: ...
)

Neumorphic Neumorphic

☝️ Playing with LightSource & Depth

🛠️ Attributes

Attributes Values Description
LightSource TopLeft, BottomRight, etc. / (dx, dy) The source of light specifit to the theme or the widget, used to project white/dark shadows on neumorphic elements
Shape Concave / Convex / Flat The shape of the curve used in the neumorphic container
Depth -20 <= double <= 20 The distance of the widget to his parent. Can be negative => emboss. It influences on the shadow's color and its size/blur
Intensity 0 <= double <= 1 The intensity of the Light, it influences on the shadow's color
SurfaceIntensity 0 <= double <= 1 The intensity of the Surface, it influences on the concave/convex darkness
Color any Color The default color of Neumorphic elements
Accent any Color The default accent color of the Neumorphic element when activated (eg: checkbox)
Variant any Color The default secondary color of the Neumorphic element (eg: used as second color on the progress gradient)
BoxShape Circle, RoundRect(radius), Stadium, Path The box shape of a Neumorphic element. Stadium : roundrect with cirlces on each side
Border NeumorphicBorder A border (color/width) to enhance contrast with background and others elements

Neumorphic Neumorphic Neumorphic Neumorphic

🔧 Shapes

Shape Widget Image Condition
Flat depth >= 0 && shape == Flat
Convex depth >= 0 && shape == Convex
Concave depth >= 0 && shape == Concave
Emboss depth < 0

Neumorphic Text

text

Text only handle positive depth

child: NeumorphicText(
        "I love flutter",
        style: NeumorphicStyle(
          depth: 4,  //customize depth here
          color: Colors.white, //customize color here
        ),
        textStyle: NeumorphicTextStyle(
          fontSize: 18, //customize size here
          // AND others usual text style properties (fontFamily, fontWeight, ...)
        ),
    ),

Neumorphic Icon

custom_shape

child: NeumorphicIcon(
        Icons.add_circle,
        size: 80,
    ),

How to display SVG icons ?

Simply use https://fluttericon.com/ to export your svg as .ttf & use NeumorphicIcon(YOUR_ICON)

custom_shape

🎨 Custom Shape

custom_shape

Flutter Neumorphic supports custom shapes, just provide a path to

class MyShapePathProvider extends NeumorphicPathProvider {
  @override
  bool shouldReclip(NeumorphicPathProvider oldClipper) {
    return true;
  }

  @override
  Path getPath(Size size) {
    return Path()
      ..moveTo(0, 0)
      ..lineTo(size.width/2, 0)
      ..lineTo(size.width, size.height/2)
      ..lineTo(size.width/2, size.height/2)
      ..lineTo(size.width, size.height)
      ..lineTo(0, size.height)
      ..close();
  }
}

And use NeumorphicBoxShape.path

Neumorphic(
  style: NeumorphicStyle(
     boxShape: NeumorphicBoxShape.path(MyShapePathProvider()),
  ),
  ...
),

You can import the Flutter logo as a custom shape using

Neumorphic(
  style: NeumorphicStyle(
    shape: NeumorphicBoxShape.path(NeumorphicFlutterLogoPathProvider()),
  ),
  ...
),

🔲 Accessibility / Border

For design purposes, or simply to enhance accessibility, you can add a border on Neumorphic widgets

Neumorphic

Neumorphic(
      style: NeumorphicStyle(
        border: NeumorphicBorder(
          color: Color(0x33000000),
          width: 0.8,
        )
      ),
      ...
)

You can enable/disable it (eg: listening an Accessibility Provider) with isEnabled

border: NeumorphicBorder(
    isEnabled: true,
    color: Color(0x33000000),
    width: 0.8,
)

Note that borderColor and borderWidth default values has been added to NeumorphicThemeData

🎨 Neumorphic Theme

neumorphic_theme neumorphic_theme

NeumorphicTheme(
    themeMode: ThemeMode.light, //or dark / system
    darkTheme: NeumorphicThemeData(
        baseColor: Color(0xff333333),
        accentColor: Colors.green,
        lightSource: LightSource.topLeft,
        depth: 4,
        intensity: 0.3,
    ),
    theme: NeumorphicThemeData(
        baseColor: Color(0xffDDDDDD),
        accentColor: Colors.cyan,
        lightSource: LightSource.topLeft,
        depth: 6,
        intensity: 0.5,
    ),
    child: ...
)

To retrieve the current used theme :

final theme = NeumorphicTheme.currentTheme(context);
final baseColor = theme.baseColor;
final accentColor = theme.accentColor;
...

Toggle from light to dark

NeumorphicTheme.of(context).themeMode = ThemeMode.dark;

Know if using dark

if(NeumorphicTheme.of(context).isUsingDark){
  
}

NeumorphicApp

You can use direcly in your project a NeumorphicApp, surrounding your code

It handle directly NeumorphicTheme & Navigation (and all possibilities of MaterialApp )

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return NeumorphicApp(
      debugShowCheckedModeBanner: false,
      title: 'Neumorphic App',
      themeMode: ThemeMode.light,
      theme: NeumorphicThemeData(
        baseColor: Color(0xFFFFFFFF),
        lightSource: LightSource.topLeft,
        depth: 10,
      ),
      darkTheme: NeumorphicThemeData(
        baseColor: Color(0xFF3E3E3E),
        lightSource: LightSource.topLeft,
        depth: 6,
      ),
      home: MyHomePage(),
    );
  }
}

What's neumorphic

neumorphic

Material Cards

A Modern / Material (upgraded) card usually is a surface floating on top of our perceived background and casting a shadow onto it. The shadow both gives it depth and also in many cases defines the shape itself — as it’s quite often borderless.

Neumorphic cards

Neumorphic card however pretends to extrude from the background. It’s a raised shape made from the exact same material as the background. When we look at it from the side we see that it doesn’t “float”.

neumorphic_button

Here's a Nereumorphic Button tap (slowed x2) from the sample app, you can see how the element seems to change its depth to its surface.

👥 Contributors

Contributors
florent Florent Champigny
olivier Olivier Bonvila
gyl Gyl Jean Lambert
jaumard Jimmy Aumard
Overman775 Overman775
schopy schopy

📄 License

Flutter-Neumorphic is released under the Apache2 license. See LICENSE for details.

If you use the open-source library in your project, please make sure to credit and backlink to www.idean.com

bottom_banner

flutter-neumorphic's People

Contributors

ahmednfwela avatar almighty972 avatar ashank96 avatar atanascu avatar brenodt avatar chodex-xyz avatar debilobob avatar florent37 avatar giovannilattanzio avatar idean-obo avatar jaumard avatar manukj avatar michaltorma avatar miguelpruivo avatar nateshmbhat avatar nikhilmufc7 avatar overman775 avatar sami-ul avatar shankulkarni avatar tsvillain 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flutter-neumorphic's Issues

Slider / Seekbar

A progress with a selector above

named NeumorphicSeekBar ?

Capture d’écran 2020-02-26 à 09 32 29

Try to have a better design than this one ☝️

the min/max label is not part of the component !

Theme is not accessible after navigation to next page

When on the app we navigate to sub level, the theme is no more available and in some case it fire exceptions.

here a sample code:

`import 'package:flutter/material.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@OverRide
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: NeumorphicTheme(
usedTheme: UsedTheme.LIGHT,
theme: NeumorphicThemeData(
baseColor: Color(0xFFFFFFFF),
intensity: 0.5,
lightSource: LightSource.topLeft,
depth: 10,
),
darkTheme: NeumorphicThemeData(
baseColor: Color(0xFF3E3E3E),
intensity: 0.5,
lightSource: LightSource.topLeft,
depth: 6,
),
child: MyHomePage()),
);
}
}

class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);

Widget build(BuildContext context) {
return Scaffold(
backgroundColor: NeumorphicTheme.baseColor(context),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
NeumorphicButton(
margin: EdgeInsets.only(top: 12),
onClick: () {
NeumorphicTheme.of(context).usedTheme =
NeumorphicTheme.isUsingDark(context)
? UsedTheme.LIGHT
: UsedTheme.DARK;
},
style: NeumorphicStyle(shape: NeumorphicShape.flat),
boxShape: NeumorphicBoxShape.roundRect(
borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.all(12.0),
child: Text(
"Toggle Theme",
style: TextStyle(color: _textColor(context)),
)),
NeumorphicButton(
margin: EdgeInsets.only(top: 12),
onClick: () {
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (context) {
return FirstLevelPage();
}));
},
style: NeumorphicStyle(shape: NeumorphicShape.flat),
boxShape: NeumorphicBoxShape.roundRect(
borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.all(12.0),
child: Text(
"Go to child where the theme is not applyed",
style: TextStyle(color: _textColor(context)),
)),
NeumorphicButton(
margin: EdgeInsets.only(top: 12),
onClick: () {
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (context) {
return CrashLevelPage();
}));
},
style: NeumorphicStyle(shape: NeumorphicShape.flat),
boxShape: NeumorphicBoxShape.roundRect(
borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.all(12.0),
child: Text(
"Go to child it crash",
style: TextStyle(color: _textColor(context)),
)),
],
),
),
);
}

Color _textColor(BuildContext context) {
if (NeumorphicTheme.isUsingDark(context)) {
return Colors.white;
} else {
return Colors.black;
}
}
}

class FirstLevelPage extends StatelessWidget {
@OverRide
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
NeumorphicRadio(
style: NeumorphicRadioStyle(selectedDepth: 4, unselectedDepth: -4),
child: Text('I'm the first level '),
),
NeumorphicButton(
child: Icon(Icons.send),
)
],
),
);
}
}

class CrashLevelPage extends StatelessWidget {
@OverRide
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
NeumorphicRadio(
child: Text('I'm the first level '),
),
NeumorphicButton(
child: Icon(Icons.send),
)
],
),
);
}
}
`

Checkbox

multiple proposals :
Capture d’écran 2020-02-21 à 11 43 28

NeumortphicCheckbox(
      checked: true / false
      style: NeumortphicCheckboxStyle(
            //todo
      )

Vertical / horizontal Indicator

Capture d’écran 2020-02-21 à 11 06 18

Only handle EMBOSS here

NeumortphicVerticalIndicator(
      height: 200,
      width: 50,
      accent: Color(0xAAAAAA)
      style: //TODO,
      percent: 0.2 // 0 <= percent <= 1
)
NeumortphicHorizontalndicator(
      height: 50,
      width: 200,
      accent: Color(0xAAAAAA)
      style: //TODO
      percent: 0.2 // 0 <= percent <= 1
)

proposal :

NeumortphicIndicator(
      height: 50,
      width: 200,
      orientation: horizontal / vertical
      accent: Color(0xAAAAAA)
      percent: 0.2 // 0 <= percent <= 1
)

Dark Theme

Capture d’écran 2020-02-18 à 14 44 17

dark

Proposal :

NeumorphicThemeProvider(
      light: NeumorphicTheme(...)
      dark: NeumorphicTheme(...)
      darkMode: true / false,
      child: ...
)

Add a break in change label when renaming varibales

In the last version 1.0.1, some variables was renamed causing a break in the existing code.

  • Renamed CurrentTheme to UsedTheme in NeumorphicTheme (Dark, Light, System)
  • Renamed NeumorphicTheme.getCurrentTheme(context) to NeumorphicTheme.currentTheme(context)

Can you please add a tag for such change so when we read the change log we can detect them.

Thanks.

Disabled depth

I thought it could be cool to have an optional disabled/not enabled depth, rather than always 0 as of right now (in NeumorphicButton expecially).

I'd done it myself, but one question came in my mind: could a disabledDepth in NeumorphicStyle be the right way to do it?
And should it affect all components (which ones?), or NeumorphicButton only (in this case, an inner variable in this class could be better)?

p.s. Thanks for the great package: it becomes better and better every release comes up!

Tap effect flickering when Theme changes

When you change any parameter with NeumorphicTheme.of(context) (e.g. the onClick function of the Audio Player Sample, or the Color Picker in the Container section), we have this wierd effect:

theme-bug
(every flickering is a click, it's not doing it by itselft!)

It seems the old theme/color stays for a while, but after some times, the right effect is back on track

TODO : Texts

Try to reproduce a elevation / emboss effect on Texts

sample :

Text(
  'Hello, world!',
  style: TextStyle(
    shadows: <Shadow>[
      Shadow(
        offset: Offset(10.0, 10.0),
        blurRadius: 3.0,
        color: Color.fromARGB(255, 0, 0, 0),
      ),
      Shadow(
        offset: Offset(10.0, 10.0),
        blurRadius: 8.0,
        color: Color.fromARGB(125, 0, 0, 255),
      ),
    ],
  ),
),

find a way to generate it to the user

  • a method that generate shadows ?
  • a NeumorphicText ?

TODO : Handle rotation

add a rotation (Z) to any Neumorphic element

because : we need to rotate the lightsource on -Z

Its possible to choose color ?

Hi, its possible to choose the color of the shadows?
For example:

Neumorphic(
            style: NeumorphicStyle(
              firstColor: Colors.white, <----
              secondColor: Colors.black, <----
            ),
            boxShape: NeumorphicBoxShape.circle(), 
            child: Icon(Icons.star_border, size: 17, color: Theme.of(context).accentColor)
)

Slider colour leak at extremes

When I use the Slider widget it looks visually find unless I slide it to the extremes on the right and left

In the middle - no issue
image

When at the left extreme
Screenshot 2020-04-01 at 21 24 22

When at the right extreme
Screenshot 2020-04-01 at 21 24 31

Happy to provide some code for this if needed :)

I am running beta, v1.15.17 and on iPhone simulator

Progress

Capture d’écran 2020-02-21 à 15 31 21

NeumorphicProgress(
     height: 10,
     //width from parent
     percent: 0.3,   //from 0 to 1
     style: ...
)

Only available in FLAT or EMBOSS

the bubble is not in the widget IMO

[ NeumorphicButton ] Graphic bug when switching from portrait to landscape

First of all, thank you for your work !

When I switch from portrait to landscape or from landscape to portrait, the button does not rebuild as expected until I click on it. Here are some screenshots :

The behavior is the same if I start from landscape and switch to portrait, buttons are not rebuild correctly. But if I do :

  • portrait -> landscape -> portrait, without clicking, in portrait button looks as expected
  • landscape -> portrait -> landscape, without clicking, in landscape button looks as expected

This bug also happens in both platforms.

I stay around if you need more infos !

Radio

Buttons that move from convex/concave/flat to emboss

T _groupValue = ...;

Widget build(BuildContext context) {
    return Row(
        children: [
            NeumorphicRadio(
                value: VALUE_1,
                groupValue: _groupValue,
                onChanged: (T value) {
                    setState(() { _groupValue = value; });
                },
            ),
            NeumorphicRadio(
                value: VALUE_2,
                groupValue: _groupValue,
                onChanged: (T value) {
                    setState(() { _groupValue = value; });
                },
            ),
        ]
    )
}

inspired from https://api.flutter.dev/flutter/material/Radio-class.html

Capture d’écran 2020-02-24 à 14 25 12

TODO : TextField

Capture d’écran 2020-02-21 à 11 06 13

proposals :

  1. use the real TextField
TextField(
  decoration: NeumortphicDecoration(
    //TODO
  ),
);
  1. create a widget
NeumortphicTextField(
      //TODO
)

Shadow bad rendering

Hello and thank you for your awesome work!

Just tried your package and I have an issue on web, shadow seems to be cropped.
I made a compare between your sample hosted on my computer and your sample hosted on firebase. (Flutter 1.15.17)

You can see that bottom and right side are cropped :/

image

image

Did I miss something ?

Thank you !

Publish the 1.0.0

  • define the scope
  • fill the README.md
  • fill the example/README.md
  • fille the CHANGELOG.md

SquareButton

possible name : NeumorphicRatioButton ?

a button that have the same witdh / height

Capture d’écran 2020-02-26 à 09 37 14

Add a border ?

tesla1_2x

In this sample here we have a border, try to add it into the shape ?

[1.0.3+1] Button box shape radius not correctly rendering

If we specify a custom boxshape radius, this one is not correctly applied.

`NeumorphicButton(
padding: EdgeInsets.all(8),
onClick: () {

          },
          style: NeumorphicStyle(
            shape: NeumorphicShape.concave,
            depth: 5,
          ),
          boxShape: NeumorphicBoxShape.roundRect(
              borderRadius:
                  BorderRadius.only(bottomLeft: Radius.circular(12))
              // BorderRadius.only(
              //     topLeft: Radius.circular(12),
              //     bottomLeft: Radius.circular(12),
              //     topRight: Radius.circular(0),
              //     bottomRight: Radius.circular(0))
              ),
          child: Icon(
            Icons.stop,
          ),
        ),`

If we set the top left corner, this one is applied for all the borders.
if we set other corner, the button is rendered as a rectangle.

The idea is to be able to create a grouped button options.

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.