algolia / instantsearch

⚡️ Libraries for building performant and instant search and recommend experiences with Algolia. Compatible with JavaScript, TypeScript, React and Vue.
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/
MIT License
3.68k stars 515 forks source link

Naming of Widgets #219

Closed kokliKo closed 8 years ago

kokliKo commented 8 years ago

Hey! I'd love the name of the widgets to be more self-explaining for the users that won't code on the project. I tried a different naming for most of them. I also propose a different organisation of the filter-related widgets.

Wdyt?

SearchBox => SearchBar Most of the search solutions use the naming Search Bar, I agree.

IndexSelector => SortBySelector If you want to change an index, you're either doing a SortBy, or doing a multi-index search. If you're doing a muti-index search, search parameters won't be the same, so you'll need different instances of instantsearch.js. -> Changing the index is only useful if you're doing a SortBy (very rare exceptions IMO)

Hits => Results Seems more simple to understand to someone that doesn't know the Algolia API.

RefinementList + Menu => FilterList The main Facet widget, contains options to select

To me, it doesn't make sense to have separate widgets when 95% of the behavior/markup/usage is identical. I'd rather have a parameter.

Toggle => BooleanFilter Trying a different naming. Not sure about this one.

HierarchicalMenu => HierarchicalFilter

RangeSlider, Stats, Pagination, URLSynchronisation These ones seem good to me.

redox commented 8 years ago

SearchBox => SearchBar Most of the search solutions use the naming Search Bar, I agree.

We already chat about that one, it seems Google disagree and says "search box" is better.

IndexSelector => SortBySelector

Same; but we decided to go for Index because:

  1. it's not only for sorts, we could target another index
  2. Algolia really requires you to understand that it will target a specific index for the sorts

Hits => Results

I think I like this one. :+1:

RefinementList + Menu => FilterList Toggle => BooleanFilter HierarchicalMenu => HierarchicalFilter

I wouldn't got for those ones, we need to keep names than explain what the widget is about; not really which action will be performed.

bobylito commented 8 years ago
Jerska commented 8 years ago

I also really think toggle, menu and hierarchicalMenu should be changed.

vvo commented 8 years ago

tl;dr;

I would keep the current names, maybe change indexSelector back to sortBy. And if searchBox is not obvious then searchInput.

More:

Nice to have so much discussion about widget and naming, we already did have a lot of them at the beginning also.

Much have been said, I will give some context

SearchBox => SearchBar Most of the search solutions use the naming Search Bar, I agree.

@redox answered that, also when instantiating a search bar one would expect it to expand automatically to the max width (=bar). That's not what we want, this is up to the user or theme.

We could have searchInput which is maybe better than searchBox. But I think we are good.

IndexSelector => SortBySelector

This one is tricky. It was originally named widgets.sortBy which is self explanatory because "sort by" is always the text next to the <select>. We then thought "well, but it does not reflect the fact that it requires you to have mutiple indices..".

Right now I would like to call it sortBy because that's the only widget where the name is tied to the underlying implementation on our side. Of course the user will have to know that he needs multiple indices (slaves) but that's a documentation issue. The name should be sortBy I think.

Every widget will require some index/algolia configuration and that's completely OK if we do state this well in the documentation (see #156).

Hits => Results

Not sure again, because what you are dealing with are the result.hits. If at any moment you see a response from Algolia (dashboard, helper). Then your mind will do the mapping: hits widget maps to result.hits.

Yes we could name it results. Dunno if that's really better.

RefinementList + Menu => FilterList

We already spend a lot of time finding refinementList but we need the menu widget.

To me, it doesn't make sense to have separate widgets when 95% of the behavior/markup/usage is identical.

The fact that internally we are DRY does not mean that the underlying widget API menu, hierarchicalMenu, refinementList should be merged. If you are a user looking at a way to "create a menu out of categories" then you will look for a "menu" widget I think.

Toggle => BooleanFilter

Nope, it's implementation bubbling up to the API. I am looking for a toggle, I will search toggle.

RangeSlider, Stats, Pagination, URLSynchronisation

Careful thought, we need to map the exact API names into the documentation. So we will not speak about URLSynchronisation or link to it but urlSync. Because once you start using the library it's important to find the things you are looking for and to map your code to the docs. We cannot have titles like "Range Slider" because I will search for rangeSlider once used to it. But still, we can have "range slider" in the text of course, but links and headers should reflect the API.

I wouldn't got for those ones, we need to keep names than explain what the widget is about; not really which action will be performed.

:100:

I also really think toggle, menu and hierarchicalMenu should be changed.

Can you precise how you would like them to change?

pixelastic commented 8 years ago

tl;dr

I'd rather have several high-level widgets, even if they are internally just using the same components with different attributes.

more:

This issue is important to me at the moment because I'm working on the theming of widgets and I would like every widget to have its own set of CSS classes, so we can style them independently. At the moment, a lot of widgets are actually refinementList widgets, with very specific attributes to completly change their behavior. But they are still the same widget, and they will still have the same CSS class.

I think widgets should be high level, exposed to the users (keep in mind that instantsearch.js is geared toward non tech-savvy users), while we can still share some code internally (like re-using the same React components). I'd rather we have 10 different top-level widgets, for each possible combination of options of the underlying React components, than one do-it-all top level one.

SearchBox or SearchBar is fine for me. I feel like sortBy is clearer from a user POV than indexSelector (yes, we actually change the index, but I've never seen a real-life implementation where we were using it for something else than sorting). And Hits => Results is way clearer. We have some naming in the API that is clearly not user-friendly, but let's not bubble it to the instantsearch API.

Then, what seems the real hard part, will be naming the widgets that acts as refinementLists. Here is a proposal:

multipleSelectionUnion

multipleSelectionIntersection

uniqueSelection

We currently also have a widget like the uniqueSelection, but where other choices are hidden (so the user need to first click the current selected item to unselect it, then select another one). I don't think this is one useful and we should just drop it.

I've not included any information about checkboxes or links in the above examples. We currently use checkboxes for the multipleSelectionUnion, but they are actually a perfect choice for the multipleSelectionIntersection as well. Also, simple "active" links are also a viable choice for both of them. I don't think we should enforce checkboxes on those widgets, but let the users opt-in for the kind of display they want.

I also think the vocabulary is really confusing. I personnaly understand Union and Intersection better than Conjunctive/Disjunctive, Convergent/Divergent or AND/OR, but not everyone might feel the same.

vvo commented 8 years ago

This issue is important to me at the moment because I'm working on the theming of widgets and I would like every widget to have its own set of CSS classes, so we can style them independently. At the moment, a lot of widgets are actually refinementList widgets

I am not sure to understand the issue of widgets naming for theming/default css classes.

The widget are separated in menu, hierachicalMenu, toggle, refinementList. So the theming can just use those names to reflect the differences and provide the user the ability to have different styling.

There's little chance you will want to style a menu the same way you will style a refinementList (links vs checkboxes).

Can you elaborate with css code on what's the issue?

pixelastic commented 8 years ago

There's little chance you will want to style a menu the same way you will style a refinementList (links vs checkboxes).

Actually, the choice of using checkboxes or links is not that obvious. Both are perfectly acceptable in almost every case (except maybe using a checkbox for a menu, where a radio might be more explicit). I feel that this display choice should not be linked to the widget, but that we let the user choose which one they want (through css classes).

My issue today is that the refinementList widget is used to display both of these widgets: imageimage

But they have really different behavior (one lets you select multiple items, the other only one). The way the code is currently set, CSS classes are defined at the widget level. But as those two widgets are actually the same, they will both have a class of ais-refinement-list, while we would want them to have classes of ais-multiple-selection and ais-single-selection (for example), to style them differently.

I could add code inside the refinementList widget, testing if singleRefine is set to true or not to see if I'm in a single select or multiple, and adapt the css classes based on that. But creating two different widgets (because they have two different behaviors) would make code much more readable.

Note: Regarding my above example, I actually think that all widgets that are using the refinement-list component internally should also share the ais-refinement-list CSS class in addition to their ais-multiple-select or ais-single-select one. But that is not the main issue here.

vvo commented 8 years ago

But they have really different behavior (one lets you select multiple items, the other only one). The way the code is currently set, CSS classes are defined at the widget level. But as those two widgets are actually the same, they will both have a class of ais-refinement-list, while we would want them to have classes of ais-multiple-selection and ais-single-selection (for example), to style them differently.

I think the BEM root name (ais-refinement-list) should be defined at the widget level, not the component level. Components are just internal implementation, the user should not care about it.

Indeed if I am using the menu widget and get ais-refinementList, I will be surprised.

This will solve your question here I guess.

pixelastic commented 8 years ago

I totally agree with you. CSS classes definition should stay in the widgets, and components are just internals.

That's why I suggest we create new widgets on top of refinementList, so they can have their own classes (and explicit name) instead of using refinementList for very different things.

vvo commented 8 years ago

That's why I suggest we create new widgets on top of refinementList, so they can have their own classes (and explicit name) instead of using refinementList for very different things.

What are the different things we use the refinementList widget for? Right now we use it for:

I do not feel those are very different things, it's always a list of checkbox by default. As for the theming, there's no need to provide a different theme for those 3 use cases, this is just a list of checkboxes.

There's no need to add/remove classes internally based on the options since the rendering is the same. The user has already all he needs to specify a custom class or even his own #container if he really want different css/template at the widget instantiation level.

We talked a lot at the begining if we needed things like "singleRefinementList" "multipleRefinementList" and agreed that in the end, a simple refinementList should be good with theses three options. And single refine is really an edge case. See #42.

If we really discover that this is a pain for our users then we can just move on and split etc.. That's not a problem.

pixelastic commented 8 years ago

What is exactly singleRefine? I understand that it means one can only select one element in a list of multiple element (ie. when selecting one, the previous one is unselected). But this seems really the same as what the menu widget is doing.

Also, in the issue you linked, we're saying that menu is a special case of refinementList, but we make it its own widget so it's easier to understand (and I agree with that).

So do we still have a singleRefine attribute on refinementList that does the same thing as a menu?

I'm also not convinced we always want to display those elements using checkboxes. I've created a separate issue for that, because the discussion here is getting hard to follow.

vvo commented 8 years ago

But this seems really the same as what the menu widget is doing.

Yes, but menu is really sugar that people will look for if they want to create a "menu". We can get rid of singleRefine for sure, but then people will have to use a menu widget, provide a checkbox template.

So do we still have a singleRefine attribute on refinementList that does the same thing as a menu?

I would say yes. If we get an issue or more people are using menu + checkboxes then we can remove it.

vvo commented 8 years ago

We are good here I think

pixelastic commented 8 years ago

I don't think so :) (menu, toggle, hits, indexSelector are still subject to debate). But we should open separate issues for that next time.

Let's close that one for now.