diff --git a/src/components/DefinitionList/DefinitionList.scss b/src/components/DefinitionList/DefinitionList.scss index 15d4a14..eef1bd2 100644 --- a/src/components/DefinitionList/DefinitionList.scss +++ b/src/components/DefinitionList/DefinitionList.scss @@ -4,9 +4,11 @@ $block: '.#{variables.$ns}definition-list'; #{$block} { - margin: 0; + &__list { + margin: 0; + } - &__title { + &__group-title { margin-block-end: var(--g-spacing-3); &:not(:first-of-type) { @@ -14,10 +16,6 @@ $block: '.#{variables.$ns}definition-list'; } } - #{$block}__item:is(#{$block}__item_grouped) + #{$block}__item:not(#{$block}__item_grouped) { - margin-block-start: var(--g-spacing-5); - } - &__item { display: flex; align-items: baseline; @@ -34,8 +32,16 @@ $block: '.#{variables.$ns}definition-list'; } } + &_margin { + &:not(:first-of-type) { + margin-block-start: var(--g-spacing-5); + } + } + &__term-container { - flex: 0 0 300px; + flex: 0 0 auto; + width: 300px; + max-width: 300px; display: flex; align-items: baseline; @@ -133,10 +139,10 @@ $block: '.#{variables.$ns}definition-list'; #{$block}__item + #{$block}__item { margin-block-start: var(--g-spacing-3); } - #{$block}__title:not(:first-of-type) { + #{$block}__group-title:not(:first-of-type) { margin-block-start: var(--g-spacing-8); } - #{$block}__item:is(#{$block}__item_grouped) + #{$block}__item:not(#{$block}__item_grouped) { + #{$block}_margin:not(:first-of-type) { margin-block-start: var(--g-spacing-8); } } diff --git a/src/components/DefinitionList/DefinitionList.tsx b/src/components/DefinitionList/DefinitionList.tsx index f04dfe8..a42a1eb 100644 --- a/src/components/DefinitionList/DefinitionList.tsx +++ b/src/components/DefinitionList/DefinitionList.tsx @@ -3,20 +3,16 @@ import React from 'react'; import {Definition} from './components/Definition'; import {GroupLabel} from './components/GroupLabel'; import {Term} from './components/Term'; -import {DefinitionListProps} from './types'; import { - b, - getFlattenItems, - getKeyStyles, - getTitle, - getValueStyles, - isGroup, - isUnbreakableOver, -} from './utils'; + DefinitionListGranularProps, + DefinitionListGroupedProps, + DefinitionListProps, +} from './types'; +import {b, getAllItemsAsGroups, getTitle, isUnbreakableOver, onlySingleItems} from './utils'; import './DefinitionList.scss'; -export function DefinitionList({ +function DefinitionListGranular({ items, responsive, direction = 'horizontal', @@ -26,68 +22,115 @@ export function DefinitionList({ itemClassName, copyPosition = 'outside', qa, -}: DefinitionListProps) { - const keyStyle = getKeyStyles({nameMaxWidth, direction}); +}: DefinitionListGranularProps) { + const keyStyle = nameMaxWidth ? {maxWidth: nameMaxWidth, width: nameMaxWidth} : {}; - const valueStyle = getValueStyles({contentMaxWidth, direction}); + const valueStyle = + typeof contentMaxWidth === 'number' + ? {width: contentMaxWidth, maxWidth: contentMaxWidth} + : {}; const normalizedItems = React.useMemo(() => { - return getFlattenItems(items).map((value, index) => ({...value, key: index})); + return items.map((value, index) => ({...value, key: index})); }, [items]); return ( -
+
+
+ {normalizedItems.map((item) => { + const { + name, + key, + content, + contentTitle, + nameTitle, + copyText, + note, + multilineName, + } = item; + + return ( +
+
+ +
+
+ +
+
+ ); + })} +
+
+ ); +} + +function DefinitionListGrouped({ + items, + className, + itemClassName, + ...rest +}: DefinitionListGroupedProps) { + const normalizedItems = React.useMemo(() => { + return items.map((value, index) => ({...value, key: index})); + }, [items]); + + return ( +
{normalizedItems.map((item) => { - if (isGroup(item)) { - const {key, label} = item; - return ; - } - const { - name, - key, - content, - contentTitle, - nameTitle, - copyText, - note, - multilineName, - isGrouped, - } = item; + const {key, label} = item; return ( -
-
- -
-
- + {label && } + {item.items && ( + -
-
+ )} + ); })} -
+ ); } + +export function DefinitionList({items, ...rest}: DefinitionListProps) { + if (onlySingleItems(items)) { + return ; + } + + const preparedItems = getAllItemsAsGroups(items); + + return ; +} diff --git a/src/components/DefinitionList/components/GroupLabel.tsx b/src/components/DefinitionList/components/GroupLabel.tsx index fd59f54..c02e76c 100644 --- a/src/components/DefinitionList/components/GroupLabel.tsx +++ b/src/components/DefinitionList/components/GroupLabel.tsx @@ -10,7 +10,7 @@ interface GroupLabelProps { export function GroupLabel({label}: GroupLabelProps) { return ( -
+
{label} diff --git a/src/components/DefinitionList/types.ts b/src/components/DefinitionList/types.ts index cd55a30..3132f3c 100644 --- a/src/components/DefinitionList/types.ts +++ b/src/components/DefinitionList/types.ts @@ -20,10 +20,6 @@ export interface DefinitionListSingleItem { multilineName?: boolean; } -export interface DefinitionListItemGrouped extends DefinitionListSingleItem { - isGrouped?: boolean; -} - export type DefinitionListItem = DefinitionListSingleItem | DefinitionListGroup; export type DefinitionListDirection = 'vertical' | 'horizontal'; @@ -38,3 +34,10 @@ export interface DefinitionListProps extends QAProps { className?: string; itemClassName?: string; } + +export interface DefinitionListGranularProps extends Omit { + items: DefinitionListSingleItem[]; +} +export interface DefinitionListGroupedProps extends Omit { + items: DefinitionListGroup[]; +} diff --git a/src/components/DefinitionList/utils.ts b/src/components/DefinitionList/utils.ts index 62eb2f6..7a12d6f 100644 --- a/src/components/DefinitionList/utils.ts +++ b/src/components/DefinitionList/utils.ts @@ -2,13 +2,7 @@ import React from 'react'; import {block} from '../utils/cn'; -import type { - DefinitionListGroup, - DefinitionListItem, - DefinitionListItemGrouped, - DefinitionListProps, - DefinitionListSingleItem, -} from './types'; +import type {DefinitionListGroup, DefinitionListItem, DefinitionListSingleItem} from './types'; export const b = block('definition-list'); @@ -23,19 +17,31 @@ export function isUnbreakableOver(limit: number) { export const isGroup = (item: DefinitionListItem): item is DefinitionListGroup => 'label' in item && !('name' in item); -export function getFlattenItems( +export const onlySingleItems = (items: DefinitionListItem[]): items is DefinitionListSingleItem[] => + !items.some((el) => isGroup(el)); + +export function getAllItemsAsGroups( items: (DefinitionListSingleItem | DefinitionListGroup)[], -): (DefinitionListItemGrouped | DefinitionListGroup)[] { - return items.reduce<(DefinitionListSingleItem | DefinitionListGroup)[]>((acc, item) => { +): DefinitionListGroup[] { + const result: DefinitionListGroup[] = []; + let temporaryList: DefinitionListSingleItem[] = []; + for (const item of items) { if (isGroup(item)) { - acc.push({label: item.label}); - const items = [...(item.items ?? [])].map((el) => ({...el, isGrouped: true})); - acc.push(...items); + if (temporaryList.length) { + result.push({items: temporaryList, label: null}); + temporaryList = []; + } + + result.push(item); } else { - acc.push(item); + temporaryList.push(item); } - return acc; - }, []); + } + if (temporaryList.length) { + result.push({items: temporaryList, label: null}); + temporaryList = []; + } + return result; } export function getTitle(title?: string, content?: React.ReactNode) { @@ -49,29 +55,3 @@ export function getTitle(title?: string, content?: React.ReactNode) { return undefined; } - -export function getKeyStyles({ - nameMaxWidth, - direction, -}: Pick) { - if (!nameMaxWidth) { - return {}; - } - if (direction === 'vertical') { - return {maxWidth: nameMaxWidth}; - } - return {flexBasis: nameMaxWidth}; -} - -export function getValueStyles({ - contentMaxWidth, - direction, -}: Pick) { - if (!(typeof contentMaxWidth === 'number')) { - return {}; - } - if (direction === 'vertical') { - return {maxWidth: contentMaxWidth}; - } - return {flexBasis: contentMaxWidth, maxWidth: contentMaxWidth}; -}