houdini.how icon indicating copy to clipboard operation
houdini.how copied to clipboard

Filtering Functionality

Open una opened this issue 3 years ago • 5 comments

Add functionality to filter by tag for both Resources and Worklets pages.

una avatar Sep 23 '20 02:09 una

Hello @una, Can I work on this?

Kartik1397 avatar Dec 18 '20 12:12 Kartik1397

Sure, thanks—that would be great! Feel free to open a PR :)

una avatar Dec 18 '20 19:12 una

Is there any easier or finer way to implement this apart from adding route for each tag?

Kartik1397 avatar Dec 19 '20 19:12 Kartik1397

Hello @Kartik1397

This is possible without adding a new route for each tag. Here is a working proof of concept example to help you get started.

Defaults to show all resources with filter tag buttons at top of page

image

Click or tap to filtered by tag

image

Notes and Code

Additionally all Worklets have the same tag to it seems this would only need to go on the Resources page for now (but I'm not a site maintainer) so I can't be certain on that or future plans of how Worklet tags should work.

The above images were created by modifying this one file with the code below. However, if you end up adding this feature you would want to properly structure the code to separate component files, add CSS, etc.

https://github.com/GoogleChromeLabs/houdini.how/blob/main/public/pages/resources/index.js

import { useState } from 'preact/hooks';
import Resource from '../../components/Resource/index.js'
import resources from '../../resource-data.js'
import style from '../../components/CardMeta/style.module.css'

const selectedStyle = (selectedTag, tag) => {
  if (selectedTag === tag) {
    return { 'transform': 'scale(1.3)' };
  }
  return null;
}

const buildTag = (tag, selectedTag, setFilter) => {
  if (tag === 'paint') {
    return (<li class={style.paint}  style={selectedStyle(selectedTag, tag)}><a href="#" onClick={() => setFilter(tag)}>Paint</a></li>)
  } else if (tag === 'properties and values') {
    return (<li class={style.props}  style={selectedStyle(selectedTag, tag)}><a href="#" onClick={() => setFilter(tag)}>Properties & Values</a></li>)
  } else if (tag === 'typed object model') {
    return (<li class={style.typed}  style={selectedStyle(selectedTag, tag)}><a href="#" onClick={() => setFilter(tag)}>Typed Object Model</a></li>)
  } else if (tag === 'layout') {
    return (<li class={style.layout}  style={selectedStyle(selectedTag, tag)}><a href="#" onClick={() => setFilter(tag)}>Layout</a></li>)
  } else if (tag === 'animation') {
    return (<li class={style.animation}  style={selectedStyle(selectedTag, tag)}><a href="#" onClick={() => setFilter(tag)}>Animation</a></li>)
  }
  else return
}

export default function ResourcesPage() {
  const [selectedTag, setFilter] = useState(null);

  const allTags = new Set();
  resources.forEach(resource => {
    resource.tags.forEach(tag => {
      allTags.add(tag);
    });
  });

  const displayResources = (
    selectedTag === null ?
    resources :
    resources.filter(resource => { return resource.tags.includes(selectedTag)} )
  );

  return (
    <div>
      <div class={style.tags} style={{'align-items':'center', 'padding-bottom':'4rem', 'padding-top':'2rem'}}>
        <ul style={{'justify-content':'center', 'gap':'25px'}}>
          {selectedTag === null ?
            <strong>Filter</strong> :
            <li class={style.paint} style={{'background-color': '#66ff66', 'border-color':'transparent'}}><a href="#" onClick={() => setFilter(null)}>Show All</a></li>
          }
          {Array.from(allTags).map((tag) =>
            buildTag(tag, selectedTag, setFilter)
          )}
        </ul>
      </div>
      <div>
        {displayResources.map(resource => (
          <Resource resource={resource} />
        ))}
      </div>
    </div>
  );
}

Compared to the original file you can see I added a lot of code and mixed styles within the components, etc which why I call this a proof of concept even though it works.

From the above code example const buildTag = ... was copied and modified from here. https://github.com/GoogleChromeLabs/houdini.how/blob/main/public/components/CardMeta/index.js

Hope this helps, Good Luck! :smile:

ConradSollitt avatar Jan 09 '21 00:01 ConradSollitt

Thank You @ConradSollitt :)

Kartik1397 avatar Jan 23 '21 21:01 Kartik1397