@bitrise/bitkit 12.90.0 → 12.91.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitrise/bitkit",
3
3
  "description": "Bitrise React component library",
4
- "version": "12.90.0",
4
+ "version": "12.91.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+ssh://git@github.com/bitrise-io/bitkit.git"
@@ -40,6 +40,7 @@
40
40
  "react": "^18.2.0",
41
41
  "react-dom": "^18.2.0",
42
42
  "react-focus-lock": "^2.9.7",
43
+ "react-imask": "^7.3.0",
43
44
  "react-markdown": "^9.0.1"
44
45
  },
45
46
  "peerDependencies": {
@@ -53,9 +53,18 @@ const DatePicker = (props: DatePickerProps) => {
53
53
  );
54
54
 
55
55
  const [dateFrom, setDateFrom] = useState(initialRange?.from);
56
+
57
+ const { leftViewDate, rightViewDate, updateLeftViewDate, updateRightViewDate } = useViewDate({
58
+ initalView: dateFrom || selectable?.to,
59
+ });
60
+
56
61
  useEffect(() => {
57
62
  if (!initialRange?.from || !dateFrom?.equals(initialRange.from)) {
58
- setDateFrom(initialRange?.from);
63
+ const newDateFrom = initialRange?.from;
64
+ setDateFrom(newDateFrom);
65
+ if (newDateFrom) {
66
+ updateLeftViewDate(newDateFrom.startOf('month'));
67
+ }
59
68
  }
60
69
  }, [initialRange]);
61
70
  const [dateTo, setDateTo] = useState(initialRange?.to);
@@ -83,10 +92,6 @@ const DatePicker = (props: DatePickerProps) => {
83
92
  handleClose();
84
93
  };
85
94
 
86
- const { leftViewDate, rightViewDate, updateLeftViewDate, updateRightViewDate } = useViewDate({
87
- initalView: dateFrom || selectable?.to,
88
- });
89
-
90
95
  const isSingleMonthView = mode === 'day' || isMobile;
91
96
 
92
97
  const [preview, setPreview] = useState<'from' | 'to' | undefined>(undefined);
@@ -35,6 +35,10 @@ const days = createElement(
35
35
  {},
36
36
  ...Array.from({ length: daysCount }).map((_, i) => <DatePickerDay n={i + 1} />),
37
37
  );
38
+
39
+ export const datePickerMinYear = 1990;
40
+ export const datePickerMaxYear = 2100;
41
+
38
42
  const DatePickerMonth = ({ controls, onMonthClick, onViewDateChange, viewDate }: Props) => {
39
43
  const onNextMonth = useCallback(() => onViewDateChange(viewDate.plus({ months: 1 })), [onViewDateChange, viewDate]);
40
44
  const onPreviousMonth = useCallback(
@@ -63,8 +67,8 @@ const DatePickerMonth = ({ controls, onMonthClick, onViewDateChange, viewDate }:
63
67
  <NumberInput
64
68
  aria-label="year"
65
69
  flexShrink={1}
66
- max={2100}
67
- min={1990}
70
+ max={datePickerMaxYear}
71
+ min={datePickerMinYear}
68
72
  onChange={(_, year) => onViewDateChange(viewDate.set({ year }))}
69
73
  size="small"
70
74
  value={viewDate.year}
@@ -1,5 +1,8 @@
1
- import { useState } from 'react';
1
+ import { useEffect, useImperativeHandle, useMemo, useState } from 'react';
2
2
  import { forwardRef } from '@chakra-ui/react';
3
+ import { IMask, useIMask } from 'react-imask';
4
+ import { DateTime } from 'luxon';
5
+ import { datePickerMaxYear, datePickerMinYear } from '../../DatePicker/DatePickerMonth';
3
6
  import DatePicker from '../../DatePicker/DatePicker';
4
7
  import IconButton from '../../IconButton/IconButton';
5
8
  import Input, { InputProps } from '../Input/Input';
@@ -11,37 +14,93 @@ export type DateInputProps = Omit<InputProps, 'value' | 'onChange' | 'placeholde
11
14
  };
12
15
 
13
16
  const DateInput = forwardRef<DateInputProps, 'div'>((props, ref) => {
14
- const { onCalendarClick, onChange, value, ...rest } = props;
17
+ const { inputRef, onCalendarClick, onChange, value, ...rest } = props;
15
18
  const [isDatePickerVisible, setIsDatePickerVisible] = useState(false);
16
19
 
17
- const rightButton = (
18
- <IconButton
19
- _active={{ background: 'transparent' }}
20
- _hover={{ background: 'transparent' }}
21
- aria-label="Show date picker"
22
- color="icon.tertiary"
23
- iconName="Calendar"
24
- onClick={() => setIsDatePickerVisible(true)}
25
- variant="tertiary"
26
- />
20
+ const dateFormat = 'MM/dd/yyyy';
21
+
22
+ const {
23
+ ref: innerRef,
24
+ setValue,
25
+ value: currentValue,
26
+ } = useIMask<HTMLInputElement>(
27
+ {
28
+ autofix: 'pad',
29
+ blocks: {
30
+ dd: {
31
+ from: 1,
32
+ mask: IMask.MaskedRange,
33
+ placeholderChar: 'd',
34
+ to: 31,
35
+ },
36
+ LL: {
37
+ from: 1,
38
+ mask: IMask.MaskedRange,
39
+ placeholderChar: 'm',
40
+ to: 12,
41
+ },
42
+ yyyy: {
43
+ autofix: false,
44
+ from: datePickerMinYear,
45
+ mask: IMask.MaskedRange,
46
+ placeholderChar: 'y',
47
+ to: datePickerMaxYear,
48
+ },
49
+ },
50
+ format: (date: Date | null) => (date ? DateTime.fromJSDate(date).toFormat(dateFormat) : ''),
51
+ lazy: false,
52
+ mask: Date,
53
+ parse: (str: string) => {
54
+ try {
55
+ return DateTime.fromFormat(str, dateFormat).toJSDate();
56
+ } catch {
57
+ return DateTime.now().toJSDate();
58
+ }
59
+ },
60
+ pattern: 'LL/dd/yyyy',
61
+ },
62
+ {
63
+ onAccept: (val) => onChange?.(val),
64
+ },
27
65
  );
28
66
 
67
+ useImperativeHandle(inputRef, () => innerRef.current!, []);
68
+
69
+ useEffect(() => setValue(value || ''), [value]);
70
+
71
+ const currentDate = useMemo(() => {
72
+ try {
73
+ return DateTime.fromFormat(currentValue, dateFormat);
74
+ } catch {
75
+ return undefined;
76
+ }
77
+ }, [currentValue]);
78
+
29
79
  return (
30
80
  <DatePicker
31
81
  mode="day"
32
- onApply={(day) => onChange?.(day?.toLocaleString() || '')}
82
+ onApply={(day) => setValue(day?.toFormat(dateFormat) || '')}
33
83
  onClose={() => setIsDatePickerVisible(false)}
84
+ selected={currentDate}
34
85
  variant="default"
35
86
  visible={isDatePickerVisible}
36
87
  >
37
88
  <Input
38
89
  {...rest}
39
90
  ref={ref}
40
- onChange={(e) => onChange?.(e.target.value)}
41
- placeholder="dd/mm/yyyy"
42
- rightAddon={rightButton}
91
+ inputRef={innerRef}
92
+ rightAddon={
93
+ <IconButton
94
+ _active={{ background: 'transparent' }}
95
+ _hover={{ background: 'transparent' }}
96
+ aria-label="Show date picker"
97
+ color="icon.tertiary"
98
+ iconName="Calendar"
99
+ onClick={() => setIsDatePickerVisible(true)}
100
+ variant="tertiary"
101
+ />
102
+ }
43
103
  rightAddonPlacement="inside"
44
- value={value}
45
104
  />
46
105
  </DatePicker>
47
106
  );
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from './types/chakra';
2
- export * from './utils/chakra';
2
+ export * from './utils/reexports';
3
3
  export * from './hooks';
4
4
 
5
5
  export { default as theme } from './theme';
@@ -1 +1,2 @@
1
1
  export { forwardRef, keyframes } from '@chakra-ui/react';
2
+ export { IMask, useIMask } from 'react-imask';