@megafon/ui-core 4.15.2 → 4.15.3

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/CHANGELOG.md CHANGED
@@ -3,6 +3,18 @@
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
+ ## [4.15.3](https://github.com/MegafonWebLab/megafon-ui/compare/@megafon/ui-core@4.15.2...@megafon/ui-core@4.15.3) (2023-04-14)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **tabs:** fixed tabs scroll on mobile resolution, set hover for desktop ([f18da75](https://github.com/MegafonWebLab/megafon-ui/commit/f18da7552911bca92ea1b1229c70ecad810d30ae))
12
+ * **textfield:** add a correct count of the graphemes entered ([8e51585](https://github.com/MegafonWebLab/megafon-ui/commit/8e515856193eefa8a63fd17cab3faab7737ad41d))
13
+
14
+
15
+
16
+
17
+
6
18
  ## [4.15.2](https://github.com/MegafonWebLab/megafon-ui/compare/@megafon/ui-core@4.15.1...@megafon/ui-core@4.15.2) (2023-04-11)
7
19
 
8
20
 
@@ -160,9 +160,11 @@
160
160
  .mfui-tabs__tab-inner:hover {
161
161
  text-decoration: none;
162
162
  }
163
- .mfui-tabs__tab-inner:not(.mfui-tabs__tab-inner_current):hover {
164
- color: var(--content);
165
- fill: var(--content);
163
+ @media screen and (min-width: 1024px) {
164
+ .mfui-tabs__tab-inner:not(.mfui-tabs__tab-inner_current):hover {
165
+ color: var(--content);
166
+ fill: var(--content);
167
+ }
166
168
  }
167
169
  .mfui-tabs__tab-inner:not(.mfui-tabs__tab-inner_current):active {
168
170
  color: var(--buttonDown);
@@ -250,15 +250,23 @@ var Tabs = function Tabs(_ref) {
250
250
  swiperInstance === null || swiperInstance === void 0 ? void 0 : swiperInstance.slideNext();
251
251
  }, [swiperInstance]);
252
252
  var handleReachBeginning = React.useCallback(function (swiper) {
253
+ if (isBeginning === swiper.isBeginning) {
254
+ return;
255
+ }
256
+
253
257
  setBeginning(swiper.isBeginning);
254
- }, []);
258
+ }, [isBeginning]);
255
259
  var handleReachEnd = React.useCallback(function (swiper) {
260
+ if (isEnd === swiper.isEnd) {
261
+ return;
262
+ }
263
+
256
264
  setEnd(swiper.isEnd);
257
- }, []);
265
+ }, [isEnd]);
258
266
  var handleFromEdge = React.useCallback(function (swiper) {
259
- setBeginning(swiper.isBeginning);
260
- setEnd(swiper.isEnd);
261
- }, []);
267
+ isBeginning !== swiper.isBeginning && setBeginning(swiper.isBeginning);
268
+ isEnd !== swiper.isEnd && setEnd(swiper.isEnd);
269
+ }, [isBeginning, isEnd]);
262
270
  var addObserveEvent = React.useCallback(function () {
263
271
  var _a;
264
272
 
@@ -316,7 +324,7 @@ var Tabs = function Tabs(_ref) {
316
324
  ref: setTabRef(i)
317
325
  }, filterDataAttrs(data === null || data === void 0 ? void 0 : data.root, i + 1)), renderTabWrapper ? renderTabWrapper(tab) : tab));
318
326
  });
319
- }, [renderTab, children, classes === null || classes === void 0 ? void 0 : classes.activeTab, currentIndex, setTabRef, classes === null || classes === void 0 ? void 0 : classes.tab]);
327
+ }, [children, renderTab, currentIndex, classes === null || classes === void 0 ? void 0 : classes.activeTab, classes === null || classes === void 0 ? void 0 : classes.tab, setTabRef]);
320
328
  var renderPanels = React.useCallback(function () {
321
329
  return React.Children.map(children, function (child, i) {
322
330
  var panel = child.props.children;
@@ -56,6 +56,14 @@ export declare type TextFieldProps = {
56
56
  maxLength?: number;
57
57
  /** Показывает счетчик с подсчетом введенных символов. Только для textarea. */
58
58
  symbolCounter?: number;
59
+ /** Включает подсчет введенных [графем](https://ru.wikipedia.org/wiki/%D0%93%D1%80%D0%B0%D1%84%D0%B5%D0%BC%D0%B0) и символов при `symbolCounter=true`
60
+ *
61
+ * **Пример**: эмоджи 👩‍💻 - это одна графема, состоящая из 5 символов.
62
+ *
63
+ * - для `true` Количество символов в строке "hello world👩‍💻" = 12
64
+ * - для `false` Количество символов в строке "hello world👩‍💻" = 16
65
+ */
66
+ graphemesCounter?: boolean;
59
67
  /** Иконка */
60
68
  customIcon?: JSX.Element;
61
69
  /** Маска для поля. Не работает с textarea=true. */
@@ -15,6 +15,7 @@ import throttle from 'lodash.throttle';
15
15
  import * as PropTypes from 'prop-types';
16
16
  import InputMask from 'react-input-mask';
17
17
  import throttleTime from "../../constants/throttleTime";
18
+ import countGraphemes from "./utils/countGraphemes";
18
19
  import "./TextField.css";
19
20
 
20
21
  var Hide = function Hide(props) {
@@ -96,6 +97,7 @@ var TextField = function TextField(_ref) {
96
97
  mask = _ref.mask,
97
98
  maskChar = _ref.maskChar,
98
99
  maxLength = _ref.maxLength,
100
+ graphemesCounter = _ref.graphemesCounter,
99
101
  symbolCounter = _ref.symbolCounter,
100
102
  _ref$textarea = _ref.textarea,
101
103
  textarea = _ref$textarea === void 0 ? false : _ref$textarea,
@@ -191,8 +193,9 @@ var TextField = function TextField(_ref) {
191
193
  return;
192
194
  }
193
195
 
194
- setIsMaxLimitExceeded(symbolCounter < String(textareaValue).length);
195
- }, [symbolCounter]);
196
+ var countValue = graphemesCounter ? countGraphemes(String(textareaValue)) : String(textareaValue).length;
197
+ setIsMaxLimitExceeded(symbolCounter < countValue);
198
+ }, [graphemesCounter, symbolCounter]);
196
199
  useEffect(function () {
197
200
  if (!textarea || !fieldNode.current || isTextareaResized) {
198
201
  return;
@@ -325,7 +328,7 @@ var TextField = function TextField(_ref) {
325
328
  onBlur: handleBlur,
326
329
  onFocus: handleFocus,
327
330
  onKeyUp: onKeyUp,
328
- maxLength: maxLength,
331
+ maxLength: (graphemesCounter && maxLength && countGraphemes(String(inputValue)) < maxLength ? -1 : maxLength) || maxLength,
329
332
  placeholder: hidePlaceholder ? ' ' : actualPlaceholder,
330
333
  required: required,
331
334
  inputMode: inputMode
@@ -451,7 +454,7 @@ var TextField = function TextField(_ref) {
451
454
 
452
455
  var isPlaceholderShowed = isPasswordType && isPasswordHidden && !!inputValue;
453
456
  var valueHasSymbols = inputValue !== null && inputValue !== undefined;
454
- var currentSymbolCount = valueHasSymbols && String(inputValue).length || 0;
457
+ var currentSymbolCount = valueHasSymbols && (graphemesCounter && countGraphemes(String(inputValue)) || String(inputValue).length) || 0;
455
458
  return /*#__PURE__*/React.createElement("div", _extends({}, filterDataAttrs(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.root), {
456
459
  className: cn({
457
460
  disabled: disabled,
@@ -503,6 +506,7 @@ TextField.propTypes = {
503
506
  value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
504
507
  maxLength: PropTypes.number,
505
508
  symbolCounter: PropTypes.number,
509
+ graphemesCounter: PropTypes.bool,
506
510
  customIcon: PropTypes.element,
507
511
  mask: PropTypes.string,
508
512
  maskChar: PropTypes.string,
@@ -0,0 +1,2 @@
1
+ declare const countGraphemes: (text: string) => number;
2
+ export default countGraphemes;
@@ -0,0 +1,52 @@
1
+ import "core-js/modules/es.array.from";
2
+ import "core-js/modules/es.date.to-string";
3
+ import "core-js/modules/es.object.to-string";
4
+ import "core-js/modules/es.regexp.exec";
5
+ import "core-js/modules/es.regexp.to-string";
6
+ import "core-js/modules/es.string.iterator";
7
+ import "core-js/modules/es.string.replace";
8
+ var regex = /[\uFE00-\uFE0F]|(?:\uD83C[\uDFFB-\uDFFF])/g;
9
+ var regexSymbolWithCombiningMarks = /((?:[\0-\u02FF\u0370-\u0482\u048A-\u0590\u05BE\u05C0\u05C3\u05C6\u05C8-\u060F\u061B-\u064A\u0660-\u066F\u0671-\u06D5\u06DD\u06DE\u06E5\u06E6\u06E9\u06EE-\u0710\u0712-\u072F\u074B-\u07A5\u07B1-\u07EA\u07F4-\u07FC\u07FE-\u0815\u081A\u0824\u0828\u082E-\u0858\u085C-\u08D2\u08E2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0964-\u0980\u0984-\u09BB\u09BD\u09C5\u09C6\u09C9\u09CA\u09CE-\u09D6\u09D8-\u09E1\u09E4-\u09FD\u09FF\u0A00\u0A04-\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A6F\u0A72-\u0A74\u0A76-\u0A80\u0A84-\u0ABB\u0ABD\u0AC6\u0ACA\u0ACE-\u0AE1\u0AE4-\u0AF9\u0B00\u0B04-\u0B3B\u0B3D\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B61\u0B64-\u0B81\u0B83-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE-\u0BD6\u0BD8-\u0BFF\u0C05-\u0C3D\u0C45\u0C49\u0C4E-\u0C54\u0C57-\u0C61\u0C64-\u0C80\u0C84-\u0CBB\u0CBD\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CE1\u0CE4-\u0CFF\u0D04-\u0D3A\u0D3D\u0D45\u0D49\u0D4E-\u0D56\u0D58-\u0D61\u0D64-\u0D80\u0D84-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF4-\u0E30\u0E32\u0E33\u0E3B-\u0E46\u0E4F-\u0EB0\u0EB2\u0EB3\u0EBD-\u0EC7\u0ECE-\u0F17\u0F1A-\u0F34\u0F36\u0F38\u0F3A-\u0F3D\u0F40-\u0F70\u0F85\u0F88-\u0F8C\u0F98\u0FBD-\u0FC5\u0FC7-\u102A\u103F-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u109E-\u135C\u1360-\u1711\u1715-\u1731\u1735-\u1751\u1754-\u1771\u1774-\u17B3\u17D4-\u17DC\u17DE-\u180A\u180E-\u1884\u1887-\u18A8\u18AA-\u191F\u192C-\u192F\u193C-\u1A16\u1A1C-\u1A54\u1A5F\u1A7D\u1A7E\u1A80-\u1AAF\u1AC1-\u1AFF\u1B05-\u1B33\u1B45-\u1B6A\u1B74-\u1B7F\u1B83-\u1BA0\u1BAE-\u1BE5\u1BF4-\u1C23\u1C38-\u1CCF\u1CD3\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA-\u1DBF\u1DFA\u1E00-\u20CF\u20F1-\u2CEE\u2CF2-\u2D7E\u2D80-\u2DDF\u2E00-\u3029\u3030-\u3098\u309B-\uA66E\uA673\uA67E-\uA69D\uA6A0-\uA6EF\uA6F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA828-\uA82B\uA82D-\uA87F\uA882-\uA8B3\uA8C6-\uA8DF\uA8F2-\uA8FE\uA900-\uA925\uA92E-\uA946\uA954-\uA97F\uA984-\uA9B2\uA9C1-\uA9E4\uA9E6-\uAA28\uAA37-\uAA42\uAA44-\uAA4B\uAA4E-\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2-\uAAEA\uAAF0-\uAAF4\uAAF7-\uABE2\uABEB\uABEE-\uD7FF\uE000-\uFB1D\uFB1F-\uFDFF\uFE10-\uFE1F\uFE30-\uFFFF]|\uD800[\uDC00-\uDDFC\uDDFE-\uDEDF\uDEE1-\uDF75\uDF7B-\uDFFF]|[\uD801\uD808-\uD819\uD81C-\uD82E\uD830-\uD833\uD835\uD837\uD839\uD83B-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD802[\uDC00-\uDE00\uDE04\uDE07-\uDE0B\uDE10-\uDE37\uDE3B-\uDE3E\uDE40-\uDEE4\uDEE7-\uDFFF]|\uD803[\uDC00-\uDD23\uDD28-\uDEAA\uDEAD-\uDF45\uDF51-\uDFFF]|\uD804[\uDC03-\uDC37\uDC47-\uDC7E\uDC83-\uDCAF\uDCBB-\uDCFF\uDD03-\uDD26\uDD35-\uDD44\uDD47-\uDD72\uDD74-\uDD7F\uDD83-\uDDB2\uDDC1-\uDDC8\uDDCD\uDDD0-\uDE2B\uDE38-\uDE3D\uDE3F-\uDEDE\uDEEB-\uDEFF\uDF04-\uDF3A\uDF3D\uDF45\uDF46\uDF49\uDF4A\uDF4E-\uDF56\uDF58-\uDF61\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC00-\uDC34\uDC47-\uDC5D\uDC5F-\uDCAF\uDCC4-\uDDAE\uDDB6\uDDB7\uDDC1-\uDDDB\uDDDE-\uDE2F\uDE41-\uDEAA\uDEB8-\uDF1C\uDF2C-\uDFFF]|\uD806[\uDC00-\uDC2B\uDC3B-\uDD2F\uDD36\uDD39\uDD3A\uDD3F\uDD41\uDD44-\uDDD0\uDDD8\uDDD9\uDDE1-\uDDE3\uDDE5-\uDE00\uDE0B-\uDE32\uDE3A\uDE3F-\uDE46\uDE48-\uDE50\uDE5C-\uDE89\uDE9A-\uDFFF]|\uD807[\uDC00-\uDC2E\uDC37\uDC40-\uDC91\uDCA8\uDCB7-\uDD30\uDD37-\uDD39\uDD3B\uDD3E\uDD46\uDD48-\uDD89\uDD8F\uDD92\uDD98-\uDEF2\uDEF7-\uDFFF]|\uD81A[\uDC00-\uDEEF\uDEF5-\uDF2F\uDF37-\uDFFF]|\uD81B[\uDC00-\uDF4E\uDF50\uDF88-\uDF8E\uDF93-\uDFE3\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD82F[\uDC00-\uDC9C\uDC9F-\uDFFF]|\uD834[\uDC00-\uDD64\uDD6A-\uDD6C\uDD73-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDE41\uDE45-\uDFFF]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDD2F\uDD37-\uDEEB\uDEF0-\uDFFF]|\uD83A[\uDC00-\uDCCF\uDCD7-\uDD43\uDD4B-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))((?:[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C04\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D81-\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1AC0\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA82C\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD803[\uDD24-\uDD27\uDEAB\uDEAC\uDF46-\uDF50]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD45\uDD46\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDDC9-\uDDCC\uDDCE\uDDCF\uDE2C-\uDE37\uDE3E\uDEDF-\uDEEA\uDF00-\uDF03\uDF3B\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC35-\uDC46\uDC5E\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDDDC\uDDDD\uDE30-\uDE40\uDEAB-\uDEB7\uDF1D-\uDF2B]|\uD806[\uDC2C-\uDC3A\uDD30-\uDD35\uDD37\uDD38\uDD3B-\uDD3E\uDD40\uDD42\uDD43\uDDD1-\uDDD7\uDDDA-\uDDE0\uDDE4\uDE01-\uDE0A\uDE33-\uDE39\uDE3B-\uDE3E\uDE47\uDE51-\uDE5B\uDE8A-\uDE99]|\uD807[\uDC2F-\uDC36\uDC38-\uDC3F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD31-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD45\uDD47\uDD8A-\uDD8E\uDD90\uDD91\uDD93-\uDD97\uDEF3-\uDEF6]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF4F\uDF51-\uDF87\uDF8F-\uDF92\uDFE4\uDFF0\uDFF1]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD30-\uDD36\uDEEC-\uDEEF]|\uD83A[\uDCD0-\uDCD6\uDD44-\uDD4A]|\uDB40[\uDD00-\uDDEF])+)/g;
10
+ var joiner = '200d'; // eslint-disable-next-line no-magic-numbers
11
+
12
+ var isJoiner = function isJoiner(_char) {
13
+ return _char.charCodeAt(0).toString(16) === joiner;
14
+ };
15
+
16
+ var countGraphemes = function countGraphemes(text) {
17
+ var normalizedText = text.normalize('NFC').replace(regex, '').replace(regexSymbolWithCombiningMarks, function (_, symbol) {
18
+ return symbol;
19
+ });
20
+ var tokens = Array.from(normalizedText);
21
+ var length = 0;
22
+ var isComplexChar = false;
23
+
24
+ for (var i = 0; i < tokens.length; i++) {
25
+ var _char2 = tokens[i];
26
+ var nextChar = tokens[i + 1];
27
+
28
+ if (!nextChar) {
29
+ length += 1; // eslint-disable-next-line no-continue
30
+
31
+ continue;
32
+ }
33
+
34
+ if (isJoiner(nextChar)) {
35
+ isComplexChar = true; // eslint-disable-next-line no-continue
36
+
37
+ continue;
38
+ }
39
+
40
+ if (!isJoiner(_char2) && isComplexChar) {
41
+ isComplexChar = false;
42
+ }
43
+
44
+ if (!isComplexChar) {
45
+ length += 1;
46
+ }
47
+ }
48
+
49
+ return length;
50
+ };
51
+
52
+ export default countGraphemes;
@@ -10,6 +10,7 @@ export { default as checkBreakpointsPropTypes } from './components/Carousel/chec
10
10
  export { default as Collapse } from './components/Collapse/Collapse';
11
11
  export { default as ContentArea } from './components/ContentArea/ContentArea';
12
12
  export { default as Counter } from './components/Counter/Counter';
13
+ export { default as countGraphemes } from './components/TextField/utils/countGraphemes';
13
14
  export { default as Day } from './components/Calendar/components/Day/Day';
14
15
  export { default as Grid } from './components/Grid/Grid';
15
16
  export { default as GridColumn } from './components/Grid/GridColumn';
package/dist/es/index.js CHANGED
@@ -10,6 +10,7 @@ export { default as checkBreakpointsPropTypes } from "./components/Carousel/chec
10
10
  export { default as Collapse } from "./components/Collapse/Collapse";
11
11
  export { default as ContentArea } from "./components/ContentArea/ContentArea";
12
12
  export { default as Counter } from "./components/Counter/Counter";
13
+ export { default as countGraphemes } from "./components/TextField/utils/countGraphemes";
13
14
  export { default as Day } from "./components/Calendar/components/Day/Day";
14
15
  export { default as Grid } from "./components/Grid/Grid";
15
16
  export { default as GridColumn } from "./components/Grid/GridColumn";
@@ -160,9 +160,11 @@
160
160
  .mfui-tabs__tab-inner:hover {
161
161
  text-decoration: none;
162
162
  }
163
- .mfui-tabs__tab-inner:not(.mfui-tabs__tab-inner_current):hover {
164
- color: var(--content);
165
- fill: var(--content);
163
+ @media screen and (min-width: 1024px) {
164
+ .mfui-tabs__tab-inner:not(.mfui-tabs__tab-inner_current):hover {
165
+ color: var(--content);
166
+ fill: var(--content);
167
+ }
166
168
  }
167
169
  .mfui-tabs__tab-inner:not(.mfui-tabs__tab-inner_current):active {
168
170
  color: var(--buttonDown);
@@ -281,15 +281,23 @@ var Tabs = function Tabs(_ref) {
281
281
  swiperInstance === null || swiperInstance === void 0 ? void 0 : swiperInstance.slideNext();
282
282
  }, [swiperInstance]);
283
283
  var handleReachBeginning = React.useCallback(function (swiper) {
284
+ if (isBeginning === swiper.isBeginning) {
285
+ return;
286
+ }
287
+
284
288
  setBeginning(swiper.isBeginning);
285
- }, []);
289
+ }, [isBeginning]);
286
290
  var handleReachEnd = React.useCallback(function (swiper) {
291
+ if (isEnd === swiper.isEnd) {
292
+ return;
293
+ }
294
+
287
295
  setEnd(swiper.isEnd);
288
- }, []);
296
+ }, [isEnd]);
289
297
  var handleFromEdge = React.useCallback(function (swiper) {
290
- setBeginning(swiper.isBeginning);
291
- setEnd(swiper.isEnd);
292
- }, []);
298
+ isBeginning !== swiper.isBeginning && setBeginning(swiper.isBeginning);
299
+ isEnd !== swiper.isEnd && setEnd(swiper.isEnd);
300
+ }, [isBeginning, isEnd]);
293
301
  var addObserveEvent = React.useCallback(function () {
294
302
  var _a;
295
303
 
@@ -347,7 +355,7 @@ var Tabs = function Tabs(_ref) {
347
355
  ref: setTabRef(i)
348
356
  }, (0, _uiHelpers.filterDataAttrs)(data === null || data === void 0 ? void 0 : data.root, i + 1)), renderTabWrapper ? renderTabWrapper(tab) : tab));
349
357
  });
350
- }, [renderTab, children, classes === null || classes === void 0 ? void 0 : classes.activeTab, currentIndex, setTabRef, classes === null || classes === void 0 ? void 0 : classes.tab]);
358
+ }, [children, renderTab, currentIndex, classes === null || classes === void 0 ? void 0 : classes.activeTab, classes === null || classes === void 0 ? void 0 : classes.tab, setTabRef]);
351
359
  var renderPanels = React.useCallback(function () {
352
360
  return React.Children.map(children, function (child, i) {
353
361
  var panel = child.props.children;
@@ -56,6 +56,14 @@ export declare type TextFieldProps = {
56
56
  maxLength?: number;
57
57
  /** Показывает счетчик с подсчетом введенных символов. Только для textarea. */
58
58
  symbolCounter?: number;
59
+ /** Включает подсчет введенных [графем](https://ru.wikipedia.org/wiki/%D0%93%D1%80%D0%B0%D1%84%D0%B5%D0%BC%D0%B0) и символов при `symbolCounter=true`
60
+ *
61
+ * **Пример**: эмоджи 👩‍💻 - это одна графема, состоящая из 5 символов.
62
+ *
63
+ * - для `true` Количество символов в строке "hello world👩‍💻" = 12
64
+ * - для `false` Количество символов в строке "hello world👩‍💻" = 16
65
+ */
66
+ graphemesCounter?: boolean;
59
67
  /** Иконка */
60
68
  customIcon?: JSX.Element;
61
69
  /** Маска для поля. Не работает с textarea=true. */
@@ -35,6 +35,8 @@ var _reactInputMask = _interopRequireDefault(require("react-input-mask"));
35
35
 
36
36
  var _throttleTime = _interopRequireDefault(require("../../constants/throttleTime"));
37
37
 
38
+ var _countGraphemes = _interopRequireDefault(require("./utils/countGraphemes"));
39
+
38
40
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
39
41
 
40
42
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -124,6 +126,7 @@ var TextField = function TextField(_ref) {
124
126
  mask = _ref.mask,
125
127
  maskChar = _ref.maskChar,
126
128
  maxLength = _ref.maxLength,
129
+ graphemesCounter = _ref.graphemesCounter,
127
130
  symbolCounter = _ref.symbolCounter,
128
131
  _ref$textarea = _ref.textarea,
129
132
  textarea = _ref$textarea === void 0 ? false : _ref$textarea,
@@ -219,8 +222,9 @@ var TextField = function TextField(_ref) {
219
222
  return;
220
223
  }
221
224
 
222
- setIsMaxLimitExceeded(symbolCounter < String(textareaValue).length);
223
- }, [symbolCounter]);
225
+ var countValue = graphemesCounter ? (0, _countGraphemes["default"])(String(textareaValue)) : String(textareaValue).length;
226
+ setIsMaxLimitExceeded(symbolCounter < countValue);
227
+ }, [graphemesCounter, symbolCounter]);
224
228
  (0, React.useEffect)(function () {
225
229
  if (!textarea || !fieldNode.current || isTextareaResized) {
226
230
  return;
@@ -352,7 +356,7 @@ var TextField = function TextField(_ref) {
352
356
  onBlur: handleBlur,
353
357
  onFocus: handleFocus,
354
358
  onKeyUp: onKeyUp,
355
- maxLength: maxLength,
359
+ maxLength: (graphemesCounter && maxLength && (0, _countGraphemes["default"])(String(inputValue)) < maxLength ? -1 : maxLength) || maxLength,
356
360
  placeholder: hidePlaceholder ? ' ' : actualPlaceholder,
357
361
  required: required,
358
362
  inputMode: inputMode
@@ -475,7 +479,7 @@ var TextField = function TextField(_ref) {
475
479
 
476
480
  var isPlaceholderShowed = isPasswordType && isPasswordHidden && !!inputValue;
477
481
  var valueHasSymbols = inputValue !== null && inputValue !== undefined;
478
- var currentSymbolCount = valueHasSymbols && String(inputValue).length || 0;
482
+ var currentSymbolCount = valueHasSymbols && (graphemesCounter && (0, _countGraphemes["default"])(String(inputValue)) || String(inputValue).length) || 0;
479
483
  return /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.root), {
480
484
  className: cn({
481
485
  disabled: disabled,
@@ -527,6 +531,7 @@ TextField.propTypes = {
527
531
  value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
528
532
  maxLength: PropTypes.number,
529
533
  symbolCounter: PropTypes.number,
534
+ graphemesCounter: PropTypes.bool,
530
535
  customIcon: PropTypes.element,
531
536
  mask: PropTypes.string,
532
537
  maskChar: PropTypes.string,
@@ -0,0 +1,2 @@
1
+ declare const countGraphemes: (text: string) => number;
2
+ export default countGraphemes;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+
8
+ require("core-js/modules/es.array.from");
9
+
10
+ require("core-js/modules/es.date.to-string");
11
+
12
+ require("core-js/modules/es.object.to-string");
13
+
14
+ require("core-js/modules/es.regexp.exec");
15
+
16
+ require("core-js/modules/es.regexp.to-string");
17
+
18
+ require("core-js/modules/es.string.iterator");
19
+
20
+ require("core-js/modules/es.string.replace");
21
+
22
+ var regex = /[\uFE00-\uFE0F]|(?:\uD83C[\uDFFB-\uDFFF])/g;
23
+ var regexSymbolWithCombiningMarks = /((?:[\0-\u02FF\u0370-\u0482\u048A-\u0590\u05BE\u05C0\u05C3\u05C6\u05C8-\u060F\u061B-\u064A\u0660-\u066F\u0671-\u06D5\u06DD\u06DE\u06E5\u06E6\u06E9\u06EE-\u0710\u0712-\u072F\u074B-\u07A5\u07B1-\u07EA\u07F4-\u07FC\u07FE-\u0815\u081A\u0824\u0828\u082E-\u0858\u085C-\u08D2\u08E2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0964-\u0980\u0984-\u09BB\u09BD\u09C5\u09C6\u09C9\u09CA\u09CE-\u09D6\u09D8-\u09E1\u09E4-\u09FD\u09FF\u0A00\u0A04-\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A6F\u0A72-\u0A74\u0A76-\u0A80\u0A84-\u0ABB\u0ABD\u0AC6\u0ACA\u0ACE-\u0AE1\u0AE4-\u0AF9\u0B00\u0B04-\u0B3B\u0B3D\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B61\u0B64-\u0B81\u0B83-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE-\u0BD6\u0BD8-\u0BFF\u0C05-\u0C3D\u0C45\u0C49\u0C4E-\u0C54\u0C57-\u0C61\u0C64-\u0C80\u0C84-\u0CBB\u0CBD\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CE1\u0CE4-\u0CFF\u0D04-\u0D3A\u0D3D\u0D45\u0D49\u0D4E-\u0D56\u0D58-\u0D61\u0D64-\u0D80\u0D84-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF4-\u0E30\u0E32\u0E33\u0E3B-\u0E46\u0E4F-\u0EB0\u0EB2\u0EB3\u0EBD-\u0EC7\u0ECE-\u0F17\u0F1A-\u0F34\u0F36\u0F38\u0F3A-\u0F3D\u0F40-\u0F70\u0F85\u0F88-\u0F8C\u0F98\u0FBD-\u0FC5\u0FC7-\u102A\u103F-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u109E-\u135C\u1360-\u1711\u1715-\u1731\u1735-\u1751\u1754-\u1771\u1774-\u17B3\u17D4-\u17DC\u17DE-\u180A\u180E-\u1884\u1887-\u18A8\u18AA-\u191F\u192C-\u192F\u193C-\u1A16\u1A1C-\u1A54\u1A5F\u1A7D\u1A7E\u1A80-\u1AAF\u1AC1-\u1AFF\u1B05-\u1B33\u1B45-\u1B6A\u1B74-\u1B7F\u1B83-\u1BA0\u1BAE-\u1BE5\u1BF4-\u1C23\u1C38-\u1CCF\u1CD3\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA-\u1DBF\u1DFA\u1E00-\u20CF\u20F1-\u2CEE\u2CF2-\u2D7E\u2D80-\u2DDF\u2E00-\u3029\u3030-\u3098\u309B-\uA66E\uA673\uA67E-\uA69D\uA6A0-\uA6EF\uA6F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA828-\uA82B\uA82D-\uA87F\uA882-\uA8B3\uA8C6-\uA8DF\uA8F2-\uA8FE\uA900-\uA925\uA92E-\uA946\uA954-\uA97F\uA984-\uA9B2\uA9C1-\uA9E4\uA9E6-\uAA28\uAA37-\uAA42\uAA44-\uAA4B\uAA4E-\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2-\uAAEA\uAAF0-\uAAF4\uAAF7-\uABE2\uABEB\uABEE-\uD7FF\uE000-\uFB1D\uFB1F-\uFDFF\uFE10-\uFE1F\uFE30-\uFFFF]|\uD800[\uDC00-\uDDFC\uDDFE-\uDEDF\uDEE1-\uDF75\uDF7B-\uDFFF]|[\uD801\uD808-\uD819\uD81C-\uD82E\uD830-\uD833\uD835\uD837\uD839\uD83B-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD802[\uDC00-\uDE00\uDE04\uDE07-\uDE0B\uDE10-\uDE37\uDE3B-\uDE3E\uDE40-\uDEE4\uDEE7-\uDFFF]|\uD803[\uDC00-\uDD23\uDD28-\uDEAA\uDEAD-\uDF45\uDF51-\uDFFF]|\uD804[\uDC03-\uDC37\uDC47-\uDC7E\uDC83-\uDCAF\uDCBB-\uDCFF\uDD03-\uDD26\uDD35-\uDD44\uDD47-\uDD72\uDD74-\uDD7F\uDD83-\uDDB2\uDDC1-\uDDC8\uDDCD\uDDD0-\uDE2B\uDE38-\uDE3D\uDE3F-\uDEDE\uDEEB-\uDEFF\uDF04-\uDF3A\uDF3D\uDF45\uDF46\uDF49\uDF4A\uDF4E-\uDF56\uDF58-\uDF61\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC00-\uDC34\uDC47-\uDC5D\uDC5F-\uDCAF\uDCC4-\uDDAE\uDDB6\uDDB7\uDDC1-\uDDDB\uDDDE-\uDE2F\uDE41-\uDEAA\uDEB8-\uDF1C\uDF2C-\uDFFF]|\uD806[\uDC00-\uDC2B\uDC3B-\uDD2F\uDD36\uDD39\uDD3A\uDD3F\uDD41\uDD44-\uDDD0\uDDD8\uDDD9\uDDE1-\uDDE3\uDDE5-\uDE00\uDE0B-\uDE32\uDE3A\uDE3F-\uDE46\uDE48-\uDE50\uDE5C-\uDE89\uDE9A-\uDFFF]|\uD807[\uDC00-\uDC2E\uDC37\uDC40-\uDC91\uDCA8\uDCB7-\uDD30\uDD37-\uDD39\uDD3B\uDD3E\uDD46\uDD48-\uDD89\uDD8F\uDD92\uDD98-\uDEF2\uDEF7-\uDFFF]|\uD81A[\uDC00-\uDEEF\uDEF5-\uDF2F\uDF37-\uDFFF]|\uD81B[\uDC00-\uDF4E\uDF50\uDF88-\uDF8E\uDF93-\uDFE3\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD82F[\uDC00-\uDC9C\uDC9F-\uDFFF]|\uD834[\uDC00-\uDD64\uDD6A-\uDD6C\uDD73-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDE41\uDE45-\uDFFF]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDD2F\uDD37-\uDEEB\uDEF0-\uDFFF]|\uD83A[\uDC00-\uDCCF\uDCD7-\uDD43\uDD4B-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))((?:[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C04\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D81-\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1AC0\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA82C\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD803[\uDD24-\uDD27\uDEAB\uDEAC\uDF46-\uDF50]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD45\uDD46\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDDC9-\uDDCC\uDDCE\uDDCF\uDE2C-\uDE37\uDE3E\uDEDF-\uDEEA\uDF00-\uDF03\uDF3B\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC35-\uDC46\uDC5E\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDDDC\uDDDD\uDE30-\uDE40\uDEAB-\uDEB7\uDF1D-\uDF2B]|\uD806[\uDC2C-\uDC3A\uDD30-\uDD35\uDD37\uDD38\uDD3B-\uDD3E\uDD40\uDD42\uDD43\uDDD1-\uDDD7\uDDDA-\uDDE0\uDDE4\uDE01-\uDE0A\uDE33-\uDE39\uDE3B-\uDE3E\uDE47\uDE51-\uDE5B\uDE8A-\uDE99]|\uD807[\uDC2F-\uDC36\uDC38-\uDC3F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD31-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD45\uDD47\uDD8A-\uDD8E\uDD90\uDD91\uDD93-\uDD97\uDEF3-\uDEF6]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF4F\uDF51-\uDF87\uDF8F-\uDF92\uDFE4\uDFF0\uDFF1]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD30-\uDD36\uDEEC-\uDEEF]|\uD83A[\uDCD0-\uDCD6\uDD44-\uDD4A]|\uDB40[\uDD00-\uDDEF])+)/g;
24
+ var joiner = '200d'; // eslint-disable-next-line no-magic-numbers
25
+
26
+ var isJoiner = function isJoiner(_char) {
27
+ return _char.charCodeAt(0).toString(16) === joiner;
28
+ };
29
+
30
+ var countGraphemes = function countGraphemes(text) {
31
+ var normalizedText = text.normalize('NFC').replace(regex, '').replace(regexSymbolWithCombiningMarks, function (_, symbol) {
32
+ return symbol;
33
+ });
34
+ var tokens = Array.from(normalizedText);
35
+ var length = 0;
36
+ var isComplexChar = false;
37
+
38
+ for (var i = 0; i < tokens.length; i++) {
39
+ var _char2 = tokens[i];
40
+ var nextChar = tokens[i + 1];
41
+
42
+ if (!nextChar) {
43
+ length += 1; // eslint-disable-next-line no-continue
44
+
45
+ continue;
46
+ }
47
+
48
+ if (isJoiner(nextChar)) {
49
+ isComplexChar = true; // eslint-disable-next-line no-continue
50
+
51
+ continue;
52
+ }
53
+
54
+ if (!isJoiner(_char2) && isComplexChar) {
55
+ isComplexChar = false;
56
+ }
57
+
58
+ if (!isComplexChar) {
59
+ length += 1;
60
+ }
61
+ }
62
+
63
+ return length;
64
+ };
65
+
66
+ var _default = countGraphemes;
67
+ exports["default"] = _default;
@@ -10,6 +10,7 @@ export { default as checkBreakpointsPropTypes } from './components/Carousel/chec
10
10
  export { default as Collapse } from './components/Collapse/Collapse';
11
11
  export { default as ContentArea } from './components/ContentArea/ContentArea';
12
12
  export { default as Counter } from './components/Counter/Counter';
13
+ export { default as countGraphemes } from './components/TextField/utils/countGraphemes';
13
14
  export { default as Day } from './components/Calendar/components/Day/Day';
14
15
  export { default as Grid } from './components/Grid/Grid';
15
16
  export { default as GridColumn } from './components/Grid/GridColumn';
package/dist/lib/index.js CHANGED
@@ -75,6 +75,12 @@ Object.defineProperty(exports, "Counter", {
75
75
  return _Counter["default"];
76
76
  }
77
77
  });
78
+ Object.defineProperty(exports, "countGraphemes", {
79
+ enumerable: true,
80
+ get: function get() {
81
+ return _countGraphemes["default"];
82
+ }
83
+ });
78
84
  Object.defineProperty(exports, "Day", {
79
85
  enumerable: true,
80
86
  get: function get() {
@@ -310,6 +316,8 @@ var _ContentArea = _interopRequireDefault(require("./components/ContentArea/Cont
310
316
 
311
317
  var _Counter = _interopRequireDefault(require("./components/Counter/Counter"));
312
318
 
319
+ var _countGraphemes = _interopRequireDefault(require("./components/TextField/utils/countGraphemes"));
320
+
313
321
  var _Day = _interopRequireDefault(require("./components/Calendar/components/Day/Day"));
314
322
 
315
323
  var _Grid = _interopRequireDefault(require("./components/Grid/Grid"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@megafon/ui-core",
3
- "version": "4.15.2",
3
+ "version": "4.15.3",
4
4
  "files": [
5
5
  "dist",
6
6
  "styles"
@@ -100,5 +100,5 @@
100
100
  "react-popper": "^2.2.3",
101
101
  "swiper": "^6.5.6"
102
102
  },
103
- "gitHead": "c2d54353eccef1c32cac6aa03b91d48e98dcdb84"
103
+ "gitHead": "f51175c15bbd3009ef1a67aebb8107d21f43052a"
104
104
  }