From b66706c997693e5d58a8fce44ee25737acff92e3 Mon Sep 17 00:00:00 2001 From: dev2820 Date: Fri, 31 May 2024 20:54:24 +0900 Subject: [PATCH 1/3] feat: implements useDisclosure --- .../useDisclosure/Disclosure.stories.ts | 19 +++++++ src/stories/useDisclosure/Docs.mdx | 56 +++++++++++++++++++ .../useDisclosure/UseDisclosureExample.tsx | 23 ++++++++ src/useDisclosure/_useDisclosure.test.ts | 28 ++++++++++ src/useDisclosure/useDisclosure.ts | 22 ++++++++ 5 files changed, 148 insertions(+) create mode 100644 src/stories/useDisclosure/Disclosure.stories.ts create mode 100644 src/stories/useDisclosure/Docs.mdx create mode 100644 src/stories/useDisclosure/UseDisclosureExample.tsx create mode 100644 src/useDisclosure/_useDisclosure.test.ts create mode 100644 src/useDisclosure/useDisclosure.ts diff --git a/src/stories/useDisclosure/Disclosure.stories.ts b/src/stories/useDisclosure/Disclosure.stories.ts new file mode 100644 index 0000000..982d6bb --- /dev/null +++ b/src/stories/useDisclosure/Disclosure.stories.ts @@ -0,0 +1,19 @@ +import { Meta, StoryObj } from '@storybook/react'; +import UseDisclosureExample from './UseDisclosureExample'; + +const meta = { + title: 'hooks/useDisclosure', + component: UseDisclosureExample, + parameters: { + layout: 'centered', + docs: { + canvas: {}, + }, + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const defaultStory: Story = {}; diff --git a/src/stories/useDisclosure/Docs.mdx b/src/stories/useDisclosure/Docs.mdx new file mode 100644 index 0000000..9896f45 --- /dev/null +++ b/src/stories/useDisclosure/Docs.mdx @@ -0,0 +1,56 @@ +import { Canvas, Meta, Description } from '@storybook/blocks'; +import * as DisclosureStories from './Disclosure.stories'; + + + +# useDisclosure + +useDisclosure를 통해 선언적으로 Modal, Disclosure등의 컴포넌트를 관리할 수 있습니다. + +## 함수인자 + +defaultValue를 통해 초기 요소의 열림/닫힘 상태를 결정할 수 있습니다. + +## 반환값 + +### `isOpen` (default `false`) + +요소의 열림 상태를 나타냅니다. 요소가 열려있으면 `true`, 아니면 `false`입니다. + +### `open` + +요소를 열림 상태로 전환합니다. + +### `close` + +요소를 닫힘 상태로 전환합니다. + +## 기본 사용 예시 + +```typescript +import useDisclosure from '../../useDisclosure/useDisclosure'; +import React from 'react'; + +export default function UseDisclosureExample() { + const modal = useDisclosure(false); + + const handleOpenModal = () => { + modal.open(); + }; + const handleCloseModal = () => { + modal.close(); + }; + + return ( + + ); +} +``` + + diff --git a/src/stories/useDisclosure/UseDisclosureExample.tsx b/src/stories/useDisclosure/UseDisclosureExample.tsx new file mode 100644 index 0000000..d54fa81 --- /dev/null +++ b/src/stories/useDisclosure/UseDisclosureExample.tsx @@ -0,0 +1,23 @@ +import useDisclosure from '../../useDisclosure/useDisclosure'; +import React from 'react'; + +export default function UseDisclosureExample() { + const modal = useDisclosure(false); + + const handleOpenModal = () => { + modal.open(); + }; + const handleCloseModal = () => { + modal.close(); + }; + + return ( + + ); +} diff --git a/src/useDisclosure/_useDisclosure.test.ts b/src/useDisclosure/_useDisclosure.test.ts new file mode 100644 index 0000000..6e4f45a --- /dev/null +++ b/src/useDisclosure/_useDisclosure.test.ts @@ -0,0 +1,28 @@ +import useDisclosure from './useDisclosure'; +import { renderHook, act } from '@testing-library/react'; + +describe('useDisclosure 기능테스트', () => { + it('useDisclosure는 modal, disclosure와 같이 컴포넌트의 열림과 닫힘 상태를 조절할 수 있는 기능들을 반환한다.', () => { + const { result } = renderHook(() => useDisclosure(false)); + + expect(result.current.isOpen).toBe(false); + act(() => { + result.current.open(); + }); + expect(result.current.isOpen).toBe(true); + act(() => { + result.current.close(); + }); + expect(result.current.isOpen).toBe(false); + }); + + it('useDisclosure는 초기값을 파라미터로 받는다.', () => { + const { result: resultFalse } = renderHook(() => useDisclosure(false)); + const { result: resultTrue } = renderHook(() => useDisclosure(true)); + const maybeFalse = resultFalse.current.isOpen; + const maybeTrue = resultTrue.current.isOpen; + + expect(maybeFalse).toBe(false); + expect(maybeTrue).toBe(true); + }); +}); diff --git a/src/useDisclosure/useDisclosure.ts b/src/useDisclosure/useDisclosure.ts new file mode 100644 index 0000000..7682c6e --- /dev/null +++ b/src/useDisclosure/useDisclosure.ts @@ -0,0 +1,22 @@ +import useBoolean from '../useBoolean/useBoolean'; +import { useCallback } from 'react'; + +export type UseDisclosureReturn = ReturnType; + +export default function useDisclosure(defaultValue: boolean = false) { + const [isOpen, setIsOpen] = useBoolean(defaultValue); + + const open = useCallback(() => { + setIsOpen(true); + }, [setIsOpen]); + + const close = useCallback(() => { + setIsOpen(false); + }, [setIsOpen]); + + return { + isOpen, + open, + close, + }; +} From 25f6128d5617251b5efa1bf9c765a80308afeeb0 Mon Sep 17 00:00:00 2001 From: dev2820 Date: Fri, 31 May 2024 20:50:22 +0900 Subject: [PATCH 2/3] docs: update README (useDisclosure) --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index a61f677..5bbc99d 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,35 @@ function App() { } ``` +### useDisclosure + +`useDisclosure` is a custom hook for managing the open/closed state of a component. It initializes the state and provides open and close functions to control the component's visibility. This allows for easy and efficient control of the modal, disclosure, ...etc's open/closed state. + +```tsx +import useBoolean from '../useBoolean/useBoolean'; +import { useCallback } from 'react'; + +export type UseDisclosureReturn = ReturnType; + +export default function useDisclosure(defaultValue: boolean = false) { + const [isOpen, setIsOpen] = useBoolean(defaultValue); + + const open = useCallback(() => { + setIsOpen(true); + }, [setIsOpen]); + + const close = useCallback(() => { + setIsOpen(false); + }, [setIsOpen]); + + return { + isOpen, + open, + close, + }; +} +``` + #### Generic ``: Type of data stored on local storage. From 4f3ed289f58848cef39767934787cc87cfe41c48 Mon Sep 17 00:00:00 2001 From: dev2820 Date: Fri, 31 May 2024 20:51:17 +0900 Subject: [PATCH 3/3] fix: add useDisclosure to index.ts for export --- src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.ts b/src/index.ts index e147401..621c9bd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,7 @@ import useRadio from './useRadio/useRadio'; import useThrottle from './useThrottle/useThrottle'; import useDebounce from './useDebounce/useDebounce'; import useLocalStorage from './useLocalStorage/useLocalStorage'; +import useDisclosure from './useDisclosure/useDisclosure'; export { useInput, @@ -24,4 +25,5 @@ export { useThrottle, useDebounce, useLocalStorage, + useDisclosure, };