mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tab: Make active tab clickable and add hyperlink functionality (#25546)
* onChangeTab for active tab and pointer mouse * Add anchor element to tab * Make a strict 'anchor' mode * Add short docs * Apply suggestions from code review Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com> * Fix nits Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
parent
e8e280c83e
commit
615b000acd
@ -11,31 +11,41 @@ import { Counter } from './Counter';
|
||||
export interface TabProps extends HTMLProps<HTMLLIElement> {
|
||||
label: string;
|
||||
active?: boolean;
|
||||
/** When provided, it is possible to use the tab as a hyperlink. Use in cases where the tabs update location. */
|
||||
href?: string;
|
||||
icon?: IconName;
|
||||
onChangeTab: () => void;
|
||||
onChangeTab: (event?: React.MouseEvent<HTMLLIElement>) => void;
|
||||
/** A number rendered next to the text. Usually used to display the number of items in a tab's view. */
|
||||
counter?: number;
|
||||
}
|
||||
|
||||
export const Tab = React.forwardRef<HTMLLIElement, TabProps>(
|
||||
({ label, active, icon, onChangeTab, counter, className, ...otherProps }, ref) => {
|
||||
({ label, active, icon, onChangeTab, counter, className, href, ...otherProps }, ref) => {
|
||||
const theme = useTheme();
|
||||
const tabsStyles = getTabStyles(theme);
|
||||
const content = () => (
|
||||
<>
|
||||
{icon && <Icon name={icon} />}
|
||||
{label}
|
||||
{typeof counter === 'number' && <Counter value={counter} />}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<li
|
||||
{...otherProps}
|
||||
className={cx(tabsStyles.tabItem, active && tabsStyles.activeStyle)}
|
||||
onClick={() => {
|
||||
if (!active) {
|
||||
onChangeTab();
|
||||
}
|
||||
}}
|
||||
className={cx(!href && tabsStyles.padding, tabsStyles.tabItem, active && tabsStyles.activeStyle)}
|
||||
onClick={onChangeTab}
|
||||
aria-label={otherProps['aria-label'] || selectors.components.Tab.title(label)}
|
||||
ref={ref}
|
||||
>
|
||||
{icon && <Icon name={icon} />}
|
||||
{label}
|
||||
{typeof counter === 'number' && <Counter value={counter} />}
|
||||
{href ? (
|
||||
<a href={href} className={tabsStyles.padding}>
|
||||
{content()}
|
||||
</a>
|
||||
) : (
|
||||
<>{content()}</>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
@ -47,7 +57,6 @@ const getTabStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
return {
|
||||
tabItem: css`
|
||||
list-style: none;
|
||||
padding: 11px 15px 9px;
|
||||
margin-right: ${theme.spacing.md};
|
||||
position: relative;
|
||||
display: block;
|
||||
@ -61,18 +70,24 @@ const getTabStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
margin-right: ${theme.spacing.sm};
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: ${colors.linkHover};
|
||||
}
|
||||
`,
|
||||
padding: css`
|
||||
padding: 11px 15px 9px;
|
||||
`,
|
||||
activeStyle: css`
|
||||
label: activeTabStyle;
|
||||
border-color: ${theme.palette.orange} ${colors.pageHeaderBorder} transparent;
|
||||
background: ${colors.bodyBg};
|
||||
color: ${colors.link};
|
||||
overflow: hidden;
|
||||
cursor: default;
|
||||
|
||||
&::before {
|
||||
display: block;
|
||||
|
@ -1,9 +1,12 @@
|
||||
import { Props } from '@storybook/addon-docs/blocks';
|
||||
import { TabsBar } from './TabsBar'
|
||||
import { TabsBar } from './TabsBar';
|
||||
|
||||
# TabBar
|
||||
|
||||
A composition component for rendering a TabBar with Tabs for navigation
|
||||
A composition component for rendering a TabBar with Tabs for navigation.
|
||||
|
||||
It has two modes - navigation and onClick. Navigation renders it as a simple `<a>` element. To enable it, use the `href` prop. The onClick mode uses an onClick handler instead. To enable it, use the `onChangeTab` prop.
|
||||
|
||||
**Warning!** Using `href` and `onChangeTab` at the same time may have unintended consequences.
|
||||
|
||||
<Props of={TabsBar} />
|
||||
|
@ -79,6 +79,7 @@ const Navigation = ({ children }: { children: NavModelItem[] }) => {
|
||||
key={`${child.url}-${index}`}
|
||||
icon={child.icon as IconName}
|
||||
onChangeTab={() => goToUrl(index)}
|
||||
href={child.url}
|
||||
/>
|
||||
)
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user