@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
885 lines (884 loc) • 27.9 kB
JavaScript
"use client";
import _pushInstanceProperty from "core-js-pure/stable/instance/push.js";
import _JSON$parse from "core-js-pure/stable/json/parse.js";
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
import clsx from 'clsx';
import withComponentMarkers from "../../shared/helpers/withComponentMarkers.js";
import Context from "../../shared/Context.js";
import { warn, slugify, validateDOMAttributes, dispatchCustomElementEvent, getClosestParent, filterProps, combineLabelledBy } from "../../shared/component-helper.js";
import { extendPropsWithContext } from "../../shared/helpers/extendPropsWithContext.js";
import { applySpacing } from "../space/SpacingUtils.js";
import { createSkeletonClass, skeletonDOMAttributes } from "../skeleton/SkeletonHelper.js";
import Button from "../button/Button.js";
import useId from "../../shared/helpers/useId.js";
import useIsomorphicLayoutEffect from "../../shared/helpers/useIsomorphicLayoutEffect.js";
import useUpdateEffect from "../../shared/helpers/useUpdateEffect.js";
import whatInput from "../../shared/helpers/whatInput.js";
import CustomContent from "./TabsCustomContent.js";
import ContentWrapper from "./TabsContentWrapper.js";
import { createSharedState } from "../../shared/helpers/useSharedState.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const tabsDefaultProps = {
data: null,
content: null,
contentStyle: null,
contentInnerSpace: {
top: 'large'
},
label: null,
tabElement: 'button',
selectedKey: null,
align: 'left',
tabsStyle: null,
tabsInnerSpace: undefined,
noBorder: false,
navButtonEdge: false,
onOpenTabNavigationFn: null,
keepInDOM: false,
preventRerender: false,
scroll: null,
skeleton: null,
id: null,
className: null,
children: null,
render: null,
onChange: null,
onMouseEnter: null,
onClick: null,
onFocus: null,
breakout: true
};
function getSelectedKeyOrFallback(selectedKey, data) {
let useKey = selectedKey;
if (!useKey) {
useKey = data.reduce((acc, {
selected,
key
}) => selected ? key : acc, null) || data[0] && data[0].key;
} else {
const keyExists = data.findIndex(({
key
}) => key == selectedKey);
if (keyExists === -1) {
useKey = data[0] && data[0].key;
}
}
return useKey;
}
function getData(props) {
const addReactElement = (list, reactElem, reactElemIndex) => {
if (reactElem && reactElem.type === CustomContent) {
const dataProps = props.children && Array.isArray(props.children) && props.children[reactElemIndex] || {};
const componentProps = {
...reactElem.props
};
if (componentProps.title === null) {
delete componentProps.title;
}
const {
title,
key: _key,
hash,
...rest
} = {
...dataProps,
...componentProps,
...{
children: null
}
};
_pushInstanceProperty(list).call(list, {
title,
key: (!_key && hash ? hash : _key) || slugify(title),
content: reactElem,
...rest
});
}
};
let res = [];
const data = !props.data && props.children ? props.children : props.data;
if (Array.isArray(props.children) && props.children.some(element => typeof element === 'function' || React.isValidElement(element))) {
res = props.children.reduce((list, reactElem, i) => {
addReactElement(list, reactElem, i);
return list;
}, []);
}
if (!Array.isArray(props.children) && (typeof props.children === 'function' || React.isValidElement(props.children))) {
addReactElement(res, props.children);
}
if (!(res && res.length > 0)) {
if (props.data && Array.isArray(data)) {
res = data;
} else if (typeof data === 'string') {
res = data[0] === '[' ? _JSON$parse(data) : [];
} else if (data && typeof data === 'object') {
res = Object.entries(data).reduce((acc, [key, obj]) => {
if (obj) {
_pushInstanceProperty(acc).call(acc, {
key,
...obj
});
}
return acc;
}, []);
}
}
return res || [];
}
function TabsComponent(ownProps) {
const context = useContext(Context);
const props = extendPropsWithContext(ownProps, tabsDefaultProps, {
skeleton: context === null || context === void 0 ? void 0 : context.skeleton
});
const propsRef = useRef(props);
propsRef.current = props;
const tabsRef = useRef(null);
const tablistRef = useRef(null);
const cacheRef = useRef({});
const listenForPropChangesRef = useRef(true);
const _id = useId(ownProps.id);
const sharedStateRef = useRef(null);
const propChangeRef = useRef(false);
const initialData = useRef(getData(ownProps));
const [data, setData] = useState(initialData.current);
const [selectedKey, setSelectedKey] = useState(() => getSelectedKeyOrFallback(ownProps.selectedKey, initialData.current));
const [focusKey, setFocusKey] = useState(selectedKey);
const [hasScrollbar, setHasScrollbar] = useState(false);
const [isFirst, setIsFirst] = useState(undefined);
const [isLast, setIsLast] = useState(undefined);
const [prevDataSource, setPrevDataSource] = useState(ownProps.data || ownProps.children);
const [prevSelectedKey, setPrevSelectedKey] = useState(ownProps.selectedKey);
if (listenForPropChangesRef.current) {
const dataSource = ownProps.data || ownProps.children;
let currentData = data;
if (prevDataSource !== dataSource) {
setPrevDataSource(dataSource);
const newData = getData(ownProps);
setData(newData);
currentData = newData;
propChangeRef.current = true;
}
if (ownProps.selectedKey && prevSelectedKey !== ownProps.selectedKey) {
setPrevSelectedKey(ownProps.selectedKey);
setSelectedKey(getSelectedKeyOrFallback(ownProps.selectedKey, currentData));
propChangeRef.current = true;
}
}
useEffect(() => {
listenForPropChangesRef.current = true;
});
const dataRef = useRef(data);
dataRef.current = data;
const selectedKeyRef = useRef(selectedKey);
selectedKeyRef.current = selectedKey;
const focusKeyRef = useRef(focusKey);
focusKeyRef.current = focusKey;
const hasScrollbarRef = useRef(hasScrollbar);
hasScrollbarRef.current = hasScrollbar;
const isFirstRef = useRef(isFirst);
isFirstRef.current = isFirst;
const isLastRef = useRef(isLast);
isLastRef.current = isLast;
const contextRef = useRef(context);
contextRef.current = context;
const getLastPosition = () => {
if (typeof window !== 'undefined') {
try {
const pos = parseFloat(window.localStorage.getItem(`tabs-pos-${_id}`));
window.localStorage.removeItem(`tabs-pos-${_id}`);
return isNaN(pos) ? -1 : pos;
} catch (e) {
warn(e);
}
}
return -1;
};
const hasLastPosition = () => {
return lastPositionRef.current > -1;
};
const lastPositionRef = useRef(getLastPosition());
const hasLastUsedTab = () => {
if (typeof window !== 'undefined') {
try {
const key = window.localStorage.getItem(`tabs-last-${_id}`) || null;
window.localStorage.removeItem(`tabs-last-${_id}`);
return key;
} catch (e) {
warn(e);
}
}
return -1;
};
const saveLastUsedTab = () => {
if (typeof window !== 'undefined') {
try {
window.localStorage.setItem(`tabs-last-${_id}`, String(selectedKeyRef.current));
} catch (e) {
warn(e);
}
}
};
const saveLastPosition = (position = (_tablistRef$current => (_tablistRef$current = tablistRef.current) === null || _tablistRef$current === void 0 ? void 0 : _tablistRef$current.scrollLeft)()) => {
if (typeof window !== 'undefined') {
try {
window.localStorage.setItem(`tabs-pos-${_id}`, String(position));
} catch (e) {
warn(e);
}
}
};
const checkHasScrollbar = () => {
if (!tablistRef.current) {
return false;
}
const tablistElem = tablistRef.current;
let tolerance = 1;
const lastSnap = tablistElem.querySelector('.dnb-tabs__button__snap:last-of-type');
if (lastSnap) {
const lastButton = lastSnap.querySelector('.dnb-tabs__button');
if (lastButton) {
const buttonMargin = parseFloat(window.getComputedStyle(lastButton).marginRight) || 0;
const snapMargin = parseFloat(window.getComputedStyle(lastSnap).marginRight) || 0;
tolerance += Math.max(0, buttonMargin + snapMargin);
}
}
return tablistElem.scrollWidth - tolerance > tablistElem.offsetWidth;
};
const setLeftPosition = scrollLeft => {
try {
tablistRef.current.style.scrollBehavior = 'auto';
tablistRef.current.scrollLeft = scrollLeft;
tablistRef.current.style.scrollBehavior = 'smooth';
} catch (e) {}
};
const scrollToTab = useCallback(({
type,
behavior = 'smooth'
}) => {
if (typeof window === 'undefined') {
return;
}
if (window.IS_TEST) {
behavior = 'auto';
}
const delay = () => {
try {
if (hasScrollbarRef.current && tablistRef.current) {
const first = tablistRef.current.querySelector('.dnb-tabs__button__snap:first-of-type');
const isFirstItem = first.classList.contains(type);
const last = tablistRef.current.querySelector('.dnb-tabs__button__snap:last-of-type');
const isLastItem = last.classList.contains(type);
const elem = tablistRef.current.querySelector(`.dnb-tabs__button.${type}`);
const style = window.getComputedStyle(tabsRef.current);
const margin = parseFloat(style.marginLeft);
let padding = margin < 0 ? parseFloat(style.paddingLeft) : 0;
if (!isFirstItem && !isLastItem && parseFloat(style.paddingLeft) < 16) {
const navButton = tabsRef.current.querySelector('.dnb-tabs__scroll-nav-button:first-of-type');
const additionalSpace = parseFloat(window.getComputedStyle(navButton).width) * 1.5;
padding += additionalSpace;
}
const leftPadding = (margin < 0 ? Math.abs(margin) : 0) + padding + parseFloat(window.getComputedStyle(first).paddingLeft);
const offsetLeft = elem.offsetLeft;
const left = elem && !isFirstItem ? offsetLeft - leftPadding : 0;
if (behavior === 'auto') {
tablistRef.current.style.scrollBehavior = 'auto';
}
tablistRef.current.scrollTo({
left,
behavior
});
if (behavior === 'auto') {
tablistRef.current.style.scrollBehavior = '';
}
setIsFirst(isFirstItem);
setIsLast(isLastItem);
}
} catch (e) {
warn(e);
}
};
window.requestAnimationFrame(delay);
}, []);
const handleVerticalScroll = () => {
if (propsRef.current.scroll && tablistRef.current && typeof tablistRef.current.scrollIntoView === 'function') {
tablistRef.current.scrollIntoView({
block: 'start',
behavior: 'smooth'
});
}
};
const setFocusOnTabButton = useCallback(() => {
try {
const elem = tablistRef.current.querySelector('.dnb-tabs__button.focus');
elem.focus({
preventScroll: true
});
if (!document.getElementById(`${_id}-content`) && typeof process !== 'undefined' && process.env.NODE_ENV !== 'test') {
warn(`Could not find the required <Tabs.Content id="${_id}-content" ... /> that provides role="tabpanel"`);
}
} catch (e) {
warn(e);
}
}, [_id]);
const getCurrentTitle = key => {
const useKey = key !== null && key !== void 0 ? key : selectedKeyRef.current;
const current = dataRef.current.filter(({
key: k
}) => k == useKey)[0];
return current && current.title || null;
};
const getStepKey = (useKey, stateKey) => {
const currentData = dataRef.current.filter(({
disabled
}) => !disabled);
const currentIndex = currentData.reduce((acc, {
key
}, i) => key == stateKey ? i : acc, -1);
let nextIndex = currentIndex + Number(useKey);
if (nextIndex < 0) {
nextIndex = currentData.length - 1;
}
if (nextIndex >= currentData.length) {
nextIndex = 0;
}
return currentData.reduce((acc, {
key
}, i) => i === nextIndex ? key : acc, null);
};
const getEventArgs = args => {
const key = typeof args.selectedKey !== 'undefined' ? args.selectedKey : selectedKeyRef.current;
return {
key,
selectedKey: selectedKeyRef.current,
focusKey: focusKeyRef.current,
title: getCurrentTitle(key),
...args
};
};
const focusTab = (newFocusKey, event = null, mode = null) => {
if (mode === 'step' && parseFloat(String(newFocusKey))) {
newFocusKey = getStepKey(newFocusKey, focusKeyRef.current);
}
listenForPropChangesRef.current = false;
setFocusKey(newFocusKey);
dispatchCustomElementEvent({
props: propsRef.current
}, 'onFocus', getEventArgs({
event,
focusKey: newFocusKey
}));
whatInput.specificKeys([9, 37, 39, 33, 34, 35, 36]);
};
useUpdateEffect(() => {
setFocusOnTabButton();
}, [focusKey]);
const openTab = (newSelectedKey, event = null, mode = null) => {
saveLastPosition();
saveLastUsedTab();
whatInput.specificKeys([9]);
if (mode === 'step' && parseFloat(String(newSelectedKey))) {
newSelectedKey = getStepKey(newSelectedKey, selectedKeyRef.current);
}
if (typeof newSelectedKey !== 'undefined') {
listenForPropChangesRef.current = false;
setSelectedKey(newSelectedKey);
setFocusKey(newSelectedKey);
}
dispatchCustomElementEvent({
props: propsRef.current
}, 'onChange', getEventArgs({
event,
selectedKey: newSelectedKey
}));
if (propsRef.current.onOpenTabNavigationFn && typeof window !== 'undefined') {
try {
propsRef.current.onOpenTabNavigationFn(newSelectedKey);
} catch (e) {
warn('Tabs Error:', e);
}
}
if (sharedStateRef.current) {
sharedStateRef.current.update(getEventArgs({
event,
selectedKey: newSelectedKey
}));
}
};
useUpdateEffect(() => {
handleVerticalScroll();
}, [selectedKey]);
const onResizeHandler = useCallback(() => {
const scrollbarVisible = checkHasScrollbar();
setHasScrollbar(scrollbarVisible);
if (scrollbarVisible) {
scrollToTab({
type: 'selected'
});
}
}, [scrollToTab]);
if (ownProps.id && !sharedStateRef.current) {
sharedStateRef.current = createSharedState(ownProps.id);
sharedStateRef.current.set({
key: selectedKey,
selectedKey,
focusKey,
title: getCurrentTitle(selectedKey)
});
}
useIsomorphicLayoutEffect(() => {
let isMounted = true;
const init = () => {
if (isMounted && tablistRef.current) {
const scrollbarVisible = checkHasScrollbar();
const hasLP = lastPositionRef.current > -1;
setHasScrollbar(scrollbarVisible);
if (hasLP) {
setLeftPosition(lastPositionRef.current);
}
if (scrollbarVisible) {
scrollToTab({
type: 'selected',
behavior: hasLP ? 'smooth' : 'auto'
});
}
if (hasLastUsedTab() !== null) {
setFocusOnTabButton();
}
}
};
if (document.readyState === 'complete') {
init();
} else if (typeof window !== 'undefined') {
window.addEventListener('load', init);
}
if (typeof window !== 'undefined') {
window.addEventListener('resize', onResizeHandler);
}
return () => {
isMounted = false;
whatInput.specificKeys([9]);
sharedStateRef.current = null;
if (typeof window !== 'undefined') {
window.removeEventListener('resize', onResizeHandler);
window.removeEventListener('load', init);
}
};
}, []);
useUpdateEffect(() => {
if (sharedStateRef.current && propChangeRef.current) {
propChangeRef.current = false;
onResizeHandler();
sharedStateRef.current.update(getEventArgs({
selectedKey
}));
}
}, [selectedKey, data]);
const focusFirstTab = e => {
const key = dataRef.current[0].key;
focusTab(key, e, 'step');
scrollToTab({
type: 'focus'
});
};
const focusLastTab = e => {
const d = dataRef.current;
const key = d[d.length - 1].key;
focusTab(key, e, 'step');
scrollToTab({
type: 'focus'
});
};
const focusPrevTab = e => {
focusTab(-1, e, 'step');
scrollToTab({
type: 'focus'
});
};
const focusNextTab = e => {
focusTab(+1, e, 'step');
scrollToTab({
type: 'focus'
});
};
const openPrevTab = e => {
openTab(-1, e, 'step');
scrollToTab({
type: 'selected'
});
};
const openNextTab = e => {
openTab(+1, e, 'step');
scrollToTab({
type: 'selected'
});
};
const onTablistKeyDownHandler = e => {
switch (e.key) {
case 'ArrowUp':
case 'PageUp':
case 'ArrowLeft':
e.preventDefault();
focusPrevTab(e);
break;
case 'ArrowDown':
case 'PageDown':
case 'ArrowRight':
e.preventDefault();
focusNextTab(e);
break;
case 'Home':
e.preventDefault();
focusFirstTab(e);
break;
case 'End':
e.preventDefault();
focusLastTab(e);
break;
}
};
const getCurrentKey = event => {
let currentKey;
try {
var _elem$dataset;
const elem = getClosestParent('dnb-tabs__button', event.target);
currentKey = elem === null || elem === void 0 || (_elem$dataset = elem.dataset) === null || _elem$dataset === void 0 ? void 0 : _elem$dataset.tabKey;
} catch (e) {
warn('Tabs Error:', e);
}
return currentKey;
};
const onMouseEnterHandler = event => {
const key = getCurrentKey(event);
if (key) {
dispatchCustomElementEvent({
props: propsRef.current
}, 'onMouseEnter', getEventArgs({
event,
selectedKey: key
}));
}
};
const onClickHandler = event => {
const key = getCurrentKey(event);
if (key) {
const ret = dispatchCustomElementEvent({
props: propsRef.current
}, 'onClick', getEventArgs({
event,
selectedKey: key
}));
if (ret !== false) {
openTab(key, event);
scrollToTab({
type: 'selected'
});
}
}
};
const onMouseDown = event => {
event.preventDefault();
};
const onKeyDownHandler = event => {
if (event.key === 'Enter') {
try {
const elem = document.getElementById(`${_id}-content`);
elem.focus({
preventScroll: true
});
} catch (e) {
warn(`Could not find the required <Tabs.Content id="${_id}-content" ... /> that provides role="tabpanel"`);
}
}
};
const getContent = key => {
const {
children,
content: _content
} = propsRef.current;
const contentToRender = children || _content;
let content = null;
if (contentToRender) {
if (typeof contentToRender === 'object' && contentToRender[key]) {
content = contentToRender[key];
} else if (typeof contentToRender === 'function') {
content = contentToRender(key);
} else if (React.isValidElement(contentToRender)) {
content = contentToRender;
}
}
if (!content) {
let items = [];
if (Array.isArray(dataRef.current)) {
items = dataRef.current;
} else if (Array.isArray(contentToRender)) {
items = contentToRender;
}
if (items) {
content = items.filter(({
key: k
}) => k && key && k == key).reduce((acc, {
content
}) => content || acc, null);
}
}
if (typeof content === 'function') {
const Component = content;
content = _jsx(Component, {});
}
return content;
};
const renderWrapperRef = useRef(null);
const renderTabsListRef = useRef(null);
const renderContentRef = useRef(null);
const renderTabsRef = useRef(null);
renderWrapperRef.current = ({
children,
...rest
}) => {
const {
className,
class: _className
} = ownProps;
const {
...attributes
} = filterProps(ownProps, tabsDefaultProps);
const params = applySpacing(ownProps, {
...attributes,
className: clsx('dnb-tabs', className, _className)
});
validateDOMAttributes(ownProps, params);
delete params.contentInnerSpace;
delete params.tabsInnerSpace;
return _jsx("div", {
...params,
...rest,
children: children
});
};
renderTabsListRef.current = ({
children,
className: extraClassName,
...rest
}) => {
const {
align,
tabsStyle,
tabsInnerSpace,
noBorder,
navButtonEdge,
breakout
} = propsRef.current;
return _jsxs("div", {
className: clsx('dnb-tabs__tabs', extraClassName, align && `dnb-tabs__tabs--${align}`, tabsStyle && `dnb-section dnb-section--${tabsStyle}`, hasScrollbarRef.current && 'dnb-tabs--has-scrollbar', navButtonEdge && 'dnb-tabs--at-edge', noBorder && 'dnb-tabs__tabs--no-border', breakout && 'dnb-tabs__tabs--breakout'),
ref: tabsRef,
style: tabsInnerSpace ? {
paddingTop: `var(--spacing-${tabsInnerSpace === true ? 'large' : tabsInnerSpace})`
} : undefined,
...rest,
children: [_jsx(ScrollNavButton, {
onMouseDown: openPrevTab,
icon: "chevron_left",
className: clsx(hasScrollbarRef.current && (typeof isFirstRef.current !== 'undefined' || hasLastPosition()) && 'dnb-tabs__scroll-nav-button--visible', isFirstRef.current && 'dnb-tabs__scroll-nav-button--hide')
}), children, _jsx(ScrollNavButton, {
onMouseDown: openNextTab,
icon: "chevron_right",
className: clsx(hasScrollbarRef.current && (typeof isLastRef.current !== 'undefined' || hasLastPosition()) && 'dnb-tabs__scroll-nav-button--visible', isLastRef.current && 'dnb-tabs__scroll-nav-button--hide')
})]
});
};
renderContentRef.current = () => {
const {
preventRerender,
keepInDOM
} = propsRef.current;
const currentSelectedKey = selectedKeyRef.current;
const currentData = dataRef.current;
let content;
if (preventRerender || keepInDOM) {
if (keepInDOM) {
cacheRef.current = Object.entries(currentData).reduce((acc, [_idx, cur]) => {
acc[cur.key] = {
...cur,
content: getContent(cur.key)
};
return acc;
}, {});
} else if (preventRerender) {
cacheRef.current = {
...(cacheRef.current || {}),
[currentSelectedKey]: {
content: getContent(currentSelectedKey)
}
};
}
content = Object.entries(cacheRef.current).map(([key, {
content: cachedContent
}]) => {
const hide = key !== String(currentSelectedKey);
return _jsx("div", {
"aria-hidden": hide ? true : undefined,
className: 'dnb-tabs__cached' + (hide ? " dnb-tabs__cached--hidden" : ""),
children: cachedContent
}, key);
});
} else {
content = getContent(currentSelectedKey);
}
if (!sharedStateRef.current && !content) {
warn(`No content was given to the Tabs component!
Tip: Check out other solutions like <Tabs.Content id="unique">Your content, outside of the Tabs component</Tabs.Content>
`);
}
return _jsx(ContentWrapper, {
id: _id,
selectedKey: currentSelectedKey,
contentStyle: propsRef.current.contentStyle,
contentInnerSpace: propsRef.current.contentInnerSpace,
animate: propsRef.current.keepInDOM,
children: content
});
};
renderTabsRef.current = (extraProps = {}) => {
const mergedProps = propsRef.current;
const {
label,
skeleton,
tabElement
} = {
...mergedProps,
...extraProps
};
const currentData = dataRef.current;
const currentFocusKey = focusKeyRef.current;
const currentSelectedKey = selectedKeyRef.current;
const currentContext = contextRef.current;
const TabElement = tabElement || 'button';
const tabs = currentData.map(({
title,
key,
disabled = false,
to,
href
}) => {
const itemParams = {
to,
href
};
const isFocus = currentFocusKey == key;
const isSelected = currentSelectedKey == key;
if (isSelected) {
itemParams['aria-controls'] = `${_id}-content`;
}
if (disabled) {
itemParams.disabled = true;
itemParams['aria-disabled'] = true;
}
if (TabElement === 'button') {
itemParams.type = 'button';
}
skeletonDOMAttributes(itemParams, skeleton, currentContext);
return _jsx("div", {
className: clsx('dnb-tabs__button__snap', isFocus && 'focus', isSelected && 'selected'),
children: _jsxs(TabElement, {
role: "tab",
tabIndex: -1,
id: `${_id}-tab-${key}`,
"aria-selected": isSelected,
className: clsx('dnb-tabs__button', isFocus && 'focus', isSelected && 'selected'),
onMouseEnter: onMouseEnterHandler,
onClick: onClickHandler,
onKeyUp: onKeyDownHandler,
onMouseDown: onMouseDown,
"data-tab-key": key,
...itemParams,
children: [_jsx("span", {
className: clsx('dnb-tabs__button__title', createSkeletonClass('font', skeleton, currentContext)),
children: title
}), _jsx(Dummy, {
children: title
})]
})
}, `tab-${key}`);
});
const params = {};
if (label) {
params['aria-label'] = label;
}
if (currentSelectedKey) {
params['aria-labelledby'] = combineLabelledBy(params, `${_id}-tab-${currentSelectedKey}`);
}
return _jsx("div", {
role: "tablist",
className: "dnb-tabs__tabs__tablist",
tabIndex: 0,
onKeyDown: onTablistKeyDownHandler,
ref: tablistRef,
...params,
children: tabs
});
};
const Wrapper = useMemo(() => {
const C = p => renderWrapperRef.current(p);
C.displayName = 'TabsWrapper';
return C;
}, []);
const TabsList = useMemo(() => {
const C = p => renderTabsListRef.current(p);
C.displayName = 'TabsList';
return C;
}, []);
const Content = useMemo(() => {
const C = () => renderContentRef.current();
C.displayName = 'TabContent';
return C;
}, []);
const TabItems = useMemo(() => {
const C = p => renderTabsRef.current(p);
C.displayName = 'Tabs';
return C;
}, []);
if (typeof props.render === 'function') {
return props.render({
Wrapper,
Content,
TabsList,
Tabs: TabItems
});
}
return _jsxs(Wrapper, {
children: [_jsx(TabsList, {
children: _jsx(TabItems, {})
}), _jsx(Content, {})]
});
}
TabsComponent.displayName = 'Tabs';
const Tabs = Object.assign(React.memo(TabsComponent), {
Content: CustomContent,
ContentWrapper: ContentWrapper
});
withComponentMarkers(Tabs, {
_supportsSpacingProps: true
});
export default Tabs;
export const Dummy = ({
children
}) => {
return _jsx("span", {
"aria-hidden": true,
hidden: true,
className: "dnb-dummy",
children: children
});
};
const ScrollNavButton = props => {
return _jsx(Button, {
size: "medium",
variant: "primary",
tabIndex: -1,
bounding: true,
"aria-hidden": true,
...props,
className: clsx('dnb-tabs__scroll-nav-button', props.className)
});
};
//# sourceMappingURL=Tabs.js.map