cozy-ui 80.0.0 → 80.0.2

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
+ ## [80.0.2](https://github.com/cozy/cozy-ui/compare/v80.0.1...v80.0.2) (2023-01-19)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Force formatLocallyDistanceToNowStrict to use whole number of day ([a30442f](https://github.com/cozy/cozy-ui/commit/a30442f))
7
+
8
+ ## [80.0.1](https://github.com/cozy/cozy-ui/compare/v80.0.0...v80.0.1) (2023-01-19)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **IllustrationDialog:** The title was not centered properly ([584a58c](https://github.com/cozy/cozy-ui/commit/584a58c))
14
+
1
15
  # [80.0.0](https://github.com/cozy/cozy-ui/compare/v79.5.0...v80.0.0) (2023-01-18)
2
16
 
3
17
 
package/jest.config.js ADDED
@@ -0,0 +1,27 @@
1
+ process.env.TZ = 'UTC'
2
+
3
+ module.exports = {
4
+ testURL: 'http://localhost/',
5
+ moduleFileExtensions: ['js', 'jsx', 'json', 'styl', 'ts', 'tsx'],
6
+ setupFilesAfterEnv: ['./test/jestsetup.js', 'jest-canvas-mock'],
7
+ moduleDirectories: ['node_modules', 'src', 'react-styleguidist/lib'],
8
+ moduleNameMapper: {
9
+ '\\.(png|gif|jpe?g|svg)$': '<rootDir>/test/__mocks__/fileMock.js',
10
+ '\\.styl$': 'identity-obj-proxy',
11
+ 'react-styleguidist.+\\.jsx?$': 'babel-jest',
12
+ '^rsg-components(.*)$':
13
+ '<rootDir>/node_modules/react-styleguidist/lib/client/rsg-components$1',
14
+ 'react-pdf/dist/entry.webpack.js': 'react-pdf',
15
+ '^cozy-client$': 'cozy-client/dist/index'
16
+ },
17
+ transformIgnorePatterns: ['node_modules/(?!(react-styleguidist)/)'],
18
+ testPathIgnorePatterns: ['/node_modules/', '/transpiled/', '/dist/'],
19
+ transform: {
20
+ '^.+\\.(ts|tsx|js|jsx)?$': 'babel-jest'
21
+ },
22
+ globals: {
23
+ __ALLOW_HTTP__: false,
24
+ cozy: {}
25
+ },
26
+ snapshotSerializers: ['enzyme-to-json/serializer']
27
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "80.0.0",
3
+ "version": "80.0.2",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -121,6 +121,7 @@
121
121
  "lodash": "4.17.21",
122
122
  "michelangelo": "https://github.com/cozy/michelangelo.git",
123
123
  "mini-css-extract-plugin": "0.6.0",
124
+ "mockdate": "^3.0.5",
124
125
  "nodemon": "1.19.4",
125
126
  "npm-run-all": "4.1.5",
126
127
  "postcss-cli": "6.1.3",
@@ -203,52 +204,6 @@
203
204
  "cozy"
204
205
  ]
205
206
  },
206
- "jest": {
207
- "setupFilesAfterEnv": [
208
- "./test/jestsetup.js",
209
- "jest-canvas-mock"
210
- ],
211
- "moduleFileExtensions": [
212
- "js",
213
- "jsx",
214
- "json",
215
- "styl",
216
- "ts",
217
- "tsx"
218
- ],
219
- "testPathIgnorePatterns": [
220
- "/node_modules/",
221
- "/transpiled/",
222
- "/dist/"
223
- ],
224
- "moduleDirectories": [
225
- "node_modules",
226
- "src",
227
- "react-styleguidist/lib"
228
- ],
229
- "transform": {
230
- "^.+\\.(ts|tsx|js|jsx)?$": "babel-jest"
231
- },
232
- "transformIgnorePatterns": [
233
- "node_modules/(?!(react-styleguidist)/)"
234
- ],
235
- "moduleNameMapper": {
236
- "\\.(png|gif|jpe?g|svg)$": "<rootDir>/test/__mocks__/fileMock.js",
237
- "\\.styl$": "identity-obj-proxy",
238
- "react-styleguidist.+\\.jsx?$": "babel-jest",
239
- "^rsg-components(.*)$": "<rootDir>/node_modules/react-styleguidist/lib/client/rsg-components$1",
240
- "react-pdf/dist/entry.webpack.js": "react-pdf",
241
- "^cozy-client$": "cozy-client/dist/index"
242
- },
243
- "globals": {
244
- "__ALLOW_HTTP__": false,
245
- "cozy": {}
246
- },
247
- "testURL": "http://localhost/",
248
- "snapshotSerializers": [
249
- "enzyme-to-json/serializer"
250
- ]
251
- },
252
207
  "browserslist": [
253
208
  "extends browserslist-config-cozy"
254
209
  ]
@@ -17,7 +17,11 @@ const IllustrationDialog = props => {
17
17
  fullScreen,
18
18
  dialogActionsProps,
19
19
  dialogContentProps
20
- } = useCozyDialog({ ...props, isFluidTitle: true })
20
+ } = useCozyDialog({
21
+ ...props,
22
+ isFluidTitle: true,
23
+ disableTitleAutoPadding: true
24
+ })
21
25
 
22
26
  const onBackOrClose = onBack || onClose
23
27
 
@@ -44,9 +48,17 @@ const IllustrationDialog = props => {
44
48
  <DialogContent {...dialogContentProps}>
45
49
  <div className="dialogContentInner withFluidActions">
46
50
  {title && (
47
- <DialogTitle {...dialogTitleProps}>
48
- <div className="u-flex u-flex-justify-center">{title}</div>
49
- </DialogTitle>
51
+ <div className="dialogTitleFluidContainer">
52
+ <DialogTitle
53
+ {...dialogTitleProps}
54
+ className={cx(
55
+ `u-flex u-flex-justify-center`,
56
+ dialogTitleProps.className
57
+ )}
58
+ >
59
+ {title}
60
+ </DialogTitle>
61
+ </div>
50
62
  )}
51
63
  <div
52
64
  className={cx('dialogContentWrapper', {
@@ -1,7 +1,13 @@
1
1
  import format from 'date-fns/format'
2
+ import distanceInWordsToNow from 'date-fns/distance_in_words_to_now'
3
+ import distanceInWordsStrict from 'date-fns/distance_in_words_strict'
4
+ import differenceInCalendarDays from 'date-fns/difference_in_calendar_days'
5
+ import getHours from 'date-fns/get_hours'
6
+ import setHours from 'date-fns/set_hours'
7
+ import setMinutes from 'date-fns/set_minutes'
8
+ import getMinutes from 'date-fns/get_minutes'
9
+
2
10
  import { DEFAULT_LANG } from '.'
3
- import formatDistanceToNow from 'date-fns/distance_in_words_to_now'
4
- import formatDistanceStrict from 'date-fns/distance_in_words_strict'
5
11
 
6
12
  const locales = {}
7
13
  let lang = DEFAULT_LANG
@@ -36,7 +42,32 @@ export const initFormat = (userLang, defaultLang = DEFAULT_LANG) => (
36
42
  }
37
43
 
38
44
  export const formatLocallyDistanceToNow = date =>
39
- formatDistanceToNow(date, { locale: locales[lang] })
45
+ distanceInWordsToNow(date, { locale: locales[lang] })
46
+
47
+ export const setHoursAndMinutesFromDate = (date, refDate) => {
48
+ let newDate = date
49
+ newDate = setHours(newDate, getHours(refDate))
50
+ newDate = setMinutes(newDate, getMinutes(refDate))
51
+ return newDate
52
+ }
40
53
 
41
- export const formatLocallyDistanceToNowStrict = date =>
42
- formatDistanceStrict(Date.now(), date, { locale: locales[lang] })
54
+ /**
55
+ * Return the distance between the given dates in words, using strict units.
56
+ * If the distance is in days, we force the time to be a whole number of days
57
+ * @param {Date} date - Future date compared to the current date
58
+ * @returns {string} Number of hours/day/month that separates the date from the present moment
59
+ */
60
+ export const formatLocallyDistanceToNowStrict = date => {
61
+ const now = new Date()
62
+ const days = differenceInCalendarDays(date, now)
63
+ const isSameDay = days === 0
64
+ const isInMonth = days > 0 && days < 32
65
+
66
+ const refDate = isSameDay ? date : setHoursAndMinutesFromDate(date, now)
67
+ const unit = isInMonth ? 'd' : undefined
68
+
69
+ return distanceInWordsStrict(now, refDate, {
70
+ locale: locales[lang],
71
+ unit
72
+ })
73
+ }
@@ -1,7 +1,10 @@
1
+ import MockDate from 'mockdate'
2
+
1
3
  import {
2
4
  initFormat,
3
5
  formatLocallyDistanceToNow,
4
- formatLocallyDistanceToNowStrict
6
+ formatLocallyDistanceToNowStrict,
7
+ setHoursAndMinutesFromDate
5
8
  } from './format'
6
9
 
7
10
  describe('initFormat', () => {
@@ -75,6 +78,22 @@ describe('formatLocallyDistanceToNowStrict', () => {
75
78
  expect(result).toEqual('1 hour')
76
79
  })
77
80
 
81
+ it('should formatDistanceToNowStrict with one day', () => {
82
+ const date = Date.now() + 24 * 60 * 60 * 1000 // 1d
83
+
84
+ const result = formatLocallyDistanceToNowStrict(date)
85
+
86
+ expect(result).toEqual('1 day')
87
+ })
88
+
89
+ it('should formatDistanceToNowStrict with two days', () => {
90
+ const date = Date.now() + 2 * 24 * 60 * 60 * 1000 // 2d
91
+
92
+ const result = formatLocallyDistanceToNowStrict(date)
93
+
94
+ expect(result).toEqual('2 days')
95
+ })
96
+
78
97
  it('should formatDistanceToNowStrict with very high value', () => {
79
98
  const date = Date.now() + 42 * 24 * 60 * 60 * 1000 // 42d
80
99
 
@@ -82,4 +101,166 @@ describe('formatLocallyDistanceToNowStrict', () => {
82
101
 
83
102
  expect(result).toEqual('1 month')
84
103
  })
104
+
105
+ describe('for hours', () => {
106
+ afterEach(() => {
107
+ MockDate.reset()
108
+ })
109
+
110
+ it('should return 1 hour', () => {
111
+ MockDate.set('2023-01-01T00:00:00')
112
+ const date = new Date('2023-01-01T01:00:00')
113
+
114
+ const result = formatLocallyDistanceToNowStrict(date)
115
+
116
+ expect(result).toEqual('1 hour')
117
+ })
118
+
119
+ it('should return 23 hours', () => {
120
+ MockDate.set('2023-01-01T00:00:00')
121
+ const date = new Date('2023-01-01T23:59:00')
122
+
123
+ const result = formatLocallyDistanceToNowStrict(date)
124
+
125
+ expect(result).toEqual('23 hours')
126
+ })
127
+
128
+ it('should return 11 hours', () => {
129
+ MockDate.set('2023-01-01T12:00:00')
130
+ const date = new Date('2023-01-01T23:59:00')
131
+
132
+ const result = formatLocallyDistanceToNowStrict(date)
133
+
134
+ expect(result).toEqual('11 hours')
135
+ })
136
+ })
137
+
138
+ describe('for days', () => {
139
+ describe('at midnight', () => {
140
+ beforeEach(() => {
141
+ MockDate.set('2023-01-01T00:00:00')
142
+ })
143
+
144
+ afterEach(() => {
145
+ MockDate.reset()
146
+ })
147
+
148
+ it('should return 1 day when 00:00:00', () => {
149
+ const date = new Date('2023-01-02T00:00:00')
150
+
151
+ const result = formatLocallyDistanceToNowStrict(date)
152
+
153
+ expect(result).toEqual('1 day')
154
+ })
155
+
156
+ it('should return 1 day when 01:00:00', () => {
157
+ const date = new Date('2023-01-02T01:00:00')
158
+
159
+ const result = formatLocallyDistanceToNowStrict(date)
160
+
161
+ expect(result).toEqual('1 day')
162
+ })
163
+
164
+ it('should return 1 day when 23:59:00', () => {
165
+ const date = new Date('2023-01-02T23:59:00')
166
+
167
+ const result = formatLocallyDistanceToNowStrict(date)
168
+
169
+ expect(result).toEqual('1 day')
170
+ })
171
+
172
+ it('should return 2 days when 00:00:00', () => {
173
+ const date = new Date('2023-01-03T00:00:00')
174
+
175
+ const result = formatLocallyDistanceToNowStrict(date)
176
+
177
+ expect(result).toEqual('2 days')
178
+ })
179
+
180
+ it('should return 2 days when 01:00:00', () => {
181
+ const date = new Date('2023-01-03T01:00:00')
182
+
183
+ const result = formatLocallyDistanceToNowStrict(date)
184
+
185
+ expect(result).toEqual('2 days')
186
+ })
187
+
188
+ it('should return 2 days when 23:59:00', () => {
189
+ const date = new Date('2023-01-03T23:59:00')
190
+
191
+ const result = formatLocallyDistanceToNowStrict(date)
192
+
193
+ expect(result).toEqual('2 days')
194
+ })
195
+ })
196
+
197
+ describe('at midday', () => {
198
+ beforeEach(() => {
199
+ MockDate.set('2023-01-01T12:00:00')
200
+ })
201
+
202
+ afterEach(() => {
203
+ MockDate.reset()
204
+ })
205
+
206
+ it('should return 1 day when 00:00:00', () => {
207
+ const date = new Date('2023-01-02T00:00:00')
208
+
209
+ const result = formatLocallyDistanceToNowStrict(date)
210
+
211
+ expect(result).toEqual('1 day')
212
+ })
213
+
214
+ it('should return 1 day when 11:00:00', () => {
215
+ const date = new Date('2023-01-02T11:00:00')
216
+
217
+ const result = formatLocallyDistanceToNowStrict(date)
218
+
219
+ expect(result).toEqual('1 day')
220
+ })
221
+
222
+ it('should return 1 day when 23:59:00', () => {
223
+ const date = new Date('2023-01-02T23:59:00')
224
+
225
+ const result = formatLocallyDistanceToNowStrict(date)
226
+
227
+ expect(result).toEqual('1 day')
228
+ })
229
+
230
+ it('should return 2 days when 00:00:00', () => {
231
+ const date = new Date('2023-01-03T00:00:00')
232
+
233
+ const result = formatLocallyDistanceToNowStrict(date)
234
+
235
+ expect(result).toEqual('2 days')
236
+ })
237
+
238
+ it('should return 2 days when 01:00:00', () => {
239
+ const date = new Date('2023-01-03T01:00:00')
240
+
241
+ const result = formatLocallyDistanceToNowStrict(date)
242
+
243
+ expect(result).toEqual('2 days')
244
+ })
245
+
246
+ it('should return 2 days when 23:59:00', () => {
247
+ const date = new Date('2023-01-03T23:59:00')
248
+
249
+ const result = formatLocallyDistanceToNowStrict(date)
250
+
251
+ expect(result).toEqual('2 days')
252
+ })
253
+ })
254
+ })
255
+ })
256
+
257
+ describe('setHoursAndMinutesFromDate', () => {
258
+ it('should return correct date', () => {
259
+ const res = setHoursAndMinutesFromDate(
260
+ new Date('2023-01-03T00:00:30'),
261
+ new Date('2023-01-01T12:24:00')
262
+ )
263
+
264
+ expect(res).toStrictEqual(new Date('2023-01-03T12:24:30'))
265
+ })
85
266
  })
@@ -22,7 +22,8 @@ var IllustrationDialog = function IllustrationDialog(props) {
22
22
  actionsLayout = props.actionsLayout;
23
23
 
24
24
  var _useCozyDialog = useCozyDialog(_objectSpread(_objectSpread({}, props), {}, {
25
- isFluidTitle: true
25
+ isFluidTitle: true,
26
+ disableTitleAutoPadding: true
26
27
  })),
27
28
  dialogProps = _useCozyDialog.dialogProps,
28
29
  dialogTitleProps = _useCozyDialog.dialogTitleProps,
@@ -43,9 +44,11 @@ var IllustrationDialog = function IllustrationDialog(props) {
43
44
  onClick: onBackOrClose
44
45
  }), /*#__PURE__*/React.createElement(DialogContent, dialogContentProps, /*#__PURE__*/React.createElement("div", {
45
46
  className: "dialogContentInner withFluidActions"
46
- }, title && /*#__PURE__*/React.createElement(DialogTitle, dialogTitleProps, /*#__PURE__*/React.createElement("div", {
47
- className: "u-flex u-flex-justify-center"
48
- }, title)), /*#__PURE__*/React.createElement("div", {
47
+ }, title && /*#__PURE__*/React.createElement("div", {
48
+ className: "dialogTitleFluidContainer"
49
+ }, /*#__PURE__*/React.createElement(DialogTitle, _extends({}, dialogTitleProps, {
50
+ className: cx("u-flex u-flex-justify-center", dialogTitleProps.className)
51
+ }), title)), /*#__PURE__*/React.createElement("div", {
49
52
  className: cx('dialogContentWrapper', {
50
53
  withActions: Boolean(actions)
51
54
  })
@@ -1,7 +1,12 @@
1
1
  import format from 'date-fns/format';
2
+ import distanceInWordsToNow from 'date-fns/distance_in_words_to_now';
3
+ import distanceInWordsStrict from 'date-fns/distance_in_words_strict';
4
+ import differenceInCalendarDays from 'date-fns/difference_in_calendar_days';
5
+ import getHours from 'date-fns/get_hours';
6
+ import setHours from 'date-fns/set_hours';
7
+ import setMinutes from 'date-fns/set_minutes';
8
+ import getMinutes from 'date-fns/get_minutes';
2
9
  import { DEFAULT_LANG } from "cozy-ui/transpiled/react/I18n";
3
- import formatDistanceToNow from 'date-fns/distance_in_words_to_now';
4
- import formatDistanceStrict from 'date-fns/distance_in_words_strict';
5
10
  var locales = {};
6
11
  var lang = DEFAULT_LANG;
7
12
 
@@ -39,12 +44,32 @@ export var initFormat = function initFormat(userLang) {
39
44
  };
40
45
  };
41
46
  export var formatLocallyDistanceToNow = function formatLocallyDistanceToNow(date) {
42
- return formatDistanceToNow(date, {
47
+ return distanceInWordsToNow(date, {
43
48
  locale: locales[lang]
44
49
  });
45
50
  };
51
+ export var setHoursAndMinutesFromDate = function setHoursAndMinutesFromDate(date, refDate) {
52
+ var newDate = date;
53
+ newDate = setHours(newDate, getHours(refDate));
54
+ newDate = setMinutes(newDate, getMinutes(refDate));
55
+ return newDate;
56
+ };
57
+ /**
58
+ * Return the distance between the given dates in words, using strict units.
59
+ * If the distance is in days, we force the time to be a whole number of days
60
+ * @param {Date} date - Future date compared to the current date
61
+ * @returns {string} Number of hours/day/month that separates the date from the present moment
62
+ */
63
+
46
64
  export var formatLocallyDistanceToNowStrict = function formatLocallyDistanceToNowStrict(date) {
47
- return formatDistanceStrict(Date.now(), date, {
48
- locale: locales[lang]
65
+ var now = new Date();
66
+ var days = differenceInCalendarDays(date, now);
67
+ var isSameDay = days === 0;
68
+ var isInMonth = days > 0 && days < 32;
69
+ var refDate = isSameDay ? date : setHoursAndMinutesFromDate(date, now);
70
+ var unit = isInMonth ? 'd' : undefined;
71
+ return distanceInWordsStrict(now, refDate, {
72
+ locale: locales[lang],
73
+ unit: unit
49
74
  });
50
75
  };