@c-rex/contexts 0.1.21 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +53 -53
- package/src/config-provider.tsx +126 -127
- package/src/highlight-provider.tsx +77 -77
- package/src/search.tsx +33 -33
package/package.json
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@c-rex/contexts",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"files": [
|
|
6
|
-
"src"
|
|
7
|
-
],
|
|
8
|
-
"publishConfig": {
|
|
9
|
-
"access": "public"
|
|
10
|
-
},
|
|
11
|
-
"exports": {
|
|
12
|
-
"./config-provider": {
|
|
13
|
-
"types": "./src/config-provider.tsx",
|
|
14
|
-
"import": "./src/config-provider.tsx"
|
|
15
|
-
},
|
|
16
|
-
"./search": {
|
|
17
|
-
"types": "./src/search.tsx",
|
|
18
|
-
"import": "./src/search.tsx"
|
|
19
|
-
},
|
|
20
|
-
"./highlight-provider": {
|
|
21
|
-
"types": "./src/highlight-provider.tsx",
|
|
22
|
-
"import": "./src/highlight-provider.tsx"
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
"scripts": {
|
|
26
|
-
"lint": "eslint .",
|
|
27
|
-
"lint:fix": "eslint . --fix"
|
|
28
|
-
},
|
|
29
|
-
"devDependencies": {
|
|
30
|
-
"@c-rex/eslint-config": "*",
|
|
31
|
-
"@c-rex/typescript-config": "*",
|
|
32
|
-
"@turbo/gen": "^2.4.4",
|
|
33
|
-
"@types/node": "^22.13.10",
|
|
34
|
-
"@types/react": "19.0.10",
|
|
35
|
-
"@types/react-dom": "19.0.4",
|
|
36
|
-
"eslint": "^9.23.0",
|
|
37
|
-
"typescript": "latest"
|
|
38
|
-
},
|
|
39
|
-
"dependencies": {
|
|
40
|
-
"next": "^14",
|
|
41
|
-
"react": "^18.3.1",
|
|
42
|
-
"react-dom": "^18.3.1",
|
|
43
|
-
"@c-rex/core": "*",
|
|
44
|
-
"@c-rex/constants": "*",
|
|
45
|
-
"@c-rex/services": "*",
|
|
46
|
-
"@c-rex/utils": "*",
|
|
47
|
-
"@c-rex/interfaces": "*"
|
|
48
|
-
},
|
|
49
|
-
"peerDependencies": {
|
|
50
|
-
"react": "^18.3.1",
|
|
51
|
-
"react-dom": "^18.3.1"
|
|
52
|
-
}
|
|
53
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@c-rex/contexts",
|
|
3
|
+
"version": "0.1.22",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"src"
|
|
7
|
+
],
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
"./config-provider": {
|
|
13
|
+
"types": "./src/config-provider.tsx",
|
|
14
|
+
"import": "./src/config-provider.tsx"
|
|
15
|
+
},
|
|
16
|
+
"./search": {
|
|
17
|
+
"types": "./src/search.tsx",
|
|
18
|
+
"import": "./src/search.tsx"
|
|
19
|
+
},
|
|
20
|
+
"./highlight-provider": {
|
|
21
|
+
"types": "./src/highlight-provider.tsx",
|
|
22
|
+
"import": "./src/highlight-provider.tsx"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"lint": "eslint .",
|
|
27
|
+
"lint:fix": "eslint . --fix"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@c-rex/eslint-config": "*",
|
|
31
|
+
"@c-rex/typescript-config": "*",
|
|
32
|
+
"@turbo/gen": "^2.4.4",
|
|
33
|
+
"@types/node": "^22.13.10",
|
|
34
|
+
"@types/react": "19.0.10",
|
|
35
|
+
"@types/react-dom": "19.0.4",
|
|
36
|
+
"eslint": "^9.23.0",
|
|
37
|
+
"typescript": "latest"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"next": "^14",
|
|
41
|
+
"react": "^18.3.1",
|
|
42
|
+
"react-dom": "^18.3.1",
|
|
43
|
+
"@c-rex/core": "*",
|
|
44
|
+
"@c-rex/constants": "*",
|
|
45
|
+
"@c-rex/services": "*",
|
|
46
|
+
"@c-rex/utils": "*",
|
|
47
|
+
"@c-rex/interfaces": "*"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"react": "^18.3.1",
|
|
51
|
+
"react-dom": "^18.3.1"
|
|
52
|
+
}
|
|
53
|
+
}
|
package/src/config-provider.tsx
CHANGED
|
@@ -1,127 +1,126 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { UI_LANG_KEY,
|
|
4
|
-
import { CookiesConfigs, LanguageAndCountries, AvailableVersionsInterface } from '@c-rex/interfaces'
|
|
5
|
-
import { call } from '@c-rex/utils'
|
|
6
|
-
import { setCookie } from '@c-rex/utils/cookies'
|
|
7
|
-
import React, { createContext, useContext, useEffect, useState } from 'react'
|
|
8
|
-
import { useLanguageStore } from '@c-rex/components/language-store'
|
|
9
|
-
import { useSearchSettingsStore } from '@c-rex/components/search-settings-store'
|
|
10
|
-
|
|
11
|
-
type AppConfigContextType = {
|
|
12
|
-
error: Error | null
|
|
13
|
-
configs: CookiesConfigs
|
|
14
|
-
packageID: string | null
|
|
15
|
-
articleLang: string | null
|
|
16
|
-
availableVersions: AvailableVersionsInterface[] | null
|
|
17
|
-
setAvailableVersions: (versions: AvailableVersionsInterface[] | null) => void
|
|
18
|
-
setPackageID: (id: string | null) => void
|
|
19
|
-
setArticleLang: (lang: string | null) => void
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const AppConfigContext = createContext<AppConfigContextType | undefined>(undefined)
|
|
23
|
-
type AppConfigProviderProps = {
|
|
24
|
-
children: React.ReactNode
|
|
25
|
-
uiLang: string
|
|
26
|
-
contentLang: string
|
|
27
|
-
availableLanguages: LanguageAndCountries[]
|
|
28
|
-
initialConfig: CookiesConfigs
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const AppConfigProvider = ({
|
|
32
|
-
children,
|
|
33
|
-
uiLang,
|
|
34
|
-
contentLang,
|
|
35
|
-
availableLanguages,
|
|
36
|
-
initialConfig
|
|
37
|
-
}: AppConfigProviderProps) => {
|
|
38
|
-
|
|
39
|
-
const [error, setError] = useState<Error | null>(null)
|
|
40
|
-
const [packageID, setPackageID] = useState<string | null>(null)
|
|
41
|
-
const [articleLang, setArticleLang] = useState<string | null>(null)
|
|
42
|
-
const [availableVersions, setAvailableVersions] = useState<AvailableVersionsInterface[] | null>(null)
|
|
43
|
-
|
|
44
|
-
const manageToken = async (): Promise<void> => {
|
|
45
|
-
try {
|
|
46
|
-
const res = await fetch(`/api/cookies?key=${CREX_TOKEN_HEADER_KEY}`);
|
|
47
|
-
|
|
48
|
-
if (!res.ok) {
|
|
49
|
-
await requestToken();
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const hasToken = await res.json();
|
|
54
|
-
|
|
55
|
-
if (hasToken.value === null) {
|
|
56
|
-
await requestToken();
|
|
57
|
-
}
|
|
58
|
-
} catch (error) {
|
|
59
|
-
call("CrexLogger.log", {
|
|
60
|
-
level: "error",
|
|
61
|
-
message: `config-provider.manageToken error: ${error}`
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const requestToken = async (): Promise<void> => {
|
|
67
|
-
try {
|
|
68
|
-
await fetch('/api/oidc/token', {
|
|
69
|
-
method: 'POST',
|
|
70
|
-
credentials: 'include',
|
|
71
|
-
});
|
|
72
|
-
} catch (error) {
|
|
73
|
-
call("CrexLogger.log", {
|
|
74
|
-
level: "error",
|
|
75
|
-
message: `config-provider.requestToken error: ${error}`
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
useEffect(() => {
|
|
81
|
-
useLanguageStore.getState().setAvailableLanguages(availableLanguages)
|
|
82
|
-
useSearchSettingsStore.getState().updatePreferences({
|
|
83
|
-
language: contentLang
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
setCookie(UI_LANG_KEY, uiLang, { httpOnly: false });
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { UI_LANG_KEY, CREX_TOKEN_HEADER_KEY } from '@c-rex/constants'
|
|
4
|
+
import { CookiesConfigs, LanguageAndCountries, AvailableVersionsInterface } from '@c-rex/interfaces'
|
|
5
|
+
import { call } from '@c-rex/utils'
|
|
6
|
+
import { setCookie } from '@c-rex/utils/cookies'
|
|
7
|
+
import React, { createContext, useContext, useEffect, useState } from 'react'
|
|
8
|
+
import { useLanguageStore } from '@c-rex/components/language-store'
|
|
9
|
+
import { useSearchSettingsStore } from '@c-rex/components/search-settings-store'
|
|
10
|
+
|
|
11
|
+
type AppConfigContextType = {
|
|
12
|
+
error: Error | null
|
|
13
|
+
configs: CookiesConfigs
|
|
14
|
+
packageID: string | null
|
|
15
|
+
articleLang: string | null
|
|
16
|
+
availableVersions: AvailableVersionsInterface[] | null
|
|
17
|
+
setAvailableVersions: (versions: AvailableVersionsInterface[] | null) => void
|
|
18
|
+
setPackageID: (id: string | null) => void
|
|
19
|
+
setArticleLang: (lang: string | null) => void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const AppConfigContext = createContext<AppConfigContextType | undefined>(undefined)
|
|
23
|
+
type AppConfigProviderProps = {
|
|
24
|
+
children: React.ReactNode
|
|
25
|
+
uiLang: string
|
|
26
|
+
contentLang: string
|
|
27
|
+
availableLanguages: LanguageAndCountries[]
|
|
28
|
+
initialConfig: CookiesConfigs
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const AppConfigProvider = ({
|
|
32
|
+
children,
|
|
33
|
+
uiLang,
|
|
34
|
+
contentLang,
|
|
35
|
+
availableLanguages,
|
|
36
|
+
initialConfig
|
|
37
|
+
}: AppConfigProviderProps) => {
|
|
38
|
+
|
|
39
|
+
const [error, setError] = useState<Error | null>(null)
|
|
40
|
+
const [packageID, setPackageID] = useState<string | null>(null)
|
|
41
|
+
const [articleLang, setArticleLang] = useState<string | null>(null)
|
|
42
|
+
const [availableVersions, setAvailableVersions] = useState<AvailableVersionsInterface[] | null>(null)
|
|
43
|
+
|
|
44
|
+
const manageToken = async (): Promise<void> => {
|
|
45
|
+
try {
|
|
46
|
+
const res = await fetch(`/api/cookies?key=${CREX_TOKEN_HEADER_KEY}`);
|
|
47
|
+
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
await requestToken();
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const hasToken = await res.json();
|
|
54
|
+
|
|
55
|
+
if (hasToken.value === null) {
|
|
56
|
+
await requestToken();
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
call("CrexLogger.log", {
|
|
60
|
+
level: "error",
|
|
61
|
+
message: `config-provider.manageToken error: ${error}`
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const requestToken = async (): Promise<void> => {
|
|
67
|
+
try {
|
|
68
|
+
await fetch('/api/oidc/token', {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
credentials: 'include',
|
|
71
|
+
});
|
|
72
|
+
} catch (error) {
|
|
73
|
+
call("CrexLogger.log", {
|
|
74
|
+
level: "error",
|
|
75
|
+
message: `config-provider.requestToken error: ${error}`
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
useLanguageStore.getState().setAvailableLanguages(availableLanguages)
|
|
82
|
+
useSearchSettingsStore.getState().updatePreferences({
|
|
83
|
+
language: contentLang
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
setCookie(UI_LANG_KEY, uiLang, { httpOnly: false });
|
|
87
|
+
|
|
88
|
+
const load = async () => {
|
|
89
|
+
try {
|
|
90
|
+
await manageToken()
|
|
91
|
+
setError(null)
|
|
92
|
+
} catch (err) {
|
|
93
|
+
call("CrexLogger.log", {
|
|
94
|
+
level: "error",
|
|
95
|
+
message: `config-provider.load error: ${err}`
|
|
96
|
+
});
|
|
97
|
+
setError(err as Error)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
load()
|
|
102
|
+
}, [])
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<AppConfigContext.Provider
|
|
106
|
+
value={{
|
|
107
|
+
configs: initialConfig,
|
|
108
|
+
error,
|
|
109
|
+
availableVersions,
|
|
110
|
+
packageID,
|
|
111
|
+
articleLang,
|
|
112
|
+
setArticleLang,
|
|
113
|
+
setAvailableVersions,
|
|
114
|
+
setPackageID
|
|
115
|
+
}}
|
|
116
|
+
>
|
|
117
|
+
{children}
|
|
118
|
+
</AppConfigContext.Provider>
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const useAppConfig = () => {
|
|
123
|
+
const ctx = useContext(AppConfigContext)
|
|
124
|
+
if (!ctx) throw new Error('useAppConfig must be used within AppConfigProvider')
|
|
125
|
+
return ctx
|
|
126
|
+
}
|
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
createContext,
|
|
5
|
-
useCallback,
|
|
6
|
-
useContext,
|
|
7
|
-
useEffect,
|
|
8
|
-
useRef,
|
|
9
|
-
useState,
|
|
10
|
-
} from "react";
|
|
11
|
-
|
|
12
|
-
type HighlightContextType = {
|
|
13
|
-
currentIndex: number;
|
|
14
|
-
total: number;
|
|
15
|
-
next: () => void;
|
|
16
|
-
prev: () => void;
|
|
17
|
-
registerContainer: (el: HTMLElement | null) => void;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const HighlightContext = createContext<HighlightContextType | null>(null);
|
|
21
|
-
|
|
22
|
-
export const HighlightProvider = ({ children }: { children: React.ReactNode }) => {
|
|
23
|
-
|
|
24
|
-
const containerRef = useRef<HTMLElement | null>(null);
|
|
25
|
-
const [marks, setMarks] = useState<NodeListOf<HTMLElement> | null>(null);
|
|
26
|
-
const [currentIndex, setCurrentIndex] = useState(-1);
|
|
27
|
-
|
|
28
|
-
const registerContainer = useCallback((el: HTMLElement | null) => {
|
|
29
|
-
containerRef.current = el;
|
|
30
|
-
if (el) {
|
|
31
|
-
const found = el.querySelectorAll("mark");
|
|
32
|
-
setMarks(found);
|
|
33
|
-
setCurrentIndex(found.length > 0 ? 0 : -1);
|
|
34
|
-
} else {
|
|
35
|
-
setMarks(null);
|
|
36
|
-
setCurrentIndex(-1);
|
|
37
|
-
}
|
|
38
|
-
}, []);
|
|
39
|
-
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
if (marks && currentIndex >= 0 && marks[currentIndex]) {
|
|
42
|
-
marks.forEach((m) => m.classList.remove("bg-yellow-200", "bg-orange-300"));
|
|
43
|
-
marks[currentIndex].classList.add("bg-orange-300");
|
|
44
|
-
marks[currentIndex].scrollIntoView({ behavior: "smooth", block: "center" });
|
|
45
|
-
}
|
|
46
|
-
}, [currentIndex, marks]);
|
|
47
|
-
|
|
48
|
-
const next = () => {
|
|
49
|
-
if (!marks || marks.length === 0) return;
|
|
50
|
-
setCurrentIndex((i) => (i + 1) % marks.length);
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const prev = () => {
|
|
54
|
-
if (!marks || marks.length === 0) return;
|
|
55
|
-
setCurrentIndex((i) => (i - 1 + marks.length) % marks.length);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
<HighlightContext.Provider
|
|
60
|
-
value={{
|
|
61
|
-
currentIndex,
|
|
62
|
-
total: marks?.length ?? 0,
|
|
63
|
-
next,
|
|
64
|
-
prev,
|
|
65
|
-
registerContainer,
|
|
66
|
-
}}
|
|
67
|
-
>
|
|
68
|
-
{children}
|
|
69
|
-
</HighlightContext.Provider>
|
|
70
|
-
);
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export const useHighlight = () => {
|
|
74
|
-
const ctx = useContext(HighlightContext);
|
|
75
|
-
if (!ctx) throw new Error("useHighlight must be used inside HighlightProvider");
|
|
76
|
-
return ctx;
|
|
77
|
-
};
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createContext,
|
|
5
|
+
useCallback,
|
|
6
|
+
useContext,
|
|
7
|
+
useEffect,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
} from "react";
|
|
11
|
+
|
|
12
|
+
type HighlightContextType = {
|
|
13
|
+
currentIndex: number;
|
|
14
|
+
total: number;
|
|
15
|
+
next: () => void;
|
|
16
|
+
prev: () => void;
|
|
17
|
+
registerContainer: (el: HTMLElement | null) => void;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const HighlightContext = createContext<HighlightContextType | null>(null);
|
|
21
|
+
|
|
22
|
+
export const HighlightProvider = ({ children }: { children: React.ReactNode }) => {
|
|
23
|
+
|
|
24
|
+
const containerRef = useRef<HTMLElement | null>(null);
|
|
25
|
+
const [marks, setMarks] = useState<NodeListOf<HTMLElement> | null>(null);
|
|
26
|
+
const [currentIndex, setCurrentIndex] = useState(-1);
|
|
27
|
+
|
|
28
|
+
const registerContainer = useCallback((el: HTMLElement | null) => {
|
|
29
|
+
containerRef.current = el;
|
|
30
|
+
if (el) {
|
|
31
|
+
const found = el.querySelectorAll("mark");
|
|
32
|
+
setMarks(found);
|
|
33
|
+
setCurrentIndex(found.length > 0 ? 0 : -1);
|
|
34
|
+
} else {
|
|
35
|
+
setMarks(null);
|
|
36
|
+
setCurrentIndex(-1);
|
|
37
|
+
}
|
|
38
|
+
}, []);
|
|
39
|
+
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (marks && currentIndex >= 0 && marks[currentIndex]) {
|
|
42
|
+
marks.forEach((m) => m.classList.remove("bg-yellow-200", "bg-orange-300"));
|
|
43
|
+
marks[currentIndex].classList.add("bg-orange-300");
|
|
44
|
+
marks[currentIndex].scrollIntoView({ behavior: "smooth", block: "center" });
|
|
45
|
+
}
|
|
46
|
+
}, [currentIndex, marks]);
|
|
47
|
+
|
|
48
|
+
const next = () => {
|
|
49
|
+
if (!marks || marks.length === 0) return;
|
|
50
|
+
setCurrentIndex((i) => (i + 1) % marks.length);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const prev = () => {
|
|
54
|
+
if (!marks || marks.length === 0) return;
|
|
55
|
+
setCurrentIndex((i) => (i - 1 + marks.length) % marks.length);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<HighlightContext.Provider
|
|
60
|
+
value={{
|
|
61
|
+
currentIndex,
|
|
62
|
+
total: marks?.length ?? 0,
|
|
63
|
+
next,
|
|
64
|
+
prev,
|
|
65
|
+
registerContainer,
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
{children}
|
|
69
|
+
</HighlightContext.Provider>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const useHighlight = () => {
|
|
74
|
+
const ctx = useContext(HighlightContext);
|
|
75
|
+
if (!ctx) throw new Error("useHighlight must be used inside HighlightProvider");
|
|
76
|
+
return ctx;
|
|
77
|
+
};
|
package/src/search.tsx
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { createContext, useContext, ReactNode, useState, useEffect } from "react";
|
|
4
|
-
import { Loading } from "@c-rex/components/loading";
|
|
5
|
-
|
|
6
|
-
type SearchContextProps = {
|
|
7
|
-
loading: boolean;
|
|
8
|
-
setLoading: (loading: boolean) => void;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const SearchContext = createContext<SearchContextProps | undefined>(undefined);
|
|
12
|
-
|
|
13
|
-
export const SearchProvider = ({ children }: { children: ReactNode }) => {
|
|
14
|
-
const [mounted, setMounted] = useState(false)
|
|
15
|
-
const [loading, setLoading] = useState<boolean>(false)
|
|
16
|
-
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
setMounted(true)
|
|
19
|
-
}, [])
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<SearchContext.Provider value={{ setLoading, loading }}>
|
|
23
|
-
{mounted && loading && <Loading opacity />}
|
|
24
|
-
|
|
25
|
-
{children}
|
|
26
|
-
</SearchContext.Provider>
|
|
27
|
-
);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export const useSearchContext = () => {
|
|
31
|
-
const context = useContext(SearchContext);
|
|
32
|
-
if (!context) throw new Error("useSearchContext must be used within a SearchProvider");
|
|
33
|
-
return context;
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, ReactNode, useState, useEffect } from "react";
|
|
4
|
+
import { Loading } from "@c-rex/components/loading";
|
|
5
|
+
|
|
6
|
+
type SearchContextProps = {
|
|
7
|
+
loading: boolean;
|
|
8
|
+
setLoading: (loading: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const SearchContext = createContext<SearchContextProps | undefined>(undefined);
|
|
12
|
+
|
|
13
|
+
export const SearchProvider = ({ children }: { children: ReactNode }) => {
|
|
14
|
+
const [mounted, setMounted] = useState(false)
|
|
15
|
+
const [loading, setLoading] = useState<boolean>(false)
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setMounted(true)
|
|
19
|
+
}, [])
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<SearchContext.Provider value={{ setLoading, loading }}>
|
|
23
|
+
{mounted && loading && <Loading opacity />}
|
|
24
|
+
|
|
25
|
+
{children}
|
|
26
|
+
</SearchContext.Provider>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const useSearchContext = () => {
|
|
31
|
+
const context = useContext(SearchContext);
|
|
32
|
+
if (!context) throw new Error("useSearchContext must be used within a SearchProvider");
|
|
33
|
+
return context;
|
|
34
34
|
};
|