mediacube-ui 0.1.345 → 0.1.347

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 (109) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/0.mediacube-ui.umd.js +50 -0
  3. package/dist/assets/img/icons.3b7d59b2f49c67a2a3a4566b8ab233fd.svg +1 -0
  4. package/dist/assets/img/no_table_data.236cd56f46cfb71fc363b008d4ca70d5.png +0 -0
  5. package/dist/assets/img/no_user.e0030d6e54e2400e1181fd22b83cf8ae.png +0 -0
  6. package/dist/mediacube-ui.umd.js +1 -0
  7. package/package.json +14 -16
  8. package/src/assets/icons.svg +1 -1
  9. package/src/assets/tokens/tokens.json +5 -0
  10. package/dist/mediacube-ui.common.js +0 -378
  11. package/src/elements/McAvatar/McAvatar.vue +0 -274
  12. package/src/elements/McBadge/McBadge.vue +0 -148
  13. package/src/elements/McButton/McButton.vue +0 -841
  14. package/src/elements/McChip/McChip.vue +0 -300
  15. package/src/elements/McCropper/McCropper.vue +0 -133
  16. package/src/elements/McDate/McDate.vue +0 -105
  17. package/src/elements/McDatePicker/McDatePicker.vue +0 -902
  18. package/src/elements/McField/McFieldCheckbox/McFieldCheckbox.vue +0 -332
  19. package/src/elements/McField/McFieldRadio/McFieldRadioButton/McFieldRadioButton.vue +0 -201
  20. package/src/elements/McField/McFieldRadio/McFieldRadioGroup/McFieldRadioGroup.vue +0 -194
  21. package/src/elements/McField/McFieldSelect/McFieldSelect.vue +0 -1087
  22. package/src/elements/McField/McFieldText/McFieldText.vue +0 -969
  23. package/src/elements/McField/McFieldToggle/McFieldToggle.vue +0 -268
  24. package/src/elements/McInfinityLoadingIndicator/McInfinityLoadingIndicator.vue +0 -97
  25. package/src/elements/McNotification/McNotification.vue +0 -209
  26. package/src/elements/McProgress/McProgress.vue +0 -218
  27. package/src/elements/McRangeSlider/McRangeSlider.vue +0 -195
  28. package/src/elements/McSeparator/McSeparator.vue +0 -143
  29. package/src/elements/McSlideUpDown/McSlideUpDown.vue +0 -157
  30. package/src/elements/McSvgIcon/McSvgIcon.vue +0 -127
  31. package/src/elements/McTabs/McTab/McTab.vue +0 -187
  32. package/src/elements/McTabs/McTabs/McTabs.vue +0 -531
  33. package/src/elements/McTitle/McTitle.vue +0 -365
  34. package/src/elements/McTooltip/McTooltip.vue +0 -334
  35. package/src/helpers/consts.js +0 -3
  36. package/src/helpers/delayedAction.js +0 -26
  37. package/src/helpers/storybookFunctions.js +0 -20
  38. package/src/helpers/storybookVariables.js +0 -24
  39. package/src/mixins/equalFieldHeight.js +0 -59
  40. package/src/mixins/fieldErrors.js +0 -28
  41. package/src/patterns/McAccordion/McAccordion.vue +0 -53
  42. package/src/patterns/McCells/McCell/McCell.vue +0 -101
  43. package/src/patterns/McChat/McChat.vue +0 -305
  44. package/src/patterns/McChat/McChatComment/McChatComment.vue +0 -265
  45. package/src/patterns/McChat/McChatForm/McChatForm.vue +0 -147
  46. package/src/patterns/McCollapse/McCollapse.vue +0 -280
  47. package/src/patterns/McDrawer/McDrawer.vue +0 -146
  48. package/src/patterns/McDropdown/McDropdown.vue +0 -247
  49. package/src/patterns/McDropdown/McDropdownPanel/McDropdownPanel.vue +0 -40
  50. package/src/patterns/McFakeScroll/McFakeScroll.vue +0 -277
  51. package/src/patterns/McFilter/McFilter.vue +0 -847
  52. package/src/patterns/McFilter/McFilterChip/McFilterChip.vue +0 -83
  53. package/src/patterns/McFilter/McFilterTags/McFilterTags.vue +0 -374
  54. package/src/patterns/McFilter/McFilterTypeDate/McFilterTypeDate.vue +0 -70
  55. package/src/patterns/McFilter/McFilterTypeRange/McFilterTypeRange.vue +0 -132
  56. package/src/patterns/McFilter/McFilterTypeRelation/McFilterTypeRelation.vue +0 -221
  57. package/src/patterns/McFilter/McFilterTypeSimple/McFilterTypeSimple.vue +0 -161
  58. package/src/patterns/McFilter/McFilterTypeText/McFilterTypeText.vue +0 -62
  59. package/src/patterns/McGrid/McGridCol/McGridCol.vue +0 -165
  60. package/src/patterns/McGrid/McGridRow/McGridRow.vue +0 -158
  61. package/src/patterns/McModal/McModal.vue +0 -680
  62. package/src/patterns/McOverlay/McOverlay.vue +0 -78
  63. package/src/patterns/McPreview/McPreview.vue +0 -118
  64. package/src/patterns/McSideBar/McSideBar/McSideBar.vue +0 -387
  65. package/src/patterns/McSideBar/McSideBarBottom/McSideBarBottom.vue +0 -125
  66. package/src/patterns/McSideBar/McSideBarButton/McSideBarButton.vue +0 -252
  67. package/src/patterns/McSideBar/McSideBarCenter/McSideBarCenter.vue +0 -367
  68. package/src/patterns/McSideBar/McSideBarTop/McSideBarTop.vue +0 -238
  69. package/src/patterns/McStack/McStack.vue +0 -158
  70. package/src/patterns/McTable/McTable/McTable.vue +0 -854
  71. package/src/patterns/McTable/McTableCol/McTableCol.vue +0 -296
  72. package/src/patterns/McTableCard/McTableCard.vue +0 -135
  73. package/src/patterns/McTableCard/McTableCardHeader/McTableCardHeader.vue +0 -74
  74. package/src/patterns/McTopBar/McTopBar.vue +0 -153
  75. package/src/patterns/McWrapScroll/McWrapScroll.vue +0 -291
  76. package/src/styles/_functions.scss +0 -187
  77. package/src/styles/_mixins.scss +0 -612
  78. package/src/styles/_spacing.scss +0 -33
  79. package/src/styles/_variables.scss +0 -23
  80. package/src/styles/global.scss +0 -308
  81. package/src/styles/main.scss +0 -4
  82. package/src/styles/table.scss +0 -10
  83. package/src/styles/toast.scss +0 -55
  84. package/src/templates/layouts/McContentFixed/McContentFixed.vue +0 -60
  85. package/src/templates/layouts/McMain/McMain.vue +0 -115
  86. package/src/templates/layouts/McRoot/McRoot.vue +0 -45
  87. package/src/tokens/animations.scss +0 -9
  88. package/src/tokens/border-radius.scss +0 -26
  89. package/src/tokens/box-shadows.scss +0 -28
  90. package/src/tokens/colors.scss +0 -82
  91. package/src/tokens/durations.scss +0 -7
  92. package/src/tokens/easings.scss +0 -6
  93. package/src/tokens/font-families.scss +0 -8
  94. package/src/tokens/font-sizes.scss +0 -23
  95. package/src/tokens/font-weights.scss +0 -9
  96. package/src/tokens/gradients.scss +0 -18
  97. package/src/tokens/letter-spacings.scss +0 -6
  98. package/src/tokens/line-heights.scss +0 -22
  99. package/src/tokens/media-queries.scss +0 -32
  100. package/src/tokens/opacities.scss +0 -8
  101. package/src/tokens/sizes.scss +0 -47
  102. package/src/tokens/spacings.scss +0 -38
  103. package/src/tokens/z-indexes.scss +0 -14
  104. package/src/utils/dayjs.js +0 -19
  105. package/src/utils/filters.js +0 -11
  106. package/src/utils/getTokens.js +0 -41
  107. package/src/utils/load-icons.js +0 -3
  108. package/src/utils/treeSearch.js +0 -30
  109. package/src/utils/webFontLoader.js +0 -12
@@ -1,969 +0,0 @@
1
- <template>
2
- <div ref="field" :dir="dir" :class="classes">
3
- <label :for="name" class="mc-field-text__header">
4
- <!-- @slot Слот заголовка -->
5
- <slot name="header">
6
- <mc-title v-if="title" :ellipsis="false" max-width="100%" weight="medium">{{ computedTitle }}</mc-title>
7
- </slot>
8
- </label>
9
- <div class="mc-field-text__inner">
10
- <div class="mc-field-text__main">
11
- <div v-if="$slots.prepend" class="mc-field-text__prepend">
12
- <!-- @slot Слот в начале инпута -->
13
- <slot name="prepend" />
14
- </div>
15
- <label class="mc-field-text__input-wrapper">
16
- <textarea
17
- v-if="isTextarea"
18
- v-bind="inputAttrs"
19
- :maxlength="maxLength"
20
- v-on="listeners"
21
- @input="$event => handleInput($event.target.value)"
22
- />
23
- <textarea-autosize
24
- v-else-if="isTextareaAutosize"
25
- v-bind="inputAttrs"
26
- rows="1"
27
- :min-height="minHeight"
28
- :max-height="maxHeight"
29
- v-on="listeners"
30
- @input="handleInput"
31
- />
32
-
33
- <template v-else>
34
- <!-- When possible, prefer to use input type="tel" to avoid glitch on android devices -->
35
- <imask-input
36
- v-if="isMaskVisible"
37
- ref="input"
38
- v-bind="maskInputAttrs"
39
- v-on="listeners"
40
- @input="handleInput"
41
- />
42
- <input
43
- v-else
44
- ref="input"
45
- v-bind="inputAttrs"
46
- :type="prettyType"
47
- :readonly="readOnly"
48
- :maxlength="maxLength"
49
- v-on="listeners"
50
- @input="prepareHandleInput"
51
- @keydown="prepareHandleKeyDown"
52
- />
53
- </template>
54
- </label>
55
- <div
56
- v-if="$slots.append || copy || isPassword"
57
- class="mc-field-text__append"
58
- :class="{ 'mc-field-text__append--indent-bottom': hasCharCounter }"
59
- >
60
- <!-- @slot Слот в конце инпута -->
61
- <slot name="append" />
62
- <mc-button v-if="copy" variation="black-link" size="m-compact" @click.prevent="handlerCopy(value)">
63
- <mc-svg-icon slot="icon-append" name="copy" />
64
- </mc-button>
65
- <component v-bind="passwordTooltipProps">
66
- <mc-button
67
- v-if="isPassword"
68
- variation="black-link"
69
- size="m-compact"
70
- tabindex="-1"
71
- type="button"
72
- @click.prevent="togglePasswordVisibility"
73
- >
74
- <mc-svg-icon slot="icon-append" :name="passwordIcon" />
75
- </mc-button>
76
- </component>
77
- </div>
78
- <mc-title
79
- v-if="hasCharCounter"
80
- class="mc-field-text__char-counter"
81
- variation="overline"
82
- text-align="right"
83
- :color="charCounterColor"
84
- >
85
- {{ charCounterTitle }}
86
- </mc-title>
87
- </div>
88
- <div v-if="$slots.right" class="mc-field-text__right">
89
- <!-- @slot Слот справа инпута -->
90
- <slot name="right" />
91
- </div>
92
- </div>
93
- <div v-if="errorText || helpText || $slots.footer" class="mc-field-text__footer">
94
- <mc-title
95
- v-if="errorText"
96
- tag-name="div"
97
- color="red"
98
- variation="overline"
99
- max-width="100%"
100
- :ellipsis="false"
101
- class="mc-field-text__error-text"
102
- v-html="errorText.replace(/-/gm, '&#x2011;')"
103
- />
104
- <br v-if="errorText" />
105
- <!-- @slot Слот доп. текста под инпутом -->
106
- <slot name="footer">
107
- <mc-title
108
- v-if="helpText"
109
- tag-name="div"
110
- variation="overline"
111
- color="gray"
112
- max-width="100%"
113
- :ellipsis="false"
114
- >
115
- {{ helpText }}
116
- </mc-title>
117
- </slot>
118
- </div>
119
- </div>
120
- </template>
121
-
122
- <script>
123
- import _omit from 'lodash/omit'
124
- import { getTokenValue } from '../../../utils/getTokens'
125
- import { IMaskComponent, IMask } from 'vue-imask'
126
-
127
- import TextareaAutosize from 'vue2-textarea-autosize/src/components/TextareaAutosize.vue'
128
- import McTitle from '../../McTitle/McTitle'
129
- import McButton from '../../McButton/McButton'
130
- import McSvgIcon from '../../McSvgIcon/McSvgIcon'
131
- import fieldErrors from '../../../mixins/fieldErrors'
132
- import McTooltip from '../../McTooltip/McTooltip'
133
- import equalFieldHeight from '../../../mixins/equalFieldHeight'
134
- import { LANGUAGES } from '../../../helpers/consts'
135
-
136
- export default {
137
- name: 'McFieldText',
138
- components: {
139
- McButton,
140
- McTitle,
141
- McSvgIcon,
142
- TextareaAutosize,
143
- // eslint-disable-next-line vue/no-unused-components
144
- McTooltip, //Используется через component :is
145
- 'imask-input': IMaskComponent,
146
- },
147
- mixins: [fieldErrors, equalFieldHeight],
148
- props: {
149
- /**
150
- * Тип:
151
- * `textarea, textarea-autosize и
152
- * нативные как text, password, email и т.д.`
153
- *
154
- * кастомный num - разрешает ввод только цифр и дробных чисел, без ислчений ввиде буквы 'E'
155
- * кастомный int - разрешает ввод только целочисленных значений
156
- * кастомный amount_format - форматирует ввод числовых данных разделяя на разряды(1 000 000)
157
- * date - добавляет placeholder, маску и ограничения ввода
158
- * uppercase\lowercase - форматирует текст согласну значению (верхний\нижний регистр)
159
- * phone_number - добавляет '+' к номеру телефона при фокусе без возможности удалить его
160
- */
161
- type: {
162
- type: String,
163
- default: 'text',
164
- },
165
-
166
- /**
167
- * Заголовок поля:
168
- *
169
- */
170
- title: {
171
- type: String,
172
- default: null,
173
- },
174
-
175
- /**
176
- * Маска поля:
177
- *
178
- * tokens - https://imask.js.org/guide.html
179
- *
180
- */
181
- mask: {
182
- type: String,
183
- default: null,
184
- },
185
-
186
- /**
187
- * Вспомогательный текст под инпутом:
188
- *
189
- */
190
- helpText: {
191
- type: String,
192
- default: null,
193
- },
194
-
195
- /**
196
- * Отключенное состояние
197
- *
198
- */
199
- disabled: {
200
- type: Boolean,
201
- default: false,
202
- },
203
-
204
- /**
205
- * Значение
206
- *
207
- */
208
- value: {
209
- default: null,
210
- },
211
-
212
- /**
213
- * Ошибки
214
- *
215
- */
216
- errors: {
217
- type: Array,
218
- default: null,
219
- },
220
-
221
- /**
222
- * Placeholder
223
- *
224
- */
225
- placeholder: {
226
- type: String,
227
- default: null,
228
- },
229
-
230
- /**
231
- * Name
232
- *
233
- */
234
- name: {
235
- type: String,
236
- required: true,
237
- },
238
- /**
239
- * плейсхолдеры для короткого обозначения даты (для маски dd.mm.yyyy)
240
- * {
241
- * date: 'd',
242
- * month: 'm',
243
- * year: 'y',
244
- * }
245
- *
246
- */
247
- dateMaskPlaceholder: {
248
- type: Object,
249
- default: () => ({}),
250
- },
251
- /**
252
- * textarea-autosize Min height
253
- *
254
- */
255
- minHeight: {
256
- type: Number,
257
- default: null,
258
- },
259
-
260
- /**
261
- * textarea-autosize Max height
262
- *
263
- */
264
- maxHeight: {
265
- type: Number,
266
- default: null,
267
- },
268
-
269
- /**
270
- * Максимальная длина строки в инпуте
271
- *
272
- */
273
- maxLength: {
274
- type: Number,
275
- default: null,
276
- },
277
-
278
- /**
279
- * Состояние копирования
280
- *
281
- */
282
- copy: {
283
- type: Boolean,
284
- default: false,
285
- },
286
-
287
- /**
288
- * Автокомплит введённого ранее текста: on, off
289
- *
290
- */
291
- autocomplete: {
292
- type: String,
293
- default: 'on',
294
- },
295
-
296
- /**
297
- * только чтение текста
298
- *
299
- */
300
- readOnly: {
301
- type: Boolean,
302
- default: false,
303
- },
304
-
305
- /**
306
- * Атрибут tabindex для главного элемента
307
- *
308
- */
309
- tabindex: {
310
- type: [String, Number],
311
- },
312
-
313
- /**
314
- * Tooltip для кнопка "показать пароль"
315
- *
316
- */
317
- passwordTooltip: {
318
- type: String,
319
- default: null,
320
- },
321
-
322
- /**
323
- * Tooltip для кнопка "Скрыть пароль", если не указывать, то будет аналогичен "показать"
324
- *
325
- */
326
- passwordHideTooltip: {
327
- type: String,
328
- default: null,
329
- },
330
-
331
- /**
332
- * Очищаем данные от маски на выходе
333
- */
334
- clearOutput: {
335
- type: Boolean,
336
- default: false,
337
- },
338
-
339
- /**
340
- * Кастомные настройки для маски
341
- * См. https://imask.js.org/guide.html
342
- *
343
- * Например:
344
- * {
345
- * autofix: true,
346
- * blocks: {
347
- * d: {mask: IMask.MaskedRange, placeholderChar: 'd', from: 1, to: 31, maxLength: 2},
348
- * m: {mask: IMask.MaskedRange, placeholderChar: 'm', from: 1, to: 12, maxLength: 2},
349
- * Y: {mask: IMask.MaskedRange, placeholderChar: 'y', from: 1900, to: 2999, maxLength: 4}
350
- * }
351
- * }
352
- */
353
- maskOptions: {
354
- type: Object,
355
- default: null,
356
- },
357
- required: {
358
- type: Boolean,
359
- default: false,
360
- },
361
- /**
362
- * Для какого языка поле ввода
363
- */
364
- locale: {
365
- type: String,
366
- default: null,
367
- },
368
- /**
369
- * Мобильное ли разрешение
370
- * (Используется для триггера тултипа в кнопке с паролем)
371
- */
372
- isMobile: {
373
- type: Boolean,
374
- default: false,
375
- },
376
- /**
377
- * Свойство на ограничение количества символов после точки для числовых типов (num || amount_format)
378
- */
379
- maxDecimals: {
380
- type: Number,
381
- default: 2,
382
- },
383
- },
384
-
385
- data() {
386
- return {
387
- prependWidth: 0,
388
- appendWidth: 0,
389
- prettyType: this.type,
390
- }
391
- },
392
-
393
- computed: {
394
- rtl() {
395
- return LANGUAGES.rtl.includes(this.locale)
396
- },
397
- dir() {
398
- return this.rtl ? 'rtl' : null
399
- },
400
- classes() {
401
- return {
402
- 'mc-field-text': true,
403
- 'mc-field-text--error': this.errorText,
404
- 'mc-field-text--textarea': this.isTextarea,
405
- 'mc-field-text--textarea-autosize': this.isTextareaAutosize,
406
- 'mc-field-text--disabled': this.disabled,
407
- 'mc-field-text--copy': this.copy,
408
- 'mc-field-text--rtl': this.rtl,
409
- }
410
- },
411
- computedTitle() {
412
- return `${this.title}${this.required ? ' *' : ''}`
413
- },
414
- isMaskVisible() {
415
- return this.mask || this.maskOptions || this.prettyType === 'date'
416
- },
417
-
418
- isTextarea() {
419
- return this.type === 'textarea'
420
- },
421
-
422
- isTextareaAutosize() {
423
- return this.type === 'textarea-autosize'
424
- },
425
-
426
- isPassword() {
427
- return this.type === 'password'
428
- },
429
- isAmountFormat() {
430
- return this.type === 'amount_format'
431
- },
432
-
433
- hasCharCounter() {
434
- return this.maxLength && (this.isTextarea || this.isTextareaAutosize)
435
- },
436
-
437
- dateMask() {
438
- return {
439
- mask: Date,
440
- autofix: true,
441
- blocks: {
442
- d: {
443
- mask: IMask.MaskedRange,
444
- placeholderChar: this.dateMaskPlaceholder.date || 'd',
445
- from: 1,
446
- to: 31,
447
- maxLength: 2,
448
- },
449
- m: {
450
- mask: IMask.MaskedRange,
451
- placeholderChar: this.dateMaskPlaceholder.month || 'm',
452
- from: 1,
453
- to: 12,
454
- maxLength: 2,
455
- },
456
- Y: {
457
- mask: IMask.MaskedRange,
458
- placeholderChar: this.dateMaskPlaceholder.year || 'y',
459
- from: 1900,
460
- to: 2999,
461
- maxLength: 4,
462
- },
463
- },
464
- }
465
- },
466
-
467
- maskInputAttrs() {
468
- return {
469
- ...this.inputAttrs,
470
- mask: this.mask,
471
- lazy: false,
472
- overwrite: false,
473
- unmask: this.clearOutput,
474
- definitions: {
475
- '#': /./,
476
- },
477
- readonly: this.readOnly,
478
- maxlength: this.maxLength,
479
- type: 'tel',
480
- ...(this.maskOptions ?? {}),
481
- ...(this.prettyType === 'date' ? this.dateMask : {}),
482
- }
483
- },
484
-
485
- computedValue() {
486
- if (this.isAmountFormat && !this.isRtl) {
487
- return this.getAmountFormat(this.value)
488
- } else return this.value
489
- },
490
- isRtl() {
491
- return (
492
- document.querySelector('html').getAttribute('dir') === 'rtl' ||
493
- document.querySelector('html').getAttribute('direction') === 'rtl'
494
- )
495
- },
496
-
497
- inputAttrs() {
498
- return {
499
- class: 'mc-field-text__input',
500
- style: this.inputStyles,
501
- placeholder: this.placeholder,
502
- value: this.computedValue,
503
- disabled: this.disabled,
504
- name: this.name,
505
- id: this.name,
506
- autocomplete: this.autocomplete,
507
- tabindex: this.tabindex,
508
- }
509
- },
510
-
511
- isPasswordType() {
512
- return this.prettyType === 'password'
513
- },
514
-
515
- passwordIcon() {
516
- return this.isPasswordType ? 'visibility_off' : 'visibility'
517
- },
518
-
519
- charCounter() {
520
- return this.value ? this.value.length : 0
521
- },
522
-
523
- charCounterTitle() {
524
- return `${this.charCounter}/${this.maxLength}`
525
- },
526
-
527
- charCounterColor() {
528
- return this.maxLength < this.charCounter ? 'red' : 'dark-gray'
529
- },
530
-
531
- inputStyles() {
532
- const space = parseInt(getTokenValue('$space-150'))
533
- let bottomStyle = {}
534
- if (this.isTextarea || this.isTextareaAutosize) {
535
- const spaceBottomToken = this.hasCharCounter ? '$space-400' : '$space-150'
536
- const spaceBottomValue = parseInt(getTokenValue(spaceBottomToken))
537
- bottomStyle = { paddingBottom: `${spaceBottomValue - 1}px` }
538
- }
539
- return {
540
- paddingInlineStart: this.prependWidth && `${this.prependWidth + space}px`,
541
- paddingInlineEnd: this.appendWidth && `${this.appendWidth + space}px`,
542
- ...bottomStyle,
543
- }
544
- },
545
-
546
- listeners() {
547
- return _omit(this.$listeners, 'input')
548
- },
549
-
550
- passwordTooltipProps() {
551
- return this.passwordTooltip
552
- ? {
553
- is: 'mc-tooltip',
554
- content: this.isPasswordType
555
- ? this.passwordTooltip
556
- : this.passwordHideTooltip || this.passwordTooltip,
557
- placement: 'top',
558
- trigger: this.isMobile ? 'focus click' : 'hover focus',
559
- size: 's',
560
- }
561
- : {
562
- is: 'div',
563
- class: 'mc-field-text__empty-tooltip',
564
- }
565
- },
566
- },
567
-
568
- mounted() {
569
- this.calculatePadding()
570
- },
571
-
572
- methods: {
573
- setDecimalsLimit(val) {
574
- if (val && this.maxDecimals) {
575
- const [integerPart, decimalPart] = val.split('.')
576
- if (decimalPart?.length > this.maxDecimals) {
577
- return `${integerPart}.${decimalPart.slice(0, this.maxDecimals)}`
578
- }
579
- }
580
- return val
581
- },
582
- /**
583
- * Remove leading zero from input if length > 1 && number isn't decimal
584
- * */
585
- removeLeadingZero(val) {
586
- let result = val
587
- const [first_char] = val || []
588
- if (val.length > 1 && +first_char === 0 && val.indexOf('.') === -1) result = val.slice(1)
589
- return result
590
- },
591
- prepareHandleInput(e) {
592
- let value = e.target.value
593
- const number_types = ['num', 'amount_format']
594
- // For number types add possibility to write ","
595
- if (number_types.includes(this.type)) value = value?.replace(',', '.')
596
- switch (this.type) {
597
- case 'num': {
598
- let [num] = /-?\d*[\.]?\d*/.exec(String(value)) || []
599
- num = this.setDecimalsLimit(num)
600
- num = this.removeLeadingZero(num)
601
- value = num
602
- e.target.value = num
603
- break
604
- }
605
- case 'int': {
606
- let [int] = /-?\d*/.exec(String(e.target.value)) || []
607
- int = this.removeLeadingZero(int)
608
- value = int
609
- e.target.value = int
610
- break
611
- }
612
- case 'amount_format': {
613
- value = this.setDecimalsLimit(value)
614
- value = this.removeLeadingZero(value)
615
- const cursor_position = this.getCaretPos(e.target)?.start
616
- const prepared_value = this.formattedToNumber(value)
617
-
618
- const float_value = parseFloat(prepared_value)
619
- const without_spaces_value = prepared_value.replace(/ /gm, '')
620
-
621
- value = prepared_value
622
- ? String(float_value) === without_spaces_value
623
- ? float_value
624
- : without_spaces_value || float_value || prepared_value
625
- : null
626
- const formatted_value = this.getAmountFormat(prepared_value)
627
- e.target.value = this.isRtl ? formatted_value.replace(/ /gm, '') : formatted_value
628
- const space_length = e.target.value?.slice(0, cursor_position).replace(/[^ ]/gm, '')?.length || 0
629
- this.setCaretPos(e.target, cursor_position + space_length, cursor_position + space_length)
630
- break
631
- }
632
- case 'uppercase': {
633
- const cursor_position = this.getCaretPos(e.target)?.start
634
- value = value?.toUpperCase()
635
- e.target.value = value
636
- this.setCaretPos(e.target, cursor_position, cursor_position)
637
- break
638
- }
639
- case 'lowercase': {
640
- const cursor_position = this.getCaretPos(e.target)?.start
641
- value = value?.toLowerCase()
642
- e.target.value = value
643
- this.setCaretPos(e.target, cursor_position, cursor_position)
644
- break
645
- }
646
- case 'password':
647
- const cursor_position = this.getCaretPos(e.target)?.start
648
- value = value?.replace(/ /gm, '')
649
- e.target.value = value
650
- this.setCaretPos(e.target, cursor_position, cursor_position)
651
- break
652
- case 'phone_number':
653
- if (value.length === 0) value = '+'
654
- if (value.charAt(0) !== '+') value = '+' + value
655
- value = value.replace(/(?!^)\D/g, '')
656
- e.target.value = value
657
- break
658
- }
659
-
660
- this.handleInput(value)
661
- },
662
- prepareHandleKeyDown(e) {
663
- switch (this.type) {
664
- case 'amount_format':
665
- case 'num': {
666
- const exluded_symbols = ['.', ',']
667
- const already_has_symbol =
668
- typeof this.value === 'string' && exluded_symbols.some(symbol => this.value.includes(symbol))
669
- if (exluded_symbols.includes(e.key) && already_has_symbol) {
670
- e.preventDefault()
671
- }
672
- break
673
- }
674
- }
675
- this.$emit('keydown', e)
676
- },
677
- formattedToNumber(value) {
678
- const [first] =
679
- /-?\d*[\.]?\d*/.exec(
680
- String(value)
681
- ?.replace(/ /gm, '')
682
- ?.trim(),
683
- ) || []
684
-
685
- return first
686
- },
687
- setCaretPos(ctrl, start, end) {
688
- // IE >= 9 and other browsers
689
- if (ctrl.setSelectionRange) {
690
- ctrl.focus()
691
- ctrl.setSelectionRange(start, end)
692
- }
693
- // IE < 9
694
- else if (ctrl.createTextRange) {
695
- let range = ctrl.createTextRange()
696
- range.collapse(true)
697
- range.moveEnd('character', end)
698
- range.moveStart('character', start)
699
- range.select()
700
- }
701
- },
702
- getCaretPos(ctrl) {
703
- // IE < 9 Support
704
- if (document.selection) {
705
- ctrl.focus()
706
- let range = document.selection.createRange()
707
- let rangelen = range.text.length
708
- range.moveStart('character', -ctrl.value.length)
709
- let start = range.text.length - rangelen
710
- return { start: start, end: start + rangelen }
711
- }
712
- // IE >=9 and other browsers
713
- else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
714
- return { start: ctrl.selectionStart, end: ctrl.selectionEnd }
715
- } else {
716
- return { start: 0, end: 0 }
717
- }
718
- },
719
- getAmountFormat(value) {
720
- const formatted_number = this.formattedToNumber(value)
721
- const has_fraction = !!String(formatted_number)?.match(/\./)
722
-
723
- const [int, fraction] = String(formatted_number)
724
- .replace(/[^\d\.-]/g, '')
725
- .replace(/\B(?=(?:\d{3})+(?!\d))/g, ' ')
726
- .split('.')
727
-
728
- const formatted_values = [int, fraction?.replace(/ /gm, '') || '']
729
- if (has_fraction) {
730
- return formatted_values.join('.')
731
- }
732
- return formatted_values.filter(v => !!v).join('.')
733
- },
734
- handleInput(value) {
735
- this.toggleErrorVisible()
736
- /**
737
- * Событие инпута
738
- * @property {string}
739
- */
740
- this.$emit('input', value)
741
- },
742
-
743
- calculatePadding() {
744
- this.prependWidth = this.calculateSlotPadding('prepend')
745
- this.appendWidth = this.calculateSlotPadding('append')
746
- },
747
-
748
- calculateSlotPadding(name) {
749
- const tokenSpace = parseInt(getTokenValue('$space-50'))
750
- let result =
751
- this.$slots[name] &&
752
- this.$slots[name].reduce((acc, cur, index) => {
753
- const $el = cur.elm || cur
754
- const space = index && tokenSpace
755
- return acc + $el.getBoundingClientRect().width + space
756
- }, 0)
757
-
758
- if (name === 'prepend') return result
759
-
760
- /**
761
- * Также увеличиваем padding при наличии кнопки копирования и если тип password
762
- */
763
-
764
- const iconSpace = parseInt(getTokenValue('$space-300'))
765
-
766
- result = result ? result + tokenSpace : tokenSpace
767
- this.copy && (result += iconSpace)
768
- this.isPassword && (result += iconSpace)
769
- return result
770
- },
771
- handlerCopy(value) {
772
- /**
773
- * Событие по кнопке копирования
774
- * @property {string}
775
- */
776
- this.$emit('copy', value)
777
- },
778
- togglePasswordVisibility() {
779
- this.prettyType = this.isPasswordType ? 'text' : 'password'
780
- },
781
- },
782
- }
783
- </script>
784
-
785
- <style lang="scss">
786
- @import '../../../styles/mixins';
787
- @import '../../../tokens/durations';
788
- @import '../../../tokens/font-families';
789
- .mc-field-text {
790
- $block-name: &;
791
- display: block;
792
-
793
- &__header {
794
- @include reset-text-indents();
795
- display: block;
796
- margin-bottom: $space-100;
797
-
798
- &:empty {
799
- display: none;
800
- }
801
- }
802
-
803
- &__inner {
804
- display: flex;
805
- align-items: center;
806
- }
807
-
808
- &__right {
809
- flex-shrink: 0;
810
- }
811
-
812
- &__main {
813
- position: relative;
814
- width: 100%;
815
- @include custom-scroll($space-50);
816
- }
817
-
818
- &__prepend,
819
- &__append {
820
- @include reset-text-indents();
821
- position: absolute;
822
- top: 0;
823
- display: flex;
824
- align-items: center;
825
- justify-content: center;
826
- height: 100%;
827
-
828
- &:empty {
829
- display: none;
830
- }
831
-
832
- @include child-indent-right($space-50);
833
- }
834
-
835
- &__prepend {
836
- inset-inline-start: 0;
837
- padding: $space-100 0;
838
- padding-inline: $space-100 $space-50;
839
- }
840
-
841
- &__append {
842
- inset-inline-end: $space-100;
843
- padding: $space-100 0;
844
- padding-inline: $space-50 0;
845
- &--indent-bottom {
846
- padding-bottom: $space-400;
847
- }
848
- }
849
-
850
- &__char-counter {
851
- width: auto !important;
852
- position: absolute;
853
- inset-inline-end: $space-150;
854
- bottom: $space-150;
855
- background-color: $color-transparent;
856
- }
857
-
858
- &__input-wrapper {
859
- display: block;
860
- }
861
-
862
- &__input {
863
- font-family: $font-family-main;
864
- display: inline-block;
865
- vertical-align: middle;
866
- width: 100%;
867
- height: $size-500;
868
- margin: 0;
869
- border: 1px solid $color-outline-gray;
870
- border-radius: $radius-100;
871
- padding: $space-150 - 1px $space-150;
872
- line-height: $line-height-200;
873
- font-size: $font-size-200;
874
- background-color: $color-white;
875
- -moz-appearance: textfield;
876
- transition: background-color $duration-s ease, border-color $duration-s ease;
877
- color: $color-black;
878
-
879
- &:focus,
880
- &:hover {
881
- outline: 0;
882
- border-color: $color-purple;
883
- }
884
-
885
- &::-webkit-search-cancel-button,
886
- &::-webkit-search-decoration,
887
- &::-webkit-inner-spin-button,
888
- &::-webkit-outer-spin-button {
889
- -webkit-appearance: none;
890
- }
891
-
892
- @include input-placeholder() {
893
- color: $color-gray;
894
- }
895
- }
896
-
897
- &__footer {
898
- margin-top: $space-50;
899
- line-height: $line-height-150;
900
-
901
- &:empty {
902
- display: none;
903
- }
904
- }
905
-
906
- &--error {
907
- #{$block-name} {
908
- &__input {
909
- border-color: $color-red;
910
- }
911
- }
912
- }
913
-
914
- &--textarea {
915
- #{$block-name} {
916
- &__append,
917
- &__prepend {
918
- align-items: flex-start;
919
- }
920
-
921
- &__input {
922
- height: auto;
923
- min-height: 92px;
924
- resize: vertical;
925
- }
926
- }
927
- }
928
-
929
- &--textarea-autosize {
930
- #{$block-name} {
931
- &__input {
932
- height: auto;
933
- }
934
- }
935
- }
936
-
937
- &--disabled {
938
- #{$block-name} {
939
- &__input {
940
- color: $color-gray;
941
- cursor: not-allowed;
942
- background-color: $color-hover-gray;
943
- border-color: $color-outline-gray;
944
- }
945
- }
946
- }
947
-
948
- &--copy {
949
- #{$block-name} {
950
- &__input {
951
- color: $color-dark-gray;
952
- background-color: $color-hover-gray;
953
- border-color: $color-outline-gray;
954
- }
955
- }
956
- }
957
-
958
- &--rtl {
959
- direction: rtl;
960
- input {
961
- direction: rtl;
962
- }
963
- }
964
-
965
- &__empty-tooltip {
966
- display: contents;
967
- }
968
- }
969
- </style>