@orangesk/orange-design-system 2.0.0-beta.6 → 2.0.0-beta.8
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/build/components/index.js +4 -4
- package/build/components/index.js.map +1 -1
- package/build/components/tsconfig.tsbuildinfo +1 -1
- package/build/components/types/index.d.ts +24 -5
- package/build/components/types/src/components/AnchorNavigation/AnchorNavigation.d.ts +1 -1
- package/build/components/types/src/components/AnchorNavigation/AnchorNavigation.static.d.ts +19 -17
- package/build/components/types/src/components/Card/Card.d.ts +1 -1
- package/build/components/types/src/components/Expander/Expander.d.ts +2 -2
- package/build/components/types/src/components/Megamenu/constants.d.ts +2 -0
- package/build/components/types/src/components/Pill/Pill.d.ts +4 -1
- package/build/components/types/src/components/index.d.ts +2 -1
- package/build/components/types/src/scripts/index.d.ts +5 -0
- package/build/lib/after-components.css +1 -1
- package/build/lib/after-components.css.map +1 -1
- package/build/lib/before-components.css +1 -1
- package/build/lib/before-components.css.map +1 -1
- package/build/lib/components.css +1 -1
- package/build/lib/components.css.map +1 -1
- package/build/lib/megamenu.css +1 -1
- package/build/lib/megamenu.css.map +1 -1
- package/build/lib/megamenu.js +1 -1
- package/build/lib/megamenu.js.map +1 -1
- package/build/lib/scripts.js +4 -4
- package/build/lib/scripts.js.map +1 -1
- package/build/lib/style.css +1 -1
- package/build/lib/style.css.map +1 -1
- package/build/lib/tsconfig.tsbuildinfo +1 -1
- package/build/sprite.svg +1 -1
- package/package.json +13 -13
- package/src/assets/icons/article.svg +4 -4
- package/src/components/Accordion/styles/config.scss +4 -4
- package/src/components/Accordion/styles/mixins.scss +2 -2
- package/src/components/AnchorNavigation/AnchorNavigation.static.ts +253 -73
- package/src/components/AnchorNavigation/AnchorNavigation.tsx +20 -16
- package/src/components/AnchorNavigation/styles/mixins.scss +14 -27
- package/src/components/AnchorNavigation/tests/AnchorNavigation.conformance.test.js +67 -0
- package/src/components/AnchorNavigation/tests/AnchorNavigation.unit.test.js +163 -0
- package/src/components/BlockAction/styles/mixins.scss +0 -6
- package/src/components/Card/Card.tsx +1 -0
- package/src/components/Card/styles/config.scss +1 -1
- package/src/components/Expander/Expander.tsx +4 -2
- package/src/components/Expander/styles/style.scss +7 -0
- package/src/components/Link/styles/style.scss +1 -1
- package/src/components/Link/tests/Link.conformance.test.js +5 -20
- package/src/components/Link/tests/Link.unit.test.js +1 -10
- package/src/components/Megamenu/Megamenu.static.ts +2 -0
- package/src/components/Megamenu/Megamenu.tsx +671 -665
- package/src/components/Megamenu/MegamenuBlog.tsx +187 -183
- package/src/components/Megamenu/constants.ts +2 -0
- package/src/components/Megamenu/styles/mixins.scss +30 -1
- package/src/components/Megamenu/styles/style.scss +8 -0
- package/src/components/Pill/Pill.tsx +8 -3
- package/src/components/Pill/styles/config.scss +18 -2
- package/src/components/Pill/styles/style.scss +7 -3
- package/src/components/Pill/tests/Pill.conformance.test.js +7 -3
- package/src/components/Pill/tests/Pill.unit.test.js +45 -7
- package/src/components/index.ts +2 -0
- package/src/styles/base/globals.scss +18 -0
- package/src/styles/utilities/color.scss +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orangesk/orange-design-system",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.8",
|
|
4
4
|
"private": false,
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.x"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@cloudfour/transition-hidden-element": "^2.0.2",
|
|
35
35
|
"@mdx-js/loader": "^3.1.1",
|
|
36
36
|
"@mdx-js/react": "^3.1.1",
|
|
37
|
-
"@next/mdx": "^15.5.
|
|
37
|
+
"@next/mdx": "^15.5.4",
|
|
38
38
|
"@orangesk/accessible-autocomplete": "^3.1.2",
|
|
39
39
|
"@popperjs/core": "^2.11.8",
|
|
40
40
|
"@types/mdx": "^2.0.13",
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"diff2html": "^3.4.52",
|
|
45
45
|
"dompurify": "^3.2.7",
|
|
46
46
|
"html-react-parser": "^5.2.6",
|
|
47
|
-
"jest-environment-jsdom": "^30.
|
|
47
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
48
48
|
"lorem-ipsum": "^2.0.8",
|
|
49
|
-
"next": "15.5.
|
|
49
|
+
"next": "15.5.4",
|
|
50
50
|
"normalize.css": "^8.0.1",
|
|
51
51
|
"nouislider": "^15.8.1",
|
|
52
52
|
"pretty": "^2.0.0",
|
|
@@ -78,17 +78,17 @@
|
|
|
78
78
|
"@rollup/plugin-typescript": "^12.1.4",
|
|
79
79
|
"@rollup/plugin-url": "^8.0.2",
|
|
80
80
|
"@testing-library/dom": "^10.4.1",
|
|
81
|
-
"@testing-library/jest-dom": "^6.
|
|
81
|
+
"@testing-library/jest-dom": "^6.9.0",
|
|
82
82
|
"@testing-library/react": "^16.3.0",
|
|
83
83
|
"@testing-library/user-event": "^14.6.1",
|
|
84
|
-
"@types/node": "^24.
|
|
84
|
+
"@types/node": "^24.6.1",
|
|
85
85
|
"@types/pretty": "^2.0.3",
|
|
86
|
-
"@types/react": "19.1.
|
|
86
|
+
"@types/react": "19.1.16",
|
|
87
87
|
"@types/react-dom": "19.1.9",
|
|
88
88
|
"@types/wnumb": "^1.2.3",
|
|
89
|
-
"babel-jest": "30.
|
|
89
|
+
"babel-jest": "30.2.0",
|
|
90
90
|
"eslint": "latest",
|
|
91
|
-
"eslint-config-next": "^15.5.
|
|
91
|
+
"eslint-config-next": "^15.5.4",
|
|
92
92
|
"eslint-config-prettier": "^10.1.8",
|
|
93
93
|
"eslint-plugin-unused-imports": "^4.2.0",
|
|
94
94
|
"fs-extra": "^11.3.2",
|
|
@@ -96,16 +96,16 @@
|
|
|
96
96
|
"html-validate": "10.0.0",
|
|
97
97
|
"husky": "^9.1.7",
|
|
98
98
|
"identity-obj-proxy": "^3.0.0",
|
|
99
|
-
"jest": "30.
|
|
99
|
+
"jest": "30.2.0",
|
|
100
100
|
"jest-axe": "10.0.0",
|
|
101
|
-
"jest-snapshot": "^30.
|
|
102
|
-
"lint-staged": "16.2.
|
|
101
|
+
"jest-snapshot": "^30.2.0",
|
|
102
|
+
"lint-staged": "16.2.3",
|
|
103
103
|
"prettier": "^3.6.2",
|
|
104
104
|
"rollup-plugin-copy": "^3.5.0",
|
|
105
105
|
"rollup-plugin-dts": "^6.2.3",
|
|
106
106
|
"rollup-plugin-postcss": "^4.0.2",
|
|
107
107
|
"sass": "^1.93.2",
|
|
108
108
|
"svg-sprite": "^2.0.4",
|
|
109
|
-
"typescript": "5.9.
|
|
109
|
+
"typescript": "5.9.3"
|
|
110
110
|
}
|
|
111
111
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<svg width="80" height="80" viewBox="0 0 80 80" fill="none"
|
|
2
2
|
xmlns="http://www.w3.org/2000/svg">
|
|
3
|
-
<path d="M55.1469 22.6034C56.5877 22.6034 57.7543 23.7749 57.7543 25.2157C57.7537 26.6558 56.5872 27.8231 55.1469 27.8231L37.7543 27.8231C36.3146 27.8224 35.1476 26.6554 35.1469 25.2157C35.1469 23.7754 36.3142 22.6041 37.7543 22.6034L55.1469 22.6034Z" fill="
|
|
4
|
-
<path d="M55.1469 34.774C56.5877 34.774 57.7543 35.9456 57.7543 37.3863C57.7537 38.8265 56.5872 39.9937 55.1469 39.9937L37.7543 39.9937C36.3146 39.993 35.1476 38.826 35.1469 37.3863C35.1469 35.946 36.3142 34.7747 37.7543 34.774L55.1469 34.774Z" fill="
|
|
5
|
-
<path d="M55.1469 46.9497C56.5877 46.9497 57.7543 48.1212 57.7543 49.562C57.7537 51.0021 56.5872 52.1694 55.1469 52.1694H37.7543C36.3146 52.1687 35.1476 51.0017 35.1469 49.562C35.1469 48.1217 36.3142 46.9504 37.7543 46.9497L55.1469 46.9497Z" fill="
|
|
6
|
-
<path d="M69.9268 60.8679C69.9261 65.6699 66.0325 69.5642 61.2305 69.5642H15.3613C11.9101 69.5633 9.07156 66.9393 8.73047 63.5779L8.69629 62.8992V29.5349H22.9736V8.69507H69.9268V60.8679ZM28.1885 60.8679L28.1445 61.7566C28.0515 62.6713 27.8104 63.5408 27.4561 64.3494H61.2305C63.1511 64.3494 64.7113 62.7884 64.7119 60.8679V13.9148H28.1885V60.8679ZM14.2773 60.8679C14.2785 62.7875 15.8343 64.3437 17.7539 64.3445H19.4922C21.4125 64.3445 22.9676 62.788 22.9688 60.8679V34.7839H14.2773V60.8679Z" fill="
|
|
3
|
+
<path d="M55.1469 22.6034C56.5877 22.6034 57.7543 23.7749 57.7543 25.2157C57.7537 26.6558 56.5872 27.8231 55.1469 27.8231L37.7543 27.8231C36.3146 27.8224 35.1476 26.6554 35.1469 25.2157C35.1469 23.7754 36.3142 22.6041 37.7543 22.6034L55.1469 22.6034Z" fill="currentColor"/>
|
|
4
|
+
<path d="M55.1469 34.774C56.5877 34.774 57.7543 35.9456 57.7543 37.3863C57.7537 38.8265 56.5872 39.9937 55.1469 39.9937L37.7543 39.9937C36.3146 39.993 35.1476 38.826 35.1469 37.3863C35.1469 35.946 36.3142 34.7747 37.7543 34.774L55.1469 34.774Z" fill="currentColor"/>
|
|
5
|
+
<path d="M55.1469 46.9497C56.5877 46.9497 57.7543 48.1212 57.7543 49.562C57.7537 51.0021 56.5872 52.1694 55.1469 52.1694H37.7543C36.3146 52.1687 35.1476 51.0017 35.1469 49.562C35.1469 48.1217 36.3142 46.9504 37.7543 46.9497L55.1469 46.9497Z" fill="currentColor"/>
|
|
6
|
+
<path d="M69.9268 60.8679C69.9261 65.6699 66.0325 69.5642 61.2305 69.5642H15.3613C11.9101 69.5633 9.07156 66.9393 8.73047 63.5779L8.69629 62.8992V29.5349H22.9736V8.69507H69.9268V60.8679ZM28.1885 60.8679L28.1445 61.7566C28.0515 62.6713 27.8104 63.5408 27.4561 64.3494H61.2305C63.1511 64.3494 64.7113 62.7884 64.7119 60.8679V13.9148H28.1885V60.8679ZM14.2773 60.8679C14.2785 62.7875 15.8343 64.3437 17.7539 64.3445H19.4922C21.4125 64.3445 22.9676 62.788 22.9688 60.8679V34.7839H14.2773V60.8679Z" fill="currentColor"/>
|
|
7
7
|
</svg>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
@use
|
|
1
|
+
@use "../../../styles/tools/convert";
|
|
2
2
|
|
|
3
3
|
$spacing: (
|
|
4
|
-
default:
|
|
5
|
-
large:
|
|
4
|
+
default: convert.to-rem(15px) 0,
|
|
5
|
+
large: convert.to-rem(20px) 0,
|
|
6
6
|
);
|
|
7
7
|
|
|
8
|
-
$enclosed-spacing:
|
|
8
|
+
$enclosed-spacing: convert.to-rem(20px);
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
display: flex;
|
|
21
21
|
flex-direction: column;
|
|
22
22
|
justify-content: center;
|
|
23
|
-
border-
|
|
23
|
+
border-bottom: 1px solid var(--color-border-strong);
|
|
24
24
|
|
|
25
25
|
&:last-child {
|
|
26
|
-
border-bottom:
|
|
26
|
+
border-bottom: 0px;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
ul {
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
interface AnchorNavigationConfig {
|
|
2
|
-
itemSelector: string;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const defaultConfig: AnchorNavigationConfig = {
|
|
6
|
-
itemSelector: '.anchor-navigation__item',
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const configDocs = {
|
|
10
|
-
itemSelector: "Anchor navigation item element selector",
|
|
11
|
-
};
|
|
12
|
-
|
|
13
1
|
export default class AnchorNavigation {
|
|
14
2
|
private element: HTMLElement;
|
|
15
|
-
private
|
|
16
|
-
private
|
|
17
|
-
private
|
|
3
|
+
private megamenuElement: HTMLElement | null;
|
|
4
|
+
private resizeObserver: ResizeObserver | null;
|
|
5
|
+
private scrollHandler: () => void;
|
|
6
|
+
private scrollSpyHandler: () => void;
|
|
7
|
+
private scrollEndHandler: () => void;
|
|
8
|
+
private resizeHandler: () => void;
|
|
9
|
+
private isAutoScrolling: boolean = false;
|
|
10
|
+
private navLinks: NodeListOf<HTMLAnchorElement> | null = null;
|
|
11
|
+
private sections: HTMLElement[] = [];
|
|
12
|
+
private currentPath: string;
|
|
13
|
+
private lastActiveIndex: number = 0;
|
|
18
14
|
|
|
19
|
-
constructor(element: HTMLElement
|
|
15
|
+
constructor(element: HTMLElement) {
|
|
20
16
|
this.element = element;
|
|
21
|
-
this.config = { ...defaultConfig, ...config };
|
|
22
17
|
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
18
|
+
this.megamenuElement = null;
|
|
19
|
+
this.resizeObserver = null;
|
|
20
|
+
this.isAutoScrolling = false;
|
|
21
|
+
this.currentPath = window.location.pathname;
|
|
25
22
|
|
|
26
|
-
this.
|
|
23
|
+
this.scrollHandler = this.updateStickyPosition.bind(this);
|
|
24
|
+
this.scrollSpyHandler = this.handleScrollSpy.bind(this);
|
|
25
|
+
this.scrollEndHandler = this.handleScrollEnd.bind(this);
|
|
26
|
+
this.resizeHandler = this.initScrollSpy.bind(this);
|
|
27
27
|
|
|
28
28
|
(this.element as any).ODS_AnchorNavigation = this;
|
|
29
29
|
|
|
@@ -33,83 +33,263 @@ export default class AnchorNavigation {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
static getInstance(el: HTMLElement): AnchorNavigation | null {
|
|
36
|
-
return el && (el as any).ODS_AnchorNavigation
|
|
36
|
+
return el && (el as any).ODS_AnchorNavigation
|
|
37
|
+
? (el as any).ODS_AnchorNavigation
|
|
38
|
+
: null;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
private
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
);
|
|
41
|
+
private findMegamenuElement(): HTMLElement | null {
|
|
42
|
+
return document.querySelector("[data-megamenu]") as HTMLElement | null;
|
|
43
|
+
}
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
private updateStickyPosition(): void {
|
|
46
|
+
if (!this.megamenuElement) return;
|
|
47
|
+
this.element.style.top = `${this.megamenuElement.offsetHeight}px`;
|
|
48
|
+
}
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
});
|
|
50
|
+
private setupMegamenuObserver(): void {
|
|
51
|
+
this.megamenuElement = this.findMegamenuElement();
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
if (!this.megamenuElement) {
|
|
54
|
+
this.element.style.top = "0px";
|
|
55
|
+
return;
|
|
55
56
|
}
|
|
57
|
+
|
|
58
|
+
this.updateStickyPosition();
|
|
59
|
+
window.addEventListener("scroll", this.scrollHandler, { passive: true });
|
|
60
|
+
|
|
61
|
+
this.resizeObserver = new ResizeObserver(
|
|
62
|
+
this.updateStickyPosition.bind(this),
|
|
63
|
+
);
|
|
64
|
+
this.resizeObserver.observe(this.megamenuElement);
|
|
56
65
|
}
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
private setupScrollSpy(): void {
|
|
68
|
+
// Set dynamic scroll margin for CSS
|
|
69
|
+
document.documentElement.style.setProperty(
|
|
70
|
+
"--extra-scroll-margin",
|
|
71
|
+
this.element.offsetHeight + "px",
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Get all anchor navigation links
|
|
75
|
+
this.navLinks = this.element.querySelectorAll(".anchor-navigation__item");
|
|
76
|
+
|
|
77
|
+
// Get all sections that correspond to the navigation links
|
|
78
|
+
this.sections = Array.from(this.navLinks || [])
|
|
79
|
+
.map((link) => link.getAttribute("href"))
|
|
80
|
+
.filter((href) => href?.includes("#"))
|
|
81
|
+
.map((href) => document.getElementById(href!.split("#")[1]))
|
|
82
|
+
.filter(Boolean) as HTMLElement[];
|
|
83
|
+
|
|
84
|
+
// Add click listeners to anchor navigation items
|
|
85
|
+
this.navLinks.forEach((anchor) => {
|
|
86
|
+
anchor.addEventListener("click", (event) => {
|
|
87
|
+
event.preventDefault();
|
|
88
|
+
const href = anchor.getAttribute("href");
|
|
89
|
+
if (href && href.includes("#")) {
|
|
90
|
+
const targetId = href.split("#")[1];
|
|
91
|
+
const targetElement = document.getElementById(targetId);
|
|
92
|
+
|
|
93
|
+
if (targetElement) {
|
|
94
|
+
this.isAutoScrolling = true;
|
|
95
|
+
|
|
96
|
+
// Calculate scroll position
|
|
97
|
+
const scrollOffset = this.megamenuElement
|
|
98
|
+
? this.megamenuElement.offsetHeight
|
|
99
|
+
: 0;
|
|
100
|
+
const additionalOffset = this.element.offsetHeight;
|
|
101
|
+
const targetTop =
|
|
102
|
+
targetElement.offsetTop - scrollOffset - additionalOffset;
|
|
103
|
+
|
|
104
|
+
// Smooth scroll to target
|
|
105
|
+
window.scrollTo({
|
|
106
|
+
top: Math.max(0, targetTop),
|
|
107
|
+
behavior: "smooth",
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Update active state
|
|
111
|
+
this.initScrollSpy(targetId);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
61
115
|
});
|
|
62
116
|
|
|
63
|
-
|
|
64
|
-
(this.
|
|
65
|
-
}
|
|
117
|
+
// Add scroll listeners
|
|
118
|
+
window.addEventListener("scroll", this.scrollSpyHandler, { passive: true });
|
|
66
119
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
120
|
+
// Add scrollend listener with fallback
|
|
121
|
+
try {
|
|
122
|
+
window.addEventListener("scrollend", this.scrollEndHandler);
|
|
123
|
+
} catch {
|
|
124
|
+
// Fallback for browsers that don't support scrollend
|
|
125
|
+
let scrollTimeout: ReturnType<typeof setTimeout>;
|
|
126
|
+
const scrollEndFallback = () => {
|
|
127
|
+
clearTimeout(scrollTimeout);
|
|
128
|
+
scrollTimeout = setTimeout(() => {
|
|
129
|
+
this.handleScrollEnd();
|
|
130
|
+
}, 150);
|
|
131
|
+
};
|
|
132
|
+
window.addEventListener("scroll", scrollEndFallback, { passive: true });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
window.addEventListener("resize", this.resizeHandler);
|
|
136
|
+
|
|
137
|
+
this.initScrollSpy();
|
|
70
138
|
}
|
|
71
139
|
|
|
72
|
-
private
|
|
73
|
-
|
|
74
|
-
|
|
140
|
+
private initScrollSpy(forcedSectionId: string | null = null): void {
|
|
141
|
+
if (!this.navLinks || !this.sections.length) return;
|
|
142
|
+
|
|
143
|
+
let targetSection: HTMLElement | undefined;
|
|
144
|
+
let targetIndex: number = -1;
|
|
145
|
+
|
|
146
|
+
// Remove active class from all links
|
|
147
|
+
this.navLinks.forEach((link) => link.classList.remove("is-active"));
|
|
148
|
+
|
|
149
|
+
if (forcedSectionId) {
|
|
150
|
+
targetSection = document.getElementById(forcedSectionId) || undefined;
|
|
151
|
+
if (targetSection) {
|
|
152
|
+
// Find the index of the forced section
|
|
153
|
+
targetIndex = this.sections.findIndex(
|
|
154
|
+
(section) => section.id === forcedSectionId,
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
// Calculate scroll offset from megamenu height and anchor nav height
|
|
159
|
+
const scrollOffset = this.megamenuElement
|
|
160
|
+
? this.megamenuElement.offsetHeight
|
|
161
|
+
: 0;
|
|
162
|
+
const anchorNavOffset = this.element.offsetHeight;
|
|
163
|
+
const totalOffset = scrollOffset + anchorNavOffset;
|
|
164
|
+
const effectiveCenter = window.scrollY + totalOffset + 50; // Add some buffer
|
|
165
|
+
|
|
166
|
+
// Find the section that's currently in view
|
|
167
|
+
for (let i = 0; i < this.sections.length; i++) {
|
|
168
|
+
const section = this.sections[i];
|
|
169
|
+
const { top: sectionTopRaw, height: sectionHeight } =
|
|
170
|
+
section.getBoundingClientRect();
|
|
171
|
+
const sectionTop = sectionTopRaw + window.scrollY;
|
|
172
|
+
const sectionBottom = sectionTop + sectionHeight;
|
|
75
173
|
|
|
76
|
-
|
|
77
|
-
|
|
174
|
+
if (effectiveCenter >= sectionTop && effectiveCenter < sectionBottom) {
|
|
175
|
+
targetSection = section;
|
|
176
|
+
targetIndex = i;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
78
181
|
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
182
|
+
// Fallback logic: if no section is found, use fallback rules
|
|
183
|
+
if (!targetSection) {
|
|
184
|
+
// If we're at the very top, activate first item
|
|
185
|
+
if (window.scrollY <= 100) {
|
|
186
|
+
targetIndex = 0;
|
|
187
|
+
targetSection = this.sections[0];
|
|
188
|
+
} else {
|
|
189
|
+
// Keep the last active item
|
|
190
|
+
targetIndex = this.lastActiveIndex;
|
|
191
|
+
targetSection = this.sections[targetIndex];
|
|
192
|
+
}
|
|
84
193
|
}
|
|
85
|
-
}
|
|
86
194
|
|
|
87
|
-
|
|
88
|
-
|
|
195
|
+
// Update last active index if we found a valid target
|
|
196
|
+
if (targetIndex >= 0) {
|
|
197
|
+
this.lastActiveIndex = targetIndex;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (targetSection) {
|
|
201
|
+
const id = targetSection.getAttribute("id");
|
|
89
202
|
|
|
90
|
-
|
|
91
|
-
|
|
203
|
+
// Find the matching navigation link - try different href patterns
|
|
204
|
+
let activeLink = this.element.querySelector(
|
|
205
|
+
`.anchor-navigation__item[href="#${id}"]`,
|
|
206
|
+
) as HTMLElement;
|
|
207
|
+
|
|
208
|
+
if (!activeLink) {
|
|
209
|
+
activeLink = this.element.querySelector(
|
|
210
|
+
`.anchor-navigation__item[href="${this.currentPath}#${id}"]`,
|
|
211
|
+
) as HTMLElement;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (!activeLink) {
|
|
215
|
+
// Try without current path for relative links
|
|
216
|
+
activeLink = Array.from(this.navLinks).find((link) => {
|
|
217
|
+
const href = link.getAttribute("href");
|
|
218
|
+
return href && href.endsWith(`#${id}`);
|
|
219
|
+
}) as HTMLElement;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (activeLink) {
|
|
223
|
+
activeLink.classList.add("is-active");
|
|
224
|
+
|
|
225
|
+
// Smooth scroll the navigation to center the active link
|
|
226
|
+
const contentLeft = this.element.querySelector(
|
|
227
|
+
".anchor-navigation__content-left",
|
|
228
|
+
) as HTMLElement;
|
|
229
|
+
if (contentLeft) {
|
|
230
|
+
contentLeft.scrollTo({
|
|
231
|
+
left:
|
|
232
|
+
activeLink.offsetLeft -
|
|
233
|
+
this.element.clientWidth / 2 +
|
|
234
|
+
activeLink.clientWidth / 2,
|
|
235
|
+
behavior: "smooth",
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
92
239
|
}
|
|
240
|
+
}
|
|
93
241
|
|
|
94
|
-
|
|
95
|
-
|
|
242
|
+
private handleScrollSpy(): void {
|
|
243
|
+
if (!this.isAutoScrolling) {
|
|
244
|
+
this.initScrollSpy();
|
|
96
245
|
}
|
|
97
246
|
}
|
|
98
247
|
|
|
99
|
-
|
|
100
|
-
|
|
248
|
+
private handleScrollEnd(): void {
|
|
249
|
+
this.isAutoScrolling = false;
|
|
250
|
+
this.initScrollSpy();
|
|
251
|
+
}
|
|
101
252
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this.toggleItem(item, "on");
|
|
106
|
-
} else {
|
|
107
|
-
this.toggleItem(item, "off");
|
|
108
|
-
}
|
|
109
|
-
});
|
|
253
|
+
private init(): void {
|
|
254
|
+
this.setupMegamenuObserver();
|
|
255
|
+
this.setupScrollSpy();
|
|
110
256
|
}
|
|
111
257
|
|
|
112
|
-
|
|
113
|
-
|
|
258
|
+
destroy(): void {
|
|
259
|
+
window.removeEventListener("scroll", this.scrollHandler);
|
|
260
|
+
window.removeEventListener("scroll", this.scrollSpyHandler);
|
|
261
|
+
window.removeEventListener("scrollend", this.scrollEndHandler);
|
|
262
|
+
window.removeEventListener("resize", this.resizeHandler);
|
|
263
|
+
|
|
264
|
+
if (this.resizeObserver) {
|
|
265
|
+
this.resizeObserver.disconnect();
|
|
266
|
+
this.resizeObserver = null;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
this.element.style.top = "";
|
|
270
|
+
this.megamenuElement = null;
|
|
271
|
+
this.navLinks = null;
|
|
272
|
+
this.sections = [];
|
|
273
|
+
this.lastActiveIndex = 0;
|
|
274
|
+
(this.element as any).ODS_AnchorNavigation = null;
|
|
114
275
|
}
|
|
115
|
-
|
|
276
|
+
|
|
277
|
+
update(): void {
|
|
278
|
+
window.removeEventListener("scroll", this.scrollHandler);
|
|
279
|
+
window.removeEventListener("scroll", this.scrollSpyHandler);
|
|
280
|
+
window.removeEventListener("scrollend", this.scrollEndHandler);
|
|
281
|
+
window.removeEventListener("resize", this.resizeHandler);
|
|
282
|
+
|
|
283
|
+
if (this.resizeObserver) {
|
|
284
|
+
this.resizeObserver.disconnect();
|
|
285
|
+
this.resizeObserver = null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
this.megamenuElement = null;
|
|
289
|
+
this.navLinks = null;
|
|
290
|
+
this.sections = [];
|
|
291
|
+
this.lastActiveIndex = 0;
|
|
292
|
+
|
|
293
|
+
this.init();
|
|
294
|
+
}
|
|
295
|
+
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import React from "react";
|
|
4
4
|
import cx from "classnames";
|
|
5
|
-
import { Grid, GridCol } from "../Grid";
|
|
6
5
|
import { Link } from "../Link";
|
|
6
|
+
import { Container } from "../Container";
|
|
7
7
|
import { useStatic } from "../../utils/hooks";
|
|
8
8
|
import AnchorNavigationStatic from "./AnchorNavigation.static";
|
|
9
9
|
|
|
@@ -27,6 +27,7 @@ const AnchorNavigation = ({
|
|
|
27
27
|
className,
|
|
28
28
|
colorScheme,
|
|
29
29
|
children,
|
|
30
|
+
...other
|
|
30
31
|
}: AnchorNavigationProps) => {
|
|
31
32
|
const classes = cx(
|
|
32
33
|
CLASS_ROOT,
|
|
@@ -40,35 +41,38 @@ const AnchorNavigation = ({
|
|
|
40
41
|
const [anchorNavRef] = useStatic(AnchorNavigationStatic);
|
|
41
42
|
|
|
42
43
|
return (
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
<nav
|
|
45
|
+
className={classes}
|
|
46
|
+
ref={anchorNavRef}
|
|
47
|
+
data-anchor-navigation
|
|
48
|
+
aria-label="Sekcie stránky"
|
|
49
|
+
{...other}
|
|
50
|
+
>
|
|
51
|
+
<Container className={`${CLASS_ROOT}__content`}>
|
|
52
|
+
<ul
|
|
53
|
+
className={cx(
|
|
54
|
+
"list-inline horizontal-scroll mb-none",
|
|
55
|
+
`${CLASS_ROOT}__content-left`,
|
|
56
|
+
)}
|
|
47
57
|
>
|
|
48
58
|
{items.map((item) => (
|
|
49
|
-
<
|
|
50
|
-
id={item.href.replace("#", "")}
|
|
51
|
-
size={"auto"}
|
|
52
|
-
key={item.href}
|
|
53
|
-
className="pr-none pl-none"
|
|
54
|
-
>
|
|
59
|
+
<li key={item.href}>
|
|
55
60
|
<Link
|
|
56
61
|
href={item.href}
|
|
57
|
-
colorScheme={colorScheme}
|
|
58
62
|
className={cx(`${CLASS_ROOT}__item`, {
|
|
59
63
|
"is-active": item.isActive,
|
|
60
64
|
})}
|
|
61
65
|
>
|
|
62
66
|
{item.label}
|
|
63
67
|
</Link>
|
|
64
|
-
</
|
|
68
|
+
</li>
|
|
65
69
|
))}
|
|
66
|
-
</
|
|
70
|
+
</ul>
|
|
67
71
|
{children && (
|
|
68
72
|
<div className={`${CLASS_ROOT}__content-right`}>{children}</div>
|
|
69
73
|
)}
|
|
70
|
-
</
|
|
71
|
-
</
|
|
74
|
+
</Container>
|
|
75
|
+
</nav>
|
|
72
76
|
);
|
|
73
77
|
};
|
|
74
78
|
|
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
@use "./../../../styles/tools/generate";
|
|
5
5
|
@use "./../../../styles/tools/convert";
|
|
6
6
|
@use "./../../../styles/typography/config" as typography;
|
|
7
|
+
@use "../../Megamenu/styles/config" as megamenuConfig;
|
|
7
8
|
@use "sass:map" as sass-map;
|
|
8
9
|
|
|
9
10
|
@mixin anchor-navigation() {
|
|
10
11
|
position: sticky;
|
|
11
12
|
top: 0;
|
|
12
|
-
z-index:
|
|
13
|
+
z-index: 10;
|
|
13
14
|
background-color: var(--color-background-primary) !important;
|
|
14
|
-
|
|
15
|
+
border-bottom: 1px solid var(--color-border-strong);
|
|
15
16
|
|
|
16
|
-
// Štýly pre Grid s horizontal-scroll
|
|
17
17
|
.horizontal-scroll {
|
|
18
18
|
&::-webkit-scrollbar {
|
|
19
19
|
display: none !important;
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
background: transparent !important;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
// Pre Firefox
|
|
26
25
|
scrollbar-width: none !important;
|
|
27
26
|
-ms-overflow-style: none !important;
|
|
28
27
|
}
|
|
@@ -30,22 +29,13 @@
|
|
|
30
29
|
|
|
31
30
|
@mixin anchor-navigation-item() {
|
|
32
31
|
margin-right: space.get("large") !important;
|
|
32
|
+
margin-bottom: 0 !important;
|
|
33
33
|
padding: convert.to-rem(25px) 0 !important;
|
|
34
34
|
white-space: nowrap;
|
|
35
|
-
border-bottom: 4px solid transparent;
|
|
36
35
|
text-decoration: none !important;
|
|
37
36
|
display: inline-block;
|
|
38
37
|
cursor: pointer;
|
|
39
|
-
|
|
40
|
-
&:focus {
|
|
41
|
-
background-color: var(--color-background-primary) !important;
|
|
42
|
-
color: var(--color-text-default) !important;
|
|
43
|
-
outline: none !important;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
&:hover {
|
|
47
|
-
text-decoration: none !important;
|
|
48
|
-
}
|
|
38
|
+
font-weight: 700 !important;
|
|
49
39
|
|
|
50
40
|
&:last-child {
|
|
51
41
|
margin-right: 0;
|
|
@@ -56,9 +46,14 @@
|
|
|
56
46
|
padding: space.get("small") 0 !important;
|
|
57
47
|
}
|
|
58
48
|
|
|
49
|
+
&:hover,
|
|
50
|
+
&:focus-visible,
|
|
51
|
+
&:active,
|
|
59
52
|
&.is-active {
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
box-shadow: megamenuConfig.$active-line;
|
|
54
|
+
color: initial;
|
|
55
|
+
text-decoration: none !important;
|
|
56
|
+
outline: none;
|
|
62
57
|
}
|
|
63
58
|
}
|
|
64
59
|
|
|
@@ -67,24 +62,17 @@
|
|
|
67
62
|
justify-content: space-between;
|
|
68
63
|
align-items: center;
|
|
69
64
|
position: relative;
|
|
70
|
-
border-bottom: 1px solid var(--color-border-subtle);
|
|
71
|
-
padding: 0 convert.to-rem(70px);
|
|
72
|
-
|
|
73
|
-
@include breakpoint.get("xl", "down") {
|
|
74
|
-
padding: 0 convert.to-rem(42px);
|
|
75
|
-
}
|
|
76
65
|
|
|
77
66
|
@include breakpoint.get("xs", "down") {
|
|
78
|
-
padding: 0 convert.to-rem(10px);
|
|
79
|
-
border-bottom: none;
|
|
80
67
|
overflow: hidden;
|
|
81
68
|
flex-direction: column;
|
|
82
69
|
}
|
|
83
70
|
}
|
|
84
71
|
|
|
85
72
|
@mixin anchor-navigation-content-left() {
|
|
73
|
+
display: flex;
|
|
74
|
+
|
|
86
75
|
@include breakpoint.get("xs", "down") {
|
|
87
|
-
border-bottom: 1px solid var(--color-border-subtle);
|
|
88
76
|
width: 100%;
|
|
89
77
|
}
|
|
90
78
|
}
|
|
@@ -119,7 +107,6 @@
|
|
|
119
107
|
display: none;
|
|
120
108
|
}
|
|
121
109
|
padding: space.get("small") 0;
|
|
122
|
-
border-bottom: 1px solid var(--color-border-subtle);
|
|
123
110
|
width: 100%;
|
|
124
111
|
justify-content: space-between;
|
|
125
112
|
}
|