1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.JumpLinks = void 0;
|
4 | const tslib_1 = require("tslib");
|
5 | const React = tslib_1.__importStar(require("react"));
|
6 | const react_styles_1 = require("@patternfly/react-styles");
|
7 | const jump_links_1 = tslib_1.__importDefault(require("@patternfly/react-styles/css/components/JumpLinks/jump-links"));
|
8 | const sidebar_1 = tslib_1.__importDefault(require("@patternfly/react-styles/css/components/Sidebar/sidebar"));
|
9 | const JumpLinksItem_1 = require("./JumpLinksItem");
|
10 | const JumpLinksList_1 = require("./JumpLinksList");
|
11 | const util_1 = require("../../helpers/util");
|
12 | const Button_1 = require("../Button");
|
13 | const angle_right_icon_1 = tslib_1.__importDefault(require('@patternfly/react-icons/dist/js/icons/angle-right-icon'));
|
14 | const c_jump_links__toggle_Display_1 = tslib_1.__importDefault(require('@patternfly/react-tokens/dist/js/c_jump_links__toggle_Display'));
|
15 | const util_2 = require("../../helpers/util");
|
16 |
|
17 | const getScrollItems = (children, res) => {
|
18 | React.Children.forEach(children, (child) => {
|
19 | if (util_2.canUseDOM && document.getElementById && document.querySelector && child.type === JumpLinksItem_1.JumpLinksItem) {
|
20 | const scrollNode = child.props.node || child.props.href;
|
21 | if (typeof scrollNode === 'string') {
|
22 | if (scrollNode.startsWith('#')) {
|
23 |
|
24 |
|
25 | res.push(document.getElementById(scrollNode.substr(1)));
|
26 | }
|
27 | else {
|
28 | res.push(document.querySelector(scrollNode));
|
29 | }
|
30 | }
|
31 | else if (scrollNode instanceof HTMLElement) {
|
32 | res.push(scrollNode);
|
33 | }
|
34 | }
|
35 | if ([React.Fragment, JumpLinksList_1.JumpLinksList, JumpLinksItem_1.JumpLinksItem].includes(child.type)) {
|
36 | getScrollItems(child.props.children, res);
|
37 | }
|
38 | });
|
39 | return res;
|
40 | };
|
41 | function isResponsive(jumpLinks) {
|
42 |
|
43 | return (jumpLinks &&
|
44 | getComputedStyle(jumpLinks)
|
45 | .getPropertyValue(c_jump_links__toggle_Display_1.default.name)
|
46 | .includes('block'));
|
47 | }
|
48 | const JumpLinks = (_a) => {
|
49 | var { isCentered, isVertical, children, label, 'aria-label': ariaLabel = typeof label === 'string' ? label : null, scrollableSelector, activeIndex: activeIndexProp = 0, offset = 0, expandable, isExpanded: isExpandedProp = false, alwaysShowLabel = true, toggleAriaLabel = 'Toggle jump links', className } = _a, props = tslib_1.__rest(_a, ["isCentered", "isVertical", "children", "label", 'aria-label', "scrollableSelector", "activeIndex", "offset", "expandable", "isExpanded", "alwaysShowLabel", "toggleAriaLabel", "className"]);
|
50 | const hasScrollSpy = Boolean(scrollableSelector);
|
51 | const [scrollItems, setScrollItems] = React.useState(hasScrollSpy ? getScrollItems(children, []) : []);
|
52 | const [activeIndex, setActiveIndex] = React.useState(activeIndexProp);
|
53 | const [isExpanded, setIsExpanded] = React.useState(isExpandedProp);
|
54 |
|
55 | const isLinkClicked = React.useRef(false);
|
56 |
|
57 | React.useEffect(() => setIsExpanded(isExpandedProp), [isExpandedProp]);
|
58 | const navRef = React.useRef();
|
59 | let scrollableElement;
|
60 | const scrollSpy = React.useCallback(() => {
|
61 | if (!util_2.canUseDOM || !hasScrollSpy || !(scrollableElement instanceof HTMLElement)) {
|
62 | return;
|
63 | }
|
64 | if (isLinkClicked.current) {
|
65 | isLinkClicked.current = false;
|
66 | return;
|
67 | }
|
68 | const scrollPosition = Math.ceil(scrollableElement.scrollTop + offset);
|
69 | window.requestAnimationFrame(() => {
|
70 | let newScrollItems = scrollItems;
|
71 |
|
72 | if (!newScrollItems[0] || newScrollItems.includes(null)) {
|
73 | newScrollItems = getScrollItems(children, []);
|
74 | setScrollItems(newScrollItems);
|
75 | }
|
76 | const scrollElements = newScrollItems
|
77 | .map((e, index) => ({
|
78 | y: e ? e.offsetTop : null,
|
79 | index
|
80 | }))
|
81 | .filter(({ y }) => y !== null)
|
82 | .sort((e1, e2) => e2.y - e1.y);
|
83 | for (const { y, index } of scrollElements) {
|
84 | if (scrollPosition >= y) {
|
85 | return setActiveIndex(index);
|
86 | }
|
87 | }
|
88 | });
|
89 | }, [scrollItems, hasScrollSpy, scrollableElement, offset]);
|
90 | React.useEffect(() => {
|
91 | scrollableElement = document.querySelector(scrollableSelector);
|
92 | if (!(scrollableElement instanceof HTMLElement)) {
|
93 | return;
|
94 | }
|
95 | scrollableElement.addEventListener('scroll', scrollSpy);
|
96 | return () => scrollableElement.removeEventListener('scroll', scrollSpy);
|
97 | }, [scrollableSelector, scrollSpy]);
|
98 | React.useEffect(() => {
|
99 | scrollSpy();
|
100 | }, []);
|
101 | let jumpLinkIndex = 0;
|
102 | const cloneChildren = (children) => !hasScrollSpy
|
103 | ? children
|
104 | : React.Children.map(children, (child) => {
|
105 | if (child.type === JumpLinksItem_1.JumpLinksItem) {
|
106 | const { onClick: onClickProp, isActive: isActiveProp } = child.props;
|
107 | const itemIndex = jumpLinkIndex++;
|
108 | const scrollItem = scrollItems[itemIndex];
|
109 | return React.cloneElement(child, {
|
110 | onClick(ev) {
|
111 | isLinkClicked.current = true;
|
112 |
|
113 | let newScrollItems;
|
114 | if (!scrollItem) {
|
115 | newScrollItems = getScrollItems(children, []);
|
116 | setScrollItems(newScrollItems);
|
117 | }
|
118 | const newScrollItem = scrollItem || newScrollItems[itemIndex];
|
119 | if (newScrollItem) {
|
120 |
|
121 | const scrollableElement = document.querySelector(scrollableSelector);
|
122 | if (scrollableElement instanceof HTMLElement) {
|
123 | if (isResponsive(navRef.current)) {
|
124 |
|
125 | if (navRef.current) {
|
126 | navRef.current.classList.remove(jump_links_1.default.modifiers.expanded);
|
127 | }
|
128 | let stickyParent = navRef.current && navRef.current.parentElement;
|
129 | while (stickyParent && !stickyParent.classList.contains(sidebar_1.default.modifiers.sticky)) {
|
130 | stickyParent = stickyParent.parentElement;
|
131 | }
|
132 | setIsExpanded(false);
|
133 | if (stickyParent) {
|
134 | offset += stickyParent.scrollHeight;
|
135 | }
|
136 | }
|
137 | scrollableElement.scrollTo(0, newScrollItem.offsetTop - offset);
|
138 | }
|
139 | newScrollItem.focus();
|
140 | ev.preventDefault();
|
141 | setActiveIndex(itemIndex);
|
142 | }
|
143 | if (onClickProp) {
|
144 | onClickProp(ev);
|
145 | }
|
146 | },
|
147 | isActive: isActiveProp || activeIndex === itemIndex,
|
148 | children: cloneChildren(child.props.children)
|
149 | });
|
150 | }
|
151 | else if (child.type === React.Fragment) {
|
152 | return cloneChildren(child.props.children);
|
153 | }
|
154 | else if (child.type === JumpLinksList_1.JumpLinksList) {
|
155 | return React.cloneElement(child, { children: cloneChildren(child.props.children) });
|
156 | }
|
157 | return child;
|
158 | });
|
159 | return (React.createElement("nav", Object.assign({ className: react_styles_1.css(jump_links_1.default.jumpLinks, isCentered && jump_links_1.default.modifiers.center, isVertical && jump_links_1.default.modifiers.vertical, util_1.formatBreakpointMods(expandable, jump_links_1.default), isExpanded && jump_links_1.default.modifiers.expanded, className), "aria-label": ariaLabel, ref: navRef }, props),
|
160 | React.createElement("div", { className: jump_links_1.default.jumpLinksMain },
|
161 | React.createElement("div", { className: react_styles_1.css('pf-c-jump-links__header') },
|
162 | expandable && (React.createElement("div", { className: jump_links_1.default.jumpLinksToggle },
|
163 | React.createElement(Button_1.Button, { variant: "plain", onClick: () => setIsExpanded(!isExpanded), "aria-label": toggleAriaLabel, "aria-expanded": isExpanded },
|
164 | React.createElement("span", { className: jump_links_1.default.jumpLinksToggleIcon },
|
165 | React.createElement(angle_right_icon_1.default, null)),
|
166 | label && React.createElement("span", { className: react_styles_1.css(jump_links_1.default.jumpLinksToggleText) },
|
167 | " ",
|
168 | label,
|
169 | " ")))),
|
170 | label && alwaysShowLabel && React.createElement("div", { className: react_styles_1.css(jump_links_1.default.jumpLinksLabel) }, label)),
|
171 | React.createElement("ul", { className: jump_links_1.default.jumpLinksList }, cloneChildren(children)))));
|
172 | };
|
173 | exports.JumpLinks = JumpLinks;
|
174 | exports.JumpLinks.displayName = 'JumpLinks';
|
175 |
|
\ | No newline at end of file |