skip to Main Content

I have a class, and I want to access the members of some enum through it, in favor of encapsulation and convenience. i.e: I wouldn’t like the client code to have to import and directly deal with the enums.

So, ideally, I would like have something like this in the client code:

print(DesignSystem.colors.white);
print(DesignSystem.spacings.xs);

Right now I have achieved what I want doing the following, but it feels kind of cumbersome:

enum Color {
  black(value: '#000000'),
  white(value: '#FFFFFF');
 
  final String value;
  
  const Color({required this.value});
 }

class _Colors {
  final Color black = Color.black;
  final Color white = Color.white;
}

enum Spacing {
  xs(value: 5),
  sm(value: 10);
 
  final int value;
  
  const Spacing({required this.value});
}

class _Spacings {
  final Spacing xs = Spacing.xs;
  final Spacing sm = Spacing.sm;
}

class DesignSystem {
  static final _Colors colors = _Colors();
  static final _Spacings spacings = _Spacings();
  
}

So is there any other way that I might be missing? I’ve tried to directly assign the enum classes as class variables of DesignSystem but it doesn’t seem to be possible in Dart.

2

Answers


  1. In Dart, you cannot directly assign enum classes as static class variables because enums are not instantiated in the same way regular classes are. However, your current approach, where you’re encapsulating the enums in a separate class (_Colors and _Spacings), is a reasonable one to achieve encapsulation and convenience. You can use like this:

        enum Color {
      black(value: '#000000'),
      white(value: '#FFFFFF');
      
      final String value;
      
      const Color({required this.value});
    }
    
    enum Spacing {
      xs(value: 5),
      sm(value: 10);
      
      final int value;
      
      const Spacing({required this.value});
    }
    
    class DesignSystem {
      // Directly expose the enum values through static access.
      static final Color black = Color.black;
      static final Color white = Color.white;
      
      static final Spacing xs = Spacing.xs;
      static final Spacing sm = Spacing.sm;
    }
    
    void main() {
      print(DesignSystem.white.value);  // #FFFFFF
      print(DesignSystem.xs.value);     // 5
    }
    
    Login or Signup to reply.
  2. It is not currently possible to declare a type as a nested member of another type, so what you are doing is unfortunately the only real way to accomplish this.

    There’s a more efficient way, though, by using collection classes instead of enums and using constants instead of instance variables.

    class Color {
      final String value;
    
      const Color(this.value);
    }
    
    class ColorCollection {
      static const instance = ColorCollection._();
    
      const ColorCollection._();
    
      final black = const Color('#000000');
      final white = const Color('#FFFFFF');
    }
    
    class DesignSystem {
      static ColorCollection get colors => ColorCollection.instance;
    }
    
    void main() {
      final black = DesignSystem.colors.black;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search