cozy-ui 130.5.0 → 130.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [130.6.1](https://github.com/cozy/cozy-ui/compare/v130.6.0...v130.6.1) (2025-10-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **AddModal/ContactForm:** Custom label now display correctly unsupported label ([8f81a8a](https://github.com/cozy/cozy-ui/commit/8f81a8a))
7
+
8
+ # [130.6.0](https://github.com/cozy/cozy-ui/compare/v130.5.0...v130.6.0) (2025-10-02)
9
+
10
+
11
+ ### Features
12
+
13
+ * **AlertProvider:** Add `noClickAway` and `noTimeOut` prop ([eee29d0](https://github.com/cozy/cozy-ui/commit/eee29d0))
14
+
1
15
  # [130.5.0](https://github.com/cozy/cozy-ui/compare/v130.4.0...v130.5.0) (2025-10-01)
2
16
 
3
17
 
package/CODEOWNERS CHANGED
@@ -1,2 +1,2 @@
1
1
  # General code owners
2
- * @JF-Cozy @Merkur39 @Ldoppea @zatteo
2
+ * @JF-Cozy @rezk2ll @zatteo
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "130.5.0",
3
+ "version": "130.6.1",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -117,6 +117,12 @@ describe('formValuesToContact', () => {
117
117
  primary: false,
118
118
  type: undefined,
119
119
  label: undefined
120
+ },
121
+ {
122
+ label: 'Mobile',
123
+ number: '0876467998',
124
+ primary: false,
125
+ type: 'mobile'
120
126
  }
121
127
  ],
122
128
  relationships: {
@@ -271,12 +271,17 @@ export const removeField = (fields, index) => {
271
271
  export const makeCustomLabel = (value, t) => {
272
272
  const { type, label } = JSON.parse(value)
273
273
 
274
+ const isSupportedLabel = ['home', 'work'].includes(label)
275
+
274
276
  const firstString = type || ''
275
- const secondString = label
276
- ? type
277
- ? ` (${t(`Contacts.AddModal.ContactForm.label.${label}`)})`.toLowerCase()
278
- : `label.${label}`
279
- : ''
277
+ const secondString =
278
+ label && isSupportedLabel
279
+ ? type
280
+ ? ` (${t(
281
+ `Contacts.AddModal.ContactForm.label.${label}`
282
+ )})`.toLowerCase()
283
+ : `label.${label}`
284
+ : ''
280
285
 
281
286
  return firstString + secondString || null
282
287
  }
@@ -1,10 +1,45 @@
1
+ import get from 'lodash/get'
2
+
1
3
  import {
2
4
  moveToHead,
3
5
  makeItemLabel,
4
6
  makeTypeAndLabel,
5
7
  makeImppValues,
8
+ makeCustomLabel,
6
9
  makeInitialCustomValue
7
10
  } from './helpers'
11
+ import { locales } from './locales'
12
+
13
+ const t = x => get(locales.en, x)
14
+
15
+ describe('makeCustomLabel', () => {
16
+ it('should return custom type and supported label', () => {
17
+ const resForWork = makeCustomLabel('{"type":"someType","label":"work"}', t)
18
+ expect(resForWork).toBe('someType (pro)')
19
+
20
+ const resForHome = makeCustomLabel('{"type":"someType","label":"home"}', t)
21
+ expect(resForHome).toBe('someType (personal)')
22
+ })
23
+
24
+ it('should return label if no type', () => {
25
+ const resForWork = makeCustomLabel('{"label":"work"}', t)
26
+ expect(resForWork).toBe('label.work')
27
+
28
+ const resForHome = makeCustomLabel('{"label":"home"}', t)
29
+ expect(resForHome).toBe('label.home')
30
+ })
31
+
32
+ it('should return only custom type if label is not supported or undefined', () => {
33
+ const resForNotSupported = makeCustomLabel(
34
+ '{"type":"someType","label":"someLabel"}',
35
+ t
36
+ )
37
+ expect(resForNotSupported).toBe('someType')
38
+
39
+ const resForUndefined = makeCustomLabel('{"type":"someType"}', t)
40
+ expect(resForUndefined).toBe('someType')
41
+ })
42
+ })
8
43
 
9
44
  describe('moveToHead function', () => {
10
45
  it('should move an item to head of the array', () => {
@@ -86,6 +86,12 @@ export const johnDoeContact = {
86
86
  {
87
87
  number: '+33 6 77 11 22 33',
88
88
  primary: false
89
+ },
90
+ {
91
+ label: 'Mobile', // could be this when importing from other sources i.e. google
92
+ number: '0876467998',
93
+ primary: false,
94
+ type: 'mobile'
89
95
  }
90
96
  ]
91
97
  }
@@ -156,6 +162,11 @@ export const johnDoeFormValues = {
156
162
  fieldId: 'fieldId_6',
157
163
  phone: '+33 6 77 11 22 33',
158
164
  phoneLabel: undefined
165
+ },
166
+ {
167
+ fieldId: 'fieldId_7',
168
+ phone: '0876467998',
169
+ phoneLabel: '{"type":"mobile","label":"Mobile"}'
159
170
  }
160
171
  ],
161
172
  givenName: 'John',
@@ -15,6 +15,8 @@ const initialVariants = [{
15
15
  square: false,
16
16
  standard: false,
17
17
  outlined: false,
18
+ noClickAway: false,
19
+ noTimeOut: false,
18
20
  close: true
19
21
  }]
20
22
 
@@ -23,7 +25,7 @@ const Component = ({ variant }) => {
23
25
 
24
26
  return (
25
27
  <Button
26
- label="show alert"
28
+ label="Show alert"
27
29
  onClick={() =>
28
30
  showAlert({
29
31
  title: variant.title ? 'Alert title' : undefined,
@@ -42,6 +44,8 @@ const Component = ({ variant }) => {
42
44
  : variant.largeIcon
43
45
  ? <Icon icon={DeviceLaptopIcon} size={32} />
44
46
  : undefined,
47
+ noClickAway: variant.noClickAway,
48
+ noTimeOut: variant.noTimeOut,
45
49
  onClose: variant.close ? () => {} : undefined
46
50
  })
47
51
  }
@@ -0,0 +1,13 @@
1
+ export const handleClose = (state, setState) => (event, reason) => {
2
+ const { noClickAway, noTimeOut } = state
3
+
4
+ if (reason === 'clickaway' && noClickAway) {
5
+ return
6
+ }
7
+
8
+ if (reason === 'timeout' && noTimeOut) {
9
+ return
10
+ }
11
+
12
+ return setState({ ...state, open: false })
13
+ }
@@ -1,5 +1,6 @@
1
1
  import React, { createContext, useState, useContext, useMemo } from 'react'
2
2
 
3
+ import { handleClose } from './helpers'
3
4
  import Alert from '../../Alert'
4
5
  import AlertTitle from '../../AlertTitle'
5
6
  import Snackbar from '../../Snackbar'
@@ -32,13 +33,19 @@ const defaultState = {
32
33
  duration: null,
33
34
  open: false
34
35
  }
35
- const handleClose = (state, setState) => () => {
36
- return setState({ ...state, open: false })
37
- }
38
36
 
39
37
  const AlertProvider = ({ children }) => {
40
38
  const [state, setState] = useState(defaultState)
41
- const { open, message, title, duration, ...alertProps } = state
39
+ // noTimeOut and noClickAway are destructured to not being passed to the DOM through ...alertProps
40
+ const {
41
+ open,
42
+ message,
43
+ title,
44
+ duration,
45
+ noTimeOut, // eslint-disable-line no-unused-vars
46
+ noClickAway, // eslint-disable-line no-unused-vars
47
+ ...alertProps
48
+ } = state
42
49
 
43
50
  const value = useMemo(
44
51
  () => ({
@@ -63,7 +70,7 @@ const AlertProvider = ({ children }) => {
63
70
  <Alert
64
71
  variant="filled"
65
72
  elevation={6}
66
- onClose={handleClose(state, setState)}
73
+ onClose={ev => handleClose(state, setState)(ev, 'click')}
67
74
  {...alertProps}
68
75
  >
69
76
  {title && <AlertTitle>{title}</AlertTitle>}
@@ -278,8 +278,9 @@ export var makeCustomLabel = function makeCustomLabel(value, t) {
278
278
  type = _JSON$parse.type,
279
279
  label = _JSON$parse.label;
280
280
 
281
+ var isSupportedLabel = ['home', 'work'].includes(label);
281
282
  var firstString = type || '';
282
- var secondString = label ? type ? " (".concat(t("Contacts.AddModal.ContactForm.label.".concat(label)), ")").toLowerCase() : "label.".concat(label) : '';
283
+ var secondString = label && isSupportedLabel ? type ? " (".concat(t("Contacts.AddModal.ContactForm.label.".concat(label)), ")").toLowerCase() : "label.".concat(label) : '';
283
284
  return firstString + secondString || null;
284
285
  };
285
286
  /**
@@ -66,10 +66,17 @@ export namespace johnDoeContact {
66
66
  export const version: number;
67
67
  }
68
68
  const note: string;
69
- const phone: {
69
+ const phone: ({
70
70
  number: string;
71
71
  primary: boolean;
72
- }[];
72
+ label?: undefined;
73
+ type?: undefined;
74
+ } | {
75
+ label: string;
76
+ number: string;
77
+ primary: boolean;
78
+ type: string;
79
+ })[];
73
80
  }
74
81
  export namespace johnDoeFormValues {
75
82
  const birthday_1: string;
@@ -126,11 +133,15 @@ export namespace johnDoeFormValues {
126
133
  emailLabel: string;
127
134
  })[];
128
135
  export { email_1 as email };
129
- const phone_1: {
136
+ const phone_1: ({
130
137
  fieldId: string;
131
138
  phone: string;
132
139
  phoneLabel: undefined;
133
- }[];
140
+ } | {
141
+ fieldId: string;
142
+ phone: string;
143
+ phoneLabel: string;
144
+ })[];
134
145
  export { phone_1 as phone };
135
146
  const givenName_1: string;
136
147
  export { givenName_1 as givenName };
@@ -71,6 +71,12 @@ export var johnDoeContact = {
71
71
  }, {
72
72
  number: '+33 6 77 11 22 33',
73
73
  primary: false
74
+ }, {
75
+ label: 'Mobile',
76
+ // could be this when importing from other sources i.e. google
77
+ number: '0876467998',
78
+ primary: false,
79
+ type: 'mobile'
74
80
  }]
75
81
  };
76
82
  export var johnDoeFormValues = {
@@ -130,6 +136,10 @@ export var johnDoeFormValues = {
130
136
  fieldId: 'fieldId_6',
131
137
  phone: '+33 6 77 11 22 33',
132
138
  phoneLabel: undefined
139
+ }, {
140
+ fieldId: 'fieldId_7',
141
+ phone: '0876467998',
142
+ phoneLabel: '{"type":"mobile","label":"Mobile"}'
133
143
  }],
134
144
  givenName: 'John',
135
145
  additionalName: 'J.',
@@ -0,0 +1 @@
1
+ export function handleClose(state: any, setState: any): (event: any, reason: any) => any;
@@ -0,0 +1,24 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+
3
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
4
+
5
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
+
7
+ export var handleClose = function handleClose(state, setState) {
8
+ return function (event, reason) {
9
+ var noClickAway = state.noClickAway,
10
+ noTimeOut = state.noTimeOut;
11
+
12
+ if (reason === 'clickaway' && noClickAway) {
13
+ return;
14
+ }
15
+
16
+ if (reason === 'timeout' && noTimeOut) {
17
+ return;
18
+ }
19
+
20
+ return setState(_objectSpread(_objectSpread({}, state), {}, {
21
+ open: false
22
+ }));
23
+ };
24
+ };
@@ -1,14 +1,15 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
3
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
4
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
- var _excluded = ["open", "message", "title", "duration"];
5
+ var _excluded = ["open", "message", "title", "duration", "noTimeOut", "noClickAway"];
6
6
 
7
7
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
8
8
 
9
9
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
10
10
 
11
11
  import React, { createContext, useState, useContext, useMemo } from 'react';
12
+ import { handleClose } from "cozy-ui/transpiled/react/providers/Alert/helpers";
12
13
  import Alert from "cozy-ui/transpiled/react/Alert";
13
14
  import AlertTitle from "cozy-ui/transpiled/react/AlertTitle";
14
15
  import Snackbar from "cozy-ui/transpiled/react/Snackbar";
@@ -42,26 +43,21 @@ var defaultState = {
42
43
  open: false
43
44
  };
44
45
 
45
- var handleClose = function handleClose(state, setState) {
46
- return function () {
47
- return setState(_objectSpread(_objectSpread({}, state), {}, {
48
- open: false
49
- }));
50
- };
51
- };
52
-
53
46
  var AlertProvider = function AlertProvider(_ref) {
54
47
  var children = _ref.children;
55
48
 
56
49
  var _useState = useState(defaultState),
57
50
  _useState2 = _slicedToArray(_useState, 2),
58
51
  state = _useState2[0],
59
- setState = _useState2[1];
52
+ setState = _useState2[1]; // noTimeOut and noClickAway are destructured to not being passed to the DOM through ...alertProps
53
+
60
54
 
61
55
  var open = state.open,
62
56
  message = state.message,
63
57
  title = state.title,
64
58
  duration = state.duration,
59
+ noTimeOut = state.noTimeOut,
60
+ noClickAway = state.noClickAway,
65
61
  alertProps = _objectWithoutProperties(state, _excluded);
66
62
 
67
63
  var value = useMemo(function () {
@@ -85,7 +81,9 @@ var AlertProvider = function AlertProvider(_ref) {
85
81
  }, /*#__PURE__*/React.createElement(Alert, _extends({
86
82
  variant: "filled",
87
83
  elevation: 6,
88
- onClose: handleClose(state, setState)
84
+ onClose: function onClose(ev) {
85
+ return handleClose(state, setState)(ev, 'click');
86
+ }
89
87
  }, alertProps), title && /*#__PURE__*/React.createElement(AlertTitle, null, title), message)));
90
88
  };
91
89