mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tabs: adds counter component (#23548)
* Chore: Initial commit * Initial commit * Refactor: some style changes * Refactor: removes isDark/isLight theme logic * Minor style tweak * Minor style tweak * Minor adjustments * Refactor: changes after PR comments * Refactor: moves margin-left to counter Co-authored-by: Torkel Ödegaard <torkel@grafana.com> Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
parent
ba60be97fe
commit
e64e8dd098
30
packages/grafana-ui/src/components/Tabs/Counter.tsx
Normal file
30
packages/grafana-ui/src/components/Tabs/Counter.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import React, { FC, useContext } from 'react';
|
||||||
|
import { css } from 'emotion';
|
||||||
|
import { stylesFactory, ThemeContext } from '../../themes';
|
||||||
|
import { GrafanaTheme, locale } from '@grafana/data';
|
||||||
|
|
||||||
|
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||||
|
return {
|
||||||
|
counter: css`
|
||||||
|
label: counter;
|
||||||
|
margin-left: ${theme.spacing.sm};
|
||||||
|
border-radius: ${theme.spacing.lg};
|
||||||
|
background-color: ${theme.colors.bg2};
|
||||||
|
padding: ${theme.spacing.xxs} ${theme.spacing.sm};
|
||||||
|
color: ${theme.colors.textWeak};
|
||||||
|
font-weight: ${theme.typography.weight.semibold};
|
||||||
|
font-size: ${theme.typography.size.sm};
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
export interface CounterProps {
|
||||||
|
value: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Counter: FC<CounterProps> = ({ value }) => {
|
||||||
|
const theme = useContext(ThemeContext);
|
||||||
|
const styles = getStyles(theme);
|
||||||
|
|
||||||
|
return <span className={styles.counter}>{locale(value, 0).text}</span>;
|
||||||
|
};
|
@ -4,12 +4,14 @@ import { GrafanaTheme } from '@grafana/data';
|
|||||||
import { Icon } from '../Icon/Icon';
|
import { Icon } from '../Icon/Icon';
|
||||||
import { IconName } from '../../types';
|
import { IconName } from '../../types';
|
||||||
import { stylesFactory, useTheme } from '../../themes';
|
import { stylesFactory, useTheme } from '../../themes';
|
||||||
|
import { Counter } from './Counter';
|
||||||
|
|
||||||
export interface TabProps {
|
export interface TabProps {
|
||||||
label: string;
|
label: string;
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
icon?: IconName;
|
icon?: IconName;
|
||||||
onChangeTab: () => void;
|
onChangeTab: () => void;
|
||||||
|
counter?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTabStyles = stylesFactory((theme: GrafanaTheme) => {
|
const getTabStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||||
@ -57,7 +59,7 @@ const getTabStyles = stylesFactory((theme: GrafanaTheme) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Tab: FC<TabProps> = ({ label, active, icon, onChangeTab }) => {
|
export const Tab: FC<TabProps> = ({ label, active, icon, onChangeTab, counter }) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const tabsStyles = getTabStyles(theme);
|
const tabsStyles = getTabStyles(theme);
|
||||||
|
|
||||||
@ -65,6 +67,7 @@ export const Tab: FC<TabProps> = ({ label, active, icon, onChangeTab }) => {
|
|||||||
<li className={cx(tabsStyles.tabItem, active && tabsStyles.activeStyle)} onClick={onChangeTab}>
|
<li className={cx(tabsStyles.tabItem, active && tabsStyles.activeStyle)} onClick={onChangeTab}>
|
||||||
{icon && <Icon name={icon} />}
|
{icon && <Icon name={icon} />}
|
||||||
{label}
|
{label}
|
||||||
|
{!!counter && <Counter value={counter} />}
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -30,6 +30,7 @@ export const Simple = () => {
|
|||||||
label={tab.label}
|
label={tab.label}
|
||||||
active={tab.active}
|
active={tab.active}
|
||||||
onChangeTab={() => updateState(state.map((tab, idx) => ({ ...tab, active: idx === index })))}
|
onChangeTab={() => updateState(state.map((tab, idx) => ({ ...tab, active: idx === index })))}
|
||||||
|
counter={(index + 1) * 1000}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { config } from 'app/core/config';
|
import { config } from 'app/core/config';
|
||||||
import { css } from 'emotion';
|
import { css } from 'emotion';
|
||||||
import { TabsBar, Tab, stylesFactory, TabContent, IconName } from '@grafana/ui';
|
import { IconName, stylesFactory, Tab, TabContent, TabsBar } from '@grafana/ui';
|
||||||
import { DataTransformerConfig, LoadingState, PanelData } from '@grafana/data';
|
import { DataTransformerConfig, LoadingState, PanelData } from '@grafana/data';
|
||||||
import { PanelEditorTab, PanelEditorTabId } from './types';
|
import { PanelEditorTab, PanelEditorTabId } from './types';
|
||||||
import { DashboardModel } from '../../state';
|
import { DashboardModel } from '../../state';
|
||||||
|
Loading…
Reference in New Issue
Block a user