@jobber/components 6.36.0 → 6.36.1

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.
@@ -1,6 +1,6 @@
1
1
  import React, { ReactElement, ReactNode } from "react";
2
2
  interface TabsProps {
3
- readonly children: ReactElement | ReactElement[];
3
+ readonly children: ReactElement | Array<ReactElement | null | undefined | boolean>;
4
4
  /**
5
5
  * Specifies the index of the tab that should be active on mount
6
6
  *
@@ -1,5 +1,5 @@
1
1
  interface UseArrowKeyNavigationProps {
2
- elementsRef: React.RefObject<(HTMLElement | null)[]>;
2
+ elementsRef: React.RefObject<Map<number, HTMLElement>>;
3
3
  onActivate: (index: number) => void;
4
4
  }
5
5
  export declare const useArrowKeyNavigation: ({ elementsRef, onActivate, }: UseArrowKeyNavigationProps) => (event: React.KeyboardEvent<HTMLElement>) => void;
package/dist/Tabs-cjs.js CHANGED
@@ -43,11 +43,11 @@ const useArrowKeyNavigation = ({ elementsRef, onActivate, }) => {
43
43
  const elements = elementsRef.current;
44
44
  if (!elements)
45
45
  return;
46
- const currentIndex = elements.findIndex(element => element === document.activeElement);
46
+ const currentIndex = getActiveTabIndex(elements);
47
47
  if (currentIndex === -1)
48
48
  return;
49
49
  const focusAndActivateTab = (index) => {
50
- const element = elements[index];
50
+ const element = elements.get(index);
51
51
  if (element) {
52
52
  element.focus();
53
53
  onActivate(index);
@@ -55,21 +55,30 @@ const useArrowKeyNavigation = ({ elementsRef, onActivate, }) => {
55
55
  };
56
56
  if (event.key === "ArrowRight") {
57
57
  event.preventDefault();
58
- const nextIndex = (currentIndex + 1) % elements.length;
58
+ const nextIndex = (currentIndex + 1) % elements.size;
59
59
  focusAndActivateTab(nextIndex);
60
60
  }
61
61
  else if (event.key === "ArrowLeft") {
62
62
  event.preventDefault();
63
- const prevIndex = (currentIndex - 1 + elements.length) % elements.length;
63
+ const prevIndex = (currentIndex - 1 + elements.size) % elements.size;
64
64
  focusAndActivateTab(prevIndex);
65
65
  }
66
66
  }, [elementsRef, onActivate]);
67
67
  return handleKeyDown;
68
68
  };
69
+ function getActiveTabIndex(elements) {
70
+ const currentTab = Array.from(elements).find(([, element]) => element === document.activeElement);
71
+ if (!currentTab) {
72
+ return -1;
73
+ }
74
+ const [currentIndex] = currentTab;
75
+ return currentIndex;
76
+ }
69
77
 
70
78
  function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabChange, }) {
71
79
  var _a;
72
- const activeTabInitialValue = defaultTab < React.Children.count(children) ? defaultTab : 0;
80
+ const tabChildren = getActiveTabs(children);
81
+ const activeTabInitialValue = defaultTab < tabChildren.length ? defaultTab : 0;
73
82
  const [internalActiveTab, setInternalActiveTab] = React.useState(activeTabInitialValue);
74
83
  const activeTab = controlledActiveTab !== undefined ? controlledActiveTab : internalActiveTab;
75
84
  const { overflowRight, overflowLeft, tabRow } = useTabsOverflow();
@@ -77,7 +86,7 @@ function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabC
77
86
  [styles.overflowRight]: overflowRight,
78
87
  [styles.overflowLeft]: overflowLeft,
79
88
  });
80
- const tabRefs = React.useRef([]);
89
+ const tabRefs = React.useRef(new Map());
81
90
  const activateTab = (index) => {
82
91
  return () => {
83
92
  if (controlledActiveTab === undefined) {
@@ -92,15 +101,28 @@ function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabC
92
101
  elementsRef: tabRefs,
93
102
  onActivate: index => activateTab(index)(),
94
103
  });
95
- const activeTabProps = (_a = React.Children.toArray(children)[activeTab]) === null || _a === void 0 ? void 0 : _a.props;
104
+ const activeTabProps = (_a = tabChildren[activeTab]) === null || _a === void 0 ? void 0 : _a.props;
96
105
  React.useEffect(() => {
97
- if (activeTab > React.Children.count(children) - 1) {
106
+ if (activeTab > tabChildren.length - 1) {
98
107
  setInternalActiveTab(activeTabInitialValue);
99
108
  }
100
- }, [React.Children.count(children)]);
109
+ }, [tabChildren.length]);
101
110
  return (React.createElement("div", { className: styles.tabs },
102
111
  React.createElement("div", { className: overflowClassNames },
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 }))))),
112
+ React.createElement("ul", { role: "tablist", className: styles.tabRow, ref: tabRow, onKeyDown: handleKeyDown }, React.Children.map(children, child => {
113
+ if (!isChildTab(child)) {
114
+ return child;
115
+ }
116
+ const index = tabChildren.findIndex(tab => tab.props.label === child.props.label);
117
+ return (React.createElement(InternalTab, { label: child.props.label, selected: activeTab === index, activateTab: activateTab(index), onClick: child.props.onClick, ref: el => {
118
+ if (el) {
119
+ tabRefs.current.set(index, el);
120
+ }
121
+ else {
122
+ tabRefs.current.delete(index);
123
+ }
124
+ }, tabIndex: activeTab === index ? 0 : -1 }));
125
+ }))),
104
126
  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)));
105
127
  }
106
128
  function Tab({ label }) {
@@ -115,6 +137,18 @@ const InternalTab = React.forwardRef(({ label, selected, activateTab, onClick, t
115
137
  }, ref: ref, tabIndex: tabIndex }, typeof label === "string" ? (React.createElement(Typography.Typography, { element: "span", size: "large", fontWeight: "semiBold" }, label)) : (label))));
116
138
  });
117
139
  InternalTab.displayName = "InternalTab";
140
+ function getActiveTabs(children) {
141
+ const activeTabChildren = [];
142
+ React.Children.toArray(children).forEach(child => {
143
+ if (isChildTab(child)) {
144
+ activeTabChildren.push(child);
145
+ }
146
+ });
147
+ return activeTabChildren;
148
+ }
149
+ function isChildTab(child) {
150
+ return React.isValidElement(child) && child.type === Tab;
151
+ }
118
152
 
119
153
  exports.Tab = Tab;
120
154
  exports.Tabs = Tabs;
package/dist/Tabs-es.js CHANGED
@@ -41,11 +41,11 @@ const useArrowKeyNavigation = ({ elementsRef, onActivate, }) => {
41
41
  const elements = elementsRef.current;
42
42
  if (!elements)
43
43
  return;
44
- const currentIndex = elements.findIndex(element => element === document.activeElement);
44
+ const currentIndex = getActiveTabIndex(elements);
45
45
  if (currentIndex === -1)
46
46
  return;
47
47
  const focusAndActivateTab = (index) => {
48
- const element = elements[index];
48
+ const element = elements.get(index);
49
49
  if (element) {
50
50
  element.focus();
51
51
  onActivate(index);
@@ -53,21 +53,30 @@ const useArrowKeyNavigation = ({ elementsRef, onActivate, }) => {
53
53
  };
54
54
  if (event.key === "ArrowRight") {
55
55
  event.preventDefault();
56
- const nextIndex = (currentIndex + 1) % elements.length;
56
+ const nextIndex = (currentIndex + 1) % elements.size;
57
57
  focusAndActivateTab(nextIndex);
58
58
  }
59
59
  else if (event.key === "ArrowLeft") {
60
60
  event.preventDefault();
61
- const prevIndex = (currentIndex - 1 + elements.length) % elements.length;
61
+ const prevIndex = (currentIndex - 1 + elements.size) % elements.size;
62
62
  focusAndActivateTab(prevIndex);
63
63
  }
64
64
  }, [elementsRef, onActivate]);
65
65
  return handleKeyDown;
66
66
  };
67
+ function getActiveTabIndex(elements) {
68
+ const currentTab = Array.from(elements).find(([, element]) => element === document.activeElement);
69
+ if (!currentTab) {
70
+ return -1;
71
+ }
72
+ const [currentIndex] = currentTab;
73
+ return currentIndex;
74
+ }
67
75
 
68
76
  function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabChange, }) {
69
77
  var _a;
70
- const activeTabInitialValue = defaultTab < React__default.Children.count(children) ? defaultTab : 0;
78
+ const tabChildren = getActiveTabs(children);
79
+ const activeTabInitialValue = defaultTab < tabChildren.length ? defaultTab : 0;
71
80
  const [internalActiveTab, setInternalActiveTab] = useState(activeTabInitialValue);
72
81
  const activeTab = controlledActiveTab !== undefined ? controlledActiveTab : internalActiveTab;
73
82
  const { overflowRight, overflowLeft, tabRow } = useTabsOverflow();
@@ -75,7 +84,7 @@ function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabC
75
84
  [styles.overflowRight]: overflowRight,
76
85
  [styles.overflowLeft]: overflowLeft,
77
86
  });
78
- const tabRefs = useRef([]);
87
+ const tabRefs = useRef(new Map());
79
88
  const activateTab = (index) => {
80
89
  return () => {
81
90
  if (controlledActiveTab === undefined) {
@@ -90,15 +99,28 @@ function Tabs({ children, defaultTab = 0, activeTab: controlledActiveTab, onTabC
90
99
  elementsRef: tabRefs,
91
100
  onActivate: index => activateTab(index)(),
92
101
  });
93
- const activeTabProps = (_a = React__default.Children.toArray(children)[activeTab]) === null || _a === void 0 ? void 0 : _a.props;
102
+ const activeTabProps = (_a = tabChildren[activeTab]) === null || _a === void 0 ? void 0 : _a.props;
94
103
  useEffect(() => {
95
- if (activeTab > React__default.Children.count(children) - 1) {
104
+ if (activeTab > tabChildren.length - 1) {
96
105
  setInternalActiveTab(activeTabInitialValue);
97
106
  }
98
- }, [React__default.Children.count(children)]);
107
+ }, [tabChildren.length]);
99
108
  return (React__default.createElement("div", { className: styles.tabs },
100
109
  React__default.createElement("div", { className: overflowClassNames },
101
- React__default.createElement("ul", { role: "tablist", className: styles.tabRow, ref: tabRow, onKeyDown: handleKeyDown }, React__default.Children.map(children, (tab, index) => (React__default.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 }))))),
110
+ React__default.createElement("ul", { role: "tablist", className: styles.tabRow, ref: tabRow, onKeyDown: handleKeyDown }, React__default.Children.map(children, child => {
111
+ if (!isChildTab(child)) {
112
+ return child;
113
+ }
114
+ const index = tabChildren.findIndex(tab => tab.props.label === child.props.label);
115
+ return (React__default.createElement(InternalTab, { label: child.props.label, selected: activeTab === index, activateTab: activateTab(index), onClick: child.props.onClick, ref: el => {
116
+ if (el) {
117
+ tabRefs.current.set(index, el);
118
+ }
119
+ else {
120
+ tabRefs.current.delete(index);
121
+ }
122
+ }, tabIndex: activeTab === index ? 0 : -1 }));
123
+ }))),
102
124
  React__default.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)));
103
125
  }
104
126
  function Tab({ label }) {
@@ -113,5 +135,17 @@ const InternalTab = React__default.forwardRef(({ label, selected, activateTab, o
113
135
  }, ref: ref, tabIndex: tabIndex }, typeof label === "string" ? (React__default.createElement(Typography, { element: "span", size: "large", fontWeight: "semiBold" }, label)) : (label))));
114
136
  });
115
137
  InternalTab.displayName = "InternalTab";
138
+ function getActiveTabs(children) {
139
+ const activeTabChildren = [];
140
+ React__default.Children.toArray(children).forEach(child => {
141
+ if (isChildTab(child)) {
142
+ activeTabChildren.push(child);
143
+ }
144
+ });
145
+ return activeTabChildren;
146
+ }
147
+ function isChildTab(child) {
148
+ return React__default.isValidElement(child) && child.type === Tab;
149
+ }
116
150
 
117
151
  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.36.0",
3
+ "version": "6.36.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -489,5 +489,5 @@
489
489
  "> 1%",
490
490
  "IE 10"
491
491
  ],
492
- "gitHead": "afdf51d018850844414cee76e5e743fcf9ae4b05"
492
+ "gitHead": "f3711451382859ff2339bd2d548a489e7e6b9f14"
493
493
  }