demo working with the first action
This commit is contained in:
parent
648f9464cb
commit
e3635677d5
@ -1,5 +1,50 @@
|
|||||||
import React from 'react';
|
import React, { useReducer } from 'react';
|
||||||
|
import { useAnimatedListItems } from './useAnimatedListItems';
|
||||||
|
|
||||||
|
type Mutation = 'reverse' | 'randomize' | 'insert' | 'remove';
|
||||||
|
|
||||||
export const AnimatedListDemo = () => {
|
export const AnimatedListDemo = () => {
|
||||||
return <main>Hello, world</main>;
|
const [items, mutateItems] = useReducer(
|
||||||
|
(prevState: string[], mutation: Mutation) => {
|
||||||
|
switch (mutation) {
|
||||||
|
case 'reverse':
|
||||||
|
const newState = [...prevState];
|
||||||
|
newState.reverse();
|
||||||
|
return newState;
|
||||||
|
default:
|
||||||
|
return prevState;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['Item 0', 'Item 1', 'Item 2', 'Item 3'],
|
||||||
|
);
|
||||||
|
|
||||||
|
const { updateItemRef, updateItemPositions, itemStyles } =
|
||||||
|
useAnimatedListItems({ keys: items });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<ol>
|
||||||
|
{items.map((item) => {
|
||||||
|
return (
|
||||||
|
<li
|
||||||
|
key={item}
|
||||||
|
ref={(li) => updateItemRef(item, li)}
|
||||||
|
style={itemStyles[item]}
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ol>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
updateItemPositions();
|
||||||
|
mutateItems('reverse');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Reverse
|
||||||
|
</button>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,6 @@ class AnimatedListComponent extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
console.log('Hello, world!');
|
|
||||||
const rootNode = document.createElement('main');
|
const rootNode = document.createElement('main');
|
||||||
this.appendChild(rootNode);
|
this.appendChild(rootNode);
|
||||||
this.root = createRoot(rootNode);
|
this.root = createRoot(rootNode);
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { useLayoutEffect, useRef, useState } from 'react';
|
import { useLayoutEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
interface ItemTops {
|
interface ItemTops {
|
||||||
[id: number]: number | undefined;
|
[id: string]: number | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ListItemRefsById {
|
interface ListItemRefsById {
|
||||||
[id: number]: HTMLLIElement | undefined;
|
[id: string]: HTMLLIElement | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ItemOffsets {
|
interface ItemOffsets {
|
||||||
[id: number]: number | undefined;
|
[id: string]: number | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ItemStyles {
|
interface ItemStyles {
|
||||||
@ -26,7 +26,7 @@ interface UseAnimatedListItemArgs {
|
|||||||
* The list of item keys. Each key should uniquely identify a `<ListItem>` component, and
|
* The list of item keys. Each key should uniquely identify a `<ListItem>` component, and
|
||||||
* should be the same value passed to the `ListItem`'s `key` prop.
|
* should be the same value passed to the `ListItem`'s `key` prop.
|
||||||
*/
|
*/
|
||||||
keys: number[] | undefined;
|
keys: string[] | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UseAnimatedListItemReturns {
|
interface UseAnimatedListItemReturns {
|
||||||
@ -34,16 +34,16 @@ interface UseAnimatedListItemReturns {
|
|||||||
* Item styles that should be passed to the `sx` prop of each `ListItem`. The styles are
|
* Item styles that should be passed to the `sx` prop of each `ListItem`. The styles are
|
||||||
* mapped per item key.
|
* mapped per item key.
|
||||||
*/
|
*/
|
||||||
itemStyles: { [key: number]: ItemStyles | undefined };
|
itemStyles: { [key: string]: ItemStyles | undefined };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function that must be called within the `ref` callback prop of each `ListItem`.
|
* Function that must be called within the `ref` callback prop of each `ListItem`.
|
||||||
*
|
*
|
||||||
* @param {number} key - the `ListItem`'s unique key.
|
* @param {string} key - the `ListItem`'s unique key.
|
||||||
* @param {HTMLLIElement} li - the list item element reference.
|
* @param {HTMLLIElement} li - the list item element reference.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
updateItemRef: (key: number, li: HTMLLIElement | null) => void;
|
updateItemRef: (key: string, li: HTMLLIElement | null) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function that must be called within each and every callback that causes the list of items
|
* Function that must be called within each and every callback that causes the list of items
|
||||||
@ -68,7 +68,6 @@ export const useAnimatedListItems = ({
|
|||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (!keys) return;
|
if (!keys) return;
|
||||||
|
|
||||||
const newItemOffsets: ItemOffsets = {};
|
const newItemOffsets: ItemOffsets = {};
|
||||||
keys.forEach((key) => {
|
keys.forEach((key) => {
|
||||||
const itemRef = itemRefs.current[key];
|
const itemRef = itemRefs.current[key];
|
||||||
|
Loading…
Reference in New Issue
Block a user