Ember-remodal re-imagining

sethbrasile [7:20 PM]
I’m planning on rebuilding ember-remodal by building it out of standalone behavioral “primitives” as @locks and I (and @runspired to a limited extent) have discussed.

The idea behind it is based on Trek Glowacki’s talks on the Frontside podcasts, encouraging folks to start building and sharing primitives for “reuse in-the-small” and then building their larger “reuse in-the-large” libraries out of these primitives.

I started messing around with the concept, but I would like start some discussion if anyone is interested, as I hope this could inspire other libraries to do similarly. I don’t feel comfortable making API decisions here without community support, as I feel like some form of “standards” would be a good thing.

So, for instance the first primitive that I’m focusing on (because it seems the easiest/most intuitive) is an overlay primitive titled ember-primitive-overlay.

My first iteration of this primitive exposes two ways to open/close the overlay:

  1. via the overlay service: this.get('overlay').open()
  2. via the primitive-overlay component and toggling an isOpen bool that is passed into the component

A small amount of css is included which creates the base functionality of an overlay, but does not style further:

  display: none;
  top: 0;
  left: 0;
  position: fixed;
  height: 100%;
  width: 100%;
}

.overlay[overlay-state="opened"] {
  display: block;
}

And currently, use of the service-overlay in a template looks like this

<div {{action 'closeOverlay'}} class="overlay" overlay-state={{overlay.state}}></div>

Thoughts? 1

[7:24]
And I’m thinking the use of the primitive-overlay component in a template could look something like this:


{{!-- block form could work too --}}
{{primitive-overlay
  isOpen=isSomeOverlayOpen
  closeOverlay=(action 'closeOverlay')
}}

(edited)

sethbrasile [7:45 PM]
Another discussion point I’d like to hit is performance: Is there a surefire way to structure a primitive that won’t negatively affect performance if there were ​_many_​ instances alive at once? (edited)

sethbrasile [8:18 PM]
One more discussion point: How should primitives be released? As standalone addons? As collections of related primitives in a single addon? As standalone addons that released and then pulled together into related concepts and also released as collections? Should they be addons at all? Will there any size bloat / performance degradation due to them being addons instead of something like importable es6 modules or something like that?

Allow me to try and clarify the “size bloat” question. Say 10 authors release small collections of primitives, and the consuming app ends up using all 10 collections as deps of various addons. Does the sole fact that each collection is an addon contribute anything to the consuming app’s size? Would there be any benefit in making them “lighter” than an addon?

I felt inspired inspired by Trek’s discussion on the Frontside. (But, to date, I haven’t done much in the open source to help realize it). The first thing I’m curious about — are you planning to do this in such a way that it removes the jQuery/Remodal dependency? Or is the plan to still use that?

Regardless, I’ll give you an example of a component I recently built for my app that I think fits into the pattern Trek described and relates to this project — it’s dismissible-block. It functions similar to an {{#if}} block, but it also sets up all the necessary event listeners, so that if a user clicks off of it or hits the escape key, it will send an action (in my case, it also tries to be ARIA compliant with focusing the first focusable element, restore focus on close, etc).

So, that looks like this:

<button {{action 'showTheThing'}}>Show</button>

{{#dismissible-block isShowing on-dismiss=(action 'hideTheThing')}}
  Things to be dismissed. 
{{/dismissible-block}}

By itself, it doesn’t do much. But, I think that’s a good thing. I find I am able to reuse it in many different places (for context menus, modals, and auto-suggest lists) without really ever having to retool it to work in a new context.

Anyway, it may or may not be relevant to your goals…but food for thought!

Yes, @Spencer_Price I was planning on attempting to get rid of the dependencies and make it as “native ember” as possible.

And yes, I do think that your example is basically exactly what we’re aiming for. Release a primitive! “ember-primitave-dismissable” or something like that :smiley:

1 Like

Cool beans. Once I get a free cycle, I’ll try to port what I’ve done so far into an addon.

@sethbrasile — I got something started. Have a look: GitHub - spencer516/ember-dismissible: A lightweight Ember component for supporting dismiss panels (modals, menus, etc)