@snack-uikit/breadcrumbs 0.5.1 → 0.6.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +2 -1
  3. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +6 -6
  4. package/dist/components/Breadcrumbs/Breadcrumbs.js +7 -9
  5. package/dist/components/Collapse/Collapse.js +4 -4
  6. package/dist/components/Crumb/Crumb.d.ts +1 -2
  7. package/dist/components/Crumb/Crumb.js +6 -6
  8. package/dist/components/CrumbsTypography/CrumbsTypography.d.ts +1 -1
  9. package/dist/components/CrumbsTypography/CrumbsTypography.js +2 -2
  10. package/dist/components/HiddenChain/HiddenChain.d.ts +1 -2
  11. package/dist/components/HiddenChain/hooks.js +5 -5
  12. package/dist/components/Separator/Separator.js +2 -2
  13. package/dist/components/Wrapper/Wrapper.d.ts +1 -1
  14. package/dist/constants.d.ts +15 -15
  15. package/dist/constants.js +15 -18
  16. package/dist/context.d.ts +1 -1
  17. package/dist/context.js +2 -2
  18. package/dist/types.d.ts +12 -8
  19. package/dist/types.js +1 -1
  20. package/dist/utils/buildBreadcrumbsConfigs.js +25 -21
  21. package/dist/utils/buildSizeMap.js +5 -5
  22. package/package.json +5 -5
  23. package/src/components/Breadcrumbs/Breadcrumbs.tsx +9 -15
  24. package/src/components/Collapse/Collapse.tsx +5 -5
  25. package/src/components/Crumb/Crumb.tsx +7 -7
  26. package/src/components/CrumbsTypography/CrumbsTypography.tsx +3 -8
  27. package/src/components/HiddenChain/HiddenChain.tsx +1 -2
  28. package/src/components/HiddenChain/hooks.tsx +6 -6
  29. package/src/components/Separator/Separator.tsx +2 -2
  30. package/src/components/Wrapper/Wrapper.tsx +1 -1
  31. package/src/constants.ts +15 -15
  32. package/src/context.ts +3 -2
  33. package/src/types.ts +16 -8
  34. package/src/utils/buildBreadcrumbsConfigs.ts +26 -22
  35. package/src/utils/buildSizeMap.ts +6 -6
package/CHANGELOG.md CHANGED
@@ -3,6 +3,26 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 0.6.0 (2023-12-14)
7
+
8
+
9
+ ### BREAKING CHANGES
10
+
11
+
12
+ * **FF-3729:** replace enum with unions ([910db4a](https://github.com/cloud-ru-tech/snack-uikit/commit/910db4aa8231ccbc58e538e5c5c1f461b1dec275))
13
+
14
+
15
+
16
+
17
+ ## 0.5.2 (2023-12-07)
18
+
19
+ ### Only dependencies have been changed
20
+ * [@snack-uikit/popover@0.5.2](https://git.sbercloud.tech/sbercloud-ui/tokens-design-system/snack-uikit/-/blob/master/packages/popover/CHANGELOG.md)
21
+
22
+
23
+
24
+
25
+
6
26
  ## 0.5.1 (2023-12-06)
7
27
 
8
28
  ### Only dependencies have been changed
package/README.md CHANGED
@@ -9,13 +9,14 @@
9
9
  [//]: DOCUMENTATION_SECTION_START
10
10
  [//]: THIS_SECTION_IS_AUTOGENERATED_PLEASE_DONT_EDIT_IT
11
11
  ## Breadcrumbs
12
+ Компонент хлебных крошек
12
13
  ### Props
13
14
  | name | type | default value | description |
14
15
  |------|------|---------------|-------------|
15
16
  | items* | `Item[]` | - | Массив айтемов |
16
17
  | className | `string` | - | CSS-класс |
17
18
  | separator | `string` | "›" | Разделитель |
18
- | size | enum Size: `"xs"`, `"s"` | Breadcrumbs.sizes.S | Размер |
19
+ | size | enum Size: `"xs"`, `"s"` | s | Размер |
19
20
  | firstItemIconOnly | `boolean` | false | Использовать иконку без лейбла в первом айтеме |
20
21
  | inactiveLastItem | `boolean` | false | Делает некликабельным последний элемент, даже если для него переданы `href` или `onClick` |
21
22
 
@@ -1,7 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { WithSupportProps } from '@snack-uikit/utils';
3
- import { Size } from '../../constants';
4
- import { Item } from '../../types';
3
+ import { Item, Size } from '../../types';
5
4
  export type BreadcrumbsProps = WithSupportProps<{
6
5
  /** Массив айтемов */
7
6
  items: Item[];
@@ -14,7 +13,7 @@ export type BreadcrumbsProps = WithSupportProps<{
14
13
  separator?: string;
15
14
  /**
16
15
  * Размер
17
- * @default Breadcrumbs.sizes.S
16
+ * @default s
18
17
  */
19
18
  size?: Size;
20
19
  /**
@@ -28,6 +27,7 @@ export type BreadcrumbsProps = WithSupportProps<{
28
27
  */
29
28
  inactiveLastItem?: boolean;
30
29
  }>;
31
- export declare const Breadcrumbs: import("react").NamedExoticComponent<BreadcrumbsProps> & {
32
- sizes: typeof Size;
33
- };
30
+ /**
31
+ * Компонент хлебных крошек
32
+ */
33
+ export declare const Breadcrumbs: import("react").NamedExoticComponent<BreadcrumbsProps>;
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  import { memo, useMemo, useRef } from 'react';
14
- import { ElementType, ItemRenderMode, SEPARATOR, Size } from '../../constants';
14
+ import { ELEMENT_TYPE, ITEM_RENDER_MODE, SEPARATOR, SIZE } from '../../constants';
15
15
  import { useBreadcrumbsLayout } from '../../hooks';
16
16
  import { Collapse } from '../Collapse';
17
17
  import { Crumb } from '../Crumb';
@@ -21,8 +21,8 @@ import { Wrapper } from '../Wrapper';
21
21
  /**
22
22
  * Компонент хлебных крошек
23
23
  */
24
- const BreadcrumbsComponent = memo(function Breadcrumbs(_a) {
25
- var { items: itemsProps, size = Size.S, separator = SEPARATOR, className, firstItemIconOnly = false, inactiveLastItem = false } = _a, rest = __rest(_a, ["items", "size", "separator", "className", "firstItemIconOnly", "inactiveLastItem"]);
24
+ export const Breadcrumbs = memo(function Breadcrumbs(_a) {
25
+ var { items: itemsProps, size = SIZE.S, separator = SEPARATOR, className, firstItemIconOnly = false, inactiveLastItem = false } = _a, rest = __rest(_a, ["items", "size", "separator", "className", "firstItemIconOnly", "inactiveLastItem"]);
26
26
  const containerRef = useRef(null);
27
27
  const { setConfigs, currentConfig } = useBreadcrumbsLayout(containerRef);
28
28
  const items = useMemo(() => inactiveLastItem
@@ -31,13 +31,13 @@ const BreadcrumbsComponent = memo(function Breadcrumbs(_a) {
31
31
  return (_jsxs(_Fragment, { children: [_jsx(HiddenChain, { items: items, size: size, separator: separator, onConfigsBuilt: setConfigs, firstItemIconOnly: firstItemIconOnly }), _jsx(Wrapper, Object.assign({}, rest, { ref: containerRef, hidden: false, size: size, separator: separator, className: className }, { children: currentConfig === null || currentConfig === void 0 ? void 0 : currentConfig.chain.map((block, index, array) => {
32
32
  const isLastElement = index === array.length - 1;
33
33
  switch (block.element) {
34
- case ElementType.Separator:
34
+ case ELEMENT_TYPE.Separator:
35
35
  return _jsx(Separator, {}, index);
36
- case ElementType.Collapse:
36
+ case ELEMENT_TYPE.Collapse:
37
37
  return _jsx(Collapse, { currentConfig: currentConfig.chain }, index);
38
- case ElementType.Item:
38
+ case ELEMENT_TYPE.Item:
39
39
  const { renderMode, id } = block.item;
40
- if (renderMode !== ItemRenderMode.Collapsed) {
40
+ if (renderMode !== ITEM_RENDER_MODE.Collapsed) {
41
41
  return (_jsx(Crumb, { useIconOnly: !index && firstItemIconOnly, current: isLastElement, renderMode: renderMode, minWidth: block.width, item: block.item }, id));
42
42
  }
43
43
  default:
@@ -45,5 +45,3 @@ const BreadcrumbsComponent = memo(function Breadcrumbs(_a) {
45
45
  }
46
46
  }) }))] }));
47
47
  });
48
- export const Breadcrumbs = BreadcrumbsComponent;
49
- Breadcrumbs.sizes = Size;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useContext } from 'react';
3
3
  import { Popover } from '@snack-uikit/popover';
4
- import { ElementType, ItemRenderMode } from '../../constants';
4
+ import { ELEMENT_TYPE, ITEM_RENDER_MODE } from '../../constants';
5
5
  import { BreadcrumbsContext } from '../../context';
6
6
  import { getTestId } from '../../utils';
7
7
  import { Crumb } from '../Crumb';
@@ -12,12 +12,12 @@ export function Collapse({ currentConfig, className }) {
12
12
  const ctx = useContext(BreadcrumbsContext);
13
13
  const { hidden, size, testId } = ctx;
14
14
  const collapsedItems = currentConfig.map(node => {
15
- if (node.element === ElementType.Item && node.item.renderMode === ItemRenderMode.Collapsed) {
15
+ if (node.element === ELEMENT_TYPE.Item && node.item.renderMode === ITEM_RENDER_MODE.Collapsed) {
16
16
  const { id } = node.item;
17
- return (_jsxs("div", Object.assign({ className: styles.collapsedRow }, { children: [_jsx(Crumb, { item: node.item, renderMode: ItemRenderMode.Full }), _jsx(Separator, {})] }), id));
17
+ return (_jsxs("div", Object.assign({ className: styles.collapsedRow }, { children: [_jsx(Crumb, { item: node.item, renderMode: ITEM_RENDER_MODE.Full }), _jsx(Separator, {})] }), id));
18
18
  }
19
19
  return null;
20
20
  });
21
21
  const tip = (_jsx(BreadcrumbsContext.Provider, Object.assign({ value: Object.assign(Object.assign({}, ctx), { testId: `${testId}-collapsed` }) }, { children: collapsedItems })));
22
- return (_jsx("div", Object.assign({ className: className, "data-test-id": getTestId('collapse', testId), "data-element-type": ElementType.Collapse }, { children: _jsx(Popover, Object.assign({ tip: tip, trigger: Popover.triggers.HoverAndFocusVisible, placement: Popover.placements.Top }, { children: _jsx("button", Object.assign({ className: styles.collapse, tabIndex: hidden ? -1 : 0 }, { children: _jsx(CrumbsTypography, Object.assign({ size: size }, { children: "..." })) })) })) })));
22
+ return (_jsx("div", Object.assign({ className: className, "data-test-id": getTestId('collapse', testId), "data-element-type": ELEMENT_TYPE.Collapse }, { children: _jsx(Popover, Object.assign({ tip: tip, trigger: 'hoverAndFocusVisible', placement: 'top' }, { children: _jsx("button", Object.assign({ className: styles.collapse, tabIndex: hidden ? -1 : 0 }, { children: _jsx(CrumbsTypography, Object.assign({ size: size }, { children: "..." })) })) })) })));
23
23
  }
@@ -1,7 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { WithSupportProps } from '@snack-uikit/utils';
3
- import { ItemRenderMode } from '../../constants';
4
- import { Item } from '../../types';
3
+ import { Item, ItemRenderMode } from '../../types';
5
4
  export type CrumbProps = WithSupportProps<{
6
5
  renderMode: ItemRenderMode;
7
6
  className?: string;
@@ -13,7 +13,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
13
13
  import cn from 'classnames';
14
14
  import { memo, useContext } from 'react';
15
15
  import { extractSupportProps } from '@snack-uikit/utils';
16
- import { ElementType, ItemRenderMode } from '../../constants';
16
+ import { ELEMENT_TYPE, ITEM_RENDER_MODE } from '../../constants';
17
17
  import { BreadcrumbsContext } from '../../context';
18
18
  import { getTestId } from '../../utils';
19
19
  import { CrumbsTypography } from '../CrumbsTypography';
@@ -23,9 +23,9 @@ export const Crumb = memo(function Crumb(_a) {
23
23
  var { minWidth: minWidthProp = 0, current = false, renderMode, className, item: { label: labelProp, shortLabel, icon: Icon, id, onClick, href }, useIconOnly: useIconOnlyProp } = _a, rest = __rest(_a, ["minWidth", "current", "renderMode", "className", "item", "useIconOnly"]);
24
24
  const { hidden, size, testId } = useContext(BreadcrumbsContext);
25
25
  const isLabelShouldBeEllipse = hidden && labelProp.length > ELLIPSIS_LABEL_LENGTH;
26
- const label = isLabelShouldBeEllipse && renderMode === ItemRenderMode.Ellipsis ? `${labelProp.substring(0, 4)}...` : labelProp;
26
+ const label = isLabelShouldBeEllipse && renderMode === ITEM_RENDER_MODE.Ellipsis ? `${labelProp.substring(0, 4)}...` : labelProp;
27
27
  const useIconOnly = Boolean(Icon && useIconOnlyProp);
28
- const minWidth = minWidthProp && renderMode === ItemRenderMode.Ellipsis ? minWidthProp : 'auto';
28
+ const minWidth = minWidthProp && renderMode === ITEM_RENDER_MODE.Ellipsis ? minWidthProp : 'auto';
29
29
  const dataAttributes = {
30
30
  'data-render-mode': renderMode,
31
31
  'data-current': current,
@@ -33,9 +33,9 @@ export const Crumb = memo(function Crumb(_a) {
33
33
  'data-size': size,
34
34
  'data-id': id,
35
35
  };
36
- const content = (_jsxs(_Fragment, { children: [Icon && (_jsx("div", Object.assign({ className: styles.icon }, { children: _jsx(Icon, { size: 24 }) }))), !useIconOnly && (_jsx(CrumbsTypography, Object.assign({ size: size, className: styles.label }, { children: renderMode === ItemRenderMode.ShortLabel ? shortLabel : label })))] }));
36
+ const content = (_jsxs(_Fragment, { children: [Icon && (_jsx("div", Object.assign({ className: styles.icon }, { children: _jsx(Icon, { size: 24 }) }))), !useIconOnly && (_jsx(CrumbsTypography, Object.assign({ size: size, className: styles.label }, { children: renderMode === ITEM_RENDER_MODE.ShortLabel ? shortLabel : label })))] }));
37
37
  const tabIndex = hidden ? { tabIndex: -1 } : {};
38
- const title = renderMode === ItemRenderMode.Ellipsis ? label : '';
38
+ const title = renderMode === ITEM_RENDER_MODE.Ellipsis ? label : '';
39
39
  let crumb = null;
40
40
  if (href) {
41
41
  crumb = (_jsx("a", Object.assign({ className: styles.crumb, onClick: onClick, href: href, "aria-label": useIconOnly ? label : undefined, "data-clickable": true }, dataAttributes, tabIndex, { children: content })));
@@ -46,5 +46,5 @@ export const Crumb = memo(function Crumb(_a) {
46
46
  else {
47
47
  crumb = (_jsx("div", Object.assign({ className: styles.crumb }, dataAttributes, { children: content })));
48
48
  }
49
- return (_jsx("li", Object.assign({}, extractSupportProps(rest), dataAttributes, { "data-test-id": getTestId('crumb', testId), className: cn(styles.wrapper, className), "data-element-type": ElementType.Item, style: { minWidth }, title: title }, { children: crumb })));
49
+ return (_jsx("li", Object.assign({}, extractSupportProps(rest), dataAttributes, { "data-test-id": getTestId('crumb', testId), className: cn(styles.wrapper, className), "data-element-type": ELEMENT_TYPE.Item, style: { minWidth }, title: title }, { children: crumb })));
50
50
  });
@@ -1,5 +1,5 @@
1
1
  import { PropsWithChildren } from 'react';
2
- import { Size } from '../../constants';
2
+ import { Size } from '../../types';
3
3
  export type CrumbsTypographyProps = PropsWithChildren<{
4
4
  size: Size;
5
5
  className?: string;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Typography } from '@snack-uikit/typography';
3
- import { Size } from '../../constants';
3
+ import { SIZE } from '../../constants';
4
4
  export function CrumbsTypography({ size, children, className }) {
5
- return (_jsx(Typography, Object.assign({ className: className, size: size === Size.S ? Typography.sizes.L : Typography.sizes.M, tag: Typography.tags.div, family: Typography.families.Sans, role: Typography.roles.Body }, { children: children })));
5
+ return (_jsx(Typography, Object.assign({ className: className, size: size === SIZE.S ? 'l' : 'm', tag: 'div', family: 'sans', purpose: 'body' }, { children: children })));
6
6
  }
@@ -1,6 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { Size } from '../../constants';
3
- import { BreadcrumbsConfig, Item } from '../../types';
2
+ import { BreadcrumbsConfig, Item, Size } from '../../types';
4
3
  export type HiddenChainProps = {
5
4
  separator: string;
6
5
  items: Item[];
@@ -1,19 +1,19 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useMemo } from 'react';
3
- import { ItemRenderMode } from '../../constants';
3
+ import { ITEM_RENDER_MODE } from '../../constants';
4
4
  import { Crumb } from '../Crumb';
5
5
  /**
6
6
  * Варианты отображения для обычного айтема
7
7
  */
8
8
  const NORMAL_MODES = [
9
- [ItemRenderMode.ShortLabel, 'shortLabel'],
10
- [ItemRenderMode.Ellipsis, 'label'],
11
- [ItemRenderMode.Full, 'label'],
9
+ [ITEM_RENDER_MODE.ShortLabel, 'shortLabel'],
10
+ [ITEM_RENDER_MODE.Ellipsis, 'label'],
11
+ [ITEM_RENDER_MODE.Full, 'label'],
12
12
  ];
13
13
  /**
14
14
  * Варианты отображения айтемов состоящих из одной иконки
15
15
  */
16
- const ICON_ONLY_MODES = [[ItemRenderMode.Full, 'label']];
16
+ const ICON_ONLY_MODES = [[ITEM_RENDER_MODE.Full, 'label']];
17
17
  const getItemModesRenderer = (firstItemIconOnly) => (item, index) => {
18
18
  const isIconOnlyMode = !index && firstItemIconOnly;
19
19
  const modes = isIconOnlyMode ? ICON_ONLY_MODES : NORMAL_MODES;
@@ -1,11 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useContext } from 'react';
3
- import { ElementType } from '../../constants';
3
+ import { ELEMENT_TYPE } from '../../constants';
4
4
  import { BreadcrumbsContext } from '../../context';
5
5
  import { getTestId } from '../../utils';
6
6
  import { CrumbsTypography } from '../CrumbsTypography';
7
7
  import styles from './styles.module.css';
8
8
  export function Separator() {
9
9
  const { size, separator, testId } = useContext(BreadcrumbsContext);
10
- return (_jsx("div", Object.assign({ "aria-hidden": true, "data-size": size, className: styles.separator, "data-test-id": getTestId('separator', testId), "data-element-type": ElementType.Separator }, { children: _jsx(CrumbsTypography, Object.assign({ size: size }, { children: separator })) })));
10
+ return (_jsx("div", Object.assign({ "aria-hidden": true, "data-size": size, className: styles.separator, "data-test-id": getTestId('separator', testId), "data-element-type": ELEMENT_TYPE.Separator }, { children: _jsx(CrumbsTypography, Object.assign({ size: size }, { children: separator })) })));
11
11
  }
@@ -1,6 +1,6 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
  import { WithSupportProps } from '@snack-uikit/utils';
3
- import { Size } from '../../constants';
3
+ import { Size } from '../../types';
4
4
  export type WrapperProps = PropsWithChildren<WithSupportProps<{
5
5
  hidden: boolean;
6
6
  className?: string;
@@ -1,16 +1,16 @@
1
1
  export declare const SEPARATOR = "\u203A";
2
- export declare enum ItemRenderMode {
3
- Full = "full",
4
- ShortLabel = "shortLabel",
5
- Ellipsis = "ellipsis",
6
- Collapsed = "collapsed"
7
- }
8
- export declare enum ElementType {
9
- Separator = "separator",
10
- Collapse = "collapse",
11
- Item = "item"
12
- }
13
- export declare enum Size {
14
- Xs = "xs",
15
- S = "s"
16
- }
2
+ export declare const ITEM_RENDER_MODE: {
3
+ readonly Full: "full";
4
+ readonly ShortLabel: "shortLabel";
5
+ readonly Ellipsis: "ellipsis";
6
+ readonly Collapsed: "collapsed";
7
+ };
8
+ export declare const ELEMENT_TYPE: {
9
+ readonly Separator: "separator";
10
+ readonly Collapse: "collapse";
11
+ readonly Item: "item";
12
+ };
13
+ export declare const SIZE: {
14
+ readonly Xs: "xs";
15
+ readonly S: "s";
16
+ };
package/dist/constants.js CHANGED
@@ -1,19 +1,16 @@
1
1
  export const SEPARATOR = '›';
2
- export var ItemRenderMode;
3
- (function (ItemRenderMode) {
4
- ItemRenderMode["Full"] = "full";
5
- ItemRenderMode["ShortLabel"] = "shortLabel";
6
- ItemRenderMode["Ellipsis"] = "ellipsis";
7
- ItemRenderMode["Collapsed"] = "collapsed";
8
- })(ItemRenderMode || (ItemRenderMode = {}));
9
- export var ElementType;
10
- (function (ElementType) {
11
- ElementType["Separator"] = "separator";
12
- ElementType["Collapse"] = "collapse";
13
- ElementType["Item"] = "item";
14
- })(ElementType || (ElementType = {}));
15
- export var Size;
16
- (function (Size) {
17
- Size["Xs"] = "xs";
18
- Size["S"] = "s";
19
- })(Size || (Size = {}));
2
+ export const ITEM_RENDER_MODE = {
3
+ Full: 'full',
4
+ ShortLabel: 'shortLabel',
5
+ Ellipsis: 'ellipsis',
6
+ Collapsed: 'collapsed',
7
+ };
8
+ export const ELEMENT_TYPE = {
9
+ Separator: 'separator',
10
+ Collapse: 'collapse',
11
+ Item: 'item',
12
+ };
13
+ export const SIZE = {
14
+ Xs: 'xs',
15
+ S: 's',
16
+ };
package/dist/context.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { Size } from './constants';
2
+ import { Size } from './types';
3
3
  type BreadcrumbsContextValue = {
4
4
  hidden: boolean;
5
5
  size: Size;
package/dist/context.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createContext } from 'react';
2
- import { SEPARATOR, Size } from './constants';
2
+ import { SEPARATOR, SIZE } from './constants';
3
3
  export const BreadcrumbsContext = createContext({
4
4
  hidden: false,
5
- size: Size.S,
5
+ size: SIZE.S,
6
6
  separator: SEPARATOR,
7
7
  });
package/dist/types.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import { JSXElementConstructor, MouseEventHandler } from 'react';
2
- import { ElementType, ItemRenderMode } from './constants';
2
+ import { ValueOf } from '@snack-uikit/utils';
3
+ import { ELEMENT_TYPE, ITEM_RENDER_MODE, SIZE } from './constants';
4
+ export type Size = ValueOf<typeof SIZE>;
5
+ export type ElementType = ValueOf<typeof ELEMENT_TYPE>;
6
+ export type ItemRenderMode = ValueOf<typeof ITEM_RENDER_MODE>;
3
7
  export type Item = {
4
8
  id: string;
5
9
  label: string;
@@ -14,10 +18,10 @@ export type InnerItem = Item & {
14
18
  renderMode: ItemRenderMode;
15
19
  };
16
20
  export type ItemSizeMap = {
17
- [ItemRenderMode.ShortLabel]: number;
18
- [ItemRenderMode.Collapsed]: number;
19
- [ItemRenderMode.Ellipsis]: number;
20
- [ItemRenderMode.Full]: number;
21
+ [ITEM_RENDER_MODE.ShortLabel]: number;
22
+ [ITEM_RENDER_MODE.Collapsed]: number;
23
+ [ITEM_RENDER_MODE.Ellipsis]: number;
24
+ [ITEM_RENDER_MODE.Full]: number;
21
25
  };
22
26
  export type SizeMap = {
23
27
  separator: number;
@@ -27,13 +31,13 @@ export type SizeMap = {
27
31
  };
28
32
  };
29
33
  export type BreadcrumbsConfigChain = Array<{
30
- element: ElementType.Collapse;
34
+ element: typeof ELEMENT_TYPE.Collapse;
31
35
  width: number;
32
36
  } | {
33
- element: ElementType.Separator;
37
+ element: typeof ELEMENT_TYPE.Separator;
34
38
  width: number;
35
39
  } | {
36
- element: ElementType.Item;
40
+ element: typeof ELEMENT_TYPE.Item;
37
41
  width: number;
38
42
  item: InnerItem;
39
43
  }>;
package/dist/types.js CHANGED
@@ -1 +1 @@
1
- import { ItemRenderMode } from './constants';
1
+ import { ITEM_RENDER_MODE } from './constants';
@@ -1,16 +1,20 @@
1
- import { ElementType, ItemRenderMode } from '../constants';
1
+ import { ELEMENT_TYPE, ITEM_RENDER_MODE } from '../constants';
2
2
  const RENDER_MODE_WEIGHT = {
3
- [ItemRenderMode.Full]: 0,
4
- [ItemRenderMode.ShortLabel]: 1,
5
- [ItemRenderMode.Ellipsis]: 100,
6
- [ItemRenderMode.Collapsed]: 10000,
3
+ [ITEM_RENDER_MODE.Full]: 0,
4
+ [ITEM_RENDER_MODE.ShortLabel]: 1,
5
+ [ITEM_RENDER_MODE.Ellipsis]: 100,
6
+ [ITEM_RENDER_MODE.Collapsed]: 10000,
7
7
  };
8
- const RENDER_MODE_WITH_WIDTH = [ItemRenderMode.Full, ItemRenderMode.ShortLabel, ItemRenderMode.Ellipsis];
8
+ const RENDER_MODE_WITH_WIDTH = [
9
+ ITEM_RENDER_MODE.Full,
10
+ ITEM_RENDER_MODE.ShortLabel,
11
+ ITEM_RENDER_MODE.Ellipsis,
12
+ ];
9
13
  const startsWith = (renderMode) => (item, tail) => [Object.assign(Object.assign({}, item), { renderMode }), ...tail];
10
- const startsWithFull = startsWith(ItemRenderMode.Full);
11
- const startsWithShortLabel = startsWith(ItemRenderMode.ShortLabel);
12
- const startsWithEllipsis = startsWith(ItemRenderMode.Ellipsis);
13
- const startsWithCollapsed = startsWith(ItemRenderMode.Collapsed);
14
+ const startsWithFull = startsWith(ITEM_RENDER_MODE.Full);
15
+ const startsWithShortLabel = startsWith(ITEM_RENDER_MODE.ShortLabel);
16
+ const startsWithEllipsis = startsWith(ITEM_RENDER_MODE.Ellipsis);
17
+ const startsWithCollapsed = startsWith(ITEM_RENDER_MODE.Collapsed);
14
18
  function buildSubChain([current, ...rest], { useCollapse = true, useEllipse = true }) {
15
19
  const result = [];
16
20
  if (!current) {
@@ -39,39 +43,39 @@ function buildSubChain([current, ...rest], { useCollapse = true, useEllipse = tr
39
43
  }
40
44
  const collapseAllRest = (lastElementRenderMode, rest) => rest.map((element, index, array) => {
41
45
  const lastItem = index === array.length - 1;
42
- return Object.assign(Object.assign({}, element), { renderMode: lastItem ? lastElementRenderMode : ItemRenderMode.Collapsed });
46
+ return Object.assign(Object.assign({}, element), { renderMode: lastItem ? lastElementRenderMode : ITEM_RENDER_MODE.Collapsed });
43
47
  });
44
48
  export function buildBreadcrumbsConfigs(items, sizeMap) {
45
49
  const chains = [];
46
- const [first, ...rest] = items.map(item => (Object.assign(Object.assign({}, item), { renderMode: ItemRenderMode.Full })));
50
+ const [first, ...rest] = items.map(item => (Object.assign(Object.assign({}, item), { renderMode: ITEM_RENDER_MODE.Full })));
47
51
  buildSubChain(rest, { useCollapse: true, useEllipse: true }).forEach(subset => {
48
52
  chains.push(startsWithFull(first, subset));
49
53
  first.shortLabel && chains.push(startsWithShortLabel(first, subset));
50
54
  });
51
55
  /** Первый элемент можно схлопывать/сокращать только когда уже сокращено все что можно */
52
- chains.push(startsWithEllipsis(first, collapseAllRest(ItemRenderMode.Full, rest)));
53
- chains.push(startsWithEllipsis(first, collapseAllRest(ItemRenderMode.Ellipsis, rest)));
54
- chains.push(startsWithCollapsed(first, collapseAllRest(ItemRenderMode.Full, rest)));
55
- chains.push(startsWithCollapsed(first, collapseAllRest(ItemRenderMode.Ellipsis, rest)));
56
+ chains.push(startsWithEllipsis(first, collapseAllRest(ITEM_RENDER_MODE.Full, rest)));
57
+ chains.push(startsWithEllipsis(first, collapseAllRest(ITEM_RENDER_MODE.Ellipsis, rest)));
58
+ chains.push(startsWithCollapsed(first, collapseAllRest(ITEM_RENDER_MODE.Full, rest)));
59
+ chains.push(startsWithCollapsed(first, collapseAllRest(ITEM_RENDER_MODE.Ellipsis, rest)));
56
60
  return chains.map(chain => chain.reduce((acc, item, index) => {
57
61
  const { renderMode } = item;
58
62
  if (index && RENDER_MODE_WITH_WIDTH.includes(renderMode)) {
59
63
  acc.width += sizeMap.separator;
60
- acc.chain.push({ element: ElementType.Separator, width: sizeMap.separator });
64
+ acc.chain.push({ element: ELEMENT_TYPE.Separator, width: sizeMap.separator });
61
65
  }
62
- if (!acc.hasCollapsed && renderMode === ItemRenderMode.Collapsed) {
66
+ if (!acc.hasCollapsed && renderMode === ITEM_RENDER_MODE.Collapsed) {
63
67
  if (index) {
64
68
  acc.width += sizeMap.separator;
65
- acc.chain.push({ element: ElementType.Separator, width: sizeMap.separator });
69
+ acc.chain.push({ element: ELEMENT_TYPE.Separator, width: sizeMap.separator });
66
70
  }
67
71
  acc.hasCollapsed = true;
68
72
  acc.width += sizeMap.collapse;
69
- acc.chain.push({ element: ElementType.Collapse, width: sizeMap.collapse });
73
+ acc.chain.push({ element: ELEMENT_TYPE.Collapse, width: sizeMap.collapse });
70
74
  }
71
75
  const width = sizeMap.items[item.id][renderMode];
72
76
  acc.weight += RENDER_MODE_WEIGHT[item.renderMode];
73
77
  acc.width += width;
74
- acc.chain.push({ element: ElementType.Item, item, width });
78
+ acc.chain.push({ element: ELEMENT_TYPE.Item, item, width });
75
79
  return acc;
76
80
  }, { chain: [], weight: 0, width: 0, hasCollapsed: false }));
77
81
  }
@@ -1,9 +1,9 @@
1
- import { ItemRenderMode } from '../constants';
1
+ import { ITEM_RENDER_MODE } from '../constants';
2
2
  const getEmptyItemSizeMap = () => ({
3
- [ItemRenderMode.ShortLabel]: 0,
4
- [ItemRenderMode.Collapsed]: 0,
5
- [ItemRenderMode.Ellipsis]: 0,
6
- [ItemRenderMode.Full]: 0,
3
+ [ITEM_RENDER_MODE.ShortLabel]: 0,
4
+ [ITEM_RENDER_MODE.Collapsed]: 0,
5
+ [ITEM_RENDER_MODE.Ellipsis]: 0,
6
+ [ITEM_RENDER_MODE.Full]: 0,
7
7
  });
8
8
  const getElementWidth = (element) => element.getBoundingClientRect().width;
9
9
  export function buildSizeMap(container) {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "title": "Breadcrumbs",
7
- "version": "0.5.1",
7
+ "version": "0.6.0",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -32,11 +32,11 @@
32
32
  "license": "Apache-2.0",
33
33
  "scripts": {},
34
34
  "dependencies": {
35
- "@snack-uikit/popover": "0.5.1",
36
- "@snack-uikit/typography": "0.5.1",
37
- "@snack-uikit/utils": "3.1.0",
35
+ "@snack-uikit/popover": "0.6.0",
36
+ "@snack-uikit/typography": "0.6.0",
37
+ "@snack-uikit/utils": "3.2.0",
38
38
  "classnames": "2.3.2",
39
39
  "lodash.debounce": "4.0.8"
40
40
  },
41
- "gitHead": "76a159dde7baccf49dc7b11e1fd7abc31424b42f"
41
+ "gitHead": "bd39c5e674f3b91b0e2487782a04b15034cf3d8b"
42
42
  }
@@ -2,9 +2,9 @@ import { memo, useMemo, useRef } from 'react';
2
2
 
3
3
  import { WithSupportProps } from '@snack-uikit/utils';
4
4
 
5
- import { ElementType, ItemRenderMode, SEPARATOR, Size } from '../../constants';
5
+ import { ELEMENT_TYPE, ITEM_RENDER_MODE, SEPARATOR, SIZE } from '../../constants';
6
6
  import { useBreadcrumbsLayout } from '../../hooks';
7
- import { Item } from '../../types';
7
+ import { Item, Size } from '../../types';
8
8
  import { Collapse } from '../Collapse';
9
9
  import { Crumb } from '../Crumb';
10
10
  import { HiddenChain } from '../HiddenChain';
@@ -23,7 +23,7 @@ export type BreadcrumbsProps = WithSupportProps<{
23
23
  separator?: string;
24
24
  /**
25
25
  * Размер
26
- * @default Breadcrumbs.sizes.S
26
+ * @default s
27
27
  */
28
28
  size?: Size;
29
29
  /**
@@ -41,9 +41,9 @@ export type BreadcrumbsProps = WithSupportProps<{
41
41
  /**
42
42
  * Компонент хлебных крошек
43
43
  */
44
- const BreadcrumbsComponent = memo(function Breadcrumbs({
44
+ export const Breadcrumbs = memo(function Breadcrumbs({
45
45
  items: itemsProps,
46
- size = Size.S,
46
+ size = SIZE.S,
47
47
  separator = SEPARATOR,
48
48
  className,
49
49
  firstItemIconOnly = false,
@@ -78,13 +78,13 @@ const BreadcrumbsComponent = memo(function Breadcrumbs({
78
78
  const isLastElement = index === array.length - 1;
79
79
 
80
80
  switch (block.element) {
81
- case ElementType.Separator:
81
+ case ELEMENT_TYPE.Separator:
82
82
  return <Separator key={index} />;
83
- case ElementType.Collapse:
83
+ case ELEMENT_TYPE.Collapse:
84
84
  return <Collapse key={index} currentConfig={currentConfig.chain} />;
85
- case ElementType.Item:
85
+ case ELEMENT_TYPE.Item:
86
86
  const { renderMode, id } = block.item;
87
- if (renderMode !== ItemRenderMode.Collapsed) {
87
+ if (renderMode !== ITEM_RENDER_MODE.Collapsed) {
88
88
  return (
89
89
  <Crumb
90
90
  useIconOnly={!index && firstItemIconOnly}
@@ -104,9 +104,3 @@ const BreadcrumbsComponent = memo(function Breadcrumbs({
104
104
  </>
105
105
  );
106
106
  });
107
-
108
- export const Breadcrumbs = BreadcrumbsComponent as typeof BreadcrumbsComponent & {
109
- sizes: typeof Size;
110
- };
111
-
112
- Breadcrumbs.sizes = Size;
@@ -2,7 +2,7 @@ import { useContext } from 'react';
2
2
 
3
3
  import { Popover } from '@snack-uikit/popover';
4
4
 
5
- import { ElementType, ItemRenderMode } from '../../constants';
5
+ import { ELEMENT_TYPE, ITEM_RENDER_MODE } from '../../constants';
6
6
  import { BreadcrumbsContext } from '../../context';
7
7
  import { BreadcrumbsConfigChain } from '../../types';
8
8
  import { getTestId } from '../../utils';
@@ -21,12 +21,12 @@ export function Collapse({ currentConfig, className }: CollapseProps) {
21
21
  const { hidden, size, testId } = ctx;
22
22
 
23
23
  const collapsedItems = currentConfig.map(node => {
24
- if (node.element === ElementType.Item && node.item.renderMode === ItemRenderMode.Collapsed) {
24
+ if (node.element === ELEMENT_TYPE.Item && node.item.renderMode === ITEM_RENDER_MODE.Collapsed) {
25
25
  const { id } = node.item;
26
26
 
27
27
  return (
28
28
  <div key={id} className={styles.collapsedRow}>
29
- <Crumb item={node.item} renderMode={ItemRenderMode.Full} />
29
+ <Crumb item={node.item} renderMode={ITEM_RENDER_MODE.Full} />
30
30
  <Separator />
31
31
  </div>
32
32
  );
@@ -41,8 +41,8 @@ export function Collapse({ currentConfig, className }: CollapseProps) {
41
41
  );
42
42
 
43
43
  return (
44
- <div className={className} data-test-id={getTestId('collapse', testId)} data-element-type={ElementType.Collapse}>
45
- <Popover tip={tip} trigger={Popover.triggers.HoverAndFocusVisible} placement={Popover.placements.Top}>
44
+ <div className={className} data-test-id={getTestId('collapse', testId)} data-element-type={ELEMENT_TYPE.Collapse}>
45
+ <Popover tip={tip} trigger='hoverAndFocusVisible' placement='top'>
46
46
  <button className={styles.collapse} tabIndex={hidden ? -1 : 0}>
47
47
  <CrumbsTypography size={size}>...</CrumbsTypography>
48
48
  </button>
@@ -3,9 +3,9 @@ import { memo, useContext } from 'react';
3
3
 
4
4
  import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
5
5
 
6
- import { ElementType, ItemRenderMode } from '../../constants';
6
+ import { ELEMENT_TYPE, ITEM_RENDER_MODE } from '../../constants';
7
7
  import { BreadcrumbsContext } from '../../context';
8
- import { Item } from '../../types';
8
+ import { Item, ItemRenderMode } from '../../types';
9
9
  import { getTestId } from '../../utils';
10
10
  import { CrumbsTypography } from '../CrumbsTypography';
11
11
  import styles from './styles.module.scss';
@@ -33,10 +33,10 @@ export const Crumb = memo(function Crumb({
33
33
  const { hidden, size, testId } = useContext(BreadcrumbsContext);
34
34
  const isLabelShouldBeEllipse = hidden && labelProp.length > ELLIPSIS_LABEL_LENGTH;
35
35
  const label =
36
- isLabelShouldBeEllipse && renderMode === ItemRenderMode.Ellipsis ? `${labelProp.substring(0, 4)}...` : labelProp;
36
+ isLabelShouldBeEllipse && renderMode === ITEM_RENDER_MODE.Ellipsis ? `${labelProp.substring(0, 4)}...` : labelProp;
37
37
  const useIconOnly = Boolean(Icon && useIconOnlyProp);
38
38
 
39
- const minWidth = minWidthProp && renderMode === ItemRenderMode.Ellipsis ? minWidthProp : 'auto';
39
+ const minWidth = minWidthProp && renderMode === ITEM_RENDER_MODE.Ellipsis ? minWidthProp : 'auto';
40
40
 
41
41
  const dataAttributes = {
42
42
  'data-render-mode': renderMode,
@@ -55,7 +55,7 @@ export const Crumb = memo(function Crumb({
55
55
  )}
56
56
  {!useIconOnly && (
57
57
  <CrumbsTypography size={size} className={styles.label}>
58
- {renderMode === ItemRenderMode.ShortLabel ? shortLabel : label}
58
+ {renderMode === ITEM_RENDER_MODE.ShortLabel ? shortLabel : label}
59
59
  </CrumbsTypography>
60
60
  )}
61
61
  </>
@@ -63,7 +63,7 @@ export const Crumb = memo(function Crumb({
63
63
 
64
64
  const tabIndex = hidden ? { tabIndex: -1 } : {};
65
65
 
66
- const title = renderMode === ItemRenderMode.Ellipsis ? label : '';
66
+ const title = renderMode === ITEM_RENDER_MODE.Ellipsis ? label : '';
67
67
 
68
68
  let crumb = null;
69
69
  if (href) {
@@ -108,7 +108,7 @@ export const Crumb = memo(function Crumb({
108
108
  {...dataAttributes}
109
109
  data-test-id={getTestId('crumb', testId)}
110
110
  className={cn(styles.wrapper, className)}
111
- data-element-type={ElementType.Item}
111
+ data-element-type={ELEMENT_TYPE.Item}
112
112
  style={{ minWidth }}
113
113
  title={title}
114
114
  >
@@ -2,7 +2,8 @@ import { PropsWithChildren } from 'react';
2
2
 
3
3
  import { Typography } from '@snack-uikit/typography';
4
4
 
5
- import { Size } from '../../constants';
5
+ import { SIZE } from '../../constants';
6
+ import { Size } from '../../types';
6
7
 
7
8
  export type CrumbsTypographyProps = PropsWithChildren<{
8
9
  size: Size;
@@ -11,13 +12,7 @@ export type CrumbsTypographyProps = PropsWithChildren<{
11
12
 
12
13
  export function CrumbsTypography({ size, children, className }: CrumbsTypographyProps) {
13
14
  return (
14
- <Typography
15
- className={className}
16
- size={size === Size.S ? Typography.sizes.L : Typography.sizes.M}
17
- tag={Typography.tags.div}
18
- family={Typography.families.Sans}
19
- role={Typography.roles.Body}
20
- >
15
+ <Typography className={className} size={size === SIZE.S ? 'l' : 'm'} tag='div' family='sans' purpose='body'>
21
16
  {children}
22
17
  </Typography>
23
18
  );
@@ -1,7 +1,6 @@
1
1
  import { memo, useEffect, useRef } from 'react';
2
2
 
3
- import { Size } from '../../constants';
4
- import { BreadcrumbsConfig, Item } from '../../types';
3
+ import { BreadcrumbsConfig, Item, Size } from '../../types';
5
4
  import { buildBreadcrumbsConfigs, buildSizeMap } from '../../utils';
6
5
  import { Collapse } from '../Collapse';
7
6
  import { Separator } from '../Separator';
@@ -1,7 +1,7 @@
1
1
  import { useMemo } from 'react';
2
2
 
3
- import { ItemRenderMode } from '../../constants';
4
- import { Item } from '../../types';
3
+ import { ITEM_RENDER_MODE } from '../../constants';
4
+ import { Item, ItemRenderMode } from '../../types';
5
5
  import { Crumb } from '../Crumb';
6
6
 
7
7
  type RenderModes = [ItemRenderMode, 'label' | 'shortLabel'][];
@@ -12,15 +12,15 @@ type UseItemModesRenderProps = { firstItemIconOnly: boolean };
12
12
  * Варианты отображения для обычного айтема
13
13
  */
14
14
  const NORMAL_MODES: RenderModes = [
15
- [ItemRenderMode.ShortLabel, 'shortLabel'],
16
- [ItemRenderMode.Ellipsis, 'label'],
17
- [ItemRenderMode.Full, 'label'],
15
+ [ITEM_RENDER_MODE.ShortLabel, 'shortLabel'],
16
+ [ITEM_RENDER_MODE.Ellipsis, 'label'],
17
+ [ITEM_RENDER_MODE.Full, 'label'],
18
18
  ];
19
19
 
20
20
  /**
21
21
  * Варианты отображения айтемов состоящих из одной иконки
22
22
  */
23
- const ICON_ONLY_MODES: RenderModes = [[ItemRenderMode.Full, 'label']];
23
+ const ICON_ONLY_MODES: RenderModes = [[ITEM_RENDER_MODE.Full, 'label']];
24
24
 
25
25
  const getItemModesRenderer = (firstItemIconOnly: boolean) => (item: Item, index: number) => {
26
26
  const isIconOnlyMode = !index && firstItemIconOnly;
@@ -1,6 +1,6 @@
1
1
  import { useContext } from 'react';
2
2
 
3
- import { ElementType } from '../../constants';
3
+ import { ELEMENT_TYPE } from '../../constants';
4
4
  import { BreadcrumbsContext } from '../../context';
5
5
  import { getTestId } from '../../utils';
6
6
  import { CrumbsTypography } from '../CrumbsTypography';
@@ -15,7 +15,7 @@ export function Separator() {
15
15
  data-size={size}
16
16
  className={styles.separator}
17
17
  data-test-id={getTestId('separator', testId)}
18
- data-element-type={ElementType.Separator}
18
+ data-element-type={ELEMENT_TYPE.Separator}
19
19
  >
20
20
  <CrumbsTypography size={size}>{separator}</CrumbsTypography>
21
21
  </div>
@@ -3,8 +3,8 @@ import { forwardRef, PropsWithChildren } from 'react';
3
3
 
4
4
  import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
5
5
 
6
- import { Size } from '../../constants';
7
6
  import { BreadcrumbsContext } from '../../context';
7
+ import { Size } from '../../types';
8
8
  import styles from './styles.module.scss';
9
9
 
10
10
  export type WrapperProps = PropsWithChildren<
package/src/constants.ts CHANGED
@@ -1,19 +1,19 @@
1
1
  export const SEPARATOR = '›';
2
2
 
3
- export enum ItemRenderMode {
4
- Full = 'full',
5
- ShortLabel = 'shortLabel',
6
- Ellipsis = 'ellipsis',
7
- Collapsed = 'collapsed',
8
- }
3
+ export const ITEM_RENDER_MODE = {
4
+ Full: 'full',
5
+ ShortLabel: 'shortLabel',
6
+ Ellipsis: 'ellipsis',
7
+ Collapsed: 'collapsed',
8
+ } as const;
9
9
 
10
- export enum ElementType {
11
- Separator = 'separator',
12
- Collapse = 'collapse',
13
- Item = 'item',
14
- }
10
+ export const ELEMENT_TYPE = {
11
+ Separator: 'separator',
12
+ Collapse: 'collapse',
13
+ Item: 'item',
14
+ } as const;
15
15
 
16
- export enum Size {
17
- Xs = 'xs',
18
- S = 's',
19
- }
16
+ export const SIZE = {
17
+ Xs: 'xs',
18
+ S: 's',
19
+ } as const;
package/src/context.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createContext } from 'react';
2
2
 
3
- import { SEPARATOR, Size } from './constants';
3
+ import { SEPARATOR, SIZE } from './constants';
4
+ import { Size } from './types';
4
5
 
5
6
  type BreadcrumbsContextValue = {
6
7
  hidden: boolean;
@@ -11,6 +12,6 @@ type BreadcrumbsContextValue = {
11
12
 
12
13
  export const BreadcrumbsContext = createContext<BreadcrumbsContextValue>({
13
14
  hidden: false,
14
- size: Size.S,
15
+ size: SIZE.S,
15
16
  separator: SEPARATOR,
16
17
  });
package/src/types.ts CHANGED
@@ -1,6 +1,14 @@
1
1
  import { JSXElementConstructor, MouseEventHandler } from 'react';
2
2
 
3
- import { ElementType, ItemRenderMode } from './constants';
3
+ import { ValueOf } from '@snack-uikit/utils';
4
+
5
+ import { ELEMENT_TYPE, ITEM_RENDER_MODE, SIZE } from './constants';
6
+
7
+ export type Size = ValueOf<typeof SIZE>;
8
+
9
+ export type ElementType = ValueOf<typeof ELEMENT_TYPE>;
10
+
11
+ export type ItemRenderMode = ValueOf<typeof ITEM_RENDER_MODE>;
4
12
 
5
13
  export type Item = {
6
14
  id: string;
@@ -16,10 +24,10 @@ export type InnerItem = Item & {
16
24
  };
17
25
 
18
26
  export type ItemSizeMap = {
19
- [ItemRenderMode.ShortLabel]: number;
20
- [ItemRenderMode.Collapsed]: number;
21
- [ItemRenderMode.Ellipsis]: number;
22
- [ItemRenderMode.Full]: number;
27
+ [ITEM_RENDER_MODE.ShortLabel]: number;
28
+ [ITEM_RENDER_MODE.Collapsed]: number;
29
+ [ITEM_RENDER_MODE.Ellipsis]: number;
30
+ [ITEM_RENDER_MODE.Full]: number;
23
31
  };
24
32
 
25
33
  export type SizeMap = {
@@ -32,15 +40,15 @@ export type SizeMap = {
32
40
 
33
41
  export type BreadcrumbsConfigChain = Array<
34
42
  | {
35
- element: ElementType.Collapse;
43
+ element: typeof ELEMENT_TYPE.Collapse;
36
44
  width: number;
37
45
  }
38
46
  | {
39
- element: ElementType.Separator;
47
+ element: typeof ELEMENT_TYPE.Separator;
40
48
  width: number;
41
49
  }
42
50
  | {
43
- element: ElementType.Item;
51
+ element: typeof ELEMENT_TYPE.Item;
44
52
  width: number;
45
53
  item: InnerItem;
46
54
  }
@@ -1,25 +1,29 @@
1
- import { ElementType, ItemRenderMode } from '../constants';
2
- import { BreadcrumbsConfig, InnerItem, Item, SizeMap } from '../types';
1
+ import { ELEMENT_TYPE, ITEM_RENDER_MODE } from '../constants';
2
+ import { BreadcrumbsConfig, InnerItem, Item, ItemRenderMode, SizeMap } from '../types';
3
3
 
4
4
  type Chain = InnerItem[];
5
5
 
6
6
  const RENDER_MODE_WEIGHT = {
7
- [ItemRenderMode.Full]: 0,
8
- [ItemRenderMode.ShortLabel]: 1,
9
- [ItemRenderMode.Ellipsis]: 100,
10
- [ItemRenderMode.Collapsed]: 10000,
7
+ [ITEM_RENDER_MODE.Full]: 0,
8
+ [ITEM_RENDER_MODE.ShortLabel]: 1,
9
+ [ITEM_RENDER_MODE.Ellipsis]: 100,
10
+ [ITEM_RENDER_MODE.Collapsed]: 10000,
11
11
  };
12
12
 
13
- const RENDER_MODE_WITH_WIDTH = [ItemRenderMode.Full, ItemRenderMode.ShortLabel, ItemRenderMode.Ellipsis];
13
+ const RENDER_MODE_WITH_WIDTH = [
14
+ ITEM_RENDER_MODE.Full,
15
+ ITEM_RENDER_MODE.ShortLabel,
16
+ ITEM_RENDER_MODE.Ellipsis,
17
+ ] as ItemRenderMode[];
14
18
 
15
19
  const startsWith =
16
20
  (renderMode: ItemRenderMode) =>
17
21
  (item: InnerItem, tail: Chain): Chain =>
18
22
  [{ ...item, renderMode }, ...tail];
19
- const startsWithFull = startsWith(ItemRenderMode.Full);
20
- const startsWithShortLabel = startsWith(ItemRenderMode.ShortLabel);
21
- const startsWithEllipsis = startsWith(ItemRenderMode.Ellipsis);
22
- const startsWithCollapsed = startsWith(ItemRenderMode.Collapsed);
23
+ const startsWithFull = startsWith(ITEM_RENDER_MODE.Full);
24
+ const startsWithShortLabel = startsWith(ITEM_RENDER_MODE.ShortLabel);
25
+ const startsWithEllipsis = startsWith(ITEM_RENDER_MODE.Ellipsis);
26
+ const startsWithCollapsed = startsWith(ITEM_RENDER_MODE.Collapsed);
23
27
 
24
28
  type BuildSubChainOptions = {
25
29
  useCollapse: boolean;
@@ -65,12 +69,12 @@ function buildSubChain(
65
69
  const collapseAllRest = (lastElementRenderMode: ItemRenderMode, rest: InnerItem[]) =>
66
70
  rest.map((element, index, array) => {
67
71
  const lastItem = index === array.length - 1;
68
- return { ...element, renderMode: lastItem ? lastElementRenderMode : ItemRenderMode.Collapsed };
72
+ return { ...element, renderMode: lastItem ? lastElementRenderMode : ITEM_RENDER_MODE.Collapsed };
69
73
  });
70
74
 
71
75
  export function buildBreadcrumbsConfigs(items: Item[], sizeMap: SizeMap): BreadcrumbsConfig[] {
72
76
  const chains: InnerItem[][] = [];
73
- const [first, ...rest] = items.map(item => ({ ...item, renderMode: ItemRenderMode.Full }));
77
+ const [first, ...rest] = items.map(item => ({ ...item, renderMode: ITEM_RENDER_MODE.Full }));
74
78
 
75
79
  buildSubChain(rest, { useCollapse: true, useEllipse: true }).forEach(subset => {
76
80
  chains.push(startsWithFull(first, subset));
@@ -78,10 +82,10 @@ export function buildBreadcrumbsConfigs(items: Item[], sizeMap: SizeMap): Breadc
78
82
  });
79
83
 
80
84
  /** Первый элемент можно схлопывать/сокращать только когда уже сокращено все что можно */
81
- chains.push(startsWithEllipsis(first, collapseAllRest(ItemRenderMode.Full, rest)));
82
- chains.push(startsWithEllipsis(first, collapseAllRest(ItemRenderMode.Ellipsis, rest)));
83
- chains.push(startsWithCollapsed(first, collapseAllRest(ItemRenderMode.Full, rest)));
84
- chains.push(startsWithCollapsed(first, collapseAllRest(ItemRenderMode.Ellipsis, rest)));
85
+ chains.push(startsWithEllipsis(first, collapseAllRest(ITEM_RENDER_MODE.Full, rest)));
86
+ chains.push(startsWithEllipsis(first, collapseAllRest(ITEM_RENDER_MODE.Ellipsis, rest)));
87
+ chains.push(startsWithCollapsed(first, collapseAllRest(ITEM_RENDER_MODE.Full, rest)));
88
+ chains.push(startsWithCollapsed(first, collapseAllRest(ITEM_RENDER_MODE.Ellipsis, rest)));
85
89
 
86
90
  return chains.map(chain =>
87
91
  chain.reduce<BreadcrumbsConfig>(
@@ -90,23 +94,23 @@ export function buildBreadcrumbsConfigs(items: Item[], sizeMap: SizeMap): Breadc
90
94
 
91
95
  if (index && RENDER_MODE_WITH_WIDTH.includes(renderMode)) {
92
96
  acc.width += sizeMap.separator;
93
- acc.chain.push({ element: ElementType.Separator, width: sizeMap.separator });
97
+ acc.chain.push({ element: ELEMENT_TYPE.Separator, width: sizeMap.separator });
94
98
  }
95
99
 
96
- if (!acc.hasCollapsed && renderMode === ItemRenderMode.Collapsed) {
100
+ if (!acc.hasCollapsed && renderMode === ITEM_RENDER_MODE.Collapsed) {
97
101
  if (index) {
98
102
  acc.width += sizeMap.separator;
99
- acc.chain.push({ element: ElementType.Separator, width: sizeMap.separator });
103
+ acc.chain.push({ element: ELEMENT_TYPE.Separator, width: sizeMap.separator });
100
104
  }
101
105
  acc.hasCollapsed = true;
102
106
  acc.width += sizeMap.collapse;
103
- acc.chain.push({ element: ElementType.Collapse, width: sizeMap.collapse });
107
+ acc.chain.push({ element: ELEMENT_TYPE.Collapse, width: sizeMap.collapse });
104
108
  }
105
109
 
106
110
  const width = sizeMap.items[item.id][renderMode];
107
111
  acc.weight += RENDER_MODE_WEIGHT[item.renderMode];
108
112
  acc.width += width;
109
- acc.chain.push({ element: ElementType.Item, item, width });
113
+ acc.chain.push({ element: ELEMENT_TYPE.Item, item, width });
110
114
 
111
115
  return acc;
112
116
  },
@@ -1,11 +1,11 @@
1
- import { ItemRenderMode } from '../constants';
2
- import { ItemSizeMap, SizeMap } from '../types';
1
+ import { ITEM_RENDER_MODE } from '../constants';
2
+ import { ItemRenderMode, ItemSizeMap, SizeMap } from '../types';
3
3
 
4
4
  const getEmptyItemSizeMap = (): ItemSizeMap => ({
5
- [ItemRenderMode.ShortLabel]: 0,
6
- [ItemRenderMode.Collapsed]: 0,
7
- [ItemRenderMode.Ellipsis]: 0,
8
- [ItemRenderMode.Full]: 0,
5
+ [ITEM_RENDER_MODE.ShortLabel]: 0,
6
+ [ITEM_RENDER_MODE.Collapsed]: 0,
7
+ [ITEM_RENDER_MODE.Ellipsis]: 0,
8
+ [ITEM_RENDER_MODE.Full]: 0,
9
9
  });
10
10
 
11
11
  const getElementWidth = (element: HTMLElement): number => element.getBoundingClientRect().width;