@snack-uikit/fields 0.51.11 → 0.51.12-preview-97a466ef.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -213,371 +213,58 @@ FieldStepper в основном предназначен для работы с
213
213
  ### Props
214
214
  | name | type | default value | description |
215
215
  |------|------|---------------|-------------|
216
- | open | `boolean` | - | Открыт color-picker |
217
- | onOpenChange | `(value: boolean) => void` | - | Колбек открытия пикера |
218
- | showCopyButton | `boolean` | - | Отображение кнопки копирования |
219
- | onCopyButtonClick | `() => void` | - | Колбек клика по кнопке Копировать для поля |
220
- | showClearButton | `boolean` | true | Отображение кнопки Очистки поля |
221
- | value | `string` | - | Значение input |
222
- | onChange | `(value: string) => void` | - | |
223
- | withAlpha | `boolean` | - | Значение с альфаканалом |
224
- | autoApply | `boolean` | - | Применять изменения автоматически, если значение false - то изменения происходят по кнопке |
225
- | className | `string` | - | Класснейм |
226
- | colorMode | `{ hex?: boolean; rgb?: boolean; hsv?: boolean; }` | - | |
227
- | id | `string` | - | Значение html-атрибута id |
228
- | name | `string` | - | Значение html-атрибута name |
229
- | disabled | `boolean` | - | Является ли поле деактивированным |
230
- | readonly | `boolean` | - | Является ли поле доступным только для чтения |
231
- | onFocus | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки получения фокуса |
232
- | onBlur | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки потери фокуса |
233
- | placeholder | `string` | - | Значение плейсхолдера |
234
- | autoFocus | `boolean` | false | Включен ли авто-фокус для поля |
235
- | label | `string` | - | Лейбл |
236
- | labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
237
- | required | `boolean` | - | Является ли поле обязательным |
238
- | caption | `string` | - | Подпись справа от лейбла |
239
- | hint | `string` | - | Подсказка внизу |
240
- | showHintIcon | `boolean` | - | Отображать иконку подсказки |
241
- | size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
242
- | validationState | enum ValidationState: `"error"`, `"default"`, `"warning"`, `"success"` | default | Состояние валидации |
243
- | labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
244
- | error | `string` | - | |
245
216
  | ref | `LegacyRef<HTMLInputElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |
246
217
  | key | `Key` | - | |
247
218
  ## FieldDate
248
219
  ### Props
249
220
  | name | type | default value | description |
250
221
  |------|------|---------------|-------------|
251
- | mode* | "date" \| "date-time" | - | |
252
- | open | `boolean` | - | Открыт date-picker |
253
- | onOpenChange | `(value: boolean) => void` | - | Колбек открытия пикера |
254
- | value | `Date` | - | Значение поля |
255
- | onChange | `(value: Date) => void` | - | Колбек смены значения |
256
- | showCopyButton | `boolean` | - | Отображение кнопки копирования |
257
- | onCopyButtonClick | `() => void` | - | Колбек клика по кнопке Копировать для поля |
258
- | showClearButton | `boolean` | true | Отображение кнопки Очистки поля |
259
- | buildCellProps | `(date: Date, viewMode: ViewMode) => { isDisabled?: boolean; isHoliday?: boolean } ;` | - | Колбек установки свойств ячеек календаря. Вызывается на построение каждой ячейки. Принимает два параметра: <br> `Date` - дата ячейки <br> `ViewMode`: <br> - `month` отображение месяца, каждая ячейка - 1 день <br> - `year` отображение года, каждая ячейка - 1 месяц <br> - `decade` отображение декады, каждая ячейка - 1 год <br><br> Колбек должен возвращать объект с полями, отвечающими за отключение и подкраску ячейки. |
260
- | id | `string` | - | Значение html-атрибута id |
261
- | name | `string` | - | Значение html-атрибута name |
262
- | disabled | `boolean` | - | Является ли поле деактивированным |
263
- | readonly | `boolean` | - | Является ли поле доступным только для чтения |
264
- | onFocus | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки получения фокуса |
265
- | onBlur | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки потери фокуса |
266
- | autoFocus | `boolean` | false | Включен ли авто-фокус для поля |
267
- | className | `string` | - | CSS-класс |
268
- | label | `string` | - | Лейбл |
269
- | labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
270
- | required | `boolean` | - | Является ли поле обязательным |
271
- | caption | `string` | - | Подпись справа от лейбла |
272
- | hint | `string` | - | Подсказка внизу |
273
- | showHintIcon | `boolean` | - | Отображать иконку подсказки |
274
- | size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
275
- | validationState | enum ValidationState: `"error"`, `"default"`, `"warning"`, `"success"` | default | Состояние валидации |
276
- | labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
277
- | error | `string` | - | |
278
222
  | ref | `LegacyRef<HTMLInputElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |
279
223
  | key | `Key` | - | |
280
- | showSeconds | `boolean` | - | |
281
224
  ## FieldDecorator
282
225
  ### Props
283
226
  | name | type | default value | description |
284
227
  |------|------|---------------|-------------|
285
- | children* | `ReactNode` | - | Контент |
286
- | className | `string` | - | CSS-класс |
287
- | disabled | `boolean` | - | Деактивирован ли элемент Является ли поле деактивированным |
288
- | readonly | `boolean` | - | Является ли поле доступным только на чтение Доступно ли поле только на чтение |
289
- | error | `string` | - | |
290
- | label | `string` | - | Лейбл |
291
- | caption | `string` | - | Подпись справа от лейбла |
292
- | labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
293
- | labelFor | `string` | - | Аттрибут for |
294
- | required | `boolean` | - | Является ли поле обязательным |
295
- | size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
296
- | labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
297
- | length | `{ current: number; max?: number; }` | - | Допустимая длинна текста |
298
- | hint | `string` | - | Подсказка внизу |
299
- | validationState | enum ValidationState: `"error"`, `"default"`, `"warning"`, `"success"` | default | Состояние валидации |
300
- | showHintIcon | `boolean` | - | Отображать иконку подсказки |
301
228
  | ref | `LegacyRef<HTMLDivElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |
302
229
  | key | `Key` | - | |
303
230
  ## FieldSecure
304
231
  ### Props
305
232
  | name | type | default value | description |
306
233
  |------|------|---------------|-------------|
307
- | hidden | `boolean` | - | Замаскированно ли значение поля |
308
- | onHiddenChange | `(value: boolean) => void` | - | Колбек смены маскирования |
309
- | showCopyButton | `boolean` | - | Отображение кнопки копирования |
310
- | onCopyButtonClick | `() => void` | - | Колбек клика по кнопке Копировать для поля |
311
- | allowMoreThanMaxLength | `boolean` | - | Можно ли вводить больше разрешённого кол-ва символов |
312
- | prefixIcon | `ReactElement<any, string \| JSXElementConstructor<any>>` | - | Иконка-префикс для поля |
313
- | asyncValueGetter | `() => Promise<string>` | - | Свойство позволяет грузить данные в поле по требованию |
314
- | onChange | `(value: string, e?: ChangeEvent<HTMLInputElement>) => void` | - | Колбек смены значения |
315
- | value | `string` | - | Значение input |
316
- | id | `string` | - | Значение html-атрибута id |
317
- | name | `string` | - | Значение html-атрибута name |
318
- | disabled | `boolean` | - | Является ли поле деактивированным |
319
- | readonly | `boolean` | - | Является ли поле доступным только для чтения |
320
- | onFocus | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки получения фокуса |
321
- | onBlur | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки потери фокуса |
322
- | placeholder | `string` | - | Значение плейсхолдера |
323
- | autoFocus | `boolean` | false | Включен ли авто-фокус для поля |
324
- | maxLength | `number` | - | Максимальная длина вводимого значения |
325
- | autoComplete | `string \| boolean` | false | Включен ли автокомплит для поля |
326
- | className | `string` | - | CSS-класс |
327
- | label | `string` | - | Лейбл |
328
- | labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
329
- | required | `boolean` | - | Является ли поле обязательным |
330
- | caption | `string` | - | Подпись справа от лейбла |
331
- | hint | `string` | - | Подсказка внизу |
332
- | showHintIcon | `boolean` | - | Отображать иконку подсказки |
333
- | size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
334
- | validationState | enum ValidationState: `"error"`, `"default"`, `"warning"`, `"success"` | default | Состояние валидации |
335
- | labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
336
- | error | `string` | - | |
337
234
  | ref | `LegacyRef<HTMLInputElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |
338
235
  | key | `Key` | - | |
339
236
  ## FieldSelect
340
237
  ### Props
341
238
  | name | type | default value | description |
342
239
  |------|------|---------------|-------------|
343
- | options* | `OptionProps[]` | - | |
344
- | id | `string` | - | Значение html-атрибута id |
345
- | name | `string` | - | Значение html-атрибута name |
346
- | disabled | `boolean` | false | Является ли поле деактивированным |
347
- | readonly | `boolean` | false false | Является ли поле доступным только для чтения |
348
- | onFocus | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки получения фокуса |
349
- | onBlur | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки потери фокуса |
350
- | placeholder | `string` | - | Значение плейсхолдера |
351
- | autoFocus | `boolean` | false | Включен ли авто-фокус для поля |
352
- | onKeyDown | `KeyboardEventHandler<HTMLInputElement>` | - | Колбек обработки начала нажатия клавиши клавиатуры |
353
- | className | `string` | - | CSS-класс |
354
- | label | `string` | - | Лейбл |
355
- | labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
356
- | required | `boolean` | - | Является ли поле обязательным |
357
- | caption | `string` | - | Подпись справа от лейбла |
358
- | hint | `string` | - | Подсказка внизу |
359
- | showHintIcon | `boolean` | - | Отображать иконку подсказки |
360
- | size | enum Size: `"s"`, `"m"`, `"l"` | - | Размер |
361
- | validationState | enum ValidationState: `"error"`, `"default"`, `"warning"`, `"success"` | - | Состояние валидации |
362
- | labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
363
- | error | `string` | - | |
364
- | loading | `boolean` | - | |
365
- | prefix | `ReactNode` | - | Произвольный префикс для поля |
366
- | postfix | `ReactNode` | - | Произвольный постфикс для поля |
367
- | onChange | `OnChangeHandler<any>` | - | Controlled обработчик измения состояния |
368
- | value | `ItemId \| ItemId[]` | - | Controlled состояние |
369
- | defaultValue | `ItemId \| ItemId[]` | - | Начальное состояние |
370
- | pinTop | `OptionProps[]` | - | |
371
- | pinBottom | `OptionProps[]` | - | |
372
- | searchable | `boolean` | - | |
373
- | showCopyButton | `boolean` | - | Отображение кнопки Копировать для поля (актуально только для `readonly = true`) |
374
- | onCopyButtonClick | `() => void` | - | Колбек клика по кнопке Копировать для поля |
375
- | showClearButton | `boolean` | true | Отображение кнопки очистки поля |
376
- | prefixIcon | `ReactElement<any, string \| JSXElementConstructor<any>>` | - | Иконка-префикс для поля |
377
- | footer | `ReactNode` | - | |
378
- | widthStrategy | enum PopoverWidthStrategy: `"auto"`, `"gte"`, `"eq"` | - | |
379
- | search | `SearchState` | - | |
380
- | autocomplete | `boolean` | - | |
381
- | addOptionByEnter | `boolean` | - | |
382
- | open | `boolean` | - | |
383
- | enableFuzzySearch | `boolean` | - | Включить нечеткий поиск |
384
- | resetSearchOnOptionSelection | `boolean` | true | Поведение строки поиска при выборе опции из списка, false необходимо при асинхронной подгрузке значений с бэка, в случае если надо поиск оставить как значение при отсутствии данных |
385
- | onOpenChange | `(open: boolean) => void` | - | |
386
- | selectedOptionFormatter | `SelectedOptionFormatter` | - | |
387
- | scrollToSelectedItem | `boolean` | - | Флаг, отвещающий за прокручивание до выбранного элемента |
388
- | virtualized | `boolean` | - | Включить виртуализацию на компоненты списка. Рекомендуется если у вас от 1к элементов списка |
389
- | untouchableScrollbars | `boolean` | - | Отключает возможность взаимодействовать со скролбарами мышью. |
390
- | dataFiltered | `boolean` | - | |
391
- | dataError | `boolean` | - | |
392
- | noDataState | `EmptyStateProps` | - | Экран при отстутствии данных |
393
- | noResultsState | `EmptyStateProps` | - | Экран при отстутствии результатов поиска или фильтров |
394
- | errorDataState | `EmptyStateProps` | - | Экран при ошибке запроса |
395
- | selection | "single" \| "multiple" | - | |
396
- | ref | `LegacyRef<HTMLInputElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |
397
- | key | `Key` | - | |
398
- | removeByBackspace | `boolean` | - | |
399
240
  ## FieldSlider
400
241
  ### Props
401
242
  | name | type | default value | description |
402
243
  |------|------|---------------|-------------|
403
- | postfixIcon | `ReactElement<any, string \| JSXElementConstructor<any>>` | - | Иконка-постфикс для поля |
404
- | showScaleBar | `boolean` | true | Отображение линейки |
405
- | textInputFormatter | `TextInputFormatter` | - | Функция для форматирования значений в текстовом поле |
406
- | unbindInputFromMarks | `boolean` | - | Отвязать текстовое поле от значений на линейке |
407
- | prefix | `ReactNode` | - | Произвольный префикс для поля |
408
- | postfix | `ReactNode` | - | Произвольный постфикс для поля |
409
- | id | `string` | - | Значение html-атрибута id |
410
- | name | `string` | - | Значение html-атрибута name |
411
- | disabled | `boolean` | - | Является ли поле деактивированным |
412
- | readonly | `boolean` | - | Является ли поле доступным только для чтения |
413
- | onFocus | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки получения фокуса |
414
- | onBlur | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки потери фокуса |
415
- | autoFocus | `boolean` | false | Включен ли авто-фокус для поля |
416
- | onChange | `(value: number \| number[]) => void` | - | |
417
- | value | `number \| number[]` | - | |
418
- | range | `boolean` | - | |
419
- | tipFormatter | `(value: string \| number) => ReactNode` | - | |
420
- | step | `number` | - | |
421
- | min | `number` | - | |
422
- | max | `number` | - | |
423
- | marks | `Record<string \| number, ReactNode \| MarkObj>` | - | |
424
- | className | `string` | - | CSS-класс |
425
- | label | `string` | - | Лейбл |
426
- | labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
427
- | required | `boolean` | - | Является ли поле обязательным |
428
- | caption | `string` | - | Подпись справа от лейбла |
429
- | hint | `string` | - | Подсказка внизу |
430
- | showHintIcon | `boolean` | - | Отображать иконку подсказки |
431
- | size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
432
- | labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
433
244
  | ref | `LegacyRef<HTMLInputElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |
434
245
  | key | `Key` | - | |
435
246
  ## FieldStepper
436
247
  ### Props
437
248
  | name | type | default value | description |
438
249
  |------|------|---------------|-------------|
439
- | value | `number` | - | Значение поля |
440
- | onChange | `(value: number, e?: ChangeEvent<HTMLInputElement>) => void` | - | Колбек смены значения |
441
- | step | `number` | 1 | Шаг поля |
442
- | allowMoreThanLimits | `boolean` | true | Можно ли вводить c клавиатуры числа, выходящие за пределы min/max |
443
- | prefix | `ReactNode` | - | Произвольный префикс для поля |
444
- | postfix | `ReactNode` | - | Произвольный постфикс для поля |
445
- | plusButtonTooltip | `TooltipProps` | - | Тултип над кнопкой увеличения значения |
446
- | minusButtonTooltip | `TooltipProps` | - | Тултип над кнопкой уменьшения значения |
447
- | id | `string` | - | Значение html-атрибута id |
448
- | name | `string` | - | Значение html-атрибута name |
449
- | disabled | `boolean` | - | Является ли поле деактивированным |
450
- | readonly | `boolean` | - | Является ли поле доступным только для чтения |
451
- | onFocus | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки получения фокуса |
452
- | onBlur | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки потери фокуса |
453
- | autoFocus | `boolean` | false | Включен ли авто-фокус для поля |
454
- | min | `number` | Number.NEGATIVE_INFINITY | Минимальное значение поля |
455
- | max | `number` | Number.POSITIVE_INFINITY | Максимальное значение поля |
456
- | className | `string` | - | CSS-класс |
457
- | label | `string` | - | Лейбл |
458
- | labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
459
- | required | `boolean` | - | Является ли поле обязательным |
460
- | caption | `string` | - | Подпись справа от лейбла |
461
- | hint | `string` | - | Подсказка внизу |
462
- | showHintIcon | `boolean` | - | Отображать иконку подсказки |
463
- | size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
464
- | validationState | enum ValidationState: `"error"`, `"default"`, `"warning"`, `"success"` | default | Состояние валидации |
465
- | labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
466
- | error | `string` | - | |
467
250
  | ref | `LegacyRef<HTMLInputElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |
468
251
  | key | `Key` | - | |
469
252
  ## FieldText
470
253
  ### Props
471
254
  | name | type | default value | description |
472
255
  |------|------|---------------|-------------|
473
- | showCopyButton | `boolean` | - | Отображение кнопки Копировать для поля (актуально только для `readonly = true`) |
474
- | onCopyButtonClick | `() => void` | - | Колбек клика по кнопке Копировать для поля |
475
- | showClearButton | `boolean` | true | Отображение кнопки очистки поля |
476
- | allowMoreThanMaxLength | `boolean` | - | Можно ли вводить больше разрешённого кол-ва символов |
477
- | prefixIcon | `ReactElement<any, string \| JSXElementConstructor<any>>` | - | Иконка-префикс для поля |
478
- | prefix | `ReactNode` | - | Произвольный префикс для поля |
479
- | postfix | `ReactNode` | - | Произвольный постфикс для поля |
480
- | button | `Button` | - | Кнопка действия внутри поля |
481
- | type | "text" \| "tel" \| "email" | text | |
482
- | onChange | `(value: string, e?: ChangeEvent<HTMLInputElement>) => void` | - | Колбек смены значения |
483
- | value | `string` | - | Значение input |
484
- | inputMode | enum InputMode: `"none"`, `"text"`, `"search"`, `"tel"`, `"email"`, `"decimal"`, `"numeric"`, `"url"` | - | Режим работы экранной клавиатуры |
485
- | id | `string` | - | Значение html-атрибута id |
486
- | name | `string` | - | Значение html-атрибута name |
487
- | disabled | `boolean` | - | Является ли поле деактивированным |
488
- | readonly | `boolean` | - | Является ли поле доступным только для чтения |
489
- | onFocus | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки получения фокуса |
490
- | onBlur | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки потери фокуса |
491
- | placeholder | `string` | - | Значение плейсхолдера |
492
- | autoFocus | `boolean` | false | Включен ли авто-фокус для поля |
493
- | maxLength | `number` | - | Максимальная длина вводимого значения |
494
- | autoComplete | `string \| boolean` | false | Включен ли автокомплит для поля |
495
- | spellCheck | `boolean` | true | Значение атрибута spellcheck (проверка орфографии) |
496
- | pattern | `string` | - | Регулярное выражение валидного инпута |
497
- | onKeyDown | `KeyboardEventHandler<HTMLInputElement>` | - | Колбек обработки начала нажатия клавиши клавиатуры |
498
- | onPaste | `ClipboardEventHandler<HTMLInputElement>` | - | Колбек обработки вставки значения |
499
- | className | `string` | - | CSS-класс |
500
- | label | `string` | - | Лейбл |
501
- | labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
502
- | required | `boolean` | - | Является ли поле обязательным |
503
- | caption | `string` | - | Подпись справа от лейбла |
504
- | hint | `string` | - | Подсказка внизу |
505
- | showHintIcon | `boolean` | - | Отображать иконку подсказки |
506
- | size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
507
- | validationState | enum ValidationState: `"error"`, `"default"`, `"warning"`, `"success"` | default | Состояние валидации |
508
- | labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
509
- | error | `string` | - | |
510
256
  | ref | `LegacyRef<HTMLInputElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |
511
257
  | key | `Key` | - | |
512
258
  ## FieldTextArea
513
259
  ### Props
514
260
  | name | type | default value | description |
515
261
  |------|------|---------------|-------------|
516
- | minRows | `number` | 3 | Минимальное кол-во строк, до которого размер поля может быть увеличен |
517
- | maxRows | `number` | 1000 | Максимальное кол-во строк, до которого размер поля может быть увеличен |
518
- | resizable | `boolean` | - | Может ли ли пользователь изменять размеры поля (если св-во не включено, поле автоматически меняет свой размер) |
519
- | onChange | `(value: string, e?: ChangeEvent<HTMLTextAreaElement>) => void` | - | Колбек смены значения |
520
- | showCopyButton | `boolean` | - | Отображение кнопки Копировать для поля (актуально только для `readonly = true`) |
521
- | onCopyButtonClick | `() => void` | - | Колбек клика по кнопке Копировать для поля |
522
- | showClearButton | `boolean` | true | Отображение кнопки очистки поля |
523
- | allowMoreThanMaxLength | `boolean` | true | Можно ли вводить больше разрешённого кол-ва символов |
524
- | footer | `ReactNode` | - | Нода под футер |
525
- | value | `string` | - | HTML-аттрибут value |
526
- | id | `string` | - | HTML-аттрибут id |
527
- | name | `string` | - | HTML-аттрибут name |
528
- | disabled | `boolean` | - | Является ли поле деактивированным |
529
- | readonly | `boolean` | - | Является ли поле доступным только на чтение |
530
- | onFocus | `FocusEventHandler<HTMLTextAreaElement>` | - | Колбек получения фокуса |
531
- | onBlur | `FocusEventHandler<HTMLTextAreaElement>` | - | Колбек потери фокуса |
532
- | placeholder | `string` | - | Плейсхолдер |
533
- | autoFocus | `boolean` | - | Включен ли авто-фокус |
534
- | maxLength | `number` | - | Максимальное кол-во символов |
535
- | inputMode | enum InputMode: `"none"`, `"text"`, `"search"`, `"tel"`, `"email"`, `"decimal"`, `"numeric"`, `"url"` | - | Режим работы экранной клавиатуры |
536
- | spellCheck | `boolean` | true | Включение проверки орфографии |
537
- | onKeyDown | `KeyboardEventHandler<HTMLTextAreaElement>` | - | Колбек нажатия клавиши клавиатуры |
538
- | className | `string` | - | CSS-класс |
539
- | label | `string` | - | Лейбл |
540
- | labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
541
- | required | `boolean` | - | Является ли поле обязательным |
542
- | caption | `string` | - | Подпись справа от лейбла |
543
- | hint | `string` | - | Подсказка внизу |
544
- | showHintIcon | `boolean` | - | Отображать иконку подсказки |
545
- | size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
546
- | validationState | enum ValidationState: `"error"`, `"default"`, `"warning"`, `"success"` | default | Состояние валидации |
547
- | labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
548
- | error | `string` | - | |
549
262
  | ref | `LegacyRef<HTMLTextAreaElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |
550
263
  | key | `Key` | - | |
551
264
  ## FieldTime
552
265
  ### Props
553
266
  | name | type | default value | description |
554
267
  |------|------|---------------|-------------|
555
- | open | `boolean` | - | Открыт time-picker |
556
- | onOpenChange | `(value: boolean) => void` | - | Колбек открытия пикера |
557
- | value | `TimeValue` | - | Значение поля |
558
- | onChange | `(value?: TimeValue) => void` | - | Колбек смены значения |
559
- | showCopyButton | `boolean` | - | Отображение кнопки копирования |
560
- | onCopyButtonClick | `() => void` | - | Колбек клика по кнопке Копировать для поля |
561
- | showSeconds | `boolean` | true | Показывать ли секунды |
562
- | showClearButton | `boolean` | true | Отображение кнопки Очистки поля |
563
- | id | `string` | - | Значение html-атрибута id |
564
- | name | `string` | - | Значение html-атрибута name |
565
- | disabled | `boolean` | - | Является ли поле деактивированным |
566
- | readonly | `boolean` | - | Является ли поле доступным только для чтения |
567
- | onFocus | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки получения фокуса |
568
- | onBlur | `FocusEventHandler<HTMLInputElement>` | - | Колбек обработки потери фокуса |
569
- | autoFocus | `boolean` | false | Включен ли авто-фокус для поля |
570
- | className | `string` | - | CSS-класс |
571
- | label | `string` | - | Лейбл |
572
- | labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
573
- | required | `boolean` | - | Является ли поле обязательным |
574
- | caption | `string` | - | Подпись справа от лейбла |
575
- | hint | `string` | - | Подсказка внизу |
576
- | showHintIcon | `boolean` | - | Отображать иконку подсказки |
577
- | size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
578
- | validationState | enum ValidationState: `"error"`, `"default"`, `"warning"`, `"success"` | default | Состояние валидации |
579
- | labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
580
- | error | `string` | - | |
581
268
  | ref | `LegacyRef<HTMLInputElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs} |
582
269
  | key | `Key` | - | |
583
270
 
@@ -15,6 +15,8 @@ type FieldTextOwnProps = {
15
15
  * @default true
16
16
  */
17
17
  showClearButton?: boolean;
18
+ /** Колбек клика по кнопке очистки поля */
19
+ onClearButtonClick?(): void;
18
20
  /** Можно ли вводить больше разрешённого кол-ва символов */
19
21
  allowMoreThanMaxLength?: boolean;
20
22
  /** Иконка-префикс для поля */
@@ -44,6 +44,7 @@ exports.FieldText = (0, react_1.forwardRef)((_a, ref) => {
44
44
  onFocus,
45
45
  onBlur,
46
46
  onCopyButtonClick,
47
+ onClearButtonClick,
47
48
  className,
48
49
  label,
49
50
  labelTooltip,
@@ -67,7 +68,7 @@ exports.FieldText = (0, react_1.forwardRef)((_a, ref) => {
67
68
  inputMode,
68
69
  spellCheck
69
70
  } = _a,
70
- rest = __rest(_a, ["id", "name", "value", "placeholder", "maxLength", "disabled", "readonly", "showCopyButton", "showClearButton", "allowMoreThanMaxLength", "onChange", "onFocus", "onBlur", "onCopyButtonClick", "className", "label", "labelTooltip", "labelTooltipPlacement", "required", "caption", "hint", "showHintIcon", "size", "validationState", "error", "autoComplete", "autoFocus", "prefixIcon", "prefix", "postfix", "button", "onPaste", "onKeyDown", "type", "inputMode", "spellCheck"]);
71
+ rest = __rest(_a, ["id", "name", "value", "placeholder", "maxLength", "disabled", "readonly", "showCopyButton", "showClearButton", "allowMoreThanMaxLength", "onChange", "onFocus", "onBlur", "onCopyButtonClick", "onClearButtonClick", "className", "label", "labelTooltip", "labelTooltipPlacement", "required", "caption", "hint", "showHintIcon", "size", "validationState", "error", "autoComplete", "autoFocus", "prefixIcon", "prefix", "postfix", "button", "onPaste", "onKeyDown", "type", "inputMode", "spellCheck"]);
71
72
  const [value = '', onChange] = (0, hooks_1.useValueControl)({
72
73
  value: valueProp,
73
74
  defaultValue: '',
@@ -98,18 +99,26 @@ exports.FieldText = (0, react_1.forwardRef)((_a, ref) => {
98
99
  const containerVariant = (0, helpers_1.getContainerVariant)({
99
100
  button
100
101
  });
101
- const onClear = () => {
102
+ const [isFieldFocused, setIsFieldFocused] = (0, react_1.useState)(false);
103
+ const focusedRef = (0, react_1.useRef)(false);
104
+ const onClear = e => {
102
105
  var _a;
106
+ e.preventDefault();
103
107
  onChange('');
104
- if (required) {
108
+ onClearButtonClick === null || onClearButtonClick === void 0 ? void 0 : onClearButtonClick();
109
+ if (focusedRef.current) {
105
110
  (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus();
106
111
  }
107
112
  };
113
+ const handleClearClickDown = () => {
114
+ focusedRef.current = isFieldFocused;
115
+ };
108
116
  const clearButtonSettings = (0, input_private_1.useClearButton)({
109
117
  clearButtonRef,
110
118
  showClearButton,
111
- size,
112
- onClear
119
+ onClear,
120
+ onDown: handleClearClickDown,
121
+ size
113
122
  });
114
123
  const copyButtonSettings = (0, hooks_1.useCopyButton)({
115
124
  copyButtonRef,
@@ -164,6 +173,20 @@ exports.FieldText = (0, react_1.forwardRef)((_a, ref) => {
164
173
  onInputKeyDown(event);
165
174
  onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
166
175
  };
176
+ const handleBlur = event => {
177
+ const nextTarget = event.relatedTarget;
178
+ // если фокус ушёл на кнопку очистки — игнорируем «внешний» onBlur
179
+ if (nextTarget && nextTarget === clearButtonRef.current) {
180
+ setIsFieldFocused(false);
181
+ return;
182
+ }
183
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
184
+ setIsFieldFocused(false);
185
+ };
186
+ const handleFocus = event => {
187
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
188
+ setIsFieldFocused(true);
189
+ };
167
190
  return (0, jsx_runtime_1.jsx)(FieldDecorator_1.FieldDecorator, Object.assign({
168
191
  className: className,
169
192
  label: label,
@@ -199,8 +222,8 @@ exports.FieldText = (0, react_1.forwardRef)((_a, ref) => {
199
222
  "data-size": size,
200
223
  value: value,
201
224
  onChange: onChange,
202
- onFocus: onFocus,
203
- onBlur: onBlur,
225
+ onFocus: handleFocus,
226
+ onBlur: handleBlur,
204
227
  tabIndex: inputTabIndex,
205
228
  onKeyDown: handleKeyDown,
206
229
  onPaste: onPaste,
@@ -15,6 +15,8 @@ type FieldTextOwnProps = {
15
15
  * @default true
16
16
  */
17
17
  showClearButton?: boolean;
18
+ /** Колбек клика по кнопке очистки поля */
19
+ onClearButtonClick?(): void;
18
20
  /** Можно ли вводить больше разрешённого кол-ва символов */
19
21
  allowMoreThanMaxLength?: boolean;
20
22
  /** Иконка-префикс для поля */
@@ -21,7 +21,7 @@ import { getValidationState } from '../../utils/getValidationState';
21
21
  import { FieldDecorator } from '../FieldDecorator';
22
22
  import { getContainerVariant } from './helpers';
23
23
  export const FieldText = forwardRef((_a, ref) => {
24
- var { id, name, value: valueProp, placeholder, maxLength, disabled = false, readonly = false, showCopyButton: showCopyButtonProp = true, showClearButton: showClearButtonProp = true, allowMoreThanMaxLength = false, onChange: onChangeProp, onFocus, onBlur, onCopyButtonClick, className, label, labelTooltip, labelTooltipPlacement, required = false, caption, hint, showHintIcon, size = SIZE.S, validationState = VALIDATION_STATE.Default, error, autoComplete, autoFocus, prefixIcon, prefix, postfix, button: buttonProp, onPaste, onKeyDown, type = 'text', inputMode, spellCheck } = _a, rest = __rest(_a, ["id", "name", "value", "placeholder", "maxLength", "disabled", "readonly", "showCopyButton", "showClearButton", "allowMoreThanMaxLength", "onChange", "onFocus", "onBlur", "onCopyButtonClick", "className", "label", "labelTooltip", "labelTooltipPlacement", "required", "caption", "hint", "showHintIcon", "size", "validationState", "error", "autoComplete", "autoFocus", "prefixIcon", "prefix", "postfix", "button", "onPaste", "onKeyDown", "type", "inputMode", "spellCheck"]);
24
+ var { id, name, value: valueProp, placeholder, maxLength, disabled = false, readonly = false, showCopyButton: showCopyButtonProp = true, showClearButton: showClearButtonProp = true, allowMoreThanMaxLength = false, onChange: onChangeProp, onFocus, onBlur, onCopyButtonClick, onClearButtonClick, className, label, labelTooltip, labelTooltipPlacement, required = false, caption, hint, showHintIcon, size = SIZE.S, validationState = VALIDATION_STATE.Default, error, autoComplete, autoFocus, prefixIcon, prefix, postfix, button: buttonProp, onPaste, onKeyDown, type = 'text', inputMode, spellCheck } = _a, rest = __rest(_a, ["id", "name", "value", "placeholder", "maxLength", "disabled", "readonly", "showCopyButton", "showClearButton", "allowMoreThanMaxLength", "onChange", "onFocus", "onBlur", "onCopyButtonClick", "onClearButtonClick", "className", "label", "labelTooltip", "labelTooltipPlacement", "required", "caption", "hint", "showHintIcon", "size", "validationState", "error", "autoComplete", "autoFocus", "prefixIcon", "prefix", "postfix", "button", "onPaste", "onKeyDown", "type", "inputMode", "spellCheck"]);
25
25
  const [value = '', onChange] = useValueControl({
26
26
  value: valueProp,
27
27
  defaultValue: '',
@@ -41,14 +41,27 @@ export const FieldText = forwardRef((_a, ref) => {
41
41
  setTimeout(() => { var _a; return (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, 0);
42
42
  } }) }) : undefined, [buttonProp]);
43
43
  const containerVariant = getContainerVariant({ button });
44
- const onClear = () => {
44
+ const [isFieldFocused, setIsFieldFocused] = useState(false);
45
+ const focusedRef = useRef(false);
46
+ const onClear = e => {
45
47
  var _a;
48
+ e.preventDefault();
46
49
  onChange('');
47
- if (required) {
50
+ onClearButtonClick === null || onClearButtonClick === void 0 ? void 0 : onClearButtonClick();
51
+ if (focusedRef.current) {
48
52
  (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus();
49
53
  }
50
54
  };
51
- const clearButtonSettings = useClearButton({ clearButtonRef, showClearButton, size, onClear });
55
+ const handleClearClickDown = () => {
56
+ focusedRef.current = isFieldFocused;
57
+ };
58
+ const clearButtonSettings = useClearButton({
59
+ clearButtonRef,
60
+ showClearButton,
61
+ onClear,
62
+ onDown: handleClearClickDown,
63
+ size,
64
+ });
52
65
  const copyButtonSettings = useCopyButton({
53
66
  copyButtonRef,
54
67
  showCopyButton,
@@ -91,5 +104,19 @@ export const FieldText = forwardRef((_a, ref) => {
91
104
  onInputKeyDown(event);
92
105
  onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
93
106
  };
94
- return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, caption: caption, length: maxLength ? { max: maxLength, current: value.length } : undefined, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, validationState: fieldValidationState, error: error }, extractSupportProps(rest), { children: _jsx(FieldContainerPrivate, { size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: containerVariant, inputRef: localRef, prefix: prefixButtons, postfix: postfixButtons, disableFocus: isButtonFocused, children: _jsx(InputPrivate, { ref: mergeRefs(ref, localRef), "data-size": size, value: value, onChange: onChange, onFocus: onFocus, onBlur: onBlur, tabIndex: inputTabIndex, onKeyDown: handleKeyDown, onPaste: onPaste, placeholder: placeholder, disabled: disabled, readonly: readonly, type: type, inputMode: inputMode, maxLength: allowMoreThanMaxLength ? undefined : maxLength || undefined, id: id, name: name, autoComplete: autoComplete, autoFocus: autoFocus, spellCheck: spellCheck, "data-test-id": 'field-text__input' }) }) })));
107
+ const handleBlur = event => {
108
+ const nextTarget = event.relatedTarget;
109
+ // если фокус ушёл на кнопку очистки — игнорируем «внешний» onBlur
110
+ if (nextTarget && nextTarget === clearButtonRef.current) {
111
+ setIsFieldFocused(false);
112
+ return;
113
+ }
114
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
115
+ setIsFieldFocused(false);
116
+ };
117
+ const handleFocus = event => {
118
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
119
+ setIsFieldFocused(true);
120
+ };
121
+ return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, caption: caption, length: maxLength ? { max: maxLength, current: value.length } : undefined, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, validationState: fieldValidationState, error: error }, extractSupportProps(rest), { children: _jsx(FieldContainerPrivate, { size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: containerVariant, inputRef: localRef, prefix: prefixButtons, postfix: postfixButtons, disableFocus: isButtonFocused, children: _jsx(InputPrivate, { ref: mergeRefs(ref, localRef), "data-size": size, value: value, onChange: onChange, onFocus: handleFocus, onBlur: handleBlur, tabIndex: inputTabIndex, onKeyDown: handleKeyDown, onPaste: onPaste, placeholder: placeholder, disabled: disabled, readonly: readonly, type: type, inputMode: inputMode, maxLength: allowMoreThanMaxLength ? undefined : maxLength || undefined, id: id, name: name, autoComplete: autoComplete, autoFocus: autoFocus, spellCheck: spellCheck, "data-test-id": 'field-text__input' }) }) })));
95
122
  });
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "title": "Fields",
7
- "version": "0.51.11",
7
+ "version": "0.51.12-preview-97a466ef.0",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -37,13 +37,13 @@
37
37
  "scripts": {},
38
38
  "dependencies": {
39
39
  "@snack-uikit/button": "0.19.16",
40
- "@snack-uikit/calendar": "0.13.10",
41
- "@snack-uikit/color-picker": "0.3.49",
40
+ "@snack-uikit/calendar": "0.13.11-preview-97a466ef.0",
41
+ "@snack-uikit/color-picker": "0.3.50-preview-97a466ef.0",
42
42
  "@snack-uikit/divider": "3.2.10",
43
43
  "@snack-uikit/dropdown": "0.5.3",
44
44
  "@snack-uikit/icons": "0.27.4",
45
- "@snack-uikit/input-private": "4.8.4",
46
- "@snack-uikit/list": "0.32.9",
45
+ "@snack-uikit/input-private": "4.8.5-preview-97a466ef.0",
46
+ "@snack-uikit/list": "0.32.10-preview-97a466ef.0",
47
47
  "@snack-uikit/scroll": "0.10.5",
48
48
  "@snack-uikit/skeleton": "0.6.9",
49
49
  "@snack-uikit/slider": "0.3.30",
@@ -66,5 +66,5 @@
66
66
  "peerDependencies": {
67
67
  "@snack-uikit/locale": "*"
68
68
  },
69
- "gitHead": "6b39e180766635f8190da903bf560d1fbcbfaf52"
69
+ "gitHead": "450dcb64cce754f9b3622e7b2bfaf109c00ccfad"
70
70
  }
@@ -1,7 +1,9 @@
1
1
  import mergeRefs from 'merge-refs';
2
2
  import {
3
+ FocusEventHandler,
3
4
  forwardRef,
4
5
  KeyboardEventHandler,
6
+ MouseEventHandler,
5
7
  ReactElement,
6
8
  ReactNode,
7
9
  useCallback,
@@ -66,6 +68,8 @@ type FieldTextOwnProps = {
66
68
  * @default true
67
69
  */
68
70
  showClearButton?: boolean;
71
+ /** Колбек клика по кнопке очистки поля */
72
+ onClearButtonClick?(): void;
69
73
  /** Можно ли вводить больше разрешённого кол-ва символов */
70
74
  allowMoreThanMaxLength?: boolean;
71
75
  /** Иконка-префикс для поля */
@@ -100,6 +104,7 @@ export const FieldText = forwardRef<HTMLInputElement, FieldTextProps>(
100
104
  onFocus,
101
105
  onBlur,
102
106
  onCopyButtonClick,
107
+ onClearButtonClick,
103
108
  className,
104
109
  label,
105
110
  labelTooltip,
@@ -158,15 +163,31 @@ export const FieldText = forwardRef<HTMLInputElement, FieldTextProps>(
158
163
 
159
164
  const containerVariant = getContainerVariant({ button });
160
165
 
161
- const onClear = () => {
166
+ const [isFieldFocused, setIsFieldFocused] = useState(false);
167
+ const focusedRef = useRef(false);
168
+
169
+ const onClear: MouseEventHandler<HTMLButtonElement> = e => {
170
+ e.preventDefault();
162
171
  onChange('');
172
+ onClearButtonClick?.();
163
173
 
164
- if (required) {
174
+ if (focusedRef.current) {
165
175
  localRef.current?.focus();
166
176
  }
167
177
  };
168
178
 
169
- const clearButtonSettings = useClearButton({ clearButtonRef, showClearButton, size, onClear });
179
+ const handleClearClickDown = () => {
180
+ focusedRef.current = isFieldFocused;
181
+ };
182
+
183
+ const clearButtonSettings = useClearButton({
184
+ clearButtonRef,
185
+ showClearButton,
186
+ onClear,
187
+ onDown: handleClearClickDown,
188
+ size,
189
+ });
190
+
170
191
  const copyButtonSettings = useCopyButton({
171
192
  copyButtonRef,
172
193
  showCopyButton,
@@ -218,6 +239,24 @@ export const FieldText = forwardRef<HTMLInputElement, FieldTextProps>(
218
239
  onKeyDown?.(event);
219
240
  };
220
241
 
242
+ const handleBlur: FocusEventHandler<HTMLInputElement> = event => {
243
+ const nextTarget = event.relatedTarget as HTMLElement | null;
244
+
245
+ // если фокус ушёл на кнопку очистки — игнорируем «внешний» onBlur
246
+ if (nextTarget && nextTarget === clearButtonRef.current) {
247
+ setIsFieldFocused(false);
248
+ return;
249
+ }
250
+
251
+ onBlur?.(event);
252
+ setIsFieldFocused(false);
253
+ };
254
+
255
+ const handleFocus: FocusEventHandler<HTMLInputElement> = event => {
256
+ onFocus?.(event);
257
+ setIsFieldFocused(true);
258
+ };
259
+
221
260
  return (
222
261
  <FieldDecorator
223
262
  className={className}
@@ -253,8 +292,8 @@ export const FieldText = forwardRef<HTMLInputElement, FieldTextProps>(
253
292
  data-size={size}
254
293
  value={value}
255
294
  onChange={onChange}
256
- onFocus={onFocus}
257
- onBlur={onBlur}
295
+ onFocus={handleFocus}
296
+ onBlur={handleBlur}
258
297
  tabIndex={inputTabIndex}
259
298
  onKeyDown={handleKeyDown}
260
299
  onPaste={onPaste}