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

Remove jQuery dependency from tabs.js and dropdowns.js #21

Closed
3 tasks done
claviska opened this issue Aug 4, 2017 · 7 comments
Closed
3 tasks done

Remove jQuery dependency from tabs.js and dropdowns.js #21

claviska opened this issue Aug 4, 2017 · 7 comments
Labels
planning Discussion about the project's upcoming features and more.

Comments

@claviska
Copy link
Member

claviska commented Aug 4, 2017

I whipped up a minimal script for tabs and for dropdowns, both on top of jQuery. I'd like to remove this dependency, however, as it can add a lot of weight to projects that aren't using jQuery.

In previous versions of Shoelace, the docs stated:

Tabs are not interactive by default! Shoelace is a CSS starter kit, not a framework. For convenience, a lightweight sample script is provided to demonstrate how to make tabs interactive.

However, it's apparent that pretty much everyone will just copy and paste the sample script and use it. If that's the case, we might as well provide an official version of tabs/dropdowns in the dist so users can load it via CDN.

Objective

My goal for shoelace.js is to provide vanilla JS scripts for tabs and dropdowns that just work, much like the current jQuery-based versions. These should be simple scripts that don't require initialization and don't have any API. Also like the current versions, they need to use event bubbling to ensure dynamically created tabs/dropdowns also work.

Now, before people lose their minds about not having an API and not requiring initialization, I feel this is important to say:

Shoelace components should act like native components as much as possible. This is part of Shoelace's core philosophy.

In the same way you expect a <select> control to open without JavaScript, tabs and dropdowns should activate "without JavaScript."

In the same way you can disable an <input> by adding the disabled property, you can disable tabs and dropdowns by adding the disabled property.

In other words, we're using JavaScript as a shim to make these controls work, not as an extensive plugin that packs in a million features.

Of course, shoelace.js will be completely optional. Users who want a more robust solution are welcome to adopt alternatives such as Tabby.

So that's where I'm trying to go with things. We're basically cloning tabs.js and dropdowns.js in a non-jQuery way. Browser support should include IE11 even though it doesn't support CSS vars, as many users use Shoelace + a polyfill for older browsers.

If you're interested in taking a stab at it, comment here and let me know.


Additional planning:

  • show and hide events for tabs
    • Should fire on the tabs container
    • Affected tab pane will be passed as second argument
  • show and hide events for dropdowns
    • Should fire on the dropdown container
  • select event for dropdowns
    • Affected menu item will be passed as second argument
@claviska claviska added help wanted Ready for a contributor to tackle. planning Discussion about the project's upcoming features and more. labels Aug 4, 2017
@EvgenyOrekhov
Copy link

EvgenyOrekhov commented Aug 5, 2017

How about implementing tabs and dropdowns in pure CSS?
A quick googling brings up a lot of solutions, for example:

@claviska
Copy link
Member Author

claviska commented Aug 6, 2017

See #19 for some discussion about that.

Good to see that you can access those CSS-only tabs with the keyboard, but I'm still not a fan of the markup. The script is also useful to add helpful events so users can tap into show and hide once those get added.

Also, that dropdown example isn't apples to apples. We don't want them showing on hover — they need to be activated by a button or link by design :)

@TheMonster1995
Copy link

I could give it a shot, hopefully getting it down in the next 2-3 days.

@claviska claviska removed the help wanted Ready for a contributor to tackle. label Aug 7, 2017
@claviska
Copy link
Member Author

claviska commented Aug 7, 2017

I just pushed e2160a9 which lets you use either jQuery (34.6KB) OR Zepto (9.7KB) for tabs and dropowns. This is what the next beta will feature and they'll be available in /dist as a single minified file.

I think this is a fair compromise since now you can shrink Shoelace's JS down to:

  • 9.7KB Zepto
  • 0.6KB Shoelace tabs & dropdowns
  • 10.3KB TOTAL

This is about 10KB total (min/gzipped). For comparison, Bootstrap 4.0.0-alpha6 requires:

  • 27.2KB jQuery Slim
  • 8.1KB Tether
  • 13.8KB Bootstrap
  • 49.1KB TOTAL

Granted, Bootstrap has more components and scripts than Shoelace, but now we have a guaranteed foundation to build core and third-party components with.

I realize this may be an unpopular opinion in some circles, but for practical use and ease of development, I think it's a good decision. Here are a few reasons why:

  • I'm a huge fan of chaining, particularly when traversing the DOM. It's more elegant than vanilla JS, and you don't need to worry about unobvious browser quirks like this.

  • We still need shims for basic things like element.closest. This one is nearly the same number of lines as the tabs script alone. Polyfills and helper functions add up, and relying on multiple third-party scripts makes updating and testing more difficult.

  • Libraries such as jQuery and Zepto exist to normalize behavior across various browsers and make our lives easier. I don't leave 10 virtual machines running with various browser versions to test basic functionality in scripts. I let the libs test those things so I don't have to — their communities do a better job than I ever could on my own.

  • The code isn't not littered with random helper functions or polyfills. It doesn't need to be. If you think vanilla JS is more elegant, I challenge you to create an equivalent version of tabs.js and dropdowns.js so we can compare them apples to apples.

Some people use jQuery as a crutch. I don't agree that loading a 34KB (or even a 9.7KB) library just to toggle a class is a good idea. However, I do believe loading such a library is a good idea if it helps the developer and the project significantly. In this case, requiring jQuery or Zepto provides a foundation for future core and third-party components.

Let's imagine that we go pure vanilla. Now every component has to use its own element.closest polyfill, its own siblings helper, and so on. Here we go adding unnecessary duplicate code to the project.

Hmm, well, why not create a base JS file for Shoelace that has all these polyfills and helper functions so third-party components can use them too?! Well guess what? That's exactly what fucking jQuery and Zepto do.

I'm sure you can save a few KBs with a vanilla version. And you're absolutely encouraged to write your own if you want to go that route. It's open source. Tear it apart! But the fact is, many projects and websites are already using one of jQuery or Zepto. When loaded via CDN, it's probably already cached in their browser.

Personally, I don't think going vanilla at this point adds much benefit to the project, especially considering Zepto as an official 10KB alternative to jQuery.

@claviska
Copy link
Member Author

claviska commented Aug 9, 2017

Reopening for further discussion.

@claviska claviska reopened this Aug 9, 2017
@ghost
Copy link

ghost commented Aug 9, 2017

I am enjoying the direction that you are taking with shoelace and fully intend to use it in several production sites / applications.

I would be disappointed to see you bow to a different design paradigm, so encourage you to keep going the way you see fit. I, however small that may be, like your approach.

One production application that I work on makes heavy use of jQuery, not as a crutch but to ensure cross-browser compatability with many disappointing excuses for web browsers; however because of my interest in shoelace, I have now begun to investigate if we could switch over to zepto for the next major publish.

@claviska
Copy link
Member Author

I would be disappointed to see you bow to a different design paradigm

In terms of JavaScript, it's less about the paradigm and more about what works for me (the developer) and users. It's a balance. I do appreciate the encouragement though 😄

To further emphasize my feelings on this:

As a developer, I know I can do everything without jQuery or Zepto. That doesn't mean I want the burden of polyfilling and testing every feature that target browsers may or may not haven't implemented yet. I like their API. I like chaining. I like that I can write much more elegant code. I like that I created the first version of the tabs plugin in a matter of minutes instead of wasting time copying and pasting functions and polyfills.

For users, a mere 10KB for shoelace.js + Zepto is pretty damn good considering it's still a fraction of the size of many alternatives. Again, it's a balance.

Those who don't like it don't have to use it. Anyone is welcome to create a vanilla version. Hell, you can create a chocolate chip cookie dough version if you want. It's open source. Go crazy. 🍦

If your code is good, it may even make it's way into a successful PR. But if the code is littered with polyfills and copy/pasted functions that make my life harder, I'm going to pass. 👋

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
planning Discussion about the project's upcoming features and more.
Projects
None yet
Development

No branches or pull requests

3 participants