cozy-ui 146.3.0 → 146.3.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,11 @@
1
+ ## [146.3.1](https://github.com/cozy/cozy-ui/compare/v146.3.0...v146.3.1) (2026-11-03)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **MemberAutocomplete:** Enable Send only for a text giving members ([6ffaeb0](https://github.com/cozy/cozy-ui/commit/6ffaeb0))
7
+ * **MuiCozyTheme:** Stop the CircularProgress animation in screenshots ([d5025ad](https://github.com/cozy/cozy-ui/commit/d5025ad))
8
+
1
9
  # [146.3.0](https://github.com/cozy/cozy-ui/compare/v146.2.2...v146.3.0) (2026-11-03)
2
10
 
3
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "146.3.0",
3
+ "version": "146.3.1",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "engines": {
6
6
  "node": "24.x"
@@ -80,4 +80,28 @@ describe('MemberAutocomplete', () => {
80
80
 
81
81
  expect(input.value).toBe('bo')
82
82
  })
83
+
84
+ it('enables Send only for a typed text that gives members', () => {
85
+ const getMembersWithDomain = text =>
86
+ (text.match(/\S+@\S+\.\S+/g) || []).map(email => ({ id: email }))
87
+ render(
88
+ <DemoProvider>
89
+ <MemberAutocomplete
90
+ value={[]}
91
+ getMembersFromText={getMembersWithDomain}
92
+ placeholder="Add people"
93
+ onChange={() => {}}
94
+ onSubmit={() => {}}
95
+ />
96
+ </DemoProvider>
97
+ )
98
+ const input = screen.getByPlaceholderText('Add people')
99
+ const send = screen.getByRole('button', { name: 'Send' })
100
+
101
+ fireEvent.change(input, { target: { value: 'bob@example' } })
102
+ expect(send).toBeDisabled()
103
+
104
+ fireEvent.change(input, { target: { value: 'bob@example.com' } })
105
+ expect(send).toBeEnabled()
106
+ })
83
107
  })
@@ -6,7 +6,7 @@ import { useI18n, useExtendI18n } from 'twake-i18n'
6
6
  import MemberAutocompleteActions from './MemberAutocompleteActions'
7
7
  import MemberChip from './MemberChip'
8
8
  import MemberSuggestion from './MemberSuggestion'
9
- import { getUnpickedMembers, isEmailLike } from './helpers'
9
+ import { getUnpickedMembers } from './helpers'
10
10
  import { locales } from './locales'
11
11
  import { useMemberInput } from './useMemberInput'
12
12
  import { useMemberSuggestions } from './useMemberSuggestions'
@@ -89,6 +89,7 @@ const MemberAutocomplete = ({
89
89
  debounceMs
90
90
  })
91
91
  const {
92
+ isTextAddedOnBlur,
92
93
  handleChange,
93
94
  handleInputChange,
94
95
  handleKeyDown,
@@ -112,7 +113,7 @@ const MemberAutocomplete = ({
112
113
  const titleId = `${inputId}-title`
113
114
  const isTitleShown = title !== undefined
114
115
  const isSubmitShown = onSubmit !== undefined
115
- const hasMembersToSend = value.length > 0 || isEmailLike(inputValue)
116
+ const hasMembersToSend = value.length > 0 || isTextAddedOnBlur
116
117
  const isLoading = loading || isFetching
117
118
  const unpickedSuggestions = getUnpickedMembers(suggestions, value)
118
119
  const fieldPlaceholder = value.length === 0 ? placeholder : undefined
@@ -64,13 +64,17 @@ export const useMemberInput = ({
64
64
  }
65
65
  }
66
66
 
67
+ const isTextAddedOnBlur =
68
+ isEmailLike(inputValue) && getKnownMembersFromText(inputValue).length > 0
69
+
67
70
  const handleBlur = () => {
68
- if (isEmailLike(inputValue) && addMembersFromText(inputValue)) {
71
+ if (isTextAddedOnBlur && addMembersFromText(inputValue)) {
69
72
  onInputValueChange('')
70
73
  }
71
74
  }
72
75
 
73
76
  return {
77
+ isTextAddedOnBlur,
74
78
  handleChange,
75
79
  handleInputChange,
76
80
  handleKeyDown,
@@ -35,6 +35,14 @@ const themesCommonConfig = {
35
35
  ...(isTesting() && { transitions: { create: () => 'none' } })
36
36
  }
37
37
 
38
+ // Keyframe animations ignore `transitions`, so they would change each screenshot
39
+ const testingOverrides = {
40
+ MuiCircularProgress: {
41
+ indeterminate: { animation: 'none' },
42
+ circleIndeterminate: { animation: 'none' }
43
+ }
44
+ }
45
+
38
46
  export const makeTheme = type => {
39
47
  // to hold the values of css variables, recoverable by getCssVariableValue()
40
48
  createNodeWithThemeCssVars(type)
@@ -48,7 +56,10 @@ export const makeTheme = type => {
48
56
  palette
49
57
  })
50
58
 
51
- const overrides = makeOverridesByTheme(theme)[type]
59
+ const overrides = {
60
+ ...makeOverridesByTheme(theme)[type],
61
+ ...(isTesting() && testingOverrides)
62
+ }
52
63
 
53
64
  return {
54
65
  ...theme,
@@ -13,7 +13,7 @@ import { useI18n, useExtendI18n } from 'twake-i18n';
13
13
  import MemberAutocompleteActions from "cozy-ui/transpiled/react/MemberAutocomplete/MemberAutocompleteActions";
14
14
  import MemberChip from "cozy-ui/transpiled/react/MemberAutocomplete/MemberChip";
15
15
  import MemberSuggestion from "cozy-ui/transpiled/react/MemberAutocomplete/MemberSuggestion";
16
- import { getUnpickedMembers, isEmailLike } from "cozy-ui/transpiled/react/MemberAutocomplete/helpers";
16
+ import { getUnpickedMembers } from "cozy-ui/transpiled/react/MemberAutocomplete/helpers";
17
17
  import { locales } from "cozy-ui/transpiled/react/MemberAutocomplete/locales";
18
18
  import { useMemberInput } from "cozy-ui/transpiled/react/MemberAutocomplete/useMemberInput";
19
19
  import { useMemberSuggestions } from "cozy-ui/transpiled/react/MemberAutocomplete/useMemberSuggestions";
@@ -133,6 +133,7 @@ var MemberAutocomplete = function MemberAutocomplete(_ref2) {
133
133
  onInputValueChange: setInputValue,
134
134
  onChange: onChange
135
135
  }),
136
+ isTextAddedOnBlur = _useMemberInput.isTextAddedOnBlur,
136
137
  handleChange = _useMemberInput.handleChange,
137
138
  handleInputChange = _useMemberInput.handleInputChange,
138
139
  handleKeyDown = _useMemberInput.handleKeyDown,
@@ -148,7 +149,7 @@ var MemberAutocomplete = function MemberAutocomplete(_ref2) {
148
149
  var titleId = "".concat(inputId, "-title");
149
150
  var isTitleShown = title !== undefined;
150
151
  var isSubmitShown = onSubmit !== undefined;
151
- var hasMembersToSend = value.length > 0 || isEmailLike(inputValue);
152
+ var hasMembersToSend = value.length > 0 || isTextAddedOnBlur;
152
153
  var isLoading = loading || isFetching;
153
154
  var unpickedSuggestions = getUnpickedMembers(suggestions, value);
154
155
  var fieldPlaceholder = value.length === 0 ? placeholder : undefined;
@@ -6,6 +6,7 @@ export function useMemberInput({ inputValue, value, suggestions, getMembersFromT
6
6
  onInputValueChange: Function;
7
7
  onChange: Function;
8
8
  }): {
9
+ isTextAddedOnBlur: boolean;
9
10
  handleChange: (event: any, newValue: any, reason: any) => void;
10
11
  handleInputChange: (event: any, newInputValue: any, reason: any) => void;
11
12
  handleKeyDown: (event: any) => void;
@@ -60,13 +60,16 @@ export var useMemberInput = function useMemberInput(_ref) {
60
60
  }
61
61
  };
62
62
 
63
+ var isTextAddedOnBlur = isEmailLike(inputValue) && getKnownMembersFromText(inputValue).length > 0;
64
+
63
65
  var handleBlur = function handleBlur() {
64
- if (isEmailLike(inputValue) && addMembersFromText(inputValue)) {
66
+ if (isTextAddedOnBlur && addMembersFromText(inputValue)) {
65
67
  onInputValueChange('');
66
68
  }
67
69
  };
68
70
 
69
71
  return {
72
+ isTextAddedOnBlur: isTextAddedOnBlur,
70
73
  handleChange: handleChange,
71
74
  handleInputChange: handleInputChange,
72
75
  handleKeyDown: handleKeyDown,
@@ -43,8 +43,19 @@ var themesCommonConfig = _objectSpread({
43
43
  return 'none';
44
44
  }
45
45
  }
46
- });
46
+ }); // Keyframe animations ignore `transitions`, so they would change each screenshot
47
47
 
48
+
49
+ var testingOverrides = {
50
+ MuiCircularProgress: {
51
+ indeterminate: {
52
+ animation: 'none'
53
+ },
54
+ circleIndeterminate: {
55
+ animation: 'none'
56
+ }
57
+ }
58
+ };
48
59
  export var makeTheme = function makeTheme(type) {
49
60
  // to hold the values of css variables, recoverable by getCssVariableValue()
50
61
  createNodeWithThemeCssVars(type);
@@ -55,7 +66,9 @@ export var makeTheme = function makeTheme(type) {
55
66
  type: type,
56
67
  palette: palette
57
68
  }));
58
- var overrides = makeOverridesByTheme(theme)[type];
69
+
70
+ var overrides = _objectSpread(_objectSpread({}, makeOverridesByTheme(theme)[type]), isTesting() && testingOverrides);
71
+
59
72
  return _objectSpread(_objectSpread({}, theme), {}, {
60
73
  overrides: overrides
61
74
  });