@cloud-ru/ds-fields 1.0.8-preview-6d260fa4.0 → 1.0.8-preview-3405f207.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloud-ru/ds-fields",
3
- "version": "1.0.8-preview-6d260fa4.0",
3
+ "version": "1.0.8-preview-3405f207.0",
4
4
  "description": "Поля ввода с единой обёрткой label/caption/hint/error и общими осями size/validationState — текст, пароль, число, ползунок, дата, время, выбор, цвет.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,24 +39,24 @@
39
39
  "classnames": "^2.5.1",
40
40
  "merge-refs": "^2.0.0",
41
41
  "react-textarea-autosize": "^8.5.9",
42
+ "@cloud-ru/ds-bottom-sheet": "1.0.3-preview-3405f207.0",
43
+ "@cloud-ru/ds-calendar": "1.0.7-preview-3405f207.0",
44
+ "@cloud-ru/ds-color-picker": "1.0.2",
45
+ "@cloud-ru/ds-button": "1.0.1",
42
46
  "@cloud-ru/ds-adaptive": "1.0.1",
43
- "@cloud-ru/ds-color-picker": "1.0.3-preview-6d260fa4.0",
44
47
  "@cloud-ru/ds-divider": "1.0.1",
45
- "@cloud-ru/ds-field-decorator": "1.0.3-preview-6d260fa4.0",
46
- "@cloud-ru/ds-dropdown": "1.0.3-preview-6d260fa4.0",
47
- "@cloud-ru/ds-icons": "1.0.2-preview-6d260fa4.0",
48
- "@cloud-ru/ds-input-private": "1.0.2-preview-6d260fa4.0",
49
- "@cloud-ru/ds-list": "2.0.1-preview-6d260fa4.0",
48
+ "@cloud-ru/ds-dropdown": "1.0.3-preview-3405f207.0",
49
+ "@cloud-ru/ds-field-decorator": "1.0.2",
50
+ "@cloud-ru/ds-icons": "1.0.1",
51
+ "@cloud-ru/ds-list": "2.0.1-preview-3405f207.0",
52
+ "@cloud-ru/ds-input-private": "1.0.1",
50
53
  "@cloud-ru/ds-loader": "1.0.1",
51
- "@cloud-ru/ds-skeleton": "1.0.1",
52
- "@cloud-ru/ds-scroll": "1.0.2-preview-6d260fa4.0",
53
54
  "@cloud-ru/ds-materials": "1.0.1",
54
- "@cloud-ru/ds-slider": "1.0.3-preview-6d260fa4.0",
55
- "@cloud-ru/ds-tag": "1.0.4-preview-6d260fa4.0",
56
- "@cloud-ru/ds-tooltip": "1.0.3-preview-6d260fa4.0",
57
- "@cloud-ru/ds-calendar": "1.0.7-preview-6d260fa4.0",
58
- "@cloud-ru/ds-utils": "1.1.0",
59
- "@cloud-ru/ds-button": "1.0.1",
60
- "@cloud-ru/ds-bottom-sheet": "1.0.3-preview-6d260fa4.0"
55
+ "@cloud-ru/ds-scroll": "1.0.1",
56
+ "@cloud-ru/ds-skeleton": "1.0.1",
57
+ "@cloud-ru/ds-slider": "1.0.2",
58
+ "@cloud-ru/ds-tag": "1.0.4-preview-3405f207.0",
59
+ "@cloud-ru/ds-tooltip": "1.0.2",
60
+ "@cloud-ru/ds-utils": "1.1.0"
61
61
  }
62
62
  }
@@ -141,42 +141,15 @@ export const FieldSelect = forwardRef<HTMLInputElement, FieldSelectProps>(functi
141
141
  // строкой при переключении selection) не должен ронять компонент на `.map` строки.
142
142
  multiple && Array.isArray(props.defaultValue) ? (props.defaultValue as ItemId[]) : [],
143
143
  );
144
-
145
- // Controlled-режим «залипает»: как только потребитель прислал `value`, локальный стейт больше
146
- // не читается. Иначе очистка (потребитель ставит `undefined`) откатывалась бы на устаревший
147
- // локальный выбор и воскрешала прошлое значение.
148
- const singleControlled = useRef(false);
149
- const multipleControlled = useRef(false);
150
-
151
- if (!multiple && props.value !== undefined) {
152
- singleControlled.current = true;
153
- }
154
-
155
- if (multiple && Array.isArray(props.value)) {
156
- multipleControlled.current = true;
157
- }
158
-
159
- const singleValue = useMemo<ItemId | undefined>(() => {
160
- if (multiple) {
161
- return undefined;
162
- }
163
-
164
- const raw = singleControlled.current ? (props.value as ItemId | undefined) : singleLocal;
165
-
166
- // `''` = «значение не выбрано»: формы отдают пустое значение строкой.
167
- return raw === '' ? undefined : raw;
168
- }, [multiple, props.value, singleLocal]);
169
-
144
+ const singleValue = useMemo<ItemId | undefined>(
145
+ () => (!multiple ? ((props.value as ItemId | undefined) ?? singleLocal) : undefined),
146
+ [multiple, props.value, singleLocal],
147
+ );
170
148
  const multipleValue = useMemo<ItemId[]>(() => {
171
149
  if (!multiple) {
172
150
  return [];
173
151
  }
174
-
175
- if (multipleControlled.current) {
176
- return Array.isArray(props.value) ? (props.value as ItemId[]) : [];
177
- }
178
-
179
- return multipleLocal;
152
+ return Array.isArray(props.value) ? (props.value as ItemId[]) : multipleLocal;
180
153
  }, [multiple, props.value, multipleLocal]);
181
154
 
182
155
  const effectiveValidationState = useMemo(
@@ -574,7 +547,7 @@ export const FieldSelect = forwardRef<HTMLInputElement, FieldSelectProps>(functi
574
547
  className={cn(fieldStyles.fieldInput, !searchable && styles.readonlyCursor)}
575
548
  value={inputValue}
576
549
  onChange={searchable ? handleInputChange : undefined}
577
- placeholder={selectedLabel || hasChips ? '' : placeholder}
550
+ placeholder={selectedLabel ? '' : placeholder}
578
551
  disabled={disabled}
579
552
  readonly={!searchable || readOnly}
580
553
  id={id}
@@ -163,9 +163,9 @@ type CommonSelectProps = FieldSelectDecoratorProps &
163
163
  export type FieldSelectSingleProps = CommonSelectProps & {
164
164
  /** Режим выбора. По умолчанию `'single'`. */
165
165
  selection?: typeof SELECTION_MODE.Single;
166
- /** Управляемое значение. Пустая строка трактуется как «значение не выбрано». */
166
+ /** Управляемое значение */
167
167
  value?: ItemId;
168
- /** Неуправляемое значение по умолчанию. Пустая строка трактуется как «значение не выбрано». */
168
+ /** Неуправляемое значение по умолчанию */
169
169
  defaultValue?: ItemId;
170
170
  /** Колбек смены значения */
171
171
  onChange?(value: ItemId | undefined): void;
@@ -105,16 +105,10 @@ type FieldTextAreaOwnProps = {
105
105
  */
106
106
  showClearButton?: boolean;
107
107
  /**
108
- * Кнопка копирования (видна при непустом value в режиме readonly, как у остальных полей)
108
+ * Кнопка копирования (видна при value && !disabled, независимо от readonly)
109
109
  * @default true
110
110
  */
111
111
  showCopyButton?: boolean;
112
- /**
113
- * Показывать кнопку копирования и в обычном (не readonly) режиме — рядом с кнопкой очистки.
114
- * Опция только для textarea: в многострочном поле копирование значения осмысленно и при вводе.
115
- * @default false
116
- */
117
- showCopyButtonInEditMode?: boolean;
118
112
  /** Колбек после копирования */
119
113
  onCopyButtonClick?(): void;
120
114
  /** Колбек фокуса */
@@ -163,7 +157,6 @@ export const FieldTextArea = forwardRef<HTMLTextAreaElement, FieldTextAreaProps>
163
157
  footer,
164
158
  showClearButton: showClearButtonProp = true,
165
159
  showCopyButton: showCopyButtonProp = true,
166
- showCopyButtonInEditMode = false,
167
160
  onCopyButtonClick,
168
161
  onFocus: onFocusProp,
169
162
  onBlur: onBlurProp,
@@ -199,9 +192,9 @@ export const FieldTextArea = forwardRef<HTMLTextAreaElement, FieldTextAreaProps>
199
192
  const stringValue = String(value ?? '');
200
193
  const isResizable = resizable && !disabled && !readOnly;
201
194
  const showClearUi = Boolean(showClearButtonProp && stringValue && !readOnly && !disabled);
202
- // По умолчанию copy — только в readonly, как у остальных полей. В editable-режиме кнопка
203
- // появляется лишь по явному `showCopyButtonInEditMode`; тогда видны обе (clear + copy).
204
- const showCopyUi = Boolean(showCopyButtonProp && stringValue && !disabled && (readOnly || showCopyButtonInEditMode));
195
+ // Copy не завязан на readonly (паритет с snack-uikit master): виден при любом непустом значении.
196
+ // В editable-режиме показываются обе кнопки (clear + copy), в readonly — только copy.
197
+ const showCopyUi = Boolean(showCopyButtonProp && stringValue && !disabled);
205
198
 
206
199
  const onClear = useCallback(() => {
207
200
  setValue('');