From 9236719fbc24226183fc06fe7584b05395e641a8 Mon Sep 17 00:00:00 2001
From: Karolina Szarek <74671633+karolinaszarek@users.noreply.github.com>
Date: Mon, 2 Sep 2024 11:54:12 +0200
Subject: [PATCH 1/3] feat: TET-903 add InlineMetrics (#154)
* feat: TET-903 initial commit
* fix: TET-903 fix build error
---
.../InlineMetrics/InlineMetrics.props.ts | 11 +++
.../InlineMetrics/InlineMetrics.stories.tsx | 39 ++++++++++
.../InlineMetrics/InlineMetrics.styles.ts | 76 +++++++++++++++++++
.../InlineMetrics/InlineMetrics.test.tsx | 45 +++++++++++
.../InlineMetrics/InlineMetrics.tsx | 56 ++++++++++++++
src/components/InlineMetrics/index.ts | 3 +
src/components/InlineMetrics/stylesBuilder.ts | 26 +++++++
src/docs-components/InlineMetricsDocs.tsx | 52 +++++++++++++
src/index.ts | 1 +
9 files changed, 309 insertions(+)
create mode 100644 src/components/InlineMetrics/InlineMetrics.props.ts
create mode 100644 src/components/InlineMetrics/InlineMetrics.stories.tsx
create mode 100644 src/components/InlineMetrics/InlineMetrics.styles.ts
create mode 100644 src/components/InlineMetrics/InlineMetrics.test.tsx
create mode 100644 src/components/InlineMetrics/InlineMetrics.tsx
create mode 100644 src/components/InlineMetrics/index.ts
create mode 100644 src/components/InlineMetrics/stylesBuilder.ts
create mode 100644 src/docs-components/InlineMetricsDocs.tsx
diff --git a/src/components/InlineMetrics/InlineMetrics.props.ts b/src/components/InlineMetrics/InlineMetrics.props.ts
new file mode 100644
index 00000000..ab060c82
--- /dev/null
+++ b/src/components/InlineMetrics/InlineMetrics.props.ts
@@ -0,0 +1,11 @@
+import { InlineMetricsConfig } from './InlineMetrics.styles';
+
+export type TrendType = 'None' | 'Positive' | 'Negative';
+
+export type InlineMetricsProps = {
+ metrics?: string;
+ label?: string;
+ trend?: TrendType;
+ trendValue?: string;
+ custom?: InlineMetricsConfig;
+};
diff --git a/src/components/InlineMetrics/InlineMetrics.stories.tsx b/src/components/InlineMetrics/InlineMetrics.stories.tsx
new file mode 100644
index 00000000..5d9dd31f
--- /dev/null
+++ b/src/components/InlineMetrics/InlineMetrics.stories.tsx
@@ -0,0 +1,39 @@
+import type { Meta, StoryObj } from '@storybook/react';
+
+import { InlineMetrics } from './InlineMetrics';
+
+import { InlineMetricsDocs } from '@/docs-components/InlineMetricsDocs';
+import { TetDocs } from '@/docs-components/TetDocs';
+
+const meta = {
+ title: 'Metrics / InlineMetrics',
+ component: InlineMetrics,
+ tags: ['autodocs'],
+ args: {},
+ parameters: {
+ backgrounds: {},
+ docs: {
+ description: {
+ component:
+ 'A set of several grouped components that displays numerical data, such as, for example, key performance indicators (KPIs). Metrics provide users with a clear, visual representation of essential statistics or progress.',
+ },
+ page: () => (
+
+
+
+ ),
+ },
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ trend: 'Negative',
+ trendValue: '+24%',
+ metrics: '$123.12',
+ label: 'Total Earnings',
+ },
+};
diff --git a/src/components/InlineMetrics/InlineMetrics.styles.ts b/src/components/InlineMetrics/InlineMetrics.styles.ts
new file mode 100644
index 00000000..5210eff1
--- /dev/null
+++ b/src/components/InlineMetrics/InlineMetrics.styles.ts
@@ -0,0 +1,76 @@
+import type { TrendType } from './InlineMetrics.props';
+
+import type { BaseProps } from '@/types/BaseProps';
+import { IconName } from '@/utility-types/IconName';
+
+export type InlineMetricsConfig = {
+ innerElements: {
+ label: BaseProps;
+ metric: BaseProps;
+ trendContainer: BaseProps;
+ trend: { trend: Partial> } & BaseProps;
+ icon: BaseProps;
+ trendValue: BaseProps;
+ };
+} & BaseProps;
+
+export const defaultConfig = {
+ w: 'fill',
+ h: '',
+ display: 'flex',
+ flexDirection: 'column',
+ innerElements: {
+ trendContainer: {
+ display: 'flex',
+ color: '$color-content-primary',
+ gap: '$space-component-gap-medium',
+ },
+ label: {
+ color: '$color-content-secondary',
+ text: '$typo-body-medium',
+ marginBottom: '$space-component-gap-medium',
+ },
+ metric: {
+ text: '$typo-header-4xLarge',
+ color: '$color-content-primary',
+ },
+ trend: {
+ gap: '$space-component-gap-small',
+ padding: '$space-component-padding-xSmall 0',
+ display: 'flex',
+ alignItems: 'center',
+ alignSelf: 'flex-end',
+ trend: {
+ None: {},
+ Positive: {
+ color: '$color-content-positive-secondary',
+ },
+ Negative: {
+ color: '$color-content-negative-secondary',
+ },
+ },
+ },
+ icon: {
+ display: 'flex',
+ },
+ trendValue: {
+ text: '$typo-body-strong-medium',
+ display: 'flex',
+ alignItems: 'end',
+ },
+ },
+} satisfies InlineMetricsConfig;
+
+export const inlineMetricsStyles = {
+ defaultConfig,
+};
+
+export const resolveIconName = (trend: TrendType) => {
+ const iconConfig = {
+ None: '20-minus',
+ Positive: '20-trend-up',
+ Negative: '20-trend-down',
+ } satisfies Record>;
+
+ return iconConfig[trend];
+};
diff --git a/src/components/InlineMetrics/InlineMetrics.test.tsx b/src/components/InlineMetrics/InlineMetrics.test.tsx
new file mode 100644
index 00000000..73e7825b
--- /dev/null
+++ b/src/components/InlineMetrics/InlineMetrics.test.tsx
@@ -0,0 +1,45 @@
+import { InlineMetrics } from './InlineMetrics';
+import { render } from '../../tests/render';
+
+import { customPropTester } from '@/tests/customPropTester';
+
+const getInlineMetrics = (jsx: JSX.Element) => {
+ const { getByTestId } = render(jsx);
+ return {
+ container: getByTestId('inline-metrics'),
+ trendContainer: getByTestId('inline-metrics-trend'),
+ };
+};
+
+describe('Inline Metrics', () => {
+ customPropTester(, {
+ containerId: 'inline-metrics',
+ props: {
+ trend: ['Negative', 'None', 'Positive'],
+ },
+ });
+
+ it('should render the inline metrics', () => {
+ const { container } = getInlineMetrics();
+ expect(container).toBeInTheDocument();
+ });
+
+ it('should render the inline metrics with trend with proper color (Positive)', () => {
+ const { trendContainer } = getInlineMetrics(
+ ,
+ );
+ expect(trendContainer).toHaveStyle('color: rgb(29, 124, 77)');
+ });
+
+ it('should render the inline metrics with trend with proper color (None)', () => {
+ const { trendContainer } = getInlineMetrics();
+ expect(trendContainer).toHaveStyle('color: rgb(39, 46, 53)');
+ });
+
+ it('should render the inline metrics with trend with proper color (Negative)', () => {
+ const { trendContainer } = getInlineMetrics(
+ ,
+ );
+ expect(trendContainer).toHaveStyle('color: rgb(197, 52, 52)');
+ });
+});
diff --git a/src/components/InlineMetrics/InlineMetrics.tsx b/src/components/InlineMetrics/InlineMetrics.tsx
new file mode 100644
index 00000000..aff774ac
--- /dev/null
+++ b/src/components/InlineMetrics/InlineMetrics.tsx
@@ -0,0 +1,56 @@
+import { Icon } from '@virtuslab/tetrisly-icons';
+import { MarginProps } from '@xstyled/styled-components';
+import { type FC, useMemo } from 'react';
+
+import { InlineMetricsProps } from './InlineMetrics.props';
+import { resolveIconName } from './InlineMetrics.styles';
+import { stylesBuilder } from './stylesBuilder';
+import { Label } from '../Label';
+
+import { tet } from '@/tetrisly';
+
+export const InlineMetrics: FC = ({
+ metrics,
+ label,
+ trend = 'None',
+ trendValue,
+ custom,
+ ...restProps
+}) => {
+ const styles = useMemo(
+ () => stylesBuilder({ trend, custom }),
+ [trend, custom],
+ );
+
+ const iconName = useMemo(() => resolveIconName(trend), [trend]);
+
+ return (
+
+ {label && (
+
+ )}
+
+
+
+ {metrics}
+
+
+
+
+ {trendValue}
+
+
+
+
+ );
+};
diff --git a/src/components/InlineMetrics/index.ts b/src/components/InlineMetrics/index.ts
new file mode 100644
index 00000000..c35225aa
--- /dev/null
+++ b/src/components/InlineMetrics/index.ts
@@ -0,0 +1,3 @@
+export { InlineMetrics } from './InlineMetrics';
+export type { InlineMetricsProps } from './InlineMetrics.props';
+export { inlineMetricsStyles } from './InlineMetrics.styles';
diff --git a/src/components/InlineMetrics/stylesBuilder.ts b/src/components/InlineMetrics/stylesBuilder.ts
new file mode 100644
index 00000000..1b59d602
--- /dev/null
+++ b/src/components/InlineMetrics/stylesBuilder.ts
@@ -0,0 +1,26 @@
+import { InlineMetricsProps, TrendType } from './InlineMetrics.props';
+import { defaultConfig } from './InlineMetrics.styles';
+
+import { mergeConfigWithCustom } from '@/services';
+
+type StylesBuilderParams = {
+ trend: TrendType;
+ custom: InlineMetricsProps['custom'];
+};
+
+export const stylesBuilder = ({ trend, custom }: StylesBuilderParams) => {
+ const { innerElements, ...restStyles } = mergeConfigWithCustom({
+ defaultConfig,
+ custom,
+ });
+ const { trend: trendContainer } = innerElements;
+ const { trend: trendStyles, ...restTrendStyles } = trendContainer;
+
+ const trendContainerStyles = { ...trendStyles[trend], ...restTrendStyles };
+
+ return {
+ container: restStyles,
+ ...innerElements,
+ trend: trendContainerStyles,
+ };
+};
diff --git a/src/docs-components/InlineMetricsDocs.tsx b/src/docs-components/InlineMetricsDocs.tsx
new file mode 100644
index 00000000..94989262
--- /dev/null
+++ b/src/docs-components/InlineMetricsDocs.tsx
@@ -0,0 +1,52 @@
+import { InlineMetrics } from '@/components/InlineMetrics/InlineMetrics';
+import { TrendType } from '@/components/InlineMetrics/InlineMetrics.props';
+import { tet } from '@/tetrisly';
+
+const trends: TrendType[] = ['None', 'Positive', 'Negative'];
+const intentNames: Record = {
+ None: 'Neutral',
+ Positive: 'Positive',
+ Negative: 'Negative',
+};
+
+export const InlineMetricsDocs = () => (
+
+
+
+ {trends.map((trend) => (
+
+
+ Intent: {intentNames[trend]}
+
+
+
+
+
+ ))}
+
+
+
+);
diff --git a/src/index.ts b/src/index.ts
index fcc44c65..f4d1ef90 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -14,6 +14,7 @@ export * from './components/Icon';
export * from './components/IconButton';
export * from './components/InlineBanner';
export * from './components/InlineMessage';
+export * from './components/InlineMetrics';
export * from './components/InlineSearchInput';
export * from './components/Label';
export * from './components/Loader';
From d48dd7fb67a026ae550d739717b3d1d292bdfa2a Mon Sep 17 00:00:00 2001
From: Karolina Szarek <74671633+karolinaszarek@users.noreply.github.com>
Date: Mon, 2 Sep 2024 11:55:47 +0200
Subject: [PATCH 2/3] feat: TET-848 add button group (#160)
* feat: TET-848 add ButtonGroup component
* feat: TET-848 add tests and fix a bug
* feat: TET-848 add export
* feat: TET-848 resolve build problems
---
.../ButtonGroup/ButtonGroup.props.ts | 9 +++
.../ButtonGroup/ButtonGroup.stories.tsx | 47 +++++++++++++++
.../ButtonGroup/ButtonGroup.styles.ts | 50 ++++++++++++++++
.../ButtonGroup/ButtonGroup.test.tsx | 41 +++++++++++++
src/components/ButtonGroup/ButtonGroup.tsx | 58 +++++++++++++++++++
src/components/ButtonGroup/index.ts | 3 +
src/components/ButtonGroup/stylesBuilder.ts | 31 ++++++++++
src/docs-components/ButtonGroupDocs.tsx | 58 +++++++++++++++++++
src/index.ts | 1 +
9 files changed, 298 insertions(+)
create mode 100644 src/components/ButtonGroup/ButtonGroup.props.ts
create mode 100644 src/components/ButtonGroup/ButtonGroup.stories.tsx
create mode 100644 src/components/ButtonGroup/ButtonGroup.styles.ts
create mode 100644 src/components/ButtonGroup/ButtonGroup.test.tsx
create mode 100644 src/components/ButtonGroup/ButtonGroup.tsx
create mode 100644 src/components/ButtonGroup/index.ts
create mode 100644 src/components/ButtonGroup/stylesBuilder.ts
create mode 100644 src/docs-components/ButtonGroupDocs.tsx
diff --git a/src/components/ButtonGroup/ButtonGroup.props.ts b/src/components/ButtonGroup/ButtonGroup.props.ts
new file mode 100644
index 00000000..fb4f1751
--- /dev/null
+++ b/src/components/ButtonGroup/ButtonGroup.props.ts
@@ -0,0 +1,9 @@
+import { HTMLAttributes } from 'react';
+
+import { ButtonGroupConfig } from './ButtonGroup.styles';
+
+export type ButtonGroupSize = 'medium' | 'small';
+export type ButtonGroupProps = {
+ size?: ButtonGroupSize;
+ custom?: ButtonGroupConfig;
+} & Omit, 'color'>;
diff --git a/src/components/ButtonGroup/ButtonGroup.stories.tsx b/src/components/ButtonGroup/ButtonGroup.stories.tsx
new file mode 100644
index 00000000..6cd146b2
--- /dev/null
+++ b/src/components/ButtonGroup/ButtonGroup.stories.tsx
@@ -0,0 +1,47 @@
+import type { Meta, StoryObj } from '@storybook/react';
+
+import { ButtonGroup } from './ButtonGroup';
+import { Button } from '../Button/Button';
+
+import { ButtonGroupDocs } from '@/docs-components/ButtonGroupDocs';
+import { TetDocs } from '@/docs-components/TetDocs';
+
+const meta = {
+ title: 'ButtonGroup',
+ component: ButtonGroup,
+ tags: ['autodocs'],
+ argTypes: {
+ size: {
+ options: ['small', 'medium'],
+ defaultValue: 'medium',
+ control: { type: 'radio' },
+ },
+ },
+ parameters: {
+ docs: {
+ description: {
+ component:
+ 'A set of related buttons that are visually and functionally grouped. Button Group acts as a cohesive unit, providing users with clear options for actions or navigation.',
+ },
+ page: () => (
+
+
+
+ ),
+ },
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ children: [
+ ,
+ ,
+ ,
+ ,
+ ],
+ },
+};
diff --git a/src/components/ButtonGroup/ButtonGroup.styles.ts b/src/components/ButtonGroup/ButtonGroup.styles.ts
new file mode 100644
index 00000000..514b14e4
--- /dev/null
+++ b/src/components/ButtonGroup/ButtonGroup.styles.ts
@@ -0,0 +1,50 @@
+import { BaseProps } from '@/types';
+
+export type ButtonGroupConfig = {
+ button: {
+ size: {
+ medium: BaseProps;
+ small: BaseProps;
+ };
+ } & BaseProps;
+} & BaseProps;
+
+export const defaultConfig = {
+ display: 'inline-flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ button: {
+ color: {
+ _: '$color-action-neutral-normal',
+ hover: '$color-action-neutral-hover',
+ },
+ backgroundColor: {
+ _: '$color-action-inverted-normal',
+ active: '$color-action-ghost-active',
+ hover: '$color-action-ghost-hover',
+ selected: '$color-action-ghost-selected',
+ },
+ ringColor: '$color-action-outline-normal',
+ size: {
+ // TODO think if it can be done by passing size prop to a button component
+ medium: {
+ h: '$size-medium',
+ px: '$space-component-padding-large',
+ },
+ small: {
+ h: '$size-small',
+ px: '$space-component-padding-medium',
+ },
+ },
+ borderRadius: {
+ first: `$border-radius-large 0px 0px $border-radius-large`,
+ last: `0px $border-radius-large $border-radius-large 0px`,
+ },
+ transition: true,
+ transitionDuration: 200,
+ },
+} as const satisfies ButtonGroupConfig;
+
+export const buttonGroupStyles = {
+ defaultConfig,
+};
diff --git a/src/components/ButtonGroup/ButtonGroup.test.tsx b/src/components/ButtonGroup/ButtonGroup.test.tsx
new file mode 100644
index 00000000..52638400
--- /dev/null
+++ b/src/components/ButtonGroup/ButtonGroup.test.tsx
@@ -0,0 +1,41 @@
+import { render } from '../../tests/render';
+
+import { ButtonGroup } from '.';
+
+import { customPropTester } from '@/tests/customPropTester';
+
+// TODO
+
+const getButtonGroup = (jsx: JSX.Element) => {
+ const { getByTestId } = render(jsx);
+ return {
+ buttonGroup: getByTestId('button-group'),
+ };
+};
+describe('ButtonGroup', () => {
+ it('should render the ButtonGroup ', () => {
+ const { buttonGroup } = getButtonGroup();
+ expect(buttonGroup).toBeInTheDocument();
+ });
+
+ it('should render correct number of children', () => {
+ const { buttonGroup } = getButtonGroup(
+
+
+
+
+
+
+ ,
+ );
+
+ expect(buttonGroup?.children.length).toEqual(5);
+ });
+
+ customPropTester(, {
+ containerId: 'button-group',
+ props: {
+ options: ['small', 'medium'],
+ },
+ });
+});
diff --git a/src/components/ButtonGroup/ButtonGroup.tsx b/src/components/ButtonGroup/ButtonGroup.tsx
new file mode 100644
index 00000000..83ff7103
--- /dev/null
+++ b/src/components/ButtonGroup/ButtonGroup.tsx
@@ -0,0 +1,58 @@
+import { MarginProps } from '@xstyled/styled-components';
+import {
+ Children,
+ cloneElement,
+ isValidElement,
+ PropsWithChildren,
+ useMemo,
+ type FC,
+} from 'react';
+
+import { ButtonGroupProps } from './ButtonGroup.props';
+import { stylesBuilder } from './stylesBuilder';
+import { Button, ButtonProps } from '../Button';
+
+import { tet } from '@/tetrisly';
+
+type Props = FC> & {
+ Item: FC;
+};
+
+export const ButtonGroup: Props = ({
+ size = 'medium',
+ children,
+ custom,
+ ...rest
+}) => {
+ const styles = useMemo(
+ () =>
+ stylesBuilder({
+ size,
+ custom,
+ }),
+ [custom, size],
+ );
+
+ Children.forEach(children, (child) => {
+ if (isValidElement(child) && child?.type !== ButtonGroup.Item) {
+ console.error(
+ 'You should use only ButtonGroup.Item as a child of a CheckboxGroup component.',
+ );
+ }
+ });
+
+ const childrenWithProps = Children.map(children, (child) => {
+ if (isValidElement(child)) {
+ return cloneElement(child, { ...styles.button });
+ }
+ return child;
+ });
+
+ return (
+
+ {childrenWithProps}
+
+ );
+};
+
+ButtonGroup.Item = Button;
diff --git a/src/components/ButtonGroup/index.ts b/src/components/ButtonGroup/index.ts
new file mode 100644
index 00000000..fb07bc2f
--- /dev/null
+++ b/src/components/ButtonGroup/index.ts
@@ -0,0 +1,3 @@
+export { ButtonGroup } from './ButtonGroup';
+export type { ButtonGroupProps } from './ButtonGroup.props';
+export { buttonGroupStyles } from './ButtonGroup.styles';
diff --git a/src/components/ButtonGroup/stylesBuilder.ts b/src/components/ButtonGroup/stylesBuilder.ts
new file mode 100644
index 00000000..e1402225
--- /dev/null
+++ b/src/components/ButtonGroup/stylesBuilder.ts
@@ -0,0 +1,31 @@
+import type { ButtonGroupSize } from './ButtonGroup.props';
+import { ButtonGroupConfig, defaultConfig } from './ButtonGroup.styles';
+
+import { mergeConfigWithCustom } from '@/services';
+import { BaseProps } from '@/types/BaseProps';
+
+type ButtonGroupStyleBuilder = {
+ container: BaseProps;
+ button: BaseProps;
+};
+
+type ButtonGroupStyleBuilderInput = {
+ size: ButtonGroupSize;
+ custom?: ButtonGroupConfig;
+};
+
+export const stylesBuilder = ({
+ size,
+ custom,
+}: ButtonGroupStyleBuilderInput): ButtonGroupStyleBuilder => {
+ const { button, ...container } = mergeConfigWithCustom({
+ defaultConfig,
+ custom,
+ });
+ const buttonStyles = { ...button, ...button.size[size] };
+
+ return {
+ container,
+ button: buttonStyles,
+ };
+};
diff --git a/src/docs-components/ButtonGroupDocs.tsx b/src/docs-components/ButtonGroupDocs.tsx
new file mode 100644
index 00000000..2222994b
--- /dev/null
+++ b/src/docs-components/ButtonGroupDocs.tsx
@@ -0,0 +1,58 @@
+import { FC } from 'react';
+import { v4 as uuidv4 } from 'uuid';
+
+import { SectionHeader } from './common/SectionHeader';
+
+import { Button } from '@/components/Button';
+import { ButtonGroup } from '@/components/ButtonGroup';
+import { tet } from '@/tetrisly';
+
+const items = [4, 3, 2] as const;
+const sizes = ['medium', 'small'] as const;
+
+export const ButtonGroupDocs: FC = () => (
+ <>
+ {items.map((item) => (
+
+
+ {item} items
+
+ {sizes.map((size) => (
+
+
+ Size: {size === 'medium' ? 'Medium (Default)' : 'Small'}
+
+
+
+ {[...Array(item)].map(() => {
+ const id = uuidv4();
+ return (
+
+ );
+ })}
+
+
+
+ ))}
+
+ ))}
+ >
+);
diff --git a/src/index.ts b/src/index.ts
index f4d1ef90..55f0c675 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,6 +3,7 @@ export * from './components/Avatar';
export * from './components/Badge';
export * from './components/BooleanPill';
export * from './components/Button';
+export * from './components/ButtonGroup';
export * from './components/Checkbox';
export * from './components/CheckboxGroup';
export * from './components/CornerDialog';
From 7250e0a2cc393462f1b5c81524679ec90bc795d0 Mon Sep 17 00:00:00 2001
From: Karolina Szarek <74671633+karolinaszarek@users.noreply.github.com>
Date: Mon, 2 Sep 2024 15:31:56 +0200
Subject: [PATCH 3/3] feat: TET-868 add tooltip (#153)
* feat: TET-868 add Tooltip component
* feat: TET-868 improve tooltip
* feat: TET-868 add export to index file
* feat: TET-868 add tests
* feat: TET-868 fix reccurency
* feat: TET-868 update tooltip component
* feat: TET-868 add Tooltip to Label component
* feat: TET-868 adjust styling
* feat: TET-868 resolve edge case
* feat: TET-868 adjust documentation
* feat: TET-868 add tests and add small fixes
* feat: TET-868 review changes
* feat: TET-868 review changes
---
src/components/Label/Label.styles.ts | 1 +
src/components/Label/Label.tsx | 10 +-
src/components/Tooltip/Arrow.tsx | 84 +++++++++
src/components/Tooltip/Tooltip.props.ts | 11 ++
src/components/Tooltip/Tooltip.stories.tsx | 75 ++++++++
src/components/Tooltip/Tooltip.styles.ts | 63 +++++++
src/components/Tooltip/Tooltip.test.tsx | 196 +++++++++++++++++++++
src/components/Tooltip/Tooltip.tsx | 105 +++++++++++
src/components/Tooltip/TooltipElement.tsx | 68 +++++++
src/components/Tooltip/index.ts | 2 +
src/components/Tooltip/stylesBuilder.ts | 58 ++++++
src/components/Tooltip/useOpacity.ts | 11 ++
src/components/Tooltip/utils.ts | 117 ++++++++++++
src/docs-components/TooltipDocs.tsx | 74 ++++++++
src/index.ts | 1 +
15 files changed, 873 insertions(+), 3 deletions(-)
create mode 100644 src/components/Tooltip/Arrow.tsx
create mode 100644 src/components/Tooltip/Tooltip.props.ts
create mode 100644 src/components/Tooltip/Tooltip.stories.tsx
create mode 100644 src/components/Tooltip/Tooltip.styles.ts
create mode 100644 src/components/Tooltip/Tooltip.test.tsx
create mode 100644 src/components/Tooltip/Tooltip.tsx
create mode 100644 src/components/Tooltip/TooltipElement.tsx
create mode 100644 src/components/Tooltip/index.ts
create mode 100644 src/components/Tooltip/stylesBuilder.ts
create mode 100644 src/components/Tooltip/useOpacity.ts
create mode 100644 src/components/Tooltip/utils.ts
create mode 100644 src/docs-components/TooltipDocs.tsx
diff --git a/src/components/Label/Label.styles.ts b/src/components/Label/Label.styles.ts
index 8df71119..2c9a3f54 100644
--- a/src/components/Label/Label.styles.ts
+++ b/src/components/Label/Label.styles.ts
@@ -20,6 +20,7 @@ export const defaultConfig = {
display: 'flex',
alignItems: 'center',
minHeight: '$size-xSmall',
+ justifyContent: 'center',
},
optional: {
color: '$color-content-tertiary',
diff --git a/src/components/Label/Label.tsx b/src/components/Label/Label.tsx
index 54d4af35..baf1f746 100644
--- a/src/components/Label/Label.tsx
+++ b/src/components/Label/Label.tsx
@@ -4,6 +4,7 @@ import { type FC, useMemo } from 'react';
import type { LabelProps } from './Label.props';
import { stylesBuilder } from './stylesBuilder';
import { Button } from '../Button';
+import { Tooltip } from '../Tooltip';
import { tet } from '@/tetrisly';
import type { MarginProps } from '@/types/MarginProps';
@@ -26,11 +27,14 @@ export const Label: FC = ({
{optional}
)}
- {/* TODO: add tooltip instead of bare icon, when we get one */}
{tooltip && (
-
+
-
+
)}
{!!action && (