diff --git a/CODEOWNERS b/CODEOWNERS index bf4622efb..dd3fceac5 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,63 +1,64 @@ -- @amje @ValeraS @korvin89 - /src/components/ActionTooltip @amje - /src/components/Alert @IsaevAlexandr - /src/components/ArrowToggle @Marginy605 - /src/components/Avatar @DakEnviy - /src/components/AvatarStack @ogonkov - #/src/components/Breadcrumbs - /src/components/Button @amje - /src/components/Card @Lunory - /src/components/Checkbox @zamkovskaya - /src/components/ClipboardButton @Raubzeug - /src/components/ClipboardIcon @Raubzeug - /src/components/ControlLabel @korvin89 - /src/components/CopyToClipboard @SeqviriouM - /src/components/DefinitionList @Raubzeug - #/src/components/Dialog - /src/components/Disclosure @Raubzeug - /src/components/Divider @v4dyar4 - /src/components/DropdownMenu @axtk - /src/components/HelpMark @Raubzeug - /src/components/Hotkey @d3m1d0v - /src/components/Icon @amje - /src/components/Label @goshander - /src/components/Link @Estasie - /src/components/List @korvin89 - /src/components/Loader @SeqviriouM - /src/components/Menu @NikitaCG - /src/components/Modal @amje - /src/components/Overlay @Vladeeg - /src/components/Pagination @jhoncool - /src/components/Palette @Ruminat - /src/components/PinInput @amje - /src/components/PlaceholderContainer @Marginy605 - /src/components/Popover @kseniya57 - /src/components/Popup @amje - /src/components/Portal @amje - /src/components/Progress @Lunory - /src/components/Radio @zamkovskaya - /src/components/RadioButton @zamkovskaya - /src/components/RadioGroup @zamkovskaya - /src/components/User @DakEnviy - /src/components/UserLabel @DakEnviy - /src/components/useList @IsaevAlexandr - /src/components/Select @korvin89 - /src/components/Sheet @mournfulCoroner - /src/components/Skeleton @SeqviriouM - /src/components/Slider @Arucard89 - /src/components/Spin @SeqviriouM - /src/components/Stories @DarkGenius - /src/components/Switch @zamkovskaya - /src/components/Table @Raubzeug - /src/components/Tabs @sofiushko - /src/components/Text @IsaevAlexandr - /src/components/TreeList @IsaevAlexandr - /src/components/TreeSelect @IsaevAlexandr - /src/components/controls/TextArea @korvin89 - /src/components/controls/TextInput @korvin89 - /src/components/Toaster @ogonkov - /src/components/Tooltip @amje - /src/components/layout @IsaevAlexandr +* @amje @ValeraS @korvin89 +/src/components/ActionsPanel @jhoncool +/src/components/ActionTooltip @amje +/src/components/Alert @IsaevAlexandr +/src/components/ArrowToggle @Marginy605 +/src/components/Avatar @DakEnviy +/src/components/AvatarStack @ogonkov +#/src/components/Breadcrumbs +/src/components/Button @amje +/src/components/Card @Lunory +/src/components/Checkbox @zamkovskaya +/src/components/ClipboardButton @Raubzeug +/src/components/ClipboardIcon @Raubzeug +/src/components/ControlLabel @korvin89 +/src/components/CopyToClipboard @SeqviriouM +/src/components/DefinitionList @Raubzeug +#/src/components/Dialog +/src/components/Disclosure @Raubzeug +/src/components/Divider @v4dyar4 +/src/components/DropdownMenu @axtk +/src/components/HelpMark @Raubzeug +/src/components/Hotkey @d3m1d0v +/src/components/Icon @amje +/src/components/Label @goshander +/src/components/Link @Estasie +/src/components/List @korvin89 +/src/components/Loader @SeqviriouM +/src/components/Menu @NikitaCG +/src/components/Modal @amje +/src/components/Overlay @Vladeeg +/src/components/Pagination @jhoncool +/src/components/Palette @Ruminat +/src/components/PinInput @amje +/src/components/PlaceholderContainer @Marginy605 +/src/components/Popover @kseniya57 +/src/components/Popup @amje +/src/components/Portal @amje +/src/components/Progress @Lunory +/src/components/Radio @zamkovskaya +/src/components/RadioButton @zamkovskaya +/src/components/RadioGroup @zamkovskaya +/src/components/User @DakEnviy +/src/components/UserLabel @DakEnviy +/src/components/useList @IsaevAlexandr +/src/components/Select @korvin89 +/src/components/Sheet @mournfulCoroner +/src/components/Skeleton @SeqviriouM +/src/components/Slider @Arucard89 +/src/components/Spin @SeqviriouM +/src/components/Stories @DarkGenius +/src/components/Switch @zamkovskaya +/src/components/Table @Raubzeug +/src/components/Tabs @sofiushko +/src/components/Text @IsaevAlexandr +/src/components/TreeList @IsaevAlexandr +/src/components/TreeSelect @IsaevAlexandr +/src/components/controls/TextArea @korvin89 +/src/components/controls/TextInput @korvin89 +/src/components/Toaster @ogonkov +/src/components/Tooltip @amje +/src/components/layout @IsaevAlexandr /src/hooks/useActionHandlers @ogonkov /src/hooks/useFileInput @korvin89 diff --git a/src/components/DefinitionList/DefinitionList.scss b/src/components/DefinitionList/DefinitionList.scss index 2454d572b..95736e0e2 100644 --- a/src/components/DefinitionList/DefinitionList.scss +++ b/src/components/DefinitionList/DefinitionList.scss @@ -6,9 +6,7 @@ $block: '.#{variables.$ns}definition-list'; #{$block} { --_--item-block-start: var(--g-spacing-4); --_--term-width: 300px; - &__list { - margin: 0; - } + margin: 0; &__item { display: flex; diff --git a/src/components/DefinitionList/DefinitionList.tsx b/src/components/DefinitionList/DefinitionList.tsx index a217f71eb..531337ec3 100644 --- a/src/components/DefinitionList/DefinitionList.tsx +++ b/src/components/DefinitionList/DefinitionList.tsx @@ -1,11 +1,12 @@ import React from 'react'; import {isOfType} from '../utils/isOfType'; +import {warnOnce} from '../utils/warn'; import {DefinitionListProvider} from './components/DefinitionListContext'; import {DefinitionListItem} from './components/DefinitionListItem'; +import {b} from './constants'; import type {DefinitionListProps} from './types'; -import {b} from './utils'; import './DefinitionList.scss'; @@ -20,18 +21,18 @@ export function DefinitionList({ }: DefinitionListProps) { const normalizedChildren = prepareChildren(children); return ( -
- -
{normalizedChildren}
-
-
+ {normalizedChildren} + + ); } @@ -40,15 +41,16 @@ const isDefinitionListItem = isOfType(DefinitionListItem); function prepareChildren(children: React.ReactNode) { const items = React.Children.toArray(children); + const normalizedItems = []; for (const item of items) { const isItem = isDefinitionListItem(item); - if (!isItem) { - throw new Error( - 'Only components is allowed inside ', - ); + if (isItem) { + normalizedItems.push(item); + } else { + warnOnce('Only components is allowed inside '); } } - return children; + return normalizedItems; } DefinitionList.Item = DefinitionListItem; diff --git a/src/components/DefinitionList/README.md b/src/components/DefinitionList/README.md index b95b0fa9d..9c65b67f4 100644 --- a/src/components/DefinitionList/README.md +++ b/src/components/DefinitionList/README.md @@ -21,10 +21,10 @@ The component to display definition list with term and definition separated by d `} > - + value with copy - - + + ; diff --git a/src/components/DefinitionList/__stories__/DefinitionList.stories.tsx b/src/components/DefinitionList/__stories__/DefinitionList.stories.tsx index a281d1b2b..a13fc3575 100644 --- a/src/components/DefinitionList/__stories__/DefinitionList.stories.tsx +++ b/src/components/DefinitionList/__stories__/DefinitionList.stories.tsx @@ -1,12 +1,12 @@ import React from 'react'; -import type {Meta, StoryFn} from '@storybook/react'; +import type {Meta, StoryObj} from '@storybook/react'; import {Label} from '../../Label'; import {Link} from '../../Link'; import {User} from '../../User'; import {DefinitionList} from '../DefinitionList'; -import type {DefinitionListItem as DefinitionListItemProps, DefinitionListProps} from '../types'; +import type {DefinitionListItemProps} from '../types'; const items: DefinitionListItemProps[] = [ { @@ -166,20 +166,10 @@ export default { }, } as Meta; -const DefaultTemplate: StoryFn = (args) => ; -export const Default = DefaultTemplate.bind({}); -Default.args = {contentMaxWidth: 480}; +type Story = StoryObj; -const TemplateResponsive: StoryFn = (args) => ; -export const ResponsiveList = TemplateResponsive.bind({}); -ResponsiveList.args = { - responsive: true, -}; +export const Default: Story = {args: {contentMaxWidth: 480}}; -const TemplateVertical: StoryFn = (args) => { - return ; -}; -export const VerticalList = TemplateVertical.bind({}); -VerticalList.args = { - direction: 'vertical', -}; +export const ResponsiveList: Story = {args: {responsive: true}}; + +export const VerticalList: Story = {args: {direction: 'vertical'}}; diff --git a/src/components/DefinitionList/__tests__/DefinitionList.test.tsx b/src/components/DefinitionList/__tests__/DefinitionList.test.tsx index a8673eff3..c72e606eb 100644 --- a/src/components/DefinitionList/__tests__/DefinitionList.test.tsx +++ b/src/components/DefinitionList/__tests__/DefinitionList.test.tsx @@ -2,18 +2,20 @@ import React from 'react'; import {render, screen} from '../../../../test-utils/utils'; import {DefinitionList} from '../DefinitionList'; -import type {DefinitionListItem, DefinitionListProps} from '../types'; -import {b} from '../utils'; +import {b} from '../constants'; +import type {DefinitionListItemProps, DefinitionListProps} from '../types'; const qaAttribute = 'definition-list'; -const defaultItems: DefinitionListItem[] = [ +const defaultItems: DefinitionListItemProps[] = [ {name: 'test1', children: 'value1'}, {name: 'test2', children: 2}, {name: 'test3', children:
node value
}, ]; -const getComponent = (props?: Partial & {items?: DefinitionListItem[]}) => { +const getComponent = ( + props?: Partial & {items?: DefinitionListItemProps[]}, +) => { const {items = defaultItems} = props ?? {}; return render( @@ -24,7 +26,7 @@ const getComponent = (props?: Partial & {items?: Definition ).container; }; -describe('components: DefinitionList', () => { +describe('DefinitionList', () => { it('should render', () => { getComponent(); const component = screen.getByTestId(qaAttribute); diff --git a/src/components/DefinitionList/components/Definition.tsx b/src/components/DefinitionList/components/Definition.tsx index 31c73846d..ad86fd216 100644 --- a/src/components/DefinitionList/components/Definition.tsx +++ b/src/components/DefinitionList/components/Definition.tsx @@ -1,10 +1,10 @@ import React from 'react'; import {ClipboardButton} from '../../ClipboardButton'; -import type {DefinitionListItem} from '../types'; -import {b} from '../utils'; +import {b} from '../constants'; +import type {DefinitionListItemProps} from '../types'; -interface DefinitionProps extends Pick {} +interface DefinitionProps extends Pick {} export function Definition({copyText, children}: DefinitionProps) { const definitionContent = children ?? '—'; diff --git a/src/components/DefinitionList/components/DefinitionListItem.tsx b/src/components/DefinitionList/components/DefinitionListItem.tsx index 34c1795d8..238ceb33d 100644 --- a/src/components/DefinitionList/components/DefinitionListItem.tsx +++ b/src/components/DefinitionList/components/DefinitionListItem.tsx @@ -1,7 +1,8 @@ import React from 'react'; -import type {DefinitionListItem as DefinitionListItemProps} from '../types'; -import {b, getTitle, isUnbreakableOver} from '../utils'; +import {b} from '../constants'; +import type {DefinitionListItemProps} from '../types'; +import {getTitle, isUnbreakableOver} from '../utils'; import {Definition} from './Definition'; import {useDefinitionListAttributes} from './DefinitionListContext'; @@ -31,4 +32,4 @@ export function DefinitionListItem({name, children, copyText, note}: DefinitionL ); } -DefinitionListItem.displayName = 'DefinitionListItemin'; +DefinitionListItem.displayName = 'DefinitionListItem'; diff --git a/src/components/DefinitionList/components/Term.tsx b/src/components/DefinitionList/components/Term.tsx index f75f589b0..7a68fa184 100644 --- a/src/components/DefinitionList/components/Term.tsx +++ b/src/components/DefinitionList/components/Term.tsx @@ -1,9 +1,14 @@ import React from 'react'; import {HelpMark} from '../../HelpMark'; +import {b} from '../constants'; import i18n from '../i18n'; -import type {DefinitionListDirection, DefinitionListItem, DefinitionListItemNote} from '../types'; -import {b, getTitle} from '../utils'; +import type { + DefinitionListDirection, + DefinitionListItemNote, + DefinitionListItemProps, +} from '../types'; +import {getTitle} from '../utils'; interface NoteElementsProps { note?: DefinitionListItemNote; @@ -46,7 +51,7 @@ function NoteElement({note}: NoteElementsProps) { return null; } -interface TermProps extends Pick { +interface TermProps extends Pick { direction?: DefinitionListDirection; } diff --git a/src/components/DefinitionList/constants.ts b/src/components/DefinitionList/constants.ts new file mode 100644 index 000000000..cb71c486a --- /dev/null +++ b/src/components/DefinitionList/constants.ts @@ -0,0 +1,3 @@ +import {block} from '../utils/cn'; + +export const b = block('definition-list'); diff --git a/src/components/DefinitionList/index.ts b/src/components/DefinitionList/index.ts index cfe7f5f06..8a35d5a7e 100644 --- a/src/components/DefinitionList/index.ts +++ b/src/components/DefinitionList/index.ts @@ -1,2 +1,2 @@ export {DefinitionList} from './DefinitionList'; -export type {DefinitionListProps, DefinitionListItem} from './types'; +export type {DefinitionListProps, DefinitionListItemProps} from './types'; diff --git a/src/components/DefinitionList/types.ts b/src/components/DefinitionList/types.ts index 0522c49c5..4cda2b326 100644 --- a/src/components/DefinitionList/types.ts +++ b/src/components/DefinitionList/types.ts @@ -4,7 +4,7 @@ import type {HelpMarkProps} from '../HelpMark'; import type {QAProps} from '../types'; export type DefinitionListItemNote = string | HelpMarkProps; -export interface DefinitionListItem { +export interface DefinitionListItemProps { name: React.ReactNode; children?: React.ReactNode; copyText?: string; diff --git a/src/components/DefinitionList/utils.ts b/src/components/DefinitionList/utils.ts index 4a88e4386..e5999334d 100644 --- a/src/components/DefinitionList/utils.ts +++ b/src/components/DefinitionList/utils.ts @@ -1,9 +1,5 @@ import type React from 'react'; -import {block} from '../utils/cn'; - -export const b = block('definition-list'); - export function isUnbreakableOver(limit: number) { return function (value: string): boolean { const posibleLines = value.split(/\s+/); diff --git a/src/components/HelpMark/HelpMark.tsx b/src/components/HelpMark/HelpMark.tsx index b7528d017..2dd401716 100644 --- a/src/components/HelpMark/HelpMark.tsx +++ b/src/components/HelpMark/HelpMark.tsx @@ -16,7 +16,6 @@ const ICON_SIZE = 16; export interface HelpMarkProps extends QAProps { buttonProps?: React.ButtonHTMLAttributes; buttonRef?: React.RefObject; - delayClosing?: number; placement?: PopupPlacement; className?: string; children?: React.ReactNode; @@ -27,24 +26,20 @@ export function HelpMark({ buttonProps = {}, children, className, - delayClosing = 300, ...rest }: HelpMarkProps) { return ( - - + + {() => ( + + )} ); } diff --git a/src/components/HelpMark/README.md b/src/components/HelpMark/README.md index 93e8554ef..3d5b3ab5a 100644 --- a/src/components/HelpMark/README.md +++ b/src/components/HelpMark/README.md @@ -12,14 +12,13 @@ Component to display help icon with popover ## Examples -Component with rendered raw html (use `content` for plain text) and close on mouse leave after timeout set by `delayClosing`: +Component with rendered raw html and close on mouse leave: ```tsx console.log('just action happened'), @@ -70,35 +67,12 @@ LANDING_BLOCK--> -Popover with JSX component as content: - - - - - -```tsx -} /> -``` - - - ## Properties -| Property | Type | Required | Default | Description | -| :----------- | :---------------------------------------------- | :------- | :------------------ | :---------------------------------------------- | -| className | `String` | | | Control class name | -| placement | `Array` | | [`right`, `bottom`] | Allowed popover positions | -| delayClosing | `Number` | | `300` | Timeout before closing popover | -| children | `ReactNode` | | | Popover content | -| buttonProps | `React.ButtonHTMLAttributes` | | | Set attributes to the underlying button element | -| buttonRef | `React.RefObject` | | | Ref to the underlying button element | +| Property | Type | Required | Default | Description | +| :---------- | :---------------------------------------------- | :------- | :------------------ | :---------------------------------------------- | +| className | `String` | | | Control class name | +| placement | `Array` | | [`right`, `bottom`] | Allowed popover positions | +| children | `ReactNode` | | | Popover content | +| buttonProps | `React.ButtonHTMLAttributes` | | | Set attributes to the underlying button element | +| buttonRef | `React.RefObject` | | | Ref to the underlying button element | diff --git a/src/components/HelpMark/__stories__/HelpMark.stories.tsx b/src/components/HelpMark/__stories__/HelpMark.stories.tsx index 72a54ee98..5f070d151 100644 --- a/src/components/HelpMark/__stories__/HelpMark.stories.tsx +++ b/src/components/HelpMark/__stories__/HelpMark.stories.tsx @@ -1,9 +1,6 @@ -import React from 'react'; - -import type {Meta, StoryFn} from '@storybook/react'; +import type {Meta, StoryObj} from '@storybook/react'; import {HelpMark} from '../HelpMark'; -import type {HelpMarkProps} from '../HelpMark'; export default { title: 'Components/Utils/HelpMark', @@ -20,7 +17,7 @@ export default { config: { rules: [ { - id: 'button-name', + id: 'help-mark', enabled: false, // aria-labelledby id is valid after tooltip content is rendered selector: 'button[aria-labelledby="helpMarkWithoutActionsId"]', @@ -29,10 +26,8 @@ export default { }, }, }, -} as Meta; +} as Meta; + +type Story = StoryObj; -const DefaultTemplate: StoryFn = (args) => ; -export const Default = DefaultTemplate.bind({}); -Default.args = { - children: 'Some content', -}; +export const Default: Story = {args: {children: 'Some content'}};