@jobber/components 6.6.0 → 6.7.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/dist/Tabs/Tabs.d.ts +3 -2
- package/dist/Tabs/hooks/useArrowKeyNavigation.d.ts +6 -0
- package/dist/Tabs-cjs.js +40 -7
- package/dist/Tabs-es.js +40 -7
- package/package.json +2 -2
package/dist/Tabs/Tabs.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ interface InternalTabProps {
|
|
|
31
31
|
readonly selected: boolean;
|
|
32
32
|
activateTab(): void;
|
|
33
33
|
onClick?(event: React.MouseEvent<HTMLButtonElement>): void;
|
|
34
|
+
readonly tabIndex: number;
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
-
export {};
|
|
36
|
+
declare const InternalTab: React.ForwardRefExoticComponent<InternalTabProps & React.RefAttributes<HTMLButtonElement>>;
|
|
37
|
+
export { InternalTab };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
interface UseArrowKeyNavigationProps {
|
|
2
|
+
elementsRef: React.RefObject<(HTMLElement | null)[]>;
|
|
3
|
+
onActivate: (index: number) => void;
|
|
4
|
+
}
|
|
5
|
+
export declare const useArrowKeyNavigation: ({ elementsRef, onActivate, }: UseArrowKeyNavigationProps) => (event: React.KeyboardEvent<HTMLElement>) => void;
|
|
6
|
+
export {};
|
package/dist/Tabs-cjs.js
CHANGED
|
@@ -38,6 +38,35 @@ function useTabsOverflow() {
|
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
const useArrowKeyNavigation = ({ elementsRef, onActivate, }) => {
|
|
42
|
+
const handleKeyDown = React.useCallback((event) => {
|
|
43
|
+
const elements = elementsRef.current;
|
|
44
|
+
if (!elements)
|
|
45
|
+
return;
|
|
46
|
+
const currentIndex = elements.findIndex(element => element === document.activeElement);
|
|
47
|
+
if (currentIndex === -1)
|
|
48
|
+
return;
|
|
49
|
+
const focusAndActivateTab = (index) => {
|
|
50
|
+
const element = elements[index];
|
|
51
|
+
if (element) {
|
|
52
|
+
element.focus();
|
|
53
|
+
onActivate(index);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
if (event.key === "ArrowRight") {
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
const nextIndex = (currentIndex + 1) % elements.length;
|
|
59
|
+
focusAndActivateTab(nextIndex);
|
|
60
|
+
}
|
|
61
|
+
else if (event.key === "ArrowLeft") {
|
|
62
|
+
event.preventDefault();
|
|
63
|
+
const prevIndex = (currentIndex - 1 + elements.length) % elements.length;
|
|
64
|
+
focusAndActivateTab(prevIndex);
|
|
65
|
+
}
|
|
66
|
+
}, [elementsRef, onActivate]);
|
|
67
|
+
return handleKeyDown;
|
|
68
|
+
};
|
|
69
|
+
|
|
41
70
|
function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabChange, }) {
|
|
42
71
|
var _a;
|
|
43
72
|
const activeTabInitialValue = defaultTab < React.Children.count(children) ? defaultTab : 0;
|
|
@@ -48,6 +77,7 @@ function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabC
|
|
|
48
77
|
[styles.overflowRight]: overflowRight,
|
|
49
78
|
[styles.overflowLeft]: overflowLeft,
|
|
50
79
|
});
|
|
80
|
+
const tabRefs = React.useRef([]);
|
|
51
81
|
const activateTab = (index) => {
|
|
52
82
|
return () => {
|
|
53
83
|
if (controlledActiveTab === undefined) {
|
|
@@ -58,6 +88,10 @@ function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabC
|
|
|
58
88
|
}
|
|
59
89
|
};
|
|
60
90
|
};
|
|
91
|
+
const handleKeyDown = useArrowKeyNavigation({
|
|
92
|
+
elementsRef: tabRefs,
|
|
93
|
+
onActivate: index => activateTab(index)(),
|
|
94
|
+
});
|
|
61
95
|
const activeTabProps = (_a = React.Children.toArray(children)[activeTab]) === null || _a === void 0 ? void 0 : _a.props;
|
|
62
96
|
React.useEffect(() => {
|
|
63
97
|
if (activeTab > React.Children.count(children) - 1) {
|
|
@@ -66,22 +100,21 @@ function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabC
|
|
|
66
100
|
}, [React.Children.count(children)]);
|
|
67
101
|
return (React.createElement("div", { className: styles.tabs },
|
|
68
102
|
React.createElement("div", { className: overflowClassNames },
|
|
69
|
-
React.createElement("ul", { role: "tablist", className: styles.tabRow, ref: tabRow }, React.Children.map(children, (tab, index) => (React.createElement(InternalTab, { label: tab.props.label, selected: activeTab === index, activateTab: activateTab(index), onClick: tab.props.onClick }))))),
|
|
103
|
+
React.createElement("ul", { role: "tablist", className: styles.tabRow, ref: tabRow, onKeyDown: handleKeyDown }, React.Children.map(children, (tab, index) => (React.createElement(InternalTab, { label: tab.props.label, selected: activeTab === index, activateTab: activateTab(index), onClick: tab.props.onClick, ref: el => (tabRefs.current[index] = el), tabIndex: activeTab === index ? 0 : -1 }))))),
|
|
70
104
|
React.createElement("section", { role: "tabpanel", className: styles.tabContent, "aria-label": activeTabProps === null || activeTabProps === void 0 ? void 0 : activeTabProps.label }, activeTabProps === null || activeTabProps === void 0 ? void 0 : activeTabProps.children)));
|
|
71
105
|
}
|
|
72
106
|
function Tab({ label }) {
|
|
73
107
|
return React.createElement(React.Fragment, null, label);
|
|
74
108
|
}
|
|
75
|
-
|
|
76
|
-
return;
|
|
77
|
-
}, }) {
|
|
109
|
+
const InternalTab = React.forwardRef(({ label, selected, activateTab, onClick, tabIndex }, ref) => {
|
|
78
110
|
const className = classnames(styles.tab, { [styles.selected]: selected });
|
|
79
111
|
return (React.createElement("li", { role: "presentation" },
|
|
80
112
|
React.createElement("button", { type: "button", role: "tab", className: className, onClick: event => {
|
|
81
113
|
activateTab();
|
|
82
|
-
onClick(event);
|
|
83
|
-
} }, typeof label === "string" ? (React.createElement(Typography.Typography, { element: "span", size: "large", fontWeight: "semiBold" }, label)) : (label))));
|
|
84
|
-
}
|
|
114
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
115
|
+
}, ref: ref, tabIndex: tabIndex }, typeof label === "string" ? (React.createElement(Typography.Typography, { element: "span", size: "large", fontWeight: "semiBold" }, label)) : (label))));
|
|
116
|
+
});
|
|
117
|
+
InternalTab.displayName = "InternalTab";
|
|
85
118
|
|
|
86
119
|
exports.Tab = Tab;
|
|
87
120
|
exports.Tabs = Tabs;
|
package/dist/Tabs-es.js
CHANGED
|
@@ -36,6 +36,35 @@ function useTabsOverflow() {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
const useArrowKeyNavigation = ({ elementsRef, onActivate, }) => {
|
|
40
|
+
const handleKeyDown = useCallback((event) => {
|
|
41
|
+
const elements = elementsRef.current;
|
|
42
|
+
if (!elements)
|
|
43
|
+
return;
|
|
44
|
+
const currentIndex = elements.findIndex(element => element === document.activeElement);
|
|
45
|
+
if (currentIndex === -1)
|
|
46
|
+
return;
|
|
47
|
+
const focusAndActivateTab = (index) => {
|
|
48
|
+
const element = elements[index];
|
|
49
|
+
if (element) {
|
|
50
|
+
element.focus();
|
|
51
|
+
onActivate(index);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
if (event.key === "ArrowRight") {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
const nextIndex = (currentIndex + 1) % elements.length;
|
|
57
|
+
focusAndActivateTab(nextIndex);
|
|
58
|
+
}
|
|
59
|
+
else if (event.key === "ArrowLeft") {
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
const prevIndex = (currentIndex - 1 + elements.length) % elements.length;
|
|
62
|
+
focusAndActivateTab(prevIndex);
|
|
63
|
+
}
|
|
64
|
+
}, [elementsRef, onActivate]);
|
|
65
|
+
return handleKeyDown;
|
|
66
|
+
};
|
|
67
|
+
|
|
39
68
|
function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabChange, }) {
|
|
40
69
|
var _a;
|
|
41
70
|
const activeTabInitialValue = defaultTab < React.Children.count(children) ? defaultTab : 0;
|
|
@@ -46,6 +75,7 @@ function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabC
|
|
|
46
75
|
[styles.overflowRight]: overflowRight,
|
|
47
76
|
[styles.overflowLeft]: overflowLeft,
|
|
48
77
|
});
|
|
78
|
+
const tabRefs = useRef([]);
|
|
49
79
|
const activateTab = (index) => {
|
|
50
80
|
return () => {
|
|
51
81
|
if (controlledActiveTab === undefined) {
|
|
@@ -56,6 +86,10 @@ function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabC
|
|
|
56
86
|
}
|
|
57
87
|
};
|
|
58
88
|
};
|
|
89
|
+
const handleKeyDown = useArrowKeyNavigation({
|
|
90
|
+
elementsRef: tabRefs,
|
|
91
|
+
onActivate: index => activateTab(index)(),
|
|
92
|
+
});
|
|
59
93
|
const activeTabProps = (_a = React.Children.toArray(children)[activeTab]) === null || _a === void 0 ? void 0 : _a.props;
|
|
60
94
|
useEffect(() => {
|
|
61
95
|
if (activeTab > React.Children.count(children) - 1) {
|
|
@@ -64,21 +98,20 @@ function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabC
|
|
|
64
98
|
}, [React.Children.count(children)]);
|
|
65
99
|
return (React.createElement("div", { className: styles.tabs },
|
|
66
100
|
React.createElement("div", { className: overflowClassNames },
|
|
67
|
-
React.createElement("ul", { role: "tablist", className: styles.tabRow, ref: tabRow }, React.Children.map(children, (tab, index) => (React.createElement(InternalTab, { label: tab.props.label, selected: activeTab === index, activateTab: activateTab(index), onClick: tab.props.onClick }))))),
|
|
101
|
+
React.createElement("ul", { role: "tablist", className: styles.tabRow, ref: tabRow, onKeyDown: handleKeyDown }, React.Children.map(children, (tab, index) => (React.createElement(InternalTab, { label: tab.props.label, selected: activeTab === index, activateTab: activateTab(index), onClick: tab.props.onClick, ref: el => (tabRefs.current[index] = el), tabIndex: activeTab === index ? 0 : -1 }))))),
|
|
68
102
|
React.createElement("section", { role: "tabpanel", className: styles.tabContent, "aria-label": activeTabProps === null || activeTabProps === void 0 ? void 0 : activeTabProps.label }, activeTabProps === null || activeTabProps === void 0 ? void 0 : activeTabProps.children)));
|
|
69
103
|
}
|
|
70
104
|
function Tab({ label }) {
|
|
71
105
|
return React.createElement(React.Fragment, null, label);
|
|
72
106
|
}
|
|
73
|
-
|
|
74
|
-
return;
|
|
75
|
-
}, }) {
|
|
107
|
+
const InternalTab = React.forwardRef(({ label, selected, activateTab, onClick, tabIndex }, ref) => {
|
|
76
108
|
const className = classnames(styles.tab, { [styles.selected]: selected });
|
|
77
109
|
return (React.createElement("li", { role: "presentation" },
|
|
78
110
|
React.createElement("button", { type: "button", role: "tab", className: className, onClick: event => {
|
|
79
111
|
activateTab();
|
|
80
|
-
onClick(event);
|
|
81
|
-
} }, typeof label === "string" ? (React.createElement(Typography, { element: "span", size: "large", fontWeight: "semiBold" }, label)) : (label))));
|
|
82
|
-
}
|
|
112
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
113
|
+
}, ref: ref, tabIndex: tabIndex }, typeof label === "string" ? (React.createElement(Typography, { element: "span", size: "large", fontWeight: "semiBold" }, label)) : (label))));
|
|
114
|
+
});
|
|
115
|
+
InternalTab.displayName = "InternalTab";
|
|
83
116
|
|
|
84
117
|
export { Tabs as T, Tab as a };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.7.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -487,5 +487,5 @@
|
|
|
487
487
|
"> 1%",
|
|
488
488
|
"IE 10"
|
|
489
489
|
],
|
|
490
|
-
"gitHead": "
|
|
490
|
+
"gitHead": "79e357ec4d4fa986b23ef2337525ab34d0f4b471"
|
|
491
491
|
}
|