@vkontakte/vkui 6.5.2 → 6.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/cjs/components/CustomSelect/CustomSelect.d.ts +12 -2
  2. package/dist/cjs/components/CustomSelect/CustomSelect.d.ts.map +1 -1
  3. package/dist/cjs/components/CustomSelect/CustomSelect.js +68 -43
  4. package/dist/cjs/components/CustomSelect/CustomSelect.js.map +1 -1
  5. package/dist/cjs/components/CustomSelect/CustomSelectInput.d.ts +1 -3
  6. package/dist/cjs/components/CustomSelect/CustomSelectInput.d.ts.map +1 -1
  7. package/dist/cjs/components/CustomSelect/CustomSelectInput.js +24 -19
  8. package/dist/cjs/components/CustomSelect/CustomSelectInput.js.map +1 -1
  9. package/dist/cjs/components/ImageBase/ImageBase.js +4 -1
  10. package/dist/cjs/components/ImageBase/ImageBase.js.map +1 -1
  11. package/dist/components/CustomSelect/CustomSelect.d.ts +12 -2
  12. package/dist/components/CustomSelect/CustomSelect.d.ts.map +1 -1
  13. package/dist/components/CustomSelect/CustomSelect.js +60 -35
  14. package/dist/components/CustomSelect/CustomSelect.js.map +1 -1
  15. package/dist/components/CustomSelect/CustomSelectInput.d.ts +1 -3
  16. package/dist/components/CustomSelect/CustomSelectInput.d.ts.map +1 -1
  17. package/dist/components/CustomSelect/CustomSelectInput.js +24 -19
  18. package/dist/components/CustomSelect/CustomSelectInput.js.map +1 -1
  19. package/dist/components/ImageBase/ImageBase.js +4 -1
  20. package/dist/components/ImageBase/ImageBase.js.map +1 -1
  21. package/dist/components.css +2 -2
  22. package/dist/components.css.map +1 -1
  23. package/dist/components.js.tmp +100 -148
  24. package/dist/cssm/components/CustomSelect/CustomSelect.d.ts +12 -2
  25. package/dist/cssm/components/CustomSelect/CustomSelect.d.ts.map +1 -1
  26. package/dist/cssm/components/CustomSelect/CustomSelect.js +57 -34
  27. package/dist/cssm/components/CustomSelect/CustomSelect.js.map +1 -1
  28. package/dist/cssm/components/CustomSelect/CustomSelectInput.d.ts +1 -3
  29. package/dist/cssm/components/CustomSelect/CustomSelectInput.d.ts.map +1 -1
  30. package/dist/cssm/components/CustomSelect/CustomSelectInput.js +21 -16
  31. package/dist/cssm/components/CustomSelect/CustomSelectInput.js.map +1 -1
  32. package/dist/cssm/components/CustomSelect/CustomSelectInput.module.css +40 -74
  33. package/dist/cssm/components/ImageBase/ImageBase.js +4 -1
  34. package/dist/cssm/components/ImageBase/ImageBase.js.map +1 -1
  35. package/dist/cssm/components/ImageBase/ImageBase.module.css +13 -2
  36. package/dist/vkui.css +2 -2
  37. package/dist/vkui.css.map +1 -1
  38. package/dist/vkui.js.tmp +100 -148
  39. package/package.json +1 -1
  40. package/src/components/CustomSelect/CustomSelect.tsx +98 -47
  41. package/src/components/CustomSelect/CustomSelectInput.module.css +35 -55
  42. package/src/components/CustomSelect/CustomSelectInput.tsx +35 -24
  43. package/src/components/ImageBase/ImageBase.module.css +13 -2
  44. package/src/components/ImageBase/ImageBase.tsx +1 -1
  45. package/dist/cjs/components/CustomSelect/helpers.d.ts +0 -8
  46. package/dist/cjs/components/CustomSelect/helpers.d.ts.map +0 -1
  47. package/dist/cjs/components/CustomSelect/helpers.js +0 -76
  48. package/dist/cjs/components/CustomSelect/helpers.js.map +0 -1
  49. package/dist/cjs/components/CustomSelect/types.d.ts +0 -12
  50. package/dist/cjs/components/CustomSelect/types.d.ts.map +0 -1
  51. package/dist/cjs/components/CustomSelect/types.js +0 -6
  52. package/dist/cjs/components/CustomSelect/types.js.map +0 -1
  53. package/dist/components/CustomSelect/helpers.d.ts +0 -8
  54. package/dist/components/CustomSelect/helpers.d.ts.map +0 -1
  55. package/dist/components/CustomSelect/helpers.js +0 -48
  56. package/dist/components/CustomSelect/helpers.js.map +0 -1
  57. package/dist/components/CustomSelect/types.d.ts +0 -12
  58. package/dist/components/CustomSelect/types.d.ts.map +0 -1
  59. package/dist/components/CustomSelect/types.js +0 -3
  60. package/dist/components/CustomSelect/types.js.map +0 -1
  61. package/dist/cssm/components/CustomSelect/helpers.d.ts +0 -8
  62. package/dist/cssm/components/CustomSelect/helpers.d.ts.map +0 -1
  63. package/dist/cssm/components/CustomSelect/helpers.js +0 -44
  64. package/dist/cssm/components/CustomSelect/helpers.js.map +0 -1
  65. package/dist/cssm/components/CustomSelect/types.d.ts +0 -12
  66. package/dist/cssm/components/CustomSelect/types.d.ts.map +0 -1
  67. package/dist/cssm/components/CustomSelect/types.js +0 -3
  68. package/dist/cssm/components/CustomSelect/types.js.map +0 -1
  69. package/src/components/CustomSelect/helpers.tsx +0 -61
  70. package/src/components/CustomSelect/types.ts +0 -15
@@ -17,17 +17,19 @@ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
17
17
  const _vkjs = require("@vkontakte/vkjs");
18
18
  const _useAdaptivity = require("../../hooks/useAdaptivity");
19
19
  const _useExternRef = require("../../hooks/useExternRef");
20
+ const _useFocusWithin = require("../../hooks/useFocusWithin");
20
21
  const _usePlatform = require("../../hooks/usePlatform");
21
22
  const _select = require("../../lib/select");
22
23
  const _FormField = require("../FormField/FormField");
23
24
  const _SelectTypography = require("../SelectTypography/SelectTypography");
25
+ const _Text = require("../Typography/Text/Text");
24
26
  const _VisuallyHidden = require("../VisuallyHidden/VisuallyHidden");
25
27
  const sizeYClassNames = {
26
28
  none: "vkuiCustomSelectInput--sizeY-none",
27
29
  compact: "vkuiCustomSelectInput--sizeY-compact"
28
30
  };
29
31
  const CustomSelectInput = (_param)=>{
30
- var { align = 'left', getRef, className, getRootRef, style, before, after, status, selectedOptionLabel, selectType = 'default', multiline, disabled, fetching, labelTextTestId, searchable } = _param, restInputProps = _object_without_properties._(_param, [
32
+ var { align = 'left', getRef, className, getRootRef, style, before, after, status, children, placeholder, selectType = 'default', multiline, disabled, fetching, labelTextTestId } = _param, restProps = _object_without_properties._(_param, [
31
33
  "align",
32
34
  "getRef",
33
35
  "className",
@@ -36,32 +38,35 @@ const CustomSelectInput = (_param)=>{
36
38
  "before",
37
39
  "after",
38
40
  "status",
39
- "selectedOptionLabel",
41
+ "children",
42
+ "placeholder",
40
43
  "selectType",
41
44
  "multiline",
42
45
  "disabled",
43
46
  "fetching",
44
- "labelTextTestId",
45
- "searchable"
47
+ "labelTextTestId"
46
48
  ]);
47
49
  const { sizeY = 'none' } = (0, _useAdaptivity.useAdaptivity)();
50
+ const title = children || placeholder;
51
+ const showLabelOrPlaceholder = !Boolean(restProps.value);
48
52
  const handleRootRef = (0, _useExternRef.useExternRef)(getRootRef);
49
- const platform = (0, _usePlatform.usePlatform)();
50
- const input = /*#__PURE__*/ (0, _jsxruntime.jsx)(_SelectTypography.SelectTypography, _object_spread_props._(_object_spread._({
51
- selectType: selectType,
53
+ const focusWithin = (0, _useFocusWithin.useFocusWithin)(handleRootRef);
54
+ const input = /*#__PURE__*/ (0, _jsxruntime.jsx)(_Text.Text, _object_spread_props._(_object_spread._({
52
55
  type: "text"
53
- }, restInputProps), {
56
+ }, restProps), {
54
57
  disabled: disabled && !fetching,
55
- readOnly: restInputProps.readOnly || !searchable || disabled && fetching,
58
+ readOnly: restProps.readOnly || disabled && fetching,
56
59
  Component: "input",
57
60
  normalize: false,
58
- className: "vkuiCustomSelectInput__input",
59
- getRootRef: getRef
61
+ className: (0, _vkjs.classNames)("vkuiCustomSelectInput__el", (restProps.readOnly || showLabelOrPlaceholder && !focusWithin) && "vkuiCustomSelectInput__el--cursor-pointer"),
62
+ getRootRef: getRef,
63
+ placeholder: children ? '' : placeholder
60
64
  }));
65
+ const platform = (0, _usePlatform.usePlatform)();
61
66
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_FormField.FormField, {
62
67
  Component: "div",
63
68
  style: style,
64
- className: (0, _vkjs.classNames)("vkuiCustomSelectInput", align === 'right' && "vkuiCustomSelectInput--align-right", align === 'center' && "vkuiCustomSelectInput--align-center", !selectedOptionLabel && "vkuiCustomSelectInput--empty", multiline && "vkuiCustomSelectInput--multiline", sizeY !== 'regular' && sizeYClassNames[sizeY], before && "vkuiCustomSelectInput--hasBefore", after && "vkuiCustomSelectInput--hasAfter", className),
69
+ className: (0, _vkjs.classNames)("vkuiCustomSelectInput", align === 'right' && "vkuiCustomSelectInput--align-right", align === 'center' && "vkuiCustomSelectInput--align-center", !children && "vkuiCustomSelectInput--empty", multiline && "vkuiCustomSelectInput--multiline", sizeY !== 'regular' && sizeYClassNames[sizeY], before && "vkuiCustomSelectInput--hasBefore", after && "vkuiCustomSelectInput--hasAfter", className),
65
70
  getRootRef: handleRootRef,
66
71
  before: before,
67
72
  after: after,
@@ -71,20 +76,20 @@ const CustomSelectInput = (_param)=>{
71
76
  children: /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
72
77
  className: "vkuiCustomSelectInput__input-group",
73
78
  children: [
74
- !searchable && platform === 'ios' ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_VisuallyHidden.VisuallyHidden, {
75
- children: input
76
- }) : input,
77
79
  /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
78
- className: (0, _vkjs.classNames)("vkuiCustomSelectInput__label-wrapper", className),
80
+ className: (0, _vkjs.classNames)("vkuiCustomSelectInput__container", className),
79
81
  tabIndex: -1,
80
82
  "aria-hidden": true,
81
83
  "data-testid": labelTextTestId,
82
84
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_SelectTypography.SelectTypography, {
83
85
  selectType: selectType,
84
- className: "vkuiCustomSelectInput__label",
85
- children: selectedOptionLabel || restInputProps.placeholder
86
+ className: "vkuiCustomSelectInput__title",
87
+ children: showLabelOrPlaceholder && title
86
88
  })
87
- })
89
+ }),
90
+ restProps.readOnly && platform === 'ios' ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_VisuallyHidden.VisuallyHidden, {
91
+ children: input
92
+ }) : input
88
93
  ]
89
94
  })
90
95
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/CustomSelect/CustomSelectInput.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { getFormFieldModeFromSelectType } from '../../lib/select';\nimport { HasAlign, HasRef, HasRootRef } from '../../types';\nimport { FormField, FormFieldProps } from '../FormField/FormField';\nimport type { SelectType } from '../Select/Select';\nimport { SelectTypography } from '../SelectTypography/SelectTypography';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './CustomSelectInput.module.css';\n\nconst sizeYClassNames = {\n none: styles['CustomSelectInput--sizeY-none'],\n compact: styles['CustomSelectInput--sizeY-compact'],\n};\n\nexport interface CustomSelectInputProps\n extends React.InputHTMLAttributes<HTMLInputElement>,\n HasRef<HTMLInputElement>,\n HasRootRef<HTMLDivElement>,\n HasAlign,\n Omit<FormFieldProps, 'mode' | 'type' | 'maxHeight'> {\n selectType?: SelectType;\n multiline?: boolean;\n labelTextTestId?: string;\n fetching?: boolean;\n searchable?: boolean;\n selectedOptionLabel?: React.ReactElement | string;\n}\n\n/**\n * @since 5.10.0\n * @private\n */\nexport const CustomSelectInput = ({\n align = 'left',\n getRef,\n className,\n getRootRef,\n style,\n before,\n after,\n status,\n selectedOptionLabel,\n selectType = 'default',\n multiline,\n disabled,\n fetching,\n labelTextTestId,\n searchable,\n ...restInputProps\n}: CustomSelectInputProps): React.ReactNode => {\n const { sizeY = 'none' } = useAdaptivity();\n\n const handleRootRef = useExternRef(getRootRef);\n\n const platform = usePlatform();\n\n const input = (\n <SelectTypography\n selectType={selectType}\n type=\"text\"\n {...restInputProps}\n disabled={disabled && !fetching}\n readOnly={restInputProps.readOnly || !searchable || (disabled && fetching)}\n Component=\"input\"\n normalize={false}\n className={styles['CustomSelectInput__input']}\n getRootRef={getRef}\n />\n );\n\n return (\n <FormField\n Component=\"div\"\n style={style}\n className={classNames(\n styles['CustomSelectInput'],\n align === 'right' && styles['CustomSelectInput--align-right'],\n align === 'center' && styles['CustomSelectInput--align-center'],\n !selectedOptionLabel && styles['CustomSelectInput--empty'],\n multiline && styles['CustomSelectInput--multiline'],\n sizeY !== 'regular' && sizeYClassNames[sizeY],\n before && styles['CustomSelectInput--hasBefore'],\n after && styles['CustomSelectInput--hasAfter'],\n className,\n )}\n getRootRef={handleRootRef}\n before={before}\n after={after}\n disabled={disabled}\n mode={getFormFieldModeFromSelectType(selectType)}\n status={status}\n >\n <div className={styles['CustomSelectInput__input-group']}>\n {/* Чтобы отключить autosuggestion в iOS, тултипы которого начинают всплывать даже когда input\n * в режиме readonly, мы оборачиваем инпут в VisuallyHidden.\n * Тултипы появляются при каждом клике на input.\n * смотри: https://github.com/VKCOM/VKUI/issues/6205\n *\n * Достаточно не дать пользователю кликнуть по инпуту.\n * Делаем это только для режима read-only. Потому что проблема именно в режиме read-only.\n * Обертка вокруг инпута обрабатывает клики и передаёт фокус, так что на взаимодействии с инпутом это никак не скажется.\n **/}\n {!searchable && platform === 'ios' ? <VisuallyHidden>{input}</VisuallyHidden> : input}\n <div\n className={classNames(styles['CustomSelectInput__label-wrapper'], className)}\n tabIndex={-1}\n aria-hidden\n data-testid={labelTextTestId}\n >\n <SelectTypography selectType={selectType} className={styles['CustomSelectInput__label']}>\n {selectedOptionLabel || restInputProps.placeholder}\n </SelectTypography>\n </div>\n </div>\n </FormField>\n );\n};\n"],"names":["CustomSelectInput","sizeYClassNames","none","compact","align","getRef","className","getRootRef","style","before","after","status","selectedOptionLabel","selectType","multiline","disabled","fetching","labelTextTestId","searchable","restInputProps","sizeY","useAdaptivity","handleRootRef","useExternRef","platform","usePlatform","input","SelectTypography","type","readOnly","Component","normalize","FormField","classNames","mode","getFormFieldModeFromSelectType","div","VisuallyHidden","tabIndex","aria-hidden","data-testid","placeholder"],"mappings":";;;;+BAoCaA;;;eAAAA;;;;;;;;iEApCU;sBACI;+BACG;8BACD;6BACD;wBACmB;2BAEL;kCAET;gCACF;AAG/B,MAAMC,kBAAkB;IACtBC,IAAI;IACJC,OAAO;AACT;AAoBO,MAAMH,oBAAoB;QAAC,EAChCI,QAAQ,MAAM,EACdC,MAAM,EACNC,SAAS,EACTC,UAAU,EACVC,KAAK,EACLC,MAAM,EACNC,KAAK,EACLC,MAAM,EACNC,mBAAmB,EACnBC,aAAa,SAAS,EACtBC,SAAS,EACTC,QAAQ,EACRC,QAAQ,EACRC,eAAe,EACfC,UAAU,EAEa,WADpBC;QAfHf;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;;IAGA,MAAM,EAAEE,QAAQ,MAAM,EAAE,GAAGC,IAAAA,4BAAa;IAExC,MAAMC,gBAAgBC,IAAAA,0BAAY,EAAChB;IAEnC,MAAMiB,WAAWC,IAAAA,wBAAW;IAE5B,MAAMC,sBACJ,qBAACC,kCAAgB;QACfd,YAAYA;QACZe,MAAK;OACDT;QACJJ,UAAUA,YAAY,CAACC;QACvBa,UAAUV,eAAeU,QAAQ,IAAI,CAACX,cAAeH,YAAYC;QACjEc,WAAU;QACVC,WAAW;QACXzB,SAAS;QACTC,YAAYF;;IAIhB,qBACE,qBAAC2B,oBAAS;QACRF,WAAU;QACVtB,OAAOA;QACPF,WAAW2B,IAAAA,gBAAU,2BAEnB7B,UAAU,iDACVA,UAAU,mDACV,CAACQ,uDACDE,iDACAM,UAAU,aAAanB,eAAe,CAACmB,MAAM,EAC7CX,8CACAC,4CACAJ;QAEFC,YAAYe;QACZb,QAAQA;QACRC,OAAOA;QACPK,UAAUA;QACVmB,MAAMC,IAAAA,sCAA8B,EAACtB;QACrCF,QAAQA;kBAER,cAAA,sBAACyB;YAAI9B,SAAS;;gBAUX,CAACY,cAAcM,aAAa,sBAAQ,qBAACa,8BAAc;8BAAEX;qBAA0BA;8BAChF,qBAACU;oBACC9B,WAAW2B,IAAAA,gBAAU,0CAA6C3B;oBAClEgC,UAAU,CAAC;oBACXC,aAAW;oBACXC,eAAavB;8BAEb,cAAA,qBAACU,kCAAgB;wBAACd,YAAYA;wBAAYP,SAAS;kCAChDM,uBAAuBO,eAAesB,WAAW;;;;;;AAM9D"}
1
+ {"version":3,"sources":["../../../../src/components/CustomSelect/CustomSelectInput.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useFocusWithin } from '../../hooks/useFocusWithin';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { getFormFieldModeFromSelectType } from '../../lib/select';\nimport { HasAlign, HasRef, HasRootRef } from '../../types';\nimport { FormField, FormFieldProps } from '../FormField/FormField';\nimport type { SelectType } from '../Select/Select';\nimport { SelectTypography } from '../SelectTypography/SelectTypography';\nimport { Text } from '../Typography/Text/Text';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './CustomSelectInput.module.css';\n\nconst sizeYClassNames = {\n none: styles['CustomSelectInput--sizeY-none'],\n compact: styles['CustomSelectInput--sizeY-compact'],\n};\n\nexport interface CustomSelectInputProps\n extends React.InputHTMLAttributes<HTMLInputElement>,\n HasRef<HTMLInputElement>,\n HasRootRef<HTMLDivElement>,\n HasAlign,\n Omit<FormFieldProps, 'mode' | 'type' | 'maxHeight'> {\n selectType?: SelectType;\n multiline?: boolean;\n labelTextTestId?: string;\n fetching?: boolean;\n}\n\n/**\n * @since 5.10.0\n * @private\n */\nexport const CustomSelectInput = ({\n align = 'left',\n getRef,\n className,\n getRootRef,\n style,\n before,\n after,\n status,\n children,\n placeholder,\n selectType = 'default',\n multiline,\n disabled,\n fetching,\n labelTextTestId,\n ...restProps\n}: CustomSelectInputProps): React.ReactNode => {\n const { sizeY = 'none' } = useAdaptivity();\n\n const title = children || placeholder;\n const showLabelOrPlaceholder = !Boolean(restProps.value);\n\n const handleRootRef = useExternRef(getRootRef);\n const focusWithin = useFocusWithin(handleRootRef);\n\n const input = (\n <Text\n type=\"text\"\n {...restProps}\n disabled={disabled && !fetching}\n readOnly={restProps.readOnly || (disabled && fetching)}\n Component=\"input\"\n normalize={false}\n className={classNames(\n styles['CustomSelectInput__el'],\n (restProps.readOnly || (showLabelOrPlaceholder && !focusWithin)) &&\n styles['CustomSelectInput__el--cursor-pointer'],\n )}\n getRootRef={getRef}\n placeholder={children ? '' : placeholder}\n />\n );\n\n const platform = usePlatform();\n return (\n <FormField\n Component=\"div\"\n style={style}\n className={classNames(\n styles['CustomSelectInput'],\n align === 'right' && styles['CustomSelectInput--align-right'],\n align === 'center' && styles['CustomSelectInput--align-center'],\n !children && styles['CustomSelectInput--empty'],\n multiline && styles['CustomSelectInput--multiline'],\n sizeY !== 'regular' && sizeYClassNames[sizeY],\n before && styles['CustomSelectInput--hasBefore'],\n after && styles['CustomSelectInput--hasAfter'],\n className,\n )}\n getRootRef={handleRootRef}\n before={before}\n after={after}\n disabled={disabled}\n mode={getFormFieldModeFromSelectType(selectType)}\n status={status}\n >\n <div className={styles['CustomSelectInput__input-group']}>\n <div\n className={classNames(styles['CustomSelectInput__container'], className)}\n tabIndex={-1}\n aria-hidden\n data-testid={labelTextTestId}\n >\n <SelectTypography selectType={selectType} className={styles['CustomSelectInput__title']}>\n {showLabelOrPlaceholder && title}\n </SelectTypography>\n </div>\n {/* Чтобы отключить autosuggestion в iOS, тултипы которого начинают всплывать даже когда input\n * в режиме readonly, мы оборачиваем инпут в VisuallyHidden.\n * Тултипы появляются при каждом клике на input.\n * смотри: https://github.com/VKCOM/VKUI/issues/6205\n *\n * Достаточно не дать пользователю кликнуть по инпуту.\n * Делаем это только для режима read-only. Потому что проблема именно в режиме read-only.\n * Обертка вокруг инпута обрабатывает клики и передаёт фокус, так что на взаимодействии с инпутом это никак не скажется.\n **/}\n {restProps.readOnly && platform === 'ios' ? (\n <VisuallyHidden>{input}</VisuallyHidden>\n ) : (\n input\n )}\n </div>\n </FormField>\n );\n};\n"],"names":["CustomSelectInput","sizeYClassNames","none","compact","align","getRef","className","getRootRef","style","before","after","status","children","placeholder","selectType","multiline","disabled","fetching","labelTextTestId","restProps","sizeY","useAdaptivity","title","showLabelOrPlaceholder","Boolean","value","handleRootRef","useExternRef","focusWithin","useFocusWithin","input","Text","type","readOnly","Component","normalize","classNames","platform","usePlatform","FormField","mode","getFormFieldModeFromSelectType","div","tabIndex","aria-hidden","data-testid","SelectTypography","VisuallyHidden"],"mappings":";;;;+BAoCaA;;;eAAAA;;;;;;;;iEApCU;sBACI;+BACG;8BACD;gCACE;6BACH;wBACmB;2BAEL;kCAET;sBACZ;gCACU;AAG/B,MAAMC,kBAAkB;IACtBC,IAAI;IACJC,OAAO;AACT;AAkBO,MAAMH,oBAAoB;QAAC,EAChCI,QAAQ,MAAM,EACdC,MAAM,EACNC,SAAS,EACTC,UAAU,EACVC,KAAK,EACLC,MAAM,EACNC,KAAK,EACLC,MAAM,EACNC,QAAQ,EACRC,WAAW,EACXC,aAAa,SAAS,EACtBC,SAAS,EACTC,QAAQ,EACRC,QAAQ,EACRC,eAAe,EAEQ,WADpBC;QAfHf;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;;IAGA,MAAM,EAAEE,QAAQ,MAAM,EAAE,GAAGC,IAAAA,4BAAa;IAExC,MAAMC,QAAQV,YAAYC;IAC1B,MAAMU,yBAAyB,CAACC,QAAQL,UAAUM,KAAK;IAEvD,MAAMC,gBAAgBC,IAAAA,0BAAY,EAACpB;IACnC,MAAMqB,cAAcC,IAAAA,8BAAc,EAACH;IAEnC,MAAMI,sBACJ,qBAACC,UAAI;QACHC,MAAK;OACDb;QACJH,UAAUA,YAAY,CAACC;QACvBgB,UAAUd,UAAUc,QAAQ,IAAKjB,YAAYC;QAC7CiB,WAAU;QACVC,WAAW;QACX7B,WAAW8B,IAAAA,gBAAU,+BAEnB,AAACjB,CAAAA,UAAUc,QAAQ,IAAKV,0BAA0B,CAACK,WAAW;QAGhErB,YAAYF;QACZQ,aAAaD,WAAW,KAAKC;;IAIjC,MAAMwB,WAAWC,IAAAA,wBAAW;IAC5B,qBACE,qBAACC,oBAAS;QACRL,WAAU;QACV1B,OAAOA;QACPF,WAAW8B,IAAAA,gBAAU,2BAEnBhC,UAAU,iDACVA,UAAU,mDACV,CAACQ,4CACDG,iDACAK,UAAU,aAAanB,eAAe,CAACmB,MAAM,EAC7CX,8CACAC,4CACAJ;QAEFC,YAAYmB;QACZjB,QAAQA;QACRC,OAAOA;QACPM,UAAUA;QACVwB,MAAMC,IAAAA,sCAA8B,EAAC3B;QACrCH,QAAQA;kBAER,cAAA,sBAAC+B;YAAIpC,SAAS;;8BACZ,qBAACoC;oBACCpC,WAAW8B,IAAAA,gBAAU,sCAAyC9B;oBAC9DqC,UAAU,CAAC;oBACXC,aAAW;oBACXC,eAAa3B;8BAEb,cAAA,qBAAC4B,kCAAgB;wBAAChC,YAAYA;wBAAYR,SAAS;kCAChDiB,0BAA0BD;;;gBAY9BH,UAAUc,QAAQ,IAAII,aAAa,sBAClC,qBAACU,8BAAc;8BAAEjB;qBAEjBA;;;;AAKV"}
@@ -182,7 +182,10 @@ const ImageBase = (_param)=>{
182
182
  className: "vkuiImageBase__fallback",
183
183
  children: fallbackIcon
184
184
  }),
185
- children,
185
+ children && /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
186
+ className: "vkuiImageBase__children",
187
+ children: children
188
+ }),
186
189
  !noBorder && /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
187
190
  "aria-hidden": true,
188
191
  className: "vkuiImageBase__border"
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ImageBase/ImageBase.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { minOr } from '../../lib/comparing';\nimport { getFetchPriorityProp } from '../../lib/utils';\nimport type { AnchorHTMLAttributesOnly, HasRef, HasRootRef, LiteralUnion } from '../../types';\nimport { Clickable } from '../Clickable/Clickable';\nimport { ImageBaseBadge, type ImageBaseBadgeProps } from './ImageBaseBadge/ImageBaseBadge';\nimport { ImageBaseOverlay, type ImageBaseOverlayProps } from './ImageBaseOverlay/ImageBaseOverlay';\nimport { ImageBaseContext } from './context';\nimport type { ImageBaseContextProps, ImageBaseExpectedIconProps, ImageBaseSize } from './types';\nimport { validateFallbackIcon, validateSize } from './validators';\nimport styles from './ImageBase.module.css';\n\nexport type {\n ImageBaseSize,\n ImageBaseExpectedIconProps,\n ImageBaseBadgeProps,\n ImageBaseOverlayProps,\n ImageBaseContextProps,\n};\n\nexport {\n getBadgeIconSizeByImageBaseSize,\n getFallbackIconSizeByImageBaseSize,\n getOverlayIconSizeByImageBaseSize,\n} from './helpers';\n\nexport { ImageBaseContext };\n\n/**\n * Размер по умолчанию.\n */\nconst defaultSize = 24;\n\nexport interface ImageBaseProps\n extends React.ImgHTMLAttributes<HTMLElement>,\n AnchorHTMLAttributesOnly,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLImageElement> {\n /**\n * Задаёт размер картинки.\n *\n * Используйте размеры заданные дизайн-системой `16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 56 | 64 | 72 | 80 | 88 | 96`.\n *\n * > ⚠️ Использование кастомного размера – это пограничный кейс.\n */\n size?: LiteralUnion<ImageBaseSize, number>;\n /**\n * Ширина изображения\n */\n widthSize?: number | string;\n /**\n * Высота изображения\n */\n heightSize?: number | string;\n /**\n * Отключает обводку.\n */\n noBorder?: boolean;\n /**\n * Фолбек на случай, если картинка не прогрузилась.\n *\n * > 📝 Нужный для `<ImageBase size={...} />` размер можно узнать из функции `getFallbackIconSizeByImageBaseSize()`.\n *\n * > Предпочтительней использовать иконки из `@vkontakte/icons`.\n *\n * > 📊️ Если вы хотите передать кастомную иконку, то следует именовать её по шаблону `Icon<size><name>`. Или же\n * > чтобы в неё был передан параметр `width`. Тогда мы сможем выводить в консоль подсказку правильного ли размера вы\n * > использовали иконку.\n *\n * > ⚠️ Может перекрывать `children`.\n */\n fallbackIcon?: React.ReactElement<ImageBaseExpectedIconProps>;\n /**\n * Отключает фон, заданный по умолчанию. Полезен для отображения картинок с прозрачностью.\n * @since 5.10.0\n */\n withTransparentBackground?: boolean;\n /**\n * Пользовательское значения стиля object-fit\n * Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/object-fit)\n */\n objectFit?: React.CSSProperties['objectFit'];\n /**\n * Флаг для сохранения пропорций картинки.\n * Для корректной работы необходимо задать размеры хотя бы одной стороны картинки\n */\n keepAspectRatio?: boolean;\n}\n\nconst getObjectFitClassName = (objectFit: React.CSSProperties['objectFit']) => {\n switch (objectFit) {\n case 'contain':\n return styles['ImageBase__img--objectFit-contain'];\n case 'cover':\n return styles['ImageBase__img--objectFit-cover'];\n case 'none':\n return styles['ImageBase__img--objectFit-none'];\n case 'scale-down':\n return styles['ImageBase__img--objectFit-scaleDown'];\n }\n return undefined;\n};\n\nconst parsePx = (value: string): number | undefined => {\n if (value.endsWith('px')) {\n return parseInt(value);\n }\n return undefined;\n};\n\nconst sizeToNumber = (size: number | string | undefined): number | undefined => {\n if (typeof size === 'string') {\n return parsePx(size);\n }\n return size;\n};\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ImageBase\n */\nexport const ImageBase: React.FC<ImageBaseProps> & {\n Badge: typeof ImageBaseBadge;\n Overlay: typeof ImageBaseOverlay;\n} = ({\n alt,\n crossOrigin,\n decoding,\n loading,\n referrerPolicy,\n sizes,\n src,\n srcSet,\n useMap,\n fetchPriority,\n getRef,\n size: sizeProp,\n width: widthImg,\n height: heightImg,\n widthSize,\n heightSize,\n style,\n noBorder = false,\n fallbackIcon: fallbackIconProp,\n children,\n onLoad,\n onError,\n withTransparentBackground,\n objectFit = 'cover',\n keepAspectRatio = false,\n ...restProps\n}: ImageBaseProps) => {\n const size = sizeProp ?? minOr([sizeToNumber(widthSize), sizeToNumber(heightSize)], defaultSize);\n\n const width = widthSize ?? (keepAspectRatio ? undefined : size);\n const height = heightSize ?? (keepAspectRatio ? undefined : size);\n\n const [loaded, setLoaded] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n\n const hasSrc = src || srcSet;\n const needShowFallbackIcon = (failed || !hasSrc) && React.isValidElement(fallbackIconProp);\n\n const fallbackIcon = needShowFallbackIcon ? fallbackIconProp : null;\n\n if (process.env.NODE_ENV === 'development') {\n validateSize(size);\n if (fallbackIcon) {\n validateFallbackIcon(size, { name: 'fallbackIcon', value: fallbackIcon });\n }\n }\n\n const handleImageLoad = (event: React.SyntheticEvent<HTMLImageElement>) => {\n if (loaded) {\n return;\n }\n\n setLoaded(true);\n setFailed(false);\n onLoad?.(event);\n };\n\n const handleImageError = (event: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(false);\n setFailed(true);\n onError?.(event);\n };\n\n const imgRef = useExternRef(getRef);\n const isOnLoadStatusCheckedRef = React.useRef(false);\n React.useEffect(\n function dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater() {\n if (isOnLoadStatusCheckedRef.current) {\n return;\n }\n isOnLoadStatusCheckedRef.current = true;\n\n if (imgRef.current && imgRef.current.complete && !loaded) {\n const event = new Event('load');\n imgRef.current.dispatchEvent(event);\n }\n },\n [imgRef, loaded],\n );\n\n return (\n <ImageBaseContext.Provider value={{ size }}>\n <Clickable\n style={{ width, height, ...style }}\n baseClassName={classNames(\n styles['ImageBase'],\n loaded && styles['ImageBase--loaded'],\n withTransparentBackground && styles['ImageBase--transparent-background'],\n )}\n {...restProps}\n >\n {hasSrc && (\n <img\n ref={imgRef}\n alt={alt}\n className={classNames(\n styles['ImageBase__img'],\n getObjectFitClassName(objectFit),\n keepAspectRatio && styles['ImageBase__img--keepRatio'],\n )}\n crossOrigin={crossOrigin}\n decoding={decoding}\n loading={loading}\n referrerPolicy={referrerPolicy}\n style={\n keepAspectRatio\n ? {\n width: widthImg || width,\n height: heightImg || height,\n }\n : undefined\n }\n sizes={sizes}\n src={src}\n srcSet={srcSet}\n useMap={useMap}\n width={widthImg}\n height={heightImg}\n onLoad={handleImageLoad}\n onError={handleImageError}\n {...getFetchPriorityProp(fetchPriority)}\n />\n )}\n {fallbackIcon && <div className={styles['ImageBase__fallback']}>{fallbackIcon}</div>}\n {children}\n {!noBorder && <div aria-hidden className={styles['ImageBase__border']} />}\n </Clickable>\n </ImageBaseContext.Provider>\n );\n};\n\nImageBase.displayName = 'ImageBase';\n\nImageBase.Badge = ImageBaseBadge;\nImageBase.Badge.displayName = 'ImageBase.Badge';\n\nImageBase.Overlay = ImageBaseOverlay;\nImageBase.Overlay.displayName = 'ImageBase.Overlay';\n"],"names":["ImageBase","ImageBaseContext","getBadgeIconSizeByImageBaseSize","getFallbackIconSizeByImageBaseSize","getOverlayIconSizeByImageBaseSize","defaultSize","getObjectFitClassName","objectFit","undefined","parsePx","value","endsWith","parseInt","sizeToNumber","size","alt","crossOrigin","decoding","loading","referrerPolicy","sizes","src","srcSet","useMap","fetchPriority","getRef","sizeProp","width","widthImg","height","heightImg","widthSize","heightSize","style","noBorder","fallbackIcon","fallbackIconProp","children","onLoad","onError","withTransparentBackground","keepAspectRatio","restProps","minOr","loaded","setLoaded","React","useState","failed","setFailed","hasSrc","needShowFallbackIcon","isValidElement","process","env","NODE_ENV","validateSize","validateFallbackIcon","name","handleImageLoad","event","handleImageError","imgRef","useExternRef","isOnLoadStatusCheckedRef","useRef","useEffect","dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater","current","complete","Event","dispatchEvent","Provider","Clickable","baseClassName","classNames","img","ref","className","getFetchPriorityProp","div","aria-hidden","displayName","Badge","ImageBaseBadge","Overlay","ImageBaseOverlay"],"mappings":";;;;;;;;;;;IA0HaA,SAAS;eAATA;;IA9FJC,gBAAgB;eAAhBA,yBAAgB;;IALvBC,+BAA+B;eAA/BA,wCAA+B;;IAC/BC,kCAAkC;eAAlCA,2CAAkC;;IAClCC,iCAAiC;eAAjCA,0CAAiC;;;;;;;;iEAzBZ;sBACI;8BACE;2BACP;uBACe;2BAEX;gCAC+B;kCACI;yBAC5B;4BAEkB;yBAe5C;AAIP;;CAEC,GACD,MAAMC,cAAc;AA0DpB,MAAMC,wBAAwB,CAACC;IAC7B,OAAQA;QACN,KAAK;YACH;QACF,KAAK;YACH;QACF,KAAK;YACH;QACF,KAAK;YACH;IACJ;IACA,OAAOC;AACT;AAEA,MAAMC,UAAU,CAACC;IACf,IAAIA,MAAMC,QAAQ,CAAC,OAAO;QACxB,OAAOC,SAASF;IAClB;IACA,OAAOF;AACT;AAEA,MAAMK,eAAe,CAACC;IACpB,IAAI,OAAOA,SAAS,UAAU;QAC5B,OAAOL,QAAQK;IACjB;IACA,OAAOA;AACT;AAKO,MAAMd,YAGT;QAAC,EACHe,GAAG,EACHC,WAAW,EACXC,QAAQ,EACRC,OAAO,EACPC,cAAc,EACdC,KAAK,EACLC,GAAG,EACHC,MAAM,EACNC,MAAM,EACNC,aAAa,EACbC,MAAM,EACNX,MAAMY,QAAQ,EACdC,OAAOC,QAAQ,EACfC,QAAQC,SAAS,EACjBC,SAAS,EACTC,UAAU,EACVC,KAAK,EACLC,WAAW,KAAK,EAChBC,cAAcC,gBAAgB,EAC9BC,QAAQ,EACRC,MAAM,EACNC,OAAO,EACPC,yBAAyB,EACzBjC,YAAY,OAAO,EACnBkC,kBAAkB,KAAK,EAER,WADZC;QAzBH3B;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAX;QACAa;QACAE;QACAE;QACAC;QACAC;QACAC;QACAC;QACAE;QACAC;QACAC;QACAC;QACAjC;QACAkC;;IAGA,MAAM3B,OAAOY,qBAAAA,sBAAAA,WAAYiB,IAAAA,gBAAK,EAAC;QAAC9B,aAAakB;QAAYlB,aAAamB;KAAY,EAAE3B;IAEpF,MAAMsB,QAAQI,sBAAAA,uBAAAA,YAAcU,kBAAkBjC,YAAYM;IAC1D,MAAMe,SAASG,uBAAAA,wBAAAA,aAAeS,kBAAkBjC,YAAYM;IAE5D,MAAM,CAAC8B,QAAQC,UAAU,GAAGC,OAAMC,QAAQ,CAAC;IAC3C,MAAM,CAACC,QAAQC,UAAU,GAAGH,OAAMC,QAAQ,CAAC;IAE3C,MAAMG,SAAS7B,OAAOC;IACtB,MAAM6B,uBAAuB,AAACH,CAAAA,UAAU,CAACE,MAAK,mBAAMJ,OAAMM,cAAc,CAAChB;IAEzE,MAAMD,eAAegB,uBAAuBf,mBAAmB;IAE/D,IAAIiB,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QAC1CC,IAAAA,wBAAY,EAAC1C;QACb,IAAIqB,cAAc;YAChBsB,IAAAA,gCAAoB,EAAC3C,MAAM;gBAAE4C,MAAM;gBAAgBhD,OAAOyB;YAAa;QACzE;IACF;IAEA,MAAMwB,kBAAkB,CAACC;QACvB,IAAIhB,QAAQ;YACV;QACF;QAEAC,UAAU;QACVI,UAAU;QACVX,mBAAAA,6BAAAA,OAASsB;IACX;IAEA,MAAMC,mBAAmB,CAACD;QACxBf,UAAU;QACVI,UAAU;QACVV,oBAAAA,8BAAAA,QAAUqB;IACZ;IAEA,MAAME,SAASC,IAAAA,0BAAY,EAACtC;IAC5B,MAAMuC,2BAA2BlB,OAAMmB,MAAM,CAAC;IAC9CnB,OAAMoB,SAAS,CACb,SAASC;QACP,IAAIH,yBAAyBI,OAAO,EAAE;YACpC;QACF;QACAJ,yBAAyBI,OAAO,GAAG;QAEnC,IAAIN,OAAOM,OAAO,IAAIN,OAAOM,OAAO,CAACC,QAAQ,IAAI,CAACzB,QAAQ;YACxD,MAAMgB,QAAQ,IAAIU,MAAM;YACxBR,OAAOM,OAAO,CAACG,aAAa,CAACX;QAC/B;IACF,GACA;QAACE;QAAQlB;KAAO;IAGlB,qBACE,qBAAC3C,yBAAgB,CAACuE,QAAQ;QAAC9D,OAAO;YAAEI;QAAK;kBACvC,cAAA,sBAAC2D,oBAAS;YACRxC,OAAO;gBAAEN;gBAAOE;eAAWI;YAC3ByC,eAAeC,IAAAA,gBAAU,mBAEvB/B,mCACAJ;WAEEE;;gBAEHQ,wBACC,qBAAC0B;oBACCC,KAAKf;oBACL/C,KAAKA;oBACL+D,WAAWH,IAAAA,gBAAU,wBAEnBrE,sBAAsBC,YACtBkC;oBAEFzB,aAAaA;oBACbC,UAAUA;oBACVC,SAASA;oBACTC,gBAAgBA;oBAChBc,OACEQ,kBACI;wBACEd,OAAOC,YAAYD;wBACnBE,QAAQC,aAAaD;oBACvB,IACArB;oBAENY,OAAOA;oBACPC,KAAKA;oBACLC,QAAQA;oBACRC,QAAQA;oBACRI,OAAOC;oBACPC,QAAQC;oBACRQ,QAAQqB;oBACRpB,SAASsB;mBACLkB,IAAAA,2BAAoB,EAACvD;gBAG5BW,8BAAgB,qBAAC6C;oBAAIF,SAAS;8BAAkC3C;;gBAChEE;gBACA,CAACH,0BAAY,qBAAC8C;oBAAIC,aAAW;oBAACH,SAAS;;;;;AAIhD;AAEA9E,UAAUkF,WAAW,GAAG;AAExBlF,UAAUmF,KAAK,GAAGC,8BAAc;AAChCpF,UAAUmF,KAAK,CAACD,WAAW,GAAG;AAE9BlF,UAAUqF,OAAO,GAAGC,kCAAgB;AACpCtF,UAAUqF,OAAO,CAACH,WAAW,GAAG"}
1
+ {"version":3,"sources":["../../../../src/components/ImageBase/ImageBase.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { minOr } from '../../lib/comparing';\nimport { getFetchPriorityProp } from '../../lib/utils';\nimport type { AnchorHTMLAttributesOnly, HasRef, HasRootRef, LiteralUnion } from '../../types';\nimport { Clickable } from '../Clickable/Clickable';\nimport { ImageBaseBadge, type ImageBaseBadgeProps } from './ImageBaseBadge/ImageBaseBadge';\nimport { ImageBaseOverlay, type ImageBaseOverlayProps } from './ImageBaseOverlay/ImageBaseOverlay';\nimport { ImageBaseContext } from './context';\nimport type { ImageBaseContextProps, ImageBaseExpectedIconProps, ImageBaseSize } from './types';\nimport { validateFallbackIcon, validateSize } from './validators';\nimport styles from './ImageBase.module.css';\n\nexport type {\n ImageBaseSize,\n ImageBaseExpectedIconProps,\n ImageBaseBadgeProps,\n ImageBaseOverlayProps,\n ImageBaseContextProps,\n};\n\nexport {\n getBadgeIconSizeByImageBaseSize,\n getFallbackIconSizeByImageBaseSize,\n getOverlayIconSizeByImageBaseSize,\n} from './helpers';\n\nexport { ImageBaseContext };\n\n/**\n * Размер по умолчанию.\n */\nconst defaultSize = 24;\n\nexport interface ImageBaseProps\n extends React.ImgHTMLAttributes<HTMLElement>,\n AnchorHTMLAttributesOnly,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLImageElement> {\n /**\n * Задаёт размер картинки.\n *\n * Используйте размеры заданные дизайн-системой `16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 56 | 64 | 72 | 80 | 88 | 96`.\n *\n * > ⚠️ Использование кастомного размера – это пограничный кейс.\n */\n size?: LiteralUnion<ImageBaseSize, number>;\n /**\n * Ширина изображения\n */\n widthSize?: number | string;\n /**\n * Высота изображения\n */\n heightSize?: number | string;\n /**\n * Отключает обводку.\n */\n noBorder?: boolean;\n /**\n * Фолбек на случай, если картинка не прогрузилась.\n *\n * > 📝 Нужный для `<ImageBase size={...} />` размер можно узнать из функции `getFallbackIconSizeByImageBaseSize()`.\n *\n * > Предпочтительней использовать иконки из `@vkontakte/icons`.\n *\n * > 📊️ Если вы хотите передать кастомную иконку, то следует именовать её по шаблону `Icon<size><name>`. Или же\n * > чтобы в неё был передан параметр `width`. Тогда мы сможем выводить в консоль подсказку правильного ли размера вы\n * > использовали иконку.\n *\n * > ⚠️ Может перекрывать `children`.\n */\n fallbackIcon?: React.ReactElement<ImageBaseExpectedIconProps>;\n /**\n * Отключает фон, заданный по умолчанию. Полезен для отображения картинок с прозрачностью.\n * @since 5.10.0\n */\n withTransparentBackground?: boolean;\n /**\n * Пользовательское значения стиля object-fit\n * Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/object-fit)\n */\n objectFit?: React.CSSProperties['objectFit'];\n /**\n * Флаг для сохранения пропорций картинки.\n * Для корректной работы необходимо задать размеры хотя бы одной стороны картинки\n */\n keepAspectRatio?: boolean;\n}\n\nconst getObjectFitClassName = (objectFit: React.CSSProperties['objectFit']) => {\n switch (objectFit) {\n case 'contain':\n return styles['ImageBase__img--objectFit-contain'];\n case 'cover':\n return styles['ImageBase__img--objectFit-cover'];\n case 'none':\n return styles['ImageBase__img--objectFit-none'];\n case 'scale-down':\n return styles['ImageBase__img--objectFit-scaleDown'];\n }\n return undefined;\n};\n\nconst parsePx = (value: string): number | undefined => {\n if (value.endsWith('px')) {\n return parseInt(value);\n }\n return undefined;\n};\n\nconst sizeToNumber = (size: number | string | undefined): number | undefined => {\n if (typeof size === 'string') {\n return parsePx(size);\n }\n return size;\n};\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ImageBase\n */\nexport const ImageBase: React.FC<ImageBaseProps> & {\n Badge: typeof ImageBaseBadge;\n Overlay: typeof ImageBaseOverlay;\n} = ({\n alt,\n crossOrigin,\n decoding,\n loading,\n referrerPolicy,\n sizes,\n src,\n srcSet,\n useMap,\n fetchPriority,\n getRef,\n size: sizeProp,\n width: widthImg,\n height: heightImg,\n widthSize,\n heightSize,\n style,\n noBorder = false,\n fallbackIcon: fallbackIconProp,\n children,\n onLoad,\n onError,\n withTransparentBackground,\n objectFit = 'cover',\n keepAspectRatio = false,\n ...restProps\n}: ImageBaseProps) => {\n const size = sizeProp ?? minOr([sizeToNumber(widthSize), sizeToNumber(heightSize)], defaultSize);\n\n const width = widthSize ?? (keepAspectRatio ? undefined : size);\n const height = heightSize ?? (keepAspectRatio ? undefined : size);\n\n const [loaded, setLoaded] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n\n const hasSrc = src || srcSet;\n const needShowFallbackIcon = (failed || !hasSrc) && React.isValidElement(fallbackIconProp);\n\n const fallbackIcon = needShowFallbackIcon ? fallbackIconProp : null;\n\n if (process.env.NODE_ENV === 'development') {\n validateSize(size);\n if (fallbackIcon) {\n validateFallbackIcon(size, { name: 'fallbackIcon', value: fallbackIcon });\n }\n }\n\n const handleImageLoad = (event: React.SyntheticEvent<HTMLImageElement>) => {\n if (loaded) {\n return;\n }\n\n setLoaded(true);\n setFailed(false);\n onLoad?.(event);\n };\n\n const handleImageError = (event: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(false);\n setFailed(true);\n onError?.(event);\n };\n\n const imgRef = useExternRef(getRef);\n const isOnLoadStatusCheckedRef = React.useRef(false);\n React.useEffect(\n function dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater() {\n if (isOnLoadStatusCheckedRef.current) {\n return;\n }\n isOnLoadStatusCheckedRef.current = true;\n\n if (imgRef.current && imgRef.current.complete && !loaded) {\n const event = new Event('load');\n imgRef.current.dispatchEvent(event);\n }\n },\n [imgRef, loaded],\n );\n\n return (\n <ImageBaseContext.Provider value={{ size }}>\n <Clickable\n style={{ width, height, ...style }}\n baseClassName={classNames(\n styles['ImageBase'],\n loaded && styles['ImageBase--loaded'],\n withTransparentBackground && styles['ImageBase--transparent-background'],\n )}\n {...restProps}\n >\n {hasSrc && (\n <img\n ref={imgRef}\n alt={alt}\n className={classNames(\n styles['ImageBase__img'],\n getObjectFitClassName(objectFit),\n keepAspectRatio && styles['ImageBase__img--keepRatio'],\n )}\n crossOrigin={crossOrigin}\n decoding={decoding}\n loading={loading}\n referrerPolicy={referrerPolicy}\n style={\n keepAspectRatio\n ? {\n width: widthImg || width,\n height: heightImg || height,\n }\n : undefined\n }\n sizes={sizes}\n src={src}\n srcSet={srcSet}\n useMap={useMap}\n width={widthImg}\n height={heightImg}\n onLoad={handleImageLoad}\n onError={handleImageError}\n {...getFetchPriorityProp(fetchPriority)}\n />\n )}\n {fallbackIcon && <div className={styles['ImageBase__fallback']}>{fallbackIcon}</div>}\n {children && <div className={styles['ImageBase__children']}>{children}</div>}\n {!noBorder && <div aria-hidden className={styles['ImageBase__border']} />}\n </Clickable>\n </ImageBaseContext.Provider>\n );\n};\n\nImageBase.displayName = 'ImageBase';\n\nImageBase.Badge = ImageBaseBadge;\nImageBase.Badge.displayName = 'ImageBase.Badge';\n\nImageBase.Overlay = ImageBaseOverlay;\nImageBase.Overlay.displayName = 'ImageBase.Overlay';\n"],"names":["ImageBase","ImageBaseContext","getBadgeIconSizeByImageBaseSize","getFallbackIconSizeByImageBaseSize","getOverlayIconSizeByImageBaseSize","defaultSize","getObjectFitClassName","objectFit","undefined","parsePx","value","endsWith","parseInt","sizeToNumber","size","alt","crossOrigin","decoding","loading","referrerPolicy","sizes","src","srcSet","useMap","fetchPriority","getRef","sizeProp","width","widthImg","height","heightImg","widthSize","heightSize","style","noBorder","fallbackIcon","fallbackIconProp","children","onLoad","onError","withTransparentBackground","keepAspectRatio","restProps","minOr","loaded","setLoaded","React","useState","failed","setFailed","hasSrc","needShowFallbackIcon","isValidElement","process","env","NODE_ENV","validateSize","validateFallbackIcon","name","handleImageLoad","event","handleImageError","imgRef","useExternRef","isOnLoadStatusCheckedRef","useRef","useEffect","dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater","current","complete","Event","dispatchEvent","Provider","Clickable","baseClassName","classNames","img","ref","className","getFetchPriorityProp","div","aria-hidden","displayName","Badge","ImageBaseBadge","Overlay","ImageBaseOverlay"],"mappings":"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"}
@@ -2,12 +2,22 @@ import * as React from 'react';
2
2
  import { type FilterFn } from '../../lib/select';
3
3
  import { TrackerOptionsProps } from '../CustomScrollView/useTrackerVisibility';
4
4
  import { CustomSelectDropdownProps } from '../CustomSelectDropdown/CustomSelectDropdown';
5
+ import { type CustomSelectOptionProps } from '../CustomSelectOption/CustomSelectOption';
5
6
  import { FormFieldProps } from '../FormField/FormField';
6
7
  import { NativeSelectProps } from '../NativeSelect/NativeSelect';
7
8
  import { SelectType } from '../Select/Select';
8
9
  import { type CustomSelectClearButtonProps } from './CustomSelectClearButton';
9
- import type { CustomSelectOptionInterface, CustomSelectRenderOption } from './types';
10
- export type { CustomSelectClearButtonProps, CustomSelectOptionInterface, CustomSelectRenderOption };
10
+ type SelectValue = React.SelectHTMLAttributes<HTMLSelectElement>['value'];
11
+ export interface CustomSelectOptionInterface {
12
+ value: SelectValue;
13
+ label: React.ReactElement | string;
14
+ disabled?: boolean;
15
+ [index: string]: any;
16
+ }
17
+ export interface CustomSelectRenderOption<T extends CustomSelectOptionInterface> extends CustomSelectOptionProps {
18
+ option: T;
19
+ }
20
+ export type { CustomSelectClearButtonProps };
11
21
  export interface SelectProps<OptionInterfaceT extends CustomSelectOptionInterface = CustomSelectOptionInterface> extends NativeSelectProps, Omit<FormFieldProps, 'maxHeight'>, TrackerOptionsProps, Pick<CustomSelectDropdownProps, 'overscrollBehavior' | 'autoHideScrollbar' | 'autoHideScrollbarDelay'> {
12
22
  /**
13
23
  * ref на внутрений компонент input
@@ -1 +1 @@
1
- {"version":3,"file":"CustomSelect.d.ts","sourceRoot":"","sources":["../../../src/components/CustomSelect/CustomSelect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGlE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAC/E,OAAO,EAEL,yBAAyB,EAC1B,MAAM,8CAA8C,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,2BAA2B,CAAC;AASnC,OAAO,KAAK,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAiCrF,YAAY,EAAE,4BAA4B,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,CAAC;AAEpG,MAAM,WAAW,WAAW,CAC1B,gBAAgB,SAAS,2BAA2B,GAAG,2BAA2B,CAClF,SAAQ,iBAAiB,EACvB,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,EACjC,mBAAmB,EACnB,IAAI,CACF,yBAAyB,EACzB,oBAAoB,GAAG,mBAAmB,GAAG,wBAAwB,CACtE;IACH;;OAEG;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAChD;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC;IAC/C,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAC9C,cAAc,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAClC;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,CAAC,gBAAgB,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IACtF;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,EAChB,sBAAsB,GACvB,EAAE;QACD,sBAAsB,EAAE,KAAK,CAAC,SAAS,CAAC;KACzC,KAAK,KAAK,CAAC,SAAS,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;OAEG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,4BAA4B,CAAC,CAAC;IAChE;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID;;GAEG;AACH,wBAAgB,YAAY,CAAC,gBAAgB,SAAS,2BAA2B,EAC/E,KAAK,EAAE,WAAW,CAAC,gBAAgB,CAAC,GACnC,KAAK,CAAC,SAAS,CAisBjB"}
1
+ {"version":3,"file":"CustomSelect.d.ts","sourceRoot":"","sources":["../../../src/components/CustomSelect/CustomSelect.tsx"],"names":[],"mappings":"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"}
@@ -6,29 +6,67 @@ import * as React from 'react';
6
6
  import { classNames, debounce } from '@vkontakte/vkjs';
7
7
  import { useAdaptivity } from '../../hooks/useAdaptivity';
8
8
  import { useExternRef } from '../../hooks/useExternRef';
9
+ import { useFocusWithin } from '../../hooks/useFocusWithin';
9
10
  import { useDOM } from '../../lib/dom';
10
11
  import { defaultFilterFn } from '../../lib/select';
11
12
  import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
12
13
  import { warnOnce } from '../../lib/warnOnce';
13
14
  import { CustomSelectDropdown } from '../CustomSelectDropdown/CustomSelectDropdown';
15
+ import { CustomSelectOption } from '../CustomSelectOption/CustomSelectOption';
14
16
  import { DropdownIcon } from '../DropdownIcon/DropdownIcon';
15
17
  import { Footnote } from '../Typography/Footnote/Footnote';
18
+ import { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';
16
19
  import { CustomSelectClearButton } from './CustomSelectClearButton';
17
20
  import { CustomSelectInput } from './CustomSelectInput';
18
- import { calculateInputValueFromOptions, defaultRenderOptionFn, findIndexAfter, findIndexBefore, findSelectedIndex } from './helpers';
19
21
  const sizeYClassNames = {
20
22
  none: "vkuiCustomSelect--sizeY-none",
21
23
  ['compact']: "vkuiCustomSelect--sizeY-compact"
22
24
  };
25
+ const findIndexAfter = (options = [], startIndex = -1)=>{
26
+ if (startIndex >= options.length - 1) {
27
+ return -1;
28
+ }
29
+ return options.findIndex((option, i)=>i > startIndex && !option.disabled);
30
+ };
31
+ const findIndexBefore = (options = [], endIndex = options.length)=>{
32
+ let result = -1;
33
+ if (endIndex <= 0) {
34
+ return result;
35
+ }
36
+ for(let i = endIndex - 1; i >= 0; i--){
37
+ let option = options[i];
38
+ if (!option.disabled) {
39
+ result = i;
40
+ break;
41
+ }
42
+ }
43
+ return result;
44
+ };
23
45
  const warn = warnOnce('CustomSelect');
24
46
  const checkOptionsValueType = (options)=>{
25
47
  if (new Set(options.map((item)=>typeof item.value)).size > 1) {
26
48
  warn('Некоторые значения ваших опций имеют разные типы. onChange всегда возвращает строковый тип.', 'error');
27
49
  }
28
50
  };
51
+ function defaultRenderOptionFn(_param) {
52
+ var { option } = _param, props = _object_without_properties(_param, [
53
+ "option"
54
+ ]);
55
+ return /*#__PURE__*/ _jsx(CustomSelectOption, _object_spread({}, props));
56
+ }
29
57
  const handleOptionDown = (e)=>{
30
58
  e.preventDefault();
31
59
  };
60
+ function findSelectedIndex(options = [], value, withClear) {
61
+ if (withClear && value === '') {
62
+ return -1;
63
+ }
64
+ var _options_findIndex;
65
+ return (_options_findIndex = options.findIndex((item)=>{
66
+ value = typeof item.value === 'number' ? Number(value) : value;
67
+ return item.value === value;
68
+ })) !== null && _options_findIndex !== void 0 ? _options_findIndex : -1;
69
+ }
32
70
  const filter = (options, inputValue, filterFn)=>{
33
71
  return typeof filterFn === 'function' ? options.filter((option)=>filterFn(inputValue, option)) : options;
34
72
  };
@@ -85,11 +123,11 @@ const filter = (options, inputValue, filterFn)=>{
85
123
  const optionsWrapperRef = React.useRef(null);
86
124
  const [focusedOptionIndex, setFocusedOptionIndex] = React.useState(-1);
87
125
  const [isControlledOutside, setIsControlledOutside] = React.useState(props.value !== undefined);
126
+ const [inputValue, setInputValue] = React.useState('');
88
127
  const [nativeSelectValue, setNativeSelectValue] = React.useState(()=>{
89
128
  var _props_value, _ref;
90
129
  return (_ref = (_props_value = props.value) !== null && _props_value !== void 0 ? _props_value : defaultValue) !== null && _ref !== void 0 ? _ref : allowClearButton ? '' : undefined;
91
130
  });
92
- const [inputValue, setInputValue] = React.useState(()=>calculateInputValueFromOptions(optionsProp, nativeSelectValue));
93
131
  const [popperPlacement, setPopperPlacement] = React.useState(popupDirection);
94
132
  const [options, setOptions] = React.useState(optionsProp);
95
133
  var _props_value;
@@ -207,6 +245,7 @@ const filter = (options, inputValue, filterFn)=>{
207
245
  * Сброс происходит в одном из эффекте `updateOptionsAndSelectedOptionIndex()`.
208
246
  */ const close = React.useCallback(()=>{
209
247
  resetKeyboardInput();
248
+ setInputValue('');
210
249
  setOpened(false);
211
250
  resetFocusedOption();
212
251
  onClose === null || onClose === void 0 ? void 0 : onClose();
@@ -217,8 +256,8 @@ const filter = (options, inputValue, filterFn)=>{
217
256
  ]);
218
257
  const selectOption = React.useCallback((index)=>{
219
258
  const item = options[index];
220
- close();
221
259
  setNativeSelectValue(item === null || item === void 0 ? void 0 : item.value);
260
+ close();
222
261
  const shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync = isControlledOutside && props.value !== nativeSelectValue && nativeSelectValue === (item === null || item === void 0 ? void 0 : item.value);
223
262
  if (shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync) {
224
263
  var _selectElRef_current;
@@ -262,12 +301,9 @@ const filter = (options, inputValue, filterFn)=>{
262
301
  bubbles: true
263
302
  });
264
303
  (_selectElRef_current = selectElRef.current) === null || _selectElRef_current === void 0 ? void 0 : _selectElRef_current.dispatchEvent(event);
265
- setInputValue(calculateInputValueFromOptions(optionsProp, nativeSelectValue));
266
304
  }, [
267
305
  close,
268
- selectElRef,
269
- optionsProp,
270
- nativeSelectValue
306
+ selectElRef
271
307
  ]);
272
308
  const onFocus = React.useCallback(()=>{
273
309
  var _selectElRef_current;
@@ -307,38 +343,21 @@ const filter = (options, inputValue, filterFn)=>{
307
343
  focusedOptionIndex,
308
344
  options
309
345
  ]);
310
- React.useEffect(function filterOptions() {
346
+ React.useEffect(function updateOptionsAndSelectedOptionIndex() {
347
+ var _props_value, _ref;
348
+ const value = (_ref = (_props_value = props.value) !== null && _props_value !== void 0 ? _props_value : nativeSelectValue) !== null && _ref !== void 0 ? _ref : defaultValue;
311
349
  const options = searchable && inputValue !== undefined ? filter(optionsProp, inputValue, filterFn) : optionsProp;
312
350
  setOptions(options);
351
+ setSelectedOptionIndex(findSelectedIndex(options, value, allowClearButton));
313
352
  }, [
314
353
  filterFn,
315
354
  inputValue,
355
+ nativeSelectValue,
316
356
  optionsProp,
317
- searchable
318
- ]);
319
- var _props_value1, _ref;
320
- const selectValue = (_ref = (_props_value1 = props.value) !== null && _props_value1 !== void 0 ? _props_value1 : nativeSelectValue) !== null && _ref !== void 0 ? _ref : defaultValue;
321
- React.useEffect(function updateSelectedOptionIndexOnValueChange() {
322
- setSelectedOptionIndex(findSelectedIndex(options, selectValue, allowClearButton));
323
- }, [
324
- selectValue,
325
- allowClearButton,
326
- options
327
- ]);
328
- const prevSelectValueRef = React.useRef(selectValue);
329
- React.useEffect(function updateInputValueOnSelectValueChange() {
330
- if (prevSelectValueRef.current === selectValue) {
331
- return;
332
- }
333
- setInputValue(calculateInputValueFromOptions(optionsProp, selectValue));
334
- }, [
335
- selectValue,
336
- optionsProp
337
- ]);
338
- React.useEffect(function updatePrevSelectValue() {
339
- prevSelectValueRef.current = selectValue;
340
- }, [
341
- selectValue
357
+ defaultValue,
358
+ props.value,
359
+ searchable,
360
+ allowClearButton
342
361
  ]);
343
362
  const onNativeSelectChange = (e)=>{
344
363
  const newSelectedOptionIndex = findSelectedIndex(options, e.currentTarget.value, allowClearButton);
@@ -602,12 +621,14 @@ const filter = (options, inputValue, filterFn)=>{
602
621
  const selectInputAriaProps = {
603
622
  'role': 'combobox',
604
623
  'aria-controls': popupAriaId,
624
+ 'aria-owns': popupAriaId,
605
625
  'aria-expanded': opened,
606
626
  ['aria-activedescendant']: ariaActiveDescendantId && opened ? `${popupAriaId}-${ariaActiveDescendantId}` : undefined,
607
627
  'aria-labelledby': ariaLabelledBy,
608
628
  'aria-haspopup': 'listbox',
609
629
  'aria-autocomplete': 'none'
610
630
  };
631
+ const focusWithin = useFocusWithin(handleRootRef);
611
632
  return /*#__PURE__*/ _jsxs("div", {
612
633
  className: classNames("vkuiCustomSelect", sizeY !== 'regular' && sizeYClassNames[sizeY], className),
613
634
  style: style,
@@ -615,6 +636,10 @@ const filter = (options, inputValue, filterFn)=>{
615
636
  onClick: passClickAndFocusToInputOnClick,
616
637
  onMouseDown: preventInputBlurWhenClickInsideFocusedSelectArea,
617
638
  children: [
639
+ focusWithin && selected && !opened && /*#__PURE__*/ _jsx(VisuallyHidden, {
640
+ "aria-live": "polite",
641
+ children: selected.label
642
+ }),
618
643
  /*#__PURE__*/ _jsx(CustomSelectInput, _object_spread_props(_object_spread({
619
644
  autoComplete: "off",
620
645
  autoCapitalize: "none",
@@ -625,7 +650,7 @@ const filter = (options, inputValue, filterFn)=>{
625
650
  onFocus: onFocus,
626
651
  onBlur: onBlur,
627
652
  className: openedClassNames,
628
- searchable: searchable,
653
+ readOnly: !searchable,
629
654
  fetching: fetching,
630
655
  value: inputValue,
631
656
  onKeyUp: handleKeyUp,
@@ -635,7 +660,7 @@ const filter = (options, inputValue, filterFn)=>{
635
660
  before: before,
636
661
  after: afterIcons,
637
662
  selectType: selectType,
638
- selectedOptionLabel: selected === null || selected === void 0 ? void 0 : selected.label
663
+ children: selected === null || selected === void 0 ? void 0 : selected.label
639
664
  })),
640
665
  /*#__PURE__*/ _jsxs("select", {
641
666
  ref: selectElRef,