@pingux/astro 2.70.0-alpha.2 → 2.71.0-alpha.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 (74) hide show
  1. package/lib/cjs/components/AccordionItem/AccordionItem.d.ts +1 -1
  2. package/lib/cjs/components/AccordionItem/AccordionItem.js +1 -1
  3. package/lib/cjs/components/Calendar/Calendar.js +4 -0
  4. package/lib/cjs/components/Calendar/Calendar.mdx +1 -1
  5. package/lib/cjs/components/Calendar/Calendar.test.js +1 -4
  6. package/lib/cjs/components/Calendar/CalendarCell.js +1 -1
  7. package/lib/cjs/components/DatePicker/DatePicker.test.js +62 -6
  8. package/lib/cjs/components/RangeCalendar/RangeCalendar.d.ts +7 -0
  9. package/lib/cjs/components/RangeCalendar/RangeCalendar.js +100 -0
  10. package/lib/cjs/components/RangeCalendar/RangeCalendar.mdx +39 -0
  11. package/lib/cjs/components/RangeCalendar/RangeCalendar.stories.d.ts +103 -0
  12. package/lib/cjs/components/RangeCalendar/RangeCalendar.stories.js +131 -0
  13. package/lib/cjs/components/RangeCalendar/RangeCalendar.styles.d.ts +104 -0
  14. package/lib/cjs/components/RangeCalendar/RangeCalendar.styles.js +118 -0
  15. package/lib/cjs/components/RangeCalendar/RangeCalendar.test.d.ts +1 -0
  16. package/lib/cjs/components/RangeCalendar/RangeCalendar.test.js +217 -0
  17. package/lib/cjs/components/RangeCalendar/RangeCalendarCell.d.ts +4 -0
  18. package/lib/cjs/components/RangeCalendar/RangeCalendarCell.js +96 -0
  19. package/lib/cjs/components/RangeCalendar/RangeCalendarGrid.d.ts +4 -0
  20. package/lib/cjs/components/RangeCalendar/RangeCalendarGrid.js +70 -0
  21. package/lib/cjs/components/RangeCalendar/RangeCalendarHeader.d.ts +4 -0
  22. package/lib/cjs/components/RangeCalendar/RangeCalendarHeader.js +85 -0
  23. package/lib/cjs/components/RangeCalendar/index.d.ts +2 -0
  24. package/lib/cjs/components/RangeCalendar/index.js +33 -0
  25. package/lib/cjs/components/TimeField/TimeField.d.ts +7 -0
  26. package/lib/cjs/components/TimeField/TimeField.js +105 -0
  27. package/lib/cjs/components/TimeField/TimeField.mdx +35 -0
  28. package/lib/cjs/components/TimeField/TimeField.stories.d.ts +27 -0
  29. package/lib/cjs/components/TimeField/TimeField.stories.js +96 -0
  30. package/lib/cjs/components/TimeField/TimeField.styles.d.ts +865 -0
  31. package/lib/cjs/components/TimeField/TimeField.styles.js +47 -0
  32. package/lib/cjs/components/TimeField/TimeField.test.d.ts +1 -0
  33. package/lib/cjs/components/TimeField/TimeField.test.js +194 -0
  34. package/lib/cjs/components/TimeField/TimeSegment.d.ts +4 -0
  35. package/lib/cjs/components/TimeField/TimeSegment.js +64 -0
  36. package/lib/cjs/components/TimeField/index.d.ts +2 -0
  37. package/lib/cjs/components/TimeField/index.js +33 -0
  38. package/lib/cjs/index.d.ts +4 -0
  39. package/lib/cjs/index.js +64 -26
  40. package/lib/cjs/styles/forms/index.js +2 -0
  41. package/lib/cjs/styles/variants/variants.js +4 -0
  42. package/lib/cjs/types/calendar.d.ts +51 -16
  43. package/lib/cjs/types/index.d.ts +1 -0
  44. package/lib/cjs/types/index.js +13 -2
  45. package/lib/cjs/types/timefield.d.ts +69 -0
  46. package/lib/cjs/types/timefield.js +6 -0
  47. package/lib/components/AccordionItem/AccordionItem.js +0 -3
  48. package/lib/components/Calendar/Calendar.js +4 -0
  49. package/lib/components/Calendar/Calendar.mdx +1 -1
  50. package/lib/components/Calendar/Calendar.test.js +1 -4
  51. package/lib/components/Calendar/CalendarCell.js +1 -1
  52. package/lib/components/DatePicker/DatePicker.test.js +62 -6
  53. package/lib/components/RangeCalendar/RangeCalendar.js +86 -0
  54. package/lib/components/RangeCalendar/RangeCalendar.mdx +39 -0
  55. package/lib/components/RangeCalendar/RangeCalendar.stories.js +112 -0
  56. package/lib/components/RangeCalendar/RangeCalendar.styles.js +110 -0
  57. package/lib/components/RangeCalendar/RangeCalendar.test.js +208 -0
  58. package/lib/components/RangeCalendar/RangeCalendarCell.js +82 -0
  59. package/lib/components/RangeCalendar/RangeCalendarGrid.js +61 -0
  60. package/lib/components/RangeCalendar/RangeCalendarHeader.js +76 -0
  61. package/lib/components/RangeCalendar/index.js +2 -0
  62. package/lib/components/TimeField/TimeField.js +92 -0
  63. package/lib/components/TimeField/TimeField.mdx +35 -0
  64. package/lib/components/TimeField/TimeField.stories.js +75 -0
  65. package/lib/components/TimeField/TimeField.styles.js +39 -0
  66. package/lib/components/TimeField/TimeField.test.js +191 -0
  67. package/lib/components/TimeField/TimeSegment.js +50 -0
  68. package/lib/components/TimeField/index.js +2 -0
  69. package/lib/index.js +4 -0
  70. package/lib/styles/forms/index.js +2 -0
  71. package/lib/styles/variants/variants.js +4 -0
  72. package/lib/types/index.js +1 -0
  73. package/lib/types/timefield.js +1 -0
  74. package/package.json +4 -4
@@ -0,0 +1,82 @@
1
+ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
2
+ import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
3
+ var _excluded = ["state", "date", "currentMonth", "className"];
4
+ import React, { forwardRef } from 'react';
5
+ import { isSameDay, isSameMonth } from '@internationalized/date';
6
+ import { useCalendarCell } from '@react-aria/calendar';
7
+ import { useFocusRing } from '@react-aria/focus';
8
+ import { useHover, usePress } from '@react-aria/interactions';
9
+ import { mergeProps } from '@react-aria/utils';
10
+ import { useLocalOrForwardRef, useStatusClasses } from '../../hooks';
11
+ import { Box, TableCell } from '../../index';
12
+ import { jsx as ___EmotionJSX } from "@emotion/react";
13
+ var RangeCalendarCell = /*#__PURE__*/forwardRef(function (props, ref) {
14
+ var state = props.state,
15
+ date = props.date,
16
+ currentMonth = props.currentMonth,
17
+ className = props.className,
18
+ others = _objectWithoutProperties(props, _excluded);
19
+ var cellRef = useLocalOrForwardRef(ref);
20
+ var _useCalendarCell = useCalendarCell({
21
+ date: date
22
+ }, state, cellRef),
23
+ cellProps = _useCalendarCell.cellProps,
24
+ buttonProps = _useCalendarCell.buttonProps,
25
+ isSelected = _useCalendarCell.isSelected,
26
+ isOutsideVisibleRange = _useCalendarCell.isOutsideVisibleRange,
27
+ isUnavailable = _useCalendarCell.isUnavailable,
28
+ formattedDate = _useCalendarCell.formattedDate,
29
+ isDisabled = _useCalendarCell.isDisabled;
30
+ var highlightedRange = state.highlightedRange;
31
+ var isOutsideMonth = !isSameMonth(currentMonth, date);
32
+
33
+ // The start and end date of the selected range will have
34
+ // an emphasized appearance.
35
+ var isSelectionStart = highlightedRange ? isSameDay(date, highlightedRange.start) : isSelected;
36
+ var isSelectionEnd = highlightedRange ? isSameDay(date, highlightedRange.end) : isSelected;
37
+ var _useHover = useHover({}),
38
+ hoverProps = _useHover.hoverProps,
39
+ isHovered = _useHover.isHovered;
40
+ var _usePress = usePress({
41
+ ref: cellRef
42
+ }),
43
+ pressProps = _usePress.pressProps,
44
+ isPressed = _usePress.isPressed;
45
+ var _useFocusRing = useFocusRing({
46
+ within: true
47
+ }),
48
+ focusWithinProps = _useFocusRing.focusProps,
49
+ isFocusVisible = _useFocusRing.isFocusVisible;
50
+ var mergedProps = mergeProps(cellProps, hoverProps, pressProps, focusWithinProps);
51
+ var _useStatusClasses = useStatusClasses(className, {
52
+ isSelected: isSelected,
53
+ isExtreme: isDisabled,
54
+ isUnavailable: isUnavailable,
55
+ isPressed: isPressed,
56
+ isFocused: isFocusVisible,
57
+ isHovered: isHovered,
58
+ isOutsideVisibleRange: isOutsideVisibleRange,
59
+ isCompletelyDisabled: state.isDisabled,
60
+ isRangeEnds: isSelectionStart || isSelectionEnd,
61
+ isStartAndEnd: isSelectionStart && isSelectionEnd,
62
+ isSelectionStart: isSelectionStart,
63
+ isSelectionEnd: isSelectionEnd
64
+ }),
65
+ classNames = _useStatusClasses.classNames;
66
+ return ___EmotionJSX(TableCell, _extends({}, mergedProps, {
67
+ variant: "rangeCalendar.calendarCell"
68
+ }), ___EmotionJSX(Box, {
69
+ style: {
70
+ display: isOutsideMonth ? 'none' : 'flex'
71
+ }
72
+ }, ___EmotionJSX(Box, _extends({
73
+ variant: "rangeCalendar.calendarButton",
74
+ ref: cellRef
75
+ }, mergeProps(buttonProps, others), {
76
+ isSelected: isSelected,
77
+ isDisabled: isDisabled,
78
+ isUnavailable: isUnavailable,
79
+ className: classNames
80
+ }), formattedDate)));
81
+ });
82
+ export default RangeCalendarCell;
@@ -0,0 +1,61 @@
1
+ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
2
+ import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat";
3
+ import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
4
+ import _Array$from from "@babel/runtime-corejs3/core-js-stable/array/from";
5
+ import _keysInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/keys";
6
+ import React from 'react';
7
+ import { endOfMonth, getWeeksInMonth } from '@internationalized/date';
8
+ import { useCalendarGrid } from '@react-aria/calendar';
9
+ import { useLocale } from '@react-aria/i18n';
10
+ import { Table, TableBody, TableCell, TableHead, TableRow } from '../../index';
11
+ import RangeCalendarCell from './RangeCalendarCell';
12
+ import { jsx as ___EmotionJSX } from "@emotion/react";
13
+ var RangeCalendarGrid = function RangeCalendarGrid(props) {
14
+ var _context2, _context3;
15
+ var state = props.state,
16
+ _props$offset = props.offset,
17
+ offset = _props$offset === void 0 ? {} : _props$offset;
18
+ var visibleRange = state.visibleRange,
19
+ getDatesInWeek = state.getDatesInWeek;
20
+ var _useLocale = useLocale(),
21
+ locale = _useLocale.locale;
22
+ var startDate = visibleRange.start.add(offset);
23
+ var endDate = endOfMonth(startDate);
24
+ var _useCalendarGrid = useCalendarGrid({
25
+ startDate: startDate,
26
+ endDate: endDate
27
+ }, state),
28
+ gridProps = _useCalendarGrid.gridProps,
29
+ headerProps = _useCalendarGrid.headerProps,
30
+ weekDays = _useCalendarGrid.weekDays;
31
+ var weeksInMonth = getWeeksInMonth(startDate, locale);
32
+ var getKey = function getKey(day, index) {
33
+ var _context;
34
+ return _concatInstanceProperty(_context = "".concat(day, "-")).call(_context, index);
35
+ };
36
+ return ___EmotionJSX(Table, _extends({}, gridProps, {
37
+ role: "grid"
38
+ }), ___EmotionJSX(TableHead, headerProps, ___EmotionJSX(TableRow, null, _mapInstanceProperty(weekDays).call(weekDays, function (day, index) {
39
+ return ___EmotionJSX(TableCell, {
40
+ isHeading: true,
41
+ variant: "rangeCalendar.columnHeader",
42
+ key: getKey(day, index),
43
+ role: "columnheader"
44
+ }, day);
45
+ }))), ___EmotionJSX(TableBody, {
46
+ variant: "rangeCalendar.calendarBody"
47
+ }, _mapInstanceProperty(_context2 = _Array$from(_keysInstanceProperty(_context3 = Array(weeksInMonth)).call(_context3))).call(_context2, function (weekIndex) {
48
+ var _context4;
49
+ return ___EmotionJSX(TableRow, {
50
+ key: weekIndex
51
+ }, _mapInstanceProperty(_context4 = getDatesInWeek(weekIndex, startDate)).call(_context4, function (date) {
52
+ return (date === null || date === void 0 ? void 0 : date.day) && ___EmotionJSX(RangeCalendarCell, {
53
+ key: date.toString(),
54
+ state: state,
55
+ date: date,
56
+ currentMonth: startDate
57
+ });
58
+ }));
59
+ })));
60
+ };
61
+ export default RangeCalendarGrid;
@@ -0,0 +1,76 @@
1
+ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
2
+ import React from 'react';
3
+ import ChevronLeftIcon from '@pingux/mdi-react/ChevronLeftIcon';
4
+ import ChevronRightIcon from '@pingux/mdi-react/ChevronRightIcon';
5
+ import { useDateFormatter } from '@react-aria/i18n';
6
+ import { VisuallyHidden } from '@react-aria/visually-hidden';
7
+ import { Box, Icon, IconButton, Text } from '../../index';
8
+ import { jsx as ___EmotionJSX } from "@emotion/react";
9
+ var RangeCalendarHeader = function RangeCalendarHeader(props) {
10
+ var state = props.state,
11
+ calendarProps = props.calendarProps,
12
+ prevButtonProps = props.prevButtonProps,
13
+ nextButtonProps = props.nextButtonProps;
14
+ var monthDateFormatter = useDateFormatter({
15
+ month: 'long',
16
+ year: 'numeric',
17
+ timeZone: state.timeZone
18
+ });
19
+
20
+ // to remove warning for unknown event handler property `onFocusChange`.
21
+ delete prevButtonProps.onFocusChange;
22
+ delete nextButtonProps.onFocusChange;
23
+ return ___EmotionJSX(Box, {
24
+ variant: "rangeCalendar.calendarHeaderContainer",
25
+ isRow: true
26
+ }, ___EmotionJSX(VisuallyHidden, {
27
+ "aria-live": "assertive"
28
+ }, ___EmotionJSX(Text, null, calendarProps['aria-label'])), ___EmotionJSX(Box, {
29
+ isRow: true,
30
+ variant: "rangeCalendar.calendarHeader"
31
+ }, ___EmotionJSX(Box, {
32
+ style: {
33
+ position: 'absolute',
34
+ left: '10px'
35
+ }
36
+ }, ___EmotionJSX(IconButton, _extends({}, prevButtonProps, {
37
+ "aria-label": "Previous month navigation"
38
+ }), ___EmotionJSX(Icon, {
39
+ icon: ChevronLeftIcon,
40
+ size: 25,
41
+ title: {
42
+ name: 'Chevron Left Icon'
43
+ }
44
+ }))), ___EmotionJSX(Text, {
45
+ "aria-hidden": true,
46
+ variant: "itemTitle",
47
+ role: "heading",
48
+ "aria-level": 3,
49
+ fontWeight: 3
50
+ }, monthDateFormatter.format(state.visibleRange.start.toDate(state.timeZone)))), ___EmotionJSX(Box, {
51
+ isRow: true,
52
+ variant: "rangeCalendar.calendarHeader"
53
+ }, ___EmotionJSX(Text, {
54
+ "aria-hidden": true,
55
+ variant: "itemTitle",
56
+ role: "heading",
57
+ "aria-level": 3,
58
+ fontWeight: 3
59
+ }, monthDateFormatter.format(state.visibleRange.start.add({
60
+ months: 1
61
+ }).toDate(state.timeZone))), ___EmotionJSX(Box, {
62
+ style: {
63
+ position: 'absolute',
64
+ right: '10px'
65
+ }
66
+ }, ___EmotionJSX(IconButton, _extends({}, nextButtonProps, {
67
+ "aria-label": "Next month navigation"
68
+ }), ___EmotionJSX(Icon, {
69
+ icon: ChevronRightIcon,
70
+ size: 25,
71
+ title: {
72
+ name: 'Chevron Right Icon'
73
+ }
74
+ })))));
75
+ };
76
+ export default RangeCalendarHeader;
@@ -0,0 +1,2 @@
1
+ export { default } from './RangeCalendar';
2
+ export * from './RangeCalendar';
@@ -0,0 +1,92 @@
1
+ import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
2
+ import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
3
+ import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
4
+ import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
5
+ import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
6
+ import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
7
+ import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
8
+ import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
9
+ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
10
+ import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
11
+ import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
12
+ var _excluded = ["className", "isDisabled", "isReadOnly"];
13
+ import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
14
+ function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
15
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context2, _context3; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context2 = ownKeys(Object(source), !0)).call(_context2, function (key) { _defineProperty(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context3 = ownKeys(Object(source))).call(_context3, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
16
+ import React, { forwardRef, useRef } from 'react';
17
+ import { FocusScope } from 'react-aria';
18
+ import { parseTime, Time } from '@internationalized/date';
19
+ import { useTimeField } from '@react-aria/datepicker';
20
+ import { useLocale } from '@react-aria/i18n';
21
+ import { useTimeFieldState } from '@react-stately/datepicker';
22
+ import { useField, useLocalOrForwardRef, useStatusClasses } from '../../hooks';
23
+ import { Box, Label } from '../../index';
24
+ import TimeSegment from './TimeSegment';
25
+ import { jsx as ___EmotionJSX } from "@emotion/react";
26
+ export var parseTimeIfString = function parseTimeIfString(value) {
27
+ return typeof value === 'string' ? parseTime(value) : value;
28
+ };
29
+ var TimeField = /*#__PURE__*/forwardRef(function (props, ref) {
30
+ var _state$value, _context;
31
+ var className = props.className,
32
+ isDisabled = props.isDisabled,
33
+ isReadOnly = props.isReadOnly,
34
+ others = _objectWithoutProperties(props, _excluded);
35
+ var _useLocale = useLocale(),
36
+ locale = _useLocale.locale;
37
+ var timeFieldRef = useLocalOrForwardRef(ref);
38
+ var fieldRef = useRef(null);
39
+ var labelRef = useRef(null);
40
+ var parsedTimes = {
41
+ value: props.value && parseTimeIfString(props.value),
42
+ defaultValue: props.defaultValue ? parseTimeIfString(props.defaultValue) : new Time(),
43
+ placeholderValue: props.placeholderValue && parseTimeIfString(props.placeholderValue),
44
+ minValue: props.minValue && parseTimeIfString(props.minValue),
45
+ maxValue: props.maxValue && parseTimeIfString(props.maxValue)
46
+ };
47
+ var state = useTimeFieldState(_objectSpread(_objectSpread(_objectSpread({}, props), parsedTimes), {}, {
48
+ locale: locale
49
+ }));
50
+ var _useStatusClasses = useStatusClasses(className, {
51
+ isDisabled: isDisabled,
52
+ isReadOnly: isReadOnly,
53
+ is24Hour: props.hourCycle === 24
54
+ }),
55
+ classNames = _useStatusClasses.classNames;
56
+ var _useTimeField = useTimeField(_objectSpread(_objectSpread({}, props), parsedTimes), state, fieldRef),
57
+ fieldProps = _useTimeField.fieldProps;
58
+ var _useField = useField(_objectSpread(_objectSpread({}, others), {}, {
59
+ value: (state === null || state === void 0 || (_state$value = state.value) === null || _state$value === void 0 ? void 0 : _state$value.toString()) || ''
60
+ })),
61
+ fieldContainerProps = _useField.fieldContainerProps,
62
+ fieldLabelProps = _useField.fieldLabelProps;
63
+ return ___EmotionJSX(Box, _extends({
64
+ variant: "forms.input.fieldContainer"
65
+ }, fieldContainerProps, {
66
+ ref: timeFieldRef
67
+ }), ___EmotionJSX(Label, _extends({}, fieldLabelProps, {
68
+ ref: labelRef
69
+ })), ___EmotionJSX(Box, {
70
+ isRow: true,
71
+ variant: "forms.input.fieldControlWrapper",
72
+ className: classNames
73
+ }, ___EmotionJSX(Box, _extends({
74
+ isRow: true,
75
+ variant: "forms.timeField.inputField"
76
+ }, fieldProps, {
77
+ ref: fieldRef,
78
+ className: classNames,
79
+ role: "group"
80
+ }), ___EmotionJSX(FocusScope, null, _mapInstanceProperty(_context = state.segments).call(_context, function (segment, i) {
81
+ return ___EmotionJSX(TimeSegment
82
+ // eslint-disable-next-line react/no-array-index-key
83
+ , {
84
+ key: i,
85
+ segment: segment,
86
+ state: state,
87
+ segments: state.segments,
88
+ segmentIndex: i
89
+ });
90
+ })))));
91
+ });
92
+ export default TimeField;
@@ -0,0 +1,35 @@
1
+ import { Meta } from '@storybook/addon-docs';
2
+
3
+ <Meta title="Experimental/TimeField/TimeField" />
4
+
5
+ # TimeField
6
+
7
+ The TimeField component allows users to enter and edit time values using a keyboard. Each part of the time is displayed in individual editable segments.
8
+
9
+ When using strings as props for different TimeValues, ensure that they adhere to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format.
10
+
11
+ This component is built on [useTimeField](https://react-spectrum.adobe.com/react-aria/useTimeField.html) from React Aria
12
+ and [useTimeFieldState](https://react-spectrum.adobe.com/react-stately/useTimeFieldState.html) from React Stately.
13
+
14
+ ### Required components
15
+
16
+ This component can be used independently and does not require additional components.
17
+
18
+ #### Keyboard Navigation
19
+
20
+ These keys provide additional functionality to the component.
21
+
22
+ | Keys | Functions |
23
+ | ---- | --------- |
24
+ | Tab | Focuses the field and follows the page tab sequence. |
25
+ | Shift + Tab | Moves focus to the previous focusable component. |
26
+ | Up and down Arrow keys | When segments are focused, it increments and decrements time values |
27
+ | Left and right arrows | Moves focus between segments. |
28
+
29
+ #### Screen Readers
30
+
31
+ This component uses the following attributes to assist screen readers:
32
+
33
+ - The **`aria-label`** attribute is used to provide an accessible name.
34
+ - The hidden input, TimeField, and all spin buttons have an **`aria-labelledby`** attribute pointing to the label ID, along with the **`aria-label`** attribute for an accessible name.
35
+ - Each spin button has an **`aria-valuenow`**, **`aria-valuemin`**, and **`aria-valuemax`** to represent the current value, minimum allowed value, and maximum allowed value.
@@ -0,0 +1,75 @@
1
+ import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
2
+ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
3
+ import React, { useState } from 'react';
4
+ import DocsLayout from '../../../.storybook/storybookDocsLayout';
5
+ import { TimeField } from '../../index';
6
+ import TimeFieldReadme from './TimeField.mdx';
7
+ import { jsx as ___EmotionJSX } from "@emotion/react";
8
+ export default {
9
+ title: 'Experimental/TimeField',
10
+ component: TimeField,
11
+ parameters: {
12
+ actions: {
13
+ argTypesRegex: '^on.*'
14
+ },
15
+ docs: {
16
+ source: {
17
+ type: 'code'
18
+ },
19
+ page: function page() {
20
+ return ___EmotionJSX(React.Fragment, null, ___EmotionJSX(TimeFieldReadme, null), ___EmotionJSX(DocsLayout, null));
21
+ }
22
+ }
23
+ },
24
+ argTypes: {}
25
+ };
26
+ export var Default = function Default(args) {
27
+ return ___EmotionJSX(TimeField, _extends({}, args, {
28
+ "aria-label": "timefield-default"
29
+ }));
30
+ };
31
+ export var DefaultValue = function DefaultValue(args) {
32
+ return ___EmotionJSX(TimeField, _extends({}, args, {
33
+ "aria-label": "timefield-default",
34
+ defaultValue: "12:30"
35
+ }));
36
+ };
37
+ export var Controlled = function Controlled(args) {
38
+ var _useState = useState('12:30'),
39
+ _useState2 = _slicedToArray(_useState, 2),
40
+ time = _useState2[0],
41
+ setTime = _useState2[1];
42
+ var onChangeHandler = function onChangeHandler(value) {
43
+ return setTime(value.toString());
44
+ };
45
+ return ___EmotionJSX(TimeField, _extends({}, args, {
46
+ "aria-label": "timefield-default",
47
+ value: time,
48
+ onChange: onChangeHandler
49
+ }));
50
+ };
51
+ export var Disabled = function Disabled(args) {
52
+ return ___EmotionJSX(TimeField, _extends({}, args, {
53
+ "aria-label": "timefield-default",
54
+ isDisabled: true
55
+ }));
56
+ };
57
+ export var ReadOnly = function ReadOnly(args) {
58
+ return ___EmotionJSX(TimeField, _extends({}, args, {
59
+ "aria-label": "timefield-default",
60
+ isReadOnly: true
61
+ }));
62
+ };
63
+ export var Required = function Required(args) {
64
+ return ___EmotionJSX(TimeField, _extends({}, args, {
65
+ "aria-label": "timefield-default",
66
+ isRequired: true,
67
+ label: "Example label"
68
+ }));
69
+ };
70
+ export var WithLabel = function WithLabel(args) {
71
+ return ___EmotionJSX(TimeField, _extends({}, args, {
72
+ label: "Loren Ipsum",
73
+ "aria-label": "timefield-default"
74
+ }));
75
+ };
@@ -0,0 +1,39 @@
1
+ import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
2
+ import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
3
+ import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
4
+ import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
5
+ import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
6
+ import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
7
+ import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
8
+ import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
9
+ import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
10
+ function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
11
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context, _context2; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(source), !0)).call(_context, function (key) { _defineProperty(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context2 = ownKeys(Object(source))).call(_context2, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
12
+ import { defaultFocus, input } from '../Input/Input.styles';
13
+ var inputField = _objectSpread(_objectSpread({}, input), {}, {
14
+ minWidth: '100px',
15
+ width: 'auto',
16
+ position: 'relative',
17
+ '&:focus-within:not(.is-read-only)': _objectSpread({}, defaultFocus),
18
+ ':hover': {
19
+ cursor: 'text'
20
+ },
21
+ '&.is-read-only': {
22
+ backgroundColor: 'accent.95',
23
+ border: 'none'
24
+ },
25
+ '&.is-24-hour': {
26
+ minWidth: '0px'
27
+ }
28
+ });
29
+ var segment = {
30
+ '&:focus-visible': {
31
+ outline: '1px solid',
32
+ outlineColor: 'active',
33
+ borderRadius: 4
34
+ }
35
+ };
36
+ export default {
37
+ inputField: inputField,
38
+ segment: segment
39
+ };
@@ -0,0 +1,191 @@
1
+ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
2
+ import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
3
+ import React from 'react';
4
+ import { Time } from '@internationalized/date';
5
+ import { parseTimeIfString, TimeField } from '../../index';
6
+ import { act, fireEvent, render, screen } from '../../utils/testUtils/testWrapper';
7
+ import { universalComponentTests } from '../../utils/testUtils/universalComponentTest';
8
+ import { jsx as ___EmotionJSX } from "@emotion/react";
9
+ var getComponent = function getComponent() {
10
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
11
+ return render(___EmotionJSX(TimeField, _extends({}, props, {
12
+ "aria-label": "TimeField"
13
+ })));
14
+ };
15
+
16
+ // Needs to be added to each components test file.
17
+ universalComponentTests({
18
+ renderComponent: function renderComponent(props) {
19
+ return ___EmotionJSX(TimeField, _extends({}, props, {
20
+ "aria-label": "TimeField"
21
+ }));
22
+ }
23
+ });
24
+ test('renders TimeField component', function () {
25
+ getComponent();
26
+ expect(screen.getByRole('group')).toBeInTheDocument();
27
+ });
28
+ test('renders the correct number of time segments', function () {
29
+ getComponent();
30
+ var timeSegments = screen.getAllByRole('spinbutton');
31
+ expect(timeSegments.length).toBe(3);
32
+ });
33
+ test('renders the correct number of time segments when granularity is set to seconds', function () {
34
+ getComponent({
35
+ granularity: 'second'
36
+ });
37
+ var timeSegments = screen.getAllByRole('spinbutton');
38
+ expect(timeSegments.length).toBe(4);
39
+ });
40
+ test('renders the correct number of time segments when hourCycle is set to 24', function () {
41
+ getComponent({
42
+ hourCycle: 24
43
+ });
44
+ var timeSegments = screen.getAllByRole('spinbutton');
45
+ expect(timeSegments.length).toBe(2);
46
+ });
47
+ test('renders the correct number of time segments when hourCycle is set to 24 and granularity is set to seconds', function () {
48
+ getComponent({
49
+ hourCycle: 24,
50
+ granularity: 'second'
51
+ });
52
+ var timeSegments = screen.getAllByRole('spinbutton');
53
+ expect(timeSegments.length).toBe(3);
54
+ });
55
+ test('renders the correct time with defaultValue', function () {
56
+ var defaultValue = new Time(3);
57
+ getComponent({
58
+ defaultValue: defaultValue
59
+ });
60
+ var timeSegments = screen.getAllByRole('spinbutton');
61
+ expect(timeSegments[0]).toHaveTextContent('3');
62
+ expect(timeSegments[1]).toHaveTextContent('00');
63
+ expect(timeSegments[2]).toHaveTextContent('AM');
64
+ });
65
+ test('renders the correct time with controlled value', function () {
66
+ var value = new Time(3);
67
+ getComponent({
68
+ value: value
69
+ });
70
+ var timeSegments = screen.getAllByRole('spinbutton');
71
+ expect(timeSegments[0]).toHaveTextContent('3');
72
+ expect(timeSegments[1]).toHaveTextContent('00');
73
+ expect(timeSegments[2]).toHaveTextContent('AM');
74
+ });
75
+ test('renders TimeField component with isDisabled', function () {
76
+ getComponent({
77
+ isDisabled: true
78
+ });
79
+ var timeSegments = screen.getAllByRole('spinbutton');
80
+ _forEachInstanceProperty(timeSegments).call(timeSegments, function (segment) {
81
+ expect(segment).toHaveAttribute('aria-disabled', 'true');
82
+ });
83
+ });
84
+ test('renders TimeField component with isReadOnly', function () {
85
+ getComponent({
86
+ isReadOnly: true
87
+ });
88
+ var timeSegments = screen.getAllByRole('spinbutton');
89
+ _forEachInstanceProperty(timeSegments).call(timeSegments, function (segment) {
90
+ expect(segment).toHaveAttribute('aria-readonly', 'true');
91
+ });
92
+ });
93
+ test('should handle autofocus when deleting segments from left to right', function () {
94
+ var defaultValue = new Time(12, 30);
95
+ getComponent({
96
+ defaultValue: defaultValue
97
+ });
98
+ var timeSegments = screen.queryAllByRole('spinbutton');
99
+ var hour = timeSegments[0];
100
+ var minute = timeSegments[1];
101
+ var period = timeSegments[2];
102
+ expect(hour).toHaveTextContent('12');
103
+ expect(minute).toHaveTextContent('30');
104
+ expect(period).toHaveTextContent('PM');
105
+ act(function () {
106
+ hour.focus();
107
+ });
108
+ for (var i = 0; i < 2; i += 1) {
109
+ fireEvent.keyDown(hour, {
110
+ key: 'Backspace'
111
+ });
112
+ fireEvent.keyUp(hour, {
113
+ key: 'Backspace'
114
+ });
115
+ }
116
+ expect(minute).toHaveFocus();
117
+ });
118
+ test('should handle autofocus when deleting segments from right to left', function () {
119
+ var defaultValue = new Time(12, 30);
120
+ getComponent({
121
+ defaultValue: defaultValue
122
+ });
123
+ var timeSegments = screen.queryAllByRole('spinbutton');
124
+ var hour = timeSegments[0];
125
+ var minute = timeSegments[1];
126
+ var period = timeSegments[2];
127
+ expect(hour).toHaveTextContent('12');
128
+ expect(minute).toHaveTextContent('30');
129
+ expect(period).toHaveTextContent('PM');
130
+ act(function () {
131
+ minute.focus();
132
+ });
133
+ for (var i = 0; i < 2; i += 1) {
134
+ fireEvent.keyDown(minute, {
135
+ key: 'Backspace'
136
+ });
137
+ fireEvent.keyUp(minute, {
138
+ key: 'Backspace'
139
+ });
140
+ }
141
+ expect(hour).toHaveFocus();
142
+ });
143
+ describe('parseTimeIfString', function () {
144
+ it('should parse a time with only hours', function () {
145
+ var time = parseTimeIfString('14');
146
+ var expected = new Time(14);
147
+ expect(time).toEqual(expected);
148
+ });
149
+ it('should parse a padded time with only hours', function () {
150
+ var time = parseTimeIfString('04');
151
+ var expected = new Time(4);
152
+ expect(time).toEqual(expected);
153
+ });
154
+ it('should parse a time with hours and minutes', function () {
155
+ var time = parseTimeIfString('14:05');
156
+ var expected = new Time(14, 5);
157
+ expect(time).toEqual(expected);
158
+ });
159
+ it('should parse a time with hours, minutes, and seconds', function () {
160
+ var time = parseTimeIfString('14:05:25');
161
+ var expected = new Time(14, 5, 25);
162
+ expect(time).toEqual(expected);
163
+ });
164
+ it('should parse a time with hours, minutes, seconds, and milliseconds', function () {
165
+ var time = parseTimeIfString('14:05:25.1');
166
+ var expected = new Time(14, 5, 25, 100);
167
+ expect(time).toEqual(expected);
168
+ time = parseTimeIfString('14:05:25.12');
169
+ expected = new Time(14, 5, 25, 120);
170
+ expect(time).toEqual(expected);
171
+ });
172
+ it('should error if time is not padded', function () {
173
+ expect(function () {
174
+ return parseTimeIfString('1');
175
+ }).toThrow();
176
+ expect(function () {
177
+ return parseTimeIfString('01:4');
178
+ }).toThrow();
179
+ });
180
+ it('should error if components are out of range', function () {
181
+ expect(function () {
182
+ return parseTimeIfString('45:23');
183
+ }).toThrow();
184
+ expect(function () {
185
+ return parseTimeIfString('12:99');
186
+ }).toThrow();
187
+ expect(function () {
188
+ return parseTimeIfString('12:45:99');
189
+ }).toThrow();
190
+ });
191
+ });