A Look on Creating and Maintaining an Axure Widget Library
Here, at eMAG, we have quite a few (to be read dozens) internal apps and a few more development teams building and maintaining them. Creating an internal UI Kit for this was undoubtedly the first thing to do to keep everybody on the same page, at least with the UI part.
On the other hand (the UX hand more precisely) we have to build a lot of prototypes, some of them pretty accurate on the functionality side and we thought why not give a try to have them accurate on the looks also. Still not sure the best idea but we’ll be back on this.
Of course, consistency is important in prototypes too and it was not long until we felt the need for a common library of reusable elements, a single source of truth, as it’s called now. We use Axure for the richly interactive prototypes, so it was about an Axure widget library.
Therefore, enough talking, let’s jump into doing. Or you can skip to the conclusions at the end of the article if you’re in a hurry.
Creating the library
One can create a local library or a cloud library.
A local library can be created by choosing Create Library… in the hamburger menu of the Libraries pane. I’ll keep mentioning this hamburger, see it on the left image.
A .rplib file will be created in the ~/Documents/Axure/Libraries folder (or you can choose another folder). The library will automatically be present in all prototypes open or created on the local system.
A cloud library, on the other hand, can be created by initiating a New Team Project, this time from the File menu, subsequently checking the (tiny) option to create it as a widget library.
Note that it must be placed in a custom work space on the cloud to be able to further share it with other users because the default one seems too lack this sharing option.
To use it, the library must be loaded (manually) from Axure Share, in the same hamburger menu. It’s enough to load the library once, then it will be available for all the files on that machine.
From now on we’ll call that file you created in the previous step the library source file and any file that uses those widgets the target file.
Every page in a library source file will be a widget in the library. You can even draw and load two thumbnails for every widget to display them in the Libraries pane. Otherwise a thumbnail will be generated automatically and nobody will understand nothing of it because the thumbnail is only 28x28 (56x56 for retina’s, that’s why you have to upload two).
Folders in the library source file will be widget groups in the Libraries pane, but only if they contain at least one page (widget). In the Libraries pane they will be listed on one level only, no matter their hierarchy in the library source file. Their order is kept though. Pages in the root of the library source file (those not in a folder) will be present in the Libraries pane in a group having the same name as the library. Great, we’ll make the best structured library ever.
Now let’s get to the facts, the interactions
Good thing: every interaction in the library source file will be kept for the widget in the target file.
Not such a good thing: every interaction in the library source file will be kept for the widget in the target file.
It is obvious why this is good but it is also nasty. First of all, because the badges are also kept. Now imagine a prototype with a multi-option filter area, for searching products in one of the back-office apps. Full of tag inputs, autocompletes and a date picker, all built as widgets in our library. In fact, don’t imagine it, here it is:
All those seen in the image above are just basic interactions, you know, click to display the drop list, select one item, update the value of the input, etc. If they were native widgets all these basic interactions would have been invisible to us.
We also need events to handle. Take a custom checkbox we built as a widget, comprised of a box with different interaction styles and a text label. Of course we made the label clickable too, it sets the box selected or not. Then, when we drag the widget in the target file, we treat the OnSelected and the other events of the box.
It works just fine for the checkbox (those badges still bother me though, especially when I have a bunch of them in a group) but, if for the checkbox we fond a way to mimic its native events, when it gets to custom selects, multi-selects, tag inputs, etc., the things become more difficult. We could use hidden native widgets that we update when the custom visible ones are clicked and then listen to the hidden ones events. But they add to the project load and it still doesn’t always work.
A nice thing, for the future maybe, would be a way to encapsulate the widget, so no inner kitchen is visible and only some, maybe raised events (like masters have) to be listenable in the target file. But they also need a way to customize their label or their values and another way to output their selected option(s) if case. No easy task, but a nice subject to think for the guys at Axure.
For the encapsulating part, we can transform each widget into a dynamic panel. But, you know, it becomes harder to edit then, you have to make some clicks and double clicks to open states, and we don’t like that many clicks.
Maybe the best thing for now is to keep them loose in the library source file and transforming them to dynamic panels right after you drag them in the target file and make their needed, hopefully final, customization.
Also on the interactions, be careful, when you build one widget in the library source file you may want to outfit it with all the interactions in the world because you think, and you’re right, that you do this only once then it is useful every time you use that widget. Only that, all these interactions add to the prototype load, especially when you start to use more of those widgets in the same page and you end up, like I did in the above example, in waiting good seconds for a page to run.
So go as far as you need with the details, is just a prototype after all.
Maintaining the library
Updating the library is easy. Updating the widgets already used in target files is not easy at all.
So, updating the library.
To update the library you must edit the library source file. For local libraries you must save the file. For cloud libraries you must send the changes to the cloud and, of course, at some point, save the file to keep it updated also on the local environment.
The library automatically refreshes when you open a file or create a new one.
If there were files already open when the updating has been done you can manually refresh the library in the Libraries pane hamburger menu. You need to do the refresh only once (per machine), and it will affect all the open files on that machine.
However, notice that if you have an open file and you made the refresh somewhere else (either manually either by opening or creating a new file) the widgets thumbnails will not be updated in the Libraries pane. But don’t worry, the widgets will be up to date and the thumbs will update next time when you open the file or manually refresh the library in its window instance or when you switch to another library and then back, as I observed.
Updating the widgets already on pages
Now, all of those above are only available for the widgets in the library, not for those already on pages inside target files.
If we’re talking about those widgets, let me begin by saying that Axure widgets are nothing like CC or Sketch symbols. Those widgets that are already used in the target files will not be affected in any way when a library is updated.
However there are few workarounds for this but don’t get too optimistic, only few.
Let’s clarify one thing from the start, for those changes regarding the content or the interactions of the library widgets I didn’t find any way to propagate these changes on the already used widgets. You have to manually replace every one of them. Now let’s move on.
What about the looks of the widgets?
Now, this is long but essential if you’re interested in looks.
Remember widget styles? You know, you have 20 H2’s in a prototype then you decide to increase their font size. You do it on one (any) of them, then update the widget style and then, bam, all H2’s are updated.
More than this, all H2’s that you drag from the Libraries pane after you updated the style will match the altered font size, they will take a bow and subdue to the local file widget style, ignoring the library widget style.
It’s a good thing it is like this, isn’t it? If yes then find out that it is exactly the same with custom libraries.
So, let’s say you have an widget in a custom library that is already present on some pages of the target file. Then you will alter the widget in the library source file, update its style, send the changes and wish to do this change in the target file too, for all the widgets already present on pages.
It will not happen, because no matter how many times you refresh the library, when you drop the newly updated widget in the target file it will take the target file style, it is priority and you agreed that this is a good thing.
You can work this out by importing the library source file widget styles into the target file with Import from RP File wizard from the File menu. But that’s a long wizard with many clicks and what did I told you about many clicks?
Now, pay attention to this: doing all kinds of back-and-forth with widget styles I found out that, if you alter the look of a widget in the library source file and DON’T update its style and then drop the widget on the target file, well then the changes are kept, at least on the newly dropped widget (you know, save-send-refresh the library before dropping the widget).
I can only suppose that those changes made in the library source file and NOT saved at the widget style level are taken like exceptions from the style and are treated similarly in the target file and, therefore, kept as they are.
So it seems like a better idea to alter the widget look in the library source file without updating its style and then bring the newly updated widget in the target file. Just drop one on any page in the target file and then you can update it’s style there, so all the old “instances” of the widget will update to the new look. I used the quotes because they are not really instances, they are only connected through their style. Get used to it.
More than this, seems like a better idea to build the library without saving any small detail to the widget style. That way, you will not need to import any style when you create a brand new target file who intends to use the library.
Of course, this way we cannot take the undoubted advantages of using widget styles in the library source file, but, for the moment, it turned out to be the less time consuming method of updating custom libraries.
Maybe an “Apply Library Styles” command in the hamburger menu for the future? But again, this is only a quick thought.
More interesting cases about styles
We’ll may be tempted to say that, if having custom styles (not present in a default style list of a newly created file), then it doesn’t matter if we update them or not in the library source file, because those styles will not conflict with any style in the newly created target file. They will be added to the list when you drag the first widget in the target file. But remember, maybe you’ll need to update those styles too one day, and you’ll get in the same situation, the style created first in the target file will trump the one newly updated in the library. Honestly, I still work on figuring out what’s the best practice.
Another situation worth mentioning is when, in the library source file the widget had, not a custom widget style, but one of the default Axure widget styles, only that it was modified from the original. Modified and its style updated I mean. Then, in the target file, when dragged for the first time in a page, a new style is created, with the same name as the default style but not replacing the default style of the target file. That means that if, further, a default widget having that default style is also dragged in a page, the file will end up in having two styles with the same name, the default style and the one created when first dragging the custom widget. Man, these styles are tricky.
Also be aware though that some properties are not saved on the widget style level, take width or height for instance. Quick tip: when possible, manipulate the dimensions of the widget by tweaking its paddings, those can be saved in the widget style.
Conclusion (for now)
It definitely feels like worth it to have some semi prepared ingredients for the prototypes we do but, on the maintenance side of it, it feels like some friction to update components already used.
Widgets are not symbols, they don’t have a master instance that synchronizes with all other instances on the pages. They are just basic widgets grouped into other widgets in the Libraries pane, once you take them out of there and put them in a page, they lose any connection with the library, except styles, which are tricky to use.
On the looks of the widget, for the moment NOT using styles in the library source file seems more smoothly.
On the interaction side, some encapsulating concept may be a nice idea, it works for OOP, why not working for prototyping also.
This is a pretty thorough look but still a first look, so I may be wrong on some assumptions here, please comment if you find something different or have a better idea.