diff --git a/src/config/lexics/public.tsx b/src/config/lexics/public.tsx
new file mode 100644
index 00000000..72a7c501
--- /dev/null
+++ b/src/config/lexics/public.tsx
@@ -0,0 +1,3 @@
+export const publicLexics = {
+ authorization: 500,
+}
diff --git a/src/features/App/UnauthenticatedApp.tsx b/src/features/App/UnauthenticatedApp.tsx
index a4e7a5a8..bad1d9b6 100644
--- a/src/features/App/UnauthenticatedApp.tsx
+++ b/src/features/App/UnauthenticatedApp.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { Fragment } from 'react'
import {
Route,
Redirect,
@@ -6,20 +6,27 @@ import {
} from 'react-router-dom'
import { PAGES } from 'config'
+import { publicLexics } from 'config/lexics/public'
import { Login } from 'features/Login'
import { Register } from 'features/Register'
+import { useLexicsConfig } from 'features/LexicsStore'
-export const UnauthenticatedApp = () => (
-
-
-
-
+export const UnauthenticatedApp = () => {
+ useLexicsConfig(publicLexics)
+ return (
+
+
+
+
+
-
-
-
+
+
+
-
-
-)
+
+
+
+ )
+}
diff --git a/src/features/LexicsStore/index.tsx b/src/features/LexicsStore/index.tsx
index 23325084..1e21c456 100644
--- a/src/features/LexicsStore/index.tsx
+++ b/src/features/LexicsStore/index.tsx
@@ -2,8 +2,10 @@ import type { ReactNode } from 'react'
import React, {
createContext,
useContext,
+ useEffect,
} from 'react'
+import { LexicsConfig } from './types'
import { useLexics } from './hooks'
type LexicsStore = ReturnType
@@ -17,3 +19,11 @@ export const LexicsStore = ({ children }: Props) => {
}
export const useLexicsStore = () => useContext(LexicsContext)
+
+export const useLexicsConfig = (config: LexicsConfig) => {
+ const { addLexicsConfig } = useLexicsStore()
+
+ useEffect(() => {
+ addLexicsConfig(config)
+ }, [addLexicsConfig, config])
+}
diff --git a/src/features/OutsideClick/hooks/index.tsx b/src/features/OutsideClick/hooks/index.tsx
new file mode 100644
index 00000000..ca065c82
--- /dev/null
+++ b/src/features/OutsideClick/hooks/index.tsx
@@ -0,0 +1,30 @@
+import { useEffect, useRef } from 'react'
+
+type TUseOutsideClickEffect = {
+ onClick: Function,
+}
+
+export const useOutsideClickEffect = ({
+ onClick,
+}: TUseOutsideClickEffect) => {
+ const wrapperRef = useRef(null)
+ useEffect(() => {
+ const handleOutsideClick = ({ target }: MouseEvent) => {
+ const targetNode = target instanceof Node
+ ? target
+ : null
+
+ /** деструктуризация wrapperRef не сработает, ссылка на реф теряется */
+ if (wrapperRef.current && !wrapperRef.current.contains(targetNode)) {
+ onClick()
+ }
+ }
+
+ window.addEventListener('mousedown', handleOutsideClick)
+
+ return () => {
+ window.removeEventListener('mousedown', handleOutsideClick)
+ }
+ }, [onClick, wrapperRef])
+ return wrapperRef
+}
diff --git a/src/features/OutsideClick/index.tsx b/src/features/OutsideClick/index.tsx
new file mode 100644
index 00000000..822cb023
--- /dev/null
+++ b/src/features/OutsideClick/index.tsx
@@ -0,0 +1,28 @@
+import type { ReactNode } from 'react'
+import React from 'react'
+
+import styled from 'styled-components'
+
+import { useOutsideClickEffect } from './hooks'
+
+type Props = {
+ /** элемент, которому необходим функционал `OutsideClick` */
+ children: ReactNode,
+ /** функция-коллбек, отрабатывающая по клику вне области элемента */
+ onClick: () => void,
+}
+
+const OutsideClickWrapper = styled.div``
+
+export const OutsideClick = ({
+ children,
+ onClick,
+}: Props) => {
+ const wrapperRef = useOutsideClickEffect({ onClick })
+
+ return (
+
+ {children}
+
+ )
+}
diff --git a/src/hooks/index.tsx b/src/hooks/index.tsx
index 4c227a28..c0595961 100644
--- a/src/hooks/index.tsx
+++ b/src/hooks/index.tsx
@@ -1,2 +1,3 @@
export * from './usePageId'
export * from './useCurrentLang'
+export * from './useToggle'
diff --git a/src/hooks/useToggle.tsx b/src/hooks/useToggle.tsx
new file mode 100644
index 00000000..a2827d0f
--- /dev/null
+++ b/src/hooks/useToggle.tsx
@@ -0,0 +1,14 @@
+import { useState, useCallback } from 'react'
+
+export const useToggle = () => {
+ const [isOpen, setIsOpen] = useState(false)
+ const open = useCallback(() => setIsOpen(true), [])
+ const close = useCallback(() => setIsOpen(false), [])
+ const toggle = useCallback(() => setIsOpen((state) => !state), [])
+ return {
+ close,
+ isOpen,
+ open,
+ toggle,
+ }
+}