@digital-ai/dot-components 2.7.0 → 2.7.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/CHANGE_LOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.7.1](https://www.npmjs.com/package/@digital-ai/dot-components) (04/20/2023)
4
+
5
+ [Full Changelog](https://digital-ai.github.io/dot-components/?path=/story/introduction--page/digital-ai/dot-components/compare/2.7.0...2.7.1)
6
+
7
+ **Features:**
8
+
9
+ - S-91943: `DotDatePicker` - add `minDate` and `maxDate` props [\#1450](https://github.com/digital-ai/dot-components/pull/1450) ([dmiletic85](https://github.com/dmiletic85))
10
+
11
+ **Fixed bugs:**
12
+
13
+ - `DotTimePicker`, `DotDatePicker`: fix issues with controlled and uncontrolled states [\#1454](https://github.com/digital-ai/dot-components/pull/1454) ([dmiletic85](https://github.com/dmiletic85))
14
+ - D-24807: `Demo app` - fix error when starting demo application [\#1451](https://github.com/digital-ai/dot-components/pull/1451) ([dmiletic85](https://github.com/dmiletic85))
15
+
16
+ **Misc:**
17
+
18
+ - S-91314: Remove use of deprecated `StylesProvider` [\#1457](https://github.com/digital-ai/dot-components/pull/1457) ([CWSites](https://github.com/CWSites))
19
+ - S-91975: `TimePicker` - Improve keyboard access [\#1455](https://github.com/digital-ai/dot-components/pull/1455) ([dmiletic85](https://github.com/dmiletic85))
20
+
3
21
  ## [2.7.0](https://www.npmjs.com/package/@digital-ai/dot-components) (04/14/2023)
4
22
 
5
23
  [Full Changelog](https://digital-ai.github.io/dot-components/?path=/story/introduction--page/digital-ai/dot-components/compare/2.6.1...2.7.0)
@@ -322,6 +340,7 @@
322
340
  **Features:**
323
341
 
324
342
  - S-87871 Expose callback when sidebar collapses/expands [\#1274](https://github.com/digital-ai/dot-components/pull/1274) ([angel-git](https://github.com/angel-git))
343
+ - S-87620 Adjust height for inputs and for medium sized buttons [\#1263](https://github.com/digital-ai/dot-components/pull/1263) ([nikolinadapic](https://github.com/nikolinadapic))
325
344
 
326
345
  **Fixed bugs:**
327
346
 
@@ -334,7 +353,6 @@
334
353
  **Features:**
335
354
 
336
355
  - S-87726 Align input content with helper text [\#1265](https://github.com/digital-ai/dot-components/pull/1265) ([nikolinadapic](https://github.com/nikolinadapic))
337
- - S-87620 Adjust height for inputs and for medium sized buttons [\#1263](https://github.com/digital-ai/dot-components/pull/1263) ([nikolinadapic](https://github.com/nikolinadapic))
338
356
  - S-87616 Adjust left margin for helper text [\#1262](https://github.com/digital-ai/dot-components/pull/1262) ([nikolinadapic](https://github.com/nikolinadapic))
339
357
  - S-87599: `DotAutocomplete` Add optional `persistentLabel` prop [\#1258](https://github.com/digital-ai/dot-components/pull/1258) ([dmiletic85](https://github.com/dmiletic85))
340
358
 
@@ -507,7 +525,6 @@
507
525
 
508
526
  **Fixed bugs:**
509
527
 
510
- - S-84816: `InlineEdit`: Disable Save button when value contains only spaces [\#1156](https://github.com/digital-ai/dot-components/pull/1156) ([dmiletic85](https://github.com/dmiletic85))
511
528
  - D-20958: Safari animation jitter [\#1154](https://github.com/digital-ai/dot-components/pull/1154) ([CWSites](https://github.com/CWSites))
512
529
 
513
530
  **Misc:**
@@ -524,6 +541,7 @@
524
541
 
525
542
  **Fixed bugs:**
526
543
 
544
+ - S-84816: `InlineEdit`: Disable Save button when value contains only spaces [\#1156](https://github.com/digital-ai/dot-components/pull/1156) ([dmiletic85](https://github.com/dmiletic85))
527
545
  - D-20970: DotTableActions component [\#1134](https://github.com/digital-ai/dot-components/pull/1134) ([selsemore](https://github.com/selsemore))
528
546
  - D-20359: only display tooltip if string [\#1127](https://github.com/digital-ai/dot-components/pull/1127) ([CWSites](https://github.com/CWSites))
529
547
 
@@ -1248,7 +1266,6 @@
1248
1266
  - S-77681: setup test-coverage for reporting on dot-components [\#610](https://github.com/digital-ai/dot-components/pull/610) ([CWSites](https://github.com/CWSites))
1249
1267
  - S-76838: address Sonarcloud code issues [\#608](https://github.com/digital-ai/dot-components/pull/608) ([CWSites](https://github.com/CWSites))
1250
1268
  - S-77317: Add 'height' prop to DotDrawer component [\#603](https://github.com/digital-ai/dot-components/pull/603) ([selsemore](https://github.com/selsemore))
1251
- - Update GitHub prerelease [\#599](https://github.com/digital-ai/dot-components/pull/599) ([CWSites](https://github.com/CWSites))
1252
1269
  - S-76917: remove progressionBoard styles from theme provider [\#597](https://github.com/digital-ai/dot-components/pull/597) ([CWSites](https://github.com/CWSites))
1253
1270
 
1254
1271
  ## [1.0.3](https://www.npmjs.com/package/@digital-ai/dot-components) (07/27/2021)
package/index.esm.js CHANGED
@@ -1,11 +1,10 @@
1
1
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import { useState, useEffect, useRef, useMemo, useContext, createContext, forwardRef, Fragment, useCallback, createElement, useLayoutEffect } from 'react';
4
- import { Tooltip, Icon, Typography, Accordion, AccordionSummary, AccordionDetails, AccordionActions, InputAdornment, InputLabel, TextField, Toolbar, Alert, Fade, Avatar, Button, darken, Link, List, ListItem, CircularProgress, Popper, MenuList, MenuItem, Paper, ClickAwayListener, Drawer, IconButton, ListItemIcon, Collapse, ListSubheader, Divider, ListItemText, Badge, useMediaQuery, Autocomplete, Chip, AvatarGroup, Breadcrumbs, ToggleButtonGroup, ToggleButton, Card, CardContent, CardHeader, FormControlLabel, Checkbox, FormControl, FormGroup, FormLabel, FormHelperText, Dialog, DialogContent, DialogActions, useTheme as useTheme$1, RadioGroup, Radio, Switch, Skeleton, Snackbar, ButtonGroup, Stepper, Step, StepLabel, StepContent, TablePagination, TableContainer, TableCell, TableRow, TableBody, TableSortLabel, TableHead, Table, Tabs, Tab, LinearProgress } from '@mui/material';
4
+ import { Tooltip, Icon, Typography, Accordion, AccordionSummary, AccordionDetails, AccordionActions, InputAdornment, InputLabel, TextField, Toolbar, Alert, Fade, StyledEngineProvider, Avatar, Button, darken, Link, List, ListItem, CircularProgress, Popper, MenuList, MenuItem, Paper, ClickAwayListener, Drawer, IconButton, ListItemIcon, Collapse, ListSubheader, Divider, ListItemText, Badge, useMediaQuery, Autocomplete, Chip, AvatarGroup, Breadcrumbs, ToggleButtonGroup, ToggleButton, Card, CardContent, CardHeader, FormControlLabel, Checkbox, FormControl, FormGroup, FormLabel, FormHelperText, Dialog, DialogContent, DialogActions, useTheme as useTheme$1, RadioGroup, Radio, Switch, Skeleton, Snackbar, ButtonGroup, Stepper, Step, StepLabel, StepContent, TablePagination, TableContainer, TableCell, TableRow, TableBody, TableSortLabel, TableHead, Table, Tabs, Tab, LinearProgress } from '@mui/material';
5
5
  import '@digital-ai/dot-icons';
6
6
  import styled, { css, createGlobalStyle, ThemeProvider as ThemeProvider$1, keyframes } from 'styled-components';
7
7
  import { createTheme, ThemeProvider, alpha, useTheme } from '@mui/material/styles';
8
- import { StylesProvider } from '@mui/styles';
9
8
  import jwt_decode from 'jwt-decode';
10
9
  import { useDropzone } from 'react-dropzone';
11
10
  import GridLayout, { WidthProvider } from 'react-grid-layout';
@@ -873,7 +872,7 @@ function DotThemeProvider({
873
872
  theme = lightTheme
874
873
  }) {
875
874
  const userTheme = typeof theme === 'string' && theme === 'dark' ? darkTheme : lightTheme;
876
- return jsx(StylesProvider, Object.assign({
875
+ return jsx(StyledEngineProvider, Object.assign({
877
876
  injectFirst: true
878
877
  }, {
879
878
  children: jsx(ThemeProvider, Object.assign({
@@ -914,6 +913,8 @@ const renderNodeOrTypography = (content, typographyVariant = 'body1') => {
914
913
  children: content
915
914
  }), void 0) : content;
916
915
  };
916
+ const checkIfArrowUpPressed = event => event.key === 'ArrowUp';
917
+ const checkIfArrowDownPressed = event => event.key === 'ArrowDown';
917
918
 
918
919
  const DotAlertBanner = ({
919
920
  action,
@@ -1728,6 +1729,7 @@ const DotButton = /*#__PURE__*/forwardRef(({
1728
1729
  fullWidth: _fullWidth = false,
1729
1730
  isSubmit: _isSubmit = false,
1730
1731
  onClick,
1732
+ onKeyDown,
1731
1733
  size: _size = 'medium',
1732
1734
  startIcon,
1733
1735
  tabIndex,
@@ -1771,6 +1773,7 @@ const DotButton = /*#__PURE__*/forwardRef(({
1771
1773
  endIcon: endIcon,
1772
1774
  fullWidth: _fullWidth,
1773
1775
  onClick: event => onClick && onClick(event),
1776
+ onKeyDown: onKeyDown,
1774
1777
  ref: ref,
1775
1778
  size: _size,
1776
1779
  startIcon: startIcon,
@@ -9479,6 +9482,7 @@ const DotDatePicker = ({
9479
9482
  className,
9480
9483
  closeOnSelect: _closeOnSelect = true,
9481
9484
  'data-testid': dataTestId,
9485
+ defaultValue,
9482
9486
  disableOpenPicker,
9483
9487
  disablePast,
9484
9488
  disabled,
@@ -9493,6 +9497,8 @@ const DotDatePicker = ({
9493
9497
  inputName,
9494
9498
  label,
9495
9499
  locale,
9500
+ maxDate,
9501
+ minDate,
9496
9502
  onAccept,
9497
9503
  onBlur,
9498
9504
  onChange,
@@ -9506,8 +9512,20 @@ const DotDatePicker = ({
9506
9512
  showDaysOutsideCurrentMonth,
9507
9513
  value
9508
9514
  }) => {
9509
- const rootClasses = useStylesWithRootClass(rootClassName$1, className, _readOnly ? 'read-only' : '');
9515
+ const dateFormat = format || 'YYYY-MM-DD';
9516
+ const hasValueWithoutChangeHandler = value !== undefined && onChange === undefined;
9517
+ const hasBothValueAndDefaultValue = value !== undefined && defaultValue !== undefined;
9518
+ const isInputReadOnly = _readOnly || hasValueWithoutChangeHandler || hasBothValueAndDefaultValue;
9519
+ const rootClasses = useStylesWithRootClass(rootClassName$1, className, isInputReadOnly ? 'read-only' : '');
9510
9520
  const containerClasses = useStylesWithRootClass(containerClassName$1, _fullWidth ? 'full-width' : '', className);
9521
+ useEffect(() => {
9522
+ if (hasValueWithoutChangeHandler) {
9523
+ console.warn('Warning: You provided a `value` prop without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.');
9524
+ }
9525
+ if (hasBothValueAndDefaultValue) {
9526
+ console.warn('Warning: A component contains both `value` and `defaultValue` props. Component must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props.');
9527
+ }
9528
+ }, []);
9511
9529
  useEffect(() => {
9512
9530
  if (!locale) return;
9513
9531
  const userLocaleName = dayjs.locale();
@@ -9515,7 +9533,6 @@ const DotDatePicker = ({
9515
9533
  dayjs.extend(updateLocale);
9516
9534
  dayjs.updateLocale(userLocaleName, Object.assign(Object.assign({}, userLocaleProps), locale));
9517
9535
  }, [locale]);
9518
- const dateFormat = format || 'YYYY-MM-DD';
9519
9536
  const handleChange = (changedValue, context) => {
9520
9537
  if (!onChange || changedValue && !changedValue.isValid()) return;
9521
9538
  onChange(changedValue ? changedValue.format(dateFormat) : null, context);
@@ -9524,6 +9541,7 @@ const DotDatePicker = ({
9524
9541
  if (!onAccept) return;
9525
9542
  onAccept(changedValue ? changedValue.format(dateFormat) : null);
9526
9543
  };
9544
+ const handleError = (validationError, currentValue) => onError === null || onError === void 0 ? void 0 : onError(validationError, dayjs(currentValue).format(dateFormat));
9527
9545
  const createActionBar = () => {
9528
9546
  const actionBar = {
9529
9547
  actions: []
@@ -9552,17 +9570,20 @@ const DotDatePicker = ({
9552
9570
  autoFocus: _autoFocus,
9553
9571
  closeOnSelect: _closeOnSelect,
9554
9572
  className: rootClasses,
9555
- disableOpenPicker: disableOpenPicker || _readOnly || disabled,
9573
+ defaultValue: defaultValue && dayjs(defaultValue, dateFormat),
9574
+ disableOpenPicker: disableOpenPicker || isInputReadOnly || disabled,
9556
9575
  disablePast: disablePast,
9557
9576
  disabled: disabled,
9558
9577
  displayWeekNumber: displayWeekNumber,
9559
9578
  fixedWeekNumber: fixedWeekNumber,
9560
- format: format,
9579
+ format: dateFormat,
9561
9580
  label: persistentLabel ? null : label,
9581
+ maxDate: maxDate && dayjs(maxDate, dateFormat),
9582
+ minDate: minDate && dayjs(minDate, dateFormat),
9562
9583
  onAccept: handleAccept,
9563
9584
  onChange: handleChange,
9564
9585
  onClose: onClose,
9565
- onError: onError,
9586
+ onError: handleError,
9566
9587
  onOpen: onOpen,
9567
9588
  open: open,
9568
9589
  showDaysOutsideCurrentMonth: showDaysOutsideCurrentMonth,
@@ -9587,7 +9608,7 @@ const DotDatePicker = ({
9587
9608
  required: _required,
9588
9609
  helperText,
9589
9610
  error,
9590
- focused: _readOnly ? false : undefined,
9611
+ focused: isInputReadOnly ? false : undefined,
9591
9612
  inputProps: {
9592
9613
  className: 'dot-input',
9593
9614
  'data-testid': 'dot-date-picker-input',
@@ -9597,10 +9618,13 @@ const DotDatePicker = ({
9597
9618
  name: inputName
9598
9619
  },
9599
9620
  field: {
9600
- readOnly: _readOnly
9621
+ readOnly: isInputReadOnly
9622
+ },
9623
+ desktopTrapFocus: {
9624
+ disableEnforceFocus: true
9601
9625
  }
9602
9626
  },
9603
- value: value && dayjs(value)
9627
+ value: value && dayjs(value, dateFormat)
9604
9628
  }, void 0)]
9605
9629
  }), void 0)
9606
9630
  }), void 0);
@@ -9665,6 +9689,10 @@ const getSelectedHourButtonIndex = (selectedHour, is12HourFormat) => {
9665
9689
  return selectedHour;
9666
9690
  }
9667
9691
  };
9692
+ const getPopperButtonTabIndex = (index, isSelected, selectedValue) => selectedValue && isSelected || !selectedValue && index === 0 ? undefined : -1;
9693
+ const getDaytimeButtonTabIndex = (currentDaytime, selectedDaytime) => selectedDaytime && currentDaytime === selectedDaytime || !selectedDaytime && currentDaytime === Daytime.AM ? undefined : -1;
9694
+ const getSelectedDaytime = dateTime => dateTime && dateTime.format('A') || Daytime.AM;
9695
+ const getTimePickerButtonType = selectedDaytime => selectedDaytime && selectedDaytime === Daytime.PM ? 'primary' : 'text';
9668
9696
 
9669
9697
  const rootClassName = 'dot-time-picker';
9670
9698
  const containerClassName = 'dot-time-picker-container';
@@ -9695,6 +9723,7 @@ const DotTimePicker = ({
9695
9723
  autoFocus: _autoFocus = false,
9696
9724
  className,
9697
9725
  'data-testid': dataTestId,
9726
+ defaultValue,
9698
9727
  disableOpenPicker: _disableOpenPicker = false,
9699
9728
  disabled,
9700
9729
  error,
@@ -9716,24 +9745,43 @@ const DotTimePicker = ({
9716
9745
  required: _required = false,
9717
9746
  value
9718
9747
  }) => {
9719
- const rootClasses = useStylesWithRootClass(rootClassName, className, _readOnly ? 'read-only' : '');
9748
+ const timeFormat = format || DEFAULT_TIME_FORMAT;
9749
+ const hasValueWithoutChangeHandler = value !== undefined && onChange === undefined;
9750
+ const hasBothValueAndDefaultValue = value !== undefined && defaultValue !== undefined;
9751
+ const isComponentReadOnly = _readOnly || hasValueWithoutChangeHandler || hasBothValueAndDefaultValue;
9752
+ const rootClasses = useStylesWithRootClass(rootClassName, className, isComponentReadOnly ? 'read-only' : '');
9720
9753
  const containerClasses = useStylesWithRootClass(containerClassName, _fullWidth ? 'full-width' : '', className);
9721
9754
  const inputRef = useRef(null);
9722
9755
  const [isPickerOpened, setIsPickerOpened] = useState(false);
9723
- const timeFormat = format || DEFAULT_TIME_FORMAT;
9724
9756
  const [time, setTime] = useState(null);
9725
9757
  const [pickerTime, setPickerTime] = useState();
9726
9758
  const hoursRef = useRef(null);
9727
9759
  const minutesRef = useRef(null);
9760
+ const daytimeRef = useRef(null);
9728
9761
  const hours = getHoursForTimePicker(_ampm);
9729
9762
  const minutes = getMinutesForTimePicker();
9730
- const daytimeSelected = pickerTime && pickerTime.format('A') || Daytime.AM;
9763
+ const daytimeSelected = getSelectedDaytime(pickerTime);
9764
+ const selectedPickerHour = pickerTime && calculateHourBasedOnTimeFormat(pickerTime, _ampm);
9731
9765
  const isOpenPropDefined = open !== null && open !== undefined;
9766
+ const isControlledComponent = onChange && value !== undefined;
9767
+ useEffect(() => {
9768
+ if (hasValueWithoutChangeHandler) {
9769
+ console.warn('Warning: You provided a `value` prop without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.');
9770
+ }
9771
+ if (hasBothValueAndDefaultValue) {
9772
+ console.warn('Warning: A component contains both `value` and `defaultValue` props. Component must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props.');
9773
+ }
9774
+ }, []);
9732
9775
  useEffect(() => {
9733
- const timeValue = value ? getDayjsUtcDate(value, timeFormat) : null;
9776
+ let timeValue = null;
9777
+ if (defaultValue) {
9778
+ timeValue = getDayjsUtcDate(defaultValue, timeFormat);
9779
+ } else if (value) {
9780
+ timeValue = getDayjsUtcDate(value, timeFormat);
9781
+ }
9734
9782
  setTime(timeValue);
9735
9783
  setPickerTime(timeValue);
9736
- }, [value]);
9784
+ }, [value, defaultValue]);
9737
9785
  useLayoutEffect(() => {
9738
9786
  if (isPickerOpened && time) {
9739
9787
  scrollToSelectedTime();
@@ -9752,7 +9800,9 @@ const DotTimePicker = ({
9752
9800
  setPickerTime(pickedDateTime);
9753
9801
  };
9754
9802
  const handleInputChange = (currentValue, context) => {
9803
+ const currentTimeValue = currentValue ? currentValue : null;
9755
9804
  setPickerTime(currentValue ? currentValue : null);
9805
+ !isControlledComponent && setTime(currentTimeValue);
9756
9806
  onChange === null || onChange === void 0 ? void 0 : onChange(currentValue ? currentValue.format(timeFormat) : null, context);
9757
9807
  };
9758
9808
  const handleClose = () => {
@@ -9781,12 +9831,16 @@ const DotTimePicker = ({
9781
9831
  handleClose();
9782
9832
  };
9783
9833
  const handleSet = () => {
9784
- handleClose();
9834
+ if (!pickerTime) {
9835
+ handleClose();
9836
+ return;
9837
+ }
9785
9838
  setTime(pickerTime);
9786
9839
  onChange === null || onChange === void 0 ? void 0 : onChange(pickerTime.format(timeFormat), {
9787
9840
  validationError: null
9788
9841
  });
9789
9842
  onAccept === null || onAccept === void 0 ? void 0 : onAccept(pickerTime.format(timeFormat));
9843
+ handleClose();
9790
9844
  };
9791
9845
  const scrollToSelectedTime = () => {
9792
9846
  if (!(hoursRef === null || hoursRef === void 0 ? void 0 : hoursRef.current) || !(minutesRef === null || minutesRef === void 0 ? void 0 : minutesRef.current)) return;
@@ -9804,9 +9858,26 @@ const DotTimePicker = ({
9804
9858
  minutesRef.current.children[selectedMinute].scrollIntoView(scrollOptions);
9805
9859
  }
9806
9860
  };
9861
+ const handleTimeKeydown = (ref, index) => event => {
9862
+ const numberOfElements = ref.current.children.length;
9863
+ const prevElement = index > 0 && ref.current.children[index - 1];
9864
+ const nextElement = index < numberOfElements - 1 && ref.current.children[index + 1];
9865
+ if (checkIfArrowUpPressed(event) && prevElement) {
9866
+ event.preventDefault();
9867
+ prevElement.focus();
9868
+ } else if (checkIfArrowDownPressed(event) && nextElement) {
9869
+ event.preventDefault();
9870
+ nextElement.focus();
9871
+ }
9872
+ };
9873
+ const handleTimePickerKeyDown = event => {
9874
+ if (event.key !== 'Escape' || !isPickerOpened) return;
9875
+ handleCancel();
9876
+ };
9807
9877
  return jsxs(StyledTimePickerContainer, Object.assign({
9808
9878
  className: containerClasses,
9809
- "data-testid": dataTestId
9879
+ "data-testid": dataTestId,
9880
+ onKeyDown: handleTimePickerKeyDown
9810
9881
  }, {
9811
9882
  children: [jsxs(LocalizationProvider, Object.assign({
9812
9883
  dateAdapter: AdapterDayjs
@@ -9833,14 +9904,14 @@ const DotTimePicker = ({
9833
9904
  required: _required,
9834
9905
  helperText,
9835
9906
  error,
9836
- focused: _readOnly ? false : undefined,
9907
+ focused: isComponentReadOnly ? false : undefined,
9837
9908
  InputProps: {
9838
9909
  endAdornment: jsxs(Fragment$1, {
9839
9910
  children: [error && jsx(DotIcon, {
9840
9911
  className: "dot-error-icon",
9841
9912
  "data-testid": dataTestId && `${dataTestId}-input-error-icon`,
9842
9913
  iconId: "error-solid"
9843
- }, void 0), !_disableOpenPicker && !_readOnly && !disabled && jsx(DotIconButton, {
9914
+ }, void 0), !_disableOpenPicker && !isComponentReadOnly && !disabled && jsx(DotIconButton, {
9844
9915
  "data-testid": dataTestId && `${dataTestId}-open-btn`,
9845
9916
  iconId: "pending-clock",
9846
9917
  onClick: _event => handleTimePickerButtonClick(),
@@ -9857,17 +9928,17 @@ const DotTimePicker = ({
9857
9928
  name: inputName
9858
9929
  },
9859
9930
  field: {
9860
- readOnly: _readOnly
9931
+ readOnly: isComponentReadOnly
9861
9932
  }
9862
9933
  },
9863
9934
  value: time
9864
9935
  }, void 0)]
9865
9936
  }), void 0), jsx(Popper, Object.assign({
9937
+ anchorEl: inputRef === null || inputRef === void 0 ? void 0 : inputRef.current,
9866
9938
  className: "dot-time-picker-popper",
9867
9939
  "data-testid": dataTestId && `${dataTestId}-popper`,
9868
- open: isPickerOpened,
9869
- anchorEl: inputRef === null || inputRef === void 0 ? void 0 : inputRef.current,
9870
9940
  disablePortal: true,
9941
+ open: isPickerOpened,
9871
9942
  placement: "bottom-start"
9872
9943
  }, {
9873
9944
  children: jsx(ClickAwayListener, Object.assign({
@@ -9884,12 +9955,14 @@ const DotTimePicker = ({
9884
9955
  className: "dot-time-picker-hours",
9885
9956
  ref: hoursRef
9886
9957
  }, {
9887
- children: hours.map(hour => {
9888
- const isSelected = pickerTime ? calculateHourBasedOnTimeFormat(pickerTime, _ampm) === hour : false;
9958
+ children: hours.map((hour, index) => {
9959
+ const isSelected = pickerTime ? selectedPickerHour === hour : false;
9889
9960
  return jsx(DotButton, Object.assign({
9890
9961
  className: "dot-picker-button",
9891
9962
  "data-testid": dataTestId && `${dataTestId}-hour-button-${hour}`,
9892
9963
  onClick: () => handleHourClick(hour),
9964
+ onKeyDown: handleTimeKeydown(hoursRef, index),
9965
+ tabIndex: getPopperButtonTabIndex(index, isSelected, selectedPickerHour),
9893
9966
  type: isSelected ? 'primary' : 'text'
9894
9967
  }, {
9895
9968
  children: hour.toString().padStart(2, '0')
@@ -9899,32 +9972,39 @@ const DotTimePicker = ({
9899
9972
  className: "dot-time-picker-minutes",
9900
9973
  ref: minutesRef
9901
9974
  }, {
9902
- children: minutes.map(minute => {
9975
+ children: minutes.map((minute, index) => {
9903
9976
  const isSelected = pickerTime ? pickerTime.minute() === minute : false;
9904
9977
  return jsx(DotButton, Object.assign({
9905
9978
  className: "dot-picker-button",
9906
9979
  "data-testid": dataTestId && `${dataTestId}-minute-button-${minute}`,
9907
9980
  type: isSelected ? 'primary' : 'text',
9908
- onClick: () => handleMinuteClick(minute)
9981
+ onClick: () => handleMinuteClick(minute),
9982
+ onKeyDown: handleTimeKeydown(minutesRef, index),
9983
+ tabIndex: getPopperButtonTabIndex(index, isSelected, pickerTime === null || pickerTime === void 0 ? void 0 : pickerTime.minute())
9909
9984
  }, {
9910
9985
  children: minute.toString().padStart(2, '0')
9911
9986
  }), minute);
9912
9987
  })
9913
9988
  }), void 0), _ampm && jsxs("div", Object.assign({
9914
- className: "dot-time-picker-daytime"
9989
+ className: "dot-time-picker-daytime",
9990
+ ref: daytimeRef
9915
9991
  }, {
9916
9992
  children: [jsx(DotButton, Object.assign({
9917
9993
  className: "dot-picker-button",
9918
9994
  "data-testid": dataTestId && `${dataTestId}-am-button`,
9919
- type: daytimeSelected && daytimeSelected === Daytime.AM ? 'primary' : 'text',
9920
- onClick: () => handleDaytimeSelection(Daytime.AM)
9995
+ onClick: () => handleDaytimeSelection(Daytime.AM),
9996
+ onKeyDown: handleTimeKeydown(daytimeRef, 0),
9997
+ tabIndex: getDaytimeButtonTabIndex(Daytime.AM, daytimeSelected),
9998
+ type: daytimeSelected && daytimeSelected === Daytime.AM ? 'primary' : 'text'
9921
9999
  }, {
9922
10000
  children: Daytime.AM
9923
10001
  }), Daytime.AM), jsx(DotButton, Object.assign({
9924
10002
  className: "dot-picker-button",
9925
10003
  "data-testid": dataTestId && `${dataTestId}-pm-button`,
9926
- type: daytimeSelected && daytimeSelected === Daytime.PM ? 'primary' : 'text',
9927
- onClick: () => handleDaytimeSelection(Daytime.PM)
10004
+ onClick: () => handleDaytimeSelection(Daytime.PM),
10005
+ onKeyDown: handleTimeKeydown(daytimeRef, 1),
10006
+ tabIndex: getDaytimeButtonTabIndex(Daytime.PM, daytimeSelected),
10007
+ type: getTimePickerButtonType(daytimeSelected)
9928
10008
  }, {
9929
10009
  children: Daytime.PM
9930
10010
  }), Daytime.PM)]
package/index.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react/jsx-runtime'), require('react'), require('@mui/material'), require('@digital-ai/dot-icons'), require('styled-components'), require('@mui/material/styles'), require('@mui/styles'), require('jwt-decode'), require('react-dropzone'), require('react-grid-layout'), require('dayjs'), require('dayjs/plugin/updateLocale'), require('@mui/x-date-pickers'), require('@mui/x-date-pickers/AdapterDayjs'), require('dayjs/plugin/utc')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'react/jsx-runtime', 'react', '@mui/material', '@digital-ai/dot-icons', 'styled-components', '@mui/material/styles', '@mui/styles', 'jwt-decode', 'react-dropzone', 'react-grid-layout', 'dayjs', 'dayjs/plugin/updateLocale', '@mui/x-date-pickers', '@mui/x-date-pickers/AdapterDayjs', 'dayjs/plugin/utc'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.DotComponents = {}, global.jsxRuntime, global.React, global.MuiCore, null, global.styled, global.styles, global.styles$1, global.jwt_decode, global.ReactDropzone, global.GridLayout, global.dayjs, global.updateLocale, global.xDatePickers, global.AdapterDayjs, global.utc));
5
- })(this, (function (exports, jsxRuntime, React, material, dotIcons, styled, styles, styles$1, jwt_decode, reactDropzone, GridLayout, dayjs, updateLocale, xDatePickers, AdapterDayjs, utc) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react/jsx-runtime'), require('react'), require('@mui/material'), require('@digital-ai/dot-icons'), require('styled-components'), require('@mui/material/styles'), require('jwt-decode'), require('react-dropzone'), require('react-grid-layout'), require('dayjs'), require('dayjs/plugin/updateLocale'), require('@mui/x-date-pickers'), require('@mui/x-date-pickers/AdapterDayjs'), require('dayjs/plugin/utc')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'react/jsx-runtime', 'react', '@mui/material', '@digital-ai/dot-icons', 'styled-components', '@mui/material/styles', 'jwt-decode', 'react-dropzone', 'react-grid-layout', 'dayjs', 'dayjs/plugin/updateLocale', '@mui/x-date-pickers', '@mui/x-date-pickers/AdapterDayjs', 'dayjs/plugin/utc'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.DotComponents = {}, global.jsxRuntime, global.React, global.MuiCore, null, global.styled, global.styles, global.jwt_decode, global.ReactDropzone, global.GridLayout, global.dayjs, global.updateLocale, global.xDatePickers, global.AdapterDayjs, global.utc));
5
+ })(this, (function (exports, jsxRuntime, React, material, dotIcons, styled, styles, jwt_decode, reactDropzone, GridLayout, dayjs, updateLocale, xDatePickers, AdapterDayjs, utc) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -1007,7 +1007,7 @@
1007
1007
  _b = _a.theme,
1008
1008
  theme = _b === void 0 ? lightTheme : _b;
1009
1009
  var userTheme = typeof theme === 'string' && theme === 'dark' ? darkTheme : lightTheme;
1010
- return jsxRuntime.jsx(styles$1.StylesProvider, __assign({
1010
+ return jsxRuntime.jsx(material.StyledEngineProvider, __assign({
1011
1011
  injectFirst: true
1012
1012
  }, {
1013
1013
  children: jsxRuntime.jsx(styles.ThemeProvider, __assign({
@@ -1059,6 +1059,12 @@
1059
1059
  children: content
1060
1060
  }), void 0) : content;
1061
1061
  };
1062
+ var checkIfArrowUpPressed = function checkIfArrowUpPressed(event) {
1063
+ return event.key === 'ArrowUp';
1064
+ };
1065
+ var checkIfArrowDownPressed = function checkIfArrowDownPressed(event) {
1066
+ return event.key === 'ArrowDown';
1067
+ };
1062
1068
 
1063
1069
  var DotAlertBanner = function DotAlertBanner(_a) {
1064
1070
  var action = _a.action,
@@ -1954,6 +1960,7 @@
1954
1960
  _f = _a.isSubmit,
1955
1961
  isSubmit = _f === void 0 ? false : _f,
1956
1962
  onClick = _a.onClick,
1963
+ onKeyDown = _a.onKeyDown,
1957
1964
  _g = _a.size,
1958
1965
  size = _g === void 0 ? 'medium' : _g,
1959
1966
  startIcon = _a.startIcon,
@@ -2000,6 +2007,7 @@
2000
2007
  onClick: function (event) {
2001
2008
  return onClick && onClick(event);
2002
2009
  },
2010
+ onKeyDown: onKeyDown,
2003
2011
  ref: ref,
2004
2012
  size: size,
2005
2013
  startIcon: startIcon,
@@ -10308,6 +10316,7 @@
10308
10316
  _c = _a.closeOnSelect,
10309
10317
  closeOnSelect = _c === void 0 ? true : _c,
10310
10318
  dataTestId = _a["data-testid"],
10319
+ defaultValue = _a.defaultValue,
10311
10320
  disableOpenPicker = _a.disableOpenPicker,
10312
10321
  disablePast = _a.disablePast,
10313
10322
  disabled = _a.disabled,
@@ -10324,6 +10333,8 @@
10324
10333
  inputName = _a.inputName,
10325
10334
  label = _a.label,
10326
10335
  locale = _a.locale,
10336
+ maxDate = _a.maxDate,
10337
+ minDate = _a.minDate,
10327
10338
  onAccept = _a.onAccept,
10328
10339
  onBlur = _a.onBlur,
10329
10340
  onChange = _a.onChange,
@@ -10338,8 +10349,20 @@
10338
10349
  required = _g === void 0 ? false : _g,
10339
10350
  showDaysOutsideCurrentMonth = _a.showDaysOutsideCurrentMonth,
10340
10351
  value = _a.value;
10341
- var rootClasses = useStylesWithRootClass(rootClassName$1, className, readOnly ? 'read-only' : '');
10352
+ var dateFormat = format || 'YYYY-MM-DD';
10353
+ var hasValueWithoutChangeHandler = value !== undefined && onChange === undefined;
10354
+ var hasBothValueAndDefaultValue = value !== undefined && defaultValue !== undefined;
10355
+ var isInputReadOnly = readOnly || hasValueWithoutChangeHandler || hasBothValueAndDefaultValue;
10356
+ var rootClasses = useStylesWithRootClass(rootClassName$1, className, isInputReadOnly ? 'read-only' : '');
10342
10357
  var containerClasses = useStylesWithRootClass(containerClassName$1, fullWidth ? 'full-width' : '', className);
10358
+ React.useEffect(function () {
10359
+ if (hasValueWithoutChangeHandler) {
10360
+ console.warn('Warning: You provided a `value` prop without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.');
10361
+ }
10362
+ if (hasBothValueAndDefaultValue) {
10363
+ console.warn('Warning: A component contains both `value` and `defaultValue` props. Component must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props.');
10364
+ }
10365
+ }, []);
10343
10366
  React.useEffect(function () {
10344
10367
  if (!locale) return;
10345
10368
  var userLocaleName = dayjs__default["default"].locale();
@@ -10347,7 +10370,6 @@
10347
10370
  dayjs__default["default"].extend(updateLocale__default["default"]);
10348
10371
  dayjs__default["default"].updateLocale(userLocaleName, __assign(__assign({}, userLocaleProps), locale));
10349
10372
  }, [locale]);
10350
- var dateFormat = format || 'YYYY-MM-DD';
10351
10373
  var handleChange = function handleChange(changedValue, context) {
10352
10374
  if (!onChange || changedValue && !changedValue.isValid()) return;
10353
10375
  onChange(changedValue ? changedValue.format(dateFormat) : null, context);
@@ -10356,6 +10378,9 @@
10356
10378
  if (!onAccept) return;
10357
10379
  onAccept(changedValue ? changedValue.format(dateFormat) : null);
10358
10380
  };
10381
+ var handleError = function handleError(validationError, currentValue) {
10382
+ return onError === null || onError === void 0 ? void 0 : onError(validationError, dayjs__default["default"](currentValue).format(dateFormat));
10383
+ };
10359
10384
  var createActionBar = function createActionBar() {
10360
10385
  var actionBar = {
10361
10386
  actions: []
@@ -10384,17 +10409,20 @@
10384
10409
  autoFocus: autoFocus,
10385
10410
  closeOnSelect: closeOnSelect,
10386
10411
  className: rootClasses,
10387
- disableOpenPicker: disableOpenPicker || readOnly || disabled,
10412
+ defaultValue: defaultValue && dayjs__default["default"](defaultValue, dateFormat),
10413
+ disableOpenPicker: disableOpenPicker || isInputReadOnly || disabled,
10388
10414
  disablePast: disablePast,
10389
10415
  disabled: disabled,
10390
10416
  displayWeekNumber: displayWeekNumber,
10391
10417
  fixedWeekNumber: fixedWeekNumber,
10392
- format: format,
10418
+ format: dateFormat,
10393
10419
  label: persistentLabel ? null : label,
10420
+ maxDate: maxDate && dayjs__default["default"](maxDate, dateFormat),
10421
+ minDate: minDate && dayjs__default["default"](minDate, dateFormat),
10394
10422
  onAccept: handleAccept,
10395
10423
  onChange: handleChange,
10396
10424
  onClose: onClose,
10397
- onError: onError,
10425
+ onError: handleError,
10398
10426
  onOpen: onOpen,
10399
10427
  open: open,
10400
10428
  showDaysOutsideCurrentMonth: showDaysOutsideCurrentMonth,
@@ -10423,7 +10451,7 @@
10423
10451
  required: required,
10424
10452
  helperText: helperText,
10425
10453
  error: error,
10426
- focused: readOnly ? false : undefined,
10454
+ focused: isInputReadOnly ? false : undefined,
10427
10455
  inputProps: {
10428
10456
  className: 'dot-input',
10429
10457
  'data-testid': 'dot-date-picker-input',
@@ -10433,10 +10461,13 @@
10433
10461
  name: inputName
10434
10462
  },
10435
10463
  field: {
10436
- readOnly: readOnly
10464
+ readOnly: isInputReadOnly
10465
+ },
10466
+ desktopTrapFocus: {
10467
+ disableEnforceFocus: true
10437
10468
  }
10438
10469
  },
10439
- value: value && dayjs__default["default"](value)
10470
+ value: value && dayjs__default["default"](value, dateFormat)
10440
10471
  }, void 0)]
10441
10472
  }), void 0)
10442
10473
  }), void 0);
@@ -10511,6 +10542,18 @@
10511
10542
  return selectedHour;
10512
10543
  }
10513
10544
  };
10545
+ var getPopperButtonTabIndex = function getPopperButtonTabIndex(index, isSelected, selectedValue) {
10546
+ return selectedValue && isSelected || !selectedValue && index === 0 ? undefined : -1;
10547
+ };
10548
+ var getDaytimeButtonTabIndex = function getDaytimeButtonTabIndex(currentDaytime, selectedDaytime) {
10549
+ return selectedDaytime && currentDaytime === selectedDaytime || !selectedDaytime && currentDaytime === exports.Daytime.AM ? undefined : -1;
10550
+ };
10551
+ var getSelectedDaytime = function getSelectedDaytime(dateTime) {
10552
+ return dateTime && dateTime.format('A') || exports.Daytime.AM;
10553
+ };
10554
+ var getTimePickerButtonType = function getTimePickerButtonType(selectedDaytime) {
10555
+ return selectedDaytime && selectedDaytime === exports.Daytime.PM ? 'primary' : 'text';
10556
+ };
10514
10557
 
10515
10558
  var rootClassName = 'dot-time-picker';
10516
10559
  var containerClassName = 'dot-time-picker-container';
@@ -10546,6 +10589,7 @@
10546
10589
  autoFocus = _c === void 0 ? false : _c,
10547
10590
  className = _a.className,
10548
10591
  dataTestId = _a["data-testid"],
10592
+ defaultValue = _a.defaultValue,
10549
10593
  _d = _a.disableOpenPicker,
10550
10594
  disableOpenPicker = _d === void 0 ? false : _d,
10551
10595
  disabled = _a.disabled,
@@ -10570,13 +10614,16 @@
10570
10614
  _g = _a.required,
10571
10615
  required = _g === void 0 ? false : _g,
10572
10616
  value = _a.value;
10573
- var rootClasses = useStylesWithRootClass(rootClassName, className, readOnly ? 'read-only' : '');
10617
+ var timeFormat = format || DEFAULT_TIME_FORMAT;
10618
+ var hasValueWithoutChangeHandler = value !== undefined && onChange === undefined;
10619
+ var hasBothValueAndDefaultValue = value !== undefined && defaultValue !== undefined;
10620
+ var isComponentReadOnly = readOnly || hasValueWithoutChangeHandler || hasBothValueAndDefaultValue;
10621
+ var rootClasses = useStylesWithRootClass(rootClassName, className, isComponentReadOnly ? 'read-only' : '');
10574
10622
  var containerClasses = useStylesWithRootClass(containerClassName, fullWidth ? 'full-width' : '', className);
10575
10623
  var inputRef = React.useRef(null);
10576
10624
  var _h = React.useState(false),
10577
10625
  isPickerOpened = _h[0],
10578
10626
  setIsPickerOpened = _h[1];
10579
- var timeFormat = format || DEFAULT_TIME_FORMAT;
10580
10627
  var _j = React.useState(null),
10581
10628
  time = _j[0],
10582
10629
  setTime = _j[1];
@@ -10585,15 +10632,31 @@
10585
10632
  setPickerTime = _k[1];
10586
10633
  var hoursRef = React.useRef(null);
10587
10634
  var minutesRef = React.useRef(null);
10635
+ var daytimeRef = React.useRef(null);
10588
10636
  var hours = getHoursForTimePicker(ampm);
10589
10637
  var minutes = getMinutesForTimePicker();
10590
- var daytimeSelected = pickerTime && pickerTime.format('A') || exports.Daytime.AM;
10638
+ var daytimeSelected = getSelectedDaytime(pickerTime);
10639
+ var selectedPickerHour = pickerTime && calculateHourBasedOnTimeFormat(pickerTime, ampm);
10591
10640
  var isOpenPropDefined = open !== null && open !== undefined;
10641
+ var isControlledComponent = onChange && value !== undefined;
10592
10642
  React.useEffect(function () {
10593
- var timeValue = value ? getDayjsUtcDate(value, timeFormat) : null;
10643
+ if (hasValueWithoutChangeHandler) {
10644
+ console.warn('Warning: You provided a `value` prop without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.');
10645
+ }
10646
+ if (hasBothValueAndDefaultValue) {
10647
+ console.warn('Warning: A component contains both `value` and `defaultValue` props. Component must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props.');
10648
+ }
10649
+ }, []);
10650
+ React.useEffect(function () {
10651
+ var timeValue = null;
10652
+ if (defaultValue) {
10653
+ timeValue = getDayjsUtcDate(defaultValue, timeFormat);
10654
+ } else if (value) {
10655
+ timeValue = getDayjsUtcDate(value, timeFormat);
10656
+ }
10594
10657
  setTime(timeValue);
10595
10658
  setPickerTime(timeValue);
10596
- }, [value]);
10659
+ }, [value, defaultValue]);
10597
10660
  React.useLayoutEffect(function () {
10598
10661
  if (isPickerOpened && time) {
10599
10662
  scrollToSelectedTime();
@@ -10612,7 +10675,9 @@
10612
10675
  setPickerTime(pickedDateTime);
10613
10676
  };
10614
10677
  var handleInputChange = function handleInputChange(currentValue, context) {
10678
+ var currentTimeValue = currentValue ? currentValue : null;
10615
10679
  setPickerTime(currentValue ? currentValue : null);
10680
+ !isControlledComponent && setTime(currentTimeValue);
10616
10681
  onChange === null || onChange === void 0 ? void 0 : onChange(currentValue ? currentValue.format(timeFormat) : null, context);
10617
10682
  };
10618
10683
  var handleClose = function handleClose() {
@@ -10641,12 +10706,16 @@
10641
10706
  handleClose();
10642
10707
  };
10643
10708
  var handleSet = function handleSet() {
10644
- handleClose();
10709
+ if (!pickerTime) {
10710
+ handleClose();
10711
+ return;
10712
+ }
10645
10713
  setTime(pickerTime);
10646
10714
  onChange === null || onChange === void 0 ? void 0 : onChange(pickerTime.format(timeFormat), {
10647
10715
  validationError: null
10648
10716
  });
10649
10717
  onAccept === null || onAccept === void 0 ? void 0 : onAccept(pickerTime.format(timeFormat));
10718
+ handleClose();
10650
10719
  };
10651
10720
  var scrollToSelectedTime = function scrollToSelectedTime() {
10652
10721
  if (!(hoursRef === null || hoursRef === void 0 ? void 0 : hoursRef.current) || !(minutesRef === null || minutesRef === void 0 ? void 0 : minutesRef.current)) return;
@@ -10664,9 +10733,28 @@
10664
10733
  minutesRef.current.children[selectedMinute].scrollIntoView(scrollOptions);
10665
10734
  }
10666
10735
  };
10736
+ var handleTimeKeydown = function handleTimeKeydown(ref, index) {
10737
+ return function (event) {
10738
+ var numberOfElements = ref.current.children.length;
10739
+ var prevElement = index > 0 && ref.current.children[index - 1];
10740
+ var nextElement = index < numberOfElements - 1 && ref.current.children[index + 1];
10741
+ if (checkIfArrowUpPressed(event) && prevElement) {
10742
+ event.preventDefault();
10743
+ prevElement.focus();
10744
+ } else if (checkIfArrowDownPressed(event) && nextElement) {
10745
+ event.preventDefault();
10746
+ nextElement.focus();
10747
+ }
10748
+ };
10749
+ };
10750
+ var handleTimePickerKeyDown = function handleTimePickerKeyDown(event) {
10751
+ if (event.key !== 'Escape' || !isPickerOpened) return;
10752
+ handleCancel();
10753
+ };
10667
10754
  return jsxRuntime.jsxs(StyledTimePickerContainer, __assign({
10668
10755
  className: containerClasses,
10669
- "data-testid": dataTestId
10756
+ "data-testid": dataTestId,
10757
+ onKeyDown: handleTimePickerKeyDown
10670
10758
  }, {
10671
10759
  children: [jsxRuntime.jsxs(xDatePickers.LocalizationProvider, __assign({
10672
10760
  dateAdapter: AdapterDayjs.AdapterDayjs
@@ -10693,14 +10781,14 @@
10693
10781
  required: required,
10694
10782
  helperText: helperText,
10695
10783
  error: error,
10696
- focused: readOnly ? false : undefined,
10784
+ focused: isComponentReadOnly ? false : undefined,
10697
10785
  InputProps: {
10698
10786
  endAdornment: jsxRuntime.jsxs(jsxRuntime.Fragment, {
10699
10787
  children: [error && jsxRuntime.jsx(DotIcon, {
10700
10788
  className: "dot-error-icon",
10701
10789
  "data-testid": dataTestId && dataTestId + "-input-error-icon",
10702
10790
  iconId: "error-solid"
10703
- }, void 0), !disableOpenPicker && !readOnly && !disabled && jsxRuntime.jsx(DotIconButton, {
10791
+ }, void 0), !disableOpenPicker && !isComponentReadOnly && !disabled && jsxRuntime.jsx(DotIconButton, {
10704
10792
  "data-testid": dataTestId && dataTestId + "-open-btn",
10705
10793
  iconId: "pending-clock",
10706
10794
  onClick: function (_event) {
@@ -10719,17 +10807,17 @@
10719
10807
  name: inputName
10720
10808
  },
10721
10809
  field: {
10722
- readOnly: readOnly
10810
+ readOnly: isComponentReadOnly
10723
10811
  }
10724
10812
  },
10725
10813
  value: time
10726
10814
  }, void 0)]
10727
10815
  }), void 0), jsxRuntime.jsx(material.Popper, __assign({
10816
+ anchorEl: inputRef === null || inputRef === void 0 ? void 0 : inputRef.current,
10728
10817
  className: "dot-time-picker-popper",
10729
10818
  "data-testid": dataTestId && dataTestId + "-popper",
10730
- open: isPickerOpened,
10731
- anchorEl: inputRef === null || inputRef === void 0 ? void 0 : inputRef.current,
10732
10819
  disablePortal: true,
10820
+ open: isPickerOpened,
10733
10821
  placement: "bottom-start"
10734
10822
  }, {
10735
10823
  children: jsxRuntime.jsx(material.ClickAwayListener, __assign({
@@ -10746,14 +10834,16 @@
10746
10834
  className: "dot-time-picker-hours",
10747
10835
  ref: hoursRef
10748
10836
  }, {
10749
- children: hours.map(function (hour) {
10750
- var isSelected = pickerTime ? calculateHourBasedOnTimeFormat(pickerTime, ampm) === hour : false;
10837
+ children: hours.map(function (hour, index) {
10838
+ var isSelected = pickerTime ? selectedPickerHour === hour : false;
10751
10839
  return jsxRuntime.jsx(DotButton, __assign({
10752
10840
  className: "dot-picker-button",
10753
10841
  "data-testid": dataTestId && dataTestId + "-hour-button-" + hour,
10754
10842
  onClick: function () {
10755
10843
  return handleHourClick(hour);
10756
10844
  },
10845
+ onKeyDown: handleTimeKeydown(hoursRef, index),
10846
+ tabIndex: getPopperButtonTabIndex(index, isSelected, selectedPickerHour),
10757
10847
  type: isSelected ? 'primary' : 'text'
10758
10848
  }, {
10759
10849
  children: hour.toString().padStart(2, '0')
@@ -10763,7 +10853,7 @@
10763
10853
  className: "dot-time-picker-minutes",
10764
10854
  ref: minutesRef
10765
10855
  }, {
10766
- children: minutes.map(function (minute) {
10856
+ children: minutes.map(function (minute, index) {
10767
10857
  var isSelected = pickerTime ? pickerTime.minute() === minute : false;
10768
10858
  return jsxRuntime.jsx(DotButton, __assign({
10769
10859
  className: "dot-picker-button",
@@ -10771,30 +10861,37 @@
10771
10861
  type: isSelected ? 'primary' : 'text',
10772
10862
  onClick: function () {
10773
10863
  return handleMinuteClick(minute);
10774
- }
10864
+ },
10865
+ onKeyDown: handleTimeKeydown(minutesRef, index),
10866
+ tabIndex: getPopperButtonTabIndex(index, isSelected, pickerTime === null || pickerTime === void 0 ? void 0 : pickerTime.minute())
10775
10867
  }, {
10776
10868
  children: minute.toString().padStart(2, '0')
10777
10869
  }), minute);
10778
10870
  })
10779
10871
  }), void 0), ampm && jsxRuntime.jsxs("div", __assign({
10780
- className: "dot-time-picker-daytime"
10872
+ className: "dot-time-picker-daytime",
10873
+ ref: daytimeRef
10781
10874
  }, {
10782
10875
  children: [jsxRuntime.jsx(DotButton, __assign({
10783
10876
  className: "dot-picker-button",
10784
10877
  "data-testid": dataTestId && dataTestId + "-am-button",
10785
- type: daytimeSelected && daytimeSelected === exports.Daytime.AM ? 'primary' : 'text',
10786
10878
  onClick: function () {
10787
10879
  return handleDaytimeSelection(exports.Daytime.AM);
10788
- }
10880
+ },
10881
+ onKeyDown: handleTimeKeydown(daytimeRef, 0),
10882
+ tabIndex: getDaytimeButtonTabIndex(exports.Daytime.AM, daytimeSelected),
10883
+ type: daytimeSelected && daytimeSelected === exports.Daytime.AM ? 'primary' : 'text'
10789
10884
  }, {
10790
10885
  children: exports.Daytime.AM
10791
10886
  }), exports.Daytime.AM), jsxRuntime.jsx(DotButton, __assign({
10792
10887
  className: "dot-picker-button",
10793
10888
  "data-testid": dataTestId && dataTestId + "-pm-button",
10794
- type: daytimeSelected && daytimeSelected === exports.Daytime.PM ? 'primary' : 'text',
10795
10889
  onClick: function () {
10796
10890
  return handleDaytimeSelection(exports.Daytime.PM);
10797
- }
10891
+ },
10892
+ onKeyDown: handleTimeKeydown(daytimeRef, 1),
10893
+ tabIndex: getDaytimeButtonTabIndex(exports.Daytime.PM, daytimeSelected),
10894
+ type: getTimePickerButtonType(daytimeSelected)
10798
10895
  }, {
10799
10896
  children: exports.Daytime.PM
10800
10897
  }), exports.Daytime.PM)]
@@ -1,10 +1,11 @@
1
- import { ReactNode } from 'react';
1
+ import { KeyboardEventHandler, ReactNode } from 'react';
2
2
  import { BaseButtonProps } from '../BaseButtonProps';
3
3
  export interface ButtonProps extends BaseButtonProps {
4
4
  /** The text for the button. Button text should be in sentence case. */
5
5
  children: ReactNode;
6
6
  /** Icon placed after the children. */
7
7
  endIcon?: ReactNode;
8
+ onKeyDown?: KeyboardEventHandler;
8
9
  /** Icon placed before the children. */
9
10
  startIcon?: ReactNode;
10
11
  /** Tab order for the button. */
@@ -9,6 +9,8 @@ export interface DatePickerProps extends CommonProps {
9
9
  autoFocus?: boolean;
10
10
  /** If `true`, the popover or modal will close after submitting the full date. */
11
11
  closeOnSelect?: boolean;
12
+ /** The default value. Use when the component is not controlled. */
13
+ defaultValue?: string;
12
14
  /** If `true`, the open picker button will not be rendered (renders only the field). */
13
15
  disableOpenPicker?: boolean;
14
16
  /** If `true`, disable values before the current date for date components, time for time components and both for date time components. */
@@ -37,6 +39,10 @@ export interface DatePickerProps extends CommonProps {
37
39
  label?: string;
38
40
  /** Locale for the date library you are using */
39
41
  locale?: DatePickerLocale;
42
+ /** Maximal selectable date */
43
+ maxDate?: string;
44
+ /** Minimal selectable date. */
45
+ minDate?: string;
40
46
  /** Callback fired when the value is accepted. */
41
47
  onAccept?: (value: string) => void;
42
48
  /** A function that should be executed when the input loses focus */
@@ -67,4 +73,4 @@ export interface DatePickerProps extends CommonProps {
67
73
  /** The selected value. Used when the component is controlled. */
68
74
  value?: string;
69
75
  }
70
- export declare const DotDatePicker: ({ ariaLabel, autoFocus, className, closeOnSelect, "data-testid": dataTestId, disableOpenPicker, disablePast, disabled, displayWeekNumber, displayClearButton, error, fixedWeekNumber, format, fullWidth, helperText, inputId, inputName, label, locale, onAccept, onBlur, onChange, onClose, onError, onOpen, open, persistentLabel, readOnly, required, showDaysOutsideCurrentMonth, value, }: DatePickerProps) => JSX.Element;
76
+ export declare const DotDatePicker: ({ ariaLabel, autoFocus, className, closeOnSelect, "data-testid": dataTestId, defaultValue, disableOpenPicker, disablePast, disabled, displayWeekNumber, displayClearButton, error, fixedWeekNumber, format, fullWidth, helperText, inputId, inputName, label, locale, maxDate, minDate, onAccept, onBlur, onChange, onClose, onError, onOpen, open, persistentLabel, readOnly, required, showDaysOutsideCurrentMonth, value, }: DatePickerProps) => JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import { ComponentMeta, Story } from '@storybook/react';
2
2
  import { DatePickerProps } from './';
3
- declare const _default: ComponentMeta<({ ariaLabel, autoFocus, className, closeOnSelect, "data-testid": dataTestId, disableOpenPicker, disablePast, disabled, displayWeekNumber, displayClearButton, error, fixedWeekNumber, format, fullWidth, helperText, inputId, inputName, label, locale, onAccept, onBlur, onChange, onClose, onError, onOpen, open, persistentLabel, readOnly, required, showDaysOutsideCurrentMonth, value, }: DatePickerProps) => JSX.Element>;
3
+ declare const _default: ComponentMeta<({ ariaLabel, autoFocus, className, closeOnSelect, "data-testid": dataTestId, defaultValue, disableOpenPicker, disablePast, disabled, displayWeekNumber, displayClearButton, error, fixedWeekNumber, format, fullWidth, helperText, inputId, inputName, label, locale, maxDate, minDate, onAccept, onBlur, onChange, onClose, onError, onOpen, open, persistentLabel, readOnly, required, showDaysOutsideCurrentMonth, value, }: DatePickerProps) => JSX.Element>;
4
4
  export default _default;
5
5
  export declare const Default: DatePickerProps;
6
6
  export declare const WithHelperText: any;
@@ -16,6 +16,10 @@ export declare const WithRequiredOption: any;
16
16
  export declare const WithDaysOutsideOfCurrentMonth: any;
17
17
  export declare const WithFullWidth: any;
18
18
  export declare const WithoutClearButton: any;
19
+ export declare const WithConsoleWarning: any;
20
+ export declare const WithDefaultValue: any;
19
21
  export declare const WithControlledMode: Story<DatePickerProps>;
22
+ export declare const WithMinMaxDates: Story<DatePickerProps>;
20
23
  export declare const WithLocaleConfiguration: Story<DatePickerProps>;
21
24
  export declare const WithChangeOnBlur: Story<DatePickerProps>;
25
+ export declare const WithOpenedPopperInControlledMode: Story<DatePickerProps>;
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
1
+ import { ReactNode, KeyboardEvent } from 'react';
2
2
  import { TypographyVariant } from './typography/Typography';
3
3
  import { AvatarColor } from './avatar/Avatar';
4
4
  export declare const calculateNumberFromText: (text: string) => number;
@@ -9,3 +9,5 @@ export declare const isLowerCase: (str: string) => boolean;
9
9
  export declare const isNumber: (num: unknown) => boolean;
10
10
  export declare const renderNodeOrTypography: (content: string | ReactNode, typographyVariant?: TypographyVariant) => ReactNode;
11
11
  export declare const searchString: (needle: string, haystack: string) => boolean;
12
+ export declare const checkIfArrowUpPressed: (event: KeyboardEvent) => boolean;
13
+ export declare const checkIfArrowDownPressed: (event: KeyboardEvent) => boolean;
@@ -6,6 +6,8 @@ export interface TimePickerProps extends CommonProps {
6
6
  ampm?: boolean;
7
7
  /** If `true`, the `input` element is focused during the first mount. */
8
8
  autoFocus?: boolean;
9
+ /** The default value. Use when the component is not controlled. */
10
+ defaultValue?: string;
9
11
  /** If `true`, the open picker button will not be rendered (renders only the field). */
10
12
  disableOpenPicker?: boolean;
11
13
  /** If `true`, the picker and text field are disabled. */
@@ -49,4 +51,4 @@ export interface TimePickerProps extends CommonProps {
49
51
  export declare const DEFAULT_PICKER_TIME_FORMAT = "hh:mm";
50
52
  export declare const DEFAULT_TIME_FORMAT = "hh:mm A";
51
53
  export declare const DEFAULT_TIME = "01:00";
52
- export declare const DotTimePicker: ({ ampm, ariaLabel, autoFocus, className, "data-testid": dataTestId, disableOpenPicker, disabled, error, format, fullWidth, helperText, hideActionButtons, inputId, inputName, label, onAccept, onBlur, onChange, onClose, onOpen, open, persistentLabel, readOnly, required, value, }: TimePickerProps) => JSX.Element;
54
+ export declare const DotTimePicker: ({ ampm, ariaLabel, autoFocus, className, "data-testid": dataTestId, defaultValue, disableOpenPicker, disabled, error, format, fullWidth, helperText, hideActionButtons, inputId, inputName, label, onAccept, onBlur, onChange, onClose, onOpen, open, persistentLabel, readOnly, required, value, }: TimePickerProps) => JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import { ComponentMeta, Story } from '@storybook/react';
2
2
  import { TimePickerProps } from './';
3
- declare const _default: ComponentMeta<({ ampm, ariaLabel, autoFocus, className, "data-testid": dataTestId, disableOpenPicker, disabled, error, format, fullWidth, helperText, hideActionButtons, inputId, inputName, label, onAccept, onBlur, onChange, onClose, onOpen, open, persistentLabel, readOnly, required, value, }: TimePickerProps) => JSX.Element>;
3
+ declare const _default: ComponentMeta<({ ampm, ariaLabel, autoFocus, className, "data-testid": dataTestId, defaultValue, disableOpenPicker, disabled, error, format, fullWidth, helperText, hideActionButtons, inputId, inputName, label, onAccept, onBlur, onChange, onClose, onOpen, open, persistentLabel, readOnly, required, value, }: TimePickerProps) => JSX.Element>;
4
4
  export default _default;
5
5
  export declare const Default: TimePickerProps;
6
6
  export declare const WithAutoFocus: any;
@@ -15,6 +15,8 @@ export declare const WithReadOnly: any;
15
15
  export declare const WithHelperText: any;
16
16
  export declare const WithRequiredOption: any;
17
17
  export declare const WithOpenedTimePopper: any;
18
+ export declare const WithConsoleWarning: any;
19
+ export declare const WithDefaultValue: any;
18
20
  export declare const WithControlledMode: Story<TimePickerProps>;
19
21
  export declare const WithHourFormatPicker: Story<TimePickerProps>;
20
22
  export declare const WithOutsideTimeSetter: Story<TimePickerProps>;
@@ -1,5 +1,6 @@
1
1
  import dayjs, { Dayjs } from 'dayjs';
2
2
  import { Daytime } from './models';
3
+ import { ButtonType } from '../../BaseButtonProps';
3
4
  export declare const getDayjsUtcDate: (value: string, timeFormat?: string) => dayjs.Dayjs;
4
5
  export declare const createNumbersArray: (length: number, offset?: number) => number[];
5
6
  export declare const getHoursForTimePicker: (hasDaytimeSelection: boolean) => number[];
@@ -9,3 +10,7 @@ export declare const calculateTimeForHourSelection: (is12hourFormat: boolean, se
9
10
  export declare const calculateTimeForDaytimeSelection: (currentTime: Dayjs, selectedDaytime: Daytime) => Dayjs;
10
11
  export declare const calculateHourBasedOnTimeFormat: (time: Dayjs, is12hourFormat: boolean) => number;
11
12
  export declare const getSelectedHourButtonIndex: (selectedHour: number, is12HourFormat: boolean) => number;
13
+ export declare const getPopperButtonTabIndex: (index: number, isSelected: boolean, selectedValue?: number) => number | undefined;
14
+ export declare const getDaytimeButtonTabIndex: (currentDaytime: Daytime, selectedDaytime?: string) => number | undefined;
15
+ export declare const getSelectedDaytime: (dateTime?: Dayjs) => string;
16
+ export declare const getTimePickerButtonType: (selectedDaytime: string) => ButtonType;
@@ -56,5 +56,6 @@ declare const renderWithTheme: (ui: ReactNode) => {
56
56
  findByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions, waitForElementOptions?: import("@testing-library/react").waitForOptions) => Promise<HTMLElement>;
57
57
  findAllByTestId: (id: import("@testing-library/react").Matcher, options?: import("@testing-library/react").MatcherOptions, waitForElementOptions?: import("@testing-library/react").waitForOptions) => Promise<HTMLElement[]>;
58
58
  };
59
+ declare const rerenderWithTheme: (rerenderFn: (ui: ReactNode) => void, ui: ReactNode) => void;
59
60
  export * from '@testing-library/react';
60
- export { renderWithTheme as render };
61
+ export { renderWithTheme as render, rerenderWithTheme as rerender };
@@ -1 +1,3 @@
1
- export declare const mockScrollIntoView: (scrollIntoViewMock: typeof jest.fn) => void;
1
+ declare type ScrollIntoViewMock = (arg?: boolean | ScrollIntoViewOptions) => void;
2
+ export declare const mockScrollIntoView: (scrollIntoViewMock: ScrollIntoViewMock) => void;
3
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digital-ai/dot-components",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
4
4
  "private": false,
5
5
  "license": "SEE LICENSE IN <LICENSE.md>",
6
6
  "contributors": [
@@ -28,7 +28,6 @@
28
28
  "@emotion/react": "^11.10.4",
29
29
  "@emotion/styled": "^11.10.4",
30
30
  "@mui/material": "^5.2.5",
31
- "@mui/styles": "^5.2.3",
32
31
  "@mui/x-date-pickers": "^6.0.1",
33
32
  "jwt-decode": "^3.1.2",
34
33
  "react-dropzone": "^11.4.2",