Logo-amall

feat: Color knobs

Last active 1 months ago

3 replies

7 views

  • MB

    Proposal: knobs for colors
    Description
    As a developer, I want to be able to leverage knobs to specify a Widget's constructor parameter of type Color. The API can be reminiscent of other knobs:
    Icon(
    Icons.thumbsupsharp,
    color: context.knobs.color(
    label: 'Color of the icon'
    initialValue: Colors.red,
    ),
    )
    The signature of the color method (inside KnobsBuilder) can be:
    bool color({
    required String label,
    String? description,
    Color? initialValue,
    });
    In terms of how the knob would reflect on the UI, it can use something like this open source package https://pub.dev/packages/flutter_colorpicker, or perhaps a custom implementation. But the gist is that users would be able to change the color of a widget using knobs.
    Rate the proposal
    Make sure to hit 👍🏻 if you'd like to see this implemented soon.
    Make sure to hit 👎🏻 if you think this proposal is a bad idea.

  • MB

    If anyone else is looking for a similar functionality in the meantime, this workaround is possible:
    const _kFallbackColor = 0xFFFF0000;

    extension on String {
    Color asColor() {
    if (length != 7) {
    return const Color(_kFallbackColor);
    }
    return Color(int.tryParse(replaceFirst('#', '0xFF')) ?? _kFallbackColor);
    }
    }

    extension on Color {
    String get hexString =>
    '#${value.toRadixString(16).substring(2, 8).toUpperCase()}';
    }

    Color colorKnob(
    BuildContext context, {
    required String label,
    required Color initialValue,
    }) {
    return context.knobs
    .text(
    label: label,
    description: "Must be a valid hexadecimal color prefixed with '#'. "
    "Defaults to a red color if the value can't be parsed.",
    initialValue: initialValue.hexString,
    )
    .asColor();
    }
    The colorKnob function can be used as follows:
    WidgetbookUseCase(
    name: 'elevated',
    builder: (context) => Icon(
    Icons.thumbupsharp,
    color: colorKnob(
    context,
    label: 'Color',
    initialValue: Colors.blue,
    ),
    ),
    ),
    Unfortunately you can't use an extension to make the API more reminscent of the other knobs (i.e context.knobs.color), since the KnobsBuilder is an abstract class and dart doesn't support extensions on abstract classes.
    The results:

  • JE

    Love the proposal! I'll add some requirements so that we can start with the implementation. We already got a basic color knob implemented but it's not yet feature complete.

    Requirements

    Color spaces

    The following color spaces should be supported:

    • Support for hexadecimal colors (including alpha value)
      • Input validation
      • [Optional] Color picker (should not depend on additional packages)
    • Support for RGBA (RGB + Alpha value)
      • Input validation
      • [Optional] Color picker (should not depend on additional packages)
    • Support for HSL (Hue, Saturation, Lightness)
      • Input validation
      • [Optional] Color picker (should not depend on additional packages

    Preview

    A small color preview would be nice (see figma screenshot)

    Testing

    • 100% test coverage for the whole widget

    Design

    • Should be based on Material 3

    Usage

    Icon(
      Icons.thumbs_up_sharp,
      color: context.knobs.color(
        label: 'Color of the icon'
        initialValue: Colors.red,
        initialColorSpace: ColorSpace.rgba,
      ),
    )
    

    Parameters:
    | Property | Description | Required | Default value |
    |-------------------|------------------------------------------------------------------|----------|----------------|
    | label | Unique label, used to update the knob | Yes | - |
    | initialValue | The color that is preselected, when the use-case is loaded | Yes | - |
    | initialColorSpace | The color space that is preselected, when the use-case is loaded | No | ColorSpace.hex |
    | description | The description of what the knob is doing | No | - |

Last active 1 months ago

3 replies

7 views