@redneckz/wildless-cms-uni-blocks 0.8.10 → 0.8.12
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/bundle/bundle.umd.js +79 -93
- package/bundle/bundle.umd.min.js +1 -1
- package/bundle/services/BlockRouter/BlockRouter.d.ts +1 -3
- package/bundle/ui-kit/Img/ImgAsPicture.d.ts +0 -2
- package/bundle/utils/adjustHref.d.ts +3 -0
- package/bundle/utils/dirname.d.ts +1 -0
- package/bundle/utils/url.d.ts +2 -2
- package/dist/ProjectSettings.js +3 -4
- package/dist/ProjectSettings.js.map +1 -1
- package/dist/hooks/useLink.js +4 -16
- package/dist/hooks/useLink.js.map +1 -1
- package/dist/services/BlockRouter/BlockRouter.d.ts +1 -3
- package/dist/services/BlockRouter/BlockRouter.js +6 -9
- package/dist/services/BlockRouter/BlockRouter.js.map +1 -1
- package/dist/services/BlockRouter/useBlockRouterProvider.js +2 -10
- package/dist/services/BlockRouter/useBlockRouterProvider.js.map +1 -1
- package/dist/setup-fixture.js +3 -4
- package/dist/setup-fixture.js.map +1 -1
- package/dist/ui-kit/BlockWrapper.js +3 -2
- package/dist/ui-kit/BlockWrapper.js.map +1 -1
- package/dist/ui-kit/Icon/Icon.js +5 -1
- package/dist/ui-kit/Icon/Icon.js.map +1 -1
- package/dist/ui-kit/Img/ImgAsPicture.d.ts +0 -2
- package/dist/ui-kit/Img/ImgAsPicture.js +18 -21
- package/dist/ui-kit/Img/ImgAsPicture.js.map +1 -1
- package/dist/utils/adjustHref.d.ts +3 -0
- package/dist/utils/adjustHref.js +14 -0
- package/dist/utils/adjustHref.js.map +1 -0
- package/dist/utils/dirname.d.ts +1 -0
- package/dist/utils/dirname.js +5 -0
- package/dist/utils/dirname.js.map +1 -0
- package/dist/utils/url.d.ts +2 -2
- package/dist/utils/url.js +1 -1
- package/dist/utils/url.js.map +1 -1
- package/dist/wlc.json +0 -1
- package/lib/ProjectSettings.js +3 -4
- package/lib/ProjectSettings.js.map +1 -1
- package/lib/hooks/useLink.js +5 -17
- package/lib/hooks/useLink.js.map +1 -1
- package/lib/services/BlockRouter/BlockRouter.d.ts +1 -3
- package/lib/services/BlockRouter/BlockRouter.js +5 -7
- package/lib/services/BlockRouter/BlockRouter.js.map +1 -1
- package/lib/services/BlockRouter/useBlockRouterProvider.js +2 -10
- package/lib/services/BlockRouter/useBlockRouterProvider.js.map +1 -1
- package/lib/setup-fixture.js +3 -4
- package/lib/setup-fixture.js.map +1 -1
- package/lib/ui-kit/BlockWrapper.js +3 -2
- package/lib/ui-kit/BlockWrapper.js.map +1 -1
- package/lib/ui-kit/Icon/Icon.js +5 -1
- package/lib/ui-kit/Icon/Icon.js.map +1 -1
- package/lib/ui-kit/Img/ImgAsPicture.d.ts +0 -2
- package/lib/ui-kit/Img/ImgAsPicture.js +17 -19
- package/lib/ui-kit/Img/ImgAsPicture.js.map +1 -1
- package/lib/utils/adjustHref.d.ts +3 -0
- package/lib/utils/adjustHref.js +11 -0
- package/lib/utils/adjustHref.js.map +1 -0
- package/lib/utils/dirname.d.ts +1 -0
- package/lib/utils/dirname.js +2 -0
- package/lib/utils/dirname.js.map +1 -0
- package/lib/utils/url.d.ts +2 -2
- package/lib/utils/url.js +1 -1
- package/lib/utils/url.js.map +1 -1
- package/lib/wlc.json +0 -1
- package/mobile/bundle/bundle.umd.js +79 -93
- package/mobile/bundle/bundle.umd.min.js +1 -1
- package/mobile/bundle/services/BlockRouter/BlockRouter.d.ts +1 -3
- package/mobile/bundle/ui-kit/Img/ImgAsPicture.d.ts +0 -2
- package/mobile/bundle/utils/adjustHref.d.ts +3 -0
- package/mobile/bundle/utils/dirname.d.ts +1 -0
- package/mobile/bundle/utils/url.d.ts +2 -2
- package/mobile/dist/ProjectSettings.js +3 -4
- package/mobile/dist/ProjectSettings.js.map +1 -1
- package/mobile/dist/hooks/useLink.js +4 -16
- package/mobile/dist/hooks/useLink.js.map +1 -1
- package/mobile/dist/services/BlockRouter/BlockRouter.d.ts +1 -3
- package/mobile/dist/services/BlockRouter/BlockRouter.js +6 -9
- package/mobile/dist/services/BlockRouter/BlockRouter.js.map +1 -1
- package/mobile/dist/services/BlockRouter/useBlockRouterProvider.js +2 -10
- package/mobile/dist/services/BlockRouter/useBlockRouterProvider.js.map +1 -1
- package/mobile/dist/setup-fixture.js +3 -4
- package/mobile/dist/setup-fixture.js.map +1 -1
- package/mobile/dist/ui-kit/BlockWrapper.js +3 -2
- package/mobile/dist/ui-kit/BlockWrapper.js.map +1 -1
- package/mobile/dist/ui-kit/Icon/Icon.js +5 -1
- package/mobile/dist/ui-kit/Icon/Icon.js.map +1 -1
- package/mobile/dist/ui-kit/Img/ImgAsPicture.d.ts +0 -2
- package/mobile/dist/ui-kit/Img/ImgAsPicture.js +18 -21
- package/mobile/dist/ui-kit/Img/ImgAsPicture.js.map +1 -1
- package/mobile/dist/utils/adjustHref.d.ts +3 -0
- package/mobile/dist/utils/adjustHref.js +14 -0
- package/mobile/dist/utils/adjustHref.js.map +1 -0
- package/mobile/dist/utils/dirname.d.ts +1 -0
- package/mobile/dist/utils/dirname.js +5 -0
- package/mobile/dist/utils/dirname.js.map +1 -0
- package/mobile/dist/utils/url.d.ts +2 -2
- package/mobile/dist/utils/url.js +1 -1
- package/mobile/dist/utils/url.js.map +1 -1
- package/mobile/dist/wlc.json +0 -1
- package/mobile/lib/ProjectSettings.js +3 -4
- package/mobile/lib/ProjectSettings.js.map +1 -1
- package/mobile/lib/hooks/useLink.js +5 -17
- package/mobile/lib/hooks/useLink.js.map +1 -1
- package/mobile/lib/services/BlockRouter/BlockRouter.d.ts +1 -3
- package/mobile/lib/services/BlockRouter/BlockRouter.js +5 -7
- package/mobile/lib/services/BlockRouter/BlockRouter.js.map +1 -1
- package/mobile/lib/services/BlockRouter/useBlockRouterProvider.js +2 -10
- package/mobile/lib/services/BlockRouter/useBlockRouterProvider.js.map +1 -1
- package/mobile/lib/setup-fixture.js +3 -4
- package/mobile/lib/setup-fixture.js.map +1 -1
- package/mobile/lib/ui-kit/BlockWrapper.js +3 -2
- package/mobile/lib/ui-kit/BlockWrapper.js.map +1 -1
- package/mobile/lib/ui-kit/Icon/Icon.js +5 -1
- package/mobile/lib/ui-kit/Icon/Icon.js.map +1 -1
- package/mobile/lib/ui-kit/Img/ImgAsPicture.d.ts +0 -2
- package/mobile/lib/ui-kit/Img/ImgAsPicture.js +17 -19
- package/mobile/lib/ui-kit/Img/ImgAsPicture.js.map +1 -1
- package/mobile/lib/utils/adjustHref.d.ts +3 -0
- package/mobile/lib/utils/adjustHref.js +11 -0
- package/mobile/lib/utils/adjustHref.js.map +1 -0
- package/mobile/lib/utils/dirname.d.ts +1 -0
- package/mobile/lib/utils/dirname.js +2 -0
- package/mobile/lib/utils/dirname.js.map +1 -0
- package/mobile/lib/utils/url.d.ts +2 -2
- package/mobile/lib/utils/url.js +1 -1
- package/mobile/lib/utils/url.js.map +1 -1
- package/mobile/lib/wlc.json +0 -1
- package/mobile/src/ProjectSettings.ts +4 -4
- package/mobile/src/hooks/useLink.ts +5 -18
- package/mobile/src/services/BlockRouter/BlockRouter.ts +5 -8
- package/mobile/src/services/BlockRouter/useBlockRouterProvider.ts +4 -10
- package/mobile/src/setup-fixture.ts +5 -4
- package/mobile/src/ui-kit/BlockWrapper.tsx +3 -2
- package/mobile/src/ui-kit/Icon/Icon.tsx +5 -1
- package/mobile/src/ui-kit/Img/ImgAsPicture.tsx +23 -28
- package/mobile/src/utils/adjustHref.ts +17 -0
- package/mobile/src/utils/dirname.ts +1 -0
- package/mobile/src/utils/url.ts +2 -3
- package/mobile/src/wlc.json +0 -1
- package/package.json +1 -1
- package/src/ProjectSettings.ts +4 -4
- package/src/hooks/useLink.ts +5 -18
- package/src/services/BlockRouter/BlockRouter.ts +5 -8
- package/src/services/BlockRouter/useBlockRouterProvider.ts +4 -10
- package/src/setup-fixture.ts +5 -4
- package/src/ui-kit/BlockWrapper.tsx +3 -2
- package/src/ui-kit/Icon/Icon.tsx +5 -1
- package/src/ui-kit/Img/ImgAsPicture.tsx +23 -28
- package/src/utils/adjustHref.ts +17 -0
- package/src/utils/dirname.ts +1 -0
- package/src/utils/url.ts +2 -3
- package/src/wlc.json +0 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { LinkProps } from '../model/LinkProps';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { isHash, isLocalURL, joinPath } from '../utils/url';
|
|
2
|
+
import { adjustHref } from '../utils/adjustHref';
|
|
3
|
+
import { isLocalURL } from '../utils/url';
|
|
5
4
|
import { handlerDecorator } from './handlerDecorator';
|
|
6
5
|
import { useRouter } from './useRouter';
|
|
7
6
|
|
|
@@ -18,35 +17,23 @@ export function useLink(isRemote?: boolean) {
|
|
|
18
17
|
|
|
19
18
|
return <L extends Partial<LinkProps & Clickable>>(props: L): L & Clickable => ({
|
|
20
19
|
...props,
|
|
21
|
-
href: adjustHref(props.href),
|
|
20
|
+
href: isRemote ? props.href : adjustHref(router)(props.href),
|
|
22
21
|
'aria-label': props.text,
|
|
23
22
|
onClick: handlerDecorator(handleHref(props), props),
|
|
24
23
|
});
|
|
25
24
|
|
|
26
|
-
function adjustHref(href: string | undefined) {
|
|
27
|
-
const isRelativeToBase = !isRemote && href?.startsWith('/');
|
|
28
|
-
|
|
29
|
-
return projectSettings.BASE_PATH && href && isRelativeToBase
|
|
30
|
-
? joinPath(projectSettings.BASE_PATH, href)
|
|
31
|
-
: href;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
25
|
function handleHref({ href, target, onClick }: Partial<LinkProps & Clickable>) {
|
|
35
26
|
return (ev?: PreventableEvent) => {
|
|
36
27
|
onClick && onClick(ev);
|
|
37
28
|
|
|
38
|
-
if (isRemote || !isLocalURL(href, target)) {
|
|
29
|
+
if (!href || isRemote || !isLocalURL(href, target)) {
|
|
39
30
|
// Default routing
|
|
40
31
|
return;
|
|
41
32
|
}
|
|
42
33
|
|
|
43
34
|
// Client routing
|
|
44
35
|
ev?.preventDefault();
|
|
45
|
-
|
|
46
|
-
gotoBlock(router, href);
|
|
47
|
-
} else if (href) {
|
|
48
|
-
router.push(href);
|
|
49
|
-
}
|
|
36
|
+
router.push(href);
|
|
50
37
|
};
|
|
51
38
|
}
|
|
52
39
|
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import type { Router } from '../../hooks/useRouter';
|
|
2
1
|
import type { BlockDef } from '../../model/ContentPageDef';
|
|
3
2
|
|
|
4
3
|
const normalizeAnchor = (anchor?: string) => anchor?.replace('#', '') || '';
|
|
5
4
|
|
|
6
|
-
export function
|
|
7
|
-
|
|
8
|
-
}
|
|
5
|
+
export function trackBlock(block?: BlockDef) {
|
|
6
|
+
const hash = `#${normalizeAnchor(block?.anchor)}`;
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
});
|
|
8
|
+
if (globalThis.location?.hash !== hash) {
|
|
9
|
+
globalThis.history?.replaceState(globalThis.history?.state, '', hash);
|
|
10
|
+
}
|
|
14
11
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { useEffect, useRef } from '@redneckz/uni-jsx/lib/hooks';
|
|
2
|
-
import { useRouter } from '../../hooks/useRouter';
|
|
3
2
|
import type { BlockDef } from '../../model/ContentPageDef';
|
|
4
3
|
import { debounce } from '../../utils/debounce';
|
|
5
4
|
import { trackBlock } from './BlockRouter';
|
|
@@ -9,8 +8,6 @@ import { findActiveBlock } from './findActiveBlock';
|
|
|
9
8
|
const isScrolledEnough = () => globalThis.scrollY > (globalThis.innerHeight * 3) / 4;
|
|
10
9
|
|
|
11
10
|
export function useBlockRouterProvider(scrollTarget: EventTarget = globalThis) {
|
|
12
|
-
const router = useRouter();
|
|
13
|
-
|
|
14
11
|
const intersectionsMapRef = useRef<Map<BlockDef, IntersectionObserverEntry>>(new Map());
|
|
15
12
|
|
|
16
13
|
useEffect(
|
|
@@ -25,12 +22,9 @@ export function useBlockRouterProvider(scrollTarget: EventTarget = globalThis) {
|
|
|
25
22
|
|
|
26
23
|
useEffect(() => {
|
|
27
24
|
const handleScroll = debounce(() => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} else {
|
|
32
|
-
trackBlock(router);
|
|
33
|
-
}
|
|
25
|
+
trackBlock(
|
|
26
|
+
isScrolledEnough() ? findActiveBlock([...(intersectionsMapRef.current || [])]) : undefined,
|
|
27
|
+
);
|
|
34
28
|
}, 100);
|
|
35
29
|
|
|
36
30
|
scrollTarget.addEventListener('scroll', handleScroll);
|
|
@@ -39,5 +33,5 @@ export function useBlockRouterProvider(scrollTarget: EventTarget = globalThis) {
|
|
|
39
33
|
handleScroll.dispose();
|
|
40
34
|
scrollTarget.removeEventListener('scroll', handleScroll);
|
|
41
35
|
};
|
|
42
|
-
}, [
|
|
36
|
+
}, [scrollTarget]);
|
|
43
37
|
}
|
|
@@ -3,13 +3,14 @@ import { useEffect, useState } from 'react';
|
|
|
3
3
|
import { handlerDecorator } from './hooks/handlerDecorator';
|
|
4
4
|
import { useRouter } from './hooks/useRouter';
|
|
5
5
|
import { projectSettings } from './ProjectSettings';
|
|
6
|
+
import { joinPath } from './utils/url';
|
|
6
7
|
import wlc from './wlc.json';
|
|
7
8
|
|
|
8
9
|
projectSettings.setup(wlc);
|
|
9
10
|
|
|
10
11
|
useRouter.setup(() => {
|
|
11
12
|
const [href, setHref] = useState<string>(
|
|
12
|
-
|
|
13
|
+
joinPath(globalThis.location.origin, projectSettings.BASE_PATH, 'cards-credit'),
|
|
13
14
|
);
|
|
14
15
|
|
|
15
16
|
useEffect(() => {
|
|
@@ -26,9 +27,9 @@ useRouter.setup(() => {
|
|
|
26
27
|
|
|
27
28
|
return {
|
|
28
29
|
href,
|
|
29
|
-
pathname:
|
|
30
|
-
?
|
|
31
|
-
|
|
30
|
+
pathname: new URL(href).pathname.substring(
|
|
31
|
+
projectSettings.BASE_PATH ? projectSettings.BASE_PATH.length - 1 : 0,
|
|
32
|
+
),
|
|
32
33
|
query: {},
|
|
33
34
|
push: (url: string) => {
|
|
34
35
|
globalThis.history.pushState(null, '', url);
|
|
@@ -30,9 +30,10 @@ export const BlockWrapper = JSX<BlockWrapperProps>(
|
|
|
30
30
|
() =>
|
|
31
31
|
defaultEventBus.subscribe('tab', (event) => {
|
|
32
32
|
if (event.type === 'group') {
|
|
33
|
-
const hasSettings = block?.labels?.length || block?.anchor;
|
|
34
33
|
setVisible(
|
|
35
|
-
|
|
34
|
+
!block?.labels?.length ||
|
|
35
|
+
!event.label ||
|
|
36
|
+
Boolean(block?.labels?.includes(event.label)),
|
|
36
37
|
);
|
|
37
38
|
} else {
|
|
38
39
|
setVisible(true);
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import { useRouter } from '../../hooks/useRouter';
|
|
2
3
|
import type { IconVersion } from '../../model/IconVersion';
|
|
3
4
|
import { projectSettings } from '../../ProjectSettings';
|
|
5
|
+
import { adjustHref } from '../../utils/adjustHref';
|
|
4
6
|
import { style } from '../../utils/style';
|
|
7
|
+
import { joinPath } from '../../utils/url';
|
|
5
8
|
import type { IconProps } from './IconProps';
|
|
6
9
|
|
|
7
10
|
const svgUseStyleMap: Record<IconVersion, string> = {
|
|
@@ -22,7 +25,8 @@ export const Icon = JSX<IconProps>(
|
|
|
22
25
|
asSVG,
|
|
23
26
|
...imgProps
|
|
24
27
|
}) => {
|
|
25
|
-
const
|
|
28
|
+
const router = useRouter();
|
|
29
|
+
const href = adjustHref(router)(joinPath(projectSettings.CDN, '/icons', `${name}.svg`));
|
|
26
30
|
|
|
27
31
|
if (asSVG && iconVersion !== 'normal') {
|
|
28
32
|
return (
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import { Router, useRouter } from '../../hooks/useRouter';
|
|
2
3
|
import type { ImgSource, Picture } from '../../model/Picture';
|
|
4
|
+
import { adjustHref } from '../../utils/adjustHref';
|
|
5
|
+
import { isURL, joinPath } from '../../utils/url';
|
|
3
6
|
import type { ImageProps } from './ImgProps';
|
|
4
7
|
|
|
5
|
-
const sourcesComparator = (a: Picture, b: Picture) =>
|
|
6
|
-
|
|
7
|
-
return a.media - b.media;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return 0;
|
|
11
|
-
};
|
|
8
|
+
const sourcesComparator = (a: Picture, b: Picture) =>
|
|
9
|
+
a?.media && b?.media ? a.media - b.media : 0;
|
|
12
10
|
|
|
13
11
|
export const ImgAsPicture = JSX<ImageProps>(
|
|
14
12
|
({ className = '', image, imageClassName = '', isMobile = false, pathPrefix }) => {
|
|
15
|
-
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
13
|
+
const router = useRouter();
|
|
18
14
|
|
|
19
15
|
const pictureStyles = isMobile ? 'flex' : 'flex-none';
|
|
20
16
|
|
|
@@ -22,22 +18,25 @@ export const ImgAsPicture = JSX<ImageProps>(
|
|
|
22
18
|
<picture className={`${pictureStyles} ${className}`}>
|
|
23
19
|
{image?.sources?.length
|
|
24
20
|
? image.sources
|
|
21
|
+
.filter((_) => _?.src)
|
|
25
22
|
.sort(sourcesComparator)
|
|
26
23
|
.map(({ src, format, media }, index) => (
|
|
27
24
|
<source
|
|
28
25
|
key={`${index}_${src}`}
|
|
29
|
-
srcSet={
|
|
26
|
+
srcSet={adjustSrcset(router, pathPrefix)(src)}
|
|
30
27
|
type={formatToMimeType(format)}
|
|
31
28
|
media={media ? `(max-width: ${media}px)` : ''}
|
|
32
29
|
{...image.size}
|
|
33
30
|
/>
|
|
34
31
|
))
|
|
35
32
|
: null}
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
{image?.src
|
|
34
|
+
? renderImg(
|
|
35
|
+
{ ...image, src: adjustSrcset(router, pathPrefix)(image.src) },
|
|
36
|
+
imageClassName,
|
|
37
|
+
isMobile,
|
|
38
|
+
)
|
|
39
|
+
: null}
|
|
41
40
|
</picture>
|
|
42
41
|
);
|
|
43
42
|
},
|
|
@@ -65,18 +64,14 @@ const renderImg = (image: Picture, imageClassName = '', isMobile = false) => {
|
|
|
65
64
|
);
|
|
66
65
|
};
|
|
67
66
|
|
|
68
|
-
const
|
|
69
|
-
pathPrefix && !pathPrefix.endsWith('/') ? `${pathPrefix}/` : pathPrefix;
|
|
70
|
-
|
|
71
|
-
const addPathPrefixToSrc = (src?: string, pathPrefix?: string) =>
|
|
72
|
-
!src || src?.startsWith('data:image') ? src : `${normalizePathPrefix(pathPrefix)}${src}`;
|
|
73
|
-
|
|
74
|
-
const addPathPrefixToSrcSet = (srcset?: string, pathPrefix?: string) =>
|
|
67
|
+
const adjustSrcset = (router: Router, pathPrefix?: string) => (srcset: string | undefined) =>
|
|
75
68
|
srcset
|
|
76
|
-
?.split(
|
|
77
|
-
.map((src) =>
|
|
69
|
+
?.split(/\s*,\s*/)
|
|
70
|
+
.map((src) => src.trim())
|
|
71
|
+
.filter(Boolean)
|
|
72
|
+
.map((src) => (isURL(src) ? src : joinPath(pathPrefix, src)))
|
|
73
|
+
.map(adjustHref(router))
|
|
78
74
|
.join(', ');
|
|
79
75
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
76
|
+
const formatToMimeType = (format: ImgSource['format']) =>
|
|
77
|
+
format ? `image/${String(format)}` : undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { projectSettings } from '../ProjectSettings';
|
|
2
|
+
import { dirname } from './dirname';
|
|
3
|
+
import { isURL, joinPath } from './url';
|
|
4
|
+
|
|
5
|
+
export const adjustHref = (router: { pathname: string }) => (href: string | undefined) => {
|
|
6
|
+
if (!href || isURL(href) || (projectSettings.CDN && href.startsWith(projectSettings.CDN))) {
|
|
7
|
+
return href;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const isRelativeToBase = href.startsWith('/');
|
|
11
|
+
|
|
12
|
+
return joinPath(
|
|
13
|
+
projectSettings.BASE_PATH,
|
|
14
|
+
isRelativeToBase ? '/' : dirname(router.pathname),
|
|
15
|
+
href,
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const dirname = (path: string | undefined) => path?.split('/').slice(0, -1).join('/');
|
package/mobile/src/utils/url.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Target } from '../model/LinkProps';
|
|
2
2
|
|
|
3
|
-
export const isURL = (href?: string): href is `${string}
|
|
4
|
-
Boolean(href?.includes('//'));
|
|
3
|
+
export const isURL = (href?: string): href is `${string}:${string}` => Boolean(href?.includes(':'));
|
|
5
4
|
|
|
6
5
|
export const isLocalURL = (href: string | undefined, target?: Target) =>
|
|
7
6
|
Boolean(href && !isURL(href) && (!target || target === '_self'));
|
|
@@ -11,5 +10,5 @@ export const isHash = (href?: string): href is `#${string}` => Boolean(href?.sta
|
|
|
11
10
|
export const withoutQuery = (href?: string): string =>
|
|
12
11
|
(href || '').replace(/\?.*/, '').replace(/\/$/, '');
|
|
13
12
|
|
|
14
|
-
export const joinPath = (...path: string[]): string =>
|
|
13
|
+
export const joinPath = (...path: (string | undefined)[]): string =>
|
|
15
14
|
path.filter(Boolean).join('/').replace(/\/+/g, '/');
|
package/mobile/src/wlc.json
CHANGED
package/package.json
CHANGED
package/src/ProjectSettings.ts
CHANGED
|
@@ -43,12 +43,10 @@ export const projectSettings = new (class implements ProjectSettings {
|
|
|
43
43
|
return this._.FOOTER;
|
|
44
44
|
}
|
|
45
45
|
get CDN() {
|
|
46
|
-
return this._.CDN;
|
|
46
|
+
return appendSlash(this._.CDN);
|
|
47
47
|
}
|
|
48
48
|
get BASE_PATH() {
|
|
49
|
-
return this._.BASE_PATH
|
|
50
|
-
? `${this._.BASE_PATH}/`
|
|
51
|
-
: this._.BASE_PATH;
|
|
49
|
+
return appendSlash(this._.BASE_PATH);
|
|
52
50
|
}
|
|
53
51
|
get YANDEX_MAP_API_KEY() {
|
|
54
52
|
return this._.YANDEX_MAP_API_KEY;
|
|
@@ -57,3 +55,5 @@ export const projectSettings = new (class implements ProjectSettings {
|
|
|
57
55
|
return this._.YANDEX_METRIKA_ID;
|
|
58
56
|
}
|
|
59
57
|
})();
|
|
58
|
+
|
|
59
|
+
const appendSlash = (url: string | undefined) => (url && !url.endsWith('/') ? `${url}/` : url);
|
package/src/hooks/useLink.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { LinkProps } from '../model/LinkProps';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { isHash, isLocalURL, joinPath } from '../utils/url';
|
|
2
|
+
import { adjustHref } from '../utils/adjustHref';
|
|
3
|
+
import { isLocalURL } from '../utils/url';
|
|
5
4
|
import { handlerDecorator } from './handlerDecorator';
|
|
6
5
|
import { useRouter } from './useRouter';
|
|
7
6
|
|
|
@@ -18,35 +17,23 @@ export function useLink(isRemote?: boolean) {
|
|
|
18
17
|
|
|
19
18
|
return <L extends Partial<LinkProps & Clickable>>(props: L): L & Clickable => ({
|
|
20
19
|
...props,
|
|
21
|
-
href: adjustHref(props.href),
|
|
20
|
+
href: isRemote ? props.href : adjustHref(router)(props.href),
|
|
22
21
|
'aria-label': props.text,
|
|
23
22
|
onClick: handlerDecorator(handleHref(props), props),
|
|
24
23
|
});
|
|
25
24
|
|
|
26
|
-
function adjustHref(href: string | undefined) {
|
|
27
|
-
const isRelativeToBase = !isRemote && href?.startsWith('/');
|
|
28
|
-
|
|
29
|
-
return projectSettings.BASE_PATH && href && isRelativeToBase
|
|
30
|
-
? joinPath(projectSettings.BASE_PATH, href)
|
|
31
|
-
: href;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
25
|
function handleHref({ href, target, onClick }: Partial<LinkProps & Clickable>) {
|
|
35
26
|
return (ev?: PreventableEvent) => {
|
|
36
27
|
onClick && onClick(ev);
|
|
37
28
|
|
|
38
|
-
if (isRemote || !isLocalURL(href, target)) {
|
|
29
|
+
if (!href || isRemote || !isLocalURL(href, target)) {
|
|
39
30
|
// Default routing
|
|
40
31
|
return;
|
|
41
32
|
}
|
|
42
33
|
|
|
43
34
|
// Client routing
|
|
44
35
|
ev?.preventDefault();
|
|
45
|
-
|
|
46
|
-
gotoBlock(router, href);
|
|
47
|
-
} else if (href) {
|
|
48
|
-
router.push(href);
|
|
49
|
-
}
|
|
36
|
+
router.push(href);
|
|
50
37
|
};
|
|
51
38
|
}
|
|
52
39
|
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import type { Router } from '../../hooks/useRouter';
|
|
2
1
|
import type { BlockDef } from '../../model/ContentPageDef';
|
|
3
2
|
|
|
4
3
|
const normalizeAnchor = (anchor?: string) => anchor?.replace('#', '') || '';
|
|
5
4
|
|
|
6
|
-
export function
|
|
7
|
-
|
|
8
|
-
}
|
|
5
|
+
export function trackBlock(block?: BlockDef) {
|
|
6
|
+
const hash = `#${normalizeAnchor(block?.anchor)}`;
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
});
|
|
8
|
+
if (globalThis.location?.hash !== hash) {
|
|
9
|
+
globalThis.history?.replaceState(globalThis.history?.state, '', hash);
|
|
10
|
+
}
|
|
14
11
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { useEffect, useRef } from '@redneckz/uni-jsx/lib/hooks';
|
|
2
|
-
import { useRouter } from '../../hooks/useRouter';
|
|
3
2
|
import type { BlockDef } from '../../model/ContentPageDef';
|
|
4
3
|
import { debounce } from '../../utils/debounce';
|
|
5
4
|
import { trackBlock } from './BlockRouter';
|
|
@@ -9,8 +8,6 @@ import { findActiveBlock } from './findActiveBlock';
|
|
|
9
8
|
const isScrolledEnough = () => globalThis.scrollY > (globalThis.innerHeight * 3) / 4;
|
|
10
9
|
|
|
11
10
|
export function useBlockRouterProvider(scrollTarget: EventTarget = globalThis) {
|
|
12
|
-
const router = useRouter();
|
|
13
|
-
|
|
14
11
|
const intersectionsMapRef = useRef<Map<BlockDef, IntersectionObserverEntry>>(new Map());
|
|
15
12
|
|
|
16
13
|
useEffect(
|
|
@@ -25,12 +22,9 @@ export function useBlockRouterProvider(scrollTarget: EventTarget = globalThis) {
|
|
|
25
22
|
|
|
26
23
|
useEffect(() => {
|
|
27
24
|
const handleScroll = debounce(() => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} else {
|
|
32
|
-
trackBlock(router);
|
|
33
|
-
}
|
|
25
|
+
trackBlock(
|
|
26
|
+
isScrolledEnough() ? findActiveBlock([...(intersectionsMapRef.current || [])]) : undefined,
|
|
27
|
+
);
|
|
34
28
|
}, 100);
|
|
35
29
|
|
|
36
30
|
scrollTarget.addEventListener('scroll', handleScroll);
|
|
@@ -39,5 +33,5 @@ export function useBlockRouterProvider(scrollTarget: EventTarget = globalThis) {
|
|
|
39
33
|
handleScroll.dispose();
|
|
40
34
|
scrollTarget.removeEventListener('scroll', handleScroll);
|
|
41
35
|
};
|
|
42
|
-
}, [
|
|
36
|
+
}, [scrollTarget]);
|
|
43
37
|
}
|
package/src/setup-fixture.ts
CHANGED
|
@@ -3,13 +3,14 @@ import { useEffect, useState } from 'react';
|
|
|
3
3
|
import { handlerDecorator } from './hooks/handlerDecorator';
|
|
4
4
|
import { useRouter } from './hooks/useRouter';
|
|
5
5
|
import { projectSettings } from './ProjectSettings';
|
|
6
|
+
import { joinPath } from './utils/url';
|
|
6
7
|
import wlc from './wlc.json';
|
|
7
8
|
|
|
8
9
|
projectSettings.setup(wlc);
|
|
9
10
|
|
|
10
11
|
useRouter.setup(() => {
|
|
11
12
|
const [href, setHref] = useState<string>(
|
|
12
|
-
|
|
13
|
+
joinPath(globalThis.location.origin, projectSettings.BASE_PATH, 'cards-credit'),
|
|
13
14
|
);
|
|
14
15
|
|
|
15
16
|
useEffect(() => {
|
|
@@ -26,9 +27,9 @@ useRouter.setup(() => {
|
|
|
26
27
|
|
|
27
28
|
return {
|
|
28
29
|
href,
|
|
29
|
-
pathname:
|
|
30
|
-
?
|
|
31
|
-
|
|
30
|
+
pathname: new URL(href).pathname.substring(
|
|
31
|
+
projectSettings.BASE_PATH ? projectSettings.BASE_PATH.length - 1 : 0,
|
|
32
|
+
),
|
|
32
33
|
query: {},
|
|
33
34
|
push: (url: string) => {
|
|
34
35
|
globalThis.history.pushState(null, '', url);
|
|
@@ -30,9 +30,10 @@ export const BlockWrapper = JSX<BlockWrapperProps>(
|
|
|
30
30
|
() =>
|
|
31
31
|
defaultEventBus.subscribe('tab', (event) => {
|
|
32
32
|
if (event.type === 'group') {
|
|
33
|
-
const hasSettings = block?.labels?.length || block?.anchor;
|
|
34
33
|
setVisible(
|
|
35
|
-
|
|
34
|
+
!block?.labels?.length ||
|
|
35
|
+
!event.label ||
|
|
36
|
+
Boolean(block?.labels?.includes(event.label)),
|
|
36
37
|
);
|
|
37
38
|
} else {
|
|
38
39
|
setVisible(true);
|
package/src/ui-kit/Icon/Icon.tsx
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import { useRouter } from '../../hooks/useRouter';
|
|
2
3
|
import type { IconVersion } from '../../model/IconVersion';
|
|
3
4
|
import { projectSettings } from '../../ProjectSettings';
|
|
5
|
+
import { adjustHref } from '../../utils/adjustHref';
|
|
4
6
|
import { style } from '../../utils/style';
|
|
7
|
+
import { joinPath } from '../../utils/url';
|
|
5
8
|
import type { IconProps } from './IconProps';
|
|
6
9
|
|
|
7
10
|
const svgUseStyleMap: Record<IconVersion, string> = {
|
|
@@ -22,7 +25,8 @@ export const Icon = JSX<IconProps>(
|
|
|
22
25
|
asSVG,
|
|
23
26
|
...imgProps
|
|
24
27
|
}) => {
|
|
25
|
-
const
|
|
28
|
+
const router = useRouter();
|
|
29
|
+
const href = adjustHref(router)(joinPath(projectSettings.CDN, '/icons', `${name}.svg`));
|
|
26
30
|
|
|
27
31
|
if (asSVG && iconVersion !== 'normal') {
|
|
28
32
|
return (
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import { Router, useRouter } from '../../hooks/useRouter';
|
|
2
3
|
import type { ImgSource, Picture } from '../../model/Picture';
|
|
4
|
+
import { adjustHref } from '../../utils/adjustHref';
|
|
5
|
+
import { isURL, joinPath } from '../../utils/url';
|
|
3
6
|
import type { ImageProps } from './ImgProps';
|
|
4
7
|
|
|
5
|
-
const sourcesComparator = (a: Picture, b: Picture) =>
|
|
6
|
-
|
|
7
|
-
return a.media - b.media;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return 0;
|
|
11
|
-
};
|
|
8
|
+
const sourcesComparator = (a: Picture, b: Picture) =>
|
|
9
|
+
a?.media && b?.media ? a.media - b.media : 0;
|
|
12
10
|
|
|
13
11
|
export const ImgAsPicture = JSX<ImageProps>(
|
|
14
12
|
({ className = '', image, imageClassName = '', isMobile = false, pathPrefix }) => {
|
|
15
|
-
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
13
|
+
const router = useRouter();
|
|
18
14
|
|
|
19
15
|
const pictureStyles = isMobile ? 'flex' : 'flex-none';
|
|
20
16
|
|
|
@@ -22,22 +18,25 @@ export const ImgAsPicture = JSX<ImageProps>(
|
|
|
22
18
|
<picture className={`${pictureStyles} ${className}`}>
|
|
23
19
|
{image?.sources?.length
|
|
24
20
|
? image.sources
|
|
21
|
+
.filter((_) => _?.src)
|
|
25
22
|
.sort(sourcesComparator)
|
|
26
23
|
.map(({ src, format, media }, index) => (
|
|
27
24
|
<source
|
|
28
25
|
key={`${index}_${src}`}
|
|
29
|
-
srcSet={
|
|
26
|
+
srcSet={adjustSrcset(router, pathPrefix)(src)}
|
|
30
27
|
type={formatToMimeType(format)}
|
|
31
28
|
media={media ? `(max-width: ${media}px)` : ''}
|
|
32
29
|
{...image.size}
|
|
33
30
|
/>
|
|
34
31
|
))
|
|
35
32
|
: null}
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
{image?.src
|
|
34
|
+
? renderImg(
|
|
35
|
+
{ ...image, src: adjustSrcset(router, pathPrefix)(image.src) },
|
|
36
|
+
imageClassName,
|
|
37
|
+
isMobile,
|
|
38
|
+
)
|
|
39
|
+
: null}
|
|
41
40
|
</picture>
|
|
42
41
|
);
|
|
43
42
|
},
|
|
@@ -65,18 +64,14 @@ const renderImg = (image: Picture, imageClassName = '', isMobile = false) => {
|
|
|
65
64
|
);
|
|
66
65
|
};
|
|
67
66
|
|
|
68
|
-
const
|
|
69
|
-
pathPrefix && !pathPrefix.endsWith('/') ? `${pathPrefix}/` : pathPrefix;
|
|
70
|
-
|
|
71
|
-
const addPathPrefixToSrc = (src?: string, pathPrefix?: string) =>
|
|
72
|
-
!src || src?.startsWith('data:image') ? src : `${normalizePathPrefix(pathPrefix)}${src}`;
|
|
73
|
-
|
|
74
|
-
const addPathPrefixToSrcSet = (srcset?: string, pathPrefix?: string) =>
|
|
67
|
+
const adjustSrcset = (router: Router, pathPrefix?: string) => (srcset: string | undefined) =>
|
|
75
68
|
srcset
|
|
76
|
-
?.split(
|
|
77
|
-
.map((src) =>
|
|
69
|
+
?.split(/\s*,\s*/)
|
|
70
|
+
.map((src) => src.trim())
|
|
71
|
+
.filter(Boolean)
|
|
72
|
+
.map((src) => (isURL(src) ? src : joinPath(pathPrefix, src)))
|
|
73
|
+
.map(adjustHref(router))
|
|
78
74
|
.join(', ');
|
|
79
75
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
76
|
+
const formatToMimeType = (format: ImgSource['format']) =>
|
|
77
|
+
format ? `image/${String(format)}` : undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { projectSettings } from '../ProjectSettings';
|
|
2
|
+
import { dirname } from './dirname';
|
|
3
|
+
import { isURL, joinPath } from './url';
|
|
4
|
+
|
|
5
|
+
export const adjustHref = (router: { pathname: string }) => (href: string | undefined) => {
|
|
6
|
+
if (!href || isURL(href) || (projectSettings.CDN && href.startsWith(projectSettings.CDN))) {
|
|
7
|
+
return href;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const isRelativeToBase = href.startsWith('/');
|
|
11
|
+
|
|
12
|
+
return joinPath(
|
|
13
|
+
projectSettings.BASE_PATH,
|
|
14
|
+
isRelativeToBase ? '/' : dirname(router.pathname),
|
|
15
|
+
href,
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const dirname = (path: string | undefined) => path?.split('/').slice(0, -1).join('/');
|
package/src/utils/url.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Target } from '../model/LinkProps';
|
|
2
2
|
|
|
3
|
-
export const isURL = (href?: string): href is `${string}
|
|
4
|
-
Boolean(href?.includes('//'));
|
|
3
|
+
export const isURL = (href?: string): href is `${string}:${string}` => Boolean(href?.includes(':'));
|
|
5
4
|
|
|
6
5
|
export const isLocalURL = (href: string | undefined, target?: Target) =>
|
|
7
6
|
Boolean(href && !isURL(href) && (!target || target === '_self'));
|
|
@@ -11,5 +10,5 @@ export const isHash = (href?: string): href is `#${string}` => Boolean(href?.sta
|
|
|
11
10
|
export const withoutQuery = (href?: string): string =>
|
|
12
11
|
(href || '').replace(/\?.*/, '').replace(/\/$/, '');
|
|
13
12
|
|
|
14
|
-
export const joinPath = (...path: string[]): string =>
|
|
13
|
+
export const joinPath = (...path: (string | undefined)[]): string =>
|
|
15
14
|
path.filter(Boolean).join('/').replace(/\/+/g, '/');
|