UNPKG

10.2 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5exports.__esModule = true;
6exports.TabPanels = exports.TabPanel = exports.Tab = exports.TabList = exports["default"] = exports.TabContext = void 0;
7
8var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
10var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
11
12var _core = require("@emotion/core");
13
14var _autoId = require("@reach/auto-id");
15
16var _react = require("react");
17
18var _Box = _interopRequireDefault(require("../Box"));
19
20var _Flex = _interopRequireDefault(require("../Flex"));
21
22var _PseudoBox = _interopRequireDefault(require("../PseudoBox"));
23
24var _utils = require("../utils");
25
26var _styles = require("./styles");
27
28/** @jsx jsx */
29var Tab = (0, _react.forwardRef)(function (props, ref) {
30 var isSelected = props.isSelected,
31 isDisabled = props.isDisabled,
32 id = props.id,
33 size = props.size,
34 rest = (0, _objectWithoutPropertiesLoose2["default"])(props, ["isSelected", "isDisabled", "id", "size"]);
35 var tabStyleProps = (0, _styles.useTabStyle)();
36 return (0, _core.jsx)(_PseudoBox["default"], (0, _extends2["default"])({
37 ref: ref,
38 role: "tab",
39 tabIndex: isSelected ? 0 : -1,
40 id: "tab:" + id,
41 outline: "none",
42 as: "button",
43 type: "button",
44 disabled: isDisabled,
45 "aria-selected": isSelected,
46 "aria-disabled": isDisabled,
47 "aria-controls": "panel:" + id
48 }, tabStyleProps, rest));
49});
50exports.Tab = Tab;
51Tab.displayName = "Tab"; ////////////////////////////////////////////////////////////////////////
52
53var TabList = (0, _react.forwardRef)(function (props, ref) {
54 var children = props.children,
55 onKeyDown = props.onKeyDown,
56 onClick = props.onClick,
57 rest = (0, _objectWithoutPropertiesLoose2["default"])(props, ["children", "onKeyDown", "onClick"]);
58
59 var _useContext = (0, _react.useContext)(TabContext),
60 id = _useContext.id,
61 selectedIndex = _useContext.index,
62 manualIndex = _useContext.manualIndex,
63 onManualTabChange = _useContext.onManualTabChange,
64 isManual = _useContext.isManual,
65 onChangeTab = _useContext.onChangeTab,
66 onFocusPanel = _useContext.onFocusPanel,
67 orientation = _useContext.orientation;
68
69 var tabListStyleProps = (0, _styles.useTabListStyle)();
70 var allNodes = (0, _react.useRef)([]);
71 var validChildren = (0, _utils.cleanChildren)(children);
72 var focusableIndexes = validChildren.map(function (child, index) {
73 return child.props.isDisabled === true ? null : index;
74 }).filter(function (index) {
75 return index != null;
76 });
77 var enabledSelectedIndex = focusableIndexes.indexOf(selectedIndex);
78 var count = focusableIndexes.length;
79
80 var updateIndex = function updateIndex(index) {
81 var childIndex = focusableIndexes[index];
82 allNodes.current[childIndex].focus();
83 onChangeTab && onChangeTab(childIndex);
84 };
85
86 var handleKeyDown = function handleKeyDown(event) {
87 if (event.key === "ArrowRight") {
88 event.preventDefault();
89 var nextIndex = (enabledSelectedIndex + 1) % count;
90 updateIndex(nextIndex);
91 }
92
93 if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
94 event.preventDefault();
95
96 var _nextIndex = (enabledSelectedIndex - 1 + count) % count;
97
98 updateIndex(_nextIndex);
99 }
100
101 if (event.key === "Home") {
102 event.preventDefault();
103 updateIndex(0);
104 }
105
106 if (event.key === "End") {
107 event.preventDefault();
108 updateIndex(count - 1);
109 }
110
111 if (event.key === "ArrowDown") {
112 event.preventDefault();
113 onFocusPanel && onFocusPanel();
114 }
115
116 if (onKeyDown) {
117 onKeyDown(event);
118 }
119 };
120
121 var clones = validChildren.map(function (child, index) {
122 var isSelected = isManual ? index === manualIndex : index === selectedIndex;
123
124 var handleClick = function handleClick(event) {
125 // Hack for Safari. Buttons don't receive focus on click on Safari
126 // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
127 allNodes.current[index].focus();
128 onManualTabChange(index);
129 onChangeTab(index);
130
131 if (child.props.onClick) {
132 child.props.onClick(event);
133 }
134 };
135
136 return (0, _react.cloneElement)(child, {
137 ref: function ref(node) {
138 return allNodes.current[index] = node;
139 },
140 isSelected: isSelected,
141 onClick: handleClick,
142 id: id + "-" + index
143 });
144 });
145 return (0, _core.jsx)(_Flex["default"], (0, _extends2["default"])({
146 onKeyDown: handleKeyDown,
147 ref: ref,
148 role: "tablist",
149 "aria-orientation": orientation
150 }, tabListStyleProps, rest), clones);
151});
152exports.TabList = TabList;
153TabList.displayName = "TabList"; ////////////////////////////////////////////////////////////////////////
154
155var TabPanel = (0, _react.forwardRef)(function (_ref, _ref2) {
156 var children = _ref.children,
157 isSelected = _ref.isSelected,
158 selectedPanelRef = _ref.selectedPanelRef,
159 id = _ref.id,
160 rest = (0, _objectWithoutPropertiesLoose2["default"])(_ref, ["children", "isSelected", "selectedPanelRef", "id"]);
161 return (0, _core.jsx)(_Box["default"], (0, _extends2["default"])({
162 ref: function ref(node) {
163 if (isSelected) {
164 (0, _utils.assignRef)(selectedPanelRef, node);
165 }
166
167 (0, _utils.assignRef)(_ref2, node);
168 },
169 role: "tabpanel",
170 tabIndex: -1,
171 "aria-labelledby": "tab:" + id,
172 hidden: !isSelected,
173 id: "panel:" + id,
174 outline: 0
175 }, rest), children);
176});
177exports.TabPanel = TabPanel;
178TabPanel.displayName = "TabPanel"; ////////////////////////////////////////////////////////////////////////
179
180var TabPanels = (0, _react.forwardRef)(function (_ref3, ref) {
181 var children = _ref3.children,
182 rest = (0, _objectWithoutPropertiesLoose2["default"])(_ref3, ["children"]);
183
184 var _useContext2 = (0, _react.useContext)(TabContext),
185 selectedIndex = _useContext2.index,
186 selectedPanelRef = _useContext2.selectedPanelRef,
187 id = _useContext2.id,
188 isManual = _useContext2.isManual,
189 manualIndex = _useContext2.manualIndex;
190
191 var validChildren = (0, _utils.cleanChildren)(children);
192 var clones = validChildren.map(function (child, index) {
193 return (0, _react.cloneElement)(child, {
194 isSelected: isManual ? index === manualIndex : index === selectedIndex,
195 selectedPanelRef: selectedPanelRef,
196 id: id + "-" + index
197 });
198 });
199 return (0, _core.jsx)(_Box["default"], (0, _extends2["default"])({
200 tabIndex: "-1",
201 ref: ref
202 }, rest), clones);
203});
204exports.TabPanels = TabPanels;
205TabPanels.displayName = "TabPanels"; ////////////////////////////////////////////////////////////////////////
206
207var TabContext = (0, _react.createContext)();
208exports.TabContext = TabContext;
209var Tabs = (0, _react.forwardRef)(function (_ref4, ref) {
210 var children = _ref4.children,
211 onChange = _ref4.onChange,
212 controlledIndex = _ref4.index,
213 defaultIndex = _ref4.defaultIndex,
214 isManual = _ref4.isManual,
215 _ref4$variant = _ref4.variant,
216 variant = _ref4$variant === void 0 ? "line" : _ref4$variant,
217 _ref4$variantColor = _ref4.variantColor,
218 variantColor = _ref4$variantColor === void 0 ? "blue" : _ref4$variantColor,
219 _ref4$align = _ref4.align,
220 align = _ref4$align === void 0 ? "start" : _ref4$align,
221 _ref4$size = _ref4.size,
222 size = _ref4$size === void 0 ? "md" : _ref4$size,
223 _ref4$orientation = _ref4.orientation,
224 orientation = _ref4$orientation === void 0 ? "horizontal" : _ref4$orientation,
225 isFitted = _ref4.isFitted,
226 props = (0, _objectWithoutPropertiesLoose2["default"])(_ref4, ["children", "onChange", "index", "defaultIndex", "isManual", "variant", "variantColor", "align", "size", "orientation", "isFitted"]);
227 // Wrong usage of `variantColor` prop is quite common
228 // Let's add a warning hook that validates the passed variantColor
229 (0, _utils.useVariantColorWarning)("Tabs", variantColor);
230
231 var _useRef = (0, _react.useRef)(controlledIndex != null),
232 isControlled = _useRef.current;
233
234 var selectedPanelRef = (0, _react.useRef)();
235
236 var getInitialIndex = function getInitialIndex() {
237 if (!isManual) {
238 return defaultIndex || 0;
239 } else {
240 return controlledIndex || defaultIndex || 0;
241 }
242 };
243
244 var getActualIdx = function getActualIdx() {
245 if (isManual) {
246 return selectedIndex;
247 } else {
248 return isControlled ? controlledIndex : selectedIndex;
249 }
250 };
251
252 var _useState = (0, _react.useState)(getInitialIndex),
253 selectedIndex = _useState[0],
254 setSelectedIndex = _useState[1];
255
256 var _useState2 = (0, _react.useState)(controlledIndex || defaultIndex || 0),
257 manualIndex = _useState2[0],
258 setManualIndex = _useState2[1];
259
260 var actualIdx = getActualIdx();
261 var manualIdx = isControlled ? controlledIndex : manualIndex;
262
263 var onChangeTab = function onChangeTab(index) {
264 if (!isControlled) {
265 setSelectedIndex(index);
266 }
267
268 if (isControlled && isManual) {
269 setSelectedIndex(index);
270 }
271
272 if (!isManual) {
273 onChange && onChange(index);
274 }
275 };
276
277 var onManualTabChange = function onManualTabChange(index) {
278 if (!isControlled) {
279 setManualIndex(index);
280 }
281
282 if (isManual) {
283 onChange && onChange(index);
284 }
285 };
286
287 var onFocusPanel = function onFocusPanel() {
288 if (selectedPanelRef.current) {
289 selectedPanelRef.current.focus();
290 }
291 };
292
293 var id = (0, _autoId.useId)();
294 var context = {
295 id: id,
296 index: actualIdx,
297 manualIndex: manualIdx,
298 onManualTabChange: onManualTabChange,
299 isManual: isManual,
300 onChangeTab: onChangeTab,
301 selectedPanelRef: selectedPanelRef,
302 onFocusPanel: onFocusPanel,
303 color: variantColor,
304 size: size,
305 align: align,
306 variant: variant,
307 isFitted: isFitted,
308 orientation: orientation
309 };
310 return (0, _core.jsx)(TabContext.Provider, {
311 value: context
312 }, (0, _core.jsx)(_Box["default"], (0, _extends2["default"])({
313 ref: ref
314 }, props), children));
315});
316Tabs.displayName = "Tabs";
317var _default = Tabs;
318exports["default"] = _default;
\No newline at end of file