Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Code Segmentation and Injection on Groups #110

Open
gskinner opened this issue May 1, 2021 · 7 comments
Open

Code Segmentation and Injection on Groups #110

gskinner opened this issue May 1, 2021 · 7 comments
Labels
enhancement New feature or request

Comments

@gskinner
Copy link
Collaborator

gskinner commented May 1, 2021

This proposal aims to address two specific issues:

  1. As designs grow, the resulting code becomes increasingly nested and difficult to read.
  2. We can't possibly support every use case developers have, and round trip support is highly unlikely, so we need ways to layer in custom functionality without editing the exported Dart code directly.

To address both these cases, we could add an option for Groups to allow the user to specify alternative ways to generate its code.

  1. Segment the generated code out of the main build method. For example, the user could choose to export it as a separate method, or potentially as a separate Widget (though this latter case could get quite complicated with trying to pass parameters through). We would need to disallow certain reserved names (Ex. build), and check for duplicates on export. This could also potentially allow for a devs to subclass the widget and override specific build methods.
  2. Allow the user to provide code that would be substituted in place of the generated output. This would allow the injected code to be completely custom, and also allow for any visual representation of said code within the design.

Here's a rough mockup of what this could look like:
image

While there's an argument for supporting this functionality on other element types (ex. replacing the code for a text field with an input), I think keeping it limited will simplify the UI and implementation, while remaining super easy to work around (ex. simply make the text field a group).

Thoughts/feedback are very welcome.

@gskinner
Copy link
Collaborator Author

gskinner commented May 1, 2021

For the code injection, it could also be interesting to allow for some kind of child / children injection.

For example something like this could inject the generated output of the whole group:
Container(child: <THIS>, ...)

Whereas, this could inject an array of the children:
Column(children: <CHILDREN>, ...)

It might be worth ensuring we consider some kind of parameter system for adjusting the output. Maybe even leverage JSON so it's easy to parse?
Column(children: <CHILDREN{"layout":"none"}>, ...)

@JakubNeukirch
Copy link

For the custom widget code I am just creating component in Adobe XD and name it for example "MySuperTextField" - and just do not export it. Instead I am creating widget in my project with the same name so it is placed right there.

@gskinner
Copy link
Collaborator Author

gskinner commented May 2, 2021

@JakubNeukirch - ya, that's a smart way to work around it now. I'm hoping to do something a bit more explicit with the proposal above.

@gskinner
Copy link
Collaborator Author

gskinner commented May 3, 2021

A fourth option for adding a builder parameter would also really open up options for externally modifying the behavior of an exported widget:

image

@gskinner
Copy link
Collaborator Author

gskinner commented May 4, 2021

After an extensive battle with XD UI, I have the initial implementation of these features working locally, and am hoping to commit them after a bit more testing. Unfortunately, it doesn't look like XD UI supports monospaced fonts in textareas.

image

@gskinner
Copy link
Collaborator Author

gskinner commented May 5, 2021

I just pushed c6b6ba4 which is a monster commit that adds this feature and a bunch of additional updates / refactoring that I tackled as part of it. It seems to be quite functional, and people are welcome to test, but there are still some edge cases that need consideration - specifically how to deal with decorators (ex. onTap, blur, etc), and whether there's a reasonable way to check custom code for syntax errors.

Short description:
All groups in XD now present an setting to set their export mode to one of four options:

  1. Export as inline code – this is the default behavior, simply writes the code for that group inline.
  2. Export as build method – this will write the code into a separate build method on the widget, which is called inline. buildMyGroup(context). This reduces the depth of nesting, which makes the generated code more readable, and could potentially be overridden in subclasses.
  3. Replace with builder param – adds a required WidgetBuilder parameter to the widget, and calls it inline. Does not export the code for the group at all. This allows code external to the exported widget to inject whatever it wants at that location.
  4. Replace with custom code – injects the specified Dart code in place of the group. Does not export the code for the group. This allows a group to show a visual representation inside XD for a control, but be completely replaced by custom dart code. For example, you could imagine a group that looks like a slider, that is replaced with the dart code for a slider.

gskinner added a commit that referenced this issue May 10, 2021
@gskinner
Copy link
Collaborator Author

I just pushed initial support for tags in custom code to let you inject the target item's exported code <THIS> or a list of its children <CHILDREN>. This includes support for enabling group decorators: <THIS{"decorators":true}> and adjusting layout for children: <CHILDREN{"layout":"none|size"}>.

This is very much alpha functionality, and is subject to removal or significant change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants