Skip to content

Commit

Permalink
feat: add isFirst and isLast methods to useStateList hook
Browse files Browse the repository at this point in the history
feat(pencil): add isFirst and isLast return value to 'useStateList'
  • Loading branch information
streamich committed Jan 22, 2024
2 parents 82146f6 + 6a9dde5 commit ac64414
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 6 deletions.
10 changes: 6 additions & 4 deletions docs/useStateList.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import { useRef } from 'react';
const stateSet = ['first', 'second', 'third', 'fourth', 'fifth'];

const Demo = () => {
const { state, prev, next, setStateAt, setState, currentIndex } = useStateList(stateSet);
const { state, prev, next, setStateAt, setState, currentIndex, isFirst, isLast } = useStateList(stateSet);
const indexInput = useRef<HTMLInputElement>(null);
const stateInput = useRef<HTMLInputElement>(null);

return (
<div>
<pre>
{state} [index: {currentIndex}]
{state} [index: {currentIndex}], [isFirst: {isFirst}], [isLast: {isLast}]
</pre>
<button onClick={() => prev()}>prev</button>
<br />
Expand All @@ -38,7 +38,7 @@ const Demo = () => {
## Reference

```ts
const { state, currentIndex, prev, next, setStateAt, setState } = useStateList<T>(stateSet: T[] = []);
const { state, currentIndex, prev, next, setStateAt, setState, isFirst, isLast } = useStateList<T>(stateSet: T[] = []);
```

If `stateSet` changed, became shorter than before and `currentIndex` left in shrunk gap - the last element of list will be taken as current.
Expand All @@ -48,5 +48,7 @@ If `stateSet` changed, became shorter than before and `currentIndex` left in shr
- **`prev()`**_`: void`_ &mdash; switches state to the previous one. If first element selected it will switch to the last one;
- **`next()`**_`: void`_ &mdash; switches state to the next one. If last element selected it will switch to the first one;
- **`setStateAt(newIndex: number)`**_`: void`_ &mdash; set the arbitrary state by index. Indexes are looped, and can be negative.
_4ex:_ if list contains 5 elements, attempt to set index 9 will bring use to the 5th element, in case of negative index it will start counting from the right, so -17 will bring us to the 4th element.
_4ex:_ if list contains 5 elements, attempt to set index 9 will bring use to the 5th element, in case of negative index it will start counting from the right, so -17 will bring us to the 4th element.
- **`setState(state: T)`**_`: void`_ &mdash; set the arbitrary state value that exists in `stateSet`. _In case new state does not exists in `stateSet` an Error will be thrown._
- **`isFirst`**_`: boolean`_ &mdash; `true` if current state is the first one.
- **`isLast`**_`: boolean`_ &mdash; `true` if current state is the last one.
4 changes: 4 additions & 0 deletions src/useStateList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export interface UseStateListReturn<T> {
setState: (state: T) => void;
next: () => void;
prev: () => void;
isFirst: boolean;
isLast: boolean;
}

export default function useStateList<T>(stateSet: T[] = []): UseStateListReturn<T> {
Expand Down Expand Up @@ -68,6 +70,8 @@ export default function useStateList<T>(stateSet: T[] = []): UseStateListReturn<
return {
state: stateSet[index.current],
currentIndex: index.current,
isFirst: index.current === 0,
isLast: index.current === stateSet.length - 1,
...actions,
};
}
5 changes: 3 additions & 2 deletions stories/useStateList.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import ShowDocs from './util/ShowDocs';
const stateSet = ['first', 'second', 'third', 'fourth', 'fifth'];

const Demo = () => {
const { state, prev, next, setStateAt, setState, currentIndex } = useStateList(stateSet);
const { state, prev, next, setStateAt, setState, currentIndex, isFirst, isLast } =
useStateList(stateSet);
const indexInput = useRef<HTMLInputElement>(null);
const stateInput = useRef<HTMLInputElement>(null);

return (
<div>
<pre>
{state} [index: {currentIndex}]
{state} [index: {currentIndex}], [isFirst: {isFirst}], [isLast: {isLast}]
</pre>
<button onClick={() => prev()}>prev</button>
<br />
Expand Down
13 changes: 13 additions & 0 deletions tests/useStateList.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,26 @@ describe('useStateList', () => {
next: expect.any(Function),
setStateAt: expect.any(Function),
setState: expect.any(Function),
isFirst: expect.any(Boolean),
isLast: expect.any(Boolean),
});
});

it('should return the first state on init', () => {
expect(getHook().result.current.state).toBe('a');
});

it('should return isFirst on init', () => {
expect(getHook().result.current.isFirst).toBe(true);
});

it('should return isLast when on last state', () => {
const hook = getHook();
act(() => hook.result.current.setStateAt(2));

expect(hook.result.current.isLast).toBe(true);
});

describe('setState()', () => {
it('should set state value if it exists in states list', () => {
const hook = getHook();
Expand Down

0 comments on commit ac64414

Please sign in to comment.