cozy-ui-plus 4.5.1 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/Contacts/AddModal/ContactForm/TextFieldPhone/ButtonBase.js +30 -0
  3. package/dist/Contacts/AddModal/ContactForm/TextFieldPhone/CustomInput.js +25 -0
  4. package/dist/Contacts/AddModal/ContactForm/TextFieldPhone/FlagBottomSheet.js +79 -0
  5. package/dist/Contacts/AddModal/ContactForm/TextFieldPhone/FlagMenu.js +76 -0
  6. package/dist/Contacts/AddModal/ContactForm/TextFieldPhone/index.js +69 -0
  7. package/dist/Contacts/AddModal/ContactForm/fieldsConfig.js +3 -0
  8. package/dist/Contacts/AddModal/mocks.js +3 -3
  9. package/dist/src/Contacts/AddModal/ContactForm/TextFieldPhone/ButtonBase.d.ts +17 -0
  10. package/dist/src/Contacts/AddModal/ContactForm/TextFieldPhone/CustomInput.d.ts +2 -0
  11. package/dist/src/Contacts/AddModal/ContactForm/TextFieldPhone/FlagBottomSheet.d.ts +5 -0
  12. package/dist/src/Contacts/AddModal/ContactForm/TextFieldPhone/FlagMenu.d.ts +5 -0
  13. package/dist/src/Contacts/AddModal/ContactForm/TextFieldPhone/index.d.ts +6 -0
  14. package/jest.config.js +1 -1
  15. package/package.json +3 -4
  16. package/src/Contacts/AddModal/ContactForm/TextFieldPhone/ButtonBase.jsx +19 -0
  17. package/src/Contacts/AddModal/ContactForm/TextFieldPhone/CustomInput.jsx +15 -0
  18. package/src/Contacts/AddModal/ContactForm/TextFieldPhone/FlagBottomSheet.jsx +60 -0
  19. package/src/Contacts/AddModal/ContactForm/TextFieldPhone/FlagMenu.jsx +58 -0
  20. package/src/Contacts/AddModal/ContactForm/TextFieldPhone/index.jsx +42 -0
  21. package/src/Contacts/AddModal/ContactForm/fieldsConfig.jsx +3 -0
  22. package/src/Contacts/AddModal/ContactForm/formValuesToContact.spec.js +1 -1
  23. package/src/Contacts/AddModal/ContactForm/index.spec.jsx +0 -16
  24. package/src/Contacts/AddModal/mocks.js +3 -3
package/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [4.6.0](https://github.com/cozy/cozy-libs/compare/cozy-ui-plus@4.5.1...cozy-ui-plus@4.6.0) (2026-02-19)
7
+
8
+ ### Features
9
+
10
+ - **cozy-ui-plus:** Add menu to select phone number by country ([7750965](https://github.com/cozy/cozy-libs/commit/775096555b17dd2464b5fcad653d58ae8993d0a4))
11
+ - **cozy-ui-plus:** Add react-international-phone package ([c6eaa2e](https://github.com/cozy/cozy-libs/commit/c6eaa2ebf6218cc81ef09c4a415c3ec0d6137436))
12
+ - **cozy-ui-plus:** Add simple small component ([aabfed6](https://github.com/cozy/cozy-libs/commit/aabfed68b92d8ba31868c4e7eebc4ad6043b57b2))
13
+ - **cozy-ui-plus:** Use new textfield for phone number ([6b47fc5](https://github.com/cozy/cozy-libs/commit/6b47fc5b742b9108f35cd0e7164e942669e93c6c))
14
+
6
15
  ## [4.5.1](https://github.com/cozy/cozy-libs/compare/cozy-ui-plus@4.5.0...cozy-ui-plus@4.5.1) (2026-02-03)
7
16
 
8
17
  ### Bug Fixes
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _ButtonBase = _interopRequireDefault(require("cozy-ui/transpiled/react/ButtonBase"));
11
+
12
+ var _styles = require("cozy-ui/transpiled/react/styles");
13
+
14
+ var styles = function styles(theme) {
15
+ return {
16
+ root: {
17
+ '&:hover': {
18
+ textDecoration: 'none',
19
+ backgroundColor: (0, _styles.alpha)(theme.palette.text.primary, theme.palette.action.hoverOpacity),
20
+ '@media (hover: none)': {
21
+ backgroundColor: 'transparent'
22
+ }
23
+ }
24
+ }
25
+ };
26
+ };
27
+
28
+ var _default = (0, _styles.withStyles)(styles)(_ButtonBase.default);
29
+
30
+ exports.default = _default;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
+
12
+ var _react = _interopRequireDefault(require("react"));
13
+
14
+ var _Input = _interopRequireDefault(require("cozy-ui/transpiled/react/Input"));
15
+
16
+ var _ButtonBase = _interopRequireDefault(require("./ButtonBase"));
17
+
18
+ var CustomInput = function CustomInput(props) {
19
+ return /*#__PURE__*/_react.default.createElement(_ButtonBase.default, null, /*#__PURE__*/_react.default.createElement(_Input.default, (0, _extends2.default)({}, props, {
20
+ disableUnderline: true
21
+ })));
22
+ };
23
+
24
+ var _default = CustomInput;
25
+ exports.default = _default;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
+
12
+ var _react = _interopRequireWildcard(require("react"));
13
+
14
+ require("react-international-phone/style.css");
15
+
16
+ var _BottomSheet = _interopRequireWildcard(require("cozy-ui/transpiled/react/BottomSheet"));
17
+
18
+ var _ListItemIcon = _interopRequireDefault(require("cozy-ui/transpiled/react/ListItemIcon"));
19
+
20
+ var _ListItemText = _interopRequireDefault(require("cozy-ui/transpiled/react/ListItemText"));
21
+
22
+ var _MenuItem = _interopRequireDefault(require("cozy-ui/transpiled/react/MenuItem"));
23
+
24
+ var _Typography = _interopRequireDefault(require("cozy-ui/transpiled/react/Typography"));
25
+
26
+ var _ButtonBase = _interopRequireDefault(require("./ButtonBase"));
27
+
28
+ var _reactInternationalPhone = require("react-international-phone");
29
+
30
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
31
+
32
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
33
+
34
+ var FlagBottomSheet = function FlagBottomSheet(_ref) {
35
+ var value = _ref.value,
36
+ setCountry = _ref.setCountry;
37
+
38
+ var _useState = (0, _react.useState)(false),
39
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
40
+ open = _useState2[0],
41
+ setOpen = _useState2[1];
42
+
43
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ButtonBase.default, {
44
+ onClick: function onClick() {
45
+ return setOpen(true);
46
+ }
47
+ }, /*#__PURE__*/_react.default.createElement(_reactInternationalPhone.FlagImage, {
48
+ iso2: value
49
+ })), open && /*#__PURE__*/_react.default.createElement(_BottomSheet.default, {
50
+ backdrop: true,
51
+ onClose: function onClose() {
52
+ return setOpen(false);
53
+ }
54
+ }, /*#__PURE__*/_react.default.createElement(_BottomSheet.BottomSheetItem, null, _reactInternationalPhone.defaultCountries.map(function (c) {
55
+ var _parseCountry = (0, _reactInternationalPhone.parseCountry)(c),
56
+ iso2 = _parseCountry.iso2,
57
+ name = _parseCountry.name,
58
+ dialCode = _parseCountry.dialCode;
59
+
60
+ return /*#__PURE__*/_react.default.createElement(_MenuItem.default, {
61
+ key: iso2,
62
+ value: iso2,
63
+ onClick: function onClick() {
64
+ setCountry(iso2);
65
+ setOpen(false);
66
+ }
67
+ }, /*#__PURE__*/_react.default.createElement(_ListItemIcon.default, null, /*#__PURE__*/_react.default.createElement(_reactInternationalPhone.FlagImage, {
68
+ iso2: iso2
69
+ })), /*#__PURE__*/_react.default.createElement(_ListItemText.default, {
70
+ primary: name
71
+ }), /*#__PURE__*/_react.default.createElement(_Typography.default, {
72
+ className: "u-mr-half",
73
+ align: "right"
74
+ }, "+", dialCode));
75
+ }))));
76
+ };
77
+
78
+ var _default = FlagBottomSheet;
79
+ exports.default = _default;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _react = _interopRequireDefault(require("react"));
11
+
12
+ require("react-international-phone/style.css");
13
+
14
+ var _ListItemIcon = _interopRequireDefault(require("cozy-ui/transpiled/react/ListItemIcon"));
15
+
16
+ var _ListItemText = _interopRequireDefault(require("cozy-ui/transpiled/react/ListItemText"));
17
+
18
+ var _MenuItem = _interopRequireDefault(require("cozy-ui/transpiled/react/MenuItem"));
19
+
20
+ var _Select = _interopRequireDefault(require("cozy-ui/transpiled/react/Select"));
21
+
22
+ var _Typography = _interopRequireDefault(require("cozy-ui/transpiled/react/Typography"));
23
+
24
+ var _CustomInput = _interopRequireDefault(require("./CustomInput"));
25
+
26
+ var _reactInternationalPhone = require("react-international-phone");
27
+
28
+ var FlagMenu = function FlagMenu(_ref) {
29
+ var value = _ref.value,
30
+ setCountry = _ref.setCountry;
31
+ return /*#__PURE__*/_react.default.createElement(_Select.default, {
32
+ input: /*#__PURE__*/_react.default.createElement(_CustomInput.default, null),
33
+ MenuProps: {
34
+ style: {
35
+ height: '300px'
36
+ },
37
+ transformOrigin: {
38
+ vertical: 'top',
39
+ horizontal: 'left'
40
+ }
41
+ },
42
+ value: value,
43
+ renderValue: function renderValue(v) {
44
+ return /*#__PURE__*/_react.default.createElement(_reactInternationalPhone.FlagImage, {
45
+ iso2: v,
46
+ style: {
47
+ verticalAlign: 'bottom',
48
+ marginLeft: '0.5rem'
49
+ }
50
+ });
51
+ },
52
+ onChange: function onChange(e) {
53
+ return setCountry(e.target.value);
54
+ }
55
+ }, _reactInternationalPhone.defaultCountries.map(function (c) {
56
+ var _parseCountry = (0, _reactInternationalPhone.parseCountry)(c),
57
+ iso2 = _parseCountry.iso2,
58
+ name = _parseCountry.name,
59
+ dialCode = _parseCountry.dialCode;
60
+
61
+ return /*#__PURE__*/_react.default.createElement(_MenuItem.default, {
62
+ key: iso2,
63
+ value: iso2
64
+ }, /*#__PURE__*/_react.default.createElement(_ListItemIcon.default, null, /*#__PURE__*/_react.default.createElement(_reactInternationalPhone.FlagImage, {
65
+ iso2: iso2
66
+ })), /*#__PURE__*/_react.default.createElement(_ListItemText.default, {
67
+ primary: name
68
+ }), /*#__PURE__*/_react.default.createElement(_Typography.default, {
69
+ className: "u-mr-half",
70
+ align: "right"
71
+ }, "+", dialCode));
72
+ }));
73
+ };
74
+
75
+ var _default = FlagMenu;
76
+ exports.default = _default;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
+
12
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
13
+
14
+ var _react = _interopRequireDefault(require("react"));
15
+
16
+ var _reactInternationalPhone = require("react-international-phone");
17
+
18
+ var _InputAdornment = _interopRequireDefault(require("cozy-ui/transpiled/react/InputAdornment"));
19
+
20
+ var _TextField = _interopRequireDefault(require("cozy-ui/transpiled/react/TextField"));
21
+
22
+ var _Breakpoints = require("cozy-ui/transpiled/react/providers/Breakpoints");
23
+
24
+ var _FlagBottomSheet = _interopRequireDefault(require("./FlagBottomSheet"));
25
+
26
+ var _FlagMenu = _interopRequireDefault(require("./FlagMenu"));
27
+
28
+ var _excluded = ["value", "onChange"];
29
+
30
+ var TextFieldPhone = function TextFieldPhone(_ref) {
31
+ var value = _ref.value,
32
+ _onChange = _ref.onChange,
33
+ props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
34
+
35
+ var _useBreakpoints = (0, _Breakpoints.useBreakpoints)(),
36
+ isMobile = _useBreakpoints.isMobile;
37
+
38
+ var _usePhoneInput = (0, _reactInternationalPhone.usePhoneInput)({
39
+ defaultCountry: 'fr',
40
+ value: value,
41
+ countries: _reactInternationalPhone.defaultCountries,
42
+ onChange: function onChange(data) {
43
+ _onChange(data.phone);
44
+ }
45
+ }),
46
+ inputValue = _usePhoneInput.inputValue,
47
+ handlePhoneValueChange = _usePhoneInput.handlePhoneValueChange,
48
+ inputRef = _usePhoneInput.inputRef,
49
+ country = _usePhoneInput.country,
50
+ setCountry = _usePhoneInput.setCountry;
51
+
52
+ var ResponsiveFlagMenu = isMobile ? _FlagBottomSheet.default : _FlagMenu.default;
53
+ return /*#__PURE__*/_react.default.createElement(_TextField.default, (0, _extends2.default)({
54
+ value: inputValue,
55
+ inputRef: inputRef,
56
+ InputProps: {
57
+ startAdornment: /*#__PURE__*/_react.default.createElement(_InputAdornment.default, {
58
+ position: "start"
59
+ }, /*#__PURE__*/_react.default.createElement(ResponsiveFlagMenu, {
60
+ value: country.iso2,
61
+ setCountry: setCountry
62
+ }))
63
+ },
64
+ onChange: handlePhoneValueChange
65
+ }, props));
66
+ };
67
+
68
+ var _default = TextFieldPhone;
69
+ exports.default = _default;
@@ -35,6 +35,8 @@ var _Telephone = _interopRequireDefault(require("cozy-ui/transpiled/react/Icons/
35
35
 
36
36
  var _InputAdornment = _interopRequireDefault(require("cozy-ui/transpiled/react/InputAdornment"));
37
37
 
38
+ var _index = _interopRequireDefault(require("./TextFieldPhone/index"));
39
+
38
40
  /**
39
41
  * @type {import('../types').Field[]}
40
42
  */
@@ -82,6 +84,7 @@ var fields = [{
82
84
  icon: _Telephone.default,
83
85
  type: 'tel',
84
86
  layout: 'array',
87
+ component: _index.default,
85
88
  label: {
86
89
  name: 'phoneLabel',
87
90
  select: true,
@@ -72,7 +72,7 @@ var johnDoeContact = {
72
72
  },
73
73
  note: 'Atque cupiditate saepe omnis quos ut molestiae labore voluptates omnis.',
74
74
  phone: [{
75
- number: '+33 (2)0 90 00 54 04',
75
+ number: '+33 2 90 00 54 04',
76
76
  primary: true
77
77
  }, {
78
78
  number: '+33 6 77 11 22 33',
@@ -137,7 +137,7 @@ var johnDoeFormValues = {
137
137
  }],
138
138
  phone: [{
139
139
  fieldId: 'fieldId_5',
140
- phone: '+33 (2)0 90 00 54 04',
140
+ phone: '+33 2 90 00 54 04',
141
141
  phoneLabel: undefined
142
142
  }, {
143
143
  fieldId: 'fieldId_6',
@@ -219,7 +219,7 @@ var johnDoeContactWithRelated = {
219
219
  },
220
220
  note: 'Atque cupiditate saepe omnis quos ut molestiae labore voluptates omnis.',
221
221
  phone: [{
222
- number: '+33 (2)0 90 00 54 04',
222
+ number: '+33 2 90 00 54 04',
223
223
  primary: true
224
224
  }, {
225
225
  number: '+33 6 77 11 22 33',
@@ -0,0 +1,17 @@
1
+ declare const _default: import("react").ComponentType<Pick<{
2
+ action?: import("react").Ref<import("@material-ui/core").ButtonBaseActions>;
3
+ buttonRef?: import("react").Ref<unknown>;
4
+ centerRipple?: boolean;
5
+ children?: import("react").ReactNode;
6
+ disabled?: boolean;
7
+ disableRipple?: boolean;
8
+ disableTouchRipple?: boolean;
9
+ focusRipple?: boolean;
10
+ focusVisibleClassName?: string;
11
+ onFocusVisible?: import("react").FocusEventHandler<any>;
12
+ tabIndex?: string | number;
13
+ TouchRippleProps?: Partial<import("@material-ui/core/ButtonBase/TouchRipple").TouchRippleProps>;
14
+ } & import("@material-ui/core/OverridableComponent").CommonProps<import("@material-ui/core").ExtendButtonBaseTypeMap<import("@material-ui/core").ButtonBaseTypeMap<{}, "button">>> & Pick<Pick<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "key" | keyof import("react").ButtonHTMLAttributes<HTMLButtonElement>> & {
15
+ ref?: import("react").Ref<HTMLButtonElement>;
16
+ }, "name" | "color" | "hidden" | "ref" | "form" | "title" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "id" | "lang" | "placeholder" | "slot" | "spellCheck" | "inputMode" | "is" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "type" | "value" | "autoFocus" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget">, "name" | "color" | "hidden" | "style" | "disabled" | "ref" | "form" | "title" | "children" | "className" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "id" | "lang" | "placeholder" | "slot" | "spellCheck" | "tabIndex" | "inputMode" | "is" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "type" | "value" | "innerRef" | "autoFocus" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "action" | "buttonRef" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "onFocusVisible" | "TouchRippleProps"> & import("@material-ui/styles/withStyles/withStyles").StyledComponentProps<"root">>;
17
+ export default _default;
@@ -0,0 +1,2 @@
1
+ export default CustomInput;
2
+ declare function CustomInput(props: any): JSX.Element;
@@ -0,0 +1,5 @@
1
+ export default FlagBottomSheet;
2
+ declare function FlagBottomSheet({ value, setCountry }: {
3
+ value: any;
4
+ setCountry: any;
5
+ }): JSX.Element;
@@ -0,0 +1,5 @@
1
+ export default FlagMenu;
2
+ declare function FlagMenu({ value, setCountry }: {
3
+ value: any;
4
+ setCountry: any;
5
+ }): JSX.Element;
@@ -0,0 +1,6 @@
1
+ export default TextFieldPhone;
2
+ declare function TextFieldPhone({ value, onChange, ...props }: {
3
+ [x: string]: any;
4
+ value: any;
5
+ onChange: any;
6
+ }): JSX.Element;
package/jest.config.js CHANGED
@@ -5,7 +5,7 @@ module.exports = {
5
5
  moduleDirectories: ['src', 'node_modules'],
6
6
  moduleNameMapper: {
7
7
  '\\.(png|gif|jpe?g|svg)$': '<rootDir>/test/fileMock.js',
8
- '\\.styl$': 'identity-obj-proxy',
8
+ '\\.(styl|css)$': 'identity-obj-proxy',
9
9
  '^cozy-client$': '<rootDir>/node_modules/cozy-client/dist/index',
10
10
  '^cozy-client/dist/types$':
11
11
  '<rootDir>/node_modules/cozy-client/dist/types.js',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui-plus",
3
- "version": "4.5.1",
3
+ "version": "4.6.0",
4
4
  "description": "Cozy-ui-plus is an extension of cozy-ui and provides components based on cozy-client",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",
@@ -44,8 +44,6 @@
44
44
  "node-polyglot": "^2.4.0",
45
45
  "prop-types": "15.8.1",
46
46
  "react": "16.12.0",
47
- "react-dnd": "16.0.1",
48
- "react-dnd-html5-backend": "16.0.1",
49
47
  "react-dom": "16.12.0",
50
48
  "react-test-renderer": "16.12.0",
51
49
  "stylus": "0.64.0",
@@ -62,6 +60,7 @@
62
60
  "mime-types": "2.1.35",
63
61
  "react-final-form": "6.5.9",
64
62
  "react-final-form-arrays": "3.1.4",
63
+ "react-international-phone": "4.7.0",
65
64
  "rooks": "7.14.1"
66
65
  },
67
66
  "peerDependencies": {
@@ -74,5 +73,5 @@
74
73
  "react-dom": "^16 || ^17 || ^18",
75
74
  "twake-i18n": ">=0.3.0"
76
75
  },
77
- "gitHead": "549503df8a2071ff837e672ad5f7019aa122cb1f"
76
+ "gitHead": "8a5f3cb0c64efb15a79cb856927dba5513a94623"
78
77
  }
@@ -0,0 +1,19 @@
1
+ import ButtonBase from 'cozy-ui/transpiled/react/ButtonBase'
2
+ import { alpha, withStyles } from 'cozy-ui/transpiled/react/styles'
3
+
4
+ const styles = theme => ({
5
+ root: {
6
+ '&:hover': {
7
+ textDecoration: 'none',
8
+ backgroundColor: alpha(
9
+ theme.palette.text.primary,
10
+ theme.palette.action.hoverOpacity
11
+ ),
12
+ '@media (hover: none)': {
13
+ backgroundColor: 'transparent'
14
+ }
15
+ }
16
+ }
17
+ })
18
+
19
+ export default withStyles(styles)(ButtonBase)
@@ -0,0 +1,15 @@
1
+ import React from 'react'
2
+
3
+ import Input from 'cozy-ui/transpiled/react/Input'
4
+
5
+ import ButtonBase from './ButtonBase'
6
+
7
+ const CustomInput = props => {
8
+ return (
9
+ <ButtonBase>
10
+ <Input {...props} disableUnderline />
11
+ </ButtonBase>
12
+ )
13
+ }
14
+
15
+ export default CustomInput
@@ -0,0 +1,60 @@
1
+ import React, { useState } from 'react'
2
+ import 'react-international-phone/style.css'
3
+
4
+ import BottomSheet, {
5
+ BottomSheetItem
6
+ } from 'cozy-ui/transpiled/react/BottomSheet'
7
+ import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
8
+ import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
9
+ import MenuItem from 'cozy-ui/transpiled/react/MenuItem'
10
+ import Typography from 'cozy-ui/transpiled/react/Typography'
11
+
12
+ import ButtonBase from './ButtonBase'
13
+
14
+ import {
15
+ defaultCountries,
16
+ FlagImage,
17
+ parseCountry
18
+ } from 'react-international-phone'
19
+
20
+ const FlagBottomSheet = ({ value, setCountry }) => {
21
+ const [open, setOpen] = useState(false)
22
+
23
+ return (
24
+ <>
25
+ <ButtonBase onClick={() => setOpen(true)}>
26
+ <FlagImage iso2={value} />
27
+ </ButtonBase>
28
+
29
+ {open && (
30
+ <BottomSheet backdrop onClose={() => setOpen(false)}>
31
+ <BottomSheetItem>
32
+ {defaultCountries.map(c => {
33
+ const { iso2, name, dialCode } = parseCountry(c)
34
+ return (
35
+ <MenuItem
36
+ key={iso2}
37
+ value={iso2}
38
+ onClick={() => {
39
+ setCountry(iso2)
40
+ setOpen(false)
41
+ }}
42
+ >
43
+ <ListItemIcon>
44
+ <FlagImage iso2={iso2} />
45
+ </ListItemIcon>
46
+ <ListItemText primary={name} />
47
+ <Typography className="u-mr-half" align="right">
48
+ +{dialCode}
49
+ </Typography>
50
+ </MenuItem>
51
+ )
52
+ })}
53
+ </BottomSheetItem>
54
+ </BottomSheet>
55
+ )}
56
+ </>
57
+ )
58
+ }
59
+
60
+ export default FlagBottomSheet
@@ -0,0 +1,58 @@
1
+ import React from 'react'
2
+ import 'react-international-phone/style.css'
3
+
4
+ import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
5
+ import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
6
+ import MenuItem from 'cozy-ui/transpiled/react/MenuItem'
7
+ import Select from 'cozy-ui/transpiled/react/Select'
8
+ import Typography from 'cozy-ui/transpiled/react/Typography'
9
+
10
+ import CustomInput from './CustomInput'
11
+
12
+ import {
13
+ defaultCountries,
14
+ FlagImage,
15
+ parseCountry
16
+ } from 'react-international-phone'
17
+
18
+ const FlagMenu = ({ value, setCountry }) => {
19
+ return (
20
+ <Select
21
+ input={<CustomInput />}
22
+ MenuProps={{
23
+ style: {
24
+ height: '300px'
25
+ },
26
+ transformOrigin: {
27
+ vertical: 'top',
28
+ horizontal: 'left'
29
+ }
30
+ }}
31
+ value={value}
32
+ renderValue={v => (
33
+ <FlagImage
34
+ iso2={v}
35
+ style={{ verticalAlign: 'bottom', marginLeft: '0.5rem' }}
36
+ />
37
+ )}
38
+ onChange={e => setCountry(e.target.value)}
39
+ >
40
+ {defaultCountries.map(c => {
41
+ const { iso2, name, dialCode } = parseCountry(c)
42
+ return (
43
+ <MenuItem key={iso2} value={iso2}>
44
+ <ListItemIcon>
45
+ <FlagImage iso2={iso2} />
46
+ </ListItemIcon>
47
+ <ListItemText primary={name} />
48
+ <Typography className="u-mr-half" align="right">
49
+ +{dialCode}
50
+ </Typography>
51
+ </MenuItem>
52
+ )
53
+ })}
54
+ </Select>
55
+ )
56
+ }
57
+
58
+ export default FlagMenu
@@ -0,0 +1,42 @@
1
+ import React from 'react'
2
+ import { defaultCountries, usePhoneInput } from 'react-international-phone'
3
+
4
+ import InputAdornment from 'cozy-ui/transpiled/react/InputAdornment'
5
+ import TextField from 'cozy-ui/transpiled/react/TextField'
6
+ import { useBreakpoints } from 'cozy-ui/transpiled/react/providers/Breakpoints'
7
+
8
+ import FlagBottomSheet from './FlagBottomSheet'
9
+ import FlagMenu from './FlagMenu'
10
+
11
+ const TextFieldPhone = ({ value, onChange, ...props }) => {
12
+ const { isMobile } = useBreakpoints()
13
+ const { inputValue, handlePhoneValueChange, inputRef, country, setCountry } =
14
+ usePhoneInput({
15
+ defaultCountry: 'fr',
16
+ value,
17
+ countries: defaultCountries,
18
+ onChange: data => {
19
+ onChange(data.phone)
20
+ }
21
+ })
22
+
23
+ const ResponsiveFlagMenu = isMobile ? FlagBottomSheet : FlagMenu
24
+
25
+ return (
26
+ <TextField
27
+ value={inputValue}
28
+ inputRef={inputRef}
29
+ InputProps={{
30
+ startAdornment: (
31
+ <InputAdornment position="start">
32
+ <ResponsiveFlagMenu value={country.iso2} setCountry={setCountry} />
33
+ </InputAdornment>
34
+ )
35
+ }}
36
+ onChange={handlePhoneValueChange}
37
+ {...props}
38
+ />
39
+ )
40
+ }
41
+
42
+ export default TextFieldPhone
@@ -14,6 +14,8 @@ import RelationshipIcon from 'cozy-ui/transpiled/react/Icons/Relationship'
14
14
  import TelephoneIcon from 'cozy-ui/transpiled/react/Icons/Telephone'
15
15
  import InputAdornment from 'cozy-ui/transpiled/react/InputAdornment'
16
16
 
17
+ import TextFieldPhone from './TextFieldPhone/index'
18
+
17
19
  /**
18
20
  * @type {import('../types').Field[]}
19
21
  */
@@ -74,6 +76,7 @@ export const fields = [
74
76
  icon: TelephoneIcon,
75
77
  type: 'tel',
76
78
  layout: 'array',
79
+ component: TextFieldPhone,
77
80
  label: {
78
81
  name: 'phoneLabel',
79
82
  select: true,
@@ -107,7 +107,7 @@ describe('formValuesToContact', () => {
107
107
  note: 'Atque cupiditate saepe omnis quos ut molestiae labore voluptates omnis.',
108
108
  phone: [
109
109
  {
110
- number: '+33 (2)0 90 00 54 04',
110
+ number: '+33 2 90 00 54 04',
111
111
  primary: true,
112
112
  type: undefined,
113
113
  label: undefined
@@ -211,22 +211,6 @@ describe('ContactForm', () => {
211
211
  expect(screen.queryByDisplayValue(testFields['Notes'])).not.toBeNull()
212
212
  })
213
213
 
214
- it('should not submit empty fields', () => {
215
- const onSubmit = jest.fn()
216
-
217
- render(
218
- <DemoProvider>
219
- <ContactForm onSubmit={onSubmit} onCancel={() => {}} />
220
- </DemoProvider>
221
- )
222
-
223
- act(() => {
224
- fireEvent.submit(screen.getByRole('form'))
225
- })
226
-
227
- expect(onSubmit).not.toBeCalled()
228
- })
229
-
230
214
  describe('isSameContactProp', () => {
231
215
  it('should return true if contacts have the same "related" relationships', () => {
232
216
  const prevProps = {
@@ -80,7 +80,7 @@ export const johnDoeContact = {
80
80
  note: 'Atque cupiditate saepe omnis quos ut molestiae labore voluptates omnis.',
81
81
  phone: [
82
82
  {
83
- number: '+33 (2)0 90 00 54 04',
83
+ number: '+33 2 90 00 54 04',
84
84
  primary: true
85
85
  },
86
86
  {
@@ -155,7 +155,7 @@ export const johnDoeFormValues = {
155
155
  phone: [
156
156
  {
157
157
  fieldId: 'fieldId_5',
158
- phone: '+33 (2)0 90 00 54 04',
158
+ phone: '+33 2 90 00 54 04',
159
159
  phoneLabel: undefined
160
160
  },
161
161
  {
@@ -254,7 +254,7 @@ export const johnDoeContactWithRelated = {
254
254
  note: 'Atque cupiditate saepe omnis quos ut molestiae labore voluptates omnis.',
255
255
  phone: [
256
256
  {
257
- number: '+33 (2)0 90 00 54 04',
257
+ number: '+33 2 90 00 54 04',
258
258
  primary: true
259
259
  },
260
260
  {