Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add gradient border support for Button and FilledButton #956

Merged
merged 13 commits into from
Nov 2, 2023
Merged

Add gradient border support for Button and FilledButton #956

merged 13 commits into from
Nov 2, 2023

Conversation

Ferry-200
Copy link
Contributor

@Ferry-200 Ferry-200 commented Oct 28, 2023

This pr is for #920.

I am creating a new class called RoundedRectangleGradientBorder , which extends the ShapeBorder class in package: flutter/painting.dart. You can use it wherever RoundedRectangleBorder can be used.

This class is similar to the original RoundedRectangleBorder class, except that I changed side to gradient, width and strokeAlign. At the same time I override the paint method and assign gradient to paint.shader to draw a gradient border.

I am not familiar with the structure of your project, so I put the different border style in the rounded_rectangle_gradient_border.dart file. The style is copied from Windows UI 3.

In my test, it works like this:
buttons

The WindowsUI 3 in Figma Windows UI 3:
buttons in figma

The test code is:

Material(
      color: const Color.fromRGBO(0, 95, 184, 1.0),
      shape: const RoundedRectangleGradientBorder(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [
            Color.fromRGBO(255, 255, 255, 0.08),
            Color.fromRGBO(0, 0, 0, 0.40)
          ],
          stops: [0.90, 1.0],
        ),
        borderRadius: BorderRadius.all(Radius.circular(4.0)),
        width: 1.0,
      ),
      child: InkWell(
        onTap: () {},
        borderRadius: BorderRadius.circular(4.0),
        child: const Row(
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          children: [
            Padding(
              padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
              child: Text(
                "Button",
                style: TextStyle(color: Colors.white, fontSize: 14.0),
              ),
            ),
          ],
        ),
      ),
    )

Pre-launch Checklist

  • I have updated CHANGELOG.md with my changes
  • I have run "dart format ." on the project
  • I have added/updated relevant documentation

I create a new class named `RoundedRectangleGradientBorder`, which extends `ShapeBorder` class in package: flutter/painting.dart.

This class draws on the original `RoundedRectangleBorder` class, only changing ‘side’ to ‘gradient’, ‘width’, and ‘strokeAlign’. At the same time, I also override the `paint` method, assigning ‘gradient’ to ‘paint.shader’ to draw a gradient border.

I am not familiar with your project's structure, so I put the different border style in the file `rounded_rectangle_gradient_border.dart`. The style is copy from [Windows UI 3](https://www.figma.com/community/file/1159947337437047524/windows-ui-3).
@bdlukaa
Copy link
Owner

bdlukaa commented Oct 28, 2023

This is awesome! I'd love to work on this, do you mind if I commit to your branch?

This is an awesome start, but some things need to be addressed:

  • Documentation
    This is a Flutter-Favorite package, which means we need to maintain a proper inline documentation on classes
  • Theme colors
    One app can have different colors: light, dark and high constrast. The border must adapt to the current theme mode and data.

@Ferry-200
Copy link
Contributor Author

Never mind.
For the documentation, I think that draw on the documemtation of RoundedRectangleBorder is good.
As for the theme colors, I will try to list them later. Just copy from the project of Figma.

@Ferry-200
Copy link
Contributor Author

Ferry-200 commented Oct 28, 2023

Copy from Windows UI 3
They can be found at page "Basic Input".

Light Mode

FilledButton

  1. Rest AccentControlBorder
    LinearGradient
    colors: [(255, 255, 255, 0.08), (0, 0, 0, 0.40)]
    stops: [0.90, 1.0]
  2. Hovered
    same with Rest
  3. Pressed ControlStrokeOnAccentDefault
    color with opacity
    color: (255, 255, 255, 0.08)
  4. Disabled
    None

Button

  1. Rest ControlBorder
    LinearGradient
    colors: [(0 ,0, 0, 0.0578), (0, 0, 0, 0.1622)]
    stops: [0.90, 1.0]
  2. Hovered
    same with Rest
  3. Pressed ControlStrokeDefault
    color with opacity
    color: (0, 0, 0, 0.0578)
  4. Disabled
    same with Pressed

Dark Mode

FilledButton

  1. Rest AccentControlBorder
    LinearGradient
    colors: [(255, 255, 255, 0.08), (0, 0, 0, 0.14)]
    stops: [0.90, 1.0]
  2. Hovered
    same with Rest
  3. Pressed ControlStrokeOnAccentDefault
    color with opacity
    color: (255, 255, 255, 0.08)
  4. Disabled
    None

Button

  1. Rest ControlBorder
    LinearGradient
    colors: [(255, 255, 255, 0.093), (255, 255, 255, 0.0698)] // strange... why need gradient
    stops: [0, 0.10]
  2. Hovered
    same with Rest
  3. Pressed ControlStrokeDefault
    color with opacity
    color: (0, 0, 0, 0.0698)
  4. Disabled
    same with Pressed

…on, works. prodused a small bug in ToggleButton

* Add `style` property. Same with `RoundedRectangleBorder`, used `BorderStyle.solid` as default. To omit the border, use `BorderStyle.none`.
* in `base.dart`, `_BaseButtonState`, `build` method: Remove `resolvedBorder`. Because we don't need `BorderSide` in `RoundedRectangelGradientBorder`; Change `OutlinedBorder` to `ShapeBorder` so it can support `RoundedRectangelGradientBorder`;
* in `color_resources.dart`. Add `controlBorderGradient`, `accentControlBorderGradient`. The first is used by Button when rest or hover, while the second is used by FilledButton when rest or hover; When they're disabled or pressed, the gradient change to color with opacity. With that change, it looks like being pressed in Light Mode. In Dark Mode, the gradient is just like normol color with opacity. It seems that we don't neet apply gradient border when Dark Mode is used.
* These changes are test in example app. Work as thought. **I modified the `lerp` method in `ButtonStyle` by simply changing `OutlinedBorder` to `RoundedRectangleGradientBorder`. I don't kown how it works, so I can't test it. I am not sure it will work.**
* **Changes in `Button` produses a bug in `ToggleButton`. When state change between pressed and rest, the high changed. It seems to use different border when state changes, I couldn't find where the style set, so I don't kown how to fix it.**
@Ferry-200
Copy link
Contributor Author

Just now I added a commit with many changes. I am trying to enable gradient border in Button and FilledButton. It works as thought.
image

Unfortunately, it produse a bug in ToggleButton. When press it, it height changes. Look like it uses different border in different state. I don't kown where it is, so I don't know how to fix it.

@bdlukaa bdlukaa linked an issue Nov 1, 2023 that may be closed by this pull request
@bdlukaa
Copy link
Owner

bdlukaa commented Nov 1, 2023

Hey @Ferry-200! Thank you so much for this PR, it is really good.

I commit a few changes, please tell me if there's anything you want to change. Thank you, looking forward to it

@Ferry-200
Copy link
Contributor Author

Hello @bdlukaa , I think there's nothing need to change. Thank you so much for these commit. I learned very much. By the way, I wonder that how do you think about this minor break. Is it easy to migrate?

@bdlukaa
Copy link
Owner

bdlukaa commented Nov 2, 2023

yes, it actually is! I added a migration guide on the changelog.

@bdlukaa bdlukaa merged commit 8728eec into bdlukaa:master Nov 2, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

🐛 Buttons miss bottom border accent
2 participants