@gravity-ui/navigation 0.14.0 → 0.16.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 (43) hide show
  1. package/build/cjs/components/AsideHeader/AsideHeader.d.ts +5 -3
  2. package/build/cjs/components/AsideHeader/__stories__/moc.d.ts +2 -0
  3. package/build/cjs/components/AsideHeader/i18n/index.d.ts +2 -0
  4. package/build/cjs/components/CompositeBar/CompositeBar.d.ts +11 -7
  5. package/build/cjs/components/CompositeBar/utils.d.ts +6 -4
  6. package/build/cjs/components/MobileHeader/Burger/Burger.d.ts +5 -2
  7. package/build/cjs/components/MobileHeader/MobileHeader.d.ts +2 -0
  8. package/build/cjs/components/MobileHeader/i18n/index.d.ts +2 -0
  9. package/build/cjs/components/Settings/Settings.d.ts +4 -7
  10. package/build/cjs/components/Settings/i18n/index.d.ts +2 -0
  11. package/build/cjs/components/Title/Title.d.ts +1 -3
  12. package/build/cjs/components/Title/i18n/index.d.ts +2 -0
  13. package/build/cjs/components/constants.d.ts +0 -7
  14. package/build/cjs/components/index.d.ts +1 -0
  15. package/build/cjs/components/types.d.ts +2 -10
  16. package/build/cjs/components/utils/registerKeyset.d.ts +5 -0
  17. package/build/cjs/i18n.d.ts +2 -0
  18. package/build/cjs/index.js +322 -62
  19. package/build/cjs/index.js.map +1 -1
  20. package/build/esm/components/AsideHeader/AsideHeader.d.ts +5 -3
  21. package/build/esm/components/AsideHeader/__stories__/moc.d.ts +2 -0
  22. package/build/esm/components/AsideHeader/i18n/index.d.ts +2 -0
  23. package/build/esm/components/CompositeBar/CompositeBar.d.ts +11 -7
  24. package/build/esm/components/CompositeBar/utils.d.ts +6 -4
  25. package/build/esm/components/MobileHeader/Burger/Burger.d.ts +5 -2
  26. package/build/esm/components/MobileHeader/MobileHeader.d.ts +2 -0
  27. package/build/esm/components/MobileHeader/i18n/index.d.ts +2 -0
  28. package/build/esm/components/Settings/Settings.d.ts +4 -7
  29. package/build/esm/components/Settings/i18n/index.d.ts +2 -0
  30. package/build/esm/components/Title/Title.d.ts +1 -3
  31. package/build/esm/components/Title/i18n/index.d.ts +2 -0
  32. package/build/esm/components/constants.d.ts +0 -7
  33. package/build/esm/components/index.d.ts +1 -0
  34. package/build/esm/components/types.d.ts +2 -10
  35. package/build/esm/components/utils/registerKeyset.d.ts +5 -0
  36. package/build/esm/i18n.d.ts +2 -0
  37. package/build/esm/index.js +322 -63
  38. package/build/esm/index.js.map +1 -1
  39. package/package.json +2 -1
  40. package/build/cjs/components/CompositeBar/__stories__/CompositeBar.stories.d.ts +0 -5
  41. package/build/cjs/components/CompositeBar/__stories__/moc.d.ts +0 -2
  42. package/build/esm/components/CompositeBar/__stories__/CompositeBar.stories.d.ts +0 -5
  43. package/build/esm/components/CompositeBar/__stories__/moc.d.ts +0 -2
@@ -94,28 +94,9 @@ function block(name) {
94
94
  return _default(`${NAMESPACE}${name}`);
95
95
  }
96
96
 
97
- exports.MobileHeaderDict = void 0;
98
- (function (MobileHeaderDict) {
99
- MobileHeaderDict["CloseBurger"] = "button_close-burger";
100
- MobileHeaderDict["OpenBurger"] = "button_open-burger";
101
- })(exports.MobileHeaderDict || (exports.MobileHeaderDict = {}));
102
- exports.Dict = void 0;
103
- (function (Dict) {
104
- Dict["ExpandButton"] = "button_expand";
105
- Dict["CollapseButton"] = "button_collapse";
106
- Dict["MoreButton"] = "button_more";
107
- })(exports.Dict || (exports.Dict = {}));
108
-
109
97
  const ASIDE_HEADER_FOOTER_ICON_SIZE = 20;
110
98
  const ASIDE_HEADER_COMPACT_WIDTH = 56;
111
99
  const ASIDE_HEADER_EXPANDED_WIDTH = 236;
112
- const defaultDict$2 = {
113
- [exports.Dict.CollapseButton]: 'Collapse',
114
- [exports.Dict.ExpandButton]: 'Expand',
115
- [exports.Dict.MoreButton]: 'More',
116
- [exports.MobileHeaderDict.CloseBurger]: 'Close menu',
117
- [exports.MobileHeaderDict.OpenBurger]: 'Open menu',
118
- };
119
100
 
120
101
  function _extends$2() {
121
102
  _extends$2 = Object.assign ? Object.assign.bind() : function (target) {
@@ -1384,7 +1365,7 @@ function removeClass$1(element, className) {
1384
1365
  }
1385
1366
  }
1386
1367
 
1387
- var config = {
1368
+ var config$1 = {
1388
1369
  disabled: false
1389
1370
  };
1390
1371
 
@@ -1664,7 +1645,7 @@ var Transition = /*#__PURE__*/function (_React$Component) {
1664
1645
  var enterTimeout = appearing ? timeouts.appear : timeouts.enter; // no enter animation skip right to ENTERED
1665
1646
  // if we are mounting and running this it means appear _must_ be set
1666
1647
 
1667
- if (!mounting && !enter || config.disabled) {
1648
+ if (!mounting && !enter || config$1.disabled) {
1668
1649
  this.safeSetState({
1669
1650
  status: ENTERED
1670
1651
  }, function () {
@@ -1696,7 +1677,7 @@ var Transition = /*#__PURE__*/function (_React$Component) {
1696
1677
  var timeouts = this.getTimeouts();
1697
1678
  var maybeNode = this.props.nodeRef ? undefined : ReactDOM__default["default"].findDOMNode(this); // no exit animation skip right to EXITED
1698
1679
 
1699
- if (!exit || config.disabled) {
1680
+ if (!exit || config$1.disabled) {
1700
1681
  this.safeSetState({
1701
1682
  status: EXITED
1702
1683
  }, function () {
@@ -3635,6 +3616,9 @@ const POPUP_PLACEMENT = ['right-start', 'right-end', 'right'];
3635
3616
  const POPUP_ITEM_HEIGHT = 28;
3636
3617
 
3637
3618
  function getItemHeight$1(item) {
3619
+ if (!isMenuItem(item)) {
3620
+ return ITEM_HEIGHT;
3621
+ }
3638
3622
  switch (item.type) {
3639
3623
  case 'action':
3640
3624
  return 50;
@@ -3672,12 +3656,10 @@ function getItemsMinHeight(items) {
3672
3656
  getItemsHeight(afterMoreButtonItems) +
3673
3657
  (pinnedItems.length === items.length ? 0 : ITEM_HEIGHT));
3674
3658
  }
3675
- function getMoreButtonItem(dict) {
3676
- var _a;
3677
- const title = (_a = dict === null || dict === void 0 ? void 0 : dict[exports.Dict.MoreButton]) !== null && _a !== void 0 ? _a : defaultDict$2[exports.Dict.MoreButton];
3659
+ function getMoreButtonItem(menuMoreTitle) {
3678
3660
  return {
3679
3661
  id: COLLAPSE_ITEM_ID,
3680
- title,
3662
+ title: menuMoreTitle,
3681
3663
  icon: icons.Ellipsis,
3682
3664
  iconSize: 18,
3683
3665
  };
@@ -3721,6 +3703,9 @@ function getAutosizeListItems(items, height, collapseItem) {
3721
3703
  }
3722
3704
  return { listItems, collapseItems };
3723
3705
  }
3706
+ function isMenuItem(item) {
3707
+ return (item === null || item === void 0 ? void 0 : item.id) !== undefined;
3708
+ }
3724
3709
 
3725
3710
  var css_248z$k = ".gn-composite-bar-item {\n --composite-bar-item-action-size: 36px;\n display: flex;\n width: 100%;\n height: 100%;\n align-items: center;\n cursor: pointer;\n}\n.gn-composite-bar-item__icon {\n color: var(--g-color-text-misc);\n}\n.gn-composite-bar-item__icon-place {\n flex-shrink: 0;\n width: var(--aside-header-min-width);\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n}\n.gn-composite-bar-item__title {\n display: flex;\n overflow: hidden;\n}\n.gn-composite-bar-item__title-text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n.gn-composite-bar-item__title-adornment {\n margin: 0 10px;\n}\n.gn-composite-bar-item__collapse-item {\n display: flex;\n padding: 0 16px;\n align-items: center;\n width: 100%;\n height: 100%;\n cursor: pointer;\n}\n.gn-composite-bar-item__collapse-item .gn-composite-bar-item__title-adornment {\n margin-right: 0;\n}\n.gn-composite-bar-item__menu-divider {\n margin: 0 8px;\n width: 100%;\n border-top: 1px solid var(--g-color-line-generic);\n cursor: default;\n}\n.gn-composite-bar-item__collapse-items-popup-content {\n padding: 4px 0;\n}\n.gn-composite-bar-item__link {\n display: flex;\n width: 100%;\n height: 100%;\n align-items: center;\n}\n.gn-composite-bar-item__link, .gn-composite-bar-item__link:hover, .gn-composite-bar-item__link:active, .gn-composite-bar-item__link:visited, .gn-composite-bar-item__link:focus {\n text-decoration: none;\n outline: none;\n color: inherit;\n}\n.gn-composite-bar-item__btn-icon {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.gn-composite-bar-item_type_action {\n justify-content: center;\n height: var(--composite-bar-item-action-size);\n margin: 0 10px 8px;\n background: var(--g-color-base-float);\n box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.03), 0px 5px 6px rgba(0, 0, 0, 0.12);\n border-radius: var(--composite-bar-item-action-size);\n transition: transform 0.1s ease-out, background-color 0.15s linear;\n}\n.gn-composite-bar-item_type_action:focus {\n box-shadow: 0 0 0 2px var(--g-color-line-misc);\n}\n.gn-composite-bar-item_type_action:focus:not(:focus-visible) {\n box-shadow: none;\n}\n.gn-composite-bar-item_type_action:hover {\n background-color: var(--g-color-base-float-hover);\n}\n.gn-composite-bar-item_type_action:active {\n box-shadow: 0 1px 2px var(--g-color-sfx-shadow);\n transition: none;\n transform: scale(0.96);\n}\n.gn-composite-bar-item_type_action .gn-composite-bar-item__icon-place {\n width: var(--composite-bar-item-action-size);\n}\n.gn-composite-bar-item_type_action .gn-composite-bar-item__title {\n margin-right: 16px;\n}\n.gn-composite-bar-item__icon-tooltip_item-type_action {\n margin-left: 10px;\n}\n.gn-composite-bar-item:not(.gn-composite-bar-item_compact).gn-composite-bar-item_current.gn-composite-bar-item_type_regular {\n background-color: var(--g-color-base-selection);\n}\n.gn-composite-bar-item:not(.gn-composite-bar-item_compact):not(.gn-composite-bar-item_current):hover.gn-composite-bar-item_type_regular {\n background-color: var(--g-color-base-simple-hover);\n}\n.gn-composite-bar-item_compact.gn-composite-bar-item_type_action {\n width: var(--composite-bar-item-action-size);\n}\n.gn-composite-bar-item_compact.gn-composite-bar-item_type_action .gn-composite-bar-item__title {\n margin: 0;\n}\n.gn-composite-bar-item_compact.gn-composite-bar-item_current.gn-composite-bar-item_type_regular .gn-composite-bar-item__btn-icon {\n position: relative;\n background-color: transparent;\n}\n.gn-composite-bar-item_compact.gn-composite-bar-item_current.gn-composite-bar-item_type_regular .gn-composite-bar-item__btn-icon::before {\n content: \"\";\n position: absolute;\n top: 50%;\n left: 50%;\n z-index: -1;\n width: 38px;\n height: 38px;\n margin-top: -19px;\n margin-left: -19px;\n border-radius: 7px;\n}\n.gn-composite-bar-item_compact.gn-composite-bar-item_current.gn-composite-bar-item_type_regular .gn-composite-bar-item__btn-icon::before {\n background-color: var(--g-color-base-selection);\n}\n.gn-composite-bar-item_compact:not(.gn-composite-bar-item_current):hover.gn-composite-bar-item_type_regular .gn-composite-bar-item__btn-icon {\n position: relative;\n background-color: transparent;\n}\n.gn-composite-bar-item_compact:not(.gn-composite-bar-item_current):hover.gn-composite-bar-item_type_regular .gn-composite-bar-item__btn-icon::before {\n content: \"\";\n position: absolute;\n top: 50%;\n left: 50%;\n z-index: -1;\n width: 38px;\n height: 38px;\n margin-top: -19px;\n margin-left: -19px;\n border-radius: 7px;\n}\n.gn-composite-bar-item_compact:not(.gn-composite-bar-item_current):hover.gn-composite-bar-item_type_regular .gn-composite-bar-item__btn-icon::before {\n background-color: var(--g-color-base-simple-hover);\n}";
3726
3711
  styleInject(css_248z$k);
@@ -3783,7 +3768,7 @@ const Item$1 = (props) => {
3783
3768
  onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave();
3784
3769
  }
3785
3770
  } },
3786
- React__default["default"].createElement("div", { className: b$l('icon-place') }, compact ? (React__default["default"].createElement(uikit.Tooltip, { content: tooltipText, disabled: !enableTooltip || (collapsedItem && open), placement: "right", className: b$l('icon-tooltip', { 'item-type': type }) },
3771
+ React__default["default"].createElement("div", { className: b$l('icon-place') }, compact ? (React__default["default"].createElement(uikit.Tooltip, { content: tooltipText, disabled: !enableTooltip || (collapsedItem && open) || popupVisible, placement: "right", className: b$l('icon-tooltip', { 'item-type': type }) },
3787
3772
  React__default["default"].createElement("div", { onMouseEnter: () => onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(), onMouseLeave: () => onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave(), className: b$l('btn-icon') }, iconEl))) : (iconEl)),
3788
3773
  React__default["default"].createElement("div", { className: b$l('title'), title: typeof item.title === 'string' ? item.title : undefined }, titleEl),
3789
3774
  renderPopupContent && Boolean(anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current) && (React__default["default"].createElement(uikit.Popup, { contentClassName: b$l('popup'), open: popupVisible, keepMounted: popupKeepMounted, placement: popupPlacement, offset: popupOffset, anchorRef: anchorRef, onClose: onClose }, renderPopupContent()))));
@@ -3884,7 +3869,7 @@ var css_248z$i = ".gn-composite-bar {\n flex: 1 0 auto;\n width: 100%;\n min-
3884
3869
  styleInject(css_248z$i);
3885
3870
 
3886
3871
  const b$j = block('composite-bar');
3887
- const CompositeBarView = ({ items, onItemClick, collapseItems, multipleTooltip = true, }) => {
3872
+ const CompositeBarView = ({ type, items, onItemClick, collapseItems, multipleTooltip = false, }) => {
3888
3873
  const ref = React.useRef(null);
3889
3874
  const tooltipRef = React.useRef(null);
3890
3875
  const { setValue: setMultipleTooltipContextValue, active: multipleTooltipActive, activeIndex, lastClickedItemIndex, } = React.useContext(MultipleTooltipContext);
@@ -3949,26 +3934,32 @@ const CompositeBarView = ({ items, onItemClick, collapseItems, multipleTooltip =
3949
3934
  }, [lastClickedItemIndex, setMultipleTooltipContextValue]);
3950
3935
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
3951
3936
  React__default["default"].createElement("div", { ref: tooltipRef, onMouseEnter: onTooltipMouseEnter, onMouseLeave: onTooltipMouseLeave },
3952
- React__default["default"].createElement(uikit.List, { ref: ref, items: items, selectedItemIndex: getSelectedItemIndex$1(items), itemHeight: getItemHeight$1, itemClassName: b$j('root-menu-item'), itemsHeight: getItemsHeight, virtualized: false, filterable: false, sortable: false, renderItem: (item, _isItemActive, itemIndex) => (React__default["default"].createElement(Item$1, { item: item, onMouseEnter: onMouseEnterByIndex(itemIndex), onMouseLeave: onMouseLeave, onItemClick: onItemClickByIndex(itemIndex), collapseItems: collapseItems, enableTooltip: !multipleTooltip })) })),
3953
- React__default["default"].createElement(MultipleTooltip, { open: compact && multipleTooltip && multipleTooltipActive, anchorRef: tooltipRef, placement: ['right-start'], items: items })));
3937
+ React__default["default"].createElement(uikit.List, { ref: ref, items: items, selectedItemIndex: type === 'menu' ? getSelectedItemIndex$1(items) : undefined, itemHeight: getItemHeight$1, itemsHeight: getItemsHeight, itemClassName: b$j('root-menu-item'), virtualized: false, filterable: false, sortable: false, renderItem: (item, _isItemActive, itemIndex) => {
3938
+ const itemExtraProps = isMenuItem(item) ? { item } : item;
3939
+ const enableTooltip = isMenuItem(item)
3940
+ ? !multipleTooltip
3941
+ : item.enableTooltip;
3942
+ return (React__default["default"].createElement(Item$1, Object.assign({}, itemExtraProps, { enableTooltip: enableTooltip, onMouseEnter: onMouseEnterByIndex(itemIndex), onMouseLeave: onMouseLeave, onItemClick: onItemClickByIndex(itemIndex), collapseItems: collapseItems })));
3943
+ } })),
3944
+ type === 'menu' && (React__default["default"].createElement(MultipleTooltip, { open: compact && multipleTooltip && multipleTooltipActive, anchorRef: tooltipRef, placement: ['right-start'], items: items }))));
3954
3945
  };
3955
- const CompositeBar = ({ items, enableCollapsing, dict, onItemClick, multipleTooltip = false, }) => {
3946
+ const CompositeBar = ({ type, items, menuMoreTitle, onItemClick, multipleTooltip = false, }) => {
3956
3947
  if (items.length === 0) {
3957
3948
  return null;
3958
3949
  }
3959
3950
  let node;
3960
- if (enableCollapsing) {
3951
+ if (type === 'menu') {
3961
3952
  const minHeight = getItemsMinHeight(items);
3962
- const collapseItem = getMoreButtonItem(dict);
3953
+ const collapseItem = getMoreButtonItem(menuMoreTitle);
3963
3954
  node = (React__default["default"].createElement("div", { className: b$j({ autosizer: true }), style: { minHeight } }, items.length !== 0 && (React__default["default"].createElement(AutoSizer, null, ({ width, height }) => {
3964
3955
  const { listItems, collapseItems } = getAutosizeListItems(items, height, collapseItem);
3965
3956
  return (React__default["default"].createElement("div", { style: { width, height } },
3966
- React__default["default"].createElement(CompositeBarView, { items: listItems, onItemClick: onItemClick, collapseItems: collapseItems, multipleTooltip: multipleTooltip })));
3957
+ React__default["default"].createElement(CompositeBarView, { type: "menu", items: listItems, onItemClick: onItemClick, collapseItems: collapseItems, multipleTooltip: multipleTooltip })));
3967
3958
  }))));
3968
3959
  }
3969
3960
  else {
3970
3961
  node = (React__default["default"].createElement("div", { className: b$j() },
3971
- React__default["default"].createElement(CompositeBarView, { items: items, onItemClick: onItemClick, multipleTooltip: multipleTooltip })));
3962
+ React__default["default"].createElement(CompositeBarView, { type: "subheader", items: items, onItemClick: onItemClick })));
3972
3963
  }
3973
3964
  return React__default["default"].createElement(MultipleTooltipProvider, null, node);
3974
3965
  };
@@ -3989,6 +3980,237 @@ function fakeDisplayName(newDisplayName, Component) {
3989
3980
  return Fake;
3990
3981
  }
3991
3982
 
3983
+ const PARAM_REGEXP = /{{(.*?)}}/g;
3984
+ function replaceParams(keyValue, params) {
3985
+ let result = '';
3986
+ let lastIndex = (PARAM_REGEXP.lastIndex = 0);
3987
+ let match;
3988
+ while ((match = PARAM_REGEXP.exec(keyValue))) {
3989
+ if (lastIndex !== match.index) {
3990
+ result += keyValue.slice(lastIndex, match.index);
3991
+ }
3992
+ lastIndex = PARAM_REGEXP.lastIndex;
3993
+ const [all, key] = match;
3994
+ if (Object.prototype.hasOwnProperty.call(params, key)) {
3995
+ result += params[key];
3996
+ }
3997
+ else {
3998
+ result += all;
3999
+ }
4000
+ }
4001
+ if (lastIndex < keyValue.length) {
4002
+ result += keyValue.slice(lastIndex);
4003
+ }
4004
+ return result;
4005
+ }
4006
+
4007
+ var PluralForm;
4008
+ (function (PluralForm) {
4009
+ PluralForm[PluralForm["One"] = 0] = "One";
4010
+ PluralForm[PluralForm["Few"] = 1] = "Few";
4011
+ PluralForm[PluralForm["Many"] = 2] = "Many";
4012
+ PluralForm[PluralForm["None"] = 3] = "None";
4013
+ })(PluralForm || (PluralForm = {}));
4014
+
4015
+ function pluralizerEn (count, pluralForms) {
4016
+ if (count === 0) {
4017
+ return pluralForms.None;
4018
+ }
4019
+ if (count === 1 || count === -1) {
4020
+ return pluralForms.One;
4021
+ }
4022
+ return pluralForms.Many;
4023
+ }
4024
+
4025
+ function pluralizerRu (count, pluralForms) {
4026
+ // the rules for negative numbers are the same
4027
+ const lastDigit = Math.abs(count % 10);
4028
+ const last2Digits = Math.abs(count % 100);
4029
+ if (count === 0) {
4030
+ return pluralForms.None;
4031
+ }
4032
+ if (lastDigit === 1 && last2Digits !== 11) {
4033
+ return pluralForms.One;
4034
+ }
4035
+ if ((lastDigit > 1 && lastDigit < 5) && (last2Digits < 10 || last2Digits > 20)) {
4036
+ return pluralForms.Few;
4037
+ }
4038
+ return pluralForms.Many;
4039
+ }
4040
+
4041
+ class I18N {
4042
+ constructor(options) {
4043
+ this.data = {};
4044
+ this.lang = undefined;
4045
+ this.pluralizers = {
4046
+ en: pluralizerEn,
4047
+ ru: pluralizerRu,
4048
+ };
4049
+ this.logger = null;
4050
+ this.logger = (options === null || options === void 0 ? void 0 : options.logger) || null;
4051
+ }
4052
+ setLang(lang) {
4053
+ this.lang = lang;
4054
+ }
4055
+ configurePluralization(pluralizers) {
4056
+ this.pluralizers = Object.assign({}, this.pluralizers, pluralizers);
4057
+ }
4058
+ registerKeyset(lang, keysetName, data = {}) {
4059
+ if (this.data[lang] && Object.prototype.hasOwnProperty.call(this.data[lang], keysetName)) {
4060
+ throw new Error(`Keyset '${keysetName}' is already registered, aborting!`);
4061
+ }
4062
+ this.data[lang] = Object.assign({}, this.data[lang], { [keysetName]: data });
4063
+ }
4064
+ registerKeysets(lang, data) {
4065
+ Object.keys(data).forEach((keysetName) => {
4066
+ this.registerKeyset(lang, keysetName, data[keysetName]);
4067
+ });
4068
+ }
4069
+ has(keysetName, key, lang) {
4070
+ const languageData = this.getLanguageData(lang);
4071
+ return Boolean(languageData && languageData[keysetName] && languageData[keysetName][key]);
4072
+ }
4073
+ i18n(keysetName, key, params) {
4074
+ const languageData = this.getLanguageData(this.lang);
4075
+ if (typeof languageData === 'undefined') {
4076
+ throw new Error(`Language '${this.lang}' is not defined, make sure you call setLang for the same language you called registerKeysets for!`);
4077
+ }
4078
+ if (Object.keys(languageData).length === 0) {
4079
+ this.warn('Language data is empty.');
4080
+ return key;
4081
+ }
4082
+ const keyset = languageData[keysetName];
4083
+ if (!keyset) {
4084
+ this.warn('Keyset not found.', keysetName);
4085
+ return key;
4086
+ }
4087
+ if (Object.keys(keyset).length === 0) {
4088
+ this.warn('Keyset is empty.', keysetName);
4089
+ return key;
4090
+ }
4091
+ const keyValue = keyset && keyset[key];
4092
+ let result;
4093
+ if (typeof keyValue === 'undefined') {
4094
+ this.warn('Missing key.', keysetName, key);
4095
+ return key;
4096
+ }
4097
+ if (Array.isArray(keyValue)) {
4098
+ if (keyValue.length < 3) {
4099
+ this.warn('Missing required plurals', keysetName, key);
4100
+ return key;
4101
+ }
4102
+ const count = Number(params === null || params === void 0 ? void 0 : params.count);
4103
+ if (Number.isNaN(count)) {
4104
+ this.warn('Missing params.count for key.', keysetName, key);
4105
+ return key;
4106
+ }
4107
+ const pluralizer = this.getLanguagePluralizer(this.lang);
4108
+ result = keyValue[pluralizer(count, PluralForm)] || keyValue[PluralForm.Many];
4109
+ if (keyValue[PluralForm.None] === undefined) {
4110
+ this.warn('Missing key for 0', keysetName, key);
4111
+ }
4112
+ }
4113
+ else {
4114
+ result = keyValue;
4115
+ }
4116
+ if (params) {
4117
+ result = replaceParams(result, params);
4118
+ }
4119
+ return result;
4120
+ }
4121
+ keyset(keysetName) {
4122
+ return (key, params) => {
4123
+ return this.i18n(keysetName, key, params);
4124
+ };
4125
+ }
4126
+ warn(msg, keyset, key) {
4127
+ var _a;
4128
+ let cacheKey = '';
4129
+ if (keyset) {
4130
+ cacheKey += keyset;
4131
+ if (key) {
4132
+ cacheKey += `.${key}`;
4133
+ }
4134
+ }
4135
+ else {
4136
+ cacheKey = 'languageData';
4137
+ }
4138
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log(`I18n: ${msg}`, {
4139
+ level: 'info',
4140
+ logger: cacheKey,
4141
+ extra: {
4142
+ type: 'i18n'
4143
+ }
4144
+ });
4145
+ }
4146
+ getLanguageData(lang) {
4147
+ const langCode = lang || this.lang;
4148
+ return langCode ? this.data[langCode] : undefined;
4149
+ }
4150
+ getLanguagePluralizer(lang) {
4151
+ const pluralizer = lang ? this.pluralizers[lang] : undefined;
4152
+ if (!pluralizer) {
4153
+ this.warn(`Pluralization is not configured for language '${lang}', falling back to the english ruleset`);
4154
+ }
4155
+ return pluralizer || pluralizerEn;
4156
+ }
4157
+ }
4158
+
4159
+ exports.Lang = void 0;
4160
+ (function (Lang) {
4161
+ Lang["Ru"] = "ru";
4162
+ Lang["En"] = "en";
4163
+ })(exports.Lang || (exports.Lang = {}));
4164
+ let subs = [];
4165
+ const config = {
4166
+ lang: exports.Lang.En,
4167
+ };
4168
+ const configure = (newConfig) => {
4169
+ Object.assign(config, newConfig);
4170
+ subs.forEach((sub) => {
4171
+ sub(config);
4172
+ });
4173
+ };
4174
+ const subscribeConfigure = (sub) => {
4175
+ subs.push(sub);
4176
+ return () => {
4177
+ subs = subs.filter((item) => item !== sub);
4178
+ };
4179
+ };
4180
+ const getConfig = () => config;
4181
+
4182
+ const i18n$4 = new I18N();
4183
+ i18n$4.setLang(getConfig().lang);
4184
+ subscribeConfigure((config) => {
4185
+ i18n$4.setLang(config.lang);
4186
+ });
4187
+
4188
+ function registerKeyset(data, keysetName) {
4189
+ Object.entries(data).forEach(([lang, keys]) => i18n$4.registerKeyset(lang, keysetName, keys));
4190
+ return i18n$4.keyset(keysetName);
4191
+ }
4192
+
4193
+ var button_collapse$1 = "Collapse";
4194
+ var button_expand$1 = "Expand";
4195
+ var label_more$1 = "More";
4196
+ var en$3 = {
4197
+ button_collapse: button_collapse$1,
4198
+ button_expand: button_expand$1,
4199
+ label_more: label_more$1
4200
+ };
4201
+
4202
+ var button_collapse = "Свернуть";
4203
+ var button_expand = "Развернуть";
4204
+ var label_more = "Ещё";
4205
+ var ru$3 = {
4206
+ button_collapse: button_collapse,
4207
+ button_expand: button_expand,
4208
+ label_more: label_more
4209
+ };
4210
+
4211
+ const COMPONENT$3 = 'AsideHeader';
4212
+ var i18n$3 = registerKeyset({ en: en$3, ru: ru$3 }, COMPONENT$3);
4213
+
3992
4214
  var _path$1;
3993
4215
  function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
3994
4216
  var SvgControlMenuButton = function SvgControlMenuButton(props) {
@@ -4030,13 +4252,13 @@ class AsideHeader extends React__default["default"].Component {
4030
4252
  super(...arguments);
4031
4253
  this.asideRef = React__default["default"].createRef();
4032
4254
  this.renderFirstPane = (size) => {
4033
- const { dict, menuItems, panelItems, headerDecoration, multipleTooltip } = this.props;
4255
+ const { menuItems, panelItems, headerDecoration, multipleTooltip, menuMoreTitle } = this.props;
4034
4256
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
4035
4257
  React__default["default"].createElement("div", { className: b$i('aside'), style: { width: size } },
4036
4258
  React__default["default"].createElement("div", { className: b$i('aside-popup-anchor'), ref: this.asideRef }),
4037
4259
  React__default["default"].createElement("div", { className: b$i('aside-content', { ['with-decoration']: headerDecoration }) },
4038
4260
  this.renderHeader(),
4039
- (menuItems === null || menuItems === void 0 ? void 0 : menuItems.length) ? (React__default["default"].createElement(CompositeBar, { items: menuItems, enableCollapsing: true, dict: dict, onItemClick: this.onItemClick, multipleTooltip: multipleTooltip })) : (React__default["default"].createElement("div", { className: b$i('menu-items') })),
4261
+ (menuItems === null || menuItems === void 0 ? void 0 : menuItems.length) ? (React__default["default"].createElement(CompositeBar, { type: "menu", items: menuItems, menuMoreTitle: menuMoreTitle !== null && menuMoreTitle !== void 0 ? menuMoreTitle : i18n$3('label_more'), onItemClick: this.onItemClick, multipleTooltip: multipleTooltip })) : (React__default["default"].createElement("div", { className: b$i('menu-items') })),
4040
4262
  this.renderFooter(size),
4041
4263
  this.renderCollapseButton())),
4042
4264
  panelItems && this.renderPanels(size)));
@@ -4047,7 +4269,7 @@ class AsideHeader extends React__default["default"].Component {
4047
4269
  this.renderLogo = () => React__default["default"].createElement(Logo$1, Object.assign({}, this.props.logo, { onClick: this.onLogoClick }));
4048
4270
  this.renderHeader = () => (React__default["default"].createElement("div", { className: b$i('header', { ['with-decoration']: this.props.headerDecoration }) },
4049
4271
  this.renderLogo(),
4050
- React__default["default"].createElement(CompositeBar, { items: this.props.subheaderItems, enableCollapsing: false, onItemClick: this.onItemClick }),
4272
+ React__default["default"].createElement(CompositeBar, { type: "subheader", items: this.props.subheaderItems, onItemClick: this.onItemClick }),
4051
4273
  React__default["default"].createElement(uikit.Icon, { data: headerDividerCollapsedIcon, className: b$i('header-divider'), width: ASIDE_HEADER_COMPACT_WIDTH, height: "29" })));
4052
4274
  this.renderFooter = (size) => {
4053
4275
  const { renderFooter, compact } = this.props;
@@ -4062,10 +4284,11 @@ class AsideHeader extends React__default["default"].Component {
4062
4284
  return (React__default["default"].createElement(Drawer, { className: b$i('panels'), onVeilClick: this.onCloseDrawer, onEscape: this.onCloseDrawer, style: { left: size } }, panelItems.map((item) => (React__default["default"].createElement(DrawerItem, Object.assign({ key: item.id }, item))))));
4063
4285
  };
4064
4286
  this.renderCollapseButton = () => {
4065
- var _a;
4066
- const { dict, compact } = this.props;
4067
- const typeButton = compact ? exports.Dict.ExpandButton : exports.Dict.CollapseButton;
4068
- return (React__default["default"].createElement(uikit.Button, { className: b$i('collapse-button', { compact }), view: "flat", onClick: this.onCollapseButtonClick, title: (_a = dict === null || dict === void 0 ? void 0 : dict[typeButton]) !== null && _a !== void 0 ? _a : defaultDict$2[typeButton] },
4287
+ const { expandTitle, collapseTitle, compact } = this.props;
4288
+ const buttonTitle = compact
4289
+ ? expandTitle || i18n$3('button_expand')
4290
+ : collapseTitle || i18n$3('button_collapse');
4291
+ return (React__default["default"].createElement(uikit.Button, { className: b$i('collapse-button', { compact }), view: "flat", onClick: this.onCollapseButtonClick, title: buttonTitle },
4069
4292
  React__default["default"].createElement(NotIcon, { data: controlMenuButtonIcon, className: b$i('collapse-icon'), width: "16", height: "10" })));
4070
4293
  };
4071
4294
  this.onCollapseButtonClick = () => {
@@ -4196,18 +4419,28 @@ const PublicActionBar = Object.assign(ActionBar, {
4196
4419
  Separator: ActionBarSeparator,
4197
4420
  });
4198
4421
 
4422
+ var button_close$1 = "Close";
4423
+ var en$2 = {
4424
+ button_close: button_close$1
4425
+ };
4426
+
4427
+ var button_close = "Закрыть";
4428
+ var ru$2 = {
4429
+ button_close: button_close
4430
+ };
4431
+
4432
+ const COMPONENT$2 = 'Title';
4433
+ var i18n$2 = registerKeyset({ en: en$2, ru: ru$2 }, COMPONENT$2);
4434
+
4199
4435
  var css_248z$a = ".gn-title {\n box-sizing: border-box;\n padding: 14px 10px 14px 20px;\n min-height: 64px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n.gn-title_separator {\n border-bottom: 1px solid var(--g-color-line-generic);\n}\n.gn-title__text {\n margin: 0;\n margin-right: 20px;\n}";
4200
4436
  styleInject(css_248z$a);
4201
4437
 
4202
4438
  const b$b = block('title');
4203
- const defaultDict$1 = {
4204
- close: 'Close',
4205
- };
4206
- const Title = ({ children, closeIconSize = 23, hasSeparator, dict = defaultDict$1, onClose, }) => {
4439
+ const Title = ({ children, closeIconSize = 23, hasSeparator, closeTitle = i18n$2('button_close'), onClose, }) => {
4207
4440
  return (React__default["default"].createElement("div", { className: b$b({ separator: hasSeparator }) },
4208
4441
  React__default["default"].createElement(uikit.Text, { className: b$b('text'), as: 'h3', variant: 'subheader-3' }, children),
4209
4442
  onClose && (React__default["default"].createElement(uikit.Button, { onClick: onClose, view: "flat", size: "l", extraProps: {
4210
- 'aria-label': dict['close'],
4443
+ 'aria-label': closeTitle,
4211
4444
  } },
4212
4445
  React__default["default"].createElement(uikit.Icon, { data: icons.Xmark, size: closeIconSize })))));
4213
4446
  };
@@ -4969,6 +5202,23 @@ const SettingsMenuMobile = ({ items, onChange, activeItemId, className, }) => {
4969
5202
  React__default["default"].createElement(uikit.Tabs, { items: tabItems, className: b$7(null, className), size: "l", activeTab: activeItemId, onSelectTab: onChange })));
4970
5203
  };
4971
5204
 
5205
+ var label_title$1 = "Settings";
5206
+ var en$1 = {
5207
+ label_title: label_title$1,
5208
+ "label_filter-placeholder": "Search settings",
5209
+ "label_empty-placeholder": "No results found"
5210
+ };
5211
+
5212
+ var label_title = "Настройки";
5213
+ var ru$1 = {
5214
+ label_title: label_title,
5215
+ "label_filter-placeholder": "Найти настройки",
5216
+ "label_empty-placeholder": "Ничего не найдено"
5217
+ };
5218
+
5219
+ const COMPONENT$1 = 'Settings';
5220
+ var i18n$1 = registerKeyset({ en: en$1, ru: ru$1 }, COMPONENT$1);
5221
+
4972
5222
  function getSettingsFromChildren(children, searchText = '') {
4973
5223
  // 'abc def fg' -> abc.*?cde.*?fg
4974
5224
  const preparedFilter = escapeStringForRegExp(searchText).replace(/\s+/g, '.*?');
@@ -5094,11 +5344,6 @@ var css_248z$6 = ".gn-settings {\n display: grid;\n grid-template-columns: 216
5094
5344
  styleInject(css_248z$6);
5095
5345
 
5096
5346
  const b$6 = block('settings');
5097
- const defaultDict = {
5098
- heading_settings: 'Settings',
5099
- placeholder_search: 'Search settings',
5100
- not_found: 'No results found',
5101
- };
5102
5347
  function Settings(_a) {
5103
5348
  var { loading, renderLoading, children, view = 'normal' } = _a, props = __rest(_a, ["loading", "renderLoading", "children", "view"]);
5104
5349
  if (loading) {
@@ -5118,10 +5363,7 @@ const getPageTitleById = (menu, activePage) => {
5118
5363
  }
5119
5364
  return '';
5120
5365
  };
5121
- Settings.defaultProps = {
5122
- dict: defaultDict,
5123
- };
5124
- function SettingsContent({ initialPage, children, renderNotFound, dict, view, onPageChange, onClose, }) {
5366
+ function SettingsContent({ initialPage, children, renderNotFound, title = i18n$1('label_title'), filterPlaceholder = i18n$1('label_filter-placeholder'), emptyPlaceholder = i18n$1('label_empty-placeholder'), view, onPageChange, onClose, }) {
5125
5367
  var _a, _b;
5126
5368
  const [search, setSearch] = React__default["default"].useState('');
5127
5369
  const { menu, pages } = getSettingsFromChildren(children, search);
@@ -5163,7 +5405,7 @@ function SettingsContent({ initialPage, children, renderNotFound, dict, view, on
5163
5405
  });
5164
5406
  const renderPageContent = () => {
5165
5407
  if (!activePage) {
5166
- return typeof renderNotFound === 'function' ? (renderNotFound()) : (React__default["default"].createElement("div", { className: b$6('not-found') }, dict === null || dict === void 0 ? void 0 : dict.not_found));
5408
+ return typeof renderNotFound === 'function' ? (renderNotFound()) : (React__default["default"].createElement("div", { className: b$6('not-found') }, emptyPlaceholder));
5167
5409
  }
5168
5410
  const filteredSections = pages[activePage].sections.filter((section) => !section.hidden);
5169
5411
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
@@ -5190,8 +5432,8 @@ function SettingsContent({ initialPage, children, renderNotFound, dict, view, on
5190
5432
  }
5191
5433
  }
5192
5434
  } },
5193
- React__default["default"].createElement(Title, null, dict === null || dict === void 0 ? void 0 : dict.heading_settings),
5194
- React__default["default"].createElement(SettingsSearch, { inputRef: searchInputRef, className: b$6('search'), onChange: setSearch, placeholder: dict === null || dict === void 0 ? void 0 : dict.placeholder_search, autoFocus: true }),
5435
+ React__default["default"].createElement(Title, null, title),
5436
+ React__default["default"].createElement(SettingsSearch, { inputRef: searchInputRef, className: b$6('search'), onChange: setSearch, placeholder: filterPlaceholder, autoFocus: true }),
5195
5437
  React__default["default"].createElement(SettingsMenu, { ref: menuRef, items: menu, onChange: handlePageChange, activeItemId: activePage }))),
5196
5438
  React__default["default"].createElement("div", { className: b$6('page') }, renderPageContent())));
5197
5439
  }
@@ -5254,7 +5496,7 @@ var css_248z$5 = ".gn-mobile-header-burger {\n margin: 0;\n padding: 0;\n fon
5254
5496
  styleInject(css_248z$5);
5255
5497
 
5256
5498
  const b$5 = block('mobile-header-burger');
5257
- const Burger = React__default["default"].memo(({ opened, className, onClick }) => (React__default["default"].createElement("button", { className: b$5({ opened }, className), onClick: onClick, "aria-label": opened ? defaultDict$2['button_close-burger'] : defaultDict$2['button_open-burger'] },
5499
+ const Burger = React__default["default"].memo(({ closeTitle, openTitle, opened, className, onClick }) => (React__default["default"].createElement("button", { className: b$5({ opened }, className), onClick: onClick, "aria-label": opened ? closeTitle : openTitle },
5258
5500
  React__default["default"].createElement("span", { className: b$5('icon') },
5259
5501
  React__default["default"].createElement("span", { className: b$5('icon-dash') })))));
5260
5502
  Burger.displayName = 'Burger';
@@ -5360,11 +5602,28 @@ const BurgerMenu = React__default["default"].memo(({ items = [], renderFooter, m
5360
5602
  });
5361
5603
  BurgerMenu.displayName = 'BurgerMenu';
5362
5604
 
5605
+ var burger_button_close$1 = "Close menu";
5606
+ var burger_button_open$1 = "Open menu";
5607
+ var en = {
5608
+ burger_button_close: burger_button_close$1,
5609
+ burger_button_open: burger_button_open$1
5610
+ };
5611
+
5612
+ var burger_button_close = "Закрыть меню";
5613
+ var burger_button_open = "Открыть меню";
5614
+ var ru = {
5615
+ burger_button_close: burger_button_close,
5616
+ burger_button_open: burger_button_open
5617
+ };
5618
+
5619
+ const COMPONENT = 'MobileHeader';
5620
+ var i18n = registerKeyset({ en, ru }, COMPONENT);
5621
+
5363
5622
  var css_248z$1 = ".gn-mobile-header {\n --mobile-header-min-heigth: 50px;\n --mobile-header-icon-size: 20px;\n background-color: var(--g-color-base-background);\n}\n.gn-mobile-header__header {\n background-color: var(--g-color-base-background);\n border-bottom: 1px solid var(--g-color-line-generic);\n position: sticky;\n top: 0;\n padding: 0 10px;\n box-sizing: border-box;\n display: flex;\n justify-content: space-between;\n align-items: center;\n z-index: 100;\n}\n.gn-mobile-header__burger {\n padding: 12px;\n}\n.gn-mobile-header__burger-menu, .gn-mobile-header__panel-item {\n background-color: var(--g-color-base-background);\n width: 320px;\n max-width: 90vw;\n max-height: 100%;\n}\n.gn-mobile-header__user-menu {\n overflow-y: auto;\n}\n.gn-mobile-header__panels {\n z-index: 98;\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: var(--mobile-header-min-heigth);\n overflow: hidden;\n}\n.gn-mobile-header__content {\n overflow: auto;\n}";
5364
5623
  styleInject(css_248z$1);
5365
5624
 
5366
5625
  const b$1 = block('mobile-header');
5367
- const MobileHeader = React__default["default"].forwardRef(({ logo, burgerMenu, panelItems = [], renderContent, sideItemRenderContent, onClosePanel, onEvent, className, }, ref) => {
5626
+ const MobileHeader = React__default["default"].forwardRef(({ logo, burgerMenu, burgerCloseTitle = i18n('burger_button_close'), burgerOpenTitle = i18n('burger_button_open'), panelItems = [], renderContent, sideItemRenderContent, onClosePanel, onEvent, className, }, ref) => {
5368
5627
  const targetRef = useForwardRef(ref);
5369
5628
  const [compact] = React.useState(true);
5370
5629
  const [visiblePanel, setVisiblePanel] = React.useState(null);
@@ -5454,7 +5713,7 @@ const MobileHeader = React__default["default"].forwardRef(({ logo, burgerMenu, p
5454
5713
  }, [targetRef, onBurgerClose, onBurgerOpen]);
5455
5714
  return (React__default["default"].createElement("div", { className: b$1({ compact }, className), ref: targetRef },
5456
5715
  React__default["default"].createElement("header", { className: b$1('header'), style: { height: size } },
5457
- React__default["default"].createElement(Burger, { opened: visiblePanel === burgerPanelItem.id, onClick: () => onPanelToggle(BURGER_PANEL_ITEM_ID), className: b$1('burger') }),
5716
+ React__default["default"].createElement(Burger, { opened: visiblePanel === burgerPanelItem.id, onClick: () => onPanelToggle(BURGER_PANEL_ITEM_ID), className: b$1('burger'), closeTitle: burgerCloseTitle, openTitle: burgerOpenTitle }),
5458
5717
  React__default["default"].createElement(Logo, Object.assign({}, logo, { compact: compact, onClick: onLogoClick })),
5459
5718
  React__default["default"].createElement("div", { className: b$1('side-item') }, sideItemRenderContent === null || sideItemRenderContent === void 0 ? void 0 : sideItemRenderContent({ size }))),
5460
5719
  React__default["default"].createElement(Drawer, { className: b$1('panels'), onVeilClick: onCloseDrawer, onEscape: onCloseDrawer, style: { top: size } }, [burgerPanelItem, ...panelItems].map((item) => (React__default["default"].createElement(DrawerItem, Object.assign({}, item, { key: item.id, visible: visiblePanel === item.id, className: b$1('panel-item', item.className) }))))),
@@ -5492,5 +5751,6 @@ exports.MobileHeader = MobileHeader;
5492
5751
  exports.MobileHeaderFooterItem = FooterItem;
5493
5752
  exports.Settings = Settings;
5494
5753
  exports.Title = Title;
5754
+ exports.configure = configure;
5495
5755
  exports.useAsideHeaderContext = useAsideHeaderContext;
5496
5756
  //# sourceMappingURL=index.js.map