@gympass/yoga 7.129.2 → 7.130.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.
- package/cjs/ActionRequirement/web/ActionRequirement.js +5 -3
- package/cjs/ActionRequirement/web/ActionRequirement.test.js +14 -0
- package/cjs/Datepicker/web/Calendar.js +19 -12
- package/cjs/Datepicker/web/Datepicker.js +21 -9
- package/cjs/Datepicker/web/Datepicker.test.js +67 -0
- package/esm/ActionRequirement/web/ActionRequirement.js +6 -4
- package/esm/ActionRequirement/web/ActionRequirement.test.js +14 -0
- package/esm/Datepicker/web/Calendar.js +20 -13
- package/esm/Datepicker/web/Datepicker.js +21 -9
- package/esm/Datepicker/web/Datepicker.test.js +67 -0
- package/package.json +3 -3
- package/typings/index.d.ts +4 -1
|
@@ -98,7 +98,8 @@ function ActionRequirement(props) {
|
|
|
98
98
|
checkable,
|
|
99
99
|
illustration,
|
|
100
100
|
list,
|
|
101
|
-
titleAsTextDisplay = false
|
|
101
|
+
titleAsTextDisplay = false,
|
|
102
|
+
ariaLevelTitle = 1
|
|
102
103
|
} = props;
|
|
103
104
|
let primaryButton;
|
|
104
105
|
let secondaryButton;
|
|
@@ -114,7 +115,7 @@ function ActionRequirement(props) {
|
|
|
114
115
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(StyledActionRequirement, __spreadProps(__spreadValues({}, props), { children: [
|
|
115
116
|
illustration && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BoxIllustration, { "aria-hidden": true, children: illustration }),
|
|
116
117
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Content, { children: [
|
|
117
|
-
titleAsTextDisplay ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Text.default.Display2, { as: "h1", children: title }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ActionRequirementStyles.Title, { children: title }),
|
|
118
|
+
titleAsTextDisplay ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Text.default.Display2, { as: "h1", "aria-level": ariaLevelTitle, children: title }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ActionRequirementStyles.Title, { "aria-level": ariaLevelTitle, children: title }),
|
|
118
119
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Text.default.Body1, { mt: "small", color: "deep", children: description }),
|
|
119
120
|
list && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Box.default, { mt: "large", children: list }),
|
|
120
121
|
checkable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Box.default, { mt: "xxlarge", children: checkable }),
|
|
@@ -132,6 +133,7 @@ ActionRequirement.propTypes = {
|
|
|
132
133
|
checkable: (0, import_prop_types.oneOfType)([(0, import_prop_types.arrayOf)(import_prop_types.node), import_prop_types.node]),
|
|
133
134
|
illustration: (0, import_prop_types.oneOfType)([(0, import_prop_types.arrayOf)(import_prop_types.node), import_prop_types.node]),
|
|
134
135
|
list: (0, import_prop_types.oneOfType)([(0, import_prop_types.arrayOf)(import_prop_types.node), import_prop_types.node]),
|
|
135
|
-
titleAsTextDisplay: import_prop_types.bool
|
|
136
|
+
titleAsTextDisplay: import_prop_types.bool,
|
|
137
|
+
ariaLevelTitle: import_prop_types.number
|
|
136
138
|
};
|
|
137
139
|
var ActionRequirement_default = ActionRequirement;
|
|
@@ -76,4 +76,18 @@ describe("<ActionRequirement />", () => {
|
|
|
76
76
|
);
|
|
77
77
|
expect(container).toMatchSnapshot();
|
|
78
78
|
});
|
|
79
|
+
it("should match snapshot with aria-level 2", () => {
|
|
80
|
+
const { container } = (0, import_react2.render)(
|
|
81
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
82
|
+
import_ActionRequirement.default,
|
|
83
|
+
{
|
|
84
|
+
title: "title",
|
|
85
|
+
description: "description",
|
|
86
|
+
titleAsTextDisplay: true,
|
|
87
|
+
ariaLevelTitle: 2
|
|
88
|
+
}
|
|
89
|
+
) })
|
|
90
|
+
);
|
|
91
|
+
expect(container).toMatchSnapshot();
|
|
92
|
+
});
|
|
79
93
|
});
|
|
@@ -77,6 +77,9 @@ const Month = (0, import_styled_components.default)(import__.Text.Body2)`
|
|
|
77
77
|
}) => `
|
|
78
78
|
color: ${v3theme ? colors.primary : colors.text.primary};
|
|
79
79
|
align-self: center;
|
|
80
|
+
&:first-letter {
|
|
81
|
+
text-transform: capitalize;
|
|
82
|
+
};
|
|
80
83
|
`}
|
|
81
84
|
`;
|
|
82
85
|
const getDayFieldColor = (selected, disabled, colors, aux) => {
|
|
@@ -191,7 +194,8 @@ function Calendar({
|
|
|
191
194
|
disablePastDates = false,
|
|
192
195
|
disableFutureDates = false,
|
|
193
196
|
disablePastFrom,
|
|
194
|
-
disableFutureFrom
|
|
197
|
+
disableFutureFrom,
|
|
198
|
+
locale
|
|
195
199
|
}) {
|
|
196
200
|
const [month, setMonth] = (0, import_react.useState)((/* @__PURE__ */ new Date()).getUTCMonth());
|
|
197
201
|
const [year, setYear] = (0, import_react.useState)((/* @__PURE__ */ new Date()).getUTCFullYear());
|
|
@@ -318,6 +322,16 @@ function Calendar({
|
|
|
318
322
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, { children: getLastWeek() })
|
|
319
323
|
] });
|
|
320
324
|
};
|
|
325
|
+
const getLocale = () => {
|
|
326
|
+
return Intl.DateTimeFormat.supportedLocalesOf(locale).length > 0 ? locale : "en-US";
|
|
327
|
+
};
|
|
328
|
+
const weekDays = Array.from(
|
|
329
|
+
{ length: 7 },
|
|
330
|
+
(__, i) => new Intl.DateTimeFormat(getLocale(), {
|
|
331
|
+
weekday: "short",
|
|
332
|
+
timeZone: "UTC"
|
|
333
|
+
}).format(new Date(Date.UTC(2024, 0, 7 + i)))
|
|
334
|
+
);
|
|
321
335
|
const prior = () => {
|
|
322
336
|
let local = month - 1;
|
|
323
337
|
if (local < 0) {
|
|
@@ -356,7 +370,7 @@ function Calendar({
|
|
|
356
370
|
"data-testid": "previous-month-arrow"
|
|
357
371
|
}
|
|
358
372
|
),
|
|
359
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Month, { bold: true, children: new Intl.DateTimeFormat(
|
|
373
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Month, { bold: true, children: new Intl.DateTimeFormat(getLocale(), {
|
|
360
374
|
month: "long",
|
|
361
375
|
year: "numeric"
|
|
362
376
|
}).format(new Date(year, month, 1, 0, 0, 0)) }),
|
|
@@ -375,15 +389,7 @@ function Calendar({
|
|
|
375
389
|
]
|
|
376
390
|
}
|
|
377
391
|
),
|
|
378
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
379
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Day, { children: "S" }),
|
|
380
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Day, { children: "M" }),
|
|
381
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Day, { children: "T" }),
|
|
382
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Day, { children: "W" }),
|
|
383
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Day, { children: "T" }),
|
|
384
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Day, { children: "F" }),
|
|
385
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Day, { children: "S" })
|
|
386
|
-
] }),
|
|
392
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DaysWrapper, { children: weekDays.map((weekDay) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Day, { children: weekDay.toLocaleUpperCase().charAt(0) }, `${weekDay}`)) }),
|
|
387
393
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.Box, { children: getDays() })
|
|
388
394
|
] });
|
|
389
395
|
}
|
|
@@ -396,6 +402,7 @@ Calendar.propTypes = {
|
|
|
396
402
|
disablePastDates: import_prop_types.bool,
|
|
397
403
|
disableFutureDates: import_prop_types.bool,
|
|
398
404
|
disablePastFrom: (0, import_prop_types.instanceOf)(Date),
|
|
399
|
-
disableFutureFrom: (0, import_prop_types.instanceOf)(Date)
|
|
405
|
+
disableFutureFrom: (0, import_prop_types.instanceOf)(Date),
|
|
406
|
+
locale: import_prop_types.string
|
|
400
407
|
};
|
|
401
408
|
var Calendar_default = Calendar;
|
|
@@ -66,7 +66,6 @@ var import_react = __toESM(require("react"));
|
|
|
66
66
|
var import_yoga_icons = require("@gympass/yoga-icons");
|
|
67
67
|
var import_styled_components = __toESM(require("styled-components"));
|
|
68
68
|
var import_prop_types = require("prop-types");
|
|
69
|
-
var import_date_fns = require("date-fns");
|
|
70
69
|
var import__ = require("../..");
|
|
71
70
|
var import_Theme = require("../../Theme");
|
|
72
71
|
var import_Calendar = __toESM(require("./Calendar"));
|
|
@@ -230,7 +229,8 @@ function Datepicker(_c) {
|
|
|
230
229
|
disableFutureFrom,
|
|
231
230
|
error,
|
|
232
231
|
onOpen,
|
|
233
|
-
displayEndDateOnly = false
|
|
232
|
+
displayEndDateOnly = false,
|
|
233
|
+
locale
|
|
234
234
|
} = _d, props = __objRest(_d, [
|
|
235
235
|
"fullWidth",
|
|
236
236
|
"type",
|
|
@@ -247,7 +247,8 @@ function Datepicker(_c) {
|
|
|
247
247
|
"disableFutureFrom",
|
|
248
248
|
"error",
|
|
249
249
|
"onOpen",
|
|
250
|
-
"displayEndDateOnly"
|
|
250
|
+
"displayEndDateOnly",
|
|
251
|
+
"locale"
|
|
251
252
|
]);
|
|
252
253
|
const [open, setOpen] = (0, import_react.useState)();
|
|
253
254
|
const [startDateLocal, setStartDateLocal] = (0, import_react.useState)(startDate);
|
|
@@ -318,12 +319,21 @@ function Datepicker(_c) {
|
|
|
318
319
|
if (!start && !end || displayEndDateOnly && !end) {
|
|
319
320
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InputPlaceholder, { disabled, children: placeholder != null ? placeholder : `Select Date` });
|
|
320
321
|
}
|
|
321
|
-
const
|
|
322
|
+
const formattedDate = (date) => {
|
|
323
|
+
let month = new Intl.DateTimeFormat(locale, {
|
|
324
|
+
month: "short",
|
|
325
|
+
timeZone: "UTC"
|
|
326
|
+
}).format(date);
|
|
327
|
+
month = month.charAt(0).toUpperCase() + month.slice(1, 3);
|
|
328
|
+
const day = date.getUTCDate();
|
|
329
|
+
const year = date.getUTCFullYear();
|
|
330
|
+
return `${month} ${day}, ${year}`;
|
|
331
|
+
};
|
|
322
332
|
if (displayEndDateOnly)
|
|
323
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, { disabled, children: end && (
|
|
333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, { disabled, children: end && formattedDate(end) });
|
|
324
334
|
return start && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Input, { disabled, children: [
|
|
325
|
-
(
|
|
326
|
-
end && ` - ${(
|
|
335
|
+
formattedDate(start),
|
|
336
|
+
end && ` - ${formattedDate(end)}`
|
|
327
337
|
] });
|
|
328
338
|
};
|
|
329
339
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Wrapper, __spreadProps(__spreadValues({ fullWidth, tabIndex: "0" }, props), { children: [
|
|
@@ -366,7 +376,8 @@ function Datepicker(_c) {
|
|
|
366
376
|
disablePastDates,
|
|
367
377
|
disableFutureDates,
|
|
368
378
|
disablePastFrom,
|
|
369
|
-
disableFutureFrom
|
|
379
|
+
disableFutureFrom,
|
|
380
|
+
locale
|
|
370
381
|
}
|
|
371
382
|
) })
|
|
372
383
|
] }));
|
|
@@ -387,7 +398,8 @@ Datepicker.propTypes = {
|
|
|
387
398
|
disableFutureFrom: (0, import_prop_types.instanceOf)(Date),
|
|
388
399
|
error: import_prop_types.string,
|
|
389
400
|
onOpen: import_prop_types.func,
|
|
390
|
-
displayEndDateOnly: import_prop_types.bool
|
|
401
|
+
displayEndDateOnly: import_prop_types.bool,
|
|
402
|
+
locale: import_prop_types.string
|
|
391
403
|
};
|
|
392
404
|
var Datepicker_default = Datepicker;
|
|
393
405
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -29,6 +29,10 @@ var import__ = require("../..");
|
|
|
29
29
|
var import_Datepicker = require("./Datepicker");
|
|
30
30
|
describe("<Datepicker />", () => {
|
|
31
31
|
const testDate = new Date(2022, 7, 3, 14, 0, 0);
|
|
32
|
+
let originalDateTimeFormat;
|
|
33
|
+
beforeAll(() => {
|
|
34
|
+
originalDateTimeFormat = Intl.DateTimeFormat;
|
|
35
|
+
});
|
|
32
36
|
describe("Snapshots", () => {
|
|
33
37
|
it("should match snapshot when v3Theme is settled", () => {
|
|
34
38
|
const { container } = (0, import_react2.render)(
|
|
@@ -249,4 +253,67 @@ describe("<Datepicker />", () => {
|
|
|
249
253
|
expect(import_react2.screen.getByText("This is an error")).toBeVisible();
|
|
250
254
|
});
|
|
251
255
|
});
|
|
256
|
+
describe("Internationalization", () => {
|
|
257
|
+
let originalNavigator;
|
|
258
|
+
beforeEach(() => {
|
|
259
|
+
originalNavigator = global.navigator;
|
|
260
|
+
});
|
|
261
|
+
afterEach(() => {
|
|
262
|
+
global.Intl.DateTimeFormat = originalDateTimeFormat;
|
|
263
|
+
Object.defineProperty(global, "navigator", {
|
|
264
|
+
value: originalNavigator,
|
|
265
|
+
writable: true
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
it("should display calendar in English when locale is not supported", () => {
|
|
269
|
+
(0, import_react2.render)(
|
|
270
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.Datepicker, { type: "single", locale: "xx-XX" }) })
|
|
271
|
+
);
|
|
272
|
+
import_react2.fireEvent.click(import_react2.screen.getByRole("button"));
|
|
273
|
+
const currentDate = /* @__PURE__ */ new Date();
|
|
274
|
+
const currentMonth = new Intl.DateTimeFormat("en-US", {
|
|
275
|
+
month: "long"
|
|
276
|
+
}).format(currentDate);
|
|
277
|
+
expect(
|
|
278
|
+
import_react2.screen.getByText(new RegExp(currentMonth, "i"))
|
|
279
|
+
).toBeInTheDocument();
|
|
280
|
+
});
|
|
281
|
+
it("should display calendar in Portuguese when browser locale is pt-BR", () => {
|
|
282
|
+
(0, import_react2.render)(
|
|
283
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.Datepicker, { type: "single", locale: "pt-BR" }) })
|
|
284
|
+
);
|
|
285
|
+
import_react2.fireEvent.click(import_react2.screen.getByRole("button"));
|
|
286
|
+
const currentDate = /* @__PURE__ */ new Date();
|
|
287
|
+
const months = [
|
|
288
|
+
"janeiro",
|
|
289
|
+
"fevereiro",
|
|
290
|
+
"mar\xE7o",
|
|
291
|
+
"abril",
|
|
292
|
+
"maio",
|
|
293
|
+
"junho",
|
|
294
|
+
"julho",
|
|
295
|
+
"agosto",
|
|
296
|
+
"setembro",
|
|
297
|
+
"outubro",
|
|
298
|
+
"novembro",
|
|
299
|
+
"dezembro"
|
|
300
|
+
];
|
|
301
|
+
const currentMonth = months[currentDate.getMonth()];
|
|
302
|
+
expect(
|
|
303
|
+
import_react2.screen.getByText(new RegExp(currentMonth, "i"))
|
|
304
|
+
).toBeInTheDocument();
|
|
305
|
+
});
|
|
306
|
+
it("should display only the first letter of each weekday in uppercase", () => {
|
|
307
|
+
(0, import_react2.render)(
|
|
308
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.Datepicker, { type: "single" }) })
|
|
309
|
+
);
|
|
310
|
+
import_react2.fireEvent.click(import_react2.screen.getByRole("button"));
|
|
311
|
+
const weekdayLetters = ["S", "M", "T", "W", "T", "F", "S"];
|
|
312
|
+
weekdayLetters.forEach((letter) => {
|
|
313
|
+
expect(import_react2.screen.getAllByText(letter).length).toBeGreaterThan(0);
|
|
314
|
+
});
|
|
315
|
+
expect(import_react2.screen.queryByText("sun")).not.toBeInTheDocument();
|
|
316
|
+
expect(import_react2.screen.queryByText("mon")).not.toBeInTheDocument();
|
|
317
|
+
});
|
|
318
|
+
});
|
|
252
319
|
});
|
|
@@ -19,7 +19,7 @@ var __spreadValues = (a, b) => {
|
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
20
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21
21
|
import React from "react";
|
|
22
|
-
import { arrayOf, bool, node, oneOfType, string } from "prop-types";
|
|
22
|
+
import { arrayOf, bool, node, oneOfType, string, number } from "prop-types";
|
|
23
23
|
import styled from "styled-components";
|
|
24
24
|
import { media } from "@gympass/yoga-helpers";
|
|
25
25
|
import {
|
|
@@ -72,7 +72,8 @@ function ActionRequirement(props) {
|
|
|
72
72
|
checkable,
|
|
73
73
|
illustration,
|
|
74
74
|
list,
|
|
75
|
-
titleAsTextDisplay = false
|
|
75
|
+
titleAsTextDisplay = false,
|
|
76
|
+
ariaLevelTitle = 1
|
|
76
77
|
} = props;
|
|
77
78
|
let primaryButton;
|
|
78
79
|
let secondaryButton;
|
|
@@ -88,7 +89,7 @@ function ActionRequirement(props) {
|
|
|
88
89
|
return /* @__PURE__ */ jsxs(StyledActionRequirement, __spreadProps(__spreadValues({}, props), { children: [
|
|
89
90
|
illustration && /* @__PURE__ */ jsx(BoxIllustration, { "aria-hidden": true, children: illustration }),
|
|
90
91
|
/* @__PURE__ */ jsxs(Content, { children: [
|
|
91
|
-
titleAsTextDisplay ? /* @__PURE__ */ jsx(Text.Display2, { as: "h1", children: title }) : /* @__PURE__ */ jsx(Title, { children: title }),
|
|
92
|
+
titleAsTextDisplay ? /* @__PURE__ */ jsx(Text.Display2, { as: "h1", "aria-level": ariaLevelTitle, children: title }) : /* @__PURE__ */ jsx(Title, { "aria-level": ariaLevelTitle, children: title }),
|
|
92
93
|
/* @__PURE__ */ jsx(Text.Body1, { mt: "small", color: "deep", children: description }),
|
|
93
94
|
list && /* @__PURE__ */ jsx(Box, { mt: "large", children: list }),
|
|
94
95
|
checkable && /* @__PURE__ */ jsx(Box, { mt: "xxlarge", children: checkable }),
|
|
@@ -106,7 +107,8 @@ ActionRequirement.propTypes = {
|
|
|
106
107
|
checkable: oneOfType([arrayOf(node), node]),
|
|
107
108
|
illustration: oneOfType([arrayOf(node), node]),
|
|
108
109
|
list: oneOfType([arrayOf(node), node]),
|
|
109
|
-
titleAsTextDisplay: bool
|
|
110
|
+
titleAsTextDisplay: bool,
|
|
111
|
+
ariaLevelTitle: number
|
|
110
112
|
};
|
|
111
113
|
var ActionRequirement_default = ActionRequirement;
|
|
112
114
|
export {
|
|
@@ -53,4 +53,18 @@ describe("<ActionRequirement />", () => {
|
|
|
53
53
|
);
|
|
54
54
|
expect(container).toMatchSnapshot();
|
|
55
55
|
});
|
|
56
|
+
it("should match snapshot with aria-level 2", () => {
|
|
57
|
+
const { container } = render(
|
|
58
|
+
/* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(
|
|
59
|
+
ActionRequirement,
|
|
60
|
+
{
|
|
61
|
+
title: "title",
|
|
62
|
+
description: "description",
|
|
63
|
+
titleAsTextDisplay: true,
|
|
64
|
+
ariaLevelTitle: 2
|
|
65
|
+
}
|
|
66
|
+
) })
|
|
67
|
+
);
|
|
68
|
+
expect(container).toMatchSnapshot();
|
|
69
|
+
});
|
|
56
70
|
});
|
|
@@ -2,7 +2,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import React, { useEffect, useState } from "react";
|
|
3
3
|
import styled from "styled-components";
|
|
4
4
|
import { ChevronLeft, ChevronRight } from "@gympass/yoga-icons";
|
|
5
|
-
import { oneOf, func, instanceOf, bool } from "prop-types";
|
|
5
|
+
import { oneOf, func, instanceOf, bool, string } from "prop-types";
|
|
6
6
|
import _ from "lodash";
|
|
7
7
|
import { Icon, Text, Box } from "../..";
|
|
8
8
|
const CalendarWrapper = styled.div`
|
|
@@ -44,6 +44,9 @@ const Month = styled(Text.Body2)`
|
|
|
44
44
|
}) => `
|
|
45
45
|
color: ${v3theme ? colors.primary : colors.text.primary};
|
|
46
46
|
align-self: center;
|
|
47
|
+
&:first-letter {
|
|
48
|
+
text-transform: capitalize;
|
|
49
|
+
};
|
|
47
50
|
`}
|
|
48
51
|
`;
|
|
49
52
|
const getDayFieldColor = (selected, disabled, colors, aux) => {
|
|
@@ -158,7 +161,8 @@ function Calendar({
|
|
|
158
161
|
disablePastDates = false,
|
|
159
162
|
disableFutureDates = false,
|
|
160
163
|
disablePastFrom,
|
|
161
|
-
disableFutureFrom
|
|
164
|
+
disableFutureFrom,
|
|
165
|
+
locale
|
|
162
166
|
}) {
|
|
163
167
|
const [month, setMonth] = useState((/* @__PURE__ */ new Date()).getUTCMonth());
|
|
164
168
|
const [year, setYear] = useState((/* @__PURE__ */ new Date()).getUTCFullYear());
|
|
@@ -285,6 +289,16 @@ function Calendar({
|
|
|
285
289
|
/* @__PURE__ */ jsx(Row, { children: getLastWeek() })
|
|
286
290
|
] });
|
|
287
291
|
};
|
|
292
|
+
const getLocale = () => {
|
|
293
|
+
return Intl.DateTimeFormat.supportedLocalesOf(locale).length > 0 ? locale : "en-US";
|
|
294
|
+
};
|
|
295
|
+
const weekDays = Array.from(
|
|
296
|
+
{ length: 7 },
|
|
297
|
+
(__, i) => new Intl.DateTimeFormat(getLocale(), {
|
|
298
|
+
weekday: "short",
|
|
299
|
+
timeZone: "UTC"
|
|
300
|
+
}).format(new Date(Date.UTC(2024, 0, 7 + i)))
|
|
301
|
+
);
|
|
288
302
|
const prior = () => {
|
|
289
303
|
let local = month - 1;
|
|
290
304
|
if (local < 0) {
|
|
@@ -323,7 +337,7 @@ function Calendar({
|
|
|
323
337
|
"data-testid": "previous-month-arrow"
|
|
324
338
|
}
|
|
325
339
|
),
|
|
326
|
-
/* @__PURE__ */ jsx(Month, { bold: true, children: new Intl.DateTimeFormat(
|
|
340
|
+
/* @__PURE__ */ jsx(Month, { bold: true, children: new Intl.DateTimeFormat(getLocale(), {
|
|
327
341
|
month: "long",
|
|
328
342
|
year: "numeric"
|
|
329
343
|
}).format(new Date(year, month, 1, 0, 0, 0)) }),
|
|
@@ -342,15 +356,7 @@ function Calendar({
|
|
|
342
356
|
]
|
|
343
357
|
}
|
|
344
358
|
),
|
|
345
|
-
/* @__PURE__ */
|
|
346
|
-
/* @__PURE__ */ jsx(Day, { children: "S" }),
|
|
347
|
-
/* @__PURE__ */ jsx(Day, { children: "M" }),
|
|
348
|
-
/* @__PURE__ */ jsx(Day, { children: "T" }),
|
|
349
|
-
/* @__PURE__ */ jsx(Day, { children: "W" }),
|
|
350
|
-
/* @__PURE__ */ jsx(Day, { children: "T" }),
|
|
351
|
-
/* @__PURE__ */ jsx(Day, { children: "F" }),
|
|
352
|
-
/* @__PURE__ */ jsx(Day, { children: "S" })
|
|
353
|
-
] }),
|
|
359
|
+
/* @__PURE__ */ jsx(DaysWrapper, { children: weekDays.map((weekDay) => /* @__PURE__ */ jsx(Day, { children: weekDay.toLocaleUpperCase().charAt(0) }, `${weekDay}`)) }),
|
|
354
360
|
/* @__PURE__ */ jsx(Box, { children: getDays() })
|
|
355
361
|
] });
|
|
356
362
|
}
|
|
@@ -363,7 +369,8 @@ Calendar.propTypes = {
|
|
|
363
369
|
disablePastDates: bool,
|
|
364
370
|
disableFutureDates: bool,
|
|
365
371
|
disablePastFrom: instanceOf(Date),
|
|
366
|
-
disableFutureFrom: instanceOf(Date)
|
|
372
|
+
disableFutureFrom: instanceOf(Date),
|
|
373
|
+
locale: string
|
|
367
374
|
};
|
|
368
375
|
var Calendar_default = Calendar;
|
|
369
376
|
export {
|
|
@@ -34,7 +34,6 @@ import React, { useEffect, useRef, useState, useCallback } from "react";
|
|
|
34
34
|
import { Booking, BookingFilled } from "@gympass/yoga-icons";
|
|
35
35
|
import styled, { css } from "styled-components";
|
|
36
36
|
import { bool, oneOf, func, instanceOf, string } from "prop-types";
|
|
37
|
-
import { format } from "date-fns";
|
|
38
37
|
import { Text } from "../..";
|
|
39
38
|
import { theme } from "../../Theme";
|
|
40
39
|
import Calendar from "./Calendar";
|
|
@@ -198,7 +197,8 @@ function Datepicker(_c) {
|
|
|
198
197
|
disableFutureFrom,
|
|
199
198
|
error,
|
|
200
199
|
onOpen,
|
|
201
|
-
displayEndDateOnly = false
|
|
200
|
+
displayEndDateOnly = false,
|
|
201
|
+
locale
|
|
202
202
|
} = _d, props = __objRest(_d, [
|
|
203
203
|
"fullWidth",
|
|
204
204
|
"type",
|
|
@@ -215,7 +215,8 @@ function Datepicker(_c) {
|
|
|
215
215
|
"disableFutureFrom",
|
|
216
216
|
"error",
|
|
217
217
|
"onOpen",
|
|
218
|
-
"displayEndDateOnly"
|
|
218
|
+
"displayEndDateOnly",
|
|
219
|
+
"locale"
|
|
219
220
|
]);
|
|
220
221
|
const [open, setOpen] = useState();
|
|
221
222
|
const [startDateLocal, setStartDateLocal] = useState(startDate);
|
|
@@ -286,12 +287,21 @@ function Datepicker(_c) {
|
|
|
286
287
|
if (!start && !end || displayEndDateOnly && !end) {
|
|
287
288
|
return /* @__PURE__ */ jsx(InputPlaceholder, { disabled, children: placeholder != null ? placeholder : `Select Date` });
|
|
288
289
|
}
|
|
289
|
-
const
|
|
290
|
+
const formattedDate = (date) => {
|
|
291
|
+
let month = new Intl.DateTimeFormat(locale, {
|
|
292
|
+
month: "short",
|
|
293
|
+
timeZone: "UTC"
|
|
294
|
+
}).format(date);
|
|
295
|
+
month = month.charAt(0).toUpperCase() + month.slice(1, 3);
|
|
296
|
+
const day = date.getUTCDate();
|
|
297
|
+
const year = date.getUTCFullYear();
|
|
298
|
+
return `${month} ${day}, ${year}`;
|
|
299
|
+
};
|
|
290
300
|
if (displayEndDateOnly)
|
|
291
|
-
return /* @__PURE__ */ jsx(Input, { disabled, children: end &&
|
|
301
|
+
return /* @__PURE__ */ jsx(Input, { disabled, children: end && formattedDate(end) });
|
|
292
302
|
return start && /* @__PURE__ */ jsxs(Input, { disabled, children: [
|
|
293
|
-
|
|
294
|
-
end && ` - ${
|
|
303
|
+
formattedDate(start),
|
|
304
|
+
end && ` - ${formattedDate(end)}`
|
|
295
305
|
] });
|
|
296
306
|
};
|
|
297
307
|
return /* @__PURE__ */ jsxs(Wrapper, __spreadProps(__spreadValues({ fullWidth, tabIndex: "0" }, props), { children: [
|
|
@@ -334,7 +344,8 @@ function Datepicker(_c) {
|
|
|
334
344
|
disablePastDates,
|
|
335
345
|
disableFutureDates,
|
|
336
346
|
disablePastFrom,
|
|
337
|
-
disableFutureFrom
|
|
347
|
+
disableFutureFrom,
|
|
348
|
+
locale
|
|
338
349
|
}
|
|
339
350
|
) })
|
|
340
351
|
] }));
|
|
@@ -355,7 +366,8 @@ Datepicker.propTypes = {
|
|
|
355
366
|
disableFutureFrom: instanceOf(Date),
|
|
356
367
|
error: string,
|
|
357
368
|
onOpen: func,
|
|
358
|
-
displayEndDateOnly: bool
|
|
369
|
+
displayEndDateOnly: bool,
|
|
370
|
+
locale: string
|
|
359
371
|
};
|
|
360
372
|
var Datepicker_default = Datepicker;
|
|
361
373
|
export {
|
|
@@ -6,6 +6,10 @@ import { ThemeProvider, Datepicker, v3theme } from "../..";
|
|
|
6
6
|
import { toUTC } from "./Datepicker";
|
|
7
7
|
describe("<Datepicker />", () => {
|
|
8
8
|
const testDate = new Date(2022, 7, 3, 14, 0, 0);
|
|
9
|
+
let originalDateTimeFormat;
|
|
10
|
+
beforeAll(() => {
|
|
11
|
+
originalDateTimeFormat = Intl.DateTimeFormat;
|
|
12
|
+
});
|
|
9
13
|
describe("Snapshots", () => {
|
|
10
14
|
it("should match snapshot when v3Theme is settled", () => {
|
|
11
15
|
const { container } = render(
|
|
@@ -226,4 +230,67 @@ describe("<Datepicker />", () => {
|
|
|
226
230
|
expect(screen.getByText("This is an error")).toBeVisible();
|
|
227
231
|
});
|
|
228
232
|
});
|
|
233
|
+
describe("Internationalization", () => {
|
|
234
|
+
let originalNavigator;
|
|
235
|
+
beforeEach(() => {
|
|
236
|
+
originalNavigator = global.navigator;
|
|
237
|
+
});
|
|
238
|
+
afterEach(() => {
|
|
239
|
+
global.Intl.DateTimeFormat = originalDateTimeFormat;
|
|
240
|
+
Object.defineProperty(global, "navigator", {
|
|
241
|
+
value: originalNavigator,
|
|
242
|
+
writable: true
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
it("should display calendar in English when locale is not supported", () => {
|
|
246
|
+
render(
|
|
247
|
+
/* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", locale: "xx-XX" }) })
|
|
248
|
+
);
|
|
249
|
+
fireEvent.click(screen.getByRole("button"));
|
|
250
|
+
const currentDate = /* @__PURE__ */ new Date();
|
|
251
|
+
const currentMonth = new Intl.DateTimeFormat("en-US", {
|
|
252
|
+
month: "long"
|
|
253
|
+
}).format(currentDate);
|
|
254
|
+
expect(
|
|
255
|
+
screen.getByText(new RegExp(currentMonth, "i"))
|
|
256
|
+
).toBeInTheDocument();
|
|
257
|
+
});
|
|
258
|
+
it("should display calendar in Portuguese when browser locale is pt-BR", () => {
|
|
259
|
+
render(
|
|
260
|
+
/* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", locale: "pt-BR" }) })
|
|
261
|
+
);
|
|
262
|
+
fireEvent.click(screen.getByRole("button"));
|
|
263
|
+
const currentDate = /* @__PURE__ */ new Date();
|
|
264
|
+
const months = [
|
|
265
|
+
"janeiro",
|
|
266
|
+
"fevereiro",
|
|
267
|
+
"mar\xE7o",
|
|
268
|
+
"abril",
|
|
269
|
+
"maio",
|
|
270
|
+
"junho",
|
|
271
|
+
"julho",
|
|
272
|
+
"agosto",
|
|
273
|
+
"setembro",
|
|
274
|
+
"outubro",
|
|
275
|
+
"novembro",
|
|
276
|
+
"dezembro"
|
|
277
|
+
];
|
|
278
|
+
const currentMonth = months[currentDate.getMonth()];
|
|
279
|
+
expect(
|
|
280
|
+
screen.getByText(new RegExp(currentMonth, "i"))
|
|
281
|
+
).toBeInTheDocument();
|
|
282
|
+
});
|
|
283
|
+
it("should display only the first letter of each weekday in uppercase", () => {
|
|
284
|
+
render(
|
|
285
|
+
/* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single" }) })
|
|
286
|
+
);
|
|
287
|
+
fireEvent.click(screen.getByRole("button"));
|
|
288
|
+
const weekdayLetters = ["S", "M", "T", "W", "T", "F", "S"];
|
|
289
|
+
weekdayLetters.forEach((letter) => {
|
|
290
|
+
expect(screen.getAllByText(letter).length).toBeGreaterThan(0);
|
|
291
|
+
});
|
|
292
|
+
expect(screen.queryByText("sun")).not.toBeInTheDocument();
|
|
293
|
+
expect(screen.queryByText("mon")).not.toBeInTheDocument();
|
|
294
|
+
});
|
|
295
|
+
});
|
|
229
296
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gympass/yoga",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.130.0",
|
|
4
4
|
"description": "Gympass component library",
|
|
5
5
|
"main": "./cjs",
|
|
6
6
|
"types": "./typings/index.d.ts",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"react-phone-input-2": "^2.15.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@gympass/yoga-icons": "^1.
|
|
48
|
+
"@gympass/yoga-icons": "^1.29.0",
|
|
49
49
|
"@react-native-community/eslint-config": "^3.0.1",
|
|
50
50
|
"@types/styled-components": "^5.1.34",
|
|
51
51
|
"babel-plugin-inline-react-svg": "^1.1.1",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"react-native": "0.72.3",
|
|
60
60
|
"styled-components": "^4.4.0"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "181e38376e72162bd97ae292a93c94caadf5cef2",
|
|
63
63
|
"module": "./esm",
|
|
64
64
|
"private": false,
|
|
65
65
|
"react-native": "./cjs/index.native.js"
|
package/typings/index.d.ts
CHANGED
|
@@ -342,7 +342,7 @@ declare namespace Feedback {
|
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
-
declare function Datepicker({ fullWidth, type, placeholder, startDate, endDate, onSelectSingle, disabled, onSelectRange, customOnSelectRange, disablePastDates, disableFutureDates, disablePastFrom, disableFutureFrom, error, onOpen, displayEndDateOnly, ...props }: {
|
|
345
|
+
declare function Datepicker({ fullWidth, type, placeholder, startDate, endDate, onSelectSingle, disabled, onSelectRange, customOnSelectRange, disablePastDates, disableFutureDates, disablePastFrom, disableFutureFrom, error, onOpen, displayEndDateOnly, locale, ...props }: {
|
|
346
346
|
[x: string]: any;
|
|
347
347
|
fullWidth?: boolean | undefined;
|
|
348
348
|
type: any;
|
|
@@ -360,6 +360,7 @@ declare function Datepicker({ fullWidth, type, placeholder, startDate, endDate,
|
|
|
360
360
|
error: any;
|
|
361
361
|
onOpen: any;
|
|
362
362
|
displayEndDateOnly?: boolean | undefined;
|
|
363
|
+
locale: any;
|
|
363
364
|
}): JSX.Element;
|
|
364
365
|
declare namespace Datepicker {
|
|
365
366
|
namespace propTypes {
|
|
@@ -379,6 +380,7 @@ declare namespace Datepicker {
|
|
|
379
380
|
export { string as error };
|
|
380
381
|
export { func as onOpen };
|
|
381
382
|
export { bool as displayEndDateOnly };
|
|
383
|
+
export { string as locale };
|
|
382
384
|
}
|
|
383
385
|
}
|
|
384
386
|
|
|
@@ -408,6 +410,7 @@ declare namespace ActionRequirement {
|
|
|
408
410
|
export const illustration: prop_types.Requireable<string | number | boolean | prop_types.ReactElementLike | prop_types.ReactNodeArray>;
|
|
409
411
|
export const list: prop_types.Requireable<string | number | boolean | prop_types.ReactElementLike | prop_types.ReactNodeArray>;
|
|
410
412
|
export { bool as titleAsTextDisplay };
|
|
413
|
+
export { number as ariaLevelTitle };
|
|
411
414
|
}
|
|
412
415
|
}
|
|
413
416
|
|