aholachek / react-flip-toolkit

A lightweight magic-move library for configurable layout transitions
MIT License
4.02k stars 135 forks source link

cannot use functionnal component on Demo list card #216

Open c0ncentus opened 7 months ago

c0ncentus commented 7 months ago
import { useState } from "react";
import { Flipped, Flipper, spring } from "react-flip-toolkit";

const DATA_FILTER = [
  { id: 1, title: "Twas brillig and the slithy toves" },
  { id: 2, title: "Did gyre and gimbel in the wabe" },
  { id: 3, title: "All mimsy were the borogroves" },
  {
    id: 4,
    title: "The mome raths outgrabe"
  },
  {
    id: 5,
    title: "Beware the jabberwock my son!!"
  },
  { id: 6, title: "The jaws that bite, the claws that snatch" }
];

function Card({ id, title, type, stagger, addToFilteredIds }: { id, title: string, type, stagger, addToFilteredIds }) {
  const onElementAppear = (el, index) => spring({ onUpdate: val => { el.style.opacity = val; }, delay: index * 50 });

  const onExit = type => (el: HTMLElement, index: number, removeElement: () => void) => {
    spring({
      config: { overshootClamping: true },
      onUpdate: val => { el.style.transform = `scale${type === "grid" ? "X" : "Y"}(${1 - (val as any)})`; },
      delay: index * 50,
      onComplete: removeElement
    });
    return () => {
      el.style.opacity = "";
      removeElement();
    };
  };
  const onGridExit = onExit("grid");
  const onListExit = onExit("list");
  const shouldFlip = (prev, current) => {
    if (prev.type !== current.type) { return true; }
    return false;
  };
  const flipId = `item-${id}`;
  return (
    <Flipped flipId={flipId} onAppear={onElementAppear} onExit={type === "grid" ? onGridExit : onListExit} key={flipId} stagger={stagger} shouldInvert={shouldFlip}>
      <li className="fm-item">
        <Flipped inverseFlipId={flipId}>
          <div>
            <Flipped flipId={`${flipId}-content`} translate shouldFlip={shouldFlip} delayUntil={flipId}> <div> <h3>{title}</h3> <p>{title}</p></div></Flipped>
            <Flipped flipId={`${flipId}-button`} shouldFlip={shouldFlip} delayUntil={flipId}>
              <button className="fm-remove" onClick={() => addToFilteredIds(id)}>&times;</button>
            </Flipped>
          </div>
        </Flipped>
      </li>
    </Flipped>
  );
}

export function ListExample() {
  const [sort, setSort] = useState<"asc" | "desc">("asc")
  const [filteredIds, setFilteredIds] = useState<any[]>([])

  const state = { type: "grid", sort: sort, filteredIds: filteredIds, stagger: "none", spring: "noWobble" };

  const addToFilteredIds = id => { setFilteredIds([...filteredIds, id]) };

  return (
    <div className="fm-example">
      <Flipper
        flipKey={`${state.type}-${state.sort}-${JSON.stringify(state.filteredIds)}-${JSON.stringify(state.stagger)}`}
        spring={state.spring}
        staggerConfig={{ default: { reverse: state.stagger !== "forward", speed: 1 } }}
        decisionData={state}
      >
        <div className="fm-flex-container">
          <fieldset>
            <legend>Sort</legend>
            <label onClick={() => { setSort('asc') }}>
              <input type="radio" name="sort" checked={state.sort === "asc"} />
              asc
            </label>
            <label onClick={() => { setSort('desc') }}>
              <input type="radio" name="sort" checked={state.sort === "desc"} />
              desc
            </label>
          </fieldset>
        </div>
        <div>
          {!!state.filteredIds.length && (
            <button className="fm-show-all" onClick={() => { setFilteredIds([]) }}>
              show all cards
            </button>
          )}
        </div>

        <Flipped flipId="list">
          <div className={state.type === "grid" ? "fm-grid" : "fm-list"}>
            <Flipped inverseFlipId="list">
              <ul className="list-contents">
                {[...DATA_FILTER]
                  .filter(d => state.filteredIds.includes(d.id)===false)
                  .sort((a, b) => {
                    if (state.sort === "asc") { return a.id - b.id; }
                    else { return b.id - a.id; }
                  })
                  .map(({ title, id }) => (<Card id={id} title={title} stagger={state.stagger} type={state.type} key={id} addToFilteredIds={addToFilteredIds}/>))}
              </ul>
            </Flipped>
          </div>
        </Flipped>
      </Flipper>
    </div>
  );
}
Each Flipped component must wrap a single child

I also test without remoove button and again error ... no error on my lint*