@gravity-ui/page-constructor 1.16.3 → 1.17.0
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/CHANGELOG.md +20 -0
- package/build/cjs/components/BackLink/__tests__/BackLink.test.d.ts +1 -0
- package/build/cjs/components/BackLink/__tests__/BackLink.test.js +63 -0
- package/build/cjs/components/OverflowScroller/OverflowScroller.css +16 -5
- package/build/cjs/components/OverflowScroller/OverflowScroller.d.ts +1 -1
- package/build/cjs/components/OverflowScroller/OverflowScroller.js +13 -5
- package/build/cjs/models/constructor-items/sub-blocks.d.ts +1 -0
- package/build/cjs/models/navigation.d.ts +9 -3
- package/build/cjs/models/navigation.js +1 -0
- package/build/cjs/navigation/components/Header/Header.css +2 -2
- package/build/cjs/navigation/components/Header/Header.js +1 -1
- package/build/cjs/navigation/components/NavigationItem/NavigationItem.css +0 -35
- package/build/cjs/navigation/components/NavigationItem/NavigationItem.js +9 -39
- package/build/cjs/navigation/components/NavigationItem/components/ContentWrapper/ContentWrapper.css +7 -0
- package/build/cjs/navigation/components/NavigationItem/components/ContentWrapper/ContentWrapper.d.ts +6 -0
- package/build/cjs/navigation/components/NavigationItem/components/ContentWrapper/ContentWrapper.js +12 -0
- package/build/cjs/navigation/components/NavigationItem/components/GithubStars/GithubStars.css +10 -0
- package/build/cjs/navigation/components/NavigationItem/components/GithubStars/GithubStars.d.ts +5 -0
- package/build/cjs/navigation/components/NavigationItem/components/GithubStars/GithubStars.js +11 -0
- package/build/cjs/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.css +3 -0
- package/build/cjs/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.d.ts +6 -0
- package/build/cjs/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.js +15 -0
- package/build/cjs/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.css +4 -0
- package/build/cjs/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.d.ts +6 -0
- package/build/cjs/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.js +19 -0
- package/build/cjs/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.css +21 -0
- package/build/cjs/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.d.ts +6 -0
- package/build/cjs/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.js +30 -0
- package/build/cjs/sub-blocks/BasicCard/BasicCard.js +2 -2
- package/build/cjs/sub-blocks/BasicCard/schema.d.ts +4 -0
- package/build/cjs/sub-blocks/BasicCard/schema.js +4 -1
- package/build/cjs/utils/url.d.ts +1 -0
- package/build/cjs/utils/url.js +13 -10
- package/build/cjs/utils/url.test.d.ts +1 -0
- package/build/cjs/utils/url.test.js +76 -0
- package/build/esm/components/BackLink/__tests__/BackLink.test.d.ts +1 -0
- package/build/esm/components/BackLink/__tests__/BackLink.test.js +60 -0
- package/build/esm/components/OverflowScroller/OverflowScroller.css +16 -5
- package/build/esm/components/OverflowScroller/OverflowScroller.d.ts +1 -1
- package/build/esm/components/OverflowScroller/OverflowScroller.js +13 -5
- package/build/esm/models/constructor-items/sub-blocks.d.ts +1 -0
- package/build/esm/models/navigation.d.ts +9 -3
- package/build/esm/models/navigation.js +1 -0
- package/build/esm/navigation/components/Header/Header.css +2 -2
- package/build/esm/navigation/components/Header/Header.js +1 -1
- package/build/esm/navigation/components/NavigationItem/NavigationItem.css +0 -35
- package/build/esm/navigation/components/NavigationItem/NavigationItem.js +9 -39
- package/build/esm/navigation/components/NavigationItem/components/ContentWrapper/ContentWrapper.css +7 -0
- package/build/esm/navigation/components/NavigationItem/components/ContentWrapper/ContentWrapper.d.ts +7 -0
- package/build/esm/navigation/components/NavigationItem/components/ContentWrapper/ContentWrapper.js +8 -0
- package/build/esm/navigation/components/NavigationItem/components/GithubStars/GithubStars.css +10 -0
- package/build/esm/navigation/components/NavigationItem/components/GithubStars/GithubStars.d.ts +6 -0
- package/build/esm/navigation/components/NavigationItem/components/GithubStars/GithubStars.js +7 -0
- package/build/esm/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.css +3 -0
- package/build/esm/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.d.ts +7 -0
- package/build/esm/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.js +11 -0
- package/build/esm/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.css +4 -0
- package/build/esm/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.d.ts +7 -0
- package/build/esm/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.js +16 -0
- package/build/esm/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.css +21 -0
- package/build/esm/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.d.ts +7 -0
- package/build/esm/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.js +27 -0
- package/build/esm/sub-blocks/BasicCard/BasicCard.js +3 -2
- package/build/esm/sub-blocks/BasicCard/schema.d.ts +4 -0
- package/build/esm/sub-blocks/BasicCard/schema.js +4 -1
- package/build/esm/utils/url.d.ts +1 -0
- package/build/esm/utils/url.js +11 -9
- package/build/esm/utils/url.test.d.ts +1 -0
- package/build/esm/utils/url.test.js +74 -0
- package/package.json +2 -1
- package/server/models/constructor-items/sub-blocks.d.ts +1 -0
- package/server/models/navigation.d.ts +9 -3
- package/server/models/navigation.js +1 -0
- package/server/utils/url.d.ts +1 -0
- package/server/utils/url.js +13 -10
package/build/cjs/utils/url.js
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getAbsolutePath = exports.getPageSearchParams = exports.setUrlTld = exports.getNonLocaleHostName = exports.isLinkExternal = exports.getLinkProps = exports.EXTERNAL_LINK_PROPS = void 0;
|
|
3
|
+
exports.getAbsolutePath = exports.getPageSearchParams = exports.setUrlTld = exports.getNonLocaleHostName = exports.isLinkExternal = exports.isAbsoluteUrl = exports.getLinkProps = exports.EXTERNAL_LINK_PROPS = void 0;
|
|
4
4
|
const url_1 = require("url");
|
|
5
|
+
const EXAMPLE_URL = 'https://example.org';
|
|
5
6
|
exports.EXTERNAL_LINK_PROPS = { target: '_blank', rel: 'noopener noreferrer' };
|
|
6
7
|
function getLinkProps(url, hostname, target) {
|
|
7
8
|
let linkProps = { target };
|
|
8
|
-
if (
|
|
9
|
+
if (isLinkExternal(url, hostname)) {
|
|
9
10
|
linkProps = Object.assign(Object.assign({}, linkProps), exports.EXTERNAL_LINK_PROPS);
|
|
10
11
|
}
|
|
11
12
|
return linkProps;
|
|
12
13
|
}
|
|
13
14
|
exports.getLinkProps = getLinkProps;
|
|
15
|
+
function isAbsoluteUrl(url) {
|
|
16
|
+
// Using example URL as base for relative links
|
|
17
|
+
const urlObj = new URL(url, EXAMPLE_URL);
|
|
18
|
+
return (
|
|
19
|
+
// Compare url origin with example and check that original url was not example one
|
|
20
|
+
urlObj.origin !== EXAMPLE_URL || (typeof url === 'string' && url.startsWith(EXAMPLE_URL)));
|
|
21
|
+
}
|
|
22
|
+
exports.isAbsoluteUrl = isAbsoluteUrl;
|
|
14
23
|
function isLinkExternal(url, routerHostname) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
const { hostname } = (0, url_1.parse)(url);
|
|
19
|
-
if (!hostname) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
return getNonLocaleHostName(hostname) !== getNonLocaleHostName(routerHostname);
|
|
24
|
+
return (isAbsoluteUrl(url) &&
|
|
25
|
+
getNonLocaleHostName(new URL(url).hostname) !== getNonLocaleHostName(routerHostname !== null && routerHostname !== void 0 ? routerHostname : ''));
|
|
23
26
|
}
|
|
24
27
|
exports.isLinkExternal = isLinkExternal;
|
|
25
28
|
function getNonLocaleHostName(hostname) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const url_1 = require("./url");
|
|
4
|
+
describe('URL utils check', () => {
|
|
5
|
+
test.each([
|
|
6
|
+
['https://user:pass@sub.example.com:8080/p/a/t/h?query=string&query2=1#hash', true],
|
|
7
|
+
['http://example.net/path', true],
|
|
8
|
+
['/p/a/t/h?query=string&query2=1#hash', false],
|
|
9
|
+
['/path', false],
|
|
10
|
+
['path', false],
|
|
11
|
+
])("isAbsoluteUrl('%s') should return '%s'", (url, result) => {
|
|
12
|
+
expect((0, url_1.isAbsoluteUrl)(url)).toEqual(result);
|
|
13
|
+
});
|
|
14
|
+
test.each([
|
|
15
|
+
[
|
|
16
|
+
'https://user:pass@sub.example.com:8080/p/a/t/h?query=string&query2=1#hash',
|
|
17
|
+
'example.net',
|
|
18
|
+
true,
|
|
19
|
+
],
|
|
20
|
+
[
|
|
21
|
+
'https://user:pass@sub.example.com:8080/p/a/t/h?query=string&query2=1#hash',
|
|
22
|
+
'sub.example.com',
|
|
23
|
+
false,
|
|
24
|
+
],
|
|
25
|
+
[
|
|
26
|
+
'https://user:pass@sub.example.com:8080/p/a/t/h?query=string&query2=1#hash',
|
|
27
|
+
undefined,
|
|
28
|
+
true,
|
|
29
|
+
],
|
|
30
|
+
['http://example.net/path', 'example.net', false],
|
|
31
|
+
['http://example.net/path', 'sub.example.com', true],
|
|
32
|
+
['http://example.net/path', undefined, true],
|
|
33
|
+
['/p/a/t/h?query=string&query2=1#hash', 'example.net', false],
|
|
34
|
+
['/p/a/t/h?query=string&query2=1#hash', undefined, false],
|
|
35
|
+
['/path', 'example.net', false],
|
|
36
|
+
['/path', undefined, false],
|
|
37
|
+
['path', 'example.net', false],
|
|
38
|
+
['path', undefined, false],
|
|
39
|
+
])("isLinkExternal('%s', '%s') should return '%s'", (url, hostname, result) => {
|
|
40
|
+
expect((0, url_1.isLinkExternal)(url, hostname)).toEqual(result);
|
|
41
|
+
});
|
|
42
|
+
test.each([
|
|
43
|
+
['http://example.net/path', 'example.net', '_blank', { target: '_blank' }],
|
|
44
|
+
['http://example.net/path', 'example.net', undefined, {}],
|
|
45
|
+
[
|
|
46
|
+
'http://example.net/path',
|
|
47
|
+
'example.com',
|
|
48
|
+
'_blank',
|
|
49
|
+
{ target: '_blank', rel: 'noopener noreferrer' },
|
|
50
|
+
],
|
|
51
|
+
[
|
|
52
|
+
'http://example.net/path',
|
|
53
|
+
'example.com',
|
|
54
|
+
undefined,
|
|
55
|
+
{ target: '_blank', rel: 'noopener noreferrer' },
|
|
56
|
+
],
|
|
57
|
+
[
|
|
58
|
+
'http://example.net/path',
|
|
59
|
+
undefined,
|
|
60
|
+
'_blank',
|
|
61
|
+
{ target: '_blank', rel: 'noopener noreferrer' },
|
|
62
|
+
],
|
|
63
|
+
[
|
|
64
|
+
'http://example.net/path',
|
|
65
|
+
undefined,
|
|
66
|
+
undefined,
|
|
67
|
+
{ target: '_blank', rel: 'noopener noreferrer' },
|
|
68
|
+
],
|
|
69
|
+
['/path', 'example.net', '_blank', { target: '_blank' }],
|
|
70
|
+
['/path', 'example.net', undefined, {}],
|
|
71
|
+
['/path', undefined, '_blank', { target: '_blank' }],
|
|
72
|
+
['/path', undefined, undefined, {}],
|
|
73
|
+
])("getLinkProps('%s', '%s', '%s') should return '%s'", (url, hostname, target, result) => {
|
|
74
|
+
expect((0, url_1.getLinkProps)(url, hostname, target)).toEqual(result);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import BackLink from '../BackLink';
|
|
5
|
+
import { LocationContext } from '../../../context/locationContext';
|
|
6
|
+
const backLinkProps = {
|
|
7
|
+
url: '#',
|
|
8
|
+
title: 'Button Title',
|
|
9
|
+
theme: 'default',
|
|
10
|
+
size: 's',
|
|
11
|
+
className: 'customClassName',
|
|
12
|
+
shouldHandleBackAction: true,
|
|
13
|
+
onClick: () => { },
|
|
14
|
+
};
|
|
15
|
+
describe('BackLink', () => {
|
|
16
|
+
test('Default render', async () => {
|
|
17
|
+
render(React.createElement(BackLink, Object.assign({}, backLinkProps)));
|
|
18
|
+
const backLink = screen.getByRole('button');
|
|
19
|
+
expect(backLink).toBeInTheDocument();
|
|
20
|
+
});
|
|
21
|
+
test('Has custom class', async () => {
|
|
22
|
+
render(React.createElement(BackLink, Object.assign({}, backLinkProps)));
|
|
23
|
+
const backLink = screen.getByRole('button');
|
|
24
|
+
expect(backLink).toHaveClass(backLinkProps.className);
|
|
25
|
+
});
|
|
26
|
+
test('Should render <a /> tag', async () => {
|
|
27
|
+
render(React.createElement(BackLink, Object.assign({}, backLinkProps, { shouldHandleBackAction: false })));
|
|
28
|
+
const backLink = screen.getByRole('link');
|
|
29
|
+
expect(backLink).toBeVisible();
|
|
30
|
+
expect(backLink).toHaveAttribute('href', backLinkProps.url);
|
|
31
|
+
});
|
|
32
|
+
test('Should render title', async () => {
|
|
33
|
+
render(React.createElement(BackLink, Object.assign({}, backLinkProps)));
|
|
34
|
+
const backLink = screen.getByText(backLinkProps.title);
|
|
35
|
+
expect(backLink).toBeInTheDocument();
|
|
36
|
+
});
|
|
37
|
+
test('Call onClick', async () => {
|
|
38
|
+
const user = userEvent.setup();
|
|
39
|
+
const handleClick = jest.fn();
|
|
40
|
+
render(React.createElement(LocationContext.Provider, { value: { history: { push: jest.fn() } } },
|
|
41
|
+
React.createElement(BackLink, Object.assign({}, backLinkProps, { onClick: handleClick }))));
|
|
42
|
+
const backLink = screen.getByRole('button');
|
|
43
|
+
await user.click(backLink);
|
|
44
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
45
|
+
});
|
|
46
|
+
test.each(new Array('s', 'm', 'l', 'xl'))('Render with given "%s" size', (size) => {
|
|
47
|
+
render(React.createElement(BackLink, Object.assign({}, backLinkProps, { size: size })));
|
|
48
|
+
const backLink = screen.getByRole('button');
|
|
49
|
+
expect(backLink).toHaveClass(`yc-button_size_${size}`);
|
|
50
|
+
});
|
|
51
|
+
test.each(new Array('default', 'special'))('Render with given "%s" theme', (theme) => {
|
|
52
|
+
const matchView = {
|
|
53
|
+
default: 'flat-secondary',
|
|
54
|
+
special: 'flat-contrast',
|
|
55
|
+
};
|
|
56
|
+
render(React.createElement(BackLink, Object.assign({}, backLinkProps, { theme: theme })));
|
|
57
|
+
const backLink = screen.getByRole('button');
|
|
58
|
+
expect(backLink).toHaveClass(`yc-button_view_${matchView[theme]}`);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
.pc-overflow-scroller {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
2
4
|
position: relative;
|
|
3
5
|
overflow-x: hidden;
|
|
4
6
|
}
|
|
7
|
+
.pc-overflow-scroller__container {
|
|
8
|
+
width: 100%;
|
|
9
|
+
position: relative;
|
|
10
|
+
}
|
|
11
|
+
.pc-overflow-scroller__container_padding-left {
|
|
12
|
+
padding-left: 24px;
|
|
13
|
+
}
|
|
14
|
+
.pc-overflow-scroller__container_padding-right {
|
|
15
|
+
padding-right: 24px;
|
|
16
|
+
}
|
|
5
17
|
.pc-overflow-scroller__wrapper {
|
|
6
18
|
position: relative;
|
|
7
|
-
transition: left 0.
|
|
19
|
+
transition: left 0.6s;
|
|
8
20
|
}
|
|
9
|
-
.pc-overflow-
|
|
21
|
+
.pc-overflow-scroller__arrow {
|
|
10
22
|
position: absolute;
|
|
11
23
|
z-index: 10;
|
|
12
24
|
top: 0;
|
|
@@ -17,12 +29,11 @@
|
|
|
17
29
|
height: calc(100% - 1px);
|
|
18
30
|
cursor: pointer;
|
|
19
31
|
color: var(--yc-color-text-secondary);
|
|
20
|
-
background: linear-gradient(to left, var(--yc-color-base-background) 70%, var(--pc-transparent) 100%) no-repeat;
|
|
21
32
|
}
|
|
22
|
-
.pc-overflow-
|
|
33
|
+
.pc-overflow-scroller__arrow_type_left {
|
|
23
34
|
left: 0;
|
|
24
35
|
transform: rotate(180deg);
|
|
25
36
|
}
|
|
26
|
-
.pc-overflow-
|
|
37
|
+
.pc-overflow-scroller__arrow_type_right {
|
|
27
38
|
right: 0;
|
|
28
39
|
}
|
|
@@ -12,7 +12,7 @@ export interface OverflowScrollerState {
|
|
|
12
12
|
}
|
|
13
13
|
export default class OverflowScroller extends React.Component<PropsWithChildren<OverflowScrollerProps>, OverflowScrollerState> {
|
|
14
14
|
state: {
|
|
15
|
-
arrows:
|
|
15
|
+
arrows: Arrow[];
|
|
16
16
|
scrollValue: number;
|
|
17
17
|
};
|
|
18
18
|
containerRef: React.RefObject<HTMLDivElement>;
|
|
@@ -5,6 +5,7 @@ import { ToggleArrow } from '..';
|
|
|
5
5
|
import './OverflowScroller.css';
|
|
6
6
|
const b = block('overflow-scroller');
|
|
7
7
|
const TRANSITION_TIME = 300;
|
|
8
|
+
const PADDING_SIZE = 24;
|
|
8
9
|
export default class OverflowScroller extends React.Component {
|
|
9
10
|
constructor() {
|
|
10
11
|
super(...arguments);
|
|
@@ -28,7 +29,7 @@ export default class OverflowScroller extends React.Component {
|
|
|
28
29
|
}
|
|
29
30
|
}, 100);
|
|
30
31
|
this.handleScrollClick = (e, arrow) => {
|
|
31
|
-
const { scrollValue } = this.state;
|
|
32
|
+
const { scrollValue, arrows } = this.state;
|
|
32
33
|
const { onScrollStart } = this.props;
|
|
33
34
|
if (this.containerRef &&
|
|
34
35
|
this.containerRef.current &&
|
|
@@ -37,8 +38,9 @@ export default class OverflowScroller extends React.Component {
|
|
|
37
38
|
const containerWidth = this.containerRef.current.offsetWidth;
|
|
38
39
|
const wrapperWidth = this.wrapperRef.current.offsetWidth;
|
|
39
40
|
const hiddenWidth = arrow === 'right' ? wrapperWidth - (containerWidth + scrollValue) : scrollValue;
|
|
41
|
+
const padding = arrows.length > 1 && hiddenWidth + PADDING_SIZE > containerWidth ? PADDING_SIZE : 0;
|
|
40
42
|
const delta = containerWidth > hiddenWidth ? hiddenWidth : containerWidth;
|
|
41
|
-
const newScrollValue = arrow === 'right' ? scrollValue + delta : scrollValue - delta;
|
|
43
|
+
const newScrollValue = arrow === 'right' ? scrollValue + delta + padding : scrollValue - delta - padding;
|
|
42
44
|
let newArrows = ['left', 'right'];
|
|
43
45
|
if (newScrollValue + containerWidth >= wrapperWidth) {
|
|
44
46
|
newArrows = ['left'];
|
|
@@ -71,9 +73,15 @@ export default class OverflowScroller extends React.Component {
|
|
|
71
73
|
const { className, children } = this.props;
|
|
72
74
|
const { arrows, scrollValue } = this.state;
|
|
73
75
|
const wrapperStyle = arrows.length ? { left: -scrollValue } : { left: 0 };
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
const paddingLeft = arrows.includes('left');
|
|
77
|
+
const paddingRight = arrows.includes('right');
|
|
78
|
+
return (React.createElement("div", { className: b('container', {
|
|
79
|
+
'padding-left': paddingLeft,
|
|
80
|
+
'padding-right': paddingRight,
|
|
81
|
+
}) },
|
|
82
|
+
React.createElement("div", { className: b(null, className), ref: this.containerRef },
|
|
83
|
+
React.createElement("div", { className: b('wrapper'), style: wrapperStyle, ref: this.wrapperRef }, children)),
|
|
84
|
+
arrows.map((direction) => (React.createElement("div", { key: direction, className: b('arrow', { type: direction }), onClick: (e) => this.handleScrollClick(e, direction) },
|
|
77
85
|
React.createElement(ToggleArrow, { size: 18, type: 'horizontal', iconType: "navigation" }))))));
|
|
78
86
|
}
|
|
79
87
|
}
|
|
@@ -106,6 +106,7 @@ export interface BackgroundCardProps extends CardBaseProps, Omit<ContentBlockPro
|
|
|
106
106
|
export interface BasicCardProps extends CardBaseProps, Omit<ContentBlockProps, 'colSizes' | 'centered' | 'size' | 'theme'> {
|
|
107
107
|
url: string;
|
|
108
108
|
icon?: ImageProps;
|
|
109
|
+
target?: string;
|
|
109
110
|
}
|
|
110
111
|
export interface BannerCardProps {
|
|
111
112
|
title: string;
|
|
@@ -4,13 +4,19 @@ export declare enum NavigationItemType {
|
|
|
4
4
|
Link = "link",
|
|
5
5
|
Dropdown = "dropdown",
|
|
6
6
|
Button = "button",
|
|
7
|
-
Social = "social"
|
|
7
|
+
Social = "social",
|
|
8
|
+
GithubStars = "github-stars"
|
|
8
9
|
}
|
|
9
10
|
export interface NavigationItemBase {
|
|
10
11
|
text: string;
|
|
11
12
|
icon?: ImageProps;
|
|
12
13
|
url?: string;
|
|
13
14
|
}
|
|
15
|
+
export interface NavigationGithubButton extends Omit<NavigationItemBase, 'icon'> {
|
|
16
|
+
type: NavigationItemType.GithubStars;
|
|
17
|
+
url: string;
|
|
18
|
+
label?: string;
|
|
19
|
+
}
|
|
14
20
|
export interface NavigationLinkItem extends Omit<NavigationItemBase, 'url'> {
|
|
15
21
|
type: NavigationItemType.Link;
|
|
16
22
|
url: string;
|
|
@@ -29,8 +35,8 @@ export interface NavigationSocialItem extends Omit<NavigationItemBase, 'text'> {
|
|
|
29
35
|
icon: ImageProps;
|
|
30
36
|
url: string;
|
|
31
37
|
}
|
|
32
|
-
export type NavigationItemModel = NavigationLinkItem | NavigationButtonItem | NavigationDropdownItem;
|
|
33
|
-
export type NavigationItemData = NavigationLinkItem | NavigationButtonItem | NavigationSocialItem | DropdownItemData;
|
|
38
|
+
export type NavigationItemModel = NavigationLinkItem | NavigationButtonItem | NavigationDropdownItem | NavigationGithubButton;
|
|
39
|
+
export type NavigationItemData = NavigationLinkItem | NavigationButtonItem | NavigationSocialItem | DropdownItemData | NavigationGithubButton;
|
|
34
40
|
export type DropdownItemData = Omit<NavigationDropdownItem, 'items'>;
|
|
35
41
|
export interface NavigationLogoData {
|
|
36
42
|
icon: ImageProps;
|
|
@@ -29,7 +29,6 @@ unpredictable css rules order in build */
|
|
|
29
29
|
}
|
|
30
30
|
.pc-header__navigation.pc-header__navigation {
|
|
31
31
|
position: relative;
|
|
32
|
-
margin-right: 20px;
|
|
33
32
|
flex: 1 0 0;
|
|
34
33
|
justify-content: flex-start;
|
|
35
34
|
}
|
|
@@ -49,10 +48,11 @@ unpredictable css rules order in build */
|
|
|
49
48
|
flex: 1 0 0;
|
|
50
49
|
justify-content: space-between;
|
|
51
50
|
align-items: center;
|
|
52
|
-
margin-right:
|
|
51
|
+
margin-right: 32px;
|
|
53
52
|
}
|
|
54
53
|
.pc-header__buttons {
|
|
55
54
|
display: flex;
|
|
55
|
+
align-items: center;
|
|
56
56
|
}
|
|
57
57
|
@media (max-width: 768px) {
|
|
58
58
|
.pc-header__buttons {
|
|
@@ -44,7 +44,7 @@ export const Header = ({ data, logo }) => {
|
|
|
44
44
|
React.createElement(Navigation, { className: b('navigation'), links: leftItems, activeItemIndex: activeItemIndex, onActiveItemChange: onActiveItemChange })),
|
|
45
45
|
React.createElement("div", { className: b('right') },
|
|
46
46
|
React.createElement(MobileMenuButton, { isSidebarOpened: isSidebarOpened, onSidebarOpenedChange: onSidebarOpenedChange }),
|
|
47
|
-
rightItems && (React.createElement("div", { className: b('buttons') }, rightItems.map((button) => (React.createElement(NavigationItem, { key: button.text, data: button
|
|
47
|
+
rightItems && (React.createElement("div", { className: b('buttons') }, rightItems.map((button) => (React.createElement(NavigationItem, { key: button.text, data: button })))))),
|
|
48
48
|
React.createElement(OutsideClick, { onOutsideClick: () => onSidebarOpenedChange(false) },
|
|
49
49
|
React.createElement(MobileNavigation, { topItems: leftItems, bottomItems: rightItems, isOpened: isSidebarOpened, activeItemIndex: activeItemIndex, onActiveItemChange: onActiveItemChange, onClose: hideSidebar })))))));
|
|
50
50
|
};
|
|
@@ -1,41 +1,6 @@
|
|
|
1
|
-
/* use this for style redefinitions to awoid problems with
|
|
2
|
-
unpredictable css rules order in build */
|
|
3
1
|
.pc-navigation-item {
|
|
4
2
|
position: relative;
|
|
5
3
|
display: flex;
|
|
6
4
|
align-items: center;
|
|
7
5
|
white-space: nowrap;
|
|
8
|
-
}
|
|
9
|
-
.pc-navigation-item_type_link {
|
|
10
|
-
color: var(--yc-color-text-primary);
|
|
11
|
-
color: inherit;
|
|
12
|
-
text-decoration: none;
|
|
13
|
-
outline: none;
|
|
14
|
-
}
|
|
15
|
-
.utilityfocus .pc-navigation-item_type_link:focus {
|
|
16
|
-
outline: 2px solid #ffdb4d;
|
|
17
|
-
}
|
|
18
|
-
.pc-navigation-item_type_link:hover, .pc-navigation-item_type_link_active {
|
|
19
|
-
color: var(--yc-color-text-link);
|
|
20
|
-
}
|
|
21
|
-
.pc-navigation-item_type_button {
|
|
22
|
-
display: inline-block;
|
|
23
|
-
}
|
|
24
|
-
.pc-navigation-item__arrow {
|
|
25
|
-
position: relative;
|
|
26
|
-
top: -2px;
|
|
27
|
-
width: 9px;
|
|
28
|
-
height: 9px;
|
|
29
|
-
margin-left: 5px;
|
|
30
|
-
}
|
|
31
|
-
.pc-navigation-item__icon {
|
|
32
|
-
display: flex;
|
|
33
|
-
width: 20px;
|
|
34
|
-
height: 20px;
|
|
35
|
-
margin-right: 8px;
|
|
36
|
-
object-fit: cover;
|
|
37
|
-
}
|
|
38
|
-
.pc-navigation-item__dropdown {
|
|
39
|
-
margin-left: 7px;
|
|
40
|
-
color: var(--yc-color-text-secondary);
|
|
41
6
|
}
|
|
@@ -1,45 +1,14 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
|
-
import React, {
|
|
3
|
-
import { block
|
|
4
|
-
import {
|
|
5
|
-
import { LocationContext } from '../../../context/locationContext';
|
|
6
|
-
import { NavigationItemType, } from '../../../models';
|
|
7
|
-
import { NavigationArrow } from '../../../icons';
|
|
2
|
+
import React, { useMemo } from 'react';
|
|
3
|
+
import { block } from '../../../utils';
|
|
4
|
+
import { NavigationItemType } from '../../../models';
|
|
8
5
|
import SocialIcon from '../SocialIcon/SocialIcon';
|
|
9
|
-
import {
|
|
6
|
+
import { NavigationButton } from './components/NavigationButton/NavigationButton';
|
|
7
|
+
import { NavigationDropdown } from './components/NavigationDropdown/NavigationDropdown';
|
|
8
|
+
import { NavigationLink } from './components/NavigationLink/NavigationLink';
|
|
9
|
+
import { GithubStars } from './components/GithubStars/GithubStars';
|
|
10
10
|
import './NavigationItem.css';
|
|
11
11
|
const b = block('navigation-item');
|
|
12
|
-
const Content = ({ text, icon }) => (React.createElement(Fragment, null,
|
|
13
|
-
icon && typeof icon !== 'string' && React.createElement(Image, Object.assign({ className: b('icon') }, icon)),
|
|
14
|
-
React.createElement("span", { className: b('text') }, text)));
|
|
15
|
-
const NavigationDropdown = (_a) => {
|
|
16
|
-
var { text, icon, isOpened } = _a, props = __rest(_a, ["text", "icon", "isOpened"]);
|
|
17
|
-
const iconData = icon && getMediaImage(icon);
|
|
18
|
-
return (React.createElement("span", Object.assign({}, props),
|
|
19
|
-
React.createElement(Content, { text: text, icon: iconData }),
|
|
20
|
-
React.createElement(ToggleArrow, { className: b('dropdown'), size: 12, type: 'vertical', iconType: "navigation", open: isOpened })));
|
|
21
|
-
};
|
|
22
|
-
const NavigationLink = (props) => {
|
|
23
|
-
const { hostname, Link } = useContext(LocationContext);
|
|
24
|
-
const { url, text, icon, arrow, target } = props, rest = __rest(props, ["url", "text", "icon", "arrow", "target"]);
|
|
25
|
-
const linkExtraProps = getLinkProps(url, hostname, target);
|
|
26
|
-
const iconData = icon && getMediaImage(icon);
|
|
27
|
-
const content = (React.createElement(Fragment, null,
|
|
28
|
-
React.createElement(Content, { text: text, icon: iconData }),
|
|
29
|
-
arrow && React.createElement(NavigationArrow, { className: b('arrow') })));
|
|
30
|
-
if ((linkExtraProps === null || linkExtraProps === void 0 ? void 0 : linkExtraProps.target) || !Link) {
|
|
31
|
-
return (React.createElement("a", Object.assign({ href: url, title: text }, rest, linkExtraProps), content));
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
return (React.createElement(RouterLink, { href: url, passHref: true },
|
|
35
|
-
React.createElement("a", Object.assign({}, rest), content)));
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
const NavigationButton = (props) => {
|
|
39
|
-
const { url, target } = props;
|
|
40
|
-
return target ? (React.createElement(Button, Object.assign({}, props, { url: url }))) : (React.createElement(RouterLink, { href: url },
|
|
41
|
-
React.createElement(Button, Object.assign({}, props, { url: url }))));
|
|
42
|
-
};
|
|
43
12
|
//todo: add types support form component in map
|
|
44
13
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
14
|
const NavigationItemsMap = {
|
|
@@ -47,12 +16,13 @@ const NavigationItemsMap = {
|
|
|
47
16
|
[NavigationItemType.Social]: SocialIcon,
|
|
48
17
|
[NavigationItemType.Dropdown]: NavigationDropdown,
|
|
49
18
|
[NavigationItemType.Link]: NavigationLink,
|
|
19
|
+
[NavigationItemType.GithubStars]: GithubStars,
|
|
50
20
|
};
|
|
51
21
|
const NavigationItem = (_a) => {
|
|
52
22
|
var { data, className } = _a, props = __rest(_a, ["data", "className"]);
|
|
53
23
|
const { type = NavigationItemType.Link } = data;
|
|
54
24
|
const Component = NavigationItemsMap[type];
|
|
55
|
-
const componentProps = useMemo(() => (Object.assign(Object.assign({ className: b(
|
|
25
|
+
const componentProps = useMemo(() => (Object.assign(Object.assign({ className: b(null, className) }, data), props)), [className, data, props]);
|
|
56
26
|
return React.createElement(Component, Object.assign({}, componentProps));
|
|
57
27
|
};
|
|
58
28
|
export default NavigationItem;
|
package/build/esm/navigation/components/NavigationItem/components/ContentWrapper/ContentWrapper.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React, { Fragment } from 'react';
|
|
2
|
+
import { block } from '../../../../../utils';
|
|
3
|
+
import { Image } from '../../../../../components';
|
|
4
|
+
import './ContentWrapper.css';
|
|
5
|
+
const b = block('content-wrapper');
|
|
6
|
+
export const ContentWrapper = ({ text, icon }) => (React.createElement(Fragment, null,
|
|
7
|
+
icon && typeof icon !== 'string' && React.createElement(Image, Object.assign({ className: b('icon') }, icon)),
|
|
8
|
+
React.createElement("span", { className: b('text') }, text)));
|
package/build/esm/navigation/components/NavigationItem/components/GithubStars/GithubStars.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NavigationItemProps } from '../../NavigationItem';
|
|
2
|
+
import { NavigationGithubButton } from '../../../../../models';
|
|
3
|
+
import './GithubStars.css';
|
|
4
|
+
type NavigationGithubButtonProps = NavigationItemProps & NavigationGithubButton;
|
|
5
|
+
export declare const GithubStars: ({ text, url, className, label }: NavigationGithubButtonProps) => JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import GitHubButton from 'react-github-btn';
|
|
3
|
+
import { block } from '../../../../../utils';
|
|
4
|
+
import './GithubStars.css';
|
|
5
|
+
const b = block('github-stars');
|
|
6
|
+
export const GithubStars = ({ text, url, className, label }) => (React.createElement("div", { className: b(null, className) },
|
|
7
|
+
React.createElement(GitHubButton, { href: url, "data-show-count": "true", "aria-label": label || 'Stars on GitHub' }, text)));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ButtonProps } from '../../../../../models';
|
|
3
|
+
import { NavigationItemProps } from '../../NavigationItem';
|
|
4
|
+
import './NavigationButton.css';
|
|
5
|
+
type NavigationButtonProps = Pick<NavigationItemProps, 'className'> & ButtonProps;
|
|
6
|
+
export declare const NavigationButton: React.FC<NavigationButtonProps>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { block } from '../../../../../utils';
|
|
3
|
+
import { RouterLink, Button } from '../../../../../components';
|
|
4
|
+
import './NavigationButton.css';
|
|
5
|
+
const b = block('navigation-button');
|
|
6
|
+
export const NavigationButton = (props) => {
|
|
7
|
+
const { url, target, className } = props;
|
|
8
|
+
const classes = b(null, className);
|
|
9
|
+
return target ? (React.createElement(Button, Object.assign({ className: classes }, props, { url: url }))) : (React.createElement(RouterLink, { href: url },
|
|
10
|
+
React.createElement(Button, Object.assign({}, props, { className: classes, url: url }))));
|
|
11
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { NavigationItemProps } from '../../NavigationItem';
|
|
3
|
+
import { DropdownItemData } from '../../../../../models';
|
|
4
|
+
import './NavigationDropdown.css';
|
|
5
|
+
type NavigationDropdownProps = NavigationItemProps & DropdownItemData;
|
|
6
|
+
export declare const NavigationDropdown: React.FC<NavigationDropdownProps>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { __rest } from "tslib";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { ContentWrapper } from '../ContentWrapper/ContentWrapper';
|
|
4
|
+
import { ToggleArrow } from '../../../../../components';
|
|
5
|
+
import { block } from '../../../../../utils';
|
|
6
|
+
import { getMediaImage } from '../../../../../components/Media/Image/utils';
|
|
7
|
+
import './NavigationDropdown.css';
|
|
8
|
+
const b = block('navigation-dropdown');
|
|
9
|
+
const TOGGLE_ARROW_SIZE = 12;
|
|
10
|
+
export const NavigationDropdown = (_a) => {
|
|
11
|
+
var { text, icon, isOpened } = _a, props = __rest(_a, ["text", "icon", "isOpened"]);
|
|
12
|
+
const iconData = icon && getMediaImage(icon);
|
|
13
|
+
return (React.createElement("span", Object.assign({}, props),
|
|
14
|
+
React.createElement(ContentWrapper, { text: text, icon: iconData }),
|
|
15
|
+
React.createElement(ToggleArrow, { className: b(), size: TOGGLE_ARROW_SIZE, type: 'vertical', iconType: "navigation", open: isOpened })));
|
|
16
|
+
};
|
package/build/esm/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.css
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* use this for style redefinitions to awoid problems with
|
|
2
|
+
unpredictable css rules order in build */
|
|
3
|
+
.pc-navigation-link {
|
|
4
|
+
color: var(--yc-color-text-primary);
|
|
5
|
+
color: inherit;
|
|
6
|
+
text-decoration: none;
|
|
7
|
+
outline: none;
|
|
8
|
+
}
|
|
9
|
+
.utilityfocus .pc-navigation-link:focus {
|
|
10
|
+
outline: 2px solid #ffdb4d;
|
|
11
|
+
}
|
|
12
|
+
.pc-navigation-link:hover, .pc-navigation-link_active {
|
|
13
|
+
color: var(--yc-color-text-link);
|
|
14
|
+
}
|
|
15
|
+
.pc-navigation-link__arrow {
|
|
16
|
+
position: relative;
|
|
17
|
+
top: -2px;
|
|
18
|
+
width: 9px;
|
|
19
|
+
height: 9px;
|
|
20
|
+
margin-left: 5px;
|
|
21
|
+
}
|
package/build/esm/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { NavigationItemProps } from '../../NavigationItem';
|
|
3
|
+
import { NavigationLinkItem } from '../../../../../models';
|
|
4
|
+
import './NavigationLink.css';
|
|
5
|
+
type NavigationLinkProps = NavigationItemProps & NavigationLinkItem;
|
|
6
|
+
export declare const NavigationLink: React.FC<NavigationLinkProps>;
|
|
7
|
+
export {};
|