Skip to content

Commit

Permalink
Jmainguy/chore/ds no reakit/fixes (#4797)
Browse files Browse the repository at this point in the history
review
  • Loading branch information
jmainguytalend authored Jul 18, 2023
1 parent 1f2260a commit b0c6b30
Show file tree
Hide file tree
Showing 20 changed files with 175 additions and 84 deletions.
36 changes: 33 additions & 3 deletions packages/design-system/src/components/Combobox/Combobox.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { useState, useCallback, useEffect } from 'react';
import {
useState,
useCallback,
useEffect,
useRef,

Check warning on line 5 in packages/design-system/src/components/Combobox/Combobox.tsx

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

packages/design-system/src/components/Combobox/Combobox.tsx#L5

[@typescript-eslint/no-unused-vars] 'useRef' is defined but never used.
DetailedHTMLProps,

Check warning on line 6 in packages/design-system/src/components/Combobox/Combobox.tsx

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

packages/design-system/src/components/Combobox/Combobox.tsx#L6

[@typescript-eslint/no-unused-vars] 'DetailedHTMLProps' is defined but never used.
HTMLAttributes,

Check warning on line 7 in packages/design-system/src/components/Combobox/Combobox.tsx

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

packages/design-system/src/components/Combobox/Combobox.tsx#L7

[@typescript-eslint/no-unused-vars] 'HTMLAttributes' is defined but never used.
FocusEvent,
} from 'react';
import { useTranslation } from 'react-i18next';

import { useId } from '../../useId';
import { I18N_DOMAIN_DESIGN_SYSTEM } from '../constants';

import styles from './Combobox.module.scss';
import { useId } from '../../useId';

export type ComboboxProps = {
id?: string;
Expand All @@ -23,6 +33,9 @@ const Combobox = ({ values, ...rest }: ComboboxProps) => {
setShow(false);
}
}, []);

let comboboxRef: HTMLDivElement | null = null;

// const combobox = useReakitComboboxState({
// autoSelect: true,
// inline: true,
Expand All @@ -42,8 +55,22 @@ const Combobox = ({ values, ...rest }: ComboboxProps) => {
}
}, [value, values]);

const onFocusOut = (event: FocusEvent<HTMLDivElement, Element>) => {
// Check if where user clicks out is part of combobox
let relatedTarget = event.relatedTarget;
while (relatedTarget !== null && relatedTarget !== comboboxRef) {
relatedTarget = relatedTarget.parentElement;
}

// If relatedTarget is null, it means we reach top level component without finding combobox div
// So we are sure user doesn't click in part of combobox
if (relatedTarget === null) {
setShow(false);
}
};

return (
<div className={styles.combobox}>
<div className={styles.combobox} ref={ref => (comboboxRef = ref)} onBlur={onFocusOut}>
<input
className={styles.combobox__input}
id={id}
Expand All @@ -52,6 +79,9 @@ const Combobox = ({ values, ...rest }: ComboboxProps) => {
aria-expanded={show}
onKeyDown={onKeydown}
onFocus={() => setShow(true)}
onClick={() => {
if (!show) setShow(true);
}}
aria-controls={boxId}
value={value}
placeholder={t('COMBOBOX_PLACEHOLDER', 'Search')}
Expand Down
4 changes: 3 additions & 1 deletion packages/design-system/src/components/Divider/Divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ export type DividerHTMLProps = HTMLAttributes<HTMLHRElement> & RefAttributes<HTM
export type DividerProps = DividerOptions & DividerHTMLProps;

const Divider = forwardRef((props: DividerProps, ref: Ref<HTMLHRElement>) => {
return <hr {...props} aria-orientation={props.orientation} ref={ref} className={style.divider} />;
const ruleOrientation = props.orientation || 'horizontal';

return <hr {...props} aria-orientation={ruleOrientation} ref={ref} className={style.divider} />;
});

Divider.displayName = 'Divider';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import { forwardRef, HTMLAttributes, ReactNode, Ref } from 'react';

import { DataAttributes } from '../../../types';
import { TabState } from './TabState';
import { TabStateReturn } from './TabState';

export type TabPanelPropsTypesWithoutState = DataAttributes &
HTMLAttributes<HTMLDivElement> & { children: ReactNode | ReactNode[] };

type TabPanelPropsTypes = TabPanelPropsTypesWithoutState &
TabState & {
TabStateReturn & {
id: string;
};

const TabPanel = forwardRef((props: TabPanelPropsTypes, ref: Ref<HTMLDivElement>) => {
// Extract selectedId & setSelectedId from props to pass rest to div element
const { selectedId, setSelectedId, ...rest } = props;

if (props.id !== props.selectedId) {
return null;
}

return (
<div {...props} ref={ref} role="tabpanel" tabIndex={0}>
<div {...rest} ref={ref} role="tabpanel" tabIndex={0}>
{props.children}
</div>
);
Expand Down
22 changes: 19 additions & 3 deletions packages/design-system/src/components/Tabs/Primitive/TabState.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useState, useEffect } from 'react';
import { randomUUID } from '@talend/utils';

// eslint-disable-next-line @talend/import-depth
import { IconNameWithSize } from '@talend/icons/dist/typeUtils';
import { randomUUID } from '@talend/utils';

import { DataAttributes } from '../../../types';

export type TabWithIdPropTypes = DataAttributes & {
Expand All @@ -21,6 +23,7 @@ export type TabPropTypes = Omit<TabWithIdPropTypes, 'id'> & {
export type TabsPropTypes = {
tabs: TabPropTypes[];
size?: 'M' | 'L';
selectedId?: string;
};

export type TabState = {
Expand Down Expand Up @@ -78,15 +81,28 @@ export function useTabState(initialState?: TabInitialState): TabStateReturn {
if (hasChanged) {
setPanels(getPanels(initialState?.tabs ?? []));
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [panels, initialState?.tabs]);
}, [initialState?.tabs]);

useEffect(() => {
if (selectedId !== initialState?.selectedId && initialState?.selectedId) {
setSelectedId(initialState?.selectedId);
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [initialState?.selectedId]);

useEffect(() => {
if (selectedId === undefined) {
if (panels.length) {
setSelectedId(panels[0].id);
}
}
}, [selectedId, panels]);

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [panels]);

return {
selectedId,
setSelectedId,
Expand Down
5 changes: 3 additions & 2 deletions packages/design-system/src/components/Tabs/Tabs.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BrowserRouter, Link as RouterLink } from 'react-router-dom';

import {
TabsAsLinkList,
StackHorizontal,
Expand Down Expand Up @@ -225,7 +226,7 @@ export const TabStandaloneLarge = () => (
);

export const TabsWithComposition = () => (
<TabsKit>
<TabsKit selectedId="one">
<TabsKit.TabList>
<TabsKit.Tab id="one" tooltip="Tab title that hits the size limit should get a tooltip">
Tab title that hits the size limit should get a tooltip
Expand All @@ -246,7 +247,7 @@ export const TabsWithComposition = () => (
);

export const TabsWithCompositionLarge = () => (
<TabsKit>
<TabsKit selectedId="one">
<TabsKit.TabList>
<TabsKit.Tab
id="one"
Expand Down
41 changes: 32 additions & 9 deletions packages/design-system/src/components/Tabs/variants/TabsKit.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { createContext, forwardRef, ReactNode, Ref, useContext, useMemo } from 'react';
import { TabStateReturn, useTabState } from '../Primitive/TabState';
import TabList from '../Primitive/TabList';

import { IconNameWithSize } from '@talend/icons';

import Tab from '../Primitive/Tab';
import TabList from '../Primitive/TabList';
import TabPanel from '../Primitive/TabPanel';
import { TabStateReturn, useTabState } from '../Primitive/TabState';

export type TabsProps = {
children: ReactNode | ReactNode[];
Expand All @@ -21,16 +24,36 @@ type TabComponentProps = {
size?: 'M' | 'L';
id: string;
tooltip?: string;
};

type TabComponentPropsWithChildren = TabComponentProps & {
children: ReactNode | ReactNode[];

title?: never;
icon?: never;
tag?: never;
};

const TabComponent = forwardRef((props: TabComponentProps, ref: Ref<HTMLButtonElement>) => {
const tabs = useContext(TabsContext);
if (!tabs) {
return null;
}
return <Tab {...tabs} ref={ref} {...props} />;
});
type TabComponentPropsWithTitleProps = TabComponentProps & {
title: string;
icon?: IconNameWithSize<'S'>;
tag?: string | number;

children?: never;
};

const TabComponent = forwardRef(
(
props: TabComponentPropsWithChildren | TabComponentPropsWithTitleProps,
ref: Ref<HTMLButtonElement>,
) => {
const tabs = useContext(TabsContext);
if (!tabs) {
return null;
}
return <Tab {...tabs} ref={ref} {...props} />;
},
);
TabComponent.displayName = 'Tab';

type TabPanelProps = {
Expand Down
6 changes: 5 additions & 1 deletion packages/design-system/src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { cloneElement, useState, useRef } from 'react';
import type { PropsWithChildren } from 'react';

import {
arrow,
FloatingArrow,
Expand All @@ -16,8 +17,11 @@ import {
offset,
shift,
} from '@floating-ui/react';

import { useId } from '../../useId';

import styles from './Tooltip.module.scss';

export type Placement =
| 'auto-start'
| 'auto'
Expand Down Expand Up @@ -53,7 +57,7 @@ const Tooltip = ({ id, children, title, placement = 'top', ...rest }: TooltipPro
arrow({
element: arrowRef,
}),
offset(4),
offset(10),
flip({
crossAxis: placement.includes('-'),
fallbackAxisSideDirection: 'start',
Expand Down
14 changes: 3 additions & 11 deletions packages/design-system/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
{
"extends": "@talend/scripts-config-typescript/tsconfig.json",
"include": [
"../../node_modules/cypress",
"cypress/**/*",
".storybook/docs/**/*",
"src/**/*",
"custom.d.ts"
],
"include": ["../../node_modules/cypress", "cypress/**/*", "src/**/*", "custom.d.ts"],
"files": [],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~docs": [".storybook/docs"]
},
"paths": {},
"module": "CommonJs",
"rootDirs": [".storybook", "cypress", "@testing-library/cypress", "src"],
"rootDirs": ["cypress", "@testing-library/cypress", "src"],
"types": ["cypress"]
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import type { HTMLAttributes } from 'react';

import { StackVertical, TabsKit } from '@talend/design-system';
import { ColorToken, Token, TokenType } from '../../../../src/tokens/types';
import { TokensProps } from '../TokensTypes';

import ColorCompositions from './data/ColorCompositions.json';

import { ColorToken, TokenType } from '../../../../src/tokens/types';
import { groupBy } from '../TokenFormatter';
import { TokensProps } from '../TokensTypes';
import CompositionListItem from '../components/CompositionList/CompositionListItem';
import ColorCompositions from './data/ColorCompositions.json';

type ColorComposition = {
icon?: string;
Expand All @@ -17,11 +15,12 @@ type ColorComposition = {
border: string;
};

const SemanticColors = ['Accent', 'Danger', 'Warning', 'Success', 'Beta'];

const ColorTokens = ({ tokens, ...rest }: HTMLAttributes<HTMLDivElement> & TokensProps) => {
const ColorTokens = ({
tokens,
...rest
}: HTMLAttributes<HTMLDivElement> & TokensProps<ColorToken>) => {
const colorTokens = tokens
.filter((t: Token) => [TokenType.COLOR, TokenType.GRADIENT].includes(t.type))
.filter(t => [TokenType.COLOR, TokenType.GRADIENT].includes(t.type))
.reduce((acc: Record<string, ColorToken>, curr: ColorToken) => {
acc[curr.name.replace('coral', '').replace('Color', '').replace('Gradient', '')] = curr;
return acc;
Expand Down Expand Up @@ -90,25 +89,25 @@ const ColorTokens = ({ tokens, ...rest }: HTMLAttributes<HTMLDivElement> & Token

return (
<div {...rest}>
<TabsKit>
<TabsKit selectedId="Neutral">
<StackVertical gap="L" justify="stretch" align="stretch">
<TabsKit.TabList>
<>
{Object.keys(semanticColors).map(keyTitle => {
return (
<TabsKit.Tab size="L" key={keyTitle}>
<TabsKit.Tab size="L" key={keyTitle} id={keyTitle}>
{keyTitle}
</TabsKit.Tab>
);
})}
</>
</TabsKit.TabList>

{Object.values(semanticColors).map(group => {
{Object.entries(semanticColors).map(groupEntry => {
return (
<TabsKit.TabPanel key={Object.keys(group)[0]}>
<TabsKit.TabPanel key={groupEntry[0]} id={groupEntry[0]}>
<StackVertical gap="M" align="stretch" justify="stretch">
{Object.entries(group).map(([background, tks], key) => {
{Object.entries(groupEntry[1]).map(([background, tks], key) => {
return (
<StackVertical
gap="M"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Token, TokenType } from '../../../src/tokens/types';
import { StackVertical } from '@talend/design-system';

import { ColorToken, Token, TokenType } from '../../../src/tokens/types';
import { TokensProps } from './TokensTypes';
import BreakpointScale from './components/DefinitionList/BreakpointScale/BreakpointScale';
import DefinitionListBreakpoint from './components/DefinitionList/DefinitionListBreakpoint';
import { StackVertical } from '@talend/design-system';

const TokensBreakpoint = ({ tokens }: TokensProps) => (
const TokensBreakpoint = ({ tokens }: TokensProps<ColorToken>) => (
<StackVertical gap="L" justify="stretch" align="stretch">
<BreakpointScale tokens={tokens.filter((t: Token) => t.type === TokenType.BREAKPOINT)} />
<DefinitionListBreakpoint
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ColorToken, Token, TokenType } from '../../../src/tokens/types';
import { TokensProps } from './TokensTypes';
import { getDisplayName } from './TokenFormatter';
import { TokensProps } from './TokensTypes';
import DefinitionListColors from './components/DefinitionList/DefinitionListColors';

const colorOrder = [
Expand All @@ -15,7 +15,7 @@ const colorOrder = [
'charts',
];

const TokensColor = ({ tokens }: TokensProps) => (
const TokensColor = ({ tokens }: TokensProps<ColorToken>) => (
<DefinitionListColors
tokens={tokens
.filter((t: Token) => t.type === TokenType.COLOR)
Expand Down
Loading

0 comments on commit b0c6b30

Please sign in to comment.