@blaze-cms/nextjs-tools 0.146.0-node18-core-styles-tooltips.38 → 0.146.0-node18-tooltips.33

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +32 -86
  2. package/README.md +8 -7
  3. package/example.env +1 -1
  4. package/lib/components/DebugSidebar/DebugSidebar.js +2 -1
  5. package/lib/components/DebugSidebar/DebugSidebar.js.map +1 -1
  6. package/lib/components/DebugSidebar/DebugSidebarRender.js +2 -1
  7. package/lib/components/DebugSidebar/DebugSidebarRender.js.map +1 -1
  8. package/lib/components/HashObserver.js +15 -0
  9. package/lib/components/HashObserver.js.map +1 -0
  10. package/lib/components/index.js +7 -0
  11. package/lib/components/index.js.map +1 -1
  12. package/lib/containers/ContentContainer.js +2 -1
  13. package/lib/containers/ContentContainer.js.map +1 -1
  14. package/lib/helpers/check-url.js +1 -1
  15. package/lib/helpers/check-url.js.map +1 -1
  16. package/lib/helpers/static-route-handlers/index.js +2 -1
  17. package/lib/helpers/static-route-handlers/index.js.map +1 -1
  18. package/lib/hoc/withBlaze.js +4 -2
  19. package/lib/hoc/withBlaze.js.map +1 -1
  20. package/lib/hooks/use-hash-observer.js +107 -0
  21. package/lib/hooks/use-hash-observer.js.map +1 -0
  22. package/lib/index.js +2 -1
  23. package/lib/index.js.map +1 -1
  24. package/lib/pages/document/_document.js +2 -1
  25. package/lib/pages/document/_document.js.map +1 -1
  26. package/lib-es/components/HashObserver.js +7 -0
  27. package/lib-es/components/HashObserver.js.map +1 -0
  28. package/lib-es/components/index.js +2 -1
  29. package/lib-es/components/index.js.map +1 -1
  30. package/lib-es/helpers/check-url.js +1 -1
  31. package/lib-es/helpers/check-url.js.map +1 -1
  32. package/lib-es/hoc/withBlaze.js +2 -1
  33. package/lib-es/hoc/withBlaze.js.map +1 -1
  34. package/lib-es/hooks/use-hash-observer.js +94 -0
  35. package/lib-es/hooks/use-hash-observer.js.map +1 -0
  36. package/package.json +18 -18
  37. package/src/components/HashObserver.js +8 -0
  38. package/src/components/index.js +2 -1
  39. package/src/helpers/check-url.js +1 -1
  40. package/src/hoc/withBlaze.js +2 -0
  41. package/src/hooks/use-hash-observer.js +119 -0
  42. package/tests/unit/src/hooks/use-hash-observer.test.js +260 -0
@@ -1 +1 @@
1
- {"version":3,"file":"withBlaze.js","names":["React","Component","getDataFromTree","getBlazeUi","setupCheckAccessToken","PropTypes","dynamic","AppContext","blazeConfig","getErrorMessage","ErrorBoundary","APP_LOG_NAMESPACE_MAIN","getWrappedApp","isSsr","config","blazeApp","App","_Class","getApolloClient","ctx","requestApp","apolloClient","getClient","createClient","getRequestApp","getInitialProps","context","_Component","router","AppTree","appProps","errorProps","req","res","init","events","emit","pageProps","mainProps","_objectSpread","renderAndCheckPromises","createElement","_extends","openQueryChecker","checkOpenQueries","Promise","race","error","errorCode","statusCode","log","apolloState","cache","extract","sortedState","Object","keys","sort","reduce","acc","key","processedBlazeEntities","getProcessedEntities","constructor","props","state","appLoaded","initComplete","componentDidMount","setState","setApolloClient","render","app","Provider","value","_defineProperty","object","undefined","withBlaze","buildConfig","forceSsr","window","logNameSpace"],"sources":["../../src/hoc/withBlaze.js"],"sourcesContent":["// see: https://github.com/zeit/next.js/blob/canary/examples/with-apollo-auth/lib/withApollo.js\nimport React, { Component } from 'react';\nimport { getDataFromTree } from '@apollo/client/react/ssr';\nimport getBlazeUi from '@blaze-cms/core-ui';\nimport { setupCheckAccessToken } from '@blaze-cms/core-auth-ui';\nimport PropTypes from 'prop-types';\nimport dynamic from 'next/dynamic'; // Next.js dynamic\nimport { AppContext } from '@blaze-cms/nextjs-components';\nimport blazeConfig from '../blaze.config';\nimport { getErrorMessage } from '../helpers';\n\nconst ErrorBoundary = dynamic(() => import('@blaze-cms/core-errors-ui'));\n\nconst APP_LOG_NAMESPACE_MAIN = 'main';\n\nfunction getWrappedApp(isSsr, config, blazeApp, App) {\n function getApolloClient(ctx, requestApp) {\n return ctx.apolloClient || requestApp.getClient() || requestApp.createClient();\n }\n\n function getRequestApp(requestApp) {\n return !requestApp && isSsr ? getBlazeUi({ config }) : blazeApp;\n }\n return class extends Component {\n static displayName = 'withBlaze(App)';\n\n static propTypes = {\n apolloState: PropTypes.object,\n apolloClient: PropTypes.object,\n processedBlazeEntities: PropTypes.object\n };\n\n static defaultProps = {\n apolloState: {},\n apolloClient: null,\n processedBlazeEntities: undefined\n };\n\n static async getInitialProps(context) {\n const { Component: _Component, router, AppTree, ctx } = context;\n let appProps = {};\n let errorProps = {};\n\n let requestApp = ctx.blazeApp;\n requestApp = getRequestApp(requestApp);\n\n requestApp.ctx.router = router;\n requestApp.ctx.req = ctx.req;\n requestApp.ctx.res = ctx.res;\n\n await blazeApp.init();\n await requestApp.init();\n\n const apolloClient = getApolloClient(ctx, requestApp);\n\n ctx.apolloClient = apolloClient;\n ctx.blazeApp = requestApp;\n\n requestApp.events.emit('page-load:get-initial-props:before', { ctx });\n\n if (App.getInitialProps) {\n appProps = await App.getInitialProps(context);\n }\n\n const { pageProps = {} } = appProps;\n const mainProps = {\n ...appProps,\n pageProps: { ...pageProps, ...errorProps }\n };\n\n if (!isSsr) return mainProps;\n\n try {\n const renderAndCheckPromises = [\n getDataFromTree(\n <AppTree\n {...appProps}\n Component={_Component}\n router={router}\n apolloClient={apolloClient}\n />\n ),\n requestApp.openQueryChecker.checkOpenQueries()\n ];\n // race is so that if getDataFromTree gets stuck the checkOpenQueries will resolve when outstanding queries are done\n await Promise.race(renderAndCheckPromises);\n } catch (error) {\n errorProps = getErrorMessage(error);\n if (errorProps.errorCode) ctx.res.statusCode = errorProps.errorCode;\n ctx.blazeApp.events.emit('monitor:log', { error });\n requestApp.log.error('Error while running `getDataFromTree`', error);\n }\n\n const apolloState = apolloClient.cache.extract();\n const sortedState = Object.keys(apolloState)\n .sort()\n .reduce((acc, key) => {\n acc[key] = apolloState[key];\n return acc;\n }, {});\n\n return {\n ...mainProps,\n pageProps: { ...mainProps.pageProps, ...errorProps },\n apolloState: sortedState,\n processedBlazeEntities: blazeApp.getProcessedEntities()\n };\n }\n\n constructor(props) {\n super(props);\n this.apolloClient = props.apolloClient;\n this.state = {\n appLoaded: isSsr || blazeApp.initComplete()\n };\n this.blazeApp = blazeApp;\n }\n\n async componentDidMount() {\n if (blazeApp.initComplete()) return;\n\n await blazeApp.init();\n\n this.setState({\n appLoaded: blazeApp.initComplete()\n });\n }\n\n setApolloClient() {\n if (!this.apolloClient) {\n const { apolloState, processedBlazeEntities } = this.props;\n this.apolloClient = blazeApp.createClient(apolloState, processedBlazeEntities);\n setupCheckAccessToken(this.apolloClient);\n }\n }\n\n render() {\n const { appLoaded } = this.state;\n\n if (!appLoaded && !isSsr) return '...loading';\n\n this.setApolloClient();\n\n return (\n <ErrorBoundary app={this.blazeApp}>\n <AppContext.Provider value={{ blazeApp: this.blazeApp }}>\n <App {...this.props} apolloClient={this.apolloClient} blazeApp={this.blazeApp} />\n </AppContext.Provider>\n </ErrorBoundary>\n );\n }\n };\n}\n\nconst withBlaze = (App, buildConfig, { forceSsr = false } = {}) => {\n const isSsr = forceSsr || typeof window === 'undefined';\n const config = buildConfig ? buildConfig(blazeConfig) : blazeConfig;\n const blazeApp = getBlazeUi({ config, logNameSpace: APP_LOG_NAMESPACE_MAIN });\n blazeApp.init();\n\n return getWrappedApp(isSsr, config, blazeApp, App);\n};\n\nexport default withBlaze;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"withBlaze.js","names":["React","Component","getDataFromTree","getBlazeUi","setupCheckAccessToken","PropTypes","dynamic","AppContext","blazeConfig","getErrorMessage","HashObserver","ErrorBoundary","APP_LOG_NAMESPACE_MAIN","getWrappedApp","isSsr","config","blazeApp","App","_Class","getApolloClient","ctx","requestApp","apolloClient","getClient","createClient","getRequestApp","getInitialProps","context","_Component","router","AppTree","appProps","errorProps","req","res","init","events","emit","pageProps","mainProps","_objectSpread","renderAndCheckPromises","createElement","_extends","openQueryChecker","checkOpenQueries","Promise","race","error","errorCode","statusCode","log","apolloState","cache","extract","sortedState","Object","keys","sort","reduce","acc","key","processedBlazeEntities","getProcessedEntities","constructor","props","state","appLoaded","initComplete","componentDidMount","setState","setApolloClient","render","app","Provider","value","_defineProperty","object","undefined","withBlaze","buildConfig","forceSsr","window","logNameSpace"],"sources":["../../src/hoc/withBlaze.js"],"sourcesContent":["// see: https://github.com/zeit/next.js/blob/canary/examples/with-apollo-auth/lib/withApollo.js\nimport React, { Component } from 'react';\nimport { getDataFromTree } from '@apollo/client/react/ssr';\nimport getBlazeUi from '@blaze-cms/core-ui';\nimport { setupCheckAccessToken } from '@blaze-cms/core-auth-ui';\nimport PropTypes from 'prop-types';\nimport dynamic from 'next/dynamic'; // Next.js dynamic\nimport { AppContext } from '@blaze-cms/nextjs-components';\nimport blazeConfig from '../blaze.config';\nimport { getErrorMessage } from '../helpers';\nimport HashObserver from '../components/HashObserver';\n\nconst ErrorBoundary = dynamic(() => import('@blaze-cms/core-errors-ui'));\n\nconst APP_LOG_NAMESPACE_MAIN = 'main';\n\nfunction getWrappedApp(isSsr, config, blazeApp, App) {\n function getApolloClient(ctx, requestApp) {\n return ctx.apolloClient || requestApp.getClient() || requestApp.createClient();\n }\n\n function getRequestApp(requestApp) {\n return !requestApp && isSsr ? getBlazeUi({ config }) : blazeApp;\n }\n return class extends Component {\n static displayName = 'withBlaze(App)';\n\n static propTypes = {\n apolloState: PropTypes.object,\n apolloClient: PropTypes.object,\n processedBlazeEntities: PropTypes.object\n };\n\n static defaultProps = {\n apolloState: {},\n apolloClient: null,\n processedBlazeEntities: undefined\n };\n\n static async getInitialProps(context) {\n const { Component: _Component, router, AppTree, ctx } = context;\n let appProps = {};\n let errorProps = {};\n\n let requestApp = ctx.blazeApp;\n requestApp = getRequestApp(requestApp);\n\n requestApp.ctx.router = router;\n requestApp.ctx.req = ctx.req;\n requestApp.ctx.res = ctx.res;\n\n await blazeApp.init();\n await requestApp.init();\n\n const apolloClient = getApolloClient(ctx, requestApp);\n\n ctx.apolloClient = apolloClient;\n ctx.blazeApp = requestApp;\n\n requestApp.events.emit('page-load:get-initial-props:before', { ctx });\n\n if (App.getInitialProps) {\n appProps = await App.getInitialProps(context);\n }\n\n const { pageProps = {} } = appProps;\n const mainProps = {\n ...appProps,\n pageProps: { ...pageProps, ...errorProps }\n };\n\n if (!isSsr) return mainProps;\n\n try {\n const renderAndCheckPromises = [\n getDataFromTree(\n <AppTree\n {...appProps}\n Component={_Component}\n router={router}\n apolloClient={apolloClient}\n />\n ),\n requestApp.openQueryChecker.checkOpenQueries()\n ];\n // race is so that if getDataFromTree gets stuck the checkOpenQueries will resolve when outstanding queries are done\n await Promise.race(renderAndCheckPromises);\n } catch (error) {\n errorProps = getErrorMessage(error);\n if (errorProps.errorCode) ctx.res.statusCode = errorProps.errorCode;\n ctx.blazeApp.events.emit('monitor:log', { error });\n requestApp.log.error('Error while running `getDataFromTree`', error);\n }\n\n const apolloState = apolloClient.cache.extract();\n const sortedState = Object.keys(apolloState)\n .sort()\n .reduce((acc, key) => {\n acc[key] = apolloState[key];\n return acc;\n }, {});\n\n return {\n ...mainProps,\n pageProps: { ...mainProps.pageProps, ...errorProps },\n apolloState: sortedState,\n processedBlazeEntities: blazeApp.getProcessedEntities()\n };\n }\n\n constructor(props) {\n super(props);\n this.apolloClient = props.apolloClient;\n this.state = {\n appLoaded: isSsr || blazeApp.initComplete()\n };\n this.blazeApp = blazeApp;\n }\n\n async componentDidMount() {\n if (blazeApp.initComplete()) return;\n\n await blazeApp.init();\n\n this.setState({\n appLoaded: blazeApp.initComplete()\n });\n }\n\n setApolloClient() {\n if (!this.apolloClient) {\n const { apolloState, processedBlazeEntities } = this.props;\n this.apolloClient = blazeApp.createClient(apolloState, processedBlazeEntities);\n setupCheckAccessToken(this.apolloClient);\n }\n }\n\n render() {\n const { appLoaded } = this.state;\n\n if (!appLoaded && !isSsr) return '...loading';\n\n this.setApolloClient();\n\n return (\n <ErrorBoundary app={this.blazeApp}>\n <HashObserver />\n <AppContext.Provider value={{ blazeApp: this.blazeApp }}>\n <App {...this.props} apolloClient={this.apolloClient} blazeApp={this.blazeApp} />\n </AppContext.Provider>\n </ErrorBoundary>\n );\n }\n };\n}\n\nconst withBlaze = (App, buildConfig, { forceSsr = false } = {}) => {\n const isSsr = forceSsr || typeof window === 'undefined';\n const config = buildConfig ? buildConfig(blazeConfig) : blazeConfig;\n const blazeApp = getBlazeUi({ config, logNameSpace: APP_LOG_NAMESPACE_MAIN });\n blazeApp.init();\n\n return getWrappedApp(isSsr, config, blazeApp, App);\n};\n\nexport default withBlaze;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,94 @@
1
+ import { useEffect } from 'react';
2
+ import Router from 'next/router';
3
+ const DEFAULT_TIMEOUT = 3000;
4
+ function useHashObserver(timeout = DEFAULT_TIMEOUT) {
5
+ useEffect(() => {
6
+ if (typeof window === 'undefined') return undefined;
7
+ let observer = null;
8
+ let timeoutId = null;
9
+ let currentHash = null;
10
+ let isObserving = false;
11
+ const scrollToElement = hash => {
12
+ if (!hash) return false;
13
+ const id = hash.startsWith('#') ? hash.slice(1) : hash;
14
+ const element = document.getElementById(id);
15
+ if (element) {
16
+ element.scrollIntoView();
17
+ return true;
18
+ }
19
+ return false;
20
+ };
21
+ const stopObserving = () => {
22
+ if (observer) {
23
+ observer.disconnect();
24
+ observer = null;
25
+ }
26
+ if (timeoutId) {
27
+ clearTimeout(timeoutId);
28
+ timeoutId = null;
29
+ }
30
+ isObserving = false;
31
+ currentHash = null;
32
+ };
33
+ const startObserving = hash => {
34
+ if (isObserving) {
35
+ stopObserving();
36
+ }
37
+ currentHash = hash;
38
+ isObserving = true;
39
+ if (scrollToElement(hash)) {
40
+ stopObserving();
41
+ return;
42
+ }
43
+ observer = new MutationObserver(() => {
44
+ if (scrollToElement(currentHash)) {
45
+ stopObserving();
46
+ }
47
+ });
48
+ const targetNode = document.getElementById('__next') || document.getElementById('root') || document.body;
49
+ observer.observe(targetNode, {
50
+ childList: true,
51
+ subtree: true
52
+ });
53
+ timeoutId = setTimeout(() => {
54
+ stopObserving();
55
+ }, timeout);
56
+ };
57
+ const handleRouteChange = url => {
58
+ const hashIndex = url.indexOf('#');
59
+ if (hashIndex === -1) {
60
+ stopObserving();
61
+ return;
62
+ }
63
+ const hash = url.slice(hashIndex);
64
+ if (hash) {
65
+ startObserving(hash);
66
+ }
67
+ };
68
+ const handleHashChange = url => {
69
+ const hashIndex = url.indexOf('#');
70
+ if (hashIndex === -1) {
71
+ stopObserving();
72
+ return;
73
+ }
74
+ const hash = url.slice(hashIndex);
75
+ if (hash) {
76
+ startObserving(hash);
77
+ } else {
78
+ stopObserving();
79
+ }
80
+ };
81
+ Router.events.on('routeChangeComplete', handleRouteChange);
82
+ Router.events.on('hashChangeComplete', handleHashChange);
83
+ if (window.location.hash) {
84
+ startObserving(window.location.hash);
85
+ }
86
+ return () => {
87
+ stopObserving();
88
+ Router.events.off('routeChangeComplete', handleRouteChange);
89
+ Router.events.off('hashChangeComplete', handleHashChange);
90
+ };
91
+ }, [timeout]);
92
+ }
93
+ export default useHashObserver;
94
+ //# sourceMappingURL=use-hash-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-hash-observer.js","names":["useEffect","Router","DEFAULT_TIMEOUT","useHashObserver","timeout","window","undefined","observer","timeoutId","currentHash","isObserving","scrollToElement","hash","id","startsWith","slice","element","document","getElementById","scrollIntoView","stopObserving","disconnect","clearTimeout","startObserving","MutationObserver","targetNode","body","observe","childList","subtree","setTimeout","handleRouteChange","url","hashIndex","indexOf","handleHashChange","events","on","location","off"],"sources":["../../src/hooks/use-hash-observer.js"],"sourcesContent":["import { useEffect } from 'react';\nimport Router from 'next/router';\n\nconst DEFAULT_TIMEOUT = 3000;\n\nfunction useHashObserver(timeout = DEFAULT_TIMEOUT) {\n useEffect(\n () => {\n if (typeof window === 'undefined') return undefined;\n\n let observer = null;\n let timeoutId = null;\n let currentHash = null;\n let isObserving = false;\n\n const scrollToElement = hash => {\n if (!hash) return false;\n\n const id = hash.startsWith('#') ? hash.slice(1) : hash;\n const element = document.getElementById(id);\n\n if (element) {\n element.scrollIntoView();\n return true;\n }\n\n return false;\n };\n\n const stopObserving = () => {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n isObserving = false;\n currentHash = null;\n };\n\n const startObserving = hash => {\n if (isObserving) {\n stopObserving();\n }\n\n currentHash = hash;\n isObserving = true;\n\n if (scrollToElement(hash)) {\n stopObserving();\n return;\n }\n\n observer = new MutationObserver(() => {\n if (scrollToElement(currentHash)) {\n stopObserving();\n }\n });\n\n const targetNode =\n document.getElementById('__next') || document.getElementById('root') || document.body;\n observer.observe(targetNode, {\n childList: true,\n subtree: true\n });\n\n timeoutId = setTimeout(() => {\n stopObserving();\n }, timeout);\n };\n\n const handleRouteChange = url => {\n const hashIndex = url.indexOf('#');\n if (hashIndex === -1) {\n stopObserving();\n return;\n }\n\n const hash = url.slice(hashIndex);\n if (hash) {\n startObserving(hash);\n }\n };\n\n const handleHashChange = url => {\n const hashIndex = url.indexOf('#');\n if (hashIndex === -1) {\n stopObserving();\n return;\n }\n\n const hash = url.slice(hashIndex);\n if (hash) {\n startObserving(hash);\n } else {\n stopObserving();\n }\n };\n\n Router.events.on('routeChangeComplete', handleRouteChange);\n Router.events.on('hashChangeComplete', handleHashChange);\n\n if (window.location.hash) {\n startObserving(window.location.hash);\n }\n\n return () => {\n stopObserving();\n Router.events.off('routeChangeComplete', handleRouteChange);\n Router.events.off('hashChangeComplete', handleHashChange);\n };\n },\n [timeout]\n );\n}\n\nexport default useHashObserver;\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blaze-cms/nextjs-tools",
3
- "version": "0.146.0-node18-core-styles-tooltips.38",
3
+ "version": "0.146.0-node18-tooltips.33",
4
4
  "description": "Blaze nextjs tools",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib-es/index.js",
@@ -28,22 +28,22 @@
28
28
  "license": "GPL-3.0",
29
29
  "dependencies": {
30
30
  "@apollo/client": "^3.9.2",
31
- "@blaze-cms/core-auth-ui": "0.146.0-node18-core-styles-tooltips.38",
32
- "@blaze-cms/core-errors": "0.146.0-node18-core-styles-tooltips.3",
33
- "@blaze-cms/core-errors-ui": "0.146.0-node18-core-styles-tooltips.3",
34
- "@blaze-cms/core-ui": "0.146.0-node18-core-styles-tooltips.38",
35
- "@blaze-cms/nextjs-components": "0.146.0-node18-core-styles-tooltips.32",
36
- "@blaze-cms/plugin-auth-fe": "0.146.0-node18-core-styles-tooltips.38",
37
- "@blaze-cms/plugin-auth-local-fe": "0.146.0-node18-core-styles-tooltips.38",
38
- "@blaze-cms/plugin-chart": "0.146.0-node18-core-styles-tooltips.31",
39
- "@blaze-cms/plugin-google-maps-fe": "0.146.0-node18-core-styles-tooltips.38",
40
- "@blaze-cms/plugin-gtm-fe": "0.146.0-node18-core-styles-tooltips.38",
41
- "@blaze-cms/plugin-page-builder-fe": "0.146.0-node18-core-styles-tooltips.38",
42
- "@blaze-cms/plugin-preview-fe": "0.146.0-node18-core-styles-tooltips.38",
43
- "@blaze-cms/plugin-search-ui": "0.146.0-node18-core-styles-tooltips.38",
44
- "@blaze-cms/plugin-structured-data-fe": "0.146.0-node18-core-styles-tooltips.24",
45
- "@blaze-cms/react-page-builder": "0.146.0-node18-core-styles-tooltips.38",
46
- "@blaze-cms/setup-ui": "0.146.0-node18-core-styles-tooltips.3",
31
+ "@blaze-cms/core-auth-ui": "0.146.0-node18-tooltips.32",
32
+ "@blaze-cms/core-errors": "0.146.0-node18-tooltips.0",
33
+ "@blaze-cms/core-errors-ui": "0.146.0-node18-tooltips.0",
34
+ "@blaze-cms/core-ui": "0.146.0-node18-tooltips.32",
35
+ "@blaze-cms/nextjs-components": "0.146.0-node18-tooltips.32",
36
+ "@blaze-cms/plugin-auth-fe": "0.146.0-node18-tooltips.32",
37
+ "@blaze-cms/plugin-auth-local-fe": "0.146.0-node18-tooltips.32",
38
+ "@blaze-cms/plugin-chart": "0.146.0-node18-tooltips.19",
39
+ "@blaze-cms/plugin-google-maps-fe": "0.146.0-node18-tooltips.33",
40
+ "@blaze-cms/plugin-gtm-fe": "0.146.0-node18-tooltips.33",
41
+ "@blaze-cms/plugin-page-builder-fe": "0.146.0-node18-tooltips.33",
42
+ "@blaze-cms/plugin-preview-fe": "0.146.0-node18-tooltips.32",
43
+ "@blaze-cms/plugin-search-ui": "0.146.0-node18-tooltips.33",
44
+ "@blaze-cms/plugin-structured-data-fe": "0.146.0-node18-tooltips.25",
45
+ "@blaze-cms/react-page-builder": "0.146.0-node18-tooltips.33",
46
+ "@blaze-cms/setup-ui": "0.146.0-node18-tooltips.0",
47
47
  "@blaze-react/switches": "0.8.0-alpha.112",
48
48
  "autoprefixer": "^10.2.3",
49
49
  "core-js": "^3.2.1",
@@ -71,5 +71,5 @@
71
71
  "lib/*",
72
72
  "lib-es/*"
73
73
  ],
74
- "gitHead": "846187a753c3dbd7c598d4184b6677f123f41681"
74
+ "gitHead": "716b7ae2c9ac96e4515eaf2d64f9c85f6d0458d1"
75
75
  }
@@ -0,0 +1,8 @@
1
+ import useHashObserver from '../hooks/use-hash-observer';
2
+
3
+ function HashObserver() {
4
+ useHashObserver();
5
+ return null;
6
+ }
7
+
8
+ export default HashObserver;
@@ -1,3 +1,4 @@
1
1
  import DebugSidebar from './DebugSidebar';
2
+ import HashObserver from './HashObserver';
2
3
 
3
- export { DebugSidebar };
4
+ export { DebugSidebar, HashObserver };
@@ -17,7 +17,7 @@ import handleStaticRoutes from './handle-static-routes';
17
17
  import getPageData from './get-page-data';
18
18
  import getRootSelectorClasses from './get-root-selector-classes';
19
19
 
20
- const getRootClassesLimit = () => Number(process.env.BLAZE_ROOT_SELECTOR_CLASSES_LIMIT || 1);
20
+ const getRootClassesLimit = () => Number(process.env.BLAZE_ROOT_SELECTOR_CLASSES_LIMIT);
21
21
 
22
22
  const checkUrl = async props => {
23
23
  const { asPath, apolloClient, res, req, query, blazeApp, disableSsr } = props;
@@ -8,6 +8,7 @@ import dynamic from 'next/dynamic'; // Next.js dynamic
8
8
  import { AppContext } from '@blaze-cms/nextjs-components';
9
9
  import blazeConfig from '../blaze.config';
10
10
  import { getErrorMessage } from '../helpers';
11
+ import HashObserver from '../components/HashObserver';
11
12
 
12
13
  const ErrorBoundary = dynamic(() => import('@blaze-cms/core-errors-ui'));
13
14
 
@@ -143,6 +144,7 @@ function getWrappedApp(isSsr, config, blazeApp, App) {
143
144
 
144
145
  return (
145
146
  <ErrorBoundary app={this.blazeApp}>
147
+ <HashObserver />
146
148
  <AppContext.Provider value={{ blazeApp: this.blazeApp }}>
147
149
  <App {...this.props} apolloClient={this.apolloClient} blazeApp={this.blazeApp} />
148
150
  </AppContext.Provider>
@@ -0,0 +1,119 @@
1
+ import { useEffect } from 'react';
2
+ import Router from 'next/router';
3
+
4
+ const DEFAULT_TIMEOUT = 3000;
5
+
6
+ function useHashObserver(timeout = DEFAULT_TIMEOUT) {
7
+ useEffect(
8
+ () => {
9
+ if (typeof window === 'undefined') return undefined;
10
+
11
+ let observer = null;
12
+ let timeoutId = null;
13
+ let currentHash = null;
14
+ let isObserving = false;
15
+
16
+ const scrollToElement = hash => {
17
+ if (!hash) return false;
18
+
19
+ const id = hash.startsWith('#') ? hash.slice(1) : hash;
20
+ const element = document.getElementById(id);
21
+
22
+ if (element) {
23
+ element.scrollIntoView();
24
+ return true;
25
+ }
26
+
27
+ return false;
28
+ };
29
+
30
+ const stopObserving = () => {
31
+ if (observer) {
32
+ observer.disconnect();
33
+ observer = null;
34
+ }
35
+ if (timeoutId) {
36
+ clearTimeout(timeoutId);
37
+ timeoutId = null;
38
+ }
39
+ isObserving = false;
40
+ currentHash = null;
41
+ };
42
+
43
+ const startObserving = hash => {
44
+ if (isObserving) {
45
+ stopObserving();
46
+ }
47
+
48
+ currentHash = hash;
49
+ isObserving = true;
50
+
51
+ if (scrollToElement(hash)) {
52
+ stopObserving();
53
+ return;
54
+ }
55
+
56
+ observer = new MutationObserver(() => {
57
+ if (scrollToElement(currentHash)) {
58
+ stopObserving();
59
+ }
60
+ });
61
+
62
+ const targetNode =
63
+ document.getElementById('__next') || document.getElementById('root') || document.body;
64
+ observer.observe(targetNode, {
65
+ childList: true,
66
+ subtree: true
67
+ });
68
+
69
+ timeoutId = setTimeout(() => {
70
+ stopObserving();
71
+ }, timeout);
72
+ };
73
+
74
+ const handleRouteChange = url => {
75
+ const hashIndex = url.indexOf('#');
76
+ if (hashIndex === -1) {
77
+ stopObserving();
78
+ return;
79
+ }
80
+
81
+ const hash = url.slice(hashIndex);
82
+ if (hash) {
83
+ startObserving(hash);
84
+ }
85
+ };
86
+
87
+ const handleHashChange = url => {
88
+ const hashIndex = url.indexOf('#');
89
+ if (hashIndex === -1) {
90
+ stopObserving();
91
+ return;
92
+ }
93
+
94
+ const hash = url.slice(hashIndex);
95
+ if (hash) {
96
+ startObserving(hash);
97
+ } else {
98
+ stopObserving();
99
+ }
100
+ };
101
+
102
+ Router.events.on('routeChangeComplete', handleRouteChange);
103
+ Router.events.on('hashChangeComplete', handleHashChange);
104
+
105
+ if (window.location.hash) {
106
+ startObserving(window.location.hash);
107
+ }
108
+
109
+ return () => {
110
+ stopObserving();
111
+ Router.events.off('routeChangeComplete', handleRouteChange);
112
+ Router.events.off('hashChangeComplete', handleHashChange);
113
+ };
114
+ },
115
+ [timeout]
116
+ );
117
+ }
118
+
119
+ export default useHashObserver;
@@ -0,0 +1,260 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+ import React from 'react';
5
+ import '@testing-library/jest-dom/extend-expect';
6
+ import { render, act } from '@testing-library/react';
7
+ import Router from 'next/router';
8
+ import useHashObserver from '../../../../src/hooks/use-hash-observer';
9
+
10
+ jest.mock('next/router', () => ({
11
+ events: {
12
+ on: jest.fn(),
13
+ off: jest.fn()
14
+ }
15
+ }));
16
+
17
+ function TestComponent({ timeout }) {
18
+ useHashObserver(timeout);
19
+ return <div data-testid="test-component">Test</div>;
20
+ }
21
+
22
+ describe('useHashObserver', () => {
23
+ beforeEach(() => {
24
+ document.body.innerHTML = '';
25
+ jest.clearAllMocks();
26
+
27
+ delete window.location;
28
+ window.location = { hash: '' };
29
+
30
+ Element.prototype.scrollIntoView = jest.fn();
31
+
32
+ Router.events = {
33
+ on: jest.fn(),
34
+ off: jest.fn()
35
+ };
36
+ });
37
+
38
+ afterEach(() => {
39
+ jest.clearAllTimers();
40
+ jest.useRealTimers();
41
+ });
42
+
43
+ it('should register router event listeners on mount', () => {
44
+ const { unmount } = render(<TestComponent />);
45
+
46
+ expect(Router.events.on).toHaveBeenCalledWith('routeChangeComplete', expect.any(Function));
47
+ expect(Router.events.on).toHaveBeenCalledWith('hashChangeComplete', expect.any(Function));
48
+
49
+ unmount();
50
+ });
51
+
52
+ it('should cleanup event listeners on unmount', () => {
53
+ const { unmount } = render(<TestComponent />);
54
+
55
+ unmount();
56
+
57
+ expect(Router.events.off).toHaveBeenCalledWith('routeChangeComplete', expect.any(Function));
58
+ expect(Router.events.off).toHaveBeenCalledWith('hashChangeComplete', expect.any(Function));
59
+ });
60
+
61
+ it('should scroll to element if it exists immediately', async () => {
62
+ jest.useFakeTimers();
63
+
64
+ const testElement = document.createElement('div');
65
+ testElement.id = 'test-section';
66
+ document.body.appendChild(testElement);
67
+
68
+ window.location.hash = '#test-section';
69
+
70
+ act(() => {
71
+ render(<TestComponent />);
72
+ });
73
+
74
+ act(() => {
75
+ jest.runAllTimers();
76
+ });
77
+
78
+ expect(testElement.scrollIntoView).toHaveBeenCalledWith();
79
+ });
80
+
81
+ it('should handle route change with hash', () => {
82
+ const testElement = document.createElement('div');
83
+ testElement.id = 'route-section';
84
+ document.body.appendChild(testElement);
85
+
86
+ render(<TestComponent />);
87
+
88
+ const routeChangeHandler = Router.events.on.mock.calls.find(
89
+ call => call[0] === 'routeChangeComplete'
90
+ )[1];
91
+
92
+ act(() => {
93
+ routeChangeHandler('/page#route-section');
94
+ });
95
+
96
+ expect(testElement.scrollIntoView).toHaveBeenCalled();
97
+ });
98
+
99
+ it('should handle route change without hash', () => {
100
+ render(<TestComponent />);
101
+
102
+ const routeChangeHandler = Router.events.on.mock.calls.find(
103
+ call => call[0] === 'routeChangeComplete'
104
+ )[1];
105
+
106
+ expect(() => {
107
+ act(() => {
108
+ routeChangeHandler('/page');
109
+ });
110
+ }).not.toThrow();
111
+ });
112
+
113
+ it('should handle hash change', () => {
114
+ const testElement = document.createElement('div');
115
+ testElement.id = 'hash-section';
116
+ document.body.appendChild(testElement);
117
+
118
+ render(<TestComponent />);
119
+
120
+ const hashChangeHandler = Router.events.on.mock.calls.find(
121
+ call => call[0] === 'hashChangeComplete'
122
+ )[1];
123
+
124
+ act(() => {
125
+ hashChangeHandler('/page#hash-section');
126
+ });
127
+
128
+ expect(testElement.scrollIntoView).toHaveBeenCalled();
129
+ });
130
+
131
+ it('should stop observing after timeout', () => {
132
+ jest.useFakeTimers();
133
+
134
+ render(<TestComponent timeout={1000} />);
135
+
136
+ const hashChangeHandler = Router.events.on.mock.calls.find(
137
+ call => call[0] === 'hashChangeComplete'
138
+ )[1];
139
+
140
+ act(() => {
141
+ hashChangeHandler('/page#nonexistent');
142
+ });
143
+
144
+ act(() => {
145
+ jest.advanceTimersByTime(1100);
146
+ });
147
+
148
+ const lateElement = document.createElement('div');
149
+ lateElement.id = 'nonexistent';
150
+ document.body.appendChild(lateElement);
151
+
152
+ expect(lateElement.scrollIntoView).not.toHaveBeenCalled();
153
+ });
154
+
155
+ it('should handle rapid hash changes', () => {
156
+ jest.useFakeTimers();
157
+
158
+ const element2 = document.createElement('div');
159
+ element2.id = 'section-2';
160
+ document.body.appendChild(element2);
161
+
162
+ render(<TestComponent />);
163
+
164
+ const hashChangeHandler = Router.events.on.mock.calls.find(
165
+ call => call[0] === 'hashChangeComplete'
166
+ )[1];
167
+
168
+ act(() => {
169
+ hashChangeHandler('/page#section-1');
170
+ });
171
+
172
+ act(() => {
173
+ hashChangeHandler('/page#section-2');
174
+ });
175
+
176
+ expect(element2.scrollIntoView).toHaveBeenCalled();
177
+ });
178
+
179
+ it('should handle empty hash gracefully', () => {
180
+ render(<TestComponent />);
181
+
182
+ const hashChangeHandler = Router.events.on.mock.calls.find(
183
+ call => call[0] === 'hashChangeComplete'
184
+ )[1];
185
+
186
+ expect(() => {
187
+ act(() => {
188
+ hashChangeHandler('/page');
189
+ });
190
+ }).not.toThrow();
191
+ });
192
+
193
+ it('should use custom timeout value', () => {
194
+ jest.useFakeTimers();
195
+
196
+ const customTimeout = 5000;
197
+ render(<TestComponent timeout={customTimeout} />);
198
+
199
+ const hashChangeHandler = Router.events.on.mock.calls.find(
200
+ call => call[0] === 'hashChangeComplete'
201
+ )[1];
202
+
203
+ act(() => {
204
+ hashChangeHandler('/page#nonexistent');
205
+ });
206
+
207
+ act(() => {
208
+ jest.advanceTimersByTime(4999);
209
+ });
210
+
211
+ const element = document.createElement('div');
212
+ element.id = 'nonexistent';
213
+ document.body.appendChild(element);
214
+
215
+ act(() => {
216
+ jest.advanceTimersByTime(1);
217
+ });
218
+
219
+ expect(element.scrollIntoView).not.toHaveBeenCalled();
220
+ });
221
+
222
+ it('should verify observer stops after timeout', () => {
223
+ jest.useFakeTimers();
224
+
225
+ render(<TestComponent timeout={1000} />);
226
+
227
+ const hashChangeHandler = Router.events.on.mock.calls.find(
228
+ call => call[0] === 'hashChangeComplete'
229
+ )[1];
230
+
231
+ act(() => {
232
+ hashChangeHandler('/page#delayed-element');
233
+ });
234
+
235
+ act(() => {
236
+ jest.advanceTimersByTime(1000);
237
+ });
238
+
239
+ const element = document.createElement('div');
240
+ element.id = 'delayed-element';
241
+ document.body.appendChild(element);
242
+
243
+ act(() => {
244
+ jest.advanceTimersByTime(100);
245
+ });
246
+
247
+ expect(element.scrollIntoView).not.toHaveBeenCalled();
248
+
249
+ const anotherElement = document.createElement('div');
250
+ anotherElement.id = 'another-element';
251
+ document.body.appendChild(anotherElement);
252
+
253
+ act(() => {
254
+ jest.advanceTimersByTime(100);
255
+ });
256
+
257
+ expect(element.scrollIntoView).not.toHaveBeenCalled();
258
+ expect(anotherElement.scrollIntoView).not.toHaveBeenCalled();
259
+ });
260
+ });