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

Color refinement list for InstantSearch.js #5137

Open
dhayab opened this issue Oct 12, 2022 · 3 comments
Open

Color refinement list for InstantSearch.js #5137

dhayab opened this issue Oct 12, 2022 · 3 comments
Labels
Library: InstantSearch.js Issues in instantsearch.js Type: Feature Type: Survey Asking input from the community on a feature

Comments

@dhayab
Copy link
Member

dhayab commented Oct 12, 2022

We currently provide a ColorRefinementList widget for React InstantSearch, and we'd like to gather interest in porting this widget to InstantSearch.js.

What's a color refinement list?

A color refinement list is an InstantSearch widget that filters results based on color facet values. The widget only displays the most relevant colors for the current search context.

It shares similarities with a standard refinement list, but it displays color indicators instead of text facet values. This helps users quickly visualize the kind of color that products have in your index.

See Live Demo →

How to show your interest?

Simply add a "👍" reaction on this issue, and optionally subscribe to its notifications. We will share updates here.

@aayoubi
Copy link

aayoubi commented Nov 30, 2022

Commenting on behalf of a prospect, they'd like to implement visual facets through a similar widget with vanilla js (on their custom Magento theme). Today they've built the following:

image

@dhayab dhayab added the Library: InstantSearch.js Issues in instantsearch.js label Dec 21, 2022
@dhayab dhayab changed the title Color refinement list Color refinement list for InstantSearch.js Jan 20, 2023
@Haroenv Haroenv added the Type: Survey Asking input from the community on a feature label Jan 24, 2023
@spacecat
Copy link

spacecat commented Oct 2, 2023

Hi, it's been a year since this was posted. Just wanted to check if there's been any progress? Is this feature in your roadmap? If so, do you have an ETA? Thanks.

BTW, are there any examples/demos on how to implement this feature using React Instantsearch v7?

@Haroenv
Copy link
Contributor

Haroenv commented Oct 2, 2023

This is currently not on a short-term roadmap, but it's fairly straightforward to do in a custom widget, as you can see in this example for React InstantSearch Hooks (same as React InstantSearch v7, just change the package names): https://github.com/algolia-samples/storefront-demo-nextjs/blob/main/components/ColorRefinementList.tsx

import { CheckIcon } from '@heroicons/react/24/outline';
import { useRefinementList, type RefinementListProps } from 'react-instantsearch-hooks';

type ColorRefinementListProps = RefinementListProps & {
  classNames: Pick<RefinementListProps, 'classNames'> &
    Partial<{
      swatch: string;
      swatchIcon: string;
    }>;
};

function cx(
  ...classNames: Array<string | number | boolean | undefined | null>
) {
  return classNames.filter(Boolean).join(' ');
}

function extractColorFacet(facet: string) {
  const [label, color] = facet.split(';');

  return { label, color };
}

export function ColorRefinementList({
  searchable,
  searchablePlaceholder,
  attribute,
  operator,
  limit,
  showMore,
  showMoreLimit,
  sortBy,
  escapeFacetValues,
  transformItems,
  classNames = {},
  className,
  ...props
}: ColorRefinementListProps) {
  const { canRefine, items, refine } = useRefinementList({
    attribute,
    operator,
    limit,
    showMore,
    showMoreLimit,
    sortBy,
    escapeFacetValues,
    transformItems,
  });

  return (
    <div
      {...props}
      className={cx(
        'ais-ColorRefinementList',
        classNames.root,
        !canRefine &&
          cx(
            'ais-ColorRefinementList--noRefinement',
            classNames.noRefinementRoot
          ),
        className
      )}
    >
      <ul className={cx('ais-ColorRefinementList-list', classNames.list)}>
        {items.map((item) => {
          const { label, color } = extractColorFacet(item.label);

          return (
            <li
              key={item.value}
              className={cx(
                'ais-ColorRefinementList-item',
                classNames.item,
                item.isRefined &&
                  cx(
                    'ais-ColorRefinementList-item--selected',
                    classNames.selectedItem
                  )
              )}
            >
              <label
                className={cx(
                  'ais-ColorRefinementList-label',
                  classNames.label
                )}
              >
                <input
                  checked={item.isRefined}
                  className={cx(
                    'ais-ColorRefinementList-checkbox',
                    classNames.checkbox
                  )}
                  type="checkbox"
                  value={item.value}
                  onChange={() => refine(item.value)}
                />
                <div
                  style={{
                    background: color.startsWith('#') ? color : `url(${color})`,
                  }}
                  className={cx(
                    'ais-ColorRefinementList-swatch',
                    classNames.swatch
                  )}
                >
                  {item.isRefined && (
                    <CheckIcon
                      className={cx(
                        'ais-ColorRefinementList-swatchIcon',
                        classNames.swatchIcon
                      )}
                    />
                  )}
                </div>
                <span
                  className={cx(
                    'ais-ColorRefinementList-labelText',
                    classNames.labelText
                  )}
                >
                  {label}
                </span>
                <span
                  className={cx(
                    'ais-ColorRefinementList-count',
                    classNames.count
                  )}
                >
                  {item.count}
                </span>
              </label>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Library: InstantSearch.js Issues in instantsearch.js Type: Feature Type: Survey Asking input from the community on a feature
Projects
None yet
Development

No branches or pull requests

4 participants