@hh.ru/magritte-ui-breadcrumbs 7.1.86 → 7.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Breadcrumbs.d.ts CHANGED
@@ -17,7 +17,7 @@ import type { BreadcrumbsProps } from '@hh.ru/magritte-ui-breadcrumbs/types';
17
17
  *
18
18
  * Если и после этого контент все равно будет слишком широким, первый элемент начнет уменьшаться с text-overflow:ellipsis.
19
19
  *
20
- * Коллапсирование реализовано стилями, layout effect только вычисляет, какие элементы нужно показывать в дроп-контейнере,
21
- * и прячет / показывает ellipsis с помощью `visibility:hidden`, не влияя на размеры чего-либо в верстке.
20
+ * Все пункты остаются в одном `ol` в порядке иерархии. Свёрнутые `li` выводятся из flex-раскладки
21
+ * и остаются в DOM для SEO.
22
22
  */
23
23
  export declare const Breadcrumbs: React.FC<BreadcrumbsProps>;
package/Breadcrumbs.js CHANGED
@@ -10,10 +10,26 @@ import { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';
10
10
  import { Card } from '@hh.ru/magritte-ui-card';
11
11
  import { Drop } from '@hh.ru/magritte-ui-drop';
12
12
  import { Text } from '@hh.ru/magritte-ui-typography';
13
- import { s as styles } from './breadcrumbs-GKQSyUfi.js';
13
+ import { s as styles } from './breadcrumbs-BblumBkP.js';
14
14
 
15
15
  const MAX_VISIBLE_ITEMS = 5;
16
16
  const TEXT_TYPOGRAPHY = 'label-3-regular';
17
+ // Допуск на погрешность округления при сравнении суммы offsetWidth с clientWidth.
18
+ const OVERFLOW_EPS_PX = 1;
19
+ const FIRST_COLLAPSIBLE_ITEM_INDEX = 1;
20
+ const DEFAULT_ARIA_LABEL = 'Хлебные крошки';
21
+ const DEFAULT_ELLIPSIS_ARIA_LABEL = 'Показать скрытые элементы';
22
+ const measureIntrinsicWidth = (element) => {
23
+ if (!element) {
24
+ return 0;
25
+ }
26
+ // Временно форсируем натуральную ширину: к этому моменту первая крошка
27
+ // уже может быть сжата flex-shrink, и offsetWidth будет занижен.
28
+ element.classList.add(styles.itemIntrinsicWidth);
29
+ const measuredWidth = element.offsetWidth;
30
+ element.classList.remove(styles.itemIntrinsicWidth);
31
+ return measuredWidth;
32
+ };
17
33
  const arrayFromRange = (start, end) => {
18
34
  return start <= end ? [...Array(end - start + 1).keys()].map((x) => x + start) : [];
19
35
  };
@@ -21,6 +37,9 @@ const makeItemKey = (children, index) => {
21
37
  return (children[index].key ??
22
38
  (typeof children[index].props.children === 'string' ? children[index].props.children : index));
23
39
  };
40
+ const getMinHiddenCount = (length) => {
41
+ return length > MAX_VISIBLE_ITEMS ? length - (MAX_VISIBLE_ITEMS - 1) : 0;
42
+ };
24
43
  /**
25
44
  * В спецификации указано, что breadcrumbs не может отображать более 5-ти элементов.
26
45
  *
@@ -39,59 +58,86 @@ const makeItemKey = (children, index) => {
39
58
  *
40
59
  * Если и после этого контент все равно будет слишком широким, первый элемент начнет уменьшаться с text-overflow:ellipsis.
41
60
  *
42
- * Коллапсирование реализовано стилями, layout effect только вычисляет, какие элементы нужно показывать в дроп-контейнере,
43
- * и прячет / показывает ellipsis с помощью `visibility:hidden`, не влияя на размеры чего-либо в верстке.
61
+ * Все пункты остаются в одном `ol` в порядке иерархии. Свёрнутые `li` выводятся из flex-раскладки
62
+ * и остаются в DOM для SEO.
44
63
  */
45
- const Breadcrumbs = ({ children, 'data-qa': dataQa }) => {
64
+ const Breadcrumbs = ({ children, 'aria-label': ariaLabel = DEFAULT_ARIA_LABEL, ellipsisAriaLabel = DEFAULT_ELLIPSIS_ARIA_LABEL, 'data-qa': dataQa, }) => {
65
+ const listRef = useRef(null);
66
+ const ellipsisRef = useRef(null);
46
67
  const activatorRef = useRef(null);
47
- const containerRef = useRef(null);
48
- const [firstCollapsedItemIndex, setFirstCollapsedItemIndex] = useState(null);
49
- const [lastCollapsedItemIndex, setLastCollapsedItemIndex] = useState(null);
50
- const showEllipsis = firstCollapsedItemIndex !== null && lastCollapsedItemIndex !== null;
68
+ const [hiddenCount, setHiddenCount] = useState(() => getMinHiddenCount(children.length));
51
69
  const [expandCollapsedItems, setExpandCollapsedItems] = useState(false);
70
+ const showEllipsis = hiddenCount > 0;
52
71
  const itemRefs = useRef({});
53
72
  const itemRefCallbacks = useMemo(() => [...Array(children.length).keys()].map((_, index) => (element) => {
54
73
  itemRefs.current[index] = element;
55
74
  }), [children.length]);
56
75
  const { isMobile } = useBreakpoint();
76
+ // Сжимаем первую крошку только когда больше нечего коллапсировать,
77
+ // иначе она «отдаёт» ширину соседним и они налезают друг на друга.
78
+ const canShrinkFirstItem = children.length <= 2 || hiddenCount >= children.length - 2;
57
79
  // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps
58
80
  const checkIfItemsCollapsed = useCallback(throttle(() => {
59
- const collapsedItemIndexes = Object.keys(itemRefs.current).filter((index) => itemRefs.current[index]?.offsetTop > 0);
60
- const _firstCollapsedItemIndex = Math.min(...collapsedItemIndexes, children.length > MAX_VISIBLE_ITEMS ? 1 : Infinity);
61
- const _lastCollapsedItemIndex = Math.max(...collapsedItemIndexes, children.length > MAX_VISIBLE_ITEMS ? children.length - (MAX_VISIBLE_ITEMS - 1) : -Infinity);
62
- if (Number.isFinite(_firstCollapsedItemIndex) && Number.isFinite(_lastCollapsedItemIndex)) {
63
- setFirstCollapsedItemIndex(_firstCollapsedItemIndex);
64
- setLastCollapsedItemIndex(_lastCollapsedItemIndex);
81
+ const list = listRef.current;
82
+ if (!list || children.length <= 1) {
83
+ setHiddenCount(0);
84
+ setExpandCollapsedItems(false);
85
+ return;
86
+ }
87
+ const containerWidth = list.clientWidth;
88
+ const length = children.length;
89
+ const minHidden = getMinHiddenCount(length);
90
+ const maxHidden = length - 2;
91
+ const ellipsisWidth = ellipsisRef.current?.offsetWidth ?? 0;
92
+ // offsetWidth первой крошки может быть уже сжатым — для расчёта нужна полная ширина,
93
+ // иначе соседние пункты останутся видимыми и налезут друг на друга.
94
+ const firstItemWidth = measureIntrinsicWidth(itemRefs.current[0]);
95
+ let nextHidden = minHidden;
96
+ // Ищем минимальное число скрытых средних пунктов, при котором
97
+ // first + (ellipsis) + видимые средние + last влезают в контейнер.
98
+ // Начинаем с minHidden (лимит в 5 видимых) и при нехватке места
99
+ // прячем пункты слева направо до first / ellipsis / last.
100
+ for (let hidden = minHidden; hidden <= maxHidden; hidden++) {
101
+ let totalWidth = firstItemWidth + (itemRefs.current[length - 1]?.offsetWidth ?? 0);
102
+ if (hidden > 0) {
103
+ totalWidth += ellipsisWidth;
104
+ }
105
+ for (let index = hidden + FIRST_COLLAPSIBLE_ITEM_INDEX; index < length - 1; index++) {
106
+ totalWidth += itemRefs.current[index]?.offsetWidth ?? 0;
107
+ }
108
+ nextHidden = hidden;
109
+ if (totalWidth <= containerWidth + OVERFLOW_EPS_PX) {
110
+ break;
111
+ }
65
112
  }
66
- else {
67
- setFirstCollapsedItemIndex(null);
68
- setLastCollapsedItemIndex(null);
113
+ setHiddenCount(nextHidden);
114
+ if (nextHidden === 0) {
69
115
  setExpandCollapsedItems(false);
70
116
  }
71
117
  }, 50), [children.length]);
72
118
  useLayoutEffect(checkIfItemsCollapsed);
73
119
  useResize(checkIfItemsCollapsed);
74
120
  const renderCollapsedItems = (itemClassName, typography) => {
75
- if (firstCollapsedItemIndex === null || lastCollapsedItemIndex === null) {
121
+ if (!showEllipsis) {
76
122
  return null;
77
123
  }
78
- return arrayFromRange(firstCollapsedItemIndex, Math.min(lastCollapsedItemIndex, children.length - 1)).map((index) => {
79
- const { onClick, Element = 'a', children: child, ...props } = children[index].props;
124
+ return arrayFromRange(FIRST_COLLAPSIBLE_ITEM_INDEX, hiddenCount).map((index) => {
125
+ const { Element = 'a', children: child, ...props } = children[index].props;
80
126
  return (jsx("div", { className: itemClassName, children: jsx(Card, { ...props, Element: Element, borderRadius: 12, padding: 8, paddingLeft: 12, paddingRight: 12, style: "primary", hoverStyle: "secondary", hoverEnabled: true, pressEnabled: true, stretched: true, children: jsx("div", { className: styles.interactiveText, children: jsx(Text, { Element: "div", typography: typography, children: jsx("div", { className: styles.textWithEllipsis, children: child }) }) }) }) }, makeItemKey(children, index)));
81
127
  });
82
128
  };
83
- const renderLastItem = (visible) => {
129
+ const renderLastItem = () => {
84
130
  if (children.length === 0) {
85
131
  return null;
86
132
  }
87
133
  const index = children.length - 1;
88
134
  const { children: child, href, ...props } = { ...children[index].props };
89
- return (jsx("div", { className: classnames(styles.item, { [styles.itemAfterEllipsis]: index <= 1 }), ref: visible ? itemRefCallbacks[index] : undefined, children: jsx("div", { className: styles.staticText, children: jsx(Text, { ...(visible ? props : {}), Element: "span", typography: TEXT_TYPOGRAPHY, children: child }) }) }, makeItemKey(children, index)));
135
+ return (jsx("li", { className: styles.item, ref: itemRefCallbacks[index], children: jsx("div", { className: styles.staticText, children: jsx(Text, { ...props, Element: "span", typography: TEXT_TYPOGRAPHY, "aria-current": "page", children: child }) }) }));
90
136
  };
91
- return (jsx("div", { className: styles.breadcrumbs, "data-qa": dataQa, ref: containerRef, children: jsxs("div", { className: styles.unbreakableContainer, children: [children.length > 1 && (jsxs("div", { className: classnames(styles.item, styles.firstItem), ref: itemRefCallbacks[0], children: [jsx("div", { className: styles.firstItemContent, children: cloneElement(children[0], undefined, jsx("div", { className: styles.textWithEllipsis, children: children[0].props.children })) }), jsx(BreadcrumbsDivider, {})] })), jsxs("div", { className: classnames({ [styles.invisibleContainer]: !showEllipsis }), "data-qa": "breadcrumbs-action", children: [jsx("button", { type: "button", className: styles.ellipsis, ref: activatorRef, onClick: () => setExpandCollapsedItems(!expandCollapsedItems), children: jsx("div", { className: styles.interactiveText, children: jsx(Text, { Element: "span", typography: TEXT_TYPOGRAPHY, children: "..." }) }) }), jsx(BreadcrumbsDivider, {}), showEllipsis &&
92
- (isMobile ? (jsx(BottomSheet, { visible: expandCollapsedItems, onClose: () => setExpandCollapsedItems(false), children: renderCollapsedItems(styles.bottomSheetItem, 'label-2-regular') })) : (jsx(Drop, { activatorRef: activatorRef, placement: "bottom-left", padding: 12, visible: expandCollapsedItems, onClose: () => setExpandCollapsedItems(false), children: renderCollapsedItems(styles.dropItem, TEXT_TYPOGRAPHY) })))] }), jsxs("div", { className: styles.collapsibleContainer, children: [jsx("div", { className: styles.invisibleContainer, children: renderLastItem(false) }), jsxs("div", { className: styles.collapsibleContent, children: [renderLastItem(true), arrayFromRange(children.length <= MAX_VISIBLE_ITEMS ? 1 : children.length - (MAX_VISIBLE_ITEMS - 2), children.length - 2)
93
- .reverse()
94
- .map((index) => (jsxs("div", { className: classnames(styles.item, { [styles.itemAfterEllipsis]: index <= 1 }), ref: itemRefCallbacks[index], children: [children[index], jsx(BreadcrumbsDivider, {})] }, makeItemKey(children, index))))] })] })] }) }));
137
+ return (jsx("nav", { className: styles.breadcrumbs, "aria-label": ariaLabel, "data-qa": dataQa, children: jsxs("ol", { className: styles.unbreakableContainer, ref: listRef, children: [children.length > 1 && (jsxs("li", { className: classnames(styles.item, styles.firstItem, {
138
+ [styles.firstItemShrinkable]: canShrinkFirstItem,
139
+ }), ref: itemRefCallbacks[0], children: [jsx("div", { className: styles.firstItemContent, children: cloneElement(children[0], undefined, jsx("span", { className: styles.textWithEllipsis, children: children[0].props.children })) }), jsx(BreadcrumbsDivider, {})] })), arrayFromRange(FIRST_COLLAPSIBLE_ITEM_INDEX, hiddenCount).map((index) => (jsxs("li", { className: classnames(styles.item, styles.invisibleContainer), ref: itemRefCallbacks[index], inert: '', children: [children[index], jsx(BreadcrumbsDivider, {})] }, makeItemKey(children, index)))), children.length > 2 && (jsxs("li", { className: classnames(styles.item, { [styles.invisibleContainer]: !showEllipsis }), "data-qa": "breadcrumbs-action", ref: ellipsisRef, ...(!showEllipsis ? { inert: '' } : undefined), children: [jsx("button", { type: "button", className: styles.ellipsis, ref: activatorRef, "aria-label": ellipsisAriaLabel, "aria-expanded": expandCollapsedItems, "aria-haspopup": isMobile ? 'dialog' : 'menu', onClick: () => setExpandCollapsedItems(!expandCollapsedItems), children: jsx("span", { className: styles.interactiveText, children: jsx(Text, { Element: "span", typography: TEXT_TYPOGRAPHY, children: "..." }) }) }), jsx(BreadcrumbsDivider, {}), showEllipsis &&
140
+ (isMobile ? (jsx(BottomSheet, { visible: expandCollapsedItems, onClose: () => setExpandCollapsedItems(false), children: renderCollapsedItems(styles.bottomSheetItem, 'label-2-regular') })) : (jsx(Drop, { activatorRef: activatorRef, placement: "bottom-left", padding: 12, visible: expandCollapsedItems, onClose: () => setExpandCollapsedItems(false), role: "menu", children: renderCollapsedItems(styles.dropItem, TEXT_TYPOGRAPHY) })))] })), arrayFromRange(hiddenCount + FIRST_COLLAPSIBLE_ITEM_INDEX, children.length - 2).map((index) => (jsxs("li", { className: styles.item, ref: itemRefCallbacks[index], children: [children[index], jsx(BreadcrumbsDivider, {})] }, makeItemKey(children, index)))), renderLastItem()] }) }));
95
141
  };
96
142
 
97
143
  export { Breadcrumbs };
@@ -1 +1 @@
1
- {"version":3,"file":"Breadcrumbs.js","sources":["src/Breadcrumbs.tsx"],"sourcesContent":["import { cloneElement, useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport classnames from 'classnames';\n\nimport { throttle } from '@hh.ru/magritte-common-func-utils';\nimport { useResize } from '@hh.ru/magritte-common-resize';\nimport { BottomSheet } from '@hh.ru/magritte-ui-bottom-sheet';\nimport { BreadcrumbsDivider } from '@hh.ru/magritte-ui-breadcrumbs/BreadcrumbsDivider';\nimport type { BreadcrumbsItem, BreadcrumbsProps } from '@hh.ru/magritte-ui-breadcrumbs/types';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { Card } from '@hh.ru/magritte-ui-card';\nimport { Drop } from '@hh.ru/magritte-ui-drop';\nimport { Text, TextTypography } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './breadcrumbs.less';\n\nconst MAX_VISIBLE_ITEMS = 5;\nconst TEXT_TYPOGRAPHY = 'label-3-regular';\n\nconst arrayFromRange = (start: number, end: number) => {\n return start <= end ? [...Array(end - start + 1).keys()].map((x) => x + start) : [];\n};\n\nconst makeItemKey = (children: Array<BreadcrumbsItem>, index: number): React.Key => {\n return (\n children[index].key ??\n (typeof children[index].props.children === 'string' ? children[index].props.children : index)\n );\n};\n\n/**\n * В спецификации указано, что breadcrumbs не может отображать более 5-ти элементов.\n *\n * Варианты отображения breadcrumbs:\n * -> link / link / link / link / text\n * или\n * -> link / ellipsis / link / link / text\n *\n * Если лимит будет превышен, компонент схлопнет в ellipsis все элементы, которые окажутся между первым и\n * тремя последними элементами. Таким образом breadcrumbs будет приведен к виду -> link / ellipsis / link / link / text,\n * где ellipsis — это кнопка, раскрывающая дроп-контейнер, в который складываются сколлапсировавшие элементы.\n *\n * Если после лимитирования контейнер-родитель всё равно не будет умещать в себе контент, то видимые элементы\n * один за другим начнут коллапсировать до максимально возможного уровеня сворачивания элементов:\n * -> link / ellipsis / text.\n *\n * Если и после этого контент все равно будет слишком широким, первый элемент начнет уменьшаться с text-overflow:ellipsis.\n *\n * Коллапсирование реализовано стилями, layout effect только вычисляет, какие элементы нужно показывать в дроп-контейнере,\n * и прячет / показывает ellipsis с помощью `visibility:hidden`, не влияя на размеры чего-либо в верстке.\n */\nexport const Breadcrumbs: React.FC<BreadcrumbsProps> = ({ children, 'data-qa': dataQa }) => {\n const activatorRef = useRef<HTMLButtonElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const [firstCollapsedItemIndex, setFirstCollapsedItemIndex] = useState<number | null>(null);\n const [lastCollapsedItemIndex, setLastCollapsedItemIndex] = useState<number | null>(null);\n const showEllipsis = firstCollapsedItemIndex !== null && lastCollapsedItemIndex !== null;\n const [expandCollapsedItems, setExpandCollapsedItems] = useState(false);\n\n const itemRefs = useRef<Record<number, HTMLDivElement>>({});\n const itemRefCallbacks = useMemo<React.RefCallback<HTMLDivElement>[]>(\n () =>\n [...Array(children.length).keys()].map((_, index) => (element: HTMLDivElement) => {\n itemRefs.current[index] = element;\n }),\n [children.length]\n );\n\n const { isMobile } = useBreakpoint();\n\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n const checkIfItemsCollapsed = useCallback(\n throttle(() => {\n const collapsedItemIndexes = (Object.keys(itemRefs.current) as unknown[] as number[]).filter(\n (index) => itemRefs.current[index]?.offsetTop > 0\n );\n\n const _firstCollapsedItemIndex = Math.min(\n ...collapsedItemIndexes,\n children.length > MAX_VISIBLE_ITEMS ? 1 : Infinity\n );\n\n const _lastCollapsedItemIndex = Math.max(\n ...collapsedItemIndexes,\n children.length > MAX_VISIBLE_ITEMS ? children.length - (MAX_VISIBLE_ITEMS - 1) : -Infinity\n );\n\n if (Number.isFinite(_firstCollapsedItemIndex) && Number.isFinite(_lastCollapsedItemIndex)) {\n setFirstCollapsedItemIndex(_firstCollapsedItemIndex);\n setLastCollapsedItemIndex(_lastCollapsedItemIndex);\n } else {\n setFirstCollapsedItemIndex(null);\n setLastCollapsedItemIndex(null);\n setExpandCollapsedItems(false);\n }\n }, 50),\n [children.length]\n );\n\n useLayoutEffect(checkIfItemsCollapsed);\n useResize(checkIfItemsCollapsed);\n\n const renderCollapsedItems = (itemClassName: string, typography: TextTypography) => {\n if (firstCollapsedItemIndex === null || lastCollapsedItemIndex === null) {\n return null;\n }\n\n return arrayFromRange(firstCollapsedItemIndex, Math.min(lastCollapsedItemIndex, children.length - 1)).map(\n (index) => {\n const { onClick, Element = 'a', children: child, ...props } = children[index].props;\n return (\n <div className={itemClassName} key={makeItemKey(children, index)}>\n <Card\n {...props}\n Element={Element}\n borderRadius={12}\n padding={8}\n paddingLeft={12}\n paddingRight={12}\n style=\"primary\"\n hoverStyle=\"secondary\"\n hoverEnabled\n pressEnabled\n stretched\n >\n <div className={styles.interactiveText}>\n <Text Element=\"div\" typography={typography}>\n <div className={styles.textWithEllipsis}>{child}</div>\n </Text>\n </div>\n </Card>\n </div>\n );\n }\n );\n };\n\n const renderLastItem = (visible: boolean) => {\n if (children.length === 0) {\n return null;\n }\n\n const index = children.length - 1;\n const { children: child, href, ...props } = { ...children[index].props };\n return (\n <div\n className={classnames(styles.item, { [styles.itemAfterEllipsis]: index <= 1 })}\n key={makeItemKey(children, index)}\n ref={visible ? itemRefCallbacks[index] : undefined}\n >\n <div className={styles.staticText}>\n <Text {...(visible ? props : {})} Element=\"span\" typography={TEXT_TYPOGRAPHY}>\n {child}\n </Text>\n </div>\n </div>\n );\n };\n\n return (\n <div className={styles.breadcrumbs} data-qa={dataQa} ref={containerRef}>\n <div className={styles.unbreakableContainer}>\n {/*\n Нулевой айтем имеет text-overflow:ellipsis, все остальные скрываются целиком.\n Он начнет уменьшаться, только если все остальные айтемы, кроме последнего, уже были скрыты.\n */}\n {children.length > 1 && (\n <div className={classnames(styles.item, styles.firstItem)} ref={itemRefCallbacks[0]}>\n <div className={styles.firstItemContent}>\n {cloneElement(\n children[0],\n undefined,\n <div className={styles.textWithEllipsis}>{children[0].props.children}</div>\n )}\n </div>\n <BreadcrumbsDivider />\n </div>\n )}\n\n {/*\n Всегда рендерим эллипсис, если он не нужен, прячем его через visibility:hidden.\n Если все айтемы поместились, айтем непосредственно после эллипсиса (его индекс min(length - 1, 1))\n перекроет его за счет отрицательного margin-left.\n */}\n <div\n className={classnames({ [styles.invisibleContainer]: !showEllipsis })}\n data-qa=\"breadcrumbs-action\"\n >\n <button\n type=\"button\"\n className={styles.ellipsis}\n ref={activatorRef}\n onClick={() => setExpandCollapsedItems(!expandCollapsedItems)}\n >\n <div className={styles.interactiveText}>\n <Text Element=\"span\" typography={TEXT_TYPOGRAPHY}>\n ...\n </Text>\n </div>\n </button>\n <BreadcrumbsDivider />\n {showEllipsis &&\n (isMobile ? (\n <BottomSheet visible={expandCollapsedItems} onClose={() => setExpandCollapsedItems(false)}>\n {renderCollapsedItems(styles.bottomSheetItem, 'label-2-regular')}\n </BottomSheet>\n ) : (\n <Drop\n activatorRef={activatorRef}\n placement=\"bottom-left\"\n padding={12}\n visible={expandCollapsedItems}\n onClose={() => setExpandCollapsedItems(false)}\n >\n {renderCollapsedItems(styles.dropItem, TEXT_TYPOGRAPHY)}\n </Drop>\n ))}\n </div>\n\n {/*\n Collapsible контейнер имеет минимальную ширину, равную ширине последнего айтема,\n но стремится заполнить все доступное пространство.\n При нехватке места айтемы, начиная с меньшего индекса, будут\n переноситься на следующую строку флекс-контейнера и обрезаться overflow.\n Последний айтем имеет наибольший приоритет перед всеми остальными и никогда не скрывается.\n */}\n <div className={styles.collapsibleContainer}>\n {/*\n Рендерим копию последнего айтема и прячем ее через visibility:hidden,\n чтобы задать минимальную ширину collapsible контейнера\n */}\n <div className={styles.invisibleContainer}>{renderLastItem(false)}</div>\n\n <div className={styles.collapsibleContent}>\n {renderLastItem(true)}\n\n {arrayFromRange(\n children.length <= MAX_VISIBLE_ITEMS ? 1 : children.length - (MAX_VISIBLE_ITEMS - 2),\n children.length - 2\n )\n .reverse()\n .map((index) => (\n <div\n className={classnames(styles.item, { [styles.itemAfterEllipsis]: index <= 1 })}\n key={makeItemKey(children, index)}\n ref={itemRefCallbacks[index]}\n >\n {children[index]}\n <BreadcrumbsDivider />\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n};\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"Breadcrumbs.js","sources":["src/Breadcrumbs.tsx"],"sourcesContent":["import { cloneElement, useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport classnames from 'classnames';\n\nimport { throttle } from '@hh.ru/magritte-common-func-utils';\nimport { useResize } from '@hh.ru/magritte-common-resize';\nimport { BottomSheet } from '@hh.ru/magritte-ui-bottom-sheet';\nimport { BreadcrumbsDivider } from '@hh.ru/magritte-ui-breadcrumbs/BreadcrumbsDivider';\nimport type { BreadcrumbsItem, BreadcrumbsProps } from '@hh.ru/magritte-ui-breadcrumbs/types';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { Card } from '@hh.ru/magritte-ui-card';\nimport { Drop } from '@hh.ru/magritte-ui-drop';\nimport { Text, TextTypography } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './breadcrumbs.less';\n\nconst MAX_VISIBLE_ITEMS = 5;\nconst TEXT_TYPOGRAPHY = 'label-3-regular';\n// Допуск на погрешность округления при сравнении суммы offsetWidth с clientWidth.\nconst OVERFLOW_EPS_PX = 1;\nconst FIRST_COLLAPSIBLE_ITEM_INDEX = 1;\nconst DEFAULT_ARIA_LABEL = 'Хлебные крошки';\nconst DEFAULT_ELLIPSIS_ARIA_LABEL = 'Показать скрытые элементы';\n\nconst measureIntrinsicWidth = (element: HTMLElement | null | undefined) => {\n if (!element) {\n return 0;\n }\n\n // Временно форсируем натуральную ширину: к этому моменту первая крошка\n // уже может быть сжата flex-shrink, и offsetWidth будет занижен.\n element.classList.add(styles.itemIntrinsicWidth);\n const measuredWidth = element.offsetWidth;\n element.classList.remove(styles.itemIntrinsicWidth);\n\n return measuredWidth;\n};\n\nconst arrayFromRange = (start: number, end: number) => {\n return start <= end ? [...Array(end - start + 1).keys()].map((x) => x + start) : [];\n};\n\nconst makeItemKey = (children: Array<BreadcrumbsItem>, index: number): React.Key => {\n return (\n children[index].key ??\n (typeof children[index].props.children === 'string' ? children[index].props.children : index)\n );\n};\n\nconst getMinHiddenCount = (length: number) => {\n return length > MAX_VISIBLE_ITEMS ? length - (MAX_VISIBLE_ITEMS - 1) : 0;\n};\n\n/**\n * В спецификации указано, что breadcrumbs не может отображать более 5-ти элементов.\n *\n * Варианты отображения breadcrumbs:\n * -> link / link / link / link / text\n * или\n * -> link / ellipsis / link / link / text\n *\n * Если лимит будет превышен, компонент схлопнет в ellipsis все элементы, которые окажутся между первым и\n * тремя последними элементами. Таким образом breadcrumbs будет приведен к виду -> link / ellipsis / link / link / text,\n * где ellipsis — это кнопка, раскрывающая дроп-контейнер, в который складываются сколлапсировавшие элементы.\n *\n * Если после лимитирования контейнер-родитель всё равно не будет умещать в себе контент, то видимые элементы\n * один за другим начнут коллапсировать до максимально возможного уровеня сворачивания элементов:\n * -> link / ellipsis / text.\n *\n * Если и после этого контент все равно будет слишком широким, первый элемент начнет уменьшаться с text-overflow:ellipsis.\n *\n * Все пункты остаются в одном `ol` в порядке иерархии. Свёрнутые `li` выводятся из flex-раскладки\n * и остаются в DOM для SEO.\n */\nexport const Breadcrumbs: React.FC<BreadcrumbsProps> = ({\n children,\n 'aria-label': ariaLabel = DEFAULT_ARIA_LABEL,\n ellipsisAriaLabel = DEFAULT_ELLIPSIS_ARIA_LABEL,\n 'data-qa': dataQa,\n}) => {\n const listRef = useRef<HTMLOListElement>(null);\n const ellipsisRef = useRef<HTMLLIElement>(null);\n const activatorRef = useRef<HTMLButtonElement>(null);\n\n const [hiddenCount, setHiddenCount] = useState(() => getMinHiddenCount(children.length));\n const [expandCollapsedItems, setExpandCollapsedItems] = useState(false);\n const showEllipsis = hiddenCount > 0;\n\n const itemRefs = useRef<Record<number, HTMLLIElement>>({});\n const itemRefCallbacks = useMemo<React.RefCallback<HTMLLIElement>[]>(\n () =>\n [...Array(children.length).keys()].map((_, index) => (element: HTMLLIElement) => {\n itemRefs.current[index] = element;\n }),\n [children.length]\n );\n\n const { isMobile } = useBreakpoint();\n // Сжимаем первую крошку только когда больше нечего коллапсировать,\n // иначе она «отдаёт» ширину соседним и они налезают друг на друга.\n const canShrinkFirstItem = children.length <= 2 || hiddenCount >= children.length - 2;\n\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n const checkIfItemsCollapsed = useCallback(\n throttle(() => {\n const list = listRef.current;\n if (!list || children.length <= 1) {\n setHiddenCount(0);\n setExpandCollapsedItems(false);\n return;\n }\n\n const containerWidth = list.clientWidth;\n const length = children.length;\n const minHidden = getMinHiddenCount(length);\n const maxHidden = length - 2;\n const ellipsisWidth = ellipsisRef.current?.offsetWidth ?? 0;\n // offsetWidth первой крошки может быть уже сжатым — для расчёта нужна полная ширина,\n // иначе соседние пункты останутся видимыми и налезут друг на друга.\n const firstItemWidth = measureIntrinsicWidth(itemRefs.current[0]);\n\n let nextHidden = minHidden;\n\n // Ищем минимальное число скрытых средних пунктов, при котором\n // first + (ellipsis) + видимые средние + last влезают в контейнер.\n // Начинаем с minHidden (лимит в 5 видимых) и при нехватке места\n // прячем пункты слева направо до first / ellipsis / last.\n for (let hidden = minHidden; hidden <= maxHidden; hidden++) {\n let totalWidth = firstItemWidth + (itemRefs.current[length - 1]?.offsetWidth ?? 0);\n\n if (hidden > 0) {\n totalWidth += ellipsisWidth;\n }\n\n for (let index = hidden + FIRST_COLLAPSIBLE_ITEM_INDEX; index < length - 1; index++) {\n totalWidth += itemRefs.current[index]?.offsetWidth ?? 0;\n }\n\n nextHidden = hidden;\n\n if (totalWidth <= containerWidth + OVERFLOW_EPS_PX) {\n break;\n }\n }\n\n setHiddenCount(nextHidden);\n if (nextHidden === 0) {\n setExpandCollapsedItems(false);\n }\n }, 50),\n [children.length]\n );\n\n useLayoutEffect(checkIfItemsCollapsed);\n useResize(checkIfItemsCollapsed);\n\n const renderCollapsedItems = (itemClassName: string, typography: TextTypography) => {\n if (!showEllipsis) {\n return null;\n }\n\n return arrayFromRange(FIRST_COLLAPSIBLE_ITEM_INDEX, hiddenCount).map((index) => {\n const { Element = 'a', children: child, ...props } = children[index].props;\n return (\n <div className={itemClassName} key={makeItemKey(children, index)}>\n <Card\n {...props}\n Element={Element}\n borderRadius={12}\n padding={8}\n paddingLeft={12}\n paddingRight={12}\n style=\"primary\"\n hoverStyle=\"secondary\"\n hoverEnabled\n pressEnabled\n stretched\n >\n <div className={styles.interactiveText}>\n <Text Element=\"div\" typography={typography}>\n <div className={styles.textWithEllipsis}>{child}</div>\n </Text>\n </div>\n </Card>\n </div>\n );\n });\n };\n\n const renderLastItem = () => {\n if (children.length === 0) {\n return null;\n }\n\n const index = children.length - 1;\n const { children: child, href, ...props } = { ...children[index].props };\n return (\n <li className={styles.item} ref={itemRefCallbacks[index]}>\n <div className={styles.staticText}>\n <Text {...props} Element=\"span\" typography={TEXT_TYPOGRAPHY} aria-current=\"page\">\n {child}\n </Text>\n </div>\n </li>\n );\n };\n\n return (\n <nav className={styles.breadcrumbs} aria-label={ariaLabel} data-qa={dataQa}>\n <ol className={styles.unbreakableContainer} ref={listRef}>\n {/*\n Нулевой айтем имеет text-overflow:ellipsis, все остальные скрываются целиком.\n Он начнет уменьшаться, только если все остальные айтемы, кроме последнего, уже были скрыты.\n */}\n {children.length > 1 && (\n <li\n className={classnames(styles.item, styles.firstItem, {\n [styles.firstItemShrinkable]: canShrinkFirstItem,\n })}\n ref={itemRefCallbacks[0]}\n >\n <div className={styles.firstItemContent}>\n {cloneElement(\n children[0],\n undefined,\n <span className={styles.textWithEllipsis}>{children[0].props.children}</span>\n )}\n </div>\n <BreadcrumbsDivider />\n </li>\n )}\n\n {/*\n Свёрнутые айтемы остаются в DOM в порядке иерархии для SEO,\n но выводятся из flex-раскладки через position:absolute + visibility:hidden.\n inert исключает ссылки из таб-порядка и accessibility tree.\n */}\n {arrayFromRange(FIRST_COLLAPSIBLE_ITEM_INDEX, hiddenCount).map((index) => (\n <li\n className={classnames(styles.item, styles.invisibleContainer)}\n key={makeItemKey(children, index)}\n ref={itemRefCallbacks[index]}\n // атрибут не завезли в типы react 18, только с 19го\n {...{ inert: '' }}\n >\n {children[index]}\n <BreadcrumbsDivider />\n </li>\n ))}\n\n {/*\n Эллипсис всегда в DOM (если пунктов больше двух), чтобы расчёт коллапса\n сразу знал его ширину и не мигал при появлении кнопки.\n Если свёрнутых айтемов нет — прячем через invisibleContainer + inert.\n */}\n {children.length > 2 && (\n <li\n className={classnames(styles.item, { [styles.invisibleContainer]: !showEllipsis })}\n data-qa=\"breadcrumbs-action\"\n ref={ellipsisRef}\n {...(!showEllipsis ? { inert: '' } : undefined)}\n >\n <button\n type=\"button\"\n className={styles.ellipsis}\n ref={activatorRef}\n aria-label={ellipsisAriaLabel}\n aria-expanded={expandCollapsedItems}\n aria-haspopup={isMobile ? 'dialog' : 'menu'}\n onClick={() => setExpandCollapsedItems(!expandCollapsedItems)}\n >\n <span className={styles.interactiveText}>\n <Text Element=\"span\" typography={TEXT_TYPOGRAPHY}>\n ...\n </Text>\n </span>\n </button>\n <BreadcrumbsDivider />\n {showEllipsis &&\n (isMobile ? (\n <BottomSheet\n visible={expandCollapsedItems}\n onClose={() => setExpandCollapsedItems(false)}\n >\n {renderCollapsedItems(styles.bottomSheetItem, 'label-2-regular')}\n </BottomSheet>\n ) : (\n <Drop\n activatorRef={activatorRef}\n placement=\"bottom-left\"\n padding={12}\n visible={expandCollapsedItems}\n onClose={() => setExpandCollapsedItems(false)}\n role=\"menu\"\n >\n {renderCollapsedItems(styles.dropItem, TEXT_TYPOGRAPHY)}\n </Drop>\n ))}\n </li>\n )}\n\n {/*\n Видимые средние айтемы между эллипсисом и последним пунктом.\n При нехватке места скрываются слева направо до вида link / ellipsis / text.\n Последний айтем имеет наибольший приоритет и никогда не скрывается.\n */}\n {arrayFromRange(hiddenCount + FIRST_COLLAPSIBLE_ITEM_INDEX, children.length - 2).map((index) => (\n <li className={styles.item} key={makeItemKey(children, index)} ref={itemRefCallbacks[index]}>\n {children[index]}\n <BreadcrumbsDivider />\n </li>\n ))}\n\n {renderLastItem()}\n </ol>\n </nav>\n );\n};\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import './index.css';
2
2
  import { jsx } from 'react/jsx-runtime';
3
3
  import { Text } from '@hh.ru/magritte-ui-typography';
4
- import { s as styles } from './breadcrumbs-GKQSyUfi.js';
4
+ import { s as styles } from './breadcrumbs-BblumBkP.js';
5
5
 
6
6
  const BreadcrumbsDivider = () => {
7
- return (jsx("span", { className: styles.divider, children: jsx(Text, { Element: "span", typography: "label-3-regular", children: "/" }) }));
7
+ return (jsx("span", { className: styles.divider, "aria-hidden": "true", children: jsx(Text, { Element: "span", typography: "label-3-regular", children: "/" }) }));
8
8
  };
9
9
 
10
10
  export { BreadcrumbsDivider };
@@ -1 +1 @@
1
- {"version":3,"file":"BreadcrumbsDivider.js","sources":["src/BreadcrumbsDivider.tsx"],"sourcesContent":["import { FC } from 'react';\n\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './breadcrumbs.less';\n\nexport const BreadcrumbsDivider: FC = () => {\n return (\n <span className={styles.divider}>\n <Text Element=\"span\" typography=\"label-3-regular\">\n /\n </Text>\n </span>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;AAMO,MAAM,kBAAkB,GAAO,MAAK;IACvC,QACIA,cAAM,SAAS,EAAE,MAAM,CAAC,OAAO,YAC3BA,GAAC,CAAA,IAAI,IAAC,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,iBAAiB,EAAA,QAAA,EAAA,GAAA,EAAA,CAE1C,EACJ,CAAA,EACT;AACN;;;;"}
1
+ {"version":3,"file":"BreadcrumbsDivider.js","sources":["src/BreadcrumbsDivider.tsx"],"sourcesContent":["import { FC } from 'react';\n\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './breadcrumbs.less';\n\nexport const BreadcrumbsDivider: FC = () => {\n return (\n <span className={styles.divider} aria-hidden=\"true\">\n <Text Element=\"span\" typography=\"label-3-regular\">\n /\n </Text>\n </span>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;AAMO,MAAM,kBAAkB,GAAO,MAAK;IACvC,QACIA,cAAM,SAAS,EAAE,MAAM,CAAC,OAAO,EAAc,aAAA,EAAA,MAAM,EAC/C,QAAA,EAAAA,GAAA,CAAC,IAAI,EAAC,EAAA,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,iBAAiB,EAAA,QAAA,EAAA,GAAA,EAAA,CAE1C,EACJ,CAAA,EACT;AACN;;;;"}
@@ -2,10 +2,10 @@ import './index.css';
2
2
  import { jsx } from 'react/jsx-runtime';
3
3
  import { Link } from '@hh.ru/magritte-ui-link';
4
4
  import { Text } from '@hh.ru/magritte-ui-typography';
5
- import { s as styles } from './breadcrumbs-GKQSyUfi.js';
5
+ import { s as styles } from './breadcrumbs-BblumBkP.js';
6
6
 
7
7
  const BreadcrumbsItem = ({ Element = 'a', children, ...rest }) => {
8
- return (jsx(Link, { Element: Element, ...rest, typography: "label-3-regular", inline: true, children: jsx("div", { className: styles.interactiveText, children: jsx(Text, { Element: "span", typography: "label-3-regular", children: children }) }) }));
8
+ return (jsx(Link, { Element: Element, ...rest, typography: "label-3-regular", inline: true, children: jsx("span", { className: styles.interactiveText, children: jsx(Text, { Element: "span", typography: "label-3-regular", children: children }) }) }));
9
9
  };
10
10
 
11
11
  export { BreadcrumbsItem };
@@ -1 +1 @@
1
- {"version":3,"file":"BreadcrumbsItem.js","sources":["src/BreadcrumbsItem.tsx"],"sourcesContent":["import type { PolymorphicComponent } from '@hh.ru/magritte-types';\nimport type { BreadcrumbsItemProps } from '@hh.ru/magritte-ui-breadcrumbs/types';\nimport { Link } from '@hh.ru/magritte-ui-link';\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './breadcrumbs.less';\n\nexport const BreadcrumbsItem: PolymorphicComponent<BreadcrumbsItemProps, 'a'> = ({\n Element = 'a',\n children,\n ...rest\n}) => {\n return (\n <Link Element={Element} {...rest} typography=\"label-3-regular\" inline>\n <div className={styles.interactiveText}>\n <Text Element=\"span\" typography=\"label-3-regular\">\n {children}\n </Text>\n </div>\n </Link>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;AAOa,MAAA,eAAe,GAAoD,CAAC,EAC7E,OAAO,GAAG,GAAG,EACb,QAAQ,EACR,GAAG,IAAI,EACV,KAAI;AACD,IAAA,QACIA,GAAC,CAAA,IAAI,EAAC,EAAA,OAAO,EAAE,OAAO,EAAA,GAAM,IAAI,EAAE,UAAU,EAAC,iBAAiB,EAAC,MAAM,EAAA,IAAA,EAAA,QAAA,EACjEA,aAAK,SAAS,EAAE,MAAM,CAAC,eAAe,EAClC,QAAA,EAAAA,GAAA,CAAC,IAAI,EAAC,EAAA,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,iBAAiB,EAC5C,QAAA,EAAA,QAAQ,GACN,EACL,CAAA,EAAA,CACH,EACT;AACN;;;;"}
1
+ {"version":3,"file":"BreadcrumbsItem.js","sources":["src/BreadcrumbsItem.tsx"],"sourcesContent":["import type { PolymorphicComponent } from '@hh.ru/magritte-types';\nimport type { BreadcrumbsItemProps } from '@hh.ru/magritte-ui-breadcrumbs/types';\nimport { Link } from '@hh.ru/magritte-ui-link';\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './breadcrumbs.less';\n\nexport const BreadcrumbsItem: PolymorphicComponent<BreadcrumbsItemProps, 'a'> = ({\n Element = 'a',\n children,\n ...rest\n}) => {\n return (\n <Link Element={Element} {...rest} typography=\"label-3-regular\" inline>\n <span className={styles.interactiveText}>\n <Text Element=\"span\" typography=\"label-3-regular\">\n {children}\n </Text>\n </span>\n </Link>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;AAOa,MAAA,eAAe,GAAoD,CAAC,EAC7E,OAAO,GAAG,GAAG,EACb,QAAQ,EACR,GAAG,IAAI,EACV,KAAI;AACD,IAAA,QACIA,GAAC,CAAA,IAAI,EAAC,EAAA,OAAO,EAAE,OAAO,EAAA,GAAM,IAAI,EAAE,UAAU,EAAC,iBAAiB,EAAC,MAAM,EAAA,IAAA,EAAA,QAAA,EACjEA,cAAM,SAAS,EAAE,MAAM,CAAC,eAAe,EACnC,QAAA,EAAAA,GAAA,CAAC,IAAI,EAAC,EAAA,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,iBAAiB,EAC5C,QAAA,EAAA,QAAQ,GACN,EACJ,CAAA,EAAA,CACJ,EACT;AACN;;;;"}
@@ -0,0 +1,5 @@
1
+ import './index.css';
2
+ var styles = {"breadcrumbs":"magritte-breadcrumbs___Go2gs_7-2-0","unbreakable-container":"magritte-unbreakable-container___VcQQ2_7-2-0","unbreakableContainer":"magritte-unbreakable-container___VcQQ2_7-2-0","invisible-container":"magritte-invisible-container___V0W27_7-2-0","invisibleContainer":"magritte-invisible-container___V0W27_7-2-0","ellipsis":"magritte-ellipsis___-3wI7_7-2-0","item":"magritte-item___oaSMH_7-2-0","first-item":"magritte-first-item___N6MFS_7-2-0","firstItem":"magritte-first-item___N6MFS_7-2-0","first-item-shrinkable":"magritte-first-item-shrinkable___ZDlYS_7-2-0","firstItemShrinkable":"magritte-first-item-shrinkable___ZDlYS_7-2-0","item-intrinsic-width":"magritte-item-intrinsic-width___hf4d2_7-2-0","itemIntrinsicWidth":"magritte-item-intrinsic-width___hf4d2_7-2-0","first-item-content":"magritte-first-item-content___G98CF_7-2-0","firstItemContent":"magritte-first-item-content___G98CF_7-2-0","divider":"magritte-divider___J8lfR_7-2-0","interactive-text":"magritte-interactive-text___fBwYg_7-2-0","interactiveText":"magritte-interactive-text___fBwYg_7-2-0","static-text":"magritte-static-text___pslMP_7-2-0","staticText":"magritte-static-text___pslMP_7-2-0","text-with-ellipsis":"magritte-text-with-ellipsis___bEJaf_7-2-0","textWithEllipsis":"magritte-text-with-ellipsis___bEJaf_7-2-0","bottom-sheet-item":"magritte-bottom-sheet-item___lc1TO_7-2-0","bottomSheetItem":"magritte-bottom-sheet-item___lc1TO_7-2-0","drop-item":"magritte-drop-item___62c-z_7-2-0","dropItem":"magritte-drop-item___62c-z_7-2-0"};
3
+
4
+ export { styles as s };
5
+ //# sourceMappingURL=breadcrumbs-BblumBkP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breadcrumbs-BblumBkP.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
package/index.css CHANGED
@@ -14,53 +14,61 @@
14
14
  --magritte-color-component-breadcrumbs-text-state-secondary-hovered-v24-8-1:#767676;
15
15
  --magritte-color-component-breadcrumbs-text-state-secondary-pressed-v24-8-1:#5E5E5E;
16
16
  }
17
- .magritte-breadcrumbs___Go2gs_7-1-86{
17
+ .magritte-breadcrumbs___Go2gs_7-2-0{
18
+ position:relative;
19
+ min-width:0;
20
+ max-width:100%;
18
21
  padding:12px 0;
19
22
  }
20
- .magritte-unbreakable-container___VcQQ2_7-1-86{
23
+ .magritte-unbreakable-container___VcQQ2_7-2-0{
21
24
  --magritte-ui-text-color-override:var(--magritte-color-component-breadcrumbs-text-tertiary-v24-8-1);
22
- display:flex;
23
25
  position:relative;
26
+ display:flex;
27
+ flex-wrap:nowrap;
28
+ align-items:center;
29
+ max-width:100%;
30
+ margin:0;
31
+ padding:0;
32
+ overflow:hidden;
33
+ list-style:none;
24
34
  white-space:nowrap;
25
- max-height:20px;
26
- overflow:clip;
27
- }
28
- .magritte-invisible-container___V0W27_7-1-86{
29
- visibility:hidden;
30
35
  }
31
- .magritte-collapsible-container___85hMp_7-1-86{
32
- flex:1 0 auto;
33
- position:relative;
34
- }
35
- .magritte-collapsible-content___OoBp3_7-1-86{
36
+ .magritte-invisible-container___V0W27_7-2-0{
36
37
  position:absolute;
37
- inset:0;
38
- display:flex;
39
- flex-flow:row-reverse wrap;
40
- place-content:flex-start flex-end;
38
+ top:0;
39
+ left:0;
40
+ visibility:hidden;
41
+ pointer-events:none;
41
42
  }
42
- .magritte-ellipsis___-3wI7_7-1-86{
43
+ .magritte-ellipsis___-3wI7_7-2-0{
43
44
  height:20px;
44
45
  width:20px;
45
46
  }
46
- .magritte-ellipsis___-3wI7_7-1-86.focus-visible{
47
+ .magritte-ellipsis___-3wI7_7-2-0.focus-visible{
47
48
  outline:var(--magritte-color-component-action-stroke-state-accent-focused-accessible-v24-8-1) solid 4px;
48
49
  }
49
- .magritte-item___oaSMH_7-1-86{
50
+ .magritte-item___oaSMH_7-2-0{
50
51
  display:flex;
52
+ flex-shrink:0;
51
53
  }
52
- .magritte-first-item___N6MFS_7-1-86{
54
+ .magritte-first-item___N6MFS_7-2-0{
53
55
  min-width:calc(20px + 6px * 2 + 5px);
54
- overflow:clip;
56
+ overflow:hidden;
55
57
  }
56
- .magritte-first-item-content___G98CF_7-1-86{
58
+ .magritte-first-item-shrinkable___ZDlYS_7-2-0{
59
+ flex-shrink:1;
60
+ }
61
+ .magritte-item-intrinsic-width___hf4d2_7-2-0{
62
+ width:max-content;
63
+ min-width:max-content;
64
+ max-width:none;
65
+ flex-shrink:0;
66
+ }
67
+ .magritte-first-item-content___G98CF_7-2-0{
57
68
  min-width:0;
58
69
  display:flex;
59
70
  }
60
- .magritte-item-after-ellipsis___oPDLO_7-1-86{
61
- margin-left:calc(0px - 20px - 6px * 2 - 5px);
62
- }
63
- .magritte-divider___J8lfR_7-1-86{
71
+ .magritte-divider___J8lfR_7-2-0{
64
72
  --magritte-ui-text-color-override:var(--magritte-color-component-breadcrumbs-text-tertiary-v24-8-1);
65
73
  position:relative;
66
74
  bottom:1px;
@@ -68,30 +76,31 @@
68
76
  width:5px;
69
77
  text-align:center;
70
78
  }
71
- .magritte-interactive-text___fBwYg_7-1-86{
79
+ .magritte-interactive-text___fBwYg_7-2-0{
72
80
  --magritte-ui-text-color-override:var(--magritte-color-component-breadcrumbs-text-secondary-v24-8-1);
73
81
  }
74
82
  @media (min-width: 1020px){
75
- body.magritte-old-layout .magritte-interactive-text___fBwYg_7-1-86:hover{
83
+ body.magritte-old-layout .magritte-interactive-text___fBwYg_7-2-0:hover{
76
84
  --magritte-ui-text-color-override:var(--magritte-color-component-breadcrumbs-text-state-secondary-hovered-v24-8-1);
77
85
  }
78
86
  }
79
87
  @media (min-width: 1024px){
80
- body:not(.magritte-old-layout) .magritte-interactive-text___fBwYg_7-1-86:hover{
88
+ body:not(.magritte-old-layout) .magritte-interactive-text___fBwYg_7-2-0:hover{
81
89
  --magritte-ui-text-color-override:var(--magritte-color-component-breadcrumbs-text-state-secondary-hovered-v24-8-1);
82
90
  }
83
91
  }
84
- .magritte-interactive-text___fBwYg_7-1-86:active{
92
+ .magritte-interactive-text___fBwYg_7-2-0:active{
85
93
  --magritte-ui-text-color-override:var(--magritte-color-component-breadcrumbs-text-state-secondary-pressed-v24-8-1);
86
94
  }
87
- .magritte-static-text___pslMP_7-1-86{
95
+ .magritte-static-text___pslMP_7-2-0{
88
96
  --magritte-ui-text-color-override:var(--magritte-color-component-breadcrumbs-text-primary-v24-8-1);
89
97
  }
90
- .magritte-text-with-ellipsis___bEJaf_7-1-86{
98
+ .magritte-text-with-ellipsis___bEJaf_7-2-0{
99
+ display:block;
91
100
  overflow:hidden;
92
101
  text-overflow:ellipsis;
93
102
  }
94
- .magritte-bottom-sheet-item___lc1TO_7-1-86{
103
+ .magritte-bottom-sheet-item___lc1TO_7-2-0{
95
104
  --magritte-ui-text-color-override:var(--magritte-color-component-breadcrumbs-text-primary-v24-8-1);
96
105
  overflow:hidden;
97
106
  text-overflow:ellipsis;
@@ -99,9 +108,9 @@
99
108
  line-height:22px;
100
109
  margin-bottom:8px;
101
110
  }
102
- .magritte-drop-item___62c-z_7-1-86{
111
+ .magritte-drop-item___62c-z_7-2-0{
103
112
  --magritte-ui-text-color-override:var(--magritte-color-component-breadcrumbs-text-primary-v24-8-1);
104
113
  }
105
- .magritte-drop-item___62c-z_7-1-86:not(:last-child){
114
+ .magritte-drop-item___62c-z_7-2-0:not(:last-child){
106
115
  margin-bottom:4px;
107
116
  }
package/index.js CHANGED
@@ -9,7 +9,7 @@ import '@hh.ru/magritte-common-resize';
9
9
  import '@hh.ru/magritte-ui-bottom-sheet';
10
10
  import './BreadcrumbsDivider.js';
11
11
  import '@hh.ru/magritte-ui-typography';
12
- import './breadcrumbs-GKQSyUfi.js';
12
+ import './breadcrumbs-BblumBkP.js';
13
13
  import '@hh.ru/magritte-ui-breakpoint';
14
14
  import '@hh.ru/magritte-ui-card';
15
15
  import '@hh.ru/magritte-ui-drop';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hh.ru/magritte-ui-breadcrumbs",
3
- "version": "7.1.86",
3
+ "version": "7.2.0",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "sideEffects": [
@@ -38,5 +38,5 @@
38
38
  "publishConfig": {
39
39
  "access": "public"
40
40
  },
41
- "gitHead": "a75eacf05a65406cd60e0fdf9fde2f4427939309"
41
+ "gitHead": "6a072b1c4d5d501643d7e3c42992df44bae64465"
42
42
  }
package/types.d.ts CHANGED
@@ -13,6 +13,16 @@ export type BreadcrumbsItem = React.ReactElement<BreadcrumbsItemProps & React.DO
13
13
  export interface BreadcrumbsProps {
14
14
  /** Массив элементов из которых будет построена цепочка навигации */
15
15
  children: Array<BreadcrumbsItem>;
16
+ /**
17
+ * Лейбл для скринридеров
18
+ * @default Хлебные крошки
19
+ */
20
+ 'aria-label'?: string;
21
+ /**
22
+ * Лейбл кнопки эллипсиса для скринридеров
23
+ * @default Показать скрытые элементы
24
+ */
25
+ ellipsisAriaLabel?: string;
16
26
  /** data-qa атрибут */
17
27
  'data-qa'?: string;
18
28
  }
@@ -1,5 +0,0 @@
1
- import './index.css';
2
- var styles = {"breadcrumbs":"magritte-breadcrumbs___Go2gs_7-1-86","unbreakable-container":"magritte-unbreakable-container___VcQQ2_7-1-86","unbreakableContainer":"magritte-unbreakable-container___VcQQ2_7-1-86","invisible-container":"magritte-invisible-container___V0W27_7-1-86","invisibleContainer":"magritte-invisible-container___V0W27_7-1-86","collapsible-container":"magritte-collapsible-container___85hMp_7-1-86","collapsibleContainer":"magritte-collapsible-container___85hMp_7-1-86","collapsible-content":"magritte-collapsible-content___OoBp3_7-1-86","collapsibleContent":"magritte-collapsible-content___OoBp3_7-1-86","ellipsis":"magritte-ellipsis___-3wI7_7-1-86","item":"magritte-item___oaSMH_7-1-86","first-item":"magritte-first-item___N6MFS_7-1-86","firstItem":"magritte-first-item___N6MFS_7-1-86","first-item-content":"magritte-first-item-content___G98CF_7-1-86","firstItemContent":"magritte-first-item-content___G98CF_7-1-86","item-after-ellipsis":"magritte-item-after-ellipsis___oPDLO_7-1-86","itemAfterEllipsis":"magritte-item-after-ellipsis___oPDLO_7-1-86","divider":"magritte-divider___J8lfR_7-1-86","interactive-text":"magritte-interactive-text___fBwYg_7-1-86","interactiveText":"magritte-interactive-text___fBwYg_7-1-86","static-text":"magritte-static-text___pslMP_7-1-86","staticText":"magritte-static-text___pslMP_7-1-86","text-with-ellipsis":"magritte-text-with-ellipsis___bEJaf_7-1-86","textWithEllipsis":"magritte-text-with-ellipsis___bEJaf_7-1-86","bottom-sheet-item":"magritte-bottom-sheet-item___lc1TO_7-1-86","bottomSheetItem":"magritte-bottom-sheet-item___lc1TO_7-1-86","drop-item":"magritte-drop-item___62c-z_7-1-86","dropItem":"magritte-drop-item___62c-z_7-1-86"};
3
-
4
- export { styles as s };
5
- //# sourceMappingURL=breadcrumbs-GKQSyUfi.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"breadcrumbs-GKQSyUfi.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}