@finam/web-ui-kit-components 3.33.3 → 3.34.1

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
@@ -1,3 +1,8 @@
1
+ ## 3.34.1
2
+ * В `DraggablePopover` ограничено число последовательных коррекций позиции: окно, размер которого зависит от собственной позиции, больше не вызывает бесконечную цепочку `onChangePosition`; при достижении лимита в консоль выводится `warning` с историей коррекций и метриками экрана
3
+ ## 3.34.0
4
+ * В `TextArea` добавлен prop `resizable` — изменение высоты поля пользователем за правый нижний угол
5
+ * В `TextArea` применён `customScroll`
1
6
  ## 3.33.3
2
7
  * В `Calendar` ячейка дня, месяца и года стала кнопкой, у обёртки убрана роль `button`
3
8
  * В типе `BorderRadius` у `Paper` убраны лишние литералы union
@@ -1 +1 @@
1
- {"version":3,"file":"DraggablePopover.d.ts","sourceRoot":"","sources":["../../src/DraggablePopover/DraggablePopover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,SAAS,EAEV,MAAM,OAAO,CAAC;AAGf,OAAkB,EAAE,eAAe,EAAiC,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAO5G,OAAO,EAAE,YAAY,EAAuB,MAAM,mBAAmB,CAAC;AAUtE,MAAM,WAAW,KAAM,SAAQ,OAAO,CAAC,cAAc,CAAC;IACpD,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,IAAI,EAAE,OAAO,CAAC;IACd,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,uCAAuC;IACvC,QAAQ,EAAE,SAAS,CAAC;IACpB,sEAAsE;IACtE,gBAAgB,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;IACtD,yBAAyB;IACzB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,oFAAoF;IACpF,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,YAAY,EAAE,eAAe,EAAE,CAAC;wMAY7B,KAAK;AAuMR,wBAAsC"}
1
+ {"version":3,"file":"DraggablePopover.d.ts","sourceRoot":"","sources":["../../src/DraggablePopover/DraggablePopover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,SAAS,EAEV,MAAM,OAAO,CAAC;AAGf,OAAkB,EAAE,eAAe,EAAiC,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAO5G,OAAO,EAAE,YAAY,EAAuB,MAAM,mBAAmB,CAAC;AAoCtE,MAAM,WAAW,KAAM,SAAQ,OAAO,CAAC,cAAc,CAAC;IACpD,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,IAAI,EAAE,OAAO,CAAC;IACd,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,uCAAuC;IACvC,QAAQ,EAAE,SAAS,CAAC;IACpB,sEAAsE;IACtE,gBAAgB,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;IACtD,yBAAyB;IACzB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,oFAAoF;IACpF,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,YAAY,EAAE,eAAe,EAAE,CAAC;wMAY7B,KAAK;AAiQR,wBAAsC"}
@@ -19,6 +19,7 @@ import { DraggableWrap, PaperStyled, transitionClassName } from "./DraggablePopo
19
19
  import { useIsomorphicEffect } from "../utils/useIsomorphicEffect.js";
20
20
  import { transitionClassNames } from "../utils/transition.js";
21
21
  const DEFAULT_OFFSET = 16;
22
+ const MAX_POSITION_CORRECTIONS = 2;
22
23
  const DraggablePopover = (_0)=>{
23
24
  let { show, children, onEsc, layerId: layerIdProp, className, onChangePosition, onExited, modalManager: modalManagerProp } = _0, draggableProps = _object_without_properties__(_0, [
24
25
  "show",
@@ -38,6 +39,12 @@ const DraggablePopover = (_0)=>{
38
39
  const rootRef = useRef(null);
39
40
  const [zIndex, setZIndex] = useState(0);
40
41
  const [resized, setResized] = useReducer((prev)=>!prev, false);
42
+ const correctionsRef = useRef({
43
+ resized,
44
+ count: 0,
45
+ warned: false,
46
+ log: []
47
+ });
41
48
  const positionX = null != (_ref = null != (_ref1 = null == positionProp ? void 0 : positionProp.x) ? _ref1 : null == defaultPosition ? void 0 : defaultPosition.x) ? _ref : DEFAULT_OFFSET;
42
49
  const positionY = null != (_ref2 = null != (_ref3 = null == positionProp ? void 0 : positionProp.y) ? _ref3 : null == defaultPosition ? void 0 : defaultPosition.y) ? _ref2 : DEFAULT_OFFSET;
43
50
  const position = useMemo(()=>correctPosition(positionX, positionY, popoverRef.current), [
@@ -66,6 +73,8 @@ const DraggablePopover = (_0)=>{
66
73
  onStart
67
74
  ]);
68
75
  const handleDragStop = useCallback((e, data)=>{
76
+ correctionsRef.current.count = 0;
77
+ correctionsRef.current.log = [];
69
78
  onChangePosition({
70
79
  x: data.x,
71
80
  y: data.y
@@ -116,6 +125,12 @@ const DraggablePopover = (_0)=>{
116
125
  useIsomorphicEffect(()=>{
117
126
  const popover = popoverRef.current;
118
127
  if (!popover) return;
128
+ if (correctionsRef.current.resized !== resized) correctionsRef.current = {
129
+ resized,
130
+ count: 0,
131
+ warned: false,
132
+ log: []
133
+ };
119
134
  const screenWidth = document.documentElement.scrollWidth;
120
135
  const screenHeight = document.documentElement.scrollHeight;
121
136
  const prevWidth = popover.style.width;
@@ -133,7 +148,50 @@ const DraggablePopover = (_0)=>{
133
148
  if (screenHeightDiff > 0) nextPosition.y -= screenHeightDiff;
134
149
  nextPosition.x = Math.max(0, nextPosition.x);
135
150
  nextPosition.y = Math.max(0, nextPosition.y);
136
- if (position.x !== nextPosition.x || position.y !== nextPosition.y) onChangePosition(nextPosition);
151
+ if (position.x !== nextPosition.x || position.y !== nextPosition.y) {
152
+ const corrections = correctionsRef.current;
153
+ if (corrections.log.length <= MAX_POSITION_CORRECTIONS) corrections.log.push({
154
+ from: position,
155
+ to: nextPosition,
156
+ diff: {
157
+ width: screenWidthDiff,
158
+ height: screenHeightDiff
159
+ },
160
+ popover: {
161
+ width: popover.offsetWidth,
162
+ height: popover.offsetHeight
163
+ }
164
+ });
165
+ if (corrections.count >= MAX_POSITION_CORRECTIONS) {
166
+ if (!corrections.warned) {
167
+ var _window_visualViewport, _window_visualViewport1, _window_visualViewport2;
168
+ corrections.warned = true;
169
+ console.warn(`DraggablePopover (layer "${layerIdRef.current}"): position corrections limit reached, popover is left outside the screen. If popover size changes together with position, the consumer makes its size depend on position (e.g. max-height from position.y); if size and diff stay the same, removing the popover changes the rest of the layout`, {
170
+ corrections: corrections.log,
171
+ resized,
172
+ screen: {
173
+ scrollWidth: screenWidth,
174
+ scrollHeight: screenHeight,
175
+ scrollWidthWithout: screenWidthWithout,
176
+ scrollHeightWithout: screenHeightWithout,
177
+ clientWidth: document.documentElement.clientWidth,
178
+ clientHeight: document.documentElement.clientHeight
179
+ },
180
+ viewport: {
181
+ devicePixelRatio: window.devicePixelRatio,
182
+ visualViewportScale: null == (_window_visualViewport = window.visualViewport) ? void 0 : _window_visualViewport.scale,
183
+ innerWidth: window.innerWidth,
184
+ innerHeight: window.innerHeight,
185
+ visualViewportWidth: null == (_window_visualViewport1 = window.visualViewport) ? void 0 : _window_visualViewport1.width,
186
+ visualViewportHeight: null == (_window_visualViewport2 = window.visualViewport) ? void 0 : _window_visualViewport2.height
187
+ }
188
+ });
189
+ }
190
+ return;
191
+ }
192
+ corrections.count += 1;
193
+ onChangePosition(nextPosition);
194
+ }
137
195
  }, [
138
196
  position.x,
139
197
  position.y,
@@ -1 +1 @@
1
- {"version":3,"file":"DraggablePopover/DraggablePopover.js","sources":["../../src/DraggablePopover/DraggablePopover.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n memo,\n useState,\n ReactNode,\n useReducer,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport debounce from 'lodash/debounce.js';\nimport Draggable, { ControlPosition, DraggableData, DraggableEvent, DraggableProps } from 'react-draggable';\nimport { CSSTransition } from 'react-transition-group';\nimport { tokens } from '@finam/web-ui-kit-core/theme/contract';\nimport { transitionGrow, transitionGrowParent } from '@finam/web-ui-kit-core/styles/transition';\nimport classNames from 'clsx';\n\nimport { KeyboardEventKey } from '../types.js';\nimport { ModalManager, defaultModalManager } from '../Modal/index.js';\nimport { useModalState } from '../ModalsProvider/index.js';\nimport { defaultLayersManager } from './layersManager.js';\nimport { correctPosition } from './utils.js';\nimport { PaperStyled, DraggableWrap, transitionClassName } from './DraggablePopover.styles.js';\nimport { useIsomorphicEffect } from '../utils/useIsomorphicEffect.js';\nimport { transitionClassNames } from '../utils/transition.js';\n\nconst DEFAULT_OFFSET = 16;\n\nexport interface Props extends Partial<DraggableProps> {\n /** Кастомные классы передаваемые в компонент Paper перетаскиваемого окна */\n className?: string;\n /** Идентификатор слоя, используется для управления порядком отображения окон */\n layerId?: string;\n /** Управление видимостью перетаскиваемого окна */\n show: boolean;\n /** Коллбэк, вызываемый на нажатие ESCAPE */\n onEsc?: () => void;\n /** Содержимое перетаскиваемого окна */\n children: ReactNode;\n /** Коллбэк, вызываемый при изменении позиции перетаскиваемого окна */\n onChangePosition: (position: ControlPosition) => void;\n /** from CSSTransition */\n onExited?: VoidFunction;\n /** Экземпляр класса ModalManager для управления порядком открытых модальных окон */\n modalManager?: ModalManager;\n}\n\nexport type { ControlPosition };\n\nconst DraggablePopover = ({\n show,\n children,\n onEsc,\n layerId: layerIdProp,\n className,\n onChangePosition,\n onExited,\n modalManager: modalManagerProp,\n ...draggableProps\n}: Props) => {\n const {\n position: positionProp,\n defaultPosition,\n onStart,\n onMouseDown,\n onStop,\n } = draggableProps;\n const { className: modalClassName } = useModalState();\n const layerIdRef = useRef<string>(layerIdProp || Math.random().toString());\n const popoverRef = useRef<HTMLDivElement | null>(null);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [zIndex, setZIndex] = useState(0);\n const [resized, setResized] = useReducer(prev => !prev, false);\n\n const positionX = positionProp?.x ?? defaultPosition?.x ?? DEFAULT_OFFSET;\n const positionY = positionProp?.y ?? defaultPosition?.y ?? DEFAULT_OFFSET;\n const position = useMemo(() => (\n correctPosition(positionX, positionY, popoverRef.current)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n ), [positionX, positionY, resized]);\n\n const modalManager = modalManagerProp || defaultModalManager;\n\n const handleMouseDown = useCallback((e: MouseEvent) => {\n const popover = popoverRef.current;\n const layerId = layerIdRef.current;\n\n defaultLayersManager.setLayerActive(layerId);\n if (popover) {\n modalManager.remove(popover);\n modalManager.add(popover);\n }\n onMouseDown?.(e);\n }, [modalManager, onMouseDown]);\n\n const handleDragStart = useCallback((e: DraggableEvent, data: DraggableData) => {\n e.preventDefault();\n onStart?.(e, data);\n }, [onStart]);\n\n const handleDragStop = useCallback((e: DraggableEvent, data: DraggableData) => {\n onChangePosition({ x: data.x, y: data.y });\n onStop?.(e, data);\n }, [onChangePosition, onStop]);\n\n useEffect(() => {\n if (!show) return undefined;\n\n const popover = popoverRef.current;\n const layerId = layerIdRef.current;\n\n defaultLayersManager.addLayerListener(\n layerId,\n () => {\n setZIndex(prev => (defaultLayersManager.isLayerActive(layerId) ? 0 : prev + 1));\n },\n () => {\n setZIndex(prevZIndex => prevZIndex - 1);\n },\n );\n defaultLayersManager.setLayerActive(layerId);\n if (popover) {\n modalManager.add(popover);\n }\n\n return () => {\n defaultLayersManager.removeLayerListener(layerId);\n setZIndex(0);\n if (popover) {\n modalManager.remove(popover);\n }\n };\n }, [modalManager, show]);\n\n useEffect(() => {\n if (!show) return undefined;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const { key } = event;\n if (\n (key === KeyboardEventKey.ESCAPE || key === KeyboardEventKey.ESC) &&\n onEsc && !event.defaultPrevented &&\n defaultLayersManager.isLayerActive(layerIdRef.current) &&\n popoverRef.current && modalManager.isTop(popoverRef.current)\n ) {\n event.preventDefault();\n onEsc();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [modalManager, onEsc, show]);\n\n useIsomorphicEffect(() => {\n const popover = popoverRef.current;\n if (!popover) return;\n\n const screenWidth = document.documentElement.scrollWidth;\n const screenHeight = document.documentElement.scrollHeight;\n\n const prevWidth = popover.style.width;\n const prevHeight = popover.style.height;\n popover.style.width = '0px';\n popover.style.height = '0px';\n const screenWidthWithout = document.documentElement.scrollWidth;\n const screenHeightWithout = document.documentElement.scrollHeight;\n popover.style.width = prevWidth;\n popover.style.height = prevHeight;\n\n const screenWidthDiff = screenWidth - screenWidthWithout;\n const screenHeightDiff = screenHeight - screenHeightWithout;\n\n const nextPosition = { ...position };\n if (screenWidthDiff > 0) {\n nextPosition.x -= screenWidthDiff;\n }\n if (screenHeightDiff > 0) {\n nextPosition.y -= screenHeightDiff;\n }\n\n nextPosition.x = Math.max(0, nextPosition.x);\n nextPosition.y = Math.max(0, nextPosition.y);\n\n if (position.x !== nextPosition.x || position.y !== nextPosition.y) {\n onChangePosition(nextPosition);\n }\n }, [position.x, position.y, resized, onChangePosition]);\n\n useEffect(() => {\n const popover = popoverRef.current;\n if (!show || !popover) return undefined;\n\n const handleResize = debounce(() => {\n setResized();\n }, 250);\n\n setResized();\n window.addEventListener('resize', handleResize);\n let resizeObserver: ResizeObserver | undefined;\n if ('ResizeObserver' in window) {\n try {\n resizeObserver = new window.ResizeObserver(handleResize);\n resizeObserver.observe(popover);\n } catch (e) {\n console.warn('Failed to create ResizeObserver for handling element resize', e);\n }\n }\n\n return () => {\n handleResize.cancel();\n window.removeEventListener('resize', handleResize);\n resizeObserver?.disconnect();\n };\n }, [show]);\n\n const paperClassName = classNames(\n transitionGrow(),\n className,\n );\n\n return createPortal(\n <Draggable\n bounds=\"parent\"\n {...draggableProps}\n nodeRef={popoverRef}\n position={position}\n onMouseDown={handleMouseDown}\n onStart={handleDragStart}\n onStop={handleDragStop}\n >\n <DraggableWrap\n ref={popoverRef}\n className={modalClassName}\n style={{ zIndex: `calc(${tokens.zIndex.draggablePopover} + ${zIndex})` }}\n >\n <CSSTransition\n nodeRef={rootRef}\n mountOnEnter={true}\n unmountOnExit={true}\n classNames={transitionClassNames([transitionGrowParent, transitionClassName])}\n timeout={300}\n in={show}\n onExited={onExited}\n >\n <PaperStyled shadow=\"modalDialog\" ref={rootRef} className={paperClassName} tabIndex={0}>\n {children}\n </PaperStyled>\n </CSSTransition>\n </DraggableWrap>\n </Draggable>,\n document.body,\n );\n};\n\nexport default memo(DraggablePopover);\n"],"names":["DEFAULT_OFFSET","DraggablePopover","show","children","onEsc","layerIdProp","className","onChangePosition","onExited","modalManagerProp","draggableProps","_ref","_ref2","positionProp","defaultPosition","onStart","onMouseDown","onStop","modalClassName","useModalState","layerIdRef","useRef","Math","popoverRef","rootRef","zIndex","setZIndex","useState","resized","setResized","useReducer","prev","positionX","positionY","position","useMemo","correctPosition","modalManager","defaultModalManager","handleMouseDown","useCallback","e","popover","layerId","defaultLayersManager","handleDragStart","data","handleDragStop","useEffect","prevZIndex","handleKeyDown","event","key","KeyboardEventKey","document","useIsomorphicEffect","screenWidth","screenHeight","prevWidth","prevHeight","screenWidthWithout","screenHeightWithout","screenWidthDiff","screenHeightDiff","nextPosition","handleResize","debounce","window","resizeObserver","console","paperClassName","classNames","transitionGrow","createPortal","Draggable","DraggableWrap","tokens","CSSTransition","transitionClassNames","transitionGrowParent","transitionClassName","PaperStyled","memo"],"mappings":"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"}
1
+ {"version":3,"file":"DraggablePopover/DraggablePopover.js","sources":["../../src/DraggablePopover/DraggablePopover.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n memo,\n useState,\n ReactNode,\n useReducer,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport debounce from 'lodash/debounce.js';\nimport Draggable, { ControlPosition, DraggableData, DraggableEvent, DraggableProps } from 'react-draggable';\nimport { CSSTransition } from 'react-transition-group';\nimport { tokens } from '@finam/web-ui-kit-core/theme/contract';\nimport { transitionGrow, transitionGrowParent } from '@finam/web-ui-kit-core/styles/transition';\nimport classNames from 'clsx';\n\nimport { KeyboardEventKey } from '../types.js';\nimport { ModalManager, defaultModalManager } from '../Modal/index.js';\nimport { useModalState } from '../ModalsProvider/index.js';\nimport { defaultLayersManager } from './layersManager.js';\nimport { correctPosition } from './utils.js';\nimport { PaperStyled, DraggableWrap, transitionClassName } from './DraggablePopover.styles.js';\nimport { useIsomorphicEffect } from '../utils/useIsomorphicEffect.js';\nimport { transitionClassNames } from '../utils/transition.js';\n\nconst DEFAULT_OFFSET = 16;\n\n/**\n * Сколько коррекций позиции подряд допускается между изменениями размера окна и перетаскиваниями.\n * Если размер окна зависит от его позиции (например, потребитель задаёт `max-height` от `y`),\n * сдвиг окна не убирает переполнение экрана, и цепочка коррекций становится бесконечной.\n */\nconst MAX_POSITION_CORRECTIONS = 2;\n\n/** Запись об одной коррекции позиции, нужна для диагностики упёршейся в лимит цепочки */\ninterface CorrectionLog {\n /** Позиция, с которой окно отрисовано */\n from: ControlPosition;\n /** Позиция, на которую окно сдвигается */\n to: ControlPosition;\n /** Насколько окно выходит за скролл-размер документа */\n diff: { width: number; height: number; };\n /** Размер окна на момент коррекции: меняется вместе с позицией, если размер от неё зависит */\n popover: { width: number; height: number; };\n}\n\ninterface CorrectionsState {\n resized: boolean;\n count: number;\n warned: boolean;\n log: CorrectionLog[];\n}\n\nexport interface Props extends Partial<DraggableProps> {\n /** Кастомные классы передаваемые в компонент Paper перетаскиваемого окна */\n className?: string;\n /** Идентификатор слоя, используется для управления порядком отображения окон */\n layerId?: string;\n /** Управление видимостью перетаскиваемого окна */\n show: boolean;\n /** Коллбэк, вызываемый на нажатие ESCAPE */\n onEsc?: () => void;\n /** Содержимое перетаскиваемого окна */\n children: ReactNode;\n /** Коллбэк, вызываемый при изменении позиции перетаскиваемого окна */\n onChangePosition: (position: ControlPosition) => void;\n /** from CSSTransition */\n onExited?: VoidFunction;\n /** Экземпляр класса ModalManager для управления порядком открытых модальных окон */\n modalManager?: ModalManager;\n}\n\nexport type { ControlPosition };\n\nconst DraggablePopover = ({\n show,\n children,\n onEsc,\n layerId: layerIdProp,\n className,\n onChangePosition,\n onExited,\n modalManager: modalManagerProp,\n ...draggableProps\n}: Props) => {\n const {\n position: positionProp,\n defaultPosition,\n onStart,\n onMouseDown,\n onStop,\n } = draggableProps;\n const { className: modalClassName } = useModalState();\n const layerIdRef = useRef<string>(layerIdProp || Math.random().toString());\n const popoverRef = useRef<HTMLDivElement | null>(null);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [zIndex, setZIndex] = useState(0);\n const [resized, setResized] = useReducer(prev => !prev, false);\n const correctionsRef = useRef<CorrectionsState>({ resized, count: 0, warned: false, log: [] });\n\n const positionX = positionProp?.x ?? defaultPosition?.x ?? DEFAULT_OFFSET;\n const positionY = positionProp?.y ?? defaultPosition?.y ?? DEFAULT_OFFSET;\n const position = useMemo(() => (\n correctPosition(positionX, positionY, popoverRef.current)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n ), [positionX, positionY, resized]);\n\n const modalManager = modalManagerProp || defaultModalManager;\n\n const handleMouseDown = useCallback((e: MouseEvent) => {\n const popover = popoverRef.current;\n const layerId = layerIdRef.current;\n\n defaultLayersManager.setLayerActive(layerId);\n if (popover) {\n modalManager.remove(popover);\n modalManager.add(popover);\n }\n onMouseDown?.(e);\n }, [modalManager, onMouseDown]);\n\n const handleDragStart = useCallback((e: DraggableEvent, data: DraggableData) => {\n e.preventDefault();\n onStart?.(e, data);\n }, [onStart]);\n\n const handleDragStop = useCallback((e: DraggableEvent, data: DraggableData) => {\n correctionsRef.current.count = 0;\n correctionsRef.current.log = [];\n onChangePosition({ x: data.x, y: data.y });\n onStop?.(e, data);\n }, [onChangePosition, onStop]);\n\n useEffect(() => {\n if (!show) return undefined;\n\n const popover = popoverRef.current;\n const layerId = layerIdRef.current;\n\n defaultLayersManager.addLayerListener(\n layerId,\n () => {\n setZIndex(prev => (defaultLayersManager.isLayerActive(layerId) ? 0 : prev + 1));\n },\n () => {\n setZIndex(prevZIndex => prevZIndex - 1);\n },\n );\n defaultLayersManager.setLayerActive(layerId);\n if (popover) {\n modalManager.add(popover);\n }\n\n return () => {\n defaultLayersManager.removeLayerListener(layerId);\n setZIndex(0);\n if (popover) {\n modalManager.remove(popover);\n }\n };\n }, [modalManager, show]);\n\n useEffect(() => {\n if (!show) return undefined;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const { key } = event;\n if (\n (key === KeyboardEventKey.ESCAPE || key === KeyboardEventKey.ESC) &&\n onEsc && !event.defaultPrevented &&\n defaultLayersManager.isLayerActive(layerIdRef.current) &&\n popoverRef.current && modalManager.isTop(popoverRef.current)\n ) {\n event.preventDefault();\n onEsc();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [modalManager, onEsc, show]);\n\n useIsomorphicEffect(() => {\n const popover = popoverRef.current;\n if (!popover) return;\n\n if (correctionsRef.current.resized !== resized) {\n correctionsRef.current = { resized, count: 0, warned: false, log: [] };\n }\n\n const screenWidth = document.documentElement.scrollWidth;\n const screenHeight = document.documentElement.scrollHeight;\n\n const prevWidth = popover.style.width;\n const prevHeight = popover.style.height;\n popover.style.width = '0px';\n popover.style.height = '0px';\n const screenWidthWithout = document.documentElement.scrollWidth;\n const screenHeightWithout = document.documentElement.scrollHeight;\n popover.style.width = prevWidth;\n popover.style.height = prevHeight;\n\n const screenWidthDiff = screenWidth - screenWidthWithout;\n const screenHeightDiff = screenHeight - screenHeightWithout;\n\n const nextPosition = { ...position };\n if (screenWidthDiff > 0) {\n nextPosition.x -= screenWidthDiff;\n }\n if (screenHeightDiff > 0) {\n nextPosition.y -= screenHeightDiff;\n }\n\n nextPosition.x = Math.max(0, nextPosition.x);\n nextPosition.y = Math.max(0, nextPosition.y);\n\n if (position.x !== nextPosition.x || position.y !== nextPosition.y) {\n const corrections = correctionsRef.current;\n\n // Последняя запись — проход, упёршийся в лимит, остальные — применённые коррекции\n if (corrections.log.length <= MAX_POSITION_CORRECTIONS) {\n corrections.log.push({\n from: position,\n to: nextPosition,\n diff: { width: screenWidthDiff, height: screenHeightDiff },\n popover: { width: popover.offsetWidth, height: popover.offsetHeight },\n });\n }\n\n if (corrections.count >= MAX_POSITION_CORRECTIONS) {\n if (!corrections.warned) {\n corrections.warned = true;\n console.warn(\n `DraggablePopover (layer \"${layerIdRef.current}\"): position corrections limit reached, ` +\n 'popover is left outside the screen. If popover size changes together with position, ' +\n 'the consumer makes its size depend on position (e.g. max-height from position.y); ' +\n 'if size and diff stay the same, removing the popover changes the rest of the layout',\n {\n corrections: corrections.log,\n resized,\n screen: {\n scrollWidth: screenWidth,\n scrollHeight: screenHeight,\n scrollWidthWithout: screenWidthWithout,\n scrollHeightWithout: screenHeightWithout,\n clientWidth: document.documentElement.clientWidth,\n clientHeight: document.documentElement.clientHeight,\n },\n viewport: {\n /** Зум браузера и масштаб системы по отдельности не различимы, меняется оба раза */\n devicePixelRatio: window.devicePixelRatio,\n /** Масштаб жестом, на десктопе всегда 1 */\n visualViewportScale: window.visualViewport?.scale,\n /** Больше clientWidth/clientHeight на полосы скроллбаров */\n innerWidth: window.innerWidth,\n innerHeight: window.innerHeight,\n /** Дробный размер вьюпорта: при зуме не совпадает с целым clientWidth/clientHeight */\n visualViewportWidth: window.visualViewport?.width,\n visualViewportHeight: window.visualViewport?.height,\n },\n },\n );\n }\n\n return;\n }\n\n corrections.count += 1;\n onChangePosition(nextPosition);\n }\n }, [position.x, position.y, resized, onChangePosition]);\n\n useEffect(() => {\n const popover = popoverRef.current;\n if (!show || !popover) return undefined;\n\n const handleResize = debounce(() => {\n setResized();\n }, 250);\n\n setResized();\n window.addEventListener('resize', handleResize);\n let resizeObserver: ResizeObserver | undefined;\n if ('ResizeObserver' in window) {\n try {\n resizeObserver = new window.ResizeObserver(handleResize);\n resizeObserver.observe(popover);\n } catch (e) {\n console.warn('Failed to create ResizeObserver for handling element resize', e);\n }\n }\n\n return () => {\n handleResize.cancel();\n window.removeEventListener('resize', handleResize);\n resizeObserver?.disconnect();\n };\n }, [show]);\n\n const paperClassName = classNames(\n transitionGrow(),\n className,\n );\n\n return createPortal(\n <Draggable\n bounds=\"parent\"\n {...draggableProps}\n nodeRef={popoverRef}\n position={position}\n onMouseDown={handleMouseDown}\n onStart={handleDragStart}\n onStop={handleDragStop}\n >\n <DraggableWrap\n ref={popoverRef}\n className={modalClassName}\n style={{ zIndex: `calc(${tokens.zIndex.draggablePopover} + ${zIndex})` }}\n >\n <CSSTransition\n nodeRef={rootRef}\n mountOnEnter={true}\n unmountOnExit={true}\n classNames={transitionClassNames([transitionGrowParent, transitionClassName])}\n timeout={300}\n in={show}\n onExited={onExited}\n >\n <PaperStyled shadow=\"modalDialog\" ref={rootRef} className={paperClassName} tabIndex={0}>\n {children}\n </PaperStyled>\n </CSSTransition>\n </DraggableWrap>\n </Draggable>,\n document.body,\n );\n};\n\nexport default memo(DraggablePopover);\n"],"names":["DEFAULT_OFFSET","MAX_POSITION_CORRECTIONS","DraggablePopover","show","children","onEsc","layerIdProp","className","onChangePosition","onExited","modalManagerProp","draggableProps","_ref","_ref2","positionProp","defaultPosition","onStart","onMouseDown","onStop","modalClassName","useModalState","layerIdRef","useRef","Math","popoverRef","rootRef","zIndex","setZIndex","useState","resized","setResized","useReducer","prev","correctionsRef","positionX","positionY","position","useMemo","correctPosition","modalManager","defaultModalManager","handleMouseDown","useCallback","e","popover","layerId","defaultLayersManager","handleDragStart","data","handleDragStop","useEffect","prevZIndex","handleKeyDown","event","key","KeyboardEventKey","document","useIsomorphicEffect","screenWidth","screenHeight","prevWidth","prevHeight","screenWidthWithout","screenHeightWithout","screenWidthDiff","screenHeightDiff","nextPosition","corrections","_window_visualViewport","_window_visualViewport1","_window_visualViewport2","console","window","handleResize","debounce","resizeObserver","paperClassName","classNames","transitionGrow","createPortal","Draggable","DraggableWrap","tokens","CSSTransition","transitionClassNames","transitionGrowParent","transitionClassName","PaperStyled","memo"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
- import { Ref } from 'react';
2
- import type * as React from 'react';
1
+ import { type ReactNode, type Ref } from 'react';
3
2
  import { TextareaAutosizeProps } from 'react-textarea-autosize';
4
3
  import type { Placement, InputSize, InputVariant } from '../types.js';
5
4
  import { InputProps } from '../Input/index.js';
@@ -8,7 +7,7 @@ export interface Props extends Omit<TextareaAutosizeProps & InheritedInputProps,
8
7
  /** Состояние значения поля ввода */
9
8
  value?: string;
10
9
  /** Текст сообщения подсказки */
11
- message?: React.ReactNode;
10
+ message?: ReactNode;
12
11
  /** Содержимое label поля ввода */
13
12
  label?: string;
14
13
  /** Вариант отображения поля ввода */
@@ -29,7 +28,13 @@ export interface Props extends Omit<TextareaAutosizeProps & InheritedInputProps,
29
28
  inputRef?: Ref<HTMLTextAreaElement>;
30
29
  /** Флаг, управляющий отображением счётчика символов */
31
30
  symbolCounterVisible?: boolean;
31
+ /**
32
+ * Позволяет пользователю менять высоту поля, растягивая его за правый нижний угол.
33
+ * Автоподстройка высоты под содержимое при этом отключается, `minRows` задаёт начальную высоту,
34
+ * `maxRows` не учитывается
35
+ */
36
+ resizable?: boolean;
32
37
  }
33
- declare const TextArea: ({ label, errorText, message, inputRef, onScroll, className, symbolCounterVisible, ...other }: Props) => import("react/jsx-runtime").JSX.Element;
38
+ declare const TextArea: ({ label, errorText, message, inputRef, onScroll, className, symbolCounterVisible, resizable, minRows, maxRows, cacheMeasurements, onHeightChange, ...other }: Props) => import("react/jsx-runtime").JSX.Element;
34
39
  export default TextArea;
35
40
  //# sourceMappingURL=TextArea.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../../src/TextArea/TextArea.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAqD,MAAM,OAAO,CAAC;AAC/E,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAyB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGlF,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACtE,OAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAItD,KAAK,mBAAmB,GAAG,IAAI,CAAC,UAAU,EACxC,kBAAkB,GAClB,YAAY,GACZ,qBAAqB,GACrB,oBAAoB,GACpB,YAAY,GACZ,eAAe,GACf,OAAO,CACR,CAAC;AAEF,MAAM,WAAW,KAAM,SAAQ,IAAI,CAAC,qBAAqB,GAAG,mBAAmB,EAAE,IAAI,CAAC;IACpF,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,wBAAwB;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+CAA+C;IAC/C,oBAAoB,CAAC,EAAE,SAAS,CAAC;IACjC,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACpC,uDAAuD;IACvD,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AASD,QAAA,MAAM,QAAQ,GAAI,8FASf,KAAK,4CA4CP,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../../src/TextArea/TextArea.tsx"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,SAAS,EACd,KAAK,GAAG,EAIT,MAAM,OAAO,CAAC;AACf,OAAyB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAKlF,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACtE,OAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAItD,KAAK,mBAAmB,GAAG,IAAI,CAAC,UAAU,EACxC,kBAAkB,GAClB,YAAY,GACZ,qBAAqB,GACrB,oBAAoB,GACpB,YAAY,GACZ,eAAe,GACf,OAAO,CACR,CAAC;AAEF,MAAM,WAAW,KAAM,SAAQ,IAAI,CAAC,qBAAqB,GAAG,mBAAmB,EAAE,IAAI,CAAC;IACpF,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,wBAAwB;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+CAA+C;IAC/C,oBAAoB,CAAC,EAAE,SAAS,CAAC;IACjC,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACpC,uDAAuD;IACvD,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAqBD,QAAA,MAAM,QAAQ,GAAI,8JAcf,KAAK,4CAyDP,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -2,23 +2,56 @@ import { _ } from "@swc/helpers/_/_object_spread";
2
2
  import { _ as _object_spread_props__ } from "@swc/helpers/_/_object_spread_props";
3
3
  import { _ as _object_without_properties__ } from "@swc/helpers/_/_object_without_properties";
4
4
  import { jsx } from "react/jsx-runtime";
5
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
+ import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
6
6
  import react_textarea_autosize from "react-textarea-autosize";
7
7
  import throttle from "lodash/throttle.js";
8
8
  import clsx from "clsx";
9
+ import { customScroll } from "@finam/web-ui-kit-core/styles/scroll";
10
+ import DragHandleArea from "@finam/web-ui-kit-icons/DragHandle/DragHandleArea";
9
11
  import Input from "../Input/index.js";
10
12
  import { setRef } from "../utils/withForwardedRef.js";
11
- import { inputStyles } from "./TextArea.styles.js";
13
+ import { inputStyles, resizableStyles, resizeHandleStyles } from "./TextArea.styles.js";
12
14
  const InputStyled = Input;
15
+ const AutosizeField = /*#__PURE__*/ forwardRef((_0, _1)=>{
16
+ let _ref = [
17
+ _0,
18
+ _1
19
+ ], [_ref1, ..._rest] = _ref, { className } = _ref1, props = _object_without_properties__(_ref1, [
20
+ "className"
21
+ ]), [ref] = _rest;
22
+ return /*#__PURE__*/ jsx(react_textarea_autosize, _object_spread_props__(_({}, props), {
23
+ ref: ref,
24
+ className: clsx(className, customScroll())
25
+ }));
26
+ });
27
+ AutosizeField.displayName = 'AutosizeField';
28
+ const ResizableField = /*#__PURE__*/ forwardRef((_0, _1)=>{
29
+ let _ref = [
30
+ _0,
31
+ _1
32
+ ], [_ref1, ..._rest] = _ref, { className } = _ref1, props = _object_without_properties__(_ref1, [
33
+ "className"
34
+ ]), [ref] = _rest;
35
+ return /*#__PURE__*/ jsx("textarea", _object_spread_props__(_({}, props), {
36
+ ref: ref,
37
+ className: clsx(className, customScroll())
38
+ }));
39
+ });
40
+ ResizableField.displayName = 'ResizableField';
13
41
  const TextArea = (_0)=>{
14
- let { label, errorText, message, inputRef, onScroll, className, symbolCounterVisible } = _0, other = _object_without_properties__(_0, [
42
+ let { label, errorText, message, inputRef, onScroll, className, symbolCounterVisible, resizable = false, minRows, maxRows, cacheMeasurements, onHeightChange } = _0, other = _object_without_properties__(_0, [
15
43
  "label",
16
44
  "errorText",
17
45
  "message",
18
46
  "inputRef",
19
47
  "onScroll",
20
48
  "className",
21
- "symbolCounterVisible"
49
+ "symbolCounterVisible",
50
+ "resizable",
51
+ "minRows",
52
+ "maxRows",
53
+ "cacheMeasurements",
54
+ "onHeightChange"
22
55
  ]);
23
56
  const textareaRef = useRef(null);
24
57
  const [showLabel, setShowLabel] = useState(true);
@@ -43,15 +76,31 @@ const TextArea = (_0)=>{
43
76
  onScroll,
44
77
  updateState
45
78
  ]);
46
- return /*#__PURE__*/ jsx(InputStyled, _object_spread_props__(_({
47
- as: react_textarea_autosize,
79
+ const autosizeProps = resizable ? {
80
+ rows: minRows
81
+ } : {
82
+ minRows,
83
+ maxRows,
84
+ cacheMeasurements,
85
+ onHeightChange
86
+ };
87
+ return /*#__PURE__*/ jsx(InputStyled, _object_spread_props__(_(_object_spread_props__(_({
88
+ as: resizable ? ResizableField : AutosizeField
89
+ }, autosizeProps), {
48
90
  label: showLabel ? label : void 0,
49
91
  message: errorText || message,
50
92
  error: Boolean(errorText),
51
93
  errorIcon: !!errorText,
52
- symbolCounterVisible: symbolCounterVisible
53
- }, other), {
54
- className: clsx(inputStyles, className),
94
+ symbolCounterVisible: symbolCounterVisible,
95
+ adornment: resizable && !other.disabled ? /*#__PURE__*/ jsx("div", {
96
+ className: clsx(resizeHandleStyles, 'ui-textarea__resize-handle'),
97
+ "aria-hidden": true,
98
+ children: /*#__PURE__*/ jsx(DragHandleArea, {
99
+ color: "tertiary"
100
+ })
101
+ }) : void 0
102
+ }), other), {
103
+ className: clsx(inputStyles, resizable && resizableStyles, className),
55
104
  ref: handleRef,
56
105
  onScroll: handleScroll
57
106
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"TextArea/TextArea.js","sources":["../../src/TextArea/TextArea.tsx"],"sourcesContent":["import { Ref, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type * as React from 'react';\nimport TextareaAutosize, { TextareaAutosizeProps } from 'react-textarea-autosize';\nimport throttle from 'lodash/throttle.js';\nimport classnames from 'clsx';\nimport type { Placement, InputSize, InputVariant } from '../types.js';\nimport Input, { InputProps } from '../Input/index.js';\nimport { setRef } from '../utils/withForwardedRef.js';\nimport { inputStyles } from './TextArea.styles.js';\n\ntype InheritedInputProps = Pick<InputProps,\n| 'hideReadOnlyIcon'\n| 'singleLine'\n| 'hintTooltipMaxWidth'\n| 'hintTooltipVariant'\n| 'alignRight'\n| 'hideEmptyHint'\n| 'error'\n>;\n\nexport interface Props extends Omit<TextareaAutosizeProps & InheritedInputProps, 'as'> {\n /** Состояние значения поля ввода */\n value?: string;\n /** Текст сообщения подсказки */\n message?: React.ReactNode;\n /** Содержимое label поля ввода */\n label?: string;\n /** Вариант отображения поля ввода */\n variant?: InputVariant;\n /** Размер поля ввода */\n size?: InputSize;\n /** Растяжение компонента по ширине контейнера */\n fullWidth?: boolean;\n /** Сообщение об ошибке для подсказки */\n errorText?: string;\n /** Флаг отображения подсказки в виде всплывающего окна */\n hintTooltip?: boolean;\n /** Расположение всплывающего окна подсказки */\n hintTooltipPlacement?: Placement;\n /** Текст дополнительной подписи */\n secondaryLabel?: string;\n /** ref-ссылка на элемент textarea */\n inputRef?: Ref<HTMLTextAreaElement>;\n /** Флаг, управляющий отображением счётчика символов */\n symbolCounterVisible?: boolean;\n}\n\ntype InputStyledProps =\n Omit<InputProps, keyof React.HTMLAttributes<HTMLInputElement>> &\n React.TextareaHTMLAttributes<HTMLTextAreaElement> &\n React.RefAttributes<HTMLTextAreaElement>;\n\nconst InputStyled = Input as React.ComponentType<InputStyledProps>;\n\nconst TextArea = ({\n label,\n errorText,\n message,\n inputRef,\n onScroll,\n className,\n symbolCounterVisible,\n ...other\n}: Props) => {\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const [showLabel, setShowLabel] = useState(true);\n\n const updateState = useMemo(() => (\n throttle(() => {\n if (textareaRef.current) {\n setShowLabel(textareaRef.current.scrollTop <= 1);\n }\n }, 100)\n ), []);\n\n useEffect(() => () => {\n updateState.cancel();\n }, [updateState]);\n\n const handleRef = useCallback((node: HTMLTextAreaElement | null) => {\n if (inputRef) {\n setRef(inputRef, node);\n }\n textareaRef.current = node;\n }, [inputRef]);\n\n const handleScroll = useCallback((event: React.UIEvent<HTMLTextAreaElement>) => {\n if (onScroll) {\n onScroll(event);\n }\n updateState();\n }, [onScroll, updateState]);\n\n return (\n <InputStyled\n as={TextareaAutosize}\n label={showLabel ? label : undefined}\n message={errorText || message}\n error={Boolean(errorText)}\n errorIcon={!!errorText}\n symbolCounterVisible={symbolCounterVisible}\n {...other}\n className={classnames(inputStyles, className)}\n ref={handleRef}\n onScroll={handleScroll}\n />\n );\n};\n\nexport default TextArea;\n"],"names":["InputStyled","Input","TextArea","label","errorText","message","inputRef","onScroll","className","symbolCounterVisible","other","textareaRef","useRef","showLabel","setShowLabel","useState","updateState","useMemo","throttle","useEffect","handleRef","useCallback","node","setRef","handleScroll","event","TextareaAutosize","undefined","Boolean","classnames","inputStyles"],"mappings":";;;;;;;;;;;AAoDA,MAAMA,cAAcC;AAEpB,MAAMC,WAAW,CAAC;QAAA,EAChBC,KAAK,EACLC,SAAS,EACTC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,SAAS,EACTC,oBAAoB,EAEd,OADHC,QAAAA,6BAAAA,IAAAA;;;;;;;;;IAEH,MAAMC,cAAcC,OAAmC;IACvD,MAAM,CAACC,WAAWC,aAAa,GAAGC,SAAS;IAE3C,MAAMC,cAAcC,QAAQ,IAC1BC,SAAS;YACP,IAAIP,YAAY,OAAO,EACrBG,aAAaH,YAAY,OAAO,CAAC,SAAS,IAAI;QAElD,GAAG,MACF,EAAE;IAELQ,UAAU,IAAM;YACdH,YAAY,MAAM;QACpB,GAAG;QAACA;KAAY;IAEhB,MAAMI,YAAYC,YAAY,CAACC;QAC7B,IAAIhB,UACFiB,OAAOjB,UAAUgB;QAEnBX,YAAY,OAAO,GAAGW;IACxB,GAAG;QAAChB;KAAS;IAEb,MAAMkB,eAAeH,YAAY,CAACI;QAChC,IAAIlB,UACFA,SAASkB;QAEXT;IACF,GAAG;QAACT;QAAUS;KAAY;IAE1B,OAAO,WAAP,GACE,IAAChB,aAAAA,uBAAAA,EAAAA;QACC,IAAI0B;QACJ,OAAOb,YAAYV,QAAQwB;QAC3B,SAASvB,aAAaC;QACtB,OAAOuB,QAAQxB;QACf,WAAW,CAAC,CAACA;QACb,sBAAsBK;OAClBC,QAAAA;QACJ,WAAWmB,KAAWC,aAAatB;QACnC,KAAKY;QACL,UAAUI;;AAGhB;AAEA,0BAAetB"}
1
+ {"version":3,"file":"TextArea/TextArea.js","sources":["../../src/TextArea/TextArea.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentType,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n type RefAttributes,\n type TextareaHTMLAttributes,\n type UIEvent,\n} from 'react';\nimport TextareaAutosize, { TextareaAutosizeProps } from 'react-textarea-autosize';\nimport throttle from 'lodash/throttle.js';\nimport classnames from 'clsx';\nimport { customScroll } from '@finam/web-ui-kit-core/styles/scroll';\nimport DragHandleArea from '@finam/web-ui-kit-icons/DragHandle/DragHandleArea';\nimport type { Placement, InputSize, InputVariant } from '../types.js';\nimport Input, { InputProps } from '../Input/index.js';\nimport { setRef } from '../utils/withForwardedRef.js';\nimport { inputStyles, resizableStyles, resizeHandleStyles } from './TextArea.styles.js';\n\ntype InheritedInputProps = Pick<InputProps,\n| 'hideReadOnlyIcon'\n| 'singleLine'\n| 'hintTooltipMaxWidth'\n| 'hintTooltipVariant'\n| 'alignRight'\n| 'hideEmptyHint'\n| 'error'\n>;\n\nexport interface Props extends Omit<TextareaAutosizeProps & InheritedInputProps, 'as'> {\n /** Состояние значения поля ввода */\n value?: string;\n /** Текст сообщения подсказки */\n message?: ReactNode;\n /** Содержимое label поля ввода */\n label?: string;\n /** Вариант отображения поля ввода */\n variant?: InputVariant;\n /** Размер поля ввода */\n size?: InputSize;\n /** Растяжение компонента по ширине контейнера */\n fullWidth?: boolean;\n /** Сообщение об ошибке для подсказки */\n errorText?: string;\n /** Флаг отображения подсказки в виде всплывающего окна */\n hintTooltip?: boolean;\n /** Расположение всплывающего окна подсказки */\n hintTooltipPlacement?: Placement;\n /** Текст дополнительной подписи */\n secondaryLabel?: string;\n /** ref-ссылка на элемент textarea */\n inputRef?: Ref<HTMLTextAreaElement>;\n /** Флаг, управляющий отображением счётчика символов */\n symbolCounterVisible?: boolean;\n /**\n * Позволяет пользователю менять высоту поля, растягивая его за правый нижний угол.\n * Автоподстройка высоты под содержимое при этом отключается, `minRows` задаёт начальную высоту,\n * `maxRows` не учитывается\n */\n resizable?: boolean;\n}\n\ntype InputStyledProps =\n Omit<InputProps, keyof HTMLAttributes<HTMLInputElement>> &\n TextareaHTMLAttributes<HTMLTextAreaElement> &\n RefAttributes<HTMLTextAreaElement>;\n\nconst InputStyled = Input as ComponentType<InputStyledProps>;\n\nconst AutosizeField = forwardRef<HTMLTextAreaElement, TextareaAutosizeProps>(({ className, ...props }, ref) => (\n <TextareaAutosize {...props} ref={ref} className={classnames(className, customScroll())} />\n));\nAutosizeField.displayName = 'AutosizeField';\n\nconst ResizableField = forwardRef<HTMLTextAreaElement, TextareaHTMLAttributes<HTMLTextAreaElement>>(\n ({ className, ...props }, ref) => (\n <textarea {...props} ref={ref} className={classnames(className, customScroll())} />\n ),\n);\nResizableField.displayName = 'ResizableField';\n\nconst TextArea = ({\n label,\n errorText,\n message,\n inputRef,\n onScroll,\n className,\n symbolCounterVisible,\n resizable = false,\n minRows,\n maxRows,\n cacheMeasurements,\n onHeightChange,\n ...other\n}: Props) => {\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const [showLabel, setShowLabel] = useState(true);\n\n const updateState = useMemo(() => (\n throttle(() => {\n if (textareaRef.current) {\n setShowLabel(textareaRef.current.scrollTop <= 1);\n }\n }, 100)\n ), []);\n\n useEffect(() => () => {\n updateState.cancel();\n }, [updateState]);\n\n const handleRef = useCallback((node: HTMLTextAreaElement | null) => {\n if (inputRef) {\n setRef(inputRef, node);\n }\n textareaRef.current = node;\n }, [inputRef]);\n\n const handleScroll = useCallback((event: UIEvent<HTMLTextAreaElement>) => {\n if (onScroll) {\n onScroll(event);\n }\n updateState();\n }, [onScroll, updateState]);\n\n const autosizeProps = resizable ? { rows: minRows } : {\n minRows,\n maxRows,\n cacheMeasurements,\n onHeightChange,\n };\n\n return (\n <InputStyled\n as={resizable ? ResizableField : AutosizeField}\n {...autosizeProps}\n label={showLabel ? label : undefined}\n message={errorText || message}\n error={Boolean(errorText)}\n errorIcon={!!errorText}\n symbolCounterVisible={symbolCounterVisible}\n adornment={resizable && !other.disabled ? (\n <div className={classnames(resizeHandleStyles, 'ui-textarea__resize-handle')} aria-hidden>\n <DragHandleArea color=\"tertiary\" />\n </div>\n ) : undefined}\n {...other}\n className={classnames(inputStyles, resizable && resizableStyles, className)}\n ref={handleRef}\n onScroll={handleScroll}\n />\n );\n};\n\nexport default TextArea;\n"],"names":["InputStyled","Input","AutosizeField","forwardRef","className","props","ref","TextareaAutosize","classnames","customScroll","ResizableField","TextArea","label","errorText","message","inputRef","onScroll","symbolCounterVisible","resizable","minRows","maxRows","cacheMeasurements","onHeightChange","other","textareaRef","useRef","showLabel","setShowLabel","useState","updateState","useMemo","throttle","useEffect","handleRef","useCallback","node","setRef","handleScroll","event","autosizeProps","undefined","Boolean","resizeHandleStyles","DragHandleArea","inputStyles","resizableStyles"],"mappings":";;;;;;;;;;;;;AAyEA,MAAMA,cAAcC;AAEpB,MAAMC,gBAAgB,WAAHA,GAAGC,WAAuD,CAAC,IAAD;;;;iCAAC,EAAEC,SAAS,EAAY,UAAPC,QAAAA,6BAAAA,OAAAA;;SAASC,IAAAA,GAAAA;yBACrG,IAACC,yBAAgBA,uBAAAA,EAAAA,CAAAA,GAAKF,QAAAA;QAAO,KAAKC;QAAK,WAAWE,KAAWJ,WAAWK;;;AAE1EP,cAAc,WAAW,GAAG;AAE5B,MAAMQ,iBAAiB,WAAHA,GAAGP,WACrB,CAAC,IAAD;;;;iCAAC,EAAEC,SAAS,EAAY,UAAPC,QAAAA,6BAAAA,OAAAA;;SAASC,IAAAA,GAAAA;yBACxB,IAAC,yCAAaD,QAAAA;QAAO,KAAKC;QAAK,WAAWE,KAAWJ,WAAWK;;;AAGpEC,eAAe,WAAW,GAAG;AAE7B,MAAMC,WAAW,CAAC;QAAA,EAChBC,KAAK,EACLC,SAAS,EACTC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRZ,SAAS,EACTa,oBAAoB,EACpBC,YAAY,KAAK,EACjBC,OAAO,EACPC,OAAO,EACPC,iBAAiB,EACjBC,cAAc,EAER,OADHC,QAAAA,6BAAAA,IAAAA;;;;;;;;;;;;;;IAEH,MAAMC,cAAcC,OAAmC;IACvD,MAAM,CAACC,WAAWC,aAAa,GAAGC,SAAS;IAE3C,MAAMC,cAAcC,QAAQ,IAC1BC,SAAS;YACP,IAAIP,YAAY,OAAO,EACrBG,aAAaH,YAAY,OAAO,CAAC,SAAS,IAAI;QAElD,GAAG,MACF,EAAE;IAELQ,UAAU,IAAM;YACdH,YAAY,MAAM;QACpB,GAAG;QAACA;KAAY;IAEhB,MAAMI,YAAYC,YAAY,CAACC;QAC7B,IAAIpB,UACFqB,OAAOrB,UAAUoB;QAEnBX,YAAY,OAAO,GAAGW;IACxB,GAAG;QAACpB;KAAS;IAEb,MAAMsB,eAAeH,YAAY,CAACI;QAChC,IAAItB,UACFA,SAASsB;QAEXT;IACF,GAAG;QAACb;QAAUa;KAAY;IAE1B,MAAMU,gBAAgBrB,YAAY;QAAE,MAAMC;IAAQ,IAAI;QACpDA;QACAC;QACAC;QACAC;IACF;IAEA,OAAO,WAAP,GACE,IAACtB,aAAAA,uBAAAA,EAAAA,uBAAAA,EAAAA;QACC,IAAIkB,YAAYR,iBAAiBR;OAC7BqC,gBAAAA;QACJ,OAAOb,YAAYd,QAAQ4B;QAC3B,SAAS3B,aAAaC;QACtB,OAAO2B,QAAQ5B;QACf,WAAW,CAAC,CAACA;QACb,sBAAsBI;QACtB,WAAWC,aAAa,CAACK,MAAM,QAAQ,GAAG,WAAH,GACrC,IAAC;YAAI,WAAWf,KAAWkC,oBAAoB;YAA+B,eAAW;sBACvF,kBAACC,gBAAcA;gBAAC,OAAM;;aAEtBH;QACAjB,QAAAA;QACJ,WAAWf,KAAWoC,aAAa1B,aAAa2B,iBAAiBzC;QACjE,KAAK6B;QACL,UAAUI;;AAGhB;AAEA,0BAAe1B"}
@@ -1 +1,3 @@
1
1
  .ui_components_i12kkm66 textarea{display:block;resize:none;}.ui_components_i12kkm66 .ui-input__adornment{align-self:flex-start;margin-top:var(--ui-spacing-inputM-paddingVert);}
2
+ .ui_components_rtjawjx textarea{resize:vertical;}.ui_components_rtjawjx textarea:disabled{resize:none;}.ui_components_rtjawjx textarea::-webkit-scrollbar{width:20px;height:20px;}.ui_components_rtjawjx textarea::-webkit-scrollbar-thumb{border-width:7px;}.ui_components_rtjawjx textarea::-webkit-resizer,.ui_components_rtjawjx textarea::-webkit-scrollbar-corner{background:transparent;}
3
+ .ui_components_r1ghzquy{position:absolute;right:var(--ui-spacing-xs);bottom:var(--ui-spacing-xs);display:flex;pointer-events:none;}.ui_components_r1ghzquy>svg{width:15px;height:15px;}
@@ -1,2 +1,4 @@
1
1
  export declare const inputStyles: import("@linaria/core").LinariaClassName;
2
+ export declare const resizableStyles: import("@linaria/core").LinariaClassName;
3
+ export declare const resizeHandleStyles: import("@linaria/core").LinariaClassName;
2
4
  //# sourceMappingURL=TextArea.styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextArea.styles.d.ts","sourceRoot":"","sources":["../../src/TextArea/TextArea.styles.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,0CAUvB,CAAC"}
1
+ {"version":3,"file":"TextArea.styles.d.ts","sourceRoot":"","sources":["../../src/TextArea/TextArea.styles.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,0CAUvB,CAAC;AAEF,eAAO,MAAM,eAAe,0CAsB3B,CAAC;AAEF,eAAO,MAAM,kBAAkB,0CAW9B,CAAC"}
@@ -1,5 +1,7 @@
1
1
  const inputStyles = "ui_components_i12kkm66";
2
- export { inputStyles };
2
+ const resizableStyles = "ui_components_rtjawjx";
3
+ const resizeHandleStyles = "ui_components_r1ghzquy";
4
+ export { inputStyles, resizableStyles, resizeHandleStyles };
3
5
  //# sourceMappingURL=TextArea.styles.js.map
4
6
 
5
7
  import "./TextArea.styles.css";
@@ -1 +1 @@
1
- {"version":3,"file":"TextArea/TextArea.styles.js","sources":["../../src/TextArea/TextArea.styles.ts"],"sourcesContent":["import { tokens } from '@finam/web-ui-kit-core/theme/contract';\nimport { css } from '@linaria/core';\n\nexport const inputStyles = css`\n & textarea {\n display: block;\n resize: none;\n }\n\n & .ui-input__adornment {\n align-self: flex-start;\n margin-top: ${tokens.spacing.inputM.paddingVert};\n }\n`;\n"],"names":["inputStyles","css","tokens"],"mappings":";;AAGO,MAAMA,cAAcC,GAAG,CAAC;;;;;;;;gBAQf,EAAEC,OAAO,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC;;AAEpD,CAAC"}
1
+ {"version":3,"file":"TextArea/TextArea.styles.js","sources":["../../src/TextArea/TextArea.styles.ts"],"sourcesContent":["import { tokens } from '@finam/web-ui-kit-core/theme/contract';\nimport { css } from '@linaria/core';\n\nexport const inputStyles = css`\n & textarea {\n display: block;\n resize: none;\n }\n\n & .ui-input__adornment {\n align-self: flex-start;\n margin-top: ${tokens.spacing.inputM.paddingVert};\n }\n`;\n\nexport const resizableStyles = css`\n & textarea {\n resize: vertical;\n }\n\n & textarea:disabled {\n resize: none;\n }\n\n & textarea::-webkit-scrollbar {\n width: 20px;\n height: 20px;\n }\n\n & textarea::-webkit-scrollbar-thumb {\n border-width: 7px;\n }\n\n & textarea::-webkit-resizer,\n & textarea::-webkit-scrollbar-corner {\n background: transparent;\n }\n`;\n\nexport const resizeHandleStyles = css`\n position: absolute;\n right: ${tokens.spacing.xs};\n bottom: ${tokens.spacing.xs};\n display: flex;\n pointer-events: none;\n\n & > svg {\n width: 15px;\n height: 15px;\n }\n`;\n"],"names":["inputStyles","css","tokens","resizableStyles","resizeHandleStyles"],"mappings":";;AAGO,MAAMA,cAAcC,GAAG,CAAC;;;;;;;;gBAQf,EAAEC,OAAO,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC;;AAEpD,CAAC;AAEM,MAAMC,kBAAkBF,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;AAsBnC,CAAC;AAEM,MAAMG,qBAAqBH,GAAG,CAAC;;SAE7B,EAAEC,OAAO,OAAO,CAAC,EAAE,CAAC;UACnB,EAAEA,OAAO,OAAO,CAAC,EAAE,CAAC;;;;;;;;AAQ9B,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from "./types.js";
2
- const version = "3.33.3";
2
+ const version = "3.34.1";
3
3
  export { default as Button } from "./Button/index.js";
4
4
  export { default as ButtonAsync } from "./ButtonAsync/index.js";
5
5
  export { default as MarketingButton } from "./MarketingButton/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finam/web-ui-kit-components",
3
- "version": "3.33.3",
3
+ "version": "3.34.1",
4
4
  "description": "Components library for web-ui-kit",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "scripts": {
55
55
  "clean": "rimraf dist tsconfig.tsbuildinfo",
56
- "build:lib": "npm run clean && npm run lint:es && npm run lint:styles && npm run compile:es && npm run compile:styles:es",
56
+ "build:lib": "npm run clean && npm run compile:es && npm run compile:styles:es",
57
57
  "compile:es": "rslib build -c ../../rslib.config.ts",
58
58
  "compile:styles:es": "wyw-in-js -o dist -m es2015 -t true --source-root dist --insert-css-requires dist \"dist/**/*.js\"",
59
59
  "lint:es": "eslint .",