From 63dabbbd9ddf8bd4d93efc028065cf0b3158c6c0 Mon Sep 17 00:00:00 2001 From: Punit Soni Date: Mon, 29 Jul 2024 16:47:14 +0530 Subject: [PATCH] feat(useColorScheme): new hook added resolves #21 --- README.md | 2 + .../src/common/Details/RedirectToExample.tsx | 7 ++-- example/src/hooks/useArray/index.tsx | 10 ----- example/src/hooks/useColorScheme/index.tsx | 42 +++++++++++++++++++ example/src/lib/utils.ts | 5 ++- example/src/pages/Layout/index.tsx | 17 ++++++-- example/src/pages/Sidebar/HooksList.tsx | 10 ++--- src/index.tsx | 1 + src/useColorScheme/index.tsx | 23 ++++++++++ 9 files changed, 94 insertions(+), 23 deletions(-) create mode 100644 example/src/hooks/useColorScheme/index.tsx create mode 100644 src/useColorScheme/index.tsx diff --git a/README.md b/README.md index 9bb0092..0d938fa 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,9 @@ yarn add react-helper-hooks - useArray - [![][documentation-demo]](https://punitsonime.github.io/react-helper-hooks/#useArray) - useAsync - [![][documentation-demo]](https://punitsonime.github.io/react-helper-hooks/#useAsync) - useAsyncLoop - [![][documentation-demo]](https://punitsonime.github.io/react-helper-hooks/#useAsyncLoop) +- useClickOutside - [![][documentation-demo]](https://punitsonime.github.io/react-helper-hooks/#useClickOutside) - useColorBlend - [![][documentation-demo]](https://punitsonime.github.io/react-helper-hooks/#useColorBlend) +- useColorScheme - [![][documentation-demo]](https://punitsonime.github.io/react-helper-hooks/#useColorScheme) - useCopyToClipboard - [![][documentation-demo]](https://punitsonime.github.io/react-helper-hooks/#useCopyToClipboard) - useDebounce - [![][documentation-demo]](https://punitsonime.github.io/react-helper-hooks/#useDebounce) - useEventListener - [![][documentation-demo]](https://punitsonime.github.io/react-helper-hooks/#useEventListener) diff --git a/example/src/common/Details/RedirectToExample.tsx b/example/src/common/Details/RedirectToExample.tsx index 94eca33..8ed8f58 100644 --- a/example/src/common/Details/RedirectToExample.tsx +++ b/example/src/common/Details/RedirectToExample.tsx @@ -1,9 +1,10 @@ import { Button } from '@/components/ui/button' +import { githubUrl } from '@/lib/utils'; import { MoveUpRightIcon } from 'lucide-react' -const githubUrl = 'https://github.com/PunitSoniME/react-helper-hooks/blob/main' -const hookCodeUrl = `${githubUrl}/src`; -const exampleCodeUrl = `${githubUrl}/example/src/hooks`; +const extendedGithubUrl = `${githubUrl}/blob/main`; +const hookCodeUrl = `${extendedGithubUrl}/src`; +const exampleCodeUrl = `${extendedGithubUrl}/example/src/hooks`; export default function RedirectToExample({ hook }: any) { diff --git a/example/src/hooks/useArray/index.tsx b/example/src/hooks/useArray/index.tsx index 2002810..ae13343 100644 --- a/example/src/hooks/useArray/index.tsx +++ b/example/src/hooks/useArray/index.tsx @@ -27,16 +27,6 @@ export default function Component() { const { array, set, push, remove, filter, update, clear } = ${hook}([DATA]); }` -const api = [ - { execute: 'array', type: 'array', description: 'Data on which operation to perform' }, - { execute: 'set', type: 'function', description: 'Re-initialize the array with new data' }, - { execute: 'push', type: 'function', description: 'Insert an element in array' }, - { execute: 'remove', type: 'function', description: 'Remove an element from array' }, - { execute: 'filter', type: 'function', description: 'Filter out the data from array ( This will mutate the source )' }, - { execute: 'update', type: 'function', description: 'Update any element of array' }, - { execute: 'clear', type: 'function', description: 'Clear whole array' } -]; - export default function ArrayComponent() { const { array, set, push, remove, filter, update, clear } = useArray([1, 2, 3, 4, 5, 6]) diff --git a/example/src/hooks/useColorScheme/index.tsx b/example/src/hooks/useColorScheme/index.tsx new file mode 100644 index 0000000..edd9fe9 --- /dev/null +++ b/example/src/hooks/useColorScheme/index.tsx @@ -0,0 +1,42 @@ +import { lazy, Suspense } from 'react'; +import { useColorScheme } from '../../../../'; +import { packageName } from '@/lib/utils'; + +const Block = lazy(() => import('@/common/Details/Block')); +const Documentation = lazy(() => import('@/common/Documentation')); + +const hook = 'useColorScheme'; +const info = "Use this hook to get the current color scheme either 'dark' or 'light'" + +const usage: string = `import { ${hook} } from '${packageName}'; + +export default function Component() { + /* + @returns - Current color scheme + */ + const colorScheme = ${hook}(); +}` + +export default function ColorSchemeComponent() { + + const colorScheme = useColorScheme(); + + return ( + }> + + + + + + Current color scheme is - {colorScheme} + + + + + + ) +} diff --git a/example/src/lib/utils.ts b/example/src/lib/utils.ts index 45c282f..02e4de7 100644 --- a/example/src/lib/utils.ts +++ b/example/src/lib/utils.ts @@ -5,7 +5,6 @@ import { twMerge } from "tailwind-merge" export const packageName = 'react-helper-hooks'; export const githubUrl = 'https://github.com/PunitSoniME/react-helper-hooks'; -export const exampleMarkDownPrefixUrl = `${githubUrl}/blob/main/src/docs`; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) @@ -38,6 +37,7 @@ const SpeechComponent = lazy(() => import('@/hooks/useSpeech')); const ProvidersTreeComponent = lazy(() => import('@/hooks/useProvidersTree')); const HashComponent = lazy(() => import('@/hooks/useHash')); const ClickOutsideComponent = lazy(() => import('@/hooks/useClickOutside')); +const ColorSchemeComponent = lazy(() => import('@/hooks/useColorScheme')); export const hooks = [ { key: 'useToggle', Component: ToggleComponent }, @@ -66,7 +66,8 @@ export const hooks = [ { key: 'useSpeech', Component: SpeechComponent }, { key: 'useProvidersTree', Component: ProvidersTreeComponent }, { key: 'useHash', Component: HashComponent }, - { key: 'useClickOutside', Component: ClickOutsideComponent, isNew: true } + { key: 'useClickOutside', Component: ClickOutsideComponent, isNew: true }, + { key: 'useColorScheme', Component: ColorSchemeComponent, isNew: true } ]; export const props = { diff --git a/example/src/pages/Layout/index.tsx b/example/src/pages/Layout/index.tsx index 83941b8..6c19765 100644 --- a/example/src/pages/Layout/index.tsx +++ b/example/src/pages/Layout/index.tsx @@ -1,11 +1,10 @@ -import { lazy, Suspense } from 'react' +import { lazy, Suspense, useMemo } from 'react' import { useHash } from '../../../../.'; import { hooks, props } from '@/lib/utils'; import { ScrollArea } from '@/components/ui/scroll-area'; import classes from './Layout.module.css'; import RedirectToExample from '@/common/Details/RedirectToExample'; import { Sheet, SheetContent } from '@/components/ui/sheet'; -import Title from '@/common/Details/Title'; const Header = lazy(() => import('../Header')); const Sidebar = lazy(() => import('../Sidebar')); @@ -15,7 +14,19 @@ const LandingPage = lazy(() => import('../LandingPage')); export default function Layout() { const [hash,] = useHash(); - const selectedHook: string = hash ? (hash as string).split('#')[1] : ""; + // const selectedHook: string = hash ? (hash as string).split('#')[1] : ""; + + const selectedHook = useMemo(() => { + if (hash) { + const splittedHookName = (hash as string).split('#')[1]?.toLowerCase(); + if (splittedHookName) { + const hookDetails = hooks.find(f => f.key.toLowerCase() === splittedHookName); + return hookDetails?.key; + } + return ""; + } + return ""; + }, [hash]); // @ts-ignore const Component = hooks.find(f => f.key === selectedHook)?.Component || null; diff --git a/example/src/pages/Sidebar/HooksList.tsx b/example/src/pages/Sidebar/HooksList.tsx index f2ff24a..12cf9b6 100644 --- a/example/src/pages/Sidebar/HooksList.tsx +++ b/example/src/pages/Sidebar/HooksList.tsx @@ -13,8 +13,8 @@ export default function HooksList() { const filteredComponents = components.filter(f => f.key.toLowerCase().includes(search.toLowerCase())); - const [hash, setHash] = useHash(); - const selectedHook = hash ? hash.split('#')[1] : ""; + const [hash, updateHash] = useHash(); + const selectedHook = hash ? (hash as string).split('#')[1]?.toLowerCase() : ""; return ( <> @@ -36,13 +36,13 @@ export default function HooksList() { diff --git a/src/index.tsx b/src/index.tsx index c83f05c..db9e64b 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -26,5 +26,6 @@ export { default as useHash } from './useHash'; export { default as useSpeech } from './useSpeech'; export { default as useProvidersTree } from './useProvidersTree'; export { default as useClickOutside } from './useClickOutside'; +export { default as useColorScheme } from './useColorScheme'; export { useLocalStorage, useSessionStorage }; diff --git a/src/useColorScheme/index.tsx b/src/useColorScheme/index.tsx new file mode 100644 index 0000000..aef8846 --- /dev/null +++ b/src/useColorScheme/index.tsx @@ -0,0 +1,23 @@ +import { useEffect, useState } from "react"; + +export default function useColorScheme() { + const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; + + const [colorScheme, setColorScheme] = useState<'dark' | 'light'>(isDarkMode ? 'dark' : 'light'); + + useEffect(() => { + + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { + const newColorScheme = event.matches ? "dark" : "light" + setColorScheme(newColorScheme); + }); + + return () => { + window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', event => { + setColorScheme(event.matches ? "dark" : "light"); + }); + } + }, []); + + return colorScheme; +}