ProductiveRage / Bridge.React

Bindings for Bridge.NET for React - write React applications in C#!
MIT License
74 stars 14 forks source link

Best approach to map associative arrays to C# #60

Closed kendallb closed 5 years ago

kendallb commented 5 years ago

I am trying to build custom mappings for React Modal, and I am not clear on how to map this interface from Typescript:

    interface Styles {
        content?: {
            [key: string]: any;
        };
        overlay?: {
            [key: string]: any;
        };
    }

The way the Retyped mappings are generated is rather odd and I am not sure what the IObject interface is all about and how we can write this in a cleaner manner for a custom binding? Any suggestions on a cleaner way to do this, or should I just do it the same way? It seems to me that we really want to somehow map it onto the Bridge.Html5 CSSStyleDeclaration class, but I am not sure if I can use that directly?

      [IgnoreCast]
      [ExportedAs("ReactModal.Styles")]
      [ObjectLiteral]
      [FormerInterface]
      public class Styles : IObject
      {
        private react_modal.ReactModal.Styles.contentConfig \u003Ccontent\u003Ek__BackingField;
        private react_modal.ReactModal.Styles.overlayConfig \u003Coverlay\u003Ek__BackingField;

        public react_modal.ReactModal.Styles.contentConfig content
        {
          get
          {
            return this.\u003Ccontent\u003Ek__BackingField;
          }
          set
          {
            this.\u003Ccontent\u003Ek__BackingField = value;
          }
        }

        public react_modal.ReactModal.Styles.overlayConfig overlay
        {
          get
          {
            return this.\u003Coverlay\u003Ek__BackingField;
          }
          set
          {
            this.\u003Coverlay\u003Ek__BackingField = value;
          }
        }

        [ObjectLiteral]
        public class contentConfig : IObject
        {
          public new extern object this[string key] { get; set; }

          public static extern implicit operator react_modal.ReactModal.Styles.contentConfig(
            react_modal.ReactModal.Styles.overlayConfig value);
        }

        [ObjectLiteral]
        public class overlayConfig : IObject
        {
          public new extern object this[string key] { get; set; }

          public static extern implicit operator react_modal.ReactModal.Styles.overlayConfig(
            react_modal.ReactModal.Styles.contentConfig value);
        }
      }
ProductiveRage commented 5 years ago

I guess that retyped used some of sort of generic interface because the typescript definition gives it nothing else to work with, "any" seems a bit lazy.

If it is just css styles, is the way that style properties are handled in this library a useful model? It's been a long time since I looked at them, I can't remember exactly how they're defined.

And what sort of type is the "overlay" in the modal? Could that be a ReactElement or does it represent something else?

kendallb commented 5 years ago

Overlay and Content are both just blocks of styles if you wish to manually style your modals in code (I never do so I could leave this out for my usage). I guess some people like to style stuff in code rather than using a CSS file? I just do it all in LESS.

ProductiveRage commented 5 years ago

I also use LESS for styling but css-in-js is quite a thing in some parts of the JS community (and the React community, particularly).

I suspect that you could use the "ReactStyle" class from this library instead of "IObject". The ReactStyle is used in the example app (which another contributor provided, who presumably uses css-in-js more than me!) and you should be able to define an associative array by sprinkling in some [ObjectLiteral] and [Template] attributes -

public class Program
{
    public static void Main()
    {
        var x = new Blah();
        x["abc"] = 123;
    }
}

[ObjectLiteral]
public sealed class Blah
{
    public object this[string key]
    {
        [Template("{this}[{key}] = {value}")]
        set { }
    }
}

(See https://deck.net/e93ce733e6095b14f3ecd163b7e2dde4)

kendallb commented 5 years ago

Thanks, I will give that a try.